Version 2.9.0-4.0.dev
Merge commit '726d3c772554924f62db0b9e0d4c280dbbddc824' into dev
diff --git a/41458.dart b/41458.dart
new file mode 100644
index 0000000..22bd14a
--- /dev/null
+++ b/41458.dart
@@ -0,0 +1,9 @@
+class A {}
+
+extension AList on Iterable<A> {
+ get foo => null;
+}
+
+extension AMap on Map<String, A> {
+ get bar => values.foo; // <-- foo is underlined red
+}
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 1aa6464..4415ec9 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -16,6 +16,31 @@
* Class `OSError` now implements `Exception`. This change means `OSError` will
now be caught in catch clauses catching `Exception`s.
+### Tools
+
+#### dartfmt
+
+* Add `--fix-single-cascade-statements`.
+* Correctly handle `var` in `--fix-function-typedefs`.
+* Preserve leading indentation in fixed doc comments.
+* Split outer nested control flow elements.
+* Always place a blank line after script tags.
+* Don't add unneeded splits on if elements near comments.
+* Indent blocks in initializers of multiple-variable declarations.
+* Update the null-aware subscript syntax from `?.[]` to `?[]`.
+
+#### Linter
+
+Updated the Linter to `0.1.115`, which includes:
+
+* Updated `avoid_types_as_parameter_names` to check catch-clauses.
+* Fixed `unsafe_html` to check attributes and methods on extensions.
+* Extended `unsafe_html` to include `Window.open`, `Element.html` and
+ `DocumentFragment.html` in unsafe API checks.
+* Improved docs for `sort_child_properties_last`.
+* (internal) `package:analyzer` API updates.
+* New lint: `sized_box_for_whitespace`.
+
### Dart VM
@@ -695,6 +720,13 @@
* new lint: `avoid_web_libraries_in_flutter` (experimental)
* (internal) prepare `unnecessary_lambdas` for coming `MethodInvocation` vs. `FunctionExpressionInvocation` changes
+## 2.5.2 - 2019-10-08
+
+This is a patch release with properly signed binaries required for macOS
+Catalina (Issue [38765][]).
+
+[38765]: https://github.com/dart-lang/sdk/issues/38765
+
## 2.5.1 - 2019-09-27
This is a patch release that prevents type inference failures in the analyzer
diff --git a/DEPS b/DEPS
index 232f736..13150cf 100644
--- a/DEPS
+++ b/DEPS
@@ -39,7 +39,7 @@
# co19 is a cipd package. Use update.sh in tests/co19[_2] to update these
# hashes. It requires access to the dart-build-access group, which EngProd
# has.
- "co19_rev": "929da300c553ebb8a9ff744746bcc1326613e1f9",
+ "co19_rev": "919e0b662aa4b392dcb791446d80f31e972f8635",
"co19_2_rev": "368bfa9e877a2df003547f64bb17e30596af10c7",
# As Flutter does, we use Fuchsia's GN and Clang toolchain. These revision
@@ -60,16 +60,16 @@
"async_tag": "2.4.1",
"bazel_worker_tag": "v0.1.22",
"benchmark_harness_tag": "81641290dea44c34138a109a37e215482f405f81",
- "boolean_selector_tag" : "1.0.4",
+ "boolean_selector_tag": "1309eabed510cc3b7536fd4367d39b97ebee3d69",
"boringssl_gen_rev": "b9e27cff1ff0803e97ab1f88764a83be4aa94a6d",
"boringssl_rev" : "4dfd5af70191b068aebe567b8e29ce108cee85ce",
- "charcode_tag": "v1.1.2",
+ "charcode_tag": "9085e6b6127f084d66c0a94810a808121459012a",
"chrome_rev" : "19997",
"cli_util_rev" : "4ad7ccbe3195fd2583b30f86a86697ef61e80f41",
- "collection_tag": "1.14.11",
- "convert_tag": "2.0.2",
+ "collection_tag": "7be42e03d427cc19571cd7f9fc628a5913a6b757",
+ "convert_tag": "49bde5b371eb5c2c8e721557cf762f17c75e49fc",
"crypto_tag" : "2.0.6",
- "csslib_tag" : "0.15.0",
+ "csslib_tag": "bf372d4fdc6dfa232ad93f77a0a3de0891edd04c",
"dart2js_info_tag" : "0.6.0",
# Note: Updates to dart_style have to be coordinated with the infrastructure
@@ -84,30 +84,30 @@
# and land the review.
#
# For more details, see https://github.com/dart-lang/sdk/issues/30164
- "dart_style_tag": "1.3.2", # Please see the note above before updating.
+ "dart_style_tag": "1.3.6", # Please see the note above before updating.
"dartdoc_tag" : "v0.31.0",
"ffi_tag": "ea88d71b043ee14b268c3aedff14e9eb32e20959",
- "fixnum_tag": "0.10.9",
- "glob_tag": "1.1.7",
+ "fixnum_tag": "eb3748663dc979271ff6a3d014fbe522543b1d91",
+ "glob_tag": "e9f4e6b7ae8abe5071461cf8f47191bb19cf7ef6",
"html_tag" : "0.14.0+1",
"http_io_rev": "2fa188caf7937e313026557713f7feffedd4978b",
"http_multi_server_rev" : "ea269f79321d659208402088f3297e8920a88ee6",
"http_parser_tag" : "3.1.3",
"http_retry_tag": "0.1.1",
- "http_tag" : "0.12.0+2",
+ "http_tag": "a131e563c09349f624d5421237183a06fb10552d",
"http_throttle_tag" : "1.0.2",
"icu_rev" : "5005010d694e16571b8dfbf07d70817841f80a69",
"idl_parser_rev": "5fb1ebf49d235b5a70c9f49047e83b0654031eb7",
"intl_tag": "0.16.1",
"jinja2_rev": "2222b31554f03e62600cd7e383376a7c187967a1",
- "json_rpc_2_tag": "2.0.9",
- "linter_tag": "0.1.114",
- "logging_tag": "0.11.3+2",
+ "json_rpc_2_tag": "eec10819a40e7bf2e401f2b97368776a90cc5550",
+ "linter_tag": "0.1.115",
+ "logging_tag": "9561ba016ae607747ae69b846c0e10958ca58ed4",
"markupsafe_rev": "8f45f5cfa0009d2a70589bcda0349b8cb2b72783",
- "markdown_tag": "2.1.1",
- "matcher_tag": "0.12.5",
- "mime_tag": "0.9.6+2",
+ "markdown_tag": "dd150bb64c5f3b41d31f20f399ae2a855f7f8c00",
+ "matcher_tag": "af4fe7daf8e94a46981e4f072872be550a6969e9",
+ "mime_tag": "179b5e6a88f4b63f36dc1b8fcbc1e83e5e0cd3a7",
"mockito_tag": "d39ac507483b9891165e422ec98d9fb480037c8b",
"mustache_tag" : "5e81b12215566dbe2473b2afd01a8a8aedd56ad9",
"oauth2_tag": "1.2.1",
@@ -144,7 +144,7 @@
"tflite_native_rev": "3c777c40608a2a9f1427bfe0028ab48e7116b4c1",
"typed_data_tag": "1.1.6",
"usage_tag": "3.4.0",
- "watcher_rev": "0.9.7+14",
+ "watcher_rev": "fc3c9aae5d31d707b3013b42634dde8d8a1161b4",
"web_components_rev": "8f57dac273412a7172c8ade6f361b407e2e4ed02",
"web_socket_channel_tag": "1.1.0",
"WebCore_rev": "fb11e887f77919450e497344da570d780e078bc8",
diff --git a/benchmarks/IsolateJson/dart/IsolateJson.dart b/benchmarks/IsolateJson/dart/IsolateJson.dart
index bdc7988..1fa4919 100644
--- a/benchmarks/IsolateJson/dart/IsolateJson.dart
+++ b/benchmarks/IsolateJson/dart/IsolateJson.dart
@@ -11,17 +11,24 @@
import 'package:benchmark_harness/benchmark_harness.dart' show BenchmarkBase;
import 'package:meta/meta.dart';
+import 'runtime/tests/vm/dart/export_sendAndExit_helper.dart' show sendAndExit;
+
class JsonDecodingBenchmark {
JsonDecodingBenchmark(this.name,
- {@required this.sample, @required this.numTasks});
+ {@required this.sample,
+ @required this.numTasks,
+ @required this.useSendAndExit});
Future<void> report() async {
final stopwatch = Stopwatch()..start();
- final decodedFutures = <Future>[];
- for (int i = 0; i < numTasks; i++) {
- decodedFutures.add(decodeJson(sample));
+ // Benchmark harness counts 10 iterations as one.
+ for (int i = 0; i < 10; i++) {
+ final decodedFutures = <Future>[];
+ for (int i = 0; i < numTasks; i++) {
+ decodedFutures.add(decodeJson(useSendAndExit, sample));
+ }
+ await Future.wait(decodedFutures);
}
- await Future.wait(decodedFutures);
print("$name(RunTime): ${stopwatch.elapsedMicroseconds} us.");
}
@@ -29,6 +36,7 @@
final String name;
final Uint8List sample;
final int numTasks;
+ final bool useSendAndExit;
}
Uint8List createSampleJson(final size) {
@@ -41,27 +49,42 @@
}
class JsonDecodeRequest {
+ final bool useSendAndExit;
final SendPort sendPort;
final Uint8List encodedJson;
- const JsonDecodeRequest(this.sendPort, this.encodedJson);
+ const JsonDecodeRequest(this.useSendAndExit, this.sendPort, this.encodedJson);
}
-Future<Map> decodeJson(Uint8List encodedJson) async {
+Future<Map> decodeJson(bool useSendAndExit, Uint8List encodedJson) async {
final port = ReceivePort();
final inbox = StreamIterator<dynamic>(port);
- final workerExitedPort = ReceivePort();
- await Isolate.spawn(
- jsonDecodingIsolate, JsonDecodeRequest(port.sendPort, encodedJson),
- onExit: workerExitedPort.sendPort);
+ final completer = Completer<bool>();
+ final workerExitedPort = RawReceivePort((v) {
+ completer.complete(true);
+ });
+ final workerErroredPort = RawReceivePort((v) {
+ stderr.writeln('worker errored out $v');
+ completer.completeError(true);
+ });
+ await Isolate.spawn(jsonDecodingIsolate,
+ JsonDecodeRequest(useSendAndExit, port.sendPort, encodedJson),
+ onError: workerErroredPort.sendPort, onExit: workerExitedPort.sendPort);
+ await completer.future;
+ workerExitedPort.close();
+ workerErroredPort.close();
await inbox.moveNext();
final decodedJson = inbox.current;
- await workerExitedPort.first;
port.close();
return decodedJson;
}
Future<void> jsonDecodingIsolate(JsonDecodeRequest request) async {
- request.sendPort.send(json.decode(utf8.decode(request.encodedJson)));
+ final result = json.decode(utf8.decode(request.encodedJson));
+ if (request.useSendAndExit) {
+ sendAndExit(request.sendPort, result);
+ } else {
+ request.sendPort.send(result);
+ }
}
class SyncJsonDecodingBenchmark extends BenchmarkBase {
@@ -118,6 +141,13 @@
for (final iterations in <int>[1, 4]) {
await JsonDecodingBenchmark(
"IsolateJson.Decode${config.suffix}x$iterations",
+ useSendAndExit: false,
+ sample: config.sample,
+ numTasks: iterations)
+ .report();
+ await JsonDecodingBenchmark(
+ "IsolateJson.SendAndExit_Decode${config.suffix}x$iterations",
+ useSendAndExit: true,
sample: config.sample,
numTasks: iterations)
.report();
diff --git a/benchmarks/IsolateJson/dart/runtime/tests/vm/dart/export_sendAndExit_helper.dart b/benchmarks/IsolateJson/dart/runtime/tests/vm/dart/export_sendAndExit_helper.dart
new file mode 100644
index 0000000..75628d6
--- /dev/null
+++ b/benchmarks/IsolateJson/dart/runtime/tests/vm/dart/export_sendAndExit_helper.dart
@@ -0,0 +1 @@
+export 'dart:_internal' show sendAndExit;
diff --git a/build/config/compiler/BUILD.gn b/build/config/compiler/BUILD.gn
index b3dec5b..7548761 100644
--- a/build/config/compiler/BUILD.gn
+++ b/build/config/compiler/BUILD.gn
@@ -118,10 +118,7 @@
ldflags += [ "-fsanitize=thread" ]
}
if (is_ubsan) {
- cflags += [
- "-fsanitize=undefined",
- "-fno-sanitize=null,alignment",
- ]
+ cflags += [ "-fsanitize=undefined" ]
ldflags += [ "-fsanitize=undefined" ]
}
}
diff --git a/pkg/_fe_analyzer_shared/lib/src/testing/id_testing.dart b/pkg/_fe_analyzer_shared/lib/src/testing/id_testing.dart
index 14ab354..f210251 100644
--- a/pkg/_fe_analyzer_shared/lib/src/testing/id_testing.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/testing/id_testing.dart
@@ -11,12 +11,14 @@
const String cfeMarker = 'cfe';
const String cfeWithNnbdMarker = '$cfeMarker:nnbd';
const String dart2jsMarker = 'dart2js';
+const String dart2jsWithNnbdSdkMarker = '$dart2jsMarker:nnbd-sdk';
const String analyzerMarker = 'analyzer';
/// Markers used in annotated tests shared by CFE, analyzer and dart2js.
const List<String> sharedMarkers = [
cfeMarker,
dart2jsMarker,
+ dart2jsWithNnbdSdkMarker,
analyzerMarker,
];
@@ -31,6 +33,7 @@
cfeMarker,
cfeWithNnbdMarker,
dart2jsMarker,
+ dart2jsWithNnbdSdkMarker,
analyzerMarker,
];
diff --git a/pkg/_fe_analyzer_shared/test/constants/data/basic.dart b/pkg/_fe_analyzer_shared/test/constants/data/basic.dart
index ec98279..138949b 100644
--- a/pkg/_fe_analyzer_shared/test/constants/data/basic.dart
+++ b/pkg/_fe_analyzer_shared/test/constants/data/basic.dart
@@ -20,10 +20,10 @@
print(/*Double(0.5)*/ double0);
print(
/*cfe|analyzer.Symbol(foo)*/
- /*dart2js.Instance(Symbol,{_name:String(foo))*/
+ /*dart2js|dart2js:nnbd-sdk.Instance(Symbol,{_name:String(foo))*/
symbol0);
print(
/*cfe|analyzer.Symbol(foo)*/
- /*dart2js.Instance(Symbol,{_name:String(foo))*/
+ /*dart2js|dart2js:nnbd-sdk.Instance(Symbol,{_name:String(foo))*/
symbol1);
}
diff --git a/pkg/_fe_analyzer_shared/test/constants/data/errors.dart b/pkg/_fe_analyzer_shared/test/constants/data/errors.dart
index b2026dc..a1c0f01 100644
--- a/pkg/_fe_analyzer_shared/test/constants/data/errors.dart
+++ b/pkg/_fe_analyzer_shared/test/constants/data/errors.dart
@@ -5,7 +5,7 @@
String method() => 'foo';
const String string0 =
- /*cfe|dart2js.error: Method invocation is not a constant expression.*/
+ /*cfe|dart2js|dart2js:nnbd-sdk.error: Method invocation is not a constant expression.*/
method();
main() {
diff --git a/pkg/_fe_analyzer_shared/test/constants/data/function.dart b/pkg/_fe_analyzer_shared/test/constants/data/function.dart
index 987b64c5..d8cf2b6 100644
--- a/pkg/_fe_analyzer_shared/test/constants/data/function.dart
+++ b/pkg/_fe_analyzer_shared/test/constants/data/function.dart
@@ -15,15 +15,15 @@
main() {
print(
- /*cfe|dart2js.Function(method1)*/
+ /*cfe|dart2js|dart2js:nnbd-sdk.Function(method1)*/
/*analyzer.Function(method1,type=T Function<T>(T))*/
function0);
print(
/*cfe|dart2js.Instantiation(method1<int>)*/
/*analyzer.Function(method1,type=int Function(int))*/
- instantiation0);
+ /*dart2js:nnbd-sdk.Instantiation(method1<int*>)*/ instantiation0);
print(
/*cfe|dart2js.Instantiation(method2<String,int>)*/
/*analyzer.Function(method2,type=Map<String, int> Function(String, int))*/
- instantiation1);
+ /*dart2js:nnbd-sdk.Instantiation(method2<String*,int*>)*/ instantiation1);
}
diff --git a/pkg/_fe_analyzer_shared/test/constants/data/list.dart b/pkg/_fe_analyzer_shared/test/constants/data/list.dart
index 446475d..c18686c 100644
--- a/pkg/_fe_analyzer_shared/test/constants/data/list.dart
+++ b/pkg/_fe_analyzer_shared/test/constants/data/list.dart
@@ -16,8 +16,12 @@
main() {
print(/*List<dynamic>()*/ list0);
- print(/*List<int>()*/ list1);
- print(/*List<int>()*/ list2);
- print(/*List<int>(Int(42))*/ list3);
- print(/*List<int>(Int(42),Int(87))*/ list4);
+ print(
+ /*cfe|analyzer|dart2js.List<int>()*/ /*dart2js:nnbd-sdk.List<int*>()*/ list1);
+ print(
+ /*cfe|analyzer|dart2js.List<int>()*/ /*dart2js:nnbd-sdk.List<int*>()*/ list2);
+ print(
+ /*cfe|analyzer|dart2js.List<int>(Int(42))*/ /*dart2js:nnbd-sdk.List<int*>(Int(42))*/ list3);
+ print(
+ /*cfe|analyzer|dart2js.List<int>(Int(42),Int(87))*/ /*dart2js:nnbd-sdk.List<int*>(Int(42),Int(87))*/ list4);
}
diff --git a/pkg/_fe_analyzer_shared/test/constants/data/map.dart b/pkg/_fe_analyzer_shared/test/constants/data/map.dart
index 88cf275..bb783c2 100644
--- a/pkg/_fe_analyzer_shared/test/constants/data/map.dart
+++ b/pkg/_fe_analyzer_shared/test/constants/data/map.dart
@@ -17,8 +17,12 @@
main() {
print(/*Map<dynamic,dynamic>()*/ map0);
- print(/*Map<String,int>()*/ map1);
- print(/*Map<String,int>()*/ map2);
- print(/*Map<String,int>(String(foo):Int(42))*/ map3);
- print(/*Map<String,int>(String(foo):Int(42),String(bar):Int(87))*/ map4);
+ print(
+ /*cfe|analyzer|dart2js.Map<String,int>()*/ /*dart2js:nnbd-sdk.Map<String*,int*>()*/ map1);
+ print(
+ /*cfe|analyzer|dart2js.Map<String,int>()*/ /*dart2js:nnbd-sdk.Map<String*,int*>()*/ map2);
+ print(
+ /*cfe|analyzer|dart2js.Map<String,int>(String(foo):Int(42))*/ /*dart2js:nnbd-sdk.Map<String*,int*>(String(foo):Int(42))*/ map3);
+ print(
+ /*cfe|analyzer|dart2js.Map<String,int>(String(foo):Int(42),String(bar):Int(87))*/ /*dart2js:nnbd-sdk.Map<String*,int*>(String(foo):Int(42),String(bar):Int(87))*/ map4);
}
diff --git a/pkg/_fe_analyzer_shared/test/constants/data/marker.options b/pkg/_fe_analyzer_shared/test/constants/data/marker.options
index f713e63..98b58d7 100644
--- a/pkg/_fe_analyzer_shared/test/constants/data/marker.options
+++ b/pkg/_fe_analyzer_shared/test/constants/data/marker.options
@@ -1,3 +1,4 @@
cfe=pkg/front_end/test/id_tests/constant_test.dart
analyzer=pkg/analyzer/test/id_tests/constant_test.dart
-dart2js=tests/compiler/dart2js/model/cfe_constant_test.dart
\ No newline at end of file
+dart2js=tests/compiler/dart2js/model/cfe_constant_test.dart
+dart2js:nnbd-sdk=tests/compiler/dart2js/model/cfe_constant_test.dart
\ No newline at end of file
diff --git a/pkg/_fe_analyzer_shared/test/constants/data/set.dart b/pkg/_fe_analyzer_shared/test/constants/data/set.dart
index 26ca6c3..bf567fe 100644
--- a/pkg/_fe_analyzer_shared/test/constants/data/set.dart
+++ b/pkg/_fe_analyzer_shared/test/constants/data/set.dart
@@ -21,8 +21,12 @@
main() {
print(/*Set<dynamic>()*/ set0);
- print(/*Set<int>()*/ set1);
- print(/*Set<int>()*/ set2);
- print(/*Set<int>(Int(42))*/ set3);
- print(/*Set<int>(Int(42),Int(87))*/ set4);
+ print(
+ /*cfe|analyzer|dart2js.Set<int>()*/ /*dart2js:nnbd-sdk.Set<int*>()*/ set1);
+ print(
+ /*cfe|analyzer|dart2js.Set<int>()*/ /*dart2js:nnbd-sdk.Set<int*>()*/ set2);
+ print(
+ /*cfe|analyzer|dart2js.Set<int>(Int(42))*/ /*dart2js:nnbd-sdk.Set<int*>(Int(42))*/ set3);
+ print(
+ /*cfe|analyzer|dart2js.Set<int>(Int(42),Int(87))*/ /*dart2js:nnbd-sdk.Set<int*>(Int(42),Int(87))*/ set4);
}
diff --git a/pkg/_fe_analyzer_shared/test/constants/data/type_literals.dart b/pkg/_fe_analyzer_shared/test/constants/data/type_literals.dart
index f729673..49a9d8f 100644
--- a/pkg/_fe_analyzer_shared/test/constants/data/type_literals.dart
+++ b/pkg/_fe_analyzer_shared/test/constants/data/type_literals.dart
@@ -22,27 +22,27 @@
main() {
print(
/*cfe|analyzer.TypeLiteral(dynamic Function())*/
- /*dart2js.TypeLiteral(()->dynamic)*/
+ /*dart2js|dart2js:nnbd-sdk.TypeLiteral(()->dynamic)*/
typedef);
print(
/*cfe|analyzer.TypeLiteral(void Function(dynamic))*/
- /*dart2js.TypeLiteral((dynamic)->void)*/
+ /*dart2js|dart2js:nnbd-sdk.TypeLiteral((dynamic)->void)*/
genericTypedef);
print(
/*cfe|analyzer.TypeLiteral(void Function<T>(T))*/
- /*dart2js.TypeLiteral((0)->void)*/
+ /*dart2js|dart2js:nnbd-sdk.TypeLiteral((0)->void)*/
genericFunctionTypedef);
print(
/*cfe|analyzer.TypeLiteral(void Function<T>(FutureOr<T>))*/
- /*dart2js.TypeLiteral((FutureOr<0>)->void)*/
+ /*dart2js|dart2js:nnbd-sdk.TypeLiteral((FutureOr<0>)->void)*/
typedefWithFutureOr);
print(
/*cfe|analyzer.TypeLiteral(FutureOr<dynamic>)*/
- /*dart2js.TypeLiteral(dynamic)*/
+ /*dart2js|dart2js:nnbd-sdk.TypeLiteral(dynamic)*/
futureOr);
print(
diff --git a/pkg/analysis_server/.gitignore b/pkg/analysis_server/.gitignore
deleted file mode 100644
index ad1fe33..0000000
--- a/pkg/analysis_server/.gitignore
+++ /dev/null
@@ -1,3 +0,0 @@
-lib/src/edit/nnbd_migration/resources/*.js.deps
-lib/src/edit/nnbd_migration/resources/*.js.map
-lib/src/edit/nnbd_migration/resources/migration.js
diff --git a/pkg/analysis_server/lib/src/analysis_server.dart b/pkg/analysis_server/lib/src/analysis_server.dart
index f712b61..bcc76e2 100644
--- a/pkg/analysis_server/lib/src/analysis_server.dart
+++ b/pkg/analysis_server/lib/src/analysis_server.dart
@@ -26,7 +26,6 @@
import 'package:analysis_server/src/domain_execution.dart';
import 'package:analysis_server/src/domain_kythe.dart';
import 'package:analysis_server/src/domain_server.dart';
-import 'package:analysis_server/src/domains/analysis/navigation_dart.dart';
import 'package:analysis_server/src/domains/analysis/occurrences.dart';
import 'package:analysis_server/src/domains/analysis/occurrences_dart.dart';
import 'package:analysis_server/src/edit/edit_domain.dart';
@@ -59,6 +58,7 @@
import 'package:analyzer/src/generated/utilities_general.dart';
import 'package:analyzer_plugin/protocol/protocol_common.dart' hide Element;
import 'package:analyzer_plugin/src/utilities/navigation/navigation.dart';
+import 'package:analyzer_plugin/utilities/navigation/navigation_dart.dart';
import 'package:telemetry/crash_reporting.dart';
import 'package:telemetry/telemetry.dart' as telemetry;
import 'package:watcher/watcher.dart';
@@ -597,8 +597,6 @@
}
Future<void> _scheduleAnalysisImplementedNotification() async {
- // TODO(brianwilkerson) Determine whether this await is necessary.
- await null;
var files = analysisServices[AnalysisService.IMPLEMENTED];
if (files != null) {
scheduleImplementedNotification(this, files);
diff --git a/pkg/analysis_server/lib/src/analysis_server_abstract.dart b/pkg/analysis_server/lib/src/analysis_server_abstract.dart
index 98f4efe..c7a9f65 100644
--- a/pkg/analysis_server/lib/src/analysis_server_abstract.dart
+++ b/pkg/analysis_server/lib/src/analysis_server_abstract.dart
@@ -47,10 +47,11 @@
import 'package:analyzer/src/generated/sdk.dart';
import 'package:analyzer/src/services/available_declarations.dart';
import 'package:analyzer/src/util/glob.dart';
+import 'package:nnbd_migration/api_for_analysis_server/driver_provider.dart';
/// Implementations of [AbstractAnalysisServer] implement a server that listens
/// on a [CommunicationChannel] for analysis messages and process them.
-abstract class AbstractAnalysisServer {
+abstract class AbstractAnalysisServer implements DriverProvider {
/// The options of this server instance.
AnalysisServerOptions options;
@@ -127,6 +128,7 @@
];
/// The [ResourceProvider] using which paths are converted into [Resource]s.
+ @override
final OverlayResourceProvider resourceProvider;
/// The next modification stamp for a changed file in the [resourceProvider].
@@ -282,6 +284,10 @@
return null;
}
+ @override
+ AnalysisSession getAnalysisSession(String path) =>
+ getAnalysisDriver(path).currentSession;
+
DartdocDirectiveInfo getDartdocDirectiveInfoFor(ResolvedUnitResult result) {
return declarationsTracker
?.getContext(result.session.analysisContext)
@@ -293,8 +299,6 @@
/// [offset] of the given [file], or with `null` if there is no node at the
/// [offset] or the node does not have an element.
Future<Element> getElementAtOffset(String file, int offset) async {
- // TODO(brianwilkerson) Determine whether this await is necessary.
- await null;
if (!priorityFiles.contains(file)) {
var driver = getAnalysisDriver(file);
if (driver == null) {
@@ -342,8 +346,6 @@
/// given [offset] of the given [file], or with `null` if there is no node as
/// the [offset].
Future<AstNode> getNodeAtOffset(String file, int offset) async {
- // TODO(brianwilkerson) Determine whether this await is necessary.
- await null;
var result = await getResolvedUnit(file);
var unit = result?.unit;
if (unit != null) {
diff --git a/pkg/analysis_server/lib/src/channel/byte_stream_channel.dart b/pkg/analysis_server/lib/src/channel/byte_stream_channel.dart
index 1684533..beb2d8e 100644
--- a/pkg/analysis_server/lib/src/channel/byte_stream_channel.dart
+++ b/pkg/analysis_server/lib/src/channel/byte_stream_channel.dart
@@ -49,8 +49,6 @@
@override
Future<Response> sendRequest(Request request) async {
- // TODO(brianwilkerson) Determine whether this await is necessary.
- await null;
var id = request.id;
output.write(json.encode(request.toJson()) + '\n');
return await responseStream
diff --git a/pkg/analysis_server/lib/src/cider/completion.dart b/pkg/analysis_server/lib/src/cider/completion.dart
index 2e32b66..d44effd 100644
--- a/pkg/analysis_server/lib/src/cider/completion.dart
+++ b/pkg/analysis_server/lib/src/cider/completion.dart
@@ -9,11 +9,13 @@
import 'package:analysis_server/src/services/completion/completion_performance.dart';
import 'package:analysis_server/src/services/completion/dart/completion_manager.dart';
import 'package:analysis_server/src/services/completion/dart/local_library_contributor.dart';
+import 'package:analysis_server/src/services/completion/filtering/fuzzy_matcher.dart';
+import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/element/element.dart' show LibraryElement;
-import 'package:analyzer/source/line_info.dart';
import 'package:analyzer/src/dart/analysis/performance_logger.dart';
import 'package:analyzer/src/dart/micro/resolve_file.dart';
import 'package:analyzer/src/dartdoc/dartdoc_directive_info.dart';
+import 'package:analyzer/src/test_utilities/function_ast_visitor.dart';
import 'package:analyzer_plugin/protocol/protocol_common.dart';
import 'package:meta/meta.dart';
@@ -23,6 +25,7 @@
/// example types and elements.
class CiderCompletionCache {
final Map<String, _CiderImportedLibrarySuggestions> _importedLibraries = {};
+ _LastCompletionResult _lastResult;
}
class CiderCompletionComputer {
@@ -31,22 +34,26 @@
final FileResolver _fileResolver;
DartCompletionRequestImpl _dartCompletionRequest;
- final List<String> _computedImportedLibraries = [];
+
+ /// Paths of imported libraries for which suggestions were (re)computed
+ /// during processing of this request. Does not include libraries that were
+ /// processed during previous requests, and reused from the cache now.
+ @visibleForTesting
+ final List<String> computedImportedLibraries = [];
CiderCompletionComputer(this._logger, this._cache, this._fileResolver);
@deprecated
Future<List<CompletionSuggestion>> compute(String path, int offset) async {
- var file = _fileResolver.resourceProvider.getFile(path);
- var content = file.readAsStringSync();
+ var fileContext = _fileResolver.getFileContext(path);
+ var file = fileContext.file;
- var lineInfo = LineInfo.fromContent(content);
- var location = lineInfo.getLocation(offset);
+ var location = file.lineInfo.getLocation(offset);
var result = await compute2(
path: path,
line: location.lineNumber - 1,
- character: location.columnNumber - 1,
+ column: location.columnNumber - 1,
);
return result.suggestions;
@@ -58,20 +65,37 @@
///
/// The content of the file has already been updated.
///
- /// The [line] and [character] are zero based.
+ /// The [line] and [column] are zero based.
Future<CiderCompletionResult> compute2({
@required String path,
@required int line,
- @required int character,
+ @required int column,
}) async {
- var file = _fileResolver.resourceProvider.getFile(path);
- var content = file.readAsStringSync();
+ var fileContext = _logger.run('Get file $path', () {
+ return _fileResolver.getFileContext(path);
+ });
+
+ var file = fileContext.file;
+
+ var resolvedSignature = _logger.run('Get signature', () {
+ return file.resolvedSignature;
+ });
+
+ var lineInfo = file.lineInfo;
+ var offset = lineInfo.getOffsetOfLine(line) + column;
+
+ // If the same file, in the same state as the last time, reuse the result.
+ var lastResult = _cache._lastResult;
+ if (lastResult != null &&
+ lastResult.path == path &&
+ lastResult.signature == resolvedSignature &&
+ lastResult.offset == offset) {
+ _logger.writeln('Use the last completion result.');
+ return lastResult.result;
+ }
var resolvedUnit = _fileResolver.resolve(path);
- var lineInfo = LineInfo.fromContent(content);
- var offset = lineInfo.getOffsetOfLine(line) + character;
-
var completionRequest = CompletionRequestImpl(
resolvedUnit,
offset,
@@ -100,18 +124,29 @@
dartdocDirectiveInfo,
);
- _logger.run('Add imported suggestions', () {
- suggestions.addAll(
- _importedLibrariesSuggestions(
- resolvedUnit.libraryElement,
- ),
- );
+ if (_dartCompletionRequest.includeIdentifiers) {
+ _logger.run('Add imported suggestions', () {
+ suggestions.addAll(
+ _importedLibrariesSuggestions(
+ resolvedUnit.libraryElement,
+ ),
+ );
+ });
+ }
+
+ _logger.run('Filter suggestions', () {
+ suggestions = _FilterSort(
+ _dartCompletionRequest,
+ suggestions,
+ ).perform();
});
- return CiderCompletionResult._(
- suggestions,
- _computedImportedLibraries,
- );
+ var result = CiderCompletionResult._(suggestions);
+
+ _cache._lastResult =
+ _LastCompletionResult(path, resolvedSignature, offset, result);
+
+ return result;
}
/// Return suggestions from libraries imported into the [target].
@@ -139,7 +174,7 @@
var cacheEntry = _cache._importedLibraries[path];
if (cacheEntry == null || cacheEntry.signature != signature) {
- _computedImportedLibraries.add(path);
+ computedImportedLibraries.add(path);
var suggestions = _librarySuggestions(element);
cacheEntry = _CiderImportedLibrarySuggestions(
signature,
@@ -165,16 +200,7 @@
class CiderCompletionResult {
final List<CompletionSuggestion> suggestions;
- /// Paths of imported libraries for which suggestions were (re)computed
- /// during processing of this request. Does not include libraries that were
- /// processed during previous requests, and reused from the cache now.
- @visibleForTesting
- final List<String> computedImportedLibraries;
-
- CiderCompletionResult._(
- this.suggestions,
- this.computedImportedLibraries,
- );
+ CiderCompletionResult._(this.suggestions);
}
class _CiderImportedLibrarySuggestions {
@@ -183,3 +209,80 @@
_CiderImportedLibrarySuggestions(this.signature, this.suggestions);
}
+
+class _FilterSort {
+ final DartCompletionRequestImpl _request;
+ final List<CompletionSuggestion> _suggestions;
+
+ FuzzyMatcher _matcher;
+
+ _FilterSort(this._request, this._suggestions);
+
+ List<CompletionSuggestion> perform() {
+ var pattern = _matchingPattern();
+ _matcher = FuzzyMatcher(pattern, matchStyle: MatchStyle.SYMBOL);
+
+ var scored = _suggestions
+ .map((e) => _FuzzyScoredSuggestion(e, _score(e)))
+ .where((e) => e.score > 0)
+ .toList();
+
+ scored.sort((a, b) {
+ // Prefer what the user requested by typing.
+ if (a.score > b.score) {
+ return -1;
+ } else if (a.score < b.score) {
+ return 1;
+ }
+
+ // Then prefer what is more relevant in the context.
+ if (a.suggestion.relevance != b.suggestion.relevance) {
+ return -(a.suggestion.relevance - b.suggestion.relevance);
+ }
+
+ // Other things being equal, sort by name.
+ return a.suggestion.completion.compareTo(b.suggestion.completion);
+ });
+
+ return scored.map((e) => e.suggestion).toList();
+ }
+
+ /// Return the pattern to match suggestions against, from the identifier
+ /// to the left of the caret. Return the empty string if cannot find the
+ /// identifier.
+ String _matchingPattern() {
+ SimpleIdentifier patternNode;
+ _request.target.containingNode.accept(
+ FunctionAstVisitor(simpleIdentifier: (node) {
+ if (node.end == _request.offset) {
+ patternNode = node;
+ }
+ }),
+ );
+
+ if (patternNode != null) {
+ return patternNode.name;
+ }
+
+ return '';
+ }
+
+ double _score(CompletionSuggestion e) => _matcher.score(e.completion);
+}
+
+/// [CompletionSuggestion] scored using [FuzzyMatcher].
+class _FuzzyScoredSuggestion {
+ final CompletionSuggestion suggestion;
+ final double score;
+
+ _FuzzyScoredSuggestion(this.suggestion, this.score);
+}
+
+class _LastCompletionResult {
+ final String path;
+ final String signature;
+ final int offset;
+ final CiderCompletionResult result;
+
+ _LastCompletionResult(this.path, this.signature, this.offset, this.result);
+}
diff --git a/pkg/analysis_server/lib/src/computer/import_elements_computer.dart b/pkg/analysis_server/lib/src/computer/import_elements_computer.dart
index 0bab64a..6383a22 100644
--- a/pkg/analysis_server/lib/src/computer/import_elements_computer.dart
+++ b/pkg/analysis_server/lib/src/computer/import_elements_computer.dart
@@ -38,8 +38,6 @@
/// imported into the library at the given [path].
Future<SourceChange> createEdits(
List<ImportedElements> importedElementsList) async {
- // TODO(brianwilkerson) Determine whether this await is necessary.
- await null;
var filteredImportedElements =
_filterImportedElements(importedElementsList);
var libraryElement = libraryResult.libraryElement;
diff --git a/pkg/analysis_server/lib/src/computer/new_notifications.dart b/pkg/analysis_server/lib/src/computer/new_notifications.dart
index 31f80848..e44abed 100644
--- a/pkg/analysis_server/lib/src/computer/new_notifications.dart
+++ b/pkg/analysis_server/lib/src/computer/new_notifications.dart
@@ -4,12 +4,12 @@
import 'package:analysis_server/protocol/protocol_generated.dart' as protocol;
import 'package:analysis_server/src/analysis_server.dart' show AnalysisServer;
-import 'package:analysis_server/src/domains/analysis/navigation_dart.dart';
import 'package:analysis_server/src/domains/analysis/occurrences.dart';
import 'package:analysis_server/src/domains/analysis/occurrences_dart.dart';
import 'package:analysis_server/src/protocol_server.dart' as protocol;
import 'package:analyzer/dart/analysis/results.dart';
import 'package:analyzer_plugin/src/utilities/navigation/navigation.dart';
+import 'package:analyzer_plugin/utilities/navigation/navigation_dart.dart';
void new_sendDartNotificationNavigation(
AnalysisServer analysisServer, ResolvedUnitResult result) {
diff --git a/pkg/analysis_server/lib/src/domain_abstract.dart b/pkg/analysis_server/lib/src/domain_abstract.dart
index fc0b989..a2c28e2 100644
--- a/pkg/analysis_server/lib/src/domain_abstract.dart
+++ b/pkg/analysis_server/lib/src/domain_abstract.dart
@@ -43,8 +43,6 @@
Map<PluginInfo, Future<plugin.Response>> futures,
{plugin.RequestParams requestParameters,
int timeout = 500}) async {
- // TODO(brianwilkerson) Determine whether this await is necessary.
- await null;
// TODO(brianwilkerson) requestParameters might need to be required.
var endTime = DateTime.now().millisecondsSinceEpoch + timeout;
var responses = <plugin.Response>[];
diff --git a/pkg/analysis_server/lib/src/domain_analysis.dart b/pkg/analysis_server/lib/src/domain_analysis.dart
index 6351adc..f6b02a4 100644
--- a/pkg/analysis_server/lib/src/domain_analysis.dart
+++ b/pkg/analysis_server/lib/src/domain_analysis.dart
@@ -11,7 +11,6 @@
import 'package:analysis_server/src/computer/computer_signature.dart';
import 'package:analysis_server/src/computer/imported_elements_computer.dart';
import 'package:analysis_server/src/domain_abstract.dart';
-import 'package:analysis_server/src/domains/analysis/navigation_dart.dart';
import 'package:analysis_server/src/plugin/request_converter.dart';
import 'package:analysis_server/src/plugin/result_merger.dart';
import 'package:analysis_server/src/protocol/protocol_internal.dart';
@@ -24,6 +23,7 @@
import 'package:analyzer_plugin/protocol/protocol_constants.dart' as plugin;
import 'package:analyzer_plugin/protocol/protocol_generated.dart' as plugin;
import 'package:analyzer_plugin/src/utilities/navigation/navigation.dart';
+import 'package:analyzer_plugin/utilities/navigation/navigation_dart.dart';
// TODO(devoncarew): See #31456 for the tracking issue to remove this flag.
final bool disableManageImportsOnPaste = true;
@@ -57,8 +57,6 @@
/// Implement the `analysis.getHover` request.
Future<void> getHover(Request request) async {
- // TODO(brianwilkerson) Determine whether this await is necessary.
- await null;
var params = AnalysisGetHoverParams.fromRequest(request);
var file = params.file;
@@ -87,8 +85,6 @@
/// Implement the `analysis.getImportedElements` request.
Future<void> getImportedElements(Request request) async {
- // TODO(brianwilkerson) Determine whether this await is necessary.
- await null;
var params = AnalysisGetImportedElementsParams.fromRequest(request);
var file = params.file;
@@ -147,8 +143,6 @@
/// Implement the `analysis.getNavigation` request.
Future<void> getNavigation(Request request) async {
- // TODO(brianwilkerson) Determine whether this await is necessary.
- await null;
var params = AnalysisGetNavigationParams.fromRequest(request);
var file = params.file;
var offset = params.offset;
diff --git a/pkg/analysis_server/lib/src/domain_completion.dart b/pkg/analysis_server/lib/src/domain_completion.dart
index 1527b5b..d9ffaca 100644
--- a/pkg/analysis_server/lib/src/domain_completion.dart
+++ b/pkg/analysis_server/lib/src/domain_completion.dart
@@ -69,8 +69,6 @@
Set<String> includedElementNames,
List<IncludedSuggestionRelevanceTag> includedSuggestionRelevanceTags,
) async {
- // TODO(brianwilkerson) Determine whether this await is necessary.
- await null;
//
// Allow plugins to start computing fixes.
//
diff --git a/pkg/analysis_server/lib/src/domain_diagnostic.dart b/pkg/analysis_server/lib/src/domain_diagnostic.dart
index a7faff3..f095fba 100644
--- a/pkg/analysis_server/lib/src/domain_diagnostic.dart
+++ b/pkg/analysis_server/lib/src/domain_diagnostic.dart
@@ -37,8 +37,6 @@
/// Answer the `diagnostic.getServerPort` request.
Future handleGetServerPort(Request request) async {
- // TODO(brianwilkerson) Determine whether this await is necessary.
- await null;
try {
// Open a port (or return the existing one).
var port = await server.diagnosticServer.getServerPort();
diff --git a/pkg/analysis_server/lib/src/domain_execution.dart b/pkg/analysis_server/lib/src/domain_execution.dart
index c22eec5..2e75ddd 100644
--- a/pkg/analysis_server/lib/src/domain_execution.dart
+++ b/pkg/analysis_server/lib/src/domain_execution.dart
@@ -46,8 +46,6 @@
/// Implement the 'execution.getSuggestions' request.
void getSuggestions(Request request) async {
-// // TODO(brianwilkerson) Determine whether this await is necessary.
-// await null;
// var params = new ExecutionGetSuggestionsParams.fromRequest(request);
// var computer = new RuntimeCompletionComputer(
// server.resourceProvider,
diff --git a/pkg/analysis_server/lib/src/domain_kythe.dart b/pkg/analysis_server/lib/src/domain_kythe.dart
index 357e1ae..2937a4d 100644
--- a/pkg/analysis_server/lib/src/domain_kythe.dart
+++ b/pkg/analysis_server/lib/src/domain_kythe.dart
@@ -28,8 +28,6 @@
/// Implement the `kythe.getKytheEntries` request.
Future<void> getKytheEntries(Request request) async {
- // TODO(brianwilkerson) Determine whether this await is necessary.
- await null;
var file = KytheGetKytheEntriesParams.fromRequest(request).file;
var driver = server.getAnalysisDriver(file);
if (driver == null) {
diff --git a/pkg/analysis_server/lib/src/domains/execution/completion.dart b/pkg/analysis_server/lib/src/domains/execution/completion.dart
index 55439af..35b320a 100644
--- a/pkg/analysis_server/lib/src/domains/execution/completion.dart
+++ b/pkg/analysis_server/lib/src/domains/execution/completion.dart
@@ -44,8 +44,6 @@
this.expressions);
Future<RuntimeCompletionResult> compute() async {
- // TODO(brianwilkerson) Determine whether this await is necessary.
- await null;
var contextResult = await analysisDriver.getResult(contextPath);
var session = contextResult.session;
diff --git a/pkg/analysis_server/lib/src/edit/edit_domain.dart b/pkg/analysis_server/lib/src/edit/edit_domain.dart
index 316164d..862fd83 100644
--- a/pkg/analysis_server/lib/src/edit/edit_domain.dart
+++ b/pkg/analysis_server/lib/src/edit/edit_domain.dart
@@ -165,8 +165,6 @@
}
Future getAssists(Request request) async {
- // TODO(brianwilkerson) Determine whether this await is necessary.
- await null;
var params = EditGetAssistsParams.fromRequest(request);
var file = params.file;
var offset = params.offset;
@@ -287,8 +285,6 @@
}
Future getPostfixCompletion(Request request) async {
- // TODO(brianwilkerson) Determine whether this await is necessary.
- await null;
server.options.analytics?.sendEvent('edit', 'getPostfixCompletion');
var params = EditGetPostfixCompletionParams.fromRequest(request);
@@ -319,9 +315,6 @@
}
Future getStatementCompletion(Request request) async {
- // TODO(brianwilkerson) Determine whether this await is necessary.
- await null;
-
var params = EditGetStatementCompletionParams.fromRequest(request);
var file = params.file;
@@ -396,9 +389,6 @@
/// Implement the `edit.importElements` request.
Future<void> importElements(Request request) async {
- // TODO(brianwilkerson) Determine whether this await is necessary.
- await null;
-
var params = EditImportElementsParams.fromRequest(request);
var file = params.file;
@@ -437,8 +427,6 @@
}
Future isPostfixCompletionApplicable(Request request) async {
- // TODO(brianwilkerson) Determine whether this await is necessary.
- await null;
var params = EditGetPostfixCompletionParams.fromRequest(request);
var file = params.file;
@@ -475,8 +463,6 @@
}
Future<void> organizeDirectives(Request request) async {
- // TODO(brianwilkerson) Determine whether this await is necessary.
- await null;
server.options.analytics?.sendEvent('edit', 'organizeDirectives');
var params = EditOrganizeDirectivesParams.fromRequest(request);
@@ -516,8 +502,6 @@
}
Future<void> sortMembers(Request request) async {
- // TODO(brianwilkerson) Determine whether this await is necessary.
- await null;
var params = EditSortMembersParams.fromRequest(request);
var file = params.file;
@@ -922,8 +906,6 @@
}
runZonedGuarded(() async {
- // TODO(brianwilkerson) Determine whether this await is necessary.
- await null;
await _init(params.kind, file, params.offset, params.length);
if (initStatus.hasFatalError) {
feedback = null;
@@ -1013,8 +995,6 @@
/// parameters. The existing [Refactoring] is reused or created as needed.
Future _init(
RefactoringKind kind, String file, int offset, int length) async {
- // TODO(brianwilkerson) Determine whether this await is necessary.
- await null;
// check if we can continue with the existing Refactoring instance
if (this.kind == kind &&
this.file == file &&
diff --git a/pkg/analysis_server/lib/src/edit/fix/dartfix_listener.dart b/pkg/analysis_server/lib/src/edit/fix/dartfix_listener.dart
index a711888..ca028f7 100644
--- a/pkg/analysis_server/lib/src/edit/fix/dartfix_listener.dart
+++ b/pkg/analysis_server/lib/src/edit/fix/dartfix_listener.dart
@@ -8,13 +8,17 @@
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer_plugin/protocol/protocol_common.dart'
show Location, SourceChange, SourceEdit, SourceFileEdit;
+import 'package:nnbd_migration/api_for_analysis_server/dartfix_listener_interface.dart';
/// Tasks use this API to report results.
-class DartFixListener {
+class DartFixListener implements DartFixListenerInterface {
+ @override
final AnalysisServer server;
final List<DartFixSuggestion> suggestions = <DartFixSuggestion>[];
final List<DartFixSuggestion> otherSuggestions = <DartFixSuggestion>[];
+
+ @override
final SourceChange sourceChange = SourceChange('dartfix');
/// The details to be returned to the client.
@@ -24,6 +28,7 @@
/// Add the given [detail] to the list of details to be returned to the
/// client.
+ @override
void addDetail(String detail) {
if (details.length < 200) {
details.add(detail);
@@ -34,11 +39,13 @@
///
/// The associated suggestion should be separately added by calling
/// [addSuggestion].
+ @override
void addEditWithoutSuggestion(Source source, SourceEdit edit) {
sourceChange.addEdit(source.fullName, -1, edit);
}
/// Record a recommendation to be sent to the client.
+ @override
void addRecommendation(String description, [Location location]) {
otherSuggestions.add(DartFixSuggestion(description, location: location));
}
@@ -64,6 +71,7 @@
}
/// Record a source change to be sent to the client.
+ @override
void addSourceFileEdit(
String description, Location location, SourceFileEdit fileEdit) {
suggestions.add(DartFixSuggestion(description, location: location));
@@ -76,6 +84,7 @@
///
/// The associated edits should be separately added by calling
/// [addEditWithoutRecommendation].
+ @override
void addSuggestion(String description, Location location) {
suggestions.add(DartFixSuggestion(description, location: location));
}
diff --git a/pkg/analysis_server/lib/src/edit/fix/non_nullable_fix.dart b/pkg/analysis_server/lib/src/edit/fix/non_nullable_fix.dart
index 3a695592..89432f8 100644
--- a/pkg/analysis_server/lib/src/edit/fix/non_nullable_fix.dart
+++ b/pkg/analysis_server/lib/src/edit/fix/non_nullable_fix.dart
@@ -6,16 +6,17 @@
import 'package:analysis_server/src/edit/fix/dartfix_listener.dart';
import 'package:analysis_server/src/edit/fix/dartfix_registrar.dart';
import 'package:analysis_server/src/edit/fix/fix_code_task.dart';
-import 'package:analysis_server/src/edit/nnbd_migration/instrumentation_listener.dart';
-import 'package:analysis_server/src/edit/nnbd_migration/migration_state.dart';
-import 'package:analysis_server/src/edit/preview/http_preview_server.dart';
import 'package:analyzer/dart/analysis/results.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer_plugin/protocol/protocol_common.dart';
import 'package:charcode/charcode.dart';
-import 'package:nnbd_migration/nnbd_migration.dart';
+import 'package:nnbd_migration/api_for_analysis_server/dartfix_listener_interface.dart';
+import 'package:nnbd_migration/api_for_analysis_server/http_preview_server.dart';
+import 'package:nnbd_migration/api_for_analysis_server/instrumentation_listener.dart';
+import 'package:nnbd_migration/api_for_analysis_server/migration_state.dart';
+import 'package:nnbd_migration/api_for_analysis_server/nnbd_migration.dart';
import 'package:pub_semver/pub_semver.dart';
import 'package:source_span/source_span.dart';
import 'package:yaml/yaml.dart';
@@ -37,7 +38,7 @@
final int preferredPort;
- final DartFixListener listener;
+ final DartFixListenerInterface listener;
/// The root of the included paths.
///
@@ -47,7 +48,7 @@
final String includedRoot;
/// The HTTP server that serves the preview tool.
- HttpPreviewServer server;
+ HttpPreviewServer _server;
/// The port on which preview pages should be served, or `null` if no preview
/// server should be started.
@@ -92,14 +93,14 @@
@override
Future<void> finish() async {
final state = MigrationState(
- migration, includedRoot, listener, instrumentationListener, adapter);
+ migration, includedRoot, listener, instrumentationListener);
await state.refresh();
- if (server == null) {
- server = HttpPreviewServer(state, rerun, preferredPort);
- server.serveHttp();
- port = await server.boundPort;
- authToken = await server.authToken;
+ if (_server == null) {
+ _server = HttpPreviewServer(state, rerun, preferredPort);
+ _server.serveHttp();
+ port = await _server.boundPort;
+ authToken = await _server.authToken;
}
}
@@ -240,7 +241,7 @@
reset();
await rerunFunction(changedPaths);
final state = MigrationState(
- migration, includedRoot, listener, instrumentationListener, adapter);
+ migration, includedRoot, listener, instrumentationListener);
await state.refresh();
return state;
}
@@ -253,6 +254,10 @@
instrumentation: instrumentationListener);
}
+ void shutdownServer() {
+ _server?.close();
+ }
+
static void task(DartFixRegistrar registrar, DartFixListener listener,
EditDartfixParams params) {
registrar.registerCodeTask(NonNullableFix(listener,
@@ -290,7 +295,7 @@
}
class NullabilityMigrationAdapter implements NullabilityMigrationListener {
- final DartFixListener listener;
+ final DartFixListenerInterface listener;
NullabilityMigrationAdapter(this.listener);
diff --git a/pkg/analysis_server/lib/src/edit/nnbd_migration/resources/resources.g.dart b/pkg/analysis_server/lib/src/edit/nnbd_migration/resources/resources.g.dart
deleted file mode 100644
index fa4b09e..0000000
--- a/pkg/analysis_server/lib/src/edit/nnbd_migration/resources/resources.g.dart
+++ /dev/null
@@ -1,4839 +0,0 @@
-// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// This file is generated; don't edit it directly.
-//
-// See pkg/analysis_server/tool/nnbd_migration/generate_resources.dart for how
-// to edit the source content and for re-generation instructions.
-
-import 'dart:convert' as convert;
-
-String get highlight_css {
- return _highlight_css ??= _decode(_highlight_css_base64);
-}
-
-String get highlight_pack_js {
- return _highlight_pack_js ??= _decode(_highlight_pack_js_base64);
-}
-
-String get index_html {
- return _index_html ??= _decode(_index_html_base64);
-}
-
-String get migration_css {
- return _migration_css ??= _decode(_migration_css_base64);
-}
-
-String get migration_js {
- return _migration_js ??= _decode(_migration_js_base64);
-}
-
-String _decode(String data) {
- data = data.replaceAll('\n', '').trim();
- return String.fromCharCodes(convert.base64Decode(data));
-}
-
-String _highlight_css;
-// highlight_css md5 is 'fb012626bafd286510d32da815dae448'
-String _highlight_css_base64 = '''
-LyoKRGF0ZTogMjQgRmV2IDIwMTUKQXV0aG9yOiBQZWRybyBPbGl2ZWlyYSA8a2FueXR1QGdtYWlsIC4g
-Y29tPgoqLwoKLmhsanMgewogIGNvbG9yOiAjYTliN2M2OwogIGJhY2tncm91bmQ6ICMyODJiMmU7CiAg
-ZGlzcGxheTogYmxvY2s7CiAgb3ZlcmZsb3cteDogYXV0bzsKICBwYWRkaW5nOiAwLjVlbTsKfQoKLmhs
-anMtbnVtYmVyLAouaGxqcy1saXRlcmFsLAouaGxqcy1zeW1ib2wsCi5obGpzLWJ1bGxldCB7CiAgY29s
-b3I6ICM2ODk3QkI7Cn0KCi5obGpzLWtleXdvcmQsCi5obGpzLXNlbGVjdG9yLXRhZywKLmhsanMtZGVs
-ZXRpb24gewogIGNvbG9yOiAjY2M3ODMyOwp9CgouaGxqcy12YXJpYWJsZSwKLmhsanMtdGVtcGxhdGUt
-dmFyaWFibGUsCi5obGpzLWxpbmsgewogIGNvbG9yOiAjNjI5NzU1Owp9CgouaGxqcy1jb21tZW50LAou
-aGxqcy1xdW90ZSB7CiAgY29sb3I6ICM4MDgwODA7Cn0KCi5obGpzLW1ldGEgewogIGNvbG9yOiAjYmJi
-NTI5Owp9CgouaGxqcy1zdHJpbmcsCi5obGpzLWF0dHJpYnV0ZSwKLmhsanMtYWRkaXRpb24gewogIGNv
-bG9yOiAjNkE4NzU5Owp9CgouaGxqcy1zZWN0aW9uLAouaGxqcy10aXRsZSwKLmhsanMtdHlwZSB7CiAg
-Y29sb3I6ICNmZmM2NmQ7Cn0KCi5obGpzLW5hbWUsCi5obGpzLXNlbGVjdG9yLWlkLAouaGxqcy1zZWxl
-Y3Rvci1jbGFzcyB7CiAgY29sb3I6ICNlOGJmNmE7Cn0KCi5obGpzLWVtcGhhc2lzIHsKICBmb250LXN0
-eWxlOiBpdGFsaWM7Cn0KCi5obGpzLXN0cm9uZyB7CiAgZm9udC13ZWlnaHQ6IGJvbGQ7Cn0K
-''';
-
-String _highlight_pack_js;
-// highlight_pack_js md5 is '9104bfe8b056f8e00da50b0ea3d6e6d4'
-String _highlight_pack_js_base64 = '''
-LyohIGhpZ2hsaWdodC5qcyB2OS4xNS4xMCB8IEJTRDMgTGljZW5zZSB8IGdpdC5pby9obGpzbGljZW5z
-ZSAqLwohZnVuY3Rpb24oZSl7dmFyIG49Im9iamVjdCI9PXR5cGVvZiB3aW5kb3cmJndpbmRvd3x8Im9i
-amVjdCI9PXR5cGVvZiBzZWxmJiZzZWxmOyJ1bmRlZmluZWQiPT10eXBlb2YgZXhwb3J0c3x8ZXhwb3J0
-cy5ub2RlVHlwZT9uJiYobi5obGpzPWUoe30pLCJmdW5jdGlvbiI9PXR5cGVvZiBkZWZpbmUmJmRlZmlu
-ZS5hbWQmJmRlZmluZShbXSxmdW5jdGlvbigpe3JldHVybiBuLmhsanN9KSk6ZShleHBvcnRzKX0oZnVu
-Y3Rpb24oYSl7dmFyIGY9W10sdT1PYmplY3Qua2V5cyxOPXt9LGM9e30sbj0vXihuby0/aGlnaGxpZ2h0
-fHBsYWlufHRleHQpJC9pLHM9L1xibGFuZyg/OnVhZ2UpPy0oW1x3LV0rKVxiL2ksdD0vKCheKDxbXj5d
-Kz58XHR8KSt8KD86XG4pKSkvZ20scj17Y2FzZV9pbnNlbnNpdGl2ZToiY0kiLGxleGVtZXM6ImwiLGNv
-bnRhaW5zOiJjIixrZXl3b3JkczoiayIsc3ViTGFuZ3VhZ2U6InNMIixjbGFzc05hbWU6ImNOIixiZWdp
-bjoiYiIsYmVnaW5LZXl3b3JkczoiYksiLGVuZDoiZSIsZW5kc1dpdGhQYXJlbnQ6ImVXIixpbGxlZ2Fs
-OiJpIixleGNsdWRlQmVnaW46ImVCIixleGNsdWRlRW5kOiJlRSIscmV0dXJuQmVnaW46InJCIixyZXR1
-cm5FbmQ6InJFIixyZWxldmFuY2U6InIiLHZhcmlhbnRzOiJ2IixJREVOVF9SRToiSVIiLFVOREVSU0NP
-UkVfSURFTlRfUkU6IlVJUiIsTlVNQkVSX1JFOiJOUiIsQ19OVU1CRVJfUkU6IkNOUiIsQklOQVJZX05V
-TUJFUl9SRToiQk5SIixSRV9TVEFSVEVSU19SRToiUlNSIixCQUNLU0xBU0hfRVNDQVBFOiJCRSIsQVBP
-U19TVFJJTkdfTU9ERToiQVNNIixRVU9URV9TVFJJTkdfTU9ERToiUVNNIixQSFJBU0FMX1dPUkRTX01P
-REU6IlBXTSIsQ19MSU5FX0NPTU1FTlRfTU9ERToiQ0xDTSIsQ19CTE9DS19DT01NRU5UX01PREU6IkNC
-Q00iLEhBU0hfQ09NTUVOVF9NT0RFOiJIQ00iLE5VTUJFUl9NT0RFOiJOTSIsQ19OVU1CRVJfTU9ERToi
-Q05NIixCSU5BUllfTlVNQkVSX01PREU6IkJOTSIsQ1NTX05VTUJFUl9NT0RFOiJDU1NOTSIsUkVHRVhQ
-X01PREU6IlJNIixUSVRMRV9NT0RFOiJUTSIsVU5ERVJTQ09SRV9USVRMRV9NT0RFOiJVVE0iLENPTU1F
-TlQ6IkMiLGJlZ2luUmU6ImJSIixlbmRSZToiZVIiLGlsbGVnYWxSZToiaVIiLGxleGVtZXNSZToibFIi
-LHRlcm1pbmF0b3JzOiJ0Iix0ZXJtaW5hdG9yX2VuZDoidEUifSxiPSI8L3NwYW4+IixoPXtjbGFzc1By
-ZWZpeDoiaGxqcy0iLHRhYlJlcGxhY2U6bnVsbCx1c2VCUjohMSxsYW5ndWFnZXM6dm9pZCAwfTtmdW5j
-dGlvbiBfKGUpe3JldHVybiBlLnJlcGxhY2UoLyYvZywiJmFtcDsiKS5yZXBsYWNlKC88L2csIiZsdDsi
-KS5yZXBsYWNlKC8+L2csIiZndDsiKX1mdW5jdGlvbiBFKGUpe3JldHVybiBlLm5vZGVOYW1lLnRvTG93
-ZXJDYXNlKCl9ZnVuY3Rpb24gdihlLG4pe3ZhciB0PWUmJmUuZXhlYyhuKTtyZXR1cm4gdCYmMD09PXQu
-aW5kZXh9ZnVuY3Rpb24gbChlKXtyZXR1cm4gbi50ZXN0KGUpfWZ1bmN0aW9uIGcoZSl7dmFyIG4sdD17
-fSxyPUFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywxKTtmb3IobiBpbiBlKXRbbl09
-ZVtuXTtyZXR1cm4gci5mb3JFYWNoKGZ1bmN0aW9uKGUpe2ZvcihuIGluIGUpdFtuXT1lW25dfSksdH1m
-dW5jdGlvbiBSKGUpe3ZhciBhPVtdO3JldHVybiBmdW5jdGlvbiBlKG4sdCl7Zm9yKHZhciByPW4uZmly
-c3RDaGlsZDtyO3I9ci5uZXh0U2libGluZykzPT09ci5ub2RlVHlwZT90Kz1yLm5vZGVWYWx1ZS5sZW5n
-dGg6MT09PXIubm9kZVR5cGUmJihhLnB1c2goe2V2ZW50OiJzdGFydCIsb2Zmc2V0OnQsbm9kZTpyfSks
-dD1lKHIsdCksRShyKS5tYXRjaCgvYnJ8aHJ8aW1nfGlucHV0Lyl8fGEucHVzaCh7ZXZlbnQ6InN0b3Ai
-LG9mZnNldDp0LG5vZGU6cn0pKTtyZXR1cm4gdH0oZSwwKSxhfWZ1bmN0aW9uIGkoZSl7aWYociYmIWUu
-bGFuZ0FwaVJlc3RvcmVkKXtmb3IodmFyIG4gaW4gZS5sYW5nQXBpUmVzdG9yZWQ9ITAscillW25dJiYo
-ZVtyW25dXT1lW25dKTsoZS5jfHxbXSkuY29uY2F0KGUudnx8W10pLmZvckVhY2goaSl9fWZ1bmN0aW9u
-IG0obyl7ZnVuY3Rpb24gcyhlKXtyZXR1cm4gZSYmZS5zb3VyY2V8fGV9ZnVuY3Rpb24gYyhlLG4pe3Jl
-dHVybiBuZXcgUmVnRXhwKHMoZSksIm0iKyhvLmNJPyJpIjoiIikrKG4/ImciOiIiKSl9IWZ1bmN0aW9u
-IG4odCxlKXtpZighdC5jb21waWxlZCl7aWYodC5jb21waWxlZD0hMCx0Lms9dC5rfHx0LmJLLHQuayl7
-ZnVuY3Rpb24gcih0LGUpe28uY0kmJihlPWUudG9Mb3dlckNhc2UoKSksZS5zcGxpdCgiICIpLmZvckVh
-Y2goZnVuY3Rpb24oZSl7dmFyIG49ZS5zcGxpdCgifCIpO2FbblswXV09W3QsblsxXT9OdW1iZXIoblsx
-XSk6MV19KX12YXIgYT17fTsic3RyaW5nIj09dHlwZW9mIHQuaz9yKCJrZXl3b3JkIix0LmspOnUodC5r
-KS5mb3JFYWNoKGZ1bmN0aW9uKGUpe3IoZSx0LmtbZV0pfSksdC5rPWF9dC5sUj1jKHQubHx8L1x3Ky8s
-ITApLGUmJih0LmJLJiYodC5iPSJcXGIoIit0LmJLLnNwbGl0KCIgIikuam9pbigifCIpKyIpXFxiIiks
-dC5ifHwodC5iPS9cQnxcYi8pLHQuYlI9Yyh0LmIpLHQuZW5kU2FtZUFzQmVnaW4mJih0LmU9dC5iKSx0
-LmV8fHQuZVd8fCh0LmU9L1xCfFxiLyksdC5lJiYodC5lUj1jKHQuZSkpLHQudEU9cyh0LmUpfHwiIix0
-LmVXJiZlLnRFJiYodC50RSs9KHQuZT8ifCI6IiIpK2UudEUpKSx0LmkmJih0LmlSPWModC5pKSksbnVs
-bD09dC5yJiYodC5yPTEpLHQuY3x8KHQuYz1bXSksdC5jPUFycmF5LnByb3RvdHlwZS5jb25jYXQuYXBw
-bHkoW10sdC5jLm1hcChmdW5jdGlvbihlKXtyZXR1cm4gZnVuY3Rpb24obil7cmV0dXJuIG4udiYmIW4u
-Y2FjaGVkX3ZhcmlhbnRzJiYobi5jYWNoZWRfdmFyaWFudHM9bi52Lm1hcChmdW5jdGlvbihlKXtyZXR1
-cm4gZyhuLHt2Om51bGx9LGUpfSkpLG4uY2FjaGVkX3ZhcmlhbnRzfHxuLmVXJiZbZyhuKV18fFtuXX0o
-InNlbGYiPT09ZT90OmUpfSkpLHQuYy5mb3JFYWNoKGZ1bmN0aW9uKGUpe24oZSx0KX0pLHQuc3RhcnRz
-JiZuKHQuc3RhcnRzLGUpO3ZhciBpPXQuYy5tYXAoZnVuY3Rpb24oZSl7cmV0dXJuIGUuYks/IlxcLj8o
-PzoiK2UuYisiKVxcLj8iOmUuYn0pLmNvbmNhdChbdC50RSx0LmldKS5tYXAocykuZmlsdGVyKEJvb2xl
-YW4pO3QudD1pLmxlbmd0aD9jKGZ1bmN0aW9uKGUsbil7Zm9yKHZhciB0PS9cWyg/OlteXFxcXV18XFwu
-KSpcXXxcKFw/P3xcXChbMS05XVswLTldKil8XFwuLyxyPTAsYT0iIixpPTA7aTxlLmxlbmd0aDtpKysp
-e3ZhciBvPXIsYz1zKGVbaV0pO2ZvcigwPGkmJihhKz1uKTswPGMubGVuZ3RoOyl7dmFyIHU9dC5leGVj
-KGMpO2lmKG51bGw9PXUpe2ErPWM7YnJlYWt9YSs9Yy5zdWJzdHJpbmcoMCx1LmluZGV4KSxjPWMuc3Vi
-c3RyaW5nKHUuaW5kZXgrdVswXS5sZW5ndGgpLCJcXCI9PXVbMF1bMF0mJnVbMV0/YSs9IlxcIitTdHJp
-bmcoTnVtYmVyKHVbMV0pK28pOihhKz11WzBdLCIoIj09dVswXSYmcisrKX19cmV0dXJuIGF9KGksInwi
-KSwhMCk6e2V4ZWM6ZnVuY3Rpb24oKXtyZXR1cm4gbnVsbH19fX0obyl9ZnVuY3Rpb24gQyhlLG4saSx0
-KXtmdW5jdGlvbiBjKGUsbix0LHIpe3ZhciBhPSc8c3BhbiBjbGFzcz0iJysocj8iIjpoLmNsYXNzUHJl
-Zml4KTtyZXR1cm4gZT8oYSs9ZSsnIj4nKStuKyh0PyIiOmIpOm59ZnVuY3Rpb24gbygpe0UrPW51bGwh
-PWwuc0w/ZnVuY3Rpb24oKXt2YXIgZT0ic3RyaW5nIj09dHlwZW9mIGwuc0w7aWYoZSYmIU5bbC5zTF0p
-cmV0dXJuIF8oZyk7dmFyIG49ZT9DKGwuc0wsZywhMCxmW2wuc0xdKTpPKGcsbC5zTC5sZW5ndGg/bC5z
-TDp2b2lkIDApO3JldHVybiAwPGwuciYmKFIrPW4uciksZSYmKGZbbC5zTF09bi50b3ApLGMobi5sYW5n
-dWFnZSxuLnZhbHVlLCExLCEwKX0oKTpmdW5jdGlvbigpe3ZhciBlLG4sdCxyLGEsaSxvO2lmKCFsLmsp
-cmV0dXJuIF8oZyk7Zm9yKHI9IiIsbj0wLGwubFIubGFzdEluZGV4PTAsdD1sLmxSLmV4ZWMoZyk7dDsp
-cis9XyhnLnN1YnN0cmluZyhuLHQuaW5kZXgpKSxhPWwsaT10LHZvaWQgMCxvPXMuY0k/aVswXS50b0xv
-d2VyQ2FzZSgpOmlbMF0sKGU9YS5rLmhhc093blByb3BlcnR5KG8pJiZhLmtbb10pPyhSKz1lWzFdLHIr
-PWMoZVswXSxfKHRbMF0pKSk6cis9Xyh0WzBdKSxuPWwubFIubGFzdEluZGV4LHQ9bC5sUi5leGVjKGcp
-O3JldHVybiByK18oZy5zdWJzdHIobikpfSgpLGc9IiJ9ZnVuY3Rpb24gdShlKXtFKz1lLmNOP2MoZS5j
-TiwiIiwhMCk6IiIsbD1PYmplY3QuY3JlYXRlKGUse3BhcmVudDp7dmFsdWU6bH19KX1mdW5jdGlvbiBy
-KGUsbil7aWYoZys9ZSxudWxsPT1uKXJldHVybiBvKCksMDt2YXIgdD1mdW5jdGlvbihlLG4pe3ZhciB0
-LHIsYTtmb3IodD0wLHI9bi5jLmxlbmd0aDt0PHI7dCsrKWlmKHYobi5jW3RdLmJSLGUpKXJldHVybiBu
-LmNbdF0uZW5kU2FtZUFzQmVnaW4mJihuLmNbdF0uZVI9KGE9bi5jW3RdLmJSLmV4ZWMoZSlbMF0sbmV3
-IFJlZ0V4cChhLnJlcGxhY2UoL1stXC9cXF4kKis/LigpfFtcXXt9XS9nLCJcXCQmIiksIm0iKSkpLG4u
-Y1t0XX0obixsKTtpZih0KXJldHVybiB0LnNraXA/Zys9bjoodC5lQiYmKGcrPW4pLG8oKSx0LnJCfHx0
-LmVCfHwoZz1uKSksdSh0KSx0LnJCPzA6bi5sZW5ndGg7dmFyIHI9ZnVuY3Rpb24gZShuLHQpe2lmKHYo
-bi5lUix0KSl7Zm9yKDtuLmVuZHNQYXJlbnQmJm4ucGFyZW50OyluPW4ucGFyZW50O3JldHVybiBufWlm
-KG4uZVcpcmV0dXJuIGUobi5wYXJlbnQsdCl9KGwsbik7aWYocil7dmFyIGE9bDtmb3IoYS5za2lwP2cr
-PW46KGEuckV8fGEuZUV8fChnKz1uKSxvKCksYS5lRSYmKGc9bikpO2wuY04mJihFKz1iKSxsLnNraXB8
-fGwuc0x8fChSKz1sLnIpLChsPWwucGFyZW50KSE9PXIucGFyZW50Oyk7cmV0dXJuIHIuc3RhcnRzJiYo
-ci5lbmRTYW1lQXNCZWdpbiYmKHIuc3RhcnRzLmVSPXIuZVIpLHUoci5zdGFydHMpKSxhLnJFPzA6bi5s
-ZW5ndGh9aWYoZnVuY3Rpb24oZSxuKXtyZXR1cm4haSYmdihuLmlSLGUpfShuLGwpKXRocm93IG5ldyBF
-cnJvcignSWxsZWdhbCBsZXhlbWUgIicrbisnIiBmb3IgbW9kZSAiJysobC5jTnx8Ijx1bm5hbWVkPiIp
-KyciJyk7cmV0dXJuIGcrPW4sbi5sZW5ndGh8fDF9dmFyIHM9QihlKTtpZighcyl0aHJvdyBuZXcgRXJy
-b3IoJ1Vua25vd24gbGFuZ3VhZ2U6ICInK2UrJyInKTttKHMpO3ZhciBhLGw9dHx8cyxmPXt9LEU9IiI7
-Zm9yKGE9bDthIT09czthPWEucGFyZW50KWEuY04mJihFPWMoYS5jTiwiIiwhMCkrRSk7dmFyIGc9IiIs
-Uj0wO3RyeXtmb3IodmFyIGQscCxNPTA7bC50Lmxhc3RJbmRleD1NLGQ9bC50LmV4ZWMobik7KXA9cihu
-LnN1YnN0cmluZyhNLGQuaW5kZXgpLGRbMF0pLE09ZC5pbmRleCtwO2ZvcihyKG4uc3Vic3RyKE0pKSxh
-PWw7YS5wYXJlbnQ7YT1hLnBhcmVudClhLmNOJiYoRSs9Yik7cmV0dXJue3I6Uix2YWx1ZTpFLGxhbmd1
-YWdlOmUsdG9wOmx9fWNhdGNoKGUpe2lmKGUubWVzc2FnZSYmLTEhPT1lLm1lc3NhZ2UuaW5kZXhPZigi
-SWxsZWdhbCIpKXJldHVybntyOjAsdmFsdWU6XyhuKX07dGhyb3cgZX19ZnVuY3Rpb24gTyh0LGUpe2U9
-ZXx8aC5sYW5ndWFnZXN8fHUoTik7dmFyIHI9e3I6MCx2YWx1ZTpfKHQpfSxhPXI7cmV0dXJuIGUuZmls
-dGVyKEIpLmZpbHRlcihNKS5mb3JFYWNoKGZ1bmN0aW9uKGUpe3ZhciBuPUMoZSx0LCExKTtuLmxhbmd1
-YWdlPWUsbi5yPmEuciYmKGE9biksbi5yPnIuciYmKGE9cixyPW4pfSksYS5sYW5ndWFnZSYmKHIuc2Vj
-b25kX2Jlc3Q9YSkscn1mdW5jdGlvbiBkKGUpe3JldHVybiBoLnRhYlJlcGxhY2V8fGgudXNlQlI/ZS5y
-ZXBsYWNlKHQsZnVuY3Rpb24oZSxuKXtyZXR1cm4gaC51c2VCUiYmIlxuIj09PWU/Ijxicj4iOmgudGFi
-UmVwbGFjZT9uLnJlcGxhY2UoL1x0L2csaC50YWJSZXBsYWNlKToiIn0pOmV9ZnVuY3Rpb24gbyhlKXt2
-YXIgbix0LHIsYSxpLG89ZnVuY3Rpb24oZSl7dmFyIG4sdCxyLGEsaT1lLmNsYXNzTmFtZSsiICI7aWYo
-aSs9ZS5wYXJlbnROb2RlP2UucGFyZW50Tm9kZS5jbGFzc05hbWU6IiIsdD1zLmV4ZWMoaSkpcmV0dXJu
-IEIodFsxXSk/dFsxXToibm8taGlnaGxpZ2h0Ijtmb3Iobj0wLHI9KGk9aS5zcGxpdCgvXHMrLykpLmxl
-bmd0aDtuPHI7bisrKWlmKGwoYT1pW25dKXx8QihhKSlyZXR1cm4gYX0oZSk7bChvKXx8KGgudXNlQlI/
-KG49ZG9jdW1lbnQuY3JlYXRlRWxlbWVudE5TKCJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hodG1sIiwi
-ZGl2IikpLmlubmVySFRNTD1lLmlubmVySFRNTC5yZXBsYWNlKC9cbi9nLCIiKS5yZXBsYWNlKC88YnJb
-IFwvXSo+L2csIlxuIik6bj1lLGk9bi50ZXh0Q29udGVudCxyPW8/QyhvLGksITApOk8oaSksKHQ9Uihu
-KSkubGVuZ3RoJiYoKGE9ZG9jdW1lbnQuY3JlYXRlRWxlbWVudE5TKCJodHRwOi8vd3d3LnczLm9yZy8x
-OTk5L3hodG1sIiwiZGl2IikpLmlubmVySFRNTD1yLnZhbHVlLHIudmFsdWU9ZnVuY3Rpb24oZSxuLHQp
-e3ZhciByPTAsYT0iIixpPVtdO2Z1bmN0aW9uIG8oKXtyZXR1cm4gZS5sZW5ndGgmJm4ubGVuZ3RoP2Vb
-MF0ub2Zmc2V0IT09blswXS5vZmZzZXQ/ZVswXS5vZmZzZXQ8blswXS5vZmZzZXQ/ZTpuOiJzdGFydCI9
-PT1uWzBdLmV2ZW50P2U6bjplLmxlbmd0aD9lOm59ZnVuY3Rpb24gYyhlKXthKz0iPCIrRShlKStmLm1h
-cC5jYWxsKGUuYXR0cmlidXRlcyxmdW5jdGlvbihlKXtyZXR1cm4iICIrZS5ub2RlTmFtZSsnPSInK18o
-ZS52YWx1ZSkucmVwbGFjZSgnIicsIiZxdW90OyIpKyciJ30pLmpvaW4oIiIpKyI+In1mdW5jdGlvbiB1
-KGUpe2ErPSI8LyIrRShlKSsiPiJ9ZnVuY3Rpb24gcyhlKXsoInN0YXJ0Ij09PWUuZXZlbnQ/Yzp1KShl
-Lm5vZGUpfWZvcig7ZS5sZW5ndGh8fG4ubGVuZ3RoOyl7dmFyIGw9bygpO2lmKGErPV8odC5zdWJzdHJp
-bmcocixsWzBdLm9mZnNldCkpLHI9bFswXS5vZmZzZXQsbD09PWUpe2ZvcihpLnJldmVyc2UoKS5mb3JF
-YWNoKHUpO3MobC5zcGxpY2UoMCwxKVswXSksKGw9bygpKT09PWUmJmwubGVuZ3RoJiZsWzBdLm9mZnNl
-dD09PXI7KTtpLnJldmVyc2UoKS5mb3JFYWNoKGMpfWVsc2Uic3RhcnQiPT09bFswXS5ldmVudD9pLnB1
-c2gobFswXS5ub2RlKTppLnBvcCgpLHMobC5zcGxpY2UoMCwxKVswXSl9cmV0dXJuIGErXyh0LnN1YnN0
-cihyKSl9KHQsUihhKSxpKSksci52YWx1ZT1kKHIudmFsdWUpLGUuaW5uZXJIVE1MPXIudmFsdWUsZS5j
-bGFzc05hbWU9ZnVuY3Rpb24oZSxuLHQpe3ZhciByPW4/Y1tuXTp0LGE9W2UudHJpbSgpXTtyZXR1cm4g
-ZS5tYXRjaCgvXGJobGpzXGIvKXx8YS5wdXNoKCJobGpzIiksLTE9PT1lLmluZGV4T2YocikmJmEucHVz
-aChyKSxhLmpvaW4oIiAiKS50cmltKCl9KGUuY2xhc3NOYW1lLG8sci5sYW5ndWFnZSksZS5yZXN1bHQ9
-e2xhbmd1YWdlOnIubGFuZ3VhZ2UscmU6ci5yfSxyLnNlY29uZF9iZXN0JiYoZS5zZWNvbmRfYmVzdD17
-bGFuZ3VhZ2U6ci5zZWNvbmRfYmVzdC5sYW5ndWFnZSxyZTpyLnNlY29uZF9iZXN0LnJ9KSl9ZnVuY3Rp
-b24gcCgpe2lmKCFwLmNhbGxlZCl7cC5jYWxsZWQ9ITA7dmFyIGU9ZG9jdW1lbnQucXVlcnlTZWxlY3Rv
-ckFsbCgicHJlIGNvZGUiKTtmLmZvckVhY2guY2FsbChlLG8pfX1mdW5jdGlvbiBCKGUpe3JldHVybiBl
-PShlfHwiIikudG9Mb3dlckNhc2UoKSxOW2VdfHxOW2NbZV1dfWZ1bmN0aW9uIE0oZSl7dmFyIG49Qihl
-KTtyZXR1cm4gbiYmIW4uZGlzYWJsZUF1dG9kZXRlY3R9cmV0dXJuIGEuaGlnaGxpZ2h0PUMsYS5oaWdo
-bGlnaHRBdXRvPU8sYS5maXhNYXJrdXA9ZCxhLmhpZ2hsaWdodEJsb2NrPW8sYS5jb25maWd1cmU9ZnVu
-Y3Rpb24oZSl7aD1nKGgsZSl9LGEuaW5pdEhpZ2hsaWdodGluZz1wLGEuaW5pdEhpZ2hsaWdodGluZ09u
-TG9hZD1mdW5jdGlvbigpe2FkZEV2ZW50TGlzdGVuZXIoIkRPTUNvbnRlbnRMb2FkZWQiLHAsITEpLGFk
-ZEV2ZW50TGlzdGVuZXIoImxvYWQiLHAsITEpfSxhLnJlZ2lzdGVyTGFuZ3VhZ2U9ZnVuY3Rpb24obixl
-KXt2YXIgdD1OW25dPWUoYSk7aSh0KSx0LmFsaWFzZXMmJnQuYWxpYXNlcy5mb3JFYWNoKGZ1bmN0aW9u
-KGUpe2NbZV09bn0pfSxhLmxpc3RMYW5ndWFnZXM9ZnVuY3Rpb24oKXtyZXR1cm4gdShOKX0sYS5nZXRM
-YW5ndWFnZT1CLGEuYXV0b0RldGVjdGlvbj1NLGEuaW5oZXJpdD1nLGEuSVI9YS5JREVOVF9SRT0iW2Et
-ekEtWl1cXHcqIixhLlVJUj1hLlVOREVSU0NPUkVfSURFTlRfUkU9IlthLXpBLVpfXVxcdyoiLGEuTlI9
-YS5OVU1CRVJfUkU9IlxcYlxcZCsoXFwuXFxkKyk/IixhLkNOUj1hLkNfTlVNQkVSX1JFPSIoLT8pKFxc
-YjBbeFhdW2EtZkEtRjAtOV0rfChcXGJcXGQrKFxcLlxcZCopP3xcXC5cXGQrKShbZUVdWy0rXT9cXGQr
-KT8pIixhLkJOUj1hLkJJTkFSWV9OVU1CRVJfUkU9IlxcYigwYlswMV0rKSIsYS5SU1I9YS5SRV9TVEFS
-VEVSU19SRT0iIXwhPXwhPT18JXwlPXwmfCYmfCY9fFxcKnxcXCo9fFxcK3xcXCs9fCx8LXwtPXwvPXwv
-fDp8O3w8PHw8PD18PD18PHw9PT18PT18PXw+Pj49fD4+PXw+PXw+Pj58Pj58PnxcXD98XFxbfFxce3xc
-XCh8XFxefFxcXj18XFx8fFxcfD18XFx8XFx8fH4iLGEuQkU9YS5CQUNLU0xBU0hfRVNDQVBFPXtiOiJc
-XFxcW1xcc1xcU10iLHI6MH0sYS5BU009YS5BUE9TX1NUUklOR19NT0RFPXtjTjoic3RyaW5nIixiOiIn
-IixlOiInIixpOiJcXG4iLGM6W2EuQkVdfSxhLlFTTT1hLlFVT1RFX1NUUklOR19NT0RFPXtjTjoic3Ry
-aW5nIixiOiciJyxlOiciJyxpOiJcXG4iLGM6W2EuQkVdfSxhLlBXTT1hLlBIUkFTQUxfV09SRFNfTU9E
-RT17YjovXGIoYXxhbnx0aGV8YXJlfEknbXxpc24ndHxkb24ndHxkb2Vzbid0fHdvbid0fGJ1dHxqdXN0
-fHNob3VsZHxwcmV0dHl8c2ltcGx5fGVub3VnaHxnb25uYXxnb2luZ3x3dGZ8c298c3VjaHx3aWxsfHlv
-dXx5b3VyfHRoZXl8bGlrZXxtb3JlKVxiL30sYS5DPWEuQ09NTUVOVD1mdW5jdGlvbihlLG4sdCl7dmFy
-IHI9YS5pbmhlcml0KHtjTjoiY29tbWVudCIsYjplLGU6bixjOltdfSx0fHx7fSk7cmV0dXJuIHIuYy5w
-dXNoKGEuUFdNKSxyLmMucHVzaCh7Y046ImRvY3RhZyIsYjoiKD86VE9ET3xGSVhNRXxOT1RFfEJVR3xY
-WFgpOiIscjowfSkscn0sYS5DTENNPWEuQ19MSU5FX0NPTU1FTlRfTU9ERT1hLkMoIi8vIiwiJCIpLGEu
-Q0JDTT1hLkNfQkxPQ0tfQ09NTUVOVF9NT0RFPWEuQygiL1xcKiIsIlxcKi8iKSxhLkhDTT1hLkhBU0hf
-Q09NTUVOVF9NT0RFPWEuQygiIyIsIiQiKSxhLk5NPWEuTlVNQkVSX01PREU9e2NOOiJudW1iZXIiLGI6
-YS5OUixyOjB9LGEuQ05NPWEuQ19OVU1CRVJfTU9ERT17Y046Im51bWJlciIsYjphLkNOUixyOjB9LGEu
-Qk5NPWEuQklOQVJZX05VTUJFUl9NT0RFPXtjTjoibnVtYmVyIixiOmEuQk5SLHI6MH0sYS5DU1NOTT1h
-LkNTU19OVU1CRVJfTU9ERT17Y046Im51bWJlciIsYjphLk5SKyIoJXxlbXxleHxjaHxyZW18dnd8dmh8
-dm1pbnx2bWF4fGNtfG1tfGlufHB0fHBjfHB4fGRlZ3xncmFkfHJhZHx0dXJufHN8bXN8SHp8a0h6fGRw
-aXxkcGNtfGRwcHgpPyIscjowfSxhLlJNPWEuUkVHRVhQX01PREU9e2NOOiJyZWdleHAiLGI6L1wvLyxl
-Oi9cL1tnaW11eV0qLyxpOi9cbi8sYzpbYS5CRSx7YjovXFsvLGU6L1xdLyxyOjAsYzpbYS5CRV19XX0s
-YS5UTT1hLlRJVExFX01PREU9e2NOOiJ0aXRsZSIsYjphLklSLHI6MH0sYS5VVE09YS5VTkRFUlNDT1JF
-X1RJVExFX01PREU9e2NOOiJ0aXRsZSIsYjphLlVJUixyOjB9LGEuTUVUSE9EX0dVQVJEPXtiOiJcXC5c
-XHMqIithLlVJUixyOjB9LGF9KTtobGpzLnJlZ2lzdGVyTGFuZ3VhZ2UoInhtbCIsZnVuY3Rpb24ocyl7
-dmFyIGU9e2VXOiEwLGk6LzwvLHI6MCxjOlt7Y046ImF0dHIiLGI6IltBLVphLXowLTlcXC5fOi1dKyIs
-cjowfSx7YjovPVxzKi8scjowLGM6W3tjTjoic3RyaW5nIixlbmRzUGFyZW50OiEwLHY6W3tiOi8iLyxl
-Oi8iL30se2I6LycvLGU6LycvfSx7YjovW15ccyInPTw+YF0rL31dfV19XX07cmV0dXJue2FsaWFzZXM6
-WyJodG1sIiwieGh0bWwiLCJyc3MiLCJhdG9tIiwieGpiIiwieHNkIiwieHNsIiwicGxpc3QiLCJ3c2Yi
-XSxjSTohMCxjOlt7Y046Im1ldGEiLGI6IjwhRE9DVFlQRSIsZToiPiIscjoxMCxjOlt7YjoiXFxbIixl
-OiJcXF0ifV19LHMuQygiXHgzYyEtLSIsIi0tXHgzZSIse3I6MTB9KSx7YjoiPFxcIVxcW0NEQVRBXFxb
-IixlOiJcXF1cXF0+IixyOjEwfSx7Y046Im1ldGEiLGI6LzxcP3htbC8sZTovXD8+LyxyOjEwfSx7Yjov
-PFw/KHBocCk/LyxlOi9cPz4vLHNMOiJwaHAiLGM6W3tiOiIvXFwqIixlOiJcXCovIixza2lwOiEwfSx7
-YjonYiInLGU6JyInLHNraXA6ITB9LHtiOiJiJyIsZToiJyIsc2tpcDohMH0scy5pbmhlcml0KHMuQVNN
-LHtpOm51bGwsY046bnVsbCxjOm51bGwsc2tpcDohMH0pLHMuaW5oZXJpdChzLlFTTSx7aTpudWxsLGNO
-Om51bGwsYzpudWxsLHNraXA6ITB9KV19LHtjTjoidGFnIixiOiI8c3R5bGUoPz1cXHN8PnwkKSIsZToi
-PiIsazp7bmFtZToic3R5bGUifSxjOltlXSxzdGFydHM6e2U6Ijwvc3R5bGU+IixyRTohMCxzTDpbImNz
-cyIsInhtbCJdfX0se2NOOiJ0YWciLGI6IjxzY3JpcHQoPz1cXHN8PnwkKSIsZToiPiIsazp7bmFtZToi
-c2NyaXB0In0sYzpbZV0sc3RhcnRzOntlOiI8XC9zY3JpcHQ+IixyRTohMCxzTDpbImFjdGlvbnNjcmlw
-dCIsImphdmFzY3JpcHQiLCJoYW5kbGViYXJzIiwieG1sIiwidmJzY3JpcHQiXX19LHtjTjoidGFnIixi
-OiI8Lz8iLGU6Ii8/PiIsYzpbe2NOOiJuYW1lIixiOi9bXlwvPjxcc10rLyxyOjB9LGVdfV19fSk7aGxq
-cy5yZWdpc3Rlckxhbmd1YWdlKCJtYXJrZG93biIsZnVuY3Rpb24oZSl7cmV0dXJue2FsaWFzZXM6WyJt
-ZCIsIm1rZG93biIsIm1rZCJdLGM6W3tjTjoic2VjdGlvbiIsdjpbe2I6Il4jezEsNn0iLGU6IiQifSx7
-YjoiXi4rP1xcbls9LV17Mix9JCJ9XX0se2I6IjwiLGU6Ij4iLHNMOiJ4bWwiLHI6MH0se2NOOiJidWxs
-ZXQiLGI6Il5cXHMqKFsqKy1dfChcXGQrXFwuKSlcXHMrIn0se2NOOiJzdHJvbmciLGI6IlsqX117Mn0u
-Kz9bKl9dezJ9In0se2NOOiJlbXBoYXNpcyIsdjpbe2I6IlxcKi4rP1xcKiJ9LHtiOiJfLis/XyIscjow
-fV19LHtjTjoicXVvdGUiLGI6Il4+XFxzKyIsZToiJCJ9LHtjTjoiY29kZSIsdjpbe2I6Il5gYGB3KnMq
-JCIsZToiXmBgYHMqJCJ9LHtiOiJgLis/YCJ9LHtiOiJeKCB7NH18XHQpIixlOiIkIixyOjB9XX0se2I6
-Il5bLVxcKl17Myx9IixlOiIkIn0se2I6IlxcWy4rP1xcXVtcXChcXFtdLio/W1xcKVxcXV0iLHJCOiEw
-LGM6W3tjTjoic3RyaW5nIixiOiJcXFsiLGU6IlxcXSIsZUI6ITAsckU6ITAscjowfSx7Y046Imxpbmsi
-LGI6IlxcXVxcKCIsZToiXFwpIixlQjohMCxlRTohMH0se2NOOiJzeW1ib2wiLGI6IlxcXVxcWyIsZToi
-XFxdIixlQjohMCxlRTohMH1dLHI6MTB9LHtiOi9eXFtbXlxuXStcXTovLHJCOiEwLGM6W3tjTjoic3lt
-Ym9sIixiOi9cWy8sZTovXF0vLGVCOiEwLGVFOiEwfSx7Y046ImxpbmsiLGI6LzpccyovLGU6LyQvLGVC
-OiEwfV19XX19KTtobGpzLnJlZ2lzdGVyTGFuZ3VhZ2UoImRhcnQiLGZ1bmN0aW9uKGUpe3ZhciB0PXtj
-Tjoic3Vic3QiLHY6W3tiOiJcXCRbQS1aYS16MC05X10rIn1dfSxyPXtjTjoic3Vic3QiLHY6W3tiOiJc
-XCR7IixlOiJ9In1dLGs6InRydWUgZmFsc2UgbnVsbCB0aGlzIGlzIG5ldyBzdXBlciJ9LG49e2NOOiJz
-dHJpbmciLHY6W3tiOiJyJycnIixlOiInJycifSx7YjonciIiIicsZTonIiIiJ30se2I6InInIixlOiIn
-IixpOiJcXG4ifSx7YjonciInLGU6JyInLGk6IlxcbiJ9LHtiOiInJyciLGU6IicnJyIsYzpbZS5CRSx0
-LHJdfSx7YjonIiIiJyxlOiciIiInLGM6W2UuQkUsdCxyXX0se2I6IiciLGU6IiciLGk6IlxcbiIsYzpb
-ZS5CRSx0LHJdfSx7YjonIicsZTonIicsaToiXFxuIixjOltlLkJFLHQscl19XX07ci5jPVtlLkNOTSxu
-XTtyZXR1cm57azp7a2V5d29yZDoiYXNzZXJ0IGFzeW5jIGF3YWl0IGJyZWFrIGNhc2UgY2F0Y2ggY2xh
-c3MgY29uc3QgY29udGludWUgZGVmYXVsdCBkbyBlbHNlIGVudW0gZXh0ZW5kcyBmYWxzZSBmaW5hbCBm
-aW5hbGx5IGZvciBpZiBpbiBpcyBuZXcgbnVsbCByZXRocm93IHJldHVybiBzdXBlciBzd2l0Y2ggc3lu
-YyB0aGlzIHRocm93IHRydWUgdHJ5IHZhciB2b2lkIHdoaWxlIHdpdGggeWllbGQgYWJzdHJhY3QgYXMg
-ZHluYW1pYyBleHBvcnQgZXh0ZXJuYWwgZmFjdG9yeSBnZXQgaW1wbGVtZW50cyBpbXBvcnQgbGlicmFy
-eSBvcGVyYXRvciBwYXJ0IHNldCBzdGF0aWMgdHlwZWRlZiIsYnVpbHRfaW46InByaW50IENvbXBhcmFi
-bGUgRGF0ZVRpbWUgRHVyYXRpb24gRnVuY3Rpb24gSXRlcmFibGUgSXRlcmF0b3IgTGlzdCBNYXAgTWF0
-Y2ggTnVsbCBPYmplY3QgUGF0dGVybiBSZWdFeHAgU2V0IFN0b3B3YXRjaCBTdHJpbmcgU3RyaW5nQnVm
-ZmVyIFN0cmluZ1NpbmsgU3ltYm9sIFR5cGUgVXJpIGJvb2wgZG91YmxlIGludCBudW0gZG9jdW1lbnQg
-d2luZG93IHF1ZXJ5U2VsZWN0b3IgcXVlcnlTZWxlY3RvckFsbCBFbGVtZW50IEVsZW1lbnRMaXN0In0s
-YzpbbixlLkMoIi9cXCpcXCoiLCJcXCovIix7c0w6Im1hcmtkb3duIn0pLGUuQygiLy8vIiwiJCIse3NM
-OiJtYXJrZG93biJ9KSxlLkNMQ00sZS5DQkNNLHtjTjoiY2xhc3MiLGJLOiJjbGFzcyBpbnRlcmZhY2Ui
-LGU6InsiLGVFOiEwLGM6W3tiSzoiZXh0ZW5kcyBpbXBsZW1lbnRzIn0sZS5VVE1dfSxlLkNOTSx7Y046
-Im1ldGEiLGI6IkBbQS1aYS16XSsifSx7YjoiPT4ifV19fSk7Cg==
-''';
-
-String _index_html;
-// index_html md5 is '2cf3e3cd2e7c2331a600c030c2976c58'
-String _index_html_base64 = '''
-PGh0bWw+CjxoZWFkPgogICAgPHRpdGxlPk51bGwgU2FmZXR5IFByZXZpZXc8L3RpdGxlPgogICAgPHNj
-cmlwdCBzcmM9Int7IGhpZ2hsaWdodEpzUGF0aCB9fSI+PC9zY3JpcHQ+CiAgICA8c2NyaXB0Pnt7IGRh
-cnRQYWdlU2NyaXB0IH19PC9zY3JpcHQ+CiAgICA8bGluayByZWw9InN0eWxlc2hlZXQiIGhyZWY9Imh0
-dHBzOi8vZm9udHMuZ29vZ2xlYXBpcy5jb20vY3NzP2ZhbWlseT1PcGVuK1NhbnM6NDAwLDYwMCZkaXNw
-bGF5PXN3YXAiPgogICAgPGxpbmsgcmVsPSJzdHlsZXNoZWV0IiBocmVmPSJ7eyBoaWdobGlnaHRTdHls
-ZVBhdGggfX0iPgogICAgPHN0eWxlPnt7IGRhcnRQYWdlU3R5bGUgfX08L3N0eWxlPgo8L2hlYWQ+Cjxi
-b2R5IGNsYXNzPSJ7eyBtaWdyYXRpb25BcHBsaWVkU3R5bGUgfX0ge3sgbmVlZHNSZXJ1blN0eWxlIH19
-Ij4KPGRpdiBjbGFzcz0icmVydW5uaW5nLXBhbmUiPgogIDxoMT5SZXJ1bm5pbmcuLi48L2gxPgo8L2Rp
-dj4KPHAgY2xhc3M9InJvb3QiPnt7IHJvb3QgfX08L3A+CjxoZWFkZXIgY2xhc3M9ImVsZXZhdGlvbi16
-NCI+CiAgICA8aDEgY2xhc3M9ImJlZm9yZS1hcHBseSI+UHJvcG9zZWQgbnVsbCBzYWZldHkgY2hhbmdl
-czwvaDE+CiAgICA8aDEgY2xhc3M9ImFmdGVyLWFwcGx5Ij4mIzEwMDAzOyBOdWxsIHNhZmV0eSBtaWdy
-YXRpb24gYXBwbGllZDwvaDE+CiAgICA8aDIgaWQ9InVuaXQtbmFtZSI+Jm5ic3A7PC9oMj4KICAgIDxi
-dXR0b24gY2xhc3M9ImFwcGx5LW1pZ3JhdGlvbiI+JiM5OTk4OyBBcHBseSBNaWdyYXRpb248L2J1dHRv
-bj4KICAgIDxidXR0b24gY2xhc3M9ImFwcGx5LW1pZ3JhdGlvbiIgZGlzYWJsZWQ+JiM5OTk4OyBBcHBs
-eSBNaWdyYXRpb248L2J1dHRvbj4KICAgIDxidXR0b24gY2xhc3M9InJlcnVuLW1pZ3JhdGlvbiBiZWZv
-cmUtYXBwbHkiPgogICAgICA8c3BhbiBjbGFzcz0ib3B0aW9uYWwiPiYjODYzNTsgUmVydW4gRnJvbSBT
-b3VyY2VzPC9zcGFuPgogICAgICA8c3BhbiBjbGFzcz0icmVxdWlyZWQiPgogICAgICAgIDxzcGFuIGNs
-YXNzPSJpY29uIiAKICAgICAgICAgIHRpdGxlPSJEaXNrIGNvbnRlbnRzIGhhdmUgY2hhbmdlZC4gUmVy
-dW4gdG8gZ2V0IGFuIHVwLXRvLWRhdGUgbWlncmF0aW9uLiI+ITwvc3Bhbj4KICAgICAgICBSZXJ1biBX
-aXRoIENoYW5nZXMKICAgICAgPC9zcGFuPgogICAgPC9idXR0b24+CjwvaGVhZGVyPgo8ZGl2IGNsYXNz
-PSJwYW5lbHMgaG9yaXpvbnRhbCI+CiAgICA8ZGl2IGNsYXNzPSJuYXYtcGFuZWwiPgogICAgICAgIDxk
-aXYgY2xhc3M9Im5hdi1pbm5lciI+CiAgICAgICAgICAgIDxkaXYgY2xhc3M9InBhbmVsLWhlYWRpbmci
-PlByb2plY3QgRmlsZXM8L2Rpdj4KICAgICAgICAgICAgPGRpdiBjbGFzcz0ibmF2LXRyZWUiPjwvZGl2
-PgogICAgICAgIDwvZGl2PjwhLS0gL25hdi1pbm5lciAtLT4KICAgIDwvZGl2PjwhLS0gL25hdiAtLT4K
-ICAgIDxkaXYgY2xhc3M9ImNvbnRlbnQiPgogICAgICAgIDxkaXYgY2xhc3M9InJlZ2lvbnMiPgogICAg
-ICAgICAgICA8IS0tIFRoZSByZWdpb25zIG92ZXJsYXkgY29kZSBjb3B5IG9mIHRoZSBjb250ZW50IHRv
-IHByb3ZpZGUgLS0+CiAgICAgICAgICAgIDwhLS0gdG9vbHRpcHMgZm9yIG1vZGlmaWVkIHJlZ2lvbnMu
-IC0tPgogICAgICAgIDwvZGl2PjwhLS0gL3JlZ2lvbnMgLS0+CiAgICAgICAgPGRpdiBjbGFzcz0iY29k
-ZSI+CiAgICAgICAgICAgIDwhLS0gQ29tcGlsYXRpb24gdW5pdCBjb250ZW50IGlzIHdyaXR0ZW4gaGVy
-ZS4gLS0+CiAgICAgICAgICAgIDxwIGNsYXNzPSJ3ZWxjb21lIj4KICAgICAgICAgICAgICAgIFNlbGVj
-dCBhIHNvdXJjZSBmaWxlIG9uIHRoZSBsZWZ0IHRvIHByZXZpZXcgdGhlIHByb3Bvc2VkIGVkaXRzLgog
-ICAgICAgICAgICA8L3A+CiAgICAgICAgPC9kaXY+CiAgICA8L2Rpdj48IS0tIC9jb250ZW50IC0tPgog
-ICAgPGRpdiBjbGFzcz0iaW5mby1wYW5lbCI+CiAgICAgICAgPGRpdiBjbGFzcz0iZWRpdC1saXN0Ij4K
-ICAgICAgICAgICAgPGRpdiBjbGFzcz0icGFuZWwtaGVhZGluZyI+UHJvcG9zZWQgRWRpdHM8L2Rpdj4K
-ICAgICAgICAgICAgPGRpdiBjbGFzcz0icGFuZWwtY29udGVudCI+PC9kaXY+CiAgICAgICAgPC9kaXY+
-PCEtLSAvZWRpdC1saXN0IC0tPgogICAgICAgIDxkaXYgY2xhc3M9ImVkaXQtcGFuZWwiPgogICAgICAg
-ICAgICA8ZGl2IGNsYXNzPSJwYW5lbC1oZWFkaW5nIj5FZGl0IERldGFpbHM8L2Rpdj4KICAgICAgICAg
-ICAgPGRpdiBjbGFzcz0icGFuZWwtY29udGVudCI+CiAgICAgICAgICAgICAgICA8cCBjbGFzcz0icGxh
-Y2Vob2xkZXIiPlNlZSBkZXRhaWxzIGFib3V0IGEgcHJvcG9zZWQgZWRpdC48L3A+CiAgICAgICAgICAg
-IDwvZGl2PjwhLS0gL3BhbmVsLWNvbnRlbnQgLS0+CiAgICAgICAgPC9kaXY+PCEtLSAvZWRpdC1wYW5l
-bCAtLT4KICAgIDwvZGl2PjwhLS0gL2luZm8tcGFuZWwgLS0+CjwvZGl2PjwhLS0gL3BhbmVscyAtLT4K
-PGZvb3Rlcj4KICAgIDxhIHRhcmdldD0iX2JsYW5rIgogICAgICBocmVmPSJodHRwczovL2dvby5nbGUv
-ZGFydC1udWxsLXNhZmV0eS1taWdyYXRpb24tdG9vbCI+TnVsbCBzYWZldHkKICAgICAgICBtaWdyYXRp
-b24gaGVscDwvYT4KICAgIDxzcGFuIGNsYXNzPSJ3aWRlIj4gPC9zcGFuPgogICAgPGRpdj5CYXNlZCBv
-biB7eyBzZGtWZXJzaW9uIH19PC9kaXY+CjwvZm9vdGVyPgo8L2JvZHk+CjwvaHRtbD4K
-''';
-
-String _migration_css;
-// migration_css md5 is '0063c2f22a79d4534f0b3e9d3a805e2d'
-String _migration_css_base64 = '''
-LyogQ29weXJpZ2h0IChjKSAyMDE5LCB0aGUgRGFydCBwcm9qZWN0IGF1dGhvcnMuIFBsZWFzZSBzZWUg
-dGhlIEFVVEhPUlMgZmlsZSAgKi8KLyogZm9yIGRldGFpbHMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuIFVz
-ZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGEgKi8KLyogQlNELXN0eWxlIGxpY2Vu
-c2UgdGhhdCBjYW4gYmUgZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZS4gICAgICAgICAgICAgICAgICAg
-Ki8KCmJvZHkgewogIGJhY2tncm91bmQtY29sb3I6ICMxMjIwMmY7CiAgY29sb3I6ICNjY2M7CiAgZm9u
-dC1mYW1pbHk6ICJSb2JvdG8iLCBzYW5zLXNlcmlmOwogIGZvbnQtc2l6ZTogMTRweDsKICBkaXNwbGF5
-OiBmbGV4OwogIGZsZXgtZGlyZWN0aW9uOiBjb2x1bW47CiAgcG9zaXRpb246IGFic29sdXRlOwogIHRv
-cDogMDsKICByaWdodDogMDsKICBib3R0b206IDA7CiAgbGVmdDogMDsKICBtYXJnaW46IDA7CiAgcGFk
-ZGluZzogMDsKICBvdmVyZmxvdzogaGlkZGVuOwp9CgoucHJvcG9zZWQgLmFmdGVyLWFwcGx5IHsKICBk
-aXNwbGF5OiBub25lOwp9CgouYXBwbGllZCAuYmVmb3JlLWFwcGx5IHsKICBkaXNwbGF5OiBub25lOwp9
-CgouYXBwbGllZCAuYXBwbHktbWlncmF0aW9uOm5vdChbZGlzYWJsZWRdKSwgLm5lZWRzLXJlcnVuIC5h
-cHBseS1taWdyYXRpb246bm90KFtkaXNhYmxlZF0pIHsKICBkaXNwbGF5OiBub25lOwp9CgoucHJvcG9z
-ZWQ6bm90KC5uZWVkcy1yZXJ1bikgLmFwcGx5LW1pZ3JhdGlvbltkaXNhYmxlZF0gewogIGRpc3BsYXk6
-IG5vbmU7Cn0KCmhlYWRlciB7CiAgYmFja2dyb3VuZC1jb2xvcjogIzFjMjgzNDsKICBoZWlnaHQ6IDQ4
-cHg7CiAgcGFkZGluZy1sZWZ0OiAyNHB4OwogIGFsaWduLWl0ZW1zOiBjZW50ZXI7CiAgei1pbmRleDog
-NDsKfQoKaGVhZGVyIGgxLApoZWFkZXIgaDIgewogIGRpc3BsYXk6IGlubGluZS1ibG9jazsKICBmb250
-LWZhbWlseTogIkdvb2dsZSBTYW5zIiwiUm9ib3RvIixzYW5zLXNlcmlmOwogIGZvbnQtd2VpZ2h0OiA0
-MDA7CiAgbWFyZ2luLXJpZ2h0OiAyNHB4Owp9CgpoMSB7CiAgZm9udC1zaXplOiAxLjVlbTsKfQoKaGVh
-ZGVyIGgyIHsKICBmb250LXNpemU6IDEuMmVtOwp9CgpoZWFkZXIgLmFwcGx5LW1pZ3JhdGlvbiwgLnJl
-cnVuLW1pZ3JhdGlvbiB7CiAgcmlnaHQ6IDBweDsKICBmbG9hdDogcmlnaHQ7CiAgbWFyZ2luOiAxMHB4
-Owp9CgoucmVydW4tbWlncmF0aW9uIC5yZXF1aXJlZCB7CiAgZGlzcGxheTogbm9uZTsKfQoKLm5lZWRz
-LXJlcnVuIC5yZXJ1bi1taWdyYXRpb24gLnJlcXVpcmVkIHsKICBkaXNwbGF5OiBpbml0aWFsOwp9Cgou
-bmVlZHMtcmVydW4gLnJlcnVuLW1pZ3JhdGlvbiAub3B0aW9uYWwgewogIGRpc3BsYXk6bm9uZTsKfQoK
-LyogUmVkIHRyaWFuZ2xlICovCi5yZXJ1bi1taWdyYXRpb24gLnJlcXVpcmVkIC5pY29uOjpiZWZvcmUg
-ewogIHRyYW5zZm9ybTogdHJhbnNsYXRlKC04cHgsIC0xMXB4KTsKICBjb250ZW50OiAnXDI1QjMnOwog
-IGZvbnQtc2l6ZTogMjVweDsKICBwb3NpdGlvbjogZml4ZWQ7CiAgY29sb3I6ICNlODJjMmM7CiAgdGV4
-dC1zaGFkb3c6IDBweCAwcHggNXB4IHdoaXRlOwogIHotaW5kZXg6IC0zOwp9CgovKiBSZWQgdHJpYW5n
-bGUgZmlsbCAqLwoucmVydW4tbWlncmF0aW9uIC5yZXF1aXJlZCAuaWNvbjo6YWZ0ZXIgewogIHRyYW5z
-Zm9ybTogdHJhbnNsYXRlKC05cHgsIC0xMHB4KTsKICBjb250ZW50OiAnXDI1QjQnOwogIGZvbnQtc2l6
-ZTogMjVweDsKICBwb3NpdGlvbjogZml4ZWQ7CiAgY29sb3I6ICNiM2VjZmY7CiAgei1pbmRleDogLTE7
-Cn0KCi8qIFJlZCB0cmlhbmdsZSBleGNsYW1hdGlvbiAqLwoucmVydW4tbWlncmF0aW9uIC5yZXF1aXJl
-ZCAuaWNvbiB7CiAgZGlzcGxheTogaW5saW5lLWJsb2NrOwogIG1hcmdpbi1yaWdodDogOHB4OwogIHRy
-YW5zZm9ybTogdHJhbnNsYXRlKDBweCwgMnB4KTsKICBtYXJnaW4tbGVmdDogMnB4OwogIGNvbG9yOiAj
-MmIyYjJiOwp9Cgpmb290ZXIgewogIGNvbG9yOiAjY2NjOwogIGJhY2tncm91bmQtY29sb3I6ICMyNzMy
-M2E7CiAgZGlzcGxheTogZmxleDsKICBmbGV4LWRpcmVjdGlvbjogcm93OwogIGFsaWduLWl0ZW1zOiBj
-ZW50ZXI7CiAgcGFkZGluZzogOHB4IDI0cHg7Cn0KCmZvb3RlciAud2lkZSB7CiAgZmxleDogMTsKfQoK
-Lmhvcml6b250YWwgewogIGRpc3BsYXk6IGZsZXg7Cn0KCi5wYW5lbHMgewogIGJhY2tncm91bmQtY29s
-b3I6ICMxMjFhMjU7CiAgZmxleDogMTsKICBvdmVyZmxvdzogaGlkZGVuOwp9CgoucGFuZWwtaGVhZGlu
-ZyB7CiAgY29sb3I6IGdyYXk7CiAgbWFyZ2luOiA4cHg7Cn0KCi5uYXYtbGluaywKLnJlZ2lvbiB7CiAg
-Y3Vyc29yOiBwb2ludGVyOwp9CgoubmF2LXBhbmVsIHsKICBiYWNrZ3JvdW5kLWNvbG9yOiAjMjgyYjJl
-OwogIGZsZXg6IDEgMjAwcHg7CiAgbWFyZ2luOiAwOwogIG92ZXJmbG93OiBzY3JvbGw7Cn0KCi5uYXYt
-aW5uZXIgewogIHBhZGRpbmc6IDAgMCA3cHggN3B4Owp9CgouZml4ZWQgewogIHBvc2l0aW9uOiBmaXhl
-ZDsKICB0b3A6IDA7Cn0KCi5yb290IHsKICBtYXJnaW46IDA7CiAgZGlzcGxheTogbm9uZTsKfQoKLm5h
-di10cmVlID4gdWwgewogIHBhZGRpbmctbGVmdDogNnB4Owp9CgoubmF2LWlubmVyIHVsIHsKICBwYWRk
-aW5nLWxlZnQ6IDEycHg7CiAgbWFyZ2luOiAwOwp9CgoubmF2LWlubmVyIGxpIHsKICBsaXN0LXN0eWxl
-LXR5cGU6IG5vbmU7Cn0KCi5uYXYtaW5uZXIgbGk6bm90KC5kaXIpIHsKICBtYXJnaW4tbGVmdDogMjBw
-eDsKICBtYXJnaW4tYm90dG9tOiAzcHg7Cn0KCi5uYXYtaW5uZXIgbGkuZGlyIC5hcnJvdyB7CiAgY3Vy
-c29yOiBwb2ludGVyOwogIGRpc3BsYXk6IGlubGluZS1ibG9jazsKICBmb250LXNpemU6IDEwcHg7CiAg
-bWFyZ2luLXJpZ2h0OiA0cHg7CiAgdHJhbnNpdGlvbjogdHJhbnNmb3JtIDAuNXMgZWFzZS1vdXQ7Cn0K
-Ci5uYXYtaW5uZXIgbGkuZGlyIC5hcnJvdy5jb2xsYXBzZWQgewogIHRyYW5zZm9ybTogcm90YXRlKC05
-MGRlZyk7Cn0KCi5uYXYtaW5uZXIgdWwgewogIG1heC1oZWlnaHQ6IDIwMDBweDsKICB0cmFuc2l0aW9u
-OiBtYXgtaGVpZ2h0IDAuNXMgZWFzZS1vdXQ7Cn0KCi5uYXYtaW5uZXIgdWwuY29sbGFwc2VkIHsKICBt
-YXgtaGVpZ2h0OiAwICFpbXBvcnRhbnQ7CiAgb3ZlcmZsb3c6IGhpZGRlbjsKfQoKLm5hdi1pbm5lciAu
-c2VsZWN0ZWQtZmlsZSB7CiAgY29sb3I6IHdoaXRlOwogIGN1cnNvcjogaW5oZXJpdDsKICBmb250LXdl
-aWdodDogNjAwOwogIHRleHQtZGVjb3JhdGlvbjogbm9uZTsKfQoKLmVkaXQtY291bnQgewogIGJhY2tn
-cm91bmQtY29sb3I6ICMzN2FlZGM7CiAgYm9yZGVyLXJhZGl1czogMTBweDsKICBjb2xvcjogIzAwMDAw
-MDsKICBkaXNwbGF5OiBpbmxpbmUtYmxvY2s7CiAgZm9udC1zaXplOiAxMXB4OwogIGZvbnQtd2VpZ2h0
-OiA2MDA7CiAgbWFyZ2luLWxlZnQ6IDVweDsKICBtaW4td2lkdGg6IDI1cHg7CiAgcGFkZGluZzogNHB4
-IDAgMnB4IDA7CiAgdGV4dC1hbGlnbjogY2VudGVyOwogIGxpbmUtaGVpZ2h0OiAxZW07Cn0KCi5jb250
-ZW50IHsKICBmbGV4OiA0IDMwMHB4OwogIGJhY2tncm91bmQ6ICMyODJiMmU7CiAgZm9udC1mYW1pbHk6
-IG1vbm9zcGFjZTsKICBtYXJnaW46IDAgNnB4OwogIHBvc2l0aW9uOiByZWxhdGl2ZTsKICB3aGl0ZS1z
-cGFjZTogcHJlOwogIG92ZXJmbG93OiBzY3JvbGw7Cn0KCi5jb2RlIHsKICBwYWRkaW5nOiAwLjVlbTsK
-ICBwb3NpdGlvbjogYWJzb2x1dGU7CiAgbGVmdDogMDsKICB0b3A6IDA7CiAgbWFyZ2luLWxlZnQ6IDU2
-cHg7Cn0KCi5obGpzIHsKICBiYWNrZ3JvdW5kLWNvbG9yOiAjMjgyYjJlOwogIGRpc3BsYXk6IGJsb2Nr
-OwogIG92ZXJmbG93LXg6IGF1dG87CiAgcGFkZGluZzogMC41ZW07Cn0KCi5jb2RlIC53ZWxjb21lIHsK
-ICBmb250LWZhbWlseTogIkdvb2dsZSBTYW5zIiwiUm9ib3RvIixzYW5zLXNlcmlmOwogIGZvbnQtc2l6
-ZTogMThweDsKICBtYXJnaW4tcmlnaHQ6IDYycHg7CiAgY29sb3I6ICM3Nzc7Cn0KCi5jb2RlIC5uYXYt
-bGluayB7CiAgY29sb3I6IGluaGVyaXQ7CiAgdGV4dC1kZWNvcmF0aW9uLWxpbmU6IG5vbmU7Cn0KCi5j
-b2RlIC5uYXYtbGluazp2aXNpdGVkIHsKICBjb2xvcjogaW5oZXJpdDsKICB0ZXh0LWRlY29yYXRpb24t
-bGluZTogbm9uZTsKfQoKLmNvZGUgLm5hdi1saW5rOmhvdmVyIHsKICB0ZXh0LWRlY29yYXRpb24tbGlu
-ZTogdW5kZXJsaW5lOwogIGZvbnQtd2VpZ2h0OiA2MDA7Cn0KCi5yZWdpb25zIHsKICBwYWRkaW5nOiAw
-LjVlbTsKICBwb3NpdGlvbjogYWJzb2x1dGU7CiAgbGVmdDogMDsKICB0b3A6IDA7Cn0KCi5yZWdpb25z
-IHRhYmxlIHsKICBib3JkZXItc3BhY2luZzogMDsKICBmb250LXNpemU6IGluaGVyaXQ7Cn0KCi5yZWdp
-b25zIHRkIHsKICBib3JkZXI6IG5vbmU7CiAgLyogVGhlIGNvbnRlbnQgb2YgdGhlIHJlZ2lvbnMgaXMg
-bm90IHZpc2libGU7IHRoZSB1c2VyIGluc3RlYWQgd2lsbCBzZWUgdGhlCiAgICogaGlnaGxpZ2h0ZWQg
-Y29weSBvZiB0aGUgY29udGVudC4gKi8KICBjb2xvcjogcmdiYSgyNTUsIDI1NSwgMjU1LCAwKTsKICBw
-YWRkaW5nOiAwOwogIHdoaXRlLXNwYWNlOiBwcmU7Cn0KCi5yZWdpb25zIHRkOmVtcHR5OmFmdGVyIHsK
-ICBjb250ZW50OiAiXDAwYTAiOwp9CgoucmVnaW9ucyB0ci5oaWdobGlnaHQgdGQ6bGFzdC1jaGlsZCB7
-CiAgYmFja2dyb3VuZC1jb2xvcjogIzQ0NDQ0NDsKICBjb2xvcjogd2hpdGU7Cn0KCi5yZWdpb25zIHRk
-LmxpbmUtbm8gewogIGJvcmRlci1yaWdodDogc29saWQgIzI4MmIyZSAycHg7CiAgY29sb3I6ICM5OTk5
-OTk7CiAgcGFkZGluZy1yaWdodDogNHB4OwogIHRleHQtYWxpZ246IHJpZ2h0OwogIHZpc2liaWxpdHk6
-IHZpc2libGU7CiAgd2lkdGg6IDUwcHg7CiAgZGlzcGxheTogaW5saW5lLWJsb2NrOwp9CgoucmVnaW9u
-cyB0ci5oaWdobGlnaHQgdGQubGluZS1ubyB7CiAgYm9yZGVyLXJpZ2h0OiBzb2xpZCAjY2NjIDJweDsK
-fQoKLnJlZ2lvbiB7CiAgZGlzcGxheTogaW5saW5lLWJsb2NrOwogIHBvc2l0aW9uOiByZWxhdGl2ZTsK
-ICB2aXNpYmlsaXR5OiB2aXNpYmxlOwogIHotaW5kZXg6IDIwMDsKfQoKLnJlZ2lvbi5hZGRlZC1yZWdp
-b24gewogIGJhY2tncm91bmQtY29sb3I6ICNjY2ZmY2M7CiAgY29sb3I6ICMwMDMzMDA7Cn0KCi5yZWdp
-b24ucmVtb3ZlZC1yZWdpb24gewogIGJhY2tncm91bmQtY29sb3I6ICNmZjY2NjY7CiAgY29sb3I6ICMw
-MDExMDA7Cn0KCi5yZWdpb24uaW5mb3JtYXRpdmUtcmVnaW9uIHsKICBiYWNrZ3JvdW5kLWNvbG9yOiAj
-ODg4ODg4OwogIGNvbG9yOiAjMDAwMDAwOwp9CgoudGFyZ2V0IHsKICBiYWNrZ3JvdW5kLWNvbG9yOiAj
-NDQ0OwogIHBvc2l0aW9uOiByZWxhdGl2ZTsKICB2aXNpYmlsaXR5OiB2aXNpYmxlOwogIGZvbnQtd2Vp
-Z2h0OiA2MDA7Cn0KCi5pbmZvLXBhbmVsIHsKICBmbGV4OiAxIDIwMHB4OwogIG1hcmdpbjogMDsKICBo
-ZWlnaHQ6IDEwMCU7CiAgZGlzcGxheTogZmxleDsKICBmbGV4LWRpcmVjdGlvbjogY29sdW1uOwp9Cgou
-aW5mby1wYW5lbCAuZWRpdC1wYW5lbCB7CiAgYmFja2dyb3VuZC1jb2xvcjogIzI4MmIyZTsKICBvdmVy
-ZmxvdzogYXV0bzsKfQoKLmluZm8tcGFuZWwgLnBhbmVsLWNvbnRlbnQgewogIHBhZGRpbmc6IDdweDsK
-fQoKLmluZm8tcGFuZWwgLnBhbmVsLWNvbnRlbnQ+IDpmaXJzdC1jaGlsZCB7CiAgbWFyZ2luLXRvcDog
-MDsKfQoKLmluZm8tcGFuZWwgLm5vd3JhcCB7CiAgd2hpdGUtc3BhY2U6IG5vd3JhcDsKfQoKLmluZm8t
-cGFuZWwgdWwsCi5pbmZvLXBhbmVsIG9sIHsKICBwYWRkaW5nLWxlZnQ6IDIwcHg7Cn0KCi5pbmZvLXBh
-bmVsIGxpIHsKICBtYXJnaW46IDAgMCA1cHggMDsKfQoKLmluZm8tcGFuZWwgYSB7CiAgY29sb3I6ICMz
-M2NjZmY7Cn0KCi5pbmZvLXBhbmVsIC5lZGl0LWxpc3QgewogIGJhY2tncm91bmQtY29sb3I6ICMyODJi
-MmU7CiAgb3ZlcmZsb3c6IGF1dG87Cn0KCi5lZGl0LXBhbmVsIHsKICBtYXJnaW4tdG9wOiA2cHg7CiAg
-ZmxleDogMSAxMDBweDsKfQoKLmVkaXQtbGlzdCB7CiAgZmxleDogMiAxMDBweDsKfQoKLmVkaXQtbGlz
-dCAuZWRpdCB7CiAgbWFyZ2luOiAzcHggMDsKfQoKLmVkaXQtbGlzdCAuZWRpdC1saW5rIHsKICBjdXJz
-b3I6IHBvaW50ZXI7Cn0KCi5yZXJ1bm5pbmctcGFuZSB7CiAgZGlzcGxheTogbm9uZTsKfQoKYm9keS5y
-ZXJ1bm5pbmcgLnJlcnVubmluZy1wYW5lIHsKICBkaXNwbGF5OiBibG9jazsKICBwb3NpdGlvbjogZml4
-ZWQ7CiAgdG9wOiAwcHg7CiAgYm90dG9tOiAwcHg7CiAgbGVmdDogMHB4OwogIHJpZ2h0OiAwcHg7CiAg
-YmFja2dyb3VuZC1jb2xvcjogIzAwMDAwMEFBOyAvKiB0cmFuc2x1Y2VudCBibGFjayAqLwogIHotaW5k
-ZXg6IDQwMDsKfQoKLnJlcnVubmluZy1wYW5lIGgxIHsKICBwb3NpdGlvbjogYWJzb2x1dGU7CiAgdG9w
-OiA1MCU7CiAgbGVmdDogNTAlOwogIHRyYW5zZm9ybTogdHJhbnNsYXRlKC01MCUsIC01MCUpOwp9Cgpw
-LnRyYWNlIC50eXBlLWRlc2NyaXB0aW9uIHsKICAvKiBGcm9tIEhMSlMncyAuaGxqcy1rZXl3b3JkLCAu
-aGxqcy1zZWxlY3Rvci10YWcsIC5obGpzLWRlbGV0aW9uICovCiAgY29sb3I6ICNjYzc4MzI7CiAgZm9u
-dC1mYW1pbHk6IG1vbm9zcGFjZTsKfQoKdWwudHJhY2UgewogIGZvbnQtc2l6ZTogMTNweDsKICBsaXN0
-LXN0eWxlLXR5cGU6IG5vbmU7CiAgcGFkZGluZy1sZWZ0OiAwcHg7Cn0KCnVsLnRyYWNlIGxpIHsKICBj
-b2xvcjogd2hpdGU7CiAgbWFyZ2luLWxlZnQ6IDE0cHg7CiAgdGV4dC1pbmRlbnQ6IC0xNHB4Owp9Cgp1
-bC50cmFjZSBsaSAuZnVuY3Rpb24gewogIC8qIEZyb20gSExKUydzIC5obGpzLXNlY3Rpb24sIC5obGpz
-LXRpdGxlLCAuaGxqcy10eXBlICovCiAgY29sb3I6ICNmZmM2NmQ7CiAgZm9udC1mYW1pbHk6IG1vbm9z
-cGFjZTsKICBmb250LXdlaWdodDogNjAwOwp9CgouZWxldmF0aW9uLXo0IHsKICBib3gtc2hhZG93OiAw
-cHggMnB4IDRweCAtMXB4IHJnYmEoMCwgMCwgMCwgMC4yKSwKICAgICAgMHB4IDRweCA1cHggMHB4IHJn
-YmEoMCwgMCwgMCwgMC4xNCksCiAgICAgIDBweCAxcHggMTBweCAwcHggcmdiYSgwLCAwLCAwLCAuMTIp
-Owp9CgphIHsKICBjb2xvcjogI2NjYzsKICBmaWxsOiAjY2NjOwogIHRleHQtZGVjb3JhdGlvbjogbm9u
-ZTsKfQoKYTpob3ZlciB7CiAgY29sb3I6ICNmZmY7CiAgZmlsbDogI2ZmZjsKfQoKYS5wb3N0LWxpbmsg
-ewogIGRpc3BsYXk6IGlubGluZS1ibG9jazsKICBtYXJnaW46IDNweDsKfQoKYnV0dG9uLCBhLnBvc3Qt
-bGluayB7CiAgYmFja2dyb3VuZC1jb2xvcjogIzMzY2NmZjsKICBib3JkZXI6IDJweCBzb2xpZCAjMzdh
-ZWRjOwogIGJvcmRlci1yYWRpdXM6IDNweDsKICBwYWRkaW5nOiA2cHggMTBweDsKICBmb250LXdlaWdo
-dDogYm9sZDsKICBjb2xvcjogIzI4MjgyODsKfQoKYnV0dG9uOmhvdmVyLCBhLnBvc3QtbGluazpob3Zl
-ciB7CiAgYmFja2dyb3VuZC1jb2xvcjogIzgwZGZmZjsKICBib3JkZXI6IDJweCBzb2xpZCAjNTJiOGUw
-OwogIGN1cnNvcjogcG9pbnRlcjsKfQoKYnV0dG9uW2Rpc2FibGVkXSB7CiAgYmFja2dyb3VuZC1jb2xv
-cjogIzdhYThiODsKICBjb2xvcjogIzUwNzE3NzsKICBib3JkZXI6IDJweCBzb2xpZCAjNTA3MTc3Owog
-IGN1cnNvcjogbm90LWFsbG93ZWQ7Cn0KCi5wbGFjZWhvbGRlciB7CiAgY29sb3I6ICM3Nzc7CiAgdGV4
-dC1hbGlnbjogY2VudGVyOwogIG1hcmdpbi10b3A6IDNlbSAhaW1wb3J0YW50Owp9CgovKioKICogSExK
-UyBPdmVycmlkZXMKICovCi5obGpzIHsKICAvKioKICAgKiBUaGlzIGFsbG93cyB0aGUgcGVyLWxpbmUg
-aGlnaGxpZ2h0cyB0byBzaG93LgogICAqLwogIGJhY2tncm91bmQ6IG5vbmU7Cn0K
-''';
-
-String _migration_js;
-// migration_dart md5 is '8114403a4ae0e1440ba0cea2923c01da'
-String _migration_js_base64 = '''
-KGZ1bmN0aW9uIGRhcnRQcm9ncmFtKCl7ZnVuY3Rpb24gY29weVByb3BlcnRpZXMoYSxiKXt2YXIgdD1P
-YmplY3Qua2V5cyhhKQpmb3IodmFyIHM9MDtzPHQubGVuZ3RoO3MrKyl7dmFyIHI9dFtzXQpiW3JdPWFb
-cl19fXZhciB6PWZ1bmN0aW9uKCl7dmFyIHQ9ZnVuY3Rpb24oKXt9CnQucHJvdG90eXBlPXtwOnt9fQp2
-YXIgcz1uZXcgdCgpCmlmKCEocy5fX3Byb3RvX18mJnMuX19wcm90b19fLnA9PT10LnByb3RvdHlwZS5w
-KSlyZXR1cm4gZmFsc2UKdHJ5e2lmKHR5cGVvZiBuYXZpZ2F0b3IhPSJ1bmRlZmluZWQiJiZ0eXBlb2Yg
-bmF2aWdhdG9yLnVzZXJBZ2VudD09InN0cmluZyImJm5hdmlnYXRvci51c2VyQWdlbnQuaW5kZXhPZigi
-Q2hyb21lLyIpPj0wKXJldHVybiB0cnVlCmlmKHR5cGVvZiB2ZXJzaW9uPT0iZnVuY3Rpb24iJiZ2ZXJz
-aW9uLmxlbmd0aD09MCl7dmFyIHI9dmVyc2lvbigpCmlmKC9eXGQrXC5cZCtcLlxkK1wuXGQrJC8udGVz
-dChyKSlyZXR1cm4gdHJ1ZX19Y2F0Y2gocSl7fXJldHVybiBmYWxzZX0oKQpmdW5jdGlvbiBzZXRGdW5j
-dGlvbk5hbWVzSWZOZWNlc3NhcnkoYSl7ZnVuY3Rpb24gdCgpe307aWYodHlwZW9mIHQubmFtZT09InN0
-cmluZyIpcmV0dXJuCmZvcih2YXIgdD0wO3Q8YS5sZW5ndGg7dCsrKXt2YXIgcz1hW3RdCnZhciByPU9i
-amVjdC5rZXlzKHMpCmZvcih2YXIgcT0wO3E8ci5sZW5ndGg7cSsrKXt2YXIgcD1yW3FdCnZhciBvPXNb
-cF0KaWYodHlwZW9mIG89PSdmdW5jdGlvbicpby5uYW1lPXB9fX1mdW5jdGlvbiBpbmhlcml0KGEsYil7
-YS5wcm90b3R5cGUuY29uc3RydWN0b3I9YQphLnByb3RvdHlwZVsiJGkiK2EubmFtZV09YQppZihiIT1u
-dWxsKXtpZih6KXthLnByb3RvdHlwZS5fX3Byb3RvX189Yi5wcm90b3R5cGUKcmV0dXJufXZhciB0PU9i
-amVjdC5jcmVhdGUoYi5wcm90b3R5cGUpCmNvcHlQcm9wZXJ0aWVzKGEucHJvdG90eXBlLHQpCmEucHJv
-dG90eXBlPXR9fWZ1bmN0aW9uIGluaGVyaXRNYW55KGEsYil7Zm9yKHZhciB0PTA7dDxiLmxlbmd0aDt0
-KyspaW5oZXJpdChiW3RdLGEpfWZ1bmN0aW9uIG1peGluKGEsYil7Y29weVByb3BlcnRpZXMoYi5wcm90
-b3R5cGUsYS5wcm90b3R5cGUpCmEucHJvdG90eXBlLmNvbnN0cnVjdG9yPWF9ZnVuY3Rpb24gbGF6eShh
-LGIsYyxkKXt2YXIgdD1hCmFbYl09dAphW2NdPWZ1bmN0aW9uKCl7YVtjXT1mdW5jdGlvbigpe0guYWco
-Yil9CnZhciBzCnZhciByPWQKdHJ5e2lmKGFbYl09PT10KXtzPWFbYl09cgpzPWFbYl09ZCgpfWVsc2Ug
-cz1hW2JdfWZpbmFsbHl7aWYocz09PXIpYVtiXT1udWxsCmFbY109ZnVuY3Rpb24oKXtyZXR1cm4gdGhp
-c1tiXX19cmV0dXJuIHN9fWZ1bmN0aW9uIG1ha2VDb25zdExpc3QoYSl7YS5pbW11dGFibGUkbGlzdD1B
-cnJheQphLmZpeGVkJGxlbmd0aD1BcnJheQpyZXR1cm4gYX1mdW5jdGlvbiBjb252ZXJ0VG9GYXN0T2Jq
-ZWN0KGEpe2Z1bmN0aW9uIHQoKXt9dC5wcm90b3R5cGU9YQpuZXcgdCgpCnJldHVybiBhfWZ1bmN0aW9u
-IGNvbnZlcnRBbGxUb0Zhc3RPYmplY3QoYSl7Zm9yKHZhciB0PTA7dDxhLmxlbmd0aDsrK3QpY29udmVy
-dFRvRmFzdE9iamVjdChhW3RdKX12YXIgeT0wCmZ1bmN0aW9uIHRlYXJPZmZHZXR0ZXIoYSxiLGMsZCxl
-KXtyZXR1cm4gZT9uZXcgRnVuY3Rpb24oImZ1bmNzIiwiYXBwbHlUcmFtcG9saW5lSW5kZXgiLCJyZWZs
-ZWN0aW9uSW5mbyIsIm5hbWUiLCJIIiwiYyIsInJldHVybiBmdW5jdGlvbiB0ZWFyT2ZmXyIrZCt5Kysr
-IihyZWNlaXZlcikgeyIrImlmIChjID09PSBudWxsKSBjID0gIisiSC51YyIrIigiKyJ0aGlzLCBmdW5j
-cywgYXBwbHlUcmFtcG9saW5lSW5kZXgsIHJlZmxlY3Rpb25JbmZvLCBmYWxzZSwgdHJ1ZSwgbmFtZSk7
-IisicmV0dXJuIG5ldyBjKHRoaXMsIGZ1bmNzWzBdLCByZWNlaXZlciwgbmFtZSk7IisifSIpKGEsYixj
-LGQsSCxudWxsKTpuZXcgRnVuY3Rpb24oImZ1bmNzIiwiYXBwbHlUcmFtcG9saW5lSW5kZXgiLCJyZWZs
-ZWN0aW9uSW5mbyIsIm5hbWUiLCJIIiwiYyIsInJldHVybiBmdW5jdGlvbiB0ZWFyT2ZmXyIrZCt5Kysr
-IigpIHsiKyJpZiAoYyA9PT0gbnVsbCkgYyA9ICIrIkgudWMiKyIoIisidGhpcywgZnVuY3MsIGFwcGx5
-VHJhbXBvbGluZUluZGV4LCByZWZsZWN0aW9uSW5mbywgZmFsc2UsIGZhbHNlLCBuYW1lKTsiKyJyZXR1
-cm4gbmV3IGModGhpcywgZnVuY3NbMF0sIG51bGwsIG5hbWUpOyIrIn0iKShhLGIsYyxkLEgsbnVsbCl9
-ZnVuY3Rpb24gdGVhck9mZihhLGIsYyxkLGUsZil7dmFyIHQ9bnVsbApyZXR1cm4gZD9mdW5jdGlvbigp
-e2lmKHQ9PT1udWxsKXQ9SC51Yyh0aGlzLGEsYixjLHRydWUsZmFsc2UsZSkucHJvdG90eXBlCnJldHVy
-biB0fTp0ZWFyT2ZmR2V0dGVyKGEsYixjLGUsZil9dmFyIHg9MApmdW5jdGlvbiBpbnN0YWxsVGVhck9m
-ZihhLGIsYyxkLGUsZixnLGgsaSxqKXt2YXIgdD1bXQpmb3IodmFyIHM9MDtzPGgubGVuZ3RoO3MrKyl7
-dmFyIHI9aFtzXQppZih0eXBlb2Ygcj09J3N0cmluZycpcj1hW3JdCnIuJGNhbGxOYW1lPWdbc10KdC5w
-dXNoKHIpfXZhciByPXRbMF0Kci4kUj1lCnIuJEQ9Zgp2YXIgcT1pCmlmKHR5cGVvZiBxPT0ibnVtYmVy
-IilxKz14CnZhciBwPWhbMF0Kci4kc3R1Yk5hbWU9cAp2YXIgbz10ZWFyT2ZmKHQsanx8MCxxLGMscCxk
-KQphW2JdPW8KaWYoYylyLiR0ZWFyT2ZmPW99ZnVuY3Rpb24gaW5zdGFsbFN0YXRpY1RlYXJPZmYoYSxi
-LGMsZCxlLGYsZyxoKXtyZXR1cm4gaW5zdGFsbFRlYXJPZmYoYSxiLHRydWUsZmFsc2UsYyxkLGUsZixn
-LGgpfWZ1bmN0aW9uIGluc3RhbGxJbnN0YW5jZVRlYXJPZmYoYSxiLGMsZCxlLGYsZyxoLGkpe3JldHVy
-biBpbnN0YWxsVGVhck9mZihhLGIsZmFsc2UsYyxkLGUsZixnLGgsaSl9ZnVuY3Rpb24gc2V0T3JVcGRh
-dGVJbnRlcmNlcHRvcnNCeVRhZyhhKXt2YXIgdD12LmludGVyY2VwdG9yc0J5VGFnCmlmKCF0KXt2Lmlu
-dGVyY2VwdG9yc0J5VGFnPWEKcmV0dXJufWNvcHlQcm9wZXJ0aWVzKGEsdCl9ZnVuY3Rpb24gc2V0T3JV
-cGRhdGVMZWFmVGFncyhhKXt2YXIgdD12LmxlYWZUYWdzCmlmKCF0KXt2LmxlYWZUYWdzPWEKcmV0dXJu
-fWNvcHlQcm9wZXJ0aWVzKGEsdCl9ZnVuY3Rpb24gdXBkYXRlVHlwZXMoYSl7dmFyIHQ9di50eXBlcwp2
-YXIgcz10Lmxlbmd0aAp0LnB1c2guYXBwbHkodCxhKQpyZXR1cm4gc31mdW5jdGlvbiB1cGRhdGVIb2xk
-ZXIoYSxiKXtjb3B5UHJvcGVydGllcyhiLGEpCnJldHVybiBhfXZhciBodW5rSGVscGVycz1mdW5jdGlv
-bigpe3ZhciB0PWZ1bmN0aW9uKGEsYixjLGQsZSl7cmV0dXJuIGZ1bmN0aW9uKGYsZyxoLGkpe3JldHVy
-biBpbnN0YWxsSW5zdGFuY2VUZWFyT2ZmKGYsZyxhLGIsYyxkLFtoXSxpLGUpfX0scz1mdW5jdGlvbihh
-LGIsYyxkKXtyZXR1cm4gZnVuY3Rpb24oZSxmLGcsaCl7cmV0dXJuIGluc3RhbGxTdGF0aWNUZWFyT2Zm
-KGUsZixhLGIsYyxbZ10saCxkKX19CnJldHVybntpbmhlcml0OmluaGVyaXQsaW5oZXJpdE1hbnk6aW5o
-ZXJpdE1hbnksbWl4aW46bWl4aW4saW5zdGFsbFN0YXRpY1RlYXJPZmY6aW5zdGFsbFN0YXRpY1RlYXJP
-ZmYsaW5zdGFsbEluc3RhbmNlVGVhck9mZjppbnN0YWxsSW5zdGFuY2VUZWFyT2ZmLF9pbnN0YW5jZV8w
-dTp0KDAsMCxudWxsLFsiJDAiXSwwKSxfaW5zdGFuY2VfMXU6dCgwLDEsbnVsbCxbIiQxIl0sMCksX2lu
-c3RhbmNlXzJ1OnQoMCwyLG51bGwsWyIkMiJdLDApLF9pbnN0YW5jZV8waTp0KDEsMCxudWxsLFsiJDAi
-XSwwKSxfaW5zdGFuY2VfMWk6dCgxLDEsbnVsbCxbIiQxIl0sMCksX2luc3RhbmNlXzJpOnQoMSwyLG51
-bGwsWyIkMiJdLDApLF9zdGF0aWNfMDpzKDAsbnVsbCxbIiQwIl0sMCksX3N0YXRpY18xOnMoMSxudWxs
-LFsiJDEiXSwwKSxfc3RhdGljXzI6cygyLG51bGwsWyIkMiJdLDApLG1ha2VDb25zdExpc3Q6bWFrZUNv
-bnN0TGlzdCxsYXp5OmxhenksdXBkYXRlSG9sZGVyOnVwZGF0ZUhvbGRlcixjb252ZXJ0VG9GYXN0T2Jq
-ZWN0OmNvbnZlcnRUb0Zhc3RPYmplY3Qsc2V0RnVuY3Rpb25OYW1lc0lmTmVjZXNzYXJ5OnNldEZ1bmN0
-aW9uTmFtZXNJZk5lY2Vzc2FyeSx1cGRhdGVUeXBlczp1cGRhdGVUeXBlcyxzZXRPclVwZGF0ZUludGVy
-Y2VwdG9yc0J5VGFnOnNldE9yVXBkYXRlSW50ZXJjZXB0b3JzQnlUYWcsc2V0T3JVcGRhdGVMZWFmVGFn
-czpzZXRPclVwZGF0ZUxlYWZUYWdzfX0oKQpmdW5jdGlvbiBpbml0aWFsaXplRGVmZXJyZWRIdW5rKGEp
-e3g9di50eXBlcy5sZW5ndGgKYShodW5rSGVscGVycyx2LHcsJCl9ZnVuY3Rpb24gZ2V0R2xvYmFsRnJv
-bU5hbWUoYSl7Zm9yKHZhciB0PTA7dDx3Lmxlbmd0aDt0Kyspe2lmKHdbdF09PUMpY29udGludWUKaWYo
-d1t0XVthXSlyZXR1cm4gd1t0XVthXX19dmFyIEM9e30sSD17ZW86ZnVuY3Rpb24gZW8oKXt9LApvbzpm
-dW5jdGlvbihhKXt2YXIgdCxzPWFeNDgKaWYoczw9OSlyZXR1cm4gcwp0PWF8MzIKaWYoOTc8PXQmJnQ8
-PTEwMilyZXR1cm4gdC04NwpyZXR1cm4tMX0sCnFDOmZ1bmN0aW9uKGEsYixjLGQpe1AuazEoYiwic3Rh
-cnQiKQppZihjIT1udWxsKXtQLmsxKGMsImVuZCIpCmlmKGI+YylILlZqKFAuVEUoYiwwLGMsInN0YXJ0
-IixudWxsKSl9cmV0dXJuIG5ldyBILm5IKGEsYixjLGQuQygibkg8MD4iKSl9LApLMTpmdW5jdGlvbihh
-LGIsYyxkKXtpZih1Lmd3LmMoYSkpcmV0dXJuIG5ldyBILnh5KGEsYixjLkMoIkA8MD4iKS5LKGQpLkMo
-Inh5PDEsMj4iKSkKcmV0dXJuIG5ldyBILmkxKGEsYixjLkMoIkA8MD4iKS5LKGQpLkMoImkxPDEsMj4i
-KSl9LApXcDpmdW5jdGlvbigpe3JldHVybiBuZXcgUC5saigiTm8gZWxlbWVudCIpfSwKZFU6ZnVuY3Rp
-b24oKXtyZXR1cm4gbmV3IFAubGooIlRvbyBtYW55IGVsZW1lbnRzIil9LAphcjpmdW5jdGlvbigpe3Jl
-dHVybiBuZXcgUC5saigiVG9vIGZldyBlbGVtZW50cyIpfSwKcWo6ZnVuY3Rpb24gcWooYSl7dGhpcy5h
-PWF9LApiUTpmdW5jdGlvbiBiUSgpe30sCmFMOmZ1bmN0aW9uIGFMKCl7fSwKbkg6ZnVuY3Rpb24gbkgo
-YSxiLGMsZCl7dmFyIF89dGhpcwpfLmE9YQpfLmI9YgpfLmM9YwpfLiR0aT1kfSwKYTc6ZnVuY3Rpb24g
-YTcoYSxiLGMpe3ZhciBfPXRoaXMKXy5hPWEKXy5iPWIKXy5jPTAKXy5kPW51bGwKXy4kdGk9Y30sCmkx
-OmZ1bmN0aW9uIGkxKGEsYixjKXt0aGlzLmE9YQp0aGlzLmI9Ygp0aGlzLiR0aT1jfSwKeHk6ZnVuY3Rp
-b24geHkoYSxiLGMpe3RoaXMuYT1hCnRoaXMuYj1iCnRoaXMuJHRpPWN9LApNSDpmdW5jdGlvbiBNSChh
-LGIsYyl7dmFyIF89dGhpcwpfLmE9bnVsbApfLmI9YQpfLmM9YgpfLiR0aT1jfSwKQTg6ZnVuY3Rpb24g
-QTgoYSxiLGMpe3RoaXMuYT1hCnRoaXMuYj1iCnRoaXMuJHRpPWN9LApVNTpmdW5jdGlvbiBVNShhLGIs
-Yyl7dGhpcy5hPWEKdGhpcy5iPWIKdGhpcy4kdGk9Y30sClNPOmZ1bmN0aW9uIFNPKGEsYixjKXt0aGlz
-LmE9YQp0aGlzLmI9Ygp0aGlzLiR0aT1jfSwKU1U6ZnVuY3Rpb24gU1UoKXt9LApSZTpmdW5jdGlvbiBS
-ZSgpe30sClhDOmZ1bmN0aW9uIFhDKCl7fSwKd3Y6ZnVuY3Rpb24gd3YoYSl7dGhpcy5hPWF9LApkYzpm
-dW5jdGlvbigpe3Rocm93IEguYihQLkw0KCJDYW5ub3QgbW9kaWZ5IHVubW9kaWZpYWJsZSBNYXAiKSl9
-LApOUTpmdW5jdGlvbihhKXt2YXIgdCxzPUguSmcoYSkKaWYodHlwZW9mIHM9PSJzdHJpbmciKXJldHVy
-biBzCnQ9Im1pbmlmaWVkOiIrYQpyZXR1cm4gdH0sClh0OmZ1bmN0aW9uKGEsYil7dmFyIHQKaWYoYiE9
-bnVsbCl7dD1iLngKaWYodCE9bnVsbClyZXR1cm4gdH1yZXR1cm4gdS5hVS5jKGEpfSwKZDpmdW5jdGlv
-bihhKXt2YXIgdAppZih0eXBlb2YgYT09InN0cmluZyIpcmV0dXJuIGEKaWYodHlwZW9mIGE9PSJudW1i
-ZXIiKXtpZihhIT09MClyZXR1cm4iIithfWVsc2UgaWYoITA9PT1hKXJldHVybiJ0cnVlIgplbHNlIGlm
-KCExPT09YSlyZXR1cm4iZmFsc2UiCmVsc2UgaWYoYT09bnVsbClyZXR1cm4ibnVsbCIKdD1KLmooYSkK
-aWYodHlwZW9mIHQhPSJzdHJpbmciKXRocm93IEguYihILnRMKGEpKQpyZXR1cm4gdH0sCmVROmZ1bmN0
-aW9uKGEpe3ZhciB0PWEuJGlkZW50aXR5SGFzaAppZih0PT1udWxsKXt0PU1hdGgucmFuZG9tKCkqMHgz
-ZmZmZmZmZnwwCmEuJGlkZW50aXR5SGFzaD10fXJldHVybiB0fSwKSHA6ZnVuY3Rpb24oYSxiKXt2YXIg
-dCxzLHIscSxwLG8sbj1udWxsCmlmKHR5cGVvZiBhIT0ic3RyaW5nIilILlZqKEgudEwoYSkpCnQ9L15c
-cypbKy1dPygoMHhbYS1mMC05XSspfChcZCspfChbYS16MC05XSspKVxzKiQvaS5leGVjKGEpCmlmKHQ9
-PW51bGwpcmV0dXJuIG4KaWYoMz49dC5sZW5ndGgpcmV0dXJuIEguT0godCwzKQpzPUgueSh0WzNdKQpp
-ZihiPT1udWxsKXtpZihzIT1udWxsKXJldHVybiBwYXJzZUludChhLDEwKQppZih0WzJdIT1udWxsKXJl
-dHVybiBwYXJzZUludChhLDE2KQpyZXR1cm4gbn1pZihiPDJ8fGI+MzYpdGhyb3cgSC5iKFAuVEUoYiwy
-LDM2LCJyYWRpeCIsbikpCmlmKGI9PT0xMCYmcyE9bnVsbClyZXR1cm4gcGFyc2VJbnQoYSwxMCkKaWYo
-YjwxMHx8cz09bnVsbCl7cj1iPD0xMD80NytiOjg2K2IKcT10WzFdCmZvcihwPXEubGVuZ3RoLG89MDtv
-PHA7KytvKWlmKChDLnhCLldkKHEsbyl8MzIpPnIpcmV0dXJuIG59cmV0dXJuIHBhcnNlSW50KGEsYil9
-LApNOmZ1bmN0aW9uKGEpe3ZhciB0PUguSDUoYSkKcmV0dXJuIHR9LApINTpmdW5jdGlvbihhKXt2YXIg
-dCxzLHIKaWYoYSBpbnN0YW5jZW9mIFAuaylyZXR1cm4gSC5kbShILnpLKGEpLG51bGwpCmlmKEouaWEo
-YSk9PT1DLk9rfHx1LmFrLmMoYSkpe3Q9Qy5PNChhKQppZihILmYodCkpcmV0dXJuIHQKcz1hLmNvbnN0
-cnVjdG9yCmlmKHR5cGVvZiBzPT0iZnVuY3Rpb24iKXtyPXMubmFtZQppZih0eXBlb2Ygcj09InN0cmlu
-ZyImJkguZihyKSlyZXR1cm4gcn19cmV0dXJuIEguZG0oSC56SyhhKSxudWxsKX0sCmY6ZnVuY3Rpb24o
-YSl7dmFyIHQ9YSE9PSJPYmplY3QiJiZhIT09IiIKcmV0dXJuIHR9LApNMDpmdW5jdGlvbigpe2lmKCEh
-c2VsZi5sb2NhdGlvbilyZXR1cm4gc2VsZi5sb2NhdGlvbi5ocmVmCnJldHVybiBudWxsfSwKVks6ZnVu
-Y3Rpb24oYSl7dmFyIHQscyxyLHEscD1hLmxlbmd0aAppZihwPD01MDApcmV0dXJuIFN0cmluZy5mcm9t
-Q2hhckNvZGUuYXBwbHkobnVsbCxhKQpmb3IodD0iIixzPTA7czxwO3M9cil7cj1zKzUwMApxPXI8cD9y
-OnAKdCs9U3RyaW5nLmZyb21DaGFyQ29kZS5hcHBseShudWxsLGEuc2xpY2UocyxxKSl9cmV0dXJuIHR9
-LApDcTpmdW5jdGlvbihhKXt2YXIgdCxzLHIscT1ILlZNKFtdLHUudCkKZm9yKHQ9YS5sZW5ndGgscz0w
-O3M8YS5sZW5ndGg7YS5sZW5ndGg9PT10fHwoMCxILmxrKShhKSwrK3Mpe3I9YVtzXQppZighSC5vayhy
-KSl0aHJvdyBILmIoSC50TChyKSkKaWYocjw9NjU1MzUpQy5ObS5BKHEscikKZWxzZSBpZihyPD0xMTE0
-MTExKXtDLk5tLkEocSw1NTI5NisoQy5qbi53RyhyLTY1NTM2LDEwKSYxMDIzKSkKQy5ObS5BKHEsNTYz
-MjArKHImMTAyMykpfWVsc2UgdGhyb3cgSC5iKEgudEwocikpfXJldHVybiBILlZLKHEpfSwKZVQ6ZnVu
-Y3Rpb24oYSl7dmFyIHQscyxyCmZvcih0PWEubGVuZ3RoLHM9MDtzPHQ7KytzKXtyPWFbc10KaWYoIUgu
-b2socikpdGhyb3cgSC5iKEgudEwocikpCmlmKHI8MCl0aHJvdyBILmIoSC50TChyKSkKaWYocj42NTUz
-NSlyZXR1cm4gSC5DcShhKX1yZXR1cm4gSC5WSyhhKX0sCmZ3OmZ1bmN0aW9uKGEsYixjKXt2YXIgdCxz
-LHIscQppZihjPD01MDAmJmI9PT0wJiZjPT09YS5sZW5ndGgpcmV0dXJuIFN0cmluZy5mcm9tQ2hhckNv
-ZGUuYXBwbHkobnVsbCxhKQpmb3IodD1iLHM9IiI7dDxjO3Q9cil7cj10KzUwMApxPXI8Yz9yOmMKcys9
-U3RyaW5nLmZyb21DaGFyQ29kZS5hcHBseShudWxsLGEuc3ViYXJyYXkodCxxKSl9cmV0dXJuIHN9LApM
-dzpmdW5jdGlvbihhKXt2YXIgdAppZigwPD1hKXtpZihhPD02NTUzNSlyZXR1cm4gU3RyaW5nLmZyb21D
-aGFyQ29kZShhKQppZihhPD0xMTE0MTExKXt0PWEtNjU1MzYKcmV0dXJuIFN0cmluZy5mcm9tQ2hhckNv
-ZGUoKDU1Mjk2fEMuam4ud0codCwxMCkpPj4+MCw1NjMyMHx0JjEwMjMpfX10aHJvdyBILmIoUC5URShh
-LDAsMTExNDExMSxudWxsLG51bGwpKX0sCm8yOmZ1bmN0aW9uKGEpe2lmKGEuZGF0ZT09PXZvaWQgMClh
-LmRhdGU9bmV3IERhdGUoYS5hKQpyZXR1cm4gYS5kYXRlfSwKdEo6ZnVuY3Rpb24oYSl7cmV0dXJuIGEu
-Yj9ILm8yKGEpLmdldFVUQ0Z1bGxZZWFyKCkrMDpILm8yKGEpLmdldEZ1bGxZZWFyKCkrMH0sCk5TOmZ1
-bmN0aW9uKGEpe3JldHVybiBhLmI/SC5vMihhKS5nZXRVVENNb250aCgpKzE6SC5vMihhKS5nZXRNb250
-aCgpKzF9LApqQTpmdW5jdGlvbihhKXtyZXR1cm4gYS5iP0gubzIoYSkuZ2V0VVRDRGF0ZSgpKzA6SC5v
-MihhKS5nZXREYXRlKCkrMH0sCktMOmZ1bmN0aW9uKGEpe3JldHVybiBhLmI/SC5vMihhKS5nZXRVVENI
-b3VycygpKzA6SC5vMihhKS5nZXRIb3VycygpKzB9LApjaDpmdW5jdGlvbihhKXtyZXR1cm4gYS5iP0gu
-bzIoYSkuZ2V0VVRDTWludXRlcygpKzA6SC5vMihhKS5nZXRNaW51dGVzKCkrMH0sCkpkOmZ1bmN0aW9u
-KGEpe3JldHVybiBhLmI/SC5vMihhKS5nZXRVVENTZWNvbmRzKCkrMDpILm8yKGEpLmdldFNlY29uZHMo
-KSswfSwKbzE6ZnVuY3Rpb24oYSl7cmV0dXJuIGEuYj9ILm8yKGEpLmdldFVUQ01pbGxpc2Vjb25kcygp
-KzA6SC5vMihhKS5nZXRNaWxsaXNlY29uZHMoKSswfSwKem86ZnVuY3Rpb24oYSxiLGMpe3ZhciB0LHMs
-cj17fQpyLmE9MAp0PVtdCnM9W10Kci5hPWIubGVuZ3RoCkMuTm0uRlYodCxiKQpyLmI9IiIKaWYoYyE9
-bnVsbCYmYy5hIT09MCljLlUoMCxuZXcgSC5DaihyLHMsdCkpCiIiK3IuYQpyZXR1cm4gSi5KeShhLG5l
-dyBILkxJKEMuVGUsMCx0LHMsMCkpfSwKRWs6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0LHMscixxCmlmKGIg
-aW5zdGFuY2VvZiBBcnJheSl0PWM9PW51bGx8fGMuYT09PTAKZWxzZSB0PSExCmlmKHQpe3M9YgpyPXMu
-bGVuZ3RoCmlmKHI9PT0wKXtpZighIWEuJDApcmV0dXJuIGEuJDAoKX1lbHNlIGlmKHI9PT0xKXtpZigh
-IWEuJDEpcmV0dXJuIGEuJDEoc1swXSl9ZWxzZSBpZihyPT09Mil7aWYoISFhLiQyKXJldHVybiBhLiQy
-KHNbMF0sc1sxXSl9ZWxzZSBpZihyPT09Myl7aWYoISFhLiQzKXJldHVybiBhLiQzKHNbMF0sc1sxXSxz
-WzJdKX1lbHNlIGlmKHI9PT00KXtpZighIWEuJDQpcmV0dXJuIGEuJDQoc1swXSxzWzFdLHNbMl0sc1sz
-XSl9ZWxzZSBpZihyPT09NSlpZighIWEuJDUpcmV0dXJuIGEuJDUoc1swXSxzWzFdLHNbMl0sc1szXSxz
-WzRdKQpxPWFbIiIrIiQiK3JdCmlmKHEhPW51bGwpcmV0dXJuIHEuYXBwbHkoYSxzKX1yZXR1cm4gSC5F
-dyhhLGIsYyl9LApFdzpmdW5jdGlvbihhLGIsYyl7dmFyIHQscyxyLHEscCxvLG4sbSxsLGs9YiBpbnN0
-YW5jZW9mIEFycmF5P2I6UC5DSChiLCEwLHUueiksaj1rLmxlbmd0aCxpPWEuJFIKaWYoajxpKXJldHVy
-biBILnpvKGEsayxjKQp0PWEuJEQKcz10PT1udWxsCnI9IXM/dCgpOm51bGwKcT1KLmlhKGEpCnA9cS4k
-QwppZih0eXBlb2YgcD09InN0cmluZyIpcD1xW3BdCmlmKHMpe2lmKGMhPW51bGwmJmMuYSE9PTApcmV0
-dXJuIEguem8oYSxrLGMpCmlmKGo9PT1pKXJldHVybiBwLmFwcGx5KGEsaykKcmV0dXJuIEguem8oYSxr
-LGMpfWlmKHIgaW5zdGFuY2VvZiBBcnJheSl7aWYoYyE9bnVsbCYmYy5hIT09MClyZXR1cm4gSC56byhh
-LGssYykKaWYoaj5pK3IubGVuZ3RoKXJldHVybiBILnpvKGEsayxudWxsKQpDLk5tLkZWKGssci5zbGlj
-ZShqLWkpKQpyZXR1cm4gcC5hcHBseShhLGspfWVsc2V7aWYoaj5pKXJldHVybiBILnpvKGEsayxjKQpv
-PU9iamVjdC5rZXlzKHIpCmlmKGM9PW51bGwpZm9yKHM9by5sZW5ndGgsbj0wO248by5sZW5ndGg7by5s
-ZW5ndGg9PT1zfHwoMCxILmxrKShvKSwrK24pQy5ObS5BKGsscltILnkob1tuXSldKQplbHNle2Zvcihz
-PW8ubGVuZ3RoLG09MCxuPTA7bjxvLmxlbmd0aDtvLmxlbmd0aD09PXN8fCgwLEgubGspKG8pLCsrbil7
-bD1ILnkob1tuXSkKaWYoYy54NCgwLGwpKXsrK20KQy5ObS5BKGssYy5xKDAsbCkpfWVsc2UgQy5ObS5B
-KGsscltsXSl9aWYobSE9PWMuYSlyZXR1cm4gSC56byhhLGssYyl9cmV0dXJuIHAuYXBwbHkoYSxrKX19
-LApwWTpmdW5jdGlvbihhKXt0aHJvdyBILmIoSC50TChhKSl9LApPSDpmdW5jdGlvbihhLGIpe2lmKGE9
-PW51bGwpSi5IbShhKQp0aHJvdyBILmIoSC5IWShhLGIpKX0sCkhZOmZ1bmN0aW9uKGEsYil7dmFyIHQs
-cyxyPSJpbmRleCIKaWYoIUgub2soYikpcmV0dXJuIG5ldyBQLnUoITAsYixyLG51bGwpCnQ9SC5TYyhK
-LkhtKGEpKQppZighKGI8MCkpe2lmKHR5cGVvZiB0IT09Im51bWJlciIpcmV0dXJuIEgucFkodCkKcz1i
-Pj10fWVsc2Ugcz0hMAppZihzKXJldHVybiBQLkNmKGIsYSxyLG51bGwsdCkKcmV0dXJuIFAueChiLHIp
-fSwKYXU6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0PSJJbnZhbGlkIHZhbHVlIgppZihhPmMpcmV0dXJuIG5l
-dyBQLmJKKDAsYywhMCxhLCJzdGFydCIsdCkKaWYoYiE9bnVsbCl7aWYoIUgub2soYikpcmV0dXJuIG5l
-dyBQLnUoITAsYiwiZW5kIixudWxsKQppZihiPGF8fGI+YylyZXR1cm4gbmV3IFAuYkooYSxjLCEwLGIs
-ImVuZCIsdCl9cmV0dXJuIG5ldyBQLnUoITAsYiwiZW5kIixudWxsKX0sCnRMOmZ1bmN0aW9uKGEpe3Jl
-dHVybiBuZXcgUC51KCEwLGEsbnVsbCxudWxsKX0sCmI6ZnVuY3Rpb24oYSl7dmFyIHQKaWYoYT09bnVs
-bClhPW5ldyBQLm4oKQp0PW5ldyBFcnJvcigpCnQuZGFydEV4Y2VwdGlvbj1hCmlmKCJkZWZpbmVQcm9w
-ZXJ0eSIgaW4gT2JqZWN0KXtPYmplY3QuZGVmaW5lUHJvcGVydHkodCwibWVzc2FnZSIse2dldDpILmh9
-KQp0Lm5hbWU9IiJ9ZWxzZSB0LnRvU3RyaW5nPUguaApyZXR1cm4gdH0sCmg6ZnVuY3Rpb24oKXtyZXR1
-cm4gSi5qKHRoaXMuZGFydEV4Y2VwdGlvbil9LApWajpmdW5jdGlvbihhKXt0aHJvdyBILmIoYSl9LAps
-azpmdW5jdGlvbihhKXt0aHJvdyBILmIoUC5hNChhKSl9LApjTTpmdW5jdGlvbihhKXt2YXIgdCxzLHIs
-cSxwLG8KYT1ILmVBKGEucmVwbGFjZShTdHJpbmcoe30pLCckcmVjZWl2ZXIkJykpCnQ9YS5tYXRjaCgv
-XFxcJFthLXpBLVpdK1xcXCQvZykKaWYodD09bnVsbCl0PUguVk0oW10sdS5zKQpzPXQuaW5kZXhPZigi
-XFwkYXJndW1lbnRzXFwkIikKcj10LmluZGV4T2YoIlxcJGFyZ3VtZW50c0V4cHJcXCQiKQpxPXQuaW5k
-ZXhPZigiXFwkZXhwclxcJCIpCnA9dC5pbmRleE9mKCJcXCRtZXRob2RcXCQiKQpvPXQuaW5kZXhPZigi
-XFwkcmVjZWl2ZXJcXCQiKQpyZXR1cm4gbmV3IEguZjkoYS5yZXBsYWNlKG5ldyBSZWdFeHAoJ1xcXFxc
-XCRhcmd1bWVudHNcXFxcXFwkJywnZycpLCcoKD86eHxbXnhdKSopJykucmVwbGFjZShuZXcgUmVnRXhw
-KCdcXFxcXFwkYXJndW1lbnRzRXhwclxcXFxcXCQnLCdnJyksJygoPzp4fFteeF0pKiknKS5yZXBsYWNl
-KG5ldyBSZWdFeHAoJ1xcXFxcXCRleHByXFxcXFxcJCcsJ2cnKSwnKCg/Onh8W154XSkqKScpLnJlcGxh
-Y2UobmV3IFJlZ0V4cCgnXFxcXFxcJG1ldGhvZFxcXFxcXCQnLCdnJyksJygoPzp4fFteeF0pKiknKS5y
-ZXBsYWNlKG5ldyBSZWdFeHAoJ1xcXFxcXCRyZWNlaXZlclxcXFxcXCQnLCdnJyksJygoPzp4fFteeF0p
-KiknKSxzLHIscSxwLG8pfSwKUzc6ZnVuY3Rpb24oYSl7cmV0dXJuIGZ1bmN0aW9uKCRleHByJCl7dmFy
-ICRhcmd1bWVudHNFeHByJD0nJGFyZ3VtZW50cyQnCnRyeXskZXhwciQuJG1ldGhvZCQoJGFyZ3VtZW50
-c0V4cHIkKX1jYXRjaCh0KXtyZXR1cm4gdC5tZXNzYWdlfX0oYSl9LApNajpmdW5jdGlvbihhKXtyZXR1
-cm4gZnVuY3Rpb24oJGV4cHIkKXt0cnl7JGV4cHIkLiRtZXRob2QkfWNhdGNoKHQpe3JldHVybiB0Lm1l
-c3NhZ2V9fShhKX0sCklqOmZ1bmN0aW9uKGEsYil7cmV0dXJuIG5ldyBILlcwKGEsYj09bnVsbD9udWxs
-OmIubWV0aG9kKX0sClQzOmZ1bmN0aW9uKGEsYil7dmFyIHQ9Yj09bnVsbCxzPXQ/bnVsbDpiLm1ldGhv
-ZApyZXR1cm4gbmV3IEguYXooYSxzLHQ/bnVsbDpiLnJlY2VpdmVyKX0sClJ1OmZ1bmN0aW9uKGEpe3Zh
-ciB0LHMscixxLHAsbyxuLG0sbCxrLGosaSxoLGcsZj1udWxsLGU9bmV3IEguQW0oYSkKaWYoYT09bnVs
-bClyZXR1cm4gZgppZihhIGluc3RhbmNlb2YgSC5icSlyZXR1cm4gZS4kMShhLmEpCmlmKHR5cGVvZiBh
-IT09Im9iamVjdCIpcmV0dXJuIGEKaWYoImRhcnRFeGNlcHRpb24iIGluIGEpcmV0dXJuIGUuJDEoYS5k
-YXJ0RXhjZXB0aW9uKQplbHNlIGlmKCEoIm1lc3NhZ2UiIGluIGEpKXJldHVybiBhCnQ9YS5tZXNzYWdl
-CmlmKCJudW1iZXIiIGluIGEmJnR5cGVvZiBhLm51bWJlcj09Im51bWJlciIpe3M9YS5udW1iZXIKcj1z
-JjY1NTM1CmlmKChDLmpuLndHKHMsMTYpJjgxOTEpPT09MTApc3dpdGNoKHIpe2Nhc2UgNDM4OnJldHVy
-biBlLiQxKEguVDMoSC5kKHQpKyIgKEVycm9yICIrcisiKSIsZikpCmNhc2UgNDQ1OmNhc2UgNTAwNzpy
-ZXR1cm4gZS4kMShILklqKEguZCh0KSsiIChFcnJvciAiK3IrIikiLGYpKX19aWYoYSBpbnN0YW5jZW9m
-IFR5cGVFcnJvcil7cT0kLlNuKCkKcD0kLmxxKCkKbz0kLk45KCkKbj0kLmlJKCkKbT0kLktmKCkKbD0k
-LlpoKCkKaz0kLnJOKCkKJC5jMygpCmo9JC5ISygpCmk9JC5yMSgpCmg9cS5xUyh0KQppZihoIT1udWxs
-KXJldHVybiBlLiQxKEguVDMoSC55KHQpLGgpKQplbHNle2g9cC5xUyh0KQppZihoIT1udWxsKXtoLm1l
-dGhvZD0iY2FsbCIKcmV0dXJuIGUuJDEoSC5UMyhILnkodCksaCkpfWVsc2V7aD1vLnFTKHQpCmlmKGg9
-PW51bGwpe2g9bi5xUyh0KQppZihoPT1udWxsKXtoPW0ucVModCkKaWYoaD09bnVsbCl7aD1sLnFTKHQp
-CmlmKGg9PW51bGwpe2g9ay5xUyh0KQppZihoPT1udWxsKXtoPW4ucVModCkKaWYoaD09bnVsbCl7aD1q
-LnFTKHQpCmlmKGg9PW51bGwpe2g9aS5xUyh0KQpnPWghPW51bGx9ZWxzZSBnPSEwfWVsc2UgZz0hMH1l
-bHNlIGc9ITB9ZWxzZSBnPSEwfWVsc2UgZz0hMH1lbHNlIGc9ITB9ZWxzZSBnPSEwCmlmKGcpcmV0dXJu
-IGUuJDEoSC5JaihILnkodCksaCkpfX1yZXR1cm4gZS4kMShuZXcgSC52Vih0eXBlb2YgdD09InN0cmlu
-ZyI/dDoiIikpfWlmKGEgaW5zdGFuY2VvZiBSYW5nZUVycm9yKXtpZih0eXBlb2YgdD09InN0cmluZyIm
-JnQuaW5kZXhPZigiY2FsbCBzdGFjayIpIT09LTEpcmV0dXJuIG5ldyBQLktZKCkKdD1mdW5jdGlvbihi
-KXt0cnl7cmV0dXJuIFN0cmluZyhiKX1jYXRjaChkKXt9cmV0dXJuIG51bGx9KGEpCnJldHVybiBlLiQx
-KG5ldyBQLnUoITEsZixmLHR5cGVvZiB0PT0ic3RyaW5nIj90LnJlcGxhY2UoL15SYW5nZUVycm9yOlxz
-Ki8sIiIpOnQpKX1pZih0eXBlb2YgSW50ZXJuYWxFcnJvcj09ImZ1bmN0aW9uIiYmYSBpbnN0YW5jZW9m
-IEludGVybmFsRXJyb3IpaWYodHlwZW9mIHQ9PSJzdHJpbmciJiZ0PT09InRvbyBtdWNoIHJlY3Vyc2lv
-biIpcmV0dXJuIG5ldyBQLktZKCkKcmV0dXJuIGF9LAp0czpmdW5jdGlvbihhKXt2YXIgdAppZihhIGlu
-c3RhbmNlb2YgSC5icSlyZXR1cm4gYS5iCmlmKGE9PW51bGwpcmV0dXJuIG5ldyBILlhPKGEpCnQ9YS4k
-Y2FjaGVkVHJhY2UKaWYodCE9bnVsbClyZXR1cm4gdApyZXR1cm4gYS4kY2FjaGVkVHJhY2U9bmV3IEgu
-WE8oYSl9LApCNzpmdW5jdGlvbihhLGIpe3ZhciB0LHMscixxPWEubGVuZ3RoCmZvcih0PTA7dDxxO3Q9
-cil7cz10KzEKcj1zKzEKYi5ZKDAsYVt0XSxhW3NdKX1yZXR1cm4gYn0sCmZ0OmZ1bmN0aW9uKGEsYixj
-LGQsZSxmKXt1LlouYihhKQpzd2l0Y2goSC5TYyhiKSl7Y2FzZSAwOnJldHVybiBhLiQwKCkKY2FzZSAx
-OnJldHVybiBhLiQxKGMpCmNhc2UgMjpyZXR1cm4gYS4kMihjLGQpCmNhc2UgMzpyZXR1cm4gYS4kMyhj
-LGQsZSkKY2FzZSA0OnJldHVybiBhLiQ0KGMsZCxlLGYpfXRocm93IEguYihuZXcgUC5DRCgiVW5zdXBw
-b3J0ZWQgbnVtYmVyIG9mIGFyZ3VtZW50cyBmb3Igd3JhcHBlZCBjbG9zdXJlIikpfSwKdFI6ZnVuY3Rp
-b24oYSxiKXt2YXIgdAppZihhPT1udWxsKXJldHVybiBudWxsCnQ9YS4kaWRlbnRpdHkKaWYoISF0KXJl
-dHVybiB0CnQ9ZnVuY3Rpb24oYyxkLGUpe3JldHVybiBmdW5jdGlvbihmLGcsaCxpKXtyZXR1cm4gZShj
-LGQsZixnLGgsaSl9fShhLGIsSC5mdCkKYS4kaWRlbnRpdHk9dApyZXR1cm4gdH0sCmlBOmZ1bmN0aW9u
-KGEsYixjLGQsZSxmLGcpe3ZhciB0LHMscixxLHAsbyxuLG0sbD1udWxsLGs9YlswXSxqPWsuJGNhbGxO
-YW1lLGk9ZT9PYmplY3QuY3JlYXRlKG5ldyBILnp4KCkuY29uc3RydWN0b3IucHJvdG90eXBlKTpPYmpl
-Y3QuY3JlYXRlKG5ldyBILnJUKGwsbCxsLGwpLmNvbnN0cnVjdG9yLnByb3RvdHlwZSkKaS4kaW5pdGlh
-bGl6ZT1pLmNvbnN0cnVjdG9yCmlmKGUpdD1mdW5jdGlvbiBzdGF0aWNfdGVhcl9vZmYoKXt0aGlzLiRp
-bml0aWFsaXplKCl9CmVsc2V7cz0kLnlqCmlmKHR5cGVvZiBzIT09Im51bWJlciIpcmV0dXJuIHMuVCgp
-CiQueWo9cysxCnM9bmV3IEZ1bmN0aW9uKCJhLGIsYyxkIitzLCJ0aGlzLiRpbml0aWFsaXplKGEsYixj
-LGQiK3MrIikiKQp0PXN9aS5jb25zdHJ1Y3Rvcj10CnQucHJvdG90eXBlPWkKaWYoIWUpe3I9SC5ieChh
-LGssZikKci4kcmVmbGVjdGlvbkluZm89ZH1lbHNle2kuJHN0YXRpY19uYW1lPWcKcj1rfXE9SC5pbShk
-LGUsZikKaS4kUz1xCmlbal09cgpmb3IocD1yLG89MTtvPGIubGVuZ3RoOysrbyl7bj1iW29dCm09bi4k
-Y2FsbE5hbWUKaWYobSE9bnVsbCl7bj1lP246SC5ieChhLG4sZikKaVttXT1ufWlmKG89PT1jKXtuLiRy
-ZWZsZWN0aW9uSW5mbz1kCnA9bn19aS4kQz1wCmkuJFI9ay4kUgppLiREPWsuJEQKcmV0dXJuIHR9LApp
-bTpmdW5jdGlvbihhLGIsYyl7dmFyIHQKaWYodHlwZW9mIGE9PSJudW1iZXIiKXJldHVybiBmdW5jdGlv
-bihkLGUpe3JldHVybiBmdW5jdGlvbigpe3JldHVybiBkKGUpfX0oSC5CcCxhKQppZih0eXBlb2YgYT09
-InN0cmluZyIpe2lmKGIpdGhyb3cgSC5iKCJDYW5ub3QgY29tcHV0ZSBzaWduYXR1cmUgZm9yIHN0YXRp
-YyB0ZWFyb2ZmLiIpCnQ9Yz9ILlBXOkguVG4KcmV0dXJuIGZ1bmN0aW9uKGQsZSl7cmV0dXJuIGZ1bmN0
-aW9uKCl7cmV0dXJuIGUodGhpcyxkKX19KGEsdCl9dGhyb3cgSC5iKCJFcnJvciBpbiBmdW5jdGlvblR5
-cGUgb2YgdGVhcm9mZiIpfSwKdnE6ZnVuY3Rpb24oYSxiLGMsZCl7dmFyIHQ9SC5EVgpzd2l0Y2goYj8t
-MTphKXtjYXNlIDA6cmV0dXJuIGZ1bmN0aW9uKGUsZil7cmV0dXJuIGZ1bmN0aW9uKCl7cmV0dXJuIGYo
-dGhpcylbZV0oKX19KGMsdCkKY2FzZSAxOnJldHVybiBmdW5jdGlvbihlLGYpe3JldHVybiBmdW5jdGlv
-bihnKXtyZXR1cm4gZih0aGlzKVtlXShnKX19KGMsdCkKY2FzZSAyOnJldHVybiBmdW5jdGlvbihlLGYp
-e3JldHVybiBmdW5jdGlvbihnLGgpe3JldHVybiBmKHRoaXMpW2VdKGcsaCl9fShjLHQpCmNhc2UgMzpy
-ZXR1cm4gZnVuY3Rpb24oZSxmKXtyZXR1cm4gZnVuY3Rpb24oZyxoLGkpe3JldHVybiBmKHRoaXMpW2Vd
-KGcsaCxpKX19KGMsdCkKY2FzZSA0OnJldHVybiBmdW5jdGlvbihlLGYpe3JldHVybiBmdW5jdGlvbihn
-LGgsaSxqKXtyZXR1cm4gZih0aGlzKVtlXShnLGgsaSxqKX19KGMsdCkKY2FzZSA1OnJldHVybiBmdW5j
-dGlvbihlLGYpe3JldHVybiBmdW5jdGlvbihnLGgsaSxqLGspe3JldHVybiBmKHRoaXMpW2VdKGcsaCxp
-LGosayl9fShjLHQpCmRlZmF1bHQ6cmV0dXJuIGZ1bmN0aW9uKGUsZil7cmV0dXJuIGZ1bmN0aW9uKCl7
-cmV0dXJuIGUuYXBwbHkoZih0aGlzKSxhcmd1bWVudHMpfX0oZCx0KX19LApieDpmdW5jdGlvbihhLGIs
-Yyl7dmFyIHQscyxyLHEscCxvLG4KaWYoYylyZXR1cm4gSC5IZihhLGIpCnQ9Yi4kc3R1Yk5hbWUKcz1i
-Lmxlbmd0aApyPWFbdF0KcT1iPT1udWxsP3I9PW51bGw6Yj09PXIKcD0hcXx8cz49MjcKaWYocClyZXR1
-cm4gSC52cShzLCFxLHQsYikKaWYocz09PTApe3E9JC55agppZih0eXBlb2YgcSE9PSJudW1iZXIiKXJl
-dHVybiBxLlQoKQokLnlqPXErMQpvPSJzZWxmIitxCnE9InJldHVybiBmdW5jdGlvbigpe3ZhciAiK28r
-IiA9IHRoaXMuIgpwPSQubUoKcmV0dXJuIG5ldyBGdW5jdGlvbihxK0guZChwPT1udWxsPyQubUo9SC5F
-Migic2VsZiIpOnApKyI7cmV0dXJuICIrbysiLiIrSC5kKHQpKyIoKTt9IikoKX1uPSJhYmNkZWZnaGlq
-a2xtbm9wcXJzdHV2d3h5eiIuc3BsaXQoIiIpLnNwbGljZSgwLHMpLmpvaW4oIiwiKQpxPSQueWoKaWYo
-dHlwZW9mIHEhPT0ibnVtYmVyIilyZXR1cm4gcS5UKCkKJC55aj1xKzEKbis9cQpxPSJyZXR1cm4gZnVu
-Y3Rpb24oIituKyIpe3JldHVybiB0aGlzLiIKcD0kLm1KCnJldHVybiBuZXcgRnVuY3Rpb24ocStILmQo
-cD09bnVsbD8kLm1KPUguRTIoInNlbGYiKTpwKSsiLiIrSC5kKHQpKyIoIituKyIpO30iKSgpfSwKWjQ6
-ZnVuY3Rpb24oYSxiLGMsZCl7dmFyIHQ9SC5EVixzPUgueVMKc3dpdGNoKGI/LTE6YSl7Y2FzZSAwOnRo
-cm93IEguYihILkVmKCJJbnRlcmNlcHRlZCBmdW5jdGlvbiB3aXRoIG5vIGFyZ3VtZW50cy4iKSkKY2Fz
-ZSAxOnJldHVybiBmdW5jdGlvbihlLGYsZyl7cmV0dXJuIGZ1bmN0aW9uKCl7cmV0dXJuIGYodGhpcylb
-ZV0oZyh0aGlzKSl9fShjLHQscykKY2FzZSAyOnJldHVybiBmdW5jdGlvbihlLGYsZyl7cmV0dXJuIGZ1
-bmN0aW9uKGgpe3JldHVybiBmKHRoaXMpW2VdKGcodGhpcyksaCl9fShjLHQscykKY2FzZSAzOnJldHVy
-biBmdW5jdGlvbihlLGYsZyl7cmV0dXJuIGZ1bmN0aW9uKGgsaSl7cmV0dXJuIGYodGhpcylbZV0oZyh0
-aGlzKSxoLGkpfX0oYyx0LHMpCmNhc2UgNDpyZXR1cm4gZnVuY3Rpb24oZSxmLGcpe3JldHVybiBmdW5j
-dGlvbihoLGksail7cmV0dXJuIGYodGhpcylbZV0oZyh0aGlzKSxoLGksail9fShjLHQscykKY2FzZSA1
-OnJldHVybiBmdW5jdGlvbihlLGYsZyl7cmV0dXJuIGZ1bmN0aW9uKGgsaSxqLGspe3JldHVybiBmKHRo
-aXMpW2VdKGcodGhpcyksaCxpLGosayl9fShjLHQscykKY2FzZSA2OnJldHVybiBmdW5jdGlvbihlLGYs
-Zyl7cmV0dXJuIGZ1bmN0aW9uKGgsaSxqLGssbCl7cmV0dXJuIGYodGhpcylbZV0oZyh0aGlzKSxoLGks
-aixrLGwpfX0oYyx0LHMpCmRlZmF1bHQ6cmV0dXJuIGZ1bmN0aW9uKGUsZixnLGgpe3JldHVybiBmdW5j
-dGlvbigpe2g9W2codGhpcyldCkFycmF5LnByb3RvdHlwZS5wdXNoLmFwcGx5KGgsYXJndW1lbnRzKQpy
-ZXR1cm4gZS5hcHBseShmKHRoaXMpLGgpfX0oZCx0LHMpfX0sCkhmOmZ1bmN0aW9uKGEsYil7dmFyIHQs
-cyxyLHEscCxvLG4sbT0kLm1KCmlmKG09PW51bGwpbT0kLm1KPUguRTIoInNlbGYiKQp0PSQuUDQKaWYo
-dD09bnVsbCl0PSQuUDQ9SC5FMigicmVjZWl2ZXIiKQpzPWIuJHN0dWJOYW1lCnI9Yi5sZW5ndGgKcT1h
-W3NdCnA9Yj09bnVsbD9xPT1udWxsOmI9PT1xCm89IXB8fHI+PTI4CmlmKG8pcmV0dXJuIEguWjQociwh
-cCxzLGIpCmlmKHI9PT0xKXttPSJyZXR1cm4gZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy4iK0guZChtKSsi
-LiIrSC5kKHMpKyIodGhpcy4iK0guZCh0KSsiKTsiCnQ9JC55agppZih0eXBlb2YgdCE9PSJudW1iZXIi
-KXJldHVybiB0LlQoKQokLnlqPXQrMQpyZXR1cm4gbmV3IEZ1bmN0aW9uKG0rdCsifSIpKCl9bj0iYWJj
-ZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXoiLnNwbGl0KCIiKS5zcGxpY2UoMCxyLTEpLmpvaW4oIiwiKQpt
-PSJyZXR1cm4gZnVuY3Rpb24oIituKyIpe3JldHVybiB0aGlzLiIrSC5kKG0pKyIuIitILmQocykrIih0
-aGlzLiIrSC5kKHQpKyIsICIrbisiKTsiCnQ9JC55agppZih0eXBlb2YgdCE9PSJudW1iZXIiKXJldHVy
-biB0LlQoKQokLnlqPXQrMQpyZXR1cm4gbmV3IEZ1bmN0aW9uKG0rdCsifSIpKCl9LAp1YzpmdW5jdGlv
-bihhLGIsYyxkLGUsZixnKXtyZXR1cm4gSC5pQShhLGIsYyxkLCEhZSwhIWYsZyl9LApUbjpmdW5jdGlv
-bihhLGIpe3JldHVybiBILmNFKHYudHlwZVVuaXZlcnNlLEgueksoYS5hKSxiKX0sClBXOmZ1bmN0aW9u
-KGEsYil7cmV0dXJuIEguY0Uodi50eXBlVW5pdmVyc2UsSC56SyhhLmMpLGIpfSwKRFY6ZnVuY3Rpb24o
-YSl7cmV0dXJuIGEuYX0sCnlTOmZ1bmN0aW9uKGEpe3JldHVybiBhLmN9LApFMjpmdW5jdGlvbihhKXt2
-YXIgdCxzLHIscT1uZXcgSC5yVCgic2VsZiIsInRhcmdldCIsInJlY2VpdmVyIiwibmFtZSIpLHA9Si5F
-cChPYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lcyhxKSkKZm9yKHQ9cC5sZW5ndGgscz0wO3M8dDsrK3Mp
-e3I9cFtzXQppZihxW3JdPT09YSlyZXR1cm4gcn19LApvVDpmdW5jdGlvbihhKXtpZihhPT1udWxsKUgu
-Zk8oImJvb2xlYW4gZXhwcmVzc2lvbiBtdXN0IG5vdCBiZSBudWxsIikKcmV0dXJuIGF9LApmTzpmdW5j
-dGlvbihhKXt0aHJvdyBILmIobmV3IEgua1koYSkpfSwKYWc6ZnVuY3Rpb24oYSl7dGhyb3cgSC5iKG5l
-dyBQLmMoYSkpfSwKRWY6ZnVuY3Rpb24oYSl7cmV0dXJuIG5ldyBILkVxKGEpfSwKWWc6ZnVuY3Rpb24o
-YSl7cmV0dXJuIHYuZ2V0SXNvbGF0ZVRhZyhhKX0sClZNOmZ1bmN0aW9uKGEsYil7YS4kdGk9YgpyZXR1
-cm4gYX0sCm9YOmZ1bmN0aW9uKGEpe2lmKGE9PW51bGwpcmV0dXJuIG51bGwKcmV0dXJuIGEuJHRpfSwK
-SU06ZnVuY3Rpb24oYSxiLGMpe3JldHVybiBILlk5KGFbIiRhIitILmQoYyldLEgub1goYikpfSwKWTk6
-ZnVuY3Rpb24oYSxiKXtpZihhPT1udWxsKXJldHVybiBiCmE9YS5hcHBseShudWxsLGIpCmlmKGE9PW51
-bGwpcmV0dXJuIG51bGwKaWYoQXJyYXkuaXNBcnJheShhKSlyZXR1cm4gYQppZih0eXBlb2YgYT09ImZ1
-bmN0aW9uIilyZXR1cm4gYS5hcHBseShudWxsLGIpCnJldHVybiBifSwKRlo6ZnVuY3Rpb24oYSxiLGMp
-e3JldHVybiBhLmFwcGx5KGIsSC5ZOShKLmlhKGIpWyIkYSIrSC5kKGMpXSxILm9YKGIpKSl9LAppdzpm
-dW5jdGlvbihhLGIsYyl7T2JqZWN0LmRlZmluZVByb3BlcnR5KGEsYix7dmFsdWU6YyxlbnVtZXJhYmxl
-OmZhbHNlLHdyaXRhYmxlOnRydWUsY29uZmlndXJhYmxlOnRydWV9KX0sCnczOmZ1bmN0aW9uKGEpe3Zh
-ciB0LHMscixxLHA9SC55KCQuTkYuJDEoYSkpLG89JC5ud1twXQppZihvIT1udWxsKXtPYmplY3QuZGVm
-aW5lUHJvcGVydHkoYSx2LmRpc3BhdGNoUHJvcGVydHlOYW1lLHt2YWx1ZTpvLGVudW1lcmFibGU6ZmFs
-c2Usd3JpdGFibGU6dHJ1ZSxjb25maWd1cmFibGU6dHJ1ZX0pCnJldHVybiBvLml9dD0kLnZ2W3BdCmlm
-KHQhPW51bGwpcmV0dXJuIHQKcz12LmludGVyY2VwdG9yc0J5VGFnW3BdCmlmKHM9PW51bGwpe3A9SC55
-KCQuVFguJDIoYSxwKSkKaWYocCE9bnVsbCl7bz0kLm53W3BdCmlmKG8hPW51bGwpe09iamVjdC5kZWZp
-bmVQcm9wZXJ0eShhLHYuZGlzcGF0Y2hQcm9wZXJ0eU5hbWUse3ZhbHVlOm8sZW51bWVyYWJsZTpmYWxz
-ZSx3cml0YWJsZTp0cnVlLGNvbmZpZ3VyYWJsZTp0cnVlfSkKcmV0dXJuIG8uaX10PSQudnZbcF0KaWYo
-dCE9bnVsbClyZXR1cm4gdApzPXYuaW50ZXJjZXB0b3JzQnlUYWdbcF19fWlmKHM9PW51bGwpcmV0dXJu
-IG51bGwKdD1zLnByb3RvdHlwZQpyPXBbMF0KaWYocj09PSIhIil7bz1ILlZhKHQpCiQubndbcF09bwpP
-YmplY3QuZGVmaW5lUHJvcGVydHkoYSx2LmRpc3BhdGNoUHJvcGVydHlOYW1lLHt2YWx1ZTpvLGVudW1l
-cmFibGU6ZmFsc2Usd3JpdGFibGU6dHJ1ZSxjb25maWd1cmFibGU6dHJ1ZX0pCnJldHVybiBvLml9aWYo
-cj09PSJ+Iil7JC52dltwXT10CnJldHVybiB0fWlmKHI9PT0iLSIpe3E9SC5WYSh0KQpPYmplY3QuZGVm
-aW5lUHJvcGVydHkoT2JqZWN0LmdldFByb3RvdHlwZU9mKGEpLHYuZGlzcGF0Y2hQcm9wZXJ0eU5hbWUs
-e3ZhbHVlOnEsZW51bWVyYWJsZTpmYWxzZSx3cml0YWJsZTp0cnVlLGNvbmZpZ3VyYWJsZTp0cnVlfSkK
-cmV0dXJuIHEuaX1pZihyPT09IisiKXJldHVybiBILkxjKGEsdCkKaWYocj09PSIqIil0aHJvdyBILmIo
-UC5TWShwKSkKaWYodi5sZWFmVGFnc1twXT09PXRydWUpe3E9SC5WYSh0KQpPYmplY3QuZGVmaW5lUHJv
-cGVydHkoT2JqZWN0LmdldFByb3RvdHlwZU9mKGEpLHYuZGlzcGF0Y2hQcm9wZXJ0eU5hbWUse3ZhbHVl
-OnEsZW51bWVyYWJsZTpmYWxzZSx3cml0YWJsZTp0cnVlLGNvbmZpZ3VyYWJsZTp0cnVlfSkKcmV0dXJu
-IHEuaX1lbHNlIHJldHVybiBILkxjKGEsdCl9LApMYzpmdW5jdGlvbihhLGIpe3ZhciB0PU9iamVjdC5n
-ZXRQcm90b3R5cGVPZihhKQpPYmplY3QuZGVmaW5lUHJvcGVydHkodCx2LmRpc3BhdGNoUHJvcGVydHlO
-YW1lLHt2YWx1ZTpKLlF1KGIsdCxudWxsLG51bGwpLGVudW1lcmFibGU6ZmFsc2Usd3JpdGFibGU6dHJ1
-ZSxjb25maWd1cmFibGU6dHJ1ZX0pCnJldHVybiBifSwKVmE6ZnVuY3Rpb24oYSl7cmV0dXJuIEouUXUo
-YSwhMSxudWxsLCEhYS4kaVhqKX0sClZGOmZ1bmN0aW9uKGEsYixjKXt2YXIgdD1iLnByb3RvdHlwZQpp
-Zih2LmxlYWZUYWdzW2FdPT09dHJ1ZSlyZXR1cm4gSC5WYSh0KQplbHNlIHJldHVybiBKLlF1KHQsYyxu
-dWxsLG51bGwpfSwKWEQ6ZnVuY3Rpb24oKXtpZighMD09PSQuQnYpcmV0dXJuCiQuQnY9ITAKSC5aMSgp
-fSwKWjE6ZnVuY3Rpb24oKXt2YXIgdCxzLHIscSxwLG8sbixtCiQubnc9T2JqZWN0LmNyZWF0ZShudWxs
-KQokLnZ2PU9iamVjdC5jcmVhdGUobnVsbCkKSC5rTygpCnQ9di5pbnRlcmNlcHRvcnNCeVRhZwpzPU9i
-amVjdC5nZXRPd25Qcm9wZXJ0eU5hbWVzKHQpCmlmKHR5cGVvZiB3aW5kb3chPSJ1bmRlZmluZWQiKXt3
-aW5kb3cKcj1mdW5jdGlvbigpe30KZm9yKHE9MDtxPHMubGVuZ3RoOysrcSl7cD1zW3FdCm89JC54Ny4k
-MShwKQppZihvIT1udWxsKXtuPUguVkYocCx0W3BdLG8pCmlmKG4hPW51bGwpe09iamVjdC5kZWZpbmVQ
-cm9wZXJ0eShvLHYuZGlzcGF0Y2hQcm9wZXJ0eU5hbWUse3ZhbHVlOm4sZW51bWVyYWJsZTpmYWxzZSx3
-cml0YWJsZTp0cnVlLGNvbmZpZ3VyYWJsZTp0cnVlfSkKci5wcm90b3R5cGU9b319fX1mb3IocT0wO3E8
-cy5sZW5ndGg7KytxKXtwPXNbcV0KaWYoL15bQS1aYS16X10vLnRlc3QocCkpe209dFtwXQp0WyIhIitw
-XT1tCnRbIn4iK3BdPW0KdFsiLSIrcF09bQp0WyIrIitwXT1tCnRbIioiK3BdPW19fX0sCmtPOmZ1bmN0
-aW9uKCl7dmFyIHQscyxyLHEscCxvLG49Qy5ZcSgpCm49SC51ZChDLktVLEgudWQoQy5mUSxILnVkKEMu
-aTcsSC51ZChDLmk3LEgudWQoQy54aSxILnVkKEMuZGssSC51ZChDLndiKEMuTzQpLG4pKSkpKSkpCmlm
-KHR5cGVvZiBkYXJ0TmF0aXZlRGlzcGF0Y2hIb29rc1RyYW5zZm9ybWVyIT0idW5kZWZpbmVkIil7dD1k
-YXJ0TmF0aXZlRGlzcGF0Y2hIb29rc1RyYW5zZm9ybWVyCmlmKHR5cGVvZiB0PT0iZnVuY3Rpb24iKXQ9
-W3RdCmlmKHQuY29uc3RydWN0b3I9PUFycmF5KWZvcihzPTA7czx0Lmxlbmd0aDsrK3Mpe3I9dFtzXQpp
-Zih0eXBlb2Ygcj09ImZ1bmN0aW9uIiluPXIobil8fG59fXE9bi5nZXRUYWcKcD1uLmdldFVua25vd25U
-YWcKbz1uLnByb3RvdHlwZUZvclRhZwokLk5GPW5ldyBILmRDKHEpCiQuVFg9bmV3IEgud04ocCkKJC54
-Nz1uZXcgSC5WWChvKX0sCnVkOmZ1bmN0aW9uKGEsYil7cmV0dXJuIGEoYil8fGJ9LAp2NDpmdW5jdGlv
-bihhLGIsYyxkLGUsZil7dmFyIHQ9Yj8ibSI6IiIscz1jPyIiOiJpIixyPWQ/InUiOiIiLHE9ZT8icyI6
-IiIscD1mPyJnIjoiIixvPWZ1bmN0aW9uKGcsaCl7dHJ5e3JldHVybiBuZXcgUmVnRXhwKGcsaCl9Y2F0
-Y2gobil7cmV0dXJuIG59fShhLHQrcytyK3ErcCkKaWYobyBpbnN0YW5jZW9mIFJlZ0V4cClyZXR1cm4g
-bwp0aHJvdyBILmIoUC5ycigiSWxsZWdhbCBSZWdFeHAgcGF0dGVybiAoIitTdHJpbmcobykrIikiLGEs
-bnVsbCkpfSwKbTI6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0CmlmKHR5cGVvZiBiPT0ic3RyaW5nIilyZXR1
-cm4gYS5pbmRleE9mKGIsYyk+PTAKZWxzZSBpZihiIGluc3RhbmNlb2YgSC5WUil7dD1DLnhCLnluKGEs
-YykKcmV0dXJuIGIuYi50ZXN0KHQpfWVsc2V7dD1KLkZMKGIsQy54Qi55bihhLGMpKQpyZXR1cm4hdC5n
-bDAodCl9fSwKQTQ6ZnVuY3Rpb24oYSl7aWYoYS5pbmRleE9mKCIkIiwwKT49MClyZXR1cm4gYS5yZXBs
-YWNlKC9cJC9nLCIkJCQkIikKcmV0dXJuIGF9LAplQTpmdW5jdGlvbihhKXtpZigvW1tcXXt9KCkqKz8u
-XFxeJHxdLy50ZXN0KGEpKXJldHVybiBhLnJlcGxhY2UoL1tbXF17fSgpKis/LlxcXiR8XS9nLCJcXCQm
-IikKcmV0dXJuIGF9LAp5czpmdW5jdGlvbihhLGIsYyl7dmFyIHQ9SC5uTShhLGIsYykKcmV0dXJuIHR9
-LApuTTpmdW5jdGlvbihhLGIsYyl7dmFyIHQscyxyLHEKaWYoYj09PSIiKXtpZihhPT09IiIpcmV0dXJu
-IGMKdD1hLmxlbmd0aApmb3Iocz1jLHI9MDtyPHQ7KytyKXM9cythW3JdK2MKcmV0dXJuIHMuY2hhckNv
-ZGVBdCgwKT09MD9zOnN9cT1hLmluZGV4T2YoYiwwKQppZihxPDApcmV0dXJuIGEKaWYoYS5sZW5ndGg8
-NTAwfHxjLmluZGV4T2YoIiQiLDApPj0wKXJldHVybiBhLnNwbGl0KGIpLmpvaW4oYykKcmV0dXJuIGEu
-cmVwbGFjZShuZXcgUmVnRXhwKEguZUEoYiksJ2cnKSxILkE0KGMpKX0sClBEOmZ1bmN0aW9uIFBEKGEs
-Yil7dGhpcy5hPWEKdGhpcy4kdGk9Yn0sCldVOmZ1bmN0aW9uIFdVKCl7fSwKTFA6ZnVuY3Rpb24gTFAo
-YSxiLGMsZCl7dmFyIF89dGhpcwpfLmE9YQpfLmI9YgpfLmM9YwpfLiR0aT1kfSwKWFI6ZnVuY3Rpb24g
-WFIoYSxiKXt0aGlzLmE9YQp0aGlzLiR0aT1ifSwKTEk6ZnVuY3Rpb24gTEkoYSxiLGMsZCxlKXt2YXIg
-Xz10aGlzCl8uYT1hCl8uYz1iCl8uZD1jCl8uZT1kCl8uZj1lfSwKQ2o6ZnVuY3Rpb24gQ2ooYSxiLGMp
-e3RoaXMuYT1hCnRoaXMuYj1iCnRoaXMuYz1jfSwKZjk6ZnVuY3Rpb24gZjkoYSxiLGMsZCxlLGYpe3Zh
-ciBfPXRoaXMKXy5hPWEKXy5iPWIKXy5jPWMKXy5kPWQKXy5lPWUKXy5mPWZ9LApXMDpmdW5jdGlvbiBX
-MChhLGIpe3RoaXMuYT1hCnRoaXMuYj1ifSwKYXo6ZnVuY3Rpb24gYXooYSxiLGMpe3RoaXMuYT1hCnRo
-aXMuYj1iCnRoaXMuYz1jfSwKdlY6ZnVuY3Rpb24gdlYoYSl7dGhpcy5hPWF9LApicTpmdW5jdGlvbiBi
-cShhLGIpe3RoaXMuYT1hCnRoaXMuYj1ifSwKQW06ZnVuY3Rpb24gQW0oYSl7dGhpcy5hPWF9LApYTzpm
-dW5jdGlvbiBYTyhhKXt0aGlzLmE9YQp0aGlzLmI9bnVsbH0sClRwOmZ1bmN0aW9uIFRwKCl7fSwKbGM6
-ZnVuY3Rpb24gbGMoKXt9LAp6eDpmdW5jdGlvbiB6eCgpe30sCnJUOmZ1bmN0aW9uIHJUKGEsYixjLGQp
-e3ZhciBfPXRoaXMKXy5hPWEKXy5iPWIKXy5jPWMKXy5kPWR9LApFcTpmdW5jdGlvbiBFcShhKXt0aGlz
-LmE9YX0sCmtZOmZ1bmN0aW9uIGtZKGEpe3RoaXMuYT1hfSwKTjU6ZnVuY3Rpb24gTjUoYSl7dmFyIF89
-dGhpcwpfLmE9MApfLmY9Xy5lPV8uZD1fLmM9Xy5iPW51bGwKXy5yPTAKXy4kdGk9YX0sCnZoOmZ1bmN0
-aW9uIHZoKGEsYil7dmFyIF89dGhpcwpfLmE9YQpfLmI9YgpfLmQ9Xy5jPW51bGx9LAppNTpmdW5jdGlv
-biBpNShhLGIpe3RoaXMuYT1hCnRoaXMuJHRpPWJ9LApONjpmdW5jdGlvbiBONihhLGIsYyl7dmFyIF89
-dGhpcwpfLmE9YQpfLmI9YgpfLmQ9Xy5jPW51bGwKXy4kdGk9Y30sCmRDOmZ1bmN0aW9uIGRDKGEpe3Ro
-aXMuYT1hfSwKd046ZnVuY3Rpb24gd04oYSl7dGhpcy5hPWF9LApWWDpmdW5jdGlvbiBWWChhKXt0aGlz
-LmE9YX0sClZSOmZ1bmN0aW9uIFZSKGEsYil7dmFyIF89dGhpcwpfLmE9YQpfLmI9YgpfLmQ9Xy5jPW51
-bGx9LApFSzpmdW5jdGlvbiBFSyhhKXt0aGlzLmI9YX0sCktXOmZ1bmN0aW9uIEtXKGEsYixjKXt0aGlz
-LmE9YQp0aGlzLmI9Ygp0aGlzLmM9Y30sClBiOmZ1bmN0aW9uIFBiKGEsYixjKXt2YXIgXz10aGlzCl8u
-YT1hCl8uYj1iCl8uYz1jCl8uZD1udWxsfSwKdFE6ZnVuY3Rpb24gdFEoYSxiKXt0aGlzLmE9YQp0aGlz
-LmM9Yn0sCnVuOmZ1bmN0aW9uIHVuKGEsYixjKXt0aGlzLmE9YQp0aGlzLmI9Ygp0aGlzLmM9Y30sClNk
-OmZ1bmN0aW9uIFNkKGEsYixjKXt2YXIgXz10aGlzCl8uYT1hCl8uYj1iCl8uYz1jCl8uZD1udWxsfSwK
-WEY6ZnVuY3Rpb24oYSl7cmV0dXJuIGF9LApEUTpmdW5jdGlvbihhKXtyZXR1cm4gbmV3IEludDhBcnJh
-eShhKX0sCm9kOmZ1bmN0aW9uKGEsYixjKXtpZihhPj4+MCE9PWF8fGE+PWMpdGhyb3cgSC5iKEguSFko
-YixhKSl9LApyTTpmdW5jdGlvbihhLGIsYyl7dmFyIHQKaWYoIShhPj4+MCE9PWEpKXQ9Yj4+PjAhPT1i
-fHxhPmJ8fGI+YwplbHNlIHQ9ITAKaWYodCl0aHJvdyBILmIoSC5hdShhLGIsYykpCnJldHVybiBifSwK
-V1o6ZnVuY3Rpb24gV1ooKXt9LApFVDpmdW5jdGlvbiBFVCgpe30sCmRmOmZ1bmN0aW9uIGRmKCl7fSwK
-YjA6ZnVuY3Rpb24gYjAoKXt9LApEZzpmdW5jdGlvbiBEZygpe30sClBnOmZ1bmN0aW9uIFBnKCl7fSwK
-eGo6ZnVuY3Rpb24geGooKXt9LApkRTpmdW5jdGlvbiBkRSgpe30sClpBOmZ1bmN0aW9uIFpBKCl7fSwK
-d2Y6ZnVuY3Rpb24gd2YoKXt9LApQcTpmdW5jdGlvbiBQcSgpe30sCmVFOmZ1bmN0aW9uIGVFKCl7fSwK
-VjY6ZnVuY3Rpb24gVjYoKXt9LApSRzpmdW5jdGlvbiBSRygpe30sClZQOmZ1bmN0aW9uIFZQKCl7fSwK
-V0I6ZnVuY3Rpb24gV0IoKXt9LApaRzpmdW5jdGlvbiBaRygpe30sCnhaOmZ1bmN0aW9uKGEsYil7dmFy
-IHQ9Yi5kCnJldHVybiB0PT1udWxsP2IuZD1ILkooYSwiYjgiLFtiLlFdKTp0fSwKUTE6ZnVuY3Rpb24o
-YSl7dmFyIHQ9YS56CmlmKHQ9PT02fHx0PT09N3x8dD09PTgpcmV0dXJuIEguUTEoYS5RKQpyZXR1cm4g
-dD09PTExfHx0PT09MTJ9LAptRDpmdW5jdGlvbihhKXtyZXR1cm4gYS5kYn0sCllROmZ1bmN0aW9uKGEp
-e3JldHVybiBILkUodi50eXBlVW5pdmVyc2UsYSl9LApKUzpmdW5jdGlvbihhKXt2YXIgdD1hLiRTCmlm
-KHQhPW51bGwpe2lmKHR5cGVvZiB0PT0ibnVtYmVyIilyZXR1cm4gSC5CcCh0KQpyZXR1cm4gYS4kUygp
-fXJldHVybiBudWxsfSwKVWU6ZnVuY3Rpb24oYSxiKXt2YXIgdAppZihILlExKGIpKWlmKGEgaW5zdGFu
-Y2VvZiBILlRwKXt0PUguSlMoYSkKaWYodCE9bnVsbClyZXR1cm4gdH1yZXR1cm4gSC56SyhhKX0sCnpL
-OmZ1bmN0aW9uKGEpe3ZhciB0CmlmKGEgaW5zdGFuY2VvZiBQLmspe3Q9YS4kdGkKcmV0dXJuIHQhPW51
-bGw/dDpILlZVKGEpfWlmKEFycmF5LmlzQXJyYXkoYSkpcmV0dXJuIEgudDYoYSkKcmV0dXJuIEguVlUo
-Si5pYShhKSl9LAp0NjpmdW5jdGlvbihhKXt2YXIgdD1hLiR0aSxzPXUudQppZih0PT1udWxsKXJldHVy
-biBzCmlmKHQuY29uc3RydWN0b3IhPT1zLmNvbnN0cnVjdG9yKXJldHVybiBzCnJldHVybiB0fSwKTGg6
-ZnVuY3Rpb24oYSl7dmFyIHQ9YS4kdGkKcmV0dXJuIHQhPW51bGw/dDpILlZVKGEpfSwKVlU6ZnVuY3Rp
-b24oYSl7dmFyIHQ9YS5jb25zdHJ1Y3RvcixzPXQuJGNjYWNoZQppZihzIT1udWxsKXJldHVybiBzCnJl
-dHVybiBILnI5KGEsdCl9LApyOTpmdW5jdGlvbihhLGIpe3ZhciB0PWEgaW5zdGFuY2VvZiBILlRwP2Eu
-X19wcm90b19fLl9fcHJvdG9fXy5jb25zdHJ1Y3RvcjpiLHM9SC5haSh2LnR5cGVVbml2ZXJzZSx0Lm5h
-bWUpCmIuJGNjYWNoZT1zCnJldHVybiBzfSwKQnA6ZnVuY3Rpb24oYSl7dmFyIHQscz1hLHI9di50eXBl
-cyxxPXJbc10KaWYodHlwZW9mIHE9PSJzdHJpbmciKXt0PUguRSh2LnR5cGVVbml2ZXJzZSxxKQpyW3Nd
-PXQKcmV0dXJuIHR9cmV0dXJuIHF9LApKSjpmdW5jdGlvbihhKXt2YXIgdCxzPXRoaXMscj1zLnoscT1I
-LllPCmlmKEguY2Mocykpe3E9SC5JdwpzLmI9cy5hPUguaG59ZWxzZSBpZihyPT09OSl7dD1zLmRiCmlm
-KCJLTiI9PT10KXE9SC5vawplbHNlIGlmKCJDUCI9PT10KXE9SC5LSAplbHNlIGlmKCJGSyI9PT10KXE9
-SC5LSAplbHNlIGlmKCJxVSI9PT10KXE9SC5NTQplbHNlIGlmKCJhMiI9PT10KXE9SC5sCmVsc2V7cj1z
-LlEKaWYocy5jaC5ldmVyeShILmNjKSl7cy54PSIkaSIrcgpxPUgudDR9fX1zLmM9cQpyZXR1cm4gcy5j
-KGEpfSwKWU86ZnVuY3Rpb24oYSl7dmFyIHQ9dGhpcwpyZXR1cm4gSC5XZSh2LnR5cGVVbml2ZXJzZSxI
-LlVlKGEsdCksbnVsbCx0LG51bGwpfSwKdDQ6ZnVuY3Rpb24oYSl7dmFyIHQ9dGhpcy54CmlmKGEgaW5z
-dGFuY2VvZiBQLmspcmV0dXJuISFhW3RdCnJldHVybiEhSi5pYShhKVt0XX0sCk96OmZ1bmN0aW9uKGEp
-e3ZhciB0CmlmKGE9PW51bGwpcmV0dXJuIGEKdD10aGlzCmlmKHQuYyhhKSlyZXR1cm4gYQp0aHJvdyBI
-LmIoSC5RNShILldLKGEsSC5VZShhLHQpLEguZG0odCxudWxsKSkpKX0sCkF2OmZ1bmN0aW9uKGEpe3Zh
-ciB0CmlmKGE9PW51bGwpcmV0dXJuIGEKdD10aGlzCmlmKHQuYyhhKSlyZXR1cm4gYQp0aHJvdyBILmIo
-SC5aYyhILldLKGEsSC5VZShhLHQpLEguZG0odCxudWxsKSkpKX0sCkRoOmZ1bmN0aW9uKGEsYixjLGQp
-e3ZhciB0PW51bGwKaWYoSC5XZSh2LnR5cGVVbml2ZXJzZSxhLHQsYix0KSlyZXR1cm4gYQp0aHJvdyBI
-LmIoSC5aYygiVGhlIHR5cGUgYXJndW1lbnQgJyIrSC5kKEguZG0oYSx0KSkrIicgaXMgbm90IGEgc3Vi
-dHlwZSBvZiB0aGUgdHlwZSB2YXJpYWJsZSBib3VuZCAnIitILmQoSC5kbShiLHQpKSsiJyBvZiB0eXBl
-IHZhcmlhYmxlICciK2MrIicgaW4gJyIrSC5kKGQpKyInLiIpKX0sCldLOmZ1bmN0aW9uKGEsYixjKXt2
-YXIgdD1QLnAoYSkscz1ILmRtKGI9PW51bGw/SC56SyhhKTpiLG51bGwpCnJldHVybiB0KyI6IHR5cGUg
-JyIrSC5kKHMpKyInIGlzIG5vdCBhIHN1YnR5cGUgb2YgdHlwZSAnIitILmQoYykrIicifSwKUTU6ZnVu
-Y3Rpb24oYSl7cmV0dXJuIG5ldyBILmh6KCJDYXN0RXJyb3I6ICIrYSl9LApQdjpmdW5jdGlvbihhLGIp
-e3JldHVybiBuZXcgSC5oeigiQ2FzdEVycm9yOiAiK0guV0soYSxudWxsLGIpKX0sClpjOmZ1bmN0aW9u
-KGEpe3JldHVybiBuZXcgSC5pTSgiVHlwZUVycm9yOiAiK2EpfSwKcTpmdW5jdGlvbihhLGIpe3JldHVy
-biBuZXcgSC5pTSgiVHlwZUVycm9yOiAiK0guV0soYSxudWxsLGIpKX0sCkl3OmZ1bmN0aW9uKGEpe3Jl
-dHVybiEwfSwKaG46ZnVuY3Rpb24oYSl7cmV0dXJuIGF9LApsOmZ1bmN0aW9uKGEpe3JldHVybiEwPT09
-YXx8ITE9PT1hfSwKRTk6ZnVuY3Rpb24oYSl7aWYoITA9PT1hfHwhMT09PWEpcmV0dXJuIGEKaWYoYT09
-bnVsbClyZXR1cm4gYQp0aHJvdyBILmIoSC5QdihhLCJib29sIikpfSwKeGQ6ZnVuY3Rpb24oYSl7aWYo
-ITA9PT1hfHwhMT09PWEpcmV0dXJuIGEKaWYoYT09bnVsbClyZXR1cm4gYQp0aHJvdyBILmIoSC5xKGEs
-ImJvb2wiKSl9LApkajpmdW5jdGlvbihhKXtpZih0eXBlb2YgYT09Im51bWJlciIpcmV0dXJuIGEKaWYo
-YT09bnVsbClyZXR1cm4gYQp0aHJvdyBILmIoSC5QdihhLCJkb3VibGUiKSl9LApJZzpmdW5jdGlvbihh
-KXtpZih0eXBlb2YgYT09Im51bWJlciIpcmV0dXJuIGEKaWYoYT09bnVsbClyZXR1cm4gYQp0aHJvdyBI
-LmIoSC5xKGEsImRvdWJsZSIpKX0sCm9rOmZ1bmN0aW9uKGEpe3JldHVybiB0eXBlb2YgYT09Im51bWJl
-ciImJk1hdGguZmxvb3IoYSk9PT1hfSwKU0g6ZnVuY3Rpb24oYSl7aWYodHlwZW9mIGE9PSJudW1iZXIi
-JiZNYXRoLmZsb29yKGEpPT09YSlyZXR1cm4gYQppZihhPT1udWxsKXJldHVybiBhCnRocm93IEguYihI
-LlB2KGEsImludCIpKX0sClNjOmZ1bmN0aW9uKGEpe2lmKHR5cGVvZiBhPT0ibnVtYmVyIiYmTWF0aC5m
-bG9vcihhKT09PWEpcmV0dXJuIGEKaWYoYT09bnVsbClyZXR1cm4gYQp0aHJvdyBILmIoSC5xKGEsImlu
-dCIpKX0sCktIOmZ1bmN0aW9uKGEpe3JldHVybiB0eXBlb2YgYT09Im51bWJlciJ9LAp1VTpmdW5jdGlv
-bihhKXtpZih0eXBlb2YgYT09Im51bWJlciIpcmV0dXJuIGEKaWYoYT09bnVsbClyZXR1cm4gYQp0aHJv
-dyBILmIoSC5QdihhLCJudW0iKSl9LApETjpmdW5jdGlvbihhKXtpZih0eXBlb2YgYT09Im51bWJlciIp
-cmV0dXJuIGEKaWYoYT09bnVsbClyZXR1cm4gYQp0aHJvdyBILmIoSC5xKGEsIm51bSIpKX0sCk1NOmZ1
-bmN0aW9uKGEpe3JldHVybiB0eXBlb2YgYT09InN0cmluZyJ9LApyYzpmdW5jdGlvbihhKXtpZih0eXBl
-b2YgYT09InN0cmluZyIpcmV0dXJuIGEKaWYoYT09bnVsbClyZXR1cm4gYQp0aHJvdyBILmIoSC5Qdihh
-LCJTdHJpbmciKSl9LAp5OmZ1bmN0aW9uKGEpe2lmKHR5cGVvZiBhPT0ic3RyaW5nIilyZXR1cm4gYQpp
-ZihhPT1udWxsKXJldHVybiBhCnRocm93IEguYihILnEoYSwiU3RyaW5nIikpfSwKaW86ZnVuY3Rpb24o
-YSxiKXt2YXIgdCxzLHIKZm9yKHQ9IiIscz0iIixyPTA7cjxhLmxlbmd0aDsrK3Iscz0iLCAiKXQrPUMu
-eEIuVChzLEguZG0oYVtyXSxiKSkKcmV0dXJuIHR9LApiSTpmdW5jdGlvbihhMCxhMSxhMil7dmFyIHQs
-cyxyLHEscCxvLG4sbSxsLGssaixpLGgsZyxmLGUsZCxjLGIsYT0iLCAiCmlmKGEyIT1udWxsKXt0PWEy
-Lmxlbmd0aAppZihhMT09bnVsbCl7YTE9SC5WTShbXSx1LnMpCnM9bnVsbH1lbHNlIHM9YTEubGVuZ3Ro
-CnI9YTEubGVuZ3RoCmZvcihxPXQ7cT4wOy0tcSlDLk5tLkEoYTEsIlQiKyhyK3EpKQpmb3IocD0iPCIs
-bz0iIixxPTA7cTx0OysrcSxvPWEpe3ArPW8Kbj1hMS5sZW5ndGgKbT1uLTEtcQppZihtPDApcmV0dXJu
-IEguT0goYTEsbSkKcD1DLnhCLlQocCxhMVttXSkKbD1hMltxXQppZighSC5jYyhsKSlwKz1DLnhCLlQo
-IiBleHRlbmRzICIsSC5kbShsLGExKSl9cCs9Ij4ifWVsc2V7cD0iIgpzPW51bGx9bj1hMC5RCms9YTAu
-Y2gKaj1rLmEKaT1qLmxlbmd0aApoPWsuYgpnPWgubGVuZ3RoCmY9ay5jCmU9Zi5sZW5ndGgKZD1ILmRt
-KG4sYTEpCmZvcihjPSIiLGI9IiIscT0wO3E8aTsrK3EsYj1hKWMrPUMueEIuVChiLEguZG0oaltxXSxh
-MSkpCmlmKGc+MCl7Yys9YisiWyIKZm9yKGI9IiIscT0wO3E8ZzsrK3EsYj1hKWMrPUMueEIuVChiLEgu
-ZG0oaFtxXSxhMSkpCmMrPSJdIn1pZihlPjApe2MrPWIrInsiCmZvcihiPSIiLHE9MDtxPGU7cSs9Mixi
-PWEpYys9Qy54Qi5UKGIsSC5kbShmW3ErMV0sYTEpKSsiICIrZltxXQpjKz0ifSJ9aWYocyE9bnVsbClh
-MS5sZW5ndGg9cwpyZXR1cm4gcCsiKCIrYysiKSA9PiAiK0guZChkKX0sCmRtOmZ1bmN0aW9uKGEsYil7
-dmFyIHQscyxyLHEscD1hLnoKaWYocD09PTUpcmV0dXJuImVyYXNlZCIKaWYocD09PTIpcmV0dXJuImR5
-bmFtaWMiCmlmKHA9PT0zKXJldHVybiJ2b2lkIgppZihwPT09MSlyZXR1cm4iTmV2ZXIiCmlmKHA9PT00
-KXJldHVybiJhbnkiCmlmKHA9PT02KXJldHVybiBILmQoSC5kbShhLlEsYikpKyIqIgppZihwPT09Nyly
-ZXR1cm4gSC5kKEguZG0oYS5RLGIpKSsiPyIKaWYocD09PTgpcmV0dXJuIkZ1dHVyZU9yPCIrSC5kKEgu
-ZG0oYS5RLGIpKSsiPiIKaWYocD09PTkpe3Q9SC5vMyhhLlEpCnM9YS5jaApyZXR1cm4gcy5sZW5ndGgh
-PT0wP3QrKCI8IitILmlvKHMsYikrIj4iKTp0fWlmKHA9PT0xMSlyZXR1cm4gSC5iSShhLGIsbnVsbCkK
-aWYocD09PTEyKXJldHVybiBILmJJKGEuUSxiLGEuY2gpCmlmKHA9PT0xMyl7cj1hLlEKcT1iLmxlbmd0
-aApyPXEtMS1yCmlmKHI8MHx8cj49cSlyZXR1cm4gSC5PSChiLHIpCnJldHVybiBiW3JdfXJldHVybiI/
-In0sCm8zOmZ1bmN0aW9uKGEpe3ZhciB0LHM9SC5KZyhhKQppZihzIT1udWxsKXJldHVybiBzCnQ9Im1p
-bmlmaWVkOiIrYQpyZXR1cm4gdH0sClFvOmZ1bmN0aW9uKGEsYil7dmFyIHQ9YS50UltiXQpmb3IoO3R5
-cGVvZiB0PT0ic3RyaW5nIjspdD1hLnRSW3RdCnJldHVybiB0fSwKYWk6ZnVuY3Rpb24oYSxiKXt2YXIg
-dCxzLHIscSxwLG89YS5lVCxuPW9bYl0KaWYobj09bnVsbClyZXR1cm4gSC5FKGEsYikKZWxzZSBpZih0
-eXBlb2Ygbj09Im51bWJlciIpe3Q9bgpzPUgubShhLDUsIiMiKQpyPVtdCmZvcihxPTA7cTx0OysrcSly
-LnB1c2gocykKcD1ILkooYSxiLHIpCm9bYl09cApyZXR1cm4gcH1lbHNlIHJldHVybiBufSwKeGI6ZnVu
-Y3Rpb24oYSxiKXtyZXR1cm4gSC5JeChhLnRSLGIpfSwKRkY6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gSC5J
-eChhLmVULGIpfSwKRTpmdW5jdGlvbihhLGIpe3ZhciB0LHM9YS5lQyxyPXMuZ2V0KGIpCmlmKHIhPW51
-bGwpcmV0dXJuIHIKdD1ILnooYSxudWxsLGIpCnMuc2V0KGIsdCkKcmV0dXJuIHR9LApjRTpmdW5jdGlv
-bihhLGIsYyl7dmFyIHQscyxyPWIuY3gKaWYocj09bnVsbClyPWIuY3g9bmV3IE1hcCgpCnQ9ci5nZXQo
-YykKaWYodCE9bnVsbClyZXR1cm4gdApzPUgueihhLGIsYykKci5zZXQoYyxzKQpyZXR1cm4gc30sCnY1
-OmZ1bmN0aW9uKGEsYixjKXt2YXIgdCxzLHIscT1iLmN5CmlmKHE9PW51bGwpcT1iLmN5PW5ldyBNYXAo
-KQp0PWMuZGIKcz1xLmdldCh0KQppZihzIT1udWxsKXJldHVybiBzCnI9SC5hKGEsYixjLno9PT0xMD9j
-LmNoOltjXSkKcS5zZXQodCxyKQpyZXR1cm4gcn0sCno6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0PUguaShI
-Lm8oYSxiLGMpKQpyZXR1cm4gdH0sCldHOmZ1bmN0aW9uKGEsYil7dmFyIHQ9Yi5kYgphLmVDLnNldCh0
-LGIpCmIuYT1ILk96CmIuYj1ILkF2CmIuYz1ILkpKCnJldHVybiBifSwKbTpmdW5jdGlvbihhLGIsYyl7
-dmFyIHQscz1hLmVDLmdldChjKQppZihzIT1udWxsKXJldHVybiBzCnQ9bmV3IEguSmMobnVsbCxudWxs
-LG51bGwpCnQuej1iCnQuZGI9YwpyZXR1cm4gSC5XRyhhLHQpfSwKdjpmdW5jdGlvbihhLGIsYyxkKXt2
-YXIgdCxzPWEuZUMuZ2V0KGQpCmlmKHMhPW51bGwpcmV0dXJuIHMKdD1uZXcgSC5KYyhudWxsLG51bGws
-bnVsbCkKdC56PWIKdC5RPWMKdC5kYj1kCnJldHVybiBILldHKGEsdCl9LApIOmZ1bmN0aW9uKGEsYil7
-dmFyIHQscz0iIitiKyJeIixyPWEuZUMuZ2V0KHMpCmlmKHIhPW51bGwpcmV0dXJuIHIKdD1uZXcgSC5K
-YyhudWxsLG51bGwsbnVsbCkKdC56PTEzCnQuUT1iCnQuZGI9cwpyZXR1cm4gSC5XRyhhLHQpfSwKVXg6
-ZnVuY3Rpb24oYSl7dmFyIHQscyxyLHE9YS5sZW5ndGgKZm9yKHQ9IiIscz0iIixyPTA7cjxxOysrcixz
-PSIsIil0Kz1zK2Fbcl0uZGIKcmV0dXJuIHR9LApTNDpmdW5jdGlvbihhKXt2YXIgdCxzLHIscSxwLG89
-YS5sZW5ndGgKZm9yKHQ9IiIscz0iIixyPTA7cjxvO3IrPTIscz0iLCIpe3E9YVtyXQpwPWFbcisxXS5k
-Ygp0Kz1zK3ErIjoiK3B9cmV0dXJuIHR9LApKOmZ1bmN0aW9uKGEsYixjKXt2YXIgdCxzLHI9YgppZihj
-Lmxlbmd0aCE9PTApcis9IjwiK0guVXgoYykrIj4iCnQ9YS5lQy5nZXQocikKaWYodCE9bnVsbClyZXR1
-cm4gdApzPW5ldyBILkpjKG51bGwsbnVsbCxudWxsKQpzLno9OQpzLlE9YgpzLmNoPWMKaWYoYy5sZW5n
-dGg+MClzLmQ9Y1swXQpzLmRiPXIKcmV0dXJuIEguV0coYSxzKX0sCmE6ZnVuY3Rpb24oYSxiLGMpe3Zh
-ciB0LHMscixxLHAKaWYoYi56PT09MTApe3Q9Yi5RCnM9Yi5jaC5jb25jYXQoYyl9ZWxzZXtzPWMKdD1i
-fXI9dC5kYisiOyIrKCI8IitILlV4KHMpKyI+IikKcT1hLmVDLmdldChyKQppZihxIT1udWxsKXJldHVy
-biBxCnA9bmV3IEguSmMobnVsbCxudWxsLG51bGwpCnAuej0xMApwLlE9dApwLmNoPXMKcC5kYj1yCnJl
-dHVybiBILldHKGEscCl9LApDOmZ1bmN0aW9uKGEsYixjKXt2YXIgdCxzLHIscT1iLmRiLHA9Yy5hLG89
-cC5sZW5ndGgsbj1jLmIsbT1uLmxlbmd0aCxsPWMuYyxrPWwubGVuZ3RoLGo9IigiK0guVXgocCkKaWYo
-bT4wKWorPShvPjA/IiwiOiIiKSsiWyIrSC5VeChuKSsiXSIKaWYoaz4wKWorPShvPjA/IiwiOiIiKSsi
-eyIrSC5TNChsKSsifSIKdD1xKyhqKyIpIikKcz1hLmVDLmdldCh0KQppZihzIT1udWxsKXJldHVybiBz
-CnI9bmV3IEguSmMobnVsbCxudWxsLG51bGwpCnIuej0xMQpyLlE9YgpyLmNoPWMKci5kYj10CnJldHVy
-biBILldHKGEscil9LApEOmZ1bmN0aW9uKGEsYixjKXt2YXIgdCxzPWIuZGIrIjwiK0guVXgoYykrIj4i
-LHI9YS5lQy5nZXQocykKaWYociE9bnVsbClyZXR1cm4gcgp0PW5ldyBILkpjKG51bGwsbnVsbCxudWxs
-KQp0Lno9MTIKdC5RPWIKdC5jaD1jCnQuZGI9cwpyZXR1cm4gSC5XRyhhLHQpfSwKbzpmdW5jdGlvbihh
-LGIsYyl7cmV0dXJue3U6YSxlOmIscjpjLHM6W10scDowfX0sCmk6ZnVuY3Rpb24oYSl7dmFyIHQscyxy
-LHEscCxvLG4sbSxsLGssaixpLGgsZz1hLnIsZj1hLnMKZm9yKHQ9Zy5sZW5ndGgscz0wO3M8dDspe3I9
-Zy5jaGFyQ29kZUF0KHMpCmlmKHI+PTQ4JiZyPD01NylzPUguQShzKzEscixnLGYpCmVsc2UgaWYoKCgo
-cnwzMik+Pj4wKS05NyY2NTUzNSk8MjZ8fHI9PT05NXx8cj09PTM2KXM9SC50KGEscyxnLGYsITEpCmVs
-c2UgaWYocj09PTQ2KXM9SC50KGEscyxnLGYsITApCmVsc2V7KytzCnN3aXRjaChyKXtjYXNlIDQ0OmJy
-ZWFrCmNhc2UgNTg6YnJlYWsKY2FzZSA1OTpmLnB1c2goSC5LKGEudSxhLmUsZi5wb3AoKSkpCmJyZWFr
-CmNhc2UgOTQ6Zi5wdXNoKEguSChhLnUsZi5wb3AoKSkpCmJyZWFrCmNhc2UgMzU6Zi5wdXNoKEgubShh
-LnUsNSwiIyIpKQpicmVhawpjYXNlIDY0OmYucHVzaChILm0oYS51LDIsIkAiKSkKYnJlYWsKY2FzZSAx
-MjY6Zi5wdXNoKEgubShhLnUsMywifiIpKQpicmVhawpjYXNlIDYwOmYucHVzaChhLnApCmEucD1mLmxl
-bmd0aApicmVhawpjYXNlIDYyOnE9YS51CnA9Zi5zcGxpY2UoYS5wKQpILnIoYS51LGEuZSxwKQphLnA9
-Zi5wb3AoKQpvPWYucG9wKCkKaWYodHlwZW9mIG89PSJzdHJpbmciKWYucHVzaChILkoocSxvLHApKQpl
-bHNle249SC5LKHEsYS5lLG8pCnN3aXRjaChuLnope2Nhc2UgMTE6Zi5wdXNoKEguRChxLG4scCkpCmJy
-ZWFrCmRlZmF1bHQ6Zi5wdXNoKEguYShxLG4scCkpCmJyZWFrfX1icmVhawpjYXNlIDM4OkguSShhLGYp
-CmJyZWFrCmNhc2UgNDI6bT1hLnUKbD1ILksobSxhLmUsZi5wb3AoKSkKZi5wdXNoKEgudihtLDYsbCxs
-LmRiKyIqIikpCmJyZWFrCmNhc2UgNjM6bT1hLnUKbD1ILksobSxhLmUsZi5wb3AoKSkKZi5wdXNoKEgu
-dihtLDcsbCxsLmRiKyI/IikpCmJyZWFrCmNhc2UgNDc6bT1hLnUKbD1ILksobSxhLmUsZi5wb3AoKSkK
-Zi5wdXNoKEgudihtLDgsbCxsLmRiKyIvIikpCmJyZWFrCmNhc2UgNDA6Zi5wdXNoKGEucCkKYS5wPWYu
-bGVuZ3RoCmJyZWFrCmNhc2UgNDE6cT1hLnUKaz1uZXcgSC5HKCkKaj1xLnNFQQppPXEuc0VBCm89Zi5w
-b3AoKQppZih0eXBlb2Ygbz09Im51bWJlciIpc3dpdGNoKG8pe2Nhc2UtMTpqPWYucG9wKCkKYnJlYWsK
-Y2FzZS0yOmk9Zi5wb3AoKQpicmVhawpkZWZhdWx0OmYucHVzaChvKQpicmVha31lbHNlIGYucHVzaChv
-KQpwPWYuc3BsaWNlKGEucCkKSC5yKGEudSxhLmUscCkKYS5wPWYucG9wKCkKay5hPXAKay5iPWoKay5j
-PWkKZi5wdXNoKEguQyhxLEguSyhxLGEuZSxmLnBvcCgpKSxrKSkKYnJlYWsKY2FzZSA5MTpmLnB1c2go
-YS5wKQphLnA9Zi5sZW5ndGgKYnJlYWsKY2FzZSA5MzpwPWYuc3BsaWNlKGEucCkKSC5yKGEudSxhLmUs
-cCkKYS5wPWYucG9wKCkKZi5wdXNoKHApCmYucHVzaCgtMSkKYnJlYWsKY2FzZSAxMjM6Zi5wdXNoKGEu
-cCkKYS5wPWYubGVuZ3RoCmJyZWFrCmNhc2UgMTI1OnA9Zi5zcGxpY2UoYS5wKQpILkIoYS51LGEuZSxw
-KQphLnA9Zi5wb3AoKQpmLnB1c2gocCkKZi5wdXNoKC0yKQpicmVhawpkZWZhdWx0OnRocm93IkJhZCBj
-aGFyYWN0ZXIgIityfX19aD1mLnBvcCgpCnJldHVybiBILksoYS51LGEuZSxoKX0sCkE6ZnVuY3Rpb24o
-YSxiLGMsZCl7dmFyIHQscyxyPWItNDgKZm9yKHQ9Yy5sZW5ndGg7YTx0OysrYSl7cz1jLmNoYXJDb2Rl
-QXQoYSkKaWYoIShzPj00OCYmczw9NTcpKWJyZWFrCnI9cioxMCsocy00OCl9ZC5wdXNoKHIpCnJldHVy
-biBhfSwKdDpmdW5jdGlvbihhLGIsYyxkLGUpe3ZhciB0LHMscixxLHAsbyxuPWIrMQpmb3IodD1jLmxl
-bmd0aDtuPHQ7KytuKXtzPWMuY2hhckNvZGVBdChuKQppZihzPT09NDYpe2lmKGUpYnJlYWsKZT0hMH1l
-bHNle2lmKCEoKCgoc3wzMik+Pj4wKS05NyY2NTUzNSk8MjZ8fHM9PT05NXx8cz09PTM2KSlyPXM+PTQ4
-JiZzPD01NwplbHNlIHI9ITAKaWYoIXIpYnJlYWt9fXE9Yy5zdWJzdHJpbmcoYixuKQppZihlKXt0PWEu
-dQpwPWEuZQppZihwLno9PT0xMClwPXAuUQpvPUguUW8odCxwLlEpW3FdCmlmKG89PW51bGwpSC5Waign
-Tm8gIicrcSsnIiBpbiAiJytILm1EKHApKyciJykKZC5wdXNoKEguY0UodCxwLG8pKX1lbHNlIGQucHVz
-aChxKQpyZXR1cm4gbn0sCkk6ZnVuY3Rpb24oYSxiKXt2YXIgdD1iLnBvcCgpCmlmKDA9PT10KXtiLnB1
-c2goSC5tKGEudSwxLCIwJiIpKQpyZXR1cm59aWYoMT09PXQpe2IucHVzaChILm0oYS51LDQsIjEmIikp
-CnJldHVybn10aHJvdyBILmIoUC5oVigiVW5leHBlY3RlZCBleHRlbmRlZCBvcGVyYXRpb24gIitILmQo
-dCkpKX0sCks6ZnVuY3Rpb24oYSxiLGMpe2lmKHR5cGVvZiBjPT0ic3RyaW5nIilyZXR1cm4gSC5KKGEs
-YyxhLnNFQSkKZWxzZSBpZih0eXBlb2YgYz09Im51bWJlciIpcmV0dXJuIEguVFYoYSxiLGMpCmVsc2Ug
-cmV0dXJuIGN9LApyOmZ1bmN0aW9uKGEsYixjKXt2YXIgdCxzPWMubGVuZ3RoCmZvcih0PTA7dDxzOysr
-dCljW3RdPUguSyhhLGIsY1t0XSl9LApCOmZ1bmN0aW9uKGEsYixjKXt2YXIgdCxzPWMubGVuZ3RoCmZv
-cih0PTE7dDxzO3QrPTIpY1t0XT1ILksoYSxiLGNbdF0pfSwKVFY6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0
-LHMscj1iLnoKaWYocj09PTEwKXtpZihjPT09MClyZXR1cm4gYi5RCnQ9Yi5jaApzPXQubGVuZ3RoCmlm
-KGM8PXMpcmV0dXJuIHRbYy0xXQpjLT1zCmI9Yi5RCnI9Yi56fWVsc2UgaWYoYz09PTApcmV0dXJuIGIK
-aWYociE9PTkpdGhyb3cgSC5iKFAuaFYoIkluZGV4ZWQgYmFzZSBtdXN0IGJlIGFuIGludGVyZmFjZSB0
-eXBlIikpCnQ9Yi5jaAppZihjPD10Lmxlbmd0aClyZXR1cm4gdFtjLTFdCnRocm93IEguYihQLmhWKCJC
-YWQgaW5kZXggIitjKyIgZm9yICIrYi53KDApKSl9LApXZTpmdW5jdGlvbihhLGIsYyxkLGUpe3ZhciB0
-LHMscixxLHAsbyxuLG0sbCxrCmlmKGI9PT1kKXJldHVybiEwCmlmKEguY2MoZCkpcmV0dXJuITAKdD1i
-LnoKaWYodD09PTQpcmV0dXJuITAKaWYoSC5jYyhiKSlyZXR1cm4hMQppZihiPT09dS5QKXJldHVybiEw
-CnM9dD09PTEzCmlmKHMpaWYoSC5XZShhLGNbYi5RXSxjLGQsZSkpcmV0dXJuITAKcj1kLnoKaWYodD09
-PTYpcmV0dXJuIEguV2UoYSxiLlEsYyxkLGUpCmlmKHI9PT02KXtxPWQuUQpyZXR1cm4gSC5XZShhLGIs
-YyxxLGUpfWlmKHQ9PT04KXtpZighSC5XZShhLGIuUSxjLGQsZSkpcmV0dXJuITEKcmV0dXJuIEguV2Uo
-YSxILnhaKGEsYiksYyxkLGUpfWlmKHQ9PT03KXtxPUguV2UoYSxiLlEsYyxkLGUpCnJldHVybiBxfWlm
-KHI9PT04KXtpZihILldlKGEsYixjLGQuUSxlKSlyZXR1cm4hMApyZXR1cm4gSC5XZShhLGIsYyxILnha
-KGEsZCksZSl9aWYocj09PTcpe3E9SC5XZShhLGIsYyxkLlEsZSkKcmV0dXJuIHF9aWYocylyZXR1cm4h
-MQpxPXQhPT0xMQppZigoIXF8fHQ9PT0xMikmJmQ9PT11LlopcmV0dXJuITAKaWYocj09PTEyKXtpZihi
-PT09dS5nKXJldHVybiEwCmlmKHQhPT0xMilyZXR1cm4hMQpwPWIuY2gKbz1kLmNoCm49cC5sZW5ndGgK
-aWYobiE9PW8ubGVuZ3RoKXJldHVybiExCmZvcihxPXUuYXYsbT0wO208bjsrK20pe2w9cFttXQprPW9b
-bV0KcS5iKGwpCnEuYihrKQppZighSC5XZShhLGwsYyxrLGUpfHwhSC5XZShhLGssZSxsLGMpKXJldHVy
-biExfWM9Yz09bnVsbD9wOnAuY29uY2F0KGMpCmU9ZT09bnVsbD9vOm8uY29uY2F0KGUpCnJldHVybiBI
-LmJPKGEsYi5RLGMsZC5RLGUpfWlmKHI9PT0xMSl7aWYoYj09PXUuZylyZXR1cm4hMAppZihxKXJldHVy
-biExCnJldHVybiBILmJPKGEsYixjLGQsZSl9aWYodD09PTkpe2lmKHIhPT05KXJldHVybiExCnJldHVy
-biBILnBHKGEsYixjLGQsZSl9cmV0dXJuITF9LApiTzpmdW5jdGlvbihhMCxhMSxhMixhMyxhNCl7dmFy
-IHQscyxyLHEscCxvLG4sbSxsLGssaixpLGgsZyxmLGUsZCxjLGIsYQppZighSC5XZShhMCxhMS5RLGEy
-LGEzLlEsYTQpKXJldHVybiExCnQ9YTEuY2gKcz1hMy5jaApyPXQuYQpxPXMuYQpwPXIubGVuZ3RoCm89
-cS5sZW5ndGgKaWYocD5vKXJldHVybiExCm49by1wCm09dC5iCmw9cy5iCms9bS5sZW5ndGgKaj1sLmxl
-bmd0aAppZihwK2s8bytqKXJldHVybiExCmZvcihpPTA7aTxwOysraSl7aD1yW2ldCmlmKCFILldlKGEw
-LHFbaV0sYTQsaCxhMikpcmV0dXJuITF9Zm9yKGk9MDtpPG47KytpKXtoPW1baV0KaWYoIUguV2UoYTAs
-cVtwK2ldLGE0LGgsYTIpKXJldHVybiExfWZvcihpPTA7aTxqOysraSl7aD1tW24raV0KaWYoIUguV2Uo
-YTAsbFtpXSxhNCxoLGEyKSlyZXR1cm4hMX1nPXQuYwpmPXMuYwplPWcubGVuZ3RoCmQ9Zi5sZW5ndGgK
-Zm9yKGk9MCxjPTA7YzxkO2MrPTIpe2I9ZltjXQpkb3tpZihpPj1lKXJldHVybiExCmE9Z1tpXQppKz0y
-fXdoaWxlKGE8YikKaWYoYjxhKXJldHVybiExCmg9Z1tpLTFdCmlmKCFILldlKGEwLGZbYysxXSxhNCxo
-LGEyKSlyZXR1cm4hMX1yZXR1cm4hMH0sCnBHOmZ1bmN0aW9uKGEsYixjLGQsZSl7dmFyIHQscyxyLHEs
-cCxvLG4sbSxsPWIuUSxrPWQuUQppZihsPT09ayl7dD1iLmNoCnM9ZC5jaApyPXQubGVuZ3RoCmZvcihx
-PTA7cTxyOysrcSl7cD10W3FdCm89c1txXQppZighSC5XZShhLHAsYyxvLGUpKXJldHVybiExfXJldHVy
-biEwfW49SC5RbyhhLGwpCmlmKG49PW51bGwpcmV0dXJuITEKbT1uW2tdCmlmKG09PW51bGwpcmV0dXJu
-ITEKcj1tLmxlbmd0aApzPWQuY2gKZm9yKHE9MDtxPHI7KytxKWlmKCFILldlKGEsSC5jRShhLGIsbVtx
-XSksYyxzW3FdLGUpKXJldHVybiExCnJldHVybiEwfSwKY2M6ZnVuY3Rpb24oYSl7dmFyIHQscwppZihh
-PT09dS5LKXJldHVybiEwCnQ9YS56CmlmKHQhPT0yKWlmKHQhPT0zKWlmKHQhPT00KWlmKHQhPT01KXM9
-dD09PTgmJkguY2MoYS5RKQplbHNlIHM9ITAKZWxzZSBzPSEwCmVsc2Ugcz0hMAplbHNlIHM9ITAKcmV0
-dXJuIHN9LApJeDpmdW5jdGlvbihhLGIpe3ZhciB0LHMscj1PYmplY3Qua2V5cyhiKSxxPXIubGVuZ3Ro
-CmZvcih0PTA7dDxxOysrdCl7cz1yW3RdCmFbc109YltzXX19LApKYzpmdW5jdGlvbiBKYyhhLGIsYyl7
-dmFyIF89dGhpcwpfLmE9YQpfLmI9YgpfLmM9YwpfLnk9Xy54PV8uZD1udWxsCl8uej0wCl8uZGI9Xy5j
-eT1fLmN4PV8uY2g9Xy5RPW51bGx9LApHOmZ1bmN0aW9uIEcoKXt0aGlzLmM9dGhpcy5iPXRoaXMuYT1u
-dWxsfSwKdTk6ZnVuY3Rpb24gdTkoKXt9LApoejpmdW5jdGlvbiBoeihhKXt0aGlzLmE9YX0sCmlNOmZ1
-bmN0aW9uIGlNKGEpe3RoaXMuYT1hfSwKUjk6ZnVuY3Rpb24oYSl7cmV0dXJuIHUuZC5jKGEpfHx1LkIu
-YyhhKXx8dS5kei5jKGEpfHx1LkkuYyhhKXx8dS5BLmMoYSl8fHUuZzQuYyhhKXx8dS5nMi5jKGEpfSwK
-Smc6ZnVuY3Rpb24oYSl7cmV0dXJuIHYubWFuZ2xlZEdsb2JhbE5hbWVzW2FdfX0sSj17ClF1OmZ1bmN0
-aW9uKGEsYixjLGQpe3JldHVybntpOmEscDpiLGU6Yyx4OmR9fSwKa3M6ZnVuY3Rpb24oYSl7dmFyIHQs
-cyxyLHEscD1hW3YuZGlzcGF0Y2hQcm9wZXJ0eU5hbWVdCmlmKHA9PW51bGwpaWYoJC5Cdj09bnVsbCl7
-SC5YRCgpCnA9YVt2LmRpc3BhdGNoUHJvcGVydHlOYW1lXX1pZihwIT1udWxsKXt0PXAucAppZighMT09
-PXQpcmV0dXJuIHAuaQppZighMD09PXQpcmV0dXJuIGEKcz1PYmplY3QuZ2V0UHJvdG90eXBlT2YoYSkK
-aWYodD09PXMpcmV0dXJuIHAuaQppZihwLmU9PT1zKXRocm93IEguYihQLlNZKCJSZXR1cm4gaW50ZXJj
-ZXB0b3IgZm9yICIrSC5kKHQoYSxwKSkpKX1yPWEuY29uc3RydWN0b3IKcT1yPT1udWxsP251bGw6clsk
-LlVOKCldCmlmKHEhPW51bGwpcmV0dXJuIHEKcT1ILnczKGEpCmlmKHEhPW51bGwpcmV0dXJuIHEKaWYo
-dHlwZW9mIGE9PSJmdW5jdGlvbiIpcmV0dXJuIEMuREcKdD1PYmplY3QuZ2V0UHJvdG90eXBlT2YoYSkK
-aWYodD09bnVsbClyZXR1cm4gQy5aUQppZih0PT09T2JqZWN0LnByb3RvdHlwZSlyZXR1cm4gQy5aUQpp
-Zih0eXBlb2Ygcj09ImZ1bmN0aW9uIil7T2JqZWN0LmRlZmluZVByb3BlcnR5KHIsJC5VTigpLHt2YWx1
-ZTpDLnZCLGVudW1lcmFibGU6ZmFsc2Usd3JpdGFibGU6dHJ1ZSxjb25maWd1cmFibGU6dHJ1ZX0pCnJl
-dHVybiBDLnZCfXJldHVybiBDLnZCfSwKUWk6ZnVuY3Rpb24oYSxiKXtpZihhPDB8fGE+NDI5NDk2NzI5
-NSl0aHJvdyBILmIoUC5URShhLDAsNDI5NDk2NzI5NSwibGVuZ3RoIixudWxsKSkKcmV0dXJuIEoucHko
-bmV3IEFycmF5KGEpLGIpfSwKcHk6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gSi5FcChILlZNKGEsYi5DKCJq
-ZDwwPiIpKSl9LApFcDpmdW5jdGlvbihhKXthLmZpeGVkJGxlbmd0aD1BcnJheQpyZXR1cm4gYX0sCnpD
-OmZ1bmN0aW9uKGEpe2EuZml4ZWQkbGVuZ3RoPUFycmF5CmEuaW1tdXRhYmxlJGxpc3Q9QXJyYXkKcmV0
-dXJuIGF9LApHYTpmdW5jdGlvbihhKXtpZihhPDI1Nilzd2l0Y2goYSl7Y2FzZSA5OmNhc2UgMTA6Y2Fz
-ZSAxMTpjYXNlIDEyOmNhc2UgMTM6Y2FzZSAzMjpjYXNlIDEzMzpjYXNlIDE2MDpyZXR1cm4hMApkZWZh
-dWx0OnJldHVybiExfXN3aXRjaChhKXtjYXNlIDU3NjA6Y2FzZSA4MTkyOmNhc2UgODE5MzpjYXNlIDgx
-OTQ6Y2FzZSA4MTk1OmNhc2UgODE5NjpjYXNlIDgxOTc6Y2FzZSA4MTk4OmNhc2UgODE5OTpjYXNlIDgy
-MDA6Y2FzZSA4MjAxOmNhc2UgODIwMjpjYXNlIDgyMzI6Y2FzZSA4MjMzOmNhc2UgODIzOTpjYXNlIDgy
-ODc6Y2FzZSAxMjI4ODpjYXNlIDY1Mjc5OnJldHVybiEwCmRlZmF1bHQ6cmV0dXJuITF9fSwKbW06ZnVu
-Y3Rpb24oYSxiKXt2YXIgdCxzCmZvcih0PWEubGVuZ3RoO2I8dDspe3M9Qy54Qi5XZChhLGIpCmlmKHMh
-PT0zMiYmcyE9PTEzJiYhSi5HYShzKSlicmVhazsrK2J9cmV0dXJuIGJ9LApjMTpmdW5jdGlvbihhLGIp
-e3ZhciB0LHMKZm9yKDtiPjA7Yj10KXt0PWItMQpzPUMueEIuTzIoYSx0KQppZihzIT09MzImJnMhPT0x
-MyYmIUouR2EocykpYnJlYWt9cmV0dXJuIGJ9LApSRTpmdW5jdGlvbihhKXtpZihhPT1udWxsKXJldHVy
-biBhCmlmKHR5cGVvZiBhIT0ib2JqZWN0Iil7aWYodHlwZW9mIGE9PSJmdW5jdGlvbiIpcmV0dXJuIEou
-YzUucHJvdG90eXBlCnJldHVybiBhfWlmKGEgaW5zdGFuY2VvZiBQLmspcmV0dXJuIGEKcmV0dXJuIEou
-a3MoYSl9LApUSjpmdW5jdGlvbihhKXtpZih0eXBlb2YgYT09Im51bWJlciIpcmV0dXJuIEoucUkucHJv
-dG90eXBlCmlmKHR5cGVvZiBhPT0ic3RyaW5nIilyZXR1cm4gSi5Eci5wcm90b3R5cGUKaWYoYT09bnVs
-bClyZXR1cm4gYQppZihhLmNvbnN0cnVjdG9yPT1BcnJheSlyZXR1cm4gSi5qZC5wcm90b3R5cGUKaWYo
-dHlwZW9mIGEhPSJvYmplY3QiKXtpZih0eXBlb2YgYT09ImZ1bmN0aW9uIilyZXR1cm4gSi5jNS5wcm90
-b3R5cGUKcmV0dXJuIGF9aWYoYSBpbnN0YW5jZW9mIFAuaylyZXR1cm4gYQpyZXR1cm4gSi5rcyhhKX0s
-ClU2OmZ1bmN0aW9uKGEpe2lmKHR5cGVvZiBhPT0ic3RyaW5nIilyZXR1cm4gSi5Eci5wcm90b3R5cGUK
-aWYoYT09bnVsbClyZXR1cm4gYQppZihhLmNvbnN0cnVjdG9yPT1BcnJheSlyZXR1cm4gSi5qZC5wcm90
-b3R5cGUKaWYodHlwZW9mIGEhPSJvYmplY3QiKXtpZih0eXBlb2YgYT09ImZ1bmN0aW9uIilyZXR1cm4g
-Si5jNS5wcm90b3R5cGUKcmV0dXJuIGF9aWYoYSBpbnN0YW5jZW9mIFAuaylyZXR1cm4gYQpyZXR1cm4g
-Si5rcyhhKX0sCmlhOmZ1bmN0aW9uKGEpe2lmKHR5cGVvZiBhPT0ibnVtYmVyIil7aWYoTWF0aC5mbG9v
-cihhKT09YSlyZXR1cm4gSi51ci5wcm90b3R5cGUKcmV0dXJuIEouVkEucHJvdG90eXBlfWlmKHR5cGVv
-ZiBhPT0ic3RyaW5nIilyZXR1cm4gSi5Eci5wcm90b3R5cGUKaWYoYT09bnVsbClyZXR1cm4gSi5ZRS5w
-cm90b3R5cGUKaWYodHlwZW9mIGE9PSJib29sZWFuIilyZXR1cm4gSi55RS5wcm90b3R5cGUKaWYoYS5j
-b25zdHJ1Y3Rvcj09QXJyYXkpcmV0dXJuIEouamQucHJvdG90eXBlCmlmKHR5cGVvZiBhIT0ib2JqZWN0
-Iil7aWYodHlwZW9mIGE9PSJmdW5jdGlvbiIpcmV0dXJuIEouYzUucHJvdG90eXBlCnJldHVybiBhfWlm
-KGEgaW5zdGFuY2VvZiBQLmspcmV0dXJuIGEKcmV0dXJuIEoua3MoYSl9LApyWTpmdW5jdGlvbihhKXtp
-Zih0eXBlb2YgYT09InN0cmluZyIpcmV0dXJuIEouRHIucHJvdG90eXBlCmlmKGE9PW51bGwpcmV0dXJu
-IGEKaWYoIShhIGluc3RhbmNlb2YgUC5rKSlyZXR1cm4gSi5rZC5wcm90b3R5cGUKcmV0dXJuIGF9LAp6
-cTpmdW5jdGlvbihhKXtpZihhPT1udWxsKXJldHVybiBhCmlmKGEuY29uc3RydWN0b3I9PUFycmF5KXJl
-dHVybiBKLmpkLnByb3RvdHlwZQppZih0eXBlb2YgYSE9Im9iamVjdCIpe2lmKHR5cGVvZiBhPT0iZnVu
-Y3Rpb24iKXJldHVybiBKLmM1LnByb3RvdHlwZQpyZXR1cm4gYX1pZihhIGluc3RhbmNlb2YgUC5rKXJl
-dHVybiBhCnJldHVybiBKLmtzKGEpfSwKQjI6ZnVuY3Rpb24oYSxiLGMpe3JldHVybiBKLnpxKGEpLlko
-YSxiLGMpfSwKQ006ZnVuY3Rpb24oYSxiLGMsZCl7cmV0dXJuIEouUkUoYSkuZHUoYSxiLGMsZCl9LApG
-TDpmdW5jdGlvbihhLGIpe3JldHVybiBKLnJZKGEpLmRkKGEsYil9LApHQTpmdW5jdGlvbihhLGIpe3Jl
-dHVybiBKLnpxKGEpLlcoYSxiKX0sCkdyOmZ1bmN0aW9uKGEpe3JldHVybiBKLlJFKGEpLmdtVyhhKX0s
-CkhtOmZ1bmN0aW9uKGEpe3JldHVybiBKLlU2KGEpLmdoKGEpfSwKSVQ6ZnVuY3Rpb24oYSl7cmV0dXJu
-IEouenEoYSkuZ2t6KGEpfSwKSnk6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gSi5pYShhKS5lNyhhLGIpfSwK
-S1Y6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gSi5yWShhKS55bihhLGIpfSwKTHQ6ZnVuY3Rpb24oYSl7cmV0
-dXJuIEouUkUoYSkud2coYSl9LApNMTpmdW5jdGlvbihhLGIsYyl7cmV0dXJuIEouenEoYSkuRTIoYSxi
-LGMpfSwKUU06ZnVuY3Rpb24oYSl7cmV0dXJuIEouUkUoYSkuZ1B1KGEpfSwKUXo6ZnVuY3Rpb24oYSxi
-KXtyZXR1cm4gSi5yWShhKS5XZChhLGIpfSwKUk06ZnVuY3Rpb24oYSxiKXtpZihhPT1udWxsKXJldHVy
-biBiPT1udWxsCmlmKHR5cGVvZiBhIT0ib2JqZWN0IilyZXR1cm4gYiE9bnVsbCYmYT09PWIKcmV0dXJu
-IEouaWEoYSkuRE4oYSxiKX0sClQwOmZ1bmN0aW9uKGEpe3JldHVybiBKLnJZKGEpLmJTKGEpfSwKYTY6
-ZnVuY3Rpb24oYSxiKXtyZXR1cm4gSi5yWShhKS5PMihhLGIpfSwKYlQ6ZnVuY3Rpb24oYSl7cmV0dXJu
-IEouUkUoYSkuRDQoYSl9LApiYjpmdW5jdGlvbihhLGIpe2lmKHR5cGVvZiBhPT0ibnVtYmVyIiYmdHlw
-ZW9mIGI9PSJudW1iZXIiKXJldHVybiBhK2IKcmV0dXJuIEouVEooYSkuVChhLGIpfSwKY0g6ZnVuY3Rp
-b24oYSl7cmV0dXJuIEouclkoYSkuaGMoYSl9LApkUjpmdW5jdGlvbihhKXtyZXR1cm4gSi5SRShhKS5n
-REQoYSl9LApkWjpmdW5jdGlvbihhLGIsYyxkKXtyZXR1cm4gSi5SRShhKS5PbihhLGIsYyxkKX0sCmRn
-OmZ1bmN0aW9uKGEsYixjLGQpe3JldHVybiBKLnJZKGEpLmk3KGEsYixjLGQpfSwKZGg6ZnVuY3Rpb24o
-YSl7cmV0dXJuIEouUkUoYSkudG4oYSl9LApoRTpmdW5jdGlvbihhLGIpe3JldHVybiBKLnpxKGEpLlUo
-YSxiKX0sCmhmOmZ1bmN0aW9uKGEpe3JldHVybiBKLmlhKGEpLmdpKGEpfSwKaHc6ZnVuY3Rpb24oYSxi
-KXtyZXR1cm4gSi5yWShhKS5UYyhhLGIpfSwKaWc6ZnVuY3Rpb24oYSl7cmV0dXJuIEouUkUoYSkuZ1Fn
-KGEpfSwKajpmdW5jdGlvbihhKXtyZXR1cm4gSi5pYShhKS53KGEpfSwKbDU6ZnVuY3Rpb24oYSxiKXty
-ZXR1cm4gSi5SRShhKS5zaGYoYSxiKX0sCmxkOmZ1bmN0aW9uKGEsYixjKXtyZXR1cm4gSi5yWShhKS5O
-aihhLGIsYyl9LApxMDpmdW5jdGlvbihhLGIsYyl7cmV0dXJuIEouclkoYSkuUWkoYSxiLGMpfSwKcUY6
-ZnVuY3Rpb24oYSl7cmV0dXJuIEouUkUoYSkuZ1ZsKGEpfSwKdEg6ZnVuY3Rpb24oYSxiLGMpe3JldHVy
-biBKLlJFKGEpLnBrKGEsYixjKX0sCncyOmZ1bmN0aW9uKGEsYil7aWYodHlwZW9mIGI9PT0ibnVtYmVy
-IilpZihhLmNvbnN0cnVjdG9yPT1BcnJheXx8dHlwZW9mIGE9PSJzdHJpbmcifHxILlh0KGEsYVt2LmRp
-c3BhdGNoUHJvcGVydHlOYW1lXSkpaWYoYj4+PjA9PT1iJiZiPGEubGVuZ3RoKXJldHVybiBhW2JdCnJl
-dHVybiBKLlU2KGEpLnEoYSxiKX0sCnpsOmZ1bmN0aW9uKGEsYil7cmV0dXJuIEouVTYoYSkudGcoYSxi
-KX0sCnZCOmZ1bmN0aW9uIHZCKCl7fSwKeUU6ZnVuY3Rpb24geUUoKXt9LApZRTpmdW5jdGlvbiBZRSgp
-e30sCk1GOmZ1bmN0aW9uIE1GKCl7fSwKaUM6ZnVuY3Rpb24gaUMoKXt9LAprZDpmdW5jdGlvbiBrZCgp
-e30sCmM1OmZ1bmN0aW9uIGM1KCl7fSwKamQ6ZnVuY3Rpb24gamQoYSl7dGhpcy4kdGk9YX0sClBvOmZ1
-bmN0aW9uIFBvKGEpe3RoaXMuJHRpPWF9LAptMTpmdW5jdGlvbiBtMShhLGIsYyl7dmFyIF89dGhpcwpf
-LmE9YQpfLmI9YgpfLmM9MApfLmQ9bnVsbApfLiR0aT1jfSwKcUk6ZnVuY3Rpb24gcUkoKXt9LAp1cjpm
-dW5jdGlvbiB1cigpe30sClZBOmZ1bmN0aW9uIFZBKCl7fSwKRHI6ZnVuY3Rpb24gRHIoKXt9fSxQPXsK
-T2o6ZnVuY3Rpb24oKXt2YXIgdCxzLHI9e30KaWYoc2VsZi5zY2hlZHVsZUltbWVkaWF0ZSE9bnVsbCly
-ZXR1cm4gUC5FWCgpCmlmKHNlbGYuTXV0YXRpb25PYnNlcnZlciE9bnVsbCYmc2VsZi5kb2N1bWVudCE9
-bnVsbCl7dD1zZWxmLmRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoImRpdiIpCnM9c2VsZi5kb2N1bWVudC5j
-cmVhdGVFbGVtZW50KCJzcGFuIikKci5hPW51bGwKbmV3IHNlbGYuTXV0YXRpb25PYnNlcnZlcihILnRS
-KG5ldyBQLnRoKHIpLDEpKS5vYnNlcnZlKHQse2NoaWxkTGlzdDp0cnVlfSkKcmV0dXJuIG5ldyBQLmhh
-KHIsdCxzKX1lbHNlIGlmKHNlbGYuc2V0SW1tZWRpYXRlIT1udWxsKXJldHVybiBQLnl0KCkKcmV0dXJu
-IFAucVcoKX0sClpWOmZ1bmN0aW9uKGEpe3NlbGYuc2NoZWR1bGVJbW1lZGlhdGUoSC50UihuZXcgUC5W
-cyh1Lk0uYihhKSksMCkpfSwKcUc6ZnVuY3Rpb24oYSl7c2VsZi5zZXRJbW1lZGlhdGUoSC50UihuZXcg
-UC5GdCh1Lk0uYihhKSksMCkpfSwKQno6ZnVuY3Rpb24oYSl7dS5NLmIoYSkKUC5RTigwLGEpfSwKUU46
-ZnVuY3Rpb24oYSxiKXt2YXIgdD1uZXcgUC5XMygpCnQuQ1koYSxiKQpyZXR1cm4gdH0sCkZYOmZ1bmN0
-aW9uKGEpe3JldHVybiBuZXcgUC5paChuZXcgUC52cygkLlgzLGEuQygidnM8MD4iKSksYS5DKCJpaDww
-PiIpKX0sCkRJOmZ1bmN0aW9uKGEsYil7YS4kMigwLG51bGwpCmIuYj0hMApyZXR1cm4gYi5hfSwKalE6
-ZnVuY3Rpb24oYSxiKXtQLkplKGEsYil9LAp5QzpmdW5jdGlvbihhLGIpe2IuYU0oMCxhKX0sCmYzOmZ1
-bmN0aW9uKGEsYil7Yi53MChILlJ1KGEpLEgudHMoYSkpfSwKSmU6ZnVuY3Rpb24oYSxiKXt2YXIgdCxz
-LHI9bmV3IFAuV00oYikscT1uZXcgUC5TWChiKQppZihhIGluc3RhbmNlb2YgUC52cylhLlFkKHIscSx1
-LnopCmVsc2V7dD11LnoKaWYodS5jLmMoYSkpYS5TcShyLHEsdCkKZWxzZXtzPW5ldyBQLnZzKCQuWDMs
-dS5fKQpzLmE9NApzLmM9YQpzLlFkKHIsbnVsbCx0KX19fSwKbHo6ZnVuY3Rpb24oYSl7dmFyIHQ9ZnVu
-Y3Rpb24oYixjKXtyZXR1cm4gZnVuY3Rpb24oZCxlKXt3aGlsZSh0cnVlKXRyeXtiKGQsZSkKYnJlYWt9
-Y2F0Y2gocyl7ZT1zCmQ9Y319fShhLDEpCnJldHVybiAkLlgzLkxqKG5ldyBQLkdzKHQpLHUuUCx1LmVn
-LHUueil9LApHUTpmdW5jdGlvbihhKXtyZXR1cm4gbmV3IFAuRnkoYSwxKX0sClRoOmZ1bmN0aW9uKCl7
-cmV0dXJuIEMud1F9LApZbTpmdW5jdGlvbihhKXtyZXR1cm4gbmV3IFAuRnkoYSwzKX0sCmwwOmZ1bmN0
-aW9uKGEsYil7cmV0dXJuIG5ldyBQLnE0KGEsYi5DKCJxNDwwPiIpKX0sCmszOmZ1bmN0aW9uKGEsYil7
-dmFyIHQscyxyCmIuYT0xCnRyeXthLlNxKG5ldyBQLnBWKGIpLG5ldyBQLlU3KGIpLHUuUCl9Y2F0Y2go
-cil7dD1ILlJ1KHIpCnM9SC50cyhyKQpQLnJiKG5ldyBQLnZyKGIsdCxzKSl9fSwKQTk6ZnVuY3Rpb24o
-YSxiKXt2YXIgdCxzLHIKZm9yKHQ9dS5fO3M9YS5hLHM9PT0yOylhPXQuYihhLmMpCmlmKHM+PTQpe3I9
-Yi5haCgpCmIuYT1hLmEKYi5jPWEuYwpQLkhaKGIscil9ZWxzZXtyPXUueC5iKGIuYykKYi5hPTIKYi5j
-PWEKYS5qUShyKX19LApIWjpmdW5jdGlvbihhLGIpe3ZhciB0LHMscixxLHAsbyxuLG0sbCxrLGosaSxo
-LGcsZixlPW51bGwsZD17fSxjPWQuYT1hCmZvcih0PXUubixzPXUueCxyPXUuYzshMDspe3E9e30KcD1j
-LmE9PT04CmlmKGI9PW51bGwpe2lmKHApe289dC5iKGMuYykKUC5MMihlLGUsYy5iLG8uYSxvLmIpfXJl
-dHVybn1mb3IoO249Yi5hLG4hPW51bGw7Yj1uKXtiLmE9bnVsbApQLkhaKGQuYSxiKX1jPWQuYQptPWMu
-YwpxLmE9cApxLmI9bQpsPSFwCmlmKGwpe2s9Yi5jCms9KGsmMSkhPT0wfHwoayYxNSk9PT04fWVsc2Ug
-az0hMAppZihrKXtrPWIuYgpqPWsuYgppZihwKXtpPWMuYj09PWoKaT0hKGl8fGkpfWVsc2UgaT0hMQpp
-ZihpKXt0LmIobSkKUC5MMihlLGUsYy5iLG0uYSxtLmIpCnJldHVybn1oPSQuWDMKaWYoaCE9PWopJC5Y
-Mz1qCmVsc2UgaD1lCmM9Yi5jCmlmKChjJjE1KT09PTgpbmV3IFAuUlQoZCxxLGIscCkuJDAoKQplbHNl
-IGlmKGwpe2lmKChjJjEpIT09MCluZXcgUC5ycShxLGIsbSkuJDAoKX1lbHNlIGlmKChjJjIpIT09MClu
-ZXcgUC5SVyhkLHEsYikuJDAoKQppZihoIT1udWxsKSQuWDM9aApjPXEuYgppZihyLmMoYykpe2lmKGMu
-YT49NCl7Zz1zLmIoay5jKQprLmM9bnVsbApiPWsuTjgoZykKay5hPWMuYQprLmM9Yy5jCmQuYT1jCmNv
-bnRpbnVlfWVsc2UgUC5BOShjLGspCnJldHVybn19Zj1iLmIKZz1zLmIoZi5jKQpmLmM9bnVsbApiPWYu
-TjgoZykKYz1xLmEKbD1xLmIKaWYoIWMpe2YuJHRpLmQuYihsKQpmLmE9NApmLmM9bH1lbHNle3QuYihs
-KQpmLmE9OApmLmM9bH1kLmE9ZgpjPWZ9fSwKVkg6ZnVuY3Rpb24oYSxiKXt2YXIgdAppZih1LmFnLmMo
-YSkpcmV0dXJuIGIuTGooYSx1LnosdS5LLHUubCkKdD11LnkKaWYodC5jKGEpKXJldHVybiB0LmIoYSkK
-dGhyb3cgSC5iKFAuTDMoYSwib25FcnJvciIsIkVycm9yIGhhbmRsZXIgbXVzdCBhY2NlcHQgb25lIE9i
-amVjdCBvciBvbmUgT2JqZWN0IGFuZCBhIFN0YWNrVHJhY2UgYXMgYXJndW1lbnRzLCBhbmQgcmV0dXJu
-IGEgYSB2YWxpZCByZXN1bHQiKSl9LApwdTpmdW5jdGlvbigpe3ZhciB0LHMKZm9yKDt0PSQuUzYsdCE9
-bnVsbDspeyQubWc9bnVsbApzPXQuYgokLlM2PXMKaWYocz09bnVsbCkkLms4PW51bGwKdC5hLiQwKCl9
-fSwKZU46ZnVuY3Rpb24oKXskLlVEPSEwCnRyeXtQLnB1KCl9ZmluYWxseXskLm1nPW51bGwKJC5VRD0h
-MQppZigkLlM2IT1udWxsKSQudXQoKS4kMShQLlVJKCkpfX0sCmVXOmZ1bmN0aW9uKGEpe3ZhciB0PW5l
-dyBQLk9NKGEpCmlmKCQuUzY9PW51bGwpeyQuUzY9JC5rOD10CmlmKCEkLlVEKSQudXQoKS4kMShQLlVJ
-KCkpfWVsc2UgJC5rOD0kLms4LmI9dH0sCnJSOmZ1bmN0aW9uKGEpe3ZhciB0LHMscj0kLlM2CmlmKHI9
-PW51bGwpe1AuZVcoYSkKJC5tZz0kLms4CnJldHVybn10PW5ldyBQLk9NKGEpCnM9JC5tZwppZihzPT1u
-dWxsKXt0LmI9cgokLlM2PSQubWc9dH1lbHNle3QuYj1zLmIKJC5tZz1zLmI9dAppZih0LmI9PW51bGwp
-JC5rOD10fX0sCnJiOmZ1bmN0aW9uKGEpe3ZhciB0PW51bGwscz0kLlgzCmlmKEMuTlU9PT1zKXtQLlRr
-KHQsdCxDLk5VLGEpCnJldHVybn1QLlRrKHQsdCxzLHUuTS5iKHMuR1koYSkpKX0sClF3OmZ1bmN0aW9u
-KGEsYil7aWYoYT09bnVsbClILlZqKFAuRWUoInN0cmVhbSIpKQpyZXR1cm4gbmV3IFAueEkoYi5DKCJ4
-STwwPiIpKX0sCkwyOmZ1bmN0aW9uKGEsYixjLGQsZSl7dmFyIHQ9e30KdC5hPWQKUC5yUihuZXcgUC5w
-Syh0LGUpKX0sClQ4OmZ1bmN0aW9uKGEsYixjLGQsZSl7dmFyIHQscz0kLlgzCmlmKHM9PT1jKXJldHVy
-biBkLiQwKCkKJC5YMz1jCnQ9cwp0cnl7cz1kLiQwKCkKcmV0dXJuIHN9ZmluYWxseXskLlgzPXR9fSwK
-eXY6ZnVuY3Rpb24oYSxiLGMsZCxlLGYsZyl7dmFyIHQscz0kLlgzCmlmKHM9PT1jKXJldHVybiBkLiQx
-KGUpCiQuWDM9Ywp0PXMKdHJ5e3M9ZC4kMShlKQpyZXR1cm4gc31maW5hbGx5eyQuWDM9dH19LApReDpm
-dW5jdGlvbihhLGIsYyxkLGUsZixnLGgsaSl7dmFyIHQscz0kLlgzCmlmKHM9PT1jKXJldHVybiBkLiQy
-KGUsZikKJC5YMz1jCnQ9cwp0cnl7cz1kLiQyKGUsZikKcmV0dXJuIHN9ZmluYWxseXskLlgzPXR9fSwK
-VGs6ZnVuY3Rpb24oYSxiLGMsZCl7dmFyIHQKdS5NLmIoZCkKdD1DLk5VIT09YwppZih0KWQ9ISghdHx8
-ITEpP2MuR1koZCk6Yy5SVChkLHUuSCkKUC5lVyhkKX0sCnRoOmZ1bmN0aW9uIHRoKGEpe3RoaXMuYT1h
-fSwKaGE6ZnVuY3Rpb24gaGEoYSxiLGMpe3RoaXMuYT1hCnRoaXMuYj1iCnRoaXMuYz1jfSwKVnM6ZnVu
-Y3Rpb24gVnMoYSl7dGhpcy5hPWF9LApGdDpmdW5jdGlvbiBGdChhKXt0aGlzLmE9YX0sClczOmZ1bmN0
-aW9uIFczKCl7fSwKeUg6ZnVuY3Rpb24geUgoYSxiKXt0aGlzLmE9YQp0aGlzLmI9Yn0sCmloOmZ1bmN0
-aW9uIGloKGEsYil7dGhpcy5hPWEKdGhpcy5iPSExCnRoaXMuJHRpPWJ9LApXTTpmdW5jdGlvbiBXTShh
-KXt0aGlzLmE9YX0sClNYOmZ1bmN0aW9uIFNYKGEpe3RoaXMuYT1hfSwKR3M6ZnVuY3Rpb24gR3MoYSl7
-dGhpcy5hPWF9LApGeTpmdW5jdGlvbiBGeShhLGIpe3RoaXMuYT1hCnRoaXMuYj1ifSwKR1Y6ZnVuY3Rp
-b24gR1YoYSxiKXt2YXIgXz10aGlzCl8uYT1hCl8uZD1fLmM9Xy5iPW51bGwKXy4kdGk9Yn0sCnE0OmZ1
-bmN0aW9uIHE0KGEsYil7dGhpcy5hPWEKdGhpcy4kdGk9Yn0sCmI4OmZ1bmN0aW9uIGI4KCl7fSwKUGY6
-ZnVuY3Rpb24gUGYoKXt9LApaZjpmdW5jdGlvbiBaZihhLGIpe3RoaXMuYT1hCnRoaXMuJHRpPWJ9LApG
-ZTpmdW5jdGlvbiBGZShhLGIsYyxkLGUpe3ZhciBfPXRoaXMKXy5hPW51bGwKXy5iPWEKXy5jPWIKXy5k
-PWMKXy5lPWQKXy4kdGk9ZX0sCnZzOmZ1bmN0aW9uIHZzKGEsYil7dmFyIF89dGhpcwpfLmE9MApfLmI9
-YQpfLmM9bnVsbApfLiR0aT1ifSwKZGE6ZnVuY3Rpb24gZGEoYSxiKXt0aGlzLmE9YQp0aGlzLmI9Yn0s
-Cm9ROmZ1bmN0aW9uIG9RKGEsYil7dGhpcy5hPWEKdGhpcy5iPWJ9LApwVjpmdW5jdGlvbiBwVihhKXt0
-aGlzLmE9YX0sClU3OmZ1bmN0aW9uIFU3KGEpe3RoaXMuYT1hfSwKdnI6ZnVuY3Rpb24gdnIoYSxiLGMp
-e3RoaXMuYT1hCnRoaXMuYj1iCnRoaXMuYz1jfSwKckg6ZnVuY3Rpb24gckgoYSxiKXt0aGlzLmE9YQp0
-aGlzLmI9Yn0sCktGOmZ1bmN0aW9uIEtGKGEsYil7dGhpcy5hPWEKdGhpcy5iPWJ9LApaTDpmdW5jdGlv
-biBaTChhLGIsYyl7dGhpcy5hPWEKdGhpcy5iPWIKdGhpcy5jPWN9LApSVDpmdW5jdGlvbiBSVChhLGIs
-YyxkKXt2YXIgXz10aGlzCl8uYT1hCl8uYj1iCl8uYz1jCl8uZD1kfSwKalo6ZnVuY3Rpb24galooYSl7
-dGhpcy5hPWF9LApycTpmdW5jdGlvbiBycShhLGIsYyl7dGhpcy5hPWEKdGhpcy5iPWIKdGhpcy5jPWN9
-LApSVzpmdW5jdGlvbiBSVyhhLGIsYyl7dGhpcy5hPWEKdGhpcy5iPWIKdGhpcy5jPWN9LApPTTpmdW5j
-dGlvbiBPTShhKXt0aGlzLmE9YQp0aGlzLmI9bnVsbH0sCnFoOmZ1bmN0aW9uIHFoKCl7fSwKQjU6ZnVu
-Y3Rpb24gQjUoYSxiKXt0aGlzLmE9YQp0aGlzLmI9Yn0sClBJOmZ1bmN0aW9uIFBJKGEsYil7dGhpcy5h
-PWEKdGhpcy5iPWJ9LApNTzpmdW5jdGlvbiBNTygpe30sCmtUOmZ1bmN0aW9uIGtUKCl7fSwKeEk6ZnVu
-Y3Rpb24geEkoYSl7dGhpcy4kdGk9YX0sCkN3OmZ1bmN0aW9uIEN3KGEsYil7dGhpcy5hPWEKdGhpcy5i
-PWJ9LAptMDpmdW5jdGlvbiBtMCgpe30sCnBLOmZ1bmN0aW9uIHBLKGEsYil7dGhpcy5hPWEKdGhpcy5i
-PWJ9LApKaTpmdW5jdGlvbiBKaSgpe30sCmhqOmZ1bmN0aW9uIGhqKGEsYixjKXt0aGlzLmE9YQp0aGlz
-LmI9Ygp0aGlzLmM9Y30sClZwOmZ1bmN0aW9uIFZwKGEsYil7dGhpcy5hPWEKdGhpcy5iPWJ9LApPUjpm
-dW5jdGlvbiBPUihhLGIsYyl7dGhpcy5hPWEKdGhpcy5iPWIKdGhpcy5jPWN9LApFRjpmdW5jdGlvbihh
-LGIsYyl7cmV0dXJuIGIuQygiQDwwPiIpLksoYykuQygiRm88MSwyPiIpLmIoSC5CNyhhLG5ldyBILk41
-KGIuQygiQDwwPiIpLksoYykuQygiTjU8MSwyPiIpKSkpfSwKRmw6ZnVuY3Rpb24oYSxiKXtyZXR1cm4g
-bmV3IEguTjUoYS5DKCJAPDA+IikuSyhiKS5DKCJONTwxLDI+IikpfSwKTHM6ZnVuY3Rpb24oYSl7cmV0
-dXJuIG5ldyBQLmI2KGEuQygiYjY8MD4iKSl9LApUMjpmdW5jdGlvbigpe3ZhciB0PU9iamVjdC5jcmVh
-dGUobnVsbCkKdFsiPG5vbi1pZGVudGlmaWVyLWtleT4iXT10CmRlbGV0ZSB0WyI8bm9uLWlkZW50aWZp
-ZXIta2V5PiJdCnJldHVybiB0fSwKcmo6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0PW5ldyBQLmxtKGEsYixj
-LkMoImxtPDA+IikpCnQuYz1hLmUKcmV0dXJuIHR9LApFUDpmdW5jdGlvbihhLGIsYyl7dmFyIHQscwpp
-ZihQLmhCKGEpKXtpZihiPT09IigiJiZjPT09IikiKXJldHVybiIoLi4uKSIKcmV0dXJuIGIrIi4uLiIr
-Y310PUguVk0oW10sdS5zKQpDLk5tLkEoJC54ZyxhKQp0cnl7UC5WcihhLHQpfWZpbmFsbHl7aWYoMD49
-JC54Zy5sZW5ndGgpcmV0dXJuIEguT0goJC54ZywtMSkKJC54Zy5wb3AoKX1zPVAudmcoYix1LlIuYih0
-KSwiLCAiKStjCnJldHVybiBzLmNoYXJDb2RlQXQoMCk9PTA/czpzfSwKV0U6ZnVuY3Rpb24oYSxiLGMp
-e3ZhciB0LHMKaWYoUC5oQihhKSlyZXR1cm4gYisiLi4uIitjCnQ9bmV3IFAuUm4oYikKQy5ObS5BKCQu
-eGcsYSkKdHJ5e3M9dApzLmE9UC52ZyhzLmEsYSwiLCAiKX1maW5hbGx5e2lmKDA+PSQueGcubGVuZ3Ro
-KXJldHVybiBILk9IKCQueGcsLTEpCiQueGcucG9wKCl9dC5hKz1jCnM9dC5hCnJldHVybiBzLmNoYXJD
-b2RlQXQoMCk9PTA/czpzfSwKaEI6ZnVuY3Rpb24oYSl7dmFyIHQscwpmb3IodD0kLnhnLmxlbmd0aCxz
-PTA7czx0OysrcylpZihhPT09JC54Z1tzXSlyZXR1cm4hMApyZXR1cm4hMX0sClZyOmZ1bmN0aW9uKGEs
-Yil7dmFyIHQscyxyLHEscCxvLG4sbT1hLmdreihhKSxsPTAsaz0wCndoaWxlKCEwKXtpZighKGw8ODB8
-fGs8MykpYnJlYWsKaWYoIW0ubSgpKXJldHVybgp0PUguZChtLmdSKG0pKQpDLk5tLkEoYix0KQpsKz10
-Lmxlbmd0aCsyOysra31pZighbS5tKCkpe2lmKGs8PTUpcmV0dXJuCmlmKDA+PWIubGVuZ3RoKXJldHVy
-biBILk9IKGIsLTEpCnM9Yi5wb3AoKQppZigwPj1iLmxlbmd0aClyZXR1cm4gSC5PSChiLC0xKQpyPWIu
-cG9wKCl9ZWxzZXtxPW0uZ1IobSk7KytrCmlmKCFtLm0oKSl7aWYoazw9NCl7Qy5ObS5BKGIsSC5kKHEp
-KQpyZXR1cm59cz1ILmQocSkKaWYoMD49Yi5sZW5ndGgpcmV0dXJuIEguT0goYiwtMSkKcj1iLnBvcCgp
-CmwrPXMubGVuZ3RoKzJ9ZWxzZXtwPW0uZ1IobSk7KytrCmZvcig7bS5tKCk7cT1wLHA9byl7bz1tLmdS
-KG0pOysrawppZihrPjEwMCl7d2hpbGUoITApe2lmKCEobD43NSYmaz4zKSlicmVhawppZigwPj1iLmxl
-bmd0aClyZXR1cm4gSC5PSChiLC0xKQpsLT1iLnBvcCgpLmxlbmd0aCsyOy0ta31DLk5tLkEoYiwiLi4u
-IikKcmV0dXJufX1yPUguZChxKQpzPUguZChwKQpsKz1zLmxlbmd0aCtyLmxlbmd0aCs0fX1pZihrPmIu
-bGVuZ3RoKzIpe2wrPTUKbj0iLi4uIn1lbHNlIG49bnVsbAp3aGlsZSghMCl7aWYoIShsPjgwJiZiLmxl
-bmd0aD4zKSlicmVhawppZigwPj1iLmxlbmd0aClyZXR1cm4gSC5PSChiLC0xKQpsLT1iLnBvcCgpLmxl
-bmd0aCsyCmlmKG49PW51bGwpe2wrPTUKbj0iLi4uIn19aWYobiE9bnVsbClDLk5tLkEoYixuKQpDLk5t
-LkEoYixyKQpDLk5tLkEoYixzKX0sCnRNOmZ1bmN0aW9uKGEsYil7dmFyIHQscyxyPVAuTHMoYikKZm9y
-KHQ9YS5sZW5ndGgscz0wO3M8YS5sZW5ndGg7YS5sZW5ndGg9PT10fHwoMCxILmxrKShhKSwrK3Mpci5B
-KDAsYi5iKGFbc10pKQpyZXR1cm4gcn0sCm5POmZ1bmN0aW9uKGEpe3ZhciB0LHM9e30KaWYoUC5oQihh
-KSlyZXR1cm4iey4uLn0iCnQ9bmV3IFAuUm4oIiIpCnRyeXtDLk5tLkEoJC54ZyxhKQp0LmErPSJ7Igpz
-LmE9ITAKSi5oRShhLG5ldyBQLnJhKHMsdCkpCnQuYSs9In0ifWZpbmFsbHl7aWYoMD49JC54Zy5sZW5n
-dGgpcmV0dXJuIEguT0goJC54ZywtMSkKJC54Zy5wb3AoKX1zPXQuYQpyZXR1cm4gcy5jaGFyQ29kZUF0
-KDApPT0wP3M6c30sCmI2OmZ1bmN0aW9uIGI2KGEpe3ZhciBfPXRoaXMKXy5hPTAKXy5mPV8uZT1fLmQ9
-Xy5jPV8uYj1udWxsCl8ucj0wCl8uJHRpPWF9LApibjpmdW5jdGlvbiBibihhKXt0aGlzLmE9YQp0aGlz
-LmM9dGhpcy5iPW51bGx9LApsbTpmdW5jdGlvbiBsbShhLGIsYyl7dmFyIF89dGhpcwpfLmE9YQpfLmI9
-YgpfLmQ9Xy5jPW51bGwKXy4kdGk9Y30sCm1XOmZ1bmN0aW9uIG1XKCl7fSwKTFU6ZnVuY3Rpb24gTFUo
-KXt9LApsRDpmdW5jdGlvbiBsRCgpe30sCmlsOmZ1bmN0aW9uIGlsKCl7fSwKcmE6ZnVuY3Rpb24gcmEo
-YSxiKXt0aGlzLmE9YQp0aGlzLmI9Yn0sCllrOmZ1bmN0aW9uIFlrKCl7fSwKeVE6ZnVuY3Rpb24geVEo
-YSl7dGhpcy5hPWF9LApLUDpmdW5jdGlvbiBLUCgpe30sClBuOmZ1bmN0aW9uIFBuKCl7fSwKR2o6ZnVu
-Y3Rpb24gR2ooYSxiKXt0aGlzLmE9YQp0aGlzLiR0aT1ifSwKbGY6ZnVuY3Rpb24gbGYoKXt9LApSSzpm
-dW5jdGlvbiBSSygpe30sClh2OmZ1bmN0aW9uIFh2KCl7fSwKblk6ZnVuY3Rpb24gblkoKXt9LApXWTpm
-dW5jdGlvbiBXWSgpe30sClJVOmZ1bmN0aW9uIFJVKCl7fSwKQlM6ZnVuY3Rpb24oYSxiKXt2YXIgdCxz
-LHIscQppZih0eXBlb2YgYSE9InN0cmluZyIpdGhyb3cgSC5iKEgudEwoYSkpCnQ9bnVsbAp0cnl7dD1K
-U09OLnBhcnNlKGEpfWNhdGNoKHIpe3M9SC5SdShyKQpxPVAucnIoU3RyaW5nKHMpLG51bGwsbnVsbCkK
-dGhyb3cgSC5iKHEpfXE9UC5RZSh0KQpyZXR1cm4gcX0sClFlOmZ1bmN0aW9uKGEpe3ZhciB0CmlmKGE9
-PW51bGwpcmV0dXJuIG51bGwKaWYodHlwZW9mIGEhPSJvYmplY3QiKXJldHVybiBhCmlmKE9iamVjdC5n
-ZXRQcm90b3R5cGVPZihhKSE9PUFycmF5LnByb3RvdHlwZSlyZXR1cm4gbmV3IFAudXcoYSxPYmplY3Qu
-Y3JlYXRlKG51bGwpKQpmb3IodD0wO3Q8YS5sZW5ndGg7Kyt0KWFbdF09UC5RZShhW3RdKQpyZXR1cm4g
-YX0sCmt5OmZ1bmN0aW9uKGEsYixjLGQpe2lmKGIgaW5zdGFuY2VvZiBVaW50OEFycmF5KXJldHVybiBQ
-LlJQKCExLGIsYyxkKQpyZXR1cm4gbnVsbH0sClJQOmZ1bmN0aW9uKGEsYixjLGQpe3ZhciB0LHMscj0k
-LnJmKCkKaWYocj09bnVsbClyZXR1cm4gbnVsbAp0PTA9PT1jCmlmKHQmJiEwKXJldHVybiBQLk9RKHIs
-YikKcz1iLmxlbmd0aApkPVAuakIoYyxkLHMpCmlmKHQmJmQ9PT1zKXJldHVybiBQLk9RKHIsYikKcmV0
-dXJuIFAuT1EocixiLnN1YmFycmF5KGMsZCkpfSwKT1E6ZnVuY3Rpb24oYSxiKXtpZihQLkJlKGIpKXJl
-dHVybiBudWxsCnJldHVybiBQLkpoKGEsYil9LApKaDpmdW5jdGlvbihhLGIpe3ZhciB0LHMKdHJ5e3Q9
-YS5kZWNvZGUoYikKcmV0dXJuIHR9Y2F0Y2gocyl7SC5SdShzKX1yZXR1cm4gbnVsbH0sCkJlOmZ1bmN0
-aW9uKGEpe3ZhciB0LHM9YS5sZW5ndGgtMgpmb3IodD0wO3Q8czsrK3QpaWYoYVt0XT09PTIzNylpZigo
-YVt0KzFdJjIyNCk9PT0xNjApcmV0dXJuITAKcmV0dXJuITF9LApXSTpmdW5jdGlvbigpe3ZhciB0LHMK
-dHJ5e3Q9bmV3IFRleHREZWNvZGVyKCJ1dGYtOCIse2ZhdGFsOnRydWV9KQpyZXR1cm4gdH1jYXRjaChz
-KXtILlJ1KHMpfXJldHVybiBudWxsfSwKY1A6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0LHMscgpmb3IodD1K
-LlU2KGEpLHM9YjtzPGM7KytzKXtyPXQucShhLHMpCmlmKHR5cGVvZiByIT09Im51bWJlciIpcmV0dXJu
-IHIuek0oKQppZigociYxMjcpIT09cilyZXR1cm4gcy1ifXJldHVybiBjLWJ9LAp4TTpmdW5jdGlvbihh
-LGIsYyxkLGUsZil7aWYoQy5qbi56WShmLDQpIT09MCl0aHJvdyBILmIoUC5ycigiSW52YWxpZCBiYXNl
-NjQgcGFkZGluZywgcGFkZGVkIGxlbmd0aCBtdXN0IGJlIG11bHRpcGxlIG9mIGZvdXIsIGlzICIrZixh
-LGMpKQppZihkK2UhPT1mKXRocm93IEguYihQLnJyKCJJbnZhbGlkIGJhc2U2NCBwYWRkaW5nLCAnPScg
-bm90IGF0IHRoZSBlbmQiLGEsYikpCmlmKGU+Mil0aHJvdyBILmIoUC5ycigiSW52YWxpZCBiYXNlNjQg
-cGFkZGluZywgbW9yZSB0aGFuIHR3byAnPScgY2hhcmFjdGVycyIsYSxiKSl9LAp1dzpmdW5jdGlvbiB1
-dyhhLGIpe3RoaXMuYT1hCnRoaXMuYj1iCnRoaXMuYz1udWxsfSwKaTg6ZnVuY3Rpb24gaTgoYSl7dGhp
-cy5hPWF9LApDVjpmdW5jdGlvbiBDVigpe30sCnZBOmZ1bmN0aW9uIHZBKCl7fSwKVWs6ZnVuY3Rpb24g
-VWsoKXt9LAp3STpmdW5jdGlvbiB3SSgpe30sClppOmZ1bmN0aW9uIFppKCl7fSwKYnk6ZnVuY3Rpb24g
-YnkoKXt9LApNeDpmdW5jdGlvbiBNeChhKXt0aGlzLmE9YX0sCnU1OmZ1bmN0aW9uIHU1KCl7fSwKRTM6
-ZnVuY3Rpb24gRTMoKXt9LApSdzpmdW5jdGlvbiBSdyhhKXt0aGlzLmI9MAp0aGlzLmM9YX0sCkdZOmZ1
-bmN0aW9uIEdZKGEpe3RoaXMuYT1hfSwKYno6ZnVuY3Rpb24gYnooYSxiKXt2YXIgXz10aGlzCl8uYT1h
-Cl8uYj1iCl8uYz0hMApfLmY9Xy5lPV8uZD0wfSwKUUE6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0PUguSHAo
-YSxjKQppZih0IT1udWxsKXJldHVybiB0CmlmKGIhPW51bGwpcmV0dXJuIGIuJDEoYSkKdGhyb3cgSC5i
-KFAucnIoYSxudWxsLG51bGwpKX0sCkY6ZnVuY3Rpb24oYSl7aWYoYSBpbnN0YW5jZW9mIEguVHApcmV0
-dXJuIGEudygwKQpyZXR1cm4iSW5zdGFuY2Ugb2YgJyIrSC5kKEguTShhKSkrIicifSwKTzg6ZnVuY3Rp
-b24oYSxiLGMpe3ZhciB0LHM9Si5RaShhLGMpCmlmKGEhPT0wJiYhMClmb3IodD0wO3Q8cy5sZW5ndGg7
-Kyt0KUMuTm0uWShzLHQsYikKcmV0dXJuIHN9LApDSDpmdW5jdGlvbihhLGIsYyl7dmFyIHQscz1ILlZN
-KFtdLGMuQygiamQ8MD4iKSkKZm9yKHQ9Si5JVChhKTt0Lm0oKTspQy5ObS5BKHMsYy5iKHQuZ1IodCkp
-KQppZihiKXJldHVybiBzCnJldHVybiBjLkMoInpNPDA+IikuYihKLkVwKHMpKX0sCkFGOmZ1bmN0aW9u
-KGEsYil7cmV0dXJuIGIuQygiek08MD4iKS5iKEouekMoUC5DSChhLCExLGIpKSl9LApITTpmdW5jdGlv
-bihhLGIsYyl7dmFyIHQKaWYoQXJyYXkuaXNBcnJheShhKSl7dS50LmIoYSkKdD1hLmxlbmd0aApjPVAu
-akIoYixjLHQpCnJldHVybiBILmVUKGI+MHx8Yzx0P0MuTm0uRDYoYSxiLGMpOmEpfWlmKHUuYm0uYyhh
-KSlyZXR1cm4gSC5mdyhhLGIsUC5qQihiLGMsYS5sZW5ndGgpKQpyZXR1cm4gUC5idyhhLGIsYyl9LApP
-bzpmdW5jdGlvbihhKXtyZXR1cm4gSC5MdyhhKX0sCmJ3OmZ1bmN0aW9uKGEsYixjKXt2YXIgdCxzLHIs
-cSxwPW51bGwKaWYoYjwwKXRocm93IEguYihQLlRFKGIsMCxKLkhtKGEpLHAscCkpCnQ9Yz09bnVsbApp
-ZighdCYmYzxiKXRocm93IEguYihQLlRFKGMsYixKLkhtKGEpLHAscCkpCnM9Si5JVChhKQpmb3Iocj0w
-O3I8YjsrK3IpaWYoIXMubSgpKXRocm93IEguYihQLlRFKGIsMCxyLHAscCkpCnE9W10KaWYodClmb3Io
-O3MubSgpOylxLnB1c2gocy5nUihzKSkKZWxzZSBmb3Iocj1iO3I8YzsrK3Ipe2lmKCFzLm0oKSl0aHJv
-dyBILmIoUC5URShjLGIscixwLHApKQpxLnB1c2gocy5nUihzKSl9cmV0dXJuIEguZVQocSl9LApudTpm
-dW5jdGlvbihhKXtyZXR1cm4gbmV3IEguVlIoYSxILnY0KGEsITEsITAsITEsITEsITEpKX0sCnZnOmZ1
-bmN0aW9uKGEsYixjKXt2YXIgdD1KLklUKGIpCmlmKCF0Lm0oKSlyZXR1cm4gYQppZihjLmxlbmd0aD09
-PTApe2RvIGErPUguZCh0LmdSKHQpKQp3aGlsZSh0Lm0oKSl9ZWxzZXthKz1ILmQodC5nUih0KSkKZm9y
-KDt0Lm0oKTspYT1hK2MrSC5kKHQuZ1IodCkpfXJldHVybiBhfSwKbHI6ZnVuY3Rpb24oYSxiLGMsZCl7
-cmV0dXJuIG5ldyBQLm1wKGEsYixjLGQpfSwKdW86ZnVuY3Rpb24oKXt2YXIgdD1ILk0wKCkKaWYodCE9
-bnVsbClyZXR1cm4gUC5oSyh0KQp0aHJvdyBILmIoUC5MNCgiJ1VyaS5iYXNlJyBpcyBub3Qgc3VwcG9y
-dGVkIikpfSwKZVA6ZnVuY3Rpb24oYSxiLGMsZCl7dmFyIHQscyxyLHEscCxvLG49IjAxMjM0NTY3ODlB
-QkNERUYiCmlmKGM9PT1DLnhNKXt0PSQuejQoKS5iCmlmKHR5cGVvZiBiIT0ic3RyaW5nIilILlZqKEgu
-dEwoYikpCnQ9dC50ZXN0KGIpfWVsc2UgdD0hMQppZih0KXJldHVybiBiCkguTGgoYykuQygiVWsuUyIp
-LmIoYikKcz1jLmdaRSgpLldKKGIpCmZvcih0PXMubGVuZ3RoLHI9MCxxPSIiO3I8dDsrK3Ipe3A9c1ty
-XQppZihwPDEyOCl7bz1wPj4+NAppZihvPj04KXJldHVybiBILk9IKGEsbykKbz0oYVtvXSYxPDwocCYx
-NSkpIT09MH1lbHNlIG89ITEKaWYobylxKz1ILkx3KHApCmVsc2UgcT1kJiZwPT09MzI/cSsiKyI6cSsi
-JSIrbltwPj4+NCYxNV0rbltwJjE1XX1yZXR1cm4gcS5jaGFyQ29kZUF0KDApPT0wP3E6cX0sCkdxOmZ1
-bmN0aW9uKGEpe3ZhciB0PU1hdGguYWJzKGEpLHM9YTwwPyItIjoiIgppZih0Pj0xMDAwKXJldHVybiIi
-K2EKaWYodD49MTAwKXJldHVybiBzKyIwIit0CmlmKHQ+PTEwKXJldHVybiBzKyIwMCIrdApyZXR1cm4g
-cysiMDAwIit0fSwKVng6ZnVuY3Rpb24oYSl7aWYoYT49MTAwKXJldHVybiIiK2EKaWYoYT49MTApcmV0
-dXJuIjAiK2EKcmV0dXJuIjAwIithfSwKaDA6ZnVuY3Rpb24oYSl7aWYoYT49MTApcmV0dXJuIiIrYQpy
-ZXR1cm4iMCIrYX0sCnA6ZnVuY3Rpb24oYSl7aWYodHlwZW9mIGE9PSJudW1iZXIifHxILmwoYSl8fG51
-bGw9PWEpcmV0dXJuIEouaihhKQppZih0eXBlb2YgYT09InN0cmluZyIpcmV0dXJuIEpTT04uc3RyaW5n
-aWZ5KGEpCnJldHVybiBQLkYoYSl9LApoVjpmdW5jdGlvbihhKXtyZXR1cm4gbmV3IFAuQzYoYSl9LAp4
-WTpmdW5jdGlvbihhKXtyZXR1cm4gbmV3IFAudSghMSxudWxsLG51bGwsYSl9LApMMzpmdW5jdGlvbihh
-LGIsYyl7cmV0dXJuIG5ldyBQLnUoITAsYSxiLGMpfSwKRWU6ZnVuY3Rpb24oYSl7cmV0dXJuIG5ldyBQ
-LnUoITEsbnVsbCxhLCJNdXN0IG5vdCBiZSBudWxsIil9LAp4OmZ1bmN0aW9uKGEsYil7cmV0dXJuIG5l
-dyBQLmJKKG51bGwsbnVsbCwhMCxhLGIsIlZhbHVlIG5vdCBpbiByYW5nZSIpfSwKVEU6ZnVuY3Rpb24o
-YSxiLGMsZCxlKXtyZXR1cm4gbmV3IFAuYkooYixjLCEwLGEsZCwiSW52YWxpZCB2YWx1ZSIpfSwKd0E6
-ZnVuY3Rpb24oYSxiLGMsZCl7aWYoYTxifHxhPmMpdGhyb3cgSC5iKFAuVEUoYSxiLGMsZCxudWxsKSl9
-LApqQjpmdW5jdGlvbihhLGIsYyl7aWYoMD5hfHxhPmMpdGhyb3cgSC5iKFAuVEUoYSwwLGMsInN0YXJ0
-IixudWxsKSkKaWYoYiE9bnVsbCl7aWYoYT5ifHxiPmMpdGhyb3cgSC5iKFAuVEUoYixhLGMsImVuZCIs
-bnVsbCkpCnJldHVybiBifXJldHVybiBjfSwKazE6ZnVuY3Rpb24oYSxiKXtpZih0eXBlb2YgYSE9PSJu
-dW1iZXIiKXJldHVybiBhLkooKQppZihhPDApdGhyb3cgSC5iKFAuVEUoYSwwLG51bGwsYixudWxsKSl9
-LApDZjpmdW5jdGlvbihhLGIsYyxkLGUpe3ZhciB0PUguU2MoZT09bnVsbD9KLkhtKGIpOmUpCnJldHVy
-biBuZXcgUC5lWSh0LCEwLGEsYywiSW5kZXggb3V0IG9mIHJhbmdlIil9LApMNDpmdW5jdGlvbihhKXty
-ZXR1cm4gbmV3IFAudWIoYSl9LApTWTpmdW5jdGlvbihhKXtyZXR1cm4gbmV3IFAuZHMoYSl9LApQVjpm
-dW5jdGlvbihhKXtyZXR1cm4gbmV3IFAubGooYSl9LAphNDpmdW5jdGlvbihhKXtyZXR1cm4gbmV3IFAu
-VVYoYSl9LApycjpmdW5jdGlvbihhLGIsYyl7cmV0dXJuIG5ldyBQLmFFKGEsYixjKX0sCmRIOmZ1bmN0
-aW9uKGEsYixjLGQpe3ZhciB0LHM9SC5WTShbXSxkLkMoImpkPDA+IikpCkMuTm0uc2gocyxhKQpmb3Io
-dD0wO3Q8YTsrK3QpQy5ObS5ZKHMsdCxiLiQxKHQpKQpyZXR1cm4gc30sCmhLOmZ1bmN0aW9uKGEpe3Zh
-ciB0LHMscixxLHAsbyxuLG0sbCxrLGosaSxoLGcsZixlPW51bGwsZD1hLmxlbmd0aAppZihkPj01KXt0
-PSgoSi5ReihhLDQpXjU4KSozfEMueEIuV2QoYSwwKV4xMDB8Qy54Qi5XZChhLDEpXjk3fEMueEIuV2Qo
-YSwyKV4xMTZ8Qy54Qi5XZChhLDMpXjk3KT4+PjAKaWYodD09PTApcmV0dXJuIFAuS0QoZDxkP0MueEIu
-TmooYSwwLGQpOmEsNSxlKS5nbFIoKQplbHNlIGlmKHQ9PT0zMilyZXR1cm4gUC5LRChDLnhCLk5qKGEs
-NSxkKSwwLGUpLmdsUigpfXM9bmV3IEFycmF5KDgpCnMuZml4ZWQkbGVuZ3RoPUFycmF5CnI9SC5WTShz
-LHUudCkKQy5ObS5ZKHIsMCwwKQpDLk5tLlkociwxLC0xKQpDLk5tLlkociwyLC0xKQpDLk5tLlkociw3
-LC0xKQpDLk5tLlkociwzLDApCkMuTm0uWShyLDQsMCkKQy5ObS5ZKHIsNSxkKQpDLk5tLlkociw2LGQp
-CmlmKFAuVUIoYSwwLGQsMCxyKT49MTQpQy5ObS5ZKHIsNyxkKQpxPXJbMV0KaWYodHlwZW9mIHEhPT0i
-bnVtYmVyIilyZXR1cm4gcS50QigpCmlmKHE+PTApaWYoUC5VQihhLDAscSwyMCxyKT09PTIwKXJbN109
-cQpzPXJbMl0KaWYodHlwZW9mIHMhPT0ibnVtYmVyIilyZXR1cm4gcy5UKCkKcD1zKzEKbz1yWzNdCm49
-cls0XQptPXJbNV0KbD1yWzZdCmlmKHR5cGVvZiBsIT09Im51bWJlciIpcmV0dXJuIGwuSigpCmlmKHR5
-cGVvZiBtIT09Im51bWJlciIpcmV0dXJuIEgucFkobSkKaWYobDxtKW09bAppZih0eXBlb2YgbiE9PSJu
-dW1iZXIiKXJldHVybiBuLkooKQppZihuPHApbj1tCmVsc2UgaWYobjw9cSluPXErMQppZih0eXBlb2Yg
-byE9PSJudW1iZXIiKXJldHVybiBvLkooKQppZihvPHApbz1uCnM9cls3XQppZih0eXBlb2YgcyE9PSJu
-dW1iZXIiKXJldHVybiBzLkooKQprPXM8MAppZihrKWlmKHA+cSszKXtqPWUKaz0hMX1lbHNle3M9bz4w
-CmlmKHMmJm8rMT09PW4pe2o9ZQprPSExfWVsc2V7aWYoIShtPGQmJm09PT1uKzImJkoucTAoYSwiLi4i
-LG4pKSlpPW0+bisyJiZKLnEwKGEsIi8uLiIsbS0zKQplbHNlIGk9ITAKaWYoaSl7aj1lCms9ITF9ZWxz
-ZXtpZihxPT09NClpZihKLnEwKGEsImZpbGUiLDApKXtpZihwPD0wKXtpZighQy54Qi5RaShhLCIvIixu
-KSl7aD0iZmlsZTovLy8iCnQ9M31lbHNle2g9ImZpbGU6Ly8iCnQ9Mn1hPWgrQy54Qi5OaihhLG4sZCkK
-cS09MApzPXQtMAptKz1zCmwrPXMKZD1hLmxlbmd0aApwPTcKbz03Cm49N31lbHNlIGlmKG49PT1tKXtn
-PW0rMTsrK2wKYT1DLnhCLmk3KGEsbixtLCIvIik7KytkCm09Z31qPSJmaWxlIn1lbHNlIGlmKEMueEIu
-UWkoYSwiaHR0cCIsMCkpe2lmKHMmJm8rMz09PW4mJkMueEIuUWkoYSwiODAiLG8rMSkpe2Y9bi0zCm0t
-PTMKbC09MwphPUMueEIuaTcoYSxvLG4sIiIpCmQtPTMKbj1mfWo9Imh0dHAifWVsc2Ugaj1lCmVsc2Ug
-aWYocT09PTUmJkoucTAoYSwiaHR0cHMiLDApKXtpZihzJiZvKzQ9PT1uJiZKLnEwKGEsIjQ0MyIsbysx
-KSl7Zj1uLTQKbS09NApsLT00CmE9Si5kZyhhLG8sbiwiIikKZC09MwpuPWZ9aj0iaHR0cHMifWVsc2Ug
-aj1lCms9ITB9fX1lbHNlIGo9ZQppZihrKXtzPWEubGVuZ3RoCmlmKGQ8cyl7YT1KLmxkKGEsMCxkKQpx
-LT0wCnAtPTAKby09MApuLT0wCm0tPTAKbC09MH1yZXR1cm4gbmV3IFAuVWYoYSxxLHAsbyxuLG0sbCxq
-KX1yZXR1cm4gUC5qdihhLDAsZCxxLHAsbyxuLG0sbCxqKX0sCk10OmZ1bmN0aW9uKGEpe0gueShhKQpy
-ZXR1cm4gUC5rdShhLDAsYS5sZW5ndGgsQy54TSwhMSl9LApXWDpmdW5jdGlvbihhKXt2YXIgdD11Lk4K
-cmV0dXJuIEMuTm0uTjAoSC5WTShhLnNwbGl0KCImIiksdS5zKSxQLkZsKHQsdCksbmV3IFAubjEoQy54
-TSksdS5mKX0sCkhoOmZ1bmN0aW9uKGEsYixjKXt2YXIgdCxzLHIscSxwLG8sbixtPW51bGwsbD0iSVB2
-NCBhZGRyZXNzIHNob3VsZCBjb250YWluIGV4YWN0bHkgNCBwYXJ0cyIsaz0iZWFjaCBwYXJ0IG11c3Qg
-YmUgaW4gdGhlIHJhbmdlIDAuLjI1NSIsaj1uZXcgUC5jUyhhKSxpPW5ldyBVaW50OEFycmF5KDQpCmZv
-cih0PWkubGVuZ3RoLHM9YixyPXMscT0wO3M8YzsrK3Mpe3A9Qy54Qi5PMihhLHMpCmlmKHAhPT00Nil7
-aWYoKHBeNDgpPjkpai4kMigiaW52YWxpZCBjaGFyYWN0ZXIiLHMpfWVsc2V7aWYocT09PTMpai4kMihs
-LHMpCm89UC5RQShDLnhCLk5qKGEscixzKSxtLG0pCmlmKHR5cGVvZiBvIT09Im51bWJlciIpcmV0dXJu
-IG8ub3MoKQppZihvPjI1NSlqLiQyKGsscikKbj1xKzEKaWYocT49dClyZXR1cm4gSC5PSChpLHEpCmlb
-cV09bwpyPXMrMQpxPW59fWlmKHEhPT0zKWouJDIobCxjKQpvPVAuUUEoQy54Qi5OaihhLHIsYyksbSxt
-KQppZih0eXBlb2YgbyE9PSJudW1iZXIiKXJldHVybiBvLm9zKCkKaWYobz4yNTUpai4kMihrLHIpCmlm
-KHE+PXQpcmV0dXJuIEguT0goaSxxKQppW3FdPW8KcmV0dXJuIGl9LAplZzpmdW5jdGlvbihhLGIsYTAp
-e3ZhciB0LHMscixxLHAsbyxuLG0sbCxrLGosaSxoLGcsZixlLGQ9bmV3IFAuVkMoYSksYz1uZXcgUC5K
-VChkLGEpCmlmKGEubGVuZ3RoPDIpZC4kMSgiYWRkcmVzcyBpcyB0b28gc2hvcnQiKQp0PUguVk0oW10s
-dS50KQpmb3Iocz1iLHI9cyxxPSExLHA9ITE7czxhMDsrK3Mpe289Qy54Qi5PMihhLHMpCmlmKG89PT01
-OCl7aWYocz09PWIpeysrcwppZihDLnhCLk8yKGEscykhPT01OClkLiQyKCJpbnZhbGlkIHN0YXJ0IGNv
-bG9uLiIscykKcj1zfWlmKHM9PT1yKXtpZihxKWQuJDIoIm9ubHkgb25lIHdpbGRjYXJkIGA6OmAgaXMg
-YWxsb3dlZCIscykKQy5ObS5BKHQsLTEpCnE9ITB9ZWxzZSBDLk5tLkEodCxjLiQyKHIscykpCnI9cysx
-fWVsc2UgaWYobz09PTQ2KXA9ITB9aWYodC5sZW5ndGg9PT0wKWQuJDEoInRvbyBmZXcgcGFydHMiKQpu
-PXI9PT1hMAptPUMuTm0uZ3JaKHQpCmlmKG4mJm0hPT0tMSlkLiQyKCJleHBlY3RlZCBhIHBhcnQgYWZ0
-ZXIgbGFzdCBgOmAiLGEwKQppZighbilpZighcClDLk5tLkEodCxjLiQyKHIsYTApKQplbHNle2w9UC5I
-aChhLHIsYTApCkMuTm0uQSh0LChsWzBdPDw4fGxbMV0pPj4+MCkKQy5ObS5BKHQsKGxbMl08PDh8bFsz
-XSk+Pj4wKX1pZihxKXtpZih0Lmxlbmd0aD43KWQuJDEoImFuIGFkZHJlc3Mgd2l0aCBhIHdpbGRjYXJk
-IG11c3QgaGF2ZSBsZXNzIHRoYW4gNyBwYXJ0cyIpfWVsc2UgaWYodC5sZW5ndGghPT04KWQuJDEoImFu
-IGFkZHJlc3Mgd2l0aG91dCBhIHdpbGRjYXJkIG11c3QgY29udGFpbiBleGFjdGx5IDggcGFydHMiKQpr
-PW5ldyBVaW50OEFycmF5KDE2KQpmb3IobT10Lmxlbmd0aCxqPWsubGVuZ3RoLGk9OS1tLHM9MCxoPTA7
-czxtOysrcyl7Zz10W3NdCmlmKGc9PT0tMSlmb3IoZj0wO2Y8aTsrK2Ype2lmKGg8MHx8aD49ailyZXR1
-cm4gSC5PSChrLGgpCmtbaF09MAplPWgrMQppZihlPj1qKXJldHVybiBILk9IKGssZSkKa1tlXT0wCmgr
-PTJ9ZWxzZXtlPUMuam4ud0coZyw4KQppZihoPDB8fGg+PWopcmV0dXJuIEguT0goayxoKQprW2hdPWUK
-ZT1oKzEKaWYoZT49ailyZXR1cm4gSC5PSChrLGUpCmtbZV09ZyYyNTUKaCs9Mn19cmV0dXJuIGt9LApq
-djpmdW5jdGlvbihhLGIsYyxkLGUsZixnLGgsaSxqKXt2YXIgdCxzLHIscSxwLG8sbixtPW51bGwKaWYo
-aj09bnVsbClpZihkPmIpaj1QLlBpKGEsYixkKQplbHNle2lmKGQ9PT1iKVAuUjMoYSxiLCJJbnZhbGlk
-IGVtcHR5IHNjaGVtZSIpCmo9IiJ9aWYoZT5iKXt0PWQrMwpzPXQ8ZT9QLnpSKGEsdCxlLTEpOiIiCnI9
-UC5PZShhLGUsZiwhMSkKaWYodHlwZW9mIGYhPT0ibnVtYmVyIilyZXR1cm4gZi5UKCkKcT1mKzEKaWYo
-dHlwZW9mIGchPT0ibnVtYmVyIilyZXR1cm4gSC5wWShnKQpwPXE8Zz9QLndCKFAuUUEoSi5sZChhLHEs
-ZyksbmV3IFAuZTEoYSxmKSxtKSxqKTptfWVsc2V7cD1tCnI9cApzPSIifW89UC5rYShhLGcsaCxtLGos
-ciE9bnVsbCkKaWYodHlwZW9mIGghPT0ibnVtYmVyIilyZXR1cm4gaC5KKCkKbj1oPGk/UC5sZShhLGgr
-MSxpLG0pOm0KcmV0dXJuIG5ldyBQLkRuKGoscyxyLHAsbyxuLGk8Yz9QLnRHKGEsaSsxLGMpOm0pfSwK
-d0s6ZnVuY3Rpb24oYSl7aWYoYT09PSJodHRwIilyZXR1cm4gODAKaWYoYT09PSJodHRwcyIpcmV0dXJu
-IDQ0MwpyZXR1cm4gMH0sClIzOmZ1bmN0aW9uKGEsYixjKXt0aHJvdyBILmIoUC5ycihjLGEsYikpfSwK
-a0U6ZnVuY3Rpb24oYSxiKXtDLk5tLlUoYSxuZXcgUC5OWSghMSkpfSwKSE46ZnVuY3Rpb24oYSxiLGMp
-e3ZhciB0LHMscgpmb3IodD1ILnFDKGEsYyxudWxsLEgudDYoYSkuZCksdD1uZXcgSC5hNyh0LHQuZ2go
-dCksdC4kdGkuQygiYTc8YUwuRT4iKSk7dC5tKCk7KXtzPXQuZApyPVAubnUoJ1siKi86PD4/XFxcXHxd
-JykKcy50b1N0cmluZwppZihILm0yKHMsciwwKSl7dD1QLkw0KCJJbGxlZ2FsIGNoYXJhY3RlciBpbiBw
-YXRoOiAiK3MpCnRocm93IEguYih0KX19fSwKcmc6ZnVuY3Rpb24oYSxiKXt2YXIgdAppZighKDY1PD1h
-JiZhPD05MCkpdD05Nzw9YSYmYTw9MTIyCmVsc2UgdD0hMAppZih0KXJldHVybgp0PVAuTDQoIklsbGVn
-YWwgZHJpdmUgbGV0dGVyICIrUC5PbyhhKSkKdGhyb3cgSC5iKHQpfSwKd0I6ZnVuY3Rpb24oYSxiKXtp
-ZihhIT1udWxsJiZhPT09UC53SyhiKSlyZXR1cm4gbnVsbApyZXR1cm4gYX0sCk9lOmZ1bmN0aW9uKGEs
-YixjLGQpe3ZhciB0LHMscixxLHAsbwppZihhPT1udWxsKXJldHVybiBudWxsCmlmKGI9PT1jKXJldHVy
-biIiCmlmKEMueEIuTzIoYSxiKT09PTkxKXtpZih0eXBlb2YgYyE9PSJudW1iZXIiKXJldHVybiBjLkhO
-KCkKdD1jLTEKaWYoQy54Qi5PMihhLHQpIT09OTMpUC5SMyhhLGIsIk1pc3NpbmcgZW5kIGBdYCB0byBt
-YXRjaCBgW2AgaW4gaG9zdCIpCnM9YisxCnI9UC50byhhLHMsdCkKaWYodHlwZW9mIHIhPT0ibnVtYmVy
-IilyZXR1cm4gci5KKCkKaWYocjx0KXtxPXIrMQpwPVAuT0EoYSxDLnhCLlFpKGEsIjI1IixxKT9yKzM6
-cSx0LCIlMjUiKX1lbHNlIHA9IiIKUC5lZyhhLHMscikKcmV0dXJuIEMueEIuTmooYSxiLHIpLnRvTG93
-ZXJDYXNlKCkrcCsiXSJ9aWYodHlwZW9mIGMhPT0ibnVtYmVyIilyZXR1cm4gSC5wWShjKQpvPWIKZm9y
-KDtvPGM7KytvKWlmKEMueEIuTzIoYSxvKT09PTU4KXtyPUMueEIuWFUoYSwiJSIsYikKaWYoIShyPj1i
-JiZyPGMpKXI9YwppZihyPGMpe3E9cisxCnA9UC5PQShhLEMueEIuUWkoYSwiMjUiLHEpP3IrMzpxLGMs
-IiUyNSIpfWVsc2UgcD0iIgpQLmVnKGEsYixyKQpyZXR1cm4iWyIrQy54Qi5OaihhLGIscikrcCsiXSJ9
-cmV0dXJuIFAuT0woYSxiLGMpfSwKdG86ZnVuY3Rpb24oYSxiLGMpe3ZhciB0LHM9Qy54Qi5YVShhLCIl
-IixiKQppZihzPj1iKXtpZih0eXBlb2YgYyE9PSJudW1iZXIiKXJldHVybiBILnBZKGMpCnQ9czxjfWVs
-c2UgdD0hMQpyZXR1cm4gdD9zOmN9LApPQTpmdW5jdGlvbihhLGIsYyxkKXt2YXIgdCxzLHIscSxwLG8s
-bixtLGwsaz1kIT09IiI/bmV3IFAuUm4oZCk6bnVsbAppZih0eXBlb2YgYyE9PSJudW1iZXIiKXJldHVy
-biBILnBZKGMpCnQ9YgpzPXQKcj0hMApmb3IoO3Q8Yzspe3E9Qy54Qi5PMihhLHQpCmlmKHE9PT0zNyl7
-cD1QLnJ2KGEsdCwhMCkKbz1wPT1udWxsCmlmKG8mJnIpe3QrPTMKY29udGludWV9aWYoaz09bnVsbClr
-PW5ldyBQLlJuKCIiKQpuPWsuYSs9Qy54Qi5OaihhLHMsdCkKaWYobylwPUMueEIuTmooYSx0LHQrMykK
-ZWxzZSBpZihwPT09IiUiKVAuUjMoYSx0LCJab25lSUQgc2hvdWxkIG5vdCBjb250YWluICUgYW55bW9y
-ZSIpCmsuYT1uK3AKdCs9MwpzPXQKcj0hMH1lbHNle2lmKHE8MTI3KXtvPXE+Pj40CmlmKG8+PTgpcmV0
-dXJuIEguT0goQy5GMyxvKQpvPShDLkYzW29dJjE8PChxJjE1KSkhPT0wfWVsc2Ugbz0hMQppZihvKXtp
-ZihyJiY2NTw9cSYmOTA+PXEpe2lmKGs9PW51bGwpaz1uZXcgUC5SbigiIikKaWYoczx0KXtrLmErPUMu
-eEIuTmooYSxzLHQpCnM9dH1yPSExfSsrdH1lbHNle2lmKChxJjY0NTEyKT09PTU1Mjk2JiZ0KzE8Yyl7
-bT1DLnhCLk8yKGEsdCsxKQppZigobSY2NDUxMik9PT01NjMyMCl7cT02NTUzNnwocSYxMDIzKTw8MTB8
-bSYxMDIzCmw9Mn1lbHNlIGw9MX1lbHNlIGw9MQppZihrPT1udWxsKWs9bmV3IFAuUm4oIiIpCmsuYSs9
-Qy54Qi5OaihhLHMsdCkKay5hKz1QLkhIKHEpCnQrPWwKcz10fX19aWYoaz09bnVsbClyZXR1cm4gQy54
-Qi5OaihhLGIsYykKaWYoczxjKWsuYSs9Qy54Qi5OaihhLHMsYykKbz1rLmEKcmV0dXJuIG8uY2hhckNv
-ZGVBdCgwKT09MD9vOm99LApPTDpmdW5jdGlvbihhLGIsYyl7dmFyIHQscyxyLHEscCxvLG4sbSxsLGss
-agppZih0eXBlb2YgYyE9PSJudW1iZXIiKXJldHVybiBILnBZKGMpCnQ9YgpzPXQKcj1udWxsCnE9ITAK
-Zm9yKDt0PGM7KXtwPUMueEIuTzIoYSx0KQppZihwPT09Mzcpe289UC5ydihhLHQsITApCm49bz09bnVs
-bAppZihuJiZxKXt0Kz0zCmNvbnRpbnVlfWlmKHI9PW51bGwpcj1uZXcgUC5SbigiIikKbT1DLnhCLk5q
-KGEscyx0KQpsPXIuYSs9IXE/bS50b0xvd2VyQ2FzZSgpOm0KaWYobil7bz1DLnhCLk5qKGEsdCx0KzMp
-Cms9M31lbHNlIGlmKG89PT0iJSIpe289IiUyNSIKaz0xfWVsc2Ugaz0zCnIuYT1sK28KdCs9awpzPXQK
-cT0hMH1lbHNle2lmKHA8MTI3KXtuPXA+Pj40CmlmKG4+PTgpcmV0dXJuIEguT0goQy5lYSxuKQpuPShD
-LmVhW25dJjE8PChwJjE1KSkhPT0wfWVsc2Ugbj0hMQppZihuKXtpZihxJiY2NTw9cCYmOTA+PXApe2lm
-KHI9PW51bGwpcj1uZXcgUC5SbigiIikKaWYoczx0KXtyLmErPUMueEIuTmooYSxzLHQpCnM9dH1xPSEx
-fSsrdH1lbHNle2lmKHA8PTkzKXtuPXA+Pj40CmlmKG4+PTgpcmV0dXJuIEguT0goQy5hayxuKQpuPShD
-LmFrW25dJjE8PChwJjE1KSkhPT0wfWVsc2Ugbj0hMQppZihuKVAuUjMoYSx0LCJJbnZhbGlkIGNoYXJh
-Y3RlciIpCmVsc2V7aWYoKHAmNjQ1MTIpPT09NTUyOTYmJnQrMTxjKXtqPUMueEIuTzIoYSx0KzEpCmlm
-KChqJjY0NTEyKT09PTU2MzIwKXtwPTY1NTM2fChwJjEwMjMpPDwxMHxqJjEwMjMKaz0yfWVsc2Ugaz0x
-fWVsc2Ugaz0xCmlmKHI9PW51bGwpcj1uZXcgUC5SbigiIikKbT1DLnhCLk5qKGEscyx0KQpyLmErPSFx
-P20udG9Mb3dlckNhc2UoKTptCnIuYSs9UC5ISChwKQp0Kz1rCnM9dH19fX1pZihyPT1udWxsKXJldHVy
-biBDLnhCLk5qKGEsYixjKQppZihzPGMpe209Qy54Qi5OaihhLHMsYykKci5hKz0hcT9tLnRvTG93ZXJD
-YXNlKCk6bX1uPXIuYQpyZXR1cm4gbi5jaGFyQ29kZUF0KDApPT0wP246bn0sClBpOmZ1bmN0aW9uKGEs
-YixjKXt2YXIgdCxzLHIscQppZihiPT09YylyZXR1cm4iIgppZighUC5FdChKLnJZKGEpLldkKGEsYikp
-KVAuUjMoYSxiLCJTY2hlbWUgbm90IHN0YXJ0aW5nIHdpdGggYWxwaGFiZXRpYyBjaGFyYWN0ZXIiKQpm
-b3IodD1iLHM9ITE7dDxjOysrdCl7cj1DLnhCLldkKGEsdCkKaWYocjwxMjgpe3E9cj4+PjQKaWYocT49
-OClyZXR1cm4gSC5PSChDLm1LLHEpCnE9KEMubUtbcV0mMTw8KHImMTUpKSE9PTB9ZWxzZSBxPSExCmlm
-KCFxKVAuUjMoYSx0LCJJbGxlZ2FsIHNjaGVtZSBjaGFyYWN0ZXIiKQppZig2NTw9ciYmcjw9OTApcz0h
-MH1hPUMueEIuTmooYSxiLGMpCnJldHVybiBQLllhKHM/YS50b0xvd2VyQ2FzZSgpOmEpfSwKWWE6ZnVu
-Y3Rpb24oYSl7aWYoYT09PSJodHRwIilyZXR1cm4iaHR0cCIKaWYoYT09PSJmaWxlIilyZXR1cm4iZmls
-ZSIKaWYoYT09PSJodHRwcyIpcmV0dXJuImh0dHBzIgppZihhPT09InBhY2thZ2UiKXJldHVybiJwYWNr
-YWdlIgpyZXR1cm4gYX0sCnpSOmZ1bmN0aW9uKGEsYixjKXtpZihhPT1udWxsKXJldHVybiIiCnJldHVy
-biBQLnVPKGEsYixjLEMudG8sITEpfSwKa2E6ZnVuY3Rpb24oYSxiLGMsZCxlLGYpe3ZhciB0LHM9ZT09
-PSJmaWxlIixyPXN8fGYscT1hPT1udWxsCmlmKHEmJiEwKXJldHVybiBzPyIvIjoiIgp0PSFxP1AudU8o
-YSxiLGMsQy5XZCwhMCk6Qy5qTi5FMihkLG5ldyBQLlJaKCksdS5OKS56VigwLCIvIikKaWYodC5sZW5n
-dGg9PT0wKXtpZihzKXJldHVybiIvIn1lbHNlIGlmKHImJiFDLnhCLm5DKHQsIi8iKSl0PSIvIit0CnJl
-dHVybiBQLkpyKHQsZSxmKX0sCkpyOmZ1bmN0aW9uKGEsYixjKXt2YXIgdD1iLmxlbmd0aD09PTAKaWYo
-dCYmIWMmJiFDLnhCLm5DKGEsIi8iKSlyZXR1cm4gUC53RihhLCF0fHxjKQpyZXR1cm4gUC54ZShhKX0s
-CmxlOmZ1bmN0aW9uKGEsYixjLGQpe3ZhciB0LHM9e30KaWYoYSE9bnVsbCl7aWYoZCE9bnVsbCl0aHJv
-dyBILmIoUC54WSgiQm90aCBxdWVyeSBhbmQgcXVlcnlQYXJhbWV0ZXJzIHNwZWNpZmllZCIpKQpyZXR1
-cm4gUC51TyhhLGIsYyxDLlZDLCEwKX1pZihkPT1udWxsKXJldHVybiBudWxsCnQ9bmV3IFAuUm4oIiIp
-CnMuYT0iIgpkLlUoMCxuZXcgUC55NShuZXcgUC5NRShzLHQpKSkKcz10LmEKcmV0dXJuIHMuY2hhckNv
-ZGVBdCgwKT09MD9zOnN9LAp0RzpmdW5jdGlvbihhLGIsYyl7aWYoYT09bnVsbClyZXR1cm4gbnVsbApy
-ZXR1cm4gUC51TyhhLGIsYyxDLlZDLCEwKX0sCnJ2OmZ1bmN0aW9uKGEsYixjKXt2YXIgdCxzLHIscSxw
-LG89YisyCmlmKG8+PWEubGVuZ3RoKXJldHVybiIlIgp0PUMueEIuTzIoYSxiKzEpCnM9Qy54Qi5PMihh
-LG8pCnI9SC5vbyh0KQpxPUgub28ocykKaWYocjwwfHxxPDApcmV0dXJuIiUiCnA9cioxNitxCmlmKHA8
-MTI3KXtvPUMuam4ud0cocCw0KQppZihvPj04KXJldHVybiBILk9IKEMuRjMsbykKbz0oQy5GM1tvXSYx
-PDwocCYxNSkpIT09MH1lbHNlIG89ITEKaWYobylyZXR1cm4gSC5MdyhjJiY2NTw9cCYmOTA+PXA/KHB8
-MzIpPj4+MDpwKQppZih0Pj05N3x8cz49OTcpcmV0dXJuIEMueEIuTmooYSxiLGIrMykudG9VcHBlckNh
-c2UoKQpyZXR1cm4gbnVsbH0sCkhIOmZ1bmN0aW9uKGEpe3ZhciB0LHMscixxLHAsbyxuPSIwMTIzNDU2
-Nzg5QUJDREVGIgppZihhPDEyOCl7dD1uZXcgQXJyYXkoMykKdC5maXhlZCRsZW5ndGg9QXJyYXkKcz1I
-LlZNKHQsdS50KQpDLk5tLlkocywwLDM3KQpDLk5tLlkocywxLEMueEIuV2QobixhPj4+NCkpCkMuTm0u
-WShzLDIsQy54Qi5XZChuLGEmMTUpKX1lbHNle2lmKGE+MjA0NylpZihhPjY1NTM1KXtyPTI0MApxPTR9
-ZWxzZXtyPTIyNApxPTN9ZWxzZXtyPTE5MgpxPTJ9dD1uZXcgQXJyYXkoMypxKQp0LmZpeGVkJGxlbmd0
-aD1BcnJheQpzPUguVk0odCx1LnQpCmZvcihwPTA7LS1xLHE+PTA7cj0xMjgpe289Qy5qbi5iZihhLDYq
-cSkmNjN8cgpDLk5tLlkocyxwLDM3KQpDLk5tLlkocyxwKzEsQy54Qi5XZChuLG8+Pj40KSkKQy5ObS5Z
-KHMscCsyLEMueEIuV2QobixvJjE1KSkKcCs9M319cmV0dXJuIFAuSE0ocywwLG51bGwpfSwKdU86ZnVu
-Y3Rpb24oYSxiLGMsZCxlKXt2YXIgdD1QLlVsKGEsYixjLGQsZSkKcmV0dXJuIHQ9PW51bGw/Qy54Qi5O
-aihhLGIsYyk6dH0sClVsOmZ1bmN0aW9uKGEsYixjLGQsZSl7dmFyIHQscyxyLHEscCxvPW51bGwsbj0h
-ZSxtPWIsbD1tLGs9bwp3aGlsZSghMCl7aWYodHlwZW9mIG0hPT0ibnVtYmVyIilyZXR1cm4gbS5KKCkK
-aWYodHlwZW9mIGMhPT0ibnVtYmVyIilyZXR1cm4gSC5wWShjKQppZighKG08YykpYnJlYWsKYyQwOnt0
-PUMueEIuTzIoYSxtKQppZih0PDEyNyl7cz10Pj4+NAppZihzPj04KXJldHVybiBILk9IKGQscykKcz0o
-ZFtzXSYxPDwodCYxNSkpIT09MH1lbHNlIHM9ITEKaWYocykrK20KZWxzZXtpZih0PT09Mzcpe3I9UC5y
-dihhLG0sITEpCmlmKHI9PW51bGwpe20rPTMKYnJlYWsgYyQwfWlmKCIlIj09PXIpe3I9IiUyNSIKcT0x
-fWVsc2UgcT0zfWVsc2V7aWYobilpZih0PD05Myl7cz10Pj4+NAppZihzPj04KXJldHVybiBILk9IKEMu
-YWsscykKcz0oQy5ha1tzXSYxPDwodCYxNSkpIT09MH1lbHNlIHM9ITEKZWxzZSBzPSExCmlmKHMpe1Au
-UjMoYSxtLCJJbnZhbGlkIGNoYXJhY3RlciIpCnE9bwpyPXF9ZWxzZXtpZigodCY2NDUxMik9PT01NTI5
-Nil7cz1tKzEKaWYoczxjKXtwPUMueEIuTzIoYSxzKQppZigocCY2NDUxMik9PT01NjMyMCl7dD02NTUz
-NnwodCYxMDIzKTw8MTB8cCYxMDIzCnE9Mn1lbHNlIHE9MX1lbHNlIHE9MX1lbHNlIHE9MQpyPVAuSEgo
-dCl9fWlmKGs9PW51bGwpaz1uZXcgUC5SbigiIikKay5hKz1DLnhCLk5qKGEsbCxtKQprLmErPUguZChy
-KQppZih0eXBlb2YgcSE9PSJudW1iZXIiKXJldHVybiBILnBZKHEpCm0rPXEKbD1tfX19aWYoaz09bnVs
-bClyZXR1cm4gbwppZih0eXBlb2YgbCE9PSJudW1iZXIiKXJldHVybiBsLkooKQppZihsPGMpay5hKz1D
-LnhCLk5qKGEsbCxjKQpuPWsuYQpyZXR1cm4gbi5jaGFyQ29kZUF0KDApPT0wP246bn0sCnlCOmZ1bmN0
-aW9uKGEpe2lmKEMueEIubkMoYSwiLiIpKXJldHVybiEwCnJldHVybiBDLnhCLk9ZKGEsIi8uIikhPT0t
-MX0sCnhlOmZ1bmN0aW9uKGEpe3ZhciB0LHMscixxLHAsbyxuCmlmKCFQLnlCKGEpKXJldHVybiBhCnQ9
-SC5WTShbXSx1LnMpCmZvcihzPWEuc3BsaXQoIi8iKSxyPXMubGVuZ3RoLHE9ITEscD0wO3A8cjsrK3Ap
-e289c1twXQppZihKLlJNKG8sIi4uIikpe249dC5sZW5ndGgKaWYobiE9PTApe2lmKDA+PW4pcmV0dXJu
-IEguT0godCwtMSkKdC5wb3AoKQppZih0Lmxlbmd0aD09PTApQy5ObS5BKHQsIiIpfXE9ITB9ZWxzZSBp
-ZigiLiI9PT1vKXE9ITAKZWxzZXtDLk5tLkEodCxvKQpxPSExfX1pZihxKUMuTm0uQSh0LCIiKQpyZXR1
-cm4gQy5ObS56Vih0LCIvIil9LAp3RjpmdW5jdGlvbihhLGIpe3ZhciB0LHMscixxLHAsbwppZighUC55
-QihhKSlyZXR1cm4hYj9QLkMxKGEpOmEKdD1ILlZNKFtdLHUucykKZm9yKHM9YS5zcGxpdCgiLyIpLHI9
-cy5sZW5ndGgscT0hMSxwPTA7cDxyOysrcCl7bz1zW3BdCmlmKCIuLiI9PT1vKWlmKHQubGVuZ3RoIT09
-MCYmQy5ObS5ncloodCkhPT0iLi4iKXtpZigwPj10Lmxlbmd0aClyZXR1cm4gSC5PSCh0LC0xKQp0LnBv
-cCgpCnE9ITB9ZWxzZXtDLk5tLkEodCwiLi4iKQpxPSExfWVsc2UgaWYoIi4iPT09bylxPSEwCmVsc2V7
-Qy5ObS5BKHQsbykKcT0hMX19cz10Lmxlbmd0aAppZihzIT09MClpZihzPT09MSl7aWYoMD49cylyZXR1
-cm4gSC5PSCh0LDApCnM9dFswXS5sZW5ndGg9PT0wfWVsc2Ugcz0hMQplbHNlIHM9ITAKaWYocylyZXR1
-cm4iLi8iCmlmKHF8fEMuTm0uZ3JaKHQpPT09Ii4uIilDLk5tLkEodCwiIikKaWYoIWIpe2lmKDA+PXQu
-bGVuZ3RoKXJldHVybiBILk9IKHQsMCkKQy5ObS5ZKHQsMCxQLkMxKHRbMF0pKX1yZXR1cm4gQy5ObS56
-Vih0LCIvIil9LApDMTpmdW5jdGlvbihhKXt2YXIgdCxzLHIscT1hLmxlbmd0aAppZihxPj0yJiZQLkV0
-KEouUXooYSwwKSkpZm9yKHQ9MTt0PHE7Kyt0KXtzPUMueEIuV2QoYSx0KQppZihzPT09NTgpcmV0dXJu
-IEMueEIuTmooYSwwLHQpKyIlM0EiK0MueEIueW4oYSx0KzEpCmlmKHM8PTEyNyl7cj1zPj4+NAppZihy
-Pj04KXJldHVybiBILk9IKEMubUsscikKcj0oQy5tS1tyXSYxPDwocyYxNSkpPT09MH1lbHNlIHI9ITAK
-aWYocilicmVha31yZXR1cm4gYX0sCm1uOmZ1bmN0aW9uKGEpe3ZhciB0LHMscixxPWEuZ0ZqKCkscD1x
-Lmxlbmd0aAppZihwPjAmJkouSG0ocVswXSk9PT0yJiZKLmE2KHFbMF0sMSk9PT01OCl7aWYoMD49cCly
-ZXR1cm4gSC5PSChxLDApClAucmcoSi5hNihxWzBdLDApLCExKQpQLkhOKHEsITEsMSkKdD0hMH1lbHNl
-e1AuSE4ocSwhMSwwKQp0PSExfXM9YS5ndFQoKSYmIXQ/IlxcIjoiIgppZihhLmdjaigpKXtyPWEuZ0pm
-KGEpCmlmKHIubGVuZ3RoIT09MClzPXMrIlxcIityKyJcXCJ9cz1QLnZnKHMscSwiXFwiKQpwPXQmJnA9
-PT0xP3MrIlxcIjpzCnJldHVybiBwLmNoYXJDb2RlQXQoMCk9PTA/cDpwfSwKSWg6ZnVuY3Rpb24oYSxi
-KXt2YXIgdCxzLHIKZm9yKHQ9MCxzPTA7czwyOysrcyl7cj1DLnhCLldkKGEsYitzKQppZig0ODw9ciYm
-cjw9NTcpdD10KjE2K3ItNDgKZWxzZXtyfD0zMgppZig5Nzw9ciYmcjw9MTAyKXQ9dCoxNityLTg3CmVs
-c2UgdGhyb3cgSC5iKFAueFkoIkludmFsaWQgVVJMIGVuY29kaW5nIikpfX1yZXR1cm4gdH0sCmt1OmZ1
-bmN0aW9uKGEsYixjLGQsZSl7dmFyIHQscyxyLHEscD1KLnJZKGEpLG89Ygp3aGlsZSghMCl7aWYoIShv
-PGMpKXt0PSEwCmJyZWFrfXM9cC5XZChhLG8pCmlmKHM8PTEyNylpZihzIT09Mzcpcj1lJiZzPT09NDMK
-ZWxzZSByPSEwCmVsc2Ugcj0hMAppZihyKXt0PSExCmJyZWFrfSsrb31pZih0KXtpZihDLnhNIT09ZCly
-PSExCmVsc2Ugcj0hMAppZihyKXJldHVybiBwLk5qKGEsYixjKQplbHNlIHE9bmV3IEgucWoocC5Oaihh
-LGIsYykpfWVsc2V7cT1ILlZNKFtdLHUudCkKZm9yKG89YjtvPGM7KytvKXtzPXAuV2QoYSxvKQppZihz
-PjEyNyl0aHJvdyBILmIoUC54WSgiSWxsZWdhbCBwZXJjZW50IGVuY29kaW5nIGluIFVSSSIpKQppZihz
-PT09Mzcpe2lmKG8rMz5hLmxlbmd0aCl0aHJvdyBILmIoUC54WSgiVHJ1bmNhdGVkIFVSSSIpKQpDLk5t
-LkEocSxQLkloKGEsbysxKSkKbys9Mn1lbHNlIGlmKGUmJnM9PT00MylDLk5tLkEocSwzMikKZWxzZSBD
-Lk5tLkEocSxzKX19dS5MLmIocSkKcmV0dXJuIG5ldyBQLkdZKCExKS5XSihxKX0sCkV0OmZ1bmN0aW9u
-KGEpe3ZhciB0PWF8MzIKcmV0dXJuIDk3PD10JiZ0PD0xMjJ9LApLRDpmdW5jdGlvbihhLGIsYyl7dmFy
-IHQscyxyLHEscCxvLG4sbSxsPSJJbnZhbGlkIE1JTUUgdHlwZSIsaz1ILlZNKFtiLTFdLHUudCkKZm9y
-KHQ9YS5sZW5ndGgscz1iLHI9LTEscT1udWxsO3M8dDsrK3Mpe3E9Qy54Qi5XZChhLHMpCmlmKHE9PT00
-NHx8cT09PTU5KWJyZWFrCmlmKHE9PT00Nyl7aWYocjwwKXtyPXMKY29udGludWV9dGhyb3cgSC5iKFAu
-cnIobCxhLHMpKX19aWYocjwwJiZzPmIpdGhyb3cgSC5iKFAucnIobCxhLHMpKQpmb3IoO3EhPT00NDsp
-e0MuTm0uQShrLHMpOysrcwpmb3IocD0tMTtzPHQ7KytzKXtxPUMueEIuV2QoYSxzKQppZihxPT09NjEp
-e2lmKHA8MClwPXN9ZWxzZSBpZihxPT09NTl8fHE9PT00NClicmVha31pZihwPj0wKUMuTm0uQShrLHAp
-CmVsc2V7bz1DLk5tLmdyWihrKQppZihxIT09NDR8fHMhPT1vKzd8fCFDLnhCLlFpKGEsImJhc2U2NCIs
-bysxKSl0aHJvdyBILmIoUC5ycigiRXhwZWN0aW5nICc9JyIsYSxzKSkKYnJlYWt9fUMuTm0uQShrLHMp
-Cm49cysxCmlmKChrLmxlbmd0aCYxKT09PTEpYT1DLmg5LnlyKDAsYSxuLHQpCmVsc2V7bT1QLlVsKGEs
-bix0LEMuVkMsITApCmlmKG0hPW51bGwpYT1DLnhCLmk3KGEsbix0LG0pfXJldHVybiBuZXcgUC5QRShh
-LGssYyl9LAp1eDpmdW5jdGlvbigpe3ZhciB0PSIwMTIzNDU2Nzg5QUJDREVGR0hJSktMTU5PUFFSU1RV
-VldYWVphYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ei0uX34hJCYnKCkqKyw7PSIscz0iLiIscj0iOiIs
-cT0iLyIscD0iPyIsbz0iIyIsbj11LmdjLG09UC5kSCgyMixuZXcgUC5xMygpLCEwLG4pLGw9bmV3IFAu
-eUkobSksaz1uZXcgUC5jNigpLGo9bmV3IFAucWQoKSxpPW4uYihsLiQyKDAsMjI1KSkKay4kMyhpLHQs
-MSkKay4kMyhpLHMsMTQpCmsuJDMoaSxyLDM0KQprLiQzKGkscSwzKQprLiQzKGkscCwxNzIpCmsuJDMo
-aSxvLDIwNSkKaT1uLmIobC4kMigxNCwyMjUpKQprLiQzKGksdCwxKQprLiQzKGkscywxNSkKay4kMyhp
-LHIsMzQpCmsuJDMoaSxxLDIzNCkKay4kMyhpLHAsMTcyKQprLiQzKGksbywyMDUpCmk9bi5iKGwuJDIo
-MTUsMjI1KSkKay4kMyhpLHQsMSkKay4kMyhpLCIlIiwyMjUpCmsuJDMoaSxyLDM0KQprLiQzKGkscSw5
-KQprLiQzKGkscCwxNzIpCmsuJDMoaSxvLDIwNSkKaT1uLmIobC4kMigxLDIyNSkpCmsuJDMoaSx0LDEp
-CmsuJDMoaSxyLDM0KQprLiQzKGkscSwxMCkKay4kMyhpLHAsMTcyKQprLiQzKGksbywyMDUpCmk9bi5i
-KGwuJDIoMiwyMzUpKQprLiQzKGksdCwxMzkpCmsuJDMoaSxxLDEzMSkKay4kMyhpLHMsMTQ2KQprLiQz
-KGkscCwxNzIpCmsuJDMoaSxvLDIwNSkKaT1uLmIobC4kMigzLDIzNSkpCmsuJDMoaSx0LDExKQprLiQz
-KGkscSw2OCkKay4kMyhpLHMsMTgpCmsuJDMoaSxwLDE3MikKay4kMyhpLG8sMjA1KQppPW4uYihsLiQy
-KDQsMjI5KSkKay4kMyhpLHQsNSkKai4kMyhpLCJBWiIsMjI5KQprLiQzKGksciwxMDIpCmsuJDMoaSwi
-QCIsNjgpCmsuJDMoaSwiWyIsMjMyKQprLiQzKGkscSwxMzgpCmsuJDMoaSxwLDE3MikKay4kMyhpLG8s
-MjA1KQppPW4uYihsLiQyKDUsMjI5KSkKay4kMyhpLHQsNSkKai4kMyhpLCJBWiIsMjI5KQprLiQzKGks
-ciwxMDIpCmsuJDMoaSwiQCIsNjgpCmsuJDMoaSxxLDEzOCkKay4kMyhpLHAsMTcyKQprLiQzKGksbywy
-MDUpCmk9bi5iKGwuJDIoNiwyMzEpKQpqLiQzKGksIjE5Iiw3KQprLiQzKGksIkAiLDY4KQprLiQzKGks
-cSwxMzgpCmsuJDMoaSxwLDE3MikKay4kMyhpLG8sMjA1KQppPW4uYihsLiQyKDcsMjMxKSkKai4kMyhp
-LCIwOSIsNykKay4kMyhpLCJAIiw2OCkKay4kMyhpLHEsMTM4KQprLiQzKGkscCwxNzIpCmsuJDMoaSxv
-LDIwNSkKay4kMyhuLmIobC4kMig4LDgpKSwiXSIsNSkKaT1uLmIobC4kMig5LDIzNSkpCmsuJDMoaSx0
-LDExKQprLiQzKGkscywxNikKay4kMyhpLHEsMjM0KQprLiQzKGkscCwxNzIpCmsuJDMoaSxvLDIwNSkK
-aT1uLmIobC4kMigxNiwyMzUpKQprLiQzKGksdCwxMSkKay4kMyhpLHMsMTcpCmsuJDMoaSxxLDIzNCkK
-ay4kMyhpLHAsMTcyKQprLiQzKGksbywyMDUpCmk9bi5iKGwuJDIoMTcsMjM1KSkKay4kMyhpLHQsMTEp
-CmsuJDMoaSxxLDkpCmsuJDMoaSxwLDE3MikKay4kMyhpLG8sMjA1KQppPW4uYihsLiQyKDEwLDIzNSkp
-CmsuJDMoaSx0LDExKQprLiQzKGkscywxOCkKay4kMyhpLHEsMjM0KQprLiQzKGkscCwxNzIpCmsuJDMo
-aSxvLDIwNSkKaT1uLmIobC4kMigxOCwyMzUpKQprLiQzKGksdCwxMSkKay4kMyhpLHMsMTkpCmsuJDMo
-aSxxLDIzNCkKay4kMyhpLHAsMTcyKQprLiQzKGksbywyMDUpCmk9bi5iKGwuJDIoMTksMjM1KSkKay4k
-MyhpLHQsMTEpCmsuJDMoaSxxLDIzNCkKay4kMyhpLHAsMTcyKQprLiQzKGksbywyMDUpCmk9bi5iKGwu
-JDIoMTEsMjM1KSkKay4kMyhpLHQsMTEpCmsuJDMoaSxxLDEwKQprLiQzKGkscCwxNzIpCmsuJDMoaSxv
-LDIwNSkKaT1uLmIobC4kMigxMiwyMzYpKQprLiQzKGksdCwxMikKay4kMyhpLHAsMTIpCmsuJDMoaSxv
-LDIwNSkKaT1uLmIobC4kMigxMywyMzcpKQprLiQzKGksdCwxMykKay4kMyhpLHAsMTMpCmouJDMobi5i
-KGwuJDIoMjAsMjQ1KSksImF6IiwyMSkKbD1uLmIobC4kMigyMSwyNDUpKQpqLiQzKGwsImF6IiwyMSkK
-ai4kMyhsLCIwOSIsMjEpCmsuJDMobCwiKy0uIiwyMSkKcmV0dXJuIG19LApVQjpmdW5jdGlvbihhLGIs
-YyxkLGUpe3ZhciB0LHMscixxLHAsbz0kLnZaKCkKZm9yKHQ9Si5yWShhKSxzPWI7czxjOysrcyl7aWYo
-ZDwwfHxkPj1vLmxlbmd0aClyZXR1cm4gSC5PSChvLGQpCnI9b1tkXQpxPXQuV2QoYSxzKV45NgppZihx
-Pjk1KXE9MzEKaWYocT49ci5sZW5ndGgpcmV0dXJuIEguT0gocixxKQpwPXJbcV0KZD1wJjMxCkMuTm0u
-WShlLHA+Pj41LHMpfXJldHVybiBkfSwKV0Y6ZnVuY3Rpb24gV0YoYSxiKXt0aGlzLmE9YQp0aGlzLmI9
-Yn0sCmEyOmZ1bmN0aW9uIGEyKCl7fSwKaVA6ZnVuY3Rpb24gaVAoYSxiKXt0aGlzLmE9YQp0aGlzLmI9
-Yn0sCkNQOmZ1bmN0aW9uIENQKCl7fSwKWFM6ZnVuY3Rpb24gWFMoKXt9LApDNjpmdW5jdGlvbiBDNihh
-KXt0aGlzLmE9YX0sCm46ZnVuY3Rpb24gbigpe30sCnU6ZnVuY3Rpb24gdShhLGIsYyxkKXt2YXIgXz10
-aGlzCl8uYT1hCl8uYj1iCl8uYz1jCl8uZD1kfSwKYko6ZnVuY3Rpb24gYkooYSxiLGMsZCxlLGYpe3Zh
-ciBfPXRoaXMKXy5lPWEKXy5mPWIKXy5hPWMKXy5iPWQKXy5jPWUKXy5kPWZ9LAplWTpmdW5jdGlvbiBl
-WShhLGIsYyxkLGUpe3ZhciBfPXRoaXMKXy5mPWEKXy5hPWIKXy5iPWMKXy5jPWQKXy5kPWV9LAptcDpm
-dW5jdGlvbiBtcChhLGIsYyxkKXt2YXIgXz10aGlzCl8uYT1hCl8uYj1iCl8uYz1jCl8uZD1kfSwKdWI6
-ZnVuY3Rpb24gdWIoYSl7dGhpcy5hPWF9LApkczpmdW5jdGlvbiBkcyhhKXt0aGlzLmE9YX0sCmxqOmZ1
-bmN0aW9uIGxqKGEpe3RoaXMuYT1hfSwKVVY6ZnVuY3Rpb24gVVYoYSl7dGhpcy5hPWF9LAprNTpmdW5j
-dGlvbiBrNSgpe30sCktZOmZ1bmN0aW9uIEtZKCl7fSwKYzpmdW5jdGlvbiBjKGEpe3RoaXMuYT1hfSwK
-Q0Q6ZnVuY3Rpb24gQ0QoYSl7dGhpcy5hPWF9LAphRTpmdW5jdGlvbiBhRShhLGIsYyl7dGhpcy5hPWEK
-dGhpcy5iPWIKdGhpcy5jPWN9LApFSDpmdW5jdGlvbiBFSCgpe30sCktOOmZ1bmN0aW9uIEtOKCl7fSwK
-Y1g6ZnVuY3Rpb24gY1goKXt9LApBbjpmdW5jdGlvbiBBbigpe30sCnpNOmZ1bmN0aW9uIHpNKCl7fSwK
-WjA6ZnVuY3Rpb24gWjAoKXt9LApOMzpmdW5jdGlvbiBOMyhhLGIsYyl7dGhpcy5hPWEKdGhpcy5iPWIK
-dGhpcy4kdGk9Y30sCmM4OmZ1bmN0aW9uIGM4KCl7fSwKRks6ZnVuY3Rpb24gRksoKXt9LAprOmZ1bmN0
-aW9uIGsoKXt9LApPZDpmdW5jdGlvbiBPZCgpe30sCmliOmZ1bmN0aW9uIGliKCl7fSwKeHU6ZnVuY3Rp
-b24geHUoKXt9LApHejpmdW5jdGlvbiBHeigpe30sCnFVOmZ1bmN0aW9uIHFVKCl7fSwKUm46ZnVuY3Rp
-b24gUm4oYSl7dGhpcy5hPWF9LApHRDpmdW5jdGlvbiBHRCgpe30sCm4xOmZ1bmN0aW9uIG4xKGEpe3Ro
-aXMuYT1hfSwKY1M6ZnVuY3Rpb24gY1MoYSl7dGhpcy5hPWF9LApWQzpmdW5jdGlvbiBWQyhhKXt0aGlz
-LmE9YX0sCkpUOmZ1bmN0aW9uIEpUKGEsYil7dGhpcy5hPWEKdGhpcy5iPWJ9LApEbjpmdW5jdGlvbiBE
-bihhLGIsYyxkLGUsZixnKXt2YXIgXz10aGlzCl8uYT1hCl8uYj1iCl8uYz1jCl8uZD1kCl8uZT1lCl8u
-Zj1mCl8ucj1nCl8uUT1fLno9Xy55PV8ueD1udWxsfSwKZTE6ZnVuY3Rpb24gZTEoYSxiKXt0aGlzLmE9
-YQp0aGlzLmI9Yn0sCk5ZOmZ1bmN0aW9uIE5ZKGEpe3RoaXMuYT1hfSwKUlo6ZnVuY3Rpb24gUlooKXt9
-LApNRTpmdW5jdGlvbiBNRShhLGIpe3RoaXMuYT1hCnRoaXMuYj1ifSwKeTU6ZnVuY3Rpb24geTUoYSl7
-dGhpcy5hPWF9LApQRTpmdW5jdGlvbiBQRShhLGIsYyl7dGhpcy5hPWEKdGhpcy5iPWIKdGhpcy5jPWN9
-LApxMzpmdW5jdGlvbiBxMygpe30sCnlJOmZ1bmN0aW9uIHlJKGEpe3RoaXMuYT1hfSwKYzY6ZnVuY3Rp
-b24gYzYoKXt9LApxZDpmdW5jdGlvbiBxZCgpe30sClVmOmZ1bmN0aW9uIFVmKGEsYixjLGQsZSxmLGcs
-aCl7dmFyIF89dGhpcwpfLmE9YQpfLmI9YgpfLmM9YwpfLmQ9ZApfLmU9ZQpfLmY9ZgpfLnI9ZwpfLng9
-aApfLnk9bnVsbH0sCnFlOmZ1bmN0aW9uIHFlKGEsYixjLGQsZSxmLGcpe3ZhciBfPXRoaXMKXy5hPWEK
-Xy5iPWIKXy5jPWMKXy5kPWQKXy5lPWUKXy5mPWYKXy5yPWcKXy5RPV8uej1fLnk9Xy54PW51bGx9LApt
-UjpmdW5jdGlvbihhKXt2YXIgdCxzLHIscSxwCmlmKGE9PW51bGwpcmV0dXJuIG51bGwKdD1QLkZsKHUu
-Tix1LnopCnM9T2JqZWN0LmdldE93blByb3BlcnR5TmFtZXMoYSkKZm9yKHI9cy5sZW5ndGgscT0wO3E8
-cy5sZW5ndGg7cy5sZW5ndGg9PT1yfHwoMCxILmxrKShzKSwrK3Epe3A9SC55KHNbcV0pCnQuWSgwLHAs
-YVtwXSl9cmV0dXJuIHR9LAppNjpmdW5jdGlvbiBpNigpe30sCmxSOmZ1bmN0aW9uIGxSKGEsYil7dGhp
-cy5hPWEKdGhpcy5iPWJ9LApqZzpmdW5jdGlvbiBqZyhhLGIpe3RoaXMuYT1hCnRoaXMuYj1ifSwKYUo6
-ZnVuY3Rpb24gYUooKXt9LApLNTpmdW5jdGlvbiBLNShhLGIpe3RoaXMuYT1hCnRoaXMuYj1ifSwKQmY6
-ZnVuY3Rpb24gQmYoYSxiKXt0aGlzLmE9YQp0aGlzLmI9Yn0sCnpnOmZ1bmN0aW9uIHpnKGEsYil7dGhp
-cy5hPWEKdGhpcy5iPWIKdGhpcy5jPSExfSwKZE06ZnVuY3Rpb24gZE0oKXt9LApHRTpmdW5jdGlvbiBH
-RShhKXt0aGlzLmE9YX0sCk43OmZ1bmN0aW9uIE43KGEsYil7dGhpcy5hPWEKdGhpcy5iPWJ9LAp1UTpm
-dW5jdGlvbiB1USgpe30sClcyOmZ1bmN0aW9uIFcyKCl7fSwKZTM6ZnVuY3Rpb24gZTMoKXt9LApoRjpm
-dW5jdGlvbiBoRigpe30sCkJWOmZ1bmN0aW9uIEJWKCl7fSwKUjQ6ZnVuY3Rpb24oYSxiLGMsZCl7dmFy
-IHQscyxyCkgueGQoYikKdS5qLmIoZCkKaWYoSC5vVChiKSl7dD1bY10KQy5ObS5GVih0LGQpCmQ9dH1z
-PXUuegpyPVAuQ0goSi5NMShkLFAudzAoKSxzKSwhMCxzKQp1LlouYihhKQpyZXR1cm4gUC53WShILkVr
-KGEscixudWxsKSl9LApEbTpmdW5jdGlvbihhLGIsYyl7dmFyIHQKdHJ5e2lmKE9iamVjdC5pc0V4dGVu
-c2libGUoYSkmJiFPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoYSxiKSl7T2JqZWN0
-LmRlZmluZVByb3BlcnR5KGEsYix7dmFsdWU6Y30pCnJldHVybiEwfX1jYXRjaCh0KXtILlJ1KHQpfXJl
-dHVybiExfSwKT206ZnVuY3Rpb24oYSxiKXtpZihPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5
-LmNhbGwoYSxiKSlyZXR1cm4gYVtiXQpyZXR1cm4gbnVsbH0sCndZOmZ1bmN0aW9uKGEpe2lmKGE9PW51
-bGx8fHR5cGVvZiBhPT0ic3RyaW5nInx8dHlwZW9mIGE9PSJudW1iZXIifHxILmwoYSkpcmV0dXJuIGEK
-aWYoYSBpbnN0YW5jZW9mIFAuRTQpcmV0dXJuIGEuYQppZihILlI5KGEpKXJldHVybiBhCmlmKHUudy5j
-KGEpKXJldHVybiBhCmlmKGEgaW5zdGFuY2VvZiBQLmlQKXJldHVybiBILm8yKGEpCmlmKHUuWi5jKGEp
-KXJldHVybiBQLmIzKGEsIiRkYXJ0X2pzRnVuY3Rpb24iLG5ldyBQLlBDKCkpCnJldHVybiBQLmIzKGEs
-Il8kZGFydF9qc09iamVjdCIsbmV3IFAubXQoJC5rSSgpKSl9LApiMzpmdW5jdGlvbihhLGIsYyl7dmFy
-IHQ9UC5PbShhLGIpCmlmKHQ9PW51bGwpe3Q9Yy4kMShhKQpQLkRtKGEsYix0KX1yZXR1cm4gdH0sCkw3
-OmZ1bmN0aW9uKGEpe3ZhciB0LHMKaWYoYT09bnVsbHx8dHlwZW9mIGE9PSJzdHJpbmcifHx0eXBlb2Yg
-YT09Im51bWJlciJ8fHR5cGVvZiBhPT0iYm9vbGVhbiIpcmV0dXJuIGEKZWxzZSBpZihhIGluc3RhbmNl
-b2YgT2JqZWN0JiZILlI5KGEpKXJldHVybiBhCmVsc2UgaWYoYSBpbnN0YW5jZW9mIE9iamVjdCYmdS53
-LmMoYSkpcmV0dXJuIGEKZWxzZSBpZihhIGluc3RhbmNlb2YgRGF0ZSl7dD1ILlNjKGEuZ2V0VGltZSgp
-KQpzPW5ldyBQLmlQKHQsITEpCnMuWGsodCwhMSkKcmV0dXJuIHN9ZWxzZSBpZihhLmNvbnN0cnVjdG9y
-PT09JC5rSSgpKXJldHVybiBhLm8KZWxzZSByZXR1cm4gUC5ORChhKX0sCk5EOmZ1bmN0aW9uKGEpe2lm
-KHR5cGVvZiBhPT0iZnVuY3Rpb24iKXJldHVybiBQLmlRKGEsJC53KCksbmV3IFAuTnooKSkKaWYoYSBp
-bnN0YW5jZW9mIEFycmF5KXJldHVybiBQLmlRKGEsJC5SOCgpLG5ldyBQLm5wKCkpCnJldHVybiBQLmlR
-KGEsJC5SOCgpLG5ldyBQLlV0KCkpfSwKaVE6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0PVAuT20oYSxiKQpp
-Zih0PT1udWxsfHwhKGEgaW5zdGFuY2VvZiBPYmplY3QpKXt0PWMuJDEoYSkKUC5EbShhLGIsdCl9cmV0
-dXJuIHR9LApQQzpmdW5jdGlvbiBQQygpe30sCm10OmZ1bmN0aW9uIG10KGEpe3RoaXMuYT1hfSwKTno6
-ZnVuY3Rpb24gTnooKXt9LApucDpmdW5jdGlvbiBucCgpe30sClV0OmZ1bmN0aW9uIFV0KCl7fSwKRTQ6
-ZnVuY3Rpb24gRTQoYSl7dGhpcy5hPWF9LApyNzpmdW5jdGlvbiByNyhhKXt0aGlzLmE9YX0sClR6OmZ1
-bmN0aW9uIFR6KGEsYil7dGhpcy5hPWEKdGhpcy4kdGk9Yn0sCmNvOmZ1bmN0aW9uIGNvKCl7fSwKVTg6
-ZnVuY3Rpb24oYSxiKXt2YXIgdD1uZXcgUC52cygkLlgzLGIuQygidnM8MD4iKSkscz1uZXcgUC5aZih0
-LGIuQygiWmY8MD4iKSkKYS50aGVuKEgudFIobmV3IFAudksocyxiKSwxKSxILnRSKG5ldyBQLnBVKHMp
-LDEpKQpyZXR1cm4gdH0sCnZLOmZ1bmN0aW9uIHZLKGEsYil7dGhpcy5hPWEKdGhpcy5iPWJ9LApwVTpm
-dW5jdGlvbiBwVShhKXt0aGlzLmE9YX0sCklOOmZ1bmN0aW9uIElOKCl7fSwKdG46ZnVuY3Rpb24gdG4o
-KXt9LAp1ajpmdW5jdGlvbiB1aigpe30sCngwOmZ1bmN0aW9uIHgwKCl7fSwKcTY6ZnVuY3Rpb24gcTYo
-KXt9LAp1UDpmdW5jdGlvbiB1UCgpe30sCmZ6OmZ1bmN0aW9uIGZ6KCl7fSwKRUQ6ZnVuY3Rpb24gRUQo
-KXt9LApuZDpmdW5jdGlvbiBuZCgpe30sCktxOmZ1bmN0aW9uIEtxKCl7fSwKS2U6ZnVuY3Rpb24gS2Uo
-YSl7dGhpcy5hPWF9LApkNTpmdW5jdGlvbiBkNSgpe30sCnpZOmZ1bmN0aW9uIHpZKCl7fSwKTkM6ZnVu
-Y3Rpb24gTkMoKXt9LApmVTpmdW5jdGlvbiBmVSgpe30sCkdDOmZ1bmN0aW9uIEdDKCl7fSwKakc6ZnVu
-Y3Rpb24gakcoKXt9LApqUzpmdW5jdGlvbiBqUygpe30sCnhXOmZ1bmN0aW9uIHhXKCl7fSwKZFM6ZnVu
-Y3Rpb24gZFMoKXt9LAp3ajpmdW5jdGlvbiB3aigpe30sCk1ZOmZ1bmN0aW9uIE1ZKCl7fSwKbjY6ZnVu
-Y3Rpb24gbjYoKXt9LApyMjpmdW5jdGlvbiByMigpe30sCnJPOmZ1bmN0aW9uIHJPKCl7fSwKejg6ZnVu
-Y3Rpb24gejgoKXt9LApxZjpmdW5jdGlvbiBxZihhKXt0aGlzLmE9YX0sCmZvOmZ1bmN0aW9uIGZvKCl7
-fSwKVjg6ZnVuY3Rpb24gVjgoKXt9LApHbjpmdW5jdGlvbiBHbigpe30sClUzOmZ1bmN0aW9uIFUzKCl7
-fSwKRm46ZnVuY3Rpb24gRm4oKXt9LAptbzpmdW5jdGlvbiBtbygpe30sCktnOmZ1bmN0aW9uIEtnKCl7
-fX0sVz17CngzOmZ1bmN0aW9uKCl7cmV0dXJuIHdpbmRvd30sClpyOmZ1bmN0aW9uKCl7cmV0dXJuIGRv
-Y3VtZW50fSwKVTk6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0PWRvY3VtZW50LmJvZHkscz0odCYmQy5SWSku
-cjYodCxhLGIsYykKcy50b1N0cmluZwp0PXUuYWMKdD1uZXcgSC5VNShuZXcgVy5lNyhzKSx0LkMoImEy
-KGxELkUpIikuYihuZXcgVy5DdigpKSx0LkMoIlU1PGxELkU+IikpCnJldHVybiB1LmguYih0LmdyOCh0
-KSl9LApyUzpmdW5jdGlvbihhKXt2YXIgdCxzLHI9ImVsZW1lbnQgdGFnIHVuYXZhaWxhYmxlIgp0cnl7
-dD1KLlJFKGEpCmlmKHR5cGVvZiB0LmducyhhKT09InN0cmluZyIpcj10LmducyhhKX1jYXRjaChzKXtI
-LlJ1KHMpfXJldHVybiByfSwKcUQ6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0LHMscixxPW5ldyBQLnZzKCQu
-WDMsdS5hbykscD1uZXcgUC5aZihxLHUuYmopLG89bmV3IFhNTEh0dHBSZXF1ZXN0KCkKQy5EdC5lbyhv
-LGI9PW51bGw/IkdFVCI6YixhLCEwKQpjLlUoMCxuZXcgVy5iVShvKSkKdD11LmFuCnM9dC5iKG5ldyBX
-LmhIKG8scCkpCnUuTS5iKG51bGwpCnI9dS5wClcuSkUobywibG9hZCIscywhMSxyKQpXLkpFKG8sImVy
-cm9yIix0LmIocC5nWUooKSksITEscikKby5zZW5kKCkKcmV0dXJuIHF9LApDMDpmdW5jdGlvbihhLGIp
-e2E9NTM2ODcwOTExJmErYgphPTUzNjg3MDkxMSZhKygoNTI0Mjg3JmEpPDwxMCkKcmV0dXJuIGFeYT4+
-PjZ9LApyRTpmdW5jdGlvbihhLGIsYyxkKXt2YXIgdD1XLkMwKFcuQzAoVy5DMChXLkMwKDAsYSksYiks
-YyksZCkscz01MzY4NzA5MTEmdCsoKDY3MTA4ODYzJnQpPDwzKQpzXj1zPj4+MTEKcmV0dXJuIDUzNjg3
-MDkxMSZzKygoMTYzODMmcyk8PDE1KX0sClROOmZ1bmN0aW9uKGEsYil7dmFyIHQscyxyPWEuY2xhc3NM
-aXN0CmZvcih0PWIubGVuZ3RoLHM9MDtzPGIubGVuZ3RoO2IubGVuZ3RoPT09dHx8KDAsSC5saykoYiks
-KytzKXIuYWRkKGJbc10pfSwKSkU6ZnVuY3Rpb24oYSxiLGMsZCxlKXt2YXIgdD1XLmFGKG5ldyBXLnZO
-KGMpLHUuQikKaWYodCE9bnVsbCYmITApSi5kWihhLGIsdCwhMSkKcmV0dXJuIG5ldyBXLnhDKGEsYix0
-LCExLGUuQygieEM8MD4iKSl9LApUdzpmdW5jdGlvbihhKXt2YXIgdD1kb2N1bWVudC5jcmVhdGVFbGVt
-ZW50KCJhIikscz1uZXcgVy5tayh0LHdpbmRvdy5sb2NhdGlvbikKcz1uZXcgVy5KUShzKQpzLkNZKGEp
-CnJldHVybiBzfSwKVXc6ZnVuY3Rpb24oYSxiLGMsZCl7dS5oLmIoYSkKSC55KGIpCkgueShjKQp1LkUu
-YihkKQpyZXR1cm4hMH0sCm5aOmZ1bmN0aW9uKGEsYixjLGQpe3ZhciB0LHMscgp1LmguYihhKQpILnko
-YikKSC55KGMpCnQ9dS5FLmIoZCkuYQpzPXQuYQpzLmhyZWY9YwpyPXMuaG9zdG5hbWUKdD10LmIKaWYo
-IShyPT10Lmhvc3RuYW1lJiZzLnBvcnQ9PXQucG9ydCYmcy5wcm90b2NvbD09dC5wcm90b2NvbCkpaWYo
-cj09PSIiKWlmKHMucG9ydD09PSIiKXt0PXMucHJvdG9jb2wKdD10PT09IjoifHx0PT09IiJ9ZWxzZSB0
-PSExCmVsc2UgdD0hMQplbHNlIHQ9ITAKcmV0dXJuIHR9LApCbDpmdW5jdGlvbigpe3ZhciB0PXUuTixz
-PVAudE0oQy5ReCx0KSxyPXUuZEcuYihuZXcgVy5JQSgpKSxxPUguVk0oWyJURU1QTEFURSJdLHUucykK
-dD1uZXcgVy5jdChzLFAuTHModCksUC5Mcyh0KSxQLkxzKHQpLG51bGwpCnQuQ1kobnVsbCxuZXcgSC5B
-OChDLlF4LHIsdS5kdikscSxudWxsKQpyZXR1cm4gdH0sCnVWOmZ1bmN0aW9uKGEpe2lmKGE9PW51bGwp
-cmV0dXJuIG51bGwKcmV0dXJuIFcuUDEoYSl9LApxYzpmdW5jdGlvbihhKXt2YXIgdAppZihhPT1udWxs
-KXJldHVybiBudWxsCmlmKCJwb3N0TWVzc2FnZSIgaW4gYSl7dD1XLlAxKGEpCnJldHVybiB0fWVsc2Ug
-cmV0dXJuIHUuYVMuYihhKX0sClAxOmZ1bmN0aW9uKGEpe2lmKGE9PT13aW5kb3cpcmV0dXJuIHUuY2ku
-YihhKQplbHNlIHJldHVybiBuZXcgVy5kVyhhKX0sCnpYOmZ1bmN0aW9uKGEpe2lmKGE9PT13aW5kb3cu
-bG9jYXRpb24pcmV0dXJuIGEKZWxzZSByZXR1cm4gbmV3IFcuRmIoKX0sCmFGOmZ1bmN0aW9uKGEsYil7
-dmFyIHQ9JC5YMwppZih0PT09Qy5OVSlyZXR1cm4gYQpyZXR1cm4gdC5QeShhLGIpfSwKcUU6ZnVuY3Rp
-b24gcUUoKXt9LApZZTpmdW5jdGlvbiBZZSgpe30sCkdoOmZ1bmN0aW9uIEdoKCl7fSwKZlk6ZnVuY3Rp
-b24gZlkoKXt9LApuQjpmdW5jdGlvbiBuQigpe30sCkF6OmZ1bmN0aW9uIEF6KCl7fSwKUFU6ZnVuY3Rp
-b24gUFUoKXt9LApRUDpmdW5jdGlvbiBRUCgpe30sCklGOmZ1bmN0aW9uIElGKCl7fSwKbng6ZnVuY3Rp
-b24gbngoKXt9LApSZDpmdW5jdGlvbiBSZCgpe30sCmtSOmZ1bmN0aW9uIGtSKCl7fSwKVGY6ZnVuY3Rp
-b24gVGYoKXt9LApsdzpmdW5jdGlvbiBsdygpe30sCm9KOmZ1bmN0aW9uIG9KKCl7fSwKaWQ6ZnVuY3Rp
-b24gaWQoKXt9LApCdzpmdW5jdGlvbiBCdygpe30sCm80OmZ1bmN0aW9uIG80KCl7fSwKSFM6ZnVuY3Rp
-b24gSFMoKXt9LApWbzpmdW5jdGlvbiBWbygpe30sCkZoOmZ1bmN0aW9uIEZoKCl7fSwKY3g6ZnVuY3Rp
-b24gY3goKXt9LApTYjpmdW5jdGlvbiBTYigpe30sClFGOmZ1bmN0aW9uIFFGKCl7fSwKTmg6ZnVuY3Rp
-b24gTmgoKXt9LApGdjpmdW5jdGlvbiBGdigpe30sCklCOmZ1bmN0aW9uIElCKCl7fSwKWWw6ZnVuY3Rp
-b24gWWwoKXt9LApuNzpmdW5jdGlvbiBuNygpe30sCnd6OmZ1bmN0aW9uIHd6KGEsYil7dGhpcy5hPWEK
-dGhpcy4kdGk9Yn0sCmN2OmZ1bmN0aW9uIGN2KCl7fSwKQ3Y6ZnVuY3Rpb24gQ3YoKXt9LApRSTpmdW5j
-dGlvbiBRSSgpe30sCmVhOmZ1bmN0aW9uIGVhKCl7fSwKRDA6ZnVuY3Rpb24gRDAoKXt9LApUNTpmdW5j
-dGlvbiBUNSgpe30sClhWOmZ1bmN0aW9uIFhWKCl7fSwKd0o6ZnVuY3Rpb24gd0ooKXt9LApoNDpmdW5j
-dGlvbiBoNCgpe30sCkdPOmZ1bmN0aW9uIEdPKCl7fSwKSkM6ZnVuY3Rpb24gSkMoKXt9LApicjpmdW5j
-dGlvbiBicigpe30sCnhuOmZ1bmN0aW9uIHhuKCl7fSwKVmI6ZnVuY3Rpb24gVmIoKXt9LApPNzpmdW5j
-dGlvbiBPNygpe30sCmJVOmZ1bmN0aW9uIGJVKGEpe3RoaXMuYT1hfSwKaEg6ZnVuY3Rpb24gaEgoYSxi
-KXt0aGlzLmE9YQp0aGlzLmI9Yn0sCndhOmZ1bmN0aW9uIHdhKCl7fSwKU2c6ZnVuY3Rpb24gU2coKXt9
-LApKSzpmdW5jdGlvbiBKSygpe30sCkhMOmZ1bmN0aW9uIEhMKCl7fSwKd1A6ZnVuY3Rpb24gd1AoKXt9
-LAp1ODpmdW5jdGlvbiB1OCgpe30sCno2OmZ1bmN0aW9uIHo2KCl7fSwKbEs6ZnVuY3Rpb24gbEsoKXt9
-LApRYjpmdW5jdGlvbiBRYigpe30sClMwOmZ1bmN0aW9uIFMwKCl7fSwKRkE6ZnVuY3Rpb24gRkEoYSl7
-dGhpcy5hPWF9LAp6MjpmdW5jdGlvbiB6Migpe30sCnVxOmZ1bmN0aW9uIHVxKGEpe3RoaXMuYT1hfSwK
-QVc6ZnVuY3Rpb24gQVcoKXt9LApETTpmdW5jdGlvbiBETSgpe30sCkFqOmZ1bmN0aW9uIEFqKCl7fSwK
-ZTc6ZnVuY3Rpb24gZTcoYSl7dGhpcy5hPWF9LAp1SDpmdW5jdGlvbiB1SCgpe30sCkJIOmZ1bmN0aW9u
-IEJIKCl7fSwKUWw6ZnVuY3Rpb24gUWwoKXt9LApHWDpmdW5jdGlvbiBHWCgpe30sClNOOmZ1bmN0aW9u
-IFNOKCl7fSwKSEQ6ZnVuY3Rpb24gSEQoKXt9LApjbDpmdW5jdGlvbiBjbCgpe30sCkV2OmZ1bmN0aW9u
-IEV2KCl7fSwKTHI6ZnVuY3Rpb24gTHIoKXt9LApLUjpmdW5jdGlvbiBLUigpe30sCmV3OmZ1bmN0aW9u
-IGV3KCl7fSwKcDg6ZnVuY3Rpb24gcDgoKXt9LAppaTpmdW5jdGlvbiBpaShhKXt0aGlzLmE9YX0sCmxw
-OmZ1bmN0aW9uIGxwKCl7fSwKU1Y6ZnVuY3Rpb24gU1YoKXt9LApNazpmdW5jdGlvbiBNaygpe30sClk0
-OmZ1bmN0aW9uIFk0KCl7fSwKTm46ZnVuY3Rpb24gTm4oKXt9LApsODpmdW5jdGlvbiBsOCgpe30sCkFz
-OmZ1bmN0aW9uIEFzKCl7fSwKd1E6ZnVuY3Rpb24gd1EoYSl7dGhpcy5hPWF9LApiazpmdW5jdGlvbiBi
-aygpe30sCldXOmZ1bmN0aW9uIFdXKCl7fSwKVGI6ZnVuY3Rpb24gVGIoKXt9LApJdjpmdW5jdGlvbiBJ
-digpe30sCkJUOmZ1bmN0aW9uIEJUKCl7fSwKZlg6ZnVuY3Rpb24gZlgoKXt9LApGQjpmdW5jdGlvbiBG
-Qigpe30sCkExOmZ1bmN0aW9uIEExKCl7fSwKTU46ZnVuY3Rpb24gTU4oKXt9LApYMDpmdW5jdGlvbiBY
-MCgpe30sCm5KOmZ1bmN0aW9uIG5KKCl7fSwKbXo6ZnVuY3Rpb24gbXooKXt9LAphMzpmdW5jdGlvbiBh
-Mygpe30sCmNpOmZ1bmN0aW9uIGNpKCl7fSwKY246ZnVuY3Rpb24gY24oKXt9LAp3NjpmdW5jdGlvbiB3
-Nigpe30sCkZqOmZ1bmN0aW9uIEZqKCl7fSwKdkY6ZnVuY3Rpb24gdkYoKXt9LApPaTpmdW5jdGlvbiBP
-aSgpe30sCkNtOmZ1bmN0aW9uIENtKCl7fSwKQ1E6ZnVuY3Rpb24gQ1EoKXt9LApQUjpmdW5jdGlvbiBQ
-Uigpe30sCnc0OmZ1bmN0aW9uIHc0KCl7fSwKRjI6ZnVuY3Rpb24gRjIoKXt9LApyaDpmdW5jdGlvbiBy
-aCgpe30sCkxPOmZ1bmN0aW9uIExPKCl7fSwKYjE6ZnVuY3Rpb24gYjEoKXt9LAphVDpmdW5jdGlvbiBh
-VCgpe30sCmk3OmZ1bmN0aW9uIGk3KGEpe3RoaXMuYT1hfSwKU3k6ZnVuY3Rpb24gU3koYSl7dGhpcy5h
-PWF9LApLUzpmdW5jdGlvbiBLUyhhLGIpe3RoaXMuYT1hCnRoaXMuYj1ifSwKQTM6ZnVuY3Rpb24gQTMo
-YSxiKXt0aGlzLmE9YQp0aGlzLmI9Yn0sCkk0OmZ1bmN0aW9uIEk0KGEpe3RoaXMuYT1hfSwKRms6ZnVu
-Y3Rpb24gRmsoYSxiKXt0aGlzLmE9YQp0aGlzLiR0aT1ifSwKUk86ZnVuY3Rpb24gUk8oYSxiLGMsZCl7
-dmFyIF89dGhpcwpfLmE9YQpfLmI9YgpfLmM9YwpfLiR0aT1kfSwKZXU6ZnVuY3Rpb24gZXUoYSxiLGMs
-ZCl7dmFyIF89dGhpcwpfLmE9YQpfLmI9YgpfLmM9YwpfLiR0aT1kfSwKeEM6ZnVuY3Rpb24geEMoYSxi
-LGMsZCxlKXt2YXIgXz10aGlzCl8uYj1hCl8uYz1iCl8uZD1jCl8uZT1kCl8uJHRpPWV9LAp2TjpmdW5j
-dGlvbiB2TihhKXt0aGlzLmE9YX0sCkpROmZ1bmN0aW9uIEpRKGEpe3RoaXMuYT1hfSwKR206ZnVuY3Rp
-b24gR20oKXt9LAp2RDpmdW5jdGlvbiB2RChhKXt0aGlzLmE9YX0sClV2OmZ1bmN0aW9uIFV2KGEpe3Ro
-aXMuYT1hfSwKRWc6ZnVuY3Rpb24gRWcoYSxiLGMpe3RoaXMuYT1hCnRoaXMuYj1iCnRoaXMuYz1jfSwK
-bTY6ZnVuY3Rpb24gbTYoKXt9LApFbzpmdW5jdGlvbiBFbygpe30sCldrOmZ1bmN0aW9uIFdrKCl7fSwK
-Y3Q6ZnVuY3Rpb24gY3QoYSxiLGMsZCxlKXt2YXIgXz10aGlzCl8uZT1hCl8uYT1iCl8uYj1jCl8uYz1k
-Cl8uZD1lfSwKSUE6ZnVuY3Rpb24gSUEoKXt9LApPdzpmdW5jdGlvbiBPdygpe30sClc5OmZ1bmN0aW9u
-IFc5KGEsYixjKXt2YXIgXz10aGlzCl8uYT1hCl8uYj1iCl8uYz0tMQpfLmQ9bnVsbApfLiR0aT1jfSwK
-ZFc6ZnVuY3Rpb24gZFcoYSl7dGhpcy5hPWF9LApGYjpmdW5jdGlvbiBGYigpe30sCmtGOmZ1bmN0aW9u
-IGtGKCl7fSwKbWs6ZnVuY3Rpb24gbWsoYSxiKXt0aGlzLmE9YQp0aGlzLmI9Yn0sCktvOmZ1bmN0aW9u
-IEtvKGEpe3RoaXMuYT1hfSwKZm06ZnVuY3Rpb24gZm0oYSl7dGhpcy5hPWF9LApMZTpmdW5jdGlvbiBM
-ZSgpe30sCkpVOmZ1bmN0aW9uIEpVKCl7fSwKeFg6ZnVuY3Rpb24geFgoKXt9LAp2ZTpmdW5jdGlvbiB2
-ZSgpe30sCmJHOmZ1bmN0aW9uIGJHKCl7fSwKdEk6ZnVuY3Rpb24gdEkoKXt9LApmZzpmdW5jdGlvbiBm
-Zygpe30sClo3OmZ1bmN0aW9uIFo3KCl7fSwKSFc6ZnVuY3Rpb24gSFcoKXt9LApsRzpmdW5jdGlvbiBs
-Rygpe30sCnFzOmZ1bmN0aW9uIHFzKCl7fSwKY3M6ZnVuY3Rpb24gY3MoKXt9LApLQjpmdW5jdGlvbiBL
-Qigpe30sCks3OmZ1bmN0aW9uIEs3KCl7fSwKckI6ZnVuY3Rpb24gckIoKXt9LApmVDpmdW5jdGlvbiBm
-VCgpe30sCmY3OmZ1bmN0aW9uIGY3KCl7fSwKYmc6ZnVuY3Rpb24gYmcoKXt9LApvSDpmdW5jdGlvbiBv
-SCgpe30sCkNFOmZ1bmN0aW9uIENFKCl7fSwKYUQ6ZnVuY3Rpb24gYUQoKXt9LApaeDpmdW5jdGlvbiBa
-eCgpe30sCk9YOmZ1bmN0aW9uIE9YKCl7fSwKVWo6ZnVuY3Rpb24gVWooKXt9LApqTTpmdW5jdGlvbiBq
-TSgpe30sClFWOmZ1bmN0aW9uIFFWKCl7fSwKQXc6ZnVuY3Rpb24gQXcoKXt9LAp0cjpmdW5jdGlvbiB0
-cigpe30sCk8zOmZ1bmN0aW9uIE8zKCl7fSwKT3Y6ZnVuY3Rpb24gT3YoKXt9LApjTzpmdW5jdGlvbiBj
-Tygpe30sCllEOmZ1bmN0aW9uIFlEKCl7fSwKRHg6ZnVuY3Rpb24gRHgoKXt9LApYVzpmdW5jdGlvbiBY
-Vygpe30sCm9hOmZ1bmN0aW9uIG9hKCl7fSwKWFU6ZnVuY3Rpb24gWFUoKXt9LApSeTpmdW5jdGlvbiBS
-eSgpe30sCnp2OmZ1bmN0aW9uIHp2KCl7fSwKbno6ZnVuY3Rpb24gbnooKXt9fSxVPXsKamY6ZnVuY3Rp
-b24oYSl7dmFyIHQscyxyLHEKaWYoYT09bnVsbCl0PW51bGwKZWxzZXt0PUguVk0oW10sdS5mQSkKZm9y
-KHM9Si5JVCh1LlIuYihhKSk7cy5tKCk7KXtyPXMuZ1IocykKcT1KLlU2KHIpCkMuTm0uQSh0LG5ldyBV
-LlNlKEgueShxLnEociwiZGVzY3JpcHRpb24iKSksSC55KHEucShyLCJocmVmIikpKSl9fXJldHVybiB0
-fSwKTmQ6ZnVuY3Rpb24oYSl7dmFyIHQscwppZihhPT1udWxsKXQ9bnVsbAplbHNle3Q9SC5WTShbXSx1
-LmhoKQpmb3Iocz1KLklUKHUuUi5iKGEpKTtzLm0oKTspQy5ObS5BKHQsVS5OZihzLmdSKHMpKSl9cmV0
-dXJuIHR9LApOZjpmdW5jdGlvbihhKXt2YXIgdCxzLHIscSxwLG89ImRlc2NyaXB0aW9uIixuPUouVTYo
-YSksbT1ILnkobi5xKGEsbykpLGw9SC5WTShbXSx1LmFKKQpmb3Iobj1KLklUKHUuUi5iKG4ucShhLCJl
-bnRyaWVzIikpKTtuLm0oKTspe3Q9bi5nUihuKQpzPUouVTYodCkKcj1ILnkocy5xKHQsbykpCnE9SC55
-KHMucSh0LCJmdW5jdGlvbiIpKQpzPXMucSh0LCJsaW5rIikKaWYocz09bnVsbClzPW51bGwKZWxzZXtw
-PUouVTYocykKcz1uZXcgVS5NbChILnkocC5xKHMsImhyZWYiKSksSC5TYyhwLnEocywibGluZSIpKSxI
-LnkocC5xKHMsInBhdGgiKSkpfUMuTm0uQShsLG5ldyBVLndiKHIscSxzKSl9cmV0dXJuIG5ldyBVLnlE
-KG0sbCl9LApkMjpmdW5jdGlvbiBkMihhLGIsYyxkLGUpe3ZhciBfPXRoaXMKXy5hPWEKXy5iPWIKXy5j
-PWMKXy5kPWQKXy5lPWV9LApTZTpmdW5jdGlvbiBTZShhLGIpe3RoaXMuYT1hCnRoaXMuYj1ifSwKTWw6
-ZnVuY3Rpb24gTWwoYSxiLGMpe3RoaXMuYT1hCnRoaXMuYj1iCnRoaXMuYz1jfSwKeUQ6ZnVuY3Rpb24g
-eUQoYSxiKXt0aGlzLmE9YQp0aGlzLmI9Yn0sCndiOmZ1bmN0aW9uIHdiKGEsYixjKXt0aGlzLmE9YQp0
-aGlzLmI9Ygp0aGlzLmM9Y319LEI9ewpZZjpmdW5jdGlvbihhKXt2YXIgdCxzLHIscSxwLG8sbixtLGw9
-Si5VNihhKSxrPUgueShsLnEoYSwicmVnaW9ucyIpKSxqPUgueShsLnEoYSwibmF2aWdhdGlvbkNvbnRl
-bnQiKSksaT1ILnkobC5xKGEsInNvdXJjZUNvZGUiKSksaD1QLkZsKHUuTix1LmY0KQpmb3IobD1KLklU
-KEouUU0obC5xKGEsImVkaXRzIikpKSx0PXUuUixzPXUuZ2k7bC5tKCk7KXtyPWwuZ1IobCkKcT1KLlJF
-KHIpCnA9SC55KHEuZ0czKHIpKQpvPUguVk0oW10scykKZm9yKHE9Si5JVCh0LmIocS5nbncocikpKTtx
-Lm0oKTspe249cS5nUihxKQptPUouVTYobikKQy5ObS5BKG8sbmV3IEIuajgoSC5TYyhtLnEobiwibGlu
-ZSIpKSxILnkobS5xKG4sImV4cGxhbmF0aW9uIikpLEguU2MobS5xKG4sIm9mZnNldCIpKSkpfWguWSgw
-LHAsbyl9cmV0dXJuIG5ldyBCLnFwKGssaixpLGgpfSwKajg6ZnVuY3Rpb24gajgoYSxiLGMpe3RoaXMu
-YT1hCnRoaXMuYj1iCnRoaXMuYz1jfSwKcXA6ZnVuY3Rpb24gcXAoYSxiLGMsZCl7dmFyIF89dGhpcwpf
-LmE9YQpfLmI9YgpfLmM9YwpfLmQ9ZH0sCkx1OmZ1bmN0aW9uIEx1KCl7fSwKT1M6ZnVuY3Rpb24oYSl7
-dmFyIHQKaWYoIShhPj02NSYmYTw9OTApKXQ9YT49OTcmJmE8PTEyMgplbHNlIHQ9ITAKcmV0dXJuIHR9
-LApZdTpmdW5jdGlvbihhLGIpe3ZhciB0PWEubGVuZ3RoLHM9YisyCmlmKHQ8cylyZXR1cm4hMQppZigh
-Qi5PUyhDLnhCLk8yKGEsYikpKXJldHVybiExCmlmKEMueEIuTzIoYSxiKzEpIT09NTgpcmV0dXJuITEK
-aWYodD09PXMpcmV0dXJuITAKcmV0dXJuIEMueEIuTzIoYSxzKT09PTQ3fX0sVD17bVE6ZnVuY3Rpb24g
-bVEoKXt9fSxMPXsKRGU6ZnVuY3Rpb24oKXtDLkJaLkIoZG9jdW1lbnQsIkRPTUNvbnRlbnRMb2FkZWQi
-LG5ldyBMLmUoKSkKQy5vbC5CKHdpbmRvdywicG9wc3RhdGUiLG5ldyBMLkwoKSl9LAprejpmdW5jdGlv
-bihhKXt2YXIgdCxzPXUuaC5hKGEucGFyZW50Tm9kZSkucXVlcnlTZWxlY3RvcigiOnNjb3BlID4gdWwi
-KSxyPXMuc3R5bGUscT0iIitDLkNELnpRKHMub2Zmc2V0SGVpZ2h0KSoyKyJweCIKci5tYXhIZWlnaHQ9
-cQpyPUoucUYoYSkKcT1yLiR0aQp0PXEuQygifigxKSIpLmIobmV3IEwuV3gocyxhKSkKdS5NLmIobnVs
-bCkKVy5KRShyLmEsci5iLHQsITEscS5kKX0sCnlYOmZ1bmN0aW9uKGEsYil7dmFyIHQscyxyLHEscCxv
-PSJxdWVyeVNlbGVjdG9yQWxsIixuPWRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoYSksbT11LmgKbi50b1N0
-cmluZwpILkRoKG0sbSwiVCIsbykKdD11LlMKcz1uZXcgVy53eihuLnF1ZXJ5U2VsZWN0b3JBbGwoIi5u
-YXYtbGluayIpLHQpCnMuVShzLG5ldyBMLkFPKGIpKQpILkRoKG0sbSwiVCIsbykKcj1uZXcgVy53eihu
-LnF1ZXJ5U2VsZWN0b3JBbGwoIi5yZWdpb24iKSx0KQppZihyLmdoKHIpIT09MCl7cT1uLnF1ZXJ5U2Vs
-ZWN0b3IoInRhYmxlW2RhdGEtcGF0aF0iKQpxLnRvU3RyaW5nCnIuVShyLG5ldyBMLkhvKHEuZ2V0QXR0
-cmlidXRlKCJkYXRhLSIrbmV3IFcuU3kobmV3IFcuaTcocSkpLlMoInBhdGgiKSkpKX1ILkRoKG0sbSwi
-VCIsbykKcD1uZXcgVy53eihuLnF1ZXJ5U2VsZWN0b3JBbGwoIi5wb3N0LWxpbmsiKSx0KQpwLlUocCxu
-ZXcgTC5JQygpKX0sClE2OmZ1bmN0aW9uKGEsYil7dmFyIHQ9dS5OCnJldHVybiBXLnFEKEwuUTQoYSxi
-KSxudWxsLFAuRUYoWyJDb250ZW50LVR5cGUiLCJhcHBsaWNhdGlvbi9qc29uOyBjaGFyc2V0PVVURi04
-Il0sdCx0KSl9LAp0eTpmdW5jdGlvbihhKXt2YXIgdD11Lk4KcmV0dXJuIFcucUQoTC5RNChhLFAuRmwo
-dCx0KSksIlBPU1QiLFAuRUYoWyJDb250ZW50LVR5cGUiLCJhcHBsaWNhdGlvbi9qc29uOyBjaGFyc2V0
-PVVURi04Il0sdCx0KSkuVzcobmV3IEwuTDEoKSx1LnIpfSwKYUs6ZnVuY3Rpb24oYSl7dmFyIHQ9UC5o
-SyhhKS5naFkoKS5xKDAsImxpbmUiKQpyZXR1cm4gdD09bnVsbD9udWxsOkguSHAodCxudWxsKX0sCkc2
-OmZ1bmN0aW9uKGEpe3ZhciB0PVAuaEsoYSkuZ2hZKCkucSgwLCJvZmZzZXQiKQpyZXR1cm4gdD09bnVs
-bD9udWxsOkguSHAodCxudWxsKX0sCnQyOmZ1bmN0aW9uKGEsYixjKXt2YXIgdCxzLHIscSxwLG8sbj17
-fSxtPXUuaC5iKFcucWMoYS5jdXJyZW50VGFyZ2V0KSkKYS5wcmV2ZW50RGVmYXVsdCgpCnQ9bi5hPW0u
-Z2V0QXR0cmlidXRlKCJocmVmIikKaWYoSi56bCh0LCI/Iikpe3M9Qy54Qi5Oaih0LDAsQy54Qi5PWSh0
-LCI/IikpCm4uYT1zCnI9c31lbHNlIHI9dAppZihjIT1udWxsKXtxPSQublUoKQpyPW4uYT1xLm81KDAs
-RC5ucihxLnRNKGMpLHIpKX1wPUwuRzYodCkKbz1MLmFLKHQpCmlmKHAhPW51bGwpTC5hZihyLHAsbyxi
-LG5ldyBMLm5UKG4scCxvKSkKZWxzZSBMLmFmKHIsbnVsbCxudWxsLGIsbmV3IEwuQloobikpfSwKdW06
-ZnVuY3Rpb24oYSl7cmV0dXJuIEwuUVModS5WLmIoYSkpfSwKUVM6ZnVuY3Rpb24oYSl7dmFyIHQ9MCxz
-PVAuRlgodS56KSxyPTEscSxwPVtdLG8sbixtLGwsawp2YXIgJGFzeW5jJHVtPVAubHooZnVuY3Rpb24o
-YixjKXtpZihiPT09MSl7cT1jCnQ9cn13aGlsZSh0cnVlKXN3aXRjaCh0KXtjYXNlIDA6bD11LmguYShX
-LnFjKGEuY3VycmVudFRhcmdldCkpLmdldEF0dHJpYnV0ZSgiaHJlZiIpCmEucHJldmVudERlZmF1bHQo
-KQpyPTMKdD02CnJldHVybiBQLmpRKEwudHkobCksJGFzeW5jJHVtKQpjYXNlIDY6dS5hXy5hKEouR3Io
-Vy51Vihkb2N1bWVudC5kZWZhdWx0VmlldykpKS5yZWxvYWQoKQpyPTEKdD01CmJyZWFrCmNhc2UgMzpy
-PTIKaz1xCm89SC5SdShrKQpuPUgudHMoaykKTC5xSigiaGFuZGxlUG9zdExpbmtDbGljazogIitILmQo
-byksbikKd2luZG93LmFsZXJ0KCJDb3VsZCBub3QgbG9hZCAiK0guZChsKSsiICgiK0guZChvKSsiKS4i
-KQp0PTUKYnJlYWsKY2FzZSAyOnQ9MQpicmVhawpjYXNlIDU6cmV0dXJuIFAueUMobnVsbCxzKQpjYXNl
-IDE6cmV0dXJuIFAuZjMocSxzKX19KQpyZXR1cm4gUC5ESSgkYXN5bmMkdW0scyl9LAp2VTpmdW5jdGlv
-bigpe3ZhciB0PWRvY3VtZW50LHM9dS5oCkguRGgocyxzLCJUIiwicXVlcnlTZWxlY3RvckFsbCIpCnQ9
-bmV3IFcud3oodC5xdWVyeVNlbGVjdG9yQWxsKCIuY29kZSIpLHUuUykKdC5VKHQsbmV3IEwuR0goKSl9
-LApoWDpmdW5jdGlvbihhLGIsYyl7dmFyIHQ9dS5OCkwuUTYoYSxQLkVGKFsicmVnaW9uIiwicmVnaW9u
-Iiwib2Zmc2V0IixILmQoYildLHQsdCkpLlc3KG5ldyBMLkRUKGEsYixjKSx1LlApLk9BKG5ldyBMLmVI
-KGEpKX0sCkc3OmZ1bmN0aW9uKGEsYixjLGQsZSl7dmFyIHQKaWYoIUouaHcoYSwiLmRhcnQiKSl7TC5C
-RShhLG5ldyBCLnFwKCIiLCIiLCIiLEMuQ00pLGQpCkwuQlgoYSxudWxsKQppZihlIT1udWxsKWUuJDAo
-KQpyZXR1cm59dD11Lk4KTC5RNihhLFAuRUYoWyJpbmxpbmUiLCJ0cnVlIl0sdCx0KSkuVzcobmV3IEwu
-eXUoYSxkLGIsYyxlKSx1LlApLk9BKG5ldyBMLnpEKGEpKX0sCkdlOmZ1bmN0aW9uKCl7dmFyIHQ9Ii9f
-cHJldmlldy9uYXZpZ2F0aW9uVHJlZS5qc29uIgpMLlE2KHQsQy5XTykuVzcobmV3IEwuVFcoKSx1LlAp
-Lk9BKG5ldyBMLnhyKHQpKX0sCnFKOmZ1bmN0aW9uKGEsYil7dmFyIHQKd2luZG93CmlmKHR5cGVvZiBj
-b25zb2xlIT0idW5kZWZpbmVkIil3aW5kb3cuY29uc29sZS5lcnJvcihhKQp3aW5kb3cKdD1ILmQoYikK
-aWYodHlwZW9mIGNvbnNvbGUhPSJ1bmRlZmluZWQiKXdpbmRvdy5jb25zb2xlLmVycm9yKHQpfSwKcU86
-ZnVuY3Rpb24oYSl7dmFyIHQ9YS5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKSxzPUMuQ0QuelEoJC5maSgp
-Lm9mZnNldEhlaWdodCkscj13aW5kb3cuaW5uZXJIZWlnaHQscT1DLkNELnpRKCQuRFcoKS5vZmZzZXRI
-ZWlnaHQpCmlmKHR5cGVvZiByIT09Im51bWJlciIpcmV0dXJuIHIuSE4oKQppZih0LmJvdHRvbT5yLShx
-KzE0KSlKLmRoKGEpCmVsc2UgaWYodC50b3A8cysxNClKLmRoKGEpfSwKZkc6ZnVuY3Rpb24oYSxiKXt2
-YXIgdCxzLHIKaWYoYSE9bnVsbCl7dD1kb2N1bWVudApzPXQuZ2V0RWxlbWVudEJ5SWQoIm8iK0guZChh
-KSkKcj10LnF1ZXJ5U2VsZWN0b3IoIi5saW5lLSIrSC5kKGIpKQppZihzIT1udWxsKXtMLnFPKHMpCkou
-ZFIocykuQSgwLCJ0YXJnZXQiKX1lbHNlIGlmKHIhPW51bGwpTC5xTyhyLnBhcmVudEVsZW1lbnQpCmlm
-KHIhPW51bGwpSi5kUih1LmguYShyLnBhcmVudE5vZGUpKS5BKDAsImhpZ2hsaWdodCIpfWVsc2UgTC5x
-TygkLkQ5KCkpfSwKYWY6ZnVuY3Rpb24oYSxiLGMsZCxlKXt2YXIgdCxzLHI9TC5HNih3aW5kb3cubG9j
-YXRpb24uaHJlZikscT1MLmFLKHdpbmRvdy5sb2NhdGlvbi5ocmVmKQppZihyIT1udWxsKXt0PWRvY3Vt
-ZW50LmdldEVsZW1lbnRCeUlkKCJvIitILmQocikpCmlmKHQhPW51bGwpSi5kUih0KS5SeigwLCJ0YXJn
-ZXQiKX1pZihxIT1udWxsKXtzPWRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoIi5saW5lLSIrSC5kKHEpKQpp
-ZihzIT1udWxsKUouZFIocy5wYXJlbnRFbGVtZW50KS5SeigwLCJoaWdobGlnaHQiKX1pZihhPT13aW5k
-b3cubG9jYXRpb24ucGF0aG5hbWUpe0wuZkcoYixjKQplLiQwKCl9ZWxzZSBMLkc3KGEsYixjLGQsZSl9
-LApRNDpmdW5jdGlvbihhLGIpe3ZhciB0LHMscj1QLmhLKGEpLHE9dS5OCnE9UC5GbChxLHEpCmZvcih0
-PXIuZ2hZKCksdD10LmdQdSh0KSx0PXQuZ2t6KHQpO3QubSgpOyl7cz10LmdSKHQpCnEuWSgwLHMuYSxz
-LmIpfWZvcih0PWIuZ1B1KGIpLHQ9dC5na3oodCk7dC5tKCk7KXtzPXQuZ1IodCkKcS5ZKDAscy5hLHMu
-Yil9cS5ZKDAsImF1dGhUb2tlbiIsJC5VRSgpKQpyZXR1cm4gci5ubSgwLHEpLncoMCl9LApUMTpmdW5j
-dGlvbihhKXt2YXIgdCxzLHIscSxwLG8sbixtLGw9JC5oTCgpCkoubDUobCwiIikKaWYoYT09bnVsbCl7
-dD1kb2N1bWVudC5jcmVhdGVFbGVtZW50KCJwIikKdC50ZXh0Q29udGVudD0iU2VlIGRldGFpbHMgYWJv
-dXQgYSBwcm9wb3NlZCBlZGl0LiIKQy5MdC5zREQodCxILlZNKFsicGxhY2Vob2xkZXIiXSx1LnMpKQpK
-LmRoKHUuaC5iKGwuYXBwZW5kQ2hpbGQodCkpKQpyZXR1cm59cz1hLmQKdD0kLm5VKCkKcj10LnRNKHMp
-CnE9YS5iCnA9ZG9jdW1lbnQKbz10LkhQKHMsSi5UMChwLnF1ZXJ5U2VsZWN0b3IoIi5yb290IikudGV4
-dENvbnRlbnQpKQpuPWEuYwp0PXAuY3JlYXRlRWxlbWVudCgicCIpCm09dS5oLmIobC5hcHBlbmRDaGls
-ZCh0KSkKbS5hcHBlbmRDaGlsZChwLmNyZWF0ZVRleHROb2RlKEguZChxKSsiIGF0ICIrSC5kKG8pKyI6
-IitILmQobikrIi4iKSkKSi5kaChtKQpMLkNDKGEsbCxyKQpMLkZ6KGEsbCl9LApMSDpmdW5jdGlvbihh
-LGIsYyl7dmFyIHQscyxyLHEscCxvLG4sbSxsLGssaixpLGgsZyxmPSQueVAoKQpKLmw1KGYsIiIpCmlm
-KGIuZ2goYik9PT0wKXt0PWRvY3VtZW50CnM9dC5jcmVhdGVFbGVtZW50KCJwIikKdS5oLmIoZi5hcHBl
-bmRDaGlsZChzKSkuYXBwZW5kQ2hpbGQodC5jcmVhdGVUZXh0Tm9kZSgiTm8gcHJvcG9zZWQgZWRpdHMi
-KSl9ZWxzZSBmb3IoZj1iLmdQdShiKSxmPWYuZ2t6KGYpLHQ9dS5pLHM9dS5RLHI9cy5DKCJ+KDEpIiks
-cT11Lk0scz1zLmQscD11Lmg7Zi5tKCk7KXtvPWYuZ1IoZikKbj0kLnlQKCkKbT1kb2N1bWVudApsPW0u
-Y3JlYXRlRWxlbWVudCgicCIpCnAuYihuLmFwcGVuZENoaWxkKGwpKS5hcHBlbmRDaGlsZChtLmNyZWF0
-ZVRleHROb2RlKEguZChvLmEpKyI6IikpCmw9bS5jcmVhdGVFbGVtZW50KCJ1bCIpCms9cC5iKG4uYXBw
-ZW5kQ2hpbGQobCkpCmZvcihvPUouSVQoby5iKTtvLm0oKTspe249by5nUihvKQpsPW0uY3JlYXRlRWxl
-bWVudCgibGkiKQpqPXAuYihrLmFwcGVuZENoaWxkKGwpKQpKLmRSKGopLkEoMCwiZWRpdCIpCmw9bS5j
-cmVhdGVFbGVtZW50KCJhIikKaT10LmIoai5hcHBlbmRDaGlsZChsKSkKaS5jbGFzc0xpc3QuYWRkKCJl
-ZGl0LWxpbmsiKQpoPW4uYwpsPUguZChoKQppLnNldEF0dHJpYnV0ZSgiZGF0YS0iK25ldyBXLlN5KG5l
-dyBXLmk3KGkpKS5TKCJvZmZzZXQiKSxsKQpnPW4uYQpsPUguZChnKQppLnNldEF0dHJpYnV0ZSgiZGF0
-YS0iK25ldyBXLlN5KG5ldyBXLmk3KGkpKS5TKCJsaW5lIiksbCkKaS5hcHBlbmRDaGlsZChtLmNyZWF0
-ZVRleHROb2RlKCJsaW5lICIrSC5kKGcpKSkKbD1yLmIobmV3IEwuRUUoaCxnLGEpKQpxLmIobnVsbCkK
-Vy5KRShpLCJjbGljayIsbCwhMSxzKQpqLmFwcGVuZENoaWxkKG0uY3JlYXRlVGV4dE5vZGUoIjogIitI
-LmQobi5iKSkpfX1pZihjKUwuVDEobnVsbCl9LApGcjpmdW5jdGlvbihhLGIsYyl7dmFyIHQscyxyPXdp
-bmRvdy5sb2NhdGlvbixxPVAuaEsoKHImJkMuRXgpLmdEcihyKStILmQoYSkpCnI9dS5OCnI9UC5GbChy
-LHIpCmlmKGIhPW51bGwpci5ZKDAsIm9mZnNldCIsSC5kKGIpKQppZihjIT1udWxsKXIuWSgwLCJsaW5l
-IixILmQoYykpCnIuWSgwLCJhdXRoVG9rZW4iLCQuVUUoKSkKcT1xLm5tKDAscikKcj13aW5kb3cuaGlz
-dG9yeQp0PXUuegpzPXEudygwKQpyLnRvU3RyaW5nCnIucHVzaFN0YXRlKG5ldyBQLkJmKFtdLFtdKS5Q
-dihQLkZsKHQsdCkpLCIiLHMpfSwKRW46ZnVuY3Rpb24oYSl7dmFyIHQ9Si5iYihkb2N1bWVudC5xdWVy
-eVNlbGVjdG9yKCIucm9vdCIpLnRleHRDb250ZW50LCIvIikKaWYoQy54Qi5uQyhhLHQpKXJldHVybiBD
-LnhCLnluKGEsdC5sZW5ndGgpCmVsc2UgcmV0dXJuIGF9LApCWDpmdW5jdGlvbihhLGIpe3ZhciB0LHMs
-cj17fQpyLmE9YQphPUwuRW4oYSkKci5hPWEKJC5EOSgpLnRleHRDb250ZW50PWEKdD1kb2N1bWVudApz
-PXUuaApILkRoKHMscywiVCIsInF1ZXJ5U2VsZWN0b3JBbGwiKQp0PW5ldyBXLnd6KHQucXVlcnlTZWxl
-Y3RvckFsbCgiLm5hdi1wYW5lbCAubmF2LWxpbmsiKSx1LlMpCnQuVSh0LG5ldyBMLlZTKHIpKX0sCkJF
-OmZ1bmN0aW9uKGEsYixjKXt2YXIgdD0iLnJlZ2lvbnMiLHM9ZG9jdW1lbnQscj1zLnF1ZXJ5U2VsZWN0
-b3IodCkscT1zLnF1ZXJ5U2VsZWN0b3IoIi5jb2RlIikKSi50SChyLGIuYSwkLktHKCkpCkoudEgocSxi
-LmIsJC5LRygpKQpMLkxIKGEsYi5kLGMpCkwudlUoKQpMLnlYKCIuY29kZSIsITApCkwueVgodCwhMCl9
-LAp0WDpmdW5jdGlvbihhLGIpe3ZhciB0LHMscixxLHAsbyxuLG0sbCxrLGosaT1kb2N1bWVudCxoPWku
-Y3JlYXRlRWxlbWVudCgidWwiKSxnPXUuaCxmPWcuYihhLmFwcGVuZENoaWxkKGgpKQpmb3IoaD1iLmxl
-bmd0aCx0PXUuTSxzPTA7czxiLmxlbmd0aDtiLmxlbmd0aD09PWh8fCgwLEgubGspKGIpLCsrcyl7cj1i
-W3NdCnE9aS5jcmVhdGVFbGVtZW50KCJsaSIpCnA9Zy5iKGYuYXBwZW5kQ2hpbGQocSkpCnE9Si5SRShw
-KQppZihyLmE9PT1DLlkyKXtxLmdERChwKS5BKDAsImRpciIpCnE9aS5jcmVhdGVFbGVtZW50KCJzcGFu
-IikKbz1nLmIocC5hcHBlbmRDaGlsZChxKSkKcT1KLlJFKG8pCnEuZ0REKG8pLkEoMCwiYXJyb3ciKQpx
-LnNoZihvLCImI3gyNUJDOyIpCnE9aS5jcmVhdGVFbGVtZW50KCJzcGFuIikKSi5sNShnLmIocC5hcHBl
-bmRDaGlsZChxKSksIiYjeDFGNEMxOyIpCnAuYXBwZW5kQ2hpbGQoaS5jcmVhdGVUZXh0Tm9kZShyLmIp
-KQpMLnRYKHAsci5jKQpMLmt6KG8pfWVsc2V7cS5zaGYocCwiJiN4MUY0QzQ7IikKcT1pLmNyZWF0ZUVs
-ZW1lbnQoImEiKQpuPWcuYihwLmFwcGVuZENoaWxkKHEpKQpxPUouUkUobikKcS5nREQobikuQSgwLCJu
-YXYtbGluayIpCm4uc2V0QXR0cmlidXRlKCJkYXRhLSIrbmV3IFcuU3kobmV3IFcuaTcobikpLlMoIm5h
-bWUiKSxyLmQpCm4uc2V0QXR0cmlidXRlKCJocmVmIixyLmUpCm4uYXBwZW5kQ2hpbGQoaS5jcmVhdGVU
-ZXh0Tm9kZShyLmIpKQpxPXEuZ1ZsKG4pCm09cS4kdGkKbD1tLkMoIn4oMSkiKS5iKG5ldyBMLlREKCkp
-CnQuYihudWxsKQpXLkpFKHEuYSxxLmIsbCwhMSxtLmQpCms9ci5mCmlmKHR5cGVvZiBrIT09Im51bWJl
-ciIpcmV0dXJuIGsub3MoKQppZihrPjApe3E9aS5jcmVhdGVFbGVtZW50KCJzcGFuIikKaj1nLmIocC5h
-cHBlbmRDaGlsZChxKSkKSi5kUihqKS5BKDAsImVkaXQtY291bnQiKQpxPSIiK2srIiAiCmlmKGs9PT0x
-KW09ImVkaXQiCmVsc2UgbT0iZWRpdHMiCmouc2V0QXR0cmlidXRlKCJ0aXRsZSIscSttKQpqLmFwcGVu
-ZENoaWxkKGkuY3JlYXRlVGV4dE5vZGUoQy5qbi53KGspKSl9fX19LApGejpmdW5jdGlvbihhLGIpe3Zh
-ciB0LHMscixxLHAsbyxuLG0sbCxrLGosaT1hLmEKaWYoaSE9bnVsbCl7dD1kb2N1bWVudApzPXQuY3Jl
-YXRlRWxlbWVudCgicCIpCnI9dS5oCnE9ci5iKGIuYXBwZW5kQ2hpbGQocykpCmZvcihzPWkubGVuZ3Ro
-LHA9dS5zLG89dS5YLG49MDtuPGkubGVuZ3RoO2kubGVuZ3RoPT09c3x8KDAsSC5saykoaSksKytuKXtt
-PWlbbl0KbD10LmNyZWF0ZUVsZW1lbnQoImEiKQprPXIuYihxLmFwcGVuZENoaWxkKGwpKQprLmFwcGVu
-ZENoaWxkKHQuY3JlYXRlVGV4dE5vZGUobS5hKSkKay5zZXRBdHRyaWJ1dGUoImhyZWYiLG0uYikKbD1v
-LmIoSC5WTShbInBvc3QtbGluayIsImJlZm9yZS1hcHBseSJdLHApKQpqPUouZFIoaykKai5WMSgwKQpq
-LkZWKDAsbCl9fX0sCkNDOmZ1bmN0aW9uKGEzLGE0LGE1KXt2YXIgdCxzLHIscSxwLG8sbixtLGwsayxq
-LGksaCxnLGYsZSxkLGMsYixhLGEwLGExLGEyPW51bGwKZm9yKHQ9YTMuZSxzPXQubGVuZ3RoLHI9dS5z
-LHE9dS5YLHA9dS5oLG89dS5pLG49MDtuPHQubGVuZ3RoO3QubGVuZ3RoPT09c3x8KDAsSC5saykodCks
-KytuKXttPXRbbl0KbD1kb2N1bWVudAprPWwuY3JlYXRlRWxlbWVudCgicCIpCmo9cS5iKEguVk0oWyJ0
-cmFjZSJdLHIpKQppPUouZFIoaykKaS5WMSgwKQppLkZWKDAsaikKaD1hNC5hcHBlbmRDaGlsZChrKQpr
-PWwuY3JlYXRlRWxlbWVudCgic3BhbiIpCmo9cS5iKEguVk0oWyJ0eXBlLWRlc2NyaXB0aW9uIl0scikp
-Cmk9Si5kUihrKQppLlYxKDApCmkuRlYoMCxqKQprLmFwcGVuZENoaWxkKGwuY3JlYXRlVGV4dE5vZGUo
-bS5hKSkKaC5hcHBlbmRDaGlsZChrKQpoLmFwcGVuZENoaWxkKGwuY3JlYXRlVGV4dE5vZGUoIjoiKSkK
-az1sLmNyZWF0ZUVsZW1lbnQoInVsIikKaj1xLmIoSC5WTShbInRyYWNlIl0scikpCmk9Si5kUihrKQpp
-LlYxKDApCmkuRlYoMCxqKQpnPWguYXBwZW5kQ2hpbGQoaykKZm9yKGs9bS5iLGo9ay5sZW5ndGgsZj0w
-O2Y8ay5sZW5ndGg7ay5sZW5ndGg9PT1qfHwoMCxILmxrKShrKSwrK2Ype2U9a1tmXQpkPWwuY3JlYXRl
-RWxlbWVudCgibGkiKQpKLmw1KGQsIiYjeDI3NEY7ICIpCmM9cC5iKGcuYXBwZW5kQ2hpbGQoZCkpCmQ9
-bC5jcmVhdGVFbGVtZW50KCJzcGFuIikKYj1xLmIoSC5WTShbImZ1bmN0aW9uIl0scikpCmk9Si5kUihk
-KQppLlYxKDApCmkuRlYoMCxiKQpiPWUuYgpMLmtEKGQsYj09bnVsbD8idW5rbm93biI6YikKYy5hcHBl
-bmRDaGlsZChkKQphPWUuYwppZihhIT1udWxsKXtjLmFwcGVuZENoaWxkKGwuY3JlYXRlVGV4dE5vZGUo
-IiAoIikpCmEwPWEuYgpkPWwuY3JlYXRlRWxlbWVudCgiYSIpCm8uYihkKQpkLmFwcGVuZENoaWxkKGwu
-Y3JlYXRlVGV4dE5vZGUoSC5kKGEuYykrIjoiK0guZChhMCkpKQphMT1hLmEKYj0kLm5VKCkKZC5zZXRB
-dHRyaWJ1dGUoImhyZWYiLGIubzUoMCxiLnE3KDAsYTUsYTEsYTIsYTIsYTIsYTIsYTIsYTIpKSkKZC5j
-bGFzc0xpc3QuYWRkKCJuYXYtbGluayIpCmMuYXBwZW5kQ2hpbGQoZCkKYy5hcHBlbmRDaGlsZChsLmNy
-ZWF0ZVRleHROb2RlKCIpIikpfWMuYXBwZW5kQ2hpbGQobC5jcmVhdGVUZXh0Tm9kZSgiOiAiKSkKZD1l
-LmEKTC5rRChjLGQ9PW51bGw/InVua25vd24iOmQpfX19LAprRDpmdW5jdGlvbihhLGIpe3ZhciB0LHMs
-cj1ILlZNKGIuc3BsaXQoIi4iKSx1LnMpLHE9Qy5ObS5ndEgocikscD1kb2N1bWVudAphLmFwcGVuZENo
-aWxkKHAuY3JlYXRlVGV4dE5vZGUocSkpCmZvcihxPUgucUMociwxLG51bGwsdS5OKSxxPW5ldyBILmE3
-KHEscS5naChxKSxxLiR0aS5DKCJhNzxhTC5FPiIpKSx0PUouUkUoYSk7cS5tKCk7KXtzPXEuZAp0Lm56
-KGEsImJlZm9yZWVuZCIsIiYjODIwMzsuIixudWxsLG51bGwpCmEuYXBwZW5kQ2hpbGQocC5jcmVhdGVU
-ZXh0Tm9kZShzKSl9fSwKZTpmdW5jdGlvbiBlKCl7fSwKVlc6ZnVuY3Rpb24gVlcoYSxiLGMpe3RoaXMu
-YT1hCnRoaXMuYj1iCnRoaXMuYz1jfSwKb1o6ZnVuY3Rpb24gb1ooKXt9LApqcjpmdW5jdGlvbiBqcigp
-e30sCnFsOmZ1bmN0aW9uIHFsKCl7fSwKeTg6ZnVuY3Rpb24geTgoKXt9LApMOmZ1bmN0aW9uIEwoKXt9
-LApXeDpmdW5jdGlvbiBXeChhLGIpe3RoaXMuYT1hCnRoaXMuYj1ifSwKQU86ZnVuY3Rpb24gQU8oYSl7
-dGhpcy5hPWF9LApkTjpmdW5jdGlvbiBkTihhKXt0aGlzLmE9YX0sCkhvOmZ1bmN0aW9uIEhvKGEpe3Ro
-aXMuYT1hfSwKeHo6ZnVuY3Rpb24geHooYSxiKXt0aGlzLmE9YQp0aGlzLmI9Yn0sCklDOmZ1bmN0aW9u
-IElDKCl7fSwKTDE6ZnVuY3Rpb24gTDEoKXt9LApuVDpmdW5jdGlvbiBuVChhLGIsYyl7dGhpcy5hPWEK
-dGhpcy5iPWIKdGhpcy5jPWN9LApCWjpmdW5jdGlvbiBCWihhKXt0aGlzLmE9YX0sCkdIOmZ1bmN0aW9u
-IEdIKCl7fSwKRFQ6ZnVuY3Rpb24gRFQoYSxiLGMpe3RoaXMuYT1hCnRoaXMuYj1iCnRoaXMuYz1jfSwK
-ZUg6ZnVuY3Rpb24gZUgoYSl7dGhpcy5hPWF9LAp5dTpmdW5jdGlvbiB5dShhLGIsYyxkLGUpe3ZhciBf
-PXRoaXMKXy5hPWEKXy5iPWIKXy5jPWMKXy5kPWQKXy5lPWV9LAp6RDpmdW5jdGlvbiB6RChhKXt0aGlz
-LmE9YX0sClRXOmZ1bmN0aW9uIFRXKCl7fSwKeHI6ZnVuY3Rpb24geHIoYSl7dGhpcy5hPWF9LApFRTpm
-dW5jdGlvbiBFRShhLGIsYyl7dGhpcy5hPWEKdGhpcy5iPWIKdGhpcy5jPWN9LApRTDpmdW5jdGlvbiBR
-TChhLGIpe3RoaXMuYT1hCnRoaXMuYj1ifSwKVlM6ZnVuY3Rpb24gVlMoYSl7dGhpcy5hPWF9LApURDpm
-dW5jdGlvbiBURCgpe30sClhBOmZ1bmN0aW9uIFhBKCl7fSwKbUs6ZnVuY3Rpb24oYSl7dmFyIHQscyxy
-LHEscCxvLG49SC5WTShbXSx1LmZoKQpmb3IodD1KLklUKHUuUi5iKGEpKTt0Lm0oKTspe3M9dC5nUih0
-KQpyPUouVTYocykKcT1MLnAyKEgueShyLnEocywidHlwZSIpKSkKcD1ILnkoci5xKHMsIm5hbWUiKSkK
-bz1yLnEocywic3VidHJlZSIpCm89bz09bnVsbD9udWxsOkwubUsobykKQy5ObS5BKG4sbmV3IEwuWloo
-cSxwLG8sSC55KHIucShzLCJwYXRoIikpLEgueShyLnEocywiaHJlZiIpKSxILlNjKHIucShzLCJlZGl0
-Q291bnQiKSkpKX1yZXR1cm4gbn0sCnAyOmZ1bmN0aW9uKGEpe3N3aXRjaChhKXtjYXNlImRpcmVjdG9y
-eSI6cmV0dXJuIEMuWTIKY2FzZSJmaWxlIjpyZXR1cm4gQy5yZgpkZWZhdWx0OnRocm93IEguYihQLlBW
-KCJVbnJlY29nbml6ZWQgbmF2aWdhdGlvbiB0cmVlIG5vZGUgdHlwZTogIitILmQoYSkpKX19LApaWjpm
-dW5jdGlvbiBaWihhLGIsYyxkLGUsZil7dmFyIF89dGhpcwpfLmE9YQpfLmI9YgpfLmM9YwpfLmQ9ZApf
-LmU9ZQpfLmY9Zn0sCkJjOmZ1bmN0aW9uIEJjKGEpe3RoaXMuYj1hfSwKSVY6ZnVuY3Rpb24gSVYoYSxi
-LGMsZCl7dmFyIF89dGhpcwpfLmQ9YQpfLmU9YgpfLmY9YwpfLnI9ZH19LE09ewpZRjpmdW5jdGlvbihh
-LGIpe3ZhciB0LHMscixxLHAsbyxuCmZvcih0PWIubGVuZ3RoLHM9MTtzPHQ7KytzKXtpZihiW3NdPT1u
-dWxsfHxiW3MtMV0hPW51bGwpY29udGludWUKZm9yKDt0Pj0xO3Q9cil7cj10LTEKaWYoYltyXSE9bnVs
-bClicmVha31xPW5ldyBQLlJuKCIiKQpwPWErIigiCnEuYT1wCm89SC5xQyhiLDAsdCxILnQ2KGIpLmQp
-Cm49by4kdGkKbj1wK25ldyBILkE4KG8sbi5DKCJxVShhTC5FKSIpLmIobmV3IE0uTm8oKSksbi5DKCJB
-ODxhTC5FLHFVPiIpKS56VigwLCIsICIpCnEuYT1uCnEuYT1uKygiKTogcGFydCAiKyhzLTEpKyIgd2Fz
-IG51bGwsIGJ1dCBwYXJ0ICIrcysiIHdhcyBub3QuIikKdGhyb3cgSC5iKFAueFkocS53KDApKSl9fSwK
-bEk6ZnVuY3Rpb24gbEkoYSl7dGhpcy5hPWF9LApNaTpmdW5jdGlvbiBNaSgpe30sCnE3OmZ1bmN0aW9u
-IHE3KCl7fSwKTm86ZnVuY3Rpb24gTm8oKXt9fSxYPXsKQ0w6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzLHIs
-cSxwLG89Yi54WihhKQpiLmhLKGEpCmlmKG8hPW51bGwpYT1KLktWKGEsby5sZW5ndGgpCnQ9dS5zCnM9
-SC5WTShbXSx0KQpyPUguVk0oW10sdCkKdD1hLmxlbmd0aAppZih0IT09MCYmYi5yNChDLnhCLldkKGEs
-MCkpKXtpZigwPj10KXJldHVybiBILk9IKGEsMCkKQy5ObS5BKHIsYVswXSkKcT0xfWVsc2V7Qy5ObS5B
-KHIsIiIpCnE9MH1mb3IocD1xO3A8dDsrK3ApaWYoYi5yNChDLnhCLldkKGEscCkpKXtDLk5tLkEocyxD
-LnhCLk5qKGEscSxwKSkKQy5ObS5BKHIsYVtwXSkKcT1wKzF9aWYocTx0KXtDLk5tLkEocyxDLnhCLnlu
-KGEscSkpCkMuTm0uQShyLCIiKX1yZXR1cm4gbmV3IFguV0QoYixvLHMscil9LApXRDpmdW5jdGlvbiBX
-RChhLGIsYyxkKXt2YXIgXz10aGlzCl8uYT1hCl8uYj1iCl8uZD1jCl8uZT1kfSwKcVI6ZnVuY3Rpb24g
-cVIoYSl7dGhpcy5hPWF9LApJNzpmdW5jdGlvbihhKXtyZXR1cm4gbmV3IFguZHYoYSl9LApkdjpmdW5j
-dGlvbiBkdihhKXt0aGlzLmE9YX19LE89ewpSaDpmdW5jdGlvbigpe3ZhciB0LHMscixxLHAsbyxuLG0s
-bCxrLGosaT1udWxsCmlmKFAudW8oKS5nRmkoKSE9PSJmaWxlIilyZXR1cm4gJC5FYigpCnQ9UC51bygp
-CmlmKCFDLnhCLlRjKHQuZ0lpKHQpLCIvIikpcmV0dXJuICQuRWIoKQpzPVAuUGkoaSwwLDApCnI9UC56
-UihpLDAsMCkKcT1QLk9lKGksMCwwLCExKQpwPVAubGUoaSwwLDAsaSkKbz1QLnRHKGksMCwwKQpuPVAu
-d0IoaSxzKQptPXM9PT0iZmlsZSIKaWYocT09bnVsbCl0PXIubGVuZ3RoIT09MHx8biE9bnVsbHx8bQpl
-bHNlIHQ9ITEKaWYodClxPSIiCnQ9cT09bnVsbApsPSF0Cms9UC5rYSgiYS9iIiwwLDMsaSxzLGwpCmo9
-cy5sZW5ndGg9PT0wCmlmKGomJnQmJiFDLnhCLm5DKGssIi8iKSlrPVAud0Yoaywhanx8bCkKZWxzZSBr
-PVAueGUoaykKaWYobmV3IFAuRG4ocyxyLHQmJkMueEIubkMoaywiLy8iKT8iIjpxLG4sayxwLG8pLnQ0
-KCk9PT0iYVxcYiIpcmV0dXJuICQuS2soKQpyZXR1cm4gJC5iRCgpfSwKT086ZnVuY3Rpb24gT08oKXt9
-fSxFPXtPRjpmdW5jdGlvbiBPRihhLGIsYyl7dGhpcy5kPWEKdGhpcy5lPWIKdGhpcy5mPWN9fSxGPXty
-dTpmdW5jdGlvbiBydShhLGIsYyxkKXt2YXIgXz10aGlzCl8uZD1hCl8uZT1iCl8uZj1jCl8ucj1kfX0s
-RD17ClJYOmZ1bmN0aW9uKCl7dmFyIHQscyxyPVAudW8oKQppZihKLlJNKHIsJC5JNikpcmV0dXJuICQu
-RmYKJC5JNj1yCmlmKCQuSGsoKT09JC5FYigpKXJldHVybiAkLkZmPXIuWkkoIi4iKS53KDApCmVsc2V7
-dD1yLnQ0KCkKcz10Lmxlbmd0aC0xCnJldHVybiAkLkZmPXM9PT0wP3Q6Qy54Qi5Oaih0LDAscyl9fSwK
-bnI6ZnVuY3Rpb24oYSxiKXt2YXIgdD1udWxsCnJldHVybiAkLm5VKCkucTcoMCxhLGIsdCx0LHQsdCx0
-LHQpfX0KdmFyIHc9W0MsSCxKLFAsVyxVLEIsVCxMLE0sWCxPLEUsRixEXQpodW5rSGVscGVycy5zZXRG
-dW5jdGlvbk5hbWVzSWZOZWNlc3NhcnkodykKdmFyICQ9e30KSC5lby5wcm90b3R5cGU9e30KSi52Qi5w
-cm90b3R5cGU9ewpETjpmdW5jdGlvbihhLGIpe3JldHVybiBhPT09Yn0sCmdpOmZ1bmN0aW9uKGEpe3Jl
-dHVybiBILmVRKGEpfSwKdzpmdW5jdGlvbihhKXtyZXR1cm4iSW5zdGFuY2Ugb2YgJyIrSC5kKEguTShh
-KSkrIicifSwKZTc6ZnVuY3Rpb24oYSxiKXt1Lm8uYihiKQp0aHJvdyBILmIoUC5scihhLGIuZ1dhKCks
-Yi5nbmQoKSxiLmdWbSgpKSl9fQpKLnlFLnByb3RvdHlwZT17Cnc6ZnVuY3Rpb24oYSl7cmV0dXJuIFN0
-cmluZyhhKX0sCmdpOmZ1bmN0aW9uKGEpe3JldHVybiBhPzUxOTAxODoyMTgxNTl9LAokaWEyOjF9Ckou
-WUUucHJvdG90eXBlPXsKRE46ZnVuY3Rpb24oYSxiKXtyZXR1cm4gbnVsbD09Yn0sCnc6ZnVuY3Rpb24o
-YSl7cmV0dXJuIm51bGwifSwKZ2k6ZnVuY3Rpb24oYSl7cmV0dXJuIDB9LAplNzpmdW5jdGlvbihhLGIp
-e3JldHVybiB0aGlzLlNqKGEsdS5vLmIoYikpfSwKJGljODoxfQpKLk1GLnByb3RvdHlwZT17CmdpOmZ1
-bmN0aW9uKGEpe3JldHVybiAwfSwKdzpmdW5jdGlvbihhKXtyZXR1cm4gU3RyaW5nKGEpfSwKJGl2bTox
-fQpKLmlDLnByb3RvdHlwZT17fQpKLmtkLnByb3RvdHlwZT17fQpKLmM1LnByb3RvdHlwZT17Cnc6ZnVu
-Y3Rpb24oYSl7dmFyIHQ9YVskLncoKV0KaWYodD09bnVsbClyZXR1cm4gdGhpcy50KGEpCnJldHVybiJK
-YXZhU2NyaXB0IGZ1bmN0aW9uIGZvciAiK0guZChKLmoodCkpfSwKJFM6ZnVuY3Rpb24oKXtyZXR1cm57
-ZnVuYzoxLG9wdDpbLCwsLCwsLCwsLCwsLCwsLF19fSwKJGlFSDoxfQpKLmpkLnByb3RvdHlwZT17CkE6
-ZnVuY3Rpb24oYSxiKXtILnQ2KGEpLmQuYihiKQppZighIWEuZml4ZWQkbGVuZ3RoKUguVmooUC5MNCgi
-YWRkIikpCmEucHVzaChiKX0sClc0OmZ1bmN0aW9uKGEsYil7dmFyIHQKaWYoISFhLmZpeGVkJGxlbmd0
-aClILlZqKFAuTDQoInJlbW92ZUF0IikpCnQ9YS5sZW5ndGgKaWYoYj49dCl0aHJvdyBILmIoUC54KGIs
-bnVsbCkpCnJldHVybiBhLnNwbGljZShiLDEpWzBdfSwKb0Y6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0LHMs
-cgpILnQ2KGEpLkMoImNYPDE+IikuYihjKQppZighIWEuZml4ZWQkbGVuZ3RoKUguVmooUC5MNCgiaW5z
-ZXJ0QWxsIikpCnQ9YS5sZW5ndGgKUC53QShiLDAsdCwiaW5kZXgiKQpzPWMubGVuZ3RoCnRoaXMuc2go
-YSx0K3MpCnI9YitzCnRoaXMuWVcoYSxyLGEubGVuZ3RoLGEsYikKdGhpcy52ZyhhLGIscixjKX0sCm12
-OmZ1bmN0aW9uKGEpe2lmKCEhYS5maXhlZCRsZW5ndGgpSC5WaihQLkw0KCJyZW1vdmVMYXN0IikpCmlm
-KGEubGVuZ3RoPT09MCl0aHJvdyBILmIoSC5IWShhLC0xKSkKcmV0dXJuIGEucG9wKCl9LApGVjpmdW5j
-dGlvbihhLGIpe3ZhciB0CkgudDYoYSkuQygiY1g8MT4iKS5iKGIpCmlmKCEhYS5maXhlZCRsZW5ndGgp
-SC5WaihQLkw0KCJhZGRBbGwiKSkKZm9yKHQ9Si5JVChiKTt0Lm0oKTspYS5wdXNoKHQuZ1IodCkpfSwK
-VTpmdW5jdGlvbihhLGIpe3ZhciB0LHMKSC50NihhKS5DKCJ+KDEpIikuYihiKQp0PWEubGVuZ3RoCmZv
-cihzPTA7czx0Oysrcyl7Yi4kMShhW3NdKQppZihhLmxlbmd0aCE9PXQpdGhyb3cgSC5iKFAuYTQoYSkp
-fX0sCkUyOmZ1bmN0aW9uKGEsYixjKXt2YXIgdD1ILnQ2KGEpCnJldHVybiBuZXcgSC5BOChhLHQuSyhj
-KS5DKCIxKDIpIikuYihiKSx0LkMoIkA8MT4iKS5LKGMpLkMoIkE4PDEsMj4iKSl9LAp6VjpmdW5jdGlv
-bihhLGIpe3ZhciB0LHM9bmV3IEFycmF5KGEubGVuZ3RoKQpzLmZpeGVkJGxlbmd0aD1BcnJheQpmb3Io
-dD0wO3Q8YS5sZW5ndGg7Kyt0KXRoaXMuWShzLHQsSC5kKGFbdF0pKQpyZXR1cm4gcy5qb2luKGIpfSwK
-TjA6ZnVuY3Rpb24oYSxiLGMsZCl7dmFyIHQscyxyCmQuYihiKQpILnQ2KGEpLksoZCkuQygiMSgxLDIp
-IikuYihjKQp0PWEubGVuZ3RoCmZvcihzPWIscj0wO3I8dDsrK3Ipe3M9Yy4kMihzLGFbcl0pCmlmKGEu
-bGVuZ3RoIT09dCl0aHJvdyBILmIoUC5hNChhKSl9cmV0dXJuIHN9LApXOmZ1bmN0aW9uKGEsYil7aWYo
-YjwwfHxiPj1hLmxlbmd0aClyZXR1cm4gSC5PSChhLGIpCnJldHVybiBhW2JdfSwKRDY6ZnVuY3Rpb24o
-YSxiLGMpe2lmKGI8MHx8Yj5hLmxlbmd0aCl0aHJvdyBILmIoUC5URShiLDAsYS5sZW5ndGgsInN0YXJ0
-IixudWxsKSkKaWYoYzxifHxjPmEubGVuZ3RoKXRocm93IEguYihQLlRFKGMsYixhLmxlbmd0aCwiZW5k
-IixudWxsKSkKaWYoYj09PWMpcmV0dXJuIEguVk0oW10sSC50NihhKSkKcmV0dXJuIEguVk0oYS5zbGlj
-ZShiLGMpLEgudDYoYSkpfSwKZ3RIOmZ1bmN0aW9uKGEpe2lmKGEubGVuZ3RoPjApcmV0dXJuIGFbMF0K
-dGhyb3cgSC5iKEguV3AoKSl9LApnclo6ZnVuY3Rpb24oYSl7dmFyIHQ9YS5sZW5ndGgKaWYodD4wKXJl
-dHVybiBhW3QtMV0KdGhyb3cgSC5iKEguV3AoKSl9LApZVzpmdW5jdGlvbihhLGIsYyxkLGUpe3ZhciB0
-LHMscj1ILnQ2KGEpCnIuQygiY1g8MT4iKS5iKGQpCmlmKCEhYS5pbW11dGFibGUkbGlzdClILlZqKFAu
-TDQoInNldFJhbmdlIikpClAuakIoYixjLGEubGVuZ3RoKQp0PWMtYgppZih0PT09MClyZXR1cm4KUC5r
-MShlLCJza2lwQ291bnQiKQpyLkMoInpNPDE+IikuYihkKQpyPUouVTYoZCkKaWYoZSt0PnIuZ2goZCkp
-dGhyb3cgSC5iKEguYXIoKSkKaWYoZTxiKWZvcihzPXQtMTtzPj0wOy0tcylhW2Irc109ci5xKGQsZStz
-KQplbHNlIGZvcihzPTA7czx0OysrcylhW2Irc109ci5xKGQsZStzKX0sCnZnOmZ1bmN0aW9uKGEsYixj
-LGQpe3JldHVybiB0aGlzLllXKGEsYixjLGQsMCl9LApWcjpmdW5jdGlvbihhLGIpe3ZhciB0LHMKSC50
-NihhKS5DKCJhMigxKSIpLmIoYikKdD1hLmxlbmd0aApmb3Iocz0wO3M8dDsrK3Mpe2lmKEgub1QoYi4k
-MShhW3NdKSkpcmV0dXJuITAKaWYoYS5sZW5ndGghPT10KXRocm93IEguYihQLmE0KGEpKX1yZXR1cm4h
-MX0sCnRnOmZ1bmN0aW9uKGEsYil7dmFyIHQKZm9yKHQ9MDt0PGEubGVuZ3RoOysrdClpZihKLlJNKGFb
-dF0sYikpcmV0dXJuITAKcmV0dXJuITF9LAp3OmZ1bmN0aW9uKGEpe3JldHVybiBQLldFKGEsIlsiLCJd
-Iil9LApna3o6ZnVuY3Rpb24oYSl7cmV0dXJuIG5ldyBKLm0xKGEsYS5sZW5ndGgsSC50NihhKS5DKCJt
-MTwxPiIpKX0sCmdpOmZ1bmN0aW9uKGEpe3JldHVybiBILmVRKGEpfSwKZ2g6ZnVuY3Rpb24oYSl7cmV0
-dXJuIGEubGVuZ3RofSwKc2g6ZnVuY3Rpb24oYSxiKXtpZighIWEuZml4ZWQkbGVuZ3RoKUguVmooUC5M
-NCgic2V0IGxlbmd0aCIpKQppZihiPDApdGhyb3cgSC5iKFAuVEUoYiwwLG51bGwsIm5ld0xlbmd0aCIs
-bnVsbCkpCmEubGVuZ3RoPWJ9LApxOmZ1bmN0aW9uKGEsYil7SC5TYyhiKQppZihiPj1hLmxlbmd0aHx8
-YjwwKXRocm93IEguYihILkhZKGEsYikpCnJldHVybiBhW2JdfSwKWTpmdW5jdGlvbihhLGIsYyl7SC5T
-YyhiKQpILnQ2KGEpLmQuYihjKQppZighIWEuaW1tdXRhYmxlJGxpc3QpSC5WaihQLkw0KCJpbmRleGVk
-IHNldCIpKQppZighSC5vayhiKSl0aHJvdyBILmIoSC5IWShhLGIpKQppZihiPj1hLmxlbmd0aHx8Yjww
-KXRocm93IEguYihILkhZKGEsYikpCmFbYl09Y30sCiRpYlE6MSwKJGljWDoxLAokaXpNOjF9CkouUG8u
-cHJvdG90eXBlPXt9CkoubTEucHJvdG90eXBlPXsKZ1I6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuZH0s
-Cm06ZnVuY3Rpb24oKXt2YXIgdCxzPXRoaXMscj1zLmEscT1yLmxlbmd0aAppZihzLmIhPT1xKXRocm93
-IEguYihILmxrKHIpKQp0PXMuYwppZih0Pj1xKXtzLnNNKG51bGwpCnJldHVybiExfXMuc00oclt0XSk7
-KytzLmMKcmV0dXJuITB9LApzTTpmdW5jdGlvbihhKXt0aGlzLmQ9dGhpcy4kdGkuZC5iKGEpfSwKJGlB
-bjoxfQpKLnFJLnByb3RvdHlwZT17Cnl1OmZ1bmN0aW9uKGEpe3ZhciB0CmlmKGE+PS0yMTQ3NDgzNjQ4
-JiZhPD0yMTQ3NDgzNjQ3KXJldHVybiBhfDAKaWYoaXNGaW5pdGUoYSkpe3Q9YTwwP01hdGguY2VpbChh
-KTpNYXRoLmZsb29yKGEpCnJldHVybiB0KzB9dGhyb3cgSC5iKFAuTDQoIiIrYSsiLnRvSW50KCkiKSl9
-LAp6UTpmdW5jdGlvbihhKXtpZihhPjApe2lmKGEhPT0xLzApcmV0dXJuIE1hdGgucm91bmQoYSl9ZWxz
-ZSBpZihhPi0xLzApcmV0dXJuIDAtTWF0aC5yb3VuZCgwLWEpCnRocm93IEguYihQLkw0KCIiK2ErIi5y
-b3VuZCgpIikpfSwKRDg6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzLHIscQppZihiPDJ8fGI+MzYpdGhyb3cg
-SC5iKFAuVEUoYiwyLDM2LCJyYWRpeCIsbnVsbCkpCnQ9YS50b1N0cmluZyhiKQppZihDLnhCLk8yKHQs
-dC5sZW5ndGgtMSkhPT00MSlyZXR1cm4gdApzPS9eKFtcZGEtel0rKSg/OlwuKFtcZGEtel0rKSk/XChl
-XCsoXGQrKVwpJC8uZXhlYyh0KQppZihzPT1udWxsKUguVmooUC5MNCgiVW5leHBlY3RlZCB0b1N0cmlu
-ZyByZXN1bHQ6ICIrdCkpCnI9cy5sZW5ndGgKaWYoMT49cilyZXR1cm4gSC5PSChzLDEpCnQ9c1sxXQpp
-ZigzPj1yKXJldHVybiBILk9IKHMsMykKcT0rc1szXQpyPXNbMl0KaWYociE9bnVsbCl7dCs9cgpxLT1y
-Lmxlbmd0aH1yZXR1cm4gdCtDLnhCLkl4KCIwIixxKX0sCnc6ZnVuY3Rpb24oYSl7aWYoYT09PTAmJjEv
-YTwwKXJldHVybiItMC4wIgplbHNlIHJldHVybiIiK2F9LApnaTpmdW5jdGlvbihhKXt2YXIgdCxzLHIs
-cSxwPWF8MAppZihhPT09cClyZXR1cm4gNTM2ODcwOTExJnAKdD1NYXRoLmFicyhhKQpzPU1hdGgubG9n
-KHQpLzAuNjkzMTQ3MTgwNTU5OTQ1M3wwCnI9TWF0aC5wb3coMixzKQpxPXQ8MT90L3I6ci90CnJldHVy
-biA1MzY4NzA5MTEmKChxKjkwMDcxOTkyNTQ3NDA5OTJ8MCkrKHEqMzU0MjI0MzE4MTE3NjUyMXwwKSkq
-NTk5MTk3K3MqMTI1OX0sCnpZOmZ1bmN0aW9uKGEsYil7dmFyIHQ9YSViCmlmKHQ9PT0wKXJldHVybiAw
-CmlmKHQ+MClyZXR1cm4gdAppZihiPDApcmV0dXJuIHQtYgplbHNlIHJldHVybiB0K2J9LAp3RzpmdW5j
-dGlvbihhLGIpe3ZhciB0CmlmKGE+MCl0PXRoaXMucDMoYSxiKQplbHNle3Q9Yj4zMT8zMTpiCnQ9YT4+
-dD4+PjB9cmV0dXJuIHR9LApiZjpmdW5jdGlvbihhLGIpe2lmKGI8MCl0aHJvdyBILmIoSC50TChiKSkK
-cmV0dXJuIHRoaXMucDMoYSxiKX0sCnAzOmZ1bmN0aW9uKGEsYil7cmV0dXJuIGI+MzE/MDphPj4+Yn0s
-CiRpQ1A6MSwKJGlGSzoxfQpKLnVyLnByb3RvdHlwZT17JGlLTjoxfQpKLlZBLnByb3RvdHlwZT17fQpK
-LkRyLnByb3RvdHlwZT17Ck8yOmZ1bmN0aW9uKGEsYil7aWYoYjwwKXRocm93IEguYihILkhZKGEsYikp
-CmlmKGI+PWEubGVuZ3RoKUguVmooSC5IWShhLGIpKQpyZXR1cm4gYS5jaGFyQ29kZUF0KGIpfSwKV2Q6
-ZnVuY3Rpb24oYSxiKXtpZihiPj1hLmxlbmd0aCl0aHJvdyBILmIoSC5IWShhLGIpKQpyZXR1cm4gYS5j
-aGFyQ29kZUF0KGIpfSwKZGQ6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gbmV3IEgudW4oYixhLDApfSwKVDpm
-dW5jdGlvbihhLGIpe2lmKHR5cGVvZiBiIT0ic3RyaW5nIil0aHJvdyBILmIoUC5MMyhiLG51bGwsbnVs
-bCkpCnJldHVybiBhK2J9LApUYzpmdW5jdGlvbihhLGIpe3ZhciB0PWIubGVuZ3RoLHM9YS5sZW5ndGgK
-aWYodD5zKXJldHVybiExCnJldHVybiBiPT09dGhpcy55bihhLHMtdCl9LAppNzpmdW5jdGlvbihhLGIs
-YyxkKXt2YXIgdCxzCmM9UC5qQihiLGMsYS5sZW5ndGgpCnQ9YS5zdWJzdHJpbmcoMCxiKQpzPWEuc3Vi
-c3RyaW5nKGMpCnJldHVybiB0K2Qrc30sClFpOmZ1bmN0aW9uKGEsYixjKXt2YXIgdAppZighSC5vayhj
-KSlILlZqKEgudEwoYykpCmlmKHR5cGVvZiBjIT09Im51bWJlciIpcmV0dXJuIGMuSigpCmlmKGM8MHx8
-Yz5hLmxlbmd0aCl0aHJvdyBILmIoUC5URShjLDAsYS5sZW5ndGgsbnVsbCxudWxsKSkKdD1jK2IubGVu
-Z3RoCmlmKHQ+YS5sZW5ndGgpcmV0dXJuITEKcmV0dXJuIGI9PT1hLnN1YnN0cmluZyhjLHQpfSwKbkM6
-ZnVuY3Rpb24oYSxiKXtyZXR1cm4gdGhpcy5RaShhLGIsMCl9LApOajpmdW5jdGlvbihhLGIsYyl7aWYo
-IUgub2soYikpSC5WaihILnRMKGIpKQppZihjPT1udWxsKWM9YS5sZW5ndGgKaWYodHlwZW9mIGIhPT0i
-bnVtYmVyIilyZXR1cm4gYi5KKCkKaWYoYjwwKXRocm93IEguYihQLngoYixudWxsKSkKaWYoYj5jKXRo
-cm93IEguYihQLngoYixudWxsKSkKaWYoYz5hLmxlbmd0aCl0aHJvdyBILmIoUC54KGMsbnVsbCkpCnJl
-dHVybiBhLnN1YnN0cmluZyhiLGMpfSwKeW46ZnVuY3Rpb24oYSxiKXtyZXR1cm4gdGhpcy5OaihhLGIs
-bnVsbCl9LApoYzpmdW5jdGlvbihhKXtyZXR1cm4gYS50b0xvd2VyQ2FzZSgpfSwKYlM6ZnVuY3Rpb24o
-YSl7dmFyIHQscyxyLHE9YS50cmltKCkscD1xLmxlbmd0aAppZihwPT09MClyZXR1cm4gcQppZih0aGlz
-LldkKHEsMCk9PT0xMzMpe3Q9Si5tbShxLDEpCmlmKHQ9PT1wKXJldHVybiIifWVsc2UgdD0wCnM9cC0x
-CnI9dGhpcy5PMihxLHMpPT09MTMzP0ouYzEocSxzKTpwCmlmKHQ9PT0wJiZyPT09cClyZXR1cm4gcQpy
-ZXR1cm4gcS5zdWJzdHJpbmcodCxyKX0sCkl4OmZ1bmN0aW9uKGEsYil7dmFyIHQscwppZigwPj1iKXJl
-dHVybiIiCmlmKGI9PT0xfHxhLmxlbmd0aD09PTApcmV0dXJuIGEKaWYoYiE9PWI+Pj4wKXRocm93IEgu
-YihDLkVxKQpmb3IodD1hLHM9IiI7ITA7KXtpZigoYiYxKT09PTEpcz10K3MKYj1iPj4+MQppZihiPT09
-MClicmVhawp0Kz10fXJldHVybiBzfSwKWFU6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0CmlmKGM8MHx8Yz5h
-Lmxlbmd0aCl0aHJvdyBILmIoUC5URShjLDAsYS5sZW5ndGgsbnVsbCxudWxsKSkKdD1hLmluZGV4T2Yo
-YixjKQpyZXR1cm4gdH0sCk9ZOmZ1bmN0aW9uKGEsYil7cmV0dXJuIHRoaXMuWFUoYSxiLDApfSwKUGs6
-ZnVuY3Rpb24oYSxiLGMpe3ZhciB0LHMKaWYoYz09bnVsbCljPWEubGVuZ3RoCmVsc2UgaWYoYzwwfHxj
-PmEubGVuZ3RoKXRocm93IEguYihQLlRFKGMsMCxhLmxlbmd0aCxudWxsLG51bGwpKQp0PWIubGVuZ3Ro
-CnM9YS5sZW5ndGgKaWYoYyt0PnMpYz1zLXQKcmV0dXJuIGEubGFzdEluZGV4T2YoYixjKX0sCmNuOmZ1
-bmN0aW9uKGEsYil7cmV0dXJuIHRoaXMuUGsoYSxiLG51bGwpfSwKSXM6ZnVuY3Rpb24oYSxiLGMpe3Zh
-ciB0PWEubGVuZ3RoCmlmKGM+dCl0aHJvdyBILmIoUC5URShjLDAsdCxudWxsLG51bGwpKQpyZXR1cm4g
-SC5tMihhLGIsYyl9LAp0ZzpmdW5jdGlvbihhLGIpe3JldHVybiB0aGlzLklzKGEsYiwwKX0sCnc6ZnVu
-Y3Rpb24oYSl7cmV0dXJuIGF9LApnaTpmdW5jdGlvbihhKXt2YXIgdCxzLHIKZm9yKHQ9YS5sZW5ndGgs
-cz0wLHI9MDtyPHQ7KytyKXtzPTUzNjg3MDkxMSZzK2EuY2hhckNvZGVBdChyKQpzPTUzNjg3MDkxMSZz
-KygoNTI0Mjg3JnMpPDwxMCkKc149cz4+Nn1zPTUzNjg3MDkxMSZzKygoNjcxMDg4NjMmcyk8PDMpCnNe
-PXM+PjExCnJldHVybiA1MzY4NzA5MTEmcysoKDE2MzgzJnMpPDwxNSl9LApnaDpmdW5jdGlvbihhKXty
-ZXR1cm4gYS5sZW5ndGh9LApxOmZ1bmN0aW9uKGEsYil7SC5TYyhiKQppZihiPj1hLmxlbmd0aHx8ITEp
-dGhyb3cgSC5iKEguSFkoYSxiKSkKcmV0dXJuIGFbYl19LAokaXZYOjEsCiRpcVU6MX0KSC5xai5wcm90
-b3R5cGU9ewpnaDpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5hLmxlbmd0aH0sCnE6ZnVuY3Rpb24oYSxi
-KXtyZXR1cm4gQy54Qi5PMih0aGlzLmEsSC5TYyhiKSl9fQpILmJRLnByb3RvdHlwZT17fQpILmFMLnBy
-b3RvdHlwZT17CmdrejpmdW5jdGlvbihhKXt2YXIgdD10aGlzCnJldHVybiBuZXcgSC5hNyh0LHQuZ2go
-dCksSC5MaCh0KS5DKCJhNzxhTC5FPiIpKX0sCnpWOmZ1bmN0aW9uKGEsYil7dmFyIHQscyxyLHE9dGhp
-cyxwPXEuZ2gocSkKaWYoYi5sZW5ndGghPT0wKXtpZihwPT09MClyZXR1cm4iIgp0PUguZChxLlcoMCww
-KSkKaWYocCE9PXEuZ2gocSkpdGhyb3cgSC5iKFAuYTQocSkpCmZvcihzPXQscj0xO3I8cDsrK3Ipe3M9
-cytiK0guZChxLlcoMCxyKSkKaWYocCE9PXEuZ2gocSkpdGhyb3cgSC5iKFAuYTQocSkpfXJldHVybiBz
-LmNoYXJDb2RlQXQoMCk9PTA/czpzfWVsc2V7Zm9yKHI9MCxzPSIiO3I8cDsrK3Ipe3MrPUguZChxLlco
-MCxyKSkKaWYocCE9PXEuZ2gocSkpdGhyb3cgSC5iKFAuYTQocSkpfXJldHVybiBzLmNoYXJDb2RlQXQo
-MCk9PTA/czpzfX0sCmV2OmZ1bmN0aW9uKGEsYil7cmV0dXJuIHRoaXMuR0coMCxILkxoKHRoaXMpLkMo
-ImEyKGFMLkUpIikuYihiKSl9LApFMjpmdW5jdGlvbihhLGIsYyl7dmFyIHQ9SC5MaCh0aGlzKQpyZXR1
-cm4gbmV3IEguQTgodGhpcyx0LksoYykuQygiMShhTC5FKSIpLmIoYiksdC5DKCJAPGFMLkU+IikuSyhj
-KS5DKCJBODwxLDI+IikpfX0KSC5uSC5wcm90b3R5cGU9ewpnVUQ6ZnVuY3Rpb24oKXt2YXIgdD1KLkht
-KHRoaXMuYSkscz10aGlzLmMKaWYocz09bnVsbHx8cz50KXJldHVybiB0CnJldHVybiBzfSwKZ0FzOmZ1
-bmN0aW9uKCl7dmFyIHQ9Si5IbSh0aGlzLmEpLHM9dGhpcy5iCmlmKHM+dClyZXR1cm4gdApyZXR1cm4g
-c30sCmdoOmZ1bmN0aW9uKGEpe3ZhciB0LHM9Si5IbSh0aGlzLmEpLHI9dGhpcy5iCmlmKHI+PXMpcmV0
-dXJuIDAKdD10aGlzLmMKaWYodD09bnVsbHx8dD49cylyZXR1cm4gcy1yCmlmKHR5cGVvZiB0IT09Im51
-bWJlciIpcmV0dXJuIHQuSE4oKQpyZXR1cm4gdC1yfSwKVzpmdW5jdGlvbihhLGIpe3ZhciB0LHM9dGhp
-cyxyPXMuZ0FzKCkrYgppZihiPj0wKXt0PXMuZ1VEKCkKaWYodHlwZW9mIHQhPT0ibnVtYmVyIilyZXR1
-cm4gSC5wWSh0KQp0PXI+PXR9ZWxzZSB0PSEwCmlmKHQpdGhyb3cgSC5iKFAuQ2YoYixzLCJpbmRleCIs
-bnVsbCxudWxsKSkKcmV0dXJuIEouR0Eocy5hLHIpfX0KSC5hNy5wcm90b3R5cGU9ewpnUjpmdW5jdGlv
-bihhKXtyZXR1cm4gdGhpcy5kfSwKbTpmdW5jdGlvbigpe3ZhciB0LHM9dGhpcyxyPXMuYSxxPUouVTYo
-cikscD1xLmdoKHIpCmlmKHMuYiE9PXApdGhyb3cgSC5iKFAuYTQocikpCnQ9cy5jCmlmKHQ+PXApe3Mu
-c0kobnVsbCkKcmV0dXJuITF9cy5zSShxLlcocix0KSk7KytzLmMKcmV0dXJuITB9LApzSTpmdW5jdGlv
-bihhKXt0aGlzLmQ9dGhpcy4kdGkuZC5iKGEpfSwKJGlBbjoxfQpILmkxLnByb3RvdHlwZT17Cmdrejpm
-dW5jdGlvbihhKXt2YXIgdD1ILkxoKHRoaXMpCnJldHVybiBuZXcgSC5NSChKLklUKHRoaXMuYSksdGhp
-cy5iLHQuQygiQDwxPiIpLksodC5jaFsxXSkuQygiTUg8MSwyPiIpKX0sCmdoOmZ1bmN0aW9uKGEpe3Jl
-dHVybiBKLkhtKHRoaXMuYSl9fQpILnh5LnByb3RvdHlwZT17JGliUToxfQpILk1ILnByb3RvdHlwZT17
-Cm06ZnVuY3Rpb24oKXt2YXIgdD10aGlzLHM9dC5iCmlmKHMubSgpKXt0LnNJKHQuYy4kMShzLmdSKHMp
-KSkKcmV0dXJuITB9dC5zSShudWxsKQpyZXR1cm4hMX0sCmdSOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlz
-LmF9LApzSTpmdW5jdGlvbihhKXt0aGlzLmE9dGhpcy4kdGkuY2hbMV0uYihhKX19CkguQTgucHJvdG90
-eXBlPXsKZ2g6ZnVuY3Rpb24oYSl7cmV0dXJuIEouSG0odGhpcy5hKX0sClc6ZnVuY3Rpb24oYSxiKXty
-ZXR1cm4gdGhpcy5iLiQxKEouR0EodGhpcy5hLGIpKX19CkguVTUucHJvdG90eXBlPXsKZ2t6OmZ1bmN0
-aW9uKGEpe3JldHVybiBuZXcgSC5TTyhKLklUKHRoaXMuYSksdGhpcy5iLHRoaXMuJHRpLkMoIlNPPDE+
-IikpfX0KSC5TTy5wcm90b3R5cGU9ewptOmZ1bmN0aW9uKCl7dmFyIHQscwpmb3IodD10aGlzLmEscz10
-aGlzLmI7dC5tKCk7KWlmKEgub1Qocy4kMSh0LmdSKHQpKSkpcmV0dXJuITAKcmV0dXJuITF9LApnUjpm
-dW5jdGlvbihhKXt2YXIgdD10aGlzLmEKcmV0dXJuIHQuZ1IodCl9fQpILlNVLnByb3RvdHlwZT17fQpI
-LlJlLnByb3RvdHlwZT17Clk6ZnVuY3Rpb24oYSxiLGMpe0guU2MoYikKSC5MaCh0aGlzKS5DKCJSZS5F
-IikuYihjKQp0aHJvdyBILmIoUC5MNCgiQ2Fubm90IG1vZGlmeSBhbiB1bm1vZGlmaWFibGUgbGlzdCIp
-KX19CkguWEMucHJvdG90eXBlPXt9Ckgud3YucHJvdG90eXBlPXsKZ2k6ZnVuY3Rpb24oYSl7dmFyIHQ9
-dGhpcy5faGFzaENvZGUKaWYodCE9bnVsbClyZXR1cm4gdAp0PTUzNjg3MDkxMSY2NjQ1OTcqSi5oZih0
-aGlzLmEpCnRoaXMuX2hhc2hDb2RlPXQKcmV0dXJuIHR9LAp3OmZ1bmN0aW9uKGEpe3JldHVybidTeW1i
-b2woIicrSC5kKHRoaXMuYSkrJyIpJ30sCkROOmZ1bmN0aW9uKGEsYil7aWYoYj09bnVsbClyZXR1cm4h
-MQpyZXR1cm4gYiBpbnN0YW5jZW9mIEgud3YmJnRoaXMuYT09Yi5hfSwKJGlHRDoxfQpILlBELnByb3Rv
-dHlwZT17fQpILldVLnByb3RvdHlwZT17Cnc6ZnVuY3Rpb24oYSl7cmV0dXJuIFAubk8odGhpcyl9LApZ
-OmZ1bmN0aW9uKGEsYixjKXt2YXIgdD1ILkxoKHRoaXMpCnQuZC5iKGIpCnQuY2hbMV0uYihjKQpyZXR1
-cm4gSC5kYygpfSwKZ1B1OmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLnE0KGEsSC5MaCh0aGlzKS5DKCJO
-MzwxLDI+IikpfSwKcTQ6ZnVuY3Rpb24oYSxiKXt2YXIgdD10aGlzCnJldHVybiBQLmwwKGZ1bmN0aW9u
-KCl7dmFyIHM9YQp2YXIgcj0wLHE9MSxwLG8sbixtCnJldHVybiBmdW5jdGlvbiAkYXN5bmMkZ1B1KGMs
-ZCl7aWYoYz09PTEpe3A9ZApyPXF9d2hpbGUodHJ1ZSlzd2l0Y2gocil7Y2FzZSAwOm89dC5ndih0KSxv
-PW8uZ2t6KG8pLG49SC5MaCh0KSxuPW4uQygiQDwxPiIpLksobi5jaFsxXSkuQygiTjM8MSwyPiIpCmNh
-c2UgMjppZighby5tKCkpe3I9MwpicmVha31tPW8uZ1IobykKcj00CnJldHVybiBuZXcgUC5OMyhtLHQu
-cSgwLG0pLG4pCmNhc2UgNDpyPTIKYnJlYWsKY2FzZSAzOnJldHVybiBQLlRoKCkKY2FzZSAxOnJldHVy
-biBQLlltKHApfX19LGIpfSwKJGlaMDoxfQpILkxQLnByb3RvdHlwZT17CmdoOmZ1bmN0aW9uKGEpe3Jl
-dHVybiB0aGlzLmF9LAp4NDpmdW5jdGlvbihhLGIpe2lmKHR5cGVvZiBiIT0ic3RyaW5nIilyZXR1cm4h
-MQppZigiX19wcm90b19fIj09PWIpcmV0dXJuITEKcmV0dXJuIHRoaXMuYi5oYXNPd25Qcm9wZXJ0eShi
-KX0sCnE6ZnVuY3Rpb24oYSxiKXtpZighdGhpcy54NCgwLGIpKXJldHVybiBudWxsCnJldHVybiB0aGlz
-LkQoYil9LApEOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLmJbSC55KGEpXX0sClU6ZnVuY3Rpb24oYSxi
-KXt2YXIgdCxzLHIscSxwPUguTGgodGhpcykKcC5DKCJ+KDEsMikiKS5iKGIpCnQ9dGhpcy5jCmZvcihz
-PXQubGVuZ3RoLHA9cC5jaFsxXSxyPTA7cjxzOysrcil7cT10W3JdCmIuJDIocSxwLmIodGhpcy5EKHEp
-KSl9fSwKZ3Y6ZnVuY3Rpb24oYSl7cmV0dXJuIG5ldyBILlhSKHRoaXMsSC5MaCh0aGlzKS5DKCJYUjwx
-PiIpKX19CkguWFIucHJvdG90eXBlPXsKZ2t6OmZ1bmN0aW9uKGEpe3ZhciB0PXRoaXMuYS5jCnJldHVy
-biBuZXcgSi5tMSh0LHQubGVuZ3RoLEgudDYodCkuQygibTE8MT4iKSl9LApnaDpmdW5jdGlvbihhKXty
-ZXR1cm4gdGhpcy5hLmMubGVuZ3RofX0KSC5MSS5wcm90b3R5cGU9ewpnV2E6ZnVuY3Rpb24oKXt2YXIg
-dD10aGlzLmEKcmV0dXJuIHR9LApnbmQ6ZnVuY3Rpb24oKXt2YXIgdCxzLHIscSxwPXRoaXMKaWYocC5j
-PT09MSlyZXR1cm4gQy5kbgp0PXAuZApzPXQubGVuZ3RoLXAuZS5sZW5ndGgtcC5mCmlmKHM9PT0wKXJl
-dHVybiBDLmRuCnI9W10KZm9yKHE9MDtxPHM7KytxKXtpZihxPj10Lmxlbmd0aClyZXR1cm4gSC5PSCh0
-LHEpCnIucHVzaCh0W3FdKX1yZXR1cm4gSi56QyhyKX0sCmdWbTpmdW5jdGlvbigpe3ZhciB0LHMscixx
-LHAsbyxuLG0sbD10aGlzCmlmKGwuYyE9PTApcmV0dXJuIEMuRHgKdD1sLmUKcz10Lmxlbmd0aApyPWwu
-ZApxPXIubGVuZ3RoLXMtbC5mCmlmKHM9PT0wKXJldHVybiBDLkR4CnA9bmV3IEguTjUodS5lbykKZm9y
-KG89MDtvPHM7KytvKXtpZihvPj10Lmxlbmd0aClyZXR1cm4gSC5PSCh0LG8pCm49dFtvXQptPXErbwpp
-ZihtPDB8fG0+PXIubGVuZ3RoKXJldHVybiBILk9IKHIsbSkKcC5ZKDAsbmV3IEgud3YobiksclttXSl9
-cmV0dXJuIG5ldyBILlBEKHAsdS5nRil9LAokaXZROjF9CkguQ2oucHJvdG90eXBlPXsKJDI6ZnVuY3Rp
-b24oYSxiKXt2YXIgdApILnkoYSkKdD10aGlzLmEKdC5iPXQuYisiJCIrSC5kKGEpCkMuTm0uQSh0aGlz
-LmIsYSkKQy5ObS5BKHRoaXMuYyxiKTsrK3QuYX0sCiRTOjEzfQpILmY5LnByb3RvdHlwZT17CnFTOmZ1
-bmN0aW9uKGEpe3ZhciB0LHMscj10aGlzLHE9bmV3IFJlZ0V4cChyLmEpLmV4ZWMoYSkKaWYocT09bnVs
-bClyZXR1cm4gbnVsbAp0PU9iamVjdC5jcmVhdGUobnVsbCkKcz1yLmIKaWYocyE9PS0xKXQuYXJndW1l
-bnRzPXFbcysxXQpzPXIuYwppZihzIT09LTEpdC5hcmd1bWVudHNFeHByPXFbcysxXQpzPXIuZAppZihz
-IT09LTEpdC5leHByPXFbcysxXQpzPXIuZQppZihzIT09LTEpdC5tZXRob2Q9cVtzKzFdCnM9ci5mCmlm
-KHMhPT0tMSl0LnJlY2VpdmVyPXFbcysxXQpyZXR1cm4gdH19CkguVzAucHJvdG90eXBlPXsKdzpmdW5j
-dGlvbihhKXt2YXIgdD10aGlzLmIKaWYodD09bnVsbClyZXR1cm4iTm9TdWNoTWV0aG9kRXJyb3I6ICIr
-SC5kKHRoaXMuYSkKcmV0dXJuIk5vU3VjaE1ldGhvZEVycm9yOiBtZXRob2Qgbm90IGZvdW5kOiAnIit0
-KyInIG9uIG51bGwifX0KSC5hei5wcm90b3R5cGU9ewp3OmZ1bmN0aW9uKGEpe3ZhciB0LHM9dGhpcyxy
-PSJOb1N1Y2hNZXRob2RFcnJvcjogbWV0aG9kIG5vdCBmb3VuZDogJyIscT1zLmIKaWYocT09bnVsbCly
-ZXR1cm4iTm9TdWNoTWV0aG9kRXJyb3I6ICIrSC5kKHMuYSkKdD1zLmMKaWYodD09bnVsbClyZXR1cm4g
-citxKyInICgiK0guZChzLmEpKyIpIgpyZXR1cm4gcitxKyInIG9uICciK3QrIicgKCIrSC5kKHMuYSkr
-IikifX0KSC52Vi5wcm90b3R5cGU9ewp3OmZ1bmN0aW9uKGEpe3ZhciB0PXRoaXMuYQpyZXR1cm4gdC5s
-ZW5ndGg9PT0wPyJFcnJvciI6IkVycm9yOiAiK3R9fQpILmJxLnByb3RvdHlwZT17fQpILkFtLnByb3Rv
-dHlwZT17CiQxOmZ1bmN0aW9uKGEpe2lmKHUuYlUuYyhhKSlpZihhLiR0aHJvd25Kc0Vycm9yPT1udWxs
-KWEuJHRocm93bkpzRXJyb3I9dGhpcy5hCnJldHVybiBhfSwKJFM6NH0KSC5YTy5wcm90b3R5cGU9ewp3
-OmZ1bmN0aW9uKGEpe3ZhciB0LHM9dGhpcy5iCmlmKHMhPW51bGwpcmV0dXJuIHMKcz10aGlzLmEKdD1z
-IT09bnVsbCYmdHlwZW9mIHM9PT0ib2JqZWN0Ij9zLnN0YWNrOm51bGwKcmV0dXJuIHRoaXMuYj10PT1u
-dWxsPyIiOnR9LAokaUd6OjF9CkguVHAucHJvdG90eXBlPXsKdzpmdW5jdGlvbihhKXt2YXIgdD10aGlz
-LmNvbnN0cnVjdG9yLHM9dD09bnVsbD9udWxsOnQubmFtZQpyZXR1cm4iQ2xvc3VyZSAnIitILk5RKHM9
-PW51bGw/InVua25vd24iOnMpKyInIn0sCiRpRUg6MSwKZ1FsOmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXN9
-LAokQzoiJDEiLAokUjoxLAokRDpudWxsfQpILmxjLnByb3RvdHlwZT17fQpILnp4LnByb3RvdHlwZT17
-Cnc6ZnVuY3Rpb24oYSl7dmFyIHQ9dGhpcy4kc3RhdGljX25hbWUKaWYodD09bnVsbClyZXR1cm4iQ2xv
-c3VyZSBvZiB1bmtub3duIHN0YXRpYyBtZXRob2QiCnJldHVybiJDbG9zdXJlICciK0guTlEodCkrIici
-fX0KSC5yVC5wcm90b3R5cGU9ewpETjpmdW5jdGlvbihhLGIpe3ZhciB0PXRoaXMKaWYoYj09bnVsbCly
-ZXR1cm4hMQppZih0PT09YilyZXR1cm4hMAppZighKGIgaW5zdGFuY2VvZiBILnJUKSlyZXR1cm4hMQpy
-ZXR1cm4gdC5hPT09Yi5hJiZ0LmI9PT1iLmImJnQuYz09PWIuY30sCmdpOmZ1bmN0aW9uKGEpe3ZhciB0
-LHM9dGhpcy5jCmlmKHM9PW51bGwpdD1ILmVRKHRoaXMuYSkKZWxzZSB0PXR5cGVvZiBzIT09Im9iamVj
-dCI/Si5oZihzKTpILmVRKHMpCnJldHVybih0XkguZVEodGhpcy5iKSk+Pj4wfSwKdzpmdW5jdGlvbihh
-KXt2YXIgdD10aGlzLmMKaWYodD09bnVsbCl0PXRoaXMuYQpyZXR1cm4iQ2xvc3VyZSAnIitILmQodGhp
-cy5kKSsiJyBvZiAiKygiSW5zdGFuY2Ugb2YgJyIrSC5kKEguTSh0KSkrIiciKX19CkguRXEucHJvdG90
-eXBlPXsKdzpmdW5jdGlvbihhKXtyZXR1cm4iUnVudGltZUVycm9yOiAiK0guZCh0aGlzLmEpfX0KSC5r
-WS5wcm90b3R5cGU9ewp3OmZ1bmN0aW9uKGEpe3JldHVybiJBc3NlcnRpb24gZmFpbGVkOiAiK1AucCh0
-aGlzLmEpfX0KSC5ONS5wcm90b3R5cGU9ewpnaDpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5hfSwKZ3Y6
-ZnVuY3Rpb24oYSl7cmV0dXJuIG5ldyBILmk1KHRoaXMsSC5MaCh0aGlzKS5DKCJpNTwxPiIpKX0sCng0
-OmZ1bmN0aW9uKGEsYil7dmFyIHQscwppZih0eXBlb2YgYj09InN0cmluZyIpe3Q9dGhpcy5iCmlmKHQ9
-PW51bGwpcmV0dXJuITEKcmV0dXJuIHRoaXMuWHUodCxiKX1lbHNle3M9dGhpcy5DWChiKQpyZXR1cm4g
-c319LApDWDpmdW5jdGlvbihhKXt2YXIgdD10aGlzLmQKaWYodD09bnVsbClyZXR1cm4hMQpyZXR1cm4g
-dGhpcy5GKHRoaXMuSCh0LEouaGYoYSkmMHgzZmZmZmZmKSxhKT49MH0sCnE6ZnVuY3Rpb24oYSxiKXt2
-YXIgdCxzLHIscSxwPXRoaXMsbz1udWxsCmlmKHR5cGVvZiBiPT0ic3RyaW5nIil7dD1wLmIKaWYodD09
-bnVsbClyZXR1cm4gbwpzPXAuaih0LGIpCnI9cz09bnVsbD9vOnMuYgpyZXR1cm4gcn1lbHNlIGlmKHR5
-cGVvZiBiPT0ibnVtYmVyIiYmKGImMHgzZmZmZmZmKT09PWIpe3E9cC5jCmlmKHE9PW51bGwpcmV0dXJu
-IG8Kcz1wLmoocSxiKQpyPXM9PW51bGw/bzpzLmIKcmV0dXJuIHJ9ZWxzZSByZXR1cm4gcC5rKGIpfSwK
-azpmdW5jdGlvbihhKXt2YXIgdCxzLHI9dGhpcy5kCmlmKHI9PW51bGwpcmV0dXJuIG51bGwKdD10aGlz
-LkgocixKLmhmKGEpJjB4M2ZmZmZmZikKcz10aGlzLkYodCxhKQppZihzPDApcmV0dXJuIG51bGwKcmV0
-dXJuIHRbc10uYn0sClk6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0LHMscixxLHAsbyxuPXRoaXMsbT1ILkxo
-KG4pCm0uZC5iKGIpCm0uY2hbMV0uYihjKQppZih0eXBlb2YgYj09InN0cmluZyIpe3Q9bi5iCm4uRyh0
-PT1udWxsP24uYj1uLmwoKTp0LGIsYyl9ZWxzZSBpZih0eXBlb2YgYj09Im51bWJlciImJihiJjB4M2Zm
-ZmZmZik9PT1iKXtzPW4uYwpuLkcocz09bnVsbD9uLmM9bi5sKCk6cyxiLGMpfWVsc2V7cj1uLmQKaWYo
-cj09bnVsbClyPW4uZD1uLmwoKQpxPUouaGYoYikmMHgzZmZmZmZmCnA9bi5IKHIscSkKaWYocD09bnVs
-bCluLkUocixxLFtuLk8oYixjKV0pCmVsc2V7bz1uLkYocCxiKQppZihvPj0wKXBbb10uYj1jCmVsc2Ug
-cC5wdXNoKG4uTyhiLGMpKX19fSwKVTpmdW5jdGlvbihhLGIpe3ZhciB0LHMscj10aGlzCkguTGgociku
-QygifigxLDIpIikuYihiKQp0PXIuZQpzPXIucgpmb3IoO3QhPW51bGw7KXtiLiQyKHQuYSx0LmIpCmlm
-KHMhPT1yLnIpdGhyb3cgSC5iKFAuYTQocikpCnQ9dC5jfX0sCkc6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0
-LHM9dGhpcyxyPUguTGgocykKci5kLmIoYikKci5jaFsxXS5iKGMpCnQ9cy5qKGEsYikKaWYodD09bnVs
-bClzLkUoYSxiLHMuTyhiLGMpKQplbHNlIHQuYj1jfSwKWDpmdW5jdGlvbigpe3RoaXMucj10aGlzLnIr
-MSY2NzEwODg2M30sCk86ZnVuY3Rpb24oYSxiKXt2YXIgdCxzPXRoaXMscj1ILkxoKHMpLHE9bmV3IEgu
-dmgoci5kLmIoYSksci5jaFsxXS5iKGIpKQppZihzLmU9PW51bGwpcy5lPXMuZj1xCmVsc2V7dD1zLmYK
-cS5kPXQKcy5mPXQuYz1xfSsrcy5hCnMuWCgpCnJldHVybiBxfSwKRjpmdW5jdGlvbihhLGIpe3ZhciB0
-LHMKaWYoYT09bnVsbClyZXR1cm4tMQp0PWEubGVuZ3RoCmZvcihzPTA7czx0OysrcylpZihKLlJNKGFb
-c10uYSxiKSlyZXR1cm4gcwpyZXR1cm4tMX0sCnc6ZnVuY3Rpb24oYSl7cmV0dXJuIFAubk8odGhpcyl9
-LApqOmZ1bmN0aW9uKGEsYil7cmV0dXJuIGFbYl19LApIOmZ1bmN0aW9uKGEsYil7cmV0dXJuIGFbYl19
-LApFOmZ1bmN0aW9uKGEsYixjKXthW2JdPWN9LApWOmZ1bmN0aW9uKGEsYil7ZGVsZXRlIGFbYl19LApY
-dTpmdW5jdGlvbihhLGIpe3JldHVybiB0aGlzLmooYSxiKSE9bnVsbH0sCmw6ZnVuY3Rpb24oKXt2YXIg
-dD0iPG5vbi1pZGVudGlmaWVyLWtleT4iLHM9T2JqZWN0LmNyZWF0ZShudWxsKQp0aGlzLkUocyx0LHMp
-CnRoaXMuVihzLHQpCnJldHVybiBzfSwKJGlGbzoxfQpILnZoLnByb3RvdHlwZT17fQpILmk1LnByb3Rv
-dHlwZT17CmdoOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLmEuYX0sCmdrejpmdW5jdGlvbihhKXt2YXIg
-dD10aGlzLmEscz1uZXcgSC5ONih0LHQucix0aGlzLiR0aS5DKCJONjwxPiIpKQpzLmM9dC5lCnJldHVy
-biBzfX0KSC5ONi5wcm90b3R5cGU9ewpnUjpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5kfSwKbTpmdW5j
-dGlvbigpe3ZhciB0PXRoaXMscz10LmEKaWYodC5iIT09cy5yKXRocm93IEguYihQLmE0KHMpKQplbHNl
-e3M9dC5jCmlmKHM9PW51bGwpe3Quc04obnVsbCkKcmV0dXJuITF9ZWxzZXt0LnNOKHMuYSkKdC5jPXQu
-Yy5jCnJldHVybiEwfX19LApzTjpmdW5jdGlvbihhKXt0aGlzLmQ9dGhpcy4kdGkuZC5iKGEpfSwKJGlB
-bjoxfQpILmRDLnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLmEoYSl9LAokUzo0
-fQpILndOLnByb3RvdHlwZT17CiQyOmZ1bmN0aW9uKGEsYil7cmV0dXJuIHRoaXMuYShhLGIpfSwKJFM6
-NDV9CkguVlgucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuYShILnkoYSkpfSwK
-JFM6Mjh9CkguVlIucHJvdG90eXBlPXsKdzpmdW5jdGlvbihhKXtyZXR1cm4iUmVnRXhwLyIrdGhpcy5h
-KyIvIit0aGlzLmIuZmxhZ3N9LApnSGM6ZnVuY3Rpb24oKXt2YXIgdD10aGlzLHM9dC5jCmlmKHMhPW51
-bGwpcmV0dXJuIHMKcz10LmIKcmV0dXJuIHQuYz1ILnY0KHQuYSxzLm11bHRpbGluZSwhcy5pZ25vcmVD
-YXNlLHMudW5pY29kZSxzLmRvdEFsbCwhMCl9LApkZDpmdW5jdGlvbihhLGIpe3JldHVybiBuZXcgSC5L
-Vyh0aGlzLGIsMCl9LApVWjpmdW5jdGlvbihhLGIpe3ZhciB0LHM9dGhpcy5nSGMoKQpzLmxhc3RJbmRl
-eD1iCnQ9cy5leGVjKGEpCmlmKHQ9PW51bGwpcmV0dXJuIG51bGwKcmV0dXJuIG5ldyBILkVLKHQpfSwK
-JGl2WDoxLAokaXdMOjF9CkguRUsucHJvdG90eXBlPXsKcTpmdW5jdGlvbihhLGIpe3ZhciB0CkguU2Mo
-YikKdD10aGlzLmIKaWYoYj49dC5sZW5ndGgpcmV0dXJuIEguT0godCxiKQpyZXR1cm4gdFtiXX0sCiRp
-T2Q6MSwKJGlpYjoxfQpILktXLnByb3RvdHlwZT17CmdrejpmdW5jdGlvbihhKXtyZXR1cm4gbmV3IEgu
-UGIodGhpcy5hLHRoaXMuYix0aGlzLmMpfX0KSC5QYi5wcm90b3R5cGU9ewpnUjpmdW5jdGlvbihhKXty
-ZXR1cm4gdGhpcy5kfSwKbTpmdW5jdGlvbigpe3ZhciB0LHMscixxLHA9dGhpcyxvPXAuYgppZihvPT1u
-dWxsKXJldHVybiExCnQ9cC5jCmlmKHQ8PW8ubGVuZ3RoKXtzPXAuYQpyPXMuVVoobyx0KQppZihyIT1u
-dWxsKXtwLmQ9cgpvPXIuYgp0PW8uaW5kZXgKcT10K29bMF0ubGVuZ3RoCmlmKHQ9PT1xKXtpZihzLmIu
-dW5pY29kZSl7bz1wLmMKdD1vKzEKcz1wLmIKaWYodDxzLmxlbmd0aCl7bz1KLnJZKHMpLk8yKHMsbykK
-aWYobz49NTUyOTYmJm88PTU2MzE5KXtvPUMueEIuTzIocyx0KQpvPW8+PTU2MzIwJiZvPD01NzM0M31l
-bHNlIG89ITF9ZWxzZSBvPSExfWVsc2Ugbz0hMQpxPShvP3ErMTpxKSsxfXAuYz1xCnJldHVybiEwfX1w
-LmI9cC5kPW51bGwKcmV0dXJuITF9LAokaUFuOjF9CkgudFEucHJvdG90eXBlPXsKcTpmdW5jdGlvbihh
-LGIpe0guU2MoYikKaWYoYiE9PTApSC5WaihQLngoYixudWxsKSkKcmV0dXJuIHRoaXMuY30sCiRpT2Q6
-MX0KSC51bi5wcm90b3R5cGU9ewpna3o6ZnVuY3Rpb24oYSl7cmV0dXJuIG5ldyBILlNkKHRoaXMuYSx0
-aGlzLmIsdGhpcy5jKX19CkguU2QucHJvdG90eXBlPXsKbTpmdW5jdGlvbigpe3ZhciB0LHMscj10aGlz
-LHE9ci5jLHA9ci5iLG89cC5sZW5ndGgsbj1yLmEsbT1uLmxlbmd0aAppZihxK28+bSl7ci5kPW51bGwK
-cmV0dXJuITF9dD1uLmluZGV4T2YocCxxKQppZih0PDApe3IuYz1tKzEKci5kPW51bGwKcmV0dXJuITF9
-cz10K28Kci5kPW5ldyBILnRRKHQscCkKci5jPXM9PT1yLmM/cysxOnMKcmV0dXJuITB9LApnUjpmdW5j
-dGlvbihhKXtyZXR1cm4gdGhpcy5kfSwKJGlBbjoxfQpILldaLnByb3RvdHlwZT17JGlXWjoxfQpILkVU
-LnByb3RvdHlwZT17JGlFVDoxLCRpQVM6MX0KSC5kZi5wcm90b3R5cGU9eyRpV3k6MX0KSC5iMC5wcm90
-b3R5cGU9ewpnaDpmdW5jdGlvbihhKXtyZXR1cm4gYS5sZW5ndGh9LAokaVhqOjF9CkguRGcucHJvdG90
-eXBlPXsKcTpmdW5jdGlvbihhLGIpe0guU2MoYikKSC5vZChiLGEsYS5sZW5ndGgpCnJldHVybiBhW2Jd
-fSwKWTpmdW5jdGlvbihhLGIsYyl7SC5TYyhiKQpILklnKGMpCkgub2QoYixhLGEubGVuZ3RoKQphW2Jd
-PWN9LAokaWJROjEsCiRpY1g6MSwKJGl6TToxfQpILlBnLnByb3RvdHlwZT17Clk6ZnVuY3Rpb24oYSxi
-LGMpe0guU2MoYikKSC5TYyhjKQpILm9kKGIsYSxhLmxlbmd0aCkKYVtiXT1jfSwKJGliUToxLAokaWNY
-OjEsCiRpek06MX0KSC54ai5wcm90b3R5cGU9ewpxOmZ1bmN0aW9uKGEsYil7SC5TYyhiKQpILm9kKGIs
-YSxhLmxlbmd0aCkKcmV0dXJuIGFbYl19fQpILmRFLnByb3RvdHlwZT17CnE6ZnVuY3Rpb24oYSxiKXtI
-LlNjKGIpCkgub2QoYixhLGEubGVuZ3RoKQpyZXR1cm4gYVtiXX19CkguWkEucHJvdG90eXBlPXsKcTpm
-dW5jdGlvbihhLGIpe0guU2MoYikKSC5vZChiLGEsYS5sZW5ndGgpCnJldHVybiBhW2JdfX0KSC53Zi5w
-cm90b3R5cGU9ewpxOmZ1bmN0aW9uKGEsYil7SC5TYyhiKQpILm9kKGIsYSxhLmxlbmd0aCkKcmV0dXJu
-IGFbYl19fQpILlBxLnByb3RvdHlwZT17CnE6ZnVuY3Rpb24oYSxiKXtILlNjKGIpCkgub2QoYixhLGEu
-bGVuZ3RoKQpyZXR1cm4gYVtiXX19CkguZUUucHJvdG90eXBlPXsKZ2g6ZnVuY3Rpb24oYSl7cmV0dXJu
-IGEubGVuZ3RofSwKcTpmdW5jdGlvbihhLGIpe0guU2MoYikKSC5vZChiLGEsYS5sZW5ndGgpCnJldHVy
-biBhW2JdfX0KSC5WNi5wcm90b3R5cGU9ewpnaDpmdW5jdGlvbihhKXtyZXR1cm4gYS5sZW5ndGh9LApx
-OmZ1bmN0aW9uKGEsYil7SC5TYyhiKQpILm9kKGIsYSxhLmxlbmd0aCkKcmV0dXJuIGFbYl19LAokaVY2
-OjEsCiRpbjY6MX0KSC5SRy5wcm90b3R5cGU9e30KSC5WUC5wcm90b3R5cGU9e30KSC5XQi5wcm90b3R5
-cGU9e30KSC5aRy5wcm90b3R5cGU9e30KSC5KYy5wcm90b3R5cGU9ewpDOmZ1bmN0aW9uKGEpe3JldHVy
-biBILmNFKHYudHlwZVVuaXZlcnNlLHRoaXMsYSl9LApLOmZ1bmN0aW9uKGEpe3JldHVybiBILnY1KHYu
-dHlwZVVuaXZlcnNlLHRoaXMsYSl9fQpILkcucHJvdG90eXBlPXt9CkgudTkucHJvdG90eXBlPXsKdzpm
-dW5jdGlvbihhKXtyZXR1cm4gdGhpcy5hfX0KSC5oei5wcm90b3R5cGU9e30KSC5pTS5wcm90b3R5cGU9
-e30KUC50aC5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXt2YXIgdD10aGlzLmEscz10LmEKdC5hPW51
-bGwKcy4kMCgpfSwKJFM6MTh9ClAuaGEucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7dmFyIHQscwp0
-aGlzLmEuYT11Lk0uYihhKQp0PXRoaXMuYgpzPXRoaXMuYwp0LmZpcnN0Q2hpbGQ/dC5yZW1vdmVDaGls
-ZChzKTp0LmFwcGVuZENoaWxkKHMpfSwKJFM6Mzl9ClAuVnMucHJvdG90eXBlPXsKJDA6ZnVuY3Rpb24o
-KXt0aGlzLmEuJDAoKX0sCiRDOiIkMCIsCiRSOjAsCiRTOjB9ClAuRnQucHJvdG90eXBlPXsKJDA6ZnVu
-Y3Rpb24oKXt0aGlzLmEuJDAoKX0sCiRDOiIkMCIsCiRSOjAsCiRTOjB9ClAuVzMucHJvdG90eXBlPXsK
-Q1k6ZnVuY3Rpb24oYSxiKXtpZihzZWxmLnNldFRpbWVvdXQhPW51bGwpc2VsZi5zZXRUaW1lb3V0KEgu
-dFIobmV3IFAueUgodGhpcyxiKSwwKSxhKQplbHNlIHRocm93IEguYihQLkw0KCJgc2V0VGltZW91dCgp
-YCBub3QgZm91bmQuIikpfX0KUC55SC5wcm90b3R5cGU9ewokMDpmdW5jdGlvbigpe3RoaXMuYi4kMCgp
-fSwKJEM6IiQwIiwKJFI6MCwKJFM6Mn0KUC5paC5wcm90b3R5cGU9ewphTTpmdW5jdGlvbihhLGIpe3Zh
-ciB0LHMscj10aGlzLiR0aQpyLkMoIjEvIikuYihiKQp0PSF0aGlzLmJ8fHIuQygiYjg8MT4iKS5jKGIp
-CnM9dGhpcy5hCmlmKHQpcy5YZihiKQplbHNlIHMuWDIoci5kLmIoYikpfSwKdzA6ZnVuY3Rpb24oYSxi
-KXt2YXIgdD10aGlzLmEKaWYodGhpcy5iKXQuWkwoYSxiKQplbHNlIHQuTmsoYSxiKX19ClAuV00ucHJv
-dG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuYS4kMigwLGEpfSwKJFM6MTB9ClAuU1gu
-cHJvdG90eXBlPXsKJDI6ZnVuY3Rpb24oYSxiKXt0aGlzLmEuJDIoMSxuZXcgSC5icShhLHUubC5iKGIp
-KSl9LAokQzoiJDIiLAokUjoyLAokUzo0MH0KUC5Hcy5wcm90b3R5cGU9ewokMjpmdW5jdGlvbihhLGIp
-e3RoaXMuYShILlNjKGEpLGIpfSwKJFM6NDN9ClAuRnkucHJvdG90eXBlPXsKdzpmdW5jdGlvbihhKXty
-ZXR1cm4iSXRlcmF0aW9uTWFya2VyKCIrdGhpcy5iKyIsICIrSC5kKHRoaXMuYSkrIikifSwKZ253OmZ1
-bmN0aW9uKGEpe3JldHVybiB0aGlzLmF9fQpQLkdWLnByb3RvdHlwZT17CmdSOmZ1bmN0aW9uKGEpe3Zh
-ciB0PXRoaXMuYwppZih0PT1udWxsKXJldHVybiB0aGlzLmIKcmV0dXJuIHRoaXMuJHRpLmQuYih0LmdS
-KHQpKX0sCm06ZnVuY3Rpb24oKXt2YXIgdCxzLHIscSxwPXRoaXMKZm9yKDshMDspe3Q9cC5jCmlmKHQh
-PW51bGwpaWYodC5tKCkpcmV0dXJuITAKZWxzZSBwLmM9bnVsbApzPWZ1bmN0aW9uKGEsYixjKXt2YXIg
-byxuPWIKd2hpbGUodHJ1ZSl0cnl7cmV0dXJuIGEobixvKX1jYXRjaChtKXtvPW0Kbj1jfX0ocC5hLDAs
-MSkKaWYocyBpbnN0YW5jZW9mIFAuRnkpe3I9cy5iCmlmKHI9PT0yKXt0PXAuZAppZih0PT1udWxsfHx0
-Lmxlbmd0aD09PTApe3Auc0VDKG51bGwpCnJldHVybiExfWlmKDA+PXQubGVuZ3RoKXJldHVybiBILk9I
-KHQsLTEpCnAuYT10LnBvcCgpCmNvbnRpbnVlfWVsc2V7dD1zLmEKaWYocj09PTMpdGhyb3cgdAplbHNl
-e3E9Si5JVCh0KQppZihxIGluc3RhbmNlb2YgUC5HVil7dD1wLmQKaWYodD09bnVsbCl0PXAuZD1bXQpD
-Lk5tLkEodCxwLmEpCnAuYT1xLmEKY29udGludWV9ZWxzZXtwLmM9cQpjb250aW51ZX19fX1lbHNle3Au
-c0VDKHMpCnJldHVybiEwfX1yZXR1cm4hMX0sCnNFQzpmdW5jdGlvbihhKXt0aGlzLmI9dGhpcy4kdGku
-ZC5iKGEpfSwKJGlBbjoxfQpQLnE0LnByb3RvdHlwZT17CmdrejpmdW5jdGlvbihhKXtyZXR1cm4gbmV3
-IFAuR1YodGhpcy5hKCksdGhpcy4kdGkuQygiR1Y8MT4iKSl9fQpQLmI4LnByb3RvdHlwZT17fQpQLlBm
-LnByb3RvdHlwZT17CncwOmZ1bmN0aW9uKGEsYil7dmFyIHQKaWYoYT09bnVsbClhPW5ldyBQLm4oKQp0
-PXRoaXMuYQppZih0LmEhPT0wKXRocm93IEguYihQLlBWKCJGdXR1cmUgYWxyZWFkeSBjb21wbGV0ZWQi
-KSkKdC5OayhhLGIpfSwKcG06ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMudzAoYSxudWxsKX19ClAuWmYu
-cHJvdG90eXBlPXsKYU06ZnVuY3Rpb24oYSxiKXt2YXIgdAp0aGlzLiR0aS5DKCIxLyIpLmIoYikKdD10
-aGlzLmEKaWYodC5hIT09MCl0aHJvdyBILmIoUC5QVigiRnV0dXJlIGFscmVhZHkgY29tcGxldGVkIikp
-CnQuWGYoYil9fQpQLkZlLnByb3RvdHlwZT17CkhSOmZ1bmN0aW9uKGEpe2lmKCh0aGlzLmMmMTUpIT09
-NilyZXR1cm4hMApyZXR1cm4gdGhpcy5iLmIuYnYodS5hbC5iKHRoaXMuZCksYS5hLHUuY0osdS5LKX0s
-Ckt3OmZ1bmN0aW9uKGEpe3ZhciB0PXRoaXMuZSxzPXUueixyPXUuSyxxPXRoaXMuJHRpLkMoIjIvIiks
-cD10aGlzLmIuYgppZih1LmFnLmModCkpcmV0dXJuIHEuYihwLnJwKHQsYS5hLGEuYixzLHIsdS5sKSkK
-ZWxzZSByZXR1cm4gcS5iKHAuYnYodS55LmIodCksYS5hLHMscikpfX0KUC52cy5wcm90b3R5cGU9ewpT
-cTpmdW5jdGlvbihhLGIsYyl7dmFyIHQscyxyLHE9dGhpcy4kdGkKcS5LKGMpLkMoIjEvKDIpIikuYihh
-KQp0PSQuWDMKaWYodCE9PUMuTlUpe2MuQygiQDwwLz4iKS5LKHEuZCkuQygiMSgyKSIpLmIoYSkKaWYo
-YiE9bnVsbCliPVAuVkgoYix0KX1zPW5ldyBQLnZzKCQuWDMsYy5DKCJ2czwwPiIpKQpyPWI9PW51bGw/
-MTozCnRoaXMueGYobmV3IFAuRmUocyxyLGEsYixxLkMoIkA8MT4iKS5LKGMpLkMoIkZlPDEsMj4iKSkp
-CnJldHVybiBzfSwKVzc6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gdGhpcy5TcShhLG51bGwsYil9LApRZDpm
-dW5jdGlvbihhLGIsYyl7dmFyIHQscz10aGlzLiR0aQpzLksoYykuQygiMS8oMikiKS5iKGEpCnQ9bmV3
-IFAudnMoJC5YMyxjLkMoInZzPDA+IikpCnRoaXMueGYobmV3IFAuRmUodCwoYj09bnVsbD8xOjMpfDE2
-LGEsYixzLkMoIkA8MT4iKS5LKGMpLkMoIkZlPDEsMj4iKSkpCnJldHVybiB0fSwKT0E6ZnVuY3Rpb24o
-YSl7dmFyIHQscyxyCnUuYmYuYihudWxsKQp0PXRoaXMuJHRpCnM9JC5YMwpyPW5ldyBQLnZzKHMsdCkK
-aWYocyE9PUMuTlUpYT1QLlZIKGEscykKdGhpcy54ZihuZXcgUC5GZShyLDIsbnVsbCxhLHQuQygiQDwx
-PiIpLksodC5kKS5DKCJGZTwxLDI+IikpKQpyZXR1cm4gcn0sCnhmOmZ1bmN0aW9uKGEpe3ZhciB0LHM9
-dGhpcyxyPXMuYQppZihyPD0xKXthLmE9dS54LmIocy5jKQpzLmM9YX1lbHNle2lmKHI9PT0yKXt0PXUu
-Xy5iKHMuYykKcj10LmEKaWYocjw0KXt0LnhmKGEpCnJldHVybn1zLmE9cgpzLmM9dC5jfVAuVGsobnVs
-bCxudWxsLHMuYix1Lk0uYihuZXcgUC5kYShzLGEpKSl9fSwKalE6ZnVuY3Rpb24oYSl7dmFyIHQscyxy
-LHEscCxvPXRoaXMsbj17fQpuLmE9YQppZihhPT1udWxsKXJldHVybgp0PW8uYQppZih0PD0xKXtzPXUu
-eC5iKG8uYykKcj1vLmM9YQppZihzIT1udWxsKXtmb3IoO3E9ci5hLHEhPW51bGw7cj1xKTtyLmE9c319
-ZWxzZXtpZih0PT09Mil7cD11Ll8uYihvLmMpCnQ9cC5hCmlmKHQ8NCl7cC5qUShhKQpyZXR1cm59by5h
-PXQKby5jPXAuY31uLmE9by5OOChhKQpQLlRrKG51bGwsbnVsbCxvLmIsdS5NLmIobmV3IFAub1Eobixv
-KSkpfX0sCmFoOmZ1bmN0aW9uKCl7dmFyIHQ9dS54LmIodGhpcy5jKQp0aGlzLmM9bnVsbApyZXR1cm4g
-dGhpcy5OOCh0KX0sCk44OmZ1bmN0aW9uKGEpe3ZhciB0LHMscgpmb3IodD1hLHM9bnVsbDt0IT1udWxs
-O3M9dCx0PXIpe3I9dC5hCnQuYT1zfXJldHVybiBzfSwKSEg6ZnVuY3Rpb24oYSl7dmFyIHQscz10aGlz
-LHI9cy4kdGkKci5DKCIxLyIpLmIoYSkKaWYoci5DKCJiODwxPiIpLmMoYSkpaWYoci5jKGEpKVAuQTko
-YSxzKQplbHNlIFAuazMoYSxzKQplbHNle3Q9cy5haCgpCnIuZC5iKGEpCnMuYT00CnMuYz1hClAuSFoo
-cyx0KX19LApYMjpmdW5jdGlvbihhKXt2YXIgdCxzPXRoaXMKcy4kdGkuZC5iKGEpCnQ9cy5haCgpCnMu
-YT00CnMuYz1hClAuSFoocyx0KX0sClpMOmZ1bmN0aW9uKGEsYil7dmFyIHQscz10aGlzCnUubC5iKGIp
-CnQ9cy5haCgpCnMuYT04CnMuYz1uZXcgUC5DdyhhLGIpClAuSFoocyx0KX0sClhmOmZ1bmN0aW9uKGEp
-e3ZhciB0PXRoaXMscz10LiR0aQpzLkMoIjEvIikuYihhKQppZihzLkMoImI4PDE+IikuYyhhKSl7dC5j
-VShhKQpyZXR1cm59dC5hPTEKUC5UayhudWxsLG51bGwsdC5iLHUuTS5iKG5ldyBQLnJIKHQsYSkpKX0s
-CmNVOmZ1bmN0aW9uKGEpe3ZhciB0PXRoaXMscz10LiR0aQpzLkMoImI4PDE+IikuYihhKQppZihzLmMo
-YSkpe2lmKGEuYT09PTgpe3QuYT0xClAuVGsobnVsbCxudWxsLHQuYix1Lk0uYihuZXcgUC5LRih0LGEp
-KSl9ZWxzZSBQLkE5KGEsdCkKcmV0dXJufVAuazMoYSx0KX0sCk5rOmZ1bmN0aW9uKGEsYil7dGhpcy5h
-PTEKUC5UayhudWxsLG51bGwsdGhpcy5iLHUuTS5iKG5ldyBQLlpMKHRoaXMsYSxiKSkpfSwKJGliODox
-fQpQLmRhLnByb3RvdHlwZT17CiQwOmZ1bmN0aW9uKCl7UC5IWih0aGlzLmEsdGhpcy5iKX0sCiRTOjB9
-ClAub1EucHJvdG90eXBlPXsKJDA6ZnVuY3Rpb24oKXtQLkhaKHRoaXMuYix0aGlzLmEuYSl9LAokUzow
-fQpQLnBWLnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe3ZhciB0PXRoaXMuYQp0LmE9MAp0LkhIKGEp
-fSwKJFM6MTh9ClAuVTcucHJvdG90eXBlPXsKJDI6ZnVuY3Rpb24oYSxiKXt1LmwuYihiKQp0aGlzLmEu
-WkwoYSxiKX0sCiQxOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLiQyKGEsbnVsbCl9LAokQzoiJDIiLAok
-RDpmdW5jdGlvbigpe3JldHVybltudWxsXX0sCiRTOjI2fQpQLnZyLnByb3RvdHlwZT17CiQwOmZ1bmN0
-aW9uKCl7dGhpcy5hLlpMKHRoaXMuYix0aGlzLmMpfSwKJFM6MH0KUC5ySC5wcm90b3R5cGU9ewokMDpm
-dW5jdGlvbigpe3ZhciB0PXRoaXMuYQp0LlgyKHQuJHRpLmQuYih0aGlzLmIpKX0sCiRTOjB9ClAuS0Yu
-cHJvdG90eXBlPXsKJDA6ZnVuY3Rpb24oKXtQLkE5KHRoaXMuYix0aGlzLmEpfSwKJFM6MH0KUC5aTC5w
-cm90b3R5cGU9ewokMDpmdW5jdGlvbigpe3RoaXMuYS5aTCh0aGlzLmIsdGhpcy5jKX0sCiRTOjB9ClAu
-UlQucHJvdG90eXBlPXsKJDA6ZnVuY3Rpb24oKXt2YXIgdCxzLHIscSxwLG8sbj10aGlzLG09bnVsbAp0
-cnl7cj1uLmMKbT1yLmIuYi56eih1LmZPLmIoci5kKSx1LnopfWNhdGNoKHEpe3Q9SC5SdShxKQpzPUgu
-dHMocSkKaWYobi5kKXtyPXUubi5iKG4uYS5hLmMpLmEKcD10CnA9cj09bnVsbD9wPT1udWxsOnI9PT1w
-CnI9cH1lbHNlIHI9ITEKcD1uLmIKaWYocilwLmI9dS5uLmIobi5hLmEuYykKZWxzZSBwLmI9bmV3IFAu
-Q3codCxzKQpwLmE9ITAKcmV0dXJufWlmKHUuYy5jKG0pKXtpZihtIGluc3RhbmNlb2YgUC52cyYmbS5h
-Pj00KXtpZihtLmE9PT04KXtyPW4uYgpyLmI9dS5uLmIobS5jKQpyLmE9ITB9cmV0dXJufW89bi5hLmEK
-cj1uLmIKci5iPW0uVzcobmV3IFAualoobyksdS56KQpyLmE9ITF9fSwKJFM6Mn0KUC5qWi5wcm90b3R5
-cGU9ewokMTpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5hfSwKJFM6MzB9ClAucnEucHJvdG90eXBlPXsK
-JDA6ZnVuY3Rpb24oKXt2YXIgdCxzLHIscSxwLG8sbixtPXRoaXMKdHJ5e3I9bS5iCnE9ci4kdGkKcD1x
-LmQKbz1wLmIobS5jKQptLmEuYj1yLmIuYi5idihxLkMoIjIvKDEpIikuYihyLmQpLG8scS5DKCIyLyIp
-LHApfWNhdGNoKG4pe3Q9SC5SdShuKQpzPUgudHMobikKcj1tLmEKci5iPW5ldyBQLkN3KHQscykKci5h
-PSEwfX0sCiRTOjJ9ClAuUlcucHJvdG90eXBlPXsKJDA6ZnVuY3Rpb24oKXt2YXIgdCxzLHIscSxwLG8s
-bixtLGw9dGhpcwp0cnl7dD11Lm4uYihsLmEuYS5jKQpxPWwuYwppZihILm9UKHEuSFIodCkpJiZxLmUh
-PW51bGwpe3A9bC5iCnAuYj1xLkt3KHQpCnAuYT0hMX19Y2F0Y2gobyl7cz1ILlJ1KG8pCnI9SC50cyhv
-KQpxPXUubi5iKGwuYS5hLmMpCnA9cS5hCm49cwptPWwuYgppZihwPT1udWxsP249PW51bGw6cD09PW4p
-bS5iPXEKZWxzZSBtLmI9bmV3IFAuQ3cocyxyKQptLmE9ITB9fSwKJFM6Mn0KUC5PTS5wcm90b3R5cGU9
-e30KUC5xaC5wcm90b3R5cGU9ewpnaDpmdW5jdGlvbihhKXt2YXIgdCxzLHI9dGhpcyxxPXt9LHA9bmV3
-IFAudnMoJC5YMyx1LmZKKQpxLmE9MAp0PUguTGgocikKcz10LkMoIn4oMSkiKS5iKG5ldyBQLkI1KHEs
-cikpCnUuTS5iKG5ldyBQLlBJKHEscCkpClcuSkUoci5hLHIuYixzLCExLHQuZCkKcmV0dXJuIHB9fQpQ
-LkI1LnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe0guTGgodGhpcy5iKS5kLmIoYSk7Kyt0aGlzLmEu
-YX0sCiRTOmZ1bmN0aW9uKCl7cmV0dXJuIEguTGgodGhpcy5iKS5DKCJjOCgxKSIpfX0KUC5QSS5wcm90
-b3R5cGU9ewokMDpmdW5jdGlvbigpe3RoaXMuYi5ISCh0aGlzLmEuYSl9LAokUzowfQpQLk1PLnByb3Rv
-dHlwZT17fQpQLmtULnByb3RvdHlwZT17fQpQLnhJLnByb3RvdHlwZT17fQpQLkN3LnByb3RvdHlwZT17
-Cnc6ZnVuY3Rpb24oYSl7cmV0dXJuIEguZCh0aGlzLmEpfSwKJGlYUzoxfQpQLm0wLnByb3RvdHlwZT17
-JGlKQjoxfQpQLnBLLnByb3RvdHlwZT17CiQwOmZ1bmN0aW9uKCl7dmFyIHQscz10aGlzLmEscj1zLmEK
-cz1yPT1udWxsP3MuYT1uZXcgUC5uKCk6cgpyPXRoaXMuYgppZihyPT1udWxsKXRocm93IEguYihzKQp0
-PUguYihzKQp0LnN0YWNrPXIudygwKQp0aHJvdyB0fSwKJFM6MH0KUC5KaS5wcm90b3R5cGU9ewpiSDpm
-dW5jdGlvbihhKXt2YXIgdCxzLHIscT1udWxsCnUuTS5iKGEpCnRyeXtpZihDLk5VPT09JC5YMyl7YS4k
-MCgpCnJldHVybn1QLlQ4KHEscSx0aGlzLGEsdS5IKX1jYXRjaChyKXt0PUguUnUocikKcz1ILnRzKHIp
-ClAuTDIocSxxLHRoaXMsdCx1LmwuYihzKSl9fSwKRGw6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0LHMscixx
-PW51bGwKYy5DKCJ+KDApIikuYihhKQpjLmIoYikKdHJ5e2lmKEMuTlU9PT0kLlgzKXthLiQxKGIpCnJl
-dHVybn1QLnl2KHEscSx0aGlzLGEsYix1LkgsYyl9Y2F0Y2gocil7dD1ILlJ1KHIpCnM9SC50cyhyKQpQ
-LkwyKHEscSx0aGlzLHQsdS5sLmIocykpfX0sClJUOmZ1bmN0aW9uKGEsYil7cmV0dXJuIG5ldyBQLmhq
-KHRoaXMsYi5DKCIwKCkiKS5iKGEpLGIpfSwKR1k6ZnVuY3Rpb24oYSl7cmV0dXJuIG5ldyBQLlZwKHRo
-aXMsdS5NLmIoYSkpfSwKUHk6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gbmV3IFAuT1IodGhpcyxiLkMoIn4o
-MCkiKS5iKGEpLGIpfSwKcTpmdW5jdGlvbihhLGIpe3JldHVybiBudWxsfSwKeno6ZnVuY3Rpb24oYSxi
-KXtiLkMoIjAoKSIpLmIoYSkKaWYoJC5YMz09PUMuTlUpcmV0dXJuIGEuJDAoKQpyZXR1cm4gUC5UOChu
-dWxsLG51bGwsdGhpcyxhLGIpfSwKYnY6ZnVuY3Rpb24oYSxiLGMsZCl7Yy5DKCJAPDA+IikuSyhkKS5D
-KCIxKDIpIikuYihhKQpkLmIoYikKaWYoJC5YMz09PUMuTlUpcmV0dXJuIGEuJDEoYikKcmV0dXJuIFAu
-eXYobnVsbCxudWxsLHRoaXMsYSxiLGMsZCl9LApycDpmdW5jdGlvbihhLGIsYyxkLGUsZil7ZC5DKCJA
-PDA+IikuSyhlKS5LKGYpLkMoIjEoMiwzKSIpLmIoYSkKZS5iKGIpCmYuYihjKQppZigkLlgzPT09Qy5O
-VSlyZXR1cm4gYS4kMihiLGMpCnJldHVybiBQLlF4KG51bGwsbnVsbCx0aGlzLGEsYixjLGQsZSxmKX0s
-CkxqOmZ1bmN0aW9uKGEsYixjLGQpe3JldHVybiBiLkMoIkA8MD4iKS5LKGMpLksoZCkuQygiMSgyLDMp
-IikuYihhKX19ClAuaGoucHJvdG90eXBlPXsKJDA6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5hLnp6KHRo
-aXMuYix0aGlzLmMpfSwKJFM6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5jLkMoIjAoKSIpfX0KUC5WcC5w
-cm90b3R5cGU9ewokMDpmdW5jdGlvbigpe3JldHVybiB0aGlzLmEuYkgodGhpcy5iKX0sCiRTOjJ9ClAu
-T1IucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7dmFyIHQ9dGhpcy5jCnJldHVybiB0aGlzLmEuRGwo
-dGhpcy5iLHQuYihhKSx0KX0sCiRTOmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuYy5DKCJ+KDApIil9fQpQ
-LmI2LnByb3RvdHlwZT17CmdrejpmdW5jdGlvbihhKXt2YXIgdD10aGlzLHM9bmV3IFAubG0odCx0LnIs
-SC5MaCh0KS5DKCJsbTwxPiIpKQpzLmM9dC5lCnJldHVybiBzfSwKZ2g6ZnVuY3Rpb24oYSl7cmV0dXJu
-IHRoaXMuYX0sCnRnOmZ1bmN0aW9uKGEsYil7dmFyIHQscwppZih0eXBlb2YgYj09InN0cmluZyImJmIh
-PT0iX19wcm90b19fIil7dD10aGlzLmIKaWYodD09bnVsbClyZXR1cm4hMQpyZXR1cm4gdS5KLmIodFti
-XSkhPW51bGx9ZWxzZXtzPXRoaXMuUFIoYikKcmV0dXJuIHN9fSwKUFI6ZnVuY3Rpb24oYSl7dmFyIHQ9
-dGhpcy5kCmlmKHQ9PW51bGwpcmV0dXJuITEKcmV0dXJuIHRoaXMuREYodFt0aGlzLnJrKGEpXSxhKT49
-MH0sCkE6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzLHI9dGhpcwpILkxoKHIpLmQuYihiKQppZih0eXBlb2Yg
-Yj09InN0cmluZyImJmIhPT0iX19wcm90b19fIil7dD1yLmIKcmV0dXJuIHIuY1codD09bnVsbD9yLmI9
-UC5UMigpOnQsYil9ZWxzZSBpZih0eXBlb2YgYj09Im51bWJlciImJihiJjEwNzM3NDE4MjMpPT09Yil7
-cz1yLmMKcmV0dXJuIHIuY1cocz09bnVsbD9yLmM9UC5UMigpOnMsYil9ZWxzZSByZXR1cm4gci5CNygw
-LGIpfSwKQjc6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzLHIscT10aGlzCkguTGgocSkuZC5iKGIpCnQ9cS5k
-CmlmKHQ9PW51bGwpdD1xLmQ9UC5UMigpCnM9cS5yayhiKQpyPXRbc10KaWYocj09bnVsbCl0W3NdPVtx
-LmRnKGIpXQplbHNle2lmKHEuREYocixiKT49MClyZXR1cm4hMQpyLnB1c2gocS5kZyhiKSl9cmV0dXJu
-ITB9LApSejpmdW5jdGlvbihhLGIpe3ZhciB0PXRoaXMKaWYodHlwZW9mIGI9PSJzdHJpbmciJiZiIT09
-Il9fcHJvdG9fXyIpcmV0dXJuIHQuSDQodC5iLGIpCmVsc2UgaWYodHlwZW9mIGI9PSJudW1iZXIiJiYo
-YiYxMDczNzQxODIzKT09PWIpcmV0dXJuIHQuSDQodC5jLGIpCmVsc2UgcmV0dXJuIHQucWcoMCxiKX0s
-CnFnOmZ1bmN0aW9uKGEsYil7dmFyIHQscyxyLHEscD10aGlzLG89cC5kCmlmKG89PW51bGwpcmV0dXJu
-ITEKdD1wLnJrKGIpCnM9b1t0XQpyPXAuREYocyxiKQppZihyPDApcmV0dXJuITEKcT1zLnNwbGljZShy
-LDEpWzBdCmlmKDA9PT1zLmxlbmd0aClkZWxldGUgb1t0XQpwLkdTKHEpCnJldHVybiEwfSwKY1c6ZnVu
-Y3Rpb24oYSxiKXtILkxoKHRoaXMpLmQuYihiKQppZih1LkouYihhW2JdKSE9bnVsbClyZXR1cm4hMQph
-W2JdPXRoaXMuZGcoYikKcmV0dXJuITB9LApINDpmdW5jdGlvbihhLGIpe3ZhciB0CmlmKGE9PW51bGwp
-cmV0dXJuITEKdD11LkouYihhW2JdKQppZih0PT1udWxsKXJldHVybiExCnRoaXMuR1ModCkKZGVsZXRl
-IGFbYl0KcmV0dXJuITB9LApYQTpmdW5jdGlvbigpe3RoaXMucj0xMDczNzQxODIzJnRoaXMucisxfSwK
-ZGc6ZnVuY3Rpb24oYSl7dmFyIHQscz10aGlzLHI9bmV3IFAuYm4oSC5MaChzKS5kLmIoYSkpCmlmKHMu
-ZT09bnVsbClzLmU9cy5mPXIKZWxzZXt0PXMuZgpyLmM9dApzLmY9dC5iPXJ9KytzLmEKcy5YQSgpCnJl
-dHVybiByfSwKR1M6ZnVuY3Rpb24oYSl7dmFyIHQ9dGhpcyxzPWEuYyxyPWEuYgppZihzPT1udWxsKXQu
-ZT1yCmVsc2Ugcy5iPXIKaWYocj09bnVsbCl0LmY9cwplbHNlIHIuYz1zOy0tdC5hCnQuWEEoKX0sCnJr
-OmZ1bmN0aW9uKGEpe3JldHVybiBKLmhmKGEpJjEwNzM3NDE4MjN9LApERjpmdW5jdGlvbihhLGIpe3Zh
-ciB0LHMKaWYoYT09bnVsbClyZXR1cm4tMQp0PWEubGVuZ3RoCmZvcihzPTA7czx0OysrcylpZihKLlJN
-KGFbc10uYSxiKSlyZXR1cm4gcwpyZXR1cm4tMX19ClAuYm4ucHJvdG90eXBlPXt9ClAubG0ucHJvdG90
-eXBlPXsKZ1I6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuZH0sCm06ZnVuY3Rpb24oKXt2YXIgdD10aGlz
-LHM9dC5hCmlmKHQuYiE9PXMucil0aHJvdyBILmIoUC5hNChzKSkKZWxzZXtzPXQuYwppZihzPT1udWxs
-KXt0LnNCYihudWxsKQpyZXR1cm4hMX1lbHNle3Quc0JiKHQuJHRpLmQuYihzLmEpKQp0LmM9dC5jLmIK
-cmV0dXJuITB9fX0sCnNCYjpmdW5jdGlvbihhKXt0aGlzLmQ9dGhpcy4kdGkuZC5iKGEpfSwKJGlBbjox
-fQpQLm1XLnByb3RvdHlwZT17fQpQLkxVLnByb3RvdHlwZT17JGliUToxLCRpY1g6MSwkaXpNOjF9ClAu
-bEQucHJvdG90eXBlPXsKZ2t6OmZ1bmN0aW9uKGEpe3JldHVybiBuZXcgSC5hNyhhLHRoaXMuZ2goYSks
-SC56SyhhKS5DKCJhNzxsRC5FPiIpKX0sClc6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gdGhpcy5xKGEsYil9
-LApVOmZ1bmN0aW9uKGEsYil7dmFyIHQscwpILnpLKGEpLkMoIn4obEQuRSkiKS5iKGIpCnQ9dGhpcy5n
-aChhKQpmb3Iocz0wO3M8dDsrK3Mpe2IuJDEodGhpcy5xKGEscykpCmlmKHQhPT10aGlzLmdoKGEpKXRo
-cm93IEguYihQLmE0KGEpKX19LApFMjpmdW5jdGlvbihhLGIsYyl7dmFyIHQ9SC56SyhhKQpyZXR1cm4g
-bmV3IEguQTgoYSx0LksoYykuQygiMShsRC5FKSIpLmIoYiksdC5DKCJAPGxELkU+IikuSyhjKS5DKCJB
-ODwxLDI+IikpfSwKZHU6ZnVuY3Rpb24oYSxiLGMsZCl7dmFyIHQKSC56SyhhKS5DKCJsRC5FIikuYihk
-KQpQLmpCKGIsYyx0aGlzLmdoKGEpKQpmb3IodD1iO3Q8YzsrK3QpdGhpcy5ZKGEsdCxkKX0sCnc6ZnVu
-Y3Rpb24oYSl7cmV0dXJuIFAuV0UoYSwiWyIsIl0iKX19ClAuaWwucHJvdG90eXBlPXt9ClAucmEucHJv
-dG90eXBlPXsKJDI6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzPXRoaXMuYQppZighcy5hKXRoaXMuYi5hKz0i
-LCAiCnMuYT0hMQpzPXRoaXMuYgp0PXMuYSs9SC5kKGEpCnMuYT10KyI6ICIKcy5hKz1ILmQoYil9LAok
-UzoxfQpQLllrLnByb3RvdHlwZT17ClU6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzCkgueksoYSkuQygifihZ
-ay5LLFlrLlYpIikuYihiKQpmb3IodD1KLklUKHRoaXMuZ3YoYSkpO3QubSgpOyl7cz10LmdSKHQpCmIu
-JDIocyx0aGlzLnEoYSxzKSl9fSwKZ1B1OmZ1bmN0aW9uKGEpe3JldHVybiBKLk0xKHRoaXMuZ3YoYSks
-bmV3IFAueVEoYSksSC56SyhhKS5DKCJOMzxZay5LLFlrLlY+IikpfSwKZ2g6ZnVuY3Rpb24oYSl7cmV0
-dXJuIEouSG0odGhpcy5ndihhKSl9LAp3OmZ1bmN0aW9uKGEpe3JldHVybiBQLm5PKGEpfSwKJGlaMDox
-fQpQLnlRLnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe3ZhciB0PXRoaXMuYSxzPUgueksodCkKcy5D
-KCJZay5LIikuYihhKQpyZXR1cm4gbmV3IFAuTjMoYSxKLncyKHQsYSkscy5DKCJAPFlrLks+IikuSyhz
-LkMoIllrLlYiKSkuQygiTjM8MSwyPiIpKX0sCiRTOmZ1bmN0aW9uKCl7cmV0dXJuIEgueksodGhpcy5h
-KS5DKCJOMzxZay5LLFlrLlY+KFlrLkspIil9fQpQLktQLnByb3RvdHlwZT17Clk6ZnVuY3Rpb24oYSxi
-LGMpe3ZhciB0PUguTGgodGhpcykKdC5kLmIoYikKdC5jaFsxXS5iKGMpCnRocm93IEguYihQLkw0KCJD
-YW5ub3QgbW9kaWZ5IHVubW9kaWZpYWJsZSBtYXAiKSl9fQpQLlBuLnByb3RvdHlwZT17CnE6ZnVuY3Rp
-b24oYSxiKXtyZXR1cm4gSi53Mih0aGlzLmEsYil9LApZOmZ1bmN0aW9uKGEsYixjKXt2YXIgdD1ILkxo
-KHRoaXMpCkouQjIodGhpcy5hLHQuZC5iKGIpLHQuY2hbMV0uYihjKSl9LApVOmZ1bmN0aW9uKGEsYil7
-Si5oRSh0aGlzLmEsSC5MaCh0aGlzKS5DKCJ+KDEsMikiKS5iKGIpKX0sCmdoOmZ1bmN0aW9uKGEpe3Jl
-dHVybiBKLkhtKHRoaXMuYSl9LAp3OmZ1bmN0aW9uKGEpe3JldHVybiBKLmoodGhpcy5hKX0sCmdQdTpm
-dW5jdGlvbihhKXtyZXR1cm4gSi5RTSh0aGlzLmEpfSwKJGlaMDoxfQpQLkdqLnByb3RvdHlwZT17fQpQ
-LmxmLnByb3RvdHlwZT17Cnc6ZnVuY3Rpb24oYSl7cmV0dXJuIFAuV0UodGhpcywieyIsIn0iKX19ClAu
-UksucHJvdG90eXBlPXskaWJROjEsJGljWDoxLCRpeHU6MX0KUC5Ydi5wcm90b3R5cGU9ewpGVjpmdW5j
-dGlvbihhLGIpe3ZhciB0CmZvcih0PUouSVQoSC5MaCh0aGlzKS5DKCJjWDwxPiIpLmIoYikpO3QubSgp
-Oyl0aGlzLkEoMCx0LmdSKHQpKX0sCnc6ZnVuY3Rpb24oYSl7cmV0dXJuIFAuV0UodGhpcywieyIsIn0i
-KX0sCnpWOmZ1bmN0aW9uKGEsYil7dmFyIHQscz1QLnJqKHRoaXMsdGhpcy5yLEguTGgodGhpcykuZCkK
-aWYoIXMubSgpKXJldHVybiIiCmlmKGI9PT0iIil7dD0iIgpkbyB0Kz1ILmQocy5kKQp3aGlsZShzLm0o
-KSl9ZWxzZXt0PUguZChzLmQpCmZvcig7cy5tKCk7KXQ9dCtiK0guZChzLmQpfXJldHVybiB0LmNoYXJD
-b2RlQXQoMCk9PTA/dDp0fSwKJGliUToxLAokaWNYOjEsCiRpeHU6MX0KUC5uWS5wcm90b3R5cGU9e30K
-UC5XWS5wcm90b3R5cGU9e30KUC5SVS5wcm90b3R5cGU9e30KUC51dy5wcm90b3R5cGU9ewpxOmZ1bmN0
-aW9uKGEsYil7dmFyIHQscz10aGlzLmIKaWYocz09bnVsbClyZXR1cm4gdGhpcy5jLnEoMCxiKQplbHNl
-IGlmKHR5cGVvZiBiIT0ic3RyaW5nIilyZXR1cm4gbnVsbAplbHNle3Q9c1tiXQpyZXR1cm4gdHlwZW9m
-IHQ9PSJ1bmRlZmluZWQiP3RoaXMuZmIoYik6dH19LApnaDpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5i
-PT1udWxsP3RoaXMuYy5hOnRoaXMuQ2YoKS5sZW5ndGh9LApndjpmdW5jdGlvbihhKXt2YXIgdAppZih0
-aGlzLmI9PW51bGwpe3Q9dGhpcy5jCnJldHVybiBuZXcgSC5pNSh0LEguTGgodCkuQygiaTU8MT4iKSl9
-cmV0dXJuIG5ldyBQLmk4KHRoaXMpfSwKWTpmdW5jdGlvbihhLGIsYyl7dmFyIHQscyxyPXRoaXMKaWYo
-ci5iPT1udWxsKXIuYy5ZKDAsYixjKQplbHNlIGlmKHIueDQoMCxiKSl7dD1yLmIKdFtiXT1jCnM9ci5h
-CmlmKHM9PW51bGw/dCE9bnVsbDpzIT09dClzW2JdPW51bGx9ZWxzZSByLlhLKCkuWSgwLGIsYyl9LAp4
-NDpmdW5jdGlvbihhLGIpe2lmKHRoaXMuYj09bnVsbClyZXR1cm4gdGhpcy5jLng0KDAsYikKcmV0dXJu
-IE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbCh0aGlzLmEsYil9LApVOmZ1bmN0aW9u
-KGEsYil7dmFyIHQscyxyLHEscD10aGlzCnUuVC5iKGIpCmlmKHAuYj09bnVsbClyZXR1cm4gcC5jLlUo
-MCxiKQp0PXAuQ2YoKQpmb3Iocz0wO3M8dC5sZW5ndGg7KytzKXtyPXRbc10KcT1wLmJbcl0KaWYodHlw
-ZW9mIHE9PSJ1bmRlZmluZWQiKXtxPVAuUWUocC5hW3JdKQpwLmJbcl09cX1iLiQyKHIscSkKaWYodCE9
-PXAuYyl0aHJvdyBILmIoUC5hNChwKSl9fSwKQ2Y6ZnVuY3Rpb24oKXt2YXIgdD11LmouYih0aGlzLmMp
-CmlmKHQ9PW51bGwpdD10aGlzLmM9SC5WTShPYmplY3Qua2V5cyh0aGlzLmEpLHUucykKcmV0dXJuIHR9
-LApYSzpmdW5jdGlvbigpe3ZhciB0LHMscixxLHAsbz10aGlzCmlmKG8uYj09bnVsbClyZXR1cm4gby5j
-CnQ9UC5GbCh1Lk4sdS56KQpzPW8uQ2YoKQpmb3Iocj0wO3E9cy5sZW5ndGgscjxxOysrcil7cD1zW3Jd
-CnQuWSgwLHAsby5xKDAscCkpfWlmKHE9PT0wKUMuTm0uQShzLG51bGwpCmVsc2UgQy5ObS5zaChzLDAp
-Cm8uYT1vLmI9bnVsbApyZXR1cm4gby5jPXR9LApmYjpmdW5jdGlvbihhKXt2YXIgdAppZighT2JqZWN0
-LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHRoaXMuYSxhKSlyZXR1cm4gbnVsbAp0PVAuUWUo
-dGhpcy5hW2FdKQpyZXR1cm4gdGhpcy5iW2FdPXR9fQpQLmk4LnByb3RvdHlwZT17CmdoOmZ1bmN0aW9u
-KGEpe3ZhciB0PXRoaXMuYQpyZXR1cm4gdC5naCh0KX0sClc6ZnVuY3Rpb24oYSxiKXt2YXIgdD10aGlz
-LmEKaWYodC5iPT1udWxsKXQ9dC5ndih0KS5XKDAsYikKZWxzZXt0PXQuQ2YoKQppZihiPDB8fGI+PXQu
-bGVuZ3RoKXJldHVybiBILk9IKHQsYikKdD10W2JdfXJldHVybiB0fSwKZ2t6OmZ1bmN0aW9uKGEpe3Zh
-ciB0PXRoaXMuYQppZih0LmI9PW51bGwpe3Q9dC5ndih0KQp0PXQuZ2t6KHQpfWVsc2V7dD10LkNmKCkK
-dD1uZXcgSi5tMSh0LHQubGVuZ3RoLEgudDYodCkuQygibTE8MT4iKSl9cmV0dXJuIHR9fQpQLkNWLnBy
-b3RvdHlwZT17CnlyOmZ1bmN0aW9uKGEsYTAsYTEsYTIpe3ZhciB0LHMscixxLHAsbyxuLG0sbCxrLGos
-aSxoLGcsZixlLGQsYyxiPSJJbnZhbGlkIGJhc2U2NCBlbmNvZGluZyBsZW5ndGggIgphMj1QLmpCKGEx
-LGEyLGEwLmxlbmd0aCkKdD0kLlY3KCkKZm9yKHM9YTEscj1zLHE9bnVsbCxwPS0xLG89LTEsbj0wO3M8
-YTI7cz1tKXttPXMrMQpsPUMueEIuV2QoYTAscykKaWYobD09PTM3KXtrPW0rMgppZihrPD1hMil7aj1I
-Lm9vKEMueEIuV2QoYTAsbSkpCmk9SC5vbyhDLnhCLldkKGEwLG0rMSkpCmg9aioxNitpLShpJjI1NikK
-aWYoaD09PTM3KWg9LTEKbT1rfWVsc2UgaD0tMX1lbHNlIGg9bAppZigwPD1oJiZoPD0xMjcpe2lmKGg8
-MHx8aD49dC5sZW5ndGgpcmV0dXJuIEguT0godCxoKQpnPXRbaF0KaWYoZz49MCl7aD1DLnhCLk8yKCJB
-QkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4
-OSsvIixnKQppZihoPT09bCljb250aW51ZQpsPWh9ZWxzZXtpZihnPT09LTEpe2lmKHA8MCl7Zj1xPT1u
-dWxsP251bGw6cS5hLmxlbmd0aAppZihmPT1udWxsKWY9MApwPWYrKHMtcikKbz1zfSsrbgppZihsPT09
-NjEpY29udGludWV9bD1ofWlmKGchPT0tMil7aWYocT09bnVsbClxPW5ldyBQLlJuKCIiKQpxLmErPUMu
-eEIuTmooYTAscixzKQpxLmErPUguTHcobCkKcj1tCmNvbnRpbnVlfX10aHJvdyBILmIoUC5ycigiSW52
-YWxpZCBiYXNlNjQgZGF0YSIsYTAscykpfWlmKHEhPW51bGwpe2Y9cS5hKz1DLnhCLk5qKGEwLHIsYTIp
-CmU9Zi5sZW5ndGgKaWYocD49MClQLnhNKGEwLG8sYTIscCxuLGUpCmVsc2V7ZD1DLmpuLnpZKGUtMSw0
-KSsxCmlmKGQ9PT0xKXRocm93IEguYihQLnJyKGIsYTAsYTIpKQpmb3IoO2Q8NDspe2YrPSI9IgpxLmE9
-ZjsrK2R9fWY9cS5hCnJldHVybiBDLnhCLmk3KGEwLGExLGEyLGYuY2hhckNvZGVBdCgwKT09MD9mOmYp
-fWM9YTItYTEKaWYocD49MClQLnhNKGEwLG8sYTIscCxuLGMpCmVsc2V7ZD1DLmpuLnpZKGMsNCkKaWYo
-ZD09PTEpdGhyb3cgSC5iKFAucnIoYixhMCxhMikpCmlmKGQ+MSlhMD1DLnhCLmk3KGEwLGEyLGEyLGQ9
-PT0yPyI9PSI6Ij0iKX1yZXR1cm4gYTB9fQpQLnZBLnByb3RvdHlwZT17fQpQLlVrLnByb3RvdHlwZT17
-fQpQLndJLnByb3RvdHlwZT17fQpQLlppLnByb3RvdHlwZT17fQpQLmJ5LnByb3RvdHlwZT17CnBXOmZ1
-bmN0aW9uKGEsYixjKXt2YXIgdAp1LmVwLmIoYykKdD1QLkJTKGIsdGhpcy5nSGUoKS5hKQpyZXR1cm4g
-dH0sCmdIZTpmdW5jdGlvbigpe3JldHVybiBDLkEzfX0KUC5NeC5wcm90b3R5cGU9e30KUC51NS5wcm90
-b3R5cGU9ewpnWkU6ZnVuY3Rpb24oKXtyZXR1cm4gQy5Ra319ClAuRTMucHJvdG90eXBlPXsKV0o6ZnVu
-Y3Rpb24oYSl7dmFyIHQscyxyPVAuakIoMCxudWxsLGEubGVuZ3RoKSxxPXItMAppZihxPT09MClyZXR1
-cm4gbmV3IFVpbnQ4QXJyYXkoMCkKdD1uZXcgVWludDhBcnJheShxKjMpCnM9bmV3IFAuUncodCkKaWYo
-cy5HeChhLDAscikhPT1yKXMuTzYoSi5hNihhLHItMSksMCkKcmV0dXJuIG5ldyBVaW50OEFycmF5KHQu
-c3ViYXJyYXkoMCxILnJNKDAscy5iLHQubGVuZ3RoKSkpfX0KUC5Sdy5wcm90b3R5cGU9ewpPNjpmdW5j
-dGlvbihhLGIpe3ZhciB0LHM9dGhpcyxyPXMuYyxxPXMuYixwPXErMSxvPXIubGVuZ3RoCmlmKChiJjY0
-NTEyKT09PTU2MzIwKXt0PTY1NTM2KygoYSYxMDIzKTw8MTApfGImMTAyMwpzLmI9cAppZihxPj1vKXJl
-dHVybiBILk9IKHIscSkKcltxXT0yNDB8dD4+PjE4CnE9cy5iPXArMQppZihwPj1vKXJldHVybiBILk9I
-KHIscCkKcltwXT0xMjh8dD4+PjEyJjYzCnA9cy5iPXErMQppZihxPj1vKXJldHVybiBILk9IKHIscSkK
-cltxXT0xMjh8dD4+PjYmNjMKcy5iPXArMQppZihwPj1vKXJldHVybiBILk9IKHIscCkKcltwXT0xMjh8
-dCY2MwpyZXR1cm4hMH1lbHNle3MuYj1wCmlmKHE+PW8pcmV0dXJuIEguT0gocixxKQpyW3FdPTIyNHxh
-Pj4+MTIKcT1zLmI9cCsxCmlmKHA+PW8pcmV0dXJuIEguT0gocixwKQpyW3BdPTEyOHxhPj4+NiY2Mwpz
-LmI9cSsxCmlmKHE+PW8pcmV0dXJuIEguT0gocixxKQpyW3FdPTEyOHxhJjYzCnJldHVybiExfX0sCkd4
-OmZ1bmN0aW9uKGEsYixjKXt2YXIgdCxzLHIscSxwLG8sbixtPXRoaXMKaWYoYiE9PWMmJihDLnhCLk8y
-KGEsYy0xKSY2NDUxMik9PT01NTI5NiktLWMKZm9yKHQ9bS5jLHM9dC5sZW5ndGgscj1iO3I8YzsrK3Ip
-e3E9Qy54Qi5XZChhLHIpCmlmKHE8PTEyNyl7cD1tLmIKaWYocD49cylicmVhawptLmI9cCsxCnRbcF09
-cX1lbHNlIGlmKChxJjY0NTEyKT09PTU1Mjk2KXtpZihtLmIrMz49cylicmVhawpvPXIrMQppZihtLk82
-KHEsQy54Qi5XZChhLG8pKSlyPW99ZWxzZSBpZihxPD0yMDQ3KXtwPW0uYgpuPXArMQppZihuPj1zKWJy
-ZWFrCm0uYj1uCmlmKHA+PXMpcmV0dXJuIEguT0godCxwKQp0W3BdPTE5MnxxPj4+NgptLmI9bisxCnRb
-bl09MTI4fHEmNjN9ZWxzZXtwPW0uYgppZihwKzI+PXMpYnJlYWsKbj1tLmI9cCsxCmlmKHA+PXMpcmV0
-dXJuIEguT0godCxwKQp0W3BdPTIyNHxxPj4+MTIKcD1tLmI9bisxCmlmKG4+PXMpcmV0dXJuIEguT0go
-dCxuKQp0W25dPTEyOHxxPj4+NiY2MwptLmI9cCsxCmlmKHA+PXMpcmV0dXJuIEguT0godCxwKQp0W3Bd
-PTEyOHxxJjYzfX1yZXR1cm4gcn19ClAuR1kucHJvdG90eXBlPXsKV0o6ZnVuY3Rpb24oYSl7dmFyIHQs
-cyxyLHEscCxvLG4sbSxsCnUuTC5iKGEpCnQ9UC5reSghMSxhLDAsbnVsbCkKaWYodCE9bnVsbClyZXR1
-cm4gdApzPVAuakIoMCxudWxsLEouSG0oYSkpCnI9UC5jUChhLDAscykKaWYocj4wKXtxPVAuSE0oYSww
-LHIpCmlmKHI9PT1zKXJldHVybiBxCnA9bmV3IFAuUm4ocSkKbz1yCm49ITF9ZWxzZXtvPTAKcD1udWxs
-Cm49ITB9aWYocD09bnVsbClwPW5ldyBQLlJuKCIiKQptPW5ldyBQLmJ6KCExLHApCm0uYz1uCm0uTUUo
-YSxvLHMpCmlmKG0uZT4wKXtILlZqKFAucnIoIlVuZmluaXNoZWQgVVRGLTggb2N0ZXQgc2VxdWVuY2Ui
-LGEscykpCnAuYSs9SC5Mdyg2NTUzMykKbS5mPW0uZT1tLmQ9MH1sPXAuYQpyZXR1cm4gbC5jaGFyQ29k
-ZUF0KDApPT0wP2w6bH19ClAuYnoucHJvdG90eXBlPXsKTUU6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0LHMs
-cixxLHAsbyxuLG0sbCxrLGosaSxoPXRoaXMsZz0iQmFkIFVURi04IGVuY29kaW5nIDB4Igp1LkwuYihh
-KQp0PWguZApzPWguZQpyPWguZgpoLmY9aC5lPWguZD0wCiRsYWJlbDAkMDpmb3IocT1KLlU2KGEpLHA9
-aC5iLG89YjshMDtvPWopeyRsYWJlbDEkMTppZihzPjApe2Rve2lmKG89PT1jKWJyZWFrICRsYWJlbDAk
-MApuPXEucShhLG8pCmlmKHR5cGVvZiBuIT09Im51bWJlciIpcmV0dXJuIG4uek0oKQppZigobiYxOTIp
-IT09MTI4KXttPVAucnIoZytDLmpuLkQ4KG4sMTYpLGEsbykKdGhyb3cgSC5iKG0pfWVsc2V7dD0odDw8
-NnxuJjYzKT4+PjA7LS1zOysrb319d2hpbGUocz4wKQptPXItMQppZihtPDB8fG0+PTQpcmV0dXJuIEgu
-T0goQy5HYixtKQppZih0PD1DLkdiW21dKXttPVAucnIoIk92ZXJsb25nIGVuY29kaW5nIG9mIDB4IitD
-LmpuLkQ4KHQsMTYpLGEsby1yLTEpCnRocm93IEguYihtKX1pZih0PjExMTQxMTEpe209UC5ycigiQ2hh
-cmFjdGVyIG91dHNpZGUgdmFsaWQgVW5pY29kZSByYW5nZTogMHgiK0Muam4uRDgodCwxNiksYSxvLXIt
-MSkKdGhyb3cgSC5iKG0pfWlmKCFoLmN8fHQhPT02NTI3OSlwLmErPUguTHcodCkKaC5jPSExfWZvciht
-PW88YzttOyl7bD1QLmNQKGEsbyxjKQppZihsPjApe2guYz0hMQprPW8rbApwLmErPVAuSE0oYSxvLGsp
-CmlmKGs9PT1jKWJyZWFrfWVsc2Ugaz1vCmo9aysxCm49cS5xKGEsaykKaWYodHlwZW9mIG4hPT0ibnVt
-YmVyIilyZXR1cm4gbi5KKCkKaWYobjwwKXtpPVAucnIoIk5lZ2F0aXZlIFVURi04IGNvZGUgdW5pdDog
-LTB4IitDLmpuLkQ4KC1uLDE2KSxhLGotMSkKdGhyb3cgSC5iKGkpfWVsc2V7aWYoKG4mMjI0KT09PTE5
-Mil7dD1uJjMxCnM9MQpyPTEKY29udGludWUgJGxhYmVsMCQwfWlmKChuJjI0MCk9PT0yMjQpe3Q9biYx
-NQpzPTIKcj0yCmNvbnRpbnVlICRsYWJlbDAkMH1pZigobiYyNDgpPT09MjQwJiZuPDI0NSl7dD1uJjcK
-cz0zCnI9Mwpjb250aW51ZSAkbGFiZWwwJDB9aT1QLnJyKGcrQy5qbi5EOChuLDE2KSxhLGotMSkKdGhy
-b3cgSC5iKGkpfX1icmVhayAkbGFiZWwwJDB9aWYocz4wKXtoLmQ9dApoLmU9cwpoLmY9cn19fQpQLldG
-LnByb3RvdHlwZT17CiQyOmZ1bmN0aW9uKGEsYil7dmFyIHQscyxyCnUuZm8uYihhKQp0PXRoaXMuYgpz
-PXRoaXMuYQp0LmErPXMuYQpyPXQuYSs9SC5kKGEuYSkKdC5hPXIrIjogIgp0LmErPVAucChiKQpzLmE9
-IiwgIn0sCiRTOjQ3fQpQLmEyLnByb3RvdHlwZT17fQpQLmlQLnByb3RvdHlwZT17CkROOmZ1bmN0aW9u
-KGEsYil7aWYoYj09bnVsbClyZXR1cm4hMQpyZXR1cm4gYiBpbnN0YW5jZW9mIFAuaVAmJnRoaXMuYT09
-PWIuYSYmdGhpcy5iPT09Yi5ifSwKWGs6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzPXRoaXMuYQppZihNYXRo
-LmFicyhzKTw9ODY0ZTEzKXQ9ITEKZWxzZSB0PSEwCmlmKHQpdGhyb3cgSC5iKFAueFkoIkRhdGVUaW1l
-IGlzIG91dHNpZGUgdmFsaWQgcmFuZ2U6ICIrcykpfSwKZ2k6ZnVuY3Rpb24oYSl7dmFyIHQ9dGhpcy5h
-CnJldHVybih0XkMuam4ud0codCwzMCkpJjEwNzM3NDE4MjN9LAp3OmZ1bmN0aW9uKGEpe3ZhciB0PXRo
-aXMscz1QLkdxKEgudEoodCkpLHI9UC5oMChILk5TKHQpKSxxPVAuaDAoSC5qQSh0KSkscD1QLmgwKEgu
-S0wodCkpLG89UC5oMChILmNoKHQpKSxuPVAuaDAoSC5KZCh0KSksbT1QLlZ4KEgubzEodCkpCmlmKHQu
-YilyZXR1cm4gcysiLSIrcisiLSIrcSsiICIrcCsiOiIrbysiOiIrbisiLiIrbSsiWiIKZWxzZSByZXR1
-cm4gcysiLSIrcisiLSIrcSsiICIrcCsiOiIrbysiOiIrbisiLiIrbX19ClAuQ1AucHJvdG90eXBlPXt9
-ClAuWFMucHJvdG90eXBlPXt9ClAuQzYucHJvdG90eXBlPXsKdzpmdW5jdGlvbihhKXt2YXIgdD10aGlz
-LmEKaWYodCE9bnVsbClyZXR1cm4iQXNzZXJ0aW9uIGZhaWxlZDogIitQLnAodCkKcmV0dXJuIkFzc2Vy
-dGlvbiBmYWlsZWQifX0KUC5uLnByb3RvdHlwZT17Cnc6ZnVuY3Rpb24oYSl7cmV0dXJuIlRocm93IG9m
-IG51bGwuIn19ClAudS5wcm90b3R5cGU9ewpnWjpmdW5jdGlvbigpe3JldHVybiJJbnZhbGlkIGFyZ3Vt
-ZW50IisoIXRoaXMuYT8iKHMpIjoiIil9LApndTpmdW5jdGlvbigpe3JldHVybiIifSwKdzpmdW5jdGlv
-bihhKXt2YXIgdCxzLHIscSxwPXRoaXMsbz1wLmMsbj1vIT1udWxsPyIgKCIrbysiKSI6IiIKbz1wLmQK
-dD1vPT1udWxsPyIiOiI6ICIrSC5kKG8pCnM9cC5nWigpK24rdAppZighcC5hKXJldHVybiBzCnI9cC5n
-dSgpCnE9UC5wKHAuYikKcmV0dXJuIHMrcisiOiAiK3F9fQpQLmJKLnByb3RvdHlwZT17CmdaOmZ1bmN0
-aW9uKCl7cmV0dXJuIlJhbmdlRXJyb3IifSwKZ3U6ZnVuY3Rpb24oKXt2YXIgdCxzLHI9dGhpcy5lCmlm
-KHI9PW51bGwpe3I9dGhpcy5mCnQ9ciE9bnVsbD8iOiBOb3QgbGVzcyB0aGFuIG9yIGVxdWFsIHRvICIr
-SC5kKHIpOiIifWVsc2V7cz10aGlzLmYKaWYocz09bnVsbCl0PSI6IE5vdCBncmVhdGVyIHRoYW4gb3Ig
-ZXF1YWwgdG8gIitILmQocikKZWxzZSBpZihzPnIpdD0iOiBOb3QgaW4gcmFuZ2UgIitILmQocikrIi4u
-IitILmQocykrIiwgaW5jbHVzaXZlIgplbHNlIHQ9czxyPyI6IFZhbGlkIHZhbHVlIHJhbmdlIGlzIGVt
-cHR5IjoiOiBPbmx5IHZhbGlkIHZhbHVlIGlzICIrSC5kKHIpfXJldHVybiB0fX0KUC5lWS5wcm90b3R5
-cGU9ewpnWjpmdW5jdGlvbigpe3JldHVybiJSYW5nZUVycm9yIn0sCmd1OmZ1bmN0aW9uKCl7dmFyIHQs
-cz1ILlNjKHRoaXMuYikKaWYodHlwZW9mIHMhPT0ibnVtYmVyIilyZXR1cm4gcy5KKCkKaWYoczwwKXJl
-dHVybiI6IGluZGV4IG11c3Qgbm90IGJlIG5lZ2F0aXZlIgp0PXRoaXMuZgppZih0PT09MClyZXR1cm4i
-OiBubyBpbmRpY2VzIGFyZSB2YWxpZCIKcmV0dXJuIjogaW5kZXggc2hvdWxkIGJlIGxlc3MgdGhhbiAi
-K0guZCh0KX0sCmdoOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLmZ9fQpQLm1wLnByb3RvdHlwZT17Cnc6
-ZnVuY3Rpb24oYSl7dmFyIHQscyxyLHEscCxvLG4sbSxsPXRoaXMsaz17fSxqPW5ldyBQLlJuKCIiKQpr
-LmE9IiIKZm9yKHQ9bC5jLHM9dC5sZW5ndGgscj0wLHE9IiIscD0iIjtyPHM7KytyLHA9IiwgIil7bz10
-W3JdCmouYT1xK3AKcT1qLmErPVAucChvKQprLmE9IiwgIn1sLmQuVSgwLG5ldyBQLldGKGssaikpCm49
-UC5wKGwuYSkKbT1qLncoMCkKdD0iTm9TdWNoTWV0aG9kRXJyb3I6IG1ldGhvZCBub3QgZm91bmQ6ICci
-K0guZChsLmIuYSkrIidcblJlY2VpdmVyOiAiK24rIlxuQXJndW1lbnRzOiBbIittKyJdIgpyZXR1cm4g
-dH19ClAudWIucHJvdG90eXBlPXsKdzpmdW5jdGlvbihhKXtyZXR1cm4iVW5zdXBwb3J0ZWQgb3BlcmF0
-aW9uOiAiK3RoaXMuYX19ClAuZHMucHJvdG90eXBlPXsKdzpmdW5jdGlvbihhKXt2YXIgdD10aGlzLmEK
-cmV0dXJuIHQhPW51bGw/IlVuaW1wbGVtZW50ZWRFcnJvcjogIit0OiJVbmltcGxlbWVudGVkRXJyb3Ii
-fX0KUC5sai5wcm90b3R5cGU9ewp3OmZ1bmN0aW9uKGEpe3JldHVybiJCYWQgc3RhdGU6ICIrdGhpcy5h
-fX0KUC5VVi5wcm90b3R5cGU9ewp3OmZ1bmN0aW9uKGEpe3ZhciB0PXRoaXMuYQppZih0PT1udWxsKXJl
-dHVybiJDb25jdXJyZW50IG1vZGlmaWNhdGlvbiBkdXJpbmcgaXRlcmF0aW9uLiIKcmV0dXJuIkNvbmN1
-cnJlbnQgbW9kaWZpY2F0aW9uIGR1cmluZyBpdGVyYXRpb246ICIrUC5wKHQpKyIuIn19ClAuazUucHJv
-dG90eXBlPXsKdzpmdW5jdGlvbihhKXtyZXR1cm4iT3V0IG9mIE1lbW9yeSJ9LAokaVhTOjF9ClAuS1ku
-cHJvdG90eXBlPXsKdzpmdW5jdGlvbihhKXtyZXR1cm4iU3RhY2sgT3ZlcmZsb3cifSwKJGlYUzoxfQpQ
-LmMucHJvdG90eXBlPXsKdzpmdW5jdGlvbihhKXt2YXIgdD10aGlzLmEKcmV0dXJuIHQ9PW51bGw/IlJl
-YWRpbmcgc3RhdGljIHZhcmlhYmxlIGR1cmluZyBpdHMgaW5pdGlhbGl6YXRpb24iOiJSZWFkaW5nIHN0
-YXRpYyB2YXJpYWJsZSAnIit0KyInIGR1cmluZyBpdHMgaW5pdGlhbGl6YXRpb24ifX0KUC5DRC5wcm90
-b3R5cGU9ewp3OmZ1bmN0aW9uKGEpe3JldHVybiJFeGNlcHRpb246ICIrdGhpcy5hfX0KUC5hRS5wcm90
-b3R5cGU9ewp3OmZ1bmN0aW9uKGEpe3ZhciB0LHMscixxLHAsbyxuLG0sbCxrLGosaSxoPXRoaXMuYSxn
-PWghPW51bGwmJiIiIT09aD8iRm9ybWF0RXhjZXB0aW9uOiAiK0guZChoKToiRm9ybWF0RXhjZXB0aW9u
-IixmPXRoaXMuYyxlPXRoaXMuYgppZih0eXBlb2YgZT09InN0cmluZyIpe2lmKGYhPW51bGwpaD1mPDB8
-fGY+ZS5sZW5ndGgKZWxzZSBoPSExCmlmKGgpZj1udWxsCmlmKGY9PW51bGwpe3Q9ZS5sZW5ndGg+Nzg/
-Qy54Qi5OaihlLDAsNzUpKyIuLi4iOmUKcmV0dXJuIGcrIlxuIit0fWZvcihzPTEscj0wLHE9ITEscD0w
-O3A8ZjsrK3Ape289Qy54Qi5XZChlLHApCmlmKG89PT0xMCl7aWYociE9PXB8fCFxKSsrcwpyPXArMQpx
-PSExfWVsc2UgaWYobz09PTEzKXsrK3MKcj1wKzEKcT0hMH19Zz1zPjE/ZysoIiAoYXQgbGluZSAiK3Mr
-IiwgY2hhcmFjdGVyICIrKGYtcisxKSsiKVxuIik6ZysoIiAoYXQgY2hhcmFjdGVyICIrKGYrMSkrIilc
-biIpCm49ZS5sZW5ndGgKZm9yKHA9ZjtwPG47KytwKXtvPUMueEIuTzIoZSxwKQppZihvPT09MTB8fG89
-PT0xMyl7bj1wCmJyZWFrfX1pZihuLXI+NzgpaWYoZi1yPDc1KXttPXIrNzUKbD1yCms9IiIKaj0iLi4u
-In1lbHNle2lmKG4tZjw3NSl7bD1uLTc1Cm09bgpqPSIifWVsc2V7bD1mLTM2Cm09ZiszNgpqPSIuLi4i
-fWs9Ii4uLiJ9ZWxzZXttPW4KbD1yCms9IiIKaj0iIn1pPUMueEIuTmooZSxsLG0pCnJldHVybiBnK2sr
-aStqKyJcbiIrQy54Qi5JeCgiICIsZi1sK2subGVuZ3RoKSsiXlxuIn1lbHNlIHJldHVybiBmIT1udWxs
-P2crKCIgKGF0IG9mZnNldCAiK0guZChmKSsiKSIpOmd9fQpQLkVILnByb3RvdHlwZT17fQpQLktOLnBy
-b3RvdHlwZT17fQpQLmNYLnByb3RvdHlwZT17CkUyOmZ1bmN0aW9uKGEsYixjKXt2YXIgdD1ILkxoKHRo
-aXMpCnJldHVybiBILksxKHRoaXMsdC5LKGMpLkMoIjEoY1guRSkiKS5iKGIpLHQuQygiY1guRSIpLGMp
-fSwKZXY6ZnVuY3Rpb24oYSxiKXt2YXIgdD1ILkxoKHRoaXMpCnJldHVybiBuZXcgSC5VNSh0aGlzLHQu
-QygiYTIoY1guRSkiKS5iKGIpLHQuQygiVTU8Y1guRT4iKSl9LApnaDpmdW5jdGlvbihhKXt2YXIgdCxz
-PXRoaXMuZ2t6KHRoaXMpCmZvcih0PTA7cy5tKCk7KSsrdApyZXR1cm4gdH0sCmdsMDpmdW5jdGlvbihh
-KXtyZXR1cm4hdGhpcy5na3oodGhpcykubSgpfSwKZ3I4OmZ1bmN0aW9uKGEpe3ZhciB0LHM9dGhpcy5n
-a3oodGhpcykKaWYoIXMubSgpKXRocm93IEguYihILldwKCkpCnQ9cy5nUihzKQppZihzLm0oKSl0aHJv
-dyBILmIoSC5kVSgpKQpyZXR1cm4gdH0sClc6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzLHIKUC5rMShiLCJp
-bmRleCIpCmZvcih0PXRoaXMuZ2t6KHRoaXMpLHM9MDt0Lm0oKTspe3I9dC5nUih0KQppZihiPT09cyly
-ZXR1cm4gcjsrK3N9dGhyb3cgSC5iKFAuQ2YoYix0aGlzLCJpbmRleCIsbnVsbCxzKSl9LAp3OmZ1bmN0
-aW9uKGEpe3JldHVybiBQLkVQKHRoaXMsIigiLCIpIil9fQpQLkFuLnByb3RvdHlwZT17fQpQLnpNLnBy
-b3RvdHlwZT17JGliUToxLCRpY1g6MX0KUC5aMC5wcm90b3R5cGU9e30KUC5OMy5wcm90b3R5cGU9ewp3
-OmZ1bmN0aW9uKGEpe3JldHVybiJNYXBFbnRyeSgiK0guZCh0aGlzLmEpKyI6ICIrSC5kKHRoaXMuYikr
-IikifSwKZ0czOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLmF9LApnbnc6ZnVuY3Rpb24oYSl7cmV0dXJu
-IHRoaXMuYn19ClAuYzgucHJvdG90eXBlPXsKZ2k6ZnVuY3Rpb24oYSl7cmV0dXJuIFAuay5wcm90b3R5
-cGUuZ2kuY2FsbCh0aGlzLHRoaXMpfSwKdzpmdW5jdGlvbihhKXtyZXR1cm4ibnVsbCJ9fQpQLkZLLnBy
-b3RvdHlwZT17fQpQLmsucHJvdG90eXBlPXtjb25zdHJ1Y3RvcjpQLmssJGlrOjEsCkROOmZ1bmN0aW9u
-KGEsYil7cmV0dXJuIHRoaXM9PT1ifSwKZ2k6ZnVuY3Rpb24oYSl7cmV0dXJuIEguZVEodGhpcyl9LAp3
-OmZ1bmN0aW9uKGEpe3JldHVybiJJbnN0YW5jZSBvZiAnIitILmQoSC5NKHRoaXMpKSsiJyJ9LAplNzpm
-dW5jdGlvbihhLGIpe3Uuby5iKGIpCnRocm93IEguYihQLmxyKHRoaXMsYi5nV2EoKSxiLmduZCgpLGIu
-Z1ZtKCkpKX0sCnRvU3RyaW5nOmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMudyh0aGlzKX19ClAuT2QucHJv
-dG90eXBlPXt9ClAuaWIucHJvdG90eXBlPXskaU9kOjF9ClAueHUucHJvdG90eXBlPXt9ClAuR3oucHJv
-dG90eXBlPXt9ClAucVUucHJvdG90eXBlPXskaXZYOjF9ClAuUm4ucHJvdG90eXBlPXsKZ2g6ZnVuY3Rp
-b24oYSl7cmV0dXJuIHRoaXMuYS5sZW5ndGh9LAp3OmZ1bmN0aW9uKGEpe3ZhciB0PXRoaXMuYQpyZXR1
-cm4gdC5jaGFyQ29kZUF0KDApPT0wP3Q6dH0sCiRpQkw6MX0KUC5HRC5wcm90b3R5cGU9e30KUC5uMS5w
-cm90b3R5cGU9ewokMjpmdW5jdGlvbihhLGIpe3ZhciB0LHMscixxCnUuZi5iKGEpCkgueShiKQp0PUou
-clkoYikuT1koYiwiPSIpCmlmKHQ9PT0tMSl7aWYoYiE9PSIiKUouQjIoYSxQLmt1KGIsMCxiLmxlbmd0
-aCx0aGlzLmEsITApLCIiKX1lbHNlIGlmKHQhPT0wKXtzPUMueEIuTmooYiwwLHQpCnI9Qy54Qi55bihi
-LHQrMSkKcT10aGlzLmEKSi5CMihhLFAua3UocywwLHMubGVuZ3RoLHEsITApLFAua3UociwwLHIubGVu
-Z3RoLHEsITApKX1yZXR1cm4gYX0sCiRTOjI0fQpQLmNTLnByb3RvdHlwZT17CiQyOmZ1bmN0aW9uKGEs
-Yil7dGhyb3cgSC5iKFAucnIoIklsbGVnYWwgSVB2NCBhZGRyZXNzLCAiK2EsdGhpcy5hLGIpKX0sCiRT
-OjQ4fQpQLlZDLnByb3RvdHlwZT17CiQyOmZ1bmN0aW9uKGEsYil7dGhyb3cgSC5iKFAucnIoIklsbGVn
-YWwgSVB2NiBhZGRyZXNzLCAiK2EsdGhpcy5hLGIpKX0sCiQxOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlz
-LiQyKGEsbnVsbCl9LAokUzozMX0KUC5KVC5wcm90b3R5cGU9ewokMjpmdW5jdGlvbihhLGIpe3ZhciB0
-CmlmKGItYT40KXRoaXMuYS4kMigiYW4gSVB2NiBwYXJ0IGNhbiBvbmx5IGNvbnRhaW4gYSBtYXhpbXVt
-IG9mIDQgaGV4IGRpZ2l0cyIsYSkKdD1QLlFBKEMueEIuTmoodGhpcy5iLGEsYiksbnVsbCwxNikKaWYo
-dHlwZW9mIHQhPT0ibnVtYmVyIilyZXR1cm4gdC5KKCkKaWYodDwwfHx0PjY1NTM1KXRoaXMuYS4kMigi
-ZWFjaCBwYXJ0IG11c3QgYmUgaW4gdGhlIHJhbmdlIG9mIGAweDAuLjB4RkZGRmAiLGEpCnJldHVybiB0
-fSwKJFM6MzV9ClAuRG4ucHJvdG90eXBlPXsKZ2t1OmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuYn0sCmdK
-ZjpmdW5jdGlvbihhKXt2YXIgdD10aGlzLmMKaWYodD09bnVsbClyZXR1cm4iIgppZihDLnhCLm5DKHQs
-IlsiKSlyZXR1cm4gQy54Qi5Oaih0LDEsdC5sZW5ndGgtMSkKcmV0dXJuIHR9LApndHA6ZnVuY3Rpb24o
-YSl7dmFyIHQ9dGhpcy5kCmlmKHQ9PW51bGwpcmV0dXJuIFAud0sodGhpcy5hKQpyZXR1cm4gdH0sCmd0
-UDpmdW5jdGlvbihhKXt2YXIgdD10aGlzLmYKcmV0dXJuIHQ9PW51bGw/IiI6dH0sCmdLYTpmdW5jdGlv
-bigpe3ZhciB0PXRoaXMucgpyZXR1cm4gdD09bnVsbD8iIjp0fSwKbm06ZnVuY3Rpb24oYSxiKXt2YXIg
-dCxzLHIscSxwLG8sbixtLGw9dGhpcwp1LlguYihudWxsKQp1LmIuYihiKQp0PWwuYQpzPXQ9PT0iZmls
-ZSIKcj1sLmIKcT1sLmQKcD1sLmMKaWYoIShwIT1udWxsKSlwPXIubGVuZ3RoIT09MHx8cSE9bnVsbHx8
-cz8iIjpudWxsCm89bC5lCmlmKCFzKW49cCE9bnVsbCYmby5sZW5ndGghPT0wCmVsc2Ugbj0hMAppZihu
-JiYhQy54Qi5uQyhvLCIvIikpbz0iLyIrbwptPVAubGUobnVsbCwwLDAsYikKcmV0dXJuIG5ldyBQLkRu
-KHQscixwLHEsbyxtLGwucil9LApnRmo6ZnVuY3Rpb24oKXt2YXIgdCxzPXRoaXMueAppZihzIT1udWxs
-KXJldHVybiBzCnQ9dGhpcy5lCmlmKHQubGVuZ3RoIT09MCYmQy54Qi5XZCh0LDApPT09NDcpdD1DLnhC
-LnluKHQsMSkKcz10PT09IiI/Qy54RDpQLkFGKG5ldyBILkE4KEguVk0odC5zcGxpdCgiLyIpLHUucyks
-dS5kTy5iKFAuUEgoKSksdS5kbyksdS5OKQp0aGlzLnNvNihzKQpyZXR1cm4gc30sCmdoWTpmdW5jdGlv
-bigpe3ZhciB0LHM9dGhpcwppZihzLlE9PW51bGwpe3Q9cy5mCnMuc1JIKG5ldyBQLkdqKFAuV1godD09
-bnVsbD8iIjp0KSx1LlcpKX1yZXR1cm4gcy5RfSwKSmg6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzLHIscSxw
-LG8KZm9yKHQ9MCxzPTA7Qy54Qi5RaShiLCIuLi8iLHMpOyl7cys9MzsrK3R9cj1DLnhCLmNuKGEsIi8i
-KQp3aGlsZSghMCl7aWYoIShyPjAmJnQ+MCkpYnJlYWsKcT1DLnhCLlBrKGEsIi8iLHItMSkKaWYocTww
-KWJyZWFrCnA9ci1xCm89cCE9PTIKaWYoIW98fHA9PT0zKWlmKEMueEIuTzIoYSxxKzEpPT09NDYpbz0h
-b3x8Qy54Qi5PMihhLHErMik9PT00NgplbHNlIG89ITEKZWxzZSBvPSExCmlmKG8pYnJlYWs7LS10CnI9
-cX1yZXR1cm4gQy54Qi5pNyhhLHIrMSxudWxsLEMueEIueW4oYixzLTMqdCkpfSwKWkk6ZnVuY3Rpb24o
-YSl7cmV0dXJuIHRoaXMubVMoUC5oSyhhKSl9LAptUzpmdW5jdGlvbihhKXt2YXIgdCxzLHIscSxwLG8s
-bixtLGwsaz10aGlzLGo9bnVsbAppZihhLmdGaSgpLmxlbmd0aCE9PTApe3Q9YS5nRmkoKQppZihhLmdj
-aigpKXtzPWEuZ2t1KCkKcj1hLmdKZihhKQpxPWEuZ3hBKCk/YS5ndHAoYSk6an1lbHNle3E9agpyPXEK
-cz0iIn1wPVAueGUoYS5nSWkoYSkpCm89YS5nUUQoKT9hLmd0UChhKTpqfWVsc2V7dD1rLmEKaWYoYS5n
-Y2ooKSl7cz1hLmdrdSgpCnI9YS5nSmYoYSkKcT1QLndCKGEuZ3hBKCk/YS5ndHAoYSk6aix0KQpwPVAu
-eGUoYS5nSWkoYSkpCm89YS5nUUQoKT9hLmd0UChhKTpqfWVsc2V7cz1rLmIKcj1rLmMKcT1rLmQKaWYo
-YS5nSWkoYSk9PT0iIil7cD1rLmUKbz1hLmdRRCgpP2EuZ3RQKGEpOmsuZn1lbHNle2lmKGEuZ3RUKCkp
-cD1QLnhlKGEuZ0lpKGEpKQplbHNle249ay5lCmlmKG4ubGVuZ3RoPT09MClpZihyPT1udWxsKXA9dC5s
-ZW5ndGg9PT0wP2EuZ0lpKGEpOlAueGUoYS5nSWkoYSkpCmVsc2UgcD1QLnhlKCIvIithLmdJaShhKSkK
-ZWxzZXttPWsuSmgobixhLmdJaShhKSkKbD10Lmxlbmd0aD09PTAKaWYoIWx8fHIhPW51bGx8fEMueEIu
-bkMobiwiLyIpKXA9UC54ZShtKQplbHNlIHA9UC53RihtLCFsfHxyIT1udWxsKX19bz1hLmdRRCgpP2Eu
-Z3RQKGEpOmp9fX1yZXR1cm4gbmV3IFAuRG4odCxzLHIscSxwLG8sYS5nWjgoKT9hLmdLYSgpOmopfSwK
-Z2NqOmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuYyE9bnVsbH0sCmd4QTpmdW5jdGlvbigpe3JldHVybiB0
-aGlzLmQhPW51bGx9LApnUUQ6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5mIT1udWxsfSwKZ1o4OmZ1bmN0
-aW9uKCl7cmV0dXJuIHRoaXMuciE9bnVsbH0sCmd0VDpmdW5jdGlvbigpe3JldHVybiBDLnhCLm5DKHRo
-aXMuZSwiLyIpfSwKdDQ6ZnVuY3Rpb24oKXt2YXIgdCxzLHI9dGhpcyxxPXIuYQppZihxIT09IiImJnEh
-PT0iZmlsZSIpdGhyb3cgSC5iKFAuTDQoIkNhbm5vdCBleHRyYWN0IGEgZmlsZSBwYXRoIGZyb20gYSAi
-K0guZChxKSsiIFVSSSIpKQpxPXIuZgppZigocT09bnVsbD8iIjpxKSE9PSIiKXRocm93IEguYihQLkw0
-KCJDYW5ub3QgZXh0cmFjdCBhIGZpbGUgcGF0aCBmcm9tIGEgVVJJIHdpdGggYSBxdWVyeSBjb21wb25l
-bnQiKSkKcT1yLnIKaWYoKHE9PW51bGw/IiI6cSkhPT0iIil0aHJvdyBILmIoUC5MNCgiQ2Fubm90IGV4
-dHJhY3QgYSBmaWxlIHBhdGggZnJvbSBhIFVSSSB3aXRoIGEgZnJhZ21lbnQgY29tcG9uZW50IikpCnQ9
-JC5PeCgpCmlmKEgub1QodCkpcT1QLm1uKHIpCmVsc2V7aWYoci5jIT1udWxsJiZyLmdKZihyKSE9PSIi
-KUguVmooUC5MNCgiQ2Fubm90IGV4dHJhY3QgYSBub24tV2luZG93cyBmaWxlIHBhdGggZnJvbSBhIGZp
-bGUgVVJJIHdpdGggYW4gYXV0aG9yaXR5IikpCnM9ci5nRmooKQpQLmtFKHMsITEpCnE9UC52ZyhDLnhC
-Lm5DKHIuZSwiLyIpPyIvIjoiIixzLCIvIikKcT1xLmNoYXJDb2RlQXQoMCk9PTA/cTpxfXJldHVybiBx
-fSwKdzpmdW5jdGlvbihhKXt2YXIgdCxzLHIscT10aGlzLHA9cS55CmlmKHA9PW51bGwpe3A9cS5hCnQ9
-cC5sZW5ndGghPT0wP3ArIjoiOiIiCnM9cS5jCnI9cz09bnVsbAppZighcnx8cD09PSJmaWxlIil7cD10
-KyIvLyIKdD1xLmIKaWYodC5sZW5ndGghPT0wKXA9cCt0KyJAIgppZighcilwKz1zCnQ9cS5kCmlmKHQh
-PW51bGwpcD1wKyI6IitILmQodCl9ZWxzZSBwPXQKcCs9cS5lCnQ9cS5mCmlmKHQhPW51bGwpcD1wKyI/
-Iit0CnQ9cS5yCmlmKHQhPW51bGwpcD1wKyIjIit0CnA9cS55PXAuY2hhckNvZGVBdCgwKT09MD9wOnB9
-cmV0dXJuIHB9LApETjpmdW5jdGlvbihhLGIpe3ZhciB0LHMscj10aGlzCmlmKGI9PW51bGwpcmV0dXJu
-ITEKaWYocj09PWIpcmV0dXJuITAKaWYodS5ELmMoYikpaWYoci5hPT1iLmdGaSgpKWlmKHIuYyE9bnVs
-bD09PWIuZ2NqKCkpaWYoci5iPT1iLmdrdSgpKWlmKHIuZ0pmKHIpPT1iLmdKZihiKSlpZihyLmd0cChy
-KT09Yi5ndHAoYikpaWYoci5lPT09Yi5nSWkoYikpe3Q9ci5mCnM9dD09bnVsbAppZighcz09PWIuZ1FE
-KCkpe2lmKHMpdD0iIgppZih0PT09Yi5ndFAoYikpe3Q9ci5yCnM9dD09bnVsbAppZighcz09PWIuZ1o4
-KCkpe2lmKHMpdD0iIgp0PXQ9PT1iLmdLYSgpfWVsc2UgdD0hMX1lbHNlIHQ9ITF9ZWxzZSB0PSExfWVs
-c2UgdD0hMQplbHNlIHQ9ITEKZWxzZSB0PSExCmVsc2UgdD0hMQplbHNlIHQ9ITEKZWxzZSB0PSExCmVs
-c2UgdD0hMQpyZXR1cm4gdH0sCmdpOmZ1bmN0aW9uKGEpe3ZhciB0PXRoaXMuegpyZXR1cm4gdD09bnVs
-bD90aGlzLno9Qy54Qi5naSh0aGlzLncoMCkpOnR9LApzbzY6ZnVuY3Rpb24oYSl7dGhpcy54PXUuYS5i
-KGEpfSwKc1JIOmZ1bmN0aW9uKGEpe3RoaXMuUT11LmYuYihhKX0sCiRpaUQ6MSwKZ0ZpOmZ1bmN0aW9u
-KCl7cmV0dXJuIHRoaXMuYX0sCmdJaTpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5lfX0KUC5lMS5wcm90
-b3R5cGU9ewokMTpmdW5jdGlvbihhKXt0aHJvdyBILmIoUC5ycigiSW52YWxpZCBwb3J0Iix0aGlzLmEs
-dGhpcy5iKzEpKX0sCiRTOjE1fQpQLk5ZLnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe3ZhciB0PSJJ
-bGxlZ2FsIHBhdGggY2hhcmFjdGVyICIKSC55KGEpCmlmKEouemwoYSwiLyIpKWlmKHRoaXMuYSl0aHJv
-dyBILmIoUC54WSh0K2EpKQplbHNlIHRocm93IEguYihQLkw0KHQrYSkpfSwKJFM6MTV9ClAuUloucHJv
-dG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7cmV0dXJuIFAuZVAoQy5aSixhLEMueE0sITEpfSwKJFM6NX0K
-UC5NRS5wcm90b3R5cGU9ewokMjpmdW5jdGlvbihhLGIpe3ZhciB0PXRoaXMuYixzPXRoaXMuYQp0LmEr
-PXMuYQpzLmE9IiYiCnM9dC5hKz1ILmQoUC5lUChDLkYzLGEsQy54TSwhMCkpCmlmKGIhPW51bGwmJmIu
-bGVuZ3RoIT09MCl7dC5hPXMrIj0iCnQuYSs9SC5kKFAuZVAoQy5GMyxiLEMueE0sITApKX19LAokUzox
-Nn0KUC55NS5wcm90b3R5cGU9ewokMjpmdW5jdGlvbihhLGIpe3ZhciB0LHMKSC55KGEpCmlmKGI9PW51
-bGx8fHR5cGVvZiBiPT0ic3RyaW5nIil0aGlzLmEuJDIoYSxILnkoYikpCmVsc2UgZm9yKHQ9Si5JVCh1
-LlIuYihiKSkscz10aGlzLmE7dC5tKCk7KXMuJDIoYSxILnkodC5nUih0KSkpfSwKJFM6MTN9ClAuUEUu
-cHJvdG90eXBlPXsKZ2xSOmZ1bmN0aW9uKCl7dmFyIHQscyxyLHEscD10aGlzLG89bnVsbCxuPXAuYwpp
-ZihuIT1udWxsKXJldHVybiBuCm49cC5iCmlmKDA+PW4ubGVuZ3RoKXJldHVybiBILk9IKG4sMCkKdD1w
-LmEKbj1uWzBdKzEKcz1DLnhCLlhVKHQsIj8iLG4pCnI9dC5sZW5ndGgKaWYocz49MCl7cT1QLnVPKHQs
-cysxLHIsQy5WQywhMSkKcj1zfWVsc2UgcT1vCnJldHVybiBwLmM9bmV3IFAucWUoImRhdGEiLG8sbyxv
-LFAudU8odCxuLHIsQy5XZCwhMSkscSxvKX0sCnc6ZnVuY3Rpb24oYSl7dmFyIHQscz10aGlzLmIKaWYo
-MD49cy5sZW5ndGgpcmV0dXJuIEguT0gocywwKQp0PXRoaXMuYQpyZXR1cm4gc1swXT09PS0xPyJkYXRh
-OiIrdDp0fX0KUC5xMy5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXtyZXR1cm4gbmV3IFVpbnQ4QXJy
-YXkoOTYpfSwKJFM6MjJ9ClAueUkucHJvdG90eXBlPXsKJDI6ZnVuY3Rpb24oYSxiKXt2YXIgdD10aGlz
-LmEKaWYoYT49dC5sZW5ndGgpcmV0dXJuIEguT0godCxhKQp0PXRbYV0KSi5DTSh0LDAsOTYsYikKcmV0
-dXJuIHR9LAokUzo0OX0KUC5jNi5wcm90b3R5cGU9ewokMzpmdW5jdGlvbihhLGIsYyl7dmFyIHQscyxy
-LHEKZm9yKHQ9Yi5sZW5ndGgscz1hLmxlbmd0aCxyPTA7cjx0Oysrcil7cT1DLnhCLldkKGIscileOTYK
-aWYocT49cylyZXR1cm4gSC5PSChhLHEpCmFbcV09Y319fQpQLnFkLnByb3RvdHlwZT17CiQzOmZ1bmN0
-aW9uKGEsYixjKXt2YXIgdCxzLHIscQpmb3IodD1DLnhCLldkKGIsMCkscz1DLnhCLldkKGIsMSkscj1h
-Lmxlbmd0aDt0PD1zOysrdCl7cT0odF45Nik+Pj4wCmlmKHE+PXIpcmV0dXJuIEguT0goYSxxKQphW3Fd
-PWN9fX0KUC5VZi5wcm90b3R5cGU9ewpnY2o6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5jPjB9LApneEE6
-ZnVuY3Rpb24oKXt2YXIgdCxzCmlmKHRoaXMuYz4wKXt0PXRoaXMuZAppZih0eXBlb2YgdCE9PSJudW1i
-ZXIiKXJldHVybiB0LlQoKQpzPXRoaXMuZQppZih0eXBlb2YgcyE9PSJudW1iZXIiKXJldHVybiBILnBZ
-KHMpCnM9dCsxPHMKdD1zfWVsc2UgdD0hMQpyZXR1cm4gdH0sCmdRRDpmdW5jdGlvbigpe3ZhciB0PXRo
-aXMuZgppZih0eXBlb2YgdCE9PSJudW1iZXIiKXJldHVybiB0LkooKQpyZXR1cm4gdDx0aGlzLnJ9LApn
-Wjg6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5yPHRoaXMuYS5sZW5ndGh9LApnTnc6ZnVuY3Rpb24oKXty
-ZXR1cm4gdGhpcy5iPT09NCYmQy54Qi5uQyh0aGlzLmEsImZpbGUiKX0sCmdXWjpmdW5jdGlvbigpe3Jl
-dHVybiB0aGlzLmI9PT00JiZDLnhCLm5DKHRoaXMuYSwiaHR0cCIpfSwKZ1JlOmZ1bmN0aW9uKCl7cmV0
-dXJuIHRoaXMuYj09PTUmJkMueEIubkModGhpcy5hLCJodHRwcyIpfSwKZ3RUOmZ1bmN0aW9uKCl7cmV0
-dXJuIEMueEIuUWkodGhpcy5hLCIvIix0aGlzLmUpfSwKZ0ZpOmZ1bmN0aW9uKCl7dmFyIHQscz10aGlz
-LHI9InBhY2thZ2UiLHE9cy5iCmlmKHE8PTApcmV0dXJuIiIKdD1zLngKaWYodCE9bnVsbClyZXR1cm4g
-dAppZihzLmdXWigpKXE9cy54PSJodHRwIgplbHNlIGlmKHMuZ1JlKCkpe3MueD0iaHR0cHMiCnE9Imh0
-dHBzIn1lbHNlIGlmKHMuZ053KCkpe3MueD0iZmlsZSIKcT0iZmlsZSJ9ZWxzZSBpZihxPT09NyYmQy54
-Qi5uQyhzLmEscikpe3MueD1yCnE9cn1lbHNle3E9Qy54Qi5OaihzLmEsMCxxKQpzLng9cX1yZXR1cm4g
-cX0sCmdrdTpmdW5jdGlvbigpe3ZhciB0PXRoaXMuYyxzPXRoaXMuYiszCnJldHVybiB0PnM/Qy54Qi5O
-aih0aGlzLmEscyx0LTEpOiIifSwKZ0pmOmZ1bmN0aW9uKGEpe3ZhciB0PXRoaXMuYwpyZXR1cm4gdD4w
-P0MueEIuTmoodGhpcy5hLHQsdGhpcy5kKToiIn0sCmd0cDpmdW5jdGlvbihhKXt2YXIgdCxzPXRoaXMK
-aWYocy5neEEoKSl7dD1zLmQKaWYodHlwZW9mIHQhPT0ibnVtYmVyIilyZXR1cm4gdC5UKCkKcmV0dXJu
-IFAuUUEoQy54Qi5OaihzLmEsdCsxLHMuZSksbnVsbCxudWxsKX1pZihzLmdXWigpKXJldHVybiA4MApp
-ZihzLmdSZSgpKXJldHVybiA0NDMKcmV0dXJuIDB9LApnSWk6ZnVuY3Rpb24oYSl7cmV0dXJuIEMueEIu
-TmoodGhpcy5hLHRoaXMuZSx0aGlzLmYpfSwKZ3RQOmZ1bmN0aW9uKGEpe3ZhciB0PXRoaXMuZixzPXRo
-aXMucgppZih0eXBlb2YgdCE9PSJudW1iZXIiKXJldHVybiB0LkooKQpyZXR1cm4gdDxzP0MueEIuTmoo
-dGhpcy5hLHQrMSxzKToiIn0sCmdLYTpmdW5jdGlvbigpe3ZhciB0PXRoaXMucixzPXRoaXMuYQpyZXR1
-cm4gdDxzLmxlbmd0aD9DLnhCLnluKHMsdCsxKToiIn0sCmdGajpmdW5jdGlvbigpe3ZhciB0LHMscj10
-aGlzLmUscT10aGlzLmYscD10aGlzLmEKaWYoQy54Qi5RaShwLCIvIixyKSl7aWYodHlwZW9mIHIhPT0i
-bnVtYmVyIilyZXR1cm4gci5UKCk7KytyfWlmKHI9PXEpcmV0dXJuIEMueEQKdD1ILlZNKFtdLHUucykK
-cz1yCndoaWxlKCEwKXtpZih0eXBlb2YgcyE9PSJudW1iZXIiKXJldHVybiBzLkooKQppZih0eXBlb2Yg
-cSE9PSJudW1iZXIiKXJldHVybiBILnBZKHEpCmlmKCEoczxxKSlicmVhawppZihDLnhCLk8yKHAscyk9
-PT00Nyl7Qy5ObS5BKHQsQy54Qi5OaihwLHIscykpCnI9cysxfSsrc31DLk5tLkEodCxDLnhCLk5qKHAs
-cixxKSkKcmV0dXJuIFAuQUYodCx1Lk4pfSwKZ2hZOmZ1bmN0aW9uKCl7dmFyIHQ9dGhpcyxzPXQuZgpp
-Zih0eXBlb2YgcyE9PSJudW1iZXIiKXJldHVybiBzLkooKQppZihzPj10LnIpcmV0dXJuIEMuV08KcmV0
-dXJuIG5ldyBQLkdqKFAuV1godC5ndFAodCkpLHUuVyl9LAprWDpmdW5jdGlvbihhKXt2YXIgdCxzPXRo
-aXMuZAppZih0eXBlb2YgcyE9PSJudW1iZXIiKXJldHVybiBzLlQoKQp0PXMrMQpyZXR1cm4gdCthLmxl
-bmd0aD09PXRoaXMuZSYmQy54Qi5RaSh0aGlzLmEsYSx0KX0sCk45OmZ1bmN0aW9uKCl7dmFyIHQ9dGhp
-cyxzPXQucixyPXQuYQppZihzPj1yLmxlbmd0aClyZXR1cm4gdApyZXR1cm4gbmV3IFAuVWYoQy54Qi5O
-aihyLDAscyksdC5iLHQuYyx0LmQsdC5lLHQuZixzLHQueCl9LApubTpmdW5jdGlvbihhLGIpe3ZhciB0
-LHMscixxLHAsbyxuLG0sbCxrLGo9dGhpcyxpPW51bGwKdS5YLmIobnVsbCkKdS5iLmIoYikKdD1qLmdG
-aSgpCnM9dD09PSJmaWxlIgpyPWouYwpxPXI+MD9DLnhCLk5qKGouYSxqLmIrMyxyKToiIgpwPWouZ3hB
-KCk/ai5ndHAoaik6aQpyPWouYwppZihyPjApbz1DLnhCLk5qKGouYSxyLGouZCkKZWxzZSBvPXEubGVu
-Z3RoIT09MHx8cCE9bnVsbHx8cz8iIjppCnI9ai5hCm49Qy54Qi5OaihyLGouZSxqLmYpCmlmKCFzKW09
-byE9bnVsbCYmbi5sZW5ndGghPT0wCmVsc2UgbT0hMAppZihtJiYhQy54Qi5uQyhuLCIvIikpbj0iLyIr
-bgpsPVAubGUoaSwwLDAsYikKbT1qLnIKaz1tPHIubGVuZ3RoP0MueEIueW4ocixtKzEpOmkKcmV0dXJu
-IG5ldyBQLkRuKHQscSxvLHAsbixsLGspfSwKWkk6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMubVMoUC5o
-SyhhKSl9LAptUzpmdW5jdGlvbihhKXtpZihhIGluc3RhbmNlb2YgUC5VZilyZXR1cm4gdGhpcy51MSh0
-aGlzLGEpCnJldHVybiB0aGlzLnZzKCkubVMoYSl9LAp1MTpmdW5jdGlvbihhLGIpe3ZhciB0LHMscixx
-LHAsbyxuLG0sbCxrLGosaSxoLGcsZixlPWIuYgppZihlPjApcmV0dXJuIGIKdD1iLmMKaWYodD4wKXtz
-PWEuYgppZihzPD0wKXJldHVybiBiCmlmKGEuZ053KCkpcj1iLmUhPWIuZgplbHNlIGlmKGEuZ1daKCkp
-cj0hYi5rWCgiODAiKQplbHNlIHI9IWEuZ1JlKCl8fCFiLmtYKCI0NDMiKQppZihyKXtxPXMrMQpwPUMu
-eEIuTmooYS5hLDAscSkrQy54Qi55bihiLmEsZSsxKQplPWIuZAppZih0eXBlb2YgZSE9PSJudW1iZXIi
-KXJldHVybiBlLlQoKQpvPWIuZQppZih0eXBlb2YgbyE9PSJudW1iZXIiKXJldHVybiBvLlQoKQpuPWIu
-ZgppZih0eXBlb2YgbiE9PSJudW1iZXIiKXJldHVybiBuLlQoKQpyZXR1cm4gbmV3IFAuVWYocCxzLHQr
-cSxlK3EsbytxLG4rcSxiLnIrcSxhLngpfWVsc2UgcmV0dXJuIHRoaXMudnMoKS5tUyhiKX1tPWIuZQpl
-PWIuZgppZihtPT1lKXt0PWIucgppZih0eXBlb2YgZSE9PSJudW1iZXIiKXJldHVybiBlLkooKQppZihl
-PHQpe3M9YS5mCmlmKHR5cGVvZiBzIT09Im51bWJlciIpcmV0dXJuIHMuSE4oKQpxPXMtZQpyZXR1cm4g
-bmV3IFAuVWYoQy54Qi5OaihhLmEsMCxzKStDLnhCLnluKGIuYSxlKSxhLmIsYS5jLGEuZCxhLmUsZStx
-LHQrcSxhLngpfWU9Yi5hCmlmKHQ8ZS5sZW5ndGgpe3M9YS5yCnJldHVybiBuZXcgUC5VZihDLnhCLk5q
-KGEuYSwwLHMpK0MueEIueW4oZSx0KSxhLmIsYS5jLGEuZCxhLmUsYS5mLHQrKHMtdCksYS54KX1yZXR1
-cm4gYS5OOSgpfXQ9Yi5hCmlmKEMueEIuUWkodCwiLyIsbSkpe3M9YS5lCmlmKHR5cGVvZiBzIT09Im51
-bWJlciIpcmV0dXJuIHMuSE4oKQppZih0eXBlb2YgbSE9PSJudW1iZXIiKXJldHVybiBILnBZKG0pCnE9
-cy1tCnA9Qy54Qi5OaihhLmEsMCxzKStDLnhCLnluKHQsbSkKaWYodHlwZW9mIGUhPT0ibnVtYmVyIily
-ZXR1cm4gZS5UKCkKcmV0dXJuIG5ldyBQLlVmKHAsYS5iLGEuYyxhLmQscyxlK3EsYi5yK3EsYS54KX1s
-PWEuZQprPWEuZgppZihsPT1rJiZhLmM+MCl7Zm9yKDtDLnhCLlFpKHQsIi4uLyIsbSk7KXtpZih0eXBl
-b2YgbSE9PSJudW1iZXIiKXJldHVybiBtLlQoKQptKz0zfWlmKHR5cGVvZiBsIT09Im51bWJlciIpcmV0
-dXJuIGwuSE4oKQppZih0eXBlb2YgbSE9PSJudW1iZXIiKXJldHVybiBILnBZKG0pCnE9bC1tKzEKcD1D
-LnhCLk5qKGEuYSwwLGwpKyIvIitDLnhCLnluKHQsbSkKaWYodHlwZW9mIGUhPT0ibnVtYmVyIilyZXR1
-cm4gZS5UKCkKcmV0dXJuIG5ldyBQLlVmKHAsYS5iLGEuYyxhLmQsbCxlK3EsYi5yK3EsYS54KX1qPWEu
-YQpmb3IoaT1sO0MueEIuUWkoaiwiLi4vIixpKTspe2lmKHR5cGVvZiBpIT09Im51bWJlciIpcmV0dXJu
-IGkuVCgpCmkrPTN9aD0wCndoaWxlKCEwKXtpZih0eXBlb2YgbSE9PSJudW1iZXIiKXJldHVybiBtLlQo
-KQpnPW0rMwppZih0eXBlb2YgZSE9PSJudW1iZXIiKXJldHVybiBILnBZKGUpCmlmKCEoZzw9ZSYmQy54
-Qi5RaSh0LCIuLi8iLG0pKSlicmVhazsrK2gKbT1nfWY9IiIKd2hpbGUoITApe2lmKHR5cGVvZiBrIT09
-Im51bWJlciIpcmV0dXJuIGsub3MoKQppZih0eXBlb2YgaSE9PSJudW1iZXIiKXJldHVybiBILnBZKGkp
-CmlmKCEoaz5pKSlicmVhazstLWsKaWYoQy54Qi5PMihqLGspPT09NDcpe2lmKGg9PT0wKXtmPSIvIgpi
-cmVha30tLWgKZj0iLyJ9fWlmKGs9PT1pJiZhLmI8PTAmJiFDLnhCLlFpKGosIi8iLGwpKXttLT1oKjMK
-Zj0iIn1xPWstbStmLmxlbmd0aApyZXR1cm4gbmV3IFAuVWYoQy54Qi5OaihqLDAsaykrZitDLnhCLnlu
-KHQsbSksYS5iLGEuYyxhLmQsbCxlK3EsYi5yK3EsYS54KX0sCnQ0OmZ1bmN0aW9uKCl7dmFyIHQscyxy
-LHEscD10aGlzCmlmKHAuYj49MCYmIXAuZ053KCkpdGhyb3cgSC5iKFAuTDQoIkNhbm5vdCBleHRyYWN0
-IGEgZmlsZSBwYXRoIGZyb20gYSAiK0guZChwLmdGaSgpKSsiIFVSSSIpKQp0PXAuZgpzPXAuYQppZih0
-eXBlb2YgdCE9PSJudW1iZXIiKXJldHVybiB0LkooKQppZih0PHMubGVuZ3RoKXtpZih0PHAucil0aHJv
-dyBILmIoUC5MNCgiQ2Fubm90IGV4dHJhY3QgYSBmaWxlIHBhdGggZnJvbSBhIFVSSSB3aXRoIGEgcXVl
-cnkgY29tcG9uZW50IikpCnRocm93IEguYihQLkw0KCJDYW5ub3QgZXh0cmFjdCBhIGZpbGUgcGF0aCBm
-cm9tIGEgVVJJIHdpdGggYSBmcmFnbWVudCBjb21wb25lbnQiKSl9cj0kLk94KCkKaWYoSC5vVChyKSl0
-PVAubW4ocCkKZWxzZXtxPXAuZAppZih0eXBlb2YgcSE9PSJudW1iZXIiKXJldHVybiBILnBZKHEpCmlm
-KHAuYzxxKUguVmooUC5MNCgiQ2Fubm90IGV4dHJhY3QgYSBub24tV2luZG93cyBmaWxlIHBhdGggZnJv
-bSBhIGZpbGUgVVJJIHdpdGggYW4gYXV0aG9yaXR5IikpCnQ9Qy54Qi5OaihzLHAuZSx0KX1yZXR1cm4g
-dH0sCmdpOmZ1bmN0aW9uKGEpe3ZhciB0PXRoaXMueQpyZXR1cm4gdD09bnVsbD90aGlzLnk9Qy54Qi5n
-aSh0aGlzLmEpOnR9LApETjpmdW5jdGlvbihhLGIpe2lmKGI9PW51bGwpcmV0dXJuITEKaWYodGhpcz09
-PWIpcmV0dXJuITAKcmV0dXJuIHUuRC5jKGIpJiZ0aGlzLmE9PT1iLncoMCl9LAp2czpmdW5jdGlvbigp
-e3ZhciB0PXRoaXMscz1udWxsLHI9dC5nRmkoKSxxPXQuZ2t1KCkscD10LmM+MD90LmdKZih0KTpzLG89
-dC5neEEoKT90Lmd0cCh0KTpzLG49dC5hLG09dC5mLGw9Qy54Qi5OaihuLHQuZSxtKSxrPXQucgppZih0
-eXBlb2YgbSE9PSJudW1iZXIiKXJldHVybiBtLkooKQptPW08az90Lmd0UCh0KTpzCnJldHVybiBuZXcg
-UC5EbihyLHEscCxvLGwsbSxrPG4ubGVuZ3RoP3QuZ0thKCk6cyl9LAp3OmZ1bmN0aW9uKGEpe3JldHVy
-biB0aGlzLmF9LAokaWlEOjF9ClAucWUucHJvdG90eXBlPXt9ClcucUUucHJvdG90eXBlPXt9ClcuWWUu
-cHJvdG90eXBlPXsKZ2g6ZnVuY3Rpb24oYSl7cmV0dXJuIGEubGVuZ3RofX0KVy5HaC5wcm90b3R5cGU9
-ewp3OmZ1bmN0aW9uKGEpe3JldHVybiBTdHJpbmcoYSl9LAokaUdoOjF9ClcuZlkucHJvdG90eXBlPXsK
-dzpmdW5jdGlvbihhKXtyZXR1cm4gU3RyaW5nKGEpfX0KVy5uQi5wcm90b3R5cGU9eyRpbkI6MX0KVy5B
-ei5wcm90b3R5cGU9eyRpQXo6MX0KVy5QVS5wcm90b3R5cGU9ewpnbnc6ZnVuY3Rpb24oYSl7cmV0dXJu
-IGEudmFsdWV9fQpXLlFQLnByb3RvdHlwZT17JGlRUDoxfQpXLklGLnByb3RvdHlwZT17CmdudzpmdW5j
-dGlvbihhKXtyZXR1cm4gYS52YWx1ZX19ClcubngucHJvdG90eXBlPXsKZ2g6ZnVuY3Rpb24oYSl7cmV0
-dXJuIGEubGVuZ3RofX0KVy5SZC5wcm90b3R5cGU9ewpnbnc6ZnVuY3Rpb24oYSl7cmV0dXJuIGEudmFs
-dWV9fQpXLmtSLnByb3RvdHlwZT17JGlrUjoxfQpXLlRmLnByb3RvdHlwZT17CmdoOmZ1bmN0aW9uKGEp
-e3JldHVybiBhLmxlbmd0aH19ClcubHcucHJvdG90eXBlPXskaWx3OjF9Clcub0oucHJvdG90eXBlPXsK
-Z2g6ZnVuY3Rpb24oYSl7cmV0dXJuIGEubGVuZ3RofX0KVy5pZC5wcm90b3R5cGU9e30KVy5Cdy5wcm90
-b3R5cGU9e30KVy5vNC5wcm90b3R5cGU9e30KVy5IUy5wcm90b3R5cGU9ewpnaDpmdW5jdGlvbihhKXty
-ZXR1cm4gYS5sZW5ndGh9fQpXLlZvLnByb3RvdHlwZT17CmdudzpmdW5jdGlvbihhKXtyZXR1cm4gYS52
-YWx1ZX19ClcuRmgucHJvdG90eXBlPXsKZ2g6ZnVuY3Rpb24oYSl7cmV0dXJuIGEubGVuZ3RofX0KVy5j
-eC5wcm90b3R5cGU9ewpnbnc6ZnVuY3Rpb24oYSl7cmV0dXJuIGEudmFsdWV9fQpXLlNiLnByb3RvdHlw
-ZT17CnE6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gYVtILlNjKGIpXX0sCmdoOmZ1bmN0aW9uKGEpe3JldHVy
-biBhLmxlbmd0aH19ClcuUUYucHJvdG90eXBlPXt9ClcuTmgucHJvdG90eXBlPXsKdzpmdW5jdGlvbihh
-KXtyZXR1cm4gU3RyaW5nKGEpfX0KVy5Gdi5wcm90b3R5cGU9ewpnaDpmdW5jdGlvbihhKXtyZXR1cm4g
-YS5sZW5ndGh9LApxOmZ1bmN0aW9uKGEsYil7SC5TYyhiKQppZihiPj4+MCE9PWJ8fGI+PWEubGVuZ3Ro
-KXRocm93IEguYihQLkNmKGIsYSxudWxsLG51bGwsbnVsbCkpCnJldHVybiBhW2JdfSwKWTpmdW5jdGlv
-bihhLGIsYyl7SC5TYyhiKQp1LnEuYihjKQp0aHJvdyBILmIoUC5MNCgiQ2Fubm90IGFzc2lnbiBlbGVt
-ZW50IG9mIGltbXV0YWJsZSBMaXN0LiIpKX0sClc6ZnVuY3Rpb24oYSxiKXtpZihiPDB8fGI+PWEubGVu
-Z3RoKXJldHVybiBILk9IKGEsYikKcmV0dXJuIGFbYl19LAokaWJROjEsCiRpWGo6MSwKJGljWDoxLAok
-aXpNOjF9ClcuSUIucHJvdG90eXBlPXsKdzpmdW5jdGlvbihhKXtyZXR1cm4iUmVjdGFuZ2xlICgiK0gu
-ZChhLmxlZnQpKyIsICIrSC5kKGEudG9wKSsiKSAiK0guZCh0aGlzLmdQKGEpKSsiIHggIitILmQodGhp
-cy5nTChhKSl9LApETjpmdW5jdGlvbihhLGIpe3ZhciB0CmlmKGI9PW51bGwpcmV0dXJuITEKaWYodS5x
-LmMoYikpaWYoYS5sZWZ0PT09Yi5sZWZ0KWlmKGEudG9wPT09Yi50b3Ape3Q9Si5SRShiKQp0PXRoaXMu
-Z1AoYSk9PT10LmdQKGIpJiZ0aGlzLmdMKGEpPT09dC5nTChiKX1lbHNlIHQ9ITEKZWxzZSB0PSExCmVs
-c2UgdD0hMQpyZXR1cm4gdH0sCmdpOmZ1bmN0aW9uKGEpe3JldHVybiBXLnJFKEMuQ0QuZ2koYS5sZWZ0
-KSxDLkNELmdpKGEudG9wKSxDLkNELmdpKHRoaXMuZ1AoYSkpLEMuQ0QuZ2kodGhpcy5nTChhKSkpfSwK
-Z0w6ZnVuY3Rpb24oYSl7cmV0dXJuIGEuaGVpZ2h0fSwKZ1A6ZnVuY3Rpb24oYSl7cmV0dXJuIGEud2lk
-dGh9LAokaXRuOjF9ClcuWWwucHJvdG90eXBlPXsKZ2g6ZnVuY3Rpb24oYSl7cmV0dXJuIGEubGVuZ3Ro
-fSwKcTpmdW5jdGlvbihhLGIpe0guU2MoYikKaWYoYj4+PjAhPT1ifHxiPj1hLmxlbmd0aCl0aHJvdyBI
-LmIoUC5DZihiLGEsbnVsbCxudWxsLG51bGwpKQpyZXR1cm4gYVtiXX0sClk6ZnVuY3Rpb24oYSxiLGMp
-e0guU2MoYikKSC55KGMpCnRocm93IEguYihQLkw0KCJDYW5ub3QgYXNzaWduIGVsZW1lbnQgb2YgaW1t
-dXRhYmxlIExpc3QuIikpfSwKVzpmdW5jdGlvbihhLGIpe2lmKGI8MHx8Yj49YS5sZW5ndGgpcmV0dXJu
-IEguT0goYSxiKQpyZXR1cm4gYVtiXX0sCiRpYlE6MSwKJGlYajoxLAokaWNYOjEsCiRpek06MX0KVy5u
-Ny5wcm90b3R5cGU9ewpnaDpmdW5jdGlvbihhKXtyZXR1cm4gYS5sZW5ndGh9LApnbnc6ZnVuY3Rpb24o
-YSl7cmV0dXJuIGEudmFsdWV9fQpXLnd6LnByb3RvdHlwZT17CmdoOmZ1bmN0aW9uKGEpe3JldHVybiB0
-aGlzLmEubGVuZ3RofSwKcTpmdW5jdGlvbihhLGIpe3ZhciB0CkguU2MoYikKdD10aGlzLmEKaWYoYjww
-fHxiPj10Lmxlbmd0aClyZXR1cm4gSC5PSCh0LGIpCnJldHVybiB0aGlzLiR0aS5kLmIodFtiXSl9LApZ
-OmZ1bmN0aW9uKGEsYixjKXtILlNjKGIpCnRoaXMuJHRpLmQuYihjKQp0aHJvdyBILmIoUC5MNCgiQ2Fu
-bm90IG1vZGlmeSBsaXN0IikpfX0KVy5jdi5wcm90b3R5cGU9ewpnUWc6ZnVuY3Rpb24oYSl7cmV0dXJu
-IG5ldyBXLmk3KGEpfSwKZ0REOmZ1bmN0aW9uKGEpe3JldHVybiBuZXcgVy5JNChhKX0sCnNERDpmdW5j
-dGlvbihhLGIpe3ZhciB0CnUuWC5iKGIpCnQ9dGhpcy5nREQoYSkKdC5WMSgwKQp0LkZWKDAsYil9LAp3
-OmZ1bmN0aW9uKGEpe3JldHVybiBhLmxvY2FsTmFtZX0sCnRuOmZ1bmN0aW9uKGEpe3ZhciB0PSEhYS5z
-Y3JvbGxJbnRvVmlld0lmTmVlZGVkCmlmKHQpYS5zY3JvbGxJbnRvVmlld0lmTmVlZGVkKCkKZWxzZSBh
-LnNjcm9sbEludG9WaWV3KCl9LApuejpmdW5jdGlvbihhLGIsYyxkLGUpe3ZhciB0LHM9dGhpcy5yNihh
-LGMsZCxlKQpzd2l0Y2goYi50b0xvd2VyQ2FzZSgpKXtjYXNlImJlZm9yZWJlZ2luIjphLnBhcmVudE5v
-ZGUuaW5zZXJ0QmVmb3JlKHMsYSkKYnJlYWsKY2FzZSJhZnRlcmJlZ2luIjp0PWEuY2hpbGROb2Rlcwph
-Lmluc2VydEJlZm9yZShzLHQubGVuZ3RoPjA/dFswXTpudWxsKQpicmVhawpjYXNlImJlZm9yZWVuZCI6
-YS5hcHBlbmRDaGlsZChzKQpicmVhawpjYXNlImFmdGVyZW5kIjphLnBhcmVudE5vZGUuaW5zZXJ0QmVm
-b3JlKHMsYS5uZXh0U2libGluZykKYnJlYWsKZGVmYXVsdDpILlZqKFAueFkoIkludmFsaWQgcG9zaXRp
-b24gIitiKSl9fSwKcjY6ZnVuY3Rpb24oYSxiLGMsZCl7dmFyIHQscyxyLHEKaWYoYz09bnVsbCl7aWYo
-ZD09bnVsbCl7dD0kLmx0CmlmKHQ9PW51bGwpe3Q9SC5WTShbXSx1Lm0pCnM9bmV3IFcudkQodCkKQy5O
-bS5BKHQsVy5UdyhudWxsKSkKQy5ObS5BKHQsVy5CbCgpKQokLmx0PXMKZD1zfWVsc2UgZD10fXQ9JC5F
-VQppZih0PT1udWxsKXt0PW5ldyBXLktvKGQpCiQuRVU9dApjPXR9ZWxzZXt0LmE9ZApjPXR9fWVsc2Ug
-aWYoZCE9bnVsbCl0aHJvdyBILmIoUC54WSgidmFsaWRhdG9yIGNhbiBvbmx5IGJlIHBhc3NlZCBpZiB0
-cmVlU2FuaXRpemVyIGlzIG51bGwiKSkKaWYoJC54bz09bnVsbCl7dD1kb2N1bWVudApzPXQuaW1wbGVt
-ZW50YXRpb24uY3JlYXRlSFRNTERvY3VtZW50KCIiKQokLnhvPXMKJC5CTz1zLmNyZWF0ZVJhbmdlKCkK
-cz0kLnhvLmNyZWF0ZUVsZW1lbnQoImJhc2UiKQp1LmNSLmIocykKcy5ocmVmPXQuYmFzZVVSSQokLnhv
-LmhlYWQuYXBwZW5kQ2hpbGQocyl9dD0kLnhvCmlmKHQuYm9keT09bnVsbCl7cz10LmNyZWF0ZUVsZW1l
-bnQoImJvZHkiKQp0LmJvZHk9dS5rLmIocyl9dD0kLnhvCmlmKHUuay5jKGEpKXI9dC5ib2R5CmVsc2V7
-cj10LmNyZWF0ZUVsZW1lbnQoYS50YWdOYW1lKQokLnhvLmJvZHkuYXBwZW5kQ2hpbGQocil9aWYoImNy
-ZWF0ZUNvbnRleHR1YWxGcmFnbWVudCIgaW4gd2luZG93LlJhbmdlLnByb3RvdHlwZSYmIUMuTm0udGco
-Qy5TcSxhLnRhZ05hbWUpKXskLkJPLnNlbGVjdE5vZGVDb250ZW50cyhyKQpxPSQuQk8uY3JlYXRlQ29u
-dGV4dHVhbEZyYWdtZW50KGIpfWVsc2V7ci5pbm5lckhUTUw9YgpxPSQueG8uY3JlYXRlRG9jdW1lbnRG
-cmFnbWVudCgpCmZvcig7dD1yLmZpcnN0Q2hpbGQsdCE9bnVsbDspcS5hcHBlbmRDaGlsZCh0KX10PSQu
-eG8uYm9keQppZihyPT1udWxsP3QhPW51bGw6ciE9PXQpSi5MdChyKQpjLlBuKHEpCmRvY3VtZW50LmFk
-b3B0Tm9kZShxKQpyZXR1cm4gcX0sCkFIOmZ1bmN0aW9uKGEsYixjKXtyZXR1cm4gdGhpcy5yNihhLGIs
-YyxudWxsKX0sCnNoZjpmdW5jdGlvbihhLGIpe3RoaXMuWUMoYSxiKX0sCnBrOmZ1bmN0aW9uKGEsYixj
-KXthLnRleHRDb250ZW50PW51bGwKYS5hcHBlbmRDaGlsZCh0aGlzLnI2KGEsYixudWxsLGMpKX0sCllD
-OmZ1bmN0aW9uKGEsYil7cmV0dXJuIHRoaXMucGsoYSxiLG51bGwpfSwKZ1ZsOmZ1bmN0aW9uKGEpe3Jl
-dHVybiBuZXcgVy5ldShhLCJjbGljayIsITEsdS5RKX0sCiRpY3Y6MSwKZ25zOmZ1bmN0aW9uKGEpe3Jl
-dHVybiBhLnRhZ05hbWV9fQpXLkN2LnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe3JldHVybiB1Lmgu
-Yyh1LkEuYihhKSl9LAokUzoyNX0KVy5RSS5wcm90b3R5cGU9eyRpUUk6MX0KVy5lYS5wcm90b3R5cGU9
-eyRpZWE6MX0KVy5EMC5wcm90b3R5cGU9ewpPbjpmdW5jdGlvbihhLGIsYyxkKXt1LkYuYihjKQppZihj
-IT1udWxsKXRoaXMubihhLGIsYyxkKX0sCkI6ZnVuY3Rpb24oYSxiLGMpe3JldHVybiB0aGlzLk9uKGEs
-YixjLG51bGwpfSwKbjpmdW5jdGlvbihhLGIsYyxkKXtyZXR1cm4gYS5hZGRFdmVudExpc3RlbmVyKGIs
-SC50Uih1LkYuYihjKSwxKSxkKX0sCiRpRDA6MX0KVy5UNS5wcm90b3R5cGU9eyRpVDU6MX0KVy5YVi5w
-cm90b3R5cGU9ewpnaDpmdW5jdGlvbihhKXtyZXR1cm4gYS5sZW5ndGh9LApxOmZ1bmN0aW9uKGEsYil7
-SC5TYyhiKQppZihiPj4+MCE9PWJ8fGI+PWEubGVuZ3RoKXRocm93IEguYihQLkNmKGIsYSxudWxsLG51
-bGwsbnVsbCkpCnJldHVybiBhW2JdfSwKWTpmdW5jdGlvbihhLGIsYyl7SC5TYyhiKQp1Lk8uYihjKQp0
-aHJvdyBILmIoUC5MNCgiQ2Fubm90IGFzc2lnbiBlbGVtZW50IG9mIGltbXV0YWJsZSBMaXN0LiIpKX0s
-Clc6ZnVuY3Rpb24oYSxiKXtpZihiPDB8fGI+PWEubGVuZ3RoKXJldHVybiBILk9IKGEsYikKcmV0dXJu
-IGFbYl19LAokaWJROjEsCiRpWGo6MSwKJGljWDoxLAokaXpNOjEsCiRpWFY6MX0KVy53Si5wcm90b3R5
-cGU9ewpnaDpmdW5jdGlvbihhKXtyZXR1cm4gYS5sZW5ndGh9fQpXLmg0LnByb3RvdHlwZT17CmdoOmZ1
-bmN0aW9uKGEpe3JldHVybiBhLmxlbmd0aH19ClcuR08ucHJvdG90eXBlPXskaUdPOjF9ClcuSkMucHJv
-dG90eXBlPXsKZ253OmZ1bmN0aW9uKGEpe3JldHVybiBhLnZhbHVlfX0KVy5ici5wcm90b3R5cGU9ewpn
-aDpmdW5jdGlvbihhKXtyZXR1cm4gYS5sZW5ndGh9fQpXLnhuLnByb3RvdHlwZT17CmdoOmZ1bmN0aW9u
-KGEpe3JldHVybiBhLmxlbmd0aH0sCnE6ZnVuY3Rpb24oYSxiKXtILlNjKGIpCmlmKGI+Pj4wIT09Ynx8
-Yj49YS5sZW5ndGgpdGhyb3cgSC5iKFAuQ2YoYixhLG51bGwsbnVsbCxudWxsKSkKcmV0dXJuIGFbYl19
-LApZOmZ1bmN0aW9uKGEsYixjKXtILlNjKGIpCnUuQS5iKGMpCnRocm93IEguYihQLkw0KCJDYW5ub3Qg
-YXNzaWduIGVsZW1lbnQgb2YgaW1tdXRhYmxlIExpc3QuIikpfSwKVzpmdW5jdGlvbihhLGIpe2lmKGI8
-MHx8Yj49YS5sZW5ndGgpcmV0dXJuIEguT0goYSxiKQpyZXR1cm4gYVtiXX0sCiRpYlE6MSwKJGlYajox
-LAokaWNYOjEsCiRpek06MX0KVy5WYi5wcm90b3R5cGU9e30KVy5PNy5wcm90b3R5cGU9ewplbzpmdW5j
-dGlvbihhLGIsYyxkKXtyZXR1cm4gYS5vcGVuKGIsYywhMCl9LAokaU83OjF9ClcuYlUucHJvdG90eXBl
-PXsKJDI6ZnVuY3Rpb24oYSxiKXt0aGlzLmEuc2V0UmVxdWVzdEhlYWRlcihILnkoYSksSC55KGIpKX0s
-CiRTOjEyfQpXLmhILnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe3ZhciB0LHMscixxLHAKdS5wLmIo
-YSkKdD10aGlzLmEKcz10LnN0YXR1cwppZih0eXBlb2YgcyE9PSJudW1iZXIiKXJldHVybiBzLnRCKCkK
-cj1zPj0yMDAmJnM8MzAwCnE9cz4zMDcmJnM8NDAwCnM9cnx8cz09PTB8fHM9PT0zMDR8fHEKcD10aGlz
-LmIKaWYocylwLmFNKDAsdCkKZWxzZSBwLnBtKGEpfSwKJFM6Mjd9Clcud2EucHJvdG90eXBlPXt9Clcu
-U2cucHJvdG90eXBlPXskaVNnOjF9ClcuSksucHJvdG90eXBlPXsKZ253OmZ1bmN0aW9uKGEpe3JldHVy
-biBhLnZhbHVlfSwKZ1B1OmZ1bmN0aW9uKGEpe3JldHVybiBhLndlYmtpdEVudHJpZXN9fQpXLkhMLnBy
-b3RvdHlwZT17CmdHMzpmdW5jdGlvbihhKXtyZXR1cm4gYS5rZXl9fQpXLndQLnByb3RvdHlwZT17Cmdu
-dzpmdW5jdGlvbihhKXtyZXR1cm4gYS52YWx1ZX19ClcudTgucHJvdG90eXBlPXsKZ0RyOmZ1bmN0aW9u
-KGEpe2lmKCJvcmlnaW4iIGluIGEpcmV0dXJuIGEub3JpZ2luCnJldHVybiBILmQoYS5wcm90b2NvbCkr
-Ii8vIitILmQoYS5ob3N0KX0sCnc6ZnVuY3Rpb24oYSl7cmV0dXJuIFN0cmluZyhhKX0sCiRpdTg6MX0K
-Vy56Ni5wcm90b3R5cGU9ewpnaDpmdW5jdGlvbihhKXtyZXR1cm4gYS5sZW5ndGh9fQpXLmxLLnByb3Rv
-dHlwZT17JGlsSzoxfQpXLlFiLnByb3RvdHlwZT17CmdudzpmdW5jdGlvbihhKXtyZXR1cm4gYS52YWx1
-ZX19ClcuUzAucHJvdG90eXBlPXsKcTpmdW5jdGlvbihhLGIpe3JldHVybiBQLm1SKGEuZ2V0KEgueShi
-KSkpfSwKVTpmdW5jdGlvbihhLGIpe3ZhciB0LHMKdS5ULmIoYikKdD1hLmVudHJpZXMoKQpmb3IoOyEw
-Oyl7cz10Lm5leHQoKQppZihzLmRvbmUpcmV0dXJuCmIuJDIocy52YWx1ZVswXSxQLm1SKHMudmFsdWVb
-MV0pKX19LApndjpmdW5jdGlvbihhKXt2YXIgdD1ILlZNKFtdLHUucykKdGhpcy5VKGEsbmV3IFcuRkEo
-dCkpCnJldHVybiB0fSwKZ2g6ZnVuY3Rpb24oYSl7cmV0dXJuIGEuc2l6ZX0sClk6ZnVuY3Rpb24oYSxi
-LGMpe3Rocm93IEguYihQLkw0KCJOb3Qgc3VwcG9ydGVkIikpfSwKJGlaMDoxfQpXLkZBLnByb3RvdHlw
-ZT17CiQyOmZ1bmN0aW9uKGEsYil7cmV0dXJuIEMuTm0uQSh0aGlzLmEsYSl9LAokUzo4fQpXLnoyLnBy
-b3RvdHlwZT17CnE6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gUC5tUihhLmdldChILnkoYikpKX0sClU6ZnVu
-Y3Rpb24oYSxiKXt2YXIgdCxzCnUuVC5iKGIpCnQ9YS5lbnRyaWVzKCkKZm9yKDshMDspe3M9dC5uZXh0
-KCkKaWYocy5kb25lKXJldHVybgpiLiQyKHMudmFsdWVbMF0sUC5tUihzLnZhbHVlWzFdKSl9fSwKZ3Y6
-ZnVuY3Rpb24oYSl7dmFyIHQ9SC5WTShbXSx1LnMpCnRoaXMuVShhLG5ldyBXLnVxKHQpKQpyZXR1cm4g
-dH0sCmdoOmZ1bmN0aW9uKGEpe3JldHVybiBhLnNpemV9LApZOmZ1bmN0aW9uKGEsYixjKXt0aHJvdyBI
-LmIoUC5MNCgiTm90IHN1cHBvcnRlZCIpKX0sCiRpWjA6MX0KVy51cS5wcm90b3R5cGU9ewokMjpmdW5j
-dGlvbihhLGIpe3JldHVybiBDLk5tLkEodGhpcy5hLGEpfSwKJFM6OH0KVy5BVy5wcm90b3R5cGU9eyRp
-QVc6MX0KVy5ETS5wcm90b3R5cGU9ewpnaDpmdW5jdGlvbihhKXtyZXR1cm4gYS5sZW5ndGh9LApxOmZ1
-bmN0aW9uKGEsYil7SC5TYyhiKQppZihiPj4+MCE9PWJ8fGI+PWEubGVuZ3RoKXRocm93IEguYihQLkNm
-KGIsYSxudWxsLG51bGwsbnVsbCkpCnJldHVybiBhW2JdfSwKWTpmdW5jdGlvbihhLGIsYyl7SC5TYyhi
-KQp1LmNJLmIoYykKdGhyb3cgSC5iKFAuTDQoIkNhbm5vdCBhc3NpZ24gZWxlbWVudCBvZiBpbW11dGFi
-bGUgTGlzdC4iKSl9LApXOmZ1bmN0aW9uKGEsYil7aWYoYjwwfHxiPj1hLmxlbmd0aClyZXR1cm4gSC5P
-SChhLGIpCnJldHVybiBhW2JdfSwKJGliUToxLAokaVhqOjEsCiRpY1g6MSwKJGl6TToxfQpXLkFqLnBy
-b3RvdHlwZT17JGlBajoxfQpXLmU3LnByb3RvdHlwZT17CmdyODpmdW5jdGlvbihhKXt2YXIgdD10aGlz
-LmEscz10LmNoaWxkTm9kZXMubGVuZ3RoCmlmKHM9PT0wKXRocm93IEguYihQLlBWKCJObyBlbGVtZW50
-cyIpKQppZihzPjEpdGhyb3cgSC5iKFAuUFYoIk1vcmUgdGhhbiBvbmUgZWxlbWVudCIpKQpyZXR1cm4g
-dC5maXJzdENoaWxkfSwKRlY6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzLHIscQp1LmVoLmIoYikKdD1iLmEK
-cz10aGlzLmEKaWYodCE9PXMpZm9yKHI9dC5jaGlsZE5vZGVzLmxlbmd0aCxxPTA7cTxyOysrcSlzLmFw
-cGVuZENoaWxkKHQuZmlyc3RDaGlsZCkKcmV0dXJufSwKWTpmdW5jdGlvbihhLGIsYyl7dmFyIHQKSC5T
-YyhiKQp0PXRoaXMuYQp0LnJlcGxhY2VDaGlsZCh1LkEuYihjKSxDLnQ1LnEodC5jaGlsZE5vZGVzLGIp
-KX0sCmdrejpmdW5jdGlvbihhKXt2YXIgdD10aGlzLmEuY2hpbGROb2RlcwpyZXR1cm4gbmV3IFcuVzko
-dCx0Lmxlbmd0aCxILnpLKHQpLkMoIlc5PEdtLkU+IikpfSwKZ2g6ZnVuY3Rpb24oYSl7cmV0dXJuIHRo
-aXMuYS5jaGlsZE5vZGVzLmxlbmd0aH0sCnE6ZnVuY3Rpb24oYSxiKXtILlNjKGIpCnJldHVybiBDLnQ1
-LnEodGhpcy5hLmNoaWxkTm9kZXMsYil9fQpXLnVILnByb3RvdHlwZT17CndnOmZ1bmN0aW9uKGEpe3Zh
-ciB0PWEucGFyZW50Tm9kZQppZih0IT1udWxsKXQucmVtb3ZlQ2hpbGQoYSl9LApENDpmdW5jdGlvbihh
-KXt2YXIgdApmb3IoO3Q9YS5maXJzdENoaWxkLHQhPW51bGw7KWEucmVtb3ZlQ2hpbGQodCl9LAp3OmZ1
-bmN0aW9uKGEpe3ZhciB0PWEubm9kZVZhbHVlCnJldHVybiB0PT1udWxsP3RoaXMuVUcoYSk6dH0sCiRp
-dUg6MX0KVy5CSC5wcm90b3R5cGU9ewpnaDpmdW5jdGlvbihhKXtyZXR1cm4gYS5sZW5ndGh9LApxOmZ1
-bmN0aW9uKGEsYil7SC5TYyhiKQppZihiPj4+MCE9PWJ8fGI+PWEubGVuZ3RoKXRocm93IEguYihQLkNm
-KGIsYSxudWxsLG51bGwsbnVsbCkpCnJldHVybiBhW2JdfSwKWTpmdW5jdGlvbihhLGIsYyl7SC5TYyhi
-KQp1LkEuYihjKQp0aHJvdyBILmIoUC5MNCgiQ2Fubm90IGFzc2lnbiBlbGVtZW50IG9mIGltbXV0YWJs
-ZSBMaXN0LiIpKX0sClc6ZnVuY3Rpb24oYSxiKXtpZihiPDB8fGI+PWEubGVuZ3RoKXJldHVybiBILk9I
-KGEsYikKcmV0dXJuIGFbYl19LAokaWJROjEsCiRpWGo6MSwKJGljWDoxLAokaXpNOjF9ClcuUWwucHJv
-dG90eXBlPXsKZ253OmZ1bmN0aW9uKGEpe3JldHVybiBhLnZhbHVlfX0KVy5HWC5wcm90b3R5cGU9ewpn
-bnc6ZnVuY3Rpb24oYSl7cmV0dXJuIGEudmFsdWV9fQpXLlNOLnByb3RvdHlwZT17fQpXLkhELnByb3Rv
-dHlwZT17CmdudzpmdW5jdGlvbihhKXtyZXR1cm4gYS52YWx1ZX19ClcuY2wucHJvdG90eXBlPXskaWNs
-OjEsCmdoOmZ1bmN0aW9uKGEpe3JldHVybiBhLmxlbmd0aH19ClcuRXYucHJvdG90eXBlPXsKZ2g6ZnVu
-Y3Rpb24oYSl7cmV0dXJuIGEubGVuZ3RofSwKcTpmdW5jdGlvbihhLGIpe0guU2MoYikKaWYoYj4+PjAh
-PT1ifHxiPj1hLmxlbmd0aCl0aHJvdyBILmIoUC5DZihiLGEsbnVsbCxudWxsLG51bGwpKQpyZXR1cm4g
-YVtiXX0sClk6ZnVuY3Rpb24oYSxiLGMpe0guU2MoYikKdS5oZS5iKGMpCnRocm93IEguYihQLkw0KCJD
-YW5ub3QgYXNzaWduIGVsZW1lbnQgb2YgaW1tdXRhYmxlIExpc3QuIikpfSwKVzpmdW5jdGlvbihhLGIp
-e2lmKGI8MHx8Yj49YS5sZW5ndGgpcmV0dXJuIEguT0goYSxiKQpyZXR1cm4gYVtiXX0sCiRpYlE6MSwK
-JGlYajoxLAokaWNYOjEsCiRpek06MX0KVy5Mci5wcm90b3R5cGU9ewpnbnc6ZnVuY3Rpb24oYSl7cmV0
-dXJuIGEudmFsdWV9fQpXLktSLnByb3RvdHlwZT17CmdudzpmdW5jdGlvbihhKXtyZXR1cm4gYS52YWx1
-ZX19ClcuZXcucHJvdG90eXBlPXskaWV3OjF9ClcucDgucHJvdG90eXBlPXsKcTpmdW5jdGlvbihhLGIp
-e3JldHVybiBQLm1SKGEuZ2V0KEgueShiKSkpfSwKVTpmdW5jdGlvbihhLGIpe3ZhciB0LHMKdS5ULmIo
-YikKdD1hLmVudHJpZXMoKQpmb3IoOyEwOyl7cz10Lm5leHQoKQppZihzLmRvbmUpcmV0dXJuCmIuJDIo
-cy52YWx1ZVswXSxQLm1SKHMudmFsdWVbMV0pKX19LApndjpmdW5jdGlvbihhKXt2YXIgdD1ILlZNKFtd
-LHUucykKdGhpcy5VKGEsbmV3IFcuaWkodCkpCnJldHVybiB0fSwKZ2g6ZnVuY3Rpb24oYSl7cmV0dXJu
-IGEuc2l6ZX0sClk6ZnVuY3Rpb24oYSxiLGMpe3Rocm93IEguYihQLkw0KCJOb3Qgc3VwcG9ydGVkIikp
-fSwKJGlaMDoxfQpXLmlpLnByb3RvdHlwZT17CiQyOmZ1bmN0aW9uKGEsYil7cmV0dXJuIEMuTm0uQSh0
-aGlzLmEsYSl9LAokUzo4fQpXLmxwLnByb3RvdHlwZT17CmdoOmZ1bmN0aW9uKGEpe3JldHVybiBhLmxl
-bmd0aH0sCmdudzpmdW5jdGlvbihhKXtyZXR1cm4gYS52YWx1ZX19ClcuU1YucHJvdG90eXBlPXskaVNW
-OjF9ClcuTWsucHJvdG90eXBlPXsKZ2g6ZnVuY3Rpb24oYSl7cmV0dXJuIGEubGVuZ3RofSwKcTpmdW5j
-dGlvbihhLGIpe0guU2MoYikKaWYoYj4+PjAhPT1ifHxiPj1hLmxlbmd0aCl0aHJvdyBILmIoUC5DZihi
-LGEsbnVsbCxudWxsLG51bGwpKQpyZXR1cm4gYVtiXX0sClk6ZnVuY3Rpb24oYSxiLGMpe0guU2MoYikK
-dS5mWS5iKGMpCnRocm93IEguYihQLkw0KCJDYW5ub3QgYXNzaWduIGVsZW1lbnQgb2YgaW1tdXRhYmxl
-IExpc3QuIikpfSwKVzpmdW5jdGlvbihhLGIpe2lmKGI8MHx8Yj49YS5sZW5ndGgpcmV0dXJuIEguT0go
-YSxiKQpyZXR1cm4gYVtiXX0sCiRpYlE6MSwKJGlYajoxLAokaWNYOjEsCiRpek06MX0KVy5ZNC5wcm90
-b3R5cGU9eyRpWTQ6MX0KVy5Obi5wcm90b3R5cGU9ewpnaDpmdW5jdGlvbihhKXtyZXR1cm4gYS5sZW5n
-dGh9LApxOmZ1bmN0aW9uKGEsYil7SC5TYyhiKQppZihiPj4+MCE9PWJ8fGI+PWEubGVuZ3RoKXRocm93
-IEguYihQLkNmKGIsYSxudWxsLG51bGwsbnVsbCkpCnJldHVybiBhW2JdfSwKWTpmdW5jdGlvbihhLGIs
-Yyl7SC5TYyhiKQp1LmY3LmIoYykKdGhyb3cgSC5iKFAuTDQoIkNhbm5vdCBhc3NpZ24gZWxlbWVudCBv
-ZiBpbW11dGFibGUgTGlzdC4iKSl9LApXOmZ1bmN0aW9uKGEsYil7aWYoYjwwfHxiPj1hLmxlbmd0aCly
-ZXR1cm4gSC5PSChhLGIpCnJldHVybiBhW2JdfSwKJGliUToxLAokaVhqOjEsCiRpY1g6MSwKJGl6TTox
-fQpXLmw4LnByb3RvdHlwZT17JGlsODoxLApnaDpmdW5jdGlvbihhKXtyZXR1cm4gYS5sZW5ndGh9fQpX
-LkFzLnByb3RvdHlwZT17CnE6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gYS5nZXRJdGVtKEgueShiKSl9LApZ
-OmZ1bmN0aW9uKGEsYixjKXthLnNldEl0ZW0oYixjKX0sClU6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzCnUu
-VS5iKGIpCmZvcih0PTA7ITA7Kyt0KXtzPWEua2V5KHQpCmlmKHM9PW51bGwpcmV0dXJuCmIuJDIocyxh
-LmdldEl0ZW0ocykpfX0sCmd2OmZ1bmN0aW9uKGEpe3ZhciB0PUguVk0oW10sdS5zKQp0aGlzLlUoYSxu
-ZXcgVy53USh0KSkKcmV0dXJuIHR9LApnaDpmdW5jdGlvbihhKXtyZXR1cm4gYS5sZW5ndGh9LAokaVow
-OjF9Clcud1EucHJvdG90eXBlPXsKJDI6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gQy5ObS5BKHRoaXMuYSxh
-KX0sCiRTOjE2fQpXLmJrLnByb3RvdHlwZT17CmdHMzpmdW5jdGlvbihhKXtyZXR1cm4gYS5rZXl9fQpX
-LldXLnByb3RvdHlwZT17JGlXVzoxfQpXLlRiLnByb3RvdHlwZT17CnI2OmZ1bmN0aW9uKGEsYixjLGQp
-e3ZhciB0LHMKaWYoImNyZWF0ZUNvbnRleHR1YWxGcmFnbWVudCIgaW4gd2luZG93LlJhbmdlLnByb3Rv
-dHlwZSlyZXR1cm4gdGhpcy5EVyhhLGIsYyxkKQp0PVcuVTkoIjx0YWJsZT4iK0guZChiKSsiPC90YWJs
-ZT4iLGMsZCkKcz1kb2N1bWVudC5jcmVhdGVEb2N1bWVudEZyYWdtZW50KCkKcy50b1N0cmluZwp0LnRv
-U3RyaW5nCm5ldyBXLmU3KHMpLkZWKDAsbmV3IFcuZTcodCkpCnJldHVybiBzfX0KVy5Jdi5wcm90b3R5
-cGU9ewpyNjpmdW5jdGlvbihhLGIsYyxkKXt2YXIgdCxzLHIscQppZigiY3JlYXRlQ29udGV4dHVhbEZy
-YWdtZW50IiBpbiB3aW5kb3cuUmFuZ2UucHJvdG90eXBlKXJldHVybiB0aGlzLkRXKGEsYixjLGQpCnQ9
-ZG9jdW1lbnQKcz10LmNyZWF0ZURvY3VtZW50RnJhZ21lbnQoKQp0PUMuSWUucjYodC5jcmVhdGVFbGVt
-ZW50KCJ0YWJsZSIpLGIsYyxkKQp0LnRvU3RyaW5nCnQ9bmV3IFcuZTcodCkKcj10LmdyOCh0KQpyLnRv
-U3RyaW5nCnQ9bmV3IFcuZTcocikKcT10LmdyOCh0KQpzLnRvU3RyaW5nCnEudG9TdHJpbmcKbmV3IFcu
-ZTcocykuRlYoMCxuZXcgVy5lNyhxKSkKcmV0dXJuIHN9fQpXLkJULnByb3RvdHlwZT17CnI2OmZ1bmN0
-aW9uKGEsYixjLGQpe3ZhciB0LHMscgppZigiY3JlYXRlQ29udGV4dHVhbEZyYWdtZW50IiBpbiB3aW5k
-b3cuUmFuZ2UucHJvdG90eXBlKXJldHVybiB0aGlzLkRXKGEsYixjLGQpCnQ9ZG9jdW1lbnQKcz10LmNy
-ZWF0ZURvY3VtZW50RnJhZ21lbnQoKQp0PUMuSWUucjYodC5jcmVhdGVFbGVtZW50KCJ0YWJsZSIpLGIs
-YyxkKQp0LnRvU3RyaW5nCnQ9bmV3IFcuZTcodCkKcj10LmdyOCh0KQpzLnRvU3RyaW5nCnIudG9TdHJp
-bmcKbmV3IFcuZTcocykuRlYoMCxuZXcgVy5lNyhyKSkKcmV0dXJuIHN9fQpXLmZYLnByb3RvdHlwZT17
-CnBrOmZ1bmN0aW9uKGEsYixjKXt2YXIgdCxzCmEudGV4dENvbnRlbnQ9bnVsbAp0PWEuY29udGVudAp0
-LnRvU3RyaW5nCkouYlQodCkKcz10aGlzLnI2KGEsYixudWxsLGMpCmEuY29udGVudC5hcHBlbmRDaGls
-ZChzKX0sCllDOmZ1bmN0aW9uKGEsYil7cmV0dXJuIHRoaXMucGsoYSxiLG51bGwpfSwKJGlmWDoxfQpX
-LkZCLnByb3RvdHlwZT17CmdudzpmdW5jdGlvbihhKXtyZXR1cm4gYS52YWx1ZX19ClcuQTEucHJvdG90
-eXBlPXskaUExOjF9ClcuTU4ucHJvdG90eXBlPXskaU1OOjF9ClcuWDAucHJvdG90eXBlPXsKZ2g6ZnVu
-Y3Rpb24oYSl7cmV0dXJuIGEubGVuZ3RofSwKcTpmdW5jdGlvbihhLGIpe0guU2MoYikKaWYoYj4+PjAh
-PT1ifHxiPj1hLmxlbmd0aCl0aHJvdyBILmIoUC5DZihiLGEsbnVsbCxudWxsLG51bGwpKQpyZXR1cm4g
-YVtiXX0sClk6ZnVuY3Rpb24oYSxiLGMpe0guU2MoYikKdS5jNy5iKGMpCnRocm93IEguYihQLkw0KCJD
-YW5ub3QgYXNzaWduIGVsZW1lbnQgb2YgaW1tdXRhYmxlIExpc3QuIikpfSwKVzpmdW5jdGlvbihhLGIp
-e2lmKGI8MHx8Yj49YS5sZW5ndGgpcmV0dXJuIEguT0goYSxiKQpyZXR1cm4gYVtiXX0sCiRpYlE6MSwK
-JGlYajoxLAokaWNYOjEsCiRpek06MX0KVy5uSi5wcm90b3R5cGU9ewpnaDpmdW5jdGlvbihhKXtyZXR1
-cm4gYS5sZW5ndGh9LApxOmZ1bmN0aW9uKGEsYil7SC5TYyhiKQppZihiPj4+MCE9PWJ8fGI+PWEubGVu
-Z3RoKXRocm93IEguYihQLkNmKGIsYSxudWxsLG51bGwsbnVsbCkpCnJldHVybiBhW2JdfSwKWTpmdW5j
-dGlvbihhLGIsYyl7SC5TYyhiKQp1LmEwLmIoYykKdGhyb3cgSC5iKFAuTDQoIkNhbm5vdCBhc3NpZ24g
-ZWxlbWVudCBvZiBpbW11dGFibGUgTGlzdC4iKSl9LApXOmZ1bmN0aW9uKGEsYil7aWYoYjwwfHxiPj1h
-Lmxlbmd0aClyZXR1cm4gSC5PSChhLGIpCnJldHVybiBhW2JdfSwKJGliUToxLAokaVhqOjEsCiRpY1g6
-MSwKJGl6TToxfQpXLm16LnByb3RvdHlwZT17CmdoOmZ1bmN0aW9uKGEpe3JldHVybiBhLmxlbmd0aH19
-ClcuYTMucHJvdG90eXBlPXskaWEzOjF9ClcuY2kucHJvdG90eXBlPXsKZ2g6ZnVuY3Rpb24oYSl7cmV0
-dXJuIGEubGVuZ3RofSwKcTpmdW5jdGlvbihhLGIpe0guU2MoYikKaWYoYj4+PjAhPT1ifHxiPj1hLmxl
-bmd0aCl0aHJvdyBILmIoUC5DZihiLGEsbnVsbCxudWxsLG51bGwpKQpyZXR1cm4gYVtiXX0sClk6ZnVu
-Y3Rpb24oYSxiLGMpe0guU2MoYikKdS5hSy5iKGMpCnRocm93IEguYihQLkw0KCJDYW5ub3QgYXNzaWdu
-IGVsZW1lbnQgb2YgaW1tdXRhYmxlIExpc3QuIikpfSwKVzpmdW5jdGlvbihhLGIpe2lmKGI8MHx8Yj49
-YS5sZW5ndGgpcmV0dXJuIEguT0goYSxiKQpyZXR1cm4gYVtiXX0sCiRpYlE6MSwKJGlYajoxLAokaWNY
-OjEsCiRpek06MX0KVy5jbi5wcm90b3R5cGU9ewpnaDpmdW5jdGlvbihhKXtyZXR1cm4gYS5sZW5ndGh9
-fQpXLnc2LnByb3RvdHlwZT17fQpXLkZqLnByb3RvdHlwZT17Cnc6ZnVuY3Rpb24oYSl7cmV0dXJuIFN0
-cmluZyhhKX19ClcudkYucHJvdG90eXBlPXsKZ2g6ZnVuY3Rpb24oYSl7cmV0dXJuIGEubGVuZ3RofX0K
-Vy5PaS5wcm90b3R5cGU9ewpnbVc6ZnVuY3Rpb24oYSl7cmV0dXJuIGEubG9jYXRpb259LAokaU9pOjEs
-CiRpdjY6MX0KVy5DbS5wcm90b3R5cGU9eyRpQ206MX0KVy5DUS5wcm90b3R5cGU9eyRpQ1E6MSwKZ253
-OmZ1bmN0aW9uKGEpe3JldHVybiBhLnZhbHVlfX0KVy5QUi5wcm90b3R5cGU9ewpnaDpmdW5jdGlvbihh
-KXtyZXR1cm4gYS5sZW5ndGh9LApxOmZ1bmN0aW9uKGEsYil7SC5TYyhiKQppZihiPj4+MCE9PWJ8fGI+
-PWEubGVuZ3RoKXRocm93IEguYihQLkNmKGIsYSxudWxsLG51bGwsbnVsbCkpCnJldHVybiBhW2JdfSwK
-WTpmdW5jdGlvbihhLGIsYyl7SC5TYyhiKQp1Lmc1LmIoYykKdGhyb3cgSC5iKFAuTDQoIkNhbm5vdCBh
-c3NpZ24gZWxlbWVudCBvZiBpbW11dGFibGUgTGlzdC4iKSl9LApXOmZ1bmN0aW9uKGEsYil7aWYoYjww
-fHxiPj1hLmxlbmd0aClyZXR1cm4gSC5PSChhLGIpCnJldHVybiBhW2JdfSwKJGliUToxLAokaVhqOjEs
-CiRpY1g6MSwKJGl6TToxfQpXLnc0LnByb3RvdHlwZT17Cnc6ZnVuY3Rpb24oYSl7cmV0dXJuIlJlY3Rh
-bmdsZSAoIitILmQoYS5sZWZ0KSsiLCAiK0guZChhLnRvcCkrIikgIitILmQoYS53aWR0aCkrIiB4ICIr
-SC5kKGEuaGVpZ2h0KX0sCkROOmZ1bmN0aW9uKGEsYil7dmFyIHQKaWYoYj09bnVsbClyZXR1cm4hMQpp
-Zih1LnEuYyhiKSlpZihhLmxlZnQ9PT1iLmxlZnQpaWYoYS50b3A9PT1iLnRvcCl7dD1KLlJFKGIpCnQ9
-YS53aWR0aD09PXQuZ1AoYikmJmEuaGVpZ2h0PT09dC5nTChiKX1lbHNlIHQ9ITEKZWxzZSB0PSExCmVs
-c2UgdD0hMQpyZXR1cm4gdH0sCmdpOmZ1bmN0aW9uKGEpe3JldHVybiBXLnJFKEMuQ0QuZ2koYS5sZWZ0
-KSxDLkNELmdpKGEudG9wKSxDLkNELmdpKGEud2lkdGgpLEMuQ0QuZ2koYS5oZWlnaHQpKX0sCmdMOmZ1
-bmN0aW9uKGEpe3JldHVybiBhLmhlaWdodH0sCmdQOmZ1bmN0aW9uKGEpe3JldHVybiBhLndpZHRofX0K
-Vy5GMi5wcm90b3R5cGU9ewpnaDpmdW5jdGlvbihhKXtyZXR1cm4gYS5sZW5ndGh9LApxOmZ1bmN0aW9u
-KGEsYil7SC5TYyhiKQppZihiPj4+MCE9PWJ8fGI+PWEubGVuZ3RoKXRocm93IEguYihQLkNmKGIsYSxu
-dWxsLG51bGwsbnVsbCkpCnJldHVybiBhW2JdfSwKWTpmdW5jdGlvbihhLGIsYyl7SC5TYyhiKQp1LmRQ
-LmIoYykKdGhyb3cgSC5iKFAuTDQoIkNhbm5vdCBhc3NpZ24gZWxlbWVudCBvZiBpbW11dGFibGUgTGlz
-dC4iKSl9LApXOmZ1bmN0aW9uKGEsYil7aWYoYjwwfHxiPj1hLmxlbmd0aClyZXR1cm4gSC5PSChhLGIp
-CnJldHVybiBhW2JdfSwKJGliUToxLAokaVhqOjEsCiRpY1g6MSwKJGl6TToxfQpXLnJoLnByb3RvdHlw
-ZT17CmdoOmZ1bmN0aW9uKGEpe3JldHVybiBhLmxlbmd0aH0sCnE6ZnVuY3Rpb24oYSxiKXtILlNjKGIp
-CmlmKGI+Pj4wIT09Ynx8Yj49YS5sZW5ndGgpdGhyb3cgSC5iKFAuQ2YoYixhLG51bGwsbnVsbCxudWxs
-KSkKcmV0dXJuIGFbYl19LApZOmZ1bmN0aW9uKGEsYixjKXtILlNjKGIpCnUuQS5iKGMpCnRocm93IEgu
-YihQLkw0KCJDYW5ub3QgYXNzaWduIGVsZW1lbnQgb2YgaW1tdXRhYmxlIExpc3QuIikpfSwKVzpmdW5j
-dGlvbihhLGIpe2lmKGI8MHx8Yj49YS5sZW5ndGgpcmV0dXJuIEguT0goYSxiKQpyZXR1cm4gYVtiXX0s
-CiRpYlE6MSwKJGlYajoxLAokaWNYOjEsCiRpek06MX0KVy5MTy5wcm90b3R5cGU9ewpnaDpmdW5jdGlv
-bihhKXtyZXR1cm4gYS5sZW5ndGh9LApxOmZ1bmN0aW9uKGEsYil7SC5TYyhiKQppZihiPj4+MCE9PWJ8
-fGI+PWEubGVuZ3RoKXRocm93IEguYihQLkNmKGIsYSxudWxsLG51bGwsbnVsbCkpCnJldHVybiBhW2Jd
-fSwKWTpmdW5jdGlvbihhLGIsYyl7SC5TYyhiKQp1LmdmLmIoYykKdGhyb3cgSC5iKFAuTDQoIkNhbm5v
-dCBhc3NpZ24gZWxlbWVudCBvZiBpbW11dGFibGUgTGlzdC4iKSl9LApXOmZ1bmN0aW9uKGEsYil7aWYo
-YjwwfHxiPj1hLmxlbmd0aClyZXR1cm4gSC5PSChhLGIpCnJldHVybiBhW2JdfSwKJGliUToxLAokaVhq
-OjEsCiRpY1g6MSwKJGl6TToxfQpXLmIxLnByb3RvdHlwZT17CmdoOmZ1bmN0aW9uKGEpe3JldHVybiBh
-Lmxlbmd0aH0sCnE6ZnVuY3Rpb24oYSxiKXtILlNjKGIpCmlmKGI+Pj4wIT09Ynx8Yj49YS5sZW5ndGgp
-dGhyb3cgSC5iKFAuQ2YoYixhLG51bGwsbnVsbCxudWxsKSkKcmV0dXJuIGFbYl19LApZOmZ1bmN0aW9u
-KGEsYixjKXtILlNjKGIpCnUuZ24uYihjKQp0aHJvdyBILmIoUC5MNCgiQ2Fubm90IGFzc2lnbiBlbGVt
-ZW50IG9mIGltbXV0YWJsZSBMaXN0LiIpKX0sClc6ZnVuY3Rpb24oYSxiKXtpZihiPDB8fGI+PWEubGVu
-Z3RoKXJldHVybiBILk9IKGEsYikKcmV0dXJuIGFbYl19LAokaWJROjEsCiRpWGo6MSwKJGljWDoxLAok
-aXpNOjF9ClcuYVQucHJvdG90eXBlPXsKVTpmdW5jdGlvbihhLGIpe3ZhciB0LHMscixxLHAKdS5VLmIo
-YikKZm9yKHQ9dGhpcy5ndih0aGlzKSxzPXQubGVuZ3RoLHI9dGhpcy5hLHE9MDtxPHQubGVuZ3RoO3Qu
-bGVuZ3RoPT09c3x8KDAsSC5saykodCksKytxKXtwPXRbcV0KYi4kMihwLHIuZ2V0QXR0cmlidXRlKHAp
-KX19LApndjpmdW5jdGlvbihhKXt2YXIgdCxzLHIscSxwPXRoaXMuYS5hdHRyaWJ1dGVzLG89SC5WTShb
-XSx1LnMpCmZvcih0PXAubGVuZ3RoLHM9dS5oOSxyPTA7cjx0Oysrcil7aWYocj49cC5sZW5ndGgpcmV0
-dXJuIEguT0gocCxyKQpxPXMuYihwW3JdKQppZihxLm5hbWVzcGFjZVVSST09bnVsbClDLk5tLkEobyxx
-Lm5hbWUpfXJldHVybiBvfX0KVy5pNy5wcm90b3R5cGU9ewpxOmZ1bmN0aW9uKGEsYil7cmV0dXJuIHRo
-aXMuYS5nZXRBdHRyaWJ1dGUoSC55KGIpKX0sClk6ZnVuY3Rpb24oYSxiLGMpe3RoaXMuYS5zZXRBdHRy
-aWJ1dGUoYixjKX0sCmdoOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLmd2KHRoaXMpLmxlbmd0aH19Clcu
-U3kucHJvdG90eXBlPXsKcTpmdW5jdGlvbihhLGIpe3JldHVybiB0aGlzLmEuYS5nZXRBdHRyaWJ1dGUo
-ImRhdGEtIit0aGlzLlMoSC55KGIpKSl9LApZOmZ1bmN0aW9uKGEsYixjKXt0aGlzLmEuYS5zZXRBdHRy
-aWJ1dGUoImRhdGEtIit0aGlzLlMoYiksYyl9LApVOmZ1bmN0aW9uKGEsYil7dGhpcy5hLlUoMCxuZXcg
-Vy5LUyh0aGlzLHUuVS5iKGIpKSl9LApndjpmdW5jdGlvbihhKXt2YXIgdD1ILlZNKFtdLHUucykKdGhp
-cy5hLlUoMCxuZXcgVy5BMyh0aGlzLHQpKQpyZXR1cm4gdH0sCmdoOmZ1bmN0aW9uKGEpe3JldHVybiB0
-aGlzLmd2KHRoaXMpLmxlbmd0aH0sCnhxOmZ1bmN0aW9uKGEpe3ZhciB0LHMscj1ILlZNKGEuc3BsaXQo
-Ii0iKSx1LnMpCmZvcih0PTE7dDxyLmxlbmd0aDsrK3Qpe3M9clt0XQppZihzLmxlbmd0aD4wKUMuTm0u
-WShyLHQsc1swXS50b1VwcGVyQ2FzZSgpK0ouS1YocywxKSl9cmV0dXJuIEMuTm0uelYociwiIil9LApT
-OmZ1bmN0aW9uKGEpe3ZhciB0LHMscixxLHAKZm9yKHQ9YS5sZW5ndGgscz0wLHI9IiI7czx0Oysrcyl7
-cT1hW3NdCnA9cS50b0xvd2VyQ2FzZSgpCnI9KHEhPT1wJiZzPjA/cisiLSI6cikrcH1yZXR1cm4gci5j
-aGFyQ29kZUF0KDApPT0wP3I6cn19ClcuS1MucHJvdG90eXBlPXsKJDI6ZnVuY3Rpb24oYSxiKXtpZihK
-LnJZKGEpLm5DKGEsImRhdGEtIikpdGhpcy5iLiQyKHRoaXMuYS54cShDLnhCLnluKGEsNSkpLGIpfSwK
-JFM6MTJ9ClcuQTMucHJvdG90eXBlPXsKJDI6ZnVuY3Rpb24oYSxiKXtpZihKLnJZKGEpLm5DKGEsImRh
-dGEtIikpQy5ObS5BKHRoaXMuYix0aGlzLmEueHEoQy54Qi55bihhLDUpKSl9LAokUzoxMn0KVy5JNC5w
-cm90b3R5cGU9ewpERzpmdW5jdGlvbigpe3ZhciB0LHMscixxLHA9UC5Mcyh1Lk4pCmZvcih0PXRoaXMu
-YS5jbGFzc05hbWUuc3BsaXQoIiAiKSxzPXQubGVuZ3RoLHI9MDtyPHM7KytyKXtxPUouVDAodFtyXSkK
-aWYocS5sZW5ndGghPT0wKXAuQSgwLHEpfXJldHVybiBwfSwKcDU6ZnVuY3Rpb24oYSl7dGhpcy5hLmNs
-YXNzTmFtZT11LkMuYihhKS56VigwLCIgIil9LApnaDpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5hLmNs
-YXNzTGlzdC5sZW5ndGh9LApWMTpmdW5jdGlvbihhKXt0aGlzLmEuY2xhc3NOYW1lPSIifSwKdGc6ZnVu
-Y3Rpb24oYSxiKXt2YXIgdD10aGlzLmEuY2xhc3NMaXN0LmNvbnRhaW5zKGIpCnJldHVybiB0fSwKQTpm
-dW5jdGlvbihhLGIpe3ZhciB0PXRoaXMuYS5jbGFzc0xpc3Qscz10LmNvbnRhaW5zKGIpCnQuYWRkKGIp
-CnJldHVybiFzfSwKUno6ZnVuY3Rpb24oYSxiKXt2YXIgdD10aGlzLmEuY2xhc3NMaXN0LHM9dC5jb250
-YWlucyhiKQp0LnJlbW92ZShiKQpyZXR1cm4gc30sCkZWOmZ1bmN0aW9uKGEsYil7Vy5UTih0aGlzLmEs
-dS5YLmIoYikpfX0KVy5Gay5wcm90b3R5cGU9e30KVy5STy5wcm90b3R5cGU9e30KVy5ldS5wcm90b3R5
-cGU9e30KVy54Qy5wcm90b3R5cGU9e30KVy52Ti5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXtyZXR1
-cm4gdGhpcy5hLiQxKHUuQi5iKGEpKX0sCiRTOjI5fQpXLkpRLnByb3RvdHlwZT17CkNZOmZ1bmN0aW9u
-KGEpe3ZhciB0CmlmKCQub3IuYT09PTApe2Zvcih0PTA7dDwyNjI7Kyt0KSQub3IuWSgwLEMuY21bdF0s
-Vy5wUygpKQpmb3IodD0wO3Q8MTI7Kyt0KSQub3IuWSgwLEMuQklbdF0sVy5WNCgpKX19LAppMDpmdW5j
-dGlvbihhKXtyZXR1cm4gJC5BTigpLnRnKDAsVy5yUyhhKSl9LApFYjpmdW5jdGlvbihhLGIsYyl7dmFy
-IHQ9JC5vci5xKDAsSC5kKFcuclMoYSkpKyI6OiIrYikKaWYodD09bnVsbCl0PSQub3IucSgwLCIqOjoi
-K2IpCmlmKHQ9PW51bGwpcmV0dXJuITEKcmV0dXJuIEgueGQodC4kNChhLGIsYyx0aGlzKSl9LAokaWtG
-OjF9ClcuR20ucHJvdG90eXBlPXsKZ2t6OmZ1bmN0aW9uKGEpe3JldHVybiBuZXcgVy5XOShhLHRoaXMu
-Z2goYSksSC56SyhhKS5DKCJXOTxHbS5FPiIpKX19ClcudkQucHJvdG90eXBlPXsKaTA6ZnVuY3Rpb24o
-YSl7cmV0dXJuIEMuTm0uVnIodGhpcy5hLG5ldyBXLlV2KGEpKX0sCkViOmZ1bmN0aW9uKGEsYixjKXty
-ZXR1cm4gQy5ObS5Wcih0aGlzLmEsbmV3IFcuRWcoYSxiLGMpKX0sCiRpa0Y6MX0KVy5Vdi5wcm90b3R5
-cGU9ewokMTpmdW5jdGlvbihhKXtyZXR1cm4gdS5lLmIoYSkuaTAodGhpcy5hKX0sCiRTOjE3fQpXLkVn
-LnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe3JldHVybiB1LmUuYihhKS5FYih0aGlzLmEsdGhpcy5i
-LHRoaXMuYyl9LAokUzoxN30KVy5tNi5wcm90b3R5cGU9ewpDWTpmdW5jdGlvbihhLGIsYyxkKXt2YXIg
-dCxzLHIKdGhpcy5hLkZWKDAsYykKdD1iLmV2KDAsbmV3IFcuRW8oKSkKcz1iLmV2KDAsbmV3IFcuV2so
-KSkKdGhpcy5iLkZWKDAsdCkKcj10aGlzLmMKci5GVigwLEMueEQpCnIuRlYoMCxzKX0sCmkwOmZ1bmN0
-aW9uKGEpe3JldHVybiB0aGlzLmEudGcoMCxXLnJTKGEpKX0sCkViOmZ1bmN0aW9uKGEsYixjKXt2YXIg
-dD10aGlzLHM9Vy5yUyhhKSxyPXQuYwppZihyLnRnKDAsSC5kKHMpKyI6OiIrYikpcmV0dXJuIHQuZC5E
-dChjKQplbHNlIGlmKHIudGcoMCwiKjo6IitiKSlyZXR1cm4gdC5kLkR0KGMpCmVsc2V7cj10LmIKaWYo
-ci50ZygwLEguZChzKSsiOjoiK2IpKXJldHVybiEwCmVsc2UgaWYoci50ZygwLCIqOjoiK2IpKXJldHVy
-biEwCmVsc2UgaWYoci50ZygwLEguZChzKSsiOjoqIikpcmV0dXJuITAKZWxzZSBpZihyLnRnKDAsIio6
-OioiKSlyZXR1cm4hMH1yZXR1cm4hMX0sCiRpa0Y6MX0KVy5Fby5wcm90b3R5cGU9ewokMTpmdW5jdGlv
-bihhKXtyZXR1cm4hQy5ObS50ZyhDLkJJLEgueShhKSl9LAokUzo5fQpXLldrLnByb3RvdHlwZT17CiQx
-OmZ1bmN0aW9uKGEpe3JldHVybiBDLk5tLnRnKEMuQkksSC55KGEpKX0sCiRTOjl9ClcuY3QucHJvdG90
-eXBlPXsKRWI6ZnVuY3Rpb24oYSxiLGMpe2lmKHRoaXMuakYoYSxiLGMpKXJldHVybiEwCmlmKGI9PT0i
-dGVtcGxhdGUiJiZjPT09IiIpcmV0dXJuITAKaWYoYS5nZXRBdHRyaWJ1dGUoInRlbXBsYXRlIik9PT0i
-IilyZXR1cm4gdGhpcy5lLnRnKDAsYikKcmV0dXJuITF9fQpXLklBLnByb3RvdHlwZT17CiQxOmZ1bmN0
-aW9uKGEpe3JldHVybiJURU1QTEFURTo6IitILmQoSC55KGEpKX0sCiRTOjV9ClcuT3cucHJvdG90eXBl
-PXsKaTA6ZnVuY3Rpb24oYSl7dmFyIHQKaWYodS5ldy5jKGEpKXJldHVybiExCnQ9dS5nNy5jKGEpCmlm
-KHQmJlcuclMoYSk9PT0iZm9yZWlnbk9iamVjdCIpcmV0dXJuITEKaWYodClyZXR1cm4hMApyZXR1cm4h
-MX0sCkViOmZ1bmN0aW9uKGEsYixjKXtpZihiPT09ImlzInx8Qy54Qi5uQyhiLCJvbiIpKXJldHVybiEx
-CnJldHVybiB0aGlzLmkwKGEpfSwKJGlrRjoxfQpXLlc5LnByb3RvdHlwZT17Cm06ZnVuY3Rpb24oKXt2
-YXIgdD10aGlzLHM9dC5jKzEscj10LmIKaWYoczxyKXt0LnNwKEoudzIodC5hLHMpKQp0LmM9cwpyZXR1
-cm4hMH10LnNwKG51bGwpCnQuYz1yCnJldHVybiExfSwKZ1I6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMu
-ZH0sCnNwOmZ1bmN0aW9uKGEpe3RoaXMuZD10aGlzLiR0aS5kLmIoYSl9LAokaUFuOjF9ClcuZFcucHJv
-dG90eXBlPXsKZ21XOmZ1bmN0aW9uKGEpe3JldHVybiBXLnpYKHRoaXMuYS5sb2NhdGlvbil9LAokaUQw
-OjEsCiRpdjY6MX0KVy5GYi5wcm90b3R5cGU9e30KVy5rRi5wcm90b3R5cGU9e30KVy5tay5wcm90b3R5
-cGU9eyRpV1E6MX0KVy5Lby5wcm90b3R5cGU9ewpQbjpmdW5jdGlvbihhKXtuZXcgVy5mbSh0aGlzKS4k
-MihhLG51bGwpfSwKRVA6ZnVuY3Rpb24oYSxiKXtpZihiPT1udWxsKUouTHQoYSkKZWxzZSBiLnJlbW92
-ZUNoaWxkKGEpfSwKSTQ6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzLHIscSxwLG89ITAsbj1udWxsLG09bnVs
-bAp0cnl7bj1KLmlnKGEpCm09bi5hLmdldEF0dHJpYnV0ZSgiaXMiKQp1LmguYihhKQp0PWZ1bmN0aW9u
-KGMpe2lmKCEoYy5hdHRyaWJ1dGVzIGluc3RhbmNlb2YgTmFtZWROb2RlTWFwKSlyZXR1cm4gdHJ1ZQp2
-YXIgbD1jLmNoaWxkTm9kZXMKaWYoYy5sYXN0Q2hpbGQmJmMubGFzdENoaWxkIT09bFtsLmxlbmd0aC0x
-XSlyZXR1cm4gdHJ1ZQppZihjLmNoaWxkcmVuKWlmKCEoYy5jaGlsZHJlbiBpbnN0YW5jZW9mIEhUTUxD
-b2xsZWN0aW9ufHxjLmNoaWxkcmVuIGluc3RhbmNlb2YgTm9kZUxpc3QpKXJldHVybiB0cnVlCnZhciBr
-PTAKaWYoYy5jaGlsZHJlbilrPWMuY2hpbGRyZW4ubGVuZ3RoCmZvcih2YXIgaj0wO2o8aztqKyspe3Zh
-ciBpPWMuY2hpbGRyZW5bal0KaWYoaS5pZD09J2F0dHJpYnV0ZXMnfHxpLm5hbWU9PSdhdHRyaWJ1dGVz
-J3x8aS5pZD09J2xhc3RDaGlsZCd8fGkubmFtZT09J2xhc3RDaGlsZCd8fGkuaWQ9PSdjaGlsZHJlbid8
-fGkubmFtZT09J2NoaWxkcmVuJylyZXR1cm4gdHJ1ZX1yZXR1cm4gZmFsc2V9KGEpCm89SC5vVCh0KT8h
-MDohKGEuYXR0cmlidXRlcyBpbnN0YW5jZW9mIE5hbWVkTm9kZU1hcCl9Y2F0Y2gocSl7SC5SdShxKX1z
-PSJlbGVtZW50IHVucHJpbnRhYmxlIgp0cnl7cz1KLmooYSl9Y2F0Y2gocSl7SC5SdShxKX10cnl7cj1X
-LnJTKGEpCnRoaXMua1IodS5oLmIoYSksYixvLHMscix1LkcuYihuKSxILnkobSkpfWNhdGNoKHEpe2lm
-KEguUnUocSkgaW5zdGFuY2VvZiBQLnUpdGhyb3cgcQplbHNle3RoaXMuRVAoYSxiKQp3aW5kb3cKcD0i
-UmVtb3ZpbmcgY29ycnVwdGVkIGVsZW1lbnQgIitILmQocykKaWYodHlwZW9mIGNvbnNvbGUhPSJ1bmRl
-ZmluZWQiKXdpbmRvdy5jb25zb2xlLndhcm4ocCl9fX0sCmtSOmZ1bmN0aW9uKGEsYixjLGQsZSxmLGcp
-e3ZhciB0LHMscixxLHAsbyxuPXRoaXMKaWYoYyl7bi5FUChhLGIpCndpbmRvdwp0PSJSZW1vdmluZyBl
-bGVtZW50IGR1ZSB0byBjb3JydXB0ZWQgYXR0cmlidXRlcyBvbiA8IitkKyI+IgppZih0eXBlb2YgY29u
-c29sZSE9InVuZGVmaW5lZCIpd2luZG93LmNvbnNvbGUud2Fybih0KQpyZXR1cm59aWYoIW4uYS5pMChh
-KSl7bi5FUChhLGIpCndpbmRvdwp0PSJSZW1vdmluZyBkaXNhbGxvd2VkIGVsZW1lbnQgPCIrSC5kKGUp
-KyI+IGZyb20gIitILmQoYikKaWYodHlwZW9mIGNvbnNvbGUhPSJ1bmRlZmluZWQiKXdpbmRvdy5jb25z
-b2xlLndhcm4odCkKcmV0dXJufWlmKGchPW51bGwpaWYoIW4uYS5FYihhLCJpcyIsZykpe24uRVAoYSxi
-KQp3aW5kb3cKdD0iUmVtb3ZpbmcgZGlzYWxsb3dlZCB0eXBlIGV4dGVuc2lvbiA8IitILmQoZSkrJyBp
-cz0iJytnKyciPicKaWYodHlwZW9mIGNvbnNvbGUhPSJ1bmRlZmluZWQiKXdpbmRvdy5jb25zb2xlLndh
-cm4odCkKcmV0dXJufXQ9Zi5ndihmKQpzPUguVk0odC5zbGljZSgwKSxILnQ2KHQpLkMoImpkPDE+Iikp
-CmZvcihyPWYuZ3YoZikubGVuZ3RoLTEsdD1mLmE7cj49MDstLXIpe2lmKHI+PXMubGVuZ3RoKXJldHVy
-biBILk9IKHMscikKcT1zW3JdCnA9bi5hCm89Si5jSChxKQpILnkocSkKaWYoIXAuRWIoYSxvLHQuZ2V0
-QXR0cmlidXRlKHEpKSl7d2luZG93CnA9IlJlbW92aW5nIGRpc2FsbG93ZWQgYXR0cmlidXRlIDwiK0gu
-ZChlKSsiICIrcSsnPSInK0guZCh0LmdldEF0dHJpYnV0ZShxKSkrJyI+JwppZih0eXBlb2YgY29uc29s
-ZSE9InVuZGVmaW5lZCIpd2luZG93LmNvbnNvbGUud2FybihwKQp0LnJlbW92ZUF0dHJpYnV0ZShxKX19
-aWYodS5hVy5jKGEpKW4uUG4oYS5jb250ZW50KX0sCiRpb246MX0KVy5mbS5wcm90b3R5cGU9ewokMjpm
-dW5jdGlvbihhLGIpe3ZhciB0LHMscixxLHA9dGhpcy5hCnN3aXRjaChhLm5vZGVUeXBlKXtjYXNlIDE6
-cC5JNChhLGIpCmJyZWFrCmNhc2UgODpjYXNlIDExOmNhc2UgMzpjYXNlIDQ6YnJlYWsKZGVmYXVsdDpw
-LkVQKGEsYil9dD1hLmxhc3RDaGlsZApmb3IocD11LkE7bnVsbCE9dDspe3M9bnVsbAp0cnl7cz10LnBy
-ZXZpb3VzU2libGluZ31jYXRjaChyKXtILlJ1KHIpCnE9cC5iKHQpCmEucmVtb3ZlQ2hpbGQocSkKdD1u
-dWxsCnM9YS5sYXN0Q2hpbGR9aWYodCE9bnVsbCl0aGlzLiQyKHQsYSkKdD1wLmIocyl9fSwKJFM6NDF9
-ClcuTGUucHJvdG90eXBlPXt9ClcuSlUucHJvdG90eXBlPXt9ClcueFgucHJvdG90eXBlPXt9ClcudmUu
-cHJvdG90eXBlPXt9ClcuYkcucHJvdG90eXBlPXt9ClcudEkucHJvdG90eXBlPXt9ClcuZmcucHJvdG90
-eXBlPXt9ClcuWjcucHJvdG90eXBlPXt9ClcuSFcucHJvdG90eXBlPXt9ClcubEcucHJvdG90eXBlPXt9
-ClcucXMucHJvdG90eXBlPXt9ClcuY3MucHJvdG90eXBlPXt9ClcuS0IucHJvdG90eXBlPXt9ClcuSzcu
-cHJvdG90eXBlPXt9ClcuckIucHJvdG90eXBlPXt9ClcuZlQucHJvdG90eXBlPXt9ClcuZjcucHJvdG90
-eXBlPXt9ClcuYmcucHJvdG90eXBlPXt9Clcub0gucHJvdG90eXBlPXt9ClcuQ0UucHJvdG90eXBlPXt9
-ClcuYUQucHJvdG90eXBlPXt9ClcuWngucHJvdG90eXBlPXt9ClcuT1gucHJvdG90eXBlPXt9ClcuVWou
-cHJvdG90eXBlPXt9Clcuak0ucHJvdG90eXBlPXt9ClcuUVYucHJvdG90eXBlPXt9ClcuQXcucHJvdG90
-eXBlPXt9ClcudHIucHJvdG90eXBlPXt9ClcuTzMucHJvdG90eXBlPXt9ClcuT3YucHJvdG90eXBlPXt9
-ClcuY08ucHJvdG90eXBlPXt9ClcuWUQucHJvdG90eXBlPXt9ClcuRHgucHJvdG90eXBlPXt9ClcuWFcu
-cHJvdG90eXBlPXt9Clcub2EucHJvdG90eXBlPXt9ClcuWFUucHJvdG90eXBlPXt9ClcuUnkucHJvdG90
-eXBlPXt9ClcuenYucHJvdG90eXBlPXt9ClcubnoucHJvdG90eXBlPXt9ClAuaTYucHJvdG90eXBlPXsK
-Vkg6ZnVuY3Rpb24oYSl7dmFyIHQscz10aGlzLmEscj1zLmxlbmd0aApmb3IodD0wO3Q8cjsrK3QpaWYo
-c1t0XT09PWEpcmV0dXJuIHQKQy5ObS5BKHMsYSkKQy5ObS5BKHRoaXMuYixudWxsKQpyZXR1cm4gcn0s
-ClB2OmZ1bmN0aW9uKGEpe3ZhciB0LHMscixxPXRoaXMscD17fQppZihhPT1udWxsKXJldHVybiBhCmlm
-KEgubChhKSlyZXR1cm4gYQppZih0eXBlb2YgYT09Im51bWJlciIpcmV0dXJuIGEKaWYodHlwZW9mIGE9
-PSJzdHJpbmciKXJldHVybiBhCmlmKGEgaW5zdGFuY2VvZiBQLmlQKXJldHVybiBuZXcgRGF0ZShhLmEp
-CmlmKHUuZnYuYyhhKSl0aHJvdyBILmIoUC5TWSgic3RydWN0dXJlZCBjbG9uZSBvZiBSZWdFeHAiKSkK
-aWYodS5PLmMoYSkpcmV0dXJuIGEKaWYodS5kLmMoYSkpcmV0dXJuIGEKaWYodS5iWC5jKGEpKXJldHVy
-biBhCmlmKHUuSS5jKGEpKXJldHVybiBhCmlmKHUuYlouYyhhKXx8dS5kRC5jKGEpfHx1LmJLLmMoYSkp
-cmV0dXJuIGEKaWYodS5HLmMoYSkpe3Q9cS5WSChhKQpzPXEuYgppZih0Pj1zLmxlbmd0aClyZXR1cm4g
-SC5PSChzLHQpCnI9cC5hPXNbdF0KaWYociE9bnVsbClyZXR1cm4gcgpyPXt9CnAuYT1yCkMuTm0uWShz
-LHQscikKSi5oRShhLG5ldyBQLmxSKHAscSkpCnJldHVybiBwLmF9aWYodS5qLmMoYSkpe3Q9cS5WSChh
-KQpwPXEuYgppZih0Pj1wLmxlbmd0aClyZXR1cm4gSC5PSChwLHQpCnI9cFt0XQppZihyIT1udWxsKXJl
-dHVybiByCnJldHVybiBxLmVrKGEsdCl9aWYodS5lSC5jKGEpKXt0PXEuVkgoYSkKcz1xLmIKaWYodD49
-cy5sZW5ndGgpcmV0dXJuIEguT0gocyx0KQpyPXAuYj1zW3RdCmlmKHIhPW51bGwpcmV0dXJuIHIKcj17
-fQpwLmI9cgpDLk5tLlkocyx0LHIpCnEuaW0oYSxuZXcgUC5qZyhwLHEpKQpyZXR1cm4gcC5ifXRocm93
-IEguYihQLlNZKCJzdHJ1Y3R1cmVkIGNsb25lIG9mIG90aGVyIHR5cGUiKSl9LAplazpmdW5jdGlvbihh
-LGIpe3ZhciB0LHM9Si5VNihhKSxyPXMuZ2goYSkscT1uZXcgQXJyYXkocikKQy5ObS5ZKHRoaXMuYixi
-LHEpCmZvcih0PTA7dDxyOysrdClDLk5tLlkocSx0LHRoaXMuUHYocy5xKGEsdCkpKQpyZXR1cm4gcX19
-ClAubFIucHJvdG90eXBlPXsKJDI6ZnVuY3Rpb24oYSxiKXt0aGlzLmEuYVthXT10aGlzLmIuUHYoYil9
-LAokUzoxfQpQLmpnLnByb3RvdHlwZT17CiQyOmZ1bmN0aW9uKGEsYil7dGhpcy5hLmJbYV09dGhpcy5i
-LlB2KGIpfSwKJFM6MX0KUC5hSi5wcm90b3R5cGU9ewpWSDpmdW5jdGlvbihhKXt2YXIgdCxzPXRoaXMu
-YSxyPXMubGVuZ3RoCmZvcih0PTA7dDxyOysrdClpZihzW3RdPT09YSlyZXR1cm4gdApDLk5tLkEocyxh
-KQpDLk5tLkEodGhpcy5iLG51bGwpCnJldHVybiByfSwKUHY6ZnVuY3Rpb24oYSl7dmFyIHQscyxyLHEs
-cCxvLG4sbSxsLGs9dGhpcyxqPXt9CmlmKGE9PW51bGwpcmV0dXJuIGEKaWYoSC5sKGEpKXJldHVybiBh
-CmlmKHR5cGVvZiBhPT0ibnVtYmVyIilyZXR1cm4gYQppZih0eXBlb2YgYT09InN0cmluZyIpcmV0dXJu
-IGEKaWYoYSBpbnN0YW5jZW9mIERhdGUpe3Q9YS5nZXRUaW1lKCkKcz1uZXcgUC5pUCh0LCEwKQpzLlhr
-KHQsITApCnJldHVybiBzfWlmKGEgaW5zdGFuY2VvZiBSZWdFeHApdGhyb3cgSC5iKFAuU1koInN0cnVj
-dHVyZWQgY2xvbmUgb2YgUmVnRXhwIikpCmlmKHR5cGVvZiBQcm9taXNlIT0idW5kZWZpbmVkIiYmYSBp
-bnN0YW5jZW9mIFByb21pc2UpcmV0dXJuIFAuVTgoYSx1LnopCnI9T2JqZWN0LmdldFByb3RvdHlwZU9m
-KGEpCmlmKHI9PT1PYmplY3QucHJvdG90eXBlfHxyPT09bnVsbCl7cT1rLlZIKGEpCnM9ay5iCmlmKHE+
-PXMubGVuZ3RoKXJldHVybiBILk9IKHMscSkKcD1qLmE9c1txXQppZihwIT1udWxsKXJldHVybiBwCm89
-dS56CnA9UC5GbChvLG8pCmouYT1wCkMuTm0uWShzLHEscCkKay5IcChhLG5ldyBQLks1KGosaykpCnJl
-dHVybiBqLmF9aWYoYSBpbnN0YW5jZW9mIEFycmF5KXtuPWEKcT1rLlZIKG4pCnM9ay5iCmlmKHE+PXMu
-bGVuZ3RoKXJldHVybiBILk9IKHMscSkKcD1zW3FdCmlmKHAhPW51bGwpcmV0dXJuIHAKbz1KLlU2KG4p
-Cm09by5naChuKQpDLk5tLlkocyxxLG4pCmZvcihsPTA7bDxtOysrbClvLlkobixsLGsuUHYoby5xKG4s
-bCkpKQpyZXR1cm4gbn1yZXR1cm4gYX19ClAuSzUucHJvdG90eXBlPXsKJDI6ZnVuY3Rpb24oYSxiKXt2
-YXIgdD10aGlzLmEuYSxzPXRoaXMuYi5QdihiKQpKLkIyKHQsYSxzKQpyZXR1cm4gc30sCiRTOjMzfQpQ
-LkJmLnByb3RvdHlwZT17CmltOmZ1bmN0aW9uKGEsYil7dmFyIHQscyxyLHEKdS5ZLmIoYikKZm9yKHQ9
-T2JqZWN0LmtleXMoYSkscz10Lmxlbmd0aCxyPTA7cjxzOysrcil7cT10W3JdCmIuJDIocSxhW3FdKX19
-fQpQLnpnLnByb3RvdHlwZT17CkhwOmZ1bmN0aW9uKGEsYil7dmFyIHQscyxyLHEKdS5ZLmIoYikKZm9y
-KHQ9T2JqZWN0LmtleXMoYSkscz10Lmxlbmd0aCxyPTA7cjx0Lmxlbmd0aDt0Lmxlbmd0aD09PXN8fCgw
-LEgubGspKHQpLCsrcil7cT10W3JdCmIuJDIocSxhW3FdKX19fQpQLmRNLnByb3RvdHlwZT17ClZMOmZ1
-bmN0aW9uKGEpe3ZhciB0CkgueShhKQp0PSQuaEcoKS5iCmlmKHR5cGVvZiBhIT0ic3RyaW5nIilILlZq
-KEgudEwoYSkpCmlmKHQudGVzdChhKSlyZXR1cm4gYQp0aHJvdyBILmIoUC5MMyhhLCJ2YWx1ZSIsIk5v
-dCBhIHZhbGlkIGNsYXNzIHRva2VuIikpfSwKdzpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5ERygpLnpW
-KDAsIiAiKX0sCmdrejpmdW5jdGlvbihhKXt2YXIgdD10aGlzLkRHKCkKcmV0dXJuIFAucmoodCx0LnIs
-SC5MaCh0KS5kKX0sCmdoOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLkRHKCkuYX0sCnRnOmZ1bmN0aW9u
-KGEsYil7dGhpcy5WTChiKQpyZXR1cm4gdGhpcy5ERygpLnRnKDAsYil9LApBOmZ1bmN0aW9uKGEsYil7
-dGhpcy5WTChiKQpyZXR1cm4gSC54ZCh0aGlzLk9TKDAsbmV3IFAuR0UoYikpKX0sClJ6OmZ1bmN0aW9u
-KGEsYil7dmFyIHQscwp0aGlzLlZMKGIpCnQ9dGhpcy5ERygpCnM9dC5SeigwLGIpCnRoaXMucDUodCkK
-cmV0dXJuIHN9LApGVjpmdW5jdGlvbihhLGIpe3RoaXMuT1MoMCxuZXcgUC5ONyh0aGlzLHUuWC5iKGIp
-KSl9LApWMTpmdW5jdGlvbihhKXt0aGlzLk9TKDAsbmV3IFAudVEoKSl9LApPUzpmdW5jdGlvbihhLGIp
-e3ZhciB0LHMKdS5jaC5iKGIpCnQ9dGhpcy5ERygpCnM9Yi4kMSh0KQp0aGlzLnA1KHQpCnJldHVybiBz
-fX0KUC5HRS5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXtyZXR1cm4gdS5DLmIoYSkuQSgwLHRoaXMu
-YSl9LAokUzozNH0KUC5ONy5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXt2YXIgdD10aGlzLmIscz1I
-LnQ2KHQpCnJldHVybiB1LkMuYihhKS5GVigwLG5ldyBILkE4KHQscy5DKCJxVSgxKSIpLmIodGhpcy5h
-Lmd1TSgpKSxzLkMoIkE4PDEscVU+IikpKX0sCiRTOjE0fQpQLnVRLnByb3RvdHlwZT17CiQxOmZ1bmN0
-aW9uKGEpe3UuQy5iKGEpCmlmKGEuYT4wKXthLmI9YS5jPWEuZD1hLmU9YS5mPW51bGwKYS5hPTAKYS5Y
-QSgpfXJldHVybiBudWxsfSwKJFM6MTR9ClAuVzIucHJvdG90eXBlPXsKZ0czOmZ1bmN0aW9uKGEpe3Jl
-dHVybiBhLmtleX19ClAuZTMucHJvdG90eXBlPXsKZ253OmZ1bmN0aW9uKGEpe3JldHVybiBuZXcgUC56
-ZyhbXSxbXSkuUHYoYS52YWx1ZSl9fQpQLmhGLnByb3RvdHlwZT17JGloRjoxfQpQLkJWLnByb3RvdHlw
-ZT17CmdHMzpmdW5jdGlvbihhKXtyZXR1cm4gYS5rZXl9LApnbnc6ZnVuY3Rpb24oYSl7cmV0dXJuIGEu
-dmFsdWV9fQpQLlBDLnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe3ZhciB0CnUuWi5iKGEpCnQ9ZnVu
-Y3Rpb24oYixjLGQpe3JldHVybiBmdW5jdGlvbigpe3JldHVybiBiKGMsZCx0aGlzLEFycmF5LnByb3Rv
-dHlwZS5zbGljZS5hcHBseShhcmd1bWVudHMpKX19KFAuUjQsYSwhMSkKUC5EbSh0LCQudygpLGEpCnJl
-dHVybiB0fSwKJFM6NH0KUC5tdC5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXtyZXR1cm4gbmV3IHRo
-aXMuYShhKX0sCiRTOjR9ClAuTnoucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7cmV0dXJuIG5ldyBQ
-LnI3KGEpfSwKJFM6MzZ9ClAubnAucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7cmV0dXJuIG5ldyBQ
-LlR6KGEsdS5hbSl9LAokUzozN30KUC5VdC5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXtyZXR1cm4g
-bmV3IFAuRTQoYSl9LAokUzozOH0KUC5FNC5wcm90b3R5cGU9ewpxOmZ1bmN0aW9uKGEsYil7aWYodHlw
-ZW9mIGIhPSJzdHJpbmciJiZ0eXBlb2YgYiE9Im51bWJlciIpdGhyb3cgSC5iKFAueFkoInByb3BlcnR5
-IGlzIG5vdCBhIFN0cmluZyBvciBudW0iKSkKcmV0dXJuIFAuTDcodGhpcy5hW2JdKX0sClk6ZnVuY3Rp
-b24oYSxiLGMpe2lmKHR5cGVvZiBiIT0ic3RyaW5nIiYmdHlwZW9mIGIhPSJudW1iZXIiKXRocm93IEgu
-YihQLnhZKCJwcm9wZXJ0eSBpcyBub3QgYSBTdHJpbmcgb3IgbnVtIikpCnRoaXMuYVtiXT1QLndZKGMp
-fSwKRE46ZnVuY3Rpb24oYSxiKXtpZihiPT1udWxsKXJldHVybiExCnJldHVybiBiIGluc3RhbmNlb2Yg
-UC5FNCYmdGhpcy5hPT09Yi5hfSwKdzpmdW5jdGlvbihhKXt2YXIgdCxzCnRyeXt0PVN0cmluZyh0aGlz
-LmEpCnJldHVybiB0fWNhdGNoKHMpe0guUnUocykKdD10aGlzLnhiKDApCnJldHVybiB0fX0sClY3OmZ1
-bmN0aW9uKGEsYil7dmFyIHQscz10aGlzLmEKaWYoYj09bnVsbCl0PW51bGwKZWxzZXt0PUgudDYoYikK
-dD1QLkNIKG5ldyBILkE4KGIsdC5DKCJAKDEpIikuYihQLmlHKCkpLHQuQygiQTg8MSxAPiIpKSwhMCx1
-LnopfXJldHVybiBQLkw3KHNbYV0uYXBwbHkocyx0KSl9LApnaTpmdW5jdGlvbihhKXtyZXR1cm4gMH19
-ClAucjcucHJvdG90eXBlPXt9ClAuVHoucHJvdG90eXBlPXsKY1A6ZnVuY3Rpb24oYSl7dmFyIHQ9dGhp
-cyxzPWE8MHx8YT49dC5naCh0KQppZihzKXRocm93IEguYihQLlRFKGEsMCx0LmdoKHQpLG51bGwsbnVs
-bCkpfSwKcTpmdW5jdGlvbihhLGIpe2lmKHR5cGVvZiBiPT0ibnVtYmVyIiYmYj09PUMuam4ueXUoYikp
-dGhpcy5jUChILlNjKGIpKQpyZXR1cm4gdGhpcy4kdGkuZC5iKHRoaXMuVXIoMCxiKSl9LApZOmZ1bmN0
-aW9uKGEsYixjKXt0aGlzLiR0aS5kLmIoYykKaWYodHlwZW9mIGI9PSJudW1iZXIiJiZiPT09Qy5DRC55
-dShiKSl0aGlzLmNQKEguU2MoYikpCnRoaXMuZTQoMCxiLGMpfSwKZ2g6ZnVuY3Rpb24oYSl7dmFyIHQ9
-dGhpcy5hLmxlbmd0aAppZih0eXBlb2YgdD09PSJudW1iZXIiJiZ0Pj4+MD09PXQpcmV0dXJuIHQKdGhy
-b3cgSC5iKFAuUFYoIkJhZCBKc0FycmF5IGxlbmd0aCIpKX0sCiRpYlE6MSwKJGljWDoxLAokaXpNOjF9
-ClAuY28ucHJvdG90eXBlPXt9ClAudksucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7cmV0dXJuIHRo
-aXMuYS5hTSgwLHRoaXMuYi5DKCIwLyIpLmIoYSkpfSwKJFM6MTB9ClAucFUucHJvdG90eXBlPXsKJDE6
-ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuYS5wbShhKX0sCiRTOjEwfQpQLklOLnByb3RvdHlwZT17fQpQ
-LnRuLnByb3RvdHlwZT17fQpQLnVqLnByb3RvdHlwZT17CmdudzpmdW5jdGlvbihhKXtyZXR1cm4gYS52
-YWx1ZX19ClAueDAucHJvdG90eXBlPXskaXgwOjEsCmdudzpmdW5jdGlvbihhKXtyZXR1cm4gYS52YWx1
-ZX19ClAucTYucHJvdG90eXBlPXsKZ2g6ZnVuY3Rpb24oYSl7cmV0dXJuIGEubGVuZ3RofSwKcTpmdW5j
-dGlvbihhLGIpe0guU2MoYikKaWYoYj4+PjAhPT1ifHxiPj1hLmxlbmd0aCl0aHJvdyBILmIoUC5DZihi
-LGEsbnVsbCxudWxsLG51bGwpKQpyZXR1cm4gYS5nZXRJdGVtKGIpfSwKWTpmdW5jdGlvbihhLGIsYyl7
-SC5TYyhiKQp1LmJHLmIoYykKdGhyb3cgSC5iKFAuTDQoIkNhbm5vdCBhc3NpZ24gZWxlbWVudCBvZiBp
-bW11dGFibGUgTGlzdC4iKSl9LApXOmZ1bmN0aW9uKGEsYil7cmV0dXJuIHRoaXMucShhLGIpfSwKJGli
-UToxLAokaWNYOjEsCiRpek06MX0KUC51UC5wcm90b3R5cGU9eyRpdVA6MSwKZ253OmZ1bmN0aW9uKGEp
-e3JldHVybiBhLnZhbHVlfX0KUC5mei5wcm90b3R5cGU9ewpnaDpmdW5jdGlvbihhKXtyZXR1cm4gYS5s
-ZW5ndGh9LApxOmZ1bmN0aW9uKGEsYil7SC5TYyhiKQppZihiPj4+MCE9PWJ8fGI+PWEubGVuZ3RoKXRo
-cm93IEguYihQLkNmKGIsYSxudWxsLG51bGwsbnVsbCkpCnJldHVybiBhLmdldEl0ZW0oYil9LApZOmZ1
-bmN0aW9uKGEsYixjKXtILlNjKGIpCnUuY2suYihjKQp0aHJvdyBILmIoUC5MNCgiQ2Fubm90IGFzc2ln
-biBlbGVtZW50IG9mIGltbXV0YWJsZSBMaXN0LiIpKX0sClc6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gdGhp
-cy5xKGEsYil9LAokaWJROjEsCiRpY1g6MSwKJGl6TToxfQpQLkVELnByb3RvdHlwZT17CmdoOmZ1bmN0
-aW9uKGEpe3JldHVybiBhLmxlbmd0aH19ClAubmQucHJvdG90eXBlPXskaW5kOjF9ClAuS3EucHJvdG90
-eXBlPXsKZ2g6ZnVuY3Rpb24oYSl7cmV0dXJuIGEubGVuZ3RofSwKcTpmdW5jdGlvbihhLGIpe0guU2Mo
-YikKaWYoYj4+PjAhPT1ifHxiPj1hLmxlbmd0aCl0aHJvdyBILmIoUC5DZihiLGEsbnVsbCxudWxsLG51
-bGwpKQpyZXR1cm4gYS5nZXRJdGVtKGIpfSwKWTpmdW5jdGlvbihhLGIsYyl7SC5TYyhiKQpILnkoYykK
-dGhyb3cgSC5iKFAuTDQoIkNhbm5vdCBhc3NpZ24gZWxlbWVudCBvZiBpbW11dGFibGUgTGlzdC4iKSl9
-LApXOmZ1bmN0aW9uKGEsYil7cmV0dXJuIHRoaXMucShhLGIpfSwKJGliUToxLAokaWNYOjEsCiRpek06
-MX0KUC5LZS5wcm90b3R5cGU9ewpERzpmdW5jdGlvbigpe3ZhciB0LHMscixxLHA9dGhpcy5hLmdldEF0
-dHJpYnV0ZSgiY2xhc3MiKSxvPVAuTHModS5OKQppZihwPT1udWxsKXJldHVybiBvCmZvcih0PXAuc3Bs
-aXQoIiAiKSxzPXQubGVuZ3RoLHI9MDtyPHM7KytyKXtxPUouVDAodFtyXSkKaWYocS5sZW5ndGghPT0w
-KW8uQSgwLHEpfXJldHVybiBvfSwKcDU6ZnVuY3Rpb24oYSl7dGhpcy5hLnNldEF0dHJpYnV0ZSgiY2xh
-c3MiLGEuelYoMCwiICIpKX19ClAuZDUucHJvdG90eXBlPXsKZ0REOmZ1bmN0aW9uKGEpe3JldHVybiBu
-ZXcgUC5LZShhKX0sCnNoZjpmdW5jdGlvbihhLGIpe3RoaXMuWUMoYSxiKX0sCnI2OmZ1bmN0aW9uKGEs
-YixjLGQpe3ZhciB0LHMscixxLHAsbwppZihkPT1udWxsKXt0PUguVk0oW10sdS5tKQpkPW5ldyBXLnZE
-KHQpCkMuTm0uQSh0LFcuVHcobnVsbCkpCkMuTm0uQSh0LFcuQmwoKSkKQy5ObS5BKHQsbmV3IFcuT3co
-KSl9Yz1uZXcgVy5LbyhkKQpzPSc8c3ZnIHZlcnNpb249IjEuMSI+JytILmQoYikrIjwvc3ZnPiIKdD1k
-b2N1bWVudApyPXQuYm9keQpxPShyJiZDLlJZKS5BSChyLHMsYykKcD10LmNyZWF0ZURvY3VtZW50RnJh
-Z21lbnQoKQpxLnRvU3RyaW5nCnQ9bmV3IFcuZTcocSkKbz10LmdyOCh0KQpmb3IoO3Q9by5maXJzdENo
-aWxkLHQhPW51bGw7KXAuYXBwZW5kQ2hpbGQodCkKcmV0dXJuIHB9LApuejpmdW5jdGlvbihhLGIsYyxk
-LGUpe3Rocm93IEguYihQLkw0KCJDYW5ub3QgaW52b2tlIGluc2VydEFkamFjZW50SHRtbCBvbiBTVkcu
-IikpfSwKZ1ZsOmZ1bmN0aW9uKGEpe3JldHVybiBuZXcgVy5ldShhLCJjbGljayIsITEsdS5RKX0sCiRp
-ZDU6MX0KUC56WS5wcm90b3R5cGU9eyRpelk6MX0KUC5OQy5wcm90b3R5cGU9ewpnaDpmdW5jdGlvbihh
-KXtyZXR1cm4gYS5sZW5ndGh9LApxOmZ1bmN0aW9uKGEsYil7SC5TYyhiKQppZihiPj4+MCE9PWJ8fGI+
-PWEubGVuZ3RoKXRocm93IEguYihQLkNmKGIsYSxudWxsLG51bGwsbnVsbCkpCnJldHVybiBhLmdldEl0
-ZW0oYil9LApZOmZ1bmN0aW9uKGEsYixjKXtILlNjKGIpCnUuY00uYihjKQp0aHJvdyBILmIoUC5MNCgi
-Q2Fubm90IGFzc2lnbiBlbGVtZW50IG9mIGltbXV0YWJsZSBMaXN0LiIpKX0sClc6ZnVuY3Rpb24oYSxi
-KXtyZXR1cm4gdGhpcy5xKGEsYil9LAokaWJROjEsCiRpY1g6MSwKJGl6TToxfQpQLmZVLnByb3RvdHlw
-ZT17fQpQLkdDLnByb3RvdHlwZT17fQpQLmpHLnByb3RvdHlwZT17fQpQLmpTLnByb3RvdHlwZT17fQpQ
-LnhXLnByb3RvdHlwZT17fQpQLmRTLnByb3RvdHlwZT17fQpQLndqLnByb3RvdHlwZT17fQpQLk1ZLnBy
-b3RvdHlwZT17fQpQLm42LnByb3RvdHlwZT17JGliUToxLCRpY1g6MSwkaXpNOjEsJGlBUzoxfQpQLnIy
-LnByb3RvdHlwZT17CmdoOmZ1bmN0aW9uKGEpe3JldHVybiBhLmxlbmd0aH19ClAuck8ucHJvdG90eXBl
-PXsKZ253OmZ1bmN0aW9uKGEpe3JldHVybiBhLnZhbHVlfX0KUC56OC5wcm90b3R5cGU9ewpxOmZ1bmN0
-aW9uKGEsYil7cmV0dXJuIFAubVIoYS5nZXQoSC55KGIpKSl9LApVOmZ1bmN0aW9uKGEsYil7dmFyIHQs
-cwp1LlQuYihiKQp0PWEuZW50cmllcygpCmZvcig7ITA7KXtzPXQubmV4dCgpCmlmKHMuZG9uZSlyZXR1
-cm4KYi4kMihzLnZhbHVlWzBdLFAubVIocy52YWx1ZVsxXSkpfX0sCmd2OmZ1bmN0aW9uKGEpe3ZhciB0
-PUguVk0oW10sdS5zKQp0aGlzLlUoYSxuZXcgUC5xZih0KSkKcmV0dXJuIHR9LApnaDpmdW5jdGlvbihh
-KXtyZXR1cm4gYS5zaXplfSwKWTpmdW5jdGlvbihhLGIsYyl7dGhyb3cgSC5iKFAuTDQoIk5vdCBzdXBw
-b3J0ZWQiKSl9LAokaVowOjF9ClAucWYucHJvdG90eXBlPXsKJDI6ZnVuY3Rpb24oYSxiKXtyZXR1cm4g
-Qy5ObS5BKHRoaXMuYSxhKX0sCiRTOjh9ClAuZm8ucHJvdG90eXBlPXsKZ2g6ZnVuY3Rpb24oYSl7cmV0
-dXJuIGEubGVuZ3RofX0KUC5WOC5wcm90b3R5cGU9e30KUC5Hbi5wcm90b3R5cGU9ewpnaDpmdW5jdGlv
-bihhKXtyZXR1cm4gYS5sZW5ndGh9fQpQLlUzLnByb3RvdHlwZT17fQpQLkZuLnByb3RvdHlwZT17Cmdo
-OmZ1bmN0aW9uKGEpe3JldHVybiBhLmxlbmd0aH0sCnE6ZnVuY3Rpb24oYSxiKXtILlNjKGIpCmlmKGI+
-Pj4wIT09Ynx8Yj49YS5sZW5ndGgpdGhyb3cgSC5iKFAuQ2YoYixhLG51bGwsbnVsbCxudWxsKSkKcmV0
-dXJuIFAubVIoYS5pdGVtKGIpKX0sClk6ZnVuY3Rpb24oYSxiLGMpe0guU2MoYikKdS5HLmIoYykKdGhy
-b3cgSC5iKFAuTDQoIkNhbm5vdCBhc3NpZ24gZWxlbWVudCBvZiBpbW11dGFibGUgTGlzdC4iKSl9LApX
-OmZ1bmN0aW9uKGEsYil7cmV0dXJuIHRoaXMucShhLGIpfSwKJGliUToxLAokaWNYOjEsCiRpek06MX0K
-UC5tby5wcm90b3R5cGU9e30KUC5LZy5wcm90b3R5cGU9e30KVS5kMi5wcm90b3R5cGU9e30KVS5TZS5w
-cm90b3R5cGU9e30KVS5NbC5wcm90b3R5cGU9e30KVS55RC5wcm90b3R5cGU9ewpnUHU6ZnVuY3Rpb24o
-YSl7cmV0dXJuIHRoaXMuYn19ClUud2IucHJvdG90eXBlPXt9CkIuajgucHJvdG90eXBlPXt9CkIucXAu
-cHJvdG90eXBlPXt9ClQubVEucHJvdG90eXBlPXt9CkwuZS5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihh
-KXt2YXIgdCxzLHIscSxwLG8sbgp1LkIuYihhKQp0PXdpbmRvdy5sb2NhdGlvbi5wYXRobmFtZQpzPUwu
-RzYod2luZG93LmxvY2F0aW9uLmhyZWYpCnI9TC5hSyh3aW5kb3cubG9jYXRpb24uaHJlZikKTC5HZSgp
-CmlmKHQhPT0iLyImJnQhPT1KLlQwKGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoIi5yb290IikudGV4dENv
-bnRlbnQpKUwuRzcodCxzLHIsITAsbmV3IEwuVlcodCxzLHIpKQpxPWRvY3VtZW50CnA9Si5xRihxLnF1
-ZXJ5U2VsZWN0b3IoIi5hcHBseS1taWdyYXRpb24iKSkKbz1wLiR0aQpuPW8uQygifigxKSIpLmIobmV3
-IEwub1ooKSkKdS5NLmIobnVsbCkKVy5KRShwLmEscC5iLG4sITEsby5kKQpxPUoucUYocS5xdWVyeVNl
-bGVjdG9yKCIucmVydW4tbWlncmF0aW9uIikpCm89cS4kdGkKVy5KRShxLmEscS5iLG8uQygifigxKSIp
-LmIobmV3IEwueTgoKSksITEsby5kKX0sCiRTOjIwfQpMLlZXLnByb3RvdHlwZT17CiQwOmZ1bmN0aW9u
-KCl7TC5Gcih0aGlzLmEsdGhpcy5iLHRoaXMuYyl9LAokUzowfQpMLm9aLnByb3RvdHlwZT17CiQxOmZ1
-bmN0aW9uKGEpe3UuVi5iKGEpCmlmKEgub1Qod2luZG93LmNvbmZpcm0oIlRoaXMgd2lsbCBhcHBseSB0
-aGUgY2hhbmdlcyB5b3UndmUgcHJldmlld2VkIHRvIHlvdXIgd29ya2luZyBkaXJlY3RvcnkuIEl0IGlz
-IHJlY29tbWVuZGVkIHlvdSBjb21taXQgYW55IGNoYW5nZXMgeW91IG1hZGUgYmVmb3JlIGRvaW5nIHRo
-aXMuIikpKUwudHkoIi9hcHBseS1taWdyYXRpb24iKS5XNyhuZXcgTC5qcigpLHUuUCkuT0EobmV3IEwu
-cWwoKSl9LAokUzo2fQpMLmpyLnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe3ZhciB0CnUuci5iKGEp
-CnQ9ZG9jdW1lbnQuYm9keQp0LmNsYXNzTGlzdC5yZW1vdmUoInByb3Bvc2VkIikKdC5jbGFzc0xpc3Qu
-YWRkKCJhcHBsaWVkIil9LAokUzo3fQpMLnFsLnByb3RvdHlwZT17CiQyOmZ1bmN0aW9uKGEsYil7TC5x
-SigiYXBwbHkgbWlncmF0aW9uIGVycm9yOiAiK0guZChhKSxiKQp3aW5kb3cuYWxlcnQoIkNvdWxkIG5v
-dCBhcHBseSBtaWdyYXRpb24gKCIrSC5kKGEpKyIpLiIpfSwKJEM6IiQyIiwKJFI6MiwKJFM6MX0KTC55
-OC5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy54bih1LlYuYihhKSl9LAp4bjpm
-dW5jdGlvbihhKXt2YXIgdD0wLHM9UC5GWCh1LlApLHI9MSxxLHA9W10sbyxuLG0sbAp2YXIgJGFzeW5j
-JCQxPVAubHooZnVuY3Rpb24oYixjKXtpZihiPT09MSl7cT1jCnQ9cn13aGlsZSh0cnVlKXN3aXRjaCh0
-KXtjYXNlIDA6cj0zCmRvY3VtZW50LmJvZHkuY2xhc3NMaXN0LmFkZCgicmVydW5uaW5nIikKdD02CnJl
-dHVybiBQLmpRKEwudHkoIi9yZXJ1bi1taWdyYXRpb24iKSwkYXN5bmMkJDEpCmNhc2UgNjp3aW5kb3cu
-bG9jYXRpb24ucmVsb2FkKCkKcC5wdXNoKDUpCnQ9NApicmVhawpjYXNlIDM6cj0yCmw9cQpvPUguUnUo
-bCkKbj1ILnRzKGwpCkwucUooInJlcnVuIG1pZ3JhdGlvbjogIitILmQobyksbikKd2luZG93LmFsZXJ0
-KCJGYWlsZWQgdG8gcmVydW4gbWlncmF0aW9uOiAiK0guZChvKSsiLiIpCnAucHVzaCg1KQp0PTQKYnJl
-YWsKY2FzZSAyOnA9WzFdCmNhc2UgNDpyPTEKZG9jdW1lbnQuYm9keS5jbGFzc0xpc3QucmVtb3ZlKCJy
-ZXJ1bm5pbmciKQp0PXAucG9wKCkKYnJlYWsKY2FzZSA1OnJldHVybiBQLnlDKG51bGwscykKY2FzZSAx
-OnJldHVybiBQLmYzKHEscyl9fSkKcmV0dXJuIFAuREkoJGFzeW5jJCQxLHMpfSwKJFM6NDJ9CkwuTC5w
-cm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXt2YXIgdCxzLHIKdS5CLmIoYSkKdD13aW5kb3cubG9jYXRp
-b24ucGF0aG5hbWUKcz1MLkc2KHdpbmRvdy5sb2NhdGlvbi5ocmVmKQpyPUwuYUsod2luZG93LmxvY2F0
-aW9uLmhyZWYpCmlmKHQubGVuZ3RoPjEpTC5HNyh0LHMsciwhMSxudWxsKQplbHNle0wuQkUodCxuZXcg
-Qi5xcCgiIiwiIiwiIixDLkNNKSwhMCkKTC5CWCgiJm5ic3A7IixudWxsKX19LAokUzoyMH0KTC5XeC5w
-cm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXt2YXIgdCxzLHIscT0iY29sbGFwc2VkIgp1LlYuYihhKQp0
-PXRoaXMuYQpzPUouUkUodCkKcj10aGlzLmIKaWYoIXMuZ0REKHQpLnRnKDAscSkpe3MuZ0REKHQpLkEo
-MCxxKQpKLmRSKHIpLkEoMCxxKX1lbHNle3MuZ0REKHQpLlJ6KDAscSkKSi5kUihyKS5SeigwLHEpfX0s
-CiRTOjZ9CkwuQU8ucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7dmFyIHQ9Si5xRih1LmguYihhKSks
-cz10LiR0aSxyPXMuQygifigxKSIpLmIobmV3IEwuZE4odGhpcy5hKSkKdS5NLmIobnVsbCkKVy5KRSh0
-LmEsdC5iLHIsITEscy5kKX0sCiRTOjN9CkwuZE4ucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7dmFy
-IHQKdS5WLmIoYSkKdD1kb2N1bWVudC5xdWVyeVNlbGVjdG9yKCJ0YWJsZVtkYXRhLXBhdGhdIikKdC50
-b1N0cmluZwpMLnQyKGEsdGhpcy5hLHQuZ2V0QXR0cmlidXRlKCJkYXRhLSIrbmV3IFcuU3kobmV3IFcu
-aTcodCkpLlMoInBhdGgiKSkpfSwKJFM6Nn0KTC5Iby5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXt2
-YXIgdCxzLHIKdS5oLmIoYSkKdD1KLnFGKGEpCnM9dC4kdGkKcj1zLkMoIn4oMSkiKS5iKG5ldyBMLnh6
-KGEsdGhpcy5hKSkKdS5NLmIobnVsbCkKVy5KRSh0LmEsdC5iLHIsITEscy5kKX0sCiRTOjN9CkwueHou
-cHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7dmFyIHQscz1udWxsCnUuVi5iKGEpCnQ9dGhpcy5hCkwu
-aFgodGhpcy5iLFAuUUEodC5nZXRBdHRyaWJ1dGUoImRhdGEtIituZXcgVy5TeShuZXcgVy5pNyh0KSku
-Uygib2Zmc2V0IikpLHMscyksUC5RQSh0LmdldEF0dHJpYnV0ZSgiZGF0YS0iK25ldyBXLlN5KG5ldyBX
-Lmk3KHQpKS5TKCJsaW5lIikpLHMscykpfSwKJFM6Nn0KTC5JQy5wcm90b3R5cGU9ewokMTpmdW5jdGlv
-bihhKXt2YXIgdD1KLnFGKHUuaC5iKGEpKSxzPXQuJHRpCnMuQygifigxKSIpLmIoTC5IMCgpKQp1Lk0u
-YihudWxsKQpXLkpFKHQuYSx0LmIsTC5IMCgpLCExLHMuZCl9LAokUzozfQpMLkwxLnByb3RvdHlwZT17
-CiQxOmZ1bmN0aW9uKGEpe3ZhciB0CnUuci5iKGEpCnQ9YS5zdGF0dXMKaWYodD09PTIwMClyZXR1cm4g
-YQplbHNlIHRocm93IEguYigiUmVxdWVzdCBmYWlsZWQ7IHN0YXR1cyBvZiAiK0guZCh0KSl9LAokUzo0
-NH0KTC5uVC5wcm90b3R5cGU9ewokMDpmdW5jdGlvbigpe0wuRnIodGhpcy5hLmEsdGhpcy5iLHRoaXMu
-Yyl9LAokUzowfQpMLkJaLnByb3RvdHlwZT17CiQwOmZ1bmN0aW9uKCl7TC5Gcih0aGlzLmEuYSxudWxs
-LG51bGwpfSwKJFM6MH0KTC5HSC5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXt1LmguYihhKQokLnpC
-KCkudG9TdHJpbmcKdS52LmIoJC5vdygpLnEoMCwiaGxqcyIpKS5WNygiaGlnaGxpZ2h0QmxvY2siLFth
-XSl9LAokUzozfQpMLkRULnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe3ZhciB0LHMKdS5yLmIoYSkK
-dD1hLnN0YXR1cwppZih0PT09MjAwKXt0PUMuQ3QucFcoMCxhLnJlc3BvbnNlVGV4dCxudWxsKQpzPUou
-VTYodCkKTC5UMShuZXcgVS5kMihVLmpmKHMucSh0LCJlZGl0cyIpKSxILnkocy5xKHQsImV4cGxhbmF0
-aW9uIikpLEguU2Mocy5xKHQsImxpbmUiKSksSC55KHMucSh0LCJwYXRoIikpLFUuTmQocy5xKHQsInRy
-YWNlcyIpKSkpCkwuRnIodGhpcy5hLHRoaXMuYix0aGlzLmMpCkwueVgoIi5lZGl0LXBhbmVsIC5wYW5l
-bC1jb250ZW50IiwhMSl9ZWxzZSB3aW5kb3cuYWxlcnQoIlJlcXVlc3QgZmFpbGVkOyBzdGF0dXMgb2Yg
-IitILmQodCkpfSwKJFM6N30KTC5lSC5wcm90b3R5cGU9ewokMjpmdW5jdGlvbihhLGIpe0wucUooImxv
-YWRSZWdpb25FeHBsYW5hdGlvbjogIitILmQoYSksYikKd2luZG93LmFsZXJ0KCJDb3VsZCBub3QgbG9h
-ZCAiK0guZCh0aGlzLmEpKyIgKCIrSC5kKGEpKyIpLiIpfSwKJEM6IiQyIiwKJFI6MiwKJFM6MX0KTC55
-dS5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXt2YXIgdCxzLHI9dGhpcwp1LnIuYihhKQp0PWEuc3Rh
-dHVzCmlmKHQ9PT0yMDApe3M9ci5hCkwuQkUocyxCLllmKHUuYi5iKEMuQ3QucFcoMCxhLnJlc3BvbnNl
-VGV4dCxudWxsKSkpLHIuYikKdD1yLmMKTC5mRyh0LHIuZCkKTC5CWChDLnhCLnRnKHMsIj8iKT9DLnhC
-Lk5qKHMsMCxDLnhCLk9ZKHMsIj8iKSk6cyx0KQp0PXIuZQppZih0IT1udWxsKXQuJDAoKX1lbHNlIHdp
-bmRvdy5hbGVydCgiUmVxdWVzdCBmYWlsZWQ7IHN0YXR1cyBvZiAiK0guZCh0KSl9LAokUzo3fQpMLnpE
-LnByb3RvdHlwZT17CiQyOmZ1bmN0aW9uKGEsYil7TC5xSigibG9hZEZpbGU6ICIrSC5kKGEpLGIpCndp
-bmRvdy5hbGVydCgiQ291bGQgbm90IGxvYWQgIit0aGlzLmErIiAoIitILmQoYSkrIikuIil9LAokQzoi
-JDIiLAokUjoyLAokUzoxfQpMLlRXLnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe3ZhciB0LHMscgp1
-LnIuYihhKQp0PWEuc3RhdHVzCmlmKHQ9PT0yMDApe3M9Qy5DdC5wVygwLGEucmVzcG9uc2VUZXh0LG51
-bGwpCnI9ZG9jdW1lbnQucXVlcnlTZWxlY3RvcigiLm5hdi10cmVlIikKSi5sNShyLCIiKQpMLnRYKHIs
-TC5tSyhzKSl9ZWxzZSB3aW5kb3cuYWxlcnQoIlJlcXVlc3QgZmFpbGVkOyBzdGF0dXMgb2YgIitILmQo
-dCkpfSwKJFM6N30KTC54ci5wcm90b3R5cGU9ewokMjpmdW5jdGlvbihhLGIpe0wucUooImxvYWROYXZp
-Z2F0aW9uVHJlZTogIitILmQoYSksYikKd2luZG93LmFsZXJ0KCJDb3VsZCBub3QgbG9hZCAiK3RoaXMu
-YSsiICgiK0guZChhKSsiKS4iKX0sCiRDOiIkMiIsCiRSOjIsCiRTOjF9CkwuRUUucHJvdG90eXBlPXsK
-JDE6ZnVuY3Rpb24oYSl7dmFyIHQscwp1LlYuYihhKQp0PXRoaXMuYQpzPXRoaXMuYgpMLmFmKHdpbmRv
-dy5sb2NhdGlvbi5wYXRobmFtZSx0LHMsITAsbmV3IEwuUUwodCxzKSkKTC5oWCh0aGlzLmMsdCxzKX0s
-CiRTOjZ9CkwuUUwucHJvdG90eXBlPXsKJDA6ZnVuY3Rpb24oKXtMLkZyKHdpbmRvdy5sb2NhdGlvbi5w
-YXRobmFtZSx0aGlzLmEsdGhpcy5iKX0sCiRTOjB9CkwuVlMucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24o
-YSl7dmFyIHQscz0ic2VsZWN0ZWQtZmlsZSIKdS5oLmIoYSkKYS50b1N0cmluZwp0PUouUkUoYSkKaWYo
-YS5nZXRBdHRyaWJ1dGUoImRhdGEtIituZXcgVy5TeShuZXcgVy5pNyhhKSkuUygibmFtZSIpKT09PXRo
-aXMuYS5hKXQuZ0REKGEpLkEoMCxzKQplbHNlIHQuZ0REKGEpLlJ6KDAscyl9LAokUzozfQpMLlRELnBy
-b3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe3JldHVybiBMLnQyKHUuVi5iKGEpLCEwLG51bGwpfSwKJFM6
-MjF9CkwuWEEucHJvdG90eXBlPXsKRWI6ZnVuY3Rpb24oYSxiLGMpe3JldHVybiEwfSwKaTA6ZnVuY3Rp
-b24oYSl7cmV0dXJuITB9LAokaWtGOjF9CkwuWloucHJvdG90eXBlPXt9CkwuQmMucHJvdG90eXBlPXsK
-dzpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5ifX0KTS5sSS5wcm90b3R5cGU9ewpXTzpmdW5jdGlvbihh
-LGIpe3ZhciB0LHM9bnVsbApNLllGKCJhYnNvbHV0ZSIsSC5WTShbYixudWxsLG51bGwsbnVsbCxudWxs
-LG51bGwsbnVsbF0sdS5zKSkKdD10aGlzLmEKdD10LllyKGIpPjAmJiF0LmhLKGIpCmlmKHQpcmV0dXJu
-IGIKdD1ELlJYKCkKcmV0dXJuIHRoaXMucTcoMCx0LGIscyxzLHMscyxzLHMpfSwKdE06ZnVuY3Rpb24o
-YSl7dmFyIHQscyxyPVguQ0woYSx0aGlzLmEpCnIuSVYoKQp0PXIuZApzPXQubGVuZ3RoCmlmKHM9PT0w
-KXt0PXIuYgpyZXR1cm4gdD09bnVsbD8iLiI6dH1pZihzPT09MSl7dD1yLmIKcmV0dXJuIHQ9PW51bGw/
-Ii4iOnR9aWYoMD49cylyZXR1cm4gSC5PSCh0LC0xKQp0LnBvcCgpCkMuTm0ubXYoci5lKQpyLklWKCkK
-cmV0dXJuIHIudygwKX0sCnE3OmZ1bmN0aW9uKGEsYixjLGQsZSxmLGcsaCxpKXt2YXIgdD1ILlZNKFti
-LGMsZCxlLGYsZyxoLGldLHUucykKTS5ZRigiam9pbiIsdCkKcmV0dXJuIHRoaXMuSVAobmV3IEguVTUo
-dCx1LmJCLmIobmV3IE0uTWkoKSksdS5jYykpfSwKSVA6ZnVuY3Rpb24oYSl7dmFyIHQscyxyLHEscCxv
-LG4sbSxsCnUuWC5iKGEpCmZvcih0PWEuJHRpLHM9dC5DKCJhMihjWC5FKSIpLmIobmV3IE0ucTcoKSks
-cj1hLmdreihhKSx0PW5ldyBILlNPKHIscyx0LkMoIlNPPGNYLkU+IikpLHM9dGhpcy5hLHE9ITEscD0h
-MSxvPSIiO3QubSgpOyl7bj1yLmdSKHIpCmlmKHMuaEsobikmJnApe209WC5DTChuLHMpCmw9by5jaGFy
-Q29kZUF0KDApPT0wP286bwpvPUMueEIuTmoobCwwLHMuU3AobCwhMCkpCm0uYj1vCmlmKHMuZHMobykp
-Qy5ObS5ZKG0uZSwwLHMuZ21JKCkpCm89bS53KDApfWVsc2UgaWYocy5ZcihuKT4wKXtwPSFzLmhLKG4p
-Cm89SC5kKG4pfWVsc2V7aWYoIShuLmxlbmd0aD4wJiZzLlVkKG5bMF0pKSlpZihxKW8rPXMuZ21JKCkK
-bys9SC5kKG4pfXE9cy5kcyhuKX1yZXR1cm4gby5jaGFyQ29kZUF0KDApPT0wP286b30sCm81OmZ1bmN0
-aW9uKGEsYil7dmFyIHQKaWYoIXRoaXMueTMoYikpcmV0dXJuIGIKdD1YLkNMKGIsdGhpcy5hKQp0LnJS
-KDApCnJldHVybiB0LncoMCl9LAp5MzpmdW5jdGlvbihhKXt2YXIgdCxzLHIscSxwLG8sbixtLGwsawph
-LnRvU3RyaW5nCnQ9dGhpcy5hCnM9dC5ZcihhKQppZihzIT09MCl7aWYodD09PSQuS2soKSlmb3Iocj0w
-O3I8czsrK3IpaWYoQy54Qi5XZChhLHIpPT09NDcpcmV0dXJuITAKcT1zCnA9NDd9ZWxzZXtxPTAKcD1u
-dWxsfWZvcihvPW5ldyBILnFqKGEpLmEsbj1vLmxlbmd0aCxyPXEsbT1udWxsO3I8bjsrK3IsbT1wLHA9
-bCl7bD1DLnhCLk8yKG8scikKaWYodC5yNChsKSl7aWYodD09PSQuS2soKSYmbD09PTQ3KXJldHVybiEw
-CmlmKHAhPW51bGwmJnQucjQocCkpcmV0dXJuITAKaWYocD09PTQ2KWs9bT09bnVsbHx8bT09PTQ2fHx0
-LnI0KG0pCmVsc2Ugaz0hMQppZihrKXJldHVybiEwfX1pZihwPT1udWxsKXJldHVybiEwCmlmKHQucjQo
-cCkpcmV0dXJuITAKaWYocD09PTQ2KXQ9bT09bnVsbHx8dC5yNChtKXx8bT09PTQ2CmVsc2UgdD0hMQpp
-Zih0KXJldHVybiEwCnJldHVybiExfSwKSFA6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzLHIscSxwLG89dGhp
-cyxuPSdVbmFibGUgdG8gZmluZCBhIHBhdGggdG8gIicKYj1vLldPKDAsYikKdD1vLmEKaWYodC5Zcihi
-KTw9MCYmdC5ZcihhKT4wKXJldHVybiBvLm81KDAsYSkKaWYodC5ZcihhKTw9MHx8dC5oSyhhKSlhPW8u
-V08oMCxhKQppZih0LllyKGEpPD0wJiZ0LllyKGIpPjApdGhyb3cgSC5iKFguSTcobitILmQoYSkrJyIg
-ZnJvbSAiJytILmQoYikrJyIuJykpCnM9WC5DTChiLHQpCnMuclIoMCkKcj1YLkNMKGEsdCkKci5yUigw
-KQpxPXMuZAppZihxLmxlbmd0aD4wJiZKLlJNKHFbMF0sIi4iKSlyZXR1cm4gci53KDApCnE9cy5iCnA9
-ci5iCmlmKHEhPXApcT1xPT1udWxsfHxwPT1udWxsfHwhdC5OYyhxLHApCmVsc2UgcT0hMQppZihxKXJl
-dHVybiByLncoMCkKd2hpbGUoITApe3E9cy5kCmlmKHEubGVuZ3RoPjApe3A9ci5kCnE9cC5sZW5ndGg+
-MCYmdC5OYyhxWzBdLHBbMF0pfWVsc2UgcT0hMQppZighcSlicmVhawpDLk5tLlc0KHMuZCwwKQpDLk5t
-Llc0KHMuZSwxKQpDLk5tLlc0KHIuZCwwKQpDLk5tLlc0KHIuZSwxKX1xPXMuZAppZihxLmxlbmd0aD4w
-JiZKLlJNKHFbMF0sIi4uIikpdGhyb3cgSC5iKFguSTcobitILmQoYSkrJyIgZnJvbSAiJytILmQoYikr
-JyIuJykpCnE9dS5OCkMuTm0ub0Yoci5kLDAsUC5POChzLmQubGVuZ3RoLCIuLiIscSkpCkMuTm0uWShy
-LmUsMCwiIikKQy5ObS5vRihyLmUsMSxQLk84KHMuZC5sZW5ndGgsdC5nbUkoKSxxKSkKdD1yLmQKcT10
-Lmxlbmd0aAppZihxPT09MClyZXR1cm4iLiIKaWYocT4xJiZKLlJNKEMuTm0uZ3JaKHQpLCIuIikpe3Q9
-ci5kCmlmKDA+PXQubGVuZ3RoKXJldHVybiBILk9IKHQsLTEpCnQucG9wKCkKdD1yLmUKQy5ObS5tdih0
-KQpDLk5tLm12KHQpCkMuTm0uQSh0LCIiKX1yLmI9IiIKci5JVigpCnJldHVybiByLncoMCl9fQpNLk1p
-LnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe3JldHVybiBILnkoYSkhPW51bGx9LAokUzo5fQpNLnE3
-LnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe3JldHVybiBILnkoYSkhPT0iIn0sCiRTOjl9Ck0uTm8u
-cHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7SC55KGEpCnJldHVybiBhPT1udWxsPyJudWxsIjonIicr
-YSsnIid9LAokUzo1fQpCLkx1LnByb3RvdHlwZT17CnhaOmZ1bmN0aW9uKGEpe3ZhciB0LHM9dGhpcy5Z
-cihhKQppZihzPjApcmV0dXJuIEoubGQoYSwwLHMpCmlmKHRoaXMuaEsoYSkpe2lmKDA+PWEubGVuZ3Ro
-KXJldHVybiBILk9IKGEsMCkKdD1hWzBdfWVsc2UgdD1udWxsCnJldHVybiB0fSwKTmM6ZnVuY3Rpb24o
-YSxiKXtyZXR1cm4gYT09Yn19ClguV0QucHJvdG90eXBlPXsKSVY6ZnVuY3Rpb24oKXt2YXIgdCxzLHI9
-dGhpcwp3aGlsZSghMCl7dD1yLmQKaWYoISh0Lmxlbmd0aCE9PTAmJkouUk0oQy5ObS5ncloodCksIiIp
-KSlicmVhawp0PXIuZAppZigwPj10Lmxlbmd0aClyZXR1cm4gSC5PSCh0LC0xKQp0LnBvcCgpCkMuTm0u
-bXYoci5lKX10PXIuZQpzPXQubGVuZ3RoCmlmKHM+MClDLk5tLlkodCxzLTEsIiIpfSwKclI6ZnVuY3Rp
-b24oYSl7dmFyIHQscyxyLHEscCxvLG4sbT10aGlzLGw9SC5WTShbXSx1LnMpCmZvcih0PW0uZCxzPXQu
-bGVuZ3RoLHI9MCxxPTA7cTx0Lmxlbmd0aDt0Lmxlbmd0aD09PXN8fCgwLEgubGspKHQpLCsrcSl7cD10
-W3FdCm89Si5pYShwKQppZighKG8uRE4ocCwiLiIpfHxvLkROKHAsIiIpKSlpZihvLkROKHAsIi4uIikp
-aWYobC5sZW5ndGg+MClsLnBvcCgpCmVsc2UgKytyCmVsc2UgQy5ObS5BKGwscCl9aWYobS5iPT1udWxs
-KUMuTm0ub0YobCwwLFAuTzgociwiLi4iLHUuTikpCmlmKGwubGVuZ3RoPT09MCYmbS5iPT1udWxsKUMu
-Tm0uQShsLCIuIikKbj1QLmRIKGwubGVuZ3RoLG5ldyBYLnFSKG0pLCEwLHUuTikKdD1tLmIKdD10IT1u
-dWxsJiZsLmxlbmd0aD4wJiZtLmEuZHModCk/bS5hLmdtSSgpOiIiCkgudDYobikuZC5iKHQpCmlmKCEh
-bi5maXhlZCRsZW5ndGgpSC5WaihQLkw0KCJpbnNlcnQiKSkKbi5zcGxpY2UoMCwwLHQpCm0uc25KKGwp
-Cm0uc1BoKG4pCnQ9bS5iCmlmKHQhPW51bGwmJm0uYT09PSQuS2soKSl7dC50b1N0cmluZwptLmI9SC55
-cyh0LCIvIiwiXFwiKX1tLklWKCl9LAp3OmZ1bmN0aW9uKGEpe3ZhciB0LHMscj10aGlzLHE9ci5iCnE9
-cSE9bnVsbD9xOiIiCmZvcih0PTA7dDxyLmQubGVuZ3RoOysrdCl7cz1yLmUKaWYodD49cy5sZW5ndGgp
-cmV0dXJuIEguT0gocyx0KQpzPXErSC5kKHNbdF0pCnE9ci5kCmlmKHQ+PXEubGVuZ3RoKXJldHVybiBI
-Lk9IKHEsdCkKcT1zK0guZChxW3RdKX1xKz1ILmQoQy5ObS5nclooci5lKSkKcmV0dXJuIHEuY2hhckNv
-ZGVBdCgwKT09MD9xOnF9LApzbko6ZnVuY3Rpb24oYSl7dGhpcy5kPXUuYS5iKGEpfSwKc1BoOmZ1bmN0
-aW9uKGEpe3RoaXMuZT11LmEuYihhKX19ClgucVIucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7cmV0
-dXJuIHRoaXMuYS5hLmdtSSgpfSwKJFM6NDZ9ClguZHYucHJvdG90eXBlPXsKdzpmdW5jdGlvbihhKXty
-ZXR1cm4iUGF0aEV4Y2VwdGlvbjogIit0aGlzLmF9fQpPLk9PLnByb3RvdHlwZT17Cnc6ZnVuY3Rpb24o
-YSl7cmV0dXJuIHRoaXMuZ29jKHRoaXMpfX0KRS5PRi5wcm90b3R5cGU9ewpVZDpmdW5jdGlvbihhKXty
-ZXR1cm4gQy54Qi50ZyhhLCIvIil9LApyNDpmdW5jdGlvbihhKXtyZXR1cm4gYT09PTQ3fSwKZHM6ZnVu
-Y3Rpb24oYSl7dmFyIHQ9YS5sZW5ndGgKcmV0dXJuIHQhPT0wJiZDLnhCLk8yKGEsdC0xKSE9PTQ3fSwK
-U3A6ZnVuY3Rpb24oYSxiKXtpZihhLmxlbmd0aCE9PTAmJkMueEIuV2QoYSwwKT09PTQ3KXJldHVybiAx
-CnJldHVybiAwfSwKWXI6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuU3AoYSwhMSl9LApoSzpmdW5jdGlv
-bihhKXtyZXR1cm4hMX0sCmdvYzpmdW5jdGlvbigpe3JldHVybiJwb3NpeCJ9LApnbUk6ZnVuY3Rpb24o
-KXtyZXR1cm4iLyJ9fQpGLnJ1LnByb3RvdHlwZT17ClVkOmZ1bmN0aW9uKGEpe3JldHVybiBDLnhCLnRn
-KGEsIi8iKX0sCnI0OmZ1bmN0aW9uKGEpe3JldHVybiBhPT09NDd9LApkczpmdW5jdGlvbihhKXt2YXIg
-dD1hLmxlbmd0aAppZih0PT09MClyZXR1cm4hMQppZihDLnhCLk8yKGEsdC0xKSE9PTQ3KXJldHVybiEw
-CnJldHVybiBDLnhCLlRjKGEsIjovLyIpJiZ0aGlzLllyKGEpPT09dH0sClNwOmZ1bmN0aW9uKGEsYil7
-dmFyIHQscyxyLHEscD1hLmxlbmd0aAppZihwPT09MClyZXR1cm4gMAppZihDLnhCLldkKGEsMCk9PT00
-NylyZXR1cm4gMQpmb3IodD0wO3Q8cDsrK3Qpe3M9Qy54Qi5XZChhLHQpCmlmKHM9PT00NylyZXR1cm4g
-MAppZihzPT09NTgpe2lmKHQ9PT0wKXJldHVybiAwCnI9Qy54Qi5YVShhLCIvIixDLnhCLlFpKGEsIi8v
-Iix0KzEpP3QrMzp0KQppZihyPD0wKXJldHVybiBwCmlmKCFifHxwPHIrMylyZXR1cm4gcgppZighQy54
-Qi5uQyhhLCJmaWxlOi8vIikpcmV0dXJuIHIKaWYoIUIuWXUoYSxyKzEpKXJldHVybiByCnE9ciszCnJl
-dHVybiBwPT09cT9xOnIrNH19cmV0dXJuIDB9LApZcjpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5TcChh
-LCExKX0sCmhLOmZ1bmN0aW9uKGEpe3JldHVybiBhLmxlbmd0aCE9PTAmJkMueEIuV2QoYSwwKT09PTQ3
-fSwKZ29jOmZ1bmN0aW9uKCl7cmV0dXJuInVybCJ9LApnbUk6ZnVuY3Rpb24oKXtyZXR1cm4iLyJ9fQpM
-LklWLnByb3RvdHlwZT17ClVkOmZ1bmN0aW9uKGEpe3JldHVybiBDLnhCLnRnKGEsIi8iKX0sCnI0OmZ1
-bmN0aW9uKGEpe3JldHVybiBhPT09NDd8fGE9PT05Mn0sCmRzOmZ1bmN0aW9uKGEpe3ZhciB0PWEubGVu
-Z3RoCmlmKHQ9PT0wKXJldHVybiExCnQ9Qy54Qi5PMihhLHQtMSkKcmV0dXJuISh0PT09NDd8fHQ9PT05
-Mil9LApTcDpmdW5jdGlvbihhLGIpe3ZhciB0LHMscj1hLmxlbmd0aAppZihyPT09MClyZXR1cm4gMAp0
-PUMueEIuV2QoYSwwKQppZih0PT09NDcpcmV0dXJuIDEKaWYodD09PTkyKXtpZihyPDJ8fEMueEIuV2Qo
-YSwxKSE9PTkyKXJldHVybiAxCnM9Qy54Qi5YVShhLCJcXCIsMikKaWYocz4wKXtzPUMueEIuWFUoYSwi
-XFwiLHMrMSkKaWYocz4wKXJldHVybiBzfXJldHVybiByfWlmKHI8MylyZXR1cm4gMAppZighQi5PUyh0
-KSlyZXR1cm4gMAppZihDLnhCLldkKGEsMSkhPT01OClyZXR1cm4gMApyPUMueEIuV2QoYSwyKQppZigh
-KHI9PT00N3x8cj09PTkyKSlyZXR1cm4gMApyZXR1cm4gM30sCllyOmZ1bmN0aW9uKGEpe3JldHVybiB0
-aGlzLlNwKGEsITEpfSwKaEs6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuWXIoYSk9PT0xfSwKT3Q6ZnVu
-Y3Rpb24oYSxiKXt2YXIgdAppZihhPT09YilyZXR1cm4hMAppZihhPT09NDcpcmV0dXJuIGI9PT05Mgpp
-ZihhPT09OTIpcmV0dXJuIGI9PT00NwppZigoYV5iKSE9PTMyKXJldHVybiExCnQ9YXwzMgpyZXR1cm4g
-dD49OTcmJnQ8PTEyMn0sCk5jOmZ1bmN0aW9uKGEsYil7dmFyIHQscyxyCmlmKGE9PWIpcmV0dXJuITAK
-dD1hLmxlbmd0aAppZih0IT09Yi5sZW5ndGgpcmV0dXJuITEKZm9yKHM9Si5yWShiKSxyPTA7cjx0Oysr
-cilpZighdGhpcy5PdChDLnhCLldkKGEscikscy5XZChiLHIpKSlyZXR1cm4hMQpyZXR1cm4hMH0sCmdv
-YzpmdW5jdGlvbigpe3JldHVybiJ3aW5kb3dzIn0sCmdtSTpmdW5jdGlvbigpe3JldHVybiJcXCJ9fTso
-ZnVuY3Rpb24gYWxpYXNlcygpe3ZhciB0PUoudkIucHJvdG90eXBlCnQuVUc9dC53CnQuU2o9dC5lNwp0
-PUouTUYucHJvdG90eXBlCnQudD10LncKdD1QLmNYLnByb3RvdHlwZQp0LkdHPXQuZXYKdD1QLmsucHJv
-dG90eXBlCnQueGI9dC53CnQ9Vy5jdi5wcm90b3R5cGUKdC5EVz10LnI2CnQ9Vy5tNi5wcm90b3R5cGUK
-dC5qRj10LkViCnQ9UC5FNC5wcm90b3R5cGUKdC5Vcj10LnEKdC5lND10Lll9KSgpOyhmdW5jdGlvbiBp
-bnN0YWxsVGVhck9mZnMoKXt2YXIgdD1odW5rSGVscGVycy5fc3RhdGljXzEscz1odW5rSGVscGVycy5f
-c3RhdGljXzAscj1odW5rSGVscGVycy5pbnN0YWxsSW5zdGFuY2VUZWFyT2ZmLHE9aHVua0hlbHBlcnMu
-aW5zdGFsbFN0YXRpY1RlYXJPZmYscD1odW5rSGVscGVycy5faW5zdGFuY2VfMXUKdChQLCJFWCIsIlpW
-IiwxMSkKdChQLCJ5dCIsInFHIiwxMSkKdChQLCJxVyIsIkJ6IiwxMSkKcyhQLCJVSSIsImVOIiwyKQpy
-KFAuUGYucHJvdG90eXBlLCJnWUoiLDAsMSxudWxsLFsiJDIiLCIkMSJdLFsidzAiLCJwbSJdLDIzLDAp
-CnQoUCwiUEgiLCJNdCIsNSkKcShXLCJwUyIsNCxudWxsLFsiJDQiXSxbIlV3Il0sMTksMCkKcShXLCJW
-NCIsNCxudWxsLFsiJDQiXSxbIm5aIl0sMTksMCkKcChQLmRNLnByb3RvdHlwZSwiZ3VNIiwiVkwiLDUp
-CnQoUCwiaUciLCJ3WSIsNCkKdChQLCJ3MCIsIkw3IiwzMikKdChMLCJIMCIsInVtIiwyMSl9KSgpOyhm
-dW5jdGlvbiBpbmhlcml0YW5jZSgpe3ZhciB0PWh1bmtIZWxwZXJzLm1peGluLHM9aHVua0hlbHBlcnMu
-aW5oZXJpdCxyPWh1bmtIZWxwZXJzLmluaGVyaXRNYW55CnMoUC5rLG51bGwpCnIoUC5rLFtILmVvLEou
-dkIsSi5tMSxQLm5ZLFAuY1gsSC5hNyxQLkFuLEguU1UsSC5SZSxILnd2LFAuUG4sSC5XVSxILkxJLEgu
-VHAsSC5mOSxQLlhTLEguYnEsSC5YTyxQLllrLEgudmgsSC5ONixILlZSLEguRUssSC5QYixILnRRLEgu
-U2QsSC5KYyxILkcsUC5XMyxQLmloLFAuRnksUC5HVixQLmI4LFAuUGYsUC5GZSxQLnZzLFAuT00sUC5x
-aCxQLk1PLFAua1QsUC54SSxQLkN3LFAubTAsUC5YdixQLmJuLFAubG0sUC5sRCxQLktQLFAubGYsUC5X
-WSxQLlVrLFAuUncsUC5ieixQLmEyLFAuaVAsUC5GSyxQLms1LFAuS1ksUC5DRCxQLmFFLFAuRUgsUC56
-TSxQLlowLFAuTjMsUC5jOCxQLk9kLFAuaWIsUC5HeixQLnFVLFAuUm4sUC5HRCxQLkRuLFAuUEUsUC5V
-ZixXLmlkLFcuRmssVy5KUSxXLkdtLFcudkQsVy5tNixXLk93LFcuVzksVy5kVyxXLkZiLFcua0YsVy5t
-ayxXLktvLFAuaTYsUC5hSixQLkU0LFAuSU4sUC5uNixVLmQyLFUuU2UsVS5NbCxVLnlELFUud2IsQi5q
-OCxCLnFwLFQubVEsTC5YQSxMLlpaLEwuQmMsTS5sSSxPLk9PLFguV0QsWC5kdl0pCnIoSi52QixbSi55
-RSxKLllFLEouTUYsSi5qZCxKLnFJLEouRHIsSC5XWixILkVULFcuRDAsVy5ZZSxXLkF6LFcuUFUsVy5C
-dyxXLm80LFcubHcsVy5MZSxXLlNiLFcuTmgsVy5KVSxXLklCLFcudmUsVy5uNyxXLlFJLFcuZWEsVy50
-SSxXLkdPLFcuSkMsVy5icixXLlo3LFcuU2csVy51OCxXLno2LFcubEcsVy5xcyxXLkFXLFcuY3MsVy5L
-NyxXLmNsLFcuZlQsVy5iZyxXLlk0LFcuYUQsVy5sOCxXLk9YLFcuV1csVy5VaixXLm16LFcuYTMsVy50
-cixXLmNuLFcuRmosVy5PdixXLllELFcuWFcsVy5YVSxXLnp2LFAuVzIsUC5oRixQLkJWLFAudWosUC54
-MCxQLmZVLFAudVAsUC5qRyxQLkVELFAueFcsUC56WSxQLndqLFAucjIsUC5yTyxQLlUzLFAubW9dKQpy
-KEouTUYsW0ouaUMsSi5rZCxKLmM1XSkKcyhKLlBvLEouamQpCnIoSi5xSSxbSi51cixKLlZBXSkKcyhQ
-LkxVLFAublkpCnIoUC5MVSxbSC5YQyxXLnd6LFcuZTddKQpzKEgucWosSC5YQykKcihQLmNYLFtILmJR
-LEguaTEsSC5VNSxILlhSLFAubVcsSC51bl0pCnIoSC5iUSxbSC5hTCxILmk1LFAueHVdKQpyKEguYUws
-W0gubkgsSC5BOCxQLmk4XSkKcyhILnh5LEguaTEpCnIoUC5BbixbSC5NSCxILlNPXSkKcyhQLlJVLFAu
-UG4pCnMoUC5HaixQLlJVKQpzKEguUEQsUC5HaikKcyhILkxQLEguV1UpCnIoSC5UcCxbSC5DaixILkFt
-LEgubGMsSC5kQyxILndOLEguVlgsUC50aCxQLmhhLFAuVnMsUC5GdCxQLnlILFAuV00sUC5TWCxQLkdz
-LFAuZGEsUC5vUSxQLnBWLFAuVTcsUC52cixQLnJILFAuS0YsUC5aTCxQLlJULFAualosUC5ycSxQLlJX
-LFAuQjUsUC5QSSxQLnBLLFAuaGosUC5WcCxQLk9SLFAucmEsUC55USxQLldGLFAubjEsUC5jUyxQLlZD
-LFAuSlQsUC5lMSxQLk5ZLFAuUlosUC5NRSxQLnk1LFAucTMsUC55SSxQLmM2LFAucWQsVy5DdixXLmJV
-LFcuaEgsVy5GQSxXLnVxLFcuaWksVy53USxXLktTLFcuQTMsVy52TixXLlV2LFcuRWcsVy5FbyxXLldr
-LFcuSUEsVy5mbSxQLmxSLFAuamcsUC5LNSxQLkdFLFAuTjcsUC51USxQLlBDLFAubXQsUC5OeixQLm5w
-LFAuVXQsUC52SyxQLnBVLFAucWYsTC5lLEwuVlcsTC5vWixMLmpyLEwucWwsTC55OCxMLkwsTC5XeCxM
-LkFPLEwuZE4sTC5IbyxMLnh6LEwuSUMsTC5MMSxMLm5ULEwuQlosTC5HSCxMLkRULEwuZUgsTC55dSxM
-LnpELEwuVFcsTC54cixMLkVFLEwuUUwsTC5WUyxMLlRELE0uTWksTS5xNyxNLk5vLFgucVJdKQpyKFAu
-WFMsW0guVzAsSC5heixILnZWLEguRXEsUC5DNixILnU5LFAubixQLnUsUC5tcCxQLnViLFAuZHMsUC5s
-aixQLlVWLFAuY10pCnIoSC5sYyxbSC56eCxILnJUXSkKcyhILmtZLFAuQzYpCnMoUC5pbCxQLllrKQpy
-KFAuaWwsW0guTjUsUC51dyxXLmFULFcuU3ldKQpyKFAubVcsW0guS1csUC5xNF0pCnIoSC5FVCxbSC5k
-ZixILmIwXSkKcihILmIwLFtILlJHLEguV0JdKQpzKEguVlAsSC5SRykKcyhILkRnLEguVlApCnMoSC5a
-RyxILldCKQpzKEguUGcsSC5aRykKcihILlBnLFtILnhqLEguZEUsSC5aQSxILndmLEguUHEsSC5lRSxI
-LlY2XSkKcihILnU5LFtILmh6LEguaU1dKQpzKFAuWmYsUC5QZikKcyhQLkppLFAubTApCnMoUC5iNixQ
-Llh2KQpzKFAuUkssUC5XWSkKcihQLlVrLFtQLkNWLFAuWmksUC5ieV0pCnMoUC53SSxQLmtUKQpyKFAu
-d0ksW1AudkEsUC5NeCxQLkUzLFAuR1ldKQpzKFAudTUsUC5aaSkKcihQLkZLLFtQLkNQLFAuS05dKQpy
-KFAudSxbUC5iSixQLmVZXSkKcyhQLnFlLFAuRG4pCnIoVy5EMCxbVy51SCxXLndKLFcud2EsVy5sSyxX
-LkxyLFcuU1YsVy5vSCxXLkExLFcuTU4sVy5RVixXLnZGLFcuT2ksVy5DbSxQLmZvLFAuVjhdKQpyKFcu
-dUgsW1cuY3YsVy5ueCxXLlFGLFcuQ1FdKQpyKFcuY3YsW1cucUUsUC5kNV0pCnIoVy5xRSxbVy5HaCxX
-LmZZLFcubkIsVy5RUCxXLklGLFcuY3gsVy5oNCxXLkpLLFcud1AsVy5RYixXLlFsLFcuR1gsVy5TTixX
-LkhELFcuS1IsVy5scCxXLlRiLFcuSXYsVy5CVCxXLmZYLFcuRkJdKQpyKFcuQncsW1cuUmQsVy5rUixX
-LkhTLFcuRmhdKQpzKFcuVGYsVy5vNCkKcyhXLm9KLFcuTGUpCnMoVy5WbyxXLmtSKQpzKFcueFgsVy5K
-VSkKcyhXLkZ2LFcueFgpCnMoVy5iRyxXLnZlKQpzKFcuWWwsVy5iRykKcyhXLlQ1LFcuQXopCnMoVy5m
-ZyxXLnRJKQpzKFcuWFYsVy5mZykKcyhXLkhXLFcuWjcpCnMoVy54bixXLkhXKQpzKFcuVmIsVy5RRikK
-cyhXLk83LFcud2EpCnIoVy5lYSxbVy53NixXLmV3LFcuYmtdKQpyKFcudzYsW1cuSEwsVy5Bal0pCnMo
-Vy5TMCxXLmxHKQpzKFcuejIsVy5xcykKcyhXLktCLFcuY3MpCnMoVy5ETSxXLktCKQpzKFcuckIsVy5L
-NykKcyhXLkJILFcuckIpCnMoVy5mNyxXLmZUKQpzKFcuRXYsVy5mNykKcyhXLnA4LFcuYmcpCnMoVy5D
-RSxXLm9IKQpzKFcuTWssVy5DRSkKcyhXLlp4LFcuYUQpCnMoVy5ObixXLlp4KQpzKFcuQXMsVy5PWCkK
-cyhXLmpNLFcuVWopCnMoVy5YMCxXLmpNKQpzKFcuQXcsVy5RVikKcyhXLm5KLFcuQXcpCnMoVy5PMyxX
-LnRyKQpzKFcuY2ksVy5PMykKcyhXLmNPLFcuT3YpCnMoVy5QUixXLmNPKQpzKFcudzQsVy5JQikKcyhX
-LkR4LFcuWUQpCnMoVy5GMixXLkR4KQpzKFcub2EsVy5YVykKcyhXLnJoLFcub2EpCnMoVy5SeSxXLlhV
-KQpzKFcuTE8sVy5SeSkKcyhXLm56LFcuenYpCnMoVy5iMSxXLm56KQpzKFcuaTcsVy5hVCkKcyhQLmRN
-LFAuUkspCnIoUC5kTSxbVy5JNCxQLktlXSkKcyhXLlJPLFAucWgpCnMoVy5ldSxXLlJPKQpzKFcueEMs
-UC5NTykKcyhXLmN0LFcubTYpCnMoUC5CZixQLmk2KQpzKFAuemcsUC5hSikKcyhQLmUzLFAuVzIpCnIo
-UC5FNCxbUC5yNyxQLmNvXSkKcyhQLlR6LFAuY28pCnMoUC50bixQLklOKQpzKFAuR0MsUC5mVSkKcyhQ
-LnE2LFAuR0MpCnMoUC5qUyxQLmpHKQpzKFAuZnosUC5qUykKcyhQLm5kLFAuZDUpCnMoUC5kUyxQLnhX
-KQpzKFAuS3EsUC5kUykKcyhQLk1ZLFAud2opCnMoUC5OQyxQLk1ZKQpzKFAuejgsUC5VMykKcyhQLkdu
-LFAuVjgpCnMoUC5LZyxQLm1vKQpzKFAuRm4sUC5LZykKcyhCLkx1LE8uT08pCnIoQi5MdSxbRS5PRixG
-LnJ1LEwuSVZdKQp0KEguWEMsSC5SZSkKdChILlJHLFAubEQpCnQoSC5WUCxILlNVKQp0KEguV0IsUC5s
-RCkKdChILlpHLEguU1UpCnQoUC5uWSxQLmxEKQp0KFAuV1ksUC5sZikKdChQLlJVLFAuS1ApCnQoVy5M
-ZSxXLmlkKQp0KFcuSlUsUC5sRCkKdChXLnhYLFcuR20pCnQoVy52ZSxQLmxEKQp0KFcuYkcsVy5HbSkK
-dChXLnRJLFAubEQpCnQoVy5mZyxXLkdtKQp0KFcuWjcsUC5sRCkKdChXLkhXLFcuR20pCnQoVy5sRyxQ
-LllrKQp0KFcucXMsUC5ZaykKdChXLmNzLFAubEQpCnQoVy5LQixXLkdtKQp0KFcuSzcsUC5sRCkKdChX
-LnJCLFcuR20pCnQoVy5mVCxQLmxEKQp0KFcuZjcsVy5HbSkKdChXLmJnLFAuWWspCnQoVy5vSCxQLmxE
-KQp0KFcuQ0UsVy5HbSkKdChXLmFELFAubEQpCnQoVy5aeCxXLkdtKQp0KFcuT1gsUC5ZaykKdChXLlVq
-LFAubEQpCnQoVy5qTSxXLkdtKQp0KFcuUVYsUC5sRCkKdChXLkF3LFcuR20pCnQoVy50cixQLmxEKQp0
-KFcuTzMsVy5HbSkKdChXLk92LFAubEQpCnQoVy5jTyxXLkdtKQp0KFcuWUQsUC5sRCkKdChXLkR4LFcu
-R20pCnQoVy5YVyxQLmxEKQp0KFcub2EsVy5HbSkKdChXLlhVLFAubEQpCnQoVy5SeSxXLkdtKQp0KFcu
-enYsUC5sRCkKdChXLm56LFcuR20pCnQoUC5jbyxQLmxEKQp0KFAuZlUsUC5sRCkKdChQLkdDLFcuR20p
-CnQoUC5qRyxQLmxEKQp0KFAualMsVy5HbSkKdChQLnhXLFAubEQpCnQoUC5kUyxXLkdtKQp0KFAud2os
-UC5sRCkKdChQLk1ZLFcuR20pCnQoUC5VMyxQLllrKQp0KFAubW8sUC5sRCkKdChQLktnLFcuR20pfSko
-KQp2YXIgdj17dHlwZVVuaXZlcnNlOntlQzpuZXcgTWFwKCksdFI6e30sZVQ6e30sdFBWOnt9LHNFQTpb
-XX0sbWFuZ2xlZEdsb2JhbE5hbWVzOntLTjoiaW50IixDUDoiZG91YmxlIixGSzoibnVtIixxVToiU3Ry
-aW5nIixhMjoiYm9vbCIsYzg6Ik51bGwiLHpNOiJMaXN0In0sbWFuZ2xlZE5hbWVzOnt9LGdldFR5cGVG
-cm9tTmFtZTpnZXRHbG9iYWxGcm9tTmFtZSxtZXRhZGF0YTpbXSx0eXBlczpbImM4KCkiLCJjOChALEAp
-IiwifigpIiwiYzgoY3YpIiwiQChAKSIsInFVKHFVKSIsImM4KEFqKSIsImM4KE83KSIsIn4ocVUsQCki
-LCJhMihxVSkiLCJ+KEApIiwifih+KCkpIiwiYzgocVUscVUpIiwiYzgocVUsQCkiLCJ+KHh1PHFVPiki
-LCJjOChxVSkiLCJ+KHFVLHFVKSIsImEyKGtGKSIsImM4KEApIiwiYTIoY3YscVUscVUsSlEpIiwiYzgo
-ZWEpIiwifihBaikiLCJuNihLTikiLCJ+KGtbR3pdKSIsIlowPHFVLHFVPihaMDxxVSxxVT4scVUpIiwi
-YTIodUgpIiwiYzgoQFtHel0pIiwiYzgoZXcpIiwiQChxVSkiLCJAKGVhKSIsInZzPEA+KEApIiwifihx
-VVtAXSkiLCJrKEApIiwiQChALEApIiwiYTIoeHU8cVU+KSIsIktOKEtOLEtOKSIsInI3KEApIiwiVHo8
-QD4oQCkiLCJFNChAKSIsImM4KH4oKSkiLCJjOChALEd6KSIsIn4odUgsdUgpIiwiYjg8Yzg+KEFqKSIs
-ImM4KEtOLEApIiwiTzcoTzcpIiwiQChALHFVKSIsInFVKEtOKSIsImM4KEdELEApIiwifihxVSxLTiki
-LCJuNihALEApIl0saW50ZXJjZXB0b3JzQnlUYWc6bnVsbCxsZWFmVGFnczpudWxsfQpILnhiKHYudHlw
-ZVVuaXZlcnNlLEpTT04ucGFyc2UoJ3siYzUiOiJNRiIsImlDIjoiTUYiLCJrZCI6Ik1GIiwicngiOiJl
-YSIsImU1IjoiZWEiLCJEWCI6IlY4IiwiYzAiOiJEMCIsImZ5IjoiRDAiLCJjZyI6IkQwIiwiWTAiOiJk
-NSIsInRwIjoiZDUiLCJ2MCI6ImV3IiwiTXIiOiJxRSIsImVMIjoicUUiLCJJMCI6InVIIiwiaHMiOiJ1
-SCIsIlhnIjoiUUYiLCJ5YyI6IkFqIiwiajYiOiJNTiIsInk0IjoidzYiLCJhUCI6IkNtIiwieGMiOiJu
-eCIsImtKIjoibngiLCJqNyI6IndhIiwiUUgiOiJ4biIsIncxIjoiUUkiLCJINiI6Imx3IiwiSEUiOiJX
-VyIsInpVIjoiRGciLCJ5RSI6eyJhMiI6W119LCJZRSI6eyJjOCI6W119LCJNRiI6eyJ2bSI6W10sIkVI
-IjpbXX0sImpkIjp7InpNIjpbIjEiXSwiYlEiOlsiMSJdLCJjWCI6WyIxIl19LCJQbyI6eyJqZCI6WyIx
-Il0sInpNIjpbIjEiXSwiYlEiOlsiMSJdLCJjWCI6WyIxIl19LCJtMSI6eyJBbiI6WyIxIl19LCJxSSI6
-eyJDUCI6W10sIkZLIjpbXX0sInVyIjp7IktOIjpbXSwiQ1AiOltdLCJGSyI6W119LCJWQSI6eyJDUCI6
-W10sIkZLIjpbXX0sIkRyIjp7InFVIjpbXSwidlgiOltdfSwicWoiOnsiUmUiOlsiS04iXSwibEQiOlsi
-S04iXSwiek0iOlsiS04iXSwiYlEiOlsiS04iXSwiY1giOlsiS04iXSwibEQuRSI6IktOIiwiUmUuRSI6
-IktOIn0sImJRIjp7ImNYIjpbIjEiXX0sImFMIjp7ImJRIjpbIjEiXSwiY1giOlsiMSJdfSwibkgiOnsi
-YUwiOlsiMSJdLCJiUSI6WyIxIl0sImNYIjpbIjEiXSwiYUwuRSI6IjEiLCJjWC5FIjoiMSJ9LCJhNyI6
-eyJBbiI6WyIxIl19LCJpMSI6eyJjWCI6WyIyIl0sImNYLkUiOiIyIn0sInh5Ijp7ImkxIjpbIjEiLCIy
-Il0sImJRIjpbIjIiXSwiY1giOlsiMiJdLCJjWC5FIjoiMiJ9LCJNSCI6eyJBbiI6WyIyIl19LCJBOCI6
-eyJhTCI6WyIyIl0sImJRIjpbIjIiXSwiY1giOlsiMiJdLCJhTC5FIjoiMiIsImNYLkUiOiIyIn0sIlU1
-Ijp7ImNYIjpbIjEiXSwiY1guRSI6IjEifSwiU08iOnsiQW4iOlsiMSJdfSwiWEMiOnsiUmUiOlsiMSJd
-LCJsRCI6WyIxIl0sInpNIjpbIjEiXSwiYlEiOlsiMSJdLCJjWCI6WyIxIl19LCJ3diI6eyJHRCI6W119
-LCJQRCI6eyJHaiI6WyIxIiwiMiJdLCJSVSI6WyIxIiwiMiJdLCJQbiI6WyIxIiwiMiJdLCJLUCI6WyIx
-IiwiMiJdLCJaMCI6WyIxIiwiMiJdfSwiV1UiOnsiWjAiOlsiMSIsIjIiXX0sIkxQIjp7IldVIjpbIjEi
-LCIyIl0sIlowIjpbIjEiLCIyIl19LCJYUiI6eyJjWCI6WyIxIl0sImNYLkUiOiIxIn0sIkxJIjp7InZR
-IjpbXX0sIlcwIjp7IlhTIjpbXX0sImF6Ijp7IlhTIjpbXX0sInZWIjp7IlhTIjpbXX0sIlhPIjp7Ikd6
-IjpbXX0sIlRwIjp7IkVIIjpbXX0sImxjIjp7IkVIIjpbXX0sInp4Ijp7IkVIIjpbXX0sInJUIjp7IkVI
-IjpbXX0sIkVxIjp7IlhTIjpbXX0sImtZIjp7IlhTIjpbXX0sIk41Ijp7IkZvIjpbIjEiLCIyIl0sIllr
-IjpbIjEiLCIyIl0sIlowIjpbIjEiLCIyIl0sIllrLksiOiIxIiwiWWsuViI6IjIifSwiaTUiOnsiYlEi
-OlsiMSJdLCJjWCI6WyIxIl0sImNYLkUiOiIxIn0sIk42Ijp7IkFuIjpbIjEiXX0sIlZSIjp7IndMIjpb
-XSwidlgiOltdfSwiRUsiOnsiaWIiOltdLCJPZCI6W119LCJLVyI6eyJjWCI6WyJpYiJdLCJjWC5FIjoi
-aWIifSwiUGIiOnsiQW4iOlsiaWIiXX0sInRRIjp7Ik9kIjpbXX0sInVuIjp7ImNYIjpbIk9kIl0sImNY
-LkUiOiJPZCJ9LCJTZCI6eyJBbiI6WyJPZCJdfSwiRVQiOnsiQVMiOltdfSwiZGYiOnsiRVQiOltdLCJX
-eSI6W10sIkFTIjpbXX0sImIwIjp7IlhqIjpbIkAiXSwiRVQiOltdLCJBUyI6W119LCJEZyI6eyJsRCI6
-WyJDUCJdLCJYaiI6WyJAIl0sInpNIjpbIkNQIl0sIkVUIjpbXSwiYlEiOlsiQ1AiXSwiU1UiOlsiQ1Ai
-XSwiQVMiOltdLCJjWCI6WyJDUCJdLCJsRC5FIjoiQ1AifSwiUGciOnsibEQiOlsiS04iXSwiek0iOlsi
-S04iXSwiWGoiOlsiQCJdLCJFVCI6W10sImJRIjpbIktOIl0sIlNVIjpbIktOIl0sIkFTIjpbXSwiY1gi
-OlsiS04iXX0sInhqIjp7ImxEIjpbIktOIl0sInpNIjpbIktOIl0sIlhqIjpbIkAiXSwiRVQiOltdLCJi
-USI6WyJLTiJdLCJTVSI6WyJLTiJdLCJBUyI6W10sImNYIjpbIktOIl0sImxELkUiOiJLTiJ9LCJkRSI6
-eyJsRCI6WyJLTiJdLCJ6TSI6WyJLTiJdLCJYaiI6WyJAIl0sIkVUIjpbXSwiYlEiOlsiS04iXSwiU1Ui
-OlsiS04iXSwiQVMiOltdLCJjWCI6WyJLTiJdLCJsRC5FIjoiS04ifSwiWkEiOnsibEQiOlsiS04iXSwi
-ek0iOlsiS04iXSwiWGoiOlsiQCJdLCJFVCI6W10sImJRIjpbIktOIl0sIlNVIjpbIktOIl0sIkFTIjpb
-XSwiY1giOlsiS04iXSwibEQuRSI6IktOIn0sIndmIjp7ImxEIjpbIktOIl0sInpNIjpbIktOIl0sIlhq
-IjpbIkAiXSwiRVQiOltdLCJiUSI6WyJLTiJdLCJTVSI6WyJLTiJdLCJBUyI6W10sImNYIjpbIktOIl0s
-ImxELkUiOiJLTiJ9LCJQcSI6eyJsRCI6WyJLTiJdLCJ6TSI6WyJLTiJdLCJYaiI6WyJAIl0sIkVUIjpb
-XSwiYlEiOlsiS04iXSwiU1UiOlsiS04iXSwiQVMiOltdLCJjWCI6WyJLTiJdLCJsRC5FIjoiS04ifSwi
-ZUUiOnsibEQiOlsiS04iXSwiek0iOlsiS04iXSwiWGoiOlsiQCJdLCJFVCI6W10sImJRIjpbIktOIl0s
-IlNVIjpbIktOIl0sIkFTIjpbXSwiY1giOlsiS04iXSwibEQuRSI6IktOIn0sIlY2Ijp7Im42IjpbXSwi
-bEQiOlsiS04iXSwiek0iOlsiS04iXSwiWGoiOlsiQCJdLCJFVCI6W10sImJRIjpbIktOIl0sIlNVIjpb
-IktOIl0sIkFTIjpbXSwiY1giOlsiS04iXSwibEQuRSI6IktOIn0sInU5Ijp7IlhTIjpbXX0sImh6Ijp7
-IlhTIjpbXX0sImlNIjp7IlhTIjpbXX0sIkdWIjp7IkFuIjpbIjEiXX0sInE0Ijp7ImNYIjpbIjEiXSwi
-Y1guRSI6IjEifSwiWmYiOnsiUGYiOlsiMSJdfSwidnMiOnsiYjgiOlsiMSJdfSwiQ3ciOnsiWFMiOltd
-fSwibTAiOnsiSkIiOltdfSwiSmkiOnsiSkIiOltdfSwiYjYiOnsiWHYiOlsiMSJdLCJ4dSI6WyIxIl0s
-ImJRIjpbIjEiXSwiY1giOlsiMSJdfSwibG0iOnsiQW4iOlsiMSJdfSwibVciOnsiY1giOlsiMSJdfSwi
-TFUiOnsibEQiOlsiMSJdLCJ6TSI6WyIxIl0sImJRIjpbIjEiXSwiY1giOlsiMSJdfSwiaWwiOnsiWWsi
-OlsiMSIsIjIiXSwiWjAiOlsiMSIsIjIiXX0sIllrIjp7IlowIjpbIjEiLCIyIl19LCJQbiI6eyJaMCI6
-WyIxIiwiMiJdfSwiR2oiOnsiUlUiOlsiMSIsIjIiXSwiUG4iOlsiMSIsIjIiXSwiS1AiOlsiMSIsIjIi
-XSwiWjAiOlsiMSIsIjIiXX0sIlJLIjp7ImxmIjpbIjEiXSwieHUiOlsiMSJdLCJiUSI6WyIxIl0sImNY
-IjpbIjEiXX0sIlh2Ijp7Inh1IjpbIjEiXSwiYlEiOlsiMSJdLCJjWCI6WyIxIl19LCJ1dyI6eyJZayI6
-WyJxVSIsIkAiXSwiWjAiOlsicVUiLCJAIl0sIllrLksiOiJxVSIsIllrLlYiOiJAIn0sImk4Ijp7ImFM
-IjpbInFVIl0sImJRIjpbInFVIl0sImNYIjpbInFVIl0sImFMLkUiOiJxVSIsImNYLkUiOiJxVSJ9LCJD
-ViI6eyJVayI6WyJ6TTxLTj4iLCJxVSJdLCJVay5TIjoiek08S04+In0sInZBIjp7IndJIjpbInpNPEtO
-PiIsInFVIl19LCJaaSI6eyJVayI6WyJxVSIsInpNPEtOPiJdfSwiYnkiOnsiVWsiOlsiayIsInFVIl0s
-IlVrLlMiOiJrIn0sIk14Ijp7IndJIjpbInFVIiwiayJdfSwidTUiOnsiVWsiOlsicVUiLCJ6TTxLTj4i
-XSwiVWsuUyI6InFVIn0sIkUzIjp7IndJIjpbInFVIiwiek08S04+Il19LCJHWSI6eyJ3SSI6WyJ6TTxL
-Tj4iLCJxVSJdfSwiQ1AiOnsiRksiOltdfSwiQzYiOnsiWFMiOltdfSwibiI6eyJYUyI6W119LCJ1Ijp7
-IlhTIjpbXX0sImJKIjp7IlhTIjpbXX0sImVZIjp7IlhTIjpbXX0sIm1wIjp7IlhTIjpbXX0sInViIjp7
-IlhTIjpbXX0sImRzIjp7IlhTIjpbXX0sImxqIjp7IlhTIjpbXX0sIlVWIjp7IlhTIjpbXX0sIms1Ijp7
-IlhTIjpbXX0sIktZIjp7IlhTIjpbXX0sImMiOnsiWFMiOltdfSwiS04iOnsiRksiOltdfSwiek0iOnsi
-YlEiOlsiMSJdLCJjWCI6WyIxIl19LCJpYiI6eyJPZCI6W119LCJ4dSI6eyJiUSI6WyIxIl0sImNYIjpb
-IjEiXX0sInFVIjp7InZYIjpbXX0sIlJuIjp7IkJMIjpbXX0sIkRuIjp7ImlEIjpbXX0sIlVmIjp7ImlE
-IjpbXX0sInFlIjp7ImlEIjpbXX0sInFFIjp7ImN2IjpbXSwidUgiOltdLCJEMCI6W119LCJHaCI6eyJj
-diI6W10sInVIIjpbXSwiRDAiOltdfSwiZlkiOnsiY3YiOltdLCJ1SCI6W10sIkQwIjpbXX0sIm5CIjp7
-ImN2IjpbXSwidUgiOltdLCJEMCI6W119LCJRUCI6eyJjdiI6W10sInVIIjpbXSwiRDAiOltdfSwiSUYi
-OnsiY3YiOltdLCJ1SCI6W10sIkQwIjpbXX0sIm54Ijp7InVIIjpbXSwiRDAiOltdfSwiVm8iOnsia1Ii
-OltdfSwiY3giOnsiY3YiOltdLCJ1SCI6W10sIkQwIjpbXX0sIlFGIjp7InVIIjpbXSwiRDAiOltdfSwi
-RnYiOnsiR20iOlsidG48Rks+Il0sImxEIjpbInRuPEZLPiJdLCJYaiI6WyJ0bjxGSz4iXSwiek0iOlsi
-dG48Rks+Il0sImJRIjpbInRuPEZLPiJdLCJjWCI6WyJ0bjxGSz4iXSwiR20uRSI6InRuPEZLPiIsImxE
-LkUiOiJ0bjxGSz4ifSwiSUIiOnsidG4iOlsiRksiXX0sIllsIjp7IkdtIjpbInFVIl0sImxEIjpbInFV
-Il0sInpNIjpbInFVIl0sIlhqIjpbInFVIl0sImJRIjpbInFVIl0sImNYIjpbInFVIl0sIkdtLkUiOiJx
-VSIsImxELkUiOiJxVSJ9LCJ3eiI6eyJsRCI6WyIxIl0sInpNIjpbIjEiXSwiYlEiOlsiMSJdLCJjWCI6
-WyIxIl0sImxELkUiOiIxIn0sImN2Ijp7InVIIjpbXSwiRDAiOltdfSwiVDUiOnsiQXoiOltdfSwiWFYi
-OnsiR20iOlsiVDUiXSwibEQiOlsiVDUiXSwiWGoiOlsiVDUiXSwiek0iOlsiVDUiXSwiYlEiOlsiVDUi
-XSwiY1giOlsiVDUiXSwiR20uRSI6IlQ1IiwibEQuRSI6IlQ1In0sIndKIjp7IkQwIjpbXX0sImg0Ijp7
-ImN2IjpbXSwidUgiOltdLCJEMCI6W119LCJ4biI6eyJHbSI6WyJ1SCJdLCJsRCI6WyJ1SCJdLCJ6TSI6
-WyJ1SCJdLCJYaiI6WyJ1SCJdLCJiUSI6WyJ1SCJdLCJjWCI6WyJ1SCJdLCJHbS5FIjoidUgiLCJsRC5F
-IjoidUgifSwiVmIiOnsidUgiOltdLCJEMCI6W119LCJPNyI6eyJEMCI6W119LCJ3YSI6eyJEMCI6W119
-LCJKSyI6eyJjdiI6W10sInVIIjpbXSwiRDAiOltdfSwiSEwiOnsiZWEiOltdfSwid1AiOnsiY3YiOltd
-LCJ1SCI6W10sIkQwIjpbXX0sImxLIjp7IkQwIjpbXX0sIlFiIjp7ImN2IjpbXSwidUgiOltdLCJEMCI6
-W119LCJTMCI6eyJZayI6WyJxVSIsIkAiXSwiWjAiOlsicVUiLCJAIl0sIllrLksiOiJxVSIsIllrLlYi
-OiJAIn0sInoyIjp7IllrIjpbInFVIiwiQCJdLCJaMCI6WyJxVSIsIkAiXSwiWWsuSyI6InFVIiwiWWsu
-ViI6IkAifSwiRE0iOnsiR20iOlsiQVciXSwibEQiOlsiQVciXSwiWGoiOlsiQVciXSwiek0iOlsiQVci
-XSwiYlEiOlsiQVciXSwiY1giOlsiQVciXSwiR20uRSI6IkFXIiwibEQuRSI6IkFXIn0sIkFqIjp7ImVh
-IjpbXX0sImU3Ijp7ImxEIjpbInVIIl0sInpNIjpbInVIIl0sImJRIjpbInVIIl0sImNYIjpbInVIIl0s
-ImxELkUiOiJ1SCJ9LCJ1SCI6eyJEMCI6W119LCJCSCI6eyJHbSI6WyJ1SCJdLCJsRCI6WyJ1SCJdLCJ6
-TSI6WyJ1SCJdLCJYaiI6WyJ1SCJdLCJiUSI6WyJ1SCJdLCJjWCI6WyJ1SCJdLCJHbS5FIjoidUgiLCJs
-RC5FIjoidUgifSwiUWwiOnsiY3YiOltdLCJ1SCI6W10sIkQwIjpbXX0sIkdYIjp7ImN2IjpbXSwidUgi
-OltdLCJEMCI6W119LCJTTiI6eyJjdiI6W10sInVIIjpbXSwiRDAiOltdfSwiSEQiOnsiY3YiOltdLCJ1
-SCI6W10sIkQwIjpbXX0sIkV2Ijp7IkdtIjpbImNsIl0sImxEIjpbImNsIl0sInpNIjpbImNsIl0sIlhq
-IjpbImNsIl0sImJRIjpbImNsIl0sImNYIjpbImNsIl0sIkdtLkUiOiJjbCIsImxELkUiOiJjbCJ9LCJM
-ciI6eyJEMCI6W119LCJLUiI6eyJjdiI6W10sInVIIjpbXSwiRDAiOltdfSwiZXciOnsiZWEiOltdfSwi
-cDgiOnsiWWsiOlsicVUiLCJAIl0sIlowIjpbInFVIiwiQCJdLCJZay5LIjoicVUiLCJZay5WIjoiQCJ9
-LCJscCI6eyJjdiI6W10sInVIIjpbXSwiRDAiOltdfSwiU1YiOnsiRDAiOltdfSwiTWsiOnsiR20iOlsi
-U1YiXSwibEQiOlsiU1YiXSwiek0iOlsiU1YiXSwiWGoiOlsiU1YiXSwiRDAiOltdLCJiUSI6WyJTViJd
-LCJjWCI6WyJTViJdLCJHbS5FIjoiU1YiLCJsRC5FIjoiU1YifSwiTm4iOnsiR20iOlsiWTQiXSwibEQi
-OlsiWTQiXSwiek0iOlsiWTQiXSwiWGoiOlsiWTQiXSwiYlEiOlsiWTQiXSwiY1giOlsiWTQiXSwiR20u
-RSI6Ilk0IiwibEQuRSI6Ilk0In0sIkFzIjp7IllrIjpbInFVIiwicVUiXSwiWjAiOlsicVUiLCJxVSJd
-LCJZay5LIjoicVUiLCJZay5WIjoicVUifSwiYmsiOnsiZWEiOltdfSwiVGIiOnsiY3YiOltdLCJ1SCI6
-W10sIkQwIjpbXX0sIkl2Ijp7ImN2IjpbXSwidUgiOltdLCJEMCI6W119LCJCVCI6eyJjdiI6W10sInVI
-IjpbXSwiRDAiOltdfSwiZlgiOnsiY3YiOltdLCJ1SCI6W10sIkQwIjpbXX0sIkZCIjp7ImN2IjpbXSwi
-dUgiOltdLCJEMCI6W119LCJBMSI6eyJEMCI6W119LCJNTiI6eyJEMCI6W119LCJYMCI6eyJHbSI6WyJN
-TiJdLCJsRCI6WyJNTiJdLCJYaiI6WyJNTiJdLCJ6TSI6WyJNTiJdLCJiUSI6WyJNTiJdLCJjWCI6WyJN
-TiJdLCJHbS5FIjoiTU4iLCJsRC5FIjoiTU4ifSwibkoiOnsiR20iOlsiQTEiXSwibEQiOlsiQTEiXSwi
-WGoiOlsiQTEiXSwiek0iOlsiQTEiXSwiRDAiOltdLCJiUSI6WyJBMSJdLCJjWCI6WyJBMSJdLCJHbS5F
-IjoiQTEiLCJsRC5FIjoiQTEifSwiY2kiOnsiR20iOlsiYTMiXSwibEQiOlsiYTMiXSwiek0iOlsiYTMi
-XSwiWGoiOlsiYTMiXSwiYlEiOlsiYTMiXSwiY1giOlsiYTMiXSwiR20uRSI6ImEzIiwibEQuRSI6ImEz
-In0sInc2Ijp7ImVhIjpbXX0sInZGIjp7IkQwIjpbXX0sIk9pIjp7InY2IjpbXSwiRDAiOltdfSwiQ20i
-OnsiRDAiOltdfSwiQ1EiOnsidUgiOltdLCJEMCI6W119LCJQUiI6eyJHbSI6WyJsdyJdLCJsRCI6WyJs
-dyJdLCJ6TSI6WyJsdyJdLCJYaiI6WyJsdyJdLCJiUSI6WyJsdyJdLCJjWCI6WyJsdyJdLCJHbS5FIjoi
-bHciLCJsRC5FIjoibHcifSwidzQiOnsidG4iOlsiRksiXX0sIkYyIjp7IkdtIjpbIkdPIl0sImxEIjpb
-IkdPIl0sIlhqIjpbIkdPIl0sInpNIjpbIkdPIl0sImJRIjpbIkdPIl0sImNYIjpbIkdPIl0sIkdtLkUi
-OiJHTyIsImxELkUiOiJHTyJ9LCJyaCI6eyJHbSI6WyJ1SCJdLCJsRCI6WyJ1SCJdLCJ6TSI6WyJ1SCJd
-LCJYaiI6WyJ1SCJdLCJiUSI6WyJ1SCJdLCJjWCI6WyJ1SCJdLCJHbS5FIjoidUgiLCJsRC5FIjoidUgi
-fSwiTE8iOnsiR20iOlsibDgiXSwibEQiOlsibDgiXSwiek0iOlsibDgiXSwiWGoiOlsibDgiXSwiYlEi
-OlsibDgiXSwiY1giOlsibDgiXSwiR20uRSI6Imw4IiwibEQuRSI6Imw4In0sImIxIjp7IkdtIjpbIldX
-Il0sImxEIjpbIldXIl0sIlhqIjpbIldXIl0sInpNIjpbIldXIl0sImJRIjpbIldXIl0sImNYIjpbIldX
-Il0sIkdtLkUiOiJXVyIsImxELkUiOiJXVyJ9LCJhVCI6eyJZayI6WyJxVSIsInFVIl0sIlowIjpbInFV
-IiwicVUiXX0sImk3Ijp7IllrIjpbInFVIiwicVUiXSwiWjAiOlsicVUiLCJxVSJdLCJZay5LIjoicVUi
-LCJZay5WIjoicVUifSwiU3kiOnsiWWsiOlsicVUiLCJxVSJdLCJaMCI6WyJxVSIsInFVIl0sIllrLksi
-OiJxVSIsIllrLlYiOiJxVSJ9LCJJNCI6eyJsZiI6WyJxVSJdLCJ4dSI6WyJxVSJdLCJiUSI6WyJxVSJd
-LCJjWCI6WyJxVSJdfSwiUk8iOnsicWgiOlsiMSJdfSwiZXUiOnsiUk8iOlsiMSJdLCJxaCI6WyIxIl19
-LCJ4QyI6eyJNTyI6WyIxIl19LCJKUSI6eyJrRiI6W119LCJ2RCI6eyJrRiI6W119LCJtNiI6eyJrRiI6
-W119LCJjdCI6eyJrRiI6W119LCJPdyI6eyJrRiI6W119LCJXOSI6eyJBbiI6WyIxIl19LCJkVyI6eyJ2
-NiI6W10sIkQwIjpbXX0sIm1rIjp7IldRIjpbXX0sIktvIjp7Im9uIjpbXX0sImRNIjp7ImxmIjpbInFV
-Il0sInh1IjpbInFVIl0sImJRIjpbInFVIl0sImNYIjpbInFVIl19LCJyNyI6eyJFNCI6W119LCJUeiI6
-eyJsRCI6WyIxIl0sInpNIjpbIjEiXSwiYlEiOlsiMSJdLCJFNCI6W10sImNYIjpbIjEiXSwibEQuRSI6
-IjEifSwicTYiOnsiR20iOlsieDAiXSwibEQiOlsieDAiXSwiek0iOlsieDAiXSwiYlEiOlsieDAiXSwi
-Y1giOlsieDAiXSwiR20uRSI6IngwIiwibEQuRSI6IngwIn0sImZ6Ijp7IkdtIjpbInVQIl0sImxEIjpb
-InVQIl0sInpNIjpbInVQIl0sImJRIjpbInVQIl0sImNYIjpbInVQIl0sIkdtLkUiOiJ1UCIsImxELkUi
-OiJ1UCJ9LCJuZCI6eyJkNSI6W10sImN2IjpbXSwidUgiOltdLCJEMCI6W119LCJLcSI6eyJHbSI6WyJx
-VSJdLCJsRCI6WyJxVSJdLCJ6TSI6WyJxVSJdLCJiUSI6WyJxVSJdLCJjWCI6WyJxVSJdLCJHbS5FIjoi
-cVUiLCJsRC5FIjoicVUifSwiS2UiOnsibGYiOlsicVUiXSwieHUiOlsicVUiXSwiYlEiOlsicVUiXSwi
-Y1giOlsicVUiXX0sImQ1Ijp7ImN2IjpbXSwidUgiOltdLCJEMCI6W119LCJOQyI6eyJHbSI6WyJ6WSJd
-LCJsRCI6WyJ6WSJdLCJ6TSI6WyJ6WSJdLCJiUSI6WyJ6WSJdLCJjWCI6WyJ6WSJdLCJHbS5FIjoielki
-LCJsRC5FIjoielkifSwibjYiOnsiek0iOlsiS04iXSwiYlEiOlsiS04iXSwiQVMiOltdLCJjWCI6WyJL
-TiJdfSwiejgiOnsiWWsiOlsicVUiLCJAIl0sIlowIjpbInFVIiwiQCJdLCJZay5LIjoicVUiLCJZay5W
-IjoiQCJ9LCJmbyI6eyJEMCI6W119LCJWOCI6eyJEMCI6W119LCJHbiI6eyJEMCI6W119LCJGbiI6eyJH
-bSI6WyJaMDxALEA+Il0sImxEIjpbIlowPEAsQD4iXSwiek0iOlsiWjA8QCxAPiJdLCJiUSI6WyJaMDxA
-LEA+Il0sImNYIjpbIlowPEAsQD4iXSwiR20uRSI6IlowPEAsQD4iLCJsRC5FIjoiWjA8QCxAPiJ9LCJY
-QSI6eyJrRiI6W119LCJPRiI6eyJMdSI6W119LCJydSI6eyJMdSI6W119LCJJViI6eyJMdSI6W119fScp
-KQpILkZGKHYudHlwZVVuaXZlcnNlLEpTT04ucGFyc2UoJ3siYlEiOjEsIlhDIjoxLCJNTyI6MSwia1Qi
-OjIsIm1XIjoxLCJMVSI6MSwiaWwiOjIsIlJLIjoxLCJuWSI6MSwiV1kiOjEsImNvIjoxLCJJTiI6MX0n
-KSkKdmFyIHU9KGZ1bmN0aW9uIHJ0aWkoKXt2YXIgdD1ILllRCnJldHVybntpOnQoIkdoIiksbjp0KCJD
-dyIpLGNSOnQoIm5CIiksZDp0KCJBeiIpLGs6dCgiUVAiKSxnRjp0KCJQRDxHRCxAPiIpLGc1OnQoImx3
-IiksZ3c6dCgiYlE8QD4iKSxoOnQoImN2IiksYlU6dCgiWFMiKSxCOnQoImVhIiksYVM6dCgiRDAiKSxP
-OnQoIlQ1IiksYlg6dCgiWFYiKSxaOnQoIkVIIiksYzp0KCJiODxAPiIpLGRQOnQoIkdPIikscjp0KCJP
-NyIpLEk6dCgiU2ciKSxvOnQoInZRIiksZWg6dCgiY1g8dUg+IiksWDp0KCJjWDxxVT4iKSxSOnQoImNY
-PEA+IiksZkE6dCgiamQ8U2U+IiksZ2k6dCgiamQ8ajg+IiksZmg6dCgiamQ8Wlo+IiksbTp0KCJqZDxr
-Rj4iKSxzOnQoImpkPHFVPiIpLGhoOnQoImpkPHlEPiIpLGFKOnQoImpkPHdiPiIpLHU6dCgiamQ8QD4i
-KSx0OnQoImpkPEtOPiIpLGVIOnQoInZtIiksZzp0KCJjNSIpLGFVOnQoIlhqPEA+IiksYW06dCgiVHo8
-QD4iKSxlbzp0KCJONTxHRCxAPiIpLHY6dCgiRTQiKSxkejp0KCJoRiIpLGJHOnQoIngwIiksZjQ6dCgi
-ek08ajg+IiksYTp0KCJ6TTxxVT4iKSxqOnQoInpNPEA+IiksTDp0KCJ6TTxLTj4iKSxhXzp0KCJ1OCIp
-LGY6dCgiWjA8cVUscVU+IiksYjp0KCJaMDxxVSxAPiIpLEc6dCgiWjA8QCxAPiIpLGR2OnQoIkE4PHFV
-LHFVPiIpLGRvOnQoIkE4PHFVLEA+IiksYks6dCgibEsiKSxjSTp0KCJBVyIpLFY6dCgiQWoiKSxiWjp0
-KCJXWiIpLGREOnQoIkVUIiksYm06dCgiVjYiKSxBOnQoInVIIiksZTp0KCJrRiIpLFA6dCgiYzgiKSxj
-azp0KCJ1UCIpLEs6dCgiayIpLGhlOnQoImNsIikscDp0KCJldyIpLHE6dCgidG48Rks+IiksZnY6dCgi
-d0wiKSxhdjp0KCJKYyIpLGV3OnQoIm5kIiksQzp0KCJ4dTxxVT4iKSxmWTp0KCJTViIpLGY3OnQoIlk0
-IiksZ2Y6dCgibDgiKSxsOnQoIkd6IiksTjp0KCJxVSIpLGRHOnQoInFVKHFVKSIpLGduOnQoIldXIiks
-Zzc6dCgiZDUiKSxmbzp0KCJHRCIpLGFXOnQoImZYIiksYTA6dCgiQTEiKSxjNzp0KCJNTiIpLGFLOnQo
-ImEzIiksY006dCgielkiKSx3OnQoIkFTIiksZ2M6dCgibjYiKSxhazp0KCJrZCIpLFc6dCgiR2o8cVUs
-cVU+IiksRDp0KCJpRCIpLGNjOnQoIlU1PHFVPiIpLGc0OnQoIk9pIiksY2k6dCgidjYiKSxnMjp0KCJD
-bSIpLGJqOnQoIlpmPE83PiIpLGg5OnQoIkNRIiksYWM6dCgiZTciKSxROnQoImV1PEFqPiIpLFM6dCgi
-d3o8Y3Y+IikseDp0KCJGZTxALEA+IiksYW86dCgidnM8Tzc+IiksXzp0KCJ2czxAPiIpLGZKOnQoInZz
-PEtOPiIpLEU6dCgiSlEiKSxKOnQoImJuIiksY0o6dCgiYTIiKSxhbDp0KCJhMihrKSIpLGJCOnQoImEy
-KHFVKSIpLGJmOnQoImEyKEApIiksejp0KCJAIiksZk86dCgiQCgpIiksRjp0KCJAKGVhKSIpLHk6dCgi
-QChrKSIpLGVwOnQoIkAoayxrKSIpLGFnOnQoIkAoayxHeikiKSxjaDp0KCJAKHh1PHFVPikiKSxkTzp0
-KCJAKHFVKSIpLFk6dCgiQChALEApIiksZWc6dCgiS04iKSxIOnQoIn4iKSxNOnQoIn4oKSIpLGFuOnQo
-In4oZXcpIiksVTp0KCJ+KHFVLHFVKSIpLFQ6dCgifihxVSxAKSIpfX0pKCk7KGZ1bmN0aW9uIGNvbnN0
-YW50cygpe3ZhciB0PWh1bmtIZWxwZXJzLm1ha2VDb25zdExpc3QKQy5SWT1XLlFQLnByb3RvdHlwZQpD
-LkJaPVcuVmIucHJvdG90eXBlCkMuRHQ9Vy5PNy5wcm90b3R5cGUKQy5Paz1KLnZCLnByb3RvdHlwZQpD
-Lk5tPUouamQucHJvdG90eXBlCkMuam49Si51ci5wcm90b3R5cGUKQy5qTj1KLllFLnByb3RvdHlwZQpD
-LkNEPUoucUkucHJvdG90eXBlCkMueEI9Si5Eci5wcm90b3R5cGUKQy5ERz1KLmM1LnByb3RvdHlwZQpD
-LkV4PVcudTgucHJvdG90eXBlCkMudDU9Vy5CSC5wcm90b3R5cGUKQy5MdD1XLlNOLnByb3RvdHlwZQpD
-LlpRPUouaUMucHJvdG90eXBlCkMuSWU9Vy5UYi5wcm90b3R5cGUKQy52Qj1KLmtkLnByb3RvdHlwZQpD
-Lm9sPVcuT2kucHJvdG90eXBlCkMueTg9bmV3IFAudkEoKQpDLmg5PW5ldyBQLkNWKCkKQy5PND1mdW5j
-dGlvbiBnZXRUYWdGYWxsYmFjayhvKSB7CiAgdmFyIHMgPSBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5n
-LmNhbGwobyk7CiAgcmV0dXJuIHMuc3Vic3RyaW5nKDgsIHMubGVuZ3RoIC0gMSk7Cn0KQy5ZcT1mdW5j
-dGlvbigpIHsKICB2YXIgdG9TdHJpbmdGdW5jdGlvbiA9IE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmc7
-CiAgZnVuY3Rpb24gZ2V0VGFnKG8pIHsKICAgIHZhciBzID0gdG9TdHJpbmdGdW5jdGlvbi5jYWxsKG8p
-OwogICAgcmV0dXJuIHMuc3Vic3RyaW5nKDgsIHMubGVuZ3RoIC0gMSk7CiAgfQogIGZ1bmN0aW9uIGdl
-dFVua25vd25UYWcob2JqZWN0LCB0YWcpIHsKICAgIGlmICgvXkhUTUxbQS1aXS4qRWxlbWVudCQvLnRl
-c3QodGFnKSkgewogICAgICB2YXIgbmFtZSA9IHRvU3RyaW5nRnVuY3Rpb24uY2FsbChvYmplY3QpOwog
-ICAgICBpZiAobmFtZSA9PSAiW29iamVjdCBPYmplY3RdIikgcmV0dXJuIG51bGw7CiAgICAgIHJldHVy
-biAiSFRNTEVsZW1lbnQiOwogICAgfQogIH0KICBmdW5jdGlvbiBnZXRVbmtub3duVGFnR2VuZXJpY0Jy
-b3dzZXIob2JqZWN0LCB0YWcpIHsKICAgIGlmIChzZWxmLkhUTUxFbGVtZW50ICYmIG9iamVjdCBpbnN0
-YW5jZW9mIEhUTUxFbGVtZW50KSByZXR1cm4gIkhUTUxFbGVtZW50IjsKICAgIHJldHVybiBnZXRVbmtu
-b3duVGFnKG9iamVjdCwgdGFnKTsKICB9CiAgZnVuY3Rpb24gcHJvdG90eXBlRm9yVGFnKHRhZykgewog
-ICAgaWYgKHR5cGVvZiB3aW5kb3cgPT0gInVuZGVmaW5lZCIpIHJldHVybiBudWxsOwogICAgaWYgKHR5
-cGVvZiB3aW5kb3dbdGFnXSA9PSAidW5kZWZpbmVkIikgcmV0dXJuIG51bGw7CiAgICB2YXIgY29uc3Ry
-dWN0b3IgPSB3aW5kb3dbdGFnXTsKICAgIGlmICh0eXBlb2YgY29uc3RydWN0b3IgIT0gImZ1bmN0aW9u
-IikgcmV0dXJuIG51bGw7CiAgICByZXR1cm4gY29uc3RydWN0b3IucHJvdG90eXBlOwogIH0KICBmdW5j
-dGlvbiBkaXNjcmltaW5hdG9yKHRhZykgeyByZXR1cm4gbnVsbDsgfQogIHZhciBpc0Jyb3dzZXIgPSB0
-eXBlb2YgbmF2aWdhdG9yID09ICJvYmplY3QiOwogIHJldHVybiB7CiAgICBnZXRUYWc6IGdldFRhZywK
-ICAgIGdldFVua25vd25UYWc6IGlzQnJvd3NlciA/IGdldFVua25vd25UYWdHZW5lcmljQnJvd3NlciA6
-IGdldFVua25vd25UYWcsCiAgICBwcm90b3R5cGVGb3JUYWc6IHByb3RvdHlwZUZvclRhZywKICAgIGRp
-c2NyaW1pbmF0b3I6IGRpc2NyaW1pbmF0b3IgfTsKfQpDLndiPWZ1bmN0aW9uKGdldFRhZ0ZhbGxiYWNr
-KSB7CiAgcmV0dXJuIGZ1bmN0aW9uKGhvb2tzKSB7CiAgICBpZiAodHlwZW9mIG5hdmlnYXRvciAhPSAi
-b2JqZWN0IikgcmV0dXJuIGhvb2tzOwogICAgdmFyIHVhID0gbmF2aWdhdG9yLnVzZXJBZ2VudDsKICAg
-IGlmICh1YS5pbmRleE9mKCJEdW1wUmVuZGVyVHJlZSIpID49IDApIHJldHVybiBob29rczsKICAgIGlm
-ICh1YS5pbmRleE9mKCJDaHJvbWUiKSA+PSAwKSB7CiAgICAgIGZ1bmN0aW9uIGNvbmZpcm0ocCkgewog
-ICAgICAgIHJldHVybiB0eXBlb2Ygd2luZG93ID09ICJvYmplY3QiICYmIHdpbmRvd1twXSAmJiB3aW5k
-b3dbcF0ubmFtZSA9PSBwOwogICAgICB9CiAgICAgIGlmIChjb25maXJtKCJXaW5kb3ciKSAmJiBjb25m
-aXJtKCJIVE1MRWxlbWVudCIpKSByZXR1cm4gaG9va3M7CiAgICB9CiAgICBob29rcy5nZXRUYWcgPSBn
-ZXRUYWdGYWxsYmFjazsKICB9Owp9CkMuS1U9ZnVuY3Rpb24oaG9va3MpIHsKICBpZiAodHlwZW9mIGRh
-cnRFeHBlcmltZW50YWxGaXh1cEdldFRhZyAhPSAiZnVuY3Rpb24iKSByZXR1cm4gaG9va3M7CiAgaG9v
-a3MuZ2V0VGFnID0gZGFydEV4cGVyaW1lbnRhbEZpeHVwR2V0VGFnKGhvb2tzLmdldFRhZyk7Cn0KQy5m
-UT1mdW5jdGlvbihob29rcykgewogIHZhciBnZXRUYWcgPSBob29rcy5nZXRUYWc7CiAgdmFyIHByb3Rv
-dHlwZUZvclRhZyA9IGhvb2tzLnByb3RvdHlwZUZvclRhZzsKICBmdW5jdGlvbiBnZXRUYWdGaXhlZChv
-KSB7CiAgICB2YXIgdGFnID0gZ2V0VGFnKG8pOwogICAgaWYgKHRhZyA9PSAiRG9jdW1lbnQiKSB7CiAg
-ICAgIGlmICghIW8ueG1sVmVyc2lvbikgcmV0dXJuICIhRG9jdW1lbnQiOwogICAgICByZXR1cm4gIiFI
-VE1MRG9jdW1lbnQiOwogICAgfQogICAgcmV0dXJuIHRhZzsKICB9CiAgZnVuY3Rpb24gcHJvdG90eXBl
-Rm9yVGFnRml4ZWQodGFnKSB7CiAgICBpZiAodGFnID09ICJEb2N1bWVudCIpIHJldHVybiBudWxsOwog
-ICAgcmV0dXJuIHByb3RvdHlwZUZvclRhZyh0YWcpOwogIH0KICBob29rcy5nZXRUYWcgPSBnZXRUYWdG
-aXhlZDsKICBob29rcy5wcm90b3R5cGVGb3JUYWcgPSBwcm90b3R5cGVGb3JUYWdGaXhlZDsKfQpDLmRr
-PWZ1bmN0aW9uKGhvb2tzKSB7CiAgdmFyIHVzZXJBZ2VudCA9IHR5cGVvZiBuYXZpZ2F0b3IgPT0gIm9i
-amVjdCIgPyBuYXZpZ2F0b3IudXNlckFnZW50IDogIiI7CiAgaWYgKHVzZXJBZ2VudC5pbmRleE9mKCJG
-aXJlZm94IikgPT0gLTEpIHJldHVybiBob29rczsKICB2YXIgZ2V0VGFnID0gaG9va3MuZ2V0VGFnOwog
-IHZhciBxdWlja01hcCA9IHsKICAgICJCZWZvcmVVbmxvYWRFdmVudCI6ICJFdmVudCIsCiAgICAiRGF0
-YVRyYW5zZmVyIjogIkNsaXBib2FyZCIsCiAgICAiR2VvR2VvbG9jYXRpb24iOiAiR2VvbG9jYXRpb24i
-LAogICAgIkxvY2F0aW9uIjogIiFMb2NhdGlvbiIsCiAgICAiV29ya2VyTWVzc2FnZUV2ZW50IjogIk1l
-c3NhZ2VFdmVudCIsCiAgICAiWE1MRG9jdW1lbnQiOiAiIURvY3VtZW50In07CiAgZnVuY3Rpb24gZ2V0
-VGFnRmlyZWZveChvKSB7CiAgICB2YXIgdGFnID0gZ2V0VGFnKG8pOwogICAgcmV0dXJuIHF1aWNrTWFw
-W3RhZ10gfHwgdGFnOwogIH0KICBob29rcy5nZXRUYWcgPSBnZXRUYWdGaXJlZm94Owp9CkMueGk9ZnVu
-Y3Rpb24oaG9va3MpIHsKICB2YXIgdXNlckFnZW50ID0gdHlwZW9mIG5hdmlnYXRvciA9PSAib2JqZWN0
-IiA/IG5hdmlnYXRvci51c2VyQWdlbnQgOiAiIjsKICBpZiAodXNlckFnZW50LmluZGV4T2YoIlRyaWRl
-bnQvIikgPT0gLTEpIHJldHVybiBob29rczsKICB2YXIgZ2V0VGFnID0gaG9va3MuZ2V0VGFnOwogIHZh
-ciBxdWlja01hcCA9IHsKICAgICJCZWZvcmVVbmxvYWRFdmVudCI6ICJFdmVudCIsCiAgICAiRGF0YVRy
-YW5zZmVyIjogIkNsaXBib2FyZCIsCiAgICAiSFRNTERERWxlbWVudCI6ICJIVE1MRWxlbWVudCIsCiAg
-ICAiSFRNTERURWxlbWVudCI6ICJIVE1MRWxlbWVudCIsCiAgICAiSFRNTFBocmFzZUVsZW1lbnQiOiAi
-SFRNTEVsZW1lbnQiLAogICAgIlBvc2l0aW9uIjogIkdlb3Bvc2l0aW9uIgogIH07CiAgZnVuY3Rpb24g
-Z2V0VGFnSUUobykgewogICAgdmFyIHRhZyA9IGdldFRhZyhvKTsKICAgIHZhciBuZXdUYWcgPSBxdWlj
-a01hcFt0YWddOwogICAgaWYgKG5ld1RhZykgcmV0dXJuIG5ld1RhZzsKICAgIGlmICh0YWcgPT0gIk9i
-amVjdCIpIHsKICAgICAgaWYgKHdpbmRvdy5EYXRhVmlldyAmJiAobyBpbnN0YW5jZW9mIHdpbmRvdy5E
-YXRhVmlldykpIHJldHVybiAiRGF0YVZpZXciOwogICAgfQogICAgcmV0dXJuIHRhZzsKICB9CiAgZnVu
-Y3Rpb24gcHJvdG90eXBlRm9yVGFnSUUodGFnKSB7CiAgICB2YXIgY29uc3RydWN0b3IgPSB3aW5kb3db
-dGFnXTsKICAgIGlmIChjb25zdHJ1Y3RvciA9PSBudWxsKSByZXR1cm4gbnVsbDsKICAgIHJldHVybiBj
-b25zdHJ1Y3Rvci5wcm90b3R5cGU7CiAgfQogIGhvb2tzLmdldFRhZyA9IGdldFRhZ0lFOwogIGhvb2tz
-LnByb3RvdHlwZUZvclRhZyA9IHByb3RvdHlwZUZvclRhZ0lFOwp9CkMuaTc9ZnVuY3Rpb24oaG9va3Mp
-IHsgcmV0dXJuIGhvb2tzOyB9CgpDLkN0PW5ldyBQLmJ5KCkKQy5FcT1uZXcgUC5rNSgpCkMueE09bmV3
-IFAudTUoKQpDLlFrPW5ldyBQLkUzKCkKQy5OVT1uZXcgUC5KaSgpCkMuQTM9bmV3IFAuTXgobnVsbCkK
-Qy5HYj1ILlZNKHQoWzEyNywyMDQ3LDY1NTM1LDExMTQxMTFdKSx1LnQpCkMuYWs9SC5WTSh0KFswLDAs
-MzI3NzYsMzM3OTIsMSwxMDI0MCwwLDBdKSx1LnQpCkMuY209SC5WTSh0KFsiKjo6Y2xhc3MiLCIqOjpk
-aXIiLCIqOjpkcmFnZ2FibGUiLCIqOjpoaWRkZW4iLCIqOjppZCIsIio6OmluZXJ0IiwiKjo6aXRlbXBy
-b3AiLCIqOjppdGVtcmVmIiwiKjo6aXRlbXNjb3BlIiwiKjo6bGFuZyIsIio6OnNwZWxsY2hlY2siLCIq
-Ojp0aXRsZSIsIio6OnRyYW5zbGF0ZSIsIkE6OmFjY2Vzc2tleSIsIkE6OmNvb3JkcyIsIkE6OmhyZWZs
-YW5nIiwiQTo6bmFtZSIsIkE6OnNoYXBlIiwiQTo6dGFiaW5kZXgiLCJBOjp0YXJnZXQiLCJBOjp0eXBl
-IiwiQVJFQTo6YWNjZXNza2V5IiwiQVJFQTo6YWx0IiwiQVJFQTo6Y29vcmRzIiwiQVJFQTo6bm9ocmVm
-IiwiQVJFQTo6c2hhcGUiLCJBUkVBOjp0YWJpbmRleCIsIkFSRUE6OnRhcmdldCIsIkFVRElPOjpjb250
-cm9scyIsIkFVRElPOjpsb29wIiwiQVVESU86Om1lZGlhZ3JvdXAiLCJBVURJTzo6bXV0ZWQiLCJBVURJ
-Tzo6cHJlbG9hZCIsIkJETzo6ZGlyIiwiQk9EWTo6YWxpbmsiLCJCT0RZOjpiZ2NvbG9yIiwiQk9EWTo6
-bGluayIsIkJPRFk6OnRleHQiLCJCT0RZOjp2bGluayIsIkJSOjpjbGVhciIsIkJVVFRPTjo6YWNjZXNz
-a2V5IiwiQlVUVE9OOjpkaXNhYmxlZCIsIkJVVFRPTjo6bmFtZSIsIkJVVFRPTjo6dGFiaW5kZXgiLCJC
-VVRUT046OnR5cGUiLCJCVVRUT046OnZhbHVlIiwiQ0FOVkFTOjpoZWlnaHQiLCJDQU5WQVM6OndpZHRo
-IiwiQ0FQVElPTjo6YWxpZ24iLCJDT0w6OmFsaWduIiwiQ09MOjpjaGFyIiwiQ09MOjpjaGFyb2ZmIiwi
-Q09MOjpzcGFuIiwiQ09MOjp2YWxpZ24iLCJDT0w6OndpZHRoIiwiQ09MR1JPVVA6OmFsaWduIiwiQ09M
-R1JPVVA6OmNoYXIiLCJDT0xHUk9VUDo6Y2hhcm9mZiIsIkNPTEdST1VQOjpzcGFuIiwiQ09MR1JPVVA6
-OnZhbGlnbiIsIkNPTEdST1VQOjp3aWR0aCIsIkNPTU1BTkQ6OmNoZWNrZWQiLCJDT01NQU5EOjpjb21t
-YW5kIiwiQ09NTUFORDo6ZGlzYWJsZWQiLCJDT01NQU5EOjpsYWJlbCIsIkNPTU1BTkQ6OnJhZGlvZ3Jv
-dXAiLCJDT01NQU5EOjp0eXBlIiwiREFUQTo6dmFsdWUiLCJERUw6OmRhdGV0aW1lIiwiREVUQUlMUzo6
-b3BlbiIsIkRJUjo6Y29tcGFjdCIsIkRJVjo6YWxpZ24iLCJETDo6Y29tcGFjdCIsIkZJRUxEU0VUOjpk
-aXNhYmxlZCIsIkZPTlQ6OmNvbG9yIiwiRk9OVDo6ZmFjZSIsIkZPTlQ6OnNpemUiLCJGT1JNOjphY2Nl
-cHQiLCJGT1JNOjphdXRvY29tcGxldGUiLCJGT1JNOjplbmN0eXBlIiwiRk9STTo6bWV0aG9kIiwiRk9S
-TTo6bmFtZSIsIkZPUk06Om5vdmFsaWRhdGUiLCJGT1JNOjp0YXJnZXQiLCJGUkFNRTo6bmFtZSIsIkgx
-OjphbGlnbiIsIkgyOjphbGlnbiIsIkgzOjphbGlnbiIsIkg0OjphbGlnbiIsIkg1OjphbGlnbiIsIkg2
-OjphbGlnbiIsIkhSOjphbGlnbiIsIkhSOjpub3NoYWRlIiwiSFI6OnNpemUiLCJIUjo6d2lkdGgiLCJI
-VE1MOjp2ZXJzaW9uIiwiSUZSQU1FOjphbGlnbiIsIklGUkFNRTo6ZnJhbWVib3JkZXIiLCJJRlJBTUU6
-OmhlaWdodCIsIklGUkFNRTo6bWFyZ2luaGVpZ2h0IiwiSUZSQU1FOjptYXJnaW53aWR0aCIsIklGUkFN
-RTo6d2lkdGgiLCJJTUc6OmFsaWduIiwiSU1HOjphbHQiLCJJTUc6OmJvcmRlciIsIklNRzo6aGVpZ2h0
-IiwiSU1HOjpoc3BhY2UiLCJJTUc6OmlzbWFwIiwiSU1HOjpuYW1lIiwiSU1HOjp1c2VtYXAiLCJJTUc6
-OnZzcGFjZSIsIklNRzo6d2lkdGgiLCJJTlBVVDo6YWNjZXB0IiwiSU5QVVQ6OmFjY2Vzc2tleSIsIklO
-UFVUOjphbGlnbiIsIklOUFVUOjphbHQiLCJJTlBVVDo6YXV0b2NvbXBsZXRlIiwiSU5QVVQ6OmF1dG9m
-b2N1cyIsIklOUFVUOjpjaGVja2VkIiwiSU5QVVQ6OmRpc2FibGVkIiwiSU5QVVQ6OmlucHV0bW9kZSIs
-IklOUFVUOjppc21hcCIsIklOUFVUOjpsaXN0IiwiSU5QVVQ6Om1heCIsIklOUFVUOjptYXhsZW5ndGgi
-LCJJTlBVVDo6bWluIiwiSU5QVVQ6Om11bHRpcGxlIiwiSU5QVVQ6Om5hbWUiLCJJTlBVVDo6cGxhY2Vo
-b2xkZXIiLCJJTlBVVDo6cmVhZG9ubHkiLCJJTlBVVDo6cmVxdWlyZWQiLCJJTlBVVDo6c2l6ZSIsIklO
-UFVUOjpzdGVwIiwiSU5QVVQ6OnRhYmluZGV4IiwiSU5QVVQ6OnR5cGUiLCJJTlBVVDo6dXNlbWFwIiwi
-SU5QVVQ6OnZhbHVlIiwiSU5TOjpkYXRldGltZSIsIktFWUdFTjo6ZGlzYWJsZWQiLCJLRVlHRU46Omtl
-eXR5cGUiLCJLRVlHRU46Om5hbWUiLCJMQUJFTDo6YWNjZXNza2V5IiwiTEFCRUw6OmZvciIsIkxFR0VO
-RDo6YWNjZXNza2V5IiwiTEVHRU5EOjphbGlnbiIsIkxJOjp0eXBlIiwiTEk6OnZhbHVlIiwiTElOSzo6
-c2l6ZXMiLCJNQVA6Om5hbWUiLCJNRU5VOjpjb21wYWN0IiwiTUVOVTo6bGFiZWwiLCJNRU5VOjp0eXBl
-IiwiTUVURVI6OmhpZ2giLCJNRVRFUjo6bG93IiwiTUVURVI6Om1heCIsIk1FVEVSOjptaW4iLCJNRVRF
-Ujo6dmFsdWUiLCJPQkpFQ1Q6OnR5cGVtdXN0bWF0Y2giLCJPTDo6Y29tcGFjdCIsIk9MOjpyZXZlcnNl
-ZCIsIk9MOjpzdGFydCIsIk9MOjp0eXBlIiwiT1BUR1JPVVA6OmRpc2FibGVkIiwiT1BUR1JPVVA6Omxh
-YmVsIiwiT1BUSU9OOjpkaXNhYmxlZCIsIk9QVElPTjo6bGFiZWwiLCJPUFRJT046OnNlbGVjdGVkIiwi
-T1BUSU9OOjp2YWx1ZSIsIk9VVFBVVDo6Zm9yIiwiT1VUUFVUOjpuYW1lIiwiUDo6YWxpZ24iLCJQUkU6
-OndpZHRoIiwiUFJPR1JFU1M6Om1heCIsIlBST0dSRVNTOjptaW4iLCJQUk9HUkVTUzo6dmFsdWUiLCJT
-RUxFQ1Q6OmF1dG9jb21wbGV0ZSIsIlNFTEVDVDo6ZGlzYWJsZWQiLCJTRUxFQ1Q6Om11bHRpcGxlIiwi
-U0VMRUNUOjpuYW1lIiwiU0VMRUNUOjpyZXF1aXJlZCIsIlNFTEVDVDo6c2l6ZSIsIlNFTEVDVDo6dGFi
-aW5kZXgiLCJTT1VSQ0U6OnR5cGUiLCJUQUJMRTo6YWxpZ24iLCJUQUJMRTo6Ymdjb2xvciIsIlRBQkxF
-Ojpib3JkZXIiLCJUQUJMRTo6Y2VsbHBhZGRpbmciLCJUQUJMRTo6Y2VsbHNwYWNpbmciLCJUQUJMRTo6
-ZnJhbWUiLCJUQUJMRTo6cnVsZXMiLCJUQUJMRTo6c3VtbWFyeSIsIlRBQkxFOjp3aWR0aCIsIlRCT0RZ
-OjphbGlnbiIsIlRCT0RZOjpjaGFyIiwiVEJPRFk6OmNoYXJvZmYiLCJUQk9EWTo6dmFsaWduIiwiVEQ6
-OmFiYnIiLCJURDo6YWxpZ24iLCJURDo6YXhpcyIsIlREOjpiZ2NvbG9yIiwiVEQ6OmNoYXIiLCJURDo6
-Y2hhcm9mZiIsIlREOjpjb2xzcGFuIiwiVEQ6OmhlYWRlcnMiLCJURDo6aGVpZ2h0IiwiVEQ6Om5vd3Jh
-cCIsIlREOjpyb3dzcGFuIiwiVEQ6OnNjb3BlIiwiVEQ6OnZhbGlnbiIsIlREOjp3aWR0aCIsIlRFWFRB
-UkVBOjphY2Nlc3NrZXkiLCJURVhUQVJFQTo6YXV0b2NvbXBsZXRlIiwiVEVYVEFSRUE6OmNvbHMiLCJU
-RVhUQVJFQTo6ZGlzYWJsZWQiLCJURVhUQVJFQTo6aW5wdXRtb2RlIiwiVEVYVEFSRUE6Om5hbWUiLCJU
-RVhUQVJFQTo6cGxhY2Vob2xkZXIiLCJURVhUQVJFQTo6cmVhZG9ubHkiLCJURVhUQVJFQTo6cmVxdWly
-ZWQiLCJURVhUQVJFQTo6cm93cyIsIlRFWFRBUkVBOjp0YWJpbmRleCIsIlRFWFRBUkVBOjp3cmFwIiwi
-VEZPT1Q6OmFsaWduIiwiVEZPT1Q6OmNoYXIiLCJURk9PVDo6Y2hhcm9mZiIsIlRGT09UOjp2YWxpZ24i
-LCJUSDo6YWJiciIsIlRIOjphbGlnbiIsIlRIOjpheGlzIiwiVEg6OmJnY29sb3IiLCJUSDo6Y2hhciIs
-IlRIOjpjaGFyb2ZmIiwiVEg6OmNvbHNwYW4iLCJUSDo6aGVhZGVycyIsIlRIOjpoZWlnaHQiLCJUSDo6
-bm93cmFwIiwiVEg6OnJvd3NwYW4iLCJUSDo6c2NvcGUiLCJUSDo6dmFsaWduIiwiVEg6OndpZHRoIiwi
-VEhFQUQ6OmFsaWduIiwiVEhFQUQ6OmNoYXIiLCJUSEVBRDo6Y2hhcm9mZiIsIlRIRUFEOjp2YWxpZ24i
-LCJUUjo6YWxpZ24iLCJUUjo6Ymdjb2xvciIsIlRSOjpjaGFyIiwiVFI6OmNoYXJvZmYiLCJUUjo6dmFs
-aWduIiwiVFJBQ0s6OmRlZmF1bHQiLCJUUkFDSzo6a2luZCIsIlRSQUNLOjpsYWJlbCIsIlRSQUNLOjpz
-cmNsYW5nIiwiVUw6OmNvbXBhY3QiLCJVTDo6dHlwZSIsIlZJREVPOjpjb250cm9scyIsIlZJREVPOjpo
-ZWlnaHQiLCJWSURFTzo6bG9vcCIsIlZJREVPOjptZWRpYWdyb3VwIiwiVklERU86Om11dGVkIiwiVklE
-RU86OnByZWxvYWQiLCJWSURFTzo6d2lkdGgiXSksdS5zKQpDLlZDPUguVk0odChbMCwwLDY1NDkwLDQ1
-MDU1LDY1NTM1LDM0ODE1LDY1NTM0LDE4NDMxXSksdS50KQpDLm1LPUguVk0odChbMCwwLDI2NjI0LDEw
-MjMsNjU1MzQsMjA0Nyw2NTUzNCwyMDQ3XSksdS50KQpDLlNxPUguVk0odChbIkhFQUQiLCJBUkVBIiwi
-QkFTRSIsIkJBU0VGT05UIiwiQlIiLCJDT0wiLCJDT0xHUk9VUCIsIkVNQkVEIiwiRlJBTUUiLCJGUkFN
-RVNFVCIsIkhSIiwiSU1BR0UiLCJJTUciLCJJTlBVVCIsIklTSU5ERVgiLCJMSU5LIiwiTUVUQSIsIlBB
-UkFNIiwiU09VUkNFIiwiU1RZTEUiLCJUSVRMRSIsIldCUiJdKSx1LnMpCkMueEQ9SC5WTSh0KFtdKSx1
-LnMpCkMuZG49SC5WTSh0KFtdKSx1LnUpCkMudG89SC5WTSh0KFswLDAsMzI3MjIsMTIyODcsNjU1MzQs
-MzQ4MTUsNjU1MzQsMTg0MzFdKSx1LnQpCkMuRjM9SC5WTSh0KFswLDAsMjQ1NzYsMTAyMyw2NTUzNCwz
-NDgxNSw2NTUzNCwxODQzMV0pLHUudCkKQy5lYT1ILlZNKHQoWzAsMCwzMjc1NCwxMTI2Myw2NTUzNCwz
-NDgxNSw2NTUzNCwxODQzMV0pLHUudCkKQy5aSj1ILlZNKHQoWzAsMCwzMjcyMiwxMjI4Nyw2NTUzNSwz
-NDgxNSw2NTUzNCwxODQzMV0pLHUudCkKQy5XZD1ILlZNKHQoWzAsMCw2NTQ5MCwxMjI4Nyw2NTUzNSwz
-NDgxNSw2NTUzNCwxODQzMV0pLHUudCkKQy5ReD1ILlZNKHQoWyJiaW5kIiwiaWYiLCJyZWYiLCJyZXBl
-YXQiLCJzeW50YXgiXSksdS5zKQpDLkJJPUguVk0odChbIkE6OmhyZWYiLCJBUkVBOjpocmVmIiwiQkxP
-Q0tRVU9URTo6Y2l0ZSIsIkJPRFk6OmJhY2tncm91bmQiLCJDT01NQU5EOjppY29uIiwiREVMOjpjaXRl
-IiwiRk9STTo6YWN0aW9uIiwiSU1HOjpzcmMiLCJJTlBVVDo6c3JjIiwiSU5TOjpjaXRlIiwiUTo6Y2l0
-ZSIsIlZJREVPOjpwb3N0ZXIiXSksdS5zKQpDLkNNPW5ldyBILkxQKDAse30sQy54RCxILllRKCJMUDxx
-VSx6TTxqOD4+IikpCkMuV089bmV3IEguTFAoMCx7fSxDLnhELEguWVEoIkxQPHFVLHFVPiIpKQpDLmhV
-PUguVk0odChbXSksSC5ZUSgiamQ8R0Q+IikpCkMuRHg9bmV3IEguTFAoMCx7fSxDLmhVLEguWVEoIkxQ
-PEdELEA+IikpCkMuWTI9bmV3IEwuQmMoIk5hdmlnYXRpb25UcmVlTm9kZVR5cGUuZGlyZWN0b3J5IikK
-Qy5yZj1uZXcgTC5CYygiTmF2aWdhdGlvblRyZWVOb2RlVHlwZS5maWxlIikKQy5UZT1uZXcgSC53digi
-Y2FsbCIpCkMud1E9bmV3IFAuRnkobnVsbCwyKX0pKCk7KGZ1bmN0aW9uIHN0YXRpY0ZpZWxkcygpeyQu
-eWo9MAokLm1KPW51bGwKJC5QND1udWxsCiQuTkY9bnVsbAokLlRYPW51bGwKJC54Nz1udWxsCiQubnc9
-bnVsbAokLnZ2PW51bGwKJC5Cdj1udWxsCiQuUzY9bnVsbAokLms4PW51bGwKJC5tZz1udWxsCiQuVUQ9
-ITEKJC5YMz1DLk5VCiQueGc9W10KJC54bz1udWxsCiQuQk89bnVsbAokLmx0PW51bGwKJC5FVT1udWxs
-CiQub3I9UC5GbCh1Lk4sdS5aKQokLkk2PW51bGwKJC5GZj1udWxsfSkoKTsoZnVuY3Rpb24gbGF6eUlu
-aXRpYWxpemVycygpe3ZhciB0PWh1bmtIZWxwZXJzLmxhenkKdCgkLCJmYSIsInciLGZ1bmN0aW9uKCl7
-cmV0dXJuIEguWWcoIl8kZGFydF9kYXJ0Q2xvc3VyZSIpfSkKdCgkLCJZMiIsIlVOIixmdW5jdGlvbigp
-e3JldHVybiBILllnKCJfJGRhcnRfanMiKX0pCnQoJCwiVTIiLCJTbiIsZnVuY3Rpb24oKXtyZXR1cm4g
-SC5jTShILlM3KHsKdG9TdHJpbmc6ZnVuY3Rpb24oKXtyZXR1cm4iJHJlY2VpdmVyJCJ9fSkpfSkKdCgk
-LCJ4cSIsImxxIixmdW5jdGlvbigpe3JldHVybiBILmNNKEguUzcoeyRtZXRob2QkOm51bGwsCnRvU3Ry
-aW5nOmZ1bmN0aW9uKCl7cmV0dXJuIiRyZWNlaXZlciQifX0pKX0pCnQoJCwiUjEiLCJOOSIsZnVuY3Rp
-b24oKXtyZXR1cm4gSC5jTShILlM3KG51bGwpKX0pCnQoJCwiZk4iLCJpSSIsZnVuY3Rpb24oKXtyZXR1
-cm4gSC5jTShmdW5jdGlvbigpe3ZhciAkYXJndW1lbnRzRXhwciQ9JyRhcmd1bWVudHMkJwp0cnl7bnVs
-bC4kbWV0aG9kJCgkYXJndW1lbnRzRXhwciQpfWNhdGNoKHMpe3JldHVybiBzLm1lc3NhZ2V9fSgpKX0p
-CnQoJCwicWkiLCJLZiIsZnVuY3Rpb24oKXtyZXR1cm4gSC5jTShILlM3KHZvaWQgMCkpfSkKdCgkLCJy
-WiIsIlpoIixmdW5jdGlvbigpe3JldHVybiBILmNNKGZ1bmN0aW9uKCl7dmFyICRhcmd1bWVudHNFeHBy
-JD0nJGFyZ3VtZW50cyQnCnRyeXsodm9pZCAwKS4kbWV0aG9kJCgkYXJndW1lbnRzRXhwciQpfWNhdGNo
-KHMpe3JldHVybiBzLm1lc3NhZ2V9fSgpKX0pCnQoJCwia3EiLCJyTiIsZnVuY3Rpb24oKXtyZXR1cm4g
-SC5jTShILk1qKG51bGwpKX0pCnQoJCwidHQiLCJjMyIsZnVuY3Rpb24oKXtyZXR1cm4gSC5jTShmdW5j
-dGlvbigpe3RyeXtudWxsLiRtZXRob2QkfWNhdGNoKHMpe3JldHVybiBzLm1lc3NhZ2V9fSgpKX0pCnQo
-JCwiZHQiLCJISyIsZnVuY3Rpb24oKXtyZXR1cm4gSC5jTShILk1qKHZvaWQgMCkpfSkKdCgkLCJBNyIs
-InIxIixmdW5jdGlvbigpe3JldHVybiBILmNNKGZ1bmN0aW9uKCl7dHJ5eyh2b2lkIDApLiRtZXRob2Qk
-fWNhdGNoKHMpe3JldHVybiBzLm1lc3NhZ2V9fSgpKX0pCnQoJCwiV2MiLCJ1dCIsZnVuY3Rpb24oKXty
-ZXR1cm4gUC5PaigpfSkKdCgkLCJraCIsInJmIixmdW5jdGlvbigpe3JldHVybiBQLldJKCl9KQp0KCQs
-ImJ0IiwiVjciLGZ1bmN0aW9uKCl7cmV0dXJuIEguRFEoSC5YRihILlZNKFstMiwtMiwtMiwtMiwtMiwt
-MiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwt
-MiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwtMSwtMiwtMiwtMiwtMiwtMiw2MiwtMiw2
-MiwtMiw2Myw1Miw1Myw1NCw1NSw1Niw1Nyw1OCw1OSw2MCw2MSwtMiwtMiwtMiwtMSwtMiwtMiwtMiww
-LDEsMiwzLDQsNSw2LDcsOCw5LDEwLDExLDEyLDEzLDE0LDE1LDE2LDE3LDE4LDE5LDIwLDIxLDIyLDIz
-LDI0LDI1LC0yLC0yLC0yLC0yLDYzLC0yLDI2LDI3LDI4LDI5LDMwLDMxLDMyLDMzLDM0LDM1LDM2LDM3
-LDM4LDM5LDQwLDQxLDQyLDQzLDQ0LDQ1LDQ2LDQ3LDQ4LDQ5LDUwLDUxLC0yLC0yLC0yLC0yLC0yXSx1
-LnQpKSl9KQp0KCQsIk01IiwiT3giLGZ1bmN0aW9uKCl7cmV0dXJuIHR5cGVvZiBwcm9jZXNzIT0idW5k
-ZWZpbmVkIiYmT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKHByb2Nlc3MpPT0iW29iamVjdCBw
-cm9jZXNzXSImJnByb2Nlc3MucGxhdGZvcm09PSJ3aW4zMiJ9KQp0KCQsIm1mIiwiejQiLGZ1bmN0aW9u
-KCl7cmV0dXJuIFAubnUoIl5bXFwtXFwuMC05QS1aX2Eten5dKiQiKX0pCnQoJCwiSkciLCJ2WiIsZnVu
-Y3Rpb24oKXtyZXR1cm4gUC51eCgpfSkKdCgkLCJTQyIsIkFOIixmdW5jdGlvbigpe3JldHVybiBQLnRN
-KFsiQSIsIkFCQlIiLCJBQ1JPTllNIiwiQUREUkVTUyIsIkFSRUEiLCJBUlRJQ0xFIiwiQVNJREUiLCJB
-VURJTyIsIkIiLCJCREkiLCJCRE8iLCJCSUciLCJCTE9DS1FVT1RFIiwiQlIiLCJCVVRUT04iLCJDQU5W
-QVMiLCJDQVBUSU9OIiwiQ0VOVEVSIiwiQ0lURSIsIkNPREUiLCJDT0wiLCJDT0xHUk9VUCIsIkNPTU1B
-TkQiLCJEQVRBIiwiREFUQUxJU1QiLCJERCIsIkRFTCIsIkRFVEFJTFMiLCJERk4iLCJESVIiLCJESVYi
-LCJETCIsIkRUIiwiRU0iLCJGSUVMRFNFVCIsIkZJR0NBUFRJT04iLCJGSUdVUkUiLCJGT05UIiwiRk9P
-VEVSIiwiRk9STSIsIkgxIiwiSDIiLCJIMyIsIkg0IiwiSDUiLCJINiIsIkhFQURFUiIsIkhHUk9VUCIs
-IkhSIiwiSSIsIklGUkFNRSIsIklNRyIsIklOUFVUIiwiSU5TIiwiS0JEIiwiTEFCRUwiLCJMRUdFTkQi
-LCJMSSIsIk1BUCIsIk1BUksiLCJNRU5VIiwiTUVURVIiLCJOQVYiLCJOT0JSIiwiT0wiLCJPUFRHUk9V
-UCIsIk9QVElPTiIsIk9VVFBVVCIsIlAiLCJQUkUiLCJQUk9HUkVTUyIsIlEiLCJTIiwiU0FNUCIsIlNF
-Q1RJT04iLCJTRUxFQ1QiLCJTTUFMTCIsIlNPVVJDRSIsIlNQQU4iLCJTVFJJS0UiLCJTVFJPTkciLCJT
-VUIiLCJTVU1NQVJZIiwiU1VQIiwiVEFCTEUiLCJUQk9EWSIsIlREIiwiVEVYVEFSRUEiLCJURk9PVCIs
-IlRIIiwiVEhFQUQiLCJUSU1FIiwiVFIiLCJUUkFDSyIsIlRUIiwiVSIsIlVMIiwiVkFSIiwiVklERU8i
-LCJXQlIiXSx1Lk4pfSkKdCgkLCJWUSIsImhHIixmdW5jdGlvbigpe3JldHVybiBQLm51KCJeXFxTKyQi
-KX0pCnQoJCwid08iLCJvdyIsZnVuY3Rpb24oKXtyZXR1cm4gdS52LmIoUC5ORChzZWxmKSl9KQp0KCQs
-Imt0IiwiUjgiLGZ1bmN0aW9uKCl7cmV0dXJuIEguWWcoIl8kZGFydF9kYXJ0T2JqZWN0Iil9KQp0KCQs
-IkxGIiwia0kiLGZ1bmN0aW9uKCl7cmV0dXJuIGZ1bmN0aW9uIERhcnRPYmplY3QoYSl7dGhpcy5vPWF9
-fSkKdCgkLCJxdCIsInpCIixmdW5jdGlvbigpe3JldHVybiBuZXcgVC5tUSgpfSkKdCgkLCJPbCIsIlVF
-IixmdW5jdGlvbigpe3JldHVybiBQLmhLKEMub2wuZ21XKFcueDMoKSkuaHJlZikuZ2hZKCkucSgwLCJh
-dXRoVG9rZW4iKX0pCnQoJCwiaFQiLCJ5UCIsZnVuY3Rpb24oKXtyZXR1cm4gVy5acigpLnF1ZXJ5U2Vs
-ZWN0b3IoIi5lZGl0LWxpc3QgLnBhbmVsLWNvbnRlbnQiKX0pCnQoJCwiVzYiLCJoTCIsZnVuY3Rpb24o
-KXtyZXR1cm4gVy5acigpLnF1ZXJ5U2VsZWN0b3IoIi5lZGl0LXBhbmVsIC5wYW5lbC1jb250ZW50Iil9
-KQp0KCQsIlRSIiwiRFciLGZ1bmN0aW9uKCl7cmV0dXJuIFcuWnIoKS5xdWVyeVNlbGVjdG9yKCJmb290
-ZXIiKX0pCnQoJCwiRVkiLCJmaSIsZnVuY3Rpb24oKXtyZXR1cm4gVy5acigpLnF1ZXJ5U2VsZWN0b3Io
-ImhlYWRlciIpfSkKdCgkLCJhZCIsIkQ5IixmdW5jdGlvbigpe3JldHVybiBXLlpyKCkucXVlcnlTZWxl
-Y3RvcigiI3VuaXQtbmFtZSIpfSkKdCgkLCJtcSIsIktHIixmdW5jdGlvbigpe3JldHVybiBuZXcgTC5Y
-QSgpfSkKdCgkLCJtTSIsIm5VIixmdW5jdGlvbigpe3JldHVybiBuZXcgTS5sSSgkLkhrKCkpfSkKdCgk
-LCJlOSIsImJEIixmdW5jdGlvbigpe3JldHVybiBuZXcgRS5PRihQLm51KCIvIiksUC5udSgiW14vXSQi
-KSxQLm51KCJeLyIpKX0pCnQoJCwiWUsiLCJLayIsZnVuY3Rpb24oKXtyZXR1cm4gbmV3IEwuSVYoUC5u
-dSgiWy9cXFxcXSIpLFAubnUoIlteL1xcXFxdJCIpLFAubnUoIl4oXFxcXFxcXFxbXlxcXFxdK1xcXFxb
-XlxcXFwvXSt8W2EtekEtWl06Wy9cXFxcXSkiKSxQLm51KCJeWy9cXFxcXSg/IVsvXFxcXF0pIikpfSkK
-dCgkLCJhQyIsIkViIixmdW5jdGlvbigpe3JldHVybiBuZXcgRi5ydShQLm51KCIvIiksUC5udSgiKF5b
-YS16QS1aXVstKy5hLXpBLVpcXGRdKjovL3xbXi9dKSQiKSxQLm51KCJbYS16QS1aXVstKy5hLXpBLVpc
-XGRdKjovL1teL10qIiksUC5udSgiXi8iKSl9KQp0KCQsImxzIiwiSGsiLGZ1bmN0aW9uKCl7cmV0dXJu
-IE8uUmgoKX0pfSkoKTsoZnVuY3Rpb24gbmF0aXZlU3VwcG9ydCgpeyFmdW5jdGlvbigpe3ZhciB0PWZ1
-bmN0aW9uKGEpe3ZhciBuPXt9Cm5bYV09MQpyZXR1cm4gT2JqZWN0LmtleXMoaHVua0hlbHBlcnMuY29u
-dmVydFRvRmFzdE9iamVjdChuKSlbMF19CnYuZ2V0SXNvbGF0ZVRhZz1mdW5jdGlvbihhKXtyZXR1cm4g
-dCgiX19fZGFydF8iK2Erdi5pc29sYXRlVGFnKX0KdmFyIHM9Il9fX2RhcnRfaXNvbGF0ZV90YWdzXyIK
-dmFyIHI9T2JqZWN0W3NdfHwoT2JqZWN0W3NdPU9iamVjdC5jcmVhdGUobnVsbCkpCnZhciBxPSJfWnhZ
-eFgiCmZvcih2YXIgcD0wOztwKyspe3ZhciBvPXQocSsiXyIrcCsiXyIpCmlmKCEobyBpbiByKSl7cltv
-XT0xCnYuaXNvbGF0ZVRhZz1vCmJyZWFrfX12LmRpc3BhdGNoUHJvcGVydHlOYW1lPXYuZ2V0SXNvbGF0
-ZVRhZygiZGlzcGF0Y2hfcmVjb3JkIil9KCkKaHVua0hlbHBlcnMuc2V0T3JVcGRhdGVJbnRlcmNlcHRv
-cnNCeVRhZyh7QW5pbWF0aW9uRWZmZWN0UmVhZE9ubHk6Si52QixBbmltYXRpb25FZmZlY3RUaW1pbmc6
-Si52QixBbmltYXRpb25FZmZlY3RUaW1pbmdSZWFkT25seTpKLnZCLEFuaW1hdGlvblRpbWVsaW5lOkou
-dkIsQW5pbWF0aW9uV29ya2xldEdsb2JhbFNjb3BlOkoudkIsQXV0aGVudGljYXRvckFzc2VydGlvblJl
-c3BvbnNlOkoudkIsQXV0aGVudGljYXRvckF0dGVzdGF0aW9uUmVzcG9uc2U6Si52QixBdXRoZW50aWNh
-dG9yUmVzcG9uc2U6Si52QixCYWNrZ3JvdW5kRmV0Y2hGZXRjaDpKLnZCLEJhY2tncm91bmRGZXRjaE1h
-bmFnZXI6Si52QixCYWNrZ3JvdW5kRmV0Y2hTZXR0bGVkRmV0Y2g6Si52QixCYXJQcm9wOkoudkIsQmFy
-Y29kZURldGVjdG9yOkoudkIsQm9keTpKLnZCLEJ1ZGdldFN0YXRlOkoudkIsQ2FjaGVTdG9yYWdlOkou
-dkIsQ2FudmFzR3JhZGllbnQ6Si52QixDYW52YXNQYXR0ZXJuOkoudkIsQ2FudmFzUmVuZGVyaW5nQ29u
-dGV4dDJEOkoudkIsQ2xpZW50OkoudkIsQ2xpZW50czpKLnZCLENvb2tpZVN0b3JlOkoudkIsQ29vcmRp
-bmF0ZXM6Si52QixDcmVkZW50aWFsOkoudkIsQ3JlZGVudGlhbFVzZXJEYXRhOkoudkIsQ3JlZGVudGlh
-bHNDb250YWluZXI6Si52QixDcnlwdG86Si52QixDcnlwdG9LZXk6Si52QixDU1M6Si52QixDU1NWYXJp
-YWJsZVJlZmVyZW5jZVZhbHVlOkoudkIsQ3VzdG9tRWxlbWVudFJlZ2lzdHJ5OkoudkIsRGF0YVRyYW5z
-ZmVyOkoudkIsRGF0YVRyYW5zZmVySXRlbTpKLnZCLERlcHJlY2F0ZWRTdG9yYWdlSW5mbzpKLnZCLERl
-cHJlY2F0ZWRTdG9yYWdlUXVvdGE6Si52QixEZXByZWNhdGlvblJlcG9ydDpKLnZCLERldGVjdGVkQmFy
-Y29kZTpKLnZCLERldGVjdGVkRmFjZTpKLnZCLERldGVjdGVkVGV4dDpKLnZCLERldmljZUFjY2VsZXJh
-dGlvbjpKLnZCLERldmljZVJvdGF0aW9uUmF0ZTpKLnZCLERpcmVjdG9yeVJlYWRlcjpKLnZCLERvY3Vt
-ZW50T3JTaGFkb3dSb290OkoudkIsRG9jdW1lbnRUaW1lbGluZTpKLnZCLERPTUVycm9yOkoudkIsRE9N
-SW1wbGVtZW50YXRpb246Si52QixJdGVyYXRvcjpKLnZCLERPTU1hdHJpeDpKLnZCLERPTU1hdHJpeFJl
-YWRPbmx5OkoudkIsRE9NUGFyc2VyOkoudkIsRE9NUG9pbnQ6Si52QixET01Qb2ludFJlYWRPbmx5Okou
-dkIsRE9NUXVhZDpKLnZCLERPTVN0cmluZ01hcDpKLnZCLEV4dGVybmFsOkoudkIsRmFjZURldGVjdG9y
-OkoudkIsRmVkZXJhdGVkQ3JlZGVudGlhbDpKLnZCLERPTUZpbGVTeXN0ZW06Si52QixGb250RmFjZTpK
-LnZCLEZvbnRGYWNlU291cmNlOkoudkIsRm9ybURhdGE6Si52QixHYW1lcGFkUG9zZTpKLnZCLEdlb2xv
-Y2F0aW9uOkoudkIsUG9zaXRpb246Si52QixIZWFkZXJzOkoudkIsSFRNTEh5cGVybGlua0VsZW1lbnRV
-dGlsczpKLnZCLElkbGVEZWFkbGluZTpKLnZCLEltYWdlQml0bWFwOkoudkIsSW1hZ2VCaXRtYXBSZW5k
-ZXJpbmdDb250ZXh0OkoudkIsSW1hZ2VDYXB0dXJlOkoudkIsSW5wdXREZXZpY2VDYXBhYmlsaXRpZXM6
-Si52QixJbnRlcnNlY3Rpb25PYnNlcnZlcjpKLnZCLEludGVyc2VjdGlvbk9ic2VydmVyRW50cnk6Si52
-QixJbnRlcnZlbnRpb25SZXBvcnQ6Si52QixLZXlmcmFtZUVmZmVjdDpKLnZCLEtleWZyYW1lRWZmZWN0
-UmVhZE9ubHk6Si52QixNZWRpYUNhcGFiaWxpdGllczpKLnZCLE1lZGlhQ2FwYWJpbGl0aWVzSW5mbzpK
-LnZCLE1lZGlhRGV2aWNlSW5mbzpKLnZCLE1lZGlhRXJyb3I6Si52QixNZWRpYUtleVN0YXR1c01hcDpK
-LnZCLE1lZGlhS2V5U3lzdGVtQWNjZXNzOkoudkIsTWVkaWFLZXlzOkoudkIsTWVkaWFLZXlzUG9saWN5
-OkoudkIsTWVkaWFNZXRhZGF0YTpKLnZCLE1lZGlhU2Vzc2lvbjpKLnZCLE1lZGlhU2V0dGluZ3NSYW5n
-ZTpKLnZCLE1lbW9yeUluZm86Si52QixNZXNzYWdlQ2hhbm5lbDpKLnZCLE1ldGFkYXRhOkoudkIsTXV0
-YXRpb25PYnNlcnZlcjpKLnZCLFdlYktpdE11dGF0aW9uT2JzZXJ2ZXI6Si52QixNdXRhdGlvblJlY29y
-ZDpKLnZCLE5hdmlnYXRpb25QcmVsb2FkTWFuYWdlcjpKLnZCLE5hdmlnYXRvcjpKLnZCLE5hdmlnYXRv
-ckF1dG9tYXRpb25JbmZvcm1hdGlvbjpKLnZCLE5hdmlnYXRvckNvbmN1cnJlbnRIYXJkd2FyZTpKLnZC
-LE5hdmlnYXRvckNvb2tpZXM6Si52QixOYXZpZ2F0b3JVc2VyTWVkaWFFcnJvcjpKLnZCLE5vZGVGaWx0
-ZXI6Si52QixOb2RlSXRlcmF0b3I6Si52QixOb25Eb2N1bWVudFR5cGVDaGlsZE5vZGU6Si52QixOb25F
-bGVtZW50UGFyZW50Tm9kZTpKLnZCLE5vbmNlZEVsZW1lbnQ6Si52QixPZmZzY3JlZW5DYW52YXNSZW5k
-ZXJpbmdDb250ZXh0MkQ6Si52QixPdmVyY29uc3RyYWluZWRFcnJvcjpKLnZCLFBhaW50UmVuZGVyaW5n
-Q29udGV4dDJEOkoudkIsUGFpbnRTaXplOkoudkIsUGFpbnRXb3JrbGV0R2xvYmFsU2NvcGU6Si52QixQ
-YXNzd29yZENyZWRlbnRpYWw6Si52QixQYXRoMkQ6Si52QixQYXltZW50QWRkcmVzczpKLnZCLFBheW1l
-bnRJbnN0cnVtZW50czpKLnZCLFBheW1lbnRNYW5hZ2VyOkoudkIsUGF5bWVudFJlc3BvbnNlOkoudkIs
-UGVyZm9ybWFuY2VFbnRyeTpKLnZCLFBlcmZvcm1hbmNlTG9uZ1Rhc2tUaW1pbmc6Si52QixQZXJmb3Jt
-YW5jZU1hcms6Si52QixQZXJmb3JtYW5jZU1lYXN1cmU6Si52QixQZXJmb3JtYW5jZU5hdmlnYXRpb246
-Si52QixQZXJmb3JtYW5jZU5hdmlnYXRpb25UaW1pbmc6Si52QixQZXJmb3JtYW5jZU9ic2VydmVyOkou
-dkIsUGVyZm9ybWFuY2VPYnNlcnZlckVudHJ5TGlzdDpKLnZCLFBlcmZvcm1hbmNlUGFpbnRUaW1pbmc6
-Si52QixQZXJmb3JtYW5jZVJlc291cmNlVGltaW5nOkoudkIsUGVyZm9ybWFuY2VTZXJ2ZXJUaW1pbmc6
-Si52QixQZXJmb3JtYW5jZVRpbWluZzpKLnZCLFBlcm1pc3Npb25zOkoudkIsUGhvdG9DYXBhYmlsaXRp
-ZXM6Si52QixQb3NpdGlvbkVycm9yOkoudkIsUHJlc2VudGF0aW9uOkoudkIsUHJlc2VudGF0aW9uUmVj
-ZWl2ZXI6Si52QixQdWJsaWNLZXlDcmVkZW50aWFsOkoudkIsUHVzaE1hbmFnZXI6Si52QixQdXNoTWVz
-c2FnZURhdGE6Si52QixQdXNoU3Vic2NyaXB0aW9uOkoudkIsUHVzaFN1YnNjcmlwdGlvbk9wdGlvbnM6
-Si52QixSYW5nZTpKLnZCLFJlbGF0ZWRBcHBsaWNhdGlvbjpKLnZCLFJlcG9ydEJvZHk6Si52QixSZXBv
-cnRpbmdPYnNlcnZlcjpKLnZCLFJlc2l6ZU9ic2VydmVyOkoudkIsUmVzaXplT2JzZXJ2ZXJFbnRyeTpK
-LnZCLFJUQ0NlcnRpZmljYXRlOkoudkIsUlRDSWNlQ2FuZGlkYXRlOkoudkIsbW96UlRDSWNlQ2FuZGlk
-YXRlOkoudkIsUlRDTGVnYWN5U3RhdHNSZXBvcnQ6Si52QixSVENSdHBDb250cmlidXRpbmdTb3VyY2U6
-Si52QixSVENSdHBSZWNlaXZlcjpKLnZCLFJUQ1J0cFNlbmRlcjpKLnZCLFJUQ1Nlc3Npb25EZXNjcmlw
-dGlvbjpKLnZCLG1velJUQ1Nlc3Npb25EZXNjcmlwdGlvbjpKLnZCLFJUQ1N0YXRzUmVzcG9uc2U6Si52
-QixTY3JlZW46Si52QixTY3JvbGxTdGF0ZTpKLnZCLFNjcm9sbFRpbWVsaW5lOkoudkIsU2VsZWN0aW9u
-OkoudkIsU2hhcmVkQXJyYXlCdWZmZXI6Si52QixTcGVlY2hSZWNvZ25pdGlvbkFsdGVybmF0aXZlOkou
-dkIsU3BlZWNoU3ludGhlc2lzVm9pY2U6Si52QixTdGF0aWNSYW5nZTpKLnZCLFN0b3JhZ2VNYW5hZ2Vy
-OkoudkIsU3R5bGVNZWRpYTpKLnZCLFN0eWxlUHJvcGVydHlNYXA6Si52QixTdHlsZVByb3BlcnR5TWFw
-UmVhZG9ubHk6Si52QixTeW5jTWFuYWdlcjpKLnZCLFRhc2tBdHRyaWJ1dGlvblRpbWluZzpKLnZCLFRl
-eHREZXRlY3RvcjpKLnZCLFRleHRNZXRyaWNzOkoudkIsVHJhY2tEZWZhdWx0OkoudkIsVHJlZVdhbGtl
-cjpKLnZCLFRydXN0ZWRIVE1MOkoudkIsVHJ1c3RlZFNjcmlwdFVSTDpKLnZCLFRydXN0ZWRVUkw6Si52
-QixVbmRlcmx5aW5nU291cmNlQmFzZTpKLnZCLFVSTFNlYXJjaFBhcmFtczpKLnZCLFZSQ29vcmRpbmF0
-ZVN5c3RlbTpKLnZCLFZSRGlzcGxheUNhcGFiaWxpdGllczpKLnZCLFZSRXllUGFyYW1ldGVyczpKLnZC
-LFZSRnJhbWVEYXRhOkoudkIsVlJGcmFtZU9mUmVmZXJlbmNlOkoudkIsVlJQb3NlOkoudkIsVlJTdGFn
-ZUJvdW5kczpKLnZCLFZSU3RhZ2VCb3VuZHNQb2ludDpKLnZCLFZSU3RhZ2VQYXJhbWV0ZXJzOkoudkIs
-VmFsaWRpdHlTdGF0ZTpKLnZCLFZpZGVvUGxheWJhY2tRdWFsaXR5OkoudkIsVmlkZW9UcmFjazpKLnZC
-LFZUVFJlZ2lvbjpKLnZCLFdpbmRvd0NsaWVudDpKLnZCLFdvcmtsZXRBbmltYXRpb246Si52QixXb3Jr
-bGV0R2xvYmFsU2NvcGU6Si52QixYUGF0aEV2YWx1YXRvcjpKLnZCLFhQYXRoRXhwcmVzc2lvbjpKLnZC
-LFhQYXRoTlNSZXNvbHZlcjpKLnZCLFhQYXRoUmVzdWx0OkoudkIsWE1MU2VyaWFsaXplcjpKLnZCLFhT
-TFRQcm9jZXNzb3I6Si52QixCbHVldG9vdGg6Si52QixCbHVldG9vdGhDaGFyYWN0ZXJpc3RpY1Byb3Bl
-cnRpZXM6Si52QixCbHVldG9vdGhSZW1vdGVHQVRUU2VydmVyOkoudkIsQmx1ZXRvb3RoUmVtb3RlR0FU
-VFNlcnZpY2U6Si52QixCbHVldG9vdGhVVUlEOkoudkIsQnVkZ2V0U2VydmljZTpKLnZCLENhY2hlOkou
-dkIsRE9NRmlsZVN5c3RlbVN5bmM6Si52QixEaXJlY3RvcnlFbnRyeVN5bmM6Si52QixEaXJlY3RvcnlS
-ZWFkZXJTeW5jOkoudkIsRW50cnlTeW5jOkoudkIsRmlsZUVudHJ5U3luYzpKLnZCLEZpbGVSZWFkZXJT
-eW5jOkoudkIsRmlsZVdyaXRlclN5bmM6Si52QixIVE1MQWxsQ29sbGVjdGlvbjpKLnZCLE1vam86Si52
-QixNb2pvSGFuZGxlOkoudkIsTW9qb1dhdGNoZXI6Si52QixORkM6Si52QixQYWdlUG9wdXBDb250cm9s
-bGVyOkoudkIsUmVwb3J0OkoudkIsUmVxdWVzdDpKLnZCLFJlc3BvbnNlOkoudkIsU3VidGxlQ3J5cHRv
-OkoudkIsVVNCQWx0ZXJuYXRlSW50ZXJmYWNlOkoudkIsVVNCQ29uZmlndXJhdGlvbjpKLnZCLFVTQkRl
-dmljZTpKLnZCLFVTQkVuZHBvaW50OkoudkIsVVNCSW5UcmFuc2ZlclJlc3VsdDpKLnZCLFVTQkludGVy
-ZmFjZTpKLnZCLFVTQklzb2Nocm9ub3VzSW5UcmFuc2ZlclBhY2tldDpKLnZCLFVTQklzb2Nocm9ub3Vz
-SW5UcmFuc2ZlclJlc3VsdDpKLnZCLFVTQklzb2Nocm9ub3VzT3V0VHJhbnNmZXJQYWNrZXQ6Si52QixV
-U0JJc29jaHJvbm91c091dFRyYW5zZmVyUmVzdWx0OkoudkIsVVNCT3V0VHJhbnNmZXJSZXN1bHQ6Si52
-QixXb3JrZXJMb2NhdGlvbjpKLnZCLFdvcmtlck5hdmlnYXRvcjpKLnZCLFdvcmtsZXQ6Si52QixJREJG
-YWN0b3J5OkoudkIsSURCSW5kZXg6Si52QixJREJPYmplY3RTdG9yZTpKLnZCLElEQk9ic2VydmVyOkou
-dkIsSURCT2JzZXJ2ZXJDaGFuZ2VzOkoudkIsU1ZHQW5pbWF0ZWRBbmdsZTpKLnZCLFNWR0FuaW1hdGVk
-Qm9vbGVhbjpKLnZCLFNWR0FuaW1hdGVkRW51bWVyYXRpb246Si52QixTVkdBbmltYXRlZEludGVnZXI6
-Si52QixTVkdBbmltYXRlZExlbmd0aDpKLnZCLFNWR0FuaW1hdGVkTGVuZ3RoTGlzdDpKLnZCLFNWR0Fu
-aW1hdGVkTnVtYmVyOkoudkIsU1ZHQW5pbWF0ZWROdW1iZXJMaXN0OkoudkIsU1ZHQW5pbWF0ZWRQcmVz
-ZXJ2ZUFzcGVjdFJhdGlvOkoudkIsU1ZHQW5pbWF0ZWRSZWN0OkoudkIsU1ZHQW5pbWF0ZWRTdHJpbmc6
-Si52QixTVkdBbmltYXRlZFRyYW5zZm9ybUxpc3Q6Si52QixTVkdNYXRyaXg6Si52QixTVkdQb2ludDpK
-LnZCLFNWR1ByZXNlcnZlQXNwZWN0UmF0aW86Si52QixTVkdSZWN0OkoudkIsU1ZHVW5pdFR5cGVzOkou
-dkIsQXVkaW9MaXN0ZW5lcjpKLnZCLEF1ZGlvVHJhY2s6Si52QixBdWRpb1dvcmtsZXRHbG9iYWxTY29w
-ZTpKLnZCLEF1ZGlvV29ya2xldFByb2Nlc3NvcjpKLnZCLFBlcmlvZGljV2F2ZTpKLnZCLFdlYkdMQWN0
-aXZlSW5mbzpKLnZCLEFOR0xFSW5zdGFuY2VkQXJyYXlzOkoudkIsQU5HTEVfaW5zdGFuY2VkX2FycmF5
-czpKLnZCLFdlYkdMQnVmZmVyOkoudkIsV2ViR0xDYW52YXM6Si52QixXZWJHTENvbG9yQnVmZmVyRmxv
-YXQ6Si52QixXZWJHTENvbXByZXNzZWRUZXh0dXJlQVNUQzpKLnZCLFdlYkdMQ29tcHJlc3NlZFRleHR1
-cmVBVEM6Si52QixXRUJHTF9jb21wcmVzc2VkX3RleHR1cmVfYXRjOkoudkIsV2ViR0xDb21wcmVzc2Vk
-VGV4dHVyZUVUQzE6Si52QixXRUJHTF9jb21wcmVzc2VkX3RleHR1cmVfZXRjMTpKLnZCLFdlYkdMQ29t
-cHJlc3NlZFRleHR1cmVFVEM6Si52QixXZWJHTENvbXByZXNzZWRUZXh0dXJlUFZSVEM6Si52QixXRUJH
-TF9jb21wcmVzc2VkX3RleHR1cmVfcHZydGM6Si52QixXZWJHTENvbXByZXNzZWRUZXh0dXJlUzNUQzpK
-LnZCLFdFQkdMX2NvbXByZXNzZWRfdGV4dHVyZV9zM3RjOkoudkIsV2ViR0xDb21wcmVzc2VkVGV4dHVy
-ZVMzVENzUkdCOkoudkIsV2ViR0xEZWJ1Z1JlbmRlcmVySW5mbzpKLnZCLFdFQkdMX2RlYnVnX3JlbmRl
-cmVyX2luZm86Si52QixXZWJHTERlYnVnU2hhZGVyczpKLnZCLFdFQkdMX2RlYnVnX3NoYWRlcnM6Si52
-QixXZWJHTERlcHRoVGV4dHVyZTpKLnZCLFdFQkdMX2RlcHRoX3RleHR1cmU6Si52QixXZWJHTERyYXdC
-dWZmZXJzOkoudkIsV0VCR0xfZHJhd19idWZmZXJzOkoudkIsRVhUc1JHQjpKLnZCLEVYVF9zUkdCOkou
-dkIsRVhUQmxlbmRNaW5NYXg6Si52QixFWFRfYmxlbmRfbWlubWF4OkoudkIsRVhUQ29sb3JCdWZmZXJG
-bG9hdDpKLnZCLEVYVENvbG9yQnVmZmVySGFsZkZsb2F0OkoudkIsRVhURGlzam9pbnRUaW1lclF1ZXJ5
-OkoudkIsRVhURGlzam9pbnRUaW1lclF1ZXJ5V2ViR0wyOkoudkIsRVhURnJhZ0RlcHRoOkoudkIsRVhU
-X2ZyYWdfZGVwdGg6Si52QixFWFRTaGFkZXJUZXh0dXJlTE9EOkoudkIsRVhUX3NoYWRlcl90ZXh0dXJl
-X2xvZDpKLnZCLEVYVFRleHR1cmVGaWx0ZXJBbmlzb3Ryb3BpYzpKLnZCLEVYVF90ZXh0dXJlX2ZpbHRl
-cl9hbmlzb3Ryb3BpYzpKLnZCLFdlYkdMRnJhbWVidWZmZXI6Si52QixXZWJHTEdldEJ1ZmZlclN1YkRh
-dGFBc3luYzpKLnZCLFdlYkdMTG9zZUNvbnRleHQ6Si52QixXZWJHTEV4dGVuc2lvbkxvc2VDb250ZXh0
-OkoudkIsV0VCR0xfbG9zZV9jb250ZXh0OkoudkIsT0VTRWxlbWVudEluZGV4VWludDpKLnZCLE9FU19l
-bGVtZW50X2luZGV4X3VpbnQ6Si52QixPRVNTdGFuZGFyZERlcml2YXRpdmVzOkoudkIsT0VTX3N0YW5k
-YXJkX2Rlcml2YXRpdmVzOkoudkIsT0VTVGV4dHVyZUZsb2F0OkoudkIsT0VTX3RleHR1cmVfZmxvYXQ6
-Si52QixPRVNUZXh0dXJlRmxvYXRMaW5lYXI6Si52QixPRVNfdGV4dHVyZV9mbG9hdF9saW5lYXI6Si52
-QixPRVNUZXh0dXJlSGFsZkZsb2F0OkoudkIsT0VTX3RleHR1cmVfaGFsZl9mbG9hdDpKLnZCLE9FU1Rl
-eHR1cmVIYWxmRmxvYXRMaW5lYXI6Si52QixPRVNfdGV4dHVyZV9oYWxmX2Zsb2F0X2xpbmVhcjpKLnZC
-LE9FU1ZlcnRleEFycmF5T2JqZWN0OkoudkIsT0VTX3ZlcnRleF9hcnJheV9vYmplY3Q6Si52QixXZWJH
-TFByb2dyYW06Si52QixXZWJHTFF1ZXJ5OkoudkIsV2ViR0xSZW5kZXJidWZmZXI6Si52QixXZWJHTFJl
-bmRlcmluZ0NvbnRleHQ6Si52QixXZWJHTDJSZW5kZXJpbmdDb250ZXh0OkoudkIsV2ViR0xTYW1wbGVy
-OkoudkIsV2ViR0xTaGFkZXI6Si52QixXZWJHTFNoYWRlclByZWNpc2lvbkZvcm1hdDpKLnZCLFdlYkdM
-U3luYzpKLnZCLFdlYkdMVGV4dHVyZTpKLnZCLFdlYkdMVGltZXJRdWVyeUVYVDpKLnZCLFdlYkdMVHJh
-bnNmb3JtRmVlZGJhY2s6Si52QixXZWJHTFVuaWZvcm1Mb2NhdGlvbjpKLnZCLFdlYkdMVmVydGV4QXJy
-YXlPYmplY3Q6Si52QixXZWJHTFZlcnRleEFycmF5T2JqZWN0T0VTOkoudkIsV2ViR0w6Si52QixXZWJH
-TDJSZW5kZXJpbmdDb250ZXh0QmFzZTpKLnZCLERhdGFiYXNlOkoudkIsU1FMRXJyb3I6Si52QixTUUxS
-ZXN1bHRTZXQ6Si52QixTUUxUcmFuc2FjdGlvbjpKLnZCLEFycmF5QnVmZmVyOkguV1osQXJyYXlCdWZm
-ZXJWaWV3OkguRVQsRGF0YVZpZXc6SC5kZixGbG9hdDMyQXJyYXk6SC5EZyxGbG9hdDY0QXJyYXk6SC5E
-ZyxJbnQxNkFycmF5OkgueGosSW50MzJBcnJheTpILmRFLEludDhBcnJheTpILlpBLFVpbnQxNkFycmF5
-Okgud2YsVWludDMyQXJyYXk6SC5QcSxVaW50OENsYW1wZWRBcnJheTpILmVFLENhbnZhc1BpeGVsQXJy
-YXk6SC5lRSxVaW50OEFycmF5OkguVjYsSFRNTEF1ZGlvRWxlbWVudDpXLnFFLEhUTUxCUkVsZW1lbnQ6
-Vy5xRSxIVE1MQ2FudmFzRWxlbWVudDpXLnFFLEhUTUxDb250ZW50RWxlbWVudDpXLnFFLEhUTUxETGlz
-dEVsZW1lbnQ6Vy5xRSxIVE1MRGF0YUxpc3RFbGVtZW50OlcucUUsSFRNTERldGFpbHNFbGVtZW50Olcu
-cUUsSFRNTERpYWxvZ0VsZW1lbnQ6Vy5xRSxIVE1MRGl2RWxlbWVudDpXLnFFLEhUTUxFbWJlZEVsZW1l
-bnQ6Vy5xRSxIVE1MRmllbGRTZXRFbGVtZW50OlcucUUsSFRNTEhSRWxlbWVudDpXLnFFLEhUTUxIZWFk
-RWxlbWVudDpXLnFFLEhUTUxIZWFkaW5nRWxlbWVudDpXLnFFLEhUTUxIdG1sRWxlbWVudDpXLnFFLEhU
-TUxJRnJhbWVFbGVtZW50OlcucUUsSFRNTEltYWdlRWxlbWVudDpXLnFFLEhUTUxMYWJlbEVsZW1lbnQ6
-Vy5xRSxIVE1MTGVnZW5kRWxlbWVudDpXLnFFLEhUTUxMaW5rRWxlbWVudDpXLnFFLEhUTUxNYXBFbGVt
-ZW50OlcucUUsSFRNTE1lZGlhRWxlbWVudDpXLnFFLEhUTUxNZW51RWxlbWVudDpXLnFFLEhUTUxNZXRh
-RWxlbWVudDpXLnFFLEhUTUxNb2RFbGVtZW50OlcucUUsSFRNTE9MaXN0RWxlbWVudDpXLnFFLEhUTUxP
-YmplY3RFbGVtZW50OlcucUUsSFRNTE9wdEdyb3VwRWxlbWVudDpXLnFFLEhUTUxQaWN0dXJlRWxlbWVu
-dDpXLnFFLEhUTUxQcmVFbGVtZW50OlcucUUsSFRNTFF1b3RlRWxlbWVudDpXLnFFLEhUTUxTY3JpcHRF
-bGVtZW50OlcucUUsSFRNTFNoYWRvd0VsZW1lbnQ6Vy5xRSxIVE1MU2xvdEVsZW1lbnQ6Vy5xRSxIVE1M
-U291cmNlRWxlbWVudDpXLnFFLEhUTUxTcGFuRWxlbWVudDpXLnFFLEhUTUxTdHlsZUVsZW1lbnQ6Vy5x
-RSxIVE1MVGFibGVDYXB0aW9uRWxlbWVudDpXLnFFLEhUTUxUYWJsZUNlbGxFbGVtZW50OlcucUUsSFRN
-TFRhYmxlRGF0YUNlbGxFbGVtZW50OlcucUUsSFRNTFRhYmxlSGVhZGVyQ2VsbEVsZW1lbnQ6Vy5xRSxI
-VE1MVGFibGVDb2xFbGVtZW50OlcucUUsSFRNTFRpbWVFbGVtZW50OlcucUUsSFRNTFRpdGxlRWxlbWVu
-dDpXLnFFLEhUTUxUcmFja0VsZW1lbnQ6Vy5xRSxIVE1MVUxpc3RFbGVtZW50OlcucUUsSFRNTFVua25v
-d25FbGVtZW50OlcucUUsSFRNTFZpZGVvRWxlbWVudDpXLnFFLEhUTUxEaXJlY3RvcnlFbGVtZW50Olcu
-cUUsSFRNTEZvbnRFbGVtZW50OlcucUUsSFRNTEZyYW1lRWxlbWVudDpXLnFFLEhUTUxGcmFtZVNldEVs
-ZW1lbnQ6Vy5xRSxIVE1MTWFycXVlZUVsZW1lbnQ6Vy5xRSxIVE1MRWxlbWVudDpXLnFFLEFjY2Vzc2li
-bGVOb2RlTGlzdDpXLlllLEhUTUxBbmNob3JFbGVtZW50OlcuR2gsSFRNTEFyZWFFbGVtZW50OlcuZlks
-SFRNTEJhc2VFbGVtZW50OlcubkIsQmxvYjpXLkF6LEJsdWV0b290aFJlbW90ZUdBVFREZXNjcmlwdG9y
-OlcuUFUsSFRNTEJvZHlFbGVtZW50OlcuUVAsSFRNTEJ1dHRvbkVsZW1lbnQ6Vy5JRixDREFUQVNlY3Rp
-b246Vy5ueCxDaGFyYWN0ZXJEYXRhOlcubngsQ29tbWVudDpXLm54LFByb2Nlc3NpbmdJbnN0cnVjdGlv
-bjpXLm54LFRleHQ6Vy5ueCxDU1NLZXl3b3JkVmFsdWU6Vy5SZCxDU1NOdW1lcmljVmFsdWU6Vy5rUixD
-U1NQZXJzcGVjdGl2ZTpXLlRmLENTU0NoYXJzZXRSdWxlOlcubHcsQ1NTQ29uZGl0aW9uUnVsZTpXLmx3
-LENTU0ZvbnRGYWNlUnVsZTpXLmx3LENTU0dyb3VwaW5nUnVsZTpXLmx3LENTU0ltcG9ydFJ1bGU6Vy5s
-dyxDU1NLZXlmcmFtZVJ1bGU6Vy5sdyxNb3pDU1NLZXlmcmFtZVJ1bGU6Vy5sdyxXZWJLaXRDU1NLZXlm
-cmFtZVJ1bGU6Vy5sdyxDU1NLZXlmcmFtZXNSdWxlOlcubHcsTW96Q1NTS2V5ZnJhbWVzUnVsZTpXLmx3
-LFdlYktpdENTU0tleWZyYW1lc1J1bGU6Vy5sdyxDU1NNZWRpYVJ1bGU6Vy5sdyxDU1NOYW1lc3BhY2VS
-dWxlOlcubHcsQ1NTUGFnZVJ1bGU6Vy5sdyxDU1NSdWxlOlcubHcsQ1NTU3R5bGVSdWxlOlcubHcsQ1NT
-U3VwcG9ydHNSdWxlOlcubHcsQ1NTVmlld3BvcnRSdWxlOlcubHcsQ1NTU3R5bGVEZWNsYXJhdGlvbjpX
-Lm9KLE1TU3R5bGVDU1NQcm9wZXJ0aWVzOlcub0osQ1NTMlByb3BlcnRpZXM6Vy5vSixDU1NJbWFnZVZh
-bHVlOlcuQncsQ1NTUG9zaXRpb25WYWx1ZTpXLkJ3LENTU1Jlc291cmNlVmFsdWU6Vy5CdyxDU1NVUkxJ
-bWFnZVZhbHVlOlcuQncsQ1NTU3R5bGVWYWx1ZTpXLkJ3LENTU01hdHJpeENvbXBvbmVudDpXLm80LENT
-U1JvdGF0aW9uOlcubzQsQ1NTU2NhbGU6Vy5vNCxDU1NTa2V3OlcubzQsQ1NTVHJhbnNsYXRpb246Vy5v
-NCxDU1NUcmFuc2Zvcm1Db21wb25lbnQ6Vy5vNCxDU1NUcmFuc2Zvcm1WYWx1ZTpXLkhTLENTU1VuaXRW
-YWx1ZTpXLlZvLENTU1VucGFyc2VkVmFsdWU6Vy5GaCxIVE1MRGF0YUVsZW1lbnQ6Vy5jeCxEYXRhVHJh
-bnNmZXJJdGVtTGlzdDpXLlNiLFhNTERvY3VtZW50OlcuUUYsRG9jdW1lbnQ6Vy5RRixET01FeGNlcHRp
-b246Vy5OaCxDbGllbnRSZWN0TGlzdDpXLkZ2LERPTVJlY3RMaXN0OlcuRnYsRE9NUmVjdFJlYWRPbmx5
-OlcuSUIsRE9NU3RyaW5nTGlzdDpXLllsLERPTVRva2VuTGlzdDpXLm43LEVsZW1lbnQ6Vy5jdixEaXJl
-Y3RvcnlFbnRyeTpXLlFJLEVudHJ5OlcuUUksRmlsZUVudHJ5OlcuUUksQWJvcnRQYXltZW50RXZlbnQ6
-Vy5lYSxBbmltYXRpb25FdmVudDpXLmVhLEFuaW1hdGlvblBsYXliYWNrRXZlbnQ6Vy5lYSxBcHBsaWNh
-dGlvbkNhY2hlRXJyb3JFdmVudDpXLmVhLEJhY2tncm91bmRGZXRjaENsaWNrRXZlbnQ6Vy5lYSxCYWNr
-Z3JvdW5kRmV0Y2hFdmVudDpXLmVhLEJhY2tncm91bmRGZXRjaEZhaWxFdmVudDpXLmVhLEJhY2tncm91
-bmRGZXRjaGVkRXZlbnQ6Vy5lYSxCZWZvcmVJbnN0YWxsUHJvbXB0RXZlbnQ6Vy5lYSxCZWZvcmVVbmxv
-YWRFdmVudDpXLmVhLEJsb2JFdmVudDpXLmVhLENhbk1ha2VQYXltZW50RXZlbnQ6Vy5lYSxDbGlwYm9h
-cmRFdmVudDpXLmVhLENsb3NlRXZlbnQ6Vy5lYSxDdXN0b21FdmVudDpXLmVhLERldmljZU1vdGlvbkV2
-ZW50OlcuZWEsRGV2aWNlT3JpZW50YXRpb25FdmVudDpXLmVhLEVycm9yRXZlbnQ6Vy5lYSxFeHRlbmRh
-YmxlRXZlbnQ6Vy5lYSxFeHRlbmRhYmxlTWVzc2FnZUV2ZW50OlcuZWEsRmV0Y2hFdmVudDpXLmVhLEZv
-bnRGYWNlU2V0TG9hZEV2ZW50OlcuZWEsRm9yZWlnbkZldGNoRXZlbnQ6Vy5lYSxHYW1lcGFkRXZlbnQ6
-Vy5lYSxIYXNoQ2hhbmdlRXZlbnQ6Vy5lYSxJbnN0YWxsRXZlbnQ6Vy5lYSxNZWRpYUVuY3J5cHRlZEV2
-ZW50OlcuZWEsTWVkaWFLZXlNZXNzYWdlRXZlbnQ6Vy5lYSxNZWRpYVF1ZXJ5TGlzdEV2ZW50OlcuZWEs
-TWVkaWFTdHJlYW1FdmVudDpXLmVhLE1lZGlhU3RyZWFtVHJhY2tFdmVudDpXLmVhLE1lc3NhZ2VFdmVu
-dDpXLmVhLE1JRElDb25uZWN0aW9uRXZlbnQ6Vy5lYSxNSURJTWVzc2FnZUV2ZW50OlcuZWEsTXV0YXRp
-b25FdmVudDpXLmVhLE5vdGlmaWNhdGlvbkV2ZW50OlcuZWEsUGFnZVRyYW5zaXRpb25FdmVudDpXLmVh
-LFBheW1lbnRSZXF1ZXN0RXZlbnQ6Vy5lYSxQYXltZW50UmVxdWVzdFVwZGF0ZUV2ZW50OlcuZWEsUG9w
-U3RhdGVFdmVudDpXLmVhLFByZXNlbnRhdGlvbkNvbm5lY3Rpb25BdmFpbGFibGVFdmVudDpXLmVhLFBy
-ZXNlbnRhdGlvbkNvbm5lY3Rpb25DbG9zZUV2ZW50OlcuZWEsUHJvbWlzZVJlamVjdGlvbkV2ZW50Olcu
-ZWEsUHVzaEV2ZW50OlcuZWEsUlRDRGF0YUNoYW5uZWxFdmVudDpXLmVhLFJUQ0RUTUZUb25lQ2hhbmdl
-RXZlbnQ6Vy5lYSxSVENQZWVyQ29ubmVjdGlvbkljZUV2ZW50OlcuZWEsUlRDVHJhY2tFdmVudDpXLmVh
-LFNlY3VyaXR5UG9saWN5VmlvbGF0aW9uRXZlbnQ6Vy5lYSxTZW5zb3JFcnJvckV2ZW50OlcuZWEsU3Bl
-ZWNoUmVjb2duaXRpb25FcnJvcjpXLmVhLFNwZWVjaFJlY29nbml0aW9uRXZlbnQ6Vy5lYSxTcGVlY2hT
-eW50aGVzaXNFdmVudDpXLmVhLFN5bmNFdmVudDpXLmVhLFRyYWNrRXZlbnQ6Vy5lYSxUcmFuc2l0aW9u
-RXZlbnQ6Vy5lYSxXZWJLaXRUcmFuc2l0aW9uRXZlbnQ6Vy5lYSxWUkRldmljZUV2ZW50OlcuZWEsVlJE
-aXNwbGF5RXZlbnQ6Vy5lYSxWUlNlc3Npb25FdmVudDpXLmVhLE1vam9JbnRlcmZhY2VSZXF1ZXN0RXZl
-bnQ6Vy5lYSxVU0JDb25uZWN0aW9uRXZlbnQ6Vy5lYSxJREJWZXJzaW9uQ2hhbmdlRXZlbnQ6Vy5lYSxB
-dWRpb1Byb2Nlc3NpbmdFdmVudDpXLmVhLE9mZmxpbmVBdWRpb0NvbXBsZXRpb25FdmVudDpXLmVhLFdl
-YkdMQ29udGV4dEV2ZW50OlcuZWEsRXZlbnQ6Vy5lYSxJbnB1dEV2ZW50OlcuZWEsQWJzb2x1dGVPcmll
-bnRhdGlvblNlbnNvcjpXLkQwLEFjY2VsZXJvbWV0ZXI6Vy5EMCxBY2Nlc3NpYmxlTm9kZTpXLkQwLEFt
-YmllbnRMaWdodFNlbnNvcjpXLkQwLEFuaW1hdGlvbjpXLkQwLEFwcGxpY2F0aW9uQ2FjaGU6Vy5EMCxE
-T01BcHBsaWNhdGlvbkNhY2hlOlcuRDAsT2ZmbGluZVJlc291cmNlTGlzdDpXLkQwLEJhY2tncm91bmRG
-ZXRjaFJlZ2lzdHJhdGlvbjpXLkQwLEJhdHRlcnlNYW5hZ2VyOlcuRDAsQnJvYWRjYXN0Q2hhbm5lbDpX
-LkQwLENhbnZhc0NhcHR1cmVNZWRpYVN0cmVhbVRyYWNrOlcuRDAsRXZlbnRTb3VyY2U6Vy5EMCxGaWxl
-UmVhZGVyOlcuRDAsRm9udEZhY2VTZXQ6Vy5EMCxHeXJvc2NvcGU6Vy5EMCxMaW5lYXJBY2NlbGVyYXRp
-b25TZW5zb3I6Vy5EMCxNYWduZXRvbWV0ZXI6Vy5EMCxNZWRpYURldmljZXM6Vy5EMCxNZWRpYUtleVNl
-c3Npb246Vy5EMCxNZWRpYVF1ZXJ5TGlzdDpXLkQwLE1lZGlhUmVjb3JkZXI6Vy5EMCxNZWRpYVNvdXJj
-ZTpXLkQwLE1lZGlhU3RyZWFtOlcuRDAsTWVkaWFTdHJlYW1UcmFjazpXLkQwLE1JRElBY2Nlc3M6Vy5E
-MCxNSURJSW5wdXQ6Vy5EMCxNSURJT3V0cHV0OlcuRDAsTUlESVBvcnQ6Vy5EMCxOZXR3b3JrSW5mb3Jt
-YXRpb246Vy5EMCxOb3RpZmljYXRpb246Vy5EMCxPZmZzY3JlZW5DYW52YXM6Vy5EMCxPcmllbnRhdGlv
-blNlbnNvcjpXLkQwLFBheW1lbnRSZXF1ZXN0OlcuRDAsUGVyZm9ybWFuY2U6Vy5EMCxQZXJtaXNzaW9u
-U3RhdHVzOlcuRDAsUHJlc2VudGF0aW9uQ29ubmVjdGlvbjpXLkQwLFByZXNlbnRhdGlvbkNvbm5lY3Rp
-b25MaXN0OlcuRDAsUHJlc2VudGF0aW9uUmVxdWVzdDpXLkQwLFJlbGF0aXZlT3JpZW50YXRpb25TZW5z
-b3I6Vy5EMCxSZW1vdGVQbGF5YmFjazpXLkQwLFJUQ0RhdGFDaGFubmVsOlcuRDAsRGF0YUNoYW5uZWw6
-Vy5EMCxSVENEVE1GU2VuZGVyOlcuRDAsUlRDUGVlckNvbm5lY3Rpb246Vy5EMCx3ZWJraXRSVENQZWVy
-Q29ubmVjdGlvbjpXLkQwLG1velJUQ1BlZXJDb25uZWN0aW9uOlcuRDAsU2NyZWVuT3JpZW50YXRpb246
-Vy5EMCxTZW5zb3I6Vy5EMCxTZXJ2aWNlV29ya2VyOlcuRDAsU2VydmljZVdvcmtlckNvbnRhaW5lcjpX
-LkQwLFNlcnZpY2VXb3JrZXJSZWdpc3RyYXRpb246Vy5EMCxTaGFyZWRXb3JrZXI6Vy5EMCxTcGVlY2hS
-ZWNvZ25pdGlvbjpXLkQwLFNwZWVjaFN5bnRoZXNpczpXLkQwLFNwZWVjaFN5bnRoZXNpc1V0dGVyYW5j
-ZTpXLkQwLFZSOlcuRDAsVlJEZXZpY2U6Vy5EMCxWUkRpc3BsYXk6Vy5EMCxWUlNlc3Npb246Vy5EMCxW
-aXN1YWxWaWV3cG9ydDpXLkQwLFdlYlNvY2tldDpXLkQwLFdvcmtlcjpXLkQwLFdvcmtlclBlcmZvcm1h
-bmNlOlcuRDAsQmx1ZXRvb3RoRGV2aWNlOlcuRDAsQmx1ZXRvb3RoUmVtb3RlR0FUVENoYXJhY3Rlcmlz
-dGljOlcuRDAsQ2xpcGJvYXJkOlcuRDAsTW9qb0ludGVyZmFjZUludGVyY2VwdG9yOlcuRDAsVVNCOlcu
-RDAsSURCRGF0YWJhc2U6Vy5EMCxJREJPcGVuREJSZXF1ZXN0OlcuRDAsSURCVmVyc2lvbkNoYW5nZVJl
-cXVlc3Q6Vy5EMCxJREJSZXF1ZXN0OlcuRDAsSURCVHJhbnNhY3Rpb246Vy5EMCxBbmFseXNlck5vZGU6
-Vy5EMCxSZWFsdGltZUFuYWx5c2VyTm9kZTpXLkQwLEF1ZGlvQnVmZmVyU291cmNlTm9kZTpXLkQwLEF1
-ZGlvRGVzdGluYXRpb25Ob2RlOlcuRDAsQXVkaW9Ob2RlOlcuRDAsQXVkaW9TY2hlZHVsZWRTb3VyY2VO
-b2RlOlcuRDAsQXVkaW9Xb3JrbGV0Tm9kZTpXLkQwLEJpcXVhZEZpbHRlck5vZGU6Vy5EMCxDaGFubmVs
-TWVyZ2VyTm9kZTpXLkQwLEF1ZGlvQ2hhbm5lbE1lcmdlcjpXLkQwLENoYW5uZWxTcGxpdHRlck5vZGU6
-Vy5EMCxBdWRpb0NoYW5uZWxTcGxpdHRlcjpXLkQwLENvbnN0YW50U291cmNlTm9kZTpXLkQwLENvbnZv
-bHZlck5vZGU6Vy5EMCxEZWxheU5vZGU6Vy5EMCxEeW5hbWljc0NvbXByZXNzb3JOb2RlOlcuRDAsR2Fp
-bk5vZGU6Vy5EMCxBdWRpb0dhaW5Ob2RlOlcuRDAsSUlSRmlsdGVyTm9kZTpXLkQwLE1lZGlhRWxlbWVu
-dEF1ZGlvU291cmNlTm9kZTpXLkQwLE1lZGlhU3RyZWFtQXVkaW9EZXN0aW5hdGlvbk5vZGU6Vy5EMCxN
-ZWRpYVN0cmVhbUF1ZGlvU291cmNlTm9kZTpXLkQwLE9zY2lsbGF0b3JOb2RlOlcuRDAsT3NjaWxsYXRv
-cjpXLkQwLFBhbm5lck5vZGU6Vy5EMCxBdWRpb1Bhbm5lck5vZGU6Vy5EMCx3ZWJraXRBdWRpb1Bhbm5l
-ck5vZGU6Vy5EMCxTY3JpcHRQcm9jZXNzb3JOb2RlOlcuRDAsSmF2YVNjcmlwdEF1ZGlvTm9kZTpXLkQw
-LFN0ZXJlb1Bhbm5lck5vZGU6Vy5EMCxXYXZlU2hhcGVyTm9kZTpXLkQwLEV2ZW50VGFyZ2V0OlcuRDAs
-RmlsZTpXLlQ1LEZpbGVMaXN0OlcuWFYsRmlsZVdyaXRlcjpXLndKLEhUTUxGb3JtRWxlbWVudDpXLmg0
-LEdhbWVwYWQ6Vy5HTyxHYW1lcGFkQnV0dG9uOlcuSkMsSGlzdG9yeTpXLmJyLEhUTUxDb2xsZWN0aW9u
-OlcueG4sSFRNTEZvcm1Db250cm9sc0NvbGxlY3Rpb246Vy54bixIVE1MT3B0aW9uc0NvbGxlY3Rpb246
-Vy54bixIVE1MRG9jdW1lbnQ6Vy5WYixYTUxIdHRwUmVxdWVzdDpXLk83LFhNTEh0dHBSZXF1ZXN0VXBs
-b2FkOlcud2EsWE1MSHR0cFJlcXVlc3RFdmVudFRhcmdldDpXLndhLEltYWdlRGF0YTpXLlNnLEhUTUxJ
-bnB1dEVsZW1lbnQ6Vy5KSyxLZXlib2FyZEV2ZW50OlcuSEwsSFRNTExJRWxlbWVudDpXLndQLExvY2F0
-aW9uOlcudTgsTWVkaWFMaXN0OlcuejYsTWVzc2FnZVBvcnQ6Vy5sSyxIVE1MTWV0ZXJFbGVtZW50Olcu
-UWIsTUlESUlucHV0TWFwOlcuUzAsTUlESU91dHB1dE1hcDpXLnoyLE1pbWVUeXBlOlcuQVcsTWltZVR5
-cGVBcnJheTpXLkRNLE1vdXNlRXZlbnQ6Vy5BaixEcmFnRXZlbnQ6Vy5BaixQb2ludGVyRXZlbnQ6Vy5B
-aixXaGVlbEV2ZW50OlcuQWosRG9jdW1lbnRGcmFnbWVudDpXLnVILFNoYWRvd1Jvb3Q6Vy51SCxEb2N1
-bWVudFR5cGU6Vy51SCxOb2RlOlcudUgsTm9kZUxpc3Q6Vy5CSCxSYWRpb05vZGVMaXN0OlcuQkgsSFRN
-TE9wdGlvbkVsZW1lbnQ6Vy5RbCxIVE1MT3V0cHV0RWxlbWVudDpXLkdYLEhUTUxQYXJhZ3JhcGhFbGVt
-ZW50OlcuU04sSFRNTFBhcmFtRWxlbWVudDpXLkhELFBsdWdpbjpXLmNsLFBsdWdpbkFycmF5OlcuRXYs
-UHJlc2VudGF0aW9uQXZhaWxhYmlsaXR5OlcuTHIsSFRNTFByb2dyZXNzRWxlbWVudDpXLktSLFByb2dy
-ZXNzRXZlbnQ6Vy5ldyxSZXNvdXJjZVByb2dyZXNzRXZlbnQ6Vy5ldyxSVENTdGF0c1JlcG9ydDpXLnA4
-LEhUTUxTZWxlY3RFbGVtZW50OlcubHAsU291cmNlQnVmZmVyOlcuU1YsU291cmNlQnVmZmVyTGlzdDpX
-Lk1rLFNwZWVjaEdyYW1tYXI6Vy5ZNCxTcGVlY2hHcmFtbWFyTGlzdDpXLk5uLFNwZWVjaFJlY29nbml0
-aW9uUmVzdWx0OlcubDgsU3RvcmFnZTpXLkFzLFN0b3JhZ2VFdmVudDpXLmJrLENTU1N0eWxlU2hlZXQ6
-Vy5XVyxTdHlsZVNoZWV0OlcuV1csSFRNTFRhYmxlRWxlbWVudDpXLlRiLEhUTUxUYWJsZVJvd0VsZW1l
-bnQ6Vy5JdixIVE1MVGFibGVTZWN0aW9uRWxlbWVudDpXLkJULEhUTUxUZW1wbGF0ZUVsZW1lbnQ6Vy5m
-WCxIVE1MVGV4dEFyZWFFbGVtZW50OlcuRkIsVGV4dFRyYWNrOlcuQTEsVGV4dFRyYWNrQ3VlOlcuTU4s
-VlRUQ3VlOlcuTU4sVGV4dFRyYWNrQ3VlTGlzdDpXLlgwLFRleHRUcmFja0xpc3Q6Vy5uSixUaW1lUmFu
-Z2VzOlcubXosVG91Y2g6Vy5hMyxUb3VjaExpc3Q6Vy5jaSxUcmFja0RlZmF1bHRMaXN0OlcuY24sQ29t
-cG9zaXRpb25FdmVudDpXLnc2LEZvY3VzRXZlbnQ6Vy53NixUZXh0RXZlbnQ6Vy53NixUb3VjaEV2ZW50
-OlcudzYsVUlFdmVudDpXLnc2LFVSTDpXLkZqLFZpZGVvVHJhY2tMaXN0OlcudkYsV2luZG93OlcuT2ks
-RE9NV2luZG93OlcuT2ksRGVkaWNhdGVkV29ya2VyR2xvYmFsU2NvcGU6Vy5DbSxTZXJ2aWNlV29ya2Vy
-R2xvYmFsU2NvcGU6Vy5DbSxTaGFyZWRXb3JrZXJHbG9iYWxTY29wZTpXLkNtLFdvcmtlckdsb2JhbFNj
-b3BlOlcuQ20sQXR0cjpXLkNRLENTU1J1bGVMaXN0OlcuUFIsQ2xpZW50UmVjdDpXLnc0LERPTVJlY3Q6
-Vy53NCxHYW1lcGFkTGlzdDpXLkYyLE5hbWVkTm9kZU1hcDpXLnJoLE1vek5hbWVkQXR0ck1hcDpXLnJo
-LFNwZWVjaFJlY29nbml0aW9uUmVzdWx0TGlzdDpXLkxPLFN0eWxlU2hlZXRMaXN0OlcuYjEsSURCQ3Vy
-c29yOlAuVzIsSURCQ3Vyc29yV2l0aFZhbHVlOlAuZTMsSURCS2V5UmFuZ2U6UC5oRixJREJPYnNlcnZh
-dGlvbjpQLkJWLFNWR0FuZ2xlOlAudWosU1ZHTGVuZ3RoOlAueDAsU1ZHTGVuZ3RoTGlzdDpQLnE2LFNW
-R051bWJlcjpQLnVQLFNWR051bWJlckxpc3Q6UC5meixTVkdQb2ludExpc3Q6UC5FRCxTVkdTY3JpcHRF
-bGVtZW50OlAubmQsU1ZHU3RyaW5nTGlzdDpQLktxLFNWR0FFbGVtZW50OlAuZDUsU1ZHQW5pbWF0ZUVs
-ZW1lbnQ6UC5kNSxTVkdBbmltYXRlTW90aW9uRWxlbWVudDpQLmQ1LFNWR0FuaW1hdGVUcmFuc2Zvcm1F
-bGVtZW50OlAuZDUsU1ZHQW5pbWF0aW9uRWxlbWVudDpQLmQ1LFNWR0NpcmNsZUVsZW1lbnQ6UC5kNSxT
-VkdDbGlwUGF0aEVsZW1lbnQ6UC5kNSxTVkdEZWZzRWxlbWVudDpQLmQ1LFNWR0Rlc2NFbGVtZW50OlAu
-ZDUsU1ZHRGlzY2FyZEVsZW1lbnQ6UC5kNSxTVkdFbGxpcHNlRWxlbWVudDpQLmQ1LFNWR0ZFQmxlbmRF
-bGVtZW50OlAuZDUsU1ZHRkVDb2xvck1hdHJpeEVsZW1lbnQ6UC5kNSxTVkdGRUNvbXBvbmVudFRyYW5z
-ZmVyRWxlbWVudDpQLmQ1LFNWR0ZFQ29tcG9zaXRlRWxlbWVudDpQLmQ1LFNWR0ZFQ29udm9sdmVNYXRy
-aXhFbGVtZW50OlAuZDUsU1ZHRkVEaWZmdXNlTGlnaHRpbmdFbGVtZW50OlAuZDUsU1ZHRkVEaXNwbGFj
-ZW1lbnRNYXBFbGVtZW50OlAuZDUsU1ZHRkVEaXN0YW50TGlnaHRFbGVtZW50OlAuZDUsU1ZHRkVGbG9v
-ZEVsZW1lbnQ6UC5kNSxTVkdGRUZ1bmNBRWxlbWVudDpQLmQ1LFNWR0ZFRnVuY0JFbGVtZW50OlAuZDUs
-U1ZHRkVGdW5jR0VsZW1lbnQ6UC5kNSxTVkdGRUZ1bmNSRWxlbWVudDpQLmQ1LFNWR0ZFR2F1c3NpYW5C
-bHVyRWxlbWVudDpQLmQ1LFNWR0ZFSW1hZ2VFbGVtZW50OlAuZDUsU1ZHRkVNZXJnZUVsZW1lbnQ6UC5k
-NSxTVkdGRU1lcmdlTm9kZUVsZW1lbnQ6UC5kNSxTVkdGRU1vcnBob2xvZ3lFbGVtZW50OlAuZDUsU1ZH
-RkVPZmZzZXRFbGVtZW50OlAuZDUsU1ZHRkVQb2ludExpZ2h0RWxlbWVudDpQLmQ1LFNWR0ZFU3BlY3Vs
-YXJMaWdodGluZ0VsZW1lbnQ6UC5kNSxTVkdGRVNwb3RMaWdodEVsZW1lbnQ6UC5kNSxTVkdGRVRpbGVF
-bGVtZW50OlAuZDUsU1ZHRkVUdXJidWxlbmNlRWxlbWVudDpQLmQ1LFNWR0ZpbHRlckVsZW1lbnQ6UC5k
-NSxTVkdGb3JlaWduT2JqZWN0RWxlbWVudDpQLmQ1LFNWR0dFbGVtZW50OlAuZDUsU1ZHR2VvbWV0cnlF
-bGVtZW50OlAuZDUsU1ZHR3JhcGhpY3NFbGVtZW50OlAuZDUsU1ZHSW1hZ2VFbGVtZW50OlAuZDUsU1ZH
-TGluZUVsZW1lbnQ6UC5kNSxTVkdMaW5lYXJHcmFkaWVudEVsZW1lbnQ6UC5kNSxTVkdNYXJrZXJFbGVt
-ZW50OlAuZDUsU1ZHTWFza0VsZW1lbnQ6UC5kNSxTVkdNZXRhZGF0YUVsZW1lbnQ6UC5kNSxTVkdQYXRo
-RWxlbWVudDpQLmQ1LFNWR1BhdHRlcm5FbGVtZW50OlAuZDUsU1ZHUG9seWdvbkVsZW1lbnQ6UC5kNSxT
-VkdQb2x5bGluZUVsZW1lbnQ6UC5kNSxTVkdSYWRpYWxHcmFkaWVudEVsZW1lbnQ6UC5kNSxTVkdSZWN0
-RWxlbWVudDpQLmQ1LFNWR1NldEVsZW1lbnQ6UC5kNSxTVkdTdG9wRWxlbWVudDpQLmQ1LFNWR1N0eWxl
-RWxlbWVudDpQLmQ1LFNWR1NWR0VsZW1lbnQ6UC5kNSxTVkdTd2l0Y2hFbGVtZW50OlAuZDUsU1ZHU3lt
-Ym9sRWxlbWVudDpQLmQ1LFNWR1RTcGFuRWxlbWVudDpQLmQ1LFNWR1RleHRDb250ZW50RWxlbWVudDpQ
-LmQ1LFNWR1RleHRFbGVtZW50OlAuZDUsU1ZHVGV4dFBhdGhFbGVtZW50OlAuZDUsU1ZHVGV4dFBvc2l0
-aW9uaW5nRWxlbWVudDpQLmQ1LFNWR1RpdGxlRWxlbWVudDpQLmQ1LFNWR1VzZUVsZW1lbnQ6UC5kNSxT
-VkdWaWV3RWxlbWVudDpQLmQ1LFNWR0dyYWRpZW50RWxlbWVudDpQLmQ1LFNWR0NvbXBvbmVudFRyYW5z
-ZmVyRnVuY3Rpb25FbGVtZW50OlAuZDUsU1ZHRkVEcm9wU2hhZG93RWxlbWVudDpQLmQ1LFNWR01QYXRo
-RWxlbWVudDpQLmQ1LFNWR0VsZW1lbnQ6UC5kNSxTVkdUcmFuc2Zvcm06UC56WSxTVkdUcmFuc2Zvcm1M
-aXN0OlAuTkMsQXVkaW9CdWZmZXI6UC5yMixBdWRpb1BhcmFtOlAuck8sQXVkaW9QYXJhbU1hcDpQLno4
-LEF1ZGlvVHJhY2tMaXN0OlAuZm8sQXVkaW9Db250ZXh0OlAuVjgsd2Via2l0QXVkaW9Db250ZXh0OlAu
-VjgsQmFzZUF1ZGlvQ29udGV4dDpQLlY4LE9mZmxpbmVBdWRpb0NvbnRleHQ6UC5HbixTUUxSZXN1bHRT
-ZXRSb3dMaXN0OlAuRm59KQpodW5rSGVscGVycy5zZXRPclVwZGF0ZUxlYWZUYWdzKHtBbmltYXRpb25F
-ZmZlY3RSZWFkT25seTp0cnVlLEFuaW1hdGlvbkVmZmVjdFRpbWluZzp0cnVlLEFuaW1hdGlvbkVmZmVj
-dFRpbWluZ1JlYWRPbmx5OnRydWUsQW5pbWF0aW9uVGltZWxpbmU6dHJ1ZSxBbmltYXRpb25Xb3JrbGV0
-R2xvYmFsU2NvcGU6dHJ1ZSxBdXRoZW50aWNhdG9yQXNzZXJ0aW9uUmVzcG9uc2U6dHJ1ZSxBdXRoZW50
-aWNhdG9yQXR0ZXN0YXRpb25SZXNwb25zZTp0cnVlLEF1dGhlbnRpY2F0b3JSZXNwb25zZTp0cnVlLEJh
-Y2tncm91bmRGZXRjaEZldGNoOnRydWUsQmFja2dyb3VuZEZldGNoTWFuYWdlcjp0cnVlLEJhY2tncm91
-bmRGZXRjaFNldHRsZWRGZXRjaDp0cnVlLEJhclByb3A6dHJ1ZSxCYXJjb2RlRGV0ZWN0b3I6dHJ1ZSxC
-b2R5OnRydWUsQnVkZ2V0U3RhdGU6dHJ1ZSxDYWNoZVN0b3JhZ2U6dHJ1ZSxDYW52YXNHcmFkaWVudDp0
-cnVlLENhbnZhc1BhdHRlcm46dHJ1ZSxDYW52YXNSZW5kZXJpbmdDb250ZXh0MkQ6dHJ1ZSxDbGllbnQ6
-dHJ1ZSxDbGllbnRzOnRydWUsQ29va2llU3RvcmU6dHJ1ZSxDb29yZGluYXRlczp0cnVlLENyZWRlbnRp
-YWw6dHJ1ZSxDcmVkZW50aWFsVXNlckRhdGE6dHJ1ZSxDcmVkZW50aWFsc0NvbnRhaW5lcjp0cnVlLENy
-eXB0bzp0cnVlLENyeXB0b0tleTp0cnVlLENTUzp0cnVlLENTU1ZhcmlhYmxlUmVmZXJlbmNlVmFsdWU6
-dHJ1ZSxDdXN0b21FbGVtZW50UmVnaXN0cnk6dHJ1ZSxEYXRhVHJhbnNmZXI6dHJ1ZSxEYXRhVHJhbnNm
-ZXJJdGVtOnRydWUsRGVwcmVjYXRlZFN0b3JhZ2VJbmZvOnRydWUsRGVwcmVjYXRlZFN0b3JhZ2VRdW90
-YTp0cnVlLERlcHJlY2F0aW9uUmVwb3J0OnRydWUsRGV0ZWN0ZWRCYXJjb2RlOnRydWUsRGV0ZWN0ZWRG
-YWNlOnRydWUsRGV0ZWN0ZWRUZXh0OnRydWUsRGV2aWNlQWNjZWxlcmF0aW9uOnRydWUsRGV2aWNlUm90
-YXRpb25SYXRlOnRydWUsRGlyZWN0b3J5UmVhZGVyOnRydWUsRG9jdW1lbnRPclNoYWRvd1Jvb3Q6dHJ1
-ZSxEb2N1bWVudFRpbWVsaW5lOnRydWUsRE9NRXJyb3I6dHJ1ZSxET01JbXBsZW1lbnRhdGlvbjp0cnVl
-LEl0ZXJhdG9yOnRydWUsRE9NTWF0cml4OnRydWUsRE9NTWF0cml4UmVhZE9ubHk6dHJ1ZSxET01QYXJz
-ZXI6dHJ1ZSxET01Qb2ludDp0cnVlLERPTVBvaW50UmVhZE9ubHk6dHJ1ZSxET01RdWFkOnRydWUsRE9N
-U3RyaW5nTWFwOnRydWUsRXh0ZXJuYWw6dHJ1ZSxGYWNlRGV0ZWN0b3I6dHJ1ZSxGZWRlcmF0ZWRDcmVk
-ZW50aWFsOnRydWUsRE9NRmlsZVN5c3RlbTp0cnVlLEZvbnRGYWNlOnRydWUsRm9udEZhY2VTb3VyY2U6
-dHJ1ZSxGb3JtRGF0YTp0cnVlLEdhbWVwYWRQb3NlOnRydWUsR2VvbG9jYXRpb246dHJ1ZSxQb3NpdGlv
-bjp0cnVlLEhlYWRlcnM6dHJ1ZSxIVE1MSHlwZXJsaW5rRWxlbWVudFV0aWxzOnRydWUsSWRsZURlYWRs
-aW5lOnRydWUsSW1hZ2VCaXRtYXA6dHJ1ZSxJbWFnZUJpdG1hcFJlbmRlcmluZ0NvbnRleHQ6dHJ1ZSxJ
-bWFnZUNhcHR1cmU6dHJ1ZSxJbnB1dERldmljZUNhcGFiaWxpdGllczp0cnVlLEludGVyc2VjdGlvbk9i
-c2VydmVyOnRydWUsSW50ZXJzZWN0aW9uT2JzZXJ2ZXJFbnRyeTp0cnVlLEludGVydmVudGlvblJlcG9y
-dDp0cnVlLEtleWZyYW1lRWZmZWN0OnRydWUsS2V5ZnJhbWVFZmZlY3RSZWFkT25seTp0cnVlLE1lZGlh
-Q2FwYWJpbGl0aWVzOnRydWUsTWVkaWFDYXBhYmlsaXRpZXNJbmZvOnRydWUsTWVkaWFEZXZpY2VJbmZv
-OnRydWUsTWVkaWFFcnJvcjp0cnVlLE1lZGlhS2V5U3RhdHVzTWFwOnRydWUsTWVkaWFLZXlTeXN0ZW1B
-Y2Nlc3M6dHJ1ZSxNZWRpYUtleXM6dHJ1ZSxNZWRpYUtleXNQb2xpY3k6dHJ1ZSxNZWRpYU1ldGFkYXRh
-OnRydWUsTWVkaWFTZXNzaW9uOnRydWUsTWVkaWFTZXR0aW5nc1JhbmdlOnRydWUsTWVtb3J5SW5mbzp0
-cnVlLE1lc3NhZ2VDaGFubmVsOnRydWUsTWV0YWRhdGE6dHJ1ZSxNdXRhdGlvbk9ic2VydmVyOnRydWUs
-V2ViS2l0TXV0YXRpb25PYnNlcnZlcjp0cnVlLE11dGF0aW9uUmVjb3JkOnRydWUsTmF2aWdhdGlvblBy
-ZWxvYWRNYW5hZ2VyOnRydWUsTmF2aWdhdG9yOnRydWUsTmF2aWdhdG9yQXV0b21hdGlvbkluZm9ybWF0
-aW9uOnRydWUsTmF2aWdhdG9yQ29uY3VycmVudEhhcmR3YXJlOnRydWUsTmF2aWdhdG9yQ29va2llczp0
-cnVlLE5hdmlnYXRvclVzZXJNZWRpYUVycm9yOnRydWUsTm9kZUZpbHRlcjp0cnVlLE5vZGVJdGVyYXRv
-cjp0cnVlLE5vbkRvY3VtZW50VHlwZUNoaWxkTm9kZTp0cnVlLE5vbkVsZW1lbnRQYXJlbnROb2RlOnRy
-dWUsTm9uY2VkRWxlbWVudDp0cnVlLE9mZnNjcmVlbkNhbnZhc1JlbmRlcmluZ0NvbnRleHQyRDp0cnVl
-LE92ZXJjb25zdHJhaW5lZEVycm9yOnRydWUsUGFpbnRSZW5kZXJpbmdDb250ZXh0MkQ6dHJ1ZSxQYWlu
-dFNpemU6dHJ1ZSxQYWludFdvcmtsZXRHbG9iYWxTY29wZTp0cnVlLFBhc3N3b3JkQ3JlZGVudGlhbDp0
-cnVlLFBhdGgyRDp0cnVlLFBheW1lbnRBZGRyZXNzOnRydWUsUGF5bWVudEluc3RydW1lbnRzOnRydWUs
-UGF5bWVudE1hbmFnZXI6dHJ1ZSxQYXltZW50UmVzcG9uc2U6dHJ1ZSxQZXJmb3JtYW5jZUVudHJ5OnRy
-dWUsUGVyZm9ybWFuY2VMb25nVGFza1RpbWluZzp0cnVlLFBlcmZvcm1hbmNlTWFyazp0cnVlLFBlcmZv
-cm1hbmNlTWVhc3VyZTp0cnVlLFBlcmZvcm1hbmNlTmF2aWdhdGlvbjp0cnVlLFBlcmZvcm1hbmNlTmF2
-aWdhdGlvblRpbWluZzp0cnVlLFBlcmZvcm1hbmNlT2JzZXJ2ZXI6dHJ1ZSxQZXJmb3JtYW5jZU9ic2Vy
-dmVyRW50cnlMaXN0OnRydWUsUGVyZm9ybWFuY2VQYWludFRpbWluZzp0cnVlLFBlcmZvcm1hbmNlUmVz
-b3VyY2VUaW1pbmc6dHJ1ZSxQZXJmb3JtYW5jZVNlcnZlclRpbWluZzp0cnVlLFBlcmZvcm1hbmNlVGlt
-aW5nOnRydWUsUGVybWlzc2lvbnM6dHJ1ZSxQaG90b0NhcGFiaWxpdGllczp0cnVlLFBvc2l0aW9uRXJy
-b3I6dHJ1ZSxQcmVzZW50YXRpb246dHJ1ZSxQcmVzZW50YXRpb25SZWNlaXZlcjp0cnVlLFB1YmxpY0tl
-eUNyZWRlbnRpYWw6dHJ1ZSxQdXNoTWFuYWdlcjp0cnVlLFB1c2hNZXNzYWdlRGF0YTp0cnVlLFB1c2hT
-dWJzY3JpcHRpb246dHJ1ZSxQdXNoU3Vic2NyaXB0aW9uT3B0aW9uczp0cnVlLFJhbmdlOnRydWUsUmVs
-YXRlZEFwcGxpY2F0aW9uOnRydWUsUmVwb3J0Qm9keTp0cnVlLFJlcG9ydGluZ09ic2VydmVyOnRydWUs
-UmVzaXplT2JzZXJ2ZXI6dHJ1ZSxSZXNpemVPYnNlcnZlckVudHJ5OnRydWUsUlRDQ2VydGlmaWNhdGU6
-dHJ1ZSxSVENJY2VDYW5kaWRhdGU6dHJ1ZSxtb3pSVENJY2VDYW5kaWRhdGU6dHJ1ZSxSVENMZWdhY3lT
-dGF0c1JlcG9ydDp0cnVlLFJUQ1J0cENvbnRyaWJ1dGluZ1NvdXJjZTp0cnVlLFJUQ1J0cFJlY2VpdmVy
-OnRydWUsUlRDUnRwU2VuZGVyOnRydWUsUlRDU2Vzc2lvbkRlc2NyaXB0aW9uOnRydWUsbW96UlRDU2Vz
-c2lvbkRlc2NyaXB0aW9uOnRydWUsUlRDU3RhdHNSZXNwb25zZTp0cnVlLFNjcmVlbjp0cnVlLFNjcm9s
-bFN0YXRlOnRydWUsU2Nyb2xsVGltZWxpbmU6dHJ1ZSxTZWxlY3Rpb246dHJ1ZSxTaGFyZWRBcnJheUJ1
-ZmZlcjp0cnVlLFNwZWVjaFJlY29nbml0aW9uQWx0ZXJuYXRpdmU6dHJ1ZSxTcGVlY2hTeW50aGVzaXNW
-b2ljZTp0cnVlLFN0YXRpY1JhbmdlOnRydWUsU3RvcmFnZU1hbmFnZXI6dHJ1ZSxTdHlsZU1lZGlhOnRy
-dWUsU3R5bGVQcm9wZXJ0eU1hcDp0cnVlLFN0eWxlUHJvcGVydHlNYXBSZWFkb25seTp0cnVlLFN5bmNN
-YW5hZ2VyOnRydWUsVGFza0F0dHJpYnV0aW9uVGltaW5nOnRydWUsVGV4dERldGVjdG9yOnRydWUsVGV4
-dE1ldHJpY3M6dHJ1ZSxUcmFja0RlZmF1bHQ6dHJ1ZSxUcmVlV2Fsa2VyOnRydWUsVHJ1c3RlZEhUTUw6
-dHJ1ZSxUcnVzdGVkU2NyaXB0VVJMOnRydWUsVHJ1c3RlZFVSTDp0cnVlLFVuZGVybHlpbmdTb3VyY2VC
-YXNlOnRydWUsVVJMU2VhcmNoUGFyYW1zOnRydWUsVlJDb29yZGluYXRlU3lzdGVtOnRydWUsVlJEaXNw
-bGF5Q2FwYWJpbGl0aWVzOnRydWUsVlJFeWVQYXJhbWV0ZXJzOnRydWUsVlJGcmFtZURhdGE6dHJ1ZSxW
-UkZyYW1lT2ZSZWZlcmVuY2U6dHJ1ZSxWUlBvc2U6dHJ1ZSxWUlN0YWdlQm91bmRzOnRydWUsVlJTdGFn
-ZUJvdW5kc1BvaW50OnRydWUsVlJTdGFnZVBhcmFtZXRlcnM6dHJ1ZSxWYWxpZGl0eVN0YXRlOnRydWUs
-VmlkZW9QbGF5YmFja1F1YWxpdHk6dHJ1ZSxWaWRlb1RyYWNrOnRydWUsVlRUUmVnaW9uOnRydWUsV2lu
-ZG93Q2xpZW50OnRydWUsV29ya2xldEFuaW1hdGlvbjp0cnVlLFdvcmtsZXRHbG9iYWxTY29wZTp0cnVl
-LFhQYXRoRXZhbHVhdG9yOnRydWUsWFBhdGhFeHByZXNzaW9uOnRydWUsWFBhdGhOU1Jlc29sdmVyOnRy
-dWUsWFBhdGhSZXN1bHQ6dHJ1ZSxYTUxTZXJpYWxpemVyOnRydWUsWFNMVFByb2Nlc3Nvcjp0cnVlLEJs
-dWV0b290aDp0cnVlLEJsdWV0b290aENoYXJhY3RlcmlzdGljUHJvcGVydGllczp0cnVlLEJsdWV0b290
-aFJlbW90ZUdBVFRTZXJ2ZXI6dHJ1ZSxCbHVldG9vdGhSZW1vdGVHQVRUU2VydmljZTp0cnVlLEJsdWV0
-b290aFVVSUQ6dHJ1ZSxCdWRnZXRTZXJ2aWNlOnRydWUsQ2FjaGU6dHJ1ZSxET01GaWxlU3lzdGVtU3lu
-Yzp0cnVlLERpcmVjdG9yeUVudHJ5U3luYzp0cnVlLERpcmVjdG9yeVJlYWRlclN5bmM6dHJ1ZSxFbnRy
-eVN5bmM6dHJ1ZSxGaWxlRW50cnlTeW5jOnRydWUsRmlsZVJlYWRlclN5bmM6dHJ1ZSxGaWxlV3JpdGVy
-U3luYzp0cnVlLEhUTUxBbGxDb2xsZWN0aW9uOnRydWUsTW9qbzp0cnVlLE1vam9IYW5kbGU6dHJ1ZSxN
-b2pvV2F0Y2hlcjp0cnVlLE5GQzp0cnVlLFBhZ2VQb3B1cENvbnRyb2xsZXI6dHJ1ZSxSZXBvcnQ6dHJ1
-ZSxSZXF1ZXN0OnRydWUsUmVzcG9uc2U6dHJ1ZSxTdWJ0bGVDcnlwdG86dHJ1ZSxVU0JBbHRlcm5hdGVJ
-bnRlcmZhY2U6dHJ1ZSxVU0JDb25maWd1cmF0aW9uOnRydWUsVVNCRGV2aWNlOnRydWUsVVNCRW5kcG9p
-bnQ6dHJ1ZSxVU0JJblRyYW5zZmVyUmVzdWx0OnRydWUsVVNCSW50ZXJmYWNlOnRydWUsVVNCSXNvY2hy
-b25vdXNJblRyYW5zZmVyUGFja2V0OnRydWUsVVNCSXNvY2hyb25vdXNJblRyYW5zZmVyUmVzdWx0OnRy
-dWUsVVNCSXNvY2hyb25vdXNPdXRUcmFuc2ZlclBhY2tldDp0cnVlLFVTQklzb2Nocm9ub3VzT3V0VHJh
-bnNmZXJSZXN1bHQ6dHJ1ZSxVU0JPdXRUcmFuc2ZlclJlc3VsdDp0cnVlLFdvcmtlckxvY2F0aW9uOnRy
-dWUsV29ya2VyTmF2aWdhdG9yOnRydWUsV29ya2xldDp0cnVlLElEQkZhY3Rvcnk6dHJ1ZSxJREJJbmRl
-eDp0cnVlLElEQk9iamVjdFN0b3JlOnRydWUsSURCT2JzZXJ2ZXI6dHJ1ZSxJREJPYnNlcnZlckNoYW5n
-ZXM6dHJ1ZSxTVkdBbmltYXRlZEFuZ2xlOnRydWUsU1ZHQW5pbWF0ZWRCb29sZWFuOnRydWUsU1ZHQW5p
-bWF0ZWRFbnVtZXJhdGlvbjp0cnVlLFNWR0FuaW1hdGVkSW50ZWdlcjp0cnVlLFNWR0FuaW1hdGVkTGVu
-Z3RoOnRydWUsU1ZHQW5pbWF0ZWRMZW5ndGhMaXN0OnRydWUsU1ZHQW5pbWF0ZWROdW1iZXI6dHJ1ZSxT
-VkdBbmltYXRlZE51bWJlckxpc3Q6dHJ1ZSxTVkdBbmltYXRlZFByZXNlcnZlQXNwZWN0UmF0aW86dHJ1
-ZSxTVkdBbmltYXRlZFJlY3Q6dHJ1ZSxTVkdBbmltYXRlZFN0cmluZzp0cnVlLFNWR0FuaW1hdGVkVHJh
-bnNmb3JtTGlzdDp0cnVlLFNWR01hdHJpeDp0cnVlLFNWR1BvaW50OnRydWUsU1ZHUHJlc2VydmVBc3Bl
-Y3RSYXRpbzp0cnVlLFNWR1JlY3Q6dHJ1ZSxTVkdVbml0VHlwZXM6dHJ1ZSxBdWRpb0xpc3RlbmVyOnRy
-dWUsQXVkaW9UcmFjazp0cnVlLEF1ZGlvV29ya2xldEdsb2JhbFNjb3BlOnRydWUsQXVkaW9Xb3JrbGV0
-UHJvY2Vzc29yOnRydWUsUGVyaW9kaWNXYXZlOnRydWUsV2ViR0xBY3RpdmVJbmZvOnRydWUsQU5HTEVJ
-bnN0YW5jZWRBcnJheXM6dHJ1ZSxBTkdMRV9pbnN0YW5jZWRfYXJyYXlzOnRydWUsV2ViR0xCdWZmZXI6
-dHJ1ZSxXZWJHTENhbnZhczp0cnVlLFdlYkdMQ29sb3JCdWZmZXJGbG9hdDp0cnVlLFdlYkdMQ29tcHJl
-c3NlZFRleHR1cmVBU1RDOnRydWUsV2ViR0xDb21wcmVzc2VkVGV4dHVyZUFUQzp0cnVlLFdFQkdMX2Nv
-bXByZXNzZWRfdGV4dHVyZV9hdGM6dHJ1ZSxXZWJHTENvbXByZXNzZWRUZXh0dXJlRVRDMTp0cnVlLFdF
-QkdMX2NvbXByZXNzZWRfdGV4dHVyZV9ldGMxOnRydWUsV2ViR0xDb21wcmVzc2VkVGV4dHVyZUVUQzp0
-cnVlLFdlYkdMQ29tcHJlc3NlZFRleHR1cmVQVlJUQzp0cnVlLFdFQkdMX2NvbXByZXNzZWRfdGV4dHVy
-ZV9wdnJ0Yzp0cnVlLFdlYkdMQ29tcHJlc3NlZFRleHR1cmVTM1RDOnRydWUsV0VCR0xfY29tcHJlc3Nl
-ZF90ZXh0dXJlX3MzdGM6dHJ1ZSxXZWJHTENvbXByZXNzZWRUZXh0dXJlUzNUQ3NSR0I6dHJ1ZSxXZWJH
-TERlYnVnUmVuZGVyZXJJbmZvOnRydWUsV0VCR0xfZGVidWdfcmVuZGVyZXJfaW5mbzp0cnVlLFdlYkdM
-RGVidWdTaGFkZXJzOnRydWUsV0VCR0xfZGVidWdfc2hhZGVyczp0cnVlLFdlYkdMRGVwdGhUZXh0dXJl
-OnRydWUsV0VCR0xfZGVwdGhfdGV4dHVyZTp0cnVlLFdlYkdMRHJhd0J1ZmZlcnM6dHJ1ZSxXRUJHTF9k
-cmF3X2J1ZmZlcnM6dHJ1ZSxFWFRzUkdCOnRydWUsRVhUX3NSR0I6dHJ1ZSxFWFRCbGVuZE1pbk1heDp0
-cnVlLEVYVF9ibGVuZF9taW5tYXg6dHJ1ZSxFWFRDb2xvckJ1ZmZlckZsb2F0OnRydWUsRVhUQ29sb3JC
-dWZmZXJIYWxmRmxvYXQ6dHJ1ZSxFWFREaXNqb2ludFRpbWVyUXVlcnk6dHJ1ZSxFWFREaXNqb2ludFRp
-bWVyUXVlcnlXZWJHTDI6dHJ1ZSxFWFRGcmFnRGVwdGg6dHJ1ZSxFWFRfZnJhZ19kZXB0aDp0cnVlLEVY
-VFNoYWRlclRleHR1cmVMT0Q6dHJ1ZSxFWFRfc2hhZGVyX3RleHR1cmVfbG9kOnRydWUsRVhUVGV4dHVy
-ZUZpbHRlckFuaXNvdHJvcGljOnRydWUsRVhUX3RleHR1cmVfZmlsdGVyX2FuaXNvdHJvcGljOnRydWUs
-V2ViR0xGcmFtZWJ1ZmZlcjp0cnVlLFdlYkdMR2V0QnVmZmVyU3ViRGF0YUFzeW5jOnRydWUsV2ViR0xM
-b3NlQ29udGV4dDp0cnVlLFdlYkdMRXh0ZW5zaW9uTG9zZUNvbnRleHQ6dHJ1ZSxXRUJHTF9sb3NlX2Nv
-bnRleHQ6dHJ1ZSxPRVNFbGVtZW50SW5kZXhVaW50OnRydWUsT0VTX2VsZW1lbnRfaW5kZXhfdWludDp0
-cnVlLE9FU1N0YW5kYXJkRGVyaXZhdGl2ZXM6dHJ1ZSxPRVNfc3RhbmRhcmRfZGVyaXZhdGl2ZXM6dHJ1
-ZSxPRVNUZXh0dXJlRmxvYXQ6dHJ1ZSxPRVNfdGV4dHVyZV9mbG9hdDp0cnVlLE9FU1RleHR1cmVGbG9h
-dExpbmVhcjp0cnVlLE9FU190ZXh0dXJlX2Zsb2F0X2xpbmVhcjp0cnVlLE9FU1RleHR1cmVIYWxmRmxv
-YXQ6dHJ1ZSxPRVNfdGV4dHVyZV9oYWxmX2Zsb2F0OnRydWUsT0VTVGV4dHVyZUhhbGZGbG9hdExpbmVh
-cjp0cnVlLE9FU190ZXh0dXJlX2hhbGZfZmxvYXRfbGluZWFyOnRydWUsT0VTVmVydGV4QXJyYXlPYmpl
-Y3Q6dHJ1ZSxPRVNfdmVydGV4X2FycmF5X29iamVjdDp0cnVlLFdlYkdMUHJvZ3JhbTp0cnVlLFdlYkdM
-UXVlcnk6dHJ1ZSxXZWJHTFJlbmRlcmJ1ZmZlcjp0cnVlLFdlYkdMUmVuZGVyaW5nQ29udGV4dDp0cnVl
-LFdlYkdMMlJlbmRlcmluZ0NvbnRleHQ6dHJ1ZSxXZWJHTFNhbXBsZXI6dHJ1ZSxXZWJHTFNoYWRlcjp0
-cnVlLFdlYkdMU2hhZGVyUHJlY2lzaW9uRm9ybWF0OnRydWUsV2ViR0xTeW5jOnRydWUsV2ViR0xUZXh0
-dXJlOnRydWUsV2ViR0xUaW1lclF1ZXJ5RVhUOnRydWUsV2ViR0xUcmFuc2Zvcm1GZWVkYmFjazp0cnVl
-LFdlYkdMVW5pZm9ybUxvY2F0aW9uOnRydWUsV2ViR0xWZXJ0ZXhBcnJheU9iamVjdDp0cnVlLFdlYkdM
-VmVydGV4QXJyYXlPYmplY3RPRVM6dHJ1ZSxXZWJHTDp0cnVlLFdlYkdMMlJlbmRlcmluZ0NvbnRleHRC
-YXNlOnRydWUsRGF0YWJhc2U6dHJ1ZSxTUUxFcnJvcjp0cnVlLFNRTFJlc3VsdFNldDp0cnVlLFNRTFRy
-YW5zYWN0aW9uOnRydWUsQXJyYXlCdWZmZXI6dHJ1ZSxBcnJheUJ1ZmZlclZpZXc6ZmFsc2UsRGF0YVZp
-ZXc6dHJ1ZSxGbG9hdDMyQXJyYXk6dHJ1ZSxGbG9hdDY0QXJyYXk6dHJ1ZSxJbnQxNkFycmF5OnRydWUs
-SW50MzJBcnJheTp0cnVlLEludDhBcnJheTp0cnVlLFVpbnQxNkFycmF5OnRydWUsVWludDMyQXJyYXk6
-dHJ1ZSxVaW50OENsYW1wZWRBcnJheTp0cnVlLENhbnZhc1BpeGVsQXJyYXk6dHJ1ZSxVaW50OEFycmF5
-OmZhbHNlLEhUTUxBdWRpb0VsZW1lbnQ6dHJ1ZSxIVE1MQlJFbGVtZW50OnRydWUsSFRNTENhbnZhc0Vs
-ZW1lbnQ6dHJ1ZSxIVE1MQ29udGVudEVsZW1lbnQ6dHJ1ZSxIVE1MRExpc3RFbGVtZW50OnRydWUsSFRN
-TERhdGFMaXN0RWxlbWVudDp0cnVlLEhUTUxEZXRhaWxzRWxlbWVudDp0cnVlLEhUTUxEaWFsb2dFbGVt
-ZW50OnRydWUsSFRNTERpdkVsZW1lbnQ6dHJ1ZSxIVE1MRW1iZWRFbGVtZW50OnRydWUsSFRNTEZpZWxk
-U2V0RWxlbWVudDp0cnVlLEhUTUxIUkVsZW1lbnQ6dHJ1ZSxIVE1MSGVhZEVsZW1lbnQ6dHJ1ZSxIVE1M
-SGVhZGluZ0VsZW1lbnQ6dHJ1ZSxIVE1MSHRtbEVsZW1lbnQ6dHJ1ZSxIVE1MSUZyYW1lRWxlbWVudDp0
-cnVlLEhUTUxJbWFnZUVsZW1lbnQ6dHJ1ZSxIVE1MTGFiZWxFbGVtZW50OnRydWUsSFRNTExlZ2VuZEVs
-ZW1lbnQ6dHJ1ZSxIVE1MTGlua0VsZW1lbnQ6dHJ1ZSxIVE1MTWFwRWxlbWVudDp0cnVlLEhUTUxNZWRp
-YUVsZW1lbnQ6dHJ1ZSxIVE1MTWVudUVsZW1lbnQ6dHJ1ZSxIVE1MTWV0YUVsZW1lbnQ6dHJ1ZSxIVE1M
-TW9kRWxlbWVudDp0cnVlLEhUTUxPTGlzdEVsZW1lbnQ6dHJ1ZSxIVE1MT2JqZWN0RWxlbWVudDp0cnVl
-LEhUTUxPcHRHcm91cEVsZW1lbnQ6dHJ1ZSxIVE1MUGljdHVyZUVsZW1lbnQ6dHJ1ZSxIVE1MUHJlRWxl
-bWVudDp0cnVlLEhUTUxRdW90ZUVsZW1lbnQ6dHJ1ZSxIVE1MU2NyaXB0RWxlbWVudDp0cnVlLEhUTUxT
-aGFkb3dFbGVtZW50OnRydWUsSFRNTFNsb3RFbGVtZW50OnRydWUsSFRNTFNvdXJjZUVsZW1lbnQ6dHJ1
-ZSxIVE1MU3BhbkVsZW1lbnQ6dHJ1ZSxIVE1MU3R5bGVFbGVtZW50OnRydWUsSFRNTFRhYmxlQ2FwdGlv
-bkVsZW1lbnQ6dHJ1ZSxIVE1MVGFibGVDZWxsRWxlbWVudDp0cnVlLEhUTUxUYWJsZURhdGFDZWxsRWxl
-bWVudDp0cnVlLEhUTUxUYWJsZUhlYWRlckNlbGxFbGVtZW50OnRydWUsSFRNTFRhYmxlQ29sRWxlbWVu
-dDp0cnVlLEhUTUxUaW1lRWxlbWVudDp0cnVlLEhUTUxUaXRsZUVsZW1lbnQ6dHJ1ZSxIVE1MVHJhY2tF
-bGVtZW50OnRydWUsSFRNTFVMaXN0RWxlbWVudDp0cnVlLEhUTUxVbmtub3duRWxlbWVudDp0cnVlLEhU
-TUxWaWRlb0VsZW1lbnQ6dHJ1ZSxIVE1MRGlyZWN0b3J5RWxlbWVudDp0cnVlLEhUTUxGb250RWxlbWVu
-dDp0cnVlLEhUTUxGcmFtZUVsZW1lbnQ6dHJ1ZSxIVE1MRnJhbWVTZXRFbGVtZW50OnRydWUsSFRNTE1h
-cnF1ZWVFbGVtZW50OnRydWUsSFRNTEVsZW1lbnQ6ZmFsc2UsQWNjZXNzaWJsZU5vZGVMaXN0OnRydWUs
-SFRNTEFuY2hvckVsZW1lbnQ6dHJ1ZSxIVE1MQXJlYUVsZW1lbnQ6dHJ1ZSxIVE1MQmFzZUVsZW1lbnQ6
-dHJ1ZSxCbG9iOmZhbHNlLEJsdWV0b290aFJlbW90ZUdBVFREZXNjcmlwdG9yOnRydWUsSFRNTEJvZHlF
-bGVtZW50OnRydWUsSFRNTEJ1dHRvbkVsZW1lbnQ6dHJ1ZSxDREFUQVNlY3Rpb246dHJ1ZSxDaGFyYWN0
-ZXJEYXRhOnRydWUsQ29tbWVudDp0cnVlLFByb2Nlc3NpbmdJbnN0cnVjdGlvbjp0cnVlLFRleHQ6dHJ1
-ZSxDU1NLZXl3b3JkVmFsdWU6dHJ1ZSxDU1NOdW1lcmljVmFsdWU6ZmFsc2UsQ1NTUGVyc3BlY3RpdmU6
-dHJ1ZSxDU1NDaGFyc2V0UnVsZTp0cnVlLENTU0NvbmRpdGlvblJ1bGU6dHJ1ZSxDU1NGb250RmFjZVJ1
-bGU6dHJ1ZSxDU1NHcm91cGluZ1J1bGU6dHJ1ZSxDU1NJbXBvcnRSdWxlOnRydWUsQ1NTS2V5ZnJhbWVS
-dWxlOnRydWUsTW96Q1NTS2V5ZnJhbWVSdWxlOnRydWUsV2ViS2l0Q1NTS2V5ZnJhbWVSdWxlOnRydWUs
-Q1NTS2V5ZnJhbWVzUnVsZTp0cnVlLE1vekNTU0tleWZyYW1lc1J1bGU6dHJ1ZSxXZWJLaXRDU1NLZXlm
-cmFtZXNSdWxlOnRydWUsQ1NTTWVkaWFSdWxlOnRydWUsQ1NTTmFtZXNwYWNlUnVsZTp0cnVlLENTU1Bh
-Z2VSdWxlOnRydWUsQ1NTUnVsZTp0cnVlLENTU1N0eWxlUnVsZTp0cnVlLENTU1N1cHBvcnRzUnVsZTp0
-cnVlLENTU1ZpZXdwb3J0UnVsZTp0cnVlLENTU1N0eWxlRGVjbGFyYXRpb246dHJ1ZSxNU1N0eWxlQ1NT
-UHJvcGVydGllczp0cnVlLENTUzJQcm9wZXJ0aWVzOnRydWUsQ1NTSW1hZ2VWYWx1ZTp0cnVlLENTU1Bv
-c2l0aW9uVmFsdWU6dHJ1ZSxDU1NSZXNvdXJjZVZhbHVlOnRydWUsQ1NTVVJMSW1hZ2VWYWx1ZTp0cnVl
-LENTU1N0eWxlVmFsdWU6ZmFsc2UsQ1NTTWF0cml4Q29tcG9uZW50OnRydWUsQ1NTUm90YXRpb246dHJ1
-ZSxDU1NTY2FsZTp0cnVlLENTU1NrZXc6dHJ1ZSxDU1NUcmFuc2xhdGlvbjp0cnVlLENTU1RyYW5zZm9y
-bUNvbXBvbmVudDpmYWxzZSxDU1NUcmFuc2Zvcm1WYWx1ZTp0cnVlLENTU1VuaXRWYWx1ZTp0cnVlLENT
-U1VucGFyc2VkVmFsdWU6dHJ1ZSxIVE1MRGF0YUVsZW1lbnQ6dHJ1ZSxEYXRhVHJhbnNmZXJJdGVtTGlz
-dDp0cnVlLFhNTERvY3VtZW50OnRydWUsRG9jdW1lbnQ6ZmFsc2UsRE9NRXhjZXB0aW9uOnRydWUsQ2xp
-ZW50UmVjdExpc3Q6dHJ1ZSxET01SZWN0TGlzdDp0cnVlLERPTVJlY3RSZWFkT25seTpmYWxzZSxET01T
-dHJpbmdMaXN0OnRydWUsRE9NVG9rZW5MaXN0OnRydWUsRWxlbWVudDpmYWxzZSxEaXJlY3RvcnlFbnRy
-eTp0cnVlLEVudHJ5OnRydWUsRmlsZUVudHJ5OnRydWUsQWJvcnRQYXltZW50RXZlbnQ6dHJ1ZSxBbmlt
-YXRpb25FdmVudDp0cnVlLEFuaW1hdGlvblBsYXliYWNrRXZlbnQ6dHJ1ZSxBcHBsaWNhdGlvbkNhY2hl
-RXJyb3JFdmVudDp0cnVlLEJhY2tncm91bmRGZXRjaENsaWNrRXZlbnQ6dHJ1ZSxCYWNrZ3JvdW5kRmV0
-Y2hFdmVudDp0cnVlLEJhY2tncm91bmRGZXRjaEZhaWxFdmVudDp0cnVlLEJhY2tncm91bmRGZXRjaGVk
-RXZlbnQ6dHJ1ZSxCZWZvcmVJbnN0YWxsUHJvbXB0RXZlbnQ6dHJ1ZSxCZWZvcmVVbmxvYWRFdmVudDp0
-cnVlLEJsb2JFdmVudDp0cnVlLENhbk1ha2VQYXltZW50RXZlbnQ6dHJ1ZSxDbGlwYm9hcmRFdmVudDp0
-cnVlLENsb3NlRXZlbnQ6dHJ1ZSxDdXN0b21FdmVudDp0cnVlLERldmljZU1vdGlvbkV2ZW50OnRydWUs
-RGV2aWNlT3JpZW50YXRpb25FdmVudDp0cnVlLEVycm9yRXZlbnQ6dHJ1ZSxFeHRlbmRhYmxlRXZlbnQ6
-dHJ1ZSxFeHRlbmRhYmxlTWVzc2FnZUV2ZW50OnRydWUsRmV0Y2hFdmVudDp0cnVlLEZvbnRGYWNlU2V0
-TG9hZEV2ZW50OnRydWUsRm9yZWlnbkZldGNoRXZlbnQ6dHJ1ZSxHYW1lcGFkRXZlbnQ6dHJ1ZSxIYXNo
-Q2hhbmdlRXZlbnQ6dHJ1ZSxJbnN0YWxsRXZlbnQ6dHJ1ZSxNZWRpYUVuY3J5cHRlZEV2ZW50OnRydWUs
-TWVkaWFLZXlNZXNzYWdlRXZlbnQ6dHJ1ZSxNZWRpYVF1ZXJ5TGlzdEV2ZW50OnRydWUsTWVkaWFTdHJl
-YW1FdmVudDp0cnVlLE1lZGlhU3RyZWFtVHJhY2tFdmVudDp0cnVlLE1lc3NhZ2VFdmVudDp0cnVlLE1J
-RElDb25uZWN0aW9uRXZlbnQ6dHJ1ZSxNSURJTWVzc2FnZUV2ZW50OnRydWUsTXV0YXRpb25FdmVudDp0
-cnVlLE5vdGlmaWNhdGlvbkV2ZW50OnRydWUsUGFnZVRyYW5zaXRpb25FdmVudDp0cnVlLFBheW1lbnRS
-ZXF1ZXN0RXZlbnQ6dHJ1ZSxQYXltZW50UmVxdWVzdFVwZGF0ZUV2ZW50OnRydWUsUG9wU3RhdGVFdmVu
-dDp0cnVlLFByZXNlbnRhdGlvbkNvbm5lY3Rpb25BdmFpbGFibGVFdmVudDp0cnVlLFByZXNlbnRhdGlv
-bkNvbm5lY3Rpb25DbG9zZUV2ZW50OnRydWUsUHJvbWlzZVJlamVjdGlvbkV2ZW50OnRydWUsUHVzaEV2
-ZW50OnRydWUsUlRDRGF0YUNoYW5uZWxFdmVudDp0cnVlLFJUQ0RUTUZUb25lQ2hhbmdlRXZlbnQ6dHJ1
-ZSxSVENQZWVyQ29ubmVjdGlvbkljZUV2ZW50OnRydWUsUlRDVHJhY2tFdmVudDp0cnVlLFNlY3VyaXR5
-UG9saWN5VmlvbGF0aW9uRXZlbnQ6dHJ1ZSxTZW5zb3JFcnJvckV2ZW50OnRydWUsU3BlZWNoUmVjb2du
-aXRpb25FcnJvcjp0cnVlLFNwZWVjaFJlY29nbml0aW9uRXZlbnQ6dHJ1ZSxTcGVlY2hTeW50aGVzaXNF
-dmVudDp0cnVlLFN5bmNFdmVudDp0cnVlLFRyYWNrRXZlbnQ6dHJ1ZSxUcmFuc2l0aW9uRXZlbnQ6dHJ1
-ZSxXZWJLaXRUcmFuc2l0aW9uRXZlbnQ6dHJ1ZSxWUkRldmljZUV2ZW50OnRydWUsVlJEaXNwbGF5RXZl
-bnQ6dHJ1ZSxWUlNlc3Npb25FdmVudDp0cnVlLE1vam9JbnRlcmZhY2VSZXF1ZXN0RXZlbnQ6dHJ1ZSxV
-U0JDb25uZWN0aW9uRXZlbnQ6dHJ1ZSxJREJWZXJzaW9uQ2hhbmdlRXZlbnQ6dHJ1ZSxBdWRpb1Byb2Nl
-c3NpbmdFdmVudDp0cnVlLE9mZmxpbmVBdWRpb0NvbXBsZXRpb25FdmVudDp0cnVlLFdlYkdMQ29udGV4
-dEV2ZW50OnRydWUsRXZlbnQ6ZmFsc2UsSW5wdXRFdmVudDpmYWxzZSxBYnNvbHV0ZU9yaWVudGF0aW9u
-U2Vuc29yOnRydWUsQWNjZWxlcm9tZXRlcjp0cnVlLEFjY2Vzc2libGVOb2RlOnRydWUsQW1iaWVudExp
-Z2h0U2Vuc29yOnRydWUsQW5pbWF0aW9uOnRydWUsQXBwbGljYXRpb25DYWNoZTp0cnVlLERPTUFwcGxp
-Y2F0aW9uQ2FjaGU6dHJ1ZSxPZmZsaW5lUmVzb3VyY2VMaXN0OnRydWUsQmFja2dyb3VuZEZldGNoUmVn
-aXN0cmF0aW9uOnRydWUsQmF0dGVyeU1hbmFnZXI6dHJ1ZSxCcm9hZGNhc3RDaGFubmVsOnRydWUsQ2Fu
-dmFzQ2FwdHVyZU1lZGlhU3RyZWFtVHJhY2s6dHJ1ZSxFdmVudFNvdXJjZTp0cnVlLEZpbGVSZWFkZXI6
-dHJ1ZSxGb250RmFjZVNldDp0cnVlLEd5cm9zY29wZTp0cnVlLExpbmVhckFjY2VsZXJhdGlvblNlbnNv
-cjp0cnVlLE1hZ25ldG9tZXRlcjp0cnVlLE1lZGlhRGV2aWNlczp0cnVlLE1lZGlhS2V5U2Vzc2lvbjp0
-cnVlLE1lZGlhUXVlcnlMaXN0OnRydWUsTWVkaWFSZWNvcmRlcjp0cnVlLE1lZGlhU291cmNlOnRydWUs
-TWVkaWFTdHJlYW06dHJ1ZSxNZWRpYVN0cmVhbVRyYWNrOnRydWUsTUlESUFjY2Vzczp0cnVlLE1JRElJ
-bnB1dDp0cnVlLE1JRElPdXRwdXQ6dHJ1ZSxNSURJUG9ydDp0cnVlLE5ldHdvcmtJbmZvcm1hdGlvbjp0
-cnVlLE5vdGlmaWNhdGlvbjp0cnVlLE9mZnNjcmVlbkNhbnZhczp0cnVlLE9yaWVudGF0aW9uU2Vuc29y
-OnRydWUsUGF5bWVudFJlcXVlc3Q6dHJ1ZSxQZXJmb3JtYW5jZTp0cnVlLFBlcm1pc3Npb25TdGF0dXM6
-dHJ1ZSxQcmVzZW50YXRpb25Db25uZWN0aW9uOnRydWUsUHJlc2VudGF0aW9uQ29ubmVjdGlvbkxpc3Q6
-dHJ1ZSxQcmVzZW50YXRpb25SZXF1ZXN0OnRydWUsUmVsYXRpdmVPcmllbnRhdGlvblNlbnNvcjp0cnVl
-LFJlbW90ZVBsYXliYWNrOnRydWUsUlRDRGF0YUNoYW5uZWw6dHJ1ZSxEYXRhQ2hhbm5lbDp0cnVlLFJU
-Q0RUTUZTZW5kZXI6dHJ1ZSxSVENQZWVyQ29ubmVjdGlvbjp0cnVlLHdlYmtpdFJUQ1BlZXJDb25uZWN0
-aW9uOnRydWUsbW96UlRDUGVlckNvbm5lY3Rpb246dHJ1ZSxTY3JlZW5PcmllbnRhdGlvbjp0cnVlLFNl
-bnNvcjp0cnVlLFNlcnZpY2VXb3JrZXI6dHJ1ZSxTZXJ2aWNlV29ya2VyQ29udGFpbmVyOnRydWUsU2Vy
-dmljZVdvcmtlclJlZ2lzdHJhdGlvbjp0cnVlLFNoYXJlZFdvcmtlcjp0cnVlLFNwZWVjaFJlY29nbml0
-aW9uOnRydWUsU3BlZWNoU3ludGhlc2lzOnRydWUsU3BlZWNoU3ludGhlc2lzVXR0ZXJhbmNlOnRydWUs
-VlI6dHJ1ZSxWUkRldmljZTp0cnVlLFZSRGlzcGxheTp0cnVlLFZSU2Vzc2lvbjp0cnVlLFZpc3VhbFZp
-ZXdwb3J0OnRydWUsV2ViU29ja2V0OnRydWUsV29ya2VyOnRydWUsV29ya2VyUGVyZm9ybWFuY2U6dHJ1
-ZSxCbHVldG9vdGhEZXZpY2U6dHJ1ZSxCbHVldG9vdGhSZW1vdGVHQVRUQ2hhcmFjdGVyaXN0aWM6dHJ1
-ZSxDbGlwYm9hcmQ6dHJ1ZSxNb2pvSW50ZXJmYWNlSW50ZXJjZXB0b3I6dHJ1ZSxVU0I6dHJ1ZSxJREJE
-YXRhYmFzZTp0cnVlLElEQk9wZW5EQlJlcXVlc3Q6dHJ1ZSxJREJWZXJzaW9uQ2hhbmdlUmVxdWVzdDp0
-cnVlLElEQlJlcXVlc3Q6dHJ1ZSxJREJUcmFuc2FjdGlvbjp0cnVlLEFuYWx5c2VyTm9kZTp0cnVlLFJl
-YWx0aW1lQW5hbHlzZXJOb2RlOnRydWUsQXVkaW9CdWZmZXJTb3VyY2VOb2RlOnRydWUsQXVkaW9EZXN0
-aW5hdGlvbk5vZGU6dHJ1ZSxBdWRpb05vZGU6dHJ1ZSxBdWRpb1NjaGVkdWxlZFNvdXJjZU5vZGU6dHJ1
-ZSxBdWRpb1dvcmtsZXROb2RlOnRydWUsQmlxdWFkRmlsdGVyTm9kZTp0cnVlLENoYW5uZWxNZXJnZXJO
-b2RlOnRydWUsQXVkaW9DaGFubmVsTWVyZ2VyOnRydWUsQ2hhbm5lbFNwbGl0dGVyTm9kZTp0cnVlLEF1
-ZGlvQ2hhbm5lbFNwbGl0dGVyOnRydWUsQ29uc3RhbnRTb3VyY2VOb2RlOnRydWUsQ29udm9sdmVyTm9k
-ZTp0cnVlLERlbGF5Tm9kZTp0cnVlLER5bmFtaWNzQ29tcHJlc3Nvck5vZGU6dHJ1ZSxHYWluTm9kZTp0
-cnVlLEF1ZGlvR2Fpbk5vZGU6dHJ1ZSxJSVJGaWx0ZXJOb2RlOnRydWUsTWVkaWFFbGVtZW50QXVkaW9T
-b3VyY2VOb2RlOnRydWUsTWVkaWFTdHJlYW1BdWRpb0Rlc3RpbmF0aW9uTm9kZTp0cnVlLE1lZGlhU3Ry
-ZWFtQXVkaW9Tb3VyY2VOb2RlOnRydWUsT3NjaWxsYXRvck5vZGU6dHJ1ZSxPc2NpbGxhdG9yOnRydWUs
-UGFubmVyTm9kZTp0cnVlLEF1ZGlvUGFubmVyTm9kZTp0cnVlLHdlYmtpdEF1ZGlvUGFubmVyTm9kZTp0
-cnVlLFNjcmlwdFByb2Nlc3Nvck5vZGU6dHJ1ZSxKYXZhU2NyaXB0QXVkaW9Ob2RlOnRydWUsU3RlcmVv
-UGFubmVyTm9kZTp0cnVlLFdhdmVTaGFwZXJOb2RlOnRydWUsRXZlbnRUYXJnZXQ6ZmFsc2UsRmlsZTp0
-cnVlLEZpbGVMaXN0OnRydWUsRmlsZVdyaXRlcjp0cnVlLEhUTUxGb3JtRWxlbWVudDp0cnVlLEdhbWVw
-YWQ6dHJ1ZSxHYW1lcGFkQnV0dG9uOnRydWUsSGlzdG9yeTp0cnVlLEhUTUxDb2xsZWN0aW9uOnRydWUs
-SFRNTEZvcm1Db250cm9sc0NvbGxlY3Rpb246dHJ1ZSxIVE1MT3B0aW9uc0NvbGxlY3Rpb246dHJ1ZSxI
-VE1MRG9jdW1lbnQ6dHJ1ZSxYTUxIdHRwUmVxdWVzdDp0cnVlLFhNTEh0dHBSZXF1ZXN0VXBsb2FkOnRy
-dWUsWE1MSHR0cFJlcXVlc3RFdmVudFRhcmdldDpmYWxzZSxJbWFnZURhdGE6dHJ1ZSxIVE1MSW5wdXRF
-bGVtZW50OnRydWUsS2V5Ym9hcmRFdmVudDp0cnVlLEhUTUxMSUVsZW1lbnQ6dHJ1ZSxMb2NhdGlvbjp0
-cnVlLE1lZGlhTGlzdDp0cnVlLE1lc3NhZ2VQb3J0OnRydWUsSFRNTE1ldGVyRWxlbWVudDp0cnVlLE1J
-RElJbnB1dE1hcDp0cnVlLE1JRElPdXRwdXRNYXA6dHJ1ZSxNaW1lVHlwZTp0cnVlLE1pbWVUeXBlQXJy
-YXk6dHJ1ZSxNb3VzZUV2ZW50OnRydWUsRHJhZ0V2ZW50OnRydWUsUG9pbnRlckV2ZW50OnRydWUsV2hl
-ZWxFdmVudDp0cnVlLERvY3VtZW50RnJhZ21lbnQ6dHJ1ZSxTaGFkb3dSb290OnRydWUsRG9jdW1lbnRU
-eXBlOnRydWUsTm9kZTpmYWxzZSxOb2RlTGlzdDp0cnVlLFJhZGlvTm9kZUxpc3Q6dHJ1ZSxIVE1MT3B0
-aW9uRWxlbWVudDp0cnVlLEhUTUxPdXRwdXRFbGVtZW50OnRydWUsSFRNTFBhcmFncmFwaEVsZW1lbnQ6
-dHJ1ZSxIVE1MUGFyYW1FbGVtZW50OnRydWUsUGx1Z2luOnRydWUsUGx1Z2luQXJyYXk6dHJ1ZSxQcmVz
-ZW50YXRpb25BdmFpbGFiaWxpdHk6dHJ1ZSxIVE1MUHJvZ3Jlc3NFbGVtZW50OnRydWUsUHJvZ3Jlc3NF
-dmVudDp0cnVlLFJlc291cmNlUHJvZ3Jlc3NFdmVudDp0cnVlLFJUQ1N0YXRzUmVwb3J0OnRydWUsSFRN
-TFNlbGVjdEVsZW1lbnQ6dHJ1ZSxTb3VyY2VCdWZmZXI6dHJ1ZSxTb3VyY2VCdWZmZXJMaXN0OnRydWUs
-U3BlZWNoR3JhbW1hcjp0cnVlLFNwZWVjaEdyYW1tYXJMaXN0OnRydWUsU3BlZWNoUmVjb2duaXRpb25S
-ZXN1bHQ6dHJ1ZSxTdG9yYWdlOnRydWUsU3RvcmFnZUV2ZW50OnRydWUsQ1NTU3R5bGVTaGVldDp0cnVl
-LFN0eWxlU2hlZXQ6dHJ1ZSxIVE1MVGFibGVFbGVtZW50OnRydWUsSFRNTFRhYmxlUm93RWxlbWVudDp0
-cnVlLEhUTUxUYWJsZVNlY3Rpb25FbGVtZW50OnRydWUsSFRNTFRlbXBsYXRlRWxlbWVudDp0cnVlLEhU
-TUxUZXh0QXJlYUVsZW1lbnQ6dHJ1ZSxUZXh0VHJhY2s6dHJ1ZSxUZXh0VHJhY2tDdWU6dHJ1ZSxWVFRD
-dWU6dHJ1ZSxUZXh0VHJhY2tDdWVMaXN0OnRydWUsVGV4dFRyYWNrTGlzdDp0cnVlLFRpbWVSYW5nZXM6
-dHJ1ZSxUb3VjaDp0cnVlLFRvdWNoTGlzdDp0cnVlLFRyYWNrRGVmYXVsdExpc3Q6dHJ1ZSxDb21wb3Np
-dGlvbkV2ZW50OnRydWUsRm9jdXNFdmVudDp0cnVlLFRleHRFdmVudDp0cnVlLFRvdWNoRXZlbnQ6dHJ1
-ZSxVSUV2ZW50OmZhbHNlLFVSTDp0cnVlLFZpZGVvVHJhY2tMaXN0OnRydWUsV2luZG93OnRydWUsRE9N
-V2luZG93OnRydWUsRGVkaWNhdGVkV29ya2VyR2xvYmFsU2NvcGU6dHJ1ZSxTZXJ2aWNlV29ya2VyR2xv
-YmFsU2NvcGU6dHJ1ZSxTaGFyZWRXb3JrZXJHbG9iYWxTY29wZTp0cnVlLFdvcmtlckdsb2JhbFNjb3Bl
-OnRydWUsQXR0cjp0cnVlLENTU1J1bGVMaXN0OnRydWUsQ2xpZW50UmVjdDp0cnVlLERPTVJlY3Q6dHJ1
-ZSxHYW1lcGFkTGlzdDp0cnVlLE5hbWVkTm9kZU1hcDp0cnVlLE1vek5hbWVkQXR0ck1hcDp0cnVlLFNw
-ZWVjaFJlY29nbml0aW9uUmVzdWx0TGlzdDp0cnVlLFN0eWxlU2hlZXRMaXN0OnRydWUsSURCQ3Vyc29y
-OmZhbHNlLElEQkN1cnNvcldpdGhWYWx1ZTp0cnVlLElEQktleVJhbmdlOnRydWUsSURCT2JzZXJ2YXRp
-b246dHJ1ZSxTVkdBbmdsZTp0cnVlLFNWR0xlbmd0aDp0cnVlLFNWR0xlbmd0aExpc3Q6dHJ1ZSxTVkdO
-dW1iZXI6dHJ1ZSxTVkdOdW1iZXJMaXN0OnRydWUsU1ZHUG9pbnRMaXN0OnRydWUsU1ZHU2NyaXB0RWxl
-bWVudDp0cnVlLFNWR1N0cmluZ0xpc3Q6dHJ1ZSxTVkdBRWxlbWVudDp0cnVlLFNWR0FuaW1hdGVFbGVt
-ZW50OnRydWUsU1ZHQW5pbWF0ZU1vdGlvbkVsZW1lbnQ6dHJ1ZSxTVkdBbmltYXRlVHJhbnNmb3JtRWxl
-bWVudDp0cnVlLFNWR0FuaW1hdGlvbkVsZW1lbnQ6dHJ1ZSxTVkdDaXJjbGVFbGVtZW50OnRydWUsU1ZH
-Q2xpcFBhdGhFbGVtZW50OnRydWUsU1ZHRGVmc0VsZW1lbnQ6dHJ1ZSxTVkdEZXNjRWxlbWVudDp0cnVl
-LFNWR0Rpc2NhcmRFbGVtZW50OnRydWUsU1ZHRWxsaXBzZUVsZW1lbnQ6dHJ1ZSxTVkdGRUJsZW5kRWxl
-bWVudDp0cnVlLFNWR0ZFQ29sb3JNYXRyaXhFbGVtZW50OnRydWUsU1ZHRkVDb21wb25lbnRUcmFuc2Zl
-ckVsZW1lbnQ6dHJ1ZSxTVkdGRUNvbXBvc2l0ZUVsZW1lbnQ6dHJ1ZSxTVkdGRUNvbnZvbHZlTWF0cml4
-RWxlbWVudDp0cnVlLFNWR0ZFRGlmZnVzZUxpZ2h0aW5nRWxlbWVudDp0cnVlLFNWR0ZFRGlzcGxhY2Vt
-ZW50TWFwRWxlbWVudDp0cnVlLFNWR0ZFRGlzdGFudExpZ2h0RWxlbWVudDp0cnVlLFNWR0ZFRmxvb2RF
-bGVtZW50OnRydWUsU1ZHRkVGdW5jQUVsZW1lbnQ6dHJ1ZSxTVkdGRUZ1bmNCRWxlbWVudDp0cnVlLFNW
-R0ZFRnVuY0dFbGVtZW50OnRydWUsU1ZHRkVGdW5jUkVsZW1lbnQ6dHJ1ZSxTVkdGRUdhdXNzaWFuQmx1
-ckVsZW1lbnQ6dHJ1ZSxTVkdGRUltYWdlRWxlbWVudDp0cnVlLFNWR0ZFTWVyZ2VFbGVtZW50OnRydWUs
-U1ZHRkVNZXJnZU5vZGVFbGVtZW50OnRydWUsU1ZHRkVNb3JwaG9sb2d5RWxlbWVudDp0cnVlLFNWR0ZF
-T2Zmc2V0RWxlbWVudDp0cnVlLFNWR0ZFUG9pbnRMaWdodEVsZW1lbnQ6dHJ1ZSxTVkdGRVNwZWN1bGFy
-TGlnaHRpbmdFbGVtZW50OnRydWUsU1ZHRkVTcG90TGlnaHRFbGVtZW50OnRydWUsU1ZHRkVUaWxlRWxl
-bWVudDp0cnVlLFNWR0ZFVHVyYnVsZW5jZUVsZW1lbnQ6dHJ1ZSxTVkdGaWx0ZXJFbGVtZW50OnRydWUs
-U1ZHRm9yZWlnbk9iamVjdEVsZW1lbnQ6dHJ1ZSxTVkdHRWxlbWVudDp0cnVlLFNWR0dlb21ldHJ5RWxl
-bWVudDp0cnVlLFNWR0dyYXBoaWNzRWxlbWVudDp0cnVlLFNWR0ltYWdlRWxlbWVudDp0cnVlLFNWR0xp
-bmVFbGVtZW50OnRydWUsU1ZHTGluZWFyR3JhZGllbnRFbGVtZW50OnRydWUsU1ZHTWFya2VyRWxlbWVu
-dDp0cnVlLFNWR01hc2tFbGVtZW50OnRydWUsU1ZHTWV0YWRhdGFFbGVtZW50OnRydWUsU1ZHUGF0aEVs
-ZW1lbnQ6dHJ1ZSxTVkdQYXR0ZXJuRWxlbWVudDp0cnVlLFNWR1BvbHlnb25FbGVtZW50OnRydWUsU1ZH
-UG9seWxpbmVFbGVtZW50OnRydWUsU1ZHUmFkaWFsR3JhZGllbnRFbGVtZW50OnRydWUsU1ZHUmVjdEVs
-ZW1lbnQ6dHJ1ZSxTVkdTZXRFbGVtZW50OnRydWUsU1ZHU3RvcEVsZW1lbnQ6dHJ1ZSxTVkdTdHlsZUVs
-ZW1lbnQ6dHJ1ZSxTVkdTVkdFbGVtZW50OnRydWUsU1ZHU3dpdGNoRWxlbWVudDp0cnVlLFNWR1N5bWJv
-bEVsZW1lbnQ6dHJ1ZSxTVkdUU3BhbkVsZW1lbnQ6dHJ1ZSxTVkdUZXh0Q29udGVudEVsZW1lbnQ6dHJ1
-ZSxTVkdUZXh0RWxlbWVudDp0cnVlLFNWR1RleHRQYXRoRWxlbWVudDp0cnVlLFNWR1RleHRQb3NpdGlv
-bmluZ0VsZW1lbnQ6dHJ1ZSxTVkdUaXRsZUVsZW1lbnQ6dHJ1ZSxTVkdVc2VFbGVtZW50OnRydWUsU1ZH
-Vmlld0VsZW1lbnQ6dHJ1ZSxTVkdHcmFkaWVudEVsZW1lbnQ6dHJ1ZSxTVkdDb21wb25lbnRUcmFuc2Zl
-ckZ1bmN0aW9uRWxlbWVudDp0cnVlLFNWR0ZFRHJvcFNoYWRvd0VsZW1lbnQ6dHJ1ZSxTVkdNUGF0aEVs
-ZW1lbnQ6dHJ1ZSxTVkdFbGVtZW50OmZhbHNlLFNWR1RyYW5zZm9ybTp0cnVlLFNWR1RyYW5zZm9ybUxp
-c3Q6dHJ1ZSxBdWRpb0J1ZmZlcjp0cnVlLEF1ZGlvUGFyYW06dHJ1ZSxBdWRpb1BhcmFtTWFwOnRydWUs
-QXVkaW9UcmFja0xpc3Q6dHJ1ZSxBdWRpb0NvbnRleHQ6dHJ1ZSx3ZWJraXRBdWRpb0NvbnRleHQ6dHJ1
-ZSxCYXNlQXVkaW9Db250ZXh0OmZhbHNlLE9mZmxpbmVBdWRpb0NvbnRleHQ6dHJ1ZSxTUUxSZXN1bHRT
-ZXRSb3dMaXN0OnRydWV9KQpILmIwLiRuYXRpdmVTdXBlcmNsYXNzVGFnPSJBcnJheUJ1ZmZlclZpZXci
-CkguUkcuJG5hdGl2ZVN1cGVyY2xhc3NUYWc9IkFycmF5QnVmZmVyVmlldyIKSC5WUC4kbmF0aXZlU3Vw
-ZXJjbGFzc1RhZz0iQXJyYXlCdWZmZXJWaWV3IgpILkRnLiRuYXRpdmVTdXBlcmNsYXNzVGFnPSJBcnJh
-eUJ1ZmZlclZpZXciCkguV0IuJG5hdGl2ZVN1cGVyY2xhc3NUYWc9IkFycmF5QnVmZmVyVmlldyIKSC5a
-Ry4kbmF0aXZlU3VwZXJjbGFzc1RhZz0iQXJyYXlCdWZmZXJWaWV3IgpILlBnLiRuYXRpdmVTdXBlcmNs
-YXNzVGFnPSJBcnJheUJ1ZmZlclZpZXciClcub0guJG5hdGl2ZVN1cGVyY2xhc3NUYWc9IkV2ZW50VGFy
-Z2V0IgpXLkNFLiRuYXRpdmVTdXBlcmNsYXNzVGFnPSJFdmVudFRhcmdldCIKVy5RVi4kbmF0aXZlU3Vw
-ZXJjbGFzc1RhZz0iRXZlbnRUYXJnZXQiClcuQXcuJG5hdGl2ZVN1cGVyY2xhc3NUYWc9IkV2ZW50VGFy
-Z2V0In0pKCkKY29udmVydEFsbFRvRmFzdE9iamVjdCh3KQpjb252ZXJ0VG9GYXN0T2JqZWN0KCQpOyhm
-dW5jdGlvbihhKXtpZih0eXBlb2YgZG9jdW1lbnQ9PT0idW5kZWZpbmVkIil7YShudWxsKQpyZXR1cm59
-aWYodHlwZW9mIGRvY3VtZW50LmN1cnJlbnRTY3JpcHQhPSd1bmRlZmluZWQnKXthKGRvY3VtZW50LmN1
-cnJlbnRTY3JpcHQpCnJldHVybn12YXIgdD1kb2N1bWVudC5zY3JpcHRzCmZ1bmN0aW9uIG9uTG9hZChi
-KXtmb3IodmFyIHI9MDtyPHQubGVuZ3RoOysrcil0W3JdLnJlbW92ZUV2ZW50TGlzdGVuZXIoImxvYWQi
-LG9uTG9hZCxmYWxzZSkKYShiLnRhcmdldCl9Zm9yKHZhciBzPTA7czx0Lmxlbmd0aDsrK3MpdFtzXS5h
-ZGRFdmVudExpc3RlbmVyKCJsb2FkIixvbkxvYWQsZmFsc2UpfSkoZnVuY3Rpb24oYSl7di5jdXJyZW50
-U2NyaXB0PWEKaWYodHlwZW9mIGRhcnRNYWluUnVubmVyPT09ImZ1bmN0aW9uIilkYXJ0TWFpblJ1bm5l
-cihMLkRlLFtdKQplbHNlIEwuRGUoW10pfSl9KSgpCi8vIyBzb3VyY2VNYXBwaW5nVVJMPW1pZ3JhdGlv
-bi5qcy5tYXAK
-''';
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/handler_definition.dart b/pkg/analysis_server/lib/src/lsp/handlers/handler_definition.dart
index 0997d44..e9009a3 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/handler_definition.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/handler_definition.dart
@@ -8,7 +8,6 @@
import 'package:analysis_server/lsp_protocol/protocol_special.dart';
import 'package:analysis_server/protocol/protocol_generated.dart'
hide AnalysisGetNavigationParams;
-import 'package:analysis_server/src/domains/analysis/navigation_dart.dart';
import 'package:analysis_server/src/lsp/handlers/handlers.dart';
import 'package:analysis_server/src/lsp/lsp_analysis_server.dart';
import 'package:analysis_server/src/lsp/mapping.dart';
@@ -17,6 +16,7 @@
import 'package:analyzer/dart/analysis/results.dart';
import 'package:analyzer_plugin/protocol/protocol_generated.dart' as plugin;
import 'package:analyzer_plugin/src/utilities/navigation/navigation.dart';
+import 'package:analyzer_plugin/utilities/navigation/navigation_dart.dart';
class DefinitionHandler
extends MessageHandler<TextDocumentPositionParams, List<Location>> {
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/handler_folding.dart b/pkg/analysis_server/lib/src/lsp/handlers/handler_folding.dart
index bb721de..418e84d 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/handler_folding.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/handler_folding.dart
@@ -10,6 +10,9 @@
import 'package:analysis_server/src/lsp/handlers/handlers.dart';
import 'package:analysis_server/src/lsp/lsp_analysis_server.dart';
import 'package:analysis_server/src/lsp/mapping.dart';
+import 'package:analysis_server/src/protocol_server.dart';
+import 'package:analyzer/dart/analysis/results.dart';
+import 'package:analyzer/source/line_info.dart';
class FoldingHandler
extends MessageHandler<FoldingRangeParams, List<FoldingRange>> {
@@ -24,16 +27,36 @@
@override
Future<ErrorOr<List<FoldingRange>>> handle(
FoldingRangeParams params, CancellationToken token) async {
- if (!isDartDocument(params.textDocument)) {
- return success(const []);
- }
-
final path = pathOfDoc(params.textDocument);
- final unit = await path.mapResult(requireUnresolvedUnit);
- return unit.mapResult((unit) {
- final lineInfo = unit.lineInfo;
- final regions = DartUnitFoldingComputer(lineInfo, unit.unit).compute();
+ return path.mapResult((path) async {
+ final partialResults = <List<FoldingRegion>>[];
+ LineInfo lineInfo;
+
+ final unit = server.getParsedUnit(path);
+ if (unit?.state == ResultState.VALID) {
+ lineInfo = unit.lineInfo;
+
+ final regions = DartUnitFoldingComputer(lineInfo, unit.unit).compute();
+ partialResults.insert(0, regions);
+ }
+
+ // Still try to obtain line info for invalid or non-Dart files, as plugins
+ // could contribute to those.
+ lineInfo ??= server.getLineInfo(path);
+
+ if (lineInfo == null) {
+ // Line information would be required to translate folding results to
+ // LSP.
+ return success(const []);
+ }
+
+ final notificationManager = server.notificationManager;
+ final pluginResults = notificationManager.folding.getResults(path);
+ partialResults.addAll(pluginResults);
+
+ final regions =
+ notificationManager.merger.mergeFoldingRegions(partialResults);
return success(
regions.map((region) => toFoldingRange(lineInfo, region)).toList(),
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/handler_initialize.dart b/pkg/analysis_server/lib/src/lsp/handlers/handler_initialize.dart
index eeee66f..7df227a 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/handler_initialize.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/handler_initialize.dart
@@ -4,88 +4,10 @@
import 'package:analysis_server/lsp_protocol/protocol_generated.dart';
import 'package:analysis_server/lsp_protocol/protocol_special.dart';
-import 'package:analysis_server/src/lsp/constants.dart';
import 'package:analysis_server/src/lsp/handlers/handler_states.dart';
import 'package:analysis_server/src/lsp/handlers/handlers.dart';
import 'package:analysis_server/src/lsp/lsp_analysis_server.dart';
-/// Helper for reading client dynamic registrations which may be ommitted by the
-/// client.
-class ClientDynamicRegistrations {
- /// All dynamic registrations supported by the Dart LSP server.
- ///
- /// Anything listed here and supported by the client will not send a static
- /// registration but intead dynamically register (usually only for a subset of
- /// files such as for .dart/pubspec.yaml/etc).
- ///
- /// When adding new capabilities that will be registered dynamically, the
- /// test_dynamicRegistration_XXX tests in `lsp/initialization_test.dart` should
- /// also be updated to ensure no double-registrations.
- static const supported = [
- Method.textDocument_didOpen,
- Method.textDocument_didChange,
- Method.textDocument_didClose,
- Method.textDocument_completion,
- Method.textDocument_hover,
- Method.textDocument_signatureHelp,
- Method.textDocument_references,
- Method.textDocument_documentHighlight,
- Method.textDocument_formatting,
- Method.textDocument_onTypeFormatting,
- Method.textDocument_definition,
- Method.textDocument_codeAction,
- Method.textDocument_rename,
- Method.textDocument_foldingRange,
- ];
- final ClientCapabilities _capabilities;
-
- ClientDynamicRegistrations(this._capabilities);
-
- bool get codeActions =>
- _capabilities.textDocument?.foldingRange?.dynamicRegistration ?? false;
-
- bool get completion =>
- _capabilities.textDocument?.completion?.dynamicRegistration ?? false;
-
- bool get definition =>
- _capabilities.textDocument?.definition?.dynamicRegistration ?? false;
-
- bool get documentHighlights =>
- _capabilities.textDocument?.documentHighlight?.dynamicRegistration ??
- false;
-
- bool get documentSymbol =>
- _capabilities.textDocument?.documentSymbol?.dynamicRegistration ?? false;
-
- bool get folding =>
- _capabilities.textDocument?.foldingRange?.dynamicRegistration ?? false;
-
- bool get formatting =>
- _capabilities.textDocument?.formatting?.dynamicRegistration ?? false;
-
- bool get hover =>
- _capabilities.textDocument?.hover?.dynamicRegistration ?? false;
-
- bool get implementation =>
- _capabilities.textDocument?.implementation?.dynamicRegistration ?? false;
-
- bool get references =>
- _capabilities.textDocument?.references?.dynamicRegistration ?? false;
-
- bool get rename =>
- _capabilities.textDocument?.rename?.dynamicRegistration ?? false;
-
- bool get signatureHelp =>
- _capabilities.textDocument?.signatureHelp?.dynamicRegistration ?? false;
-
- bool get textSync =>
- _capabilities.textDocument?.synchronization?.dynamicRegistration ?? false;
-
- bool get typeFormatting =>
- _capabilities.textDocument?.onTypeFormatting?.dynamicRegistration ??
- false;
-}
-
class InitializeMessageHandler
extends MessageHandler<InitializeParams, InitializeResult> {
InitializeMessageHandler(LspAnalysisServer server) : super(server);
@@ -131,92 +53,8 @@
openWorkspacePaths,
);
- final codeActionLiteralSupport =
- params.capabilities.textDocument?.codeAction?.codeActionLiteralSupport;
-
- final renameOptionsSupport =
- params.capabilities.textDocument?.rename?.prepareSupport ?? false;
-
- final dynamicRegistrations =
- ClientDynamicRegistrations(params.capabilities);
-
- // When adding new capabilities to the server that may apply to specific file
- // types, it's important to update
- // [IntializedMessageHandler._performDynamicRegistration()] to notify
- // supporting clients of this. This avoids clients needing to hard-code the
- // list of what files types we support (and allows them to avoid sending
- // requests where we have only partial support for some types).
- server.capabilities = ServerCapabilities(
- dynamicRegistrations.textSync
- ? null
- : Either2<TextDocumentSyncOptions, num>.t1(TextDocumentSyncOptions(
- // The open/close and sync kind flags are registered dynamically if the
- // client supports them, so these static registrations are based on whether
- // the client supports dynamic registration.
- true,
- TextDocumentSyncKind.Incremental,
- false,
- false,
- null,
- )),
- dynamicRegistrations.hover ? null : true, // hoverProvider
- dynamicRegistrations.completion
- ? null
- : CompletionOptions(
- true, // resolveProvider
- dartCompletionTriggerCharacters,
- ),
- dynamicRegistrations.signatureHelp
- ? null
- : SignatureHelpOptions(
- dartSignatureHelpTriggerCharacters,
- ),
- dynamicRegistrations.definition ? null : true, // definitionProvider
- null,
- dynamicRegistrations.implementation
- ? null
- : true, // implementationProvider
- dynamicRegistrations.references ? null : true, // referencesProvider
- dynamicRegistrations.documentHighlights
- ? null
- : true, // documentHighlightProvider
- dynamicRegistrations.documentSymbol
- ? null
- : true, // documentSymbolProvider
- true, // workspaceSymbolProvider
- // "The `CodeActionOptions` return type is only valid if the client
- // signals code action literal support via the property
- // `textDocument.codeAction.codeActionLiteralSupport`."
- dynamicRegistrations.codeActions
- ? null
- : codeActionLiteralSupport != null
- ? Either2<bool, CodeActionOptions>.t2(
- CodeActionOptions(DartCodeActionKind.serverSupportedKinds))
- : Either2<bool, CodeActionOptions>.t1(true),
- null,
- dynamicRegistrations.formatting
- ? null
- : true, // documentFormattingProvider
- false, // documentRangeFormattingProvider
- dynamicRegistrations.typeFormatting
- ? null
- : DocumentOnTypeFormattingOptions(
- dartTypeFormattingCharacters.first,
- dartTypeFormattingCharacters.skip(1).toList()),
- dynamicRegistrations.rename
- ? null
- : renameOptionsSupport
- ? Either2<bool, RenameOptions>.t2(RenameOptions(true))
- : Either2<bool, RenameOptions>.t1(true),
- null,
- null,
- dynamicRegistrations.folding ? null : true, // foldingRangeProvider
- null, // declarationProvider
- ExecuteCommandOptions(Commands.serverSupportedCommands),
- ServerCapabilitiesWorkspace(
- ServerCapabilitiesWorkspaceFolders(true, true)),
- null);
-
+ server.capabilities = server.capabilitiesComputer
+ .computeServerCapabilities(params.capabilities);
return success(InitializeResult(server.capabilities));
}
}
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/handler_initialized.dart b/pkg/analysis_server/lib/src/lsp/handlers/handler_initialized.dart
index 854eaf5..f1cbeba 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/handler_initialized.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/handler_initialized.dart
@@ -4,7 +4,6 @@
import 'package:analysis_server/lsp_protocol/protocol_generated.dart';
import 'package:analysis_server/lsp_protocol/protocol_special.dart';
-import 'package:analysis_server/src/lsp/constants.dart';
import 'package:analysis_server/src/lsp/handlers/handler_states.dart';
import 'package:analysis_server/src/lsp/handlers/handlers.dart';
import 'package:analysis_server/src/lsp/lsp_analysis_server.dart';
@@ -28,7 +27,7 @@
server,
);
- _performDynamicRegistration();
+ server.capabilitiesComputer.performDynamicRegistration();
if (!server.initializationOptions.onlyAnalyzeProjectsWithOpenFiles) {
server.setAnalysisRoots(openWorkspacePaths);
@@ -36,146 +35,4 @@
return success();
}
-
- /// If the client supports dynamic registrations we can tell it what methods
- /// we support for which documents. For example, this allows us to ask for
- /// file edits for .dart as well as pubspec.yaml but only get hover/completion
- /// calls for .dart. This functionality may not be supported by the client, in
- /// which case they will use the ServerCapabilities to know which methods we
- /// support and it will be up to them to decide which file types they will
- /// send requests for.
- Future<void> _performDynamicRegistration() async {
- final dartFiles = DocumentFilter('dart', 'file', null);
- final pubspecFile = DocumentFilter('yaml', 'file', '**/pubspec.yaml');
- final analysisOptionsFile =
- DocumentFilter('yaml', 'file', '**/analysis_options.yaml');
- final allTypes = [dartFiles, pubspecFile, analysisOptionsFile];
-
- // TODO(dantup): When we support plugins, we will need to collect their
- // requirements too. For example, the Angular plugin might wish to add HTML
- // `DocumentFilter('html', 'file', null)` to many of these requests.
-
- var _lastRegistrationId = 1;
- final registrations = <Registration>[];
-
- /// Helper for creating registrations with IDs.
- void register(bool condition, Method method, [ToJsonable options]) {
- if (condition == true) {
- registrations.add(Registration(
- (_lastRegistrationId++).toString(), method.toJson(), options));
- }
- }
-
- final textCapabilities = server.clientCapabilities?.textDocument;
-
- register(
- textCapabilities?.synchronization?.dynamicRegistration,
- Method.textDocument_didOpen,
- TextDocumentRegistrationOptions(allTypes),
- );
- register(
- textCapabilities?.synchronization?.dynamicRegistration,
- Method.textDocument_didClose,
- TextDocumentRegistrationOptions(allTypes),
- );
- register(
- textCapabilities?.synchronization?.dynamicRegistration,
- Method.textDocument_didChange,
- TextDocumentChangeRegistrationOptions(
- TextDocumentSyncKind.Incremental, allTypes),
- );
- register(
- server.clientCapabilities?.textDocument?.completion?.dynamicRegistration,
- Method.textDocument_completion,
- CompletionRegistrationOptions(
- dartCompletionTriggerCharacters,
- null,
- true,
- [dartFiles],
- ),
- );
- register(
- textCapabilities?.hover?.dynamicRegistration,
- Method.textDocument_hover,
- TextDocumentRegistrationOptions([dartFiles]),
- );
- register(
- textCapabilities?.signatureHelp?.dynamicRegistration,
- Method.textDocument_signatureHelp,
- SignatureHelpRegistrationOptions(
- dartSignatureHelpTriggerCharacters, [dartFiles]),
- );
- register(
- server.clientCapabilities?.textDocument?.references?.dynamicRegistration,
- Method.textDocument_references,
- TextDocumentRegistrationOptions([dartFiles]),
- );
- register(
- textCapabilities?.documentHighlight?.dynamicRegistration,
- Method.textDocument_documentHighlight,
- TextDocumentRegistrationOptions([dartFiles]),
- );
- register(
- textCapabilities?.documentSymbol?.dynamicRegistration,
- Method.textDocument_documentSymbol,
- TextDocumentRegistrationOptions([dartFiles]),
- );
- register(
- server.clientCapabilities?.textDocument?.formatting?.dynamicRegistration,
- Method.textDocument_formatting,
- TextDocumentRegistrationOptions([dartFiles]),
- );
- register(
- textCapabilities?.onTypeFormatting?.dynamicRegistration,
- Method.textDocument_onTypeFormatting,
- DocumentOnTypeFormattingRegistrationOptions(
- dartTypeFormattingCharacters.first,
- dartTypeFormattingCharacters.skip(1).toList(),
- [dartFiles],
- ),
- );
- register(
- server.clientCapabilities?.textDocument?.definition?.dynamicRegistration,
- Method.textDocument_definition,
- TextDocumentRegistrationOptions([dartFiles]),
- );
- register(
- textCapabilities?.implementation?.dynamicRegistration,
- Method.textDocument_implementation,
- TextDocumentRegistrationOptions([dartFiles]),
- );
- register(
- server.clientCapabilities?.textDocument?.codeAction?.dynamicRegistration,
- Method.textDocument_codeAction,
- CodeActionRegistrationOptions(
- [dartFiles], DartCodeActionKind.serverSupportedKinds),
- );
- register(
- textCapabilities?.rename?.dynamicRegistration,
- Method.textDocument_rename,
- RenameRegistrationOptions(true, [dartFiles]),
- );
- register(
- textCapabilities?.foldingRange?.dynamicRegistration,
- Method.textDocument_foldingRange,
- TextDocumentRegistrationOptions([dartFiles]),
- );
-
- // Only send the registration request if we have at least one (since
- // otherwise we don't know that the client supports registerCapability).
- if (registrations.isNotEmpty) {
- final registrationResponse = await server.sendRequest(
- Method.client_registerCapability,
- RegistrationParams(registrations),
- );
-
- if (registrationResponse.error != null) {
- server.logErrorToClient(
- 'Failed to register capabilities with client: '
- '(${registrationResponse.error.code}) '
- '${registrationResponse.error.message}',
- );
- }
- }
- }
}
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/handler_references.dart b/pkg/analysis_server/lib/src/lsp/handlers/handler_references.dart
index be37eac..bf4094e 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/handler_references.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/handler_references.dart
@@ -6,7 +6,6 @@
import 'package:analysis_server/lsp_protocol/protocol_generated.dart';
import 'package:analysis_server/lsp_protocol/protocol_special.dart';
-import 'package:analysis_server/src/domains/analysis/navigation_dart.dart';
import 'package:analysis_server/src/lsp/handlers/handlers.dart';
import 'package:analysis_server/src/lsp/lsp_analysis_server.dart';
import 'package:analysis_server/src/lsp/mapping.dart';
@@ -17,6 +16,7 @@
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer_plugin/src/utilities/navigation/navigation.dart';
+import 'package:analyzer_plugin/utilities/navigation/navigation_dart.dart';
class ReferencesHandler
extends MessageHandler<ReferenceParams, List<Location>> {
diff --git a/pkg/analysis_server/lib/src/lsp/lsp_analysis_server.dart b/pkg/analysis_server/lib/src/lsp/lsp_analysis_server.dart
index c91a44c..cecd4f4 100644
--- a/pkg/analysis_server/lib/src/lsp/lsp_analysis_server.dart
+++ b/pkg/analysis_server/lib/src/lsp/lsp_analysis_server.dart
@@ -11,6 +11,7 @@
import 'package:analysis_server/protocol/protocol_generated.dart' as protocol;
import 'package:analysis_server/src/analysis_server.dart';
import 'package:analysis_server/src/analysis_server_abstract.dart';
+import 'package:analysis_server/src/channel/channel.dart';
import 'package:analysis_server/src/collections.dart';
import 'package:analysis_server/src/computer/computer_closingLabels.dart';
import 'package:analysis_server/src/computer/computer_outline.dart';
@@ -23,7 +24,9 @@
import 'package:analysis_server/src/lsp/handlers/handler_states.dart';
import 'package:analysis_server/src/lsp/handlers/handlers.dart';
import 'package:analysis_server/src/lsp/mapping.dart';
+import 'package:analysis_server/src/lsp/server_capabilities_computer.dart';
import 'package:analysis_server/src/plugin/notification_manager.dart';
+import 'package:analysis_server/src/plugin/plugin_manager.dart';
import 'package:analysis_server/src/protocol_server.dart' as protocol;
import 'package:analysis_server/src/server/crash_reporting_attachments.dart';
import 'package:analysis_server/src/server/diagnostic_server.dart';
@@ -42,6 +45,7 @@
import 'package:analyzer/src/dart/analysis/status.dart' as nd;
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/sdk.dart';
+import 'package:analyzer_plugin/protocol/protocol_generated.dart' as plugin;
import 'package:watcher/watcher.dart';
/// Instances of the class [LspAnalysisServer] implement an LSP-based server
@@ -81,6 +85,7 @@
/// Capabilities of the server. Will be null prior to initialization as
/// the server capabilities depend on the client capabilities.
ServerCapabilities capabilities;
+ ServerCapabilitiesComputer capabilitiesComputer;
LspPerformance performanceStats = LspPerformance();
@@ -88,6 +93,8 @@
/// automatically.
bool willExit = false;
+ StreamSubscription _pluginChangeSubscription;
+
/// Initialize a newly created server to send and receive messages to the
/// given [channel].
LspAnalysisServer(
@@ -99,14 +106,19 @@
InstrumentationService instrumentationService, {
DiagnosticServer diagnosticServer,
}) : super(
- options,
- sdkManager,
- diagnosticServer,
- crashReportingAttachmentsBuilder,
- baseResourceProvider,
- instrumentationService,
- NullNotificationManager()) {
+ options,
+ sdkManager,
+ diagnosticServer,
+ crashReportingAttachmentsBuilder,
+ baseResourceProvider,
+ instrumentationService,
+ NotificationManager(
+ const NoOpServerCommunicationChannel(),
+ baseResourceProvider.pathContext,
+ ),
+ ) {
messageHandler = UninitializedStateMessageHandler(this);
+ capabilitiesComputer = ServerCapabilitiesComputer(this);
final contextManagerCallbacks =
LspServerContextManagerCallbacks(this, resourceProvider);
@@ -116,6 +128,8 @@
analysisDriverScheduler.start();
channel.listen(handleMessage, onDone: done, onError: socketError);
+ _pluginChangeSubscription =
+ pluginManager.pluginsChanged.listen((_) => _onPluginsChanged());
}
/// The capabilities of the LSP client. Will be null prior to initialization.
@@ -127,6 +141,16 @@
/// specific server functionality. Will be null prior to initialization.
LspInitializationOptions get initializationOptions => _initializationOptions;
+ @override
+ set pluginManager(PluginManager value) {
+ // we exchange the plugin manager in tests
+ super.pluginManager = value;
+ _pluginChangeSubscription?.cancel();
+
+ _pluginChangeSubscription =
+ pluginManager.pluginsChanged.listen((_) => _onPluginsChanged());
+ }
+
RefactoringWorkspace get refactoringWorkspace => _refactoringWorkspace ??=
RefactoringWorkspace(driverMap.values, searchEngine);
@@ -134,7 +158,7 @@
final didAdd = priorityFiles.add(path);
assert(didAdd);
if (didAdd) {
- _updateDriversPriorityFiles();
+ _updateDriversAndPluginsPriorityFiles();
}
}
@@ -315,7 +339,7 @@
final didRemove = priorityFiles.remove(path);
assert(didRemove);
if (didRemove) {
- _updateDriversPriorityFiles();
+ _updateDriversAndPluginsPriorityFiles();
}
}
@@ -398,6 +422,7 @@
declarationsTracker?.discardContexts();
final uniquePaths = HashSet<String>.of(includedPaths ?? const []);
contextManager.setRoots(uniquePaths.toList(), [], {});
+ notificationManager.setAnalysisRoots(includedPaths, []);
addContextsToDeclarationsTracker();
}
@@ -457,6 +482,7 @@
Future(() {
channel.close();
});
+ _pluginChangeSubscription?.cancel();
return Future.value();
}
@@ -491,9 +517,32 @@
notifyFlutterWidgetDescriptions(path);
}
- void _updateDriversPriorityFiles() {
+ void _onPluginsChanged() {
+ capabilitiesComputer.performDynamicRegistration();
+ }
+
+ void _updateDriversAndPluginsPriorityFiles() {
+ final priorityFilesList = priorityFiles.toList();
driverMap.values.forEach((driver) {
- driver.priorityFiles = priorityFiles.toList();
+ driver.priorityFiles = priorityFilesList;
+ });
+
+ final pluginPriorities =
+ plugin.AnalysisSetPriorityFilesParams(priorityFilesList);
+ pluginManager.setAnalysisSetPriorityFilesParams(pluginPriorities);
+
+ // Plugins send most of their analysis results via notifications, but with
+ // LSP we're supposed to have them available per request. Assume that we'll
+ // only receive requests for files that are currently open.
+ final pluginSubscriptions = plugin.AnalysisSetSubscriptionsParams({
+ for (final service in plugin.AnalysisService.VALUES)
+ service: priorityFilesList,
+ });
+ pluginManager.setAnalysisSetSubscriptionsParams(pluginSubscriptions);
+
+ notificationManager.setSubscriptions({
+ for (final service in protocol.AnalysisService.VALUES)
+ service: priorityFiles
});
}
}
@@ -665,7 +714,19 @@
}
}
-class NullNotificationManager implements NotificationManager {
+class NoOpServerCommunicationChannel implements ServerCommunicationChannel {
+ const NoOpServerCommunicationChannel();
+
@override
- dynamic noSuchMethod(Invocation invocation) {}
+ void close() {}
+
+ @override
+ void listen(void Function(protocol.Request request) onRequest,
+ {Function onError, void Function() onDone}) {}
+
+ @override
+ void sendNotification(protocol.Notification notification) {}
+
+ @override
+ void sendResponse(protocol.Response response) {}
}
diff --git a/pkg/analysis_server/lib/src/lsp/server_capabilities_computer.dart b/pkg/analysis_server/lib/src/lsp/server_capabilities_computer.dart
new file mode 100644
index 0000000..a359d36
--- /dev/null
+++ b/pkg/analysis_server/lib/src/lsp/server_capabilities_computer.dart
@@ -0,0 +1,371 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analysis_server/lsp_protocol/protocol_generated.dart';
+import 'package:analysis_server/lsp_protocol/protocol_special.dart';
+import 'package:analysis_server/src/lsp/constants.dart';
+import 'package:analysis_server/src/lsp/lsp_analysis_server.dart';
+
+/// Helper for reading client dynamic registrations which may be ommitted by the
+/// client.
+class ClientDynamicRegistrations {
+ /// All dynamic registrations supported by the Dart LSP server.
+ ///
+ /// Anything listed here and supported by the client will not send a static
+ /// registration but intead dynamically register (usually only for a subset of
+ /// files such as for .dart/pubspec.yaml/etc).
+ ///
+ /// When adding new capabilities that will be registered dynamically, the
+ /// test_dynamicRegistration_XXX tests in `lsp/initialization_test.dart` should
+ /// also be updated to ensure no double-registrations.
+ static const supported = [
+ Method.textDocument_didOpen,
+ Method.textDocument_didChange,
+ Method.textDocument_didClose,
+ Method.textDocument_completion,
+ Method.textDocument_hover,
+ Method.textDocument_signatureHelp,
+ Method.textDocument_references,
+ Method.textDocument_documentHighlight,
+ Method.textDocument_formatting,
+ Method.textDocument_onTypeFormatting,
+ Method.textDocument_definition,
+ Method.textDocument_codeAction,
+ Method.textDocument_rename,
+ Method.textDocument_foldingRange,
+ ];
+ final ClientCapabilities _capabilities;
+
+ ClientDynamicRegistrations(this._capabilities);
+
+ bool get codeActions =>
+ _capabilities.textDocument?.foldingRange?.dynamicRegistration ?? false;
+
+ bool get completion =>
+ _capabilities.textDocument?.completion?.dynamicRegistration ?? false;
+
+ bool get definition =>
+ _capabilities.textDocument?.definition?.dynamicRegistration ?? false;
+
+ bool get documentHighlights =>
+ _capabilities.textDocument?.documentHighlight?.dynamicRegistration ??
+ false;
+
+ bool get documentSymbol =>
+ _capabilities.textDocument?.documentSymbol?.dynamicRegistration ?? false;
+
+ bool get folding =>
+ _capabilities.textDocument?.foldingRange?.dynamicRegistration ?? false;
+
+ bool get formatting =>
+ _capabilities.textDocument?.formatting?.dynamicRegistration ?? false;
+
+ bool get hover =>
+ _capabilities.textDocument?.hover?.dynamicRegistration ?? false;
+
+ bool get implementation =>
+ _capabilities.textDocument?.implementation?.dynamicRegistration ?? false;
+
+ bool get references =>
+ _capabilities.textDocument?.references?.dynamicRegistration ?? false;
+
+ bool get rename =>
+ _capabilities.textDocument?.rename?.dynamicRegistration ?? false;
+
+ bool get signatureHelp =>
+ _capabilities.textDocument?.signatureHelp?.dynamicRegistration ?? false;
+
+ bool get textSync =>
+ _capabilities.textDocument?.synchronization?.dynamicRegistration ?? false;
+
+ bool get typeFormatting =>
+ _capabilities.textDocument?.onTypeFormatting?.dynamicRegistration ??
+ false;
+}
+
+class ServerCapabilitiesComputer {
+ final LspAnalysisServer _server;
+
+ /// Map from method name to current registration data.
+ Map<String, Registration> _currentRegistrations = {};
+ var _lastRegistrationId = 0;
+
+ ServerCapabilitiesComputer(this._server);
+
+ ServerCapabilities computeServerCapabilities(
+ ClientCapabilities clientCapabilities) {
+ final codeActionLiteralSupport =
+ clientCapabilities.textDocument?.codeAction?.codeActionLiteralSupport;
+
+ final renameOptionsSupport =
+ clientCapabilities.textDocument?.rename?.prepareSupport ?? false;
+
+ final dynamicRegistrations = ClientDynamicRegistrations(clientCapabilities);
+
+ // When adding new capabilities to the server that may apply to specific file
+ // types, it's important to update
+ // [IntializedMessageHandler._performDynamicRegistration()] to notify
+ // supporting clients of this. This avoids clients needing to hard-code the
+ // list of what files types we support (and allows them to avoid sending
+ // requests where we have only partial support for some types).
+ return ServerCapabilities(
+ dynamicRegistrations.textSync
+ ? null
+ : Either2<TextDocumentSyncOptions, num>.t1(TextDocumentSyncOptions(
+ // The open/close and sync kind flags are registered dynamically if the
+ // client supports them, so these static registrations are based on whether
+ // the client supports dynamic registration.
+ true,
+ TextDocumentSyncKind.Incremental,
+ false,
+ false,
+ null,
+ )),
+ dynamicRegistrations.hover ? null : true, // hoverProvider
+ dynamicRegistrations.completion
+ ? null
+ : CompletionOptions(
+ true, // resolveProvider
+ dartCompletionTriggerCharacters,
+ ),
+ dynamicRegistrations.signatureHelp
+ ? null
+ : SignatureHelpOptions(
+ dartSignatureHelpTriggerCharacters,
+ ),
+ dynamicRegistrations.definition ? null : true, // definitionProvider
+ null,
+ dynamicRegistrations.implementation
+ ? null
+ : true, // implementationProvider
+ dynamicRegistrations.references ? null : true, // referencesProvider
+ dynamicRegistrations.documentHighlights
+ ? null
+ : true, // documentHighlightProvider
+ dynamicRegistrations.documentSymbol
+ ? null
+ : true, // documentSymbolProvider
+ true, // workspaceSymbolProvider
+ // "The `CodeActionOptions` return type is only valid if the client
+ // signals code action literal support via the property
+ // `textDocument.codeAction.codeActionLiteralSupport`."
+ dynamicRegistrations.codeActions
+ ? null
+ : codeActionLiteralSupport != null
+ ? Either2<bool, CodeActionOptions>.t2(
+ CodeActionOptions(DartCodeActionKind.serverSupportedKinds))
+ : Either2<bool, CodeActionOptions>.t1(true),
+ null,
+ dynamicRegistrations.formatting
+ ? null
+ : true, // documentFormattingProvider
+ false, // documentRangeFormattingProvider
+ dynamicRegistrations.typeFormatting
+ ? null
+ : DocumentOnTypeFormattingOptions(
+ dartTypeFormattingCharacters.first,
+ dartTypeFormattingCharacters.skip(1).toList()),
+ dynamicRegistrations.rename
+ ? null
+ : renameOptionsSupport
+ ? Either2<bool, RenameOptions>.t2(RenameOptions(true))
+ : Either2<bool, RenameOptions>.t1(true),
+ null,
+ null,
+ dynamicRegistrations.folding ? null : true, // foldingRangeProvider
+ null, // declarationProvider
+ ExecuteCommandOptions(Commands.serverSupportedCommands),
+ ServerCapabilitiesWorkspace(
+ ServerCapabilitiesWorkspaceFolders(true, true)),
+ null);
+ }
+
+ /// If the client supports dynamic registrations we can tell it what methods
+ /// we support for which documents. For example, this allows us to ask for
+ /// file edits for .dart as well as pubspec.yaml but only get hover/completion
+ /// calls for .dart. This functionality may not be supported by the client, in
+ /// which case they will use the ServerCapabilities to know which methods we
+ /// support and it will be up to them to decide which file types they will
+ /// send requests for.
+ Future<void> performDynamicRegistration() async {
+ final dartFiles = DocumentFilter('dart', 'file', null);
+ final pubspecFile = DocumentFilter('yaml', 'file', '**/pubspec.yaml');
+ final analysisOptionsFile =
+ DocumentFilter('yaml', 'file', '**/analysis_options.yaml');
+
+ final pluginTypes = _server.pluginManager.plugins
+ .expand((plugin) => plugin.currentSession?.interestingFiles ?? const [])
+ // All published plugins use something like `*.extension` as
+ // interestingFiles. Prefix a `**/` so that the glob matches nested
+ // folders as well.
+ .map((glob) => DocumentFilter(null, 'file', '**/$glob'));
+
+ final allTypes = [
+ dartFiles,
+ pubspecFile,
+ analysisOptionsFile,
+ ...pluginTypes
+ ];
+
+ final registrations = <Registration>[];
+
+ /// Helper for creating registrations with IDs.
+ void register(bool condition, Method method, [ToJsonable options]) {
+ if (condition == true) {
+ registrations.add(Registration(
+ (_lastRegistrationId++).toString(), method.toJson(), options));
+ }
+ }
+
+ final textCapabilities = _server.clientCapabilities?.textDocument;
+
+ register(
+ textCapabilities?.synchronization?.dynamicRegistration,
+ Method.textDocument_didOpen,
+ TextDocumentRegistrationOptions(allTypes),
+ );
+ register(
+ textCapabilities?.synchronization?.dynamicRegistration,
+ Method.textDocument_didClose,
+ TextDocumentRegistrationOptions(allTypes),
+ );
+ register(
+ textCapabilities?.synchronization?.dynamicRegistration,
+ Method.textDocument_didChange,
+ TextDocumentChangeRegistrationOptions(
+ TextDocumentSyncKind.Incremental, allTypes),
+ );
+ register(
+ _server.clientCapabilities?.textDocument?.completion?.dynamicRegistration,
+ Method.textDocument_completion,
+ CompletionRegistrationOptions(
+ dartCompletionTriggerCharacters,
+ null,
+ true,
+ [dartFiles],
+ ),
+ );
+ register(
+ textCapabilities?.hover?.dynamicRegistration,
+ Method.textDocument_hover,
+ TextDocumentRegistrationOptions([dartFiles]),
+ );
+ register(
+ textCapabilities?.signatureHelp?.dynamicRegistration,
+ Method.textDocument_signatureHelp,
+ SignatureHelpRegistrationOptions(
+ dartSignatureHelpTriggerCharacters, [dartFiles]),
+ );
+ register(
+ _server.clientCapabilities?.textDocument?.references?.dynamicRegistration,
+ Method.textDocument_references,
+ TextDocumentRegistrationOptions([dartFiles]),
+ );
+ register(
+ textCapabilities?.documentHighlight?.dynamicRegistration,
+ Method.textDocument_documentHighlight,
+ TextDocumentRegistrationOptions([dartFiles]),
+ );
+ register(
+ textCapabilities?.documentSymbol?.dynamicRegistration,
+ Method.textDocument_documentSymbol,
+ TextDocumentRegistrationOptions([dartFiles]),
+ );
+ register(
+ _server.clientCapabilities?.textDocument?.formatting?.dynamicRegistration,
+ Method.textDocument_formatting,
+ TextDocumentRegistrationOptions([dartFiles]),
+ );
+ register(
+ textCapabilities?.onTypeFormatting?.dynamicRegistration,
+ Method.textDocument_onTypeFormatting,
+ DocumentOnTypeFormattingRegistrationOptions(
+ dartTypeFormattingCharacters.first,
+ dartTypeFormattingCharacters.skip(1).toList(),
+ [dartFiles],
+ ),
+ );
+ register(
+ _server.clientCapabilities?.textDocument?.definition?.dynamicRegistration,
+ Method.textDocument_definition,
+ TextDocumentRegistrationOptions([dartFiles]),
+ );
+ register(
+ textCapabilities?.implementation?.dynamicRegistration,
+ Method.textDocument_implementation,
+ TextDocumentRegistrationOptions([dartFiles]),
+ );
+ register(
+ _server.clientCapabilities?.textDocument?.codeAction?.dynamicRegistration,
+ Method.textDocument_codeAction,
+ CodeActionRegistrationOptions(
+ [dartFiles], DartCodeActionKind.serverSupportedKinds),
+ );
+ register(
+ textCapabilities?.rename?.dynamicRegistration,
+ Method.textDocument_rename,
+ RenameRegistrationOptions(true, [dartFiles]),
+ );
+ register(
+ textCapabilities?.foldingRange?.dynamicRegistration,
+ Method.textDocument_foldingRange,
+ TextDocumentRegistrationOptions(allTypes),
+ );
+
+ await _applyRegistrations(registrations);
+ }
+
+ Future<void> _applyRegistrations(List<Registration> registrations) async {
+ final newRegistrationsByMethod = {
+ for (final registration in registrations)
+ registration.method: registration
+ };
+
+ final additionalRegistrations = List.of(registrations);
+ final removedRegistrations = <Unregistration>[];
+
+ // compute a diff of old and new registrations to send the unregister or
+ // another register request. We assume that we'll only ever have one
+ // registration per LSP method name.
+ for (final entry in _currentRegistrations.entries) {
+ final method = entry.key;
+ final registration = entry.value;
+
+ final newRegistrationForMethod = newRegistrationsByMethod[method];
+ final entryRemovedOrChanged = newRegistrationForMethod?.registerOptions !=
+ registration.registerOptions;
+
+ if (entryRemovedOrChanged) {
+ removedRegistrations
+ .add(Unregistration(registration.id, registration.method));
+ } else {
+ additionalRegistrations.remove(newRegistrationForMethod);
+ }
+ }
+
+ _currentRegistrations = newRegistrationsByMethod;
+
+ if (removedRegistrations.isNotEmpty) {
+ await _server.sendRequest(Method.client_unregisterCapability,
+ UnregistrationParams(removedRegistrations));
+ }
+
+ // Only send the registration request if we have at least one (since
+ // otherwise we don't know that the client supports registerCapability).
+ if (additionalRegistrations.isNotEmpty) {
+ final registrationResponse = await _server.sendRequest(
+ Method.client_registerCapability,
+ RegistrationParams(additionalRegistrations),
+ );
+
+ if (registrationResponse.error != null) {
+ _server.logErrorToClient(
+ 'Failed to register capabilities with client: '
+ '(${registrationResponse.error.code}) '
+ '${registrationResponse.error.message}',
+ );
+ }
+ }
+ }
+}
diff --git a/pkg/analysis_server/lib/src/operation/operation_analysis.dart b/pkg/analysis_server/lib/src/operation/operation_analysis.dart
index 9a0fadc..7890009 100644
--- a/pkg/analysis_server/lib/src/operation/operation_analysis.dart
+++ b/pkg/analysis_server/lib/src/operation/operation_analysis.dart
@@ -21,8 +21,6 @@
Future<void> scheduleImplementedNotification(
AnalysisServer server, Iterable<String> files) async {
- // TODO(brianwilkerson) Determine whether this await is necessary.
- await null;
var searchEngine = server.searchEngine;
if (searchEngine == null) {
return;
diff --git a/pkg/analysis_server/lib/src/plugin/plugin_manager.dart b/pkg/analysis_server/lib/src/plugin/plugin_manager.dart
index de68843..785e77b 100644
--- a/pkg/analysis_server/lib/src/plugin/plugin_manager.dart
+++ b/pkg/analysis_server/lib/src/plugin/plugin_manager.dart
@@ -195,8 +195,6 @@
/// used to interact with the plugin, or `null` if the plugin could not be
/// run.
Future<PluginSession> start(String byteStorePath, String sdkPath) async {
- // TODO(brianwilkerson) Determine whether this await is necessary.
- await null;
if (currentSession != null) {
throw StateError('Cannot start a plugin that is already running.');
}
@@ -281,6 +279,8 @@
/// plugin has been started.
final Map<String, dynamic> _overlayState = <String, dynamic>{};
+ final StreamController<void> _pluginsChanged = StreamController.broadcast();
+
/// Initialize a newly created plugin manager. The notifications from the
/// running plugins will be handled by the given [notificationManager].
PluginManager(this.resourceProvider, this.byteStorePath, this.sdkPath,
@@ -289,13 +289,14 @@
/// Return a list of all of the plugins that are currently known.
List<PluginInfo> get plugins => _pluginMap.values.toList();
+ /// Stream emitting an event when known [plugins] change.
+ Stream<void> get pluginsChanged => _pluginsChanged.stream;
+
/// Add the plugin with the given [path] to the list of plugins that should be
/// used when analyzing code for the given [contextRoot]. If the plugin had
/// not yet been started, then it will be started by this method.
Future<void> addPluginToContextRoot(
analyzer.ContextRoot contextRoot, String path) async {
- // TODO(brianwilkerson) Determine whether this await is necessary.
- await null;
var plugin = _pluginMap[path];
var isNew = plugin == null;
if (isNew) {
@@ -317,6 +318,7 @@
var session = await plugin.start(byteStorePath, sdkPath);
session?.onDone?.then((_) {
_pluginMap.remove(path);
+ _notifyPluginsChanged();
});
} catch (exception, stackTrace) {
// Record the exception (for debugging purposes) and record the fact
@@ -325,6 +327,8 @@
isNew = false;
}
}
+
+ _notifyPluginsChanged();
}
plugin.addContextRoot(contextRoot);
if (isNew) {
@@ -364,8 +368,6 @@
/// response.
Future<List<Future<Response>>> broadcastWatchEvent(
watcher.WatchEvent watchEvent) async {
- // TODO(brianwilkerson) Determine whether this await is necessary.
- await null;
var filePath = watchEvent.path;
/// Return `true` if the given glob [pattern] matches the file being
@@ -469,6 +471,7 @@
plugin.removeContextRoot(contextRoot);
if (plugin is DiscoveredPluginInfo && plugin.contextRoots.isEmpty) {
_pluginMap.remove(plugin.path);
+ _notifyPluginsChanged();
try {
plugin.stop();
} catch (e, st) {
@@ -481,8 +484,6 @@
/// Restart all currently running plugins.
Future<void> restartPlugins() async {
- // TODO(brianwilkerson) Determine whether this await is necessary.
- await null;
for (var plugin in _pluginMap.values.toList()) {
if (plugin.currentSession != null) {
//
@@ -708,6 +709,8 @@
return packagesFile;
}
+ void _notifyPluginsChanged() => _pluginsChanged.add(null);
+
/// Return the names of packages that are listed as dependencies in the given
/// [pubspecFile].
Iterable<String> _readDependecies(File pubspecFile) {
@@ -893,8 +896,6 @@
/// the given [byteStorePath]. Return `true` if the plugin is compatible and
/// running.
Future<bool> start(String byteStorePath, String sdkPath) async {
- // TODO(brianwilkerson) Determine whether this await is necessary.
- await null;
if (channel != null) {
throw StateError('Cannot start a plugin that is already running.');
}
diff --git a/pkg/analysis_server/lib/src/search/element_references.dart b/pkg/analysis_server/lib/src/search/element_references.dart
index 4b34793..ba332d9 100644
--- a/pkg/analysis_server/lib/src/search/element_references.dart
+++ b/pkg/analysis_server/lib/src/search/element_references.dart
@@ -19,8 +19,6 @@
/// Computes [SearchResult]s for [element] references.
Future<List<SearchResult>> compute(
Element element, bool withPotential) async {
- // TODO(brianwilkerson) Determine whether this await is necessary.
- await null;
var results = <SearchResult>[];
// Add element references.
@@ -40,8 +38,6 @@
/// Returns a [Future] completing with a [List] of references to [element] or
/// to the corresponding hierarchy [Element]s.
Future<List<SearchResult>> _findElementsReferences(Element element) async {
- // TODO(brianwilkerson) Determine whether this await is necessary.
- await null;
var allResults = <SearchResult>[];
var refElements = await _getRefElements(element);
for (var refElement in refElements) {
@@ -54,8 +50,6 @@
/// Returns a [Future] completing with a [List] of references to [element].
Future<List<SearchResult>> _findSingleElementReferences(
Element element) async {
- // TODO(brianwilkerson) Determine whether this await is necessary.
- await null;
var matches = await searchEngine.searchReferences(element);
matches = SearchMatch.withNotNullElement(matches);
return matches.map(toResult).toList();
diff --git a/pkg/analysis_server/lib/src/search/search_domain.dart b/pkg/analysis_server/lib/src/search/search_domain.dart
index 5ddaa75..e3ad323 100644
--- a/pkg/analysis_server/lib/src/search/search_domain.dart
+++ b/pkg/analysis_server/lib/src/search/search_domain.dart
@@ -32,8 +32,6 @@
searchEngine = server.searchEngine;
Future findElementReferences(protocol.Request request) async {
- // TODO(brianwilkerson) Determine whether this await is necessary.
- await null;
var params =
protocol.SearchFindElementReferencesParams.fromRequest(request);
var file = params.file;
@@ -65,8 +63,6 @@
}
Future findMemberDeclarations(protocol.Request request) async {
- // TODO(brianwilkerson) Determine whether this await is necessary.
- await null;
var params =
protocol.SearchFindMemberDeclarationsParams.fromRequest(request);
await server.onAnalysisComplete;
@@ -81,8 +77,6 @@
}
Future findMemberReferences(protocol.Request request) async {
- // TODO(brianwilkerson) Determine whether this await is necessary.
- await null;
var params = protocol.SearchFindMemberReferencesParams.fromRequest(request);
await server.onAnalysisComplete;
// respond
@@ -96,8 +90,6 @@
}
Future findTopLevelDeclarations(protocol.Request request) async {
- // TODO(brianwilkerson) Determine whether this await is necessary.
- await null;
var params =
protocol.SearchFindTopLevelDeclarationsParams.fromRequest(request);
try {
@@ -122,8 +114,6 @@
/// Implement the `search.getDeclarations` request.
Future getDeclarations(protocol.Request request) async {
- // TODO(brianwilkerson) Determine whether this await is necessary.
- await null;
var params =
protocol.SearchGetElementDeclarationsParams.fromRequest(request);
@@ -203,8 +193,6 @@
/// Implement the `search.getTypeHierarchy` request.
Future getTypeHierarchy(protocol.Request request) async {
- // TODO(brianwilkerson) Determine whether this await is necessary.
- await null;
var params = protocol.SearchGetTypeHierarchyParams.fromRequest(request);
var file = params.file;
// prepare element
diff --git a/pkg/analysis_server/lib/src/server/driver.dart b/pkg/analysis_server/lib/src/server/driver.dart
index 3d14a00..91c6074 100644
--- a/pkg/analysis_server/lib/src/server/driver.dart
+++ b/pkg/analysis_server/lib/src/server/driver.dart
@@ -613,9 +613,6 @@
serveResult = isolateAnalysisServer.serveIsolate(sendPort);
}
serveResult.then((_) async {
- // TODO(brianwilkerson) Determine whether this await is necessary.
- await null;
-
if (serve_http) {
httpServer.close();
}
diff --git a/pkg/analysis_server/lib/src/server/http_server.dart b/pkg/analysis_server/lib/src/server/http_server.dart
index b1d8d36..394cb9a 100644
--- a/pkg/analysis_server/lib/src/server/http_server.dart
+++ b/pkg/analysis_server/lib/src/server/http_server.dart
@@ -41,8 +41,6 @@
/// Return the port this server is bound to.
Future<int> get boundPort async {
- // TODO(brianwilkerson) Determine whether this await is necessary.
- await null;
return (await _serverFuture)?.port;
}
@@ -63,8 +61,6 @@
/// Begin serving HTTP requests over the given port.
Future<int> serveHttp([int initialPort]) async {
- // TODO(brianwilkerson) Determine whether this await is necessary.
- await null;
if (_serverFuture != null) {
return boundPort;
}
@@ -87,8 +83,6 @@
/// Handle a GET request received by the HTTP server.
Future<void> _handleGetRequest(HttpRequest request) async {
- // TODO(brianwilkerson) Determine whether this await is necessary.
- await null;
getHandler ??= DiagnosticsSite(socketServer, _printBuffer);
// TODO(brianwilkerson) Determine if await is necessary, if so, change the
// return type of [AbstractGetHandler.handleGetRequest] to `Future<void>`.
@@ -98,8 +92,6 @@
/// Attach a listener to a newly created HTTP server.
void _handleServer(HttpServer httpServer) {
httpServer.listen((HttpRequest request) async {
- // TODO(brianwilkerson) Determine whether this await is necessary.
- await null;
var updateValues = request.headers[HttpHeaders.upgradeHeader];
if (request.method == 'GET') {
await _handleGetRequest(request);
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/combinator_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/combinator_contributor.dart
index da7524d..db8e83f 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/combinator_contributor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/combinator_contributor.dart
@@ -26,12 +26,10 @@
if (directive is NamespaceDirective) {
var library = directive.uriElement as LibraryElement;
if (library != null) {
- var builder = LibraryElementSuggestionBuilder(
- request, CompletionSuggestionKind.IDENTIFIER, false, false);
for (var element in library.exportNamespace.definedNames.values) {
- element.accept(builder);
+ builder.suggestElement(element,
+ kind: CompletionSuggestionKind.IDENTIFIER);
}
- return builder.suggestions;
}
}
return const <CompletionSuggestion>[];
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/extension_member_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/extension_member_contributor.dart
index 19d6d70..1eb2d01 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/extension_member_contributor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/extension_member_contributor.dart
@@ -32,7 +32,7 @@
return const <CompletionSuggestion>[];
}
- memberBuilder = MemberSuggestionBuilder(request);
+ memberBuilder = MemberSuggestionBuilder(request, builder);
// Recompute the target because resolution might have changed it.
var expression = request.dotTarget;
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/inherited_reference_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/inherited_reference_contributor.dart
index 7be25c6..d7c061b 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/inherited_reference_contributor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/inherited_reference_contributor.dart
@@ -40,7 +40,7 @@
var classOrMixin = member.parent;
if (classOrMixin is ClassOrMixinDeclaration &&
classOrMixin.declaredElement != null) {
- memberBuilder = MemberSuggestionBuilder(request);
+ memberBuilder = MemberSuggestionBuilder(request, builder);
return _computeSuggestionsForClass(classOrMixin.declaredElement, request);
}
return const <CompletionSuggestion>[];
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/keyword_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/keyword_contributor.dart
index bbe61ce..6d08f63 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/keyword_contributor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/keyword_contributor.dart
@@ -7,6 +7,7 @@
import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
import 'package:analysis_server/src/services/completion/dart/completion_manager.dart';
import 'package:analysis_server/src/services/completion/dart/suggestion_builder.dart';
+import 'package:analysis_server/src/utilities/extensions/ast.dart';
import 'package:analyzer/dart/analysis/features.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/ast/token.dart';
@@ -63,10 +64,6 @@
int get lowKeyword =>
request.useNewRelevance ? 400 : DART_RELEVANCE_KEYWORD - 1;
- bool isEmptyBody(FunctionBody body) =>
- body is EmptyFunctionBody ||
- (body is BlockFunctionBody && body.beginToken.isSynthetic);
-
@override
void visitArgumentList(ArgumentList node) {
if (request is DartCompletionRequestImpl) {
@@ -151,7 +148,7 @@
}
}
_addStatementKeywords(node);
- if (_inCatchClause(node)) {
+ if (node.inCatchClause) {
_addSuggestion(Keyword.RETHROW, relevance: lowKeyword);
}
}
@@ -168,7 +165,7 @@
_addClassBodyKeywords();
var index = node.members.indexOf(entity);
var previous = index > 0 ? node.members[index - 1] : null;
- if (previous is MethodDeclaration && isEmptyBody(previous.body)) {
+ if (previous is MethodDeclaration && previous.body.isEmpty) {
_addSuggestion(Keyword.ASYNC);
_addSuggestion2(ASYNC_STAR);
_addSuggestion2(SYNC_STAR);
@@ -235,7 +232,7 @@
if (entity == null || entity is Declaration) {
if (previousMember is FunctionDeclaration &&
previousMember.functionExpression is FunctionExpression &&
- isEmptyBody(previousMember.functionExpression.body)) {
+ previousMember.functionExpression.body.isEmpty) {
_addSuggestion(Keyword.ASYNC, relevance: highKeyword);
_addSuggestion2(ASYNC_STAR, relevance: highKeyword);
_addSuggestion2(SYNC_STAR, relevance: highKeyword);
@@ -521,7 +518,7 @@
@override
void visitMethodDeclaration(MethodDeclaration node) {
if (entity == node.body) {
- if (isEmptyBody(node.body)) {
+ if (node.body.isEmpty) {
_addClassBodyKeywords();
_addSuggestion(Keyword.ASYNC);
_addSuggestion2(ASYNC_STAR);
@@ -569,7 +566,7 @@
_addClassBodyKeywords();
var index = node.members.indexOf(entity);
var previous = index > 0 ? node.members[index - 1] : null;
- if (previous is MethodDeclaration && isEmptyBody(previous.body)) {
+ if (previous is MethodDeclaration && previous.body.isEmpty) {
_addSuggestion(Keyword.ASYNC);
_addSuggestion2(ASYNC_STAR);
_addSuggestion2(SYNC_STAR);
@@ -772,10 +769,10 @@
Keyword.NULL,
Keyword.TRUE,
]);
- if (_inClassMemberBody(node)) {
+ if (node.inClassMemberBody) {
_addSuggestions([Keyword.SUPER, Keyword.THIS]);
}
- if (_inAsyncMethodOrFunction(node)) {
+ if (node.inAsyncMethodOrFunction) {
_addSuggestion(Keyword.AWAIT);
}
}
@@ -836,20 +833,20 @@
}
void _addStatementKeywords(AstNode node) {
- if (_inClassMemberBody(node)) {
+ if (node.inClassMemberBody) {
_addSuggestions([Keyword.SUPER, Keyword.THIS]);
}
- if (_inAsyncMethodOrFunction(node)) {
+ if (node.inAsyncMethodOrFunction) {
_addSuggestion(Keyword.AWAIT);
- } else if (_inAsyncStarOrSyncStarMethodOrFunction(node)) {
+ } else if (node.inAsyncStarOrSyncStarMethodOrFunction) {
_addSuggestion(Keyword.AWAIT);
_addSuggestion(Keyword.YIELD);
_addSuggestion2(YIELD_STAR);
}
- if (_inLoop(node)) {
+ if (node.inLoop) {
_addSuggestions([Keyword.BREAK, Keyword.CONTINUE]);
}
- if (_inSwitch(node)) {
+ if (node.inSwitch) {
_addSuggestions([Keyword.BREAK]);
}
if (_isEntityAfterIfWithoutElse(node)) {
@@ -892,48 +889,6 @@
});
}
- bool _inAsyncMethodOrFunction(AstNode node) {
- var body = node.thisOrAncestorOfType<FunctionBody>();
- return body != null && body.isAsynchronous && body.star == null;
- }
-
- bool _inAsyncStarOrSyncStarMethodOrFunction(AstNode node) {
- var body = node.thisOrAncestorOfType<FunctionBody>();
- return body != null && body.keyword != null && body.star != null;
- }
-
- bool _inCatchClause(Block node) =>
- node.thisOrAncestorOfType<CatchClause>() != null;
-
- bool _inClassMemberBody(AstNode node) {
- while (true) {
- var body = node.thisOrAncestorOfType<FunctionBody>();
- if (body == null) {
- return false;
- }
- var parent = body.parent;
- if (parent is ConstructorDeclaration || parent is MethodDeclaration) {
- return true;
- }
- node = parent;
- }
- }
-
- bool _inDoLoop(AstNode node) =>
- node.thisOrAncestorOfType<DoStatement>() != null;
-
- bool _inForLoop(AstNode node) =>
- node.thisOrAncestorMatching((p) => p is ForStatement) != null;
-
- bool _inLoop(AstNode node) =>
- _inDoLoop(node) || _inForLoop(node) || _inWhileLoop(node);
-
- bool _inSwitch(AstNode node) =>
- node.thisOrAncestorOfType<SwitchStatement>() != null;
-
- bool _inWhileLoop(AstNode node) =>
- node.thisOrAncestorOfType<WhileStatement>() != null;
-
bool _isEntityAfterIfWithoutElse(AstNode node) {
var block = node?.thisOrAncestorOfType<Block>();
if (block == null) {
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/library_member_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/library_member_contributor.dart
index 24e45fc..f011a42 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/library_member_contributor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/library_member_contributor.dart
@@ -31,7 +31,7 @@
if (containingLibrary != null) {
var imports = containingLibrary.imports;
if (imports != null) {
- return _buildSuggestions(request, elem, imports);
+ return _buildSuggestions(request, builder, elem, imports);
}
}
}
@@ -39,35 +39,50 @@
return const <CompletionSuggestion>[];
}
- List<CompletionSuggestion> _buildSuggestions(DartCompletionRequest request,
- PrefixElement elem, List<ImportElement> imports) {
+ List<CompletionSuggestion> _buildSuggestions(
+ DartCompletionRequest request,
+ SuggestionBuilder builder,
+ PrefixElement elem,
+ List<ImportElement> imports) {
var parent = request.target.containingNode.parent;
- var isConstructor = parent.parent is ConstructorName;
var typesOnly = parent is TypeName;
- var instCreation = typesOnly && isConstructor;
- var builder = LibraryElementSuggestionBuilder(
- request, CompletionSuggestionKind.INVOCATION, typesOnly, instCreation);
+ var isConstructor = parent.parent is ConstructorName;
for (var importElem in imports) {
if (importElem.prefix?.name == elem.name) {
var library = importElem.importedLibrary;
if (library != null) {
- // Suggest elements from the imported library.
for (var element in importElem.namespace.definedNames.values) {
- element.accept(builder);
+ if (typesOnly && isConstructor) {
+ // Suggest constructors from the imported libraries.
+ if (element is ClassElement) {
+ for (var constructor in element.constructors) {
+ if (!constructor.isPrivate) {
+ builder.suggestConstructor(constructor,
+ kind: CompletionSuggestionKind.INVOCATION);
+ }
+ }
+ }
+ } else {
+ if (element is ClassElement ||
+ element is ExtensionElement ||
+ element is FunctionTypeAliasElement) {
+ builder.suggestElement(element,
+ kind: CompletionSuggestionKind.INVOCATION);
+ } else if (!typesOnly &&
+ (element is FunctionElement ||
+ element is PropertyAccessorElement)) {
+ builder.suggestElement(element,
+ kind: CompletionSuggestionKind.INVOCATION);
+ }
+ }
}
- // If the import is 'deferred' then suggest 'loadLibrary'.
- if (importElem.isDeferred) {
- var function = library.loadLibraryFunction;
- var useNewRelevance = request.useNewRelevance;
- var relevance = useNewRelevance
- ? Relevance.loadLibrary
- : DART_RELEVANCE_DEFAULT;
- builder.suggestions.add(createSuggestion(request, function,
- relevance: relevance, useNewRelevance: useNewRelevance));
+ // If the import is `deferred` then suggest `loadLibrary`.
+ if (!typesOnly && importElem.isDeferred) {
+ builder.suggestLoadLibraryFunction(library.loadLibraryFunction);
}
}
}
}
- return builder.suggestions;
+ return const <CompletionSuggestion>[];
}
}
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/library_prefix_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/library_prefix_contributor.dart
index c837cb4..c9e4d19 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/library_prefix_contributor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/library_prefix_contributor.dart
@@ -36,13 +36,15 @@
if (completion != null && completion.isNotEmpty) {
var libraryElement = element.importedLibrary;
if (libraryElement != null) {
- var relevance =
- useNewRelevance ? Relevance.prefix : DART_RELEVANCE_DEFAULT;
+ var relevance = useNewRelevance
+ ? Relevance.prefix
+ : (libraryElement.hasDeprecated
+ ? DART_RELEVANCE_LOW
+ : DART_RELEVANCE_DEFAULT);
var suggestion = createSuggestion(request, libraryElement,
completion: completion,
kind: CompletionSuggestionKind.IDENTIFIER,
- relevance: relevance,
- useNewRelevance: useNewRelevance);
+ relevance: relevance);
if (suggestion != null) {
suggestions.add(suggestion);
}
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/local_constructor_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/local_constructor_contributor.dart
index 81d91a5..007b8df 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/local_constructor_contributor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/local_constructor_contributor.dart
@@ -136,11 +136,12 @@
if (name != null && name.isNotEmpty) {
completion = '$completion.$name';
}
+ if (!useNewRelevance && element.hasDeprecated) {
+ relevance = DART_RELEVANCE_LOW;
+ }
var suggestion = createSuggestion(request, element,
- completion: completion,
- relevance: relevance,
- useNewRelevance: useNewRelevance);
+ completion: completion, relevance: relevance);
if (suggestion != null) {
suggestions.add(suggestion);
}
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/local_library_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/local_library_contributor.dart
index 2f2f80c..8f8e024 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/local_library_contributor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/local_library_contributor.dart
@@ -54,39 +54,39 @@
void visitClassElement(ClassElement element) {
if (optype.includeTypeNameSuggestions) {
// if includeTypeNameSuggestions, then use the filter
- var useNewRelevance = request.useNewRelevance;
int relevance;
- if (useNewRelevance) {
+ if (request.useNewRelevance) {
relevance = _relevanceForType(element.thisType);
+ } else if (element.hasDeprecated) {
+ relevance = DART_RELEVANCE_LOW;
} else {
relevance = optype.typeNameSuggestionsFilter(
_instantiateClassElement(element), DART_RELEVANCE_DEFAULT);
}
if (relevance != null) {
- addSuggestion(element,
- prefix: prefix,
- relevance: relevance,
- useNewRelevance: useNewRelevance);
+ addSuggestion(element, prefix: prefix, relevance: relevance);
}
}
if (optype.includeConstructorSuggestions) {
- var useNewRelevance = request.useNewRelevance;
int relevance;
- if (useNewRelevance) {
+ if (request.useNewRelevance) {
relevance = _relevanceForType(element.thisType);
+ } else if (element.hasDeprecated) {
+ relevance = DART_RELEVANCE_LOW;
} else {
relevance = optype.returnValueSuggestionsFilter(
_instantiateClassElement(element), DART_RELEVANCE_DEFAULT);
}
- _addConstructorSuggestions(element, relevance, useNewRelevance);
+ _addConstructorSuggestions(element, relevance);
}
if (optype.includeReturnValueSuggestions) {
if (element.isEnum) {
var enumName = element.displayName;
- var useNewRelevance = request.useNewRelevance;
int relevance;
- if (useNewRelevance) {
+ if (request.useNewRelevance) {
relevance = _relevanceForType(element.thisType);
+ } else if (element.hasDeprecated) {
+ relevance = DART_RELEVANCE_LOW;
} else {
relevance = optype.returnValueSuggestionsFilter(
_instantiateClassElement(element), DART_RELEVANCE_DEFAULT);
@@ -96,8 +96,7 @@
addSuggestion(field,
prefix: prefix,
relevance: relevance,
- elementCompletion: '$enumName.${field.name}',
- useNewRelevance: useNewRelevance);
+ elementCompletion: '$enumName.${field.name}');
}
}
}
@@ -117,17 +116,14 @@
@override
void visitExtensionElement(ExtensionElement element) {
if (optype.includeReturnValueSuggestions) {
- var useNewRelevance = request.useNewRelevance;
int relevance;
- if (useNewRelevance) {
+ if (request.useNewRelevance) {
relevance = _relevanceForType(element.extendedType);
} else {
- relevance = DART_RELEVANCE_DEFAULT;
+ relevance =
+ element.hasDeprecated ? DART_RELEVANCE_LOW : DART_RELEVANCE_DEFAULT;
}
- addSuggestion(element,
- prefix: prefix,
- relevance: relevance,
- useNewRelevance: useNewRelevance);
+ addSuggestion(element, prefix: prefix, relevance: relevance);
}
element.visitChildren(this);
}
@@ -142,28 +138,23 @@
return;
}
var returnType = element.returnType;
- var useNewRelevance = request.useNewRelevance;
int relevance;
- if (useNewRelevance) {
+ if (request.useNewRelevance) {
relevance = _relevanceForType(returnType);
} else {
- relevance = element.library == containingLibrary
- ? DART_RELEVANCE_LOCAL_FUNCTION
- : DART_RELEVANCE_DEFAULT;
+ relevance = element.hasDeprecated
+ ? DART_RELEVANCE_LOW
+ : (element.library == containingLibrary
+ ? DART_RELEVANCE_LOCAL_FUNCTION
+ : DART_RELEVANCE_DEFAULT);
}
if (returnType != null && returnType.isVoid) {
if (optype.includeVoidReturnSuggestions) {
- addSuggestion(element,
- prefix: prefix,
- relevance: relevance,
- useNewRelevance: useNewRelevance);
+ addSuggestion(element, prefix: prefix, relevance: relevance);
}
} else {
if (optype.includeReturnValueSuggestions) {
- addSuggestion(element,
- prefix: prefix,
- relevance: relevance,
- useNewRelevance: useNewRelevance);
+ addSuggestion(element, prefix: prefix, relevance: relevance);
}
}
}
@@ -171,21 +162,19 @@
@override
void visitFunctionTypeAliasElement(FunctionTypeAliasElement element) {
if (optype.includeTypeNameSuggestions) {
- var useNewRelevance = request.useNewRelevance;
int relevance;
- if (useNewRelevance) {
+ if (request.useNewRelevance) {
// TODO(brianwilkerson) Figure out whether there are any features that
// ought to be used here and what the right default value is.
relevance = 400;
} else {
- relevance = element.library == containingLibrary
- ? DART_RELEVANCE_LOCAL_FUNCTION
- : DART_RELEVANCE_DEFAULT;
+ relevance = element.hasDeprecated
+ ? DART_RELEVANCE_LOW
+ : (element.library == containingLibrary
+ ? DART_RELEVANCE_LOCAL_FUNCTION
+ : DART_RELEVANCE_DEFAULT);
}
- addSuggestion(element,
- prefix: prefix,
- relevance: relevance,
- useNewRelevance: useNewRelevance);
+ addSuggestion(element, prefix: prefix, relevance: relevance);
}
}
@@ -199,10 +188,11 @@
@override
void visitPropertyAccessorElement(PropertyAccessorElement element) {
if (optype.includeReturnValueSuggestions) {
- var useNewRelevance = request.useNewRelevance;
int relevance;
- if (useNewRelevance) {
+ if (request.useNewRelevance) {
relevance = _relevanceForType(element.returnType);
+ } else if (element.hasDeprecated) {
+ relevance = DART_RELEVANCE_LOW;
} else {
if (element.library == containingLibrary) {
if (element.enclosingElement is ClassElement) {
@@ -214,35 +204,29 @@
relevance = DART_RELEVANCE_DEFAULT;
}
}
- addSuggestion(element,
- prefix: prefix,
- relevance: relevance,
- useNewRelevance: useNewRelevance);
+ addSuggestion(element, prefix: prefix, relevance: relevance);
}
}
@override
void visitTopLevelVariableElement(TopLevelVariableElement element) {
if (optype.includeReturnValueSuggestions) {
- var useNewRelevance = request.useNewRelevance;
int relevance;
- if (useNewRelevance) {
+ if (request.useNewRelevance) {
relevance = _relevanceForType(element.type);
} else {
- relevance = element.library == containingLibrary
- ? DART_RELEVANCE_LOCAL_TOP_LEVEL_VARIABLE
- : DART_RELEVANCE_DEFAULT;
+ relevance = element.hasDeprecated
+ ? DART_RELEVANCE_LOW
+ : (element.library == containingLibrary
+ ? DART_RELEVANCE_LOCAL_TOP_LEVEL_VARIABLE
+ : DART_RELEVANCE_DEFAULT);
}
- addSuggestion(element,
- prefix: prefix,
- relevance: relevance,
- useNewRelevance: useNewRelevance);
+ addSuggestion(element, prefix: prefix, relevance: relevance);
}
}
/// Add constructor suggestions for the given class.
- void _addConstructorSuggestions(
- ClassElement classElem, int relevance, bool useNewRelevance) {
+ void _addConstructorSuggestions(ClassElement classElem, int relevance) {
var className = classElem.name;
for (var constructor in classElem.constructors) {
if (constructor.isPrivate) {
@@ -252,15 +236,14 @@
continue;
}
+ var completion = constructor.displayName;
+ completion = completion.isNotEmpty ? '$className.$completion' : className;
+ if (prefix != null && prefix.isNotEmpty) {
+ completion = '$prefix.$completion';
+ }
var suggestion = createSuggestion(request, constructor,
- relevance: relevance, useNewRelevance: useNewRelevance);
+ completion: completion, relevance: relevance);
if (suggestion != null) {
- var name = suggestion.completion;
- name = name.isNotEmpty ? '$className.$name' : className;
- if (prefix != null && prefix.isNotEmpty) {
- name = '$prefix.$name';
- }
- suggestion.completion = name;
suggestion.selectionOffset = suggestion.completion.length;
suggestions.add(suggestion);
}
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/named_constructor_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/named_constructor_contributor.dart
index 3472d5d..04b783e 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/named_constructor_contributor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/named_constructor_contributor.dart
@@ -32,8 +32,7 @@
if (type != null) {
var element = type.element;
if (element is ClassElement) {
- return _buildSuggestions(
- request, libraryElement, element, request.useNewRelevance);
+ return _buildSuggestions(request, libraryElement, element);
}
}
}
@@ -42,20 +41,20 @@
}
List<CompletionSuggestion> _buildSuggestions(DartCompletionRequest request,
- LibraryElement libElem, ClassElement classElem, bool useNewRelevance) {
+ LibraryElement libElem, ClassElement classElem) {
var isLocalClassDecl = classElem.library == libElem;
var suggestions = <CompletionSuggestion>[];
for (var constructor in classElem.constructors) {
if (isLocalClassDecl || !constructor.isPrivate) {
var name = constructor.name;
if (name != null) {
- var relevance = useNewRelevance
+ var relevance = request.useNewRelevance
? Relevance.namedConstructor
- : DART_RELEVANCE_DEFAULT;
+ : (constructor.hasDeprecated
+ ? DART_RELEVANCE_LOW
+ : DART_RELEVANCE_DEFAULT);
var suggestion = createSuggestion(request, constructor,
- completion: name,
- relevance: relevance,
- useNewRelevance: useNewRelevance);
+ completion: name, relevance: relevance);
if (suggestion != null) {
suggestions.add(suggestion);
}
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/override_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/override_contributor.dart
index 28c0d6f..b6760de 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/override_contributor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/override_contributor.dart
@@ -10,11 +10,13 @@
hide CompletionSuggestion, CompletionSuggestionKind;
import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
import 'package:analysis_server/src/services/completion/dart/suggestion_builder.dart';
+import 'package:analysis_server/src/utilities/extensions/ast.dart';
import 'package:analyzer/dart/analysis/features.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/nullability_suffix.dart';
import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer/source/source_range.dart';
import 'package:analyzer/src/dart/element/inheritance_manager3.dart';
import 'package:analyzer_plugin/src/utilities/completion/completion_target.dart';
import 'package:analyzer_plugin/utilities/change_builder/change_builder_dart.dart';
@@ -26,14 +28,24 @@
@override
Future<List<CompletionSuggestion>> computeSuggestions(
DartCompletionRequest request, SuggestionBuilder builder) async {
- var targetId = _getTargetId(request.target);
- if (targetId == null) {
- return const <CompletionSuggestion>[];
- }
- var classDecl = targetId.thisOrAncestorOfType<ClassOrMixinDeclaration>();
+ var target = request.target;
+ var containingNode = target.containingNode;
+ var classDecl =
+ containingNode.thisOrAncestorOfType<ClassOrMixinDeclaration>();
if (classDecl == null) {
return const <CompletionSuggestion>[];
}
+ if (containingNode.inClassMemberBody) {
+ return const <CompletionSuggestion>[];
+ }
+
+ var comment = containingNode.thisOrAncestorOfType<Comment>();
+ if (target.isCommentText || comment != null) {
+ return const <CompletionSuggestion>[];
+ }
+
+ var sourceRange = _getTargetSourceRange(target);
+ sourceRange ??= range.startOffsetEndOffset(request.offset, 0);
var inheritance = InheritanceManager3();
@@ -53,7 +65,7 @@
if (element.returnType != null) {
var invokeSuper = interface.isSuperImplemented(name);
var suggestion =
- await _buildSuggestion(request, targetId, element, invokeSuper);
+ await _buildSuggestion(request, sourceRange, element, invokeSuper);
if (suggestion != null) {
suggestions.add(suggestion);
}
@@ -62,17 +74,17 @@
return suggestions;
}
- /// Build a suggestion to replace [targetId] in the given [request] with an
+ /// Build a suggestion to replace [sourceRange] in the given [request] with an
/// override of the given [element].
Future<CompletionSuggestion> _buildSuggestion(
DartCompletionRequest request,
- SimpleIdentifier targetId,
+ SourceRange sourceRange,
ExecutableElement element,
bool invokeSuper) async {
var displayTextBuffer = StringBuffer();
var builder = DartChangeBuilder(request.result.session);
await builder.addFileEdit(request.result.path, (builder) {
- builder.addReplacement(range.node(targetId), (builder) {
+ builder.addReplacement(sourceRange, (builder) {
builder.writeOverride(
element,
displayTextBuffer: displayTextBuffer,
@@ -102,7 +114,7 @@
if (selectionRange == null) {
return null;
}
- var offsetDelta = targetId.offset + replacement.indexOf(completion);
+ var offsetDelta = sourceRange.offset + replacement.indexOf(completion);
var displayText =
displayTextBuffer.isNotEmpty ? displayTextBuffer.toString() : null;
var suggestion = CompletionSuggestion(
@@ -118,24 +130,6 @@
return suggestion;
}
- /// If the target looks like a partial identifier inside a class declaration
- /// then return that identifier, otherwise return `null`.
- SimpleIdentifier _getTargetId(CompletionTarget target) {
- var node = target.containingNode;
- if (node is ClassOrMixinDeclaration) {
- var entity = target.entity;
- if (entity is FieldDeclaration) {
- return _getTargetIdFromVarList(entity.fields);
- }
- } else if (node is FieldDeclaration) {
- var entity = target.entity;
- if (entity is VariableDeclarationList) {
- return _getTargetIdFromVarList(entity);
- }
- }
- return null;
- }
-
SimpleIdentifier _getTargetIdFromVarList(VariableDeclarationList fields) {
var variables = fields.variables;
if (variables.length == 1) {
@@ -157,6 +151,29 @@
return null;
}
+ /// If the target looks like a partial identifier inside a class declaration
+ /// then return that identifier [SourceRange], otherwise return `null`.
+ SourceRange _getTargetSourceRange(CompletionTarget target) {
+ var containingNode = target.containingNode;
+ if (containingNode is ClassOrMixinDeclaration) {
+ if (target.entity is FieldDeclaration) {
+ var fieldDecl = target.entity as FieldDeclaration;
+ var simpleIdentifier = _getTargetIdFromVarList(fieldDecl.fields);
+ if (simpleIdentifier != null) {
+ return range.node(simpleIdentifier);
+ }
+ }
+ } else if (containingNode is FieldDeclaration) {
+ if (target.entity is VariableDeclarationList) {
+ var simpleIdentifier = _getTargetIdFromVarList(target.entity);
+ if (simpleIdentifier != null) {
+ return range.node(simpleIdentifier);
+ }
+ }
+ }
+ return null;
+ }
+
/// Return `true` if the given [node] has an `override` annotation.
bool _hasOverride(AstNode node) {
if (node is AnnotatedNode) {
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/static_member_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/static_member_contributor.dart
index 9f9f584..b970dab 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/static_member_contributor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/static_member_contributor.dart
@@ -107,9 +107,8 @@
if (completion == null || completion.isEmpty) {
return;
}
- var relevance = DART_RELEVANCE_DEFAULT;
- var useNewRelevance = request.useNewRelevance;
- if (useNewRelevance) {
+ var relevance;
+ if (request.useNewRelevance) {
var contextType = request.featureComputer
.contextTypeFeature(request.contextType, elementType);
var elementKind = request.featureComputer
@@ -119,11 +118,12 @@
contextType: contextType,
elementKind: elementKind,
hasDeprecated: hasDeprecated);
+ } else {
+ relevance =
+ element.hasDeprecated ? DART_RELEVANCE_LOW : DART_RELEVANCE_DEFAULT;
}
var suggestion = createSuggestion(request, element,
- completion: completion,
- relevance: relevance,
- useNewRelevance: useNewRelevance);
+ completion: completion, relevance: relevance);
if (suggestion != null) {
suggestions.add(suggestion);
}
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/suggestion_builder.dart b/pkg/analysis_server/lib/src/services/completion/dart/suggestion_builder.dart
index bdf356d..43ae5ba 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/suggestion_builder.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/suggestion_builder.dart
@@ -13,19 +13,20 @@
import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
import 'package:analysis_server/src/services/completion/dart/feature_computer.dart';
import 'package:analysis_server/src/services/completion/dart/utilities.dart';
+import 'package:analyzer/dart/analysis/features.dart';
import 'package:analyzer/dart/element/element.dart';
-import 'package:analyzer/dart/element/visitor.dart';
+import 'package:analyzer/dart/element/nullability_suffix.dart';
+import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/src/util/comment.dart';
import 'package:meta/meta.dart';
-/// Return a suggestion based upon the given element or `null` if a suggestion
+/// Return a suggestion based on the given [element], or `null` if a suggestion
/// is not appropriate for the given element.
CompletionSuggestion createSuggestion(
DartCompletionRequest request, Element element,
{String completion,
CompletionSuggestionKind kind,
- int relevance = DART_RELEVANCE_DEFAULT,
- bool useNewRelevance = false}) {
+ int relevance = DART_RELEVANCE_DEFAULT}) {
if (element == null) {
return null;
}
@@ -34,13 +35,12 @@
return null;
}
completion ??= element.displayName;
- kind ??= CompletionSuggestionKind.INVOCATION;
- var isDeprecated = element.hasDeprecated;
- if (!useNewRelevance && isDeprecated) {
- relevance = DART_RELEVANCE_LOW;
+ if (completion == null || completion.isEmpty) {
+ return null;
}
- var suggestion = CompletionSuggestion(
- kind, relevance, completion, completion.length, 0, isDeprecated, false);
+ kind ??= CompletionSuggestionKind.INVOCATION;
+ var suggestion = CompletionSuggestion(kind, relevance, completion,
+ completion.length, 0, element.hasDeprecated, false);
// Attach docs.
var doc = DartUnitHoverComputer.computeDocumentation(
@@ -108,7 +108,6 @@
CompletionSuggestion addSuggestion(Element element,
{String prefix,
int relevance = DART_RELEVANCE_DEFAULT,
- bool useNewRelevance = false,
String elementCompletion}) {
if (element.isPrivate) {
if (element.library != containingLibrary) {
@@ -127,10 +126,7 @@
return null;
}
var suggestion = createSuggestion(request, element,
- completion: completion,
- kind: kind,
- relevance: relevance,
- useNewRelevance: useNewRelevance);
+ completion: completion, kind: kind, relevance: relevance);
if (suggestion != null) {
if (element.isSynthetic && element is PropertyAccessorElement) {
String cacheKey;
@@ -173,121 +169,6 @@
}
}
-/// This class creates suggestions based on top-level elements.
-class LibraryElementSuggestionBuilder extends SimpleElementVisitor<void>
- with ElementSuggestionBuilder {
- @override
- final DartCompletionRequest request;
-
- @override
- final CompletionSuggestionKind kind;
-
- final bool typesOnly;
-
- final bool instCreation;
-
- /// Return `true` if the new relevance scores should be produced.
- final bool useNewRelevance;
-
- LibraryElementSuggestionBuilder(
- this.request, this.kind, this.typesOnly, this.instCreation)
- : useNewRelevance = request.useNewRelevance;
-
- @override
- LibraryElement get containingLibrary => request.libraryElement;
-
- @override
- void visitClassElement(ClassElement element) {
- if (instCreation) {
- element.visitChildren(this);
- } else {
- // TODO(brianwilkerson) Determine whether this should be based on features
- // (such as the kind of the element) or a constant.
- var relevance = useNewRelevance ? 750 : DART_RELEVANCE_DEFAULT;
- addSuggestion(element,
- relevance: relevance, useNewRelevance: useNewRelevance);
- }
- }
-
- @override
- void visitConstructorElement(ConstructorElement element) {
- if (instCreation) {
- var classElem = element.enclosingElement;
- if (classElem != null) {
- var prefix = classElem.name;
- if (prefix != null && prefix.isNotEmpty) {
- // TODO(brianwilkerson) Determine whether this should be based on features
- // (such as the kind of the element) or a constant.
- var relevance = useNewRelevance ? 750 : DART_RELEVANCE_DEFAULT;
- addSuggestion(element,
- prefix: prefix,
- relevance: relevance,
- useNewRelevance: useNewRelevance);
- }
- }
- }
- }
-
- @override
- void visitExtensionElement(ExtensionElement element) {
- if (!instCreation) {
- // TODO(brianwilkerson) Determine whether this should be based on features
- // (such as the kind of the element) or a constant.
- var relevance = useNewRelevance ? 750 : DART_RELEVANCE_DEFAULT;
- addSuggestion(element,
- relevance: relevance, useNewRelevance: useNewRelevance);
- }
- }
-
- @override
- void visitFunctionElement(FunctionElement element) {
- if (!typesOnly) {
- int relevance;
- if (useNewRelevance) {
- // TODO(brianwilkerson) Determine whether this should be based on
- // features (such as the kind of the element) or a constant.
- relevance = element.library == containingLibrary ? 800 : 750;
- } else {
- relevance = element.library == containingLibrary
- ? DART_RELEVANCE_LOCAL_FUNCTION
- : DART_RELEVANCE_DEFAULT;
- }
- addSuggestion(element,
- relevance: relevance, useNewRelevance: useNewRelevance);
- }
- }
-
- @override
- void visitFunctionTypeAliasElement(FunctionTypeAliasElement element) {
- if (!instCreation) {
- // TODO(brianwilkerson) Determine whether this should be based on features
- // (such as the kind of the element) or a constant.
- var relevance = useNewRelevance ? 750 : DART_RELEVANCE_DEFAULT;
- addSuggestion(element,
- relevance: relevance, useNewRelevance: useNewRelevance);
- }
- }
-
- @override
- void visitPropertyAccessorElement(PropertyAccessorElement element) {
- if (!typesOnly) {
- var variable = element.variable;
- int relevance;
- if (useNewRelevance) {
- // TODO(brianwilkerson) Determine whether this should be based on
- // features (such as the kind of the element) or a constant.
- relevance = variable.library == containingLibrary ? 800 : 750;
- } else {
- relevance = variable.library == containingLibrary
- ? DART_RELEVANCE_LOCAL_TOP_LEVEL_VARIABLE
- : DART_RELEVANCE_DEFAULT;
- }
- addSuggestion(variable,
- relevance: relevance, useNewRelevance: useNewRelevance);
- }
- }
-}
-
/// This class provides suggestions based upon the visible instance members in
/// an interface type.
class MemberSuggestionBuilder {
@@ -310,6 +191,9 @@
/// The request for which suggestions are being built.
final DartCompletionRequest request;
+ /// The builder used to build the suggestions.
+ final SuggestionBuilder builder;
+
/// Map indicating, for each possible completion identifier, whether we have
/// already generated completions for a getter, setter, or both. The "both"
/// case also handles the case where have generated a completion for a method
@@ -323,7 +207,7 @@
final Map<String, CompletionSuggestion> _suggestionMap =
<String, CompletionSuggestion>{};
- MemberSuggestionBuilder(this.request);
+ MemberSuggestionBuilder(this.request, this.builder);
Iterable<CompletionSuggestion> get suggestions => _suggestionMap.values;
@@ -361,8 +245,7 @@
if (accessor.isGetter) {
var variable = accessor.variable;
int relevance;
- var useNewRelevance = request.useNewRelevance;
- if (useNewRelevance) {
+ if (request.useNewRelevance) {
var featureComputer = request.featureComputer;
var contextType = featureComputer.contextTypeFeature(
request.contextType, variable.type);
@@ -380,14 +263,13 @@
} else {
relevance = oldRelevance();
}
- return _addSuggestion(variable, relevance, useNewRelevance);
+ return _addSuggestion(variable, relevance);
}
} else {
var type =
accessor.isGetter ? accessor.returnType : accessor.parameters[0].type;
int relevance;
- var useNewRelevance = request.useNewRelevance;
- if (useNewRelevance) {
+ if (request.useNewRelevance) {
var featureComputer = request.featureComputer;
var contextType =
featureComputer.contextTypeFeature(request.contextType, type);
@@ -405,7 +287,7 @@
} else {
relevance = oldRelevance();
}
- return _addSuggestion(accessor, relevance, useNewRelevance);
+ return _addSuggestion(accessor, relevance);
}
return null;
}
@@ -438,8 +320,7 @@
return null;
}
int relevance;
- var useNewRelevance = request.useNewRelevance;
- if (useNewRelevance) {
+ if (request.useNewRelevance) {
var featureComputer = request.featureComputer;
var contextType = featureComputer.contextTypeFeature(
request.contextType, method.returnType);
@@ -457,13 +338,12 @@
} else {
relevance = oldRelevance();
}
- return _addSuggestion(method, relevance, useNewRelevance, kind: kind);
+ return _addSuggestion(method, relevance, kind: kind);
}
/// Add a suggestion for the given [element] with the given [relevance],
/// provided that it is not shadowed by a previously added suggestion.
- CompletionSuggestion _addSuggestion(
- Element element, int relevance, bool useNewRelevance,
+ CompletionSuggestion _addSuggestion(Element element, int relevance,
{CompletionSuggestionKind kind}) {
var identifier = element.displayName;
@@ -503,8 +383,8 @@
assert(false);
return null;
}
- var suggestion = createSuggestion(request, element,
- kind: kind, relevance: relevance, useNewRelevance: useNewRelevance);
+ var suggestion =
+ createSuggestion(request, element, kind: kind, relevance: relevance);
if (suggestion != null) {
addCompletionSuggestion(suggestion);
}
@@ -553,7 +433,264 @@
/// A collection of completion suggestions.
final List<CompletionSuggestion> suggestions = <CompletionSuggestion>[];
+ /// A flag indicating whether the [_cachedContextType] has been computed.
+ bool _hasContextType = false;
+
+ /// The context type associated with the completion location, or `null` if
+ /// either the location does not have a context type, or if the context type
+ /// has not yet been computed. In the latter case, [_hasContextType] will be
+ /// `false`.
+ DartType _cachedContextType;
+
/// Initialize a newly created suggestion builder to build suggestions for the
/// given [request].
SuggestionBuilder(this.request);
+
+ DartType get _contextType {
+ if (!_hasContextType) {
+ _hasContextType = true;
+ _cachedContextType = request.featureComputer
+ .computeContextType(request.target.containingNode);
+ }
+ return _cachedContextType;
+ }
+
+ /// Add a suggestion for the [classElement].
+ void suggestClass(ClassElement classElement,
+ {CompletionSuggestionKind kind = CompletionSuggestionKind.INVOCATION}) {
+ int relevance;
+ if (request.useNewRelevance) {
+ relevance = _computeTopLevelRelevance(classElement,
+ elementType: _instantiateClassElement(classElement));
+ } else if (classElement.hasDeprecated) {
+ relevance = DART_RELEVANCE_LOW;
+ } else {
+ relevance = request.opType.typeNameSuggestionsFilter(
+ _instantiateClassElement(classElement), DART_RELEVANCE_DEFAULT);
+ }
+
+ suggestions.add(createSuggestion(request, classElement,
+ kind: kind, relevance: relevance));
+ }
+
+ /// Add a suggestion for the [constructor]. If a [kind] is provided
+ /// it will be used as the kind for the suggestion.
+ void suggestConstructor(ConstructorElement constructor,
+ {CompletionSuggestionKind kind = CompletionSuggestionKind.INVOCATION}) {
+ var classElement = constructor.enclosingElement;
+ if (classElement == null) {
+ return;
+ }
+ var prefix = classElement.name;
+ // TODO(brianwilkerson) It shouldn't be necessary to test for an empty
+ // prefix.
+ if (prefix == null || prefix.isEmpty) {
+ return;
+ }
+
+ var completion = constructor.displayName;
+ if (prefix != null && prefix.isNotEmpty) {
+ if (completion == null || completion.isEmpty) {
+ completion = prefix;
+ } else {
+ completion = '$prefix.$completion';
+ }
+ }
+ if (completion == null || completion.isEmpty) {
+ return null;
+ }
+
+ int relevance;
+ if (request.useNewRelevance) {
+ relevance = _computeTopLevelRelevance(constructor);
+ } else {
+ relevance = constructor.hasDeprecated
+ ? DART_RELEVANCE_LOW
+ : DART_RELEVANCE_DEFAULT;
+ }
+
+ suggestions.add(createSuggestion(request, constructor,
+ completion: completion, kind: kind, relevance: relevance));
+ }
+
+ /// Add a suggestion for the [element].
+ void suggestElement(Element element,
+ {CompletionSuggestionKind kind = CompletionSuggestionKind.INVOCATION}) {
+ if (element is ClassElement) {
+ suggestClass(element, kind: kind);
+ } else if (element is ConstructorElement) {
+ suggestConstructor(element, kind: kind);
+ } else if (element is ExtensionElement) {
+ suggestExtension(element, kind: kind);
+ } else if (element is FunctionElement &&
+ element.enclosingElement is CompilationUnitElement) {
+ suggestTopLevelFunction(element, kind: kind);
+ } else if (element is FunctionTypeAliasElement) {
+ suggestFunctionTypeAlias(element, kind: kind);
+ } else if (element is PropertyAccessorElement &&
+ element.enclosingElement is CompilationUnitElement) {
+ suggestTopLevelPropertyAccessor(element, kind: kind);
+ } else {
+ throw ArgumentError('Cannot suggest a ${element.runtimeType}');
+ }
+ }
+
+ /// Add a suggestion for the [extension].
+ void suggestExtension(ExtensionElement extension,
+ {CompletionSuggestionKind kind = CompletionSuggestionKind.INVOCATION}) {
+ int relevance;
+ if (request.useNewRelevance) {
+ relevance = _computeTopLevelRelevance(extension,
+ elementType: extension.extendedType);
+ } else {
+ relevance =
+ extension.hasDeprecated ? DART_RELEVANCE_LOW : DART_RELEVANCE_DEFAULT;
+ }
+
+ suggestions.add(
+ createSuggestion(request, extension, kind: kind, relevance: relevance));
+ }
+
+ /// Add a suggestion for the `call` method defined on functions.
+ void suggestFunctionCall() {
+ const callString = 'call()';
+ final element = protocol.Element(
+ protocol.ElementKind.METHOD, callString, protocol.Element.makeFlags(),
+ location: null,
+ typeParameters: null,
+ parameters: null,
+ returnType: 'void');
+ suggestions.add(CompletionSuggestion(
+ CompletionSuggestionKind.INVOCATION,
+ request.useNewRelevance ? Relevance.callFunction : DART_RELEVANCE_HIGH,
+ callString,
+ callString.length,
+ 0,
+ false,
+ false,
+ displayText: callString,
+ element: element,
+ returnType: 'void',
+ ));
+ }
+
+ /// Add a suggestion for the [functionTypeAlias].
+ void suggestFunctionTypeAlias(FunctionTypeAliasElement functionTypeAlias,
+ {CompletionSuggestionKind kind = CompletionSuggestionKind.INVOCATION}) {
+ int relevance;
+ if (request.useNewRelevance) {
+ relevance =
+ _computeTopLevelRelevance(functionTypeAlias, defaultRelevance: 750);
+ } else {
+ relevance = functionTypeAlias.hasDeprecated
+ ? DART_RELEVANCE_LOW
+ : (functionTypeAlias.library == request.libraryElement
+ ? DART_RELEVANCE_LOCAL_FUNCTION
+ : DART_RELEVANCE_DEFAULT);
+ }
+ suggestions.add(createSuggestion(request, functionTypeAlias,
+ kind: kind, relevance: relevance));
+ }
+
+ /// Add a suggestion for the `loadLibrary` [function] associated with a
+ /// prefix.
+ void suggestLoadLibraryFunction(FunctionElement function) {
+ int relevance;
+ if (request.useNewRelevance) {
+ // TODO(brianwilkerson) This might want to use the context type rather
+ // than a fixed value.
+ relevance = Relevance.loadLibrary;
+ } else {
+ relevance =
+ function.hasDeprecated ? DART_RELEVANCE_LOW : DART_RELEVANCE_DEFAULT;
+ }
+
+ suggestions.add(createSuggestion(request, function, relevance: relevance));
+ }
+
+ /// Add a suggestion for the top-level [function].
+ void suggestTopLevelFunction(FunctionElement function,
+ {CompletionSuggestionKind kind = CompletionSuggestionKind.INVOCATION}) {
+ int relevance;
+ if (request.useNewRelevance) {
+ relevance =
+ _computeTopLevelRelevance(function, elementType: function.returnType);
+ } else {
+ relevance = function.hasDeprecated
+ ? DART_RELEVANCE_LOW
+ : (function.library == request.libraryElement
+ ? DART_RELEVANCE_LOCAL_FUNCTION
+ : DART_RELEVANCE_DEFAULT);
+ }
+
+ suggestions.add(
+ createSuggestion(request, function, kind: kind, relevance: relevance));
+ }
+
+ /// Add a suggestion for the top-level property [accessor].
+ void suggestTopLevelPropertyAccessor(PropertyAccessorElement accessor,
+ {CompletionSuggestionKind kind = CompletionSuggestionKind.INVOCATION}) {
+ if (accessor.isSetter && accessor.isSynthetic) {
+ // TODO(brianwilkerson) Only discard the setter if a suggestion is built
+ // for the corresponding getter. Currently that's always the case.
+ // Handling this more generally will require the ability to build
+ // suggestions for setters and then remove them later when the
+ // corresponding getter is found.
+ return;
+ }
+ // TODO(brianwilkerson) Should we use the variable only when the [element]
+ // is synthetic?
+ var variable = accessor.variable;
+ int relevance;
+ if (request.useNewRelevance) {
+ relevance =
+ _computeTopLevelRelevance(variable, elementType: variable.type);
+ } else {
+ relevance = accessor.hasDeprecated
+ ? DART_RELEVANCE_LOW
+ : (variable.library == request.libraryElement
+ ? DART_RELEVANCE_LOCAL_TOP_LEVEL_VARIABLE
+ : DART_RELEVANCE_DEFAULT);
+ }
+
+ suggestions.add(
+ createSuggestion(request, variable, kind: kind, relevance: relevance));
+ }
+
+ /// Return the relevance score for a top-level [element].
+ int _computeTopLevelRelevance(Element element,
+ {int defaultRelevance = 800, DartType elementType}) {
+ // TODO(brianwilkerson) The old relevance computation used a signal based
+ // on whether the element being suggested was from the same library in
+ // which completion is being performed. Explore whether that's a useful
+ // signal.
+ var featureComputer = request.featureComputer;
+ var contextTypeFeature =
+ featureComputer.contextTypeFeature(_contextType, elementType);
+ var elementKind = featureComputer.elementKindFeature(
+ element, request.opType.completionLocation);
+ var hasDeprecated = featureComputer.hasDeprecatedFeature(element);
+ return toRelevance(
+ weightedAverage(
+ [contextTypeFeature, elementKind, hasDeprecated], [0.8, 0.8, 0.2]),
+ defaultRelevance);
+ }
+
+ InterfaceType _instantiateClassElement(ClassElement element) {
+ var typeParameters = element.typeParameters;
+ var typeArguments = const <DartType>[];
+ if (typeParameters.isNotEmpty) {
+ var neverType = request.libraryElement.typeProvider.neverType;
+ typeArguments = List.filled(typeParameters.length, neverType);
+ }
+
+ var nullabilitySuffix = request.featureSet.isEnabled(Feature.non_nullable)
+ ? NullabilitySuffix.none
+ : NullabilitySuffix.star;
+
+ return element.instantiate(
+ typeArguments: typeArguments,
+ nullabilitySuffix: nullabilitySuffix,
+ );
+ }
}
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/type_member_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/type_member_contributor.dart
index 6852927..491bfac 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/type_member_contributor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/type_member_contributor.dart
@@ -6,13 +6,12 @@
import 'dart:collection';
import 'package:analysis_server/src/protocol_server.dart'
- show CompletionSuggestion, CompletionSuggestionKind;
+ show CompletionSuggestion;
import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
import 'package:analysis_server/src/services/completion/dart/suggestion_builder.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/type.dart';
-import 'package:analyzer_plugin/protocol/protocol_common.dart' as protocol;
import 'package:analyzer_plugin/src/utilities/visitors/local_declaration_visitor.dart';
/// A contributor that produces suggestions based on the instance members of a
@@ -101,14 +100,12 @@
// Build the suggestions.
if (type is InterfaceType) {
- var builder = _SuggestionBuilder(request);
- builder.buildSuggestions(type, containingMethodName,
+ var memberBuilder = _SuggestionBuilder(request, builder);
+ memberBuilder.buildSuggestions(type, containingMethodName,
mixins: mixins, superclassConstraints: superclassConstraints);
- return builder.suggestions.toList();
- }
- if (type is FunctionType) {
- var builder = _SuggestionBuilder(request);
- return [builder._createFunctionCallSuggestion()];
+ return memberBuilder.suggestions.toList();
+ } else if (type is FunctionType) {
+ builder.suggestFunctionCall();
}
return const <CompletionSuggestion>[];
@@ -238,7 +235,8 @@
/// an interface type.
class _SuggestionBuilder extends MemberSuggestionBuilder {
/// Initialize a newly created suggestion builder.
- _SuggestionBuilder(DartCompletionRequest request) : super(request);
+ _SuggestionBuilder(DartCompletionRequest request, SuggestionBuilder builder)
+ : super(request, builder);
/// Return completion suggestions for 'dot' completions on the given [type].
/// If the 'dot' completion is a super expression, then [containingMethodName]
@@ -280,33 +278,11 @@
}
}
if (targetType.isDartCoreFunction) {
- addCompletionSuggestion(_createFunctionCallSuggestion());
+ builder.suggestFunctionCall();
}
}
}
- CompletionSuggestion _createFunctionCallSuggestion() {
- const callString = 'call()';
- final element = protocol.Element(
- protocol.ElementKind.METHOD, callString, protocol.Element.makeFlags(),
- location: null,
- typeParameters: null,
- parameters: null,
- returnType: 'void');
- return CompletionSuggestion(
- CompletionSuggestionKind.INVOCATION,
- request.useNewRelevance ? Relevance.callFunction : DART_RELEVANCE_HIGH,
- callString,
- callString.length,
- 0,
- false,
- false,
- displayText: callString,
- element: element,
- returnType: 'void',
- );
- }
-
/// Get a list of [InterfaceType]s that should be searched to find the
/// possible completions for an object having type [type].
List<InterfaceType> _getTypeOrdering(InterfaceType type) {
diff --git a/pkg/analysis_server/lib/src/services/completion/postfix/postfix_completion.dart b/pkg/analysis_server/lib/src/services/completion/postfix/postfix_completion.dart
index 95ddfce..4d2409c 100644
--- a/pkg/analysis_server/lib/src/services/completion/postfix/postfix_completion.dart
+++ b/pkg/analysis_server/lib/src/services/completion/postfix/postfix_completion.dart
@@ -67,8 +67,6 @@
static Future<PostfixCompletion> expandAssert(
PostfixCompletionProcessor processor, PostfixCompletionKind kind) async {
- // TODO(brianwilkerson) Determine whether this await is necessary.
- await null;
return processor.expand(kind, processor.findAssertExpression, (expr) {
return 'assert(${processor.utils.getNodeText(expr)});';
}, withBraces: false);
@@ -76,16 +74,12 @@
static Future<PostfixCompletion> expandElse(
PostfixCompletionProcessor processor, PostfixCompletionKind kind) async {
- // TODO(brianwilkerson) Determine whether this await is necessary.
- await null;
return processor.expand(kind, processor.findBoolExpression,
(expr) => 'if (${processor.makeNegatedBoolExpr(expr)})');
}
static Future<PostfixCompletion> expandFor(
PostfixCompletionProcessor processor, PostfixCompletionKind kind) async {
- // TODO(brianwilkerson) Determine whether this await is necessary.
- await null;
return processor.expand(kind, processor.findIterableExpression, (expr) {
var value = processor.newVariable('value');
return 'for (var $value in ${processor.utils.getNodeText(expr)})';
@@ -94,8 +88,6 @@
static Future<PostfixCompletion> expandFori(
PostfixCompletionProcessor processor, PostfixCompletionKind kind) async {
- // TODO(brianwilkerson) Determine whether this await is necessary.
- await null;
return processor.expand(kind, processor.findIntExpression, (expr) {
var index = processor.newVariable('i');
return 'for (int $index = 0; $index < ${processor.utils.getNodeText(expr)}; $index++)';
@@ -104,16 +96,12 @@
static Future<PostfixCompletion> expandIf(
PostfixCompletionProcessor processor, PostfixCompletionKind kind) async {
- // TODO(brianwilkerson) Determine whether this await is necessary.
- await null;
return processor.expand(kind, processor.findBoolExpression,
(expr) => 'if (${processor.utils.getNodeText(expr)})');
}
static Future<PostfixCompletion> expandNegate(
PostfixCompletionProcessor processor, PostfixCompletionKind kind) async {
- // TODO(brianwilkerson) Determine whether this await is necessary.
- await null;
return processor.expand(kind, processor.findBoolExpression,
(expr) => processor.makeNegatedBoolExpr(expr),
withBraces: false);
@@ -121,8 +109,6 @@
static Future<PostfixCompletion> expandNotNull(
PostfixCompletionProcessor processor, PostfixCompletionKind kind) async {
- // TODO(brianwilkerson) Determine whether this await is necessary.
- await null;
return processor.expand(kind, processor.findObjectExpression, (expr) {
return expr is NullLiteral
? 'if (false)'
@@ -132,8 +118,6 @@
static Future<PostfixCompletion> expandNull(
PostfixCompletionProcessor processor, PostfixCompletionKind kind) async {
- // TODO(brianwilkerson) Determine whether this await is necessary.
- await null;
return processor.expand(kind, processor.findObjectExpression, (expr) {
return expr is NullLiteral
? 'if (true)'
@@ -143,8 +127,6 @@
static Future<PostfixCompletion> expandParen(
PostfixCompletionProcessor processor, PostfixCompletionKind kind) async {
- // TODO(brianwilkerson) Determine whether this await is necessary.
- await null;
return processor.expand(kind, processor.findObjectExpression,
(expr) => '(${processor.utils.getNodeText(expr)})',
withBraces: false);
@@ -152,8 +134,6 @@
static Future<PostfixCompletion> expandReturn(
PostfixCompletionProcessor processor, PostfixCompletionKind kind) async {
- // TODO(brianwilkerson) Determine whether this await is necessary.
- await null;
return processor.expand(kind, processor.findObjectExpression,
(expr) => 'return ${processor.utils.getNodeText(expr)};',
withBraces: false);
@@ -161,30 +141,22 @@
static Future<PostfixCompletion> expandSwitch(
PostfixCompletionProcessor processor, PostfixCompletionKind kind) async {
- // TODO(brianwilkerson) Determine whether this await is necessary.
- await null;
return processor.expand(kind, processor.findObjectExpression,
(expr) => 'switch (${processor.utils.getNodeText(expr)})');
}
static Future<PostfixCompletion> expandTry(
PostfixCompletionProcessor processor, PostfixCompletionKind kind) async {
- // TODO(brianwilkerson) Determine whether this await is necessary.
- await null;
return processor.expandTry(kind, processor.findStatement, withOn: false);
}
static Future<PostfixCompletion> expandTryon(
PostfixCompletionProcessor processor, PostfixCompletionKind kind) async {
- // TODO(brianwilkerson) Determine whether this await is necessary.
- await null;
return processor.expandTry(kind, processor.findStatement, withOn: true);
}
static Future<PostfixCompletion> expandWhile(
PostfixCompletionProcessor processor, PostfixCompletionKind kind) async {
- // TODO(brianwilkerson) Determine whether this await is necessary.
- await null;
return processor.expand(kind, processor.findBoolExpression,
(expr) => 'while (${processor.utils.getNodeText(expr)})');
}
@@ -300,8 +272,6 @@
TypeSystem get typeSystem => completionContext.resolveResult.typeSystem;
Future<PostfixCompletion> compute() async {
- // TODO(brianwilkerson) Determine whether this await is necessary.
- await null;
node = _selectedNode();
if (node == null) {
return NO_COMPLETION;
@@ -313,8 +283,6 @@
Future<PostfixCompletion> expand(
PostfixCompletionKind kind, Function contexter, Function sourcer,
{bool withBraces = true}) async {
- // TODO(brianwilkerson) Determine whether this await is necessary.
- await null;
AstNode expr = contexter();
if (expr == null) {
return null;
@@ -350,8 +318,6 @@
Future<PostfixCompletion> expandTry(
PostfixCompletionKind kind, Function contexter,
{bool withOn = false}) async {
- // TODO(brianwilkerson) Determine whether this await is necessary.
- await null;
AstNode stmt = contexter();
if (stmt == null) {
return null;
@@ -455,8 +421,6 @@
}
Future<bool> isApplicable() async {
- // TODO(brianwilkerson) Determine whether this await is necessary.
- await null;
node = _selectedNode();
if (node == null) {
return false;
diff --git a/pkg/analysis_server/lib/src/services/completion/statement/statement_completion.dart b/pkg/analysis_server/lib/src/services/completion/statement/statement_completion.dart
index 9b025cd..6b19e69 100644
--- a/pkg/analysis_server/lib/src/services/completion/statement/statement_completion.dart
+++ b/pkg/analysis_server/lib/src/services/completion/statement/statement_completion.dart
@@ -132,8 +132,6 @@
statementContext.resolveResult.unit.declaredElement;
Future<StatementCompletion> compute() async {
- // TODO(brianwilkerson) Determine whether this await is necessary.
- await null;
node = _selectedNode();
if (node == null) {
return NO_COMPLETION;
diff --git a/pkg/analysis_server/lib/src/services/correction/assist.dart b/pkg/analysis_server/lib/src/services/correction/assist.dart
index 50e59d7..88f78e0 100644
--- a/pkg/analysis_server/lib/src/services/correction/assist.dart
+++ b/pkg/analysis_server/lib/src/services/correction/assist.dart
@@ -107,6 +107,10 @@
'dart.assist.convert.relativeToPackageImport',
30,
"Convert to 'package:' import");
+ static const CONVERT_TO_RELATIVE_IMPORT = AssistKind(
+ 'dart.assist.convert.packageToRelativeImport',
+ 30,
+ 'Convert to a relative import');
static const CONVERT_TO_SET_LITERAL = AssistKind(
'dart.assist.convert.toSetLiteral', 30, 'Convert to set literal',
associatedErrorCodes: <String>['prefer_collection_literals']);
diff --git a/pkg/analysis_server/lib/src/services/correction/assist_internal.dart b/pkg/analysis_server/lib/src/services/correction/assist_internal.dart
index 8478e7d..8ab9a0f 100644
--- a/pkg/analysis_server/lib/src/services/correction/assist_internal.dart
+++ b/pkg/analysis_server/lib/src/services/correction/assist_internal.dart
@@ -11,14 +11,31 @@
import 'package:analysis_server/src/services/correction/assist.dart';
import 'package:analysis_server/src/services/correction/base_processor.dart';
import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
+import 'package:analysis_server/src/services/correction/dart/add_diagnostic_property_reference.dart';
import 'package:analysis_server/src/services/correction/dart/add_return_type.dart';
+import 'package:analysis_server/src/services/correction/dart/add_type_annotation.dart';
+import 'package:analysis_server/src/services/correction/dart/convert_add_all_to_spread.dart';
+import 'package:analysis_server/src/services/correction/dart/convert_conditional_expression_to_if_element.dart';
+import 'package:analysis_server/src/services/correction/dart/convert_documentation_into_line.dart';
+import 'package:analysis_server/src/services/correction/dart/convert_map_from_iterable_to_for_literal.dart';
+import 'package:analysis_server/src/services/correction/dart/convert_quotes.dart';
+import 'package:analysis_server/src/services/correction/dart/convert_to_expression_function_body.dart';
+import 'package:analysis_server/src/services/correction/dart/convert_to_generic_function_syntax.dart';
+import 'package:analysis_server/src/services/correction/dart/convert_to_int_literal.dart';
import 'package:analysis_server/src/services/correction/dart/convert_to_list_literal.dart';
import 'package:analysis_server/src/services/correction/dart/convert_to_map_literal.dart';
import 'package:analysis_server/src/services/correction/dart/convert_to_null_aware.dart';
+import 'package:analysis_server/src/services/correction/dart/convert_to_package_import.dart';
+import 'package:analysis_server/src/services/correction/dart/convert_to_relative_import.dart';
import 'package:analysis_server/src/services/correction/dart/convert_to_set_literal.dart';
import 'package:analysis_server/src/services/correction/dart/exchange_operands.dart';
+import 'package:analysis_server/src/services/correction/dart/inline_invocation.dart';
+import 'package:analysis_server/src/services/correction/dart/remove_type_annotation.dart';
+import 'package:analysis_server/src/services/correction/dart/replace_with_var.dart';
import 'package:analysis_server/src/services/correction/dart/shadow_field.dart';
+import 'package:analysis_server/src/services/correction/dart/sort_child_property_last.dart';
import 'package:analysis_server/src/services/correction/dart/split_and_condition.dart';
+import 'package:analysis_server/src/services/correction/dart/use_curly_braces.dart';
import 'package:analysis_server/src/services/correction/name_suggestion.dart';
import 'package:analysis_server/src/services/correction/selection_analyzer.dart';
import 'package:analysis_server/src/services/correction/statement_analyzer.dart';
@@ -33,7 +50,6 @@
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/src/dart/ast/token.dart';
import 'package:analyzer/src/dart/ast/utilities.dart';
-import 'package:analyzer/src/dart/element/type.dart';
import 'package:analyzer/src/generated/java_core.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer_plugin/protocol/protocol_common.dart' hide Element;
@@ -64,56 +80,22 @@
if (!setupCompute()) {
return assists;
}
- if (!_containsErrorCode(
- {LintNames.always_specify_types, LintNames.type_annotate_public_apis},
- )) {
- await _addProposals_addTypeAnnotation();
- }
await _addProposal_addNotNullAssert();
await _addProposal_assignToLocalVariable();
await _addProposal_convertClassToMixin();
await _addProposal_convertDocumentationIntoBlock();
- if (!_containsErrorCode(
- {LintNames.slash_for_doc_comments},
- )) {
- await _addProposal_convertDocumentationIntoLine();
- }
await _addProposal_convertIntoFinalField();
await _addProposal_convertIntoGetter();
await _addProposal_convertPartOfToUri();
await _addProposal_convertToAsyncFunctionBody();
await _addProposal_convertToBlockFunctionBody();
- await _addProposal_convertToDoubleQuotedString();
- if (!_containsErrorCode(
- {LintNames.prefer_expression_function_bodies},
- )) {
- await _addProposal_convertToExpressionFunctionBody();
- }
await _addProposal_convertToFieldParameter();
await _addProposal_convertToForIndexLoop();
- if (!_containsErrorCode({LintNames.prefer_generic_function_type_aliases})) {
- await _addProposal_convertToGenericFunctionSyntax();
- }
- if (!_containsErrorCode(
- {LintNames.prefer_int_literals},
- )) {
- await _addProposal_convertToIntLiteral();
- }
await _addProposal_convertToIsNot_onIs();
await _addProposal_convertToIsNot_onNot();
await _addProposal_convertToIsNotEmpty();
await _addProposal_convertToMultilineString();
await _addProposal_convertToNormalParameter();
- if (!_containsErrorCode(
- {LintNames.avoid_relative_lib_imports},
- )) {
- await _addProposal_convertToPackageImport();
- }
- if (!_containsErrorCode(
- {LintNames.prefer_single_quotes},
- )) {
- await _addProposal_convertToSingleQuotedString();
- }
await _addProposal_encapsulateField();
await _addProposal_flutterConvertToChildren();
await _addProposal_flutterConvertToStatefulWidget();
@@ -127,66 +109,17 @@
await _addProposal_flutterWrapWidget();
await _addProposal_flutterWrapWidgets();
await _addProposal_importAddShow();
- if (!_containsErrorCode(
- {LintNames.prefer_inlined_adds},
- )) {
- await _addProposal_inlineAdd();
- }
await _addProposal_introduceLocalTestedType();
await _addProposal_invertIf();
await _addProposal_joinIfStatementInner();
await _addProposal_joinIfStatementOuter();
await _addProposal_joinVariableDeclaration_onAssignment();
await _addProposal_joinVariableDeclaration_onDeclaration();
- await _addProposal_removeTypeAnnotation();
await _addProposal_reparentFlutterList();
await _addProposal_replaceConditionalWithIfElse();
await _addProposal_replaceIfElseWithConditional();
- if (!_containsErrorCode({LintNames.omit_local_variable_types})) {
- await _addProposal_replaceWithVar();
- }
- if (!_containsErrorCode(
- {LintNames.sort_child_properties_last},
- )) {
- await _addProposal_sortChildPropertyLast();
- }
await _addProposal_splitVariableDeclaration();
await _addProposal_surroundWith();
- if (!_containsErrorCode(
- {LintNames.curly_braces_in_flow_control_structures},
- )) {
- await _addProposal_useCurlyBraces();
- }
- if (!_containsErrorCode(
- {LintNames.diagnostic_describe_all_properties},
- )) {
- await _addProposal_addDiagnosticPropertyReference();
- }
- if (experimentStatus.control_flow_collections) {
- if (!_containsErrorCode(
- {LintNames.prefer_if_elements_to_conditional_expressions},
- )) {
- await _addProposal_convertConditionalExpressionToIfElement();
- }
- if (!_containsErrorCode(
- {LintNames.prefer_for_elements_to_map_fromIterable},
- )) {
- await _addProposal_convertMapFromIterableToForLiteral();
- }
- }
- if (experimentStatus.spread_collections) {
- final preferSpreadsLintFound =
- _containsErrorCode({LintNames.prefer_spread_collections});
- final preferInlinedAddsLintFound =
- _containsErrorCode({LintNames.prefer_inlined_adds});
- if (!_containsErrorCode(
- {LintNames.prefer_spread_collections},
- )) {
- await _addProposal_convertAddAllToSpread(
- preferInlinedAdds: !preferInlinedAddsLintFound,
- convertToSpreads: !preferSpreadsLintFound);
- }
- }
await _addFromProducers();
@@ -198,23 +131,39 @@
return assists;
}
+ var context = CorrectionProducerContext(
+ selectionOffset: selectionOffset,
+ selectionLength: selectionLength,
+ resolvedResult: resolvedResult,
+ workspace: workspace,
+ );
+
+ var setupSuccess = context.setupCompute();
+ if (!setupSuccess) {
+ return assists;
+ }
+
+ Future<void> compute(CorrectionProducer producer) async {
+ producer.configure(context);
+
+ var builder = _newDartChangeBuilder();
+ await producer.compute(builder);
+
+ _addAssistFromBuilder(builder, producer.assistKind,
+ args: producer.assistArguments);
+ }
+
// Calculate only specific assists for edit.dartFix
if (assistKind == DartAssistKind.CONVERT_CLASS_TO_MIXIN) {
await _addProposal_convertClassToMixin();
} else if (assistKind == DartAssistKind.CONVERT_TO_INT_LITERAL) {
- await _addProposal_convertToIntLiteral();
+ await compute(ConvertToIntLiteral());
} else if (assistKind == DartAssistKind.CONVERT_TO_SPREAD) {
- if (experimentStatus.spread_collections) {
- await _addProposal_convertAddAllToSpread();
- }
+ await compute(ConvertAddAllToSpread());
} else if (assistKind == DartAssistKind.CONVERT_TO_FOR_ELEMENT) {
- if (experimentStatus.control_flow_collections) {
- await _addProposal_convertMapFromIterableToForLiteral();
- }
+ await compute(ConvertMapFromIterableToForLiteral());
} else if (assistKind == DartAssistKind.CONVERT_TO_IF_ELEMENT) {
- if (experimentStatus.control_flow_collections) {
- await _addProposal_convertConditionalExpressionToIfElement();
- }
+ await compute(ConvertConditionalExpressionToIfElement());
}
return assists;
}
@@ -271,6 +220,43 @@
{LintNames.always_declare_return_types},
);
await computeIfNotErrorCode(
+ AddDiagnosticPropertyReference(),
+ {LintNames.diagnostic_describe_all_properties},
+ );
+ await computeIfNotErrorCode(
+ AddTypeAnnotation(),
+ {LintNames.always_specify_types, LintNames.type_annotate_public_apis},
+ );
+ await computeIfNotErrorCode(
+ ConvertConditionalExpressionToIfElement(),
+ {LintNames.prefer_if_elements_to_conditional_expressions},
+ );
+ await computeIfNotErrorCode(
+ ConvertDocumentationIntoLine(),
+ {LintNames.slash_for_doc_comments},
+ );
+ await computeIfNotErrorCode(
+ ConvertMapFromIterableToForLiteral(),
+ {LintNames.prefer_for_elements_to_map_fromIterable},
+ );
+ await compute(ConvertToDoubleQuotes());
+ await computeIfNotErrorCode(
+ ConvertToSingleQuotes(),
+ {LintNames.prefer_single_quotes},
+ );
+ await computeIfNotErrorCode(
+ ConvertToExpressionFunctionBody(),
+ {LintNames.prefer_expression_function_bodies},
+ );
+ await computeIfNotErrorCode(
+ ConvertToGenericFunctionSyntax(),
+ {LintNames.prefer_generic_function_type_aliases},
+ );
+ await computeIfNotErrorCode(
+ ConvertToIntLiteral(),
+ {LintNames.prefer_int_literals},
+ );
+ await computeIfNotErrorCode(
ConvertToListLiteral(),
{LintNames.prefer_collection_literals},
);
@@ -283,18 +269,41 @@
{LintNames.prefer_null_aware_operators},
);
await computeIfNotErrorCode(
+ ConvertToPackageImport(),
+ {LintNames.avoid_relative_lib_imports},
+ );
+ await computeIfNotErrorCode(
+ ConvertToRelativeImport(),
+ {LintNames.prefer_relative_imports},
+ );
+ await computeIfNotErrorCode(
ConvertToSetLiteral(),
{LintNames.prefer_collection_literals},
);
await compute(ExchangeOperands());
+ await computeIfNotErrorCode(
+ InlineInvocation(),
+ {LintNames.prefer_inlined_adds},
+ );
+ await compute(RemoveTypeAnnotation());
+ await computeIfNotErrorCode(
+ ReplaceWithVar(),
+ {LintNames.omit_local_variable_types},
+ );
await compute(ShadowField());
+ await computeIfNotErrorCode(
+ SortChildPropertyLast(),
+ {LintNames.sort_child_properties_last},
+ );
await compute(SplitAndCondition());
- }
-
- Future<void> _addProposal_addDiagnosticPropertyReference() async {
- final changeBuilder = await createBuilder_addDiagnosticPropertyReference();
- _addAssistFromBuilder(
- changeBuilder, DartAssistKind.ADD_DIAGNOSTIC_PROPERTY_REFERENCE);
+ await computeIfNotErrorCode(
+ UseCurlyBraces(),
+ {LintNames.curly_braces_in_flow_control_structures},
+ );
+ await computeIfNotErrorCode(
+ ConvertAddAllToSpread(),
+ {LintNames.prefer_inlined_adds, LintNames.prefer_spread_collections},
+ );
}
Future<void> _addProposal_addNotNullAssert() async {
@@ -406,20 +415,6 @@
}
}
- Future<void> _addProposal_convertAddAllToSpread(
- {bool preferInlinedAdds = true, bool convertToSpreads = true}) async {
- final change = await createBuilder_convertAddAllToSpread();
- if (change != null) {
- if (change.isLineInvocation && !preferInlinedAdds || !convertToSpreads) {
- return;
- }
- final kind = change.isLineInvocation
- ? DartAssistKind.INLINE_INVOCATION
- : DartAssistKind.CONVERT_TO_SPREAD;
- _addAssistFromBuilder(change.builder, kind, args: change.args);
- }
- }
-
Future<void> _addProposal_convertClassToMixin() async {
var classDeclaration = node.thisOrAncestorOfType<ClassDeclaration>();
if (classDeclaration == null) {
@@ -475,12 +470,6 @@
_addAssistFromBuilder(changeBuilder, DartAssistKind.CONVERT_CLASS_TO_MIXIN);
}
- Future<void> _addProposal_convertConditionalExpressionToIfElement() async {
- final changeBuilder =
- await createBuilder_convertConditionalExpressionToIfElement();
- _addAssistFromBuilder(changeBuilder, DartAssistKind.CONVERT_TO_IF_ELEMENT);
- }
-
Future<void> _addProposal_convertDocumentationIntoBlock() async {
var comment = node.thisOrAncestorOfType<Comment>();
if (comment == null || !comment.isDocumentation) {
@@ -512,12 +501,6 @@
changeBuilder, DartAssistKind.CONVERT_DOCUMENTATION_INTO_BLOCK);
}
- Future<void> _addProposal_convertDocumentationIntoLine() async {
- final changeBuilder = await createBuilder_convertDocumentationIntoLine();
- _addAssistFromBuilder(
- changeBuilder, DartAssistKind.CONVERT_DOCUMENTATION_INTO_LINE);
- }
-
Future<void> _addProposal_convertIntoFinalField() async {
// Find the enclosing getter.
MethodDeclaration getter;
@@ -635,12 +618,6 @@
_addAssistFromBuilder(changeBuilder, DartAssistKind.CONVERT_INTO_GETTER);
}
- Future<void> _addProposal_convertMapFromIterableToForLiteral() async {
- final changeBuilder =
- await createBuilder_convertMapFromIterableToForLiteral();
- _addAssistFromBuilder(changeBuilder, DartAssistKind.CONVERT_TO_FOR_ELEMENT);
- }
-
Future<void> _addProposal_convertPartOfToUri() async {
var directive = node.thisOrAncestorOfType<PartOfDirective>();
if (directive == null || directive.libraryName == null) {
@@ -659,7 +636,7 @@
}
Future<void> _addProposal_convertToAsyncFunctionBody() async {
- var body = getEnclosingFunctionBody();
+ var body = _getEnclosingFunctionBody();
if (body == null ||
body is EmptyFunctionBody ||
body.isAsynchronous ||
@@ -693,7 +670,7 @@
}
Future<void> _addProposal_convertToBlockFunctionBody() async {
- var body = getEnclosingFunctionBody();
+ var body = _getEnclosingFunctionBody();
// prepare expression body
if (body is! ExpressionFunctionBody || body.isGenerator) {
_coverageMarker();
@@ -735,16 +712,6 @@
changeBuilder, DartAssistKind.CONVERT_INTO_BLOCK_BODY);
}
- Future<void> _addProposal_convertToDoubleQuotedString() async {
- await _convertQuotes(false, DartAssistKind.CONVERT_TO_DOUBLE_QUOTED_STRING);
- }
-
- Future<void> _addProposal_convertToExpressionFunctionBody() async {
- final changeBuilder = await createBuilder_convertToExpressionFunctionBody();
- _addAssistFromBuilder(
- changeBuilder, DartAssistKind.CONVERT_INTO_EXPRESSION_BODY);
- }
-
Future<void> _addProposal_convertToFieldParameter() async {
if (node == null) {
return;
@@ -917,17 +884,6 @@
_addAssistFromBuilder(changeBuilder, DartAssistKind.CONVERT_INTO_FOR_INDEX);
}
- Future<void> _addProposal_convertToGenericFunctionSyntax() async {
- var changeBuilder = await createBuilder_convertToGenericFunctionSyntax();
- _addAssistFromBuilder(
- changeBuilder, DartAssistKind.CONVERT_INTO_GENERIC_FUNCTION_SYNTAX);
- }
-
- Future<void> _addProposal_convertToIntLiteral() async {
- final changeBuilder = await createBuilder_convertToIntLiteral();
- _addAssistFromBuilder(changeBuilder, DartAssistKind.CONVERT_TO_INT_LITERAL);
- }
-
Future<void> _addProposal_convertToIsNot_onIs() async {
// may be child of "is"
var node = this.node;
@@ -1158,16 +1114,6 @@
}
}
- Future<void> _addProposal_convertToPackageImport() async {
- final changeBuilder = await createBuilder_convertToPackageImport();
- _addAssistFromBuilder(
- changeBuilder, DartAssistKind.CONVERT_TO_PACKAGE_IMPORT);
- }
-
- Future<void> _addProposal_convertToSingleQuotedString() async {
- await _convertQuotes(true, DartAssistKind.CONVERT_TO_SINGLE_QUOTED_STRING);
- }
-
Future<void> _addProposal_encapsulateField() async {
// find FieldDeclaration
var fieldDeclaration = node.thisOrAncestorOfType<FieldDeclaration>();
@@ -1997,12 +1943,6 @@
_addAssistFromBuilder(changeBuilder, DartAssistKind.IMPORT_ADD_SHOW);
}
- Future<void> _addProposal_inlineAdd() async {
- final changeBuilder = await createBuilder_inlineAdd();
- _addAssistFromBuilder(changeBuilder, DartAssistKind.INLINE_INVOCATION,
- args: ['add']);
- }
-
Future<void> _addProposal_introduceLocalTestedType() async {
var node = this.node;
if (node is IfStatement) {
@@ -2362,13 +2302,6 @@
changeBuilder, DartAssistKind.JOIN_VARIABLE_DECLARATION);
}
- Future<void> _addProposal_removeTypeAnnotation() async {
- // todo (pq): unify w/ fix (and then add a guard to not assist on lints:
- // avoid_return_types_on_setters, type_init_formals)
- final changeBuilder = await createBuilder_removeTypeAnnotation();
- _addAssistFromBuilder(changeBuilder, DartAssistKind.REMOVE_TYPE_ANNOTATION);
- }
-
Future<void> _addProposal_reparentFlutterList() async {
if (node is! ListLiteral) {
return;
@@ -2581,63 +2514,6 @@
}
}
- Future<void> _addProposal_replaceWithVar() async {
- /// Return `true` if the type in the [node] can be replaced with `var`.
- bool canConvertVariableDeclarationList(VariableDeclarationList node) {
- final staticType = node?.type?.type;
- if (staticType == null || staticType.isDynamic) {
- return false;
- }
- for (final child in node.variables) {
- var initializer = child.initializer;
- if (initializer == null || initializer.staticType != staticType) {
- return false;
- }
- }
- return true;
- }
-
- /// Return `true` if the given node can be replaced with `var`.
- bool canReplaceWithVar() {
- var parent = node.parent;
- while (parent != null) {
- if (parent is VariableDeclarationStatement) {
- return canConvertVariableDeclarationList(parent.variables);
- } else if (parent is ForPartsWithDeclarations) {
- return canConvertVariableDeclarationList(parent.variables);
- } else if (parent is ForEachPartsWithDeclaration) {
- var loopVariableType = parent.loopVariable.type;
- var staticType = loopVariableType?.type;
- if (staticType == null || staticType.isDynamic) {
- return false;
- }
- final iterableType = parent.iterable.staticType;
- if (iterableType is InterfaceTypeImpl) {
- var instantiatedType =
- iterableType.asInstanceOf(typeProvider.iterableElement);
- if (instantiatedType?.typeArguments?.first == staticType) {
- return true;
- }
- }
- return false;
- }
- parent = parent.parent;
- }
- return false;
- }
-
- if (canReplaceWithVar()) {
- var changeBuilder = await createBuilder_replaceWithVar();
- _addAssistFromBuilder(changeBuilder, DartAssistKind.REPLACE_WITH_VAR);
- }
- }
-
- Future<void> _addProposal_sortChildPropertyLast() async {
- final changeBuilder = await createBuilder_sortChildPropertyLast();
- _addAssistFromBuilder(
- changeBuilder, DartAssistKind.SORT_CHILD_PROPERTY_LAST);
- }
-
Future<void> _addProposal_splitVariableDeclaration() async {
var variableList = node?.thisOrAncestorOfType<VariableDeclarationList>();
@@ -2922,24 +2798,6 @@
}
}
- Future<void> _addProposal_useCurlyBraces() async {
- final changeBuilder = await createBuilder_useCurlyBraces();
- _addAssistFromBuilder(changeBuilder, DartAssistKind.USE_CURLY_BRACES);
- }
-
- Future<void> _addProposals_addTypeAnnotation() async {
- var changeBuilder =
- await createBuilder_addTypeAnnotation_DeclaredIdentifier();
- _addAssistFromBuilder(changeBuilder, DartAssistKind.ADD_TYPE_ANNOTATION);
-
- changeBuilder =
- await createBuilder_addTypeAnnotation_SimpleFormalParameter();
- _addAssistFromBuilder(changeBuilder, DartAssistKind.ADD_TYPE_ANNOTATION);
-
- changeBuilder = await createBuilder_addTypeAnnotation_VariableDeclaration();
- _addAssistFromBuilder(changeBuilder, DartAssistKind.ADD_TYPE_ANNOTATION);
- }
-
bool _containsErrorCode(Set<String> errorCodes) {
final fileOffset = node.offset;
for (var error in context.resolveResult.errors) {
@@ -2998,9 +2856,27 @@
}
}
- Future<void> _convertQuotes(bool fromDouble, AssistKind kind) async {
- final changeBuilder = await createBuilder_convertQuotes(fromDouble);
- _addAssistFromBuilder(changeBuilder, kind);
+ FunctionBody _getEnclosingFunctionBody() {
+ // This is duplicated from [CorrectionProducer] and should be replaced by
+ // that method when the assists that reference it are converted to be
+ // producers.
+ var closure = node.thisOrAncestorOfType<FunctionExpression>();
+ if (closure != null) {
+ return closure.body;
+ }
+ var function = node.thisOrAncestorOfType<FunctionDeclaration>();
+ if (function != null) {
+ return function.functionExpression.body;
+ }
+ var constructor = node.thisOrAncestorOfType<ConstructorDeclaration>();
+ if (constructor != null) {
+ return constructor.body;
+ }
+ var method = node.thisOrAncestorOfType<MethodDeclaration>();
+ if (method != null) {
+ return method.body;
+ }
+ return null;
}
/// Returns the text of the given node in the unit.
diff --git a/pkg/analysis_server/lib/src/services/correction/base_processor.dart b/pkg/analysis_server/lib/src/services/correction/base_processor.dart
index ecaaa94..2e797a5 100644
--- a/pkg/analysis_server/lib/src/services/correction/base_processor.dart
+++ b/pkg/analysis_server/lib/src/services/correction/base_processor.dart
@@ -7,24 +7,13 @@
import 'package:analyzer/dart/analysis/results.dart';
import 'package:analyzer/dart/analysis/session.dart';
import 'package:analyzer/dart/ast/ast.dart';
-import 'package:analyzer/dart/ast/token.dart';
-import 'package:analyzer/dart/ast/visitor.dart';
-import 'package:analyzer/dart/element/element.dart';
-import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/dart/element/type_provider.dart';
-import 'package:analyzer/source/source_range.dart';
import 'package:analyzer/src/dart/analysis/experiments.dart';
import 'package:analyzer/src/dart/analysis/session_helper.dart';
import 'package:analyzer/src/dart/ast/utilities.dart';
import 'package:analyzer/src/generated/engine.dart' show AnalysisOptionsImpl;
-import 'package:analyzer_plugin/protocol/protocol_common.dart';
-import 'package:analyzer_plugin/src/utilities/change_builder/change_builder_dart.dart';
-import 'package:analyzer_plugin/utilities/change_builder/change_builder_core.dart';
-import 'package:analyzer_plugin/utilities/change_builder/change_builder_dart.dart';
import 'package:analyzer_plugin/utilities/change_builder/change_workspace.dart';
-import 'package:analyzer_plugin/utilities/range_factory.dart';
import 'package:meta/meta.dart';
-import 'package:path/path.dart' as path;
/// Base class for common processor functionality.
abstract class BaseProcessor {
@@ -66,1464 +55,10 @@
(session.analysisContext.analysisOptions as AnalysisOptionsImpl)
.experimentStatus;
- Future<ChangeBuilder> createBuilder_addDiagnosticPropertyReference() async {
- final node = this.node;
- if (node is! SimpleIdentifier) {
- _coverageMarker();
- return null;
- }
- SimpleIdentifier name = node;
- final parent = node.parent;
-
- DartType type;
-
- // Getter.
- if (parent is MethodDeclaration) {
- var methodDeclaration = parent;
- var element = methodDeclaration.declaredElement;
- if (element is PropertyAccessorElement) {
- var propertyAccessor = element;
- type = propertyAccessor.returnType;
- }
- // Field.
- } else if (parent is VariableDeclaration) {
- var variableDeclaration = parent;
- final element = variableDeclaration.declaredElement;
- if (element is FieldElement) {
- var fieldElement = element;
- type = fieldElement.type;
- }
- }
-
- if (type == null) {
- return null;
- }
-
- var constructorId;
- var typeArgs;
- var constructorName = '';
-
- if (type.element is FunctionTypedElement) {
- constructorId = 'ObjectFlagProperty';
- typeArgs = [type];
- constructorName = '.has';
- } else if (type.isDartCoreInt) {
- constructorId = 'IntProperty';
- } else if (type.isDartCoreDouble) {
- constructorId = 'DoubleProperty';
- } else if (type.isDartCoreString) {
- constructorId = 'StringProperty';
- } else if (isEnum(type)) {
- constructorId = 'EnumProperty';
- typeArgs = [type];
- } else if (isIterable(type)) {
- constructorId = 'IterableProperty';
- typeArgs = (type as InterfaceType).typeArguments;
- } else if (flutter.isColor(type)) {
- constructorId = 'ColorProperty';
- } else if (flutter.isMatrix4(type)) {
- constructorId = 'TransformProperty';
- } else {
- constructorId = 'DiagnosticsProperty';
- if (!type.isDynamic) {
- typeArgs = [type];
- }
- }
-
- void writePropertyReference(
- DartEditBuilder builder, {
- @required String prefix,
- @required String builderName,
- }) {
- builder.write('$prefix$builderName.add($constructorId');
- if (typeArgs != null) {
- builder.write('<');
- builder.writeTypes(typeArgs);
- builder.write('>');
- } else if (type.isDynamic) {
- TypeAnnotation declType;
- final decl = node.thisOrAncestorOfType<VariableDeclarationList>();
- if (decl != null) {
- declType = decl.type;
- // getter
- } else if (parent is MethodDeclaration) {
- declType = parent.returnType;
- }
-
- if (declType != null) {
- final typeText = utils.getNodeText(declType);
- if (typeText != 'dynamic') {
- builder.write('<');
- builder.write(utils.getNodeText(declType));
- builder.write('>');
- }
- }
- }
- builder.writeln("$constructorName('${name.name}', ${name.name}));");
- }
-
- final classDeclaration = parent.thisOrAncestorOfType<ClassDeclaration>();
- final debugFillProperties =
- classDeclaration.getMethod('debugFillProperties');
- if (debugFillProperties == null) {
- final insertOffset =
- utils.prepareNewMethodLocation(classDeclaration).offset;
- final changeBuilder = _newDartChangeBuilder();
- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
- builder.addInsertion(utils.getLineNext(insertOffset),
- (DartEditBuilder builder) {
- final declPrefix =
- utils.getLinePrefix(classDeclaration.offset) + utils.getIndent(1);
- final bodyPrefix = declPrefix + utils.getIndent(1);
-
- builder.writeln('$declPrefix@override');
- builder.writeln(
- '${declPrefix}void debugFillProperties(DiagnosticPropertiesBuilder properties) {');
- builder
- .writeln('${bodyPrefix}super.debugFillProperties(properties);');
- writePropertyReference(builder,
- prefix: bodyPrefix, builderName: 'properties');
- builder.writeln('$declPrefix}');
- });
- });
- return changeBuilder;
- }
-
- final body = debugFillProperties.body;
- if (body is BlockFunctionBody) {
- var functionBody = body;
-
- var offset;
- var prefix;
- if (functionBody.block.statements.isEmpty) {
- offset = functionBody.block.leftBracket.offset;
- prefix = utils.getLinePrefix(offset) + utils.getIndent(1);
- } else {
- offset = functionBody.block.statements.last.endToken.offset;
- prefix = utils.getLinePrefix(offset);
- }
-
- var parameters = debugFillProperties.parameters.parameters;
- var propertiesBuilderName;
- for (var parameter in parameters) {
- if (parameter is SimpleFormalParameter) {
- final type = parameter.type;
- if (type is TypeName) {
- if (type.name.name == 'DiagnosticPropertiesBuilder') {
- propertiesBuilderName = parameter.identifier.name;
- break;
- }
- }
- }
- }
- if (propertiesBuilderName == null) {
- return null;
- }
-
- final changeBuilder = _newDartChangeBuilder();
- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
- builder.addInsertion(utils.getLineNext(offset),
- (DartEditBuilder builder) {
- writePropertyReference(builder,
- prefix: prefix, builderName: propertiesBuilderName);
- });
- });
- return changeBuilder;
- }
-
- return null;
- }
-
- Future<ChangeBuilder>
- createBuilder_addTypeAnnotation_DeclaredIdentifier() async {
- var declaredIdentifier = node.thisOrAncestorOfType<DeclaredIdentifier>();
- if (declaredIdentifier == null) {
- var forEach = node.thisOrAncestorMatching((node) =>
- node is ForStatement && node.forLoopParts is ForEachParts)
- as ForStatement;
- ForEachParts forEachParts = forEach?.forLoopParts;
- var offset = node.offset;
- if (forEach != null &&
- forEachParts.iterable != null &&
- offset < forEachParts.iterable.offset) {
- declaredIdentifier = forEachParts is ForEachPartsWithDeclaration
- ? forEachParts.loopVariable
- : null;
- }
- }
- if (declaredIdentifier == null) {
- _coverageMarker();
- return null;
- }
- // Ensure that there isn't already a type annotation.
- if (declaredIdentifier.type != null) {
- _coverageMarker();
- return null;
- }
- var type = declaredIdentifier.declaredElement.type;
- if (type is! InterfaceType && type is! FunctionType) {
- _coverageMarker();
- return null;
- }
- _configureTargetLocation(node);
-
- var changeBuilder = _newDartChangeBuilder();
- var validChange = true;
- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
- var keyword = declaredIdentifier.keyword;
- if (keyword.keyword == Keyword.VAR) {
- builder.addReplacement(range.token(keyword), (DartEditBuilder builder) {
- validChange = builder.writeType(type);
- });
- } else {
- builder.addInsertion(declaredIdentifier.identifier.offset,
- (DartEditBuilder builder) {
- validChange = builder.writeType(type);
- builder.write(' ');
- });
- }
- });
- return validChange ? changeBuilder : null;
- }
-
- Future<ChangeBuilder>
- createBuilder_addTypeAnnotation_SimpleFormalParameter() async {
- var node = this.node;
- // should be the name of a simple parameter
- if (node is! SimpleIdentifier || node.parent is! SimpleFormalParameter) {
- _coverageMarker();
- return null;
- }
- SimpleIdentifier name = node;
- SimpleFormalParameter parameter = node.parent;
- // the parameter should not have a type
- if (parameter.type != null) {
- _coverageMarker();
- return null;
- }
- // prepare the type
- var type = parameter.declaredElement.type;
- // TODO(scheglov) If the parameter is in a method declaration, and if the
- // method overrides a method that has a type for the corresponding
- // parameter, it would be nice to copy down the type from the overridden
- // method.
- if (type is! InterfaceType) {
- _coverageMarker();
- return null;
- }
- // prepare type source
- _configureTargetLocation(node);
-
- var changeBuilder = _newDartChangeBuilder();
- var validChange = true;
- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
- builder.addInsertion(name.offset, (DartEditBuilder builder) {
- validChange = builder.writeType(type);
- builder.write(' ');
- });
- });
- return validChange ? changeBuilder : null;
- }
-
- Future<ChangeBuilder>
- createBuilder_addTypeAnnotation_VariableDeclaration() async {
- var node = this.node;
- // prepare VariableDeclarationList
- var declarationList = node.thisOrAncestorOfType<VariableDeclarationList>();
- if (declarationList == null) {
- _coverageMarker();
- return null;
- }
- // may be has type annotation already
- if (declarationList.type != null) {
- _coverageMarker();
- return null;
- }
- // prepare single VariableDeclaration
- List<VariableDeclaration> variables = declarationList.variables;
- if (variables.length != 1) {
- _coverageMarker();
- return null;
- }
- var variable = variables[0];
- // must be not after the name of the variable
- if (selectionOffset > variable.name.end) {
- _coverageMarker();
- return null;
- }
- // we need an initializer to get the type from
- var initializer = variable.initializer;
- if (initializer == null) {
- _coverageMarker();
- return null;
- }
- var type = initializer.staticType;
- // prepare type source
- if ((type is! InterfaceType || type.isDartCoreNull) &&
- type is! FunctionType) {
- _coverageMarker();
- return null;
- }
- _configureTargetLocation(node);
-
- var changeBuilder = _newDartChangeBuilder();
- var validChange = true;
- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
- var keyword = declarationList.keyword;
- if (keyword?.keyword == Keyword.VAR) {
- builder.addReplacement(range.token(keyword), (DartEditBuilder builder) {
- validChange = builder.writeType(type);
- });
- } else {
- builder.addInsertion(variable.offset, (DartEditBuilder builder) {
- validChange = builder.writeType(type);
- builder.write(' ');
- });
- }
- });
- return validChange ? changeBuilder : null;
- }
-
- Future<ConvertToSpreadCollectionsChange>
- createBuilder_convertAddAllToSpread() async {
- var node = this.node;
- if (node is! SimpleIdentifier || node.parent is! MethodInvocation) {
- _coverageMarker();
- return null;
- }
- SimpleIdentifier name = node;
- MethodInvocation invocation = node.parent;
- if (name != invocation.methodName ||
- name.name != 'addAll' ||
- !invocation.isCascaded ||
- invocation.argumentList.arguments.length != 1) {
- _coverageMarker();
- return null;
- }
- var cascade = invocation.thisOrAncestorOfType<CascadeExpression>();
- var sections = cascade.cascadeSections;
- var target = cascade.target;
- if (target is! ListLiteral || sections[0] != invocation) {
- // TODO(brianwilkerson) Consider extending this to handle set literals.
- _coverageMarker();
- return null;
- }
-
- bool isEmptyListLiteral(Expression expression) =>
- expression is ListLiteral && expression.elements.isEmpty;
-
- ListLiteral list = target;
- var argument = invocation.argumentList.arguments[0];
- String elementText;
- var change = ConvertToSpreadCollectionsChange();
- List<String> args;
- if (argument is BinaryExpression &&
- argument.operator.type == TokenType.QUESTION_QUESTION) {
- var right = argument.rightOperand;
- if (isEmptyListLiteral(right)) {
- // ..addAll(things ?? const [])
- // ..addAll(things ?? [])
- elementText = '...?${utils.getNodeText(argument.leftOperand)}';
- }
- } else if (experimentStatus.control_flow_collections &&
- argument is ConditionalExpression) {
- var elseExpression = argument.elseExpression;
- if (isEmptyListLiteral(elseExpression)) {
- // ..addAll(condition ? things : const [])
- // ..addAll(condition ? things : [])
- var conditionText = utils.getNodeText(argument.condition);
- var thenText = utils.getNodeText(argument.thenExpression);
- elementText = 'if ($conditionText) ...$thenText';
- }
- } else if (argument is ListLiteral) {
- // ..addAll([ ... ])
- var elements = argument.elements;
- if (elements.isEmpty) {
- // TODO(brianwilkerson) Consider adding a cleanup for the empty list
- // case. We can essentially remove the whole invocation because it does
- // nothing.
- return null;
- }
- var startOffset = elements.first.offset;
- var endOffset = elements.last.end;
- elementText = utils.getText(startOffset, endOffset - startOffset);
- change.isLineInvocation = true;
- args = ['addAll'];
- }
- elementText ??= '...${utils.getNodeText(argument)}';
- var changeBuilder = _newDartChangeBuilder();
- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
- if (list.elements.isNotEmpty) {
- // ['a']..addAll(['b', 'c']);
- builder.addSimpleInsertion(list.elements.last.end, ', $elementText');
- } else {
- // []..addAll(['b', 'c']);
- builder.addSimpleInsertion(list.leftBracket.end, elementText);
- }
- builder.addDeletion(range.node(invocation));
- });
- change.args = args;
- change.builder = changeBuilder;
- return change;
- }
-
- Future<ChangeBuilder>
- createBuilder_convertConditionalExpressionToIfElement() async {
- AstNode node = this.node.thisOrAncestorOfType<ConditionalExpression>();
- if (node == null) {
- _coverageMarker();
- return null;
- }
- var nodeToReplace = node;
- var parent = node.parent;
- while (parent is ParenthesizedExpression) {
- nodeToReplace = parent;
- parent = parent.parent;
- }
- if (parent is ListLiteral || (parent is SetOrMapLiteral && parent.isSet)) {
- ConditionalExpression conditional = node;
- var condition = conditional.condition.unParenthesized;
- var thenExpression = conditional.thenExpression.unParenthesized;
- var elseExpression = conditional.elseExpression.unParenthesized;
-
- var changeBuilder = _newDartChangeBuilder();
- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
- builder.addReplacement(range.node(nodeToReplace),
- (DartEditBuilder builder) {
- builder.write('if (');
- builder.write(utils.getNodeText(condition));
- builder.write(') ');
- builder.write(utils.getNodeText(thenExpression));
- builder.write(' else ');
- builder.write(utils.getNodeText(elseExpression));
- });
- });
- return changeBuilder;
- }
-
- return null;
- }
-
- Future<ChangeBuilder> createBuilder_convertDocumentationIntoLine() async {
- var comment = node.thisOrAncestorOfType<Comment>();
- if (comment == null ||
- !comment.isDocumentation ||
- comment.tokens.length != 1) {
- _coverageMarker();
- return null;
- }
- var token = comment.tokens.first;
- if (token.type != TokenType.MULTI_LINE_COMMENT) {
- _coverageMarker();
- return null;
- }
- var text = token.lexeme;
- var lines = text.split('\n');
- var prefix = utils.getNodePrefix(comment);
- var newLines = <String>[];
- var firstLine = true;
- var linePrefix = '';
- for (var line in lines) {
- if (firstLine) {
- firstLine = false;
- var expectedPrefix = '/**';
- if (!line.startsWith(expectedPrefix)) {
- _coverageMarker();
- return null;
- }
- line = line.substring(expectedPrefix.length).trim();
- if (line.isNotEmpty) {
- newLines.add('/// $line');
- linePrefix = eol + prefix;
- }
- } else {
- if (line.startsWith(prefix + ' */')) {
- break;
- }
- var expectedPrefix = prefix + ' *';
- if (!line.startsWith(expectedPrefix)) {
- _coverageMarker();
- return null;
- }
- line = line.substring(expectedPrefix.length);
- if (line.isEmpty) {
- newLines.add('$linePrefix///');
- } else {
- newLines.add('$linePrefix///$line');
- }
- linePrefix = eol + prefix;
- }
- }
-
- var changeBuilder = _newDartChangeBuilder();
- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
- builder.addReplacement(range.node(comment), (DartEditBuilder builder) {
- for (var newLine in newLines) {
- builder.write(newLine);
- }
- });
- });
- return changeBuilder;
- }
-
- Future<ChangeBuilder>
- createBuilder_convertMapFromIterableToForLiteral() async {
- //
- // Ensure that the selection is inside an invocation of Map.fromIterable.
- //
- var creation = node.thisOrAncestorOfType<InstanceCreationExpression>();
- if (creation == null) {
- _coverageMarker();
- return null;
- }
- var element = creation.staticElement;
- if (element == null ||
- element.name != 'fromIterable' ||
- element.enclosingElement != typeProvider.mapElement) {
- _coverageMarker();
- return null;
- }
- //
- // Ensure that the arguments have the right form.
- //
- var arguments = creation.argumentList.arguments;
- if (arguments.length != 3) {
- _coverageMarker();
- return null;
- }
- var iterator = arguments[0].unParenthesized;
- var secondArg = arguments[1];
- var thirdArg = arguments[2];
-
- Expression extractBody(FunctionExpression expression) {
- var body = expression.body;
- if (body is ExpressionFunctionBody) {
- return body.expression;
- } else if (body is BlockFunctionBody) {
- var statements = body.block.statements;
- if (statements.length == 1) {
- var statement = statements[0];
- if (statement is ReturnStatement) {
- return statement.expression;
- }
- }
- }
- return null;
- }
-
- FunctionExpression extractClosure(String name, Expression argument) {
- if (argument is NamedExpression && argument.name.label.name == name) {
- var expression = argument.expression.unParenthesized;
- if (expression is FunctionExpression) {
- var parameters = expression.parameters.parameters;
- if (parameters.length == 1 && parameters[0].isRequiredPositional) {
- if (extractBody(expression) != null) {
- return expression;
- }
- }
- }
- }
- return null;
- }
-
- var keyClosure =
- extractClosure('key', secondArg) ?? extractClosure('key', thirdArg);
- var valueClosure =
- extractClosure('value', thirdArg) ?? extractClosure('value', secondArg);
- if (keyClosure == null || valueClosure == null) {
- _coverageMarker();
- return null;
- }
- //
- // Compute the loop variable name and convert the key and value closures if
- // necessary.
- //
- SimpleFormalParameter keyParameter = keyClosure.parameters.parameters[0];
- var keyParameterName = keyParameter.identifier.name;
- SimpleFormalParameter valueParameter =
- valueClosure.parameters.parameters[0];
- var valueParameterName = valueParameter.identifier.name;
- var keyBody = extractBody(keyClosure);
- var keyExpressionText = utils.getNodeText(keyBody);
- var valueBody = extractBody(valueClosure);
- var valueExpressionText = utils.getNodeText(valueBody);
-
- String loopVariableName;
- if (keyParameterName == valueParameterName) {
- loopVariableName = keyParameterName;
- } else {
- var keyFinder = _ParameterReferenceFinder(keyParameter.declaredElement);
- keyBody.accept(keyFinder);
-
- var valueFinder =
- _ParameterReferenceFinder(valueParameter.declaredElement);
- valueBody.accept(valueFinder);
-
- String computeUnusedVariableName() {
- var candidate = 'e';
- var index = 1;
- while (keyFinder.referencesName(candidate) ||
- valueFinder.referencesName(candidate)) {
- candidate = 'e${index++}';
- }
- return candidate;
- }
-
- if (valueFinder.isParameterUnreferenced) {
- if (valueFinder.referencesName(keyParameterName)) {
- // The name of the value parameter is not used, but we can't use the
- // name of the key parameter because doing so would hide a variable
- // referenced in the value expression.
- loopVariableName = computeUnusedVariableName();
- keyExpressionText = keyFinder.replaceName(
- keyExpressionText, loopVariableName, keyBody.offset);
- } else {
- loopVariableName = keyParameterName;
- }
- } else if (keyFinder.isParameterUnreferenced) {
- if (keyFinder.referencesName(valueParameterName)) {
- // The name of the key parameter is not used, but we can't use the
- // name of the value parameter because doing so would hide a variable
- // referenced in the key expression.
- loopVariableName = computeUnusedVariableName();
- valueExpressionText = valueFinder.replaceName(
- valueExpressionText, loopVariableName, valueBody.offset);
- } else {
- loopVariableName = valueParameterName;
- }
- } else {
- // The names are different and both are used. We need to find a name
- // that would not change the resolution of any other identifiers in
- // either the key or value expressions.
- loopVariableName = computeUnusedVariableName();
- keyExpressionText = keyFinder.replaceName(
- keyExpressionText, loopVariableName, keyBody.offset);
- valueExpressionText = valueFinder.replaceName(
- valueExpressionText, loopVariableName, valueBody.offset);
- }
- }
- //
- // Construct the edit.
- //
- var changeBuilder = _newDartChangeBuilder();
- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
- builder.addReplacement(range.node(creation), (DartEditBuilder builder) {
- builder.write('{ for (var ');
- builder.write(loopVariableName);
- builder.write(' in ');
- builder.write(utils.getNodeText(iterator));
- builder.write(') ');
- builder.write(keyExpressionText);
- builder.write(' : ');
- builder.write(valueExpressionText);
- builder.write(' }');
- });
- });
- return changeBuilder;
- }
-
- Future<ChangeBuilder> createBuilder_convertQuotes(bool fromDouble) async {
- if (node is SimpleStringLiteral) {
- SimpleStringLiteral literal = node;
- if (fromDouble ? !literal.isSingleQuoted : literal.isSingleQuoted) {
- var newQuote = literal.isMultiline
- ? (fromDouble ? "'''" : '"""')
- : (fromDouble ? "'" : '"');
- var quoteLength = literal.isMultiline ? 3 : 1;
- var lexeme = literal.literal.lexeme;
- if (!lexeme.contains(newQuote)) {
- var changeBuilder = _newDartChangeBuilder();
- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
- builder.addSimpleReplacement(
- SourceRange(
- literal.offset + (literal.isRaw ? 1 : 0), quoteLength),
- newQuote);
- builder.addSimpleReplacement(
- SourceRange(literal.end - quoteLength, quoteLength), newQuote);
- });
- return changeBuilder;
- }
- }
- } else if (node is InterpolationString) {
- StringInterpolation parent = node.parent;
- if (fromDouble ? !parent.isSingleQuoted : parent.isSingleQuoted) {
- var newQuote = parent.isMultiline
- ? (fromDouble ? "'''" : '"""')
- : (fromDouble ? "'" : '"');
- var quoteLength = parent.isMultiline ? 3 : 1;
- var elements = parent.elements;
- for (var i = 0; i < elements.length; i++) {
- var element = elements[i];
- if (element is InterpolationString) {
- var lexeme = element.contents.lexeme;
- if (lexeme.contains(newQuote)) {
- return null;
- }
- }
- }
- var changeBuilder = _newDartChangeBuilder();
- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
- builder.addSimpleReplacement(
- SourceRange(parent.offset + (parent.isRaw ? 1 : 0), quoteLength),
- newQuote);
- builder.addSimpleReplacement(
- SourceRange(parent.end - quoteLength, quoteLength), newQuote);
- });
- return changeBuilder;
- }
- }
- return null;
- }
-
- Future<ChangeBuilder> createBuilder_convertToExpressionFunctionBody() async {
- // prepare current body
- var body = getEnclosingFunctionBody();
- if (body is! BlockFunctionBody || body.isGenerator) {
- _coverageMarker();
- return null;
- }
- // prepare return statement
- List<Statement> statements = (body as BlockFunctionBody).block.statements;
- if (statements.length != 1) {
- _coverageMarker();
- return null;
- }
- var onlyStatement = statements.first;
- // prepare returned expression
- Expression returnExpression;
- if (onlyStatement is ReturnStatement) {
- returnExpression = onlyStatement.expression;
- } else if (onlyStatement is ExpressionStatement) {
- returnExpression = onlyStatement.expression;
- }
- if (returnExpression == null) {
- _coverageMarker();
- return null;
- }
-
- // Return expressions can be quite large, e.g. Flutter build() methods.
- // It is surprising to see this Quick Assist deep in the function body.
- if (selectionOffset >= returnExpression.offset) {
- _coverageMarker();
- return null;
- }
-
- var changeBuilder = _newDartChangeBuilder();
- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
- builder.addReplacement(range.node(body), (DartEditBuilder builder) {
- if (body.isAsynchronous) {
- builder.write('async ');
- }
- builder.write('=> ');
- builder.write(_getNodeText(returnExpression));
- if (body.parent is! FunctionExpression ||
- body.parent.parent is FunctionDeclaration) {
- builder.write(';');
- }
- });
- });
- return changeBuilder;
- }
-
- Future<ChangeBuilder> createBuilder_convertToGenericFunctionSyntax() async {
- var node = this.node;
- while (node != null) {
- if (node is FunctionTypeAlias) {
- return _createBuilder_convertFunctionTypeAliasToGenericTypeAlias(node);
- } else if (node is FunctionTypedFormalParameter) {
- return _createBuilder_convertFunctionTypedFormalParameterToGenericTypeAlias(
- node);
- } else if (node is FormalParameterList) {
- // It would be confusing for this assist to alter a surrounding context
- // when the selection is inside a parameter list.
- return null;
- }
- node = node.parent;
- }
- return null;
- }
-
- Future<ChangeBuilder> createBuilder_convertToIntLiteral() async {
- if (node is! DoubleLiteral) {
- _coverageMarker();
- return null;
- }
- DoubleLiteral literal = node;
- int intValue;
- try {
- intValue = literal.value?.truncate();
- } catch (e) {
- // Double cannot be converted to int
- }
- if (intValue == null || intValue != literal.value) {
- _coverageMarker();
- return null;
- }
-
- var changeBuilder = _newDartChangeBuilder();
- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
- builder.addReplacement(SourceRange(literal.offset, literal.length),
- (DartEditBuilder builder) {
- builder.write('$intValue');
- });
- });
- return changeBuilder;
- }
-
- Future<ChangeBuilder> createBuilder_convertToPackageImport() async {
- var node = this.node;
- if (node is StringLiteral) {
- node = node.parent;
- }
- if (node is ImportDirective) {
- var importDirective = node;
- var uriSource = importDirective.uriSource;
-
- // Ignore if invalid URI.
- if (uriSource == null) {
- return null;
- }
-
- var importUri = uriSource.uri;
- if (importUri.scheme != 'package') {
- return null;
- }
-
- // Don't offer to convert a 'package:' URI to itself.
- try {
- if (Uri.parse(importDirective.uriContent).scheme == 'package') {
- return null;
- }
- } on FormatException {
- return null;
- }
-
- var changeBuilder = _newDartChangeBuilder();
- await changeBuilder.addFileEdit(file, (builder) {
- builder.addSimpleReplacement(
- range.node(importDirective.uri),
- "'$importUri'",
- );
- });
- return changeBuilder;
- }
- return null;
- }
-
- Future<ChangeBuilder> createBuilder_convertToRelativeImport() async {
- var node = this.node;
- if (node is StringLiteral) {
- node = node.parent;
- }
- if (node is! ImportDirective) {
- return null;
- }
-
- ImportDirective importDirective = node;
-
- // Ignore if invalid URI.
- if (importDirective.uriSource == null) {
- return null;
- }
-
- // Ignore if the uri is not a package: uri.
- var sourceUri = resolvedResult.uri;
- if (sourceUri.scheme != 'package') {
- return null;
- }
-
- Uri importUri;
- try {
- importUri = Uri.parse(importDirective.uriContent);
- } on FormatException {
- return null;
- }
-
- // Ignore if import uri is not a package: uri.
- if (importUri.scheme != 'package') {
- return null;
- }
-
- // Verify that the source's uri and the import uri have the same package
- // name.
- var sourceSegments = sourceUri.pathSegments;
- var importSegments = importUri.pathSegments;
- if (sourceSegments.isEmpty ||
- importSegments.isEmpty ||
- sourceSegments.first != importSegments.first) {
- return null;
- }
-
- // We only write posix style paths in import directives.
- var relativePath = path.posix.relative(
- importUri.path,
- from: path.dirname(sourceUri.path),
- );
-
- var changeBuilder = _newDartChangeBuilder();
- await changeBuilder.addFileEdit(file, (builder) {
- builder.addSimpleReplacement(
- range.node(importDirective.uri).getExpanded(-1),
- relativePath,
- );
- });
- return changeBuilder;
- }
-
- Future<ChangeBuilder> createBuilder_inlineAdd() async {
- var node = this.node;
- if (node is! SimpleIdentifier || node.parent is! MethodInvocation) {
- _coverageMarker();
- return null;
- }
- SimpleIdentifier name = node;
- MethodInvocation invocation = node.parent;
- if (name != invocation.methodName ||
- name.name != 'add' ||
- !invocation.isCascaded ||
- invocation.argumentList.arguments.length != 1) {
- _coverageMarker();
- return null;
- }
- var cascade = invocation.thisOrAncestorOfType<CascadeExpression>();
- var sections = cascade.cascadeSections;
- var target = cascade.target;
- if (target is! ListLiteral || sections[0] != invocation) {
- // TODO(brianwilkerson) Consider extending this to handle set literals.
- _coverageMarker();
- return null;
- }
- ListLiteral list = target;
- var argument = invocation.argumentList.arguments[0];
- var elementText = utils.getNodeText(argument);
-
- var changeBuilder = _newDartChangeBuilder();
- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
- if (list.elements.isNotEmpty) {
- // ['a']..add(e);
- builder.addSimpleInsertion(list.elements.last.end, ', $elementText');
- } else {
- // []..add(e);
- builder.addSimpleInsertion(list.leftBracket.end, elementText);
- }
- builder.addDeletion(range.node(invocation));
- });
- return changeBuilder;
- }
-
- /// todo (pq): unify with similar behavior in fix.
- Future<ChangeBuilder> createBuilder_removeTypeAnnotation() async {
- var declarationList = node.thisOrAncestorOfType<VariableDeclarationList>();
- if (declarationList == null) {
- var declaration = node.thisOrAncestorOfType<DeclaredIdentifier>();
- if (declaration == null) {
- _coverageMarker();
- return null;
- }
- var typeNode = declaration.type;
- if (typeNode == null) {
- _coverageMarker();
- return null;
- }
- var keyword = declaration.keyword;
- var variableName = declaration.identifier;
- var changeBuilder = _newDartChangeBuilder();
- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
- var typeRange = range.startStart(typeNode, variableName);
- if (keyword != null && keyword.lexeme != 'var') {
- builder.addSimpleReplacement(typeRange, '');
- } else {
- builder.addSimpleReplacement(typeRange, 'var ');
- }
- });
- return changeBuilder;
- }
- // we need a type
- var typeNode = declarationList.type;
- if (typeNode == null) {
- _coverageMarker();
- return null;
- }
- // ignore if an incomplete variable declaration
- if (declarationList.variables.length == 1 &&
- declarationList.variables[0].name.isSynthetic) {
- _coverageMarker();
- return null;
- }
- // must be not after the name of the variable
- var firstVariable = declarationList.variables[0];
- if (selectionOffset > firstVariable.name.end) {
- _coverageMarker();
- return null;
- }
- // The variable must have an initializer, otherwise there is no other
- // source for its type.
- if (firstVariable.initializer == null) {
- _coverageMarker();
- return null;
- }
- var keyword = declarationList.keyword;
- var changeBuilder = _newDartChangeBuilder();
- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
- var typeRange = range.startStart(typeNode, firstVariable);
- if (keyword != null && keyword.lexeme != 'var') {
- builder.addSimpleReplacement(typeRange, '');
- } else {
- builder.addSimpleReplacement(typeRange, 'var ');
- }
- });
- return changeBuilder;
- }
-
- Future<ChangeBuilder> createBuilder_replaceWithVar() async {
- var type = node.thisOrAncestorOfType<TypeAnnotation>();
- if (type == null) {
- return null;
- }
- var parent = type.parent;
- var grandparent = parent?.parent;
- if (parent is VariableDeclarationList &&
- (grandparent is VariableDeclarationStatement ||
- grandparent is ForPartsWithDeclarations)) {
- var variables = parent.variables;
- if (variables.length != 1) {
- return null;
- }
- var initializer = variables[0].initializer;
- String typeArgumentsText;
- int typeArgumentsOffset;
- if (type is NamedType && type.typeArguments != null) {
- if (initializer is TypedLiteral) {
- if (initializer.typeArguments == null) {
- typeArgumentsText = utils.getNodeText(type.typeArguments);
- typeArgumentsOffset = initializer.offset;
- }
- } else if (initializer is InstanceCreationExpression) {
- if (initializer.constructorName.type.typeArguments == null) {
- typeArgumentsText = utils.getNodeText(type.typeArguments);
- typeArgumentsOffset = initializer.constructorName.type.end;
- }
- }
- }
- if (initializer is SetOrMapLiteral &&
- initializer.typeArguments == null &&
- typeArgumentsText == null) {
- // TODO(brianwilkerson) This is to prevent the fix from converting a
- // valid map or set literal into an ambiguous literal. We could apply
- // this in more places by examining the elements of the collection.
- return null;
- }
- var changeBuilder = _newDartChangeBuilder();
- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
- builder.addSimpleReplacement(range.node(type), 'var');
- if (typeArgumentsText != null) {
- builder.addSimpleInsertion(typeArgumentsOffset, typeArgumentsText);
- }
- });
- return changeBuilder;
- } else if (parent is DeclaredIdentifier &&
- grandparent is ForEachPartsWithDeclaration) {
- String typeArgumentsText;
- int typeArgumentsOffset;
- if (type is NamedType && type.typeArguments != null) {
- var iterable = grandparent.iterable;
- if (iterable is TypedLiteral && iterable.typeArguments == null) {
- typeArgumentsText = utils.getNodeText(type.typeArguments);
- typeArgumentsOffset = iterable.offset;
- }
- }
- var changeBuilder = _newDartChangeBuilder();
- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
- builder.addSimpleReplacement(range.node(type), 'var');
- if (typeArgumentsText != null) {
- builder.addSimpleInsertion(typeArgumentsOffset, typeArgumentsText);
- }
- });
- return changeBuilder;
- }
- return null;
- }
-
- Future<ChangeBuilder> createBuilder_sortChildPropertyLast() async {
- var childProp = flutter.findNamedExpression(node, 'child');
- childProp ??= flutter.findNamedExpression(node, 'children');
- if (childProp == null) {
- return null;
- }
-
- var parent = childProp.parent?.parent;
- if (parent is! InstanceCreationExpression ||
- !flutter.isWidgetCreation(parent)) {
- return null;
- }
-
- InstanceCreationExpression creationExpression = parent;
- var args = creationExpression.argumentList;
-
- var last = args.arguments.last;
- if (last == childProp) {
- // Already sorted.
- return null;
- }
-
- var changeBuilder = _newDartChangeBuilder();
- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
- var start = childProp.beginToken.previous.end;
- var end = childProp.endToken.next.end;
- var childRange = range.startOffsetEndOffset(start, end);
-
- var childText = utils.getRangeText(childRange);
- builder.addSimpleReplacement(childRange, '');
- builder.addSimpleInsertion(last.end + 1, childText);
-
- changeBuilder.setSelection(Position(file, last.end + 1));
- });
-
- return changeBuilder;
- }
-
- @protected
- Future<ChangeBuilder> createBuilder_useCurlyBraces() async {
- Future<ChangeBuilder> doStatement(DoStatement node) async {
- var body = node.body;
- if (body is Block) return null;
-
- var prefix = utils.getLinePrefix(node.offset);
- var indent = prefix + utils.getIndent(1);
-
- var changeBuilder = _newDartChangeBuilder();
- await changeBuilder.addFileEdit(file, (builder) {
- builder.addSimpleReplacement(
- range.endStart(node.doKeyword, body),
- ' {$eol$indent',
- );
- builder.addSimpleReplacement(
- range.endStart(body, node.whileKeyword),
- '$eol$prefix} ',
- );
- });
- return changeBuilder;
- }
-
- Future<ChangeBuilder> forStatement(ForStatement node) async {
- var body = node.body;
- if (body is Block) return null;
-
- var prefix = utils.getLinePrefix(node.offset);
- var indent = prefix + utils.getIndent(1);
-
- var changeBuilder = _newDartChangeBuilder();
- await changeBuilder.addFileEdit(file, (builder) {
- builder.addSimpleReplacement(
- range.endStart(node.rightParenthesis, body),
- ' {$eol$indent',
- );
- builder.addSimpleInsertion(body.end, '$eol$prefix}');
- });
-
- return changeBuilder;
- }
-
- Future<ChangeBuilder> ifStatement(
- IfStatement node, Statement thenOrElse) async {
- var prefix = utils.getLinePrefix(node.offset);
- var indent = prefix + utils.getIndent(1);
-
- var changeBuilder = _newDartChangeBuilder();
- await changeBuilder.addFileEdit(file, (builder) {
- var thenStatement = node.thenStatement;
- if (thenStatement is! Block &&
- (thenOrElse == null || thenOrElse == thenStatement)) {
- builder.addSimpleReplacement(
- range.endStart(node.rightParenthesis, thenStatement),
- ' {$eol$indent',
- );
- if (node.elseKeyword != null) {
- builder.addSimpleReplacement(
- range.endStart(thenStatement, node.elseKeyword),
- '$eol$prefix} ',
- );
- } else {
- builder.addSimpleInsertion(thenStatement.end, '$eol$prefix}');
- }
- }
-
- var elseStatement = node.elseStatement;
- if (elseStatement != null &&
- elseStatement is! Block &&
- (thenOrElse == null || thenOrElse == elseStatement)) {
- builder.addSimpleReplacement(
- range.endStart(node.elseKeyword, elseStatement),
- ' {$eol$indent',
- );
- builder.addSimpleInsertion(elseStatement.end, '$eol$prefix}');
- }
- });
-
- return changeBuilder;
- }
-
- Future<ChangeBuilder> whileStatement(WhileStatement node) async {
- var body = node.body;
- if (body is Block) return null;
-
- var prefix = utils.getLinePrefix(node.offset);
- var indent = prefix + utils.getIndent(1);
-
- var changeBuilder = _newDartChangeBuilder();
- await changeBuilder.addFileEdit(file, (builder) {
- builder.addSimpleReplacement(
- range.endStart(node.rightParenthesis, body),
- ' {$eol$indent',
- );
- builder.addSimpleInsertion(body.end, '$eol$prefix}');
- });
- return changeBuilder;
- }
-
- var statement = node.thisOrAncestorOfType<Statement>();
- var parent = statement?.parent;
-
- if (statement is DoStatement) {
- return doStatement(statement);
- } else if (parent is DoStatement) {
- return doStatement(parent);
- } else if (statement is ForStatement) {
- return forStatement(statement);
- } else if (parent is ForStatement) {
- return forStatement(parent);
- } else if (statement is IfStatement) {
- if (statement.elseKeyword != null &&
- range.token(statement.elseKeyword).contains(selectionOffset)) {
- return ifStatement(statement, statement.elseStatement);
- } else {
- return ifStatement(statement, null);
- }
- } else if (parent is IfStatement) {
- return ifStatement(parent, statement);
- } else if (statement is WhileStatement) {
- return whileStatement(statement);
- } else if (parent is WhileStatement) {
- return whileStatement(parent);
- }
- return null;
- }
-
- FunctionBody getEnclosingFunctionBody() {
- // TODO(brianwilkerson) Determine whether there is a reason why this method
- // isn't just "return node.getAncestor((node) => node is FunctionBody);"
- {
- var function = node.thisOrAncestorOfType<FunctionExpression>();
- if (function != null) {
- return function.body;
- }
- }
- {
- var function = node.thisOrAncestorOfType<FunctionDeclaration>();
- if (function != null) {
- return function.functionExpression.body;
- }
- }
- {
- var constructor = node.thisOrAncestorOfType<ConstructorDeclaration>();
- if (constructor != null) {
- return constructor.body;
- }
- }
- {
- var method = node.thisOrAncestorOfType<MethodDeclaration>();
- if (method != null) {
- return method.body;
- }
- }
- return null;
- }
-
- bool isEnum(DartType type) {
- final element = type.element;
- return element is ClassElement && element.isEnum;
- }
-
- bool isIterable(DartType type) {
- if (type is! InterfaceType) {
- return false;
- }
-
- ClassElement element = type.element;
-
- bool isExactIterable(ClassElement element) {
- return element?.name == 'Iterable' && element.library.isDartCore;
- }
-
- if (isExactIterable(element)) {
- return true;
- }
- for (var type in element.allSupertypes) {
- if (isExactIterable(type.element)) {
- return true;
- }
- }
- return false;
- }
-
@protected
bool setupCompute() {
final locator = NodeLocator(selectionOffset, selectionEnd);
node = locator.searchWithin(resolvedResult.unit);
return node != null;
}
-
- /// Return `true` if all of the parameters in the given list of [parameters]
- /// have an explicit type annotation.
- bool _allParametersHaveTypes(FormalParameterList parameters) {
- for (var parameter in parameters.parameters) {
- if (parameter is DefaultFormalParameter) {
- parameter = (parameter as DefaultFormalParameter).parameter;
- }
- if (parameter is SimpleFormalParameter) {
- if (parameter.type == null) {
- return false;
- }
- } else if (parameter is! FunctionTypedFormalParameter) {
- return false;
- }
- }
- return true;
- }
-
- /// Configures [utils] using given [target].
- void _configureTargetLocation(Object target) {
- utils.targetClassElement = null;
- if (target is AstNode) {
- var targetClassDeclaration =
- target.thisOrAncestorOfType<ClassDeclaration>();
- if (targetClassDeclaration != null) {
- utils.targetClassElement = targetClassDeclaration.declaredElement;
- }
- }
- }
-
- Future<ChangeBuilder>
- _createBuilder_convertFunctionTypeAliasToGenericTypeAlias(
- FunctionTypeAlias node) async {
- if (!_allParametersHaveTypes(node.parameters)) {
- return null;
- }
- String returnType;
- if (node.returnType != null) {
- returnType = utils.getNodeText(node.returnType);
- }
- var functionName = utils.getRangeText(
- range.startEnd(node.name, node.typeParameters ?? node.name));
- var parameters = utils.getNodeText(node.parameters);
- String replacement;
- if (returnType == null) {
- replacement = '$functionName = Function$parameters';
- } else {
- replacement = '$functionName = $returnType Function$parameters';
- }
- // add change
- var changeBuilder = _newDartChangeBuilder();
- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
- builder.addSimpleReplacement(
- range.startStart(node.typedefKeyword.next, node.semicolon),
- replacement);
- });
- return changeBuilder;
- }
-
- Future<ChangeBuilder>
- _createBuilder_convertFunctionTypedFormalParameterToGenericTypeAlias(
- FunctionTypedFormalParameter node) async {
- if (!_allParametersHaveTypes(node.parameters)) {
- return null;
- }
- String returnType;
- if (node.returnType != null) {
- returnType = utils.getNodeText(node.returnType);
- }
- var functionName = utils.getRangeText(range.startEnd(
- node.identifier, node.typeParameters ?? node.identifier));
- var parameters = utils.getNodeText(node.parameters);
- String replacement;
- if (returnType == null) {
- replacement = 'Function$parameters $functionName';
- } else {
- replacement = '$returnType Function$parameters $functionName';
- }
- // add change
- var changeBuilder = _newDartChangeBuilder();
- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
- builder.addSimpleReplacement(range.node(node), replacement);
- });
- return changeBuilder;
- }
-
- /// Returns the text of the given node in the unit.
- String /* TODO (pq): make visible */ _getNodeText(AstNode node) =>
- utils.getNodeText(node);
-
- DartChangeBuilder _newDartChangeBuilder() =>
- DartChangeBuilderImpl.forWorkspace(workspace);
-
- /// This method does nothing, but we invoke it in places where Dart VM
- /// coverage agent fails to provide coverage information - such as almost
- /// all "return" statements.
- ///
- /// https://code.google.com/p/dart/issues/detail?id=19912
- static void _coverageMarker() {}
-}
-
-class ConvertToSpreadCollectionsChange {
- ChangeBuilder builder;
- List<String> args;
- bool isLineInvocation = false;
-}
-
-/// A visitor that can be used to find references to a parameter.
-class _ParameterReferenceFinder extends RecursiveAstVisitor<void> {
- /// The parameter for which references are being sought, or `null` if we are
- /// just accumulating a list of referenced names.
- final ParameterElement parameter;
-
- /// A list of the simple identifiers that reference the [parameter].
- final List<SimpleIdentifier> references = <SimpleIdentifier>[];
-
- /// A collection of the names of other simple identifiers that were found. We
- /// need to know these in order to ensure that the selected loop variable does
- /// not hide a name from an enclosing scope that is already being referenced.
- final Set<String> otherNames = <String>{};
-
- /// Initialize a newly created finder to find references to the [parameter].
- _ParameterReferenceFinder(this.parameter) : assert(parameter != null);
-
- /// Return `true` if the parameter is unreferenced in the nodes that have been
- /// visited.
- bool get isParameterUnreferenced => references.isEmpty;
-
- /// Return `true` is the given name (assumed to be different than the name of
- /// the parameter) is references in the nodes that have been visited.
- bool referencesName(String name) => otherNames.contains(name);
-
- /// Replace all of the references to the parameter in the given [source] with
- /// the [newName]. The [offset] is the offset of the first character of the
- /// [source] relative to the start of the file.
- String replaceName(String source, String newName, int offset) {
- var oldLength = parameter.name.length;
- for (var i = references.length - 1; i >= 0; i--) {
- var oldOffset = references[i].offset - offset;
- source = source.replaceRange(oldOffset, oldOffset + oldLength, newName);
- }
- return source;
- }
-
- @override
- void visitSimpleIdentifier(SimpleIdentifier node) {
- if (node.staticElement == parameter) {
- references.add(node);
- } else if (!node.isQualified) {
- // Only non-prefixed identifiers can be hidden.
- otherNames.add(node.name);
- }
- }
}
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/abstract_producer.dart b/pkg/analysis_server/lib/src/services/correction/dart/abstract_producer.dart
index 9f7282e..e624242 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/abstract_producer.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/abstract_producer.dart
@@ -65,6 +65,28 @@
_context = context;
}
+ /// Return the function body of the most deeply nested method or function that
+ /// encloses the [node], or `null` if the node is not in a method or function.
+ FunctionBody getEnclosingFunctionBody() {
+ var closure = node.thisOrAncestorOfType<FunctionExpression>();
+ if (closure != null) {
+ return closure.body;
+ }
+ var function = node.thisOrAncestorOfType<FunctionDeclaration>();
+ if (function != null) {
+ return function.functionExpression.body;
+ }
+ var constructor = node.thisOrAncestorOfType<ConstructorDeclaration>();
+ if (constructor != null) {
+ return constructor.body;
+ }
+ var method = node.thisOrAncestorOfType<MethodDeclaration>();
+ if (method != null) {
+ return method.body;
+ }
+ return null;
+ }
+
/// Return the text of the given [range] in the unit.
String getRangeText(SourceRange range) {
return utils.getRangeText(range);
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/add_diagnostic_property_reference.dart b/pkg/analysis_server/lib/src/services/correction/dart/add_diagnostic_property_reference.dart
new file mode 100644
index 0000000..292bee5
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/correction/dart/add_diagnostic_property_reference.dart
@@ -0,0 +1,211 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analysis_server/src/services/correction/assist.dart';
+import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
+import 'package:analysis_server/src/services/correction/fix.dart';
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer_plugin/utilities/assist/assist.dart';
+import 'package:analyzer_plugin/utilities/change_builder/change_builder_dart.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:meta/meta.dart';
+
+class AddDiagnosticPropertyReference extends CorrectionProducer {
+ @override
+ AssistKind get assistKind => DartAssistKind.ADD_DIAGNOSTIC_PROPERTY_REFERENCE;
+
+ @override
+ FixKind get fixKind => DartFixKind.ADD_DIAGNOSTIC_PROPERTY_REFERENCE;
+
+ @override
+ Future<void> compute(DartChangeBuilder builder) async {
+ final node = this.node;
+ if (node is! SimpleIdentifier) {
+ return;
+ }
+ SimpleIdentifier name = node;
+ final parent = node.parent;
+
+ var type = _getReturnType(parent);
+ if (type == null) {
+ return;
+ }
+
+ var constructorId;
+ var typeArgs;
+ var constructorName = '';
+
+ if (type.element is FunctionTypedElement) {
+ constructorId = 'ObjectFlagProperty';
+ typeArgs = [type];
+ constructorName = '.has';
+ } else if (type.isDartCoreInt) {
+ constructorId = 'IntProperty';
+ } else if (type.isDartCoreDouble) {
+ constructorId = 'DoubleProperty';
+ } else if (type.isDartCoreString) {
+ constructorId = 'StringProperty';
+ } else if (_isEnum(type)) {
+ constructorId = 'EnumProperty';
+ typeArgs = [type];
+ } else if (_isIterable(type)) {
+ constructorId = 'IterableProperty';
+ typeArgs = (type as InterfaceType).typeArguments;
+ } else if (flutter.isColor(type)) {
+ constructorId = 'ColorProperty';
+ } else if (flutter.isMatrix4(type)) {
+ constructorId = 'TransformProperty';
+ } else {
+ constructorId = 'DiagnosticsProperty';
+ if (!type.isDynamic) {
+ typeArgs = [type];
+ }
+ }
+
+ void writePropertyReference(
+ DartEditBuilder builder, {
+ @required String prefix,
+ @required String builderName,
+ }) {
+ builder.write('$prefix$builderName.add($constructorId');
+ if (typeArgs != null) {
+ builder.write('<');
+ builder.writeTypes(typeArgs);
+ builder.write('>');
+ } else if (type.isDynamic) {
+ TypeAnnotation declType;
+ final decl = node.thisOrAncestorOfType<VariableDeclarationList>();
+ if (decl != null) {
+ declType = decl.type;
+ // getter
+ } else if (parent is MethodDeclaration) {
+ declType = parent.returnType;
+ }
+
+ if (declType != null) {
+ final typeText = utils.getNodeText(declType);
+ if (typeText != 'dynamic') {
+ builder.write('<');
+ builder.write(utils.getNodeText(declType));
+ builder.write('>');
+ }
+ }
+ }
+ builder.writeln("$constructorName('${name.name}', ${name.name}));");
+ }
+
+ final classDeclaration = parent.thisOrAncestorOfType<ClassDeclaration>();
+ final debugFillProperties =
+ classDeclaration.getMethod('debugFillProperties');
+ if (debugFillProperties == null) {
+ final insertOffset =
+ utils.prepareNewMethodLocation(classDeclaration).offset;
+ await builder.addFileEdit(file, (DartFileEditBuilder builder) {
+ builder.addInsertion(utils.getLineNext(insertOffset),
+ (DartEditBuilder builder) {
+ final declPrefix =
+ utils.getLinePrefix(classDeclaration.offset) + utils.getIndent(1);
+ final bodyPrefix = declPrefix + utils.getIndent(1);
+
+ builder.writeln('$declPrefix@override');
+ builder.writeln(
+ '${declPrefix}void debugFillProperties(DiagnosticPropertiesBuilder properties) {');
+ builder
+ .writeln('${bodyPrefix}super.debugFillProperties(properties);');
+ writePropertyReference(builder,
+ prefix: bodyPrefix, builderName: 'properties');
+ builder.writeln('$declPrefix}');
+ });
+ });
+ return;
+ }
+
+ final body = debugFillProperties.body;
+ if (body is BlockFunctionBody) {
+ var functionBody = body;
+
+ var offset;
+ var prefix;
+ if (functionBody.block.statements.isEmpty) {
+ offset = functionBody.block.leftBracket.offset;
+ prefix = utils.getLinePrefix(offset) + utils.getIndent(1);
+ } else {
+ offset = functionBody.block.statements.last.endToken.offset;
+ prefix = utils.getLinePrefix(offset);
+ }
+
+ var parameters = debugFillProperties.parameters.parameters;
+ var propertiesBuilderName;
+ for (var parameter in parameters) {
+ if (parameter is SimpleFormalParameter) {
+ final type = parameter.type;
+ if (type is TypeName) {
+ if (type.name.name == 'DiagnosticPropertiesBuilder') {
+ propertiesBuilderName = parameter.identifier.name;
+ break;
+ }
+ }
+ }
+ }
+ if (propertiesBuilderName == null) {
+ return null;
+ }
+
+ await builder.addFileEdit(file, (DartFileEditBuilder builder) {
+ builder.addInsertion(utils.getLineNext(offset),
+ (DartEditBuilder builder) {
+ writePropertyReference(builder,
+ prefix: prefix, builderName: propertiesBuilderName);
+ });
+ });
+ }
+ }
+
+ /// Return the return type of the given [node].
+ DartType _getReturnType(AstNode node) {
+ if (node is MethodDeclaration) {
+ // Getter.
+ var element = node.declaredElement;
+ if (element is PropertyAccessorElement) {
+ return element.returnType;
+ }
+ } else if (node is VariableDeclaration) {
+ // Field.
+ var element = node.declaredElement;
+ if (element is FieldElement) {
+ return element.type;
+ }
+ }
+ return null;
+ }
+
+ bool _isEnum(DartType type) {
+ final element = type.element;
+ return element is ClassElement && element.isEnum;
+ }
+
+ bool _isIterable(DartType type) {
+ if (type is! InterfaceType) {
+ return false;
+ }
+
+ ClassElement element = type.element;
+
+ bool isExactIterable(ClassElement element) {
+ return element?.name == 'Iterable' && element.library.isDartCore;
+ }
+
+ if (isExactIterable(element)) {
+ return true;
+ }
+ for (var type in element.allSupertypes) {
+ if (isExactIterable(type.element)) {
+ return true;
+ }
+ }
+ return false;
+ }
+}
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/add_type_annotation.dart b/pkg/analysis_server/lib/src/services/correction/dart/add_type_annotation.dart
new file mode 100644
index 0000000..b8a8824
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/correction/dart/add_type_annotation.dart
@@ -0,0 +1,198 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:_fe_analyzer_shared/src/scanner/token.dart';
+import 'package:analysis_server/src/services/correction/assist.dart';
+import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
+import 'package:analysis_server/src/services/correction/fix.dart';
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer_plugin/src/utilities/change_builder/change_builder_dart.dart';
+import 'package:analyzer_plugin/utilities/assist/assist.dart';
+import 'package:analyzer_plugin/utilities/change_builder/change_builder_dart.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:analyzer_plugin/utilities/range_factory.dart';
+
+class AddTypeAnnotation extends CorrectionProducer {
+ @override
+ AssistKind get assistKind => DartAssistKind.ADD_TYPE_ANNOTATION;
+
+ @override
+ FixKind get fixKind => DartFixKind.ADD_TYPE_ANNOTATION;
+
+ @override
+ Future<void> compute(DartChangeBuilder builder) async {
+ var node = this.node;
+ if (node is SimpleIdentifier) {
+ var parent = node.parent;
+ if (parent is SimpleFormalParameter) {
+ await _forSimpleFormalParameter(builder, node, parent);
+ return;
+ }
+ }
+ while (node != null) {
+ if (node is VariableDeclarationList) {
+ await _forVariableDeclaration(builder, node);
+ return;
+ } else if (node is DeclaredIdentifier) {
+ await _forDeclaredIdentifier(builder, node);
+ return;
+ } else if (node is ForStatement) {
+ var forLoopParts = node.forLoopParts;
+ if (forLoopParts is ForEachParts) {
+ var offset = this.node.offset;
+ if (forLoopParts.iterable != null &&
+ offset < forLoopParts.iterable.offset) {
+ if (forLoopParts is ForEachPartsWithDeclaration) {
+ await _forDeclaredIdentifier(builder, forLoopParts.loopVariable);
+ }
+ }
+ }
+ return;
+ }
+ node = node.parent;
+ }
+ }
+
+ /// Configure the [utils] using the given [target].
+ void _configureTargetLocation(Object target) {
+ utils.targetClassElement = null;
+ if (target is AstNode) {
+ var targetClassDeclaration =
+ target.thisOrAncestorOfType<ClassDeclaration>();
+ if (targetClassDeclaration != null) {
+ utils.targetClassElement = targetClassDeclaration.declaredElement;
+ }
+ }
+ }
+
+ Future<void> _forDeclaredIdentifier(
+ DartChangeBuilder builder, DeclaredIdentifier declaredIdentifier) async {
+ // Ensure that there isn't already a type annotation.
+ if (declaredIdentifier.type != null) {
+ return;
+ }
+ var type = declaredIdentifier.declaredElement.type;
+ if (type is! InterfaceType && type is! FunctionType) {
+ return;
+ }
+ _configureTargetLocation(node);
+
+ Future<bool> applyChange(DartChangeBuilder builder) async {
+ var validChange = true;
+ await builder.addFileEdit(file, (DartFileEditBuilder builder) {
+ var keyword = declaredIdentifier.keyword;
+ if (keyword.keyword == Keyword.VAR) {
+ builder.addReplacement(range.token(keyword),
+ (DartEditBuilder builder) {
+ validChange = builder.writeType(type);
+ });
+ } else {
+ builder.addInsertion(declaredIdentifier.identifier.offset,
+ (DartEditBuilder builder) {
+ validChange = builder.writeType(type);
+ builder.write(' ');
+ });
+ }
+ });
+ return validChange;
+ }
+
+ if (await applyChange(_temporaryBuilder(builder))) {
+ await applyChange(builder);
+ }
+ }
+
+ Future<void> _forSimpleFormalParameter(DartChangeBuilder builder,
+ SimpleIdentifier name, SimpleFormalParameter parameter) async {
+ // Ensure that there isn't already a type annotation.
+ if (parameter.type != null) {
+ return;
+ }
+ // Prepare the type.
+ var type = parameter.declaredElement.type;
+ // TODO(scheglov) If the parameter is in a method declaration, and if the
+ // method overrides a method that has a type for the corresponding
+ // parameter, it would be nice to copy down the type from the overridden
+ // method.
+ if (type is! InterfaceType) {
+ return;
+ }
+ _configureTargetLocation(node);
+
+ Future<bool> applyChange(DartChangeBuilder builder) async {
+ var validChange = true;
+ await builder.addFileEdit(file, (DartFileEditBuilder builder) {
+ builder.addInsertion(name.offset, (DartEditBuilder builder) {
+ validChange = builder.writeType(type);
+ if (validChange) {
+ builder.write(' ');
+ }
+ });
+ });
+ return validChange;
+ }
+
+ if (await applyChange(_temporaryBuilder(builder))) {
+ await applyChange(builder);
+ }
+ }
+
+ Future<void> _forVariableDeclaration(DartChangeBuilder builder,
+ VariableDeclarationList declarationList) async {
+ // Ensure that there isn't already a type annotation.
+ if (declarationList.type != null) {
+ return;
+ }
+ // Ensure that there is a single VariableDeclaration.
+ List<VariableDeclaration> variables = declarationList.variables;
+ if (variables.length != 1) {
+ return;
+ }
+ var variable = variables[0];
+ // Ensure that the selection is not after the name of the variable.
+ if (selectionOffset > variable.name.end) {
+ return;
+ }
+ // Ensure that there is an initializer to get the type from.
+ var initializer = variable.initializer;
+ if (initializer == null) {
+ return;
+ }
+ var type = initializer.staticType;
+ // prepare type source
+ if ((type is! InterfaceType || type.isDartCoreNull) &&
+ type is! FunctionType) {
+ return;
+ }
+ _configureTargetLocation(node);
+
+ Future<bool> applyChange(DartChangeBuilder builder) async {
+ var validChange = true;
+ await builder.addFileEdit(file, (DartFileEditBuilder builder) {
+ var keyword = declarationList.keyword;
+ if (keyword?.keyword == Keyword.VAR) {
+ builder.addReplacement(range.token(keyword),
+ (DartEditBuilder builder) {
+ validChange = builder.writeType(type);
+ });
+ } else {
+ builder.addInsertion(variable.offset, (DartEditBuilder builder) {
+ validChange = builder.writeType(type);
+ builder.write(' ');
+ });
+ }
+ });
+ return validChange;
+ }
+
+ if (await applyChange(_temporaryBuilder(builder))) {
+ await applyChange(builder);
+ }
+ }
+
+ DartChangeBuilder _temporaryBuilder(DartChangeBuilder builder) =>
+ DartChangeBuilderImpl.forWorkspace(
+ (builder as DartChangeBuilderImpl).workspace);
+}
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/convert_add_all_to_spread.dart b/pkg/analysis_server/lib/src/services/correction/dart/convert_add_all_to_spread.dart
new file mode 100644
index 0000000..f1099b6
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/correction/dart/convert_add_all_to_spread.dart
@@ -0,0 +1,112 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:_fe_analyzer_shared/src/scanner/token.dart';
+import 'package:analysis_server/src/services/correction/assist.dart';
+import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
+import 'package:analysis_server/src/services/correction/fix.dart';
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer_plugin/utilities/assist/assist.dart';
+import 'package:analyzer_plugin/utilities/change_builder/change_builder_dart.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:analyzer_plugin/utilities/range_factory.dart';
+
+class ConvertAddAllToSpread extends CorrectionProducer {
+ /// The arguments used to compose the message.
+ List<String> args;
+
+ /// A flag indicating whether the change that was built is one that inlines
+ /// the elements of another list into the target list.
+ bool isInlineInvocation = false;
+
+ @override
+ List<Object> get assistArguments => args;
+
+ @override
+ AssistKind get assistKind => isInlineInvocation
+ ? DartAssistKind.INLINE_INVOCATION
+ : DartAssistKind.CONVERT_TO_SPREAD;
+
+ @override
+ List<Object> get fixArguments => args;
+
+ @override
+ FixKind get fixKind => isInlineInvocation
+ ? DartFixKind.INLINE_INVOCATION
+ : DartFixKind.CONVERT_TO_SPREAD;
+
+ @override
+ Future<void> compute(DartChangeBuilder builder) async {
+ var node = this.node;
+ if (node is! SimpleIdentifier || node.parent is! MethodInvocation) {
+ return;
+ }
+ SimpleIdentifier name = node;
+ MethodInvocation invocation = node.parent;
+ if (name != invocation.methodName ||
+ name.name != 'addAll' ||
+ !invocation.isCascaded ||
+ invocation.argumentList.arguments.length != 1) {
+ return;
+ }
+ var cascade = invocation.thisOrAncestorOfType<CascadeExpression>();
+ var sections = cascade.cascadeSections;
+ var target = cascade.target;
+ if (target is! ListLiteral || sections[0] != invocation) {
+ // TODO(brianwilkerson) Consider extending this to handle set literals.
+ return;
+ }
+
+ bool isEmptyListLiteral(Expression expression) =>
+ expression is ListLiteral && expression.elements.isEmpty;
+
+ ListLiteral list = target;
+ var argument = invocation.argumentList.arguments[0];
+ String elementText;
+ if (argument is BinaryExpression &&
+ argument.operator.type == TokenType.QUESTION_QUESTION) {
+ var right = argument.rightOperand;
+ if (isEmptyListLiteral(right)) {
+ // ..addAll(things ?? const [])
+ // ..addAll(things ?? [])
+ elementText = '...?${utils.getNodeText(argument.leftOperand)}';
+ }
+ } else if (argument is ConditionalExpression) {
+ var elseExpression = argument.elseExpression;
+ if (isEmptyListLiteral(elseExpression)) {
+ // ..addAll(condition ? things : const [])
+ // ..addAll(condition ? things : [])
+ var conditionText = utils.getNodeText(argument.condition);
+ var thenText = utils.getNodeText(argument.thenExpression);
+ elementText = 'if ($conditionText) ...$thenText';
+ }
+ } else if (argument is ListLiteral) {
+ // ..addAll([ ... ])
+ var elements = argument.elements;
+ if (elements.isEmpty) {
+ // TODO(brianwilkerson) Consider adding a cleanup for the empty list
+ // case. We can essentially remove the whole invocation because it does
+ // nothing.
+ return null;
+ }
+ var startOffset = elements.first.offset;
+ var endOffset = elements.last.end;
+ elementText = utils.getText(startOffset, endOffset - startOffset);
+ args = ['addAll'];
+ isInlineInvocation = true;
+ }
+ elementText ??= '...${utils.getNodeText(argument)}';
+
+ await builder.addFileEdit(file, (DartFileEditBuilder builder) {
+ if (list.elements.isNotEmpty) {
+ // ['a']..addAll(['b', 'c']);
+ builder.addSimpleInsertion(list.elements.last.end, ', $elementText');
+ } else {
+ // []..addAll(['b', 'c']);
+ builder.addSimpleInsertion(list.leftBracket.end, elementText);
+ }
+ builder.addDeletion(range.node(invocation));
+ });
+ }
+}
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/convert_conditional_expression_to_if_element.dart b/pkg/analysis_server/lib/src/services/correction/dart/convert_conditional_expression_to_if_element.dart
new file mode 100644
index 0000000..1a2e32f
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/correction/dart/convert_conditional_expression_to_if_element.dart
@@ -0,0 +1,52 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analysis_server/src/services/correction/assist.dart';
+import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
+import 'package:analysis_server/src/services/correction/fix.dart';
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer_plugin/utilities/assist/assist.dart';
+import 'package:analyzer_plugin/utilities/change_builder/change_builder_dart.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:analyzer_plugin/utilities/range_factory.dart';
+
+class ConvertConditionalExpressionToIfElement extends CorrectionProducer {
+ @override
+ AssistKind get assistKind => DartAssistKind.CONVERT_TO_IF_ELEMENT;
+
+ @override
+ FixKind get fixKind => DartFixKind.CONVERT_TO_IF_ELEMENT;
+
+ @override
+ Future<void> compute(DartChangeBuilder builder) async {
+ AstNode node = this.node.thisOrAncestorOfType<ConditionalExpression>();
+ if (node == null) {
+ return null;
+ }
+ var nodeToReplace = node;
+ var parent = node.parent;
+ while (parent is ParenthesizedExpression) {
+ nodeToReplace = parent;
+ parent = parent.parent;
+ }
+ if (parent is ListLiteral || (parent is SetOrMapLiteral && parent.isSet)) {
+ ConditionalExpression conditional = node;
+ var condition = conditional.condition.unParenthesized;
+ var thenExpression = conditional.thenExpression.unParenthesized;
+ var elseExpression = conditional.elseExpression.unParenthesized;
+
+ await builder.addFileEdit(file, (DartFileEditBuilder builder) {
+ builder.addReplacement(range.node(nodeToReplace),
+ (DartEditBuilder builder) {
+ builder.write('if (');
+ builder.write(utils.getNodeText(condition));
+ builder.write(') ');
+ builder.write(utils.getNodeText(thenExpression));
+ builder.write(' else ');
+ builder.write(utils.getNodeText(elseExpression));
+ });
+ });
+ }
+ }
+}
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/convert_documentation_into_line.dart b/pkg/analysis_server/lib/src/services/correction/dart/convert_documentation_into_line.dart
new file mode 100644
index 0000000..b87f9f6
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/correction/dart/convert_documentation_into_line.dart
@@ -0,0 +1,78 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:_fe_analyzer_shared/src/scanner/token.dart';
+import 'package:analysis_server/src/services/correction/assist.dart';
+import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
+import 'package:analysis_server/src/services/correction/fix.dart';
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer_plugin/utilities/assist/assist.dart';
+import 'package:analyzer_plugin/utilities/change_builder/change_builder_dart.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:analyzer_plugin/utilities/range_factory.dart';
+
+class ConvertDocumentationIntoLine extends CorrectionProducer {
+ @override
+ AssistKind get assistKind => DartAssistKind.CONVERT_DOCUMENTATION_INTO_LINE;
+
+ @override
+ FixKind get fixKind => DartFixKind.CONVERT_TO_LINE_COMMENT;
+
+ @override
+ Future<void> compute(DartChangeBuilder builder) async {
+ var comment = node.thisOrAncestorOfType<Comment>();
+ if (comment == null ||
+ !comment.isDocumentation ||
+ comment.tokens.length != 1) {
+ return null;
+ }
+ var token = comment.tokens.first;
+ if (token.type != TokenType.MULTI_LINE_COMMENT) {
+ return null;
+ }
+ var text = token.lexeme;
+ var lines = text.split('\n');
+ var prefix = utils.getNodePrefix(comment);
+ var newLines = <String>[];
+ var firstLine = true;
+ var linePrefix = '';
+ for (var line in lines) {
+ if (firstLine) {
+ firstLine = false;
+ var expectedPrefix = '/**';
+ if (!line.startsWith(expectedPrefix)) {
+ return null;
+ }
+ line = line.substring(expectedPrefix.length).trim();
+ if (line.isNotEmpty) {
+ newLines.add('/// $line');
+ linePrefix = eol + prefix;
+ }
+ } else {
+ if (line.startsWith(prefix + ' */')) {
+ break;
+ }
+ var expectedPrefix = prefix + ' *';
+ if (!line.startsWith(expectedPrefix)) {
+ return null;
+ }
+ line = line.substring(expectedPrefix.length);
+ if (line.isEmpty) {
+ newLines.add('$linePrefix///');
+ } else {
+ newLines.add('$linePrefix///$line');
+ }
+ linePrefix = eol + prefix;
+ }
+ }
+
+ await builder.addFileEdit(file, (DartFileEditBuilder builder) {
+ builder.addReplacement(range.node(comment), (DartEditBuilder builder) {
+ for (var newLine in newLines) {
+ builder.write(newLine);
+ }
+ });
+ });
+ }
+}
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/convert_map_from_iterable_to_for_literal.dart b/pkg/analysis_server/lib/src/services/correction/dart/convert_map_from_iterable_to_for_literal.dart
new file mode 100644
index 0000000..5d3108b
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/correction/dart/convert_map_from_iterable_to_for_literal.dart
@@ -0,0 +1,220 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analysis_server/src/services/correction/assist.dart';
+import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
+import 'package:analysis_server/src/services/correction/fix.dart';
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/ast/visitor.dart';
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer_plugin/utilities/assist/assist.dart';
+import 'package:analyzer_plugin/utilities/change_builder/change_builder_dart.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:analyzer_plugin/utilities/range_factory.dart';
+
+class ConvertMapFromIterableToForLiteral extends CorrectionProducer {
+ @override
+ AssistKind get assistKind => DartAssistKind.CONVERT_TO_FOR_ELEMENT;
+
+ @override
+ FixKind get fixKind => DartFixKind.CONVERT_TO_FOR_ELEMENT;
+
+ @override
+ Future<void> compute(DartChangeBuilder builder) async {
+ //
+ // Ensure that the selection is inside an invocation of Map.fromIterable.
+ //
+ var creation = node.thisOrAncestorOfType<InstanceCreationExpression>();
+ if (creation == null) {
+ return null;
+ }
+ var element = creation.staticElement;
+ if (element == null ||
+ element.name != 'fromIterable' ||
+ element.enclosingElement != typeProvider.mapElement) {
+ return null;
+ }
+ //
+ // Ensure that the arguments have the right form.
+ //
+ var arguments = creation.argumentList.arguments;
+ if (arguments.length != 3) {
+ return null;
+ }
+ var iterator = arguments[0].unParenthesized;
+ var secondArg = arguments[1];
+ var thirdArg = arguments[2];
+
+ Expression extractBody(FunctionExpression expression) {
+ var body = expression.body;
+ if (body is ExpressionFunctionBody) {
+ return body.expression;
+ } else if (body is BlockFunctionBody) {
+ var statements = body.block.statements;
+ if (statements.length == 1) {
+ var statement = statements[0];
+ if (statement is ReturnStatement) {
+ return statement.expression;
+ }
+ }
+ }
+ return null;
+ }
+
+ FunctionExpression extractClosure(String name, Expression argument) {
+ if (argument is NamedExpression && argument.name.label.name == name) {
+ var expression = argument.expression.unParenthesized;
+ if (expression is FunctionExpression) {
+ var parameters = expression.parameters.parameters;
+ if (parameters.length == 1 && parameters[0].isRequiredPositional) {
+ if (extractBody(expression) != null) {
+ return expression;
+ }
+ }
+ }
+ }
+ return null;
+ }
+
+ var keyClosure =
+ extractClosure('key', secondArg) ?? extractClosure('key', thirdArg);
+ var valueClosure =
+ extractClosure('value', thirdArg) ?? extractClosure('value', secondArg);
+ if (keyClosure == null || valueClosure == null) {
+ return null;
+ }
+ //
+ // Compute the loop variable name and convert the key and value closures if
+ // necessary.
+ //
+ SimpleFormalParameter keyParameter = keyClosure.parameters.parameters[0];
+ var keyParameterName = keyParameter.identifier.name;
+ SimpleFormalParameter valueParameter =
+ valueClosure.parameters.parameters[0];
+ var valueParameterName = valueParameter.identifier.name;
+ var keyBody = extractBody(keyClosure);
+ var keyExpressionText = utils.getNodeText(keyBody);
+ var valueBody = extractBody(valueClosure);
+ var valueExpressionText = utils.getNodeText(valueBody);
+
+ String loopVariableName;
+ if (keyParameterName == valueParameterName) {
+ loopVariableName = keyParameterName;
+ } else {
+ var keyFinder = _ParameterReferenceFinder(keyParameter.declaredElement);
+ keyBody.accept(keyFinder);
+
+ var valueFinder =
+ _ParameterReferenceFinder(valueParameter.declaredElement);
+ valueBody.accept(valueFinder);
+
+ String computeUnusedVariableName() {
+ var candidate = 'e';
+ var index = 1;
+ while (keyFinder.referencesName(candidate) ||
+ valueFinder.referencesName(candidate)) {
+ candidate = 'e${index++}';
+ }
+ return candidate;
+ }
+
+ if (valueFinder.isParameterUnreferenced) {
+ if (valueFinder.referencesName(keyParameterName)) {
+ // The name of the value parameter is not used, but we can't use the
+ // name of the key parameter because doing so would hide a variable
+ // referenced in the value expression.
+ loopVariableName = computeUnusedVariableName();
+ keyExpressionText = keyFinder.replaceName(
+ keyExpressionText, loopVariableName, keyBody.offset);
+ } else {
+ loopVariableName = keyParameterName;
+ }
+ } else if (keyFinder.isParameterUnreferenced) {
+ if (keyFinder.referencesName(valueParameterName)) {
+ // The name of the key parameter is not used, but we can't use the
+ // name of the value parameter because doing so would hide a variable
+ // referenced in the key expression.
+ loopVariableName = computeUnusedVariableName();
+ valueExpressionText = valueFinder.replaceName(
+ valueExpressionText, loopVariableName, valueBody.offset);
+ } else {
+ loopVariableName = valueParameterName;
+ }
+ } else {
+ // The names are different and both are used. We need to find a name
+ // that would not change the resolution of any other identifiers in
+ // either the key or value expressions.
+ loopVariableName = computeUnusedVariableName();
+ keyExpressionText = keyFinder.replaceName(
+ keyExpressionText, loopVariableName, keyBody.offset);
+ valueExpressionText = valueFinder.replaceName(
+ valueExpressionText, loopVariableName, valueBody.offset);
+ }
+ }
+ //
+ // Construct the edit.
+ //
+ await builder.addFileEdit(file, (DartFileEditBuilder builder) {
+ builder.addReplacement(range.node(creation), (DartEditBuilder builder) {
+ builder.write('{ for (var ');
+ builder.write(loopVariableName);
+ builder.write(' in ');
+ builder.write(utils.getNodeText(iterator));
+ builder.write(') ');
+ builder.write(keyExpressionText);
+ builder.write(' : ');
+ builder.write(valueExpressionText);
+ builder.write(' }');
+ });
+ });
+ }
+}
+
+/// A visitor that can be used to find references to a parameter.
+class _ParameterReferenceFinder extends RecursiveAstVisitor<void> {
+ /// The parameter for which references are being sought, or `null` if we are
+ /// just accumulating a list of referenced names.
+ final ParameterElement parameter;
+
+ /// A list of the simple identifiers that reference the [parameter].
+ final List<SimpleIdentifier> references = <SimpleIdentifier>[];
+
+ /// A collection of the names of other simple identifiers that were found. We
+ /// need to know these in order to ensure that the selected loop variable does
+ /// not hide a name from an enclosing scope that is already being referenced.
+ final Set<String> otherNames = <String>{};
+
+ /// Initialize a newly created finder to find references to the [parameter].
+ _ParameterReferenceFinder(this.parameter) : assert(parameter != null);
+
+ /// Return `true` if the parameter is unreferenced in the nodes that have been
+ /// visited.
+ bool get isParameterUnreferenced => references.isEmpty;
+
+ /// Return `true` is the given name (assumed to be different than the name of
+ /// the parameter) is references in the nodes that have been visited.
+ bool referencesName(String name) => otherNames.contains(name);
+
+ /// Replace all of the references to the parameter in the given [source] with
+ /// the [newName]. The [offset] is the offset of the first character of the
+ /// [source] relative to the start of the file.
+ String replaceName(String source, String newName, int offset) {
+ var oldLength = parameter.name.length;
+ for (var i = references.length - 1; i >= 0; i--) {
+ var oldOffset = references[i].offset - offset;
+ source = source.replaceRange(oldOffset, oldOffset + oldLength, newName);
+ }
+ return source;
+ }
+
+ @override
+ void visitSimpleIdentifier(SimpleIdentifier node) {
+ if (node.staticElement == parameter) {
+ references.add(node);
+ } else if (!node.isQualified) {
+ // Only non-prefixed identifiers can be hidden.
+ otherNames.add(node.name);
+ }
+ }
+}
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/convert_quotes.dart b/pkg/analysis_server/lib/src/services/correction/dart/convert_quotes.dart
new file mode 100644
index 0000000..2e661fd
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/correction/dart/convert_quotes.dart
@@ -0,0 +1,92 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analysis_server/src/services/correction/assist.dart';
+import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
+import 'package:analysis_server/src/services/correction/fix.dart';
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/source/source_range.dart';
+import 'package:analyzer_plugin/utilities/assist/assist.dart';
+import 'package:analyzer_plugin/utilities/change_builder/change_builder_dart.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+
+abstract class ConvertQuotes extends CorrectionProducer {
+ ConvertQuotes();
+
+ /// Return `true` if this producer is converting from double quotes to single
+ /// quotes, or `false` if it's converting from single quotes to double quotes.
+ bool get fromDouble;
+
+ @override
+ Future<void> compute(DartChangeBuilder builder) async {
+ if (node is SimpleStringLiteral) {
+ SimpleStringLiteral literal = node;
+ if (fromDouble ? !literal.isSingleQuoted : literal.isSingleQuoted) {
+ var newQuote = literal.isMultiline
+ ? (fromDouble ? "'''" : '"""')
+ : (fromDouble ? "'" : '"');
+ var quoteLength = literal.isMultiline ? 3 : 1;
+ var lexeme = literal.literal.lexeme;
+ if (!lexeme.contains(newQuote)) {
+ await builder.addFileEdit(file, (DartFileEditBuilder builder) {
+ builder.addSimpleReplacement(
+ SourceRange(
+ literal.offset + (literal.isRaw ? 1 : 0), quoteLength),
+ newQuote);
+ builder.addSimpleReplacement(
+ SourceRange(literal.end - quoteLength, quoteLength), newQuote);
+ });
+ }
+ }
+ } else if (node is InterpolationString) {
+ StringInterpolation parent = node.parent;
+ if (fromDouble ? !parent.isSingleQuoted : parent.isSingleQuoted) {
+ var newQuote = parent.isMultiline
+ ? (fromDouble ? "'''" : '"""')
+ : (fromDouble ? "'" : '"');
+ var quoteLength = parent.isMultiline ? 3 : 1;
+ var elements = parent.elements;
+ for (var i = 0; i < elements.length; i++) {
+ var element = elements[i];
+ if (element is InterpolationString) {
+ var lexeme = element.contents.lexeme;
+ if (lexeme.contains(newQuote)) {
+ return null;
+ }
+ }
+ }
+ await builder.addFileEdit(file, (DartFileEditBuilder builder) {
+ builder.addSimpleReplacement(
+ SourceRange(parent.offset + (parent.isRaw ? 1 : 0), quoteLength),
+ newQuote);
+ builder.addSimpleReplacement(
+ SourceRange(parent.end - quoteLength, quoteLength), newQuote);
+ });
+ }
+ }
+ }
+}
+
+class ConvertToDoubleQuotes extends ConvertQuotes {
+ ConvertToDoubleQuotes();
+
+ @override
+ AssistKind get assistKind => DartAssistKind.CONVERT_TO_DOUBLE_QUOTED_STRING;
+
+ @override
+ bool get fromDouble => false;
+}
+
+class ConvertToSingleQuotes extends ConvertQuotes {
+ ConvertToSingleQuotes();
+
+ @override
+ AssistKind get assistKind => DartAssistKind.CONVERT_TO_SINGLE_QUOTED_STRING;
+
+ @override
+ FixKind get fixKind => DartFixKind.CONVERT_TO_SINGLE_QUOTED_STRING;
+
+ @override
+ bool get fromDouble => true;
+}
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/convert_to_expression_function_body.dart b/pkg/analysis_server/lib/src/services/correction/dart/convert_to_expression_function_body.dart
new file mode 100644
index 0000000..771db27
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/correction/dart/convert_to_expression_function_body.dart
@@ -0,0 +1,65 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analysis_server/src/services/correction/assist.dart';
+import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
+import 'package:analysis_server/src/services/correction/fix.dart';
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer_plugin/utilities/assist/assist.dart';
+import 'package:analyzer_plugin/utilities/change_builder/change_builder_dart.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:analyzer_plugin/utilities/range_factory.dart';
+
+class ConvertToExpressionFunctionBody extends CorrectionProducer {
+ @override
+ AssistKind get assistKind => DartAssistKind.CONVERT_INTO_EXPRESSION_BODY;
+
+ @override
+ FixKind get fixKind => DartFixKind.CONVERT_INTO_EXPRESSION_BODY;
+
+ @override
+ Future<void> compute(DartChangeBuilder builder) async {
+ // prepare current body
+ var body = getEnclosingFunctionBody();
+ if (body is! BlockFunctionBody || body.isGenerator) {
+ return;
+ }
+ // prepare return statement
+ List<Statement> statements = (body as BlockFunctionBody).block.statements;
+ if (statements.length != 1) {
+ return;
+ }
+ var onlyStatement = statements.first;
+ // prepare returned expression
+ Expression returnExpression;
+ if (onlyStatement is ReturnStatement) {
+ returnExpression = onlyStatement.expression;
+ } else if (onlyStatement is ExpressionStatement) {
+ returnExpression = onlyStatement.expression;
+ }
+ if (returnExpression == null) {
+ return;
+ }
+
+ // Return expressions can be quite large, e.g. Flutter build() methods.
+ // It is surprising to see this Quick Assist deep in the function body.
+ if (selectionOffset >= returnExpression.offset) {
+ return;
+ }
+
+ await builder.addFileEdit(file, (DartFileEditBuilder builder) {
+ builder.addReplacement(range.node(body), (DartEditBuilder builder) {
+ if (body.isAsynchronous) {
+ builder.write('async ');
+ }
+ builder.write('=> ');
+ builder.write(utils.getNodeText(returnExpression));
+ if (body.parent is! FunctionExpression ||
+ body.parent.parent is FunctionDeclaration) {
+ builder.write(';');
+ }
+ });
+ });
+ }
+}
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/convert_to_generic_function_syntax.dart b/pkg/analysis_server/lib/src/services/correction/dart/convert_to_generic_function_syntax.dart
new file mode 100644
index 0000000..bba054b
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/correction/dart/convert_to_generic_function_syntax.dart
@@ -0,0 +1,106 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analysis_server/src/services/correction/assist.dart';
+import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
+import 'package:analysis_server/src/services/correction/fix.dart';
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer_plugin/utilities/assist/assist.dart';
+import 'package:analyzer_plugin/utilities/change_builder/change_builder_dart.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:analyzer_plugin/utilities/range_factory.dart';
+
+class ConvertToGenericFunctionSyntax extends CorrectionProducer {
+ @override
+ AssistKind get assistKind =>
+ DartAssistKind.CONVERT_INTO_GENERIC_FUNCTION_SYNTAX;
+
+ @override
+ FixKind get fixKind => DartFixKind.CONVERT_TO_GENERIC_FUNCTION_SYNTAX;
+
+ @override
+ Future<void> compute(DartChangeBuilder builder) async {
+ var node = this.node;
+ while (node != null) {
+ if (node is FunctionTypeAlias) {
+ return _convertFunctionTypeAlias(builder, node);
+ } else if (node is FunctionTypedFormalParameter) {
+ return _convertFunctionTypedFormalParameter(builder, node);
+ } else if (node is FormalParameterList) {
+ // It would be confusing for this assist to alter a surrounding context
+ // when the selection is inside a parameter list.
+ return null;
+ }
+ node = node.parent;
+ }
+ }
+
+ /// Return `true` if all of the parameters in the given list of [parameters]
+ /// have an explicit type annotation.
+ bool _allParametersHaveTypes(FormalParameterList parameters) {
+ for (var parameter in parameters.parameters) {
+ if (parameter is DefaultFormalParameter) {
+ parameter = (parameter as DefaultFormalParameter).parameter;
+ }
+ if (parameter is SimpleFormalParameter) {
+ if (parameter.type == null) {
+ return false;
+ }
+ } else if (parameter is! FunctionTypedFormalParameter) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ Future<void> _convertFunctionTypeAlias(
+ DartChangeBuilder builder, FunctionTypeAlias node) async {
+ if (!_allParametersHaveTypes(node.parameters)) {
+ return;
+ }
+ String returnType;
+ if (node.returnType != null) {
+ returnType = utils.getNodeText(node.returnType);
+ }
+ var functionName = utils.getRangeText(
+ range.startEnd(node.name, node.typeParameters ?? node.name));
+ var parameters = utils.getNodeText(node.parameters);
+ String replacement;
+ if (returnType == null) {
+ replacement = '$functionName = Function$parameters';
+ } else {
+ replacement = '$functionName = $returnType Function$parameters';
+ }
+ // add change
+ await builder.addFileEdit(file, (DartFileEditBuilder builder) {
+ builder.addSimpleReplacement(
+ range.startStart(node.typedefKeyword.next, node.semicolon),
+ replacement);
+ });
+ }
+
+ Future<void> _convertFunctionTypedFormalParameter(
+ DartChangeBuilder builder, FunctionTypedFormalParameter node) async {
+ if (!_allParametersHaveTypes(node.parameters)) {
+ return;
+ }
+ String returnType;
+ if (node.returnType != null) {
+ returnType = utils.getNodeText(node.returnType);
+ }
+ var functionName = utils.getRangeText(range.startEnd(
+ node.identifier, node.typeParameters ?? node.identifier));
+ var parameters = utils.getNodeText(node.parameters);
+ String replacement;
+ if (returnType == null) {
+ replacement = 'Function$parameters $functionName';
+ } else {
+ replacement = '$returnType Function$parameters $functionName';
+ }
+ // add change
+ await builder.addFileEdit(file, (DartFileEditBuilder builder) {
+ builder.addSimpleReplacement(range.node(node), replacement);
+ });
+ }
+}
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/convert_to_int_literal.dart b/pkg/analysis_server/lib/src/services/correction/dart/convert_to_int_literal.dart
new file mode 100644
index 0000000..b4f967c
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/correction/dart/convert_to_int_literal.dart
@@ -0,0 +1,44 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analysis_server/src/services/correction/assist.dart';
+import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
+import 'package:analysis_server/src/services/correction/fix.dart';
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/source/source_range.dart';
+import 'package:analyzer_plugin/utilities/assist/assist.dart';
+import 'package:analyzer_plugin/utilities/change_builder/change_builder_dart.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+
+class ConvertToIntLiteral extends CorrectionProducer {
+ @override
+ AssistKind get assistKind => DartAssistKind.CONVERT_TO_INT_LITERAL;
+
+ @override
+ FixKind get fixKind => DartFixKind.CONVERT_TO_INT_LITERAL;
+
+ @override
+ Future<void> compute(DartChangeBuilder builder) async {
+ if (node is! DoubleLiteral) {
+ return;
+ }
+ DoubleLiteral literal = node;
+ int intValue;
+ try {
+ intValue = literal.value?.truncate();
+ } catch (e) {
+ // Double cannot be converted to int
+ }
+ if (intValue == null || intValue != literal.value) {
+ return;
+ }
+
+ await builder.addFileEdit(file, (DartFileEditBuilder builder) {
+ builder.addReplacement(SourceRange(literal.offset, literal.length),
+ (DartEditBuilder builder) {
+ builder.write('$intValue');
+ });
+ });
+ }
+}
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/convert_to_on_type.dart b/pkg/analysis_server/lib/src/services/correction/dart/convert_to_on_type.dart
new file mode 100644
index 0000000..22876af
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/correction/dart/convert_to_on_type.dart
@@ -0,0 +1,51 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
+import 'package:analysis_server/src/services/correction/fix.dart';
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer_plugin/utilities/change_builder/change_builder_dart.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:analyzer_plugin/utilities/range_factory.dart';
+
+class ConvertToOnType extends CorrectionProducer {
+ @override
+ final List<Object> fixArguments = [];
+
+ @override
+ FixKind get fixKind => DartFixKind.CONVERT_TO_ON_TYPE;
+
+ @override
+ Future<void> compute(DartChangeBuilder builder) async {
+ var exceptionParameter = node;
+ if (exceptionParameter is SimpleIdentifier) {
+ var catchClause = exceptionParameter.parent;
+ if (catchClause is CatchClause &&
+ catchClause.exceptionType == null &&
+ catchClause.exceptionParameter == exceptionParameter) {
+ var exceptionTypeName = exceptionParameter.name;
+ fixArguments.add(exceptionTypeName);
+ await builder.addFileEdit(file, (builder) {
+ if (catchClause.stackTraceParameter != null) {
+ builder.addSimpleReplacement(
+ range.startStart(
+ catchClause.catchKeyword,
+ catchClause.stackTraceParameter,
+ ),
+ 'on $exceptionTypeName catch (_, ',
+ );
+ } else {
+ builder.addSimpleReplacement(
+ range.startEnd(
+ catchClause.catchKeyword,
+ catchClause.rightParenthesis,
+ ),
+ 'on $exceptionTypeName',
+ );
+ }
+ });
+ }
+ }
+ }
+}
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/convert_to_package_import.dart b/pkg/analysis_server/lib/src/services/correction/dart/convert_to_package_import.dart
new file mode 100644
index 0000000..a055b5c
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/correction/dart/convert_to_package_import.dart
@@ -0,0 +1,58 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analysis_server/src/services/correction/assist.dart';
+import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
+import 'package:analysis_server/src/services/correction/fix.dart';
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer_plugin/utilities/assist/assist.dart';
+import 'package:analyzer_plugin/utilities/change_builder/change_builder_dart.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:analyzer_plugin/utilities/range_factory.dart';
+
+class ConvertToPackageImport extends CorrectionProducer {
+ @override
+ AssistKind get assistKind => DartAssistKind.CONVERT_TO_PACKAGE_IMPORT;
+
+ @override
+ FixKind get fixKind => DartFixKind.CONVERT_TO_PACKAGE_IMPORT;
+
+ @override
+ Future<void> compute(DartChangeBuilder builder) async {
+ var node = this.node;
+ if (node is StringLiteral) {
+ node = node.parent;
+ }
+ if (node is ImportDirective) {
+ var importDirective = node;
+ var uriSource = importDirective.uriSource;
+
+ // Ignore if invalid URI.
+ if (uriSource == null) {
+ return;
+ }
+
+ var importUri = uriSource.uri;
+ if (importUri.scheme != 'package') {
+ return;
+ }
+
+ // Don't offer to convert a 'package:' URI to itself.
+ try {
+ if (Uri.parse(importDirective.uriContent).scheme == 'package') {
+ return;
+ }
+ } on FormatException {
+ return;
+ }
+
+ await builder.addFileEdit(file, (builder) {
+ builder.addSimpleReplacement(
+ range.node(importDirective.uri),
+ "'$importUri'",
+ );
+ });
+ }
+ }
+}
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/convert_to_relative_import.dart b/pkg/analysis_server/lib/src/services/correction/dart/convert_to_relative_import.dart
new file mode 100644
index 0000000..938214b
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/correction/dart/convert_to_relative_import.dart
@@ -0,0 +1,80 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analysis_server/src/services/correction/assist.dart';
+import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
+import 'package:analysis_server/src/services/correction/fix.dart';
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer_plugin/utilities/assist/assist.dart';
+import 'package:analyzer_plugin/utilities/change_builder/change_builder_dart.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:analyzer_plugin/utilities/range_factory.dart';
+import 'package:path/path.dart' as path;
+
+class ConvertToRelativeImport extends CorrectionProducer {
+ @override
+ AssistKind get assistKind => DartAssistKind.CONVERT_TO_RELATIVE_IMPORT;
+
+ @override
+ FixKind get fixKind => DartFixKind.CONVERT_TO_RELATIVE_IMPORT;
+
+ @override
+ Future<void> compute(DartChangeBuilder builder) async {
+ var node = this.node;
+ if (node is StringLiteral) {
+ node = node.parent;
+ }
+ if (node is! ImportDirective) {
+ return;
+ }
+
+ ImportDirective importDirective = node;
+
+ // Ignore if invalid URI.
+ if (importDirective.uriSource == null) {
+ return;
+ }
+
+ // Ignore if the uri is not a package: uri.
+ var sourceUri = resolvedResult.uri;
+ if (sourceUri.scheme != 'package') {
+ return;
+ }
+
+ Uri importUri;
+ try {
+ importUri = Uri.parse(importDirective.uriContent);
+ } on FormatException {
+ return;
+ }
+
+ // Ignore if import uri is not a package: uri.
+ if (importUri.scheme != 'package') {
+ return;
+ }
+
+ // Verify that the source's uri and the import uri have the same package
+ // name.
+ var sourceSegments = sourceUri.pathSegments;
+ var importSegments = importUri.pathSegments;
+ if (sourceSegments.isEmpty ||
+ importSegments.isEmpty ||
+ sourceSegments.first != importSegments.first) {
+ return;
+ }
+
+ // We only write posix style paths in import directives.
+ var relativePath = path.posix.relative(
+ importUri.path,
+ from: path.dirname(sourceUri.path),
+ );
+
+ await builder.addFileEdit(file, (builder) {
+ builder.addSimpleReplacement(
+ range.node(importDirective.uri).getExpanded(-1),
+ relativePath,
+ );
+ });
+ }
+}
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/inline_invocation.dart b/pkg/analysis_server/lib/src/services/correction/dart/inline_invocation.dart
new file mode 100644
index 0000000..4787df2
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/correction/dart/inline_invocation.dart
@@ -0,0 +1,63 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analysis_server/src/services/correction/assist.dart';
+import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
+import 'package:analysis_server/src/services/correction/fix.dart';
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer_plugin/utilities/assist/assist.dart';
+import 'package:analyzer_plugin/utilities/change_builder/change_builder_dart.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:analyzer_plugin/utilities/range_factory.dart';
+
+class InlineInvocation extends CorrectionProducer {
+ @override
+ List<Object> get assistArguments => ['add'];
+
+ @override
+ AssistKind get assistKind => DartAssistKind.INLINE_INVOCATION;
+
+ @override
+ List<Object> get fixArguments => ['add'];
+
+ @override
+ FixKind get fixKind => DartFixKind.INLINE_INVOCATION;
+
+ @override
+ Future<void> compute(DartChangeBuilder builder) async {
+ var node = this.node;
+ if (node is! SimpleIdentifier || node.parent is! MethodInvocation) {
+ return;
+ }
+ SimpleIdentifier name = node;
+ MethodInvocation invocation = node.parent;
+ if (name != invocation.methodName ||
+ name.name != 'add' ||
+ !invocation.isCascaded ||
+ invocation.argumentList.arguments.length != 1) {
+ return;
+ }
+ var cascade = invocation.thisOrAncestorOfType<CascadeExpression>();
+ var sections = cascade.cascadeSections;
+ var target = cascade.target;
+ if (target is! ListLiteral || sections[0] != invocation) {
+ // TODO(brianwilkerson) Consider extending this to handle set literals.
+ return;
+ }
+ ListLiteral list = target;
+ var argument = invocation.argumentList.arguments[0];
+ var elementText = utils.getNodeText(argument);
+
+ await builder.addFileEdit(file, (DartFileEditBuilder builder) {
+ if (list.elements.isNotEmpty) {
+ // ['a']..add(e);
+ builder.addSimpleInsertion(list.elements.last.end, ', $elementText');
+ } else {
+ // []..add(e);
+ builder.addSimpleInsertion(list.leftBracket.end, elementText);
+ }
+ builder.addDeletion(range.node(invocation));
+ });
+ }
+}
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/remove_type_annotation.dart b/pkg/analysis_server/lib/src/services/correction/dart/remove_type_annotation.dart
new file mode 100644
index 0000000..023a9cf
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/correction/dart/remove_type_annotation.dart
@@ -0,0 +1,86 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analysis_server/src/services/correction/assist.dart';
+import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
+import 'package:analysis_server/src/services/correction/fix.dart';
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer_plugin/utilities/assist/assist.dart';
+import 'package:analyzer_plugin/utilities/change_builder/change_builder_dart.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:analyzer_plugin/utilities/range_factory.dart';
+
+class RemoveTypeAnnotation extends CorrectionProducer {
+ @override
+ AssistKind get assistKind => DartAssistKind.REMOVE_TYPE_ANNOTATION;
+
+ @override
+ FixKind get fixKind => DartFixKind.REMOVE_TYPE_ANNOTATION;
+
+ @override
+ Future<void> compute(DartChangeBuilder builder) async {
+ // todo (pq): unify w/ fix (and then add a guard to not assist on lints:
+ // avoid_return_types_on_setters, type_init_formals)
+ var declarationList = node.thisOrAncestorOfType<VariableDeclarationList>();
+ if (declarationList == null) {
+ await _removeFromDeclaredIdentifier(builder);
+ } else {
+ await _removeFromDeclarationList(builder, declarationList);
+ }
+ }
+
+ Future<void> _removeFromDeclarationList(DartChangeBuilder builder,
+ VariableDeclarationList declarationList) async {
+ // we need a type
+ var typeNode = declarationList.type;
+ if (typeNode == null) {
+ return;
+ }
+ // ignore if an incomplete variable declaration
+ if (declarationList.variables.length == 1 &&
+ declarationList.variables[0].name.isSynthetic) {
+ return;
+ }
+ // must be not after the name of the variable
+ var firstVariable = declarationList.variables[0];
+ if (selectionOffset > firstVariable.name.end) {
+ return;
+ }
+ // The variable must have an initializer, otherwise there is no other
+ // source for its type.
+ if (firstVariable.initializer == null) {
+ return;
+ }
+ var keyword = declarationList.keyword;
+ await builder.addFileEdit(file, (DartFileEditBuilder builder) {
+ var typeRange = range.startStart(typeNode, firstVariable);
+ if (keyword != null && keyword.lexeme != 'var') {
+ builder.addSimpleReplacement(typeRange, '');
+ } else {
+ builder.addSimpleReplacement(typeRange, 'var ');
+ }
+ });
+ }
+
+ Future<void> _removeFromDeclaredIdentifier(DartChangeBuilder builder) async {
+ var declaration = node.thisOrAncestorOfType<DeclaredIdentifier>();
+ if (declaration == null) {
+ return;
+ }
+ var typeNode = declaration.type;
+ if (typeNode == null) {
+ return;
+ }
+ var keyword = declaration.keyword;
+ var variableName = declaration.identifier;
+ await builder.addFileEdit(file, (DartFileEditBuilder builder) {
+ var typeRange = range.startStart(typeNode, variableName);
+ if (keyword != null && keyword.lexeme != 'var') {
+ builder.addSimpleReplacement(typeRange, '');
+ } else {
+ builder.addSimpleReplacement(typeRange, 'var ');
+ }
+ });
+ }
+}
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/replace_with_var.dart b/pkg/analysis_server/lib/src/services/correction/dart/replace_with_var.dart
new file mode 100644
index 0000000..787dcb6
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/correction/dart/replace_with_var.dart
@@ -0,0 +1,135 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analysis_server/src/services/correction/assist.dart';
+import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
+import 'package:analysis_server/src/services/correction/fix.dart';
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/src/dart/element/type.dart';
+import 'package:analyzer_plugin/utilities/assist/assist.dart';
+import 'package:analyzer_plugin/utilities/change_builder/change_builder_dart.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:analyzer_plugin/utilities/range_factory.dart';
+
+class ReplaceWithVar extends CorrectionProducer {
+ @override
+ AssistKind get assistKind => DartAssistKind.REPLACE_WITH_VAR;
+
+ @override
+ FixKind get fixKind => DartFixKind.REPLACE_WITH_VAR;
+
+ @override
+ Future<void> compute(DartChangeBuilder builder) async {
+ var type = node.thisOrAncestorOfType<TypeAnnotation>();
+ if (type == null) {
+ return;
+ }
+ // TODO(brianwilkerson) Optimize this by removing the duplication between
+ // [_canReplaceWithVar] and the rest of this method.
+ if (!_canReplaceWithVar()) {
+ return;
+ }
+ var parent = type.parent;
+ var grandparent = parent?.parent;
+ if (parent is VariableDeclarationList &&
+ (grandparent is VariableDeclarationStatement ||
+ grandparent is ForPartsWithDeclarations)) {
+ var variables = parent.variables;
+ if (variables.length != 1) {
+ return;
+ }
+ var initializer = variables[0].initializer;
+ String typeArgumentsText;
+ int typeArgumentsOffset;
+ if (type is NamedType && type.typeArguments != null) {
+ if (initializer is TypedLiteral) {
+ if (initializer.typeArguments == null) {
+ typeArgumentsText = utils.getNodeText(type.typeArguments);
+ typeArgumentsOffset = initializer.offset;
+ }
+ } else if (initializer is InstanceCreationExpression) {
+ if (initializer.constructorName.type.typeArguments == null) {
+ typeArgumentsText = utils.getNodeText(type.typeArguments);
+ typeArgumentsOffset = initializer.constructorName.type.end;
+ }
+ }
+ }
+ if (initializer is SetOrMapLiteral &&
+ initializer.typeArguments == null &&
+ typeArgumentsText == null) {
+ // TODO(brianwilkerson) This is to prevent the fix from converting a
+ // valid map or set literal into an ambiguous literal. We could apply
+ // this in more places by examining the elements of the collection.
+ return;
+ }
+ await builder.addFileEdit(file, (DartFileEditBuilder builder) {
+ builder.addSimpleReplacement(range.node(type), 'var');
+ if (typeArgumentsText != null) {
+ builder.addSimpleInsertion(typeArgumentsOffset, typeArgumentsText);
+ }
+ });
+ } else if (parent is DeclaredIdentifier &&
+ grandparent is ForEachPartsWithDeclaration) {
+ String typeArgumentsText;
+ int typeArgumentsOffset;
+ if (type is NamedType && type.typeArguments != null) {
+ var iterable = grandparent.iterable;
+ if (iterable is TypedLiteral && iterable.typeArguments == null) {
+ typeArgumentsText = utils.getNodeText(type.typeArguments);
+ typeArgumentsOffset = iterable.offset;
+ }
+ }
+ await builder.addFileEdit(file, (DartFileEditBuilder builder) {
+ builder.addSimpleReplacement(range.node(type), 'var');
+ if (typeArgumentsText != null) {
+ builder.addSimpleInsertion(typeArgumentsOffset, typeArgumentsText);
+ }
+ });
+ }
+ }
+
+ /// Return `true` if the type in the [node] can be replaced with `var`.
+ bool _canConvertVariableDeclarationList(VariableDeclarationList node) {
+ final staticType = node?.type?.type;
+ if (staticType == null || staticType.isDynamic) {
+ return false;
+ }
+ for (final child in node.variables) {
+ var initializer = child.initializer;
+ if (initializer == null || initializer.staticType != staticType) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /// Return `true` if the [node] can be replaced with `var`.
+ bool _canReplaceWithVar() {
+ var parent = node.parent;
+ while (parent != null) {
+ if (parent is VariableDeclarationStatement) {
+ return _canConvertVariableDeclarationList(parent.variables);
+ } else if (parent is ForPartsWithDeclarations) {
+ return _canConvertVariableDeclarationList(parent.variables);
+ } else if (parent is ForEachPartsWithDeclaration) {
+ var loopVariableType = parent.loopVariable.type;
+ var staticType = loopVariableType?.type;
+ if (staticType == null || staticType.isDynamic) {
+ return false;
+ }
+ final iterableType = parent.iterable.staticType;
+ if (iterableType is InterfaceTypeImpl) {
+ var instantiatedType =
+ iterableType.asInstanceOf(typeProvider.iterableElement);
+ if (instantiatedType?.typeArguments?.first == staticType) {
+ return true;
+ }
+ }
+ return false;
+ }
+ parent = parent.parent;
+ }
+ return false;
+ }
+}
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/sort_child_property_last.dart b/pkg/analysis_server/lib/src/services/correction/dart/sort_child_property_last.dart
new file mode 100644
index 0000000..778bc28
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/correction/dart/sort_child_property_last.dart
@@ -0,0 +1,57 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analysis_server/src/services/correction/assist.dart';
+import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
+import 'package:analysis_server/src/services/correction/fix.dart';
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer_plugin/protocol/protocol_common.dart';
+import 'package:analyzer_plugin/utilities/assist/assist.dart';
+import 'package:analyzer_plugin/utilities/change_builder/change_builder_dart.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:analyzer_plugin/utilities/range_factory.dart';
+
+class SortChildPropertyLast extends CorrectionProducer {
+ @override
+ AssistKind get assistKind => DartAssistKind.SORT_CHILD_PROPERTY_LAST;
+
+ @override
+ FixKind get fixKind => DartFixKind.SORT_CHILD_PROPERTY_LAST;
+
+ @override
+ Future<void> compute(DartChangeBuilder builder) async {
+ var childProp = flutter.findNamedExpression(node, 'child');
+ childProp ??= flutter.findNamedExpression(node, 'children');
+ if (childProp == null) {
+ return;
+ }
+
+ var parent = childProp.parent?.parent;
+ if (parent is! InstanceCreationExpression ||
+ !flutter.isWidgetCreation(parent)) {
+ return;
+ }
+
+ InstanceCreationExpression creationExpression = parent;
+ var args = creationExpression.argumentList;
+
+ var last = args.arguments.last;
+ if (last == childProp) {
+ // Already sorted.
+ return;
+ }
+
+ await builder.addFileEdit(file, (DartFileEditBuilder fileEditBuilder) {
+ var start = childProp.beginToken.previous.end;
+ var end = childProp.endToken.next.end;
+ var childRange = range.startOffsetEndOffset(start, end);
+
+ var childText = utils.getRangeText(childRange);
+ fileEditBuilder.addSimpleReplacement(childRange, '');
+ fileEditBuilder.addSimpleInsertion(last.end + 1, childText);
+
+ builder.setSelection(Position(file, last.end + 1));
+ });
+ }
+}
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/use_curly_braces.dart b/pkg/analysis_server/lib/src/services/correction/dart/use_curly_braces.dart
new file mode 100644
index 0000000..53362cc
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/correction/dart/use_curly_braces.dart
@@ -0,0 +1,138 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analysis_server/src/services/correction/assist.dart';
+import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
+import 'package:analysis_server/src/services/correction/fix.dart';
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer_plugin/utilities/assist/assist.dart';
+import 'package:analyzer_plugin/utilities/change_builder/change_builder_dart.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:analyzer_plugin/utilities/range_factory.dart';
+
+class UseCurlyBraces extends CorrectionProducer {
+ @override
+ AssistKind get assistKind => DartAssistKind.USE_CURLY_BRACES;
+
+ @override
+ FixKind get fixKind => DartFixKind.ADD_CURLY_BRACES;
+
+ @override
+ Future<void> compute(DartChangeBuilder builder) async {
+ var statement = node.thisOrAncestorOfType<Statement>();
+ var parent = statement?.parent;
+
+ if (statement is DoStatement) {
+ return _doStatement(builder, statement);
+ } else if (parent is DoStatement) {
+ return _doStatement(builder, parent);
+ } else if (statement is ForStatement) {
+ return _forStatement(builder, statement);
+ } else if (parent is ForStatement) {
+ return _forStatement(builder, parent);
+ } else if (statement is IfStatement) {
+ if (statement.elseKeyword != null &&
+ range.token(statement.elseKeyword).contains(selectionOffset)) {
+ return _ifStatement(builder, statement, statement.elseStatement);
+ } else {
+ return _ifStatement(builder, statement, null);
+ }
+ } else if (parent is IfStatement) {
+ return _ifStatement(builder, parent, statement);
+ } else if (statement is WhileStatement) {
+ return _whileStatement(builder, statement);
+ } else if (parent is WhileStatement) {
+ return _whileStatement(builder, parent);
+ }
+ }
+
+ Future<void> _doStatement(DartChangeBuilder builder, DoStatement node) async {
+ var body = node.body;
+ if (body is Block) return null;
+
+ var prefix = utils.getLinePrefix(node.offset);
+ var indent = prefix + utils.getIndent(1);
+
+ await builder.addFileEdit(file, (builder) {
+ builder.addSimpleReplacement(
+ range.endStart(node.doKeyword, body),
+ ' {$eol$indent',
+ );
+ builder.addSimpleReplacement(
+ range.endStart(body, node.whileKeyword),
+ '$eol$prefix} ',
+ );
+ });
+ }
+
+ Future<void> _forStatement(
+ DartChangeBuilder builder, ForStatement node) async {
+ var body = node.body;
+ if (body is Block) return null;
+
+ var prefix = utils.getLinePrefix(node.offset);
+ var indent = prefix + utils.getIndent(1);
+
+ await builder.addFileEdit(file, (builder) {
+ builder.addSimpleReplacement(
+ range.endStart(node.rightParenthesis, body),
+ ' {$eol$indent',
+ );
+ builder.addSimpleInsertion(body.end, '$eol$prefix}');
+ });
+ }
+
+ Future<void> _ifStatement(
+ DartChangeBuilder builder, IfStatement node, Statement thenOrElse) async {
+ var prefix = utils.getLinePrefix(node.offset);
+ var indent = prefix + utils.getIndent(1);
+
+ await builder.addFileEdit(file, (builder) {
+ var thenStatement = node.thenStatement;
+ if (thenStatement is! Block &&
+ (thenOrElse == null || thenOrElse == thenStatement)) {
+ builder.addSimpleReplacement(
+ range.endStart(node.rightParenthesis, thenStatement),
+ ' {$eol$indent',
+ );
+ if (node.elseKeyword != null) {
+ builder.addSimpleReplacement(
+ range.endStart(thenStatement, node.elseKeyword),
+ '$eol$prefix} ',
+ );
+ } else {
+ builder.addSimpleInsertion(thenStatement.end, '$eol$prefix}');
+ }
+ }
+
+ var elseStatement = node.elseStatement;
+ if (elseStatement != null &&
+ elseStatement is! Block &&
+ (thenOrElse == null || thenOrElse == elseStatement)) {
+ builder.addSimpleReplacement(
+ range.endStart(node.elseKeyword, elseStatement),
+ ' {$eol$indent',
+ );
+ builder.addSimpleInsertion(elseStatement.end, '$eol$prefix}');
+ }
+ });
+ }
+
+ Future<void> _whileStatement(
+ DartChangeBuilder builder, WhileStatement node) async {
+ var body = node.body;
+ if (body is Block) return null;
+
+ var prefix = utils.getLinePrefix(node.offset);
+ var indent = prefix + utils.getIndent(1);
+
+ await builder.addFileEdit(file, (builder) {
+ builder.addSimpleReplacement(
+ range.endStart(node.rightParenthesis, body),
+ ' {$eol$indent',
+ );
+ builder.addSimpleInsertion(body.end, '$eol$prefix}');
+ });
+ }
+}
diff --git a/pkg/analysis_server/lib/src/services/correction/fix.dart b/pkg/analysis_server/lib/src/services/correction/fix.dart
index 07bf305..68563e5 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix.dart
@@ -231,6 +231,8 @@
'dart.fix.convert.toNamedArguments', 50, 'Convert to named arguments');
static const CONVERT_TO_NULL_AWARE =
FixKind('dart.fix.convert.toNullAware', 50, "Convert to use '?.'");
+ static const CONVERT_TO_ON_TYPE =
+ FixKind('dart.fix.convert.toOnType', 50, "Convert to 'on {0}'");
static const CONVERT_TO_PACKAGE_IMPORT = FixKind(
'dart.fix.convert.toPackageImport', 50, "Convert to 'package:' import");
static const CONVERT_TO_RELATIVE_IMPORT = FixKind(
diff --git a/pkg/analysis_server/lib/src/services/correction/fix_internal.dart b/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
index 56b9ab1..b2b500d 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
@@ -12,14 +12,28 @@
import 'package:analysis_server/src/services/completion/dart/utilities.dart';
import 'package:analysis_server/src/services/correction/base_processor.dart';
import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
+import 'package:analysis_server/src/services/correction/dart/add_diagnostic_property_reference.dart';
import 'package:analysis_server/src/services/correction/dart/add_field_formal_parameters.dart';
import 'package:analysis_server/src/services/correction/dart/add_return_type.dart';
+import 'package:analysis_server/src/services/correction/dart/add_type_annotation.dart';
+import 'package:analysis_server/src/services/correction/dart/convert_add_all_to_spread.dart';
+import 'package:analysis_server/src/services/correction/dart/convert_conditional_expression_to_if_element.dart';
+import 'package:analysis_server/src/services/correction/dart/convert_documentation_into_line.dart';
+import 'package:analysis_server/src/services/correction/dart/convert_map_from_iterable_to_for_literal.dart';
+import 'package:analysis_server/src/services/correction/dart/convert_quotes.dart';
import 'package:analysis_server/src/services/correction/dart/convert_to_contains.dart';
+import 'package:analysis_server/src/services/correction/dart/convert_to_expression_function_body.dart';
+import 'package:analysis_server/src/services/correction/dart/convert_to_generic_function_syntax.dart';
+import 'package:analysis_server/src/services/correction/dart/convert_to_int_literal.dart';
import 'package:analysis_server/src/services/correction/dart/convert_to_list_literal.dart';
import 'package:analysis_server/src/services/correction/dart/convert_to_map_literal.dart';
import 'package:analysis_server/src/services/correction/dart/convert_to_null_aware.dart';
+import 'package:analysis_server/src/services/correction/dart/convert_to_on_type.dart';
+import 'package:analysis_server/src/services/correction/dart/convert_to_package_import.dart';
+import 'package:analysis_server/src/services/correction/dart/convert_to_relative_import.dart';
import 'package:analysis_server/src/services/correction/dart/convert_to_set_literal.dart';
import 'package:analysis_server/src/services/correction/dart/convert_to_where_type.dart';
+import 'package:analysis_server/src/services/correction/dart/inline_invocation.dart';
import 'package:analysis_server/src/services/correction/dart/inline_typedef.dart';
import 'package:analysis_server/src/services/correction/dart/remove_dead_if_null.dart';
import 'package:analysis_server/src/services/correction/dart/remove_if_null_operator.dart';
@@ -28,6 +42,9 @@
import 'package:analysis_server/src/services/correction/dart/remove_unused_local_variable.dart';
import 'package:analysis_server/src/services/correction/dart/replace_with_eight_digit_hex.dart';
import 'package:analysis_server/src/services/correction/dart/replace_with_interpolation.dart';
+import 'package:analysis_server/src/services/correction/dart/replace_with_var.dart';
+import 'package:analysis_server/src/services/correction/dart/sort_child_property_last.dart';
+import 'package:analysis_server/src/services/correction/dart/use_curly_braces.dart';
import 'package:analysis_server/src/services/correction/dart/wrap_in_future.dart';
import 'package:analysis_server/src/services/correction/dart/wrap_in_text.dart';
import 'package:analysis_server/src/services/correction/fix.dart';
@@ -396,9 +413,6 @@
if (errorCode == ParserErrorCode.VAR_AS_TYPE_NAME) {
await _addFix_replaceVarWithDynamic();
}
- if (errorCode == ParserErrorCode.MISSING_CONST_FINAL_VAR_OR_TYPE) {
- await _addFix_addTypeAnnotation();
- }
if (errorCode == StaticWarningCode.ASSIGNMENT_TO_FINAL) {
await _addFix_makeFieldNotFinal();
}
@@ -592,10 +606,6 @@
// lints
if (errorCode is LintCode) {
var name = errorCode.name;
- if (name == LintNames.always_specify_types ||
- name == LintNames.type_annotate_public_apis) {
- await _addFix_addTypeAnnotation();
- }
if (name == LintNames.always_require_non_null_named_parameters) {
await _addFix_addRequiredAnnotation();
}
@@ -614,9 +624,6 @@
if (name == LintNames.avoid_redundant_argument_values) {
await _addFix_removeArgument();
}
- if (name == LintNames.avoid_relative_lib_imports) {
- await _addFix_convertToPackageImport();
- }
if (name == LintNames.avoid_return_types_on_setters) {
await _addFix_removeTypeAnnotation();
}
@@ -629,12 +636,6 @@
if (name == LintNames.await_only_futures) {
await _addFix_removeAwait();
}
- if (name == LintNames.curly_braces_in_flow_control_structures) {
- await _addFix_addCurlyBraces();
- }
- if (name == LintNames.diagnostic_describe_all_properties) {
- await _addFix_addDiagnosticPropertyReference();
- }
if (name == LintNames.directives_ordering) {
await _addFix_sortDirectives();
}
@@ -659,9 +660,6 @@
if (name == LintNames.null_closures) {
await _addFix_replaceNullWithClosure();
}
- if (name == LintNames.omit_local_variable_types) {
- await _addFix_replaceWithVar();
- }
if (name == LintNames.prefer_adjacent_string_concatenation) {
await _addFix_removeOperator();
}
@@ -671,12 +669,6 @@
if (errorCode.name == LintNames.prefer_const_declarations) {
await _addFix_replaceFinalWithConst();
}
- if (errorCode.name == LintNames.prefer_expression_function_bodies) {
- await _addFix_convertToExpressionBody();
- }
- if (errorCode.name == LintNames.prefer_for_elements_to_map_fromIterable) {
- await _addFix_convertMapFromIterableToForLiteral();
- }
if (errorCode.name == LintNames.prefer_equal_for_default_values) {
await _addFix_replaceColonWithEquals();
}
@@ -686,19 +678,6 @@
if (name == LintNames.prefer_final_locals) {
await _addFix_makeVariableFinal();
}
- if (name == LintNames.prefer_generic_function_type_aliases) {
- await _addFix_convertToGenericFunctionSyntax();
- }
- if (errorCode.name ==
- LintNames.prefer_if_elements_to_conditional_expressions) {
- await _addFix_convertConditionalToIfElement();
- }
- if (name == LintNames.prefer_inlined_adds) {
- await _addFix_convertToInlineAdd();
- }
- if (name == LintNames.prefer_int_literals) {
- await _addFix_convertToIntLiteral();
- }
if (name == LintNames.prefer_is_empty) {
await _addFix_replaceWithIsEmpty();
}
@@ -715,21 +694,6 @@
if (errorCode.name == LintNames.prefer_if_null_operators) {
await _addFix_convertToIfNullOperator();
}
- if (name == LintNames.prefer_relative_imports) {
- await _addFix_convertToRelativeImport();
- }
- if (name == LintNames.prefer_single_quotes) {
- await _addFix_convertSingleQuotes();
- }
- if (errorCode.name == LintNames.slash_for_doc_comments) {
- await _addFix_convertDocumentationIntoLine();
- }
- if (name == LintNames.prefer_spread_collections) {
- await _addFix_convertAddAllToSpread();
- }
- if (name == LintNames.sort_child_properties_last) {
- await _addFix_sortChildPropertiesLast();
- }
if (name == LintNames.type_init_formals) {
await _addFix_removeTypeAnnotation();
}
@@ -754,9 +718,6 @@
if (name == LintNames.unnecessary_this) {
await _addFix_removeThisExpression();
}
- if (name == LintNames.use_function_type_syntax_for_parameters) {
- await _addFix_convertToGenericFunctionSyntax();
- }
if (name == LintNames.use_rethrow_when_possible) {
await _addFix_replaceWithRethrow();
}
@@ -827,17 +788,6 @@
}
}
- Future<void> _addFix_addCurlyBraces() async {
- final changeBuilder = await createBuilder_useCurlyBraces();
- _addFixFromBuilder(changeBuilder, DartFixKind.ADD_CURLY_BRACES);
- }
-
- Future<void> _addFix_addDiagnosticPropertyReference() async {
- final changeBuilder = await createBuilder_addDiagnosticPropertyReference();
- _addFixFromBuilder(
- changeBuilder, DartFixKind.ADD_DIAGNOSTIC_PROPERTY_REFERENCE);
- }
-
Future<void> _addFix_addExplicitCast() async {
if (coveredNode is! Expression) {
return;
@@ -1303,19 +1253,6 @@
_addFixFromBuilder(changeBuilder, DartFixKind.ADD_STATIC);
}
- Future<void> _addFix_addTypeAnnotation() async {
- var changeBuilder =
- await createBuilder_addTypeAnnotation_DeclaredIdentifier();
- _addFixFromBuilder(changeBuilder, DartFixKind.ADD_TYPE_ANNOTATION);
-
- changeBuilder =
- await createBuilder_addTypeAnnotation_SimpleFormalParameter();
- _addFixFromBuilder(changeBuilder, DartFixKind.ADD_TYPE_ANNOTATION);
-
- changeBuilder = await createBuilder_addTypeAnnotation_VariableDeclaration();
- _addFixFromBuilder(changeBuilder, DartFixKind.ADD_TYPE_ANNOTATION);
- }
-
Future<void> _addFix_boolInsteadOfBoolean() async {
var changeBuilder = _newDartChangeBuilder();
await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
@@ -1447,27 +1384,6 @@
}
}
- Future<void> _addFix_convertAddAllToSpread() async {
- final change = await createBuilder_convertAddAllToSpread();
- if (change != null) {
- final kind = change.isLineInvocation
- ? DartFixKind.INLINE_INVOCATION
- : DartFixKind.CONVERT_TO_SPREAD;
- _addFixFromBuilder(change.builder, kind, args: change.args);
- }
- }
-
- Future<void> _addFix_convertConditionalToIfElement() async {
- final changeBuilder =
- await createBuilder_convertConditionalExpressionToIfElement();
- _addFixFromBuilder(changeBuilder, DartFixKind.CONVERT_TO_IF_ELEMENT);
- }
-
- Future<void> _addFix_convertDocumentationIntoLine() async {
- final changeBuilder = await createBuilder_convertDocumentationIntoLine();
- _addFixFromBuilder(changeBuilder, DartFixKind.CONVERT_TO_LINE_COMMENT);
- }
-
Future<void> _addFix_convertFlutterChild() async {
var named = flutter.findNamedExpression(node, 'child');
if (named == null) {
@@ -1533,29 +1449,6 @@
}
}
- Future<void> _addFix_convertMapFromIterableToForLiteral() async {
- final changeBuilder =
- await createBuilder_convertMapFromIterableToForLiteral();
- _addFixFromBuilder(changeBuilder, DartFixKind.CONVERT_TO_FOR_ELEMENT);
- }
-
- Future<void> _addFix_convertSingleQuotes() async {
- final changeBuilder = await createBuilder_convertQuotes(true);
- _addFixFromBuilder(
- changeBuilder, DartFixKind.CONVERT_TO_SINGLE_QUOTED_STRING);
- }
-
- Future<void> _addFix_convertToExpressionBody() async {
- final changeBuilder = await createBuilder_convertToExpressionFunctionBody();
- _addFixFromBuilder(changeBuilder, DartFixKind.CONVERT_INTO_EXPRESSION_BODY);
- }
-
- Future<void> _addFix_convertToGenericFunctionSyntax() async {
- var changeBuilder = await createBuilder_convertToGenericFunctionSyntax();
- _addFixFromBuilder(
- changeBuilder, DartFixKind.CONVERT_TO_GENERIC_FUNCTION_SYNTAX);
- }
-
Future<void> _addFix_convertToIfNullOperator() async {
var conditional = node.thisOrAncestorOfType<ConditionalExpression>();
if (conditional == null) {
@@ -1582,17 +1475,6 @@
_addFixFromBuilder(changeBuilder, DartFixKind.CONVERT_TO_IF_NULL);
}
- Future<void> _addFix_convertToInlineAdd() async {
- final changeBuilder = await createBuilder_inlineAdd();
- _addFixFromBuilder(changeBuilder, DartFixKind.INLINE_INVOCATION,
- args: ['add']);
- }
-
- Future<void> _addFix_convertToIntLiteral() async {
- final changeBuilder = await createBuilder_convertToIntLiteral();
- _addFixFromBuilder(changeBuilder, DartFixKind.CONVERT_TO_INT_LITERAL);
- }
-
Future<void> _addFix_convertToNamedArgument() async {
var argumentList = node;
if (argumentList is ArgumentList) {
@@ -1669,16 +1551,6 @@
}
}
- Future<void> _addFix_convertToPackageImport() async {
- final changeBuilder = await createBuilder_convertToPackageImport();
- _addFixFromBuilder(changeBuilder, DartFixKind.CONVERT_TO_PACKAGE_IMPORT);
- }
-
- Future<void> _addFix_convertToRelativeImport() async {
- final changeBuilder = await createBuilder_convertToRelativeImport();
- _addFixFromBuilder(changeBuilder, DartFixKind.CONVERT_TO_RELATIVE_IMPORT);
- }
-
Future<void> _addFix_createClass() async {
Element prefixElement;
String name;
@@ -4115,16 +3987,6 @@
}
}
- Future<void> _addFix_replaceWithVar() async {
- var changeBuilder = await createBuilder_replaceWithVar();
- _addFixFromBuilder(changeBuilder, DartFixKind.REPLACE_WITH_VAR);
- }
-
- Future<void> _addFix_sortChildPropertiesLast() async {
- final changeBuilder = await createBuilder_sortChildPropertyLast();
- _addFixFromBuilder(changeBuilder, DartFixKind.SORT_CHILD_PROPERTY_LAST);
- }
-
Future<void> _addFix_sortDirectives() async {
var organizer =
DirectiveOrganizer(resolvedResult.content, unit, resolvedResult.errors);
@@ -4518,6 +4380,8 @@
await compute(RemoveQuestionMark());
} else if (errorCode == CompileTimeErrorCode.NULLABLE_TYPE_IN_WITH_CLAUSE) {
await compute(RemoveQuestionMark());
+ } else if (errorCode == ParserErrorCode.MISSING_CONST_FINAL_VAR_OR_TYPE) {
+ await compute(AddTypeAnnotation());
} else if (errorCode == StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE) {
await compute(WrapInText());
} else if (errorCode == StaticWarningCode.DEAD_NULL_AWARE_EXPRESSION) {
@@ -4532,26 +4396,67 @@
var name = errorCode.name;
if (name == LintNames.always_declare_return_types) {
await compute(AddReturnType());
+ } else if (name == LintNames.always_specify_types) {
+ await compute(AddTypeAnnotation());
} else if (name == LintNames.avoid_private_typedef_functions) {
await compute(InlineTypedef());
+ } else if (name == LintNames.avoid_relative_lib_imports) {
+ await compute(ConvertToPackageImport());
} else if (name == LintNames.avoid_returning_null_for_future) {
await compute(WrapInFuture());
+ } else if (name == LintNames.avoid_types_as_parameter_names) {
+ await compute(ConvertToOnType());
+ } else if (name == LintNames.curly_braces_in_flow_control_structures) {
+ await compute(UseCurlyBraces());
+ } else if (name == LintNames.diagnostic_describe_all_properties) {
+ await compute(AddDiagnosticPropertyReference());
+ } else if (name == LintNames.omit_local_variable_types) {
+ await compute(ReplaceWithVar());
} else if (name == LintNames.prefer_collection_literals) {
await compute(ConvertToListLiteral());
await compute(ConvertToMapLiteral());
await compute(ConvertToSetLiteral());
} else if (name == LintNames.prefer_contains) {
await compute(ConvertToContains());
+ } else if (errorCode.name ==
+ LintNames.prefer_expression_function_bodies) {
+ await compute(ConvertToExpressionFunctionBody());
+ } else if (errorCode.name ==
+ LintNames.prefer_for_elements_to_map_fromIterable) {
+ await compute(ConvertMapFromIterableToForLiteral());
+ } else if (name == LintNames.prefer_generic_function_type_aliases) {
+ await compute(ConvertToGenericFunctionSyntax());
+ } else if (errorCode.name ==
+ LintNames.prefer_if_elements_to_conditional_expressions) {
+ await compute(ConvertConditionalExpressionToIfElement());
+ } else if (name == LintNames.prefer_inlined_adds) {
+ await compute(InlineInvocation());
+ } else if (name == LintNames.prefer_int_literals) {
+ await compute(ConvertToIntLiteral());
} else if (name == LintNames.prefer_interpolation_to_compose_strings) {
await compute(ReplaceWithInterpolation());
} else if (name == LintNames.prefer_iterable_whereType) {
await compute(ConvertToWhereType());
} else if (name == LintNames.prefer_null_aware_operators) {
await compute(ConvertToNullAware());
+ } else if (name == LintNames.prefer_relative_imports) {
+ await compute(ConvertToRelativeImport());
+ } else if (name == LintNames.prefer_single_quotes) {
+ await compute(ConvertToSingleQuotes());
+ } else if (name == LintNames.prefer_spread_collections) {
+ await compute(ConvertAddAllToSpread());
+ } else if (errorCode.name == LintNames.slash_for_doc_comments) {
+ await compute(ConvertDocumentationIntoLine());
+ } else if (name == LintNames.sort_child_properties_last) {
+ await compute(SortChildPropertyLast());
+ } else if (name == LintNames.type_annotate_public_apis) {
+ await compute(AddTypeAnnotation());
} else if (name == LintNames.unnecessary_null_in_if_null_operators) {
await compute(RemoveIfNullOperator());
} else if (name == LintNames.use_full_hex_values_for_flutter_colors) {
await compute(ReplaceWithEightDigitHex());
+ } else if (name == LintNames.use_function_type_syntax_for_parameters) {
+ await compute(ConvertToGenericFunctionSyntax());
}
}
}
diff --git a/pkg/analysis_server/lib/src/services/linter/lint_names.dart b/pkg/analysis_server/lib/src/services/linter/lint_names.dart
index 345d7d7..187c91b 100644
--- a/pkg/analysis_server/lib/src/services/linter/lint_names.dart
+++ b/pkg/analysis_server/lib/src/services/linter/lint_names.dart
@@ -23,6 +23,8 @@
'avoid_return_types_on_setters';
static const String avoid_returning_null_for_future =
'avoid_returning_null_for_future';
+ static const String avoid_types_as_parameter_names =
+ 'avoid_types_as_parameter_names';
static const String avoid_types_on_closure_parameters =
'avoid_types_on_closure_parameters';
static const String await_only_futures = 'await_only_futures';
diff --git a/pkg/analysis_server/lib/src/services/refactoring/convert_getter_to_method.dart b/pkg/analysis_server/lib/src/services/refactoring/convert_getter_to_method.dart
index 9253e3b..d1436b8 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/convert_getter_to_method.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/convert_getter_to_method.dart
@@ -46,8 +46,6 @@
@override
Future<SourceChange> createChange() async {
- // TODO(brianwilkerson) Determine whether this await is necessary.
- await null;
change = SourceChange(refactoringName);
// function
if (element.enclosingElement is CompilationUnitElement) {
@@ -59,8 +57,6 @@
FieldElement field = element.variable;
var elements = await getHierarchyMembers(searchEngine, field);
await Future.forEach(elements, (ClassMemberElement member) async {
- // TODO(brianwilkerson) Determine whether this await is necessary.
- await null;
if (member is FieldElement) {
var getter = member.getter;
if (!getter.isSynthetic) {
@@ -84,8 +80,6 @@
Future<void> _updateElementDeclaration(
PropertyAccessorElement element) async {
- // TODO(brianwilkerson) Determine whether this await is necessary.
- await null;
// prepare "get" keyword
Token getKeyword;
{
@@ -115,8 +109,6 @@
}
Future _updateElementReferences(Element element) async {
- // TODO(brianwilkerson) Determine whether this await is necessary.
- await null;
var matches = await searchEngine.searchReferences(element);
var references = getSourceReferences(matches);
for (var reference in references) {
diff --git a/pkg/analysis_server/lib/src/services/refactoring/convert_method_to_getter.dart b/pkg/analysis_server/lib/src/services/refactoring/convert_method_to_getter.dart
index 6744118..416e5f2 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/convert_method_to_getter.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/convert_method_to_getter.dart
@@ -39,8 +39,6 @@
@override
Future<RefactoringStatus> checkInitialConditions() async {
- // TODO(brianwilkerson) Determine whether this await is necessary.
- await null;
// check Element type
if (element is FunctionElement) {
if (element.enclosingElement is! CompilationUnitElement) {
@@ -67,8 +65,6 @@
@override
Future<SourceChange> createChange() async {
- // TODO(brianwilkerson) Determine whether this await is necessary.
- await null;
change = SourceChange(refactoringName);
// FunctionElement
if (element is FunctionElement) {
@@ -80,8 +76,6 @@
MethodElement method = element;
var elements = await getHierarchyMembers(searchEngine, method);
await Future.forEach(elements, (Element element) async {
- // TODO(brianwilkerson) Determine whether this await is necessary.
- await null;
await _updateElementDeclaration(element);
return _updateElementReferences(element);
});
@@ -91,8 +85,6 @@
}
Future<void> _updateElementDeclaration(Element element) async {
- // TODO(brianwilkerson) Determine whether this await is necessary.
- await null;
// prepare parameters
FormalParameterList parameters;
{
@@ -119,8 +111,6 @@
}
Future<void> _updateElementReferences(Element element) async {
- // TODO(brianwilkerson) Determine whether this await is necessary.
- await null;
var matches = await searchEngine.searchReferences(element);
var references = getSourceReferences(matches);
for (var reference in references) {
diff --git a/pkg/analysis_server/lib/src/services/refactoring/extract_method.dart b/pkg/analysis_server/lib/src/services/refactoring/extract_method.dart
index 7818889..8aa4a78 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/extract_method.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/extract_method.dart
@@ -179,8 +179,6 @@
@override
Future<RefactoringStatus> checkFinalConditions() async {
- // TODO(brianwilkerson) Determine whether this await is necessary.
- await null;
var result = RefactoringStatus();
result.addStatus(validateMethodName(name));
result.addStatus(_checkParameterNames());
@@ -191,8 +189,6 @@
@override
Future<RefactoringStatus> checkInitialConditions() async {
- // TODO(brianwilkerson) Determine whether this await is necessary.
- await null;
var result = RefactoringStatus();
// selection
result.addStatus(_checkSelection());
@@ -231,8 +227,6 @@
@override
Future<SourceChange> createChange() async {
- // TODO(brianwilkerson) Determine whether this await is necessary.
- await null;
var change = SourceChange(refactoringName);
// replace occurrences with method invocation
for (var occurrence in _occurrences) {
@@ -431,8 +425,6 @@
/// Checks if created method will shadow or will be shadowed by other
/// elements.
Future<RefactoringStatus> _checkPossibleConflicts() async {
- // TODO(brianwilkerson) Determine whether this await is necessary.
- await null;
var result = RefactoringStatus();
var parent = _parentMember.parent;
// top-level function
@@ -701,8 +693,6 @@
/// Prepares information about used variables, which should be turned into
/// parameters.
Future<RefactoringStatus> _initializeParameters() async {
- // TODO(brianwilkerson) Determine whether this await is necessary.
- await null;
_parameters.clear();
_parametersMap.clear();
_parameterReferencesMap.clear();
@@ -766,8 +756,6 @@
}
Future<void> _initializeReturnType() async {
- // TODO(brianwilkerson) Determine whether this await is necessary.
- await null;
var typeProvider = await resolveResult.typeProvider;
if (_selectionFunctionExpression != null) {
variableType = '';
diff --git a/pkg/analysis_server/lib/src/services/refactoring/extract_widget.dart b/pkg/analysis_server/lib/src/services/refactoring/extract_widget.dart
index 843a254..6726707 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/extract_widget.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/extract_widget.dart
@@ -94,8 +94,6 @@
@override
Future<RefactoringStatus> checkFinalConditions() async {
- // TODO(brianwilkerson) Determine whether this await is necessary.
- await null;
var result = RefactoringStatus();
result.addStatus(validateClassName(name));
return result;
@@ -103,8 +101,6 @@
@override
Future<RefactoringStatus> checkInitialConditions() async {
- // TODO(brianwilkerson) Determine whether this await is necessary.
- await null;
var result = RefactoringStatus();
result.addStatus(_checkSelection());
@@ -146,8 +142,6 @@
@override
Future<SourceChange> createChange() async {
- // TODO(brianwilkerson) Determine whether this await is necessary.
- await null;
var changeBuilder = DartChangeBuilder(sessionHelper.session);
await changeBuilder.addFileEdit(resolveResult.path, (builder) {
if (_expression != null) {
@@ -241,13 +235,9 @@
}
Future<RefactoringStatus> _initializeClasses() async {
- // TODO(brianwilkerson) Determine whether this await is necessary.
- await null;
var result = RefactoringStatus();
Future<ClassElement> getClass(String name) async {
- // TODO(brianwilkerson) Determine whether this await is necessary.
- await null;
var element = await sessionHelper.getClass(flutter.widgetsUri, name);
if (element == null) {
result.addFatalError(
@@ -258,8 +248,6 @@
}
Future<PropertyAccessorElement> getAccessor(String uri, String name) async {
- // TODO(brianwilkerson) Determine whether this await is necessary.
- await null;
var element = await sessionHelper.getTopLevelPropertyAccessor(uri, name);
if (element == null) {
result.addFatalError("Unable to find 'required' in $uri");
@@ -280,8 +268,6 @@
/// Prepare referenced local variables and fields, that should be turned
/// into the widget class fields and constructor parameters.
Future<RefactoringStatus> _initializeParameters() async {
- // TODO(brianwilkerson) Determine whether this await is necessary.
- await null;
_ParametersCollector collector;
if (_expression != null) {
var localRange = range.node(_expression);
diff --git a/pkg/analysis_server/lib/src/services/refactoring/inline_local.dart b/pkg/analysis_server/lib/src/services/refactoring/inline_local.dart
index f5e2e3f..1ad6b64 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/inline_local.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/inline_local.dart
@@ -63,8 +63,6 @@
@override
Future<RefactoringStatus> checkInitialConditions() async {
- // TODO(brianwilkerson) Determine whether this await is necessary.
- await null;
var result = RefactoringStatus();
// prepare variable
{
diff --git a/pkg/analysis_server/lib/src/services/refactoring/inline_method.dart b/pkg/analysis_server/lib/src/services/refactoring/inline_method.dart
index a35aa2a..00e267f 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/inline_method.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/inline_method.dart
@@ -263,8 +263,6 @@
@override
Future<RefactoringStatus> checkInitialConditions() async {
- // TODO(brianwilkerson) Determine whether this await is necessary.
- await null;
var result = RefactoringStatus();
// prepare method information
result.addStatus(await _prepareMethod());
@@ -311,8 +309,6 @@
/// Initializes [_methodElement] and related fields.
Future<RefactoringStatus> _prepareMethod() async {
- // TODO(brianwilkerson) Determine whether this await is necessary.
- await null;
_methodElement = null;
_methodParameters = null;
_methodBody = null;
@@ -423,8 +419,6 @@
_ReferenceProcessor(this.ref, this.reference);
Future<void> init() async {
- // TODO(brianwilkerson) Determine whether this await is necessary.
- await null;
refElement = reference.element;
// prepare CorrectionUtils
diff --git a/pkg/analysis_server/lib/src/services/refactoring/refactoring_internal.dart b/pkg/analysis_server/lib/src/services/refactoring/refactoring_internal.dart
index b32654d..bb06cec 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/refactoring_internal.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/refactoring_internal.dart
@@ -40,8 +40,6 @@
@override
Future<RefactoringStatus> checkAllConditions() async {
- // TODO(brianwilkerson) Determine whether this await is necessary.
- await null;
var result = RefactoringStatus();
result.addStatus(await checkInitialConditions());
if (result.hasFatalError) {
diff --git a/pkg/analysis_server/lib/src/services/refactoring/rename.dart b/pkg/analysis_server/lib/src/services/refactoring/rename.dart
index 371f720..4e4caef 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/rename.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/rename.dart
@@ -104,8 +104,6 @@
@override
Future<SourceChange> createChange() async {
- // TODO(brianwilkerson) Determine whether this await is necessary.
- await null;
var changeName = "$refactoringName '$oldName' to '$newName'";
change = SourceChange(changeName);
await fillChange();
diff --git a/pkg/analysis_server/lib/src/services/refactoring/rename_class_member.dart b/pkg/analysis_server/lib/src/services/refactoring/rename_class_member.dart
index 38fc012..75d6ce5 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/rename_class_member.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/rename_class_member.dart
@@ -66,8 +66,6 @@
@override
Future<RefactoringStatus> checkInitialConditions() async {
- // TODO(brianwilkerson) Determine whether this await is necessary.
- await null;
var result = await super.checkInitialConditions();
if (element is MethodElement && (element as MethodElement).isOperator) {
result.addFatalError('Cannot rename operator.');
@@ -160,8 +158,6 @@
elementKind = element.kind;
Future<RefactoringStatus> validate() async {
- // TODO(brianwilkerson) Determine whether this await is necessary.
- await null;
// check if there is a member with "newName" in the same ClassElement
for (var newNameMember in getChildren(elementClass, name)) {
result.addError(
@@ -292,8 +288,6 @@
/// Fills [elements] with [Element]s to rename.
Future _prepareElements() async {
- // TODO(brianwilkerson) Determine whether this await is necessary.
- await null;
if (element is ClassMemberElement) {
elements = await getHierarchyMembers(searchEngine, element);
} else {
@@ -303,15 +297,11 @@
/// Fills [references] with all references to [elements].
Future _prepareReferences() async {
- // TODO(brianwilkerson) Determine whether this await is necessary.
- await null;
if (!isRename) {
return Future.value();
}
await _prepareElements();
await Future.forEach(elements, (Element element) async {
- // TODO(brianwilkerson) Determine whether this await is necessary.
- await null;
var elementReferences = await searchEngine.searchReferences(element);
references.addAll(elementReferences);
});
diff --git a/pkg/analysis_server/lib/src/services/refactoring/rename_constructor.dart b/pkg/analysis_server/lib/src/services/refactoring/rename_constructor.dart
index 9376f8a..1ea0e0d 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/rename_constructor.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/rename_constructor.dart
@@ -56,8 +56,6 @@
@override
Future<void> fillChange() async {
- // TODO(brianwilkerson) Determine whether this await is necessary.
- await null;
// prepare references
var matches = await searchEngine.searchReferences(element);
var references = getSourceReferences(matches);
@@ -110,8 +108,6 @@
}
Future<void> _replaceSynthetic() async {
- // TODO(brianwilkerson) Determine whether this await is necessary.
- await null;
var classElement = element.enclosingElement;
var result = await AnalysisSessionHelper(session)
diff --git a/pkg/analysis_server/lib/src/services/refactoring/rename_import.dart b/pkg/analysis_server/lib/src/services/refactoring/rename_import.dart
index 0876e3a..1183fcc 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/rename_import.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/rename_import.dart
@@ -48,8 +48,6 @@
@override
Future<void> fillChange() async {
- // TODO(brianwilkerson) Determine whether this await is necessary.
- await null;
// update declaration
{
var prefix = element.prefix;
diff --git a/pkg/analysis_server/lib/src/services/refactoring/rename_unit_member.dart b/pkg/analysis_server/lib/src/services/refactoring/rename_unit_member.dart
index e6306ba..b3c18ef 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/rename_unit_member.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/rename_unit_member.dart
@@ -186,8 +186,6 @@
}
Future<RefactoringStatus> validate() async {
- // TODO(brianwilkerson) Determine whether this await is necessary.
- await null;
_validateWillConflict();
if (isRename) {
references = await searchEngine.searchReferences(element);
@@ -271,8 +269,6 @@
/// Validates if renamed [element] will shadow any [Element] named [name].
Future _validateWillShadow() async {
- // TODO(brianwilkerson) Determine whether this await is necessary.
- await null;
var declarations = await searchEngine.searchMemberDeclarations(name);
for (var declaration in declarations) {
var member = declaration.element;
diff --git a/pkg/analysis_server/lib/src/services/search/hierarchy.dart b/pkg/analysis_server/lib/src/services/search/hierarchy.dart
index 59cccd8..9f600f3 100644
--- a/pkg/analysis_server/lib/src/services/search/hierarchy.dart
+++ b/pkg/analysis_server/lib/src/services/search/hierarchy.dart
@@ -51,8 +51,6 @@
/// Returns a [Set] with direct subclasses of [seed].
Future<Set<ClassElement>> getDirectSubClasses(
SearchEngine searchEngine, ClassElement seed) async {
- // TODO(brianwilkerson) Determine whether this await is necessary.
- await null;
var matches = await searchEngine.searchSubtypes(seed);
return matches.map((match) => match.element).cast<ClassElement>().toSet();
}
@@ -83,8 +81,6 @@
/// their subclasses.
Future<Set<ClassMemberElement>> getHierarchyMembers(
SearchEngine searchEngine, ClassMemberElement member) async {
- // TODO(brianwilkerson) Determine whether this await is necessary.
- await null;
Set<ClassMemberElement> result = HashSet<ClassMemberElement>();
// extension member
if (member.enclosingElement is ExtensionElement) {
@@ -125,8 +121,6 @@
/// corresponding named parameters in the method hierarchy.
Future<List<ParameterElement>> getHierarchyNamedParameters(
SearchEngine searchEngine, ParameterElement element) async {
- // TODO(brianwilkerson) Determine whether this await is necessary.
- await null;
if (element.isNamed) {
var method = element.enclosingElement;
if (method is MethodElement) {
diff --git a/pkg/analysis_server/lib/src/services/search/search_engine_internal.dart b/pkg/analysis_server/lib/src/services/search/search_engine_internal.dart
index 968e7a1..b680a98 100644
--- a/pkg/analysis_server/lib/src/services/search/search_engine_internal.dart
+++ b/pkg/analysis_server/lib/src/services/search/search_engine_internal.dart
@@ -18,8 +18,6 @@
@override
Future<Set<String>> membersOfSubtypes(ClassElement type) async {
- // TODO(brianwilkerson) Determine whether this await is necessary.
- await null;
var drivers = _drivers.toList();
var searchedFiles = _createSearchedFiles(drivers);
@@ -29,8 +27,6 @@
var members = <String>{};
Future<void> addMembers(ClassElement type, SubtypeResult subtype) async {
- // TODO(brianwilkerson) Determine whether this await is necessary.
- await null;
if (subtype != null && !visitedIds.add(subtype.id)) {
return;
}
@@ -57,13 +53,9 @@
@override
Future<Set<ClassElement>> searchAllSubtypes(ClassElement type) async {
- // TODO(brianwilkerson) Determine whether this await is necessary.
- await null;
var allSubtypes = <ClassElement>{};
Future<void> addSubtypes(ClassElement type) async {
- // TODO(brianwilkerson) Determine whether this await is necessary.
- await null;
var directResults = await _searchDirectSubtypes(type);
for (var directResult in directResults) {
var directSubtype = directResult.enclosingElement as ClassElement;
@@ -79,8 +71,6 @@
@override
Future<List<SearchMatch>> searchMemberDeclarations(String name) async {
- // TODO(brianwilkerson) Determine whether this await is necessary.
- await null;
var allDeclarations = <SearchMatch>[];
var drivers = _drivers.toList();
for (var driver in drivers) {
@@ -92,8 +82,6 @@
@override
Future<List<SearchMatch>> searchMemberReferences(String name) async {
- // TODO(brianwilkerson) Determine whether this await is necessary.
- await null;
var allResults = <SearchResult>[];
var drivers = _drivers.toList();
var searchedFiles = _createSearchedFiles(drivers);
@@ -107,8 +95,6 @@
@override
Future<List<SearchMatch>> searchReferences(Element element) async {
- // TODO(brianwilkerson) Determine whether this await is necessary.
- await null;
var allResults = <SearchResult>[];
var drivers = _drivers.toList();
var searchedFiles = _createSearchedFiles(drivers);
@@ -121,16 +107,12 @@
@override
Future<List<SearchMatch>> searchSubtypes(ClassElement type) async {
- // TODO(brianwilkerson) Determine whether this await is necessary.
- await null;
var results = await _searchDirectSubtypes(type);
return results.map(SearchMatchImpl.forSearchResult).toList();
}
@override
Future<List<SearchMatch>> searchTopLevelDeclarations(String pattern) async {
- // TODO(brianwilkerson) Determine whether this await is necessary.
- await null;
var allElements = <Element>{};
var regExp = RegExp(pattern);
var drivers = _drivers.toList();
@@ -152,8 +134,6 @@
}
Future<List<SearchResult>> _searchDirectSubtypes(ClassElement type) async {
- // TODO(brianwilkerson) Determine whether this await is necessary.
- await null;
var allResults = <SearchResult>[];
var drivers = _drivers.toList();
var searchedFiles = _createSearchedFiles(drivers);
diff --git a/pkg/analysis_server/lib/src/status/element_writer.dart b/pkg/analysis_server/lib/src/status/element_writer.dart
index 929313a..71f5835 100644
--- a/pkg/analysis_server/lib/src/status/element_writer.dart
+++ b/pkg/analysis_server/lib/src/status/element_writer.dart
@@ -145,7 +145,6 @@
properties['typeParameters'] = element.typeParameters;
}
if (element is VariableElement) {
- properties['constantValue'] = element.constantValue;
properties['hasImplicitType'] = element.hasImplicitType;
properties['isConst'] = element.isConst;
properties['isFinal'] = element.isFinal;
diff --git a/pkg/analysis_server/lib/src/status/pages.dart b/pkg/analysis_server/lib/src/status/pages.dart
index 2a83d87..795b8c9 100644
--- a/pkg/analysis_server/lib/src/status/pages.dart
+++ b/pkg/analysis_server/lib/src/status/pages.dart
@@ -32,8 +32,6 @@
String get path => '/$id';
Future<void> asyncDiv(void Function() gen, {String classes}) async {
- // TODO(brianwilkerson) Determine whether this await is necessary.
- await null;
if (classes != null) {
buf.writeln('<div class="$classes">');
} else {
@@ -60,8 +58,6 @@
}
Future<String> generate(Map<String, String> params) async {
- // TODO(brianwilkerson) Determine whether this await is necessary.
- await null;
buf.clear();
// TODO(brianwilkerson) Determine if await is necessary, if so, change the
// return type of [generatePage] to `Future<void>`.
@@ -155,8 +151,6 @@
Page createUnknownPage(String unknownPath);
Future<void> handleGetRequest(HttpRequest request) async {
- // TODO(brianwilkerson) Determine whether this await is necessary.
- await null;
try {
var path = request.uri.path;
@@ -195,8 +189,6 @@
Page page, [
int code = HttpStatus.ok,
]) async {
- // TODO(brianwilkerson) Determine whether this await is necessary.
- await null;
var response = request.response;
response.statusCode = code;
response.headers.contentType = ContentType.html;
@@ -204,10 +196,26 @@
await response.close();
}
+ Future<void> respondJson(
+ HttpRequest request,
+ Map<String, Object> json, [
+ int code = HttpStatus.ok,
+ ]) async {
+ var response = request.response;
+ response.statusCode = code;
+ response.headers.contentType = ContentType.json;
+ response.write(jsonEncode(json));
+ await response.close();
+ }
+
Future<void> respondOk(
HttpRequest request, {
int code = HttpStatus.ok,
}) async {
+ if (request.headers.contentType.subType == 'json') {
+ return respondJson(request, {'success': true}, code);
+ }
+
var response = request.response;
response.statusCode = code;
await response.close();
diff --git a/pkg/analysis_server/lib/src/utilities/extensions/ast.dart b/pkg/analysis_server/lib/src/utilities/extensions/ast.dart
new file mode 100644
index 0000000..20a9324
--- /dev/null
+++ b/pkg/analysis_server/lib/src/utilities/extensions/ast.dart
@@ -0,0 +1,53 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analyzer/dart/ast/ast.dart';
+
+/// Extensions for [AstNode]s
+extension AstNodeExtensions on AstNode {
+ bool get inAsyncMethodOrFunction {
+ var body = thisOrAncestorOfType<FunctionBody>();
+ return body != null && body.isAsynchronous && body.star == null;
+ }
+
+ bool get inAsyncStarOrSyncStarMethodOrFunction {
+ var body = thisOrAncestorOfType<FunctionBody>();
+ return body != null && body.keyword != null && body.star != null;
+ }
+
+ bool get inCatchClause => thisOrAncestorOfType<CatchClause>() != null;
+
+ bool get inClassMemberBody {
+ var node = this;
+ while (true) {
+ var body = node.thisOrAncestorOfType<FunctionBody>();
+ if (body == null) {
+ return false;
+ }
+ var parent = body.parent;
+ if (parent is ConstructorDeclaration || parent is MethodDeclaration) {
+ return true;
+ }
+ node = parent;
+ }
+ }
+
+ bool get inDoLoop => thisOrAncestorOfType<DoStatement>() != null;
+
+ bool get inForLoop =>
+ thisOrAncestorMatching((p) => p is ForStatement) != null;
+
+ bool get inLoop => inDoLoop || inForLoop || inWhileLoop;
+
+ bool get inSwitch => thisOrAncestorOfType<SwitchStatement>() != null;
+
+ bool get inWhileLoop => thisOrAncestorOfType<WhileStatement>() != null;
+}
+
+/// Extensions for [FunctionBody]s
+extension FunctionBodyExtensions on FunctionBody {
+ bool get isEmpty =>
+ this is EmptyFunctionBody ||
+ (this is BlockFunctionBody && beginToken.isSynthetic);
+}
diff --git a/pkg/analysis_server/lib/src/utilities/mocks.dart b/pkg/analysis_server/lib/src/utilities/mocks.dart
index 1552225..1602ed4 100644
--- a/pkg/analysis_server/lib/src/utilities/mocks.dart
+++ b/pkg/analysis_server/lib/src/utilities/mocks.dart
@@ -148,6 +148,12 @@
Map<PluginInfo, Future<plugin.Response>> broadcastResults;
@override
+ List<PluginInfo> plugins = [];
+
+ StreamController<void> pluginsChangedController =
+ StreamController.broadcast();
+
+ @override
String get byteStorePath {
fail('Unexpected invocation of byteStorePath');
}
@@ -163,9 +169,7 @@
}
@override
- List<PluginInfo> get plugins {
- fail('Unexpected invocation of plugins');
- }
+ Stream<void> get pluginsChanged => pluginsChangedController.stream;
@override
ResourceProvider get resourceProvider {
diff --git a/pkg/analysis_server/test/domain_edit_dartfix_test.dart b/pkg/analysis_server/test/domain_edit_dartfix_test.dart
index 7cff0de..70b8662 100644
--- a/pkg/analysis_server/test/domain_edit_dartfix_test.dart
+++ b/pkg/analysis_server/test/domain_edit_dartfix_test.dart
@@ -68,7 +68,7 @@
var fix = EditDartFix(server, request);
final response = await fix.compute();
- fix.nonNullableFixTask?.server?.close();
+ fix.nonNullableFixTask?.shutdownServer();
expect(response.id, id);
return response;
}
diff --git a/pkg/analysis_server/test/lsp/folding_test.dart b/pkg/analysis_server/test/lsp/folding_test.dart
index b27ea0b..49dc5ce 100644
--- a/pkg/analysis_server/test/lsp/folding_test.dart
+++ b/pkg/analysis_server/test/lsp/folding_test.dart
@@ -3,6 +3,8 @@
// BSD-style license that can be found in the LICENSE file.
import 'package:analysis_server/lsp_protocol/protocol_generated.dart';
+import 'package:analyzer_plugin/protocol/protocol_common.dart' as plugin;
+import 'package:analyzer_plugin/protocol/protocol_generated.dart' as plugin;
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
@@ -66,6 +68,65 @@
expect(regions, unorderedEquals(expectedRegions));
}
+ Future<void> test_fromPlugins_dartFile() async {
+ final pluginAnalyzedFilePath = join(projectFolderPath, 'lib', 'foo.dart');
+ final pluginAnalyzedUri = Uri.file(pluginAnalyzedFilePath);
+
+ const content = '''
+ // [[contributed by fake plugin]]
+
+ class AnnotatedDartClass {[[
+ // content of dart class, contributed by server
+ ]]}
+ ''';
+ final ranges = rangesFromMarkers(content);
+ final withoutMarkers = withoutRangeMarkers(content);
+ newFile(pluginAnalyzedFilePath);
+
+ await initialize();
+ await openFile(pluginAnalyzedUri, withoutMarkers);
+
+ final pluginResult = plugin.AnalysisFoldingParams(
+ pluginAnalyzedFilePath,
+ [plugin.FoldingRegion(plugin.FoldingKind.DIRECTIVES, 7, 26)],
+ );
+ configureTestPlugin(notification: pluginResult.toNotification());
+
+ final res = await getFoldingRegions(pluginAnalyzedUri);
+ expect(
+ res,
+ unorderedEquals([
+ _toFoldingRange(ranges[0], FoldingRangeKind.Imports),
+ _toFoldingRange(ranges[1], null),
+ ]),
+ );
+ }
+
+ Future<void> test_fromPlugins_nonDartFile() async {
+ final pluginAnalyzedFilePath = join(projectFolderPath, 'lib', 'foo.sql');
+ final pluginAnalyzedUri = Uri.file(pluginAnalyzedFilePath);
+ const content = '''
+ CREATE TABLE foo(
+ [[-- some columns]]
+ );
+ ''';
+ final withoutMarkers = withoutRangeMarkers(content);
+ newFile(pluginAnalyzedFilePath, content: withoutMarkers);
+
+ await initialize();
+ await openFile(pluginAnalyzedUri, withoutMarkers);
+
+ final pluginResult = plugin.AnalysisFoldingParams(
+ pluginAnalyzedFilePath,
+ [plugin.FoldingRegion(plugin.FoldingKind.CLASS_BODY, 33, 15)],
+ );
+ configureTestPlugin(notification: pluginResult.toNotification());
+
+ final res = await getFoldingRegions(pluginAnalyzedUri);
+ final expectedRange = rangeFromMarkers(content);
+ expect(res, [_toFoldingRange(expectedRange, null)]);
+ }
+
Future<void> test_headersImportsComments() async {
// TODO(dantup): Review why the file header and the method comment ranges
// are different... one spans only the range to collapse, but the other
diff --git a/pkg/analysis_server/test/lsp/initialization_test.dart b/pkg/analysis_server/test/lsp/initialization_test.dart
index 0d0421f..2d132bb 100644
--- a/pkg/analysis_server/test/lsp/initialization_test.dart
+++ b/pkg/analysis_server/test/lsp/initialization_test.dart
@@ -5,7 +5,8 @@
import 'package:analysis_server/lsp_protocol/protocol_generated.dart';
import 'package:analysis_server/lsp_protocol/protocol_special.dart';
import 'package:analysis_server/src/lsp/constants.dart';
-import 'package:analysis_server/src/lsp/handlers/handler_initialize.dart';
+import 'package:analysis_server/src/lsp/server_capabilities_computer.dart';
+import 'package:analysis_server/src/plugin/plugin_manager.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
@@ -185,6 +186,95 @@
}
}
+ Future<void> test_dynamicRegistration_unregistersOutdatedAfterChange() async {
+ // Initialize by supporting dynamic registrations everywhere
+ List<Registration> registrations;
+ await handleExpectedRequest<ResponseMessage, RegistrationParams, void>(
+ Method.client_registerCapability,
+ () => initialize(
+ textDocumentCapabilities: withAllSupportedDynamicRegistrations(
+ emptyTextDocumentClientCapabilities)),
+ handler: (registrationParams) =>
+ registrations = registrationParams.registrations,
+ );
+
+ final unregisterRequest =
+ await expectRequest(Method.client_unregisterCapability, () {
+ final plugin = configureTestPlugin();
+ plugin.currentSession = PluginSession(plugin)
+ ..interestingFiles = ['*.foo'];
+ pluginManager.pluginsChangedController.add(null);
+ });
+ final unregistrations =
+ (unregisterRequest.params as UnregistrationParams).unregisterations;
+
+ // folding method should have been unregistered as the server now supports
+ // *.foo files for it as well.
+ final registrationIdForFolding = registrations
+ .singleWhere((r) => r.method == 'textDocument/foldingRange')
+ .id;
+ expect(
+ unregistrations,
+ contains(isA<Unregistration>()
+ .having((r) => r.method, 'method', 'textDocument/foldingRange')
+ .having((r) => r.id, 'id', registrationIdForFolding)),
+ );
+
+ // Renaming documents is a Dart-specific service that should not have been
+ // affected by the plugin change.
+ final registrationIdForRename =
+ registrations.singleWhere((r) => r.method == 'textDocument/rename').id;
+ expect(
+ unregistrations,
+ isNot(contains(isA<Unregistration>()
+ .having((r) => r.id, 'id', registrationIdForRename))));
+ }
+
+ Future<void> test_dynamicRegistration_updatesWithPlugins() async {
+ await initialize(
+ textDocumentCapabilities:
+ extendTextDocumentCapabilities(emptyTextDocumentClientCapabilities, {
+ 'foldingRange': {'dynamicRegistration': true},
+ }),
+ );
+
+ // The server will send an unregister request followed by another register
+ // request to change document filter on folding. We need to respond to the
+ // unregister request as the server awaits that.
+ requestsFromServer
+ .firstWhere((r) => r.method == Method.client_unregisterCapability)
+ .then((request) {
+ respondTo(request, null);
+ return (request.params as UnregistrationParams).unregisterations;
+ });
+
+ final request = await expectRequest(Method.client_registerCapability, () {
+ final plugin = configureTestPlugin();
+ plugin.currentSession = PluginSession(plugin)
+ ..interestingFiles = ['*.sql'];
+ pluginManager.pluginsChangedController.add(null);
+ });
+
+ final registrations = (request.params as RegistrationParams).registrations;
+
+ final documentFilterSql = DocumentFilter(null, 'file', '**/*.sql');
+ final documentFilterDart = DocumentFilter('dart', 'file', null);
+ final expectedFoldingRegistration =
+ isA<TextDocumentRegistrationOptions>().having(
+ (o) => o.documentSelector,
+ 'documentSelector',
+ containsAll([documentFilterSql, documentFilterDart]),
+ );
+
+ expect(
+ registrations,
+ contains(isA<Registration>()
+ .having((r) => r.method, 'method', 'textDocument/foldingRange')
+ .having((r) => r.registerOptions, 'registerOptions',
+ expectedFoldingRegistration)),
+ );
+ }
+
Future<void> test_initialize() async {
final response = await initialize();
expect(response, isNotNull);
diff --git a/pkg/analysis_server/test/lsp/server_abstract.dart b/pkg/analysis_server/test/lsp/server_abstract.dart
index ebd7388..b009198 100644
--- a/pkg/analysis_server/test/lsp/server_abstract.dart
+++ b/pkg/analysis_server/test/lsp/server_abstract.dart
@@ -49,11 +49,25 @@
@override
Stream<Message> get serverToClient => channel.serverToClient;
- void configureTestPlugin({plugin.ResponseResult respondWith}) {
- PluginInfo info = DiscoveredPluginInfo('a', 'b', 'c', null, null);
- pluginManager.broadcastResults = <PluginInfo, Future<plugin.Response>>{
- info: Future.value(respondWith.toResponse('-', 1))
- };
+ DiscoveredPluginInfo configureTestPlugin({
+ plugin.ResponseResult respondWith,
+ plugin.Notification notification,
+ }) {
+ final info = DiscoveredPluginInfo('a', 'b', 'c', null, null);
+ pluginManager.plugins.add(info);
+
+ if (respondWith != null) {
+ pluginManager.broadcastResults = <PluginInfo, Future<plugin.Response>>{
+ info: Future.value(respondWith.toResponse('-', 1))
+ };
+ }
+
+ if (notification != null) {
+ server.notificationManager
+ .handlePluginNotification(info.pluginId, notification);
+ }
+
+ return info;
}
/// Sends a request to the server and unwraps the result. Throws if the
diff --git a/pkg/analysis_server/test/services/completion/dart/override_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/override_contributor_test.dart
index ff816cc..9fd7549 100644
--- a/pkg/analysis_server/test/services/completion/dart/override_contributor_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/override_contributor_test.dart
@@ -285,6 +285,69 @@
selectionLength: 22);
}
+ Future<void> test_no_target_inClass_of_interface() async {
+ addTestSource('''
+class A {
+ void foo() {}
+}
+
+class B implements A {
+ ^
+}
+''');
+ await computeSuggestions();
+ _assertOverride('''
+@override
+ void foo() {
+ // TODO: implement foo
+ }''', displayText: 'foo() { … }', selectionOffset: 51, selectionLength: 0);
+ }
+
+ Future<void> test_no_target_inComment() async {
+ addTestSource('''
+class A {
+ void foo() {}
+}
+
+class B implements A {
+ // comment ^
+ void m() {}
+}
+''');
+ await computeSuggestions();
+ _assertNoOverrideContaining('foo');
+ }
+
+ Future<void> test_no_target_inComment2() async {
+ addTestSource('''
+class A {
+ void foo() {}
+}
+
+class B implements A {
+ /// dartdoc ^
+ void m() {}
+}
+''');
+ await computeSuggestions();
+ _assertNoOverrideContaining('foo');
+ }
+
+ Future<void> test_no_target_inComment3() async {
+ addTestSource('''
+class A {
+ void foo() {}
+}
+
+class B implements A {
+ /// Asdf [St^]
+ void m() {}
+}
+''');
+ await computeSuggestions();
+ _assertNoOverrideContaining('foo');
+ }
+
Future<void> test_outsideOfWorkspace() async {
testFile = convertPath('/home/other/lib/a.dart');
addTestSource('''
diff --git a/pkg/analysis_server/test/src/cider/completion_test.dart b/pkg/analysis_server/test/src/cider/completion_test.dart
index 1d14888..9aedd3f 100644
--- a/pkg/analysis_server/test/src/cider/completion_test.dart
+++ b/pkg/analysis_server/test/src/cider/completion_test.dart
@@ -22,6 +22,7 @@
class CiderCompletionComputerTest extends CiderServiceTest {
final CiderCompletionCache _completionCache = CiderCompletionCache();
+ CiderCompletionComputer _computer;
CiderCompletionResult _completionResult;
List<CompletionSuggestion> _suggestions;
@@ -44,7 +45,7 @@
// ignore: deprecated_member_use_from_same_package
_suggestions = await _newComputer().compute(
- testPath,
+ convertPath(testPath),
context.offset,
);
@@ -78,6 +79,22 @@
_assertNoClass(text: 'Random');
}
+ Future<void> test_compute2_sameSignature_sameResult() async {
+ _createFileResolver();
+ await _compute2(r'''
+var a = ^;
+''');
+ var lastResult = _completionResult;
+
+ // Ask for completion using new resolver and computer.
+ // But the file signature is the same, so the same result.
+ _createFileResolver();
+ await _compute2(r'''
+var a = ^;
+''');
+ expect(_completionResult, same(lastResult));
+ }
+
Future<void> test_compute2_updateImportedLibrary() async {
var corePath = convertPath('/sdk/lib/core/core.dart');
@@ -139,20 +156,135 @@
_assertHasClass(text: 'String');
}
+ Future<void> test_filterSort_byPattern_excludeNotMatching() async {
+ await _compute2(r'''
+var a = F^;
+''');
+
+ _assertHasClass(text: 'Future');
+ _assertNoClass(text: 'String');
+ }
+
+ Future<void> test_filterSort_byPattern_location_beforeMethod() async {
+ await _compute2(r'''
+class A {
+ F^
+ void foo() {}
+}
+''');
+
+ _assertHasClass(text: 'Future');
+ _assertNoClass(text: 'String');
+ }
+
+ Future<void> test_filterSort_byPattern_location_functionReturnType() async {
+ await _compute2(r'''
+F^ foo() {}
+''');
+
+ _assertHasClass(text: 'Future');
+ _assertNoClass(text: 'String');
+ }
+
+ Future<void> test_filterSort_byPattern_location_methodReturnType() async {
+ await _compute2(r'''
+class A {
+ F^ foo() {}
+}
+''');
+
+ _assertHasClass(text: 'Future');
+ _assertNoClass(text: 'String');
+ }
+
+ Future<void> test_filterSort_byPattern_location_parameterType() async {
+ await _compute2(r'''
+void foo(F^ a) {}
+''');
+
+ _assertHasClass(text: 'Future');
+ _assertNoClass(text: 'String');
+ }
+
+ Future<void> test_filterSort_byPattern_location_parameterType2() async {
+ await _compute2(r'''
+void foo(^a) {}
+''');
+
+ _assertHasClass(text: 'Future');
+ _assertHasClass(text: 'String');
+ }
+
+ Future<void> test_filterSort_byPattern_location_statement() async {
+ await _compute2(r'''
+main() {
+ F^
+ 0;
+}
+''');
+
+ _assertHasClass(text: 'Future');
+ _assertNoClass(text: 'String');
+ }
+
+ Future<void> test_filterSort_byPattern_preferPrefix() async {
+ await _compute2(r'''
+class Foobar {}
+class Falcon {}
+var a = Fo^;
+''');
+
+ _assertOrder([
+ _assertHasClass(text: 'Foobar'),
+ _assertHasClass(text: 'Falcon'),
+ ]);
+ }
+
+ Future<void> test_filterSort_preferLocal() async {
+ await _compute2(r'''
+var a = 0;
+main() {
+ var b = 0;
+ var v = ^;
+}
+''');
+
+ _assertOrder([
+ _assertHasLocalVariable(text: 'b'),
+ _assertHasTopLevelVariable(text: 'a'),
+ ]);
+ }
+
+ Future<void> test_filterSort_sortByName() async {
+ await _compute2(r'''
+main() {
+ var a = 0;
+ var b = 0;
+ var v = ^;
+}
+''');
+
+ _assertOrder([
+ _assertHasLocalVariable(text: 'a'),
+ _assertHasLocalVariable(text: 'b'),
+ ]);
+ }
+
void _assertComputedImportedLibraries(List<String> expected) {
expected = expected.map(convertPath).toList();
expect(
- _completionResult.computedImportedLibraries,
+ _computer.computedImportedLibraries,
unorderedEquals(expected),
);
}
- void _assertHasClass({@required String text}) {
+ CompletionSuggestion _assertHasClass({@required String text}) {
var matching = _matchingCompletions(
text: text,
elementKind: ElementKind.CLASS,
);
expect(matching, hasLength(1), reason: 'Expected exactly one completion');
+ return matching.single;
}
void _assertHasCompletion({@required String text}) {
@@ -160,6 +292,32 @@
expect(matching, hasLength(1), reason: 'Expected exactly one completion');
}
+ CompletionSuggestion _assertHasLocalVariable({@required String text}) {
+ var matching = _matchingCompletions(
+ text: text,
+ elementKind: ElementKind.LOCAL_VARIABLE,
+ );
+ expect(
+ matching,
+ hasLength(1),
+ reason: 'Expected exactly one completion in $_suggestions',
+ );
+ return matching.single;
+ }
+
+ CompletionSuggestion _assertHasTopLevelVariable({@required String text}) {
+ var matching = _matchingCompletions(
+ text: text,
+ elementKind: ElementKind.TOP_LEVEL_VARIABLE,
+ );
+ expect(
+ matching,
+ hasLength(1),
+ reason: 'Expected exactly one completion in $_suggestions',
+ );
+ return matching.single;
+ }
+
void _assertNoClass({@required String text}) {
var matching = _matchingCompletions(
text: text,
@@ -168,13 +326,23 @@
expect(matching, isEmpty, reason: 'Expected zero completions');
}
+ void _assertOrder(List<CompletionSuggestion> suggestions) {
+ var lastIndex = -2;
+ for (var suggestion in suggestions) {
+ var index = _suggestions.indexOf(suggestion);
+ expect(index, isNonNegative, reason: '$suggestion');
+ expect(index, greaterThan(lastIndex), reason: '$suggestion');
+ lastIndex = index;
+ }
+ }
+
Future _compute2(String content) async {
var context = _updateFile(content);
_completionResult = await _newComputer().compute2(
- path: testPath,
+ path: convertPath(testPath),
line: context.line,
- character: context.character,
+ column: context.character,
);
_suggestions = _completionResult.suggestions;
}
@@ -202,12 +370,14 @@
}
CiderCompletionComputer _newComputer() {
- return CiderCompletionComputer(logger, _completionCache, fileResolver);
+ return _computer = CiderCompletionComputer(
+ logger,
+ _completionCache,
+ fileResolver,
+ );
}
_CompletionContext _updateFile(String content) {
- newFile(testPath, content: content);
-
var offset = content.indexOf('^');
expect(offset, isPositive, reason: 'Expected to find ^');
expect(content.indexOf('^', offset + 1), -1, reason: 'Expected only one ^');
@@ -215,6 +385,9 @@
var lineInfo = LineInfo.fromContent(content);
var location = lineInfo.getLocation(offset);
+ content = content.substring(0, offset) + content.substring(offset + 1);
+ newFile(testPath, content: content);
+
return _CompletionContext(
content,
offset,
diff --git a/pkg/analysis_server/test/src/edit/test_all.dart b/pkg/analysis_server/test/src/edit/test_all.dart
index f63fe71..b91a43d 100644
--- a/pkg/analysis_server/test/src/edit/test_all.dart
+++ b/pkg/analysis_server/test/src/edit/test_all.dart
@@ -5,13 +5,9 @@
import 'package:test_reflective_loader/test_reflective_loader.dart';
import 'fix/test_all.dart' as fix;
-import 'nnbd_migration/test_all.dart' as nnbd_migration;
-import 'preview/test_all.dart' as preview;
void main() {
defineReflectiveSuite(() {
fix.main();
- nnbd_migration.main();
- preview.main();
}, name: 'edit');
}
diff --git a/pkg/analysis_server/test/src/services/correction/assist/convert_to_for_element_test.dart b/pkg/analysis_server/test/src/services/correction/assist/convert_to_for_element_test.dart
index 3dfe23e..6a2da91 100644
--- a/pkg/analysis_server/test/src/services/correction/assist/convert_to_for_element_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/assist/convert_to_for_element_test.dart
@@ -4,7 +4,6 @@
import 'package:analysis_server/src/services/correction/assist.dart';
import 'package:analysis_server/src/services/linter/lint_names.dart';
-import 'package:analyzer/src/dart/analysis/experiments.dart';
import 'package:analyzer_plugin/utilities/assist/assist.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
@@ -12,22 +11,15 @@
void main() {
defineReflectiveSuite(() {
- defineReflectiveTests(ConvertToIfElementTest);
+ defineReflectiveTests(ConvertToForElementTest);
});
}
@reflectiveTest
-class ConvertToIfElementTest extends AssistProcessorTest {
+class ConvertToForElementTest extends AssistProcessorTest {
@override
AssistKind get kind => DartAssistKind.CONVERT_TO_FOR_ELEMENT;
- @override
- void setUp() {
- createAnalysisOptionsFile(
- experiments: [EnableString.control_flow_collections]);
- super.setUp();
- }
-
Future<void> test_mapFromIterable_complexKey() async {
await resolveTestUnit('''
f(Iterable<int> i) {
diff --git a/pkg/analysis_server/test/src/services/correction/fix/convert_to_on_type_test.dart b/pkg/analysis_server/test/src/services/correction/fix/convert_to_on_type_test.dart
new file mode 100644
index 0000000..41d23a3
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/fix/convert_to_on_type_test.dart
@@ -0,0 +1,76 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analysis_server/src/services/correction/fix.dart';
+import 'package:analysis_server/src/services/linter/lint_names.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'fix_processor.dart';
+
+void main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(ConvertToOnTypeTest);
+ });
+}
+
+@reflectiveTest
+class ConvertToOnTypeTest extends FixProcessorLintTest {
+ @override
+ FixKind get kind => DartFixKind.CONVERT_TO_ON_TYPE;
+
+ @override
+ String get lintCode => LintNames.avoid_types_as_parameter_names;
+
+ Future<void> test_withOnType() async {
+ await resolveTestUnit('''
+void f() {
+ try {
+ } on ArgumentError catch (Object) {
+ }
+}
+''');
+ await assertNoFix(
+ errorFilter: lintNameFilter(
+ LintNames.avoid_types_as_parameter_names,
+ ),
+ );
+ }
+
+ Future<void> test_withoutStackTrace() async {
+ await resolveTestUnit('''
+void f() {
+ try {
+ } catch (ArgumentError) {
+ }
+}
+''');
+ await assertHasFix('''
+void f() {
+ try {
+ } on ArgumentError {
+ }
+}
+''');
+ }
+
+ Future<void> test_withStackTrace() async {
+ await resolveTestUnit('''
+void f() {
+ try {
+ } catch (ArgumentError, st) {
+ st;
+ }
+}
+''');
+ await assertHasFix('''
+void f() {
+ try {
+ } on ArgumentError catch (_, st) {
+ st;
+ }
+}
+''');
+ }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/fix_processor.dart b/pkg/analysis_server/test/src/services/correction/fix/fix_processor.dart
index d806718..1ed5b4a 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/fix_processor.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/fix_processor.dart
@@ -34,6 +34,12 @@
/// Return the lint code being tested.
String get lintCode;
+ bool Function(AnalysisError) lintNameFilter(String name) {
+ return (e) {
+ return e.errorCode is LintCode && e.errorCode.name == name;
+ };
+ }
+
@override
void setUp() {
super.setUp();
diff --git a/pkg/analysis_server/test/src/services/correction/fix/sort_child_property_last_test.dart b/pkg/analysis_server/test/src/services/correction/fix/sort_child_property_last_test.dart
index 8da5969..48d2b28 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/sort_child_property_last_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/sort_child_property_last_test.dart
@@ -11,12 +11,12 @@
void main() {
defineReflectiveSuite(() {
- defineReflectiveTests(SortChildPropertiesLastTest);
+ defineReflectiveTests(SortChildPropertyLastTest);
});
}
@reflectiveTest
-class SortChildPropertiesLastTest extends FixProcessorLintTest {
+class SortChildPropertyLastTest extends FixProcessorLintTest {
@override
FixKind get kind => DartFixKind.SORT_CHILD_PROPERTY_LAST;
diff --git a/pkg/analysis_server/test/src/services/correction/fix/test_all.dart b/pkg/analysis_server/test/src/services/correction/fix/test_all.dart
index 843263f..2c18bb7 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/test_all.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/test_all.dart
@@ -52,6 +52,7 @@
import 'convert_to_map_literal_test.dart' as convert_to_map_literal;
import 'convert_to_named_arguments_test.dart' as convert_to_named_arguments;
import 'convert_to_null_aware_test.dart' as convert_to_null_aware;
+import 'convert_to_on_type_test.dart' as convert_to_on_type;
import 'convert_to_package_import_test.dart' as convert_to_package_import;
import 'convert_to_relative_import_test.dart' as convert_to_relative_import;
import 'convert_to_set_literal_test.dart' as convert_to_set_literal;
@@ -199,6 +200,7 @@
convert_to_map_literal.main();
convert_to_named_arguments.main();
convert_to_null_aware.main();
+ convert_to_on_type.main();
convert_to_package_import.main();
convert_to_relative_import.main();
convert_to_set_literal.main();
diff --git a/pkg/analysis_server/tool/completion_metrics/relevance_table_generator.dart b/pkg/analysis_server/tool/completion_metrics/relevance_table_generator.dart
index f1cd4e2..9d4e2bb 100644
--- a/pkg/analysis_server/tool/completion_metrics/relevance_table_generator.dart
+++ b/pkg/analysis_server/tool/completion_metrics/relevance_table_generator.dart
@@ -1210,30 +1210,34 @@
String _argumentListContext(AstNode node) {
if (node is ArgumentList) {
var parent = node.parent;
- if (parent is InstanceCreationExpression) {
+ if (parent is Annotation) {
+ return 'annotation';
+ } else if (parent is ExtensionOverride) {
+ return 'extensionOverride';
+ } else if (parent is FunctionExpressionInvocation) {
+ return 'function';
+ } else if (parent is InstanceCreationExpression) {
if (flutter.isWidgetType(parent.staticType)) {
return 'widgetConstructor';
}
return 'constructor';
} else if (parent is MethodInvocation) {
return 'method';
- } else if (parent is FunctionExpressionInvocation) {
- return 'function';
- } else if (parent is SuperConstructorInvocation ||
- parent is RedirectingConstructorInvocation) {
+ } else if (parent is RedirectingConstructorInvocation) {
return 'constructorRedirect';
- } else if (parent is Annotation) {
- return 'annotation';
+ } else if (parent is SuperConstructorInvocation) {
+ return 'constructorRedirect';
}
- } else if (node is IndexExpression) {
- return 'index';
} else if (node is AssignmentExpression ||
node is BinaryExpression ||
node is PrefixExpression ||
node is PostfixExpression) {
return 'operator';
+ } else if (node is IndexExpression) {
+ return 'index';
}
- throw ArgumentError('Unknown parent of ${node.runtimeType}');
+ throw ArgumentError(
+ 'Unknown parent of ${node.runtimeType}: ${node.parent.runtimeType}');
}
/// Return the first child of the [node] that is neither a comment nor an
diff --git a/pkg/analysis_server/tool/lsp_spec/README.md b/pkg/analysis_server/tool/lsp_spec/README.md
index da5c60f..3208c04 100644
--- a/pkg/analysis_server/tool/lsp_spec/README.md
+++ b/pkg/analysis_server/tool/lsp_spec/README.md
@@ -46,7 +46,7 @@
| window/logMessage | ✅ | | | |
| telemetry/event | | | | |
| client/registerCapability | ✅ | ✅ | ✅ | ✅ |
-| client/unregisterCapability | | | | | (unused, capabilities don't change currently)
+| client/unregisterCapability | ✅ | ✅ | ✅ | | Capabilities only change when using analyzer plugins
| workspace/workspaceFolders | | | | |
| workspace/didChangeWorkspaceFolders | ✅ | ✅ | ✅ | ✅ |
| workspace/configuration | | | | |
diff --git a/pkg/analyzer/CHANGELOG.md b/pkg/analyzer/CHANGELOG.md
index 3e0c73e..abb323f 100644
--- a/pkg/analyzer/CHANGELOG.md
+++ b/pkg/analyzer/CHANGELOG.md
@@ -1,3 +1,7 @@
+## 0.39.8-dev
+* Deprecated `VariableElement.constantValue`, it does not guarantee that
+ the value has been computed. Use `computeConstantValue()` instead.
+
## 0.39.7
* Added new error codes: ENUM_CONSTANT_SAME_NAME_AS_ENCLOSING and
THROW_OF_INVALID_TYPE.
diff --git a/pkg/analyzer/lib/dart/element/element.dart b/pkg/analyzer/lib/dart/element/element.dart
index 4841b13..308face 100644
--- a/pkg/analyzer/lib/dart/element/element.dart
+++ b/pkg/analyzer/lib/dart/element/element.dart
@@ -1735,6 +1735,7 @@
/// Return `null` if either this variable was not declared with the 'const'
/// modifier or if the value of this variable could not be computed because of
/// errors.
+ @Deprecated('Use computeConstantValue() instead')
DartObject get constantValue;
@override
diff --git a/pkg/analyzer/lib/src/dart/analysis/file_byte_store.dart b/pkg/analyzer/lib/src/dart/analysis/file_byte_store.dart
index 1456849..a5652ec 100644
--- a/pkg/analyzer/lib/src/dart/analysis/file_byte_store.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/file_byte_store.dart
@@ -106,12 +106,17 @@
}
static void _cleanUpFolder(String cachePath, int maxSizeBytes) {
+ List<FileSystemEntity> resources;
+ try {
+ resources = Directory(cachePath).listSync(recursive: true);
+ } catch (_) {
+ return;
+ }
+
// Prepare the list of files and their statistics.
List<File> files = <File>[];
Map<File, FileStat> fileStatMap = {};
int currentSizeBytes = 0;
- List<FileSystemEntity> resources =
- Directory(cachePath).listSync(recursive: true);
for (FileSystemEntity resource in resources) {
if (resource is File) {
try {
diff --git a/pkg/analyzer/lib/src/dart/analysis/library_context.dart b/pkg/analyzer/lib/src/dart/analysis/library_context.dart
index ec2e3e9..559c900 100644
--- a/pkg/analyzer/lib/src/dart/analysis/library_context.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/library_context.dart
@@ -3,7 +3,6 @@
// BSD-style license that can be found in the LICENSE file.
import 'package:analyzer/dart/analysis/declared_variables.dart';
-import 'package:analyzer/dart/analysis/session.dart';
import 'package:analyzer/dart/element/element.dart'
show CompilationUnitElement, LibraryElement;
import 'package:analyzer/exception/exception.dart';
@@ -44,7 +43,7 @@
final PerformanceLog logger;
final ByteStore byteStore;
- final AnalysisSession analysisSession;
+ final AnalysisSessionImpl analysisSession;
final SummaryDataStore externalSummaries;
final SummaryDataStore store = SummaryDataStore([]);
@@ -60,7 +59,7 @@
var loadedBundles = Set<LibraryCycle>.identity();
LibraryContext({
- @required AnalysisSession session,
+ @required AnalysisSessionImpl session,
@required PerformanceLog logger,
@required ByteStore byteStore,
@required FileSystemState fsState,
diff --git a/pkg/analyzer/lib/src/dart/element/class_hierarchy.dart b/pkg/analyzer/lib/src/dart/element/class_hierarchy.dart
index 543e4ba..f14f835 100644
--- a/pkg/analyzer/lib/src/dart/element/class_hierarchy.dart
+++ b/pkg/analyzer/lib/src/dart/element/class_hierarchy.dart
@@ -24,6 +24,15 @@
_map.remove(element);
}
+ /// Remove hierarchies for classes defined in specified libraries.
+ void removeOfLibraries(Iterable<String> uriStrIterable) {
+ var uriStrSet = uriStrIterable.toSet();
+ _map.removeWhere((element, _) {
+ var uriStr = '${element.librarySource.uri}';
+ return uriStrSet.contains(uriStr);
+ });
+ }
+
_Hierarchy _getHierarchy(ClassElement element) {
var hierarchy = _map[element];
diff --git a/pkg/analyzer/lib/src/dart/element/member.dart b/pkg/analyzer/lib/src/dart/element/member.dart
index 23be79f..2fc7443 100644
--- a/pkg/analyzer/lib/src/dart/element/member.dart
+++ b/pkg/analyzer/lib/src/dart/element/member.dart
@@ -1021,6 +1021,7 @@
@override
VariableElement get baseElement => declaration;
+ @Deprecated('Use computeConstantValue() instead')
@override
DartObject get constantValue => declaration.constantValue;
diff --git a/pkg/analyzer/lib/src/dart/element/top_merge.dart b/pkg/analyzer/lib/src/dart/element/top_merge.dart
index d166d7f..974ad2e 100644
--- a/pkg/analyzer/lib/src/dart/element/top_merge.dart
+++ b/pkg/analyzer/lib/src/dart/element/top_merge.dart
@@ -44,6 +44,11 @@
return DynamicTypeImpl.instance;
}
+ if (identical(T, NeverTypeImpl.instance) &&
+ identical(S, NeverTypeImpl.instance)) {
+ return NeverTypeImpl.instance;
+ }
+
// NNBD_TOP_MERGE(void, void) = void
var T_isVoid = identical(T, VoidTypeImpl.instance);
var S_isVoid = identical(S, VoidTypeImpl.instance);
diff --git a/pkg/analyzer/lib/src/dart/micro/library_graph.dart b/pkg/analyzer/lib/src/dart/micro/library_graph.dart
index e0d05e7..30f89ed 100644
--- a/pkg/analyzer/lib/src/dart/micro/library_graph.dart
+++ b/pkg/analyzer/lib/src/dart/micro/library_graph.dart
@@ -55,6 +55,9 @@
*/
final Source source;
+ /// Files that reference this file.
+ final List<FileState> referencingFiles = [];
+
final List<FileState> importedFiles = [];
final List<FileState> exportedFiles = [];
final List<FileState> partedFiles = [];
@@ -87,9 +90,32 @@
LineInfo get lineInfo => LineInfo(unlinked2.lineStarts);
+ /// The resolved signature of the file, that depends on the [libraryCycle]
+ /// signature, and the content of the file.
+ String get resolvedSignature {
+ var signatureBuilder = ApiSignature();
+ signatureBuilder.addString(path);
+ signatureBuilder.addBytes(libraryCycle.signature);
+
+ var content = getContent();
+ signatureBuilder.addString(content);
+
+ return signatureBuilder.toHex();
+ }
+
/// Return the [uri] string.
String get uriStr => uri.toString();
+ /// Return the content of the file, the empty string if cannot be read.
+ String getContent() {
+ try {
+ var resource = _fsState._resourceProvider.getFile(path);
+ return resource.readAsStringSync();
+ } catch (_) {
+ return '';
+ }
+ }
+
void internal_setLibraryCycle(LibraryCycle cycle, String signature) {
_libraryCycle = cycle;
}
@@ -129,8 +155,13 @@
}
void refresh() {
- _digest = utf8.encode(_fsState.getFileDigest(path));
- _exists = _digest.isNotEmpty;
+ _fsState.testView.refreshedFiles.add(path);
+
+ _fsState.timers.digest.run(() {
+ _digest = utf8.encode(_fsState.getFileDigest(path));
+ _exists = _digest.isNotEmpty;
+ });
+
String unlinkedKey = path;
// Prepare bytes of the unlinked bundle - existing or new.
@@ -148,21 +179,22 @@
}
if (bytes == null || bytes.isEmpty) {
- String content;
- try {
- content = _fsState._resourceProvider.getFile(path).readAsStringSync();
- } catch (_) {
- content = '';
- }
- var unit = parse(AnalysisErrorListener.NULL_LISTENER, content);
- _fsState._logger.run('Create unlinked for $path', () {
+ var content = _fsState.timers.read.run(() {
+ return getContent();
+ });
+ var unit = _fsState.timers.parse.run(() {
+ return parse(AnalysisErrorListener.NULL_LISTENER, content);
+ });
+ _fsState.timers.unlinked.run(() {
var unlinkedBuilder = serializeAstCiderUnlinked(_digest, unit);
bytes = unlinkedBuilder.toBuffer();
_fsState._byteStore.put(unlinkedKey, bytes);
});
- unlinked2 = CiderUnlinkedUnit.fromBuffer(bytes).unlinkedUnit;
- _prefetchDirectReferences(unlinked2);
+ _fsState.timers.prefetch.run(() {
+ unlinked2 = CiderUnlinkedUnit.fromBuffer(bytes).unlinkedUnit;
+ _prefetchDirectReferences(unlinked2);
+ });
}
}
@@ -206,7 +238,10 @@
return _fsState.unresolvedFile;
}
- return _fsState.getFileForUri(absoluteUri);
+ var file = _fsState.getFileForUri(absoluteUri);
+ file.referencingFiles.add(this);
+
+ return file;
}
void _prefetchDirectReferences(UnlinkedUnit2 unlinkedUnit2) {
@@ -341,6 +376,10 @@
*/
FileState _unresolvedFile;
+ final FileSystemStateTimers timers = FileSystemStateTimers();
+
+ final FileSystemStateTestView testView = FileSystemStateTestView();
+
FileSystemState(
this._logger,
this._resourceProvider,
@@ -364,6 +403,23 @@
return _unresolvedFile;
}
+ /// Update the state to reflect the fact that the file with the given [path]
+ /// was changed. Specifically this means that we evict this file and every
+ /// file that referenced it.
+ void changeFile(String path, List<FileState> removedFiles) {
+ var file = _pathToFile.remove(path);
+ if (file == null) {
+ return;
+ }
+
+ removedFiles.add(file);
+ _uriToFile.remove(file.uri);
+
+ for (var reference in file.referencingFiles) {
+ changeFile(reference.path, removedFiles);
+ }
+ }
+
FileState getFileForPath(String path) {
var file = _pathToFile[path];
if (file == null) {
@@ -408,6 +464,60 @@
}
return source.fullName;
}
+
+ void logStatistics() {
+ _logger.writeln(
+ '[files: ${_pathToFile.length}]'
+ '[digest: ${timers.digest.timer.elapsedMilliseconds} ms]'
+ '[read: ${timers.read.timer.elapsedMilliseconds} ms]'
+ '[parse: ${timers.parse.timer.elapsedMilliseconds} ms]'
+ '[unlinked: ${timers.unlinked.timer.elapsedMilliseconds} ms]'
+ '[prefetch: ${timers.prefetch.timer.elapsedMilliseconds} ms]',
+ );
+ timers.reset();
+ }
+}
+
+class FileSystemStateTestView {
+ final List<String> refreshedFiles = [];
+}
+
+class FileSystemStateTimer {
+ final Stopwatch timer = Stopwatch();
+
+ T run<T>(T Function() f) {
+ timer.start();
+ try {
+ return f();
+ } finally {
+ timer.stop();
+ }
+ }
+
+ Future<T> runAsync<T>(T Function() f) async {
+ timer.start();
+ try {
+ return f();
+ } finally {
+ timer.stop();
+ }
+ }
+}
+
+class FileSystemStateTimers {
+ final FileSystemStateTimer digest = FileSystemStateTimer();
+ final FileSystemStateTimer read = FileSystemStateTimer();
+ final FileSystemStateTimer parse = FileSystemStateTimer();
+ final FileSystemStateTimer unlinked = FileSystemStateTimer();
+ final FileSystemStateTimer prefetch = FileSystemStateTimer();
+
+ void reset() {
+ digest.timer.reset();
+ read.timer.reset();
+ parse.timer.reset();
+ unlinked.timer.reset();
+ prefetch.timer.reset();
+ }
}
/// Information about libraries that reference each other, so form a cycle.
diff --git a/pkg/analyzer/lib/src/dart/micro/resolve_file.dart b/pkg/analyzer/lib/src/dart/micro/resolve_file.dart
index 57506b2..f6b5fc2 100644
--- a/pkg/analyzer/lib/src/dart/micro/resolve_file.dart
+++ b/pkg/analyzer/lib/src/dart/micro/resolve_file.dart
@@ -41,6 +41,13 @@
import 'package:meta/meta.dart';
import 'package:yaml/yaml.dart';
+class FileContext {
+ final AnalysisOptionsImpl analysisOptions;
+ final FileState file;
+
+ FileContext(this.analysisOptions, this.file);
+}
+
class FileResolver {
final PerformanceLog logger;
final ResourceProvider resourceProvider;
@@ -62,6 +69,16 @@
final Workspace workspace;
+ /// If not `null`, the library context will be reset after the specified
+ /// interval of inactivity. Keeping library context with loaded elements
+ /// significantly improves performance of resolution, because we don't have
+ /// to resynthesize elements, build export scopes for libraries, etc.
+ /// However keeping elements that we don't need anymore, or when the user
+ /// does not work with files, is wasteful.
+ ///
+ /// TODO(scheglov) use it
+ final Duration libraryContextResetDuration;
+
/// This field gets value only during testing.
FileResolverTestView testView;
@@ -71,20 +88,46 @@
_LibraryContext libraryContext;
- FileResolver(this.logger, this.resourceProvider, this.byteStore,
- this.sourceFactory, this.getFileDigest, this.prefetchFiles,
- {@required Workspace workspace})
- : this.workspace = workspace;
+ FileResolver(
+ this.logger,
+ this.resourceProvider,
+ this.byteStore,
+ this.sourceFactory,
+ this.getFileDigest,
+ this.prefetchFiles, {
+ @required Workspace workspace,
+ this.libraryContextResetDuration,
+ }) : this.workspace = workspace;
FeatureSet get defaultFeatureSet => FeatureSet.fromEnableFlags([]);
+ /// Update the resolver to reflect the fact that the file with the given
+ /// [path] was changed. We need to make sure that when this file, of any file
+ /// that directly or indirectly referenced it, is resolved, we used the new
+ /// state of the file.
+ void changeFile(String path) {
+ if (fsState == null) {
+ return;
+ }
+
+ // Remove this file and all files that transitively depend on it.
+ var removedFiles = <FileState>[];
+ fsState.changeFile(path, removedFiles);
+
+ // Remove libraries represented by removed files.
+ // If we need these libraries later, we will relink and reattach them.
+ if (libraryContext != null) {
+ libraryContext.elementFactory.removeLibraries(
+ removedFiles.map((e) => e.uriStr).toList(),
+ );
+ }
+ }
+
ErrorsResult getErrors(String path) {
_throwIfNotAbsoluteNormalizedPath(path);
return logger.run('Get errors for $path', () {
- var fileContext = logger.run('Get file $path', () {
- return _createFileContext(path);
- });
+ var fileContext = getFileContext(path, withLog: true);
var file = fileContext.file;
var errorsSignatureBuilder = ApiSignature();
@@ -127,10 +170,33 @@
});
}
+ FileContext getFileContext(String path, {bool withLog = false}) {
+ FileContext perform() {
+ var analysisOptions = _getAnalysisOptions(path);
+
+ _createContext(analysisOptions);
+
+ var file = fsState.getFileForPath(path);
+ return FileContext(analysisOptions, file);
+ }
+
+ if (withLog) {
+ return logger.run('Get file $path', () {
+ try {
+ return getFileContext(path);
+ } finally {
+ fsState.logStatistics();
+ }
+ });
+ } else {
+ return perform();
+ }
+ }
+
String getLibraryLinkedSignature(String path) {
_throwIfNotAbsoluteNormalizedPath(path);
- var fileContext = _createFileContext(path);
+ var fileContext = getFileContext(path);
var file = fileContext.file;
return file.libraryCycle.signatureStr;
}
@@ -139,9 +205,7 @@
_throwIfNotAbsoluteNormalizedPath(path);
return logger.run('Resolve $path', () {
- var fileContext = logger.run('Get file $path', () {
- return _createFileContext(path);
- });
+ var fileContext = getFileContext(path, withLog: true);
var file = fileContext.file;
libraryContext.load2(file);
@@ -234,22 +298,23 @@
}
if (analysisContext == null) {
- logger.run('Create AnalysisContext', () {
- var root = ContextRootImpl(
- resourceProvider,
- resourceProvider.getFolder(workspace.root),
- );
+ var rootFolder = resourceProvider.getFolder(workspace.root);
+ var root = ContextRootImpl(
+ resourceProvider,
+ rootFolder,
+ );
- analysisContext = MicroAnalysisContextImpl(
- this,
- root,
- analysisOptions,
- DeclaredVariables(),
- sourceFactory,
- resourceProvider,
- workspace: workspace,
- );
- });
+ root.included.add(rootFolder);
+
+ analysisContext = MicroAnalysisContextImpl(
+ this,
+ root,
+ analysisOptions,
+ DeclaredVariables(),
+ sourceFactory,
+ resourceProvider,
+ workspace: workspace,
+ );
}
if (libraryContext == null) {
@@ -265,15 +330,6 @@
}
}
- _FileContext _createFileContext(String path) {
- var analysisOptions = _getAnalysisOptions(path);
-
- _createContext(analysisOptions);
-
- var file = fsState.getFileForPath(path);
- return _FileContext(analysisOptions, file);
- }
-
File _findOptionsFile(Folder folder) {
while (folder != null) {
File packagesFile =
@@ -359,13 +415,6 @@
}
}
-class _FileContext {
- final AnalysisOptionsImpl analysisOptions;
- final FileState file;
-
- _FileContext(this.analysisOptions, this.file);
-}
-
class _LibraryContext {
final PerformanceLog logger;
final ResourceProvider resourceProvider;
diff --git a/pkg/analyzer/lib/src/generated/error_verifier.dart b/pkg/analyzer/lib/src/generated/error_verifier.dart
index 0a4d3d4..a44252f 100644
--- a/pkg/analyzer/lib/src/generated/error_verifier.dart
+++ b/pkg/analyzer/lib/src/generated/error_verifier.dart
@@ -350,6 +350,9 @@
_errorReporter.reportErrorForToken(
CompileTimeErrorCode.AWAIT_IN_WRONG_CONTEXT, node.awaitKeyword);
}
+ if (_isNonNullableByDefault) {
+ _checkForUseOfVoidResult(node.expression);
+ }
_checkForAwaitInLateLocalVariableInitializer(node);
super.visitAwaitExpression(node);
}
@@ -3143,7 +3146,12 @@
return;
}
- if (identical(lhs.staticType, NeverTypeImpl.instance)) {
+ if (lhs is IndexExpression &&
+ identical(lhs.realTarget.staticType, NeverTypeImpl.instance) ||
+ lhs is PrefixedIdentifier &&
+ identical(lhs.prefix.staticType, NeverTypeImpl.instance) ||
+ lhs is PropertyAccess &&
+ identical(lhs.realTarget.staticType, NeverTypeImpl.instance)) {
return;
}
diff --git a/pkg/analyzer/lib/src/generated/resolver.dart b/pkg/analyzer/lib/src/generated/resolver.dart
index 1dbeab5..ea4d2dd 100644
--- a/pkg/analyzer/lib/src/generated/resolver.dart
+++ b/pkg/analyzer/lib/src/generated/resolver.dart
@@ -517,7 +517,9 @@
_unfinishedNullShorts.removeLast();
_flowAnalysis.flow.nullAwareAccess_end();
} while (identical(_unfinishedNullShorts.last, node));
- node.staticType = typeSystem.makeNullable(node.staticType);
+ if (node is! CascadeExpression) {
+ node.staticType = typeSystem.makeNullable(node.staticType);
+ }
}
}
@@ -1691,6 +1693,7 @@
body.accept(this);
if (catchClauses.isNotEmpty) {
flow.tryCatchStatement_bodyEnd(body);
+ nullSafetyDeadCodeVerifier?.flowEnd(node.body);
nullSafetyDeadCodeVerifier.tryStatementEnter(node);
var catchLength = catchClauses.length;
diff --git a/pkg/analyzer/lib/src/summary2/linked_element_factory.dart b/pkg/analyzer/lib/src/summary2/linked_element_factory.dart
index 4d4d3a1..374cfb3 100644
--- a/pkg/analyzer/lib/src/summary2/linked_element_factory.dart
+++ b/pkg/analyzer/lib/src/summary2/linked_element_factory.dart
@@ -2,10 +2,10 @@
// 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:analyzer/dart/analysis/session.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/src/context/context.dart';
+import 'package:analyzer/src/dart/analysis/session.dart';
import 'package:analyzer/src/dart/element/element.dart';
import 'package:analyzer/src/dart/element/type_provider.dart';
import 'package:analyzer/src/dart/resolver/scope.dart';
@@ -18,7 +18,7 @@
class LinkedElementFactory {
final AnalysisContextImpl analysisContext;
- final AnalysisSession analysisSession;
+ final AnalysisSessionImpl analysisSession;
final Reference rootReference;
final Map<String, LinkedLibraryContext> libraryMap = {};
@@ -150,10 +150,26 @@
/// We have linked the bundle, and need to disconnect its libraries, so
/// that the client can re-add the bundle, this time read from bytes.
void removeBundle(LinkedBundleContext context) {
+ // TODO(scheglov) Use removeLibraries()
for (var uriStr in context.libraryMap.keys) {
libraryMap.remove(uriStr);
rootReference.removeChild(uriStr);
}
+
+ var classHierarchy = analysisSession.classHierarchy;
+ classHierarchy.removeOfLibraries(context.libraryMap.keys);
+ }
+
+ /// Remove libraries with the specified URIs from the reference tree, and
+ /// any session level caches.
+ void removeLibraries(List<String> uriStrList) {
+ for (var uriStr in uriStrList) {
+ libraryMap.remove(uriStr);
+ rootReference.removeChild(uriStr);
+ }
+
+ var classHierarchy = analysisSession.classHierarchy;
+ classHierarchy.removeOfLibraries(uriStrList);
}
/// Set optional informative data for the unit.
diff --git a/pkg/analyzer/test/id_tests/constant_test.dart b/pkg/analyzer/test/id_tests/constant_test.dart
index 7d6e44f..9a78106 100644
--- a/pkg/analyzer/test/id_tests/constant_test.dart
+++ b/pkg/analyzer/test/id_tests/constant_test.dart
@@ -68,7 +68,7 @@
if (element is PropertyAccessorElement && element.isSynthetic) {
var variable = element.variable;
if (!variable.isSynthetic && variable.isConst) {
- var value = variable.constantValue;
+ var value = variable.computeConstantValue();
if (value != null) return _stringify(value);
}
}
diff --git a/pkg/analyzer/test/src/dart/analysis/driver_test.dart b/pkg/analyzer/test/src/dart/analysis/driver_test.dart
index 45376fd..c9d26a4 100644
--- a/pkg/analyzer/test/src/dart/analysis/driver_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/driver_test.dart
@@ -885,8 +885,8 @@
var result = await driver.getResult(testFile);
var x = AstFinder.getTopLevelVariableElement(result.unit, 'x');
var y = AstFinder.getTopLevelVariableElement(result.unit, 'y');
- expect(x.constantValue.toIntValue(), 2);
- expect(y.constantValue.toIntValue(), 1);
+ expect(x.computeConstantValue().toIntValue(), 2);
+ expect(y.computeConstantValue().toIntValue(), 1);
}
test_const_externalConstFactory() async {
@@ -901,7 +901,7 @@
''');
var result = await driver.getResult(testFile);
var x = AstFinder.getTopLevelVariableElement(result.unit, 'x');
- expect(x.constantValue, isNotNull);
+ expect(x.computeConstantValue(), isNotNull);
}
test_const_implicitCreation() async {
@@ -967,7 +967,7 @@
''');
var result = await driver.getResult(testFile);
var x = AstFinder.getTopLevelVariableElement(result.unit, 'x');
- expect(x.constantValue, isNotNull);
+ expect(x.computeConstantValue(), isNotNull);
}
test_const_simple_topLevelVariable() async {
@@ -976,7 +976,7 @@
''');
var result = await driver.getResult(testFile);
var x = AstFinder.getTopLevelVariableElement(result.unit, 'x');
- expect(x.constantValue.toIntValue(), 1);
+ expect(x.computeConstantValue().toIntValue(), 1);
}
test_currentSession() async {
diff --git a/pkg/analyzer/test/src/dart/element/element_test.dart b/pkg/analyzer/test/src/dart/element/element_test.dart
index 7887d88..06e4bb6 100644
--- a/pkg/analyzer/test/src/dart/element/element_test.dart
+++ b/pkg/analyzer/test/src/dart/element/element_test.dart
@@ -2212,12 +2212,10 @@
SimpleIdentifier argument = findNode.simple('C);');
PropertyAccessorElementImpl getter = argument.staticElement;
TopLevelVariableElement constant = getter.variable;
- expect(constant.constantValue, isNull);
DartObject value = constant.computeConstantValue();
expect(value, isNotNull);
expect(value.toIntValue(), 42);
- expect(constant.constantValue, value);
}
}
diff --git a/pkg/analyzer/test/src/dart/element/top_merge_test.dart b/pkg/analyzer/test/src/dart/element/top_merge_test.dart
index be03653..008ed17 100644
--- a/pkg/analyzer/test/src/dart/element/top_merge_test.dart
+++ b/pkg/analyzer/test/src/dart/element/top_merge_test.dart
@@ -233,6 +233,10 @@
);
}
+ test_never() {
+ _check(neverNone, neverNone, neverNone);
+ }
+
test_null() {
// NNBD_TOP_MERGE(Never*, Null) = Null
// NNBD_TOP_MERGE(Null, Never*) = Null
diff --git a/pkg/analyzer/test/src/dart/micro/simple_file_resolver_test.dart b/pkg/analyzer/test/src/dart/micro/simple_file_resolver_test.dart
index 3236c52..6166778 100644
--- a/pkg/analyzer/test/src/dart/micro/simple_file_resolver_test.dart
+++ b/pkg/analyzer/test/src/dart/micro/simple_file_resolver_test.dart
@@ -12,11 +12,102 @@
main() {
defineReflectiveSuite(() {
+ defineReflectiveTests(FileResolver_changeFile_Test);
defineReflectiveTests(FileResolverTest);
});
}
@reflectiveTest
+class FileResolver_changeFile_Test extends FileResolutionTest {
+ String aPath;
+ String bPath;
+ String cPath;
+
+ @override
+ void setUp() {
+ super.setUp();
+ aPath = convertPath('/workspace/dart/test/lib/a.dart');
+ bPath = convertPath('/workspace/dart/test/lib/b.dart');
+ cPath = convertPath('/workspace/dart/test/lib/c.dart');
+ }
+
+ test_changeFile_refreshedFiles() async {
+ newFile(aPath, content: r'''
+class A {}
+''');
+
+ newFile(bPath, content: r'''
+class B {}
+''');
+
+ newFile(cPath, content: r'''
+import 'a.dart';
+import 'b.dart';
+''');
+
+ // First time we refresh everything.
+ await fileResolver.resolve(cPath);
+ _assertRefreshedFiles([aPath, bPath, cPath], withSdk: true);
+
+ // Without changes we refresh nothing.
+ await fileResolver.resolve(cPath);
+ _assertRefreshedFiles([]);
+
+ // We already know a.dart, refresh nothing.
+ await fileResolver.resolve(aPath);
+ _assertRefreshedFiles([]);
+
+ // Change a.dart, refresh a.dart and c.dart, but not b.dart
+ fileResolver.changeFile(aPath);
+ await fileResolver.resolve(cPath);
+ _assertRefreshedFiles([aPath, cPath]);
+ }
+
+ test_changeFile_resolution() async {
+ newFile(aPath, content: r'''
+class A {}
+''');
+
+ newFile(bPath, content: r'''
+import 'a.dart';
+A a;
+B b;
+''');
+
+ result = fileResolver.resolve(bPath);
+ assertErrorsInResolvedUnit(result, [
+ error(CompileTimeErrorCode.UNDEFINED_CLASS, 22, 1),
+ ]);
+
+ newFile(aPath, content: r'''
+class A {}
+class B {}
+''');
+ fileResolver.changeFile(aPath);
+
+ result = fileResolver.resolve(bPath);
+ assertErrorsInResolvedUnit(result, []);
+ }
+
+ void _assertRefreshedFiles(List<String> expected, {bool withSdk = false}) {
+ var expectedPlusSdk = expected.toSet();
+
+ if (withSdk) {
+ expectedPlusSdk
+ ..add(convertPath('/sdk/lib/async/async.dart'))
+ ..add(convertPath('/sdk/lib/async/stream.dart'))
+ ..add(convertPath('/sdk/lib/core/core.dart'))
+ ..add(convertPath('/sdk/lib/math/math.dart'));
+ }
+
+ var refreshedFiles = fileResolver.fsState.testView.refreshedFiles;
+ expect(refreshedFiles, unorderedEquals(expectedPlusSdk));
+
+ refreshedFiles.clear();
+ }
+}
+
+@reflectiveTest
class FileResolverTest extends FileResolutionTest {
test_analysisOptions_default_fromPackageUri() async {
newFile('/workspace/dart/analysis_options/lib/default.yaml', content: r'''
diff --git a/pkg/analyzer/test/src/dart/resolution/constant_test.dart b/pkg/analyzer/test/src/dart/resolution/constant_test.dart
index 25c3b3d..9d51f53 100644
--- a/pkg/analyzer/test/src/dart/resolution/constant_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/constant_test.dart
@@ -347,6 +347,6 @@
}
void _assertIntValue(VariableElement element, int value) {
- expect(element.constantValue.toIntValue(), value);
+ expect(element.computeConstantValue().toIntValue(), value);
}
}
diff --git a/pkg/analyzer/test/src/dart/resolution/method_invocation_test.dart b/pkg/analyzer/test/src/dart/resolution/method_invocation_test.dart
index c6ce42f..096e13c 100644
--- a/pkg/analyzer/test/src/dart/resolution/method_invocation_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/method_invocation_test.dart
@@ -2042,4 +2042,35 @@
assertType(findNode.cascade('a?'), 'A?');
}
+
+ test_nullShorting_cascade_nullAwareInside() async {
+ await assertNoErrorsInCode(r'''
+class A {
+ int? foo() => 0;
+}
+
+main() {
+ A a = A()..foo()?.abs();
+ a;
+}
+''');
+
+ assertMethodInvocation2(
+ findNode.methodInvocation('..foo()'),
+ element: findElement.method('foo'),
+ typeArgumentTypes: [],
+ invokeType: 'int? Function()',
+ type: 'int?',
+ );
+
+ assertMethodInvocation2(
+ findNode.methodInvocation('.abs()'),
+ element: intElement.getMethod('abs'),
+ typeArgumentTypes: [],
+ invokeType: 'int Function()',
+ type: 'int',
+ );
+
+ assertType(findNode.cascade('A()'), 'A');
+ }
}
diff --git a/pkg/analyzer/test/src/dart/resolution/property_access_test.dart b/pkg/analyzer/test/src/dart/resolution/property_access_test.dart
index 9bceab5..41e7bea 100644
--- a/pkg/analyzer/test/src/dart/resolution/property_access_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/property_access_test.dart
@@ -94,4 +94,108 @@
assertType(findNode.cascade('a?'), 'A?');
}
+
+ test_nullShorting_cascade2() async {
+ await assertNoErrorsInCode(r'''
+class A {
+ int? get foo => 0;
+}
+
+main() {
+ A a = A()..foo?.isEven;
+ a;
+}
+''');
+
+ assertPropertyAccess2(
+ findNode.propertyAccess('..foo?'),
+ element: findElement.getter('foo'),
+ type: 'int?',
+ );
+
+ assertPropertyAccess2(
+ findNode.propertyAccess('.isEven'),
+ element: intElement.getGetter('isEven'),
+ type: 'bool',
+ );
+
+ assertType(findNode.cascade('A()'), 'A');
+ }
+
+ test_nullShorting_cascade3() async {
+ await assertNoErrorsInCode(r'''
+class A {
+ A? get foo => this;
+ A? get bar => this;
+ A? get baz => this;
+}
+
+main() {
+ A a = A()..foo?.bar?.baz;
+ a;
+}
+''');
+
+ assertPropertyAccess2(
+ findNode.propertyAccess('.foo'),
+ element: findElement.getter('foo'),
+ type: 'A?',
+ );
+
+ assertPropertyAccess2(
+ findNode.propertyAccess('.bar'),
+ element: findElement.getter('bar'),
+ type: 'A?',
+ );
+
+ assertPropertyAccess2(
+ findNode.propertyAccess('.baz'),
+ element: findElement.getter('baz'),
+ type: 'A?',
+ );
+
+ assertType(findNode.cascade('A()'), 'A');
+ }
+
+ test_nullShorting_cascade4() async {
+ await assertNoErrorsInCode(r'''
+A? get foo => A();
+
+class A {
+ A get bar => this;
+ A? get baz => this;
+ A get baq => this;
+}
+
+main() {
+ foo?.bar?..baz?.baq;
+}
+''');
+
+ assertSimpleIdentifier(
+ findNode.simple('foo?'),
+ element: findElement.topGet('foo'),
+ type: 'A?',
+ );
+
+ assertPropertyAccess2(
+ findNode.propertyAccess('.bar'),
+ element: findElement.getter('bar'),
+ type: 'A?',
+ );
+
+ assertPropertyAccess2(
+ findNode.propertyAccess('.baz'),
+ element: findElement.getter('baz'),
+ type: 'A?',
+ );
+
+ assertPropertyAccess2(
+ findNode.propertyAccess('.baq'),
+ element: findElement.getter('baq'),
+ type: 'A',
+ );
+
+ assertType(findNode.cascade('foo?'), 'A?');
+ }
}
diff --git a/pkg/analyzer/test/src/diagnostics/dead_code_test.dart b/pkg/analyzer/test/src/diagnostics/dead_code_test.dart
index ae0e08e..088a0a8 100644
--- a/pkg/analyzer/test/src/diagnostics/dead_code_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/dead_code_test.dart
@@ -438,6 +438,75 @@
''');
}
+ test_flowEnd_forStatement() async {
+ await assertErrorsInCode(r'''
+main() {
+ for (var v in [0, 1, 2]) {
+ v;
+ return;
+ 1;
+ }
+ 2;
+}
+''', [
+ error(HintCode.DEAD_CODE, 61, 2),
+ ]);
+ }
+
+ test_flowEnd_ifStatement() async {
+ await assertErrorsInCode(r'''
+main(bool a) {
+ if (a) {
+ return;
+ 1;
+ }
+ 2;
+}
+''', [
+ error(HintCode.DEAD_CODE, 42, 2),
+ ]);
+ }
+
+ test_flowEnd_tryStatement_catchClause() async {
+ await assertErrorsInCode(r'''
+main() {
+ try {
+ 1;
+ } catch (_) {
+ return;
+ 2;
+ }
+ 3;
+}
+''', [
+ error(HintCode.DEAD_CODE, 56, 2),
+ ]);
+ }
+
+ test_flowEnd_tryStatement_finally() async {
+ var expectedErrors = expectedErrorsByNullability(
+ nullable: [
+ error(HintCode.DEAD_CODE, 61, 11),
+ ],
+ legacy: [
+ error(HintCode.DEAD_CODE, 61, 2),
+ error(HintCode.DEAD_CODE, 70, 2),
+ ],
+ );
+ await assertErrorsInCode(r'''
+main() {
+ try {
+ 1;
+ } finally {
+ 2;
+ return;
+ 3;
+ }
+ 4;
+}
+''', expectedErrors);
+ }
+
test_statementAfterAlwaysThrowsFunction() async {
addMetaPackage();
await assertErrorsInCode(r'''
@@ -740,6 +809,50 @@
@reflectiveTest
class DeadCodeWithNullSafetyTest extends DeadCodeTest with WithNullSafetyMixin {
+ test_flowEnd_tryStatement_body() async {
+ await assertErrorsInCode(r'''
+Never foo() => throw 0;
+
+main() {
+ try {
+ foo();
+ 1;
+ } catch (_) {
+ 2;
+ }
+ 3;
+}
+''', [
+ error(HintCode.DEAD_CODE, 57, 2),
+ ]);
+ }
+
+ test_returnTypeNever_function() async {
+ await assertErrorsInCode(r'''
+Never foo() => throw 0;
+
+main() {
+ foo();
+ 1;
+}
+''', [
+ error(HintCode.DEAD_CODE, 45, 2),
+ ]);
+ }
+
+ test_returnTypeNever_getter() async {
+ await assertErrorsInCode(r'''
+Never get foo => throw 0;
+
+main() {
+ foo;
+ 2;
+}
+''', [
+ error(HintCode.DEAD_CODE, 45, 2),
+ ]);
+ }
+
@FailingTest(reason: '@alwaysThrows is not supported in flow analysis')
@override
test_statementAfterAlwaysThrowsFunction() async {
diff --git a/pkg/analyzer/test/src/diagnostics/invalid_assignment_test.dart b/pkg/analyzer/test/src/diagnostics/invalid_assignment_test.dart
index d9209a9..312f892 100644
--- a/pkg/analyzer/test/src/diagnostics/invalid_assignment_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/invalid_assignment_test.dart
@@ -44,6 +44,30 @@
}
''');
}
+
+ test_localLevelVariable_never_null() async {
+ await assertErrorsInCode('''
+void f(Never x) {
+ x = null;
+}
+''', [
+ error(HintCode.DEAD_CODE, 24, 5),
+ error(StaticTypeWarningCode.INVALID_ASSIGNMENT, 24, 4),
+ ]);
+ }
+
+ test_topLevelVariable_never_null() async {
+ await assertErrorsInCode('''
+Never x = throw 0;
+
+void f() {
+ x = null;
+}
+''', [
+ error(HintCode.DEAD_CODE, 37, 5),
+ error(StaticTypeWarningCode.INVALID_ASSIGNMENT, 37, 4),
+ ]);
+ }
}
@reflectiveTest
diff --git a/pkg/analyzer/test/src/diagnostics/use_of_void_result_test.dart b/pkg/analyzer/test/src/diagnostics/use_of_void_result_test.dart
index 2613cb9..b1cbafc 100644
--- a/pkg/analyzer/test/src/diagnostics/use_of_void_result_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/use_of_void_result_test.dart
@@ -2,13 +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.
-import 'package:analyzer/dart/analysis/features.dart';
-import 'package:analyzer/src/dart/analysis/experiments.dart';
import 'package:analyzer/src/error/codes.dart';
-import 'package:analyzer/src/generated/engine.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
import '../../generated/test_support.dart';
+import '../dart/constant/potentially_constant_test.dart';
import '../dart/resolution/driver_resolution.dart';
main() {
@@ -97,10 +95,10 @@
test_await() async {
await assertNoErrorsInCode('''
-main() async {
- void x;
+main(void x) async {
await x;
-}''');
+}
+''');
}
test_extensionApplication() async {
@@ -728,12 +726,17 @@
}
@reflectiveTest
-class UseOfVoidResultTest_NonNullable extends DriverResolutionTest {
- @override
- AnalysisOptionsImpl get analysisOptions => AnalysisOptionsImpl()
- ..contextFeatures = FeatureSet.fromEnableFlags(
- [EnableString.non_nullable],
- );
+class UseOfVoidResultTest_NonNullable extends DriverResolutionTest
+ with WithNullSafetyMixin {
+ test_await() async {
+ await assertErrorsInCode('''
+main(void x) async {
+ await x;
+}
+''', [
+ error(StaticWarningCode.USE_OF_VOID_RESULT, 29, 1),
+ ]);
+ }
test_nullCheck() async {
await assertErrorsInCode(r'''
diff --git a/pkg/analyzer_plugin/lib/src/utilities/completion/optype.dart b/pkg/analyzer_plugin/lib/src/utilities/completion/optype.dart
index 2887b49..adbccee 100644
--- a/pkg/analyzer_plugin/lib/src/utilities/completion/optype.dart
+++ b/pkg/analyzer_plugin/lib/src/utilities/completion/optype.dart
@@ -1362,7 +1362,13 @@
String _argumentListContext(AstNode node) {
if (node is ArgumentList) {
var parent = node.parent;
- if (parent is InstanceCreationExpression) {
+ if (parent is Annotation) {
+ return 'annotation';
+ } else if (parent is ExtensionOverride) {
+ return 'extensionOverride';
+ } else if (parent is FunctionExpressionInvocation) {
+ return 'function';
+ } else if (parent is InstanceCreationExpression) {
// TODO(brianwilkerson) Enable this case.
// if (flutter.isWidgetType(parent.staticType)) {
// return 'widgetConstructor';
@@ -1370,23 +1376,21 @@
return 'constructor';
} else if (parent is MethodInvocation) {
return 'method';
- } else if (parent is FunctionExpressionInvocation) {
- return 'function';
- } else if (parent is SuperConstructorInvocation ||
- parent is RedirectingConstructorInvocation) {
+ } else if (parent is RedirectingConstructorInvocation) {
return 'constructorRedirect';
- } else if (parent is Annotation) {
- return 'annotation';
+ } else if (parent is SuperConstructorInvocation) {
+ return 'constructorRedirect';
}
- } else if (node is IndexExpression) {
- return 'index';
} else if (node is AssignmentExpression ||
node is BinaryExpression ||
node is PrefixExpression ||
node is PostfixExpression) {
return 'operator';
+ } else if (node is IndexExpression) {
+ return 'index';
}
- throw ArgumentError('Unknown parent of ${node.runtimeType}');
+ throw ArgumentError(
+ 'Unknown parent of ${node.runtimeType}: ${node.parent.runtimeType}');
}
bool _isEntityPrevTokenSynthetic() {
diff --git a/pkg/analysis_server/lib/src/domains/analysis/navigation_dart.dart b/pkg/analyzer_plugin/lib/utilities/navigation/navigation_dart.dart
similarity index 98%
rename from pkg/analysis_server/lib/src/domains/analysis/navigation_dart.dart
rename to pkg/analyzer_plugin/lib/utilities/navigation/navigation_dart.dart
index d9b9a3b..f375d47 100644
--- a/pkg/analysis_server/lib/src/domains/analysis/navigation_dart.dart
+++ b/pkg/analyzer_plugin/lib/utilities/navigation/navigation_dart.dart
@@ -188,7 +188,7 @@
@override
void visitExportDirective(ExportDirective node) {
- ExportElement exportElement = node.element;
+ var exportElement = node.element as ExportElement;
if (exportElement != null) {
Element libraryElement = exportElement.exportedLibrary;
_addUriDirectiveRegion(node, libraryElement);
@@ -198,7 +198,7 @@
@override
void visitImportDirective(ImportDirective node) {
- ImportElement importElement = node.element;
+ var importElement = node.element as ImportElement;
if (importElement != null) {
Element libraryElement = importElement.importedLibrary;
_addUriDirectiveRegion(node, libraryElement);
diff --git a/pkg/analyzer_plugin/test/src/utilities/completion/optype_test.dart b/pkg/analyzer_plugin/test/src/utilities/completion/optype_test.dart
index 1613b9d..07ba9b9 100644
--- a/pkg/analyzer_plugin/test/src/utilities/completion/optype_test.dart
+++ b/pkg/analyzer_plugin/test/src/utilities/completion/optype_test.dart
@@ -1070,6 +1070,19 @@
completionLocation: 'ExtensionDeclaration_member', typeNames: true);
}
+ Future<void> test_extensionOverride_argumentList() async {
+ // ExtensionDeclaration CompilationUnit
+ addTestSource('''
+extension E on int {}
+int x = E(^);
+''');
+ await assertOpType(
+ completionLocation: 'ArgumentList_extensionOverride_unnamed',
+ constructors: true,
+ returnValue: true,
+ typeNames: true);
+ }
+
Future<void> test_fieldDeclaration_name_typed() async {
// SimpleIdentifier VariableDeclaration VariableDeclarationList
// FieldDeclaration
diff --git a/pkg/compiler/lib/src/js_model/js_world.dart b/pkg/compiler/lib/src/js_model/js_world.dart
index bb9a5ca..e510eff 100644
--- a/pkg/compiler/lib/src/js_model/js_world.dart
+++ b/pkg/compiler/lib/src/js_model/js_world.dart
@@ -259,21 +259,21 @@
@override
ClassEntity getLubOfInstantiatedSubclasses(ClassEntity cls) {
if (nativeData.isJsInteropClass(cls)) {
- return commonElements.jsJavaScriptObjectClass;
+ return getLubOfInstantiatedSubclasses(
+ commonElements.jsJavaScriptObjectClass);
}
ClassHierarchyNode hierarchy = classHierarchy.getClassHierarchyNode(cls);
- return hierarchy != null
- ? hierarchy.getLubOfInstantiatedSubclasses()
- : null;
+ return hierarchy?.getLubOfInstantiatedSubclasses();
}
@override
ClassEntity getLubOfInstantiatedSubtypes(ClassEntity cls) {
if (nativeData.isJsInteropClass(cls)) {
- return commonElements.jsJavaScriptObjectClass;
+ return getLubOfInstantiatedSubtypes(
+ commonElements.jsJavaScriptObjectClass);
}
ClassSet classSet = classHierarchy.getClassSet(cls);
- return classSet != null ? classSet.getLubOfInstantiatedSubtypes() : null;
+ return classSet?.getLubOfInstantiatedSubtypes();
}
@override
diff --git a/pkg/compiler/lib/src/ssa/builder_kernel.dart b/pkg/compiler/lib/src/ssa/builder_kernel.dart
index a10948d..ba9f5f6 100644
--- a/pkg/compiler/lib/src/ssa/builder_kernel.dart
+++ b/pkg/compiler/lib/src/ssa/builder_kernel.dart
@@ -705,22 +705,29 @@
for (TypeVariableType typeVariable
in _elementEnvironment.getFunctionTypeVariables(function)) {
HInstruction param;
+ bool erased = false;
if (elideTypeParameters) {
// Add elided type parameters.
param = _computeTypeArgumentDefaultValue(function, typeVariable);
+ erased = true;
} else if (needsTypeArguments) {
param = addParameter(
typeVariable.element, _abstractValueDomain.nonNullType);
} else {
- // Unused, so bind to `dynamic`.
- param = graph.addConstantNull(closedWorld);
+ // Unused, so bind to bound.
+ param = _computeTypeArgumentDefaultValue(function, typeVariable);
+ erased = true;
}
Local local = localsHandler.getTypeVariableAsLocal(typeVariable);
localsHandler.directLocals[local] = param;
- _functionTypeParameterLocals.add(local);
+ if (!erased) {
+ _functionTypeParameterLocals.add(local);
+ }
}
}
+ // Locals for function type parameters that can be forwarded, in argument
+ // position order.
List<Local> _functionTypeParameterLocals = <Local>[];
/// Builds a generative constructor.
@@ -1392,6 +1399,9 @@
DartType elementType = _elementEnvironment.getAsyncOrSyncStarElementType(
function.asyncMarker, _returnType);
+ // TODO(sra): [elementType] can contain free type variables that are erased
+ // due to no rtiNeed. We will get getter code if these type variables are
+ // substituted with an <any> or <erased> type.
if (elementType.containsFreeTypeVariables) {
// Type must be computed in the entry function, where the type variables
// are in scope, and passed to the body function.
diff --git a/pkg/dartdev/lib/src/commands/run.dart b/pkg/dartdev/lib/src/commands/run.dart
index c7089b1..3a3e9c4 100644
--- a/pkg/dartdev/lib/src/commands/run.dart
+++ b/pkg/dartdev/lib/src/commands/run.dart
@@ -12,8 +12,8 @@
class RunCommand extends DartdevCommand<int> {
final ArgParser argParser = ArgParser.allowAnything();
-
- RunCommand({bool verbose = false}) : super('run', '''
+ final bool verbose;
+ RunCommand({this.verbose = false}) : super('run', '''
Run a Dart file.''');
@override
@@ -25,7 +25,10 @@
// execute [run] below. Without this, the 'dart help run' reports the
// command pub with no commands or flags.
final command = sdk.dart;
- final args = ['--help'];
+ final args = [
+ '--help',
+ if (verbose) '--verbose',
+ ];
log.trace('$command ${args.first}');
@@ -49,7 +52,7 @@
// Starting in ProcessStartMode.inheritStdio mode means the child process
// can detect support for ansi chars.
- var process = await Process.start(sdk.dart, args,
+ final process = await Process.start(sdk.dart, args,
mode: ProcessStartMode.inheritStdio);
return process.exitCode;
}
diff --git a/pkg/dds/lib/dds.dart b/pkg/dds/lib/dds.dart
index 03ced9f..c71a3d6 100644
--- a/pkg/dds/lib/dds.dart
+++ b/pkg/dds/lib/dds.dart
@@ -7,12 +7,14 @@
library dds;
import 'dart:async';
+import 'dart:collection';
import 'dart:convert';
import 'dart:io';
import 'dart:typed_data';
import 'package:async/async.dart';
import 'package:json_rpc_2/json_rpc_2.dart' as json_rpc;
+import 'package:meta/meta.dart';
import 'package:pedantic/pedantic.dart';
import 'package:shelf/shelf.dart';
import 'package:shelf/shelf_io.dart' as io;
@@ -24,6 +26,8 @@
part 'src/binary_compatible_peer.dart';
part 'src/client.dart';
part 'src/dds_impl.dart';
+part 'src/named_lookup.dart';
+part 'src/rpc_error_codes.dart';
part 'src/stream_manager.dart';
/// An intermediary between a Dart VM service and its clients that offers
@@ -33,7 +37,8 @@
/// for details.
abstract class DartDevelopmentService {
/// Creates a [DartDevelopmentService] instance which will communicate with a
- /// VM service.
+ /// VM service. Requires the target VM service to have no other connected
+ /// clients.
///
/// [remoteVmServiceUri] is the address of the VM service that this
/// development service will communicate with.
@@ -94,3 +99,11 @@
/// requests.
bool get isRunning;
}
+
+class DartDevelopmentServiceException implements Exception {
+ DartDevelopmentServiceException._(this.message);
+
+ String toString() => 'DartDevelopmentServiceException: $message';
+
+ final String message;
+}
diff --git a/pkg/dds/lib/src/client.dart b/pkg/dds/lib/src/client.dart
index 11dac82..a6e39c2 100644
--- a/pkg/dds/lib/src/client.dart
+++ b/pkg/dds/lib/src/client.dart
@@ -30,13 +30,21 @@
}
/// Send a JSON RPC notification to the client.
- void sendNotification(String method, [dynamic parameters]) async {
+ void sendNotification(String method, [dynamic parameters]) {
if (_clientPeer.isClosed) {
return;
}
_clientPeer.sendNotification(method, parameters);
}
+ /// Send a JSON RPC request to the client.
+ Future<dynamic> sendRequest(String method, [dynamic parameters]) async {
+ if (_clientPeer.isClosed) {
+ return null;
+ }
+ return await _clientPeer.sendRequest(method, parameters);
+ }
+
/// Registers handlers for JSON RPC methods which need to be intercepted by
/// DDS as well as fallback request forwarder.
void _registerJsonRpcMethods() {
@@ -52,7 +60,65 @@
return _success;
});
+ _clientPeer.registerMethod('registerService', (parameters) async {
+ final serviceId = parameters['service'].asString;
+ final alias = parameters['alias'].asString;
+ if (services.containsKey(serviceId)) {
+ throw _RpcErrorCodes.buildRpcException(
+ _RpcErrorCodes.kServiceAlreadyRegistered,
+ );
+ }
+ services[serviceId] = alias;
+ // Notify other clients that a new service extension is available.
+ dds.streamManager.sendServiceRegisteredEvent(
+ this,
+ serviceId,
+ alias,
+ );
+ return _success;
+ });
+
+ // When invoked within a fallback, the next fallback will start executing.
+ // The final fallback forwards the request to the VM service directly.
+ @alwaysThrows
+ nextFallback() => throw json_rpc.RpcException.methodNotFound('');
+
+ // Handle service extension invocations.
+ _clientPeer.registerFallback((parameters) async {
+ hasNamespace(String method) => method.contains('.');
+ getMethod(String method) => method.split('.').last;
+ getNamespace(String method) => method.split('.').first;
+ if (!hasNamespace(parameters.method)) {
+ nextFallback();
+ }
+ // Lookup the client associated with the service extension's namespace.
+ // If the client exists and that client has registered the specified
+ // method, forward the request to that client.
+ final method = getMethod(parameters.method);
+ final namespace = getNamespace(parameters.method);
+ final serviceClient = dds._clients[namespace];
+ if (serviceClient != null && serviceClient.services.containsKey(method)) {
+ return await Future.any(
+ [
+ // Forward the request to the service client or...
+ serviceClient.sendRequest(method, parameters.asMap),
+ // if the service client closes, return an error response.
+ serviceClient._clientPeer.done.then(
+ (_) => throw _RpcErrorCodes.buildRpcException(
+ _RpcErrorCodes.kServiceDisappeared,
+ ),
+ ),
+ ],
+ );
+ }
+ throw json_rpc.RpcException(
+ _RpcErrorCodes.kMethodNotFound,
+ 'Unknown service: ${parameters.method}',
+ );
+ });
+
// Unless otherwise specified, the request is forwarded to the VM service.
+ // NOTE: This must be the last fallback registered.
_clientPeer.registerFallback((parameters) async =>
await _vmServicePeer.sendRequest(parameters.method, parameters.asMap));
}
@@ -62,6 +128,7 @@
};
final _DartDevelopmentService dds;
+ final Map<String, String> services = {};
final json_rpc.Peer _vmServicePeer;
final WebSocketChannel ws;
json_rpc.Peer _clientPeer;
diff --git a/pkg/dds/lib/src/dds_impl.dart b/pkg/dds/lib/src/dds_impl.dart
index fb2bf74..4cd7b2d 100644
--- a/pkg/dds/lib/src/dds_impl.dart
+++ b/pkg/dds/lib/src/dds_impl.dart
@@ -31,7 +31,23 @@
// Start the DDS server.
_server = await io.serve(_handlers().handler, host, port);
- _uri = Uri(scheme: 'http', host: host, port: _server.port);
+
+ final tmpUri = Uri(scheme: 'http', host: host, port: _server.port);
+
+ // Notify the VM service that this client is DDS and that it should close
+ // and refuse connections from other clients. DDS is now acting in place of
+ // the VM service.
+ try {
+ await _vmServiceClient.sendRequest('_yieldControlToDDS', {
+ 'uri': tmpUri.toString(),
+ });
+ } on json_rpc.RpcException catch (e) {
+ await _server.close(force: true);
+ // _yieldControlToDDS fails if DDS is not the only VM service client.
+ throw DartDevelopmentServiceException._(e.data['details']);
+ }
+
+ _uri = tmpUri;
}
/// Stop accepting requests after gracefully handling existing requests.
@@ -91,6 +107,9 @@
return uri.replace(scheme: 'ws', pathSegments: pathSegments);
}
+ String _getNamespace(_DartDevelopmentServiceClient client) =>
+ _clients.keyOf(client);
+
Uri get remoteVmServiceUri => _remoteVmServiceUri;
Uri get remoteVmServiceWsUri => _toWebSocket(_remoteVmServiceUri);
Uri _remoteVmServiceUri;
@@ -107,7 +126,11 @@
_StreamManager get streamManager => _streamManager;
_StreamManager _streamManager;
- final List<_DartDevelopmentServiceClient> _clients = [];
+ // Handles namespace generation for service extensions.
+ static const _kServicePrologue = 's';
+ final NamedLookup<_DartDevelopmentServiceClient> _clients = NamedLookup(
+ prologue: _kServicePrologue,
+ );
json_rpc.Peer _vmServiceClient;
WebSocketChannel _vmServiceSocket;
diff --git a/pkg/dds/lib/src/named_lookup.dart b/pkg/dds/lib/src/named_lookup.dart
new file mode 100644
index 0000000..4b89633
--- /dev/null
+++ b/pkg/dds/lib/src/named_lookup.dart
@@ -0,0 +1,72 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Originally pulled from dart:_vmservice.
+
+part of dds;
+
+/// [Set]-like containers which automatically generate [String] IDs for its
+/// items.
+class NamedLookup<E> with IterableMixin<E> {
+ final IdGenerator _generator;
+ final Map<String, E> _elements = {};
+ final Map<E, String> _ids = {};
+
+ NamedLookup({String prologue = ''})
+ : _generator = IdGenerator(prologue: prologue);
+
+ void add(E e) {
+ final id = _generator.newId();
+ _elements[id] = e;
+ _ids[e] = id;
+ }
+
+ void remove(E e) {
+ final id = _ids.remove(e);
+ _elements.remove(id);
+ _generator.release(id);
+ }
+
+ E operator [](String id) => _elements[id];
+ String keyOf(E e) => _ids[e];
+
+ Iterator<E> get iterator => _ids.keys.iterator;
+}
+
+/// Generator for unique IDs which recycles expired ones.
+class IdGenerator {
+ /// Fixed initial part of the ID
+ final String prologue;
+
+ // IDs in use.
+ final Set<String> _used = {};
+
+ /// IDs to be recycled (use these before generate new ones).
+ final Set<String> _free = {};
+
+ /// Next ID to generate when no recycled IDs are available.
+ int _next = 0;
+
+ IdGenerator({this.prologue = ''});
+
+ /// Returns a new ID (possibly recycled).
+ String newId() {
+ String id;
+ if (_free.isEmpty) {
+ id = prologue + (_next++).toString();
+ } else {
+ id = _free.first;
+ }
+ _free.remove(id);
+ _used.add(id);
+ return id;
+ }
+
+ /// Releases the ID and mark it for recycling.
+ void release(String id) {
+ if (_used.remove(id)) {
+ _free.add(id);
+ }
+ }
+}
diff --git a/pkg/dds/lib/src/rpc_error_codes.dart b/pkg/dds/lib/src/rpc_error_codes.dart
new file mode 100644
index 0000000..84b1f62
--- /dev/null
+++ b/pkg/dds/lib/src/rpc_error_codes.dart
@@ -0,0 +1,52 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+part of dds;
+
+abstract class _RpcErrorCodes {
+ static json_rpc.RpcException buildRpcException(int code) {
+ return json_rpc.RpcException(
+ code,
+ errorMessages[code],
+ );
+ }
+
+ // These error codes must be kept in sync with those in vm/json_stream.h and
+ // vmservice.dart.
+ // static const kParseError = -32700;
+ // static const kInvalidRequest = -32600;
+ static const kMethodNotFound = -32601;
+ // static const kInvalidParams = -32602;
+ // static const kInternalError = -32603;
+
+ // static const kExtensionError = -32000;
+
+ static const kFeatureDisabled = 100;
+ // static const kCannotAddBreakpoint = 102;
+ static const kStreamAlreadySubscribed = 103;
+ static const kStreamNotSubscribed = 104;
+ // static const kIsolateMustBeRunnable = 105;
+ // static const kIsolateMustBePaused = 106;
+ // static const kCannotResume = 107;
+ // static const kIsolateIsReloading = 108;
+ // static const kIsolateReloadBarred = 109;
+ // static const kIsolateMustHaveReloaded = 110;
+ static const kServiceAlreadyRegistered = 111;
+ static const kServiceDisappeared = 112;
+ // static const kExpressionCompilationError = 113;
+ // static const kInvalidTimelineRequest = 114;
+
+ // Experimental (used in private rpcs).
+ // static const kFileSystemAlreadyExists = 1001;
+ // static const kFileSystemDoesNotExist = 1002;
+ // static const kFileDoesNotExist = 1003;
+
+ static const errorMessages = {
+ kFeatureDisabled: 'Feature is disabled',
+ kStreamAlreadySubscribed: 'Stream already subscribed',
+ kStreamNotSubscribed: 'Stream not subscribed',
+ kServiceAlreadyRegistered: 'Service already registered',
+ kServiceDisappeared: 'Service has disappeared',
+ };
+}
diff --git a/pkg/dds/lib/src/stream_manager.dart b/pkg/dds/lib/src/stream_manager.dart
index 318cc39..6e2d8dd 100644
--- a/pkg/dds/lib/src/stream_manager.dart
+++ b/pkg/dds/lib/src/stream_manager.dart
@@ -12,11 +12,21 @@
/// If `data` is of type `Uint8List`, the notification is assumed to be a
/// binary event and is forwarded directly over the subscriber's websocket.
/// Otherwise, the event is sent via the JSON RPC client.
- void streamNotify(String streamId, data) {
+ ///
+ /// If `excludedClient` is provided, the notification will be sent to all
+ /// clients subscribed to `streamId` except for `excludedClient`.
+ void streamNotify(
+ String streamId,
+ data, {
+ _DartDevelopmentServiceClient excludedClient,
+ }) {
if (streamListeners.containsKey(streamId)) {
final listeners = streamListeners[streamId];
final isBinaryData = data is Uint8List;
for (final listener in listeners) {
+ if (listener == excludedClient) {
+ continue;
+ }
if (isBinaryData) {
listener.ws.sink.add(data);
} else {
@@ -26,6 +36,51 @@
}
}
+ void sendServiceRegisteredEvent(
+ _DartDevelopmentServiceClient client,
+ String service,
+ String alias,
+ ) {
+ final namespace = dds._getNamespace(client);
+ streamNotify(
+ kServiceStream,
+ {
+ 'streamId': kServiceStream,
+ 'event': {
+ 'type': 'Event',
+ 'kind': 'ServiceRegistered',
+ 'timestamp': DateTime.now().millisecondsSinceEpoch,
+ 'service': service,
+ 'method': namespace + '.' + service,
+ 'alias': alias,
+ },
+ },
+ excludedClient: client,
+ );
+ }
+
+ void _sendServiceUnregisteredEvents(
+ _DartDevelopmentServiceClient client,
+ ) {
+ final namespace = dds._getNamespace(client);
+ for (final service in client.services.keys) {
+ streamNotify(
+ kServiceStream,
+ {
+ 'streamId': kServiceStream,
+ 'event': {
+ 'type': 'Event',
+ 'kind': 'ServiceUnregistered',
+ 'timestamp': DateTime.now().millisecondsSinceEpoch,
+ 'service': service,
+ 'method': namespace + '.' + service,
+ },
+ },
+ excludedClient: client,
+ );
+ }
+ }
+
/// Start listening for `streamNotify` events from the VM service and forward
/// them to the clients which have subscribed to the stream.
void listen() => dds._vmServiceClient.registerMethod(
@@ -88,24 +143,26 @@
/// Cleanup stream subscriptions for `client` when it has disconnected.
void clientDisconnect(_DartDevelopmentServiceClient client) {
for (final streamId in streamListeners.keys.toList()) {
- streamCancel(client, streamId);
+ streamCancel(client, streamId).catchError(
+ (_) => null,
+ // Ignore 'stream not subscribed' errors.
+ test: (e) => e is json_rpc.RpcException,
+ );
}
+ // Notify other service clients of service extensions that are being
+ // unregistered.
+ _sendServiceUnregisteredEvents(client);
}
- // These error codes must be kept in sync with those in vm/json_stream.h and
- // vmservice.dart.
- static const kStreamAlreadySubscribed = 103;
- static const kStreamNotSubscribed = 104;
+ static const kServiceStream = 'Service';
- // Keep these messages in sync with the VM service.
- static final kStreamAlreadySubscribedException = json_rpc.RpcException(
- kStreamAlreadySubscribed,
- 'Stream already subscribed',
+ static final kStreamAlreadySubscribedException =
+ _RpcErrorCodes.buildRpcException(
+ _RpcErrorCodes.kStreamAlreadySubscribed,
);
- static final kStreamNotSubscribedException = json_rpc.RpcException(
- kStreamNotSubscribed,
- 'Stream not subscribed',
+ static final kStreamNotSubscribedException = _RpcErrorCodes.buildRpcException(
+ _RpcErrorCodes.kStreamNotSubscribed,
);
final _DartDevelopmentService dds;
diff --git a/pkg/dds/test/smoke_test.dart b/pkg/dds/test/smoke_test.dart
index 6e6c1ed..39468b0 100644
--- a/pkg/dds/test/smoke_test.dart
+++ b/pkg/dds/test/smoke_test.dart
@@ -41,35 +41,78 @@
}
void main() {
- test('DDS Smoke Test', () async {
- final process = await spawnDartProcess('smoke.dart');
- final dds = await DartDevelopmentService.startDartDevelopmentService(
- remoteVmServiceUri,
- );
- expect(dds.isRunning, true);
+ group('DDS', () {
+ Process process;
+ DartDevelopmentService dds;
- // Ensure basic websocket requests are forwarded correctly to the VM service.
- final service = await vmServiceConnectUri(dds.wsUri.toString());
- final version = await service.getVersion();
- expect(version.major > 0, true);
- expect(version.minor > 0, true);
+ setUp(() async {
+ process = await spawnDartProcess('smoke.dart');
+ });
- // Ensure we can still make requests of the VM service via HTTP.
- HttpClient client = HttpClient();
- final request = await client.getUrl(remoteVmServiceUri.replace(
- pathSegments: [
- remoteVmServiceUri.pathSegments.first,
- 'getVersion',
- ],
- ));
- final response = await request.close();
- final Map<String, dynamic> jsonResponse =
- (await response.transform(utf8.decoder).transform(json.decoder).single);
- expect(jsonResponse['result']['type'], 'Version');
- expect(jsonResponse['result']['major'] > 0, true);
- expect(jsonResponse['result']['minor'] > 0, true);
- await dds.shutdown();
- process.kill();
+ tearDown(() async {
+ await dds?.shutdown();
+ process?.kill();
+ dds = null;
+ process = null;
+ });
+
+ test('Smoke Test', () async {
+ dds = await DartDevelopmentService.startDartDevelopmentService(
+ remoteVmServiceUri,
+ );
+ expect(dds.isRunning, true);
+
+ // Ensure basic websocket requests are forwarded correctly to the VM service.
+ final service = await vmServiceConnectUri(dds.wsUri.toString());
+ final version = await service.getVersion();
+ expect(version.major > 0, true);
+ expect(version.minor > 0, true);
+
+ // Ensure we can still make requests of the VM service via HTTP.
+ HttpClient client = HttpClient();
+ final request = await client.getUrl(remoteVmServiceUri.replace(
+ pathSegments: [
+ if (remoteVmServiceUri.pathSegments.isNotEmpty)
+ remoteVmServiceUri.pathSegments.first,
+ 'getVersion',
+ ],
+ ));
+ final response = await request.close();
+ final Map<String, dynamic> jsonResponse = (await response
+ .transform(utf8.decoder)
+ .transform(json.decoder)
+ .single);
+ expect(jsonResponse['result']['type'], 'Version');
+ expect(jsonResponse['result']['major'] > 0, true);
+ expect(jsonResponse['result']['minor'] > 0, true);
+ });
+
+ test('startup fails when VM service has existing clients', () async {
+ Uri httpToWebSocketUri(Uri httpUri) {
+ final segments = (httpUri.pathSegments.isNotEmpty)
+ ? (httpUri.pathSegments.toList()..removeLast())
+ : <String>[];
+ segments.add('ws');
+ return httpUri.replace(
+ scheme: 'ws',
+ pathSegments: segments,
+ );
+ }
+
+ final _ = await vmServiceConnectUri(
+ httpToWebSocketUri(remoteVmServiceUri).toString(),
+ );
+ try {
+ dds = await DartDevelopmentService.startDartDevelopmentService(
+ remoteVmServiceUri,
+ );
+ fail(
+ 'DDS startup should fail if there are existing VM service clients.');
+ } on DartDevelopmentServiceException catch (e) {
+ expect(e.message,
+ 'Existing VM service clients prevent DDS from taking control.');
+ }
+ });
});
test('Invalid args test', () async {
diff --git a/pkg/dev_compiler/lib/src/kernel/target.dart b/pkg/dev_compiler/lib/src/kernel/target.dart
index acf7573..cea0477 100644
--- a/pkg/dev_compiler/lib/src/kernel/target.dart
+++ b/pkg/dev_compiler/lib/src/kernel/target.dart
@@ -158,7 +158,7 @@
{void Function(String msg) logger,
ChangedStructureNotifier changedStructureNotifier}) {
if (flags.trackWidgetCreation) {
- _widgetTracker ??= WidgetCreatorTracker();
+ _widgetTracker ??= WidgetCreatorTracker(changedStructureNotifier);
_widgetTracker.transform(component, libraries);
}
}
diff --git a/pkg/dev_compiler/tool/dartdevc_nnbd_sdk_error_golden.txt b/pkg/dev_compiler/tool/dartdevc_nnbd_sdk_error_golden.txt
index b093430..1f1e98a 100644
--- a/pkg/dev_compiler/tool/dartdevc_nnbd_sdk_error_golden.txt
+++ b/pkg/dev_compiler/tool/dartdevc_nnbd_sdk_error_golden.txt
@@ -1,9 +1,9 @@
-ERROR|COMPILE_TIME_ERROR|CONST_CONSTRUCTOR_THROWS_EXCEPTION|lib/core/core.dart|3716|5|94|Const constructors can't throw exceptions.
-ERROR|COMPILE_TIME_ERROR|CONST_CONSTRUCTOR_THROWS_EXCEPTION|lib/core/core.dart|7902|5|97|Const constructors can't throw exceptions.
+ERROR|COMPILE_TIME_ERROR|CONST_CONSTRUCTOR_THROWS_EXCEPTION|lib/core/core.dart|3719|5|94|Const constructors can't throw exceptions.
+ERROR|COMPILE_TIME_ERROR|CONST_CONSTRUCTOR_THROWS_EXCEPTION|lib/core/core.dart|7908|5|97|Const constructors can't throw exceptions.
ERROR|COMPILE_TIME_ERROR|CONST_CONSTRUCTOR_THROWS_EXCEPTION|lib/core/core.dart|940|5|95|Const constructors can't throw exceptions.
ERROR|COMPILE_TIME_ERROR|CONST_CONSTRUCTOR_THROWS_EXCEPTION|lib/core/core.dart|973|5|94|Const constructors can't throw exceptions.
ERROR|STATIC_WARNING|ARGUMENT_TYPE_NOT_ASSIGNABLE|lib/io/io.dart|6334|51|12|The argument type 'Object' can't be assigned to the parameter type 'String'.
-ERROR|SYNTACTIC_ERROR|CONST_FACTORY|lib/core/core.dart|3714|3|5|Only redirecting factory constructors can be declared to be 'const'.
-ERROR|SYNTACTIC_ERROR|CONST_FACTORY|lib/core/core.dart|7900|3|5|Only redirecting factory constructors can be declared to be 'const'.
+ERROR|SYNTACTIC_ERROR|CONST_FACTORY|lib/core/core.dart|3717|3|5|Only redirecting factory constructors can be declared to be 'const'.
+ERROR|SYNTACTIC_ERROR|CONST_FACTORY|lib/core/core.dart|7906|3|5|Only redirecting factory constructors can be declared to be 'const'.
ERROR|SYNTACTIC_ERROR|CONST_FACTORY|lib/core/core.dart|938|3|5|Only redirecting factory constructors can be declared to be 'const'.
ERROR|SYNTACTIC_ERROR|CONST_FACTORY|lib/core/core.dart|971|3|5|Only redirecting factory constructors can be declared to be 'const'.
diff --git a/pkg/front_end/lib/src/fasta/incremental_compiler.dart b/pkg/front_end/lib/src/fasta/incremental_compiler.dart
index 20acc5d..3da4fa2 100644
--- a/pkg/front_end/lib/src/fasta/incremental_compiler.dart
+++ b/pkg/front_end/lib/src/fasta/incremental_compiler.dart
@@ -281,9 +281,14 @@
await userCode.buildComponent(verify: c.options.verify);
}
hierarchy ??= userCode.loader.hierarchy;
- if (hierarchy != null && userCode.classesChangedStructure != null) {
- hierarchy.applyMemberChanges(userCode.classesChangedStructure,
- findDescendants: true);
+ if (hierarchy != null) {
+ if (userCode.classHierarchyChanges != null) {
+ hierarchy.applyTreeChanges([], [], userCode.classHierarchyChanges);
+ }
+ if (userCode.classMemberChanges != null) {
+ hierarchy.applyMemberChanges(userCode.classMemberChanges,
+ findDescendants: true);
+ }
}
recordNonFullComponentForTesting(componentWithDill);
@@ -789,7 +794,7 @@
Library lib = builder.library;
removedLibraries.add(lib);
}
- hierarchy.applyTreeChanges(removedLibraries, const []);
+ hierarchy.applyTreeChanges(removedLibraries, const [], const []);
}
}
@@ -1380,7 +1385,7 @@
incrementalSerializer?.invalidate(builder.fileUri);
}
}
- hierarchy?.applyTreeChanges(removedLibraries, const []);
+ hierarchy?.applyTreeChanges(removedLibraries, const [], const []);
if (removedDillBuilders) {
makeDillLoaderLibrariesUpToDateWithBuildersMap();
}
@@ -1923,7 +1928,9 @@
class IncrementalKernelTarget extends KernelTarget
implements ChangedStructureNotifier {
- Set<Class> classesChangedStructure;
+ Set<Class> classHierarchyChanges;
+ Set<Class> classMemberChanges;
+
IncrementalKernelTarget(FileSystem fileSystem, bool includeComments,
DillTarget dillTarget, UriTranslator uriTranslator)
: super(fileSystem, includeComments, dillTarget, uriTranslator);
@@ -1931,8 +1938,14 @@
ChangedStructureNotifier get changedStructureNotifier => this;
@override
- void forClass(Class c) {
- classesChangedStructure ??= new Set<Class>();
- classesChangedStructure.add(c);
+ void registerClassMemberChange(Class c) {
+ classMemberChanges ??= new Set<Class>();
+ classMemberChanges.add(c);
+ }
+
+ @override
+ void registerClassHierarchyChange(Class cls) {
+ classHierarchyChanges ??= <Class>{};
+ classHierarchyChanges.add(cls);
}
}
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart
index 4688b62..fa7ea0c 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart
@@ -1073,7 +1073,8 @@
loader.coreTypes,
loader.libraries,
new KernelDiagnosticReporter(loader),
- logger: (String msg) => ticker.logMs(msg));
+ logger: (String msg) => ticker.logMs(msg),
+ changedStructureNotifier: changedStructureNotifier);
TypeEnvironment environment =
new TypeEnvironment(loader.coreTypes, loader.hierarchy);
diff --git a/pkg/front_end/lib/src/fasta/source/source_class_builder.dart b/pkg/front_end/lib/src/fasta/source/source_class_builder.dart
index 2f37d76..75eacd7 100644
--- a/pkg/front_end/lib/src/fasta/source/source_class_builder.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_class_builder.dart
@@ -799,15 +799,25 @@
Member bestSoFar = members.first;
DartType bestSoFarType =
forSetters ? bestSoFar.setterType : bestSoFar.getterType;
- bestSoFarType = Substitution.fromSupertype(
- hierarchy.getClassAsInstanceOf(cls, bestSoFar.enclosingClass))
- .substituteType(bestSoFarType);
+ Supertype supertype =
+ hierarchy.getClassAsInstanceOf(cls, bestSoFar.enclosingClass);
+ assert(
+ supertype != null,
+ "No supertype of enclosing class ${bestSoFar.enclosingClass} for "
+ "$bestSoFar found for $cls.");
+ bestSoFarType =
+ Substitution.fromSupertype(supertype).substituteType(bestSoFarType);
for (int i = 1; i < members.length; ++i) {
Member candidate = members[i];
DartType candidateType =
forSetters ? candidate.setterType : candidate.getterType;
- Substitution substitution = Substitution.fromSupertype(
- hierarchy.getClassAsInstanceOf(cls, candidate.enclosingClass));
+ Supertype supertype =
+ hierarchy.getClassAsInstanceOf(cls, candidate.enclosingClass);
+ assert(
+ supertype != null,
+ "No supertype of enclosing class ${candidate.enclosingClass} for "
+ "$candidate found for $cls.");
+ Substitution substitution = Substitution.fromSupertype(supertype);
candidateType = substitution.substituteType(candidateType);
memberTypes.add(candidateType);
bool isMoreSpecific = forSetters
diff --git a/pkg/front_end/lib/src/fasta/source/source_loader.dart b/pkg/front_end/lib/src/fasta/source/source_loader.dart
index ad7173c..92f6450 100644
--- a/pkg/front_end/lib/src/fasta/source/source_loader.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_loader.dart
@@ -926,7 +926,7 @@
hierarchy.onAmbiguousSupertypes = onAmbiguousSupertypes;
Component component = computeFullComponent();
hierarchy.coreTypes = coreTypes;
- hierarchy.applyTreeChanges(const [], component.libraries,
+ hierarchy.applyTreeChanges(const [], component.libraries, const [],
reissueAmbiguousSupertypesFor: component);
}
for (AmbiguousTypesRecord record in ambiguousTypesRecords) {
diff --git a/pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart b/pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart
index c8b7fa4..d2628dd 100644
--- a/pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart
+++ b/pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart
@@ -2967,7 +2967,8 @@
FunctionType functionType = getFunctionTypeForImplicitCall(calleeType);
List<VariableDeclaration> locallyHoistedExpressions;
- if (hoistedExpressions == null) {
+ if (hoistedExpressions == null && !isTopLevel) {
+ // We don't hoist in top-level inference.
hoistedExpressions = locallyHoistedExpressions = <VariableDeclaration>[];
}
if (arguments.positional.isNotEmpty || arguments.named.isNotEmpty) {
@@ -3006,7 +3007,7 @@
isImplicitCall: true,
implicitInvocationPropertyName: getter.name);
- if (isExpressionInvocation) {
+ if (!isTopLevel && isExpressionInvocation) {
Expression error = helper.buildProblem(
templateImplicitCallOfNonMethod.withArguments(
receiverType, isNonNullableByDefault),
@@ -3080,7 +3081,8 @@
FunctionType functionType = getFunctionTypeForImplicitCall(calleeType);
List<VariableDeclaration> locallyHoistedExpressions;
- if (hoistedExpressions == null) {
+ if (hoistedExpressions == null && !isTopLevel) {
+ // We don't hoist in top-level inference.
hoistedExpressions = locallyHoistedExpressions = <VariableDeclaration>[];
}
if (arguments.positional.isNotEmpty || arguments.named.isNotEmpty) {
@@ -3120,7 +3122,7 @@
hoistedExpressions: hoistedExpressions,
implicitInvocationPropertyName: field.name);
- if (isExpressionInvocation) {
+ if (!isTopLevel && isExpressionInvocation) {
Expression error = helper.buildProblem(
templateImplicitCallOfNonMethod.withArguments(
receiverType, isNonNullableByDefault),
diff --git a/pkg/front_end/test/ast_nodes_has_to_string_test.dart b/pkg/front_end/test/ast_nodes_has_to_string_test.dart
index efab92a0..dd3cbf7 100644
--- a/pkg/front_end/test/ast_nodes_has_to_string_test.dart
+++ b/pkg/front_end/test/ast_nodes_has_to_string_test.dart
@@ -18,7 +18,7 @@
{
Uri input = Platform.script.resolve("../tool/_fasta/compile.dart");
- CompilerOptions options = helper.getOptions(targetName: "VM");
+ CompilerOptions options = helper.getOptions();
helper.TestIncrementalCompiler compiler =
new helper.TestIncrementalCompiler(
options,
diff --git a/pkg/front_end/test/crashing_test_case_minimizer.dart b/pkg/front_end/test/crashing_test_case_minimizer.dart
new file mode 100644
index 0000000..797bded
--- /dev/null
+++ b/pkg/front_end/test/crashing_test_case_minimizer.dart
@@ -0,0 +1,344 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:convert' show utf8;
+
+import 'dart:io' show BytesBuilder, File;
+
+import 'dart:typed_data' show Uint8List;
+
+import 'package:_fe_analyzer_shared/src/parser/parser.dart' show Parser;
+
+import 'package:_fe_analyzer_shared/src/scanner/scanner.dart'
+ show ScannerConfiguration, Token;
+
+import 'package:_fe_analyzer_shared/src/scanner/token.dart' show Token;
+
+import 'package:front_end/src/api_prototype/compiler_options.dart'
+ show CompilerOptions, DiagnosticMessage;
+
+import 'package:front_end/src/api_prototype/memory_file_system.dart'
+ show MemoryFileSystem;
+
+import 'package:front_end/src/base/processed_options.dart'
+ show ProcessedOptions;
+
+import 'package:front_end/src/compute_platform_binaries_location.dart'
+ show computePlatformBinariesLocation;
+
+import 'package:front_end/src/fasta/compiler_context.dart' show CompilerContext;
+
+import 'package:front_end/src/fasta/incremental_compiler.dart'
+ show IncrementalCompiler;
+
+import 'package:kernel/ast.dart' show Component;
+
+import 'parser_test_listener.dart' show ParserTestListener;
+
+import 'parser_suite.dart' as parser_suite;
+
+import 'incremental_load_from_dill_suite.dart' show getOptions;
+
+Uri sdkRoot = computePlatformBinariesLocation(forceBuildDir: true);
+Uri base = Uri.parse("org-dartlang-test:///");
+Uri sdkSummary = base.resolve("vm_platform.dill");
+Uri platformUri = sdkRoot.resolve("vm_platform_strong.dill");
+
+main(List<String> arguments) async {
+ String filename;
+ bool nnbd = false;
+ for (String arg in arguments) {
+ if (arg.startsWith("--")) {
+ if (arg == "--nnbd") {
+ nnbd = true;
+ } else {
+ throw "Unknown option $arg";
+ }
+ } else if (filename != null) {
+ throw "Already got '$filename', '$arg' is also a filename; "
+ "can only get one";
+ } else {
+ filename = arg;
+ }
+ }
+ if (filename == null) {
+ throw "Need file to operate on";
+ }
+ File file = new File(filename);
+ if (!file.existsSync()) throw "File $filename doesn't exist.";
+
+ await tryToMinimize(file, nnbd);
+}
+
+Future tryToMinimize(File file, bool nnbd) async {
+ Uint8List data;
+ try {
+ String parsedString = getFileAsStringContent(file, nnbd);
+ data = utf8.encode(parsedString);
+ } catch (e) {
+ // If this crash it's a crash in the scanner/parser. It's good to minimize
+ // that too.
+ data = file.readAsBytesSync();
+ }
+
+ print("Got data");
+
+ Uri main = base.resolve("main.dart");
+
+ CompilerContext compilerContext = setupCompilerContext(main);
+ Component initialComponent = await getInitialComponent(compilerContext);
+ MemoryFileSystem fs = compilerContext.options.fileSystem;
+
+ print("Compiled initially (without data)");
+
+ // First assure it actually crash on the input.
+ if (!await crashesOnCompile(
+ fs, main, data, compilerContext, initialComponent)) {
+ throw "Input doesn't crash the compiler: ${dataToText(data)}";
+ }
+ print("Step #1: We did crash on the input!");
+
+ // Try to delete lines.
+ Uint8List latestCrashData =
+ await deleteLines(data, fs, main, compilerContext, initialComponent);
+ print("We're now at ${latestCrashData.length} bytes.");
+
+ // Now try to delete 'arbitrarily' (for any given start offset do an
+ // exponential binary search).
+ int prevLength = latestCrashData.length;
+ while (true) {
+ latestCrashData = await binarySearchDeleteData(
+ latestCrashData, fs, main, compilerContext, initialComponent);
+
+ if (latestCrashData.length == prevLength) {
+ // No progress.
+ break;
+ } else {
+ print("We're now at ${latestCrashData.length} bytes");
+ prevLength = latestCrashData.length;
+ }
+ }
+
+ print("Got it down to ${latestCrashData.length} bytes: "
+ "${dataToText(latestCrashData)}");
+ try {
+ String utfDecoded = utf8.decode(latestCrashData, allowMalformed: true);
+ print("That's '$utfDecoded' as text");
+ } catch (e) {
+ print("(which crashes when trying to decode as utf8)");
+ }
+}
+
+Uint8List sublist(Uint8List data, int start, int end) {
+ Uint8List result = new Uint8List(end - start);
+ result.setRange(0, result.length, data, start);
+ return result;
+}
+
+String dataToText(Uint8List data) {
+ StringBuffer sb = new StringBuffer();
+ String comma = "[";
+ for (int i = 0; i < data.length; i++) {
+ sb.write(comma);
+ sb.write(data[i]);
+ comma = ", ";
+ if (i > 100) break;
+ }
+ if (data.length > 100) {
+ sb.write("...");
+ }
+ sb.write("]");
+ return sb.toString();
+}
+
+Future<Uint8List> binarySearchDeleteData(
+ Uint8List latestCrashData,
+ MemoryFileSystem fs,
+ Uri main,
+ CompilerContext compilerContext,
+ Component initialComponent) async {
+ int offset = 0;
+ while (offset < latestCrashData.length) {
+ print("Working at offset $offset of ${latestCrashData.length}");
+ BytesBuilder builder = new BytesBuilder();
+ builder.add(sublist(latestCrashData, 0, offset));
+ builder.add(sublist(latestCrashData, offset + 1, latestCrashData.length));
+ Uint8List candidate = builder.takeBytes();
+ if (!await crashesOnCompile(
+ fs, main, candidate, compilerContext, initialComponent)) {
+ // Deleting 1 char didn't crash; don't try to delete anymore starting
+ // here.
+ offset++;
+ continue;
+ }
+
+ // Find how long we can go.
+ int crashingAt = 1;
+ int noLongerCrashingAt;
+ while (true) {
+ int deleteChars = 2 * crashingAt;
+ if (offset + deleteChars > latestCrashData.length) {
+ deleteChars = latestCrashData.length - offset;
+ }
+ builder = new BytesBuilder();
+ builder.add(sublist(latestCrashData, 0, offset));
+ builder.add(sublist(
+ latestCrashData, offset + deleteChars, latestCrashData.length));
+ candidate = builder.takeBytes();
+ if (!await crashesOnCompile(
+ fs, main, candidate, compilerContext, initialComponent)) {
+ noLongerCrashingAt = deleteChars;
+ break;
+ }
+ crashingAt = deleteChars;
+ if (crashingAt + offset == latestCrashData.length) break;
+ }
+
+ if (noLongerCrashingAt == null) {
+ // We can delete the rest.
+ latestCrashData = candidate;
+ continue;
+ }
+
+ // Binary search between [crashingAt] and [noLongerCrashingAt].
+ while (crashingAt < noLongerCrashingAt) {
+ int mid = noLongerCrashingAt -
+ ((noLongerCrashingAt - crashingAt) >> 1); // Get middle, rounding up.
+ builder = new BytesBuilder();
+ builder.add(sublist(latestCrashData, 0, offset));
+ builder
+ .add(sublist(latestCrashData, offset + mid, latestCrashData.length));
+ candidate = builder.takeBytes();
+ if (await crashesOnCompile(
+ fs, main, candidate, compilerContext, initialComponent)) {
+ crashingAt = mid;
+ } else {
+ // [noLongerCrashingAt] might actually crash now.
+ noLongerCrashingAt = mid - 1;
+ }
+ }
+
+ // This is basically an assert.
+ builder = new BytesBuilder();
+ builder.add(sublist(latestCrashData, 0, offset));
+ builder.add(
+ sublist(latestCrashData, offset + crashingAt, latestCrashData.length));
+ candidate = builder.takeBytes();
+ if (!await crashesOnCompile(
+ fs, main, candidate, compilerContext, initialComponent)) {
+ throw "Error in binary search.";
+ }
+ latestCrashData = candidate;
+ }
+ return latestCrashData;
+}
+
+Future<Uint8List> deleteLines(Uint8List data, MemoryFileSystem fs, Uri main,
+ CompilerContext compilerContext, Component initialComponent) async {
+ // Try to delete "lines".
+ const int $LF = 10;
+ Uint8List latestCrashData = data;
+ List<Uint8List> lines = [];
+ int start = 0;
+ for (int i = 0; i < data.length; i++) {
+ if (data[i] == $LF) {
+ lines.add(sublist(data, start, i));
+ start = i + 1;
+ }
+ }
+ lines.add(sublist(data, start, data.length));
+ List<bool> include = new List.filled(lines.length, true);
+ for (int i = 0; i < lines.length; i++) {
+ include[i] = false;
+ final BytesBuilder builder = new BytesBuilder();
+ for (int j = 0; j < lines.length; j++) {
+ if (include[j]) {
+ builder.add(lines[j]);
+ if (j + 1 < lines.length) {
+ builder.addByte($LF);
+ }
+ }
+ }
+ Uint8List candidate = builder.takeBytes();
+ if (!await crashesOnCompile(
+ fs, main, candidate, compilerContext, initialComponent)) {
+ // Didn't crash => Can't remove line i.
+ include[i] = true;
+ } else {
+ print("Can delete line $i");
+ latestCrashData = candidate;
+ }
+ }
+ return latestCrashData;
+}
+
+Future<bool> crashesOnCompile(MemoryFileSystem fs, Uri main, Uint8List data,
+ CompilerContext compilerContext, Component initialComponent) async {
+ fs.entityForUri(main).writeAsBytesSync(data);
+ IncrementalCompiler incrementalCompiler =
+ new IncrementalCompiler.fromComponent(compilerContext, initialComponent);
+ incrementalCompiler.invalidate(main);
+ try {
+ await incrementalCompiler.computeDelta();
+ return false;
+ } catch (e) {
+ return true;
+ }
+}
+
+Future<Component> getInitialComponent(CompilerContext compilerContext) async {
+ IncrementalCompiler incrementalCompiler =
+ new IncrementalCompiler(compilerContext);
+ Component originalComponent = await incrementalCompiler.computeDelta();
+ return originalComponent;
+}
+
+CompilerContext setupCompilerContext(Uri main) {
+ Uint8List sdkSummaryData = new File.fromUri(platformUri).readAsBytesSync();
+ MemoryFileSystem fs = new MemoryFileSystem(base);
+ CompilerOptions options = getOptions();
+
+ options.fileSystem = fs;
+ options.sdkRoot = null;
+ options.sdkSummary = sdkSummary;
+ options.omitPlatform = false;
+ options.onDiagnostic = (DiagnosticMessage message) {
+ // don't care.
+ };
+ fs.entityForUri(sdkSummary).writeAsBytesSync(sdkSummaryData);
+ fs.entityForUri(main).writeAsStringSync("main() {}");
+
+ CompilerContext compilerContext = new CompilerContext(
+ new ProcessedOptions(options: options, inputs: [main]));
+ return compilerContext;
+}
+
+String getFileAsStringContent(File file, bool nnbd) {
+ Uint8List rawBytes = file.readAsBytesSync();
+ List<int> lineStarts = new List<int>();
+
+ Token firstToken = parser_suite.scanRawBytes(rawBytes,
+ nnbd ? scannerConfiguration : scannerConfigurationNonNNBD, lineStarts);
+
+ if (firstToken == null) {
+ throw "Got null token from scanner";
+ }
+
+ ParserTestListener parserTestListener = new ParserTestListener(false);
+ Parser parser = new Parser(parserTestListener);
+ parser.parseUnit(firstToken);
+ String parsedString =
+ parser_suite.tokenStreamToString(firstToken, lineStarts).toString();
+ return parsedString;
+}
+
+ScannerConfiguration scannerConfiguration = new ScannerConfiguration(
+ enableTripleShift: true,
+ enableExtensionMethods: true,
+ enableNonNullable: true);
+
+ScannerConfiguration scannerConfigurationNonNNBD = new ScannerConfiguration(
+ enableTripleShift: true,
+ enableExtensionMethods: true,
+ enableNonNullable: false);
diff --git a/pkg/front_end/test/id_testing/data/marker.options b/pkg/front_end/test/id_testing/data/marker.options
index bb35ae5..c846376b 100644
--- a/pkg/front_end/test/id_testing/data/marker.options
+++ b/pkg/front_end/test/id_testing/data/marker.options
@@ -1,2 +1,3 @@
cfe=pkg/front_end/test/id_testing/id_testing_test.dart
dart2js=tests/compiler/dart2js/equivalence/id_testing_test.dart
+dart2js:nnbd-sdk=tests/compiler/dart2js/equivalence/id_testing_test.dart
diff --git a/pkg/front_end/test/incremental_dart2js_load_from_dill_test.dart b/pkg/front_end/test/incremental_dart2js_load_from_dill_test.dart
index ec1eebd..2d7e57c 100644
--- a/pkg/front_end/test/incremental_dart2js_load_from_dill_test.dart
+++ b/pkg/front_end/test/incremental_dart2js_load_from_dill_test.dart
@@ -46,7 +46,7 @@
// type inference occurring before or after mixin transformation.
Stopwatch stopwatch = new Stopwatch()..start();
await normalCompile(dart2jsUrl, normalDill,
- options: getOptions()..target = new NoneTarget(new TargetFlags()));
+ options: getOptions(target: new NoneTarget(new TargetFlags())));
print("Normal compile took ${stopwatch.elapsedMilliseconds} ms");
{
// Check that we don't include the source from files from the sdk.
@@ -84,7 +84,7 @@
stopwatch.reset();
bool initializeResult = await initializedCompile(
dart2jsUrl, fullDillFromInitialized, initializeWith, [invalidateUri],
- options: getOptions()..target = new NoneTarget(new TargetFlags()));
+ options: getOptions(target: new NoneTarget(new TargetFlags())));
Expect.equals(initializeExpect, initializeResult);
print("Initialized compile(s) from ${initializeWith.pathSegments.last} "
"took ${stopwatch.elapsedMilliseconds} ms");
@@ -99,7 +99,7 @@
stopwatch.reset();
initializeResult = await initializedCompile(
dart2jsUrl, fullDillFromInitialized, initializeWith, [],
- options: getOptions()..target = new NoneTarget(new TargetFlags()));
+ options: getOptions(target: new NoneTarget(new TargetFlags())));
Expect.equals(initializeExpect, initializeResult);
print("Initialized compile(s) from ${initializeWith.pathSegments.last} "
"took ${stopwatch.elapsedMilliseconds} ms");
diff --git a/pkg/front_end/test/incremental_dart2js_tester.dart b/pkg/front_end/test/incremental_dart2js_tester.dart
index 8a5401c..a67953d 100644
--- a/pkg/front_end/test/incremental_dart2js_tester.dart
+++ b/pkg/front_end/test/incremental_dart2js_tester.dart
@@ -174,7 +174,7 @@
stopwatch.reset();
stopwatch.start();
Uri input = Platform.script.resolve("../../compiler/bin/dart2js.dart");
- CompilerOptions options = helper.getOptions(targetName: "VM");
+ CompilerOptions options = helper.getOptions();
helper.TestIncrementalCompiler compiler =
new helper.TestIncrementalCompiler(options, input);
compiler.useExperimentalInvalidation = useExperimentalInvalidation;
diff --git a/pkg/front_end/test/incremental_load_from_dill_suite.dart b/pkg/front_end/test/incremental_load_from_dill_suite.dart
index 97a33b5..015e3d5 100644
--- a/pkg/front_end/test/incremental_load_from_dill_suite.dart
+++ b/pkg/front_end/test/incremental_load_from_dill_suite.dart
@@ -15,6 +15,8 @@
import 'package:_fe_analyzer_shared/src/messages/severity.dart' show Severity;
+import "package:dev_compiler/src/kernel/target.dart" show DevCompilerTarget;
+
import 'package:expect/expect.dart' show Expect;
import 'package:front_end/src/api_prototype/compiler_options.dart'
@@ -59,7 +61,8 @@
LibraryDependency,
Member,
Name,
- Procedure;
+ Procedure,
+ Supertype;
import 'package:kernel/target/targets.dart'
show NoneTarget, Target, TargetFlags;
@@ -164,6 +167,7 @@
"omitPlatform",
"target",
"forceLateLoweringForTesting",
+ "trackWidgetCreation",
"incrementalSerialization"
]);
await new NewWorldTest().newWorldTest(
@@ -173,7 +177,8 @@
map["modules"],
map["omitPlatform"],
map["target"],
- map["forceLateLoweringForTesting"],
+ map["forceLateLoweringForTesting"] ?? false,
+ map["trackWidgetCreation"] ?? false,
map["incrementalSerialization"],
);
break;
@@ -245,16 +250,13 @@
checkIsEqual(normalDillData, initializedDillData);
}
-Future<Map<String, List<int>>> createModules(
- Map module,
- final List<int> sdkSummaryData,
- String targetName,
- bool forceLateLoweringForTesting) async {
+Future<Map<String, List<int>>> createModules(Map module,
+ final List<int> sdkSummaryData, Target target, String sdkSummary) async {
final Uri base = Uri.parse("org-dartlang-test:///");
- final Uri sdkSummary = base.resolve("vm_platform_strong.dill");
+ final Uri sdkSummaryUri = base.resolve(sdkSummary);
MemoryFileSystem fs = new MemoryFileSystem(base);
- fs.entityForUri(sdkSummary).writeAsBytesSync(sdkSummaryData);
+ fs.entityForUri(sdkSummaryUri).writeAsBytesSync(sdkSummaryData);
// Setup all sources
for (Map moduleSources in module.values) {
@@ -281,12 +283,11 @@
moduleSources.add(uri);
}
}
- CompilerOptions options = getOptions(
- targetName: targetName,
- forceLateLoweringForTesting: forceLateLoweringForTesting);
+ CompilerOptions options =
+ getOptions(target: target, sdkSummary: sdkSummary);
options.fileSystem = fs;
options.sdkRoot = null;
- options.sdkSummary = sdkSummary;
+ options.sdkSummary = sdkSummaryUri;
options.omitPlatform = true;
options.onDiagnostic = (DiagnosticMessage message) {
if (getMessageCodeObject(message)?.name == "InferredPackageUri") return;
@@ -334,12 +335,32 @@
bool omitPlatform,
String targetName,
bool forceLateLoweringForTesting,
+ bool trackWidgetCreation,
bool incrementalSerialization) async {
final Uri sdkRoot = computePlatformBinariesLocation(forceBuildDir: true);
+
+ TargetFlags targetFlags = new TargetFlags(
+ forceLateLoweringForTesting: forceLateLoweringForTesting,
+ trackWidgetCreation: trackWidgetCreation);
+ Target target = new VmTarget(targetFlags);
+ String sdkSummary = "vm_platform_strong.dill";
+ if (targetName != null) {
+ if (targetName == "None") {
+ target = new NoneTarget(targetFlags);
+ } else if (targetName == "DDC") {
+ target = new DevCompilerTarget(targetFlags);
+ sdkSummary = "ddc_platform.dill";
+ } else if (targetName == "VM") {
+ // default.
+ } else {
+ throw "Unknown target name '$targetName'";
+ }
+ }
+
final Uri base = Uri.parse("org-dartlang-test:///");
- final Uri sdkSummary = base.resolve("vm_platform_strong.dill");
+ final Uri sdkSummaryUri = base.resolve(sdkSummary);
final Uri initializeFrom = base.resolve("initializeFrom.dill");
- Uri platformUri = sdkRoot.resolve("vm_platform_strong.dill");
+ Uri platformUri = sdkRoot.resolve(sdkSummary);
final List<int> sdkSummaryData =
await new File.fromUri(platformUri).readAsBytes();
@@ -354,8 +375,8 @@
Map<String, Component> moduleComponents;
if (modules != null) {
- moduleData = await createModules(
- modules, sdkSummaryData, targetName, forceLateLoweringForTesting);
+ moduleData =
+ await createModules(modules, sdkSummaryData, target, sdkSummary);
sdk = newestWholeComponent = new Component();
new BinaryBuilder(sdkSummaryData,
filename: null, disableLazyReading: false)
@@ -411,7 +432,7 @@
if (brandNewWorld) {
fs = new MemoryFileSystem(base);
}
- fs.entityForUri(sdkSummary).writeAsBytesSync(sdkSummaryData);
+ fs.entityForUri(sdkSummaryUri).writeAsBytesSync(sdkSummaryData);
bool expectInitializeFromDill = false;
if (newestWholeComponentData != null &&
newestWholeComponentData.isNotEmpty) {
@@ -443,12 +464,10 @@
}
if (brandNewWorld) {
- options = getOptions(
- targetName: targetName,
- forceLateLoweringForTesting: forceLateLoweringForTesting);
+ options = getOptions(target: target, sdkSummary: sdkSummary);
options.fileSystem = fs;
options.sdkRoot = null;
- options.sdkSummary = sdkSummary;
+ options.sdkSummary = sdkSummaryUri;
options.omitPlatform = omitPlatform != false;
if (world["experiments"] != null) {
Map<ExperimentalFlag, bool> experimentalFlags =
@@ -908,10 +927,32 @@
sb.writeln("Library ${library.importUri}");
for (Class c in library.classes) {
sb.writeln(" - Class ${c.name}");
+
+ Set<Class> checkedSupertypes = <Class>{};
+ void checkSupertype(Supertype supertype) {
+ if (supertype == null) return;
+ Class superclass = supertype.classNode;
+ if (checkedSupertypes.add(superclass)) {
+ Supertype asSuperClass =
+ classHierarchy.getClassAsInstanceOf(c, superclass);
+ if (asSuperClass == null) {
+ throw "${superclass} not found as a superclass of $c";
+ }
+ checkSupertype(superclass.supertype);
+ checkSupertype(superclass.mixedInType);
+ for (Supertype interface in superclass.implementedTypes) {
+ checkSupertype(interface);
+ }
+ }
+ }
+
+ checkSupertype(c.asThisSupertype);
+
ForTestingClassInfo info = classHierarchyMap[c];
if (info == null) {
throw "Didn't find any class hierarchy info for $c";
}
+
if (info.lazyDeclaredGettersAndCalls != null) {
sb.writeln(" - lazyDeclaredGettersAndCalls:");
for (Member member in info.lazyDeclaredGettersAndCalls) {
@@ -1330,20 +1371,10 @@
Expect.equals(a.length, b.length);
}
-CompilerOptions getOptions(
- {String targetName, bool forceLateLoweringForTesting: false}) {
+CompilerOptions getOptions({Target target, String sdkSummary}) {
+ target ??= new VmTarget(new TargetFlags());
+ sdkSummary ??= 'vm_platform_strong.dill';
final Uri sdkRoot = computePlatformBinariesLocation(forceBuildDir: true);
- Target target = new VmTarget(new TargetFlags(
- forceLateLoweringForTesting: forceLateLoweringForTesting));
- if (targetName != null) {
- if (targetName == "None") {
- target = new NoneTarget(new TargetFlags());
- } else if (targetName == "VM") {
- // default.
- } else {
- throw "Unknown target name '$targetName'";
- }
- }
CompilerOptions options = new CompilerOptions()
..sdkRoot = sdkRoot
..target = target
@@ -1356,7 +1387,7 @@
"Unexpected error: ${message.plainTextFormatted.join('\n')}");
}
}
- ..sdkSummary = sdkRoot.resolve("vm_platform_strong.dill")
+ ..sdkSummary = sdkRoot.resolve(sdkSummary)
..environmentDefines = const {};
return options;
}
diff --git a/pkg/front_end/test/parser_suite.dart b/pkg/front_end/test/parser_suite.dart
index 4824e2e..cbbf1219 100644
--- a/pkg/front_end/test/parser_suite.dart
+++ b/pkg/front_end/test/parser_suite.dart
@@ -237,66 +237,66 @@
}
});
}
+}
- StringBuffer tokenStreamToString(Token firstToken, List<int> lineStarts,
- {bool addTypes: false}) {
- StringBuffer sb = new StringBuffer();
- Token token = firstToken;
+StringBuffer tokenStreamToString(Token firstToken, List<int> lineStarts,
+ {bool addTypes: false}) {
+ StringBuffer sb = new StringBuffer();
+ Token token = firstToken;
- Token process(Token token, bool errorTokens) {
- bool printed = false;
- int endOfLast = -1;
- int lineStartsIteratorLine = 1;
- Iterator<int> lineStartsIterator = lineStarts.iterator;
- lineStartsIterator.moveNext();
- lineStartsIterator.moveNext();
- lineStartsIteratorLine++;
+ Token process(Token token, bool errorTokens) {
+ bool printed = false;
+ int endOfLast = -1;
+ int lineStartsIteratorLine = 1;
+ Iterator<int> lineStartsIterator = lineStarts.iterator;
+ lineStartsIterator.moveNext();
+ lineStartsIterator.moveNext();
+ lineStartsIteratorLine++;
- while (token != null) {
- if (errorTokens && token is! ErrorToken) return token;
- if (!errorTokens && token is ErrorToken) {
- if (token == token.next) break;
- token = token.next;
- continue;
- }
-
- int prevLine = lineStartsIteratorLine;
- while (token.offset >= lineStartsIterator.current &&
- lineStartsIterator.moveNext()) {
- lineStartsIteratorLine++;
- }
- if (printed &&
- (token.offset > endOfLast || prevLine < lineStartsIteratorLine)) {
- if (prevLine < lineStartsIteratorLine) {
- for (int i = prevLine; i < lineStartsIteratorLine; i++) {
- sb.write("\n");
- }
- } else {
- sb.write(" ");
- }
- }
- if (token is! ErrorToken) {
- sb.write(token.lexeme);
- }
- if (addTypes) {
- sb.write("[${token.runtimeType}]");
- }
- printed = true;
- endOfLast = token.end;
+ while (token != null) {
+ if (errorTokens && token is! ErrorToken) return token;
+ if (!errorTokens && token is ErrorToken) {
if (token == token.next) break;
token = token.next;
+ continue;
}
- return token;
+ int prevLine = lineStartsIteratorLine;
+ while (token.offset >= lineStartsIterator.current &&
+ lineStartsIterator.moveNext()) {
+ lineStartsIteratorLine++;
+ }
+ if (printed &&
+ (token.offset > endOfLast || prevLine < lineStartsIteratorLine)) {
+ if (prevLine < lineStartsIteratorLine) {
+ for (int i = prevLine; i < lineStartsIteratorLine; i++) {
+ sb.write("\n");
+ }
+ } else {
+ sb.write(" ");
+ }
+ }
+ if (token is! ErrorToken) {
+ sb.write(token.lexeme);
+ }
+ if (addTypes) {
+ sb.write("[${token.runtimeType}]");
+ }
+ printed = true;
+ endOfLast = token.end;
+ if (token == token.next) break;
+ token = token.next;
}
- if (addTypes) {
- token = process(token, true);
- }
- token = process(token, false);
-
- return sb;
+ return token;
}
+
+ if (addTypes) {
+ token = process(token, true);
+ }
+ token = process(token, false);
+
+ return sb;
}
Token scanUri(Uri uri, String shortName, {List<int> lineStarts}) {
@@ -312,6 +312,11 @@
File f = new File.fromUri(uri);
List<int> rawBytes = f.readAsBytesSync();
+ return scanRawBytes(rawBytes, config, lineStarts);
+}
+
+Token scanRawBytes(
+ List<int> rawBytes, ScannerConfiguration config, List<int> lineStarts) {
Uint8List bytes = new Uint8List(rawBytes.length + 1);
bytes.setRange(0, rawBytes.length, rawBytes);
diff --git a/pkg/front_end/test/read_dill_from_binary_md_test.dart b/pkg/front_end/test/read_dill_from_binary_md_test.dart
index 8b9c6d3..4907f4e 100644
--- a/pkg/front_end/test/read_dill_from_binary_md_test.dart
+++ b/pkg/front_end/test/read_dill_from_binary_md_test.dart
@@ -23,7 +23,7 @@
final Uri dart2jsUrl = Uri.base.resolve("pkg/compiler/bin/dart2js.dart");
Stopwatch stopwatch = new Stopwatch()..start();
List<int> bytes = await normalCompileToBytes(dart2jsUrl,
- options: getOptions()..target = new NoneTarget(new TargetFlags()));
+ options: getOptions(target: new NoneTarget(new TargetFlags())));
print("Compiled dart2js in ${stopwatch.elapsedMilliseconds} ms");
stopwatch.reset();
diff --git a/pkg/front_end/test/spell_checking_list_code.txt b/pkg/front_end/test/spell_checking_list_code.txt
index 93a4423..88dcde6 100644
--- a/pkg/front_end/test/spell_checking_list_code.txt
+++ b/pkg/front_end/test/spell_checking_list_code.txt
@@ -106,6 +106,7 @@
bj
blob
blocking
+bmp
bn
bo
bodied
@@ -239,6 +240,7 @@
cyclically
d
d11e
+d7c
dag
dangerous
dangling
@@ -595,6 +597,7 @@
mangled
manipulation
markdown
+masking
matcher
mb
md
@@ -925,6 +928,7 @@
shallow
shas
shelf
+shifts
showing
shrinking
shru
@@ -1199,6 +1203,7 @@
worthwhile
writeln
wrt
+wtf
www
x
x0
@@ -1239,6 +1244,7 @@
xn
xnon
xor
+xor's
xpotentially
xs
xss
diff --git a/pkg/front_end/test/spell_checking_list_common.txt b/pkg/front_end/test/spell_checking_list_common.txt
index aae076c..2327236 100644
--- a/pkg/front_end/test/spell_checking_list_common.txt
+++ b/pkg/front_end/test/spell_checking_list_common.txt
@@ -1054,8 +1054,8 @@
exited
exits
expand
-expands
expanding
+expands
expansion
expect
expectation
@@ -1411,6 +1411,7 @@
included
includes
including
+inclusion
inclusive
incoming
incompatible
@@ -1706,6 +1707,7 @@
logging
logic
logical
+lone
long
longer
longest
@@ -1768,6 +1770,7 @@
matter
maturity
max
+maximal
maximum
may
maybe
@@ -1843,6 +1846,7 @@
modulo
moment
mongolian
+monotonous
more
moreover
most
@@ -1944,6 +1948,7 @@
objects
oblivious
observation
+observations
observed
obtain
obtained
@@ -2247,6 +2252,7 @@
promotion
promotions
propagate
+propagates
propagating
propagation
proper
@@ -2327,6 +2333,8 @@
recognizes
recommend
recommendations
+recomputation
+recomputes
record
recorded
recording
@@ -2991,6 +2999,7 @@
translates
translating
translator
+traveling
traversed
treat
treated
@@ -3017,6 +3026,8 @@
truly
truncate
truncating
+trust
+trusts
truth
try
trying
diff --git a/pkg/front_end/test/spell_checking_list_tests.txt b/pkg/front_end/test/spell_checking_list_tests.txt
index 95a7bb3..2b8ccc0 100644
--- a/pkg/front_end/test/spell_checking_list_tests.txt
+++ b/pkg/front_end/test/spell_checking_list_tests.txt
@@ -27,8 +27,10 @@
aoo
approval
approximation
+arbitrarily
asdf
asserter
+assure
auth
authority
auto
@@ -279,6 +281,7 @@
issue41496b
issue41498b
issue41499b
+it'll
iter
joo
jumped
@@ -340,6 +343,7 @@
metrics
mf
micro
+minimize
minutes
mismatched
misnamed
@@ -365,6 +369,7 @@
oh
okay
ooo
+operate
ops
optimal
oracle
diff --git a/pkg/front_end/test/test_generator_test.dart b/pkg/front_end/test/test_generator_test.dart
index d0e3e1a..9ce654d 100644
--- a/pkg/front_end/test/test_generator_test.dart
+++ b/pkg/front_end/test/test_generator_test.dart
@@ -130,7 +130,7 @@
MemoryFileSystem fs = new MemoryFileSystem(base);
fs.entityForUri(sdkSummary).writeAsBytesSync(sdkSummaryData);
- CompilerOptions options = helper.getOptions(targetName: "VM");
+ CompilerOptions options = helper.getOptions();
options.fileSystem = fs;
options.sdkRoot = null;
options.sdkSummary = sdkSummary;
diff --git a/pkg/front_end/test/utils/kernel_chain.dart b/pkg/front_end/test/utils/kernel_chain.dart
index a9d27a9..855e343 100644
--- a/pkg/front_end/test/utils/kernel_chain.dart
+++ b/pkg/front_end/test/utils/kernel_chain.dart
@@ -369,7 +369,7 @@
for (Library library in component.libraries) {
if (library.importUri.scheme != "dart" &&
library.importUri.scheme != "package") {
- library.accept(verifier);
+ verifier.verify(library);
}
}
for (TextSerializationVerificationFailure failure in verifier.failures) {
diff --git a/pkg/front_end/testcases/extensions/call_methods.dart b/pkg/front_end/testcases/extensions/call_methods.dart
index cf0ecfab..3ae8fe3 100644
--- a/pkg/front_end/testcases/extensions/call_methods.dart
+++ b/pkg/front_end/testcases/extensions/call_methods.dart
@@ -26,6 +26,15 @@
""();
}
+var topLevel1 = 1(10);
+var topLevel2 = 1("10");
+var topLevel3 = 1.0(10);
+var topLevel4 = 1.0("10");
+A a = new A();
+var topLevel5 = a(2);
+B b = new B();
+var topLevel6 = a(2, "3");
+
errors() {
1(10);
1("10");
diff --git a/pkg/front_end/testcases/extensions/call_methods.dart.outline.expect b/pkg/front_end/testcases/extensions/call_methods.dart.outline.expect
index b57cf7b..04fd8c7 100644
--- a/pkg/front_end/testcases/extensions/call_methods.dart.outline.expect
+++ b/pkg/front_end/testcases/extensions/call_methods.dart.outline.expect
@@ -23,6 +23,14 @@
extension _extension#2 on core::String* {
get call = self::_extension#2|get#call;
}
+static field core::String* topLevel1;
+static field core::String* topLevel2;
+static field core::String* topLevel3;
+static field core::String* topLevel4;
+static field self::A* a;
+static field core::String* topLevel5;
+static field self::B* b;
+static field core::String* topLevel6;
static method _extension#0|get#call(final core::int* #this) → core::String*
;
static method _extension#1|get#call(final core::num* #this) → core::String*
diff --git a/pkg/front_end/testcases/extensions/call_methods.dart.strong.expect b/pkg/front_end/testcases/extensions/call_methods.dart.strong.expect
index e831fc5..7835653 100644
--- a/pkg/front_end/testcases/extensions/call_methods.dart.strong.expect
+++ b/pkg/front_end/testcases/extensions/call_methods.dart.strong.expect
@@ -2,49 +2,91 @@
//
// Problems in library:
//
-// pkg/front_end/testcases/extensions/call_methods.dart:30:4: Error: Too many positional arguments: 0 allowed, but 1 found.
+// pkg/front_end/testcases/extensions/call_methods.dart:29:18: Error: Too many positional arguments: 0 allowed, but 1 found.
+// Try removing the extra positional arguments.
+// var topLevel1 = 1(10);
+// ^
+//
+// pkg/front_end/testcases/extensions/call_methods.dart:30:18: Error: Too many positional arguments: 0 allowed, but 1 found.
+// Try removing the extra positional arguments.
+// var topLevel2 = 1("10");
+// ^
+//
+// pkg/front_end/testcases/extensions/call_methods.dart:31:20: Error: Too many positional arguments: 0 allowed, but 1 found.
+// Try removing the extra positional arguments.
+// var topLevel3 = 1.0(10);
+// ^
+//
+// pkg/front_end/testcases/extensions/call_methods.dart:32:20: Error: Too many positional arguments: 0 allowed, but 1 found.
+// Try removing the extra positional arguments.
+// var topLevel4 = 1.0("10");
+// ^
+//
+// pkg/front_end/testcases/extensions/call_methods.dart:34:18: Error: Too many positional arguments: 0 allowed, but 1 found.
+// Try removing the extra positional arguments.
+// var topLevel5 = a(2);
+// ^
+//
+// pkg/front_end/testcases/extensions/call_methods.dart:34:18: Error: Cannot invoke an instance of 'A' because it declares 'call' to be something other than a method.
+// - 'A' is from 'pkg/front_end/testcases/extensions/call_methods.dart'.
+// Try changing 'call' to a method or explicitly invoke 'call'.
+// var topLevel5 = a(2);
+// ^
+//
+// pkg/front_end/testcases/extensions/call_methods.dart:36:18: Error: Too many positional arguments: 0 allowed, but 2 found.
+// Try removing the extra positional arguments.
+// var topLevel6 = a(2, "3");
+// ^
+//
+// pkg/front_end/testcases/extensions/call_methods.dart:36:18: Error: Cannot invoke an instance of 'A' because it declares 'call' to be something other than a method.
+// - 'A' is from 'pkg/front_end/testcases/extensions/call_methods.dart'.
+// Try changing 'call' to a method or explicitly invoke 'call'.
+// var topLevel6 = a(2, "3");
+// ^
+//
+// pkg/front_end/testcases/extensions/call_methods.dart:39:4: Error: Too many positional arguments: 0 allowed, but 1 found.
// Try removing the extra positional arguments.
// 1(10);
// ^
//
-// pkg/front_end/testcases/extensions/call_methods.dart:31:4: Error: Too many positional arguments: 0 allowed, but 1 found.
+// pkg/front_end/testcases/extensions/call_methods.dart:40:4: Error: Too many positional arguments: 0 allowed, but 1 found.
// Try removing the extra positional arguments.
// 1("10");
// ^
//
-// pkg/front_end/testcases/extensions/call_methods.dart:32:6: Error: Too many positional arguments: 0 allowed, but 1 found.
+// pkg/front_end/testcases/extensions/call_methods.dart:41:6: Error: Too many positional arguments: 0 allowed, but 1 found.
// Try removing the extra positional arguments.
// 1.0(10);
// ^
//
-// pkg/front_end/testcases/extensions/call_methods.dart:33:6: Error: Too many positional arguments: 0 allowed, but 1 found.
+// pkg/front_end/testcases/extensions/call_methods.dart:42:6: Error: Too many positional arguments: 0 allowed, but 1 found.
// Try removing the extra positional arguments.
// 1.0("10");
// ^
//
-// pkg/front_end/testcases/extensions/call_methods.dart:35:4: Error: Too many positional arguments: 0 allowed, but 1 found.
+// pkg/front_end/testcases/extensions/call_methods.dart:44:4: Error: Too many positional arguments: 0 allowed, but 1 found.
// Try removing the extra positional arguments.
// a(2);
// ^
//
-// pkg/front_end/testcases/extensions/call_methods.dart:35:4: Error: Cannot invoke an instance of 'A' because it declares 'call' to be something other than a method.
+// pkg/front_end/testcases/extensions/call_methods.dart:44:4: Error: Cannot invoke an instance of 'A' because it declares 'call' to be something other than a method.
// - 'A' is from 'pkg/front_end/testcases/extensions/call_methods.dart'.
// Try changing 'call' to a method or explicitly invoke 'call'.
// a(2);
// ^
//
-// pkg/front_end/testcases/extensions/call_methods.dart:36:4: Error: Too many positional arguments: 0 allowed, but 2 found.
+// pkg/front_end/testcases/extensions/call_methods.dart:45:4: Error: Too many positional arguments: 0 allowed, but 2 found.
// Try removing the extra positional arguments.
// a(2, "3");
// ^
//
-// pkg/front_end/testcases/extensions/call_methods.dart:36:4: Error: Cannot invoke an instance of 'A' because it declares 'call' to be something other than a method.
+// pkg/front_end/testcases/extensions/call_methods.dart:45:4: Error: Cannot invoke an instance of 'A' because it declares 'call' to be something other than a method.
// - 'A' is from 'pkg/front_end/testcases/extensions/call_methods.dart'.
// Try changing 'call' to a method or explicitly invoke 'call'.
// a(2, "3");
// ^
//
-// pkg/front_end/testcases/extensions/call_methods.dart:38:4: Error: Cannot invoke an instance of 'B' because it declares 'call' to be something other than a method.
+// pkg/front_end/testcases/extensions/call_methods.dart:47:4: Error: Cannot invoke an instance of 'B' because it declares 'call' to be something other than a method.
// - 'B' is from 'pkg/front_end/testcases/extensions/call_methods.dart'.
// Try changing 'call' to a method or explicitly invoke 'call'.
// b();
@@ -76,6 +118,34 @@
extension _extension#2 on core::String* {
get call = self::_extension#2|get#call;
}
+static field core::String* topLevel1 = let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/extensions/call_methods.dart:29:18: Error: Too many positional arguments: 0 allowed, but 1 found.
+Try removing the extra positional arguments.
+var topLevel1 = 1(10);
+ ^" in self::_extension#2|get#call(self::_extension#0|get#call(1)).call(10);
+static field core::String* topLevel2 = let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/extensions/call_methods.dart:30:18: Error: Too many positional arguments: 0 allowed, but 1 found.
+Try removing the extra positional arguments.
+var topLevel2 = 1(\"10\");
+ ^" in self::_extension#2|get#call(self::_extension#0|get#call(1)).call("10");
+static field core::String* topLevel3 = let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/extensions/call_methods.dart:31:20: Error: Too many positional arguments: 0 allowed, but 1 found.
+Try removing the extra positional arguments.
+var topLevel3 = 1.0(10);
+ ^" in self::_extension#2|get#call(self::_extension#1|get#call(1.0)).call(10);
+static field core::String* topLevel4 = let final<BottomType> #t4 = invalid-expression "pkg/front_end/testcases/extensions/call_methods.dart:32:20: Error: Too many positional arguments: 0 allowed, but 1 found.
+Try removing the extra positional arguments.
+var topLevel4 = 1.0(\"10\");
+ ^" in self::_extension#2|get#call(self::_extension#1|get#call(1.0)).call("10");
+static field self::A* a = new self::A::•();
+static field core::String* topLevel5 = invalid-expression "pkg/front_end/testcases/extensions/call_methods.dart:34:18: Error: Cannot invoke an instance of 'A' because it declares 'call' to be something other than a method.
+ - 'A' is from 'pkg/front_end/testcases/extensions/call_methods.dart'.
+Try changing 'call' to a method or explicitly invoke 'call'.
+var topLevel5 = a(2);
+ ^" as{TypeError,ForDynamic} core::String*;
+static field self::B* b = new self::B::•();
+static field core::String* topLevel6 = invalid-expression "pkg/front_end/testcases/extensions/call_methods.dart:36:18: Error: Cannot invoke an instance of 'A' because it declares 'call' to be something other than a method.
+ - 'A' is from 'pkg/front_end/testcases/extensions/call_methods.dart'.
+Try changing 'call' to a method or explicitly invoke 'call'.
+var topLevel6 = a(2, \"3\");
+ ^" as{TypeError,ForDynamic} core::String*;
static method _extension#0|get#call(final core::int* #this) → core::String*
return "My name is int";
static method _extension#1|get#call(final core::num* #this) → core::String*
@@ -86,35 +156,35 @@
self::_extension#2|get#call("").call();
}
static method errors() → dynamic {
- let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/extensions/call_methods.dart:30:4: Error: Too many positional arguments: 0 allowed, but 1 found.
+ let final<BottomType> #t5 = invalid-expression "pkg/front_end/testcases/extensions/call_methods.dart:39:4: Error: Too many positional arguments: 0 allowed, but 1 found.
Try removing the extra positional arguments.
1(10);
^" in self::_extension#2|get#call(self::_extension#0|get#call(1)).call(10);
- let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/extensions/call_methods.dart:31:4: Error: Too many positional arguments: 0 allowed, but 1 found.
+ let final<BottomType> #t6 = invalid-expression "pkg/front_end/testcases/extensions/call_methods.dart:40:4: Error: Too many positional arguments: 0 allowed, but 1 found.
Try removing the extra positional arguments.
1(\"10\");
^" in self::_extension#2|get#call(self::_extension#0|get#call(1)).call("10");
- let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/extensions/call_methods.dart:32:6: Error: Too many positional arguments: 0 allowed, but 1 found.
+ let final<BottomType> #t7 = invalid-expression "pkg/front_end/testcases/extensions/call_methods.dart:41:6: Error: Too many positional arguments: 0 allowed, but 1 found.
Try removing the extra positional arguments.
1.0(10);
^" in self::_extension#2|get#call(self::_extension#1|get#call(1.0)).call(10);
- let final<BottomType> #t4 = invalid-expression "pkg/front_end/testcases/extensions/call_methods.dart:33:6: Error: Too many positional arguments: 0 allowed, but 1 found.
+ let final<BottomType> #t8 = invalid-expression "pkg/front_end/testcases/extensions/call_methods.dart:42:6: Error: Too many positional arguments: 0 allowed, but 1 found.
Try removing the extra positional arguments.
1.0(\"10\");
^" in self::_extension#2|get#call(self::_extension#1|get#call(1.0)).call("10");
self::A* a = new self::A::•();
- invalid-expression "pkg/front_end/testcases/extensions/call_methods.dart:35:4: Error: Cannot invoke an instance of 'A' because it declares 'call' to be something other than a method.
+ invalid-expression "pkg/front_end/testcases/extensions/call_methods.dart:44:4: Error: Cannot invoke an instance of 'A' because it declares 'call' to be something other than a method.
- 'A' is from 'pkg/front_end/testcases/extensions/call_methods.dart'.
Try changing 'call' to a method or explicitly invoke 'call'.
a(2);
^";
- invalid-expression "pkg/front_end/testcases/extensions/call_methods.dart:36:4: Error: Cannot invoke an instance of 'A' because it declares 'call' to be something other than a method.
+ invalid-expression "pkg/front_end/testcases/extensions/call_methods.dart:45:4: Error: Cannot invoke an instance of 'A' because it declares 'call' to be something other than a method.
- 'A' is from 'pkg/front_end/testcases/extensions/call_methods.dart'.
Try changing 'call' to a method or explicitly invoke 'call'.
a(2, \"3\");
^";
self::B* b = new self::B::•();
- invalid-expression "pkg/front_end/testcases/extensions/call_methods.dart:38:4: Error: Cannot invoke an instance of 'B' because it declares 'call' to be something other than a method.
+ invalid-expression "pkg/front_end/testcases/extensions/call_methods.dart:47:4: Error: Cannot invoke an instance of 'B' because it declares 'call' to be something other than a method.
- 'B' is from 'pkg/front_end/testcases/extensions/call_methods.dart'.
Try changing 'call' to a method or explicitly invoke 'call'.
b();
diff --git a/pkg/front_end/testcases/general/call.dart b/pkg/front_end/testcases/general/call.dart
index 1543991..4152cd8 100644
--- a/pkg/front_end/testcases/general/call.dart
+++ b/pkg/front_end/testcases/general/call.dart
@@ -46,3 +46,36 @@
var nothing11 = callableGetter.call.call();
var nothing12 = callableGetter.call.call.call();
}
+
+var closure = (x) => x;
+var int1 = closure(1);
+var int2 = closure.call(1);
+var int3 = closure.call.call(1);
+var int4 = closure.call.call.call(1);
+
+var callable = new Callable();
+var string1 = callable(1);
+var string2 = callable.call(1);
+var string3 = callable.call.call(1);
+var string4 = callable.call.call.call(1);
+
+var callableGetter = new CallableGetter();
+var string5 = callableGetter(1);
+var string6 = callableGetter.call(1);
+var string7 = callableGetter.call.call(1);
+var string8 = callableGetter.call.call.call(1);
+
+var nothing1 = closure();
+var nothing2 = closure.call();
+var nothing3 = closure.call.call();
+var nothing4 = closure.call.call.call();
+
+var nothing5 = callable();
+var nothing6 = callable.call();
+var nothing7 = callable.call.call();
+var nothing8 = callable.call.call.call();
+
+var nothing9 = callableGetter();
+var nothing10 = callableGetter.call();
+var nothing11 = callableGetter.call.call();
+var nothing12 = callableGetter.call.call.call();
diff --git a/pkg/front_end/testcases/general/call.dart.outline.expect b/pkg/front_end/testcases/general/call.dart.outline.expect
index 5aba50d..93fbf2a 100644
--- a/pkg/front_end/testcases/general/call.dart.outline.expect
+++ b/pkg/front_end/testcases/general/call.dart.outline.expect
@@ -14,5 +14,32 @@
get call() → dynamic
;
}
+static field (dynamic) →* dynamic closure;
+static field dynamic int1;
+static field dynamic int2;
+static field dynamic int3;
+static field dynamic int4;
+static field self::Callable* callable;
+static field dynamic string1;
+static field dynamic string2;
+static field dynamic string3;
+static field dynamic string4;
+static field self::CallableGetter* callableGetter;
+static field dynamic string5;
+static field dynamic string6;
+static field dynamic string7;
+static field dynamic string8;
+static field dynamic nothing1;
+static field dynamic nothing2;
+static field dynamic nothing3;
+static field dynamic nothing4;
+static field dynamic nothing5;
+static field dynamic nothing6;
+static field dynamic nothing7;
+static field dynamic nothing8;
+static field dynamic nothing9;
+static field dynamic nothing10;
+static field dynamic nothing11;
+static field dynamic nothing12;
static method main() → dynamic
;
diff --git a/pkg/front_end/testcases/general/call.dart.strong.expect b/pkg/front_end/testcases/general/call.dart.strong.expect
index 9efa544..9bbc04c 100644
--- a/pkg/front_end/testcases/general/call.dart.strong.expect
+++ b/pkg/front_end/testcases/general/call.dart.strong.expect
@@ -46,6 +46,50 @@
// var nothing9 = callableGetter();
// ^
//
+// pkg/front_end/testcases/general/call.dart:63:29: Error: Cannot invoke an instance of 'CallableGetter' because it declares 'call' to be something other than a method.
+// - 'CallableGetter' is from 'pkg/front_end/testcases/general/call.dart'.
+// Try changing 'call' to a method or explicitly invoke 'call'.
+// var string5 = callableGetter(1);
+// ^
+//
+// pkg/front_end/testcases/general/call.dart:68:23: Error: Too few positional arguments: 1 required, 0 given.
+// var nothing1 = closure();
+// ^
+//
+// pkg/front_end/testcases/general/call.dart:69:28: Error: Too few positional arguments: 1 required, 0 given.
+// var nothing2 = closure.call();
+// ^
+//
+// pkg/front_end/testcases/general/call.dart:70:33: Error: Too few positional arguments: 1 required, 0 given.
+// var nothing3 = closure.call.call();
+// ^
+//
+// pkg/front_end/testcases/general/call.dart:71:38: Error: Too few positional arguments: 1 required, 0 given.
+// var nothing4 = closure.call.call.call();
+// ^
+//
+// pkg/front_end/testcases/general/call.dart:73:24: Error: Too few positional arguments: 1 required, 0 given.
+// var nothing5 = callable();
+// ^
+//
+// pkg/front_end/testcases/general/call.dart:74:29: Error: Too few positional arguments: 1 required, 0 given.
+// var nothing6 = callable.call();
+// ^
+//
+// pkg/front_end/testcases/general/call.dart:75:34: Error: Too few positional arguments: 1 required, 0 given.
+// var nothing7 = callable.call.call();
+// ^
+//
+// pkg/front_end/testcases/general/call.dart:76:39: Error: Too few positional arguments: 1 required, 0 given.
+// var nothing8 = callable.call.call.call();
+// ^
+//
+// pkg/front_end/testcases/general/call.dart:78:30: Error: Cannot invoke an instance of 'CallableGetter' because it declares 'call' to be something other than a method.
+// - 'CallableGetter' is from 'pkg/front_end/testcases/general/call.dart'.
+// Try changing 'call' to a method or explicitly invoke 'call'.
+// var nothing9 = callableGetter();
+// ^
+//
import self as self;
import "dart:core" as core;
@@ -64,6 +108,57 @@
get call() → dynamic
return new self::Callable::•();
}
+static field (dynamic) →* dynamic closure = (dynamic x) → dynamic => x;
+static field dynamic int1 = self::closure.call(1);
+static field dynamic int2 = self::closure.call(1);
+static field dynamic int3 = self::closure.call.call(1);
+static field dynamic int4 = self::closure.call.call.call(1);
+static field self::Callable* callable = new self::Callable::•();
+static field dynamic string1 = self::callable.{self::Callable::call}(1);
+static field dynamic string2 = self::callable.{self::Callable::call}(1);
+static field dynamic string3 = self::callable.{self::Callable::call}.call(1);
+static field dynamic string4 = self::callable.{self::Callable::call}.call.call(1);
+static field self::CallableGetter* callableGetter = new self::CallableGetter::•();
+static field dynamic string5 = invalid-expression "pkg/front_end/testcases/general/call.dart:63:29: Error: Cannot invoke an instance of 'CallableGetter' because it declares 'call' to be something other than a method.
+ - 'CallableGetter' is from 'pkg/front_end/testcases/general/call.dart'.
+Try changing 'call' to a method or explicitly invoke 'call'.
+var string5 = callableGetter(1);
+ ^";
+static field dynamic string6 = let final self::CallableGetter* #t1 = self::callableGetter in let final core::int* #t2 = 1 in #t1.{self::CallableGetter::call}.call(#t2);
+static field dynamic string7 = self::callableGetter.{self::CallableGetter::call}.call(1);
+static field dynamic string8 = self::callableGetter.{self::CallableGetter::call}.call.call(1);
+static field dynamic nothing1 = let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/general/call.dart:68:23: Error: Too few positional arguments: 1 required, 0 given.
+var nothing1 = closure();
+ ^" in self::closure.call();
+static field dynamic nothing2 = let final<BottomType> #t4 = invalid-expression "pkg/front_end/testcases/general/call.dart:69:28: Error: Too few positional arguments: 1 required, 0 given.
+var nothing2 = closure.call();
+ ^" in self::closure.call();
+static field dynamic nothing3 = let final<BottomType> #t5 = invalid-expression "pkg/front_end/testcases/general/call.dart:70:33: Error: Too few positional arguments: 1 required, 0 given.
+var nothing3 = closure.call.call();
+ ^" in self::closure.call.call();
+static field dynamic nothing4 = let final<BottomType> #t6 = invalid-expression "pkg/front_end/testcases/general/call.dart:71:38: Error: Too few positional arguments: 1 required, 0 given.
+var nothing4 = closure.call.call.call();
+ ^" in self::closure.call.call.call();
+static field dynamic nothing5 = let final<BottomType> #t7 = invalid-expression "pkg/front_end/testcases/general/call.dart:73:24: Error: Too few positional arguments: 1 required, 0 given.
+var nothing5 = callable();
+ ^" in self::callable.{self::Callable::call}();
+static field dynamic nothing6 = let final<BottomType> #t8 = invalid-expression "pkg/front_end/testcases/general/call.dart:74:29: Error: Too few positional arguments: 1 required, 0 given.
+var nothing6 = callable.call();
+ ^" in self::callable.{self::Callable::call}();
+static field dynamic nothing7 = let final<BottomType> #t9 = invalid-expression "pkg/front_end/testcases/general/call.dart:75:34: Error: Too few positional arguments: 1 required, 0 given.
+var nothing7 = callable.call.call();
+ ^" in self::callable.{self::Callable::call}.call();
+static field dynamic nothing8 = let final<BottomType> #t10 = invalid-expression "pkg/front_end/testcases/general/call.dart:76:39: Error: Too few positional arguments: 1 required, 0 given.
+var nothing8 = callable.call.call.call();
+ ^" in self::callable.{self::Callable::call}.call.call();
+static field dynamic nothing9 = invalid-expression "pkg/front_end/testcases/general/call.dart:78:30: Error: Cannot invoke an instance of 'CallableGetter' because it declares 'call' to be something other than a method.
+ - 'CallableGetter' is from 'pkg/front_end/testcases/general/call.dart'.
+Try changing 'call' to a method or explicitly invoke 'call'.
+var nothing9 = callableGetter();
+ ^";
+static field dynamic nothing10 = self::callableGetter.{self::CallableGetter::call}.call();
+static field dynamic nothing11 = self::callableGetter.{self::CallableGetter::call}.call();
+static field dynamic nothing12 = self::callableGetter.{self::CallableGetter::call}.call.call();
static method main() → dynamic {
(dynamic) →* dynamic closure = (dynamic x) → dynamic => x;
dynamic int1 = closure.call(1);
@@ -81,31 +176,31 @@
Try changing 'call' to a method or explicitly invoke 'call'.
var string5 = callableGetter(1);
^";
- dynamic string6 = let final self::CallableGetter* #t1 = callableGetter in let final core::int* #t2 = 1 in #t1.{self::CallableGetter::call}.call(#t2);
+ dynamic string6 = let final self::CallableGetter* #t11 = callableGetter in let final core::int* #t12 = 1 in #t11.{self::CallableGetter::call}.call(#t12);
dynamic string7 = callableGetter.{self::CallableGetter::call}.call(1);
dynamic string8 = callableGetter.{self::CallableGetter::call}.call.call(1);
- invalid-type nothing1 = let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/general/call.dart:34:25: Error: Too few positional arguments: 1 required, 0 given.
+ invalid-type nothing1 = let final<BottomType> #t13 = invalid-expression "pkg/front_end/testcases/general/call.dart:34:25: Error: Too few positional arguments: 1 required, 0 given.
var nothing1 = closure();
^" in closure.call();
- invalid-type nothing2 = let final<BottomType> #t4 = invalid-expression "pkg/front_end/testcases/general/call.dart:35:30: Error: Too few positional arguments: 1 required, 0 given.
+ invalid-type nothing2 = let final<BottomType> #t14 = invalid-expression "pkg/front_end/testcases/general/call.dart:35:30: Error: Too few positional arguments: 1 required, 0 given.
var nothing2 = closure.call();
^" in closure.call();
- invalid-type nothing3 = let final<BottomType> #t5 = invalid-expression "pkg/front_end/testcases/general/call.dart:36:35: Error: Too few positional arguments: 1 required, 0 given.
+ invalid-type nothing3 = let final<BottomType> #t15 = invalid-expression "pkg/front_end/testcases/general/call.dart:36:35: Error: Too few positional arguments: 1 required, 0 given.
var nothing3 = closure.call.call();
^" in closure.call.call();
- invalid-type nothing4 = let final<BottomType> #t6 = invalid-expression "pkg/front_end/testcases/general/call.dart:37:40: Error: Too few positional arguments: 1 required, 0 given.
+ invalid-type nothing4 = let final<BottomType> #t16 = invalid-expression "pkg/front_end/testcases/general/call.dart:37:40: Error: Too few positional arguments: 1 required, 0 given.
var nothing4 = closure.call.call.call();
^" in closure.call.call.call();
- invalid-type nothing5 = let final<BottomType> #t7 = invalid-expression "pkg/front_end/testcases/general/call.dart:39:26: Error: Too few positional arguments: 1 required, 0 given.
+ invalid-type nothing5 = let final<BottomType> #t17 = invalid-expression "pkg/front_end/testcases/general/call.dart:39:26: Error: Too few positional arguments: 1 required, 0 given.
var nothing5 = callable();
^" in callable.{self::Callable::call}();
- invalid-type nothing6 = let final<BottomType> #t8 = invalid-expression "pkg/front_end/testcases/general/call.dart:40:31: Error: Too few positional arguments: 1 required, 0 given.
+ invalid-type nothing6 = let final<BottomType> #t18 = invalid-expression "pkg/front_end/testcases/general/call.dart:40:31: Error: Too few positional arguments: 1 required, 0 given.
var nothing6 = callable.call();
^" in callable.{self::Callable::call}();
- invalid-type nothing7 = let final<BottomType> #t9 = invalid-expression "pkg/front_end/testcases/general/call.dart:41:36: Error: Too few positional arguments: 1 required, 0 given.
+ invalid-type nothing7 = let final<BottomType> #t19 = invalid-expression "pkg/front_end/testcases/general/call.dart:41:36: Error: Too few positional arguments: 1 required, 0 given.
var nothing7 = callable.call.call();
^" in callable.{self::Callable::call}.call();
- invalid-type nothing8 = let final<BottomType> #t10 = invalid-expression "pkg/front_end/testcases/general/call.dart:42:41: Error: Too few positional arguments: 1 required, 0 given.
+ invalid-type nothing8 = let final<BottomType> #t20 = invalid-expression "pkg/front_end/testcases/general/call.dart:42:41: Error: Too few positional arguments: 1 required, 0 given.
var nothing8 = callable.call.call.call();
^" in callable.{self::Callable::call}.call.call();
dynamic nothing9 = invalid-expression "pkg/front_end/testcases/general/call.dart:44:32: Error: Cannot invoke an instance of 'CallableGetter' because it declares 'call' to be something other than a method.
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/flutter_widget_transform.yaml b/pkg/front_end/testcases/incremental_initialize_from_dill/flutter_widget_transform.yaml
new file mode 100644
index 0000000..3e3b988
--- /dev/null
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/flutter_widget_transform.yaml
@@ -0,0 +1,65 @@
+# Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+# for details. All rights reserved. Use of this source code is governed by a
+# BSD-style license that can be found in the LICENSE.md file.
+
+type: newworld
+target: DDC
+trackWidgetCreation: true
+worlds:
+ - entry: main.dart
+ sources:
+ main.dart: |
+ import 'package:flutter/src/widgets/framework.dart';
+ import 'package:flutter/src/widgets/widget_inspector.dart';
+
+ class Foo extends Widget {}
+ flutter/lib/src/widgets/framework.dart: |
+ abstract class Bar {}
+
+ abstract class Widget extends Bar {}
+ flutter/lib/src/widgets/widget_inspector.dart: |
+ abstract class _HasCreationLocation {
+ _Location get _location;
+ }
+
+ /// A tuple with file, line, and column number, for displaying human-readable
+ /// file locations.
+ class _Location {
+ const _Location({
+ this.file,
+ this.line,
+ this.column,
+ this.name,
+ this.parameterLocations,
+ });
+
+ /// File path of the location.
+ final String file;
+
+ /// 1-based line number.
+ final int line;
+
+ /// 1-based column number.
+ final int column;
+
+ /// Optional name of the parameter or function at this location.
+ final String name;
+
+ /// Optional locations of the parameters of the member at this location.
+ final List<_Location> parameterLocations;
+ }
+ .packages: |
+ flutter:flutter/lib
+ expectedLibraryCount: 3
+ - entry: main.dart
+ worldType: updated
+ invalidate:
+ - main.dart
+ expectInitializeFromDill: false
+ sources:
+ main.dart: |
+ import 'package:flutter/src/widgets/framework.dart';
+ import 'package:flutter/src/widgets/widget_inspector.dart';
+
+ class Foo extends Widget {}
+ expectedLibraryCount: 3
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/flutter_widget_transform.yaml.world.1.expect b/pkg/front_end/testcases/incremental_initialize_from_dill/flutter_widget_transform.yaml.world.1.expect
new file mode 100644
index 0000000..95a88d7
--- /dev/null
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/flutter_widget_transform.yaml.world.1.expect
@@ -0,0 +1,48 @@
+main = <No Member>;
+library from "package:flutter/src/widgets/framework.dart" as fra {
+
+ abstract class Bar extends dart.core::Object {
+ synthetic constructor •() → fra::Bar*
+ : super dart.core::Object::•()
+ ;
+ }
+ abstract class Widget extends fra::Bar implements wid::_HasCreationLocation {
+ final field wid::_Location* _location /* from null */;
+ synthetic constructor •({wid::_Location* $creationLocationd_0dea112b090073317d4}) → fra::Widget*
+ : super fra::Bar::•(), fra::Widget::_location = $creationLocationd_0dea112b090073317d4
+ ;
+ }
+}
+library from "package:flutter/src/widgets/widget_inspector.dart" as wid {
+
+ abstract class _HasCreationLocation extends dart.core::Object {
+ synthetic constructor •() → wid::_HasCreationLocation*
+ : super dart.core::Object::•()
+ ;
+ abstract get _location() → wid::_Location*;
+ }
+ class _Location extends dart.core::Object /*hasConstConstructor*/ {
+ final field dart.core::String* file;
+ final field dart.core::int* line;
+ final field dart.core::int* column;
+ final field dart.core::String* name;
+ final field dart.core::List<wid::_Location*>* parameterLocations;
+ const constructor •({dart.core::String* file = #C1, dart.core::int* line = #C1, dart.core::int* column = #C1, dart.core::String* name = #C1, dart.core::List<wid::_Location*>* parameterLocations = #C1}) → wid::_Location*
+ : wid::_Location::file = file, wid::_Location::line = line, wid::_Location::column = column, wid::_Location::name = name, wid::_Location::parameterLocations = parameterLocations, super dart.core::Object::•()
+ ;
+ }
+}
+library from "org-dartlang-test:///main.dart" as main {
+
+ import "package:flutter/src/widgets/framework.dart";
+ import "package:flutter/src/widgets/widget_inspector.dart";
+
+ class Foo extends fra::Widget {
+ synthetic constructor •({wid::_Location* $creationLocationd_0dea112b090073317d4}) → main::Foo*
+ : super fra::Widget::•($creationLocationd_0dea112b090073317d4: $creationLocationd_0dea112b090073317d4)
+ ;
+ }
+}
+constants {
+ #C1 = null
+}
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/flutter_widget_transform.yaml.world.2.expect b/pkg/front_end/testcases/incremental_initialize_from_dill/flutter_widget_transform.yaml.world.2.expect
new file mode 100644
index 0000000..95a88d7
--- /dev/null
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/flutter_widget_transform.yaml.world.2.expect
@@ -0,0 +1,48 @@
+main = <No Member>;
+library from "package:flutter/src/widgets/framework.dart" as fra {
+
+ abstract class Bar extends dart.core::Object {
+ synthetic constructor •() → fra::Bar*
+ : super dart.core::Object::•()
+ ;
+ }
+ abstract class Widget extends fra::Bar implements wid::_HasCreationLocation {
+ final field wid::_Location* _location /* from null */;
+ synthetic constructor •({wid::_Location* $creationLocationd_0dea112b090073317d4}) → fra::Widget*
+ : super fra::Bar::•(), fra::Widget::_location = $creationLocationd_0dea112b090073317d4
+ ;
+ }
+}
+library from "package:flutter/src/widgets/widget_inspector.dart" as wid {
+
+ abstract class _HasCreationLocation extends dart.core::Object {
+ synthetic constructor •() → wid::_HasCreationLocation*
+ : super dart.core::Object::•()
+ ;
+ abstract get _location() → wid::_Location*;
+ }
+ class _Location extends dart.core::Object /*hasConstConstructor*/ {
+ final field dart.core::String* file;
+ final field dart.core::int* line;
+ final field dart.core::int* column;
+ final field dart.core::String* name;
+ final field dart.core::List<wid::_Location*>* parameterLocations;
+ const constructor •({dart.core::String* file = #C1, dart.core::int* line = #C1, dart.core::int* column = #C1, dart.core::String* name = #C1, dart.core::List<wid::_Location*>* parameterLocations = #C1}) → wid::_Location*
+ : wid::_Location::file = file, wid::_Location::line = line, wid::_Location::column = column, wid::_Location::name = name, wid::_Location::parameterLocations = parameterLocations, super dart.core::Object::•()
+ ;
+ }
+}
+library from "org-dartlang-test:///main.dart" as main {
+
+ import "package:flutter/src/widgets/framework.dart";
+ import "package:flutter/src/widgets/widget_inspector.dart";
+
+ class Foo extends fra::Widget {
+ synthetic constructor •({wid::_Location* $creationLocationd_0dea112b090073317d4}) → main::Foo*
+ : super fra::Widget::•($creationLocationd_0dea112b090073317d4: $creationLocationd_0dea112b090073317d4)
+ ;
+ }
+}
+constants {
+ #C1 = null
+}
diff --git a/pkg/front_end/testcases/inference/issue41199.dart b/pkg/front_end/testcases/inference/issue41199.dart
new file mode 100644
index 0000000..778bf42
--- /dev/null
+++ b/pkg/front_end/testcases/inference/issue41199.dart
@@ -0,0 +1,8 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+foo<X>(Map<X, Y> Function<Y>() f) => null;
+baz() => foo(<Z>() => <dynamic, Z>{});
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/issue41199.dart.outline.expect b/pkg/front_end/testcases/inference/issue41199.dart.outline.expect
new file mode 100644
index 0000000..69b0cc3
--- /dev/null
+++ b/pkg/front_end/testcases/inference/issue41199.dart.outline.expect
@@ -0,0 +1,10 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+static method foo<X extends core::Object* = dynamic>(<Y extends core::Object* = dynamic>() →* core::Map<self::foo::X*, Y*>* f) → dynamic
+ ;
+static method baz() → dynamic
+ ;
+static method main() → dynamic
+ ;
diff --git a/pkg/front_end/testcases/inference/issue41199.dart.strong.expect b/pkg/front_end/testcases/inference/issue41199.dart.strong.expect
new file mode 100644
index 0000000..6d7392d
--- /dev/null
+++ b/pkg/front_end/testcases/inference/issue41199.dart.strong.expect
@@ -0,0 +1,9 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+static method foo<X extends core::Object* = dynamic>(<Y extends core::Object* = dynamic>() →* core::Map<self::foo::X*, Y*>* f) → dynamic
+ return null;
+static method baz() → dynamic
+ return self::foo<dynamic>(<Z extends core::Object* = dynamic>() → core::Map<dynamic, Z*>* => <dynamic, Z*>{});
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/issue41199.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/issue41199.dart.strong.transformed.expect
new file mode 100644
index 0000000..6d7392d
--- /dev/null
+++ b/pkg/front_end/testcases/inference/issue41199.dart.strong.transformed.expect
@@ -0,0 +1,9 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+static method foo<X extends core::Object* = dynamic>(<Y extends core::Object* = dynamic>() →* core::Map<self::foo::X*, Y*>* f) → dynamic
+ return null;
+static method baz() → dynamic
+ return self::foo<dynamic>(<Z extends core::Object* = dynamic>() → core::Map<dynamic, Z*>* => <dynamic, Z*>{});
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/issue41102.dart b/pkg/front_end/testcases/nnbd/issue41102.dart
index f10ab27..a237a56 100644
--- a/pkg/front_end/testcases/nnbd/issue41102.dart
+++ b/pkg/front_end/testcases/nnbd/issue41102.dart
@@ -38,7 +38,7 @@
final s10 = s7.length;
-final s11 = s5.length = 0;
+final s11 = s7.length = 0;
final s12 = -s5;
diff --git a/pkg/front_end/testcases/nnbd/issue41102.dart.strong.expect b/pkg/front_end/testcases/nnbd/issue41102.dart.strong.expect
index 7157bfd..6c39527 100644
--- a/pkg/front_end/testcases/nnbd/issue41102.dart.strong.expect
+++ b/pkg/front_end/testcases/nnbd/issue41102.dart.strong.expect
@@ -43,14 +43,10 @@
// final s10 = s7.length;
// ^^^^^^
//
-// pkg/front_end/testcases/nnbd/issue41102.dart:41:16: Error: The setter 'length' isn't defined for the class 'int?'.
-// Try correcting the name to the name of an existing setter, or defining a setter or field named 'length'.
-// final s11 = s5.length = 0;
-// ^^^^^^
-//
-// pkg/front_end/testcases/nnbd/issue41102.dart:41:16: Error: Property 'length' cannot be accessed on 'int?' because it is potentially null.
+// pkg/front_end/testcases/nnbd/issue41102.dart:41:16: Error: Property 'length' cannot be accessed on 'List<dynamic>?' because it is potentially null.
+// - 'List' is from 'dart:core'.
// Try accessing using ?. instead.
-// final s11 = s5.length = 0;
+// final s11 = s7.length = 0;
// ^^^^^^
//
// pkg/front_end/testcases/nnbd/issue41102.dart:43:13: Error: Operator 'unary-' cannot be called on 'int?' because it is potentially null.
@@ -111,13 +107,11 @@
Try accessing using ?. instead.
final s10 = s7.length;
^^^^^^" in self::s7.{core::List::length};
-static final field core::int s11 = let final<BottomType> #t11 = invalid-expression "pkg/front_end/testcases/nnbd/issue41102.dart:41:16: Error: Property 'length' cannot be accessed on 'int?' because it is potentially null.
+static final field core::int s11 = let final<BottomType> #t11 = invalid-expression "pkg/front_end/testcases/nnbd/issue41102.dart:41:16: Error: Property 'length' cannot be accessed on 'List<dynamic>?' because it is potentially null.
+ - 'List' is from 'dart:core'.
Try accessing using ?. instead.
-final s11 = s5.length = 0;
- ^^^^^^" in invalid-expression "pkg/front_end/testcases/nnbd/issue41102.dart:41:16: Error: The setter 'length' isn't defined for the class 'int?'.
-Try correcting the name to the name of an existing setter, or defining a setter or field named 'length'.
-final s11 = s5.length = 0;
- ^^^^^^";
+final s11 = s7.length = 0;
+ ^^^^^^" in self::s7.{core::List::length} = 0;
static final field core::int s12 = let final<BottomType> #t12 = invalid-expression "pkg/front_end/testcases/nnbd/issue41102.dart:43:13: Error: Operator 'unary-' cannot be called on 'int?' because it is potentially null.
final s12 = -s5;
^" in self::s5.{core::int::unary-}();
diff --git a/pkg/front_end/testcases/nnbd/issue41102.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/issue41102.dart.strong.transformed.expect
index d888b44..ae59b84 100644
--- a/pkg/front_end/testcases/nnbd/issue41102.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/issue41102.dart.strong.transformed.expect
@@ -43,14 +43,10 @@
// final s10 = s7.length;
// ^^^^^^
//
-// pkg/front_end/testcases/nnbd/issue41102.dart:41:16: Error: The setter 'length' isn't defined for the class 'int?'.
-// Try correcting the name to the name of an existing setter, or defining a setter or field named 'length'.
-// final s11 = s5.length = 0;
-// ^^^^^^
-//
-// pkg/front_end/testcases/nnbd/issue41102.dart:41:16: Error: Property 'length' cannot be accessed on 'int?' because it is potentially null.
+// pkg/front_end/testcases/nnbd/issue41102.dart:41:16: Error: Property 'length' cannot be accessed on 'List<dynamic>?' because it is potentially null.
+// - 'List' is from 'dart:core'.
// Try accessing using ?. instead.
-// final s11 = s5.length = 0;
+// final s11 = s7.length = 0;
// ^^^^^^
//
// pkg/front_end/testcases/nnbd/issue41102.dart:43:13: Error: Operator 'unary-' cannot be called on 'int?' because it is potentially null.
@@ -111,13 +107,11 @@
Try accessing using ?. instead.
final s10 = s7.length;
^^^^^^" in self::s7.{core::List::length};
-static final field core::int s11 = let final<BottomType> #t11 = invalid-expression "pkg/front_end/testcases/nnbd/issue41102.dart:41:16: Error: Property 'length' cannot be accessed on 'int?' because it is potentially null.
+static final field core::int s11 = let final<BottomType> #t11 = invalid-expression "pkg/front_end/testcases/nnbd/issue41102.dart:41:16: Error: Property 'length' cannot be accessed on 'List<dynamic>?' because it is potentially null.
+ - 'List' is from 'dart:core'.
Try accessing using ?. instead.
-final s11 = s5.length = 0;
- ^^^^^^" in invalid-expression "pkg/front_end/testcases/nnbd/issue41102.dart:41:16: Error: The setter 'length' isn't defined for the class 'int?'.
-Try correcting the name to the name of an existing setter, or defining a setter or field named 'length'.
-final s11 = s5.length = 0;
- ^^^^^^";
+final s11 = s7.length = 0;
+ ^^^^^^" in self::s7.{core::List::length} = 0;
static final field core::int s12 = let final<BottomType> #t12 = invalid-expression "pkg/front_end/testcases/nnbd/issue41102.dart:43:13: Error: Operator 'unary-' cannot be called on 'int?' because it is potentially null.
final s12 = -s5;
^" in self::s5.{core::int::unary-}();
diff --git a/pkg/front_end/testcases/nnbd/issue41102.dart.weak.expect b/pkg/front_end/testcases/nnbd/issue41102.dart.weak.expect
index 7157bfd..6c39527 100644
--- a/pkg/front_end/testcases/nnbd/issue41102.dart.weak.expect
+++ b/pkg/front_end/testcases/nnbd/issue41102.dart.weak.expect
@@ -43,14 +43,10 @@
// final s10 = s7.length;
// ^^^^^^
//
-// pkg/front_end/testcases/nnbd/issue41102.dart:41:16: Error: The setter 'length' isn't defined for the class 'int?'.
-// Try correcting the name to the name of an existing setter, or defining a setter or field named 'length'.
-// final s11 = s5.length = 0;
-// ^^^^^^
-//
-// pkg/front_end/testcases/nnbd/issue41102.dart:41:16: Error: Property 'length' cannot be accessed on 'int?' because it is potentially null.
+// pkg/front_end/testcases/nnbd/issue41102.dart:41:16: Error: Property 'length' cannot be accessed on 'List<dynamic>?' because it is potentially null.
+// - 'List' is from 'dart:core'.
// Try accessing using ?. instead.
-// final s11 = s5.length = 0;
+// final s11 = s7.length = 0;
// ^^^^^^
//
// pkg/front_end/testcases/nnbd/issue41102.dart:43:13: Error: Operator 'unary-' cannot be called on 'int?' because it is potentially null.
@@ -111,13 +107,11 @@
Try accessing using ?. instead.
final s10 = s7.length;
^^^^^^" in self::s7.{core::List::length};
-static final field core::int s11 = let final<BottomType> #t11 = invalid-expression "pkg/front_end/testcases/nnbd/issue41102.dart:41:16: Error: Property 'length' cannot be accessed on 'int?' because it is potentially null.
+static final field core::int s11 = let final<BottomType> #t11 = invalid-expression "pkg/front_end/testcases/nnbd/issue41102.dart:41:16: Error: Property 'length' cannot be accessed on 'List<dynamic>?' because it is potentially null.
+ - 'List' is from 'dart:core'.
Try accessing using ?. instead.
-final s11 = s5.length = 0;
- ^^^^^^" in invalid-expression "pkg/front_end/testcases/nnbd/issue41102.dart:41:16: Error: The setter 'length' isn't defined for the class 'int?'.
-Try correcting the name to the name of an existing setter, or defining a setter or field named 'length'.
-final s11 = s5.length = 0;
- ^^^^^^";
+final s11 = s7.length = 0;
+ ^^^^^^" in self::s7.{core::List::length} = 0;
static final field core::int s12 = let final<BottomType> #t12 = invalid-expression "pkg/front_end/testcases/nnbd/issue41102.dart:43:13: Error: Operator 'unary-' cannot be called on 'int?' because it is potentially null.
final s12 = -s5;
^" in self::s5.{core::int::unary-}();
diff --git a/pkg/front_end/testcases/nnbd/issue41102.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/issue41102.dart.weak.transformed.expect
index d888b44..ae59b84 100644
--- a/pkg/front_end/testcases/nnbd/issue41102.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/issue41102.dart.weak.transformed.expect
@@ -43,14 +43,10 @@
// final s10 = s7.length;
// ^^^^^^
//
-// pkg/front_end/testcases/nnbd/issue41102.dart:41:16: Error: The setter 'length' isn't defined for the class 'int?'.
-// Try correcting the name to the name of an existing setter, or defining a setter or field named 'length'.
-// final s11 = s5.length = 0;
-// ^^^^^^
-//
-// pkg/front_end/testcases/nnbd/issue41102.dart:41:16: Error: Property 'length' cannot be accessed on 'int?' because it is potentially null.
+// pkg/front_end/testcases/nnbd/issue41102.dart:41:16: Error: Property 'length' cannot be accessed on 'List<dynamic>?' because it is potentially null.
+// - 'List' is from 'dart:core'.
// Try accessing using ?. instead.
-// final s11 = s5.length = 0;
+// final s11 = s7.length = 0;
// ^^^^^^
//
// pkg/front_end/testcases/nnbd/issue41102.dart:43:13: Error: Operator 'unary-' cannot be called on 'int?' because it is potentially null.
@@ -111,13 +107,11 @@
Try accessing using ?. instead.
final s10 = s7.length;
^^^^^^" in self::s7.{core::List::length};
-static final field core::int s11 = let final<BottomType> #t11 = invalid-expression "pkg/front_end/testcases/nnbd/issue41102.dart:41:16: Error: Property 'length' cannot be accessed on 'int?' because it is potentially null.
+static final field core::int s11 = let final<BottomType> #t11 = invalid-expression "pkg/front_end/testcases/nnbd/issue41102.dart:41:16: Error: Property 'length' cannot be accessed on 'List<dynamic>?' because it is potentially null.
+ - 'List' is from 'dart:core'.
Try accessing using ?. instead.
-final s11 = s5.length = 0;
- ^^^^^^" in invalid-expression "pkg/front_end/testcases/nnbd/issue41102.dart:41:16: Error: The setter 'length' isn't defined for the class 'int?'.
-Try correcting the name to the name of an existing setter, or defining a setter or field named 'length'.
-final s11 = s5.length = 0;
- ^^^^^^";
+final s11 = s7.length = 0;
+ ^^^^^^" in self::s7.{core::List::length} = 0;
static final field core::int s12 = let final<BottomType> #t12 = invalid-expression "pkg/front_end/testcases/nnbd/issue41102.dart:43:13: Error: Operator 'unary-' cannot be called on 'int?' because it is potentially null.
final s12 = -s5;
^" in self::s5.{core::int::unary-}();
diff --git a/pkg/front_end/testcases/nnbd/potentially_nullable_access.dart b/pkg/front_end/testcases/nnbd/potentially_nullable_access.dart
new file mode 100644
index 0000000..a000d92
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/potentially_nullable_access.dart
@@ -0,0 +1,68 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE.md file.
+
+class Class {
+ int property = 0;
+ int method() => 0;
+ Function functionField = () {};
+ void Function() functionTypeField = () {};
+ Function get functionGetter => () {};
+ void Function() get functionTypeGetter => () {};
+}
+
+Function? get nullableFunction => () {};
+
+void Function()? get nullableFunctionType => () {};
+
+int? get nullableInt => 0;
+
+Map<dynamic, dynamic>? get nullableMap => {};
+
+Class? get nullableClass => new Class();
+
+var topLevelBinary = nullableInt + 0;
+var topLevelUnary = -nullableInt;
+var topLevelIndexGet = nullableMap[0];
+var topLevelIndexSet = nullableMap[0] = 1;
+var topLevelIndexGetSet = nullableMap[0] += 1;
+var topLevelPropertyGet = nullableClass.property;
+var topLevelPropertySet = nullableClass.property = 1;
+var topLevelPropertyGetSet = nullableClass.property += 1;
+var topLevelMethodInvocation = nullableClass.method();
+var topLevelMethodTearOff = nullableClass.method;
+var topLevelFunctionImplicitCall = nullableFunction();
+var topLevelFunctionExplicitCall = nullableFunction.call();
+var topLevelFunctionTearOff = nullableFunction.call;
+var topLevelFunctionTypeImplicitCall = nullableFunctionType();
+var topLevelFunctionTypeExplicitCall = nullableFunctionType.call();
+var topLevelFunctionTypeTearOff = nullableFunctionType.call;
+var topLevelFunctionField = nullableClass.functionField();
+var topLevelFunctionTypeField = nullableClass.functionTypeField();
+var topLevelFunctionGetter = nullableClass.functionGetter();
+var topLevelFunctionTypeGetter = nullableClass.functionTypeGetter();
+
+test() {
+ var localBinary = nullableInt + 0;
+ var localUnary = -nullableInt;
+ var localIndexGet = nullableMap[0];
+ var localIndexSet = nullableMap[0] = 1;
+ var localIndexGetSet = nullableMap[0] += 1;
+ var localPropertyGet = nullableClass.property;
+ var localPropertySet = nullableClass.property = 1;
+ var localPropertyGetSet = nullableClass.property += 1;
+ var localMethodInvocation = nullableClass.method();
+ var localMethodTearOff = nullableClass.method;
+ var localFunctionImplicitCall = nullableFunction();
+ var localFunctionExplicitCall = nullableFunction.call();
+ var localFunctionTearOff = nullableFunction.call;
+ var localFunctionTypeImplicitCall = nullableFunctionType();
+ var localFunctionTypeExplicitCall = nullableFunctionType.call();
+ var localFunctionTypeTearOff = nullableFunctionType.call;
+ var localFunctionField = nullableClass.functionField();
+ var localFunctionTypeField = nullableClass.functionTypeField();
+ var localFunctionGetter = nullableClass.functionGetter();
+ var localFunctionTypeGetter = nullableClass.functionTypeGetter();
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/potentially_nullable_access.dart.outline.expect b/pkg/front_end/testcases/nnbd/potentially_nullable_access.dart.outline.expect
new file mode 100644
index 0000000..e9455e1
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/potentially_nullable_access.dart.outline.expect
@@ -0,0 +1,51 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class Class extends core::Object {
+ field core::int property;
+ field core::Function functionField;
+ field () → void functionTypeField;
+ synthetic constructor •() → self::Class
+ ;
+ method method() → core::int
+ ;
+ get functionGetter() → core::Function
+ ;
+ get functionTypeGetter() → () → void
+ ;
+}
+static field core::int? topLevelBinary;
+static field core::int topLevelUnary;
+static field dynamic topLevelIndexGet;
+static field core::int topLevelIndexSet;
+static field dynamic topLevelIndexGetSet;
+static field core::int topLevelPropertyGet;
+static field core::int topLevelPropertySet;
+static field core::int topLevelPropertyGetSet;
+static field core::int topLevelMethodInvocation;
+static field () → core::int topLevelMethodTearOff;
+static field dynamic topLevelFunctionImplicitCall;
+static field dynamic topLevelFunctionExplicitCall;
+static field core::Function? topLevelFunctionTearOff;
+static field void topLevelFunctionTypeImplicitCall;
+static field void topLevelFunctionTypeExplicitCall;
+static field () →? void topLevelFunctionTypeTearOff;
+static field dynamic topLevelFunctionField;
+static field void topLevelFunctionTypeField;
+static field dynamic topLevelFunctionGetter;
+static field void topLevelFunctionTypeGetter;
+static get nullableFunction() → core::Function?
+ ;
+static get nullableFunctionType() → () →? void
+ ;
+static get nullableInt() → core::int?
+ ;
+static get nullableMap() → core::Map<dynamic, dynamic>?
+ ;
+static get nullableClass() → self::Class?
+ ;
+static method test() → dynamic
+ ;
+static method main() → dynamic
+ ;
diff --git a/pkg/front_end/testcases/nnbd/potentially_nullable_access.dart.strong.expect b/pkg/front_end/testcases/nnbd/potentially_nullable_access.dart.strong.expect
new file mode 100644
index 0000000..eeb102b
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/potentially_nullable_access.dart.strong.expect
@@ -0,0 +1,358 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:24:34: Error: Operator '+' cannot be called on 'int?' because it is potentially null.
+// var topLevelBinary = nullableInt + 0;
+// ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:25:21: Error: Operator 'unary-' cannot be called on 'int?' because it is potentially null.
+// var topLevelUnary = -nullableInt;
+// ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:26:35: Error: Operator '[]' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
+// - 'Map' is from 'dart:core'.
+// var topLevelIndexGet = nullableMap[0];
+// ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:27:35: Error: Operator '[]=' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
+// - 'Map' is from 'dart:core'.
+// var topLevelIndexSet = nullableMap[0] = 1;
+// ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:28:38: Error: Operator '[]' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
+// - 'Map' is from 'dart:core'.
+// var topLevelIndexGetSet = nullableMap[0] += 1;
+// ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:28:38: Error: Operator '[]=' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
+// - 'Map' is from 'dart:core'.
+// var topLevelIndexGetSet = nullableMap[0] += 1;
+// ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:29:41: Error: Property 'property' cannot be accessed on 'Class?' because it is potentially null.
+// - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try accessing using ?. instead.
+// var topLevelPropertyGet = nullableClass.property;
+// ^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:30:41: Error: Property 'property' cannot be accessed on 'Class?' because it is potentially null.
+// - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try accessing using ?. instead.
+// var topLevelPropertySet = nullableClass.property = 1;
+// ^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:31:44: Error: Property 'property' cannot be accessed on 'Class?' because it is potentially null.
+// - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try accessing using ?. instead.
+// var topLevelPropertyGetSet = nullableClass.property += 1;
+// ^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:32:46: Error: Method 'method' cannot be called on 'Class?' because it is potentially null.
+// - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try calling using ?. instead.
+// var topLevelMethodInvocation = nullableClass.method();
+// ^^^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:34:52: Error: Can't use an expression of type 'Function?' as a function because it's potentially null.
+// - 'Function' is from 'dart:core'.
+// Try calling using ?.call instead.
+// var topLevelFunctionImplicitCall = nullableFunction();
+// ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:35:53: Error: Method 'call' cannot be called on 'Function?' because it is potentially null.
+// - 'Function' is from 'dart:core'.
+// Try calling using ?. instead.
+// var topLevelFunctionExplicitCall = nullableFunction.call();
+// ^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:36:48: Error: Property 'call' cannot be accessed on 'Function?' because it is potentially null.
+// - 'Function' is from 'dart:core'.
+// Try accessing using ?. instead.
+// var topLevelFunctionTearOff = nullableFunction.call;
+// ^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:37:60: Error: Can't use an expression of type 'void Function()?' as a function because it's potentially null.
+// Try calling using ?.call instead.
+// var topLevelFunctionTypeImplicitCall = nullableFunctionType();
+// ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:38:61: Error: Method 'call' cannot be called on 'void Function()?' because it is potentially null.
+// Try calling using ?. instead.
+// var topLevelFunctionTypeExplicitCall = nullableFunctionType.call();
+// ^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:39:56: Error: Property 'call' cannot be accessed on 'void Function()?' because it is potentially null.
+// Try accessing using ?. instead.
+// var topLevelFunctionTypeTearOff = nullableFunctionType.call;
+// ^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:46:33: Error: Operator '+' cannot be called on 'int?' because it is potentially null.
+// var localBinary = nullableInt + 0;
+// ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:47:20: Error: Operator 'unary-' cannot be called on 'int?' because it is potentially null.
+// var localUnary = -nullableInt;
+// ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:48:34: Error: Operator '[]' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
+// - 'Map' is from 'dart:core'.
+// var localIndexGet = nullableMap[0];
+// ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:49:34: Error: Operator '[]=' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
+// - 'Map' is from 'dart:core'.
+// var localIndexSet = nullableMap[0] = 1;
+// ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:50:37: Error: Operator '[]' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
+// - 'Map' is from 'dart:core'.
+// var localIndexGetSet = nullableMap[0] += 1;
+// ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:50:37: Error: Operator '[]=' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
+// - 'Map' is from 'dart:core'.
+// var localIndexGetSet = nullableMap[0] += 1;
+// ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:51:40: Error: Property 'property' cannot be accessed on 'Class?' because it is potentially null.
+// - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try accessing using ?. instead.
+// var localPropertyGet = nullableClass.property;
+// ^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:52:40: Error: Property 'property' cannot be accessed on 'Class?' because it is potentially null.
+// - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try accessing using ?. instead.
+// var localPropertySet = nullableClass.property = 1;
+// ^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:53:43: Error: Property 'property' cannot be accessed on 'Class?' because it is potentially null.
+// - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try accessing using ?. instead.
+// var localPropertyGetSet = nullableClass.property += 1;
+// ^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:54:45: Error: Method 'method' cannot be called on 'Class?' because it is potentially null.
+// - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try calling using ?. instead.
+// var localMethodInvocation = nullableClass.method();
+// ^^^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:56:51: Error: Can't use an expression of type 'Function?' as a function because it's potentially null.
+// - 'Function' is from 'dart:core'.
+// Try calling using ?.call instead.
+// var localFunctionImplicitCall = nullableFunction();
+// ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:57:52: Error: Method 'call' cannot be called on 'Function?' because it is potentially null.
+// - 'Function' is from 'dart:core'.
+// Try calling using ?. instead.
+// var localFunctionExplicitCall = nullableFunction.call();
+// ^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:58:47: Error: Property 'call' cannot be accessed on 'Function?' because it is potentially null.
+// - 'Function' is from 'dart:core'.
+// Try accessing using ?. instead.
+// var localFunctionTearOff = nullableFunction.call;
+// ^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:59:59: Error: Can't use an expression of type 'void Function()?' as a function because it's potentially null.
+// Try calling using ?.call instead.
+// var localFunctionTypeImplicitCall = nullableFunctionType();
+// ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:60:60: Error: Method 'call' cannot be called on 'void Function()?' because it is potentially null.
+// Try calling using ?. instead.
+// var localFunctionTypeExplicitCall = nullableFunctionType.call();
+// ^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:61:55: Error: Property 'call' cannot be accessed on 'void Function()?' because it is potentially null.
+// Try accessing using ?. instead.
+// var localFunctionTypeTearOff = nullableFunctionType.call;
+// ^^^^
+//
+import self as self;
+import "dart:core" as core;
+
+class Class extends core::Object {
+ field core::int property = 0;
+ field core::Function functionField = () → core::Null? {};
+ field () → void functionTypeField = () → core::Null? {};
+ synthetic constructor •() → self::Class
+ : super core::Object::•()
+ ;
+ method method() → core::int
+ return 0;
+ get functionGetter() → core::Function
+ return () → core::Null? {};
+ get functionTypeGetter() → () → void
+ return () → core::Null? {};
+}
+static field core::int? topLevelBinary = let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:24:34: Error: Operator '+' cannot be called on 'int?' because it is potentially null.
+var topLevelBinary = nullableInt + 0;
+ ^" in self::nullableInt.{core::num::+}(0);
+static field core::int topLevelUnary = let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:25:21: Error: Operator 'unary-' cannot be called on 'int?' because it is potentially null.
+var topLevelUnary = -nullableInt;
+ ^" in self::nullableInt.{core::int::unary-}();
+static field dynamic topLevelIndexGet = let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:26:35: Error: Operator '[]' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
+ - 'Map' is from 'dart:core'.
+var topLevelIndexGet = nullableMap[0];
+ ^" in self::nullableMap.{core::Map::[]}(0);
+static field core::int topLevelIndexSet = let final core::Map<dynamic, dynamic>? #t4 = self::nullableMap in let final core::int #t5 = 0 in let final core::int #t6 = 1 in let final void #t7 = let final<BottomType> #t8 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:27:35: Error: Operator '[]=' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
+ - 'Map' is from 'dart:core'.
+var topLevelIndexSet = nullableMap[0] = 1;
+ ^" in #t4.{core::Map::[]=}(#t5, #t6) in #t6;
+static field dynamic topLevelIndexGetSet = let final core::Map<dynamic, dynamic>? #t9 = self::nullableMap in let final core::int #t10 = 0 in let final dynamic #t11 = (let final<BottomType> #t12 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:28:38: Error: Operator '[]' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
+ - 'Map' is from 'dart:core'.
+var topLevelIndexGetSet = nullableMap[0] += 1;
+ ^" in #t9.{core::Map::[]}(#t10)).+(1) in let final void #t13 = let final<BottomType> #t14 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:28:38: Error: Operator '[]=' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
+ - 'Map' is from 'dart:core'.
+var topLevelIndexGetSet = nullableMap[0] += 1;
+ ^" in #t9.{core::Map::[]=}(#t10, #t11) in #t11;
+static field core::int topLevelPropertyGet = let final<BottomType> #t15 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:29:41: Error: Property 'property' cannot be accessed on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try accessing using ?. instead.
+var topLevelPropertyGet = nullableClass.property;
+ ^^^^^^^^" in self::nullableClass.{self::Class::property};
+static field core::int topLevelPropertySet = let final<BottomType> #t16 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:30:41: Error: Property 'property' cannot be accessed on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try accessing using ?. instead.
+var topLevelPropertySet = nullableClass.property = 1;
+ ^^^^^^^^" in self::nullableClass.{self::Class::property} = 1;
+static field core::int topLevelPropertyGetSet = let final self::Class? #t17 = self::nullableClass in let final<BottomType> #t18 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:31:44: Error: Property 'property' cannot be accessed on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try accessing using ?. instead.
+var topLevelPropertyGetSet = nullableClass.property += 1;
+ ^^^^^^^^" in #t17.{self::Class::property} = (let final<BottomType> #t19 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:31:44: Error: Property 'property' cannot be accessed on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try accessing using ?. instead.
+var topLevelPropertyGetSet = nullableClass.property += 1;
+ ^^^^^^^^" in #t17.{self::Class::property}).{core::num::+}(1);
+static field core::int topLevelMethodInvocation = let final<BottomType> #t20 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:32:46: Error: Method 'method' cannot be called on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try calling using ?. instead.
+var topLevelMethodInvocation = nullableClass.method();
+ ^^^^^^" in self::nullableClass.{self::Class::method}();
+static field () → core::int topLevelMethodTearOff = self::nullableClass.{self::Class::method};
+static field dynamic topLevelFunctionImplicitCall = let final<BottomType> #t21 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:34:52: Error: Can't use an expression of type 'Function?' as a function because it's potentially null.
+ - 'Function' is from 'dart:core'.
+Try calling using ?.call instead.
+var topLevelFunctionImplicitCall = nullableFunction();
+ ^" in self::nullableFunction.call();
+static field dynamic topLevelFunctionExplicitCall = let final<BottomType> #t22 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:35:53: Error: Method 'call' cannot be called on 'Function?' because it is potentially null.
+ - 'Function' is from 'dart:core'.
+Try calling using ?. instead.
+var topLevelFunctionExplicitCall = nullableFunction.call();
+ ^^^^" in self::nullableFunction.call();
+static field core::Function? topLevelFunctionTearOff = let final<BottomType> #t23 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:36:48: Error: Property 'call' cannot be accessed on 'Function?' because it is potentially null.
+ - 'Function' is from 'dart:core'.
+Try accessing using ?. instead.
+var topLevelFunctionTearOff = nullableFunction.call;
+ ^^^^" in self::nullableFunction.call;
+static field void topLevelFunctionTypeImplicitCall = let final<BottomType> #t24 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:37:60: Error: Can't use an expression of type 'void Function()?' as a function because it's potentially null.
+Try calling using ?.call instead.
+var topLevelFunctionTypeImplicitCall = nullableFunctionType();
+ ^" in self::nullableFunctionType.call();
+static field void topLevelFunctionTypeExplicitCall = let final<BottomType> #t25 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:38:61: Error: Method 'call' cannot be called on 'void Function()?' because it is potentially null.
+Try calling using ?. instead.
+var topLevelFunctionTypeExplicitCall = nullableFunctionType.call();
+ ^^^^" in self::nullableFunctionType.call();
+static field () →? void topLevelFunctionTypeTearOff = let final<BottomType> #t26 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:39:56: Error: Property 'call' cannot be accessed on 'void Function()?' because it is potentially null.
+Try accessing using ?. instead.
+var topLevelFunctionTypeTearOff = nullableFunctionType.call;
+ ^^^^" in self::nullableFunctionType.call;
+static field dynamic topLevelFunctionField = self::nullableClass.{self::Class::functionField}.call();
+static field void topLevelFunctionTypeField = self::nullableClass.{self::Class::functionTypeField}.call();
+static field dynamic topLevelFunctionGetter = self::nullableClass.{self::Class::functionGetter}.call();
+static field void topLevelFunctionTypeGetter = self::nullableClass.{self::Class::functionTypeGetter}.call();
+static get nullableFunction() → core::Function?
+ return () → core::Null? {};
+static get nullableFunctionType() → () →? void
+ return () → core::Null? {};
+static get nullableInt() → core::int?
+ return 0;
+static get nullableMap() → core::Map<dynamic, dynamic>?
+ return <dynamic, dynamic>{};
+static get nullableClass() → self::Class?
+ return new self::Class::•();
+static method test() → dynamic {
+ core::int? localBinary = let final<BottomType> #t27 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:46:33: Error: Operator '+' cannot be called on 'int?' because it is potentially null.
+ var localBinary = nullableInt + 0;
+ ^" in self::nullableInt.{core::num::+}(0);
+ core::int localUnary = let final<BottomType> #t28 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:47:20: Error: Operator 'unary-' cannot be called on 'int?' because it is potentially null.
+ var localUnary = -nullableInt;
+ ^" in self::nullableInt.{core::int::unary-}();
+ dynamic localIndexGet = let final<BottomType> #t29 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:48:34: Error: Operator '[]' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
+ - 'Map' is from 'dart:core'.
+ var localIndexGet = nullableMap[0];
+ ^" in self::nullableMap.{core::Map::[]}(0);
+ core::int localIndexSet = let final core::Map<dynamic, dynamic>? #t30 = self::nullableMap in let final core::int #t31 = 0 in let final core::int #t32 = 1 in let final void #t33 = let final<BottomType> #t34 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:49:34: Error: Operator '[]=' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
+ - 'Map' is from 'dart:core'.
+ var localIndexSet = nullableMap[0] = 1;
+ ^" in #t30.{core::Map::[]=}(#t31, #t32) in #t32;
+ dynamic localIndexGetSet = let final core::Map<dynamic, dynamic>? #t35 = self::nullableMap in let final core::int #t36 = 0 in let final dynamic #t37 = (let final<BottomType> #t38 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:50:37: Error: Operator '[]' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
+ - 'Map' is from 'dart:core'.
+ var localIndexGetSet = nullableMap[0] += 1;
+ ^" in #t35.{core::Map::[]}(#t36)).+(1) in let final void #t39 = let final<BottomType> #t40 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:50:37: Error: Operator '[]=' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
+ - 'Map' is from 'dart:core'.
+ var localIndexGetSet = nullableMap[0] += 1;
+ ^" in #t35.{core::Map::[]=}(#t36, #t37) in #t37;
+ core::int localPropertyGet = let final<BottomType> #t41 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:51:40: Error: Property 'property' cannot be accessed on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try accessing using ?. instead.
+ var localPropertyGet = nullableClass.property;
+ ^^^^^^^^" in self::nullableClass.{self::Class::property};
+ core::int localPropertySet = let final<BottomType> #t42 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:52:40: Error: Property 'property' cannot be accessed on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try accessing using ?. instead.
+ var localPropertySet = nullableClass.property = 1;
+ ^^^^^^^^" in self::nullableClass.{self::Class::property} = 1;
+ core::int localPropertyGetSet = let final self::Class? #t43 = self::nullableClass in let final<BottomType> #t44 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:53:43: Error: Property 'property' cannot be accessed on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try accessing using ?. instead.
+ var localPropertyGetSet = nullableClass.property += 1;
+ ^^^^^^^^" in #t43.{self::Class::property} = (let final<BottomType> #t45 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:53:43: Error: Property 'property' cannot be accessed on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try accessing using ?. instead.
+ var localPropertyGetSet = nullableClass.property += 1;
+ ^^^^^^^^" in #t43.{self::Class::property}).{core::num::+}(1);
+ core::int localMethodInvocation = let final<BottomType> #t46 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:54:45: Error: Method 'method' cannot be called on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try calling using ?. instead.
+ var localMethodInvocation = nullableClass.method();
+ ^^^^^^" in self::nullableClass.{self::Class::method}();
+ () → core::int localMethodTearOff = self::nullableClass.{self::Class::method};
+ dynamic localFunctionImplicitCall = let final<BottomType> #t47 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:56:51: Error: Can't use an expression of type 'Function?' as a function because it's potentially null.
+ - 'Function' is from 'dart:core'.
+Try calling using ?.call instead.
+ var localFunctionImplicitCall = nullableFunction();
+ ^" in self::nullableFunction.call();
+ dynamic localFunctionExplicitCall = let final<BottomType> #t48 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:57:52: Error: Method 'call' cannot be called on 'Function?' because it is potentially null.
+ - 'Function' is from 'dart:core'.
+Try calling using ?. instead.
+ var localFunctionExplicitCall = nullableFunction.call();
+ ^^^^" in self::nullableFunction.call();
+ core::Function? localFunctionTearOff = let final<BottomType> #t49 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:58:47: Error: Property 'call' cannot be accessed on 'Function?' because it is potentially null.
+ - 'Function' is from 'dart:core'.
+Try accessing using ?. instead.
+ var localFunctionTearOff = nullableFunction.call;
+ ^^^^" in self::nullableFunction.call;
+ void localFunctionTypeImplicitCall = let final<BottomType> #t50 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:59:59: Error: Can't use an expression of type 'void Function()?' as a function because it's potentially null.
+Try calling using ?.call instead.
+ var localFunctionTypeImplicitCall = nullableFunctionType();
+ ^" in self::nullableFunctionType.call();
+ void localFunctionTypeExplicitCall = let final<BottomType> #t51 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:60:60: Error: Method 'call' cannot be called on 'void Function()?' because it is potentially null.
+Try calling using ?. instead.
+ var localFunctionTypeExplicitCall = nullableFunctionType.call();
+ ^^^^" in self::nullableFunctionType.call();
+ () →? void localFunctionTypeTearOff = let final<BottomType> #t52 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:61:55: Error: Property 'call' cannot be accessed on 'void Function()?' because it is potentially null.
+Try accessing using ?. instead.
+ var localFunctionTypeTearOff = nullableFunctionType.call;
+ ^^^^" in self::nullableFunctionType.call;
+ dynamic localFunctionField = self::nullableClass.{self::Class::functionField}.call();
+ void localFunctionTypeField = self::nullableClass.{self::Class::functionTypeField}.call();
+ dynamic localFunctionGetter = self::nullableClass.{self::Class::functionGetter}.call();
+ void localFunctionTypeGetter = self::nullableClass.{self::Class::functionTypeGetter}.call();
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/potentially_nullable_access.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/potentially_nullable_access.dart.strong.transformed.expect
new file mode 100644
index 0000000..f0ea1d5
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/potentially_nullable_access.dart.strong.transformed.expect
@@ -0,0 +1,356 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:20:34: Error: Operator '+' cannot be called on 'int?' because it is potentially null.
+// var topLevelBinary = nullableInt + 0;
+// ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:21:21: Error: Operator 'unary-' cannot be called on 'int?' because it is potentially null.
+// var topLevelUnary = -nullableInt;
+// ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:22:35: Error: Operator '[]' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
+// - 'Map' is from 'dart:core'.
+// var topLevelIndexGet = nullableMap[0];
+// ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:23:35: Error: Operator '[]=' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
+// - 'Map' is from 'dart:core'.
+// var topLevelIndexSet = nullableMap[0] = 1;
+// ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:24:38: Error: Operator '[]' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
+// - 'Map' is from 'dart:core'.
+// var topLevelIndexGetSet = nullableMap[0] += 1;
+// ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:24:38: Error: Operator '[]=' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
+// - 'Map' is from 'dart:core'.
+// var topLevelIndexGetSet = nullableMap[0] += 1;
+// ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:25:41: Error: Property 'property' cannot be accessed on 'Class?' because it is potentially null.
+// - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try accessing using ?. instead.
+// var topLevelPropertyGet = nullableClass.property;
+// ^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:26:41: Error: Property 'property' cannot be accessed on 'Class?' because it is potentially null.
+// - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try accessing using ?. instead.
+// var topLevelPropertySet = nullableClass.property = 1;
+// ^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:27:44: Error: Property 'property' cannot be accessed on 'Class?' because it is potentially null.
+// - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try accessing using ?. instead.
+// var topLevelPropertyGetSet = nullableClass.property += 1;
+// ^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:28:46: Error: Method 'method' cannot be called on 'Class?' because it is potentially null.
+// - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try calling using ?. instead.
+// var topLevelMethodInvocation = nullableClass.method();
+// ^^^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:29:43: Error: Property 'method' cannot be accessed on 'Class?' because it is potentially null.
+// - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try accessing using ?. instead.
+// var topLevelMethodTearOff = nullableClass.method;
+// ^^^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:30:52: Error: Method 'call' cannot be called on 'Function?' because it is potentially null.
+// - 'Function' is from 'dart:core'.
+// Try calling using ?. instead.
+// var topLevelFunctionImplicitCall = nullableFunction();
+// ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:31:53: Error: Method 'call' cannot be called on 'Function?' because it is potentially null.
+// - 'Function' is from 'dart:core'.
+// Try calling using ?. instead.
+// var topLevelFunctionExplicitCall = nullableFunction.call();
+// ^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:32:48: Error: Property 'call' cannot be accessed on 'Function?' because it is potentially null.
+// - 'Function' is from 'dart:core'.
+// Try accessing using ?. instead.
+// var topLevelFunctionTearOff = nullableFunction.call;
+// ^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:33:60: Error: Method 'call' cannot be called on 'void Function()?' because it is potentially null.
+// Try calling using ?. instead.
+// var topLevelFunctionTypeImplicitCall = nullableFunctionType();
+// ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:34:61: Error: Method 'call' cannot be called on 'void Function()?' because it is potentially null.
+// Try calling using ?. instead.
+// var topLevelFunctionTypeExplicitCall = nullableFunctionType.call();
+// ^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:35:56: Error: Property 'call' cannot be accessed on 'void Function()?' because it is potentially null.
+// Try accessing using ?. instead.
+// var topLevelFunctionTypeTearOff = nullableFunctionType.call;
+// ^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:38:33: Error: Operator '+' cannot be called on 'int?' because it is potentially null.
+// var localBinary = nullableInt + 0;
+// ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:39:20: Error: Operator 'unary-' cannot be called on 'int?' because it is potentially null.
+// var localUnary = -nullableInt;
+// ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:40:34: Error: Operator '[]' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
+// - 'Map' is from 'dart:core'.
+// var localIndexGet = nullableMap[0];
+// ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:41:34: Error: Operator '[]=' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
+// - 'Map' is from 'dart:core'.
+// var localIndexSet = nullableMap[0] = 1;
+// ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:42:37: Error: Operator '[]' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
+// - 'Map' is from 'dart:core'.
+// var localIndexGetSet = nullableMap[0] += 1;
+// ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:42:37: Error: Operator '[]=' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
+// - 'Map' is from 'dart:core'.
+// var localIndexGetSet = nullableMap[0] += 1;
+// ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:43:40: Error: Property 'property' cannot be accessed on 'Class?' because it is potentially null.
+// - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try accessing using ?. instead.
+// var localPropertyGet = nullableClass.property;
+// ^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:44:40: Error: Property 'property' cannot be accessed on 'Class?' because it is potentially null.
+// - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try accessing using ?. instead.
+// var localPropertySet = nullableClass.property = 1;
+// ^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:45:43: Error: Property 'property' cannot be accessed on 'Class?' because it is potentially null.
+// - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try accessing using ?. instead.
+// var localPropertyGetSet = nullableClass.property += 1;
+// ^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:46:45: Error: Method 'method' cannot be called on 'Class?' because it is potentially null.
+// - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try calling using ?. instead.
+// var localMethodInvocation = nullableClass.method();
+// ^^^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:47:42: Error: Property 'method' cannot be accessed on 'Class?' because it is potentially null.
+// - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try accessing using ?. instead.
+// var localMethodTearOff = nullableClass.method;
+// ^^^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:48:51: Error: Method 'call' cannot be called on 'Function?' because it is potentially null.
+// - 'Function' is from 'dart:core'.
+// Try calling using ?. instead.
+// var localFunctionImplicitCall = nullableFunction();
+// ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:49:52: Error: Method 'call' cannot be called on 'Function?' because it is potentially null.
+// - 'Function' is from 'dart:core'.
+// Try calling using ?. instead.
+// var localFunctionExplicitCall = nullableFunction.call();
+// ^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:50:47: Error: Property 'call' cannot be accessed on 'Function?' because it is potentially null.
+// - 'Function' is from 'dart:core'.
+// Try accessing using ?. instead.
+// var localFunctionTearOff = nullableFunction.call;
+// ^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:51:59: Error: Method 'call' cannot be called on 'void Function()?' because it is potentially null.
+// Try calling using ?. instead.
+// var localFunctionTypeImplicitCall = nullableFunctionType();
+// ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:52:60: Error: Method 'call' cannot be called on 'void Function()?' because it is potentially null.
+// Try calling using ?. instead.
+// var localFunctionTypeExplicitCall = nullableFunctionType.call();
+// ^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:53:55: Error: Property 'call' cannot be accessed on 'void Function()?' because it is potentially null.
+// Try accessing using ?. instead.
+// var localFunctionTypeTearOff = nullableFunctionType.call;
+// ^^^^
+//
+import self as self;
+import "dart:core" as core;
+
+class Class extends core::Object {
+ field core::int property = 0;
+ synthetic constructor •() → self::Class
+ : super core::Object::•()
+ ;
+ method method() → core::int
+ return 0;
+}
+static field core::num topLevelBinary = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:20:34: Error: Operator '+' cannot be called on 'int?' because it is potentially null.
+var topLevelBinary = nullableInt + 0;
+ ^";
+static field core::int topLevelUnary = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:21:21: Error: Operator 'unary-' cannot be called on 'int?' because it is potentially null.
+var topLevelUnary = -nullableInt;
+ ^";
+static field dynamic topLevelIndexGet = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:22:35: Error: Operator '[]' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
+ - 'Map' is from 'dart:core'.
+var topLevelIndexGet = nullableMap[0];
+ ^";
+static field core::int topLevelIndexSet = let final core::Map<dynamic, dynamic>? #t1 = self::nullableMap in let final core::int #t2 = 0 in let final core::int #t3 = 1 in let final void #t4 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:23:35: Error: Operator '[]=' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
+ - 'Map' is from 'dart:core'.
+var topLevelIndexSet = nullableMap[0] = 1;
+ ^" in #t3;
+static field dynamic topLevelIndexGetSet = let final core::Map<dynamic, dynamic>? #t5 = self::nullableMap in let final core::int #t6 = 0 in let final dynamic #t7 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:24:38: Error: Operator '[]' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
+ - 'Map' is from 'dart:core'.
+var topLevelIndexGetSet = nullableMap[0] += 1;
+ ^".+(1) in let final void #t8 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:24:38: Error: Operator '[]=' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
+ - 'Map' is from 'dart:core'.
+var topLevelIndexGetSet = nullableMap[0] += 1;
+ ^" in #t7;
+static field core::int topLevelPropertyGet = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:25:41: Error: Property 'property' cannot be accessed on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try accessing using ?. instead.
+var topLevelPropertyGet = nullableClass.property;
+ ^^^^^^^^";
+static field core::int topLevelPropertySet = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:26:41: Error: Property 'property' cannot be accessed on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try accessing using ?. instead.
+var topLevelPropertySet = nullableClass.property = 1;
+ ^^^^^^^^";
+static field core::int topLevelPropertyGetSet = let final self::Class? #t9 = self::nullableClass in invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:27:44: Error: Property 'property' cannot be accessed on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try accessing using ?. instead.
+var topLevelPropertyGetSet = nullableClass.property += 1;
+ ^^^^^^^^";
+static field dynamic topLevelMethodInvocation = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:28:46: Error: Method 'method' cannot be called on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try calling using ?. instead.
+var topLevelMethodInvocation = nullableClass.method();
+ ^^^^^^";
+static field () → core::int topLevelMethodTearOff = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:29:43: Error: Property 'method' cannot be accessed on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try accessing using ?. instead.
+var topLevelMethodTearOff = nullableClass.method;
+ ^^^^^^";
+static field dynamic topLevelFunctionImplicitCall = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:30:52: Error: Method 'call' cannot be called on 'Function?' because it is potentially null.
+ - 'Function' is from 'dart:core'.
+Try calling using ?. instead.
+var topLevelFunctionImplicitCall = nullableFunction();
+ ^";
+static field dynamic topLevelFunctionExplicitCall = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:31:53: Error: Method 'call' cannot be called on 'Function?' because it is potentially null.
+ - 'Function' is from 'dart:core'.
+Try calling using ?. instead.
+var topLevelFunctionExplicitCall = nullableFunction.call();
+ ^^^^";
+static field core::Function? topLevelFunctionTearOff = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:32:48: Error: Property 'call' cannot be accessed on 'Function?' because it is potentially null.
+ - 'Function' is from 'dart:core'.
+Try accessing using ?. instead.
+var topLevelFunctionTearOff = nullableFunction.call;
+ ^^^^";
+static field dynamic topLevelFunctionTypeImplicitCall = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:33:60: Error: Method 'call' cannot be called on 'void Function()?' because it is potentially null.
+Try calling using ?. instead.
+var topLevelFunctionTypeImplicitCall = nullableFunctionType();
+ ^";
+static field dynamic topLevelFunctionTypeExplicitCall = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:34:61: Error: Method 'call' cannot be called on 'void Function()?' because it is potentially null.
+Try calling using ?. instead.
+var topLevelFunctionTypeExplicitCall = nullableFunctionType.call();
+ ^^^^";
+static field () →? void topLevelFunctionTypeTearOff = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:35:56: Error: Property 'call' cannot be accessed on 'void Function()?' because it is potentially null.
+Try accessing using ?. instead.
+var topLevelFunctionTypeTearOff = nullableFunctionType.call;
+ ^^^^";
+static get nullableFunction() → core::Function?
+ return () → core::Null? {};
+static get nullableFunctionType() → () →? void
+ return () → core::Null? {};
+static get nullableInt() → core::int?
+ return 0;
+static get nullableMap() → core::Map<dynamic, dynamic>?
+ return <dynamic, dynamic>{};
+static get nullableClass() → self::Class?
+ return new self::Class::•();
+static method test() → dynamic {
+ core::num localBinary = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:38:33: Error: Operator '+' cannot be called on 'int?' because it is potentially null.
+ var localBinary = nullableInt + 0;
+ ^";
+ core::int localUnary = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:39:20: Error: Operator 'unary-' cannot be called on 'int?' because it is potentially null.
+ var localUnary = -nullableInt;
+ ^";
+ dynamic localIndexGet = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:40:34: Error: Operator '[]' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
+ - 'Map' is from 'dart:core'.
+ var localIndexGet = nullableMap[0];
+ ^";
+ core::int localIndexSet = let final core::Map<dynamic, dynamic>? #t10 = self::nullableMap in let final core::int #t11 = 0 in let final core::int #t12 = 1 in let final void #t13 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:41:34: Error: Operator '[]=' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
+ - 'Map' is from 'dart:core'.
+ var localIndexSet = nullableMap[0] = 1;
+ ^" in #t12;
+ dynamic localIndexGetSet = let final core::Map<dynamic, dynamic>? #t14 = self::nullableMap in let final core::int #t15 = 0 in let final dynamic #t16 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:42:37: Error: Operator '[]' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
+ - 'Map' is from 'dart:core'.
+ var localIndexGetSet = nullableMap[0] += 1;
+ ^".+(1) in let final void #t17 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:42:37: Error: Operator '[]=' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
+ - 'Map' is from 'dart:core'.
+ var localIndexGetSet = nullableMap[0] += 1;
+ ^" in #t16;
+ core::int localPropertyGet = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:43:40: Error: Property 'property' cannot be accessed on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try accessing using ?. instead.
+ var localPropertyGet = nullableClass.property;
+ ^^^^^^^^";
+ core::int localPropertySet = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:44:40: Error: Property 'property' cannot be accessed on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try accessing using ?. instead.
+ var localPropertySet = nullableClass.property = 1;
+ ^^^^^^^^";
+ core::int localPropertyGetSet = let final self::Class? #t18 = self::nullableClass in invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:45:43: Error: Property 'property' cannot be accessed on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try accessing using ?. instead.
+ var localPropertyGetSet = nullableClass.property += 1;
+ ^^^^^^^^";
+ dynamic localMethodInvocation = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:46:45: Error: Method 'method' cannot be called on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try calling using ?. instead.
+ var localMethodInvocation = nullableClass.method();
+ ^^^^^^";
+ () → core::int localMethodTearOff = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:47:42: Error: Property 'method' cannot be accessed on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try accessing using ?. instead.
+ var localMethodTearOff = nullableClass.method;
+ ^^^^^^";
+ dynamic localFunctionImplicitCall = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:48:51: Error: Method 'call' cannot be called on 'Function?' because it is potentially null.
+ - 'Function' is from 'dart:core'.
+Try calling using ?. instead.
+ var localFunctionImplicitCall = nullableFunction();
+ ^";
+ dynamic localFunctionExplicitCall = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:49:52: Error: Method 'call' cannot be called on 'Function?' because it is potentially null.
+ - 'Function' is from 'dart:core'.
+Try calling using ?. instead.
+ var localFunctionExplicitCall = nullableFunction.call();
+ ^^^^";
+ core::Function? localFunctionTearOff = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:50:47: Error: Property 'call' cannot be accessed on 'Function?' because it is potentially null.
+ - 'Function' is from 'dart:core'.
+Try accessing using ?. instead.
+ var localFunctionTearOff = nullableFunction.call;
+ ^^^^";
+ dynamic localFunctionTypeImplicitCall = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:51:59: Error: Method 'call' cannot be called on 'void Function()?' because it is potentially null.
+Try calling using ?. instead.
+ var localFunctionTypeImplicitCall = nullableFunctionType();
+ ^";
+ dynamic localFunctionTypeExplicitCall = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:52:60: Error: Method 'call' cannot be called on 'void Function()?' because it is potentially null.
+Try calling using ?. instead.
+ var localFunctionTypeExplicitCall = nullableFunctionType.call();
+ ^^^^";
+ () →? void localFunctionTypeTearOff = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:53:55: Error: Property 'call' cannot be accessed on 'void Function()?' because it is potentially null.
+Try accessing using ?. instead.
+ var localFunctionTypeTearOff = nullableFunctionType.call;
+ ^^^^";
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/potentially_nullable_access.dart.weak.expect b/pkg/front_end/testcases/nnbd/potentially_nullable_access.dart.weak.expect
new file mode 100644
index 0000000..eeb102b
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/potentially_nullable_access.dart.weak.expect
@@ -0,0 +1,358 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:24:34: Error: Operator '+' cannot be called on 'int?' because it is potentially null.
+// var topLevelBinary = nullableInt + 0;
+// ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:25:21: Error: Operator 'unary-' cannot be called on 'int?' because it is potentially null.
+// var topLevelUnary = -nullableInt;
+// ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:26:35: Error: Operator '[]' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
+// - 'Map' is from 'dart:core'.
+// var topLevelIndexGet = nullableMap[0];
+// ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:27:35: Error: Operator '[]=' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
+// - 'Map' is from 'dart:core'.
+// var topLevelIndexSet = nullableMap[0] = 1;
+// ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:28:38: Error: Operator '[]' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
+// - 'Map' is from 'dart:core'.
+// var topLevelIndexGetSet = nullableMap[0] += 1;
+// ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:28:38: Error: Operator '[]=' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
+// - 'Map' is from 'dart:core'.
+// var topLevelIndexGetSet = nullableMap[0] += 1;
+// ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:29:41: Error: Property 'property' cannot be accessed on 'Class?' because it is potentially null.
+// - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try accessing using ?. instead.
+// var topLevelPropertyGet = nullableClass.property;
+// ^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:30:41: Error: Property 'property' cannot be accessed on 'Class?' because it is potentially null.
+// - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try accessing using ?. instead.
+// var topLevelPropertySet = nullableClass.property = 1;
+// ^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:31:44: Error: Property 'property' cannot be accessed on 'Class?' because it is potentially null.
+// - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try accessing using ?. instead.
+// var topLevelPropertyGetSet = nullableClass.property += 1;
+// ^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:32:46: Error: Method 'method' cannot be called on 'Class?' because it is potentially null.
+// - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try calling using ?. instead.
+// var topLevelMethodInvocation = nullableClass.method();
+// ^^^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:34:52: Error: Can't use an expression of type 'Function?' as a function because it's potentially null.
+// - 'Function' is from 'dart:core'.
+// Try calling using ?.call instead.
+// var topLevelFunctionImplicitCall = nullableFunction();
+// ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:35:53: Error: Method 'call' cannot be called on 'Function?' because it is potentially null.
+// - 'Function' is from 'dart:core'.
+// Try calling using ?. instead.
+// var topLevelFunctionExplicitCall = nullableFunction.call();
+// ^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:36:48: Error: Property 'call' cannot be accessed on 'Function?' because it is potentially null.
+// - 'Function' is from 'dart:core'.
+// Try accessing using ?. instead.
+// var topLevelFunctionTearOff = nullableFunction.call;
+// ^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:37:60: Error: Can't use an expression of type 'void Function()?' as a function because it's potentially null.
+// Try calling using ?.call instead.
+// var topLevelFunctionTypeImplicitCall = nullableFunctionType();
+// ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:38:61: Error: Method 'call' cannot be called on 'void Function()?' because it is potentially null.
+// Try calling using ?. instead.
+// var topLevelFunctionTypeExplicitCall = nullableFunctionType.call();
+// ^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:39:56: Error: Property 'call' cannot be accessed on 'void Function()?' because it is potentially null.
+// Try accessing using ?. instead.
+// var topLevelFunctionTypeTearOff = nullableFunctionType.call;
+// ^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:46:33: Error: Operator '+' cannot be called on 'int?' because it is potentially null.
+// var localBinary = nullableInt + 0;
+// ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:47:20: Error: Operator 'unary-' cannot be called on 'int?' because it is potentially null.
+// var localUnary = -nullableInt;
+// ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:48:34: Error: Operator '[]' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
+// - 'Map' is from 'dart:core'.
+// var localIndexGet = nullableMap[0];
+// ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:49:34: Error: Operator '[]=' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
+// - 'Map' is from 'dart:core'.
+// var localIndexSet = nullableMap[0] = 1;
+// ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:50:37: Error: Operator '[]' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
+// - 'Map' is from 'dart:core'.
+// var localIndexGetSet = nullableMap[0] += 1;
+// ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:50:37: Error: Operator '[]=' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
+// - 'Map' is from 'dart:core'.
+// var localIndexGetSet = nullableMap[0] += 1;
+// ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:51:40: Error: Property 'property' cannot be accessed on 'Class?' because it is potentially null.
+// - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try accessing using ?. instead.
+// var localPropertyGet = nullableClass.property;
+// ^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:52:40: Error: Property 'property' cannot be accessed on 'Class?' because it is potentially null.
+// - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try accessing using ?. instead.
+// var localPropertySet = nullableClass.property = 1;
+// ^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:53:43: Error: Property 'property' cannot be accessed on 'Class?' because it is potentially null.
+// - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try accessing using ?. instead.
+// var localPropertyGetSet = nullableClass.property += 1;
+// ^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:54:45: Error: Method 'method' cannot be called on 'Class?' because it is potentially null.
+// - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try calling using ?. instead.
+// var localMethodInvocation = nullableClass.method();
+// ^^^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:56:51: Error: Can't use an expression of type 'Function?' as a function because it's potentially null.
+// - 'Function' is from 'dart:core'.
+// Try calling using ?.call instead.
+// var localFunctionImplicitCall = nullableFunction();
+// ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:57:52: Error: Method 'call' cannot be called on 'Function?' because it is potentially null.
+// - 'Function' is from 'dart:core'.
+// Try calling using ?. instead.
+// var localFunctionExplicitCall = nullableFunction.call();
+// ^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:58:47: Error: Property 'call' cannot be accessed on 'Function?' because it is potentially null.
+// - 'Function' is from 'dart:core'.
+// Try accessing using ?. instead.
+// var localFunctionTearOff = nullableFunction.call;
+// ^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:59:59: Error: Can't use an expression of type 'void Function()?' as a function because it's potentially null.
+// Try calling using ?.call instead.
+// var localFunctionTypeImplicitCall = nullableFunctionType();
+// ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:60:60: Error: Method 'call' cannot be called on 'void Function()?' because it is potentially null.
+// Try calling using ?. instead.
+// var localFunctionTypeExplicitCall = nullableFunctionType.call();
+// ^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:61:55: Error: Property 'call' cannot be accessed on 'void Function()?' because it is potentially null.
+// Try accessing using ?. instead.
+// var localFunctionTypeTearOff = nullableFunctionType.call;
+// ^^^^
+//
+import self as self;
+import "dart:core" as core;
+
+class Class extends core::Object {
+ field core::int property = 0;
+ field core::Function functionField = () → core::Null? {};
+ field () → void functionTypeField = () → core::Null? {};
+ synthetic constructor •() → self::Class
+ : super core::Object::•()
+ ;
+ method method() → core::int
+ return 0;
+ get functionGetter() → core::Function
+ return () → core::Null? {};
+ get functionTypeGetter() → () → void
+ return () → core::Null? {};
+}
+static field core::int? topLevelBinary = let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:24:34: Error: Operator '+' cannot be called on 'int?' because it is potentially null.
+var topLevelBinary = nullableInt + 0;
+ ^" in self::nullableInt.{core::num::+}(0);
+static field core::int topLevelUnary = let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:25:21: Error: Operator 'unary-' cannot be called on 'int?' because it is potentially null.
+var topLevelUnary = -nullableInt;
+ ^" in self::nullableInt.{core::int::unary-}();
+static field dynamic topLevelIndexGet = let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:26:35: Error: Operator '[]' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
+ - 'Map' is from 'dart:core'.
+var topLevelIndexGet = nullableMap[0];
+ ^" in self::nullableMap.{core::Map::[]}(0);
+static field core::int topLevelIndexSet = let final core::Map<dynamic, dynamic>? #t4 = self::nullableMap in let final core::int #t5 = 0 in let final core::int #t6 = 1 in let final void #t7 = let final<BottomType> #t8 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:27:35: Error: Operator '[]=' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
+ - 'Map' is from 'dart:core'.
+var topLevelIndexSet = nullableMap[0] = 1;
+ ^" in #t4.{core::Map::[]=}(#t5, #t6) in #t6;
+static field dynamic topLevelIndexGetSet = let final core::Map<dynamic, dynamic>? #t9 = self::nullableMap in let final core::int #t10 = 0 in let final dynamic #t11 = (let final<BottomType> #t12 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:28:38: Error: Operator '[]' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
+ - 'Map' is from 'dart:core'.
+var topLevelIndexGetSet = nullableMap[0] += 1;
+ ^" in #t9.{core::Map::[]}(#t10)).+(1) in let final void #t13 = let final<BottomType> #t14 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:28:38: Error: Operator '[]=' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
+ - 'Map' is from 'dart:core'.
+var topLevelIndexGetSet = nullableMap[0] += 1;
+ ^" in #t9.{core::Map::[]=}(#t10, #t11) in #t11;
+static field core::int topLevelPropertyGet = let final<BottomType> #t15 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:29:41: Error: Property 'property' cannot be accessed on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try accessing using ?. instead.
+var topLevelPropertyGet = nullableClass.property;
+ ^^^^^^^^" in self::nullableClass.{self::Class::property};
+static field core::int topLevelPropertySet = let final<BottomType> #t16 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:30:41: Error: Property 'property' cannot be accessed on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try accessing using ?. instead.
+var topLevelPropertySet = nullableClass.property = 1;
+ ^^^^^^^^" in self::nullableClass.{self::Class::property} = 1;
+static field core::int topLevelPropertyGetSet = let final self::Class? #t17 = self::nullableClass in let final<BottomType> #t18 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:31:44: Error: Property 'property' cannot be accessed on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try accessing using ?. instead.
+var topLevelPropertyGetSet = nullableClass.property += 1;
+ ^^^^^^^^" in #t17.{self::Class::property} = (let final<BottomType> #t19 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:31:44: Error: Property 'property' cannot be accessed on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try accessing using ?. instead.
+var topLevelPropertyGetSet = nullableClass.property += 1;
+ ^^^^^^^^" in #t17.{self::Class::property}).{core::num::+}(1);
+static field core::int topLevelMethodInvocation = let final<BottomType> #t20 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:32:46: Error: Method 'method' cannot be called on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try calling using ?. instead.
+var topLevelMethodInvocation = nullableClass.method();
+ ^^^^^^" in self::nullableClass.{self::Class::method}();
+static field () → core::int topLevelMethodTearOff = self::nullableClass.{self::Class::method};
+static field dynamic topLevelFunctionImplicitCall = let final<BottomType> #t21 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:34:52: Error: Can't use an expression of type 'Function?' as a function because it's potentially null.
+ - 'Function' is from 'dart:core'.
+Try calling using ?.call instead.
+var topLevelFunctionImplicitCall = nullableFunction();
+ ^" in self::nullableFunction.call();
+static field dynamic topLevelFunctionExplicitCall = let final<BottomType> #t22 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:35:53: Error: Method 'call' cannot be called on 'Function?' because it is potentially null.
+ - 'Function' is from 'dart:core'.
+Try calling using ?. instead.
+var topLevelFunctionExplicitCall = nullableFunction.call();
+ ^^^^" in self::nullableFunction.call();
+static field core::Function? topLevelFunctionTearOff = let final<BottomType> #t23 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:36:48: Error: Property 'call' cannot be accessed on 'Function?' because it is potentially null.
+ - 'Function' is from 'dart:core'.
+Try accessing using ?. instead.
+var topLevelFunctionTearOff = nullableFunction.call;
+ ^^^^" in self::nullableFunction.call;
+static field void topLevelFunctionTypeImplicitCall = let final<BottomType> #t24 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:37:60: Error: Can't use an expression of type 'void Function()?' as a function because it's potentially null.
+Try calling using ?.call instead.
+var topLevelFunctionTypeImplicitCall = nullableFunctionType();
+ ^" in self::nullableFunctionType.call();
+static field void topLevelFunctionTypeExplicitCall = let final<BottomType> #t25 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:38:61: Error: Method 'call' cannot be called on 'void Function()?' because it is potentially null.
+Try calling using ?. instead.
+var topLevelFunctionTypeExplicitCall = nullableFunctionType.call();
+ ^^^^" in self::nullableFunctionType.call();
+static field () →? void topLevelFunctionTypeTearOff = let final<BottomType> #t26 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:39:56: Error: Property 'call' cannot be accessed on 'void Function()?' because it is potentially null.
+Try accessing using ?. instead.
+var topLevelFunctionTypeTearOff = nullableFunctionType.call;
+ ^^^^" in self::nullableFunctionType.call;
+static field dynamic topLevelFunctionField = self::nullableClass.{self::Class::functionField}.call();
+static field void topLevelFunctionTypeField = self::nullableClass.{self::Class::functionTypeField}.call();
+static field dynamic topLevelFunctionGetter = self::nullableClass.{self::Class::functionGetter}.call();
+static field void topLevelFunctionTypeGetter = self::nullableClass.{self::Class::functionTypeGetter}.call();
+static get nullableFunction() → core::Function?
+ return () → core::Null? {};
+static get nullableFunctionType() → () →? void
+ return () → core::Null? {};
+static get nullableInt() → core::int?
+ return 0;
+static get nullableMap() → core::Map<dynamic, dynamic>?
+ return <dynamic, dynamic>{};
+static get nullableClass() → self::Class?
+ return new self::Class::•();
+static method test() → dynamic {
+ core::int? localBinary = let final<BottomType> #t27 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:46:33: Error: Operator '+' cannot be called on 'int?' because it is potentially null.
+ var localBinary = nullableInt + 0;
+ ^" in self::nullableInt.{core::num::+}(0);
+ core::int localUnary = let final<BottomType> #t28 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:47:20: Error: Operator 'unary-' cannot be called on 'int?' because it is potentially null.
+ var localUnary = -nullableInt;
+ ^" in self::nullableInt.{core::int::unary-}();
+ dynamic localIndexGet = let final<BottomType> #t29 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:48:34: Error: Operator '[]' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
+ - 'Map' is from 'dart:core'.
+ var localIndexGet = nullableMap[0];
+ ^" in self::nullableMap.{core::Map::[]}(0);
+ core::int localIndexSet = let final core::Map<dynamic, dynamic>? #t30 = self::nullableMap in let final core::int #t31 = 0 in let final core::int #t32 = 1 in let final void #t33 = let final<BottomType> #t34 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:49:34: Error: Operator '[]=' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
+ - 'Map' is from 'dart:core'.
+ var localIndexSet = nullableMap[0] = 1;
+ ^" in #t30.{core::Map::[]=}(#t31, #t32) in #t32;
+ dynamic localIndexGetSet = let final core::Map<dynamic, dynamic>? #t35 = self::nullableMap in let final core::int #t36 = 0 in let final dynamic #t37 = (let final<BottomType> #t38 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:50:37: Error: Operator '[]' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
+ - 'Map' is from 'dart:core'.
+ var localIndexGetSet = nullableMap[0] += 1;
+ ^" in #t35.{core::Map::[]}(#t36)).+(1) in let final void #t39 = let final<BottomType> #t40 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:50:37: Error: Operator '[]=' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
+ - 'Map' is from 'dart:core'.
+ var localIndexGetSet = nullableMap[0] += 1;
+ ^" in #t35.{core::Map::[]=}(#t36, #t37) in #t37;
+ core::int localPropertyGet = let final<BottomType> #t41 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:51:40: Error: Property 'property' cannot be accessed on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try accessing using ?. instead.
+ var localPropertyGet = nullableClass.property;
+ ^^^^^^^^" in self::nullableClass.{self::Class::property};
+ core::int localPropertySet = let final<BottomType> #t42 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:52:40: Error: Property 'property' cannot be accessed on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try accessing using ?. instead.
+ var localPropertySet = nullableClass.property = 1;
+ ^^^^^^^^" in self::nullableClass.{self::Class::property} = 1;
+ core::int localPropertyGetSet = let final self::Class? #t43 = self::nullableClass in let final<BottomType> #t44 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:53:43: Error: Property 'property' cannot be accessed on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try accessing using ?. instead.
+ var localPropertyGetSet = nullableClass.property += 1;
+ ^^^^^^^^" in #t43.{self::Class::property} = (let final<BottomType> #t45 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:53:43: Error: Property 'property' cannot be accessed on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try accessing using ?. instead.
+ var localPropertyGetSet = nullableClass.property += 1;
+ ^^^^^^^^" in #t43.{self::Class::property}).{core::num::+}(1);
+ core::int localMethodInvocation = let final<BottomType> #t46 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:54:45: Error: Method 'method' cannot be called on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try calling using ?. instead.
+ var localMethodInvocation = nullableClass.method();
+ ^^^^^^" in self::nullableClass.{self::Class::method}();
+ () → core::int localMethodTearOff = self::nullableClass.{self::Class::method};
+ dynamic localFunctionImplicitCall = let final<BottomType> #t47 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:56:51: Error: Can't use an expression of type 'Function?' as a function because it's potentially null.
+ - 'Function' is from 'dart:core'.
+Try calling using ?.call instead.
+ var localFunctionImplicitCall = nullableFunction();
+ ^" in self::nullableFunction.call();
+ dynamic localFunctionExplicitCall = let final<BottomType> #t48 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:57:52: Error: Method 'call' cannot be called on 'Function?' because it is potentially null.
+ - 'Function' is from 'dart:core'.
+Try calling using ?. instead.
+ var localFunctionExplicitCall = nullableFunction.call();
+ ^^^^" in self::nullableFunction.call();
+ core::Function? localFunctionTearOff = let final<BottomType> #t49 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:58:47: Error: Property 'call' cannot be accessed on 'Function?' because it is potentially null.
+ - 'Function' is from 'dart:core'.
+Try accessing using ?. instead.
+ var localFunctionTearOff = nullableFunction.call;
+ ^^^^" in self::nullableFunction.call;
+ void localFunctionTypeImplicitCall = let final<BottomType> #t50 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:59:59: Error: Can't use an expression of type 'void Function()?' as a function because it's potentially null.
+Try calling using ?.call instead.
+ var localFunctionTypeImplicitCall = nullableFunctionType();
+ ^" in self::nullableFunctionType.call();
+ void localFunctionTypeExplicitCall = let final<BottomType> #t51 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:60:60: Error: Method 'call' cannot be called on 'void Function()?' because it is potentially null.
+Try calling using ?. instead.
+ var localFunctionTypeExplicitCall = nullableFunctionType.call();
+ ^^^^" in self::nullableFunctionType.call();
+ () →? void localFunctionTypeTearOff = let final<BottomType> #t52 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:61:55: Error: Property 'call' cannot be accessed on 'void Function()?' because it is potentially null.
+Try accessing using ?. instead.
+ var localFunctionTypeTearOff = nullableFunctionType.call;
+ ^^^^" in self::nullableFunctionType.call;
+ dynamic localFunctionField = self::nullableClass.{self::Class::functionField}.call();
+ void localFunctionTypeField = self::nullableClass.{self::Class::functionTypeField}.call();
+ dynamic localFunctionGetter = self::nullableClass.{self::Class::functionGetter}.call();
+ void localFunctionTypeGetter = self::nullableClass.{self::Class::functionTypeGetter}.call();
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/potentially_nullable_access.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/potentially_nullable_access.dart.weak.transformed.expect
new file mode 100644
index 0000000..f0ea1d5
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/potentially_nullable_access.dart.weak.transformed.expect
@@ -0,0 +1,356 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:20:34: Error: Operator '+' cannot be called on 'int?' because it is potentially null.
+// var topLevelBinary = nullableInt + 0;
+// ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:21:21: Error: Operator 'unary-' cannot be called on 'int?' because it is potentially null.
+// var topLevelUnary = -nullableInt;
+// ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:22:35: Error: Operator '[]' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
+// - 'Map' is from 'dart:core'.
+// var topLevelIndexGet = nullableMap[0];
+// ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:23:35: Error: Operator '[]=' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
+// - 'Map' is from 'dart:core'.
+// var topLevelIndexSet = nullableMap[0] = 1;
+// ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:24:38: Error: Operator '[]' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
+// - 'Map' is from 'dart:core'.
+// var topLevelIndexGetSet = nullableMap[0] += 1;
+// ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:24:38: Error: Operator '[]=' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
+// - 'Map' is from 'dart:core'.
+// var topLevelIndexGetSet = nullableMap[0] += 1;
+// ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:25:41: Error: Property 'property' cannot be accessed on 'Class?' because it is potentially null.
+// - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try accessing using ?. instead.
+// var topLevelPropertyGet = nullableClass.property;
+// ^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:26:41: Error: Property 'property' cannot be accessed on 'Class?' because it is potentially null.
+// - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try accessing using ?. instead.
+// var topLevelPropertySet = nullableClass.property = 1;
+// ^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:27:44: Error: Property 'property' cannot be accessed on 'Class?' because it is potentially null.
+// - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try accessing using ?. instead.
+// var topLevelPropertyGetSet = nullableClass.property += 1;
+// ^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:28:46: Error: Method 'method' cannot be called on 'Class?' because it is potentially null.
+// - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try calling using ?. instead.
+// var topLevelMethodInvocation = nullableClass.method();
+// ^^^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:29:43: Error: Property 'method' cannot be accessed on 'Class?' because it is potentially null.
+// - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try accessing using ?. instead.
+// var topLevelMethodTearOff = nullableClass.method;
+// ^^^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:30:52: Error: Method 'call' cannot be called on 'Function?' because it is potentially null.
+// - 'Function' is from 'dart:core'.
+// Try calling using ?. instead.
+// var topLevelFunctionImplicitCall = nullableFunction();
+// ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:31:53: Error: Method 'call' cannot be called on 'Function?' because it is potentially null.
+// - 'Function' is from 'dart:core'.
+// Try calling using ?. instead.
+// var topLevelFunctionExplicitCall = nullableFunction.call();
+// ^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:32:48: Error: Property 'call' cannot be accessed on 'Function?' because it is potentially null.
+// - 'Function' is from 'dart:core'.
+// Try accessing using ?. instead.
+// var topLevelFunctionTearOff = nullableFunction.call;
+// ^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:33:60: Error: Method 'call' cannot be called on 'void Function()?' because it is potentially null.
+// Try calling using ?. instead.
+// var topLevelFunctionTypeImplicitCall = nullableFunctionType();
+// ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:34:61: Error: Method 'call' cannot be called on 'void Function()?' because it is potentially null.
+// Try calling using ?. instead.
+// var topLevelFunctionTypeExplicitCall = nullableFunctionType.call();
+// ^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:35:56: Error: Property 'call' cannot be accessed on 'void Function()?' because it is potentially null.
+// Try accessing using ?. instead.
+// var topLevelFunctionTypeTearOff = nullableFunctionType.call;
+// ^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:38:33: Error: Operator '+' cannot be called on 'int?' because it is potentially null.
+// var localBinary = nullableInt + 0;
+// ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:39:20: Error: Operator 'unary-' cannot be called on 'int?' because it is potentially null.
+// var localUnary = -nullableInt;
+// ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:40:34: Error: Operator '[]' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
+// - 'Map' is from 'dart:core'.
+// var localIndexGet = nullableMap[0];
+// ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:41:34: Error: Operator '[]=' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
+// - 'Map' is from 'dart:core'.
+// var localIndexSet = nullableMap[0] = 1;
+// ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:42:37: Error: Operator '[]' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
+// - 'Map' is from 'dart:core'.
+// var localIndexGetSet = nullableMap[0] += 1;
+// ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:42:37: Error: Operator '[]=' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
+// - 'Map' is from 'dart:core'.
+// var localIndexGetSet = nullableMap[0] += 1;
+// ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:43:40: Error: Property 'property' cannot be accessed on 'Class?' because it is potentially null.
+// - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try accessing using ?. instead.
+// var localPropertyGet = nullableClass.property;
+// ^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:44:40: Error: Property 'property' cannot be accessed on 'Class?' because it is potentially null.
+// - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try accessing using ?. instead.
+// var localPropertySet = nullableClass.property = 1;
+// ^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:45:43: Error: Property 'property' cannot be accessed on 'Class?' because it is potentially null.
+// - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try accessing using ?. instead.
+// var localPropertyGetSet = nullableClass.property += 1;
+// ^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:46:45: Error: Method 'method' cannot be called on 'Class?' because it is potentially null.
+// - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try calling using ?. instead.
+// var localMethodInvocation = nullableClass.method();
+// ^^^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:47:42: Error: Property 'method' cannot be accessed on 'Class?' because it is potentially null.
+// - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try accessing using ?. instead.
+// var localMethodTearOff = nullableClass.method;
+// ^^^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:48:51: Error: Method 'call' cannot be called on 'Function?' because it is potentially null.
+// - 'Function' is from 'dart:core'.
+// Try calling using ?. instead.
+// var localFunctionImplicitCall = nullableFunction();
+// ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:49:52: Error: Method 'call' cannot be called on 'Function?' because it is potentially null.
+// - 'Function' is from 'dart:core'.
+// Try calling using ?. instead.
+// var localFunctionExplicitCall = nullableFunction.call();
+// ^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:50:47: Error: Property 'call' cannot be accessed on 'Function?' because it is potentially null.
+// - 'Function' is from 'dart:core'.
+// Try accessing using ?. instead.
+// var localFunctionTearOff = nullableFunction.call;
+// ^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:51:59: Error: Method 'call' cannot be called on 'void Function()?' because it is potentially null.
+// Try calling using ?. instead.
+// var localFunctionTypeImplicitCall = nullableFunctionType();
+// ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:52:60: Error: Method 'call' cannot be called on 'void Function()?' because it is potentially null.
+// Try calling using ?. instead.
+// var localFunctionTypeExplicitCall = nullableFunctionType.call();
+// ^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:53:55: Error: Property 'call' cannot be accessed on 'void Function()?' because it is potentially null.
+// Try accessing using ?. instead.
+// var localFunctionTypeTearOff = nullableFunctionType.call;
+// ^^^^
+//
+import self as self;
+import "dart:core" as core;
+
+class Class extends core::Object {
+ field core::int property = 0;
+ synthetic constructor •() → self::Class
+ : super core::Object::•()
+ ;
+ method method() → core::int
+ return 0;
+}
+static field core::num topLevelBinary = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:20:34: Error: Operator '+' cannot be called on 'int?' because it is potentially null.
+var topLevelBinary = nullableInt + 0;
+ ^";
+static field core::int topLevelUnary = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:21:21: Error: Operator 'unary-' cannot be called on 'int?' because it is potentially null.
+var topLevelUnary = -nullableInt;
+ ^";
+static field dynamic topLevelIndexGet = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:22:35: Error: Operator '[]' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
+ - 'Map' is from 'dart:core'.
+var topLevelIndexGet = nullableMap[0];
+ ^";
+static field core::int topLevelIndexSet = let final core::Map<dynamic, dynamic>? #t1 = self::nullableMap in let final core::int #t2 = 0 in let final core::int #t3 = 1 in let final void #t4 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:23:35: Error: Operator '[]=' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
+ - 'Map' is from 'dart:core'.
+var topLevelIndexSet = nullableMap[0] = 1;
+ ^" in #t3;
+static field dynamic topLevelIndexGetSet = let final core::Map<dynamic, dynamic>? #t5 = self::nullableMap in let final core::int #t6 = 0 in let final dynamic #t7 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:24:38: Error: Operator '[]' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
+ - 'Map' is from 'dart:core'.
+var topLevelIndexGetSet = nullableMap[0] += 1;
+ ^".+(1) in let final void #t8 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:24:38: Error: Operator '[]=' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
+ - 'Map' is from 'dart:core'.
+var topLevelIndexGetSet = nullableMap[0] += 1;
+ ^" in #t7;
+static field core::int topLevelPropertyGet = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:25:41: Error: Property 'property' cannot be accessed on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try accessing using ?. instead.
+var topLevelPropertyGet = nullableClass.property;
+ ^^^^^^^^";
+static field core::int topLevelPropertySet = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:26:41: Error: Property 'property' cannot be accessed on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try accessing using ?. instead.
+var topLevelPropertySet = nullableClass.property = 1;
+ ^^^^^^^^";
+static field core::int topLevelPropertyGetSet = let final self::Class? #t9 = self::nullableClass in invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:27:44: Error: Property 'property' cannot be accessed on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try accessing using ?. instead.
+var topLevelPropertyGetSet = nullableClass.property += 1;
+ ^^^^^^^^";
+static field dynamic topLevelMethodInvocation = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:28:46: Error: Method 'method' cannot be called on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try calling using ?. instead.
+var topLevelMethodInvocation = nullableClass.method();
+ ^^^^^^";
+static field () → core::int topLevelMethodTearOff = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:29:43: Error: Property 'method' cannot be accessed on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try accessing using ?. instead.
+var topLevelMethodTearOff = nullableClass.method;
+ ^^^^^^";
+static field dynamic topLevelFunctionImplicitCall = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:30:52: Error: Method 'call' cannot be called on 'Function?' because it is potentially null.
+ - 'Function' is from 'dart:core'.
+Try calling using ?. instead.
+var topLevelFunctionImplicitCall = nullableFunction();
+ ^";
+static field dynamic topLevelFunctionExplicitCall = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:31:53: Error: Method 'call' cannot be called on 'Function?' because it is potentially null.
+ - 'Function' is from 'dart:core'.
+Try calling using ?. instead.
+var topLevelFunctionExplicitCall = nullableFunction.call();
+ ^^^^";
+static field core::Function? topLevelFunctionTearOff = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:32:48: Error: Property 'call' cannot be accessed on 'Function?' because it is potentially null.
+ - 'Function' is from 'dart:core'.
+Try accessing using ?. instead.
+var topLevelFunctionTearOff = nullableFunction.call;
+ ^^^^";
+static field dynamic topLevelFunctionTypeImplicitCall = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:33:60: Error: Method 'call' cannot be called on 'void Function()?' because it is potentially null.
+Try calling using ?. instead.
+var topLevelFunctionTypeImplicitCall = nullableFunctionType();
+ ^";
+static field dynamic topLevelFunctionTypeExplicitCall = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:34:61: Error: Method 'call' cannot be called on 'void Function()?' because it is potentially null.
+Try calling using ?. instead.
+var topLevelFunctionTypeExplicitCall = nullableFunctionType.call();
+ ^^^^";
+static field () →? void topLevelFunctionTypeTearOff = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:35:56: Error: Property 'call' cannot be accessed on 'void Function()?' because it is potentially null.
+Try accessing using ?. instead.
+var topLevelFunctionTypeTearOff = nullableFunctionType.call;
+ ^^^^";
+static get nullableFunction() → core::Function?
+ return () → core::Null? {};
+static get nullableFunctionType() → () →? void
+ return () → core::Null? {};
+static get nullableInt() → core::int?
+ return 0;
+static get nullableMap() → core::Map<dynamic, dynamic>?
+ return <dynamic, dynamic>{};
+static get nullableClass() → self::Class?
+ return new self::Class::•();
+static method test() → dynamic {
+ core::num localBinary = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:38:33: Error: Operator '+' cannot be called on 'int?' because it is potentially null.
+ var localBinary = nullableInt + 0;
+ ^";
+ core::int localUnary = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:39:20: Error: Operator 'unary-' cannot be called on 'int?' because it is potentially null.
+ var localUnary = -nullableInt;
+ ^";
+ dynamic localIndexGet = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:40:34: Error: Operator '[]' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
+ - 'Map' is from 'dart:core'.
+ var localIndexGet = nullableMap[0];
+ ^";
+ core::int localIndexSet = let final core::Map<dynamic, dynamic>? #t10 = self::nullableMap in let final core::int #t11 = 0 in let final core::int #t12 = 1 in let final void #t13 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:41:34: Error: Operator '[]=' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
+ - 'Map' is from 'dart:core'.
+ var localIndexSet = nullableMap[0] = 1;
+ ^" in #t12;
+ dynamic localIndexGetSet = let final core::Map<dynamic, dynamic>? #t14 = self::nullableMap in let final core::int #t15 = 0 in let final dynamic #t16 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:42:37: Error: Operator '[]' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
+ - 'Map' is from 'dart:core'.
+ var localIndexGetSet = nullableMap[0] += 1;
+ ^".+(1) in let final void #t17 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:42:37: Error: Operator '[]=' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
+ - 'Map' is from 'dart:core'.
+ var localIndexGetSet = nullableMap[0] += 1;
+ ^" in #t16;
+ core::int localPropertyGet = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:43:40: Error: Property 'property' cannot be accessed on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try accessing using ?. instead.
+ var localPropertyGet = nullableClass.property;
+ ^^^^^^^^";
+ core::int localPropertySet = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:44:40: Error: Property 'property' cannot be accessed on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try accessing using ?. instead.
+ var localPropertySet = nullableClass.property = 1;
+ ^^^^^^^^";
+ core::int localPropertyGetSet = let final self::Class? #t18 = self::nullableClass in invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:45:43: Error: Property 'property' cannot be accessed on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try accessing using ?. instead.
+ var localPropertyGetSet = nullableClass.property += 1;
+ ^^^^^^^^";
+ dynamic localMethodInvocation = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:46:45: Error: Method 'method' cannot be called on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try calling using ?. instead.
+ var localMethodInvocation = nullableClass.method();
+ ^^^^^^";
+ () → core::int localMethodTearOff = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:47:42: Error: Property 'method' cannot be accessed on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try accessing using ?. instead.
+ var localMethodTearOff = nullableClass.method;
+ ^^^^^^";
+ dynamic localFunctionImplicitCall = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:48:51: Error: Method 'call' cannot be called on 'Function?' because it is potentially null.
+ - 'Function' is from 'dart:core'.
+Try calling using ?. instead.
+ var localFunctionImplicitCall = nullableFunction();
+ ^";
+ dynamic localFunctionExplicitCall = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:49:52: Error: Method 'call' cannot be called on 'Function?' because it is potentially null.
+ - 'Function' is from 'dart:core'.
+Try calling using ?. instead.
+ var localFunctionExplicitCall = nullableFunction.call();
+ ^^^^";
+ core::Function? localFunctionTearOff = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:50:47: Error: Property 'call' cannot be accessed on 'Function?' because it is potentially null.
+ - 'Function' is from 'dart:core'.
+Try accessing using ?. instead.
+ var localFunctionTearOff = nullableFunction.call;
+ ^^^^";
+ dynamic localFunctionTypeImplicitCall = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:51:59: Error: Method 'call' cannot be called on 'void Function()?' because it is potentially null.
+Try calling using ?. instead.
+ var localFunctionTypeImplicitCall = nullableFunctionType();
+ ^";
+ dynamic localFunctionTypeExplicitCall = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:52:60: Error: Method 'call' cannot be called on 'void Function()?' because it is potentially null.
+Try calling using ?. instead.
+ var localFunctionTypeExplicitCall = nullableFunctionType.call();
+ ^^^^";
+ () →? void localFunctionTypeTearOff = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:53:55: Error: Property 'call' cannot be accessed on 'void Function()?' because it is potentially null.
+Try accessing using ?. instead.
+ var localFunctionTypeTearOff = nullableFunctionType.call;
+ ^^^^";
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/strong.status b/pkg/front_end/testcases/strong.status
index 486fea6..bd6eb1d 100644
--- a/pkg/front_end/testcases/strong.status
+++ b/pkg/front_end/testcases/strong.status
@@ -12,6 +12,84 @@
extensions/invalid_explicit_access: RuntimeError
extensions/issue40713: TypeCheckError
extensions/static_access_of_instance: RuntimeError
+general/abstract_members: TypeCheckError
+general/accessors: RuntimeError
+general/ambiguous_exports: RuntimeError # Expected, this file exports two main methods.
+general/await_in_non_async: RuntimeError # Expected.
+general/bug21938: TypeCheckError
+general/bug30695: TypeCheckError
+general/bug31124: RuntimeError # Test has no main method (and we shouldn't add one).
+general/call: TypeCheckError
+general/candidate_found: TypeCheckError
+general/cascade: RuntimeError
+general/constructor_initializer_invalid: RuntimeError # Fails execution after recovery
+general/covariant_generic: RuntimeError
+general/duplicated_declarations: TypeCheckError
+general/duplicated_field_initializer: RuntimeError
+general/error_locations/error_location_01: RuntimeError
+general/error_locations/error_location_02: RuntimeError
+general/error_locations/error_location_03: RuntimeError
+general/error_locations/error_location_05: RuntimeError
+general/error_locations/error_location_06: RuntimeError
+general/error_recovery/await_not_in_async: RuntimeError
+general/error_recovery/constructor_recovery_bad_name_general.crash: RuntimeError
+general/error_recovery/constructor_recovery_bad_name_get.crash: RuntimeError
+general/error_recovery/constructor_recovery_bad_name_return_type.crash: RuntimeError
+general/error_recovery/constructor_recovery_bad_name_set.crash: RuntimeError
+general/error_recovery/constructor_recovery_get: RuntimeError
+general/error_recovery/constructor_recovery_ok: RuntimeError
+general/error_recovery/constructor_recovery_operator.crash: RuntimeError
+general/error_recovery/constructor_recovery_return_type: RuntimeError
+general/error_recovery/constructor_recovery_set: RuntimeError
+general/error_recovery/empty_await_for: RuntimeError
+general/error_recovery/empty_for: RuntimeError
+general/error_recovery/issue_38415.crash: RuntimeError
+general/error_recovery/issue_39024.crash: RuntimeError
+general/error_recovery/issue_39026.crash: RuntimeError
+general/error_recovery/issue_39026_prime.crash: RuntimeError
+general/error_recovery/issue_39033.crash: RuntimeError
+general/error_recovery/issue_39058.crash: RuntimeError
+general/error_recovery/issue_39058_prime.crash: RuntimeError
+general/error_recovery/issue_39202.crash: RuntimeError
+general/error_recovery/issue_39230.crash: RuntimeError
+general/error_recovery/issue_39958_01: RuntimeError
+general/error_recovery/issue_39958_02: RuntimeError
+general/error_recovery/issue_39958_03: RuntimeError
+general/error_recovery/issue_39958_04: RuntimeError
+general/error_recovery/yield_not_in_generator: RuntimeError
+general/expressions: RuntimeError
+general/external_import: RuntimeError # The native extension to import doesn't exist. This is ok.
+general/incomplete_field_formal_parameter: RuntimeError
+general/infer_field_from_multiple: TypeCheckError
+general/invalid_operator: TypeCheckError
+general/invocations: RuntimeError
+general/issue37776: RuntimeError
+general/issue38938: RuntimeError # no main and compile time errors.
+general/issue38944: RuntimeError # no main and compile time errors.
+general/issue38961: RuntimeError # no main and compile time errors.
+general/issue41210a: TypeCheckError
+general/issue41210b/issue41210: TypeCheckError
+general/micro: RuntimeError
+general/mixin_application_override: ExpectationFileMismatch # Too many errors.
+general/mixin_application_override: TypeCheckError
+general/mixin_constructors_with_default_values: RuntimeError # Expected
+general/operator_method_not_found: RuntimeError # Expected
+general/optional: TypeCheckError
+general/override_check_accessor_after_inference: TypeCheckError # Issue #31620
+general/override_check_accessor_basic: TypeCheckError # Issue #31620
+general/override_check_accessor_with_covariant_modifier: TypeCheckError # Issue #31620
+general/override_check_after_inference: TypeCheckError # Issue #31620
+general/override_check_basic: TypeCheckError # Issue #31620
+general/override_check_with_covariant_modifier: TypeCheckError # Issue #31620
+general/override_setter_with_field: TypeCheckError
+general/reject_generic_function_types_in_bounds: RuntimeError # Expected
+general/spread_collection: RuntimeError
+general/statements: Crash
+general/type_parameter_type_named_int: RuntimeError # Expected
+general/type_variable_as_super: RuntimeError
+general/type_variable_bound_access: TypeCheckError
+general/unsound_promotion: TypeCheckError
+general/void_methods: RuntimeError
general_nnbd_opt_out/abstract_members: TypeCheckError
general_nnbd_opt_out/accessors: RuntimeError
general_nnbd_opt_out/ambiguous_exports: RuntimeError # Expected, this file exports two main methods.
@@ -60,95 +138,12 @@
general_nnbd_opt_out/type_variable_bound_access: TypeCheckError
general_nnbd_opt_out/unsound_promotion: TypeCheckError
general_nnbd_opt_out/void_methods: RuntimeError
-general/abstract_members: TypeCheckError
-general/accessors: RuntimeError
-general/ambiguous_exports: RuntimeError # Expected, this file exports two main methods.
-general/await_in_non_async: RuntimeError # Expected.
-general/bug21938: TypeCheckError
-general/bug30695: TypeCheckError
-general/bug31124: RuntimeError # Test has no main method (and we shouldn't add one).
-general/call: TypeCheckError
-general/candidate_found: TypeCheckError
-general/cascade: RuntimeError
-general/constructor_initializer_invalid: RuntimeError # Fails execution after recovery
-general/covariant_generic: RuntimeError
-general/duplicated_declarations: TypeCheckError
-general/duplicated_field_initializer: RuntimeError
-general/error_locations/error_location_01: RuntimeError
-general/error_locations/error_location_02: RuntimeError
-general/error_locations/error_location_03: RuntimeError
-general/error_locations/error_location_05: RuntimeError
-general/error_locations/error_location_06: RuntimeError
-general/error_recovery/await_not_in_async: RuntimeError
-general/error_recovery/constructor_recovery_bad_name_general.crash: RuntimeError
-general/error_recovery/constructor_recovery_bad_name_get.crash: RuntimeError
-general/error_recovery/constructor_recovery_bad_name_return_type.crash: RuntimeError
-general/error_recovery/constructor_recovery_bad_name_set.crash: RuntimeError
-general/error_recovery/constructor_recovery_get: RuntimeError
-general/error_recovery/constructor_recovery_ok: RuntimeError
-general/error_recovery/constructor_recovery_operator.crash: RuntimeError
-general/error_recovery/constructor_recovery_return_type: RuntimeError
-general/error_recovery/constructor_recovery_set: RuntimeError
-general/error_recovery/empty_await_for: RuntimeError
-general/error_recovery/empty_for: RuntimeError
-general/error_recovery/issue_38415.crash: RuntimeError
-general/error_recovery/issue_39024.crash: RuntimeError
-general/error_recovery/issue_39026_prime.crash: RuntimeError
-general/error_recovery/issue_39026.crash: RuntimeError
-general/error_recovery/issue_39033.crash: RuntimeError
-general/error_recovery/issue_39058_prime.crash: RuntimeError
-general/error_recovery/issue_39058.crash: RuntimeError
-general/error_recovery/issue_39202.crash: RuntimeError
-general/error_recovery/issue_39230.crash: RuntimeError
-general/error_recovery/issue_39958_01: RuntimeError
-general/error_recovery/issue_39958_02: RuntimeError
-general/error_recovery/issue_39958_03: RuntimeError
-general/error_recovery/issue_39958_04: RuntimeError
-general/error_recovery/yield_not_in_generator: RuntimeError
-general/expressions: RuntimeError
-general/external_import: RuntimeError # The native extension to import doesn't exist. This is ok.
-general/incomplete_field_formal_parameter: RuntimeError
-general/infer_field_from_multiple: TypeCheckError
-general/invalid_operator: TypeCheckError
-general/invocations: RuntimeError
-general/issue37776: RuntimeError
-general/issue38938: RuntimeError # no main and compile time errors.
-general/issue38944: RuntimeError # no main and compile time errors.
-general/issue38961: RuntimeError # no main and compile time errors.
-general/issue41210a: TypeCheckError
-general/issue41210b/issue41210: TypeCheckError
-general/micro: RuntimeError
-general/mixin_application_override: ExpectationFileMismatch # Too many errors.
-general/mixin_application_override: TypeCheckError
-general/mixin_constructors_with_default_values: RuntimeError # Expected
-general/operator_method_not_found: RuntimeError # Expected
-general/optional: TypeCheckError
-general/override_check_accessor_after_inference: TypeCheckError # Issue #31620
-general/override_check_accessor_basic: TypeCheckError # Issue #31620
-general/override_check_accessor_with_covariant_modifier: TypeCheckError # Issue #31620
-general/override_check_after_inference: TypeCheckError # Issue #31620
-general/override_check_basic: TypeCheckError # Issue #31620
-general/override_check_with_covariant_modifier: TypeCheckError # Issue #31620
-general/override_setter_with_field: TypeCheckError
-general/reject_generic_function_types_in_bounds: RuntimeError # Expected
-general/spread_collection: RuntimeError
-general/statements: Crash
-general/type_parameter_type_named_int: RuntimeError # Expected
-general/type_variable_as_super: RuntimeError
-general/type_variable_bound_access: TypeCheckError
-general/unsound_promotion: TypeCheckError
-general/void_methods: RuntimeError
-inference_new/infer_assign_to_index_super_upwards: TypeCheckError
-inference_new/infer_assign_to_index_this_upwards: TypeCheckError
-inference_new/infer_assign_to_index_upwards: TypeCheckError
-inference_new/infer_assign_to_property_custom: TypeCheckError
-inference_new/invalid_assignment_during_toplevel_inference: TypeCheckError
inference/constructors_infer_from_arguments_argument_not_assignable: TypeCheckError
inference/do_not_infer_overridden_fields_that_explicitly_say_dynamic_infer: TypeCheckError
inference/downwards_inference_for_each: RuntimeError # Issue #36382
inference/downwards_inference_on_list_literals_infer_downwards: RuntimeError
-inference/future_then_upwards_2: RuntimeError
inference/future_then_upwards: RuntimeError
+inference/future_then_upwards_2: RuntimeError
inference/generic_methods_correctly_recognize_generic_upper_bound: TypeCheckError
inference/generic_methods_do_not_infer_invalid_override_of_generic_method: TypeCheckError
inference/generic_methods_handle_override_of_non_generic_with_generic: TypeCheckError
@@ -163,6 +158,11 @@
inference/mixin_inference_unification_1: TypeCheckError
inference/mixin_inference_unification_2: TypeCheckError
inference/override_equals: RuntimeError
+inference_new/infer_assign_to_index_super_upwards: TypeCheckError
+inference_new/infer_assign_to_index_this_upwards: TypeCheckError
+inference_new/infer_assign_to_index_upwards: TypeCheckError
+inference_new/infer_assign_to_property_custom: TypeCheckError
+inference_new/invalid_assignment_during_toplevel_inference: TypeCheckError
instantiate_to_bound/non_simple_class_parametrized_typedef_cycle: RuntimeError # Expected
instantiate_to_bound/non_simple_generic_function_in_bound_regress: RuntimeError # Expected
nnbd/inheritance_from_opt_in: TypeCheckError
@@ -170,6 +170,7 @@
nnbd/messages_with_types_opt_in: TypeCheckError
nnbd/messages_with_types_opt_out: TypeCheckError
nnbd/never_opt_out: TypeCheckError
+nnbd/potentially_nullable_access: TypeCheckError
rasta/abstract_constructor: RuntimeError
rasta/bad_constructor_redirection: RuntimeError
rasta/bad_continue: RuntimeError
@@ -205,16 +206,16 @@
rasta/native_is_illegal: RuntimeError
rasta/parser_error: RuntimeError
rasta/static: RuntimeError
+rasta/super: TypeCheckError
rasta/super_initializer: RuntimeError
rasta/super_mixin: TypeCheckError
rasta/super_operator: TypeCheckError
-rasta/super: TypeCheckError
rasta/type_literals: RuntimeError
rasta/typedef: RuntimeError
+rasta/unresolved: RuntimeError
rasta/unresolved_constructor: RuntimeError
rasta/unresolved_for_in: RuntimeError
rasta/unresolved_recovery: TypeCheckError
-rasta/unresolved: RuntimeError
regress/issue_29976: RuntimeError # Tests runtime behavior of error recovery.
regress/issue_29982: RuntimeError # Tests runtime behavior of error recovery.
regress/issue_30836: RuntimeError # Issue 30836.
@@ -229,8 +230,8 @@
regress/issue_35260: RuntimeError # Expected
regress/issue_35266: RuntimeError # Expected
regress/issue_36400: RuntimeError
-regress/issue_36647_2: RuntimeError # Expected
regress/issue_36647: RuntimeError # Expected
+regress/issue_36647_2: RuntimeError # Expected
regress/issue_36669: RuntimeError
regress/issue_37285: RuntimeError
regress/issue_39035.crash: RuntimeError
diff --git a/pkg/front_end/testcases/text_serialization.status b/pkg/front_end/testcases/text_serialization.status
index bf8a83c..ec59b90 100644
--- a/pkg/front_end/testcases/text_serialization.status
+++ b/pkg/front_end/testcases/text_serialization.status
@@ -6,139 +6,29 @@
# the round trip for Kernel textual serialization where the initial binary
# Kernel files are produced by compiling Dart code via Fasta.
-expression/eval: TextSerializationFailure # Was: Pass
-expression/main: TextSerializationFailure # Was: Pass
-extensions/ambiguous: TextSerializationFailure
-extensions/annotations: TextSerializationFailure
extensions/call_methods: TypeCheckError
-extensions/check_bounds: TextSerializationFailure
-extensions/compounds: TextSerializationFailure
-extensions/conflict_with_object: TextSerializationFailure
-extensions/conflicts: TextSerializationFailure
-extensions/default_values: TextSerializationFailure
-extensions/deferred_explicit_access: TextSerializationFailure
-extensions/deferred_import_hidden: TextSerializationFailure
-extensions/direct_instance_access: TextSerializationFailure
-extensions/direct_static_access: TextSerializationFailure
-extensions/dynamic_invoke: TextSerializationFailure
-extensions/explicit_extension_access: TextSerializationFailure
-extensions/explicit_extension_inference: TextSerializationFailure
-extensions/explicit_generic_extension_access: TextSerializationFailure
-extensions/explicit_this: TextSerializationFailure
-extensions/export_twice: TextSerializationFailure
-extensions/extension_call: TextSerializationFailure
-extensions/extension_constructor: TextSerializationFailure
-extensions/extension_field_with_type_parameter_usage: TextSerializationFailure
-extensions/extension_methods: TextSerializationFailure
-extensions/extension_setter: TextSerializationFailure
extensions/extension_setter_error: TypeCheckError
-extensions/generic_function_in_generic_extension: TextSerializationFailure
-extensions/getter_setter_conflict: TextSerializationFailure
-extensions/if_null: TextSerializationFailure
-extensions/implicit_extension_inference: TextSerializationFailure
-extensions/implicit_this: TextSerializationFailure
-extensions/import_via_prefix: TextSerializationFailure
-extensions/index: TextSerializationFailure
-extensions/instance_access: TextSerializationFailure
-extensions/instance_access_of_static: TextSerializationFailure
-extensions/instance_members: TextSerializationFailure
-extensions/instance_tearoff: TextSerializationFailure
-extensions/internal_resolution: TextSerializationFailure
-extensions/invalid_explicit_access: TextSerializationFailure
-extensions/issue38600: TextSerializationFailure
-extensions/issue38745: TextSerializationFailure
-extensions/issue38750: TextSerializationFailure
-extensions/issue38755: TextSerializationFailure
-extensions/issue38915: TextSerializationFailure
-extensions/issue39527: TextSerializationFailure
-extensions/issue39889: TextSerializationFailure
-extensions/issue39938/issue39938: TextSerializationFailure
-extensions/issue40596: TextSerializationFailure
+extensions/instance_access_of_static: RuntimeError
+extensions/invalid_explicit_access: RuntimeError
extensions/issue40713: TypeCheckError
-extensions/issue40816: TextSerializationFailure
-extensions/missing_toplevel: TextSerializationFailure
-extensions/nested_on_types: TextSerializationFailure
-extensions/null_aware: TextSerializationFailure
-extensions/on_function_type: TextSerializationFailure
-extensions/on_type_inference: TextSerializationFailure
-extensions/on_type_variable_inference: TextSerializationFailure
-extensions/operators: TextSerializationFailure
-extensions/other_kinds: TextSerializationFailure
-extensions/private_members: TextSerializationFailure
-extensions/static_access: TextSerializationFailure
-extensions/static_access_of_instance: TextSerializationFailure
-extensions/tear_offs: TextSerializationFailure
-extensions/type_variables: TextSerializationFailure
-extensions/unnamed_extensions: TextSerializationFailure
-extensions/use_this: TextSerializationFailure
-general/DeltaBlue: TextSerializationFailure # Was: Pass
+extensions/static_access_of_instance: RuntimeError
general/abstract_members: TypeCheckError
-general/accessors: TextSerializationFailure # Was: RuntimeError
-general/all_variances: TextSerializationFailure
+general/accessors: RuntimeError
general/ambiguous_exports: RuntimeError
-general/annotation_on_enum_values: TextSerializationFailure # Was: Pass
-general/argument: TextSerializationFailure # Was: Pass
-general/arithmetic: TextSerializationFailure # Was: Pass
-general/arrow_function: TextSerializationFailure # Was: Pass
-general/assign_to_initializing_formal: TextSerializationFailure
-general/async_nested: TextSerializationFailure # Was: Pass
-general/await_complex: TextSerializationFailure
-general/await_in_cascade: TextSerializationFailure
general/await_in_non_async: RuntimeError
-general/await_in_non_async: TextSerializationFailure
-general/bad_setter_abstract: TextSerializationFailure # Was: Pass
-general/bad_store: TextSerializationFailure # Was: Pass
-general/bad_type_variable_uses_in_supertypes: TextSerializationFailure
-general/bounds_check_depends_on_inference: TextSerializationFailure # Was: Pass
general/bug21938: TypeCheckError
general/bug30695: TypeCheckError
general/bug31124: RuntimeError
-general/bug32414a: TextSerializationFailure # Was: Pass
-general/bug32414b: TextSerializationFailure # Was: Pass
-general/bug32426: TextSerializationFailure # Was: Pass
-general/bug32629: TextSerializationFailure
-general/bug32866: TextSerializationFailure # Was: Pass
-general/bug33099: TextSerializationFailure # Was: Pass
-general/bug33196: TextSerializationFailure # Was: Pass
-general/bug33206: TextSerializationFailure # Was: Pass
-general/bug33298: TextSerializationFailure # Was: Pass
-general/bug34511: TextSerializationFailure # Was: Pass
-general/bug35470: TextSerializationFailure # Was: Pass
-general/bug37476: TextSerializationFailure
general/call: TypeCheckError
general/candidate_found: TypeCheckError
-general/cascade: TextSerializationFailure # Was: RuntimeError
-general/check_deferred_as_check: TextSerializationFailure # Was: Pass
-general/check_deferred_is_check: TextSerializationFailure # Was: Pass
-general/circularity-via-initializing-formal: TextSerializationFailure # Was: Pass
-general/classes: TextSerializationFailure # Was: Pass
-general/clone_function_type: TextSerializationFailure # Was: Pass
-general/closure: TextSerializationFailure # Was: Pass
-general/complex_class_hierarchy: TextSerializationFailure
-general/compound_binary_implicit_as: TextSerializationFailure
-general/constant_truncate: TextSerializationFailure
-general/constructor_const_inference: TextSerializationFailure # Was: Pass
-general/constructor_function_types: TextSerializationFailure # Was: Pass
-general/constructor_initializer_invalid: TextSerializationFailure # Was: RuntimeError # Fails execution after recovery
-general/continue_inference_after_error_lib: TextSerializationFailure # Was: Pass
-general/control_flow_collection: TextSerializationFailure
-general/control_flow_collection_inference: TextSerializationFailure
-general/covariant_equals: TextSerializationFailure
-general/covariant_generic: TextSerializationFailure # Was: RuntimeError
-general/covariant_parameter_in_superclass_of_mixin_application: TextSerializationFailure
-general/default_values: TextSerializationFailure # Was: Pass
-general/deferred_lib: TextSerializationFailure # Was: Pass
-general/demote_closure_types: TextSerializationFailure
-general/duplicated_bad_prefix_lib1: TextSerializationFailure # Was: Pass
-general/duplicated_bad_prefix_lib2: TextSerializationFailure # Was: Pass
+general/cascade: RuntimeError
+general/constructor_initializer_invalid: RuntimeError
+general/covariant_generic: RuntimeError
general/duplicated_declarations: TypeCheckError
-general/duplicated_declarations_lib: TextSerializationFailure # Was: Pass
-general/duplicated_declarations_part: TextSerializationFailure # Was: Pass
general/duplicated_field_initializer: RuntimeError
-general/error_locations/error_location_01: TextSerializationFailure
-general/error_locations/error_location_02: TextSerializationFailure
-general/error_locations/error_location_03: TextSerializationFailure
-general/error_locations/error_location_04: TextSerializationFailure
+general/error_locations/error_location_01: RuntimeError
+general/error_locations/error_location_02: RuntimeError
+general/error_locations/error_location_03: RuntimeError
general/error_locations/error_location_05: RuntimeError
general/error_locations/error_location_06: RuntimeError
general/error_recovery/await_not_in_async: RuntimeError
@@ -154,7 +44,6 @@
general/error_recovery/empty_await_for: RuntimeError
general/error_recovery/empty_for: RuntimeError
general/error_recovery/issue_38415.crash: RuntimeError
-general/error_recovery/issue_38415.crash: TextSerializationFailure
general/error_recovery/issue_39024.crash: RuntimeError
general/error_recovery/issue_39026.crash: RuntimeError
general/error_recovery/issue_39026_prime.crash: RuntimeError
@@ -162,918 +51,124 @@
general/error_recovery/issue_39058.crash: RuntimeError
general/error_recovery/issue_39058_prime.crash: RuntimeError
general/error_recovery/issue_39202.crash: RuntimeError
-general/error_recovery/issue_39202.crash: TextSerializationFailure
general/error_recovery/issue_39230.crash: RuntimeError
general/error_recovery/issue_39958_01: RuntimeError
-general/error_recovery/issue_39958_01: TextSerializationFailure
general/error_recovery/issue_39958_02: RuntimeError
-general/error_recovery/issue_39958_02: TextSerializationFailure
general/error_recovery/issue_39958_03: RuntimeError
-general/error_recovery/issue_39958_03: TextSerializationFailure
general/error_recovery/issue_39958_04: RuntimeError
-general/error_recovery/issue_39958_04: TextSerializationFailure
general/error_recovery/yield_not_in_generator: RuntimeError
-general/escape: TextSerializationFailure # Was: Pass
-general/expressions: TextSerializationFailure # Was: RuntimeError
-general/extend_with_type_variable: TextSerializationFailure
-general/external: TextSerializationFailure # Was: Pass
+general/expressions: RuntimeError
general/external_import: RuntimeError
-general/fallthrough: TextSerializationFailure
-general/ffi_sample: TextSerializationFailure
-general/fibonacci: TextSerializationFailure # Was: Pass
-general/for_in_scope: TextSerializationFailure # Was: Pass
-general/for_in_without_declaration: TextSerializationFailure
-general/forwarding_stub_for_operator: TextSerializationFailure
-general/function_in_field: TextSerializationFailure # Was: Pass
-general/function_type_assignments: TextSerializationFailure # Was: Pass
-general/function_type_is_check: TextSerializationFailure # Was: Pass
-general/functions: TextSerializationFailure # Was: Pass
-general/generic_function_type_in_message: TextSerializationFailure
-general/getter_call: TextSerializationFailure
-general/if_null_in_cascade: TextSerializationFailure
-general/if_null_in_list_literal: TextSerializationFailure
-general/if_null_in_set_literal: TextSerializationFailure
-general/illegal_named_function_expression: TextSerializationFailure # Was: Pass
-general/illegal_named_function_expression_scope: TextSerializationFailure # Was: Pass
-general/implicit_new: TextSerializationFailure # Was: Pass
-general/implicit_scope_test: TextSerializationFailure # Was: Pass
general/incomplete_field_formal_parameter: RuntimeError
general/infer_field_from_multiple: TypeCheckError
-general/infer_fixed_generic_return_type: TextSerializationFailure
-general/infer_map_literal_with_closure: TextSerializationFailure
-general/interface_contravariant_from_class: TextSerializationFailure
-general/interface_covariantImpl_from_class: TextSerializationFailure
-general/interface_covariantInterface_from_class: TextSerializationFailure
-general/invalid_assignment: TextSerializationFailure # Was: Pass
-general/invalid_cast: TextSerializationFailure # Was: Pass
general/invalid_operator: TypeCheckError
general/invocations: RuntimeError
-general/issue34899: TextSerializationFailure
-general/issue35875: TextSerializationFailure
-general/issue37027: TextSerializationFailure
-general/issue37381: TextSerializationFailure
general/issue37776: RuntimeError
-general/issue38812: TextSerializationFailure
general/issue38938: RuntimeError
-general/issue38943: TextSerializationFailure
-general/issue38944: TextSerializationFailure
+general/issue38944: RuntimeError
general/issue38961: RuntimeError
-general/issue39344: TextSerializationFailure
-general/issue39817: TextSerializationFailure
-general/issue40242: TextSerializationFailure
-general/issue40428: TextSerializationFailure
-general/issue40662: TextSerializationFailure
-general/issue40744: TextSerializationFailure
-general/issue41070: TextSerializationFailure
general/issue41210a: TypeCheckError
general/issue41210b/issue41210: TypeCheckError
-general/local_generic_function: TextSerializationFailure # Was: Pass
-general/long_chain_of_typedefs: TextSerializationFailure
-general/many_errors: TextSerializationFailure
-general/metadata_enum: TextSerializationFailure # Was: Pass
-general/micro: TextSerializationFailure # Was: RuntimeError
-general/missing_toplevel: TextSerializationFailure
-general/mixin: TextSerializationFailure # Was: Pass
-general/mixin_application_inferred_parameter_type: TextSerializationFailure
-general/mixin_application_override: ExpectationFileMismatch
+general/micro: RuntimeError
general/mixin_application_override: TypeCheckError
-general/mixin_constructors_with_default_values: TextSerializationFailure # Was: Pass
-general/mixin_covariant: TextSerializationFailure
-general/mixin_inherited_setter_for_mixed_in_field: TextSerializationFailure # Was: Pass
-general/mixin_super_repeated: TextSerializationFailure # Was: Pass
-general/named_function_scope: TextSerializationFailure # Was: Pass
-general/named_parameters: TextSerializationFailure # Was: Pass
-general/native_as_name: TextSerializationFailure # Was: Pass
-general/nested_implicit_const_with_env_var: TextSerializationFailure # Was: Pass
-general/nested_property_set: TextSerializationFailure
-general/nested_variable_set: TextSerializationFailure
-general/nested_variance: TextSerializationFailure
-general/no_such_method_private_setter: TextSerializationFailure # Was: Pass
-general/no_such_method_private_setter_lib: TextSerializationFailure # Was: Pass
-general/non_covariant_checks: TextSerializationFailure
-general/null_aware: TextSerializationFailure # Was: Pass
-general/null_aware_for_in: TextSerializationFailure
-general/null_aware_postfix: TextSerializationFailure
-general/null_aware_spread: TextSerializationFailure
-general/operator_method_not_found: TextSerializationFailure
-general/operators: TextSerializationFailure # Was: Pass
+general/mixin_constructors_with_default_values: RuntimeError
+general/operator_method_not_found: RuntimeError
general/optional: TypeCheckError
-general/override: TextSerializationFailure # Was: Pass
general/override_check_accessor_after_inference: TypeCheckError # Issue #31620
general/override_check_accessor_basic: TypeCheckError # Issue #31620
general/override_check_accessor_with_covariant_modifier: TypeCheckError # Issue #31620
general/override_check_after_inference: TypeCheckError # Issue #31620
general/override_check_basic: TypeCheckError # Issue #31620
-general/override_check_generic_method_f_bounded: TextSerializationFailure # Was: Pass
-general/override_check_two_substitutions: TextSerializationFailure # Was: Pass
general/override_check_with_covariant_modifier: TypeCheckError # Issue #31620
general/override_setter_with_field: TypeCheckError
-general/part_as_entry_point_lib: TextSerializationFailure # Was: Pass
-general/private_method_tearoff: TextSerializationFailure # Was: Pass
-general/private_method_tearoff_lib: TextSerializationFailure # Was: Pass
-general/promoted_access: TextSerializationFailure
-general/promoted_null_aware_access: TextSerializationFailure
-general/public_method_tearoff: TextSerializationFailure # Was: Pass
-general/public_method_tearoff_lib: TextSerializationFailure # Was: Pass
-general/qualified: TextSerializationFailure # Was: Pass
-general/qualified_lib: TextSerializationFailure # Was: Pass
-general/qualified_part: TextSerializationFailure # Was: Pass
-general/redirecting_factory: TextSerializationFailure # Was: Pass
-general/redirecting_factory_const_inference: TextSerializationFailure # Was: Pass
-general/redirecting_factory_typeargs_test: TextSerializationFailure # Was: Pass
-general/redirecting_factory_typeparam_test: TextSerializationFailure # Was: Pass
-general/redirecting_factory_typeparambounds_test: TextSerializationFailure # Was: Pass
-general/redirecting_initializer_arguments_assignable_test: TextSerializationFailure # Was: Pass
-general/redirecting_initializer_arguments_test: TextSerializationFailure # Was: Pass
-general/redirection_chain_type_arguments: TextSerializationFailure # Was: Pass
-general/redirection_chain_type_arguments_subst: TextSerializationFailure # Was: Pass
-general/redirection_type_arguments: TextSerializationFailure # Was: Pass
-general/reject_generic_function_types_in_bounds: TextSerializationFailure # Was: RuntimeError # Expected
-general/return_with_unknown_type_in_context: TextSerializationFailure # Was: Pass
-general/spread_collection: TextSerializationFailure # Should be fixed as part of implementing spread collection support
-general/spread_collection_inference: TextSerializationFailure # Should be fixed as part of implementing spread collection support
+general/reject_generic_function_types_in_bounds: RuntimeError
+general/spread_collection: RuntimeError # Should be fixed as part of implementing spread collection support
general/statements: Crash
-general/store_load: TextSerializationFailure # Was: Pass
-general/super_call: TextSerializationFailure # Was: Pass
-general/super_nsm: TextSerializationFailure # Was: Pass
-general/this_field_call: TextSerializationFailure
-general/three_typedefs_loop: TextSerializationFailure
-general/top_level_accessors: TextSerializationFailure # Was: Pass
-general/top_level_accessors_part: TextSerializationFailure # Was: Pass
-general/type_of_null: TextSerializationFailure
-general/type_parameter_type_named_int: TextSerializationFailure
-general/type_parameter_usage_in_static_method_in_class: TextSerializationFailure
-general/type_parameter_usage_in_static_method_in_extension: TextSerializationFailure
-general/type_variable_as_super: TextSerializationFailure # Was: RuntimeError
+general/type_parameter_type_named_int: RuntimeError
+general/type_variable_as_super: RuntimeError
general/type_variable_bound_access: TypeCheckError
-general/type_variable_prefix: TextSerializationFailure # Was: RuntimeError
-general/type_variable_uses: TextSerializationFailure # Was: Pass
-general/undefined: TextSerializationFailure # Was: Pass
-general/undefined_getter_in_compound_assignment: TextSerializationFailure # Was: Pass
-general/uninitialized_fields: TextSerializationFailure # Was: Pass
general/unsound_promotion: TypeCheckError
-general/unused_methods: TextSerializationFailure # Was: Pass
-general/var_as_type_name: TextSerializationFailure # Was: Pass
-general/vm_type_ops: TextSerializationFailure
-general/void_methods: TextSerializationFailure
-general/well_boundness_checks_in_outline: TextSerializationFailure
-general/with_dependencies/extension_from_dill/extension_from_dill: TextSerializationFailure
-general/with_dependencies/variance_from_dill/variance_from_dill: TextSerializationFailure
-general_nnbd_opt_out/DeltaBlue: TextSerializationFailure # Was: Pass
+general/void_methods: RuntimeError
general_nnbd_opt_out/abstract_members: TypeCheckError
-general_nnbd_opt_out/accessors: TextSerializationFailure # Was: RuntimeError
-general_nnbd_opt_out/all_variances: TextSerializationFailure
+general_nnbd_opt_out/accessors: RuntimeError
general_nnbd_opt_out/ambiguous_exports: RuntimeError
-general_nnbd_opt_out/annotation_on_enum_values: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/argument: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/arithmetic: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/arrow_function: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/assign_to_initializing_formal: TextSerializationFailure
-general_nnbd_opt_out/async_nested: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/await_complex: TextSerializationFailure
-general_nnbd_opt_out/await_in_cascade: TextSerializationFailure
general_nnbd_opt_out/await_in_non_async: RuntimeError
-general_nnbd_opt_out/await_in_non_async: TextSerializationFailure
-general_nnbd_opt_out/bad_setter_abstract: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/bad_store: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/bad_type_variable_uses_in_supertypes: TextSerializationFailure
-general_nnbd_opt_out/bounds_check_depends_on_inference: TextSerializationFailure # Was: Pass
general_nnbd_opt_out/bug21938: TypeCheckError
general_nnbd_opt_out/bug30695: TypeCheckError
general_nnbd_opt_out/bug31124: RuntimeError
-general_nnbd_opt_out/bug32414a: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/bug32414b: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/bug32426: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/bug32629: TextSerializationFailure
-general_nnbd_opt_out/bug32866: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/bug33099: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/bug33196: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/bug33206: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/bug33298: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/bug34511: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/bug35470: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/bug37476: TextSerializationFailure
general_nnbd_opt_out/call: TypeCheckError
general_nnbd_opt_out/candidate_found: TypeCheckError
-general_nnbd_opt_out/cascade: TextSerializationFailure # Was: RuntimeError
-general_nnbd_opt_out/check_deferred_as_check: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/check_deferred_is_check: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/circularity-via-initializing-formal: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/classes: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/clone_function_type: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/closure: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/complex_class_hierarchy: TextSerializationFailure
-general_nnbd_opt_out/compound_binary_implicit_as: TextSerializationFailure
-general_nnbd_opt_out/constructor_const_inference: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/constructor_function_types: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/constructor_initializer_invalid: TextSerializationFailure # Was: RuntimeError # Fails execution after recovery
-general_nnbd_opt_out/continue_inference_after_error_lib: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/control_flow_collection: TextSerializationFailure
-general_nnbd_opt_out/control_flow_collection_inference: TextSerializationFailure
-general_nnbd_opt_out/covariant_equals: TextSerializationFailure
-general_nnbd_opt_out/covariant_generic: TextSerializationFailure # Was: RuntimeError
-general_nnbd_opt_out/covariant_parameter_in_superclass_of_mixin_application: TextSerializationFailure
-general_nnbd_opt_out/default_values: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/deferred_lib: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/duplicated_bad_prefix_lib1: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/duplicated_bad_prefix_lib2: TextSerializationFailure # Was: Pass
+general_nnbd_opt_out/cascade: RuntimeError
+general_nnbd_opt_out/constructor_initializer_invalid: RuntimeError
+general_nnbd_opt_out/covariant_generic: RuntimeError
general_nnbd_opt_out/duplicated_declarations: TypeCheckError
-general_nnbd_opt_out/duplicated_declarations_lib: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/duplicated_declarations_part: TextSerializationFailure # Was: Pass
general_nnbd_opt_out/duplicated_field_initializer: RuntimeError
-general_nnbd_opt_out/error_locations/error_location_01: TextSerializationFailure
-general_nnbd_opt_out/error_locations/error_location_02: TextSerializationFailure
-general_nnbd_opt_out/error_locations/error_location_03: TextSerializationFailure
-general_nnbd_opt_out/error_locations/error_location_04: TextSerializationFailure
+general_nnbd_opt_out/error_locations/error_location_01: RuntimeError
+general_nnbd_opt_out/error_locations/error_location_02: RuntimeError
+general_nnbd_opt_out/error_locations/error_location_03: RuntimeError
general_nnbd_opt_out/error_locations/error_location_05: RuntimeError
general_nnbd_opt_out/error_locations/error_location_06: RuntimeError
-general_nnbd_opt_out/escape: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/expressions: TextSerializationFailure # Was: RuntimeError
-general_nnbd_opt_out/extend_with_type_variable: TextSerializationFailure
-general_nnbd_opt_out/external: TextSerializationFailure # Was: Pass
+general_nnbd_opt_out/expressions: RuntimeError
general_nnbd_opt_out/external_import: RuntimeError
-general_nnbd_opt_out/fallthrough: TextSerializationFailure
-general_nnbd_opt_out/ffi_sample: TextSerializationFailure
-general_nnbd_opt_out/fibonacci: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/for_in_scope: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/for_in_without_declaration: TextSerializationFailure
-general_nnbd_opt_out/forwarding_stub_for_operator: TextSerializationFailure
-general_nnbd_opt_out/function_in_field: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/function_type_assignments: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/function_type_is_check: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/functions: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/generic_function_type_in_message: TextSerializationFailure
-general_nnbd_opt_out/if_null_in_cascade: TextSerializationFailure
-general_nnbd_opt_out/if_null_in_list_literal: TextSerializationFailure
-general_nnbd_opt_out/if_null_in_set_literal: TextSerializationFailure
-general_nnbd_opt_out/illegal_named_function_expression: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/illegal_named_function_expression_scope: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/implicit_new: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/implicit_scope_test: TextSerializationFailure # Was: Pass
general_nnbd_opt_out/incomplete_field_formal_parameter: RuntimeError
-general_nnbd_opt_out/interface_contravariant_from_class: TextSerializationFailure
-general_nnbd_opt_out/interface_covariantImpl_from_class: TextSerializationFailure
-general_nnbd_opt_out/interface_covariantInterface_from_class: TextSerializationFailure
-general_nnbd_opt_out/invalid_assignment: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/invalid_cast: TextSerializationFailure # Was: Pass
general_nnbd_opt_out/invocations: RuntimeError
-general_nnbd_opt_out/issue34899: TextSerializationFailure
-general_nnbd_opt_out/issue35875: TextSerializationFailure
-general_nnbd_opt_out/issue37027: TextSerializationFailure
-general_nnbd_opt_out/issue37381: TextSerializationFailure
general_nnbd_opt_out/issue37776: RuntimeError
-general_nnbd_opt_out/issue38812: TextSerializationFailure
general_nnbd_opt_out/issue38938: RuntimeError
-general_nnbd_opt_out/issue38943: TextSerializationFailure
-general_nnbd_opt_out/issue38944: TextSerializationFailure
+general_nnbd_opt_out/issue38944: RuntimeError
general_nnbd_opt_out/issue38961: RuntimeError
-general_nnbd_opt_out/issue39344: TextSerializationFailure
-general_nnbd_opt_out/issue39817: TextSerializationFailure
-general_nnbd_opt_out/local_generic_function: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/long_chain_of_typedefs: TextSerializationFailure
-general_nnbd_opt_out/many_errors: TextSerializationFailure
-general_nnbd_opt_out/metadata_enum: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/micro: TextSerializationFailure # Was: RuntimeError
-general_nnbd_opt_out/missing_toplevel: TextSerializationFailure
-general_nnbd_opt_out/mixin: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/mixin_application_inferred_parameter_type: TextSerializationFailure
-general_nnbd_opt_out/mixin_application_override: ExpectationFileMismatch
+general_nnbd_opt_out/micro: RuntimeError
general_nnbd_opt_out/mixin_application_override: TypeCheckError
-general_nnbd_opt_out/mixin_constructors_with_default_values: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/mixin_inherited_setter_for_mixed_in_field: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/mixin_super_repeated: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/named_function_scope: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/named_parameters: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/native_as_name: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/nested_implicit_const_with_env_var: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/nested_property_set: TextSerializationFailure
-general_nnbd_opt_out/nested_variable_set: TextSerializationFailure
-general_nnbd_opt_out/nested_variance: TextSerializationFailure
-general_nnbd_opt_out/no_such_method_private_setter: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/no_such_method_private_setter_lib: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/non_covariant_checks: TextSerializationFailure
-general_nnbd_opt_out/null_aware: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/null_aware_for_in: TextSerializationFailure
-general_nnbd_opt_out/null_aware_postfix: TextSerializationFailure
-general_nnbd_opt_out/null_aware_spread: TextSerializationFailure
-general_nnbd_opt_out/operator_method_not_found: TextSerializationFailure
-general_nnbd_opt_out/operators: TextSerializationFailure # Was: Pass
+general_nnbd_opt_out/mixin_constructors_with_default_values: RuntimeError
+general_nnbd_opt_out/operator_method_not_found: RuntimeError
general_nnbd_opt_out/optional: TypeCheckError
-general_nnbd_opt_out/override: TextSerializationFailure # Was: Pass
general_nnbd_opt_out/override_check_accessor_after_inference: TypeCheckError # Issue #31620
general_nnbd_opt_out/override_check_accessor_basic: TypeCheckError # Issue #31620
general_nnbd_opt_out/override_check_accessor_with_covariant_modifier: TypeCheckError # Issue #31620
general_nnbd_opt_out/override_check_after_inference: TypeCheckError # Issue #31620
general_nnbd_opt_out/override_check_basic: TypeCheckError # Issue #31620
-general_nnbd_opt_out/override_check_generic_method_f_bounded: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/override_check_two_substitutions: TextSerializationFailure # Was: Pass
general_nnbd_opt_out/override_check_with_covariant_modifier: TypeCheckError # Issue #31620
general_nnbd_opt_out/override_setter_with_field: TypeCheckError
-general_nnbd_opt_out/part_as_entry_point_lib: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/private_method_tearoff: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/private_method_tearoff_lib: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/promoted_access: TextSerializationFailure
-general_nnbd_opt_out/public_method_tearoff: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/public_method_tearoff_lib: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/qualified: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/qualified_lib: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/qualified_part: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/redirecting_factory: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/redirecting_factory_const_inference: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/redirecting_factory_typeargs_test: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/redirecting_factory_typeparam_test: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/redirecting_factory_typeparambounds_test: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/redirecting_initializer_arguments_assignable_test: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/redirecting_initializer_arguments_test: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/redirection_chain_type_arguments: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/redirection_chain_type_arguments_subst: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/redirection_type_arguments: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/reject_generic_function_types_in_bounds: TextSerializationFailure # Was: RuntimeError # Expected
-general_nnbd_opt_out/return_with_unknown_type_in_context: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/spread_collection: TextSerializationFailure # Should be fixed as part of implementing spread collection support
-general_nnbd_opt_out/spread_collection_inference: TextSerializationFailure # Should be fixed as part of implementing spread collection support
+general_nnbd_opt_out/reject_generic_function_types_in_bounds: RuntimeError
+general_nnbd_opt_out/spread_collection: RuntimeError # Should be fixed as part of implementing spread collection support
general_nnbd_opt_out/statements: Crash
-general_nnbd_opt_out/store_load: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/super_call: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/super_nsm: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/three_typedefs_loop: TextSerializationFailure
-general_nnbd_opt_out/top_level_accessors: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/top_level_accessors_part: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/type_of_null: TextSerializationFailure
-general_nnbd_opt_out/type_parameter_type_named_int: TextSerializationFailure
-general_nnbd_opt_out/type_variable_as_super: TextSerializationFailure # Was: RuntimeError
+general_nnbd_opt_out/type_parameter_type_named_int: RuntimeError
+general_nnbd_opt_out/type_variable_as_super: RuntimeError
general_nnbd_opt_out/type_variable_bound_access: TypeCheckError
-general_nnbd_opt_out/type_variable_prefix: TextSerializationFailure # Was: RuntimeError
-general_nnbd_opt_out/type_variable_uses: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/undefined: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/undefined_getter_in_compound_assignment: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/uninitialized_fields: TextSerializationFailure # Was: Pass
general_nnbd_opt_out/unsound_promotion: TypeCheckError
-general_nnbd_opt_out/unused_methods: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/var_as_type_name: TextSerializationFailure # Was: Pass
-general_nnbd_opt_out/void_methods: TextSerializationFailure
-implicit_getter_calls/getter_call: TextSerializationFailure
-implicit_getter_calls/this_field_call: TextSerializationFailure
-inference/abstract_class_instantiation: TextSerializationFailure
-inference/assert: TextSerializationFailure # Was: Pass
-inference/assert_initializer: TextSerializationFailure # Was: Pass
-inference/assign_local: TextSerializationFailure # Was: Pass
-inference/async_await: TextSerializationFailure # Was: Pass
-inference/block_bodied_lambdas_async_all_returns_are_futures: TextSerializationFailure # Was: Pass
-inference/block_bodied_lambdas_async_all_returns_are_values: TextSerializationFailure # Was: Pass
-inference/block_bodied_lambdas_async_mix_of_values_and_futures: TextSerializationFailure # Was: Pass
-inference/block_bodied_lambdas_async_star: TextSerializationFailure # Was: Pass
-inference/block_bodied_lambdas_basic: TextSerializationFailure # Was: Pass
-inference/block_bodied_lambdas_basic_void: TextSerializationFailure # Was: Pass
-inference/block_bodied_lambdas_downwards_incompatible_with_upwards_inference: TextSerializationFailure # Was: Pass
-inference/block_bodied_lambdas_infer_bottom_async: TextSerializationFailure # Was: Pass
-inference/block_bodied_lambdas_infer_bottom_async_star: TextSerializationFailure # Was: Pass
-inference/block_bodied_lambdas_infer_bottom_sync: TextSerializationFailure # Was: Pass
-inference/block_bodied_lambdas_infer_bottom_sync_star: TextSerializationFailure # Was: Pass
-inference/block_bodied_lambdas_lub: TextSerializationFailure # Was: Pass
-inference/block_bodied_lambdas_nested_lambdas: TextSerializationFailure # Was: Pass
-inference/block_bodied_lambdas_no_return: TextSerializationFailure # Was: Pass
-inference/block_bodied_lambdas_returns: TextSerializationFailure # Was: Pass
-inference/block_bodied_lambdas_sync_star: TextSerializationFailure # Was: Pass
-inference/block_bodied_lambdas_void_context: TextSerializationFailure # Was: Pass
-inference/bug30251: TextSerializationFailure # Was: Pass
-inference/bug30620: TextSerializationFailure # Was: Pass
-inference/bug30620_b: TextSerializationFailure # Was: Pass
-inference/bug30620_c: TextSerializationFailure # Was: Pass
-inference/bug30620_d: TextSerializationFailure # Was: Pass
-inference/bug30624: TextSerializationFailure # Was: Pass
-inference/bug31132: TextSerializationFailure # Was: Pass
-inference/bug31133: TextSerializationFailure # Was: Pass
-inference/bug31436: TextSerializationFailure # Was: Pass
-inference/bug32291: TextSerializationFailure # Was: Pass
-inference/bug33324: TextSerializationFailure # Was: Pass
-inference/callable_generic_class: TextSerializationFailure # Was: Pass
-inference/complex_predecrement: TextSerializationFailure # Was: Pass
-inference/conditional_upwards_inference: TextSerializationFailure # Was: Pass
-inference/constructors_downwards_with_constraint: TextSerializationFailure # Was: Pass
-inference/constructors_infer_from_arguments: TextSerializationFailure # Was: Pass
+general_nnbd_opt_out/void_methods: RuntimeError
inference/constructors_infer_from_arguments_argument_not_assignable: TypeCheckError
-inference/constructors_infer_from_arguments_const: TextSerializationFailure # Was: Pass
-inference/constructors_infer_from_arguments_const_with_upper_bound: TextSerializationFailure # Was: Pass
-inference/constructors_infer_from_arguments_downwards_from_constructor: TextSerializationFailure
-inference/constructors_infer_from_arguments_factory: TextSerializationFailure # Was: Pass
-inference/constructors_infer_from_arguments_factory_calls_constructor: TextSerializationFailure # Was: Pass
-inference/constructors_infer_from_arguments_named: TextSerializationFailure # Was: Pass
-inference/constructors_infer_from_arguments_named_factory: TextSerializationFailure # Was: Pass
-inference/constructors_infer_from_arguments_redirecting: TextSerializationFailure # Was: Pass
-inference/constructors_infer_from_arguments_redirecting_factory: TextSerializationFailure # Was: Pass
-inference/constructors_infer_from_arguments_redirecting_factory_to_factory: TextSerializationFailure # Was: Pass
-inference/constructors_inference_f_bounded: TextSerializationFailure # Was: Pass
-inference/constructors_reverse_type_parameters: TextSerializationFailure # Was: Pass
-inference/constructors_too_many_positional_arguments: TextSerializationFailure
inference/do_not_infer_overridden_fields_that_explicitly_say_dynamic_infer: TypeCheckError
-inference/dont_infer_type_on_dynamic: TextSerializationFailure # Was: Pass
-inference/dont_infer_type_when_initializer_is_null: TextSerializationFailure # Was: Pass
-inference/downward_inference_fixes_no_upwards_errors: TextSerializationFailure # Was: Pass
-inference/downward_inference_miscellaneous: TextSerializationFailure # Was: Pass
-inference/downwards_inference_annotations_for_loop_variable: TextSerializationFailure # Was: Pass
-inference/downwards_inference_annotations_type_variable: TextSerializationFailure
-inference/downwards_inference_async_await: TextSerializationFailure # Was: Pass
-inference/downwards_inference_for_each: TextSerializationFailure # Was: Pass
-inference/downwards_inference_initializing_formal_default_formal: TextSerializationFailure # Was: Pass
-inference/downwards_inference_inside_top_level: TextSerializationFailure # Was: Pass
-inference/downwards_inference_inside_top_level_2: TextSerializationFailure # Was: Pass
-inference/downwards_inference_on_function_expressions: TextSerializationFailure # Was: Pass
-inference/downwards_inference_on_function_of_t_using_the_t: TextSerializationFailure
-inference/downwards_inference_on_generic_constructor_arguments_empty_list: TextSerializationFailure # Was: Pass
-inference/downwards_inference_on_generic_constructor_arguments_infer_downwards: TextSerializationFailure # Was: Pass
-inference/downwards_inference_on_generic_function_expressions: TextSerializationFailure # Was: Pass
-inference/downwards_inference_on_instance_creations_infer_downwards: TextSerializationFailure # Was: Pass
+inference/downwards_inference_for_each: RuntimeError
inference/downwards_inference_on_list_literals_infer_downwards: RuntimeError
-inference/downwards_inference_on_list_literals_infer_if_value_types_match_context: TextSerializationFailure # Was: Pass
-inference/downwards_inference_yield_yield_star: TextSerializationFailure # Was: Pass
-inference/dynamic_methods: TextSerializationFailure # Was: Pass
-inference/field_initializer_context_explicit: TextSerializationFailure # Was: Pass
-inference/field_initializer_context_implicit: TextSerializationFailure # Was: Pass
-inference/field_initializer_context_this: TextSerializationFailure # Was: Pass
-inference/field_initializer_parameter: TextSerializationFailure # Was: Pass
-inference/for_each_downcast_iterable: TextSerializationFailure # Was: Pass
-inference/for_in_loop_promotion: TextSerializationFailure # Was: Pass
-inference/for_loop_empty_condition: TextSerializationFailure # Was: Pass
-inference/for_loop_initializer_expression: TextSerializationFailure # Was: Pass
-inference/for_loop_promotion: TextSerializationFailure # Was: Pass
-inference/future_or_subtyping: TextSerializationFailure # Was: Pass
-inference/future_then: TextSerializationFailure # Was: Pass
-inference/future_then_2: TextSerializationFailure # Was: Pass
-inference/future_then_3: TextSerializationFailure # Was: Pass
-inference/future_then_4: TextSerializationFailure # Was: Pass
-inference/future_then_5: TextSerializationFailure # Was: Pass
-inference/future_then_6: TextSerializationFailure # Was: Pass
-inference/future_then_conditional: TextSerializationFailure # Was: Pass
-inference/future_then_conditional_2: TextSerializationFailure # Was: Pass
-inference/future_then_conditional_3: TextSerializationFailure # Was: Pass
-inference/future_then_conditional_4: TextSerializationFailure # Was: Pass
-inference/future_then_conditional_5: TextSerializationFailure # Was: Pass
-inference/future_then_conditional_6: TextSerializationFailure # Was: Pass
-inference/future_then_downwards_method_target: TextSerializationFailure # Was: Pass
-inference/future_then_explicit_future: TextSerializationFailure
-inference/future_then_ifNull: TextSerializationFailure # Was: Pass
-inference/future_then_upwards: TextSerializationFailure # Was: RuntimeError
-inference/future_then_upwards_2: TextSerializationFailure # Was: RuntimeError
-inference/future_then_upwards_3: TextSerializationFailure # Was: Pass
-inference/future_then_upwards_from_block: TextSerializationFailure # Was: Pass
-inference/future_union_async_conditional: TextSerializationFailure # Was: Pass
-inference/future_union_async_conditional_2: TextSerializationFailure # Was: Pass
-inference/future_union_downwards: TextSerializationFailure # Was: Pass
-inference/future_union_downwards_2: TextSerializationFailure # Was: Pass
-inference/future_union_downwards_3: TextSerializationFailure # Was: Pass
-inference/future_union_downwards_4: TextSerializationFailure # Was: Pass
-inference/future_union_downwards_generic_method_with_future_return: TextSerializationFailure # Was: Pass
-inference/future_union_downwards_generic_method_with_generic_return: TextSerializationFailure # Was: Pass
-inference/future_union_upwards_generic_methods: TextSerializationFailure # Was: Pass
-inference/generic_functions_return_typedef: TextSerializationFailure
-inference/generic_methods_basic_downward_inference: TextSerializationFailure # Was: Pass
+inference/future_then_upwards: RuntimeError
+inference/future_then_upwards_2: RuntimeError
inference/generic_methods_correctly_recognize_generic_upper_bound: TypeCheckError
-inference/generic_methods_dart_math_min_max: TextSerializationFailure # Was: Pass
inference/generic_methods_do_not_infer_invalid_override_of_generic_method: TypeCheckError
-inference/generic_methods_downwards_inference_affects_arguments: TextSerializationFailure # Was: Pass
-inference/generic_methods_downwards_inference_fold: TextSerializationFailure # Was: Pass
inference/generic_methods_handle_override_of_non_generic_with_generic: TypeCheckError
-inference/generic_methods_infer_generic_function_parameter_type2: TextSerializationFailure # Was: Pass
-inference/generic_methods_infer_generic_function_parameter_type: TextSerializationFailure # Was: Pass
-inference/generic_methods_infer_generic_function_return_type: TextSerializationFailure # Was: Pass
-inference/generic_methods_infer_generic_instantiation: TextSerializationFailure # Was: Pass
-inference/generic_methods_infer_generic_method_type: TextSerializationFailure # Was: Pass
-inference/generic_methods_infer_js_builtin: TextSerializationFailure
-inference/generic_methods_inference_error: TextSerializationFailure # Was: Pass
-inference/generic_methods_iterable_and_future: TextSerializationFailure # Was: Pass
-inference/generic_methods_nested_generic_instantiation: TextSerializationFailure # Was: Pass
-inference/generic_methods_uses_greatest_lower_bound: TextSerializationFailure # Was: Pass
-inference/greatest_closure_multiple_params: TextSerializationFailure # Was: Pass
-inference/infer_assign_to_implicit_this: TextSerializationFailure # Was: Pass
-inference/infer_assign_to_implicit_this_upwards: TextSerializationFailure # Was: Pass
-inference/infer_assign_to_index_full: TextSerializationFailure # Was: Pass
-inference/infer_assign_to_index_super: TextSerializationFailure # Was: Pass
-inference/infer_assign_to_index_this: TextSerializationFailure # Was: Pass
-inference/infer_assign_to_local: TextSerializationFailure # Was: Pass
-inference/infer_assign_to_local_upwards: TextSerializationFailure # Was: Pass
-inference/infer_assign_to_property_full: TextSerializationFailure # Was: Pass
-inference/infer_assign_to_property_null_aware: TextSerializationFailure # Was: Pass
-inference/infer_assign_to_property_null_aware_upwards: TextSerializationFailure # Was: Pass
-inference/infer_assign_to_property_super: TextSerializationFailure # Was: Pass
-inference/infer_assign_to_property_super_upwards: TextSerializationFailure # Was: Pass
-inference/infer_assign_to_property_upwards: TextSerializationFailure # Was: Pass
-inference/infer_assign_to_static: TextSerializationFailure # Was: Pass
-inference/infer_assign_to_static_upwards: TextSerializationFailure # Was: Pass
-inference/infer_field_override_with_substitution: TextSerializationFailure # Was: Pass
-inference/infer_final_field_getter_and_setter: TextSerializationFailure # Was: Pass
-inference/infer_final_field_getter_only: TextSerializationFailure # Was: Pass
-inference/infer_final_field_setter_only: TextSerializationFailure # Was: Pass
-inference/infer_from_complex_expressions_if_outer_most_value_is_precise: TextSerializationFailure
-inference/infer_from_variables_in_cycle_libs_when_flag_is_on2: TextSerializationFailure # Was: Pass
-inference/infer_from_variables_in_cycle_libs_when_flag_is_on2_a: TextSerializationFailure # Was: Pass
-inference/infer_from_variables_in_cycle_libs_when_flag_is_on: TextSerializationFailure # Was: Pass
-inference/infer_from_variables_in_cycle_libs_when_flag_is_on_a: TextSerializationFailure # Was: Pass
-inference/infer_generic_field_types: TextSerializationFailure
-inference/infer_generic_method_type_named: TextSerializationFailure # Was: Pass
-inference/infer_generic_method_type_positional2: TextSerializationFailure # Was: Pass
-inference/infer_generic_method_type_positional: TextSerializationFailure # Was: Pass
-inference/infer_generic_method_type_required: TextSerializationFailure # Was: Pass
-inference/infer_list_literal_nested_in_map_literal: TextSerializationFailure # Was: Pass
-inference/infer_local_function_referenced_before_declaration: TextSerializationFailure # Was: Pass
-inference/infer_local_function_return_type: TextSerializationFailure # Was: Pass
-inference/infer_method_function_typed: TextSerializationFailure # Was: Pass
-inference/infer_method_missing_params: ExpectationFileMismatch
inference/infer_method_missing_params: TypeCheckError
-inference/infer_rethrow: TextSerializationFailure # Was: Pass
-inference/infer_return_of_statement_lambda: TextSerializationFailure # Was: Pass
-inference/infer_setter_function_typed: TextSerializationFailure # Was: Pass
-inference/infer_statics_transitively2: TextSerializationFailure # Was: Pass
-inference/infer_statics_transitively: TextSerializationFailure # Was: Pass
-inference/infer_statics_transitively_2_a: TextSerializationFailure # Was: Pass
-inference/infer_statics_transitively_a: TextSerializationFailure # Was: Pass
-inference/infer_throw_downwards: TextSerializationFailure # Was: Pass
-inference/infer_type_on_var_from_field: TextSerializationFailure # Was: Pass
-inference/infer_type_on_var_from_top_level: TextSerializationFailure # Was: Pass
inference/infer_type_regardless_of_declaration_order_or_cycles: RuntimeError
-inference/infer_types_on_generic_instantiations_3: TextSerializationFailure # Was: Pass
-inference/infer_types_on_generic_instantiations_4: TextSerializationFailure # Was: RuntimeError
-inference/infer_types_on_generic_instantiations_5: TextSerializationFailure # Was: Pass
-inference/infer_types_on_generic_instantiations_in_library_cycle: TextSerializationFailure # Was: Pass
-inference/infer_types_on_generic_instantiations_in_library_cycle_a: TextSerializationFailure # Was: Pass
+inference/infer_types_on_generic_instantiations_4: RuntimeError
inference/infer_types_on_generic_instantiations_infer: TypeCheckError
-inference/infer_types_on_loop_indices_for_each_loop: TextSerializationFailure # Was: Pass
-inference/infer_types_on_loop_indices_for_each_loop_async: TextSerializationFailure # Was: Pass
-inference/infer_types_on_loop_indices_for_loop_with_inference: TextSerializationFailure # Was: Pass
-inference/inferred_initializing_formal_checks_default_value: TextSerializationFailure # Was: Pass
-inference/inferred_type_cascade: TextSerializationFailure # Was: Pass
-inference/inferred_type_custom_index_op: TextSerializationFailure # Was: Pass
-inference/inferred_type_custom_index_op_via_interface: TextSerializationFailure # Was: Pass
-inference/inferred_type_is_enum: TextSerializationFailure # Was: Pass
-inference/inferred_type_is_enum_values: TextSerializationFailure # Was: Pass
-inference/inferred_type_is_typedef_parameterized: TextSerializationFailure # Was: Pass
-inference/inferred_type_via_closure_multiple_levels_of_nesting: TextSerializationFailure # Was: Pass
-inference/inferred_type_via_closure_type_depends_on_args: TextSerializationFailure # Was: Pass
-inference/instance_creation_downwards: TextSerializationFailure # Was: Pass
-inference/instantiate_tearoff: TextSerializationFailure # Was: Pass
-inference/instantiate_tearoff_after_contravariance_check: TextSerializationFailure # Was: Pass
inference/instantiate_tearoff_of_call: TypeCheckError # Issue #31746
-inference/instantiate_to_bounds_generic2_has_bound_defined_after: TextSerializationFailure # Was: Pass
-inference/instantiate_to_bounds_generic2_has_bound_defined_before: TextSerializationFailure # Was: Pass
-inference/instantiate_to_bounds_generic2_no_bound: TextSerializationFailure # Was: Pass
inference/instantiate_to_bounds_generic_has_bound_defined_after transform: RuntimeError
-inference/instantiate_to_bounds_generic_has_bound_defined_after: TextSerializationFailure # Was: Pass
-inference/instantiate_to_bounds_generic_has_bound_defined_before: TextSerializationFailure # Was: Pass
-inference/instantiate_to_bounds_invoke_constructor_no_bound: TextSerializationFailure # Was: Pass
-inference/instantiate_to_bounds_invoke_constructor_type_args_exact: TextSerializationFailure # Was: Pass
-inference/instantiate_to_bounds_not_generic: TextSerializationFailure # Was: Pass
-inference/lambda_does_not_have_propagated_type_hint: TextSerializationFailure # Was: Pass
-inference/lambda_return_type: TextSerializationFailure # Was: Pass
-inference/lambda_void_context: TextSerializationFailure # Was: Pass
-inference/list_literals: TextSerializationFailure # Was: Pass
-inference/list_literals_can_infer_null_bottom: TextSerializationFailure # Was: Pass
-inference/local_constructor_from_arguments: TextSerializationFailure # Was: Pass
-inference/local_reference_upwards_local: TextSerializationFailure # Was: Pass
-inference/local_return_and_yield: TextSerializationFailure # Was: Pass
-inference/logical_or_promotion: TextSerializationFailure # Was: Pass
-inference/map_literals: TextSerializationFailure # Was: Pass
-inference/map_literals_can_infer_null: TextSerializationFailure # Was: Pass
-inference/map_literals_top_level: TextSerializationFailure # Was: Pass
-inference/method_call_with_type_arguments_instance_method: TextSerializationFailure # Was: Pass
-inference/method_call_with_type_arguments_instance_method_identifier_sequence: TextSerializationFailure # Was: Pass
-inference/method_call_with_type_arguments_static_method: TextSerializationFailure # Was: Pass
-inference/method_call_with_type_arguments_top_level_function: TextSerializationFailure # Was: Pass
-inference/mixin_inference_instantiate_to_bounds_1: TextSerializationFailure # Was: Pass
-inference/mixin_inference_instantiate_to_bounds_2: TextSerializationFailure # Was: Pass
-inference/mixin_inference_instantiate_to_bounds_3: TextSerializationFailure # Was: Pass
-inference/mixin_inference_multiple_constraints: TextSerializationFailure # Was: Pass
-inference/mixin_inference_non_trivial_constraints: TextSerializationFailure # Was: Pass
-inference/mixin_inference_outwards_1: TextSerializationFailure # Was: Pass
-inference/mixin_inference_outwards_2: TextSerializationFailure # Was: Pass
inference/mixin_inference_outwards_3: TypeCheckError
inference/mixin_inference_outwards_4: TypeCheckError
inference/mixin_inference_unification_1: TypeCheckError
inference/mixin_inference_unification_2: TypeCheckError
-inference/no_error_when_declared_type_is_num_and_assigned_null: TextSerializationFailure # Was: Pass
-inference/non_const_invocation: TextSerializationFailure # Was: Pass
-inference/null_aware_method_invocation: TextSerializationFailure # Was: Pass
-inference/null_aware_property_get: TextSerializationFailure # Was: Pass
-inference/null_coalescing_operator: TextSerializationFailure # Was: Pass
-inference/null_coalescing_operator_2: TextSerializationFailure # Was: Pass
-inference/null_literal_should_not_infer_as_bottom: TextSerializationFailure # Was: Pass
-inference/overloaded_int_operators: TextSerializationFailure # Was: Pass
-inference/override_equals: TextSerializationFailure # Was: RuntimeError
-inference/override_inference_depends_on_field_inference: TextSerializationFailure
-inference/override_inference_with_type_parameters: TextSerializationFailure
-inference/parameter_defaults_upwards: TextSerializationFailure # Was: Pass
-inference/promote_bounds: TextSerializationFailure # Was: Pass
-inference/promote_from_logical_rhs: TextSerializationFailure # Was: Pass
-inference/promotion_subtype_check: TextSerializationFailure # Was: Pass
-inference/propagate_inference_to_field_in_class: TextSerializationFailure # Was: Pass
-inference/propagate_inference_to_field_in_class_dynamic_warnings: TextSerializationFailure # Was: Pass
-inference/propagate_inference_transitively2: TextSerializationFailure # Was: Pass
-inference/propagate_inference_transitively: TextSerializationFailure # Was: Pass
-inference/propagate_variable_get: TextSerializationFailure # Was: Pass
-inference/property_set: TextSerializationFailure # Was: Pass
-inference/property_set_bad_setter: TextSerializationFailure # Was: Pass
-inference/recursive_generic_function: TextSerializationFailure # Was: Pass
-inference/refine_binary_expression_type_type_parameter_t_double: TextSerializationFailure # Was: Pass
-inference/refine_binary_expression_type_type_parameter_t_int: TextSerializationFailure # Was: Pass
-inference/refine_binary_expression_type_type_parameter_t_t: TextSerializationFailure # Was: Pass
-inference/string_literal: TextSerializationFailure # Was: Pass
-inference/super_index_set: TextSerializationFailure # Was: Pass
-inference/super_index_set_substitution: TextSerializationFailure # Was: Pass
-inference/super_initializer: TextSerializationFailure # Was: Pass
-inference/super_initializer_substitution: TextSerializationFailure # Was: Pass
-inference/super_method_invocation_substitution: TextSerializationFailure # Was: Pass
-inference/super_property_get_substitution: TextSerializationFailure # Was: Pass
-inference/super_property_set_substitution: TextSerializationFailure # Was: Pass
-inference/switch_continue: TextSerializationFailure # Was: Pass
-inference/this_reference: TextSerializationFailure # Was: Pass
-inference/top_level_return_and_yield: TextSerializationFailure # Was: Pass
-inference/try_catch: TextSerializationFailure # Was: Pass
-inference/try_catch_finally: TextSerializationFailure # Was: Pass
-inference/try_catch_promotion: TextSerializationFailure # Was: Pass
-inference/try_finally: TextSerializationFailure # Was: Pass
-inference/type_cast: TextSerializationFailure # Was: Pass
-inference/type_promotion_ignores_local_functions: TextSerializationFailure # Was: Pass
-inference/type_promotion_not_and_not: TextSerializationFailure # Was: Pass
-inference/type_promotion_simple: TextSerializationFailure # Was: Pass
-inference/type_promotion_stopped_by_access_in_a_closure: TextSerializationFailure # Was: Pass
-inference/type_promotion_stopped_by_assignment_in_scope: TextSerializationFailure # Was: Pass
-inference/type_promotion_stopped_by_mutation_in_a_closure: TextSerializationFailure # Was: Pass
-inference/unresolved_super: TextSerializationFailure
-inference/unsafe_block_closure_inference_constructor_call_explicit_dynamic_param: TextSerializationFailure # Was: Pass
-inference/unsafe_block_closure_inference_constructor_call_explicit_type_param: TextSerializationFailure # Was: Pass
-inference/unsafe_block_closure_inference_constructor_call_implicit_type_param: TextSerializationFailure # Was: Pass
-inference/unsafe_block_closure_inference_function_call_explicit_dynamic_param: TextSerializationFailure # Was: Pass
-inference/unsafe_block_closure_inference_function_call_explicit_dynamic_param_via_expr1: TextSerializationFailure
-inference/unsafe_block_closure_inference_function_call_explicit_dynamic_param_via_expr2: TextSerializationFailure
-inference/unsafe_block_closure_inference_function_call_explicit_type_param: TextSerializationFailure # Was: Pass
-inference/unsafe_block_closure_inference_function_call_explicit_type_param_via_expr1: TextSerializationFailure
-inference/unsafe_block_closure_inference_function_call_explicit_type_param_via_expr2: TextSerializationFailure
-inference/unsafe_block_closure_inference_function_call_implicit_type_param: TextSerializationFailure # Was: Pass
-inference/unsafe_block_closure_inference_function_call_implicit_type_param_via_expr: TextSerializationFailure # Was: Pass
-inference/unsafe_block_closure_inference_method_call_explicit_dynamic_param: TextSerializationFailure # Was: Pass
-inference/unsafe_block_closure_inference_method_call_explicit_type_param: TextSerializationFailure # Was: Pass
-inference/unsafe_block_closure_inference_method_call_implicit_type_param: TextSerializationFailure # Was: Pass
-inference/void_return_type_subtypes_dynamic: TextSerializationFailure # Was: Pass
-inference_new/const_invocation: TextSerializationFailure # Was: Pass
-inference_new/dependency_only_if_generic_method: TextSerializationFailure # Was: Pass
-inference_new/do_loop: TextSerializationFailure # Was: Pass
-inference_new/downwards_inference_inside_top_level: TextSerializationFailure # Was: Pass
-inference_new/downwards_inference_inside_top_level_2: TextSerializationFailure # Was: Pass
-inference_new/for_each_identifier_downwards: TextSerializationFailure # Was: Pass
-inference_new/for_each_invalid_iterable: TextSerializationFailure # Was: Pass
-inference_new/for_each_outer_var_type: TextSerializationFailure # Was: Pass
-inference_new/indexed_assign_combiner: TextSerializationFailure # Was: Pass
-inference_new/infer_assign_to_implicit_this: TextSerializationFailure # Was: Pass
-inference_new/infer_assign_to_implicit_this_upwards: TextSerializationFailure # Was: Pass
-inference_new/infer_assign_to_index: TextSerializationFailure # Was: Pass
-inference_new/infer_assign_to_index_full: TextSerializationFailure # Was: Pass
-inference_new/infer_assign_to_index_set_vs_get: TextSerializationFailure # Was: Pass
-inference_new/infer_assign_to_index_super: TextSerializationFailure # Was: Pass
+inference/override_equals: RuntimeError
inference_new/infer_assign_to_index_super_upwards: TypeCheckError
-inference_new/infer_assign_to_index_this: TextSerializationFailure # Was: Pass
inference_new/infer_assign_to_index_this_upwards: TypeCheckError
inference_new/infer_assign_to_index_upwards: TypeCheckError
-inference_new/infer_assign_to_local: TextSerializationFailure # Was: Pass
-inference_new/infer_assign_to_local_upwards: TextSerializationFailure # Was: Pass
-inference_new/infer_assign_to_property: TextSerializationFailure # Was: Pass
inference_new/infer_assign_to_property_custom: TypeCheckError
-inference_new/infer_assign_to_property_full: TextSerializationFailure # Was: Pass
-inference_new/infer_assign_to_property_null_aware: TextSerializationFailure # Was: Pass
-inference_new/infer_assign_to_property_null_aware_upwards: TextSerializationFailure # Was: Pass
-inference_new/infer_assign_to_property_super: TextSerializationFailure # Was: Pass
-inference_new/infer_assign_to_property_super_upwards: TextSerializationFailure # Was: Pass
-inference_new/infer_assign_to_property_upwards: TextSerializationFailure # Was: Pass
-inference_new/infer_assign_to_static: TextSerializationFailure # Was: Pass
-inference_new/infer_assign_to_static_upwards: TextSerializationFailure # Was: Pass
-inference_new/infer_instance_accessor_ref: TextSerializationFailure # Was: Pass
-inference_new/infer_instance_field_ref: TextSerializationFailure # Was: Pass
-inference_new/infer_logical: TextSerializationFailure # Was: Pass
inference_new/invalid_assignment_during_toplevel_inference: TypeCheckError
-inference_new/multiple_interface_inheritance: TextSerializationFailure # Was: Pass
-inference_new/null_aware_property_get: TextSerializationFailure
-inference_new/property_assign_combiner: TextSerializationFailure # Was: Pass
-inference_new/static_assign_combiner: TextSerializationFailure # Was: Pass
-inference_new/super_index_get: TextSerializationFailure # Was: Pass
-inference_new/super_index_get_substitution: TextSerializationFailure # Was: Pass
-inference_new/switch: TextSerializationFailure # Was: Pass
-inference_new/unsafe_block_closure_inference_function_call_explicit_dynamic_param_via_expr2: TextSerializationFailure # Was: Pass
-inference_new/unsafe_block_closure_inference_function_call_explicit_type_param_via_expr2: TextSerializationFailure # Was: Pass
-inference_new/void_return_type_subtypes_dynamic: TextSerializationFailure # Was: Pass
-inference_new/while_loop: TextSerializationFailure # Was: Pass
-instantiate_to_bound/all_steps: TextSerializationFailure # Was: Pass
-instantiate_to_bound/body_literal_list: TextSerializationFailure # Was: Pass
-instantiate_to_bound/body_literal_list_with_generic_argument: TextSerializationFailure # Was: Pass
-instantiate_to_bound/body_literal_map: TextSerializationFailure # Was: Pass
-instantiate_to_bound/body_omitted_bound: TextSerializationFailure # Was: Pass
-instantiate_to_bound/body_super_bounded_type: TextSerializationFailure # Was: Pass
-instantiate_to_bound/body_typedef_literal_list: TextSerializationFailure # Was: Pass
-instantiate_to_bound/body_typedef_literal_list_with_generic_argument: TextSerializationFailure # Was: Pass
-instantiate_to_bound/body_typedef_literal_map: TextSerializationFailure # Was: Pass
-instantiate_to_bound/body_typedef_omitted_bound: TextSerializationFailure # Was: Pass
-instantiate_to_bound/body_typedef_super_bounded_type: TextSerializationFailure # Was: Pass
-instantiate_to_bound/contravariant_dependence: TextSerializationFailure # Was: Pass
-instantiate_to_bound/contravariant_dependence_in_literals: TextSerializationFailure # Was: Pass
-instantiate_to_bound/contravariant_mutual_dependence: TextSerializationFailure # Was: Pass
-instantiate_to_bound/contravariant_mutual_dependence_in_literals: TextSerializationFailure # Was: Pass
-instantiate_to_bound/covariant_dependence: TextSerializationFailure # Was: Pass
-instantiate_to_bound/covariant_dependence_in_literals: TextSerializationFailure # Was: Pass
-instantiate_to_bound/covariant_mutual_dependence: TextSerializationFailure # Was: Pass
-instantiate_to_bound/covariant_mutual_dependence_in_literals: TextSerializationFailure # Was: Pass
-instantiate_to_bound/dependence: TextSerializationFailure # Was: Pass
-instantiate_to_bound/dependence_in_literals: TextSerializationFailure # Was: Pass
-instantiate_to_bound/inference_constrained_by_bound: TextSerializationFailure # Was: Pass
-instantiate_to_bound/inference_defaults_to_bound: TextSerializationFailure # Was: Pass
-instantiate_to_bound/inference_gives_input: TextSerializationFailure # Was: Pass
-instantiate_to_bound/inference_super_bounded_rejected: TextSerializationFailure # Was: Pass
-instantiate_to_bound/instantiated_in_outline: TextSerializationFailure # Was: Pass
-instantiate_to_bound/literal_list: TextSerializationFailure # Was: Pass
-instantiate_to_bound/literal_list_with_generic_argument: TextSerializationFailure # Was: Pass
-instantiate_to_bound/literal_map: TextSerializationFailure # Was: Pass
-instantiate_to_bound/multiple_strongly_connected: TextSerializationFailure # Was: Pass
-instantiate_to_bound/mutual_dependence: TextSerializationFailure # Was: Pass
-instantiate_to_bound/mutual_dependence_in_literals: TextSerializationFailure # Was: Pass
-instantiate_to_bound/non_simple_bound_due_to_non_simple: TextSerializationFailure # Was: Pass
-instantiate_to_bound/non_simple_bound_due_to_variables: TextSerializationFailure # Was: Pass
-instantiate_to_bound/non_simple_class_parametrized_typedef_cycle: TextSerializationFailure # Was: RuntimeError # Expected
-instantiate_to_bound/non_simple_class_typedef_cycle: TextSerializationFailure # Was: Pass
-instantiate_to_bound/non_simple_co_inductive: TextSerializationFailure # Was: Pass
-instantiate_to_bound/non_simple_co_inductive_for_each: TextSerializationFailure # Was: Pass
-instantiate_to_bound/non_simple_co_inductive_no_dup: TextSerializationFailure # Was: Pass
-instantiate_to_bound/non_simple_folded_regress: TextSerializationFailure # Was: Pass
-instantiate_to_bound/non_simple_for_each: TextSerializationFailure # Was: Pass
-instantiate_to_bound/non_simple_from_compiled: TextSerializationFailure # Was: Pass
-instantiate_to_bound/non_simple_generic_function_in_bound_regress: TextSerializationFailure # Was: RuntimeError # Expected
-instantiate_to_bound/non_simple_many: TextSerializationFailure # Was: Pass
-instantiate_to_bound/non_simple_many_libs_same_name_cycle: TextSerializationFailure # Was: Pass
-instantiate_to_bound/non_simple_many_libs_same_name_cycle_lib: TextSerializationFailure # Was: Pass
-instantiate_to_bound/non_simple_no_dup: TextSerializationFailure # Was: Pass
-instantiate_to_bound/non_simple_suppress_consequence: TextSerializationFailure # Was: Pass
-instantiate_to_bound/non_simple_variables_from_same: TextSerializationFailure # Was: Pass
-instantiate_to_bound/omitted_bound: TextSerializationFailure # Was: Pass
-instantiate_to_bound/raw_in_bound: TextSerializationFailure # Was: Pass
-instantiate_to_bound/super_bounded_in_bound: TextSerializationFailure
-instantiate_to_bound/super_bounded_type: TextSerializationFailure # Was: Pass
-instantiate_to_bound/supertypes: TextSerializationFailure # Was: Pass
-instantiate_to_bound/typedef_instantiated_in_outline: TextSerializationFailure # Was: Pass
-instantiate_to_bound/typedef_literal_list: TextSerializationFailure # Was: Pass
-instantiate_to_bound/typedef_literal_list_with_generic_argument: TextSerializationFailure # Was: Pass
-instantiate_to_bound/typedef_literal_map: TextSerializationFailure # Was: Pass
-instantiate_to_bound/typedef_omitted_bound: TextSerializationFailure # Was: Pass
-instantiate_to_bound/typedef_raw_in_bound: TextSerializationFailure # Was: Pass
-instantiate_to_bound/typedef_super_bounded_type: TextSerializationFailure # Was: Pass
-late_lowering/compound: TextSerializationFailure
-late_lowering/definitely_assigned: TextSerializationFailure
-late_lowering/definitely_unassigned: TextSerializationFailure
-late_lowering/infer_from_late_variable: TextSerializationFailure
-late_lowering/infer_late_field_type: TextSerializationFailure
-late_lowering/initializer_rewrite: TextSerializationFailure
-late_lowering/instance_field_with_initializer: TextSerializationFailure
-late_lowering/instance_field_without_initializer: TextSerializationFailure
-late_lowering/instance_final_field_without_initializer: TextSerializationFailure
-late_lowering/instance_nullable_field_with_initializer: TextSerializationFailure
-late_lowering/instance_nullable_field_without_initializer: TextSerializationFailure
-late_lowering/instance_nullable_final_field_without_initializer: TextSerializationFailure
-late_lowering/issue40093: TextSerializationFailure
-late_lowering/issue40373: TextSerializationFailure
-late_lowering/issue40373b: TextSerializationFailure
-late_lowering/issue40601: TextSerializationFailure
-late_lowering/issue40805: TextSerializationFailure
-late_lowering/issue41436b: TextSerializationFailure
-late_lowering/issue41436c/issue41436c: TextSerializationFailure
-late_lowering/late_field_inference: TextSerializationFailure
-late_lowering/late_field_with_initializer: TextSerializationFailure
-late_lowering/late_field_without_initializer: TextSerializationFailure
-late_lowering/late_final_field_with_initializer: TextSerializationFailure
-late_lowering/late_final_field_without_initializer: TextSerializationFailure
-late_lowering/late_final_local_with_initializer: TextSerializationFailure
-late_lowering/late_final_local_without_initializer: TextSerializationFailure
-late_lowering/late_final_nullable_field_with_initializer: TextSerializationFailure
-late_lowering/late_final_nullable_field_without_initializer: TextSerializationFailure
-late_lowering/late_final_nullable_local_with_initializer: TextSerializationFailure
-late_lowering/late_final_nullable_local_without_initializer: TextSerializationFailure
-late_lowering/late_future_or: TextSerializationFailure
-late_lowering/late_local_with_initializer: TextSerializationFailure
-late_lowering/late_local_without_initializer: TextSerializationFailure
-late_lowering/late_nullable_field_with_initializer: TextSerializationFailure
-late_lowering/late_nullable_field_without_initializer: TextSerializationFailure
-late_lowering/late_nullable_local_with_initializer: TextSerializationFailure
-late_lowering/late_nullable_local_without_initializer: TextSerializationFailure
-late_lowering/later: TextSerializationFailure
-late_lowering/override: TextSerializationFailure
-late_lowering/override_getter_setter: TextSerializationFailure
-late_lowering/return_late: TextSerializationFailure
-late_lowering/uninitialized_non_nullable_late_fields: TextSerializationFailure
-new_const_insertion/simple: TextSerializationFailure # Was: Pass
-nnbd/assign_type_variable: TextSerializationFailure
-nnbd/assignability: TextSerializationFailure
-nnbd/bounds_checks: TextSerializationFailure
-nnbd/bounds_from_opt_in: TextSerializationFailure
-nnbd/call: TextSerializationFailure
-nnbd/constant_null_is: TextSerializationFailure
-nnbd/constants: TextSerializationFailure
-nnbd/covariant_equals: TextSerializationFailure
-nnbd/definite_assignment_and_completion: TextSerializationFailure
-nnbd/definitely_assigned: TextSerializationFailure
-nnbd/definitely_unassigned: TextSerializationFailure
-nnbd/definitely_unassigned_late_local_variables: TextSerializationFailure
-nnbd/demote_closure_types: TextSerializationFailure
-nnbd/forin: TextSerializationFailure
-nnbd/function_types: TextSerializationFailure
-nnbd/future_or_variables: TextSerializationFailure
-nnbd/infer_constraints_from_opt_in: TextSerializationFailure
-nnbd/infer_from_late_variable: TextSerializationFailure
-nnbd/infer_from_opt_in: TextSerializationFailure
-nnbd/infer_from_opt_out: TextSerializationFailure
-nnbd/infer_if_null: TextSerializationFailure
-nnbd/infer_in_legacy_from_opted_in: TextSerializationFailure
+instantiate_to_bound/non_simple_class_parametrized_typedef_cycle: RuntimeError
+instantiate_to_bound/non_simple_generic_function_in_bound_regress: RuntimeError
nnbd/inheritance_from_opt_in: TypeCheckError
-nnbd/inheritance_from_opt_out: TextSerializationFailure
-nnbd/intersection_types: TextSerializationFailure
-nnbd/issue39822: TextSerializationFailure
-nnbd/issue40093: TextSerializationFailure
-nnbd/issue40134: TextSerializationFailure
-nnbd/issue40512/issue40512: TextSerializationFailure
-nnbd/issue40600: TextSerializationFailure
-nnbd/issue40601: TextSerializationFailure
-nnbd/issue40805: TextSerializationFailure
-nnbd/issue41102: TextSerializationFailure
-nnbd/issue41103: TextSerializationFailure
-nnbd/issue41114: TextSerializationFailure
-nnbd/issue41156: TextSerializationFailure
-nnbd/issue41180: TextSerializationFailure
-nnbd/issue41210a/issue41210: TextSerializationFailure
-nnbd/issue41210b: TextSerializationFailure
-nnbd/issue41273: TextSerializationFailure
-nnbd/issue41498: TextSerializationFailure
-nnbd/issue41498b: TextSerializationFailure
-nnbd/issue_39286: TextSerializationFailure
-nnbd/issue_39286_2: TextSerializationFailure
-nnbd/late: TextSerializationFailure
-nnbd/later: TextSerializationFailure
-nnbd/lhs_of_if_null: TextSerializationFailure
-nnbd/list_constructor: TextSerializationFailure
-nnbd/literal_from_opt_in: TextSerializationFailure
-nnbd/load_library: TextSerializationFailure
-nnbd/member_inheritance_from_opt_out: TextSerializationFailure
+nnbd/issue41180: RuntimeError
nnbd/messages_with_types_opt_in: TypeCheckError
nnbd/messages_with_types_opt_out: TypeCheckError
-nnbd/missing_required_named_parameter: TextSerializationFailure
-nnbd/mixed_mode_hierarchy_generic_methods: TextSerializationFailure
-nnbd/mixin_from_opt_in: TextSerializationFailure
-nnbd/mixin_from_opt_in_out_in: TextSerializationFailure
-nnbd/mixin_from_opt_out: TextSerializationFailure
-nnbd/never_bound: TextSerializationFailure
nnbd/never_opt_out: TypeCheckError
-nnbd/never_receiver: TextSerializationFailure
-nnbd/no_null_shorting: TextSerializationFailure
-nnbd/no_null_shorting_explicit_extension: TextSerializationFailure
-nnbd/no_null_shorting_extension: TextSerializationFailure
-nnbd/non_nullable_field_initialization: TextSerializationFailure
-nnbd/not_definitely_unassigned_late_local_variables: TextSerializationFailure
-nnbd/nsm_from_opt_in: TextSerializationFailure
-nnbd/null_access: TextSerializationFailure
-nnbd/null_aware_chain: TextSerializationFailure
-nnbd/null_check: TextSerializationFailure
-nnbd/null_check_context: TextSerializationFailure
-nnbd/null_shorting: TextSerializationFailure
-nnbd/null_shorting_cascade: TextSerializationFailure
-nnbd/null_shorting_explicit_extension: TextSerializationFailure
-nnbd/null_shorting_extension: TextSerializationFailure
-nnbd/null_shorting_index: TextSerializationFailure
-nnbd/nullable_access: TextSerializationFailure
-nnbd/nullable_null: TextSerializationFailure
-nnbd/nullable_object_access: TextSerializationFailure
-nnbd/nullable_param: TextSerializationFailure
-nnbd/nullable_receiver: TextSerializationFailure
-nnbd/nullable_rhs_of_typedef: TextSerializationFailure
-nnbd/opt_out: TextSerializationFailure
-nnbd/override_checks: TextSerializationFailure
-nnbd/potentially_constant_type_as: TextSerializationFailure
-nnbd/potentially_constant_type_is: TextSerializationFailure
-nnbd/potentially_non_nullable_field: TextSerializationFailure
-nnbd/regress_null_aware: TextSerializationFailure
-nnbd/return_late: TextSerializationFailure
-nnbd/return_null: TextSerializationFailure
-nnbd/shorting_stop: TextSerializationFailure
-nnbd/sink_hierarchy: TextSerializationFailure
-nnbd/strictly_non_nullable_warnings: TextSerializationFailure
-nnbd/substitution_in_inference: TextSerializationFailure
-nnbd/switch_redesign_fall_over: TextSerializationFailure
-nnbd/switch_redesign_types: TextSerializationFailure
-nnbd/tearoff_from_nullable_receiver: TextSerializationFailure
-nnbd/type_parameter_types: TextSerializationFailure
-nnbd/uninitialized_non_nullable_late_fields: TextSerializationFailure
-no_such_method_forwarders/abstract_accessors_from_field: TextSerializationFailure # Was: Pass
-no_such_method_forwarders/abstract_accessors_from_field_arent_mixed_in: TextSerializationFailure # Was: Pass
-no_such_method_forwarders/abstract_accessors_from_field_one_defined: TextSerializationFailure # Was: Pass
-no_such_method_forwarders/abstract_accessors_from_field_with_substitution: TextSerializationFailure # Was: Pass
-no_such_method_forwarders/abstract_override_abstract_different_type: TextSerializationFailure
-no_such_method_forwarders/abstract_override_with_different_signature: TextSerializationFailure
-no_such_method_forwarders/default_argument_values: TextSerializationFailure # Was: Pass
-no_such_method_forwarders/forwarder_propagation: TextSerializationFailure
-no_such_method_forwarders/multiple_abstract_setters: TextSerializationFailure
-no_such_method_forwarders/nsm_inherited: TextSerializationFailure # Was: Pass
-no_such_method_forwarders/setter_not_shadowed_by_method: TextSerializationFailure # Was: Pass
-no_such_method_forwarders/subst_on_forwarder: TextSerializationFailure # Was: Pass
+nnbd/potentially_nullable_access: TypeCheckError
rasta/abstract_constructor: RuntimeError
rasta/bad_constructor_redirection: RuntimeError
rasta/bad_continue: RuntimeError
@@ -1081,194 +176,67 @@
rasta/bad_explicit_super_constructor: RuntimeError
rasta/bad_implicit_super_constructor: RuntimeError
rasta/bad_interpolation: RuntimeError
-rasta/bad_interpolation: TextSerializationFailure # Was: RuntimeError
rasta/bad_redirection: RuntimeError
rasta/bad_setter_initializer: RuntimeError
rasta/breaking_bad: RuntimeError
-rasta/cascades: TextSerializationFailure # Was: Pass
rasta/class_hierarchy: RuntimeError
rasta/class_member: RuntimeError
rasta/constant_get_and_invoke: RuntimeError
-rasta/deferred_lib: TextSerializationFailure # Was: Pass
rasta/duplicated_mixin: RuntimeError
-rasta/enum: TextSerializationFailure # Was: Pass
rasta/export: RuntimeError
-rasta/export: TextSerializationFailure # Was: RuntimeError # Expected, this file has no main method.
rasta/foo: RuntimeError
-rasta/foo: TextSerializationFailure # Was: RuntimeError # Expected, this file has no main method.
-rasta/for_loop: TextSerializationFailure # Was: Pass
-rasta/generic_factory: TextSerializationFailure # Was: RuntimeError
+rasta/generic_factory: RuntimeError
rasta/issue_000001: RuntimeError
-rasta/issue_000002: TextSerializationFailure # Was: Pass
-rasta/issue_000004: TextSerializationFailure # Was: Pass
-rasta/issue_000008: TextSerializationFailure # Was: Pass
-rasta/issue_000031: TextSerializationFailure # Was: RuntimeError
+rasta/issue_000031: RuntimeError
rasta/issue_000032: RuntimeError
rasta/issue_000034: RuntimeError
rasta/issue_000036: RuntimeError
-rasta/issue_000036: TextSerializationFailure # Was: RuntimeError
rasta/issue_000039: RuntimeError
rasta/issue_000041: RuntimeError
rasta/issue_000042: RuntimeError
rasta/issue_000043: RuntimeError
rasta/issue_000044: RuntimeError
rasta/issue_000046: RuntimeError
-rasta/issue_000048: TextSerializationFailure # Was: Pass
-rasta/issue_000052: TextSerializationFailure # Was: Pass
-rasta/issue_000067: TextSerializationFailure # Was: Pass
-rasta/issue_000068: TextSerializationFailure # Was: Pass
-rasta/issue_000069: TextSerializationFailure # Was: Pass
-rasta/issue_000070: TextSerializationFailure # Was: Pass
-rasta/issue_000080: TextSerializationFailure # Was: Pass
-rasta/issue_000081: TextSerializationFailure # Was: RuntimeError
+rasta/issue_000081: RuntimeError
rasta/malformed_const_constructor: RuntimeError
rasta/malformed_function: RuntimeError
-rasta/malformed_function: TextSerializationFailure # Was: RuntimeError
rasta/mixin_library: TypeCheckError
rasta/native_is_illegal: RuntimeError
-rasta/parser_error: TextSerializationFailure # Was: RuntimeError
-rasta/static: TextSerializationFailure # Was: RuntimeError
+rasta/parser_error: RuntimeError
+rasta/static: RuntimeError
rasta/super: TypeCheckError
-rasta/super_initializer: TextSerializationFailure # Was: RuntimeError
+rasta/super_initializer: RuntimeError
rasta/super_mixin: TypeCheckError
rasta/super_operator: TypeCheckError
-rasta/switch_execution_case_t02: TextSerializationFailure # Was: Pass
-rasta/this_invoke: TextSerializationFailure # Was: Pass
-rasta/type_literals: TextSerializationFailure
-rasta/type_with_parse_error: TextSerializationFailure # Was: Pass
+rasta/type_literals: RuntimeError
rasta/typedef: RuntimeError
-rasta/typedef: TextSerializationFailure
rasta/unresolved: RuntimeError
-rasta/unresolved: TextSerializationFailure # Was: RuntimeError
rasta/unresolved_constructor: RuntimeError
-rasta/unresolved_for_in: TextSerializationFailure # Was: RuntimeError
+rasta/unresolved_for_in: RuntimeError
rasta/unresolved_recovery: TypeCheckError
-regress/issue_29937: TextSerializationFailure # Was: Pass
-regress/issue_29942: TextSerializationFailure # Was: Pass
regress/issue_29976: RuntimeError
-regress/issue_29976: TextSerializationFailure # Was: RuntimeError # Tests runtime behavior of error recovery.
-regress/issue_29978: TextSerializationFailure # Was: Pass
-regress/issue_29979: TextSerializationFailure # Was: Pass
-regress/issue_29981: TextSerializationFailure # Was: Pass
-regress/issue_29982: TextSerializationFailure # Was: RuntimeError # Tests runtime behavior of error recovery.
-regress/issue_30834: TextSerializationFailure # Was: Pass
+regress/issue_29982: RuntimeError
regress/issue_30836: RuntimeError
-regress/issue_30838: TextSerializationFailure # Was: Pass
-regress/issue_31181: TextSerializationFailure # Was: Pass
-regress/issue_31184: TextSerializationFailure # Was: Pass
-regress/issue_31185: TextSerializationFailure # Was: Pass
-regress/issue_31190: TextSerializationFailure # Was: Pass
-regress/issue_31213: TextSerializationFailure # Was: Pass
regress/issue_31299: TypeCheckError
-regress/issue_31766: TextSerializationFailure # Was: Pass
-regress/issue_31846: TextSerializationFailure # Was: Pass
-regress/issue_31996: TextSerializationFailure # Was: Pass
-regress/issue_32182: TextSerializationFailure # Was: Pass
-regress/issue_32196: TextSerializationFailure # Was: Pass
-regress/issue_32200: TextSerializationFailure # Was: RuntimeError # Invalid type.
-regress/issue_32660: TextSerializationFailure # Was: Pass
regress/issue_32972: TypeCheckError
-regress/issue_33452: TextSerializationFailure # Was: RuntimeError # Test has an intentional error
-regress/issue_33672: TextSerializationFailure # Was: Pass
-regress/issue_34225: TextSerializationFailure # Was: RuntimeError
-regress/issue_34291_lib: TextSerializationFailure # Was: Pass
-regress/issue_34403: TextSerializationFailure # Was: Pass
-regress/issue_34403_lib: TextSerializationFailure # Was: Pass
-regress/issue_34498: TextSerializationFailure # Was: Pass
-regress/issue_34498_lib: TextSerializationFailure # Was: Pass
+regress/issue_33452: RuntimeError
+regress/issue_34225: RuntimeError
regress/issue_34563: RuntimeError
-regress/issue_34614: TextSerializationFailure # Was: Pass
-regress/issue_35177: TextSerializationFailure # Was: RuntimeError
+regress/issue_35177: RuntimeError
regress/issue_35258: RuntimeError
regress/issue_35259: RuntimeError
regress/issue_35260: RuntimeError
-regress/issue_35266: TextSerializationFailure # Was: RuntimeError # Expected
-regress/issue_35900: TextSerializationFailure
+regress/issue_35266: RuntimeError
regress/issue_36400: RuntimeError
regress/issue_36647: RuntimeError
regress/issue_36647_2: RuntimeError
regress/issue_36669: RuntimeError
regress/issue_37285: RuntimeError
-regress/issue_37681: TextSerializationFailure
regress/issue_39035.crash: RuntimeError
-regress/issue_39035.crash: TextSerializationFailure
-regress/issue_39040: TextSerializationFailure
regress/issue_39091_1: RuntimeError
regress/issue_39091_2: RuntimeError
-regress/issue_39091_2: TextSerializationFailure
-regress/issue_39682: TextSerializationFailure
-regress/issue_41265.crash: TextSerializationFailure
-runtime_checks/call_kinds: TextSerializationFailure # Was: Pass
regress/utf_16_le_content.crash: Crash
-runtime_checks/call_kinds_get: TextSerializationFailure # Was: Pass
-runtime_checks/call_kinds_set: TextSerializationFailure # Was: Pass
-runtime_checks/call_method_implicit_tear_off: TextSerializationFailure # Was: Pass
-runtime_checks/call_method_implicit_tear_off_future_or: TextSerializationFailure # Was: Pass
-runtime_checks/contravariant_field: TextSerializationFailure # Was: Pass
-runtime_checks/contravariant_generic_method_type_parameter: TextSerializationFailure # Was: Pass
-runtime_checks/contravariant_generic_return: TextSerializationFailure # Was: Pass
-runtime_checks/contravariant_generic_return_null_aware: TextSerializationFailure # Was: Pass
-runtime_checks/contravariant_generic_return_tear_off: TextSerializationFailure # Was: Pass
-runtime_checks/contravariant_getter: TextSerializationFailure # Was: Pass
-runtime_checks/contravariant_getter_return: TextSerializationFailure # Was: Pass
-runtime_checks/contravariant_getter_return_null_aware: TextSerializationFailure # Was: Pass
-runtime_checks/covariant_generic_method_type_parameter: TextSerializationFailure # Was: Pass
-runtime_checks/covariant_generic_parameter: TextSerializationFailure # Was: Pass
-runtime_checks/covariant_generic_parameter_complex: TextSerializationFailure # Was: Pass
-runtime_checks/covariant_generic_parameter_in_interface: TextSerializationFailure # Was: Pass
-runtime_checks/covariant_generic_parameter_in_interface_mixin: TextSerializationFailure # Was: Pass
-runtime_checks/covariant_generic_parameter_in_interface_super: TextSerializationFailure # Was: Pass
-runtime_checks/covariant_generic_parameter_in_interface_super_mixin: TextSerializationFailure # Was: Pass
-runtime_checks/covariant_generic_parameter_tear_off: TextSerializationFailure # Was: Pass
-runtime_checks/covariant_keyword: TextSerializationFailure # Was: Pass
-runtime_checks/covariant_setter: TextSerializationFailure # Was: Pass
-runtime_checks/dynamic_invocation: TextSerializationFailure # Was: Pass
-runtime_checks/dynamic_invocation_generic: TextSerializationFailure # Was: Pass
-runtime_checks/dynamic_invocation_of_getter: TextSerializationFailure # Was: Pass
-runtime_checks/field_forwarding_stub_generic_covariant: ExpectationFileMismatch
-runtime_checks/field_forwarding_stub_generic_covariant: TextSerializationFailure # Was: Pass
-runtime_checks/forwarding_stub_with_default_values: TextSerializationFailure # Was: Pass
-runtime_checks/forwarding_stub_with_non_covariant_param: TextSerializationFailure # Was: Pass
-runtime_checks/generic_covariance_inheritance_setter_field: TextSerializationFailure # Was: Pass
-runtime_checks/generic_vs_explicit_covariance: TextSerializationFailure # Was: Pass
-runtime_checks/implicit_downcast_assert_initializer: TextSerializationFailure # Was: Pass
-runtime_checks/implicit_downcast_assert_statement: TextSerializationFailure # Was: Pass
-runtime_checks/implicit_downcast_constructor_initializer: TextSerializationFailure # Was: Pass
-runtime_checks/implicit_downcast_do: TextSerializationFailure # Was: Pass
-runtime_checks/implicit_downcast_for_condition: TextSerializationFailure # Was: Pass
-runtime_checks/implicit_downcast_if: TextSerializationFailure # Was: Pass
-runtime_checks/implicit_downcast_not: TextSerializationFailure # Was: Pass
-runtime_checks/implicit_downcast_while: TextSerializationFailure # Was: Pass
-runtime_checks_new/abstract_override_becomes_forwarding_stub: ExpectationFileMismatch
-runtime_checks_new/abstract_override_becomes_forwarding_stub: TextSerializationFailure # Was: Pass
-runtime_checks_new/call_through_this: TextSerializationFailure # Was: Pass
-runtime_checks_new/contravariant_combiner: TextSerializationFailure # Was: Pass
-runtime_checks_new/contravariant_generic_return_with_compound_assign_implicit_downcast: TextSerializationFailure # Was: RuntimeError
-runtime_checks_new/contravariant_getter_return_compound_assign: TextSerializationFailure # Was: Pass
-runtime_checks_new/contravariant_index_assign: TextSerializationFailure # Was: Pass
-runtime_checks_new/contravariant_index_get: TextSerializationFailure # Was: Pass
-runtime_checks_new/derived_class_typed: TextSerializationFailure # Was: Pass
-runtime_checks_new/field_forwarding_stub_abstract_generic_covariant: TextSerializationFailure # Was: Pass
-runtime_checks_new/field_forwarding_stub_explicit_covariant: ExpectationFileMismatch
-runtime_checks_new/field_forwarding_stub_explicit_covariant: TextSerializationFailure # Was: Pass
-runtime_checks_new/for_in_call_kinds: TextSerializationFailure # Was: Pass
-runtime_checks_new/generic_covariance_based_on_inference: TextSerializationFailure # Was: Pass
-runtime_checks_new/mixin_forwarding_stub_field: ExpectationFileMismatch
+runtime_checks_new/contravariant_generic_return_with_compound_assign_implicit_downcast: RuntimeError
runtime_checks_new/mixin_forwarding_stub_field: TypeCheckError
-runtime_checks_new/mixin_forwarding_stub_getter: TypeCheckError
-runtime_checks_new/mixin_forwarding_stub_setter: ExpectationFileMismatch
runtime_checks_new/mixin_forwarding_stub_setter: TypeCheckError
-runtime_checks_new/stub_checked_via_target: TextSerializationFailure # Was: Pass
-runtime_checks_new/stub_from_interface_contravariant_from_class: TextSerializationFailure # Was: Pass
-runtime_checks_new/stub_from_interface_covariantImpl_from_class: TextSerializationFailure # Was: Pass
-runtime_checks_new/stub_from_interface_covariantImpl_from_interface: TextSerializationFailure # Was: Pass
-runtime_checks_new/stub_from_interface_covariantImpl_from_super: TextSerializationFailure # Was: Pass
-runtime_checks_new/stub_from_interface_covariantInterface_from_class: TextSerializationFailure # Was: Pass
-runtime_checks_new/stub_from_interface_covariant_from_interface: TextSerializationFailure # Was: Pass
-set_literals/disambiguation_rule: TextSerializationFailure # Was: RuntimeError
-top_level_variance_test: TextSerializationFailure
-unified_collections/mixed_entries: TextSerializationFailure
-unified_collections/string_concatenation: TextSerializationFailure
-variance/class_type_parameter_modifier: TextSerializationFailure
-variance/generic_covariance_sound_variance: TextSerializationFailure
-variance/unconstrained_inference: TextSerializationFailure
+set_literals/disambiguation_rule: RuntimeError
diff --git a/pkg/front_end/testcases/weak.status b/pkg/front_end/testcases/weak.status
index 5b3a8c9..9be9f1e 100644
--- a/pkg/front_end/testcases/weak.status
+++ b/pkg/front_end/testcases/weak.status
@@ -62,3 +62,5 @@
nnbd/messages_with_types_opt_in: TypeCheckError
nnbd/messages_with_types_opt_out: TypeCheckError
nnbd/never_opt_out: TypeCheckError
+nnbd/potentially_nullable_access: TypeCheckError
+
diff --git a/pkg/kernel/binary.md b/pkg/kernel/binary.md
index 3c70beb..2b37b2c 100644
--- a/pkg/kernel/binary.md
+++ b/pkg/kernel/binary.md
@@ -68,12 +68,12 @@
```
A string table consists of an array of end offsets and a payload array of
-strings encoded as UTF-8. The array of end offsets maps a string index to the
+strings encoded as WTF-8. The array of end offsets maps a string index to the
offset of the _next_ string in the table or the offset of the end of the array
for the last string. These offsets are relative to the string payload array.
-Thus, string number 0 consists of the UTF-8 encoded string stretching from
+Thus, string number 0 consists of the WTF-8 encoded string stretching from
offset 0 (inclusive) to endOffset[0] (exclusive); and string number N for N > 0
-consists of the UTF-8 encoded string stretching from offset endOffset[N-1]
+consists of the WTF-8 encoded string stretching from offset endOffset[N-1]
(inclusive) to endOffset[N] (exclusive).
``` scala
diff --git a/pkg/kernel/lib/binary/ast_from_binary.dart b/pkg/kernel/lib/binary/ast_from_binary.dart
index 73b41c5..df48c44 100644
--- a/pkg/kernel/lib/binary/ast_from_binary.dart
+++ b/pkg/kernel/lib/binary/ast_from_binary.dart
@@ -4,7 +4,6 @@
library kernel.ast_from_binary;
import 'dart:core' hide MapEntry;
-import 'dart:convert';
import 'dart:developer';
import 'dart:typed_data';
@@ -171,36 +170,74 @@
return _doubleBuffer[0];
}
- List<int> readBytes(int length) {
- List<int> bytes = new Uint8List(length);
+ Uint8List readBytes(int length) {
+ Uint8List bytes = new Uint8List(length);
bytes.setRange(0, bytes.length, _bytes, _byteOffset);
_byteOffset += bytes.length;
return bytes;
}
- List<int> readByteList() {
+ Uint8List readByteList() {
return readBytes(readUInt());
}
+ String readString() {
+ return readStringEntry(readUInt());
+ }
+
String readStringEntry(int numBytes) {
- // Utf8Decoder will skip leading BOM characters, but we must preserve them.
- // Collect leading BOMs before passing the bytes onto Utf8Decoder.
- int numByteOrderMarks = 0;
- while (_byteOffset + 2 < _bytes.length &&
- _bytes[_byteOffset] == 0xef &&
- _bytes[_byteOffset + 1] == 0xbb &&
- _bytes[_byteOffset + 2] == 0xbf) {
- ++numByteOrderMarks;
- _byteOffset += 3;
- numBytes -= 3;
+ int start = _byteOffset;
+ int end = start + numBytes;
+ _byteOffset = end;
+ for (int i = start; i < end; i++) {
+ if (_bytes[i] > 127) {
+ return _decodeWtf8(start, end);
+ }
}
- String string = const Utf8Decoder()
- .convert(_bytes, _byteOffset, _byteOffset + numBytes);
- _byteOffset += numBytes;
- if (numByteOrderMarks > 0) {
- return '\ufeff' * numByteOrderMarks + string;
+ return new String.fromCharCodes(_bytes, start, end);
+ }
+
+ String _decodeWtf8(int start, int end) {
+ // WTF-8 decoder that trusts its input, meaning that the correctness of
+ // the code depends on the bytes from start to end being valid and
+ // complete WTF-8. Instead of masking off the control bits from every
+ // byte, it simply xor's the byte values together at their appropriate
+ // bit shifts, and then xor's out all of the control bits at once.
+ Uint16List charCodes = new Uint16List(end - start);
+ int i = start;
+ int j = 0;
+ while (i < end) {
+ int byte = _bytes[i++];
+ if (byte < 0x80) {
+ // ASCII.
+ charCodes[j++] = byte;
+ } else if (byte < 0xE0) {
+ // Two-byte sequence (11-bit unicode value).
+ int byte2 = _bytes[i++];
+ int value = (byte << 6) ^ byte2 ^ 0x3080;
+ assert(value >= 0x80 && value < 0x800);
+ charCodes[j++] = value;
+ } else if (byte < 0xF0) {
+ // Three-byte sequence (16-bit unicode value).
+ int byte2 = _bytes[i++];
+ int byte3 = _bytes[i++];
+ int value = (byte << 12) ^ (byte2 << 6) ^ byte3 ^ 0xE2080;
+ assert(value >= 0x800 && value < 0x10000);
+ charCodes[j++] = value;
+ } else {
+ // Four-byte sequence (non-BMP unicode value).
+ int byte2 = _bytes[i++];
+ int byte3 = _bytes[i++];
+ int byte4 = _bytes[i++];
+ int value =
+ (byte << 18) ^ (byte2 << 12) ^ (byte3 << 6) ^ byte4 ^ 0x3C82080;
+ assert(value >= 0x10000 && value < 0x110000);
+ charCodes[j++] = 0xD7C0 + (value >> 10);
+ charCodes[j++] = 0xDC00 + (value & 0x3FF);
+ }
}
- return string;
+ assert(i == end);
+ return new String.fromCharCodes(charCodes, 0, j);
}
/// Read metadataMappings section from the binary.
@@ -222,7 +259,7 @@
for (int i = 0; i < length; ++i) {
endOffsets[i] = readUInt();
}
- // Read the UTF-8 encoded strings.
+ // Read the WTF-8 encoded strings.
table.length = length;
int startOffset = 0;
for (int i = 0; i < length; ++i) {
@@ -756,7 +793,7 @@
List<String> strings =
new List<String>.filled(length, null, growable: true);
for (int i = 0; i < length; i++) {
- String s = const Utf8Decoder().convert(readByteList());
+ String s = readString();
strings[i] = s;
}
return strings;
@@ -769,12 +806,10 @@
_sourceUriTable.length = length;
Map<Uri, Source> uriToSource = <Uri, Source>{};
for (int i = 0; i < length; ++i) {
- List<int> uriBytes = readByteList();
- Uri uri = uriBytes.isEmpty
- ? null
- : Uri.parse(const Utf8Decoder().convert(uriBytes));
+ String uriString = readString();
+ Uri uri = uriString.isEmpty ? null : Uri.parse(uriString);
_sourceUriTable[i] = uri;
- List<int> sourceCode = readByteList();
+ Uint8List sourceCode = readByteList();
int lineCount = readUInt();
List<int> lineStarts = new List<int>(lineCount);
int previousLineStart = 0;
@@ -783,10 +818,9 @@
lineStarts[j] = lineStart;
previousLineStart = lineStart;
}
- List<int> importUriBytes = readByteList();
- Uri importUri = importUriBytes.isEmpty
- ? null
- : Uri.parse(const Utf8Decoder().convert(importUriBytes));
+ String importUriString = readString();
+ Uri importUri =
+ importUriString.isEmpty ? null : Uri.parse(importUriString);
uriToSource[uri] = new Source(lineStarts, sourceCode, importUri, uri);
}
diff --git a/pkg/kernel/lib/binary/ast_to_binary.dart b/pkg/kernel/lib/binary/ast_to_binary.dart
index 93546be..c481d69 100644
--- a/pkg/kernel/lib/binary/ast_to_binary.dart
+++ b/pkg/kernel/lib/binary/ast_to_binary.dart
@@ -4,7 +4,6 @@
library kernel.ast_to_binary;
import 'dart:core' hide MapEntry;
-import 'dart:convert' show utf8;
import 'dart:developer';
import 'dart:io' show BytesBuilder;
import 'dart:typed_data';
@@ -105,9 +104,9 @@
(value >> 8) & 0xFF, value & 0xFF);
}
- void writeByteList(List<int> utf8Bytes) {
- writeUInt30(utf8Bytes.length);
- writeBytes(utf8Bytes);
+ void writeByteList(List<int> bytes) {
+ writeUInt30(bytes.length);
+ writeBytes(bytes);
}
int getBufferOffset() {
@@ -117,7 +116,7 @@
void writeStringTable(StringIndexer indexer) {
_binaryOffsetForStringTable = getBufferOffset();
- // Containers for the utf8 encoded strings.
+ // Containers for the WTF-8 encoded strings.
final List<Uint8List> data = new List<Uint8List>();
int totalLength = 0;
const int minLength = 1 << 16;
@@ -141,24 +140,13 @@
index = 0;
buffer = new Uint8List(newLength);
}
- newIndex = NotQuiteString.writeUtf8(buffer, index, key);
+ newIndex = _writeWtf8(buffer, index, key);
if (newIndex != -1) break;
requiredMinLength = allocateMinLength;
}
- if (newIndex < 0) {
- // Utf8 encoding failed.
- if (buffer != null && index > 0) {
- data.add(new Uint8List.view(buffer.buffer, 0, index));
- buffer = null;
- index = 0;
- }
- List<int> converted = utf8.encoder.convert(key);
- data.add(converted);
- totalLength += converted.length;
- } else {
- totalLength += newIndex - index;
- index = newIndex;
- }
+ assert(newIndex >= 0);
+ totalLength += newIndex - index;
+ index = newIndex;
}
writeUInt30(totalLength);
}
@@ -166,7 +154,7 @@
data.add(Uint8List.view(buffer.buffer, 0, index));
}
- // Write the UTF-8 encoded strings.
+ // Write the WTF-8 encoded strings.
for (int i = 0; i < data.length; ++i) {
writeBytes(data[i]);
}
@@ -586,9 +574,7 @@
if (strings != null) {
for (int i = 0; i < strings.length; i++) {
String s = strings[i];
- // This is slow, but we expect there to in general be no problems. If this
- // turns out to be wrong we can optimize it as we do URLs for instance.
- writeByteList(utf8.encoder.convert(s));
+ outputStringViaBuffer(s, new Uint8List(s.length * 3));
}
}
}
@@ -820,21 +806,16 @@
}
}
- void outputStringViaBuffer(String uriAsString, Uint8List buffer) {
- if (uriAsString.length * 3 < buffer.length) {
- int length = NotQuiteString.writeUtf8(buffer, 0, uriAsString);
- if (length < 0) {
- // Utf8 encoding failed.
- writeByteList(utf8.encoder.convert(uriAsString));
- } else {
- writeUInt30(length);
- for (int j = 0; j < length; j++) {
- writeByte(buffer[j]);
- }
+ void outputStringViaBuffer(String s, Uint8List buffer) {
+ int length = _writeWtf8(buffer, 0, s);
+ if (length >= 0) {
+ writeUInt30(length);
+ for (int j = 0; j < length; j++) {
+ writeByte(buffer[j]);
}
} else {
// Uncommon case with very long url.
- writeByteList(utf8.encoder.convert(uriAsString));
+ outputStringViaBuffer(s, new Uint8List(s.length * 3));
}
}
@@ -2758,63 +2739,58 @@
}
}
-class NotQuiteString {
- /**
- * Write [source] string into [target] starting at index [index].
- *
- * Optionally only write part of the input [source] starting at [start] and
- * ending at [end].
- *
- * The output space needed is at most [source.length] * 3.
- *
- * Returns
- * * Non-negative on success (the new index in [target]).
- * * -1 when [target] doesn't have enough space. Note that [target] can be
- * polluted starting at [index].
- * * -2 on input error, i.e. an unpaired lead or tail surrogate.
- */
- static int writeUtf8(List<int> target, int index, String source,
- [int start = 0, int end]) {
- RangeError.checkValidIndex(index, target, null, target.length);
- end = RangeError.checkValidRange(start, end, source.length);
- if (start == end) return index;
- int i = start;
- int length = target.length;
- do {
- int codeUnit = source.codeUnitAt(i++);
- while (codeUnit < 128) {
- if (index >= length) return -1;
- target[index++] = codeUnit;
- if (i >= end) return index;
- codeUnit = source.codeUnitAt(i++);
- }
- if (codeUnit < 0x800) {
- index += 2;
- if (index > length) return -1;
- target[index - 2] = 0xC0 | (codeUnit >> 6);
- target[index - 1] = 0x80 | (codeUnit & 0x3f);
- } else if (codeUnit & 0xF800 != 0xD800) {
- // Not a surrogate.
- index += 3;
- if (index > length) return -1;
- target[index - 3] = 0xE0 | (codeUnit >> 12);
- target[index - 2] = 0x80 | ((codeUnit >> 6) & 0x3f);
- target[index - 1] = 0x80 | (codeUnit & 0x3f);
- } else {
- if (codeUnit >= 0xDC00) return -2; // Unpaired tail surrogate.
- if (i >= end) return -2; // Unpaired lead surrogate.
- int nextChar = source.codeUnitAt(i++);
- if (nextChar & 0xFC00 != 0xDC00) return -2; // Unpaired lead surrogate.
- index += 4;
- if (index > length) return -1;
- codeUnit = (codeUnit & 0x3FF) + 0x40;
- target[index - 4] = 0xF0 | (codeUnit >> 8);
- target[index - 3] = 0x80 | ((codeUnit >> 2) & 0x3F);
- target[index - 2] =
- 0x80 | (((codeUnit & 3) << 4) | ((nextChar & 0x3FF) >> 6));
- target[index - 1] = 0x80 | (nextChar & 0x3f);
- }
- } while (i < end);
- return index;
- }
+/**
+ * Write [source] string into [target] starting at index [index].
+ *
+ * The output space needed is at most [source.length] * 3.
+ *
+ * Returns
+ * * Non-negative on success (the new index in [target]).
+ * * -1 when [target] doesn't have enough space. Note that [target] can be
+ * polluted starting at [index].
+ */
+int _writeWtf8(Uint8List target, int index, String source) {
+ int end = source.length;
+ if (end == 0) return index;
+ int length = target.length;
+ assert(index <= length);
+ int i = 0;
+ do {
+ int codeUnit = source.codeUnitAt(i++);
+ while (codeUnit < 128) {
+ // ASCII.
+ if (index >= length) return -1;
+ target[index++] = codeUnit;
+ if (i >= end) return index;
+ codeUnit = source.codeUnitAt(i++);
+ }
+ if (codeUnit < 0x800) {
+ // Two-byte sequence (11-bit unicode value).
+ index += 2;
+ if (index > length) return -1;
+ target[index - 2] = 0xC0 | (codeUnit >> 6);
+ target[index - 1] = 0x80 | (codeUnit & 0x3f);
+ } else if ((codeUnit & 0xFC00) == 0xD800 &&
+ i < end &&
+ (source.codeUnitAt(i) & 0xFC00) == 0xDC00) {
+ // Surrogate pair -> four-byte sequence (non-BMP unicode value).
+ index += 4;
+ if (index > length) return -1;
+ int codeUnit2 = source.codeUnitAt(i++);
+ int unicode = 0x10000 + ((codeUnit & 0x3FF) << 10) + (codeUnit2 & 0x3FF);
+ target[index - 4] = 0xF0 | (unicode >> 18);
+ target[index - 3] = 0x80 | ((unicode >> 12) & 0x3F);
+ target[index - 2] = 0x80 | ((unicode >> 6) & 0x3F);
+ target[index - 1] = 0x80 | (unicode & 0x3F);
+ } else {
+ // Three-byte sequence (16-bit unicode value), including lone
+ // surrogates.
+ index += 3;
+ if (index > length) return -1;
+ target[index - 3] = 0xE0 | (codeUnit >> 12);
+ target[index - 2] = 0x80 | ((codeUnit >> 6) & 0x3f);
+ target[index - 1] = 0x80 | (codeUnit & 0x3f);
+ }
+ } while (i < end);
+ return index;
}
diff --git a/pkg/kernel/lib/class_hierarchy.dart b/pkg/kernel/lib/class_hierarchy.dart
index d649729..8bbae44 100644
--- a/pkg/kernel/lib/class_hierarchy.dart
+++ b/pkg/kernel/lib/class_hierarchy.dart
@@ -204,8 +204,10 @@
///
/// Note, that it is the clients responsibility to mark all subclasses as
/// changed too.
+ // TODO(johnniwinther): Support class hierarchy changes directly. Currently
+ // we can handle added superclasses but not removed superclasses.
ClassHierarchy applyTreeChanges(Iterable<Library> removedLibraries,
- Iterable<Library> ensureKnownLibraries,
+ Iterable<Library> ensureKnownLibraries, Iterable<Class> updatedClasses,
{Component reissueAmbiguousSupertypesFor});
/// This method is invoked by the client after a member change on classes:
@@ -801,30 +803,61 @@
@override
ClassHierarchy applyTreeChanges(Iterable<Library> removedLibraries,
- Iterable<Library> ensureKnownLibraries,
+ Iterable<Library> ensureKnownLibraries, Iterable<Class> updatedClasses,
{Component reissueAmbiguousSupertypesFor}) {
+ Set<_ClassInfo> changedClasses = <_ClassInfo>{};
+
+ void removeClass(Class cls) {
+ _ClassInfo info = _infoMap[cls];
+ if (info == null) return;
+ if (cls.supertype != null) {
+ _infoMap[cls.supertype.classNode]?.directExtenders?.remove(info);
+ }
+ if (cls.mixedInType != null) {
+ _infoMap[cls.mixedInType.classNode]?.directMixers?.remove(info);
+ }
+ for (Supertype supertype in cls.implementedTypes) {
+ _infoMap[supertype.classNode]?.directImplementers?.remove(info);
+ // Remove from directMixers too as the mixin transformation will
+ // "move" the type here.
+ if (cls.isAnonymousMixin || cls.isEliminatedMixin) {
+ _infoMap[supertype.classNode]?.directMixers?.remove(info);
+ }
+ }
+ _infoMap.remove(cls);
+ _recordedAmbiguousSupertypes.remove(cls);
+ }
+
+ void invalidateClass(_ClassInfo info) {
+ if (info == null) return;
+ if (!changedClasses.add(info)) return;
+ if (info.directExtenders != null) {
+ for (_ClassInfo i in info.directExtenders.toList()) {
+ invalidateClass(i);
+ }
+ }
+ if (info.directMixers != null) {
+ for (_ClassInfo i in info.directMixers.toList()) {
+ invalidateClass(i);
+ }
+ }
+ if (info.directImplementers != null) {
+ for (_ClassInfo i in info.directImplementers.toList()) {
+ invalidateClass(i);
+ }
+ }
+ removeClass(info.classNode);
+ }
+
+ for (Class cls in updatedClasses) {
+ invalidateClass(_infoMap[cls]);
+ }
+
// Remove all references to the removed classes.
for (Library lib in removedLibraries) {
if (!knownLibraries.contains(lib)) continue;
for (Class class_ in lib.classes) {
- _ClassInfo info = _infoMap[class_];
- if (class_.supertype != null) {
- _infoMap[class_.supertype.classNode]?.directExtenders?.remove(info);
- }
- if (class_.mixedInType != null) {
- _infoMap[class_.mixedInType.classNode]?.directMixers?.remove(info);
- }
- for (Supertype supertype in class_.implementedTypes) {
- _infoMap[supertype.classNode]?.directImplementers?.remove(info);
- // Remove from directMixers too as the mixin transformation will
- // "move" the type here.
- if (class_.isAnonymousMixin || class_.isEliminatedMixin) {
- _infoMap[supertype.classNode]?.directMixers?.remove(info);
- }
- }
-
- _infoMap.remove(class_);
- _recordedAmbiguousSupertypes.remove(class_);
+ removeClass(class_);
}
knownLibraries.remove(lib);
}
@@ -860,6 +893,10 @@
}
knownLibraries.add(lib);
}
+ for (_ClassInfo info in changedClasses) {
+ _topologicalSortVisit(info.classNode, new Set<Class>(),
+ orderedList: addedClassesSorted);
+ }
_initializeTopologicallySortedClasses(
addedClassesSorted, expectedStartIndex);
diff --git a/pkg/kernel/lib/target/changed_structure_notifier.dart b/pkg/kernel/lib/target/changed_structure_notifier.dart
index d18c7de..e1b2c7f 100644
--- a/pkg/kernel/lib/target/changed_structure_notifier.dart
+++ b/pkg/kernel/lib/target/changed_structure_notifier.dart
@@ -7,6 +7,9 @@
/// Meant for notifying the backend (the compiler) that the structure has
/// changed, in turn allowing it to update its internal model.
abstract class ChangedStructureNotifier {
- /// Mark the class [c] as having changed in that its members have changed.
- void forClass(Class c);
+ /// Mark the members of class [cls] have changed.
+ void registerClassMemberChange(Class cls);
+
+ /// Mark that the class hierarchy for class [cls] has changed.
+ void registerClassHierarchyChange(Class cls);
}
diff --git a/pkg/kernel/lib/text/serializer_combinators.dart b/pkg/kernel/lib/text/serializer_combinators.dart
index 9a2dda6..30eb6a3 100644
--- a/pkg/kernel/lib/text/serializer_combinators.dart
+++ b/pkg/kernel/lib/text/serializer_combinators.dart
@@ -26,7 +26,7 @@
T addBinder(String name, T node) {
if (usedNames.contains(name)) {
- throw StateError("name '$name' is already declared in this scope");
+ throw StateError("Name '${name}' is already declared in this scope.");
}
usedNames.add(name);
return binders[name] = node;
@@ -115,7 +115,7 @@
String readFrom(Iterator<Object> stream, DeserializationState _) {
if (stream.current is! String) {
- throw StateError("expected an atom, found a list");
+ throw StateError("Expected an atom, found a list: '${stream.current}'.");
}
String result = json.decode(stream.current);
stream.moveNext();
@@ -132,7 +132,7 @@
int readFrom(Iterator<Object> stream, DeserializationState _) {
if (stream.current is! String) {
- throw StateError("expected an atom, found a list");
+ throw StateError("Expected an atom, found a list: '${stream.current}'.");
}
int result = int.parse(stream.current);
stream.moveNext();
@@ -149,7 +149,7 @@
double readFrom(Iterator<Object> stream, DeserializationState _) {
if (stream.current is! String) {
- throw StateError("expected an atom, found a list");
+ throw StateError("Expected an atom, found a list: '${stream.current}'.");
}
double result = double.parse(stream.current);
stream.moveNext();
@@ -166,7 +166,7 @@
bool readFrom(Iterator<Object> stream, DeserializationState _) {
if (stream.current is! String) {
- throw StateError("expected an atom, found a list");
+ throw StateError("Expected an atom, found a list: '${stream.current}'.");
}
bool result;
if (stream.current == "true") {
@@ -174,7 +174,7 @@
} else if (stream.current == "false") {
result = false;
} else {
- throw StateError("expected 'true' or 'false', found '${stream.current}'");
+ throw StateError("Expected 'true' or 'false', found '${stream.current}'");
}
stream.moveNext();
return result;
@@ -223,12 +223,12 @@
T readFrom(Iterator<Object> stream, DeserializationState state) {
if (stream.current is! Iterator) {
- throw StateError("expected list, found atom");
+ throw StateError("Expected list, found atom: '${stream.current}'.");
}
Iterator nested = stream.current;
nested.moveNext();
if (nested.current is! String) {
- throw StateError("expected atom, found list");
+ throw StateError("Expected atom, found list: '${nested.current}'.");
}
String tag = nested.current;
for (int i = 0; i < _tags.length; ++i) {
@@ -236,13 +236,14 @@
nested.moveNext();
T result = _serializers[i].readFrom(nested, state);
if (nested.moveNext()) {
- throw StateError("extra cruft in tagged '${tag}'");
+ throw StateError(
+ "Extra data in tagged '${tag}': '${nested.current}'.");
}
stream.moveNext();
return result;
}
}
- throw StateError("unrecognized tag '${tag}'");
+ throw StateError("Unrecognized tag '${tag}'.");
}
void writeTo(StringBuffer buffer, T object, SerializationState state) {
@@ -258,7 +259,7 @@
return;
}
}
- throw StateError("unrecognized tag '${tag}'");
+ throw StateError("Unrecognized tag '${tag}'.");
}
}
@@ -401,7 +402,7 @@
List<T> readFrom(Iterator<Object> stream, DeserializationState state) {
if (stream.current is! Iterator) {
- throw StateError("expected a list, found an atom");
+ throw StateError("Expected a list, found an atom: '${stream.current}'.");
}
Iterator<Object> list = stream.current;
list.moveNext();
diff --git a/pkg/kernel/lib/text/text_serialization_verifier.dart b/pkg/kernel/lib/text/text_serialization_verifier.dart
index 3f31c54..7d60bb7 100644
--- a/pkg/kernel/lib/text/text_serialization_verifier.dart
+++ b/pkg/kernel/lib/text/text_serialization_verifier.dart
@@ -55,21 +55,189 @@
}
class VerificationStatus {
+ final VerificationStatus parent;
+
final Node node;
- int childrenCount = 0;
- final List<Node> supportedChildren = [];
- VerificationStatus(this.node);
+ bool allChildrenAreSupported = true;
+ final List<Node> roundTripReadyNodes = [];
- bool isFullySupported(TextSerializationVerifier verifier) {
- return verifier.isSupported(node) &&
- childrenCount == supportedChildren.length;
+ final Set<VariableDeclaration> variableDeclarations =
+ new Set<VariableDeclaration>.identity();
+ final Set<TypeParameter> typeParameters = new Set<TypeParameter>.identity();
+
+ final Set<VariableDeclaration> usedVariables =
+ new Set<VariableDeclaration>.identity();
+ final Set<TypeParameter> usedTypeParameters =
+ new Set<TypeParameter>.identity();
+
+ VerificationStatus(this.parent, this.node);
+
+ bool get isRoot => parent == null;
+
+ bool get isFullySupported => isSupported(node) && allChildrenAreSupported;
+
+ bool get hasSufficientScope {
+ return usedVariables.every((v) => variableDeclarations.contains(v)) &&
+ usedTypeParameters.every((p) => typeParameters.contains(p));
}
- void addChild(Node child, bool isSupported) {
- ++childrenCount;
- if (isSupported) supportedChildren.add(child);
+ bool get isRoundTripReady => isFullySupported && hasSufficientScope;
+
+ bool isVariableDeclared(VariableDeclaration node) {
+ return variableDeclarations.contains(node) ||
+ !isRoot && parent.isVariableDeclared(node);
}
+
+ bool isTypeParameterDeclared(TypeParameter node) {
+ return typeParameters.contains(node) ||
+ !isRoot && parent.isTypeParameterDeclared(node);
+ }
+
+ void handleChild(VerificationStatus childStatus) {
+ allChildrenAreSupported =
+ allChildrenAreSupported && childStatus.isFullySupported;
+ }
+
+ void handleDeclarations() {
+ Node node = this.node;
+ if (node is VariableDeclaration) {
+ parent.variableDeclarations.add(node);
+ }
+ if (node is TypeParameter) {
+ parent.typeParameters.add(node);
+ }
+ if (node is VariableGet) {
+ usedVariables.add(node.variable);
+ }
+ if (node is VariableSet) {
+ usedVariables.add(node.variable);
+ }
+ if (node is TypeParameterType) {
+ usedTypeParameters.add(node.parameter);
+ }
+ }
+
+ /// Computes round-trip ready nodes or propagates them further in the stack.
+ ///
+ /// The returned nodes are the roots of maximal-by-inclusion subtrees that are
+ /// ready for the round-trip textual serialization.
+ List<Node> takeRoundTripReadyNodes() {
+ if (isRoot) {
+ // If the node is the root of the AST and is round-trip ready, return just
+ // the root because it's maximal-by-inclusion.
+ // Otherwise, return the nodes collected so far.
+ List<Node> result =
+ isRoundTripReady ? <Node>[node] : roundTripReadyNodes.toList();
+ roundTripReadyNodes.clear();
+ return result;
+ }
+
+ // The algorithm in this branch is based on the following observations:
+ // - The isFullySupported property is monotonous. That is, when traveling
+ // from a leaf to the root, the property may only change its value from
+ // true to false.
+ // - The isRoundTripReady property is not monotonous because the sub-tree
+ // that is ready for the round trip shouldn't contain free variables or
+ // free type parameters.
+ // - The isRoundTripReady property implies the isFullySupported property.
+
+ if (!isFullySupported) {
+ // We're out of the isFullySupported sub-tree, run the round trip on the
+ // nodes that are ready for it so far -- they are maximal-by-inclusion by
+ // construction.
+ List<Node> result = roundTripReadyNodes.toList();
+ roundTripReadyNodes.clear();
+ return result;
+ } else {
+ // We're still in the isFullySupported sub-tree. It's to early to decide
+ // if the collected sub-trees or the node itself are maximal-by-inclusion.
+ // The decision should be made in one of the parent nodes. So, we just
+ // propagate the information to the parent, returning an empty list for
+ // the current node.
+ if (isRoundTripReady) {
+ // The current tree is ready for the round trip. Its sub-trees, which
+ // are also round-trip ready, are not maximal-by-inclusion. So only the
+ // node itself is passed to the parent.
+ parent.roundTripReadyNodes.add(node);
+ } else {
+ // The node is not round-trip ready. The round-trip ready sub-trees
+ // collected so far remain the candidates for being
+ // maximal-by-inclusion.
+ parent.roundTripReadyNodes.addAll(roundTripReadyNodes);
+ }
+ return const <Node>[];
+ }
+ }
+
+ /// Passes the necessary information to the parent when popped from the stack.
+ void mergeToParent() {
+ // Pass the free occurrences of variables and type parameters to the parent.
+ if (parent != null) {
+ parent.usedVariables
+ .addAll(usedVariables.difference(variableDeclarations));
+ parent.usedTypeParameters
+ .addAll(usedTypeParameters.difference(typeParameters));
+ parent.handleChild(this);
+ }
+ }
+
+ static bool isDartTypeSupported(DartType node) =>
+ node is InvalidType ||
+ node is DynamicType ||
+ node is VoidType ||
+ node is BottomType ||
+ node is FunctionType ||
+ node is TypeParameterType;
+
+ static bool isExpressionSupported(Expression node) =>
+ node is StringLiteral ||
+ node is SymbolLiteral ||
+ node is IntLiteral ||
+ node is DoubleLiteral ||
+ node is BoolLiteral ||
+ node is NullLiteral ||
+ node is ListLiteral ||
+ node is SetLiteral ||
+ node is MapLiteral ||
+ node is TypeLiteral ||
+ node is InvalidExpression ||
+ node is Not ||
+ node is LogicalExpression ||
+ node is StringConcatenation ||
+ node is ThisExpression ||
+ node is Rethrow ||
+ node is Throw ||
+ node is AwaitExpression ||
+ node is ConditionalExpression ||
+ node is IsExpression ||
+ node is AsExpression ||
+ node is Let ||
+ node is PropertyGet ||
+ node is PropertySet ||
+ node is SuperPropertyGet ||
+ node is SuperPropertySet ||
+ node is MethodInvocation ||
+ node is SuperMethodInvocation ||
+ node is VariableGet ||
+ node is VariableSet ||
+ node is StaticGet ||
+ node is StaticSet ||
+ node is DirectPropertyGet ||
+ node is DirectPropertySet ||
+ node is StaticInvocation ||
+ node is DirectMethodInvocation ||
+ node is ConstructorInvocation ||
+ node is FunctionExpression;
+
+ static bool isStatementSupported(Statement node) =>
+ node is ExpressionStatement ||
+ node is ReturnStatement && node.expression != null;
+
+ static bool isSupported(Node node) =>
+ node is DartType && isDartTypeSupported(node) ||
+ node is Expression && isExpressionSupported(node) ||
+ node is Statement && isStatementSupported(node);
}
class TextSerializationVerifier extends RecursiveVisitor<void> {
@@ -87,61 +255,52 @@
int lastSeenOffset = noOffset;
- List<VerificationStatus> _statusStack = [];
+ VerificationStatus _statusStackTop;
TextSerializationVerifier({CanonicalName root})
: root = root ?? new CanonicalName.root() {
initializeSerializers();
}
- bool get isRoot => _statusStack.isEmpty;
+ VerificationStatus get currentStatus => _statusStackTop;
- VerificationStatus get currentStatus => _statusStack.last;
-
- void pushStatus(VerificationStatus status) {
- _statusStack.add(status);
+ void pushStatusFor(Node node) {
+ _statusStackTop = new VerificationStatus(_statusStackTop, node);
}
- VerificationStatus popStatus() {
- return _statusStack.removeLast();
+ void dropStatus() {
+ if (_statusStackTop == null) {
+ throw new StateError(
+ "Attempting to remove a status from an empty status stack.");
+ }
+ _statusStackTop = _statusStackTop.parent;
}
- void verify(Node node) {}
+ void verify(Node node) => node.accept(this);
void defaultNode(Node node) {
enterNode(node);
node.visitChildren(this);
- bool isFullySupported = exitNode(node);
- if (isFullySupported) {
- if (node is DartType) {
- makeRoundTrip<DartType>(node, dartTypeSerializer);
- } else if (node is Expression) {
- makeRoundTrip<Expression>(node, expressionSerializer);
- } else if (node is Statement) {
- makeRoundTrip<Statement>(node, statementSerializer);
- } else {
- throw new StateError(
- "Don't know how to make a round trip for a supported node '${node.runtimeType}'");
- }
- }
+ exitNode(node);
}
void enterNode(node) {
storeLastSeenUriAndOffset(node);
- pushStatus(new VerificationStatus(node));
+ pushStatusFor(node);
+ currentStatus.handleDeclarations();
}
- bool exitNode(node) {
+ void exitNode(node) {
if (!identical(node, currentStatus.node)) {
throw new StateError("Trying to remove node '${node}' from the stack, "
"while another node '${currentStatus.node}' is on the top of it.");
}
- VerificationStatus status = popStatus();
- bool isFullySupported = status.isFullySupported(this);
- if (!isRoot) {
- currentStatus.addChild(node, isFullySupported);
+ List<Node> roundTripReadyNodes = currentStatus.takeRoundTripReadyNodes();
+ for (Node node in roundTripReadyNodes) {
+ makeRoundTripDispatch(node);
}
- return isFullySupported;
+ currentStatus.mergeToParent();
+ dropStatus();
}
void storeLastSeenUriAndOffset(Node node) {
@@ -193,14 +352,30 @@
return buffer.toString();
}
- void makeRoundTrip<T extends Node>(T node, TextSerializer<T> serializer) {
+ RoundTripStatus makeRoundTripDispatch(Node node) {
+ if (node is DartType) {
+ return makeRoundTrip<DartType>(node, dartTypeSerializer);
+ } else if (node is Expression) {
+ return makeRoundTrip<Expression>(node, expressionSerializer);
+ } else if (node is Statement) {
+ return makeRoundTrip<Statement>(node, statementSerializer);
+ } else {
+ throw new StateError(
+ "Don't know how to make a round trip for a supported node '${node.runtimeType}'");
+ }
+ }
+
+ RoundTripStatus makeRoundTrip<T extends Node>(
+ T node, TextSerializer<T> serializer) {
String initial = writeNode(node, serializer, lastSeenUri, lastSeenOffset);
// Do the round trip.
T deserialized = readNode(initial, serializer, lastSeenUri, lastSeenOffset);
// The error is reported elsewhere for the case of null.
- if (deserialized == null) return;
+ if (deserialized == null) {
+ return new RoundTripStatus(false, initial);
+ }
String serialized =
writeNode(deserialized, serializer, lastSeenUri, lastSeenOffset);
@@ -208,62 +383,15 @@
if (initial != serialized) {
failures.add(new TextRoundTripFailure(
initial, serialized, lastSeenUri, lastSeenOffset));
+ return new RoundTripStatus(false, initial);
}
+ return new RoundTripStatus(true, initial);
}
+}
- bool isDartTypeSupported(DartType node) =>
- node is InvalidType ||
- node is DynamicType ||
- node is VoidType ||
- node is BottomType ||
- node is FunctionType ||
- node is TypeParameterType;
+class RoundTripStatus {
+ final bool successful;
+ final String serialized;
- bool isExpressionSupported(Expression node) =>
- node is StringLiteral ||
- node is SymbolLiteral ||
- node is IntLiteral ||
- node is DoubleLiteral ||
- node is BoolLiteral ||
- node is NullLiteral ||
- node is ListLiteral ||
- node is SetLiteral ||
- node is MapLiteral ||
- node is TypeLiteral ||
- node is InvalidExpression ||
- node is Not ||
- node is LogicalExpression ||
- node is StringConcatenation ||
- node is ThisExpression ||
- node is Rethrow ||
- node is Throw ||
- node is AwaitExpression ||
- node is ConditionalExpression ||
- node is IsExpression ||
- node is AsExpression ||
- node is Let ||
- node is PropertyGet ||
- node is PropertySet ||
- node is SuperPropertyGet ||
- node is SuperPropertySet ||
- node is MethodInvocation ||
- node is SuperMethodInvocation ||
- node is VariableGet ||
- node is VariableSet ||
- node is StaticGet ||
- node is StaticSet ||
- node is DirectPropertyGet ||
- node is DirectPropertySet ||
- node is StaticInvocation ||
- node is DirectMethodInvocation ||
- node is ConstructorInvocation ||
- node is FunctionExpression;
-
- bool isStatementSupported(Statement node) =>
- node is ExpressionStatement || node is ReturnStatement;
-
- bool isSupported(Node node) =>
- node is DartType && isDartTypeSupported(node) ||
- node is Expression && isExpressionSupported(node) ||
- node is Statement && isStatementSupported(node);
+ RoundTripStatus(this.successful, this.serialized);
}
diff --git a/pkg/kernel/lib/text/text_serializer.dart b/pkg/kernel/lib/text/text_serializer.dart
index 02dd86e..1b8ddd4 100644
--- a/pkg/kernel/lib/text/text_serializer.dart
+++ b/pkg/kernel/lib/text/text_serializer.dart
@@ -37,7 +37,7 @@
Name wrapPrivateName(Tuple2<String, String> tuple) {
// We need a map from import URI to libraries. More generally, we will need
// a way to map any 'named' node to the node's reference.
- throw UnimplementedError('deserialization of private names');
+ throw UnimplementedError('Deserialization of private names.');
}
TextSerializer<Name> nameSerializer = new Case(
@@ -738,8 +738,8 @@
const VariableDeclarationTagger();
String tag(VariableDeclaration decl) {
- if (decl.isCovariant) throw UnimplementedError("covariant declaration");
- if (decl.isFieldFormal) throw UnimplementedError("initializing formal");
+ if (decl.isCovariant) throw UnimplementedError("Covariant declaration.");
+ if (decl.isFieldFormal) throw UnimplementedError("Initializing formal.");
if (decl.isConst) {
// It's not clear what invariants we assume about const/final. For now
// throw if we have both.
diff --git a/pkg/kernel/lib/transformations/track_widget_constructor_locations.dart b/pkg/kernel/lib/transformations/track_widget_constructor_locations.dart
index 44a7285..3a0bc0dd 100644
--- a/pkg/kernel/lib/transformations/track_widget_constructor_locations.dart
+++ b/pkg/kernel/lib/transformations/track_widget_constructor_locations.dart
@@ -7,6 +7,7 @@
import 'package:meta/meta.dart';
import '../ast.dart';
+import '../target/changed_structure_notifier.dart';
// Parameter name used to track were widget constructor calls were made from.
//
@@ -309,11 +310,13 @@
Class _widgetClass;
Class _locationClass;
+ final ChangedStructureNotifier _changedStructureNotifier;
+
/// Marker interface indicating that a private _location field is
/// available.
Class _hasCreationLocationClass;
- WidgetCreatorTracker();
+ WidgetCreatorTracker(this._changedStructureNotifier);
void _resolveFlutterClasses(Iterable<Library> libraries) {
// If the Widget or Debug location classes have been updated we need to get
@@ -358,6 +361,8 @@
}
clazz.implementedTypes
.add(new Supertype(_hasCreationLocationClass, <DartType>[]));
+ _changedStructureNotifier?.registerClassHierarchyChange(clazz);
+
// We intentionally use the library context of the _HasCreationLocation
// class for the private field even if [clazz] is in a different library
// so that all classes implementing Widget behave consistently.
diff --git a/pkg/kernel/lib/type_algebra.dart b/pkg/kernel/lib/type_algebra.dart
index 5af2a2d..fbe87af 100644
--- a/pkg/kernel/lib/type_algebra.dart
+++ b/pkg/kernel/lib/type_algebra.dart
@@ -475,6 +475,7 @@
DartType visit(DartType node) => node.accept(this);
+ DartType defaultDartType(DartType node) => node;
DartType visitInvalidType(InvalidType node) => node;
DartType visitDynamicType(DynamicType node) => node;
DartType visitVoidType(VoidType node) => node;
diff --git a/pkg/kernel/test/class_hierarchy_test.dart b/pkg/kernel/test/class_hierarchy_test.dart
index 17c380a..3f6d770 100644
--- a/pkg/kernel/test/class_hierarchy_test.dart
+++ b/pkg/kernel/test/class_hierarchy_test.dart
@@ -118,7 +118,7 @@
''');
// No updated classes, the same hierarchy.
- expect(hierarchy.applyTreeChanges([], []), same(hierarchy));
+ expect(hierarchy.applyTreeChanges([], [], []), same(hierarchy));
// Has updated classes, still the same hierarchy (instance). Can answer
// queries about the new classes.
@@ -129,12 +129,13 @@
component.libraries.add(libWithC);
libWithC.addClass(c);
- expect(hierarchy.applyTreeChanges([libWithB], [libWithC]), same(hierarchy));
+ expect(hierarchy.applyTreeChanges([libWithB], [libWithC], []),
+ same(hierarchy));
expect(hierarchy.isSubclassOf(a, c), false);
expect(hierarchy.isSubclassOf(c, a), true);
// Remove so A should no longer be a super of anything.
- expect(hierarchy.applyTreeChanges([libWithC], []), same(hierarchy));
+ expect(hierarchy.applyTreeChanges([libWithC], [], []), same(hierarchy));
}
void test_applyMemberChanges() {
diff --git a/pkg/native_stack_traces/CHANGELOG.md b/pkg/native_stack_traces/CHANGELOG.md
index 222b0d9..0d1a91d 100644
--- a/pkg/native_stack_traces/CHANGELOG.md
+++ b/pkg/native_stack_traces/CHANGELOG.md
@@ -1,5 +1,18 @@
# Changelog
+## 0.3.4
+
+- Decoded Dart calls are now never considered internal, only VM stub calls.
+ This is due to a concurrent change in the Dart VM that no longer prints
+ non-symbolic frames for functions considered invisible, which matches the
+ symbolic frame printer and removes the need for the decoder to guess which
+ frames should be hidden.
+
+ This package still works on earlier versions of Dart, so the dependencies have
+ not changed. However, it may print more frame information than expected when
+ decoding stack frames from a Dart VM that does not include this change to
+ non-symbolic stack printing.
+
## 0.3.3
- No externally visible changes.
diff --git a/pkg/native_stack_traces/lib/src/dwarf.dart b/pkg/native_stack_traces/lib/src/dwarf.dart
index 0b20555..a6e842e 100644
--- a/pkg/native_stack_traces/lib/src/dwarf.dart
+++ b/pkg/native_stack_traces/lib/src/dwarf.dart
@@ -1058,7 +1058,7 @@
DartCallInfo({this.inlined = false, this.function, this.filename, this.line});
@override
- bool get isInternal => line <= 0;
+ bool get isInternal => false;
@override
int get hashCode => _hashFinish(_hashCombine(
@@ -1079,8 +1079,7 @@
}
@override
- String toString() =>
- "${function} (${filename}:${isInternal ? "??" : line.toString()})";
+ String toString() => "${function} (${filename}${line <= 0 ? '' : ':$line'})";
}
/// Represents the information for a call site located in a Dart stub.
@@ -1225,10 +1224,7 @@
{bool includeInternalFrames = false}) {
var calls = _debugInfo.callInfo(_lineNumberInfo, address);
if (calls == null) {
- // Since we're dealing with return addresses in stack frames, subtract
- // one in case the return address is just off the end of the stub (since
- // the calling instruction is before the return address).
- final symbol = _elf.staticSymbolAt(address - 1);
+ final symbol = _elf.staticSymbolAt(address);
if (symbol != null) {
final offset = address - symbol.value;
calls = <CallInfo>[StubCallInfo(name: symbol.name, offset: offset)];
diff --git a/pkg/native_stack_traces/lib/src/elf.dart b/pkg/native_stack_traces/lib/src/elf.dart
index 6b4e305..cee46f0 100644
--- a/pkg/native_stack_traces/lib/src/elf.dart
+++ b/pkg/native_stack_traces/lib/src/elf.dart
@@ -719,7 +719,7 @@
/// A table of (static or dynamic) [Symbol]s.
class SymbolTable extends Section {
final List<Symbol> _entries;
- final _nameCache;
+ final Map<String, Symbol> _nameCache;
SymbolTable._(SectionHeaderEntry entry, this._entries)
: _nameCache = {},
diff --git a/pkg/native_stack_traces/pubspec.yaml b/pkg/native_stack_traces/pubspec.yaml
index b0aa7df..c7f8f15 100644
--- a/pkg/native_stack_traces/pubspec.yaml
+++ b/pkg/native_stack_traces/pubspec.yaml
@@ -1,6 +1,6 @@
name: native_stack_traces
description: Utilities for working with non-symbolic stack traces.
-version: 0.3.3
+version: 0.3.4
homepage: https://github.com/dart-lang/sdk/tree/master/pkg/native_stack_traces
diff --git a/pkg/nnbd_migration/.gitignore b/pkg/nnbd_migration/.gitignore
new file mode 100644
index 0000000..7138b41
--- /dev/null
+++ b/pkg/nnbd_migration/.gitignore
@@ -0,0 +1,3 @@
+lib/src/front_end/resources/*.js.deps
+lib/src/front_end/resources/*.js.map
+lib/src/front_end/resources/migration.js
diff --git a/pkg/nnbd_migration/lib/api_for_analysis_server/dartfix_listener_interface.dart b/pkg/nnbd_migration/lib/api_for_analysis_server/dartfix_listener_interface.dart
new file mode 100644
index 0000000..c2505a2
--- /dev/null
+++ b/pkg/nnbd_migration/lib/api_for_analysis_server/dartfix_listener_interface.dart
@@ -0,0 +1,36 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer_plugin/protocol/protocol_common.dart';
+import 'package:nnbd_migration/api_for_analysis_server/driver_provider.dart';
+
+abstract class DartFixListenerInterface {
+ DriverProvider get server;
+
+ SourceChange get sourceChange;
+
+ /// Add the given [detail] to the list of details to be returned to the
+ /// client.
+ void addDetail(String detail);
+
+ /// Record an edit to be sent to the client.
+ ///
+ /// The associated suggestion should be separately added by calling
+ /// [addSuggestion].
+ void addEditWithoutSuggestion(Source source, SourceEdit edit);
+
+ /// Record a recommendation to be sent to the client.
+ void addRecommendation(String description, [Location location]);
+
+ /// Record a source change to be sent to the client.
+ void addSourceFileEdit(
+ String description, Location location, SourceFileEdit fileEdit);
+
+ /// Record a suggestion to be sent to the client.
+ ///
+ /// The associated edits should be separately added by calling
+ /// [addEditWithoutRecommendation].
+ void addSuggestion(String description, Location location);
+}
diff --git a/pkg/nnbd_migration/lib/api_for_analysis_server/driver_provider.dart b/pkg/nnbd_migration/lib/api_for_analysis_server/driver_provider.dart
new file mode 100644
index 0000000..2079378
--- /dev/null
+++ b/pkg/nnbd_migration/lib/api_for_analysis_server/driver_provider.dart
@@ -0,0 +1,14 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analyzer/dart/analysis/session.dart';
+import 'package:analyzer/file_system/file_system.dart';
+
+abstract class DriverProvider {
+ ResourceProvider get resourceProvider;
+
+ /// Return the appropriate analysis session for the file with the given
+ /// [path].
+ AnalysisSession getAnalysisSession(String path);
+}
diff --git a/pkg/nnbd_migration/lib/api_for_analysis_server/http_preview_server.dart b/pkg/nnbd_migration/lib/api_for_analysis_server/http_preview_server.dart
new file mode 100644
index 0000000..4a409a01
--- /dev/null
+++ b/pkg/nnbd_migration/lib/api_for_analysis_server/http_preview_server.dart
@@ -0,0 +1,6 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+export 'package:nnbd_migration/src/preview/http_preview_server.dart'
+ show HttpPreviewServer;
diff --git a/pkg/nnbd_migration/lib/api_for_analysis_server/instrumentation_listener.dart b/pkg/nnbd_migration/lib/api_for_analysis_server/instrumentation_listener.dart
new file mode 100644
index 0000000..dc2785e
--- /dev/null
+++ b/pkg/nnbd_migration/lib/api_for_analysis_server/instrumentation_listener.dart
@@ -0,0 +1,6 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+export 'package:nnbd_migration/src/front_end/instrumentation_listener.dart'
+ show InstrumentationListener;
diff --git a/pkg/nnbd_migration/lib/api_for_analysis_server/migration_state.dart b/pkg/nnbd_migration/lib/api_for_analysis_server/migration_state.dart
new file mode 100644
index 0000000..dabbeed
--- /dev/null
+++ b/pkg/nnbd_migration/lib/api_for_analysis_server/migration_state.dart
@@ -0,0 +1,6 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+export 'package:nnbd_migration/src/front_end/migration_state.dart'
+ show MigrationState;
diff --git a/pkg/nnbd_migration/lib/api_for_analysis_server/nnbd_migration.dart b/pkg/nnbd_migration/lib/api_for_analysis_server/nnbd_migration.dart
new file mode 100644
index 0000000..e888dfc
--- /dev/null
+++ b/pkg/nnbd_migration/lib/api_for_analysis_server/nnbd_migration.dart
@@ -0,0 +1,6 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+export 'package:nnbd_migration/nnbd_migration.dart'
+ show NullabilityMigration, NullabilityMigrationListener;
diff --git a/pkg/nnbd_migration/lib/nnbd_migration.dart b/pkg/nnbd_migration/lib/nnbd_migration.dart
index 8e2da63..c8670c0 100644
--- a/pkg/nnbd_migration/lib/nnbd_migration.dart
+++ b/pkg/nnbd_migration/lib/nnbd_migration.dart
@@ -17,6 +17,10 @@
/// Description of fixes that might be performed by nullability migration.
class NullabilityFixDescription {
+ /// A variable declaration needs to be marked as "late".
+ static const addLate = const NullabilityFixDescription._(
+ appliedMessage: 'Added a late keyword', kind: NullabilityFixKind.addLate);
+
/// A variable declaration needs to be marked as "late" due to the presence of
/// a `/*late*/` hint.
static const addLateDueToHint = const NullabilityFixDescription._(
@@ -200,6 +204,7 @@
/// An enumeration of the various kinds of nullability fixes.
enum NullabilityFixKind {
+ addLate,
addLateDueToHint,
addRequired,
addType,
diff --git a/pkg/nnbd_migration/lib/src/fix_aggregator.dart b/pkg/nnbd_migration/lib/src/fix_aggregator.dart
index 7c37739..bedc3f5 100644
--- a/pkg/nnbd_migration/lib/src/fix_aggregator.dart
+++ b/pkg/nnbd_migration/lib/src/fix_aggregator.dart
@@ -707,8 +707,12 @@
/// that should be added. Otherwise `null`.
DartType addExplicitType;
- /// If a "late" annotation should be added to this variable declaration, the
- /// hint that caused it. Otherwise `null`.
+ /// Indicates whether a "late" annotation should be added to this variable
+ /// declaration, caused by inference.
+ bool addLate = false;
+
+ /// If a "late" annotation should be added to this variable declaration, and
+ /// the cause is a "late" hint, the hint that caused it. Otherwise `null`.
HintComment lateHint;
NodeChangeForVariableDeclarationList() : super._();
@@ -716,6 +720,13 @@
@override
EditPlan _apply(VariableDeclarationList node, FixAggregator aggregator) {
List<EditPlan> innerPlans = [];
+ if (addLate) {
+ var info = AtomicEditInfo(NullabilityFixDescription.addLate, {});
+ innerPlans.add(aggregator.planner.insertText(
+ node,
+ node.firstTokenAfterCommentAndMetadata.offset,
+ [AtomicEdit.insert('late', info: info), AtomicEdit.insert(' ')]));
+ }
if (addExplicitType != null) {
var typeText = addExplicitType.getDisplayString(withNullability: true);
if (node.keyword?.keyword == Keyword.VAR) {
diff --git a/pkg/nnbd_migration/lib/src/fix_builder.dart b/pkg/nnbd_migration/lib/src/fix_builder.dart
index 0bc3fd1..76732f9 100644
--- a/pkg/nnbd_migration/lib/src/fix_builder.dart
+++ b/pkg/nnbd_migration/lib/src/fix_builder.dart
@@ -684,6 +684,24 @@
}
}
}
+
+ // Check if the nullability node for a single variable declaration has been
+ // declared to be late.
+ var lateNeeded = false;
+ if (node.variables.length == 1) {
+ var variableElement = node.variables.single.declaredElement;
+ if (_fixBuilder._variables
+ .decoratedElementType(variableElement)
+ .node
+ .isLate) {
+ lateNeeded = true;
+ }
+ }
+ if (lateNeeded) {
+ (_fixBuilder._getChange(node) as NodeChangeForVariableDeclarationList)
+ .addLate = true;
+ }
+
var lateHint = _fixBuilder._variables.getLateHint(source, node);
if (lateHint != null) {
(_fixBuilder._getChange(node) as NodeChangeForVariableDeclarationList)
diff --git a/pkg/analysis_server/lib/src/edit/nnbd_migration/info_builder.dart b/pkg/nnbd_migration/lib/src/front_end/info_builder.dart
similarity index 92%
rename from pkg/analysis_server/lib/src/edit/nnbd_migration/info_builder.dart
rename to pkg/nnbd_migration/lib/src/front_end/info_builder.dart
index 69506b5..e436326 100644
--- a/pkg/analysis_server/lib/src/edit/nnbd_migration/info_builder.dart
+++ b/pkg/nnbd_migration/lib/src/front_end/info_builder.dart
@@ -4,13 +4,6 @@
import 'dart:collection';
-import 'package:analysis_server/src/analysis_server.dart';
-import 'package:analysis_server/src/domains/analysis/navigation_dart.dart';
-import 'package:analysis_server/src/edit/fix/dartfix_listener.dart';
-import 'package:analysis_server/src/edit/fix/non_nullable_fix.dart';
-import 'package:analysis_server/src/edit/nnbd_migration/instrumentation_information.dart';
-import 'package:analysis_server/src/edit/nnbd_migration/migration_info.dart';
-import 'package:analysis_server/src/edit/nnbd_migration/offset_mapper.dart';
import 'package:analyzer/dart/analysis/results.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/file_system/file_system.dart';
@@ -18,11 +11,17 @@
show SourceFileEdit;
import 'package:analyzer_plugin/protocol/protocol_common.dart' as protocol;
import 'package:analyzer_plugin/src/utilities/navigation/navigation.dart';
+import 'package:analyzer_plugin/utilities/navigation/navigation_dart.dart';
import 'package:meta/meta.dart';
+import 'package:nnbd_migration/api_for_analysis_server/dartfix_listener_interface.dart';
+import 'package:nnbd_migration/api_for_analysis_server/driver_provider.dart';
import 'package:nnbd_migration/fix_reason_target.dart';
import 'package:nnbd_migration/instrumentation.dart';
import 'package:nnbd_migration/nnbd_migration.dart';
import 'package:nnbd_migration/src/edit_plan.dart';
+import 'package:nnbd_migration/src/front_end/instrumentation_information.dart';
+import 'package:nnbd_migration/src/front_end/migration_info.dart';
+import 'package:nnbd_migration/src/front_end/offset_mapper.dart';
/// A builder used to build the migration information for a library.
class InfoBuilder {
@@ -36,10 +35,7 @@
final InstrumentationInformation info;
/// The listener used to gather the changes to be applied.
- final DartFixListener listener;
-
- /// The dartfix adapter, which can be used to report exceptions that occur.
- final NullabilityMigrationAdapter adapter;
+ final DartFixListenerInterface listener;
/// The [NullabilityMigration] instance for this migration.
final NullabilityMigration migration;
@@ -50,10 +46,10 @@
/// Initialize a newly created builder.
InfoBuilder(this.provider, this.includedPath, this.info, this.listener,
- this.adapter, this.migration);
+ this.migration);
- /// The analysis server used to get information about libraries.
- AnalysisServer get server => listener.server;
+ /// The provider used to get information about libraries.
+ DriverProvider get driverProvider => listener.server;
/// Return the migration information for all of the libraries that were
/// migrated.
@@ -63,7 +59,7 @@
SplayTreeSet<UnitInfo>((u1, u2) => u1.path.compareTo(u2.path));
for (var source in sourceInfoMap.keys) {
var filePath = source.fullName;
- var session = server.getAnalysisDriver(filePath).currentSession;
+ var session = driverProvider.getAnalysisSession(filePath);
if (!session.getFile(filePath).isPart) {
var result = await session.getResolvedLibrary(filePath);
for (var unitResult in result.units) {
@@ -185,6 +181,10 @@
edits.add(_removeHint('Remove /*!*/ hint'));
edits.add(_changeHint('Change to /*?*/ hint', '/*?*/'));
break;
+ case NullabilityFixKind.addLate:
+ // We could add an edit to add a `/*?*/` hint, but the offset is a
+ // little tricky.
+ break;
case NullabilityFixKind.nullAwarenessUnnecessaryInStrongMode:
case NullabilityFixKind.conditionTrueInStrongMode:
case NullabilityFixKind.conditionFalseInStrongMode:
@@ -322,9 +322,11 @@
var info = edit.info;
var edits = info != null
? _computeEdits(info, sourceOffset, result.content)
- : [];
+ : <EditDetail>[];
var lineNumber = lineInfo.getLocation(sourceOffset).lineNumber;
- var traces = info == null ? const [] : _computeTraces(info.fixReasons);
+ var traces = info == null
+ ? const <TraceInfo>[]
+ : _computeTraces(info.fixReasons);
var description = info?.description;
var hint = info?.hintComment;
var isCounted = hint == null || hintsSeen.add(hint);
@@ -435,10 +437,14 @@
if (enclosingNode is ConstructorDeclaration) {
if (enclosingNode.name == null) {
return _describeClassOrExtensionMember(
- enclosingNode.parent, 'the default constructor of', '');
+ enclosingNode.parent as CompilationUnitMember,
+ 'the default constructor of',
+ '');
} else {
return _describeClassOrExtensionMember(
- enclosingNode.parent, 'the constructor', enclosingNode.name.name);
+ enclosingNode.parent as CompilationUnitMember,
+ 'the constructor',
+ enclosingNode.name.name);
}
} else if (enclosingNode is MethodDeclaration) {
var functionName = enclosingNode.name.name;
@@ -454,7 +460,9 @@
baseDescription = 'the method';
}
return _describeClassOrExtensionMember(
- enclosingNode.parent, baseDescription, functionName);
+ enclosingNode.parent as CompilationUnitMember,
+ baseDescription,
+ functionName);
} else if (enclosingNode is FunctionDeclaration &&
enclosingNode.parent is CompilationUnit) {
var functionName = enclosingNode.name.name;
@@ -511,7 +519,9 @@
var grandParent = parent.parent;
if (grandParent is FieldDeclaration) {
return _describeClassOrExtensionMember(
- grandParent.parent, 'the field', variableName);
+ grandParent.parent as CompilationUnitMember,
+ 'the field',
+ variableName);
} else if (grandParent is TopLevelVariableDeclaration) {
return "the variable '$variableName'";
} else {
diff --git a/pkg/analysis_server/lib/src/edit/nnbd_migration/instrumentation_information.dart b/pkg/nnbd_migration/lib/src/front_end/instrumentation_information.dart
similarity index 100%
rename from pkg/analysis_server/lib/src/edit/nnbd_migration/instrumentation_information.dart
rename to pkg/nnbd_migration/lib/src/front_end/instrumentation_information.dart
diff --git a/pkg/analysis_server/lib/src/edit/nnbd_migration/instrumentation_listener.dart b/pkg/nnbd_migration/lib/src/front_end/instrumentation_listener.dart
similarity index 97%
rename from pkg/analysis_server/lib/src/edit/nnbd_migration/instrumentation_listener.dart
rename to pkg/nnbd_migration/lib/src/front_end/instrumentation_listener.dart
index 933b7b5..fbbbbcf 100644
--- a/pkg/analysis_server/lib/src/edit/nnbd_migration/instrumentation_listener.dart
+++ b/pkg/nnbd_migration/lib/src/front_end/instrumentation_listener.dart
@@ -2,13 +2,13 @@
// 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:analysis_server/src/edit/nnbd_migration/instrumentation_information.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:nnbd_migration/instrumentation.dart';
import 'package:nnbd_migration/src/edit_plan.dart';
+import 'package:nnbd_migration/src/front_end/instrumentation_information.dart';
/// A listener used to gather instrumentation information from the migration
/// engine.
diff --git a/pkg/analysis_server/lib/src/edit/nnbd_migration/instrumentation_renderer.dart b/pkg/nnbd_migration/lib/src/front_end/instrumentation_renderer.dart
similarity index 91%
rename from pkg/analysis_server/lib/src/edit/nnbd_migration/instrumentation_renderer.dart
rename to pkg/nnbd_migration/lib/src/front_end/instrumentation_renderer.dart
index 6eb9fd4..e5538ea 100644
--- a/pkg/analysis_server/lib/src/edit/nnbd_migration/instrumentation_renderer.dart
+++ b/pkg/nnbd_migration/lib/src/front_end/instrumentation_renderer.dart
@@ -4,9 +4,9 @@
import 'dart:io';
-import 'package:analysis_server/src/edit/nnbd_migration/migration_info.dart';
-import 'package:analysis_server/src/edit/nnbd_migration/path_mapper.dart';
-import 'package:analysis_server/src/edit/nnbd_migration/resources/resources.g.dart'
+import 'package:nnbd_migration/src/front_end/migration_info.dart';
+import 'package:nnbd_migration/src/front_end/path_mapper.dart';
+import 'package:nnbd_migration/src/front_end/resources/resources.g.dart'
as resources;
import 'package:path/path.dart' as path;
diff --git a/pkg/analysis_server/lib/src/edit/nnbd_migration/migration_info.dart b/pkg/nnbd_migration/lib/src/front_end/migration_info.dart
similarity index 97%
rename from pkg/analysis_server/lib/src/edit/nnbd_migration/migration_info.dart
rename to pkg/nnbd_migration/lib/src/front_end/migration_info.dart
index adb8601..cafab98 100644
--- a/pkg/analysis_server/lib/src/edit/nnbd_migration/migration_info.dart
+++ b/pkg/nnbd_migration/lib/src/front_end/migration_info.dart
@@ -2,15 +2,15 @@
// 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:analysis_server/src/edit/nnbd_migration/offset_mapper.dart';
-import 'package:analysis_server/src/edit/nnbd_migration/unit_link.dart';
-import 'package:analysis_server/src/edit/preview/preview_site.dart';
import 'package:analyzer/src/generated/utilities_general.dart';
import 'package:analyzer_plugin/protocol/protocol_common.dart';
import 'package:collection/collection.dart';
import 'package:crypto/crypto.dart';
import 'package:meta/meta.dart';
import 'package:nnbd_migration/nnbd_migration.dart';
+import 'package:nnbd_migration/src/front_end/offset_mapper.dart';
+import 'package:nnbd_migration/src/front_end/unit_link.dart';
+import 'package:nnbd_migration/src/preview/preview_site.dart';
import 'package:path/path.dart' as path;
/// A description of an edit that can be applied before rerunning the migration
diff --git a/pkg/analysis_server/lib/src/edit/nnbd_migration/migration_state.dart b/pkg/nnbd_migration/lib/src/front_end/migration_state.dart
similarity index 72%
rename from pkg/analysis_server/lib/src/edit/nnbd_migration/migration_state.dart
rename to pkg/nnbd_migration/lib/src/front_end/migration_state.dart
index 53b0a73..1d714bd 100644
--- a/pkg/analysis_server/lib/src/edit/nnbd_migration/migration_state.dart
+++ b/pkg/nnbd_migration/lib/src/front_end/migration_state.dart
@@ -2,13 +2,12 @@
// 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:analysis_server/src/edit/fix/dartfix_listener.dart';
-import 'package:analysis_server/src/edit/fix/non_nullable_fix.dart';
-import 'package:analysis_server/src/edit/nnbd_migration/info_builder.dart';
-import 'package:analysis_server/src/edit/nnbd_migration/instrumentation_listener.dart';
-import 'package:analysis_server/src/edit/nnbd_migration/migration_info.dart';
-import 'package:analysis_server/src/edit/nnbd_migration/path_mapper.dart';
+import 'package:nnbd_migration/api_for_analysis_server/dartfix_listener_interface.dart';
import 'package:nnbd_migration/nnbd_migration.dart';
+import 'package:nnbd_migration/src/front_end/info_builder.dart';
+import 'package:nnbd_migration/src/front_end/instrumentation_listener.dart';
+import 'package:nnbd_migration/src/front_end/migration_info.dart';
+import 'package:nnbd_migration/src/front_end/path_mapper.dart';
/// The state of an NNBD migration.
class MigrationState {
@@ -17,14 +16,11 @@
/// The migration associated with the state.
final NullabilityMigration migration;
- /// The adapter to dartfix for this migration.
- final NullabilityMigrationAdapter adapter;
-
/// The root directory that contains all of the files that were migrated.
final String includedRoot;
/// The listener used to collect fixes.
- final DartFixListener listener;
+ final DartFixListenerInterface listener;
/// The listener that collected information during the migration.
final InstrumentationListener instrumentationListener;
@@ -40,7 +36,7 @@
/// Initialize a newly created migration state with the given values.
MigrationState(this.migration, this.includedRoot, this.listener,
- this.instrumentationListener, this.adapter);
+ this.instrumentationListener);
/// If the migration has been applied to disk.
bool get hasBeenApplied => _hasBeenApplied;
@@ -56,7 +52,7 @@
assert(!hasBeenApplied);
var provider = listener.server.resourceProvider;
var infoBuilder = InfoBuilder(provider, includedRoot,
- instrumentationListener.data, listener, adapter, migration);
+ instrumentationListener.data, listener, migration);
var unitInfos = await infoBuilder.explainMigration();
var pathContext = provider.pathContext;
migrationInfo = MigrationInfo(
diff --git a/pkg/analysis_server/lib/src/edit/nnbd_migration/navigation_tree_renderer.dart b/pkg/nnbd_migration/lib/src/front_end/navigation_tree_renderer.dart
similarity index 87%
rename from pkg/analysis_server/lib/src/edit/nnbd_migration/navigation_tree_renderer.dart
rename to pkg/nnbd_migration/lib/src/front_end/navigation_tree_renderer.dart
index 124a631..09d975c 100644
--- a/pkg/analysis_server/lib/src/edit/nnbd_migration/navigation_tree_renderer.dart
+++ b/pkg/nnbd_migration/lib/src/front_end/navigation_tree_renderer.dart
@@ -2,10 +2,10 @@
// 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:analysis_server/src/edit/nnbd_migration/migration_info.dart';
-import 'package:analysis_server/src/edit/nnbd_migration/path_mapper.dart';
-import 'package:analysis_server/src/edit/nnbd_migration/unit_link.dart';
-import 'package:analysis_server/src/edit/nnbd_migration/web/navigation_tree.dart';
+import 'package:nnbd_migration/src/front_end/migration_info.dart';
+import 'package:nnbd_migration/src/front_end/path_mapper.dart';
+import 'package:nnbd_migration/src/front_end/unit_link.dart';
+import 'package:nnbd_migration/src/front_end/web/navigation_tree.dart';
import 'package:path/path.dart' as path;
/// Groups the items in [iterable] by the result of applying [groupFn] to each
diff --git a/pkg/analysis_server/lib/src/edit/nnbd_migration/offset_mapper.dart b/pkg/nnbd_migration/lib/src/front_end/offset_mapper.dart
similarity index 100%
rename from pkg/analysis_server/lib/src/edit/nnbd_migration/offset_mapper.dart
rename to pkg/nnbd_migration/lib/src/front_end/offset_mapper.dart
diff --git a/pkg/analysis_server/lib/src/edit/nnbd_migration/path_mapper.dart b/pkg/nnbd_migration/lib/src/front_end/path_mapper.dart
similarity index 100%
rename from pkg/analysis_server/lib/src/edit/nnbd_migration/path_mapper.dart
rename to pkg/nnbd_migration/lib/src/front_end/path_mapper.dart
diff --git a/pkg/analysis_server/lib/src/edit/nnbd_migration/region_renderer.dart b/pkg/nnbd_migration/lib/src/front_end/region_renderer.dart
similarity index 93%
rename from pkg/analysis_server/lib/src/edit/nnbd_migration/region_renderer.dart
rename to pkg/nnbd_migration/lib/src/front_end/region_renderer.dart
index 6ac067c3..6b65c50 100644
--- a/pkg/analysis_server/lib/src/edit/nnbd_migration/region_renderer.dart
+++ b/pkg/nnbd_migration/lib/src/front_end/region_renderer.dart
@@ -2,9 +2,9 @@
// 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:analysis_server/src/edit/nnbd_migration/migration_info.dart';
-import 'package:analysis_server/src/edit/nnbd_migration/path_mapper.dart';
-import 'package:analysis_server/src/edit/nnbd_migration/web/edit_details.dart';
+import 'package:nnbd_migration/src/front_end/migration_info.dart';
+import 'package:nnbd_migration/src/front_end/path_mapper.dart';
+import 'package:nnbd_migration/src/front_end/web/edit_details.dart';
import 'package:path/path.dart' as path;
/// The HTML that is displayed for a region of code.
diff --git a/pkg/analysis_server/lib/src/edit/nnbd_migration/resources/.clang-format b/pkg/nnbd_migration/lib/src/front_end/resources/.clang-format
similarity index 100%
rename from pkg/analysis_server/lib/src/edit/nnbd_migration/resources/.clang-format
rename to pkg/nnbd_migration/lib/src/front_end/resources/.clang-format
diff --git a/pkg/analysis_server/lib/src/edit/nnbd_migration/resources/highlight.css b/pkg/nnbd_migration/lib/src/front_end/resources/highlight.css
similarity index 100%
rename from pkg/analysis_server/lib/src/edit/nnbd_migration/resources/highlight.css
rename to pkg/nnbd_migration/lib/src/front_end/resources/highlight.css
diff --git a/pkg/analysis_server/lib/src/edit/nnbd_migration/resources/highlight.md b/pkg/nnbd_migration/lib/src/front_end/resources/highlight.md
similarity index 100%
rename from pkg/analysis_server/lib/src/edit/nnbd_migration/resources/highlight.md
rename to pkg/nnbd_migration/lib/src/front_end/resources/highlight.md
diff --git a/pkg/analysis_server/lib/src/edit/nnbd_migration/resources/highlight.pack.js b/pkg/nnbd_migration/lib/src/front_end/resources/highlight.pack.js
similarity index 100%
rename from pkg/analysis_server/lib/src/edit/nnbd_migration/resources/highlight.pack.js
rename to pkg/nnbd_migration/lib/src/front_end/resources/highlight.pack.js
diff --git a/pkg/analysis_server/lib/src/edit/nnbd_migration/resources/index.html b/pkg/nnbd_migration/lib/src/front_end/resources/index.html
similarity index 86%
rename from pkg/analysis_server/lib/src/edit/nnbd_migration/resources/index.html
rename to pkg/nnbd_migration/lib/src/front_end/resources/index.html
index 629cb25..a1e8242 100644
--- a/pkg/analysis_server/lib/src/edit/nnbd_migration/resources/index.html
+++ b/pkg/nnbd_migration/lib/src/front_end/resources/index.html
@@ -11,6 +11,13 @@
<div class="rerunning-pane">
<h1>Rerunning...</h1>
</div>
+<div class="popup-pane">
+ <div class="close button">X</div>
+ <h2></h2><!-- header placeholder element -->
+ <p></p><!-- subheader placeholder element -->
+ <pre></pre><!-- preformated content placeholder element -->
+ <a class="button bottom" target="_blank">File on GitHub</a><!-- post to github placeholder element -->
+</div>
<p class="root">{{ root }}</p>
<header class="elevation-z4">
<h1 class="before-apply">Proposed null safety changes</h1>
@@ -65,6 +72,7 @@
migration help</a>
<span class="wide"> </span>
<div>Based on {{ sdkVersion }}</div>
+ <button class="report-problem">Report a Problem</button>
</footer>
</body>
</html>
diff --git a/pkg/analysis_server/lib/src/edit/nnbd_migration/resources/migration.css b/pkg/nnbd_migration/lib/src/front_end/resources/migration.css
similarity index 87%
rename from pkg/analysis_server/lib/src/edit/nnbd_migration/resources/migration.css
rename to pkg/nnbd_migration/lib/src/front_end/resources/migration.css
index c857fab..41940da 100644
--- a/pkg/analysis_server/lib/src/edit/nnbd_migration/resources/migration.css
+++ b/pkg/nnbd_migration/lib/src/front_end/resources/migration.css
@@ -65,6 +65,11 @@
margin: 10px;
}
+footer .report-problem {
+ right: 0px;
+ margin: 4px 8px;
+}
+
.rerun-migration .required {
display: none;
}
@@ -113,7 +118,7 @@
display: flex;
flex-direction: row;
align-items: center;
- padding: 8px 24px;
+ padding: 8px 0 8px 24px;
}
footer .wide {
@@ -402,6 +407,60 @@
cursor: pointer;
}
+.popup-pane {
+ display: none;
+ position: fixed;
+ top: 150px;
+ left: 150px;
+ right: 150px;
+ bottom: 150px;
+ border: 1px solid black;
+ border-top: 2px solid black;
+ border-radius: 7px;
+ box-shadow: 0px 0px 20px 2px #b4bfcb22;
+ z-index: 1;
+ background: #2b3036;
+ padding: 20px;
+}
+
+.popup-pane .close {
+ position: absolute;
+ right: 10px;
+ top: 10px;
+ cursor: pointer;
+ text-shadow: 1px 1px 2px #888;
+ box-shadow: 1px 1px 2px #111;
+}
+
+.popup-pane h2 {
+ padding: 21px;
+ height: 10%;
+ margin: 0px;
+ box-sizing: border-box;
+}
+
+.popup-pane p {
+ height: 10%;
+ box-sizing: border-box;
+ padding: 0px 20px;
+}
+
+.popup-pane pre {
+ background: #282b2e;
+ padding: 20px;
+ bottom: 0px;
+ overflow: auto scroll;
+ height: 65%;
+ margin: 0px;
+ box-sizing: border-box;
+}
+
+.popup-pane .button.bottom {
+ margin: 20px 0px;
+ display: block;
+ text-align: center;
+}
+
.rerunning-pane {
display: none;
}
@@ -466,12 +525,12 @@
fill: #fff;
}
-a.post-link {
+.add-hint-link {
display: inline-block;
margin: 3px;
}
-button, a.post-link {
+button, a.button {
background-color: #33ccff;
border: 2px solid #37aedc;
border-radius: 3px;
@@ -480,7 +539,7 @@
color: #282828;
}
-button:hover, a.post-link:hover {
+button:hover, .button:hover {
background-color: #80dfff;
border: 2px solid #52b8e0;
cursor: pointer;
diff --git a/pkg/nnbd_migration/lib/src/front_end/resources/resources.g.dart b/pkg/nnbd_migration/lib/src/front_end/resources/resources.g.dart
new file mode 100644
index 0000000..2285f5c
--- /dev/null
+++ b/pkg/nnbd_migration/lib/src/front_end/resources/resources.g.dart
@@ -0,0 +1,4158 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// This file is generated; don't edit it directly.
+//
+// See pkg/nnbd_migration/tool/codegen/generate_resources.dart for how
+// to edit the source content and for re-generation instructions.
+
+import 'dart:convert' as convert;
+
+String get highlight_css {
+ return _highlight_css ??= _decode(_highlight_css_base64);
+}
+
+String get highlight_pack_js {
+ return _highlight_pack_js ??= _decode(_highlight_pack_js_base64);
+}
+
+String get index_html {
+ return _index_html ??= _decode(_index_html_base64);
+}
+
+String get migration_css {
+ return _migration_css ??= _decode(_migration_css_base64);
+}
+
+String get migration_js {
+ return _migration_js ??= _decode(_migration_js_base64);
+}
+
+String _decode(String data) {
+ data = data.replaceAll('\n', '').trim();
+ return String.fromCharCodes(convert.base64Decode(data));
+}
+
+String _highlight_css;
+// highlight_css md5 is 'fb012626bafd286510d32da815dae448'
+String _highlight_css_base64 = '''
+LyoKRGF0ZTogMjQgRmV2IDIwMTUKQXV0aG9yOiBQZWRybyBPbGl2ZWlyYSA8a2FueXR1QGdtYWlsIC4g
+Y29tPgoqLwoKLmhsanMgewogIGNvbG9yOiAjYTliN2M2OwogIGJhY2tncm91bmQ6ICMyODJiMmU7CiAg
+ZGlzcGxheTogYmxvY2s7CiAgb3ZlcmZsb3cteDogYXV0bzsKICBwYWRkaW5nOiAwLjVlbTsKfQoKLmhs
+anMtbnVtYmVyLAouaGxqcy1saXRlcmFsLAouaGxqcy1zeW1ib2wsCi5obGpzLWJ1bGxldCB7CiAgY29s
+b3I6ICM2ODk3QkI7Cn0KCi5obGpzLWtleXdvcmQsCi5obGpzLXNlbGVjdG9yLXRhZywKLmhsanMtZGVs
+ZXRpb24gewogIGNvbG9yOiAjY2M3ODMyOwp9CgouaGxqcy12YXJpYWJsZSwKLmhsanMtdGVtcGxhdGUt
+dmFyaWFibGUsCi5obGpzLWxpbmsgewogIGNvbG9yOiAjNjI5NzU1Owp9CgouaGxqcy1jb21tZW50LAou
+aGxqcy1xdW90ZSB7CiAgY29sb3I6ICM4MDgwODA7Cn0KCi5obGpzLW1ldGEgewogIGNvbG9yOiAjYmJi
+NTI5Owp9CgouaGxqcy1zdHJpbmcsCi5obGpzLWF0dHJpYnV0ZSwKLmhsanMtYWRkaXRpb24gewogIGNv
+bG9yOiAjNkE4NzU5Owp9CgouaGxqcy1zZWN0aW9uLAouaGxqcy10aXRsZSwKLmhsanMtdHlwZSB7CiAg
+Y29sb3I6ICNmZmM2NmQ7Cn0KCi5obGpzLW5hbWUsCi5obGpzLXNlbGVjdG9yLWlkLAouaGxqcy1zZWxl
+Y3Rvci1jbGFzcyB7CiAgY29sb3I6ICNlOGJmNmE7Cn0KCi5obGpzLWVtcGhhc2lzIHsKICBmb250LXN0
+eWxlOiBpdGFsaWM7Cn0KCi5obGpzLXN0cm9uZyB7CiAgZm9udC13ZWlnaHQ6IGJvbGQ7Cn0K
+''';
+
+String _highlight_pack_js;
+// highlight_pack_js md5 is '9104bfe8b056f8e00da50b0ea3d6e6d4'
+String _highlight_pack_js_base64 = '''
+LyohIGhpZ2hsaWdodC5qcyB2OS4xNS4xMCB8IEJTRDMgTGljZW5zZSB8IGdpdC5pby9obGpzbGljZW5z
+ZSAqLwohZnVuY3Rpb24oZSl7dmFyIG49Im9iamVjdCI9PXR5cGVvZiB3aW5kb3cmJndpbmRvd3x8Im9i
+amVjdCI9PXR5cGVvZiBzZWxmJiZzZWxmOyJ1bmRlZmluZWQiPT10eXBlb2YgZXhwb3J0c3x8ZXhwb3J0
+cy5ub2RlVHlwZT9uJiYobi5obGpzPWUoe30pLCJmdW5jdGlvbiI9PXR5cGVvZiBkZWZpbmUmJmRlZmlu
+ZS5hbWQmJmRlZmluZShbXSxmdW5jdGlvbigpe3JldHVybiBuLmhsanN9KSk6ZShleHBvcnRzKX0oZnVu
+Y3Rpb24oYSl7dmFyIGY9W10sdT1PYmplY3Qua2V5cyxOPXt9LGM9e30sbj0vXihuby0/aGlnaGxpZ2h0
+fHBsYWlufHRleHQpJC9pLHM9L1xibGFuZyg/OnVhZ2UpPy0oW1x3LV0rKVxiL2ksdD0vKCheKDxbXj5d
+Kz58XHR8KSt8KD86XG4pKSkvZ20scj17Y2FzZV9pbnNlbnNpdGl2ZToiY0kiLGxleGVtZXM6ImwiLGNv
+bnRhaW5zOiJjIixrZXl3b3JkczoiayIsc3ViTGFuZ3VhZ2U6InNMIixjbGFzc05hbWU6ImNOIixiZWdp
+bjoiYiIsYmVnaW5LZXl3b3JkczoiYksiLGVuZDoiZSIsZW5kc1dpdGhQYXJlbnQ6ImVXIixpbGxlZ2Fs
+OiJpIixleGNsdWRlQmVnaW46ImVCIixleGNsdWRlRW5kOiJlRSIscmV0dXJuQmVnaW46InJCIixyZXR1
+cm5FbmQ6InJFIixyZWxldmFuY2U6InIiLHZhcmlhbnRzOiJ2IixJREVOVF9SRToiSVIiLFVOREVSU0NP
+UkVfSURFTlRfUkU6IlVJUiIsTlVNQkVSX1JFOiJOUiIsQ19OVU1CRVJfUkU6IkNOUiIsQklOQVJZX05V
+TUJFUl9SRToiQk5SIixSRV9TVEFSVEVSU19SRToiUlNSIixCQUNLU0xBU0hfRVNDQVBFOiJCRSIsQVBP
+U19TVFJJTkdfTU9ERToiQVNNIixRVU9URV9TVFJJTkdfTU9ERToiUVNNIixQSFJBU0FMX1dPUkRTX01P
+REU6IlBXTSIsQ19MSU5FX0NPTU1FTlRfTU9ERToiQ0xDTSIsQ19CTE9DS19DT01NRU5UX01PREU6IkNC
+Q00iLEhBU0hfQ09NTUVOVF9NT0RFOiJIQ00iLE5VTUJFUl9NT0RFOiJOTSIsQ19OVU1CRVJfTU9ERToi
+Q05NIixCSU5BUllfTlVNQkVSX01PREU6IkJOTSIsQ1NTX05VTUJFUl9NT0RFOiJDU1NOTSIsUkVHRVhQ
+X01PREU6IlJNIixUSVRMRV9NT0RFOiJUTSIsVU5ERVJTQ09SRV9USVRMRV9NT0RFOiJVVE0iLENPTU1F
+TlQ6IkMiLGJlZ2luUmU6ImJSIixlbmRSZToiZVIiLGlsbGVnYWxSZToiaVIiLGxleGVtZXNSZToibFIi
+LHRlcm1pbmF0b3JzOiJ0Iix0ZXJtaW5hdG9yX2VuZDoidEUifSxiPSI8L3NwYW4+IixoPXtjbGFzc1By
+ZWZpeDoiaGxqcy0iLHRhYlJlcGxhY2U6bnVsbCx1c2VCUjohMSxsYW5ndWFnZXM6dm9pZCAwfTtmdW5j
+dGlvbiBfKGUpe3JldHVybiBlLnJlcGxhY2UoLyYvZywiJmFtcDsiKS5yZXBsYWNlKC88L2csIiZsdDsi
+KS5yZXBsYWNlKC8+L2csIiZndDsiKX1mdW5jdGlvbiBFKGUpe3JldHVybiBlLm5vZGVOYW1lLnRvTG93
+ZXJDYXNlKCl9ZnVuY3Rpb24gdihlLG4pe3ZhciB0PWUmJmUuZXhlYyhuKTtyZXR1cm4gdCYmMD09PXQu
+aW5kZXh9ZnVuY3Rpb24gbChlKXtyZXR1cm4gbi50ZXN0KGUpfWZ1bmN0aW9uIGcoZSl7dmFyIG4sdD17
+fSxyPUFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywxKTtmb3IobiBpbiBlKXRbbl09
+ZVtuXTtyZXR1cm4gci5mb3JFYWNoKGZ1bmN0aW9uKGUpe2ZvcihuIGluIGUpdFtuXT1lW25dfSksdH1m
+dW5jdGlvbiBSKGUpe3ZhciBhPVtdO3JldHVybiBmdW5jdGlvbiBlKG4sdCl7Zm9yKHZhciByPW4uZmly
+c3RDaGlsZDtyO3I9ci5uZXh0U2libGluZykzPT09ci5ub2RlVHlwZT90Kz1yLm5vZGVWYWx1ZS5sZW5n
+dGg6MT09PXIubm9kZVR5cGUmJihhLnB1c2goe2V2ZW50OiJzdGFydCIsb2Zmc2V0OnQsbm9kZTpyfSks
+dD1lKHIsdCksRShyKS5tYXRjaCgvYnJ8aHJ8aW1nfGlucHV0Lyl8fGEucHVzaCh7ZXZlbnQ6InN0b3Ai
+LG9mZnNldDp0LG5vZGU6cn0pKTtyZXR1cm4gdH0oZSwwKSxhfWZ1bmN0aW9uIGkoZSl7aWYociYmIWUu
+bGFuZ0FwaVJlc3RvcmVkKXtmb3IodmFyIG4gaW4gZS5sYW5nQXBpUmVzdG9yZWQ9ITAscillW25dJiYo
+ZVtyW25dXT1lW25dKTsoZS5jfHxbXSkuY29uY2F0KGUudnx8W10pLmZvckVhY2goaSl9fWZ1bmN0aW9u
+IG0obyl7ZnVuY3Rpb24gcyhlKXtyZXR1cm4gZSYmZS5zb3VyY2V8fGV9ZnVuY3Rpb24gYyhlLG4pe3Jl
+dHVybiBuZXcgUmVnRXhwKHMoZSksIm0iKyhvLmNJPyJpIjoiIikrKG4/ImciOiIiKSl9IWZ1bmN0aW9u
+IG4odCxlKXtpZighdC5jb21waWxlZCl7aWYodC5jb21waWxlZD0hMCx0Lms9dC5rfHx0LmJLLHQuayl7
+ZnVuY3Rpb24gcih0LGUpe28uY0kmJihlPWUudG9Mb3dlckNhc2UoKSksZS5zcGxpdCgiICIpLmZvckVh
+Y2goZnVuY3Rpb24oZSl7dmFyIG49ZS5zcGxpdCgifCIpO2FbblswXV09W3QsblsxXT9OdW1iZXIoblsx
+XSk6MV19KX12YXIgYT17fTsic3RyaW5nIj09dHlwZW9mIHQuaz9yKCJrZXl3b3JkIix0LmspOnUodC5r
+KS5mb3JFYWNoKGZ1bmN0aW9uKGUpe3IoZSx0LmtbZV0pfSksdC5rPWF9dC5sUj1jKHQubHx8L1x3Ky8s
+ITApLGUmJih0LmJLJiYodC5iPSJcXGIoIit0LmJLLnNwbGl0KCIgIikuam9pbigifCIpKyIpXFxiIiks
+dC5ifHwodC5iPS9cQnxcYi8pLHQuYlI9Yyh0LmIpLHQuZW5kU2FtZUFzQmVnaW4mJih0LmU9dC5iKSx0
+LmV8fHQuZVd8fCh0LmU9L1xCfFxiLyksdC5lJiYodC5lUj1jKHQuZSkpLHQudEU9cyh0LmUpfHwiIix0
+LmVXJiZlLnRFJiYodC50RSs9KHQuZT8ifCI6IiIpK2UudEUpKSx0LmkmJih0LmlSPWModC5pKSksbnVs
+bD09dC5yJiYodC5yPTEpLHQuY3x8KHQuYz1bXSksdC5jPUFycmF5LnByb3RvdHlwZS5jb25jYXQuYXBw
+bHkoW10sdC5jLm1hcChmdW5jdGlvbihlKXtyZXR1cm4gZnVuY3Rpb24obil7cmV0dXJuIG4udiYmIW4u
+Y2FjaGVkX3ZhcmlhbnRzJiYobi5jYWNoZWRfdmFyaWFudHM9bi52Lm1hcChmdW5jdGlvbihlKXtyZXR1
+cm4gZyhuLHt2Om51bGx9LGUpfSkpLG4uY2FjaGVkX3ZhcmlhbnRzfHxuLmVXJiZbZyhuKV18fFtuXX0o
+InNlbGYiPT09ZT90OmUpfSkpLHQuYy5mb3JFYWNoKGZ1bmN0aW9uKGUpe24oZSx0KX0pLHQuc3RhcnRz
+JiZuKHQuc3RhcnRzLGUpO3ZhciBpPXQuYy5tYXAoZnVuY3Rpb24oZSl7cmV0dXJuIGUuYks/IlxcLj8o
+PzoiK2UuYisiKVxcLj8iOmUuYn0pLmNvbmNhdChbdC50RSx0LmldKS5tYXAocykuZmlsdGVyKEJvb2xl
+YW4pO3QudD1pLmxlbmd0aD9jKGZ1bmN0aW9uKGUsbil7Zm9yKHZhciB0PS9cWyg/OlteXFxcXV18XFwu
+KSpcXXxcKFw/P3xcXChbMS05XVswLTldKil8XFwuLyxyPTAsYT0iIixpPTA7aTxlLmxlbmd0aDtpKysp
+e3ZhciBvPXIsYz1zKGVbaV0pO2ZvcigwPGkmJihhKz1uKTswPGMubGVuZ3RoOyl7dmFyIHU9dC5leGVj
+KGMpO2lmKG51bGw9PXUpe2ErPWM7YnJlYWt9YSs9Yy5zdWJzdHJpbmcoMCx1LmluZGV4KSxjPWMuc3Vi
+c3RyaW5nKHUuaW5kZXgrdVswXS5sZW5ndGgpLCJcXCI9PXVbMF1bMF0mJnVbMV0/YSs9IlxcIitTdHJp
+bmcoTnVtYmVyKHVbMV0pK28pOihhKz11WzBdLCIoIj09dVswXSYmcisrKX19cmV0dXJuIGF9KGksInwi
+KSwhMCk6e2V4ZWM6ZnVuY3Rpb24oKXtyZXR1cm4gbnVsbH19fX0obyl9ZnVuY3Rpb24gQyhlLG4saSx0
+KXtmdW5jdGlvbiBjKGUsbix0LHIpe3ZhciBhPSc8c3BhbiBjbGFzcz0iJysocj8iIjpoLmNsYXNzUHJl
+Zml4KTtyZXR1cm4gZT8oYSs9ZSsnIj4nKStuKyh0PyIiOmIpOm59ZnVuY3Rpb24gbygpe0UrPW51bGwh
+PWwuc0w/ZnVuY3Rpb24oKXt2YXIgZT0ic3RyaW5nIj09dHlwZW9mIGwuc0w7aWYoZSYmIU5bbC5zTF0p
+cmV0dXJuIF8oZyk7dmFyIG49ZT9DKGwuc0wsZywhMCxmW2wuc0xdKTpPKGcsbC5zTC5sZW5ndGg/bC5z
+TDp2b2lkIDApO3JldHVybiAwPGwuciYmKFIrPW4uciksZSYmKGZbbC5zTF09bi50b3ApLGMobi5sYW5n
+dWFnZSxuLnZhbHVlLCExLCEwKX0oKTpmdW5jdGlvbigpe3ZhciBlLG4sdCxyLGEsaSxvO2lmKCFsLmsp
+cmV0dXJuIF8oZyk7Zm9yKHI9IiIsbj0wLGwubFIubGFzdEluZGV4PTAsdD1sLmxSLmV4ZWMoZyk7dDsp
+cis9XyhnLnN1YnN0cmluZyhuLHQuaW5kZXgpKSxhPWwsaT10LHZvaWQgMCxvPXMuY0k/aVswXS50b0xv
+d2VyQ2FzZSgpOmlbMF0sKGU9YS5rLmhhc093blByb3BlcnR5KG8pJiZhLmtbb10pPyhSKz1lWzFdLHIr
+PWMoZVswXSxfKHRbMF0pKSk6cis9Xyh0WzBdKSxuPWwubFIubGFzdEluZGV4LHQ9bC5sUi5leGVjKGcp
+O3JldHVybiByK18oZy5zdWJzdHIobikpfSgpLGc9IiJ9ZnVuY3Rpb24gdShlKXtFKz1lLmNOP2MoZS5j
+TiwiIiwhMCk6IiIsbD1PYmplY3QuY3JlYXRlKGUse3BhcmVudDp7dmFsdWU6bH19KX1mdW5jdGlvbiBy
+KGUsbil7aWYoZys9ZSxudWxsPT1uKXJldHVybiBvKCksMDt2YXIgdD1mdW5jdGlvbihlLG4pe3ZhciB0
+LHIsYTtmb3IodD0wLHI9bi5jLmxlbmd0aDt0PHI7dCsrKWlmKHYobi5jW3RdLmJSLGUpKXJldHVybiBu
+LmNbdF0uZW5kU2FtZUFzQmVnaW4mJihuLmNbdF0uZVI9KGE9bi5jW3RdLmJSLmV4ZWMoZSlbMF0sbmV3
+IFJlZ0V4cChhLnJlcGxhY2UoL1stXC9cXF4kKis/LigpfFtcXXt9XS9nLCJcXCQmIiksIm0iKSkpLG4u
+Y1t0XX0obixsKTtpZih0KXJldHVybiB0LnNraXA/Zys9bjoodC5lQiYmKGcrPW4pLG8oKSx0LnJCfHx0
+LmVCfHwoZz1uKSksdSh0KSx0LnJCPzA6bi5sZW5ndGg7dmFyIHI9ZnVuY3Rpb24gZShuLHQpe2lmKHYo
+bi5lUix0KSl7Zm9yKDtuLmVuZHNQYXJlbnQmJm4ucGFyZW50OyluPW4ucGFyZW50O3JldHVybiBufWlm
+KG4uZVcpcmV0dXJuIGUobi5wYXJlbnQsdCl9KGwsbik7aWYocil7dmFyIGE9bDtmb3IoYS5za2lwP2cr
+PW46KGEuckV8fGEuZUV8fChnKz1uKSxvKCksYS5lRSYmKGc9bikpO2wuY04mJihFKz1iKSxsLnNraXB8
+fGwuc0x8fChSKz1sLnIpLChsPWwucGFyZW50KSE9PXIucGFyZW50Oyk7cmV0dXJuIHIuc3RhcnRzJiYo
+ci5lbmRTYW1lQXNCZWdpbiYmKHIuc3RhcnRzLmVSPXIuZVIpLHUoci5zdGFydHMpKSxhLnJFPzA6bi5s
+ZW5ndGh9aWYoZnVuY3Rpb24oZSxuKXtyZXR1cm4haSYmdihuLmlSLGUpfShuLGwpKXRocm93IG5ldyBF
+cnJvcignSWxsZWdhbCBsZXhlbWUgIicrbisnIiBmb3IgbW9kZSAiJysobC5jTnx8Ijx1bm5hbWVkPiIp
+KyciJyk7cmV0dXJuIGcrPW4sbi5sZW5ndGh8fDF9dmFyIHM9QihlKTtpZighcyl0aHJvdyBuZXcgRXJy
+b3IoJ1Vua25vd24gbGFuZ3VhZ2U6ICInK2UrJyInKTttKHMpO3ZhciBhLGw9dHx8cyxmPXt9LEU9IiI7
+Zm9yKGE9bDthIT09czthPWEucGFyZW50KWEuY04mJihFPWMoYS5jTiwiIiwhMCkrRSk7dmFyIGc9IiIs
+Uj0wO3RyeXtmb3IodmFyIGQscCxNPTA7bC50Lmxhc3RJbmRleD1NLGQ9bC50LmV4ZWMobik7KXA9cihu
+LnN1YnN0cmluZyhNLGQuaW5kZXgpLGRbMF0pLE09ZC5pbmRleCtwO2ZvcihyKG4uc3Vic3RyKE0pKSxh
+PWw7YS5wYXJlbnQ7YT1hLnBhcmVudClhLmNOJiYoRSs9Yik7cmV0dXJue3I6Uix2YWx1ZTpFLGxhbmd1
+YWdlOmUsdG9wOmx9fWNhdGNoKGUpe2lmKGUubWVzc2FnZSYmLTEhPT1lLm1lc3NhZ2UuaW5kZXhPZigi
+SWxsZWdhbCIpKXJldHVybntyOjAsdmFsdWU6XyhuKX07dGhyb3cgZX19ZnVuY3Rpb24gTyh0LGUpe2U9
+ZXx8aC5sYW5ndWFnZXN8fHUoTik7dmFyIHI9e3I6MCx2YWx1ZTpfKHQpfSxhPXI7cmV0dXJuIGUuZmls
+dGVyKEIpLmZpbHRlcihNKS5mb3JFYWNoKGZ1bmN0aW9uKGUpe3ZhciBuPUMoZSx0LCExKTtuLmxhbmd1
+YWdlPWUsbi5yPmEuciYmKGE9biksbi5yPnIuciYmKGE9cixyPW4pfSksYS5sYW5ndWFnZSYmKHIuc2Vj
+b25kX2Jlc3Q9YSkscn1mdW5jdGlvbiBkKGUpe3JldHVybiBoLnRhYlJlcGxhY2V8fGgudXNlQlI/ZS5y
+ZXBsYWNlKHQsZnVuY3Rpb24oZSxuKXtyZXR1cm4gaC51c2VCUiYmIlxuIj09PWU/Ijxicj4iOmgudGFi
+UmVwbGFjZT9uLnJlcGxhY2UoL1x0L2csaC50YWJSZXBsYWNlKToiIn0pOmV9ZnVuY3Rpb24gbyhlKXt2
+YXIgbix0LHIsYSxpLG89ZnVuY3Rpb24oZSl7dmFyIG4sdCxyLGEsaT1lLmNsYXNzTmFtZSsiICI7aWYo
+aSs9ZS5wYXJlbnROb2RlP2UucGFyZW50Tm9kZS5jbGFzc05hbWU6IiIsdD1zLmV4ZWMoaSkpcmV0dXJu
+IEIodFsxXSk/dFsxXToibm8taGlnaGxpZ2h0Ijtmb3Iobj0wLHI9KGk9aS5zcGxpdCgvXHMrLykpLmxl
+bmd0aDtuPHI7bisrKWlmKGwoYT1pW25dKXx8QihhKSlyZXR1cm4gYX0oZSk7bChvKXx8KGgudXNlQlI/
+KG49ZG9jdW1lbnQuY3JlYXRlRWxlbWVudE5TKCJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hodG1sIiwi
+ZGl2IikpLmlubmVySFRNTD1lLmlubmVySFRNTC5yZXBsYWNlKC9cbi9nLCIiKS5yZXBsYWNlKC88YnJb
+IFwvXSo+L2csIlxuIik6bj1lLGk9bi50ZXh0Q29udGVudCxyPW8/QyhvLGksITApOk8oaSksKHQ9Uihu
+KSkubGVuZ3RoJiYoKGE9ZG9jdW1lbnQuY3JlYXRlRWxlbWVudE5TKCJodHRwOi8vd3d3LnczLm9yZy8x
+OTk5L3hodG1sIiwiZGl2IikpLmlubmVySFRNTD1yLnZhbHVlLHIudmFsdWU9ZnVuY3Rpb24oZSxuLHQp
+e3ZhciByPTAsYT0iIixpPVtdO2Z1bmN0aW9uIG8oKXtyZXR1cm4gZS5sZW5ndGgmJm4ubGVuZ3RoP2Vb
+MF0ub2Zmc2V0IT09blswXS5vZmZzZXQ/ZVswXS5vZmZzZXQ8blswXS5vZmZzZXQ/ZTpuOiJzdGFydCI9
+PT1uWzBdLmV2ZW50P2U6bjplLmxlbmd0aD9lOm59ZnVuY3Rpb24gYyhlKXthKz0iPCIrRShlKStmLm1h
+cC5jYWxsKGUuYXR0cmlidXRlcyxmdW5jdGlvbihlKXtyZXR1cm4iICIrZS5ub2RlTmFtZSsnPSInK18o
+ZS52YWx1ZSkucmVwbGFjZSgnIicsIiZxdW90OyIpKyciJ30pLmpvaW4oIiIpKyI+In1mdW5jdGlvbiB1
+KGUpe2ErPSI8LyIrRShlKSsiPiJ9ZnVuY3Rpb24gcyhlKXsoInN0YXJ0Ij09PWUuZXZlbnQ/Yzp1KShl
+Lm5vZGUpfWZvcig7ZS5sZW5ndGh8fG4ubGVuZ3RoOyl7dmFyIGw9bygpO2lmKGErPV8odC5zdWJzdHJp
+bmcocixsWzBdLm9mZnNldCkpLHI9bFswXS5vZmZzZXQsbD09PWUpe2ZvcihpLnJldmVyc2UoKS5mb3JF
+YWNoKHUpO3MobC5zcGxpY2UoMCwxKVswXSksKGw9bygpKT09PWUmJmwubGVuZ3RoJiZsWzBdLm9mZnNl
+dD09PXI7KTtpLnJldmVyc2UoKS5mb3JFYWNoKGMpfWVsc2Uic3RhcnQiPT09bFswXS5ldmVudD9pLnB1
+c2gobFswXS5ub2RlKTppLnBvcCgpLHMobC5zcGxpY2UoMCwxKVswXSl9cmV0dXJuIGErXyh0LnN1YnN0
+cihyKSl9KHQsUihhKSxpKSksci52YWx1ZT1kKHIudmFsdWUpLGUuaW5uZXJIVE1MPXIudmFsdWUsZS5j
+bGFzc05hbWU9ZnVuY3Rpb24oZSxuLHQpe3ZhciByPW4/Y1tuXTp0LGE9W2UudHJpbSgpXTtyZXR1cm4g
+ZS5tYXRjaCgvXGJobGpzXGIvKXx8YS5wdXNoKCJobGpzIiksLTE9PT1lLmluZGV4T2YocikmJmEucHVz
+aChyKSxhLmpvaW4oIiAiKS50cmltKCl9KGUuY2xhc3NOYW1lLG8sci5sYW5ndWFnZSksZS5yZXN1bHQ9
+e2xhbmd1YWdlOnIubGFuZ3VhZ2UscmU6ci5yfSxyLnNlY29uZF9iZXN0JiYoZS5zZWNvbmRfYmVzdD17
+bGFuZ3VhZ2U6ci5zZWNvbmRfYmVzdC5sYW5ndWFnZSxyZTpyLnNlY29uZF9iZXN0LnJ9KSl9ZnVuY3Rp
+b24gcCgpe2lmKCFwLmNhbGxlZCl7cC5jYWxsZWQ9ITA7dmFyIGU9ZG9jdW1lbnQucXVlcnlTZWxlY3Rv
+ckFsbCgicHJlIGNvZGUiKTtmLmZvckVhY2guY2FsbChlLG8pfX1mdW5jdGlvbiBCKGUpe3JldHVybiBl
+PShlfHwiIikudG9Mb3dlckNhc2UoKSxOW2VdfHxOW2NbZV1dfWZ1bmN0aW9uIE0oZSl7dmFyIG49Qihl
+KTtyZXR1cm4gbiYmIW4uZGlzYWJsZUF1dG9kZXRlY3R9cmV0dXJuIGEuaGlnaGxpZ2h0PUMsYS5oaWdo
+bGlnaHRBdXRvPU8sYS5maXhNYXJrdXA9ZCxhLmhpZ2hsaWdodEJsb2NrPW8sYS5jb25maWd1cmU9ZnVu
+Y3Rpb24oZSl7aD1nKGgsZSl9LGEuaW5pdEhpZ2hsaWdodGluZz1wLGEuaW5pdEhpZ2hsaWdodGluZ09u
+TG9hZD1mdW5jdGlvbigpe2FkZEV2ZW50TGlzdGVuZXIoIkRPTUNvbnRlbnRMb2FkZWQiLHAsITEpLGFk
+ZEV2ZW50TGlzdGVuZXIoImxvYWQiLHAsITEpfSxhLnJlZ2lzdGVyTGFuZ3VhZ2U9ZnVuY3Rpb24obixl
+KXt2YXIgdD1OW25dPWUoYSk7aSh0KSx0LmFsaWFzZXMmJnQuYWxpYXNlcy5mb3JFYWNoKGZ1bmN0aW9u
+KGUpe2NbZV09bn0pfSxhLmxpc3RMYW5ndWFnZXM9ZnVuY3Rpb24oKXtyZXR1cm4gdShOKX0sYS5nZXRM
+YW5ndWFnZT1CLGEuYXV0b0RldGVjdGlvbj1NLGEuaW5oZXJpdD1nLGEuSVI9YS5JREVOVF9SRT0iW2Et
+ekEtWl1cXHcqIixhLlVJUj1hLlVOREVSU0NPUkVfSURFTlRfUkU9IlthLXpBLVpfXVxcdyoiLGEuTlI9
+YS5OVU1CRVJfUkU9IlxcYlxcZCsoXFwuXFxkKyk/IixhLkNOUj1hLkNfTlVNQkVSX1JFPSIoLT8pKFxc
+YjBbeFhdW2EtZkEtRjAtOV0rfChcXGJcXGQrKFxcLlxcZCopP3xcXC5cXGQrKShbZUVdWy0rXT9cXGQr
+KT8pIixhLkJOUj1hLkJJTkFSWV9OVU1CRVJfUkU9IlxcYigwYlswMV0rKSIsYS5SU1I9YS5SRV9TVEFS
+VEVSU19SRT0iIXwhPXwhPT18JXwlPXwmfCYmfCY9fFxcKnxcXCo9fFxcK3xcXCs9fCx8LXwtPXwvPXwv
+fDp8O3w8PHw8PD18PD18PHw9PT18PT18PXw+Pj49fD4+PXw+PXw+Pj58Pj58PnxcXD98XFxbfFxce3xc
+XCh8XFxefFxcXj18XFx8fFxcfD18XFx8XFx8fH4iLGEuQkU9YS5CQUNLU0xBU0hfRVNDQVBFPXtiOiJc
+XFxcW1xcc1xcU10iLHI6MH0sYS5BU009YS5BUE9TX1NUUklOR19NT0RFPXtjTjoic3RyaW5nIixiOiIn
+IixlOiInIixpOiJcXG4iLGM6W2EuQkVdfSxhLlFTTT1hLlFVT1RFX1NUUklOR19NT0RFPXtjTjoic3Ry
+aW5nIixiOiciJyxlOiciJyxpOiJcXG4iLGM6W2EuQkVdfSxhLlBXTT1hLlBIUkFTQUxfV09SRFNfTU9E
+RT17YjovXGIoYXxhbnx0aGV8YXJlfEknbXxpc24ndHxkb24ndHxkb2Vzbid0fHdvbid0fGJ1dHxqdXN0
+fHNob3VsZHxwcmV0dHl8c2ltcGx5fGVub3VnaHxnb25uYXxnb2luZ3x3dGZ8c298c3VjaHx3aWxsfHlv
+dXx5b3VyfHRoZXl8bGlrZXxtb3JlKVxiL30sYS5DPWEuQ09NTUVOVD1mdW5jdGlvbihlLG4sdCl7dmFy
+IHI9YS5pbmhlcml0KHtjTjoiY29tbWVudCIsYjplLGU6bixjOltdfSx0fHx7fSk7cmV0dXJuIHIuYy5w
+dXNoKGEuUFdNKSxyLmMucHVzaCh7Y046ImRvY3RhZyIsYjoiKD86VE9ET3xGSVhNRXxOT1RFfEJVR3xY
+WFgpOiIscjowfSkscn0sYS5DTENNPWEuQ19MSU5FX0NPTU1FTlRfTU9ERT1hLkMoIi8vIiwiJCIpLGEu
+Q0JDTT1hLkNfQkxPQ0tfQ09NTUVOVF9NT0RFPWEuQygiL1xcKiIsIlxcKi8iKSxhLkhDTT1hLkhBU0hf
+Q09NTUVOVF9NT0RFPWEuQygiIyIsIiQiKSxhLk5NPWEuTlVNQkVSX01PREU9e2NOOiJudW1iZXIiLGI6
+YS5OUixyOjB9LGEuQ05NPWEuQ19OVU1CRVJfTU9ERT17Y046Im51bWJlciIsYjphLkNOUixyOjB9LGEu
+Qk5NPWEuQklOQVJZX05VTUJFUl9NT0RFPXtjTjoibnVtYmVyIixiOmEuQk5SLHI6MH0sYS5DU1NOTT1h
+LkNTU19OVU1CRVJfTU9ERT17Y046Im51bWJlciIsYjphLk5SKyIoJXxlbXxleHxjaHxyZW18dnd8dmh8
+dm1pbnx2bWF4fGNtfG1tfGlufHB0fHBjfHB4fGRlZ3xncmFkfHJhZHx0dXJufHN8bXN8SHp8a0h6fGRw
+aXxkcGNtfGRwcHgpPyIscjowfSxhLlJNPWEuUkVHRVhQX01PREU9e2NOOiJyZWdleHAiLGI6L1wvLyxl
+Oi9cL1tnaW11eV0qLyxpOi9cbi8sYzpbYS5CRSx7YjovXFsvLGU6L1xdLyxyOjAsYzpbYS5CRV19XX0s
+YS5UTT1hLlRJVExFX01PREU9e2NOOiJ0aXRsZSIsYjphLklSLHI6MH0sYS5VVE09YS5VTkRFUlNDT1JF
+X1RJVExFX01PREU9e2NOOiJ0aXRsZSIsYjphLlVJUixyOjB9LGEuTUVUSE9EX0dVQVJEPXtiOiJcXC5c
+XHMqIithLlVJUixyOjB9LGF9KTtobGpzLnJlZ2lzdGVyTGFuZ3VhZ2UoInhtbCIsZnVuY3Rpb24ocyl7
+dmFyIGU9e2VXOiEwLGk6LzwvLHI6MCxjOlt7Y046ImF0dHIiLGI6IltBLVphLXowLTlcXC5fOi1dKyIs
+cjowfSx7YjovPVxzKi8scjowLGM6W3tjTjoic3RyaW5nIixlbmRzUGFyZW50OiEwLHY6W3tiOi8iLyxl
+Oi8iL30se2I6LycvLGU6LycvfSx7YjovW15ccyInPTw+YF0rL31dfV19XX07cmV0dXJue2FsaWFzZXM6
+WyJodG1sIiwieGh0bWwiLCJyc3MiLCJhdG9tIiwieGpiIiwieHNkIiwieHNsIiwicGxpc3QiLCJ3c2Yi
+XSxjSTohMCxjOlt7Y046Im1ldGEiLGI6IjwhRE9DVFlQRSIsZToiPiIscjoxMCxjOlt7YjoiXFxbIixl
+OiJcXF0ifV19LHMuQygiXHgzYyEtLSIsIi0tXHgzZSIse3I6MTB9KSx7YjoiPFxcIVxcW0NEQVRBXFxb
+IixlOiJcXF1cXF0+IixyOjEwfSx7Y046Im1ldGEiLGI6LzxcP3htbC8sZTovXD8+LyxyOjEwfSx7Yjov
+PFw/KHBocCk/LyxlOi9cPz4vLHNMOiJwaHAiLGM6W3tiOiIvXFwqIixlOiJcXCovIixza2lwOiEwfSx7
+YjonYiInLGU6JyInLHNraXA6ITB9LHtiOiJiJyIsZToiJyIsc2tpcDohMH0scy5pbmhlcml0KHMuQVNN
+LHtpOm51bGwsY046bnVsbCxjOm51bGwsc2tpcDohMH0pLHMuaW5oZXJpdChzLlFTTSx7aTpudWxsLGNO
+Om51bGwsYzpudWxsLHNraXA6ITB9KV19LHtjTjoidGFnIixiOiI8c3R5bGUoPz1cXHN8PnwkKSIsZToi
+PiIsazp7bmFtZToic3R5bGUifSxjOltlXSxzdGFydHM6e2U6Ijwvc3R5bGU+IixyRTohMCxzTDpbImNz
+cyIsInhtbCJdfX0se2NOOiJ0YWciLGI6IjxzY3JpcHQoPz1cXHN8PnwkKSIsZToiPiIsazp7bmFtZToi
+c2NyaXB0In0sYzpbZV0sc3RhcnRzOntlOiI8XC9zY3JpcHQ+IixyRTohMCxzTDpbImFjdGlvbnNjcmlw
+dCIsImphdmFzY3JpcHQiLCJoYW5kbGViYXJzIiwieG1sIiwidmJzY3JpcHQiXX19LHtjTjoidGFnIixi
+OiI8Lz8iLGU6Ii8/PiIsYzpbe2NOOiJuYW1lIixiOi9bXlwvPjxcc10rLyxyOjB9LGVdfV19fSk7aGxq
+cy5yZWdpc3Rlckxhbmd1YWdlKCJtYXJrZG93biIsZnVuY3Rpb24oZSl7cmV0dXJue2FsaWFzZXM6WyJt
+ZCIsIm1rZG93biIsIm1rZCJdLGM6W3tjTjoic2VjdGlvbiIsdjpbe2I6Il4jezEsNn0iLGU6IiQifSx7
+YjoiXi4rP1xcbls9LV17Mix9JCJ9XX0se2I6IjwiLGU6Ij4iLHNMOiJ4bWwiLHI6MH0se2NOOiJidWxs
+ZXQiLGI6Il5cXHMqKFsqKy1dfChcXGQrXFwuKSlcXHMrIn0se2NOOiJzdHJvbmciLGI6IlsqX117Mn0u
+Kz9bKl9dezJ9In0se2NOOiJlbXBoYXNpcyIsdjpbe2I6IlxcKi4rP1xcKiJ9LHtiOiJfLis/XyIscjow
+fV19LHtjTjoicXVvdGUiLGI6Il4+XFxzKyIsZToiJCJ9LHtjTjoiY29kZSIsdjpbe2I6Il5gYGB3KnMq
+JCIsZToiXmBgYHMqJCJ9LHtiOiJgLis/YCJ9LHtiOiJeKCB7NH18XHQpIixlOiIkIixyOjB9XX0se2I6
+Il5bLVxcKl17Myx9IixlOiIkIn0se2I6IlxcWy4rP1xcXVtcXChcXFtdLio/W1xcKVxcXV0iLHJCOiEw
+LGM6W3tjTjoic3RyaW5nIixiOiJcXFsiLGU6IlxcXSIsZUI6ITAsckU6ITAscjowfSx7Y046Imxpbmsi
+LGI6IlxcXVxcKCIsZToiXFwpIixlQjohMCxlRTohMH0se2NOOiJzeW1ib2wiLGI6IlxcXVxcWyIsZToi
+XFxdIixlQjohMCxlRTohMH1dLHI6MTB9LHtiOi9eXFtbXlxuXStcXTovLHJCOiEwLGM6W3tjTjoic3lt
+Ym9sIixiOi9cWy8sZTovXF0vLGVCOiEwLGVFOiEwfSx7Y046ImxpbmsiLGI6LzpccyovLGU6LyQvLGVC
+OiEwfV19XX19KTtobGpzLnJlZ2lzdGVyTGFuZ3VhZ2UoImRhcnQiLGZ1bmN0aW9uKGUpe3ZhciB0PXtj
+Tjoic3Vic3QiLHY6W3tiOiJcXCRbQS1aYS16MC05X10rIn1dfSxyPXtjTjoic3Vic3QiLHY6W3tiOiJc
+XCR7IixlOiJ9In1dLGs6InRydWUgZmFsc2UgbnVsbCB0aGlzIGlzIG5ldyBzdXBlciJ9LG49e2NOOiJz
+dHJpbmciLHY6W3tiOiJyJycnIixlOiInJycifSx7YjonciIiIicsZTonIiIiJ30se2I6InInIixlOiIn
+IixpOiJcXG4ifSx7YjonciInLGU6JyInLGk6IlxcbiJ9LHtiOiInJyciLGU6IicnJyIsYzpbZS5CRSx0
+LHJdfSx7YjonIiIiJyxlOiciIiInLGM6W2UuQkUsdCxyXX0se2I6IiciLGU6IiciLGk6IlxcbiIsYzpb
+ZS5CRSx0LHJdfSx7YjonIicsZTonIicsaToiXFxuIixjOltlLkJFLHQscl19XX07ci5jPVtlLkNOTSxu
+XTtyZXR1cm57azp7a2V5d29yZDoiYXNzZXJ0IGFzeW5jIGF3YWl0IGJyZWFrIGNhc2UgY2F0Y2ggY2xh
+c3MgY29uc3QgY29udGludWUgZGVmYXVsdCBkbyBlbHNlIGVudW0gZXh0ZW5kcyBmYWxzZSBmaW5hbCBm
+aW5hbGx5IGZvciBpZiBpbiBpcyBuZXcgbnVsbCByZXRocm93IHJldHVybiBzdXBlciBzd2l0Y2ggc3lu
+YyB0aGlzIHRocm93IHRydWUgdHJ5IHZhciB2b2lkIHdoaWxlIHdpdGggeWllbGQgYWJzdHJhY3QgYXMg
+ZHluYW1pYyBleHBvcnQgZXh0ZXJuYWwgZmFjdG9yeSBnZXQgaW1wbGVtZW50cyBpbXBvcnQgbGlicmFy
+eSBvcGVyYXRvciBwYXJ0IHNldCBzdGF0aWMgdHlwZWRlZiIsYnVpbHRfaW46InByaW50IENvbXBhcmFi
+bGUgRGF0ZVRpbWUgRHVyYXRpb24gRnVuY3Rpb24gSXRlcmFibGUgSXRlcmF0b3IgTGlzdCBNYXAgTWF0
+Y2ggTnVsbCBPYmplY3QgUGF0dGVybiBSZWdFeHAgU2V0IFN0b3B3YXRjaCBTdHJpbmcgU3RyaW5nQnVm
+ZmVyIFN0cmluZ1NpbmsgU3ltYm9sIFR5cGUgVXJpIGJvb2wgZG91YmxlIGludCBudW0gZG9jdW1lbnQg
+d2luZG93IHF1ZXJ5U2VsZWN0b3IgcXVlcnlTZWxlY3RvckFsbCBFbGVtZW50IEVsZW1lbnRMaXN0In0s
+YzpbbixlLkMoIi9cXCpcXCoiLCJcXCovIix7c0w6Im1hcmtkb3duIn0pLGUuQygiLy8vIiwiJCIse3NM
+OiJtYXJrZG93biJ9KSxlLkNMQ00sZS5DQkNNLHtjTjoiY2xhc3MiLGJLOiJjbGFzcyBpbnRlcmZhY2Ui
+LGU6InsiLGVFOiEwLGM6W3tiSzoiZXh0ZW5kcyBpbXBsZW1lbnRzIn0sZS5VVE1dfSxlLkNOTSx7Y046
+Im1ldGEiLGI6IkBbQS1aYS16XSsifSx7YjoiPT4ifV19fSk7Cg==
+''';
+
+String _index_html;
+// index_html md5 is 'f3749ede15251d6832acc370afaca966'
+String _index_html_base64 = '''
+PGh0bWw+CjxoZWFkPgogICAgPHRpdGxlPk51bGwgU2FmZXR5IFByZXZpZXc8L3RpdGxlPgogICAgPHNj
+cmlwdCBzcmM9Int7IGhpZ2hsaWdodEpzUGF0aCB9fSI+PC9zY3JpcHQ+CiAgICA8c2NyaXB0Pnt7IGRh
+cnRQYWdlU2NyaXB0IH19PC9zY3JpcHQ+CiAgICA8bGluayByZWw9InN0eWxlc2hlZXQiIGhyZWY9Imh0
+dHBzOi8vZm9udHMuZ29vZ2xlYXBpcy5jb20vY3NzP2ZhbWlseT1PcGVuK1NhbnM6NDAwLDYwMCZkaXNw
+bGF5PXN3YXAiPgogICAgPGxpbmsgcmVsPSJzdHlsZXNoZWV0IiBocmVmPSJ7eyBoaWdobGlnaHRTdHls
+ZVBhdGggfX0iPgogICAgPHN0eWxlPnt7IGRhcnRQYWdlU3R5bGUgfX08L3N0eWxlPgo8L2hlYWQ+Cjxi
+b2R5IGNsYXNzPSJ7eyBtaWdyYXRpb25BcHBsaWVkU3R5bGUgfX0ge3sgbmVlZHNSZXJ1blN0eWxlIH19
+Ij4KPGRpdiBjbGFzcz0icmVydW5uaW5nLXBhbmUiPgogIDxoMT5SZXJ1bm5pbmcuLi48L2gxPgo8L2Rp
+dj4KPGRpdiBjbGFzcz0icG9wdXAtcGFuZSI+CiAgPGRpdiBjbGFzcz0iY2xvc2UgYnV0dG9uIj5YPC9k
+aXY+CiAgPGgyPjwvaDI+PCEtLSBoZWFkZXIgcGxhY2Vob2xkZXIgZWxlbWVudCAtLT4KICA8cD48L3A+
+PCEtLSBzdWJoZWFkZXIgcGxhY2Vob2xkZXIgZWxlbWVudCAtLT4KICA8cHJlPjwvcHJlPjwhLS0gcHJl
+Zm9ybWF0ZWQgY29udGVudCBwbGFjZWhvbGRlciBlbGVtZW50IC0tPgogIDxhIGNsYXNzPSJidXR0b24g
+Ym90dG9tIiB0YXJnZXQ9Il9ibGFuayI+RmlsZSBvbiBHaXRIdWI8L2E+PCEtLSBwb3N0IHRvIGdpdGh1
+YiBwbGFjZWhvbGRlciBlbGVtZW50IC0tPgo8L2Rpdj4KPHAgY2xhc3M9InJvb3QiPnt7IHJvb3QgfX08
+L3A+CjxoZWFkZXIgY2xhc3M9ImVsZXZhdGlvbi16NCI+CiAgICA8aDEgY2xhc3M9ImJlZm9yZS1hcHBs
+eSI+UHJvcG9zZWQgbnVsbCBzYWZldHkgY2hhbmdlczwvaDE+CiAgICA8aDEgY2xhc3M9ImFmdGVyLWFw
+cGx5Ij4mIzEwMDAzOyBOdWxsIHNhZmV0eSBtaWdyYXRpb24gYXBwbGllZDwvaDE+CiAgICA8aDIgaWQ9
+InVuaXQtbmFtZSI+Jm5ic3A7PC9oMj4KICAgIDxidXR0b24gY2xhc3M9ImFwcGx5LW1pZ3JhdGlvbiI+
+JiM5OTk4OyBBcHBseSBNaWdyYXRpb248L2J1dHRvbj4KICAgIDxidXR0b24gY2xhc3M9ImFwcGx5LW1p
+Z3JhdGlvbiIgZGlzYWJsZWQ+JiM5OTk4OyBBcHBseSBNaWdyYXRpb248L2J1dHRvbj4KICAgIDxidXR0
+b24gY2xhc3M9InJlcnVuLW1pZ3JhdGlvbiBiZWZvcmUtYXBwbHkiPgogICAgICA8c3BhbiBjbGFzcz0i
+b3B0aW9uYWwiPiYjODYzNTsgUmVydW4gRnJvbSBTb3VyY2VzPC9zcGFuPgogICAgICA8c3BhbiBjbGFz
+cz0icmVxdWlyZWQiPgogICAgICAgIDxzcGFuIGNsYXNzPSJpY29uIiAKICAgICAgICAgIHRpdGxlPSJE
+aXNrIGNvbnRlbnRzIGhhdmUgY2hhbmdlZC4gUmVydW4gdG8gZ2V0IGFuIHVwLXRvLWRhdGUgbWlncmF0
+aW9uLiI+ITwvc3Bhbj4KICAgICAgICBSZXJ1biBXaXRoIENoYW5nZXMKICAgICAgPC9zcGFuPgogICAg
+PC9idXR0b24+CjwvaGVhZGVyPgo8ZGl2IGNsYXNzPSJwYW5lbHMgaG9yaXpvbnRhbCI+CiAgICA8ZGl2
+IGNsYXNzPSJuYXYtcGFuZWwiPgogICAgICAgIDxkaXYgY2xhc3M9Im5hdi1pbm5lciI+CiAgICAgICAg
+ICAgIDxkaXYgY2xhc3M9InBhbmVsLWhlYWRpbmciPlByb2plY3QgRmlsZXM8L2Rpdj4KICAgICAgICAg
+ICAgPGRpdiBjbGFzcz0ibmF2LXRyZWUiPjwvZGl2PgogICAgICAgIDwvZGl2PjwhLS0gL25hdi1pbm5l
+ciAtLT4KICAgIDwvZGl2PjwhLS0gL25hdiAtLT4KICAgIDxkaXYgY2xhc3M9ImNvbnRlbnQiPgogICAg
+ICAgIDxkaXYgY2xhc3M9InJlZ2lvbnMiPgogICAgICAgICAgICA8IS0tIFRoZSByZWdpb25zIG92ZXJs
+YXkgY29kZSBjb3B5IG9mIHRoZSBjb250ZW50IHRvIHByb3ZpZGUgLS0+CiAgICAgICAgICAgIDwhLS0g
+dG9vbHRpcHMgZm9yIG1vZGlmaWVkIHJlZ2lvbnMuIC0tPgogICAgICAgIDwvZGl2PjwhLS0gL3JlZ2lv
+bnMgLS0+CiAgICAgICAgPGRpdiBjbGFzcz0iY29kZSI+CiAgICAgICAgICAgIDwhLS0gQ29tcGlsYXRp
+b24gdW5pdCBjb250ZW50IGlzIHdyaXR0ZW4gaGVyZS4gLS0+CiAgICAgICAgICAgIDxwIGNsYXNzPSJ3
+ZWxjb21lIj4KICAgICAgICAgICAgICAgIFNlbGVjdCBhIHNvdXJjZSBmaWxlIG9uIHRoZSBsZWZ0IHRv
+IHByZXZpZXcgdGhlIHByb3Bvc2VkIGVkaXRzLgogICAgICAgICAgICA8L3A+CiAgICAgICAgPC9kaXY+
+CiAgICA8L2Rpdj48IS0tIC9jb250ZW50IC0tPgogICAgPGRpdiBjbGFzcz0iaW5mby1wYW5lbCI+CiAg
+ICAgICAgPGRpdiBjbGFzcz0iZWRpdC1saXN0Ij4KICAgICAgICAgICAgPGRpdiBjbGFzcz0icGFuZWwt
+aGVhZGluZyI+UHJvcG9zZWQgRWRpdHM8L2Rpdj4KICAgICAgICAgICAgPGRpdiBjbGFzcz0icGFuZWwt
+Y29udGVudCI+PC9kaXY+CiAgICAgICAgPC9kaXY+PCEtLSAvZWRpdC1saXN0IC0tPgogICAgICAgIDxk
+aXYgY2xhc3M9ImVkaXQtcGFuZWwiPgogICAgICAgICAgICA8ZGl2IGNsYXNzPSJwYW5lbC1oZWFkaW5n
+Ij5FZGl0IERldGFpbHM8L2Rpdj4KICAgICAgICAgICAgPGRpdiBjbGFzcz0icGFuZWwtY29udGVudCI+
+CiAgICAgICAgICAgICAgICA8cCBjbGFzcz0icGxhY2Vob2xkZXIiPlNlZSBkZXRhaWxzIGFib3V0IGEg
+cHJvcG9zZWQgZWRpdC48L3A+CiAgICAgICAgICAgIDwvZGl2PjwhLS0gL3BhbmVsLWNvbnRlbnQgLS0+
+CiAgICAgICAgPC9kaXY+PCEtLSAvZWRpdC1wYW5lbCAtLT4KICAgIDwvZGl2PjwhLS0gL2luZm8tcGFu
+ZWwgLS0+CjwvZGl2PjwhLS0gL3BhbmVscyAtLT4KPGZvb3Rlcj4KICAgIDxhIHRhcmdldD0iX2JsYW5r
+IgogICAgICBocmVmPSJodHRwczovL2dvby5nbGUvZGFydC1udWxsLXNhZmV0eS1taWdyYXRpb24tdG9v
+bCI+TnVsbCBzYWZldHkKICAgICAgICBtaWdyYXRpb24gaGVscDwvYT4KICAgIDxzcGFuIGNsYXNzPSJ3
+aWRlIj4gPC9zcGFuPgogICAgPGRpdj5CYXNlZCBvbiB7eyBzZGtWZXJzaW9uIH19PC9kaXY+CiAgICA8
+YnV0dG9uIGNsYXNzPSJyZXBvcnQtcHJvYmxlbSI+UmVwb3J0IGEgUHJvYmxlbTwvYnV0dG9uPgo8L2Zv
+b3Rlcj4KPC9ib2R5Pgo8L2h0bWw+Cg==
+''';
+
+String _migration_css;
+// migration_css md5 is '3ac37808bdb8d07efd1c9ce21b67fccc'
+String _migration_css_base64 = '''
+LyogQ29weXJpZ2h0IChjKSAyMDE5LCB0aGUgRGFydCBwcm9qZWN0IGF1dGhvcnMuIFBsZWFzZSBzZWUg
+dGhlIEFVVEhPUlMgZmlsZSAgKi8KLyogZm9yIGRldGFpbHMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuIFVz
+ZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGEgKi8KLyogQlNELXN0eWxlIGxpY2Vu
+c2UgdGhhdCBjYW4gYmUgZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZS4gICAgICAgICAgICAgICAgICAg
+Ki8KCmJvZHkgewogIGJhY2tncm91bmQtY29sb3I6ICMxMjIwMmY7CiAgY29sb3I6ICNjY2M7CiAgZm9u
+dC1mYW1pbHk6ICJSb2JvdG8iLCBzYW5zLXNlcmlmOwogIGZvbnQtc2l6ZTogMTRweDsKICBkaXNwbGF5
+OiBmbGV4OwogIGZsZXgtZGlyZWN0aW9uOiBjb2x1bW47CiAgcG9zaXRpb246IGFic29sdXRlOwogIHRv
+cDogMDsKICByaWdodDogMDsKICBib3R0b206IDA7CiAgbGVmdDogMDsKICBtYXJnaW46IDA7CiAgcGFk
+ZGluZzogMDsKICBvdmVyZmxvdzogaGlkZGVuOwp9CgoucHJvcG9zZWQgLmFmdGVyLWFwcGx5IHsKICBk
+aXNwbGF5OiBub25lOwp9CgouYXBwbGllZCAuYmVmb3JlLWFwcGx5IHsKICBkaXNwbGF5OiBub25lOwp9
+CgouYXBwbGllZCAuYXBwbHktbWlncmF0aW9uOm5vdChbZGlzYWJsZWRdKSwgLm5lZWRzLXJlcnVuIC5h
+cHBseS1taWdyYXRpb246bm90KFtkaXNhYmxlZF0pIHsKICBkaXNwbGF5OiBub25lOwp9CgoucHJvcG9z
+ZWQ6bm90KC5uZWVkcy1yZXJ1bikgLmFwcGx5LW1pZ3JhdGlvbltkaXNhYmxlZF0gewogIGRpc3BsYXk6
+IG5vbmU7Cn0KCmhlYWRlciB7CiAgYmFja2dyb3VuZC1jb2xvcjogIzFjMjgzNDsKICBoZWlnaHQ6IDQ4
+cHg7CiAgcGFkZGluZy1sZWZ0OiAyNHB4OwogIGFsaWduLWl0ZW1zOiBjZW50ZXI7CiAgei1pbmRleDog
+NDsKfQoKaGVhZGVyIGgxLApoZWFkZXIgaDIgewogIGRpc3BsYXk6IGlubGluZS1ibG9jazsKICBmb250
+LWZhbWlseTogIkdvb2dsZSBTYW5zIiwiUm9ib3RvIixzYW5zLXNlcmlmOwogIGZvbnQtd2VpZ2h0OiA0
+MDA7CiAgbWFyZ2luLXJpZ2h0OiAyNHB4Owp9CgpoMSB7CiAgZm9udC1zaXplOiAxLjVlbTsKfQoKaGVh
+ZGVyIGgyIHsKICBmb250LXNpemU6IDEuMmVtOwp9CgpoZWFkZXIgLmFwcGx5LW1pZ3JhdGlvbiwgLnJl
+cnVuLW1pZ3JhdGlvbiB7CiAgcmlnaHQ6IDBweDsKICBmbG9hdDogcmlnaHQ7CiAgbWFyZ2luOiAxMHB4
+Owp9Cgpmb290ZXIgLnJlcG9ydC1wcm9ibGVtIHsKICByaWdodDogMHB4OwogIG1hcmdpbjogNHB4IDhw
+eDsKfQoKLnJlcnVuLW1pZ3JhdGlvbiAucmVxdWlyZWQgewogIGRpc3BsYXk6IG5vbmU7Cn0KCi5uZWVk
+cy1yZXJ1biAucmVydW4tbWlncmF0aW9uIC5yZXF1aXJlZCB7CiAgZGlzcGxheTogaW5pdGlhbDsKfQoK
+Lm5lZWRzLXJlcnVuIC5yZXJ1bi1taWdyYXRpb24gLm9wdGlvbmFsIHsKICBkaXNwbGF5Om5vbmU7Cn0K
+Ci8qIFJlZCB0cmlhbmdsZSAqLwoucmVydW4tbWlncmF0aW9uIC5yZXF1aXJlZCAuaWNvbjo6YmVmb3Jl
+IHsKICB0cmFuc2Zvcm06IHRyYW5zbGF0ZSgtOHB4LCAtMTFweCk7CiAgY29udGVudDogJ1wyNUIzJzsK
+ICBmb250LXNpemU6IDI1cHg7CiAgcG9zaXRpb246IGZpeGVkOwogIGNvbG9yOiAjZTgyYzJjOwogIHRl
+eHQtc2hhZG93OiAwcHggMHB4IDVweCB3aGl0ZTsKICB6LWluZGV4OiAtMzsKfQoKLyogUmVkIHRyaWFu
+Z2xlIGZpbGwgKi8KLnJlcnVuLW1pZ3JhdGlvbiAucmVxdWlyZWQgLmljb246OmFmdGVyIHsKICB0cmFu
+c2Zvcm06IHRyYW5zbGF0ZSgtOXB4LCAtMTBweCk7CiAgY29udGVudDogJ1wyNUI0JzsKICBmb250LXNp
+emU6IDI1cHg7CiAgcG9zaXRpb246IGZpeGVkOwogIGNvbG9yOiAjYjNlY2ZmOwogIHotaW5kZXg6IC0x
+Owp9CgovKiBSZWQgdHJpYW5nbGUgZXhjbGFtYXRpb24gKi8KLnJlcnVuLW1pZ3JhdGlvbiAucmVxdWly
+ZWQgLmljb24gewogIGRpc3BsYXk6IGlubGluZS1ibG9jazsKICBtYXJnaW4tcmlnaHQ6IDhweDsKICB0
+cmFuc2Zvcm06IHRyYW5zbGF0ZSgwcHgsIDJweCk7CiAgbWFyZ2luLWxlZnQ6IDJweDsKICBjb2xvcjog
+IzJiMmIyYjsKfQoKZm9vdGVyIHsKICBjb2xvcjogI2NjYzsKICBiYWNrZ3JvdW5kLWNvbG9yOiAjMjcz
+MjNhOwogIGRpc3BsYXk6IGZsZXg7CiAgZmxleC1kaXJlY3Rpb246IHJvdzsKICBhbGlnbi1pdGVtczog
+Y2VudGVyOwogIHBhZGRpbmc6IDhweCAwIDhweCAyNHB4Owp9Cgpmb290ZXIgLndpZGUgewogIGZsZXg6
+IDE7Cn0KCi5ob3Jpem9udGFsIHsKICBkaXNwbGF5OiBmbGV4Owp9CgoucGFuZWxzIHsKICBiYWNrZ3Jv
+dW5kLWNvbG9yOiAjMTIxYTI1OwogIGZsZXg6IDE7CiAgb3ZlcmZsb3c6IGhpZGRlbjsKfQoKLnBhbmVs
+LWhlYWRpbmcgewogIGNvbG9yOiBncmF5OwogIG1hcmdpbjogOHB4Owp9CgoubmF2LWxpbmssCi5yZWdp
+b24gewogIGN1cnNvcjogcG9pbnRlcjsKfQoKLm5hdi1wYW5lbCB7CiAgYmFja2dyb3VuZC1jb2xvcjog
+IzI4MmIyZTsKICBmbGV4OiAxIDIwMHB4OwogIG1hcmdpbjogMDsKICBvdmVyZmxvdzogc2Nyb2xsOwp9
+CgoubmF2LWlubmVyIHsKICBwYWRkaW5nOiAwIDAgN3B4IDdweDsKfQoKLmZpeGVkIHsKICBwb3NpdGlv
+bjogZml4ZWQ7CiAgdG9wOiAwOwp9Cgoucm9vdCB7CiAgbWFyZ2luOiAwOwogIGRpc3BsYXk6IG5vbmU7
+Cn0KCi5uYXYtdHJlZSA+IHVsIHsKICBwYWRkaW5nLWxlZnQ6IDZweDsKfQoKLm5hdi1pbm5lciB1bCB7
+CiAgcGFkZGluZy1sZWZ0OiAxMnB4OwogIG1hcmdpbjogMDsKfQoKLm5hdi1pbm5lciBsaSB7CiAgbGlz
+dC1zdHlsZS10eXBlOiBub25lOwp9CgoubmF2LWlubmVyIGxpOm5vdCguZGlyKSB7CiAgbWFyZ2luLWxl
+ZnQ6IDIwcHg7CiAgbWFyZ2luLWJvdHRvbTogM3B4Owp9CgoubmF2LWlubmVyIGxpLmRpciAuYXJyb3cg
+ewogIGN1cnNvcjogcG9pbnRlcjsKICBkaXNwbGF5OiBpbmxpbmUtYmxvY2s7CiAgZm9udC1zaXplOiAx
+MHB4OwogIG1hcmdpbi1yaWdodDogNHB4OwogIHRyYW5zaXRpb246IHRyYW5zZm9ybSAwLjVzIGVhc2Ut
+b3V0Owp9CgoubmF2LWlubmVyIGxpLmRpciAuYXJyb3cuY29sbGFwc2VkIHsKICB0cmFuc2Zvcm06IHJv
+dGF0ZSgtOTBkZWcpOwp9CgoubmF2LWlubmVyIHVsIHsKICBtYXgtaGVpZ2h0OiAyMDAwcHg7CiAgdHJh
+bnNpdGlvbjogbWF4LWhlaWdodCAwLjVzIGVhc2Utb3V0Owp9CgoubmF2LWlubmVyIHVsLmNvbGxhcHNl
+ZCB7CiAgbWF4LWhlaWdodDogMCAhaW1wb3J0YW50OwogIG92ZXJmbG93OiBoaWRkZW47Cn0KCi5uYXYt
+aW5uZXIgLnNlbGVjdGVkLWZpbGUgewogIGNvbG9yOiB3aGl0ZTsKICBjdXJzb3I6IGluaGVyaXQ7CiAg
+Zm9udC13ZWlnaHQ6IDYwMDsKICB0ZXh0LWRlY29yYXRpb246IG5vbmU7Cn0KCi5lZGl0LWNvdW50IHsK
+ICBiYWNrZ3JvdW5kLWNvbG9yOiAjMzdhZWRjOwogIGJvcmRlci1yYWRpdXM6IDEwcHg7CiAgY29sb3I6
+ICMwMDAwMDA7CiAgZGlzcGxheTogaW5saW5lLWJsb2NrOwogIGZvbnQtc2l6ZTogMTFweDsKICBmb250
+LXdlaWdodDogNjAwOwogIG1hcmdpbi1sZWZ0OiA1cHg7CiAgbWluLXdpZHRoOiAyNXB4OwogIHBhZGRp
+bmc6IDRweCAwIDJweCAwOwogIHRleHQtYWxpZ246IGNlbnRlcjsKICBsaW5lLWhlaWdodDogMWVtOwp9
+CgouY29udGVudCB7CiAgZmxleDogNCAzMDBweDsKICBiYWNrZ3JvdW5kOiAjMjgyYjJlOwogIGZvbnQt
+ZmFtaWx5OiBtb25vc3BhY2U7CiAgbWFyZ2luOiAwIDZweDsKICBwb3NpdGlvbjogcmVsYXRpdmU7CiAg
+d2hpdGUtc3BhY2U6IHByZTsKICBvdmVyZmxvdzogc2Nyb2xsOwp9CgouY29kZSB7CiAgcGFkZGluZzog
+MC41ZW07CiAgcG9zaXRpb246IGFic29sdXRlOwogIGxlZnQ6IDA7CiAgdG9wOiAwOwogIG1hcmdpbi1s
+ZWZ0OiA1NnB4Owp9CgouaGxqcyB7CiAgYmFja2dyb3VuZC1jb2xvcjogIzI4MmIyZTsKICBkaXNwbGF5
+OiBibG9jazsKICBvdmVyZmxvdy14OiBhdXRvOwogIHBhZGRpbmc6IDAuNWVtOwp9CgouY29kZSAud2Vs
+Y29tZSB7CiAgZm9udC1mYW1pbHk6ICJHb29nbGUgU2FucyIsIlJvYm90byIsc2Fucy1zZXJpZjsKICBm
+b250LXNpemU6IDE4cHg7CiAgbWFyZ2luLXJpZ2h0OiA2MnB4OwogIGNvbG9yOiAjNzc3Owp9CgouY29k
+ZSAubmF2LWxpbmsgewogIGNvbG9yOiBpbmhlcml0OwogIHRleHQtZGVjb3JhdGlvbi1saW5lOiBub25l
+Owp9CgouY29kZSAubmF2LWxpbms6dmlzaXRlZCB7CiAgY29sb3I6IGluaGVyaXQ7CiAgdGV4dC1kZWNv
+cmF0aW9uLWxpbmU6IG5vbmU7Cn0KCi5jb2RlIC5uYXYtbGluazpob3ZlciB7CiAgdGV4dC1kZWNvcmF0
+aW9uLWxpbmU6IHVuZGVybGluZTsKICBmb250LXdlaWdodDogNjAwOwp9CgoucmVnaW9ucyB7CiAgcGFk
+ZGluZzogMC41ZW07CiAgcG9zaXRpb246IGFic29sdXRlOwogIGxlZnQ6IDA7CiAgdG9wOiAwOwp9Cgou
+cmVnaW9ucyB0YWJsZSB7CiAgYm9yZGVyLXNwYWNpbmc6IDA7CiAgZm9udC1zaXplOiBpbmhlcml0Owp9
+CgoucmVnaW9ucyB0ZCB7CiAgYm9yZGVyOiBub25lOwogIC8qIFRoZSBjb250ZW50IG9mIHRoZSByZWdp
+b25zIGlzIG5vdCB2aXNpYmxlOyB0aGUgdXNlciBpbnN0ZWFkIHdpbGwgc2VlIHRoZQogICAqIGhpZ2hs
+aWdodGVkIGNvcHkgb2YgdGhlIGNvbnRlbnQuICovCiAgY29sb3I6IHJnYmEoMjU1LCAyNTUsIDI1NSwg
+MCk7CiAgcGFkZGluZzogMDsKICB3aGl0ZS1zcGFjZTogcHJlOwp9CgoucmVnaW9ucyB0ZDplbXB0eTph
+ZnRlciB7CiAgY29udGVudDogIlwwMGEwIjsKfQoKLnJlZ2lvbnMgdHIuaGlnaGxpZ2h0IHRkOmxhc3Qt
+Y2hpbGQgewogIGJhY2tncm91bmQtY29sb3I6ICM0NDQ0NDQ7CiAgY29sb3I6IHdoaXRlOwp9CgoucmVn
+aW9ucyB0ZC5saW5lLW5vIHsKICBib3JkZXItcmlnaHQ6IHNvbGlkICMyODJiMmUgMnB4OwogIGNvbG9y
+OiAjOTk5OTk5OwogIHBhZGRpbmctcmlnaHQ6IDRweDsKICB0ZXh0LWFsaWduOiByaWdodDsKICB2aXNp
+YmlsaXR5OiB2aXNpYmxlOwogIHdpZHRoOiA1MHB4OwogIGRpc3BsYXk6IGlubGluZS1ibG9jazsKfQoK
+LnJlZ2lvbnMgdHIuaGlnaGxpZ2h0IHRkLmxpbmUtbm8gewogIGJvcmRlci1yaWdodDogc29saWQgI2Nj
+YyAycHg7Cn0KCi5yZWdpb24gewogIGRpc3BsYXk6IGlubGluZS1ibG9jazsKICBwb3NpdGlvbjogcmVs
+YXRpdmU7CiAgdmlzaWJpbGl0eTogdmlzaWJsZTsKICB6LWluZGV4OiAyMDA7Cn0KCi5yZWdpb24uYWRk
+ZWQtcmVnaW9uIHsKICBiYWNrZ3JvdW5kLWNvbG9yOiAjY2NmZmNjOwogIGNvbG9yOiAjMDAzMzAwOwp9
+CgoucmVnaW9uLnJlbW92ZWQtcmVnaW9uIHsKICBiYWNrZ3JvdW5kLWNvbG9yOiAjZmY2NjY2OwogIGNv
+bG9yOiAjMDAxMTAwOwp9CgoucmVnaW9uLmluZm9ybWF0aXZlLXJlZ2lvbiB7CiAgYmFja2dyb3VuZC1j
+b2xvcjogIzg4ODg4ODsKICBjb2xvcjogIzAwMDAwMDsKfQoKLnRhcmdldCB7CiAgYmFja2dyb3VuZC1j
+b2xvcjogIzQ0NDsKICBwb3NpdGlvbjogcmVsYXRpdmU7CiAgdmlzaWJpbGl0eTogdmlzaWJsZTsKICBm
+b250LXdlaWdodDogNjAwOwp9CgouaW5mby1wYW5lbCB7CiAgZmxleDogMSAyMDBweDsKICBtYXJnaW46
+IDA7CiAgaGVpZ2h0OiAxMDAlOwogIGRpc3BsYXk6IGZsZXg7CiAgZmxleC1kaXJlY3Rpb246IGNvbHVt
+bjsKfQoKLmluZm8tcGFuZWwgLmVkaXQtcGFuZWwgewogIGJhY2tncm91bmQtY29sb3I6ICMyODJiMmU7
+CiAgb3ZlcmZsb3c6IGF1dG87Cn0KCi5pbmZvLXBhbmVsIC5wYW5lbC1jb250ZW50IHsKICBwYWRkaW5n
+OiA3cHg7Cn0KCi5pbmZvLXBhbmVsIC5wYW5lbC1jb250ZW50PiA6Zmlyc3QtY2hpbGQgewogIG1hcmdp
+bi10b3A6IDA7Cn0KCi5pbmZvLXBhbmVsIC5ub3dyYXAgewogIHdoaXRlLXNwYWNlOiBub3dyYXA7Cn0K
+Ci5pbmZvLXBhbmVsIHVsLAouaW5mby1wYW5lbCBvbCB7CiAgcGFkZGluZy1sZWZ0OiAyMHB4Owp9Cgou
+aW5mby1wYW5lbCBsaSB7CiAgbWFyZ2luOiAwIDAgNXB4IDA7Cn0KCi5pbmZvLXBhbmVsIGEgewogIGNv
+bG9yOiAjMzNjY2ZmOwp9CgouaW5mby1wYW5lbCAuZWRpdC1saXN0IHsKICBiYWNrZ3JvdW5kLWNvbG9y
+OiAjMjgyYjJlOwogIG92ZXJmbG93OiBhdXRvOwp9CgouZWRpdC1wYW5lbCB7CiAgbWFyZ2luLXRvcDog
+NnB4OwogIGZsZXg6IDEgMTAwcHg7Cn0KCi5lZGl0LWxpc3QgewogIGZsZXg6IDIgMTAwcHg7Cn0KCi5l
+ZGl0LWxpc3QgLmVkaXQgewogIG1hcmdpbjogM3B4IDA7Cn0KCi5lZGl0LWxpc3QgLmVkaXQtbGluayB7
+CiAgY3Vyc29yOiBwb2ludGVyOwp9CgoucG9wdXAtcGFuZSB7CiAgZGlzcGxheTogbm9uZTsKICBwb3Np
+dGlvbjogZml4ZWQ7CiAgdG9wOiAxNTBweDsKICBsZWZ0OiAxNTBweDsKICByaWdodDogMTUwcHg7CiAg
+Ym90dG9tOiAxNTBweDsKICBib3JkZXI6IDFweCBzb2xpZCBibGFjazsKICBib3JkZXItdG9wOiAycHgg
+c29saWQgYmxhY2s7CiAgYm9yZGVyLXJhZGl1czogN3B4OwogIGJveC1zaGFkb3c6IDBweCAwcHggMjBw
+eCAycHggI2I0YmZjYjIyOwogIHotaW5kZXg6IDE7CiAgYmFja2dyb3VuZDogIzJiMzAzNjsKICBwYWRk
+aW5nOiAyMHB4Owp9CgoucG9wdXAtcGFuZSAuY2xvc2UgewogIHBvc2l0aW9uOiBhYnNvbHV0ZTsKICBy
+aWdodDogMTBweDsKICB0b3A6IDEwcHg7CiAgY3Vyc29yOiBwb2ludGVyOwogIHRleHQtc2hhZG93OiAx
+cHggMXB4IDJweCAjODg4OwogIGJveC1zaGFkb3c6IDFweCAxcHggMnB4ICMxMTE7Cn0KCi5wb3B1cC1w
+YW5lIGgyIHsKICBwYWRkaW5nOiAyMXB4OwogIGhlaWdodDogMTAlOwogIG1hcmdpbjogMHB4OwogIGJv
+eC1zaXppbmc6IGJvcmRlci1ib3g7Cn0KCi5wb3B1cC1wYW5lIHAgewogIGhlaWdodDogMTAlOwogIGJv
+eC1zaXppbmc6IGJvcmRlci1ib3g7CiAgcGFkZGluZzogMHB4IDIwcHg7Cn0KCi5wb3B1cC1wYW5lIHBy
+ZSB7CiAgYmFja2dyb3VuZDogIzI4MmIyZTsKICBwYWRkaW5nOiAyMHB4OwogIGJvdHRvbTogMHB4Owog
+IG92ZXJmbG93OiBhdXRvIHNjcm9sbDsKICBoZWlnaHQ6IDY1JTsKICBtYXJnaW46IDBweDsKICBib3gt
+c2l6aW5nOiBib3JkZXItYm94Owp9CgoucG9wdXAtcGFuZSAuYnV0dG9uLmJvdHRvbSB7CiAgbWFyZ2lu
+OiAyMHB4IDBweDsKICBkaXNwbGF5OiBibG9jazsKICB0ZXh0LWFsaWduOiBjZW50ZXI7Cn0KCi5yZXJ1
+bm5pbmctcGFuZSB7CiAgZGlzcGxheTogbm9uZTsKfQoKYm9keS5yZXJ1bm5pbmcgLnJlcnVubmluZy1w
+YW5lIHsKICBkaXNwbGF5OiBibG9jazsKICBwb3NpdGlvbjogZml4ZWQ7CiAgdG9wOiAwcHg7CiAgYm90
+dG9tOiAwcHg7CiAgbGVmdDogMHB4OwogIHJpZ2h0OiAwcHg7CiAgYmFja2dyb3VuZC1jb2xvcjogIzAw
+MDAwMEFBOyAvKiB0cmFuc2x1Y2VudCBibGFjayAqLwogIHotaW5kZXg6IDQwMDsKfQoKLnJlcnVubmlu
+Zy1wYW5lIGgxIHsKICBwb3NpdGlvbjogYWJzb2x1dGU7CiAgdG9wOiA1MCU7CiAgbGVmdDogNTAlOwog
+IHRyYW5zZm9ybTogdHJhbnNsYXRlKC01MCUsIC01MCUpOwp9CgpwLnRyYWNlIC50eXBlLWRlc2NyaXB0
+aW9uIHsKICAvKiBGcm9tIEhMSlMncyAuaGxqcy1rZXl3b3JkLCAuaGxqcy1zZWxlY3Rvci10YWcsIC5o
+bGpzLWRlbGV0aW9uICovCiAgY29sb3I6ICNjYzc4MzI7CiAgZm9udC1mYW1pbHk6IG1vbm9zcGFjZTsK
+fQoKdWwudHJhY2UgewogIGZvbnQtc2l6ZTogMTNweDsKICBsaXN0LXN0eWxlLXR5cGU6IG5vbmU7CiAg
+cGFkZGluZy1sZWZ0OiAwcHg7Cn0KCnVsLnRyYWNlIGxpIHsKICBjb2xvcjogd2hpdGU7CiAgbWFyZ2lu
+LWxlZnQ6IDE0cHg7CiAgdGV4dC1pbmRlbnQ6IC0xNHB4Owp9Cgp1bC50cmFjZSBsaSAuZnVuY3Rpb24g
+ewogIC8qIEZyb20gSExKUydzIC5obGpzLXNlY3Rpb24sIC5obGpzLXRpdGxlLCAuaGxqcy10eXBlICov
+CiAgY29sb3I6ICNmZmM2NmQ7CiAgZm9udC1mYW1pbHk6IG1vbm9zcGFjZTsKICBmb250LXdlaWdodDog
+NjAwOwp9CgouZWxldmF0aW9uLXo0IHsKICBib3gtc2hhZG93OiAwcHggMnB4IDRweCAtMXB4IHJnYmEo
+MCwgMCwgMCwgMC4yKSwKICAgICAgMHB4IDRweCA1cHggMHB4IHJnYmEoMCwgMCwgMCwgMC4xNCksCiAg
+ICAgIDBweCAxcHggMTBweCAwcHggcmdiYSgwLCAwLCAwLCAuMTIpOwp9CgphIHsKICBjb2xvcjogI2Nj
+YzsKICBmaWxsOiAjY2NjOwogIHRleHQtZGVjb3JhdGlvbjogbm9uZTsKfQoKYTpob3ZlciB7CiAgY29s
+b3I6ICNmZmY7CiAgZmlsbDogI2ZmZjsKfQoKLmFkZC1oaW50LWxpbmsgewogIGRpc3BsYXk6IGlubGlu
+ZS1ibG9jazsKICBtYXJnaW46IDNweDsKfQoKYnV0dG9uLCBhLmJ1dHRvbiB7CiAgYmFja2dyb3VuZC1j
+b2xvcjogIzMzY2NmZjsKICBib3JkZXI6IDJweCBzb2xpZCAjMzdhZWRjOwogIGJvcmRlci1yYWRpdXM6
+IDNweDsKICBwYWRkaW5nOiA2cHggMTBweDsKICBmb250LXdlaWdodDogYm9sZDsKICBjb2xvcjogIzI4
+MjgyODsKfQoKYnV0dG9uOmhvdmVyLCAuYnV0dG9uOmhvdmVyIHsKICBiYWNrZ3JvdW5kLWNvbG9yOiAj
+ODBkZmZmOwogIGJvcmRlcjogMnB4IHNvbGlkICM1MmI4ZTA7CiAgY3Vyc29yOiBwb2ludGVyOwp9Cgpi
+dXR0b25bZGlzYWJsZWRdIHsKICBiYWNrZ3JvdW5kLWNvbG9yOiAjN2FhOGI4OwogIGNvbG9yOiAjNTA3
+MTc3OwogIGJvcmRlcjogMnB4IHNvbGlkICM1MDcxNzc7CiAgY3Vyc29yOiBub3QtYWxsb3dlZDsKfQoK
+LnBsYWNlaG9sZGVyIHsKICBjb2xvcjogIzc3NzsKICB0ZXh0LWFsaWduOiBjZW50ZXI7CiAgbWFyZ2lu
+LXRvcDogM2VtICFpbXBvcnRhbnQ7Cn0KCi8qKgogKiBITEpTIE92ZXJyaWRlcwogKi8KLmhsanMgewog
+IC8qKgogICAqIFRoaXMgYWxsb3dzIHRoZSBwZXItbGluZSBoaWdobGlnaHRzIHRvIHNob3cuCiAgICov
+CiAgYmFja2dyb3VuZDogbm9uZTsKfQo=
+''';
+
+String _migration_js;
+// migration_dart md5 is '4517c0056bd2b39ccf2a244d0548213d'
+String _migration_js_base64 = '''
+KGZ1bmN0aW9uIGRhcnRQcm9ncmFtKCl7ZnVuY3Rpb24gY29weVByb3BlcnRpZXMoYSxiKXt2YXIgdD1P
+YmplY3Qua2V5cyhhKQpmb3IodmFyIHM9MDtzPHQubGVuZ3RoO3MrKyl7dmFyIHI9dFtzXQpiW3JdPWFb
+cl19fXZhciB6PWZ1bmN0aW9uKCl7dmFyIHQ9ZnVuY3Rpb24oKXt9CnQucHJvdG90eXBlPXtwOnt9fQp2
+YXIgcz1uZXcgdCgpCmlmKCEocy5fX3Byb3RvX18mJnMuX19wcm90b19fLnA9PT10LnByb3RvdHlwZS5w
+KSlyZXR1cm4gZmFsc2UKdHJ5e2lmKHR5cGVvZiBuYXZpZ2F0b3IhPSJ1bmRlZmluZWQiJiZ0eXBlb2Yg
+bmF2aWdhdG9yLnVzZXJBZ2VudD09InN0cmluZyImJm5hdmlnYXRvci51c2VyQWdlbnQuaW5kZXhPZigi
+Q2hyb21lLyIpPj0wKXJldHVybiB0cnVlCmlmKHR5cGVvZiB2ZXJzaW9uPT0iZnVuY3Rpb24iJiZ2ZXJz
+aW9uLmxlbmd0aD09MCl7dmFyIHI9dmVyc2lvbigpCmlmKC9eXGQrXC5cZCtcLlxkK1wuXGQrJC8udGVz
+dChyKSlyZXR1cm4gdHJ1ZX19Y2F0Y2gocSl7fXJldHVybiBmYWxzZX0oKQpmdW5jdGlvbiBzZXRGdW5j
+dGlvbk5hbWVzSWZOZWNlc3NhcnkoYSl7ZnVuY3Rpb24gdCgpe307aWYodHlwZW9mIHQubmFtZT09InN0
+cmluZyIpcmV0dXJuCmZvcih2YXIgdD0wO3Q8YS5sZW5ndGg7dCsrKXt2YXIgcz1hW3RdCnZhciByPU9i
+amVjdC5rZXlzKHMpCmZvcih2YXIgcT0wO3E8ci5sZW5ndGg7cSsrKXt2YXIgcD1yW3FdCnZhciBvPXNb
+cF0KaWYodHlwZW9mIG89PSdmdW5jdGlvbicpby5uYW1lPXB9fX1mdW5jdGlvbiBpbmhlcml0KGEsYil7
+YS5wcm90b3R5cGUuY29uc3RydWN0b3I9YQphLnByb3RvdHlwZVsiJGkiK2EubmFtZV09YQppZihiIT1u
+dWxsKXtpZih6KXthLnByb3RvdHlwZS5fX3Byb3RvX189Yi5wcm90b3R5cGUKcmV0dXJufXZhciB0PU9i
+amVjdC5jcmVhdGUoYi5wcm90b3R5cGUpCmNvcHlQcm9wZXJ0aWVzKGEucHJvdG90eXBlLHQpCmEucHJv
+dG90eXBlPXR9fWZ1bmN0aW9uIGluaGVyaXRNYW55KGEsYil7Zm9yKHZhciB0PTA7dDxiLmxlbmd0aDt0
+KyspaW5oZXJpdChiW3RdLGEpfWZ1bmN0aW9uIG1peGluKGEsYil7Y29weVByb3BlcnRpZXMoYi5wcm90
+b3R5cGUsYS5wcm90b3R5cGUpCmEucHJvdG90eXBlLmNvbnN0cnVjdG9yPWF9ZnVuY3Rpb24gbGF6eShh
+LGIsYyxkKXt2YXIgdD1hCmFbYl09dAphW2NdPWZ1bmN0aW9uKCl7YVtjXT1mdW5jdGlvbigpe0guYWco
+Yil9CnZhciBzCnZhciByPWQKdHJ5e2lmKGFbYl09PT10KXtzPWFbYl09cgpzPWFbYl09ZCgpfWVsc2Ug
+cz1hW2JdfWZpbmFsbHl7aWYocz09PXIpYVtiXT1udWxsCmFbY109ZnVuY3Rpb24oKXtyZXR1cm4gdGhp
+c1tiXX19cmV0dXJuIHN9fWZ1bmN0aW9uIG1ha2VDb25zdExpc3QoYSl7YS5pbW11dGFibGUkbGlzdD1B
+cnJheQphLmZpeGVkJGxlbmd0aD1BcnJheQpyZXR1cm4gYX1mdW5jdGlvbiBjb252ZXJ0VG9GYXN0T2Jq
+ZWN0KGEpe2Z1bmN0aW9uIHQoKXt9dC5wcm90b3R5cGU9YQpuZXcgdCgpCnJldHVybiBhfWZ1bmN0aW9u
+IGNvbnZlcnRBbGxUb0Zhc3RPYmplY3QoYSl7Zm9yKHZhciB0PTA7dDxhLmxlbmd0aDsrK3QpY29udmVy
+dFRvRmFzdE9iamVjdChhW3RdKX12YXIgeT0wCmZ1bmN0aW9uIHRlYXJPZmZHZXR0ZXIoYSxiLGMsZCxl
+KXtyZXR1cm4gZT9uZXcgRnVuY3Rpb24oImZ1bmNzIiwiYXBwbHlUcmFtcG9saW5lSW5kZXgiLCJyZWZs
+ZWN0aW9uSW5mbyIsIm5hbWUiLCJIIiwiYyIsInJldHVybiBmdW5jdGlvbiB0ZWFyT2ZmXyIrZCt5Kysr
+IihyZWNlaXZlcikgeyIrImlmIChjID09PSBudWxsKSBjID0gIisiSC5LcSIrIigiKyJ0aGlzLCBmdW5j
+cywgYXBwbHlUcmFtcG9saW5lSW5kZXgsIHJlZmxlY3Rpb25JbmZvLCBmYWxzZSwgdHJ1ZSwgbmFtZSk7
+IisicmV0dXJuIG5ldyBjKHRoaXMsIGZ1bmNzWzBdLCByZWNlaXZlciwgbmFtZSk7IisifSIpKGEsYixj
+LGQsSCxudWxsKTpuZXcgRnVuY3Rpb24oImZ1bmNzIiwiYXBwbHlUcmFtcG9saW5lSW5kZXgiLCJyZWZs
+ZWN0aW9uSW5mbyIsIm5hbWUiLCJIIiwiYyIsInJldHVybiBmdW5jdGlvbiB0ZWFyT2ZmXyIrZCt5Kysr
+IigpIHsiKyJpZiAoYyA9PT0gbnVsbCkgYyA9ICIrIkguS3EiKyIoIisidGhpcywgZnVuY3MsIGFwcGx5
+VHJhbXBvbGluZUluZGV4LCByZWZsZWN0aW9uSW5mbywgZmFsc2UsIGZhbHNlLCBuYW1lKTsiKyJyZXR1
+cm4gbmV3IGModGhpcywgZnVuY3NbMF0sIG51bGwsIG5hbWUpOyIrIn0iKShhLGIsYyxkLEgsbnVsbCl9
+ZnVuY3Rpb24gdGVhck9mZihhLGIsYyxkLGUsZil7dmFyIHQ9bnVsbApyZXR1cm4gZD9mdW5jdGlvbigp
+e2lmKHQ9PT1udWxsKXQ9SC5LcSh0aGlzLGEsYixjLHRydWUsZmFsc2UsZSkucHJvdG90eXBlCnJldHVy
+biB0fTp0ZWFyT2ZmR2V0dGVyKGEsYixjLGUsZil9dmFyIHg9MApmdW5jdGlvbiBpbnN0YWxsVGVhck9m
+ZihhLGIsYyxkLGUsZixnLGgsaSxqKXt2YXIgdD1bXQpmb3IodmFyIHM9MDtzPGgubGVuZ3RoO3MrKyl7
+dmFyIHI9aFtzXQppZih0eXBlb2Ygcj09J3N0cmluZycpcj1hW3JdCnIuJGNhbGxOYW1lPWdbc10KdC5w
+dXNoKHIpfXZhciByPXRbMF0Kci4kUj1lCnIuJEQ9Zgp2YXIgcT1pCmlmKHR5cGVvZiBxPT0ibnVtYmVy
+IilxKz14CnZhciBwPWhbMF0Kci4kc3R1Yk5hbWU9cAp2YXIgbz10ZWFyT2ZmKHQsanx8MCxxLGMscCxk
+KQphW2JdPW8KaWYoYylyLiR0ZWFyT2ZmPW99ZnVuY3Rpb24gaW5zdGFsbFN0YXRpY1RlYXJPZmYoYSxi
+LGMsZCxlLGYsZyxoKXtyZXR1cm4gaW5zdGFsbFRlYXJPZmYoYSxiLHRydWUsZmFsc2UsYyxkLGUsZixn
+LGgpfWZ1bmN0aW9uIGluc3RhbGxJbnN0YW5jZVRlYXJPZmYoYSxiLGMsZCxlLGYsZyxoLGkpe3JldHVy
+biBpbnN0YWxsVGVhck9mZihhLGIsZmFsc2UsYyxkLGUsZixnLGgsaSl9ZnVuY3Rpb24gc2V0T3JVcGRh
+dGVJbnRlcmNlcHRvcnNCeVRhZyhhKXt2YXIgdD12LmludGVyY2VwdG9yc0J5VGFnCmlmKCF0KXt2Lmlu
+dGVyY2VwdG9yc0J5VGFnPWEKcmV0dXJufWNvcHlQcm9wZXJ0aWVzKGEsdCl9ZnVuY3Rpb24gc2V0T3JV
+cGRhdGVMZWFmVGFncyhhKXt2YXIgdD12LmxlYWZUYWdzCmlmKCF0KXt2LmxlYWZUYWdzPWEKcmV0dXJu
+fWNvcHlQcm9wZXJ0aWVzKGEsdCl9ZnVuY3Rpb24gdXBkYXRlVHlwZXMoYSl7dmFyIHQ9di50eXBlcwp2
+YXIgcz10Lmxlbmd0aAp0LnB1c2guYXBwbHkodCxhKQpyZXR1cm4gc31mdW5jdGlvbiB1cGRhdGVIb2xk
+ZXIoYSxiKXtjb3B5UHJvcGVydGllcyhiLGEpCnJldHVybiBhfXZhciBodW5rSGVscGVycz1mdW5jdGlv
+bigpe3ZhciB0PWZ1bmN0aW9uKGEsYixjLGQsZSl7cmV0dXJuIGZ1bmN0aW9uKGYsZyxoLGkpe3JldHVy
+biBpbnN0YWxsSW5zdGFuY2VUZWFyT2ZmKGYsZyxhLGIsYyxkLFtoXSxpLGUpfX0scz1mdW5jdGlvbihh
+LGIsYyxkKXtyZXR1cm4gZnVuY3Rpb24oZSxmLGcsaCl7cmV0dXJuIGluc3RhbGxTdGF0aWNUZWFyT2Zm
+KGUsZixhLGIsYyxbZ10saCxkKX19CnJldHVybntpbmhlcml0OmluaGVyaXQsaW5oZXJpdE1hbnk6aW5o
+ZXJpdE1hbnksbWl4aW46bWl4aW4saW5zdGFsbFN0YXRpY1RlYXJPZmY6aW5zdGFsbFN0YXRpY1RlYXJP
+ZmYsaW5zdGFsbEluc3RhbmNlVGVhck9mZjppbnN0YWxsSW5zdGFuY2VUZWFyT2ZmLF9pbnN0YW5jZV8w
+dTp0KDAsMCxudWxsLFsiJDAiXSwwKSxfaW5zdGFuY2VfMXU6dCgwLDEsbnVsbCxbIiQxIl0sMCksX2lu
+c3RhbmNlXzJ1OnQoMCwyLG51bGwsWyIkMiJdLDApLF9pbnN0YW5jZV8waTp0KDEsMCxudWxsLFsiJDAi
+XSwwKSxfaW5zdGFuY2VfMWk6dCgxLDEsbnVsbCxbIiQxIl0sMCksX2luc3RhbmNlXzJpOnQoMSwyLG51
+bGwsWyIkMiJdLDApLF9zdGF0aWNfMDpzKDAsbnVsbCxbIiQwIl0sMCksX3N0YXRpY18xOnMoMSxudWxs
+LFsiJDEiXSwwKSxfc3RhdGljXzI6cygyLG51bGwsWyIkMiJdLDApLG1ha2VDb25zdExpc3Q6bWFrZUNv
+bnN0TGlzdCxsYXp5OmxhenksdXBkYXRlSG9sZGVyOnVwZGF0ZUhvbGRlcixjb252ZXJ0VG9GYXN0T2Jq
+ZWN0OmNvbnZlcnRUb0Zhc3RPYmplY3Qsc2V0RnVuY3Rpb25OYW1lc0lmTmVjZXNzYXJ5OnNldEZ1bmN0
+aW9uTmFtZXNJZk5lY2Vzc2FyeSx1cGRhdGVUeXBlczp1cGRhdGVUeXBlcyxzZXRPclVwZGF0ZUludGVy
+Y2VwdG9yc0J5VGFnOnNldE9yVXBkYXRlSW50ZXJjZXB0b3JzQnlUYWcsc2V0T3JVcGRhdGVMZWFmVGFn
+czpzZXRPclVwZGF0ZUxlYWZUYWdzfX0oKQpmdW5jdGlvbiBpbml0aWFsaXplRGVmZXJyZWRIdW5rKGEp
+e3g9di50eXBlcy5sZW5ndGgKYShodW5rSGVscGVycyx2LHcsJCl9ZnVuY3Rpb24gZ2V0R2xvYmFsRnJv
+bU5hbWUoYSl7Zm9yKHZhciB0PTA7dDx3Lmxlbmd0aDt0Kyspe2lmKHdbdF09PUMpY29udGludWUKaWYo
+d1t0XVthXSlyZXR1cm4gd1t0XVthXX19dmFyIEM9e30sSD17Rks6ZnVuY3Rpb24gRksoKXt9LAp5Ujpm
+dW5jdGlvbihhKXtyZXR1cm4gbmV3IEgubmQoYSl9LApvbzpmdW5jdGlvbihhKXt2YXIgdCxzPWFeNDgK
+aWYoczw9OSlyZXR1cm4gcwp0PWF8MzIKaWYoOTc8PXQmJnQ8PTEwMilyZXR1cm4gdC04NwpyZXR1cm4t
+MX0sCnFDOmZ1bmN0aW9uKGEsYixjLGQpe1AuazEoYiwic3RhcnQiKQppZihjIT1udWxsKXtQLmsxKGMs
+ImVuZCIpCmlmKGI+YylILnZoKFAuVEUoYiwwLGMsInN0YXJ0IixudWxsKSl9cmV0dXJuIG5ldyBILm5I
+KGEsYixjLGQuQygibkg8MD4iKSl9LApLMTpmdW5jdGlvbihhLGIsYyxkKXtpZih1Lmd3LmIoYSkpcmV0
+dXJuIG5ldyBILnh5KGEsYixjLkMoIkA8MD4iKS5LcShkKS5DKCJ4eTwxLDI+IikpCnJldHVybiBuZXcg
+SC5pMShhLGIsYy5DKCJAPDA+IikuS3EoZCkuQygiaTE8MSwyPiIpKX0sCldwOmZ1bmN0aW9uKCl7cmV0
+dXJuIG5ldyBQLmxqKCJObyBlbGVtZW50Iil9LApkVTpmdW5jdGlvbigpe3JldHVybiBuZXcgUC5saigi
+VG9vIG1hbnkgZWxlbWVudHMiKX0sCmFyOmZ1bmN0aW9uKCl7cmV0dXJuIG5ldyBQLmxqKCJUb28gZmV3
+IGVsZW1lbnRzIil9LApuZDpmdW5jdGlvbiBuZChhKXt0aGlzLmE9YX0sCnFqOmZ1bmN0aW9uIHFqKGEp
+e3RoaXMuYT1hfSwKYlE6ZnVuY3Rpb24gYlEoKXt9LAphTDpmdW5jdGlvbiBhTCgpe30sCm5IOmZ1bmN0
+aW9uIG5IKGEsYixjLGQpe3ZhciBfPXRoaXMKXy5hPWEKXy5iPWIKXy5jPWMKXy4kdGk9ZH0sCmE3OmZ1
+bmN0aW9uIGE3KGEsYixjKXt2YXIgXz10aGlzCl8uYT1hCl8uYj1iCl8uYz0wCl8uZD1udWxsCl8uJHRp
+PWN9LAppMTpmdW5jdGlvbiBpMShhLGIsYyl7dGhpcy5hPWEKdGhpcy5iPWIKdGhpcy4kdGk9Y30sCnh5
+OmZ1bmN0aW9uIHh5KGEsYixjKXt0aGlzLmE9YQp0aGlzLmI9Ygp0aGlzLiR0aT1jfSwKTUg6ZnVuY3Rp
+b24gTUgoYSxiLGMpe3ZhciBfPXRoaXMKXy5hPW51bGwKXy5iPWEKXy5jPWIKXy4kdGk9Y30sCmxKOmZ1
+bmN0aW9uIGxKKGEsYixjKXt0aGlzLmE9YQp0aGlzLmI9Ygp0aGlzLiR0aT1jfSwKVTU6ZnVuY3Rpb24g
+VTUoYSxiLGMpe3RoaXMuYT1hCnRoaXMuYj1iCnRoaXMuJHRpPWN9LAp2RzpmdW5jdGlvbiB2RyhhLGIs
+Yyl7dGhpcy5hPWEKdGhpcy5iPWIKdGhpcy4kdGk9Y30sClNVOmZ1bmN0aW9uIFNVKCl7fSwKUmU6ZnVu
+Y3Rpb24gUmUoKXt9LAp3MjpmdW5jdGlvbiB3Migpe30sCnd2OmZ1bmN0aW9uIHd2KGEpe3RoaXMuYT1h
+fSwKZGM6ZnVuY3Rpb24oKXt0aHJvdyBILmIoUC5MNCgiQ2Fubm90IG1vZGlmeSB1bm1vZGlmaWFibGUg
+TWFwIikpfSwKTlE6ZnVuY3Rpb24oYSl7dmFyIHQscz1ILkpnKGEpCmlmKHMhPW51bGwpcmV0dXJuIHMK
+dD0ibWluaWZpZWQ6IithCnJldHVybiB0fSwKd1Y6ZnVuY3Rpb24oYSxiKXt2YXIgdAppZihiIT1udWxs
+KXt0PWIueAppZih0IT1udWxsKXJldHVybiB0fXJldHVybiB1LmFVLmIoYSl9LApkOmZ1bmN0aW9uKGEp
+e3ZhciB0CmlmKHR5cGVvZiBhPT0ic3RyaW5nIilyZXR1cm4gYQppZih0eXBlb2YgYT09Im51bWJlciIp
+e2lmKGEhPT0wKXJldHVybiIiK2F9ZWxzZSBpZighMD09PWEpcmV0dXJuInRydWUiCmVsc2UgaWYoITE9
+PT1hKXJldHVybiJmYWxzZSIKZWxzZSBpZihhPT1udWxsKXJldHVybiJudWxsIgp0PUouQWMoYSkKaWYo
+dHlwZW9mIHQhPSJzdHJpbmciKXRocm93IEguYihILkkoYSkpCnJldHVybiB0fSwKZVE6ZnVuY3Rpb24o
+YSl7dmFyIHQ9YS4kaWRlbnRpdHlIYXNoCmlmKHQ9PW51bGwpe3Q9TWF0aC5yYW5kb20oKSoweDNmZmZm
+ZmZmfDAKYS4kaWRlbnRpdHlIYXNoPXR9cmV0dXJuIHR9LApIcDpmdW5jdGlvbihhLGIpe3ZhciB0LHMs
+cixxLHAsbyxuPW51bGwKaWYodHlwZW9mIGEhPSJzdHJpbmciKUgudmgoSC5JKGEpKQp0PS9eXHMqWyst
+XT8oKDB4W2EtZjAtOV0rKXwoXGQrKXwoW2EtejAtOV0rKSlccyokL2kuZXhlYyhhKQppZih0PT1udWxs
+KXJldHVybiBuCmlmKDM+PXQubGVuZ3RoKXJldHVybiBILmsodCwzKQpzPUguYyh0WzNdKQppZihiPT1u
+dWxsKXtpZihzIT1udWxsKXJldHVybiBwYXJzZUludChhLDEwKQppZih0WzJdIT1udWxsKXJldHVybiBw
+YXJzZUludChhLDE2KQpyZXR1cm4gbn1pZihiPDJ8fGI+MzYpdGhyb3cgSC5iKFAuVEUoYiwyLDM2LCJy
+YWRpeCIsbikpCmlmKGI9PT0xMCYmcyE9bnVsbClyZXR1cm4gcGFyc2VJbnQoYSwxMCkKaWYoYjwxMHx8
+cz09bnVsbCl7cj1iPD0xMD80NytiOjg2K2IKcT10WzFdCmZvcihwPXEubGVuZ3RoLG89MDtvPHA7Kytv
+KWlmKChDLnhCLlcocSxvKXwzMik+cilyZXR1cm4gbn1yZXR1cm4gcGFyc2VJbnQoYSxiKX0sCmxoOmZ1
+bmN0aW9uKGEpe3ZhciB0PUguSDUoYSkKcmV0dXJuIHR9LApINTpmdW5jdGlvbihhKXt2YXIgdCxzLHIK
+aWYoYSBpbnN0YW5jZW9mIFAuTWgpcmV0dXJuIEguSihILnEoYSksbnVsbCkKaWYoSi5pYShhKT09PUMu
+T2t8fHUuYWsuYihhKSl7dD1DLndiKGEpCmlmKEguQmUodCkpcmV0dXJuIHQKcz1hLmNvbnN0cnVjdG9y
+CmlmKHR5cGVvZiBzPT0iZnVuY3Rpb24iKXtyPXMubmFtZQppZih0eXBlb2Ygcj09InN0cmluZyImJkgu
+QmUocikpcmV0dXJuIHJ9fXJldHVybiBILkooSC5xKGEpLG51bGwpfSwKQmU6ZnVuY3Rpb24oYSl7dmFy
+IHQ9YSE9PSJPYmplY3QiJiZhIT09IiIKcmV0dXJuIHR9LApNMDpmdW5jdGlvbigpe2lmKCEhc2VsZi5s
+b2NhdGlvbilyZXR1cm4gc2VsZi5sb2NhdGlvbi5ocmVmCnJldHVybiBudWxsfSwKVks6ZnVuY3Rpb24o
+YSl7dmFyIHQscyxyLHEscD1hLmxlbmd0aAppZihwPD01MDApcmV0dXJuIFN0cmluZy5mcm9tQ2hhckNv
+ZGUuYXBwbHkobnVsbCxhKQpmb3IodD0iIixzPTA7czxwO3M9cil7cj1zKzUwMApxPXI8cD9yOnAKdCs9
+U3RyaW5nLmZyb21DaGFyQ29kZS5hcHBseShudWxsLGEuc2xpY2UocyxxKSl9cmV0dXJuIHR9LApDcTpm
+dW5jdGlvbihhKXt2YXIgdCxzLHIscT1ILlZNKFtdLHUudCkKZm9yKHQ9YS5sZW5ndGgscz0wO3M8YS5s
+ZW5ndGg7YS5sZW5ndGg9PT10fHwoMCxILmxrKShhKSwrK3Mpe3I9YVtzXQppZighSC5vayhyKSl0aHJv
+dyBILmIoSC5JKHIpKQppZihyPD02NTUzNSlDLk5tLmkocSxyKQplbHNlIGlmKHI8PTExMTQxMTEpe0Mu
+Tm0uaShxLDU1Mjk2KyhDLmpuLndHKHItNjU1MzYsMTApJjEwMjMpKQpDLk5tLmkocSw1NjMyMCsociYx
+MDIzKSl9ZWxzZSB0aHJvdyBILmIoSC5JKHIpKX1yZXR1cm4gSC5WSyhxKX0sCmVUOmZ1bmN0aW9uKGEp
+e3ZhciB0LHMscgpmb3IodD1hLmxlbmd0aCxzPTA7czx0Oysrcyl7cj1hW3NdCmlmKCFILm9rKHIpKXRo
+cm93IEguYihILkkocikpCmlmKHI8MCl0aHJvdyBILmIoSC5JKHIpKQppZihyPjY1NTM1KXJldHVybiBI
+LkNxKGEpfXJldHVybiBILlZLKGEpfSwKZnc6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0LHMscixxCmlmKGM8
+PTUwMCYmYj09PTAmJmM9PT1hLmxlbmd0aClyZXR1cm4gU3RyaW5nLmZyb21DaGFyQ29kZS5hcHBseShu
+dWxsLGEpCmZvcih0PWIscz0iIjt0PGM7dD1yKXtyPXQrNTAwCnE9cjxjP3I6YwpzKz1TdHJpbmcuZnJv
+bUNoYXJDb2RlLmFwcGx5KG51bGwsYS5zdWJhcnJheSh0LHEpKX1yZXR1cm4gc30sCkx3OmZ1bmN0aW9u
+KGEpe3ZhciB0CmlmKDA8PWEpe2lmKGE8PTY1NTM1KXJldHVybiBTdHJpbmcuZnJvbUNoYXJDb2RlKGEp
+CmlmKGE8PTExMTQxMTEpe3Q9YS02NTUzNgpyZXR1cm4gU3RyaW5nLmZyb21DaGFyQ29kZSgoNTUyOTZ8
+Qy5qbi53Ryh0LDEwKSk+Pj4wLDU2MzIwfHQmMTAyMyl9fXRocm93IEguYihQLlRFKGEsMCwxMTE0MTEx
+LG51bGwsbnVsbCkpfSwKbzI6ZnVuY3Rpb24oYSl7aWYoYS5kYXRlPT09dm9pZCAwKWEuZGF0ZT1uZXcg
+RGF0ZShhLmEpCnJldHVybiBhLmRhdGV9LAp0SjpmdW5jdGlvbihhKXt2YXIgdD1ILm8yKGEpLmdldEZ1
+bGxZZWFyKCkrMApyZXR1cm4gdH0sCk5TOmZ1bmN0aW9uKGEpe3ZhciB0PUgubzIoYSkuZ2V0TW9udGgo
+KSsxCnJldHVybiB0fSwKakE6ZnVuY3Rpb24oYSl7dmFyIHQ9SC5vMihhKS5nZXREYXRlKCkrMApyZXR1
+cm4gdH0sCklYOmZ1bmN0aW9uKGEpe3ZhciB0PUgubzIoYSkuZ2V0SG91cnMoKSswCnJldHVybiB0fSwK
+Y2g6ZnVuY3Rpb24oYSl7dmFyIHQ9SC5vMihhKS5nZXRNaW51dGVzKCkrMApyZXR1cm4gdH0sCkpkOmZ1
+bmN0aW9uKGEpe3ZhciB0PUgubzIoYSkuZ2V0U2Vjb25kcygpKzAKcmV0dXJuIHR9LApWYTpmdW5jdGlv
+bihhKXt2YXIgdD1ILm8yKGEpLmdldE1pbGxpc2Vjb25kcygpKzAKcmV0dXJuIHR9LAp6bzpmdW5jdGlv
+bihhLGIsYyl7dmFyIHQscyxyPXt9CnIuYT0wCnQ9W10Kcz1bXQpyLmE9Yi5sZW5ndGgKQy5ObS5GVih0
+LGIpCnIuYj0iIgppZihjIT1udWxsJiZjLmEhPT0wKWMuSygwLG5ldyBILkNqKHIscyx0KSkKIiIrci5h
+CnJldHVybiBKLkp5KGEsbmV3IEguTEkoQy5UZSwwLHQscywwKSl9LApFazpmdW5jdGlvbihhLGIsYyl7
+dmFyIHQscyxyLHEKaWYoYiBpbnN0YW5jZW9mIEFycmF5KXQ9Yz09bnVsbHx8Yy5hPT09MAplbHNlIHQ9
+ITEKaWYodCl7cz1iCnI9cy5sZW5ndGgKaWYocj09PTApe2lmKCEhYS4kMClyZXR1cm4gYS4kMCgpfWVs
+c2UgaWYocj09PTEpe2lmKCEhYS4kMSlyZXR1cm4gYS4kMShzWzBdKX1lbHNlIGlmKHI9PT0yKXtpZigh
+IWEuJDIpcmV0dXJuIGEuJDIoc1swXSxzWzFdKX1lbHNlIGlmKHI9PT0zKXtpZighIWEuJDMpcmV0dXJu
+IGEuJDMoc1swXSxzWzFdLHNbMl0pfWVsc2UgaWYocj09PTQpe2lmKCEhYS4kNClyZXR1cm4gYS4kNChz
+WzBdLHNbMV0sc1syXSxzWzNdKX1lbHNlIGlmKHI9PT01KWlmKCEhYS4kNSlyZXR1cm4gYS4kNShzWzBd
+LHNbMV0sc1syXSxzWzNdLHNbNF0pCnE9YVsiIisiJCIrcl0KaWYocSE9bnVsbClyZXR1cm4gcS5hcHBs
+eShhLHMpfXJldHVybiBILmUxKGEsYixjKX0sCmUxOmZ1bmN0aW9uKGEsYixjKXt2YXIgdCxzLHIscSxw
+LG8sbixtLGwsaz1iIGluc3RhbmNlb2YgQXJyYXk/YjpQLkNIKGIsITAsdS56KSxqPWsubGVuZ3RoLGk9
+YS4kUgppZihqPGkpcmV0dXJuIEguem8oYSxrLGMpCnQ9YS4kRApzPXQ9PW51bGwKcj0hcz90KCk6bnVs
+bApxPUouaWEoYSkKcD1xLiRDCmlmKHR5cGVvZiBwPT0ic3RyaW5nIilwPXFbcF0KaWYocyl7aWYoYyE9
+bnVsbCYmYy5hIT09MClyZXR1cm4gSC56byhhLGssYykKaWYoaj09PWkpcmV0dXJuIHAuYXBwbHkoYSxr
+KQpyZXR1cm4gSC56byhhLGssYyl9aWYociBpbnN0YW5jZW9mIEFycmF5KXtpZihjIT1udWxsJiZjLmEh
+PT0wKXJldHVybiBILnpvKGEsayxjKQppZihqPmkrci5sZW5ndGgpcmV0dXJuIEguem8oYSxrLG51bGwp
+CkMuTm0uRlYoayxyLnNsaWNlKGotaSkpCnJldHVybiBwLmFwcGx5KGEsayl9ZWxzZXtpZihqPmkpcmV0
+dXJuIEguem8oYSxrLGMpCm89T2JqZWN0LmtleXMocikKaWYoYz09bnVsbClmb3Iocz1vLmxlbmd0aCxu
+PTA7bjxvLmxlbmd0aDtvLmxlbmd0aD09PXN8fCgwLEgubGspKG8pLCsrbilDLk5tLmkoayxyW0guYyhv
+W25dKV0pCmVsc2V7Zm9yKHM9by5sZW5ndGgsbT0wLG49MDtuPG8ubGVuZ3RoO28ubGVuZ3RoPT09c3x8
+KDAsSC5saykobyksKytuKXtsPUguYyhvW25dKQppZihjLng0KGwpKXsrK20KQy5ObS5pKGssYy5xKDAs
+bCkpfWVsc2UgQy5ObS5pKGsscltsXSl9aWYobSE9PWMuYSlyZXR1cm4gSC56byhhLGssYyl9cmV0dXJu
+IHAuYXBwbHkoYSxrKX19LApwWTpmdW5jdGlvbihhKXt0aHJvdyBILmIoSC5JKGEpKX0sCms6ZnVuY3Rp
+b24oYSxiKXtpZihhPT1udWxsKUouSChhKQp0aHJvdyBILmIoSC5IWShhLGIpKX0sCkhZOmZ1bmN0aW9u
+KGEsYil7dmFyIHQscyxyPSJpbmRleCIKaWYoIUgub2soYikpcmV0dXJuIG5ldyBQLkFUKCEwLGIscixu
+dWxsKQp0PUguV1koSi5IKGEpKQppZighKGI8MCkpe2lmKHR5cGVvZiB0IT09Im51bWJlciIpcmV0dXJu
+IEgucFkodCkKcz1iPj10fWVsc2Ugcz0hMAppZihzKXJldHVybiBQLnQoYixhLHIsbnVsbCx0KQpyZXR1
+cm4gUC5PNyhiLHIpfSwKYXU6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0PW51bGwKaWYoYT5jKXJldHVybiBQ
+LlRFKGEsMCxjLCJzdGFydCIsdCkKaWYoYiE9bnVsbCl7aWYoIUgub2soYikpcmV0dXJuIG5ldyBQLkFU
+KCEwLGIsImVuZCIsdCkKaWYoYjxhfHxiPmMpcmV0dXJuIFAuVEUoYixhLGMsImVuZCIsdCl9cmV0dXJu
+IG5ldyBQLkFUKCEwLGIsImVuZCIsdCl9LApJOmZ1bmN0aW9uKGEpe3JldHVybiBuZXcgUC5BVCghMCxh
+LG51bGwsbnVsbCl9LApiOmZ1bmN0aW9uKGEpe3ZhciB0CmlmKGE9PW51bGwpYT1uZXcgUC5MSygpCnQ9
+bmV3IEVycm9yKCkKdC5kYXJ0RXhjZXB0aW9uPWEKaWYoImRlZmluZVByb3BlcnR5IiBpbiBPYmplY3Qp
+e09iamVjdC5kZWZpbmVQcm9wZXJ0eSh0LCJtZXNzYWdlIix7Z2V0OkguSnV9KQp0Lm5hbWU9IiJ9ZWxz
+ZSB0LnRvU3RyaW5nPUguSnUKcmV0dXJuIHR9LApKdTpmdW5jdGlvbigpe3JldHVybiBKLkFjKHRoaXMu
+ZGFydEV4Y2VwdGlvbil9LAp2aDpmdW5jdGlvbihhKXt0aHJvdyBILmIoYSl9LApsazpmdW5jdGlvbihh
+KXt0aHJvdyBILmIoUC5hNChhKSl9LApjTTpmdW5jdGlvbihhKXt2YXIgdCxzLHIscSxwLG8KYT1ILmVB
+KGEucmVwbGFjZShTdHJpbmcoe30pLCckcmVjZWl2ZXIkJykpCnQ9YS5tYXRjaCgvXFxcJFthLXpBLVpd
+K1xcXCQvZykKaWYodD09bnVsbCl0PUguVk0oW10sdS5zKQpzPXQuaW5kZXhPZigiXFwkYXJndW1lbnRz
+XFwkIikKcj10LmluZGV4T2YoIlxcJGFyZ3VtZW50c0V4cHJcXCQiKQpxPXQuaW5kZXhPZigiXFwkZXhw
+clxcJCIpCnA9dC5pbmRleE9mKCJcXCRtZXRob2RcXCQiKQpvPXQuaW5kZXhPZigiXFwkcmVjZWl2ZXJc
+XCQiKQpyZXR1cm4gbmV3IEguZjkoYS5yZXBsYWNlKG5ldyBSZWdFeHAoJ1xcXFxcXCRhcmd1bWVudHNc
+XFxcXFwkJywnZycpLCcoKD86eHxbXnhdKSopJykucmVwbGFjZShuZXcgUmVnRXhwKCdcXFxcXFwkYXJn
+dW1lbnRzRXhwclxcXFxcXCQnLCdnJyksJygoPzp4fFteeF0pKiknKS5yZXBsYWNlKG5ldyBSZWdFeHAo
+J1xcXFxcXCRleHByXFxcXFxcJCcsJ2cnKSwnKCg/Onh8W154XSkqKScpLnJlcGxhY2UobmV3IFJlZ0V4
+cCgnXFxcXFxcJG1ldGhvZFxcXFxcXCQnLCdnJyksJygoPzp4fFteeF0pKiknKS5yZXBsYWNlKG5ldyBS
+ZWdFeHAoJ1xcXFxcXCRyZWNlaXZlclxcXFxcXCQnLCdnJyksJygoPzp4fFteeF0pKiknKSxzLHIscSxw
+LG8pfSwKUzc6ZnVuY3Rpb24oYSl7cmV0dXJuIGZ1bmN0aW9uKCRleHByJCl7dmFyICRhcmd1bWVudHNF
+eHByJD0nJGFyZ3VtZW50cyQnCnRyeXskZXhwciQuJG1ldGhvZCQoJGFyZ3VtZW50c0V4cHIkKX1jYXRj
+aCh0KXtyZXR1cm4gdC5tZXNzYWdlfX0oYSl9LApNajpmdW5jdGlvbihhKXtyZXR1cm4gZnVuY3Rpb24o
+JGV4cHIkKXt0cnl7JGV4cHIkLiRtZXRob2QkfWNhdGNoKHQpe3JldHVybiB0Lm1lc3NhZ2V9fShhKX0s
+CklqOmZ1bmN0aW9uKGEsYil7cmV0dXJuIG5ldyBILlcwKGEsYj09bnVsbD9udWxsOmIubWV0aG9kKX0s
+ClQzOmZ1bmN0aW9uKGEsYil7dmFyIHQ9Yj09bnVsbCxzPXQ/bnVsbDpiLm1ldGhvZApyZXR1cm4gbmV3
+IEguYXooYSxzLHQ/bnVsbDpiLnJlY2VpdmVyKX0sClJ1OmZ1bmN0aW9uKGEpe3ZhciB0LHMscixxLHAs
+byxuLG0sbCxrLGosaSxoLGcsZj1udWxsLGU9bmV3IEguQW0oYSkKaWYoYT09bnVsbClyZXR1cm4gZgpp
+ZihhIGluc3RhbmNlb2YgSC5icSlyZXR1cm4gZS4kMShhLmEpCmlmKHR5cGVvZiBhIT09Im9iamVjdCIp
+cmV0dXJuIGEKaWYoImRhcnRFeGNlcHRpb24iIGluIGEpcmV0dXJuIGUuJDEoYS5kYXJ0RXhjZXB0aW9u
+KQplbHNlIGlmKCEoIm1lc3NhZ2UiIGluIGEpKXJldHVybiBhCnQ9YS5tZXNzYWdlCmlmKCJudW1iZXIi
+IGluIGEmJnR5cGVvZiBhLm51bWJlcj09Im51bWJlciIpe3M9YS5udW1iZXIKcj1zJjY1NTM1CmlmKChD
+LmpuLndHKHMsMTYpJjgxOTEpPT09MTApc3dpdGNoKHIpe2Nhc2UgNDM4OnJldHVybiBlLiQxKEguVDMo
+SC5kKHQpKyIgKEVycm9yICIrcisiKSIsZikpCmNhc2UgNDQ1OmNhc2UgNTAwNzpyZXR1cm4gZS4kMShI
+LklqKEguZCh0KSsiIChFcnJvciAiK3IrIikiLGYpKX19aWYoYSBpbnN0YW5jZW9mIFR5cGVFcnJvcil7
+cT0kLlNuKCkKcD0kLmxxKCkKbz0kLk45KCkKbj0kLmlJKCkKbT0kLlVOKCkKbD0kLlpoKCkKaz0kLnJO
+KCkKJC5jMygpCmo9JC5ISygpCmk9JC5yMSgpCmg9cS5xUyh0KQppZihoIT1udWxsKXJldHVybiBlLiQx
+KEguVDMoSC5jKHQpLGgpKQplbHNle2g9cC5xUyh0KQppZihoIT1udWxsKXtoLm1ldGhvZD0iY2FsbCIK
+cmV0dXJuIGUuJDEoSC5UMyhILmModCksaCkpfWVsc2V7aD1vLnFTKHQpCmlmKGg9PW51bGwpe2g9bi5x
+Uyh0KQppZihoPT1udWxsKXtoPW0ucVModCkKaWYoaD09bnVsbCl7aD1sLnFTKHQpCmlmKGg9PW51bGwp
+e2g9ay5xUyh0KQppZihoPT1udWxsKXtoPW4ucVModCkKaWYoaD09bnVsbCl7aD1qLnFTKHQpCmlmKGg9
+PW51bGwpe2g9aS5xUyh0KQpnPWghPW51bGx9ZWxzZSBnPSEwfWVsc2UgZz0hMH1lbHNlIGc9ITB9ZWxz
+ZSBnPSEwfWVsc2UgZz0hMH1lbHNlIGc9ITB9ZWxzZSBnPSEwCmlmKGcpcmV0dXJuIGUuJDEoSC5JaihI
+LmModCksaCkpfX1yZXR1cm4gZS4kMShuZXcgSC52Vih0eXBlb2YgdD09InN0cmluZyI/dDoiIikpfWlm
+KGEgaW5zdGFuY2VvZiBSYW5nZUVycm9yKXtpZih0eXBlb2YgdD09InN0cmluZyImJnQuaW5kZXhPZigi
+Y2FsbCBzdGFjayIpIT09LTEpcmV0dXJuIG5ldyBQLktZKCkKdD1mdW5jdGlvbihiKXt0cnl7cmV0dXJu
+IFN0cmluZyhiKX1jYXRjaChkKXt9cmV0dXJuIG51bGx9KGEpCnJldHVybiBlLiQxKG5ldyBQLkFUKCEx
+LGYsZix0eXBlb2YgdD09InN0cmluZyI/dC5yZXBsYWNlKC9eUmFuZ2VFcnJvcjpccyovLCIiKTp0KSl9
+aWYodHlwZW9mIEludGVybmFsRXJyb3I9PSJmdW5jdGlvbiImJmEgaW5zdGFuY2VvZiBJbnRlcm5hbEVy
+cm9yKWlmKHR5cGVvZiB0PT0ic3RyaW5nIiYmdD09PSJ0b28gbXVjaCByZWN1cnNpb24iKXJldHVybiBu
+ZXcgUC5LWSgpCnJldHVybiBhfSwKdHM6ZnVuY3Rpb24oYSl7dmFyIHQKaWYoYSBpbnN0YW5jZW9mIEgu
+YnEpcmV0dXJuIGEuYgppZihhPT1udWxsKXJldHVybiBuZXcgSC5YTyhhKQp0PWEuJGNhY2hlZFRyYWNl
+CmlmKHQhPW51bGwpcmV0dXJuIHQKcmV0dXJuIGEuJGNhY2hlZFRyYWNlPW5ldyBILlhPKGEpfSwKQjc6
+ZnVuY3Rpb24oYSxiKXt2YXIgdCxzLHIscT1hLmxlbmd0aApmb3IodD0wO3Q8cTt0PXIpe3M9dCsxCnI9
+cysxCmIuWSgwLGFbdF0sYVtzXSl9cmV0dXJuIGJ9LApmdDpmdW5jdGlvbihhLGIsYyxkLGUsZil7dS5a
+LmEoYSkKc3dpdGNoKEguV1koYikpe2Nhc2UgMDpyZXR1cm4gYS4kMCgpCmNhc2UgMTpyZXR1cm4gYS4k
+MShjKQpjYXNlIDI6cmV0dXJuIGEuJDIoYyxkKQpjYXNlIDM6cmV0dXJuIGEuJDMoYyxkLGUpCmNhc2Ug
+NDpyZXR1cm4gYS4kNChjLGQsZSxmKX10aHJvdyBILmIobmV3IFAuQ0QoIlVuc3VwcG9ydGVkIG51bWJl
+ciBvZiBhcmd1bWVudHMgZm9yIHdyYXBwZWQgY2xvc3VyZSIpKX0sCnRSOmZ1bmN0aW9uKGEsYil7dmFy
+IHQKaWYoYT09bnVsbClyZXR1cm4gbnVsbAp0PWEuJGlkZW50aXR5CmlmKCEhdClyZXR1cm4gdAp0PWZ1
+bmN0aW9uKGMsZCxlKXtyZXR1cm4gZnVuY3Rpb24oZixnLGgsaSl7cmV0dXJuIGUoYyxkLGYsZyxoLGkp
+fX0oYSxiLEguZnQpCmEuJGlkZW50aXR5PXQKcmV0dXJuIHR9LAppQTpmdW5jdGlvbihhLGIsYyxkLGUs
+ZixnKXt2YXIgdCxzLHIscSxwLG8sbixtLGw9YlswXSxrPWwuJGNhbGxOYW1lLGo9ZT9PYmplY3QuY3Jl
+YXRlKG5ldyBILnp4KCkuY29uc3RydWN0b3IucHJvdG90eXBlKTpPYmplY3QuY3JlYXRlKG5ldyBILmp5
+KG51bGwsbnVsbCxudWxsLCIiKS5jb25zdHJ1Y3Rvci5wcm90b3R5cGUpCmouJGluaXRpYWxpemU9ai5j
+b25zdHJ1Y3RvcgppZihlKXQ9ZnVuY3Rpb24gc3RhdGljX3RlYXJfb2ZmKCl7dGhpcy4kaW5pdGlhbGl6
+ZSgpfQplbHNle3M9JC55agppZih0eXBlb2YgcyE9PSJudW1iZXIiKXJldHVybiBzLmgoKQokLnlqPXMr
+MQpzPW5ldyBGdW5jdGlvbigiYSxiLGMsZCIrcywidGhpcy4kaW5pdGlhbGl6ZShhLGIsYyxkIitzKyIp
+IikKdD1zfWouY29uc3RydWN0b3I9dAp0LnByb3RvdHlwZT1qCmlmKCFlKXtyPUguYngoYSxsLGYpCnIu
+JHJlZmxlY3Rpb25JbmZvPWR9ZWxzZXtqLiRzdGF0aWNfbmFtZT1nCnI9bH1xPUguaW0oZCxlLGYpCmou
+JFM9cQpqW2tdPXIKZm9yKHA9cixvPTE7bzxiLmxlbmd0aDsrK28pe249YltvXQptPW4uJGNhbGxOYW1l
+CmlmKG0hPW51bGwpe249ZT9uOkguYngoYSxuLGYpCmpbbV09bn1pZihvPT09Yyl7bi4kcmVmbGVjdGlv
+bkluZm89ZApwPW59fWouJEM9cApqLiRSPWwuJFIKai4kRD1sLiRECnJldHVybiB0fSwKaW06ZnVuY3Rp
+b24oYSxiLGMpe3ZhciB0CmlmKHR5cGVvZiBhPT0ibnVtYmVyIilyZXR1cm4gZnVuY3Rpb24oZCxlKXty
+ZXR1cm4gZnVuY3Rpb24oKXtyZXR1cm4gZChlKX19KEguQnAsYSkKaWYodHlwZW9mIGE9PSJzdHJpbmci
+KXtpZihiKXRocm93IEguYigiQ2Fubm90IGNvbXB1dGUgc2lnbmF0dXJlIGZvciBzdGF0aWMgdGVhcm9m
+Zi4iKQp0PWM/SC5QVzpILlRuCnJldHVybiBmdW5jdGlvbihkLGUpe3JldHVybiBmdW5jdGlvbigpe3Jl
+dHVybiBlKHRoaXMsZCl9fShhLHQpfXRocm93IEguYigiRXJyb3IgaW4gZnVuY3Rpb25UeXBlIG9mIHRl
+YXJvZmYiKX0sCnZxOmZ1bmN0aW9uKGEsYixjLGQpe3ZhciB0PUguRFYKc3dpdGNoKGI/LTE6YSl7Y2Fz
+ZSAwOnJldHVybiBmdW5jdGlvbihlLGYpe3JldHVybiBmdW5jdGlvbigpe3JldHVybiBmKHRoaXMpW2Vd
+KCl9fShjLHQpCmNhc2UgMTpyZXR1cm4gZnVuY3Rpb24oZSxmKXtyZXR1cm4gZnVuY3Rpb24oZyl7cmV0
+dXJuIGYodGhpcylbZV0oZyl9fShjLHQpCmNhc2UgMjpyZXR1cm4gZnVuY3Rpb24oZSxmKXtyZXR1cm4g
+ZnVuY3Rpb24oZyxoKXtyZXR1cm4gZih0aGlzKVtlXShnLGgpfX0oYyx0KQpjYXNlIDM6cmV0dXJuIGZ1
+bmN0aW9uKGUsZil7cmV0dXJuIGZ1bmN0aW9uKGcsaCxpKXtyZXR1cm4gZih0aGlzKVtlXShnLGgsaSl9
+fShjLHQpCmNhc2UgNDpyZXR1cm4gZnVuY3Rpb24oZSxmKXtyZXR1cm4gZnVuY3Rpb24oZyxoLGksail7
+cmV0dXJuIGYodGhpcylbZV0oZyxoLGksail9fShjLHQpCmNhc2UgNTpyZXR1cm4gZnVuY3Rpb24oZSxm
+KXtyZXR1cm4gZnVuY3Rpb24oZyxoLGksaixrKXtyZXR1cm4gZih0aGlzKVtlXShnLGgsaSxqLGspfX0o
+Yyx0KQpkZWZhdWx0OnJldHVybiBmdW5jdGlvbihlLGYpe3JldHVybiBmdW5jdGlvbigpe3JldHVybiBl
+LmFwcGx5KGYodGhpcyksYXJndW1lbnRzKX19KGQsdCl9fSwKYng6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0
+LHMscixxLHAsbyxuCmlmKGMpcmV0dXJuIEguSGYoYSxiKQp0PWIuJHN0dWJOYW1lCnM9Yi5sZW5ndGgK
+cj1hW3RdCnE9Yj09bnVsbD9yPT1udWxsOmI9PT1yCnA9IXF8fHM+PTI3CmlmKHApcmV0dXJuIEgudnEo
+cywhcSx0LGIpCmlmKHM9PT0wKXtxPSQueWoKaWYodHlwZW9mIHEhPT0ibnVtYmVyIilyZXR1cm4gcS5o
+KCkKJC55aj1xKzEKbz0ic2VsZiIrcQpyZXR1cm4gbmV3IEZ1bmN0aW9uKCJyZXR1cm4gZnVuY3Rpb24o
+KXt2YXIgIitvKyIgPSB0aGlzLiIrSC5kKEgub04oKSkrIjtyZXR1cm4gIitvKyIuIitILmQodCkrIigp
+O30iKSgpfW49ImFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6Ii5zcGxpdCgiIikuc3BsaWNlKDAscyku
+am9pbigiLCIpCnE9JC55agppZih0eXBlb2YgcSE9PSJudW1iZXIiKXJldHVybiBxLmgoKQokLnlqPXEr
+MQpuKz1xCnJldHVybiBuZXcgRnVuY3Rpb24oInJldHVybiBmdW5jdGlvbigiK24rIil7cmV0dXJuIHRo
+aXMuIitILmQoSC5vTigpKSsiLiIrSC5kKHQpKyIoIituKyIpO30iKSgpfSwKWjQ6ZnVuY3Rpb24oYSxi
+LGMsZCl7dmFyIHQ9SC5EVixzPUgueVMKc3dpdGNoKGI/LTE6YSl7Y2FzZSAwOnRocm93IEguYihILkVm
+KCJJbnRlcmNlcHRlZCBmdW5jdGlvbiB3aXRoIG5vIGFyZ3VtZW50cy4iKSkKY2FzZSAxOnJldHVybiBm
+dW5jdGlvbihlLGYsZyl7cmV0dXJuIGZ1bmN0aW9uKCl7cmV0dXJuIGYodGhpcylbZV0oZyh0aGlzKSl9
+fShjLHQscykKY2FzZSAyOnJldHVybiBmdW5jdGlvbihlLGYsZyl7cmV0dXJuIGZ1bmN0aW9uKGgpe3Jl
+dHVybiBmKHRoaXMpW2VdKGcodGhpcyksaCl9fShjLHQscykKY2FzZSAzOnJldHVybiBmdW5jdGlvbihl
+LGYsZyl7cmV0dXJuIGZ1bmN0aW9uKGgsaSl7cmV0dXJuIGYodGhpcylbZV0oZyh0aGlzKSxoLGkpfX0o
+Yyx0LHMpCmNhc2UgNDpyZXR1cm4gZnVuY3Rpb24oZSxmLGcpe3JldHVybiBmdW5jdGlvbihoLGksail7
+cmV0dXJuIGYodGhpcylbZV0oZyh0aGlzKSxoLGksail9fShjLHQscykKY2FzZSA1OnJldHVybiBmdW5j
+dGlvbihlLGYsZyl7cmV0dXJuIGZ1bmN0aW9uKGgsaSxqLGspe3JldHVybiBmKHRoaXMpW2VdKGcodGhp
+cyksaCxpLGosayl9fShjLHQscykKY2FzZSA2OnJldHVybiBmdW5jdGlvbihlLGYsZyl7cmV0dXJuIGZ1
+bmN0aW9uKGgsaSxqLGssbCl7cmV0dXJuIGYodGhpcylbZV0oZyh0aGlzKSxoLGksaixrLGwpfX0oYyx0
+LHMpCmRlZmF1bHQ6cmV0dXJuIGZ1bmN0aW9uKGUsZixnLGgpe3JldHVybiBmdW5jdGlvbigpe2g9W2co
+dGhpcyldCkFycmF5LnByb3RvdHlwZS5wdXNoLmFwcGx5KGgsYXJndW1lbnRzKQpyZXR1cm4gZS5hcHBs
+eShmKHRoaXMpLGgpfX0oZCx0LHMpfX0sCkhmOmZ1bmN0aW9uKGEsYil7dmFyIHQscyxyLHEscCxvLG49
+SC5vTigpLG09JC5QNAppZihtPT1udWxsKW09JC5QND1ILkUyKCJyZWNlaXZlciIpCnQ9Yi4kc3R1Yk5h
+bWUKcz1iLmxlbmd0aApyPWFbdF0KcT1iPT1udWxsP3I9PW51bGw6Yj09PXIKcD0hcXx8cz49MjgKaWYo
+cClyZXR1cm4gSC5aNChzLCFxLHQsYikKaWYocz09PTEpe3E9InJldHVybiBmdW5jdGlvbigpe3JldHVy
+biB0aGlzLiIrSC5kKG4pKyIuIitILmQodCkrIih0aGlzLiIrbSsiKTsiCnA9JC55agppZih0eXBlb2Yg
+cCE9PSJudW1iZXIiKXJldHVybiBwLmgoKQokLnlqPXArMQpyZXR1cm4gbmV3IEZ1bmN0aW9uKHErcCsi
+fSIpKCl9bz0iYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXoiLnNwbGl0KCIiKS5zcGxpY2UoMCxzLTEp
+LmpvaW4oIiwiKQpxPSJyZXR1cm4gZnVuY3Rpb24oIitvKyIpe3JldHVybiB0aGlzLiIrSC5kKG4pKyIu
+IitILmQodCkrIih0aGlzLiIrbSsiLCAiK28rIik7IgpwPSQueWoKaWYodHlwZW9mIHAhPT0ibnVtYmVy
+IilyZXR1cm4gcC5oKCkKJC55aj1wKzEKcmV0dXJuIG5ldyBGdW5jdGlvbihxK3ArIn0iKSgpfSwKS3E6
+ZnVuY3Rpb24oYSxiLGMsZCxlLGYsZyl7cmV0dXJuIEguaUEoYSxiLGMsZCwhIWUsISFmLGcpfSwKVG46
+ZnVuY3Rpb24oYSxiKXtyZXR1cm4gSC5jRSh2LnR5cGVVbml2ZXJzZSxILnEoYS5hKSxiKX0sClBXOmZ1
+bmN0aW9uKGEsYil7cmV0dXJuIEguY0Uodi50eXBlVW5pdmVyc2UsSC5xKGEuYyksYil9LApEVjpmdW5j
+dGlvbihhKXtyZXR1cm4gYS5hfSwKeVM6ZnVuY3Rpb24oYSl7cmV0dXJuIGEuY30sCm9OOmZ1bmN0aW9u
+KCl7dmFyIHQ9JC5tSgpyZXR1cm4gdD09bnVsbD8kLm1KPUguRTIoInNlbGYiKTp0fSwKRTI6ZnVuY3Rp
+b24oYSl7dmFyIHQscyxyLHE9bmV3IEguankoInNlbGYiLCJ0YXJnZXQiLCJyZWNlaXZlciIsIm5hbWUi
+KSxwPUouRXAoT2JqZWN0LmdldE93blByb3BlcnR5TmFtZXMocSksdS56KQpmb3IodD1wLmxlbmd0aCxz
+PTA7czx0Oysrcyl7cj1wW3NdCmlmKHFbcl09PT1hKXJldHVybiByfXRocm93IEguYihQLnhZKCJGaWVs
+ZCBuYW1lICIrYSsiIG5vdCBmb3VuZC4iKSl9LApvVDpmdW5jdGlvbihhKXtpZihhPT1udWxsKUguZk8o
+ImJvb2xlYW4gZXhwcmVzc2lvbiBtdXN0IG5vdCBiZSBudWxsIikKcmV0dXJuIGF9LApmTzpmdW5jdGlv
+bihhKXt0aHJvdyBILmIobmV3IEgua1koYSkpfSwKYWc6ZnVuY3Rpb24oYSl7dGhyb3cgSC5iKG5ldyBQ
+LnQ3KGEpKX0sCkVmOmZ1bmN0aW9uKGEpe3JldHVybiBuZXcgSC5FcShhKX0sCllnOmZ1bmN0aW9uKGEp
+e3JldHVybiB2LmdldElzb2xhdGVUYWcoYSl9LApWTTpmdW5jdGlvbihhLGIpe2Fbdi5hcnJheVJ0aV09
+YgpyZXR1cm4gYX0sCm9YOmZ1bmN0aW9uKGEpe2lmKGE9PW51bGwpcmV0dXJuIG51bGwKcmV0dXJuIGEu
+JHRpfSwKSU06ZnVuY3Rpb24oYSxiLGMpe3JldHVybiBILlk5KGFbIiRhIitILmQoYyldLEgub1goYikp
+fSwKWTk6ZnVuY3Rpb24oYSxiKXtpZihhPT1udWxsKXJldHVybiBiCmE9YS5hcHBseShudWxsLGIpCmlm
+KGE9PW51bGwpcmV0dXJuIG51bGwKaWYoQXJyYXkuaXNBcnJheShhKSlyZXR1cm4gYQppZih0eXBlb2Yg
+YT09ImZ1bmN0aW9uIilyZXR1cm4gYS5hcHBseShudWxsLGIpCnJldHVybiBifSwKSUc6ZnVuY3Rpb24o
+YSxiLGMpe3JldHVybiBhLmFwcGx5KGIsSC5JTShKLmlhKGIpLGIsYykpfSwKaXc6ZnVuY3Rpb24oYSxi
+LGMpe09iamVjdC5kZWZpbmVQcm9wZXJ0eShhLGIse3ZhbHVlOmMsZW51bWVyYWJsZTpmYWxzZSx3cml0
+YWJsZTp0cnVlLGNvbmZpZ3VyYWJsZTp0cnVlfSl9LApHOmZ1bmN0aW9uKGEpe3ZhciB0LHMscixxLHA9
+SC5jKCQueS4kMShhKSksbz0kLmpbcF0KaWYobyE9bnVsbCl7T2JqZWN0LmRlZmluZVByb3BlcnR5KGEs
+di5kaXNwYXRjaFByb3BlcnR5TmFtZSx7dmFsdWU6byxlbnVtZXJhYmxlOmZhbHNlLHdyaXRhYmxlOnRy
+dWUsY29uZmlndXJhYmxlOnRydWV9KQpyZXR1cm4gby5pfXQ9JC52W3BdCmlmKHQhPW51bGwpcmV0dXJu
+IHQKcz12LmludGVyY2VwdG9yc0J5VGFnW3BdCmlmKHM9PW51bGwpe3A9SC5jKCQudS4kMihhLHApKQpp
+ZihwIT1udWxsKXtvPSQualtwXQppZihvIT1udWxsKXtPYmplY3QuZGVmaW5lUHJvcGVydHkoYSx2LmRp
+c3BhdGNoUHJvcGVydHlOYW1lLHt2YWx1ZTpvLGVudW1lcmFibGU6ZmFsc2Usd3JpdGFibGU6dHJ1ZSxj
+b25maWd1cmFibGU6dHJ1ZX0pCnJldHVybiBvLml9dD0kLnZbcF0KaWYodCE9bnVsbClyZXR1cm4gdApz
+PXYuaW50ZXJjZXB0b3JzQnlUYWdbcF19fWlmKHM9PW51bGwpcmV0dXJuIG51bGwKdD1zLnByb3RvdHlw
+ZQpyPXBbMF0KaWYocj09PSIhIil7bz1ILmwodCkKJC5qW3BdPW8KT2JqZWN0LmRlZmluZVByb3BlcnR5
+KGEsdi5kaXNwYXRjaFByb3BlcnR5TmFtZSx7dmFsdWU6byxlbnVtZXJhYmxlOmZhbHNlLHdyaXRhYmxl
+OnRydWUsY29uZmlndXJhYmxlOnRydWV9KQpyZXR1cm4gby5pfWlmKHI9PT0ifiIpeyQudltwXT10CnJl
+dHVybiB0fWlmKHI9PT0iLSIpe3E9SC5sKHQpCk9iamVjdC5kZWZpbmVQcm9wZXJ0eShPYmplY3QuZ2V0
+UHJvdG90eXBlT2YoYSksdi5kaXNwYXRjaFByb3BlcnR5TmFtZSx7dmFsdWU6cSxlbnVtZXJhYmxlOmZh
+bHNlLHdyaXRhYmxlOnRydWUsY29uZmlndXJhYmxlOnRydWV9KQpyZXR1cm4gcS5pfWlmKHI9PT0iKyIp
+cmV0dXJuIEguTGMoYSx0KQppZihyPT09IioiKXRocm93IEguYihQLm4ocCkpCmlmKHYubGVhZlRhZ3Nb
+cF09PT10cnVlKXtxPUgubCh0KQpPYmplY3QuZGVmaW5lUHJvcGVydHkoT2JqZWN0LmdldFByb3RvdHlw
+ZU9mKGEpLHYuZGlzcGF0Y2hQcm9wZXJ0eU5hbWUse3ZhbHVlOnEsZW51bWVyYWJsZTpmYWxzZSx3cml0
+YWJsZTp0cnVlLGNvbmZpZ3VyYWJsZTp0cnVlfSkKcmV0dXJuIHEuaX1lbHNlIHJldHVybiBILkxjKGEs
+dCl9LApMYzpmdW5jdGlvbihhLGIpe3ZhciB0PU9iamVjdC5nZXRQcm90b3R5cGVPZihhKQpPYmplY3Qu
+ZGVmaW5lUHJvcGVydHkodCx2LmRpc3BhdGNoUHJvcGVydHlOYW1lLHt2YWx1ZTpKLlF1KGIsdCxudWxs
+LG51bGwpLGVudW1lcmFibGU6ZmFsc2Usd3JpdGFibGU6dHJ1ZSxjb25maWd1cmFibGU6dHJ1ZX0pCnJl
+dHVybiBifSwKbDpmdW5jdGlvbihhKXtyZXR1cm4gSi5RdShhLCExLG51bGwsISFhLiRpWGopfSwKVkY6
+ZnVuY3Rpb24oYSxiLGMpe3ZhciB0PWIucHJvdG90eXBlCmlmKHYubGVhZlRhZ3NbYV09PT10cnVlKXJl
+dHVybiBILmwodCkKZWxzZSByZXR1cm4gSi5RdSh0LGMsbnVsbCxudWxsKX0sCk06ZnVuY3Rpb24oKXtp
+ZighMD09PSQuSylyZXR1cm4KJC5LPSEwCkguRCgpfSwKRDpmdW5jdGlvbigpe3ZhciB0LHMscixxLHAs
+byxuLG0KJC5qPU9iamVjdC5jcmVhdGUobnVsbCkKJC52PU9iamVjdC5jcmVhdGUobnVsbCkKSC5hKCkK
+dD12LmludGVyY2VwdG9yc0J5VGFnCnM9T2JqZWN0LmdldE93blByb3BlcnR5TmFtZXModCkKaWYodHlw
+ZW9mIHdpbmRvdyE9InVuZGVmaW5lZCIpe3dpbmRvdwpyPWZ1bmN0aW9uKCl7fQpmb3IocT0wO3E8cy5s
+ZW5ndGg7KytxKXtwPXNbcV0Kbz0kLng3LiQxKHApCmlmKG8hPW51bGwpe249SC5WRihwLHRbcF0sbykK
+aWYobiE9bnVsbCl7T2JqZWN0LmRlZmluZVByb3BlcnR5KG8sdi5kaXNwYXRjaFByb3BlcnR5TmFtZSx7
+dmFsdWU6bixlbnVtZXJhYmxlOmZhbHNlLHdyaXRhYmxlOnRydWUsY29uZmlndXJhYmxlOnRydWV9KQpy
+LnByb3RvdHlwZT1vfX19fWZvcihxPTA7cTxzLmxlbmd0aDsrK3Epe3A9c1txXQppZigvXltBLVphLXpf
+XS8udGVzdChwKSl7bT10W3BdCnRbIiEiK3BdPW0KdFsifiIrcF09bQp0WyItIitwXT1tCnRbIisiK3Bd
+PW0KdFsiKiIrcF09bX19fSwKYTpmdW5jdGlvbigpe3ZhciB0LHMscixxLHAsbyxuPUMuTzQoKQpuPUgu
+RihDLllxLEguRihDLktVLEguRihDLmZRLEguRihDLmZRLEguRihDLmk3LEguRihDLnhpLEguRihDLmRr
+KEMud2IpLG4pKSkpKSkpCmlmKHR5cGVvZiBkYXJ0TmF0aXZlRGlzcGF0Y2hIb29rc1RyYW5zZm9ybWVy
+IT0idW5kZWZpbmVkIil7dD1kYXJ0TmF0aXZlRGlzcGF0Y2hIb29rc1RyYW5zZm9ybWVyCmlmKHR5cGVv
+ZiB0PT0iZnVuY3Rpb24iKXQ9W3RdCmlmKHQuY29uc3RydWN0b3I9PUFycmF5KWZvcihzPTA7czx0Lmxl
+bmd0aDsrK3Mpe3I9dFtzXQppZih0eXBlb2Ygcj09ImZ1bmN0aW9uIiluPXIobil8fG59fXE9bi5nZXRU
+YWcKcD1uLmdldFVua25vd25UYWcKbz1uLnByb3RvdHlwZUZvclRhZwokLnk9bmV3IEgucihxKQokLnU9
+bmV3IEguZEMocCkKJC54Nz1uZXcgSC53TihvKX0sCkY6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gYShiKXx8
+Yn0sCnY0OmZ1bmN0aW9uKGEsYixjLGQsZSxmKXt2YXIgdD1iPyJtIjoiIixzPWM/IiI6ImkiLHI9ZD8i
+dSI6IiIscT1lPyJzIjoiIixwPWY/ImciOiIiLG89ZnVuY3Rpb24oZyxoKXt0cnl7cmV0dXJuIG5ldyBS
+ZWdFeHAoZyxoKX1jYXRjaChuKXtyZXR1cm4gbn19KGEsdCtzK3IrcStwKQppZihvIGluc3RhbmNlb2Yg
+UmVnRXhwKXJldHVybiBvCnRocm93IEguYihQLnJyKCJJbGxlZ2FsIFJlZ0V4cCBwYXR0ZXJuICgiK1N0
+cmluZyhvKSsiKSIsYSxudWxsKSl9LAptMjpmdW5jdGlvbihhLGIsYyl7dmFyIHQKaWYodHlwZW9mIGI9
+PSJzdHJpbmciKXJldHVybiBhLmluZGV4T2YoYixjKT49MAplbHNlIGlmKGIgaW5zdGFuY2VvZiBILlZS
+KXt0PUMueEIuRyhhLGMpCnJldHVybiBiLmIudGVzdCh0KX1lbHNle3Q9Si5GTChiLEMueEIuRyhhLGMp
+KQpyZXR1cm4hdC5nbDAodCl9fSwKQTQ6ZnVuY3Rpb24oYSl7aWYoYS5pbmRleE9mKCIkIiwwKT49MCly
+ZXR1cm4gYS5yZXBsYWNlKC9cJC9nLCIkJCQkIikKcmV0dXJuIGF9LAplQTpmdW5jdGlvbihhKXtpZigv
+W1tcXXt9KCkqKz8uXFxeJHxdLy50ZXN0KGEpKXJldHVybiBhLnJlcGxhY2UoL1tbXF17fSgpKis/Llxc
+XiR8XS9nLCJcXCQmIikKcmV0dXJuIGF9LAp5czpmdW5jdGlvbihhLGIsYyl7dmFyIHQ9SC5uTShhLGIs
+YykKcmV0dXJuIHR9LApuTTpmdW5jdGlvbihhLGIsYyl7dmFyIHQscyxyLHEKaWYoYj09PSIiKXtpZihh
+PT09IiIpcmV0dXJuIGMKdD1hLmxlbmd0aApmb3Iocz1jLHI9MDtyPHQ7KytyKXM9cythW3JdK2MKcmV0
+dXJuIHMuY2hhckNvZGVBdCgwKT09MD9zOnN9cT1hLmluZGV4T2YoYiwwKQppZihxPDApcmV0dXJuIGEK
+aWYoYS5sZW5ndGg8NTAwfHxjLmluZGV4T2YoIiQiLDApPj0wKXJldHVybiBhLnNwbGl0KGIpLmpvaW4o
+YykKcmV0dXJuIGEucmVwbGFjZShuZXcgUmVnRXhwKEguZUEoYiksJ2cnKSxILkE0KGMpKX0sClBEOmZ1
+bmN0aW9uIFBEKGEsYil7dGhpcy5hPWEKdGhpcy4kdGk9Yn0sCldVOmZ1bmN0aW9uIFdVKCl7fSwKTFA6
+ZnVuY3Rpb24gTFAoYSxiLGMsZCl7dmFyIF89dGhpcwpfLmE9YQpfLmI9YgpfLmM9YwpfLiR0aT1kfSwK
+WFI6ZnVuY3Rpb24gWFIoYSxiKXt0aGlzLmE9YQp0aGlzLiR0aT1ifSwKTEk6ZnVuY3Rpb24gTEkoYSxi
+LGMsZCxlKXt2YXIgXz10aGlzCl8uYT1hCl8uYz1iCl8uZD1jCl8uZT1kCl8uZj1lfSwKQ2o6ZnVuY3Rp
+b24gQ2ooYSxiLGMpe3RoaXMuYT1hCnRoaXMuYj1iCnRoaXMuYz1jfSwKZjk6ZnVuY3Rpb24gZjkoYSxi
+LGMsZCxlLGYpe3ZhciBfPXRoaXMKXy5hPWEKXy5iPWIKXy5jPWMKXy5kPWQKXy5lPWUKXy5mPWZ9LApX
+MDpmdW5jdGlvbiBXMChhLGIpe3RoaXMuYT1hCnRoaXMuYj1ifSwKYXo6ZnVuY3Rpb24gYXooYSxiLGMp
+e3RoaXMuYT1hCnRoaXMuYj1iCnRoaXMuYz1jfSwKdlY6ZnVuY3Rpb24gdlYoYSl7dGhpcy5hPWF9LApi
+cTpmdW5jdGlvbiBicShhLGIpe3RoaXMuYT1hCnRoaXMuYj1ifSwKQW06ZnVuY3Rpb24gQW0oYSl7dGhp
+cy5hPWF9LApYTzpmdW5jdGlvbiBYTyhhKXt0aGlzLmE9YQp0aGlzLmI9bnVsbH0sClRwOmZ1bmN0aW9u
+IFRwKCl7fSwKbGM6ZnVuY3Rpb24gbGMoKXt9LAp6eDpmdW5jdGlvbiB6eCgpe30sCmp5OmZ1bmN0aW9u
+IGp5KGEsYixjLGQpe3ZhciBfPXRoaXMKXy5hPWEKXy5iPWIKXy5jPWMKXy5kPWR9LApFcTpmdW5jdGlv
+biBFcShhKXt0aGlzLmE9YX0sCmtZOmZ1bmN0aW9uIGtZKGEpe3RoaXMuYT1hfSwKTjU6ZnVuY3Rpb24g
+TjUoYSl7dmFyIF89dGhpcwpfLmE9MApfLmY9Xy5lPV8uZD1fLmM9Xy5iPW51bGwKXy5yPTAKXy4kdGk9
+YX0sCmRiOmZ1bmN0aW9uIGRiKGEsYil7dmFyIF89dGhpcwpfLmE9YQpfLmI9YgpfLmQ9Xy5jPW51bGx9
+LAppNTpmdW5jdGlvbiBpNShhLGIpe3RoaXMuYT1hCnRoaXMuJHRpPWJ9LApONjpmdW5jdGlvbiBONihh
+LGIsYyl7dmFyIF89dGhpcwpfLmE9YQpfLmI9YgpfLmQ9Xy5jPW51bGwKXy4kdGk9Y30sCnI6ZnVuY3Rp
+b24gcihhKXt0aGlzLmE9YX0sCmRDOmZ1bmN0aW9uIGRDKGEpe3RoaXMuYT1hfSwKd046ZnVuY3Rpb24g
+d04oYSl7dGhpcy5hPWF9LApWUjpmdW5jdGlvbiBWUihhLGIpe3ZhciBfPXRoaXMKXy5hPWEKXy5iPWIK
+Xy5kPV8uYz1udWxsfSwKRUs6ZnVuY3Rpb24gRUsoYSl7dGhpcy5iPWF9LApLVzpmdW5jdGlvbiBLVyhh
+LGIsYyl7dGhpcy5hPWEKdGhpcy5iPWIKdGhpcy5jPWN9LApQYjpmdW5jdGlvbiBQYihhLGIsYyl7dmFy
+IF89dGhpcwpfLmE9YQpfLmI9YgpfLmM9YwpfLmQ9bnVsbH0sCnRROmZ1bmN0aW9uIHRRKGEsYil7dGhp
+cy5hPWEKdGhpcy5jPWJ9LApORjpmdW5jdGlvbiBORihhLGIsYyl7dGhpcy5hPWEKdGhpcy5iPWIKdGhp
+cy5jPWN9LApTZDpmdW5jdGlvbiBTZChhLGIsYyl7dmFyIF89dGhpcwpfLmE9YQpfLmI9YgpfLmM9Ywpf
+LmQ9bnVsbH0sClhGOmZ1bmN0aW9uKGEpe3JldHVybiBhfSwKb2Q6ZnVuY3Rpb24oYSxiLGMpe2lmKGE+
+Pj4wIT09YXx8YT49Yyl0aHJvdyBILmIoSC5IWShiLGEpKX0sCnJNOmZ1bmN0aW9uKGEsYixjKXt2YXIg
+dAppZighKGE+Pj4wIT09YSkpdD1iPj4+MCE9PWJ8fGE+Ynx8Yj5jCmVsc2UgdD0hMAppZih0KXRocm93
+IEguYihILmF1KGEsYixjKSkKcmV0dXJuIGJ9LApwRjpmdW5jdGlvbiBwRigpe30sCmIwOmZ1bmN0aW9u
+IGIwKCl7fSwKRGc6ZnVuY3Rpb24gRGcoKXt9LApQZzpmdW5jdGlvbiBQZygpe30sCnhqOmZ1bmN0aW9u
+IHhqKCl7fSwKZEU6ZnVuY3Rpb24gZEUoKXt9LApaQTpmdW5jdGlvbiBaQSgpe30sCndmOmZ1bmN0aW9u
+IHdmKCl7fSwKUHE6ZnVuY3Rpb24gUHEoKXt9LAplRTpmdW5jdGlvbiBlRSgpe30sClY2OmZ1bmN0aW9u
+IFY2KCl7fSwKUkc6ZnVuY3Rpb24gUkcoKXt9LApWUDpmdW5jdGlvbiBWUCgpe30sCldCOmZ1bmN0aW9u
+IFdCKCl7fSwKWkc6ZnVuY3Rpb24gWkcoKXt9LApjejpmdW5jdGlvbihhLGIpe3ZhciB0PWIuYwpyZXR1
+cm4gdD09bnVsbD9iLmM9SC5CYyhhLGIueiwhMCk6dH0sCnhaOmZ1bmN0aW9uKGEsYil7dmFyIHQ9Yi5j
+CnJldHVybiB0PT1udWxsP2IuYz1ILlEyKGEsImI4IixbYi56XSk6dH0sClExOmZ1bmN0aW9uKGEpe3Zh
+ciB0PWEueQppZih0PT09Nnx8dD09PTd8fHQ9PT04KXJldHVybiBILlExKGEueikKcmV0dXJuIHQ9PT0x
+MXx8dD09PTEyfSwKbUQ6ZnVuY3Rpb24oYSl7dmFyIHQ9YS5jeQp0LnRvU3RyaW5nCnJldHVybiB0fSwK
+TjA6ZnVuY3Rpb24oYSl7cmV0dXJuIEguRSh2LnR5cGVVbml2ZXJzZSxhLCExKX0sClBMOmZ1bmN0aW9u
+KGEsYixjLGEwKXt2YXIgdCxzLHIscSxwLG8sbixtLGwsayxqLGksaCxnLGYsZSxkPWIueQpzd2l0Y2go
+ZCl7Y2FzZSA1OmNhc2UgMTpjYXNlIDI6Y2FzZSAzOmNhc2UgNDpyZXR1cm4gYgpjYXNlIDY6dD1iLnoK
+cz1ILlBMKGEsdCxjLGEwKQppZihzPT09dClyZXR1cm4gYgpyZXR1cm4gSC5TTyhhLHMsITApCmNhc2Ug
+Nzp0PWIuegpzPUguUEwoYSx0LGMsYTApCmlmKHM9PT10KXJldHVybiBiCnJldHVybiBILkJjKGEscywh
+MCkKY2FzZSA4OnQ9Yi56CnM9SC5QTChhLHQsYyxhMCkKaWYocz09PXQpcmV0dXJuIGIKcmV0dXJuIEgu
+TE4oYSxzLCEwKQpjYXNlIDk6cj1iLlEKcT1ILmJaKGEscixjLGEwKQppZihxPT09cilyZXR1cm4gYgpy
+ZXR1cm4gSC5RMihhLGIueixxKQpjYXNlIDEwOnA9Yi56Cm89SC5QTChhLHAsYyxhMCkKbj1iLlEKbT1I
+LmJaKGEsbixjLGEwKQppZihvPT09cCYmbT09PW4pcmV0dXJuIGIKcmV0dXJuIEguYXAoYSxvLG0pCmNh
+c2UgMTE6bD1iLnoKaz1ILlBMKGEsbCxjLGEwKQpqPWIuUQppPUgucVQoYSxqLGMsYTApCmlmKGs9PT1s
+JiZpPT09ailyZXR1cm4gYgpyZXR1cm4gSC5OZihhLGssaSkKY2FzZSAxMjpoPWIuUQphMCs9aC5sZW5n
+dGgKZz1ILmJaKGEsaCxjLGEwKQpwPWIuegpvPUguUEwoYSxwLGMsYTApCmlmKGc9PT1oJiZvPT09cCly
+ZXR1cm4gYgpyZXR1cm4gSC5EUyhhLG8sZywhMCkKY2FzZSAxMzpmPWIuegppZihmPGEwKXJldHVybiBi
+CmU9Y1tmLWEwXQppZihlPT1udWxsKXJldHVybiBiCnJldHVybiBlCmRlZmF1bHQ6dGhyb3cgSC5iKFAu
+aFYoIkF0dGVtcHRlZCB0byBzdWJzdGl0dXRlIHVuZXhwZWN0ZWQgUlRJIGtpbmQgIitkKSl9fSwKYlo6
+ZnVuY3Rpb24oYSxiLGMsZCl7dmFyIHQscyxyLHEscD1iLmxlbmd0aCxvPVtdCmZvcih0PSExLHM9MDtz
+PHA7KytzKXtyPWJbc10KcT1ILlBMKGEscixjLGQpCmlmKHEhPT1yKXQ9ITAKby5wdXNoKHEpfXJldHVy
+biB0P286Yn0sCnZPOmZ1bmN0aW9uKGEsYixjLGQpe3ZhciB0LHMscixxLHAsbz1iLmxlbmd0aCxuPVtd
+CmZvcih0PSExLHM9MDtzPG87cys9Mil7cj1iW3NdCnE9YltzKzFdCnA9SC5QTChhLHEsYyxkKQppZihw
+IT09cSl0PSEwCm4ucHVzaChyKQpuLnB1c2gocCl9cmV0dXJuIHQ/bjpifSwKcVQ6ZnVuY3Rpb24oYSxi
+LGMsZCl7dmFyIHQscz1iLmEscj1ILmJaKGEscyxjLGQpLHE9Yi5iLHA9SC5iWihhLHEsYyxkKSxvPWIu
+YyxuPUgudk8oYSxvLGMsZCkKaWYocj09PXMmJnA9PT1xJiZuPT09bylyZXR1cm4gYgp0PW5ldyBILkVU
+KCkKdC5hPXIKdC5iPXAKdC5jPW4KcmV0dXJuIHR9LApKUzpmdW5jdGlvbihhKXt2YXIgdD1hLiRTCmlm
+KHQhPW51bGwpe2lmKHR5cGVvZiB0PT0ibnVtYmVyIilyZXR1cm4gSC5CcCh0KQpyZXR1cm4gYS4kUygp
+fXJldHVybiBudWxsfSwKVWU6ZnVuY3Rpb24oYSxiKXt2YXIgdAppZihILlExKGIpKWlmKGEgaW5zdGFu
+Y2VvZiBILlRwKXt0PUguSlMoYSkKaWYodCE9bnVsbClyZXR1cm4gdH1yZXR1cm4gSC5xKGEpfSwKcTpm
+dW5jdGlvbihhKXt2YXIgdAppZihhIGluc3RhbmNlb2YgUC5NaCl7dD1hLiR0aQpyZXR1cm4gdCE9bnVs
+bD90OkguVlUoYSl9aWYoQXJyYXkuaXNBcnJheShhKSlyZXR1cm4gSC50NihhKQpyZXR1cm4gSC5WVShK
+LmlhKGEpKX0sCnQ2OmZ1bmN0aW9uKGEpe3ZhciB0PWFbdi5hcnJheVJ0aV0scz11LnYKaWYodD09bnVs
+bClyZXR1cm4gcwppZih0LmNvbnN0cnVjdG9yIT09cy5jb25zdHJ1Y3RvcilyZXR1cm4gcwpyZXR1cm4g
+dH0sCkxoOmZ1bmN0aW9uKGEpe3ZhciB0PWEuJHRpCnJldHVybiB0IT1udWxsP3Q6SC5WVShhKX0sClZV
+OmZ1bmN0aW9uKGEpe3ZhciB0PWEuY29uc3RydWN0b3Iscz10LiRjY2FjaGUKaWYocyE9bnVsbClyZXR1
+cm4gcwpyZXR1cm4gSC5yOShhLHQpfSwKcjk6ZnVuY3Rpb24oYSxiKXt2YXIgdD1hIGluc3RhbmNlb2Yg
+SC5UcD9hLl9fcHJvdG9fXy5fX3Byb3RvX18uY29uc3RydWN0b3I6YixzPUguYWkodi50eXBlVW5pdmVy
+c2UsdC5uYW1lKQpiLiRjY2FjaGU9cwpyZXR1cm4gc30sCkJwOmZ1bmN0aW9uKGEpe3ZhciB0LHM9YSxy
+PXYudHlwZXMscT1yW3NdCmlmKHR5cGVvZiBxPT0ic3RyaW5nIil7dD1ILkUodi50eXBlVW5pdmVyc2Us
+cSwhMSkKcltzXT10CnJldHVybiB0fXJldHVybiBxfSwKSko6ZnVuY3Rpb24oYSl7dmFyIHQ9dGhpcyxz
+PUguWU8scj11LksKaWYodD09PXIpe3M9SC5rZQp0LmE9SC5UaX1lbHNlIGlmKEguQTgodCl8fHQ9PT1y
+KXtzPUguSXcKdC5hPUguaG59ZWxzZSBpZih0PT09dS5xKXM9SC5vawplbHNlIGlmKHQ9PT11LmdSKXM9
+SC5LSAplbHNlIGlmKHQ9PT11LmRpKXM9SC5LSAplbHNlIGlmKHQ9PT11Lk4pcz1ILk1NCmVsc2UgaWYo
+dD09PXUueSlzPUguclEKZWxzZSBpZih0Lnk9PT05KXtyPXQuegppZih0LlEuZXZlcnkoSC5jYykpe3Qu
+cj0iJGkiK3IKcz1ILnQ0fX10LmI9cwpyZXR1cm4gdC5iKGEpfSwKWU86ZnVuY3Rpb24oYSl7dmFyIHQ9
+dGhpcwpyZXR1cm4gSC5XZSh2LnR5cGVVbml2ZXJzZSxILlVlKGEsdCksbnVsbCx0LG51bGwpfSwKdDQ6
+ZnVuY3Rpb24oYSl7dmFyIHQ9dGhpcwp0PXQucgp0LnRvU3RyaW5nCmlmKGEgaW5zdGFuY2VvZiBQLk1o
+KXJldHVybiEhYVt0XQpyZXR1cm4hIUouaWEoYSlbdF19LApPejpmdW5jdGlvbihhKXt2YXIgdD10aGlz
+CmlmKGE9PW51bGwpcmV0dXJuIGEKZWxzZSBpZih0LmIoYSkpcmV0dXJuIGEKdGhyb3cgSC5iKEguWmMo
+SC5wKGEsSC5VZShhLHQpLEguSih0LG51bGwpKSkpfSwKRGg6ZnVuY3Rpb24oYSxiLGMsZCl7dmFyIHQ9
+bnVsbAppZihILldlKHYudHlwZVVuaXZlcnNlLGEsdCxiLHQpKXJldHVybiBhCnRocm93IEguYihILlpj
+KCJUaGUgdHlwZSBhcmd1bWVudCAnIitILmQoSC5KKGEsdCkpKyInIGlzIG5vdCBhIHN1YnR5cGUgb2Yg
+dGhlIHR5cGUgdmFyaWFibGUgYm91bmQgJyIrSC5kKEguSihiLHQpKSsiJyBvZiB0eXBlIHZhcmlhYmxl
+ICciK2MrIicgaW4gJyIrSC5kKGQpKyInLiIpKX0sCnA6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0PVAuaChh
+KSxzPUguSihiPT1udWxsP0gucShhKTpiLG51bGwpCnJldHVybiB0KyI6IHR5cGUgJyIrSC5kKHMpKyIn
+IGlzIG5vdCBhIHN1YnR5cGUgb2YgdHlwZSAnIitILmQoYykrIicifSwKWmM6ZnVuY3Rpb24oYSl7cmV0
+dXJuIG5ldyBILngoIlR5cGVFcnJvcjogIithKX0sCkI6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gbmV3IEgu
+eCgiVHlwZUVycm9yOiAiK0gucChhLG51bGwsYikpfSwKa2U6ZnVuY3Rpb24oYSl7cmV0dXJuITB9LApU
+aTpmdW5jdGlvbihhKXtyZXR1cm4gYX0sCkl3OmZ1bmN0aW9uKGEpe3JldHVybiEwfSwKaG46ZnVuY3Rp
+b24oYSl7cmV0dXJuIGF9LApyUTpmdW5jdGlvbihhKXtyZXR1cm4hMD09PWF8fCExPT09YX0sCkU5OmZ1
+bmN0aW9uKGEpe2lmKCEwPT09YXx8ITE9PT1hKXJldHVybiBhCmlmKGE9PW51bGwpcmV0dXJuIGEKdGhy
+b3cgSC5iKEguQihhLCJib29sIikpfSwKZGo6ZnVuY3Rpb24oYSl7aWYodHlwZW9mIGE9PSJudW1iZXIi
+KXJldHVybiBhCmlmKGE9PW51bGwpcmV0dXJuIGEKdGhyb3cgSC5iKEguQihhLCJkb3VibGUiKSl9LApv
+azpmdW5jdGlvbihhKXtyZXR1cm4gdHlwZW9mIGE9PSJudW1iZXIiJiZNYXRoLmZsb29yKGEpPT09YX0s
+CldZOmZ1bmN0aW9uKGEpe2lmKHR5cGVvZiBhPT0ibnVtYmVyIiYmTWF0aC5mbG9vcihhKT09PWEpcmV0
+dXJuIGEKaWYoYT09bnVsbClyZXR1cm4gYQp0aHJvdyBILmIoSC5CKGEsImludCIpKX0sCktIOmZ1bmN0
+aW9uKGEpe3JldHVybiB0eXBlb2YgYT09Im51bWJlciJ9LAp1VTpmdW5jdGlvbihhKXtpZih0eXBlb2Yg
+YT09Im51bWJlciIpcmV0dXJuIGEKaWYoYT09bnVsbClyZXR1cm4gYQp0aHJvdyBILmIoSC5CKGEsIm51
+bSIpKX0sCk1NOmZ1bmN0aW9uKGEpe3JldHVybiB0eXBlb2YgYT09InN0cmluZyJ9LApjOmZ1bmN0aW9u
+KGEpe2lmKHR5cGVvZiBhPT0ic3RyaW5nIilyZXR1cm4gYQppZihhPT1udWxsKXJldHVybiBhCnRocm93
+IEguYihILkIoYSwiU3RyaW5nIikpfSwKdzpmdW5jdGlvbihhLGIpe3ZhciB0LHMscgpmb3IodD0iIixz
+PSIiLHI9MDtyPGEubGVuZ3RoOysrcixzPSIsICIpdCs9Qy54Qi5oKHMsSC5KKGFbcl0sYikpCnJldHVy
+biB0fSwKZjpmdW5jdGlvbihhMSxhMixhMyl7dmFyIHQscyxyLHEscCxvLG4sbSxsLGssaixpLGgsZyxm
+LGUsZCxjLGIsYSxhMD0iLCAiCmlmKGEzIT1udWxsKXt0PWEzLmxlbmd0aAppZihhMj09bnVsbCl7YTI9
+SC5WTShbXSx1LnMpCnM9bnVsbH1lbHNlIHM9YTIubGVuZ3RoCnI9YTIubGVuZ3RoCmZvcihxPXQ7cT4w
+Oy0tcSlDLk5tLmkoYTIsIlQiKyhyK3EpKQpmb3IocD11Lkssbz0iPCIsbj0iIixxPTA7cTx0OysrcSxu
+PWEwKXtvKz1uCm09YTIubGVuZ3RoCmw9bS0xLXEKaWYobDwwKXJldHVybiBILmsoYTIsbCkKbz1DLnhC
+LmgobyxhMltsXSkKaz1hM1txXQppZighKEguQTgoayl8fGs9PT1wKSltPSEoaz09PXApCmVsc2UgbT0h
+MQppZihtKW8rPUMueEIuaCgiIGV4dGVuZHMgIixILkooayxhMikpfW8rPSI+In1lbHNle289IiIKcz1u
+dWxsfXA9YTEuegpqPWExLlEKaT1qLmEKaD1pLmxlbmd0aApnPWouYgpmPWcubGVuZ3RoCmU9ai5jCmQ9
+ZS5sZW5ndGgKYz1ILkoocCxhMikKZm9yKGI9IiIsYT0iIixxPTA7cTxoOysrcSxhPWEwKWIrPUMueEIu
+aChhLEguSihpW3FdLGEyKSkKaWYoZj4wKXtiKz1hKyJbIgpmb3IoYT0iIixxPTA7cTxmOysrcSxhPWEw
+KWIrPUMueEIuaChhLEguSihnW3FdLGEyKSkKYis9Il0ifWlmKGQ+MCl7Yis9YSsieyIKZm9yKGE9IiIs
+cT0wO3E8ZDtxKz0yLGE9YTApYis9Qy54Qi5oKGEsSC5KKGVbcSsxXSxhMikpKyIgIitlW3FdCmIrPSJ9
+In1pZihzIT1udWxsKXthMi50b1N0cmluZwphMi5sZW5ndGg9c31yZXR1cm4gbysiKCIrYisiKSA9PiAi
+K0guZChjKX0sCko6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzLHIscSxwLG8sbixtPWEueQppZihtPT09NSly
+ZXR1cm4iZXJhc2VkIgppZihtPT09MilyZXR1cm4iZHluYW1pYyIKaWYobT09PTMpcmV0dXJuInZvaWQi
+CmlmKG09PT0xKXJldHVybiJOZXZlciIKaWYobT09PTQpcmV0dXJuImFueSIKaWYobT09PTYpe3Q9SC5K
+KGEueixiKQpyZXR1cm4gdH1pZihtPT09Nyl7cz1hLnoKdD1ILkoocyxiKQpyPXMueQpyZXR1cm4gSi5t
+KHI9PT0xMXx8cj09PTEyP0MueEIuaCgiKCIsdCkrIikiOnQsIj8iKX1pZihtPT09OClyZXR1cm4iRnV0
+dXJlT3I8IitILmQoSC5KKGEueixiKSkrIj4iCmlmKG09PT05KXtxPUguQyhhLnopCnA9YS5RCnJldHVy
+biBwLmxlbmd0aCE9PTA/cSsoIjwiK0gudyhwLGIpKyI+Iik6cX1pZihtPT09MTEpcmV0dXJuIEguZihh
+LGIsbnVsbCkKaWYobT09PTEyKXJldHVybiBILmYoYS56LGIsYS5RKQppZihtPT09MTMpe2IudG9TdHJp
+bmcKbz1hLnoKbj1iLmxlbmd0aApvPW4tMS1vCmlmKG88MHx8bz49bilyZXR1cm4gSC5rKGIsbykKcmV0
+dXJuIGJbb119cmV0dXJuIj8ifSwKQzpmdW5jdGlvbihhKXt2YXIgdCxzPUguSmcoYSkKaWYocyE9bnVs
+bClyZXR1cm4gcwp0PSJtaW5pZmllZDoiK2EKcmV0dXJuIHR9LApRbzpmdW5jdGlvbihhLGIpe3ZhciB0
+PWEudFJbYl0KZm9yKDt0eXBlb2YgdD09InN0cmluZyI7KXQ9YS50Ult0XQpyZXR1cm4gdH0sCmFpOmZ1
+bmN0aW9uKGEsYil7dmFyIHQscyxyLHEscCxvPWEuZVQsbj1vW2JdCmlmKG49PW51bGwpcmV0dXJuIEgu
+RShhLGIsITEpCmVsc2UgaWYodHlwZW9mIG49PSJudW1iZXIiKXt0PW4Kcz1ILm1aKGEsNSwiIyIpCnI9
+W10KZm9yKHE9MDtxPHQ7KytxKXIucHVzaChzKQpwPUguUTIoYSxiLHIpCm9bYl09cApyZXR1cm4gcH1l
+bHNlIHJldHVybiBufSwKeGI6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gSC5JeChhLnRSLGIpfSwKRkY6ZnVu
+Y3Rpb24oYSxiKXtyZXR1cm4gSC5JeChhLmVULGIpfSwKRTpmdW5jdGlvbihhLGIsYyl7dmFyIHQscz1h
+LmVDLHI9cy5nZXQoYikKaWYociE9bnVsbClyZXR1cm4gcgp0PUgueihhLG51bGwsYixjKQpzLnNldChi
+LHQpCnJldHVybiB0fSwKY0U6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0LHMscj1iLmNoCmlmKHI9PW51bGwp
+cj1iLmNoPW5ldyBNYXAoKQp0PXIuZ2V0KGMpCmlmKHQhPW51bGwpcmV0dXJuIHQKcz1ILnooYSxiLGMs
+ITApCnIuc2V0KGMscykKcmV0dXJuIHN9LAp2NTpmdW5jdGlvbihhLGIsYyl7dmFyIHQscyxyLHEscD1i
+LmN4CmlmKHA9PW51bGwpcD1iLmN4PW5ldyBNYXAoKQp0PWMuY3kKdC50b1N0cmluZwpzPXQKcj1wLmdl
+dChzKQppZihyIT1udWxsKXJldHVybiByCnE9SC5hcChhLGIsYy55PT09MTA/Yy5ROltjXSkKcC5zZXQo
+cyxxKQpyZXR1cm4gcX0sCno6ZnVuY3Rpb24oYSxiLGMsZCl7dmFyIHQ9SC5pKEgubyhhLGIsYyxkKSkK
+aWYodCE9bnVsbClyZXR1cm4gdAp0aHJvdyBILmIoUC5uKCdfVW5pdmVyc2UuX3BhcnNlUmVjaXBlKCIn
+K0guZChjKSsnIiknKSl9LApCRDpmdW5jdGlvbihhLGIpe2IuYT1ILk96CmIuYj1ILkpKCnJldHVybiBi
+fSwKbVo6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0LHMscj1hLmVDLmdldChjKQppZihyIT1udWxsKXJldHVy
+biByCnQ9bmV3IEguSmMobnVsbCxudWxsKQp0Lnk9Ygp0LmN5PWMKcz1ILkJEKGEsdCkKYS5lQy5zZXQo
+YyxzKQpyZXR1cm4gc30sClNPOmZ1bmN0aW9uKGEsYixjKXt2YXIgdCxzLHI9Yi5jeQpyLnRvU3RyaW5n
+CnQ9cisiKiIKcz1hLmVDLmdldCh0KQppZihzIT1udWxsKXJldHVybiBzCnI9SC5aNyhhLGIsdCxjKQph
+LmVDLnNldCh0LHIpCnJldHVybiByfSwKWjc6ZnVuY3Rpb24oYSxiLGMsZCl7dmFyIHQscwppZihkKXt0
+PWIueQppZihILkE4KGIpfHxiPT09dS5LfHxiPT09dS5QfHx0PT09N3x8dD09PTYpcmV0dXJuIGJ9cz1u
+ZXcgSC5KYyhudWxsLG51bGwpCnMueT02CnMuej1iCnMuY3k9YwpyZXR1cm4gSC5CRChhLHMpfSwKQmM6
+ZnVuY3Rpb24oYSxiLGMpe3ZhciB0LHMscj1iLmN5CnIudG9TdHJpbmcKdD1yKyI/IgpzPWEuZUMuZ2V0
+KHQpCmlmKHMhPW51bGwpcmV0dXJuIHMKcj1ILmxsKGEsYix0LGMpCmEuZUMuc2V0KHQscikKcmV0dXJu
+IHJ9LApsbDpmdW5jdGlvbihhLGIsYyxkKXt2YXIgdCxzLHIscQppZihkKXt0PWIueQppZighSC5BOChi
+KSlpZighKGI9PT11LlApKWlmKHQhPT03KXM9dD09PTgmJkgubFIoYi56KQplbHNlIHM9ITAKZWxzZSBz
+PSEwCmVsc2Ugcz0hMAppZihzKXJldHVybiBiCmVsc2UgaWYodD09PTF8fGI9PT11LmF3KXJldHVybiB1
+LlAKZWxzZSBpZih0PT09Nil7cj1iLnoKaWYoci55PT09OCYmSC5sUihyLnopKXJldHVybiByCmVsc2Ug
+cmV0dXJuIEguY3ooYSxiKX19cT1uZXcgSC5KYyhudWxsLG51bGwpCnEueT03CnEuej1iCnEuY3k9Ywpy
+ZXR1cm4gSC5CRChhLHEpfSwKTE46ZnVuY3Rpb24oYSxiLGMpe3ZhciB0LHMscj1iLmN5CnIudG9TdHJp
+bmcKdD1yKyIvIgpzPWEuZUMuZ2V0KHQpCmlmKHMhPW51bGwpcmV0dXJuIHMKcj1ILmVWKGEsYix0LGMp
+CmEuZUMuc2V0KHQscikKcmV0dXJuIHJ9LAplVjpmdW5jdGlvbihhLGIsYyxkKXt2YXIgdCxzCmlmKGQp
+e3Q9Yi55CmlmKEguQTgoYil8fGI9PT11Lkt8fGI9PT11LkspcmV0dXJuIGIKZWxzZSBpZih0PT09MSly
+ZXR1cm4gSC5RMihhLCJiOCIsW2JdKQplbHNlIGlmKGI9PT11LlApcmV0dXJuIHUuYVF9cz1uZXcgSC5K
+YyhudWxsLG51bGwpCnMueT04CnMuej1iCnMuY3k9YwpyZXR1cm4gSC5CRChhLHMpfSwKSGM6ZnVuY3Rp
+b24oYSxiKXt2YXIgdCxzLHI9IiIrYisiXiIscT1hLmVDLmdldChyKQppZihxIT1udWxsKXJldHVybiBx
+CnQ9bmV3IEguSmMobnVsbCxudWxsKQp0Lnk9MTMKdC56PWIKdC5jeT1yCnM9SC5CRChhLHQpCmEuZUMu
+c2V0KHIscykKcmV0dXJuIHN9LApVeDpmdW5jdGlvbihhKXt2YXIgdCxzLHIscSxwPWEubGVuZ3RoCmZv
+cih0PSIiLHM9IiIscj0wO3I8cDsrK3Iscz0iLCIpe3E9YVtyXS5jeQpxLnRvU3RyaW5nCnQrPXMrcX1y
+ZXR1cm4gdH0sClM0OmZ1bmN0aW9uKGEpe3ZhciB0LHMscixxLHAsbz1hLmxlbmd0aApmb3IodD0iIixz
+PSIiLHI9MDtyPG87cis9MixzPSIsIil7cT1hW3JdCnA9YVtyKzFdLmN5CnAudG9TdHJpbmcKdCs9cytx
+KyI6IitwfXJldHVybiB0fSwKUTI6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0LHMscixxPWIKaWYoYy5sZW5n
+dGghPT0wKXErPSI8IitILlV4KGMpKyI+Igp0PWEuZUMuZ2V0KHEpCmlmKHQhPW51bGwpcmV0dXJuIHQK
+cz1uZXcgSC5KYyhudWxsLG51bGwpCnMueT05CnMuej1iCnMuUT1jCmlmKGMubGVuZ3RoPjApcy5jPWNb
+MF0Kcy5jeT1xCnI9SC5CRChhLHMpCmEuZUMuc2V0KHEscikKcmV0dXJuIHJ9LAphcDpmdW5jdGlvbihh
+LGIsYyl7dmFyIHQscyxyLHEscCxvCmlmKGIueT09PTEwKXt0PWIuegpzPWIuUS5jb25jYXQoYyl9ZWxz
+ZXtzPWMKdD1ifXI9dC5jeQpyLnRvU3RyaW5nCnE9cisiOyIrKCI8IitILlV4KHMpKyI+IikKcD1hLmVD
+LmdldChxKQppZihwIT1udWxsKXJldHVybiBwCm89bmV3IEguSmMobnVsbCxudWxsKQpvLnk9MTAKby56
+PXQKby5RPXMKby5jeT1xCnI9SC5CRChhLG8pCmEuZUMuc2V0KHEscikKcmV0dXJuIHJ9LApOZjpmdW5j
+dGlvbihhLGIsYyl7dmFyIHQscyxyLHEscCxvLG4sbSxsLGssaj1iLmN5CmoudG9TdHJpbmcKdD1jLmEK
+cz10Lmxlbmd0aApyPWMuYgpxPXIubGVuZ3RoCnA9Yy5jCm89cC5sZW5ndGgKbj0iKCIrSC5VeCh0KQpp
+ZihxPjApbis9KHM+MD8iLCI6IiIpKyJbIitILlV4KHIpKyJdIgppZihvPjApbis9KHM+MD8iLCI6IiIp
+KyJ7IitILlM0KHApKyJ9IgptPWorKG4rIikiKQpsPWEuZUMuZ2V0KG0pCmlmKGwhPW51bGwpcmV0dXJu
+IGwKaz1uZXcgSC5KYyhudWxsLG51bGwpCmsueT0xMQprLno9YgprLlE9YwprLmN5PW0Kaj1ILkJEKGEs
+aykKYS5lQy5zZXQobSxqKQpyZXR1cm4gan0sCkRTOmZ1bmN0aW9uKGEsYixjLGQpe3ZhciB0LHMscj1i
+LmN5CnIudG9TdHJpbmcKdD1yKyI8IitILlV4KGMpKyI+IgpzPWEuZUMuZ2V0KHQpCmlmKHMhPW51bGwp
+cmV0dXJuIHMKcj1ILmh3KGEsYixjLHQsZCkKYS5lQy5zZXQodCxyKQpyZXR1cm4gcn0sCmh3OmZ1bmN0
+aW9uKGEsYixjLGQsZSl7dmFyIHQscyxyLHEscCxvLG4sbQppZihlKXt0PWMubGVuZ3RoCnM9bmV3IEFy
+cmF5KHQpCmZvcihyPTAscT0wO3E8dDsrK3Epe3A9Y1txXQppZihwLnk9PT0xKXtzW3FdPXA7KytyfX1p
+ZihyPjApe289SC5QTChhLGIscywwKQpuPUguYlooYSxjLHMsMCkKcmV0dXJuIEguRFMoYSxvLG4sYyE9
+PW4pfX1tPW5ldyBILkpjKG51bGwsbnVsbCkKbS55PTEyCm0uej1iCm0uUT1jCm0uY3k9ZApyZXR1cm4g
+SC5CRChhLG0pfSwKbzpmdW5jdGlvbihhLGIsYyxkKXtyZXR1cm57dTphLGU6YixyOmMsczpbXSxwOjAs
+bjpkfX0sCmk6ZnVuY3Rpb24oYSl7dmFyIHQscyxyLHEscCxvLG4sbSxsLGssaixpLGg9YS5yLGc9YS5z
+CmZvcih0PWgubGVuZ3RoLHM9MDtzPHQ7KXtyPWguY2hhckNvZGVBdChzKQppZihyPj00OCYmcjw9NTcp
+cz1ILkFsKHMrMSxyLGgsZykKZWxzZSBpZigoKChyfDMyKT4+PjApLTk3JjY1NTM1KTwyNnx8cj09PTk1
+fHxyPT09MzYpcz1ILlI4KGEscyxoLGcsITEpCmVsc2UgaWYocj09PTQ2KXM9SC5SOChhLHMsaCxnLCEw
+KQplbHNleysrcwpzd2l0Y2gocil7Y2FzZSA0NDpicmVhawpjYXNlIDU4OmJyZWFrCmNhc2UgNTk6Zy5w
+dXNoKEguS1EoYS51LGEuZSxnLnBvcCgpKSkKYnJlYWsKY2FzZSA5NDpnLnB1c2goSC5IYyhhLnUsZy5w
+b3AoKSkpCmJyZWFrCmNhc2UgMzU6Zy5wdXNoKEgubVooYS51LDUsIiMiKSkKYnJlYWsKY2FzZSA2NDpn
+LnB1c2goSC5tWihhLnUsMiwiQCIpKQpicmVhawpjYXNlIDEyNjpnLnB1c2goSC5tWihhLnUsMywifiIp
+KQpicmVhawpjYXNlIDYwOmcucHVzaChhLnApCmEucD1nLmxlbmd0aApicmVhawpjYXNlIDYyOnE9YS51
+CnA9Zy5zcGxpY2UoYS5wKQpILnJUKGEudSxhLmUscCkKYS5wPWcucG9wKCkKbz1nLnBvcCgpCmlmKHR5
+cGVvZiBvPT0ic3RyaW5nIilnLnB1c2goSC5RMihxLG8scCkpCmVsc2V7bj1ILktRKHEsYS5lLG8pCnN3
+aXRjaChuLnkpe2Nhc2UgMTE6Zy5wdXNoKEguRFMocSxuLHAsYS5uKSkKYnJlYWsKZGVmYXVsdDpnLnB1
+c2goSC5hcChxLG4scCkpCmJyZWFrfX1icmVhawpjYXNlIDM4OkguSTMoYSxnKQpicmVhawpjYXNlIDQy
+Om09YS51CmcucHVzaChILlNPKG0sSC5LUShtLGEuZSxnLnBvcCgpKSxhLm4pKQpicmVhawpjYXNlIDYz
+Om09YS51CmcucHVzaChILkJjKG0sSC5LUShtLGEuZSxnLnBvcCgpKSxhLm4pKQpicmVhawpjYXNlIDQ3
+Om09YS51CmcucHVzaChILkxOKG0sSC5LUShtLGEuZSxnLnBvcCgpKSxhLm4pKQpicmVhawpjYXNlIDQw
+OmcucHVzaChhLnApCmEucD1nLmxlbmd0aApicmVhawpjYXNlIDQxOnE9YS51Cmw9bmV3IEguRVQoKQpr
+PXEuc0VBCmo9cS5zRUEKbz1nLnBvcCgpCmlmKHR5cGVvZiBvPT0ibnVtYmVyIilzd2l0Y2gobyl7Y2Fz
+ZS0xOms9Zy5wb3AoKQpicmVhawpjYXNlLTI6aj1nLnBvcCgpCmJyZWFrCmRlZmF1bHQ6Zy5wdXNoKG8p
+CmJyZWFrfWVsc2UgZy5wdXNoKG8pCnA9Zy5zcGxpY2UoYS5wKQpILnJUKGEudSxhLmUscCkKYS5wPWcu
+cG9wKCkKbC5hPXAKbC5iPWsKbC5jPWoKZy5wdXNoKEguTmYocSxILktRKHEsYS5lLGcucG9wKCkpLGwp
+KQpicmVhawpjYXNlIDkxOmcucHVzaChhLnApCmEucD1nLmxlbmd0aApicmVhawpjYXNlIDkzOnA9Zy5z
+cGxpY2UoYS5wKQpILnJUKGEudSxhLmUscCkKYS5wPWcucG9wKCkKZy5wdXNoKHApCmcucHVzaCgtMSkK
+YnJlYWsKY2FzZSAxMjM6Zy5wdXNoKGEucCkKYS5wPWcubGVuZ3RoCmJyZWFrCmNhc2UgMTI1OnA9Zy5z
+cGxpY2UoYS5wKQpILldTKGEudSxhLmUscCkKYS5wPWcucG9wKCkKZy5wdXNoKHApCmcucHVzaCgtMikK
+YnJlYWsKZGVmYXVsdDp0aHJvdyJCYWQgY2hhcmFjdGVyICIrcn19fWk9Zy5wb3AoKQpyZXR1cm4gSC5L
+UShhLnUsYS5lLGkpfSwKQWw6ZnVuY3Rpb24oYSxiLGMsZCl7dmFyIHQscyxyPWItNDgKZm9yKHQ9Yy5s
+ZW5ndGg7YTx0OysrYSl7cz1jLmNoYXJDb2RlQXQoYSkKaWYoIShzPj00OCYmczw9NTcpKWJyZWFrCnI9
+cioxMCsocy00OCl9ZC5wdXNoKHIpCnJldHVybiBhfSwKUjg6ZnVuY3Rpb24oYSxiLGMsZCxlKXt2YXIg
+dCxzLHIscSxwLG8sbj1iKzEKZm9yKHQ9Yy5sZW5ndGg7bjx0Oysrbil7cz1jLmNoYXJDb2RlQXQobikK
+aWYocz09PTQ2KXtpZihlKWJyZWFrCmU9ITB9ZWxzZXtpZighKCgoKHN8MzIpPj4+MCktOTcmNjU1MzUp
+PDI2fHxzPT09OTV8fHM9PT0zNikpcj1zPj00OCYmczw9NTcKZWxzZSByPSEwCmlmKCFyKWJyZWFrfX1x
+PWMuc3Vic3RyaW5nKGIsbikKaWYoZSl7dD1hLnUKcD1hLmUKaWYocC55PT09MTApcD1wLnoKbz1ILlFv
+KHQscC56KVtxXQppZihvPT1udWxsKUgudmgoJ05vICInK3ErJyIgaW4gIicrSC5tRChwKSsnIicpCmQu
+cHVzaChILmNFKHQscCxvKSl9ZWxzZSBkLnB1c2gocSkKcmV0dXJuIG59LApJMzpmdW5jdGlvbihhLGIp
+e3ZhciB0PWIucG9wKCkKaWYoMD09PXQpe2IucHVzaChILm1aKGEudSwxLCIwJiIpKQpyZXR1cm59aWYo
+MT09PXQpe2IucHVzaChILm1aKGEudSw0LCIxJiIpKQpyZXR1cm59dGhyb3cgSC5iKFAuaFYoIlVuZXhw
+ZWN0ZWQgZXh0ZW5kZWQgb3BlcmF0aW9uICIrSC5kKHQpKSl9LApLUTpmdW5jdGlvbihhLGIsYyl7aWYo
+dHlwZW9mIGM9PSJzdHJpbmciKXJldHVybiBILlEyKGEsYyxhLnNFQSkKZWxzZSBpZih0eXBlb2YgYz09
+Im51bWJlciIpcmV0dXJuIEguVFYoYSxiLGMpCmVsc2UgcmV0dXJuIGN9LApyVDpmdW5jdGlvbihhLGIs
+Yyl7dmFyIHQscz1jLmxlbmd0aApmb3IodD0wO3Q8czsrK3QpY1t0XT1ILktRKGEsYixjW3RdKX0sCldT
+OmZ1bmN0aW9uKGEsYixjKXt2YXIgdCxzPWMubGVuZ3RoCmZvcih0PTE7dDxzO3QrPTIpY1t0XT1ILktR
+KGEsYixjW3RdKX0sClRWOmZ1bmN0aW9uKGEsYixjKXt2YXIgdCxzLHI9Yi55CmlmKHI9PT0xMCl7aWYo
+Yz09PTApcmV0dXJuIGIuegp0PWIuUQpzPXQubGVuZ3RoCmlmKGM8PXMpcmV0dXJuIHRbYy0xXQpjLT1z
+CmI9Yi56CnI9Yi55fWVsc2UgaWYoYz09PTApcmV0dXJuIGIKaWYociE9PTkpdGhyb3cgSC5iKFAuaFYo
+IkluZGV4ZWQgYmFzZSBtdXN0IGJlIGFuIGludGVyZmFjZSB0eXBlIikpCnQ9Yi5RCmlmKGM8PXQubGVu
+Z3RoKXJldHVybiB0W2MtMV0KdGhyb3cgSC5iKFAuaFYoIkJhZCBpbmRleCAiK2MrIiBmb3IgIitiLloo
+MCkpKX0sCldlOmZ1bmN0aW9uKGEsYixjLGQsZSl7dmFyIHQscyxyLHEscCxvLG4sbSxsLGsKaWYoYj09
+PWQpcmV0dXJuITAKaWYoSC5BOChkKXx8ZD09PXUuSylyZXR1cm4hMAp0PWIueQppZih0PT09NClyZXR1
+cm4hMAppZihILkE4KGIpKXJldHVybiExCmlmKGI9PT11LlApcmV0dXJuITAKcz10PT09MTMKaWYocylp
+ZihILldlKGEsY1tiLnpdLGMsZCxlKSlyZXR1cm4hMApyPWQueQppZih0PT09NilyZXR1cm4gSC5XZShh
+LGIueixjLGQsZSkKaWYocj09PTYpe3E9ZC56CnJldHVybiBILldlKGEsYixjLHEsZSl9aWYodD09PTgp
+e2lmKCFILldlKGEsYi56LGMsZCxlKSlyZXR1cm4hMQpyZXR1cm4gSC5XZShhLEgueFooYSxiKSxjLGQs
+ZSl9aWYodD09PTcpe3E9SC5XZShhLGIueixjLGQsZSkKcmV0dXJuIHF9aWYocj09PTgpe2lmKEguV2Uo
+YSxiLGMsZC56LGUpKXJldHVybiEwCnJldHVybiBILldlKGEsYixjLEgueFooYSxkKSxlKX1pZihyPT09
+Nyl7cT1ILldlKGEsYixjLGQueixlKQpyZXR1cm4gcX1pZihzKXJldHVybiExCnE9dCE9PTExCmlmKCgh
+cXx8dD09PTEyKSYmZD09PXUuWilyZXR1cm4hMAppZihyPT09MTIpe2lmKGI9PT11LmcpcmV0dXJuITAK
+aWYodCE9PTEyKXJldHVybiExCnA9Yi5RCm89ZC5RCm49cC5sZW5ndGgKaWYobiE9PW8ubGVuZ3RoKXJl
+dHVybiExCmM9Yz09bnVsbD9wOnAuY29uY2F0KGMpCmU9ZT09bnVsbD9vOm8uY29uY2F0KGUpCmZvciht
+PTA7bTxuOysrbSl7bD1wW21dCms9b1ttXQppZighSC5XZShhLGwsYyxrLGUpfHwhSC5XZShhLGssZSxs
+LGMpKXJldHVybiExfXJldHVybiBILmJPKGEsYi56LGMsZC56LGUpfWlmKHI9PT0xMSl7aWYoYj09PXUu
+ZylyZXR1cm4hMAppZihxKXJldHVybiExCnJldHVybiBILmJPKGEsYixjLGQsZSl9aWYodD09PTkpe2lm
+KHIhPT05KXJldHVybiExCnJldHVybiBILnBHKGEsYixjLGQsZSl9cmV0dXJuITF9LApiTzpmdW5jdGlv
+bihhMCxhMSxhMixhMyxhNCl7dmFyIHQscyxyLHEscCxvLG4sbSxsLGssaixpLGgsZyxmLGUsZCxjLGIs
+YQppZighSC5XZShhMCxhMS56LGEyLGEzLnosYTQpKXJldHVybiExCnQ9YTEuUQpzPWEzLlEKcj10LmEK
+cT1zLmEKcD1yLmxlbmd0aApvPXEubGVuZ3RoCmlmKHA+bylyZXR1cm4hMQpuPW8tcAptPXQuYgpsPXMu
+YgprPW0ubGVuZ3RoCmo9bC5sZW5ndGgKaWYocCtrPG8railyZXR1cm4hMQpmb3IoaT0wO2k8cDsrK2kp
+e2g9cltpXQppZighSC5XZShhMCxxW2ldLGE0LGgsYTIpKXJldHVybiExfWZvcihpPTA7aTxuOysraSl7
+aD1tW2ldCmlmKCFILldlKGEwLHFbcCtpXSxhNCxoLGEyKSlyZXR1cm4hMX1mb3IoaT0wO2k8ajsrK2kp
+e2g9bVtuK2ldCmlmKCFILldlKGEwLGxbaV0sYTQsaCxhMikpcmV0dXJuITF9Zz10LmMKZj1zLmMKZT1n
+Lmxlbmd0aApkPWYubGVuZ3RoCmZvcihpPTAsYz0wO2M8ZDtjKz0yKXtiPWZbY10KZG97aWYoaT49ZSly
+ZXR1cm4hMQphPWdbaV0KaSs9Mn13aGlsZShhPGIpCmlmKGI8YSlyZXR1cm4hMQpoPWdbaS0xXQppZigh
+SC5XZShhMCxmW2MrMV0sYTQsaCxhMikpcmV0dXJuITF9cmV0dXJuITB9LApwRzpmdW5jdGlvbihhLGIs
+YyxkLGUpe3ZhciB0LHMscixxLHAsbyxuLG0sbD1iLnosaz1kLnoKaWYobD09PWspe3Q9Yi5RCnM9ZC5R
+CnI9dC5sZW5ndGgKZm9yKHE9MDtxPHI7KytxKXtwPXRbcV0Kbz1zW3FdCmlmKCFILldlKGEscCxjLG8s
+ZSkpcmV0dXJuITF9cmV0dXJuITB9aWYoZD09PXUuSylyZXR1cm4hMApuPUguUW8oYSxsKQppZihuPT1u
+dWxsKXJldHVybiExCm09bltrXQppZihtPT1udWxsKXJldHVybiExCnI9bS5sZW5ndGgKcz1kLlEKZm9y
+KHE9MDtxPHI7KytxKWlmKCFILldlKGEsSC5jRShhLGIsbVtxXSksYyxzW3FdLGUpKXJldHVybiExCnJl
+dHVybiEwfSwKbFI6ZnVuY3Rpb24oYSl7dmFyIHQscz1hLnkKaWYoIShhPT09dS5QKSlpZighSC5BOChh
+KSlpZihzIT09NylpZighKHM9PT02JiZILmxSKGEueikpKXQ9cz09PTgmJkgubFIoYS56KQplbHNlIHQ9
+ITAKZWxzZSB0PSEwCmVsc2UgdD0hMAplbHNlIHQ9ITAKcmV0dXJuIHR9LApjYzpmdW5jdGlvbihhKXty
+ZXR1cm4gSC5BOChhKXx8YT09PXUuS30sCkE4OmZ1bmN0aW9uKGEpe3ZhciB0LHM9YS55CmlmKHMhPT0y
+KWlmKHMhPT0zKWlmKHMhPT00KWlmKHMhPT01KXt0PXUuSwp0PWE9PT10fHxhPT09dH1lbHNlIHQ9ITAK
+ZWxzZSB0PSEwCmVsc2UgdD0hMAplbHNlIHQ9ITAKcmV0dXJuIHR9LApJeDpmdW5jdGlvbihhLGIpe3Zh
+ciB0LHMscj1PYmplY3Qua2V5cyhiKSxxPXIubGVuZ3RoCmZvcih0PTA7dDxxOysrdCl7cz1yW3RdCmFb
+c109YltzXX19LApKYzpmdW5jdGlvbiBKYyhhLGIpe3ZhciBfPXRoaXMKXy5hPWEKXy5iPWIKXy54PV8u
+cj1fLmM9bnVsbApfLnk9MApfLmN5PV8uY3g9Xy5jaD1fLlE9Xy56PW51bGx9LApFVDpmdW5jdGlvbiBF
+VCgpe3RoaXMuYz10aGlzLmI9dGhpcy5hPW51bGx9LAp1OTpmdW5jdGlvbiB1OSgpe30sCng6ZnVuY3Rp
+b24geChhKXt0aGlzLmE9YX0sClI5OmZ1bmN0aW9uKGEpe3JldHVybiB1LmQuYihhKXx8dS5CLmIoYSl8
+fHUuZHouYihhKXx8dS5JLmIoYSl8fHUuQS5iKGEpfHx1Lmc0LmIoYSl8fHUuZzIuYihhKX0sCkpnOmZ1
+bmN0aW9uKGEpe3JldHVybiB2Lm1hbmdsZWRHbG9iYWxOYW1lc1thXX19LEo9ewpRdTpmdW5jdGlvbihh
+LGIsYyxkKXtyZXR1cm57aTphLHA6YixlOmMseDpkfX0sCmtzOmZ1bmN0aW9uKGEpe3ZhciB0LHMscixx
+LHA9YVt2LmRpc3BhdGNoUHJvcGVydHlOYW1lXQppZihwPT1udWxsKWlmKCQuSz09bnVsbCl7SC5NKCkK
+cD1hW3YuZGlzcGF0Y2hQcm9wZXJ0eU5hbWVdfWlmKHAhPW51bGwpe3Q9cC5wCmlmKCExPT09dClyZXR1
+cm4gcC5pCmlmKCEwPT09dClyZXR1cm4gYQpzPU9iamVjdC5nZXRQcm90b3R5cGVPZihhKQppZih0PT09
+cylyZXR1cm4gcC5pCmlmKHAuZT09PXMpdGhyb3cgSC5iKFAubigiUmV0dXJuIGludGVyY2VwdG9yIGZv
+ciAiK0guZCh0KGEscCkpKSl9cj1hLmNvbnN0cnVjdG9yCnE9cj09bnVsbD9udWxsOnJbJC5BKCldCmlm
+KHEhPW51bGwpcmV0dXJuIHEKcT1ILkcoYSkKaWYocSE9bnVsbClyZXR1cm4gcQppZih0eXBlb2YgYT09
+ImZ1bmN0aW9uIilyZXR1cm4gQy5ERwp0PU9iamVjdC5nZXRQcm90b3R5cGVPZihhKQppZih0PT1udWxs
+KXJldHVybiBDLlpRCmlmKHQ9PT1PYmplY3QucHJvdG90eXBlKXJldHVybiBDLlpRCmlmKHR5cGVvZiBy
+PT0iZnVuY3Rpb24iKXtPYmplY3QuZGVmaW5lUHJvcGVydHkociwkLkEoKSx7dmFsdWU6Qy52QixlbnVt
+ZXJhYmxlOmZhbHNlLHdyaXRhYmxlOnRydWUsY29uZmlndXJhYmxlOnRydWV9KQpyZXR1cm4gQy52Qn1y
+ZXR1cm4gQy52Qn0sClFpOmZ1bmN0aW9uKGEsYil7aWYoYTwwfHxhPjQyOTQ5NjcyOTUpdGhyb3cgSC5i
+KFAuVEUoYSwwLDQyOTQ5NjcyOTUsImxlbmd0aCIsbnVsbCkpCnJldHVybiBKLnB5KG5ldyBBcnJheShh
+KSxiKX0sCktoOmZ1bmN0aW9uKGEsYil7aWYoYTwwKXRocm93IEguYihQLnhZKCJMZW5ndGggbXVzdCBi
+ZSBhIG5vbi1uZWdhdGl2ZSBpbnRlZ2VyOiAiK2EpKQpyZXR1cm4gSC5WTShuZXcgQXJyYXkoYSksYi5D
+KCJqZDwwPiIpKX0sCnB5OmZ1bmN0aW9uKGEsYil7cmV0dXJuIEouRXAoSC5WTShhLGIuQygiamQ8MD4i
+KSksYil9LApFcDpmdW5jdGlvbihhLGIpe2EuZml4ZWQkbGVuZ3RoPUFycmF5CnJldHVybiBhfSwKdW46
+ZnVuY3Rpb24oYSl7YS5maXhlZCRsZW5ndGg9QXJyYXkKYS5pbW11dGFibGUkbGlzdD1BcnJheQpyZXR1
+cm4gYX0sCkdhOmZ1bmN0aW9uKGEpe2lmKGE8MjU2KXN3aXRjaChhKXtjYXNlIDk6Y2FzZSAxMDpjYXNl
+IDExOmNhc2UgMTI6Y2FzZSAxMzpjYXNlIDMyOmNhc2UgMTMzOmNhc2UgMTYwOnJldHVybiEwCmRlZmF1
+bHQ6cmV0dXJuITF9c3dpdGNoKGEpe2Nhc2UgNTc2MDpjYXNlIDgxOTI6Y2FzZSA4MTkzOmNhc2UgODE5
+NDpjYXNlIDgxOTU6Y2FzZSA4MTk2OmNhc2UgODE5NzpjYXNlIDgxOTg6Y2FzZSA4MTk5OmNhc2UgODIw
+MDpjYXNlIDgyMDE6Y2FzZSA4MjAyOmNhc2UgODIzMjpjYXNlIDgyMzM6Y2FzZSA4MjM5OmNhc2UgODI4
+NzpjYXNlIDEyMjg4OmNhc2UgNjUyNzk6cmV0dXJuITAKZGVmYXVsdDpyZXR1cm4hMX19LAptbTpmdW5j
+dGlvbihhLGIpe3ZhciB0LHMKZm9yKHQ9YS5sZW5ndGg7Yjx0Oyl7cz1DLnhCLlcoYSxiKQppZihzIT09
+MzImJnMhPT0xMyYmIUouR2EocykpYnJlYWs7KytifXJldHVybiBifSwKYzE6ZnVuY3Rpb24oYSxiKXt2
+YXIgdCxzCmZvcig7Yj4wO2I9dCl7dD1iLTEKcz1DLnhCLm0oYSx0KQppZihzIT09MzImJnMhPT0xMyYm
+IUouR2EocykpYnJlYWt9cmV0dXJuIGJ9LApSRTpmdW5jdGlvbihhKXtpZihhPT1udWxsKXJldHVybiBh
+CmlmKHR5cGVvZiBhIT0ib2JqZWN0Iil7aWYodHlwZW9mIGE9PSJmdW5jdGlvbiIpcmV0dXJuIEouYzUu
+cHJvdG90eXBlCnJldHVybiBhfWlmKGEgaW5zdGFuY2VvZiBQLk1oKXJldHVybiBhCnJldHVybiBKLmtz
+KGEpfSwKVEo6ZnVuY3Rpb24oYSl7aWYodHlwZW9mIGE9PSJudW1iZXIiKXJldHVybiBKLnFJLnByb3Rv
+dHlwZQppZih0eXBlb2YgYT09InN0cmluZyIpcmV0dXJuIEouRHIucHJvdG90eXBlCmlmKGE9PW51bGwp
+cmV0dXJuIGEKaWYoYS5jb25zdHJ1Y3Rvcj09QXJyYXkpcmV0dXJuIEouamQucHJvdG90eXBlCmlmKHR5
+cGVvZiBhIT0ib2JqZWN0Iil7aWYodHlwZW9mIGE9PSJmdW5jdGlvbiIpcmV0dXJuIEouYzUucHJvdG90
+eXBlCnJldHVybiBhfWlmKGEgaW5zdGFuY2VvZiBQLk1oKXJldHVybiBhCnJldHVybiBKLmtzKGEpfSwK
+VTY6ZnVuY3Rpb24oYSl7aWYodHlwZW9mIGE9PSJzdHJpbmciKXJldHVybiBKLkRyLnByb3RvdHlwZQpp
+ZihhPT1udWxsKXJldHVybiBhCmlmKGEuY29uc3RydWN0b3I9PUFycmF5KXJldHVybiBKLmpkLnByb3Rv
+dHlwZQppZih0eXBlb2YgYSE9Im9iamVjdCIpe2lmKHR5cGVvZiBhPT0iZnVuY3Rpb24iKXJldHVybiBK
+LmM1LnByb3RvdHlwZQpyZXR1cm4gYX1pZihhIGluc3RhbmNlb2YgUC5NaClyZXR1cm4gYQpyZXR1cm4g
+Si5rcyhhKX0sCmlhOmZ1bmN0aW9uKGEpe2lmKHR5cGVvZiBhPT0ibnVtYmVyIil7aWYoTWF0aC5mbG9v
+cihhKT09YSlyZXR1cm4gSi51ci5wcm90b3R5cGUKcmV0dXJuIEouVkEucHJvdG90eXBlfWlmKHR5cGVv
+ZiBhPT0ic3RyaW5nIilyZXR1cm4gSi5Eci5wcm90b3R5cGUKaWYoYT09bnVsbClyZXR1cm4gSi5ZRS5w
+cm90b3R5cGUKaWYodHlwZW9mIGE9PSJib29sZWFuIilyZXR1cm4gSi55RS5wcm90b3R5cGUKaWYoYS5j
+b25zdHJ1Y3Rvcj09QXJyYXkpcmV0dXJuIEouamQucHJvdG90eXBlCmlmKHR5cGVvZiBhIT0ib2JqZWN0
+Iil7aWYodHlwZW9mIGE9PSJmdW5jdGlvbiIpcmV0dXJuIEouYzUucHJvdG90eXBlCnJldHVybiBhfWlm
+KGEgaW5zdGFuY2VvZiBQLk1oKXJldHVybiBhCnJldHVybiBKLmtzKGEpfSwKclk6ZnVuY3Rpb24oYSl7
+aWYodHlwZW9mIGE9PSJzdHJpbmciKXJldHVybiBKLkRyLnByb3RvdHlwZQppZihhPT1udWxsKXJldHVy
+biBhCmlmKCEoYSBpbnN0YW5jZW9mIFAuTWgpKXJldHVybiBKLmtkLnByb3RvdHlwZQpyZXR1cm4gYX0s
+CncxOmZ1bmN0aW9uKGEpe2lmKGE9PW51bGwpcmV0dXJuIGEKaWYoYS5jb25zdHJ1Y3Rvcj09QXJyYXkp
+cmV0dXJuIEouamQucHJvdG90eXBlCmlmKHR5cGVvZiBhIT0ib2JqZWN0Iil7aWYodHlwZW9mIGE9PSJm
+dW5jdGlvbiIpcmV0dXJuIEouYzUucHJvdG90eXBlCnJldHVybiBhfWlmKGEgaW5zdGFuY2VvZiBQLk1o
+KXJldHVybiBhCnJldHVybiBKLmtzKGEpfSwKQWM6ZnVuY3Rpb24oYSl7cmV0dXJuIEouaWEoYSkuWihh
+KX0sCkNNOmZ1bmN0aW9uKGEsYixjLGQpe3JldHVybiBKLlJFKGEpLmR1KGEsYixjLGQpfSwKRkw6ZnVu
+Y3Rpb24oYSxiKXtyZXR1cm4gSi5yWShhKS5kZChhLGIpfSwKR0E6ZnVuY3Rpb24oYSxiKXtyZXR1cm4g
+Si53MShhKS5FKGEsYil9LApHcjpmdW5jdGlvbihhKXtyZXR1cm4gSi5SRShhKS5nbVcoYSl9LApIOmZ1
+bmN0aW9uKGEpe3JldHVybiBKLlU2KGEpLmdBKGEpfSwKSVQ6ZnVuY3Rpb24oYSl7cmV0dXJuIEoudzEo
+YSkuZ2t6KGEpfSwKSnk6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gSi5pYShhKS5lNyhhLGIpfSwKS1Y6ZnVu
+Y3Rpb24oYSxiKXtyZXR1cm4gSi5yWShhKS5HKGEsYil9LApMdDpmdW5jdGlvbihhKXtyZXR1cm4gSi5S
+RShhKS53ZyhhKX0sCk0xOmZ1bmN0aW9uKGEsYixjKXtyZXR1cm4gSi53MShhKS5FMihhLGIsYyl9LApR
+ejpmdW5jdGlvbihhLGIpe3JldHVybiBKLnJZKGEpLlcoYSxiKX0sClJNOmZ1bmN0aW9uKGEsYil7aWYo
+YT09bnVsbClyZXR1cm4gYj09bnVsbAppZih0eXBlb2YgYSE9Im9iamVjdCIpcmV0dXJuIGIhPW51bGwm
+JmE9PT1iCnJldHVybiBKLmlhKGEpLkROKGEsYil9LApUMDpmdW5jdGlvbihhKXtyZXR1cm4gSi5yWShh
+KS5iUyhhKX0sCmE2OmZ1bmN0aW9uKGEsYil7cmV0dXJuIEouclkoYSkubShhLGIpfSwKYlQ6ZnVuY3Rp
+b24oYSl7cmV0dXJuIEouUkUoYSkuRDQoYSl9LApjSDpmdW5jdGlvbihhKXtyZXR1cm4gSi5yWShhKS5o
+YyhhKX0sCmRSOmZ1bmN0aW9uKGEpe3JldHVybiBKLlJFKGEpLmdQKGEpfSwKZFo6ZnVuY3Rpb24oYSxi
+LGMsZCl7cmV0dXJuIEouUkUoYSkuT24oYSxiLGMsZCl9LApkZzpmdW5jdGlvbihhLGIsYyxkKXtyZXR1
+cm4gSi5yWShhKS5pNyhhLGIsYyxkKX0sCmRoOmZ1bmN0aW9uKGEpe3JldHVybiBKLlJFKGEpLkZGKGEp
+fSwKaGY6ZnVuY3Rpb24oYSl7cmV0dXJuIEouaWEoYSkuZ2lPKGEpfSwKaWc6ZnVuY3Rpb24oYSl7cmV0
+dXJuIEouUkUoYSkuZ1FnKGEpfSwKbDU6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gSi5SRShhKS5zaGYoYSxi
+KX0sCmxkOmZ1bmN0aW9uKGEsYixjKXtyZXR1cm4gSi5yWShhKS5OaihhLGIsYyl9LAptOmZ1bmN0aW9u
+KGEsYil7aWYodHlwZW9mIGE9PSJudW1iZXIiJiZ0eXBlb2YgYj09Im51bWJlciIpcmV0dXJuIGErYgpy
+ZXR1cm4gSi5USihhKS5oKGEsYil9LApwNDpmdW5jdGlvbihhLGIpe3JldHVybiBKLnJZKGEpLlRjKGEs
+Yil9LApxMDpmdW5jdGlvbihhLGIsYyl7cmV0dXJuIEouclkoYSkuUWkoYSxiLGMpfSwKcUY6ZnVuY3Rp
+b24oYSl7cmV0dXJuIEouUkUoYSkuZ1ZsKGEpfSwKdEg6ZnVuY3Rpb24oYSxiLGMpe3JldHVybiBKLlJF
+KGEpLnBrKGEsYixjKX0sCng5OmZ1bmN0aW9uKGEsYil7aWYodHlwZW9mIGI9PT0ibnVtYmVyIilpZihh
+LmNvbnN0cnVjdG9yPT1BcnJheXx8dHlwZW9mIGE9PSJzdHJpbmcifHxILndWKGEsYVt2LmRpc3BhdGNo
+UHJvcGVydHlOYW1lXSkpaWYoYj4+PjA9PT1iJiZiPGEubGVuZ3RoKXJldHVybiBhW2JdCnJldHVybiBK
+LlU2KGEpLnEoYSxiKX0sCnpsOmZ1bmN0aW9uKGEsYil7cmV0dXJuIEouVTYoYSkudGcoYSxiKX0sCnZC
+OmZ1bmN0aW9uIHZCKCl7fSwKeUU6ZnVuY3Rpb24geUUoKXt9LApZRTpmdW5jdGlvbiBZRSgpe30sCk1G
+OmZ1bmN0aW9uIE1GKCl7fSwKaUM6ZnVuY3Rpb24gaUMoKXt9LAprZDpmdW5jdGlvbiBrZCgpe30sCmM1
+OmZ1bmN0aW9uIGM1KCl7fSwKamQ6ZnVuY3Rpb24gamQoYSl7dGhpcy4kdGk9YX0sClBvOmZ1bmN0aW9u
+IFBvKGEpe3RoaXMuJHRpPWF9LAptMTpmdW5jdGlvbiBtMShhLGIsYyl7dmFyIF89dGhpcwpfLmE9YQpf
+LmI9YgpfLmM9MApfLmQ9bnVsbApfLiR0aT1jfSwKcUk6ZnVuY3Rpb24gcUkoKXt9LAp1cjpmdW5jdGlv
+biB1cigpe30sClZBOmZ1bmN0aW9uIFZBKCl7fSwKRHI6ZnVuY3Rpb24gRHIoKXt9fSxQPXsKT2o6ZnVu
+Y3Rpb24oKXt2YXIgdCxzLHI9e30KaWYoc2VsZi5zY2hlZHVsZUltbWVkaWF0ZSE9bnVsbClyZXR1cm4g
+UC5FWCgpCmlmKHNlbGYuTXV0YXRpb25PYnNlcnZlciE9bnVsbCYmc2VsZi5kb2N1bWVudCE9bnVsbCl7
+dD1zZWxmLmRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoImRpdiIpCnM9c2VsZi5kb2N1bWVudC5jcmVhdGVF
+bGVtZW50KCJzcGFuIikKci5hPW51bGwKbmV3IHNlbGYuTXV0YXRpb25PYnNlcnZlcihILnRSKG5ldyBQ
+LnRoKHIpLDEpKS5vYnNlcnZlKHQse2NoaWxkTGlzdDp0cnVlfSkKcmV0dXJuIG5ldyBQLmhhKHIsdCxz
+KX1lbHNlIGlmKHNlbGYuc2V0SW1tZWRpYXRlIT1udWxsKXJldHVybiBQLnl0KCkKcmV0dXJuIFAucVco
+KX0sClpWOmZ1bmN0aW9uKGEpe3NlbGYuc2NoZWR1bGVJbW1lZGlhdGUoSC50UihuZXcgUC5Wcyh1Lk0u
+YShhKSksMCkpfSwKb0E6ZnVuY3Rpb24oYSl7c2VsZi5zZXRJbW1lZGlhdGUoSC50UihuZXcgUC5GdCh1
+Lk0uYShhKSksMCkpfSwKQno6ZnVuY3Rpb24oYSl7dS5NLmEoYSkKUC5RTigwLGEpfSwKUU46ZnVuY3Rp
+b24oYSxiKXt2YXIgdD1uZXcgUC5XMygpCnQuQ1koYSxiKQpyZXR1cm4gdH0sCkZYOmZ1bmN0aW9uKGEp
+e3JldHVybiBuZXcgUC5paChuZXcgUC52cygkLlgzLGEuQygidnM8MD4iKSksYS5DKCJpaDwwPiIpKX0s
+CkRJOmZ1bmN0aW9uKGEsYil7YS4kMigwLG51bGwpCmIuYj0hMApyZXR1cm4gYi5hfSwKalE6ZnVuY3Rp
+b24oYSxiKXtQLkplKGEsYil9LAp5QzpmdW5jdGlvbihhLGIpe2IuYU0oMCxhKX0sCmYzOmZ1bmN0aW9u
+KGEsYil7Yi53MChILlJ1KGEpLEgudHMoYSkpfSwKSmU6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzLHI9bmV3
+IFAuV00oYikscT1uZXcgUC5TWChiKQppZihhIGluc3RhbmNlb2YgUC52cylhLlFkKHIscSx1LnopCmVs
+c2V7dD11LnoKaWYodS5jLmIoYSkpYS5TcShyLHEsdCkKZWxzZXtzPW5ldyBQLnZzKCQuWDMsdS5fKQpz
+LmE9NApzLmM9YQpzLlFkKHIscSx0KX19fSwKbHo6ZnVuY3Rpb24oYSl7dmFyIHQ9ZnVuY3Rpb24oYixj
+KXtyZXR1cm4gZnVuY3Rpb24oZCxlKXt3aGlsZSh0cnVlKXRyeXtiKGQsZSkKYnJlYWt9Y2F0Y2gocyl7
+ZT1zCmQ9Y319fShhLDEpCnJldHVybiAkLlgzLkxqKG5ldyBQLkdzKHQpLHUuUCx1LnEsdS56KX0sCkdR
+OmZ1bmN0aW9uKGEpe3JldHVybiBuZXcgUC5GeShhLDEpfSwKVGg6ZnVuY3Rpb24oKXtyZXR1cm4gQy53
+UX0sClltOmZ1bmN0aW9uKGEpe3JldHVybiBuZXcgUC5GeShhLDMpfSwKbDA6ZnVuY3Rpb24oYSxiKXty
+ZXR1cm4gbmV3IFAucTQoYSxiLkMoInE0PDA+IikpfSwKazM6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzLHIK
+Yi5hPTEKdHJ5e2EuU3EobmV3IFAucFYoYiksbmV3IFAuVTcoYiksdS5QKX1jYXRjaChyKXt0PUguUnUo
+cikKcz1ILnRzKHIpClAucmIobmV3IFAudnIoYix0LHMpKX19LApBOTpmdW5jdGlvbihhLGIpe3ZhciB0
+LHMscgpmb3IodD11Ll87cz1hLmEscz09PTI7KWE9dC5hKGEuYykKaWYocz49NCl7cj1iLmFoKCkKYi5h
+PWEuYQpiLmM9YS5jClAuSFooYixyKX1lbHNle3I9dS54LmEoYi5jKQpiLmE9MgpiLmM9YQphLmpRKHIp
+fX0sCkhaOmZ1bmN0aW9uKGEsYTApe3ZhciB0LHMscixxLHAsbyxuLG0sbCxrLGosaSxoLGcsZixlLGQ9
+bnVsbCxjPXt9LGI9Yy5hPWEKZm9yKHQ9dS5uLHM9dS54LHI9dS5jOyEwOyl7cT17fQpwPWIuYT09PTgK
+aWYoYTA9PW51bGwpe2lmKHApe289dC5hKGIuYykKUC5MMihkLGQsYi5iLG8uYSxvLmIpfXJldHVybn1x
+LmE9YTAKbj1hMC5hCmZvcihiPWEwO24hPW51bGw7Yj1uLG49bSl7Yi5hPW51bGwKUC5IWihjLmEsYikK
+cS5hPW4KbT1uLmF9bD1jLmEKaz1sLmMKcS5iPXAKcS5jPWsKaj0hcAppZihqKXtpPWIuYwppPShpJjEp
+IT09MHx8KGkmMTUpPT09OH1lbHNlIGk9ITAKaWYoaSl7aD1iLmIuYgppZihwKXtpPWwuYj09PWgKaT0h
+KGl8fGkpfWVsc2UgaT0hMQppZihpKXt0LmEoaykKUC5MMihkLGQsbC5iLGsuYSxrLmIpCnJldHVybn1n
+PSQuWDMKaWYoZyE9PWgpJC5YMz1oCmVsc2UgZz1kCmI9Yi5jCmlmKChiJjE1KT09PTgpbmV3IFAuUlQo
+cSxjLHApLiQwKCkKZWxzZSBpZihqKXtpZigoYiYxKSE9PTApbmV3IFAucnEocSxrKS4kMCgpfWVsc2Ug
+aWYoKGImMikhPT0wKW5ldyBQLlJXKGMscSkuJDAoKQppZihnIT1udWxsKSQuWDM9ZwpiPXEuYwppZihy
+LmIoYikpe2Y9cS5hLmIKaWYoYi5hPj00KXtlPXMuYShmLmMpCmYuYz1udWxsCmEwPWYuTjgoZSkKZi5h
+PWIuYQpmLmM9Yi5jCmMuYT1iCmNvbnRpbnVlfWVsc2UgUC5BOShiLGYpCnJldHVybn19Zj1xLmEuYgpl
+PXMuYShmLmMpCmYuYz1udWxsCmEwPWYuTjgoZSkKYj1xLmIKbD1xLmMKaWYoIWIpe2YuJHRpLmMuYShs
+KQpmLmE9NApmLmM9bH1lbHNle3QuYShsKQpmLmE9OApmLmM9bH1jLmE9ZgpiPWZ9fSwKVkg6ZnVuY3Rp
+b24oYSxiKXt2YXIgdAppZih1LmFnLmIoYSkpcmV0dXJuIGIuTGooYSx1LnosdS5LLHUubCkKdD11LmJJ
+CmlmKHQuYihhKSlyZXR1cm4gdC5hKGEpCnRocm93IEguYihQLkwzKGEsIm9uRXJyb3IiLCJFcnJvciBo
+YW5kbGVyIG11c3QgYWNjZXB0IG9uZSBPYmplY3Qgb3Igb25lIE9iamVjdCBhbmQgYSBTdGFja1RyYWNl
+IGFzIGFyZ3VtZW50cywgYW5kIHJldHVybiBhIGEgdmFsaWQgcmVzdWx0IikpfSwKcHU6ZnVuY3Rpb24o
+KXt2YXIgdCxzCmZvcih0PSQuUzY7dCE9bnVsbDt0PSQuUzYpeyQubWc9bnVsbApzPXQuYgokLlM2PXMK
+aWYocz09bnVsbCkkLms4PW51bGwKdC5hLiQwKCl9fSwKZU46ZnVuY3Rpb24oKXskLlVEPSEwCnRyeXtQ
+LnB1KCl9ZmluYWxseXskLm1nPW51bGwKJC5VRD0hMQppZigkLlM2IT1udWxsKSQudXQoKS4kMShQLlY5
+KCkpfX0sCmVXOmZ1bmN0aW9uKGEpe3ZhciB0PW5ldyBQLk9NKGEpLHM9JC5rOAppZihzPT1udWxsKXsk
+LlM2PSQuazg9dAppZighJC5VRCkkLnV0KCkuJDEoUC5WOSgpKX1lbHNlICQuazg9cy5iPXR9LApyUjpm
+dW5jdGlvbihhKXt2YXIgdCxzLHIscT0kLlM2CmlmKHE9PW51bGwpe1AuZVcoYSkKJC5tZz0kLms4CnJl
+dHVybn10PW5ldyBQLk9NKGEpCnM9JC5tZwppZihzPT1udWxsKXt0LmI9cQokLlM2PSQubWc9dH1lbHNl
+e3I9cy5iCnQuYj1yCiQubWc9cy5iPXQKaWYocj09bnVsbCkkLms4PXR9fSwKcmI6ZnVuY3Rpb24oYSl7
+dmFyIHQ9bnVsbCxzPSQuWDMKaWYoQy5OVT09PXMpe1AuVGsodCx0LEMuTlUsYSkKcmV0dXJufVAuVGso
+dCx0LHMsdS5NLmEocy5HWShhKSkpfSwKUXc6ZnVuY3Rpb24oYSxiKXtQLlVJKGEsInN0cmVhbSIsYi5D
+KCJxaDwwPiIpKQpyZXR1cm4gbmV3IFAueEkoYi5DKCJ4STwwPiIpKX0sClRsOmZ1bmN0aW9uKGEsYil7
+dmFyIHQ9Yj09bnVsbD9QLnYwKGEpOmIKUC5VSShhLCJlcnJvciIsdS5LKQpyZXR1cm4gbmV3IFAuT0go
+YSx0KX0sCnYwOmZ1bmN0aW9uKGEpe3ZhciB0CmlmKHUuVy5iKGEpKXt0PWEuZ0lJKCkKaWYodCE9bnVs
+bClyZXR1cm4gdH1yZXR1cm4gQy5wZH0sCkwyOmZ1bmN0aW9uKGEsYixjLGQsZSl7UC5yUihuZXcgUC5w
+SyhkLGUpKX0sClQ4OmZ1bmN0aW9uKGEsYixjLGQsZSl7dmFyIHQscz0kLlgzCmlmKHM9PT1jKXJldHVy
+biBkLiQwKCkKJC5YMz1jCnQ9cwp0cnl7cz1kLiQwKCkKcmV0dXJuIHN9ZmluYWxseXskLlgzPXR9fSwK
+eXY6ZnVuY3Rpb24oYSxiLGMsZCxlLGYsZyl7dmFyIHQscz0kLlgzCmlmKHM9PT1jKXJldHVybiBkLiQx
+KGUpCiQuWDM9Ywp0PXMKdHJ5e3M9ZC4kMShlKQpyZXR1cm4gc31maW5hbGx5eyQuWDM9dH19LApReDpm
+dW5jdGlvbihhLGIsYyxkLGUsZixnLGgsaSl7dmFyIHQscz0kLlgzCmlmKHM9PT1jKXJldHVybiBkLiQy
+KGUsZikKJC5YMz1jCnQ9cwp0cnl7cz1kLiQyKGUsZikKcmV0dXJuIHN9ZmluYWxseXskLlgzPXR9fSwK
+VGs6ZnVuY3Rpb24oYSxiLGMsZCl7dmFyIHQKdS5NLmEoZCkKdD1DLk5VIT09YwppZih0KWQ9ISghdHx8
+ITEpP2MuR1koZCk6Yy5SVChkLHUuSCkKUC5lVyhkKX0sCnRoOmZ1bmN0aW9uIHRoKGEpe3RoaXMuYT1h
+fSwKaGE6ZnVuY3Rpb24gaGEoYSxiLGMpe3RoaXMuYT1hCnRoaXMuYj1iCnRoaXMuYz1jfSwKVnM6ZnVu
+Y3Rpb24gVnMoYSl7dGhpcy5hPWF9LApGdDpmdW5jdGlvbiBGdChhKXt0aGlzLmE9YX0sClczOmZ1bmN0
+aW9uIFczKCl7fSwKeUg6ZnVuY3Rpb24geUgoYSxiKXt0aGlzLmE9YQp0aGlzLmI9Yn0sCmloOmZ1bmN0
+aW9uIGloKGEsYil7dGhpcy5hPWEKdGhpcy5iPSExCnRoaXMuJHRpPWJ9LApXTTpmdW5jdGlvbiBXTShh
+KXt0aGlzLmE9YX0sClNYOmZ1bmN0aW9uIFNYKGEpe3RoaXMuYT1hfSwKR3M6ZnVuY3Rpb24gR3MoYSl7
+dGhpcy5hPWF9LApGeTpmdW5jdGlvbiBGeShhLGIpe3RoaXMuYT1hCnRoaXMuYj1ifSwKR1Y6ZnVuY3Rp
+b24gR1YoYSxiKXt2YXIgXz10aGlzCl8uYT1hCl8uZD1fLmM9Xy5iPW51bGwKXy4kdGk9Yn0sCnE0OmZ1
+bmN0aW9uIHE0KGEsYil7dGhpcy5hPWEKdGhpcy4kdGk9Yn0sCmI4OmZ1bmN0aW9uIGI4KCl7fSwKUGY6
+ZnVuY3Rpb24gUGYoKXt9LApaZjpmdW5jdGlvbiBaZihhLGIpe3RoaXMuYT1hCnRoaXMuJHRpPWJ9LApG
+ZTpmdW5jdGlvbiBGZShhLGIsYyxkLGUpe3ZhciBfPXRoaXMKXy5hPW51bGwKXy5iPWEKXy5jPWIKXy5k
+PWMKXy5lPWQKXy4kdGk9ZX0sCnZzOmZ1bmN0aW9uIHZzKGEsYil7dmFyIF89dGhpcwpfLmE9MApfLmI9
+YQpfLmM9bnVsbApfLiR0aT1ifSwKZGE6ZnVuY3Rpb24gZGEoYSxiKXt0aGlzLmE9YQp0aGlzLmI9Yn0s
+Cm9ROmZ1bmN0aW9uIG9RKGEsYil7dGhpcy5hPWEKdGhpcy5iPWJ9LApwVjpmdW5jdGlvbiBwVihhKXt0
+aGlzLmE9YX0sClU3OmZ1bmN0aW9uIFU3KGEpe3RoaXMuYT1hfSwKdnI6ZnVuY3Rpb24gdnIoYSxiLGMp
+e3RoaXMuYT1hCnRoaXMuYj1iCnRoaXMuYz1jfSwKckg6ZnVuY3Rpb24gckgoYSxiKXt0aGlzLmE9YQp0
+aGlzLmI9Yn0sCktGOmZ1bmN0aW9uIEtGKGEsYil7dGhpcy5hPWEKdGhpcy5iPWJ9LApaTDpmdW5jdGlv
+biBaTChhLGIsYyl7dGhpcy5hPWEKdGhpcy5iPWIKdGhpcy5jPWN9LApSVDpmdW5jdGlvbiBSVChhLGIs
+Yyl7dGhpcy5hPWEKdGhpcy5iPWIKdGhpcy5jPWN9LApqWjpmdW5jdGlvbiBqWihhKXt0aGlzLmE9YX0s
+CnJxOmZ1bmN0aW9uIHJxKGEsYil7dGhpcy5hPWEKdGhpcy5iPWJ9LApSVzpmdW5jdGlvbiBSVyhhLGIp
+e3RoaXMuYT1hCnRoaXMuYj1ifSwKT006ZnVuY3Rpb24gT00oYSl7dGhpcy5hPWEKdGhpcy5iPW51bGx9
+LApxaDpmdW5jdGlvbiBxaCgpe30sCkI1OmZ1bmN0aW9uIEI1KGEsYil7dGhpcy5hPWEKdGhpcy5iPWJ9
+LAp1TzpmdW5jdGlvbiB1TyhhLGIpe3RoaXMuYT1hCnRoaXMuYj1ifSwKTU86ZnVuY3Rpb24gTU8oKXt9
+LAprVDpmdW5jdGlvbiBrVCgpe30sCnhJOmZ1bmN0aW9uIHhJKGEpe3RoaXMuJHRpPWF9LApPSDpmdW5j
+dGlvbiBPSChhLGIpe3RoaXMuYT1hCnRoaXMuYj1ifSwKbTA6ZnVuY3Rpb24gbTAoKXt9LApwSzpmdW5j
+dGlvbiBwSyhhLGIpe3RoaXMuYT1hCnRoaXMuYj1ifSwKSmk6ZnVuY3Rpb24gSmkoKXt9LApoajpmdW5j
+dGlvbiBoaihhLGIsYyl7dGhpcy5hPWEKdGhpcy5iPWIKdGhpcy5jPWN9LApWcDpmdW5jdGlvbiBWcChh
+LGIpe3RoaXMuYT1hCnRoaXMuYj1ifSwKT1I6ZnVuY3Rpb24gT1IoYSxiLGMpe3RoaXMuYT1hCnRoaXMu
+Yj1iCnRoaXMuYz1jfSwKRUY6ZnVuY3Rpb24oYSxiLGMpe3JldHVybiBiLkMoIkA8MD4iKS5LcShjKS5D
+KCJGbzwxLDI+IikuYShILkI3KGEsbmV3IEguTjUoYi5DKCJAPDA+IikuS3EoYykuQygiTjU8MSwyPiIp
+KSkpfSwKRmw6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gbmV3IEguTjUoYS5DKCJAPDA+IikuS3EoYikuQygi
+TjU8MSwyPiIpKX0sCkxzOmZ1bmN0aW9uKGEpe3JldHVybiBuZXcgUC5iNihhLkMoImI2PDA+IikpfSwK
+VDI6ZnVuY3Rpb24oKXt2YXIgdD1PYmplY3QuY3JlYXRlKG51bGwpCnRbIjxub24taWRlbnRpZmllci1r
+ZXk+Il09dApkZWxldGUgdFsiPG5vbi1pZGVudGlmaWVyLWtleT4iXQpyZXR1cm4gdH0sCnJqOmZ1bmN0
+aW9uKGEsYixjKXt2YXIgdD1uZXcgUC5sbShhLGIsYy5DKCJsbTwwPiIpKQp0LmM9YS5lCnJldHVybiB0
+fSwKRVA6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0LHMKaWYoUC5oQihhKSl7aWYoYj09PSIoIiYmYz09PSIp
+IilyZXR1cm4iKC4uLikiCnJldHVybiBiKyIuLi4iK2N9dD1ILlZNKFtdLHUucykKQy5ObS5pKCQueGcs
+YSkKdHJ5e1AuVnIoYSx0KX1maW5hbGx5e2lmKDA+PSQueGcubGVuZ3RoKXJldHVybiBILmsoJC54Zywt
+MSkKJC54Zy5wb3AoKX1zPVAudmcoYix1LlIuYSh0KSwiLCAiKStjCnJldHVybiBzLmNoYXJDb2RlQXQo
+MCk9PTA/czpzfSwKV0U6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0LHMKaWYoUC5oQihhKSlyZXR1cm4gYisi
+Li4uIitjCnQ9bmV3IFAuUm4oYikKQy5ObS5pKCQueGcsYSkKdHJ5e3M9dApzLmE9UC52ZyhzLmEsYSwi
+LCAiKX1maW5hbGx5e2lmKDA+PSQueGcubGVuZ3RoKXJldHVybiBILmsoJC54ZywtMSkKJC54Zy5wb3Ao
+KX10LmErPWMKcz10LmEKcmV0dXJuIHMuY2hhckNvZGVBdCgwKT09MD9zOnN9LApoQjpmdW5jdGlvbihh
+KXt2YXIgdCxzCmZvcih0PSQueGcubGVuZ3RoLHM9MDtzPHQ7KytzKWlmKGE9PT0kLnhnW3NdKXJldHVy
+biEwCnJldHVybiExfSwKVnI6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzLHIscSxwLG8sbixtPWEuZ2t6KGEp
+LGw9MCxrPTAKd2hpbGUoITApe2lmKCEobDw4MHx8azwzKSlicmVhawppZighbS5GKCkpcmV0dXJuCnQ9
+SC5kKG0uZ2woKSkKQy5ObS5pKGIsdCkKbCs9dC5sZW5ndGgrMjsrK2t9aWYoIW0uRigpKXtpZihrPD01
+KXJldHVybgppZigwPj1iLmxlbmd0aClyZXR1cm4gSC5rKGIsLTEpCnM9Yi5wb3AoKQppZigwPj1iLmxl
+bmd0aClyZXR1cm4gSC5rKGIsLTEpCnI9Yi5wb3AoKX1lbHNle3E9bS5nbCgpOysrawppZighbS5GKCkp
+e2lmKGs8PTQpe0MuTm0uaShiLEguZChxKSkKcmV0dXJufXM9SC5kKHEpCmlmKDA+PWIubGVuZ3RoKXJl
+dHVybiBILmsoYiwtMSkKcj1iLnBvcCgpCmwrPXMubGVuZ3RoKzJ9ZWxzZXtwPW0uZ2woKTsrK2sKZm9y
+KDttLkYoKTtxPXAscD1vKXtvPW0uZ2woKTsrK2sKaWYoaz4xMDApe3doaWxlKCEwKXtpZighKGw+NzUm
+Jms+MykpYnJlYWsKaWYoMD49Yi5sZW5ndGgpcmV0dXJuIEguayhiLC0xKQpsLT1iLnBvcCgpLmxlbmd0
+aCsyOy0ta31DLk5tLmkoYiwiLi4uIikKcmV0dXJufX1yPUguZChxKQpzPUguZChwKQpsKz1zLmxlbmd0
+aCtyLmxlbmd0aCs0fX1pZihrPmIubGVuZ3RoKzIpe2wrPTUKbj0iLi4uIn1lbHNlIG49bnVsbAp3aGls
+ZSghMCl7aWYoIShsPjgwJiZiLmxlbmd0aD4zKSlicmVhawppZigwPj1iLmxlbmd0aClyZXR1cm4gSC5r
+KGIsLTEpCmwtPWIucG9wKCkubGVuZ3RoKzIKaWYobj09bnVsbCl7bCs9NQpuPSIuLi4ifX1pZihuIT1u
+dWxsKUMuTm0uaShiLG4pCkMuTm0uaShiLHIpCkMuTm0uaShiLHMpfSwKdE06ZnVuY3Rpb24oYSxiKXt2
+YXIgdCxzLHI9UC5McyhiKQpmb3IodD1hLmxlbmd0aCxzPTA7czxhLmxlbmd0aDthLmxlbmd0aD09PXR8
+fCgwLEgubGspKGEpLCsrcylyLmkoMCxiLmEoYVtzXSkpCnJldHVybiByfSwKbk86ZnVuY3Rpb24oYSl7
+dmFyIHQscz17fQppZihQLmhCKGEpKXJldHVybiJ7Li4ufSIKdD1uZXcgUC5SbigiIikKdHJ5e0MuTm0u
+aSgkLnhnLGEpCnQuYSs9InsiCnMuYT0hMAphLksoMCxuZXcgUC5yYShzLHQpKQp0LmErPSJ9In1maW5h
+bGx5e2lmKDA+PSQueGcubGVuZ3RoKXJldHVybiBILmsoJC54ZywtMSkKJC54Zy5wb3AoKX1zPXQuYQpy
+ZXR1cm4gcy5jaGFyQ29kZUF0KDApPT0wP3M6c30sCmI2OmZ1bmN0aW9uIGI2KGEpe3ZhciBfPXRoaXMK
+Xy5hPTAKXy5mPV8uZT1fLmQ9Xy5jPV8uYj1udWxsCl8ucj0wCl8uJHRpPWF9LApibjpmdW5jdGlvbiBi
+bihhKXt0aGlzLmE9YQp0aGlzLmM9dGhpcy5iPW51bGx9LApsbTpmdW5jdGlvbiBsbShhLGIsYyl7dmFy
+IF89dGhpcwpfLmE9YQpfLmI9YgpfLmQ9Xy5jPW51bGwKXy4kdGk9Y30sCm1XOmZ1bmN0aW9uIG1XKCl7
+fSwKTFU6ZnVuY3Rpb24gTFUoKXt9LApsRDpmdW5jdGlvbiBsRCgpe30sCmlsOmZ1bmN0aW9uIGlsKCl7
+fSwKcmE6ZnVuY3Rpb24gcmEoYSxiKXt0aGlzLmE9YQp0aGlzLmI9Yn0sCllrOmZ1bmN0aW9uIFlrKCl7
+fSwKeVE6ZnVuY3Rpb24geVEoYSl7dGhpcy5hPWF9LApLUDpmdW5jdGlvbiBLUCgpe30sClBuOmZ1bmN0
+aW9uIFBuKCl7fSwKR2o6ZnVuY3Rpb24gR2ooYSxiKXt0aGlzLmE9YQp0aGlzLiR0aT1ifSwKTWE6ZnVu
+Y3Rpb24gTWEoKXt9LApWajpmdW5jdGlvbiBWaigpe30sClh2OmZ1bmN0aW9uIFh2KCl7fSwKblk6ZnVu
+Y3Rpb24gblkoKXt9LApUQzpmdW5jdGlvbiBUQygpe30sClJVOmZ1bmN0aW9uIFJVKCl7fSwKQlM6ZnVu
+Y3Rpb24oYSxiKXt2YXIgdCxzLHIscQppZih0eXBlb2YgYSE9InN0cmluZyIpdGhyb3cgSC5iKEguSShh
+KSkKdD1udWxsCnRyeXt0PUpTT04ucGFyc2UoYSl9Y2F0Y2gocil7cz1ILlJ1KHIpCnE9UC5ycihTdHJp
+bmcocyksbnVsbCxudWxsKQp0aHJvdyBILmIocSl9cT1QLlFlKHQpCnJldHVybiBxfSwKUWU6ZnVuY3Rp
+b24oYSl7dmFyIHQKaWYoYT09bnVsbClyZXR1cm4gbnVsbAppZih0eXBlb2YgYSE9Im9iamVjdCIpcmV0
+dXJuIGEKaWYoT2JqZWN0LmdldFByb3RvdHlwZU9mKGEpIT09QXJyYXkucHJvdG90eXBlKXJldHVybiBu
+ZXcgUC51dyhhLE9iamVjdC5jcmVhdGUobnVsbCkpCmZvcih0PTA7dDxhLmxlbmd0aDsrK3QpYVt0XT1Q
+LlFlKGFbdF0pCnJldHVybiBhfSwKa3k6ZnVuY3Rpb24oYSxiLGMsZCl7aWYoYiBpbnN0YW5jZW9mIFVp
+bnQ4QXJyYXkpcmV0dXJuIFAuUlAoITEsYixjLGQpCnJldHVybiBudWxsfSwKUlA6ZnVuY3Rpb24oYSxi
+LGMsZCl7dmFyIHQscyxyPSQudEwoKQppZihyPT1udWxsKXJldHVybiBudWxsCnQ9MD09PWMKaWYodCYm
+ITApcmV0dXJuIFAuT1EocixiKQpzPWIubGVuZ3RoCmQ9UC5qQihjLGQscykKaWYodCYmZD09PXMpcmV0
+dXJuIFAuT1EocixiKQpyZXR1cm4gUC5PUShyLGIuc3ViYXJyYXkoYyxkKSl9LApPUTpmdW5jdGlvbihh
+LGIpe2lmKFAuQWooYikpcmV0dXJuIG51bGwKcmV0dXJuIFAuSmgoYSxiKX0sCkpoOmZ1bmN0aW9uKGEs
+Yil7dmFyIHQscwp0cnl7dD1hLmRlY29kZShiKQpyZXR1cm4gdH1jYXRjaChzKXtILlJ1KHMpfXJldHVy
+biBudWxsfSwKQWo6ZnVuY3Rpb24oYSl7dmFyIHQscz1hLmxlbmd0aC0yCmZvcih0PTA7dDxzOysrdClp
+ZihhW3RdPT09MjM3KWlmKChhW3QrMV0mMjI0KT09PTE2MClyZXR1cm4hMApyZXR1cm4hMX0sCmNQOmZ1
+bmN0aW9uKGEsYixjKXt2YXIgdCxzLHIKZm9yKHQ9Si5VNihhKSxzPWI7czxjOysrcyl7cj10LnEoYSxz
+KQppZih0eXBlb2YgciE9PSJudW1iZXIiKXJldHVybiByLnpNKCkKaWYoKHImMTI3KSE9PXIpcmV0dXJu
+IHMtYn1yZXR1cm4gYy1ifSwKeE06ZnVuY3Rpb24oYSxiLGMsZCxlLGYpe2lmKEMuam4uelkoZiw0KSE9
+PTApdGhyb3cgSC5iKFAucnIoIkludmFsaWQgYmFzZTY0IHBhZGRpbmcsIHBhZGRlZCBsZW5ndGggbXVz
+dCBiZSBtdWx0aXBsZSBvZiBmb3VyLCBpcyAiK2YsYSxjKSkKaWYoZCtlIT09Zil0aHJvdyBILmIoUC5y
+cigiSW52YWxpZCBiYXNlNjQgcGFkZGluZywgJz0nIG5vdCBhdCB0aGUgZW5kIixhLGIpKQppZihlPjIp
+dGhyb3cgSC5iKFAucnIoIkludmFsaWQgYmFzZTY0IHBhZGRpbmcsIG1vcmUgdGhhbiB0d28gJz0nIGNo
+YXJhY3RlcnMiLGEsYikpfSwKdXc6ZnVuY3Rpb24gdXcoYSxiKXt0aGlzLmE9YQp0aGlzLmI9Ygp0aGlz
+LmM9bnVsbH0sCmk4OmZ1bmN0aW9uIGk4KGEpe3RoaXMuYT1hfSwKcGc6ZnVuY3Rpb24gcGcoKXt9LApD
+VjpmdW5jdGlvbiBDVigpe30sClU4OmZ1bmN0aW9uIFU4KCl7fSwKVWs6ZnVuY3Rpb24gVWsoKXt9LAp3
+STpmdW5jdGlvbiB3SSgpe30sClppOmZ1bmN0aW9uIFppKCl7fSwKYnk6ZnVuY3Rpb24gYnkoKXt9LApN
+eDpmdW5jdGlvbiBNeChhKXt0aGlzLmE9YX0sCnU1OmZ1bmN0aW9uIHU1KCl7fSwKRTM6ZnVuY3Rpb24g
+RTMoKXt9LApSdzpmdW5jdGlvbiBSdyhhKXt0aGlzLmI9MAp0aGlzLmM9YX0sCkdZOmZ1bmN0aW9uIEdZ
+KGEpe3RoaXMuYT1hfSwKYno6ZnVuY3Rpb24gYnooYSxiKXt2YXIgXz10aGlzCl8uYT1hCl8uYj1iCl8u
+Yz0hMApfLmY9Xy5lPV8uZD0wfSwKUUE6ZnVuY3Rpb24oYSxiKXt2YXIgdD1ILkhwKGEsYikKaWYodCE9
+bnVsbClyZXR1cm4gdAp0aHJvdyBILmIoUC5ycihhLG51bGwsbnVsbCkpfSwKb3M6ZnVuY3Rpb24oYSl7
+aWYoYSBpbnN0YW5jZW9mIEguVHApcmV0dXJuIGEuWigwKQpyZXR1cm4iSW5zdGFuY2Ugb2YgJyIrSC5k
+KEgubGgoYSkpKyInIn0sCk84OmZ1bmN0aW9uKGEsYixjLGQpe3ZhciB0LHM9Si5RaShhLGQpCmlmKGEh
+PT0wJiZiIT1udWxsKWZvcih0PTA7dDxzLmxlbmd0aDsrK3QpQy5ObS5ZKHMsdCxiKQpyZXR1cm4gc30s
+CkNIOmZ1bmN0aW9uKGEsYixjKXt2YXIgdCxzPUguVk0oW10sYy5DKCJqZDwwPiIpKQpmb3IodD1KLklU
+KGEpO3QuRigpOylDLk5tLmkocyxjLmEodC5nbCgpKSkKaWYoYilyZXR1cm4gcwpyZXR1cm4gSi5FcChz
+LGMpfSwKZEg6ZnVuY3Rpb24oYSxiLGMsZCl7dmFyIHQscz1KLktoKGEsZCkKZm9yKHQ9MDt0PGE7Kyt0
+KUMuTm0uWShzLHQsYi4kMSh0KSkKcmV0dXJuIHN9LApBRjpmdW5jdGlvbihhLGIpe3JldHVybiBKLnVu
+KFAuQ0goYSwhMSxiKSl9LApITTpmdW5jdGlvbihhLGIsYyl7dmFyIHQscz11LnQKaWYocy5iKGEpKXt0
+PWEubGVuZ3RoCmM9UC5qQihiLGMsdCkKcmV0dXJuIEguZVQoYj4wfHxjPHQ/cy5hKEMuTm0uRDYoYSxi
+LGMpKTphKX1pZih1LmJtLmIoYSkpcmV0dXJuIEguZncoYSxiLFAuakIoYixjLGEubGVuZ3RoKSkKcmV0
+dXJuIFAuYncoYSxiLGMpfSwKT286ZnVuY3Rpb24oYSl7cmV0dXJuIEguTHcoYSl9LApidzpmdW5jdGlv
+bihhLGIsYyl7dmFyIHQscyxyLHEscD1udWxsCmlmKGI8MCl0aHJvdyBILmIoUC5URShiLDAsSi5IKGEp
+LHAscCkpCnQ9Yz09bnVsbAppZighdCYmYzxiKXRocm93IEguYihQLlRFKGMsYixKLkgoYSkscCxwKSkK
+cz1KLklUKGEpCmZvcihyPTA7cjxiOysrcilpZighcy5GKCkpdGhyb3cgSC5iKFAuVEUoYiwwLHIscCxw
+KSkKcT1bXQppZih0KWZvcig7cy5GKCk7KXEucHVzaChzLmdsKCkpCmVsc2UgZm9yKHI9YjtyPGM7Kyty
+KXtpZighcy5GKCkpdGhyb3cgSC5iKFAuVEUoYyxiLHIscCxwKSkKcS5wdXNoKHMuZ2woKSl9cmV0dXJu
+IEguZVQocSl9LApudTpmdW5jdGlvbihhKXtyZXR1cm4gbmV3IEguVlIoYSxILnY0KGEsITEsITAsITEs
+ITEsITEpKX0sCnZnOmZ1bmN0aW9uKGEsYixjKXt2YXIgdD1KLklUKGIpCmlmKCF0LkYoKSlyZXR1cm4g
+YQppZihjLmxlbmd0aD09PTApe2RvIGErPUguZCh0LmdsKCkpCndoaWxlKHQuRigpKX1lbHNle2ErPUgu
+ZCh0LmdsKCkpCmZvcig7dC5GKCk7KWE9YStjK0guZCh0LmdsKCkpfXJldHVybiBhfSwKbHI6ZnVuY3Rp
+b24oYSxiLGMsZCl7cmV0dXJuIG5ldyBQLm1wKGEsYixjLGQpfSwKdW86ZnVuY3Rpb24oKXt2YXIgdD1I
+Lk0wKCkKaWYodCE9bnVsbClyZXR1cm4gUC5oSyh0KQp0aHJvdyBILmIoUC5MNCgiJ1VyaS5iYXNlJyBp
+cyBub3Qgc3VwcG9ydGVkIikpfSwKZVA6ZnVuY3Rpb24oYSxiLGMsZCl7dmFyIHQscyxyLHEscCxvLG49
+IjAxMjM0NTY3ODlBQkNERUYiCmlmKGM9PT1DLnhNKXt0PSQuejQoKS5iCmlmKHR5cGVvZiBiIT0ic3Ry
+aW5nIilILnZoKEguSShiKSkKdD10LnRlc3QoYil9ZWxzZSB0PSExCmlmKHQpcmV0dXJuIGIKSC5MaChj
+KS5DKCJVay5TIikuYShiKQpzPWMuZ1pFKCkuV0ooYikKZm9yKHQ9cy5sZW5ndGgscj0wLHE9IiI7cjx0
+Oysrcil7cD1zW3JdCmlmKHA8MTI4KXtvPXA+Pj40CmlmKG8+PTgpcmV0dXJuIEguayhhLG8pCm89KGFb
+b10mMTw8KHAmMTUpKSE9PTB9ZWxzZSBvPSExCmlmKG8pcSs9SC5MdyhwKQplbHNlIHE9ZCYmcD09PTMy
+P3ErIisiOnErIiUiK25bcD4+PjQmMTVdK25bcCYxNV19cmV0dXJuIHEuY2hhckNvZGVBdCgwKT09MD9x
+OnF9LApHcTpmdW5jdGlvbihhKXt2YXIgdD1NYXRoLmFicyhhKSxzPWE8MD8iLSI6IiIKaWYodD49MTAw
+MClyZXR1cm4iIithCmlmKHQ+PTEwMClyZXR1cm4gcysiMCIrdAppZih0Pj0xMClyZXR1cm4gcysiMDAi
+K3QKcmV0dXJuIHMrIjAwMCIrdH0sClZ4OmZ1bmN0aW9uKGEpe2lmKGE+PTEwMClyZXR1cm4iIithCmlm
+KGE+PTEwKXJldHVybiIwIithCnJldHVybiIwMCIrYX0sCmgwOmZ1bmN0aW9uKGEpe2lmKGE+PTEwKXJl
+dHVybiIiK2EKcmV0dXJuIjAiK2F9LApoOmZ1bmN0aW9uKGEpe2lmKHR5cGVvZiBhPT0ibnVtYmVyInx8
+SC5yUShhKXx8bnVsbD09YSlyZXR1cm4gSi5BYyhhKQppZih0eXBlb2YgYT09InN0cmluZyIpcmV0dXJu
+IEpTT04uc3RyaW5naWZ5KGEpCnJldHVybiBQLm9zKGEpfSwKaFY6ZnVuY3Rpb24oYSl7cmV0dXJuIG5l
+dyBQLkM2KGEpfSwKeFk6ZnVuY3Rpb24oYSl7cmV0dXJuIG5ldyBQLkFUKCExLG51bGwsbnVsbCxhKX0s
+CkwzOmZ1bmN0aW9uKGEsYixjKXtyZXR1cm4gbmV3IFAuQVQoITAsYSxiLGMpfSwKVUk6ZnVuY3Rpb24o
+YSxiLGMpe2lmKGE9PW51bGwpdGhyb3cgSC5iKG5ldyBQLkFUKCExLG51bGwsYiwiTXVzdCBub3QgYmUg
+bnVsbCIpKQpyZXR1cm4gYX0sCk83OmZ1bmN0aW9uKGEsYil7cmV0dXJuIG5ldyBQLmJKKG51bGwsbnVs
+bCwhMCxhLGIsIlZhbHVlIG5vdCBpbiByYW5nZSIpfSwKVEU6ZnVuY3Rpb24oYSxiLGMsZCxlKXtyZXR1
+cm4gbmV3IFAuYkooYixjLCEwLGEsZCwiSW52YWxpZCB2YWx1ZSIpfSwKd0E6ZnVuY3Rpb24oYSxiLGMs
+ZCl7aWYoYTxifHxhPmMpdGhyb3cgSC5iKFAuVEUoYSxiLGMsZCxudWxsKSkKcmV0dXJuIGF9LApqQjpm
+dW5jdGlvbihhLGIsYyl7aWYoMD5hfHxhPmMpdGhyb3cgSC5iKFAuVEUoYSwwLGMsInN0YXJ0IixudWxs
+KSkKaWYoYiE9bnVsbCl7aWYoYT5ifHxiPmMpdGhyb3cgSC5iKFAuVEUoYixhLGMsImVuZCIsbnVsbCkp
+CnJldHVybiBifXJldHVybiBjfSwKazE6ZnVuY3Rpb24oYSxiKXtpZihhPDApdGhyb3cgSC5iKFAuVEUo
+YSwwLG51bGwsYixudWxsKSkKcmV0dXJuIGF9LAp0OmZ1bmN0aW9uKGEsYixjLGQsZSl7dmFyIHQ9SC5X
+WShlPT1udWxsP0ouSChiKTplKQpyZXR1cm4gbmV3IFAuZVkodCwhMCxhLGMsIkluZGV4IG91dCBvZiBy
+YW5nZSIpfSwKTDQ6ZnVuY3Rpb24oYSl7cmV0dXJuIG5ldyBQLnViKGEpfSwKbjpmdW5jdGlvbihhKXty
+ZXR1cm4gbmV3IFAuZHMoYSl9LApQVjpmdW5jdGlvbihhKXtyZXR1cm4gbmV3IFAubGooYSl9LAphNDpm
+dW5jdGlvbihhKXtyZXR1cm4gbmV3IFAuVVYoYSl9LApycjpmdW5jdGlvbihhLGIsYyl7cmV0dXJuIG5l
+dyBQLmFFKGEsYixjKX0sCmhLOmZ1bmN0aW9uKGE0KXt2YXIgdCxzLHIscSxwLG8sbixtLGwsayxqLGks
+aCxnLGYsZSxkLGMsYixhLGEwLGExLGEyPW51bGwsYTM9YTQubGVuZ3RoCmlmKGEzPj01KXt0PSgoSi5R
+eihhNCw0KV41OCkqM3xDLnhCLlcoYTQsMCleMTAwfEMueEIuVyhhNCwxKV45N3xDLnhCLlcoYTQsMile
+MTE2fEMueEIuVyhhNCwzKV45Nyk+Pj4wCmlmKHQ9PT0wKXJldHVybiBQLktEKGEzPGEzP0MueEIuTmoo
+YTQsMCxhMyk6YTQsNSxhMikuZ2xSKCkKZWxzZSBpZih0PT09MzIpcmV0dXJuIFAuS0QoQy54Qi5Oaihh
+NCw1LGEzKSwwLGEyKS5nbFIoKX1zPVAuTzgoOCwwLCExLHUucSkKQy5ObS5ZKHMsMCwwKQpDLk5tLlko
+cywxLC0xKQpDLk5tLlkocywyLC0xKQpDLk5tLlkocyw3LC0xKQpDLk5tLlkocywzLDApCkMuTm0uWShz
+LDQsMCkKQy5ObS5ZKHMsNSxhMykKQy5ObS5ZKHMsNixhMykKaWYoUC5VQihhNCwwLGEzLDAscyk+PTE0
+KUMuTm0uWShzLDcsYTMpCmlmKDE+PXMubGVuZ3RoKXJldHVybiBILmsocywxKQpyPXNbMV0KaWYocj49
+MClpZihQLlVCKGE0LDAsciwyMCxzKT09PTIwKXtpZig3Pj1zLmxlbmd0aClyZXR1cm4gSC5rKHMsNykK
+c1s3XT1yfXE9cy5sZW5ndGgKaWYoMj49cSlyZXR1cm4gSC5rKHMsMikKcD1zWzJdKzEKaWYoMz49cSly
+ZXR1cm4gSC5rKHMsMykKbz1zWzNdCmlmKDQ+PXEpcmV0dXJuIEguayhzLDQpCm49c1s0XQppZig1Pj1x
+KXJldHVybiBILmsocyw1KQptPXNbNV0KaWYoNj49cSlyZXR1cm4gSC5rKHMsNikKbD1zWzZdCmlmKGw8
+bSltPWwKaWYobjxwKW49bQplbHNlIGlmKG48PXIpbj1yKzEKaWYobzxwKW89bgppZig3Pj1xKXJldHVy
+biBILmsocyw3KQprPXNbN108MAppZihrKWlmKHA+ciszKXtqPWEyCms9ITF9ZWxzZXtxPW8+MAppZihx
+JiZvKzE9PT1uKXtqPWEyCms9ITF9ZWxzZXtpZighKG08YTMmJm09PT1uKzImJkoucTAoYTQsIi4uIixu
+KSkpaT1tPm4rMiYmSi5xMChhNCwiLy4uIixtLTMpCmVsc2UgaT0hMAppZihpKXtqPWEyCms9ITF9ZWxz
+ZXtpZihyPT09NClpZihKLnEwKGE0LCJmaWxlIiwwKSl7aWYocDw9MCl7aWYoIUMueEIuUWkoYTQsIi8i
+LG4pKXtoPSJmaWxlOi8vLyIKdD0zfWVsc2V7aD0iZmlsZTovLyIKdD0yfWE0PWgrQy54Qi5OaihhNCxu
+LGEzKQpyLT0wCnE9dC0wCm0rPXEKbCs9cQphMz1hNC5sZW5ndGgKcD03Cm89NwpuPTd9ZWxzZSBpZihu
+PT09bSl7KytsCmc9bSsxCmE0PUMueEIuaTcoYTQsbixtLCIvIik7KythMwptPWd9aj0iZmlsZSJ9ZWxz
+ZSBpZihDLnhCLlFpKGE0LCJodHRwIiwwKSl7aWYocSYmbyszPT09biYmQy54Qi5RaShhNCwiODAiLG8r
+MSkpe2wtPTMKZj1uLTMKbS09MwphND1DLnhCLmk3KGE0LG8sbiwiIikKYTMtPTMKbj1mfWo9Imh0dHAi
+fWVsc2Ugaj1hMgplbHNlIGlmKHI9PT01JiZKLnEwKGE0LCJodHRwcyIsMCkpe2lmKHEmJm8rND09PW4m
+JkoucTAoYTQsIjQ0MyIsbysxKSl7bC09NApmPW4tNAptLT00CmE0PUouZGcoYTQsbyxuLCIiKQphMy09
+MwpuPWZ9aj0iaHR0cHMifWVsc2Ugaj1hMgprPSEwfX19ZWxzZSBqPWEyCmlmKGspe3E9YTQubGVuZ3Ro
+CmlmKGEzPHEpe2E0PUoubGQoYTQsMCxhMykKci09MApwLT0wCm8tPTAKbi09MAptLT0wCmwtPTB9cmV0
+dXJuIG5ldyBQLlVmKGE0LHIscCxvLG4sbSxsLGopfWlmKGo9PW51bGwpaWYocj4wKWo9UC5QaShhNCww
+LHIpCmVsc2V7aWYocj09PTApUC5SMyhhNCwwLCJJbnZhbGlkIGVtcHR5IHNjaGVtZSIpCmo9IiJ9aWYo
+cD4wKXtlPXIrMwpkPWU8cD9QLnpSKGE0LGUscC0xKToiIgpjPVAuT2UoYTQscCxvLCExKQpxPW8rMQpp
+ZihxPG4pe2I9SC5IcChKLmxkKGE0LHEsbiksYTIpCmE9UC53QihiPT1udWxsP0gudmgoUC5ycigiSW52
+YWxpZCBwb3J0IixhNCxxKSk6YixqKX1lbHNlIGE9YTJ9ZWxzZXthPWEyCmM9YQpkPSIifWEwPVAua2Eo
+YTQsbixtLGEyLGosYyE9bnVsbCkKYTE9bTxsP1AubGUoYTQsbSsxLGwsYTIpOmEyCnJldHVybiBuZXcg
+UC5EbihqLGQsYyxhLGEwLGExLGw8YTM/UC50RyhhNCxsKzEsYTMpOmEyKX0sCk10OmZ1bmN0aW9uKGEp
+e0guYyhhKQpyZXR1cm4gUC5rdShhLDAsYS5sZW5ndGgsQy54TSwhMSl9LApXWDpmdW5jdGlvbihhKXt2
+YXIgdD11Lk4KcmV0dXJuIEMuTm0uTjAoSC5WTShhLnNwbGl0KCImIiksdS5zKSxQLkZsKHQsdCksbmV3
+IFAubjEoQy54TSksdS5mKX0sCkhoOmZ1bmN0aW9uKGEsYixjKXt2YXIgdCxzLHIscSxwLG8sbixtPSJJ
+UHY0IGFkZHJlc3Mgc2hvdWxkIGNvbnRhaW4gZXhhY3RseSA0IHBhcnRzIixsPSJlYWNoIHBhcnQgbXVz
+dCBiZSBpbiB0aGUgcmFuZ2UgMC4uMjU1IixrPW5ldyBQLmNTKGEpLGo9bmV3IFVpbnQ4QXJyYXkoNCkK
+Zm9yKHQ9ai5sZW5ndGgscz1iLHI9cyxxPTA7czxjOysrcyl7cD1DLnhCLm0oYSxzKQppZihwIT09NDYp
+e2lmKChwXjQ4KT45KWsuJDIoImludmFsaWQgY2hhcmFjdGVyIixzKX1lbHNle2lmKHE9PT0zKWsuJDIo
+bSxzKQpvPVAuUUEoQy54Qi5OaihhLHIscyksbnVsbCkKaWYodHlwZW9mIG8hPT0ibnVtYmVyIilyZXR1
+cm4gby5vcygpCmlmKG8+MjU1KWsuJDIobCxyKQpuPXErMQppZihxPj10KXJldHVybiBILmsoaixxKQpq
+W3FdPW8Kcj1zKzEKcT1ufX1pZihxIT09MylrLiQyKG0sYykKbz1QLlFBKEMueEIuTmooYSxyLGMpLG51
+bGwpCmlmKHR5cGVvZiBvIT09Im51bWJlciIpcmV0dXJuIG8ub3MoKQppZihvPjI1NSlrLiQyKGwscikK
+aWYocT49dClyZXR1cm4gSC5rKGoscSkKaltxXT1vCnJldHVybiBqfSwKZWc6ZnVuY3Rpb24oYSxiLGEw
+KXt2YXIgdCxzLHIscSxwLG8sbixtLGwsayxqLGksaCxnLGYsZSxkPW5ldyBQLlZDKGEpLGM9bmV3IFAu
+SlQoZCxhKQppZihhLmxlbmd0aDwyKWQuJDEoImFkZHJlc3MgaXMgdG9vIHNob3J0IikKdD1ILlZNKFtd
+LHUudCkKZm9yKHM9YixyPXMscT0hMSxwPSExO3M8YTA7KytzKXtvPUMueEIubShhLHMpCmlmKG89PT01
+OCl7aWYocz09PWIpeysrcwppZihDLnhCLm0oYSxzKSE9PTU4KWQuJDIoImludmFsaWQgc3RhcnQgY29s
+b24uIixzKQpyPXN9aWYocz09PXIpe2lmKHEpZC4kMigib25seSBvbmUgd2lsZGNhcmQgYDo6YCBpcyBh
+bGxvd2VkIixzKQpDLk5tLmkodCwtMSkKcT0hMH1lbHNlIEMuTm0uaSh0LGMuJDIocixzKSkKcj1zKzF9
+ZWxzZSBpZihvPT09NDYpcD0hMH1pZih0Lmxlbmd0aD09PTApZC4kMSgidG9vIGZldyBwYXJ0cyIpCm49
+cj09PWEwCm09Qy5ObS5ncloodCkKaWYobiYmbSE9PS0xKWQuJDIoImV4cGVjdGVkIGEgcGFydCBhZnRl
+ciBsYXN0IGA6YCIsYTApCmlmKCFuKWlmKCFwKUMuTm0uaSh0LGMuJDIocixhMCkpCmVsc2V7bD1QLkho
+KGEscixhMCkKQy5ObS5pKHQsKGxbMF08PDh8bFsxXSk+Pj4wKQpDLk5tLmkodCwobFsyXTw8OHxsWzNd
+KT4+PjApfWlmKHEpe2lmKHQubGVuZ3RoPjcpZC4kMSgiYW4gYWRkcmVzcyB3aXRoIGEgd2lsZGNhcmQg
+bXVzdCBoYXZlIGxlc3MgdGhhbiA3IHBhcnRzIil9ZWxzZSBpZih0Lmxlbmd0aCE9PTgpZC4kMSgiYW4g
+YWRkcmVzcyB3aXRob3V0IGEgd2lsZGNhcmQgbXVzdCBjb250YWluIGV4YWN0bHkgOCBwYXJ0cyIpCms9
+bmV3IFVpbnQ4QXJyYXkoMTYpCmZvcihtPXQubGVuZ3RoLGo9ay5sZW5ndGgsaT05LW0scz0wLGg9MDtz
+PG07KytzKXtnPXRbc10KaWYoZz09PS0xKWZvcihmPTA7ZjxpOysrZil7aWYoaDwwfHxoPj1qKXJldHVy
+biBILmsoayxoKQprW2hdPTAKZT1oKzEKaWYoZT49ailyZXR1cm4gSC5rKGssZSkKa1tlXT0wCmgrPTJ9
+ZWxzZXtlPUMuam4ud0coZyw4KQppZihoPDB8fGg+PWopcmV0dXJuIEguayhrLGgpCmtbaF09ZQplPWgr
+MQppZihlPj1qKXJldHVybiBILmsoayxlKQprW2VdPWcmMjU1CmgrPTJ9fXJldHVybiBrfSwKS0w6ZnVu
+Y3Rpb24oYSxiLGMsZCxlLGYsZyl7dmFyIHQscyxyLHEscCxvCmY9Zj09bnVsbD8iIjpQLlBpKGYsMCxm
+Lmxlbmd0aCkKZz1QLnpSKGcsMCxnPT1udWxsPzA6Zy5sZW5ndGgpCmE9UC5PZShhLDAsYT09bnVsbD8w
+OmEubGVuZ3RoLCExKQp0PVAubGUobnVsbCwwLDAsZSkKcz1QLnRHKG51bGwsMCwwKQpkPVAud0IoZCxm
+KQpyPWY9PT0iZmlsZSIKaWYoYT09bnVsbClxPWcubGVuZ3RoIT09MHx8ZCE9bnVsbHx8cgplbHNlIHE9
+ITEKaWYocSlhPSIiCnE9YT09bnVsbApwPSFxCmI9UC5rYShiLDAsYj09bnVsbD8wOmIubGVuZ3RoLGMs
+ZixwKQpvPWYubGVuZ3RoPT09MAppZihvJiZxJiYhQy54Qi5uKGIsIi8iKSliPVAud0YoYiwhb3x8cCkK
+ZWxzZSBiPVAueGUoYikKcmV0dXJuIG5ldyBQLkRuKGYsZyxxJiZDLnhCLm4oYiwiLy8iKT8iIjphLGQs
+Yix0LHMpfSwKd0s6ZnVuY3Rpb24oYSl7aWYoYT09PSJodHRwIilyZXR1cm4gODAKaWYoYT09PSJodHRw
+cyIpcmV0dXJuIDQ0MwpyZXR1cm4gMH0sClIzOmZ1bmN0aW9uKGEsYixjKXt0aHJvdyBILmIoUC5ycihj
+LGEsYikpfSwKWGQ6ZnVuY3Rpb24oYSxiLGMsZCl7dmFyIHQscyxyLHEscCxvLG4sbSxsLGssaixpPW51
+bGwsaD1iLmxlbmd0aAppZihoIT09MCl7cj0wCndoaWxlKCEwKXtpZighKHI8aCkpe3Q9IiIKcz0wCmJy
+ZWFrfWlmKEMueEIuVyhiLHIpPT09NjQpe3Q9Qy54Qi5OaihiLDAscikKcz1yKzEKYnJlYWt9KytyfWlm
+KHM8aCYmQy54Qi5XKGIscyk9PT05MSl7Zm9yKHE9cyxwPS0xO3E8aDsrK3Epe289Qy54Qi5XKGIscSkK
+aWYobz09PTM3JiZwPDApe249Qy54Qi5RaShiLCIyNSIscSsxKT9xKzI6cQpwPXEKcT1ufWVsc2UgaWYo
+bz09PTkzKWJyZWFrfWlmKHE9PT1oKXRocm93IEguYihQLnJyKCJJbnZhbGlkIElQdjYgaG9zdCBlbnRy
+eS4iLGIscykpCm09cDwwP3E6cApQLmVnKGIscysxLG0pOysrcQppZihxIT09aCYmQy54Qi5XKGIscSkh
+PT01OCl0aHJvdyBILmIoUC5ycigiSW52YWxpZCBlbmQgb2YgYXV0aG9yaXR5IixiLHEpKX1lbHNlIHE9
+cwp3aGlsZSghMCl7aWYoIShxPGgpKXtsPWkKYnJlYWt9aWYoQy54Qi5XKGIscSk9PT01OCl7az1DLnhC
+LkcoYixxKzEpCmw9ay5sZW5ndGghPT0wP1AuUUEoayxpKTppCmJyZWFrfSsrcX1qPUMueEIuTmooYixz
+LHEpfWVsc2V7bD1pCmo9bAp0PSIifXJldHVybiBQLktMKGosaSxILlZNKGMuc3BsaXQoIi8iKSx1LnMp
+LGwsZCxhLHQpfSwKa0U6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzLHIscSxwCmZvcih0PWEubGVuZ3RoLHM9
+MDtzPHQ7KytzKXtyPWFbc10Kci50b1N0cmluZwpxPUouVTYocikKcD1xLmdBKHIpCmlmKDA+cClILnZo
+KFAuVEUoMCwwLHEuZ0EociksbnVsbCxudWxsKSkKaWYoSC5tMihyLCIvIiwwKSl7dD1QLkw0KCJJbGxl
+Z2FsIHBhdGggY2hhcmFjdGVyICIrSC5kKHIpKQp0aHJvdyBILmIodCl9fX0sCkhOOmZ1bmN0aW9uKGEs
+YixjKXt2YXIgdCxzLHIKZm9yKHQ9SC5xQyhhLGMsbnVsbCxILnQ2KGEpLmMpLHQ9bmV3IEguYTcodCx0
+LmdBKHQpLHQuJHRpLkMoImE3PGFMLkU+IikpO3QuRigpOyl7cz10LmQKcj1QLm51KCdbIiovOjw+P1xc
+XFx8XScpCnMudG9TdHJpbmcKaWYoSC5tMihzLHIsMCkpe3Q9UC5MNCgiSWxsZWdhbCBjaGFyYWN0ZXIg
+aW4gcGF0aDogIitzKQp0aHJvdyBILmIodCl9fX0sCnJnOmZ1bmN0aW9uKGEsYil7dmFyIHQKaWYoISg2
+NTw9YSYmYTw9OTApKXQ9OTc8PWEmJmE8PTEyMgplbHNlIHQ9ITAKaWYodClyZXR1cm4KdD1QLkw0KCJJ
+bGxlZ2FsIGRyaXZlIGxldHRlciAiK1AuT28oYSkpCnRocm93IEguYih0KX0sCndCOmZ1bmN0aW9uKGEs
+Yil7aWYoYSE9bnVsbCYmYT09PVAud0soYikpcmV0dXJuIG51bGwKcmV0dXJuIGF9LApPZTpmdW5jdGlv
+bihhLGIsYyxkKXt2YXIgdCxzLHIscSxwLG8KaWYoYT09bnVsbClyZXR1cm4gbnVsbAppZihiPT09Yyly
+ZXR1cm4iIgppZihDLnhCLm0oYSxiKT09PTkxKXt0PWMtMQppZihDLnhCLm0oYSx0KSE9PTkzKVAuUjMo
+YSxiLCJNaXNzaW5nIGVuZCBgXWAgdG8gbWF0Y2ggYFtgIGluIGhvc3QiKQpzPWIrMQpyPVAudG8oYSxz
+LHQpCmlmKHI8dCl7cT1yKzEKcD1QLk9BKGEsQy54Qi5RaShhLCIyNSIscSk/ciszOnEsdCwiJTI1Iil9
+ZWxzZSBwPSIiClAuZWcoYSxzLHIpCnJldHVybiBDLnhCLk5qKGEsYixyKS50b0xvd2VyQ2FzZSgpK3Ar
+Il0ifWZvcihvPWI7bzxjOysrbylpZihDLnhCLm0oYSxvKT09PTU4KXtyPUMueEIuWFUoYSwiJSIsYikK
+cj1yPj1iJiZyPGM/cjpjCmlmKHI8Yyl7cT1yKzEKcD1QLk9BKGEsQy54Qi5RaShhLCIyNSIscSk/cisz
+OnEsYywiJTI1Iil9ZWxzZSBwPSIiClAuZWcoYSxiLHIpCnJldHVybiJbIitDLnhCLk5qKGEsYixyKStw
+KyJdIn1yZXR1cm4gUC5PTChhLGIsYyl9LAp0bzpmdW5jdGlvbihhLGIsYyl7dmFyIHQ9Qy54Qi5YVShh
+LCIlIixiKQpyZXR1cm4gdD49YiYmdDxjP3Q6Y30sCk9BOmZ1bmN0aW9uKGEsYixjLGQpe3ZhciB0LHMs
+cixxLHAsbyxuLG0sbCxrLGo9ZCE9PSIiP25ldyBQLlJuKGQpOm51bGwKZm9yKHQ9YixzPXQscj0hMDt0
+PGM7KXtxPUMueEIubShhLHQpCmlmKHE9PT0zNyl7cD1QLnJ2KGEsdCwhMCkKbz1wPT1udWxsCmlmKG8m
+JnIpe3QrPTMKY29udGludWV9aWYoaj09bnVsbClqPW5ldyBQLlJuKCIiKQpuPWouYSs9Qy54Qi5Oaihh
+LHMsdCkKaWYobylwPUMueEIuTmooYSx0LHQrMykKZWxzZSBpZihwPT09IiUiKVAuUjMoYSx0LCJab25l
+SUQgc2hvdWxkIG5vdCBjb250YWluICUgYW55bW9yZSIpCmouYT1uK3AKdCs9MwpzPXQKcj0hMH1lbHNl
+e2lmKHE8MTI3KXtvPXE+Pj40CmlmKG8+PTgpcmV0dXJuIEguayhDLkYzLG8pCm89KEMuRjNbb10mMTw8
+KHEmMTUpKSE9PTB9ZWxzZSBvPSExCmlmKG8pe2lmKHImJjY1PD1xJiY5MD49cSl7aWYoaj09bnVsbClq
+PW5ldyBQLlJuKCIiKQppZihzPHQpe2ouYSs9Qy54Qi5OaihhLHMsdCkKcz10fXI9ITF9Kyt0fWVsc2V7
+aWYoKHEmNjQ1MTIpPT09NTUyOTYmJnQrMTxjKXttPUMueEIubShhLHQrMSkKaWYoKG0mNjQ1MTIpPT09
+NTYzMjApe3E9NjU1MzZ8KHEmMTAyMyk8PDEwfG0mMTAyMwpsPTJ9ZWxzZSBsPTF9ZWxzZSBsPTEKaz1D
+LnhCLk5qKGEscyx0KQppZihqPT1udWxsKXtqPW5ldyBQLlJuKCIiKQpvPWp9ZWxzZSBvPWoKby5hKz1r
+Cm8uYSs9UC56WChxKQp0Kz1sCnM9dH19fWlmKGo9PW51bGwpcmV0dXJuIEMueEIuTmooYSxiLGMpCmlm
+KHM8YylqLmErPUMueEIuTmooYSxzLGMpCm89ai5hCnJldHVybiBvLmNoYXJDb2RlQXQoMCk9PTA/bzpv
+fSwKT0w6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0LHMscixxLHAsbyxuLG0sbCxrLGoKZm9yKHQ9YixzPXQs
+cj1udWxsLHE9ITA7dDxjOyl7cD1DLnhCLm0oYSx0KQppZihwPT09Mzcpe289UC5ydihhLHQsITApCm49
+bz09bnVsbAppZihuJiZxKXt0Kz0zCmNvbnRpbnVlfWlmKHI9PW51bGwpcj1uZXcgUC5SbigiIikKbT1D
+LnhCLk5qKGEscyx0KQpsPXIuYSs9IXE/bS50b0xvd2VyQ2FzZSgpOm0KaWYobil7bz1DLnhCLk5qKGEs
+dCx0KzMpCms9M31lbHNlIGlmKG89PT0iJSIpe289IiUyNSIKaz0xfWVsc2Ugaz0zCnIuYT1sK28KdCs9
+awpzPXQKcT0hMH1lbHNle2lmKHA8MTI3KXtuPXA+Pj40CmlmKG4+PTgpcmV0dXJuIEguayhDLmVhLG4p
+Cm49KEMuZWFbbl0mMTw8KHAmMTUpKSE9PTB9ZWxzZSBuPSExCmlmKG4pe2lmKHEmJjY1PD1wJiY5MD49
+cCl7aWYocj09bnVsbClyPW5ldyBQLlJuKCIiKQppZihzPHQpe3IuYSs9Qy54Qi5OaihhLHMsdCkKcz10
+fXE9ITF9Kyt0fWVsc2V7aWYocDw9OTMpe249cD4+PjQKaWYobj49OClyZXR1cm4gSC5rKEMuYWssbikK
+bj0oQy5ha1tuXSYxPDwocCYxNSkpIT09MH1lbHNlIG49ITEKaWYobilQLlIzKGEsdCwiSW52YWxpZCBj
+aGFyYWN0ZXIiKQplbHNle2lmKChwJjY0NTEyKT09PTU1Mjk2JiZ0KzE8Yyl7aj1DLnhCLm0oYSx0KzEp
+CmlmKChqJjY0NTEyKT09PTU2MzIwKXtwPTY1NTM2fChwJjEwMjMpPDwxMHxqJjEwMjMKaz0yfWVsc2Ug
+az0xfWVsc2Ugaz0xCm09Qy54Qi5OaihhLHMsdCkKaWYoIXEpbT1tLnRvTG93ZXJDYXNlKCkKaWYocj09
+bnVsbCl7cj1uZXcgUC5SbigiIikKbj1yfWVsc2Ugbj1yCm4uYSs9bQpuLmErPVAuelgocCkKdCs9awpz
+PXR9fX19aWYocj09bnVsbClyZXR1cm4gQy54Qi5OaihhLGIsYykKaWYoczxjKXttPUMueEIuTmooYSxz
+LGMpCnIuYSs9IXE/bS50b0xvd2VyQ2FzZSgpOm19bj1yLmEKcmV0dXJuIG4uY2hhckNvZGVBdCgwKT09
+MD9uOm59LApQaTpmdW5jdGlvbihhLGIsYyl7dmFyIHQscyxyLHEKaWYoYj09PWMpcmV0dXJuIiIKaWYo
+IVAuRXQoSi5yWShhKS5XKGEsYikpKVAuUjMoYSxiLCJTY2hlbWUgbm90IHN0YXJ0aW5nIHdpdGggYWxw
+aGFiZXRpYyBjaGFyYWN0ZXIiKQpmb3IodD1iLHM9ITE7dDxjOysrdCl7cj1DLnhCLlcoYSx0KQppZihy
+PDEyOCl7cT1yPj4+NAppZihxPj04KXJldHVybiBILmsoQy5tSyxxKQpxPShDLm1LW3FdJjE8PChyJjE1
+KSkhPT0wfWVsc2UgcT0hMQppZighcSlQLlIzKGEsdCwiSWxsZWdhbCBzY2hlbWUgY2hhcmFjdGVyIikK
+aWYoNjU8PXImJnI8PTkwKXM9ITB9YT1DLnhCLk5qKGEsYixjKQpyZXR1cm4gUC5ZYShzP2EudG9Mb3dl
+ckNhc2UoKTphKX0sCllhOmZ1bmN0aW9uKGEpe2lmKGE9PT0iaHR0cCIpcmV0dXJuImh0dHAiCmlmKGE9
+PT0iZmlsZSIpcmV0dXJuImZpbGUiCmlmKGE9PT0iaHR0cHMiKXJldHVybiJodHRwcyIKaWYoYT09PSJw
+YWNrYWdlIilyZXR1cm4icGFja2FnZSIKcmV0dXJuIGF9LAp6UjpmdW5jdGlvbihhLGIsYyl7aWYoYT09
+bnVsbClyZXR1cm4iIgpyZXR1cm4gUC5QSShhLGIsYyxDLnRvLCExKX0sCmthOmZ1bmN0aW9uKGEsYixj
+LGQsZSxmKXt2YXIgdCxzLHI9ZT09PSJmaWxlIixxPXJ8fGYKaWYoYT09bnVsbCl7aWYoZD09bnVsbCly
+ZXR1cm4gcj8iLyI6IiIKdD1ILnQ2KGQpCnM9bmV3IEgubEooZCx0LkMoInFVKDEpIikuYShuZXcgUC5S
+WigpKSx0LkMoImxKPDEscVU+IikpLnpWKDAsIi8iKX1lbHNlIGlmKGQhPW51bGwpdGhyb3cgSC5iKFAu
+eFkoIkJvdGggcGF0aCBhbmQgcGF0aFNlZ21lbnRzIHNwZWNpZmllZCIpKQplbHNlIHM9UC5QSShhLGIs
+YyxDLldkLCEwKQppZihzLmxlbmd0aD09PTApe2lmKHIpcmV0dXJuIi8ifWVsc2UgaWYocSYmIUMueEIu
+bihzLCIvIikpcz0iLyIrcwpyZXR1cm4gUC5KcihzLGUsZil9LApKcjpmdW5jdGlvbihhLGIsYyl7dmFy
+IHQ9Yi5sZW5ndGg9PT0wCmlmKHQmJiFjJiYhQy54Qi5uKGEsIi8iKSlyZXR1cm4gUC53RihhLCF0fHxj
+KQpyZXR1cm4gUC54ZShhKX0sCmxlOmZ1bmN0aW9uKGEsYixjLGQpe3ZhciB0LHM9e30KaWYoYSE9bnVs
+bCl7aWYoZCE9bnVsbCl0aHJvdyBILmIoUC54WSgiQm90aCBxdWVyeSBhbmQgcXVlcnlQYXJhbWV0ZXJz
+IHNwZWNpZmllZCIpKQpyZXR1cm4gUC5QSShhLGIsYyxDLlZDLCEwKX1pZihkPT1udWxsKXJldHVybiBu
+dWxsCnQ9bmV3IFAuUm4oIiIpCnMuYT0iIgpkLksoMCxuZXcgUC55NShuZXcgUC5NRShzLHQpKSkKcz10
+LmEKcmV0dXJuIHMuY2hhckNvZGVBdCgwKT09MD9zOnN9LAp0RzpmdW5jdGlvbihhLGIsYyl7aWYoYT09
+bnVsbClyZXR1cm4gbnVsbApyZXR1cm4gUC5QSShhLGIsYyxDLlZDLCEwKX0sCnJ2OmZ1bmN0aW9uKGEs
+YixjKXt2YXIgdCxzLHIscSxwLG89YisyCmlmKG8+PWEubGVuZ3RoKXJldHVybiIlIgp0PUMueEIubShh
+LGIrMSkKcz1DLnhCLm0oYSxvKQpyPUgub28odCkKcT1ILm9vKHMpCmlmKHI8MHx8cTwwKXJldHVybiIl
+IgpwPXIqMTYrcQppZihwPDEyNyl7bz1DLmpuLndHKHAsNCkKaWYobz49OClyZXR1cm4gSC5rKEMuRjMs
+bykKbz0oQy5GM1tvXSYxPDwocCYxNSkpIT09MH1lbHNlIG89ITEKaWYobylyZXR1cm4gSC5MdyhjJiY2
+NTw9cCYmOTA+PXA/KHB8MzIpPj4+MDpwKQppZih0Pj05N3x8cz49OTcpcmV0dXJuIEMueEIuTmooYSxi
+LGIrMykudG9VcHBlckNhc2UoKQpyZXR1cm4gbnVsbH0sCnpYOmZ1bmN0aW9uKGEpe3ZhciB0LHMscixx
+LHAsbyxuLG0sbD0iMDEyMzQ1Njc4OUFCQ0RFRiIKaWYoYTwxMjgpe3Q9bmV3IFVpbnQ4QXJyYXkoMykK
+cz10Lmxlbmd0aAppZigwPj1zKXJldHVybiBILmsodCwwKQp0WzBdPTM3CnI9Qy54Qi5XKGwsYT4+PjQp
+CmlmKDE+PXMpcmV0dXJuIEguayh0LDEpCnRbMV09cgpyPUMueEIuVyhsLGEmMTUpCmlmKDI+PXMpcmV0
+dXJuIEguayh0LDIpCnRbMl09cn1lbHNle2lmKGE+MjA0NylpZihhPjY1NTM1KXtxPTI0MApwPTR9ZWxz
+ZXtxPTIyNApwPTN9ZWxzZXtxPTE5MgpwPTJ9dD1uZXcgVWludDhBcnJheSgzKnApCmZvcihzPXQubGVu
+Z3RoLG89MDstLXAscD49MDtxPTEyOCl7bj1DLmpuLmJmKGEsNipwKSY2M3xxCmlmKG8+PXMpcmV0dXJu
+IEguayh0LG8pCnRbb109MzcKcj1vKzEKbT1DLnhCLlcobCxuPj4+NCkKaWYocj49cylyZXR1cm4gSC5r
+KHQscikKdFtyXT1tCm09bysyCnI9Qy54Qi5XKGwsbiYxNSkKaWYobT49cylyZXR1cm4gSC5rKHQsbSkK
+dFttXT1yCm8rPTN9fXJldHVybiBQLkhNKHQsMCxudWxsKX0sClBJOmZ1bmN0aW9uKGEsYixjLGQsZSl7
+dmFyIHQ9UC5VbChhLGIsYyxkLGUpCnJldHVybiB0PT1udWxsP0MueEIuTmooYSxiLGMpOnR9LApVbDpm
+dW5jdGlvbihhLGIsYyxkLGUpe3ZhciB0LHMscixxLHAsbyxuLG0sbCxrPW51bGwKZm9yKHQ9IWUscz1i
+LHI9cyxxPWs7czxjOyl7cD1DLnhCLm0oYSxzKQppZihwPDEyNyl7bz1wPj4+NAppZihvPj04KXJldHVy
+biBILmsoZCxvKQpvPShkW29dJjE8PChwJjE1KSkhPT0wfWVsc2Ugbz0hMQppZihvKSsrcwplbHNle2lm
+KHA9PT0zNyl7bj1QLnJ2KGEscywhMSkKaWYobj09bnVsbCl7cys9Mwpjb250aW51ZX1pZigiJSI9PT1u
+KXtuPSIlMjUiCm09MX1lbHNlIG09M31lbHNle2lmKHQpaWYocDw9OTMpe289cD4+PjQKaWYobz49OCly
+ZXR1cm4gSC5rKEMuYWssbykKbz0oQy5ha1tvXSYxPDwocCYxNSkpIT09MH1lbHNlIG89ITEKZWxzZSBv
+PSExCmlmKG8pe1AuUjMoYSxzLCJJbnZhbGlkIGNoYXJhY3RlciIpCm09awpuPW19ZWxzZXtpZigocCY2
+NDUxMik9PT01NTI5Nil7bz1zKzEKaWYobzxjKXtsPUMueEIubShhLG8pCmlmKChsJjY0NTEyKT09PTU2
+MzIwKXtwPTY1NTM2fChwJjEwMjMpPDwxMHxsJjEwMjMKbT0yfWVsc2UgbT0xfWVsc2UgbT0xfWVsc2Ug
+bT0xCm49UC56WChwKX19aWYocT09bnVsbCl7cT1uZXcgUC5SbigiIikKbz1xfWVsc2Ugbz1xCm8uYSs9
+Qy54Qi5OaihhLHIscykKby5hKz1ILmQobikKaWYodHlwZW9mIG0hPT0ibnVtYmVyIilyZXR1cm4gSC5w
+WShtKQpzKz1tCnI9c319aWYocT09bnVsbClyZXR1cm4gawppZihyPGMpcS5hKz1DLnhCLk5qKGEscixj
+KQp0PXEuYQpyZXR1cm4gdC5jaGFyQ29kZUF0KDApPT0wP3Q6dH0sCnlCOmZ1bmN0aW9uKGEpe2lmKEMu
+eEIubihhLCIuIikpcmV0dXJuITAKcmV0dXJuIEMueEIuT1koYSwiLy4iKSE9PS0xfSwKeGU6ZnVuY3Rp
+b24oYSl7dmFyIHQscyxyLHEscCxvLG4KaWYoIVAueUIoYSkpcmV0dXJuIGEKdD1ILlZNKFtdLHUucykK
+Zm9yKHM9YS5zcGxpdCgiLyIpLHI9cy5sZW5ndGgscT0hMSxwPTA7cDxyOysrcCl7bz1zW3BdCmlmKEou
+Uk0obywiLi4iKSl7bj10Lmxlbmd0aAppZihuIT09MCl7aWYoMD49bilyZXR1cm4gSC5rKHQsLTEpCnQu
+cG9wKCkKaWYodC5sZW5ndGg9PT0wKUMuTm0uaSh0LCIiKX1xPSEwfWVsc2UgaWYoIi4iPT09bylxPSEw
+CmVsc2V7Qy5ObS5pKHQsbykKcT0hMX19aWYocSlDLk5tLmkodCwiIikKcmV0dXJuIEMuTm0uelYodCwi
+LyIpfSwKd0Y6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzLHIscSxwLG8KaWYoIVAueUIoYSkpcmV0dXJuIWI/
+UC5DMShhKTphCnQ9SC5WTShbXSx1LnMpCmZvcihzPWEuc3BsaXQoIi8iKSxyPXMubGVuZ3RoLHE9ITEs
+cD0wO3A8cjsrK3Ape289c1twXQppZigiLi4iPT09bylpZih0Lmxlbmd0aCE9PTAmJkMuTm0uZ3JaKHQp
+IT09Ii4uIil7aWYoMD49dC5sZW5ndGgpcmV0dXJuIEguayh0LC0xKQp0LnBvcCgpCnE9ITB9ZWxzZXtD
+Lk5tLmkodCwiLi4iKQpxPSExfWVsc2UgaWYoIi4iPT09bylxPSEwCmVsc2V7Qy5ObS5pKHQsbykKcT0h
+MX19cz10Lmxlbmd0aAppZihzIT09MClpZihzPT09MSl7aWYoMD49cylyZXR1cm4gSC5rKHQsMCkKcz10
+WzBdLmxlbmd0aD09PTB9ZWxzZSBzPSExCmVsc2Ugcz0hMAppZihzKXJldHVybiIuLyIKaWYocXx8Qy5O
+bS5ncloodCk9PT0iLi4iKUMuTm0uaSh0LCIiKQppZighYil7aWYoMD49dC5sZW5ndGgpcmV0dXJuIEgu
+ayh0LDApCkMuTm0uWSh0LDAsUC5DMSh0WzBdKSl9cmV0dXJuIEMuTm0uelYodCwiLyIpfSwKQzE6ZnVu
+Y3Rpb24oYSl7dmFyIHQscyxyLHE9YS5sZW5ndGgKaWYocT49MiYmUC5FdChKLlF6KGEsMCkpKWZvcih0
+PTE7dDxxOysrdCl7cz1DLnhCLlcoYSx0KQppZihzPT09NTgpcmV0dXJuIEMueEIuTmooYSwwLHQpKyIl
+M0EiK0MueEIuRyhhLHQrMSkKaWYoczw9MTI3KXtyPXM+Pj40CmlmKHI+PTgpcmV0dXJuIEguayhDLm1L
+LHIpCnI9KEMubUtbcl0mMTw8KHMmMTUpKT09PTB9ZWxzZSByPSEwCmlmKHIpYnJlYWt9cmV0dXJuIGF9
+LAptbjpmdW5jdGlvbihhKXt2YXIgdCxzLHIscT1hLmdGaigpLHA9cS5sZW5ndGgKaWYocD4wJiZKLkgo
+cVswXSk9PT0yJiZKLmE2KHFbMF0sMSk9PT01OCl7aWYoMD49cClyZXR1cm4gSC5rKHEsMCkKUC5yZyhK
+LmE2KHFbMF0sMCksITEpClAuSE4ocSwhMSwxKQp0PSEwfWVsc2V7UC5ITihxLCExLDApCnQ9ITF9cz1h
+Lmd0VCgpJiYhdD8iXFwiOiIiCmlmKGEuZ2NqKCkpe3I9YS5nSmYoYSkKaWYoci5sZW5ndGghPT0wKXM9
+cysiXFwiK3IrIlxcIn1zPVAudmcocyxxLCJcXCIpCnA9dCYmcD09PTE/cysiXFwiOnMKcmV0dXJuIHAu
+Y2hhckNvZGVBdCgwKT09MD9wOnB9LApJaDpmdW5jdGlvbihhLGIpe3ZhciB0LHMscgpmb3IodD0wLHM9
+MDtzPDI7KytzKXtyPUMueEIuVyhhLGIrcykKaWYoNDg8PXImJnI8PTU3KXQ9dCoxNityLTQ4CmVsc2V7
+cnw9MzIKaWYoOTc8PXImJnI8PTEwMil0PXQqMTYrci04NwplbHNlIHRocm93IEguYihQLnhZKCJJbnZh
+bGlkIFVSTCBlbmNvZGluZyIpKX19cmV0dXJuIHR9LAprdTpmdW5jdGlvbihhLGIsYyxkLGUpe3ZhciB0
+LHMscixxLHA9Si5yWShhKSxvPWIKd2hpbGUoITApe2lmKCEobzxjKSl7dD0hMApicmVha31zPXAuVyhh
+LG8pCmlmKHM8PTEyNylpZihzIT09Mzcpcj1lJiZzPT09NDMKZWxzZSByPSEwCmVsc2Ugcj0hMAppZihy
+KXt0PSExCmJyZWFrfSsrb31pZih0KXtpZihDLnhNIT09ZClyPSExCmVsc2Ugcj0hMAppZihyKXJldHVy
+biBwLk5qKGEsYixjKQplbHNlIHE9bmV3IEgucWoocC5OaihhLGIsYykpfWVsc2V7cT1ILlZNKFtdLHUu
+dCkKZm9yKG89YjtvPGM7KytvKXtzPXAuVyhhLG8pCmlmKHM+MTI3KXRocm93IEguYihQLnhZKCJJbGxl
+Z2FsIHBlcmNlbnQgZW5jb2RpbmcgaW4gVVJJIikpCmlmKHM9PT0zNyl7aWYobyszPmEubGVuZ3RoKXRo
+cm93IEguYihQLnhZKCJUcnVuY2F0ZWQgVVJJIikpCkMuTm0uaShxLFAuSWgoYSxvKzEpKQpvKz0yfWVs
+c2UgaWYoZSYmcz09PTQzKUMuTm0uaShxLDMyKQplbHNlIEMuTm0uaShxLHMpfX11LkwuYShxKQpyZXR1
+cm4gbmV3IFAuR1koITEpLldKKHEpfSwKRXQ6ZnVuY3Rpb24oYSl7dmFyIHQ9YXwzMgpyZXR1cm4gOTc8
+PXQmJnQ8PTEyMn0sCktEOmZ1bmN0aW9uKGEsYixjKXt2YXIgdCxzLHIscSxwLG8sbixtLGw9IkludmFs
+aWQgTUlNRSB0eXBlIixrPUguVk0oW2ItMV0sdS50KQpmb3IodD1hLmxlbmd0aCxzPWIscj0tMSxxPW51
+bGw7czx0Oysrcyl7cT1DLnhCLlcoYSxzKQppZihxPT09NDR8fHE9PT01OSlicmVhawppZihxPT09NDcp
+e2lmKHI8MCl7cj1zCmNvbnRpbnVlfXRocm93IEguYihQLnJyKGwsYSxzKSl9fWlmKHI8MCYmcz5iKXRo
+cm93IEguYihQLnJyKGwsYSxzKSkKZm9yKDtxIT09NDQ7KXtDLk5tLmkoayxzKTsrK3MKZm9yKHA9LTE7
+czx0Oysrcyl7cT1DLnhCLlcoYSxzKQppZihxPT09NjEpe2lmKHA8MClwPXN9ZWxzZSBpZihxPT09NTl8
+fHE9PT00NClicmVha31pZihwPj0wKUMuTm0uaShrLHApCmVsc2V7bz1DLk5tLmdyWihrKQppZihxIT09
+NDR8fHMhPT1vKzd8fCFDLnhCLlFpKGEsImJhc2U2NCIsbysxKSl0aHJvdyBILmIoUC5ycigiRXhwZWN0
+aW5nICc9JyIsYSxzKSkKYnJlYWt9fUMuTm0uaShrLHMpCm49cysxCmlmKChrLmxlbmd0aCYxKT09PTEp
+YT1DLmg5LnlyKGEsbix0KQplbHNle209UC5VbChhLG4sdCxDLlZDLCEwKQppZihtIT1udWxsKWE9Qy54
+Qi5pNyhhLG4sdCxtKX1yZXR1cm4gbmV3IFAuUEUoYSxrLGMpfSwKS046ZnVuY3Rpb24oKXt2YXIgdD0i
+MDEyMzQ1Njc4OUFCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4
+eXotLl9+ISQmJygpKissOz0iLHM9Ii4iLHI9IjoiLHE9Ii8iLHA9Ij8iLG89IiMiLG49dS5nYyxtPVAu
+ZEgoMjIsbmV3IFAucTMoKSwhMCxuKSxsPW5ldyBQLnlJKG0pLGs9bmV3IFAuYzYoKSxqPW5ldyBQLnFk
+KCksaT1uLmEobC4kMigwLDIyNSkpCmsuJDMoaSx0LDEpCmsuJDMoaSxzLDE0KQprLiQzKGksciwzNCkK
+ay4kMyhpLHEsMykKay4kMyhpLHAsMTcyKQprLiQzKGksbywyMDUpCmk9bi5hKGwuJDIoMTQsMjI1KSkK
+ay4kMyhpLHQsMSkKay4kMyhpLHMsMTUpCmsuJDMoaSxyLDM0KQprLiQzKGkscSwyMzQpCmsuJDMoaSxw
+LDE3MikKay4kMyhpLG8sMjA1KQppPW4uYShsLiQyKDE1LDIyNSkpCmsuJDMoaSx0LDEpCmsuJDMoaSwi
+JSIsMjI1KQprLiQzKGksciwzNCkKay4kMyhpLHEsOSkKay4kMyhpLHAsMTcyKQprLiQzKGksbywyMDUp
+Cmk9bi5hKGwuJDIoMSwyMjUpKQprLiQzKGksdCwxKQprLiQzKGksciwzNCkKay4kMyhpLHEsMTApCmsu
+JDMoaSxwLDE3MikKay4kMyhpLG8sMjA1KQppPW4uYShsLiQyKDIsMjM1KSkKay4kMyhpLHQsMTM5KQpr
+LiQzKGkscSwxMzEpCmsuJDMoaSxzLDE0NikKay4kMyhpLHAsMTcyKQprLiQzKGksbywyMDUpCmk9bi5h
+KGwuJDIoMywyMzUpKQprLiQzKGksdCwxMSkKay4kMyhpLHEsNjgpCmsuJDMoaSxzLDE4KQprLiQzKGks
+cCwxNzIpCmsuJDMoaSxvLDIwNSkKaT1uLmEobC4kMig0LDIyOSkpCmsuJDMoaSx0LDUpCmouJDMoaSwi
+QVoiLDIyOSkKay4kMyhpLHIsMTAyKQprLiQzKGksIkAiLDY4KQprLiQzKGksIlsiLDIzMikKay4kMyhp
+LHEsMTM4KQprLiQzKGkscCwxNzIpCmsuJDMoaSxvLDIwNSkKaT1uLmEobC4kMig1LDIyOSkpCmsuJDMo
+aSx0LDUpCmouJDMoaSwiQVoiLDIyOSkKay4kMyhpLHIsMTAyKQprLiQzKGksIkAiLDY4KQprLiQzKGks
+cSwxMzgpCmsuJDMoaSxwLDE3MikKay4kMyhpLG8sMjA1KQppPW4uYShsLiQyKDYsMjMxKSkKai4kMyhp
+LCIxOSIsNykKay4kMyhpLCJAIiw2OCkKay4kMyhpLHEsMTM4KQprLiQzKGkscCwxNzIpCmsuJDMoaSxv
+LDIwNSkKaT1uLmEobC4kMig3LDIzMSkpCmouJDMoaSwiMDkiLDcpCmsuJDMoaSwiQCIsNjgpCmsuJDMo
+aSxxLDEzOCkKay4kMyhpLHAsMTcyKQprLiQzKGksbywyMDUpCmsuJDMobi5hKGwuJDIoOCw4KSksIl0i
+LDUpCmk9bi5hKGwuJDIoOSwyMzUpKQprLiQzKGksdCwxMSkKay4kMyhpLHMsMTYpCmsuJDMoaSxxLDIz
+NCkKay4kMyhpLHAsMTcyKQprLiQzKGksbywyMDUpCmk9bi5hKGwuJDIoMTYsMjM1KSkKay4kMyhpLHQs
+MTEpCmsuJDMoaSxzLDE3KQprLiQzKGkscSwyMzQpCmsuJDMoaSxwLDE3MikKay4kMyhpLG8sMjA1KQpp
+PW4uYShsLiQyKDE3LDIzNSkpCmsuJDMoaSx0LDExKQprLiQzKGkscSw5KQprLiQzKGkscCwxNzIpCmsu
+JDMoaSxvLDIwNSkKaT1uLmEobC4kMigxMCwyMzUpKQprLiQzKGksdCwxMSkKay4kMyhpLHMsMTgpCmsu
+JDMoaSxxLDIzNCkKay4kMyhpLHAsMTcyKQprLiQzKGksbywyMDUpCmk9bi5hKGwuJDIoMTgsMjM1KSkK
+ay4kMyhpLHQsMTEpCmsuJDMoaSxzLDE5KQprLiQzKGkscSwyMzQpCmsuJDMoaSxwLDE3MikKay4kMyhp
+LG8sMjA1KQppPW4uYShsLiQyKDE5LDIzNSkpCmsuJDMoaSx0LDExKQprLiQzKGkscSwyMzQpCmsuJDMo
+aSxwLDE3MikKay4kMyhpLG8sMjA1KQppPW4uYShsLiQyKDExLDIzNSkpCmsuJDMoaSx0LDExKQprLiQz
+KGkscSwxMCkKay4kMyhpLHAsMTcyKQprLiQzKGksbywyMDUpCmk9bi5hKGwuJDIoMTIsMjM2KSkKay4k
+MyhpLHQsMTIpCmsuJDMoaSxwLDEyKQprLiQzKGksbywyMDUpCmk9bi5hKGwuJDIoMTMsMjM3KSkKay4k
+MyhpLHQsMTMpCmsuJDMoaSxwLDEzKQpqLiQzKG4uYShsLiQyKDIwLDI0NSkpLCJheiIsMjEpCmw9bi5h
+KGwuJDIoMjEsMjQ1KSkKai4kMyhsLCJheiIsMjEpCmouJDMobCwiMDkiLDIxKQprLiQzKGwsIistLiIs
+MjEpCnJldHVybiBtfSwKVUI6ZnVuY3Rpb24oYSxiLGMsZCxlKXt2YXIgdCxzLHIscSxwLG89JC52Wigp
+CmZvcih0PUouclkoYSkscz1iO3M8YzsrK3Mpe2lmKGQ8MHx8ZD49by5sZW5ndGgpcmV0dXJuIEguayhv
+LGQpCnI9b1tkXQpxPXQuVyhhLHMpXjk2CmlmKHE+OTUpcT0zMQppZihxPj1yLmxlbmd0aClyZXR1cm4g
+SC5rKHIscSkKcD1yW3FdCmQ9cCYzMQpDLk5tLlkoZSxwPj4+NSxzKX1yZXR1cm4gZH0sCldGOmZ1bmN0
+aW9uIFdGKGEsYil7dGhpcy5hPWEKdGhpcy5iPWJ9LAphMjpmdW5jdGlvbiBhMigpe30sCmlQOmZ1bmN0
+aW9uIGlQKGEsYil7dGhpcy5hPWEKdGhpcy5iPWJ9LApDUDpmdW5jdGlvbiBDUCgpe30sClhTOmZ1bmN0
+aW9uIFhTKCl7fSwKQzY6ZnVuY3Rpb24gQzYoYSl7dGhpcy5hPWF9LApMSzpmdW5jdGlvbiBMSygpe30s
+CkFUOmZ1bmN0aW9uIEFUKGEsYixjLGQpe3ZhciBfPXRoaXMKXy5hPWEKXy5iPWIKXy5jPWMKXy5kPWR9
+LApiSjpmdW5jdGlvbiBiSihhLGIsYyxkLGUsZil7dmFyIF89dGhpcwpfLmU9YQpfLmY9YgpfLmE9Ywpf
+LmI9ZApfLmM9ZQpfLmQ9Zn0sCmVZOmZ1bmN0aW9uIGVZKGEsYixjLGQsZSl7dmFyIF89dGhpcwpfLmY9
+YQpfLmE9YgpfLmI9YwpfLmM9ZApfLmQ9ZX0sCm1wOmZ1bmN0aW9uIG1wKGEsYixjLGQpe3ZhciBfPXRo
+aXMKXy5hPWEKXy5iPWIKXy5jPWMKXy5kPWR9LAp1YjpmdW5jdGlvbiB1YihhKXt0aGlzLmE9YX0sCmRz
+OmZ1bmN0aW9uIGRzKGEpe3RoaXMuYT1hfSwKbGo6ZnVuY3Rpb24gbGooYSl7dGhpcy5hPWF9LApVVjpm
+dW5jdGlvbiBVVihhKXt0aGlzLmE9YX0sCms1OmZ1bmN0aW9uIGs1KCl7fSwKS1k6ZnVuY3Rpb24gS1ko
+KXt9LAp0NzpmdW5jdGlvbiB0NyhhKXt0aGlzLmE9YX0sCkNEOmZ1bmN0aW9uIENEKGEpe3RoaXMuYT1h
+fSwKYUU6ZnVuY3Rpb24gYUUoYSxiLGMpe3RoaXMuYT1hCnRoaXMuYj1iCnRoaXMuYz1jfSwKRUg6ZnVu
+Y3Rpb24gRUgoKXt9LApJZjpmdW5jdGlvbiBJZigpe30sCmNYOmZ1bmN0aW9uIGNYKCl7fSwKQW46ZnVu
+Y3Rpb24gQW4oKXt9LAp6TTpmdW5jdGlvbiB6TSgpe30sClowOmZ1bmN0aW9uIFowKCl7fSwKTjM6ZnVu
+Y3Rpb24gTjMoYSxiLGMpe3RoaXMuYT1hCnRoaXMuYj1iCnRoaXMuJHRpPWN9LApjODpmdW5jdGlvbiBj
+OCgpe30sCmxmOmZ1bmN0aW9uIGxmKCl7fSwKTWg6ZnVuY3Rpb24gTWgoKXt9LApPZDpmdW5jdGlvbiBP
+ZCgpe30sCmliOmZ1bmN0aW9uIGliKCl7fSwKeHU6ZnVuY3Rpb24geHUoKXt9LApHejpmdW5jdGlvbiBH
+eigpe30sClpkOmZ1bmN0aW9uIFpkKCl7fSwKcVU6ZnVuY3Rpb24gcVUoKXt9LApSbjpmdW5jdGlvbiBS
+bihhKXt0aGlzLmE9YX0sCkdEOmZ1bmN0aW9uIEdEKCl7fSwKbjE6ZnVuY3Rpb24gbjEoYSl7dGhpcy5h
+PWF9LApjUzpmdW5jdGlvbiBjUyhhKXt0aGlzLmE9YX0sClZDOmZ1bmN0aW9uIFZDKGEpe3RoaXMuYT1h
+fSwKSlQ6ZnVuY3Rpb24gSlQoYSxiKXt0aGlzLmE9YQp0aGlzLmI9Yn0sCkRuOmZ1bmN0aW9uIERuKGEs
+YixjLGQsZSxmLGcpe3ZhciBfPXRoaXMKXy5hPWEKXy5iPWIKXy5jPWMKXy5kPWQKXy5lPWUKXy5mPWYK
+Xy5yPWcKXy5RPV8uej1fLnk9Xy54PW51bGx9LApSWjpmdW5jdGlvbiBSWigpe30sCk1FOmZ1bmN0aW9u
+IE1FKGEsYil7dGhpcy5hPWEKdGhpcy5iPWJ9LAp5NTpmdW5jdGlvbiB5NShhKXt0aGlzLmE9YX0sClBF
+OmZ1bmN0aW9uIFBFKGEsYixjKXt0aGlzLmE9YQp0aGlzLmI9Ygp0aGlzLmM9Y30sCnEzOmZ1bmN0aW9u
+IHEzKCl7fSwKeUk6ZnVuY3Rpb24geUkoYSl7dGhpcy5hPWF9LApjNjpmdW5jdGlvbiBjNigpe30sCnFk
+OmZ1bmN0aW9uIHFkKCl7fSwKVWY6ZnVuY3Rpb24gVWYoYSxiLGMsZCxlLGYsZyxoKXt2YXIgXz10aGlz
+Cl8uYT1hCl8uYj1iCl8uYz1jCl8uZD1kCl8uZT1lCl8uZj1mCl8ucj1nCl8ueD1oCl8ueT1udWxsfSwK
+cWU6ZnVuY3Rpb24gcWUoYSxiLGMsZCxlLGYsZyl7dmFyIF89dGhpcwpfLmE9YQpfLmI9YgpfLmM9Ywpf
+LmQ9ZApfLmU9ZQpfLmY9ZgpfLnI9ZwpfLlE9Xy56PV8ueT1fLng9bnVsbH0sCmlKOmZ1bmN0aW9uIGlK
+KCl7fSwKamc6ZnVuY3Rpb24gamcoYSxiKXt0aGlzLmE9YQp0aGlzLmI9Yn0sClRhOmZ1bmN0aW9uIFRh
+KGEsYil7dGhpcy5hPWEKdGhpcy5iPWJ9LApCZjpmdW5jdGlvbiBCZihhLGIpe3RoaXMuYT1hCnRoaXMu
+Yj1ifSwKQXM6ZnVuY3Rpb24gQXMoKXt9LApHRTpmdW5jdGlvbiBHRShhKXt0aGlzLmE9YX0sCk43OmZ1
+bmN0aW9uIE43KGEsYil7dGhpcy5hPWEKdGhpcy5iPWJ9LAp1UTpmdW5jdGlvbiB1USgpe30sCmhGOmZ1
+bmN0aW9uIGhGKCl7fSwKUjQ6ZnVuY3Rpb24oYSxiLGMsZCl7dmFyIHQscyxyCkguRTkoYikKdS5qLmEo
+ZCkKaWYoSC5vVChiKSl7dD1bY10KQy5ObS5GVih0LGQpCmQ9dH1zPXUuegpyPVAuQ0goSi5NMShkLFAu
+dzAoKSxzKSwhMCxzKQp1LlouYShhKQpyZXR1cm4gUC53WShILkVrKGEscixudWxsKSl9LApEbTpmdW5j
+dGlvbihhLGIsYyl7dmFyIHQKdHJ5e2lmKE9iamVjdC5pc0V4dGVuc2libGUoYSkmJiFPYmplY3QucHJv
+dG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoYSxiKSl7T2JqZWN0LmRlZmluZVByb3BlcnR5KGEsYix7
+dmFsdWU6Y30pCnJldHVybiEwfX1jYXRjaCh0KXtILlJ1KHQpfXJldHVybiExfSwKT206ZnVuY3Rpb24o
+YSxiKXtpZihPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoYSxiKSlyZXR1cm4gYVti
+XQpyZXR1cm4gbnVsbH0sCndZOmZ1bmN0aW9uKGEpe2lmKGE9PW51bGx8fHR5cGVvZiBhPT0ic3RyaW5n
+Inx8dHlwZW9mIGE9PSJudW1iZXIifHxILnJRKGEpKXJldHVybiBhCmlmKGEgaW5zdGFuY2VvZiBQLkU0
+KXJldHVybiBhLmEKaWYoSC5SOShhKSlyZXR1cm4gYQppZih1LncuYihhKSlyZXR1cm4gYQppZihhIGlu
+c3RhbmNlb2YgUC5pUClyZXR1cm4gSC5vMihhKQppZih1LlouYihhKSlyZXR1cm4gUC5oRShhLCIkZGFy
+dF9qc0Z1bmN0aW9uIixuZXcgUC5QQygpKQpyZXR1cm4gUC5oRShhLCJfJGRhcnRfanNPYmplY3QiLG5l
+dyBQLm10KCQua0koKSkpfSwKaEU6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0PVAuT20oYSxiKQppZih0PT1u
+dWxsKXt0PWMuJDEoYSkKUC5EbShhLGIsdCl9cmV0dXJuIHR9LApMNzpmdW5jdGlvbihhKXt2YXIgdCxz
+CmlmKGE9PW51bGx8fHR5cGVvZiBhPT0ic3RyaW5nInx8dHlwZW9mIGE9PSJudW1iZXIifHx0eXBlb2Yg
+YT09ImJvb2xlYW4iKXJldHVybiBhCmVsc2UgaWYoYSBpbnN0YW5jZW9mIE9iamVjdCYmSC5SOShhKSly
+ZXR1cm4gYQplbHNlIGlmKGEgaW5zdGFuY2VvZiBPYmplY3QmJnUudy5iKGEpKXJldHVybiBhCmVsc2Ug
+aWYoYSBpbnN0YW5jZW9mIERhdGUpe3Q9SC5XWShhLmdldFRpbWUoKSkKaWYoTWF0aC5hYnModCk8PTg2
+NGUxMylzPSExCmVsc2Ugcz0hMAppZihzKUgudmgoUC54WSgiRGF0ZVRpbWUgaXMgb3V0c2lkZSB2YWxp
+ZCByYW5nZTogIit0KSkKUC5VSSghMSwiaXNVdGMiLHUueSkKcmV0dXJuIG5ldyBQLmlQKHQsITEpfWVs
+c2UgaWYoYS5jb25zdHJ1Y3Rvcj09PSQua0koKSlyZXR1cm4gYS5vCmVsc2UgcmV0dXJuIFAuTkQoYSl9
+LApORDpmdW5jdGlvbihhKXtpZih0eXBlb2YgYT09ImZ1bmN0aW9uIilyZXR1cm4gUC5pUShhLCQud1Eo
+KSxuZXcgUC5OeigpKQppZihhIGluc3RhbmNlb2YgQXJyYXkpcmV0dXJuIFAuaVEoYSwkLkNyKCksbmV3
+IFAuUVMoKSkKcmV0dXJuIFAuaVEoYSwkLkNyKCksbmV3IFAubnAoKSl9LAppUTpmdW5jdGlvbihhLGIs
+Yyl7dmFyIHQ9UC5PbShhLGIpCmlmKHQ9PW51bGx8fCEoYSBpbnN0YW5jZW9mIE9iamVjdCkpe3Q9Yy4k
+MShhKQpQLkRtKGEsYix0KX1yZXR1cm4gdH0sClBDOmZ1bmN0aW9uIFBDKCl7fSwKbXQ6ZnVuY3Rpb24g
+bXQoYSl7dGhpcy5hPWF9LApOejpmdW5jdGlvbiBOeigpe30sClFTOmZ1bmN0aW9uIFFTKCl7fSwKbnA6
+ZnVuY3Rpb24gbnAoKXt9LApFNDpmdW5jdGlvbiBFNChhKXt0aGlzLmE9YX0sCnI3OmZ1bmN0aW9uIHI3
+KGEpe3RoaXMuYT1hfSwKVHo6ZnVuY3Rpb24gVHooYSxiKXt0aGlzLmE9YQp0aGlzLiR0aT1ifSwKY286
+ZnVuY3Rpb24gY28oKXt9LApiQjpmdW5jdGlvbiBiQigpe30sCktlOmZ1bmN0aW9uIEtlKGEpe3RoaXMu
+YT1hfSwKZDU6ZnVuY3Rpb24gZDUoKXt9LApuNjpmdW5jdGlvbiBuNigpe319LFc9ewp4MzpmdW5jdGlv
+bigpe3JldHVybiB3aW5kb3d9LApacjpmdW5jdGlvbigpe3JldHVybiBkb2N1bWVudH0sCko2OmZ1bmN0
+aW9uKCl7dmFyIHQ9ZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgiYSIpCnJldHVybiB0fSwKVTk6ZnVuY3Rp
+b24oYSxiLGMpe3ZhciB0LHM9ZG9jdW1lbnQuYm9keQpzLnRvU3RyaW5nCnQ9Qy5SWS5yNihzLGEsYixj
+KQp0LnRvU3RyaW5nCnM9dS5hYwpzPW5ldyBILlU1KG5ldyBXLmU3KHQpLHMuQygiYTIobEQuRSkiKS5h
+KG5ldyBXLkN2KCkpLHMuQygiVTU8bEQuRT4iKSkKcmV0dXJuIHUuaC5hKHMuZ3I4KHMpKX0sCnJTOmZ1
+bmN0aW9uKGEpe3ZhciB0LHMscj0iZWxlbWVudCB0YWcgdW5hdmFpbGFibGUiCnRyeXt0PUouUkUoYSkK
+aWYodHlwZW9mIHQuZ25zKGEpPT0ic3RyaW5nIilyPXQuZ25zKGEpfWNhdGNoKHMpe0guUnUocyl9cmV0
+dXJuIHJ9LApxRDpmdW5jdGlvbihhLGIpe3ZhciB0LHMscixxPW5ldyBQLnZzKCQuWDMsdS5ZKSxwPW5l
+dyBQLlpmKHEsdS5FKSxvPW5ldyBYTUxIdHRwUmVxdWVzdCgpCkMuRHQuZW8obywiR0VUIixhLCEwKQpi
+LksoMCxuZXcgVy5iVShvKSkKdD11LmFuCnM9dC5hKG5ldyBXLmhIKG8scCkpCnUuTS5hKG51bGwpCnI9
+dS5wClcuSkUobywibG9hZCIscywhMSxyKQpXLkpFKG8sImVycm9yIix0LmEocC5nWUooKSksITEscikK
+by5zZW5kKCkKcmV0dXJuIHF9LApDMDpmdW5jdGlvbihhLGIpe2E9NTM2ODcwOTExJmErYgphPTUzNjg3
+MDkxMSZhKygoNTI0Mjg3JmEpPDwxMCkKcmV0dXJuIGFeYT4+PjZ9LApyRTpmdW5jdGlvbihhLGIsYyxk
+KXt2YXIgdD1XLkMwKFcuQzAoVy5DMChXLkMwKDAsYSksYiksYyksZCkscz01MzY4NzA5MTEmdCsoKDY3
+MTA4ODYzJnQpPDwzKQpzXj1zPj4+MTEKcmV0dXJuIDUzNjg3MDkxMSZzKygoMTYzODMmcyk8PDE1KX0s
+ClROOmZ1bmN0aW9uKGEsYil7dmFyIHQscyxyPWEuY2xhc3NMaXN0CmZvcih0PWIubGVuZ3RoLHM9MDtz
+PGIubGVuZ3RoO2IubGVuZ3RoPT09dHx8KDAsSC5saykoYiksKytzKXIuYWRkKGJbc10pfSwKSkU6ZnVu
+Y3Rpb24oYSxiLGMsZCxlKXt2YXIgdD1XLmFGKG5ldyBXLnZOKGMpLHUuQikKaWYodCE9bnVsbCYmITAp
+Si5kWihhLGIsdCwhMSkKcmV0dXJuIG5ldyBXLnhDKGEsYix0LCExLGUuQygieEM8MD4iKSl9LApUdzpm
+dW5jdGlvbihhKXt2YXIgdD1XLko2KCkscz13aW5kb3cubG9jYXRpb24KdD1uZXcgVy5KUShuZXcgVy5t
+ayh0LHMpKQp0LkNZKGEpCnJldHVybiB0fSwKeVc6ZnVuY3Rpb24oYSxiLGMsZCl7dS5oLmEoYSkKSC5j
+KGIpCkguYyhjKQp1LmNyLmEoZCkKcmV0dXJuITB9LApRVzpmdW5jdGlvbihhLGIsYyxkKXt2YXIgdCxz
+LHIKdS5oLmEoYSkKSC5jKGIpCkguYyhjKQp0PXUuY3IuYShkKS5hCnM9dC5hCnMuaHJlZj1jCnI9cy5o
+b3N0bmFtZQp0PXQuYgppZighKHI9PXQuaG9zdG5hbWUmJnMucG9ydD09dC5wb3J0JiZzLnByb3RvY29s
+PT10LnByb3RvY29sKSlpZihyPT09IiIpaWYocy5wb3J0PT09IiIpe3Q9cy5wcm90b2NvbAp0PXQ9PT0i
+OiJ8fHQ9PT0iIn1lbHNlIHQ9ITEKZWxzZSB0PSExCmVsc2UgdD0hMApyZXR1cm4gdH0sCkJsOmZ1bmN0
+aW9uKCl7dmFyIHQ9dS5OLHM9UC50TShDLlF4LHQpLHI9dS5kRy5hKG5ldyBXLklBKCkpLHE9SC5WTShb
+IlRFTVBMQVRFIl0sdS5zKQp0PW5ldyBXLmN0KHMsUC5Mcyh0KSxQLkxzKHQpLFAuTHModCksbnVsbCkK
+dC5DWShudWxsLG5ldyBILmxKKEMuUXgscix1LmR2KSxxLG51bGwpCnJldHVybiB0fSwKUHY6ZnVuY3Rp
+b24oYSl7aWYoYT09bnVsbClyZXR1cm4gbnVsbApyZXR1cm4gVy5QMShhKX0sCnFjOmZ1bmN0aW9uKGEp
+e3ZhciB0CmlmKGE9PW51bGwpcmV0dXJuIG51bGwKaWYoInBvc3RNZXNzYWdlIiBpbiBhKXt0PVcuUDEo
+YSkKaWYodS51LmIodCkpcmV0dXJuIHQKcmV0dXJuIG51bGx9ZWxzZSByZXR1cm4gdS51LmEoYSl9LApQ
+MTpmdW5jdGlvbihhKXtpZihhPT09d2luZG93KXJldHVybiB1LmNpLmEoYSkKZWxzZSByZXR1cm4gbmV3
+IFcuZFcoYSl9LApISDpmdW5jdGlvbihhKXtpZihhPT09d2luZG93LmxvY2F0aW9uKXJldHVybiBhCmVs
+c2UgcmV0dXJuIG5ldyBXLkZiKCl9LAphRjpmdW5jdGlvbihhLGIpe3ZhciB0PSQuWDMKaWYodD09PUMu
+TlUpcmV0dXJuIGEKcmV0dXJuIHQuUHkoYSxiKX0sCnFFOmZ1bmN0aW9uIHFFKCl7fSwKR2g6ZnVuY3Rp
+b24gR2goKXt9LApmWTpmdW5jdGlvbiBmWSgpe30sCm5COmZ1bmN0aW9uIG5CKCl7fSwKQXo6ZnVuY3Rp
+b24gQXooKXt9LApRUDpmdW5jdGlvbiBRUCgpe30sCm54OmZ1bmN0aW9uIG54KCl7fSwKb0o6ZnVuY3Rp
+b24gb0ooKXt9LAppZDpmdW5jdGlvbiBpZCgpe30sClFGOmZ1bmN0aW9uIFFGKCl7fSwKTmg6ZnVuY3Rp
+b24gTmgoKXt9LApJQjpmdW5jdGlvbiBJQigpe30sCm43OmZ1bmN0aW9uIG43KCl7fSwKd3o6ZnVuY3Rp
+b24gd3ooYSxiKXt0aGlzLmE9YQp0aGlzLiR0aT1ifSwKY3Y6ZnVuY3Rpb24gY3YoKXt9LApDdjpmdW5j
+dGlvbiBDdigpe30sCmVhOmZ1bmN0aW9uIGVhKCl7fSwKRDA6ZnVuY3Rpb24gRDAoKXt9LApUNTpmdW5j
+dGlvbiBUNSgpe30sCmg0OmZ1bmN0aW9uIGg0KCl7fSwKYnI6ZnVuY3Rpb24gYnIoKXt9LApWYjpmdW5j
+dGlvbiBWYigpe30sCmZKOmZ1bmN0aW9uIGZKKCl7fSwKYlU6ZnVuY3Rpb24gYlUoYSl7dGhpcy5hPWF9
+LApoSDpmdW5jdGlvbiBoSChhLGIpe3RoaXMuYT1hCnRoaXMuYj1ifSwKd2E6ZnVuY3Rpb24gd2EoKXt9
+LApTZzpmdW5jdGlvbiBTZygpe30sCnU4OmZ1bmN0aW9uIHU4KCl7fSwKT0s6ZnVuY3Rpb24gT0soKXt9
+LAplNzpmdW5jdGlvbiBlNyhhKXt0aGlzLmE9YX0sCnVIOmZ1bmN0aW9uIHVIKCl7fSwKQkg6ZnVuY3Rp
+b24gQkgoKXt9LApTTjpmdW5jdGlvbiBTTigpe30sCmV3OmZ1bmN0aW9uIGV3KCl7fSwKbHA6ZnVuY3Rp
+b24gbHAoKXt9LApUYjpmdW5jdGlvbiBUYigpe30sCkl2OmZ1bmN0aW9uIEl2KCl7fSwKV1A6ZnVuY3Rp
+b24gV1AoKXt9LAp5WTpmdW5jdGlvbiB5WSgpe30sCnc2OmZ1bmN0aW9uIHc2KCl7fSwKSzU6ZnVuY3Rp
+b24gSzUoKXt9LApDbTpmdW5jdGlvbiBDbSgpe30sCkNROmZ1bmN0aW9uIENRKCl7fSwKdzQ6ZnVuY3Rp
+b24gdzQoKXt9LApyaDpmdW5jdGlvbiByaCgpe30sCmNmOmZ1bmN0aW9uIGNmKCl7fSwKaTc6ZnVuY3Rp
+b24gaTcoYSl7dGhpcy5hPWF9LApTeTpmdW5jdGlvbiBTeShhKXt0aGlzLmE9YX0sCktTOmZ1bmN0aW9u
+IEtTKGEsYil7dGhpcy5hPWEKdGhpcy5iPWJ9LApBMzpmdW5jdGlvbiBBMyhhLGIpe3RoaXMuYT1hCnRo
+aXMuYj1ifSwKSTQ6ZnVuY3Rpb24gSTQoYSl7dGhpcy5hPWF9LApGazpmdW5jdGlvbiBGayhhLGIpe3Ro
+aXMuYT1hCnRoaXMuJHRpPWJ9LApSTzpmdW5jdGlvbiBSTyhhLGIsYyxkKXt2YXIgXz10aGlzCl8uYT1h
+Cl8uYj1iCl8uYz1jCl8uJHRpPWR9LApldTpmdW5jdGlvbiBldShhLGIsYyxkKXt2YXIgXz10aGlzCl8u
+YT1hCl8uYj1iCl8uYz1jCl8uJHRpPWR9LAp4QzpmdW5jdGlvbiB4QyhhLGIsYyxkLGUpe3ZhciBfPXRo
+aXMKXy5iPWEKXy5jPWIKXy5kPWMKXy5lPWQKXy4kdGk9ZX0sCnZOOmZ1bmN0aW9uIHZOKGEpe3RoaXMu
+YT1hfSwKSlE6ZnVuY3Rpb24gSlEoYSl7dGhpcy5hPWF9LApHbTpmdW5jdGlvbiBHbSgpe30sCnZEOmZ1
+bmN0aW9uIHZEKGEpe3RoaXMuYT1hfSwKVXY6ZnVuY3Rpb24gVXYoYSl7dGhpcy5hPWF9LApFZzpmdW5j
+dGlvbiBFZyhhLGIsYyl7dGhpcy5hPWEKdGhpcy5iPWIKdGhpcy5jPWN9LAptNjpmdW5jdGlvbiBtNigp
+e30sCkVvOmZ1bmN0aW9uIEVvKCl7fSwKV2s6ZnVuY3Rpb24gV2soKXt9LApjdDpmdW5jdGlvbiBjdChh
+LGIsYyxkLGUpe3ZhciBfPXRoaXMKXy5lPWEKXy5hPWIKXy5iPWMKXy5jPWQKXy5kPWV9LApJQTpmdW5j
+dGlvbiBJQSgpe30sCk93OmZ1bmN0aW9uIE93KCl7fSwKVzk6ZnVuY3Rpb24gVzkoYSxiLGMpe3ZhciBf
+PXRoaXMKXy5hPWEKXy5iPWIKXy5jPS0xCl8uZD1udWxsCl8uJHRpPWN9LApkVzpmdW5jdGlvbiBkVyhh
+KXt0aGlzLmE9YX0sCkZiOmZ1bmN0aW9uIEZiKCl7fSwKa0Y6ZnVuY3Rpb24ga0YoKXt9LAptazpmdW5j
+dGlvbiBtayhhLGIpe3RoaXMuYT1hCnRoaXMuYj1ifSwKS286ZnVuY3Rpb24gS28oYSl7dGhpcy5hPWEK
+dGhpcy5iPSExfSwKZm06ZnVuY3Rpb24gZm0oYSl7dGhpcy5hPWF9LApMZTpmdW5jdGlvbiBMZSgpe30s
+Cks3OmZ1bmN0aW9uIEs3KCl7fSwKckI6ZnVuY3Rpb24gckIoKXt9LApYVzpmdW5jdGlvbiBYVygpe30s
+Cm9hOmZ1bmN0aW9uIG9hKCl7fX0sVT17CmpmOmZ1bmN0aW9uKGEpe3ZhciB0LHMscixxCmlmKGE9PW51
+bGwpdD1udWxsCmVsc2V7dD1ILlZNKFtdLHUuZkEpCmZvcihzPUouSVQodS5SLmEoYSkpO3MuRigpOyl7
+cj1zLmdsKCkKcT1KLlU2KHIpCkMuTm0uaSh0LG5ldyBVLlNlKEguYyhxLnEociwiZGVzY3JpcHRpb24i
+KSksSC5jKHEucShyLCJocmVmIikpKSl9fXJldHVybiB0fSwKTmQ6ZnVuY3Rpb24oYSl7dmFyIHQscwpp
+ZihhPT1udWxsKXQ9bnVsbAplbHNle3Q9SC5WTShbXSx1LmhoKQpmb3Iocz1KLklUKHUuUi5hKGEpKTtz
+LkYoKTspQy5ObS5pKHQsVS5KaihzLmdsKCkpKX1yZXR1cm4gdH0sCkpqOmZ1bmN0aW9uKGEpe3ZhciB0
+LHMscixxLHAsbz0iZGVzY3JpcHRpb24iLG49Si5VNihhKSxtPUguYyhuLnEoYSxvKSksbD1ILlZNKFtd
+LHUuYUopCmZvcihuPUouSVQodS5SLmEobi5xKGEsImVudHJpZXMiKSkpO24uRigpOyl7dD1uLmdsKCkK
+cz1KLlU2KHQpCnI9SC5jKHMucSh0LG8pKQpxPUguYyhzLnEodCwiZnVuY3Rpb24iKSkKcz1zLnEodCwi
+bGluayIpCmlmKHM9PW51bGwpcz1udWxsCmVsc2V7cD1KLlU2KHMpCnM9bmV3IFUuTWwoSC5jKHAucShz
+LCJocmVmIikpLEguV1kocC5xKHMsImxpbmUiKSksSC5jKHAucShzLCJwYXRoIikpKX1DLk5tLmkobCxu
+ZXcgVS53YihyLHEscykpfXJldHVybiBuZXcgVS55RChtLGwpfSwKZDI6ZnVuY3Rpb24gZDIoYSxiLGMs
+ZCxlKXt2YXIgXz10aGlzCl8uYT1hCl8uYj1iCl8uYz1jCl8uZD1kCl8uZT1lfSwKU2U6ZnVuY3Rpb24g
+U2UoYSxiKXt0aGlzLmE9YQp0aGlzLmI9Yn0sCk1sOmZ1bmN0aW9uIE1sKGEsYixjKXt0aGlzLmE9YQp0
+aGlzLmI9Ygp0aGlzLmM9Y30sCnlEOmZ1bmN0aW9uIHlEKGEsYil7dGhpcy5hPWEKdGhpcy5iPWJ9LAp3
+YjpmdW5jdGlvbiB3YihhLGIsYyl7dGhpcy5hPWEKdGhpcy5iPWIKdGhpcy5jPWN9fSxCPXsKWWY6ZnVu
+Y3Rpb24oYSl7dmFyIHQscyxyLHEscCxvLG4sbSxsPUguYyhhLnEoMCwicmVnaW9ucyIpKSxrPUguYyhh
+LnEoMCwibmF2aWdhdGlvbkNvbnRlbnQiKSksaj1ILmMoYS5xKDAsInNvdXJjZUNvZGUiKSksaT1QLkZs
+KHUuTix1LmY0KQpmb3IodD11LlMuYShhLnEoMCwiZWRpdHMiKSksdD10LmdQdSh0KSx0PXQuZ2t6KHQp
+LHM9dS5SLHI9dS5naTt0LkYoKTspe3E9dC5nbCgpCnA9cS5hCm89SC5WTShbXSxyKQpmb3IocT1KLklU
+KHMuYShxLmIpKTtxLkYoKTspe249cS5nbCgpCm09Si5VNihuKQpDLk5tLmkobyxuZXcgQi5qOChILldZ
+KG0ucShuLCJsaW5lIikpLEguYyhtLnEobiwiZXhwbGFuYXRpb24iKSksSC5XWShtLnEobiwib2Zmc2V0
+IikpKSl9aS5ZKDAscCxvKX1yZXR1cm4gbmV3IEIucXAobCxrLGosaSl9LApqODpmdW5jdGlvbiBqOChh
+LGIsYyl7dGhpcy5hPWEKdGhpcy5iPWIKdGhpcy5jPWN9LApxcDpmdW5jdGlvbiBxcChhLGIsYyxkKXt2
+YXIgXz10aGlzCl8uYT1hCl8uYj1iCl8uYz1jCl8uZD1kfSwKZnY6ZnVuY3Rpb24gZnYoKXt9LApPUzpm
+dW5jdGlvbihhKXt2YXIgdAppZighKGE+PTY1JiZhPD05MCkpdD1hPj05NyYmYTw9MTIyCmVsc2UgdD0h
+MApyZXR1cm4gdH0sCll1OmZ1bmN0aW9uKGEsYil7dmFyIHQ9YS5sZW5ndGgscz1iKzIKaWYodDxzKXJl
+dHVybiExCmlmKCFCLk9TKEMueEIubShhLGIpKSlyZXR1cm4hMQppZihDLnhCLm0oYSxiKzEpIT09NTgp
+cmV0dXJuITEKaWYodD09PXMpcmV0dXJuITAKcmV0dXJuIEMueEIubShhLHMpPT09NDd9fSxUPXttUTpm
+dW5jdGlvbiBtUSgpe319LEw9ewpJcTpmdW5jdGlvbigpe0MuQlouQihkb2N1bWVudCwiRE9NQ29udGVu
+dExvYWRlZCIsbmV3IEwuZSgpKQpDLm9sLkIod2luZG93LCJwb3BzdGF0ZSIsbmV3IEwuTCgpKX0sCmt6
+OmZ1bmN0aW9uKGEpe3ZhciB0LHM9dS5oLmEoYS5wYXJlbnROb2RlKS5xdWVyeVNlbGVjdG9yKCI6c2Nv
+cGUgPiB1bCIpLHI9cy5zdHlsZSxxPSIiK0MuQ0QuelEocy5vZmZzZXRIZWlnaHQpKjIrInB4IgpyLm1h
+eEhlaWdodD1xCnI9Si5xRihhKQpxPXIuJHRpCnQ9cS5DKCJ+KDEpIikuYShuZXcgTC5XeChzLGEpKQp1
+Lk0uYShudWxsKQpXLkpFKHIuYSxyLmIsdCwhMSxxLmMpfSwKeVg6ZnVuY3Rpb24oYSxiKXt2YXIgdCxz
+LHIscSxwLG89InF1ZXJ5U2VsZWN0b3JBbGwiLG49ZG9jdW1lbnQucXVlcnlTZWxlY3RvcihhKSxtPXUu
+aApuLnRvU3RyaW5nCkguRGgobSxtLCJUIixvKQp0PXUuVApzPW5ldyBXLnd6KG4ucXVlcnlTZWxlY3Rv
+ckFsbCgiLm5hdi1saW5rIiksdCkKcy5LKHMsbmV3IEwuQU8oYikpCkguRGgobSxtLCJUIixvKQpyPW5l
+dyBXLnd6KG4ucXVlcnlTZWxlY3RvckFsbCgiLnJlZ2lvbiIpLHQpCmlmKHIuZ0EocikhPT0wKXtxPW4u
+cXVlcnlTZWxlY3RvcigidGFibGVbZGF0YS1wYXRoXSIpCnEudG9TdHJpbmcKci5LKHIsbmV3IEwuSG8o
+cS5nZXRBdHRyaWJ1dGUoImRhdGEtIituZXcgVy5TeShuZXcgVy5pNyhxKSkuTygicGF0aCIpKSkpfUgu
+RGgobSxtLCJUIixvKQpwPW5ldyBXLnd6KG4ucXVlcnlTZWxlY3RvckFsbCgiLmFkZC1oaW50LWxpbmsi
+KSx0KQpwLksocCxuZXcgTC5JQygpKX0sClE2OmZ1bmN0aW9uKGEsYil7dmFyIHQ9dS5OCnJldHVybiBX
+LnFEKEwuUTQoYSxiKSxQLkVGKFsiQ29udGVudC1UeXBlIiwiYXBwbGljYXRpb24vanNvbjsgY2hhcnNl
+dD1VVEYtOCJdLHQsdCkpfSwKdHk6ZnVuY3Rpb24oYSl7dmFyIHQ9MCxzPVAuRlgodS5TKSxyLHEscCxv
+LG4sbSxsLGsKdmFyICRhc3luYyR0eT1QLmx6KGZ1bmN0aW9uKGIsYyl7aWYoYj09PTEpcmV0dXJuIFAu
+ZjMoYyxzKQp3aGlsZSh0cnVlKXN3aXRjaCh0KXtjYXNlIDA6bj1uZXcgUC52cygkLlgzLHUuWSkKbT1u
+ZXcgUC5aZihuLHUuRSkKbD1uZXcgWE1MSHR0cFJlcXVlc3QoKQprPXUuTgpDLkR0LmVvKGwsIlBPU1Qi
+LEwuUTQoYSxQLkZsKGssaykpLCEwKQpsLnNldFJlcXVlc3RIZWFkZXIoIkNvbnRlbnQtVHlwZSIsImFw
+cGxpY2F0aW9uL2pzb247IGNoYXJzZXQ9VVRGLTgiKQprPXUuYW4KcT1rLmEobmV3IEwuTDEobSxsKSkK
+dS5NLmEobnVsbCkKcD11LnAKVy5KRShsLCJsb2FkIixxLCExLHApClcuSkUobCwiZXJyb3IiLGsuYSht
+LmdZSigpKSwhMSxwKQpsLnNlbmQoKQp0PTMKcmV0dXJuIFAualEobiwkYXN5bmMkdHkpCmNhc2UgMzpv
+PUMuQ3QucFcoMCxsLnJlc3BvbnNlVGV4dCxudWxsKQppZihsLnN0YXR1cz09PTIwMCl7cj11LlMuYShv
+KQp0PTEKYnJlYWt9ZWxzZSB0aHJvdyBILmIobykKY2FzZSAxOnJldHVybiBQLnlDKHIscyl9fSkKcmV0
+dXJuIFAuREkoJGFzeW5jJHR5LHMpfSwKYUs6ZnVuY3Rpb24oYSl7dmFyIHQ9UC5oSyhhKS5naFkoKS5x
+KDAsImxpbmUiKQpyZXR1cm4gdD09bnVsbD9udWxsOkguSHAodCxudWxsKX0sCkc2OmZ1bmN0aW9uKGEp
+e3ZhciB0PVAuaEsoYSkuZ2hZKCkucSgwLCJvZmZzZXQiKQpyZXR1cm4gdD09bnVsbD9udWxsOkguSHAo
+dCxudWxsKX0sCmk2OmZ1bmN0aW9uKGEpe3JldHVybiBMLm5XKHUuVi5hKGEpKX0sCm5XOmZ1bmN0aW9u
+KGEpe3ZhciB0PTAscz1QLkZYKHUueikscj0xLHEscD1bXSxvLG4sbSxsLGsKdmFyICRhc3luYyRpNj1Q
+Lmx6KGZ1bmN0aW9uKGIsYyl7aWYoYj09PTEpe3E9Ywp0PXJ9d2hpbGUodHJ1ZSlzd2l0Y2godCl7Y2Fz
+ZSAwOmw9dS5oLmEoVy5xYyhhLmN1cnJlbnRUYXJnZXQpKS5nZXRBdHRyaWJ1dGUoImhyZWYiKQphLnBy
+ZXZlbnREZWZhdWx0KCkKcj0zCnQ9NgpyZXR1cm4gUC5qUShMLnR5KGwpLCRhc3luYyRpNikKY2FzZSA2
+OnUuYV8uYShKLkdyKFcuUHYoZG9jdW1lbnQuZGVmYXVsdFZpZXcpKSkucmVsb2FkKCkKcj0xCnQ9NQpi
+cmVhawpjYXNlIDM6cj0yCms9cQpvPUguUnUoaykKbj1ILnRzKGspCkwuQzIoIkNvdWxkIG5vdCBhZGQv
+cmVtb3ZlIGhpbnQiLG8sbikKdD01CmJyZWFrCmNhc2UgMjp0PTEKYnJlYWsKY2FzZSA1OnJldHVybiBQ
+LnlDKG51bGwscykKY2FzZSAxOnJldHVybiBQLmYzKHEscyl9fSkKcmV0dXJuIFAuREkoJGFzeW5jJGk2
+LHMpfSwKQzI6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0LHMscj0iZXhjZXB0aW9uIixxPSJzdGFja1RyYWNl
+IixwPXUuUy5iKGIpJiZKLlJNKGIucSgwLCJzdWNjZXNzIiksITEpJiZILm9UKGIueDQocikpJiZILm9U
+KGIueDQocSkpLG89Si5pYShiKQppZihwKXt0PUguYyhvLnEoYixyKSkKYz1vLnEoYixxKX1lbHNlIHQ9
+by5aKGIpCnM9ZG9jdW1lbnQucXVlcnlTZWxlY3RvcigiLnBvcHVwLXBhbmUiKQpzLnF1ZXJ5U2VsZWN0
+b3IoImgyIikuaW5uZXJUZXh0PWEKcy5xdWVyeVNlbGVjdG9yKCJwIikuaW5uZXJUZXh0PXQKcy5xdWVy
+eVNlbGVjdG9yKCJwcmUiKS5pbm5lclRleHQ9Si5BYyhjKQpwPXUuTgp1LmJxLmEocy5xdWVyeVNlbGVj
+dG9yKCJhLmJvdHRvbSIpKS5ocmVmPVAuWGQoImh0dHBzIiwiZ2l0aHViLmNvbSIsImRhcnQtbGFuZy9z
+ZGsvaXNzdWVzL25ldyIsUC5FRihbInRpdGxlIiwiSXNzdWUgd2l0aCBOTkJEIG1pZ3JhdGlvbiB0b29s
+OiAiK2EsImxhYmVscyIsImFyZWEtYW5hbHl6ZXIsYW5hbHl6ZXItbm5iZC1taWdyYXRpb24sdHlwZS1i
+dWciLCJib2R5IixhKyJcblxuRXJyb3I6ICIrSC5kKHQpKyJcblxuUGxlYXNlIGZpbGwgaW4gdGhlIGZv
+bGxvd2luZzpcblxuKipOYW1lIG9mIHBhY2thZ2UgYmVpbmcgbWlncmF0ZWQgKGlmIHB1YmxpYykqKjpc
+bioqV2hhdCBJIHdhcyBkb2luZyB3aGVuIHRoaXMgaXNzdWUgb2NjdXJyZWQqKjpcbioqSXMgaXQgcG9z
+c2libGUgdG8gd29yayBhcm91bmQgdGhpcyBpc3N1ZSoqOlxuKipIYXMgdGhpcyBpc3N1ZSBoYXBwZW5l
+ZCBiZWZvcmUsIGFuZCBpZiBzbywgaG93IG9mdGVuKio6XG4qKkRhcnQgU0RLIHZlcnNpb24qKjogKHZp
+c2libGUgaW4gbG93ZXIgbGVmdCBvZiBtaWdyYXRpb24gcHJldmlldylcbioqQWRkaXRpb25hbCBkZXRh
+aWxzKio6XG5cblRoYW5rcyBmb3IgZmlsaW5nIVxuXG5TdGFja3RyYWNlOiBfYXV0byBwb3B1bGF0ZWQg
+YnkgbWlncmF0aW9uIHByZXZpZXcgdG9vbC5fXG5cbmBgYFxuIitILmQoYykrIlxuYGBgXG4iXSxwLHAp
+KS5nbkQoKQpwPXMuc3R5bGUKcC5kaXNwbGF5PSJpbml0aWFsIgpMLnFKKCJoYW5kbGVQb3N0TGlua0Ns
+aWNrOiAiK0guZChiKSxjKX0sCnQyOmZ1bmN0aW9uKGEsYixjKXt2YXIgdCxzLHIscSxwLG8sbj17fSxt
+PXUuaC5hKFcucWMoYS5jdXJyZW50VGFyZ2V0KSkKYS5wcmV2ZW50RGVmYXVsdCgpCnQ9bi5hPW0uZ2V0
+QXR0cmlidXRlKCJocmVmIikKaWYoSi56bCh0LCI/Iikpe3M9Qy54Qi5Oaih0LDAsQy54Qi5PWSh0LCI/
+IikpCm4uYT1zCnI9c31lbHNlIHI9dAppZihjIT1udWxsKXtxPSQublUoKQpyPW4uYT1xLm81KEQubnIo
+cS50TShjKSxyKSl9cD1MLkc2KHQpCm89TC5hSyh0KQppZihwIT1udWxsKUwuYWYocixwLG8sYixuZXcg
+TC5uVChuLHAsbykpCmVsc2UgTC5hZihyLG51bGwsbnVsbCxiLG5ldyBMLk5ZKG4pKX0sCnZVOmZ1bmN0
+aW9uKCl7dmFyIHQ9ZG9jdW1lbnQscz11LmgKSC5EaChzLHMsIlQiLCJxdWVyeVNlbGVjdG9yQWxsIikK
+dD1uZXcgVy53eih0LnF1ZXJ5U2VsZWN0b3JBbGwoIi5jb2RlIiksdS5UKQp0LksodCxuZXcgTC5HSCgp
+KX0sCmhYOmZ1bmN0aW9uKGEsYixjKXt2YXIgdD11Lk4KTC5RNihhLFAuRUYoWyJyZWdpb24iLCJyZWdp
+b24iLCJvZmZzZXQiLEguZChiKV0sdCx0KSkuVzcobmV3IEwuRFQoYSxiLGMpLHUuUCkuT0EobmV3IEwu
+ZUgoYSkpfSwKRzc6ZnVuY3Rpb24oYSxiLGMsZCxlKXt2YXIgdAppZighSi5wNChhLCIuZGFydCIpKXtM
+LkJFKGEsbmV3IEIucXAoIiIsIiIsIiIsQy5DTSksZCkKTC5CWChhLG51bGwpCmlmKGUhPW51bGwpZS4k
+MCgpCnJldHVybn10PXUuTgpMLlE2KGEsUC5FRihbImlubGluZSIsInRydWUiXSx0LHQpKS5XNyhuZXcg
+TC55dShhLGQsYixjLGUpLHUuUCkuT0EobmV3IEwuekQoYSkpfSwKR2U6ZnVuY3Rpb24oKXt2YXIgdD0i
+L19wcmV2aWV3L25hdmlnYXRpb25UcmVlLmpzb24iCkwuUTYodCxDLldPKS5XNyhuZXcgTC5UVygpLHUu
+UCkuT0EobmV3IEwueHIodCkpfSwKcUo6ZnVuY3Rpb24oYSxiKXt2YXIgdAp3aW5kb3cKaWYodHlwZW9m
+IGNvbnNvbGUhPSJ1bmRlZmluZWQiKXdpbmRvdy5jb25zb2xlLmVycm9yKGEpCndpbmRvdwp0PUguZChi
+KQppZih0eXBlb2YgY29uc29sZSE9InVuZGVmaW5lZCIpd2luZG93LmNvbnNvbGUuZXJyb3IodCl9LApx
+TzpmdW5jdGlvbihhKXt2YXIgdCxzPWEuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCkscj1DLkNELnpRKCQu
+ZmkoKS5vZmZzZXRIZWlnaHQpLHE9d2luZG93LmlubmVySGVpZ2h0LHA9Qy5DRC56USgkLkRXKCkub2Zm
+c2V0SGVpZ2h0KQppZih0eXBlb2YgcSE9PSJudW1iZXIiKXJldHVybiBxLkhOKCkKdD1zLmJvdHRvbQpp
+Zih0eXBlb2YgdCE9PSJudW1iZXIiKXJldHVybiB0Lm9zKCkKaWYodD5xLShwKzE0KSlKLmRoKGEpCmVs
+c2V7cT1zLnRvcAppZih0eXBlb2YgcSE9PSJudW1iZXIiKXJldHVybiBxLkooKQppZihxPHIrMTQpSi5k
+aChhKX19LApmRzpmdW5jdGlvbihhLGIpe3ZhciB0LHMscgppZihhIT1udWxsKXt0PWRvY3VtZW50CnM9
+dC5nZXRFbGVtZW50QnlJZCgibyIrSC5kKGEpKQpyPXQucXVlcnlTZWxlY3RvcigiLmxpbmUtIitILmQo
+YikpCmlmKHMhPW51bGwpe0wucU8ocykKSi5kUihzKS5pKDAsInRhcmdldCIpfWVsc2UgaWYociE9bnVs
+bClMLnFPKHIucGFyZW50RWxlbWVudCkKaWYociE9bnVsbClKLmRSKHUuaC5hKHIucGFyZW50Tm9kZSkp
+LmkoMCwiaGlnaGxpZ2h0Iil9ZWxzZSBMLnFPKCQuRDkoKSl9LAphZjpmdW5jdGlvbihhLGIsYyxkLGUp
+e3ZhciB0LHMscj1MLkc2KHdpbmRvdy5sb2NhdGlvbi5ocmVmKSxxPUwuYUsod2luZG93LmxvY2F0aW9u
+LmhyZWYpCmlmKHIhPW51bGwpe3Q9ZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoIm8iK0guZChyKSkKaWYo
+dCE9bnVsbClKLmRSKHQpLlIoMCwidGFyZ2V0Iil9aWYocSE9bnVsbCl7cz1kb2N1bWVudC5xdWVyeVNl
+bGVjdG9yKCIubGluZS0iK0guZChxKSkKaWYocyE9bnVsbClKLmRSKHMucGFyZW50RWxlbWVudCkuUigw
+LCJoaWdobGlnaHQiKX1pZihhPT13aW5kb3cubG9jYXRpb24ucGF0aG5hbWUpe0wuZkcoYixjKQplLiQw
+KCl9ZWxzZSBMLkc3KGEsYixjLGQsZSl9LApRNDpmdW5jdGlvbihhLGIpe3ZhciB0LHMscj1QLmhLKGEp
+LHE9dS5OCnE9UC5GbChxLHEpCmZvcih0PXIuZ2hZKCksdD10LmdQdSh0KSx0PXQuZ2t6KHQpO3QuRigp
+Oyl7cz10LmdsKCkKcS5ZKDAscy5hLHMuYil9Zm9yKHQ9Yi5nUHUoYiksdD10Lmdreih0KTt0LkYoKTsp
+e3M9dC5nbCgpCnEuWSgwLHMuYSxzLmIpfXEuWSgwLCJhdXRoVG9rZW4iLCQuVUUoKSkKcmV0dXJuIHIu
+bm0oMCxxKS5nbkQoKX0sClQxOmZ1bmN0aW9uKGEpe3ZhciB0LHMscixxLHAsbyxuLG0sbCxrPSQuaEwo
+KQpKLmw1KGssIiIpCmlmKGE9PW51bGwpe3Q9ZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgicCIpCnQudGV4
+dENvbnRlbnQ9IlNlZSBkZXRhaWxzIGFib3V0IGEgcHJvcG9zZWQgZWRpdC4iCkMuTHQuc1AodCxILlZN
+KFsicGxhY2Vob2xkZXIiXSx1LnMpKQprLmFwcGVuZENoaWxkKHQpCkMuTHQuRkYodCkKcmV0dXJufXM9
+YS5kCnI9JC5uVSgpCnE9ci50TShzKQpwPWEuYgpvPWRvY3VtZW50Cm49ci5IUChzLEouVDAoby5xdWVy
+eVNlbGVjdG9yKCIucm9vdCIpLnRleHRDb250ZW50KSkKbT1hLmMKbD1vLmNyZWF0ZUVsZW1lbnQoInAi
+KQprLmFwcGVuZENoaWxkKGwpCmwuYXBwZW5kQ2hpbGQoby5jcmVhdGVUZXh0Tm9kZShILmQocCkrIiBh
+dCAiK0guZChuKSsiOiIrSC5kKG0pKyIuIikpCkouZGgobCkKTC5DQyhhLGsscSkKTC5GeihhLGspfSwK
+TEg6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0LHMscixxLHAsbyxuLG0sbCxrLGosaSxoLGc9JC55UCgpCkou
+bDUoZywiIikKaWYoYi5nQShiKT09PTApe3Q9ZG9jdW1lbnQKcz10LmNyZWF0ZUVsZW1lbnQoInAiKQpn
+LmFwcGVuZENoaWxkKHMpCnMuYXBwZW5kQ2hpbGQodC5jcmVhdGVUZXh0Tm9kZSgiTm8gcHJvcG9zZWQg
+ZWRpdHMiKSl9ZWxzZSBmb3IoZz1iLmdQdShiKSxnPWcuZ2t6KGcpLHQ9dS5RLHI9dC5DKCJ+KDEpIiks
+cT11Lk0sdD10LmM7Zy5GKCk7KXtwPWcuZ2woKQpvPWRvY3VtZW50CnM9by5jcmVhdGVFbGVtZW50KCJw
+IikKbj0kLnlQKCkKbi5hcHBlbmRDaGlsZChzKQpzLmFwcGVuZENoaWxkKG8uY3JlYXRlVGV4dE5vZGUo
+SC5kKHAuYSkrIjoiKSkKbT1vLmNyZWF0ZUVsZW1lbnQoInVsIikKbi5hcHBlbmRDaGlsZChtKQpmb3Io
+cD1KLklUKHAuYik7cC5GKCk7KXtuPXAuZ2woKQpsPW8uY3JlYXRlRWxlbWVudCgibGkiKQptLmFwcGVu
+ZENoaWxkKGwpCkouZFIobCkuaSgwLCJlZGl0IikKaz1vLmNyZWF0ZUVsZW1lbnQoImEiKQpsLmFwcGVu
+ZENoaWxkKGspCmsuY2xhc3NMaXN0LmFkZCgiZWRpdC1saW5rIikKaj1uLmMKaT1ILmQoaikKay5zZXRB
+dHRyaWJ1dGUoImRhdGEtIituZXcgVy5TeShuZXcgVy5pNyhrKSkuTygib2Zmc2V0IiksaSkKaD1uLmEK
+aT1ILmQoaCkKay5zZXRBdHRyaWJ1dGUoImRhdGEtIituZXcgVy5TeShuZXcgVy5pNyhrKSkuTygibGlu
+ZSIpLGkpCmsuYXBwZW5kQ2hpbGQoby5jcmVhdGVUZXh0Tm9kZSgibGluZSAiK0guZChoKSkpCmk9ci5h
+KG5ldyBMLkVFKGosaCxhKSkKcS5hKG51bGwpClcuSkUoaywiY2xpY2siLGksITEsdCkKbC5hcHBlbmRD
+aGlsZChvLmNyZWF0ZVRleHROb2RlKCI6ICIrSC5kKG4uYikpKX19aWYoYylMLlQxKG51bGwpfSwKRnI6
+ZnVuY3Rpb24oYSxiLGMpe3ZhciB0LHMscj13aW5kb3cubG9jYXRpb24scT1QLmhLKChyJiZDLkV4KS5n
+RHIocikrSC5kKGEpKQpyPXUuTgpyPVAuRmwocixyKQppZihiIT1udWxsKXIuWSgwLCJvZmZzZXQiLEgu
+ZChiKSkKaWYoYyE9bnVsbClyLlkoMCwibGluZSIsSC5kKGMpKQpyLlkoMCwiYXV0aFRva2VuIiwkLlVF
+KCkpCnE9cS5ubSgwLHIpCnI9d2luZG93Lmhpc3RvcnkKdD11LnoKcz1xLmduRCgpCnIudG9TdHJpbmcK
+ci5wdXNoU3RhdGUobmV3IFAuQmYoW10sW10pLlB2KFAuRmwodCx0KSksIiIscyl9LApFbjpmdW5jdGlv
+bihhKXt2YXIgdD1KLm0oZG9jdW1lbnQucXVlcnlTZWxlY3RvcigiLnJvb3QiKS50ZXh0Q29udGVudCwi
+LyIpCmlmKEMueEIubihhLHQpKXJldHVybiBDLnhCLkcoYSx0Lmxlbmd0aCkKZWxzZSByZXR1cm4gYX0s
+CkJYOmZ1bmN0aW9uKGEsYil7dmFyIHQscyxyPXt9CnIuYT1hCmE9TC5FbihhKQpyLmE9YQokLkQ5KCku
+dGV4dENvbnRlbnQ9YQp0PWRvY3VtZW50CnM9dS5oCkguRGgocyxzLCJUIiwicXVlcnlTZWxlY3RvckFs
+bCIpCnQ9bmV3IFcud3oodC5xdWVyeVNlbGVjdG9yQWxsKCIubmF2LXBhbmVsIC5uYXYtbGluayIpLHUu
+VCkKdC5LKHQsbmV3IEwuVlMocikpfSwKQkU6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0PSIucmVnaW9ucyIs
+cz1kb2N1bWVudCxyPXMucXVlcnlTZWxlY3Rvcih0KSxxPXMucXVlcnlTZWxlY3RvcigiLmNvZGUiKQpK
+LnRIKHIsYi5hLCQuS0coKSkKSi50SChxLGIuYiwkLktHKCkpCkwuTEgoYSxiLmQsYykKTC52VSgpCkwu
+eVgoIi5jb2RlIiwhMCkKTC55WCh0LCEwKX0sCnRYOmZ1bmN0aW9uKGEsYil7dmFyIHQscyxyLHEscCxv
+LG4sbSxsLGssaixpLGgsZz1kb2N1bWVudCxmPWcuY3JlYXRlRWxlbWVudCgidWwiKQphLmFwcGVuZENo
+aWxkKGYpCmZvcih0PWIubGVuZ3RoLHM9dS5NLHI9MDtyPGIubGVuZ3RoO2IubGVuZ3RoPT09dHx8KDAs
+SC5saykoYiksKytyKXtxPWJbcl0KcD1nLmNyZWF0ZUVsZW1lbnQoImxpIikKZi5hcHBlbmRDaGlsZChw
+KQpvPUouUkUocCkKaWYocS5hPT09Qy5ZMil7by5nUChwKS5pKDAsImRpciIpCm49Zy5jcmVhdGVFbGVt
+ZW50KCJzcGFuIikKcC5hcHBlbmRDaGlsZChuKQpvPUouUkUobikKby5nUChuKS5pKDAsImFycm93IikK
+by5zaGYobiwiJiN4MjVCQzsiKQptPWcuY3JlYXRlRWxlbWVudCgic3BhbiIpCnAuYXBwZW5kQ2hpbGQo
+bSkKSi5sNShtLCImI3gxRjRDMTsiKQpwLmFwcGVuZENoaWxkKGcuY3JlYXRlVGV4dE5vZGUocS5iKSkK
+TC50WChwLHEuYykKTC5reihuKX1lbHNle28uc2hmKHAsIiYjeDFGNEM0OyIpCmw9Zy5jcmVhdGVFbGVt
+ZW50KCJhIikKcC5hcHBlbmRDaGlsZChsKQpvPUouUkUobCkKby5nUChsKS5pKDAsIm5hdi1saW5rIikK
+bC5zZXRBdHRyaWJ1dGUoImRhdGEtIituZXcgVy5TeShuZXcgVy5pNyhsKSkuTygibmFtZSIpLHEuZCkK
+bC5zZXRBdHRyaWJ1dGUoImhyZWYiLHEuZSkKbC5hcHBlbmRDaGlsZChnLmNyZWF0ZVRleHROb2RlKHEu
+YikpCm89by5nVmwobCkKaz1vLiR0aQpqPWsuQygifigxKSIpLmEobmV3IEwuVEQoKSkKcy5hKG51bGwp
+ClcuSkUoby5hLG8uYixqLCExLGsuYykKaT1xLmYKaWYodHlwZW9mIGkhPT0ibnVtYmVyIilyZXR1cm4g
+aS5vcygpCmlmKGk+MCl7aD1nLmNyZWF0ZUVsZW1lbnQoInNwYW4iKQpwLmFwcGVuZENoaWxkKGgpCkou
+ZFIoaCkuaSgwLCJlZGl0LWNvdW50IikKbz0iIitpKyIgIgppZihpPT09MSlrPSJlZGl0IgplbHNlIGs9
+ImVkaXRzIgpoLnNldEF0dHJpYnV0ZSgidGl0bGUiLG8raykKaC5hcHBlbmRDaGlsZChnLmNyZWF0ZVRl
+eHROb2RlKEMuam4uWihpKSkpfX19fSwKRno6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzLHIscSxwLG8sbixt
+LGwsayxqPWEuYQppZihqIT1udWxsKXt0PWRvY3VtZW50CnM9dC5jcmVhdGVFbGVtZW50KCJwIikKYi5h
+cHBlbmRDaGlsZChzKQpmb3Iocj1qLmxlbmd0aCxxPXUucyxwPXUuWCxvPTA7bzxqLmxlbmd0aDtqLmxl
+bmd0aD09PXJ8fCgwLEgubGspKGopLCsrbyl7bj1qW29dCm09dC5jcmVhdGVFbGVtZW50KCJhIikKcy5h
+cHBlbmRDaGlsZChtKQptLmFwcGVuZENoaWxkKHQuY3JlYXRlVGV4dE5vZGUobi5hKSkKbS5zZXRBdHRy
+aWJ1dGUoImhyZWYiLG4uYikKbD1wLmEoSC5WTShbImFkZC1oaW50LWxpbmsiLCJiZWZvcmUtYXBwbHki
+LCJidXR0b24iXSxxKSkKaz1KLmRSKG0pCmsuVjEoMCkKay5GVigwLGwpfX19LApDQzpmdW5jdGlvbihh
+MixhMyxhNCl7dmFyIHQscyxyLHEscCxvLG4sbSxsLGssaixpLGgsZyxmLGUsZCxjLGIsYSxhMCxhMT1u
+dWxsCmZvcih0PWEyLmUscz10Lmxlbmd0aCxyPXUucyxxPXUuWCxwPTA7cDx0Lmxlbmd0aDt0Lmxlbmd0
+aD09PXN8fCgwLEgubGspKHQpLCsrcCl7bz10W3BdCm49ZG9jdW1lbnQKbT1uLmNyZWF0ZUVsZW1lbnQo
+InAiKQpsPXEuYShILlZNKFsidHJhY2UiXSxyKSkKaz1KLmRSKG0pCmsuVjEoMCkKay5GVigwLGwpCmo9
+YTMuYXBwZW5kQ2hpbGQobSkKbT1uLmNyZWF0ZUVsZW1lbnQoInNwYW4iKQpsPXEuYShILlZNKFsidHlw
+ZS1kZXNjcmlwdGlvbiJdLHIpKQprPUouZFIobSkKay5WMSgwKQprLkZWKDAsbCkKbS5hcHBlbmRDaGls
+ZChuLmNyZWF0ZVRleHROb2RlKG8uYSkpCmouYXBwZW5kQ2hpbGQobSkKai5hcHBlbmRDaGlsZChuLmNy
+ZWF0ZVRleHROb2RlKCI6IikpCm09bi5jcmVhdGVFbGVtZW50KCJ1bCIpCmw9cS5hKEguVk0oWyJ0cmFj
+ZSJdLHIpKQprPUouZFIobSkKay5WMSgwKQprLkZWKDAsbCkKaT1qLmFwcGVuZENoaWxkKG0pCmZvciht
+PW8uYixsPW0ubGVuZ3RoLGg9MDtoPG0ubGVuZ3RoO20ubGVuZ3RoPT09bHx8KDAsSC5saykobSksKyto
+KXtnPW1baF0KZj1uLmNyZWF0ZUVsZW1lbnQoImxpIikKSi5sNShmLCImI3gyNzRGOyAiKQppLmFwcGVu
+ZENoaWxkKGYpCmU9bi5jcmVhdGVFbGVtZW50KCJzcGFuIikKZD1xLmEoSC5WTShbImZ1bmN0aW9uIl0s
+cikpCms9Si5kUihlKQprLlYxKDApCmsuRlYoMCxkKQpkPWcuYgpMLmtEKGUsZD09bnVsbD8idW5rbm93
+biI6ZCkKZi5hcHBlbmRDaGlsZChlKQpjPWcuYwppZihjIT1udWxsKXtmLmFwcGVuZENoaWxkKG4uY3Jl
+YXRlVGV4dE5vZGUoIiAoIikpCmI9Yy5iCmE9bi5jcmVhdGVFbGVtZW50KCJhIikKYS5hcHBlbmRDaGls
+ZChuLmNyZWF0ZVRleHROb2RlKEguZChjLmMpKyI6IitILmQoYikpKQphMD1jLmEKZT0kLm5VKCkKYS5z
+ZXRBdHRyaWJ1dGUoImhyZWYiLGUubzUoZS5xNygwLGE0LGEwLGExLGExLGExLGExLGExLGExKSkpCmEu
+Y2xhc3NMaXN0LmFkZCgibmF2LWxpbmsiKQpmLmFwcGVuZENoaWxkKGEpCmYuYXBwZW5kQ2hpbGQobi5j
+cmVhdGVUZXh0Tm9kZSgiKSIpKX1mLmFwcGVuZENoaWxkKG4uY3JlYXRlVGV4dE5vZGUoIjogIikpCmU9
+Zy5hCkwua0QoZixlPT1udWxsPyJ1bmtub3duIjplKX19fSwKa0Q6ZnVuY3Rpb24oYSxiKXt2YXIgdCxz
+LHI9SC5WTShiLnNwbGl0KCIuIiksdS5zKSxxPUMuTm0uZ3RIKHIpLHA9ZG9jdW1lbnQKYS5hcHBlbmRD
+aGlsZChwLmNyZWF0ZVRleHROb2RlKHEpKQpmb3IocT1ILnFDKHIsMSxudWxsLHUuTikscT1uZXcgSC5h
+NyhxLHEuZ0EocSkscS4kdGkuQygiYTc8YUwuRT4iKSksdD1KLlJFKGEpO3EuRigpOyl7cz1xLmQKdC5u
+eihhLCJiZWZvcmVlbmQiLCImIzgyMDM7LiIsbnVsbCxudWxsKQphLmFwcGVuZENoaWxkKHAuY3JlYXRl
+VGV4dE5vZGUocykpfX0sCmU6ZnVuY3Rpb24gZSgpe30sClZXOmZ1bmN0aW9uIFZXKGEsYixjKXt0aGlz
+LmE9YQp0aGlzLmI9Ygp0aGlzLmM9Y30sCm9aOmZ1bmN0aW9uIG9aKCl7fSwKanI6ZnVuY3Rpb24ganIo
+KXt9LApxbDpmdW5jdGlvbiBxbCgpe30sCnk4OmZ1bmN0aW9uIHk4KCl7fSwKSGk6ZnVuY3Rpb24gSGko
+KXt9LApCVDpmdW5jdGlvbiBCVCgpe30sCkw6ZnVuY3Rpb24gTCgpe30sCld4OmZ1bmN0aW9uIFd4KGEs
+Yil7dGhpcy5hPWEKdGhpcy5iPWJ9LApBTzpmdW5jdGlvbiBBTyhhKXt0aGlzLmE9YX0sCmROOmZ1bmN0
+aW9uIGROKGEpe3RoaXMuYT1hfSwKSG86ZnVuY3Rpb24gSG8oYSl7dGhpcy5hPWF9LAp4ejpmdW5jdGlv
+biB4eihhLGIpe3RoaXMuYT1hCnRoaXMuYj1ifSwKSUM6ZnVuY3Rpb24gSUMoKXt9LApMMTpmdW5jdGlv
+biBMMShhLGIpe3RoaXMuYT1hCnRoaXMuYj1ifSwKblQ6ZnVuY3Rpb24gblQoYSxiLGMpe3RoaXMuYT1h
+CnRoaXMuYj1iCnRoaXMuYz1jfSwKTlk6ZnVuY3Rpb24gTlkoYSl7dGhpcy5hPWF9LApHSDpmdW5jdGlv
+biBHSCgpe30sCkRUOmZ1bmN0aW9uIERUKGEsYixjKXt0aGlzLmE9YQp0aGlzLmI9Ygp0aGlzLmM9Y30s
+CmVIOmZ1bmN0aW9uIGVIKGEpe3RoaXMuYT1hfSwKeXU6ZnVuY3Rpb24geXUoYSxiLGMsZCxlKXt2YXIg
+Xz10aGlzCl8uYT1hCl8uYj1iCl8uYz1jCl8uZD1kCl8uZT1lfSwKekQ6ZnVuY3Rpb24gekQoYSl7dGhp
+cy5hPWF9LApUVzpmdW5jdGlvbiBUVygpe30sCnhyOmZ1bmN0aW9uIHhyKGEpe3RoaXMuYT1hfSwKRUU6
+ZnVuY3Rpb24gRUUoYSxiLGMpe3RoaXMuYT1hCnRoaXMuYj1iCnRoaXMuYz1jfSwKUUw6ZnVuY3Rpb24g
+UUwoYSxiKXt0aGlzLmE9YQp0aGlzLmI9Yn0sClZTOmZ1bmN0aW9uIFZTKGEpe3RoaXMuYT1hfSwKVEQ6
+ZnVuY3Rpb24gVEQoKXt9LApYQTpmdW5jdGlvbiBYQSgpe30sCm1LOmZ1bmN0aW9uKGEpe3ZhciB0LHMs
+cixxLHAsbyxuPUguVk0oW10sdS5maCkKZm9yKHQ9Si5JVCh1LlIuYShhKSk7dC5GKCk7KXtzPXQuZ2wo
+KQpyPUouVTYocykKcT1MLnAyKEguYyhyLnEocywidHlwZSIpKSkKcD1ILmMoci5xKHMsIm5hbWUiKSkK
+bz1yLnEocywic3VidHJlZSIpCm89bz09bnVsbD9udWxsOkwubUsobykKQy5ObS5pKG4sbmV3IEwuWloo
+cSxwLG8sSC5jKHIucShzLCJwYXRoIikpLEguYyhyLnEocywiaHJlZiIpKSxILldZKHIucShzLCJlZGl0
+Q291bnQiKSkpKX1yZXR1cm4gbn0sCnAyOmZ1bmN0aW9uKGEpe3N3aXRjaChhKXtjYXNlImRpcmVjdG9y
+eSI6cmV0dXJuIEMuWTIKY2FzZSJmaWxlIjpyZXR1cm4gQy5yZgpkZWZhdWx0OnRocm93IEguYihQLlBW
+KCJVbnJlY29nbml6ZWQgbmF2aWdhdGlvbiB0cmVlIG5vZGUgdHlwZTogIitILmQoYSkpKX19LApaWjpm
+dW5jdGlvbiBaWihhLGIsYyxkLGUsZil7dmFyIF89dGhpcwpfLmE9YQpfLmI9YgpfLmM9YwpfLmQ9ZApf
+LmU9ZQpfLmY9Zn0sCk85OmZ1bmN0aW9uIE85KGEpe3RoaXMuYj1hfSwKSVY6ZnVuY3Rpb24gSVYoYSxi
+LGMsZCl7dmFyIF89dGhpcwpfLmQ9YQpfLmU9YgpfLmY9YwpfLnI9ZH19LE09ewpZRjpmdW5jdGlvbihh
+LGIpe3ZhciB0LHMscixxLHAsbyxuCmZvcih0PWIubGVuZ3RoLHM9MTtzPHQ7KytzKXtpZihiW3NdPT1u
+dWxsfHxiW3MtMV0hPW51bGwpY29udGludWUKZm9yKDt0Pj0xO3Q9cil7cj10LTEKaWYoYltyXSE9bnVs
+bClicmVha31xPW5ldyBQLlJuKCIiKQpwPWErIigiCnEuYT1wCm89SC5xQyhiLDAsdCxILnQ2KGIpLmMp
+Cm49by4kdGkKbj1wK25ldyBILmxKKG8sbi5DKCJxVShhTC5FKSIpLmEobmV3IE0uTm8oKSksbi5DKCJs
+SjxhTC5FLHFVPiIpKS56VigwLCIsICIpCnEuYT1uCnEuYT1uKygiKTogcGFydCAiKyhzLTEpKyIgd2Fz
+IG51bGwsIGJ1dCBwYXJ0ICIrcysiIHdhcyBub3QuIikKdGhyb3cgSC5iKFAueFkocS5aKDApKSl9fSwK
+bEk6ZnVuY3Rpb24gbEkoYSl7dGhpcy5hPWF9LApNaTpmdW5jdGlvbiBNaSgpe30sCnE3OmZ1bmN0aW9u
+IHE3KCl7fSwKTm86ZnVuY3Rpb24gTm8oKXt9fSxYPXsKQ0w6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzLHIs
+cSxwLG89Yi54WihhKQpiLmhLKGEpCmlmKG8hPW51bGwpYT1KLktWKGEsby5sZW5ndGgpCnQ9dS5zCnM9
+SC5WTShbXSx0KQpyPUguVk0oW10sdCkKdD1hLmxlbmd0aAppZih0IT09MCYmYi5yNChDLnhCLlcoYSww
+KSkpe2lmKDA+PXQpcmV0dXJuIEguayhhLDApCkMuTm0uaShyLGFbMF0pCnE9MX1lbHNle0MuTm0uaShy
+LCIiKQpxPTB9Zm9yKHA9cTtwPHQ7KytwKWlmKGIucjQoQy54Qi5XKGEscCkpKXtDLk5tLmkocyxDLnhC
+Lk5qKGEscSxwKSkKQy5ObS5pKHIsYVtwXSkKcT1wKzF9aWYocTx0KXtDLk5tLmkocyxDLnhCLkcoYSxx
+KSkKQy5ObS5pKHIsIiIpfXJldHVybiBuZXcgWC5XRChiLG8scyxyKX0sCldEOmZ1bmN0aW9uIFdEKGEs
+YixjLGQpe3ZhciBfPXRoaXMKXy5hPWEKXy5iPWIKXy5kPWMKXy5lPWR9LApxUjpmdW5jdGlvbiBxUihh
+KXt0aGlzLmE9YX0sCkk3OmZ1bmN0aW9uKGEpe3JldHVybiBuZXcgWC5kdihhKX0sCmR2OmZ1bmN0aW9u
+IGR2KGEpe3RoaXMuYT1hfX0sTz17ClJoOmZ1bmN0aW9uKCl7dmFyIHQscz1udWxsCmlmKFAudW8oKS5n
+RmkoKSE9PSJmaWxlIilyZXR1cm4gJC5FYigpCnQ9UC51bygpCmlmKCFDLnhCLlRjKHQuZ0lpKHQpLCIv
+IikpcmV0dXJuICQuRWIoKQppZihQLktMKHMsImEvYiIscyxzLHMscyxzKS50NCgpPT09ImFcXGIiKXJl
+dHVybiAkLktrKCkKcmV0dXJuICQuYkQoKX0sCnpMOmZ1bmN0aW9uIHpMKCl7fX0sRT17T0Y6ZnVuY3Rp
+b24gT0YoYSxiLGMpe3RoaXMuZD1hCnRoaXMuZT1iCnRoaXMuZj1jfX0sRj17cnU6ZnVuY3Rpb24gcnUo
+YSxiLGMsZCl7dmFyIF89dGhpcwpfLmQ9YQpfLmU9YgpfLmY9YwpfLnI9ZH19LEQ9ewpSWDpmdW5jdGlv
+bigpe3ZhciB0LHMscj1QLnVvKCkKaWYoci5ETigwLCQuSTYpKXJldHVybiAkLkZmCiQuSTY9cgppZigk
+LkhrKCk9PSQuRWIoKSlyZXR1cm4gJC5GZj1yLlpJKCIuIikuWigwKQplbHNle3Q9ci50NCgpCnM9dC5s
+ZW5ndGgtMQpyZXR1cm4gJC5GZj1zPT09MD90OkMueEIuTmoodCwwLHMpfX0sCm5yOmZ1bmN0aW9uKGEs
+Yil7dmFyIHQ9bnVsbApyZXR1cm4gJC5uVSgpLnE3KDAsYSxiLHQsdCx0LHQsdCx0KX19CnZhciB3PVtD
+LEgsSixQLFcsVSxCLFQsTCxNLFgsTyxFLEYsRF0KaHVua0hlbHBlcnMuc2V0RnVuY3Rpb25OYW1lc0lm
+TmVjZXNzYXJ5KHcpCnZhciAkPXt9CkguRksucHJvdG90eXBlPXt9CkoudkIucHJvdG90eXBlPXsKRE46
+ZnVuY3Rpb24oYSxiKXtyZXR1cm4gYT09PWJ9LApnaU86ZnVuY3Rpb24oYSl7cmV0dXJuIEguZVEoYSl9
+LApaOmZ1bmN0aW9uKGEpe3JldHVybiJJbnN0YW5jZSBvZiAnIitILmQoSC5saChhKSkrIicifSwKZTc6
+ZnVuY3Rpb24oYSxiKXt1Lm8uYShiKQp0aHJvdyBILmIoUC5scihhLGIuZ1dhKCksYi5nbmQoKSxiLmdW
+bSgpKSl9fQpKLnlFLnByb3RvdHlwZT17Clo6ZnVuY3Rpb24oYSl7cmV0dXJuIFN0cmluZyhhKX0sCmdp
+TzpmdW5jdGlvbihhKXtyZXR1cm4gYT81MTkwMTg6MjE4MTU5fSwKJGlhMjoxfQpKLllFLnByb3RvdHlw
+ZT17CkROOmZ1bmN0aW9uKGEsYil7cmV0dXJuIG51bGw9PWJ9LApaOmZ1bmN0aW9uKGEpe3JldHVybiJu
+dWxsIn0sCmdpTzpmdW5jdGlvbihhKXtyZXR1cm4gMH0sCmU3OmZ1bmN0aW9uKGEsYil7cmV0dXJuIHRo
+aXMuU2ooYSx1Lm8uYShiKSl9LAokaWM4OjF9CkouTUYucHJvdG90eXBlPXsKZ2lPOmZ1bmN0aW9uKGEp
+e3JldHVybiAwfSwKWjpmdW5jdGlvbihhKXtyZXR1cm4gU3RyaW5nKGEpfSwKJGl2bToxfQpKLmlDLnBy
+b3RvdHlwZT17fQpKLmtkLnByb3RvdHlwZT17fQpKLmM1LnByb3RvdHlwZT17Clo6ZnVuY3Rpb24oYSl7
+dmFyIHQ9YVskLndRKCldCmlmKHQ9PW51bGwpcmV0dXJuIHRoaXMudChhKQpyZXR1cm4iSmF2YVNjcmlw
+dCBmdW5jdGlvbiBmb3IgIitILmQoSi5BYyh0KSl9LAokUzpmdW5jdGlvbigpe3JldHVybntmdW5jOjEs
+b3B0OlssLCwsLCwsLCwsLCwsLCwsXX19LAokaUVIOjF9CkouamQucHJvdG90eXBlPXsKaTpmdW5jdGlv
+bihhLGIpe0gudDYoYSkuYy5hKGIpCmlmKCEhYS5maXhlZCRsZW5ndGgpSC52aChQLkw0KCJhZGQiKSkK
+YS5wdXNoKGIpfSwKVzQ6ZnVuY3Rpb24oYSxiKXt2YXIgdAppZighIWEuZml4ZWQkbGVuZ3RoKUgudmgo
+UC5MNCgicmVtb3ZlQXQiKSkKdD1hLmxlbmd0aAppZihiPj10KXRocm93IEguYihQLk83KGIsbnVsbCkp
+CnJldHVybiBhLnNwbGljZShiLDEpWzBdfSwKVUc6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0LHMscgpILnQ2
+KGEpLkMoImNYPDE+IikuYShjKQppZighIWEuZml4ZWQkbGVuZ3RoKUgudmgoUC5MNCgiaW5zZXJ0QWxs
+IikpCnQ9YS5sZW5ndGgKUC53QShiLDAsdCwiaW5kZXgiKQpzPWMubGVuZ3RoCnRoaXMuc0EoYSx0K3Mp
+CnI9YitzCnRoaXMuWVcoYSxyLGEubGVuZ3RoLGEsYikKdGhpcy52ZyhhLGIscixjKX0sCm12OmZ1bmN0
+aW9uKGEpe2lmKCEhYS5maXhlZCRsZW5ndGgpSC52aChQLkw0KCJyZW1vdmVMYXN0IikpCmlmKGEubGVu
+Z3RoPT09MCl0aHJvdyBILmIoSC5IWShhLC0xKSkKcmV0dXJuIGEucG9wKCl9LApGVjpmdW5jdGlvbihh
+LGIpe3ZhciB0CkgudDYoYSkuQygiY1g8MT4iKS5hKGIpCmlmKCEhYS5maXhlZCRsZW5ndGgpSC52aChQ
+Lkw0KCJhZGRBbGwiKSkKZm9yKHQ9Si5JVChiKTt0LkYoKTspYS5wdXNoKHQuZ2woKSl9LApFMjpmdW5j
+dGlvbihhLGIsYyl7dmFyIHQ9SC50NihhKQpyZXR1cm4gbmV3IEgubEooYSx0LktxKGMpLkMoIjEoMiki
+KS5hKGIpLHQuQygiQDwxPiIpLktxKGMpLkMoImxKPDEsMj4iKSl9LAp6VjpmdW5jdGlvbihhLGIpe3Zh
+ciB0LHM9UC5POChhLmxlbmd0aCwiIiwhMSx1Lk4pCmZvcih0PTA7dDxhLmxlbmd0aDsrK3QpdGhpcy5Z
+KHMsdCxILmQoYVt0XSkpCnJldHVybiBzLmpvaW4oYil9LApOMDpmdW5jdGlvbihhLGIsYyxkKXt2YXIg
+dCxzLHIKZC5hKGIpCkgudDYoYSkuS3EoZCkuQygiMSgxLDIpIikuYShjKQp0PWEubGVuZ3RoCmZvcihz
+PWIscj0wO3I8dDsrK3Ipe3M9Yy4kMihzLGFbcl0pCmlmKGEubGVuZ3RoIT09dCl0aHJvdyBILmIoUC5h
+NChhKSl9cmV0dXJuIHN9LApFOmZ1bmN0aW9uKGEsYil7aWYoYjwwfHxiPj1hLmxlbmd0aClyZXR1cm4g
+SC5rKGEsYikKcmV0dXJuIGFbYl19LApENjpmdW5jdGlvbihhLGIsYyl7aWYoYjwwfHxiPmEubGVuZ3Ro
+KXRocm93IEguYihQLlRFKGIsMCxhLmxlbmd0aCwic3RhcnQiLG51bGwpKQppZihjPGJ8fGM+YS5sZW5n
+dGgpdGhyb3cgSC5iKFAuVEUoYyxiLGEubGVuZ3RoLCJlbmQiLG51bGwpKQppZihiPT09YylyZXR1cm4g
+SC5WTShbXSxILnQ2KGEpKQpyZXR1cm4gSC5WTShhLnNsaWNlKGIsYyksSC50NihhKSl9LApndEg6ZnVu
+Y3Rpb24oYSl7aWYoYS5sZW5ndGg+MClyZXR1cm4gYVswXQp0aHJvdyBILmIoSC5XcCgpKX0sCmdyWjpm
+dW5jdGlvbihhKXt2YXIgdD1hLmxlbmd0aAppZih0PjApcmV0dXJuIGFbdC0xXQp0aHJvdyBILmIoSC5X
+cCgpKX0sCllXOmZ1bmN0aW9uKGEsYixjLGQsZSl7dmFyIHQscyxyLHEscD1ILnQ2KGEpCnAuQygiY1g8
+MT4iKS5hKGQpCmlmKCEhYS5pbW11dGFibGUkbGlzdClILnZoKFAuTDQoInNldFJhbmdlIikpClAuakIo
+YixjLGEubGVuZ3RoKQp0PWMtYgppZih0PT09MClyZXR1cm4KUC5rMShlLCJza2lwQ291bnQiKQppZihw
+LkMoInpNPDE+IikuYihkKSl7cz1lCnI9ZH1lbHNle3I9SC5xQyhkLGUsbnVsbCxILnQ2KGQpLmMpLnR0
+KDAsITEpCnM9MH1pZihzK3Q+ci5sZW5ndGgpdGhyb3cgSC5iKEguYXIoKSkKaWYoczxiKWZvcihxPXQt
+MTtxPj0wOy0tcSl7cD1zK3EKaWYocD49ci5sZW5ndGgpcmV0dXJuIEguayhyLHApCmFbYitxXT1yW3Bd
+fWVsc2UgZm9yKHE9MDtxPHQ7KytxKXtwPXMrcQppZihwPj1yLmxlbmd0aClyZXR1cm4gSC5rKHIscCkK
+YVtiK3FdPXJbcF19fSwKdmc6ZnVuY3Rpb24oYSxiLGMsZCl7cmV0dXJuIHRoaXMuWVcoYSxiLGMsZCww
+KX0sClZyOmZ1bmN0aW9uKGEsYil7dmFyIHQscwpILnQ2KGEpLkMoImEyKDEpIikuYShiKQp0PWEubGVu
+Z3RoCmZvcihzPTA7czx0Oysrcyl7aWYoSC5vVChiLiQxKGFbc10pKSlyZXR1cm4hMAppZihhLmxlbmd0
+aCE9PXQpdGhyb3cgSC5iKFAuYTQoYSkpfXJldHVybiExfSwKdGc6ZnVuY3Rpb24oYSxiKXt2YXIgdApm
+b3IodD0wO3Q8YS5sZW5ndGg7Kyt0KWlmKEouUk0oYVt0XSxiKSlyZXR1cm4hMApyZXR1cm4hMX0sClo6
+ZnVuY3Rpb24oYSl7cmV0dXJuIFAuV0UoYSwiWyIsIl0iKX0sCmdrejpmdW5jdGlvbihhKXtyZXR1cm4g
+bmV3IEoubTEoYSxhLmxlbmd0aCxILnQ2KGEpLkMoIm0xPDE+IikpfSwKZ2lPOmZ1bmN0aW9uKGEpe3Jl
+dHVybiBILmVRKGEpfSwKZ0E6ZnVuY3Rpb24oYSl7cmV0dXJuIGEubGVuZ3RofSwKc0E6ZnVuY3Rpb24o
+YSxiKXtpZighIWEuZml4ZWQkbGVuZ3RoKUgudmgoUC5MNCgic2V0IGxlbmd0aCIpKQphLmxlbmd0aD1i
+fSwKcTpmdW5jdGlvbihhLGIpe0guV1koYikKaWYoYj49YS5sZW5ndGh8fGI8MCl0aHJvdyBILmIoSC5I
+WShhLGIpKQpyZXR1cm4gYVtiXX0sClk6ZnVuY3Rpb24oYSxiLGMpe0gudDYoYSkuYy5hKGMpCmlmKCEh
+YS5pbW11dGFibGUkbGlzdClILnZoKFAuTDQoImluZGV4ZWQgc2V0IikpCmlmKGI+PWEubGVuZ3RofHxi
+PDApdGhyb3cgSC5iKEguSFkoYSxiKSkKYVtiXT1jfSwKJGliUToxLAokaWNYOjEsCiRpek06MX0KSi5Q
+by5wcm90b3R5cGU9e30KSi5tMS5wcm90b3R5cGU9ewpnbDpmdW5jdGlvbigpe3JldHVybiB0aGlzLmR9
+LApGOmZ1bmN0aW9uKCl7dmFyIHQscz10aGlzLHI9cy5hLHE9ci5sZW5ndGgKaWYocy5iIT09cSl0aHJv
+dyBILmIoSC5sayhyKSkKdD1zLmMKaWYodD49cSl7cy5zSChudWxsKQpyZXR1cm4hMX1zLnNIKHJbdF0p
+Oysrcy5jCnJldHVybiEwfSwKc0g6ZnVuY3Rpb24oYSl7dGhpcy5kPXRoaXMuJHRpLmMuYShhKX0sCiRp
+QW46MX0KSi5xSS5wcm90b3R5cGU9ewp6UTpmdW5jdGlvbihhKXtpZihhPjApe2lmKGEhPT0xLzApcmV0
+dXJuIE1hdGgucm91bmQoYSl9ZWxzZSBpZihhPi0xLzApcmV0dXJuIDAtTWF0aC5yb3VuZCgwLWEpCnRo
+cm93IEguYihQLkw0KCIiK2ErIi5yb3VuZCgpIikpfSwKV1o6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzLHIs
+cQppZihiPDJ8fGI+MzYpdGhyb3cgSC5iKFAuVEUoYiwyLDM2LCJyYWRpeCIsbnVsbCkpCnQ9YS50b1N0
+cmluZyhiKQppZihDLnhCLm0odCx0Lmxlbmd0aC0xKSE9PTQxKXJldHVybiB0CnM9L14oW1xkYS16XSsp
+KD86XC4oW1xkYS16XSspKT9cKGVcKyhcZCspXCkkLy5leGVjKHQpCmlmKHM9PW51bGwpSC52aChQLkw0
+KCJVbmV4cGVjdGVkIHRvU3RyaW5nIHJlc3VsdDogIit0KSkKcj1zLmxlbmd0aAppZigxPj1yKXJldHVy
+biBILmsocywxKQp0PXNbMV0KaWYoMz49cilyZXR1cm4gSC5rKHMsMykKcT0rc1szXQpyPXNbMl0KaWYo
+ciE9bnVsbCl7dCs9cgpxLT1yLmxlbmd0aH1yZXR1cm4gdCtDLnhCLkl4KCIwIixxKX0sClo6ZnVuY3Rp
+b24oYSl7aWYoYT09PTAmJjEvYTwwKXJldHVybiItMC4wIgplbHNlIHJldHVybiIiK2F9LApnaU86ZnVu
+Y3Rpb24oYSl7dmFyIHQscyxyLHEscD1hfDAKaWYoYT09PXApcmV0dXJuIDUzNjg3MDkxMSZwCnQ9TWF0
+aC5hYnMoYSkKcz1NYXRoLmxvZyh0KS8wLjY5MzE0NzE4MDU1OTk0NTN8MApyPU1hdGgucG93KDIscykK
+cT10PDE/dC9yOnIvdApyZXR1cm4gNTM2ODcwOTExJigocSo5MDA3MTk5MjU0NzQwOTkyfDApKyhxKjM1
+NDIyNDMxODExNzY1MjF8MCkpKjU5OTE5NytzKjEyNTl9LAp6WTpmdW5jdGlvbihhLGIpe3ZhciB0PWEl
+YgppZih0PT09MClyZXR1cm4gMAppZih0PjApcmV0dXJuIHQKaWYoYjwwKXJldHVybiB0LWIKZWxzZSBy
+ZXR1cm4gdCtifSwKd0c6ZnVuY3Rpb24oYSxiKXt2YXIgdAppZihhPjApdD10aGlzLnAzKGEsYikKZWxz
+ZXt0PWI+MzE/MzE6Ygp0PWE+PnQ+Pj4wfXJldHVybiB0fSwKYmY6ZnVuY3Rpb24oYSxiKXtpZihiPDAp
+dGhyb3cgSC5iKEguSShiKSkKcmV0dXJuIHRoaXMucDMoYSxiKX0sCnAzOmZ1bmN0aW9uKGEsYil7cmV0
+dXJuIGI+MzE/MDphPj4+Yn0sCiRpQ1A6MSwKJGlsZjoxfQpKLnVyLnByb3RvdHlwZT17JGlJZjoxfQpK
+LlZBLnByb3RvdHlwZT17fQpKLkRyLnByb3RvdHlwZT17Cm06ZnVuY3Rpb24oYSxiKXtpZihiPDApdGhy
+b3cgSC5iKEguSFkoYSxiKSkKaWYoYj49YS5sZW5ndGgpSC52aChILkhZKGEsYikpCnJldHVybiBhLmNo
+YXJDb2RlQXQoYil9LApXOmZ1bmN0aW9uKGEsYil7aWYoYj49YS5sZW5ndGgpdGhyb3cgSC5iKEguSFko
+YSxiKSkKcmV0dXJuIGEuY2hhckNvZGVBdChiKX0sCmRkOmZ1bmN0aW9uKGEsYil7cmV0dXJuIG5ldyBI
+Lk5GKGIsYSwwKX0sCmg6ZnVuY3Rpb24oYSxiKXtpZih0eXBlb2YgYiE9InN0cmluZyIpdGhyb3cgSC5i
+KFAuTDMoYixudWxsLG51bGwpKQpyZXR1cm4gYStifSwKVGM6ZnVuY3Rpb24oYSxiKXt2YXIgdD1iLmxl
+bmd0aCxzPWEubGVuZ3RoCmlmKHQ+cylyZXR1cm4hMQpyZXR1cm4gYj09PXRoaXMuRyhhLHMtdCl9LApp
+NzpmdW5jdGlvbihhLGIsYyxkKXt2YXIgdD1QLmpCKGIsYyxhLmxlbmd0aCkscz1hLnN1YnN0cmluZygw
+LGIpLHI9YS5zdWJzdHJpbmcodCkKcmV0dXJuIHMrZCtyfSwKUWk6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0
+CmlmKGM8MHx8Yz5hLmxlbmd0aCl0aHJvdyBILmIoUC5URShjLDAsYS5sZW5ndGgsbnVsbCxudWxsKSkK
+dD1jK2IubGVuZ3RoCmlmKHQ+YS5sZW5ndGgpcmV0dXJuITEKcmV0dXJuIGI9PT1hLnN1YnN0cmluZyhj
+LHQpfSwKbjpmdW5jdGlvbihhLGIpe3JldHVybiB0aGlzLlFpKGEsYiwwKX0sCk5qOmZ1bmN0aW9uKGEs
+YixjKXtpZihjPT1udWxsKWM9YS5sZW5ndGgKaWYoYjwwKXRocm93IEguYihQLk83KGIsbnVsbCkpCmlm
+KGI+Yyl0aHJvdyBILmIoUC5PNyhiLG51bGwpKQppZihjPmEubGVuZ3RoKXRocm93IEguYihQLk83KGMs
+bnVsbCkpCnJldHVybiBhLnN1YnN0cmluZyhiLGMpfSwKRzpmdW5jdGlvbihhLGIpe3JldHVybiB0aGlz
+Lk5qKGEsYixudWxsKX0sCmhjOmZ1bmN0aW9uKGEpe3JldHVybiBhLnRvTG93ZXJDYXNlKCl9LApiUzpm
+dW5jdGlvbihhKXt2YXIgdCxzLHIscT1hLnRyaW0oKSxwPXEubGVuZ3RoCmlmKHA9PT0wKXJldHVybiBx
+CmlmKHRoaXMuVyhxLDApPT09MTMzKXt0PUoubW0ocSwxKQppZih0PT09cClyZXR1cm4iIn1lbHNlIHQ9
+MApzPXAtMQpyPXRoaXMubShxLHMpPT09MTMzP0ouYzEocSxzKTpwCmlmKHQ9PT0wJiZyPT09cClyZXR1
+cm4gcQpyZXR1cm4gcS5zdWJzdHJpbmcodCxyKX0sCkl4OmZ1bmN0aW9uKGEsYil7dmFyIHQscwppZigw
+Pj1iKXJldHVybiIiCmlmKGI9PT0xfHxhLmxlbmd0aD09PTApcmV0dXJuIGEKaWYoYiE9PWI+Pj4wKXRo
+cm93IEguYihDLkVxKQpmb3IodD1hLHM9IiI7ITA7KXtpZigoYiYxKT09PTEpcz10K3MKYj1iPj4+MQpp
+ZihiPT09MClicmVhawp0Kz10fXJldHVybiBzfSwKWFU6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0CmlmKGM8
+MHx8Yz5hLmxlbmd0aCl0aHJvdyBILmIoUC5URShjLDAsYS5sZW5ndGgsbnVsbCxudWxsKSkKdD1hLmlu
+ZGV4T2YoYixjKQpyZXR1cm4gdH0sCk9ZOmZ1bmN0aW9uKGEsYil7cmV0dXJuIHRoaXMuWFUoYSxiLDAp
+fSwKUGs6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0LHMKaWYoYz09bnVsbCljPWEubGVuZ3RoCmVsc2UgaWYo
+YzwwfHxjPmEubGVuZ3RoKXRocm93IEguYihQLlRFKGMsMCxhLmxlbmd0aCxudWxsLG51bGwpKQp0PWIu
+bGVuZ3RoCnM9YS5sZW5ndGgKaWYoYyt0PnMpYz1zLXQKcmV0dXJuIGEubGFzdEluZGV4T2YoYixjKX0s
+CmNuOmZ1bmN0aW9uKGEsYil7cmV0dXJuIHRoaXMuUGsoYSxiLG51bGwpfSwKSXM6ZnVuY3Rpb24oYSxi
+LGMpe3ZhciB0PWEubGVuZ3RoCmlmKGM+dCl0aHJvdyBILmIoUC5URShjLDAsdCxudWxsLG51bGwpKQpy
+ZXR1cm4gSC5tMihhLGIsYyl9LAp0ZzpmdW5jdGlvbihhLGIpe3JldHVybiB0aGlzLklzKGEsYiwwKX0s
+Clo6ZnVuY3Rpb24oYSl7cmV0dXJuIGF9LApnaU86ZnVuY3Rpb24oYSl7dmFyIHQscyxyCmZvcih0PWEu
+bGVuZ3RoLHM9MCxyPTA7cjx0Oysrcil7cz01MzY4NzA5MTEmcythLmNoYXJDb2RlQXQocikKcz01MzY4
+NzA5MTEmcysoKDUyNDI4NyZzKTw8MTApCnNePXM+PjZ9cz01MzY4NzA5MTEmcysoKDY3MTA4ODYzJnMp
+PDwzKQpzXj1zPj4xMQpyZXR1cm4gNTM2ODcwOTExJnMrKCgxNjM4MyZzKTw8MTUpfSwKZ0E6ZnVuY3Rp
+b24oYSl7cmV0dXJuIGEubGVuZ3RofSwKcTpmdW5jdGlvbihhLGIpe0guV1koYikKaWYoYj49YS5sZW5n
+dGh8fCExKXRocm93IEguYihILkhZKGEsYikpCnJldHVybiBhW2JdfSwKJGl2WDoxLAokaXFVOjF9Ckgu
+bmQucHJvdG90eXBlPXsKWjpmdW5jdGlvbihhKXt2YXIgdD0iTGF0ZUluaXRpYWxpemF0aW9uRXJyb3I6
+ICIrdGhpcy5hCnJldHVybiB0fX0KSC5xai5wcm90b3R5cGU9ewpnQTpmdW5jdGlvbihhKXtyZXR1cm4g
+dGhpcy5hLmxlbmd0aH0sCnE6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gQy54Qi5tKHRoaXMuYSxILldZKGIp
+KX19CkguYlEucHJvdG90eXBlPXt9CkguYUwucHJvdG90eXBlPXsKZ2t6OmZ1bmN0aW9uKGEpe3ZhciB0
+PXRoaXMKcmV0dXJuIG5ldyBILmE3KHQsdC5nQSh0KSxILkxoKHQpLkMoImE3PGFMLkU+IikpfSwKelY6
+ZnVuY3Rpb24oYSxiKXt2YXIgdCxzLHIscT10aGlzLHA9cS5nQShxKQppZihiLmxlbmd0aCE9PTApe2lm
+KHA9PT0wKXJldHVybiIiCnQ9SC5kKHEuRSgwLDApKQppZihwIT09cS5nQShxKSl0aHJvdyBILmIoUC5h
+NChxKSkKZm9yKHM9dCxyPTE7cjxwOysrcil7cz1zK2IrSC5kKHEuRSgwLHIpKQppZihwIT09cS5nQShx
+KSl0aHJvdyBILmIoUC5hNChxKSl9cmV0dXJuIHMuY2hhckNvZGVBdCgwKT09MD9zOnN9ZWxzZXtmb3Io
+cj0wLHM9IiI7cjxwOysrcil7cys9SC5kKHEuRSgwLHIpKQppZihwIT09cS5nQShxKSl0aHJvdyBILmIo
+UC5hNChxKSl9cmV0dXJuIHMuY2hhckNvZGVBdCgwKT09MD9zOnN9fSwKZXY6ZnVuY3Rpb24oYSxiKXty
+ZXR1cm4gdGhpcy5HRygwLEguTGgodGhpcykuQygiYTIoYUwuRSkiKS5hKGIpKX0sCkUyOmZ1bmN0aW9u
+KGEsYixjKXt2YXIgdD1ILkxoKHRoaXMpCnJldHVybiBuZXcgSC5sSih0aGlzLHQuS3EoYykuQygiMShh
+TC5FKSIpLmEoYiksdC5DKCJAPGFMLkU+IikuS3EoYykuQygibEo8MSwyPiIpKX19CkgubkgucHJvdG90
+eXBlPXsKZ1VEOmZ1bmN0aW9uKCl7dmFyIHQ9Si5IKHRoaXMuYSkscz10aGlzLmMKaWYocz09bnVsbHx8
+cz50KXJldHVybiB0CnJldHVybiBzfSwKZ0FzOmZ1bmN0aW9uKCl7dmFyIHQ9Si5IKHRoaXMuYSkscz10
+aGlzLmIKaWYocz50KXJldHVybiB0CnJldHVybiBzfSwKZ0E6ZnVuY3Rpb24oYSl7dmFyIHQscz1KLkgo
+dGhpcy5hKSxyPXRoaXMuYgppZihyPj1zKXJldHVybiAwCnQ9dGhpcy5jCmlmKHQ9PW51bGx8fHQ+PXMp
+cmV0dXJuIHMtcgppZih0eXBlb2YgdCE9PSJudW1iZXIiKXJldHVybiB0LkhOKCkKcmV0dXJuIHQtcn0s
+CkU6ZnVuY3Rpb24oYSxiKXt2YXIgdD10aGlzLHM9dC5nQXMoKStiCmlmKGI8MHx8cz49dC5nVUQoKSl0
+aHJvdyBILmIoUC50KGIsdCwiaW5kZXgiLG51bGwsbnVsbCkpCnJldHVybiBKLkdBKHQuYSxzKX0sCnR0
+OmZ1bmN0aW9uKGEsYil7dmFyIHQscyxyLHE9dGhpcyxwPXEuYixvPXEuYSxuPUouVTYobyksbT1uLmdB
+KG8pLGw9cS5jCmlmKGwhPW51bGwmJmw8bSltPWwKaWYodHlwZW9mIG0hPT0ibnVtYmVyIilyZXR1cm4g
+bS5ITigpCnQ9bS1wCmlmKHQ8PTApe289Si5RaSgwLHEuJHRpLmMpCnJldHVybiBvfXM9UC5POCh0LG4u
+RShvLHApLCExLHEuJHRpLmMpCmZvcihyPTE7cjx0Oysrcil7Qy5ObS5ZKHMscixuLkUobyxwK3IpKQpp
+ZihuLmdBKG8pPG0pdGhyb3cgSC5iKFAuYTQocSkpfXJldHVybiBzfX0KSC5hNy5wcm90b3R5cGU9ewpn
+bDpmdW5jdGlvbigpe3ZhciB0PXRoaXMuZApyZXR1cm4gdH0sCkY6ZnVuY3Rpb24oKXt2YXIgdCxzPXRo
+aXMscj1zLmEscT1KLlU2KHIpLHA9cS5nQShyKQppZihzLmIhPT1wKXRocm93IEguYihQLmE0KHIpKQp0
+PXMuYwppZih0Pj1wKXtzLnNJKG51bGwpCnJldHVybiExfXMuc0kocS5FKHIsdCkpOysrcy5jCnJldHVy
+biEwfSwKc0k6ZnVuY3Rpb24oYSl7dGhpcy5kPXRoaXMuJHRpLmMuYShhKX0sCiRpQW46MX0KSC5pMS5w
+cm90b3R5cGU9ewpna3o6ZnVuY3Rpb24oYSl7dmFyIHQ9SC5MaCh0aGlzKQpyZXR1cm4gbmV3IEguTUgo
+Si5JVCh0aGlzLmEpLHRoaXMuYix0LkMoIkA8MT4iKS5LcSh0LlFbMV0pLkMoIk1IPDEsMj4iKSl9LApn
+QTpmdW5jdGlvbihhKXtyZXR1cm4gSi5IKHRoaXMuYSl9fQpILnh5LnByb3RvdHlwZT17JGliUToxfQpI
+Lk1ILnByb3RvdHlwZT17CkY6ZnVuY3Rpb24oKXt2YXIgdD10aGlzLHM9dC5iCmlmKHMuRigpKXt0LnNJ
+KHQuYy4kMShzLmdsKCkpKQpyZXR1cm4hMH10LnNJKG51bGwpCnJldHVybiExfSwKZ2w6ZnVuY3Rpb24o
+KXt2YXIgdD10aGlzLmEKcmV0dXJuIHR9LApzSTpmdW5jdGlvbihhKXt0aGlzLmE9dGhpcy4kdGkuUVsx
+XS5hKGEpfX0KSC5sSi5wcm90b3R5cGU9ewpnQTpmdW5jdGlvbihhKXtyZXR1cm4gSi5IKHRoaXMuYSl9
+LApFOmZ1bmN0aW9uKGEsYil7cmV0dXJuIHRoaXMuYi4kMShKLkdBKHRoaXMuYSxiKSl9fQpILlU1LnBy
+b3RvdHlwZT17CmdrejpmdW5jdGlvbihhKXtyZXR1cm4gbmV3IEgudkcoSi5JVCh0aGlzLmEpLHRoaXMu
+Yix0aGlzLiR0aS5DKCJ2RzwxPiIpKX19CkgudkcucHJvdG90eXBlPXsKRjpmdW5jdGlvbigpe3ZhciB0
+LHMKZm9yKHQ9dGhpcy5hLHM9dGhpcy5iO3QuRigpOylpZihILm9UKHMuJDEodC5nbCgpKSkpcmV0dXJu
+ITAKcmV0dXJuITF9LApnbDpmdW5jdGlvbigpe3JldHVybiB0aGlzLmEuZ2woKX19CkguU1UucHJvdG90
+eXBlPXt9CkguUmUucHJvdG90eXBlPXsKWTpmdW5jdGlvbihhLGIsYyl7SC5MaCh0aGlzKS5DKCJSZS5F
+IikuYShjKQp0aHJvdyBILmIoUC5MNCgiQ2Fubm90IG1vZGlmeSBhbiB1bm1vZGlmaWFibGUgbGlzdCIp
+KX19CkgudzIucHJvdG90eXBlPXt9Ckgud3YucHJvdG90eXBlPXsKZ2lPOmZ1bmN0aW9uKGEpe3ZhciB0
+PXRoaXMuX2hhc2hDb2RlCmlmKHQhPW51bGwpcmV0dXJuIHQKdD01MzY4NzA5MTEmNjY0NTk3KkouaGYo
+dGhpcy5hKQp0aGlzLl9oYXNoQ29kZT10CnJldHVybiB0fSwKWjpmdW5jdGlvbihhKXtyZXR1cm4nU3lt
+Ym9sKCInK0guZCh0aGlzLmEpKyciKSd9LApETjpmdW5jdGlvbihhLGIpe2lmKGI9PW51bGwpcmV0dXJu
+ITEKcmV0dXJuIGIgaW5zdGFuY2VvZiBILnd2JiZ0aGlzLmE9PWIuYX0sCiRpR0Q6MX0KSC5QRC5wcm90
+b3R5cGU9e30KSC5XVS5wcm90b3R5cGU9ewpaOmZ1bmN0aW9uKGEpe3JldHVybiBQLm5PKHRoaXMpfSwK
+WTpmdW5jdGlvbihhLGIsYyl7dmFyIHQ9SC5MaCh0aGlzKQp0LmMuYShiKQp0LlFbMV0uYShjKQpILmRj
+KCl9LApnUHU6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMucTQoYSxILkxoKHRoaXMpLkMoIk4zPDEsMj4i
+KSl9LApxNDpmdW5jdGlvbihhLGIpe3ZhciB0PXRoaXMKcmV0dXJuIFAubDAoZnVuY3Rpb24oKXt2YXIg
+cz1hCnZhciByPTAscT0xLHAsbyxuLG0sbApyZXR1cm4gZnVuY3Rpb24gJGFzeW5jJGdQdShjLGQpe2lm
+KGM9PT0xKXtwPWQKcj1xfXdoaWxlKHRydWUpc3dpdGNoKHIpe2Nhc2UgMDpvPXQuZ1YoKSxvPW8uZ2t6
+KG8pLG49SC5MaCh0KSxuPW4uQygiQDwxPiIpLktxKG4uUVsxXSkuQygiTjM8MSwyPiIpCmNhc2UgMjpp
+Zighby5GKCkpe3I9MwpicmVha31tPW8uZ2woKQpsPXQucSgwLG0pCmwudG9TdHJpbmcKcj00CnJldHVy
+biBuZXcgUC5OMyhtLGwsbikKY2FzZSA0OnI9MgpicmVhawpjYXNlIDM6cmV0dXJuIFAuVGgoKQpjYXNl
+IDE6cmV0dXJuIFAuWW0ocCl9fX0sYil9LAokaVowOjF9CkguTFAucHJvdG90eXBlPXsKZ0E6ZnVuY3Rp
+b24oYSl7cmV0dXJuIHRoaXMuYX0sCng0OmZ1bmN0aW9uKGEpe2lmKHR5cGVvZiBhIT0ic3RyaW5nIily
+ZXR1cm4hMQppZigiX19wcm90b19fIj09PWEpcmV0dXJuITEKcmV0dXJuIHRoaXMuYi5oYXNPd25Qcm9w
+ZXJ0eShhKX0sCnE6ZnVuY3Rpb24oYSxiKXtpZighdGhpcy54NChiKSlyZXR1cm4gbnVsbApyZXR1cm4g
+dGhpcy5EKGIpfSwKRDpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5iW0guYyhhKV19LApLOmZ1bmN0aW9u
+KGEsYil7dmFyIHQscyxyLHEscD1ILkxoKHRoaXMpCnAuQygifigxLDIpIikuYShiKQp0PXRoaXMuYwpm
+b3Iocz10Lmxlbmd0aCxwPXAuUVsxXSxyPTA7cjxzOysrcil7cT10W3JdCmIuJDIocSxwLmEodGhpcy5E
+KHEpKSl9fSwKZ1Y6ZnVuY3Rpb24oKXtyZXR1cm4gbmV3IEguWFIodGhpcyxILkxoKHRoaXMpLkMoIlhS
+PDE+IikpfX0KSC5YUi5wcm90b3R5cGU9ewpna3o6ZnVuY3Rpb24oYSl7dmFyIHQ9dGhpcy5hLmMKcmV0
+dXJuIG5ldyBKLm0xKHQsdC5sZW5ndGgsSC50Nih0KS5DKCJtMTwxPiIpKX0sCmdBOmZ1bmN0aW9uKGEp
+e3JldHVybiB0aGlzLmEuYy5sZW5ndGh9fQpILkxJLnByb3RvdHlwZT17CmdXYTpmdW5jdGlvbigpe3Zh
+ciB0PXRoaXMuYQpyZXR1cm4gdH0sCmduZDpmdW5jdGlvbigpe3ZhciB0LHMscixxLHA9dGhpcwppZihw
+LmM9PT0xKXJldHVybiBDLmRuCnQ9cC5kCnM9dC5sZW5ndGgtcC5lLmxlbmd0aC1wLmYKaWYocz09PTAp
+cmV0dXJuIEMuZG4Kcj1bXQpmb3IocT0wO3E8czsrK3Epe2lmKHE+PXQubGVuZ3RoKXJldHVybiBILmso
+dCxxKQpyLnB1c2godFtxXSl9cmV0dXJuIEoudW4ocil9LApnVm06ZnVuY3Rpb24oKXt2YXIgdCxzLHIs
+cSxwLG8sbixtLGw9dGhpcwppZihsLmMhPT0wKXJldHVybiBDLkR4CnQ9bC5lCnM9dC5sZW5ndGgKcj1s
+LmQKcT1yLmxlbmd0aC1zLWwuZgppZihzPT09MClyZXR1cm4gQy5EeApwPW5ldyBILk41KHUuZW8pCmZv
+cihvPTA7bzxzOysrbyl7aWYobz49dC5sZW5ndGgpcmV0dXJuIEguayh0LG8pCm49dFtvXQptPXErbwpp
+ZihtPDB8fG0+PXIubGVuZ3RoKXJldHVybiBILmsocixtKQpwLlkoMCxuZXcgSC53dihuKSxyW21dKX1y
+ZXR1cm4gbmV3IEguUEQocCx1LmdGKX0sCiRpdlE6MX0KSC5Dai5wcm90b3R5cGU9ewokMjpmdW5jdGlv
+bihhLGIpe3ZhciB0CkguYyhhKQp0PXRoaXMuYQp0LmI9dC5iKyIkIitILmQoYSkKQy5ObS5pKHRoaXMu
+YixhKQpDLk5tLmkodGhpcy5jLGIpOysrdC5hfSwKJFM6MTN9CkguZjkucHJvdG90eXBlPXsKcVM6ZnVu
+Y3Rpb24oYSl7dmFyIHQscyxyPXRoaXMscT1uZXcgUmVnRXhwKHIuYSkuZXhlYyhhKQppZihxPT1udWxs
+KXJldHVybiBudWxsCnQ9T2JqZWN0LmNyZWF0ZShudWxsKQpzPXIuYgppZihzIT09LTEpdC5hcmd1bWVu
+dHM9cVtzKzFdCnM9ci5jCmlmKHMhPT0tMSl0LmFyZ3VtZW50c0V4cHI9cVtzKzFdCnM9ci5kCmlmKHMh
+PT0tMSl0LmV4cHI9cVtzKzFdCnM9ci5lCmlmKHMhPT0tMSl0Lm1ldGhvZD1xW3MrMV0Kcz1yLmYKaWYo
+cyE9PS0xKXQucmVjZWl2ZXI9cVtzKzFdCnJldHVybiB0fX0KSC5XMC5wcm90b3R5cGU9ewpaOmZ1bmN0
+aW9uKGEpe3ZhciB0PXRoaXMuYgppZih0PT1udWxsKXJldHVybiJOb1N1Y2hNZXRob2RFcnJvcjogIitI
+LmQodGhpcy5hKQpyZXR1cm4iTm9TdWNoTWV0aG9kRXJyb3I6IG1ldGhvZCBub3QgZm91bmQ6ICciK3Qr
+Iicgb24gbnVsbCJ9fQpILmF6LnByb3RvdHlwZT17Clo6ZnVuY3Rpb24oYSl7dmFyIHQscz10aGlzLHI9
+Ik5vU3VjaE1ldGhvZEVycm9yOiBtZXRob2Qgbm90IGZvdW5kOiAnIixxPXMuYgppZihxPT1udWxsKXJl
+dHVybiJOb1N1Y2hNZXRob2RFcnJvcjogIitILmQocy5hKQp0PXMuYwppZih0PT1udWxsKXJldHVybiBy
+K3ErIicgKCIrSC5kKHMuYSkrIikiCnJldHVybiByK3ErIicgb24gJyIrdCsiJyAoIitILmQocy5hKSsi
+KSJ9fQpILnZWLnByb3RvdHlwZT17Clo6ZnVuY3Rpb24oYSl7dmFyIHQ9dGhpcy5hCnJldHVybiB0Lmxl
+bmd0aD09PTA/IkVycm9yIjoiRXJyb3I6ICIrdH19CkguYnEucHJvdG90eXBlPXt9CkguQW0ucHJvdG90
+eXBlPXsKJDE6ZnVuY3Rpb24oYSl7aWYodS5XLmIoYSkpaWYoYS4kdGhyb3duSnNFcnJvcj09bnVsbClh
+LiR0aHJvd25Kc0Vycm9yPXRoaXMuYQpyZXR1cm4gYX0sCiRTOjZ9CkguWE8ucHJvdG90eXBlPXsKWjpm
+dW5jdGlvbihhKXt2YXIgdCxzPXRoaXMuYgppZihzIT1udWxsKXJldHVybiBzCnM9dGhpcy5hCnQ9cyE9
+PW51bGwmJnR5cGVvZiBzPT09Im9iamVjdCI/cy5zdGFjazpudWxsCnJldHVybiB0aGlzLmI9dD09bnVs
+bD8iIjp0fSwKJGlHejoxfQpILlRwLnByb3RvdHlwZT17Clo6ZnVuY3Rpb24oYSl7dmFyIHQ9dGhpcy5j
+b25zdHJ1Y3RvcixzPXQ9PW51bGw/bnVsbDp0Lm5hbWUKcmV0dXJuIkNsb3N1cmUgJyIrSC5OUShzPT1u
+dWxsPyJ1bmtub3duIjpzKSsiJyJ9LAokaUVIOjEsCmdRbDpmdW5jdGlvbigpe3JldHVybiB0aGlzfSwK
+JEM6IiQxIiwKJFI6MSwKJEQ6bnVsbH0KSC5sYy5wcm90b3R5cGU9e30KSC56eC5wcm90b3R5cGU9ewpa
+OmZ1bmN0aW9uKGEpe3ZhciB0PXRoaXMuJHN0YXRpY19uYW1lCmlmKHQ9PW51bGwpcmV0dXJuIkNsb3N1
+cmUgb2YgdW5rbm93biBzdGF0aWMgbWV0aG9kIgpyZXR1cm4iQ2xvc3VyZSAnIitILk5RKHQpKyInIn19
+CkguankucHJvdG90eXBlPXsKRE46ZnVuY3Rpb24oYSxiKXt2YXIgdD10aGlzCmlmKGI9PW51bGwpcmV0
+dXJuITEKaWYodD09PWIpcmV0dXJuITAKaWYoIShiIGluc3RhbmNlb2YgSC5qeSkpcmV0dXJuITEKcmV0
+dXJuIHQuYT09PWIuYSYmdC5iPT09Yi5iJiZ0LmM9PT1iLmN9LApnaU86ZnVuY3Rpb24oYSl7dmFyIHQs
+cz10aGlzLmMKaWYocz09bnVsbCl0PUguZVEodGhpcy5hKQplbHNlIHQ9dHlwZW9mIHMhPT0ib2JqZWN0
+Ij9KLmhmKHMpOkguZVEocykKcmV0dXJuKHReSC5lUSh0aGlzLmIpKT4+PjB9LApaOmZ1bmN0aW9uKGEp
+e3ZhciB0PXRoaXMuYwppZih0PT1udWxsKXQ9dGhpcy5hCnJldHVybiJDbG9zdXJlICciK0guZCh0aGlz
+LmQpKyInIG9mICIrKCJJbnN0YW5jZSBvZiAnIitILmQoSC5saCh0KSkrIiciKX19CkguRXEucHJvdG90
+eXBlPXsKWjpmdW5jdGlvbihhKXtyZXR1cm4iUnVudGltZUVycm9yOiAiK0guZCh0aGlzLmEpfX0KSC5r
+WS5wcm90b3R5cGU9ewpaOmZ1bmN0aW9uKGEpe3JldHVybiJBc3NlcnRpb24gZmFpbGVkOiAiK1AuaCh0
+aGlzLmEpfX0KSC5ONS5wcm90b3R5cGU9ewpnQTpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5hfSwKZ1Y6
+ZnVuY3Rpb24oKXtyZXR1cm4gbmV3IEguaTUodGhpcyxILkxoKHRoaXMpLkMoImk1PDE+IikpfSwKeDQ6
+ZnVuY3Rpb24oYSl7dmFyIHQscwppZih0eXBlb2YgYT09InN0cmluZyIpe3Q9dGhpcy5iCmlmKHQ9PW51
+bGwpcmV0dXJuITEKcmV0dXJuIHRoaXMuWHUodCxhKX1lbHNle3M9dGhpcy5DWChhKQpyZXR1cm4gc319
+LApDWDpmdW5jdGlvbihhKXt2YXIgdD10aGlzLmQKaWYodD09bnVsbClyZXR1cm4hMQpyZXR1cm4gdGhp
+cy5GaCh0aGlzLkJ0KHQsSi5oZihhKSYweDNmZmZmZmYpLGEpPj0wfSwKcTpmdW5jdGlvbihhLGIpe3Zh
+ciB0LHMscixxLHA9dGhpcyxvPW51bGwKaWYodHlwZW9mIGI9PSJzdHJpbmciKXt0PXAuYgppZih0PT1u
+dWxsKXJldHVybiBvCnM9cC5qMih0LGIpCnI9cz09bnVsbD9vOnMuYgpyZXR1cm4gcn1lbHNlIGlmKHR5
+cGVvZiBiPT0ibnVtYmVyIiYmKGImMHgzZmZmZmZmKT09PWIpe3E9cC5jCmlmKHE9PW51bGwpcmV0dXJu
+IG8Kcz1wLmoyKHEsYikKcj1zPT1udWxsP286cy5iCnJldHVybiByfWVsc2UgcmV0dXJuIHAuYWEoYil9
+LAphYTpmdW5jdGlvbihhKXt2YXIgdCxzLHI9dGhpcy5kCmlmKHI9PW51bGwpcmV0dXJuIG51bGwKdD10
+aGlzLkJ0KHIsSi5oZihhKSYweDNmZmZmZmYpCnM9dGhpcy5GaCh0LGEpCmlmKHM8MClyZXR1cm4gbnVs
+bApyZXR1cm4gdFtzXS5ifSwKWTpmdW5jdGlvbihhLGIsYyl7dmFyIHQscyxyLHEscCxvLG49dGhpcyxt
+PUguTGgobikKbS5jLmEoYikKbS5RWzFdLmEoYykKaWYodHlwZW9mIGI9PSJzdHJpbmciKXt0PW4uYgpu
+LkVIKHQ9PW51bGw/bi5iPW4ueksoKTp0LGIsYyl9ZWxzZSBpZih0eXBlb2YgYj09Im51bWJlciImJihi
+JjB4M2ZmZmZmZik9PT1iKXtzPW4uYwpuLkVIKHM9PW51bGw/bi5jPW4ueksoKTpzLGIsYyl9ZWxzZXty
+PW4uZAppZihyPT1udWxsKXI9bi5kPW4ueksoKQpxPUouaGYoYikmMHgzZmZmZmZmCnA9bi5CdChyLHEp
+CmlmKHA9PW51bGwpbi5FSShyLHEsW24uSG4oYixjKV0pCmVsc2V7bz1uLkZoKHAsYikKaWYobz49MClw
+W29dLmI9YwplbHNlIHAucHVzaChuLkhuKGIsYykpfX19LApLOmZ1bmN0aW9uKGEsYil7dmFyIHQscyxy
+PXRoaXMKSC5MaChyKS5DKCJ+KDEsMikiKS5hKGIpCnQ9ci5lCnM9ci5yCmZvcig7dCE9bnVsbDspe2Iu
+JDIodC5hLHQuYikKaWYocyE9PXIucil0aHJvdyBILmIoUC5hNChyKSkKdD10LmN9fSwKRUg6ZnVuY3Rp
+b24oYSxiLGMpe3ZhciB0LHM9dGhpcyxyPUguTGgocykKci5jLmEoYikKci5RWzFdLmEoYykKdD1zLmoy
+KGEsYikKaWYodD09bnVsbClzLkVJKGEsYixzLkhuKGIsYykpCmVsc2UgdC5iPWN9LAprczpmdW5jdGlv
+bigpe3RoaXMucj10aGlzLnIrMSY2NzEwODg2M30sCkhuOmZ1bmN0aW9uKGEsYil7dmFyIHQ9dGhpcyxz
+PUguTGgodCkscj1uZXcgSC5kYihzLmMuYShhKSxzLlFbMV0uYShiKSkKaWYodC5lPT1udWxsKXQuZT10
+LmY9cgplbHNle3M9dC5mCnMudG9TdHJpbmcKci5kPXMKdC5mPXMuYz1yfSsrdC5hCnQua3MoKQpyZXR1
+cm4gcn0sCkZoOmZ1bmN0aW9uKGEsYil7dmFyIHQscwppZihhPT1udWxsKXJldHVybi0xCnQ9YS5sZW5n
+dGgKZm9yKHM9MDtzPHQ7KytzKWlmKEouUk0oYVtzXS5hLGIpKXJldHVybiBzCnJldHVybi0xfSwKWjpm
+dW5jdGlvbihhKXtyZXR1cm4gUC5uTyh0aGlzKX0sCmoyOmZ1bmN0aW9uKGEsYil7cmV0dXJuIGFbYl19
+LApCdDpmdW5jdGlvbihhLGIpe3JldHVybiBhW2JdfSwKRUk6ZnVuY3Rpb24oYSxiLGMpe2FbYl09Y30s
+CnJuOmZ1bmN0aW9uKGEsYil7ZGVsZXRlIGFbYl19LApYdTpmdW5jdGlvbihhLGIpe3JldHVybiB0aGlz
+LmoyKGEsYikhPW51bGx9LAp6SzpmdW5jdGlvbigpe3ZhciB0PSI8bm9uLWlkZW50aWZpZXIta2V5PiIs
+cz1PYmplY3QuY3JlYXRlKG51bGwpCnRoaXMuRUkocyx0LHMpCnRoaXMucm4ocyx0KQpyZXR1cm4gc30s
+CiRpRm86MX0KSC5kYi5wcm90b3R5cGU9e30KSC5pNS5wcm90b3R5cGU9ewpnQTpmdW5jdGlvbihhKXty
+ZXR1cm4gdGhpcy5hLmF9LApna3o6ZnVuY3Rpb24oYSl7dmFyIHQ9dGhpcy5hLHM9bmV3IEguTjYodCx0
+LnIsdGhpcy4kdGkuQygiTjY8MT4iKSkKcy5jPXQuZQpyZXR1cm4gc30sCnRnOmZ1bmN0aW9uKGEsYil7
+cmV0dXJuIHRoaXMuYS54NChiKX19CkguTjYucHJvdG90eXBlPXsKZ2w6ZnVuY3Rpb24oKXtyZXR1cm4g
+dGhpcy5kfSwKRjpmdW5jdGlvbigpe3ZhciB0LHM9dGhpcyxyPXMuYQppZihzLmIhPT1yLnIpdGhyb3cg
+SC5iKFAuYTQocikpCnQ9cy5jCmlmKHQ9PW51bGwpe3Muc3FZKG51bGwpCnJldHVybiExfWVsc2V7cy5z
+cVkodC5hKQpzLmM9dC5jCnJldHVybiEwfX0sCnNxWTpmdW5jdGlvbihhKXt0aGlzLmQ9dGhpcy4kdGku
+Yy5hKGEpfSwKJGlBbjoxfQpILnIucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMu
+YShhKX0sCiRTOjZ9CkguZEMucHJvdG90eXBlPXsKJDI6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gdGhpcy5h
+KGEsYil9LAokUzoyNn0KSC53Ti5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5h
+KEguYyhhKSl9LAokUzoyMX0KSC5WUi5wcm90b3R5cGU9ewpaOmZ1bmN0aW9uKGEpe3JldHVybiJSZWdF
+eHAvIit0aGlzLmErIi8iK3RoaXMuYi5mbGFnc30sCmdIYzpmdW5jdGlvbigpe3ZhciB0PXRoaXMscz10
+LmMKaWYocyE9bnVsbClyZXR1cm4gcwpzPXQuYgpyZXR1cm4gdC5jPUgudjQodC5hLHMubXVsdGlsaW5l
+LCFzLmlnbm9yZUNhc2Uscy51bmljb2RlLHMuZG90QWxsLCEwKX0sCmRkOmZ1bmN0aW9uKGEsYil7cmV0
+dXJuIG5ldyBILktXKHRoaXMsYiwwKX0sClVaOmZ1bmN0aW9uKGEsYil7dmFyIHQscz10aGlzLmdIYygp
+CnMubGFzdEluZGV4PWIKdD1zLmV4ZWMoYSkKaWYodD09bnVsbClyZXR1cm4gbnVsbApyZXR1cm4gbmV3
+IEguRUsodCl9LAokaXZYOjEsCiRpd0w6MX0KSC5FSy5wcm90b3R5cGU9ewpxOmZ1bmN0aW9uKGEsYil7
+dmFyIHQKSC5XWShiKQp0PXRoaXMuYgppZihiPj10Lmxlbmd0aClyZXR1cm4gSC5rKHQsYikKcmV0dXJu
+IHRbYl19LAokaU9kOjEsCiRpaWI6MX0KSC5LVy5wcm90b3R5cGU9ewpna3o6ZnVuY3Rpb24oYSl7cmV0
+dXJuIG5ldyBILlBiKHRoaXMuYSx0aGlzLmIsdGhpcy5jKX19CkguUGIucHJvdG90eXBlPXsKZ2w6ZnVu
+Y3Rpb24oKXt2YXIgdD10aGlzLmQKdC50b1N0cmluZwpyZXR1cm4gdH0sCkY6ZnVuY3Rpb24oKXt2YXIg
+dCxzLHIscSxwLG8sbj10aGlzLG09bi5iCmlmKG09PW51bGwpcmV0dXJuITEKdD1uLmMKcz1tLmxlbmd0
+aAppZih0PD1zKXtyPW4uYQpxPXIuVVoobSx0KQppZihxIT1udWxsKXtuLmQ9cQp0PXEuYgpwPXQuaW5k
+ZXgKbz1wK3RbMF0ubGVuZ3RoCmlmKHA9PT1vKXtpZihyLmIudW5pY29kZSl7dD1uLmMKcj10KzEKaWYo
+cjxzKXt0PUMueEIubShtLHQpCmlmKHQ+PTU1Mjk2JiZ0PD01NjMxOSl7dD1DLnhCLm0obSxyKQp0PXQ+
+PTU2MzIwJiZ0PD01NzM0M31lbHNlIHQ9ITF9ZWxzZSB0PSExfWVsc2UgdD0hMQpvPSh0P28rMTpvKSsx
+fW4uYz1vCnJldHVybiEwfX1uLmI9bi5kPW51bGwKcmV0dXJuITF9LAokaUFuOjF9CkgudFEucHJvdG90
+eXBlPXsKcTpmdW5jdGlvbihhLGIpe0guV1koYikKaWYoYiE9PTApSC52aChQLk83KGIsbnVsbCkpCnJl
+dHVybiB0aGlzLmN9LAokaU9kOjF9CkguTkYucHJvdG90eXBlPXsKZ2t6OmZ1bmN0aW9uKGEpe3JldHVy
+biBuZXcgSC5TZCh0aGlzLmEsdGhpcy5iLHRoaXMuYyl9fQpILlNkLnByb3RvdHlwZT17CkY6ZnVuY3Rp
+b24oKXt2YXIgdCxzLHI9dGhpcyxxPXIuYyxwPXIuYixvPXAubGVuZ3RoLG49ci5hLG09bi5sZW5ndGgK
+aWYocStvPm0pe3IuZD1udWxsCnJldHVybiExfXQ9bi5pbmRleE9mKHAscSkKaWYodDwwKXtyLmM9bSsx
+CnIuZD1udWxsCnJldHVybiExfXM9dCtvCnIuZD1uZXcgSC50USh0LHApCnIuYz1zPT09ci5jP3MrMTpz
+CnJldHVybiEwfSwKZ2w6ZnVuY3Rpb24oKXt2YXIgdD10aGlzLmQKdC50b1N0cmluZwpyZXR1cm4gdH0s
+CiRpQW46MX0KSC5wRi5wcm90b3R5cGU9eyRpcEY6MSwkaUFTOjF9CkguYjAucHJvdG90eXBlPXsKZ0E6
+ZnVuY3Rpb24oYSl7cmV0dXJuIGEubGVuZ3RofSwKJGlYajoxfQpILkRnLnByb3RvdHlwZT17CnE6ZnVu
+Y3Rpb24oYSxiKXtILldZKGIpCkgub2QoYixhLGEubGVuZ3RoKQpyZXR1cm4gYVtiXX0sClk6ZnVuY3Rp
+b24oYSxiLGMpe0guZGooYykKSC5vZChiLGEsYS5sZW5ndGgpCmFbYl09Y30sCiRpYlE6MSwKJGljWDox
+LAokaXpNOjF9CkguUGcucHJvdG90eXBlPXsKWTpmdW5jdGlvbihhLGIsYyl7SC5XWShjKQpILm9kKGIs
+YSxhLmxlbmd0aCkKYVtiXT1jfSwKJGliUToxLAokaWNYOjEsCiRpek06MX0KSC54ai5wcm90b3R5cGU9
+ewpxOmZ1bmN0aW9uKGEsYil7SC5XWShiKQpILm9kKGIsYSxhLmxlbmd0aCkKcmV0dXJuIGFbYl19fQpI
+LmRFLnByb3RvdHlwZT17CnE6ZnVuY3Rpb24oYSxiKXtILldZKGIpCkgub2QoYixhLGEubGVuZ3RoKQpy
+ZXR1cm4gYVtiXX19CkguWkEucHJvdG90eXBlPXsKcTpmdW5jdGlvbihhLGIpe0guV1koYikKSC5vZChi
+LGEsYS5sZW5ndGgpCnJldHVybiBhW2JdfX0KSC53Zi5wcm90b3R5cGU9ewpxOmZ1bmN0aW9uKGEsYil7
+SC5XWShiKQpILm9kKGIsYSxhLmxlbmd0aCkKcmV0dXJuIGFbYl19fQpILlBxLnByb3RvdHlwZT17CnE6
+ZnVuY3Rpb24oYSxiKXtILldZKGIpCkgub2QoYixhLGEubGVuZ3RoKQpyZXR1cm4gYVtiXX19CkguZUUu
+cHJvdG90eXBlPXsKZ0E6ZnVuY3Rpb24oYSl7cmV0dXJuIGEubGVuZ3RofSwKcTpmdW5jdGlvbihhLGIp
+e0guV1koYikKSC5vZChiLGEsYS5sZW5ndGgpCnJldHVybiBhW2JdfX0KSC5WNi5wcm90b3R5cGU9ewpn
+QTpmdW5jdGlvbihhKXtyZXR1cm4gYS5sZW5ndGh9LApxOmZ1bmN0aW9uKGEsYil7SC5XWShiKQpILm9k
+KGIsYSxhLmxlbmd0aCkKcmV0dXJuIGFbYl19LAokaVY2OjEsCiRpbjY6MX0KSC5SRy5wcm90b3R5cGU9
+e30KSC5WUC5wcm90b3R5cGU9e30KSC5XQi5wcm90b3R5cGU9e30KSC5aRy5wcm90b3R5cGU9e30KSC5K
+Yy5wcm90b3R5cGU9ewpDOmZ1bmN0aW9uKGEpe3JldHVybiBILmNFKHYudHlwZVVuaXZlcnNlLHRoaXMs
+YSl9LApLcTpmdW5jdGlvbihhKXtyZXR1cm4gSC52NSh2LnR5cGVVbml2ZXJzZSx0aGlzLGEpfX0KSC5F
+VC5wcm90b3R5cGU9e30KSC51OS5wcm90b3R5cGU9ewpaOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLmF9
+fQpILngucHJvdG90eXBlPXt9ClAudGgucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7dmFyIHQ9dGhp
+cy5hLHM9dC5hCnQuYT1udWxsCnMuJDAoKX0sCiRTOjEyfQpQLmhhLnByb3RvdHlwZT17CiQxOmZ1bmN0
+aW9uKGEpe3ZhciB0LHMKdGhpcy5hLmE9dS5NLmEoYSkKdD10aGlzLmIKcz10aGlzLmMKdC5maXJzdENo
+aWxkP3QucmVtb3ZlQ2hpbGQocyk6dC5hcHBlbmRDaGlsZChzKX0sCiRTOjQ1fQpQLlZzLnByb3RvdHlw
+ZT17CiQwOmZ1bmN0aW9uKCl7dGhpcy5hLiQwKCl9LAokQzoiJDAiLAokUjowLAokUzowfQpQLkZ0LnBy
+b3RvdHlwZT17CiQwOmZ1bmN0aW9uKCl7dGhpcy5hLiQwKCl9LAokQzoiJDAiLAokUjowLAokUzowfQpQ
+LlczLnByb3RvdHlwZT17CkNZOmZ1bmN0aW9uKGEsYil7aWYoc2VsZi5zZXRUaW1lb3V0IT1udWxsKXNl
+bGYuc2V0VGltZW91dChILnRSKG5ldyBQLnlIKHRoaXMsYiksMCksYSkKZWxzZSB0aHJvdyBILmIoUC5M
+NCgiYHNldFRpbWVvdXQoKWAgbm90IGZvdW5kLiIpKX19ClAueUgucHJvdG90eXBlPXsKJDA6ZnVuY3Rp
+b24oKXt0aGlzLmIuJDAoKX0sCiRDOiIkMCIsCiRSOjAsCiRTOjF9ClAuaWgucHJvdG90eXBlPXsKYU06
+ZnVuY3Rpb24oYSxiKXt2YXIgdCxzLHI9dGhpcy4kdGkKci5DKCIxLyIpLmEoYikKdD0hdGhpcy5ifHxy
+LkMoImI4PDE+IikuYihiKQpzPXRoaXMuYQppZih0KXMuWGYoYikKZWxzZSBzLlgyKHIuYy5hKGIpKX0s
+CncwOmZ1bmN0aW9uKGEsYil7dmFyIHQKaWYoYj09bnVsbCliPVAudjAoYSkKdD10aGlzLmEKaWYodGhp
+cy5iKXQuWkwoYSxiKQplbHNlIHQuTmsoYSxiKX19ClAuV00ucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24o
+YSl7cmV0dXJuIHRoaXMuYS4kMigwLGEpfSwKJFM6Mjd9ClAuU1gucHJvdG90eXBlPXsKJDI6ZnVuY3Rp
+b24oYSxiKXt0aGlzLmEuJDIoMSxuZXcgSC5icShhLHUubC5hKGIpKSl9LAokQzoiJDIiLAokUjoyLAok
+UzoyOX0KUC5Hcy5wcm90b3R5cGU9ewokMjpmdW5jdGlvbihhLGIpe3RoaXMuYShILldZKGEpLGIpfSwK
+JFM6MzB9ClAuRnkucHJvdG90eXBlPXsKWjpmdW5jdGlvbihhKXtyZXR1cm4iSXRlcmF0aW9uTWFya2Vy
+KCIrdGhpcy5iKyIsICIrSC5kKHRoaXMuYSkrIikifX0KUC5HVi5wcm90b3R5cGU9ewpnbDpmdW5jdGlv
+bigpe3ZhciB0PXRoaXMuYyxzPXQhPW51bGw/dC5nbCgpOnRoaXMuYgpyZXR1cm4gdGhpcy4kdGkuYy5h
+KHMpfSwKRjpmdW5jdGlvbigpe3ZhciB0LHMscixxLHAsbz10aGlzCmZvcig7ITA7KXt0PW8uYwppZih0
+IT1udWxsKWlmKHQuRigpKXJldHVybiEwCmVsc2Ugby5jPW51bGwKcz1mdW5jdGlvbihhLGIsYyl7dmFy
+IG4sbT1iCndoaWxlKHRydWUpdHJ5e3JldHVybiBhKG0sbil9Y2F0Y2gobCl7bj1sCm09Y319KG8uYSww
+LDEpCmlmKHMgaW5zdGFuY2VvZiBQLkZ5KXtyPXMuYgppZihyPT09Mil7cT1vLmQKaWYocT09bnVsbHx8
+cS5sZW5ndGg9PT0wKXtvLnNFQyhudWxsKQpyZXR1cm4hMX1pZigwPj1xLmxlbmd0aClyZXR1cm4gSC5r
+KHEsLTEpCm8uYT1xLnBvcCgpCmNvbnRpbnVlfWVsc2V7dD1zLmEKaWYocj09PTMpdGhyb3cgdAplbHNl
+e3A9Si5JVCh0KQppZihwIGluc3RhbmNlb2YgUC5HVil7dD1vLmQKaWYodD09bnVsbCl0PW8uZD1bXQpD
+Lk5tLmkodCxvLmEpCm8uYT1wLmEKY29udGludWV9ZWxzZXtvLmM9cApjb250aW51ZX19fX1lbHNle28u
+c0VDKHMpCnJldHVybiEwfX1yZXR1cm4hMX0sCnNFQzpmdW5jdGlvbihhKXt0aGlzLmI9dGhpcy4kdGku
+Yy5hKGEpfSwKJGlBbjoxfQpQLnE0LnByb3RvdHlwZT17CmdrejpmdW5jdGlvbihhKXtyZXR1cm4gbmV3
+IFAuR1YodGhpcy5hKCksdGhpcy4kdGkuQygiR1Y8MT4iKSl9fQpQLmI4LnByb3RvdHlwZT17fQpQLlBm
+LnByb3RvdHlwZT17CncwOmZ1bmN0aW9uKGEsYil7dmFyIHQKUC5VSShhLCJlcnJvciIsdS5LKQp0PXRo
+aXMuYQppZih0LmEhPT0wKXRocm93IEguYihQLlBWKCJGdXR1cmUgYWxyZWFkeSBjb21wbGV0ZWQiKSkK
+aWYoYj09bnVsbCliPVAudjAoYSkKdC5OayhhLGIpfSwKcG06ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMu
+dzAoYSxudWxsKX19ClAuWmYucHJvdG90eXBlPXsKYU06ZnVuY3Rpb24oYSxiKXt2YXIgdAp0aGlzLiR0
+aS5DKCIxLyIpLmEoYikKdD10aGlzLmEKaWYodC5hIT09MCl0aHJvdyBILmIoUC5QVigiRnV0dXJlIGFs
+cmVhZHkgY29tcGxldGVkIikpCnQuWGYoYil9fQpQLkZlLnByb3RvdHlwZT17CkhSOmZ1bmN0aW9uKGEp
+e2lmKCh0aGlzLmMmMTUpIT09NilyZXR1cm4hMApyZXR1cm4gdGhpcy5iLmIuYnYodS5tLmEodGhpcy5k
+KSxhLmEsdS55LHUuSyl9LApLdzpmdW5jdGlvbihhKXt2YXIgdD10aGlzLmUscz11Lnoscj11LksscT10
+aGlzLiR0aS5DKCIyLyIpLHA9dGhpcy5iLmIKaWYodS5hZy5iKHQpKXJldHVybiBxLmEocC5ycCh0LGEu
+YSxhLmIscyxyLHUubCkpCmVsc2UgcmV0dXJuIHEuYShwLmJ2KHUuYkkuYSh0KSxhLmEscyxyKSl9fQpQ
+LnZzLnByb3RvdHlwZT17ClNxOmZ1bmN0aW9uKGEsYixjKXt2YXIgdCxzLHIscT10aGlzLiR0aQpxLktx
+KGMpLkMoIjEvKDIpIikuYShhKQp0PSQuWDMKaWYodCE9PUMuTlUpe2MuQygiQDwwLz4iKS5LcShxLmMp
+LkMoIjEoMikiKS5hKGEpCmlmKGIhPW51bGwpYj1QLlZIKGIsdCl9cz1uZXcgUC52cygkLlgzLGMuQygi
+dnM8MD4iKSkKcj1iPT1udWxsPzE6Mwp0aGlzLnhmKG5ldyBQLkZlKHMscixhLGIscS5DKCJAPDE+Iiku
+S3EoYykuQygiRmU8MSwyPiIpKSkKcmV0dXJuIHN9LApXNzpmdW5jdGlvbihhLGIpe3JldHVybiB0aGlz
+LlNxKGEsbnVsbCxiKX0sClFkOmZ1bmN0aW9uKGEsYixjKXt2YXIgdCxzPXRoaXMuJHRpCnMuS3EoYyku
+QygiMS8oMikiKS5hKGEpCnQ9bmV3IFAudnMoJC5YMyxjLkMoInZzPDA+IikpCnRoaXMueGYobmV3IFAu
+RmUodCwxOSxhLGIscy5DKCJAPDE+IikuS3EoYykuQygiRmU8MSwyPiIpKSkKcmV0dXJuIHR9LApPQTpm
+dW5jdGlvbihhKXt2YXIgdCxzLHIKdS5tLmEobnVsbCkKdD10aGlzLiR0aQpzPSQuWDMKcj1uZXcgUC52
+cyhzLHQpCmlmKHMhPT1DLk5VKWE9UC5WSChhLHMpCnRoaXMueGYobmV3IFAuRmUociwyLG51bGwsYSx0
+LkMoIkA8MT4iKS5LcSh0LmMpLkMoIkZlPDEsMj4iKSkpCnJldHVybiByfSwKeGY6ZnVuY3Rpb24oYSl7
+dmFyIHQscz10aGlzLHI9cy5hCmlmKHI8PTEpe2EuYT11LnguYShzLmMpCnMuYz1hfWVsc2V7aWYocj09
+PTIpe3Q9dS5fLmEocy5jKQpyPXQuYQppZihyPDQpe3QueGYoYSkKcmV0dXJufXMuYT1yCnMuYz10LmN9
+UC5UayhudWxsLG51bGwscy5iLHUuTS5hKG5ldyBQLmRhKHMsYSkpKX19LApqUTpmdW5jdGlvbihhKXt2
+YXIgdCxzLHIscSxwLG8sbj10aGlzLG09e30KbS5hPWEKaWYoYT09bnVsbClyZXR1cm4KdD1uLmEKaWYo
+dDw9MSl7cz11LnguYShuLmMpCm4uYz1hCmlmKHMhPW51bGwpe3I9YS5hCmZvcihxPWE7ciE9bnVsbDtx
+PXIscj1wKXA9ci5hCnEuYT1zfX1lbHNle2lmKHQ9PT0yKXtvPXUuXy5hKG4uYykKdD1vLmEKaWYodDw0
+KXtvLmpRKGEpCnJldHVybn1uLmE9dApuLmM9by5jfW0uYT1uLk44KGEpClAuVGsobnVsbCxudWxsLG4u
+Yix1Lk0uYShuZXcgUC5vUShtLG4pKSl9fSwKYWg6ZnVuY3Rpb24oKXt2YXIgdD11LnguYSh0aGlzLmMp
+CnRoaXMuYz1udWxsCnJldHVybiB0aGlzLk44KHQpfSwKTjg6ZnVuY3Rpb24oYSl7dmFyIHQscyxyCmZv
+cih0PWEscz1udWxsO3QhPW51bGw7cz10LHQ9cil7cj10LmEKdC5hPXN9cmV0dXJuIHN9LApISDpmdW5j
+dGlvbihhKXt2YXIgdCxzPXRoaXMscj1zLiR0aQpyLkMoIjEvIikuYShhKQppZihyLkMoImI4PDE+Iiku
+YihhKSlpZihyLmIoYSkpUC5BOShhLHMpCmVsc2UgUC5rMyhhLHMpCmVsc2V7dD1zLmFoKCkKcj1yLmMK
+YT1yLmEoci5hKGEpKQpzLmE9NApzLmM9YQpQLkhaKHMsdCl9fSwKWDI6ZnVuY3Rpb24oYSl7dmFyIHQs
+cz10aGlzCnMuJHRpLmMuYShhKQp0PXMuYWgoKQpzLmE9NApzLmM9YQpQLkhaKHMsdCl9LApaTDpmdW5j
+dGlvbihhLGIpe3ZhciB0LHMscj10aGlzCnUubC5hKGIpCnQ9ci5haCgpCnM9UC5UbChhLGIpCnIuYT04
+CnIuYz1zClAuSFoocix0KX0sClhmOmZ1bmN0aW9uKGEpe3ZhciB0PXRoaXMscz10LiR0aQpzLkMoIjEv
+IikuYShhKQppZihzLkMoImI4PDE+IikuYihhKSl7dC5jVShhKQpyZXR1cm59dC5hPTEKUC5UayhudWxs
+LG51bGwsdC5iLHUuTS5hKG5ldyBQLnJIKHQsYSkpKX0sCmNVOmZ1bmN0aW9uKGEpe3ZhciB0PXRoaXMs
+cz10LiR0aQpzLkMoImI4PDE+IikuYShhKQppZihzLmIoYSkpe2lmKGEuYT09PTgpe3QuYT0xClAuVGso
+bnVsbCxudWxsLHQuYix1Lk0uYShuZXcgUC5LRih0LGEpKSl9ZWxzZSBQLkE5KGEsdCkKcmV0dXJufVAu
+azMoYSx0KX0sCk5rOmZ1bmN0aW9uKGEsYil7dGhpcy5hPTEKUC5UayhudWxsLG51bGwsdGhpcy5iLHUu
+TS5hKG5ldyBQLlpMKHRoaXMsYSxiKSkpfSwKJGliODoxfQpQLmRhLnByb3RvdHlwZT17CiQwOmZ1bmN0
+aW9uKCl7UC5IWih0aGlzLmEsdGhpcy5iKX0sCiRTOjB9ClAub1EucHJvdG90eXBlPXsKJDA6ZnVuY3Rp
+b24oKXtQLkhaKHRoaXMuYix0aGlzLmEuYSl9LAokUzowfQpQLnBWLnByb3RvdHlwZT17CiQxOmZ1bmN0
+aW9uKGEpe3ZhciB0PXRoaXMuYQp0LmE9MAp0LkhIKGEpfSwKJFM6MTJ9ClAuVTcucHJvdG90eXBlPXsK
+JDI6ZnVuY3Rpb24oYSxiKXt1LmwuYShiKQp0aGlzLmEuWkwoYSxiKX0sCiRDOiIkMiIsCiRSOjIsCiRT
+OjM0fQpQLnZyLnByb3RvdHlwZT17CiQwOmZ1bmN0aW9uKCl7dGhpcy5hLlpMKHRoaXMuYix0aGlzLmMp
+fSwKJFM6MH0KUC5ySC5wcm90b3R5cGU9ewokMDpmdW5jdGlvbigpe3ZhciB0PXRoaXMuYQp0LlgyKHQu
+JHRpLmMuYSh0aGlzLmIpKX0sCiRTOjB9ClAuS0YucHJvdG90eXBlPXsKJDA6ZnVuY3Rpb24oKXtQLkE5
+KHRoaXMuYix0aGlzLmEpfSwKJFM6MH0KUC5aTC5wcm90b3R5cGU9ewokMDpmdW5jdGlvbigpe3RoaXMu
+YS5aTCh0aGlzLmIsdGhpcy5jKX0sCiRTOjB9ClAuUlQucHJvdG90eXBlPXsKJDA6ZnVuY3Rpb24oKXt2
+YXIgdCxzLHIscSxwLG8sbj10aGlzLG09bnVsbAp0cnl7cj1uLmEuYQptPXIuYi5iLnp6KHUuZk8uYShy
+LmQpLHUueil9Y2F0Y2gocSl7dD1ILlJ1KHEpCnM9SC50cyhxKQppZihuLmMpe3I9dS5uLmEobi5iLmEu
+YykuYQpwPXQKcD1yPT1udWxsP3A9PW51bGw6cj09PXAKcj1wfWVsc2Ugcj0hMQpwPW4uYQppZihyKXAu
+Yz11Lm4uYShuLmIuYS5jKQplbHNlIHAuYz1QLlRsKHQscykKcC5iPSEwCnJldHVybn1pZih1LmMuYiht
+KSl7aWYobSBpbnN0YW5jZW9mIFAudnMmJm0uYT49NCl7aWYobS5hPT09OCl7cj1uLmEKci5jPXUubi5h
+KG0uYykKci5iPSEwfXJldHVybn1vPW4uYi5hCnI9bi5hCnIuYz1tLlc3KG5ldyBQLmpaKG8pLHUueikK
+ci5iPSExfX0sCiRTOjF9ClAualoucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMu
+YX0sCiRTOjM4fQpQLnJxLnByb3RvdHlwZT17CiQwOmZ1bmN0aW9uKCl7dmFyIHQscyxyLHEscCxvLG4s
+bQp0cnl7cj10aGlzLmEKcT1yLmEKcD1xLiR0aQpvPXAuYwpuPW8uYSh0aGlzLmIpCnIuYz1xLmIuYi5i
+dihwLkMoIjIvKDEpIikuYShxLmQpLG4scC5DKCIyLyIpLG8pfWNhdGNoKG0pe3Q9SC5SdShtKQpzPUgu
+dHMobSkKcj10aGlzLmEKci5jPVAuVGwodCxzKQpyLmI9ITB9fSwKJFM6MX0KUC5SVy5wcm90b3R5cGU9
+ewokMDpmdW5jdGlvbigpe3ZhciB0LHMscixxLHAsbyxuLG0sbD10aGlzCnRyeXt0PXUubi5hKGwuYS5h
+LmMpCnE9bC5iCmlmKEgub1QocS5hLkhSKHQpKSYmcS5hLmUhPW51bGwpe3EuYz1xLmEuS3codCkKcS5i
+PSExfX1jYXRjaChwKXtzPUguUnUocCkKcj1ILnRzKHApCnE9dS5uLmEobC5hLmEuYykKbz1xLmEKbj1z
+Cm09bC5iCmlmKG89PW51bGw/bj09bnVsbDpvPT09biltLmM9cQplbHNlIG0uYz1QLlRsKHMscikKbS5i
+PSEwfX0sCiRTOjF9ClAuT00ucHJvdG90eXBlPXt9ClAucWgucHJvdG90eXBlPXsKZ0E6ZnVuY3Rpb24o
+YSl7dmFyIHQscyxyPXRoaXMscT17fSxwPW5ldyBQLnZzKCQuWDMsdS5mSikKcS5hPTAKdD1ILkxoKHIp
+CnM9dC5DKCJ+KDEpIikuYShuZXcgUC5CNShxLHIpKQp1Lk0uYShuZXcgUC51TyhxLHApKQpXLkpFKHIu
+YSxyLmIscywhMSx0LmMpCnJldHVybiBwfX0KUC5CNS5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXtI
+LkxoKHRoaXMuYikuYy5hKGEpOysrdGhpcy5hLmF9LAokUzpmdW5jdGlvbigpe3JldHVybiBILkxoKHRo
+aXMuYikuQygiYzgoMSkiKX19ClAudU8ucHJvdG90eXBlPXsKJDA6ZnVuY3Rpb24oKXt0aGlzLmIuSEgo
+dGhpcy5hLmEpfSwKJFM6MH0KUC5NTy5wcm90b3R5cGU9e30KUC5rVC5wcm90b3R5cGU9e30KUC54SS5w
+cm90b3R5cGU9e30KUC5PSC5wcm90b3R5cGU9ewpaOmZ1bmN0aW9uKGEpe3JldHVybiBILmQodGhpcy5h
+KX0sCiRpWFM6MSwKZ0lJOmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuYn19ClAubTAucHJvdG90eXBlPXsk
+aUpCOjF9ClAucEsucHJvdG90eXBlPXsKJDA6ZnVuY3Rpb24oKXt2YXIgdD1ILmIodGhpcy5hKQp0LnN0
+YWNrPUouQWModGhpcy5iKQp0aHJvdyB0fSwKJFM6MH0KUC5KaS5wcm90b3R5cGU9ewpiSDpmdW5jdGlv
+bihhKXt2YXIgdCxzLHIscT1udWxsCnUuTS5hKGEpCnRyeXtpZihDLk5VPT09JC5YMyl7YS4kMCgpCnJl
+dHVybn1QLlQ4KHEscSx0aGlzLGEsdS5IKX1jYXRjaChyKXt0PUguUnUocikKcz1ILnRzKHIpClAuTDIo
+cSxxLHRoaXMsdCx1LmwuYShzKSl9fSwKRGw6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0LHMscixxPW51bGwK
+Yy5DKCJ+KDApIikuYShhKQpjLmEoYikKdHJ5e2lmKEMuTlU9PT0kLlgzKXthLiQxKGIpCnJldHVybn1Q
+Lnl2KHEscSx0aGlzLGEsYix1LkgsYyl9Y2F0Y2gocil7dD1ILlJ1KHIpCnM9SC50cyhyKQpQLkwyKHEs
+cSx0aGlzLHQsdS5sLmEocykpfX0sClJUOmZ1bmN0aW9uKGEsYil7cmV0dXJuIG5ldyBQLmhqKHRoaXMs
+Yi5DKCIwKCkiKS5hKGEpLGIpfSwKR1k6ZnVuY3Rpb24oYSl7cmV0dXJuIG5ldyBQLlZwKHRoaXMsdS5N
+LmEoYSkpfSwKUHk6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gbmV3IFAuT1IodGhpcyxiLkMoIn4oMCkiKS5h
+KGEpLGIpfSwKcTpmdW5jdGlvbihhLGIpe3JldHVybiBudWxsfSwKeno6ZnVuY3Rpb24oYSxiKXtiLkMo
+IjAoKSIpLmEoYSkKaWYoJC5YMz09PUMuTlUpcmV0dXJuIGEuJDAoKQpyZXR1cm4gUC5UOChudWxsLG51
+bGwsdGhpcyxhLGIpfSwKYnY6ZnVuY3Rpb24oYSxiLGMsZCl7Yy5DKCJAPDA+IikuS3EoZCkuQygiMSgy
+KSIpLmEoYSkKZC5hKGIpCmlmKCQuWDM9PT1DLk5VKXJldHVybiBhLiQxKGIpCnJldHVybiBQLnl2KG51
+bGwsbnVsbCx0aGlzLGEsYixjLGQpfSwKcnA6ZnVuY3Rpb24oYSxiLGMsZCxlLGYpe2QuQygiQDwwPiIp
+LktxKGUpLktxKGYpLkMoIjEoMiwzKSIpLmEoYSkKZS5hKGIpCmYuYShjKQppZigkLlgzPT09Qy5OVSly
+ZXR1cm4gYS4kMihiLGMpCnJldHVybiBQLlF4KG51bGwsbnVsbCx0aGlzLGEsYixjLGQsZSxmKX0sCkxq
+OmZ1bmN0aW9uKGEsYixjLGQpe3JldHVybiBiLkMoIkA8MD4iKS5LcShjKS5LcShkKS5DKCIxKDIsMyki
+KS5hKGEpfX0KUC5oai5wcm90b3R5cGU9ewokMDpmdW5jdGlvbigpe3JldHVybiB0aGlzLmEuenoodGhp
+cy5iLHRoaXMuYyl9LAokUzpmdW5jdGlvbigpe3JldHVybiB0aGlzLmMuQygiMCgpIil9fQpQLlZwLnBy
+b3RvdHlwZT17CiQwOmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuYS5iSCh0aGlzLmIpfSwKJFM6MX0KUC5P
+Ui5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXt2YXIgdD10aGlzLmMKcmV0dXJuIHRoaXMuYS5EbCh0
+aGlzLmIsdC5hKGEpLHQpfSwKJFM6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5jLkMoIn4oMCkiKX19ClAu
+YjYucHJvdG90eXBlPXsKZ2t6OmZ1bmN0aW9uKGEpe3ZhciB0PXRoaXMscz1uZXcgUC5sbSh0LHQucixI
+LkxoKHQpLkMoImxtPDE+IikpCnMuYz10LmUKcmV0dXJuIHN9LApnQTpmdW5jdGlvbihhKXtyZXR1cm4g
+dGhpcy5hfSwKdGc6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzCmlmKHR5cGVvZiBiPT0ic3RyaW5nIiYmYiE9
+PSJfX3Byb3RvX18iKXt0PXRoaXMuYgppZih0PT1udWxsKXJldHVybiExCnJldHVybiB1LkouYSh0W2Jd
+KSE9bnVsbH1lbHNle3M9dGhpcy5QUihiKQpyZXR1cm4gc319LApQUjpmdW5jdGlvbihhKXt2YXIgdD10
+aGlzLmQKaWYodD09bnVsbClyZXR1cm4hMQpyZXR1cm4gdGhpcy5ERih0W3RoaXMuTihhKV0sYSk+PTB9
+LAppOmZ1bmN0aW9uKGEsYil7dmFyIHQscyxyPXRoaXMKSC5MaChyKS5jLmEoYikKaWYodHlwZW9mIGI9
+PSJzdHJpbmciJiZiIT09Il9fcHJvdG9fXyIpe3Q9ci5iCnJldHVybiByLlModD09bnVsbD9yLmI9UC5U
+MigpOnQsYil9ZWxzZSBpZih0eXBlb2YgYj09Im51bWJlciImJihiJjEwNzM3NDE4MjMpPT09Yil7cz1y
+LmMKcmV0dXJuIHIuUyhzPT1udWxsP3IuYz1QLlQyKCk6cyxiKX1lbHNlIHJldHVybiByLkI3KGIpfSwK
+Qjc6ZnVuY3Rpb24oYSl7dmFyIHQscyxyLHE9dGhpcwpILkxoKHEpLmMuYShhKQp0PXEuZAppZih0PT1u
+dWxsKXQ9cS5kPVAuVDIoKQpzPXEuTihhKQpyPXRbc10KaWYocj09bnVsbCl0W3NdPVtxLnlvKGEpXQpl
+bHNle2lmKHEuREYocixhKT49MClyZXR1cm4hMQpyLnB1c2gocS55byhhKSl9cmV0dXJuITB9LApSOmZ1
+bmN0aW9uKGEsYil7dmFyIHQ9dGhpcwppZih0eXBlb2YgYj09InN0cmluZyImJmIhPT0iX19wcm90b19f
+IilyZXR1cm4gdC5INCh0LmIsYikKZWxzZSBpZih0eXBlb2YgYj09Im51bWJlciImJihiJjEwNzM3NDE4
+MjMpPT09YilyZXR1cm4gdC5INCh0LmMsYikKZWxzZSByZXR1cm4gdC5xZyhiKX0sCnFnOmZ1bmN0aW9u
+KGEpe3ZhciB0LHMscixxLHA9dGhpcyxvPXAuZAppZihvPT1udWxsKXJldHVybiExCnQ9cC5OKGEpCnM9
+b1t0XQpyPXAuREYocyxhKQppZihyPDApcmV0dXJuITEKcT1zLnNwbGljZShyLDEpWzBdCmlmKDA9PT1z
+Lmxlbmd0aClkZWxldGUgb1t0XQpwLkdTKHEpCnJldHVybiEwfSwKUzpmdW5jdGlvbihhLGIpe0guTGgo
+dGhpcykuYy5hKGIpCmlmKHUuSi5hKGFbYl0pIT1udWxsKXJldHVybiExCmFbYl09dGhpcy55byhiKQpy
+ZXR1cm4hMH0sCkg0OmZ1bmN0aW9uKGEsYil7dmFyIHQKaWYoYT09bnVsbClyZXR1cm4hMQp0PXUuSi5h
+KGFbYl0pCmlmKHQ9PW51bGwpcmV0dXJuITEKdGhpcy5HUyh0KQpkZWxldGUgYVtiXQpyZXR1cm4hMH0s
+Clg6ZnVuY3Rpb24oKXt0aGlzLnI9MTA3Mzc0MTgyMyZ0aGlzLnIrMX0sCnlvOmZ1bmN0aW9uKGEpe3Zh
+ciB0LHM9dGhpcyxyPW5ldyBQLmJuKEguTGgocykuYy5hKGEpKQppZihzLmU9PW51bGwpcy5lPXMuZj1y
+CmVsc2V7dD1zLmYKdC50b1N0cmluZwpyLmM9dApzLmY9dC5iPXJ9KytzLmEKcy5YKCkKcmV0dXJuIHJ9
+LApHUzpmdW5jdGlvbihhKXt2YXIgdD10aGlzLHM9YS5jLHI9YS5iCmlmKHM9PW51bGwpdC5lPXIKZWxz
+ZSBzLmI9cgppZihyPT1udWxsKXQuZj1zCmVsc2Ugci5jPXM7LS10LmEKdC5YKCl9LApOOmZ1bmN0aW9u
+KGEpe3JldHVybiBKLmhmKGEpJjEwNzM3NDE4MjN9LApERjpmdW5jdGlvbihhLGIpe3ZhciB0LHMKaWYo
+YT09bnVsbClyZXR1cm4tMQp0PWEubGVuZ3RoCmZvcihzPTA7czx0OysrcylpZihKLlJNKGFbc10uYSxi
+KSlyZXR1cm4gcwpyZXR1cm4tMX19ClAuYm4ucHJvdG90eXBlPXt9ClAubG0ucHJvdG90eXBlPXsKZ2w6
+ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5kfSwKRjpmdW5jdGlvbigpe3ZhciB0PXRoaXMscz10LmMscj10
+LmEKaWYodC5iIT09ci5yKXRocm93IEguYihQLmE0KHIpKQplbHNlIGlmKHM9PW51bGwpe3Quc2oobnVs
+bCkKcmV0dXJuITF9ZWxzZXt0LnNqKHQuJHRpLmMuYShzLmEpKQp0LmM9cy5iCnJldHVybiEwfX0sCnNq
+OmZ1bmN0aW9uKGEpe3RoaXMuZD10aGlzLiR0aS5jLmEoYSl9LAokaUFuOjF9ClAubVcucHJvdG90eXBl
+PXt9ClAuTFUucHJvdG90eXBlPXskaWJROjEsJGljWDoxLCRpek06MX0KUC5sRC5wcm90b3R5cGU9ewpn
+a3o6ZnVuY3Rpb24oYSl7cmV0dXJuIG5ldyBILmE3KGEsdGhpcy5nQShhKSxILnEoYSkuQygiYTc8bEQu
+RT4iKSl9LApFOmZ1bmN0aW9uKGEsYil7cmV0dXJuIHRoaXMucShhLGIpfSwKSzpmdW5jdGlvbihhLGIp
+e3ZhciB0LHMKSC5xKGEpLkMoIn4obEQuRSkiKS5hKGIpCnQ9dGhpcy5nQShhKQpmb3Iocz0wO3M8dDsr
+K3Mpe2IuJDEodGhpcy5xKGEscykpCmlmKHQhPT10aGlzLmdBKGEpKXRocm93IEguYihQLmE0KGEpKX19
+LApFMjpmdW5jdGlvbihhLGIsYyl7dmFyIHQ9SC5xKGEpCnJldHVybiBuZXcgSC5sSihhLHQuS3EoYyku
+QygiMShsRC5FKSIpLmEoYiksdC5DKCJAPGxELkU+IikuS3EoYykuQygibEo8MSwyPiIpKX0sCmR1OmZ1
+bmN0aW9uKGEsYixjLGQpe3ZhciB0CkgucShhKS5DKCJsRC5FIikuYShkKQpQLmpCKGIsYyx0aGlzLmdB
+KGEpKQpmb3IodD1iO3Q8YzsrK3QpdGhpcy5ZKGEsdCxkKX0sClo6ZnVuY3Rpb24oYSl7cmV0dXJuIFAu
+V0UoYSwiWyIsIl0iKX19ClAuaWwucHJvdG90eXBlPXt9ClAucmEucHJvdG90eXBlPXsKJDI6ZnVuY3Rp
+b24oYSxiKXt2YXIgdCxzPXRoaXMuYQppZighcy5hKXRoaXMuYi5hKz0iLCAiCnMuYT0hMQpzPXRoaXMu
+Ygp0PXMuYSs9SC5kKGEpCnMuYT10KyI6ICIKcy5hKz1ILmQoYil9LAokUzozOX0KUC5Zay5wcm90b3R5
+cGU9ewpLOmZ1bmN0aW9uKGEsYil7dmFyIHQscwpILkxoKHRoaXMpLkMoIn4oWWsuSyxZay5WKSIpLmEo
+YikKZm9yKHQ9Si5JVCh0aGlzLmdWKCkpO3QuRigpOyl7cz10LmdsKCkKYi4kMihzLHRoaXMucSgwLHMp
+KX19LApnUHU6ZnVuY3Rpb24oYSl7cmV0dXJuIEouTTEodGhpcy5nVigpLG5ldyBQLnlRKHRoaXMpLEgu
+TGgodGhpcykuQygiTjM8WWsuSyxZay5WPiIpKX0sCng0OmZ1bmN0aW9uKGEpe3JldHVybiBKLnpsKHRo
+aXMuZ1YoKSxhKX0sCmdBOmZ1bmN0aW9uKGEpe3JldHVybiBKLkgodGhpcy5nVigpKX0sClo6ZnVuY3Rp
+b24oYSl7cmV0dXJuIFAubk8odGhpcyl9LAokaVowOjF9ClAueVEucHJvdG90eXBlPXsKJDE6ZnVuY3Rp
+b24oYSl7dmFyIHQ9dGhpcy5hLHM9SC5MaCh0KQpzLkMoIllrLksiKS5hKGEpCnJldHVybiBuZXcgUC5O
+MyhhLHQucSgwLGEpLHMuQygiQDxZay5LPiIpLktxKHMuQygiWWsuViIpKS5DKCJOMzwxLDI+IikpfSwK
+JFM6ZnVuY3Rpb24oKXtyZXR1cm4gSC5MaCh0aGlzLmEpLkMoIk4zPFlrLkssWWsuVj4oWWsuSykiKX19
+ClAuS1AucHJvdG90eXBlPXsKWTpmdW5jdGlvbihhLGIsYyl7dmFyIHQ9SC5MaCh0aGlzKQp0LmMuYShi
+KQp0LlFbMV0uYShjKQp0aHJvdyBILmIoUC5MNCgiQ2Fubm90IG1vZGlmeSB1bm1vZGlmaWFibGUgbWFw
+IikpfX0KUC5Qbi5wcm90b3R5cGU9ewpxOmZ1bmN0aW9uKGEsYil7cmV0dXJuIHRoaXMuYS5xKDAsYil9
+LApZOmZ1bmN0aW9uKGEsYixjKXt2YXIgdD1ILkxoKHRoaXMpCnRoaXMuYS5ZKDAsdC5jLmEoYiksdC5R
+WzFdLmEoYykpfSwKeDQ6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuYS54NChhKX0sCks6ZnVuY3Rpb24o
+YSxiKXt0aGlzLmEuSygwLEguTGgodGhpcykuQygifigxLDIpIikuYShiKSl9LApnQTpmdW5jdGlvbihh
+KXt2YXIgdD10aGlzLmEKcmV0dXJuIHQuZ0EodCl9LApaOmZ1bmN0aW9uKGEpe3JldHVybiBKLkFjKHRo
+aXMuYSl9LApnUHU6ZnVuY3Rpb24oYSl7dmFyIHQ9dGhpcy5hCnJldHVybiB0LmdQdSh0KX0sCiRpWjA6
+MX0KUC5Hai5wcm90b3R5cGU9e30KUC5NYS5wcm90b3R5cGU9ewpaOmZ1bmN0aW9uKGEpe3JldHVybiBQ
+LldFKHRoaXMsInsiLCJ9Iil9fQpQLlZqLnByb3RvdHlwZT17JGliUToxLCRpY1g6MSwkaXh1OjF9ClAu
+WHYucHJvdG90eXBlPXsKRlY6ZnVuY3Rpb24oYSxiKXt2YXIgdApmb3IodD1KLklUKEguTGgodGhpcyku
+QygiY1g8MT4iKS5hKGIpKTt0LkYoKTspdGhpcy5pKDAsdC5nbCgpKX0sClo6ZnVuY3Rpb24oYSl7cmV0
+dXJuIFAuV0UodGhpcywieyIsIn0iKX0sCnpWOmZ1bmN0aW9uKGEsYil7dmFyIHQscz1QLnJqKHRoaXMs
+dGhpcy5yLEguTGgodGhpcykuYykKaWYoIXMuRigpKXJldHVybiIiCmlmKGI9PT0iIil7dD0iIgpkbyB0
+Kz1ILmQocy5kKQp3aGlsZShzLkYoKSl9ZWxzZXt0PUguZChzLmQpCmZvcig7cy5GKCk7KXQ9dCtiK0gu
+ZChzLmQpfXJldHVybiB0LmNoYXJDb2RlQXQoMCk9PTA/dDp0fSwKJGliUToxLAokaWNYOjEsCiRpeHU6
+MX0KUC5uWS5wcm90b3R5cGU9e30KUC5UQy5wcm90b3R5cGU9e30KUC5SVS5wcm90b3R5cGU9e30KUC51
+dy5wcm90b3R5cGU9ewpxOmZ1bmN0aW9uKGEsYil7dmFyIHQscz10aGlzLmIKaWYocz09bnVsbClyZXR1
+cm4gdGhpcy5jLnEoMCxiKQplbHNlIGlmKHR5cGVvZiBiIT0ic3RyaW5nIilyZXR1cm4gbnVsbAplbHNl
+e3Q9c1tiXQpyZXR1cm4gdHlwZW9mIHQ9PSJ1bmRlZmluZWQiP3RoaXMuZmIoYik6dH19LApnQTpmdW5j
+dGlvbihhKXtyZXR1cm4gdGhpcy5iPT1udWxsP3RoaXMuYy5hOnRoaXMuQ2YoKS5sZW5ndGh9LApnVjpm
+dW5jdGlvbigpe2lmKHRoaXMuYj09bnVsbCl7dmFyIHQ9dGhpcy5jCnJldHVybiBuZXcgSC5pNSh0LEgu
+TGgodCkuQygiaTU8MT4iKSl9cmV0dXJuIG5ldyBQLmk4KHRoaXMpfSwKWTpmdW5jdGlvbihhLGIsYyl7
+dmFyIHQscyxyPXRoaXMKaWYoci5iPT1udWxsKXIuYy5ZKDAsYixjKQplbHNlIGlmKHIueDQoYikpe3Q9
+ci5iCnRbYl09YwpzPXIuYQppZihzPT1udWxsP3QhPW51bGw6cyE9PXQpc1tiXT1udWxsfWVsc2Ugci5Y
+SygpLlkoMCxiLGMpfSwKeDQ6ZnVuY3Rpb24oYSl7aWYodGhpcy5iPT1udWxsKXJldHVybiB0aGlzLmMu
+eDQoYSkKcmV0dXJuIE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbCh0aGlzLmEsYSl9
+LApLOmZ1bmN0aW9uKGEsYil7dmFyIHQscyxyLHEscD10aGlzCnUuY0EuYShiKQppZihwLmI9PW51bGwp
+cmV0dXJuIHAuYy5LKDAsYikKdD1wLkNmKCkKZm9yKHM9MDtzPHQubGVuZ3RoOysrcyl7cj10W3NdCnE9
+cC5iW3JdCmlmKHR5cGVvZiBxPT0idW5kZWZpbmVkIil7cT1QLlFlKHAuYVtyXSkKcC5iW3JdPXF9Yi4k
+MihyLHEpCmlmKHQhPT1wLmMpdGhyb3cgSC5iKFAuYTQocCkpfX0sCkNmOmZ1bmN0aW9uKCl7dmFyIHQ9
+dS5qLmEodGhpcy5jKQppZih0PT1udWxsKXQ9dGhpcy5jPUguVk0oT2JqZWN0LmtleXModGhpcy5hKSx1
+LnMpCnJldHVybiB0fSwKWEs6ZnVuY3Rpb24oKXt2YXIgdCxzLHIscSxwLG89dGhpcwppZihvLmI9PW51
+bGwpcmV0dXJuIG8uYwp0PVAuRmwodS5OLHUueikKcz1vLkNmKCkKZm9yKHI9MDtxPXMubGVuZ3RoLHI8
+cTsrK3Ipe3A9c1tyXQp0LlkoMCxwLG8ucSgwLHApKX1pZihxPT09MClDLk5tLmkocywiIikKZWxzZSBD
+Lk5tLnNBKHMsMCkKby5hPW8uYj1udWxsCnJldHVybiBvLmM9dH0sCmZiOmZ1bmN0aW9uKGEpe3ZhciB0
+CmlmKCFPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwodGhpcy5hLGEpKXJldHVybiBu
+dWxsCnQ9UC5RZSh0aGlzLmFbYV0pCnJldHVybiB0aGlzLmJbYV09dH19ClAuaTgucHJvdG90eXBlPXsK
+Z0E6ZnVuY3Rpb24oYSl7dmFyIHQ9dGhpcy5hCnJldHVybiB0LmdBKHQpfSwKRTpmdW5jdGlvbihhLGIp
+e3ZhciB0PXRoaXMuYQppZih0LmI9PW51bGwpdD10LmdWKCkuRSgwLGIpCmVsc2V7dD10LkNmKCkKaWYo
+YjwwfHxiPj10Lmxlbmd0aClyZXR1cm4gSC5rKHQsYikKdD10W2JdfXJldHVybiB0fSwKZ2t6OmZ1bmN0
+aW9uKGEpe3ZhciB0PXRoaXMuYQppZih0LmI9PW51bGwpe3Q9dC5nVigpCnQ9dC5na3oodCl9ZWxzZXt0
+PXQuQ2YoKQp0PW5ldyBKLm0xKHQsdC5sZW5ndGgsSC50Nih0KS5DKCJtMTwxPiIpKX1yZXR1cm4gdH0s
+CnRnOmZ1bmN0aW9uKGEsYil7cmV0dXJuIHRoaXMuYS54NChiKX19ClAucGcucHJvdG90eXBlPXsKJDA6
+ZnVuY3Rpb24oKXt2YXIgdCxzCnRyeXt0PW5ldyBUZXh0RGVjb2RlcigidXRmLTgiLHtmYXRhbDp0cnVl
+fSkKcmV0dXJuIHR9Y2F0Y2gocyl7SC5SdShzKX1yZXR1cm4gbnVsbH0sCiRTOjQzfQpQLkNWLnByb3Rv
+dHlwZT17CnlyOmZ1bmN0aW9uKGEsYTAsYTEpe3ZhciB0LHMscixxLHAsbyxuLG0sbCxrLGosaSxoLGcs
+ZixlLGQsYyxiPSJJbnZhbGlkIGJhc2U2NCBlbmNvZGluZyBsZW5ndGggIgphMT1QLmpCKGEwLGExLGEu
+bGVuZ3RoKQp0PSQuVjcoKQpmb3Iocz1hMCxyPXMscT1udWxsLHA9LTEsbz0tMSxuPTA7czxhMTtzPW0p
+e209cysxCmw9Qy54Qi5XKGEscykKaWYobD09PTM3KXtrPW0rMgppZihrPD1hMSl7aj1ILm9vKEMueEIu
+VyhhLG0pKQppPUgub28oQy54Qi5XKGEsbSsxKSkKaD1qKjE2K2ktKGkmMjU2KQppZihoPT09MzcpaD0t
+MQptPWt9ZWxzZSBoPS0xfWVsc2UgaD1sCmlmKDA8PWgmJmg8PTEyNyl7aWYoaDwwfHxoPj10Lmxlbmd0
+aClyZXR1cm4gSC5rKHQsaCkKZz10W2hdCmlmKGc+PTApe2g9Qy54Qi5tKCJBQkNERUZHSElKS0xNTk9Q
+UVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OSsvIixnKQppZihoPT09
+bCljb250aW51ZQpsPWh9ZWxzZXtpZihnPT09LTEpe2lmKHA8MCl7Zj1xPT1udWxsP251bGw6cS5hLmxl
+bmd0aAppZihmPT1udWxsKWY9MApwPWYrKHMtcikKbz1zfSsrbgppZihsPT09NjEpY29udGludWV9bD1o
+fWlmKGchPT0tMil7aWYocT09bnVsbCl7cT1uZXcgUC5SbigiIikKZj1xfWVsc2UgZj1xCmYuYSs9Qy54
+Qi5OaihhLHIscykKZi5hKz1ILkx3KGwpCnI9bQpjb250aW51ZX19dGhyb3cgSC5iKFAucnIoIkludmFs
+aWQgYmFzZTY0IGRhdGEiLGEscykpfWlmKHEhPW51bGwpe2Y9cS5hKz1DLnhCLk5qKGEscixhMSkKZT1m
+Lmxlbmd0aAppZihwPj0wKVAueE0oYSxvLGExLHAsbixlKQplbHNle2Q9Qy5qbi56WShlLTEsNCkrMQpp
+ZihkPT09MSl0aHJvdyBILmIoUC5ycihiLGEsYTEpKQpmb3IoO2Q8NDspe2YrPSI9IgpxLmE9ZjsrK2R9
+fWY9cS5hCnJldHVybiBDLnhCLmk3KGEsYTAsYTEsZi5jaGFyQ29kZUF0KDApPT0wP2Y6Zil9Yz1hMS1h
+MAppZihwPj0wKVAueE0oYSxvLGExLHAsbixjKQplbHNle2Q9Qy5qbi56WShjLDQpCmlmKGQ9PT0xKXRo
+cm93IEguYihQLnJyKGIsYSxhMSkpCmlmKGQ+MSlhPUMueEIuaTcoYSxhMSxhMSxkPT09Mj8iPT0iOiI9
+Iil9cmV0dXJuIGF9fQpQLlU4LnByb3RvdHlwZT17fQpQLlVrLnByb3RvdHlwZT17fQpQLndJLnByb3Rv
+dHlwZT17fQpQLlppLnByb3RvdHlwZT17fQpQLmJ5LnByb3RvdHlwZT17CnBXOmZ1bmN0aW9uKGEsYixj
+KXt2YXIgdAp1LmNhLmEoYykKdD1QLkJTKGIsdGhpcy5nSGUoKS5hKQpyZXR1cm4gdH0sCmdIZTpmdW5j
+dGlvbigpe3JldHVybiBDLkEzfX0KUC5NeC5wcm90b3R5cGU9e30KUC51NS5wcm90b3R5cGU9ewpnWkU6
+ZnVuY3Rpb24oKXtyZXR1cm4gQy5Ra319ClAuRTMucHJvdG90eXBlPXsKV0o6ZnVuY3Rpb24oYSl7dmFy
+IHQscyxyPVAuakIoMCxudWxsLGEubGVuZ3RoKSxxPXItMAppZihxPT09MClyZXR1cm4gbmV3IFVpbnQ4
+QXJyYXkoMCkKdD1uZXcgVWludDhBcnJheShxKjMpCnM9bmV3IFAuUncodCkKaWYocy5HeChhLDAscikh
+PT1yKXMuTzYoSi5hNihhLHItMSksMCkKcmV0dXJuIG5ldyBVaW50OEFycmF5KHQuc3ViYXJyYXkoMCxI
+LnJNKDAscy5iLHQubGVuZ3RoKSkpfX0KUC5Sdy5wcm90b3R5cGU9ewpPNjpmdW5jdGlvbihhLGIpe3Zh
+ciB0LHM9dGhpcyxyPXMuYyxxPXMuYixwPXErMSxvPXIubGVuZ3RoCmlmKChiJjY0NTEyKT09PTU2MzIw
+KXt0PTY1NTM2KygoYSYxMDIzKTw8MTApfGImMTAyMwpzLmI9cAppZihxPj1vKXJldHVybiBILmsocixx
+KQpyW3FdPTI0MHx0Pj4+MTgKcT1zLmI9cCsxCmlmKHA+PW8pcmV0dXJuIEguayhyLHApCnJbcF09MTI4
+fHQ+Pj4xMiY2MwpwPXMuYj1xKzEKaWYocT49bylyZXR1cm4gSC5rKHIscSkKcltxXT0xMjh8dD4+PjYm
+NjMKcy5iPXArMQppZihwPj1vKXJldHVybiBILmsocixwKQpyW3BdPTEyOHx0JjYzCnJldHVybiEwfWVs
+c2V7cy5iPXAKaWYocT49bylyZXR1cm4gSC5rKHIscSkKcltxXT0yMjR8YT4+PjEyCnE9cy5iPXArMQpp
+ZihwPj1vKXJldHVybiBILmsocixwKQpyW3BdPTEyOHxhPj4+NiY2MwpzLmI9cSsxCmlmKHE+PW8pcmV0
+dXJuIEguayhyLHEpCnJbcV09MTI4fGEmNjMKcmV0dXJuITF9fSwKR3g6ZnVuY3Rpb24oYSxiLGMpe3Zh
+ciB0LHMscixxLHAsbyxuLG09dGhpcwppZihiIT09YyYmKEMueEIubShhLGMtMSkmNjQ1MTIpPT09NTUy
+OTYpLS1jCmZvcih0PW0uYyxzPXQubGVuZ3RoLHI9YjtyPGM7KytyKXtxPUMueEIuVyhhLHIpCmlmKHE8
+PTEyNyl7cD1tLmIKaWYocD49cylicmVhawptLmI9cCsxCnRbcF09cX1lbHNlIGlmKChxJjY0NTEyKT09
+PTU1Mjk2KXtpZihtLmIrMz49cylicmVhawpvPXIrMQppZihtLk82KHEsQy54Qi5XKGEsbykpKXI9b31l
+bHNlIGlmKHE8PTIwNDcpe3A9bS5iCm49cCsxCmlmKG4+PXMpYnJlYWsKbS5iPW4KaWYocD49cylyZXR1
+cm4gSC5rKHQscCkKdFtwXT0xOTJ8cT4+PjYKbS5iPW4rMQp0W25dPTEyOHxxJjYzfWVsc2V7cD1tLmIK
+aWYocCsyPj1zKWJyZWFrCm49bS5iPXArMQppZihwPj1zKXJldHVybiBILmsodCxwKQp0W3BdPTIyNHxx
+Pj4+MTIKcD1tLmI9bisxCmlmKG4+PXMpcmV0dXJuIEguayh0LG4pCnRbbl09MTI4fHE+Pj42JjYzCm0u
+Yj1wKzEKaWYocD49cylyZXR1cm4gSC5rKHQscCkKdFtwXT0xMjh8cSY2M319cmV0dXJuIHJ9fQpQLkdZ
+LnByb3RvdHlwZT17CldKOmZ1bmN0aW9uKGEpe3ZhciB0LHMscixxLHAsbyxuLG0sbAp1LkwuYShhKQp0
+PVAua3koITEsYSwwLG51bGwpCmlmKHQhPW51bGwpcmV0dXJuIHQKcz1QLmpCKDAsbnVsbCxKLkgoYSkp
+CnI9UC5jUChhLDAscykKaWYocj4wKXtxPVAuSE0oYSwwLHIpCmlmKHI9PT1zKXJldHVybiBxCnA9bmV3
+IFAuUm4ocSkKbz1yCm49ITF9ZWxzZXtwPW5ldyBQLlJuKCIiKQpvPTAKbj0hMH1tPW5ldyBQLmJ6KCEx
+LHApCm0uYz1uCm0uTUUoYSxvLHMpCmlmKG0uZT4wKXtILnZoKFAucnIoIlVuZmluaXNoZWQgVVRGLTgg
+b2N0ZXQgc2VxdWVuY2UiLGEscykpCnAuYSs9SC5Mdyg2NTUzMykKbS5mPW0uZT1tLmQ9MH1sPXAuYQpy
+ZXR1cm4gbC5jaGFyQ29kZUF0KDApPT0wP2w6bH19ClAuYnoucHJvdG90eXBlPXsKTUU6ZnVuY3Rpb24o
+YSxiLGMpe3ZhciB0LHMscixxLHAsbyxuLG0sbCxrLGosaSxoPXRoaXMsZz0iQmFkIFVURi04IGVuY29k
+aW5nIDB4Igp1LkwuYShhKQp0PWguZApzPWguZQpyPWguZgpoLmY9aC5lPWguZD0wCiRsYWJlbDAkMDpm
+b3IocT1KLlU2KGEpLHA9aC5iLG89YjshMDtvPWopeyRsYWJlbDEkMTppZihzPjApe2Rve2lmKG89PT1j
+KWJyZWFrICRsYWJlbDAkMApuPXEucShhLG8pCmlmKHR5cGVvZiBuIT09Im51bWJlciIpcmV0dXJuIG4u
+ek0oKQppZigobiYxOTIpIT09MTI4KXttPVAucnIoZytDLmpuLldaKG4sMTYpLGEsbykKdGhyb3cgSC5i
+KG0pfWVsc2V7dD0odDw8NnxuJjYzKT4+PjA7LS1zOysrb319d2hpbGUocz4wKQptPXItMQppZihtPDB8
+fG0+PTQpcmV0dXJuIEguayhDLkdiLG0pCmlmKHQ8PUMuR2JbbV0pe209UC5ycigiT3ZlcmxvbmcgZW5j
+b2Rpbmcgb2YgMHgiK0Muam4uV1oodCwxNiksYSxvLXItMSkKdGhyb3cgSC5iKG0pfWlmKHQ+MTExNDEx
+MSl7bT1QLnJyKCJDaGFyYWN0ZXIgb3V0c2lkZSB2YWxpZCBVbmljb2RlIHJhbmdlOiAweCIrQy5qbi5X
+Wih0LDE2KSxhLG8tci0xKQp0aHJvdyBILmIobSl9aWYoIWguY3x8dCE9PTY1Mjc5KXAuYSs9SC5Mdyh0
+KQpoLmM9ITF9Zm9yKG09bzxjO207KXtsPVAuY1AoYSxvLGMpCmlmKGw+MCl7aC5jPSExCms9bytsCnAu
+YSs9UC5ITShhLG8saykKaWYoaz09PWMpYnJlYWt9ZWxzZSBrPW8Kaj1rKzEKbj1xLnEoYSxrKQppZih0
+eXBlb2YgbiE9PSJudW1iZXIiKXJldHVybiBuLkooKQppZihuPDApe2k9UC5ycigiTmVnYXRpdmUgVVRG
+LTggY29kZSB1bml0OiAtMHgiK0Muam4uV1ooLW4sMTYpLGEsai0xKQp0aHJvdyBILmIoaSl9ZWxzZXtp
+ZigobiYyMjQpPT09MTkyKXt0PW4mMzEKcz0xCnI9MQpjb250aW51ZSAkbGFiZWwwJDB9aWYoKG4mMjQw
+KT09PTIyNCl7dD1uJjE1CnM9MgpyPTIKY29udGludWUgJGxhYmVsMCQwfWlmKChuJjI0OCk9PT0yNDAm
+Jm48MjQ1KXt0PW4mNwpzPTMKcj0zCmNvbnRpbnVlICRsYWJlbDAkMH1pPVAucnIoZytDLmpuLldaKG4s
+MTYpLGEsai0xKQp0aHJvdyBILmIoaSl9fWJyZWFrICRsYWJlbDAkMH1pZihzPjApe2guZD10CmguZT1z
+CmguZj1yfX19ClAuV0YucHJvdG90eXBlPXsKJDI6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzLHIKdS5mby5h
+KGEpCnQ9dGhpcy5iCnM9dGhpcy5hCnQuYSs9cy5hCnI9dC5hKz1ILmQoYS5hKQp0LmE9cisiOiAiCnQu
+YSs9UC5oKGIpCnMuYT0iLCAifSwKJFM6NDR9ClAuYTIucHJvdG90eXBlPXt9ClAuaVAucHJvdG90eXBl
+PXsKRE46ZnVuY3Rpb24oYSxiKXtpZihiPT1udWxsKXJldHVybiExCnJldHVybiBiIGluc3RhbmNlb2Yg
+UC5pUCYmdGhpcy5hPT09Yi5hJiYhMH0sCmdpTzpmdW5jdGlvbihhKXt2YXIgdD10aGlzLmEKcmV0dXJu
+KHReQy5qbi53Ryh0LDMwKSkmMTA3Mzc0MTgyM30sClo6ZnVuY3Rpb24oYSl7dmFyIHQ9dGhpcyxzPVAu
+R3EoSC50Sih0KSkscj1QLmgwKEguTlModCkpLHE9UC5oMChILmpBKHQpKSxwPVAuaDAoSC5JWCh0KSks
+bz1QLmgwKEguY2godCkpLG49UC5oMChILkpkKHQpKSxtPVAuVngoSC5WYSh0KSksbD1zKyItIityKyIt
+IitxKyIgIitwKyI6IitvKyI6IituKyIuIittCnJldHVybiBsfX0KUC5DUC5wcm90b3R5cGU9e30KUC5Y
+Uy5wcm90b3R5cGU9ewpnSUk6ZnVuY3Rpb24oKXtyZXR1cm4gSC50cyh0aGlzLiR0aHJvd25Kc0Vycm9y
+KX19ClAuQzYucHJvdG90eXBlPXsKWjpmdW5jdGlvbihhKXt2YXIgdD10aGlzLmEKaWYodCE9bnVsbCly
+ZXR1cm4iQXNzZXJ0aW9uIGZhaWxlZDogIitQLmgodCkKcmV0dXJuIkFzc2VydGlvbiBmYWlsZWQifX0K
+UC5MSy5wcm90b3R5cGU9ewpaOmZ1bmN0aW9uKGEpe3JldHVybiJUaHJvdyBvZiBudWxsLiJ9fQpQLkFU
+LnByb3RvdHlwZT17CmdMOmZ1bmN0aW9uKCl7cmV0dXJuIkludmFsaWQgYXJndW1lbnQiKyghdGhpcy5h
+PyIocykiOiIiKX0sCmd1OmZ1bmN0aW9uKCl7cmV0dXJuIiJ9LApaOmZ1bmN0aW9uKGEpe3ZhciB0LHMs
+cj10aGlzLHE9ci5jLHA9cT09bnVsbD8iIjoiICgiK3ErIikiLG89ci5kLG49bz09bnVsbD8iIjoiOiAi
+K0guZChvKSxtPXIuZ0woKStwK24KaWYoIXIuYSlyZXR1cm4gbQp0PXIuZ3UoKQpzPVAuaChyLmIpCnJl
+dHVybiBtK3QrIjogIitzfX0KUC5iSi5wcm90b3R5cGU9ewpnTDpmdW5jdGlvbigpe3JldHVybiJSYW5n
+ZUVycm9yIn0sCmd1OmZ1bmN0aW9uKCl7dmFyIHQscz10aGlzLmUscj10aGlzLmYKaWYocz09bnVsbCl0
+PXIhPW51bGw/IjogTm90IGxlc3MgdGhhbiBvciBlcXVhbCB0byAiK0guZChyKToiIgplbHNlIGlmKHI9
+PW51bGwpdD0iOiBOb3QgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvICIrSC5kKHMpCmVsc2UgaWYocj5z
+KXQ9IjogTm90IGluIHJhbmdlICIrSC5kKHMpKyIuLiIrSC5kKHIpKyIsIGluY2x1c2l2ZSIKZWxzZSB0
+PXI8cz8iOiBWYWxpZCB2YWx1ZSByYW5nZSBpcyBlbXB0eSI6IjogT25seSB2YWxpZCB2YWx1ZSBpcyAi
+K0guZChzKQpyZXR1cm4gdH19ClAuZVkucHJvdG90eXBlPXsKZ0w6ZnVuY3Rpb24oKXtyZXR1cm4iUmFu
+Z2VFcnJvciJ9LApndTpmdW5jdGlvbigpe3ZhciB0LHM9SC5XWSh0aGlzLmIpCmlmKHR5cGVvZiBzIT09
+Im51bWJlciIpcmV0dXJuIHMuSigpCmlmKHM8MClyZXR1cm4iOiBpbmRleCBtdXN0IG5vdCBiZSBuZWdh
+dGl2ZSIKdD10aGlzLmYKaWYodD09PTApcmV0dXJuIjogbm8gaW5kaWNlcyBhcmUgdmFsaWQiCnJldHVy
+biI6IGluZGV4IHNob3VsZCBiZSBsZXNzIHRoYW4gIitILmQodCl9LApnQTpmdW5jdGlvbihhKXtyZXR1
+cm4gdGhpcy5mfX0KUC5tcC5wcm90b3R5cGU9ewpaOmZ1bmN0aW9uKGEpe3ZhciB0LHMscixxLHAsbyxu
+LG0sbD10aGlzLGs9e30saj1uZXcgUC5SbigiIikKay5hPSIiCnQ9bC5jCmZvcihzPXQubGVuZ3RoLHI9
+MCxxPSIiLHA9IiI7cjxzOysrcixwPSIsICIpe289dFtyXQpqLmE9cStwCnE9ai5hKz1QLmgobykKay5h
+PSIsICJ9bC5kLksoMCxuZXcgUC5XRihrLGopKQpuPVAuaChsLmEpCm09ai5aKDApCnM9Ik5vU3VjaE1l
+dGhvZEVycm9yOiBtZXRob2Qgbm90IGZvdW5kOiAnIitILmQobC5iLmEpKyInXG5SZWNlaXZlcjogIitu
+KyJcbkFyZ3VtZW50czogWyIrbSsiXSIKcmV0dXJuIHN9fQpQLnViLnByb3RvdHlwZT17Clo6ZnVuY3Rp
+b24oYSl7cmV0dXJuIlVuc3VwcG9ydGVkIG9wZXJhdGlvbjogIit0aGlzLmF9fQpQLmRzLnByb3RvdHlw
+ZT17Clo6ZnVuY3Rpb24oYSl7dmFyIHQ9dGhpcy5hCnJldHVybiB0IT1udWxsPyJVbmltcGxlbWVudGVk
+RXJyb3I6ICIrdDoiVW5pbXBsZW1lbnRlZEVycm9yIn19ClAubGoucHJvdG90eXBlPXsKWjpmdW5jdGlv
+bihhKXtyZXR1cm4iQmFkIHN0YXRlOiAiK3RoaXMuYX19ClAuVVYucHJvdG90eXBlPXsKWjpmdW5jdGlv
+bihhKXt2YXIgdD10aGlzLmEKaWYodD09bnVsbClyZXR1cm4iQ29uY3VycmVudCBtb2RpZmljYXRpb24g
+ZHVyaW5nIGl0ZXJhdGlvbi4iCnJldHVybiJDb25jdXJyZW50IG1vZGlmaWNhdGlvbiBkdXJpbmcgaXRl
+cmF0aW9uOiAiK1AuaCh0KSsiLiJ9fQpQLms1LnByb3RvdHlwZT17Clo6ZnVuY3Rpb24oYSl7cmV0dXJu
+Ik91dCBvZiBNZW1vcnkifSwKZ0lJOmZ1bmN0aW9uKCl7cmV0dXJuIG51bGx9LAokaVhTOjF9ClAuS1ku
+cHJvdG90eXBlPXsKWjpmdW5jdGlvbihhKXtyZXR1cm4iU3RhY2sgT3ZlcmZsb3cifSwKZ0lJOmZ1bmN0
+aW9uKCl7cmV0dXJuIG51bGx9LAokaVhTOjF9ClAudDcucHJvdG90eXBlPXsKWjpmdW5jdGlvbihhKXt2
+YXIgdD10aGlzLmEKcmV0dXJuIHQ9PW51bGw/IlJlYWRpbmcgc3RhdGljIHZhcmlhYmxlIGR1cmluZyBp
+dHMgaW5pdGlhbGl6YXRpb24iOiJSZWFkaW5nIHN0YXRpYyB2YXJpYWJsZSAnIit0KyInIGR1cmluZyBp
+dHMgaW5pdGlhbGl6YXRpb24ifX0KUC5DRC5wcm90b3R5cGU9ewpaOmZ1bmN0aW9uKGEpe3JldHVybiJF
+eGNlcHRpb246ICIrdGhpcy5hfX0KUC5hRS5wcm90b3R5cGU9ewpaOmZ1bmN0aW9uKGEpe3ZhciB0LHMs
+cixxLHAsbyxuLG0sbCxrLGosaSxoPXRoaXMuYSxnPWghPW51bGwmJiIiIT09aD8iRm9ybWF0RXhjZXB0
+aW9uOiAiK0guZChoKToiRm9ybWF0RXhjZXB0aW9uIixmPXRoaXMuYyxlPXRoaXMuYgppZih0eXBlb2Yg
+ZT09InN0cmluZyIpe2lmKGYhPW51bGwpdD1mPDB8fGY+ZS5sZW5ndGgKZWxzZSB0PSExCmlmKHQpZj1u
+dWxsCmlmKGY9PW51bGwpe2lmKGUubGVuZ3RoPjc4KWU9Qy54Qi5OaihlLDAsNzUpKyIuLi4iCnJldHVy
+biBnKyJcbiIrZX1mb3Iocz0xLHI9MCxxPSExLHA9MDtwPGY7KytwKXtvPUMueEIuVyhlLHApCmlmKG89
+PT0xMCl7aWYociE9PXB8fCFxKSsrcwpyPXArMQpxPSExfWVsc2UgaWYobz09PTEzKXsrK3MKcj1wKzEK
+cT0hMH19Zz1zPjE/ZysoIiAoYXQgbGluZSAiK3MrIiwgY2hhcmFjdGVyICIrKGYtcisxKSsiKVxuIik6
+ZysoIiAoYXQgY2hhcmFjdGVyICIrKGYrMSkrIilcbiIpCm49ZS5sZW5ndGgKZm9yKHA9ZjtwPG47Kytw
+KXtvPUMueEIubShlLHApCmlmKG89PT0xMHx8bz09PTEzKXtuPXAKYnJlYWt9fWlmKG4tcj43OClpZihm
+LXI8NzUpe209cis3NQpsPXIKaz0iIgpqPSIuLi4ifWVsc2V7aWYobi1mPDc1KXtsPW4tNzUKbT1uCmo9
+IiJ9ZWxzZXtsPWYtMzYKbT1mKzM2Cmo9Ii4uLiJ9az0iLi4uIn1lbHNle209bgpsPXIKaz0iIgpqPSIi
+fWk9Qy54Qi5OaihlLGwsbSkKcmV0dXJuIGcraytpK2orIlxuIitDLnhCLkl4KCIgIixmLWwray5sZW5n
+dGgpKyJeXG4ifWVsc2UgcmV0dXJuIGYhPW51bGw/ZysoIiAoYXQgb2Zmc2V0ICIrSC5kKGYpKyIpIik6
+Z319ClAuRUgucHJvdG90eXBlPXt9ClAuSWYucHJvdG90eXBlPXt9ClAuY1gucHJvdG90eXBlPXsKRTI6
+ZnVuY3Rpb24oYSxiLGMpe3ZhciB0PUguTGgodGhpcykKcmV0dXJuIEguSzEodGhpcyx0LktxKGMpLkMo
+IjEoY1guRSkiKS5hKGIpLHQuQygiY1guRSIpLGMpfSwKZXY6ZnVuY3Rpb24oYSxiKXt2YXIgdD1ILkxo
+KHRoaXMpCnJldHVybiBuZXcgSC5VNSh0aGlzLHQuQygiYTIoY1guRSkiKS5hKGIpLHQuQygiVTU8Y1gu
+RT4iKSl9LApnQTpmdW5jdGlvbihhKXt2YXIgdCxzPXRoaXMuZ2t6KHRoaXMpCmZvcih0PTA7cy5GKCk7
+KSsrdApyZXR1cm4gdH0sCmdsMDpmdW5jdGlvbihhKXtyZXR1cm4hdGhpcy5na3oodGhpcykuRigpfSwK
+Z3I4OmZ1bmN0aW9uKGEpe3ZhciB0LHM9dGhpcy5na3oodGhpcykKaWYoIXMuRigpKXRocm93IEguYihI
+LldwKCkpCnQ9cy5nbCgpCmlmKHMuRigpKXRocm93IEguYihILmRVKCkpCnJldHVybiB0fSwKRTpmdW5j
+dGlvbihhLGIpe3ZhciB0LHMscgpQLmsxKGIsImluZGV4IikKZm9yKHQ9dGhpcy5na3oodGhpcykscz0w
+O3QuRigpOyl7cj10LmdsKCkKaWYoYj09PXMpcmV0dXJuIHI7KytzfXRocm93IEguYihQLnQoYix0aGlz
+LCJpbmRleCIsbnVsbCxzKSl9LApaOmZ1bmN0aW9uKGEpe3JldHVybiBQLkVQKHRoaXMsIigiLCIpIil9
+fQpQLkFuLnByb3RvdHlwZT17fQpQLnpNLnByb3RvdHlwZT17JGliUToxLCRpY1g6MX0KUC5aMC5wcm90
+b3R5cGU9e30KUC5OMy5wcm90b3R5cGU9ewpaOmZ1bmN0aW9uKGEpe3JldHVybiJNYXBFbnRyeSgiK0gu
+ZChKLkFjKHRoaXMuYSkpKyI6ICIrSC5kKEouQWModGhpcy5iKSkrIikifX0KUC5jOC5wcm90b3R5cGU9
+ewpnaU86ZnVuY3Rpb24oYSl7cmV0dXJuIFAuTWgucHJvdG90eXBlLmdpTy5jYWxsKHRoaXMsdGhpcyl9
+LApaOmZ1bmN0aW9uKGEpe3JldHVybiJudWxsIn19ClAubGYucHJvdG90eXBlPXt9ClAuTWgucHJvdG90
+eXBlPXtjb25zdHJ1Y3RvcjpQLk1oLCRpTWg6MSwKRE46ZnVuY3Rpb24oYSxiKXtyZXR1cm4gdGhpcz09
+PWJ9LApnaU86ZnVuY3Rpb24oYSl7cmV0dXJuIEguZVEodGhpcyl9LApaOmZ1bmN0aW9uKGEpe3JldHVy
+biJJbnN0YW5jZSBvZiAnIitILmQoSC5saCh0aGlzKSkrIicifSwKZTc6ZnVuY3Rpb24oYSxiKXt1Lm8u
+YShiKQp0aHJvdyBILmIoUC5scih0aGlzLGIuZ1dhKCksYi5nbmQoKSxiLmdWbSgpKSl9LAp0b1N0cmlu
+ZzpmdW5jdGlvbigpe3JldHVybiB0aGlzLloodGhpcyl9fQpQLk9kLnByb3RvdHlwZT17fQpQLmliLnBy
+b3RvdHlwZT17JGlPZDoxfQpQLnh1LnByb3RvdHlwZT17fQpQLkd6LnByb3RvdHlwZT17fQpQLlpkLnBy
+b3RvdHlwZT17Clo6ZnVuY3Rpb24oYSl7cmV0dXJuIiJ9LAokaUd6OjF9ClAucVUucHJvdG90eXBlPXsk
+aXZYOjF9ClAuUm4ucHJvdG90eXBlPXsKZ0E6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuYS5sZW5ndGh9
+LApaOmZ1bmN0aW9uKGEpe3ZhciB0PXRoaXMuYQpyZXR1cm4gdC5jaGFyQ29kZUF0KDApPT0wP3Q6dH0s
+CiRpQkw6MX0KUC5HRC5wcm90b3R5cGU9e30KUC5uMS5wcm90b3R5cGU9ewokMjpmdW5jdGlvbihhLGIp
+e3ZhciB0LHMscixxCnUuZi5hKGEpCkguYyhiKQp0PUouclkoYikuT1koYiwiPSIpCmlmKHQ9PT0tMSl7
+aWYoYiE9PSIiKWEuWSgwLFAua3UoYiwwLGIubGVuZ3RoLHRoaXMuYSwhMCksIiIpfWVsc2UgaWYodCE9
+PTApe3M9Qy54Qi5OaihiLDAsdCkKcj1DLnhCLkcoYix0KzEpCnE9dGhpcy5hCmEuWSgwLFAua3Uocyww
+LHMubGVuZ3RoLHEsITApLFAua3UociwwLHIubGVuZ3RoLHEsITApKX1yZXR1cm4gYX0sCiRTOjE5fQpQ
+LmNTLnByb3RvdHlwZT17CiQyOmZ1bmN0aW9uKGEsYil7dGhyb3cgSC5iKFAucnIoIklsbGVnYWwgSVB2
+NCBhZGRyZXNzLCAiK2EsdGhpcy5hLGIpKX0sCiRTOjQ3fQpQLlZDLnByb3RvdHlwZT17CiQyOmZ1bmN0
+aW9uKGEsYil7dGhyb3cgSC5iKFAucnIoIklsbGVnYWwgSVB2NiBhZGRyZXNzLCAiK2EsdGhpcy5hLGIp
+KX0sCiQxOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLiQyKGEsbnVsbCl9LAokUzo0OH0KUC5KVC5wcm90
+b3R5cGU9ewokMjpmdW5jdGlvbihhLGIpe3ZhciB0CmlmKGItYT40KXRoaXMuYS4kMigiYW4gSVB2NiBw
+YXJ0IGNhbiBvbmx5IGNvbnRhaW4gYSBtYXhpbXVtIG9mIDQgaGV4IGRpZ2l0cyIsYSkKdD1QLlFBKEMu
+eEIuTmoodGhpcy5iLGEsYiksMTYpCmlmKHR5cGVvZiB0IT09Im51bWJlciIpcmV0dXJuIHQuSigpCmlm
+KHQ8MHx8dD42NTUzNSl0aGlzLmEuJDIoImVhY2ggcGFydCBtdXN0IGJlIGluIHRoZSByYW5nZSBvZiBg
+MHgwLi4weEZGRkZgIixhKQpyZXR1cm4gdH0sCiRTOjIwfQpQLkRuLnByb3RvdHlwZT17CmduRDpmdW5j
+dGlvbigpe3ZhciB0LHMscixxPXRoaXMscD1xLngKaWYocD09bnVsbCl7cD1xLmEKdD1wLmxlbmd0aCE9
+PTA/cCsiOiI6IiIKcz1xLmMKcj1zPT1udWxsCmlmKCFyfHxwPT09ImZpbGUiKXtwPXQrIi8vIgp0PXEu
+YgppZih0Lmxlbmd0aCE9PTApcD1wK3QrIkAiCmlmKCFyKXArPXMKdD1xLmQKaWYodCE9bnVsbClwPXAr
+IjoiK0guZCh0KX1lbHNlIHA9dApwKz1xLmUKdD1xLmYKaWYodCE9bnVsbClwPXArIj8iK3QKdD1xLnIK
+aWYodCE9bnVsbClwPXArIiMiK3QKcD1wLmNoYXJDb2RlQXQoMCk9PTA/cDpwCmlmKHEueD09bnVsbClx
+Lng9cAplbHNlIHA9SC52aChILnlSKCJGaWVsZCAnX3RleHQnIGhhcyBiZWVuIGFzc2lnbmVkIGR1cmlu
+ZyBpbml0aWFsaXphdGlvbi4iKSl9cmV0dXJuIHB9LApnRmo6ZnVuY3Rpb24oKXt2YXIgdCxzPXRoaXMs
+cj1zLnkKaWYocj09bnVsbCl7dD1zLmUKaWYodC5sZW5ndGghPT0wJiZDLnhCLlcodCwwKT09PTQ3KXQ9
+Qy54Qi5HKHQsMSkKcj10Lmxlbmd0aD09PTA/Qy54RDpQLkFGKG5ldyBILmxKKEguVk0odC5zcGxpdCgi
+LyIpLHUucyksdS5kTy5hKFAuUEgoKSksdS5kbyksdS5OKQppZihzLnk9PW51bGwpcy5zS3AocikKZWxz
+ZSByPUgudmgoSC55UigiRmllbGQgJ3BhdGhTZWdtZW50cycgaGFzIGJlZW4gYXNzaWduZWQgZHVyaW5n
+IGluaXRpYWxpemF0aW9uLiIpKX1yZXR1cm4gcn0sCmdpTzpmdW5jdGlvbihhKXt2YXIgdD10aGlzLHM9
+dC56CmlmKHM9PW51bGwpe3M9Qy54Qi5naU8odC5nbkQoKSkKaWYodC56PT1udWxsKXQuej1zCmVsc2Ug
+cz1ILnZoKEgueVIoIkZpZWxkICdoYXNoQ29kZScgaGFzIGJlZW4gYXNzaWduZWQgZHVyaW5nIGluaXRp
+YWxpemF0aW9uLiIpKX1yZXR1cm4gc30sCmdoWTpmdW5jdGlvbigpe3ZhciB0PXRoaXMscz10LlEKaWYo
+cz09bnVsbCl7cz1uZXcgUC5HaihQLldYKHQuZ3RQKCkpLHUuRCkKaWYodC5RPT1udWxsKXQuc05NKHMp
+CmVsc2Ugcz1ILnZoKEgueVIoIkZpZWxkICdxdWVyeVBhcmFtZXRlcnMnIGhhcyBiZWVuIGFzc2lnbmVk
+IGR1cmluZyBpbml0aWFsaXphdGlvbi4iKSl9cmV0dXJuIHN9LApna3U6ZnVuY3Rpb24oKXtyZXR1cm4g
+dGhpcy5ifSwKZ0pmOmZ1bmN0aW9uKGEpe3ZhciB0PXRoaXMuYwppZih0PT1udWxsKXJldHVybiIiCmlm
+KEMueEIubih0LCJbIikpcmV0dXJuIEMueEIuTmoodCwxLHQubGVuZ3RoLTEpCnJldHVybiB0fSwKZ3Rw
+OmZ1bmN0aW9uKGEpe3ZhciB0PXRoaXMuZApyZXR1cm4gdD09bnVsbD9QLndLKHRoaXMuYSk6dH0sCmd0
+UDpmdW5jdGlvbigpe3ZhciB0PXRoaXMuZgpyZXR1cm4gdD09bnVsbD8iIjp0fSwKZ0thOmZ1bmN0aW9u
+KCl7dmFyIHQ9dGhpcy5yCnJldHVybiB0PT1udWxsPyIiOnR9LApubTpmdW5jdGlvbihhLGIpe3ZhciB0
+LHMscixxLHAsbyxuLG0sbCxrPXRoaXMKdS5YLmEobnVsbCkKdS5iLmEoYikKdD1rLmEKcz10PT09ImZp
+bGUiCnI9ay5iCnE9ay5kCnA9ay5jCmlmKCEocCE9bnVsbCkpcD1yLmxlbmd0aCE9PTB8fHEhPW51bGx8
+fHM/IiI6bnVsbApvPWsuZQppZighcyluPXAhPW51bGwmJm8ubGVuZ3RoIT09MAplbHNlIG49ITAKaWYo
+biYmIUMueEIubihvLCIvIikpbz0iLyIrbwptPW8KbD1QLmxlKG51bGwsMCwwLGIpCnJldHVybiBuZXcg
+UC5Ebih0LHIscCxxLG0sbCxrLnIpfSwKSmg6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzLHIscSxwLG8KZm9y
+KHQ9MCxzPTA7Qy54Qi5RaShiLCIuLi8iLHMpOyl7cys9MzsrK3R9cj1DLnhCLmNuKGEsIi8iKQp3aGls
+ZSghMCl7aWYoIShyPjAmJnQ+MCkpYnJlYWsKcT1DLnhCLlBrKGEsIi8iLHItMSkKaWYocTwwKWJyZWFr
+CnA9ci1xCm89cCE9PTIKaWYoIW98fHA9PT0zKWlmKEMueEIubShhLHErMSk9PT00NilvPSFvfHxDLnhC
+Lm0oYSxxKzIpPT09NDYKZWxzZSBvPSExCmVsc2Ugbz0hMQppZihvKWJyZWFrOy0tdApyPXF9cmV0dXJu
+IEMueEIuaTcoYSxyKzEsbnVsbCxDLnhCLkcoYixzLTMqdCkpfSwKWkk6ZnVuY3Rpb24oYSl7cmV0dXJu
+IHRoaXMubVMoUC5oSyhhKSl9LAptUzpmdW5jdGlvbihhKXt2YXIgdCxzLHIscSxwLG8sbixtLGwsaz10
+aGlzLGo9bnVsbAppZihhLmdGaSgpLmxlbmd0aCE9PTApe3Q9YS5nRmkoKQppZihhLmdjaigpKXtzPWEu
+Z2t1KCkKcj1hLmdKZihhKQpxPWEuZ3hBKCk/YS5ndHAoYSk6an1lbHNle3E9agpyPXEKcz0iIn1wPVAu
+eGUoYS5nSWkoYSkpCm89YS5nUUQoKT9hLmd0UCgpOmp9ZWxzZXt0PWsuYQppZihhLmdjaigpKXtzPWEu
+Z2t1KCkKcj1hLmdKZihhKQpxPVAud0IoYS5neEEoKT9hLmd0cChhKTpqLHQpCnA9UC54ZShhLmdJaShh
+KSkKbz1hLmdRRCgpP2EuZ3RQKCk6an1lbHNle3M9ay5iCnI9ay5jCnE9ay5kCmlmKGEuZ0lpKGEpPT09
+IiIpe3A9ay5lCm89YS5nUUQoKT9hLmd0UCgpOmsuZn1lbHNle2lmKGEuZ3RUKCkpcD1QLnhlKGEuZ0lp
+KGEpKQplbHNle249ay5lCmlmKG4ubGVuZ3RoPT09MClpZihyPT1udWxsKXA9dC5sZW5ndGg9PT0wP2Eu
+Z0lpKGEpOlAueGUoYS5nSWkoYSkpCmVsc2UgcD1QLnhlKCIvIithLmdJaShhKSkKZWxzZXttPWsuSmgo
+bixhLmdJaShhKSkKbD10Lmxlbmd0aD09PTAKaWYoIWx8fHIhPW51bGx8fEMueEIubihuLCIvIikpcD1Q
+LnhlKG0pCmVsc2UgcD1QLndGKG0sIWx8fHIhPW51bGwpfX1vPWEuZ1FEKCk/YS5ndFAoKTpqfX19cmV0
+dXJuIG5ldyBQLkRuKHQscyxyLHEscCxvLGEuZ1o4KCk/YS5nS2EoKTpqKX0sCmdjajpmdW5jdGlvbigp
+e3JldHVybiB0aGlzLmMhPW51bGx9LApneEE6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5kIT1udWxsfSwK
+Z1FEOmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuZiE9bnVsbH0sCmdaODpmdW5jdGlvbigpe3JldHVybiB0
+aGlzLnIhPW51bGx9LApndFQ6ZnVuY3Rpb24oKXtyZXR1cm4gQy54Qi5uKHRoaXMuZSwiLyIpfSwKdDQ6
+ZnVuY3Rpb24oKXt2YXIgdCxzPXRoaXMscj1zLmEKaWYociE9PSIiJiZyIT09ImZpbGUiKXRocm93IEgu
+YihQLkw0KCJDYW5ub3QgZXh0cmFjdCBhIGZpbGUgcGF0aCBmcm9tIGEgIityKyIgVVJJIikpCmlmKHMu
+Z3RQKCkhPT0iIil0aHJvdyBILmIoUC5MNCgiQ2Fubm90IGV4dHJhY3QgYSBmaWxlIHBhdGggZnJvbSBh
+IFVSSSB3aXRoIGEgcXVlcnkgY29tcG9uZW50IikpCmlmKHMuZ0thKCkhPT0iIil0aHJvdyBILmIoUC5M
+NCgiQ2Fubm90IGV4dHJhY3QgYSBmaWxlIHBhdGggZnJvbSBhIFVSSSB3aXRoIGEgZnJhZ21lbnQgY29t
+cG9uZW50IikpCnI9JC5PeCgpCmlmKEgub1Qocikpcj1QLm1uKHMpCmVsc2V7aWYocy5jIT1udWxsJiZz
+LmdKZihzKSE9PSIiKUgudmgoUC5MNCgiQ2Fubm90IGV4dHJhY3QgYSBub24tV2luZG93cyBmaWxlIHBh
+dGggZnJvbSBhIGZpbGUgVVJJIHdpdGggYW4gYXV0aG9yaXR5IikpCnQ9cy5nRmooKQpQLmtFKHQsITEp
+CnI9UC52ZyhDLnhCLm4ocy5lLCIvIik/Ii8iOiIiLHQsIi8iKQpyPXIuY2hhckNvZGVBdCgwKT09MD9y
+OnJ9cmV0dXJuIHJ9LApaOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLmduRCgpfSwKRE46ZnVuY3Rpb24o
+YSxiKXt2YXIgdD10aGlzCmlmKGI9PW51bGwpcmV0dXJuITEKaWYodD09PWIpcmV0dXJuITAKcmV0dXJu
+IHUuRi5iKGIpJiZ0LmE9PT1iLmdGaSgpJiZ0LmMhPW51bGw9PT1iLmdjaigpJiZ0LmI9PT1iLmdrdSgp
+JiZ0LmdKZih0KT09PWIuZ0pmKGIpJiZ0Lmd0cCh0KT09PWIuZ3RwKGIpJiZ0LmU9PT1iLmdJaShiKSYm
+dC5mIT1udWxsPT09Yi5nUUQoKSYmdC5ndFAoKT09PWIuZ3RQKCkmJnQuciE9bnVsbD09PWIuZ1o4KCkm
+JnQuZ0thKCk9PT1iLmdLYSgpfSwKc0twOmZ1bmN0aW9uKGEpe3RoaXMueT11LmEuYShhKX0sCnNOTTpm
+dW5jdGlvbihhKXt0aGlzLlE9dS5mLmEoYSl9LAokaWlEOjEsCmdGaTpmdW5jdGlvbigpe3JldHVybiB0
+aGlzLmF9LApnSWk6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuZX19ClAuUloucHJvdG90eXBlPXsKJDE6
+ZnVuY3Rpb24oYSl7cmV0dXJuIFAuZVAoQy5aSixILmMoYSksQy54TSwhMSl9LAokUzo0fQpQLk1FLnBy
+b3RvdHlwZT17CiQyOmZ1bmN0aW9uKGEsYil7dmFyIHQ9dGhpcy5iLHM9dGhpcy5hCnQuYSs9cy5hCnMu
+YT0iJiIKcz10LmErPUguZChQLmVQKEMuRjMsYSxDLnhNLCEwKSkKaWYoYiE9bnVsbCYmYi5sZW5ndGgh
+PT0wKXt0LmE9cysiPSIKdC5hKz1ILmQoUC5lUChDLkYzLGIsQy54TSwhMCkpfX0sCiRTOjIyfQpQLnk1
+LnByb3RvdHlwZT17CiQyOmZ1bmN0aW9uKGEsYil7dmFyIHQscwpILmMoYSkKaWYoYj09bnVsbHx8dHlw
+ZW9mIGI9PSJzdHJpbmciKXRoaXMuYS4kMihhLEguYyhiKSkKZWxzZSBmb3IodD1KLklUKHUuUi5hKGIp
+KSxzPXRoaXMuYTt0LkYoKTspcy4kMihhLEguYyh0LmdsKCkpKX0sCiRTOjEzfQpQLlBFLnByb3RvdHlw
+ZT17CmdsUjpmdW5jdGlvbigpe3ZhciB0LHMscixxLHA9dGhpcyxvPW51bGwsbj1wLmMKaWYobj09bnVs
+bCl7bj1wLmIKaWYoMD49bi5sZW5ndGgpcmV0dXJuIEguayhuLDApCnQ9cC5hCm49blswXSsxCnM9Qy54
+Qi5YVSh0LCI/IixuKQpyPXQubGVuZ3RoCmlmKHM+PTApe3E9UC5QSSh0LHMrMSxyLEMuVkMsITEpCnI9
+c31lbHNlIHE9bwpuPXAuYz1uZXcgUC5xZSgiZGF0YSIsIiIsbyxvLFAuUEkodCxuLHIsQy5XZCwhMSks
+cSxvKX1yZXR1cm4gbn0sClo6ZnVuY3Rpb24oYSl7dmFyIHQscz10aGlzLmIKaWYoMD49cy5sZW5ndGgp
+cmV0dXJuIEguayhzLDApCnQ9dGhpcy5hCnJldHVybiBzWzBdPT09LTE/ImRhdGE6Iit0OnR9fQpQLnEz
+LnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe3JldHVybiBuZXcgVWludDhBcnJheSg5Nil9LAokUzoy
+M30KUC55SS5wcm90b3R5cGU9ewokMjpmdW5jdGlvbihhLGIpe3ZhciB0PXRoaXMuYQppZihhPj10Lmxl
+bmd0aClyZXR1cm4gSC5rKHQsYSkKdD10W2FdCkouQ00odCwwLDk2LGIpCnJldHVybiB0fSwKJFM6MjR9
+ClAuYzYucHJvdG90eXBlPXsKJDM6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0LHMscixxCmZvcih0PWIubGVu
+Z3RoLHM9YS5sZW5ndGgscj0wO3I8dDsrK3Ipe3E9Qy54Qi5XKGIscileOTYKaWYocT49cylyZXR1cm4g
+SC5rKGEscSkKYVtxXT1jfX19ClAucWQucHJvdG90eXBlPXsKJDM6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0
+LHMscixxCmZvcih0PUMueEIuVyhiLDApLHM9Qy54Qi5XKGIsMSkscj1hLmxlbmd0aDt0PD1zOysrdCl7
+cT0odF45Nik+Pj4wCmlmKHE+PXIpcmV0dXJuIEguayhhLHEpCmFbcV09Y319fQpQLlVmLnByb3RvdHlw
+ZT17CmdjajpmdW5jdGlvbigpe3JldHVybiB0aGlzLmM+MH0sCmd4QTpmdW5jdGlvbigpe3JldHVybiB0
+aGlzLmM+MCYmdGhpcy5kKzE8dGhpcy5lfSwKZ1FEOmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuZjx0aGlz
+LnJ9LApnWjg6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5yPHRoaXMuYS5sZW5ndGh9LApnTnc6ZnVuY3Rp
+b24oKXtyZXR1cm4gdGhpcy5iPT09NCYmQy54Qi5uKHRoaXMuYSwiZmlsZSIpfSwKZ3ZoOmZ1bmN0aW9u
+KCl7cmV0dXJuIHRoaXMuYj09PTQmJkMueEIubih0aGlzLmEsImh0dHAiKX0sCmdSZTpmdW5jdGlvbigp
+e3JldHVybiB0aGlzLmI9PT01JiZDLnhCLm4odGhpcy5hLCJodHRwcyIpfSwKZ3RUOmZ1bmN0aW9uKCl7
+cmV0dXJuIEMueEIuUWkodGhpcy5hLCIvIix0aGlzLmUpfSwKZ0ZpOmZ1bmN0aW9uKCl7dmFyIHQ9dGhp
+cy54CnJldHVybiB0PT1udWxsP3RoaXMueD10aGlzLlUyKCk6dH0sClUyOmZ1bmN0aW9uKCl7dmFyIHQ9
+dGhpcyxzPXQuYgppZihzPD0wKXJldHVybiIiCmlmKHQuZ3ZoKCkpcmV0dXJuImh0dHAiCmlmKHQuZ1Jl
+KCkpcmV0dXJuImh0dHBzIgppZih0LmdOdygpKXJldHVybiJmaWxlIgppZihzPT09NyYmQy54Qi5uKHQu
+YSwicGFja2FnZSIpKXJldHVybiJwYWNrYWdlIgpyZXR1cm4gQy54Qi5Oaih0LmEsMCxzKX0sCmdrdTpm
+dW5jdGlvbigpe3ZhciB0PXRoaXMuYyxzPXRoaXMuYiszCnJldHVybiB0PnM/Qy54Qi5Oaih0aGlzLmEs
+cyx0LTEpOiIifSwKZ0pmOmZ1bmN0aW9uKGEpe3ZhciB0PXRoaXMuYwpyZXR1cm4gdD4wP0MueEIuTmoo
+dGhpcy5hLHQsdGhpcy5kKToiIn0sCmd0cDpmdW5jdGlvbihhKXt2YXIgdD10aGlzCmlmKHQuZ3hBKCkp
+cmV0dXJuIFAuUUEoQy54Qi5Oaih0LmEsdC5kKzEsdC5lKSxudWxsKQppZih0Lmd2aCgpKXJldHVybiA4
+MAppZih0LmdSZSgpKXJldHVybiA0NDMKcmV0dXJuIDB9LApnSWk6ZnVuY3Rpb24oYSl7cmV0dXJuIEMu
+eEIuTmoodGhpcy5hLHRoaXMuZSx0aGlzLmYpfSwKZ3RQOmZ1bmN0aW9uKCl7dmFyIHQ9dGhpcy5mLHM9
+dGhpcy5yCnJldHVybiB0PHM/Qy54Qi5Oaih0aGlzLmEsdCsxLHMpOiIifSwKZ0thOmZ1bmN0aW9uKCl7
+dmFyIHQ9dGhpcy5yLHM9dGhpcy5hCnJldHVybiB0PHMubGVuZ3RoP0MueEIuRyhzLHQrMSk6IiJ9LApn
+Rmo6ZnVuY3Rpb24oKXt2YXIgdCxzLHI9dGhpcy5lLHE9dGhpcy5mLHA9dGhpcy5hCmlmKEMueEIuUWko
+cCwiLyIscikpKytyCmlmKHI9PT1xKXJldHVybiBDLnhECnQ9SC5WTShbXSx1LnMpCmZvcihzPXI7czxx
+OysrcylpZihDLnhCLm0ocCxzKT09PTQ3KXtDLk5tLmkodCxDLnhCLk5qKHAscixzKSkKcj1zKzF9Qy5O
+bS5pKHQsQy54Qi5OaihwLHIscSkpCnJldHVybiBQLkFGKHQsdS5OKX0sCmdoWTpmdW5jdGlvbigpe2lm
+KHRoaXMuZj49dGhpcy5yKXJldHVybiBDLldPCnJldHVybiBuZXcgUC5HaihQLldYKHRoaXMuZ3RQKCkp
+LHUuRCl9LAprWDpmdW5jdGlvbihhKXt2YXIgdD10aGlzLmQrMQpyZXR1cm4gdCthLmxlbmd0aD09PXRo
+aXMuZSYmQy54Qi5RaSh0aGlzLmEsYSx0KX0sCk45OmZ1bmN0aW9uKCl7dmFyIHQ9dGhpcyxzPXQucixy
+PXQuYQppZihzPj1yLmxlbmd0aClyZXR1cm4gdApyZXR1cm4gbmV3IFAuVWYoQy54Qi5OaihyLDAscyks
+dC5iLHQuYyx0LmQsdC5lLHQuZixzLHQueCl9LApubTpmdW5jdGlvbihhLGIpe3ZhciB0LHMscixxLHAs
+byxuLG0sbCxrLGo9dGhpcyxpPW51bGwKdS5YLmEobnVsbCkKdS5iLmEoYikKdD1qLmdGaSgpCnM9dD09
+PSJmaWxlIgpyPWouYwpxPXI+MD9DLnhCLk5qKGouYSxqLmIrMyxyKToiIgpwPWouZ3hBKCk/ai5ndHAo
+aik6aQpyPWouYwppZihyPjApbz1DLnhCLk5qKGouYSxyLGouZCkKZWxzZSBvPXEubGVuZ3RoIT09MHx8
+cCE9bnVsbHx8cz8iIjppCnI9ai5hCm49Qy54Qi5OaihyLGouZSxqLmYpCmlmKCFzKW09byE9bnVsbCYm
+bi5sZW5ndGghPT0wCmVsc2UgbT0hMAppZihtJiYhQy54Qi5uKG4sIi8iKSluPSIvIituCmw9UC5sZShp
+LDAsMCxiKQptPWoucgprPW08ci5sZW5ndGg/Qy54Qi5HKHIsbSsxKTppCnJldHVybiBuZXcgUC5Ebih0
+LHEsbyxwLG4sbCxrKX0sClpJOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLm1TKFAuaEsoYSkpfSwKbVM6
+ZnVuY3Rpb24oYSl7aWYoYSBpbnN0YW5jZW9mIFAuVWYpcmV0dXJuIHRoaXMudTEodGhpcyxhKQpyZXR1
+cm4gdGhpcy52cygpLm1TKGEpfSwKdTE6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzLHIscSxwLG8sbixtLGws
+ayxqLGksaD1iLmIKaWYoaD4wKXJldHVybiBiCnQ9Yi5jCmlmKHQ+MCl7cz1hLmIKaWYoczw9MClyZXR1
+cm4gYgppZihhLmdOdygpKXI9Yi5lIT09Yi5mCmVsc2UgaWYoYS5ndmgoKSlyPSFiLmtYKCI4MCIpCmVs
+c2Ugcj0hYS5nUmUoKXx8IWIua1goIjQ0MyIpCmlmKHIpe3E9cysxCnJldHVybiBuZXcgUC5VZihDLnhC
+Lk5qKGEuYSwwLHEpK0MueEIuRyhiLmEsaCsxKSxzLHQrcSxiLmQrcSxiLmUrcSxiLmYrcSxiLnIrcSxh
+LngpfWVsc2UgcmV0dXJuIHRoaXMudnMoKS5tUyhiKX1wPWIuZQpoPWIuZgppZihwPT09aCl7dD1iLnIK
+aWYoaDx0KXtzPWEuZgpxPXMtaApyZXR1cm4gbmV3IFAuVWYoQy54Qi5OaihhLmEsMCxzKStDLnhCLkco
+Yi5hLGgpLGEuYixhLmMsYS5kLGEuZSxoK3EsdCtxLGEueCl9aD1iLmEKaWYodDxoLmxlbmd0aCl7cz1h
+LnIKcmV0dXJuIG5ldyBQLlVmKEMueEIuTmooYS5hLDAscykrQy54Qi5HKGgsdCksYS5iLGEuYyxhLmQs
+YS5lLGEuZix0KyhzLXQpLGEueCl9cmV0dXJuIGEuTjkoKX10PWIuYQppZihDLnhCLlFpKHQsIi8iLHAp
+KXtzPWEuZQpxPXMtcApyZXR1cm4gbmV3IFAuVWYoQy54Qi5OaihhLmEsMCxzKStDLnhCLkcodCxwKSxh
+LmIsYS5jLGEuZCxzLGgrcSxiLnIrcSxhLngpfW89YS5lCm49YS5mCmlmKG89PT1uJiZhLmM+MCl7Zm9y
+KDtDLnhCLlFpKHQsIi4uLyIscCk7KXArPTMKcT1vLXArMQpyZXR1cm4gbmV3IFAuVWYoQy54Qi5Oaihh
+LmEsMCxvKSsiLyIrQy54Qi5HKHQscCksYS5iLGEuYyxhLmQsbyxoK3EsYi5yK3EsYS54KX1tPWEuYQpm
+b3IobD1vO0MueEIuUWkobSwiLi4vIixsKTspbCs9MwprPTAKd2hpbGUoITApe2o9cCszCmlmKCEoajw9
+aCYmQy54Qi5RaSh0LCIuLi8iLHApKSlicmVhazsrK2sKcD1qfWZvcihpPSIiO24+bDspey0tbgppZihD
+LnhCLm0obSxuKT09PTQ3KXtpZihrPT09MCl7aT0iLyIKYnJlYWt9LS1rCmk9Ii8ifX1pZihuPT09bCYm
+YS5iPD0wJiYhQy54Qi5RaShtLCIvIixvKSl7cC09ayozCmk9IiJ9cT1uLXAraS5sZW5ndGgKcmV0dXJu
+IG5ldyBQLlVmKEMueEIuTmoobSwwLG4pK2krQy54Qi5HKHQscCksYS5iLGEuYyxhLmQsbyxoK3EsYi5y
+K3EsYS54KX0sCnQ0OmZ1bmN0aW9uKCl7dmFyIHQscyxyLHE9dGhpcwppZihxLmI+PTAmJiFxLmdOdygp
+KXRocm93IEguYihQLkw0KCJDYW5ub3QgZXh0cmFjdCBhIGZpbGUgcGF0aCBmcm9tIGEgIitxLmdGaSgp
+KyIgVVJJIikpCnQ9cS5mCnM9cS5hCmlmKHQ8cy5sZW5ndGgpe2lmKHQ8cS5yKXRocm93IEguYihQLkw0
+KCJDYW5ub3QgZXh0cmFjdCBhIGZpbGUgcGF0aCBmcm9tIGEgVVJJIHdpdGggYSBxdWVyeSBjb21wb25l
+bnQiKSkKdGhyb3cgSC5iKFAuTDQoIkNhbm5vdCBleHRyYWN0IGEgZmlsZSBwYXRoIGZyb20gYSBVUkkg
+d2l0aCBhIGZyYWdtZW50IGNvbXBvbmVudCIpKX1yPSQuT3goKQppZihILm9UKHIpKXQ9UC5tbihxKQpl
+bHNle2lmKHEuYzxxLmQpSC52aChQLkw0KCJDYW5ub3QgZXh0cmFjdCBhIG5vbi1XaW5kb3dzIGZpbGUg
+cGF0aCBmcm9tIGEgZmlsZSBVUkkgd2l0aCBhbiBhdXRob3JpdHkiKSkKdD1DLnhCLk5qKHMscS5lLHQp
+fXJldHVybiB0fSwKZ2lPOmZ1bmN0aW9uKGEpe3ZhciB0PXRoaXMueQpyZXR1cm4gdD09bnVsbD90aGlz
+Lnk9Qy54Qi5naU8odGhpcy5hKTp0fSwKRE46ZnVuY3Rpb24oYSxiKXtpZihiPT1udWxsKXJldHVybiEx
+CmlmKHRoaXM9PT1iKXJldHVybiEwCnJldHVybiB1LkYuYihiKSYmdGhpcy5hPT09Yi5aKDApfSwKdnM6
+ZnVuY3Rpb24oKXt2YXIgdD10aGlzLHM9bnVsbCxyPXQuZ0ZpKCkscT10LmdrdSgpLHA9dC5jPjA/dC5n
+SmYodCk6cyxvPXQuZ3hBKCk/dC5ndHAodCk6cyxuPXQuYSxtPXQuZixsPUMueEIuTmoobix0LmUsbSks
+az10LnIKbT1tPGs/dC5ndFAoKTpzCnJldHVybiBuZXcgUC5EbihyLHEscCxvLGwsbSxrPG4ubGVuZ3Ro
+P3QuZ0thKCk6cyl9LApaOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLmF9LAokaWlEOjF9ClAucWUucHJv
+dG90eXBlPXt9ClcucUUucHJvdG90eXBlPXt9ClcuR2gucHJvdG90eXBlPXsKWjpmdW5jdGlvbihhKXty
+ZXR1cm4gU3RyaW5nKGEpfSwKJGlHaDoxfQpXLmZZLnByb3RvdHlwZT17Clo6ZnVuY3Rpb24oYSl7cmV0
+dXJuIFN0cmluZyhhKX19ClcubkIucHJvdG90eXBlPXskaW5COjF9ClcuQXoucHJvdG90eXBlPXskaUF6
+OjF9ClcuUVAucHJvdG90eXBlPXskaVFQOjF9ClcubngucHJvdG90eXBlPXsKZ0E6ZnVuY3Rpb24oYSl7
+cmV0dXJuIGEubGVuZ3RofX0KVy5vSi5wcm90b3R5cGU9ewpnQTpmdW5jdGlvbihhKXtyZXR1cm4gYS5s
+ZW5ndGh9fQpXLmlkLnByb3RvdHlwZT17fQpXLlFGLnByb3RvdHlwZT17fQpXLk5oLnByb3RvdHlwZT17
+Clo6ZnVuY3Rpb24oYSl7cmV0dXJuIFN0cmluZyhhKX19ClcuSUIucHJvdG90eXBlPXsKWjpmdW5jdGlv
+bihhKXtyZXR1cm4iUmVjdGFuZ2xlICgiK0guZChhLmxlZnQpKyIsICIrSC5kKGEudG9wKSsiKSAiK0gu
+ZChhLndpZHRoKSsiIHggIitILmQoYS5oZWlnaHQpfSwKRE46ZnVuY3Rpb24oYSxiKXtpZihiPT1udWxs
+KXJldHVybiExCnJldHVybiB1Lk8uYihiKSYmYS5sZWZ0PT1iLmxlZnQmJmEudG9wPT1iLnRvcCYmYS53
+aWR0aD09Yi53aWR0aCYmYS5oZWlnaHQ9PWIuaGVpZ2h0fSwKZ2lPOmZ1bmN0aW9uKGEpe3JldHVybiBX
+LnJFKEouaGYoYS5sZWZ0KSxKLmhmKGEudG9wKSxKLmhmKGEud2lkdGgpLEouaGYoYS5oZWlnaHQpKX0s
+CiRpdG46MX0KVy5uNy5wcm90b3R5cGU9ewpnQTpmdW5jdGlvbihhKXtyZXR1cm4gYS5sZW5ndGh9fQpX
+Lnd6LnByb3RvdHlwZT17CmdBOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLmEubGVuZ3RofSwKcTpmdW5j
+dGlvbihhLGIpe3ZhciB0CkguV1koYikKdD10aGlzLmEKaWYoYjwwfHxiPj10Lmxlbmd0aClyZXR1cm4g
+SC5rKHQsYikKcmV0dXJuIHRoaXMuJHRpLmMuYSh0W2JdKX0sClk6ZnVuY3Rpb24oYSxiLGMpe3RoaXMu
+JHRpLmMuYShjKQp0aHJvdyBILmIoUC5MNCgiQ2Fubm90IG1vZGlmeSBsaXN0IikpfX0KVy5jdi5wcm90
+b3R5cGU9ewpnUWc6ZnVuY3Rpb24oYSl7cmV0dXJuIG5ldyBXLmk3KGEpfSwKZ1A6ZnVuY3Rpb24oYSl7
+cmV0dXJuIG5ldyBXLkk0KGEpfSwKc1A6ZnVuY3Rpb24oYSxiKXt2YXIgdAp1LlguYShiKQp0PXRoaXMu
+Z1AoYSkKdC5WMSgwKQp0LkZWKDAsYil9LApaOmZ1bmN0aW9uKGEpe3JldHVybiBhLmxvY2FsTmFtZX0s
+CkZGOmZ1bmN0aW9uKGEpe3ZhciB0PSEhYS5zY3JvbGxJbnRvVmlld0lmTmVlZGVkCmlmKHQpYS5zY3Jv
+bGxJbnRvVmlld0lmTmVlZGVkKCkKZWxzZSBhLnNjcm9sbEludG9WaWV3KCl9LApuejpmdW5jdGlvbihh
+LGIsYyxkLGUpe3ZhciB0LHM9dGhpcy5yNihhLGMsZCxlKQpzd2l0Y2goYi50b0xvd2VyQ2FzZSgpKXtj
+YXNlImJlZm9yZWJlZ2luIjphLnBhcmVudE5vZGUuaW5zZXJ0QmVmb3JlKHMsYSkKYnJlYWsKY2FzZSJh
+ZnRlcmJlZ2luIjp0PWEuY2hpbGROb2RlcwphLmluc2VydEJlZm9yZShzLHQubGVuZ3RoPjA/dFswXTpu
+dWxsKQpicmVhawpjYXNlImJlZm9yZWVuZCI6YS5hcHBlbmRDaGlsZChzKQpicmVhawpjYXNlImFmdGVy
+ZW5kIjp0PWEucGFyZW50Tm9kZQp0LnRvU3RyaW5nCnQuaW5zZXJ0QmVmb3JlKHMsYS5uZXh0U2libGlu
+ZykKYnJlYWsKZGVmYXVsdDpILnZoKFAueFkoIkludmFsaWQgcG9zaXRpb24gIitiKSl9fSwKcjY6ZnVu
+Y3Rpb24oYSxiLGMsZCl7dmFyIHQscyxyLHEKaWYoYz09bnVsbCl7aWYoZD09bnVsbCl7dD0kLmx0Cmlm
+KHQ9PW51bGwpe3Q9SC5WTShbXSx1LmspCnM9bmV3IFcudkQodCkKQy5ObS5pKHQsVy5UdyhudWxsKSkK
+Qy5ObS5pKHQsVy5CbCgpKQokLmx0PXMKZD1zfWVsc2UgZD10fXQ9JC5FVQppZih0PT1udWxsKXt0PW5l
+dyBXLktvKGQpCiQuRVU9dApjPXR9ZWxzZXt0LmE9ZApjPXR9fWVsc2UgaWYoZCE9bnVsbCl0aHJvdyBI
+LmIoUC54WSgidmFsaWRhdG9yIGNhbiBvbmx5IGJlIHBhc3NlZCBpZiB0cmVlU2FuaXRpemVyIGlzIG51
+bGwiKSkKaWYoJC54bz09bnVsbCl7dD1kb2N1bWVudApzPXQuaW1wbGVtZW50YXRpb24uY3JlYXRlSFRN
+TERvY3VtZW50KCIiKQokLnhvPXMKJC5CTz1zLmNyZWF0ZVJhbmdlKCkKcz0kLnhvLmNyZWF0ZUVsZW1l
+bnQoImJhc2UiKQp1LmNSLmEocykKcy5ocmVmPXQuYmFzZVVSSQokLnhvLmhlYWQuYXBwZW5kQ2hpbGQo
+cyl9dD0kLnhvCmlmKHQuYm9keT09bnVsbCl7cz10LmNyZWF0ZUVsZW1lbnQoImJvZHkiKQp0LmJvZHk9
+dS5pLmEocyl9dD0kLnhvCmlmKHUuaS5iKGEpKXt0PXQuYm9keQp0LnRvU3RyaW5nCnI9dH1lbHNle3Qu
+dG9TdHJpbmcKcj10LmNyZWF0ZUVsZW1lbnQoYS50YWdOYW1lKQokLnhvLmJvZHkuYXBwZW5kQ2hpbGQo
+cil9aWYoImNyZWF0ZUNvbnRleHR1YWxGcmFnbWVudCIgaW4gd2luZG93LlJhbmdlLnByb3RvdHlwZSYm
+IUMuTm0udGcoQy5TcSxhLnRhZ05hbWUpKXskLkJPLnNlbGVjdE5vZGVDb250ZW50cyhyKQpxPSQuQk8u
+Y3JlYXRlQ29udGV4dHVhbEZyYWdtZW50KGIpfWVsc2V7ci5pbm5lckhUTUw9YgpxPSQueG8uY3JlYXRl
+RG9jdW1lbnRGcmFnbWVudCgpCmZvcig7dD1yLmZpcnN0Q2hpbGQsdCE9bnVsbDspcS5hcHBlbmRDaGls
+ZCh0KX1pZihyIT09JC54by5ib2R5KUouTHQocikKYy5QbihxKQpkb2N1bWVudC5hZG9wdE5vZGUocSkK
+cmV0dXJuIHF9LApBSDpmdW5jdGlvbihhLGIsYyl7cmV0dXJuIHRoaXMucjYoYSxiLGMsbnVsbCl9LApz
+aGY6ZnVuY3Rpb24oYSxiKXt0aGlzLllDKGEsYil9LApwazpmdW5jdGlvbihhLGIsYyl7YS50ZXh0Q29u
+dGVudD1udWxsCmEuYXBwZW5kQ2hpbGQodGhpcy5yNihhLGIsbnVsbCxjKSl9LApZQzpmdW5jdGlvbihh
+LGIpe3JldHVybiB0aGlzLnBrKGEsYixudWxsKX0sCmduczpmdW5jdGlvbihhKXtyZXR1cm4gYS50YWdO
+YW1lfSwKZ1ZsOmZ1bmN0aW9uKGEpe3JldHVybiBuZXcgVy5ldShhLCJjbGljayIsITEsdS5RKX0sCiRp
+Y3Y6MX0KVy5Ddi5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXtyZXR1cm4gdS5oLmIodS5BLmEoYSkp
+fSwKJFM6MjV9ClcuZWEucHJvdG90eXBlPXskaWVhOjF9ClcuRDAucHJvdG90eXBlPXsKT246ZnVuY3Rp
+b24oYSxiLGMsZCl7dS5VLmEoYykKaWYoYyE9bnVsbCl0aGlzLnYoYSxiLGMsZCl9LApCOmZ1bmN0aW9u
+KGEsYixjKXtyZXR1cm4gdGhpcy5PbihhLGIsYyxudWxsKX0sCnY6ZnVuY3Rpb24oYSxiLGMsZCl7cmV0
+dXJuIGEuYWRkRXZlbnRMaXN0ZW5lcihiLEgudFIodS5VLmEoYyksMSksZCl9LAokaUQwOjF9ClcuVDUu
+cHJvdG90eXBlPXskaVQ1OjF9ClcuaDQucHJvdG90eXBlPXsKZ0E6ZnVuY3Rpb24oYSl7cmV0dXJuIGEu
+bGVuZ3RofX0KVy5ici5wcm90b3R5cGU9ewpnQTpmdW5jdGlvbihhKXtyZXR1cm4gYS5sZW5ndGh9fQpX
+LlZiLnByb3RvdHlwZT17fQpXLmZKLnByb3RvdHlwZT17CmVvOmZ1bmN0aW9uKGEsYixjLGQpe3JldHVy
+biBhLm9wZW4oYixjLCEwKX0sCiRpZko6MX0KVy5iVS5wcm90b3R5cGU9ewokMjpmdW5jdGlvbihhLGIp
+e3RoaXMuYS5zZXRSZXF1ZXN0SGVhZGVyKEguYyhhKSxILmMoYikpfSwKJFM6OH0KVy5oSC5wcm90b3R5
+cGU9ewokMTpmdW5jdGlvbihhKXt2YXIgdCxzLHIscSxwCnUucC5hKGEpCnQ9dGhpcy5hCnM9dC5zdGF0
+dXMKaWYodHlwZW9mIHMhPT0ibnVtYmVyIilyZXR1cm4gcy50QigpCnI9cz49MjAwJiZzPDMwMApxPXM+
+MzA3JiZzPDQwMApzPXJ8fHM9PT0wfHxzPT09MzA0fHxxCnA9dGhpcy5iCmlmKHMpcC5hTSgwLHQpCmVs
+c2UgcC5wbShhKX0sCiRTOjE0fQpXLndhLnByb3RvdHlwZT17fQpXLlNnLnByb3RvdHlwZT17JGlTZzox
+fQpXLnU4LnByb3RvdHlwZT17CmdEcjpmdW5jdGlvbihhKXtpZigib3JpZ2luIiBpbiBhKXJldHVybiBh
+Lm9yaWdpbgpyZXR1cm4gSC5kKGEucHJvdG9jb2wpKyIvLyIrSC5kKGEuaG9zdCl9LApaOmZ1bmN0aW9u
+KGEpe3JldHVybiBTdHJpbmcoYSl9LAokaXU4OjF9ClcuT0sucHJvdG90eXBlPXskaU9LOjF9ClcuZTcu
+cHJvdG90eXBlPXsKZ3I4OmZ1bmN0aW9uKGEpe3ZhciB0PXRoaXMuYSxzPXQuY2hpbGROb2Rlcy5sZW5n
+dGgKaWYocz09PTApdGhyb3cgSC5iKFAuUFYoIk5vIGVsZW1lbnRzIikpCmlmKHM+MSl0aHJvdyBILmIo
+UC5QVigiTW9yZSB0aGFuIG9uZSBlbGVtZW50IikpCnJldHVybiB0LmZpcnN0Q2hpbGR9LApGVjpmdW5j
+dGlvbihhLGIpe3ZhciB0LHMscixxLHAKdS5laC5hKGIpCnQ9Yi5hCnM9dGhpcy5hCmlmKHQhPT1zKWZv
+cihyPXQuY2hpbGROb2Rlcy5sZW5ndGgscT0wO3E8cjsrK3Epe3A9dC5maXJzdENoaWxkCnAudG9TdHJp
+bmcKcy5hcHBlbmRDaGlsZChwKX1yZXR1cm59LApZOmZ1bmN0aW9uKGEsYixjKXt2YXIgdCxzCnUuQS5h
+KGMpCnQ9dGhpcy5hCnM9dC5jaGlsZE5vZGVzCmlmKGI8MHx8Yj49cy5sZW5ndGgpcmV0dXJuIEguayhz
+LGIpCnQucmVwbGFjZUNoaWxkKGMsc1tiXSl9LApna3o6ZnVuY3Rpb24oYSl7dmFyIHQ9dGhpcy5hLmNo
+aWxkTm9kZXMKcmV0dXJuIG5ldyBXLlc5KHQsdC5sZW5ndGgsSC5xKHQpLkMoIlc5PEdtLkU+IikpfSwK
+Z0E6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuYS5jaGlsZE5vZGVzLmxlbmd0aH0sCnE6ZnVuY3Rpb24o
+YSxiKXt2YXIgdApILldZKGIpCnQ9dGhpcy5hLmNoaWxkTm9kZXMKaWYoYjwwfHxiPj10Lmxlbmd0aCly
+ZXR1cm4gSC5rKHQsYikKcmV0dXJuIHRbYl19fQpXLnVILnByb3RvdHlwZT17CndnOmZ1bmN0aW9uKGEp
+e3ZhciB0PWEucGFyZW50Tm9kZQppZih0IT1udWxsKXQucmVtb3ZlQ2hpbGQoYSl9LApENDpmdW5jdGlv
+bihhKXt2YXIgdApmb3IoO3Q9YS5maXJzdENoaWxkLHQhPW51bGw7KWEucmVtb3ZlQ2hpbGQodCl9LApa
+OmZ1bmN0aW9uKGEpe3ZhciB0PWEubm9kZVZhbHVlCnJldHVybiB0PT1udWxsP3RoaXMuVShhKTp0fSwK
+JGl1SDoxfQpXLkJILnByb3RvdHlwZT17CmdBOmZ1bmN0aW9uKGEpe3JldHVybiBhLmxlbmd0aH0sCnE6
+ZnVuY3Rpb24oYSxiKXtILldZKGIpCmlmKGI+Pj4wIT09Ynx8Yj49YS5sZW5ndGgpdGhyb3cgSC5iKFAu
+dChiLGEsbnVsbCxudWxsLG51bGwpKQpyZXR1cm4gYVtiXX0sClk6ZnVuY3Rpb24oYSxiLGMpe3UuQS5h
+KGMpCnRocm93IEguYihQLkw0KCJDYW5ub3QgYXNzaWduIGVsZW1lbnQgb2YgaW1tdXRhYmxlIExpc3Qu
+IikpfSwKRTpmdW5jdGlvbihhLGIpe2lmKGI8MHx8Yj49YS5sZW5ndGgpcmV0dXJuIEguayhhLGIpCnJl
+dHVybiBhW2JdfSwKJGliUToxLAokaVhqOjEsCiRpY1g6MSwKJGl6TToxfQpXLlNOLnByb3RvdHlwZT17
+fQpXLmV3LnByb3RvdHlwZT17JGlldzoxfQpXLmxwLnByb3RvdHlwZT17CmdBOmZ1bmN0aW9uKGEpe3Jl
+dHVybiBhLmxlbmd0aH19ClcuVGIucHJvdG90eXBlPXsKcjY6ZnVuY3Rpb24oYSxiLGMsZCl7dmFyIHQs
+cwppZigiY3JlYXRlQ29udGV4dHVhbEZyYWdtZW50IiBpbiB3aW5kb3cuUmFuZ2UucHJvdG90eXBlKXJl
+dHVybiB0aGlzLkRXKGEsYixjLGQpCnQ9Vy5VOSgiPHRhYmxlPiIrSC5kKGIpKyI8L3RhYmxlPiIsYyxk
+KQpzPWRvY3VtZW50LmNyZWF0ZURvY3VtZW50RnJhZ21lbnQoKQpzLnRvU3RyaW5nCnQudG9TdHJpbmcK
+bmV3IFcuZTcocykuRlYoMCxuZXcgVy5lNyh0KSkKcmV0dXJuIHN9fQpXLkl2LnByb3RvdHlwZT17CnI2
+OmZ1bmN0aW9uKGEsYixjLGQpe3ZhciB0LHMscixxCmlmKCJjcmVhdGVDb250ZXh0dWFsRnJhZ21lbnQi
+IGluIHdpbmRvdy5SYW5nZS5wcm90b3R5cGUpcmV0dXJuIHRoaXMuRFcoYSxiLGMsZCkKdD1kb2N1bWVu
+dApzPXQuY3JlYXRlRG9jdW1lbnRGcmFnbWVudCgpCnQ9Qy5JZS5yNih0LmNyZWF0ZUVsZW1lbnQoInRh
+YmxlIiksYixjLGQpCnQudG9TdHJpbmcKdD1uZXcgVy5lNyh0KQpyPXQuZ3I4KHQpCnIudG9TdHJpbmcK
+dD1uZXcgVy5lNyhyKQpxPXQuZ3I4KHQpCnMudG9TdHJpbmcKcS50b1N0cmluZwpuZXcgVy5lNyhzKS5G
+VigwLG5ldyBXLmU3KHEpKQpyZXR1cm4gc319ClcuV1AucHJvdG90eXBlPXsKcjY6ZnVuY3Rpb24oYSxi
+LGMsZCl7dmFyIHQscyxyCmlmKCJjcmVhdGVDb250ZXh0dWFsRnJhZ21lbnQiIGluIHdpbmRvdy5SYW5n
+ZS5wcm90b3R5cGUpcmV0dXJuIHRoaXMuRFcoYSxiLGMsZCkKdD1kb2N1bWVudApzPXQuY3JlYXRlRG9j
+dW1lbnRGcmFnbWVudCgpCnQ9Qy5JZS5yNih0LmNyZWF0ZUVsZW1lbnQoInRhYmxlIiksYixjLGQpCnQu
+dG9TdHJpbmcKdD1uZXcgVy5lNyh0KQpyPXQuZ3I4KHQpCnMudG9TdHJpbmcKci50b1N0cmluZwpuZXcg
+Vy5lNyhzKS5GVigwLG5ldyBXLmU3KHIpKQpyZXR1cm4gc319ClcueVkucHJvdG90eXBlPXsKcGs6ZnVu
+Y3Rpb24oYSxiLGMpe3ZhciB0LHMKYS50ZXh0Q29udGVudD1udWxsCnQ9YS5jb250ZW50CnQudG9TdHJp
+bmcKSi5iVCh0KQpzPXRoaXMucjYoYSxiLG51bGwsYykKYS5jb250ZW50LmFwcGVuZENoaWxkKHMpfSwK
+WUM6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gdGhpcy5wayhhLGIsbnVsbCl9LAokaXlZOjF9ClcudzYucHJv
+dG90eXBlPXt9ClcuSzUucHJvdG90eXBlPXsKUG86ZnVuY3Rpb24oYSxiLGMpe3ZhciB0PVcuUDEoYS5v
+cGVuKGIsYykpCnJldHVybiB0fSwKZ21XOmZ1bmN0aW9uKGEpe3JldHVybiBhLmxvY2F0aW9ufSwKJGlL
+NToxLAokaXY2OjF9ClcuQ20ucHJvdG90eXBlPXskaUNtOjF9ClcuQ1EucHJvdG90eXBlPXskaUNROjF9
+ClcudzQucHJvdG90eXBlPXsKWjpmdW5jdGlvbihhKXtyZXR1cm4iUmVjdGFuZ2xlICgiK0guZChhLmxl
+ZnQpKyIsICIrSC5kKGEudG9wKSsiKSAiK0guZChhLndpZHRoKSsiIHggIitILmQoYS5oZWlnaHQpfSwK
+RE46ZnVuY3Rpb24oYSxiKXtpZihiPT1udWxsKXJldHVybiExCnJldHVybiB1Lk8uYihiKSYmYS5sZWZ0
+PT1iLmxlZnQmJmEudG9wPT1iLnRvcCYmYS53aWR0aD09Yi53aWR0aCYmYS5oZWlnaHQ9PWIuaGVpZ2h0
+fSwKZ2lPOmZ1bmN0aW9uKGEpe3JldHVybiBXLnJFKEouaGYoYS5sZWZ0KSxKLmhmKGEudG9wKSxKLmhm
+KGEud2lkdGgpLEouaGYoYS5oZWlnaHQpKX19ClcucmgucHJvdG90eXBlPXsKZ0E6ZnVuY3Rpb24oYSl7
+cmV0dXJuIGEubGVuZ3RofSwKcTpmdW5jdGlvbihhLGIpe0guV1koYikKaWYoYj4+PjAhPT1ifHxiPj1h
+Lmxlbmd0aCl0aHJvdyBILmIoUC50KGIsYSxudWxsLG51bGwsbnVsbCkpCnJldHVybiBhW2JdfSwKWTpm
+dW5jdGlvbihhLGIsYyl7dS5BLmEoYykKdGhyb3cgSC5iKFAuTDQoIkNhbm5vdCBhc3NpZ24gZWxlbWVu
+dCBvZiBpbW11dGFibGUgTGlzdC4iKSl9LApFOmZ1bmN0aW9uKGEsYil7aWYoYjwwfHxiPj1hLmxlbmd0
+aClyZXR1cm4gSC5rKGEsYikKcmV0dXJuIGFbYl19LAokaWJROjEsCiRpWGo6MSwKJGljWDoxLAokaXpN
+OjF9ClcuY2YucHJvdG90eXBlPXsKSzpmdW5jdGlvbihhLGIpe3ZhciB0LHMscixxLHAKdS5lQS5hKGIp
+CmZvcih0PXRoaXMuZ1YoKSxzPXQubGVuZ3RoLHI9dGhpcy5hLHE9MDtxPHQubGVuZ3RoO3QubGVuZ3Ro
+PT09c3x8KDAsSC5saykodCksKytxKXtwPXRbcV0KYi4kMihwLHIuZ2V0QXR0cmlidXRlKHApKX19LApn
+VjpmdW5jdGlvbigpe3ZhciB0LHMscixxLHA9dGhpcy5hLmF0dHJpYnV0ZXMsbz1ILlZNKFtdLHUucykK
+Zm9yKHQ9cC5sZW5ndGgscz11Lmg5LHI9MDtyPHQ7KytyKXtpZihyPj1wLmxlbmd0aClyZXR1cm4gSC5r
+KHAscikKcT1zLmEocFtyXSkKaWYocS5uYW1lc3BhY2VVUkk9PW51bGwpQy5ObS5pKG8scS5uYW1lKX1y
+ZXR1cm4gb319ClcuaTcucHJvdG90eXBlPXsKeDQ6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuYS5oYXNB
+dHRyaWJ1dGUoYSl9LApxOmZ1bmN0aW9uKGEsYil7cmV0dXJuIHRoaXMuYS5nZXRBdHRyaWJ1dGUoSC5j
+KGIpKX0sClk6ZnVuY3Rpb24oYSxiLGMpe3RoaXMuYS5zZXRBdHRyaWJ1dGUoYixjKX0sCmdBOmZ1bmN0
+aW9uKGEpe3JldHVybiB0aGlzLmdWKCkubGVuZ3RofX0KVy5TeS5wcm90b3R5cGU9ewp4NDpmdW5jdGlv
+bihhKXtyZXR1cm4gdGhpcy5hLmEuaGFzQXR0cmlidXRlKCJkYXRhLSIrdGhpcy5PKGEpKX0sCnE6ZnVu
+Y3Rpb24oYSxiKXtyZXR1cm4gdGhpcy5hLmEuZ2V0QXR0cmlidXRlKCJkYXRhLSIrdGhpcy5PKEguYyhi
+KSkpfSwKWTpmdW5jdGlvbihhLGIsYyl7dGhpcy5hLmEuc2V0QXR0cmlidXRlKCJkYXRhLSIrdGhpcy5P
+KGIpLGMpfSwKSzpmdW5jdGlvbihhLGIpe3RoaXMuYS5LKDAsbmV3IFcuS1ModGhpcyx1LmVBLmEoYikp
+KX0sCmdWOmZ1bmN0aW9uKCl7dmFyIHQ9SC5WTShbXSx1LnMpCnRoaXMuYS5LKDAsbmV3IFcuQTModGhp
+cyx0KSkKcmV0dXJuIHR9LApnQTpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5nVigpLmxlbmd0aH0sCms6
+ZnVuY3Rpb24oYSl7dmFyIHQscyxyPUguVk0oYS5zcGxpdCgiLSIpLHUucykKZm9yKHQ9MTt0PHIubGVu
+Z3RoOysrdCl7cz1yW3RdCmlmKHMubGVuZ3RoPjApQy5ObS5ZKHIsdCxzWzBdLnRvVXBwZXJDYXNlKCkr
+Si5LVihzLDEpKX1yZXR1cm4gQy5ObS56VihyLCIiKX0sCk86ZnVuY3Rpb24oYSl7dmFyIHQscyxyLHEs
+cApmb3IodD1hLmxlbmd0aCxzPTAscj0iIjtzPHQ7KytzKXtxPWFbc10KcD1xLnRvTG93ZXJDYXNlKCkK
+cj0ocSE9PXAmJnM+MD9yKyItIjpyKStwfXJldHVybiByLmNoYXJDb2RlQXQoMCk9PTA/cjpyfX0KVy5L
+Uy5wcm90b3R5cGU9ewokMjpmdW5jdGlvbihhLGIpe2lmKEouclkoYSkubihhLCJkYXRhLSIpKXRoaXMu
+Yi4kMih0aGlzLmEuayhDLnhCLkcoYSw1KSksYil9LAokUzo4fQpXLkEzLnByb3RvdHlwZT17CiQyOmZ1
+bmN0aW9uKGEsYil7aWYoSi5yWShhKS5uKGEsImRhdGEtIikpQy5ObS5pKHRoaXMuYix0aGlzLmEuayhD
+LnhCLkcoYSw1KSkpfSwKJFM6OH0KVy5JNC5wcm90b3R5cGU9ewp3OmZ1bmN0aW9uKCl7dmFyIHQscyxy
+LHEscD1QLkxzKHUuTikKZm9yKHQ9dGhpcy5hLmNsYXNzTmFtZS5zcGxpdCgiICIpLHM9dC5sZW5ndGgs
+cj0wO3I8czsrK3Ipe3E9Si5UMCh0W3JdKQppZihxLmxlbmd0aCE9PTApcC5pKDAscSl9cmV0dXJuIHB9
+LApwOmZ1bmN0aW9uKGEpe3RoaXMuYS5jbGFzc05hbWU9dS5DLmEoYSkuelYoMCwiICIpfSwKZ0E6ZnVu
+Y3Rpb24oYSl7cmV0dXJuIHRoaXMuYS5jbGFzc0xpc3QubGVuZ3RofSwKVjE6ZnVuY3Rpb24oYSl7dGhp
+cy5hLmNsYXNzTmFtZT0iIn0sCnRnOmZ1bmN0aW9uKGEsYil7dmFyIHQ9dGhpcy5hLmNsYXNzTGlzdC5j
+b250YWlucyhiKQpyZXR1cm4gdH0sCmk6ZnVuY3Rpb24oYSxiKXt2YXIgdD10aGlzLmEuY2xhc3NMaXN0
+LHM9dC5jb250YWlucyhiKQp0LmFkZChiKQpyZXR1cm4hc30sClI6ZnVuY3Rpb24oYSxiKXt2YXIgdD10
+aGlzLmEuY2xhc3NMaXN0LHM9dC5jb250YWlucyhiKQp0LnJlbW92ZShiKQpyZXR1cm4gc30sCkZWOmZ1
+bmN0aW9uKGEsYil7Vy5UTih0aGlzLmEsdS5YLmEoYikpfX0KVy5Gay5wcm90b3R5cGU9e30KVy5STy5w
+cm90b3R5cGU9e30KVy5ldS5wcm90b3R5cGU9e30KVy54Qy5wcm90b3R5cGU9e30KVy52Ti5wcm90b3R5
+cGU9ewokMTpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5hLiQxKHUuQi5hKGEpKX0sCiRTOjI4fQpXLkpR
+LnByb3RvdHlwZT17CkNZOmZ1bmN0aW9uKGEpe3ZhciB0CmlmKCQub3IuYT09PTApe2Zvcih0PTA7dDwy
+NjI7Kyt0KSQub3IuWSgwLEMuY21bdF0sVy5wUygpKQpmb3IodD0wO3Q8MTI7Kyt0KSQub3IuWSgwLEMu
+QklbdF0sVy5WNCgpKX19LAppMDpmdW5jdGlvbihhKXtyZXR1cm4gJC5BTigpLnRnKDAsVy5yUyhhKSl9
+LApFYjpmdW5jdGlvbihhLGIsYyl7dmFyIHQ9JC5vci5xKDAsSC5kKFcuclMoYSkpKyI6OiIrYikKaWYo
+dD09bnVsbCl0PSQub3IucSgwLCIqOjoiK2IpCmlmKHQ9PW51bGwpcmV0dXJuITEKcmV0dXJuIEguRTko
+dC4kNChhLGIsYyx0aGlzKSl9LAokaWtGOjF9ClcuR20ucHJvdG90eXBlPXsKZ2t6OmZ1bmN0aW9uKGEp
+e3JldHVybiBuZXcgVy5XOShhLHRoaXMuZ0EoYSksSC5xKGEpLkMoIlc5PEdtLkU+IikpfX0KVy52RC5w
+cm90b3R5cGU9ewppMDpmdW5jdGlvbihhKXtyZXR1cm4gQy5ObS5Wcih0aGlzLmEsbmV3IFcuVXYoYSkp
+fSwKRWI6ZnVuY3Rpb24oYSxiLGMpe3JldHVybiBDLk5tLlZyKHRoaXMuYSxuZXcgVy5FZyhhLGIsYykp
+fSwKJGlrRjoxfQpXLlV2LnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe3JldHVybiB1LmUuYShhKS5p
+MCh0aGlzLmEpfSwKJFM6MTV9ClcuRWcucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7cmV0dXJuIHUu
+ZS5hKGEpLkViKHRoaXMuYSx0aGlzLmIsdGhpcy5jKX0sCiRTOjE1fQpXLm02LnByb3RvdHlwZT17CkNZ
+OmZ1bmN0aW9uKGEsYixjLGQpe3ZhciB0LHMscgp0aGlzLmEuRlYoMCxjKQp0PWIuZXYoMCxuZXcgVy5F
+bygpKQpzPWIuZXYoMCxuZXcgVy5XaygpKQp0aGlzLmIuRlYoMCx0KQpyPXRoaXMuYwpyLkZWKDAsQy54
+RCkKci5GVigwLHMpfSwKaTA6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuYS50ZygwLFcuclMoYSkpfSwK
+RWI6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0PXRoaXMscz1XLnJTKGEpLHI9dC5jCmlmKHIudGcoMCxILmQo
+cykrIjo6IitiKSlyZXR1cm4gdC5kLkR0KGMpCmVsc2UgaWYoci50ZygwLCIqOjoiK2IpKXJldHVybiB0
+LmQuRHQoYykKZWxzZXtyPXQuYgppZihyLnRnKDAsSC5kKHMpKyI6OiIrYikpcmV0dXJuITAKZWxzZSBp
+ZihyLnRnKDAsIio6OiIrYikpcmV0dXJuITAKZWxzZSBpZihyLnRnKDAsSC5kKHMpKyI6OioiKSlyZXR1
+cm4hMAplbHNlIGlmKHIudGcoMCwiKjo6KiIpKXJldHVybiEwfXJldHVybiExfSwKJGlrRjoxfQpXLkVv
+LnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe3JldHVybiFDLk5tLnRnKEMuQkksSC5jKGEpKX0sCiRT
+Ojd9ClcuV2sucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7cmV0dXJuIEMuTm0udGcoQy5CSSxILmMo
+YSkpfSwKJFM6N30KVy5jdC5wcm90b3R5cGU9ewpFYjpmdW5jdGlvbihhLGIsYyl7aWYodGhpcy5qRihh
+LGIsYykpcmV0dXJuITAKaWYoYj09PSJ0ZW1wbGF0ZSImJmM9PT0iIilyZXR1cm4hMAppZihhLmdldEF0
+dHJpYnV0ZSgidGVtcGxhdGUiKT09PSIiKXJldHVybiB0aGlzLmUudGcoMCxiKQpyZXR1cm4hMX19Clcu
+SUEucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7cmV0dXJuIlRFTVBMQVRFOjoiK0guZChILmMoYSkp
+fSwKJFM6NH0KVy5Pdy5wcm90b3R5cGU9ewppMDpmdW5jdGlvbihhKXt2YXIgdAppZih1LmV3LmIoYSkp
+cmV0dXJuITEKdD11Lmc3LmIoYSkKaWYodCYmVy5yUyhhKT09PSJmb3JlaWduT2JqZWN0IilyZXR1cm4h
+MQppZih0KXJldHVybiEwCnJldHVybiExfSwKRWI6ZnVuY3Rpb24oYSxiLGMpe2lmKGI9PT0iaXMifHxD
+LnhCLm4oYiwib24iKSlyZXR1cm4hMQpyZXR1cm4gdGhpcy5pMChhKX0sCiRpa0Y6MX0KVy5XOS5wcm90
+b3R5cGU9ewpGOmZ1bmN0aW9uKCl7dmFyIHQ9dGhpcyxzPXQuYysxLHI9dC5iCmlmKHM8cil7dC5zTShK
+Lng5KHQuYSxzKSkKdC5jPXMKcmV0dXJuITB9dC5zTShudWxsKQp0LmM9cgpyZXR1cm4hMX0sCmdsOmZ1
+bmN0aW9uKCl7cmV0dXJuIHRoaXMuZH0sCnNNOmZ1bmN0aW9uKGEpe3RoaXMuZD10aGlzLiR0aS5jLmEo
+YSl9LAokaUFuOjF9ClcuZFcucHJvdG90eXBlPXsKZ21XOmZ1bmN0aW9uKGEpe3JldHVybiBXLkhIKHRo
+aXMuYS5sb2NhdGlvbil9LAokaUQwOjEsCiRpdjY6MX0KVy5GYi5wcm90b3R5cGU9e30KVy5rRi5wcm90
+b3R5cGU9e30KVy5tay5wcm90b3R5cGU9eyRpeTA6MX0KVy5Lby5wcm90b3R5cGU9ewpQbjpmdW5jdGlv
+bihhKXt2YXIgdD10aGlzLHM9bmV3IFcuZm0odCkKdC5iPSExCnMuJDIoYSxudWxsKQpmb3IoO3QuYjsp
+e3QuYj0hMQpzLiQyKGEsbnVsbCl9fSwKRVA6ZnVuY3Rpb24oYSxiKXt2YXIgdD10aGlzLmI9ITAKaWYo
+YiE9bnVsbD9iIT09YS5wYXJlbnROb2RlOnQpSi5MdChhKQplbHNlIGIucmVtb3ZlQ2hpbGQoYSl9LApJ
+NDpmdW5jdGlvbihhLGIpe3ZhciB0LHMscixxLHAsbz0hMCxuPW51bGwsbT1udWxsCnRyeXtuPUouaWco
+YSkKbT1uLmEuZ2V0QXR0cmlidXRlKCJpcyIpCnUuaC5hKGEpCnQ9ZnVuY3Rpb24oYyl7aWYoIShjLmF0
+dHJpYnV0ZXMgaW5zdGFuY2VvZiBOYW1lZE5vZGVNYXApKXJldHVybiB0cnVlCmlmKGMuaWQ9PSdsYXN0
+Q2hpbGQnfHxjLm5hbWU9PSdsYXN0Q2hpbGQnfHxjLmlkPT0ncHJldmlvdXNTaWJsaW5nJ3x8Yy5uYW1l
+PT0ncHJldmlvdXNTaWJsaW5nJ3x8Yy5pZD09J2NoaWxkcmVuJ3x8Yy5uYW1lPT0nY2hpbGRyZW4nKXJl
+dHVybiB0cnVlCnZhciBsPWMuY2hpbGROb2RlcwppZihjLmxhc3RDaGlsZCYmYy5sYXN0Q2hpbGQhPT1s
+W2wubGVuZ3RoLTFdKXJldHVybiB0cnVlCmlmKGMuY2hpbGRyZW4paWYoIShjLmNoaWxkcmVuIGluc3Rh
+bmNlb2YgSFRNTENvbGxlY3Rpb258fGMuY2hpbGRyZW4gaW5zdGFuY2VvZiBOb2RlTGlzdCkpcmV0dXJu
+IHRydWUKdmFyIGs9MAppZihjLmNoaWxkcmVuKWs9Yy5jaGlsZHJlbi5sZW5ndGgKZm9yKHZhciBqPTA7
+ajxrO2orKyl7dmFyIGk9Yy5jaGlsZHJlbltqXQppZihpLmlkPT0nYXR0cmlidXRlcyd8fGkubmFtZT09
+J2F0dHJpYnV0ZXMnfHxpLmlkPT0nbGFzdENoaWxkJ3x8aS5uYW1lPT0nbGFzdENoaWxkJ3x8aS5pZD09
+J3ByZXZpb3VzU2libGluZyd8fGkubmFtZT09J3ByZXZpb3VzU2libGluZyd8fGkuaWQ9PSdjaGlsZHJl
+bid8fGkubmFtZT09J2NoaWxkcmVuJylyZXR1cm4gdHJ1ZX1yZXR1cm4gZmFsc2V9KGEpCm89SC5vVCh0
+KT8hMDohKGEuYXR0cmlidXRlcyBpbnN0YW5jZW9mIE5hbWVkTm9kZU1hcCl9Y2F0Y2gocSl7SC5SdShx
+KX1zPSJlbGVtZW50IHVucHJpbnRhYmxlIgp0cnl7cz1KLkFjKGEpfWNhdGNoKHEpe0guUnUocSl9dHJ5
+e3I9Vy5yUyhhKQp0aGlzLmtSKHUuaC5hKGEpLGIsbyxzLHIsdS5HLmEobiksSC5jKG0pKX1jYXRjaChx
+KXtpZihILlJ1KHEpIGluc3RhbmNlb2YgUC5BVCl0aHJvdyBxCmVsc2V7dGhpcy5FUChhLGIpCndpbmRv
+dwpwPSJSZW1vdmluZyBjb3JydXB0ZWQgZWxlbWVudCAiK0guZChzKQppZih0eXBlb2YgY29uc29sZSE9
+InVuZGVmaW5lZCIpd2luZG93LmNvbnNvbGUud2FybihwKX19fSwKa1I6ZnVuY3Rpb24oYSxiLGMsZCxl
+LGYsZyl7dmFyIHQscyxyLHEscCxvLG49dGhpcwppZihjKXtuLkVQKGEsYikKd2luZG93CnQ9IlJlbW92
+aW5nIGVsZW1lbnQgZHVlIHRvIGNvcnJ1cHRlZCBhdHRyaWJ1dGVzIG9uIDwiK2QrIj4iCmlmKHR5cGVv
+ZiBjb25zb2xlIT0idW5kZWZpbmVkIil3aW5kb3cuY29uc29sZS53YXJuKHQpCnJldHVybn1pZighbi5h
+LmkwKGEpKXtuLkVQKGEsYikKd2luZG93CnQ9IlJlbW92aW5nIGRpc2FsbG93ZWQgZWxlbWVudCA8IitI
+LmQoZSkrIj4gZnJvbSAiK0guZChiKQppZih0eXBlb2YgY29uc29sZSE9InVuZGVmaW5lZCIpd2luZG93
+LmNvbnNvbGUud2Fybih0KQpyZXR1cm59aWYoZyE9bnVsbClpZighbi5hLkViKGEsImlzIixnKSl7bi5F
+UChhLGIpCndpbmRvdwp0PSJSZW1vdmluZyBkaXNhbGxvd2VkIHR5cGUgZXh0ZW5zaW9uIDwiK0guZChl
+KSsnIGlzPSInK2crJyI+JwppZih0eXBlb2YgY29uc29sZSE9InVuZGVmaW5lZCIpd2luZG93LmNvbnNv
+bGUud2Fybih0KQpyZXR1cm59dD1mLmdWKCkKcz1ILlZNKHQuc2xpY2UoMCksSC50Nih0KS5DKCJqZDwx
+PiIpKQpmb3Iocj1mLmdWKCkubGVuZ3RoLTEsdD1mLmE7cj49MDstLXIpe2lmKHI+PXMubGVuZ3RoKXJl
+dHVybiBILmsocyxyKQpxPXNbcl0KcD1uLmEKbz1KLmNIKHEpCkguYyhxKQppZighcC5FYihhLG8sdC5n
+ZXRBdHRyaWJ1dGUocSkpKXt3aW5kb3cKcD0iUmVtb3ZpbmcgZGlzYWxsb3dlZCBhdHRyaWJ1dGUgPCIr
+SC5kKGUpKyIgIitxKyc9IicrSC5kKHQuZ2V0QXR0cmlidXRlKHEpKSsnIj4nCmlmKHR5cGVvZiBjb25z
+b2xlIT0idW5kZWZpbmVkIil3aW5kb3cuY29uc29sZS53YXJuKHApCnQucmVtb3ZlQXR0cmlidXRlKHEp
+fX1pZih1LmFXLmIoYSkpbi5QbihhLmNvbnRlbnQpfSwKJGlvbjoxfQpXLmZtLnByb3RvdHlwZT17CiQy
+OmZ1bmN0aW9uKGEsYil7dmFyIHQscyxyLHEscCxvLG49dGhpcy5hCnN3aXRjaChhLm5vZGVUeXBlKXtj
+YXNlIDE6bi5JNChhLGIpCmJyZWFrCmNhc2UgODpjYXNlIDExOmNhc2UgMzpjYXNlIDQ6YnJlYWsKZGVm
+YXVsdDpuLkVQKGEsYil9dD1hLmxhc3RDaGlsZApmb3Iocj11LkE7bnVsbCE9dDspe3M9bnVsbAp0cnl7
+cz10LnByZXZpb3VzU2libGluZwppZihzIT1udWxsKXtxPXMubmV4dFNpYmxpbmcKcD10CnA9cT09bnVs
+bD9wIT1udWxsOnEhPT1wCnE9cH1lbHNlIHE9ITEKaWYocSl7cT1QLlBWKCJDb3JydXB0IEhUTUwiKQp0
+aHJvdyBILmIocSl9fWNhdGNoKG8pe0guUnUobykKcT1yLmEodCkKbi5iPSEwCnA9cS5wYXJlbnROb2Rl
+CnA9YT09bnVsbD9wIT1udWxsOmEhPT1wCmlmKHApe3A9cS5wYXJlbnROb2RlCmlmKHAhPW51bGwpcC5y
+ZW1vdmVDaGlsZChxKX1lbHNlIGEucmVtb3ZlQ2hpbGQocSkKdD1udWxsCnM9YS5sYXN0Q2hpbGR9aWYo
+dCE9bnVsbCl0aGlzLiQyKHQsYSkKdD1zfX0sCiRTOjMxfQpXLkxlLnByb3RvdHlwZT17fQpXLks3LnBy
+b3RvdHlwZT17fQpXLnJCLnByb3RvdHlwZT17fQpXLlhXLnByb3RvdHlwZT17fQpXLm9hLnByb3RvdHlw
+ZT17fQpQLmlKLnByb3RvdHlwZT17ClZIOmZ1bmN0aW9uKGEpe3ZhciB0LHM9dGhpcy5hLHI9cy5sZW5n
+dGgKZm9yKHQ9MDt0PHI7Kyt0KWlmKHNbdF09PT1hKXJldHVybiB0CkMuTm0uaShzLGEpCkMuTm0uaSh0
+aGlzLmIsbnVsbCkKcmV0dXJuIHJ9LApQdjpmdW5jdGlvbihhKXt2YXIgdCxzLHIscT10aGlzLHA9e30K
+aWYoYT09bnVsbClyZXR1cm4gYQppZihILnJRKGEpKXJldHVybiBhCmlmKHR5cGVvZiBhPT0ibnVtYmVy
+IilyZXR1cm4gYQppZih0eXBlb2YgYT09InN0cmluZyIpcmV0dXJuIGEKaWYoYSBpbnN0YW5jZW9mIFAu
+aVApcmV0dXJuIG5ldyBEYXRlKGEuYSkKaWYodS5mdi5iKGEpKXRocm93IEguYihQLm4oInN0cnVjdHVy
+ZWQgY2xvbmUgb2YgUmVnRXhwIikpCmlmKHUuYzguYihhKSlyZXR1cm4gYQppZih1LmQuYihhKSlyZXR1
+cm4gYQppZih1LkkuYihhKSlyZXR1cm4gYQp0PXUuZEQuYihhKXx8ITEKaWYodClyZXR1cm4gYQppZih1
+LkcuYihhKSl7cz1xLlZIKGEpCnQ9cS5iCmlmKHM+PXQubGVuZ3RoKXJldHVybiBILmsodCxzKQpyPXAu
+YT10W3NdCmlmKHIhPW51bGwpcmV0dXJuIHIKcj17fQpwLmE9cgpDLk5tLlkodCxzLHIpCmEuSygwLG5l
+dyBQLmpnKHAscSkpCnJldHVybiBwLmF9aWYodS5qLmIoYSkpe3M9cS5WSChhKQpwPXEuYgppZihzPj1w
+Lmxlbmd0aClyZXR1cm4gSC5rKHAscykKcj1wW3NdCmlmKHIhPW51bGwpcmV0dXJuIHIKcmV0dXJuIHEu
+ZWsoYSxzKX1pZih1LmVILmIoYSkpe3M9cS5WSChhKQp0PXEuYgppZihzPj10Lmxlbmd0aClyZXR1cm4g
+SC5rKHQscykKcj1wLmI9dFtzXQppZihyIT1udWxsKXJldHVybiByCnI9e30KcC5iPXIKQy5ObS5ZKHQs
+cyxyKQpxLmltKGEsbmV3IFAuVGEocCxxKSkKcmV0dXJuIHAuYn10aHJvdyBILmIoUC5uKCJzdHJ1Y3R1
+cmVkIGNsb25lIG9mIG90aGVyIHR5cGUiKSl9LAplazpmdW5jdGlvbihhLGIpe3ZhciB0LHM9Si5VNihh
+KSxyPXMuZ0EoYSkscT1uZXcgQXJyYXkocikKQy5ObS5ZKHRoaXMuYixiLHEpCmZvcih0PTA7dDxyOysr
+dClDLk5tLlkocSx0LHRoaXMuUHYocy5xKGEsdCkpKQpyZXR1cm4gcX19ClAuamcucHJvdG90eXBlPXsK
+JDI6ZnVuY3Rpb24oYSxiKXt0aGlzLmEuYVthXT10aGlzLmIuUHYoYil9LAokUzoyfQpQLlRhLnByb3Rv
+dHlwZT17CiQyOmZ1bmN0aW9uKGEsYil7dGhpcy5hLmJbYV09dGhpcy5iLlB2KGIpfSwKJFM6Mn0KUC5C
+Zi5wcm90b3R5cGU9ewppbTpmdW5jdGlvbihhLGIpe3ZhciB0LHMscixxCnUuYjguYShiKQpmb3IodD1P
+YmplY3Qua2V5cyhhKSxzPXQubGVuZ3RoLHI9MDtyPHM7KytyKXtxPXRbcl0KYi4kMihxLGFbcV0pfX19
+ClAuQXMucHJvdG90eXBlPXsKVDpmdW5jdGlvbihhKXt2YXIgdApILmMoYSkKdD0kLmhHKCkuYgppZih0
+eXBlb2YgYSE9InN0cmluZyIpSC52aChILkkoYSkpCmlmKHQudGVzdChhKSlyZXR1cm4gYQp0aHJvdyBI
+LmIoUC5MMyhhLCJ2YWx1ZSIsIk5vdCBhIHZhbGlkIGNsYXNzIHRva2VuIikpfSwKWjpmdW5jdGlvbihh
+KXtyZXR1cm4gdGhpcy53KCkuelYoMCwiICIpfSwKZ2t6OmZ1bmN0aW9uKGEpe3ZhciB0PXRoaXMudygp
+CnJldHVybiBQLnJqKHQsdC5yLEguTGgodCkuYyl9LApnQTpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy53
+KCkuYX0sCnRnOmZ1bmN0aW9uKGEsYil7dGhpcy5UKGIpCnJldHVybiB0aGlzLncoKS50ZygwLGIpfSwK
+aTpmdW5jdGlvbihhLGIpe3RoaXMuVChiKQpyZXR1cm4gSC5FOSh0aGlzLk9TKG5ldyBQLkdFKGIpKSl9
+LApSOmZ1bmN0aW9uKGEsYil7dmFyIHQscwp0aGlzLlQoYikKdD10aGlzLncoKQpzPXQuUigwLGIpCnRo
+aXMucCh0KQpyZXR1cm4gc30sCkZWOmZ1bmN0aW9uKGEsYil7dGhpcy5PUyhuZXcgUC5ONyh0aGlzLHUu
+WC5hKGIpKSl9LApWMTpmdW5jdGlvbihhKXt0aGlzLk9TKG5ldyBQLnVRKCkpfSwKT1M6ZnVuY3Rpb24o
+YSl7dmFyIHQscwp1LmJVLmEoYSkKdD10aGlzLncoKQpzPWEuJDEodCkKdGhpcy5wKHQpCnJldHVybiBz
+fX0KUC5HRS5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXtyZXR1cm4gdS5DLmEoYSkuaSgwLHRoaXMu
+YSl9LAokUzo1MH0KUC5ONy5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXt2YXIgdD10aGlzLmIscz1I
+LnQ2KHQpCnJldHVybiB1LkMuYShhKS5GVigwLG5ldyBILmxKKHQscy5DKCJxVSgxKSIpLmEodGhpcy5h
+Lmd1TSgpKSxzLkMoImxKPDEscVU+IikpKX0sCiRTOjE2fQpQLnVRLnByb3RvdHlwZT17CiQxOmZ1bmN0
+aW9uKGEpe3UuQy5hKGEpCmlmKGEuYT4wKXthLmI9YS5jPWEuZD1hLmU9YS5mPW51bGwKYS5hPTAKYS5Y
+KCl9cmV0dXJuIG51bGx9LAokUzoxNn0KUC5oRi5wcm90b3R5cGU9eyRpaEY6MX0KUC5QQy5wcm90b3R5
+cGU9ewokMTpmdW5jdGlvbihhKXt2YXIgdAp1LlouYShhKQp0PWZ1bmN0aW9uKGIsYyxkKXtyZXR1cm4g
+ZnVuY3Rpb24oKXtyZXR1cm4gYihjLGQsdGhpcyxBcnJheS5wcm90b3R5cGUuc2xpY2UuYXBwbHkoYXJn
+dW1lbnRzKSl9fShQLlI0LGEsITEpClAuRG0odCwkLndRKCksYSkKcmV0dXJuIHR9LAokUzo2fQpQLm10
+LnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe3JldHVybiBuZXcgdGhpcy5hKGEpfSwKJFM6Nn0KUC5O
+ei5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXtyZXR1cm4gbmV3IFAucjcoYSl9LAokUzozNX0KUC5R
+Uy5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXtyZXR1cm4gbmV3IFAuVHooYSx1LmFtKX0sCiRTOjM2
+fQpQLm5wLnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe3JldHVybiBuZXcgUC5FNChhKX0sCiRTOjM3
+fQpQLkU0LnByb3RvdHlwZT17CnE6ZnVuY3Rpb24oYSxiKXtpZih0eXBlb2YgYiE9InN0cmluZyImJnR5
+cGVvZiBiIT0ibnVtYmVyIil0aHJvdyBILmIoUC54WSgicHJvcGVydHkgaXMgbm90IGEgU3RyaW5nIG9y
+IG51bSIpKQpyZXR1cm4gUC5MNyh0aGlzLmFbYl0pfSwKWTpmdW5jdGlvbihhLGIsYyl7aWYodHlwZW9m
+IGIhPSJzdHJpbmciJiZ0eXBlb2YgYiE9Im51bWJlciIpdGhyb3cgSC5iKFAueFkoInByb3BlcnR5IGlz
+IG5vdCBhIFN0cmluZyBvciBudW0iKSkKdGhpcy5hW2JdPVAud1koYyl9LApETjpmdW5jdGlvbihhLGIp
+e2lmKGI9PW51bGwpcmV0dXJuITEKcmV0dXJuIGIgaW5zdGFuY2VvZiBQLkU0JiZ0aGlzLmE9PT1iLmF9
+LApaOmZ1bmN0aW9uKGEpe3ZhciB0LHMKdHJ5e3Q9U3RyaW5nKHRoaXMuYSkKcmV0dXJuIHR9Y2F0Y2go
+cyl7SC5SdShzKQp0PXRoaXMueGIoMCkKcmV0dXJuIHR9fSwKVjc6ZnVuY3Rpb24oYSxiKXt2YXIgdCxz
+PXRoaXMuYQppZihiPT1udWxsKXQ9bnVsbAplbHNle3Q9SC50NihiKQp0PVAuQ0gobmV3IEgubEooYix0
+LkMoIkAoMSkiKS5hKFAuaUcoKSksdC5DKCJsSjwxLEA+IikpLCEwLHUueil9cmV0dXJuIFAuTDcoc1th
+XS5hcHBseShzLHQpKX0sCmdpTzpmdW5jdGlvbihhKXtyZXR1cm4gMH19ClAucjcucHJvdG90eXBlPXt9
+ClAuVHoucHJvdG90eXBlPXsKY1A6ZnVuY3Rpb24oYSl7dmFyIHQ9dGhpcyxzPWE8MHx8YT49dC5nQSh0
+KQppZihzKXRocm93IEguYihQLlRFKGEsMCx0LmdBKHQpLG51bGwsbnVsbCkpfSwKcTpmdW5jdGlvbihh
+LGIpe2lmKEgub2soYikpdGhpcy5jUChiKQpyZXR1cm4gdGhpcy4kdGkuYy5hKHRoaXMuVXIoMCxiKSl9
+LApZOmZ1bmN0aW9uKGEsYixjKXt0aGlzLmNQKGIpCnRoaXMuZTQoMCxiLGMpfSwKZ0E6ZnVuY3Rpb24o
+YSl7dmFyIHQ9dGhpcy5hLmxlbmd0aAppZih0eXBlb2YgdD09PSJudW1iZXIiJiZ0Pj4+MD09PXQpcmV0
+dXJuIHQKdGhyb3cgSC5iKFAuUFYoIkJhZCBKc0FycmF5IGxlbmd0aCIpKX0sCiRpYlE6MSwKJGljWDox
+LAokaXpNOjF9ClAuY28ucHJvdG90eXBlPXt9ClAuYkIucHJvdG90eXBlPXskaWJCOjF9ClAuS2UucHJv
+dG90eXBlPXsKdzpmdW5jdGlvbigpe3ZhciB0LHMscixxLHA9dGhpcy5hLmdldEF0dHJpYnV0ZSgiY2xh
+c3MiKSxvPVAuTHModS5OKQppZihwPT1udWxsKXJldHVybiBvCmZvcih0PXAuc3BsaXQoIiAiKSxzPXQu
+bGVuZ3RoLHI9MDtyPHM7KytyKXtxPUouVDAodFtyXSkKaWYocS5sZW5ndGghPT0wKW8uaSgwLHEpfXJl
+dHVybiBvfSwKcDpmdW5jdGlvbihhKXt0aGlzLmEuc2V0QXR0cmlidXRlKCJjbGFzcyIsYS56VigwLCIg
+IikpfX0KUC5kNS5wcm90b3R5cGU9ewpnUDpmdW5jdGlvbihhKXtyZXR1cm4gbmV3IFAuS2UoYSl9LApz
+aGY6ZnVuY3Rpb24oYSxiKXt0aGlzLllDKGEsYil9LApyNjpmdW5jdGlvbihhLGIsYyxkKXt2YXIgdCxz
+LHIscSxwLG8KaWYoZD09bnVsbCl7dD1ILlZNKFtdLHUuaykKZD1uZXcgVy52RCh0KQpDLk5tLmkodCxX
+LlR3KG51bGwpKQpDLk5tLmkodCxXLkJsKCkpCkMuTm0uaSh0LG5ldyBXLk93KCkpfWM9bmV3IFcuS28o
+ZCkKcz0nPHN2ZyB2ZXJzaW9uPSIxLjEiPicrSC5kKGIpKyI8L3N2Zz4iCnQ9ZG9jdW1lbnQKcj10LmJv
+ZHkKci50b1N0cmluZwpxPUMuUlkuQUgocixzLGMpCnA9dC5jcmVhdGVEb2N1bWVudEZyYWdtZW50KCkK
+cS50b1N0cmluZwp0PW5ldyBXLmU3KHEpCm89dC5ncjgodCkKZm9yKDt0PW8uZmlyc3RDaGlsZCx0IT1u
+dWxsOylwLmFwcGVuZENoaWxkKHQpCnJldHVybiBwfSwKbno6ZnVuY3Rpb24oYSxiLGMsZCxlKXt0aHJv
+dyBILmIoUC5MNCgiQ2Fubm90IGludm9rZSBpbnNlcnRBZGphY2VudEh0bWwgb24gU1ZHLiIpKX0sCmdW
+bDpmdW5jdGlvbihhKXtyZXR1cm4gbmV3IFcuZXUoYSwiY2xpY2siLCExLHUuUSl9LAokaWQ1OjF9ClAu
+bjYucHJvdG90eXBlPXskaWJROjEsJGljWDoxLCRpek06MSwkaUFTOjF9ClUuZDIucHJvdG90eXBlPXt9
+ClUuU2UucHJvdG90eXBlPXt9ClUuTWwucHJvdG90eXBlPXt9ClUueUQucHJvdG90eXBlPXt9ClUud2Iu
+cHJvdG90eXBlPXt9CkIuajgucHJvdG90eXBlPXt9CkIucXAucHJvdG90eXBlPXt9ClQubVEucHJvdG90
+eXBlPXt9CkwuZS5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXt2YXIgdCxzLHIscSxwLG8sbgp1LkIu
+YShhKQp0PXdpbmRvdy5sb2NhdGlvbi5wYXRobmFtZQpzPUwuRzYod2luZG93LmxvY2F0aW9uLmhyZWYp
+CnI9TC5hSyh3aW5kb3cubG9jYXRpb24uaHJlZikKTC5HZSgpCmlmKHQhPT0iLyImJnQhPT1KLlQwKGRv
+Y3VtZW50LnF1ZXJ5U2VsZWN0b3IoIi5yb290IikudGV4dENvbnRlbnQpKUwuRzcodCxzLHIsITAsbmV3
+IEwuVlcodCxzLHIpKQpxPWRvY3VtZW50CnA9Si5xRihxLnF1ZXJ5U2VsZWN0b3IoIi5hcHBseS1taWdy
+YXRpb24iKSkKbz1wLiR0aQpuPW8uQygifigxKSIpLmEobmV3IEwub1ooKSkKdS5NLmEobnVsbCkKVy5K
+RShwLmEscC5iLG4sITEsby5jKQpvPUoucUYocS5xdWVyeVNlbGVjdG9yKCIucmVydW4tbWlncmF0aW9u
+IikpCm49by4kdGkKVy5KRShvLmEsby5iLG4uQygifigxKSIpLmEobmV3IEwueTgoKSksITEsbi5jKQpu
+PUoucUYocS5xdWVyeVNlbGVjdG9yKCIucmVwb3J0LXByb2JsZW0iKSkKbz1uLiR0aQpXLkpFKG4uYSxu
+LmIsby5DKCJ+KDEpIikuYShuZXcgTC5IaSgpKSwhMSxvLmMpCnE9Si5xRihxLnF1ZXJ5U2VsZWN0b3Io
+Ii5wb3B1cC1wYW5lIC5jbG9zZSIpKQpvPXEuJHRpClcuSkUocS5hLHEuYixvLkMoIn4oMSkiKS5hKG5l
+dyBMLkJUKCkpLCExLG8uYyl9LAokUzoxN30KTC5WVy5wcm90b3R5cGU9ewokMDpmdW5jdGlvbigpe0wu
+RnIodGhpcy5hLHRoaXMuYix0aGlzLmMpfSwKJFM6MH0KTC5vWi5wcm90b3R5cGU9ewokMTpmdW5jdGlv
+bihhKXt1LlYuYShhKQppZihILm9UKHdpbmRvdy5jb25maXJtKCJUaGlzIHdpbGwgYXBwbHkgdGhlIGNo
+YW5nZXMgeW91J3ZlIHByZXZpZXdlZCB0byB5b3VyIHdvcmtpbmcgZGlyZWN0b3J5LiBJdCBpcyByZWNv
+bW1lbmRlZCB5b3UgY29tbWl0IGFueSBjaGFuZ2VzIHlvdSBtYWRlIGJlZm9yZSBkb2luZyB0aGlzLiIp
+KSlMLnR5KCIvYXBwbHktbWlncmF0aW9uIikuVzcobmV3IEwuanIoKSx1LlApLk9BKG5ldyBMLnFsKCkp
+fSwKJFM6M30KTC5qci5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXt2YXIgdAp1LlMuYShhKQp0PWRv
+Y3VtZW50LmJvZHkKdC5jbGFzc0xpc3QucmVtb3ZlKCJwcm9wb3NlZCIpCnQuY2xhc3NMaXN0LmFkZCgi
+YXBwbGllZCIpfSwKJFM6NDB9CkwucWwucHJvdG90eXBlPXsKJDI6ZnVuY3Rpb24oYSxiKXtMLkMyKCJD
+b3VsZCBub3QgYXBwbHkgbWlncmF0aW9uIixhLGIpfSwKJEM6IiQyIiwKJFI6MiwKJFM6Mn0KTC55OC5w
+cm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy54bih1LlYuYShhKSl9LAp4bjpmdW5j
+dGlvbihhKXt2YXIgdD0wLHM9UC5GWCh1LlApLHI9MSxxLHA9W10sbyxuLG0sbAp2YXIgJGFzeW5jJCQx
+PVAubHooZnVuY3Rpb24oYixjKXtpZihiPT09MSl7cT1jCnQ9cn13aGlsZSh0cnVlKXN3aXRjaCh0KXtj
+YXNlIDA6cj0zCmRvY3VtZW50LmJvZHkuY2xhc3NMaXN0LmFkZCgicmVydW5uaW5nIikKdD02CnJldHVy
+biBQLmpRKEwudHkoIi9yZXJ1bi1taWdyYXRpb24iKSwkYXN5bmMkJDEpCmNhc2UgNjp3aW5kb3cubG9j
+YXRpb24ucmVsb2FkKCkKcC5wdXNoKDUpCnQ9NApicmVhawpjYXNlIDM6cj0yCmw9cQpvPUguUnUobCkK
+bj1ILnRzKGwpCkwuQzIoIkZhaWxlZCB0byByZXJ1biBtaWdyYXRpb24iLG8sbikKcC5wdXNoKDUpCnQ9
+NApicmVhawpjYXNlIDI6cD1bMV0KY2FzZSA0OnI9MQpkb2N1bWVudC5ib2R5LmNsYXNzTGlzdC5yZW1v
+dmUoInJlcnVubmluZyIpCnQ9cC5wb3AoKQpicmVhawpjYXNlIDU6cmV0dXJuIFAueUMobnVsbCxzKQpj
+YXNlIDE6cmV0dXJuIFAuZjMocSxzKX19KQpyZXR1cm4gUC5ESSgkYXN5bmMkJDEscyl9LAokUzo0MX0K
+TC5IaS5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXt1LlYuYShhKQpDLm9sLlBvKHdpbmRvdywiaHR0
+cHM6Ly9nb28uZ2xlL2RhcnQtbnVsbC1zYWZldHktbWlncmF0aW9uLXRvb2wtaXNzdWUiLCJyZXBvcnQt
+cHJvYmxlbSIpfSwKJFM6M30KTC5CVC5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXt2YXIgdAp1LlYu
+YShhKQp0PWRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoIi5wb3B1cC1wYW5lIikuc3R5bGUKdC5kaXNwbGF5
+PSJub25lIgpyZXR1cm4ibm9uZSJ9LAokUzo0Mn0KTC5MLnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEp
+e3ZhciB0LHMscgp1LkIuYShhKQp0PXdpbmRvdy5sb2NhdGlvbi5wYXRobmFtZQpzPUwuRzYod2luZG93
+LmxvY2F0aW9uLmhyZWYpCnI9TC5hSyh3aW5kb3cubG9jYXRpb24uaHJlZikKaWYodC5sZW5ndGg+MSlM
+Lkc3KHQscyxyLCExLG51bGwpCmVsc2V7TC5CRSh0LG5ldyBCLnFwKCIiLCIiLCIiLEMuQ00pLCEwKQpM
+LkJYKCImbmJzcDsiLG51bGwpfX0sCiRTOjE3fQpMLld4LnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEp
+e3ZhciB0LHMscixxPSJjb2xsYXBzZWQiCnUuVi5hKGEpCnQ9dGhpcy5hCnM9Si5SRSh0KQpyPXRoaXMu
+YgppZighcy5nUCh0KS50ZygwLHEpKXtzLmdQKHQpLmkoMCxxKQpKLmRSKHIpLmkoMCxxKX1lbHNle3Mu
+Z1AodCkuUigwLHEpCkouZFIocikuUigwLHEpfX0sCiRTOjN9CkwuQU8ucHJvdG90eXBlPXsKJDE6ZnVu
+Y3Rpb24oYSl7dmFyIHQ9Si5xRih1LmguYShhKSkscz10LiR0aSxyPXMuQygifigxKSIpLmEobmV3IEwu
+ZE4odGhpcy5hKSkKdS5NLmEobnVsbCkKVy5KRSh0LmEsdC5iLHIsITEscy5jKX0sCiRTOjV9CkwuZE4u
+cHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7dmFyIHQKdS5WLmEoYSkKdD1kb2N1bWVudC5xdWVyeVNl
+bGVjdG9yKCJ0YWJsZVtkYXRhLXBhdGhdIikKdC50b1N0cmluZwpMLnQyKGEsdGhpcy5hLHQuZ2V0QXR0
+cmlidXRlKCJkYXRhLSIrbmV3IFcuU3kobmV3IFcuaTcodCkpLk8oInBhdGgiKSkpfSwKJFM6M30KTC5I
+by5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXt2YXIgdCxzLHIKdS5oLmEoYSkKdD1KLnFGKGEpCnM9
+dC4kdGkKcj1zLkMoIn4oMSkiKS5hKG5ldyBMLnh6KGEsdGhpcy5hKSkKdS5NLmEobnVsbCkKVy5KRSh0
+LmEsdC5iLHIsITEscy5jKX0sCiRTOjV9CkwueHoucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7dmFy
+IHQKdS5WLmEoYSkKdD10aGlzLmEKTC5oWCh0aGlzLmIsUC5RQSh0LmdldEF0dHJpYnV0ZSgiZGF0YS0i
+K25ldyBXLlN5KG5ldyBXLmk3KHQpKS5PKCJvZmZzZXQiKSksbnVsbCksUC5RQSh0LmdldEF0dHJpYnV0
+ZSgiZGF0YS0iK25ldyBXLlN5KG5ldyBXLmk3KHQpKS5PKCJsaW5lIikpLG51bGwpKX0sCiRTOjN9Ckwu
+SUMucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7dmFyIHQ9Si5xRih1LmguYShhKSkscz10LiR0aQpz
+LkMoIn4oMSkiKS5hKEwuaVMoKSkKdS5NLmEobnVsbCkKVy5KRSh0LmEsdC5iLEwuaVMoKSwhMSxzLmMp
+fSwKJFM6NX0KTC5MMS5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXt1LnAuYShhKQp0aGlzLmEuYU0o
+MCx0aGlzLmIpfSwKJFM6MTR9CkwublQucHJvdG90eXBlPXsKJDA6ZnVuY3Rpb24oKXtMLkZyKHRoaXMu
+YS5hLHRoaXMuYix0aGlzLmMpfSwKJFM6MH0KTC5OWS5wcm90b3R5cGU9ewokMDpmdW5jdGlvbigpe0wu
+RnIodGhpcy5hLmEsbnVsbCxudWxsKX0sCiRTOjB9CkwuR0gucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24o
+YSl7dS5oLmEoYSkKJC56QigpLnRvU3RyaW5nCnUuaGIuYSgkLm93KCkucSgwLCJobGpzIikpLlY3KCJo
+aWdobGlnaHRCbG9jayIsW2FdKX0sCiRTOjV9CkwuRFQucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7
+dmFyIHQscwp1LnIuYShhKQp0PWEuc3RhdHVzCmlmKHQ9PT0yMDApe3Q9Qy5DdC5wVygwLGEucmVzcG9u
+c2VUZXh0LG51bGwpCnM9Si5VNih0KQpMLlQxKG5ldyBVLmQyKFUuamYocy5xKHQsImVkaXRzIikpLEgu
+YyhzLnEodCwiZXhwbGFuYXRpb24iKSksSC5XWShzLnEodCwibGluZSIpKSxILmMocy5xKHQsInBhdGgi
+KSksVS5OZChzLnEodCwidHJhY2VzIikpKSkKTC5Gcih0aGlzLmEsdGhpcy5iLHRoaXMuYykKTC55WCgi
+LmVkaXQtcGFuZWwgLnBhbmVsLWNvbnRlbnQiLCExKX1lbHNlIHdpbmRvdy5hbGVydCgiUmVxdWVzdCBm
+YWlsZWQ7IHN0YXR1cyBvZiAiK0guZCh0KSl9LAokUzo5fQpMLmVILnByb3RvdHlwZT17CiQyOmZ1bmN0
+aW9uKGEsYil7TC5xSigibG9hZFJlZ2lvbkV4cGxhbmF0aW9uOiAiK0guZChhKSxiKQp3aW5kb3cuYWxl
+cnQoIkNvdWxkIG5vdCBsb2FkICIrSC5kKHRoaXMuYSkrIiAoIitILmQoYSkrIikuIil9LAokQzoiJDIi
+LAokUjoyLAokUzoyfQpMLnl1LnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe3ZhciB0LHMscj10aGlz
+CnUuci5hKGEpCnQ9YS5zdGF0dXMKaWYodD09PTIwMCl7cz1yLmEKTC5CRShzLEIuWWYodS5iLmEoQy5D
+dC5wVygwLGEucmVzcG9uc2VUZXh0LG51bGwpKSksci5iKQp0PXIuYwpMLmZHKHQsci5kKQpMLkJYKEMu
+eEIudGcocywiPyIpP0MueEIuTmoocywwLEMueEIuT1kocywiPyIpKTpzLHQpCnQ9ci5lCmlmKHQhPW51
+bGwpdC4kMCgpfWVsc2Ugd2luZG93LmFsZXJ0KCJSZXF1ZXN0IGZhaWxlZDsgc3RhdHVzIG9mICIrSC5k
+KHQpKX0sCiRTOjl9CkwuekQucHJvdG90eXBlPXsKJDI6ZnVuY3Rpb24oYSxiKXtMLnFKKCJsb2FkRmls
+ZTogIitILmQoYSksYikKd2luZG93LmFsZXJ0KCJDb3VsZCBub3QgbG9hZCAiK3RoaXMuYSsiICgiK0gu
+ZChhKSsiKS4iKX0sCiRDOiIkMiIsCiRSOjIsCiRTOjJ9CkwuVFcucHJvdG90eXBlPXsKJDE6ZnVuY3Rp
+b24oYSl7dmFyIHQscyxyCnUuci5hKGEpCnQ9YS5zdGF0dXMKaWYodD09PTIwMCl7cz1DLkN0LnBXKDAs
+YS5yZXNwb25zZVRleHQsbnVsbCkKcj1kb2N1bWVudC5xdWVyeVNlbGVjdG9yKCIubmF2LXRyZWUiKQpK
+Lmw1KHIsIiIpCkwudFgocixMLm1LKHMpKX1lbHNlIHdpbmRvdy5hbGVydCgiUmVxdWVzdCBmYWlsZWQ7
+IHN0YXR1cyBvZiAiK0guZCh0KSl9LAokUzo5fQpMLnhyLnByb3RvdHlwZT17CiQyOmZ1bmN0aW9uKGEs
+Yil7TC5xSigibG9hZE5hdmlnYXRpb25UcmVlOiAiK0guZChhKSxiKQp3aW5kb3cuYWxlcnQoIkNvdWxk
+IG5vdCBsb2FkICIrdGhpcy5hKyIgKCIrSC5kKGEpKyIpLiIpfSwKJEM6IiQyIiwKJFI6MiwKJFM6Mn0K
+TC5FRS5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXt2YXIgdCxzCnUuVi5hKGEpCnQ9dGhpcy5hCnM9
+dGhpcy5iCkwuYWYod2luZG93LmxvY2F0aW9uLnBhdGhuYW1lLHQscywhMCxuZXcgTC5RTCh0LHMpKQpM
+LmhYKHRoaXMuYyx0LHMpfSwKJFM6M30KTC5RTC5wcm90b3R5cGU9ewokMDpmdW5jdGlvbigpe0wuRnIo
+d2luZG93LmxvY2F0aW9uLnBhdGhuYW1lLHRoaXMuYSx0aGlzLmIpfSwKJFM6MH0KTC5WUy5wcm90b3R5
+cGU9ewokMTpmdW5jdGlvbihhKXt2YXIgdCxzPSJzZWxlY3RlZC1maWxlIgp1LmguYShhKQphLnRvU3Ry
+aW5nCnQ9Si5SRShhKQppZihhLmdldEF0dHJpYnV0ZSgiZGF0YS0iK25ldyBXLlN5KG5ldyBXLmk3KGEp
+KS5PKCJuYW1lIikpPT09dGhpcy5hLmEpdC5nUChhKS5pKDAscykKZWxzZSB0LmdQKGEpLlIoMCxzKX0s
+CiRTOjV9CkwuVEQucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7cmV0dXJuIEwudDIodS5WLmEoYSks
+ITAsbnVsbCl9LAokUzoxOH0KTC5YQS5wcm90b3R5cGU9ewpFYjpmdW5jdGlvbihhLGIsYyl7cmV0dXJu
+ITB9LAppMDpmdW5jdGlvbihhKXtyZXR1cm4hMH0sCiRpa0Y6MX0KTC5aWi5wcm90b3R5cGU9e30KTC5P
+OS5wcm90b3R5cGU9ewpaOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLmJ9fQpNLmxJLnByb3RvdHlwZT17
+CldPOmZ1bmN0aW9uKGEsYil7dmFyIHQscz1udWxsCk0uWUYoImFic29sdXRlIixILlZNKFtiLG51bGws
+bnVsbCxudWxsLG51bGwsbnVsbCxudWxsXSx1LnMpKQp0PXRoaXMuYQp0PXQuWXIoYik+MCYmIXQuaEso
+YikKaWYodClyZXR1cm4gYgp0PUQuUlgoKQpyZXR1cm4gdGhpcy5xNygwLHQsYixzLHMscyxzLHMscyl9
+LAp0TTpmdW5jdGlvbihhKXt2YXIgdCxzLHI9WC5DTChhLHRoaXMuYSkKci5JVigpCnQ9ci5kCnM9dC5s
+ZW5ndGgKaWYocz09PTApe3Q9ci5iCnJldHVybiB0PT1udWxsPyIuIjp0fWlmKHM9PT0xKXt0PXIuYgpy
+ZXR1cm4gdD09bnVsbD8iLiI6dH1pZigwPj1zKXJldHVybiBILmsodCwtMSkKdC5wb3AoKQpDLk5tLm12
+KHIuZSkKci5JVigpCnJldHVybiByLlooMCl9LApxNzpmdW5jdGlvbihhLGIsYyxkLGUsZixnLGgsaSl7
+dmFyIHQ9SC5WTShbYixjLGQsZSxmLGcsaCxpXSx1LnMpCk0uWUYoImpvaW4iLHQpCnJldHVybiB0aGlz
+LklQKG5ldyBILlU1KHQsdS5iQi5hKG5ldyBNLk1pKCkpLHUuY2MpKX0sCklQOmZ1bmN0aW9uKGEpe3Zh
+ciB0LHMscixxLHAsbyxuLG0sbAp1LlguYShhKQpmb3IodD1hLiR0aSxzPXQuQygiYTIoY1guRSkiKS5h
+KG5ldyBNLnE3KCkpLHI9YS5na3ooYSksdD1uZXcgSC52RyhyLHMsdC5DKCJ2RzxjWC5FPiIpKSxzPXRo
+aXMuYSxxPSExLHA9ITEsbz0iIjt0LkYoKTspe249ci5nbCgpCmlmKHMuaEsobikmJnApe209WC5DTChu
+LHMpCmw9by5jaGFyQ29kZUF0KDApPT0wP286bwpvPUMueEIuTmoobCwwLHMuU3AobCwhMCkpCm0uYj1v
+CmlmKHMuZHMobykpQy5ObS5ZKG0uZSwwLHMuZ21JKCkpCm89bS5aKDApfWVsc2UgaWYocy5ZcihuKT4w
+KXtwPSFzLmhLKG4pCm89SC5kKG4pfWVsc2V7aWYoIShuLmxlbmd0aD4wJiZzLlVkKG5bMF0pKSlpZihx
+KW8rPXMuZ21JKCkKbys9SC5kKG4pfXE9cy5kcyhuKX1yZXR1cm4gby5jaGFyQ29kZUF0KDApPT0wP286
+b30sCm81OmZ1bmN0aW9uKGEpe3ZhciB0CmlmKCF0aGlzLnkzKGEpKXJldHVybiBhCnQ9WC5DTChhLHRo
+aXMuYSkKdC5yUigpCnJldHVybiB0LlooMCl9LAp5MzpmdW5jdGlvbihhKXt2YXIgdCxzLHIscSxwLG8s
+bixtLGwsawphLnRvU3RyaW5nCnQ9dGhpcy5hCnM9dC5ZcihhKQppZihzIT09MCl7aWYodD09PSQuS2so
+KSlmb3Iocj0wO3I8czsrK3IpaWYoQy54Qi5XKGEscik9PT00NylyZXR1cm4hMApxPXMKcD00N31lbHNl
+e3E9MApwPW51bGx9Zm9yKG89bmV3IEgucWooYSkuYSxuPW8ubGVuZ3RoLHI9cSxtPW51bGw7cjxuOysr
+cixtPXAscD1sKXtsPUMueEIubShvLHIpCmlmKHQucjQobCkpe2lmKHQ9PT0kLktrKCkmJmw9PT00Nyly
+ZXR1cm4hMAppZihwIT1udWxsJiZ0LnI0KHApKXJldHVybiEwCmlmKHA9PT00NilrPW09PW51bGx8fG09
+PT00Nnx8dC5yNChtKQplbHNlIGs9ITEKaWYoaylyZXR1cm4hMH19aWYocD09bnVsbClyZXR1cm4hMApp
+Zih0LnI0KHApKXJldHVybiEwCmlmKHA9PT00Nil0PW09PW51bGx8fHQucjQobSl8fG09PT00NgplbHNl
+IHQ9ITEKaWYodClyZXR1cm4hMApyZXR1cm4hMX0sCkhQOmZ1bmN0aW9uKGEsYil7dmFyIHQscyxyLHEs
+cCxvPXRoaXMsbj0nVW5hYmxlIHRvIGZpbmQgYSBwYXRoIHRvICInCmI9by5XTygwLGIpCnQ9by5hCmlm
+KHQuWXIoYik8PTAmJnQuWXIoYSk+MClyZXR1cm4gby5vNShhKQppZih0LllyKGEpPD0wfHx0LmhLKGEp
+KWE9by5XTygwLGEpCmlmKHQuWXIoYSk8PTAmJnQuWXIoYik+MCl0aHJvdyBILmIoWC5JNyhuK0guZChh
+KSsnIiBmcm9tICInK0guZChiKSsnIi4nKSkKcz1YLkNMKGIsdCkKcy5yUigpCnI9WC5DTChhLHQpCnIu
+clIoKQpxPXMuZAppZihxLmxlbmd0aD4wJiZKLlJNKHFbMF0sIi4iKSlyZXR1cm4gci5aKDApCnE9cy5i
+CnA9ci5iCmlmKHEhPXApcT1xPT1udWxsfHxwPT1udWxsfHwhdC5OYyhxLHApCmVsc2UgcT0hMQppZihx
+KXJldHVybiByLlooMCkKd2hpbGUoITApe3E9cy5kCmlmKHEubGVuZ3RoPjApe3A9ci5kCnE9cC5sZW5n
+dGg+MCYmdC5OYyhxWzBdLHBbMF0pfWVsc2UgcT0hMQppZighcSlicmVhawpDLk5tLlc0KHMuZCwwKQpD
+Lk5tLlc0KHMuZSwxKQpDLk5tLlc0KHIuZCwwKQpDLk5tLlc0KHIuZSwxKX1xPXMuZAppZihxLmxlbmd0
+aD4wJiZKLlJNKHFbMF0sIi4uIikpdGhyb3cgSC5iKFguSTcobitILmQoYSkrJyIgZnJvbSAiJytILmQo
+YikrJyIuJykpCnE9dS5OCkMuTm0uVUcoci5kLDAsUC5POChzLmQubGVuZ3RoLCIuLiIsITEscSkpCkMu
+Tm0uWShyLmUsMCwiIikKQy5ObS5VRyhyLmUsMSxQLk84KHMuZC5sZW5ndGgsdC5nbUkoKSwhMSxxKSkK
+dD1yLmQKcT10Lmxlbmd0aAppZihxPT09MClyZXR1cm4iLiIKaWYocT4xJiZKLlJNKEMuTm0uZ3JaKHQp
+LCIuIikpe3Q9ci5kCmlmKDA+PXQubGVuZ3RoKXJldHVybiBILmsodCwtMSkKdC5wb3AoKQp0PXIuZQpD
+Lk5tLm12KHQpCkMuTm0ubXYodCkKQy5ObS5pKHQsIiIpfXIuYj0iIgpyLklWKCkKcmV0dXJuIHIuWigw
+KX19Ck0uTWkucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7cmV0dXJuIEguYyhhKSE9bnVsbH0sCiRT
+Ojd9Ck0ucTcucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7cmV0dXJuIEguYyhhKSE9PSIifSwKJFM6
+N30KTS5Oby5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXtILmMoYSkKcmV0dXJuIGE9PW51bGw/Im51
+bGwiOiciJythKyciJ30sCiRTOjR9CkIuZnYucHJvdG90eXBlPXsKeFo6ZnVuY3Rpb24oYSl7dmFyIHQs
+cz10aGlzLllyKGEpCmlmKHM+MClyZXR1cm4gSi5sZChhLDAscykKaWYodGhpcy5oSyhhKSl7aWYoMD49
+YS5sZW5ndGgpcmV0dXJuIEguayhhLDApCnQ9YVswXX1lbHNlIHQ9bnVsbApyZXR1cm4gdH0sCk5jOmZ1
+bmN0aW9uKGEsYil7cmV0dXJuIGE9PWJ9fQpYLldELnByb3RvdHlwZT17CklWOmZ1bmN0aW9uKCl7dmFy
+IHQscyxyPXRoaXMKd2hpbGUoITApe3Q9ci5kCmlmKCEodC5sZW5ndGghPT0wJiZKLlJNKEMuTm0uZ3Ja
+KHQpLCIiKSkpYnJlYWsKdD1yLmQKaWYoMD49dC5sZW5ndGgpcmV0dXJuIEguayh0LC0xKQp0LnBvcCgp
+CkMuTm0ubXYoci5lKX10PXIuZQpzPXQubGVuZ3RoCmlmKHM+MClDLk5tLlkodCxzLTEsIiIpfSwKclI6
+ZnVuY3Rpb24oKXt2YXIgdCxzLHIscSxwLG8sbixtPXRoaXMsbD1ILlZNKFtdLHUucykKZm9yKHQ9bS5k
+LHM9dC5sZW5ndGgscj0wLHE9MDtxPHQubGVuZ3RoO3QubGVuZ3RoPT09c3x8KDAsSC5saykodCksKytx
+KXtwPXRbcV0Kbz1KLmlhKHApCmlmKCEoby5ETihwLCIuIil8fG8uRE4ocCwiIikpKWlmKG8uRE4ocCwi
+Li4iKSlpZihsLmxlbmd0aD4wKWwucG9wKCkKZWxzZSArK3IKZWxzZSBDLk5tLmkobCxwKX1pZihtLmI9
+PW51bGwpQy5ObS5VRyhsLDAsUC5POChyLCIuLiIsITEsdS5OKSkKaWYobC5sZW5ndGg9PT0wJiZtLmI9
+PW51bGwpQy5ObS5pKGwsIi4iKQpuPVAuZEgobC5sZW5ndGgsbmV3IFgucVIobSksITAsdS5OKQp0PW0u
+Ygp0PXQhPW51bGwmJmwubGVuZ3RoPjAmJm0uYS5kcyh0KT9tLmEuZ21JKCk6IiIKSC50NihuKS5jLmEo
+dCkKaWYoISFuLmZpeGVkJGxlbmd0aClILnZoKFAuTDQoImluc2VydCIpKQpuLnNwbGljZSgwLDAsdCkK
+bS5zbkoobCkKbS5zUGgobikKdD1tLmIKaWYodCE9bnVsbCYmbS5hPT09JC5LaygpKXt0LnRvU3RyaW5n
+Cm0uYj1ILnlzKHQsIi8iLCJcXCIpfW0uSVYoKX0sClo6ZnVuY3Rpb24oYSl7dmFyIHQscyxyPXRoaXMs
+cT1yLmIKcT1xIT1udWxsP3E6IiIKZm9yKHQ9MDt0PHIuZC5sZW5ndGg7Kyt0KXtzPXIuZQppZih0Pj1z
+Lmxlbmd0aClyZXR1cm4gSC5rKHMsdCkKcz1xK0guZChzW3RdKQpxPXIuZAppZih0Pj1xLmxlbmd0aCly
+ZXR1cm4gSC5rKHEsdCkKcT1zK0guZChxW3RdKX1xKz1ILmQoQy5ObS5nclooci5lKSkKcmV0dXJuIHEu
+Y2hhckNvZGVBdCgwKT09MD9xOnF9LApzbko6ZnVuY3Rpb24oYSl7dGhpcy5kPXUuYS5hKGEpfSwKc1Bo
+OmZ1bmN0aW9uKGEpe3RoaXMuZT11LmEuYShhKX19ClgucVIucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24o
+YSl7cmV0dXJuIHRoaXMuYS5hLmdtSSgpfSwKJFM6NDZ9ClguZHYucHJvdG90eXBlPXsKWjpmdW5jdGlv
+bihhKXtyZXR1cm4iUGF0aEV4Y2VwdGlvbjogIit0aGlzLmF9fQpPLnpMLnByb3RvdHlwZT17Clo6ZnVu
+Y3Rpb24oYSl7cmV0dXJuIHRoaXMuZ29jKHRoaXMpfX0KRS5PRi5wcm90b3R5cGU9ewpVZDpmdW5jdGlv
+bihhKXtyZXR1cm4gQy54Qi50ZyhhLCIvIil9LApyNDpmdW5jdGlvbihhKXtyZXR1cm4gYT09PTQ3fSwK
+ZHM6ZnVuY3Rpb24oYSl7dmFyIHQ9YS5sZW5ndGgKcmV0dXJuIHQhPT0wJiZDLnhCLm0oYSx0LTEpIT09
+NDd9LApTcDpmdW5jdGlvbihhLGIpe2lmKGEubGVuZ3RoIT09MCYmQy54Qi5XKGEsMCk9PT00NylyZXR1
+cm4gMQpyZXR1cm4gMH0sCllyOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLlNwKGEsITEpfSwKaEs6ZnVu
+Y3Rpb24oYSl7cmV0dXJuITF9LApnb2M6ZnVuY3Rpb24oKXtyZXR1cm4icG9zaXgifSwKZ21JOmZ1bmN0
+aW9uKCl7cmV0dXJuIi8ifX0KRi5ydS5wcm90b3R5cGU9ewpVZDpmdW5jdGlvbihhKXtyZXR1cm4gQy54
+Qi50ZyhhLCIvIil9LApyNDpmdW5jdGlvbihhKXtyZXR1cm4gYT09PTQ3fSwKZHM6ZnVuY3Rpb24oYSl7
+dmFyIHQ9YS5sZW5ndGgKaWYodD09PTApcmV0dXJuITEKaWYoQy54Qi5tKGEsdC0xKSE9PTQ3KXJldHVy
+biEwCnJldHVybiBDLnhCLlRjKGEsIjovLyIpJiZ0aGlzLllyKGEpPT09dH0sClNwOmZ1bmN0aW9uKGEs
+Yil7dmFyIHQscyxyLHEscD1hLmxlbmd0aAppZihwPT09MClyZXR1cm4gMAppZihDLnhCLlcoYSwwKT09
+PTQ3KXJldHVybiAxCmZvcih0PTA7dDxwOysrdCl7cz1DLnhCLlcoYSx0KQppZihzPT09NDcpcmV0dXJu
+IDAKaWYocz09PTU4KXtpZih0PT09MClyZXR1cm4gMApyPUMueEIuWFUoYSwiLyIsQy54Qi5RaShhLCIv
+LyIsdCsxKT90KzM6dCkKaWYocjw9MClyZXR1cm4gcAppZighYnx8cDxyKzMpcmV0dXJuIHIKaWYoIUMu
+eEIubihhLCJmaWxlOi8vIikpcmV0dXJuIHIKaWYoIUIuWXUoYSxyKzEpKXJldHVybiByCnE9ciszCnJl
+dHVybiBwPT09cT9xOnIrNH19cmV0dXJuIDB9LApZcjpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5TcChh
+LCExKX0sCmhLOmZ1bmN0aW9uKGEpe3JldHVybiBhLmxlbmd0aCE9PTAmJkMueEIuVyhhLDApPT09NDd9
+LApnb2M6ZnVuY3Rpb24oKXtyZXR1cm4idXJsIn0sCmdtSTpmdW5jdGlvbigpe3JldHVybiIvIn19Ckwu
+SVYucHJvdG90eXBlPXsKVWQ6ZnVuY3Rpb24oYSl7cmV0dXJuIEMueEIudGcoYSwiLyIpfSwKcjQ6ZnVu
+Y3Rpb24oYSl7cmV0dXJuIGE9PT00N3x8YT09PTkyfSwKZHM6ZnVuY3Rpb24oYSl7dmFyIHQ9YS5sZW5n
+dGgKaWYodD09PTApcmV0dXJuITEKdD1DLnhCLm0oYSx0LTEpCnJldHVybiEodD09PTQ3fHx0PT09OTIp
+fSwKU3A6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzLHI9YS5sZW5ndGgKaWYocj09PTApcmV0dXJuIDAKdD1D
+LnhCLlcoYSwwKQppZih0PT09NDcpcmV0dXJuIDEKaWYodD09PTkyKXtpZihyPDJ8fEMueEIuVyhhLDEp
+IT09OTIpcmV0dXJuIDEKcz1DLnhCLlhVKGEsIlxcIiwyKQppZihzPjApe3M9Qy54Qi5YVShhLCJcXCIs
+cysxKQppZihzPjApcmV0dXJuIHN9cmV0dXJuIHJ9aWYocjwzKXJldHVybiAwCmlmKCFCLk9TKHQpKXJl
+dHVybiAwCmlmKEMueEIuVyhhLDEpIT09NTgpcmV0dXJuIDAKcj1DLnhCLlcoYSwyKQppZighKHI9PT00
+N3x8cj09PTkyKSlyZXR1cm4gMApyZXR1cm4gM30sCllyOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLlNw
+KGEsITEpfSwKaEs6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuWXIoYSk9PT0xfSwKT3Q6ZnVuY3Rpb24o
+YSxiKXt2YXIgdAppZihhPT09YilyZXR1cm4hMAppZihhPT09NDcpcmV0dXJuIGI9PT05MgppZihhPT09
+OTIpcmV0dXJuIGI9PT00NwppZigoYV5iKSE9PTMyKXJldHVybiExCnQ9YXwzMgpyZXR1cm4gdD49OTcm
+JnQ8PTEyMn0sCk5jOmZ1bmN0aW9uKGEsYil7dmFyIHQscyxyCmlmKGE9PWIpcmV0dXJuITAKdD1hLmxl
+bmd0aAppZih0IT09Yi5sZW5ndGgpcmV0dXJuITEKZm9yKHM9Si5yWShiKSxyPTA7cjx0OysrcilpZigh
+dGhpcy5PdChDLnhCLlcoYSxyKSxzLlcoYixyKSkpcmV0dXJuITEKcmV0dXJuITB9LApnb2M6ZnVuY3Rp
+b24oKXtyZXR1cm4id2luZG93cyJ9LApnbUk6ZnVuY3Rpb24oKXtyZXR1cm4iXFwifX07KGZ1bmN0aW9u
+IGFsaWFzZXMoKXt2YXIgdD1KLnZCLnByb3RvdHlwZQp0LlU9dC5aCnQuU2o9dC5lNwp0PUouTUYucHJv
+dG90eXBlCnQudD10LloKdD1QLmNYLnByb3RvdHlwZQp0LkdHPXQuZXYKdD1QLk1oLnByb3RvdHlwZQp0
+LnhiPXQuWgp0PVcuY3YucHJvdG90eXBlCnQuRFc9dC5yNgp0PVcubTYucHJvdG90eXBlCnQuakY9dC5F
+Ygp0PVAuRTQucHJvdG90eXBlCnQuVXI9dC5xCnQuZTQ9dC5ZfSkoKTsoZnVuY3Rpb24gaW5zdGFsbFRl
+YXJPZmZzKCl7dmFyIHQ9aHVua0hlbHBlcnMuX3N0YXRpY18xLHM9aHVua0hlbHBlcnMuX3N0YXRpY18w
+LHI9aHVua0hlbHBlcnMuaW5zdGFsbEluc3RhbmNlVGVhck9mZixxPWh1bmtIZWxwZXJzLmluc3RhbGxT
+dGF0aWNUZWFyT2ZmLHA9aHVua0hlbHBlcnMuX2luc3RhbmNlXzF1CnQoUCwiRVgiLCJaViIsMTApCnQo
+UCwieXQiLCJvQSIsMTApCnQoUCwicVciLCJCeiIsMTApCnMoUCwiVjkiLCJlTiIsMSkKcihQLlBmLnBy
+b3RvdHlwZSwiZ1lKIiwwLDEsbnVsbCxbIiQyIiwiJDEiXSxbIncwIiwicG0iXSwzMiwwKQp0KFAsIlBI
+IiwiTXQiLDQpCnEoVywicFMiLDQsbnVsbCxbIiQ0Il0sWyJ5VyJdLDExLDApCnEoVywiVjQiLDQsbnVs
+bCxbIiQ0Il0sWyJRVyJdLDExLDApCnAoUC5Bcy5wcm90b3R5cGUsImd1TSIsIlQiLDQpCnQoUCwiaUci
+LCJ3WSIsNDkpCnQoUCwidzAiLCJMNyIsMzMpCnQoTCwiaVMiLCJpNiIsMTgpfSkoKTsoZnVuY3Rpb24g
+aW5oZXJpdGFuY2UoKXt2YXIgdD1odW5rSGVscGVycy5taXhpbixzPWh1bmtIZWxwZXJzLmluaGVyaXQs
+cj1odW5rSGVscGVycy5pbmhlcml0TWFueQpzKFAuTWgsbnVsbCkKcihQLk1oLFtILkZLLEoudkIsSi5t
+MSxQLlhTLFAublksUC5jWCxILmE3LFAuQW4sSC5TVSxILlJlLEgud3YsUC5QbixILldVLEguTEksSC5U
+cCxILmY5LEguYnEsSC5YTyxQLllrLEguZGIsSC5ONixILlZSLEguRUssSC5QYixILnRRLEguU2QsSC5K
+YyxILkVULFAuVzMsUC5paCxQLkZ5LFAuR1YsUC5iOCxQLlBmLFAuRmUsUC52cyxQLk9NLFAucWgsUC5N
+TyxQLmtULFAueEksUC5PSCxQLm0wLFAuWHYsUC5ibixQLmxtLFAubEQsUC5LUCxQLk1hLFAuVEMsUC5V
+ayxQLlJ3LFAuYnosUC5hMixQLmlQLFAubGYsUC5rNSxQLktZLFAuQ0QsUC5hRSxQLkVILFAuek0sUC5a
+MCxQLk4zLFAuYzgsUC5PZCxQLmliLFAuR3osUC5aZCxQLnFVLFAuUm4sUC5HRCxQLkRuLFAuUEUsUC5V
+ZixXLmlkLFcuRmssVy5KUSxXLkdtLFcudkQsVy5tNixXLk93LFcuVzksVy5kVyxXLkZiLFcua0YsVy5t
+ayxXLktvLFAuaUosUC5FNCxQLm42LFUuZDIsVS5TZSxVLk1sLFUueUQsVS53YixCLmo4LEIucXAsVC5t
+USxMLlhBLEwuWlosTC5POSxNLmxJLE8uekwsWC5XRCxYLmR2XSkKcihKLnZCLFtKLnlFLEouWUUsSi5N
+RixKLmpkLEoucUksSi5EcixILnBGLFcuRDAsVy5BeixXLkxlLFcuTmgsVy5JQixXLm43LFcuZWEsVy5i
+cixXLlNnLFcudTgsVy5LNyxXLlhXLFAuaEZdKQpyKEouTUYsW0ouaUMsSi5rZCxKLmM1XSkKcyhKLlBv
+LEouamQpCnIoSi5xSSxbSi51cixKLlZBXSkKcihQLlhTLFtILm5kLEguVzAsSC5heixILnZWLEguRXEs
+UC5DNixILnU5LFAuTEssUC5BVCxQLm1wLFAudWIsUC5kcyxQLmxqLFAuVVYsUC50N10pCnMoUC5MVSxQ
+Lm5ZKQpyKFAuTFUsW0gudzIsVy53eixXLmU3XSkKcyhILnFqLEgudzIpCnIoUC5jWCxbSC5iUSxILmkx
+LEguVTUsSC5YUixQLm1XLEguTkZdKQpyKEguYlEsW0guYUwsSC5pNSxQLnh1XSkKcihILmFMLFtILm5I
+LEgubEosUC5pOF0pCnMoSC54eSxILmkxKQpyKFAuQW4sW0guTUgsSC52R10pCnMoUC5SVSxQLlBuKQpz
+KFAuR2osUC5SVSkKcyhILlBELFAuR2opCnMoSC5MUCxILldVKQpyKEguVHAsW0guQ2osSC5BbSxILmxj
+LEgucixILmRDLEgud04sUC50aCxQLmhhLFAuVnMsUC5GdCxQLnlILFAuV00sUC5TWCxQLkdzLFAuZGEs
+UC5vUSxQLnBWLFAuVTcsUC52cixQLnJILFAuS0YsUC5aTCxQLlJULFAualosUC5ycSxQLlJXLFAuQjUs
+UC51TyxQLnBLLFAuaGosUC5WcCxQLk9SLFAucmEsUC55USxQLnBnLFAuV0YsUC5uMSxQLmNTLFAuVkMs
+UC5KVCxQLlJaLFAuTUUsUC55NSxQLnEzLFAueUksUC5jNixQLnFkLFcuQ3YsVy5iVSxXLmhILFcuS1Ms
+Vy5BMyxXLnZOLFcuVXYsVy5FZyxXLkVvLFcuV2ssVy5JQSxXLmZtLFAuamcsUC5UYSxQLkdFLFAuTjcs
+UC51USxQLlBDLFAubXQsUC5OeixQLlFTLFAubnAsTC5lLEwuVlcsTC5vWixMLmpyLEwucWwsTC55OCxM
+LkhpLEwuQlQsTC5MLEwuV3gsTC5BTyxMLmROLEwuSG8sTC54eixMLklDLEwuTDEsTC5uVCxMLk5ZLEwu
+R0gsTC5EVCxMLmVILEwueXUsTC56RCxMLlRXLEwueHIsTC5FRSxMLlFMLEwuVlMsTC5URCxNLk1pLE0u
+cTcsTS5ObyxYLnFSXSkKcihILmxjLFtILnp4LEguanldKQpzKEgua1ksUC5DNikKcyhQLmlsLFAuWWsp
+CnIoUC5pbCxbSC5ONSxQLnV3LFcuY2YsVy5TeV0pCnIoUC5tVyxbSC5LVyxQLnE0XSkKcyhILmIwLEgu
+cEYpCnIoSC5iMCxbSC5SRyxILldCXSkKcyhILlZQLEguUkcpCnMoSC5EZyxILlZQKQpzKEguWkcsSC5X
+QikKcyhILlBnLEguWkcpCnIoSC5QZyxbSC54aixILmRFLEguWkEsSC53ZixILlBxLEguZUUsSC5WNl0p
+CnMoSC54LEgudTkpCnMoUC5aZixQLlBmKQpzKFAuSmksUC5tMCkKcyhQLmI2LFAuWHYpCnMoUC5WaixQ
+LlRDKQpyKFAuVWssW1AuQ1YsUC5aaSxQLmJ5XSkKcyhQLndJLFAua1QpCnIoUC53SSxbUC5VOCxQLk14
+LFAuRTMsUC5HWV0pCnMoUC51NSxQLlppKQpyKFAubGYsW1AuQ1AsUC5JZl0pCnIoUC5BVCxbUC5iSixQ
+LmVZXSkKcyhQLnFlLFAuRG4pCnIoVy5EMCxbVy51SCxXLndhLFcuSzUsVy5DbV0pCnIoVy51SCxbVy5j
+dixXLm54LFcuUUYsVy5DUV0pCnIoVy5jdixbVy5xRSxQLmQ1XSkKcihXLnFFLFtXLkdoLFcuZlksVy5u
+QixXLlFQLFcuaDQsVy5TTixXLmxwLFcuVGIsVy5JdixXLldQLFcueVldKQpzKFcub0osVy5MZSkKcyhX
+LlQ1LFcuQXopCnMoVy5WYixXLlFGKQpzKFcuZkosVy53YSkKcihXLmVhLFtXLnc2LFcuZXddKQpzKFcu
+T0ssVy53NikKcyhXLnJCLFcuSzcpCnMoVy5CSCxXLnJCKQpzKFcudzQsVy5JQikKcyhXLm9hLFcuWFcp
+CnMoVy5yaCxXLm9hKQpzKFcuaTcsVy5jZikKcyhQLkFzLFAuVmopCnIoUC5BcyxbVy5JNCxQLktlXSkK
+cyhXLlJPLFAucWgpCnMoVy5ldSxXLlJPKQpzKFcueEMsUC5NTykKcyhXLmN0LFcubTYpCnMoUC5CZixQ
+LmlKKQpyKFAuRTQsW1AucjcsUC5jb10pCnMoUC5UeixQLmNvKQpzKFAuYkIsUC5kNSkKcyhCLmZ2LE8u
+ekwpCnIoQi5mdixbRS5PRixGLnJ1LEwuSVZdKQp0KEgudzIsSC5SZSkKdChILlJHLFAubEQpCnQoSC5W
+UCxILlNVKQp0KEguV0IsUC5sRCkKdChILlpHLEguU1UpCnQoUC5uWSxQLmxEKQp0KFAuVEMsUC5NYSkK
+dChQLlJVLFAuS1ApCnQoVy5MZSxXLmlkKQp0KFcuSzcsUC5sRCkKdChXLnJCLFcuR20pCnQoVy5YVyxQ
+LmxEKQp0KFcub2EsVy5HbSkKdChQLmNvLFAubEQpfSkoKQp2YXIgdj17dHlwZVVuaXZlcnNlOntlQzpu
+ZXcgTWFwKCksdFI6e30sZVQ6e30sdFBWOnt9LHNFQTpbXX0sbWFuZ2xlZEdsb2JhbE5hbWVzOntJZjoi
+aW50IixDUDoiZG91YmxlIixsZjoibnVtIixxVToiU3RyaW5nIixhMjoiYm9vbCIsYzg6Ik51bGwiLHpN
+OiJMaXN0In0sbWFuZ2xlZE5hbWVzOnt9LGdldFR5cGVGcm9tTmFtZTpnZXRHbG9iYWxGcm9tTmFtZSxt
+ZXRhZGF0YTpbXSx0eXBlczpbImM4KCkiLCJ+KCkiLCJjOChALEApIiwiYzgoT0spIiwicVUocVUpIiwi
+YzgoY3YpIiwiQChAKSIsImEyKHFVKSIsImM4KHFVLHFVKSIsImM4KGZKKSIsIn4ofigpKSIsImEyKGN2
+LHFVLHFVLEpRKSIsImM4KEApIiwiYzgocVUsQCkiLCJjOChldykiLCJhMihrRikiLCJ+KHh1PHFVPiki
+LCJjOChlYSkiLCJ+KE9LKSIsIlowPHFVLHFVPihaMDxxVSxxVT4scVUpIiwiSWYoSWYsSWYpIiwiQChx
+VSkiLCJ+KHFVLHFVKSIsIm42KElmKSIsIm42KEAsQCkiLCJhMih1SCkiLCJAKEAscVUpIiwifihAKSIs
+IkAoZWEpIiwiYzgoQCxHeikiLCJjOChJZixAKSIsIn4odUgsdUgpIiwifihNaFtHel0pIiwiTWgoQCki
+LCJjOChNaCxHeikiLCJyNyhAKSIsIlR6PEA+KEApIiwiRTQoQCkiLCJ2czxAPihAKSIsImM4KE1oLE1o
+KSIsImM4KFowPHFVLE1oPikiLCJiODxjOD4oT0spIiwicVUoT0spIiwiQCgpIiwiYzgoR0QsQCkiLCJj
+OCh+KCkpIiwicVUoSWYpIiwifihxVSxJZikiLCJ+KHFVW0BdKSIsIk1oKE1oKSIsImEyKHh1PHFVPiki
+XSxpbnRlcmNlcHRvcnNCeVRhZzpudWxsLGxlYWZUYWdzOm51bGwsYXJyYXlSdGk6dHlwZW9mIFN5bWJv
+bD09ImZ1bmN0aW9uIiYmdHlwZW9mIFN5bWJvbCgpPT0ic3ltYm9sIj9TeW1ib2woIiR0aSIpOiIkdGki
+fQpILnhiKHYudHlwZVVuaXZlcnNlLEpTT04ucGFyc2UoJ3siYzUiOiJNRiIsImlDIjoiTUYiLCJrZCI6
+Ik1GIiwicngiOiJlYSIsImU1IjoiZWEiLCJZMCI6ImQ1IiwidHAiOiJkNSIsIkc4IjoiZXciLCJNciI6
+InFFIiwiZUwiOiJxRSIsIkkwIjoidUgiLCJocyI6InVIIiwiWGciOiJRRiIsInljIjoiT0siLCJ5NCI6
+Inc2IiwiYVAiOiJDbSIsInhjIjoibngiLCJrSiI6Im54IiwielUiOiJEZyIsImRmIjoicEYiLCJ5RSI6
+eyJhMiI6W119LCJZRSI6eyJjOCI6W119LCJNRiI6eyJ2bSI6W10sIkVIIjpbXX0sImpkIjp7InpNIjpb
+IjEiXSwiYlEiOlsiMSJdLCJjWCI6WyIxIl19LCJQbyI6eyJqZCI6WyIxIl0sInpNIjpbIjEiXSwiYlEi
+OlsiMSJdLCJjWCI6WyIxIl19LCJtMSI6eyJBbiI6WyIxIl19LCJxSSI6eyJDUCI6W10sImxmIjpbXX0s
+InVyIjp7IklmIjpbXSwiQ1AiOltdLCJsZiI6W119LCJWQSI6eyJDUCI6W10sImxmIjpbXX0sIkRyIjp7
+InFVIjpbXSwidlgiOltdfSwibmQiOnsiWFMiOltdfSwicWoiOnsiUmUiOlsiSWYiXSwibEQiOlsiSWYi
+XSwiek0iOlsiSWYiXSwiYlEiOlsiSWYiXSwiY1giOlsiSWYiXSwibEQuRSI6IklmIiwiUmUuRSI6Iklm
+In0sImJRIjp7ImNYIjpbIjEiXX0sImFMIjp7ImJRIjpbIjEiXSwiY1giOlsiMSJdfSwibkgiOnsiYUwi
+OlsiMSJdLCJiUSI6WyIxIl0sImNYIjpbIjEiXSwiYUwuRSI6IjEiLCJjWC5FIjoiMSJ9LCJhNyI6eyJB
+biI6WyIxIl19LCJpMSI6eyJjWCI6WyIyIl0sImNYLkUiOiIyIn0sInh5Ijp7ImkxIjpbIjEiLCIyIl0s
+ImJRIjpbIjIiXSwiY1giOlsiMiJdLCJjWC5FIjoiMiJ9LCJNSCI6eyJBbiI6WyIyIl19LCJsSiI6eyJh
+TCI6WyIyIl0sImJRIjpbIjIiXSwiY1giOlsiMiJdLCJhTC5FIjoiMiIsImNYLkUiOiIyIn0sIlU1Ijp7
+ImNYIjpbIjEiXSwiY1guRSI6IjEifSwidkciOnsiQW4iOlsiMSJdfSwidzIiOnsiUmUiOlsiMSJdLCJs
+RCI6WyIxIl0sInpNIjpbIjEiXSwiYlEiOlsiMSJdLCJjWCI6WyIxIl19LCJ3diI6eyJHRCI6W119LCJQ
+RCI6eyJHaiI6WyIxIiwiMiJdLCJSVSI6WyIxIiwiMiJdLCJQbiI6WyIxIiwiMiJdLCJLUCI6WyIxIiwi
+MiJdLCJaMCI6WyIxIiwiMiJdfSwiV1UiOnsiWjAiOlsiMSIsIjIiXX0sIkxQIjp7IldVIjpbIjEiLCIy
+Il0sIlowIjpbIjEiLCIyIl19LCJYUiI6eyJjWCI6WyIxIl0sImNYLkUiOiIxIn0sIkxJIjp7InZRIjpb
+XX0sIlcwIjp7IlhTIjpbXX0sImF6Ijp7IlhTIjpbXX0sInZWIjp7IlhTIjpbXX0sIlhPIjp7Ikd6Ijpb
+XX0sIlRwIjp7IkVIIjpbXX0sImxjIjp7IkVIIjpbXX0sInp4Ijp7IkVIIjpbXX0sImp5Ijp7IkVIIjpb
+XX0sIkVxIjp7IlhTIjpbXX0sImtZIjp7IlhTIjpbXX0sIk41Ijp7IkZvIjpbIjEiLCIyIl0sIllrIjpb
+IjEiLCIyIl0sIlowIjpbIjEiLCIyIl0sIllrLksiOiIxIiwiWWsuViI6IjIifSwiaTUiOnsiYlEiOlsi
+MSJdLCJjWCI6WyIxIl0sImNYLkUiOiIxIn0sIk42Ijp7IkFuIjpbIjEiXX0sIlZSIjp7IndMIjpbXSwi
+dlgiOltdfSwiRUsiOnsiaWIiOltdLCJPZCI6W119LCJLVyI6eyJjWCI6WyJpYiJdLCJjWC5FIjoiaWIi
+fSwiUGIiOnsiQW4iOlsiaWIiXX0sInRRIjp7Ik9kIjpbXX0sIk5GIjp7ImNYIjpbIk9kIl0sImNYLkUi
+OiJPZCJ9LCJTZCI6eyJBbiI6WyJPZCJdfSwicEYiOnsiQVMiOltdfSwiYjAiOnsiWGoiOlsiMSJdLCJw
+RiI6W10sIkFTIjpbXX0sIkRnIjp7ImxEIjpbIkNQIl0sIlhqIjpbIkNQIl0sInpNIjpbIkNQIl0sInBG
+IjpbXSwiYlEiOlsiQ1AiXSwiU1UiOlsiQ1AiXSwiQVMiOltdLCJjWCI6WyJDUCJdLCJsRC5FIjoiQ1Ai
+fSwiUGciOnsibEQiOlsiSWYiXSwiek0iOlsiSWYiXSwiWGoiOlsiSWYiXSwicEYiOltdLCJiUSI6WyJJ
+ZiJdLCJTVSI6WyJJZiJdLCJBUyI6W10sImNYIjpbIklmIl19LCJ4aiI6eyJsRCI6WyJJZiJdLCJ6TSI6
+WyJJZiJdLCJYaiI6WyJJZiJdLCJwRiI6W10sImJRIjpbIklmIl0sIlNVIjpbIklmIl0sIkFTIjpbXSwi
+Y1giOlsiSWYiXSwibEQuRSI6IklmIn0sImRFIjp7ImxEIjpbIklmIl0sInpNIjpbIklmIl0sIlhqIjpb
+IklmIl0sInBGIjpbXSwiYlEiOlsiSWYiXSwiU1UiOlsiSWYiXSwiQVMiOltdLCJjWCI6WyJJZiJdLCJs
+RC5FIjoiSWYifSwiWkEiOnsibEQiOlsiSWYiXSwiek0iOlsiSWYiXSwiWGoiOlsiSWYiXSwicEYiOltd
+LCJiUSI6WyJJZiJdLCJTVSI6WyJJZiJdLCJBUyI6W10sImNYIjpbIklmIl0sImxELkUiOiJJZiJ9LCJ3
+ZiI6eyJsRCI6WyJJZiJdLCJ6TSI6WyJJZiJdLCJYaiI6WyJJZiJdLCJwRiI6W10sImJRIjpbIklmIl0s
+IlNVIjpbIklmIl0sIkFTIjpbXSwiY1giOlsiSWYiXSwibEQuRSI6IklmIn0sIlBxIjp7ImxEIjpbIklm
+Il0sInpNIjpbIklmIl0sIlhqIjpbIklmIl0sInBGIjpbXSwiYlEiOlsiSWYiXSwiU1UiOlsiSWYiXSwi
+QVMiOltdLCJjWCI6WyJJZiJdLCJsRC5FIjoiSWYifSwiZUUiOnsibEQiOlsiSWYiXSwiek0iOlsiSWYi
+XSwiWGoiOlsiSWYiXSwicEYiOltdLCJiUSI6WyJJZiJdLCJTVSI6WyJJZiJdLCJBUyI6W10sImNYIjpb
+IklmIl0sImxELkUiOiJJZiJ9LCJWNiI6eyJuNiI6W10sImxEIjpbIklmIl0sInpNIjpbIklmIl0sIlhq
+IjpbIklmIl0sInBGIjpbXSwiYlEiOlsiSWYiXSwiU1UiOlsiSWYiXSwiQVMiOltdLCJjWCI6WyJJZiJd
+LCJsRC5FIjoiSWYifSwidTkiOnsiWFMiOltdfSwieCI6eyJYUyI6W119LCJHViI6eyJBbiI6WyIxIl19
+LCJxNCI6eyJjWCI6WyIxIl0sImNYLkUiOiIxIn0sIlpmIjp7IlBmIjpbIjEiXX0sInZzIjp7ImI4Ijpb
+IjEiXX0sIk9IIjp7IlhTIjpbXX0sIm0wIjp7IkpCIjpbXX0sIkppIjp7Im0wIjpbXSwiSkIiOltdfSwi
+YjYiOnsiWHYiOlsiMSJdLCJ4dSI6WyIxIl0sImJRIjpbIjEiXSwiY1giOlsiMSJdfSwibG0iOnsiQW4i
+OlsiMSJdfSwibVciOnsiY1giOlsiMSJdfSwiTFUiOnsibEQiOlsiMSJdLCJ6TSI6WyIxIl0sImJRIjpb
+IjEiXSwiY1giOlsiMSJdfSwiaWwiOnsiWWsiOlsiMSIsIjIiXSwiWjAiOlsiMSIsIjIiXX0sIllrIjp7
+IlowIjpbIjEiLCIyIl19LCJQbiI6eyJaMCI6WyIxIiwiMiJdfSwiR2oiOnsiUlUiOlsiMSIsIjIiXSwi
+UG4iOlsiMSIsIjIiXSwiS1AiOlsiMSIsIjIiXSwiWjAiOlsiMSIsIjIiXX0sIlZqIjp7Ik1hIjpbIjEi
+XSwieHUiOlsiMSJdLCJiUSI6WyIxIl0sImNYIjpbIjEiXX0sIlh2Ijp7Inh1IjpbIjEiXSwiYlEiOlsi
+MSJdLCJjWCI6WyIxIl19LCJ1dyI6eyJZayI6WyJxVSIsIkAiXSwiWjAiOlsicVUiLCJAIl0sIllrLksi
+OiJxVSIsIllrLlYiOiJAIn0sImk4Ijp7ImFMIjpbInFVIl0sImJRIjpbInFVIl0sImNYIjpbInFVIl0s
+ImFMLkUiOiJxVSIsImNYLkUiOiJxVSJ9LCJDViI6eyJVayI6WyJ6TTxJZj4iLCJxVSJdLCJVay5TIjoi
+ek08SWY+In0sIlU4Ijp7IndJIjpbInpNPElmPiIsInFVIl19LCJaaSI6eyJVayI6WyJxVSIsInpNPElm
+PiJdfSwiYnkiOnsiVWsiOlsiTWgiLCJxVSJdLCJVay5TIjoiTWgifSwiTXgiOnsid0kiOlsicVUiLCJN
+aCJdfSwidTUiOnsiVWsiOlsicVUiLCJ6TTxJZj4iXSwiVWsuUyI6InFVIn0sIkUzIjp7IndJIjpbInFV
+Iiwiek08SWY+Il19LCJHWSI6eyJ3SSI6WyJ6TTxJZj4iLCJxVSJdfSwiQ1AiOnsibGYiOltdfSwiQzYi
+OnsiWFMiOltdfSwiTEsiOnsiWFMiOltdfSwiQVQiOnsiWFMiOltdfSwiYkoiOnsiWFMiOltdfSwiZVki
+OnsiWFMiOltdfSwibXAiOnsiWFMiOltdfSwidWIiOnsiWFMiOltdfSwiZHMiOnsiWFMiOltdfSwibGoi
+OnsiWFMiOltdfSwiVVYiOnsiWFMiOltdfSwiazUiOnsiWFMiOltdfSwiS1kiOnsiWFMiOltdfSwidDci
+OnsiWFMiOltdfSwiSWYiOnsibGYiOltdfSwiek0iOnsiYlEiOlsiMSJdLCJjWCI6WyIxIl19LCJpYiI6
+eyJPZCI6W119LCJ4dSI6eyJiUSI6WyIxIl0sImNYIjpbIjEiXX0sIlpkIjp7Ikd6IjpbXX0sInFVIjp7
+InZYIjpbXX0sIlJuIjp7IkJMIjpbXX0sIkRuIjp7ImlEIjpbXX0sIlVmIjp7ImlEIjpbXX0sInFlIjp7
+ImlEIjpbXX0sInFFIjp7ImN2IjpbXSwidUgiOltdLCJEMCI6W119LCJHaCI6eyJjdiI6W10sInVIIjpb
+XSwiRDAiOltdfSwiZlkiOnsiY3YiOltdLCJ1SCI6W10sIkQwIjpbXX0sIm5CIjp7ImN2IjpbXSwidUgi
+OltdLCJEMCI6W119LCJRUCI6eyJjdiI6W10sInVIIjpbXSwiRDAiOltdfSwibngiOnsidUgiOltdLCJE
+MCI6W119LCJRRiI6eyJ1SCI6W10sIkQwIjpbXX0sIklCIjp7InRuIjpbImxmIl19LCJ3eiI6eyJsRCI6
+WyIxIl0sInpNIjpbIjEiXSwiYlEiOlsiMSJdLCJjWCI6WyIxIl0sImxELkUiOiIxIn0sImN2Ijp7InVI
+IjpbXSwiRDAiOltdfSwiVDUiOnsiQXoiOltdfSwiaDQiOnsiY3YiOltdLCJ1SCI6W10sIkQwIjpbXX0s
+IlZiIjp7InVIIjpbXSwiRDAiOltdfSwiZkoiOnsiRDAiOltdfSwid2EiOnsiRDAiOltdfSwiT0siOnsi
+ZWEiOltdfSwiZTciOnsibEQiOlsidUgiXSwiek0iOlsidUgiXSwiYlEiOlsidUgiXSwiY1giOlsidUgi
+XSwibEQuRSI6InVIIn0sInVIIjp7IkQwIjpbXX0sIkJIIjp7IkdtIjpbInVIIl0sImxEIjpbInVIIl0s
+InpNIjpbInVIIl0sIlhqIjpbInVIIl0sImJRIjpbInVIIl0sImNYIjpbInVIIl0sIkdtLkUiOiJ1SCIs
+ImxELkUiOiJ1SCJ9LCJTTiI6eyJjdiI6W10sInVIIjpbXSwiRDAiOltdfSwiZXciOnsiZWEiOltdfSwi
+bHAiOnsiY3YiOltdLCJ1SCI6W10sIkQwIjpbXX0sIlRiIjp7ImN2IjpbXSwidUgiOltdLCJEMCI6W119
+LCJJdiI6eyJjdiI6W10sInVIIjpbXSwiRDAiOltdfSwiV1AiOnsiY3YiOltdLCJ1SCI6W10sIkQwIjpb
+XX0sInlZIjp7ImN2IjpbXSwidUgiOltdLCJEMCI6W119LCJ3NiI6eyJlYSI6W119LCJLNSI6eyJ2NiI6
+W10sIkQwIjpbXX0sIkNtIjp7IkQwIjpbXX0sIkNRIjp7InVIIjpbXSwiRDAiOltdfSwidzQiOnsidG4i
+OlsibGYiXX0sInJoIjp7IkdtIjpbInVIIl0sImxEIjpbInVIIl0sInpNIjpbInVIIl0sIlhqIjpbInVI
+Il0sImJRIjpbInVIIl0sImNYIjpbInVIIl0sIkdtLkUiOiJ1SCIsImxELkUiOiJ1SCJ9LCJjZiI6eyJZ
+ayI6WyJxVSIsInFVIl0sIlowIjpbInFVIiwicVUiXX0sImk3Ijp7IllrIjpbInFVIiwicVUiXSwiWjAi
+OlsicVUiLCJxVSJdLCJZay5LIjoicVUiLCJZay5WIjoicVUifSwiU3kiOnsiWWsiOlsicVUiLCJxVSJd
+LCJaMCI6WyJxVSIsInFVIl0sIllrLksiOiJxVSIsIllrLlYiOiJxVSJ9LCJJNCI6eyJNYSI6WyJxVSJd
+LCJ4dSI6WyJxVSJdLCJiUSI6WyJxVSJdLCJjWCI6WyJxVSJdfSwiUk8iOnsicWgiOlsiMSJdfSwiZXUi
+OnsiUk8iOlsiMSJdLCJxaCI6WyIxIl19LCJ4QyI6eyJNTyI6WyIxIl19LCJKUSI6eyJrRiI6W119LCJ2
+RCI6eyJrRiI6W119LCJtNiI6eyJrRiI6W119LCJjdCI6eyJrRiI6W119LCJPdyI6eyJrRiI6W119LCJX
+OSI6eyJBbiI6WyIxIl19LCJkVyI6eyJ2NiI6W10sIkQwIjpbXX0sIm1rIjp7InkwIjpbXX0sIktvIjp7
+Im9uIjpbXX0sIkFzIjp7Ik1hIjpbInFVIl0sInh1IjpbInFVIl0sImJRIjpbInFVIl0sImNYIjpbInFV
+Il19LCJyNyI6eyJFNCI6W119LCJUeiI6eyJsRCI6WyIxIl0sInpNIjpbIjEiXSwiYlEiOlsiMSJdLCJF
+NCI6W10sImNYIjpbIjEiXSwibEQuRSI6IjEifSwiYkIiOnsiZDUiOltdLCJjdiI6W10sInVIIjpbXSwi
+RDAiOltdfSwiS2UiOnsiTWEiOlsicVUiXSwieHUiOlsicVUiXSwiYlEiOlsicVUiXSwiY1giOlsicVUi
+XX0sImQ1Ijp7ImN2IjpbXSwidUgiOltdLCJEMCI6W119LCJuNiI6eyJ6TSI6WyJJZiJdLCJiUSI6WyJJ
+ZiJdLCJBUyI6W10sImNYIjpbIklmIl19LCJYQSI6eyJrRiI6W119LCJPRiI6eyJmdiI6W119LCJydSI6
+eyJmdiI6W119LCJJViI6eyJmdiI6W119fScpKQpILkZGKHYudHlwZVVuaXZlcnNlLEpTT04ucGFyc2Uo
+J3siYlEiOjEsIncyIjoxLCJiMCI6MSwia1QiOjIsIm1XIjoxLCJMVSI6MSwiaWwiOjIsIlZqIjoxLCJu
+WSI6MSwiVEMiOjEsImNvIjoxfScpKQp2YXIgdT0oZnVuY3Rpb24gcnRpaSgpe3ZhciB0PUguTjAKcmV0
+dXJue2JxOnQoIkdoIiksbjp0KCJPSCIpLGNSOnQoIm5CIiksZDp0KCJBeiIpLGk6dCgiUVAiKSxnRjp0
+KCJQRDxHRCxAPiIpLGd3OnQoImJRPEA+IiksaDp0KCJjdiIpLFc6dCgiWFMiKSxCOnQoImVhIiksdTp0
+KCJEMCIpLGM4OnQoIlQ1IiksWjp0KCJFSCIpLGFROnQoImI4PGM4PiIpLGM6dCgiYjg8QD4iKSxyOnQo
+ImZKIiksSTp0KCJTZyIpLG86dCgidlEiKSxlaDp0KCJjWDx1SD4iKSxYOnQoImNYPHFVPiIpLFI6dCgi
+Y1g8QD4iKSxmQTp0KCJqZDxTZT4iKSxnaTp0KCJqZDxqOD4iKSxmaDp0KCJqZDxaWj4iKSxrOnQoImpk
+PGtGPiIpLHM6dCgiamQ8cVU+IiksaGg6dCgiamQ8eUQ+IiksYUo6dCgiamQ8d2I+Iiksdjp0KCJqZDxA
+PiIpLHQ6dCgiamQ8SWY+IiksZUg6dCgidm0iKSxnOnQoImM1IiksYVU6dCgiWGo8QD4iKSxhbTp0KCJU
+ejxAPiIpLGVvOnQoIk41PEdELEA+IiksaGI6dCgiRTQiKSxkejp0KCJoRiIpLGY0OnQoInpNPGo4PiIp
+LGE6dCgiek08cVU+Iiksajp0KCJ6TTxAPiIpLEw6dCgiek08SWY+IiksYV86dCgidTgiKSxTOnQoIlow
+PHFVLE1oPiIpLGY6dCgiWjA8cVUscVU+IiksYjp0KCJaMDxxVSxAPiIpLEc6dCgiWjA8QCxAPiIpLGR2
+OnQoImxKPHFVLHFVPiIpLGRvOnQoImxKPHFVLEA+IiksVjp0KCJPSyIpLGREOnQoInBGIiksYm06dCgi
+VjYiKSxBOnQoInVIIiksZTp0KCJrRiIpLFA6dCgiYzgiKSxLOnQoIk1oIiksY2E6dCgiTWgoTWgsTWgp
+IikscDp0KCJldyIpLE86dCgidG48bGY+IiksZnY6dCgid0wiKSxldzp0KCJiQiIpLEM6dCgieHU8cVU+
+IiksbDp0KCJHeiIpLE46dCgicVUiKSxkRzp0KCJxVShxVSkiKSxnNzp0KCJkNSIpLGZvOnQoIkdEIiks
+YVc6dCgieVkiKSx3OnQoIkFTIiksZ2M6dCgibjYiKSxhazp0KCJrZCIpLEQ6dCgiR2o8cVUscVU+Iiks
+Rjp0KCJpRCIpLGNjOnQoIlU1PHFVPiIpLGc0OnQoIks1IiksY2k6dCgidjYiKSxnMjp0KCJDbSIpLEU6
+dCgiWmY8Zko+IiksaDk6dCgiQ1EiKSxhYzp0KCJlNyIpLFE6dCgiZXU8T0s+IiksVDp0KCJ3ejxjdj4i
+KSx4OnQoIkZlPEAsQD4iKSxZOnQoInZzPGZKPiIpLF86dCgidnM8QD4iKSxmSjp0KCJ2czxJZj4iKSxj
+cjp0KCJKUSIpLEo6dCgiYm4iKSx5OnQoImEyIiksbTp0KCJhMihNaCkiKSxiQjp0KCJhMihxVSkiKSxn
+Ujp0KCJDUCIpLHo6dCgiQCIpLGZPOnQoIkAoKSIpLFU6dCgiQChlYSkiKSxiSTp0KCJAKE1oKSIpLGFn
+OnQoIkAoTWgsR3opIiksYlU6dCgiQCh4dTxxVT4pIiksZE86dCgiQChxVSkiKSxiODp0KCJAKEAsQCki
+KSxxOnQoIklmIiksYXc6dCgiMCYqIiksZGk6dCgibGYiKSxIOnQoIn4iKSxNOnQoIn4oKSIpLGFuOnQo
+In4oZXcpIiksZUE6dCgifihxVSxxVSkiKSxjQTp0KCJ+KHFVLEApIil9fSkoKTsoZnVuY3Rpb24gY29u
+c3RhbnRzKCl7dmFyIHQ9aHVua0hlbHBlcnMubWFrZUNvbnN0TGlzdApDLlJZPVcuUVAucHJvdG90eXBl
+CkMuQlo9Vy5WYi5wcm90b3R5cGUKQy5EdD1XLmZKLnByb3RvdHlwZQpDLk9rPUoudkIucHJvdG90eXBl
+CkMuTm09Si5qZC5wcm90b3R5cGUKQy5qbj1KLnVyLnByb3RvdHlwZQpDLkNEPUoucUkucHJvdG90eXBl
+CkMueEI9Si5Eci5wcm90b3R5cGUKQy5ERz1KLmM1LnByb3RvdHlwZQpDLkV4PVcudTgucHJvdG90eXBl
+CkMuTHQ9Vy5TTi5wcm90b3R5cGUKQy5aUT1KLmlDLnByb3RvdHlwZQpDLkllPVcuVGIucHJvdG90eXBl
+CkMudkI9Si5rZC5wcm90b3R5cGUKQy5vbD1XLks1LnByb3RvdHlwZQpDLnk4PW5ldyBQLlU4KCkKQy5o
+OT1uZXcgUC5DVigpCkMud2I9ZnVuY3Rpb24gZ2V0VGFnRmFsbGJhY2sobykgewogIHZhciBzID0gT2Jq
+ZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKG8pOwogIHJldHVybiBzLnN1YnN0cmluZyg4LCBzLmxl
+bmd0aCAtIDEpOwp9CkMuTzQ9ZnVuY3Rpb24oKSB7CiAgdmFyIHRvU3RyaW5nRnVuY3Rpb24gPSBPYmpl
+Y3QucHJvdG90eXBlLnRvU3RyaW5nOwogIGZ1bmN0aW9uIGdldFRhZyhvKSB7CiAgICB2YXIgcyA9IHRv
+U3RyaW5nRnVuY3Rpb24uY2FsbChvKTsKICAgIHJldHVybiBzLnN1YnN0cmluZyg4LCBzLmxlbmd0aCAt
+IDEpOwogIH0KICBmdW5jdGlvbiBnZXRVbmtub3duVGFnKG9iamVjdCwgdGFnKSB7CiAgICBpZiAoL15I
+VE1MW0EtWl0uKkVsZW1lbnQkLy50ZXN0KHRhZykpIHsKICAgICAgdmFyIG5hbWUgPSB0b1N0cmluZ0Z1
+bmN0aW9uLmNhbGwob2JqZWN0KTsKICAgICAgaWYgKG5hbWUgPT0gIltvYmplY3QgT2JqZWN0XSIpIHJl
+dHVybiBudWxsOwogICAgICByZXR1cm4gIkhUTUxFbGVtZW50IjsKICAgIH0KICB9CiAgZnVuY3Rpb24g
+Z2V0VW5rbm93blRhZ0dlbmVyaWNCcm93c2VyKG9iamVjdCwgdGFnKSB7CiAgICBpZiAoc2VsZi5IVE1M
+RWxlbWVudCAmJiBvYmplY3QgaW5zdGFuY2VvZiBIVE1MRWxlbWVudCkgcmV0dXJuICJIVE1MRWxlbWVu
+dCI7CiAgICByZXR1cm4gZ2V0VW5rbm93blRhZyhvYmplY3QsIHRhZyk7CiAgfQogIGZ1bmN0aW9uIHBy
+b3RvdHlwZUZvclRhZyh0YWcpIHsKICAgIGlmICh0eXBlb2Ygd2luZG93ID09ICJ1bmRlZmluZWQiKSBy
+ZXR1cm4gbnVsbDsKICAgIGlmICh0eXBlb2Ygd2luZG93W3RhZ10gPT0gInVuZGVmaW5lZCIpIHJldHVy
+biBudWxsOwogICAgdmFyIGNvbnN0cnVjdG9yID0gd2luZG93W3RhZ107CiAgICBpZiAodHlwZW9mIGNv
+bnN0cnVjdG9yICE9ICJmdW5jdGlvbiIpIHJldHVybiBudWxsOwogICAgcmV0dXJuIGNvbnN0cnVjdG9y
+LnByb3RvdHlwZTsKICB9CiAgZnVuY3Rpb24gZGlzY3JpbWluYXRvcih0YWcpIHsgcmV0dXJuIG51bGw7
+IH0KICB2YXIgaXNCcm93c2VyID0gdHlwZW9mIG5hdmlnYXRvciA9PSAib2JqZWN0IjsKICByZXR1cm4g
+ewogICAgZ2V0VGFnOiBnZXRUYWcsCiAgICBnZXRVbmtub3duVGFnOiBpc0Jyb3dzZXIgPyBnZXRVbmtu
+b3duVGFnR2VuZXJpY0Jyb3dzZXIgOiBnZXRVbmtub3duVGFnLAogICAgcHJvdG90eXBlRm9yVGFnOiBw
+cm90b3R5cGVGb3JUYWcsCiAgICBkaXNjcmltaW5hdG9yOiBkaXNjcmltaW5hdG9yIH07Cn0KQy5kaz1m
+dW5jdGlvbihnZXRUYWdGYWxsYmFjaykgewogIHJldHVybiBmdW5jdGlvbihob29rcykgewogICAgaWYg
+KHR5cGVvZiBuYXZpZ2F0b3IgIT0gIm9iamVjdCIpIHJldHVybiBob29rczsKICAgIHZhciB1YSA9IG5h
+dmlnYXRvci51c2VyQWdlbnQ7CiAgICBpZiAodWEuaW5kZXhPZigiRHVtcFJlbmRlclRyZWUiKSA+PSAw
+KSByZXR1cm4gaG9va3M7CiAgICBpZiAodWEuaW5kZXhPZigiQ2hyb21lIikgPj0gMCkgewogICAgICBm
+dW5jdGlvbiBjb25maXJtKHApIHsKICAgICAgICByZXR1cm4gdHlwZW9mIHdpbmRvdyA9PSAib2JqZWN0
+IiAmJiB3aW5kb3dbcF0gJiYgd2luZG93W3BdLm5hbWUgPT0gcDsKICAgICAgfQogICAgICBpZiAoY29u
+ZmlybSgiV2luZG93IikgJiYgY29uZmlybSgiSFRNTEVsZW1lbnQiKSkgcmV0dXJuIGhvb2tzOwogICAg
+fQogICAgaG9va3MuZ2V0VGFnID0gZ2V0VGFnRmFsbGJhY2s7CiAgfTsKfQpDLllxPWZ1bmN0aW9uKGhv
+b2tzKSB7CiAgaWYgKHR5cGVvZiBkYXJ0RXhwZXJpbWVudGFsRml4dXBHZXRUYWcgIT0gImZ1bmN0aW9u
+IikgcmV0dXJuIGhvb2tzOwogIGhvb2tzLmdldFRhZyA9IGRhcnRFeHBlcmltZW50YWxGaXh1cEdldFRh
+Zyhob29rcy5nZXRUYWcpOwp9CkMuS1U9ZnVuY3Rpb24oaG9va3MpIHsKICB2YXIgZ2V0VGFnID0gaG9v
+a3MuZ2V0VGFnOwogIHZhciBwcm90b3R5cGVGb3JUYWcgPSBob29rcy5wcm90b3R5cGVGb3JUYWc7CiAg
+ZnVuY3Rpb24gZ2V0VGFnRml4ZWQobykgewogICAgdmFyIHRhZyA9IGdldFRhZyhvKTsKICAgIGlmICh0
+YWcgPT0gIkRvY3VtZW50IikgewogICAgICBpZiAoISFvLnhtbFZlcnNpb24pIHJldHVybiAiIURvY3Vt
+ZW50IjsKICAgICAgcmV0dXJuICIhSFRNTERvY3VtZW50IjsKICAgIH0KICAgIHJldHVybiB0YWc7CiAg
+fQogIGZ1bmN0aW9uIHByb3RvdHlwZUZvclRhZ0ZpeGVkKHRhZykgewogICAgaWYgKHRhZyA9PSAiRG9j
+dW1lbnQiKSByZXR1cm4gbnVsbDsKICAgIHJldHVybiBwcm90b3R5cGVGb3JUYWcodGFnKTsKICB9CiAg
+aG9va3MuZ2V0VGFnID0gZ2V0VGFnRml4ZWQ7CiAgaG9va3MucHJvdG90eXBlRm9yVGFnID0gcHJvdG90
+eXBlRm9yVGFnRml4ZWQ7Cn0KQy54aT1mdW5jdGlvbihob29rcykgewogIHZhciB1c2VyQWdlbnQgPSB0
+eXBlb2YgbmF2aWdhdG9yID09ICJvYmplY3QiID8gbmF2aWdhdG9yLnVzZXJBZ2VudCA6ICIiOwogIGlm
+ICh1c2VyQWdlbnQuaW5kZXhPZigiRmlyZWZveCIpID09IC0xKSByZXR1cm4gaG9va3M7CiAgdmFyIGdl
+dFRhZyA9IGhvb2tzLmdldFRhZzsKICB2YXIgcXVpY2tNYXAgPSB7CiAgICAiQmVmb3JlVW5sb2FkRXZl
+bnQiOiAiRXZlbnQiLAogICAgIkRhdGFUcmFuc2ZlciI6ICJDbGlwYm9hcmQiLAogICAgIkdlb0dlb2xv
+Y2F0aW9uIjogIkdlb2xvY2F0aW9uIiwKICAgICJMb2NhdGlvbiI6ICIhTG9jYXRpb24iLAogICAgIldv
+cmtlck1lc3NhZ2VFdmVudCI6ICJNZXNzYWdlRXZlbnQiLAogICAgIlhNTERvY3VtZW50IjogIiFEb2N1
+bWVudCJ9OwogIGZ1bmN0aW9uIGdldFRhZ0ZpcmVmb3gobykgewogICAgdmFyIHRhZyA9IGdldFRhZyhv
+KTsKICAgIHJldHVybiBxdWlja01hcFt0YWddIHx8IHRhZzsKICB9CiAgaG9va3MuZ2V0VGFnID0gZ2V0
+VGFnRmlyZWZveDsKfQpDLmk3PWZ1bmN0aW9uKGhvb2tzKSB7CiAgdmFyIHVzZXJBZ2VudCA9IHR5cGVv
+ZiBuYXZpZ2F0b3IgPT0gIm9iamVjdCIgPyBuYXZpZ2F0b3IudXNlckFnZW50IDogIiI7CiAgaWYgKHVz
+ZXJBZ2VudC5pbmRleE9mKCJUcmlkZW50LyIpID09IC0xKSByZXR1cm4gaG9va3M7CiAgdmFyIGdldFRh
+ZyA9IGhvb2tzLmdldFRhZzsKICB2YXIgcXVpY2tNYXAgPSB7CiAgICAiQmVmb3JlVW5sb2FkRXZlbnQi
+OiAiRXZlbnQiLAogICAgIkRhdGFUcmFuc2ZlciI6ICJDbGlwYm9hcmQiLAogICAgIkhUTUxEREVsZW1l
+bnQiOiAiSFRNTEVsZW1lbnQiLAogICAgIkhUTUxEVEVsZW1lbnQiOiAiSFRNTEVsZW1lbnQiLAogICAg
+IkhUTUxQaHJhc2VFbGVtZW50IjogIkhUTUxFbGVtZW50IiwKICAgICJQb3NpdGlvbiI6ICJHZW9wb3Np
+dGlvbiIKICB9OwogIGZ1bmN0aW9uIGdldFRhZ0lFKG8pIHsKICAgIHZhciB0YWcgPSBnZXRUYWcobyk7
+CiAgICB2YXIgbmV3VGFnID0gcXVpY2tNYXBbdGFnXTsKICAgIGlmIChuZXdUYWcpIHJldHVybiBuZXdU
+YWc7CiAgICBpZiAodGFnID09ICJPYmplY3QiKSB7CiAgICAgIGlmICh3aW5kb3cuRGF0YVZpZXcgJiYg
+KG8gaW5zdGFuY2VvZiB3aW5kb3cuRGF0YVZpZXcpKSByZXR1cm4gIkRhdGFWaWV3IjsKICAgIH0KICAg
+IHJldHVybiB0YWc7CiAgfQogIGZ1bmN0aW9uIHByb3RvdHlwZUZvclRhZ0lFKHRhZykgewogICAgdmFy
+IGNvbnN0cnVjdG9yID0gd2luZG93W3RhZ107CiAgICBpZiAoY29uc3RydWN0b3IgPT0gbnVsbCkgcmV0
+dXJuIG51bGw7CiAgICByZXR1cm4gY29uc3RydWN0b3IucHJvdG90eXBlOwogIH0KICBob29rcy5nZXRU
+YWcgPSBnZXRUYWdJRTsKICBob29rcy5wcm90b3R5cGVGb3JUYWcgPSBwcm90b3R5cGVGb3JUYWdJRTsK
+fQpDLmZRPWZ1bmN0aW9uKGhvb2tzKSB7IHJldHVybiBob29rczsgfQoKQy5DdD1uZXcgUC5ieSgpCkMu
+RXE9bmV3IFAuazUoKQpDLnhNPW5ldyBQLnU1KCkKQy5Raz1uZXcgUC5FMygpCkMuTlU9bmV3IFAuSmko
+KQpDLnBkPW5ldyBQLlpkKCkKQy5BMz1uZXcgUC5NeChudWxsKQpDLkdiPUguVk0odChbMTI3LDIwNDcs
+NjU1MzUsMTExNDExMV0pLHUudCkKQy5haz1ILlZNKHQoWzAsMCwzMjc3NiwzMzc5MiwxLDEwMjQwLDAs
+MF0pLHUudCkKQy5jbT1ILlZNKHQoWyIqOjpjbGFzcyIsIio6OmRpciIsIio6OmRyYWdnYWJsZSIsIio6
+OmhpZGRlbiIsIio6OmlkIiwiKjo6aW5lcnQiLCIqOjppdGVtcHJvcCIsIio6Oml0ZW1yZWYiLCIqOjpp
+dGVtc2NvcGUiLCIqOjpsYW5nIiwiKjo6c3BlbGxjaGVjayIsIio6OnRpdGxlIiwiKjo6dHJhbnNsYXRl
+IiwiQTo6YWNjZXNza2V5IiwiQTo6Y29vcmRzIiwiQTo6aHJlZmxhbmciLCJBOjpuYW1lIiwiQTo6c2hh
+cGUiLCJBOjp0YWJpbmRleCIsIkE6OnRhcmdldCIsIkE6OnR5cGUiLCJBUkVBOjphY2Nlc3NrZXkiLCJB
+UkVBOjphbHQiLCJBUkVBOjpjb29yZHMiLCJBUkVBOjpub2hyZWYiLCJBUkVBOjpzaGFwZSIsIkFSRUE6
+OnRhYmluZGV4IiwiQVJFQTo6dGFyZ2V0IiwiQVVESU86OmNvbnRyb2xzIiwiQVVESU86Omxvb3AiLCJB
+VURJTzo6bWVkaWFncm91cCIsIkFVRElPOjptdXRlZCIsIkFVRElPOjpwcmVsb2FkIiwiQkRPOjpkaXIi
+LCJCT0RZOjphbGluayIsIkJPRFk6OmJnY29sb3IiLCJCT0RZOjpsaW5rIiwiQk9EWTo6dGV4dCIsIkJP
+RFk6OnZsaW5rIiwiQlI6OmNsZWFyIiwiQlVUVE9OOjphY2Nlc3NrZXkiLCJCVVRUT046OmRpc2FibGVk
+IiwiQlVUVE9OOjpuYW1lIiwiQlVUVE9OOjp0YWJpbmRleCIsIkJVVFRPTjo6dHlwZSIsIkJVVFRPTjo6
+dmFsdWUiLCJDQU5WQVM6OmhlaWdodCIsIkNBTlZBUzo6d2lkdGgiLCJDQVBUSU9OOjphbGlnbiIsIkNP
+TDo6YWxpZ24iLCJDT0w6OmNoYXIiLCJDT0w6OmNoYXJvZmYiLCJDT0w6OnNwYW4iLCJDT0w6OnZhbGln
+biIsIkNPTDo6d2lkdGgiLCJDT0xHUk9VUDo6YWxpZ24iLCJDT0xHUk9VUDo6Y2hhciIsIkNPTEdST1VQ
+OjpjaGFyb2ZmIiwiQ09MR1JPVVA6OnNwYW4iLCJDT0xHUk9VUDo6dmFsaWduIiwiQ09MR1JPVVA6Ondp
+ZHRoIiwiQ09NTUFORDo6Y2hlY2tlZCIsIkNPTU1BTkQ6OmNvbW1hbmQiLCJDT01NQU5EOjpkaXNhYmxl
+ZCIsIkNPTU1BTkQ6OmxhYmVsIiwiQ09NTUFORDo6cmFkaW9ncm91cCIsIkNPTU1BTkQ6OnR5cGUiLCJE
+QVRBOjp2YWx1ZSIsIkRFTDo6ZGF0ZXRpbWUiLCJERVRBSUxTOjpvcGVuIiwiRElSOjpjb21wYWN0Iiwi
+RElWOjphbGlnbiIsIkRMOjpjb21wYWN0IiwiRklFTERTRVQ6OmRpc2FibGVkIiwiRk9OVDo6Y29sb3Ii
+LCJGT05UOjpmYWNlIiwiRk9OVDo6c2l6ZSIsIkZPUk06OmFjY2VwdCIsIkZPUk06OmF1dG9jb21wbGV0
+ZSIsIkZPUk06OmVuY3R5cGUiLCJGT1JNOjptZXRob2QiLCJGT1JNOjpuYW1lIiwiRk9STTo6bm92YWxp
+ZGF0ZSIsIkZPUk06OnRhcmdldCIsIkZSQU1FOjpuYW1lIiwiSDE6OmFsaWduIiwiSDI6OmFsaWduIiwi
+SDM6OmFsaWduIiwiSDQ6OmFsaWduIiwiSDU6OmFsaWduIiwiSDY6OmFsaWduIiwiSFI6OmFsaWduIiwi
+SFI6Om5vc2hhZGUiLCJIUjo6c2l6ZSIsIkhSOjp3aWR0aCIsIkhUTUw6OnZlcnNpb24iLCJJRlJBTUU6
+OmFsaWduIiwiSUZSQU1FOjpmcmFtZWJvcmRlciIsIklGUkFNRTo6aGVpZ2h0IiwiSUZSQU1FOjptYXJn
+aW5oZWlnaHQiLCJJRlJBTUU6Om1hcmdpbndpZHRoIiwiSUZSQU1FOjp3aWR0aCIsIklNRzo6YWxpZ24i
+LCJJTUc6OmFsdCIsIklNRzo6Ym9yZGVyIiwiSU1HOjpoZWlnaHQiLCJJTUc6OmhzcGFjZSIsIklNRzo6
+aXNtYXAiLCJJTUc6Om5hbWUiLCJJTUc6OnVzZW1hcCIsIklNRzo6dnNwYWNlIiwiSU1HOjp3aWR0aCIs
+IklOUFVUOjphY2NlcHQiLCJJTlBVVDo6YWNjZXNza2V5IiwiSU5QVVQ6OmFsaWduIiwiSU5QVVQ6OmFs
+dCIsIklOUFVUOjphdXRvY29tcGxldGUiLCJJTlBVVDo6YXV0b2ZvY3VzIiwiSU5QVVQ6OmNoZWNrZWQi
+LCJJTlBVVDo6ZGlzYWJsZWQiLCJJTlBVVDo6aW5wdXRtb2RlIiwiSU5QVVQ6OmlzbWFwIiwiSU5QVVQ6
+Omxpc3QiLCJJTlBVVDo6bWF4IiwiSU5QVVQ6Om1heGxlbmd0aCIsIklOUFVUOjptaW4iLCJJTlBVVDo6
+bXVsdGlwbGUiLCJJTlBVVDo6bmFtZSIsIklOUFVUOjpwbGFjZWhvbGRlciIsIklOUFVUOjpyZWFkb25s
+eSIsIklOUFVUOjpyZXF1aXJlZCIsIklOUFVUOjpzaXplIiwiSU5QVVQ6OnN0ZXAiLCJJTlBVVDo6dGFi
+aW5kZXgiLCJJTlBVVDo6dHlwZSIsIklOUFVUOjp1c2VtYXAiLCJJTlBVVDo6dmFsdWUiLCJJTlM6OmRh
+dGV0aW1lIiwiS0VZR0VOOjpkaXNhYmxlZCIsIktFWUdFTjo6a2V5dHlwZSIsIktFWUdFTjo6bmFtZSIs
+IkxBQkVMOjphY2Nlc3NrZXkiLCJMQUJFTDo6Zm9yIiwiTEVHRU5EOjphY2Nlc3NrZXkiLCJMRUdFTkQ6
+OmFsaWduIiwiTEk6OnR5cGUiLCJMSTo6dmFsdWUiLCJMSU5LOjpzaXplcyIsIk1BUDo6bmFtZSIsIk1F
+TlU6OmNvbXBhY3QiLCJNRU5VOjpsYWJlbCIsIk1FTlU6OnR5cGUiLCJNRVRFUjo6aGlnaCIsIk1FVEVS
+Ojpsb3ciLCJNRVRFUjo6bWF4IiwiTUVURVI6Om1pbiIsIk1FVEVSOjp2YWx1ZSIsIk9CSkVDVDo6dHlw
+ZW11c3RtYXRjaCIsIk9MOjpjb21wYWN0IiwiT0w6OnJldmVyc2VkIiwiT0w6OnN0YXJ0IiwiT0w6OnR5
+cGUiLCJPUFRHUk9VUDo6ZGlzYWJsZWQiLCJPUFRHUk9VUDo6bGFiZWwiLCJPUFRJT046OmRpc2FibGVk
+IiwiT1BUSU9OOjpsYWJlbCIsIk9QVElPTjo6c2VsZWN0ZWQiLCJPUFRJT046OnZhbHVlIiwiT1VUUFVU
+Ojpmb3IiLCJPVVRQVVQ6Om5hbWUiLCJQOjphbGlnbiIsIlBSRTo6d2lkdGgiLCJQUk9HUkVTUzo6bWF4
+IiwiUFJPR1JFU1M6Om1pbiIsIlBST0dSRVNTOjp2YWx1ZSIsIlNFTEVDVDo6YXV0b2NvbXBsZXRlIiwi
+U0VMRUNUOjpkaXNhYmxlZCIsIlNFTEVDVDo6bXVsdGlwbGUiLCJTRUxFQ1Q6Om5hbWUiLCJTRUxFQ1Q6
+OnJlcXVpcmVkIiwiU0VMRUNUOjpzaXplIiwiU0VMRUNUOjp0YWJpbmRleCIsIlNPVVJDRTo6dHlwZSIs
+IlRBQkxFOjphbGlnbiIsIlRBQkxFOjpiZ2NvbG9yIiwiVEFCTEU6OmJvcmRlciIsIlRBQkxFOjpjZWxs
+cGFkZGluZyIsIlRBQkxFOjpjZWxsc3BhY2luZyIsIlRBQkxFOjpmcmFtZSIsIlRBQkxFOjpydWxlcyIs
+IlRBQkxFOjpzdW1tYXJ5IiwiVEFCTEU6OndpZHRoIiwiVEJPRFk6OmFsaWduIiwiVEJPRFk6OmNoYXIi
+LCJUQk9EWTo6Y2hhcm9mZiIsIlRCT0RZOjp2YWxpZ24iLCJURDo6YWJiciIsIlREOjphbGlnbiIsIlRE
+OjpheGlzIiwiVEQ6OmJnY29sb3IiLCJURDo6Y2hhciIsIlREOjpjaGFyb2ZmIiwiVEQ6OmNvbHNwYW4i
+LCJURDo6aGVhZGVycyIsIlREOjpoZWlnaHQiLCJURDo6bm93cmFwIiwiVEQ6OnJvd3NwYW4iLCJURDo6
+c2NvcGUiLCJURDo6dmFsaWduIiwiVEQ6OndpZHRoIiwiVEVYVEFSRUE6OmFjY2Vzc2tleSIsIlRFWFRB
+UkVBOjphdXRvY29tcGxldGUiLCJURVhUQVJFQTo6Y29scyIsIlRFWFRBUkVBOjpkaXNhYmxlZCIsIlRF
+WFRBUkVBOjppbnB1dG1vZGUiLCJURVhUQVJFQTo6bmFtZSIsIlRFWFRBUkVBOjpwbGFjZWhvbGRlciIs
+IlRFWFRBUkVBOjpyZWFkb25seSIsIlRFWFRBUkVBOjpyZXF1aXJlZCIsIlRFWFRBUkVBOjpyb3dzIiwi
+VEVYVEFSRUE6OnRhYmluZGV4IiwiVEVYVEFSRUE6OndyYXAiLCJURk9PVDo6YWxpZ24iLCJURk9PVDo6
+Y2hhciIsIlRGT09UOjpjaGFyb2ZmIiwiVEZPT1Q6OnZhbGlnbiIsIlRIOjphYmJyIiwiVEg6OmFsaWdu
+IiwiVEg6OmF4aXMiLCJUSDo6Ymdjb2xvciIsIlRIOjpjaGFyIiwiVEg6OmNoYXJvZmYiLCJUSDo6Y29s
+c3BhbiIsIlRIOjpoZWFkZXJzIiwiVEg6OmhlaWdodCIsIlRIOjpub3dyYXAiLCJUSDo6cm93c3BhbiIs
+IlRIOjpzY29wZSIsIlRIOjp2YWxpZ24iLCJUSDo6d2lkdGgiLCJUSEVBRDo6YWxpZ24iLCJUSEVBRDo6
+Y2hhciIsIlRIRUFEOjpjaGFyb2ZmIiwiVEhFQUQ6OnZhbGlnbiIsIlRSOjphbGlnbiIsIlRSOjpiZ2Nv
+bG9yIiwiVFI6OmNoYXIiLCJUUjo6Y2hhcm9mZiIsIlRSOjp2YWxpZ24iLCJUUkFDSzo6ZGVmYXVsdCIs
+IlRSQUNLOjpraW5kIiwiVFJBQ0s6OmxhYmVsIiwiVFJBQ0s6OnNyY2xhbmciLCJVTDo6Y29tcGFjdCIs
+IlVMOjp0eXBlIiwiVklERU86OmNvbnRyb2xzIiwiVklERU86OmhlaWdodCIsIlZJREVPOjpsb29wIiwi
+VklERU86Om1lZGlhZ3JvdXAiLCJWSURFTzo6bXV0ZWQiLCJWSURFTzo6cHJlbG9hZCIsIlZJREVPOjp3
+aWR0aCJdKSx1LnMpCkMuVkM9SC5WTSh0KFswLDAsNjU0OTAsNDUwNTUsNjU1MzUsMzQ4MTUsNjU1MzQs
+MTg0MzFdKSx1LnQpCkMubUs9SC5WTSh0KFswLDAsMjY2MjQsMTAyMyw2NTUzNCwyMDQ3LDY1NTM0LDIw
+NDddKSx1LnQpCkMuU3E9SC5WTSh0KFsiSEVBRCIsIkFSRUEiLCJCQVNFIiwiQkFTRUZPTlQiLCJCUiIs
+IkNPTCIsIkNPTEdST1VQIiwiRU1CRUQiLCJGUkFNRSIsIkZSQU1FU0VUIiwiSFIiLCJJTUFHRSIsIklN
+RyIsIklOUFVUIiwiSVNJTkRFWCIsIkxJTksiLCJNRVRBIiwiUEFSQU0iLCJTT1VSQ0UiLCJTVFlMRSIs
+IlRJVExFIiwiV0JSIl0pLHUucykKQy54RD1ILlZNKHQoW10pLHUucykKQy5kbj1ILlZNKHQoW10pLHUu
+dikKQy50bz1ILlZNKHQoWzAsMCwzMjcyMiwxMjI4Nyw2NTUzNCwzNDgxNSw2NTUzNCwxODQzMV0pLHUu
+dCkKQy5GMz1ILlZNKHQoWzAsMCwyNDU3NiwxMDIzLDY1NTM0LDM0ODE1LDY1NTM0LDE4NDMxXSksdS50
+KQpDLmVhPUguVk0odChbMCwwLDMyNzU0LDExMjYzLDY1NTM0LDM0ODE1LDY1NTM0LDE4NDMxXSksdS50
+KQpDLlpKPUguVk0odChbMCwwLDMyNzIyLDEyMjg3LDY1NTM1LDM0ODE1LDY1NTM0LDE4NDMxXSksdS50
+KQpDLldkPUguVk0odChbMCwwLDY1NDkwLDEyMjg3LDY1NTM1LDM0ODE1LDY1NTM0LDE4NDMxXSksdS50
+KQpDLlF4PUguVk0odChbImJpbmQiLCJpZiIsInJlZiIsInJlcGVhdCIsInN5bnRheCJdKSx1LnMpCkMu
+Qkk9SC5WTSh0KFsiQTo6aHJlZiIsIkFSRUE6OmhyZWYiLCJCTE9DS1FVT1RFOjpjaXRlIiwiQk9EWTo6
+YmFja2dyb3VuZCIsIkNPTU1BTkQ6Omljb24iLCJERUw6OmNpdGUiLCJGT1JNOjphY3Rpb24iLCJJTUc6
+OnNyYyIsIklOUFVUOjpzcmMiLCJJTlM6OmNpdGUiLCJROjpjaXRlIiwiVklERU86OnBvc3RlciJdKSx1
+LnMpCkMuQ009bmV3IEguTFAoMCx7fSxDLnhELEguTjAoIkxQPHFVLHpNPGo4Pj4iKSkKQy5XTz1uZXcg
+SC5MUCgwLHt9LEMueEQsSC5OMCgiTFA8cVUscVU+IikpCkMuaFU9SC5WTSh0KFtdKSxILk4wKCJqZDxH
+RD4iKSkKQy5EeD1uZXcgSC5MUCgwLHt9LEMuaFUsSC5OMCgiTFA8R0QsQD4iKSkKQy5ZMj1uZXcgTC5P
+OSgiTmF2aWdhdGlvblRyZWVOb2RlVHlwZS5kaXJlY3RvcnkiKQpDLnJmPW5ldyBMLk85KCJOYXZpZ2F0
+aW9uVHJlZU5vZGVUeXBlLmZpbGUiKQpDLlRlPW5ldyBILnd2KCJjYWxsIikKQy53UT1uZXcgUC5GeShu
+dWxsLDIpfSkoKTsoZnVuY3Rpb24gc3RhdGljRmllbGRzKCl7JC55aj0wCiQubUo9bnVsbAokLlA0PW51
+bGwKJC55PW51bGwKJC51PW51bGwKJC54Nz1udWxsCiQuaj1udWxsCiQudj1udWxsCiQuSz1udWxsCiQu
+UzY9bnVsbAokLms4PW51bGwKJC5tZz1udWxsCiQuVUQ9ITEKJC5YMz1DLk5VCiQueGc9W10KJC54bz1u
+dWxsCiQuQk89bnVsbAokLmx0PW51bGwKJC5FVT1udWxsCiQub3I9UC5GbCh1Lk4sdS5aKQokLkk2PW51
+bGwKJC5GZj1udWxsfSkoKTsoZnVuY3Rpb24gbGF6eUluaXRpYWxpemVycygpe3ZhciB0PWh1bmtIZWxw
+ZXJzLmxhenkKdCgkLCJmYSIsIndRIixmdW5jdGlvbigpe3JldHVybiBILllnKCJfJGRhcnRfZGFydENs
+b3N1cmUiKX0pCnQoJCwiWTIiLCJBIixmdW5jdGlvbigpe3JldHVybiBILllnKCJfJGRhcnRfanMiKX0p
+CnQoJCwiVTIiLCJTbiIsZnVuY3Rpb24oKXtyZXR1cm4gSC5jTShILlM3KHsKdG9TdHJpbmc6ZnVuY3Rp
+b24oKXtyZXR1cm4iJHJlY2VpdmVyJCJ9fSkpfSkKdCgkLCJ4cSIsImxxIixmdW5jdGlvbigpe3JldHVy
+biBILmNNKEguUzcoeyRtZXRob2QkOm51bGwsCnRvU3RyaW5nOmZ1bmN0aW9uKCl7cmV0dXJuIiRyZWNl
+aXZlciQifX0pKX0pCnQoJCwiUjEiLCJOOSIsZnVuY3Rpb24oKXtyZXR1cm4gSC5jTShILlM3KG51bGwp
+KX0pCnQoJCwiZk4iLCJpSSIsZnVuY3Rpb24oKXtyZXR1cm4gSC5jTShmdW5jdGlvbigpe3ZhciAkYXJn
+dW1lbnRzRXhwciQ9JyRhcmd1bWVudHMkJwp0cnl7bnVsbC4kbWV0aG9kJCgkYXJndW1lbnRzRXhwciQp
+fWNhdGNoKHMpe3JldHVybiBzLm1lc3NhZ2V9fSgpKX0pCnQoJCwicWkiLCJVTiIsZnVuY3Rpb24oKXty
+ZXR1cm4gSC5jTShILlM3KHZvaWQgMCkpfSkKdCgkLCJyWiIsIlpoIixmdW5jdGlvbigpe3JldHVybiBI
+LmNNKGZ1bmN0aW9uKCl7dmFyICRhcmd1bWVudHNFeHByJD0nJGFyZ3VtZW50cyQnCnRyeXsodm9pZCAw
+KS4kbWV0aG9kJCgkYXJndW1lbnRzRXhwciQpfWNhdGNoKHMpe3JldHVybiBzLm1lc3NhZ2V9fSgpKX0p
+CnQoJCwia3EiLCJyTiIsZnVuY3Rpb24oKXtyZXR1cm4gSC5jTShILk1qKG51bGwpKX0pCnQoJCwidHQi
+LCJjMyIsZnVuY3Rpb24oKXtyZXR1cm4gSC5jTShmdW5jdGlvbigpe3RyeXtudWxsLiRtZXRob2QkfWNh
+dGNoKHMpe3JldHVybiBzLm1lc3NhZ2V9fSgpKX0pCnQoJCwiZHQiLCJISyIsZnVuY3Rpb24oKXtyZXR1
+cm4gSC5jTShILk1qKHZvaWQgMCkpfSkKdCgkLCJBNyIsInIxIixmdW5jdGlvbigpe3JldHVybiBILmNN
+KGZ1bmN0aW9uKCl7dHJ5eyh2b2lkIDApLiRtZXRob2QkfWNhdGNoKHMpe3JldHVybiBzLm1lc3NhZ2V9
+fSgpKX0pCnQoJCwiV2MiLCJ1dCIsZnVuY3Rpb24oKXtyZXR1cm4gUC5PaigpfSkKdCgkLCJraCIsInRM
+IixmdW5jdGlvbigpe3JldHVybiBuZXcgUC5wZygpLiQwKCl9KQp0KCQsImJ0IiwiVjciLGZ1bmN0aW9u
+KCl7cmV0dXJuIG5ldyBJbnQ4QXJyYXkoSC5YRihILlZNKFstMiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwt
+MiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwt
+MiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwtMSwtMiwtMiwtMiwtMiwtMiw2MiwtMiw2MiwtMiw2Myw1
+Miw1Myw1NCw1NSw1Niw1Nyw1OCw1OSw2MCw2MSwtMiwtMiwtMiwtMSwtMiwtMiwtMiwwLDEsMiwzLDQs
+NSw2LDcsOCw5LDEwLDExLDEyLDEzLDE0LDE1LDE2LDE3LDE4LDE5LDIwLDIxLDIyLDIzLDI0LDI1LC0y
+LC0yLC0yLC0yLDYzLC0yLDI2LDI3LDI4LDI5LDMwLDMxLDMyLDMzLDM0LDM1LDM2LDM3LDM4LDM5LDQw
+LDQxLDQyLDQzLDQ0LDQ1LDQ2LDQ3LDQ4LDQ5LDUwLDUxLC0yLC0yLC0yLC0yLC0yXSx1LnQpKSl9KQp0
+KCQsIk01IiwiT3giLGZ1bmN0aW9uKCl7cmV0dXJuIHR5cGVvZiBwcm9jZXNzIT0idW5kZWZpbmVkIiYm
+T2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKHByb2Nlc3MpPT0iW29iamVjdCBwcm9jZXNzXSIm
+JnByb2Nlc3MucGxhdGZvcm09PSJ3aW4zMiJ9KQp0KCQsIm1mIiwiejQiLGZ1bmN0aW9uKCl7cmV0dXJu
+IFAubnUoIl5bXFwtXFwuMC05QS1aX2Eten5dKiQiKX0pCnQoJCwiSkciLCJ2WiIsZnVuY3Rpb24oKXty
+ZXR1cm4gUC5LTigpfSkKdCgkLCJTQyIsIkFOIixmdW5jdGlvbigpe3JldHVybiBQLnRNKFsiQSIsIkFC
+QlIiLCJBQ1JPTllNIiwiQUREUkVTUyIsIkFSRUEiLCJBUlRJQ0xFIiwiQVNJREUiLCJBVURJTyIsIkIi
+LCJCREkiLCJCRE8iLCJCSUciLCJCTE9DS1FVT1RFIiwiQlIiLCJCVVRUT04iLCJDQU5WQVMiLCJDQVBU
+SU9OIiwiQ0VOVEVSIiwiQ0lURSIsIkNPREUiLCJDT0wiLCJDT0xHUk9VUCIsIkNPTU1BTkQiLCJEQVRB
+IiwiREFUQUxJU1QiLCJERCIsIkRFTCIsIkRFVEFJTFMiLCJERk4iLCJESVIiLCJESVYiLCJETCIsIkRU
+IiwiRU0iLCJGSUVMRFNFVCIsIkZJR0NBUFRJT04iLCJGSUdVUkUiLCJGT05UIiwiRk9PVEVSIiwiRk9S
+TSIsIkgxIiwiSDIiLCJIMyIsIkg0IiwiSDUiLCJINiIsIkhFQURFUiIsIkhHUk9VUCIsIkhSIiwiSSIs
+IklGUkFNRSIsIklNRyIsIklOUFVUIiwiSU5TIiwiS0JEIiwiTEFCRUwiLCJMRUdFTkQiLCJMSSIsIk1B
+UCIsIk1BUksiLCJNRU5VIiwiTUVURVIiLCJOQVYiLCJOT0JSIiwiT0wiLCJPUFRHUk9VUCIsIk9QVElP
+TiIsIk9VVFBVVCIsIlAiLCJQUkUiLCJQUk9HUkVTUyIsIlEiLCJTIiwiU0FNUCIsIlNFQ1RJT04iLCJT
+RUxFQ1QiLCJTTUFMTCIsIlNPVVJDRSIsIlNQQU4iLCJTVFJJS0UiLCJTVFJPTkciLCJTVUIiLCJTVU1N
+QVJZIiwiU1VQIiwiVEFCTEUiLCJUQk9EWSIsIlREIiwiVEVYVEFSRUEiLCJURk9PVCIsIlRIIiwiVEhF
+QUQiLCJUSU1FIiwiVFIiLCJUUkFDSyIsIlRUIiwiVSIsIlVMIiwiVkFSIiwiVklERU8iLCJXQlIiXSx1
+Lk4pfSkKdCgkLCJYNCIsImhHIixmdW5jdGlvbigpe3JldHVybiBQLm51KCJeXFxTKyQiKX0pCnQoJCwi
+d08iLCJvdyIsZnVuY3Rpb24oKXtyZXR1cm4gUC5ORChzZWxmKX0pCnQoJCwia3QiLCJDciIsZnVuY3Rp
+b24oKXtyZXR1cm4gSC5ZZygiXyRkYXJ0X2RhcnRPYmplY3QiKX0pCnQoJCwiZksiLCJrSSIsZnVuY3Rp
+b24oKXtyZXR1cm4gZnVuY3Rpb24gRGFydE9iamVjdChhKXt0aGlzLm89YX19KQp0KCQsInF0IiwiekIi
+LGZ1bmN0aW9uKCl7cmV0dXJuIG5ldyBULm1RKCl9KQp0KCQsIk9sIiwiVUUiLGZ1bmN0aW9uKCl7cmV0
+dXJuIFAuaEsoQy5vbC5nbVcoVy54MygpKS5ocmVmKS5naFkoKS5xKDAsImF1dGhUb2tlbiIpfSkKdCgk
+LCJoVCIsInlQIixmdW5jdGlvbigpe3JldHVybiBXLlpyKCkucXVlcnlTZWxlY3RvcigiLmVkaXQtbGlz
+dCAucGFuZWwtY29udGVudCIpfSkKdCgkLCJXNiIsImhMIixmdW5jdGlvbigpe3JldHVybiBXLlpyKCku
+cXVlcnlTZWxlY3RvcigiLmVkaXQtcGFuZWwgLnBhbmVsLWNvbnRlbnQiKX0pCnQoJCwiVFIiLCJEVyIs
+ZnVuY3Rpb24oKXtyZXR1cm4gVy5acigpLnF1ZXJ5U2VsZWN0b3IoImZvb3RlciIpfSkKdCgkLCJFWSIs
+ImZpIixmdW5jdGlvbigpe3JldHVybiBXLlpyKCkucXVlcnlTZWxlY3RvcigiaGVhZGVyIil9KQp0KCQs
+ImF2IiwiRDkiLGZ1bmN0aW9uKCl7cmV0dXJuIFcuWnIoKS5xdWVyeVNlbGVjdG9yKCIjdW5pdC1uYW1l
+Iil9KQp0KCQsImZlIiwiS0ciLGZ1bmN0aW9uKCl7cmV0dXJuIG5ldyBMLlhBKCl9KQp0KCQsImVvIiwi
+blUiLGZ1bmN0aW9uKCl7cmV0dXJuIG5ldyBNLmxJKCQuSGsoKSl9KQp0KCQsInlyIiwiYkQiLGZ1bmN0
+aW9uKCl7cmV0dXJuIG5ldyBFLk9GKFAubnUoIi8iKSxQLm51KCJbXi9dJCIpLFAubnUoIl4vIikpfSkK
+dCgkLCJNayIsIktrIixmdW5jdGlvbigpe3JldHVybiBuZXcgTC5JVihQLm51KCJbL1xcXFxdIiksUC5u
+dSgiW14vXFxcXF0kIiksUC5udSgiXihcXFxcXFxcXFteXFxcXF0rXFxcXFteXFxcXC9dK3xbYS16QS1a
+XTpbL1xcXFxdKSIpLFAubnUoIl5bL1xcXFxdKD8hWy9cXFxcXSkiKSl9KQp0KCQsImFrIiwiRWIiLGZ1
+bmN0aW9uKCl7cmV0dXJuIG5ldyBGLnJ1KFAubnUoIi8iKSxQLm51KCIoXlthLXpBLVpdWy0rLmEtekEt
+WlxcZF0qOi8vfFteL10pJCIpLFAubnUoIlthLXpBLVpdWy0rLmEtekEtWlxcZF0qOi8vW14vXSoiKSxQ
+Lm51KCJeLyIpKX0pCnQoJCwibHMiLCJIayIsZnVuY3Rpb24oKXtyZXR1cm4gTy5SaCgpfSl9KSgpOyhm
+dW5jdGlvbiBuYXRpdmVTdXBwb3J0KCl7IWZ1bmN0aW9uKCl7dmFyIHQ9ZnVuY3Rpb24oYSl7dmFyIG49
+e30KblthXT0xCnJldHVybiBPYmplY3Qua2V5cyhodW5rSGVscGVycy5jb252ZXJ0VG9GYXN0T2JqZWN0
+KG4pKVswXX0Kdi5nZXRJc29sYXRlVGFnPWZ1bmN0aW9uKGEpe3JldHVybiB0KCJfX19kYXJ0XyIrYSt2
+Lmlzb2xhdGVUYWcpfQp2YXIgcz0iX19fZGFydF9pc29sYXRlX3RhZ3NfIgp2YXIgcj1PYmplY3Rbc118
+fChPYmplY3Rbc109T2JqZWN0LmNyZWF0ZShudWxsKSkKdmFyIHE9Il9aeFl4WCIKZm9yKHZhciBwPTA7
+O3ArKyl7dmFyIG89dChxKyJfIitwKyJfIikKaWYoIShvIGluIHIpKXtyW29dPTEKdi5pc29sYXRlVGFn
+PW8KYnJlYWt9fXYuZGlzcGF0Y2hQcm9wZXJ0eU5hbWU9di5nZXRJc29sYXRlVGFnKCJkaXNwYXRjaF9y
+ZWNvcmQiKX0oKQpodW5rSGVscGVycy5zZXRPclVwZGF0ZUludGVyY2VwdG9yc0J5VGFnKHtET01FcnJv
+cjpKLnZCLERPTUltcGxlbWVudGF0aW9uOkoudkIsTWVkaWFFcnJvcjpKLnZCLE5hdmlnYXRvcjpKLnZC
+LE5hdmlnYXRvckNvbmN1cnJlbnRIYXJkd2FyZTpKLnZCLE5hdmlnYXRvclVzZXJNZWRpYUVycm9yOkou
+dkIsT3ZlcmNvbnN0cmFpbmVkRXJyb3I6Si52QixQb3NpdGlvbkVycm9yOkoudkIsUmFuZ2U6Si52QixT
+UUxFcnJvcjpKLnZCLERhdGFWaWV3OkgucEYsQXJyYXlCdWZmZXJWaWV3OkgucEYsRmxvYXQzMkFycmF5
+OkguRGcsRmxvYXQ2NEFycmF5OkguRGcsSW50MTZBcnJheTpILnhqLEludDMyQXJyYXk6SC5kRSxJbnQ4
+QXJyYXk6SC5aQSxVaW50MTZBcnJheTpILndmLFVpbnQzMkFycmF5OkguUHEsVWludDhDbGFtcGVkQXJy
+YXk6SC5lRSxDYW52YXNQaXhlbEFycmF5OkguZUUsVWludDhBcnJheTpILlY2LEhUTUxBdWRpb0VsZW1l
+bnQ6Vy5xRSxIVE1MQlJFbGVtZW50OlcucUUsSFRNTEJ1dHRvbkVsZW1lbnQ6Vy5xRSxIVE1MQ2FudmFz
+RWxlbWVudDpXLnFFLEhUTUxDb250ZW50RWxlbWVudDpXLnFFLEhUTUxETGlzdEVsZW1lbnQ6Vy5xRSxI
+VE1MRGF0YUVsZW1lbnQ6Vy5xRSxIVE1MRGF0YUxpc3RFbGVtZW50OlcucUUsSFRNTERldGFpbHNFbGVt
+ZW50OlcucUUsSFRNTERpYWxvZ0VsZW1lbnQ6Vy5xRSxIVE1MRGl2RWxlbWVudDpXLnFFLEhUTUxFbWJl
+ZEVsZW1lbnQ6Vy5xRSxIVE1MRmllbGRTZXRFbGVtZW50OlcucUUsSFRNTEhSRWxlbWVudDpXLnFFLEhU
+TUxIZWFkRWxlbWVudDpXLnFFLEhUTUxIZWFkaW5nRWxlbWVudDpXLnFFLEhUTUxIdG1sRWxlbWVudDpX
+LnFFLEhUTUxJRnJhbWVFbGVtZW50OlcucUUsSFRNTEltYWdlRWxlbWVudDpXLnFFLEhUTUxJbnB1dEVs
+ZW1lbnQ6Vy5xRSxIVE1MTElFbGVtZW50OlcucUUsSFRNTExhYmVsRWxlbWVudDpXLnFFLEhUTUxMZWdl
+bmRFbGVtZW50OlcucUUsSFRNTExpbmtFbGVtZW50OlcucUUsSFRNTE1hcEVsZW1lbnQ6Vy5xRSxIVE1M
+TWVkaWFFbGVtZW50OlcucUUsSFRNTE1lbnVFbGVtZW50OlcucUUsSFRNTE1ldGFFbGVtZW50OlcucUUs
+SFRNTE1ldGVyRWxlbWVudDpXLnFFLEhUTUxNb2RFbGVtZW50OlcucUUsSFRNTE9MaXN0RWxlbWVudDpX
+LnFFLEhUTUxPYmplY3RFbGVtZW50OlcucUUsSFRNTE9wdEdyb3VwRWxlbWVudDpXLnFFLEhUTUxPcHRp
+b25FbGVtZW50OlcucUUsSFRNTE91dHB1dEVsZW1lbnQ6Vy5xRSxIVE1MUGFyYW1FbGVtZW50OlcucUUs
+SFRNTFBpY3R1cmVFbGVtZW50OlcucUUsSFRNTFByZUVsZW1lbnQ6Vy5xRSxIVE1MUHJvZ3Jlc3NFbGVt
+ZW50OlcucUUsSFRNTFF1b3RlRWxlbWVudDpXLnFFLEhUTUxTY3JpcHRFbGVtZW50OlcucUUsSFRNTFNo
+YWRvd0VsZW1lbnQ6Vy5xRSxIVE1MU2xvdEVsZW1lbnQ6Vy5xRSxIVE1MU291cmNlRWxlbWVudDpXLnFF
+LEhUTUxTcGFuRWxlbWVudDpXLnFFLEhUTUxTdHlsZUVsZW1lbnQ6Vy5xRSxIVE1MVGFibGVDYXB0aW9u
+RWxlbWVudDpXLnFFLEhUTUxUYWJsZUNlbGxFbGVtZW50OlcucUUsSFRNTFRhYmxlRGF0YUNlbGxFbGVt
+ZW50OlcucUUsSFRNTFRhYmxlSGVhZGVyQ2VsbEVsZW1lbnQ6Vy5xRSxIVE1MVGFibGVDb2xFbGVtZW50
+OlcucUUsSFRNTFRleHRBcmVhRWxlbWVudDpXLnFFLEhUTUxUaW1lRWxlbWVudDpXLnFFLEhUTUxUaXRs
+ZUVsZW1lbnQ6Vy5xRSxIVE1MVHJhY2tFbGVtZW50OlcucUUsSFRNTFVMaXN0RWxlbWVudDpXLnFFLEhU
+TUxVbmtub3duRWxlbWVudDpXLnFFLEhUTUxWaWRlb0VsZW1lbnQ6Vy5xRSxIVE1MRGlyZWN0b3J5RWxl
+bWVudDpXLnFFLEhUTUxGb250RWxlbWVudDpXLnFFLEhUTUxGcmFtZUVsZW1lbnQ6Vy5xRSxIVE1MRnJh
+bWVTZXRFbGVtZW50OlcucUUsSFRNTE1hcnF1ZWVFbGVtZW50OlcucUUsSFRNTEVsZW1lbnQ6Vy5xRSxI
+VE1MQW5jaG9yRWxlbWVudDpXLkdoLEhUTUxBcmVhRWxlbWVudDpXLmZZLEhUTUxCYXNlRWxlbWVudDpX
+Lm5CLEJsb2I6Vy5BeixIVE1MQm9keUVsZW1lbnQ6Vy5RUCxDREFUQVNlY3Rpb246Vy5ueCxDaGFyYWN0
+ZXJEYXRhOlcubngsQ29tbWVudDpXLm54LFByb2Nlc3NpbmdJbnN0cnVjdGlvbjpXLm54LFRleHQ6Vy5u
+eCxDU1NTdHlsZURlY2xhcmF0aW9uOlcub0osTVNTdHlsZUNTU1Byb3BlcnRpZXM6Vy5vSixDU1MyUHJv
+cGVydGllczpXLm9KLFhNTERvY3VtZW50OlcuUUYsRG9jdW1lbnQ6Vy5RRixET01FeGNlcHRpb246Vy5O
+aCxET01SZWN0UmVhZE9ubHk6Vy5JQixET01Ub2tlbkxpc3Q6Vy5uNyxFbGVtZW50OlcuY3YsQWJvcnRQ
+YXltZW50RXZlbnQ6Vy5lYSxBbmltYXRpb25FdmVudDpXLmVhLEFuaW1hdGlvblBsYXliYWNrRXZlbnQ6
+Vy5lYSxBcHBsaWNhdGlvbkNhY2hlRXJyb3JFdmVudDpXLmVhLEJhY2tncm91bmRGZXRjaENsaWNrRXZl
+bnQ6Vy5lYSxCYWNrZ3JvdW5kRmV0Y2hFdmVudDpXLmVhLEJhY2tncm91bmRGZXRjaEZhaWxFdmVudDpX
+LmVhLEJhY2tncm91bmRGZXRjaGVkRXZlbnQ6Vy5lYSxCZWZvcmVJbnN0YWxsUHJvbXB0RXZlbnQ6Vy5l
+YSxCZWZvcmVVbmxvYWRFdmVudDpXLmVhLEJsb2JFdmVudDpXLmVhLENhbk1ha2VQYXltZW50RXZlbnQ6
+Vy5lYSxDbGlwYm9hcmRFdmVudDpXLmVhLENsb3NlRXZlbnQ6Vy5lYSxDdXN0b21FdmVudDpXLmVhLERl
+dmljZU1vdGlvbkV2ZW50OlcuZWEsRGV2aWNlT3JpZW50YXRpb25FdmVudDpXLmVhLEVycm9yRXZlbnQ6
+Vy5lYSxFeHRlbmRhYmxlRXZlbnQ6Vy5lYSxFeHRlbmRhYmxlTWVzc2FnZUV2ZW50OlcuZWEsRmV0Y2hF
+dmVudDpXLmVhLEZvbnRGYWNlU2V0TG9hZEV2ZW50OlcuZWEsRm9yZWlnbkZldGNoRXZlbnQ6Vy5lYSxH
+YW1lcGFkRXZlbnQ6Vy5lYSxIYXNoQ2hhbmdlRXZlbnQ6Vy5lYSxJbnN0YWxsRXZlbnQ6Vy5lYSxNZWRp
+YUVuY3J5cHRlZEV2ZW50OlcuZWEsTWVkaWFLZXlNZXNzYWdlRXZlbnQ6Vy5lYSxNZWRpYVF1ZXJ5TGlz
+dEV2ZW50OlcuZWEsTWVkaWFTdHJlYW1FdmVudDpXLmVhLE1lZGlhU3RyZWFtVHJhY2tFdmVudDpXLmVh
+LE1lc3NhZ2VFdmVudDpXLmVhLE1JRElDb25uZWN0aW9uRXZlbnQ6Vy5lYSxNSURJTWVzc2FnZUV2ZW50
+OlcuZWEsTXV0YXRpb25FdmVudDpXLmVhLE5vdGlmaWNhdGlvbkV2ZW50OlcuZWEsUGFnZVRyYW5zaXRp
+b25FdmVudDpXLmVhLFBheW1lbnRSZXF1ZXN0RXZlbnQ6Vy5lYSxQYXltZW50UmVxdWVzdFVwZGF0ZUV2
+ZW50OlcuZWEsUG9wU3RhdGVFdmVudDpXLmVhLFByZXNlbnRhdGlvbkNvbm5lY3Rpb25BdmFpbGFibGVF
+dmVudDpXLmVhLFByZXNlbnRhdGlvbkNvbm5lY3Rpb25DbG9zZUV2ZW50OlcuZWEsUHJvbWlzZVJlamVj
+dGlvbkV2ZW50OlcuZWEsUHVzaEV2ZW50OlcuZWEsUlRDRGF0YUNoYW5uZWxFdmVudDpXLmVhLFJUQ0RU
+TUZUb25lQ2hhbmdlRXZlbnQ6Vy5lYSxSVENQZWVyQ29ubmVjdGlvbkljZUV2ZW50OlcuZWEsUlRDVHJh
+Y2tFdmVudDpXLmVhLFNlY3VyaXR5UG9saWN5VmlvbGF0aW9uRXZlbnQ6Vy5lYSxTZW5zb3JFcnJvckV2
+ZW50OlcuZWEsU3BlZWNoUmVjb2duaXRpb25FcnJvcjpXLmVhLFNwZWVjaFJlY29nbml0aW9uRXZlbnQ6
+Vy5lYSxTcGVlY2hTeW50aGVzaXNFdmVudDpXLmVhLFN0b3JhZ2VFdmVudDpXLmVhLFN5bmNFdmVudDpX
+LmVhLFRyYWNrRXZlbnQ6Vy5lYSxUcmFuc2l0aW9uRXZlbnQ6Vy5lYSxXZWJLaXRUcmFuc2l0aW9uRXZl
+bnQ6Vy5lYSxWUkRldmljZUV2ZW50OlcuZWEsVlJEaXNwbGF5RXZlbnQ6Vy5lYSxWUlNlc3Npb25FdmVu
+dDpXLmVhLE1vam9JbnRlcmZhY2VSZXF1ZXN0RXZlbnQ6Vy5lYSxVU0JDb25uZWN0aW9uRXZlbnQ6Vy5l
+YSxJREJWZXJzaW9uQ2hhbmdlRXZlbnQ6Vy5lYSxBdWRpb1Byb2Nlc3NpbmdFdmVudDpXLmVhLE9mZmxp
+bmVBdWRpb0NvbXBsZXRpb25FdmVudDpXLmVhLFdlYkdMQ29udGV4dEV2ZW50OlcuZWEsRXZlbnQ6Vy5l
+YSxJbnB1dEV2ZW50OlcuZWEsRXZlbnRUYXJnZXQ6Vy5EMCxGaWxlOlcuVDUsSFRNTEZvcm1FbGVtZW50
+OlcuaDQsSGlzdG9yeTpXLmJyLEhUTUxEb2N1bWVudDpXLlZiLFhNTEh0dHBSZXF1ZXN0OlcuZkosWE1M
+SHR0cFJlcXVlc3RFdmVudFRhcmdldDpXLndhLEltYWdlRGF0YTpXLlNnLExvY2F0aW9uOlcudTgsTW91
+c2VFdmVudDpXLk9LLERyYWdFdmVudDpXLk9LLFBvaW50ZXJFdmVudDpXLk9LLFdoZWVsRXZlbnQ6Vy5P
+SyxEb2N1bWVudEZyYWdtZW50OlcudUgsU2hhZG93Um9vdDpXLnVILERvY3VtZW50VHlwZTpXLnVILE5v
+ZGU6Vy51SCxOb2RlTGlzdDpXLkJILFJhZGlvTm9kZUxpc3Q6Vy5CSCxIVE1MUGFyYWdyYXBoRWxlbWVu
+dDpXLlNOLFByb2dyZXNzRXZlbnQ6Vy5ldyxSZXNvdXJjZVByb2dyZXNzRXZlbnQ6Vy5ldyxIVE1MU2Vs
+ZWN0RWxlbWVudDpXLmxwLEhUTUxUYWJsZUVsZW1lbnQ6Vy5UYixIVE1MVGFibGVSb3dFbGVtZW50Olcu
+SXYsSFRNTFRhYmxlU2VjdGlvbkVsZW1lbnQ6Vy5XUCxIVE1MVGVtcGxhdGVFbGVtZW50OlcueVksQ29t
+cG9zaXRpb25FdmVudDpXLnc2LEZvY3VzRXZlbnQ6Vy53NixLZXlib2FyZEV2ZW50OlcudzYsVGV4dEV2
+ZW50OlcudzYsVG91Y2hFdmVudDpXLnc2LFVJRXZlbnQ6Vy53NixXaW5kb3c6Vy5LNSxET01XaW5kb3c6
+Vy5LNSxEZWRpY2F0ZWRXb3JrZXJHbG9iYWxTY29wZTpXLkNtLFNlcnZpY2VXb3JrZXJHbG9iYWxTY29w
+ZTpXLkNtLFNoYXJlZFdvcmtlckdsb2JhbFNjb3BlOlcuQ20sV29ya2VyR2xvYmFsU2NvcGU6Vy5DbSxB
+dHRyOlcuQ1EsQ2xpZW50UmVjdDpXLnc0LERPTVJlY3Q6Vy53NCxOYW1lZE5vZGVNYXA6Vy5yaCxNb3pO
+YW1lZEF0dHJNYXA6Vy5yaCxJREJLZXlSYW5nZTpQLmhGLFNWR1NjcmlwdEVsZW1lbnQ6UC5iQixTVkdB
+RWxlbWVudDpQLmQ1LFNWR0FuaW1hdGVFbGVtZW50OlAuZDUsU1ZHQW5pbWF0ZU1vdGlvbkVsZW1lbnQ6
+UC5kNSxTVkdBbmltYXRlVHJhbnNmb3JtRWxlbWVudDpQLmQ1LFNWR0FuaW1hdGlvbkVsZW1lbnQ6UC5k
+NSxTVkdDaXJjbGVFbGVtZW50OlAuZDUsU1ZHQ2xpcFBhdGhFbGVtZW50OlAuZDUsU1ZHRGVmc0VsZW1l
+bnQ6UC5kNSxTVkdEZXNjRWxlbWVudDpQLmQ1LFNWR0Rpc2NhcmRFbGVtZW50OlAuZDUsU1ZHRWxsaXBz
+ZUVsZW1lbnQ6UC5kNSxTVkdGRUJsZW5kRWxlbWVudDpQLmQ1LFNWR0ZFQ29sb3JNYXRyaXhFbGVtZW50
+OlAuZDUsU1ZHRkVDb21wb25lbnRUcmFuc2ZlckVsZW1lbnQ6UC5kNSxTVkdGRUNvbXBvc2l0ZUVsZW1l
+bnQ6UC5kNSxTVkdGRUNvbnZvbHZlTWF0cml4RWxlbWVudDpQLmQ1LFNWR0ZFRGlmZnVzZUxpZ2h0aW5n
+RWxlbWVudDpQLmQ1LFNWR0ZFRGlzcGxhY2VtZW50TWFwRWxlbWVudDpQLmQ1LFNWR0ZFRGlzdGFudExp
+Z2h0RWxlbWVudDpQLmQ1LFNWR0ZFRmxvb2RFbGVtZW50OlAuZDUsU1ZHRkVGdW5jQUVsZW1lbnQ6UC5k
+NSxTVkdGRUZ1bmNCRWxlbWVudDpQLmQ1LFNWR0ZFRnVuY0dFbGVtZW50OlAuZDUsU1ZHRkVGdW5jUkVs
+ZW1lbnQ6UC5kNSxTVkdGRUdhdXNzaWFuQmx1ckVsZW1lbnQ6UC5kNSxTVkdGRUltYWdlRWxlbWVudDpQ
+LmQ1LFNWR0ZFTWVyZ2VFbGVtZW50OlAuZDUsU1ZHRkVNZXJnZU5vZGVFbGVtZW50OlAuZDUsU1ZHRkVN
+b3JwaG9sb2d5RWxlbWVudDpQLmQ1LFNWR0ZFT2Zmc2V0RWxlbWVudDpQLmQ1LFNWR0ZFUG9pbnRMaWdo
+dEVsZW1lbnQ6UC5kNSxTVkdGRVNwZWN1bGFyTGlnaHRpbmdFbGVtZW50OlAuZDUsU1ZHRkVTcG90TGln
+aHRFbGVtZW50OlAuZDUsU1ZHRkVUaWxlRWxlbWVudDpQLmQ1LFNWR0ZFVHVyYnVsZW5jZUVsZW1lbnQ6
+UC5kNSxTVkdGaWx0ZXJFbGVtZW50OlAuZDUsU1ZHRm9yZWlnbk9iamVjdEVsZW1lbnQ6UC5kNSxTVkdH
+RWxlbWVudDpQLmQ1LFNWR0dlb21ldHJ5RWxlbWVudDpQLmQ1LFNWR0dyYXBoaWNzRWxlbWVudDpQLmQ1
+LFNWR0ltYWdlRWxlbWVudDpQLmQ1LFNWR0xpbmVFbGVtZW50OlAuZDUsU1ZHTGluZWFyR3JhZGllbnRF
+bGVtZW50OlAuZDUsU1ZHTWFya2VyRWxlbWVudDpQLmQ1LFNWR01hc2tFbGVtZW50OlAuZDUsU1ZHTWV0
+YWRhdGFFbGVtZW50OlAuZDUsU1ZHUGF0aEVsZW1lbnQ6UC5kNSxTVkdQYXR0ZXJuRWxlbWVudDpQLmQ1
+LFNWR1BvbHlnb25FbGVtZW50OlAuZDUsU1ZHUG9seWxpbmVFbGVtZW50OlAuZDUsU1ZHUmFkaWFsR3Jh
+ZGllbnRFbGVtZW50OlAuZDUsU1ZHUmVjdEVsZW1lbnQ6UC5kNSxTVkdTZXRFbGVtZW50OlAuZDUsU1ZH
+U3RvcEVsZW1lbnQ6UC5kNSxTVkdTdHlsZUVsZW1lbnQ6UC5kNSxTVkdTVkdFbGVtZW50OlAuZDUsU1ZH
+U3dpdGNoRWxlbWVudDpQLmQ1LFNWR1N5bWJvbEVsZW1lbnQ6UC5kNSxTVkdUU3BhbkVsZW1lbnQ6UC5k
+NSxTVkdUZXh0Q29udGVudEVsZW1lbnQ6UC5kNSxTVkdUZXh0RWxlbWVudDpQLmQ1LFNWR1RleHRQYXRo
+RWxlbWVudDpQLmQ1LFNWR1RleHRQb3NpdGlvbmluZ0VsZW1lbnQ6UC5kNSxTVkdUaXRsZUVsZW1lbnQ6
+UC5kNSxTVkdVc2VFbGVtZW50OlAuZDUsU1ZHVmlld0VsZW1lbnQ6UC5kNSxTVkdHcmFkaWVudEVsZW1l
+bnQ6UC5kNSxTVkdDb21wb25lbnRUcmFuc2ZlckZ1bmN0aW9uRWxlbWVudDpQLmQ1LFNWR0ZFRHJvcFNo
+YWRvd0VsZW1lbnQ6UC5kNSxTVkdNUGF0aEVsZW1lbnQ6UC5kNSxTVkdFbGVtZW50OlAuZDV9KQpodW5r
+SGVscGVycy5zZXRPclVwZGF0ZUxlYWZUYWdzKHtET01FcnJvcjp0cnVlLERPTUltcGxlbWVudGF0aW9u
+OnRydWUsTWVkaWFFcnJvcjp0cnVlLE5hdmlnYXRvcjp0cnVlLE5hdmlnYXRvckNvbmN1cnJlbnRIYXJk
+d2FyZTp0cnVlLE5hdmlnYXRvclVzZXJNZWRpYUVycm9yOnRydWUsT3ZlcmNvbnN0cmFpbmVkRXJyb3I6
+dHJ1ZSxQb3NpdGlvbkVycm9yOnRydWUsUmFuZ2U6dHJ1ZSxTUUxFcnJvcjp0cnVlLERhdGFWaWV3OnRy
+dWUsQXJyYXlCdWZmZXJWaWV3OmZhbHNlLEZsb2F0MzJBcnJheTp0cnVlLEZsb2F0NjRBcnJheTp0cnVl
+LEludDE2QXJyYXk6dHJ1ZSxJbnQzMkFycmF5OnRydWUsSW50OEFycmF5OnRydWUsVWludDE2QXJyYXk6
+dHJ1ZSxVaW50MzJBcnJheTp0cnVlLFVpbnQ4Q2xhbXBlZEFycmF5OnRydWUsQ2FudmFzUGl4ZWxBcnJh
+eTp0cnVlLFVpbnQ4QXJyYXk6ZmFsc2UsSFRNTEF1ZGlvRWxlbWVudDp0cnVlLEhUTUxCUkVsZW1lbnQ6
+dHJ1ZSxIVE1MQnV0dG9uRWxlbWVudDp0cnVlLEhUTUxDYW52YXNFbGVtZW50OnRydWUsSFRNTENvbnRl
+bnRFbGVtZW50OnRydWUsSFRNTERMaXN0RWxlbWVudDp0cnVlLEhUTUxEYXRhRWxlbWVudDp0cnVlLEhU
+TUxEYXRhTGlzdEVsZW1lbnQ6dHJ1ZSxIVE1MRGV0YWlsc0VsZW1lbnQ6dHJ1ZSxIVE1MRGlhbG9nRWxl
+bWVudDp0cnVlLEhUTUxEaXZFbGVtZW50OnRydWUsSFRNTEVtYmVkRWxlbWVudDp0cnVlLEhUTUxGaWVs
+ZFNldEVsZW1lbnQ6dHJ1ZSxIVE1MSFJFbGVtZW50OnRydWUsSFRNTEhlYWRFbGVtZW50OnRydWUsSFRN
+TEhlYWRpbmdFbGVtZW50OnRydWUsSFRNTEh0bWxFbGVtZW50OnRydWUsSFRNTElGcmFtZUVsZW1lbnQ6
+dHJ1ZSxIVE1MSW1hZ2VFbGVtZW50OnRydWUsSFRNTElucHV0RWxlbWVudDp0cnVlLEhUTUxMSUVsZW1l
+bnQ6dHJ1ZSxIVE1MTGFiZWxFbGVtZW50OnRydWUsSFRNTExlZ2VuZEVsZW1lbnQ6dHJ1ZSxIVE1MTGlu
+a0VsZW1lbnQ6dHJ1ZSxIVE1MTWFwRWxlbWVudDp0cnVlLEhUTUxNZWRpYUVsZW1lbnQ6dHJ1ZSxIVE1M
+TWVudUVsZW1lbnQ6dHJ1ZSxIVE1MTWV0YUVsZW1lbnQ6dHJ1ZSxIVE1MTWV0ZXJFbGVtZW50OnRydWUs
+SFRNTE1vZEVsZW1lbnQ6dHJ1ZSxIVE1MT0xpc3RFbGVtZW50OnRydWUsSFRNTE9iamVjdEVsZW1lbnQ6
+dHJ1ZSxIVE1MT3B0R3JvdXBFbGVtZW50OnRydWUsSFRNTE9wdGlvbkVsZW1lbnQ6dHJ1ZSxIVE1MT3V0
+cHV0RWxlbWVudDp0cnVlLEhUTUxQYXJhbUVsZW1lbnQ6dHJ1ZSxIVE1MUGljdHVyZUVsZW1lbnQ6dHJ1
+ZSxIVE1MUHJlRWxlbWVudDp0cnVlLEhUTUxQcm9ncmVzc0VsZW1lbnQ6dHJ1ZSxIVE1MUXVvdGVFbGVt
+ZW50OnRydWUsSFRNTFNjcmlwdEVsZW1lbnQ6dHJ1ZSxIVE1MU2hhZG93RWxlbWVudDp0cnVlLEhUTUxT
+bG90RWxlbWVudDp0cnVlLEhUTUxTb3VyY2VFbGVtZW50OnRydWUsSFRNTFNwYW5FbGVtZW50OnRydWUs
+SFRNTFN0eWxlRWxlbWVudDp0cnVlLEhUTUxUYWJsZUNhcHRpb25FbGVtZW50OnRydWUsSFRNTFRhYmxl
+Q2VsbEVsZW1lbnQ6dHJ1ZSxIVE1MVGFibGVEYXRhQ2VsbEVsZW1lbnQ6dHJ1ZSxIVE1MVGFibGVIZWFk
+ZXJDZWxsRWxlbWVudDp0cnVlLEhUTUxUYWJsZUNvbEVsZW1lbnQ6dHJ1ZSxIVE1MVGV4dEFyZWFFbGVt
+ZW50OnRydWUsSFRNTFRpbWVFbGVtZW50OnRydWUsSFRNTFRpdGxlRWxlbWVudDp0cnVlLEhUTUxUcmFj
+a0VsZW1lbnQ6dHJ1ZSxIVE1MVUxpc3RFbGVtZW50OnRydWUsSFRNTFVua25vd25FbGVtZW50OnRydWUs
+SFRNTFZpZGVvRWxlbWVudDp0cnVlLEhUTUxEaXJlY3RvcnlFbGVtZW50OnRydWUsSFRNTEZvbnRFbGVt
+ZW50OnRydWUsSFRNTEZyYW1lRWxlbWVudDp0cnVlLEhUTUxGcmFtZVNldEVsZW1lbnQ6dHJ1ZSxIVE1M
+TWFycXVlZUVsZW1lbnQ6dHJ1ZSxIVE1MRWxlbWVudDpmYWxzZSxIVE1MQW5jaG9yRWxlbWVudDp0cnVl
+LEhUTUxBcmVhRWxlbWVudDp0cnVlLEhUTUxCYXNlRWxlbWVudDp0cnVlLEJsb2I6ZmFsc2UsSFRNTEJv
+ZHlFbGVtZW50OnRydWUsQ0RBVEFTZWN0aW9uOnRydWUsQ2hhcmFjdGVyRGF0YTp0cnVlLENvbW1lbnQ6
+dHJ1ZSxQcm9jZXNzaW5nSW5zdHJ1Y3Rpb246dHJ1ZSxUZXh0OnRydWUsQ1NTU3R5bGVEZWNsYXJhdGlv
+bjp0cnVlLE1TU3R5bGVDU1NQcm9wZXJ0aWVzOnRydWUsQ1NTMlByb3BlcnRpZXM6dHJ1ZSxYTUxEb2N1
+bWVudDp0cnVlLERvY3VtZW50OmZhbHNlLERPTUV4Y2VwdGlvbjp0cnVlLERPTVJlY3RSZWFkT25seTpm
+YWxzZSxET01Ub2tlbkxpc3Q6dHJ1ZSxFbGVtZW50OmZhbHNlLEFib3J0UGF5bWVudEV2ZW50OnRydWUs
+QW5pbWF0aW9uRXZlbnQ6dHJ1ZSxBbmltYXRpb25QbGF5YmFja0V2ZW50OnRydWUsQXBwbGljYXRpb25D
+YWNoZUVycm9yRXZlbnQ6dHJ1ZSxCYWNrZ3JvdW5kRmV0Y2hDbGlja0V2ZW50OnRydWUsQmFja2dyb3Vu
+ZEZldGNoRXZlbnQ6dHJ1ZSxCYWNrZ3JvdW5kRmV0Y2hGYWlsRXZlbnQ6dHJ1ZSxCYWNrZ3JvdW5kRmV0
+Y2hlZEV2ZW50OnRydWUsQmVmb3JlSW5zdGFsbFByb21wdEV2ZW50OnRydWUsQmVmb3JlVW5sb2FkRXZl
+bnQ6dHJ1ZSxCbG9iRXZlbnQ6dHJ1ZSxDYW5NYWtlUGF5bWVudEV2ZW50OnRydWUsQ2xpcGJvYXJkRXZl
+bnQ6dHJ1ZSxDbG9zZUV2ZW50OnRydWUsQ3VzdG9tRXZlbnQ6dHJ1ZSxEZXZpY2VNb3Rpb25FdmVudDp0
+cnVlLERldmljZU9yaWVudGF0aW9uRXZlbnQ6dHJ1ZSxFcnJvckV2ZW50OnRydWUsRXh0ZW5kYWJsZUV2
+ZW50OnRydWUsRXh0ZW5kYWJsZU1lc3NhZ2VFdmVudDp0cnVlLEZldGNoRXZlbnQ6dHJ1ZSxGb250RmFj
+ZVNldExvYWRFdmVudDp0cnVlLEZvcmVpZ25GZXRjaEV2ZW50OnRydWUsR2FtZXBhZEV2ZW50OnRydWUs
+SGFzaENoYW5nZUV2ZW50OnRydWUsSW5zdGFsbEV2ZW50OnRydWUsTWVkaWFFbmNyeXB0ZWRFdmVudDp0
+cnVlLE1lZGlhS2V5TWVzc2FnZUV2ZW50OnRydWUsTWVkaWFRdWVyeUxpc3RFdmVudDp0cnVlLE1lZGlh
+U3RyZWFtRXZlbnQ6dHJ1ZSxNZWRpYVN0cmVhbVRyYWNrRXZlbnQ6dHJ1ZSxNZXNzYWdlRXZlbnQ6dHJ1
+ZSxNSURJQ29ubmVjdGlvbkV2ZW50OnRydWUsTUlESU1lc3NhZ2VFdmVudDp0cnVlLE11dGF0aW9uRXZl
+bnQ6dHJ1ZSxOb3RpZmljYXRpb25FdmVudDp0cnVlLFBhZ2VUcmFuc2l0aW9uRXZlbnQ6dHJ1ZSxQYXlt
+ZW50UmVxdWVzdEV2ZW50OnRydWUsUGF5bWVudFJlcXVlc3RVcGRhdGVFdmVudDp0cnVlLFBvcFN0YXRl
+RXZlbnQ6dHJ1ZSxQcmVzZW50YXRpb25Db25uZWN0aW9uQXZhaWxhYmxlRXZlbnQ6dHJ1ZSxQcmVzZW50
+YXRpb25Db25uZWN0aW9uQ2xvc2VFdmVudDp0cnVlLFByb21pc2VSZWplY3Rpb25FdmVudDp0cnVlLFB1
+c2hFdmVudDp0cnVlLFJUQ0RhdGFDaGFubmVsRXZlbnQ6dHJ1ZSxSVENEVE1GVG9uZUNoYW5nZUV2ZW50
+OnRydWUsUlRDUGVlckNvbm5lY3Rpb25JY2VFdmVudDp0cnVlLFJUQ1RyYWNrRXZlbnQ6dHJ1ZSxTZWN1
+cml0eVBvbGljeVZpb2xhdGlvbkV2ZW50OnRydWUsU2Vuc29yRXJyb3JFdmVudDp0cnVlLFNwZWVjaFJl
+Y29nbml0aW9uRXJyb3I6dHJ1ZSxTcGVlY2hSZWNvZ25pdGlvbkV2ZW50OnRydWUsU3BlZWNoU3ludGhl
+c2lzRXZlbnQ6dHJ1ZSxTdG9yYWdlRXZlbnQ6dHJ1ZSxTeW5jRXZlbnQ6dHJ1ZSxUcmFja0V2ZW50OnRy
+dWUsVHJhbnNpdGlvbkV2ZW50OnRydWUsV2ViS2l0VHJhbnNpdGlvbkV2ZW50OnRydWUsVlJEZXZpY2VF
+dmVudDp0cnVlLFZSRGlzcGxheUV2ZW50OnRydWUsVlJTZXNzaW9uRXZlbnQ6dHJ1ZSxNb2pvSW50ZXJm
+YWNlUmVxdWVzdEV2ZW50OnRydWUsVVNCQ29ubmVjdGlvbkV2ZW50OnRydWUsSURCVmVyc2lvbkNoYW5n
+ZUV2ZW50OnRydWUsQXVkaW9Qcm9jZXNzaW5nRXZlbnQ6dHJ1ZSxPZmZsaW5lQXVkaW9Db21wbGV0aW9u
+RXZlbnQ6dHJ1ZSxXZWJHTENvbnRleHRFdmVudDp0cnVlLEV2ZW50OmZhbHNlLElucHV0RXZlbnQ6ZmFs
+c2UsRXZlbnRUYXJnZXQ6ZmFsc2UsRmlsZTp0cnVlLEhUTUxGb3JtRWxlbWVudDp0cnVlLEhpc3Rvcnk6
+dHJ1ZSxIVE1MRG9jdW1lbnQ6dHJ1ZSxYTUxIdHRwUmVxdWVzdDp0cnVlLFhNTEh0dHBSZXF1ZXN0RXZl
+bnRUYXJnZXQ6ZmFsc2UsSW1hZ2VEYXRhOnRydWUsTG9jYXRpb246dHJ1ZSxNb3VzZUV2ZW50OnRydWUs
+RHJhZ0V2ZW50OnRydWUsUG9pbnRlckV2ZW50OnRydWUsV2hlZWxFdmVudDp0cnVlLERvY3VtZW50RnJh
+Z21lbnQ6dHJ1ZSxTaGFkb3dSb290OnRydWUsRG9jdW1lbnRUeXBlOnRydWUsTm9kZTpmYWxzZSxOb2Rl
+TGlzdDp0cnVlLFJhZGlvTm9kZUxpc3Q6dHJ1ZSxIVE1MUGFyYWdyYXBoRWxlbWVudDp0cnVlLFByb2dy
+ZXNzRXZlbnQ6dHJ1ZSxSZXNvdXJjZVByb2dyZXNzRXZlbnQ6dHJ1ZSxIVE1MU2VsZWN0RWxlbWVudDp0
+cnVlLEhUTUxUYWJsZUVsZW1lbnQ6dHJ1ZSxIVE1MVGFibGVSb3dFbGVtZW50OnRydWUsSFRNTFRhYmxl
+U2VjdGlvbkVsZW1lbnQ6dHJ1ZSxIVE1MVGVtcGxhdGVFbGVtZW50OnRydWUsQ29tcG9zaXRpb25FdmVu
+dDp0cnVlLEZvY3VzRXZlbnQ6dHJ1ZSxLZXlib2FyZEV2ZW50OnRydWUsVGV4dEV2ZW50OnRydWUsVG91
+Y2hFdmVudDp0cnVlLFVJRXZlbnQ6ZmFsc2UsV2luZG93OnRydWUsRE9NV2luZG93OnRydWUsRGVkaWNh
+dGVkV29ya2VyR2xvYmFsU2NvcGU6dHJ1ZSxTZXJ2aWNlV29ya2VyR2xvYmFsU2NvcGU6dHJ1ZSxTaGFy
+ZWRXb3JrZXJHbG9iYWxTY29wZTp0cnVlLFdvcmtlckdsb2JhbFNjb3BlOnRydWUsQXR0cjp0cnVlLENs
+aWVudFJlY3Q6dHJ1ZSxET01SZWN0OnRydWUsTmFtZWROb2RlTWFwOnRydWUsTW96TmFtZWRBdHRyTWFw
+OnRydWUsSURCS2V5UmFuZ2U6dHJ1ZSxTVkdTY3JpcHRFbGVtZW50OnRydWUsU1ZHQUVsZW1lbnQ6dHJ1
+ZSxTVkdBbmltYXRlRWxlbWVudDp0cnVlLFNWR0FuaW1hdGVNb3Rpb25FbGVtZW50OnRydWUsU1ZHQW5p
+bWF0ZVRyYW5zZm9ybUVsZW1lbnQ6dHJ1ZSxTVkdBbmltYXRpb25FbGVtZW50OnRydWUsU1ZHQ2lyY2xl
+RWxlbWVudDp0cnVlLFNWR0NsaXBQYXRoRWxlbWVudDp0cnVlLFNWR0RlZnNFbGVtZW50OnRydWUsU1ZH
+RGVzY0VsZW1lbnQ6dHJ1ZSxTVkdEaXNjYXJkRWxlbWVudDp0cnVlLFNWR0VsbGlwc2VFbGVtZW50OnRy
+dWUsU1ZHRkVCbGVuZEVsZW1lbnQ6dHJ1ZSxTVkdGRUNvbG9yTWF0cml4RWxlbWVudDp0cnVlLFNWR0ZF
+Q29tcG9uZW50VHJhbnNmZXJFbGVtZW50OnRydWUsU1ZHRkVDb21wb3NpdGVFbGVtZW50OnRydWUsU1ZH
+RkVDb252b2x2ZU1hdHJpeEVsZW1lbnQ6dHJ1ZSxTVkdGRURpZmZ1c2VMaWdodGluZ0VsZW1lbnQ6dHJ1
+ZSxTVkdGRURpc3BsYWNlbWVudE1hcEVsZW1lbnQ6dHJ1ZSxTVkdGRURpc3RhbnRMaWdodEVsZW1lbnQ6
+dHJ1ZSxTVkdGRUZsb29kRWxlbWVudDp0cnVlLFNWR0ZFRnVuY0FFbGVtZW50OnRydWUsU1ZHRkVGdW5j
+QkVsZW1lbnQ6dHJ1ZSxTVkdGRUZ1bmNHRWxlbWVudDp0cnVlLFNWR0ZFRnVuY1JFbGVtZW50OnRydWUs
+U1ZHRkVHYXVzc2lhbkJsdXJFbGVtZW50OnRydWUsU1ZHRkVJbWFnZUVsZW1lbnQ6dHJ1ZSxTVkdGRU1l
+cmdlRWxlbWVudDp0cnVlLFNWR0ZFTWVyZ2VOb2RlRWxlbWVudDp0cnVlLFNWR0ZFTW9ycGhvbG9neUVs
+ZW1lbnQ6dHJ1ZSxTVkdGRU9mZnNldEVsZW1lbnQ6dHJ1ZSxTVkdGRVBvaW50TGlnaHRFbGVtZW50OnRy
+dWUsU1ZHRkVTcGVjdWxhckxpZ2h0aW5nRWxlbWVudDp0cnVlLFNWR0ZFU3BvdExpZ2h0RWxlbWVudDp0
+cnVlLFNWR0ZFVGlsZUVsZW1lbnQ6dHJ1ZSxTVkdGRVR1cmJ1bGVuY2VFbGVtZW50OnRydWUsU1ZHRmls
+dGVyRWxlbWVudDp0cnVlLFNWR0ZvcmVpZ25PYmplY3RFbGVtZW50OnRydWUsU1ZHR0VsZW1lbnQ6dHJ1
+ZSxTVkdHZW9tZXRyeUVsZW1lbnQ6dHJ1ZSxTVkdHcmFwaGljc0VsZW1lbnQ6dHJ1ZSxTVkdJbWFnZUVs
+ZW1lbnQ6dHJ1ZSxTVkdMaW5lRWxlbWVudDp0cnVlLFNWR0xpbmVhckdyYWRpZW50RWxlbWVudDp0cnVl
+LFNWR01hcmtlckVsZW1lbnQ6dHJ1ZSxTVkdNYXNrRWxlbWVudDp0cnVlLFNWR01ldGFkYXRhRWxlbWVu
+dDp0cnVlLFNWR1BhdGhFbGVtZW50OnRydWUsU1ZHUGF0dGVybkVsZW1lbnQ6dHJ1ZSxTVkdQb2x5Z29u
+RWxlbWVudDp0cnVlLFNWR1BvbHlsaW5lRWxlbWVudDp0cnVlLFNWR1JhZGlhbEdyYWRpZW50RWxlbWVu
+dDp0cnVlLFNWR1JlY3RFbGVtZW50OnRydWUsU1ZHU2V0RWxlbWVudDp0cnVlLFNWR1N0b3BFbGVtZW50
+OnRydWUsU1ZHU3R5bGVFbGVtZW50OnRydWUsU1ZHU1ZHRWxlbWVudDp0cnVlLFNWR1N3aXRjaEVsZW1l
+bnQ6dHJ1ZSxTVkdTeW1ib2xFbGVtZW50OnRydWUsU1ZHVFNwYW5FbGVtZW50OnRydWUsU1ZHVGV4dENv
+bnRlbnRFbGVtZW50OnRydWUsU1ZHVGV4dEVsZW1lbnQ6dHJ1ZSxTVkdUZXh0UGF0aEVsZW1lbnQ6dHJ1
+ZSxTVkdUZXh0UG9zaXRpb25pbmdFbGVtZW50OnRydWUsU1ZHVGl0bGVFbGVtZW50OnRydWUsU1ZHVXNl
+RWxlbWVudDp0cnVlLFNWR1ZpZXdFbGVtZW50OnRydWUsU1ZHR3JhZGllbnRFbGVtZW50OnRydWUsU1ZH
+Q29tcG9uZW50VHJhbnNmZXJGdW5jdGlvbkVsZW1lbnQ6dHJ1ZSxTVkdGRURyb3BTaGFkb3dFbGVtZW50
+OnRydWUsU1ZHTVBhdGhFbGVtZW50OnRydWUsU1ZHRWxlbWVudDpmYWxzZX0pCkguYjAuJG5hdGl2ZVN1
+cGVyY2xhc3NUYWc9IkFycmF5QnVmZmVyVmlldyIKSC5SRy4kbmF0aXZlU3VwZXJjbGFzc1RhZz0iQXJy
+YXlCdWZmZXJWaWV3IgpILlZQLiRuYXRpdmVTdXBlcmNsYXNzVGFnPSJBcnJheUJ1ZmZlclZpZXciCkgu
+RGcuJG5hdGl2ZVN1cGVyY2xhc3NUYWc9IkFycmF5QnVmZmVyVmlldyIKSC5XQi4kbmF0aXZlU3VwZXJj
+bGFzc1RhZz0iQXJyYXlCdWZmZXJWaWV3IgpILlpHLiRuYXRpdmVTdXBlcmNsYXNzVGFnPSJBcnJheUJ1
+ZmZlclZpZXciCkguUGcuJG5hdGl2ZVN1cGVyY2xhc3NUYWc9IkFycmF5QnVmZmVyVmlldyJ9KSgpCmNv
+bnZlcnRBbGxUb0Zhc3RPYmplY3QodykKY29udmVydFRvRmFzdE9iamVjdCgkKTsoZnVuY3Rpb24oYSl7
+aWYodHlwZW9mIGRvY3VtZW50PT09InVuZGVmaW5lZCIpe2EobnVsbCkKcmV0dXJufWlmKHR5cGVvZiBk
+b2N1bWVudC5jdXJyZW50U2NyaXB0IT0ndW5kZWZpbmVkJyl7YShkb2N1bWVudC5jdXJyZW50U2NyaXB0
+KQpyZXR1cm59dmFyIHQ9ZG9jdW1lbnQuc2NyaXB0cwpmdW5jdGlvbiBvbkxvYWQoYil7Zm9yKHZhciBy
+PTA7cjx0Lmxlbmd0aDsrK3IpdFtyXS5yZW1vdmVFdmVudExpc3RlbmVyKCJsb2FkIixvbkxvYWQsZmFs
+c2UpCmEoYi50YXJnZXQpfWZvcih2YXIgcz0wO3M8dC5sZW5ndGg7KytzKXRbc10uYWRkRXZlbnRMaXN0
+ZW5lcigibG9hZCIsb25Mb2FkLGZhbHNlKX0pKGZ1bmN0aW9uKGEpe3YuY3VycmVudFNjcmlwdD1hCmlm
+KHR5cGVvZiBkYXJ0TWFpblJ1bm5lcj09PSJmdW5jdGlvbiIpZGFydE1haW5SdW5uZXIoTC5JcSxbXSkK
+ZWxzZSBMLklxKFtdKX0pfSkoKQovLyMgc291cmNlTWFwcGluZ1VSTD1taWdyYXRpb24uanMubWFwCg==
+''';
diff --git a/pkg/analysis_server/lib/src/edit/nnbd_migration/unit_link.dart b/pkg/nnbd_migration/lib/src/front_end/unit_link.dart
similarity index 100%
rename from pkg/analysis_server/lib/src/edit/nnbd_migration/unit_link.dart
rename to pkg/nnbd_migration/lib/src/front_end/unit_link.dart
diff --git a/pkg/analysis_server/lib/src/edit/nnbd_migration/unit_renderer.dart b/pkg/nnbd_migration/lib/src/front_end/unit_renderer.dart
similarity index 96%
rename from pkg/analysis_server/lib/src/edit/nnbd_migration/unit_renderer.dart
rename to pkg/nnbd_migration/lib/src/front_end/unit_renderer.dart
index 080d2c1..8e96fca 100644
--- a/pkg/analysis_server/lib/src/edit/nnbd_migration/unit_renderer.dart
+++ b/pkg/nnbd_migration/lib/src/front_end/unit_renderer.dart
@@ -4,11 +4,11 @@
import 'dart:convert' show HtmlEscape, HtmlEscapeMode, LineSplitter;
-import 'package:analysis_server/src/edit/nnbd_migration/migration_info.dart';
-import 'package:analysis_server/src/edit/nnbd_migration/path_mapper.dart';
-import 'package:analysis_server/src/edit/nnbd_migration/web/file_details.dart';
import 'package:meta/meta.dart';
import 'package:nnbd_migration/nnbd_migration.dart';
+import 'package:nnbd_migration/src/front_end/migration_info.dart';
+import 'package:nnbd_migration/src/front_end/path_mapper.dart';
+import 'package:nnbd_migration/src/front_end/web/file_details.dart';
import 'package:path/path.dart' as path;
/// Instrumentation display output for a library that was migrated to use
@@ -35,6 +35,7 @@
NullabilityFixKind.addType,
NullabilityFixKind.replaceVar,
NullabilityFixKind.removeAs,
+ NullabilityFixKind.addLate,
NullabilityFixKind.addLateDueToHint,
NullabilityFixKind.checkExpressionDueToHint,
NullabilityFixKind.makeTypeNullableDueToHint,
@@ -245,6 +246,8 @@
var s = count == 1 ? '' : 's';
var es = count == 1 ? '' : 'es';
switch (kind) {
+ case NullabilityFixKind.addLate:
+ return '$count late keyword$s added';
case NullabilityFixKind.addLateDueToHint:
return '$count late hint$s converted to late keyword$s';
case NullabilityFixKind.addRequired:
diff --git a/pkg/analysis_server/lib/src/edit/nnbd_migration/web/edit_details.dart b/pkg/nnbd_migration/lib/src/front_end/web/edit_details.dart
similarity index 89%
rename from pkg/analysis_server/lib/src/edit/nnbd_migration/web/edit_details.dart
rename to pkg/nnbd_migration/lib/src/front_end/web/edit_details.dart
index f74657f..1bbfecf 100644
--- a/pkg/analysis_server/lib/src/edit/nnbd_migration/web/edit_details.dart
+++ b/pkg/nnbd_migration/lib/src/front_end/web/edit_details.dart
@@ -34,9 +34,9 @@
EditDetails.fromJson(dynamic json)
: edits = _decodeEdits(json['edits']),
- explanation = json['explanation'],
- line = json['line'],
- path = json['path'],
+ explanation = json['explanation'] as String,
+ line = json['line'] as int,
+ path = json['path'] as String,
traces = _decodeTraces(json['traces']);
Map<String, Object> toJson() => {
@@ -69,8 +69,8 @@
EditLink({@required this.description, @required this.href});
EditLink.fromJson(dynamic json)
- : description = json['description'],
- href = json['href'];
+ : description = json['description'] as String,
+ href = json['href'] as String;
Map<String, Object> toJson() => {
'description': description,
@@ -95,9 +95,9 @@
TargetLink({@required this.href, @required this.line, @required this.path});
TargetLink.fromJson(dynamic json)
- : href = json['href'],
- line = json['line'],
- path = json['path'];
+ : href = json['href'] as String,
+ line = json['line'] as int,
+ path = json['path'] as String;
Map<String, Object> toJson() => {
'href': href,
@@ -117,7 +117,7 @@
Trace({@required this.description, @required this.entries});
Trace.fromJson(dynamic json)
- : description = json['description'],
+ : description = json['description'] as String,
entries = [
for (var entry in json['entries']) TraceEntry.fromJson(entry)
];
@@ -146,8 +146,8 @@
TraceEntry({@required this.description, this.function, this.link});
TraceEntry.fromJson(dynamic json)
- : description = json['description'],
- function = json['function'],
+ : description = json['description'] as String,
+ function = json['function'] as String,
link = _decodeLink(json['link']);
Map<String, Object> toJson() => {
diff --git a/pkg/analysis_server/lib/src/edit/nnbd_migration/web/file_details.dart b/pkg/nnbd_migration/lib/src/front_end/web/file_details.dart
similarity index 87%
rename from pkg/analysis_server/lib/src/edit/nnbd_migration/web/file_details.dart
rename to pkg/nnbd_migration/lib/src/front_end/web/file_details.dart
index cee2167..7b140cf 100644
--- a/pkg/analysis_server/lib/src/edit/nnbd_migration/web/file_details.dart
+++ b/pkg/nnbd_migration/lib/src/front_end/web/file_details.dart
@@ -19,9 +19,9 @@
{@required this.line, @required this.explanation, @required this.offset});
EditListItem.fromJson(dynamic json)
- : line = json['line'],
- explanation = json['explanation'],
- offset = json['offset'];
+ : line = json['line'] as int,
+ explanation = json['explanation'] as String,
+ offset = json['offset'] as int;
Map<String, Object> toJson() =>
{'line': line, 'explanation': explanation, 'offset': offset};
@@ -65,11 +65,11 @@
edits = const {};
FileDetails.fromJson(dynamic json)
- : regions = json['regions'],
- navigationContent = json['navigationContent'],
- sourceCode = json['sourceCode'],
+ : regions = json['regions'] as String,
+ navigationContent = json['navigationContent'] as String,
+ sourceCode = json['sourceCode'] as String,
edits = {
- for (var entry in json['edits'].entries)
+ for (var entry in (json['edits'] as Map<String, Object>).entries)
entry.key: [
for (var edit in entry.value) EditListItem.fromJson(edit)
]
diff --git a/pkg/analysis_server/lib/src/edit/nnbd_migration/web/highlight_js.dart b/pkg/nnbd_migration/lib/src/front_end/web/highlight_js.dart
similarity index 88%
rename from pkg/analysis_server/lib/src/edit/nnbd_migration/web/highlight_js.dart
rename to pkg/nnbd_migration/lib/src/front_end/web/highlight_js.dart
index 7e9901e..82e7daf 100644
--- a/pkg/analysis_server/lib/src/edit/nnbd_migration/web/highlight_js.dart
+++ b/pkg/nnbd_migration/lib/src/front_end/web/highlight_js.dart
@@ -9,7 +9,7 @@
/// A small wrapper around the JavaScript highlight.js APIs.
class HighlightJs {
- static JsObject get _hljs => context['hljs'];
+ static JsObject get _hljs => context['hljs'] as JsObject;
HighlightJs._();
diff --git a/pkg/analysis_server/lib/src/edit/nnbd_migration/web/migration.dart b/pkg/nnbd_migration/lib/src/front_end/web/migration.dart
similarity index 80%
rename from pkg/analysis_server/lib/src/edit/nnbd_migration/web/migration.dart
rename to pkg/nnbd_migration/lib/src/front_end/web/migration.dart
index 4423317..3447983 100644
--- a/pkg/analysis_server/lib/src/edit/nnbd_migration/web/migration.dart
+++ b/pkg/nnbd_migration/lib/src/front_end/web/migration.dart
@@ -6,9 +6,9 @@
import 'dart:convert';
import 'dart:html';
-import 'package:analysis_server/src/edit/nnbd_migration/web/edit_details.dart';
-import 'package:analysis_server/src/edit/nnbd_migration/web/file_details.dart';
-import 'package:analysis_server/src/edit/nnbd_migration/web/navigation_tree.dart';
+import 'package:nnbd_migration/src/front_end/web/edit_details.dart';
+import 'package:nnbd_migration/src/front_end/web/file_details.dart';
+import 'package:nnbd_migration/src/front_end/web/navigation_tree.dart';
import 'package:path/path.dart' as _p;
import 'highlight_js.dart';
@@ -41,9 +41,7 @@
..remove('proposed')
..add('applied');
}).catchError((e, st) {
- logError('apply migration error: $e', st);
-
- window.alert('Could not apply migration ($e).');
+ handleError('Could not apply migration', e, st);
});
}
});
@@ -55,13 +53,20 @@
await doPost('/rerun-migration');
window.location.reload();
} catch (e, st) {
- logError('rerun migration: $e', st);
-
- window.alert('Failed to rerun migration: $e.');
+ handleError('Failed to rerun migration', e, st);
} finally {
document.body.classes.remove('rerunning');
}
});
+
+ final reportProblemButton = document.querySelector('.report-problem');
+ reportProblemButton.onClick.listen((_) {
+ window.open('https://goo.gle/dart-null-safety-migration-tool-issue',
+ 'report-problem');
+ });
+
+ document.querySelector('.popup-pane .close').onClick.listen(
+ (_) => document.querySelector('.popup-pane').style.display = 'none');
});
window.addEventListener('popstate', (event) {
@@ -145,9 +150,9 @@
});
}
- List<Element> postLinks = parentElement.querySelectorAll('.post-link');
- postLinks.forEach((link) {
- link.onClick.listen(handlePostLinkClick);
+ List<Element> addHintLinks = parentElement.querySelectorAll('.add-hint-link');
+ addHintLinks.forEach((link) {
+ link.onClick.listen(handleAddHintLinkClick);
});
}
@@ -156,17 +161,58 @@
HttpRequest.request(pathWithQueryParameters(path, queryParameters),
requestHeaders: {'Content-Type': 'application/json; charset=UTF-8'});
-Future<HttpRequest> doPost(String path) => HttpRequest.request(
- pathWithQueryParameters(path, {}),
- method: 'POST',
- requestHeaders: {'Content-Type': 'application/json; charset=UTF-8'},
- ).then((HttpRequest xhr) {
- if (xhr.status == 200) {
- // Request OK.
- return xhr;
- } else {
- throw 'Request failed; status of ${xhr.status}';
- }
+Future<Map<String, Object>> doPost(String path) async {
+ var completer = new Completer<HttpRequest>();
+
+ var xhr = HttpRequest()
+ ..open('POST', pathWithQueryParameters(path, {}), async: true)
+ ..setRequestHeader('Content-Type', 'application/json; charset=UTF-8');
+
+ xhr.onLoad.listen((e) {
+ completer.complete(xhr);
+ });
+
+ xhr.onError.listen(completer.completeError);
+
+ xhr.send();
+
+ await completer.future;
+
+ final json = jsonDecode(xhr.responseText);
+ if (xhr.status == 200) {
+ // Request OK.
+ return json as Map<String, Object>;
+ } else {
+ throw json;
+ }
+}
+
+Uri getGithubUri(String description, Object exception, Object stackTrace) =>
+ Uri.https('github.com', 'dart-lang/sdk/issues/new', {
+ 'title': 'Issue with NNBD migration tool: $description',
+ 'labels': 'area-analyzer,analyzer-nnbd-migration,type-bug',
+ 'body': '''
+$description
+
+Error: $exception
+
+Please fill in the following:
+
+**Name of package being migrated (if public)**:
+**What I was doing when this issue occurred**:
+**Is it possible to work around this issue**:
+**Has this issue happened before, and if so, how often**:
+**Dart SDK version**: (visible in lower left of migration preview)
+**Additional details**:
+
+Thanks for filing!
+
+Stacktrace: _auto populated by migration preview tool._
+
+```
+$stackTrace
+```
+''',
});
int getLine(String location) {
@@ -179,12 +225,50 @@
return str == null ? null : int.tryParse(str);
}
+void handleAddHintLinkClick(MouseEvent event) async {
+ var path = (event.currentTarget as Element).getAttribute('href');
+
+ // Don't navigate on link click.
+ event.preventDefault();
+
+ try {
+ // Directing the server to produce an edit; request it, then do work with the
+ // response.
+ await doPost(path);
+ // TODO(mfairhurst): Only refresh the regions/dart code, not the window.
+ (document.window.location as Location).reload();
+ } catch (e, st) {
+ handleError('Could not add/remove hint', e, st);
+ }
+}
+
+void handleError(String header, Object exception, Object stackTrace) {
+ String subheader;
+ if (exception is Map<String, Object> &&
+ exception['success'] == false &&
+ exception.containsKey('exception') &&
+ exception.containsKey('stackTrace')) {
+ subheader = exception['exception'] as String;
+ stackTrace = exception['stackTrace'];
+ } else {
+ subheader = exception.toString();
+ }
+ final popupPane = document.querySelector('.popup-pane');
+ popupPane.querySelector('h2').innerText = header;
+ popupPane.querySelector('p').innerText = subheader;
+ popupPane.querySelector('pre').innerText = stackTrace.toString();
+ (popupPane.querySelector('a.bottom') as AnchorElement).href =
+ getGithubUri(header, subheader, stackTrace).toString();
+ popupPane..style.display = 'initial';
+ logError('handlePostLinkClick: $exception', stackTrace);
+}
+
void handleNavLinkClick(
MouseEvent event,
bool clearEditDetails, {
String relativeTo,
}) {
- Element target = event.currentTarget;
+ Element target = event.currentTarget as Element;
event.preventDefault();
var location = target.getAttribute('href');
@@ -211,25 +295,6 @@
}
}
-void handlePostLinkClick(MouseEvent event) async {
- var path = (event.currentTarget as Element).getAttribute('href');
-
- // Don't navigate on link click.
- event.preventDefault();
-
- try {
- // Directing the server to produce an edit; request it, then do work with the
- // response.
- await doPost(path);
- // TODO(mfairhurst): Only refresh the regions/dart code, not the window.
- (document.window.location as Location).reload();
- } catch (e, st) {
- logError('handlePostLinkClick: $e', st);
-
- window.alert('Could not load $path ($e).');
- }
-}
-
void highlightAllCode() {
document.querySelectorAll('.code').forEach((Element block) {
hljs.highlightBlock(block);
@@ -279,7 +344,8 @@
// Navigating to another file; request it, then do work with the response.
doGet(path, queryParameters: {'inline': 'true'}).then((HttpRequest xhr) {
if (xhr.status == 200) {
- Map<String, dynamic> response = jsonDecode(xhr.responseText);
+ Map<String, dynamic> response =
+ jsonDecode(xhr.responseText) as Map<String, dynamic>;
writeCodeAndRegions(
path, FileDetails.fromJson(response), clearEditDetails);
maybeScrollToAndHighlight(offset, line);
@@ -424,9 +490,10 @@
// Clear out any current edit details.
editPanel.innerHtml = '';
if (response == null) {
- Element p = editPanel.append(ParagraphElement()
+ Element p = ParagraphElement()
..text = 'See details about a proposed edit.'
- ..classes = ['placeholder']);
+ ..classes = ['placeholder'];
+ editPanel.append(p);
p.scrollIntoView();
return;
}
@@ -438,7 +505,8 @@
var explanationMessage = response.explanation;
var relPath = _p.relative(filePath, from: rootPath);
var line = response.line;
- Element explanation = editPanel.append(document.createElement('p'));
+ Element explanation = document.createElement('p');
+ editPanel.append(explanation);
explanation.append(Text('$explanationMessage at $relPath:$line.'));
explanation.scrollIntoView();
_populateEditTraces(response, editPanel, parentDirectory);
@@ -452,18 +520,23 @@
var editCount = edits.length;
if (editCount == 0) {
- Element p = editListElement.append(document.createElement('p'));
+ Element p = document.createElement('p');
+ editListElement.append(p);
p.append(Text('No proposed edits'));
} else {
for (var entry in edits.entries) {
- Element p = editListElement.append(document.createElement('p'));
+ Element p = document.createElement('p');
+ editListElement.append(p);
p.append(Text('${entry.key}:'));
- Element list = editListElement.append(document.createElement('ul'));
+ Element list = document.createElement('ul');
+ editListElement.append(list);
for (var edit in entry.value) {
- Element item = list.append(document.createElement('li'));
+ Element item = document.createElement('li');
+ list.append(item);
item.classes.add('edit');
- AnchorElement anchor = item.append(document.createElement('a'));
+ AnchorElement anchor = AnchorElement();
+ item.append(anchor);
anchor.classes.add('edit-link');
var offset = edit.offset;
anchor.dataset['offset'] = '$offset';
@@ -560,22 +633,27 @@
void writeNavigationSubtree(
Element parentElement, List<NavigationTreeNode> tree) {
- Element ul = parentElement.append(document.createElement('ul'));
+ Element ul = document.createElement('ul');
+ parentElement.append(ul);
for (var entity in tree) {
- Element li = ul.append(document.createElement('li'));
+ Element li = document.createElement('li');
+ ul.append(li);
if (entity.type == NavigationTreeNodeType.directory) {
li.classes.add('dir');
- Element arrow = li.append(document.createElement('span'));
+ Element arrow = document.createElement('span');
+ li.append(arrow);
arrow.classes.add('arrow');
arrow.innerHtml = '▼';
- Element icon = li.append(document.createElement('span'));
+ Element icon = document.createElement('span');
+ li.append(icon);
icon.innerHtml = '📁';
li.append(Text(entity.name));
writeNavigationSubtree(li, entity.subtree);
addArrowClickHandler(arrow);
} else {
li.innerHtml = '📄';
- Element a = li.append(document.createElement('a'));
+ Element a = document.createElement('a');
+ li.append(a);
a.classes.add('nav-link');
a.dataset['name'] = entity.path;
a.setAttribute('href', entity.href);
@@ -583,7 +661,8 @@
a.onClick.listen((MouseEvent event) => handleNavLinkClick(event, true));
var editCount = entity.editCount;
if (editCount > 0) {
- Element editsBadge = li.append(document.createElement('span'));
+ Element editsBadge = document.createElement('span');
+ li.append(editsBadge);
editsBadge.classes.add('edit-count');
editsBadge.setAttribute(
'title', '$editCount ${pluralize(editCount, 'edit')}');
@@ -595,7 +674,7 @@
AnchorElement _aElementForLink(TargetLink link, String parentDirectory) {
var targetLine = link.line;
- AnchorElement a = document.createElement('a');
+ AnchorElement a = AnchorElement();
a.append(Text('${link.path}:$targetLine'));
var relLink = link.href;
@@ -608,12 +687,14 @@
void _populateEditLinks(EditDetails response, Element editPanel) {
if (response.edits != null) {
- Element editParagraph = editPanel.append(document.createElement('p'));
+ Element editParagraph = document.createElement('p');
+ editPanel.append(editParagraph);
for (var edit in response.edits) {
- Element a = editParagraph.append(document.createElement('a'));
+ Element a = document.createElement('a');
+ editParagraph.append(a);
a.append(Text(edit.description));
a.setAttribute('href', edit.href);
- a.classes = ['post-link', 'before-apply'];
+ a.classes = ['add-hint-link', 'before-apply', 'button'];
}
}
}
@@ -630,8 +711,8 @@
var ul = traceParagraph
.append(document.createElement('ul')..classes = ['trace']);
for (var entry in trace.entries) {
- Element li =
- ul.append(document.createElement('li')..innerHtml = '❏ ');
+ Element li = document.createElement('li')..innerHtml = '❏ ';
+ ul.append(li);
li.append(document.createElement('span')
..classes = ['function']
..appendTextWithBreaks(entry.function ?? 'unknown'));
diff --git a/pkg/analysis_server/lib/src/edit/nnbd_migration/web/navigation_tree.dart b/pkg/nnbd_migration/lib/src/front_end/web/navigation_tree.dart
similarity index 93%
rename from pkg/analysis_server/lib/src/edit/nnbd_migration/web/navigation_tree.dart
rename to pkg/nnbd_migration/lib/src/front_end/web/navigation_tree.dart
index 096574d..de29189 100644
--- a/pkg/analysis_server/lib/src/edit/nnbd_migration/web/navigation_tree.dart
+++ b/pkg/nnbd_migration/lib/src/front_end/web/navigation_tree.dart
@@ -44,12 +44,12 @@
subtree = null;
NavigationTreeNode.fromJson(dynamic json)
- : type = _decodeType(json['type']),
- name = json['name'],
+ : type = _decodeType(json['type'] as String),
+ name = json['name'] as String,
subtree = listFromJsonOrNull(json['subtree']),
- path = json['path'],
- href = json['href'],
- editCount = json['editCount'];
+ path = json['path'] as String,
+ href = json['href'] as String,
+ editCount = json['editCount'] as int;
Map<String, Object> toJson() => {
'type': _encodeType(type),
diff --git a/pkg/nnbd_migration/lib/src/nullability_node.dart b/pkg/nnbd_migration/lib/src/nullability_node.dart
index 44175cb..75e9e9b 100644
--- a/pkg/nnbd_migration/lib/src/nullability_node.dart
+++ b/pkg/nnbd_migration/lib/src/nullability_node.dart
@@ -86,6 +86,9 @@
final String description;
+ /// Whether this edge is the result of an uninitialized variable declaration.
+ final bool isUninit;
+
NullabilityEdge.fromJson(
dynamic json, NullabilityGraphDeserializer deserializer)
: destinationNode = deserializer.nodeForId(json['dest'] as int),
@@ -93,7 +96,8 @@
_kind = _deserializeKind(json['kind']),
codeReference =
json['code'] == null ? null : CodeReference.fromJson(json['code']),
- description = json['description'] as String {
+ description = json['description'] as String,
+ isUninit = json['isUninit'] as bool {
deserializer.defer(() {
for (var id in json['us'] as List<dynamic>) {
upstreamNodes.add(deserializer.nodeForId(id as int));
@@ -103,7 +107,7 @@
NullabilityEdge._(
this.destinationNode, this.upstreamNodes, this._kind, this.description,
- {this.codeReference});
+ {this.codeReference, this.isUninit});
@override
Iterable<NullabilityNode> get guards => upstreamNodes.skip(1);
@@ -440,9 +444,12 @@
NullabilityNode destinationNode,
_NullabilityEdgeKind kind,
EdgeOrigin origin) {
+ var isUninit = origin?.kind == EdgeOriginKind.fieldNotInitialized ||
+ origin?.kind == EdgeOriginKind.implicitNullInitializer ||
+ origin?.kind == EdgeOriginKind.uninitializedRead;
var edge = NullabilityEdge._(
destinationNode, upstreamNodes, kind, origin?.description,
- codeReference: origin?.codeReference);
+ codeReference: origin?.codeReference, isUninit: isUninit);
instrumentation?.graphEdge(edge, origin);
for (var upstreamNode in upstreamNodes) {
_connectDownstream(upstreamNode, edge);
@@ -666,6 +673,8 @@
/// variables. Over time this will be replaced by a first class representation
/// of the nullability inference graph.
abstract class NullabilityNode implements NullabilityNodeInfo {
+ bool _isLate = false;
+
bool _isPossiblyOptional = false;
/// List of [NullabilityEdge] objects describing this node's relationship to
@@ -767,6 +776,10 @@
@visibleForTesting
bool get isExactNullable;
+ /// Indicates whether this node is associated with a variable declaration
+ /// which should be annotated with "late".
+ bool get isLate => _isLate;
+
/// After nullability propagation, this getter can be used to query whether
/// the type associated with this node should be considered nullable.
@override
@@ -1401,11 +1414,32 @@
continue;
}
}
+ if (edge.isUninit) {
+ // This is an edge from always to an uninitialized variable
+ // declaration.
+
+ // Whether all downstream edges go to nodes with non-null intent.
+ var allDownstreamHaveNonNullIntent = false;
+ if (node.downstreamEdges.isNotEmpty) {
+ allDownstreamHaveNonNullIntent = node.downstreamEdges.every((e) {
+ var destination = e.destinationNode;
+ return destination is NullabilityNode &&
+ destination.nonNullIntent.isPresent;
+ });
+ }
+ if (allDownstreamHaveNonNullIntent) {
+ if (!node.isNullable) {
+ node._isLate = true;
+ }
+ continue;
+ }
+ }
if (node is NullabilityNodeMutable && !node.isNullable) {
assert(step.targetNode == null);
step.targetNode = node;
step.newState = Nullability.ordinaryNullable;
_setNullable(step);
+ node._isLate = false;
}
}
if (_pendingSubstitutions.isEmpty) break;
diff --git a/pkg/analysis_server/lib/src/edit/preview/dart_file_page.dart b/pkg/nnbd_migration/lib/src/preview/dart_file_page.dart
similarity index 80%
rename from pkg/analysis_server/lib/src/edit/preview/dart_file_page.dart
rename to pkg/nnbd_migration/lib/src/preview/dart_file_page.dart
index 7f7da1f..12aff05 100644
--- a/pkg/analysis_server/lib/src/edit/preview/dart_file_page.dart
+++ b/pkg/nnbd_migration/lib/src/preview/dart_file_page.dart
@@ -4,10 +4,10 @@
import 'dart:convert';
-import 'package:analysis_server/src/edit/nnbd_migration/migration_info.dart';
-import 'package:analysis_server/src/edit/nnbd_migration/unit_renderer.dart';
-import 'package:analysis_server/src/edit/preview/preview_page.dart';
-import 'package:analysis_server/src/edit/preview/preview_site.dart';
+import 'package:nnbd_migration/src/front_end/migration_info.dart';
+import 'package:nnbd_migration/src/front_end/unit_renderer.dart';
+import 'package:nnbd_migration/src/preview/preview_page.dart';
+import 'package:nnbd_migration/src/preview/preview_site.dart';
/// The page that is displayed when a preview of a valid Dart file is requested.
class DartFilePage extends PreviewPage {
diff --git a/pkg/analysis_server/lib/src/edit/preview/exception_page.dart b/pkg/nnbd_migration/lib/src/preview/exception_page.dart
similarity index 90%
rename from pkg/analysis_server/lib/src/edit/preview/exception_page.dart
rename to pkg/nnbd_migration/lib/src/preview/exception_page.dart
index bb18409..2d8abcc 100644
--- a/pkg/analysis_server/lib/src/edit/preview/exception_page.dart
+++ b/pkg/nnbd_migration/lib/src/preview/exception_page.dart
@@ -4,8 +4,8 @@
import 'dart:convert';
-import 'package:analysis_server/src/edit/preview/preview_page.dart';
-import 'package:analysis_server/src/edit/preview/preview_site.dart';
+import 'package:nnbd_migration/src/preview/preview_page.dart';
+import 'package:nnbd_migration/src/preview/preview_site.dart';
/// The page that is displayed when an exception is encountered in the process
/// of composing the content of a different page.
diff --git a/pkg/analysis_server/lib/src/edit/preview/highlight_css_page.dart b/pkg/nnbd_migration/lib/src/preview/highlight_css_page.dart
similarity index 78%
rename from pkg/analysis_server/lib/src/edit/preview/highlight_css_page.dart
rename to pkg/nnbd_migration/lib/src/preview/highlight_css_page.dart
index 0104a69..7553358 100644
--- a/pkg/analysis_server/lib/src/edit/preview/highlight_css_page.dart
+++ b/pkg/nnbd_migration/lib/src/preview/highlight_css_page.dart
@@ -4,10 +4,10 @@
import 'dart:async';
-import 'package:analysis_server/src/edit/nnbd_migration/resources/resources.g.dart'
+import 'package:nnbd_migration/src/front_end/resources/resources.g.dart'
as resources;
-import 'package:analysis_server/src/edit/preview/preview_page.dart';
-import 'package:analysis_server/src/edit/preview/preview_site.dart';
+import 'package:nnbd_migration/src/preview/preview_page.dart';
+import 'package:nnbd_migration/src/preview/preview_site.dart';
/// The page that contains the CSS used to style the semantic highlighting
/// within a Dart file.
diff --git a/pkg/analysis_server/lib/src/edit/preview/highlight_js_page.dart b/pkg/nnbd_migration/lib/src/preview/highlight_js_page.dart
similarity index 78%
rename from pkg/analysis_server/lib/src/edit/preview/highlight_js_page.dart
rename to pkg/nnbd_migration/lib/src/preview/highlight_js_page.dart
index 6fb15b0..177266c 100644
--- a/pkg/analysis_server/lib/src/edit/preview/highlight_js_page.dart
+++ b/pkg/nnbd_migration/lib/src/preview/highlight_js_page.dart
@@ -4,10 +4,10 @@
import 'dart:async';
-import 'package:analysis_server/src/edit/nnbd_migration/resources/resources.g.dart'
+import 'package:nnbd_migration/src/front_end/resources/resources.g.dart'
as resources;
-import 'package:analysis_server/src/edit/preview/preview_page.dart';
-import 'package:analysis_server/src/edit/preview/preview_site.dart';
+import 'package:nnbd_migration/src/preview/preview_page.dart';
+import 'package:nnbd_migration/src/preview/preview_site.dart';
/// The page that contains the JavaScript used to apply semantic highlighting
/// styles to a Dart file.
diff --git a/pkg/analysis_server/lib/src/edit/preview/http_preview_server.dart b/pkg/nnbd_migration/lib/src/preview/http_preview_server.dart
similarity index 96%
rename from pkg/analysis_server/lib/src/edit/preview/http_preview_server.dart
rename to pkg/nnbd_migration/lib/src/preview/http_preview_server.dart
index ccdcde1..5c95f02 100644
--- a/pkg/analysis_server/lib/src/edit/preview/http_preview_server.dart
+++ b/pkg/nnbd_migration/lib/src/preview/http_preview_server.dart
@@ -5,8 +5,8 @@
import 'dart:async';
import 'dart:io';
-import 'package:analysis_server/src/edit/nnbd_migration/migration_state.dart';
-import 'package:analysis_server/src/edit/preview/preview_site.dart';
+import 'package:nnbd_migration/src/front_end/migration_state.dart';
+import 'package:nnbd_migration/src/preview/preview_site.dart';
/// Instances of the class [AbstractGetHandler] handle GET requests.
abstract class AbstractGetHandler {
diff --git a/pkg/analysis_server/lib/src/edit/preview/index_file_page.dart b/pkg/nnbd_migration/lib/src/preview/index_file_page.dart
similarity index 80%
rename from pkg/analysis_server/lib/src/edit/preview/index_file_page.dart
rename to pkg/nnbd_migration/lib/src/preview/index_file_page.dart
index 7931445..b67d12c 100644
--- a/pkg/analysis_server/lib/src/edit/preview/index_file_page.dart
+++ b/pkg/nnbd_migration/lib/src/preview/index_file_page.dart
@@ -2,9 +2,9 @@
// 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:analysis_server/src/edit/nnbd_migration/instrumentation_renderer.dart';
-import 'package:analysis_server/src/edit/preview/preview_page.dart';
-import 'package:analysis_server/src/edit/preview/preview_site.dart';
+import 'package:nnbd_migration/src/front_end/instrumentation_renderer.dart';
+import 'package:nnbd_migration/src/preview/preview_page.dart';
+import 'package:nnbd_migration/src/preview/preview_site.dart';
/// The page that is displayed when the root of the included path is requested.
class IndexFilePage extends PreviewPage {
diff --git a/pkg/analysis_server/lib/src/edit/preview/navigation_tree_page.dart b/pkg/nnbd_migration/lib/src/preview/navigation_tree_page.dart
similarity index 76%
rename from pkg/analysis_server/lib/src/edit/preview/navigation_tree_page.dart
rename to pkg/nnbd_migration/lib/src/preview/navigation_tree_page.dart
index 415d6f6..5ee145f 100644
--- a/pkg/analysis_server/lib/src/edit/preview/navigation_tree_page.dart
+++ b/pkg/nnbd_migration/lib/src/preview/navigation_tree_page.dart
@@ -4,10 +4,10 @@
import 'dart:convert';
-import 'package:analysis_server/src/edit/nnbd_migration/navigation_tree_renderer.dart';
-import 'package:analysis_server/src/edit/nnbd_migration/web/navigation_tree.dart';
-import 'package:analysis_server/src/edit/preview/preview_page.dart';
-import 'package:analysis_server/src/edit/preview/preview_site.dart';
+import 'package:nnbd_migration/src/front_end/navigation_tree_renderer.dart';
+import 'package:nnbd_migration/src/front_end/web/navigation_tree.dart';
+import 'package:nnbd_migration/src/preview/preview_page.dart';
+import 'package:nnbd_migration/src/preview/preview_site.dart';
/// The JSON that is displayed for the navigation tree.
class NavigationTreePage extends PreviewPage {
diff --git a/pkg/analysis_server/lib/src/edit/preview/not_found_page.dart b/pkg/nnbd_migration/lib/src/preview/not_found_page.dart
similarity index 84%
rename from pkg/analysis_server/lib/src/edit/preview/not_found_page.dart
rename to pkg/nnbd_migration/lib/src/preview/not_found_page.dart
index 5865b5f..7eca477 100644
--- a/pkg/analysis_server/lib/src/edit/preview/not_found_page.dart
+++ b/pkg/nnbd_migration/lib/src/preview/not_found_page.dart
@@ -2,8 +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.
-import 'package:analysis_server/src/edit/preview/preview_page.dart';
-import 'package:analysis_server/src/edit/preview/preview_site.dart';
+import 'package:nnbd_migration/src/preview/preview_page.dart';
+import 'package:nnbd_migration/src/preview/preview_site.dart';
/// The page that is displayed when an invalid URL is requested.
class NotFoundPage extends PreviewPage {
diff --git a/pkg/analysis_server/lib/src/edit/preview/preview_page.dart b/pkg/nnbd_migration/lib/src/preview/preview_page.dart
similarity index 95%
rename from pkg/analysis_server/lib/src/edit/preview/preview_page.dart
rename to pkg/nnbd_migration/lib/src/preview/preview_page.dart
index b82a4ef..7cebe8c 100644
--- a/pkg/analysis_server/lib/src/edit/preview/preview_page.dart
+++ b/pkg/nnbd_migration/lib/src/preview/preview_page.dart
@@ -4,7 +4,7 @@
import 'dart:async';
-import 'package:analysis_server/src/edit/preview/preview_site.dart';
+import 'package:nnbd_migration/src/preview/preview_site.dart';
import 'package:analysis_server/src/status/pages.dart';
/// A page displayed on the preview site.
diff --git a/pkg/analysis_server/lib/src/edit/preview/preview_site.dart b/pkg/nnbd_migration/lib/src/preview/preview_site.dart
similarity index 86%
rename from pkg/analysis_server/lib/src/edit/preview/preview_site.dart
rename to pkg/nnbd_migration/lib/src/preview/preview_site.dart
index 96941ce..8d0b4f9 100644
--- a/pkg/analysis_server/lib/src/edit/preview/preview_site.dart
+++ b/pkg/nnbd_migration/lib/src/preview/preview_site.dart
@@ -8,22 +8,22 @@
import 'dart:math';
import 'dart:typed_data';
-import 'package:analysis_server/src/edit/nnbd_migration/migration_info.dart';
-import 'package:analysis_server/src/edit/nnbd_migration/migration_state.dart';
-import 'package:analysis_server/src/edit/nnbd_migration/path_mapper.dart';
-import 'package:analysis_server/src/edit/preview/dart_file_page.dart';
-import 'package:analysis_server/src/edit/preview/exception_page.dart';
-import 'package:analysis_server/src/edit/preview/highlight_css_page.dart';
-import 'package:analysis_server/src/edit/preview/highlight_js_page.dart';
-import 'package:analysis_server/src/edit/preview/http_preview_server.dart';
-import 'package:analysis_server/src/edit/preview/index_file_page.dart';
-import 'package:analysis_server/src/edit/preview/navigation_tree_page.dart';
-import 'package:analysis_server/src/edit/preview/not_found_page.dart';
-import 'package:analysis_server/src/edit/preview/preview_page.dart';
-import 'package:analysis_server/src/edit/preview/region_page.dart';
-import 'package:analysis_server/src/edit/preview/unauthorized_page.dart';
-import 'package:analysis_server/src/protocol_server.dart';
+import 'package:analyzer_plugin/protocol/protocol_common.dart';
import 'package:analysis_server/src/status/pages.dart';
+import 'package:nnbd_migration/src/front_end/migration_info.dart';
+import 'package:nnbd_migration/src/front_end/migration_state.dart';
+import 'package:nnbd_migration/src/front_end/path_mapper.dart';
+import 'package:nnbd_migration/src/preview/dart_file_page.dart';
+import 'package:nnbd_migration/src/preview/exception_page.dart';
+import 'package:nnbd_migration/src/preview/highlight_css_page.dart';
+import 'package:nnbd_migration/src/preview/highlight_js_page.dart';
+import 'package:nnbd_migration/src/preview/http_preview_server.dart';
+import 'package:nnbd_migration/src/preview/index_file_page.dart';
+import 'package:nnbd_migration/src/preview/navigation_tree_page.dart';
+import 'package:nnbd_migration/src/preview/not_found_page.dart';
+import 'package:nnbd_migration/src/preview/preview_page.dart';
+import 'package:nnbd_migration/src/preview/region_page.dart';
+import 'package:nnbd_migration/src/preview/unauthorized_page.dart';
// The randomly generated auth token used to access the preview site.
String _makeAuthToken() {
@@ -94,6 +94,15 @@
return ExceptionPage(this, path, message, stackTrace);
}
+ /// Return a page used to display an exception that occurred while attempting
+ /// to render another page. The [path] is the path to the page that was being
+ /// rendered when the exception was thrown. The [message] and [stackTrace] are
+ /// those from the exception.
+ Page createJsonExceptionResponse(
+ String path, String message, StackTrace stackTrace) {
+ return ExceptionPage(this, path, message, stackTrace);
+ }
+
Page createUnauthorizedPage(String unauthorizedPath) {
return UnauthorizedPage(this, unauthorizedPath.substring(1));
}
@@ -310,6 +319,16 @@
Future<void> _respondInternalError(HttpRequest request, String path,
dynamic exception, StackTrace stackTrace) async {
try {
+ if (request.headers.contentType.subType == 'json') {
+ return await respondJson(
+ request,
+ {
+ 'success': false,
+ 'exception': exception.toString(),
+ 'stackTrace': stackTrace.toString(),
+ },
+ HttpStatus.internalServerError);
+ }
await respond(
request,
createExceptionPageWithPath(path, '$exception', stackTrace),
diff --git a/pkg/analysis_server/lib/src/edit/preview/region_page.dart b/pkg/nnbd_migration/lib/src/preview/region_page.dart
similarity index 79%
rename from pkg/analysis_server/lib/src/edit/preview/region_page.dart
rename to pkg/nnbd_migration/lib/src/preview/region_page.dart
index 89b67f0..cb8dd99 100644
--- a/pkg/analysis_server/lib/src/edit/preview/region_page.dart
+++ b/pkg/nnbd_migration/lib/src/preview/region_page.dart
@@ -4,10 +4,10 @@
import 'dart:convert' show jsonEncode;
-import 'package:analysis_server/src/edit/nnbd_migration/migration_info.dart';
-import 'package:analysis_server/src/edit/nnbd_migration/region_renderer.dart';
-import 'package:analysis_server/src/edit/preview/preview_page.dart';
-import 'package:analysis_server/src/edit/preview/preview_site.dart';
+import 'package:nnbd_migration/src/front_end/migration_info.dart';
+import 'package:nnbd_migration/src/front_end/region_renderer.dart';
+import 'package:nnbd_migration/src/preview/preview_page.dart';
+import 'package:nnbd_migration/src/preview/preview_site.dart';
/// The HTML that is displayed for a region of code.
class RegionPage extends PreviewPage {
diff --git a/pkg/analysis_server/lib/src/edit/preview/unauthorized_page.dart b/pkg/nnbd_migration/lib/src/preview/unauthorized_page.dart
similarity index 84%
rename from pkg/analysis_server/lib/src/edit/preview/unauthorized_page.dart
rename to pkg/nnbd_migration/lib/src/preview/unauthorized_page.dart
index e93f426..8fff1c5 100644
--- a/pkg/analysis_server/lib/src/edit/preview/unauthorized_page.dart
+++ b/pkg/nnbd_migration/lib/src/preview/unauthorized_page.dart
@@ -2,8 +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.
-import 'package:analysis_server/src/edit/preview/preview_page.dart';
-import 'package:analysis_server/src/edit/preview/preview_site.dart';
+import 'package:nnbd_migration/src/preview/preview_page.dart';
+import 'package:nnbd_migration/src/preview/preview_site.dart';
/// The page that is displayed when a request could not be authenticated.
class UnauthorizedPage extends PreviewPage {
diff --git a/pkg/nnbd_migration/test/api_test.dart b/pkg/nnbd_migration/test/api_test.dart
index 615a4bb..0a186f4 100644
--- a/pkg/nnbd_migration/test/api_test.dart
+++ b/pkg/nnbd_migration/test/api_test.dart
@@ -1898,6 +1898,30 @@
await _checkSingleFileChanges(content, expected);
}
+ Future<void> test_field_final_uninitalized_used() async {
+ var content = '''
+class C {
+ final String s;
+
+ f() {
+ g(s);
+ }
+}
+g(String /*!*/ s) {}
+''';
+ var expected = '''
+class C {
+ late final String s;
+
+ f() {
+ g(s);
+ }
+}
+g(String s) {}
+''';
+ await _checkSingleFileChanges(content, expected);
+ }
+
Future<void> test_field_formal_param_typed() async {
var content = '''
class C {
@@ -2260,6 +2284,54 @@
await _checkSingleFileChanges(content, expected);
}
+ Future<void> test_field_uninitalized_used() async {
+ var content = '''
+class C {
+ String s;
+
+ f() {
+ g(s);
+ }
+}
+g(String /*!*/ s) {}
+''';
+ var expected = '''
+class C {
+ late String s;
+
+ f() {
+ g(s);
+ }
+}
+g(String s) {}
+''';
+ await _checkSingleFileChanges(content, expected);
+ }
+
+ Future<void> test_field_uninitalized_used_hint() async {
+ var content = '''
+class C {
+ String /*?*/ s;
+
+ f() {
+ g(s);
+ }
+}
+g(String /*!*/ s) {}
+''';
+ var expected = '''
+class C {
+ String? s;
+
+ f() {
+ g(s!);
+ }
+}
+g(String s) {}
+''';
+ await _checkSingleFileChanges(content, expected);
+ }
+
Future<void> test_flow_analysis_complex() async {
var content = '''
int f(int x) {
@@ -3387,14 +3459,14 @@
''';
var expected = '''
int f() {
- int? i;
+ late int i;
g(int j) {
i = 1;
};
((int j) {
i = 1;
});
- return i! + 1;
+ return i + 1;
}
''';
await _checkSingleFileChanges(content, expected);
@@ -3420,6 +3492,113 @@
await _checkSingleFileChanges(content, expected);
}
+ Future<void> test_localVariable_uninitalized_assigned_non_nullable() async {
+ var content = '''
+f() {
+ String s;
+ if (1 == 2) s = g();
+ h(s);
+}
+String /*!*/ g() => "Hello";
+h(String /*!*/ s) {}
+''';
+ var expected = '''
+f() {
+ late String s;
+ if (1 == 2) s = g();
+ h(s);
+}
+String g() => "Hello";
+h(String s) {}
+''';
+ await _checkSingleFileChanges(content, expected);
+ }
+
+ Future<void> test_localVariable_uninitalized_used() async {
+ var content = '''
+f() {
+ String s;
+ if (1 == 2) s = "Hello";
+ g(s);
+}
+g(String /*!*/ s) {}
+''';
+ var expected = '''
+f() {
+ late String s;
+ if (1 == 2) s = "Hello";
+ g(s);
+}
+g(String s) {}
+''';
+ await _checkSingleFileChanges(content, expected);
+ }
+
+ Future<void> test_localVariable_uninitalized_usedInComparison() async {
+ var content = '''
+f() {
+ String s;
+ if (s == null) {}
+}
+''';
+ var expected = '''
+f() {
+ String? s;
+ if (s == null) {}
+}
+''';
+ await _checkSingleFileChanges(content, expected);
+ }
+
+ Future<void>
+ test_localVariable_uninitalized_usedInExpressionStatement() async {
+ var content = '''
+f() {
+ String s;
+ s;
+}
+''';
+ var expected = '''
+f() {
+ String? s;
+ s;
+}
+''';
+ await _checkSingleFileChanges(content, expected);
+ }
+
+ Future<void> test_localVariable_uninitalized_usedInForUpdaters() async {
+ var content = '''
+f() {
+ String s;
+ for (s;;) {}
+}
+''';
+ var expected = '''
+f() {
+ String? s;
+ for (s;;) {}
+}
+''';
+ await _checkSingleFileChanges(content, expected);
+ }
+
+ Future<void> test_localVariable_uninitalized_usedInForVariable() async {
+ var content = '''
+f() {
+ String s;
+ for (;; s) {}
+}
+''';
+ var expected = '''
+f() {
+ String? s;
+ for (;; s) {}
+}
+''';
+ await _checkSingleFileChanges(content, expected);
+ }
+
Future<void> test_make_downcast_explicit() async {
var content = 'int f(num n) => n;';
var expected = 'int f(num n) => n as int;';
@@ -4845,6 +5024,24 @@
await _checkSingleFileChanges(content, expected);
}
+ Future<void> test_topLevelVariable_uninitalized_used() async {
+ var content = '''
+String s;
+f() {
+ g(s);
+}
+g(String /*!*/ s) {}
+''';
+ var expected = '''
+late String s;
+f() {
+ g(s);
+}
+g(String s) {}
+''';
+ await _checkSingleFileChanges(content, expected);
+ }
+
Future<void> test_two_files() async {
var root = '/home/test/lib';
var path1 = convertPath('$root/file1.dart');
diff --git a/pkg/nnbd_migration/test/front_end/analysis_abstract.dart b/pkg/nnbd_migration/test/front_end/analysis_abstract.dart
new file mode 100644
index 0000000..f4833cc
--- /dev/null
+++ b/pkg/nnbd_migration/test/front_end/analysis_abstract.dart
@@ -0,0 +1,217 @@
+// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:async';
+
+import 'package:analysis_server/protocol/protocol.dart';
+import 'package:analysis_server/protocol/protocol_constants.dart';
+import 'package:analysis_server/protocol/protocol_generated.dart'
+ hide AnalysisOptions;
+import 'package:analysis_server/src/analysis_server.dart';
+import 'package:analysis_server/src/domain_analysis.dart';
+import 'package:analysis_server/src/server/crash_reporting_attachments.dart';
+import 'package:analysis_server/src/utilities/mocks.dart';
+import 'package:analyzer/instrumentation/instrumentation.dart';
+import 'package:analyzer/src/dart/analysis/driver.dart';
+import 'package:analyzer/src/generated/engine.dart';
+import 'package:analyzer/src/generated/sdk.dart';
+import 'package:analyzer/src/test_utilities/mock_sdk.dart';
+import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart';
+import 'package:test/test.dart';
+
+import 'mocks.dart';
+
+/// An abstract base for all 'analysis' domain tests.
+class AbstractAnalysisTest with ResourceProviderMixin {
+ bool generateSummaryFiles = false;
+ MockServerChannel serverChannel;
+ TestPluginManager pluginManager;
+ AnalysisServer server;
+ RequestHandler handler;
+
+ final List<GeneralAnalysisService> generalServices =
+ <GeneralAnalysisService>[];
+ final Map<AnalysisService, List<String>> analysisSubscriptions = {};
+
+ String projectPath;
+ String testFolder;
+ String testFile;
+ String testCode;
+
+ AbstractAnalysisTest();
+
+ AnalysisDomainHandler get analysisHandler =>
+ server.handlers.singleWhere((handler) => handler is AnalysisDomainHandler)
+ as AnalysisDomainHandler;
+
+ AnalysisOptions get analysisOptions => testDiver.analysisOptions;
+
+ AnalysisDriver get testDiver => server.getAnalysisDriver(testFile);
+
+ void addAnalysisOptionsFile(String content) {
+ newFile(
+ resourceProvider.pathContext.join(projectPath, 'analysis_options.yaml'),
+ content: content);
+ }
+
+ void addAnalysisSubscription(AnalysisService service, String file) {
+ // add file to subscription
+ var files = analysisSubscriptions[service];
+ if (files == null) {
+ files = <String>[];
+ analysisSubscriptions[service] = files;
+ }
+ files.add(file);
+ // set subscriptions
+ var request =
+ AnalysisSetSubscriptionsParams(analysisSubscriptions).toRequest('0');
+ handleSuccessfulRequest(request);
+ }
+
+ void addGeneralAnalysisSubscription(GeneralAnalysisService service) {
+ generalServices.add(service);
+ var request =
+ AnalysisSetGeneralSubscriptionsParams(generalServices).toRequest('0');
+ handleSuccessfulRequest(request);
+ }
+
+ String addTestFile(String content) {
+ newFile(testFile, content: content);
+ testCode = content;
+ return testFile;
+ }
+
+ /// Create an analysis options file based on the given arguments.
+ void createAnalysisOptionsFile({List<String> experiments}) {
+ var buffer = StringBuffer();
+ if (experiments != null) {
+ buffer.writeln('analyzer:');
+ buffer.writeln(' enable-experiment:');
+ for (var experiment in experiments) {
+ buffer.writeln(' - $experiment');
+ }
+ }
+ addAnalysisOptionsFile(buffer.toString());
+ }
+
+ AnalysisServer createAnalysisServer() {
+ //
+ // Create an SDK in the mock file system.
+ //
+ MockSdk(
+ generateSummaryFiles: generateSummaryFiles,
+ resourceProvider: resourceProvider);
+ //
+ // Create server
+ //
+ var options = AnalysisServerOptions();
+ return AnalysisServer(
+ serverChannel,
+ resourceProvider,
+ options,
+ DartSdkManager(resourceProvider.convertPath('/sdk'), true),
+ CrashReportingAttachmentsBuilder.empty,
+ InstrumentationService.NULL_SERVICE);
+ }
+
+ /// Creates a project [projectPath].
+ void createProject({Map<String, String> packageRoots}) {
+ newFolder(projectPath);
+ var request = AnalysisSetAnalysisRootsParams([projectPath], [],
+ packageRoots: packageRoots)
+ .toRequest('0');
+ handleSuccessfulRequest(request, handler: analysisHandler);
+ }
+
+ void doAllDeclarationsTrackerWork() {
+ while (server.declarationsTracker.hasWork) {
+ server.declarationsTracker.doWork();
+ }
+ }
+
+ /// Returns the offset of [search] in the file at the given [path].
+ /// Fails if not found.
+ int findFileOffset(String path, String search) {
+ var file = getFile(path);
+ var code = file.createSource().contents.data;
+ var offset = code.indexOf(search);
+ expect(offset, isNot(-1), reason: '"$search" in\n$code');
+ return offset;
+ }
+
+ /// Returns the offset of [search] in [testCode].
+ /// Fails if not found.
+ int findOffset(String search) {
+ var offset = testCode.indexOf(search);
+ expect(offset, isNot(-1));
+ return offset;
+ }
+
+ /// Validates that the given [request] is handled successfully.
+ Response handleSuccessfulRequest(Request request, {RequestHandler handler}) {
+ handler ??= this.handler;
+ var response = handler.handleRequest(request);
+ expect(response, isResponseSuccess(request.id));
+ return response;
+ }
+
+ String modifyTestFile(String content) {
+ modifyFile(testFile, content);
+ testCode = content;
+ return testFile;
+ }
+
+ void processNotification(Notification notification) {
+ if (notification.event == SERVER_NOTIFICATION_ERROR) {
+ fail('${notification.toJson()}');
+ }
+ }
+
+ void removeGeneralAnalysisSubscription(GeneralAnalysisService service) {
+ generalServices.remove(service);
+ var request =
+ AnalysisSetGeneralSubscriptionsParams(generalServices).toRequest('0');
+ handleSuccessfulRequest(request);
+ }
+
+ void setPriorityFiles(List<String> files) {
+ var request = AnalysisSetPriorityFilesParams(files).toRequest('0');
+ handleSuccessfulRequest(request);
+ }
+
+ void setUp() {
+ serverChannel = MockServerChannel();
+ projectPath = convertPath('/project');
+ testFolder = convertPath('/project/bin');
+ testFile = convertPath('/project/bin/test.dart');
+ pluginManager = TestPluginManager();
+ server = createAnalysisServer();
+ server.pluginManager = pluginManager;
+ handler = analysisHandler;
+ // listen for notifications
+ var notificationStream = serverChannel.notificationController.stream;
+ notificationStream.listen((Notification notification) {
+ processNotification(notification);
+ });
+ }
+
+ void tearDown() {
+ server.done();
+ handler = null;
+ server = null;
+ serverChannel = null;
+ }
+
+ /// Returns a [Future] that completes when the server's analysis is complete.
+ Future waitForTasksFinished() {
+ return server.onAnalysisComplete;
+ }
+
+ /// Completes with a successful [Response] for the given [request].
+ /// Otherwise fails.
+ Future<Response> waitResponse(Request request,
+ {bool throwOnError = true}) async {
+ return serverChannel.sendRequest(request, throwOnError: throwOnError);
+ }
+}
diff --git a/pkg/analysis_server/test/src/edit/nnbd_migration/info_builder_test.dart b/pkg/nnbd_migration/test/front_end/info_builder_test.dart
similarity index 93%
rename from pkg/analysis_server/test/src/edit/nnbd_migration/info_builder_test.dart
rename to pkg/nnbd_migration/test/front_end/info_builder_test.dart
index 0dc0d54..cba5d32 100644
--- a/pkg/analysis_server/test/src/edit/nnbd_migration/info_builder_test.dart
+++ b/pkg/nnbd_migration/test/front_end/info_builder_test.dart
@@ -2,16 +2,16 @@
// 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:analysis_server/src/edit/nnbd_migration/info_builder.dart';
-import 'package:analysis_server/src/edit/nnbd_migration/migration_info.dart';
import 'package:analyzer/dart/analysis/results.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:meta/meta.dart';
import 'package:nnbd_migration/nnbd_migration.dart';
+import 'package:nnbd_migration/src/front_end/info_builder.dart';
+import 'package:nnbd_migration/src/front_end/migration_info.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import '../../../analysis_abstract.dart';
+import 'analysis_abstract.dart';
import 'nnbd_migration_test_base.dart';
void main() {
@@ -39,7 +39,8 @@
}
''');
var result = await resolveTestFile();
- ClassDeclaration class_ = result.unit.declarations.single;
+ ClassDeclaration class_ =
+ result.unit.declarations.single as ClassDeclaration;
var constructor = class_.members.single;
expect(InfoBuilder.buildEnclosingMemberDescription(constructor),
equals("the constructor 'C.aaa'"));
@@ -52,7 +53,8 @@
}
''');
var result = await resolveTestFile();
- ClassDeclaration class_ = result.unit.declarations.single;
+ ClassDeclaration class_ =
+ result.unit.declarations.single as ClassDeclaration;
var constructor = class_.members.single;
expect(InfoBuilder.buildEnclosingMemberDescription(constructor),
equals("the default constructor of 'C'"));
@@ -65,8 +67,10 @@
}
''');
var result = await resolveTestFile();
- ClassDeclaration class_ = result.unit.declarations.single;
- FieldDeclaration fieldDeclaration = class_.members.single;
+ ClassDeclaration class_ =
+ result.unit.declarations.single as ClassDeclaration;
+ FieldDeclaration fieldDeclaration =
+ class_.members.single as FieldDeclaration;
var field = fieldDeclaration.fields.variables[0];
expect(InfoBuilder.buildEnclosingMemberDescription(field),
equals("the field 'C.i'"));
@@ -79,8 +83,10 @@
}
''');
var result = await resolveTestFile();
- ClassDeclaration class_ = result.unit.declarations.single;
- FieldDeclaration fieldDeclaration = class_.members.single;
+ ClassDeclaration class_ =
+ result.unit.declarations.single as ClassDeclaration;
+ FieldDeclaration fieldDeclaration =
+ class_.members.single as FieldDeclaration;
var type = fieldDeclaration.fields.type;
expect(InfoBuilder.buildEnclosingMemberDescription(type),
equals("the field 'C.i'"));
@@ -93,7 +99,8 @@
}
''');
var result = await resolveTestFile();
- ClassDeclaration class_ = result.unit.declarations.single;
+ ClassDeclaration class_ =
+ result.unit.declarations.single as ClassDeclaration;
var getter = class_.members.single;
expect(InfoBuilder.buildEnclosingMemberDescription(getter),
equals("the getter 'C.aaa'"));
@@ -106,7 +113,8 @@
}
''');
var result = await resolveTestFile();
- ClassDeclaration class_ = result.unit.declarations.single;
+ ClassDeclaration class_ =
+ result.unit.declarations.single as ClassDeclaration;
var method = class_.members.single;
expect(InfoBuilder.buildEnclosingMemberDescription(method),
equals("the method 'C.aaa'"));
@@ -119,7 +127,8 @@
}
''');
var result = await resolveTestFile();
- ClassDeclaration class_ = result.unit.declarations.single;
+ ClassDeclaration class_ =
+ result.unit.declarations.single as ClassDeclaration;
var operator = class_.members.single;
expect(InfoBuilder.buildEnclosingMemberDescription(operator),
equals("the operator 'C.=='"));
@@ -132,7 +141,8 @@
}
''');
var result = await resolveTestFile();
- ClassDeclaration class_ = result.unit.declarations.single;
+ ClassDeclaration class_ =
+ result.unit.declarations.single as ClassDeclaration;
var setter = class_.members.single;
expect(InfoBuilder.buildEnclosingMemberDescription(setter),
equals("the setter 'C.aaa='"));
@@ -145,7 +155,8 @@
}
''');
var result = await resolveTestFile();
- ExtensionDeclaration extension_ = result.unit.declarations.single;
+ ExtensionDeclaration extension_ =
+ result.unit.declarations.single as ExtensionDeclaration;
var method = extension_.members.single;
expect(InfoBuilder.buildEnclosingMemberDescription(method),
equals("the method 'E.aaa'"));
@@ -158,7 +169,8 @@
}
''');
var result = await resolveTestFile();
- ExtensionDeclaration extension_ = result.unit.declarations.single;
+ ExtensionDeclaration extension_ =
+ result.unit.declarations.single as ExtensionDeclaration;
var method = extension_.members.single;
expect(InfoBuilder.buildEnclosingMemberDescription(method),
equals("the method 'aaa' in unnamed extension on List<dynamic>"));
@@ -171,7 +183,8 @@
}
''');
var result = await resolveTestFile();
- MixinDeclaration mixin_ = result.unit.declarations.single;
+ MixinDeclaration mixin_ =
+ result.unit.declarations.single as MixinDeclaration;
var method = mixin_.members.single;
expect(InfoBuilder.buildEnclosingMemberDescription(method),
equals("the method 'C.aaa'"));
@@ -213,7 +226,7 @@
''');
var result = await resolveTestFile();
TopLevelVariableDeclaration topLevelVariableDeclaration =
- result.unit.declarations.single;
+ result.unit.declarations.single as TopLevelVariableDeclaration;
var variable = topLevelVariableDeclaration.variables.variables[0];
expect(InfoBuilder.buildEnclosingMemberDescription(variable),
equals("the variable 'i'"));
@@ -225,7 +238,7 @@
''');
var result = await resolveTestFile();
TopLevelVariableDeclaration topLevelVariableDeclaration =
- result.unit.declarations.single;
+ result.unit.declarations.single as TopLevelVariableDeclaration;
var type = topLevelVariableDeclaration.variables.type;
expect(InfoBuilder.buildEnclosingMemberDescription(type),
equals("the variable 'i'"));
@@ -258,6 +271,36 @@
.toList();
}
+ Future<void> test_addLate() async {
+ var content = '''
+f() {
+ String s;
+ if (1 == 2) s = "Hello";
+ g(s);
+}
+g(String /*!*/ s) {}
+''';
+ var migratedContent = '''
+f() {
+ late String s;
+ if (1 == 2) s = "Hello";
+ g(s);
+}
+g(String /*!*/ s) {}
+''';
+ var unit = await buildInfoForSingleTestFile(content,
+ migratedContent: migratedContent);
+ var regions = unit.fixRegions;
+ expect(regions, hasLength(2));
+ var region = regions[0];
+ assertRegion(
+ region: region,
+ offset: 8,
+ length: 4,
+ explanation: 'Added a late keyword',
+ kind: NullabilityFixKind.addLate);
+ }
+
Future<void> test_addLate_dueToHint() async {
var content = '/*late*/ int x = 0;';
var migratedContent = '/*late*/ int x = 0;';
@@ -273,7 +316,7 @@
length2: 2,
explanation: 'Added a late keyword, due to a hint',
kind: NullabilityFixKind.addLateDueToHint,
- edits: (edits) => assertEdit(
+ edits: (List<EditDetail> edits) => assertEdit(
edit: edits.single,
offset: content.indexOf(textToRemove),
length: textToRemove.length,
@@ -687,7 +730,7 @@
explanation: 'Accepted a null check hint',
kind: NullabilityFixKind.checkExpressionDueToHint,
traces: isNotEmpty,
- edits: ((edits) => assertEdit(
+ edits: ((List<EditDetail> edits) => assertEdit(
edit: edits.single,
offset: content.indexOf(hintText),
length: hintText.length,
diff --git a/pkg/analysis_server/test/src/edit/nnbd_migration/instrumentation_renderer_test.dart b/pkg/nnbd_migration/test/front_end/instrumentation_renderer_test.dart
similarity index 90%
rename from pkg/analysis_server/test/src/edit/nnbd_migration/instrumentation_renderer_test.dart
rename to pkg/nnbd_migration/test/front_end/instrumentation_renderer_test.dart
index 12190ab..5c456f8 100644
--- a/pkg/analysis_server/test/src/edit/nnbd_migration/instrumentation_renderer_test.dart
+++ b/pkg/nnbd_migration/test/front_end/instrumentation_renderer_test.dart
@@ -2,9 +2,9 @@
// 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:analysis_server/src/edit/nnbd_migration/instrumentation_renderer.dart';
-import 'package:analysis_server/src/edit/nnbd_migration/migration_info.dart';
-import 'package:analysis_server/src/edit/nnbd_migration/path_mapper.dart';
+import 'package:nnbd_migration/src/front_end/instrumentation_renderer.dart';
+import 'package:nnbd_migration/src/front_end/migration_info.dart';
+import 'package:nnbd_migration/src/front_end/path_mapper.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
diff --git a/pkg/analysis_server/test/src/edit/nnbd_migration/migration_info_test.dart b/pkg/nnbd_migration/test/front_end/migration_info_test.dart
similarity index 95%
rename from pkg/analysis_server/test/src/edit/nnbd_migration/migration_info_test.dart
rename to pkg/nnbd_migration/test/front_end/migration_info_test.dart
index 1e17f2d..dcc1abb 100644
--- a/pkg/analysis_server/test/src/edit/nnbd_migration/migration_info_test.dart
+++ b/pkg/nnbd_migration/test/front_end/migration_info_test.dart
@@ -2,7 +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.
-import 'package:analysis_server/src/edit/nnbd_migration/migration_info.dart';
+import 'package:nnbd_migration/src/front_end/migration_info.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
diff --git a/pkg/nnbd_migration/test/front_end/mocks.dart b/pkg/nnbd_migration/test/front_end/mocks.dart
new file mode 100644
index 0000000..839623c
--- /dev/null
+++ b/pkg/nnbd_migration/test/front_end/mocks.dart
@@ -0,0 +1,46 @@
+// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analysis_server/protocol/protocol.dart';
+import 'package:test/test.dart';
+
+/// A [Matcher] that check that the given [Response] has an expected identifier
+/// and no error.
+Matcher isResponseSuccess(String id) => _IsResponseSuccess(id);
+
+/// A [Matcher] that check that there are no `error` in a given [Response].
+class _IsResponseSuccess extends Matcher {
+ final String _id;
+
+ _IsResponseSuccess(this._id);
+
+ @override
+ Description describe(Description description) {
+ return description
+ .addDescriptionOf('response with identifier "$_id" and without error');
+ }
+
+ @override
+ Description describeMismatch(
+ item, Description mismatchDescription, Map matchState, bool verbose) {
+ Response response = item as Response;
+ if (response == null) {
+ mismatchDescription.add('is null response');
+ } else {
+ var id = response.id;
+ var error = response.error;
+ mismatchDescription.add('has identifier "$id"');
+ if (error != null) {
+ mismatchDescription.add(' and has error $error');
+ }
+ }
+ return mismatchDescription;
+ }
+
+ @override
+ bool matches(item, Map matchState) {
+ Response response = item as Response;
+ return response != null && response.id == _id && response.error == null;
+ }
+}
diff --git a/pkg/analysis_server/test/src/edit/nnbd_migration/navigation_tree_renderer_test.dart b/pkg/nnbd_migration/test/front_end/navigation_tree_renderer_test.dart
similarity index 95%
rename from pkg/analysis_server/test/src/edit/nnbd_migration/navigation_tree_renderer_test.dart
rename to pkg/nnbd_migration/test/front_end/navigation_tree_renderer_test.dart
index 6a8451f..b8b6231 100644
--- a/pkg/analysis_server/test/src/edit/nnbd_migration/navigation_tree_renderer_test.dart
+++ b/pkg/nnbd_migration/test/front_end/navigation_tree_renderer_test.dart
@@ -2,10 +2,10 @@
// 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:analysis_server/src/edit/nnbd_migration/migration_info.dart';
-import 'package:analysis_server/src/edit/nnbd_migration/navigation_tree_renderer.dart';
-import 'package:analysis_server/src/edit/nnbd_migration/path_mapper.dart';
-import 'package:analysis_server/src/edit/nnbd_migration/web/navigation_tree.dart';
+import 'package:nnbd_migration/src/front_end/migration_info.dart';
+import 'package:nnbd_migration/src/front_end/navigation_tree_renderer.dart';
+import 'package:nnbd_migration/src/front_end/path_mapper.dart';
+import 'package:nnbd_migration/src/front_end/web/navigation_tree.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
diff --git a/pkg/analysis_server/test/src/edit/nnbd_migration/nnbd_migration_test_base.dart b/pkg/nnbd_migration/test/front_end/nnbd_migration_test_base.dart
similarity index 93%
rename from pkg/analysis_server/test/src/edit/nnbd_migration/nnbd_migration_test_base.dart
rename to pkg/nnbd_migration/test/front_end/nnbd_migration_test_base.dart
index 6591ced..559cf15 100644
--- a/pkg/analysis_server/test/src/edit/nnbd_migration/nnbd_migration_test_base.dart
+++ b/pkg/nnbd_migration/test/front_end/nnbd_migration_test_base.dart
@@ -4,18 +4,18 @@
import 'package:analysis_server/src/edit/fix/dartfix_listener.dart';
import 'package:analysis_server/src/edit/fix/non_nullable_fix.dart';
-import 'package:analysis_server/src/edit/nnbd_migration/info_builder.dart';
-import 'package:analysis_server/src/edit/nnbd_migration/instrumentation_listener.dart';
-import 'package:analysis_server/src/edit/nnbd_migration/migration_info.dart';
-import 'package:analysis_server/src/edit/nnbd_migration/offset_mapper.dart';
import 'package:analyzer/dart/analysis/results.dart';
import 'package:analyzer/source/line_info.dart';
import 'package:meta/meta.dart';
import 'package:nnbd_migration/nnbd_migration.dart';
+import 'package:nnbd_migration/src/front_end/info_builder.dart';
+import 'package:nnbd_migration/src/front_end/instrumentation_listener.dart';
+import 'package:nnbd_migration/src/front_end/migration_info.dart';
+import 'package:nnbd_migration/src/front_end/offset_mapper.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import '../../../analysis_abstract.dart';
+import 'analysis_abstract.dart';
@reflectiveTest
class NnbdMigrationTestBase extends AbstractAnalysisTest {
@@ -193,8 +193,8 @@
migration.finish();
// Build the migration info.
var info = instrumentationListener.data;
- var builder = InfoBuilder(
- resourceProvider, includedRoot, info, listener, adapter, migration);
+ var builder =
+ InfoBuilder(resourceProvider, includedRoot, info, listener, migration);
infos = await builder.explainMigration();
}
}
diff --git a/pkg/analysis_server/test/src/edit/nnbd_migration/offset_mapper_test.dart b/pkg/nnbd_migration/test/front_end/offset_mapper_test.dart
similarity index 96%
rename from pkg/analysis_server/test/src/edit/nnbd_migration/offset_mapper_test.dart
rename to pkg/nnbd_migration/test/front_end/offset_mapper_test.dart
index b873c31..7bacfd2 100644
--- a/pkg/analysis_server/test/src/edit/nnbd_migration/offset_mapper_test.dart
+++ b/pkg/nnbd_migration/test/front_end/offset_mapper_test.dart
@@ -2,12 +2,12 @@
// 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:analysis_server/src/edit/nnbd_migration/offset_mapper.dart';
import 'package:analysis_server/src/protocol_server.dart';
+import 'package:nnbd_migration/src/front_end/offset_mapper.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import '../../../analysis_abstract.dart';
+import 'analysis_abstract.dart';
void main() {
defineReflectiveSuite(() {
diff --git a/pkg/analysis_server/test/src/edit/nnbd_migration/region_renderer_test.dart b/pkg/nnbd_migration/test/front_end/region_renderer_test.dart
similarity index 87%
rename from pkg/analysis_server/test/src/edit/nnbd_migration/region_renderer_test.dart
rename to pkg/nnbd_migration/test/front_end/region_renderer_test.dart
index 7f88d2b..db9bcfe 100644
--- a/pkg/analysis_server/test/src/edit/nnbd_migration/region_renderer_test.dart
+++ b/pkg/nnbd_migration/test/front_end/region_renderer_test.dart
@@ -2,10 +2,10 @@
// 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:analysis_server/src/edit/nnbd_migration/migration_info.dart';
-import 'package:analysis_server/src/edit/nnbd_migration/path_mapper.dart';
-import 'package:analysis_server/src/edit/nnbd_migration/region_renderer.dart';
-import 'package:analysis_server/src/edit/nnbd_migration/web/edit_details.dart';
+import 'package:nnbd_migration/src/front_end/migration_info.dart';
+import 'package:nnbd_migration/src/front_end/path_mapper.dart';
+import 'package:nnbd_migration/src/front_end/region_renderer.dart';
+import 'package:nnbd_migration/src/front_end/web/edit_details.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
diff --git a/pkg/analysis_server/test/src/edit/nnbd_migration/test_all.dart b/pkg/nnbd_migration/test/front_end/test_all.dart
similarity index 88%
rename from pkg/analysis_server/test/src/edit/nnbd_migration/test_all.dart
rename to pkg/nnbd_migration/test/front_end/test_all.dart
index 6ac9f59..9a81148 100644
--- a/pkg/analysis_server/test/src/edit/nnbd_migration/test_all.dart
+++ b/pkg/nnbd_migration/test/front_end/test_all.dart
@@ -1,4 +1,4 @@
-// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
@@ -12,7 +12,7 @@
import 'region_renderer_test.dart' as region_renderer;
import 'unit_renderer_test.dart' as unit_renderer;
-void main() {
+main() {
defineReflectiveSuite(() {
info_builder.main();
instrumentation_renderer.main();
@@ -21,5 +21,5 @@
offset_mapper.main();
region_renderer.main();
unit_renderer.main();
- }, name: 'nnbd_migration');
+ }, name: 'front_end');
}
diff --git a/pkg/analysis_server/test/src/edit/nnbd_migration/unit_renderer_test.dart b/pkg/nnbd_migration/test/front_end/unit_renderer_test.dart
similarity index 97%
rename from pkg/analysis_server/test/src/edit/nnbd_migration/unit_renderer_test.dart
rename to pkg/nnbd_migration/test/front_end/unit_renderer_test.dart
index 0e7bd9a..3a932af 100644
--- a/pkg/analysis_server/test/src/edit/nnbd_migration/unit_renderer_test.dart
+++ b/pkg/nnbd_migration/test/front_end/unit_renderer_test.dart
@@ -2,11 +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.
-import 'package:analysis_server/src/edit/nnbd_migration/migration_info.dart';
-import 'package:analysis_server/src/edit/nnbd_migration/path_mapper.dart';
-import 'package:analysis_server/src/edit/nnbd_migration/unit_renderer.dart';
-import 'package:analysis_server/src/edit/nnbd_migration/web/file_details.dart';
import 'package:nnbd_migration/nnbd_migration.dart';
+import 'package:nnbd_migration/src/front_end/migration_info.dart';
+import 'package:nnbd_migration/src/front_end/path_mapper.dart';
+import 'package:nnbd_migration/src/front_end/unit_renderer.dart';
+import 'package:nnbd_migration/src/front_end/web/file_details.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
diff --git a/pkg/analysis_server/test/src/edit/preview/preview_site_test.dart b/pkg/nnbd_migration/test/preview/preview_site_test.dart
similarity index 93%
rename from pkg/analysis_server/test/src/edit/preview/preview_site_test.dart
rename to pkg/nnbd_migration/test/preview/preview_site_test.dart
index fd1d4b0..cfce5a6 100644
--- a/pkg/analysis_server/test/src/edit/preview/preview_site_test.dart
+++ b/pkg/nnbd_migration/test/preview/preview_site_test.dart
@@ -3,19 +3,19 @@
// BSD-style license that can be found in the LICENSE file.
import 'package:analysis_server/src/edit/fix/dartfix_listener.dart';
-import 'package:analysis_server/src/edit/nnbd_migration/migration_info.dart';
-import 'package:analysis_server/src/edit/nnbd_migration/migration_state.dart';
-import 'package:analysis_server/src/edit/nnbd_migration/offset_mapper.dart';
-import 'package:analysis_server/src/edit/nnbd_migration/path_mapper.dart';
-import 'package:analysis_server/src/edit/preview/preview_site.dart';
import 'package:analyzer/file_system/memory_file_system.dart';
import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart';
import 'package:analyzer_plugin/protocol/protocol_common.dart'
hide NavigationTarget;
+import 'package:nnbd_migration/src/front_end/migration_info.dart';
+import 'package:nnbd_migration/src/front_end/migration_state.dart';
+import 'package:nnbd_migration/src/front_end/offset_mapper.dart';
+import 'package:nnbd_migration/src/front_end/path_mapper.dart';
+import 'package:nnbd_migration/src/preview/preview_site.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import '../nnbd_migration/nnbd_migration_test_base.dart';
+import '../front_end/nnbd_migration_test_base.dart';
void main() {
defineReflectiveSuite(() {
@@ -39,7 +39,7 @@
dartfixListener = DartFixListener(null);
resourceProvider = MemoryResourceProvider();
final migrationInfo = MigrationInfo({}, {}, null, null);
- state = MigrationState(null, null, dartfixListener, null, null);
+ state = MigrationState(null, null, dartfixListener, null);
state.pathMapper = PathMapper(resourceProvider);
state.migrationInfo = migrationInfo;
site = PreviewSite(state, ([paths]) async {
@@ -200,7 +200,7 @@
reranPaths = null;
dartfixListener = DartFixListener(null);
final migrationInfo = MigrationInfo({}, {}, null, null);
- state = MigrationState(null, null, dartfixListener, null, null);
+ state = MigrationState(null, null, dartfixListener, null);
state.pathMapper = PathMapper(resourceProvider);
state.migrationInfo = migrationInfo;
site = PreviewSite(state, ([paths]) async {
diff --git a/pkg/analysis_server/test/src/edit/preview/test_all.dart b/pkg/nnbd_migration/test/preview/test_all.dart
similarity index 100%
rename from pkg/analysis_server/test/src/edit/preview/test_all.dart
rename to pkg/nnbd_migration/test/preview/test_all.dart
diff --git a/pkg/nnbd_migration/test/test_all.dart b/pkg/nnbd_migration/test/test_all.dart
index b7902da..291ba60 100644
--- a/pkg/nnbd_migration/test/test_all.dart
+++ b/pkg/nnbd_migration/test/test_all.dart
@@ -19,10 +19,12 @@
import 'fix_aggregator_test.dart' as fix_aggregator_test;
import 'fix_builder_test.dart' as fix_builder_test;
import 'fix_reason_target_test.dart' as fix_reason_target_test;
+import 'front_end/test_all.dart' as front_end;
import 'instrumentation_test.dart' as instrumentation_test;
import 'isolate_server_test.dart' as isolate_server_test;
import 'node_builder_test.dart' as node_builder_test;
import 'nullability_node_test.dart' as nullability_node_test;
+import 'preview/test_all.dart' as preview;
import 'utilities/test_all.dart' as utilities;
import 'variables_test.dart' as variables;
@@ -40,10 +42,12 @@
fix_aggregator_test.main();
fix_builder_test.main();
fix_reason_target_test.main();
+ front_end.main();
instrumentation_test.main();
isolate_server_test.main();
node_builder_test.main();
nullability_node_test.main();
+ preview.main();
utilities.main();
variables.main();
});
diff --git a/pkg/analysis_server/tool/nnbd_migration/check_generated_test.dart b/pkg/nnbd_migration/tool/codegen/check_generated_test.dart
similarity index 86%
rename from pkg/analysis_server/tool/nnbd_migration/check_generated_test.dart
rename to pkg/nnbd_migration/tool/codegen/check_generated_test.dart
index 8c0f118..9a251ab 100644
--- a/pkg/analysis_server/tool/nnbd_migration/check_generated_test.dart
+++ b/pkg/nnbd_migration/tool/codegen/check_generated_test.dart
@@ -7,7 +7,7 @@
import 'generate_resources.dart' as generate_resources;
/// Validate that the
-/// pkg/analysis_server/lib/src/edit/nnbd_migration/resources/resources.g.dart
+/// pkg/nnbd_migration/lib/src/front_end/resources/resources.g.dart
/// file was regenerated after changing upstream dependencies.
void main() async {
test('description', () {
diff --git a/pkg/analysis_server/tool/nnbd_migration/generate_resources.dart b/pkg/nnbd_migration/tool/codegen/generate_resources.dart
similarity index 85%
rename from pkg/analysis_server/tool/nnbd_migration/generate_resources.dart
rename to pkg/nnbd_migration/tool/codegen/generate_resources.dart
index cdc22c5..21ed8fb 100644
--- a/pkg/analysis_server/tool/nnbd_migration/generate_resources.dart
+++ b/pkg/nnbd_migration/tool/codegen/generate_resources.dart
@@ -3,8 +3,8 @@
// BSD-style license that can be found in the LICENSE file.
// This script generates the
-// lib/src/edit/nnbd_migration/resources/resources.g.dart file from the contents
-// of the lib/src/edit/nnbd_migration/resources directory.
+// lib/src/front_end/resources/resources.g.dart file from the contents
+// of the lib/src/front_end/resources directory.
import 'dart:convert';
import 'dart:io';
@@ -22,7 +22,7 @@
var argResults = argParser.parse(args);
if (argResults['help'] == true) {
fail('''
-usage: dart pkg/analysis_server/tool/nnbd_migration/generate_resources.dart [--verify]
+usage: dart pkg/nnbd_migration/tool/codegen/generate_resources.dart [--verify]
Run with no args to generate web resources for the NNBD migration preview tool.
Run with '--verify' to validate that the web resource have been regenerated.
@@ -30,16 +30,16 @@
}
if (FileSystemEntity.isFileSync(
- path.join('tool', 'nnbd_migration', 'generate_resources.dart'))) {
+ path.join('tool', 'codegen', 'generate_resources.dart'))) {
// We're running from the project root - cd up two directories.
Directory.current = Directory.current.parent.parent;
} else if (!FileSystemEntity.isDirectorySync(
- path.join('pkg', 'analysis_server'))) {
+ path.join('pkg', 'nnbd_migration'))) {
fail('Please run this tool from the root of the sdk repo.');
}
- bool verify = argResults['verify'];
- bool dev = argResults['dev'];
+ bool verify = argResults['verify'] as bool;
+ bool dev = argResults['dev'] as bool;
if (verify) {
verifyResourcesGDartGenerated();
@@ -52,17 +52,17 @@
}
}
-final File dartSources = File(path.join('pkg', 'analysis_server', 'lib', 'src',
- 'edit', 'nnbd_migration', 'web', 'migration.dart'));
+final File dartSources = File(path.join('pkg', 'nnbd_migration', 'lib', 'src',
+ 'front_end', 'web', 'migration.dart'));
-final javascriptOutput = File(path.join('pkg', 'analysis_server', 'lib', 'src',
- 'edit', 'nnbd_migration', 'resources', 'migration.js'));
+final javascriptOutput = File(path.join('pkg', 'nnbd_migration', 'lib', 'src',
+ 'front_end', 'resources', 'migration.js'));
-final Directory resourceDir = Directory(path.join('pkg', 'analysis_server',
- 'lib', 'src', 'edit', 'nnbd_migration', 'resources'));
+final Directory resourceDir = Directory(
+ path.join('pkg', 'nnbd_migration', 'lib', 'src', 'front_end', 'resources'));
-final File resourcesFile = File(path.join('pkg', 'analysis_server', 'lib',
- 'src', 'edit', 'nnbd_migration', 'resources', 'resources.g.dart'));
+final File resourcesFile = File(path.join('pkg', 'nnbd_migration', 'lib', 'src',
+ 'front_end', 'resources', 'resources.g.dart'));
final List<String> resourceTypes = [
'.css',
@@ -129,9 +129,9 @@
stderr.writeln('$message.');
stderr.writeln();
stderr.writeln('''
-To re-generate lib/src/edit/nnbd_migration/resources/resources.g.dart, run:
+To re-generate lib/src/front_end/resources/resources.g.dart, run:
- dart pkg/analysis_server/tool/nnbd_migration/generate_resources.dart
+ dart pkg/nnbd_migration/tool/codegen/generate_resources.dart
''');
exit(1);
}
diff --git a/pkg/pkg.status b/pkg/pkg.status
index 99a1b6a..b49a9be 100644
--- a/pkg/pkg.status
+++ b/pkg/pkg.status
@@ -83,6 +83,7 @@
modular_test/test/validate_pipeline_test: Slow, Pass
modular_test/test/validate_suite_test: Slow, Pass
nnbd_migration/test/*: SkipByDesign # Uses mirrors
+nnbd_migration/tool/*: SkipByDesign # Only meant to run on vm
smith/test/*: SkipByDesign # Only meant to run on vm
status_file/test/normalize_test: SkipByDesign # Uses dart:io
status_file/test/parse_and_normalize_test: SkipByDesign # Uses dart:io
diff --git a/pkg/test_runner/lib/src/compiler_configuration.dart b/pkg/test_runner/lib/src/compiler_configuration.dart
index f57b8ed..fe588a6 100644
--- a/pkg/test_runner/lib/src/compiler_configuration.dart
+++ b/pkg/test_runner/lib/src/compiler_configuration.dart
@@ -1092,6 +1092,8 @@
var dillFile = tempKernelFile(tempDir);
+ var isProductMode = _configuration.configuration.mode == Mode.product;
+
var causalAsyncStacks = !arguments.any(noCausalAsyncStacksRegExp.hasMatch);
var args = [
@@ -1104,6 +1106,7 @@
name.startsWith('-D') ||
name.startsWith('--packages=') ||
name.startsWith('--enable-experiment=')),
+ '-Ddart.vm.product=$isProductMode',
'-Ddart.developer.causal_async_stacks=$causalAsyncStacks',
if (_enableAsserts ||
arguments.contains('--enable-asserts') ||
diff --git a/pkg/vm/bin/kernel_service.dart b/pkg/vm/bin/kernel_service.dart
index 050407d..99638ad 100644
--- a/pkg/vm/bin/kernel_service.dart
+++ b/pkg/vm/bin/kernel_service.dart
@@ -691,6 +691,7 @@
prepend = ", ";
if (sb.length > 256) break;
}
+ sb.write("]");
partToString = sb.toString();
} else {
partToString = part.toString();
diff --git a/pkg/vm/lib/bytecode/declarations.dart b/pkg/vm/lib/bytecode/declarations.dart
index 273e443..c30f096 100644
--- a/pkg/vm/lib/bytecode/declarations.dart
+++ b/pkg/vm/lib/bytecode/declarations.dart
@@ -781,6 +781,7 @@
static const isCovariantFlag = 1 << 0;
static const isGenericCovariantImplFlag = 1 << 1;
static const isFinalFlag = 1 << 2;
+ static const isRequiredFlag = 1 << 3;
final ObjectHandle name;
final ObjectHandle type;
@@ -971,6 +972,7 @@
static const isSyncStarFlag = 1 << 6;
static const isDebuggableFlag = 1 << 7;
static const hasAttributesFlag = 1 << 8;
+ static const hasParameterFlagsFlag = 1 << 9;
int flags;
final ObjectHandle parent;
@@ -981,6 +983,7 @@
final int numRequiredParams;
final int numNamedParams;
final List<NameAndType> parameters;
+ final List<int> parameterFlags;
final ObjectHandle returnType;
ObjectHandle attributes;
ClosureCode code;
@@ -995,6 +998,7 @@
this.numRequiredParams,
this.numNamedParams,
this.parameters,
+ this.parameterFlags,
this.returnType,
[this.attributes]);
@@ -1027,6 +1031,12 @@
writer.writePackedObject(param.name);
writer.writePackedObject(param.type);
}
+ if ((flags & hasParameterFlagsFlag) != 0) {
+ writer.writePackedUInt30(parameterFlags.length);
+ for (var pf in parameterFlags) {
+ writer.writePackedUInt30(pf);
+ }
+ }
writer.writePackedObject(returnType);
if ((flags & hasAttributesFlag) != 0) {
writer.writePackedObject(attributes);
@@ -1069,6 +1079,14 @@
numParams,
(_) => new NameAndType(
reader.readPackedObject(), reader.readPackedObject()));
+ List<int> parameterFlags;
+ if ((flags & hasParameterFlagsFlag) != 0) {
+ final int numParameterFlags = reader.readPackedUInt30();
+ new List<int>.generate(
+ numParameterFlags, (_) => reader.readPackedUInt30());
+ } else {
+ parameterFlags = const <int>[];
+ }
final returnType = reader.readPackedObject();
final attributes =
((flags & hasAttributesFlag) != 0) ? reader.readPackedObject() : null;
@@ -1082,6 +1100,7 @@
numRequiredParams,
numNamedParams,
parameters,
+ parameterFlags,
returnType,
attributes);
}
diff --git a/pkg/vm/lib/bytecode/gen_bytecode.dart b/pkg/vm/lib/bytecode/gen_bytecode.dart
index 60fd7d8..6a2d435 100644
--- a/pkg/vm/lib/bytecode/gen_bytecode.dart
+++ b/pkg/vm/lib/bytecode/gen_bytecode.dart
@@ -869,6 +869,9 @@
if (variable.isFinal) {
flags |= ParameterDeclaration.isFinalFlag;
}
+ if (variable.isRequired) {
+ flags |= ParameterDeclaration.isRequiredFlag;
+ }
return flags;
}
@@ -2661,6 +2664,11 @@
flags |= ClosureDeclaration.hasTypeParamsFlag;
}
+ final List<int> parameterFlags = getParameterFlags(function);
+ if (parameterFlags != null) {
+ flags |= ClosureDeclaration.hasParameterFlagsFlag;
+ }
+
return new ClosureDeclaration(
flags,
objectTable.getHandle(parent),
@@ -2671,6 +2679,7 @@
function.requiredParameterCount,
function.namedParameters.length,
parameters,
+ parameterFlags,
objectTable.getHandle(function.returnType));
}
diff --git a/pkg/vm/lib/target/flutter.dart b/pkg/vm/lib/target/flutter.dart
index d95c679..cc259c5 100644
--- a/pkg/vm/lib/target/flutter.dart
+++ b/pkg/vm/lib/target/flutter.dart
@@ -61,10 +61,10 @@
ChangedStructureNotifier changedStructureNotifier}) {
super.performPreConstantEvaluationTransformations(
component, coreTypes, libraries, diagnosticReporter,
- logger: logger);
+ logger: logger, changedStructureNotifier: changedStructureNotifier);
if (flags.trackWidgetCreation) {
if (_widgetTracker == null) {
- _widgetTracker = WidgetCreatorTracker();
+ _widgetTracker = WidgetCreatorTracker(changedStructureNotifier);
}
_widgetTracker.transform(component, libraries);
}
diff --git a/pkg/vm/lib/target/vm.dart b/pkg/vm/lib/target/vm.dart
index c7cdbc3..033258f 100644
--- a/pkg/vm/lib/target/vm.dart
+++ b/pkg/vm/lib/target/vm.dart
@@ -119,7 +119,7 @@
ChangedStructureNotifier changedStructureNotifier}) {
super.performPreConstantEvaluationTransformations(
component, coreTypes, libraries, diagnosticReporter,
- logger: logger);
+ logger: logger, changedStructureNotifier: changedStructureNotifier);
_patchVmConstants(coreTypes);
}
diff --git a/pkg/vm/lib/transformations/ffi_definitions.dart b/pkg/vm/lib/transformations/ffi_definitions.dart
index 696b5f6..cecc5a0 100644
--- a/pkg/vm/lib/transformations/ffi_definitions.dart
+++ b/pkg/vm/lib/transformations/ffi_definitions.dart
@@ -134,7 +134,7 @@
if (fieldsValid) {
final structSize = _replaceFields(node, indexedClass);
_replaceSizeOfMethod(node, structSize, indexedClass);
- changedStructureNotifier?.forClass(node);
+ changedStructureNotifier?.registerClassMemberChange(node);
}
return node;
diff --git a/pkg/vm_service/CHANGELOG.md b/pkg/vm_service/CHANGELOG.md
index 292e393..71cb31c 100644
--- a/pkg/vm_service/CHANGELOG.md
+++ b/pkg/vm_service/CHANGELOG.md
@@ -1,8 +1,9 @@
# Changelog
-## Unreleased
+## 4.0.2
- Fixed issue where RPC format did not conform to the JSON-RPC 2.0
specification.
+- Added `getClassList` RPC.
## 4.0.1
- Improved documentation.
diff --git a/pkg/vm_service/java/.gitignore b/pkg/vm_service/java/.gitignore
index ae0cc5a..ebfb5c7 100644
--- a/pkg/vm_service/java/.gitignore
+++ b/pkg/vm_service/java/.gitignore
@@ -10,6 +10,7 @@
src/org/dartlang/vm/service/consumer/EvaluateInFrameConsumer.java
src/org/dartlang/vm/service/consumer/FlagListConsumer.java
src/org/dartlang/vm/service/consumer/GetAllocationProfileConsumer.java
+src/org/dartlang/vm/service/consumer/GetClassListConsumer.java
src/org/dartlang/vm/service/consumer/GetCpuSamplesConsumer.java
src/org/dartlang/vm/service/consumer/GetInboundReferencesConsumer.java
src/org/dartlang/vm/service/consumer/GetInstancesConsumer.java
diff --git a/pkg/vm_service/java/version.properties b/pkg/vm_service/java/version.properties
index 4394db5..af022cb 100644
--- a/pkg/vm_service/java/version.properties
+++ b/pkg/vm_service/java/version.properties
@@ -1 +1 @@
-version=3.30
+version=3.32
diff --git a/pkg/vm_service/lib/src/vm_service.dart b/pkg/vm_service/lib/src/vm_service.dart
index a766007..d6569a9 100644
--- a/pkg/vm_service/lib/src/vm_service.dart
+++ b/pkg/vm_service/lib/src/vm_service.dart
@@ -28,7 +28,7 @@
HeapSnapshotObjectNoData,
HeapSnapshotObjectNullData;
-const String vmServiceVersion = '3.30.0';
+const String vmServiceVersion = '3.32.0';
/// @optional
const String optional = 'optional';
@@ -194,6 +194,7 @@
'evaluate': const ['InstanceRef', 'ErrorRef'],
'evaluateInFrame': const ['InstanceRef', 'ErrorRef'],
'getAllocationProfile': const ['AllocationProfile'],
+ 'getClassList': const ['ClassList'],
'getClientName': const ['ClientName'],
'getCpuSamples': const ['CpuSamples'],
'getFlagList': const ['FlagList'],
@@ -497,6 +498,18 @@
Future<AllocationProfile> getAllocationProfile(String isolateId,
{bool reset, bool gc});
+ /// The `getClassList` RPC is used to retrieve a `ClassList` containing all
+ /// classes for an isolate based on the isolate's `isolateId`.
+ ///
+ /// If `isolateId` refers to an isolate which has exited, then the `Collected`
+ /// [Sentinel] is returned.
+ ///
+ /// See [ClassList].
+ ///
+ /// This method will throw a [SentinelException] in the case a [Sentinel] is
+ /// returned.
+ Future<ClassList> getClassList(String isolateId);
+
/// The `getClientName` RPC is used to retrieve the name associated with the
/// currently connected VM service client. If no name was previously set
/// through the [setClientName] RPC, a default name will be returned.
@@ -1257,6 +1270,11 @@
gc: params['gc'],
);
break;
+ case 'getClassList':
+ response = await _serviceImplementation.getClassList(
+ params['isolateId'],
+ );
+ break;
case 'getClientName':
response = await _serviceImplementation.getClientName();
break;
@@ -1703,6 +1721,10 @@
});
@override
+ Future<ClassList> getClassList(String isolateId) =>
+ _call('getClassList', {'isolateId': isolateId});
+
+ @override
Future<ClientName> getClientName() => _call('getClientName');
@override
@@ -6356,7 +6378,9 @@
static Timeline parse(Map<String, dynamic> json) =>
json == null ? null : Timeline._fromJson(json);
- /// A list of timeline events.
+ /// A list of timeline events. No order is guarenteed for these events; in
+ /// particular, these events may be unordered with respect to their
+ /// timestamps.
List<TimelineEvent> traceEvents;
/// The start of the period of time in which traceEvents were collected.
diff --git a/pkg/vm_service/pubspec.yaml b/pkg/vm_service/pubspec.yaml
index a454d5b..45a7871 100644
--- a/pkg/vm_service/pubspec.yaml
+++ b/pkg/vm_service/pubspec.yaml
@@ -2,7 +2,7 @@
description: >-
A library to communicate with a service implementing the Dart VM
service protocol.
-version: 4.0.1
+version: 4.0.2
homepage: https://github.com/dart-lang/sdk/tree/master/pkg/vm_service
diff --git a/runtime/bin/dartdev_utils.cc b/runtime/bin/dartdev_utils.cc
index 0314d6e..3f14bc4 100644
--- a/runtime/bin/dartdev_utils.cc
+++ b/runtime/bin/dartdev_utils.cc
@@ -40,8 +40,7 @@
// If we're not in dart-sdk/bin, we might be in one of the $SDK/out/*
// directories. Try to use a snapshot from a previously built SDK.
- snapshot_path = Utils::SCreate(
- "%sdart-sdk/bin/snapshots/dartdev.dart.snapshot", dir_prefix.get());
+ snapshot_path = Utils::SCreate("%sdartdev.dart.snapshot", dir_prefix.get());
if (File::Exists(nullptr, snapshot_path)) {
*script_name = snapshot_path;
return true;
diff --git a/runtime/lib/double.cc b/runtime/lib/double.cc
index 6370714..471e41b 100644
--- a/runtime/lib/double.cc
+++ b/runtime/lib/double.cc
@@ -67,7 +67,7 @@
return Double::New(left / right);
}
-static RawInteger* DoubleToInteger(double val, const char* error_msg) {
+static IntegerPtr DoubleToInteger(double val, const char* error_msg) {
if (isinf(val) || isnan(val)) {
const Array& args = Array::Handle(Array::New(1));
args.SetAt(0, String::Handle(String::New(error_msg)));
diff --git a/runtime/lib/errors.cc b/runtime/lib/errors.cc
index 2bf8799..8d9fb8d 100644
--- a/runtime/lib/errors.cc
+++ b/runtime/lib/errors.cc
@@ -13,7 +13,7 @@
// Scan the stack until we hit the first function in the _AssertionError
// class. We then return the next frame's script taking inlining into account.
-static RawScript* FindScript(DartFrameIterator* iterator) {
+static ScriptPtr FindScript(DartFrameIterator* iterator) {
#if defined(DART_PRECOMPILED_RUNTIME)
// The precompiled runtime faces two issues in recovering the correct
// assertion text. First, the precompiled runtime does not include
diff --git a/runtime/lib/ffi.cc b/runtime/lib/ffi.cc
index bc51eb1..d4c6c43 100644
--- a/runtime/lib/ffi.cc
+++ b/runtime/lib/ffi.cc
@@ -103,10 +103,10 @@
return Integer::New(pointer.NativeAddress());
}
-static RawObject* LoadValueNumeric(Zone* zone,
- const Pointer& target,
- classid_t type_cid,
- const Integer& offset) {
+static ObjectPtr LoadValueNumeric(Zone* zone,
+ const Pointer& target,
+ classid_t type_cid,
+ const Integer& offset) {
// TODO(36370): Make representation consistent with kUnboxedFfiIntPtr.
const size_t address =
target.NativeAddress() + static_cast<intptr_t>(offset.AsInt64Value());
@@ -164,9 +164,9 @@
return Pointer::New(type_arg, *reinterpret_cast<uword*>(address));
}
-static RawObject* LoadValueStruct(Zone* zone,
- const Pointer& target,
- const AbstractType& instance_type_arg) {
+static ObjectPtr LoadValueStruct(Zone* zone,
+ const Pointer& target,
+ const AbstractType& instance_type_arg) {
// Result is a struct class -- find <class name>.#fromPointer
// constructor and call it.
const Class& cls = Class::Handle(zone, instance_type_arg.type_class());
diff --git a/runtime/lib/function.cc b/runtime/lib/function.cc
index 502fe47..ed2c547 100644
--- a/runtime/lib/function.cc
+++ b/runtime/lib/function.cc
@@ -51,8 +51,8 @@
const Context& context_a = Context::Handle(zone, receiver.context());
const Context& context_b =
Context::Handle(zone, other_closure.context());
- RawObject* receiver_a = context_a.At(0);
- RawObject* receiver_b = context_b.At(0);
+ ObjectPtr receiver_a = context_a.At(0);
+ ObjectPtr receiver_b = context_b.At(0);
if ((receiver_a == receiver_b) &&
((func_a.raw() == func_b.raw()) ||
((func_a.name() == func_b.name()) &&
diff --git a/runtime/lib/integers.cc b/runtime/lib/integers.cc
index c66299f..bdf51ec 100644
--- a/runtime/lib/integers.cc
+++ b/runtime/lib/integers.cc
@@ -158,7 +158,7 @@
return Bool::Get(left.CompareWith(right) == 0).raw();
}
-static RawInteger* ParseInteger(const String& value) {
+static IntegerPtr ParseInteger(const String& value) {
// Used by both Integer_parse and Integer_fromEnvironment.
if (value.IsOneByteString()) {
// Quick conversion for unpadded integers in strings.
@@ -202,9 +202,9 @@
return default_value.raw();
}
-static RawInteger* ShiftOperationHelper(Token::Kind kind,
- const Integer& value,
- const Integer& amount) {
+static IntegerPtr ShiftOperationHelper(Token::Kind kind,
+ const Integer& value,
+ const Integer& amount) {
if (amount.AsInt64Value() < 0) {
Exceptions::ThrowArgumentError(amount);
}
diff --git a/runtime/lib/isolate.cc b/runtime/lib/isolate.cc
index 1855954..4ef798d 100644
--- a/runtime/lib/isolate.cc
+++ b/runtime/lib/isolate.cc
@@ -15,6 +15,7 @@
#include "vm/dart_api_message.h"
#include "vm/dart_entry.h"
#include "vm/exceptions.h"
+#include "vm/hash_table.h"
#include "vm/lockers.h"
#include "vm/longjump.h"
#include "vm/message_handler.h"
@@ -108,6 +109,151 @@
return Object::null();
}
+class ObjectPtrSetTraitsLayout {
+ public:
+ static bool ReportStats() { return false; }
+ static const char* Name() { return "RawObjectPtrSetTraits"; }
+
+ static bool IsMatch(const ObjectPtr a, const ObjectPtr b) { return a == b; }
+
+ static uword Hash(const ObjectPtr obj) { return static_cast<uword>(obj); }
+};
+
+static ObjectPtr ValidateMessageObject(Zone* zone,
+ Isolate* isolate,
+ const Object& obj) {
+ TIMELINE_DURATION(Thread::Current(), Isolate, "ValidateMessageObject");
+
+ class SendMessageValidator : public ObjectPointerVisitor {
+ public:
+ SendMessageValidator(IsolateGroup* isolate_group,
+ WeakTable* visited,
+ MallocGrowableArray<ObjectPtr>* const working_set)
+ : ObjectPointerVisitor(isolate_group),
+ visited_(visited),
+ working_set_(working_set) {}
+
+ private:
+ void VisitPointers(ObjectPtr* from, ObjectPtr* to) {
+ for (ObjectPtr* raw = from; raw <= to; raw++) {
+ if (!(*raw)->IsHeapObject() || (*raw)->ptr()->IsCanonical()) {
+ continue;
+ }
+ if (visited_->GetValueExclusive(*raw) == 1) {
+ continue;
+ }
+ visited_->SetValueExclusive(*raw, 1);
+ working_set_->Add(*raw);
+ }
+ }
+
+ WeakTable* visited_;
+ MallocGrowableArray<ObjectPtr>* const working_set_;
+ };
+ if (!obj.raw()->IsHeapObject() || obj.raw()->ptr()->IsCanonical()) {
+ return obj.raw();
+ }
+ ClassTable* class_table = isolate->class_table();
+
+ Class& klass = Class::Handle(zone);
+ Closure& closure = Closure::Handle(zone);
+
+ MallocGrowableArray<ObjectPtr> working_set;
+ std::unique_ptr<WeakTable> visited(new WeakTable());
+
+ NoSafepointScope no_safepoint;
+ SendMessageValidator visitor(isolate->group(), visited.get(), &working_set);
+
+ visited->SetValueExclusive(obj.raw(), 1);
+ working_set.Add(obj.raw());
+
+ while (!working_set.is_empty()) {
+ ObjectPtr raw = working_set.RemoveLast();
+
+ if (visited->GetValueExclusive(raw) > 0) {
+ continue;
+ }
+ visited->SetValueExclusive(raw, 1);
+
+ const intptr_t cid = raw->GetClassId();
+ switch (cid) {
+ // List below matches the one in raw_object_snapshot.cc
+#define MESSAGE_SNAPSHOT_ILLEGAL(type) \
+ return Exceptions::CreateUnhandledException( \
+ zone, Exceptions::kArgumentValue, \
+ "Illegal argument in isolate message : (object is a " #type ")"); \
+ break;
+
+ MESSAGE_SNAPSHOT_ILLEGAL(DynamicLibrary);
+ MESSAGE_SNAPSHOT_ILLEGAL(MirrorReference);
+ MESSAGE_SNAPSHOT_ILLEGAL(Pointer);
+ MESSAGE_SNAPSHOT_ILLEGAL(ReceivePort);
+ MESSAGE_SNAPSHOT_ILLEGAL(RegExp);
+ MESSAGE_SNAPSHOT_ILLEGAL(StackTrace);
+ MESSAGE_SNAPSHOT_ILLEGAL(UserTag);
+
+ case kClosureCid: {
+ closure = Closure::RawCast(raw);
+ FunctionPtr func = closure.function();
+ // We only allow closure of top level methods or static functions in a
+ // class to be sent in isolate messages.
+ if (!Function::IsImplicitStaticClosureFunction(func)) {
+ return Exceptions::CreateUnhandledException(
+ zone, Exceptions::kArgumentValue, "Closures are not allowed");
+ }
+ break;
+ }
+ default:
+ if (cid >= kNumPredefinedCids) {
+ klass = class_table->At(cid);
+ if (klass.num_native_fields() != 0) {
+ return Exceptions::CreateUnhandledException(
+ zone, Exceptions::kArgumentValue,
+ "Objects that extend NativeWrapper are not allowed");
+ }
+ }
+ }
+ raw->ptr()->VisitPointers(&visitor);
+ }
+ isolate->set_forward_table_new(nullptr);
+ return obj.raw();
+}
+
+DEFINE_NATIVE_ENTRY(SendPortImpl_sendAndExitInternal_, 0, 2) {
+ GET_NON_NULL_NATIVE_ARGUMENT(SendPort, port, arguments->NativeArgAt(0));
+ if (!PortMap::IsReceiverInThisIsolateGroup(port.Id(), isolate->group())) {
+ const auto& error =
+ String::Handle(String::New("sendAndExit is only supported across "
+ "isolates spawned via spawnFunction."));
+ Exceptions::ThrowArgumentError(error);
+ UNREACHABLE();
+ }
+
+ GET_NON_NULL_NATIVE_ARGUMENT(Instance, obj, arguments->NativeArgAt(1));
+
+ Object& validated_result = Object::Handle(zone);
+ Object& msg_obj = Object::Handle(zone, obj.raw());
+ validated_result = ValidateMessageObject(zone, isolate, msg_obj);
+ if (validated_result.IsUnhandledException()) {
+ Exceptions::PropagateError(Error::Cast(validated_result));
+ UNREACHABLE();
+ }
+ PersistentHandle* handle =
+ isolate->group()->api_state()->AllocatePersistentHandle();
+ handle->set_raw(msg_obj);
+ isolate->bequeath(std::unique_ptr<Bequest>(new Bequest(handle, port.Id())));
+ // TODO(aam): Ensure there are no dart api calls after this point as we want
+ // to ensure that validated message won't get tampered with.
+ Isolate::KillIfExists(isolate, Isolate::LibMsgId::kKillMsg);
+ // Drain interrupts before running so any IMMEDIATE operations on the current
+ // isolate happen synchronously.
+ const Error& error = Error::Handle(thread->HandleInterrupts());
+ RELEASE_ASSERT(error.IsUnwindError());
+ Exceptions::PropagateError(error);
+ // We will never execute dart code again in this isolate.
+ return Object::null();
+}
+
static void ThrowIsolateSpawnException(const String& message) {
const Array& args = Array::Handle(Array::New(1));
args.SetAt(0, message);
diff --git a/runtime/lib/math.cc b/runtime/lib/math.cc
index b4a5bfd..b1e7513 100644
--- a/runtime/lib/math.cc
+++ b/runtime/lib/math.cc
@@ -74,7 +74,7 @@
}
// Returns the typed-data array store in '_Random._state' field.
-static RawTypedData* GetRandomStateArray(const Instance& receiver) {
+static TypedDataPtr GetRandomStateArray(const Instance& receiver) {
const Class& random_class = Class::Handle(receiver.clazz());
const Field& state_field =
Field::Handle(random_class.LookupFieldAllowPrivate(Symbols::_state()));
@@ -107,7 +107,7 @@
return Object::null();
}
-RawTypedData* CreateRandomState(Zone* zone, uint64_t seed) {
+TypedDataPtr CreateRandomState(Zone* zone, uint64_t seed) {
const TypedData& result =
TypedData::Handle(zone, TypedData::New(kTypedDataUint32ArrayCid, 2));
result.SetUint32(0, static_cast<uint32_t>(seed));
diff --git a/runtime/lib/mirrors.cc b/runtime/lib/mirrors.cc
index 0f114ee..b8a123e 100644
--- a/runtime/lib/mirrors.cc
+++ b/runtime/lib/mirrors.cc
@@ -21,14 +21,14 @@
#if !defined(DART_PRECOMPILED_RUNTIME)
#define RETURN_OR_PROPAGATE(expr) \
- RawObject* result = expr; \
+ ObjectPtr result = expr; \
if (IsErrorClassId(result->GetClassIdMayBeSmi())) { \
Exceptions::PropagateError(Error::Handle(Error::RawCast(result))); \
} \
return result;
-static RawInstance* CreateMirror(const String& mirror_class_name,
- const Array& constructor_arguments) {
+static InstancePtr CreateMirror(const String& mirror_class_name,
+ const Array& constructor_arguments) {
const Library& mirrors_lib = Library::Handle(Library::MirrorsLibrary());
const String& constructor_name = Symbols::DotUnder();
@@ -90,8 +90,8 @@
func.EnsureHasCode();
}
-static RawInstance* CreateParameterMirrorList(const Function& func,
- const Instance& owner_mirror) {
+static InstancePtr CreateParameterMirrorList(const Function& func,
+ const Instance& owner_mirror) {
HANDLESCOPE(Thread::Current());
const intptr_t implicit_param_count = func.NumImplicitParameters();
const intptr_t non_implicit_param_count =
@@ -184,8 +184,8 @@
return results.raw();
}
-static RawInstance* CreateTypeVariableMirror(const TypeParameter& param,
- const Instance& owner_mirror) {
+static InstancePtr CreateTypeVariableMirror(const TypeParameter& param,
+ const Instance& owner_mirror) {
const Array& args = Array::Handle(Array::New(3));
args.SetAt(0, param);
args.SetAt(1, String::Handle(param.name()));
@@ -195,7 +195,7 @@
// We create a list in native code and let Dart code create the type mirror
// object and the ordered map.
-static RawInstance* CreateTypeVariableList(const Class& cls) {
+static InstancePtr CreateTypeVariableList(const Class& cls) {
const TypeArguments& args = TypeArguments::Handle(cls.type_parameters());
if (args.IsNull()) {
return Object::empty_array().raw();
@@ -214,10 +214,10 @@
return result.raw();
}
-static RawInstance* CreateTypedefMirror(const Class& cls,
- const AbstractType& type,
- const Bool& is_declaration,
- const Instance& owner_mirror) {
+static InstancePtr CreateTypedefMirror(const Class& cls,
+ const AbstractType& type,
+ const Bool& is_declaration,
+ const Instance& owner_mirror) {
const Array& args = Array::Handle(Array::New(6));
args.SetAt(0, MirrorReference::Handle(MirrorReference::New(cls)));
args.SetAt(1, type);
@@ -228,7 +228,7 @@
return CreateMirror(Symbols::_TypedefMirror(), args);
}
-static RawInstance* CreateFunctionTypeMirror(const AbstractType& type) {
+static InstancePtr CreateFunctionTypeMirror(const AbstractType& type) {
ASSERT(type.IsFunctionType());
const Class& cls = Class::Handle(Type::Cast(type).type_class());
const Function& func = Function::Handle(Type::Cast(type).signature());
@@ -239,9 +239,9 @@
return CreateMirror(Symbols::_FunctionTypeMirror(), args);
}
-static RawInstance* CreateMethodMirror(const Function& func,
- const Instance& owner_mirror,
- const AbstractType& instantiator) {
+static InstancePtr CreateMethodMirror(const Function& func,
+ const Instance& owner_mirror,
+ const AbstractType& instantiator) {
const Array& args = Array::Handle(Array::New(6));
args.SetAt(0, MirrorReference::Handle(MirrorReference::New(func)));
@@ -259,7 +259,7 @@
(static_cast<intptr_t>(func.IsGetterFunction()) << Mirrors::kGetter);
kind_flags |=
(static_cast<intptr_t>(func.IsSetterFunction()) << Mirrors::kSetter);
- bool is_ctor = (func.kind() == RawFunction::kConstructor);
+ bool is_ctor = (func.kind() == FunctionLayout::kConstructor);
kind_flags |= (static_cast<intptr_t>(is_ctor) << Mirrors::kConstructor);
kind_flags |= (static_cast<intptr_t>(is_ctor && func.is_const())
<< Mirrors::kConstCtor);
@@ -281,8 +281,8 @@
return CreateMirror(Symbols::_MethodMirror(), args);
}
-static RawInstance* CreateVariableMirror(const Field& field,
- const Instance& owner_mirror) {
+static InstancePtr CreateVariableMirror(const Field& field,
+ const Instance& owner_mirror) {
const MirrorReference& field_ref =
MirrorReference::Handle(MirrorReference::New(field));
@@ -301,10 +301,10 @@
return CreateMirror(Symbols::_VariableMirror(), args);
}
-static RawInstance* CreateClassMirror(const Class& cls,
- const AbstractType& type,
- const Bool& is_declaration,
- const Instance& owner_mirror) {
+static InstancePtr CreateClassMirror(const Class& cls,
+ const AbstractType& type,
+ const Bool& is_declaration,
+ const Instance& owner_mirror) {
if (type.IsTypeRef()) {
AbstractType& ref_type = AbstractType::Handle(TypeRef::Cast(type).type());
ASSERT(!ref_type.IsTypeRef());
@@ -351,7 +351,7 @@
return false;
}
-static RawInstance* CreateLibraryMirror(Thread* thread, const Library& lib) {
+static InstancePtr CreateLibraryMirror(Thread* thread, const Library& lib) {
Zone* zone = thread->zone();
ASSERT(!lib.IsNull());
const Array& args = Array::Handle(zone, Array::New(3));
@@ -368,24 +368,24 @@
return CreateMirror(Symbols::_LibraryMirror(), args);
}
-static RawInstance* CreateCombinatorMirror(const Object& identifiers,
- bool is_show) {
+static InstancePtr CreateCombinatorMirror(const Object& identifiers,
+ bool is_show) {
const Array& args = Array::Handle(Array::New(2));
args.SetAt(0, identifiers);
args.SetAt(1, Bool::Get(is_show));
return CreateMirror(Symbols::_CombinatorMirror(), args);
}
-static RawInstance* CreateLibraryDependencyMirror(Thread* thread,
- const Instance& importer,
- const Library& importee,
- const Array& show_names,
- const Array& hide_names,
- const Object& metadata,
- const LibraryPrefix& prefix,
- const String& prefix_name,
- const bool is_import,
- const bool is_deferred) {
+static InstancePtr CreateLibraryDependencyMirror(Thread* thread,
+ const Instance& importer,
+ const Library& importee,
+ const Array& show_names,
+ const Array& hide_names,
+ const Object& metadata,
+ const LibraryPrefix& prefix,
+ const String& prefix_name,
+ const bool is_import,
+ const bool is_deferred) {
const Instance& importee_mirror =
Instance::Handle(CreateLibraryMirror(thread, importee));
if (importee_mirror.IsNull()) {
@@ -427,12 +427,12 @@
return CreateMirror(Symbols::_LibraryDependencyMirror(), args);
}
-static RawInstance* CreateLibraryDependencyMirror(Thread* thread,
- const Instance& importer,
- const Namespace& ns,
- const LibraryPrefix& prefix,
- const bool is_import,
- const bool is_deferred) {
+static InstancePtr CreateLibraryDependencyMirror(Thread* thread,
+ const Instance& importer,
+ const Namespace& ns,
+ const LibraryPrefix& prefix,
+ const bool is_import,
+ const bool is_deferred) {
const Library& importee = Library::Handle(ns.library());
const Array& show_names = Array::Handle(ns.show_names());
const Array& hide_names = Array::Handle(ns.hide_names());
@@ -453,7 +453,7 @@
prefix_name, is_import, is_deferred);
}
-static RawGrowableObjectArray* CreateBytecodeLibraryDependencies(
+static GrowableObjectArrayPtr CreateBytecodeLibraryDependencies(
Thread* thread,
const Library& lib,
const Instance& lib_mirror) {
@@ -597,7 +597,7 @@
return deps.raw();
}
-static RawInstance* CreateTypeMirror(const AbstractType& type) {
+static InstancePtr CreateTypeMirror(const AbstractType& type) {
if (type.IsTypeRef()) {
AbstractType& ref_type = AbstractType::Handle(TypeRef::Cast(type).type());
ASSERT(!ref_type.IsTypeRef());
@@ -652,7 +652,7 @@
return Instance::null();
}
-static RawInstance* CreateIsolateMirror() {
+static InstancePtr CreateIsolateMirror() {
Thread* thread = Thread::Current();
Isolate* isolate = thread->isolate();
const String& debug_name = String::Handle(String::New(isolate->name()));
@@ -697,8 +697,8 @@
#endif
}
-static RawAbstractType* InstantiateType(const AbstractType& type,
- const AbstractType& instantiator) {
+static AbstractTypePtr InstantiateType(const AbstractType& type,
+ const AbstractType& instantiator) {
// Generic function type parameters are not reified, but mapped to dynamic,
// i.e. all function type parameters are free with a null vector.
ASSERT(type.IsFinalized());
@@ -1112,9 +1112,9 @@
for (intptr_t i = 0; i < num_functions; i++) {
func ^= functions.At(i);
if (func.is_reflectable() &&
- (func.kind() == RawFunction::kRegularFunction ||
- func.kind() == RawFunction::kGetterFunction ||
- func.kind() == RawFunction::kSetterFunction)) {
+ (func.kind() == FunctionLayout::kRegularFunction ||
+ func.kind() == FunctionLayout::kGetterFunction ||
+ func.kind() == FunctionLayout::kSetterFunction)) {
member_mirror =
CreateMethodMirror(func, owner_mirror, owner_instantiator);
member_mirrors.Add(member_mirror);
@@ -1147,7 +1147,7 @@
Function& func = Function::Handle();
for (intptr_t i = 0; i < num_functions; i++) {
func ^= functions.At(i);
- if (func.is_reflectable() && func.kind() == RawFunction::kConstructor) {
+ if (func.is_reflectable() && func.kind() == FunctionLayout::kConstructor) {
constructor_mirror =
CreateMethodMirror(func, owner_mirror, owner_instantiator);
constructor_mirrors.Add(constructor_mirror);
@@ -1200,9 +1200,9 @@
} else if (entry.IsFunction()) {
const Function& func = Function::Cast(entry);
if (func.is_reflectable() &&
- (func.kind() == RawFunction::kRegularFunction ||
- func.kind() == RawFunction::kGetterFunction ||
- func.kind() == RawFunction::kSetterFunction)) {
+ (func.kind() == FunctionLayout::kRegularFunction ||
+ func.kind() == FunctionLayout::kGetterFunction ||
+ func.kind() == FunctionLayout::kSetterFunction)) {
member_mirror =
CreateMethodMirror(func, owner_mirror, AbstractType::Handle());
member_mirrors.Add(member_mirror);
@@ -1443,7 +1443,7 @@
Function::Handle(klass.LookupFunction(internal_constructor_name));
if (lookup_constructor.IsNull() ||
- (lookup_constructor.kind() != RawFunction::kConstructor) ||
+ (lookup_constructor.kind() != FunctionLayout::kConstructor) ||
!lookup_constructor.is_reflectable()) {
ThrowNoSuchMethod(AbstractType::Handle(klass.RareType()),
external_constructor_name, explicit_args, arg_names,
@@ -1640,9 +1640,9 @@
return func.GetSource();
}
-static RawInstance* CreateSourceLocation(const String& uri,
- intptr_t line,
- intptr_t column) {
+static InstancePtr CreateSourceLocation(const String& uri,
+ intptr_t line,
+ intptr_t column) {
const Array& args = Array::Handle(Array::New(3));
args.SetAt(0, uri);
args.SetAt(1, Smi::Handle(Smi::New(line)));
diff --git a/runtime/lib/regexp.cc b/runtime/lib/regexp.cc
index 6deab66..57aa72a 100644
--- a/runtime/lib/regexp.cc
+++ b/runtime/lib/regexp.cc
@@ -113,9 +113,9 @@
return Object::null();
}
-static RawObject* ExecuteMatch(Zone* zone,
- NativeArguments* arguments,
- bool sticky) {
+static ObjectPtr ExecuteMatch(Zone* zone,
+ NativeArguments* arguments,
+ bool sticky) {
const RegExp& regexp = RegExp::CheckedHandle(zone, arguments->NativeArgAt(0));
ASSERT(!regexp.IsNull());
GET_NON_NULL_NATIVE_ARGUMENT(String, subject, arguments->NativeArgAt(1));
diff --git a/runtime/lib/stacktrace.cc b/runtime/lib/stacktrace.cc
index dfe1f585..c2d8657 100644
--- a/runtime/lib/stacktrace.cc
+++ b/runtime/lib/stacktrace.cc
@@ -18,8 +18,8 @@
static const intptr_t kDefaultStackAllocation = 8;
-static RawStackTrace* CurrentSyncStackTraceLazy(Thread* thread,
- intptr_t skip_frames = 1) {
+static StackTracePtr CurrentSyncStackTraceLazy(Thread* thread,
+ intptr_t skip_frames = 1) {
Zone* zone = thread->zone();
const auto& code_array = GrowableObjectArray::ZoneHandle(
@@ -39,8 +39,8 @@
return StackTrace::New(code_array_fixed, pc_offset_array_fixed);
}
-static RawStackTrace* CurrentSyncStackTrace(Thread* thread,
- intptr_t skip_frames = 1) {
+static StackTracePtr CurrentSyncStackTrace(Thread* thread,
+ intptr_t skip_frames = 1) {
Zone* zone = thread->zone();
const Function& null_function = Function::ZoneHandle(zone);
@@ -63,7 +63,7 @@
return StackTrace::New(code_array, pc_offset_array);
}
-static RawStackTrace* CurrentStackTrace(
+static StackTracePtr CurrentStackTrace(
Thread* thread,
bool for_async_function,
intptr_t skip_frames = 1,
@@ -128,7 +128,7 @@
return result.raw();
}
-RawStackTrace* GetStackTraceForException() {
+StackTracePtr GetStackTraceForException() {
Thread* thread = Thread::Current();
return CurrentStackTrace(thread, false, 0);
}
diff --git a/runtime/lib/stacktrace.h b/runtime/lib/stacktrace.h
index c482070..9c8abae 100644
--- a/runtime/lib/stacktrace.h
+++ b/runtime/lib/stacktrace.h
@@ -5,10 +5,11 @@
#ifndef RUNTIME_LIB_STACKTRACE_H_
#define RUNTIME_LIB_STACKTRACE_H_
+#include "vm/tagged_pointer.h"
+
namespace dart {
class StackTrace;
-class RawStackTrace;
// Creates a StackTrace object from the current stack. Skips the
// first skip_frames Dart frames.
@@ -18,7 +19,7 @@
const StackTrace& GetCurrentStackTrace(int skip_frames);
// Creates a StackTrace object to be attached to an exception.
-RawStackTrace* GetStackTraceForException();
+StackTracePtr GetStackTraceForException();
} // namespace dart
diff --git a/runtime/lib/string.cc b/runtime/lib/string.cc
index 4b262c6..71ae8a6 100644
--- a/runtime/lib/string.cc
+++ b/runtime/lib/string.cc
@@ -362,8 +362,7 @@
}
String& string = String::Handle(OneByteString::New(length, space));
for (int i = 0; i < length; i++) {
- intptr_t value =
- Smi::Value(reinterpret_cast<RawSmi*>(array.At(start + i)));
+ intptr_t value = Smi::Value(static_cast<SmiPtr>(array.At(start + i)));
OneByteString::SetCharAt(string, i, value);
}
return string.raw();
@@ -376,8 +375,7 @@
}
String& string = String::Handle(OneByteString::New(length, space));
for (int i = 0; i < length; i++) {
- intptr_t value =
- Smi::Value(reinterpret_cast<RawSmi*>(array.At(start + i)));
+ intptr_t value = Smi::Value(static_cast<SmiPtr>(array.At(start + i)));
OneByteString::SetCharAt(string, i, value);
}
return string.raw();
@@ -458,8 +456,7 @@
const String& string =
String::Handle(zone, TwoByteString::New(length, space));
for (int i = 0; i < length; i++) {
- intptr_t value =
- Smi::Value(reinterpret_cast<RawSmi*>(array.At(start + i)));
+ intptr_t value = Smi::Value(static_cast<SmiPtr>(array.At(start + i)));
TwoByteString::SetCharAt(string, i, value);
}
return string.raw();
@@ -471,8 +468,7 @@
const String& string =
String::Handle(zone, TwoByteString::New(length, space));
for (int i = 0; i < length; i++) {
- intptr_t value =
- Smi::Value(reinterpret_cast<RawSmi*>(array.At(start + i)));
+ intptr_t value = Smi::Value(static_cast<SmiPtr>(array.At(start + i)));
TwoByteString::SetCharAt(string, i, value);
}
return string.raw();
diff --git a/runtime/lib/typed_data.cc b/runtime/lib/typed_data.cc
index 4980516..2e3cf1c 100644
--- a/runtime/lib/typed_data.cc
+++ b/runtime/lib/typed_data.cc
@@ -85,12 +85,12 @@
}
template <typename DstType, typename SrcType>
-static RawBool* CopyData(const Instance& dst,
- const Instance& src,
- const Smi& dst_start,
- const Smi& src_start,
- const Smi& length,
- bool clamped) {
+static BoolPtr CopyData(const Instance& dst,
+ const Instance& src,
+ const Smi& dst_start,
+ const Smi& src_start,
+ const Smi& length,
+ bool clamped) {
const DstType& dst_array = DstType::Cast(dst);
const SrcType& src_array = SrcType::Cast(src);
const intptr_t dst_offset_in_bytes = dst_start.Value();
diff --git a/runtime/lib/wasm.cc b/runtime/lib/wasm.cc
index eca0ff7..639c72a 100644
--- a/runtime/lib/wasm.cc
+++ b/runtime/lib/wasm.cc
@@ -133,7 +133,7 @@
}
}
-static RawObject* ToDartObject(wasmer_value_t ret) {
+static ObjectPtr ToDartObject(wasmer_value_t ret) {
switch (ret.tag) {
case wasmer_value_tag::WASM_I32:
return Integer::New(ret.value.I32);
@@ -165,7 +165,7 @@
}
}
-RawExternalTypedData* WasmMemoryToExternalTypedData(wasmer_memory_t* memory) {
+ExternalTypedDataPtr WasmMemoryToExternalTypedData(wasmer_memory_t* memory) {
uint8_t* data = wasmer_memory_data(memory);
uint32_t size = wasmer_memory_data_length(memory);
return ExternalTypedData::New(kExternalTypedDataUint8ArrayCid, data, size);
@@ -191,7 +191,7 @@
}
}
-RawString* DescribeModule(const wasmer_module_t* module) {
+StringPtr DescribeModule(const wasmer_module_t* module) {
std::stringstream desc;
desc << "Imports:\n";
diff --git a/runtime/observatory/lib/service_common.dart b/runtime/observatory/lib/service_common.dart
index 48181ff..f074891 100644
--- a/runtime/observatory/lib/service_common.dart
+++ b/runtime/observatory/lib/service_common.dart
@@ -131,7 +131,7 @@
_notifyDisconnect(reason);
}
- Future<Map> invokeRpcRaw(String method, Map params) {
+ Future<Map> invokeRpcRaw(String method, Map params) async {
if (!_hasInitiatedConnect) {
_hasInitiatedConnect = true;
try {
@@ -145,7 +145,7 @@
}
if (_disconnected.isCompleted) {
// This connection was closed already.
- var exception = new NetworkRpcException('WebSocket closed');
+ var exception = new NetworkRpcException(await onDisconnect);
return new Future.error(exception);
}
String serial = (_requestSerial++).toString();
diff --git a/runtime/observatory/lib/src/service/object.dart b/runtime/observatory/lib/src/service/object.dart
index 1e4bf9f..738766a 100644
--- a/runtime/observatory/lib/src/service/object.dart
+++ b/runtime/observatory/lib/src/service/object.dart
@@ -2206,6 +2206,8 @@
static const kExtension = 'Extension';
static const kServiceRegistered = 'ServiceRegistered';
static const kServiceUnregistered = 'ServiceUnregistered';
+ static const kDartDevelopmentServiceConnected =
+ 'DartDevelopmentServiceConnected';
ServiceEvent._empty(ServiceObjectOwner owner) : super._empty(owner);
@@ -2242,6 +2244,8 @@
String method;
String service;
String alias;
+ String message;
+ Uri uri;
bool lastChunk;
@@ -2345,6 +2349,12 @@
if (map['newValue'] != null) {
newValue = map['newValue'];
}
+ if (map['message'] != null) {
+ message = map['message'];
+ }
+ if (map['uri'] != null) {
+ uri = Uri.parse(map['uri']);
+ }
}
String toString() {
diff --git a/runtime/observatory/tests/service/external_service_asynchronous_invocation_test.dart b/runtime/observatory/tests/service/external_service_asynchronous_invocation_test.dart
index 58d44de..91f015d 100644
--- a/runtime/observatory/tests/service/external_service_asynchronous_invocation_test.dart
+++ b/runtime/observatory/tests/service/external_service_asynchronous_invocation_test.dart
@@ -135,7 +135,8 @@
'id': request['id'],
'error': {
'code': errorCode + iteration,
- 'data': {errorKey + end: errorValue + end}
+ 'data': {errorKey + end: errorValue + end},
+ 'message': 'error message',
}
});
}).toList();
@@ -165,7 +166,6 @@
];
main(args) => runIsolateTests(
- args, tests,
- // TODO(bkonyi): service extensions are not yet supported in DDS.
- enableDds: false,
+ args,
+ tests,
);
diff --git a/runtime/observatory/tests/service/external_service_disappear_test.dart b/runtime/observatory/tests/service/external_service_disappear_test.dart
index a015686..fec1d31 100644
--- a/runtime/observatory/tests/service/external_service_disappear_test.dart
+++ b/runtime/observatory/tests/service/external_service_disappear_test.dart
@@ -90,7 +90,6 @@
];
main(args) => runIsolateTests(
- args, tests,
- // TODO(bkonyi): service extensions are not yet supported in DDS.
- enableDds: false,
+ args,
+ tests,
);
diff --git a/runtime/observatory/tests/service/external_service_notification_invocation_test.dart b/runtime/observatory/tests/service/external_service_notification_invocation_test.dart
index a5bfd64..2a659a1 100644
--- a/runtime/observatory/tests/service/external_service_notification_invocation_test.dart
+++ b/runtime/observatory/tests/service/external_service_notification_invocation_test.dart
@@ -86,6 +86,4 @@
main(args) => runIsolateTests(
args,
tests,
- // TODO(bkonyi): service extensions are not yet supported in DDS.
- enableDds: false,
);
diff --git a/runtime/observatory/tests/service/external_service_registration_test.dart b/runtime/observatory/tests/service/external_service_registration_test.dart
index ce0aea9..469facb 100644
--- a/runtime/observatory/tests/service/external_service_registration_test.dart
+++ b/runtime/observatory/tests/service/external_service_registration_test.dart
@@ -126,6 +126,4 @@
main(args) => runIsolateTests(
args,
tests,
- // TODO(bkonyi): service extensions are not yet supported in DDS.
- enableDds: false,
);
diff --git a/runtime/observatory/tests/service/external_service_registration_via_notification_test.dart b/runtime/observatory/tests/service/external_service_registration_via_notification_test.dart
index 80729ce..008c221 100644
--- a/runtime/observatory/tests/service/external_service_registration_via_notification_test.dart
+++ b/runtime/observatory/tests/service/external_service_registration_via_notification_test.dart
@@ -104,7 +104,6 @@
];
main(args) => runIsolateTests(
- args, tests,
- // TODO(bkonyi): service extensions are not yet supported in DDS.
- enableDds: false,
+ args,
+ tests,
);
diff --git a/runtime/observatory/tests/service/external_service_synchronous_invocation_test.dart b/runtime/observatory/tests/service/external_service_synchronous_invocation_test.dart
index 45c58d8..a7cee78 100644
--- a/runtime/observatory/tests/service/external_service_synchronous_invocation_test.dart
+++ b/runtime/observatory/tests/service/external_service_synchronous_invocation_test.dart
@@ -110,7 +110,8 @@
'id': request['id'],
'error': {
'code': errorCode + iteration,
- 'data': {errorKey + end: errorValue + end}
+ 'data': {errorKey + end: errorValue + end},
+ 'message': 'error message',
}
});
@@ -127,7 +128,6 @@
];
main(args) => runIsolateTests(
- args, tests,
- // TODO(bkonyi): service extensions are not yet supported in DDS.
- enableDds: false,
+ args,
+ tests,
);
diff --git a/runtime/observatory/tests/service/get_version_rpc_test.dart b/runtime/observatory/tests/service/get_version_rpc_test.dart
index caaa488..785d7f9 100644
--- a/runtime/observatory/tests/service/get_version_rpc_test.dart
+++ b/runtime/observatory/tests/service/get_version_rpc_test.dart
@@ -12,7 +12,7 @@
var result = await vm.invokeRpcNoUpgrade('getVersion', {});
expect(result['type'], equals('Version'));
expect(result['major'], equals(3));
- expect(result['minor'], equals(30));
+ expect(result['minor'], equals(32));
expect(result['_privateMajor'], equals(0));
expect(result['_privateMinor'], equals(0));
},
diff --git a/runtime/observatory/tests/service/service_test_common.dart b/runtime/observatory/tests/service/service_test_common.dart
index 85df4f6..673f589 100644
--- a/runtime/observatory/tests/service/service_test_common.dart
+++ b/runtime/observatory/tests/service/service_test_common.dart
@@ -6,6 +6,7 @@
import 'dart:async';
import 'dart:io' show Platform;
+import 'package:dds/dds.dart';
import 'package:observatory/models.dart' as M;
import 'package:observatory/service_common.dart';
import 'package:observatory/service_io.dart';
@@ -13,6 +14,7 @@
typedef Future IsolateTest(Isolate isolate);
typedef Future VMTest(VM vm);
+typedef Future DDSTest(VM vm, DartDevelopmentService dds);
typedef void ServiceEventHandler(ServiceEvent event);
Map<String, StreamSubscription> streamSubscriptions = {};
diff --git a/runtime/observatory/tests/service/set_library_debuggable_rpc_test.dart b/runtime/observatory/tests/service/set_library_debuggable_rpc_test.dart
index 1a5c8fd..1e2753e 100644
--- a/runtime/observatory/tests/service/set_library_debuggable_rpc_test.dart
+++ b/runtime/observatory/tests/service/set_library_debuggable_rpc_test.dart
@@ -54,30 +54,6 @@
}
expect(caughtException, isTrue);
},
-
- // illegal (dart:_*) library.
- (Isolate isolate) async {
- await isolate.load();
- Library dartInternal = isolate.libraries
- .firstWhere((Library library) => library.uri == 'dart:_internal');
- var params = {
- 'libraryId': dartInternal.id,
- 'isDebuggable': false,
- };
- bool caughtException;
- try {
- await isolate.invokeRpcNoUpgrade('setLibraryDebuggable', params);
- expect(false, isTrue, reason: 'Unreachable');
- } on ServerRpcException catch (e) {
- caughtException = true;
- expect(e.code, equals(ServerRpcException.kInvalidParams));
- expect(
- e.message,
- "setLibraryDebuggable: "
- "illegal 'libraryId' parameter: ${dartInternal.id}");
- }
- expect(caughtException, isTrue);
- },
];
main(args) async => runIsolateTests(args, tests);
diff --git a/runtime/observatory/tests/service/test_helper.dart b/runtime/observatory/tests/service/test_helper.dart
index b22294d..a63bc14 100644
--- a/runtime/observatory/tests/service/test_helper.dart
+++ b/runtime/observatory/tests/service/test_helper.dart
@@ -11,7 +11,7 @@
import 'package:observatory/service_io.dart';
import 'package:test/test.dart';
import 'service_test_common.dart';
-export 'service_test_common.dart' show IsolateTest, VMTest;
+export 'service_test_common.dart' show DDSTest, IsolateTest, VMTest;
/// Whether to use causal async stacks (if not we use lazy async stacks).
const bool useCausalAsyncStacks =
@@ -337,8 +337,9 @@
List<String> mainArgs,
List<String> extraArgs,
List<String> executableArgs,
- List<VMTest> vmTests,
+ List<DDSTest> ddsTests,
List<IsolateTest> isolateTests,
+ List<VMTest> vmTests,
bool pause_on_start: false,
bool pause_on_exit: false,
bool verbose_vm: false,
@@ -460,11 +461,11 @@
);
}
- if (useDds && !enableDds) {
+ if ((useDds && !enableDds) || (!useDds && ddsTests != null)) {
print('Skipping DDS run for $name');
- } else {
- runTest(name);
+ return;
}
+ runTest(name);
}
Future<Isolate> getFirstIsolate(WebSocketVM vm) async {
@@ -581,7 +582,7 @@
}
}
-/// Runs [tests] in sequence, each of which should take an [Isolate] and
+/// Runs [tests] in sequence, each of which should take a [VM] and
/// return a [Future]. Code for setting up state can run before and/or
/// concurrently with the tests. Uses [mainArgs] to determine whether
/// to run tests or testee in this invocation of the script.
@@ -619,3 +620,42 @@
);
}
}
+
+/// Runs [tests] in sequence, each of which should take a [VM] and
+/// [DartDevelopmentService] and return a [Future]. Code for setting up state
+/// can run before and/or concurrently with the tests. Uses [mainArgs] to
+/// determine whether to run tests or testee in this invocation of the
+/// script.
+Future runDDSTests(List<String> mainArgs, List<DDSTest> tests,
+ {testeeBefore(),
+ testeeConcurrent(),
+ bool pause_on_start: false,
+ bool pause_on_exit: false,
+ bool verbose_vm: false,
+ bool pause_on_unhandled_exceptions: false,
+ bool enable_service_port_fallback: false,
+ int port = 0,
+ List<String> extraArgs,
+ List<String> executableArgs}) async {
+ if (_isTestee()) {
+ new _ServiceTesteeRunner().run(
+ testeeBefore: testeeBefore,
+ testeeConcurrent: testeeConcurrent,
+ pause_on_start: pause_on_start,
+ pause_on_exit: pause_on_exit);
+ } else {
+ new _ServiceTesterRunner().run(
+ mainArgs: mainArgs,
+ extraArgs: extraArgs,
+ executableArgs: executableArgs,
+ ddsTests: tests,
+ pause_on_start: pause_on_start,
+ pause_on_exit: pause_on_exit,
+ verbose_vm: verbose_vm,
+ pause_on_unhandled_exceptions: pause_on_unhandled_exceptions,
+ enable_service_port_fallback: enable_service_port_fallback,
+ enableDds: true,
+ port: port,
+ );
+ }
+}
diff --git a/runtime/observatory/tests/service/vm_service_dds_test.dart b/runtime/observatory/tests/service/vm_service_dds_test.dart
new file mode 100644
index 0000000..457245d
--- /dev/null
+++ b/runtime/observatory/tests/service/vm_service_dds_test.dart
@@ -0,0 +1,30 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:dds/dds.dart';
+import 'package:observatory/service_io.dart';
+import 'package:test/test.dart';
+
+import 'test_helper.dart';
+
+final tests = <DDSTest>[
+ (VM vm, DartDevelopmentService dds) async {
+ final client = WebSocketVM(
+ WebSocketVMTarget(
+ dds.remoteVmServiceWsUri.toString(),
+ ),
+ );
+ expect(client.wasOrIsConnected, false);
+ try {
+ await client.load();
+ fail(
+ 'When DDS is connected, direct connections to the VM service should fail.');
+ } on NetworkRpcException catch (e) {
+ expect(e.message, 'WebSocket closed due to error');
+ }
+ expect(client.wasOrIsConnected, false);
+ }
+];
+
+main(args) async => runDDSTests(args, tests);
diff --git a/runtime/tests/vm/dart/causal_stacks/async_throws_stack_lazy_non_symbolic_test.dart b/runtime/tests/vm/dart/causal_stacks/async_throws_stack_lazy_non_symbolic_test.dart
new file mode 100644
index 0000000..11c1a33
--- /dev/null
+++ b/runtime/tests/vm/dart/causal_stacks/async_throws_stack_lazy_non_symbolic_test.dart
@@ -0,0 +1,17 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// VMOptions=--dwarf-stack-traces --save-debugging-info=async_lazy_debug.so --lazy-async-stacks --no-causal-async-stacks
+
+import 'dart:async';
+import 'dart:io';
+
+import 'utils.dart';
+
+Future<void> main(List<String> args) async {
+ // We won't have access to the debugging info file on Android.
+ if (Platform.isAndroid) return;
+
+ await doTestsLazy('async_lazy_debug.so');
+}
diff --git a/runtime/tests/vm/dart/causal_stacks/async_throws_stack_no_causal_non_symbolic_test.dart b/runtime/tests/vm/dart/causal_stacks/async_throws_stack_no_causal_non_symbolic_test.dart
new file mode 100644
index 0000000..f65de84
--- /dev/null
+++ b/runtime/tests/vm/dart/causal_stacks/async_throws_stack_no_causal_non_symbolic_test.dart
@@ -0,0 +1,17 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// VMOptions=--dwarf-stack-traces --save-debugging-info=async_no_causal_debug.so --no-causal-async-stacks --no-lazy-async-stacks
+
+import 'dart:async';
+import 'dart:io';
+
+import 'utils.dart';
+
+Future<void> main(List<String> args) async {
+ // We won't have access to the debugging info file on Android.
+ if (Platform.isAndroid) return;
+
+ await doTestsNoCausalNoLazy('async_no_causal_debug.so');
+}
diff --git a/runtime/tests/vm/dart/causal_stacks/async_throws_stack_non_symbolic_test.dart b/runtime/tests/vm/dart/causal_stacks/async_throws_stack_non_symbolic_test.dart
new file mode 100644
index 0000000..cdb783a
--- /dev/null
+++ b/runtime/tests/vm/dart/causal_stacks/async_throws_stack_non_symbolic_test.dart
@@ -0,0 +1,17 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// VMOptions=--dwarf-stack-traces --save-debugging-info=async_causal_debug.so --causal-async-stacks --no-lazy-async-stacks
+
+import 'dart:async';
+import 'dart:io';
+
+import 'utils.dart';
+
+Future<void> main(List<String> args) async {
+ // We won't have access to the debugging info file on Android.
+ if (Platform.isAndroid) return;
+
+ await doTestsCausal('async_causal_debug.so');
+}
diff --git a/runtime/tests/vm/dart/causal_stacks/utils.dart b/runtime/tests/vm/dart/causal_stacks/utils.dart
index 118ce14..a7df656 100644
--- a/runtime/tests/vm/dart/causal_stacks/utils.dart
+++ b/runtime/tests/vm/dart/causal_stacks/utils.dart
@@ -3,12 +3,12 @@
// BSD-style license that can be found in the LICENSE file.
import 'dart:async';
+import 'dart:convert';
import 'dart:io';
-import 'dart:math';
-import 'dart:typed_data';
import 'package:path/path.dart' as path;
import 'package:expect/expect.dart';
+import 'package:native_stack_traces/native_stack_traces.dart';
// Test functions:
@@ -151,38 +151,85 @@
// Helpers:
-void assertStack(List<String> expects, StackTrace stackTrace) {
- final List<String> frames = stackTrace.toString().split('\n');
- if (frames.length < expects.length) {
- print('Actual stack:');
- print(stackTrace.toString());
- Expect.fail('Expected ${expects.length} frames, found ${frames.length}!');
+// We want lines that either start with a frame index or an async gap marker.
+final _lineRE = RegExp(r'^(?:#(?<number>\d+)|<asynchronous suspension>)');
+
+void assertStack(List<String> expects, StackTrace stackTrace,
+ [String debugInfoFilename]) async {
+ final original = await Stream.value(stackTrace.toString())
+ .transform(const LineSplitter())
+ .toList();
+ var frames = original;
+
+ // Use the DWARF stack decoder if we're running in --dwarf-stack-traces mode
+ // and in precompiled mode (otherwise --dwarf-stack-traces has no effect).
+ final decodeTrace = frames.first.startsWith('Warning:');
+ if (decodeTrace) {
+ Expect.isNotNull(debugInfoFilename);
+ final dwarf = Dwarf.fromFile(debugInfoFilename);
+ frames = await Stream.fromIterable(original)
+ .transform(DwarfStackTraceDecoder(dwarf))
+ .where(_lineRE.hasMatch)
+ .toList();
}
+
+ void printFrameInformation() {
+ print('RegExps for expected stack:');
+ expects.forEach((s) => print('"${s}"'));
+ print('');
+ if (decodeTrace) {
+ print('Non-symbolic actual stack:');
+ original.forEach(print);
+ print('');
+ }
+ print('Actual stack:');
+ frames.forEach(print);
+ print('');
+ }
+
for (int i = 0; i < expects.length; i++) {
try {
- Expect.isTrue(RegExp(expects[i]).hasMatch(frames[i]));
- } on ExpectException catch (e) {
+ Expect.isTrue(i < frames.length,
+ 'Expected at least ${expects.length} frames, found ${frames.length}');
+ } on ExpectException {
// On failed expect, print full stack for reference.
- print('Actual stack:');
- print(stackTrace.toString());
+ printFrameInformation();
+ print('Expected line ${i + 1} to be ${expects[i]} but was missing');
+ rethrow;
+ }
+ try {
+ Expect.isTrue(RegExp(expects[i]).hasMatch(frames[i]));
+ } on ExpectException {
+ // On failed expect, print full stack for reference.
+ printFrameInformation();
print('Expected line ${i + 1} to be `${expects[i]}` '
'but was `${frames[i]}`');
rethrow;
}
}
+
+ try {
+ Expect.equals(expects.length, frames.length);
+ } on ExpectException {
+ // On failed expect, print full stack for reference.
+ printFrameInformation();
+ rethrow;
+ }
}
-Future<void> doTestAwait(Future f(), List<String> expectedStack) async {
+Future<void> doTestAwait(Future f(), List<String> expectedStack,
+ [String debugInfoFilename]) async {
// Caller catches exception.
try {
await f();
Expect.fail('No exception thrown!');
} on String catch (e, s) {
- assertStack(expectedStack, s);
+ assertStack(expectedStack, s, debugInfoFilename);
}
}
-Future<void> doTestAwaitThen(Future f(), List<String> expectedStack) async {
+Future<void> doTestAwaitThen(Future f(), List<String> expectedStack,
+ [String debugInfoFilename]) async {
// Caller catches but a then is set.
try {
await f().then((e) {
@@ -190,18 +237,18 @@
});
Expect.fail('No exception thrown!');
} on String catch (e, s) {
- assertStack(expectedStack, s);
+ assertStack(expectedStack, s, debugInfoFilename);
}
}
-Future<void> doTestAwaitCatchError(
- Future f(), List<String> expectedStack) async {
+Future<void> doTestAwaitCatchError(Future f(), List<String> expectedStack,
+ [String debugInfoFilename]) async {
// Caller doesn't catch, but we have a catchError set.
StackTrace stackTrace;
await f().catchError((e, s) {
stackTrace = s;
});
- assertStack(expectedStack, stackTrace);
+ assertStack(expectedStack, stackTrace, debugInfoFilename);
}
// ----
@@ -209,7 +256,7 @@
// ----
// For: --causal-async-stacks
-Future<void> doTestsCausal() async {
+Future<void> doTestsCausal([String debugInfoFilename]) async {
final allYieldExpected = const <String>[
r'^#0 throwSync \(.*/utils.dart:16(:3)?\)$',
r'^#1 allYield3 \(.*/utils.dart:39(:3)?\)$',
@@ -228,8 +275,8 @@
r'^#6 main ',
r'^#7 _startIsolate.<anonymous closure> ',
r'^#8 _RawReceivePortImpl._handleMessage ',
- r'^$',
- ]);
+ ],
+ debugInfoFilename);
await doTestAwaitThen(
allYield,
allYieldExpected +
@@ -240,8 +287,8 @@
r'^#6 main ',
r'^#7 _startIsolate.<anonymous closure> ',
r'^#8 _RawReceivePortImpl._handleMessage ',
- r'^$',
- ]);
+ ],
+ debugInfoFilename);
await doTestAwaitCatchError(
allYield,
allYieldExpected +
@@ -252,8 +299,8 @@
r'^#6 main ',
r'^#7 _startIsolate.<anonymous closure> ',
r'^#8 _RawReceivePortImpl._handleMessage ',
- r'^$',
- ]);
+ ],
+ debugInfoFilename);
final noYieldsExpected = const <String>[
r'^#0 throwSync \(.*/utils.dart:16(:3)?\)$',
@@ -271,8 +318,8 @@
r'^#6 main ',
r'^#7 _startIsolate.<anonymous closure> ',
r'^#8 _RawReceivePortImpl._handleMessage ',
- r'^$',
- ]);
+ ],
+ debugInfoFilename);
await doTestAwaitThen(
noYields,
noYieldsExpected +
@@ -283,8 +330,8 @@
r'^#6 main ',
r'^#7 _startIsolate.<anonymous closure> ',
r'^#8 _RawReceivePortImpl._handleMessage ',
- r'^$',
- ]);
+ ],
+ debugInfoFilename);
await doTestAwaitCatchError(
noYields,
noYieldsExpected +
@@ -295,8 +342,8 @@
r'^#6 main ',
r'^#7 _startIsolate.<anonymous closure> ',
r'^#8 _RawReceivePortImpl._handleMessage ',
- r'^$',
- ]);
+ ],
+ debugInfoFilename);
final mixedYieldsExpected = const <String>[
r'^#0 throwAsync \(.*/utils.dart:21(:3)?\)$',
@@ -316,8 +363,8 @@
r'^#6 main ',
r'^#7 _startIsolate.<anonymous closure> ',
r'^#8 _RawReceivePortImpl._handleMessage ',
- r'^$',
- ]);
+ ],
+ debugInfoFilename);
await doTestAwaitThen(
mixedYields,
mixedYieldsExpected +
@@ -328,8 +375,8 @@
r'^#6 main ',
r'^#7 _startIsolate.<anonymous closure> ',
r'^#8 _RawReceivePortImpl._handleMessage ',
- r'^$',
- ]);
+ ],
+ debugInfoFilename);
await doTestAwaitCatchError(
mixedYields,
mixedYieldsExpected +
@@ -340,8 +387,8 @@
r'^#6 main ',
r'^#7 _startIsolate.<anonymous closure> ',
r'^#8 _RawReceivePortImpl._handleMessage ',
- r'^$',
- ]);
+ ],
+ debugInfoFilename);
final syncSuffixExpected = const <String>[
r'^#0 throwAsync \(.*/utils.dart:21(:3)?\)$',
@@ -361,8 +408,8 @@
r'^#6 main ',
r'^#7 _startIsolate.<anonymous closure> ',
r'^#8 _RawReceivePortImpl._handleMessage ',
- r'^$',
- ]);
+ ],
+ debugInfoFilename);
await doTestAwaitThen(
syncSuffix,
syncSuffixExpected +
@@ -373,8 +420,8 @@
r'^#6 main ',
r'^#7 _startIsolate.<anonymous closure> ',
r'^#8 _RawReceivePortImpl._handleMessage ',
- r'^$',
- ]);
+ ],
+ debugInfoFilename);
await doTestAwaitCatchError(
syncSuffix,
syncSuffixExpected +
@@ -385,8 +432,8 @@
r'^#6 main ',
r'^#7 _startIsolate.<anonymous closure> ',
r'^#8 _RawReceivePortImpl._handleMessage ',
- r'^$',
- ]);
+ ],
+ debugInfoFilename);
final nonAsyncNoStackExpected = const <String>[
r'^#0 throwAsync \(.*/utils.dart:21(:3)?\)$',
@@ -397,16 +444,18 @@
r'^#4 Future._propagateToListeners.handleValueCallback ',
r'^#5 Future._propagateToListeners ',
r'^#6 Future._completeWithValue ',
- r'^#7 Future._asyncComplete.<anonymous closure> ',
+ r'^#7 Future._asyncCompleteWithValue.<anonymous closure> ',
r'^#8 _microtaskLoop ',
r'^#9 _startMicrotaskLoop ',
r'^#10 _runPendingImmediateCallback ',
r'^#11 _RawReceivePortImpl._handleMessage ',
- r'^$',
];
- await doTestAwait(nonAsyncNoStack, nonAsyncNoStackExpected);
- await doTestAwaitThen(nonAsyncNoStack, nonAsyncNoStackExpected);
- await doTestAwaitCatchError(nonAsyncNoStack, nonAsyncNoStackExpected);
+ await doTestAwait(
+ nonAsyncNoStack, nonAsyncNoStackExpected, debugInfoFilename);
+ await doTestAwaitThen(
+ nonAsyncNoStack, nonAsyncNoStackExpected, debugInfoFilename);
+ await doTestAwaitCatchError(
+ nonAsyncNoStack, nonAsyncNoStackExpected, debugInfoFilename);
final asyncStarThrowSyncExpected = const <String>[
r'^#0 throwSync \(.*/utils.dart:16(:3)?\)$',
@@ -424,8 +473,8 @@
r'^#5 main \(.+\)$',
r'^#6 _startIsolate.<anonymous closure> \(.+\)$',
r'^#7 _RawReceivePortImpl._handleMessage \(.+\)$',
- r'^$',
- ]);
+ ],
+ debugInfoFilename);
await doTestAwaitThen(
awaitEveryAsyncStarThrowSync,
asyncStarThrowSyncExpected +
@@ -436,8 +485,8 @@
r'^#5 main \(.+\)$',
r'^#6 _startIsolate.<anonymous closure> \(.+\)$',
r'^#7 _RawReceivePortImpl._handleMessage \(.+\)$',
- r'^$',
- ]);
+ ],
+ debugInfoFilename);
await doTestAwaitCatchError(
awaitEveryAsyncStarThrowSync,
asyncStarThrowSyncExpected +
@@ -448,8 +497,8 @@
r'^#5 main \(.+\)$',
r'^#6 _startIsolate.<anonymous closure> \(.+\)$',
r'^#7 _RawReceivePortImpl._handleMessage \(.+\)$',
- r'^$',
- ]);
+ ],
+ debugInfoFilename);
final asyncStarThrowAsyncExpected = const <String>[
r'^#0 throwAsync \(.*/utils.dart:21(:3)?\)$',
@@ -468,8 +517,8 @@
r'^#5 main \(.+\)$',
r'^#6 _startIsolate.<anonymous closure> \(.+\)$',
r'^#7 _RawReceivePortImpl._handleMessage \(.+\)$',
- r'^$',
- ]);
+ ],
+ debugInfoFilename);
await doTestAwaitThen(
awaitEveryAsyncStarThrowAsync,
asyncStarThrowAsyncExpected +
@@ -480,8 +529,8 @@
r'^#5 main \(.+\)$',
r'^#6 _startIsolate.<anonymous closure> \(.+\)$',
r'^#7 _RawReceivePortImpl._handleMessage \(.+\)$',
- r'^$',
- ]);
+ ],
+ debugInfoFilename);
await doTestAwaitCatchError(
awaitEveryAsyncStarThrowAsync,
asyncStarThrowAsyncExpected +
@@ -492,8 +541,8 @@
r'^#5 main \(.+\)$',
r'^#6 _startIsolate.<anonymous closure> \(.+\)$',
r'^#7 _RawReceivePortImpl._handleMessage \(.+\)$',
- r'^$',
- ]);
+ ],
+ debugInfoFilename);
final listenAsyncStartExpected = const <String>[
r'^#0 throwAsync \(.*/utils.dart:21(:3)?\)$',
@@ -512,8 +561,8 @@
r'^#5 main \(.+\)$',
r'^#6 _startIsolate.<anonymous closure> \(.+\)$',
r'^#7 _RawReceivePortImpl._handleMessage \(.+\)$',
- r'^$',
- ]);
+ ],
+ debugInfoFilename);
await doTestAwaitThen(
listenAsyncStarThrowAsync,
listenAsyncStartExpected +
@@ -524,8 +573,8 @@
r'^#5 main \(.+\)$',
r'^#6 _startIsolate.<anonymous closure> \(.+\)$',
r'^#7 _RawReceivePortImpl._handleMessage \(.+\)$',
- r'^$',
- ]);
+ ],
+ debugInfoFilename);
await doTestAwaitCatchError(
listenAsyncStarThrowAsync,
listenAsyncStartExpected +
@@ -536,8 +585,8 @@
r'^#5 main \(.+\)$',
r'^#6 _startIsolate.<anonymous closure> \(.+\)$',
r'^#7 _RawReceivePortImpl._handleMessage \(.+\)$',
- r'^$',
- ]);
+ ],
+ debugInfoFilename);
final customErrorZoneExpected = const <String>[
r'#0 throwSync \(.*/utils.dart:16(:3)?\)$',
r'#1 allYield3 \(.*/utils.dart:39(:3)?\)$',
@@ -563,8 +612,8 @@
r'#12 main \(.+\)$',
r'#13 _startIsolate.<anonymous closure> ',
r'#14 _RawReceivePortImpl._handleMessage ',
- r'$',
- ]);
+ ],
+ debugInfoFilename);
await doTestAwaitThen(
customErrorZone,
customErrorZoneExpected +
@@ -575,8 +624,8 @@
r'#12 main \(.+\)$',
r'#13 _startIsolate.<anonymous closure> ',
r'#14 _RawReceivePortImpl._handleMessage ',
- r'$'
- ]);
+ ],
+ debugInfoFilename);
await doTestAwaitCatchError(
customErrorZone,
customErrorZoneExpected +
@@ -587,12 +636,12 @@
r'#12 main \(.+\)$',
r'#13 _startIsolate.<anonymous closure> ',
r'#14 _RawReceivePortImpl._handleMessage ',
- r'$'
- ]);
+ ],
+ debugInfoFilename);
}
// For: --no-causal-async-stacks --no-lazy-async-stacks
-Future<void> doTestsNoCausalNoLazy() async {
+Future<void> doTestsNoCausalNoLazy([String debugInfoFilename]) async {
final allYieldExpected = const <String>[
r'^#0 throwSync \(.*/utils.dart:16(:3)?\)$',
r'^#1 allYield3 \(.*/utils.dart:39(:3)?\)$',
@@ -606,11 +655,10 @@
r'^#8 _startMicrotaskLoop ',
r'^#9 _runPendingImmediateCallback ',
r'^#10 _RawReceivePortImpl._handleMessage ',
- r'^$',
];
- await doTestAwait(allYield, allYieldExpected);
- await doTestAwaitThen(allYield, allYieldExpected);
- await doTestAwaitCatchError(allYield, allYieldExpected);
+ await doTestAwait(allYield, allYieldExpected, debugInfoFilename);
+ await doTestAwaitThen(allYield, allYieldExpected, debugInfoFilename);
+ await doTestAwaitCatchError(allYield, allYieldExpected, debugInfoFilename);
final noYieldsExpected = const <String>[
r'^#0 throwSync \(.*/utils.dart:16(:3)?\)$',
@@ -673,8 +721,8 @@
r'^#51 _startMicrotaskLoop ',
r'^#52 _runPendingImmediateCallback ',
r'^#53 _RawReceivePortImpl._handleMessage ',
- r'^$',
- ]);
+ ],
+ debugInfoFilename);
await doTestAwaitThen(
noYields,
noYieldsExpected +
@@ -719,8 +767,8 @@
r'^#46 _startMicrotaskLoop ',
r'^#47 _runPendingImmediateCallback ',
r'^#48 _RawReceivePortImpl._handleMessage ',
- r'^$',
- ]);
+ ],
+ debugInfoFilename);
await doTestAwaitCatchError(
noYields,
noYieldsExpected +
@@ -765,8 +813,8 @@
r'^#46 _startMicrotaskLoop ',
r'^#47 _runPendingImmediateCallback ',
r'^#48 _RawReceivePortImpl._handleMessage ',
- r'^$',
- ]);
+ ],
+ debugInfoFilename);
final mixedYieldsExpected = const <String>[
r'^#0 throwAsync \(.*/utils.dart:21(:3)?\)$',
@@ -780,11 +828,11 @@
r'^#7 _startMicrotaskLoop ',
r'^#8 _runPendingImmediateCallback ',
r'^#9 _RawReceivePortImpl._handleMessage ',
- r'^$',
];
- await doTestAwait(mixedYields, mixedYieldsExpected);
- await doTestAwaitThen(mixedYields, mixedYieldsExpected);
- await doTestAwaitCatchError(mixedYields, mixedYieldsExpected);
+ await doTestAwait(mixedYields, mixedYieldsExpected, debugInfoFilename);
+ await doTestAwaitThen(mixedYields, mixedYieldsExpected, debugInfoFilename);
+ await doTestAwaitCatchError(
+ mixedYields, mixedYieldsExpected, debugInfoFilename);
final syncSuffixExpected = const <String>[
r'^#0 throwAsync \(.*/utils.dart:21(:3)?\)$',
@@ -798,11 +846,11 @@
r'^#7 _startMicrotaskLoop ',
r'^#8 _runPendingImmediateCallback ',
r'^#9 _RawReceivePortImpl._handleMessage ',
- r'^$',
];
- await doTestAwait(syncSuffix, syncSuffixExpected);
- await doTestAwaitThen(syncSuffix, syncSuffixExpected);
- await doTestAwaitCatchError(syncSuffix, syncSuffixExpected);
+ await doTestAwait(syncSuffix, syncSuffixExpected, debugInfoFilename);
+ await doTestAwaitThen(syncSuffix, syncSuffixExpected, debugInfoFilename);
+ await doTestAwaitCatchError(
+ syncSuffix, syncSuffixExpected, debugInfoFilename);
final nonAsyncNoStackExpected = const <String>[
r'^#0 throwAsync \(.*/utils.dart:21(:3)?\)$',
@@ -816,11 +864,13 @@
r'^#7 _startMicrotaskLoop ',
r'^#8 _runPendingImmediateCallback ',
r'^#9 _RawReceivePortImpl._handleMessage ',
- r'^$',
];
- await doTestAwait(nonAsyncNoStack, nonAsyncNoStackExpected);
- await doTestAwaitThen(nonAsyncNoStack, nonAsyncNoStackExpected);
- await doTestAwaitCatchError(nonAsyncNoStack, nonAsyncNoStackExpected);
+ await doTestAwait(
+ nonAsyncNoStack, nonAsyncNoStackExpected, debugInfoFilename);
+ await doTestAwaitThen(
+ nonAsyncNoStack, nonAsyncNoStackExpected, debugInfoFilename);
+ await doTestAwaitCatchError(
+ nonAsyncNoStack, nonAsyncNoStackExpected, debugInfoFilename);
final asyncStarThrowSyncExpected = const <String>[
r'^#0 throwSync \(.+/utils.dart:16(:3)?\)$',
@@ -835,13 +885,13 @@
r'^#8 _startMicrotaskLoop \(.+\)$',
r'^#9 _runPendingImmediateCallback \(.+\)$',
r'^#10 _RawReceivePortImpl._handleMessage \(.+\)$',
- r'^$',
];
- await doTestAwait(awaitEveryAsyncStarThrowSync, asyncStarThrowSyncExpected);
- await doTestAwaitThen(
- awaitEveryAsyncStarThrowSync, asyncStarThrowSyncExpected);
- await doTestAwaitCatchError(
- awaitEveryAsyncStarThrowSync, asyncStarThrowSyncExpected);
+ await doTestAwait(awaitEveryAsyncStarThrowSync, asyncStarThrowSyncExpected,
+ debugInfoFilename);
+ await doTestAwaitThen(awaitEveryAsyncStarThrowSync,
+ asyncStarThrowSyncExpected, debugInfoFilename);
+ await doTestAwaitCatchError(awaitEveryAsyncStarThrowSync,
+ asyncStarThrowSyncExpected, debugInfoFilename);
final asyncStarThrowAsyncExpected = const <String>[
r'^#0 throwAsync \(.*/utils.dart:21(:3)?\)$',
@@ -855,13 +905,13 @@
r'^#7 _startMicrotaskLoop ',
r'^#8 _runPendingImmediateCallback ',
r'^#9 _RawReceivePortImpl._handleMessage ',
- r'^$',
];
- await doTestAwait(awaitEveryAsyncStarThrowAsync, asyncStarThrowAsyncExpected);
- await doTestAwaitThen(
- awaitEveryAsyncStarThrowAsync, asyncStarThrowAsyncExpected);
- await doTestAwaitCatchError(
- awaitEveryAsyncStarThrowAsync, asyncStarThrowAsyncExpected);
+ await doTestAwait(awaitEveryAsyncStarThrowAsync, asyncStarThrowAsyncExpected,
+ debugInfoFilename);
+ await doTestAwaitThen(awaitEveryAsyncStarThrowAsync,
+ asyncStarThrowAsyncExpected, debugInfoFilename);
+ await doTestAwaitCatchError(awaitEveryAsyncStarThrowAsync,
+ asyncStarThrowAsyncExpected, debugInfoFilename);
final listenAsyncStartExpected = const <String>[
r'^#0 throwAsync \(.*/utils.dart:21(:3)?\)$',
@@ -875,12 +925,13 @@
r'^#7 _startMicrotaskLoop ',
r'^#8 _runPendingImmediateCallback ',
r'^#9 _RawReceivePortImpl._handleMessage ',
- r'^$',
];
- await doTestAwait(listenAsyncStarThrowAsync, listenAsyncStartExpected);
- await doTestAwaitThen(listenAsyncStarThrowAsync, listenAsyncStartExpected);
+ await doTestAwait(
+ listenAsyncStarThrowAsync, listenAsyncStartExpected, debugInfoFilename);
+ await doTestAwaitThen(
+ listenAsyncStarThrowAsync, listenAsyncStartExpected, debugInfoFilename);
await doTestAwaitCatchError(
- listenAsyncStarThrowAsync, listenAsyncStartExpected);
+ listenAsyncStarThrowAsync, listenAsyncStartExpected, debugInfoFilename);
final customErrorZoneExpected = const <String>[
r'#0 throwSync \(.*/utils.dart:16(:3)?\)$',
@@ -899,15 +950,17 @@
r'#13 _startMicrotaskLoop ',
r'#14 _runPendingImmediateCallback ',
r'#15 _RawReceivePortImpl._handleMessage ',
- r'$',
];
- await doTestAwait(customErrorZone, customErrorZoneExpected);
- await doTestAwaitThen(customErrorZone, customErrorZoneExpected);
- await doTestAwaitCatchError(customErrorZone, customErrorZoneExpected);
+ await doTestAwait(
+ customErrorZone, customErrorZoneExpected, debugInfoFilename);
+ await doTestAwaitThen(
+ customErrorZone, customErrorZoneExpected, debugInfoFilename);
+ await doTestAwaitCatchError(
+ customErrorZone, customErrorZoneExpected, debugInfoFilename);
}
// For: --lazy-async-stacks
-Future<void> doTestsLazy() async {
+Future<void> doTestsLazy([String debugInfoFilename]) async {
final allYieldExpected = const <String>[
r'^#0 throwSync \(.*/utils.dart:16(:3)?\)$',
r'^#1 allYield3 \(.*/utils.dart:39(:3)?\)$',
@@ -927,22 +980,17 @@
r'^<asynchronous suspension>$',
r'^#6 main ',
r'^<asynchronous suspension>$',
- r'^$',
- ]);
+ ],
+ debugInfoFilename);
await doTestAwaitThen(
allYield,
allYieldExpected +
const <String>[
r'^#4 doTestAwaitThen.<anonymous closure> ',
r'^<asynchronous suspension>$',
- r'^$',
- ]);
- await doTestAwaitCatchError(
- allYield,
- allYieldExpected +
- const <String>[
- r'^$',
- ]);
+ ],
+ debugInfoFilename);
+ await doTestAwaitCatchError(allYield, allYieldExpected, debugInfoFilename);
final noYieldsExpected = const <String>[
r'^#0 throwSync \(.*/utils.dart:16(:3)?\)$',
@@ -959,8 +1007,8 @@
r'^<asynchronous suspension>$',
r'^#6 main ',
r'^<asynchronous suspension>$',
- r'^$',
- ]);
+ ],
+ debugInfoFilename);
await doTestAwaitThen(
noYields,
noYieldsExpected +
@@ -970,8 +1018,8 @@
r'^<asynchronous suspension>$',
r'^#6 main ',
r'^<asynchronous suspension>$',
- r'^$',
- ]);
+ ],
+ debugInfoFilename);
await doTestAwaitCatchError(
noYields,
noYieldsExpected +
@@ -981,8 +1029,8 @@
r'^<asynchronous suspension>$',
r'^#6 main ',
r'^<asynchronous suspension>$',
- r'^$',
- ]);
+ ],
+ debugInfoFilename);
final mixedYieldsExpected = const <String>[
r'^#0 throwAsync \(.*/utils.dart:21(:3)?\)$',
@@ -1002,22 +1050,18 @@
r'^<asynchronous suspension>$',
r'^#5 main ',
r'^<asynchronous suspension>$',
- r'^$',
- ]);
+ ],
+ debugInfoFilename);
await doTestAwaitThen(
mixedYields,
mixedYieldsExpected +
const <String>[
r'^#3 doTestAwaitThen.<anonymous closure> ',
r'^<asynchronous suspension>$',
- r'^$',
- ]);
+ ],
+ debugInfoFilename);
await doTestAwaitCatchError(
- mixedYields,
- mixedYieldsExpected +
- const <String>[
- r'^$',
- ]);
+ mixedYields, mixedYieldsExpected, debugInfoFilename);
final syncSuffixExpected = const <String>[
r'^#0 throwAsync \(.*/utils.dart:21(:3)?\)$',
@@ -1037,22 +1081,18 @@
r'^<asynchronous suspension>$',
r'^#5 main ',
r'^<asynchronous suspension>$',
- r'^$',
- ]);
+ ],
+ debugInfoFilename);
await doTestAwaitThen(
syncSuffix,
syncSuffixExpected +
const <String>[
r'^#3 doTestAwaitThen.<anonymous closure> ',
r'^<asynchronous suspension>$',
- r'^$',
- ]);
+ ],
+ debugInfoFilename);
await doTestAwaitCatchError(
- syncSuffix,
- syncSuffixExpected +
- const <String>[
- r'^$',
- ]);
+ syncSuffix, syncSuffixExpected, debugInfoFilename);
final nonAsyncNoStackExpected = const <String>[
r'^#0 throwAsync \(.*/utils.dart:21(:3)?\)$',
@@ -1072,22 +1112,18 @@
r'^<asynchronous suspension>$',
r'^#5 main ',
r'^<asynchronous suspension>$',
- r'^$',
- ]);
+ ],
+ debugInfoFilename);
await doTestAwaitThen(
nonAsyncNoStack,
nonAsyncNoStackExpected +
const <String>[
r'^#3 doTestAwaitThen.<anonymous closure> ',
r'^<asynchronous suspension>$',
- r'^$',
- ]);
+ ],
+ debugInfoFilename);
await doTestAwaitCatchError(
- nonAsyncNoStack,
- nonAsyncNoStackExpected +
- const <String>[
- r'^$',
- ]);
+ nonAsyncNoStack, nonAsyncNoStackExpected, debugInfoFilename);
final asyncStarThrowSyncExpected = const <String>[
r'^#0 throwSync \(.+/utils.dart:16(:3)?\)$',
@@ -1106,22 +1142,18 @@
r'^<asynchronous suspension>$',
r'^#5 main ',
r'^<asynchronous suspension>$',
- r'^$',
- ]);
+ ],
+ debugInfoFilename);
await doTestAwaitThen(
awaitEveryAsyncStarThrowSync,
asyncStarThrowSyncExpected +
const <String>[
r'^#3 doTestAwaitThen.<anonymous closure> ',
r'^<asynchronous suspension>$',
- r'^$',
- ]);
- await doTestAwaitCatchError(
- awaitEveryAsyncStarThrowSync,
- asyncStarThrowSyncExpected +
- const <String>[
- r'^$',
- ]);
+ ],
+ debugInfoFilename);
+ await doTestAwaitCatchError(awaitEveryAsyncStarThrowSync,
+ asyncStarThrowSyncExpected, debugInfoFilename);
final asyncStarThrowAsyncExpected = const <String>[
r'^#0 throwAsync \(.*/utils.dart:21(:3)?\)$',
@@ -1141,22 +1173,18 @@
r'^<asynchronous suspension>$',
r'^#5 main ',
r'^<asynchronous suspension>$',
- r'^$',
- ]);
+ ],
+ debugInfoFilename);
await doTestAwaitThen(
awaitEveryAsyncStarThrowAsync,
asyncStarThrowAsyncExpected +
const <String>[
r'^#3 doTestAwaitThen.<anonymous closure> ',
r'^<asynchronous suspension>$',
- r'^$',
- ]);
- await doTestAwaitCatchError(
- awaitEveryAsyncStarThrowAsync,
- asyncStarThrowAsyncExpected +
- const <String>[
- r'^$',
- ]);
+ ],
+ debugInfoFilename);
+ await doTestAwaitCatchError(awaitEveryAsyncStarThrowAsync,
+ asyncStarThrowAsyncExpected, debugInfoFilename);
final listenAsyncStartExpected = const <String>[
r'^#0 throwAsync \(.*/utils.dart:21(:3)?\)$',
@@ -1165,12 +1193,13 @@
r'^<asynchronous suspension>$',
r'^#2 listenAsyncStarThrowAsync.<anonymous closure> \(.+/utils.dart(:0)?\)$',
r'^<asynchronous suspension>$',
- r'^$',
];
- await doTestAwait(listenAsyncStarThrowAsync, listenAsyncStartExpected);
- await doTestAwaitThen(listenAsyncStarThrowAsync, listenAsyncStartExpected);
+ await doTestAwait(
+ listenAsyncStarThrowAsync, listenAsyncStartExpected, debugInfoFilename);
+ await doTestAwaitThen(
+ listenAsyncStarThrowAsync, listenAsyncStartExpected, debugInfoFilename);
await doTestAwaitCatchError(
- listenAsyncStarThrowAsync, listenAsyncStartExpected);
+ listenAsyncStarThrowAsync, listenAsyncStartExpected, debugInfoFilename);
final customErrorZoneExpected = const <String>[
r'#0 throwSync \(.*/utils.dart:16(:3)?\)$',
@@ -1182,9 +1211,11 @@
r'<asynchronous suspension>$',
r'#4 customErrorZone.<anonymous closure> \(.*/utils.dart:144(:5)?\)$',
r'<asynchronous suspension>$',
- r'^$',
];
- await doTestAwait(customErrorZone, customErrorZoneExpected);
- await doTestAwaitThen(customErrorZone, customErrorZoneExpected);
- await doTestAwaitCatchError(customErrorZone, customErrorZoneExpected);
+ await doTestAwait(
+ customErrorZone, customErrorZoneExpected, debugInfoFilename);
+ await doTestAwaitThen(
+ customErrorZone, customErrorZoneExpected, debugInfoFilename);
+ await doTestAwaitCatchError(
+ customErrorZone, customErrorZoneExpected, debugInfoFilename);
}
diff --git a/runtime/tests/vm/dart/sendandexit_test.dart b/runtime/tests/vm/dart/sendandexit_test.dart
new file mode 100644
index 0000000..cbc617e
--- /dev/null
+++ b/runtime/tests/vm/dart/sendandexit_test.dart
@@ -0,0 +1,85 @@
+// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+//
+// VMOptions=--enable-isolate-groups
+//
+// Validates functionality of sendAndExit.
+
+import 'dart:_internal' show sendAndExit;
+import 'dart:async';
+import 'dart:isolate';
+import 'dart:nativewrappers';
+
+import "package:expect/expect.dart";
+
+doNothingWorker(data) {}
+
+spawnWorker(worker, data) async {
+ Completer completer = Completer();
+ runZoned(() async {
+ final isolate = await Isolate.spawn(worker, [data]);
+ completer.complete(isolate);
+ }, onError: (e, st) => completer.complete(e));
+ return await completer.future;
+}
+
+verifyCantSendAnonymousClosure() async {
+ final result = await spawnWorker(doNothingWorker, () {});
+ Expect.equals(
+ "Invalid argument(s): Illegal argument in isolate message :"
+ " (object is a closure - Function '<anonymous closure>': static.)",
+ result.toString());
+}
+
+class NativeWrapperClass extends NativeFieldWrapperClass1 {}
+
+verifyCantSendNative() async {
+ final result = await spawnWorker(doNothingWorker, NativeWrapperClass());
+ Expect.isTrue(result.toString().startsWith("Invalid argument(s): "
+ "Illegal argument in isolate message : "
+ "(object extends NativeWrapper"));
+}
+
+verifyCantSendRegexp() async {
+ var receivePort = ReceivePort();
+ final result = await spawnWorker(doNothingWorker, receivePort);
+ Expect.equals(
+ "Invalid argument(s): Illegal argument in isolate message : "
+ "(object is a ReceivePort)",
+ result.toString());
+ receivePort.close();
+}
+
+class Message {
+ SendPort sendPort;
+ Function closure;
+
+ Message(this.sendPort, this.closure);
+}
+
+add(a, b) => a + b;
+
+worker(Message message) async {
+ final port = new ReceivePort();
+ final inbox = new StreamIterator<dynamic>(port);
+ message.sendPort.send(message.closure(2, 3));
+ port.close();
+}
+
+verifyCanSendStaticMethod() async {
+ final port = ReceivePort();
+ final inbox = StreamIterator<dynamic>(port);
+ final isolate = await Isolate.spawn(worker, Message(port.sendPort, add));
+
+ await inbox.moveNext();
+ Expect.equals(inbox.current, 5);
+ port.close();
+}
+
+main() async {
+ await verifyCantSendAnonymousClosure();
+ await verifyCantSendNative();
+ await verifyCantSendRegexp();
+ await verifyCanSendStaticMethod();
+}
diff --git a/runtime/tests/vm/vm.status b/runtime/tests/vm/vm.status
index 010b5c7..7011e5b 100644
--- a/runtime/tests/vm/vm.status
+++ b/runtime/tests/vm/vm.status
@@ -28,7 +28,10 @@
dart/bytecode_with_ast_in_aot_test: SkipByDesign # The test doesn't know location of cross-platform gen_snapshot
[ $builder_tag == obfuscated ]
-dart/causal_stacks/*: SkipByDesign # Asserts exact stacktrace output.
+dart/causal_stacks/async_throws_stack_lazy_test: SkipByDesign # Asserts exact stacktrace output.
+dart/causal_stacks/async_throws_stack_no_causal_test: SkipByDesign # Asserts exact stacktrace output.
+dart/causal_stacks/async_throws_stack_test: SkipByDesign # Asserts exact stacktrace output.
+dart/causal_stacks/sync_async_start_pkg_test_test: SkipByDesign # Asserts exact stacktrace output.
[ $builder_tag == optimization_counter_threshold ]
cc/*: Skip # Many tests want see unoptimized code running
diff --git a/runtime/vm/bitmap_test.cc b/runtime/vm/bitmap_test.cc
index e8f6418..2c7f3d9 100644
--- a/runtime/vm/bitmap_test.cc
+++ b/runtime/vm/bitmap_test.cc
@@ -16,7 +16,7 @@
static const uint32_t kTestPcOffset = 0x4;
static const intptr_t kTestSpillSlotBitCount = 0;
-static RawCompressedStackMaps* MapsFromBuilder(BitmapBuilder* bmap) {
+static CompressedStackMapsPtr MapsFromBuilder(BitmapBuilder* bmap) {
CompressedStackMapsBuilder builder;
builder.AddEntry(kTestPcOffset, bmap, kTestSpillSlotBitCount);
return builder.Finalize();
diff --git a/runtime/vm/bootstrap.cc b/runtime/vm/bootstrap.cc
index 67ff960..1065295 100644
--- a/runtime/vm/bootstrap.cc
+++ b/runtime/vm/bootstrap.cc
@@ -90,9 +90,9 @@
ClassFinalizer::LoadClassMembers(cls);
}
-static RawError* BootstrapFromKernel(Thread* thread,
- const uint8_t* kernel_buffer,
- intptr_t kernel_buffer_size) {
+static ErrorPtr BootstrapFromKernel(Thread* thread,
+ const uint8_t* kernel_buffer,
+ intptr_t kernel_buffer_size) {
Zone* zone = thread->zone();
const char* error = nullptr;
std::unique_ptr<kernel::Program> program = kernel::Program::ReadFromBuffer(
@@ -140,8 +140,8 @@
return Error::null();
}
-RawError* Bootstrap::DoBootstrapping(const uint8_t* kernel_buffer,
- intptr_t kernel_buffer_size) {
+ErrorPtr Bootstrap::DoBootstrapping(const uint8_t* kernel_buffer,
+ intptr_t kernel_buffer_size) {
Thread* thread = Thread::Current();
Isolate* isolate = thread->isolate();
Zone* zone = thread->zone();
@@ -167,8 +167,8 @@
return BootstrapFromKernel(thread, kernel_buffer, kernel_buffer_size);
}
#else
-RawError* Bootstrap::DoBootstrapping(const uint8_t* kernel_buffer,
- intptr_t kernel_buffer_size) {
+ErrorPtr Bootstrap::DoBootstrapping(const uint8_t* kernel_buffer,
+ intptr_t kernel_buffer_size) {
UNREACHABLE();
return Error::null();
}
diff --git a/runtime/vm/bootstrap.h b/runtime/vm/bootstrap.h
index 895f9d1..e9c3bd9 100644
--- a/runtime/vm/bootstrap.h
+++ b/runtime/vm/bootstrap.h
@@ -7,11 +7,11 @@
#include "include/dart_api.h"
#include "vm/allocation.h"
+#include "vm/tagged_pointer.h"
namespace dart {
// Forward declarations.
-class RawError;
namespace kernel {
class Program;
}
@@ -24,8 +24,8 @@
// bootstrapping.
// The caller of this function is responsible for managing the kernel
// program's memory.
- static RawError* DoBootstrapping(const uint8_t* kernel_buffer,
- intptr_t kernel_buffer_size);
+ static ErrorPtr DoBootstrapping(const uint8_t* kernel_buffer,
+ intptr_t kernel_buffer_size);
static void SetupNativeResolver();
static bool IsBootstrapResolver(Dart_NativeEntryResolver resolver);
diff --git a/runtime/vm/bootstrap_natives.h b/runtime/vm/bootstrap_natives.h
index 8f3b762..65e0dae 100644
--- a/runtime/vm/bootstrap_natives.h
+++ b/runtime/vm/bootstrap_natives.h
@@ -58,6 +58,7 @@
V(SendPortImpl_get_id, 1) \
V(SendPortImpl_get_hashcode, 1) \
V(SendPortImpl_sendInternal_, 2) \
+ V(SendPortImpl_sendAndExitInternal_, 2) \
V(Smi_bitAndFromSmi, 2) \
V(Smi_bitNegate, 1) \
V(Smi_bitLength, 1) \
@@ -487,8 +488,8 @@
static const uint8_t* Symbol(Dart_NativeFunction* nf);
#define DECLARE_BOOTSTRAP_NATIVE(name, ignored) \
- static RawObject* DN_##name(Thread* thread, Zone* zone, \
- NativeArguments* arguments);
+ static ObjectPtr DN_##name(Thread* thread, Zone* zone, \
+ NativeArguments* arguments);
BOOTSTRAP_NATIVE_LIST(DECLARE_BOOTSTRAP_NATIVE)
#if !defined(DART_PRECOMPILED_RUNTIME)
diff --git a/runtime/vm/class_finalizer.cc b/runtime/vm/class_finalizer.cc
index a53cf86..cfe2a4d 100644
--- a/runtime/vm/class_finalizer.cc
+++ b/runtime/vm/class_finalizer.cc
@@ -668,10 +668,10 @@
}
}
-RawAbstractType* ClassFinalizer::FinalizeType(const Class& cls,
- const AbstractType& type,
- FinalizationKind finalization,
- PendingTypes* pending_types) {
+AbstractTypePtr ClassFinalizer::FinalizeType(const Class& cls,
+ const AbstractType& type,
+ FinalizationKind finalization,
+ PendingTypes* pending_types) {
// Only the 'root' type of the graph can be canonicalized, after all depending
// types have been bound checked.
ASSERT((pending_types == NULL) || (finalization < kCanonicalize));
@@ -1186,7 +1186,7 @@
}
}
-RawError* ClassFinalizer::LoadClassMembers(const Class& cls) {
+ErrorPtr ClassFinalizer::LoadClassMembers(const Class& cls) {
ASSERT(Thread::Current()->IsMutatorThread());
LongJumpScope jump;
if (setjmp(*jump.Set()) == 0) {
@@ -1474,21 +1474,21 @@
return old_to_new_cids_[cid];
}
- void VisitObject(RawObject* obj) {
+ void VisitObject(ObjectPtr obj) {
if (obj->IsClass()) {
- RawClass* cls = Class::RawCast(obj);
+ ClassPtr cls = Class::RawCast(obj);
cls->ptr()->id_ = Map(cls->ptr()->id_);
} else if (obj->IsField()) {
- RawField* field = Field::RawCast(obj);
+ FieldPtr field = Field::RawCast(obj);
field->ptr()->guarded_cid_ = Map(field->ptr()->guarded_cid_);
field->ptr()->is_nullable_ = Map(field->ptr()->is_nullable_);
} else if (obj->IsTypeParameter()) {
- RawTypeParameter* param = TypeParameter::RawCast(obj);
+ TypeParameterPtr param = TypeParameter::RawCast(obj);
param->ptr()->parameterized_class_id_ =
Map(param->ptr()->parameterized_class_id_);
} else if (obj->IsType()) {
- RawType* type = Type::RawCast(obj);
- RawObject* id = type->ptr()->type_class_id_;
+ TypePtr type = Type::RawCast(obj);
+ ObjectPtr id = type->ptr()->type_class_id_;
if (!id->IsHeapObject()) {
type->ptr()->type_class_id_ =
Smi::New(Map(Smi::Value(Smi::RawCast(id))));
@@ -1499,7 +1499,7 @@
if (old_cid != new_cid) {
// Don't touch objects that are unchanged. In particular, Instructions,
// which are write-protected.
- obj->SetClassId(new_cid);
+ obj->ptr()->SetClassId(new_cid);
}
}
}
@@ -1558,30 +1558,30 @@
// In the Dart VM heap the following instances directly use cids for the
// computation of canonical hash codes:
//
-// * RawType (due to RawType::type_class_id_)
-// * RawTypeParameter (due to RawTypeParameter::parameterized_class_id_)
+// * RawType (due to TypeLayout::type_class_id_)
+// * RawTypeParameter (due to TypeParameterLayout::parameterized_class_id_)
//
// The following instances use cids for the computation of canonical hash codes
// indirectly:
//
-// * RawTypeRef (due to RawTypeRef::type_->type_class_id)
-// * RawType (due to RawType::signature_'s result/parameter types)
+// * RawTypeRef (due to TypeRefLayout::type_->type_class_id)
+// * RawType (due to TypeLayout::signature_'s result/parameter types)
// * RawTypeArguments (due to type references)
// * RawInstance (due to instance fields)
// * RawArray (due to type arguments & array entries)
//
// Caching of the canonical hash codes happens for:
//
-// * RawType::hash_
-// * RawTypeParameter::hash_
-// * RawTypeArguments::hash_
+// * TypeLayout::hash_
+// * TypeParameterLayout::hash_
+// * TypeArgumentsLayout::hash_
// * RawInstance (weak table)
// * RawArray (weak table)
//
// No caching of canonical hash codes (i.e. it gets re-computed every time)
// happens for:
//
-// * RawTypeRef (computed via RawTypeRef::type_->type_class_id)
+// * RawTypeRef (computed via TypeRefLayout::type_->type_class_id)
//
// Usages of canonical hash codes are:
//
@@ -1596,7 +1596,7 @@
type_(Type::Handle(zone)),
type_args_(TypeArguments::Handle(zone)) {}
- void VisitObject(RawObject* obj) {
+ void VisitObject(ObjectPtr obj) {
if (obj->IsTypeParameter()) {
type_param_ ^= obj;
type_param_.SetHash(0);
diff --git a/runtime/vm/class_finalizer.h b/runtime/vm/class_finalizer.h
index f580aaf..b970fa1 100644
--- a/runtime/vm/class_finalizer.h
+++ b/runtime/vm/class_finalizer.h
@@ -27,7 +27,7 @@
// Finalize given type while parsing class cls.
// Also canonicalize and bound check type if applicable.
- static RawAbstractType* FinalizeType(
+ static AbstractTypePtr FinalizeType(
const Class& cls,
const AbstractType& type,
FinalizationKind finalization = kCanonicalize,
@@ -69,7 +69,7 @@
// and fields of the class.
//
// Returns Error::null() if there is no loading error.
- static RawError* LoadClassMembers(const Class& cls);
+ static ErrorPtr LoadClassMembers(const Class& cls);
#if !defined(DART_PRECOMPILED_RUNTIME)
// Verify that the classes have been properly prefinalized. This is
diff --git a/runtime/vm/class_finalizer_test.cc b/runtime/vm/class_finalizer_test.cc
index 7768c44..29a708a 100644
--- a/runtime/vm/class_finalizer_test.cc
+++ b/runtime/vm/class_finalizer_test.cc
@@ -9,7 +9,7 @@
namespace dart {
-static RawClass* CreateTestClass(const char* name) {
+static ClassPtr CreateTestClass(const char* name) {
const String& class_name =
String::Handle(Symbols::New(Thread::Current(), name));
const Script& script = Script::Handle();
diff --git a/runtime/vm/class_table.cc b/runtime/vm/class_table.cc
index 74a8677..c458acb 100644
--- a/runtime/vm/class_table.cc
+++ b/runtime/vm/class_table.cc
@@ -47,7 +47,6 @@
table[kForwardingCorpse] = vm_shared_class_table->SizeAt(kForwardingCorpse);
table[kDynamicCid] = vm_shared_class_table->SizeAt(kDynamicCid);
table[kVoidCid] = vm_shared_class_table->SizeAt(kVoidCid);
- table[kNeverCid] = vm_shared_class_table->SizeAt(kNeverCid);
table_.store(table);
}
#if defined(SUPPORT_UNBOXED_INSTANCE_FIELDS)
@@ -72,7 +71,7 @@
NOT_IN_PRODUCT(free(trace_allocation_table_.load()));
}
-void ClassTable::set_table(RawClass** table) {
+void ClassTable::set_table(ClassPtr* table) {
Isolate* isolate = Isolate::Current();
ASSERT(isolate != nullptr);
table_.store(table);
@@ -83,7 +82,7 @@
: top_(kNumPredefinedCids),
capacity_(0),
table_(NULL),
- old_class_tables_(new MallocGrowableArray<RawClass**>()),
+ old_class_tables_(new MallocGrowableArray<ClassPtr*>()),
shared_class_table_(shared_class_table) {
if (Dart::vm_isolate() == NULL) {
ASSERT(kInitialCapacity >= kNumPredefinedCids);
@@ -92,14 +91,14 @@
// Don't use set_table because caller is supposed to set up isolates
// cached copy when constructing ClassTable. Isolate::Current might not
// be available at this point yet.
- table_.store(static_cast<RawClass**>(calloc(capacity_, sizeof(RawClass*))));
+ table_.store(static_cast<ClassPtr*>(calloc(capacity_, sizeof(ClassPtr))));
} else {
// Duplicate the class table from the VM isolate.
ClassTable* vm_class_table = Dart::vm_isolate()->class_table();
capacity_ = vm_class_table->capacity_;
// Note that [calloc] will zero-initialize the memory.
- RawClass** table =
- static_cast<RawClass**>(calloc(capacity_, sizeof(RawClass*)));
+ ClassPtr* table =
+ static_cast<ClassPtr*>(calloc(capacity_, sizeof(ClassPtr)));
// The following cids don't have a corresponding class object in Dart code.
// We therefore need to initialize them eagerly.
for (intptr_t i = kObjectCid; i < kInstanceCid; i++) {
@@ -110,7 +109,6 @@
table[kForwardingCorpse] = vm_class_table->At(kForwardingCorpse);
table[kDynamicCid] = vm_class_table->At(kDynamicCid);
table[kVoidCid] = vm_class_table->At(kVoidCid);
- table[kNeverCid] = vm_class_table->At(kNeverCid);
// Don't use set_table because caller is supposed to set up isolates
// cached copy when constructing ClassTable. Isolate::Current might not
// be available at this point yet.
@@ -126,7 +124,7 @@
free(table_.load());
}
-void ClassTable::AddOldTable(RawClass** old_class_table) {
+void ClassTable::AddOldTable(ClassPtr* old_class_table) {
ASSERT(Thread::Current()->IsMutatorThread());
old_class_tables_->Add(old_class_table);
}
@@ -226,8 +224,8 @@
ASSERT(new_capacity > capacity_);
auto old_table = table_.load();
- auto new_table = static_cast<RawClass**>(
- malloc(new_capacity * sizeof(RawClass*))); // NOLINT
+ auto new_table = static_cast<ClassPtr*>(
+ malloc(new_capacity * sizeof(ClassPtr))); // NOLINT
intptr_t i;
for (i = 0; i < capacity_; i++) {
// Don't use memmove, which changes this from a relaxed atomic operation
@@ -337,9 +335,9 @@
void ClassTable::Remap(intptr_t* old_to_new_cid) {
ASSERT(Thread::Current()->IsAtSafepoint());
const intptr_t num_cids = NumCids();
- std::unique_ptr<RawClass*[]> cls_by_old_cid(new RawClass*[num_cids]);
+ std::unique_ptr<ClassPtr[]> cls_by_old_cid(new ClassPtr[num_cids]);
auto* table = table_.load();
- memmove(cls_by_old_cid.get(), table, sizeof(RawClass*) * num_cids);
+ memmove(cls_by_old_cid.get(), table, sizeof(ClassPtr) * num_cids);
for (intptr_t i = 0; i < num_cids; i++) {
table[old_to_new_cid[i]] = cls_by_old_cid[i];
}
@@ -374,8 +372,8 @@
visitor->set_gc_root_type("class table");
if (top_ != 0) {
auto* table = table_.load();
- RawObject** from = reinterpret_cast<RawObject**>(&table[0]);
- RawObject** to = reinterpret_cast<RawObject**>(&table[top_ - 1]);
+ ObjectPtr* from = reinterpret_cast<ObjectPtr*>(&table[0]);
+ ObjectPtr* to = reinterpret_cast<ObjectPtr*>(&table[top_ - 1]);
visitor->VisitPointers(from, to);
}
visitor->clear_gc_root_type();
@@ -415,14 +413,14 @@
continue;
}
cls = At(i);
- if (cls.raw() != reinterpret_cast<RawClass*>(0)) {
+ if (cls.raw() != nullptr) {
name = cls.Name();
OS::PrintErr("%" Pd ": %s\n", i, name.ToCString());
}
}
}
-void ClassTable::SetAt(intptr_t index, RawClass* raw_cls) {
+void ClassTable::SetAt(intptr_t index, ClassPtr raw_cls) {
// This is called by snapshot reader and class finalizer.
ASSERT(index < capacity_);
const intptr_t size =
diff --git a/runtime/vm/class_table.h b/runtime/vm/class_table.h
index 510927a..6bb42d2 100644
--- a/runtime/vm/class_table.h
+++ b/runtime/vm/class_table.h
@@ -15,6 +15,7 @@
#include "vm/class_id.h"
#include "vm/flags.h"
#include "vm/globals.h"
+#include "vm/tagged_pointer.h"
namespace dart {
@@ -30,7 +31,6 @@
template <typename T>
class MallocGrowableArray;
class ObjectPointerVisitor;
-class RawClass;
// Wraps a 64-bit integer to represent the bitmap of unboxed fields
// stored in the shared class table.
@@ -258,12 +258,12 @@
SharedClassTable* shared_class_table() const { return shared_class_table_; }
- void CopyBeforeHotReload(RawClass*** copy, intptr_t* copy_num_cids) {
+ void CopyBeforeHotReload(ClassPtr** copy, intptr_t* copy_num_cids) {
// The [IsolateReloadContext] will need to maintain a copy of the old class
// table until instances have been morphed.
const intptr_t num_cids = NumCids();
- const intptr_t bytes = sizeof(RawClass*) * num_cids;
- auto class_table = static_cast<RawClass**>(malloc(bytes));
+ const intptr_t bytes = sizeof(ClassPtr) * num_cids;
+ auto class_table = static_cast<ClassPtr*>(malloc(bytes));
auto table = table_.load();
for (intptr_t i = 0; i < num_cids; i++) {
// Don't use memmove, which changes this from a relaxed atomic operation
@@ -282,7 +282,7 @@
// here).
}
- void ResetAfterHotReload(RawClass** old_table,
+ void ResetAfterHotReload(ClassPtr* old_table,
intptr_t num_old_cids,
bool is_rollback) {
// The [IsolateReloadContext] is no longer source-of-truth for GC after we
@@ -307,7 +307,7 @@
}
// Thread-safe.
- RawClass* At(intptr_t index) const {
+ ClassPtr At(intptr_t index) const {
ASSERT(IsValidIndex(index));
return table_.load()[index];
}
@@ -316,7 +316,7 @@
return shared_class_table_->SizeAt(index);
}
- void SetAt(intptr_t index, RawClass* raw_cls);
+ void SetAt(intptr_t index, ClassPtr raw_cls);
bool IsValidIndex(intptr_t index) const {
return shared_class_table_->IsValidIndex(index);
@@ -357,7 +357,7 @@
#ifndef PRODUCT
// Describes layout of heap stats for code generation. See offset_extractor.cc
- struct ArrayLayout {
+ struct ArrayTraits {
static intptr_t elements_start_offset() { return 0; }
static constexpr intptr_t kElementSize = sizeof(uint8_t);
@@ -387,20 +387,20 @@
static const int kInitialCapacity = SharedClassTable::kInitialCapacity;
static const int kCapacityIncrement = SharedClassTable::kCapacityIncrement;
- void AddOldTable(RawClass** old_table);
+ void AddOldTable(ClassPtr* old_table);
void Grow(intptr_t index);
- RawClass** table() { return table_.load(); }
- void set_table(RawClass** table);
+ ClassPtr* table() { return table_.load(); }
+ void set_table(ClassPtr* table);
intptr_t top_;
intptr_t capacity_;
// Copy-on-write is used for table_, with old copies stored in
// old_class_tables_.
- AcqRelAtomic<RawClass**> table_;
- MallocGrowableArray<RawClass**>* old_class_tables_;
+ AcqRelAtomic<ClassPtr*> table_;
+ MallocGrowableArray<ClassPtr*>* old_class_tables_;
SharedClassTable* shared_class_table_;
DISALLOW_COPY_AND_ASSIGN(ClassTable);
diff --git a/runtime/vm/clustered_snapshot.cc b/runtime/vm/clustered_snapshot.cc
index 8eca9ce..98558ee 100644
--- a/runtime/vm/clustered_snapshot.cc
+++ b/runtime/vm/clustered_snapshot.cc
@@ -54,7 +54,7 @@
static void RelocateCodeObjects(
bool is_vm,
- GrowableArray<RawCode*>* code_objects,
+ GrowableArray<CodePtr>* code_objects,
GrowableArray<ImageWriterCommand>* image_writer_commands) {
auto thread = Thread::Current();
auto isolate = is_vm ? Dart::vm_isolate() : thread->isolate();
@@ -63,48 +63,48 @@
CodeRelocator::Relocate(thread, code_objects, image_writer_commands, is_vm);
}
-class RawCodeKeyValueTrait {
+class CodePtrKeyValueTrait {
public:
// Typedefs needed for the DirectChainedHashMap template.
- typedef const RawCode* Key;
- typedef const RawCode* Value;
- typedef const RawCode* Pair;
+ typedef const CodePtr Key;
+ typedef const CodePtr Value;
+ typedef CodePtr Pair;
static Key KeyOf(Pair kv) { return kv; }
static Value ValueOf(Pair kv) { return kv; }
static inline intptr_t Hashcode(Key key) {
- return reinterpret_cast<intptr_t>(key);
+ return static_cast<intptr_t>(key);
}
static inline bool IsKeyEqual(Pair pair, Key key) { return pair == key; }
};
-typedef DirectChainedHashMap<RawCodeKeyValueTrait> RawCodeSet;
+typedef DirectChainedHashMap<CodePtrKeyValueTrait> RawCodeSet;
#endif // defined(DART_PRECOMPILER) && !defined(TARGET_ARCH_IA32)
-static RawObject* AllocateUninitialized(PageSpace* old_space, intptr_t size) {
+static ObjectPtr AllocateUninitialized(PageSpace* old_space, intptr_t size) {
ASSERT(Utils::IsAligned(size, kObjectAlignment));
uword address = old_space->TryAllocateDataBumpLocked(size);
if (address == 0) {
OUT_OF_MEMORY();
}
- return RawObject::FromAddr(address);
+ return ObjectLayout::FromAddr(address);
}
-void Deserializer::InitializeHeader(RawObject* raw,
+void Deserializer::InitializeHeader(ObjectPtr raw,
intptr_t class_id,
intptr_t size,
bool is_canonical) {
ASSERT(Utils::IsAligned(size, kObjectAlignment));
uint32_t tags = 0;
- tags = RawObject::ClassIdTag::update(class_id, tags);
- tags = RawObject::SizeTag::update(size, tags);
- tags = RawObject::CanonicalBit::update(is_canonical, tags);
- tags = RawObject::OldBit::update(true, tags);
- tags = RawObject::OldAndNotMarkedBit::update(true, tags);
- tags = RawObject::OldAndNotRememberedBit::update(true, tags);
- tags = RawObject::NewBit::update(false, tags);
+ tags = ObjectLayout::ClassIdTag::update(class_id, tags);
+ tags = ObjectLayout::SizeTag::update(size, tags);
+ tags = ObjectLayout::CanonicalBit::update(is_canonical, tags);
+ tags = ObjectLayout::OldBit::update(true, tags);
+ tags = ObjectLayout::OldAndNotMarkedBit::update(true, tags);
+ tags = ObjectLayout::OldAndNotRememberedBit::update(true, tags);
+ tags = ObjectLayout::NewBit::update(false, tags);
raw->ptr()->tags_ = tags;
#if defined(HASH_IN_OBJECT_HEADER)
raw->ptr()->hash_ = 0;
@@ -152,8 +152,8 @@
objects_(num_cids) {}
~ClassSerializationCluster() {}
- void Trace(Serializer* s, RawObject* object) {
- RawClass* cls = Class::RawCast(object);
+ void Trace(Serializer* s, ObjectPtr object) {
+ ClassPtr cls = Class::RawCast(object);
intptr_t class_id = cls->ptr()->id_;
// Classes expected to be dropped by the precompiler should not be traced.
@@ -175,7 +175,7 @@
intptr_t count = predefined_.length();
s->WriteUnsigned(count);
for (intptr_t i = 0; i < count; i++) {
- RawClass* cls = predefined_[i];
+ ClassPtr cls = predefined_[i];
s->AssignRef(cls);
AutoTraceObject(cls);
intptr_t class_id = cls->ptr()->id_;
@@ -184,7 +184,7 @@
count = objects_.length();
s->WriteUnsigned(count);
for (intptr_t i = 0; i < count; i++) {
- RawClass* cls = objects_[i];
+ ClassPtr cls = objects_[i];
s->AssignRef(cls);
}
}
@@ -200,7 +200,7 @@
}
}
- void WriteClass(Serializer* s, RawClass* cls) {
+ void WriteClass(Serializer* s, ClassPtr cls) {
AutoTraceObjectName(cls, cls->ptr()->name_);
WriteFromTo(cls);
intptr_t class_id = cls->ptr()->id_;
@@ -231,8 +231,8 @@
}
private:
- GrowableArray<RawClass*> predefined_;
- GrowableArray<RawClass*> objects_;
+ GrowableArray<ClassPtr> predefined_;
+ GrowableArray<ClassPtr> objects_;
UnboxedFieldBitmap CalculateTargetUnboxedFieldsBitmap(Serializer* s,
intptr_t class_id) {
@@ -267,7 +267,7 @@
return unboxed_fields_bitmap;
}
- bool RequireLegacyErasureOfConstants(RawClass* cls) {
+ bool RequireLegacyErasureOfConstants(ClassPtr cls) {
// Do not generate a core snapshot containing constants that would require
// a legacy erasure of their types if loaded in an isolate running in weak
// mode.
@@ -296,8 +296,8 @@
for (intptr_t i = 0; i < count; i++) {
intptr_t class_id = d->ReadCid();
ASSERT(table->HasValidClassAt(class_id));
- RawClass* cls = table->At(class_id);
- ASSERT(cls != NULL);
+ ClassPtr cls = table->At(class_id);
+ ASSERT(cls != nullptr);
d->AssignRef(cls);
}
predefined_stop_index_ = d->next_index();
@@ -315,7 +315,7 @@
for (intptr_t id = predefined_start_index_; id < predefined_stop_index_;
id++) {
- RawClass* cls = reinterpret_cast<RawClass*>(d->Ref(id));
+ ClassPtr cls = static_cast<ClassPtr>(d->Ref(id));
ReadFromTo(cls);
intptr_t class_id = d->ReadCid();
cls->ptr()->id_ = class_id;
@@ -358,7 +358,7 @@
auto shared_class_table = d->isolate()->group()->shared_class_table();
for (intptr_t id = start_index_; id < stop_index_; id++) {
- RawClass* cls = reinterpret_cast<RawClass*>(d->Ref(id));
+ ClassPtr cls = static_cast<ClassPtr>(d->Ref(id));
Deserializer::InitializeHeader(cls, kClassCid, Class::InstanceSize());
ReadFromTo(cls);
@@ -410,8 +410,8 @@
TypeArgumentsSerializationCluster() : SerializationCluster("TypeArguments") {}
~TypeArgumentsSerializationCluster() {}
- void Trace(Serializer* s, RawObject* object) {
- RawTypeArguments* type_args = TypeArguments::RawCast(object);
+ void Trace(Serializer* s, ObjectPtr object) {
+ TypeArgumentsPtr type_args = TypeArguments::RawCast(object);
objects_.Add(type_args);
s->Push(type_args->ptr()->instantiations_);
@@ -426,7 +426,7 @@
const intptr_t count = objects_.length();
s->WriteUnsigned(count);
for (intptr_t i = 0; i < count; i++) {
- RawTypeArguments* type_args = objects_[i];
+ TypeArgumentsPtr type_args = objects_[i];
s->AssignRef(type_args);
AutoTraceObject(type_args);
const intptr_t length = Smi::Value(type_args->ptr()->length_);
@@ -437,11 +437,11 @@
void WriteFill(Serializer* s) {
const intptr_t count = objects_.length();
for (intptr_t i = 0; i < count; i++) {
- RawTypeArguments* type_args = objects_[i];
+ TypeArgumentsPtr type_args = objects_[i];
AutoTraceObject(type_args);
const intptr_t length = Smi::Value(type_args->ptr()->length_);
s->WriteUnsigned(length);
- s->Write<bool>(type_args->IsCanonical());
+ s->Write<bool>(type_args->ptr()->IsCanonical());
intptr_t hash = Smi::Value(type_args->ptr()->hash_);
s->Write<int32_t>(hash);
const intptr_t nullability = Smi::Value(type_args->ptr()->nullability_);
@@ -454,7 +454,7 @@
}
private:
- GrowableArray<RawTypeArguments*> objects_;
+ GrowableArray<TypeArgumentsPtr> objects_;
};
#endif // !DART_PRECOMPILED_RUNTIME
@@ -477,8 +477,7 @@
void ReadFill(Deserializer* d) {
for (intptr_t id = start_index_; id < stop_index_; id++) {
- RawTypeArguments* type_args =
- reinterpret_cast<RawTypeArguments*>(d->Ref(id));
+ TypeArgumentsPtr type_args = static_cast<TypeArgumentsPtr>(d->Ref(id));
const intptr_t length = d->ReadUnsigned();
bool is_canonical = d->Read<bool>();
Deserializer::InitializeHeader(type_args, kTypeArgumentsCid,
@@ -487,11 +486,10 @@
type_args->ptr()->length_ = Smi::New(length);
type_args->ptr()->hash_ = Smi::New(d->Read<int32_t>());
type_args->ptr()->nullability_ = Smi::New(d->ReadUnsigned());
- type_args->ptr()->instantiations_ =
- reinterpret_cast<RawArray*>(d->ReadRef());
+ type_args->ptr()->instantiations_ = static_cast<ArrayPtr>(d->ReadRef());
for (intptr_t j = 0; j < length; j++) {
type_args->ptr()->types()[j] =
- reinterpret_cast<RawAbstractType*>(d->ReadRef());
+ static_cast<AbstractTypePtr>(d->ReadRef());
}
}
}
@@ -503,8 +501,8 @@
PatchClassSerializationCluster() : SerializationCluster("PatchClass") {}
~PatchClassSerializationCluster() {}
- void Trace(Serializer* s, RawObject* object) {
- RawPatchClass* cls = PatchClass::RawCast(object);
+ void Trace(Serializer* s, ObjectPtr object) {
+ PatchClassPtr cls = PatchClass::RawCast(object);
objects_.Add(cls);
PushFromTo(cls);
}
@@ -514,7 +512,7 @@
const intptr_t count = objects_.length();
s->WriteUnsigned(count);
for (intptr_t i = 0; i < count; i++) {
- RawPatchClass* cls = objects_[i];
+ PatchClassPtr cls = objects_[i];
s->AssignRef(cls);
}
}
@@ -522,7 +520,7 @@
void WriteFill(Serializer* s) {
const intptr_t count = objects_.length();
for (intptr_t i = 0; i < count; i++) {
- RawPatchClass* cls = objects_[i];
+ PatchClassPtr cls = objects_[i];
AutoTraceObject(cls);
WriteFromTo(cls);
if (s->kind() != Snapshot::kFullAOT) {
@@ -532,7 +530,7 @@
}
private:
- GrowableArray<RawPatchClass*> objects_;
+ GrowableArray<PatchClassPtr> objects_;
};
#endif // !DART_PRECOMPILED_RUNTIME
@@ -554,7 +552,7 @@
void ReadFill(Deserializer* d) {
for (intptr_t id = start_index_; id < stop_index_; id++) {
- RawPatchClass* cls = reinterpret_cast<RawPatchClass*>(d->Ref(id));
+ PatchClassPtr cls = static_cast<PatchClassPtr>(d->Ref(id));
Deserializer::InitializeHeader(cls, kPatchClassCid,
PatchClass::InstanceSize());
ReadFromTo(cls);
@@ -573,9 +571,9 @@
FunctionSerializationCluster() : SerializationCluster("Function") {}
~FunctionSerializationCluster() {}
- void Trace(Serializer* s, RawObject* object) {
+ void Trace(Serializer* s, ObjectPtr object) {
Snapshot::Kind kind = s->kind();
- RawFunction* func = Function::RawCast(object);
+ FunctionPtr func = Function::RawCast(object);
objects_.Add(func);
PushFromTo(func);
@@ -596,7 +594,7 @@
const intptr_t count = objects_.length();
s->WriteUnsigned(count);
for (intptr_t i = 0; i < count; i++) {
- RawFunction* func = objects_[i];
+ FunctionPtr func = objects_[i];
s->AssignRef(func);
}
}
@@ -605,7 +603,7 @@
Snapshot::Kind kind = s->kind();
const intptr_t count = objects_.length();
for (intptr_t i = 0; i < count; i++) {
- RawFunction* func = objects_[i];
+ FunctionPtr func = objects_[i];
AutoTraceObjectName(func, func->ptr()->name_);
WriteFromTo(func);
if (kind == Snapshot::kFull) {
@@ -631,7 +629,7 @@
}
private:
- GrowableArray<RawFunction*> objects_;
+ GrowableArray<FunctionPtr> objects_;
};
#endif // !DART_PRECOMPILED_RUNTIME
@@ -654,23 +652,23 @@
Snapshot::Kind kind = d->kind();
for (intptr_t id = start_index_; id < stop_index_; id++) {
- RawFunction* func = reinterpret_cast<RawFunction*>(d->Ref(id));
+ FunctionPtr func = static_cast<FunctionPtr>(d->Ref(id));
Deserializer::InitializeHeader(func, kFunctionCid,
Function::InstanceSize());
ReadFromTo(func);
if (kind == Snapshot::kFull) {
NOT_IN_PRECOMPILED(func->ptr()->bytecode_ =
- reinterpret_cast<RawBytecode*>(d->ReadRef()));
+ static_cast<BytecodePtr>(d->ReadRef()));
} else if (kind == Snapshot::kFullAOT) {
- func->ptr()->code_ = reinterpret_cast<RawCode*>(d->ReadRef());
+ func->ptr()->code_ = static_cast<CodePtr>(d->ReadRef());
} else if (kind == Snapshot::kFullJIT) {
NOT_IN_PRECOMPILED(func->ptr()->unoptimized_code_ =
- reinterpret_cast<RawCode*>(d->ReadRef()));
+ static_cast<CodePtr>(d->ReadRef()));
NOT_IN_PRECOMPILED(func->ptr()->bytecode_ =
- reinterpret_cast<RawBytecode*>(d->ReadRef()));
- func->ptr()->code_ = reinterpret_cast<RawCode*>(d->ReadRef());
- func->ptr()->ic_data_array_ = reinterpret_cast<RawArray*>(d->ReadRef());
+ static_cast<BytecodePtr>(d->ReadRef()));
+ func->ptr()->code_ = static_cast<CodePtr>(d->ReadRef());
+ func->ptr()->ic_data_array_ = static_cast<ArrayPtr>(d->ReadRef());
}
#if defined(DEBUG)
@@ -746,8 +744,8 @@
ClosureDataSerializationCluster() : SerializationCluster("ClosureData") {}
~ClosureDataSerializationCluster() {}
- void Trace(Serializer* s, RawObject* object) {
- RawClosureData* data = ClosureData::RawCast(object);
+ void Trace(Serializer* s, ObjectPtr object) {
+ ClosureDataPtr data = ClosureData::RawCast(object);
objects_.Add(data);
if (s->kind() != Snapshot::kFullAOT) {
@@ -763,7 +761,7 @@
const intptr_t count = objects_.length();
s->WriteUnsigned(count);
for (intptr_t i = 0; i < count; i++) {
- RawClosureData* data = objects_[i];
+ ClosureDataPtr data = objects_[i];
s->AssignRef(data);
}
}
@@ -771,7 +769,7 @@
void WriteFill(Serializer* s) {
const intptr_t count = objects_.length();
for (intptr_t i = 0; i < count; i++) {
- RawClosureData* data = objects_[i];
+ ClosureDataPtr data = objects_[i];
AutoTraceObject(data);
if (s->kind() != Snapshot::kFullAOT) {
WriteField(data, context_scope_);
@@ -783,7 +781,7 @@
}
private:
- GrowableArray<RawClosureData*> objects_;
+ GrowableArray<ClosureDataPtr> objects_;
};
#endif // !DART_PRECOMPILED_RUNTIME
@@ -805,18 +803,18 @@
void ReadFill(Deserializer* d) {
for (intptr_t id = start_index_; id < stop_index_; id++) {
- RawClosureData* data = reinterpret_cast<RawClosureData*>(d->Ref(id));
+ ClosureDataPtr data = static_cast<ClosureDataPtr>(d->Ref(id));
Deserializer::InitializeHeader(data, kClosureDataCid,
ClosureData::InstanceSize());
if (d->kind() == Snapshot::kFullAOT) {
data->ptr()->context_scope_ = ContextScope::null();
} else {
data->ptr()->context_scope_ =
- static_cast<RawContextScope*>(d->ReadRef());
+ static_cast<ContextScopePtr>(d->ReadRef());
}
- data->ptr()->parent_function_ = static_cast<RawFunction*>(d->ReadRef());
- data->ptr()->signature_type_ = static_cast<RawType*>(d->ReadRef());
- data->ptr()->closure_ = static_cast<RawInstance*>(d->ReadRef());
+ data->ptr()->parent_function_ = static_cast<FunctionPtr>(d->ReadRef());
+ data->ptr()->signature_type_ = static_cast<TypePtr>(d->ReadRef());
+ data->ptr()->closure_ = static_cast<InstancePtr>(d->ReadRef());
}
}
};
@@ -827,8 +825,8 @@
SignatureDataSerializationCluster() : SerializationCluster("SignatureData") {}
~SignatureDataSerializationCluster() {}
- void Trace(Serializer* s, RawObject* object) {
- RawSignatureData* data = SignatureData::RawCast(object);
+ void Trace(Serializer* s, ObjectPtr object) {
+ SignatureDataPtr data = SignatureData::RawCast(object);
objects_.Add(data);
PushFromTo(data);
}
@@ -838,7 +836,7 @@
const intptr_t count = objects_.length();
s->WriteUnsigned(count);
for (intptr_t i = 0; i < count; i++) {
- RawSignatureData* data = objects_[i];
+ SignatureDataPtr data = objects_[i];
s->AssignRef(data);
}
}
@@ -846,14 +844,14 @@
void WriteFill(Serializer* s) {
const intptr_t count = objects_.length();
for (intptr_t i = 0; i < count; i++) {
- RawSignatureData* data = objects_[i];
+ SignatureDataPtr data = objects_[i];
AutoTraceObject(data);
WriteFromTo(data);
}
}
private:
- GrowableArray<RawSignatureData*> objects_;
+ GrowableArray<SignatureDataPtr> objects_;
};
#endif // !DART_PRECOMPILED_RUNTIME
@@ -875,7 +873,7 @@
void ReadFill(Deserializer* d) {
for (intptr_t id = start_index_; id < stop_index_; id++) {
- RawSignatureData* data = reinterpret_cast<RawSignatureData*>(d->Ref(id));
+ SignatureDataPtr data = static_cast<SignatureDataPtr>(d->Ref(id));
Deserializer::InitializeHeader(data, kSignatureDataCid,
SignatureData::InstanceSize());
ReadFromTo(data);
@@ -890,8 +888,8 @@
: SerializationCluster("FfiTrampolineData") {}
~FfiTrampolineDataSerializationCluster() {}
- void Trace(Serializer* s, RawObject* object) {
- RawFfiTrampolineData* data = FfiTrampolineData::RawCast(object);
+ void Trace(Serializer* s, ObjectPtr object) {
+ FfiTrampolineDataPtr data = FfiTrampolineData::RawCast(object);
objects_.Add(data);
PushFromTo(data);
}
@@ -908,7 +906,7 @@
void WriteFill(Serializer* s) {
const intptr_t count = objects_.length();
for (intptr_t i = 0; i < count; i++) {
- RawFfiTrampolineData* const data = objects_[i];
+ FfiTrampolineDataPtr const data = objects_[i];
AutoTraceObject(data);
WriteFromTo(data);
@@ -922,7 +920,7 @@
}
private:
- GrowableArray<RawFfiTrampolineData*> objects_;
+ GrowableArray<FfiTrampolineDataPtr> objects_;
};
#endif // !DART_PRECOMPILED_RUNTIME
@@ -944,8 +942,7 @@
void ReadFill(Deserializer* d) {
for (intptr_t id = start_index_; id < stop_index_; id++) {
- RawFfiTrampolineData* data =
- reinterpret_cast<RawFfiTrampolineData*>(d->Ref(id));
+ FfiTrampolineDataPtr data = static_cast<FfiTrampolineDataPtr>(d->Ref(id));
Deserializer::InitializeHeader(data, kFfiTrampolineDataCid,
FfiTrampolineData::InstanceSize());
ReadFromTo(data);
@@ -962,8 +959,8 @@
: SerializationCluster("RedirectionData") {}
~RedirectionDataSerializationCluster() {}
- void Trace(Serializer* s, RawObject* object) {
- RawRedirectionData* data = RedirectionData::RawCast(object);
+ void Trace(Serializer* s, ObjectPtr object) {
+ RedirectionDataPtr data = RedirectionData::RawCast(object);
objects_.Add(data);
PushFromTo(data);
}
@@ -973,7 +970,7 @@
const intptr_t count = objects_.length();
s->WriteUnsigned(count);
for (intptr_t i = 0; i < count; i++) {
- RawRedirectionData* data = objects_[i];
+ RedirectionDataPtr data = objects_[i];
s->AssignRef(data);
}
}
@@ -981,14 +978,14 @@
void WriteFill(Serializer* s) {
const intptr_t count = objects_.length();
for (intptr_t i = 0; i < count; i++) {
- RawRedirectionData* data = objects_[i];
+ RedirectionDataPtr data = objects_[i];
AutoTraceObject(data);
WriteFromTo(data);
}
}
private:
- GrowableArray<RawRedirectionData*> objects_;
+ GrowableArray<RedirectionDataPtr> objects_;
};
#endif // !DART_PRECOMPILED_RUNTIME
@@ -1010,8 +1007,7 @@
void ReadFill(Deserializer* d) {
for (intptr_t id = start_index_; id < stop_index_; id++) {
- RawRedirectionData* data =
- reinterpret_cast<RawRedirectionData*>(d->Ref(id));
+ RedirectionDataPtr data = static_cast<RedirectionDataPtr>(d->Ref(id));
Deserializer::InitializeHeader(data, kRedirectionDataCid,
RedirectionData::InstanceSize());
ReadFromTo(data);
@@ -1025,8 +1021,8 @@
FieldSerializationCluster() : SerializationCluster("Field") {}
~FieldSerializationCluster() {}
- void Trace(Serializer* s, RawObject* object) {
- RawField* field = Field::RawCast(object);
+ void Trace(Serializer* s, ObjectPtr object) {
+ FieldPtr field = Field::RawCast(object);
objects_.Add(field);
Snapshot::Kind kind = s->kind();
@@ -1071,7 +1067,7 @@
const intptr_t count = objects_.length();
s->WriteUnsigned(count);
for (intptr_t i = 0; i < count; i++) {
- RawField* field = objects_[i];
+ FieldPtr field = objects_[i];
s->AssignRef(field);
}
}
@@ -1080,7 +1076,7 @@
Snapshot::Kind kind = s->kind();
const intptr_t count = objects_.length();
for (intptr_t i = 0; i < count; i++) {
- RawField* field = objects_[i];
+ FieldPtr field = objects_[i];
AutoTraceObjectName(field, field->ptr()->name_);
WriteField(field, name_);
@@ -1135,7 +1131,7 @@
}
private:
- GrowableArray<RawField*> objects_;
+ GrowableArray<FieldPtr> objects_;
};
#endif // !DART_PRECOMPILED_RUNTIME
@@ -1158,7 +1154,7 @@
Snapshot::Kind kind = d->kind();
for (intptr_t id = start_index_; id < stop_index_; id++) {
- RawField* field = reinterpret_cast<RawField*>(d->Ref(id));
+ FieldPtr field = static_cast<FieldPtr>(d->Ref(id));
Deserializer::InitializeHeader(field, kFieldCid, Field::InstanceSize());
ReadFromTo(field);
if (kind != Snapshot::kFullAOT) {
@@ -1173,11 +1169,11 @@
}
field->ptr()->kind_bits_ = d->Read<uint16_t>();
- RawObject* value_or_offset = d->ReadRef();
+ ObjectPtr value_or_offset = d->ReadRef();
if (Field::StaticBit::decode(field->ptr()->kind_bits_)) {
intptr_t field_id = d->ReadUnsigned();
- d->field_table()->SetAt(
- field_id, reinterpret_cast<RawInstance*>(value_or_offset));
+ d->field_table()->SetAt(field_id,
+ static_cast<InstancePtr>(value_or_offset));
field->ptr()->host_offset_or_field_id_ = field_id;
} else {
field->ptr()->host_offset_or_field_id_ =
@@ -1221,8 +1217,8 @@
ScriptSerializationCluster() : SerializationCluster("Script") {}
~ScriptSerializationCluster() {}
- void Trace(Serializer* s, RawObject* object) {
- RawScript* script = Script::RawCast(object);
+ void Trace(Serializer* s, ObjectPtr object) {
+ ScriptPtr script = Script::RawCast(object);
objects_.Add(script);
PushFromTo(script);
}
@@ -1232,7 +1228,7 @@
const intptr_t count = objects_.length();
s->WriteUnsigned(count);
for (intptr_t i = 0; i < count; i++) {
- RawScript* script = objects_[i];
+ ScriptPtr script = objects_[i];
s->AssignRef(script);
}
}
@@ -1240,7 +1236,7 @@
void WriteFill(Serializer* s) {
const intptr_t count = objects_.length();
for (intptr_t i = 0; i < count; i++) {
- RawScript* script = objects_[i];
+ ScriptPtr script = objects_[i];
AutoTraceObjectName(script, script->ptr()->url_);
WriteFromTo(script);
s->Write<int32_t>(script->ptr()->line_offset_);
@@ -1251,7 +1247,7 @@
}
private:
- GrowableArray<RawScript*> objects_;
+ GrowableArray<ScriptPtr> objects_;
};
#endif // !DART_PRECOMPILED_RUNTIME
@@ -1272,7 +1268,7 @@
void ReadFill(Deserializer* d) {
for (intptr_t id = start_index_; id < stop_index_; id++) {
- RawScript* script = reinterpret_cast<RawScript*>(d->Ref(id));
+ ScriptPtr script = static_cast<ScriptPtr>(d->Ref(id));
Deserializer::InitializeHeader(script, kScriptCid,
Script::InstanceSize());
ReadFromTo(script);
@@ -1291,8 +1287,8 @@
LibrarySerializationCluster() : SerializationCluster("Library") {}
~LibrarySerializationCluster() {}
- void Trace(Serializer* s, RawObject* object) {
- RawLibrary* lib = Library::RawCast(object);
+ void Trace(Serializer* s, ObjectPtr object) {
+ LibraryPtr lib = Library::RawCast(object);
objects_.Add(lib);
PushFromTo(lib);
}
@@ -1302,7 +1298,7 @@
const intptr_t count = objects_.length();
s->WriteUnsigned(count);
for (intptr_t i = 0; i < count; i++) {
- RawLibrary* lib = objects_[i];
+ LibraryPtr lib = objects_[i];
s->AssignRef(lib);
}
}
@@ -1310,7 +1306,7 @@
void WriteFill(Serializer* s) {
const intptr_t count = objects_.length();
for (intptr_t i = 0; i < count; i++) {
- RawLibrary* lib = objects_[i];
+ LibraryPtr lib = objects_[i];
AutoTraceObjectName(lib, lib->ptr()->url_);
WriteFromTo(lib);
s->Write<int32_t>(lib->ptr()->index_);
@@ -1324,7 +1320,7 @@
}
private:
- GrowableArray<RawLibrary*> objects_;
+ GrowableArray<LibraryPtr> objects_;
};
#endif // !DART_PRECOMPILED_RUNTIME
@@ -1345,7 +1341,7 @@
void ReadFill(Deserializer* d) {
for (intptr_t id = start_index_; id < stop_index_; id++) {
- RawLibrary* lib = reinterpret_cast<RawLibrary*>(d->Ref(id));
+ LibraryPtr lib = static_cast<LibraryPtr>(d->Ref(id));
Deserializer::InitializeHeader(lib, kLibraryCid, Library::InstanceSize());
ReadFromTo(lib);
lib->ptr()->native_entry_resolver_ = NULL;
@@ -1354,7 +1350,7 @@
lib->ptr()->num_imports_ = d->Read<uint16_t>();
lib->ptr()->load_state_ = d->Read<int8_t>();
lib->ptr()->flags_ =
- RawLibrary::InFullSnapshotBit::update(true, d->Read<uint8_t>());
+ LibraryLayout::InFullSnapshotBit::update(true, d->Read<uint8_t>());
#if !defined(DART_PRECOMPILED_RUNTIME)
if (d->kind() != Snapshot::kFullAOT) {
lib->ptr()->binary_declaration_ = d->Read<uint32_t>();
@@ -1370,8 +1366,8 @@
NamespaceSerializationCluster() : SerializationCluster("Namespace") {}
~NamespaceSerializationCluster() {}
- void Trace(Serializer* s, RawObject* object) {
- RawNamespace* ns = Namespace::RawCast(object);
+ void Trace(Serializer* s, ObjectPtr object) {
+ NamespacePtr ns = Namespace::RawCast(object);
objects_.Add(ns);
PushFromTo(ns);
}
@@ -1381,7 +1377,7 @@
const intptr_t count = objects_.length();
s->WriteUnsigned(count);
for (intptr_t i = 0; i < count; i++) {
- RawNamespace* ns = objects_[i];
+ NamespacePtr ns = objects_[i];
s->AssignRef(ns);
}
}
@@ -1389,14 +1385,14 @@
void WriteFill(Serializer* s) {
const intptr_t count = objects_.length();
for (intptr_t i = 0; i < count; i++) {
- RawNamespace* ns = objects_[i];
+ NamespacePtr ns = objects_[i];
AutoTraceObject(ns);
WriteFromTo(ns);
}
}
private:
- GrowableArray<RawNamespace*> objects_;
+ GrowableArray<NamespacePtr> objects_;
};
#endif // !DART_PRECOMPILED_RUNTIME
@@ -1417,7 +1413,7 @@
void ReadFill(Deserializer* d) {
for (intptr_t id = start_index_; id < stop_index_; id++) {
- RawNamespace* ns = reinterpret_cast<RawNamespace*>(d->Ref(id));
+ NamespacePtr ns = static_cast<NamespacePtr>(d->Ref(id));
Deserializer::InitializeHeader(ns, kNamespaceCid,
Namespace::InstanceSize());
ReadFromTo(ns);
@@ -1433,8 +1429,8 @@
: SerializationCluster("KernelProgramInfo") {}
~KernelProgramInfoSerializationCluster() {}
- void Trace(Serializer* s, RawObject* object) {
- RawKernelProgramInfo* info = KernelProgramInfo::RawCast(object);
+ void Trace(Serializer* s, ObjectPtr object) {
+ KernelProgramInfoPtr info = KernelProgramInfo::RawCast(object);
objects_.Add(info);
PushFromTo(info);
}
@@ -1444,7 +1440,7 @@
const intptr_t count = objects_.length();
s->WriteUnsigned(count);
for (intptr_t i = 0; i < count; i++) {
- RawKernelProgramInfo* info = objects_[i];
+ KernelProgramInfoPtr info = objects_[i];
s->AssignRef(info);
}
}
@@ -1452,7 +1448,7 @@
void WriteFill(Serializer* s) {
const intptr_t count = objects_.length();
for (intptr_t i = 0; i < count; i++) {
- RawKernelProgramInfo* info = objects_[i];
+ KernelProgramInfoPtr info = objects_[i];
AutoTraceObject(info);
WriteFromTo(info);
s->Write<uint32_t>(info->ptr()->kernel_binary_version_);
@@ -1460,7 +1456,7 @@
}
private:
- GrowableArray<RawKernelProgramInfo*> objects_;
+ GrowableArray<KernelProgramInfoPtr> objects_;
};
// Since KernelProgramInfo objects are not written into full AOT snapshots,
@@ -1483,8 +1479,7 @@
void ReadFill(Deserializer* d) {
for (intptr_t id = start_index_; id < stop_index_; id++) {
- RawKernelProgramInfo* info =
- reinterpret_cast<RawKernelProgramInfo*>(d->Ref(id));
+ KernelProgramInfoPtr info = static_cast<KernelProgramInfoPtr>(d->Ref(id));
Deserializer::InitializeHeader(info, kKernelProgramInfoCid,
KernelProgramInfo::InstanceSize());
ReadFromTo(info);
@@ -1510,8 +1505,8 @@
CodeSerializationCluster() : SerializationCluster("Code") {}
~CodeSerializationCluster() {}
- void Trace(Serializer* s, RawObject* object) {
- RawCode* code = Code::RawCast(object);
+ void Trace(Serializer* s, ObjectPtr object) {
+ CodePtr code = Code::RawCast(object);
objects_.Add(code);
if (!(s->kind() == Snapshot::kFullAOT && FLAG_use_bare_instructions)) {
@@ -1560,7 +1555,7 @@
const intptr_t count = objects_.length();
s->WriteUnsigned(count);
for (intptr_t i = 0; i < count; i++) {
- RawCode* code = objects_[i];
+ CodePtr code = objects_[i];
s->AssignRef(code);
}
}
@@ -1569,7 +1564,7 @@
Snapshot::Kind kind = s->kind();
const intptr_t count = objects_.length();
for (intptr_t i = 0; i < count; i++) {
- RawCode* code = objects_[i];
+ CodePtr code = objects_[i];
AutoTraceObject(code);
intptr_t pointer_offsets_length =
@@ -1603,7 +1598,7 @@
code->ptr()->object_pool_ != ObjectPool::null()) {
// If we are writing V8 snapshot profile then attribute references
// going through the object pool to the code object itself.
- RawObjectPool* pool = code->ptr()->object_pool_;
+ ObjectPoolPtr pool = code->ptr()->object_pool_;
for (intptr_t i = 0; i < pool->ptr()->length_; i++) {
uint8_t bits = pool->ptr()->entry_bits()[i];
@@ -1640,10 +1635,10 @@
}
}
- GrowableArray<RawCode*>* discovered_objects() { return &objects_; }
+ GrowableArray<CodePtr>* discovered_objects() { return &objects_; }
private:
- GrowableArray<RawCode*> objects_;
+ GrowableArray<CodePtr> objects_;
};
#endif // !DART_PRECOMPILED_RUNTIME
@@ -1661,10 +1656,10 @@
// [Code]'s instructions will be located in memory.
const bool build_code_order =
FLAG_precompiled_mode && FLAG_use_bare_instructions;
- RawArray* code_order = nullptr;
+ ArrayPtr code_order = nullptr;
const intptr_t code_order_length = d->code_order_length();
if (build_code_order) {
- code_order = static_cast<RawArray*>(AllocateUninitialized(
+ code_order = static_cast<ArrayPtr>(AllocateUninitialized(
old_space, Array::InstanceSize(code_order_length)));
Deserializer::InitializeHeader(code_order, kArrayCid,
Array::InstanceSize(code_order_length),
@@ -1691,7 +1686,7 @@
void ReadFill(Deserializer* d) {
for (intptr_t id = start_index_; id < stop_index_; id++) {
- auto const code = reinterpret_cast<RawCode*>(d->Ref(id));
+ auto const code = static_cast<CodePtr>(d->Ref(id));
Deserializer::InitializeHeader(code, kCodeCid, Code::InstanceSize(0));
d->ReadInstructions(code, id, start_index_);
@@ -1699,30 +1694,28 @@
// There would be a single global pool if this is a full AOT snapshot
// with bare instructions.
if (!(d->kind() == Snapshot::kFullAOT && FLAG_use_bare_instructions)) {
- code->ptr()->object_pool_ =
- reinterpret_cast<RawObjectPool*>(d->ReadRef());
+ code->ptr()->object_pool_ = static_cast<ObjectPoolPtr>(d->ReadRef());
} else {
code->ptr()->object_pool_ = ObjectPool::null();
}
code->ptr()->owner_ = d->ReadRef();
code->ptr()->exception_handlers_ =
- reinterpret_cast<RawExceptionHandlers*>(d->ReadRef());
+ static_cast<ExceptionHandlersPtr>(d->ReadRef());
code->ptr()->pc_descriptors_ =
- reinterpret_cast<RawPcDescriptors*>(d->ReadRef());
+ static_cast<PcDescriptorsPtr>(d->ReadRef());
code->ptr()->catch_entry_ = d->ReadRef();
code->ptr()->compressed_stackmaps_ =
- reinterpret_cast<RawCompressedStackMaps*>(d->ReadRef());
+ static_cast<CompressedStackMapsPtr>(d->ReadRef());
code->ptr()->inlined_id_to_function_ =
- reinterpret_cast<RawArray*>(d->ReadRef());
+ static_cast<ArrayPtr>(d->ReadRef());
code->ptr()->code_source_map_ =
- reinterpret_cast<RawCodeSourceMap*>(d->ReadRef());
+ static_cast<CodeSourceMapPtr>(d->ReadRef());
#if !defined(DART_PRECOMPILED_RUNTIME)
if (d->kind() == Snapshot::kFullJIT) {
- code->ptr()->deopt_info_array_ =
- reinterpret_cast<RawArray*>(d->ReadRef());
+ code->ptr()->deopt_info_array_ = static_cast<ArrayPtr>(d->ReadRef());
code->ptr()->static_calls_target_table_ =
- reinterpret_cast<RawArray*>(d->ReadRef());
+ static_cast<ArrayPtr>(d->ReadRef());
}
#endif // !DART_PRECOMPILED_RUNTIME
@@ -1730,7 +1723,7 @@
code->ptr()->return_address_metadata_ = d->ReadRef();
code->ptr()->var_descriptors_ = LocalVarDescriptors::null();
code->ptr()->comments_ = FLAG_code_comments
- ? reinterpret_cast<RawArray*>(d->ReadRef())
+ ? static_cast<ArrayPtr>(d->ReadRef())
: Array::null();
code->ptr()->compile_timestamp_ = 0;
#endif
@@ -1775,8 +1768,8 @@
BytecodeSerializationCluster() : SerializationCluster("Bytecode") {}
virtual ~BytecodeSerializationCluster() {}
- void Trace(Serializer* s, RawObject* object) {
- RawBytecode* bytecode = Bytecode::RawCast(object);
+ void Trace(Serializer* s, ObjectPtr object) {
+ BytecodePtr bytecode = Bytecode::RawCast(object);
objects_.Add(bytecode);
PushFromTo(bytecode);
}
@@ -1786,7 +1779,7 @@
const intptr_t count = objects_.length();
s->WriteUnsigned(count);
for (intptr_t i = 0; i < count; i++) {
- RawBytecode* bytecode = objects_[i];
+ BytecodePtr bytecode = objects_[i];
s->AssignRef(bytecode);
}
}
@@ -1795,7 +1788,7 @@
ASSERT(s->kind() != Snapshot::kFullAOT);
const intptr_t count = objects_.length();
for (intptr_t i = 0; i < count; i++) {
- RawBytecode* bytecode = objects_[i];
+ BytecodePtr bytecode = objects_[i];
s->Write<int32_t>(bytecode->ptr()->instructions_size_);
WriteFromTo(bytecode);
s->Write<int32_t>(bytecode->ptr()->instructions_binary_offset_);
@@ -1805,7 +1798,7 @@
}
private:
- GrowableArray<RawBytecode*> objects_;
+ GrowableArray<BytecodePtr> objects_;
};
class BytecodeDeserializationCluster : public DeserializationCluster {
@@ -1827,7 +1820,7 @@
ASSERT(d->kind() != Snapshot::kFullAOT);
for (intptr_t id = start_index_; id < stop_index_; id++) {
- RawBytecode* bytecode = reinterpret_cast<RawBytecode*>(d->Ref(id));
+ BytecodePtr bytecode = static_cast<BytecodePtr>(d->Ref(id));
Deserializer::InitializeHeader(bytecode, kBytecodeCid,
Bytecode::InstanceSize());
bytecode->ptr()->instructions_ = 0;
@@ -1857,8 +1850,8 @@
ObjectPoolSerializationCluster() : SerializationCluster("ObjectPool") {}
~ObjectPoolSerializationCluster() {}
- void Trace(Serializer* s, RawObject* object) {
- RawObjectPool* pool = ObjectPool::RawCast(object);
+ void Trace(Serializer* s, ObjectPtr object) {
+ ObjectPoolPtr pool = ObjectPool::RawCast(object);
objects_.Add(pool);
const intptr_t length = pool->ptr()->length_;
@@ -1877,7 +1870,7 @@
const intptr_t count = objects_.length();
s->WriteUnsigned(count);
for (intptr_t i = 0; i < count; i++) {
- RawObjectPool* pool = objects_[i];
+ ObjectPoolPtr pool = objects_[i];
s->AssignRef(pool);
AutoTraceObject(pool);
const intptr_t length = pool->ptr()->length_;
@@ -1888,14 +1881,14 @@
void WriteFill(Serializer* s) {
const intptr_t count = objects_.length();
for (intptr_t i = 0; i < count; i++) {
- RawObjectPool* pool = objects_[i];
+ ObjectPoolPtr pool = objects_[i];
AutoTraceObject(pool);
const intptr_t length = pool->ptr()->length_;
s->WriteUnsigned(length);
uint8_t* entry_bits = pool->ptr()->entry_bits();
for (intptr_t j = 0; j < length; j++) {
s->Write<uint8_t>(entry_bits[j]);
- RawObjectPool::Entry& entry = pool->ptr()->data()[j];
+ ObjectPoolLayout::Entry& entry = pool->ptr()->data()[j];
switch (ObjectPool::TypeBits::decode(entry_bits[j])) {
case ObjectPool::EntryType::kTaggedObject: {
if ((entry.raw_obj_ == StubCode::CallNoScopeNative().raw()) ||
@@ -1914,8 +1907,8 @@
break;
}
case ObjectPool::EntryType::kNativeEntryData: {
- RawObject* raw = entry.raw_obj_;
- RawTypedData* raw_data = reinterpret_cast<RawTypedData*>(raw);
+ ObjectPtr raw = entry.raw_obj_;
+ TypedDataPtr raw_data = static_cast<TypedDataPtr>(raw);
// kNativeEntryData object pool entries are for linking natives for
// the interpreter. Before writing these entries into the snapshot,
// we need to unlink them by nulling out the 'trampoline' and
@@ -1942,7 +1935,7 @@
}
private:
- GrowableArray<RawObjectPool*> objects_;
+ GrowableArray<ObjectPoolPtr> objects_;
};
#endif // !DART_PRECOMPILED_RUNTIME
@@ -1966,14 +1959,14 @@
void ReadFill(Deserializer* d) {
for (intptr_t id = start_index_; id < stop_index_; id += 1) {
const intptr_t length = d->ReadUnsigned();
- RawObjectPool* pool = reinterpret_cast<RawObjectPool*>(d->Ref(id + 0));
+ ObjectPoolPtr pool = static_cast<ObjectPoolPtr>(d->Ref(id + 0));
Deserializer::InitializeHeader(pool, kObjectPoolCid,
ObjectPool::InstanceSize(length));
pool->ptr()->length_ = length;
for (intptr_t j = 0; j < length; j++) {
const uint8_t entry_bits = d->Read<uint8_t>();
pool->ptr()->entry_bits()[j] = entry_bits;
- RawObjectPool::Entry& entry = pool->ptr()->data()[j];
+ ObjectPoolLayout::Entry& entry = pool->ptr()->data()[j];
switch (ObjectPool::TypeBits::decode(entry_bits)) {
case ObjectPool::EntryType::kNativeEntryData:
case ObjectPool::EntryType::kTaggedObject:
@@ -2008,7 +2001,7 @@
canonical_wsr_map_(zone) {}
~WeakSerializationReferenceSerializationCluster() {}
- void Trace(Serializer* s, RawObject* object) {
+ void Trace(Serializer* s, ObjectPtr object) {
ASSERT(s->kind() == Snapshot::kFullAOT);
// Make sure we don't trace again after choosing canonical WSRs.
ASSERT(!have_canonicalized_wsrs_);
@@ -2095,14 +2088,14 @@
// Returns whether a WSR should be dropped due to its target being reachable
// via strong references. WSRs only wrap heap objects, so we can just retrieve
// the object ID from the heap directly.
- bool ShouldDrop(RawWeakSerializationReference* ref) const {
+ bool ShouldDrop(WeakSerializationReferencePtr ref) const {
auto const target = WeakSerializationReference::TargetOf(ref);
return Serializer::IsReachableReference(heap_->GetObjectId(target));
}
Heap* const heap_;
- GrowableArray<RawWeakSerializationReference*> objects_;
- GrowableArray<RawWeakSerializationReference*> canonical_wsrs_;
+ GrowableArray<WeakSerializationReferencePtr> objects_;
+ GrowableArray<WeakSerializationReferencePtr> canonical_wsrs_;
IntMap<intptr_t> canonical_wsr_map_;
bool have_canonicalized_wsrs_ = false;
};
@@ -2131,8 +2124,7 @@
void ReadFill(Deserializer* d) {
for (intptr_t id = start_index_; id < stop_index_; id++) {
- auto const ref =
- reinterpret_cast<RawWeakSerializationReference*>(d->Ref(id));
+ auto const ref = static_cast<WeakSerializationReferencePtr>(d->Ref(id));
Deserializer::InitializeHeader(
ref, kWeakSerializationReferenceCid,
WeakSerializationReference::InstanceSize());
@@ -2148,8 +2140,8 @@
PcDescriptorsSerializationCluster() : SerializationCluster("PcDescriptors") {}
~PcDescriptorsSerializationCluster() {}
- void Trace(Serializer* s, RawObject* object) {
- RawPcDescriptors* desc = PcDescriptors::RawCast(object);
+ void Trace(Serializer* s, ObjectPtr object) {
+ PcDescriptorsPtr desc = PcDescriptors::RawCast(object);
objects_.Add(desc);
}
@@ -2158,7 +2150,7 @@
const intptr_t count = objects_.length();
s->WriteUnsigned(count);
for (intptr_t i = 0; i < count; i++) {
- RawPcDescriptors* desc = objects_[i];
+ PcDescriptorsPtr desc = objects_[i];
s->AssignRef(desc);
AutoTraceObject(desc);
const intptr_t length = desc->ptr()->length_;
@@ -2169,7 +2161,7 @@
void WriteFill(Serializer* s) {
const intptr_t count = objects_.length();
for (intptr_t i = 0; i < count; i++) {
- RawPcDescriptors* desc = objects_[i];
+ PcDescriptorsPtr desc = objects_[i];
AutoTraceObject(desc);
const intptr_t length = desc->ptr()->length_;
s->WriteUnsigned(length);
@@ -2179,7 +2171,7 @@
}
private:
- GrowableArray<RawPcDescriptors*> objects_;
+ GrowableArray<PcDescriptorsPtr> objects_;
};
#endif // !DART_PRECOMPILED_RUNTIME
@@ -2203,7 +2195,7 @@
void ReadFill(Deserializer* d) {
for (intptr_t id = start_index_; id < stop_index_; id += 1) {
const intptr_t length = d->ReadUnsigned();
- RawPcDescriptors* desc = reinterpret_cast<RawPcDescriptors*>(d->Ref(id));
+ PcDescriptorsPtr desc = static_cast<PcDescriptorsPtr>(d->Ref(id));
Deserializer::InitializeHeader(desc, kPcDescriptorsCid,
PcDescriptors::InstanceSize(length));
desc->ptr()->length_ = length;
@@ -2224,12 +2216,12 @@
type_(type) {}
~RODataSerializationCluster() {}
- void Trace(Serializer* s, RawObject* object) {
+ void Trace(Serializer* s, ObjectPtr object) {
// A string's hash must already be computed when we write it because it
// will be loaded into read-only memory. Extra bytes due to allocation
// rounding need to be deterministically set for reliable deduplication in
// shared images.
- if (object->InVMIsolateHeap() ||
+ if (object->ptr()->InVMIsolateHeap() ||
s->isolate()->heap()->old_space()->IsObjectFromImagePages(object)) {
// This object is already read-only.
} else {
@@ -2246,7 +2238,7 @@
s->WriteUnsigned(count);
uint32_t running_offset = 0;
for (intptr_t i = 0; i < count; i++) {
- RawObject* object = objects_[i];
+ ObjectPtr object = objects_[i];
s->AssignRef(object);
if (cid_ == kOneByteStringCid || cid_ == kTwoByteStringCid) {
s->TraceStartWritingObject(type_, object, String::RawCast(object));
@@ -2271,7 +2263,7 @@
private:
const intptr_t cid_;
- GrowableArray<RawObject*> objects_;
+ GrowableArray<ObjectPtr> objects_;
const char* const type_;
};
#endif // !DART_PRECOMPILED_RUNTIME
@@ -2302,8 +2294,8 @@
: SerializationCluster("ExceptionHandlers") {}
~ExceptionHandlersSerializationCluster() {}
- void Trace(Serializer* s, RawObject* object) {
- RawExceptionHandlers* handlers = ExceptionHandlers::RawCast(object);
+ void Trace(Serializer* s, ObjectPtr object) {
+ ExceptionHandlersPtr handlers = ExceptionHandlers::RawCast(object);
objects_.Add(handlers);
s->Push(handlers->ptr()->handled_types_data_);
@@ -2314,7 +2306,7 @@
const intptr_t count = objects_.length();
s->WriteUnsigned(count);
for (intptr_t i = 0; i < count; i++) {
- RawExceptionHandlers* handlers = objects_[i];
+ ExceptionHandlersPtr handlers = objects_[i];
s->AssignRef(handlers);
AutoTraceObject(handlers);
const intptr_t length = handlers->ptr()->num_entries_;
@@ -2325,7 +2317,7 @@
void WriteFill(Serializer* s) {
const intptr_t count = objects_.length();
for (intptr_t i = 0; i < count; i++) {
- RawExceptionHandlers* handlers = objects_[i];
+ ExceptionHandlersPtr handlers = objects_[i];
AutoTraceObject(handlers);
const intptr_t length = handlers->ptr()->num_entries_;
s->WriteUnsigned(length);
@@ -2342,7 +2334,7 @@
}
private:
- GrowableArray<RawExceptionHandlers*> objects_;
+ GrowableArray<ExceptionHandlersPtr> objects_;
};
#endif // !DART_PRECOMPILED_RUNTIME
@@ -2365,14 +2357,14 @@
void ReadFill(Deserializer* d) {
for (intptr_t id = start_index_; id < stop_index_; id++) {
- RawExceptionHandlers* handlers =
- reinterpret_cast<RawExceptionHandlers*>(d->Ref(id));
+ ExceptionHandlersPtr handlers =
+ static_cast<ExceptionHandlersPtr>(d->Ref(id));
const intptr_t length = d->ReadUnsigned();
Deserializer::InitializeHeader(handlers, kExceptionHandlersCid,
ExceptionHandlers::InstanceSize(length));
handlers->ptr()->num_entries_ = length;
handlers->ptr()->handled_types_data_ =
- reinterpret_cast<RawArray*>(d->ReadRef());
+ static_cast<ArrayPtr>(d->ReadRef());
for (intptr_t j = 0; j < length; j++) {
ExceptionHandlerInfo& info = handlers->ptr()->data()[j];
info.handler_pc_offset = d->Read<uint32_t>();
@@ -2391,8 +2383,8 @@
ContextSerializationCluster() : SerializationCluster("Context") {}
~ContextSerializationCluster() {}
- void Trace(Serializer* s, RawObject* object) {
- RawContext* context = Context::RawCast(object);
+ void Trace(Serializer* s, ObjectPtr object) {
+ ContextPtr context = Context::RawCast(object);
objects_.Add(context);
s->Push(context->ptr()->parent_);
@@ -2407,7 +2399,7 @@
const intptr_t count = objects_.length();
s->WriteUnsigned(count);
for (intptr_t i = 0; i < count; i++) {
- RawContext* context = objects_[i];
+ ContextPtr context = objects_[i];
s->AssignRef(context);
AutoTraceObject(context);
const intptr_t length = context->ptr()->num_variables_;
@@ -2418,7 +2410,7 @@
void WriteFill(Serializer* s) {
const intptr_t count = objects_.length();
for (intptr_t i = 0; i < count; i++) {
- RawContext* context = objects_[i];
+ ContextPtr context = objects_[i];
AutoTraceObject(context);
const intptr_t length = context->ptr()->num_variables_;
s->WriteUnsigned(length);
@@ -2430,7 +2422,7 @@
}
private:
- GrowableArray<RawContext*> objects_;
+ GrowableArray<ContextPtr> objects_;
};
#endif // !DART_PRECOMPILED_RUNTIME
@@ -2453,12 +2445,12 @@
void ReadFill(Deserializer* d) {
for (intptr_t id = start_index_; id < stop_index_; id++) {
- RawContext* context = reinterpret_cast<RawContext*>(d->Ref(id));
+ ContextPtr context = static_cast<ContextPtr>(d->Ref(id));
const intptr_t length = d->ReadUnsigned();
Deserializer::InitializeHeader(context, kContextCid,
Context::InstanceSize(length));
context->ptr()->num_variables_ = length;
- context->ptr()->parent_ = reinterpret_cast<RawContext*>(d->ReadRef());
+ context->ptr()->parent_ = static_cast<ContextPtr>(d->ReadRef());
for (intptr_t j = 0; j < length; j++) {
context->ptr()->data()[j] = d->ReadRef();
}
@@ -2472,8 +2464,8 @@
ContextScopeSerializationCluster() : SerializationCluster("ContextScope") {}
~ContextScopeSerializationCluster() {}
- void Trace(Serializer* s, RawObject* object) {
- RawContextScope* scope = ContextScope::RawCast(object);
+ void Trace(Serializer* s, ObjectPtr object) {
+ ContextScopePtr scope = ContextScope::RawCast(object);
objects_.Add(scope);
const intptr_t length = scope->ptr()->num_variables_;
@@ -2485,7 +2477,7 @@
const intptr_t count = objects_.length();
s->WriteUnsigned(count);
for (intptr_t i = 0; i < count; i++) {
- RawContextScope* scope = objects_[i];
+ ContextScopePtr scope = objects_[i];
s->AssignRef(scope);
AutoTraceObject(scope);
const intptr_t length = scope->ptr()->num_variables_;
@@ -2496,7 +2488,7 @@
void WriteFill(Serializer* s) {
const intptr_t count = objects_.length();
for (intptr_t i = 0; i < count; i++) {
- RawContextScope* scope = objects_[i];
+ ContextScopePtr scope = objects_[i];
AutoTraceObject(scope);
const intptr_t length = scope->ptr()->num_variables_;
s->WriteUnsigned(length);
@@ -2506,7 +2498,7 @@
}
private:
- GrowableArray<RawContextScope*> objects_;
+ GrowableArray<ContextScopePtr> objects_;
};
#endif // !DART_PRECOMPILED_RUNTIME
@@ -2529,7 +2521,7 @@
void ReadFill(Deserializer* d) {
for (intptr_t id = start_index_; id < stop_index_; id++) {
- RawContextScope* scope = reinterpret_cast<RawContextScope*>(d->Ref(id));
+ ContextScopePtr scope = static_cast<ContextScopePtr>(d->Ref(id));
const intptr_t length = d->ReadUnsigned();
Deserializer::InitializeHeader(scope, kContextScopeCid,
ContextScope::InstanceSize(length));
@@ -2547,8 +2539,8 @@
: SerializationCluster("ParameterTypeCheck") {}
~ParameterTypeCheckSerializationCluster() {}
- void Trace(Serializer* s, RawObject* object) {
- RawParameterTypeCheck* unlinked = ParameterTypeCheck::RawCast(object);
+ void Trace(Serializer* s, ObjectPtr object) {
+ ParameterTypeCheckPtr unlinked = ParameterTypeCheck::RawCast(object);
objects_.Add(unlinked);
PushFromTo(unlinked);
}
@@ -2558,7 +2550,7 @@
const intptr_t count = objects_.length();
s->WriteUnsigned(count);
for (intptr_t i = 0; i < count; i++) {
- RawParameterTypeCheck* check = objects_[i];
+ ParameterTypeCheckPtr check = objects_[i];
s->AssignRef(check);
}
}
@@ -2566,14 +2558,14 @@
void WriteFill(Serializer* s) {
const intptr_t count = objects_.length();
for (intptr_t i = 0; i < count; i++) {
- RawParameterTypeCheck* check = objects_[i];
+ ParameterTypeCheckPtr check = objects_[i];
s->Write<intptr_t>(check->ptr()->index_);
WriteFromTo(check);
}
}
private:
- GrowableArray<RawParameterTypeCheck*> objects_;
+ GrowableArray<ParameterTypeCheckPtr> objects_;
};
#endif // !DART_PRECOMPILED_RUNTIME
@@ -2595,8 +2587,8 @@
void ReadFill(Deserializer* d) {
for (intptr_t id = start_index_; id < stop_index_; id++) {
- RawParameterTypeCheck* check =
- reinterpret_cast<RawParameterTypeCheck*>(d->Ref(id));
+ ParameterTypeCheckPtr check =
+ static_cast<ParameterTypeCheckPtr>(d->Ref(id));
Deserializer::InitializeHeader(check, kParameterTypeCheckCid,
ParameterTypeCheck::InstanceSize());
check->ptr()->index_ = d->Read<intptr_t>();
@@ -2611,8 +2603,8 @@
UnlinkedCallSerializationCluster() : SerializationCluster("UnlinkedCall") {}
~UnlinkedCallSerializationCluster() {}
- void Trace(Serializer* s, RawObject* object) {
- RawUnlinkedCall* unlinked = UnlinkedCall::RawCast(object);
+ void Trace(Serializer* s, ObjectPtr object) {
+ UnlinkedCallPtr unlinked = UnlinkedCall::RawCast(object);
objects_.Add(unlinked);
PushFromTo(unlinked);
}
@@ -2622,7 +2614,7 @@
const intptr_t count = objects_.length();
s->WriteUnsigned(count);
for (intptr_t i = 0; i < count; i++) {
- RawUnlinkedCall* unlinked = objects_[i];
+ UnlinkedCallPtr unlinked = objects_[i];
s->AssignRef(unlinked);
}
}
@@ -2630,7 +2622,7 @@
void WriteFill(Serializer* s) {
const intptr_t count = objects_.length();
for (intptr_t i = 0; i < count; i++) {
- RawUnlinkedCall* unlinked = objects_[i];
+ UnlinkedCallPtr unlinked = objects_[i];
AutoTraceObjectName(unlinked, unlinked->ptr()->target_name_);
WriteFromTo(unlinked);
s->Write<bool>(unlinked->ptr()->can_patch_to_monomorphic_);
@@ -2638,7 +2630,7 @@
}
private:
- GrowableArray<RawUnlinkedCall*> objects_;
+ GrowableArray<UnlinkedCallPtr> objects_;
};
#endif // !DART_PRECOMPILED_RUNTIME
@@ -2660,8 +2652,7 @@
void ReadFill(Deserializer* d) {
for (intptr_t id = start_index_; id < stop_index_; id++) {
- RawUnlinkedCall* unlinked =
- reinterpret_cast<RawUnlinkedCall*>(d->Ref(id));
+ UnlinkedCallPtr unlinked = static_cast<UnlinkedCallPtr>(d->Ref(id));
Deserializer::InitializeHeader(unlinked, kUnlinkedCallCid,
UnlinkedCall::InstanceSize());
ReadFromTo(unlinked);
@@ -2676,8 +2667,8 @@
ICDataSerializationCluster() : SerializationCluster("ICData") {}
~ICDataSerializationCluster() {}
- void Trace(Serializer* s, RawObject* object) {
- RawICData* ic = ICData::RawCast(object);
+ void Trace(Serializer* s, ObjectPtr object) {
+ ICDataPtr ic = ICData::RawCast(object);
objects_.Add(ic);
PushFromTo(ic);
}
@@ -2687,7 +2678,7 @@
const intptr_t count = objects_.length();
s->WriteUnsigned(count);
for (intptr_t i = 0; i < count; i++) {
- RawICData* ic = objects_[i];
+ ICDataPtr ic = objects_[i];
s->AssignRef(ic);
}
}
@@ -2696,7 +2687,7 @@
Snapshot::Kind kind = s->kind();
const intptr_t count = objects_.length();
for (intptr_t i = 0; i < count; i++) {
- RawICData* ic = objects_[i];
+ ICDataPtr ic = objects_[i];
AutoTraceObjectName(ic, ic->ptr()->target_name_);
WriteFromTo(ic);
if (kind != Snapshot::kFullAOT) {
@@ -2707,7 +2698,7 @@
}
private:
- GrowableArray<RawICData*> objects_;
+ GrowableArray<ICDataPtr> objects_;
};
#endif // !DART_PRECOMPILED_RUNTIME
@@ -2728,7 +2719,7 @@
void ReadFill(Deserializer* d) {
for (intptr_t id = start_index_; id < stop_index_; id++) {
- RawICData* ic = reinterpret_cast<RawICData*>(d->Ref(id));
+ ICDataPtr ic = static_cast<ICDataPtr>(d->Ref(id));
Deserializer::InitializeHeader(ic, kICDataCid, ICData::InstanceSize());
ReadFromTo(ic);
NOT_IN_PRECOMPILED(ic->ptr()->deopt_id_ = d->Read<int32_t>());
@@ -2744,8 +2735,8 @@
: SerializationCluster("MegamorphicCache") {}
~MegamorphicCacheSerializationCluster() {}
- void Trace(Serializer* s, RawObject* object) {
- RawMegamorphicCache* cache = MegamorphicCache::RawCast(object);
+ void Trace(Serializer* s, ObjectPtr object) {
+ MegamorphicCachePtr cache = MegamorphicCache::RawCast(object);
objects_.Add(cache);
PushFromTo(cache);
}
@@ -2755,7 +2746,7 @@
const intptr_t count = objects_.length();
s->WriteUnsigned(count);
for (intptr_t i = 0; i < count; i++) {
- RawMegamorphicCache* cache = objects_[i];
+ MegamorphicCachePtr cache = objects_[i];
s->AssignRef(cache);
}
}
@@ -2763,7 +2754,7 @@
void WriteFill(Serializer* s) {
const intptr_t count = objects_.length();
for (intptr_t i = 0; i < count; i++) {
- RawMegamorphicCache* cache = objects_[i];
+ MegamorphicCachePtr cache = objects_[i];
AutoTraceObjectName(cache, cache->ptr()->target_name_);
WriteFromTo(cache);
s->Write<int32_t>(cache->ptr()->filled_entry_count_);
@@ -2771,7 +2762,7 @@
}
private:
- GrowableArray<RawMegamorphicCache*> objects_;
+ GrowableArray<MegamorphicCachePtr> objects_;
};
#endif // !DART_PRECOMPILED_RUNTIME
@@ -2793,8 +2784,7 @@
void ReadFill(Deserializer* d) {
for (intptr_t id = start_index_; id < stop_index_; id++) {
- RawMegamorphicCache* cache =
- reinterpret_cast<RawMegamorphicCache*>(d->Ref(id));
+ MegamorphicCachePtr cache = static_cast<MegamorphicCachePtr>(d->Ref(id));
Deserializer::InitializeHeader(cache, kMegamorphicCacheCid,
MegamorphicCache::InstanceSize());
ReadFromTo(cache);
@@ -2836,8 +2826,8 @@
: SerializationCluster("SubtypeTestCache") {}
~SubtypeTestCacheSerializationCluster() {}
- void Trace(Serializer* s, RawObject* object) {
- RawSubtypeTestCache* cache = SubtypeTestCache::RawCast(object);
+ void Trace(Serializer* s, ObjectPtr object) {
+ SubtypeTestCachePtr cache = SubtypeTestCache::RawCast(object);
objects_.Add(cache);
s->Push(cache->ptr()->cache_);
}
@@ -2847,7 +2837,7 @@
const intptr_t count = objects_.length();
s->WriteUnsigned(count);
for (intptr_t i = 0; i < count; i++) {
- RawSubtypeTestCache* cache = objects_[i];
+ SubtypeTestCachePtr cache = objects_[i];
s->AssignRef(cache);
}
}
@@ -2855,14 +2845,14 @@
void WriteFill(Serializer* s) {
const intptr_t count = objects_.length();
for (intptr_t i = 0; i < count; i++) {
- RawSubtypeTestCache* cache = objects_[i];
+ SubtypeTestCachePtr cache = objects_[i];
AutoTraceObject(cache);
WriteField(cache, cache_);
}
}
private:
- GrowableArray<RawSubtypeTestCache*> objects_;
+ GrowableArray<SubtypeTestCachePtr> objects_;
};
#endif // !DART_PRECOMPILED_RUNTIME
@@ -2884,11 +2874,10 @@
void ReadFill(Deserializer* d) {
for (intptr_t id = start_index_; id < stop_index_; id++) {
- RawSubtypeTestCache* cache =
- reinterpret_cast<RawSubtypeTestCache*>(d->Ref(id));
+ SubtypeTestCachePtr cache = static_cast<SubtypeTestCachePtr>(d->Ref(id));
Deserializer::InitializeHeader(cache, kSubtypeTestCacheCid,
SubtypeTestCache::InstanceSize());
- cache->ptr()->cache_ = reinterpret_cast<RawArray*>(d->ReadRef());
+ cache->ptr()->cache_ = static_cast<ArrayPtr>(d->ReadRef());
}
}
};
@@ -2899,8 +2888,8 @@
LanguageErrorSerializationCluster() : SerializationCluster("LanguageError") {}
~LanguageErrorSerializationCluster() {}
- void Trace(Serializer* s, RawObject* object) {
- RawLanguageError* error = LanguageError::RawCast(object);
+ void Trace(Serializer* s, ObjectPtr object) {
+ LanguageErrorPtr error = LanguageError::RawCast(object);
objects_.Add(error);
PushFromTo(error);
}
@@ -2910,7 +2899,7 @@
const intptr_t count = objects_.length();
s->WriteUnsigned(count);
for (intptr_t i = 0; i < count; i++) {
- RawLanguageError* error = objects_[i];
+ LanguageErrorPtr error = objects_[i];
s->AssignRef(error);
}
}
@@ -2918,7 +2907,7 @@
void WriteFill(Serializer* s) {
const intptr_t count = objects_.length();
for (intptr_t i = 0; i < count; i++) {
- RawLanguageError* error = objects_[i];
+ LanguageErrorPtr error = objects_[i];
AutoTraceObject(error);
WriteFromTo(error);
s->WriteTokenPosition(error->ptr()->token_pos_);
@@ -2928,7 +2917,7 @@
}
private:
- GrowableArray<RawLanguageError*> objects_;
+ GrowableArray<LanguageErrorPtr> objects_;
};
#endif // !DART_PRECOMPILED_RUNTIME
@@ -2950,7 +2939,7 @@
void ReadFill(Deserializer* d) {
for (intptr_t id = start_index_; id < stop_index_; id++) {
- RawLanguageError* error = reinterpret_cast<RawLanguageError*>(d->Ref(id));
+ LanguageErrorPtr error = static_cast<LanguageErrorPtr>(d->Ref(id));
Deserializer::InitializeHeader(error, kLanguageErrorCid,
LanguageError::InstanceSize());
ReadFromTo(error);
@@ -2968,8 +2957,8 @@
: SerializationCluster("UnhandledException") {}
~UnhandledExceptionSerializationCluster() {}
- void Trace(Serializer* s, RawObject* object) {
- RawUnhandledException* exception = UnhandledException::RawCast(object);
+ void Trace(Serializer* s, ObjectPtr object) {
+ UnhandledExceptionPtr exception = UnhandledException::RawCast(object);
objects_.Add(exception);
PushFromTo(exception);
}
@@ -2979,7 +2968,7 @@
const intptr_t count = objects_.length();
s->WriteUnsigned(count);
for (intptr_t i = 0; i < count; i++) {
- RawUnhandledException* exception = objects_[i];
+ UnhandledExceptionPtr exception = objects_[i];
s->AssignRef(exception);
}
}
@@ -2987,14 +2976,14 @@
void WriteFill(Serializer* s) {
const intptr_t count = objects_.length();
for (intptr_t i = 0; i < count; i++) {
- RawUnhandledException* exception = objects_[i];
+ UnhandledExceptionPtr exception = objects_[i];
AutoTraceObject(exception);
WriteFromTo(exception);
}
}
private:
- GrowableArray<RawUnhandledException*> objects_;
+ GrowableArray<UnhandledExceptionPtr> objects_;
};
#endif // !DART_PRECOMPILED_RUNTIME
@@ -3016,8 +3005,8 @@
void ReadFill(Deserializer* d) {
for (intptr_t id = start_index_; id < stop_index_; id++) {
- RawUnhandledException* exception =
- reinterpret_cast<RawUnhandledException*>(d->Ref(id));
+ UnhandledExceptionPtr exception =
+ static_cast<UnhandledExceptionPtr>(d->Ref(id));
Deserializer::InitializeHeader(exception, kUnhandledExceptionCid,
UnhandledException::InstanceSize());
ReadFromTo(exception);
@@ -3030,7 +3019,7 @@
public:
explicit InstanceSerializationCluster(intptr_t cid)
: SerializationCluster("Instance"), cid_(cid) {
- RawClass* cls = Isolate::Current()->class_table()->At(cid);
+ ClassPtr cls = Isolate::Current()->class_table()->At(cid);
host_next_field_offset_in_words_ =
cls->ptr()->host_next_field_offset_in_words_;
ASSERT(host_next_field_offset_in_words_ > 0);
@@ -3044,8 +3033,8 @@
}
~InstanceSerializationCluster() {}
- void Trace(Serializer* s, RawObject* object) {
- RawInstance* instance = Instance::RawCast(object);
+ void Trace(Serializer* s, ObjectPtr object) {
+ InstancePtr instance = Instance::RawCast(object);
objects_.Add(instance);
const intptr_t next_field_offset = host_next_field_offset_in_words_
<< kWordSizeLog2;
@@ -3056,7 +3045,7 @@
while (offset < next_field_offset) {
// Skips unboxed fields
if (!unboxed_fields_bitmap.Get(offset / kWordSize)) {
- RawObject* raw_obj = *reinterpret_cast<RawObject**>(
+ ObjectPtr raw_obj = *reinterpret_cast<ObjectPtr*>(
reinterpret_cast<uword>(instance->ptr()) + offset);
s->Push(raw_obj);
}
@@ -3077,7 +3066,7 @@
#endif // !defined(DART_PRECOMPILED_RUNTIME)
for (intptr_t i = 0; i < count; i++) {
- RawInstance* instance = objects_[i];
+ InstancePtr instance = objects_[i];
s->AssignRef(instance);
}
}
@@ -3090,9 +3079,9 @@
s->isolate()->group()->shared_class_table()->GetUnboxedFieldsMapAt(
cid_);
for (intptr_t i = 0; i < count; i++) {
- RawInstance* instance = objects_[i];
+ InstancePtr instance = objects_[i];
AutoTraceObject(instance);
- s->Write<bool>(instance->IsCanonical());
+ s->Write<bool>(instance->ptr()->IsCanonical());
intptr_t offset = Instance::NextFieldOffset();
while (offset < next_field_offset) {
if (unboxed_fields_bitmap.Get(offset / kWordSize)) {
@@ -3101,7 +3090,7 @@
reinterpret_cast<uword>(instance->ptr()) + offset);
s->WriteWordWith32BitWrites(value);
} else {
- RawObject* raw_obj = *reinterpret_cast<RawObject**>(
+ ObjectPtr raw_obj = *reinterpret_cast<ObjectPtr*>(
reinterpret_cast<uword>(instance->ptr()) + offset);
s->WriteElementRef(raw_obj, offset);
}
@@ -3117,7 +3106,7 @@
intptr_t target_next_field_offset_in_words_;
intptr_t target_instance_size_in_words_;
#endif // !defined(DART_PRECOMPILED_RUNTIME)
- GrowableArray<RawInstance*> objects_;
+ GrowableArray<InstancePtr> objects_;
};
#endif // !DART_PRECOMPILED_RUNTIME
@@ -3149,7 +3138,7 @@
d->isolate()->group()->shared_class_table()->GetUnboxedFieldsMapAt(
cid_);
for (intptr_t id = start_index_; id < stop_index_; id++) {
- RawInstance* instance = reinterpret_cast<RawInstance*>(d->Ref(id));
+ InstancePtr instance = static_cast<InstancePtr>(d->Ref(id));
bool is_canonical = d->Read<bool>();
Deserializer::InitializeHeader(instance, cid_, instance_size,
is_canonical);
@@ -3161,14 +3150,14 @@
// Reads 32 bits of the unboxed value at a time
*p = d->ReadWordWith32BitReads();
} else {
- RawObject** p = reinterpret_cast<RawObject**>(
+ ObjectPtr* p = reinterpret_cast<ObjectPtr*>(
reinterpret_cast<uword>(instance->ptr()) + offset);
*p = d->ReadRef();
}
offset += kWordSize;
}
if (offset < instance_size) {
- RawObject** p = reinterpret_cast<RawObject**>(
+ ObjectPtr* p = reinterpret_cast<ObjectPtr*>(
reinterpret_cast<uword>(instance->ptr()) + offset);
*p = Object::null();
offset += kWordSize;
@@ -3189,8 +3178,8 @@
LibraryPrefixSerializationCluster() : SerializationCluster("LibraryPrefix") {}
~LibraryPrefixSerializationCluster() {}
- void Trace(Serializer* s, RawObject* object) {
- RawLibraryPrefix* prefix = LibraryPrefix::RawCast(object);
+ void Trace(Serializer* s, ObjectPtr object) {
+ LibraryPrefixPtr prefix = LibraryPrefix::RawCast(object);
objects_.Add(prefix);
PushFromTo(prefix);
}
@@ -3200,7 +3189,7 @@
const intptr_t count = objects_.length();
s->WriteUnsigned(count);
for (intptr_t i = 0; i < count; i++) {
- RawLibraryPrefix* prefix = objects_[i];
+ LibraryPrefixPtr prefix = objects_[i];
s->AssignRef(prefix);
}
}
@@ -3208,7 +3197,7 @@
void WriteFill(Serializer* s) {
const intptr_t count = objects_.length();
for (intptr_t i = 0; i < count; i++) {
- RawLibraryPrefix* prefix = objects_[i];
+ LibraryPrefixPtr prefix = objects_[i];
AutoTraceObject(prefix);
WriteFromTo(prefix);
s->Write<uint16_t>(prefix->ptr()->num_imports_);
@@ -3217,7 +3206,7 @@
}
private:
- GrowableArray<RawLibraryPrefix*> objects_;
+ GrowableArray<LibraryPrefixPtr> objects_;
};
#endif // !DART_PRECOMPILED_RUNTIME
@@ -3239,8 +3228,7 @@
void ReadFill(Deserializer* d) {
for (intptr_t id = start_index_; id < stop_index_; id++) {
- RawLibraryPrefix* prefix =
- reinterpret_cast<RawLibraryPrefix*>(d->Ref(id));
+ LibraryPrefixPtr prefix = static_cast<LibraryPrefixPtr>(d->Ref(id));
Deserializer::InitializeHeader(prefix, kLibraryPrefixCid,
LibraryPrefix::InstanceSize());
ReadFromTo(prefix);
@@ -3256,9 +3244,9 @@
TypeSerializationCluster() : SerializationCluster("Type") {}
~TypeSerializationCluster() {}
- void Trace(Serializer* s, RawObject* object) {
- RawType* type = Type::RawCast(object);
- if (type->IsCanonical()) {
+ void Trace(Serializer* s, ObjectPtr object) {
+ TypePtr type = Type::RawCast(object);
+ if (type->ptr()->IsCanonical()) {
canonical_objects_.Add(type);
} else {
objects_.Add(type);
@@ -3271,8 +3259,8 @@
UNREACHABLE();
}
- RawSmi* raw_type_class_id = Smi::RawCast(type->ptr()->type_class_id_);
- RawClass* type_class =
+ SmiPtr raw_type_class_id = Smi::RawCast(type->ptr()->type_class_id_);
+ ClassPtr type_class =
s->isolate()->class_table()->At(Smi::Value(raw_type_class_id));
s->Push(type_class);
}
@@ -3282,13 +3270,13 @@
intptr_t count = canonical_objects_.length();
s->WriteUnsigned(count);
for (intptr_t i = 0; i < count; i++) {
- RawType* type = canonical_objects_[i];
+ TypePtr type = canonical_objects_[i];
s->AssignRef(type);
}
count = objects_.length();
s->WriteUnsigned(count);
for (intptr_t i = 0; i < count; i++) {
- RawType* type = objects_[i];
+ TypePtr type = objects_[i];
s->AssignRef(type);
}
}
@@ -3296,7 +3284,7 @@
void WriteFill(Serializer* s) {
intptr_t count = canonical_objects_.length();
for (intptr_t i = 0; i < count; i++) {
- RawType* type = canonical_objects_[i];
+ TypePtr type = canonical_objects_[i];
AutoTraceObject(type);
WriteFromTo(type);
s->WriteTokenPosition(type->ptr()->token_pos_);
@@ -3308,7 +3296,7 @@
}
count = objects_.length();
for (intptr_t i = 0; i < count; i++) {
- RawType* type = objects_[i];
+ TypePtr type = objects_[i];
AutoTraceObject(type);
WriteFromTo(type);
s->WriteTokenPosition(type->ptr()->token_pos_);
@@ -3321,8 +3309,8 @@
}
private:
- GrowableArray<RawType*> canonical_objects_;
- GrowableArray<RawType*> objects_;
+ GrowableArray<TypePtr> canonical_objects_;
+ GrowableArray<TypePtr> objects_;
};
#endif // !DART_PRECOMPILED_RUNTIME
@@ -3351,7 +3339,7 @@
void ReadFill(Deserializer* d) {
for (intptr_t id = canonical_start_index_; id < canonical_stop_index_;
id++) {
- RawType* type = reinterpret_cast<RawType*>(d->Ref(id));
+ TypePtr type = static_cast<TypePtr>(d->Ref(id));
bool is_canonical = true;
Deserializer::InitializeHeader(type, kTypeCid, Type::InstanceSize(),
is_canonical);
@@ -3363,7 +3351,7 @@
}
for (intptr_t id = start_index_; id < stop_index_; id++) {
- RawType* type = reinterpret_cast<RawType*>(d->Ref(id));
+ TypePtr type = static_cast<TypePtr>(d->Ref(id));
bool is_canonical = false;
Deserializer::InitializeHeader(type, kTypeCid, Type::InstanceSize(),
is_canonical);
@@ -3417,8 +3405,8 @@
TypeRefSerializationCluster() : SerializationCluster("TypeRef") {}
~TypeRefSerializationCluster() {}
- void Trace(Serializer* s, RawObject* object) {
- RawTypeRef* type = TypeRef::RawCast(object);
+ void Trace(Serializer* s, ObjectPtr object) {
+ TypeRefPtr type = TypeRef::RawCast(object);
objects_.Add(type);
PushFromTo(type);
}
@@ -3428,7 +3416,7 @@
const intptr_t count = objects_.length();
s->WriteUnsigned(count);
for (intptr_t i = 0; i < count; i++) {
- RawTypeRef* type = objects_[i];
+ TypeRefPtr type = objects_[i];
s->AssignRef(type);
}
}
@@ -3436,14 +3424,14 @@
void WriteFill(Serializer* s) {
const intptr_t count = objects_.length();
for (intptr_t i = 0; i < count; i++) {
- RawTypeRef* type = objects_[i];
+ TypeRefPtr type = objects_[i];
AutoTraceObject(type);
WriteFromTo(type);
}
}
private:
- GrowableArray<RawTypeRef*> objects_;
+ GrowableArray<TypeRefPtr> objects_;
};
#endif // !DART_PRECOMPILED_RUNTIME
@@ -3464,7 +3452,7 @@
void ReadFill(Deserializer* d) {
for (intptr_t id = start_index_; id < stop_index_; id++) {
- RawTypeRef* type = reinterpret_cast<RawTypeRef*>(d->Ref(id));
+ TypeRefPtr type = static_cast<TypeRefPtr>(d->Ref(id));
Deserializer::InitializeHeader(type, kTypeRefCid,
TypeRef::InstanceSize());
ReadFromTo(type);
@@ -3499,10 +3487,10 @@
~TypeParameterSerializationCluster() {}
- void Trace(Serializer* s, RawObject* object) {
- RawTypeParameter* type = TypeParameter::RawCast(object);
+ void Trace(Serializer* s, ObjectPtr object) {
+ TypeParameterPtr type = TypeParameter::RawCast(object);
objects_.Add(type);
- ASSERT(!type->IsCanonical());
+ ASSERT(!type->ptr()->IsCanonical());
PushFromTo(type);
}
@@ -3511,7 +3499,7 @@
const intptr_t count = objects_.length();
s->WriteUnsigned(count);
for (intptr_t i = 0; i < count; i++) {
- RawTypeParameter* type = objects_[i];
+ TypeParameterPtr type = objects_[i];
s->AssignRef(type);
}
}
@@ -3519,7 +3507,7 @@
void WriteFill(Serializer* s) {
const intptr_t count = objects_.length();
for (intptr_t i = 0; i < count; i++) {
- RawTypeParameter* type = objects_[i];
+ TypeParameterPtr type = objects_[i];
AutoTraceObject(type);
WriteFromTo(type);
s->Write<int32_t>(type->ptr()->parameterized_class_id_);
@@ -3534,7 +3522,7 @@
}
private:
- GrowableArray<RawTypeParameter*> objects_;
+ GrowableArray<TypeParameterPtr> objects_;
};
#endif // !DART_PRECOMPILED_RUNTIME
@@ -3556,7 +3544,7 @@
void ReadFill(Deserializer* d) {
for (intptr_t id = start_index_; id < stop_index_; id++) {
- RawTypeParameter* type = reinterpret_cast<RawTypeParameter*>(d->Ref(id));
+ TypeParameterPtr type = static_cast<TypeParameterPtr>(d->Ref(id));
Deserializer::InitializeHeader(type, kTypeParameterCid,
TypeParameter::InstanceSize());
ReadFromTo(type);
@@ -3596,8 +3584,8 @@
ClosureSerializationCluster() : SerializationCluster("Closure") {}
~ClosureSerializationCluster() {}
- void Trace(Serializer* s, RawObject* object) {
- RawClosure* closure = Closure::RawCast(object);
+ void Trace(Serializer* s, ObjectPtr object) {
+ ClosurePtr closure = Closure::RawCast(object);
objects_.Add(closure);
PushFromTo(closure);
}
@@ -3607,7 +3595,7 @@
const intptr_t count = objects_.length();
s->WriteUnsigned(count);
for (intptr_t i = 0; i < count; i++) {
- RawClosure* closure = objects_[i];
+ ClosurePtr closure = objects_[i];
s->AssignRef(closure);
}
}
@@ -3615,15 +3603,15 @@
void WriteFill(Serializer* s) {
const intptr_t count = objects_.length();
for (intptr_t i = 0; i < count; i++) {
- RawClosure* closure = objects_[i];
+ ClosurePtr closure = objects_[i];
AutoTraceObject(closure);
- s->Write<bool>(closure->IsCanonical());
+ s->Write<bool>(closure->ptr()->IsCanonical());
WriteFromTo(closure);
}
}
private:
- GrowableArray<RawClosure*> objects_;
+ GrowableArray<ClosurePtr> objects_;
};
#endif // !DART_PRECOMPILED_RUNTIME
@@ -3644,7 +3632,7 @@
void ReadFill(Deserializer* d) {
for (intptr_t id = start_index_; id < stop_index_; id++) {
- RawClosure* closure = reinterpret_cast<RawClosure*>(d->Ref(id));
+ ClosurePtr closure = static_cast<ClosurePtr>(d->Ref(id));
bool is_canonical = d->Read<bool>();
Deserializer::InitializeHeader(closure, kClosureCid,
Closure::InstanceSize(), is_canonical);
@@ -3659,12 +3647,12 @@
MintSerializationCluster() : SerializationCluster("int") {}
~MintSerializationCluster() {}
- void Trace(Serializer* s, RawObject* object) {
+ void Trace(Serializer* s, ObjectPtr object) {
if (!object->IsHeapObject()) {
- RawSmi* smi = Smi::RawCast(object);
+ SmiPtr smi = Smi::RawCast(object);
smis_.Add(smi);
} else {
- RawMint* mint = Mint::RawCast(object);
+ MintPtr mint = Mint::RawCast(object);
mints_.Add(mint);
}
}
@@ -3674,17 +3662,17 @@
s->WriteUnsigned(smis_.length() + mints_.length());
for (intptr_t i = 0; i < smis_.length(); i++) {
- RawSmi* smi = smis_[i];
+ SmiPtr smi = smis_[i];
s->AssignRef(smi);
AutoTraceObject(smi);
s->Write<bool>(true);
s->Write<int64_t>(Smi::Value(smi));
}
for (intptr_t i = 0; i < mints_.length(); i++) {
- RawMint* mint = mints_[i];
+ MintPtr mint = mints_[i];
s->AssignRef(mint);
AutoTraceObject(mint);
- s->Write<bool>(mint->IsCanonical());
+ s->Write<bool>(mint->ptr()->IsCanonical());
s->Write<int64_t>(mint->ptr()->value_);
}
}
@@ -3692,8 +3680,8 @@
void WriteFill(Serializer* s) {}
private:
- GrowableArray<RawSmi*> smis_;
- GrowableArray<RawMint*> mints_;
+ GrowableArray<SmiPtr> smis_;
+ GrowableArray<MintPtr> mints_;
};
#endif // !DART_PRECOMPILED_RUNTIME
@@ -3713,7 +3701,7 @@
if (Smi::IsValid(value)) {
d->AssignRef(Smi::New(value));
} else {
- RawMint* mint = static_cast<RawMint*>(
+ MintPtr mint = static_cast<MintPtr>(
AllocateUninitialized(old_space, Mint::InstanceSize()));
Deserializer::InitializeHeader(mint, kMintCid, Mint::InstanceSize(),
is_canonical);
@@ -3746,8 +3734,8 @@
DoubleSerializationCluster() : SerializationCluster("double") {}
~DoubleSerializationCluster() {}
- void Trace(Serializer* s, RawObject* object) {
- RawDouble* dbl = Double::RawCast(object);
+ void Trace(Serializer* s, ObjectPtr object) {
+ DoublePtr dbl = Double::RawCast(object);
objects_.Add(dbl);
}
@@ -3756,7 +3744,7 @@
const intptr_t count = objects_.length();
s->WriteUnsigned(count);
for (intptr_t i = 0; i < count; i++) {
- RawDouble* dbl = objects_[i];
+ DoublePtr dbl = objects_[i];
s->AssignRef(dbl);
}
}
@@ -3764,15 +3752,15 @@
void WriteFill(Serializer* s) {
const intptr_t count = objects_.length();
for (intptr_t i = 0; i < count; i++) {
- RawDouble* dbl = objects_[i];
+ DoublePtr dbl = objects_[i];
AutoTraceObject(dbl);
- s->Write<bool>(dbl->IsCanonical());
+ s->Write<bool>(dbl->ptr()->IsCanonical());
s->Write<double>(dbl->ptr()->value_);
}
}
private:
- GrowableArray<RawDouble*> objects_;
+ GrowableArray<DoublePtr> objects_;
};
#endif // !DART_PRECOMPILED_RUNTIME
@@ -3793,7 +3781,7 @@
void ReadFill(Deserializer* d) {
for (intptr_t id = start_index_; id < stop_index_; id++) {
- RawDouble* dbl = reinterpret_cast<RawDouble*>(d->Ref(id));
+ DoublePtr dbl = static_cast<DoublePtr>(d->Ref(id));
bool is_canonical = d->Read<bool>();
Deserializer::InitializeHeader(dbl, kDoubleCid, Double::InstanceSize(),
is_canonical);
@@ -3809,8 +3797,8 @@
: SerializationCluster("GrowableObjectArray") {}
~GrowableObjectArraySerializationCluster() {}
- void Trace(Serializer* s, RawObject* object) {
- RawGrowableObjectArray* array = GrowableObjectArray::RawCast(object);
+ void Trace(Serializer* s, ObjectPtr object) {
+ GrowableObjectArrayPtr array = GrowableObjectArray::RawCast(object);
objects_.Add(array);
PushFromTo(array);
}
@@ -3820,7 +3808,7 @@
const intptr_t count = objects_.length();
s->WriteUnsigned(count);
for (intptr_t i = 0; i < count; i++) {
- RawGrowableObjectArray* array = objects_[i];
+ GrowableObjectArrayPtr array = objects_[i];
s->AssignRef(array);
}
}
@@ -3828,15 +3816,15 @@
void WriteFill(Serializer* s) {
const intptr_t count = objects_.length();
for (intptr_t i = 0; i < count; i++) {
- RawGrowableObjectArray* array = objects_[i];
+ GrowableObjectArrayPtr array = objects_[i];
AutoTraceObject(array);
- s->Write<bool>(array->IsCanonical());
+ s->Write<bool>(array->ptr()->IsCanonical());
WriteFromTo(array);
}
}
private:
- GrowableArray<RawGrowableObjectArray*> objects_;
+ GrowableArray<GrowableObjectArrayPtr> objects_;
};
#endif // !DART_PRECOMPILED_RUNTIME
@@ -3859,8 +3847,8 @@
void ReadFill(Deserializer* d) {
for (intptr_t id = start_index_; id < stop_index_; id++) {
- RawGrowableObjectArray* list =
- reinterpret_cast<RawGrowableObjectArray*>(d->Ref(id));
+ GrowableObjectArrayPtr list =
+ static_cast<GrowableObjectArrayPtr>(d->Ref(id));
bool is_canonical = d->Read<bool>();
Deserializer::InitializeHeader(list, kGrowableObjectArrayCid,
GrowableObjectArray::InstanceSize(),
@@ -3877,8 +3865,8 @@
: SerializationCluster("TypedData"), cid_(cid) {}
~TypedDataSerializationCluster() {}
- void Trace(Serializer* s, RawObject* object) {
- RawTypedData* data = TypedData::RawCast(object);
+ void Trace(Serializer* s, ObjectPtr object) {
+ TypedDataPtr data = TypedData::RawCast(object);
objects_.Add(data);
}
@@ -3887,7 +3875,7 @@
const intptr_t count = objects_.length();
s->WriteUnsigned(count);
for (intptr_t i = 0; i < count; i++) {
- RawTypedData* data = objects_[i];
+ TypedDataPtr data = objects_[i];
s->AssignRef(data);
AutoTraceObject(data);
const intptr_t length = Smi::Value(data->ptr()->length_);
@@ -3899,11 +3887,11 @@
const intptr_t count = objects_.length();
intptr_t element_size = TypedData::ElementSizeInBytes(cid_);
for (intptr_t i = 0; i < count; i++) {
- RawTypedData* data = objects_[i];
+ TypedDataPtr data = objects_[i];
AutoTraceObject(data);
const intptr_t length = Smi::Value(data->ptr()->length_);
s->WriteUnsigned(length);
- s->Write<bool>(data->IsCanonical());
+ s->Write<bool>(data->ptr()->IsCanonical());
uint8_t* cdata = reinterpret_cast<uint8_t*>(data->ptr()->data());
s->WriteBytes(cdata, length * element_size);
}
@@ -3911,7 +3899,7 @@
private:
const intptr_t cid_;
- GrowableArray<RawTypedData*> objects_;
+ GrowableArray<TypedDataPtr> objects_;
};
#endif // !DART_PRECOMPILED_RUNTIME
@@ -3937,14 +3925,14 @@
intptr_t element_size = TypedData::ElementSizeInBytes(cid_);
for (intptr_t id = start_index_; id < stop_index_; id++) {
- RawTypedData* data = reinterpret_cast<RawTypedData*>(d->Ref(id));
+ TypedDataPtr data = static_cast<TypedDataPtr>(d->Ref(id));
const intptr_t length = d->ReadUnsigned();
bool is_canonical = d->Read<bool>();
const intptr_t length_in_bytes = length * element_size;
Deserializer::InitializeHeader(
data, cid_, TypedData::InstanceSize(length_in_bytes), is_canonical);
data->ptr()->length_ = Smi::New(length);
- data->RecomputeDataField();
+ data->ptr()->RecomputeDataField();
uint8_t* cdata = reinterpret_cast<uint8_t*>(data->ptr()->data());
d->ReadBytes(cdata, length_in_bytes);
}
@@ -3961,8 +3949,8 @@
: SerializationCluster("TypedDataView"), cid_(cid) {}
~TypedDataViewSerializationCluster() {}
- void Trace(Serializer* s, RawObject* object) {
- RawTypedDataView* view = TypedDataView::RawCast(object);
+ void Trace(Serializer* s, ObjectPtr object) {
+ TypedDataViewPtr view = TypedDataView::RawCast(object);
objects_.Add(view);
PushFromTo(view);
@@ -3973,7 +3961,7 @@
s->WriteCid(cid_);
s->WriteUnsigned(count);
for (intptr_t i = 0; i < count; i++) {
- RawTypedDataView* view = objects_[i];
+ TypedDataViewPtr view = objects_[i];
s->AssignRef(view);
}
}
@@ -3981,16 +3969,16 @@
void WriteFill(Serializer* s) {
const intptr_t count = objects_.length();
for (intptr_t i = 0; i < count; i++) {
- RawTypedDataView* view = objects_[i];
+ TypedDataViewPtr view = objects_[i];
AutoTraceObject(view);
- s->Write<bool>(view->IsCanonical());
+ s->Write<bool>(view->ptr()->IsCanonical());
WriteFromTo(view);
}
}
private:
const intptr_t cid_;
- GrowableArray<RawTypedDataView*> objects_;
+ GrowableArray<TypedDataViewPtr> objects_;
};
#endif // !DART_PRECOMPILED_RUNTIME
@@ -4012,7 +4000,7 @@
void ReadFill(Deserializer* d) {
for (intptr_t id = start_index_; id < stop_index_; id++) {
- RawTypedDataView* view = reinterpret_cast<RawTypedDataView*>(d->Ref(id));
+ TypedDataViewPtr view = static_cast<TypedDataViewPtr>(d->Ref(id));
const bool is_canonical = d->Read<bool>();
Deserializer::InitializeHeader(view, cid_, TypedDataView::InstanceSize(),
is_canonical);
@@ -4039,10 +4027,10 @@
: SerializationCluster("ExternalTypedData"), cid_(cid) {}
~ExternalTypedDataSerializationCluster() {}
- void Trace(Serializer* s, RawObject* object) {
- RawExternalTypedData* data = ExternalTypedData::RawCast(object);
+ void Trace(Serializer* s, ObjectPtr object) {
+ ExternalTypedDataPtr data = ExternalTypedData::RawCast(object);
objects_.Add(data);
- ASSERT(!data->IsCanonical());
+ ASSERT(!data->ptr()->IsCanonical());
}
void WriteAlloc(Serializer* s) {
@@ -4050,7 +4038,7 @@
const intptr_t count = objects_.length();
s->WriteUnsigned(count);
for (intptr_t i = 0; i < count; i++) {
- RawExternalTypedData* data = objects_[i];
+ ExternalTypedDataPtr data = objects_[i];
s->AssignRef(data);
}
}
@@ -4059,7 +4047,7 @@
const intptr_t count = objects_.length();
intptr_t element_size = ExternalTypedData::ElementSizeInBytes(cid_);
for (intptr_t i = 0; i < count; i++) {
- RawExternalTypedData* data = objects_[i];
+ ExternalTypedDataPtr data = objects_[i];
AutoTraceObject(data);
const intptr_t length = Smi::Value(data->ptr()->length_);
s->WriteUnsigned(length);
@@ -4071,7 +4059,7 @@
private:
const intptr_t cid_;
- GrowableArray<RawExternalTypedData*> objects_;
+ GrowableArray<ExternalTypedDataPtr> objects_;
};
#endif // !DART_PRECOMPILED_RUNTIME
@@ -4095,8 +4083,7 @@
intptr_t element_size = ExternalTypedData::ElementSizeInBytes(cid_);
for (intptr_t id = start_index_; id < stop_index_; id++) {
- RawExternalTypedData* data =
- reinterpret_cast<RawExternalTypedData*>(d->Ref(id));
+ ExternalTypedDataPtr data = static_cast<ExternalTypedDataPtr>(d->Ref(id));
const intptr_t length = d->ReadUnsigned();
Deserializer::InitializeHeader(data, cid_,
ExternalTypedData::InstanceSize());
@@ -4118,8 +4105,8 @@
StackTraceSerializationCluster() : SerializationCluster("StackTrace") {}
~StackTraceSerializationCluster() {}
- void Trace(Serializer* s, RawObject* object) {
- RawStackTrace* trace = StackTrace::RawCast(object);
+ void Trace(Serializer* s, ObjectPtr object) {
+ StackTracePtr trace = StackTrace::RawCast(object);
objects_.Add(trace);
PushFromTo(trace);
}
@@ -4129,7 +4116,7 @@
const intptr_t count = objects_.length();
s->WriteUnsigned(count);
for (intptr_t i = 0; i < count; i++) {
- RawStackTrace* trace = objects_[i];
+ StackTracePtr trace = objects_[i];
s->AssignRef(trace);
}
}
@@ -4137,14 +4124,14 @@
void WriteFill(Serializer* s) {
const intptr_t count = objects_.length();
for (intptr_t i = 0; i < count; i++) {
- RawStackTrace* trace = objects_[i];
+ StackTracePtr trace = objects_[i];
AutoTraceObject(trace);
WriteFromTo(trace);
}
}
private:
- GrowableArray<RawStackTrace*> objects_;
+ GrowableArray<StackTracePtr> objects_;
};
#endif // !DART_PRECOMPILED_RUNTIME
@@ -4166,7 +4153,7 @@
void ReadFill(Deserializer* d) {
for (intptr_t id = start_index_; id < stop_index_; id++) {
- RawStackTrace* trace = reinterpret_cast<RawStackTrace*>(d->Ref(id));
+ StackTracePtr trace = static_cast<StackTracePtr>(d->Ref(id));
Deserializer::InitializeHeader(trace, kStackTraceCid,
StackTrace::InstanceSize());
ReadFromTo(trace);
@@ -4180,8 +4167,8 @@
RegExpSerializationCluster() : SerializationCluster("RegExp") {}
~RegExpSerializationCluster() {}
- void Trace(Serializer* s, RawObject* object) {
- RawRegExp* regexp = RegExp::RawCast(object);
+ void Trace(Serializer* s, ObjectPtr object) {
+ RegExpPtr regexp = RegExp::RawCast(object);
objects_.Add(regexp);
PushFromTo(regexp);
}
@@ -4191,7 +4178,7 @@
const intptr_t count = objects_.length();
s->WriteUnsigned(count);
for (intptr_t i = 0; i < count; i++) {
- RawRegExp* regexp = objects_[i];
+ RegExpPtr regexp = objects_[i];
s->AssignRef(regexp);
}
}
@@ -4199,7 +4186,7 @@
void WriteFill(Serializer* s) {
const intptr_t count = objects_.length();
for (intptr_t i = 0; i < count; i++) {
- RawRegExp* regexp = objects_[i];
+ RegExpPtr regexp = objects_[i];
AutoTraceObject(regexp);
WriteFromTo(regexp);
s->Write<int32_t>(regexp->ptr()->num_one_byte_registers_);
@@ -4209,7 +4196,7 @@
}
private:
- GrowableArray<RawRegExp*> objects_;
+ GrowableArray<RegExpPtr> objects_;
};
#endif // !DART_PRECOMPILED_RUNTIME
@@ -4230,7 +4217,7 @@
void ReadFill(Deserializer* d) {
for (intptr_t id = start_index_; id < stop_index_; id++) {
- RawRegExp* regexp = reinterpret_cast<RawRegExp*>(d->Ref(id));
+ RegExpPtr regexp = static_cast<RegExpPtr>(d->Ref(id));
Deserializer::InitializeHeader(regexp, kRegExpCid,
RegExp::InstanceSize());
ReadFromTo(regexp);
@@ -4247,8 +4234,8 @@
WeakPropertySerializationCluster() : SerializationCluster("WeakProperty") {}
~WeakPropertySerializationCluster() {}
- void Trace(Serializer* s, RawObject* object) {
- RawWeakProperty* property = WeakProperty::RawCast(object);
+ void Trace(Serializer* s, ObjectPtr object) {
+ WeakPropertyPtr property = WeakProperty::RawCast(object);
objects_.Add(property);
PushFromTo(property);
}
@@ -4258,7 +4245,7 @@
const intptr_t count = objects_.length();
s->WriteUnsigned(count);
for (intptr_t i = 0; i < count; i++) {
- RawWeakProperty* property = objects_[i];
+ WeakPropertyPtr property = objects_[i];
s->AssignRef(property);
}
}
@@ -4266,14 +4253,14 @@
void WriteFill(Serializer* s) {
const intptr_t count = objects_.length();
for (intptr_t i = 0; i < count; i++) {
- RawWeakProperty* property = objects_[i];
+ WeakPropertyPtr property = objects_[i];
AutoTraceObject(property);
WriteFromTo(property);
}
}
private:
- GrowableArray<RawWeakProperty*> objects_;
+ GrowableArray<WeakPropertyPtr> objects_;
};
#endif // !DART_PRECOMPILED_RUNTIME
@@ -4295,8 +4282,7 @@
void ReadFill(Deserializer* d) {
for (intptr_t id = start_index_; id < stop_index_; id++) {
- RawWeakProperty* property =
- reinterpret_cast<RawWeakProperty*>(d->Ref(id));
+ WeakPropertyPtr property = static_cast<WeakPropertyPtr>(d->Ref(id));
Deserializer::InitializeHeader(property, kWeakPropertyCid,
WeakProperty::InstanceSize());
ReadFromTo(property);
@@ -4310,19 +4296,19 @@
LinkedHashMapSerializationCluster() : SerializationCluster("LinkedHashMap") {}
~LinkedHashMapSerializationCluster() {}
- void Trace(Serializer* s, RawObject* object) {
- RawLinkedHashMap* map = LinkedHashMap::RawCast(object);
+ void Trace(Serializer* s, ObjectPtr object) {
+ LinkedHashMapPtr map = LinkedHashMap::RawCast(object);
objects_.Add(map);
s->Push(map->ptr()->type_arguments_);
intptr_t used_data = Smi::Value(map->ptr()->used_data_);
- RawArray* data_array = map->ptr()->data_;
- RawObject** data_elements = data_array->ptr()->data();
+ ArrayPtr data_array = map->ptr()->data_;
+ ObjectPtr* data_elements = data_array->ptr()->data();
for (intptr_t i = 0; i < used_data; i += 2) {
- RawObject* key = data_elements[i];
+ ObjectPtr key = data_elements[i];
if (key != data_array) {
- RawObject* value = data_elements[i + 1];
+ ObjectPtr value = data_elements[i + 1];
s->Push(key);
s->Push(value);
}
@@ -4334,7 +4320,7 @@
const intptr_t count = objects_.length();
s->WriteUnsigned(count);
for (intptr_t i = 0; i < count; i++) {
- RawLinkedHashMap* map = objects_[i];
+ LinkedHashMapPtr map = objects_[i];
s->AssignRef(map);
}
}
@@ -4342,9 +4328,9 @@
void WriteFill(Serializer* s) {
const intptr_t count = objects_.length();
for (intptr_t i = 0; i < count; i++) {
- RawLinkedHashMap* map = objects_[i];
+ LinkedHashMapPtr map = objects_[i];
AutoTraceObject(map);
- s->Write<bool>(map->IsCanonical());
+ s->Write<bool>(map->ptr()->IsCanonical());
WriteField(map, type_arguments_);
@@ -4355,12 +4341,12 @@
// Write out the number of (not deleted) key/value pairs that will follow.
s->Write<int32_t>((used_data >> 1) - deleted_keys);
- RawArray* data_array = map->ptr()->data_;
- RawObject** data_elements = data_array->ptr()->data();
+ ArrayPtr data_array = map->ptr()->data_;
+ ObjectPtr* data_elements = data_array->ptr()->data();
for (intptr_t i = 0; i < used_data; i += 2) {
- RawObject* key = data_elements[i];
+ ObjectPtr key = data_elements[i];
if (key != data_array) {
- RawObject* value = data_elements[i + 1];
+ ObjectPtr value = data_elements[i + 1];
s->WriteElementRef(key, i);
s->WriteElementRef(value, i + 1);
}
@@ -4369,7 +4355,7 @@
}
private:
- GrowableArray<RawLinkedHashMap*> objects_;
+ GrowableArray<LinkedHashMapPtr> objects_;
};
#endif // !DART_PRECOMPILED_RUNTIME
@@ -4393,13 +4379,12 @@
PageSpace* old_space = d->heap()->old_space();
for (intptr_t id = start_index_; id < stop_index_; id++) {
- RawLinkedHashMap* map = reinterpret_cast<RawLinkedHashMap*>(d->Ref(id));
+ LinkedHashMapPtr map = static_cast<LinkedHashMapPtr>(d->Ref(id));
bool is_canonical = d->Read<bool>();
Deserializer::InitializeHeader(
map, kLinkedHashMapCid, LinkedHashMap::InstanceSize(), is_canonical);
- map->ptr()->type_arguments_ =
- reinterpret_cast<RawTypeArguments*>(d->ReadRef());
+ map->ptr()->type_arguments_ = static_cast<TypeArgumentsPtr>(d->ReadRef());
// TODO(rmacnak): Reserve ref ids and co-allocate in ReadAlloc.
intptr_t pairs = d->Read<int32_t>();
@@ -4408,7 +4393,7 @@
Utils::RoundUpToPowerOfTwo(used_data),
static_cast<uintptr_t>(LinkedHashMap::kInitialIndexSize));
- RawArray* data = reinterpret_cast<RawArray*>(
+ ArrayPtr data = static_cast<ArrayPtr>(
AllocateUninitialized(old_space, Array::InstanceSize(data_size)));
data->ptr()->type_arguments_ = TypeArguments::null();
data->ptr()->length_ = Smi::New(data_size);
@@ -4436,8 +4421,8 @@
: SerializationCluster("Array"), cid_(cid) {}
~ArraySerializationCluster() {}
- void Trace(Serializer* s, RawObject* object) {
- RawArray* array = Array::RawCast(object);
+ void Trace(Serializer* s, ObjectPtr object) {
+ ArrayPtr array = Array::RawCast(object);
objects_.Add(array);
s->Push(array->ptr()->type_arguments_);
@@ -4452,7 +4437,7 @@
const intptr_t count = objects_.length();
s->WriteUnsigned(count);
for (intptr_t i = 0; i < count; i++) {
- RawArray* array = objects_[i];
+ ArrayPtr array = objects_[i];
s->AssignRef(array);
AutoTraceObject(array);
const intptr_t length = Smi::Value(array->ptr()->length_);
@@ -4463,11 +4448,11 @@
void WriteFill(Serializer* s) {
const intptr_t count = objects_.length();
for (intptr_t i = 0; i < count; i++) {
- RawArray* array = objects_[i];
+ ArrayPtr array = objects_[i];
AutoTraceObject(array);
const intptr_t length = Smi::Value(array->ptr()->length_);
s->WriteUnsigned(length);
- s->Write<bool>(array->IsCanonical());
+ s->Write<bool>(array->ptr()->IsCanonical());
WriteField(array, type_arguments_);
for (intptr_t j = 0; j < length; j++) {
s->WriteElementRef(array->ptr()->data()[j], j);
@@ -4477,7 +4462,7 @@
private:
intptr_t cid_;
- GrowableArray<RawArray*> objects_;
+ GrowableArray<ArrayPtr> objects_;
};
#endif // !DART_PRECOMPILED_RUNTIME
@@ -4500,13 +4485,13 @@
void ReadFill(Deserializer* d) {
for (intptr_t id = start_index_; id < stop_index_; id++) {
- RawArray* array = reinterpret_cast<RawArray*>(d->Ref(id));
+ ArrayPtr array = static_cast<ArrayPtr>(d->Ref(id));
const intptr_t length = d->ReadUnsigned();
bool is_canonical = d->Read<bool>();
Deserializer::InitializeHeader(array, cid_, Array::InstanceSize(length),
is_canonical);
array->ptr()->type_arguments_ =
- reinterpret_cast<RawTypeArguments*>(d->ReadRef());
+ static_cast<TypeArgumentsPtr>(d->ReadRef());
array->ptr()->length_ = Smi::New(length);
for (intptr_t j = 0; j < length; j++) {
array->ptr()->data()[j] = d->ReadRef();
@@ -4524,8 +4509,8 @@
OneByteStringSerializationCluster() : SerializationCluster("OneByteString") {}
~OneByteStringSerializationCluster() {}
- void Trace(Serializer* s, RawObject* object) {
- RawOneByteString* str = reinterpret_cast<RawOneByteString*>(object);
+ void Trace(Serializer* s, ObjectPtr object) {
+ OneByteStringPtr str = static_cast<OneByteStringPtr>(object);
objects_.Add(str);
}
@@ -4534,7 +4519,7 @@
const intptr_t count = objects_.length();
s->WriteUnsigned(count);
for (intptr_t i = 0; i < count; i++) {
- RawOneByteString* str = objects_[i];
+ OneByteStringPtr str = objects_[i];
s->AssignRef(str);
AutoTraceObject(str);
const intptr_t length = Smi::Value(str->ptr()->length_);
@@ -4545,11 +4530,11 @@
void WriteFill(Serializer* s) {
const intptr_t count = objects_.length();
for (intptr_t i = 0; i < count; i++) {
- RawOneByteString* str = objects_[i];
+ OneByteStringPtr str = objects_[i];
AutoTraceObject(str);
const intptr_t length = Smi::Value(str->ptr()->length_);
s->WriteUnsigned(length);
- s->Write<bool>(str->IsCanonical());
+ s->Write<bool>(str->ptr()->IsCanonical());
intptr_t hash = String::GetCachedHash(str);
s->Write<int32_t>(hash);
s->WriteBytes(str->ptr()->data(), length);
@@ -4557,7 +4542,7 @@
}
private:
- GrowableArray<RawOneByteString*> objects_;
+ GrowableArray<OneByteStringPtr> objects_;
};
#endif // !DART_PRECOMPILED_RUNTIME
@@ -4580,7 +4565,7 @@
void ReadFill(Deserializer* d) {
for (intptr_t id = start_index_; id < stop_index_; id++) {
- RawOneByteString* str = reinterpret_cast<RawOneByteString*>(d->Ref(id));
+ OneByteStringPtr str = static_cast<OneByteStringPtr>(d->Ref(id));
const intptr_t length = d->ReadUnsigned();
bool is_canonical = d->Read<bool>();
Deserializer::InitializeHeader(str, kOneByteStringCid,
@@ -4601,8 +4586,8 @@
TwoByteStringSerializationCluster() : SerializationCluster("TwoByteString") {}
~TwoByteStringSerializationCluster() {}
- void Trace(Serializer* s, RawObject* object) {
- RawTwoByteString* str = reinterpret_cast<RawTwoByteString*>(object);
+ void Trace(Serializer* s, ObjectPtr object) {
+ TwoByteStringPtr str = static_cast<TwoByteStringPtr>(object);
objects_.Add(str);
}
@@ -4611,7 +4596,7 @@
const intptr_t count = objects_.length();
s->WriteUnsigned(count);
for (intptr_t i = 0; i < count; i++) {
- RawTwoByteString* str = objects_[i];
+ TwoByteStringPtr str = objects_[i];
s->AssignRef(str);
AutoTraceObject(str);
const intptr_t length = Smi::Value(str->ptr()->length_);
@@ -4622,11 +4607,11 @@
void WriteFill(Serializer* s) {
const intptr_t count = objects_.length();
for (intptr_t i = 0; i < count; i++) {
- RawTwoByteString* str = objects_[i];
+ TwoByteStringPtr str = objects_[i];
AutoTraceObject(str);
const intptr_t length = Smi::Value(str->ptr()->length_);
s->WriteUnsigned(length);
- s->Write<bool>(str->IsCanonical());
+ s->Write<bool>(str->ptr()->IsCanonical());
intptr_t hash = String::GetCachedHash(str);
s->Write<int32_t>(hash);
s->WriteBytes(reinterpret_cast<uint8_t*>(str->ptr()->data()), length * 2);
@@ -4634,7 +4619,7 @@
}
private:
- GrowableArray<RawTwoByteString*> objects_;
+ GrowableArray<TwoByteStringPtr> objects_;
};
#endif // !DART_PRECOMPILED_RUNTIME
@@ -4657,7 +4642,7 @@
void ReadFill(Deserializer* d) {
for (intptr_t id = start_index_; id < stop_index_; id++) {
- RawTwoByteString* str = reinterpret_cast<RawTwoByteString*>(d->Ref(id));
+ TwoByteStringPtr str = static_cast<TwoByteStringPtr>(d->Ref(id));
const intptr_t length = d->ReadUnsigned();
bool is_canonical = d->Read<bool>();
Deserializer::InitializeHeader(str, kTwoByteStringCid,
@@ -4683,7 +4668,7 @@
}
~FakeSerializationCluster() {}
- void Trace(Serializer* s, RawObject* object) { UNREACHABLE(); }
+ void Trace(Serializer* s, ObjectPtr object) { UNREACHABLE(); }
void WriteAlloc(Serializer* s) { UNREACHABLE(); }
void WriteFill(Serializer* s) { UNREACHABLE(); }
};
@@ -4741,8 +4726,8 @@
}
void Serializer::TraceStartWritingObject(const char* type,
- RawObject* obj,
- RawString* name) {
+ ObjectPtr obj,
+ StringPtr name) {
if (profile_writer_ == nullptr) return;
intptr_t cid = -1;
@@ -4928,9 +4913,9 @@
}
#if !defined(DART_PRECOMPILED_RUNTIME)
-void Serializer::WriteInstructions(RawInstructions* instr,
+void Serializer::WriteInstructions(InstructionsPtr instr,
uint32_t unchecked_offset,
- RawCode* code,
+ CodePtr code,
intptr_t index) {
ASSERT(code != Code::null());
@@ -5010,7 +4995,7 @@
}
}
-uint32_t Serializer::GetDataOffset(RawObject* object) const {
+uint32_t Serializer::GetDataOffset(ObjectPtr object) const {
return image_writer_->GetDataOffsetFor(object);
}
@@ -5021,9 +5006,9 @@
return image_writer_->data_size();
}
-void Serializer::Push(RawObject* object) {
+void Serializer::Push(ObjectPtr object) {
if (!object->IsHeapObject()) {
- RawSmi* smi = Smi::RawCast(object);
+ SmiPtr smi = Smi::RawCast(object);
if (smi_ids_.Lookup(smi) == NULL) {
SmiObjectIdPair pair;
pair.smi_ = smi;
@@ -5066,7 +5051,7 @@
}
}
-void Serializer::Trace(RawObject* object) {
+void Serializer::Trace(ObjectPtr object) {
intptr_t cid;
if (!object->IsHeapObject()) {
// Smis are merged into the Mint cluster because Smis for the writer might
@@ -5097,27 +5082,27 @@
#endif
}
-void Serializer::UnexpectedObject(RawObject* raw_object, const char* message) {
+void Serializer::UnexpectedObject(ObjectPtr raw_object, const char* message) {
// Exit the no safepoint scope so we can allocate while printing.
while (thread()->no_safepoint_scope_depth() > 0) {
thread()->DecrementNoSafepointScopeDepth();
}
Object& object = Object::Handle(raw_object);
OS::PrintErr("Unexpected object (%s, %s): 0x%" Px " %s\n", message,
- Snapshot::KindToCString(kind_),
- reinterpret_cast<uword>(object.raw()), object.ToCString());
+ Snapshot::KindToCString(kind_), static_cast<uword>(object.raw()),
+ object.ToCString());
#if defined(SNAPSHOT_BACKTRACE)
while (!object.IsNull()) {
object = ParentOf(object);
OS::PrintErr("referenced by 0x%" Px " %s\n",
- reinterpret_cast<uword>(object.raw()), object.ToCString());
+ static_cast<uword>(object.raw()), object.ToCString());
}
#endif
OS::Abort();
}
#if defined(SNAPSHOT_BACKTRACE)
-RawObject* Serializer::ParentOf(const Object& object) {
+ObjectPtr Serializer::ParentOf(const Object& object) {
for (intptr_t i = 0; i < parent_pairs_.length(); i += 2) {
if (parent_pairs_[i]->raw() == object.raw()) {
return parent_pairs_[i + 1]->raw();
@@ -5172,18 +5157,18 @@
// We permute the code objects in the [CodeSerializationCluster] so they
// will arrive in the order in which the [Code]'s instructions will be in
// memory at AOT runtime.
- GrowableArray<RawCode*> code_order;
+ GrowableArray<CodePtr> code_order;
RawCodeSet code_set;
for (auto& command : writer_commands) {
if (command.op == ImageWriterCommand::InsertInstructionOfCode) {
- RawCode* code = command.insert_instruction_of_code.code;
+ CodePtr code = command.insert_instruction_of_code.code;
ASSERT(!code_set.HasKey(code));
code_set.Insert(code);
code_order.Add(code);
code_order_length++;
}
}
- for (RawCode* code : *code_objects) {
+ for (CodePtr code : *code_objects) {
if (!code_set.HasKey(code)) {
code_set.Insert(code);
code_order.Add(code);
@@ -5320,8 +5305,8 @@
ASSERT(first_code_id <= compiler::target::kWordMax);
WriteUnsigned(first_code_id);
- RawCode* previous_code = nullptr;
- RawCode* recent[kDispatchTableRecentCount] = {nullptr};
+ CodePtr previous_code = nullptr;
+ CodePtr recent[kDispatchTableRecentCount] = {nullptr};
intptr_t recent_index = 0;
intptr_t repeat_count = 0;
for (intptr_t i = 0; i < table_length; i++) {
@@ -5444,7 +5429,6 @@
AddBaseObject(Object::zero_array().raw(), "Array", "<zero_array>");
AddBaseObject(Object::dynamic_type().raw(), "Type", "<dynamic type>");
AddBaseObject(Object::void_type().raw(), "Type", "<void type>");
- AddBaseObject(Object::never_type().raw(), "Type", "<never type>");
AddBaseObject(Object::empty_type_arguments().raw(), "TypeArguments", "[]");
AddBaseObject(Bool::True().raw(), "bool", "true");
AddBaseObject(Bool::False().raw(), "bool", "false");
@@ -5498,7 +5482,6 @@
}
AddBaseObject(table->At(kDynamicCid), "Class");
AddBaseObject(table->At(kVoidCid), "Class");
- AddBaseObject(table->At(kNeverCid), "Class");
if (!Snapshot::IncludesCode(kind_)) {
for (intptr_t i = 0; i < StubCode::NumEntries(); i++) {
@@ -5569,9 +5552,9 @@
}
// Push roots.
- RawObject** from = object_store->from();
- RawObject** to = object_store->to_snapshot(kind_);
- for (RawObject** p = from; p <= to; p++) {
+ ObjectPtr* from = object_store->from();
+ ObjectPtr* to = object_store->to_snapshot(kind_);
+ for (ObjectPtr* p = from; p <= to; p++) {
Push(*p);
}
@@ -5595,7 +5578,7 @@
Serialize();
// Write roots.
- for (RawObject** p = from; p <= to; p++) {
+ for (ObjectPtr* p = from; p <= to; p++) {
WriteRootRef(*p, kObjectStoreFieldNames[p - from]);
}
@@ -5652,7 +5635,7 @@
kind_(kind),
stream_(buffer, size),
image_reader_(NULL),
- refs_(NULL),
+ refs_(nullptr),
next_ref_index_(1),
clusters_(NULL),
field_table_(thread->isolate()->field_table()) {
@@ -5848,7 +5831,7 @@
#endif
}
-RawApiError* Deserializer::VerifyImageAlignment() {
+ApiErrorPtr Deserializer::VerifyImageAlignment() {
if (image_reader_ != nullptr) {
return image_reader_->VerifyAlignment();
}
@@ -5953,7 +5936,7 @@
return strdup(message);
}
-RawApiError* FullSnapshotReader::ConvertToApiError(char* message) {
+ApiErrorPtr FullSnapshotReader::ConvertToApiError(char* message) {
// This can also fail while bringing up the VM isolate, so make sure to
// allocate the error message in old space.
const String& msg = String::Handle(String::New(message, Heap::kOld));
@@ -5964,7 +5947,7 @@
return ApiError::New(msg, Heap::kOld);
}
-void Deserializer::ReadInstructions(RawCode* code,
+void Deserializer::ReadInstructions(CodePtr code,
intptr_t index,
intptr_t start_index) {
#if defined(DART_PRECOMPILED_RUNTIME)
@@ -5979,7 +5962,7 @@
// object. Thus, retrieve the instructions-related information from there.
ASSERT((index - start_index) >= code_order_length());
const uint32_t source_id = (bare_offset >> 1) + start_index;
- auto const source = reinterpret_cast<RawCode*>(Ref(source_id));
+ auto const source = static_cast<CodePtr>(Ref(source_id));
code->ptr()->entry_point_ = source->ptr()->entry_point_;
code->ptr()->unchecked_entry_point_ =
source->ptr()->unchecked_entry_point_;
@@ -6021,7 +6004,7 @@
ASSERT((index - start_index) < code_order_length());
const uword curr_payload_start = Code::PayloadStartOf(code);
if (index > start_index) {
- auto const prev = reinterpret_cast<RawCode*>(Ref(index - 1));
+ auto const prev = static_cast<CodePtr>(Ref(index - 1));
const uword prev_payload_start = Code::PayloadStartOf(prev);
prev->ptr()->instructions_length_ =
curr_payload_start - prev_payload_start;
@@ -6038,7 +6021,7 @@
#endif
const uint32_t offset = Read<uint32_t>();
- RawInstructions* instr = image_reader_->GetInstructionsAt(offset);
+ InstructionsPtr instr = image_reader_->GetInstructionsAt(offset);
uint32_t unchecked_offset = ReadUnsigned();
code->ptr()->instructions_ = instr;
@@ -6056,7 +6039,7 @@
Code::InitializeCachedEntryPointsFrom(code, instr, unchecked_offset);
}
-RawObject* Deserializer::GetObjectAt(uint32_t offset) const {
+ObjectPtr Deserializer::GetObjectAt(uint32_t offset) const {
return image_reader_->GetObjectAt(offset);
}
@@ -6129,7 +6112,6 @@
AddBaseObject(Object::zero_array().raw());
AddBaseObject(Object::dynamic_type().raw());
AddBaseObject(Object::void_type().raw());
- AddBaseObject(Object::never_type().raw());
AddBaseObject(Object::empty_type_arguments().raw());
AddBaseObject(Bool::True().raw());
AddBaseObject(Bool::False().raw());
@@ -6168,7 +6150,6 @@
}
AddBaseObject(table->At(kDynamicCid));
AddBaseObject(table->At(kVoidCid));
- AddBaseObject(table->At(kNeverCid));
if (!Snapshot::IncludesCode(kind_)) {
for (intptr_t i = 0; i < StubCode::NumEntries(); i++) {
@@ -6244,9 +6225,9 @@
Deserialize();
// Read roots.
- RawObject** from = object_store->from();
- RawObject** to = object_store->to_snapshot(kind_);
- for (RawObject** p = from; p <= to; p++) {
+ ObjectPtr* from = object_store->from();
+ ObjectPtr* to = object_store->to_snapshot(kind_);
+ for (ObjectPtr* p = from; p <= to; p++) {
*p = ReadRef();
}
@@ -6364,11 +6345,11 @@
ASSERT(object_store != NULL);
// These type arguments must always be retained.
- ASSERT(object_store->type_argument_int()->IsCanonical());
- ASSERT(object_store->type_argument_double()->IsCanonical());
- ASSERT(object_store->type_argument_string()->IsCanonical());
- ASSERT(object_store->type_argument_string_dynamic()->IsCanonical());
- ASSERT(object_store->type_argument_string_string()->IsCanonical());
+ ASSERT(object_store->type_argument_int()->ptr()->IsCanonical());
+ ASSERT(object_store->type_argument_double()->ptr()->IsCanonical());
+ ASSERT(object_store->type_argument_string()->ptr()->IsCanonical());
+ ASSERT(object_store->type_argument_string_dynamic()->ptr()->IsCanonical());
+ ASSERT(object_store->type_argument_string_string()->ptr()->IsCanonical());
serializer.ReserveHeader();
serializer.WriteVersionAndFeatures(false);
@@ -6537,7 +6518,7 @@
return nullptr;
}
-RawApiError* FullSnapshotReader::ReadVMSnapshot() {
+ApiErrorPtr FullSnapshotReader::ReadVMSnapshot() {
SnapshotHeaderReader header_reader(kind_, buffer_, size_);
intptr_t offset = 0;
@@ -6549,7 +6530,7 @@
Deserializer deserializer(thread_, kind_, buffer_, size_, data_image_,
instructions_image_, offset);
- RawApiError* api_error = deserializer.VerifyImageAlignment();
+ ApiErrorPtr api_error = deserializer.VerifyImageAlignment();
if (api_error != ApiError::null()) {
return api_error;
}
@@ -6568,7 +6549,7 @@
return ApiError::null();
}
-RawApiError* FullSnapshotReader::ReadProgramSnapshot() {
+ApiErrorPtr FullSnapshotReader::ReadProgramSnapshot() {
SnapshotHeaderReader header_reader(kind_, buffer_, size_);
intptr_t offset = 0;
char* error =
@@ -6579,7 +6560,7 @@
Deserializer deserializer(thread_, kind_, buffer_, size_, data_image_,
instructions_image_, offset);
- RawApiError* api_error = deserializer.VerifyImageAlignment();
+ ApiErrorPtr api_error = deserializer.VerifyImageAlignment();
if (api_error != ApiError::null()) {
return api_error;
}
diff --git a/runtime/vm/clustered_snapshot.h b/runtime/vm/clustered_snapshot.h
index b7da466..d9d4123 100644
--- a/runtime/vm/clustered_snapshot.h
+++ b/runtime/vm/clustered_snapshot.h
@@ -57,7 +57,7 @@
virtual ~SerializationCluster() {}
// Add [object] to the cluster and push its outgoing references.
- virtual void Trace(Serializer* serializer, RawObject* object) = 0;
+ virtual void Trace(Serializer* serializer, ObjectPtr object) = 0;
// Write the cluster type and information needed to allocate the cluster's
// objects. For fixed sized objects, this is just the object count. For
@@ -104,8 +104,8 @@
class SmiObjectIdPair {
public:
- SmiObjectIdPair() : smi_(NULL), id_(0) {}
- RawSmi* smi_;
+ SmiObjectIdPair() : smi_(nullptr), id_(0) {}
+ SmiPtr smi_;
intptr_t id_;
bool operator==(const SmiObjectIdPair& other) const {
@@ -115,7 +115,7 @@
class SmiObjectIdPairTrait {
public:
- typedef RawSmi* Key;
+ typedef SmiPtr Key;
typedef intptr_t Value;
typedef SmiObjectIdPair Pair;
@@ -162,7 +162,7 @@
void AddVMIsolateBaseObjects();
- void AddBaseObject(RawObject* base_object,
+ void AddBaseObject(ObjectPtr base_object,
const char* type = nullptr,
const char* name = nullptr) {
intptr_t ref = AssignRef(base_object);
@@ -181,7 +181,7 @@
}
}
- intptr_t AssignRef(RawObject* object) {
+ intptr_t AssignRef(ObjectPtr object) {
ASSERT(IsAllocatedReference(next_ref_index_));
if (object->IsHeapObject()) {
// The object id weak table holds image offsets for Instructions instead
@@ -190,7 +190,7 @@
heap_->SetObjectId(object, next_ref_index_);
ASSERT(heap_->GetObjectId(object) == next_ref_index_);
} else {
- RawSmi* smi = Smi::RawCast(object);
+ SmiPtr smi = Smi::RawCast(object);
SmiObjectIdPair* existing_pair = smi_ids_.Lookup(smi);
if (existing_pair != NULL) {
ASSERT(existing_pair->id_ == kUnallocatedReference);
@@ -205,15 +205,15 @@
return next_ref_index_++;
}
- void Push(RawObject* object);
+ void Push(ObjectPtr object);
void AddUntracedRef() { num_written_objects_++; }
- void Trace(RawObject* object);
+ void Trace(ObjectPtr object);
- void UnexpectedObject(RawObject* object, const char* message);
+ void UnexpectedObject(ObjectPtr object, const char* message);
#if defined(SNAPSHOT_BACKTRACE)
- RawObject* ParentOf(const Object& object);
+ ObjectPtr ParentOf(const Object& object);
#endif
SerializationCluster* NewClusterForClass(intptr_t cid);
@@ -240,9 +240,7 @@
WriteStream* stream() { return &stream_; }
intptr_t bytes_written() { return stream_.bytes_written(); }
- void TraceStartWritingObject(const char* type,
- RawObject* obj,
- RawString* name);
+ void TraceStartWritingObject(const char* type, ObjectPtr obj, StringPtr name);
void TraceEndWritingObject();
// Writes raw data to the stream (basic type).
@@ -263,7 +261,7 @@
}
void Align(intptr_t alignment) { stream_.Align(alignment); }
- void WriteRootRef(RawObject* object, const char* name = nullptr) {
+ void WriteRootRef(ObjectPtr object, const char* name = nullptr) {
intptr_t id = WriteRefId(object);
WriteUnsigned(id);
if (profile_writer_ != nullptr) {
@@ -271,7 +269,7 @@
}
}
- void WriteElementRef(RawObject* object, intptr_t index) {
+ void WriteElementRef(ObjectPtr object, intptr_t index) {
intptr_t id = WriteRefId(object);
WriteUnsigned(id);
if (profile_writer_ != nullptr) {
@@ -289,7 +287,7 @@
// explicitly connected in the heap, for example an object referenced
// by the global object pool is in reality referenced by the code which
// caused this reference to be added to the global object pool.
- void AttributeElementRef(RawObject* object, intptr_t index) {
+ void AttributeElementRef(ObjectPtr object, intptr_t index) {
intptr_t id = WriteRefId(object);
if (profile_writer_ != nullptr) {
profile_writer_->AttributeReferenceTo(
@@ -300,7 +298,7 @@
}
}
- void WritePropertyRef(RawObject* object, const char* property) {
+ void WritePropertyRef(ObjectPtr object, const char* property) {
intptr_t id = WriteRefId(object);
WriteUnsigned(id);
if (profile_writer_ != nullptr) {
@@ -312,7 +310,7 @@
}
}
- void WriteOffsetRef(RawObject* object, intptr_t offset) {
+ void WriteOffsetRef(ObjectPtr object, intptr_t offset) {
intptr_t id = WriteRefId(object);
WriteUnsigned(id);
if (profile_writer_ != nullptr) {
@@ -335,20 +333,20 @@
}
template <typename T, typename... P>
- void WriteFromTo(T* obj, P&&... args) {
- RawObject** from = obj->from();
- RawObject** to = obj->to_snapshot(kind(), args...);
- for (RawObject** p = from; p <= to; p++) {
- WriteOffsetRef(*p, (p - reinterpret_cast<RawObject**>(obj->ptr())) *
- sizeof(RawObject*));
+ void WriteFromTo(T obj, P&&... args) {
+ ObjectPtr* from = obj->ptr()->from();
+ ObjectPtr* to = obj->ptr()->to_snapshot(kind(), args...);
+ for (ObjectPtr* p = from; p <= to; p++) {
+ WriteOffsetRef(*p, (p - reinterpret_cast<ObjectPtr*>(obj->ptr())) *
+ sizeof(ObjectPtr));
}
}
template <typename T, typename... P>
- void PushFromTo(T* obj, P&&... args) {
- RawObject** from = obj->from();
- RawObject** to = obj->to_snapshot(kind(), args...);
- for (RawObject** p = from; p <= to; p++) {
+ void PushFromTo(T obj, P&&... args) {
+ ObjectPtr* from = obj->ptr()->from();
+ ObjectPtr* to = obj->ptr()->to_snapshot(kind(), args...);
+ for (ObjectPtr* p = from; p <= to; p++) {
Push(*p);
}
}
@@ -358,15 +356,15 @@
}
void WriteCid(intptr_t cid) {
- COMPILE_ASSERT(RawObject::kClassIdTagSize <= 32);
+ COMPILE_ASSERT(ObjectLayout::kClassIdTagSize <= 32);
Write<int32_t>(cid);
}
- void WriteInstructions(RawInstructions* instr,
+ void WriteInstructions(InstructionsPtr instr,
uint32_t unchecked_offset,
- RawCode* code,
+ CodePtr code,
intptr_t index);
- uint32_t GetDataOffset(RawObject* object) const;
+ uint32_t GetDataOffset(ObjectPtr object) const;
void TraceDataOffset(uint32_t offset);
intptr_t GetDataSize() const;
@@ -383,9 +381,9 @@
// Returns the reference ID for the object. Fails for objects that have not
// been allocated a reference ID yet, so should be used only after all
// WriteAlloc calls.
- intptr_t WriteRefId(RawObject* object) {
+ intptr_t WriteRefId(ObjectPtr object) {
if (!object->IsHeapObject()) {
- RawSmi* smi = Smi::RawCast(object);
+ SmiPtr smi = Smi::RawCast(object);
auto const id = smi_ids_.Lookup(smi)->id_;
if (IsAllocatedReference(id)) return id;
FATAL("Missing ref");
@@ -423,7 +421,7 @@
WriteStream stream_;
ImageWriter* image_writer_;
SerializationCluster** clusters_by_cid_;
- GrowableArray<RawObject*> stack_;
+ GrowableArray<ObjectPtr> stack_;
intptr_t num_cids_;
intptr_t num_base_objects_;
intptr_t num_written_objects_;
@@ -438,7 +436,7 @@
V8SnapshotProfileWriter* profile_writer_ = nullptr;
struct ProfilingObject {
- RawObject* object_ = nullptr;
+ ObjectPtr object_ = nullptr;
intptr_t id_ = 0;
intptr_t stream_start_ = 0;
intptr_t cid_ = -1;
@@ -446,7 +444,7 @@
OffsetsTable* offsets_table_ = nullptr;
#if defined(SNAPSHOT_BACKTRACE)
- RawObject* current_parent_;
+ ObjectPtr current_parent_;
GrowableArray<Object*> parent_pairs_;
#endif
@@ -474,8 +472,8 @@
struct SerializerWritingObjectScope {
SerializerWritingObjectScope(Serializer* serializer,
const char* type,
- RawObject* object,
- RawString* name)
+ ObjectPtr object,
+ StringPtr name)
: serializer_(serializer) {
serializer_->TraceStartWritingObject(type, object, name);
}
@@ -537,14 +535,14 @@
//
// Returns ApiError::null() on success and an ApiError with an an appropriate
// message otherwise.
- RawApiError* VerifyImageAlignment();
+ ApiErrorPtr VerifyImageAlignment();
void ReadProgramSnapshot(ObjectStore* object_store);
void ReadVMSnapshot();
void AddVMIsolateBaseObjects();
- static void InitializeHeader(RawObject* raw,
+ static void InitializeHeader(ObjectPtr raw,
intptr_t cid,
intptr_t size,
bool is_canonical = false);
@@ -568,35 +566,35 @@
void Advance(intptr_t value) { stream_.Advance(value); }
void Align(intptr_t alignment) { stream_.Align(alignment); }
- void AddBaseObject(RawObject* base_object) { AssignRef(base_object); }
+ void AddBaseObject(ObjectPtr base_object) { AssignRef(base_object); }
- void AssignRef(RawObject* object) {
+ void AssignRef(ObjectPtr object) {
ASSERT(next_ref_index_ <= num_objects_);
refs_->ptr()->data()[next_ref_index_] = object;
next_ref_index_++;
}
- RawObject* Ref(intptr_t index) const {
+ ObjectPtr Ref(intptr_t index) const {
ASSERT(index > 0);
ASSERT(index <= num_objects_);
return refs_->ptr()->data()[index];
}
- RawObject* ReadRef() { return Ref(ReadUnsigned()); }
+ ObjectPtr ReadRef() { return Ref(ReadUnsigned()); }
template <typename T, typename... P>
- void ReadFromTo(T* obj, P&&... params) {
- RawObject** from = obj->from();
- RawObject** to_snapshot = obj->to_snapshot(kind(), params...);
- RawObject** to = obj->to(params...);
- for (RawObject** p = from; p <= to_snapshot; p++) {
+ void ReadFromTo(T obj, P&&... params) {
+ ObjectPtr* from = obj->ptr()->from();
+ ObjectPtr* to_snapshot = obj->ptr()->to_snapshot(kind(), params...);
+ ObjectPtr* to = obj->ptr()->to(params...);
+ for (ObjectPtr* p = from; p <= to_snapshot; p++) {
*p = ReadRef();
}
// This is necessary because, unlike Object::Allocate, the clustered
// deserializer allocates object without null-initializing them. Instead,
// each deserialization cluster is responsible for initializing every field,
// ensuring that every field is written to exactly once.
- for (RawObject** p = to_snapshot + 1; p <= to; p++) {
+ for (ObjectPtr* p = to_snapshot + 1; p <= to; p++) {
*p = Object::null();
}
}
@@ -606,12 +604,12 @@
}
intptr_t ReadCid() {
- COMPILE_ASSERT(RawObject::kClassIdTagSize <= 32);
+ COMPILE_ASSERT(ObjectLayout::kClassIdTagSize <= 32);
return Read<int32_t>();
}
- void ReadInstructions(RawCode* code, intptr_t index, intptr_t start_index);
- RawObject* GetObjectAt(uint32_t offset) const;
+ void ReadInstructions(CodePtr code, intptr_t index, intptr_t start_index);
+ ObjectPtr GetObjectAt(uint32_t offset) const;
void SkipHeader() { stream_.SetPosition(Snapshot::kHeaderSize); }
@@ -652,7 +650,7 @@
intptr_t num_objects_;
intptr_t num_clusters_;
intptr_t code_order_length_ = 0;
- RawArray* refs_;
+ ArrayPtr refs_;
intptr_t next_ref_index_;
DeserializationCluster** clusters_;
FieldTable* field_table_;
@@ -723,11 +721,11 @@
Thread* thread);
~FullSnapshotReader() {}
- RawApiError* ReadVMSnapshot();
- RawApiError* ReadProgramSnapshot();
+ ApiErrorPtr ReadVMSnapshot();
+ ApiErrorPtr ReadProgramSnapshot();
private:
- RawApiError* ConvertToApiError(char* message);
+ ApiErrorPtr ConvertToApiError(char* message);
Snapshot::Kind kind_;
Thread* thread_;
diff --git a/runtime/vm/code_descriptors.cc b/runtime/vm/code_descriptors.cc
index d773325..1a5a5f2 100644
--- a/runtime/vm/code_descriptors.cc
+++ b/runtime/vm/code_descriptors.cc
@@ -11,7 +11,7 @@
namespace dart {
-void DescriptorList::AddDescriptor(RawPcDescriptors::Kind kind,
+void DescriptorList::AddDescriptor(PcDescriptorsLayout::Kind kind,
intptr_t pc_offset,
intptr_t deopt_id,
TokenPosition token_pos,
@@ -20,19 +20,20 @@
// yield index 0 is reserved for normal entry.
RELEASE_ASSERT(yield_index != 0);
- ASSERT((kind == RawPcDescriptors::kRuntimeCall) ||
- (kind == RawPcDescriptors::kBSSRelocation) ||
- (kind == RawPcDescriptors::kOther) ||
- (yield_index != RawPcDescriptors::kInvalidYieldIndex) ||
+ ASSERT((kind == PcDescriptorsLayout::kRuntimeCall) ||
+ (kind == PcDescriptorsLayout::kBSSRelocation) ||
+ (kind == PcDescriptorsLayout::kOther) ||
+ (yield_index != PcDescriptorsLayout::kInvalidYieldIndex) ||
(deopt_id != DeoptId::kNone));
// When precompiling, we only use pc descriptors for exceptions,
// relocations and yield indices.
if (!FLAG_precompiled_mode || try_index != -1 ||
- yield_index != RawPcDescriptors::kInvalidYieldIndex ||
- kind == RawPcDescriptors::kBSSRelocation) {
+ yield_index != PcDescriptorsLayout::kInvalidYieldIndex ||
+ kind == PcDescriptorsLayout::kBSSRelocation) {
const int32_t kind_and_metadata =
- RawPcDescriptors::KindAndMetadata::Encode(kind, try_index, yield_index);
+ PcDescriptorsLayout::KindAndMetadata::Encode(kind, try_index,
+ yield_index);
PcDescriptors::EncodeInteger(&encoded_data_, kind_and_metadata);
PcDescriptors::EncodeInteger(&encoded_data_, pc_offset - prev_pc_offset);
@@ -48,7 +49,7 @@
}
}
-RawPcDescriptors* DescriptorList::FinalizePcDescriptors(uword entry_point) {
+PcDescriptorsPtr DescriptorList::FinalizePcDescriptors(uword entry_point) {
if (encoded_data_.length() == 0) {
return Object::empty_descriptors().raw();
}
@@ -82,7 +83,7 @@
last_pc_offset_ = pc_offset;
}
-RawCompressedStackMaps* CompressedStackMapsBuilder::Finalize() const {
+CompressedStackMapsPtr CompressedStackMapsBuilder::Finalize() const {
if (encoded_bytes_.length() == 0) return CompressedStackMaps::null();
return CompressedStackMaps::NewInlined(encoded_bytes_);
}
@@ -248,7 +249,7 @@
return ToCString(Thread::Current()->zone());
}
-RawExceptionHandlers* ExceptionHandlerList::FinalizeExceptionHandlers(
+ExceptionHandlersPtr ExceptionHandlerList::FinalizeExceptionHandlers(
uword entry_point) const {
intptr_t num_handlers = Length();
if (num_handlers == 0) {
@@ -360,7 +361,7 @@
}
}
-RawTypedData* CatchEntryMovesMapBuilder::FinalizeCatchEntryMovesMap() {
+TypedDataPtr CatchEntryMovesMapBuilder::FinalizeCatchEntryMovesMap() {
TypedData& td = TypedData::Handle(TypedData::New(
kTypedDataInt8ArrayCid, stream_.bytes_written(), Heap::kOld));
NoSafepointScope no_safepoint;
@@ -518,12 +519,12 @@
BufferAdvancePC(pc_offset - buffered_pc_offset_);
}
-void CodeSourceMapBuilder::NoteDescriptor(RawPcDescriptors::Kind kind,
+void CodeSourceMapBuilder::NoteDescriptor(PcDescriptorsLayout::Kind kind,
int32_t pc_offset,
TokenPosition pos) {
const uint8_t kCanThrow =
- RawPcDescriptors::kIcCall | RawPcDescriptors::kUnoptStaticCall |
- RawPcDescriptors::kRuntimeCall | RawPcDescriptors::kOther;
+ PcDescriptorsLayout::kIcCall | PcDescriptorsLayout::kUnoptStaticCall |
+ PcDescriptorsLayout::kRuntimeCall | PcDescriptorsLayout::kOther;
if ((kind & kCanThrow) != 0) {
BufferChangePosition(pos);
BufferAdvancePC(pc_offset - buffered_pc_offset_);
@@ -552,14 +553,14 @@
return inlined_functions_.Length() - 1;
}
-RawArray* CodeSourceMapBuilder::InliningIdToFunction() {
+ArrayPtr CodeSourceMapBuilder::InliningIdToFunction() {
if (inlined_functions_.Length() == 0) {
return Object::empty_array().raw();
}
return Array::MakeFixedLength(inlined_functions_);
}
-RawCodeSourceMap* CodeSourceMapBuilder::Finalize() {
+CodeSourceMapPtr CodeSourceMapBuilder::Finalize() {
if (!stack_traces_only_) {
FlushBuffer();
}
diff --git a/runtime/vm/code_descriptors.h b/runtime/vm/code_descriptors.h
index be33407..4ad6723 100644
--- a/runtime/vm/code_descriptors.h
+++ b/runtime/vm/code_descriptors.h
@@ -26,14 +26,14 @@
~DescriptorList() {}
- void AddDescriptor(RawPcDescriptors::Kind kind,
+ void AddDescriptor(PcDescriptorsLayout::Kind kind,
intptr_t pc_offset,
intptr_t deopt_id,
TokenPosition token_pos,
intptr_t try_index,
intptr_t yield_index);
- RawPcDescriptors* FinalizePcDescriptors(uword entry_point);
+ PcDescriptorsPtr FinalizePcDescriptors(uword entry_point);
private:
GrowableArray<uint8_t> encoded_data_;
@@ -55,7 +55,7 @@
BitmapBuilder* bitmap,
intptr_t spill_slot_bit_count);
- RawCompressedStackMaps* Finalize() const;
+ CompressedStackMapsPtr Finalize() const;
private:
intptr_t last_pc_offset_ = 0;
@@ -199,7 +199,7 @@
return false;
}
- RawExceptionHandlers* FinalizeExceptionHandlers(uword entry_point) const;
+ ExceptionHandlersPtr FinalizeExceptionHandlers(uword entry_point) const;
private:
GrowableArray<struct HandlerDesc> list_;
@@ -215,7 +215,7 @@
void NewMapping(intptr_t pc_offset);
void Append(const CatchEntryMove& move);
void EndMapping();
- RawTypedData* FinalizeCatchEntryMovesMap();
+ TypedDataPtr FinalizeCatchEntryMovesMap();
private:
class TrieNode;
@@ -263,13 +263,13 @@
void StartInliningInterval(int32_t pc_offset, intptr_t inline_id);
void BeginCodeSourceRange(int32_t pc_offset);
void EndCodeSourceRange(int32_t pc_offset, TokenPosition pos);
- void NoteDescriptor(RawPcDescriptors::Kind kind,
+ void NoteDescriptor(PcDescriptorsLayout::Kind kind,
int32_t pc_offset,
TokenPosition pos);
void NoteNullCheck(int32_t pc_offset, TokenPosition pos, intptr_t name_index);
- RawArray* InliningIdToFunction();
- RawCodeSourceMap* Finalize();
+ ArrayPtr InliningIdToFunction();
+ CodeSourceMapPtr Finalize();
private:
intptr_t GetFunctionId(intptr_t inline_id);
diff --git a/runtime/vm/code_descriptors_test.cc b/runtime/vm/code_descriptors_test.cc
index 8d5a376..512537e 100644
--- a/runtime/vm/code_descriptors_test.cc
+++ b/runtime/vm/code_descriptors_test.cc
@@ -96,7 +96,8 @@
const PcDescriptors& descriptors =
PcDescriptors::Handle(code.pc_descriptors());
int call_count = 0;
- PcDescriptors::Iterator iter(descriptors, RawPcDescriptors::kUnoptStaticCall);
+ PcDescriptors::Iterator iter(descriptors,
+ PcDescriptorsLayout::kUnoptStaticCall);
CompressedStackMapsBuilder compressed_maps_builder;
while (iter.MoveNext()) {
compressed_maps_builder.AddEntry(iter.PcOffset(), stack_bitmap, 0);
@@ -142,7 +143,7 @@
sizeof(token_positions) / sizeof(token_positions[0]);
for (intptr_t i = 0; i < num_token_positions; i++) {
- descriptors->AddDescriptor(RawPcDescriptors::kRuntimeCall, 0, 0,
+ descriptors->AddDescriptor(PcDescriptorsLayout::kRuntimeCall, 0, 0,
TokenPosition(token_positions[i]), 0, 1);
}
@@ -151,7 +152,7 @@
ASSERT(!finalized_descriptors.IsNull());
PcDescriptors::Iterator it(finalized_descriptors,
- RawPcDescriptors::kRuntimeCall);
+ PcDescriptorsLayout::kRuntimeCall);
intptr_t i = 0;
while (it.MoveNext()) {
diff --git a/runtime/vm/code_patcher.h b/runtime/vm/code_patcher.h
index b9cc1c9..ba7ff04 100644
--- a/runtime/vm/code_patcher.h
+++ b/runtime/vm/code_patcher.h
@@ -14,10 +14,6 @@
// Forward declaration.
class Code;
class ICData;
-class RawArray;
-class RawCode;
-class RawFunction;
-class RawObject;
#if defined(TARGET_ARCH_IA32)
// Stack-allocated class to create a scope where the specified region
@@ -47,13 +43,13 @@
// Return the target address of the static call before return_address
// in given code.
- static RawCode* GetStaticCallTargetAt(uword return_address, const Code& code);
+ static CodePtr GetStaticCallTargetAt(uword return_address, const Code& code);
// Get instance call information. Returns the call target and sets the output
// parameter data if non-NULL.
- static RawCode* GetInstanceCallAt(uword return_address,
- const Code& caller_code,
- Object* data);
+ static CodePtr GetInstanceCallAt(uword return_address,
+ const Code& caller_code,
+ Object* data);
// Change the state of an instance call by patching the corresponding object
// pool entries (non-IA32) or instructions (IA32).
@@ -69,9 +65,9 @@
// Return target of an unoptimized static call and its ICData object
// (calls target via a stub).
- static RawFunction* GetUnoptimizedStaticCallAt(uword return_address,
- const Code& code,
- ICData* ic_data);
+ static FunctionPtr GetUnoptimizedStaticCallAt(uword return_address,
+ const Code& code,
+ ICData* ic_data);
static void InsertDeoptimizationCallAt(uword start);
@@ -88,14 +84,14 @@
const Code& caller_code,
const Object& data,
const Code& target);
- static RawObject* GetSwitchableCallDataAt(uword return_address,
- const Code& caller_code);
- static RawCode* GetSwitchableCallTargetAt(uword return_address,
- const Code& caller_code);
+ static ObjectPtr GetSwitchableCallDataAt(uword return_address,
+ const Code& caller_code);
+ static CodePtr GetSwitchableCallTargetAt(uword return_address,
+ const Code& caller_code);
- static RawCode* GetNativeCallAt(uword return_address,
- const Code& caller_code,
- NativeFunction* target);
+ static CodePtr GetNativeCallAt(uword return_address,
+ const Code& caller_code,
+ NativeFunction* target);
static void PatchNativeCallAt(uword return_address,
const Code& caller_code,
diff --git a/runtime/vm/code_patcher_arm.cc b/runtime/vm/code_patcher_arm.cc
index 52bdb2c..38729b1 100644
--- a/runtime/vm/code_patcher_arm.cc
+++ b/runtime/vm/code_patcher_arm.cc
@@ -12,8 +12,8 @@
namespace dart {
-RawCode* CodePatcher::GetStaticCallTargetAt(uword return_address,
- const Code& code) {
+CodePtr CodePatcher::GetStaticCallTargetAt(uword return_address,
+ const Code& code) {
ASSERT(code.ContainsInstructionAt(return_address));
CallPattern call(return_address, code);
return call.TargetCode();
@@ -31,9 +31,9 @@
UNREACHABLE();
}
-RawCode* CodePatcher::GetInstanceCallAt(uword return_address,
- const Code& caller_code,
- Object* data) {
+CodePtr CodePatcher::GetInstanceCallAt(uword return_address,
+ const Code& caller_code,
+ Object* data) {
ASSERT(caller_code.ContainsInstructionAt(return_address));
ICCallPattern call(return_address, caller_code);
if (data != NULL) {
@@ -65,9 +65,9 @@
call.SetTargetCode(target);
}
-RawFunction* CodePatcher::GetUnoptimizedStaticCallAt(uword return_address,
- const Code& caller_code,
- ICData* ic_data_result) {
+FunctionPtr CodePatcher::GetUnoptimizedStaticCallAt(uword return_address,
+ const Code& caller_code,
+ ICData* ic_data_result) {
ASSERT(caller_code.ContainsInstructionAt(return_address));
ICCallPattern static_call(return_address, caller_code);
ICData& ic_data = ICData::Handle();
@@ -108,8 +108,8 @@
}
}
-RawCode* CodePatcher::GetSwitchableCallTargetAt(uword return_address,
- const Code& caller_code) {
+CodePtr CodePatcher::GetSwitchableCallTargetAt(uword return_address,
+ const Code& caller_code) {
ASSERT(caller_code.ContainsInstructionAt(return_address));
if (FLAG_precompiled_mode && FLAG_use_bare_instructions) {
BareSwitchableCallPattern call(return_address, caller_code);
@@ -120,8 +120,8 @@
}
}
-RawObject* CodePatcher::GetSwitchableCallDataAt(uword return_address,
- const Code& caller_code) {
+ObjectPtr CodePatcher::GetSwitchableCallDataAt(uword return_address,
+ const Code& caller_code) {
ASSERT(caller_code.ContainsInstructionAt(return_address));
if (FLAG_precompiled_mode && FLAG_use_bare_instructions) {
BareSwitchableCallPattern call(return_address, caller_code);
@@ -144,9 +144,9 @@
});
}
-RawCode* CodePatcher::GetNativeCallAt(uword return_address,
- const Code& code,
- NativeFunction* target) {
+CodePtr CodePatcher::GetNativeCallAt(uword return_address,
+ const Code& code,
+ NativeFunction* target) {
ASSERT(code.ContainsInstructionAt(return_address));
NativeCallPattern call(return_address, code);
*target = call.native_function();
diff --git a/runtime/vm/code_patcher_arm64.cc b/runtime/vm/code_patcher_arm64.cc
index abffa1b..824274a 100644
--- a/runtime/vm/code_patcher_arm64.cc
+++ b/runtime/vm/code_patcher_arm64.cc
@@ -24,8 +24,8 @@
intptr_t pp_index() const { return index_; }
- RawCode* Target() const {
- return reinterpret_cast<RawCode*>(object_pool_.ObjectAt(pp_index()));
+ CodePtr Target() const {
+ return static_cast<CodePtr>(object_pool_.ObjectAt(pp_index()));
}
void SetTarget(const Code& target) const {
@@ -42,8 +42,8 @@
DISALLOW_IMPLICIT_CONSTRUCTORS(PoolPointerCall);
};
-RawCode* CodePatcher::GetStaticCallTargetAt(uword return_address,
- const Code& code) {
+CodePtr CodePatcher::GetStaticCallTargetAt(uword return_address,
+ const Code& code) {
ASSERT(code.ContainsInstructionAt(return_address));
PoolPointerCall call(return_address, code);
return call.Target();
@@ -67,9 +67,9 @@
UNREACHABLE();
}
-RawCode* CodePatcher::GetInstanceCallAt(uword return_address,
- const Code& caller_code,
- Object* data) {
+CodePtr CodePatcher::GetInstanceCallAt(uword return_address,
+ const Code& caller_code,
+ Object* data) {
ASSERT(caller_code.ContainsInstructionAt(return_address));
ICCallPattern call(return_address, caller_code);
if (data != NULL) {
@@ -101,9 +101,9 @@
call.SetTargetCode(target);
}
-RawFunction* CodePatcher::GetUnoptimizedStaticCallAt(uword return_address,
- const Code& code,
- ICData* ic_data_result) {
+FunctionPtr CodePatcher::GetUnoptimizedStaticCallAt(uword return_address,
+ const Code& code,
+ ICData* ic_data_result) {
ASSERT(code.ContainsInstructionAt(return_address));
ICCallPattern static_call(return_address, code);
ICData& ic_data = ICData::Handle();
@@ -144,8 +144,8 @@
}
}
-RawCode* CodePatcher::GetSwitchableCallTargetAt(uword return_address,
- const Code& caller_code) {
+CodePtr CodePatcher::GetSwitchableCallTargetAt(uword return_address,
+ const Code& caller_code) {
ASSERT(caller_code.ContainsInstructionAt(return_address));
if (FLAG_precompiled_mode && FLAG_use_bare_instructions) {
BareSwitchableCallPattern call(return_address, caller_code);
@@ -156,8 +156,8 @@
}
}
-RawObject* CodePatcher::GetSwitchableCallDataAt(uword return_address,
- const Code& caller_code) {
+ObjectPtr CodePatcher::GetSwitchableCallDataAt(uword return_address,
+ const Code& caller_code) {
ASSERT(caller_code.ContainsInstructionAt(return_address));
if (FLAG_precompiled_mode && FLAG_use_bare_instructions) {
BareSwitchableCallPattern call(return_address, caller_code);
@@ -180,9 +180,9 @@
});
}
-RawCode* CodePatcher::GetNativeCallAt(uword return_address,
- const Code& caller_code,
- NativeFunction* target) {
+CodePtr CodePatcher::GetNativeCallAt(uword return_address,
+ const Code& caller_code,
+ NativeFunction* target) {
ASSERT(caller_code.ContainsInstructionAt(return_address));
NativeCallPattern call(return_address, caller_code);
*target = call.native_function();
diff --git a/runtime/vm/code_patcher_arm64_test.cc b/runtime/vm/code_patcher_arm64_test.cc
index de240e2..135452e 100644
--- a/runtime/vm/code_patcher_arm64_test.cc
+++ b/runtime/vm/code_patcher_arm64_test.cc
@@ -29,8 +29,8 @@
const String& function_name =
String::Handle(Symbols::New(thread, "callerFunction"));
const Function& function = Function::Handle(Function::New(
- function_name, RawFunction::kRegularFunction, true, false, false, false,
- false, owner_class, TokenPosition::kNoSource));
+ function_name, FunctionLayout::kRegularFunction, true, false, false,
+ false, false, owner_class, TokenPosition::kNoSource));
const String& target_name = String::Handle(String::New("targetFunction"));
const intptr_t kTypeArgsLen = 0;
diff --git a/runtime/vm/code_patcher_arm_test.cc b/runtime/vm/code_patcher_arm_test.cc
index 2e31dc8..96c34e6 100644
--- a/runtime/vm/code_patcher_arm_test.cc
+++ b/runtime/vm/code_patcher_arm_test.cc
@@ -29,8 +29,8 @@
const String& function_name =
String::Handle(Symbols::New(thread, "callerFunction"));
const Function& function = Function::Handle(Function::New(
- function_name, RawFunction::kRegularFunction, true, false, false, false,
- false, owner_class, TokenPosition::kNoSource));
+ function_name, FunctionLayout::kRegularFunction, true, false, false,
+ false, false, owner_class, TokenPosition::kNoSource));
const String& target_name = String::Handle(String::New("targetFunction"));
const intptr_t kTypeArgsLen = 0;
diff --git a/runtime/vm/code_patcher_ia32.cc b/runtime/vm/code_patcher_ia32.cc
index a82d378..3c886ba 100644
--- a/runtime/vm/code_patcher_ia32.cc
+++ b/runtime/vm/code_patcher_ia32.cc
@@ -26,8 +26,8 @@
ASSERT(IsValid());
}
- RawObject* ic_data() const {
- return *reinterpret_cast<RawObject**>(start_ + 1);
+ ObjectPtr ic_data() const {
+ return *reinterpret_cast<ObjectPtr*>(start_ + 1);
}
static const int kMovInstructionSize = 5;
@@ -89,20 +89,20 @@
#endif // DEBUG
}
- RawObject* data() const { return *reinterpret_cast<RawObject**>(start_ + 1); }
+ ObjectPtr data() const { return *reinterpret_cast<ObjectPtr*>(start_ + 1); }
void set_data(const Object& data) const {
uword* cache_addr = reinterpret_cast<uword*>(start_ + 1);
- uword imm = reinterpret_cast<uword>(data.raw());
+ uword imm = static_cast<uword>(data.raw());
*cache_addr = imm;
}
- RawCode* target() const {
+ CodePtr target() const {
const uword imm = *reinterpret_cast<uword*>(start_ + 6);
- return reinterpret_cast<RawCode*>(imm);
+ return static_cast<CodePtr>(imm);
}
void set_target(const Code& target) const {
uword* target_addr = reinterpret_cast<uword*>(start_ + 6);
- uword imm = reinterpret_cast<uword>(target.raw());
+ uword imm = static_cast<uword>(target.raw());
*target_addr = imm;
}
@@ -142,14 +142,14 @@
return (code_bytes[0] == 0xBF) && (code_bytes[5] == 0xFF);
}
- RawCode* target() const {
+ CodePtr target() const {
const uword imm = *reinterpret_cast<uword*>(start_ + 1);
- return reinterpret_cast<RawCode*>(imm);
+ return static_cast<CodePtr>(imm);
}
void set_target(const Code& target) const {
uword* target_addr = reinterpret_cast<uword*>(start_ + 1);
- uword imm = reinterpret_cast<uword>(target.raw());
+ uword imm = static_cast<uword>(target.raw());
*target_addr = imm;
CPU::FlushICache(start_ + 1, sizeof(imm));
}
@@ -169,8 +169,8 @@
DISALLOW_IMPLICIT_CONSTRUCTORS(StaticCall);
};
-RawCode* CodePatcher::GetStaticCallTargetAt(uword return_address,
- const Code& code) {
+CodePtr CodePatcher::GetStaticCallTargetAt(uword return_address,
+ const Code& code) {
ASSERT(code.ContainsInstructionAt(return_address));
StaticCall call(return_address);
return call.target();
@@ -194,9 +194,9 @@
UNREACHABLE();
}
-RawCode* CodePatcher::GetInstanceCallAt(uword return_address,
- const Code& caller_code,
- Object* data) {
+CodePtr CodePatcher::GetInstanceCallAt(uword return_address,
+ const Code& caller_code,
+ Object* data) {
ASSERT(caller_code.ContainsInstructionAt(return_address));
InstanceCall call(return_address);
if (data != NULL) {
@@ -232,9 +232,9 @@
call.set_target(target);
}
-RawFunction* CodePatcher::GetUnoptimizedStaticCallAt(uword return_address,
- const Code& caller_code,
- ICData* ic_data_result) {
+FunctionPtr CodePatcher::GetUnoptimizedStaticCallAt(uword return_address,
+ const Code& caller_code,
+ ICData* ic_data_result) {
ASSERT(caller_code.ContainsInstructionAt(return_address));
UnoptimizedStaticCall static_call(return_address);
ICData& ic_data = ICData::Handle();
@@ -263,15 +263,15 @@
UNREACHABLE();
}
-RawCode* CodePatcher::GetSwitchableCallTargetAt(uword return_address,
- const Code& caller_code) {
+CodePtr CodePatcher::GetSwitchableCallTargetAt(uword return_address,
+ const Code& caller_code) {
// Switchable instance calls only generated for precompilation.
UNREACHABLE();
return Code::null();
}
-RawObject* CodePatcher::GetSwitchableCallDataAt(uword return_address,
- const Code& caller_code) {
+ObjectPtr CodePatcher::GetSwitchableCallDataAt(uword return_address,
+ const Code& caller_code) {
// Switchable instance calls only generated for precompilation.
UNREACHABLE();
return Object::null();
@@ -284,9 +284,9 @@
UNREACHABLE();
}
-RawCode* CodePatcher::GetNativeCallAt(uword return_address,
- const Code& caller_code,
- NativeFunction* target) {
+CodePtr CodePatcher::GetNativeCallAt(uword return_address,
+ const Code& caller_code,
+ NativeFunction* target) {
UNREACHABLE();
return NULL;
}
diff --git a/runtime/vm/code_patcher_ia32_test.cc b/runtime/vm/code_patcher_ia32_test.cc
index 8aa1cd6..812f485 100644
--- a/runtime/vm/code_patcher_ia32_test.cc
+++ b/runtime/vm/code_patcher_ia32_test.cc
@@ -29,8 +29,8 @@
const String& function_name =
String::Handle(Symbols::New(thread, "callerFunction"));
const Function& function = Function::Handle(Function::New(
- function_name, RawFunction::kRegularFunction, true, false, false, false,
- false, owner_class, TokenPosition::kNoSource));
+ function_name, FunctionLayout::kRegularFunction, true, false, false,
+ false, false, owner_class, TokenPosition::kNoSource));
const String& target_name = String::Handle(String::New("targetFunction"));
const intptr_t kTypeArgsLen = 0;
diff --git a/runtime/vm/code_patcher_x64.cc b/runtime/vm/code_patcher_x64.cc
index b4c241c..d9062a4 100644
--- a/runtime/vm/code_patcher_x64.cc
+++ b/runtime/vm/code_patcher_x64.cc
@@ -75,7 +75,7 @@
intptr_t argument_index() const { return argument_index_; }
- RawCode* target() const {
+ CodePtr target() const {
Code& code = Code::Handle();
code ^= object_pool_.ObjectAt(code_index_);
return code.raw();
@@ -128,7 +128,7 @@
#endif // DEBUG
}
- RawObject* data() const { return object_pool_.ObjectAt(argument_index()); }
+ ObjectPtr data() const { return object_pool_.ObjectAt(argument_index()); }
void set_data(const Object& data) const {
ASSERT(data.IsArray() || data.IsICData() || data.IsMegamorphicCache());
object_pool_.SetObjectAt(argument_index(), data);
@@ -149,7 +149,7 @@
#endif // DEBUG
}
- RawObject* ic_data() const { return object_pool_.ObjectAt(argument_index()); }
+ ObjectPtr ic_data() const { return object_pool_.ObjectAt(argument_index()); }
private:
DISALLOW_IMPLICIT_CONSTRUCTORS(UnoptimizedStaticCall);
@@ -194,7 +194,7 @@
ASSERT(Object::Handle(object_pool_.ObjectAt(code_index_)).IsCode());
}
- RawCode* Target() const {
+ CodePtr Target() const {
Code& code = Code::Handle();
code ^= object_pool_.ObjectAt(code_index_);
return code.raw();
@@ -228,7 +228,7 @@
intptr_t data_index() const { return data_index_; }
intptr_t target_index() const { return target_index_; }
- RawObject* data() const { return object_pool_.ObjectAt(data_index()); }
+ ObjectPtr data() const { return object_pool_.ObjectAt(data_index()); }
void SetData(const Object& data) const {
ASSERT(!Object::Handle(object_pool_.ObjectAt(data_index())).IsCode());
@@ -321,8 +321,8 @@
// No need to flush the instruction cache, since the code is not modified.
}
- RawCode* target() const {
- return reinterpret_cast<RawCode*>(object_pool_.ObjectAt(target_index()));
+ CodePtr target() const {
+ return static_cast<CodePtr>(object_pool_.ObjectAt(target_index()));
}
};
@@ -395,13 +395,13 @@
object_pool_.SetRawValueAt(target_index(), target.MonomorphicEntryPoint());
}
- RawCode* target() const {
+ CodePtr target() const {
const uword pc = object_pool_.RawValueAt(target_index());
- auto rct = Isolate::Current()->reverse_pc_lookup_cache();
+ auto rct = IsolateGroup::Current()->reverse_pc_lookup_cache();
if (rct->Contains(pc)) {
return rct->Lookup(pc);
}
- rct = Dart::vm_isolate()->reverse_pc_lookup_cache();
+ rct = Dart::vm_isolate()->group()->reverse_pc_lookup_cache();
if (rct->Contains(pc)) {
return rct->Lookup(pc);
}
@@ -409,8 +409,8 @@
}
};
-RawCode* CodePatcher::GetStaticCallTargetAt(uword return_address,
- const Code& code) {
+CodePtr CodePatcher::GetStaticCallTargetAt(uword return_address,
+ const Code& code) {
ASSERT(code.ContainsInstructionAt(return_address));
PoolPointerCall call(return_address, code);
return call.Target();
@@ -430,9 +430,9 @@
call.SetTarget(new_target);
}
-RawCode* CodePatcher::GetInstanceCallAt(uword return_address,
- const Code& caller_code,
- Object* data) {
+CodePtr CodePatcher::GetInstanceCallAt(uword return_address,
+ const Code& caller_code,
+ Object* data) {
ASSERT(caller_code.ContainsInstructionAt(return_address));
InstanceCall call(return_address, caller_code);
if (data != NULL) {
@@ -468,9 +468,9 @@
UNREACHABLE();
}
-RawFunction* CodePatcher::GetUnoptimizedStaticCallAt(uword return_address,
- const Code& caller_code,
- ICData* ic_data_result) {
+FunctionPtr CodePatcher::GetUnoptimizedStaticCallAt(uword return_address,
+ const Code& caller_code,
+ ICData* ic_data_result) {
ASSERT(caller_code.ContainsInstructionAt(return_address));
UnoptimizedStaticCall static_call(return_address, caller_code);
ICData& ic_data = ICData::Handle();
@@ -511,8 +511,8 @@
}
}
-RawCode* CodePatcher::GetSwitchableCallTargetAt(uword return_address,
- const Code& caller_code) {
+CodePtr CodePatcher::GetSwitchableCallTargetAt(uword return_address,
+ const Code& caller_code) {
ASSERT(caller_code.ContainsInstructionAt(return_address));
if (FLAG_precompiled_mode && FLAG_use_bare_instructions) {
BareSwitchableCall call(return_address, caller_code);
@@ -523,8 +523,8 @@
}
}
-RawObject* CodePatcher::GetSwitchableCallDataAt(uword return_address,
- const Code& caller_code) {
+ObjectPtr CodePatcher::GetSwitchableCallDataAt(uword return_address,
+ const Code& caller_code) {
ASSERT(caller_code.ContainsInstructionAt(return_address));
if (FLAG_precompiled_mode && FLAG_use_bare_instructions) {
BareSwitchableCall call(return_address, caller_code);
@@ -547,9 +547,9 @@
});
}
-RawCode* CodePatcher::GetNativeCallAt(uword return_address,
- const Code& caller_code,
- NativeFunction* target) {
+CodePtr CodePatcher::GetNativeCallAt(uword return_address,
+ const Code& caller_code,
+ NativeFunction* target) {
ASSERT(caller_code.ContainsInstructionAt(return_address));
NativeCall call(return_address, caller_code);
*target = call.native_function();
diff --git a/runtime/vm/code_patcher_x64_test.cc b/runtime/vm/code_patcher_x64_test.cc
index e838880..d00b53c 100644
--- a/runtime/vm/code_patcher_x64_test.cc
+++ b/runtime/vm/code_patcher_x64_test.cc
@@ -29,8 +29,8 @@
const String& function_name =
String::Handle(Symbols::New(thread, "callerFunction"));
const Function& function = Function::Handle(Function::New(
- function_name, RawFunction::kRegularFunction, true, false, false, false,
- false, owner_class, TokenPosition::kNoSource));
+ function_name, FunctionLayout::kRegularFunction, true, false, false,
+ false, false, owner_class, TokenPosition::kNoSource));
const String& target_name = String::Handle(String::New("targetFunction"));
const intptr_t kTypeArgsLen = 0;
diff --git a/runtime/vm/compilation_trace.cc b/runtime/vm/compilation_trace.cc
index 1846638..174c252 100644
--- a/runtime/vm/compilation_trace.cc
+++ b/runtime/vm/compilation_trace.cc
@@ -79,8 +79,7 @@
return NULL;
}
-RawObject* CompilationTraceLoader::CompileTrace(uint8_t* buffer,
- intptr_t size) {
+ObjectPtr CompilationTraceLoader::CompileTrace(uint8_t* buffer, intptr_t size) {
// First compile functions named in the trace.
char* cursor = reinterpret_cast<char*>(buffer);
char* limit = cursor + size;
@@ -125,7 +124,7 @@
arguments_descriptor = ArgumentsDescriptor::NewBoxed(kTypeArgsLen, argc);
dispatcher = closure_class.GetInvocationDispatcher(
Symbols::Call(), arguments_descriptor,
- RawFunction::kInvokeFieldDispatcher, true /* create_if_absent */);
+ FunctionLayout::kInvokeFieldDispatcher, true /* create_if_absent */);
error_ = CompileFunction(dispatcher);
if (error_.IsError()) {
return error_.raw();
@@ -160,9 +159,9 @@
// compile the getter, create its method extractor and compile that.
// - If looking for a getter and we only have a const field, evaluate the const
// field.
-RawObject* CompilationTraceLoader::CompileTriple(const char* uri_cstr,
- const char* cls_cstr,
- const char* func_cstr) {
+ObjectPtr CompilationTraceLoader::CompileTriple(const char* uri_cstr,
+ const char* cls_cstr,
+ const char* func_cstr) {
uri_ = Symbols::New(thread_, uri_cstr);
class_name_ = Symbols::New(thread_, cls_cstr);
function_name_ = Symbols::New(thread_, func_cstr);
@@ -363,7 +362,7 @@
return Object::null();
}
-RawObject* CompilationTraceLoader::CompileFunction(const Function& function) {
+ObjectPtr CompilationTraceLoader::CompileFunction(const Function& function) {
if (function.is_abstract() || function.HasCode()) {
return Object::null();
}
@@ -612,7 +611,7 @@
delete[] cid_map_;
}
-RawObject* TypeFeedbackLoader::LoadFeedback(ReadStream* stream) {
+ObjectPtr TypeFeedbackLoader::LoadFeedback(ReadStream* stream) {
stream_ = stream;
error_ = CheckHeader();
@@ -656,7 +655,7 @@
return Error::null();
}
-RawObject* TypeFeedbackLoader::CheckHeader() {
+ObjectPtr TypeFeedbackLoader::CheckHeader() {
const char* expected_version = Version::SnapshotString();
ASSERT(expected_version != NULL);
const intptr_t version_len = strlen(expected_version);
@@ -710,7 +709,7 @@
return Error::null();
}
-RawObject* TypeFeedbackLoader::LoadClasses() {
+ObjectPtr TypeFeedbackLoader::LoadClasses() {
num_cids_ = ReadInt();
cid_map_ = new intptr_t[num_cids_];
@@ -731,7 +730,7 @@
return Error::null();
}
-RawObject* TypeFeedbackLoader::LoadFields() {
+ObjectPtr TypeFeedbackLoader::LoadFields() {
for (intptr_t cid = kNumPredefinedCids; cid < num_cids_; cid++) {
cls_ = ReadClassByName();
bool skip = cls_.IsNull();
@@ -799,7 +798,7 @@
return Error::null();
}
-RawObject* TypeFeedbackLoader::LoadFunction() {
+ObjectPtr TypeFeedbackLoader::LoadFunction() {
bool skip = false;
cls_ = ReadClassByName();
@@ -813,7 +812,7 @@
}
func_name_ = ReadString(); // Without private mangling.
- RawFunction::Kind kind = static_cast<RawFunction::Kind>(ReadInt());
+ FunctionLayout::Kind kind = static_cast<FunctionLayout::Kind>(ReadInt());
intptr_t token_pos = ReadInt();
intptr_t usage = ReadInt();
intptr_t inlining_depth = ReadInt();
@@ -923,8 +922,8 @@
return Error::null();
}
-RawFunction* TypeFeedbackLoader::FindFunction(RawFunction::Kind kind,
- intptr_t token_pos) {
+FunctionPtr TypeFeedbackLoader::FindFunction(FunctionLayout::Kind kind,
+ intptr_t token_pos) {
if (cls_name_.Equals(Symbols::TopLevel())) {
func_ = lib_.LookupFunctionAllowPrivate(func_name_);
} else {
@@ -933,7 +932,7 @@
if (!func_.IsNull()) {
// Found regular method.
- } else if (kind == RawFunction::kMethodExtractor) {
+ } else if (kind == FunctionLayout::kMethodExtractor) {
ASSERT(Field::IsGetterName(func_name_));
// Without private mangling:
String& name = String::Handle(zone_, Field::NameFromGetter(func_name_));
@@ -945,7 +944,7 @@
} else {
func_ = Function::null();
}
- } else if (kind == RawFunction::kDynamicInvocationForwarder) {
+ } else if (kind == FunctionLayout::kDynamicInvocationForwarder) {
// Without private mangling:
String& name = String::Handle(
zone_, Function::DemangleDynamicInvocationForwarderName(func_name_));
@@ -957,7 +956,7 @@
} else {
func_ = Function::null();
}
- } else if (kind == RawFunction::kClosureFunction) {
+ } else if (kind == FunctionLayout::kClosureFunction) {
// Note this lookup relies on parent functions appearing before child
// functions in the serialized feedback, so the parent will have already
// been unoptimized compilated and the child function created and added to
@@ -984,7 +983,7 @@
}
if (!func_.IsNull()) {
- if (kind == RawFunction::kImplicitClosureFunction) {
+ if (kind == FunctionLayout::kImplicitClosureFunction) {
func_ = func_.ImplicitClosureFunction();
}
if (func_.is_abstract() || (func_.kind() != kind)) {
@@ -995,7 +994,7 @@
return func_.raw();
}
-RawClass* TypeFeedbackLoader::ReadClassByName() {
+ClassPtr TypeFeedbackLoader::ReadClassByName() {
uri_ = ReadString();
cls_name_ = ReadString();
@@ -1021,7 +1020,7 @@
return cls_.raw();
}
-RawString* TypeFeedbackLoader::ReadString() {
+StringPtr TypeFeedbackLoader::ReadString() {
intptr_t len = stream_->ReadUnsigned();
const char* cstr =
reinterpret_cast<const char*>(stream_->AddressOfCurrentPosition());
diff --git a/runtime/vm/compilation_trace.h b/runtime/vm/compilation_trace.h
index d7fed08..cf26611 100644
--- a/runtime/vm/compilation_trace.h
+++ b/runtime/vm/compilation_trace.h
@@ -35,13 +35,13 @@
public:
explicit CompilationTraceLoader(Thread* thread);
- RawObject* CompileTrace(uint8_t* buffer, intptr_t buffer_length);
+ ObjectPtr CompileTrace(uint8_t* buffer, intptr_t buffer_length);
private:
- RawObject* CompileTriple(const char* uri_cstr,
- const char* cls_cstr,
- const char* func_cstr);
- RawObject* CompileFunction(const Function& function);
+ ObjectPtr CompileTriple(const char* uri_cstr,
+ const char* cls_cstr,
+ const char* func_cstr);
+ ObjectPtr CompileFunction(const Function& function);
void SpeculateInstanceCallTargets(const Function& function);
Thread* thread_;
@@ -95,17 +95,17 @@
explicit TypeFeedbackLoader(Thread* thread);
~TypeFeedbackLoader();
- RawObject* LoadFeedback(ReadStream* stream);
+ ObjectPtr LoadFeedback(ReadStream* stream);
private:
- RawObject* CheckHeader();
- RawObject* LoadClasses();
- RawObject* LoadFields();
- RawObject* LoadFunction();
- RawFunction* FindFunction(RawFunction::Kind kind, intptr_t token_pos);
+ ObjectPtr CheckHeader();
+ ObjectPtr LoadClasses();
+ ObjectPtr LoadFields();
+ ObjectPtr LoadFunction();
+ FunctionPtr FindFunction(FunctionLayout::Kind kind, intptr_t token_pos);
- RawClass* ReadClassByName();
- RawString* ReadString();
+ ClassPtr ReadClassByName();
+ StringPtr ReadString();
intptr_t ReadInt() { return stream_->Read<int32_t>(); }
Thread* thread_;
diff --git a/runtime/vm/compiler/aot/aot_call_specializer.cc b/runtime/vm/compiler/aot/aot_call_specializer.cc
index e881bcd..4da0354 100644
--- a/runtime/vm/compiler/aot/aot_call_specializer.cc
+++ b/runtime/vm/compiler/aot/aot_call_specializer.cc
@@ -851,7 +851,7 @@
if (has_one_target) {
const Function& target = targets.FirstTarget();
- RawFunction::Kind function_kind = target.kind();
+ FunctionLayout::Kind function_kind = target.kind();
if (flow_graph()->CheckForInstanceCall(instr, function_kind) ==
FlowGraph::ToCheck::kNoCheck) {
StaticCallInstr* call = StaticCallInstr::FromCall(
diff --git a/runtime/vm/compiler/aot/dispatch_table_generator.cc b/runtime/vm/compiler/aot/dispatch_table_generator.cc
index 1b24c52..af7a1e1 100644
--- a/runtime/vm/compiler/aot/dispatch_table_generator.cc
+++ b/runtime/vm/compiler/aot/dispatch_table_generator.cc
@@ -657,7 +657,7 @@
table_size_ = fitter.TableSize();
}
-RawArray* DispatchTableGenerator::BuildCodeArray() {
+ArrayPtr DispatchTableGenerator::BuildCodeArray() {
auto& entries = Array::Handle(zone_, Array::New(table_size_, Heap::kOld));
for (intptr_t i = 0; i < table_rows_.length(); i++) {
table_rows_[i]->FillTable(classes_, entries);
diff --git a/runtime/vm/compiler/aot/dispatch_table_generator.h b/runtime/vm/compiler/aot/dispatch_table_generator.h
index 336e532..20b6ca3 100644
--- a/runtime/vm/compiler/aot/dispatch_table_generator.h
+++ b/runtime/vm/compiler/aot/dispatch_table_generator.h
@@ -93,7 +93,7 @@
// Build up an array of Code objects, used to serialize the information
// deserialized as a DispatchTable at runtime.
- RawArray* BuildCodeArray();
+ ArrayPtr BuildCodeArray();
private:
void ReadTableSelectorInfo();
diff --git a/runtime/vm/compiler/aot/precompiler.cc b/runtime/vm/compiler/aot/precompiler.cc
index 1137f5c..f63bf47 100644
--- a/runtime/vm/compiler/aot/precompiler.cc
+++ b/runtime/vm/compiler/aot/precompiler.cc
@@ -134,7 +134,7 @@
Thread::Current()->long_jump_base()->Jump(1, error);
}
-RawError* Precompiler::CompileAll() {
+ErrorPtr Precompiler::CompileAll() {
LongJumpScope jump;
if (setjmp(*jump.Set()) == 0) {
Precompiler precompiler(Thread::Current());
@@ -608,7 +608,7 @@
if (subcls.is_allocated()) {
// Add dispatcher to cls.
dispatcher = subcls.GetInvocationDispatcher(
- field_name, args_desc, RawFunction::kInvokeFieldDispatcher,
+ field_name, args_desc, FunctionLayout::kInvokeFieldDispatcher,
/* create_if_absent = */ true);
if (FLAG_trace_precompiler) {
THR_Print("Added invoke-field-dispatcher for %s to %s\n",
@@ -806,7 +806,7 @@
}
Code& code = Code::Handle(Z, function.CurrentCode());
if (code.IsNull()) {
- ASSERT(function.kind() == RawFunction::kSignatureFunction);
+ ASSERT(function.kind() == FunctionLayout::kSignatureFunction);
} else {
const ExceptionHandlers& handlers =
ExceptionHandlers::Handle(Z, code.exception_handlers());
@@ -940,8 +940,8 @@
precompiler_(precompiler),
subinstance_(Object::Handle()) {}
- virtual void VisitPointers(RawObject** first, RawObject** last) {
- for (RawObject** current = first; current <= last; current++) {
+ virtual void VisitPointers(ObjectPtr* first, ObjectPtr* last) {
+ for (ObjectPtr* current = first; current <= last; current++) {
subinstance_ = *current;
if (subinstance_.IsInstance()) {
precompiler_->AddConstObject(Instance::Cast(subinstance_));
@@ -956,16 +956,17 @@
};
ConstObjectVisitor visitor(this, I);
- instance.raw()->VisitPointers(&visitor);
+ instance.raw()->ptr()->VisitPointers(&visitor);
}
void Precompiler::AddClosureCall(const Array& arguments_descriptor) {
const Class& cache_class =
Class::Handle(Z, I->object_store()->closure_class());
- const Function& dispatcher = Function::Handle(
- Z, cache_class.GetInvocationDispatcher(
- Symbols::Call(), arguments_descriptor,
- RawFunction::kInvokeFieldDispatcher, true /* create_if_absent */));
+ const Function& dispatcher =
+ Function::Handle(Z, cache_class.GetInvocationDispatcher(
+ Symbols::Call(), arguments_descriptor,
+ FunctionLayout::kInvokeFieldDispatcher,
+ true /* create_if_absent */));
AddFunction(dispatcher);
}
@@ -1181,7 +1182,7 @@
if ((type == EntryPointPragma::kAlways ||
type == EntryPointPragma::kGetterOnly) &&
- function.kind() != RawFunction::kConstructor &&
+ function.kind() != FunctionLayout::kConstructor &&
!function.IsSetterFunction()) {
function2 = function.ImplicitClosureFunction();
AddFunction(function2);
@@ -1191,7 +1192,7 @@
AddInstantiatedClass(cls);
}
}
- if (function.kind() == RawFunction::kImplicitGetter &&
+ if (function.kind() == FunctionLayout::kImplicitGetter &&
!implicit_getters.IsNull()) {
for (intptr_t i = 0; i < implicit_getters.Length(); ++i) {
field ^= implicit_getters.At(i);
@@ -1200,7 +1201,7 @@
}
}
}
- if (function.kind() == RawFunction::kImplicitSetter &&
+ if (function.kind() == FunctionLayout::kImplicitSetter &&
!implicit_setters.IsNull()) {
for (intptr_t i = 0; i < implicit_setters.Length(); ++i) {
field ^= implicit_setters.At(i);
@@ -1209,7 +1210,7 @@
}
}
}
- if (function.kind() == RawFunction::kImplicitStaticGetter &&
+ if (function.kind() == FunctionLayout::kImplicitStaticGetter &&
!implicit_static_getters.IsNull()) {
for (intptr_t i = 0; i < implicit_static_getters.Length(); ++i) {
field ^= implicit_static_getters.At(i);
@@ -1281,7 +1282,7 @@
if (IsSent(selector3)) {
AddFunction(function);
}
- } else if (function.kind() == RawFunction::kRegularFunction) {
+ } else if (function.kind() == FunctionLayout::kRegularFunction) {
selector2 = Field::LookupGetterSymbol(selector);
if (IsSent(selector2)) {
metadata = kernel::ProcedureAttributesOf(function, Z);
@@ -1300,12 +1301,12 @@
}
}
- if (function.kind() == RawFunction::kImplicitSetter ||
- function.kind() == RawFunction::kSetterFunction ||
- function.kind() == RawFunction::kRegularFunction) {
+ if (function.kind() == FunctionLayout::kImplicitSetter ||
+ function.kind() == FunctionLayout::kSetterFunction ||
+ function.kind() == FunctionLayout::kRegularFunction) {
selector2 = Function::CreateDynamicInvocationForwarderName(selector);
if (IsSent(selector2)) {
- if (function.kind() == RawFunction::kImplicitSetter) {
+ if (function.kind() == FunctionLayout::kImplicitSetter) {
field = function.accessor_field();
metadata = kernel::ProcedureAttributesOf(field, Z);
} else if (!found_metadata) {
@@ -1333,7 +1334,7 @@
String::Cast(a).Equals(String::Cast(b));
}
static uword Hash(const Object& obj) { return String::Cast(obj).Hash(); }
- static RawObject* NewKey(const String& str) { return str.raw(); }
+ static ObjectPtr NewKey(const String& str) { return str.raw(); }
};
typedef UnorderedHashMap<NameFunctionsTraits> Table;
@@ -1710,7 +1711,7 @@
GrowableHandlePtrArray<const AbstractType>* types)
: type_(AbstractType::Handle(zone)), types_(types) {}
- void VisitObject(RawObject* obj) {
+ void VisitObject(ObjectPtr obj) {
if (obj->GetClassId() == kTypeCid || obj->GetClassId() == kTypeRefCid) {
type_ ^= obj;
types_->Add(type_);
@@ -2157,7 +2158,7 @@
typedef UnorderedHashSet<CodeKeyTraits> CodeSet;
#if defined(DEBUG)
-RawFunction* Precompiler::FindUnvisitedRetainedFunction() {
+FunctionPtr Precompiler::FindUnvisitedRetainedFunction() {
class CodeChecker : public CodeVisitor {
public:
CodeChecker()
@@ -2200,7 +2201,7 @@
GrowableHandlePtrArray<const Script>* scripts)
: script_(Script::Handle(zone)), scripts_(scripts) {}
- void VisitObject(RawObject* obj) {
+ void VisitObject(ObjectPtr obj) {
if (obj->GetClassId() == kScriptCid) {
script_ ^= obj;
scripts_->Add(Script::Cast(script_));
@@ -2563,10 +2564,10 @@
return is_compiled;
}
-static RawError* PrecompileFunctionHelper(Precompiler* precompiler,
- CompilationPipeline* pipeline,
- const Function& function,
- bool optimized) {
+static ErrorPtr PrecompileFunctionHelper(Precompiler* precompiler,
+ CompilationPipeline* pipeline,
+ const Function& function,
+ bool optimized) {
// Check that we optimize, except if the function is not optimizable.
ASSERT(CompilerState::Current().is_aot());
ASSERT(!function.IsOptimizable() || optimized);
@@ -2638,10 +2639,10 @@
return Error::null();
}
-RawError* Precompiler::CompileFunction(Precompiler* precompiler,
- Thread* thread,
- Zone* zone,
- const Function& function) {
+ErrorPtr Precompiler::CompileFunction(Precompiler* precompiler,
+ Thread* thread,
+ Zone* zone,
+ const Function& function) {
VMTagScope tagScope(thread, VMTag::kCompileUnoptimizedTagId);
TIMELINE_FUNCTION_COMPILATION_DURATION(thread, "CompileFunction", function);
@@ -2780,8 +2781,8 @@
PreventRenaming("_NamespaceImpl");
}
-RawString* Obfuscator::ObfuscationState::RenameImpl(const String& name,
- bool atomic) {
+StringPtr Obfuscator::ObfuscationState::RenameImpl(const String& name,
+ bool atomic) {
ASSERT(name.IsSymbol());
renamed_ ^= renames_.GetOrNull(name);
@@ -2857,7 +2858,7 @@
}
}
-RawString* Obfuscator::ObfuscationState::NewAtomicRename(
+StringPtr Obfuscator::ObfuscationState::NewAtomicRename(
bool should_be_private) {
do {
NextName();
@@ -2869,8 +2870,8 @@
return renamed_.raw();
}
-RawString* Obfuscator::ObfuscationState::BuildRename(const String& name,
- bool atomic) {
+StringPtr Obfuscator::ObfuscationState::BuildRename(const String& name,
+ bool atomic) {
if (atomic) {
return NewAtomicRename(name.CharAt(0) == '_');
}
diff --git a/runtime/vm/compiler/aot/precompiler.h b/runtime/vm/compiler/aot/precompiler.h
index 66c091c..c4135c4 100644
--- a/runtime/vm/compiler/aot/precompiler.h
+++ b/runtime/vm/compiler/aot/precompiler.h
@@ -25,7 +25,6 @@
class Field;
class Function;
class GrowableObjectArray;
-class RawError;
class SequenceNode;
class String;
class ParsedJSONObject;
@@ -192,12 +191,12 @@
class Precompiler : public ValueObject {
public:
- static RawError* CompileAll();
+ static ErrorPtr CompileAll();
- static RawError* CompileFunction(Precompiler* precompiler,
- Thread* thread,
- Zone* zone,
- const Function& function);
+ static ErrorPtr CompileFunction(Precompiler* precompiler,
+ Thread* thread,
+ Zone* zone,
+ const Function& function);
// Returns true if get:runtimeType is not overloaded by any class.
bool get_runtime_type_is_unique() const {
@@ -269,7 +268,7 @@
void DropClasses();
void DropLibraries();
- DEBUG_ONLY(RawFunction* FindUnvisitedRetainedFunction());
+ DEBUG_ONLY(FunctionPtr FindUnvisitedRetainedFunction());
void Obfuscate();
@@ -348,7 +347,7 @@
return String::Cast(obj).Hash();
}
}
- static RawObject* NewKey(const Function& function) { return function.raw(); }
+ static ObjectPtr NewKey(const Function& function) { return function.raw(); }
};
typedef UnorderedHashSet<FunctionsTraits> UniqueFunctionsSet;
@@ -406,7 +405,7 @@
//
// This method is guaranteed to return the same value for the same
// input and it always preserves leading '_' even for atomic renames.
- RawString* Rename(const String& name, bool atomic = false) {
+ StringPtr Rename(const String& name, bool atomic = false) {
if (state_ == NULL) {
return name.raw();
}
@@ -444,13 +443,13 @@
static const intptr_t kSavedStateRenamesIndex = 1;
static const intptr_t kSavedStateSize = 2;
- static RawArray* GetRenamesFromSavedState(const Array& saved_state) {
+ static ArrayPtr GetRenamesFromSavedState(const Array& saved_state) {
Array& renames = Array::Handle();
renames ^= saved_state.At(kSavedStateRenamesIndex);
return renames.raw();
}
- static RawString* GetNameFromSavedState(const Array& saved_state) {
+ static StringPtr GetNameFromSavedState(const Array& saved_state) {
String& name = String::Handle();
name ^= saved_state.At(kSavedStateNameIndex);
return name.raw();
@@ -494,7 +493,7 @@
//
// This method is guaranteed to return the same value for the same
// input.
- RawString* RenameImpl(const String& name, bool atomic);
+ StringPtr RenameImpl(const String& name, bool atomic);
// Register an identity (name -> name) mapping in the renaming map.
//
@@ -511,11 +510,11 @@
// For non-atomic renames BuildRename ensures that private mangled
// identifiers (_ident@key) are renamed consistently with non-mangled
// counterparts (_ident).
- RawString* BuildRename(const String& name, bool atomic);
+ StringPtr BuildRename(const String& name, bool atomic);
// Generate a new rename. If |should_be_private| is set to true
// then we prefix returned identifier with '_'.
- RawString* NewAtomicRename(bool should_be_private);
+ StringPtr NewAtomicRename(bool should_be_private);
// Update next_ to generate the next free rename.
void NextName();
@@ -549,7 +548,7 @@
Obfuscator(Thread* thread, const String& private_key) {}
~Obfuscator() {}
- RawString* Rename(const String& name, bool atomic = false) {
+ StringPtr Rename(const String& name, bool atomic = false) {
return name.raw();
}
diff --git a/runtime/vm/compiler/asm_intrinsifier_arm.cc b/runtime/vm/compiler/asm_intrinsifier_arm.cc
index aff1c83..531400e 100644
--- a/runtime/vm/compiler/asm_intrinsifier_arm.cc
+++ b/runtime/vm/compiler/asm_intrinsifier_arm.cc
@@ -127,10 +127,10 @@
/* R1: new object end address. */ \
/* R2: allocation size. */ \
{ \
- __ CompareImmediate(R2, target::RawObject::kSizeTagMaxSizeTag); \
+ __ CompareImmediate(R2, target::ObjectLayout::kSizeTagMaxSizeTag); \
__ mov(R3, \
Operand(R2, LSL, \
- target::RawObject::kTagBitsSizeTagPos - \
+ target::ObjectLayout::kTagBitsSizeTagPos - \
target::ObjectAlignment::kObjectAlignmentLog2), \
LS); \
__ mov(R3, Operand(0), HI); \
@@ -2060,10 +2060,10 @@
// R1: new object end address.
// R2: allocation size.
{
- const intptr_t shift = target::RawObject::kTagBitsSizeTagPos -
+ const intptr_t shift = target::ObjectLayout::kTagBitsSizeTagPos -
target::ObjectAlignment::kObjectAlignmentLog2;
- __ CompareImmediate(R2, target::RawObject::kSizeTagMaxSizeTag);
+ __ CompareImmediate(R2, target::ObjectLayout::kSizeTagMaxSizeTag);
__ mov(R3, Operand(R2, LSL, shift), LS);
__ mov(R3, Operand(0), HI);
diff --git a/runtime/vm/compiler/asm_intrinsifier_arm64.cc b/runtime/vm/compiler/asm_intrinsifier_arm64.cc
index a8a5491..82c487d 100644
--- a/runtime/vm/compiler/asm_intrinsifier_arm64.cc
+++ b/runtime/vm/compiler/asm_intrinsifier_arm64.cc
@@ -149,9 +149,9 @@
/* R1: new object end address. */ \
/* R2: allocation size. */ \
{ \
- __ CompareImmediate(R2, target::RawObject::kSizeTagMaxSizeTag); \
+ __ CompareImmediate(R2, target::ObjectLayout::kSizeTagMaxSizeTag); \
__ LslImmediate(R2, R2, \
- target::RawObject::kTagBitsSizeTagPos - \
+ target::ObjectLayout::kTagBitsSizeTagPos - \
target::ObjectAlignment::kObjectAlignmentLog2); \
__ csel(R2, ZR, R2, HI); \
\
@@ -2131,10 +2131,10 @@
// R1: new object end address.
// R2: allocation size.
{
- const intptr_t shift = target::RawObject::kTagBitsSizeTagPos -
+ const intptr_t shift = target::ObjectLayout::kTagBitsSizeTagPos -
target::ObjectAlignment::kObjectAlignmentLog2;
- __ CompareImmediate(R2, target::RawObject::kSizeTagMaxSizeTag);
+ __ CompareImmediate(R2, target::ObjectLayout::kSizeTagMaxSizeTag);
__ LslImmediate(R2, R2, shift);
__ csel(R2, R2, ZR, LS);
diff --git a/runtime/vm/compiler/asm_intrinsifier_ia32.cc b/runtime/vm/compiler/asm_intrinsifier_ia32.cc
index 0f0f759..45627cb 100644
--- a/runtime/vm/compiler/asm_intrinsifier_ia32.cc
+++ b/runtime/vm/compiler/asm_intrinsifier_ia32.cc
@@ -135,9 +135,9 @@
/* EDI: allocation size. */ \
{ \
Label size_tag_overflow, done; \
- __ cmpl(EDI, Immediate(target::RawObject::kSizeTagMaxSizeTag)); \
+ __ cmpl(EDI, Immediate(target::ObjectLayout::kSizeTagMaxSizeTag)); \
__ j(ABOVE, &size_tag_overflow, Assembler::kNearJump); \
- __ shll(EDI, Immediate(target::RawObject::kTagBitsSizeTagPos - \
+ __ shll(EDI, Immediate(target::ObjectLayout::kTagBitsSizeTagPos - \
target::ObjectAlignment::kObjectAlignmentLog2)); \
__ jmp(&done, Assembler::kNearJump); \
\
@@ -2075,9 +2075,9 @@
// EDI: allocation size.
{
Label size_tag_overflow, done;
- __ cmpl(EDI, Immediate(target::RawObject::kSizeTagMaxSizeTag));
+ __ cmpl(EDI, Immediate(target::ObjectLayout::kSizeTagMaxSizeTag));
__ j(ABOVE, &size_tag_overflow, Assembler::kNearJump);
- __ shll(EDI, Immediate(target::RawObject::kTagBitsSizeTagPos -
+ __ shll(EDI, Immediate(target::ObjectLayout::kTagBitsSizeTagPos -
target::ObjectAlignment::kObjectAlignmentLog2));
__ jmp(&done, Assembler::kNearJump);
diff --git a/runtime/vm/compiler/asm_intrinsifier_x64.cc b/runtime/vm/compiler/asm_intrinsifier_x64.cc
index 6ce01a9..1305a35 100644
--- a/runtime/vm/compiler/asm_intrinsifier_x64.cc
+++ b/runtime/vm/compiler/asm_intrinsifier_x64.cc
@@ -137,9 +137,9 @@
/* R13: scratch register. */ \
{ \
Label size_tag_overflow, done; \
- __ cmpq(RDI, Immediate(target::RawObject::kSizeTagMaxSizeTag)); \
+ __ cmpq(RDI, Immediate(target::ObjectLayout::kSizeTagMaxSizeTag)); \
__ j(ABOVE, &size_tag_overflow, Assembler::kNearJump); \
- __ shlq(RDI, Immediate(target::RawObject::kTagBitsSizeTagPos - \
+ __ shlq(RDI, Immediate(target::ObjectLayout::kTagBitsSizeTagPos - \
target::ObjectAlignment::kObjectAlignmentLog2)); \
__ jmp(&done, Assembler::kNearJump); \
\
@@ -2105,9 +2105,9 @@
// RDI: allocation size.
{
Label size_tag_overflow, done;
- __ cmpq(RDI, Immediate(target::RawObject::kSizeTagMaxSizeTag));
+ __ cmpq(RDI, Immediate(target::ObjectLayout::kSizeTagMaxSizeTag));
__ j(ABOVE, &size_tag_overflow, Assembler::kNearJump);
- __ shlq(RDI, Immediate(target::RawObject::kTagBitsSizeTagPos -
+ __ shlq(RDI, Immediate(target::ObjectLayout::kTagBitsSizeTagPos -
target::ObjectAlignment::kObjectAlignmentLog2));
__ jmp(&done, Assembler::kNearJump);
diff --git a/runtime/vm/compiler/assembler/assembler_arm.cc b/runtime/vm/compiler/assembler/assembler_arm.cc
index cac81b9..957457f 100644
--- a/runtime/vm/compiler/assembler/assembler_arm.cc
+++ b/runtime/vm/compiler/assembler/assembler_arm.cc
@@ -1741,7 +1741,7 @@
// in progress
// If so, call the WriteBarrier stub, which will either add object to the
// store buffer (case 1) or add value to the marking stack (case 2).
- // Compare RawObject::StorePointer.
+ // Compare ObjectLayout::StorePointer.
Label done;
if (can_be_smi == kValueCanBeSmi) {
BranchIfSmi(value, &done);
@@ -1749,7 +1749,7 @@
if (!lr_reserved) Push(LR);
ldrb(TMP, FieldAddress(object, target::Object::tags_offset()));
ldrb(LR, FieldAddress(value, target::Object::tags_offset()));
- and_(TMP, LR, Operand(TMP, LSR, target::RawObject::kBarrierOverlapShift));
+ and_(TMP, LR, Operand(TMP, LSR, target::ObjectLayout::kBarrierOverlapShift));
ldr(LR, Address(THR, target::Thread::write_barrier_mask_offset()));
tst(TMP, Operand(LR));
if (value != kWriteBarrierValueReg) {
@@ -1805,7 +1805,7 @@
// in progress
// If so, call the WriteBarrier stub, which will either add object to the
// store buffer (case 1) or add value to the marking stack (case 2).
- // Compare RawObject::StorePointer.
+ // Compare ObjectLayout::StorePointer.
Label done;
if (can_be_smi == kValueCanBeSmi) {
BranchIfSmi(value, &done);
@@ -1813,7 +1813,7 @@
if (!lr_reserved) Push(LR);
ldrb(TMP, FieldAddress(object, target::Object::tags_offset()));
ldrb(LR, FieldAddress(value, target::Object::tags_offset()));
- and_(TMP, LR, Operand(TMP, LSR, target::RawObject::kBarrierOverlapShift));
+ and_(TMP, LR, Operand(TMP, LSR, target::ObjectLayout::kBarrierOverlapShift));
ldr(LR, Address(THR, target::Thread::write_barrier_mask_offset()));
tst(TMP, Operand(LR));
@@ -1853,7 +1853,7 @@
StoreIntoObjectFilter(object, value, &done, kValueCanBeSmi, kJumpToNoUpdate);
ldrb(TMP, FieldAddress(object, target::Object::tags_offset()));
- tst(TMP, Operand(1 << target::RawObject::kOldAndNotRememberedBit));
+ tst(TMP, Operand(1 << target::ObjectLayout::kOldAndNotRememberedBit));
b(&done, ZERO);
Stop("Store buffer update is required");
@@ -1974,30 +1974,30 @@
}
void Assembler::ExtractClassIdFromTags(Register result, Register tags) {
- ASSERT(target::RawObject::kClassIdTagPos == 16);
- ASSERT(target::RawObject::kClassIdTagSize == 16);
+ ASSERT(target::ObjectLayout::kClassIdTagPos == 16);
+ ASSERT(target::ObjectLayout::kClassIdTagSize == 16);
ASSERT(sizeof(classid_t) == sizeof(uint16_t));
- Lsr(result, tags, Operand(target::RawObject::kClassIdTagPos), AL);
+ Lsr(result, tags, Operand(target::ObjectLayout::kClassIdTagPos), AL);
}
void Assembler::ExtractInstanceSizeFromTags(Register result, Register tags) {
- ASSERT(target::RawObject::kSizeTagPos == 8);
- ASSERT(target::RawObject::kSizeTagSize == 8);
+ ASSERT(target::ObjectLayout::kSizeTagPos == 8);
+ ASSERT(target::ObjectLayout::kSizeTagSize == 8);
Lsr(result, tags,
- Operand(target::RawObject::kSizeTagPos -
+ Operand(target::ObjectLayout::kSizeTagPos -
target::ObjectAlignment::kObjectAlignmentLog2),
AL);
AndImmediate(result, result,
- (Utils::NBitMask(target::RawObject::kSizeTagSize)
+ (Utils::NBitMask(target::ObjectLayout::kSizeTagSize)
<< target::ObjectAlignment::kObjectAlignmentLog2));
}
void Assembler::LoadClassId(Register result, Register object, Condition cond) {
- ASSERT(target::RawObject::kClassIdTagPos == 16);
- ASSERT(target::RawObject::kClassIdTagSize == 16);
+ ASSERT(target::ObjectLayout::kClassIdTagPos == 16);
+ ASSERT(target::ObjectLayout::kClassIdTagSize == 16);
const intptr_t class_id_offset =
target::Object::tags_offset() +
- target::RawObject::kClassIdTagPos / kBitsPerByte;
+ target::ObjectLayout::kClassIdTagPos / kBitsPerByte;
ldrh(result, FieldAddress(object, class_id_offset), cond);
}
diff --git a/runtime/vm/compiler/assembler/assembler_arm.h b/runtime/vm/compiler/assembler/assembler_arm.h
index 5f2165a..c45ce98 100644
--- a/runtime/vm/compiler/assembler/assembler_arm.h
+++ b/runtime/vm/compiler/assembler/assembler_arm.h
@@ -1198,8 +1198,8 @@
// before the code can be used.
//
// The neccessary information for the "linker" (i.e. the relocation
- // information) is stored in [RawCode::static_calls_target_table_]: an entry
- // of the form
+ // information) is stored in [CodeLayout::static_calls_target_table_]: an
+ // entry of the form
//
// (Code::kPcRelativeCall & pc_offset, <target-code>, <target-function>)
//
diff --git a/runtime/vm/compiler/assembler/assembler_arm64.cc b/runtime/vm/compiler/assembler/assembler_arm64.cc
index e418a0c..52b18c2 100644
--- a/runtime/vm/compiler/assembler/assembler_arm64.cc
+++ b/runtime/vm/compiler/assembler/assembler_arm64.cc
@@ -982,14 +982,15 @@
// in progress
// If so, call the WriteBarrier stub, which will either add object to the
// store buffer (case 1) or add value to the marking stack (case 2).
- // Compare RawObject::StorePointer.
+ // Compare ObjectLayout::StorePointer.
Label done;
if (can_be_smi == kValueCanBeSmi) {
BranchIfSmi(value, &done);
}
ldr(TMP, FieldAddress(object, target::Object::tags_offset()), kUnsignedByte);
ldr(TMP2, FieldAddress(value, target::Object::tags_offset()), kUnsignedByte);
- and_(TMP, TMP2, Operand(TMP, LSR, target::RawObject::kBarrierOverlapShift));
+ and_(TMP, TMP2,
+ Operand(TMP, LSR, target::ObjectLayout::kBarrierOverlapShift));
tst(TMP, Operand(BARRIER_MASK));
b(&done, ZERO);
@@ -1043,14 +1044,15 @@
// in progress
// If so, call the WriteBarrier stub, which will either add object to the
// store buffer (case 1) or add value to the marking stack (case 2).
- // Compare RawObject::StorePointer.
+ // Compare ObjectLayout::StorePointer.
Label done;
if (can_be_smi == kValueCanBeSmi) {
BranchIfSmi(value, &done);
}
ldr(TMP, FieldAddress(object, target::Object::tags_offset()), kUnsignedByte);
ldr(TMP2, FieldAddress(value, target::Object::tags_offset()), kUnsignedByte);
- and_(TMP, TMP2, Operand(TMP, LSR, target::RawObject::kBarrierOverlapShift));
+ and_(TMP, TMP2,
+ Operand(TMP, LSR, target::ObjectLayout::kBarrierOverlapShift));
tst(TMP, Operand(BARRIER_MASK));
b(&done, ZERO);
if (!lr_reserved) Push(LR);
@@ -1076,7 +1078,7 @@
StoreIntoObjectFilter(object, value, &done, kValueCanBeSmi, kJumpToNoUpdate);
ldr(TMP, FieldAddress(object, target::Object::tags_offset()), kUnsignedByte);
- tsti(TMP, Immediate(1 << target::RawObject::kOldAndNotRememberedBit));
+ tsti(TMP, Immediate(1 << target::ObjectLayout::kOldAndNotRememberedBit));
b(&done, ZERO);
Stop("Store buffer update is required");
@@ -1128,26 +1130,26 @@
}
void Assembler::ExtractClassIdFromTags(Register result, Register tags) {
- ASSERT(target::RawObject::kClassIdTagPos == 16);
- ASSERT(target::RawObject::kClassIdTagSize == 16);
+ ASSERT(target::ObjectLayout::kClassIdTagPos == 16);
+ ASSERT(target::ObjectLayout::kClassIdTagSize == 16);
ASSERT(sizeof(classid_t) == sizeof(uint16_t));
- LsrImmediate(result, tags, target::RawObject::kClassIdTagPos, kWord);
+ LsrImmediate(result, tags, target::ObjectLayout::kClassIdTagPos, kWord);
}
void Assembler::ExtractInstanceSizeFromTags(Register result, Register tags) {
- ASSERT(target::RawObject::kSizeTagPos == 8);
- ASSERT(target::RawObject::kSizeTagSize == 8);
- ubfx(result, tags, target::RawObject::kSizeTagPos,
- target::RawObject::kSizeTagSize);
+ ASSERT(target::ObjectLayout::kSizeTagPos == 8);
+ ASSERT(target::ObjectLayout::kSizeTagSize == 8);
+ ubfx(result, tags, target::ObjectLayout::kSizeTagPos,
+ target::ObjectLayout::kSizeTagSize);
LslImmediate(result, result, target::ObjectAlignment::kObjectAlignmentLog2);
}
void Assembler::LoadClassId(Register result, Register object) {
- ASSERT(target::RawObject::kClassIdTagPos == 16);
- ASSERT(target::RawObject::kClassIdTagSize == 16);
+ ASSERT(target::ObjectLayout::kClassIdTagPos == 16);
+ ASSERT(target::ObjectLayout::kClassIdTagSize == 16);
const intptr_t class_id_offset =
target::Object::tags_offset() +
- target::RawObject::kClassIdTagPos / kBitsPerByte;
+ target::ObjectLayout::kClassIdTagPos / kBitsPerByte;
LoadFromOffset(result, object, class_id_offset - kHeapObjectTag,
kUnsignedHalfword);
}
diff --git a/runtime/vm/compiler/assembler/assembler_arm64.h b/runtime/vm/compiler/assembler/assembler_arm64.h
index d2b5e28..4f8f3bd 100644
--- a/runtime/vm/compiler/assembler/assembler_arm64.h
+++ b/runtime/vm/compiler/assembler/assembler_arm64.h
@@ -1655,8 +1655,8 @@
// the code can be used.
//
// The neccessary information for the "linker" (i.e. the relocation
- // information) is stored in [RawCode::static_calls_target_table_]: an entry
- // of the form
+ // information) is stored in [CodeLayout::static_calls_target_table_]: an
+ // entry of the form
//
// (Code::kPcRelativeCall & pc_offset, <target-code>, <target-function>)
//
diff --git a/runtime/vm/compiler/assembler/assembler_arm64_test.cc b/runtime/vm/compiler/assembler/assembler_arm64_test.cc
index 11c255f..e8c5698 100644
--- a/runtime/vm/compiler/assembler/assembler_arm64_test.cc
+++ b/runtime/vm/compiler/assembler/assembler_arm64_test.cc
@@ -2551,7 +2551,7 @@
}
ASSEMBLER_TEST_RUN(LoadObjectNull, test) {
- EXPECT_EQ(Object::null(), test->InvokeWithCodeAndThread<RawObject*>());
+ EXPECT_EQ(Object::null(), test->InvokeWithCodeAndThread<ObjectPtr>());
}
// PushObject null.
@@ -2566,7 +2566,7 @@
}
ASSEMBLER_TEST_RUN(PushObjectNull, test) {
- EXPECT_EQ(Object::null(), test->InvokeWithCodeAndThread<RawObject*>());
+ EXPECT_EQ(Object::null(), test->InvokeWithCodeAndThread<ObjectPtr>());
}
// CompareObject null.
@@ -2584,7 +2584,7 @@
}
ASSEMBLER_TEST_RUN(CompareObjectNull, test) {
- EXPECT_EQ(Bool::True().raw(), test->InvokeWithCodeAndThread<RawObject*>());
+ EXPECT_EQ(Bool::True().raw(), test->InvokeWithCodeAndThread<ObjectPtr>());
}
ASSEMBLER_TEST_GENERATE(LoadObjectTrue, assembler) {
@@ -2597,7 +2597,7 @@
}
ASSEMBLER_TEST_RUN(LoadObjectTrue, test) {
- EXPECT_EQ(Bool::True().raw(), test->InvokeWithCodeAndThread<RawObject*>());
+ EXPECT_EQ(Bool::True().raw(), test->InvokeWithCodeAndThread<ObjectPtr>());
}
ASSEMBLER_TEST_GENERATE(LoadObjectFalse, assembler) {
@@ -2610,7 +2610,7 @@
}
ASSEMBLER_TEST_RUN(LoadObjectFalse, test) {
- EXPECT_EQ(Bool::False().raw(), test->InvokeWithCodeAndThread<RawObject*>());
+ EXPECT_EQ(Bool::False().raw(), test->InvokeWithCodeAndThread<ObjectPtr>());
}
ASSEMBLER_TEST_GENERATE(CSelTrue, assembler) {
diff --git a/runtime/vm/compiler/assembler/assembler_ia32.cc b/runtime/vm/compiler/assembler/assembler_ia32.cc
index df6fe5f..cd735a8 100644
--- a/runtime/vm/compiler/assembler/assembler_ia32.cc
+++ b/runtime/vm/compiler/assembler/assembler_ia32.cc
@@ -1934,7 +1934,7 @@
StoreIntoObjectFilter(object, value, &done, kValueCanBeSmi, kJumpToNoUpdate);
testb(FieldAddress(object, target::Object::tags_offset()),
- Immediate(1 << target::RawObject::kOldAndNotRememberedBit));
+ Immediate(1 << target::ObjectLayout::kOldAndNotRememberedBit));
j(ZERO, &done, Assembler::kNearJump);
Stop("Store buffer update is required");
@@ -2622,11 +2622,11 @@
}
void Assembler::LoadClassId(Register result, Register object) {
- ASSERT(target::RawObject::kClassIdTagPos == 16);
- ASSERT(target::RawObject::kClassIdTagSize == 16);
+ ASSERT(target::ObjectLayout::kClassIdTagPos == 16);
+ ASSERT(target::ObjectLayout::kClassIdTagSize == 16);
const intptr_t class_id_offset =
target::Object::tags_offset() +
- target::RawObject::kClassIdTagPos / kBitsPerByte;
+ target::ObjectLayout::kClassIdTagPos / kBitsPerByte;
movzxw(result, FieldAddress(object, class_id_offset));
}
@@ -2652,11 +2652,11 @@
Register scratch,
Label* is_smi) {
ASSERT(kSmiTagShift == 1);
- ASSERT(target::RawObject::kClassIdTagPos == 16);
- ASSERT(target::RawObject::kClassIdTagSize == 16);
+ ASSERT(target::ObjectLayout::kClassIdTagPos == 16);
+ ASSERT(target::ObjectLayout::kClassIdTagSize == 16);
const intptr_t class_id_offset =
target::Object::tags_offset() +
- target::RawObject::kClassIdTagPos / kBitsPerByte;
+ target::ObjectLayout::kClassIdTagPos / kBitsPerByte;
// Untag optimistically. Tag bit is shifted into the CARRY.
SmiUntag(object);
@@ -2682,8 +2682,8 @@
Bind(&join);
} else {
ASSERT(result != object);
- static const intptr_t kSmiCidSource = kSmiCid
- << target::RawObject::kClassIdTagPos;
+ static const intptr_t kSmiCidSource =
+ kSmiCid << target::ObjectLayout::kClassIdTagPos;
// Make a dummy "Object" whose cid is kSmiCid.
movl(result, Immediate(reinterpret_cast<int32_t>(&kSmiCidSource) + 1));
diff --git a/runtime/vm/compiler/assembler/assembler_test.cc b/runtime/vm/compiler/assembler/assembler_test.cc
index 7a7b54a..02f6b59 100644
--- a/runtime/vm/compiler/assembler/assembler_test.cc
+++ b/runtime/vm/compiler/assembler/assembler_test.cc
@@ -17,8 +17,8 @@
ASSEMBLER_TEST_RUN(StoreIntoObject, test) {
#define TEST_CODE(value, growable_array, thread) \
- test->Invoke<void, RawObject*, RawObject*, Thread*>(value, growable_array, \
- thread)
+ test->Invoke<void, ObjectPtr, ObjectPtr, Thread*>(value, growable_array, \
+ thread)
const Array& old_array = Array::Handle(Array::New(3, Heap::kOld));
const Array& new_array = Array::Handle(Array::New(3, Heap::kNew));
@@ -38,7 +38,7 @@
for (int i = -128; i < 128; i++) {
smi = Smi::New(i);
TEST_CODE(smi.raw(), grow_old_array.raw(), thread);
- EXPECT(reinterpret_cast<RawArray*>(smi.raw()) == grow_old_array.data());
+ EXPECT(static_cast<ArrayPtr>(smi.raw()) == grow_old_array.data());
EXPECT(!thread->StoreBufferContains(grow_old_array.raw()));
}
diff --git a/runtime/vm/compiler/assembler/assembler_x64.cc b/runtime/vm/compiler/assembler/assembler_x64.cc
index 624b28e..ef5a397 100644
--- a/runtime/vm/compiler/assembler/assembler_x64.cc
+++ b/runtime/vm/compiler/assembler/assembler_x64.cc
@@ -1374,14 +1374,14 @@
// in progress
// If so, call the WriteBarrier stub, which will either add object to the
// store buffer (case 1) or add value to the marking stack (case 2).
- // Compare RawObject::StorePointer.
+ // Compare ObjectLayout::StorePointer.
Label done;
if (can_be_smi == kValueCanBeSmi) {
testq(value, Immediate(kSmiTagMask));
j(ZERO, &done, kNearJump);
}
movb(TMP, FieldAddress(object, target::Object::tags_offset()));
- shrl(TMP, Immediate(target::RawObject::kBarrierOverlapShift));
+ shrl(TMP, Immediate(target::ObjectLayout::kBarrierOverlapShift));
andl(TMP, Address(THR, target::Thread::write_barrier_mask_offset()));
testb(FieldAddress(value, target::Object::tags_offset()), TMP);
j(ZERO, &done, kNearJump);
@@ -1426,14 +1426,14 @@
// in progress
// If so, call the WriteBarrier stub, which will either add object to the
// store buffer (case 1) or add value to the marking stack (case 2).
- // Compare RawObject::StorePointer.
+ // Compare ObjectLayout::StorePointer.
Label done;
if (can_be_smi == kValueCanBeSmi) {
testq(value, Immediate(kSmiTagMask));
j(ZERO, &done, kNearJump);
}
movb(TMP, FieldAddress(object, target::Object::tags_offset()));
- shrl(TMP, Immediate(target::RawObject::kBarrierOverlapShift));
+ shrl(TMP, Immediate(target::ObjectLayout::kBarrierOverlapShift));
andl(TMP, Address(THR, target::Thread::write_barrier_mask_offset()));
testb(FieldAddress(value, target::Object::tags_offset()), TMP);
j(ZERO, &done, kNearJump);
@@ -1461,7 +1461,7 @@
StoreIntoObjectFilter(object, value, &done, kValueCanBeSmi, kJumpToNoUpdate);
testb(FieldAddress(object, target::Object::tags_offset()),
- Immediate(1 << target::RawObject::kOldAndNotRememberedBit));
+ Immediate(1 << target::ObjectLayout::kOldAndNotRememberedBit));
j(ZERO, &done, Assembler::kNearJump);
Stop("Store buffer update is required");
@@ -2104,31 +2104,31 @@
}
void Assembler::ExtractClassIdFromTags(Register result, Register tags) {
- ASSERT(target::RawObject::kClassIdTagPos == 16);
- ASSERT(target::RawObject::kClassIdTagSize == 16);
+ ASSERT(target::ObjectLayout::kClassIdTagPos == 16);
+ ASSERT(target::ObjectLayout::kClassIdTagSize == 16);
ASSERT(sizeof(classid_t) == sizeof(uint16_t));
movl(result, tags);
- shrl(result, Immediate(target::RawObject::kClassIdTagPos));
+ shrl(result, Immediate(target::ObjectLayout::kClassIdTagPos));
}
void Assembler::ExtractInstanceSizeFromTags(Register result, Register tags) {
- ASSERT(target::RawObject::kSizeTagPos == 8);
- ASSERT(target::RawObject::kSizeTagSize == 8);
+ ASSERT(target::ObjectLayout::kSizeTagPos == 8);
+ ASSERT(target::ObjectLayout::kSizeTagSize == 8);
movzxw(result, tags);
- shrl(result, Immediate(target::RawObject::kSizeTagPos -
+ shrl(result, Immediate(target::ObjectLayout::kSizeTagPos -
target::ObjectAlignment::kObjectAlignmentLog2));
AndImmediate(result,
- Immediate(Utils::NBitMask(target::RawObject::kSizeTagSize)
+ Immediate(Utils::NBitMask(target::ObjectLayout::kSizeTagSize)
<< target::ObjectAlignment::kObjectAlignmentLog2));
}
void Assembler::LoadClassId(Register result, Register object) {
- ASSERT(target::RawObject::kClassIdTagPos == 16);
- ASSERT(target::RawObject::kClassIdTagSize == 16);
+ ASSERT(target::ObjectLayout::kClassIdTagPos == 16);
+ ASSERT(target::ObjectLayout::kClassIdTagSize == 16);
ASSERT(sizeof(classid_t) == sizeof(uint16_t));
const intptr_t class_id_offset =
target::Object::tags_offset() +
- target::RawObject::kClassIdTagPos / kBitsPerByte;
+ target::ObjectLayout::kClassIdTagPos / kBitsPerByte;
movzxw(result, FieldAddress(object, class_id_offset));
}
@@ -2154,12 +2154,12 @@
intptr_t class_id,
Label* is_smi) {
ASSERT(kSmiTagShift == 1);
- ASSERT(target::RawObject::kClassIdTagPos == 16);
- ASSERT(target::RawObject::kClassIdTagSize == 16);
+ ASSERT(target::ObjectLayout::kClassIdTagPos == 16);
+ ASSERT(target::ObjectLayout::kClassIdTagSize == 16);
ASSERT(sizeof(classid_t) == sizeof(uint16_t));
const intptr_t class_id_offset =
target::Object::tags_offset() +
- target::RawObject::kClassIdTagPos / kBitsPerByte;
+ target::ObjectLayout::kClassIdTagPos / kBitsPerByte;
// Untag optimistically. Tag bit is shifted into the CARRY.
SmiUntag(object);
diff --git a/runtime/vm/compiler/assembler/assembler_x64.h b/runtime/vm/compiler/assembler/assembler_x64.h
index e39a7f2..8a0d80d 100644
--- a/runtime/vm/compiler/assembler/assembler_x64.h
+++ b/runtime/vm/compiler/assembler/assembler_x64.h
@@ -945,8 +945,8 @@
// before the code can be used.
//
// The neccessary information for the "linker" (i.e. the relocation
- // information) is stored in [RawCode::static_calls_target_table_]: an entry
- // of the form
+ // information) is stored in [CodeLayout::static_calls_target_table_]: an
+ // entry of the form
//
// (Code::kPcRelativeCall & pc_offset, <target-code>, <target-function>)
//
diff --git a/runtime/vm/compiler/assembler/disassembler.cc b/runtime/vm/compiler/assembler/disassembler.cc
index 8dd66a3..68b7847 100644
--- a/runtime/vm/compiler/assembler/disassembler.cc
+++ b/runtime/vm/compiler/assembler/disassembler.cc
@@ -232,7 +232,7 @@
Object& obj = Object::Handle(zone);
for (intptr_t i = code.pointer_offsets_length() - 1; i >= 0; i--) {
const uword addr = code.GetPointerOffsetAt(i) + code.PayloadStart();
- obj = *reinterpret_cast<RawObject**>(addr);
+ obj = *reinterpret_cast<ObjectPtr*>(addr);
THR_Print(" %d : %#" Px " '%s'\n", code.GetPointerOffsetAt(i), addr,
obj.ToCString());
}
@@ -301,20 +301,20 @@
String& var_name = String::Handle(zone);
for (intptr_t i = 0; i < var_desc_length; i++) {
var_name = var_descriptors.GetName(i);
- RawLocalVarDescriptors::VarInfo var_info;
+ LocalVarDescriptorsLayout::VarInfo var_info;
var_descriptors.GetInfo(i, &var_info);
const int8_t kind = var_info.kind();
- if (kind == RawLocalVarDescriptors::kSavedCurrentContext) {
+ if (kind == LocalVarDescriptorsLayout::kSavedCurrentContext) {
THR_Print(" saved current CTX reg offset %d\n", var_info.index());
} else {
- if (kind == RawLocalVarDescriptors::kContextLevel) {
+ if (kind == LocalVarDescriptorsLayout::kContextLevel) {
THR_Print(" context level %d scope %d", var_info.index(),
var_info.scope_id);
- } else if (kind == RawLocalVarDescriptors::kStackVar) {
+ } else if (kind == LocalVarDescriptorsLayout::kStackVar) {
THR_Print(" stack var '%s' offset %d", var_name.ToCString(),
var_info.index());
} else {
- ASSERT(kind == RawLocalVarDescriptors::kContextVar);
+ ASSERT(kind == LocalVarDescriptorsLayout::kContextVar);
THR_Print(" context var '%s' level %d offset %d",
var_name.ToCString(), var_info.scope_id, var_info.index());
}
diff --git a/runtime/vm/compiler/assembler/disassembler_x86.cc b/runtime/vm/compiler/assembler/disassembler_x86.cc
index 0d162a5..93f3129 100644
--- a/runtime/vm/compiler/assembler/disassembler_x86.cc
+++ b/runtime/vm/compiler/assembler/disassembler_x86.cc
@@ -1995,7 +1995,7 @@
for (intptr_t i = 0; i < offsets_length; i++) {
uword addr = code.GetPointerOffsetAt(i) + code.PayloadStart();
if ((pc <= addr) && (addr < (pc + instruction_length))) {
- *object = &Object::Handle(*reinterpret_cast<RawObject**>(addr));
+ *object = &Object::Handle(*reinterpret_cast<ObjectPtr*>(addr));
break;
}
}
diff --git a/runtime/vm/compiler/backend/block_builder.h b/runtime/vm/compiler/backend/block_builder.h
index 7cf8b86..311b0ab 100644
--- a/runtime/vm/compiler/backend/block_builder.h
+++ b/runtime/vm/compiler/backend/block_builder.h
@@ -61,7 +61,7 @@
ReturnInstr* instr = new ReturnInstr(
TokenPos(), value, CompilerState::Current().GetNextDeoptId(),
- RawPcDescriptors::kInvalidYieldIndex, representation);
+ PcDescriptorsLayout::kInvalidYieldIndex, representation);
AddInstruction(instr);
entry_->set_last_instruction(instr);
}
diff --git a/runtime/vm/compiler/backend/constant_propagator.cc b/runtime/vm/compiler/backend/constant_propagator.cc
index 66855f9..7c5a67d 100644
--- a/runtime/vm/compiler/backend/constant_propagator.cc
+++ b/runtime/vm/compiler/backend/constant_propagator.cc
@@ -744,7 +744,7 @@
const intptr_t ch_code = Smi::Cast(o).Value();
ASSERT(ch_code >= 0);
if (ch_code < Symbols::kMaxOneCharCodeSymbol) {
- RawString** table = Symbols::PredefinedAddress();
+ StringPtr* table = Symbols::PredefinedAddress();
SetValue(instr, String::ZoneHandle(Z, table[ch_code]));
} else {
SetValue(instr, non_constant_);
diff --git a/runtime/vm/compiler/backend/constant_propagator.h b/runtime/vm/compiler/backend/constant_propagator.h
index 6150081..d0dca7d 100644
--- a/runtime/vm/compiler/backend/constant_propagator.h
+++ b/runtime/vm/compiler/backend/constant_propagator.h
@@ -36,7 +36,7 @@
static void OptimizeBranches(FlowGraph* graph);
// Used to initialize the abstract value of definitions.
- static RawObject* Unknown() { return Object::unknown_constant().raw(); }
+ static ObjectPtr Unknown() { return Object::unknown_constant().raw(); }
private:
void Analyze();
diff --git a/runtime/vm/compiler/backend/evaluator.cc b/runtime/vm/compiler/backend/evaluator.cc
index e61c9d7..8bb0c3d 100644
--- a/runtime/vm/compiler/backend/evaluator.cc
+++ b/runtime/vm/compiler/backend/evaluator.cc
@@ -31,9 +31,9 @@
}
}
-static RawInteger* BinaryIntegerEvaluateRaw(const Integer& left,
- const Integer& right,
- Token::Kind token_kind) {
+static IntegerPtr BinaryIntegerEvaluateRaw(const Integer& left,
+ const Integer& right,
+ Token::Kind token_kind) {
switch (token_kind) {
case Token::kTRUNCDIV:
FALL_THROUGH;
@@ -71,9 +71,9 @@
return Integer::null();
}
-static RawInteger* UnaryIntegerEvaluateRaw(const Integer& value,
- Token::Kind token_kind,
- Zone* zone) {
+static IntegerPtr UnaryIntegerEvaluateRaw(const Integer& value,
+ Token::Kind token_kind,
+ Zone* zone) {
switch (token_kind) {
case Token::kNEGATE:
return value.ArithmeticOp(Token::kMUL, Smi::Handle(zone, Smi::New(-1)),
@@ -110,12 +110,12 @@
}
}
-RawInteger* Evaluator::BinaryIntegerEvaluate(const Object& left,
- const Object& right,
- Token::Kind token_kind,
- bool is_truncating,
- Representation representation,
- Thread* thread) {
+IntegerPtr Evaluator::BinaryIntegerEvaluate(const Object& left,
+ const Object& right,
+ Token::Kind token_kind,
+ bool is_truncating,
+ Representation representation,
+ Thread* thread) {
if (!left.IsInteger() || !right.IsInteger()) {
return Integer::null();
}
@@ -148,10 +148,10 @@
return result.raw();
}
-RawInteger* Evaluator::UnaryIntegerEvaluate(const Object& value,
- Token::Kind token_kind,
- Representation representation,
- Thread* thread) {
+IntegerPtr Evaluator::UnaryIntegerEvaluate(const Object& value,
+ Token::Kind token_kind,
+ Representation representation,
+ Thread* thread) {
if (!value.IsInteger()) {
return Integer::null();
}
diff --git a/runtime/vm/compiler/backend/evaluator.h b/runtime/vm/compiler/backend/evaluator.h
index 13590f9..e1ab8ea 100644
--- a/runtime/vm/compiler/backend/evaluator.h
+++ b/runtime/vm/compiler/backend/evaluator.h
@@ -24,19 +24,19 @@
// Evaluates a binary integer operation and returns a pointer to a
// canonicalized RawInteger.
- static RawInteger* BinaryIntegerEvaluate(const Object& left,
- const Object& right,
- Token::Kind token_kind,
- bool is_truncating,
- Representation representation,
- Thread* thread);
+ static IntegerPtr BinaryIntegerEvaluate(const Object& left,
+ const Object& right,
+ Token::Kind token_kind,
+ bool is_truncating,
+ Representation representation,
+ Thread* thread);
// Evaluates a unary integer operation and returns a pointer to a
// canonicalized RawInteger.
- static RawInteger* UnaryIntegerEvaluate(const Object& value,
- Token::Kind token_kind,
- Representation representation,
- Thread* thread);
+ static IntegerPtr UnaryIntegerEvaluate(const Object& value,
+ Token::Kind token_kind,
+ Representation representation,
+ Thread* thread);
// Evaluates a binary double operation and returns the result.
static double EvaluateDoubleOp(const double left,
diff --git a/runtime/vm/compiler/backend/flow_graph.cc b/runtime/vm/compiler/backend/flow_graph.cc
index e249c5e..c930e71 100644
--- a/runtime/vm/compiler/backend/flow_graph.cc
+++ b/runtime/vm/compiler/backend/flow_graph.cc
@@ -410,7 +410,7 @@
FlowGraph::ToCheck FlowGraph::CheckForInstanceCall(
InstanceCallInstr* call,
- RawFunction::Kind kind) const {
+ FunctionLayout::Kind kind) const {
if (!FLAG_use_cha_deopt && !isolate()->all_classes_finalized()) {
// Even if class or function are private, lazy class finalization
// may later add overriding methods.
@@ -472,7 +472,7 @@
}
const String& method_name =
- (kind == RawFunction::kMethodExtractor)
+ (kind == FunctionLayout::kMethodExtractor)
? String::Handle(zone(), Field::NameFromGetter(call->function_name()))
: call->function_name();
diff --git a/runtime/vm/compiler/backend/flow_graph.h b/runtime/vm/compiler/backend/flow_graph.h
index 67c1fed..0a9d929 100644
--- a/runtime/vm/compiler/backend/flow_graph.h
+++ b/runtime/vm/compiler/backend/flow_graph.h
@@ -236,7 +236,7 @@
// Return value indicates that the call needs no check at all,
// just a null check, or a full class check.
ToCheck CheckForInstanceCall(InstanceCallInstr* call,
- RawFunction::Kind kind) const;
+ FunctionLayout::Kind kind) const;
Thread* thread() const { return thread_; }
Zone* zone() const { return thread()->zone(); }
diff --git a/runtime/vm/compiler/backend/flow_graph_compiler.cc b/runtime/vm/compiler/backend/flow_graph_compiler.cc
index 04e1142..0532aa3f 100644
--- a/runtime/vm/compiler/backend/flow_graph_compiler.cc
+++ b/runtime/vm/compiler/backend/flow_graph_compiler.cc
@@ -252,7 +252,7 @@
void FlowGraphCompiler::InsertBSSRelocation(BSS::Relocation reloc) {
const intptr_t offset = assembler()->InsertAlignedRelocation(reloc);
- AddDescriptor(RawPcDescriptors::kBSSRelocation, /*pc_offset=*/offset,
+ AddDescriptor(PcDescriptorsLayout::kBSSRelocation, /*pc_offset=*/offset,
/*deopt_id=*/DeoptId::kNone, TokenPosition::kNoSource,
/*try_index=*/-1);
}
@@ -456,7 +456,7 @@
void FlowGraphCompiler::EmitCallsiteMetadata(TokenPosition token_pos,
intptr_t deopt_id,
- RawPcDescriptors::Kind kind,
+ PcDescriptorsLayout::Kind kind,
LocationSummary* locs,
Environment* env) {
AddCurrentDescriptor(kind, deopt_id, token_pos);
@@ -471,14 +471,15 @@
} else {
// Add deoptimization continuation point after the call and before the
// arguments are removed.
- AddCurrentDescriptor(RawPcDescriptors::kDeopt, deopt_id_after, token_pos);
+ AddCurrentDescriptor(PcDescriptorsLayout::kDeopt, deopt_id_after,
+ token_pos);
}
}
}
void FlowGraphCompiler::EmitYieldPositionMetadata(TokenPosition token_pos,
intptr_t yield_index) {
- AddDescriptor(RawPcDescriptors::kOther, assembler()->CodeSize(),
+ AddDescriptor(PcDescriptorsLayout::kOther, assembler()->CodeSize(),
DeoptId::kNone, token_pos, CurrentTryIndex(), yield_index);
}
@@ -488,7 +489,7 @@
// Instructions that can be deoptimization targets need to record kDeopt
// PcDescriptor corresponding to their deopt id. GotoInstr records its
// own so that it can control the placement.
- AddCurrentDescriptor(RawPcDescriptors::kDeopt, instr->deopt_id(),
+ AddCurrentDescriptor(PcDescriptorsLayout::kDeopt, instr->deopt_id(),
instr->token_pos());
}
AllocateRegistersLocally(instr);
@@ -732,7 +733,7 @@
exception_handlers_list_->SetNeedsStackTrace(try_index);
}
-void FlowGraphCompiler::AddDescriptor(RawPcDescriptors::Kind kind,
+void FlowGraphCompiler::AddDescriptor(PcDescriptorsLayout::Kind kind,
intptr_t pc_offset,
intptr_t deopt_id,
TokenPosition token_pos,
@@ -740,13 +741,13 @@
intptr_t yield_index) {
code_source_map_builder_->NoteDescriptor(kind, pc_offset, token_pos);
// Don't emit deopt-descriptors in AOT mode.
- if (FLAG_precompiled_mode && (kind == RawPcDescriptors::kDeopt)) return;
+ if (FLAG_precompiled_mode && (kind == PcDescriptorsLayout::kDeopt)) return;
pc_descriptors_list_->AddDescriptor(kind, pc_offset, deopt_id, token_pos,
try_index, yield_index);
}
// Uses current pc position and try-index.
-void FlowGraphCompiler::AddCurrentDescriptor(RawPcDescriptors::Kind kind,
+void FlowGraphCompiler::AddCurrentDescriptor(PcDescriptorsLayout::Kind kind,
intptr_t deopt_id,
TokenPosition token_pos) {
AddDescriptor(kind, assembler()->CodeSize(), deopt_id, token_pos,
@@ -1123,7 +1124,7 @@
code.set_pc_descriptors(descriptors);
}
-RawArray* FlowGraphCompiler::CreateDeoptInfo(compiler::Assembler* assembler) {
+ArrayPtr FlowGraphCompiler::CreateDeoptInfo(compiler::Assembler* assembler) {
// No deopt information if we precompile (no deoptimization allowed).
if (FLAG_precompiled_mode) {
return Array::empty_array().raw();
@@ -1185,8 +1186,8 @@
// descriptor for IrregexpFunction.
ASSERT(parsed_function().scope() == nullptr);
var_descs = LocalVarDescriptors::New(1);
- RawLocalVarDescriptors::VarInfo info;
- info.set_kind(RawLocalVarDescriptors::kSavedCurrentContext);
+ LocalVarDescriptorsLayout::VarInfo info;
+ info.set_kind(LocalVarDescriptorsLayout::kSavedCurrentContext);
info.scope_id = 0;
info.begin_pos = TokenPosition::kMinSource;
info.end_pos = TokenPosition::kMinSource;
@@ -1285,7 +1286,7 @@
// there are no checks necessary in any case and we can therefore intrinsify
// them even in checked mode and strong mode.
switch (parsed_function().function().kind()) {
- case RawFunction::kImplicitGetter: {
+ case FunctionLayout::kImplicitGetter: {
Field& field = Field::Handle(function().accessor_field());
ASSERT(!field.IsNull());
#if defined(DEBUG)
@@ -1308,7 +1309,7 @@
}
return false;
}
- case RawFunction::kImplicitSetter: {
+ case FunctionLayout::kImplicitSetter: {
if (!isolate()->argument_type_checks()) {
Field& field = Field::Handle(function().accessor_field());
ASSERT(!field.IsNull());
@@ -1329,7 +1330,7 @@
break;
}
#if !defined(TARGET_ARCH_IA32)
- case RawFunction::kMethodExtractor: {
+ case FunctionLayout::kMethodExtractor: {
auto& extracted_method = Function::ZoneHandle(
parsed_function().function().extracted_method_closure());
auto& klass = Class::Handle(extracted_method.Owner());
@@ -1371,7 +1372,7 @@
void FlowGraphCompiler::GenerateStubCall(TokenPosition token_pos,
const Code& stub,
- RawPcDescriptors::Kind kind,
+ PcDescriptorsLayout::Kind kind,
LocationSummary* locs,
intptr_t deopt_id,
Environment* env) {
@@ -1474,7 +1475,7 @@
->raw();
call_ic_data = call_ic_data.Original();
}
- AddCurrentDescriptor(RawPcDescriptors::kRewind, deopt_id, token_pos);
+ AddCurrentDescriptor(PcDescriptorsLayout::kRewind, deopt_id, token_pos);
EmitUnoptimizedStaticCall(args_info.size_with_type_args, deopt_id,
token_pos, locs, call_ic_data, entry_kind);
}
@@ -2086,8 +2087,8 @@
if (class_id < 0) return false;
if (class_id >= isolate->class_table()->NumCids()) return false;
- RawClass* raw_class = isolate->class_table()->At(class_id);
- if (raw_class == NULL) return false;
+ ClassPtr raw_class = isolate->class_table()->At(class_id);
+ if (raw_class == nullptr) return false;
Class& cls = Class::Handle(zone, raw_class);
if (cls.IsNull()) return false;
if (!cls.is_finalized()) return false;
@@ -2203,7 +2204,7 @@
// Do not use the code from the function, but let the code be patched so
// that we can record the outgoing edges to other code.
const Function& function = *targets.TargetAt(smi_case)->target;
- GenerateStaticDartCall(deopt_id, token_index, RawPcDescriptors::kOther,
+ GenerateStaticDartCall(deopt_id, token_index, PcDescriptorsLayout::kOther,
locs, function, entry_kind);
__ Drop(args_info.size_with_type_args);
if (match_found != NULL) {
@@ -2253,7 +2254,7 @@
// Do not use the code from the function, but let the code be patched so
// that we can record the outgoing edges to other code.
const Function& function = *targets.TargetAt(i)->target;
- GenerateStaticDartCall(deopt_id, token_index, RawPcDescriptors::kOther,
+ GenerateStaticDartCall(deopt_id, token_index, PcDescriptorsLayout::kOther,
locs, function, entry_kind);
__ Drop(args_info.size_with_type_args);
if (!is_last_check || add_megamorphic_call) {
@@ -2557,7 +2558,7 @@
__ CallRuntime(runtime_entry_, num_args_);
}
const intptr_t deopt_id = instruction()->deopt_id();
- compiler->AddDescriptor(RawPcDescriptors::kOther,
+ compiler->AddDescriptor(PcDescriptorsLayout::kOther,
compiler->assembler()->CodeSize(), deopt_id,
instruction()->token_pos(), try_index_);
AddMetadataForRuntimeCall(compiler);
diff --git a/runtime/vm/compiler/backend/flow_graph_compiler.h b/runtime/vm/compiler/backend/flow_graph_compiler.h
index 91ad3ab..3c2ee5c 100644
--- a/runtime/vm/compiler/backend/flow_graph_compiler.h
+++ b/runtime/vm/compiler/backend/flow_graph_compiler.h
@@ -181,9 +181,9 @@
}
virtual ~CompilerDeoptInfo() {}
- RawTypedData* CreateDeoptInfo(FlowGraphCompiler* compiler,
- DeoptInfoBuilder* builder,
- const Array& deopt_table);
+ TypedDataPtr CreateDeoptInfo(FlowGraphCompiler* compiler,
+ DeoptInfoBuilder* builder,
+ const Array& deopt_table);
// No code needs to be generated.
virtual void GenerateCode(FlowGraphCompiler* compiler, intptr_t stub_ix) {}
@@ -602,27 +602,27 @@
void GenerateStubCall(TokenPosition token_pos,
const Code& stub,
- RawPcDescriptors::Kind kind,
+ PcDescriptorsLayout::Kind kind,
LocationSummary* locs,
intptr_t deopt_id = DeoptId::kNone,
Environment* env = nullptr);
void GeneratePatchableCall(TokenPosition token_pos,
const Code& stub,
- RawPcDescriptors::Kind kind,
+ PcDescriptorsLayout::Kind kind,
LocationSummary* locs);
void GenerateDartCall(intptr_t deopt_id,
TokenPosition token_pos,
const Code& stub,
- RawPcDescriptors::Kind kind,
+ PcDescriptorsLayout::Kind kind,
LocationSummary* locs,
Code::EntryKind entry_kind = Code::EntryKind::kNormal);
void GenerateStaticDartCall(
intptr_t deopt_id,
TokenPosition token_pos,
- RawPcDescriptors::Kind kind,
+ PcDescriptorsLayout::Kind kind,
LocationSummary* locs,
const Function& target,
Code::EntryKind entry_kind = Code::EntryKind::kNormal);
@@ -785,7 +785,7 @@
// `pending_deoptimization_env`.
void EmitCallsiteMetadata(TokenPosition token_pos,
intptr_t deopt_id,
- RawPcDescriptors::Kind kind,
+ PcDescriptorsLayout::Kind kind,
LocationSummary* locs,
Environment* env = nullptr);
@@ -823,16 +823,16 @@
const Array& handler_types,
bool needs_stacktrace);
void SetNeedsStackTrace(intptr_t try_index);
- void AddCurrentDescriptor(RawPcDescriptors::Kind kind,
+ void AddCurrentDescriptor(PcDescriptorsLayout::Kind kind,
intptr_t deopt_id,
TokenPosition token_pos);
void AddDescriptor(
- RawPcDescriptors::Kind kind,
+ PcDescriptorsLayout::Kind kind,
intptr_t pc_offset,
intptr_t deopt_id,
TokenPosition token_pos,
intptr_t try_index,
- intptr_t yield_index = RawPcDescriptors::kInvalidYieldIndex);
+ intptr_t yield_index = PcDescriptorsLayout::kInvalidYieldIndex);
// Add NullCheck information for the current PC.
void AddNullCheck(TokenPosition token_pos, const String& name);
@@ -851,7 +851,7 @@
void FinalizeExceptionHandlers(const Code& code);
void FinalizePcDescriptors(const Code& code);
- RawArray* CreateDeoptInfo(compiler::Assembler* assembler);
+ ArrayPtr CreateDeoptInfo(compiler::Assembler* assembler);
void FinalizeStackMaps(const Code& code);
void FinalizeVarDescriptors(const Code& code);
void FinalizeCatchEntryMovesMap(const Code& code);
@@ -929,9 +929,9 @@
void AddStubCallTarget(const Code& code);
void AddDispatchTableCallTarget(const compiler::TableSelector* selector);
- RawArray* edge_counters_array() const { return edge_counters_array_.raw(); }
+ ArrayPtr edge_counters_array() const { return edge_counters_array_.raw(); }
- RawArray* InliningIdToFunction() const;
+ ArrayPtr InliningIdToFunction() const;
void BeginCodeSourceRange();
void EndCodeSourceRange(TokenPosition token_pos);
@@ -1029,13 +1029,13 @@
compiler::Label* is_instance_lbl,
compiler::Label* is_not_instance_lbl);
- RawSubtypeTestCache* GenerateInlineInstanceof(
+ SubtypeTestCachePtr GenerateInlineInstanceof(
TokenPosition token_pos,
const AbstractType& type,
compiler::Label* is_instance_lbl,
compiler::Label* is_not_instance_lbl);
- RawSubtypeTestCache* GenerateInstantiatedTypeWithArgumentsTest(
+ SubtypeTestCachePtr GenerateInstantiatedTypeWithArgumentsTest(
TokenPosition token_pos,
const AbstractType& dst_type,
compiler::Label* is_instance_lbl,
@@ -1047,19 +1047,19 @@
compiler::Label* is_instance_lbl,
compiler::Label* is_not_instance_lbl);
- RawSubtypeTestCache* GenerateUninstantiatedTypeTest(
+ SubtypeTestCachePtr GenerateUninstantiatedTypeTest(
TokenPosition token_pos,
const AbstractType& dst_type,
compiler::Label* is_instance_lbl,
compiler::Label* is_not_instance_label);
- RawSubtypeTestCache* GenerateFunctionTypeTest(
+ SubtypeTestCachePtr GenerateFunctionTypeTest(
TokenPosition token_pos,
const AbstractType& dst_type,
compiler::Label* is_instance_lbl,
compiler::Label* is_not_instance_label);
- RawSubtypeTestCache* GenerateSubtype1TestCacheLookup(
+ SubtypeTestCachePtr GenerateSubtype1TestCacheLookup(
TokenPosition token_pos,
const Class& type_class,
compiler::Label* is_instance_lbl,
@@ -1076,7 +1076,7 @@
TypeTestStubKind GetTypeTestStubKindForTypeParameter(
const TypeParameter& type_param);
- RawSubtypeTestCache* GenerateCallSubtypeTestStub(
+ SubtypeTestCachePtr GenerateCallSubtypeTestStub(
TypeTestStubKind test_kind,
Register instance_reg,
Register instantiator_type_arguments_reg,
diff --git a/runtime/vm/compiler/backend/flow_graph_compiler_arm.cc b/runtime/vm/compiler/backend/flow_graph_compiler_arm.cc
index f2e8e44..792d5007 100644
--- a/runtime/vm/compiler/backend/flow_graph_compiler_arm.cc
+++ b/runtime/vm/compiler/backend/flow_graph_compiler_arm.cc
@@ -99,9 +99,9 @@
intrinsic_mode_ = false;
}
-RawTypedData* CompilerDeoptInfo::CreateDeoptInfo(FlowGraphCompiler* compiler,
- DeoptInfoBuilder* builder,
- const Array& deopt_table) {
+TypedDataPtr CompilerDeoptInfo::CreateDeoptInfo(FlowGraphCompiler* compiler,
+ DeoptInfoBuilder* builder,
+ const Array& deopt_table) {
if (deopt_env_ == NULL) {
++builder->current_info_number_;
return TypedData::null();
@@ -228,7 +228,7 @@
// R2: instantiator type arguments (if used).
// R1: function type arguments (if used).
// R3: type test cache.
-RawSubtypeTestCache* FlowGraphCompiler::GenerateCallSubtypeTestStub(
+SubtypeTestCachePtr FlowGraphCompiler::GenerateCallSubtypeTestStub(
TypeTestStubKind test_kind,
Register instance_reg,
Register instantiator_type_arguments_reg,
@@ -274,7 +274,7 @@
// be completed.
// R0: instance being type checked (preserved).
// Clobbers R1, R2.
-RawSubtypeTestCache*
+SubtypeTestCachePtr
FlowGraphCompiler::GenerateInstantiatedTypeWithArgumentsTest(
TokenPosition token_pos,
const AbstractType& type,
@@ -417,7 +417,7 @@
// TODO(srdjan): Implement a quicker subtype check, as type test
// arrays can grow too high, but they may be useful when optimizing
// code (type-feedback).
-RawSubtypeTestCache* FlowGraphCompiler::GenerateSubtype1TestCacheLookup(
+SubtypeTestCachePtr FlowGraphCompiler::GenerateSubtype1TestCacheLookup(
TokenPosition token_pos,
const Class& type_class,
compiler::Label* is_instance_lbl,
@@ -455,7 +455,7 @@
// Generates inlined check if 'type' is a type parameter or type itself
// R0: instance (preserved).
-RawSubtypeTestCache* FlowGraphCompiler::GenerateUninstantiatedTypeTest(
+SubtypeTestCachePtr FlowGraphCompiler::GenerateUninstantiatedTypeTest(
TokenPosition token_pos,
const AbstractType& type,
compiler::Label* is_instance_lbl,
@@ -540,7 +540,7 @@
// Generates function type check.
//
// See [GenerateUninstantiatedTypeTest] for calling convention.
-RawSubtypeTestCache* FlowGraphCompiler::GenerateFunctionTypeTest(
+SubtypeTestCachePtr FlowGraphCompiler::GenerateFunctionTypeTest(
TokenPosition token_pos,
const AbstractType& type,
compiler::Label* is_instance_lbl,
@@ -573,7 +573,7 @@
// Note that this inlined code must be followed by the runtime_call code, as it
// may fall through to it. Otherwise, this inline code will jump to the label
// is_instance or to the label is_not_instance.
-RawSubtypeTestCache* FlowGraphCompiler::GenerateInlineInstanceof(
+SubtypeTestCachePtr FlowGraphCompiler::GenerateInlineInstanceof(
TokenPosition token_pos,
const AbstractType& type,
compiler::Label* is_instance_lbl,
@@ -668,7 +668,7 @@
__ LoadUniqueObject(TypeTestABI::kDstTypeReg, type);
__ LoadUniqueObject(TypeTestABI::kSubtypeTestCacheReg, test_cache);
GenerateStubCall(token_pos, StubCode::InstanceOf(),
- /*kind=*/RawPcDescriptors::kOther, locs, deopt_id);
+ /*kind=*/PcDescriptorsLayout::kOther, locs, deopt_id);
__ b(&done);
}
__ Bind(&is_not_instance);
@@ -809,7 +809,7 @@
sub_type_cache_offset, PP);
__ blx(R9);
}
- EmitCallsiteMetadata(token_pos, deopt_id, RawPcDescriptors::kOther, locs);
+ EmitCallsiteMetadata(token_pos, deopt_id, PcDescriptorsLayout::kOther, locs);
__ Bind(&done);
}
@@ -1016,7 +1016,7 @@
void FlowGraphCompiler::GeneratePatchableCall(TokenPosition token_pos,
const Code& stub,
- RawPcDescriptors::Kind kind,
+ PcDescriptorsLayout::Kind kind,
LocationSummary* locs) {
__ BranchLinkPatchable(stub);
EmitCallsiteMetadata(token_pos, DeoptId::kNone, kind, locs);
@@ -1025,7 +1025,7 @@
void FlowGraphCompiler::GenerateDartCall(intptr_t deopt_id,
TokenPosition token_pos,
const Code& stub,
- RawPcDescriptors::Kind kind,
+ PcDescriptorsLayout::Kind kind,
LocationSummary* locs,
Code::EntryKind entry_kind) {
ASSERT(CanCallDart());
@@ -1035,7 +1035,7 @@
void FlowGraphCompiler::GenerateStaticDartCall(intptr_t deopt_id,
TokenPosition token_pos,
- RawPcDescriptors::Kind kind,
+ PcDescriptorsLayout::Kind kind,
LocationSummary* locs,
const Function& target,
Code::EntryKind entry_kind) {
@@ -1063,7 +1063,7 @@
intptr_t argument_count,
LocationSummary* locs) {
__ CallRuntime(entry, argument_count);
- EmitCallsiteMetadata(token_pos, deopt_id, RawPcDescriptors::kOther, locs);
+ EmitCallsiteMetadata(token_pos, deopt_id, PcDescriptorsLayout::kOther, locs);
}
void FlowGraphCompiler::EmitEdgeCounter(intptr_t edge_id) {
@@ -1109,8 +1109,8 @@
__ LoadFromOffset(kWord, R0, SP,
(ic_data.SizeWithoutTypeArgs() - 1) * kWordSize);
__ LoadUniqueObject(R9, ic_data);
- GenerateDartCall(deopt_id, token_pos, stub, RawPcDescriptors::kIcCall, locs,
- entry_kind);
+ GenerateDartCall(deopt_id, token_pos, stub, PcDescriptorsLayout::kIcCall,
+ locs, entry_kind);
__ Drop(ic_data.SizeWithTypeArgs());
}
@@ -1134,7 +1134,7 @@
: Code::entry_point_offset(Code::EntryKind::kMonomorphicUnchecked);
__ ldr(LR, compiler::FieldAddress(CODE_REG, entry_point_offset));
__ blx(LR);
- EmitCallsiteMetadata(token_pos, deopt_id, RawPcDescriptors::kIcCall, locs);
+ EmitCallsiteMetadata(token_pos, deopt_id, PcDescriptorsLayout::kIcCall, locs);
__ Drop(ic_data.SizeWithTypeArgs());
}
@@ -1189,16 +1189,19 @@
if (try_index == kInvalidTryIndex) {
try_index = CurrentTryIndex();
}
- AddDescriptor(RawPcDescriptors::kOther, assembler()->CodeSize(),
+ AddDescriptor(PcDescriptorsLayout::kOther, assembler()->CodeSize(),
DeoptId::kNone, token_pos, try_index);
} else if (is_optimizing()) {
- AddCurrentDescriptor(RawPcDescriptors::kOther, DeoptId::kNone, token_pos);
+ AddCurrentDescriptor(PcDescriptorsLayout::kOther, DeoptId::kNone,
+ token_pos);
AddDeoptIndexAtCall(deopt_id_after);
} else {
- AddCurrentDescriptor(RawPcDescriptors::kOther, DeoptId::kNone, token_pos);
+ AddCurrentDescriptor(PcDescriptorsLayout::kOther, DeoptId::kNone,
+ token_pos);
// Add deoptimization continuation point after the call and before the
// arguments are removed.
- AddCurrentDescriptor(RawPcDescriptors::kDeopt, deopt_id_after, token_pos);
+ AddCurrentDescriptor(PcDescriptorsLayout::kDeopt, deopt_id_after,
+ token_pos);
}
RecordCatchEntryMoves(pending_deoptimization_env_, try_index);
__ Drop(args_desc.SizeWithTypeArgs());
@@ -1244,7 +1247,7 @@
__ LoadUniqueObject(R9, data);
__ blx(LR);
- EmitCallsiteMetadata(token_pos, DeoptId::kNone, RawPcDescriptors::kOther,
+ EmitCallsiteMetadata(token_pos, DeoptId::kNone, PcDescriptorsLayout::kOther,
locs);
__ Drop(ic_data.SizeWithTypeArgs());
}
@@ -1260,7 +1263,7 @@
StubCode::UnoptimizedStaticCallEntry(ic_data.NumArgsTested());
__ LoadObject(R9, ic_data);
GenerateDartCall(deopt_id, token_pos, stub,
- RawPcDescriptors::kUnoptStaticCall, locs, entry_kind);
+ PcDescriptorsLayout::kUnoptStaticCall, locs, entry_kind);
__ Drop(size_with_type_args);
}
@@ -1283,7 +1286,7 @@
}
// Do not use the code from the function, but let the code be patched so that
// we can record the outgoing edges to other code.
- GenerateStaticDartCall(deopt_id, token_pos, RawPcDescriptors::kOther, locs,
+ GenerateStaticDartCall(deopt_id, token_pos, PcDescriptorsLayout::kOther, locs,
function, entry_kind);
__ Drop(size_with_type_args);
}
@@ -1330,7 +1333,8 @@
} else {
__ BranchLinkPatchable(StubCode::UnoptimizedIdenticalWithNumberCheck());
}
- AddCurrentDescriptor(RawPcDescriptors::kRuntimeCall, deopt_id, token_pos);
+ AddCurrentDescriptor(PcDescriptorsLayout::kRuntimeCall, deopt_id,
+ token_pos);
// Stub returns result in flags (result of a cmp, we need Z computed).
__ Drop(1); // Discard constant.
__ Pop(reg); // Restore 'reg'.
@@ -1353,7 +1357,8 @@
} else {
__ BranchLinkPatchable(StubCode::UnoptimizedIdenticalWithNumberCheck());
}
- AddCurrentDescriptor(RawPcDescriptors::kRuntimeCall, deopt_id, token_pos);
+ AddCurrentDescriptor(PcDescriptorsLayout::kRuntimeCall, deopt_id,
+ token_pos);
// Stub returns result in flags (result of a cmp, we need Z computed).
__ Pop(right);
__ Pop(left);
diff --git a/runtime/vm/compiler/backend/flow_graph_compiler_arm64.cc b/runtime/vm/compiler/backend/flow_graph_compiler_arm64.cc
index 3f42db3..c1f274d 100644
--- a/runtime/vm/compiler/backend/flow_graph_compiler_arm64.cc
+++ b/runtime/vm/compiler/backend/flow_graph_compiler_arm64.cc
@@ -93,9 +93,9 @@
intrinsic_mode_ = false;
}
-RawTypedData* CompilerDeoptInfo::CreateDeoptInfo(FlowGraphCompiler* compiler,
- DeoptInfoBuilder* builder,
- const Array& deopt_table) {
+TypedDataPtr CompilerDeoptInfo::CreateDeoptInfo(FlowGraphCompiler* compiler,
+ DeoptInfoBuilder* builder,
+ const Array& deopt_table) {
if (deopt_env_ == NULL) {
++builder->current_info_number_;
return TypedData::null();
@@ -217,7 +217,7 @@
// R0: instance (must be preserved).
// R2: instantiator type arguments (if used).
// R1: function type arguments (if used).
-RawSubtypeTestCache* FlowGraphCompiler::GenerateCallSubtypeTestStub(
+SubtypeTestCachePtr FlowGraphCompiler::GenerateCallSubtypeTestStub(
TypeTestStubKind test_kind,
Register instance_reg,
Register instantiator_type_arguments_reg,
@@ -263,7 +263,7 @@
// be completed.
// R0: instance being type checked (preserved).
// Clobbers R1, R2.
-RawSubtypeTestCache*
+SubtypeTestCachePtr
FlowGraphCompiler::GenerateInstantiatedTypeWithArgumentsTest(
TokenPosition token_pos,
const AbstractType& type,
@@ -401,7 +401,7 @@
// TODO(srdjan): Implement a quicker subtype check, as type test
// arrays can grow too high, but they may be useful when optimizing
// code (type-feedback).
-RawSubtypeTestCache* FlowGraphCompiler::GenerateSubtype1TestCacheLookup(
+SubtypeTestCachePtr FlowGraphCompiler::GenerateSubtype1TestCacheLookup(
TokenPosition token_pos,
const Class& type_class,
compiler::Label* is_instance_lbl,
@@ -437,7 +437,7 @@
// Generates inlined check if 'type' is a type parameter or type itself
// R0: instance (preserved).
-RawSubtypeTestCache* FlowGraphCompiler::GenerateUninstantiatedTypeTest(
+SubtypeTestCachePtr FlowGraphCompiler::GenerateUninstantiatedTypeTest(
TokenPosition token_pos,
const AbstractType& type,
compiler::Label* is_instance_lbl,
@@ -515,7 +515,7 @@
// Generates function type check.
//
// See [GenerateUninstantiatedTypeTest] for calling convention.
-RawSubtypeTestCache* FlowGraphCompiler::GenerateFunctionTypeTest(
+SubtypeTestCachePtr FlowGraphCompiler::GenerateFunctionTypeTest(
TokenPosition token_pos,
const AbstractType& type,
compiler::Label* is_instance_lbl,
@@ -545,7 +545,7 @@
// Note that this inlined code must be followed by the runtime_call code, as it
// may fall through to it. Otherwise, this inline code will jump to the label
// is_instance or to the label is_not_instance.
-RawSubtypeTestCache* FlowGraphCompiler::GenerateInlineInstanceof(
+SubtypeTestCachePtr FlowGraphCompiler::GenerateInlineInstanceof(
TokenPosition token_pos,
const AbstractType& type,
compiler::Label* is_instance_lbl,
@@ -634,7 +634,7 @@
__ LoadUniqueObject(TypeTestABI::kDstTypeReg, type);
__ LoadUniqueObject(TypeTestABI::kSubtypeTestCacheReg, test_cache);
GenerateStubCall(token_pos, StubCode::InstanceOf(),
- /*kind=*/RawPcDescriptors::kOther, locs, deopt_id);
+ /*kind=*/PcDescriptorsLayout::kOther, locs, deopt_id);
__ b(&done);
}
__ Bind(&is_not_instance);
@@ -770,7 +770,7 @@
sub_type_cache_offset);
__ blr(R9);
}
- EmitCallsiteMetadata(token_pos, deopt_id, RawPcDescriptors::kOther, locs);
+ EmitCallsiteMetadata(token_pos, deopt_id, PcDescriptorsLayout::kOther, locs);
__ Bind(&done);
}
@@ -977,7 +977,7 @@
void FlowGraphCompiler::GeneratePatchableCall(TokenPosition token_pos,
const Code& stub,
- RawPcDescriptors::Kind kind,
+ PcDescriptorsLayout::Kind kind,
LocationSummary* locs) {
__ BranchLinkPatchable(stub);
EmitCallsiteMetadata(token_pos, DeoptId::kNone, kind, locs);
@@ -986,7 +986,7 @@
void FlowGraphCompiler::GenerateDartCall(intptr_t deopt_id,
TokenPosition token_pos,
const Code& stub,
- RawPcDescriptors::Kind kind,
+ PcDescriptorsLayout::Kind kind,
LocationSummary* locs,
Code::EntryKind entry_kind) {
ASSERT(CanCallDart());
@@ -996,7 +996,7 @@
void FlowGraphCompiler::GenerateStaticDartCall(intptr_t deopt_id,
TokenPosition token_pos,
- RawPcDescriptors::Kind kind,
+ PcDescriptorsLayout::Kind kind,
LocationSummary* locs,
const Function& target,
Code::EntryKind entry_kind) {
@@ -1024,7 +1024,7 @@
intptr_t argument_count,
LocationSummary* locs) {
__ CallRuntime(entry, argument_count);
- EmitCallsiteMetadata(token_pos, deopt_id, RawPcDescriptors::kOther, locs);
+ EmitCallsiteMetadata(token_pos, deopt_id, PcDescriptorsLayout::kOther, locs);
}
void FlowGraphCompiler::EmitEdgeCounter(intptr_t edge_id) {
@@ -1060,8 +1060,8 @@
__ LoadObject(R6, parsed_function().function());
__ LoadFromOffset(R0, SP, (ic_data.SizeWithoutTypeArgs() - 1) * kWordSize);
__ LoadUniqueObject(R5, ic_data);
- GenerateDartCall(deopt_id, token_pos, stub, RawPcDescriptors::kIcCall, locs,
- entry_kind);
+ GenerateDartCall(deopt_id, token_pos, stub, PcDescriptorsLayout::kIcCall,
+ locs, entry_kind);
__ Drop(ic_data.SizeWithTypeArgs());
}
@@ -1091,7 +1091,7 @@
: Code::entry_point_offset(Code::EntryKind::kMonomorphicUnchecked);
__ ldr(LR, compiler::FieldAddress(CODE_REG, entry_point_offset));
__ blr(LR);
- EmitCallsiteMetadata(token_pos, deopt_id, RawPcDescriptors::kIcCall, locs);
+ EmitCallsiteMetadata(token_pos, deopt_id, PcDescriptorsLayout::kIcCall, locs);
__ Drop(ic_data.SizeWithTypeArgs());
}
@@ -1143,16 +1143,19 @@
if (try_index == kInvalidTryIndex) {
try_index = CurrentTryIndex();
}
- AddDescriptor(RawPcDescriptors::kOther, assembler()->CodeSize(),
+ AddDescriptor(PcDescriptorsLayout::kOther, assembler()->CodeSize(),
DeoptId::kNone, token_pos, try_index);
} else if (is_optimizing()) {
- AddCurrentDescriptor(RawPcDescriptors::kOther, DeoptId::kNone, token_pos);
+ AddCurrentDescriptor(PcDescriptorsLayout::kOther, DeoptId::kNone,
+ token_pos);
AddDeoptIndexAtCall(deopt_id_after);
} else {
- AddCurrentDescriptor(RawPcDescriptors::kOther, DeoptId::kNone, token_pos);
+ AddCurrentDescriptor(PcDescriptorsLayout::kOther, DeoptId::kNone,
+ token_pos);
// Add deoptimization continuation point after the call and before the
// arguments are removed.
- AddCurrentDescriptor(RawPcDescriptors::kDeopt, deopt_id_after, token_pos);
+ AddCurrentDescriptor(PcDescriptorsLayout::kDeopt, deopt_id_after,
+ token_pos);
}
RecordCatchEntryMoves(pending_deoptimization_env_, try_index);
__ Drop(args_desc.SizeWithTypeArgs());
@@ -1207,7 +1210,7 @@
}
__ blr(LR);
- EmitCallsiteMetadata(token_pos, DeoptId::kNone, RawPcDescriptors::kOther,
+ EmitCallsiteMetadata(token_pos, DeoptId::kNone, PcDescriptorsLayout::kOther,
locs);
__ Drop(ic_data.SizeWithTypeArgs());
}
@@ -1223,7 +1226,7 @@
StubCode::UnoptimizedStaticCallEntry(ic_data.NumArgsTested());
__ LoadObject(R5, ic_data);
GenerateDartCall(deopt_id, token_pos, stub,
- RawPcDescriptors::kUnoptStaticCall, locs, entry_kind);
+ PcDescriptorsLayout::kUnoptStaticCall, locs, entry_kind);
__ Drop(size_with_type_args);
}
@@ -1246,7 +1249,7 @@
}
// Do not use the code from the function, but let the code be patched so that
// we can record the outgoing edges to other code.
- GenerateStaticDartCall(deopt_id, token_pos, RawPcDescriptors::kOther, locs,
+ GenerateStaticDartCall(deopt_id, token_pos, PcDescriptorsLayout::kOther, locs,
function, entry_kind);
__ Drop(size_with_type_args);
}
@@ -1282,7 +1285,8 @@
} else {
__ BranchLinkPatchable(StubCode::UnoptimizedIdenticalWithNumberCheck());
}
- AddCurrentDescriptor(RawPcDescriptors::kRuntimeCall, deopt_id, token_pos);
+ AddCurrentDescriptor(PcDescriptorsLayout::kRuntimeCall, deopt_id,
+ token_pos);
// Stub returns result in flags (result of a cmp, we need Z computed).
// Discard constant.
// Restore 'reg'.
@@ -1305,7 +1309,8 @@
} else {
__ BranchLinkPatchable(StubCode::UnoptimizedIdenticalWithNumberCheck());
}
- AddCurrentDescriptor(RawPcDescriptors::kRuntimeCall, deopt_id, token_pos);
+ AddCurrentDescriptor(PcDescriptorsLayout::kRuntimeCall, deopt_id,
+ token_pos);
// Stub returns result in flags (result of a cmp, we need Z computed).
__ PopPair(right, left);
} else {
diff --git a/runtime/vm/compiler/backend/flow_graph_compiler_ia32.cc b/runtime/vm/compiler/backend/flow_graph_compiler_ia32.cc
index 2c7eac4..20fcd8c 100644
--- a/runtime/vm/compiler/backend/flow_graph_compiler_ia32.cc
+++ b/runtime/vm/compiler/backend/flow_graph_compiler_ia32.cc
@@ -71,9 +71,9 @@
intrinsic_mode_ = false;
}
-RawTypedData* CompilerDeoptInfo::CreateDeoptInfo(FlowGraphCompiler* compiler,
- DeoptInfoBuilder* builder,
- const Array& deopt_table) {
+TypedDataPtr CompilerDeoptInfo::CreateDeoptInfo(FlowGraphCompiler* compiler,
+ DeoptInfoBuilder* builder,
+ const Array& deopt_table) {
if (deopt_env_ == NULL) {
++builder->current_info_number_;
return TypedData::null();
@@ -182,7 +182,7 @@
compiler::Label* is_true,
compiler::Label* is_false) {
const compiler::Immediate& raw_null =
- compiler::Immediate(reinterpret_cast<intptr_t>(Object::null()));
+ compiler::Immediate(static_cast<intptr_t>(Object::null()));
compiler::Label fall_through;
__ cmpl(bool_register, raw_null);
__ j(EQUAL, &fall_through, compiler::Assembler::kNearJump);
@@ -196,7 +196,7 @@
}
// Clobbers ECX.
-RawSubtypeTestCache* FlowGraphCompiler::GenerateCallSubtypeTestStub(
+SubtypeTestCachePtr FlowGraphCompiler::GenerateCallSubtypeTestStub(
TypeTestStubKind test_kind,
Register instance_reg,
Register instantiator_type_arguments_reg,
@@ -207,7 +207,7 @@
const SubtypeTestCache& type_test_cache =
SubtypeTestCache::ZoneHandle(zone(), SubtypeTestCache::New());
const compiler::Immediate& raw_null =
- compiler::Immediate(reinterpret_cast<intptr_t>(Object::null()));
+ compiler::Immediate(static_cast<intptr_t>(Object::null()));
__ LoadObject(temp_reg, type_test_cache);
__ pushl(temp_reg); // Subtype test cache.
__ pushl(instance_reg); // Instance.
@@ -249,7 +249,7 @@
// be completed.
// EAX: instance (must survive).
// Clobbers ECX, EDI.
-RawSubtypeTestCache*
+SubtypeTestCachePtr
FlowGraphCompiler::GenerateInstantiatedTypeWithArgumentsTest(
TokenPosition token_pos,
const AbstractType& type,
@@ -390,7 +390,7 @@
// TODO(srdjan): Implement a quicker subtype check, as type test
// arrays can grow too high, but they may be useful when optimizing
// code (type-feedback).
-RawSubtypeTestCache* FlowGraphCompiler::GenerateSubtype1TestCacheLookup(
+SubtypeTestCachePtr FlowGraphCompiler::GenerateSubtype1TestCacheLookup(
TokenPosition token_pos,
const Class& type_class,
compiler::Label* is_instance_lbl,
@@ -427,7 +427,7 @@
// Generates inlined check if 'type' is a type parameter or type itself
// EAX: instance (preserved).
// Clobbers EDX, EDI, ECX.
-RawSubtypeTestCache* FlowGraphCompiler::GenerateUninstantiatedTypeTest(
+SubtypeTestCachePtr FlowGraphCompiler::GenerateUninstantiatedTypeTest(
TokenPosition token_pos,
const AbstractType& type,
compiler::Label* is_instance_lbl,
@@ -438,7 +438,7 @@
ASSERT(!type.IsFunctionType());
// Skip check if destination is a dynamic type.
const compiler::Immediate& raw_null =
- compiler::Immediate(reinterpret_cast<intptr_t>(Object::null()));
+ compiler::Immediate(static_cast<intptr_t>(Object::null()));
if (type.IsTypeParameter()) {
const TypeParameter& type_param = TypeParameter::Cast(type);
@@ -514,7 +514,7 @@
// Generates function type check.
//
// See [GenerateUninstantiatedTypeTest] for calling convention.
-RawSubtypeTestCache* FlowGraphCompiler::GenerateFunctionTypeTest(
+SubtypeTestCachePtr FlowGraphCompiler::GenerateFunctionTypeTest(
TokenPosition token_pos,
const AbstractType& type,
compiler::Label* is_instance_lbl,
@@ -544,7 +544,7 @@
// Note that this inlined code must be followed by the runtime_call code, as it
// may fall through to it. Otherwise, this inline code will jump to the label
// is_instance or to the label is_not_instance.
-RawSubtypeTestCache* FlowGraphCompiler::GenerateInlineInstanceof(
+SubtypeTestCachePtr FlowGraphCompiler::GenerateInlineInstanceof(
TokenPosition token_pos,
const AbstractType& type,
compiler::Label* is_instance_lbl,
@@ -603,7 +603,7 @@
__ pushl(ECX); // Store function type arguments.
const compiler::Immediate& raw_null =
- compiler::Immediate(reinterpret_cast<intptr_t>(Object::null()));
+ compiler::Immediate(static_cast<intptr_t>(Object::null()));
compiler::Label is_instance, is_not_instance;
// 'null' is an instance of Null, Object*, Never*, void, and dynamic.
// In addition, 'null' is an instance of any nullable type.
@@ -688,7 +688,7 @@
compiler::Label is_assignable, runtime_call;
if (Instance::NullIsAssignableTo(dst_type)) {
const compiler::Immediate& raw_null =
- compiler::Immediate(reinterpret_cast<intptr_t>(Object::null()));
+ compiler::Immediate(static_cast<intptr_t>(Object::null()));
__ cmpl(EAX, raw_null);
__ j(EQUAL, &is_assignable);
}
@@ -762,7 +762,7 @@
__ movl(EBX, compiler::Address(ESP, 1 * kWordSize)); // Value.
__ StoreIntoObject(EAX, compiler::FieldAddress(EAX, offset), EBX);
const compiler::Immediate& raw_null =
- compiler::Immediate(reinterpret_cast<intptr_t>(Object::null()));
+ compiler::Immediate(static_cast<intptr_t>(Object::null()));
__ movl(EAX, raw_null);
__ ret();
}
@@ -819,7 +819,7 @@
__ Comment("Initialize spill slots");
if (num_locals > 1 || (num_locals == 1 && args_desc_slot == -1)) {
const compiler::Immediate& raw_null =
- compiler::Immediate(reinterpret_cast<intptr_t>(Object::null()));
+ compiler::Immediate(static_cast<intptr_t>(Object::null()));
__ movl(EAX, raw_null);
}
for (intptr_t i = 0; i < num_locals; ++i) {
@@ -859,7 +859,7 @@
void FlowGraphCompiler::GenerateDartCall(intptr_t deopt_id,
TokenPosition token_pos,
const Code& stub,
- RawPcDescriptors::Kind kind,
+ PcDescriptorsLayout::Kind kind,
LocationSummary* locs,
Code::EntryKind entry_kind) {
ASSERT(CanCallDart());
@@ -869,7 +869,7 @@
void FlowGraphCompiler::GenerateStaticDartCall(intptr_t deopt_id,
TokenPosition token_pos,
- RawPcDescriptors::Kind kind,
+ PcDescriptorsLayout::Kind kind,
LocationSummary* locs,
const Function& target,
Code::EntryKind entry_kind) {
@@ -886,7 +886,7 @@
intptr_t argument_count,
LocationSummary* locs) {
__ CallRuntime(entry, argument_count);
- EmitCallsiteMetadata(token_pos, deopt_id, RawPcDescriptors::kOther, locs);
+ EmitCallsiteMetadata(token_pos, deopt_id, PcDescriptorsLayout::kOther, locs);
}
void FlowGraphCompiler::EmitUnoptimizedStaticCall(intptr_t size_with_type_args,
@@ -900,7 +900,7 @@
StubCode::UnoptimizedStaticCallEntry(ic_data.NumArgsTested());
__ LoadObject(ECX, ic_data);
GenerateDartCall(deopt_id, token_pos, stub,
- RawPcDescriptors::kUnoptStaticCall, locs, entry_kind);
+ PcDescriptorsLayout::kUnoptStaticCall, locs, entry_kind);
__ Drop(size_with_type_args);
}
@@ -936,8 +936,8 @@
__ movl(EBX, compiler::Address(
ESP, (ic_data.SizeWithoutTypeArgs() - 1) * kWordSize));
__ LoadObject(ECX, ic_data);
- GenerateDartCall(deopt_id, token_pos, stub, RawPcDescriptors::kIcCall, locs,
- entry_kind);
+ GenerateDartCall(deopt_id, token_pos, stub, PcDescriptorsLayout::kIcCall,
+ locs, entry_kind);
__ Drop(ic_data.SizeWithTypeArgs());
}
@@ -961,7 +961,7 @@
? Code::entry_point_offset(Code::EntryKind::kMonomorphic)
: Code::entry_point_offset(Code::EntryKind::kMonomorphicUnchecked);
__ call(compiler::FieldAddress(CODE_REG, entry_point_offset));
- EmitCallsiteMetadata(token_pos, deopt_id, RawPcDescriptors::kIcCall, locs);
+ EmitCallsiteMetadata(token_pos, deopt_id, PcDescriptorsLayout::kIcCall, locs);
__ Drop(ic_data.SizeWithTypeArgs());
}
@@ -988,7 +988,7 @@
__ call(compiler::FieldAddress(
CODE_REG, Code::entry_point_offset(Code::EntryKind::kMonomorphic)));
- AddCurrentDescriptor(RawPcDescriptors::kOther, DeoptId::kNone, token_pos);
+ AddCurrentDescriptor(PcDescriptorsLayout::kOther, DeoptId::kNone, token_pos);
RecordSafepoint(locs, slow_path_argument_count);
const intptr_t deopt_id_after = DeoptId::ToDeoptAfter(deopt_id);
// Precompilation not implemented on ia32 platform.
@@ -998,7 +998,8 @@
} else {
// Add deoptimization continuation point after the call and before the
// arguments are removed.
- AddCurrentDescriptor(RawPcDescriptors::kDeopt, deopt_id_after, token_pos);
+ AddCurrentDescriptor(PcDescriptorsLayout::kDeopt, deopt_id_after,
+ token_pos);
}
RecordCatchEntryMoves(pending_deoptimization_env_, try_index);
__ Drop(args_desc.SizeWithTypeArgs());
@@ -1030,7 +1031,7 @@
}
// Do not use the code from the function, but let the code be patched so that
// we can record the outgoing edges to other code.
- GenerateStaticDartCall(deopt_id, token_pos, RawPcDescriptors::kOther, locs,
+ GenerateStaticDartCall(deopt_id, token_pos, PcDescriptorsLayout::kOther, locs,
function, entry_kind);
__ Drop(size_with_type_args);
}
@@ -1065,7 +1066,8 @@
} else {
__ Call(StubCode::UnoptimizedIdenticalWithNumberCheck());
}
- AddCurrentDescriptor(RawPcDescriptors::kRuntimeCall, deopt_id, token_pos);
+ AddCurrentDescriptor(PcDescriptorsLayout::kRuntimeCall, deopt_id,
+ token_pos);
// Stub returns result in flags (result of a cmpl, we need ZF computed).
__ popl(reg); // Discard constant.
__ popl(reg); // Restore 'reg'.
@@ -1088,7 +1090,8 @@
} else {
__ Call(StubCode::UnoptimizedIdenticalWithNumberCheck());
}
- AddCurrentDescriptor(RawPcDescriptors::kRuntimeCall, deopt_id, token_pos);
+ AddCurrentDescriptor(PcDescriptorsLayout::kRuntimeCall, deopt_id,
+ token_pos);
// Stub returns result in flags (result of a cmpl, we need ZF computed).
__ popl(right);
__ popl(left);
diff --git a/runtime/vm/compiler/backend/flow_graph_compiler_x64.cc b/runtime/vm/compiler/backend/flow_graph_compiler_x64.cc
index e75ab34..cefc349 100644
--- a/runtime/vm/compiler/backend/flow_graph_compiler_x64.cc
+++ b/runtime/vm/compiler/backend/flow_graph_compiler_x64.cc
@@ -94,9 +94,9 @@
intrinsic_mode_ = false;
}
-RawTypedData* CompilerDeoptInfo::CreateDeoptInfo(FlowGraphCompiler* compiler,
- DeoptInfoBuilder* builder,
- const Array& deopt_table) {
+TypedDataPtr CompilerDeoptInfo::CreateDeoptInfo(FlowGraphCompiler* compiler,
+ DeoptInfoBuilder* builder,
+ const Array& deopt_table) {
if (deopt_env_ == NULL) {
++builder->current_info_number_;
return TypedData::null();
@@ -226,7 +226,7 @@
// - RCX : function type arguments (if necessary).
//
// Preserves RAX/RCX/RDX.
-RawSubtypeTestCache* FlowGraphCompiler::GenerateCallSubtypeTestStub(
+SubtypeTestCachePtr FlowGraphCompiler::GenerateCallSubtypeTestStub(
TypeTestStubKind test_kind,
Register instance_reg,
Register instantiator_type_arguments_reg,
@@ -271,7 +271,7 @@
// be completed.
// RAX: instance (must survive).
// Clobbers R10.
-RawSubtypeTestCache*
+SubtypeTestCachePtr
FlowGraphCompiler::GenerateInstantiatedTypeWithArgumentsTest(
TokenPosition token_pos,
const AbstractType& type,
@@ -422,7 +422,7 @@
// TODO(srdjan): Implement a quicker subtype check, as type test
// arrays can grow too high, but they may be useful when optimizing
// code (type-feedback).
-RawSubtypeTestCache* FlowGraphCompiler::GenerateSubtype1TestCacheLookup(
+SubtypeTestCachePtr FlowGraphCompiler::GenerateSubtype1TestCacheLookup(
TokenPosition token_pos,
const Class& type_class,
compiler::Label* is_instance_lbl,
@@ -465,7 +465,7 @@
// - RCX : function type arguments (if necessary).
//
// Preserves RAX/RCX/RDX.
-RawSubtypeTestCache* FlowGraphCompiler::GenerateUninstantiatedTypeTest(
+SubtypeTestCachePtr FlowGraphCompiler::GenerateUninstantiatedTypeTest(
TokenPosition token_pos,
const AbstractType& type,
compiler::Label* is_instance_lbl,
@@ -540,7 +540,7 @@
// Generates function type check.
//
// See [GenerateUninstantiatedTypeTest] for calling convention.
-RawSubtypeTestCache* FlowGraphCompiler::GenerateFunctionTypeTest(
+SubtypeTestCachePtr FlowGraphCompiler::GenerateFunctionTypeTest(
TokenPosition token_pos,
const AbstractType& type,
compiler::Label* is_instance_lbl,
@@ -567,7 +567,7 @@
// Note that this inlined code must be followed by the runtime_call code, as it
// may fall through to it. Otherwise, this inline code will jump to the label
// is_instance or to the label is_not_instance.
-RawSubtypeTestCache* FlowGraphCompiler::GenerateInlineInstanceof(
+SubtypeTestCachePtr FlowGraphCompiler::GenerateInlineInstanceof(
TokenPosition token_pos,
const AbstractType& type,
compiler::Label* is_instance_lbl,
@@ -651,7 +651,7 @@
__ LoadUniqueObject(TypeTestABI::kDstTypeReg, type);
__ LoadUniqueObject(TypeTestABI::kSubtypeTestCacheReg, test_cache);
GenerateStubCall(token_pos, StubCode::InstanceOf(),
- /*kind=*/RawPcDescriptors::kOther, locs, deopt_id);
+ /*kind=*/PcDescriptorsLayout::kOther, locs, deopt_id);
__ jmp(&done, compiler::Assembler::kNearJump);
}
__ Bind(&is_not_instance);
@@ -769,7 +769,7 @@
__ call(compiler::FieldAddress(
kRegToCall, AbstractType::type_test_stub_entry_point_offset()));
}
- EmitCallsiteMetadata(token_pos, deopt_id, RawPcDescriptors::kOther, locs);
+ EmitCallsiteMetadata(token_pos, deopt_id, PcDescriptorsLayout::kOther, locs);
__ Bind(&done);
}
@@ -978,7 +978,7 @@
void FlowGraphCompiler::GeneratePatchableCall(TokenPosition token_pos,
const Code& stub,
- RawPcDescriptors::Kind kind,
+ PcDescriptorsLayout::Kind kind,
LocationSummary* locs) {
__ CallPatchable(stub);
EmitCallsiteMetadata(token_pos, DeoptId::kNone, kind, locs);
@@ -987,7 +987,7 @@
void FlowGraphCompiler::GenerateDartCall(intptr_t deopt_id,
TokenPosition token_pos,
const Code& stub,
- RawPcDescriptors::Kind kind,
+ PcDescriptorsLayout::Kind kind,
LocationSummary* locs,
Code::EntryKind entry_kind) {
ASSERT(CanCallDart());
@@ -997,7 +997,7 @@
void FlowGraphCompiler::GenerateStaticDartCall(intptr_t deopt_id,
TokenPosition token_pos,
- RawPcDescriptors::Kind kind,
+ PcDescriptorsLayout::Kind kind,
LocationSummary* locs,
const Function& target,
Code::EntryKind entry_kind) {
@@ -1025,7 +1025,7 @@
intptr_t argument_count,
LocationSummary* locs) {
__ CallRuntime(entry, argument_count);
- EmitCallsiteMetadata(token_pos, deopt_id, RawPcDescriptors::kOther, locs);
+ EmitCallsiteMetadata(token_pos, deopt_id, PcDescriptorsLayout::kOther, locs);
}
void FlowGraphCompiler::EmitUnoptimizedStaticCall(intptr_t size_with_type_args,
@@ -1039,7 +1039,7 @@
StubCode::UnoptimizedStaticCallEntry(ic_data.NumArgsTested());
__ LoadObject(RBX, ic_data);
GenerateDartCall(deopt_id, token_pos, stub,
- RawPcDescriptors::kUnoptStaticCall, locs, entry_kind);
+ PcDescriptorsLayout::kUnoptStaticCall, locs, entry_kind);
__ Drop(size_with_type_args, RCX);
}
@@ -1076,8 +1076,8 @@
__ movq(RDX, compiler::Address(
RSP, (ic_data.SizeWithoutTypeArgs() - 1) * kWordSize));
__ LoadUniqueObject(RBX, ic_data);
- GenerateDartCall(deopt_id, token_pos, stub, RawPcDescriptors::kIcCall, locs,
- entry_kind);
+ GenerateDartCall(deopt_id, token_pos, stub, PcDescriptorsLayout::kIcCall,
+ locs, entry_kind);
__ Drop(ic_data.SizeWithTypeArgs(), RCX);
}
@@ -1101,7 +1101,7 @@
? Code::entry_point_offset(Code::EntryKind::kMonomorphic)
: Code::entry_point_offset(Code::EntryKind::kMonomorphicUnchecked);
__ call(compiler::FieldAddress(CODE_REG, entry_point_offset));
- EmitCallsiteMetadata(token_pos, deopt_id, RawPcDescriptors::kIcCall, locs);
+ EmitCallsiteMetadata(token_pos, deopt_id, PcDescriptorsLayout::kIcCall, locs);
__ Drop(ic_data.SizeWithTypeArgs(), RCX);
}
@@ -1152,16 +1152,19 @@
if (try_index == kInvalidTryIndex) {
try_index = CurrentTryIndex();
}
- AddDescriptor(RawPcDescriptors::kOther, assembler()->CodeSize(),
+ AddDescriptor(PcDescriptorsLayout::kOther, assembler()->CodeSize(),
DeoptId::kNone, token_pos, try_index);
} else if (is_optimizing()) {
- AddCurrentDescriptor(RawPcDescriptors::kOther, DeoptId::kNone, token_pos);
+ AddCurrentDescriptor(PcDescriptorsLayout::kOther, DeoptId::kNone,
+ token_pos);
AddDeoptIndexAtCall(deopt_id_after);
} else {
- AddCurrentDescriptor(RawPcDescriptors::kOther, DeoptId::kNone, token_pos);
+ AddCurrentDescriptor(PcDescriptorsLayout::kOther, DeoptId::kNone,
+ token_pos);
// Add deoptimization continuation point after the call and before the
// arguments are removed.
- AddCurrentDescriptor(RawPcDescriptors::kDeopt, deopt_id_after, token_pos);
+ AddCurrentDescriptor(PcDescriptorsLayout::kDeopt, deopt_id_after,
+ token_pos);
}
RecordCatchEntryMoves(pending_deoptimization_env_, try_index);
__ Drop(args_desc.SizeWithTypeArgs(), RCX);
@@ -1204,7 +1207,7 @@
__ LoadUniqueObject(RBX, data);
__ call(RCX);
- EmitCallsiteMetadata(token_pos, deopt_id, RawPcDescriptors::kOther, locs);
+ EmitCallsiteMetadata(token_pos, deopt_id, PcDescriptorsLayout::kOther, locs);
__ Drop(ic_data.SizeWithTypeArgs(), RCX);
}
@@ -1227,7 +1230,7 @@
}
// Do not use the code from the function, but let the code be patched so that
// we can record the outgoing edges to other code.
- GenerateStaticDartCall(deopt_id, token_pos, RawPcDescriptors::kOther, locs,
+ GenerateStaticDartCall(deopt_id, token_pos, PcDescriptorsLayout::kOther, locs,
function, entry_kind);
__ Drop(size_with_type_args, RCX);
}
@@ -1271,7 +1274,8 @@
} else {
__ CallPatchable(StubCode::UnoptimizedIdenticalWithNumberCheck());
}
- AddCurrentDescriptor(RawPcDescriptors::kRuntimeCall, deopt_id, token_pos);
+ AddCurrentDescriptor(PcDescriptorsLayout::kRuntimeCall, deopt_id,
+ token_pos);
// Stub returns result in flags (result of a cmpq, we need ZF computed).
__ popq(reg); // Discard constant.
__ popq(reg); // Restore 'reg'.
@@ -1294,7 +1298,8 @@
} else {
__ CallPatchable(StubCode::UnoptimizedIdenticalWithNumberCheck());
}
- AddCurrentDescriptor(RawPcDescriptors::kRuntimeCall, deopt_id, token_pos);
+ AddCurrentDescriptor(PcDescriptorsLayout::kRuntimeCall, deopt_id,
+ token_pos);
// Stub returns result in flags (result of a cmpq, we need ZF computed).
__ popq(right);
__ popq(left);
diff --git a/runtime/vm/compiler/backend/il.cc b/runtime/vm/compiler/backend/il.cc
index 92ef4dc..3231fb8 100644
--- a/runtime/vm/compiler/backend/il.cc
+++ b/runtime/vm/compiler/backend/il.cc
@@ -3872,7 +3872,7 @@
void JoinEntryInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
__ Bind(compiler->GetJumpLabel(this));
if (!compiler->is_optimizing()) {
- compiler->AddCurrentDescriptor(RawPcDescriptors::kDeopt, GetDeoptId(),
+ compiler->AddCurrentDescriptor(PcDescriptorsLayout::kDeopt, GetDeoptId(),
TokenPosition::kNoSource);
}
if (HasParallelMove()) {
@@ -3899,7 +3899,7 @@
// The deoptimization descriptor points after the edge counter code for
// uniformity with ARM, where we can reuse pattern matching code that
// matches backwards from the end of the pattern.
- compiler->AddCurrentDescriptor(RawPcDescriptors::kDeopt, GetDeoptId(),
+ compiler->AddCurrentDescriptor(PcDescriptorsLayout::kDeopt, GetDeoptId(),
TokenPosition::kNoSource);
}
if (HasParallelMove()) {
@@ -3973,7 +3973,7 @@
// The deoptimization descriptor points after the edge counter code for
// uniformity with ARM, where we can reuse pattern matching code that
// matches backwards from the end of the pattern.
- compiler->AddCurrentDescriptor(RawPcDescriptors::kDeopt, GetDeoptId(),
+ compiler->AddCurrentDescriptor(PcDescriptorsLayout::kDeopt, GetDeoptId(),
TokenPosition::kNoSource);
}
if (HasParallelMove()) {
@@ -4082,7 +4082,7 @@
__ LoadObject(InitStaticFieldABI::kFieldReg,
Field::ZoneHandle(field().Original()));
compiler->GenerateStubCall(token_pos(), init_static_field_stub,
- /*kind=*/RawPcDescriptors::kOther, locs(),
+ /*kind=*/PcDescriptorsLayout::kOther, locs(),
deopt_id());
__ Bind(&no_call);
}
@@ -4116,7 +4116,7 @@
// so deoptimization environment has to be adjusted.
// This adjustment is done in FlowGraph::AttachEnvironment.
compiler->GenerateStubCall(token_pos(), stub,
- /*kind=*/RawPcDescriptors::kOther, locs(),
+ /*kind=*/PcDescriptorsLayout::kOther, locs(),
deopt_id());
__ Bind(&no_call);
}
@@ -4136,7 +4136,7 @@
Code::ZoneHandle(compiler->zone(), object_store->throw_stub());
compiler->GenerateStubCall(token_pos(), throw_stub,
- /*kind=*/RawPcDescriptors::kOther, locs(),
+ /*kind=*/PcDescriptorsLayout::kOther, locs(),
deopt_id());
// Issue(dartbug.com/41353): Right now we have to emit an extra breakpoint
// instruction: The ThrowInstr will terminate the current block. The very
@@ -4164,7 +4164,7 @@
compiler->SetNeedsStackTrace(catch_try_index());
compiler->GenerateStubCall(token_pos(), re_throw_stub,
- /*kind=*/RawPcDescriptors::kOther, locs(),
+ /*kind=*/PcDescriptorsLayout::kOther, locs(),
deopt_id());
// Issue(dartbug.com/41353): Right now we have to emit an extra breakpoint
// instruction: The ThrowInstr will terminate the current block. The very
@@ -4198,7 +4198,7 @@
__ CompareObject(AssertBooleanABI::kObjectReg, Object::null_instance());
__ BranchIf(NOT_EQUAL, &done);
compiler->GenerateStubCall(token_pos(), assert_boolean_stub,
- /*kind=*/RawPcDescriptors::kOther, locs(),
+ /*kind=*/PcDescriptorsLayout::kOther, locs(),
deopt_id());
__ Bind(&done);
}
@@ -4489,7 +4489,7 @@
return MakeCallSummary(zone, this);
}
-static RawCode* TwoArgsSmiOpInlineCacheEntry(Token::Kind kind) {
+static CodePtr TwoArgsSmiOpInlineCacheEntry(Token::Kind kind) {
if (!FLAG_two_args_smi_icd) {
return Code::null();
}
@@ -4596,7 +4596,7 @@
}
} else {
// Unoptimized code.
- compiler->AddCurrentDescriptor(RawPcDescriptors::kRewind, deopt_id(),
+ compiler->AddCurrentDescriptor(PcDescriptorsLayout::kRewind, deopt_id(),
token_pos());
bool is_smi_two_args_op = false;
const Code& stub =
@@ -4622,7 +4622,7 @@
return Library::IsPrivateCoreLibName(function_name(), name);
}
-RawFunction* InstanceCallBaseInstr::ResolveForReceiverClass(
+FunctionPtr InstanceCallBaseInstr::ResolveForReceiverClass(
const Class& cls,
bool allow_add /* = true */) {
const Array& args_desc_array = Array::Handle(GetArgumentsDescriptor());
@@ -4719,7 +4719,7 @@
compiler->EmitDispatchTableCall(cid_reg, selector()->offset,
arguments_descriptor);
compiler->EmitCallsiteMetadata(token_pos(), DeoptId::kNone,
- RawPcDescriptors::kOther, locs());
+ PcDescriptorsLayout::kOther, locs());
if (selector()->called_on_null && !selector()->on_null_interface) {
Value* receiver = ArgumentValueAt(FirstArgIndex());
if (receiver->Type()->is_nullable()) {
@@ -4850,7 +4850,7 @@
total_call_count(), !receiver_is_not_smi());
}
-RawType* PolymorphicInstanceCallInstr::ComputeRuntimeType(
+TypePtr PolymorphicInstanceCallInstr::ComputeRuntimeType(
const CallTargets& targets) {
bool is_string = true;
bool is_integer = true;
diff --git a/runtime/vm/compiler/backend/il.h b/runtime/vm/compiler/backend/il.h
index de48463..7bdedf6 100644
--- a/runtime/vm/compiler/backend/il.h
+++ b/runtime/vm/compiler/backend/il.h
@@ -2797,7 +2797,7 @@
ReturnInstr(TokenPosition token_pos,
Value* value,
intptr_t deopt_id,
- intptr_t yield_index = RawPcDescriptors::kInvalidYieldIndex,
+ intptr_t yield_index = PcDescriptorsLayout::kInvalidYieldIndex,
Representation representation = kTagged)
: TemplateInstruction(deopt_id),
token_pos_(token_pos),
@@ -3693,7 +3693,7 @@
(type_args_len > 0 ? 1 : 0)),
argument_names(argument_names) {}
- RawArray* ToArgumentsDescriptor() const {
+ ArrayPtr ToArgumentsDescriptor() const {
return ArgumentsDescriptor::New(type_args_len, count_without_type_args,
size_without_type_args, argument_names);
}
@@ -3726,7 +3726,7 @@
}
}
- RawString* Selector() {
+ StringPtr Selector() {
if (auto static_call = this->AsStaticCall()) {
return static_call->function().name();
} else if (auto instance_call = this->AsInstanceCall()) {
@@ -3783,7 +3783,7 @@
intptr_t type_args_len() const { return type_args_len_; }
const Array& argument_names() const { return argument_names_; }
virtual TokenPosition token_pos() const { return token_pos_; }
- RawArray* GetArgumentsDescriptor() const {
+ ArrayPtr GetArgumentsDescriptor() const {
return ArgumentsDescriptor::New(
type_args_len(), ArgumentCountWithoutTypeArgs(),
ArgumentsSizeWithoutTypeArgs(), argument_names());
@@ -3927,7 +3927,7 @@
return result_type_->ToCid();
}
- RawFunction* ResolveForReceiverClass(const Class& cls, bool allow_add = true);
+ FunctionPtr ResolveForReceiverClass(const Class& cls, bool allow_add = true);
Code::EntryKind entry_kind() const { return entry_kind_; }
void set_entry_kind(Code::EntryKind value) { entry_kind_ = value; }
@@ -4124,7 +4124,7 @@
virtual Definition* Canonicalize(FlowGraph* graph);
- static RawType* ComputeRuntimeType(const CallTargets& targets);
+ static TypePtr ComputeRuntimeType(const CallTargets& targets);
PRINT_OPERANDS_TO_SUPPORT
ADD_EXTRA_INFO_TO_S_EXPRESSION_SUPPORT
@@ -5024,7 +5024,7 @@
class DebugStepCheckInstr : public TemplateInstruction<0, NoThrow> {
public:
DebugStepCheckInstr(TokenPosition token_pos,
- RawPcDescriptors::Kind stub_kind,
+ PcDescriptorsLayout::Kind stub_kind,
intptr_t deopt_id)
: TemplateInstruction<0, NoThrow>(deopt_id),
token_pos_(token_pos),
@@ -5041,7 +5041,7 @@
private:
const TokenPosition token_pos_;
- const RawPcDescriptors::Kind stub_kind_;
+ const PcDescriptorsLayout::Kind stub_kind_;
DISALLOW_COPY_AND_ASSIGN(DebugStepCheckInstr);
};
@@ -5254,7 +5254,7 @@
// For a field of static type G<T0, ..., Tn> and a stored value of runtime
// type T checks that type arguments of T at G exactly match <T0, ..., Tn>
-// and updates guarded state (RawField::static_type_exactness_state_)
+// and updates guarded state (FieldLayout::static_type_exactness_state_)
// accordingly.
//
// See StaticTypeExactnessState for more information.
diff --git a/runtime/vm/compiler/backend/il_arm.cc b/runtime/vm/compiler/backend/il_arm.cc
index 71bb295..ceb2152 100644
--- a/runtime/vm/compiler/backend/il_arm.cc
+++ b/runtime/vm/compiler/backend/il_arm.cc
@@ -383,7 +383,7 @@
__ Bind(&stack_ok);
#endif
ASSERT(__ constant_pool_allowed());
- if (yield_index() != RawPcDescriptors::kInvalidYieldIndex) {
+ if (yield_index() != PcDescriptorsLayout::kInvalidYieldIndex) {
compiler->EmitYieldPositionMetadata(token_pos(), yield_index());
}
__ LeaveDartFrameAndReturn(); // Disallows constant pool use.
@@ -504,7 +504,7 @@
}
__ blx(R2);
compiler->EmitCallsiteMetadata(token_pos(), deopt_id(),
- RawPcDescriptors::kOther, locs());
+ PcDescriptorsLayout::kOther, locs());
__ Drop(argument_count);
}
@@ -1154,9 +1154,9 @@
: compiler::ObjectPoolBuilderEntry::kNotPatchable);
if (link_lazily()) {
compiler->GeneratePatchableCall(token_pos(), *stub,
- RawPcDescriptors::kOther, locs());
+ PcDescriptorsLayout::kOther, locs());
} else {
- compiler->GenerateStubCall(token_pos(), *stub, RawPcDescriptors::kOther,
+ compiler->GenerateStubCall(token_pos(), *stub, PcDescriptorsLayout::kOther,
locs());
}
__ Pop(result);
@@ -1196,7 +1196,7 @@
// instruction. Therefore we emit the metadata here, 8 bytes (2 instructions)
// after the original mov.
compiler->EmitCallsiteMetadata(TokenPosition::kNoSource, DeoptId::kNone,
- RawPcDescriptors::Kind::kOther, locs());
+ PcDescriptorsLayout::Kind::kOther, locs());
// Update information in the thread object and enter a safepoint.
if (CanExecuteGeneratedCodeInSafepoint()) {
@@ -2450,7 +2450,7 @@
compiler->SaveLiveRegisters(locs);
compiler->GenerateStubCall(TokenPosition::kNoSource, // No token position.
- stub, RawPcDescriptors::kOther, locs);
+ stub, PcDescriptorsLayout::kOther, locs);
__ MoveRegister(result_, R0);
compiler->RestoreLiveRegisters(locs);
__ b(exit_label());
@@ -2993,7 +2993,7 @@
// data area to be initialized.
// R8: null
if (num_elements > 0) {
- const intptr_t array_size = instance_size - sizeof(RawArray);
+ const intptr_t array_size = instance_size - sizeof(ArrayLayout);
__ LoadObject(R8, Object::null_object());
if (num_elements >= 2) {
__ mov(R9, compiler::Operand(R8));
@@ -3003,7 +3003,7 @@
__ LoadImmediate(R9, 0x1);
#endif // DEBUG
}
- __ AddImmediate(R6, R0, sizeof(RawArray) - kHeapObjectTag);
+ __ AddImmediate(R6, R0, sizeof(ArrayLayout) - kHeapObjectTag);
if (array_size < (kInlineArraySize * compiler::target::kWordSize)) {
__ InitializeFieldsNoBarrierUnrolled(
R0, R6, 0, num_elements * compiler::target::kWordSize, R8, R9);
@@ -3055,7 +3055,7 @@
const auto& allocate_array_stub =
Code::ZoneHandle(compiler->zone(), object_store->allocate_array_stub());
compiler->GenerateStubCall(token_pos(), allocate_array_stub,
- RawPcDescriptors::kOther, locs(), deopt_id());
+ PcDescriptorsLayout::kOther, locs(), deopt_id());
ASSERT(locs()->out(0).reg() == kResultReg);
}
@@ -3318,8 +3318,8 @@
// Lookup cache in stub before calling runtime.
__ LoadObject(InstantiationABI::kUninstantiatedTypeArgumentsReg,
type_arguments());
- compiler->GenerateStubCall(token_pos(), GetStub(), RawPcDescriptors::kOther,
- locs());
+ compiler->GenerateStubCall(token_pos(), GetStub(),
+ PcDescriptorsLayout::kOther, locs());
__ Bind(&type_arguments_instantiated);
}
@@ -3359,8 +3359,8 @@
compiler->zone(), object_store->allocate_context_stub());
__ LoadImmediate(R1, instruction()->num_context_variables());
compiler->GenerateStubCall(instruction()->token_pos(),
- allocate_context_stub, RawPcDescriptors::kOther,
- locs);
+ allocate_context_stub,
+ PcDescriptorsLayout::kOther, locs);
ASSERT(instruction()->locs()->out(0).reg() == R0);
compiler->RestoreLiveRegisters(instruction()->locs());
__ b(exit_label());
@@ -3410,7 +3410,7 @@
Code::ZoneHandle(compiler->zone(), object_store->allocate_context_stub());
__ LoadImmediate(R1, num_context_variables());
compiler->GenerateStubCall(token_pos(), allocate_context_stub,
- RawPcDescriptors::kOther, locs());
+ PcDescriptorsLayout::kOther, locs());
}
LocationSummary* CloneContextInstr::MakeLocationSummary(Zone* zone,
@@ -3432,7 +3432,7 @@
const auto& clone_context_stub =
Code::ZoneHandle(compiler->zone(), object_store->clone_context_stub());
compiler->GenerateStubCall(token_pos(), clone_context_stub,
- /*kind=*/RawPcDescriptors::kOther, locs());
+ /*kind=*/PcDescriptorsLayout::kOther, locs());
}
LocationSummary* CatchBlockEntryInstr::MakeLocationSummary(Zone* zone,
@@ -3453,7 +3453,7 @@
if (compiler->is_optimizing()) {
compiler->AddDeoptIndexAtCall(deopt_id);
} else {
- compiler->AddCurrentDescriptor(RawPcDescriptors::kDeopt, deopt_id,
+ compiler->AddCurrentDescriptor(PcDescriptorsLayout::kDeopt, deopt_id,
TokenPosition::kNoSource);
}
}
@@ -3540,7 +3540,7 @@
compiler->RecordSafepoint(instruction()->locs(), kNumSlowPathArgs);
compiler->RecordCatchEntryMoves();
compiler->AddDescriptor(
- RawPcDescriptors::kOther, compiler->assembler()->CodeSize(),
+ PcDescriptorsLayout::kOther, compiler->assembler()->CodeSize(),
instruction()->deopt_id(), instruction()->token_pos(),
compiler->CurrentTryIndex());
} else {
@@ -3552,7 +3552,7 @@
if (compiler->isolate()->use_osr() && !compiler->is_optimizing() &&
instruction()->in_loop()) {
// In unoptimized code, record loop stack checks as possible OSR entries.
- compiler->AddCurrentDescriptor(RawPcDescriptors::kOsrEntry,
+ compiler->AddCurrentDescriptor(PcDescriptorsLayout::kOsrEntry,
instruction()->deopt_id(),
TokenPosition::kNoSource);
}
@@ -3595,7 +3595,7 @@
// the stub above).
auto extended_env = compiler->SlowPathEnvironmentFor(this, 0);
compiler->EmitCallsiteMetadata(token_pos(), deopt_id(),
- RawPcDescriptors::kOther, locs(),
+ PcDescriptorsLayout::kOther, locs(),
extended_env);
return;
}
@@ -4780,6 +4780,7 @@
!Isolate::Current()
->object_store()
->allocate_mint_with_fpu_regs_stub()
+ ->ptr()
->InVMIsolateHeap())
? LocationSummary::kCallOnSharedSlowPath
: LocationSummary::kCallOnSlowPath));
@@ -4826,7 +4827,7 @@
ASSERT(!locs()->live_registers()->ContainsRegister(R0));
auto extended_env = compiler->SlowPathEnvironmentFor(this, 0);
- compiler->GenerateStubCall(token_pos(), stub, RawPcDescriptors::kOther,
+ compiler->GenerateStubCall(token_pos(), stub, PcDescriptorsLayout::kOther,
locs(), DeoptId::kNone, extended_env);
} else {
BoxAllocationSlowPath::Allocate(compiler, this, compiler->mint_class(),
@@ -6392,7 +6393,7 @@
// the stub above).
auto extended_env = compiler->SlowPathEnvironmentFor(this, 0);
compiler->EmitCallsiteMetadata(token_pos(), deopt_id(),
- RawPcDescriptors::kOther, locs(),
+ PcDescriptorsLayout::kOther, locs(),
extended_env);
CheckNullInstr::AddMetadataForRuntimeCall(this, compiler);
return;
@@ -7300,7 +7301,7 @@
}
// Add a deoptimization descriptor for deoptimizing instructions that
// may be inserted before this instruction.
- compiler->AddCurrentDescriptor(RawPcDescriptors::kDeopt, GetDeoptId(),
+ compiler->AddCurrentDescriptor(PcDescriptorsLayout::kDeopt, GetDeoptId(),
TokenPosition::kNoSource);
}
if (HasParallelMove()) {
@@ -7474,7 +7475,7 @@
}
const Code& stub = Code::ZoneHandle(
compiler->zone(), StubCode::GetAllocationStubForClass(cls()));
- compiler->GenerateStubCall(token_pos(), stub, RawPcDescriptors::kOther,
+ compiler->GenerateStubCall(token_pos(), stub, PcDescriptorsLayout::kOther,
locs());
}
diff --git a/runtime/vm/compiler/backend/il_arm64.cc b/runtime/vm/compiler/backend/il_arm64.cc
index 10bac83..0e5989c 100644
--- a/runtime/vm/compiler/backend/il_arm64.cc
+++ b/runtime/vm/compiler/backend/il_arm64.cc
@@ -283,7 +283,7 @@
__ Bind(&stack_ok);
#endif
ASSERT(__ constant_pool_allowed());
- if (yield_index() != RawPcDescriptors::kInvalidYieldIndex) {
+ if (yield_index() != PcDescriptorsLayout::kInvalidYieldIndex) {
compiler->EmitYieldPositionMetadata(token_pos(), yield_index());
}
__ LeaveDartFrame(); // Disallows constant pool use.
@@ -400,7 +400,7 @@
}
__ blr(R2);
compiler->EmitCallsiteMetadata(token_pos(), deopt_id(),
- RawPcDescriptors::kOther, locs());
+ PcDescriptorsLayout::kOther, locs());
__ Drop(argument_count);
}
@@ -837,7 +837,7 @@
Location right = locs()->in(1);
if (right.IsConstant()) {
ASSERT(right.constant().IsSmi());
- const int64_t imm = reinterpret_cast<int64_t>(right.constant().raw());
+ const int64_t imm = static_cast<int64_t>(right.constant().raw());
__ TestImmediate(left, imm);
} else {
__ tst(left, compiler::Operand(right.reg()));
@@ -980,9 +980,9 @@
: ObjectPool::Patchability::kNotPatchable);
if (link_lazily()) {
compiler->GeneratePatchableCall(token_pos(), *stub,
- RawPcDescriptors::kOther, locs());
+ PcDescriptorsLayout::kOther, locs());
} else {
- compiler->GenerateStubCall(token_pos(), *stub, RawPcDescriptors::kOther,
+ compiler->GenerateStubCall(token_pos(), *stub, PcDescriptorsLayout::kOther,
locs());
}
__ Pop(result);
@@ -1017,7 +1017,7 @@
// instruction.
__ adr(temp, compiler::Immediate(Instr::kInstrSize));
compiler->EmitCallsiteMetadata(token_pos(), DeoptId::kNone,
- RawPcDescriptors::Kind::kOther, locs());
+ PcDescriptorsLayout::Kind::kOther, locs());
__ StoreToOffset(temp, FPREG, kSavedCallerPcSlotFromFp * kWordSize);
@@ -2108,7 +2108,7 @@
compiler->SaveLiveRegisters(locs);
compiler->GenerateStubCall(TokenPosition::kNoSource, // No token position.
- stub, RawPcDescriptors::kOther, locs);
+ stub, PcDescriptorsLayout::kOther, locs);
__ MoveRegister(result_, R0);
compiler->RestoreLiveRegisters(locs);
__ b(exit_label());
@@ -2505,9 +2505,9 @@
// data area to be initialized.
// R6: null
if (num_elements > 0) {
- const intptr_t array_size = instance_size - sizeof(RawArray);
+ const intptr_t array_size = instance_size - sizeof(ArrayLayout);
__ LoadObject(R6, Object::null_object());
- __ AddImmediate(R8, R0, sizeof(RawArray) - kHeapObjectTag);
+ __ AddImmediate(R8, R0, sizeof(ArrayLayout) - kHeapObjectTag);
if (array_size < (kInlineArraySize * kWordSize)) {
intptr_t current_offset = 0;
while (current_offset < array_size) {
@@ -2566,7 +2566,7 @@
const auto& allocate_array_stub =
Code::ZoneHandle(compiler->zone(), object_store->allocate_array_stub());
compiler->GenerateStubCall(token_pos(), allocate_array_stub,
- RawPcDescriptors::kOther, locs(), deopt_id());
+ PcDescriptorsLayout::kOther, locs(), deopt_id());
ASSERT(locs()->out(0).reg() == kResultReg);
}
@@ -2807,8 +2807,8 @@
// Lookup cache in stub before calling runtime.
__ LoadObject(InstantiationABI::kUninstantiatedTypeArgumentsReg,
type_arguments());
- compiler->GenerateStubCall(token_pos(), GetStub(), RawPcDescriptors::kOther,
- locs());
+ compiler->GenerateStubCall(token_pos(), GetStub(),
+ PcDescriptorsLayout::kOther, locs());
__ Bind(&type_arguments_instantiated);
}
@@ -2849,8 +2849,8 @@
__ LoadImmediate(R1, instruction()->num_context_variables());
compiler->GenerateStubCall(instruction()->token_pos(),
- allocate_context_stub, RawPcDescriptors::kOther,
- locs);
+ allocate_context_stub,
+ PcDescriptorsLayout::kOther, locs);
ASSERT(instruction()->locs()->out(0).reg() == R0);
compiler->RestoreLiveRegisters(instruction()->locs());
__ b(exit_label());
@@ -2900,7 +2900,7 @@
Code::ZoneHandle(compiler->zone(), object_store->allocate_context_stub());
__ LoadImmediate(R1, num_context_variables());
compiler->GenerateStubCall(token_pos(), allocate_context_stub,
- RawPcDescriptors::kOther, locs());
+ PcDescriptorsLayout::kOther, locs());
}
LocationSummary* CloneContextInstr::MakeLocationSummary(Zone* zone,
@@ -2922,7 +2922,7 @@
const auto& clone_context_stub =
Code::ZoneHandle(compiler->zone(), object_store->clone_context_stub());
compiler->GenerateStubCall(token_pos(), clone_context_stub,
- /*kind=*/RawPcDescriptors::kOther, locs());
+ /*kind=*/PcDescriptorsLayout::kOther, locs());
}
LocationSummary* CatchBlockEntryInstr::MakeLocationSummary(Zone* zone,
@@ -2943,7 +2943,7 @@
if (compiler->is_optimizing()) {
compiler->AddDeoptIndexAtCall(deopt_id);
} else {
- compiler->AddCurrentDescriptor(RawPcDescriptors::kDeopt, deopt_id,
+ compiler->AddCurrentDescriptor(PcDescriptorsLayout::kDeopt, deopt_id,
TokenPosition::kNoSource);
}
}
@@ -3042,7 +3042,7 @@
compiler->RecordSafepoint(locs, kNumSlowPathArgs);
compiler->RecordCatchEntryMoves();
compiler->AddDescriptor(
- RawPcDescriptors::kOther, compiler->assembler()->CodeSize(),
+ PcDescriptorsLayout::kOther, compiler->assembler()->CodeSize(),
instruction()->deopt_id(), instruction()->token_pos(),
compiler->CurrentTryIndex());
} else {
@@ -3054,7 +3054,7 @@
if (compiler->isolate()->use_osr() && !compiler->is_optimizing() &&
instruction()->in_loop()) {
// In unoptimized code, record loop stack checks as possible OSR entries.
- compiler->AddCurrentDescriptor(RawPcDescriptors::kOsrEntry,
+ compiler->AddCurrentDescriptor(PcDescriptorsLayout::kOsrEntry,
instruction()->deopt_id(),
TokenPosition::kNoSource);
}
@@ -3151,8 +3151,7 @@
const bool right_needs_check =
!RangeUtils::IsWithin(right_range, 0, max_right - 1);
if (right_needs_check) {
- __ CompareImmediate(right,
- reinterpret_cast<int64_t>(Smi::New(max_right)));
+ __ CompareImmediate(right, static_cast<int64_t>(Smi::New(max_right)));
__ b(deopt, CS);
}
__ SmiUntag(TMP, right);
@@ -3171,8 +3170,7 @@
__ b(deopt, MI);
}
- __ CompareImmediate(right,
- reinterpret_cast<int64_t>(Smi::New(Smi::kBits)));
+ __ CompareImmediate(right, static_cast<int64_t>(Smi::New(Smi::kBits)));
__ csel(result, ZR, result, CS);
__ SmiUntag(TMP, right);
__ lslv(TMP, left, TMP);
@@ -3184,8 +3182,7 @@
} else {
if (right_needs_check) {
ASSERT(shift_left->CanDeoptimize());
- __ CompareImmediate(right,
- reinterpret_cast<int64_t>(Smi::New(Smi::kBits)));
+ __ CompareImmediate(right, static_cast<int64_t>(Smi::New(Smi::kBits)));
__ b(deopt, CS);
}
// Left is not a constant.
@@ -3309,8 +3306,7 @@
case Token::kSHL:
ASSERT(result != left);
ASSERT(result != right);
- __ CompareImmediate(right,
- reinterpret_cast<int64_t>(Smi::New(Smi::kBits)));
+ __ CompareImmediate(right, static_cast<int64_t>(Smi::New(Smi::kBits)));
__ b(slow_path->entry_label(), CS);
__ SmiUntag(TMP, right);
@@ -3322,8 +3318,7 @@
case Token::kSHR:
ASSERT(result != left);
ASSERT(result != right);
- __ CompareImmediate(right,
- reinterpret_cast<int64_t>(Smi::New(Smi::kBits)));
+ __ CompareImmediate(right, static_cast<int64_t>(Smi::New(Smi::kBits)));
__ b(slow_path->entry_label(), CS);
__ SmiUntag(result, right);
@@ -3542,7 +3537,7 @@
if (locs()->in(1).IsConstant()) {
const Object& constant = locs()->in(1).constant();
ASSERT(constant.IsSmi());
- const int64_t imm = reinterpret_cast<int64_t>(constant.raw());
+ const int64_t imm = static_cast<int64_t>(constant.raw());
switch (op_kind()) {
case Token::kADD: {
if (deopt == NULL) {
@@ -3972,10 +3967,12 @@
const bool stubs_in_vm_isolate = (Isolate::Current()
->object_store()
->allocate_mint_with_fpu_regs_stub()
+ ->ptr()
->InVMIsolateHeap() ||
Isolate::Current()
->object_store()
->allocate_mint_without_fpu_regs_stub()
+ ->ptr()
->InVMIsolateHeap());
const bool shared_slow_path_call = SlowPathSharingSupported(opt) &&
FLAG_use_bare_instructions &&
@@ -4030,7 +4027,7 @@
ASSERT(!locs()->live_registers()->ContainsRegister(R0));
auto extended_env = compiler->SlowPathEnvironmentFor(this, 0);
- compiler->GenerateStubCall(token_pos(), stub, RawPcDescriptors::kOther,
+ compiler->GenerateStubCall(token_pos(), stub, PcDescriptorsLayout::kOther,
locs(), DeoptId::kNone, extended_env);
} else {
BoxAllocationSlowPath::Allocate(compiler, this, compiler->mint_class(),
@@ -5409,7 +5406,7 @@
if (index_loc.IsConstant()) {
const Register length = length_loc.reg();
const Smi& index = Smi::Cast(index_loc.constant());
- __ CompareImmediate(length, reinterpret_cast<int64_t>(index.raw()));
+ __ CompareImmediate(length, static_cast<int64_t>(index.raw()));
__ b(deopt, LS);
} else if (length_loc.IsConstant()) {
const Smi& length = Smi::Cast(length_loc.constant());
@@ -5421,7 +5418,7 @@
__ tst(index, compiler::Operand(index));
__ b(deopt, MI);
} else {
- __ CompareImmediate(index, reinterpret_cast<int64_t>(length.raw()));
+ __ CompareImmediate(index, static_cast<int64_t>(length.raw()));
__ b(deopt, CS);
}
} else {
@@ -6250,7 +6247,7 @@
}
// Add a deoptimization descriptor for deoptimizing instructions that
// may be inserted before this instruction.
- compiler->AddCurrentDescriptor(RawPcDescriptors::kDeopt, GetDeoptId(),
+ compiler->AddCurrentDescriptor(PcDescriptorsLayout::kDeopt, GetDeoptId(),
TokenPosition::kNoSource);
}
if (HasParallelMove()) {
@@ -6417,7 +6414,7 @@
}
const Code& stub = Code::ZoneHandle(
compiler->zone(), StubCode::GetAllocationStubForClass(cls()));
- compiler->GenerateStubCall(token_pos(), stub, RawPcDescriptors::kOther,
+ compiler->GenerateStubCall(token_pos(), stub, PcDescriptorsLayout::kOther,
locs());
}
diff --git a/runtime/vm/compiler/backend/il_deserializer.cc b/runtime/vm/compiler/backend/il_deserializer.cc
index dc524d3..98c044d 100644
--- a/runtime/vm/compiler/backend/il_deserializer.cc
+++ b/runtime/vm/compiler/backend/il_deserializer.cc
@@ -1013,10 +1013,10 @@
DebugStepCheckInstr* FlowGraphDeserializer::DeserializeDebugStepCheck(
SExpList* sexp,
const InstrInfo& info) {
- auto kind = RawPcDescriptors::kAnyKind;
+ auto kind = PcDescriptorsLayout::kAnyKind;
if (auto const kind_sexp = CheckSymbol(Retrieve(sexp, "stub_kind"))) {
- if (!RawPcDescriptors::ParseKind(kind_sexp->value(), &kind)) {
- StoreError(kind_sexp, "not a valid RawPcDescriptors::Kind name");
+ if (!PcDescriptorsLayout::ParseKind(kind_sexp->value(), &kind)) {
+ StoreError(kind_sexp, "not a valid PcDescriptorsLayout::Kind name");
return nullptr;
}
}
@@ -1641,13 +1641,13 @@
auto& function = Function::Cast(*out);
// Check the kind expected by the S-expression if one was specified.
if (auto const kind_sexp = CheckSymbol(list->ExtraLookupValue("kind"))) {
- RawFunction::Kind kind;
- if (!RawFunction::ParseKind(kind_sexp->value(), &kind)) {
+ FunctionLayout::Kind kind;
+ if (!FunctionLayout::ParseKind(kind_sexp->value(), &kind)) {
StoreError(kind_sexp, "unexpected function kind");
return false;
}
if (function.kind() != kind) {
- auto const kind_str = RawFunction::KindToCString(function.kind());
+ auto const kind_str = FunctionLayout::KindToCString(function.kind());
StoreError(list, "retrieved function has kind %s", kind_str);
return false;
}
diff --git a/runtime/vm/compiler/backend/il_ia32.cc b/runtime/vm/compiler/backend/il_ia32.cc
index 57c00db..addc43e 100644
--- a/runtime/vm/compiler/backend/il_ia32.cc
+++ b/runtime/vm/compiler/backend/il_ia32.cc
@@ -140,7 +140,7 @@
__ int3();
__ Bind(&done);
#endif
- if (yield_index() != RawPcDescriptors::kInvalidYieldIndex) {
+ if (yield_index() != PcDescriptorsLayout::kInvalidYieldIndex) {
compiler->EmitYieldPositionMetadata(token_pos(), yield_index());
}
__ LeaveFrame();
@@ -324,7 +324,7 @@
} else {
if (compiler::Assembler::IsSafeSmi(value_) || value_.IsNull()) {
__ movl(LocationToStackSlotAddress(destination),
- compiler::Immediate(reinterpret_cast<int32_t>(value_.raw())));
+ compiler::Immediate(static_cast<int32_t>(value_.raw())));
} else {
__ pushl(EAX);
__ LoadObjectSafely(EAX, value_);
@@ -713,7 +713,7 @@
Location right = locs()->in(1);
if (right.IsConstant()) {
ASSERT(right.constant().IsSmi());
- const int32_t imm = reinterpret_cast<int32_t>(right.constant().raw());
+ const int32_t imm = static_cast<int32_t>(right.constant().raw());
__ testl(left, compiler::Immediate(imm));
} else {
__ testl(left, right.reg());
@@ -856,7 +856,7 @@
const compiler::ExternalLabel label(
reinterpret_cast<uword>(native_c_function()));
__ movl(ECX, compiler::Immediate(label.address()));
- compiler->GenerateStubCall(token_pos(), *stub, RawPcDescriptors::kOther,
+ compiler->GenerateStubCall(token_pos(), *stub, PcDescriptorsLayout::kOther,
locs());
__ popl(result);
@@ -893,7 +893,7 @@
compiler::Label get_pc;
__ call(&get_pc);
compiler->EmitCallsiteMetadata(TokenPosition::kNoSource, DeoptId::kNone,
- RawPcDescriptors::Kind::kOther, locs());
+ PcDescriptorsLayout::Kind::kOther, locs());
__ Bind(&get_pc);
__ popl(temp);
__ movl(compiler::Address(FPREG, kSavedCallerPcSlotFromFp * kWordSize), temp);
@@ -1729,7 +1729,7 @@
__ cmpl(value_cid_reg, compiler::Immediate(kNullCid));
} else {
const compiler::Immediate& raw_null =
- compiler::Immediate(reinterpret_cast<intptr_t>(Object::null()));
+ compiler::Immediate(static_cast<intptr_t>(Object::null()));
__ cmpl(value_reg, raw_null);
}
}
@@ -1853,7 +1853,7 @@
compiler->SaveLiveRegisters(locs);
compiler->GenerateStubCall(TokenPosition::kNoSource, stub,
- RawPcDescriptors::kOther, locs);
+ PcDescriptorsLayout::kOther, locs);
__ MoveRegister(result_, EAX);
compiler->RestoreLiveRegisters(locs);
__ jmp(exit_label());
@@ -1924,7 +1924,7 @@
Register temp) {
compiler::Label done;
const compiler::Immediate& raw_null =
- compiler::Immediate(reinterpret_cast<intptr_t>(Object::null()));
+ compiler::Immediate(static_cast<intptr_t>(Object::null()));
__ movl(box_reg, compiler::FieldAddress(instance_reg, offset));
__ cmpl(box_reg, raw_null);
__ j(NOT_EQUAL, &done);
@@ -2227,10 +2227,10 @@
// EDI: iterator which initially points to the start of the variable
// data area to be initialized.
if (num_elements > 0) {
- const intptr_t array_size = instance_size - sizeof(RawArray);
+ const intptr_t array_size = instance_size - sizeof(ArrayLayout);
const compiler::Immediate& raw_null =
- compiler::Immediate(reinterpret_cast<intptr_t>(Object::null()));
- __ leal(EDI, compiler::FieldAddress(EAX, sizeof(RawArray)));
+ compiler::Immediate(static_cast<intptr_t>(Object::null()));
+ __ leal(EDI, compiler::FieldAddress(EAX, sizeof(ArrayLayout)));
if (array_size < (kInlineArraySize * kWordSize)) {
intptr_t current_offset = 0;
__ movl(EBX, raw_null);
@@ -2282,7 +2282,7 @@
__ Bind(&slow_path);
compiler->GenerateStubCall(token_pos(), StubCode::AllocateArray(),
- RawPcDescriptors::kOther, locs(), deopt_id());
+ PcDescriptorsLayout::kOther, locs(), deopt_id());
__ Bind(&done);
ASSERT(locs()->out(0).reg() == kResultReg);
}
@@ -2493,8 +2493,8 @@
// Lookup cache in stub before calling runtime.
__ LoadObject(InstantiationABI::kUninstantiatedTypeArgumentsReg,
type_arguments());
- compiler->GenerateStubCall(token_pos(), GetStub(), RawPcDescriptors::kOther,
- locs());
+ compiler->GenerateStubCall(token_pos(), GetStub(),
+ PcDescriptorsLayout::kOther, locs());
__ Bind(&type_arguments_instantiated);
}
@@ -2531,7 +2531,7 @@
__ movl(EDX, compiler::Immediate(instruction()->num_context_variables()));
compiler->GenerateStubCall(instruction()->token_pos(),
StubCode::AllocateContext(),
- RawPcDescriptors::kOther, locs);
+ PcDescriptorsLayout::kOther, locs);
ASSERT(instruction()->locs()->out(0).reg() == EAX);
compiler->RestoreLiveRegisters(instruction()->locs());
__ jmp(exit_label());
@@ -2579,7 +2579,7 @@
__ movl(EDX, compiler::Immediate(num_context_variables()));
compiler->GenerateStubCall(token_pos(), StubCode::AllocateContext(),
- RawPcDescriptors::kOther, locs());
+ PcDescriptorsLayout::kOther, locs());
}
LocationSummary* CloneContextInstr::MakeLocationSummary(Zone* zone,
@@ -2598,7 +2598,7 @@
ASSERT(locs()->out(0).reg() == EAX);
compiler->GenerateStubCall(token_pos(), StubCode::CloneContext(),
- /*kind=*/RawPcDescriptors::kOther, locs());
+ /*kind=*/PcDescriptorsLayout::kOther, locs());
}
LocationSummary* CatchBlockEntryInstr::MakeLocationSummary(Zone* zone,
@@ -2619,7 +2619,7 @@
if (compiler->is_optimizing()) {
compiler->AddDeoptIndexAtCall(deopt_id);
} else {
- compiler->AddCurrentDescriptor(RawPcDescriptors::kDeopt, deopt_id,
+ compiler->AddCurrentDescriptor(PcDescriptorsLayout::kDeopt, deopt_id,
TokenPosition::kNoSource);
}
}
@@ -2693,7 +2693,7 @@
if (compiler->isolate()->use_osr() && !compiler->is_optimizing() &&
instruction()->in_loop()) {
// In unoptimized code, record loop stack checks as possible OSR entries.
- compiler->AddCurrentDescriptor(RawPcDescriptors::kOsrEntry,
+ compiler->AddCurrentDescriptor(PcDescriptorsLayout::kOsrEntry,
instruction()->deopt_id(),
TokenPosition::kNoSource);
}
@@ -2793,8 +2793,8 @@
const bool right_needs_check =
!RangeUtils::IsWithin(right_range, 0, max_right - 1);
if (right_needs_check) {
- __ cmpl(right, compiler::Immediate(
- reinterpret_cast<int32_t>(Smi::New(max_right))));
+ __ cmpl(right,
+ compiler::Immediate(static_cast<int32_t>(Smi::New(max_right))));
__ j(ABOVE_EQUAL, deopt);
}
__ SmiUntag(right);
@@ -2814,8 +2814,8 @@
__ j(NEGATIVE, deopt);
}
compiler::Label done, is_not_zero;
- __ cmpl(right, compiler::Immediate(
- reinterpret_cast<int32_t>(Smi::New(Smi::kBits))));
+ __ cmpl(right,
+ compiler::Immediate(static_cast<int32_t>(Smi::New(Smi::kBits))));
__ j(BELOW, &is_not_zero, compiler::Assembler::kNearJump);
__ xorl(left, left);
__ jmp(&done, compiler::Assembler::kNearJump);
@@ -2830,8 +2830,8 @@
} else {
if (right_needs_check) {
ASSERT(shift_left->CanDeoptimize());
- __ cmpl(right, compiler::Immediate(
- reinterpret_cast<int32_t>(Smi::New(Smi::kBits))));
+ __ cmpl(right,
+ compiler::Immediate(static_cast<int32_t>(Smi::New(Smi::kBits))));
__ j(ABOVE_EQUAL, deopt);
}
// Left is not a constant.
@@ -5160,7 +5160,7 @@
void CheckClassInstr::EmitNullCheck(FlowGraphCompiler* compiler,
compiler::Label* deopt) {
const compiler::Immediate& raw_null =
- compiler::Immediate(reinterpret_cast<intptr_t>(Object::null()));
+ compiler::Immediate(static_cast<intptr_t>(Object::null()));
__ cmpl(locs()->in(0).reg(), raw_null);
ASSERT(IsDeoptIfNull() || IsDeoptIfNotNull());
Condition cond = IsDeoptIfNull() ? EQUAL : NOT_EQUAL;
@@ -5325,20 +5325,17 @@
__ testl(index, index);
__ j(NEGATIVE, deopt);
} else {
- __ cmpl(index,
- compiler::Immediate(reinterpret_cast<int32_t>(length.raw())));
+ __ cmpl(index, compiler::Immediate(static_cast<int32_t>(length.raw())));
__ j(ABOVE_EQUAL, deopt);
}
} else if (index_loc.IsConstant()) {
const Smi& index = Smi::Cast(index_loc.constant());
if (length_loc.IsStackSlot()) {
const compiler::Address& length = LocationToStackSlotAddress(length_loc);
- __ cmpl(length,
- compiler::Immediate(reinterpret_cast<int32_t>(index.raw())));
+ __ cmpl(length, compiler::Immediate(static_cast<int32_t>(index.raw())));
} else {
Register length = length_loc.reg();
- __ cmpl(length,
- compiler::Immediate(reinterpret_cast<int32_t>(index.raw())));
+ __ cmpl(length, compiler::Immediate(static_cast<int32_t>(index.raw())));
}
__ j(BELOW_EQUAL, deopt);
} else if (length_loc.IsStackSlot()) {
@@ -6084,7 +6081,7 @@
}
// Add a deoptimization descriptor for deoptimizing instructions that
// may be inserted before this instruction.
- compiler->AddCurrentDescriptor(RawPcDescriptors::kDeopt, GetDeoptId(),
+ compiler->AddCurrentDescriptor(PcDescriptorsLayout::kDeopt, GetDeoptId(),
TokenPosition::kNoSource);
}
if (HasParallelMove()) {
@@ -6272,7 +6269,7 @@
__ xorl(ECX, ECX);
__ call(EBX);
compiler->EmitCallsiteMetadata(token_pos(), deopt_id(),
- RawPcDescriptors::kOther, locs());
+ PcDescriptorsLayout::kOther, locs());
__ Drop(argument_count);
}
@@ -6321,7 +6318,7 @@
void AllocateObjectInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
const Code& stub = Code::ZoneHandle(
compiler->zone(), StubCode::GetAllocationStubForClass(cls()));
- compiler->GenerateStubCall(token_pos(), stub, RawPcDescriptors::kOther,
+ compiler->GenerateStubCall(token_pos(), stub, PcDescriptorsLayout::kOther,
locs());
}
diff --git a/runtime/vm/compiler/backend/il_printer.cc b/runtime/vm/compiler/backend/il_printer.cc
index e036600..83dda2b 100644
--- a/runtime/vm/compiler/backend/il_printer.cc
+++ b/runtime/vm/compiler/backend/il_printer.cc
@@ -1025,7 +1025,7 @@
void ReturnInstr::PrintOperandsTo(BufferFormatter* f) const {
Instruction::PrintOperandsTo(f);
- if (yield_index() != RawPcDescriptors::kInvalidYieldIndex) {
+ if (yield_index() != PcDescriptorsLayout::kInvalidYieldIndex) {
f->Print(", yield_index = %" Pd "", yield_index());
}
}
diff --git a/runtime/vm/compiler/backend/il_serializer.cc b/runtime/vm/compiler/backend/il_serializer.cc
index 4a4cb57..3708c8f 100644
--- a/runtime/vm/compiler/backend/il_serializer.cc
+++ b/runtime/vm/compiler/backend/il_serializer.cc
@@ -588,9 +588,9 @@
AddExtraSymbol(sexp, "native_name", tmp_string_.ToCString());
}
}
- if (func.kind() != RawFunction::Kind::kRegularFunction ||
+ if (func.kind() != FunctionLayout::Kind::kRegularFunction ||
FLAG_verbose_flow_graph_serialization) {
- AddExtraSymbol(sexp, "kind", RawFunction::KindToCString(func.kind()));
+ AddExtraSymbol(sexp, "kind", FunctionLayout::KindToCString(func.kind()));
}
function_type_args_ = func.type_parameters();
if (auto const ta_sexp = NonEmptyTypeArgumentsToSExp(function_type_args_)) {
@@ -1061,9 +1061,9 @@
SExpList* sexp,
FlowGraphSerializer* s) const {
Instruction::AddExtraInfoToSExpression(sexp, s);
- if (stub_kind_ != RawPcDescriptors::kAnyKind ||
+ if (stub_kind_ != PcDescriptorsLayout::kAnyKind ||
FLAG_verbose_flow_graph_serialization) {
- auto const stub_kind_name = RawPcDescriptors::KindToCString(stub_kind_);
+ auto const stub_kind_name = PcDescriptorsLayout::KindToCString(stub_kind_);
ASSERT(stub_kind_name != nullptr);
s->AddExtraSymbol(sexp, "stub_kind", stub_kind_name);
}
diff --git a/runtime/vm/compiler/backend/il_serializer.h b/runtime/vm/compiler/backend/il_serializer.h
index eb7795e..8a65fad3 100644
--- a/runtime/vm/compiler/backend/il_serializer.h
+++ b/runtime/vm/compiler/backend/il_serializer.h
@@ -148,7 +148,7 @@
return a.raw() == b.raw();
}
static uword Hash(const Object& obj) {
- if (obj.IsSmi()) return reinterpret_cast<uword>(obj.raw());
+ if (obj.IsSmi()) return static_cast<uword>(obj.raw());
if (obj.IsInstance()) return Instance::Cast(obj).CanonicalizeHash();
return obj.GetClassId();
}
diff --git a/runtime/vm/compiler/backend/il_test_helper.cc b/runtime/vm/compiler/backend/il_test_helper.cc
index 5bec543..3148b0d 100644
--- a/runtime/vm/compiler/backend/il_test_helper.cc
+++ b/runtime/vm/compiler/backend/il_test_helper.cc
@@ -23,9 +23,9 @@
Definition* const FlowGraphBuilderHelper::kPhiSelfReference = nullptr;
-RawLibrary* LoadTestScript(const char* script,
- Dart_NativeEntryResolver resolver,
- const char* lib_uri) {
+LibraryPtr LoadTestScript(const char* script,
+ Dart_NativeEntryResolver resolver,
+ const char* lib_uri) {
Dart_Handle api_lib;
{
TransitionVMToNative transition(Thread::Current());
@@ -38,7 +38,7 @@
return lib.raw();
}
-RawFunction* GetFunction(const Library& lib, const char* name) {
+FunctionPtr GetFunction(const Library& lib, const char* name) {
Thread* thread = Thread::Current();
const auto& func = Function::Handle(lib.LookupFunctionAllowPrivate(
String::Handle(Symbols::New(thread, name))));
@@ -46,7 +46,7 @@
return func.raw();
}
-RawClass* GetClass(const Library& lib, const char* name) {
+ClassPtr GetClass(const Library& lib, const char* name) {
Thread* thread = Thread::Current();
const auto& cls = Class::Handle(
lib.LookupClassAllowPrivate(String::Handle(Symbols::New(thread, name))));
@@ -54,15 +54,15 @@
return cls.raw();
}
-RawTypeParameter* GetClassTypeParameter(const Class& klass, const char* name) {
+TypeParameterPtr GetClassTypeParameter(const Class& klass, const char* name) {
const auto& param = TypeParameter::Handle(
klass.LookupTypeParameter(String::Handle(String::New(name))));
EXPECT(!param.IsNull());
return param.raw();
}
-RawTypeParameter* GetFunctionTypeParameter(const Function& fun,
- const char* name) {
+TypeParameterPtr GetFunctionTypeParameter(const Function& fun,
+ const char* name) {
intptr_t fun_level = 0;
const auto& param = TypeParameter::Handle(
fun.LookupTypeParameter(String::Handle(String::New(name)), &fun_level));
@@ -70,7 +70,7 @@
return param.raw();
}
-RawObject* Invoke(const Library& lib, const char* name) {
+ObjectPtr Invoke(const Library& lib, const char* name) {
// These tests rely on running unoptimized code to collect type feedback. The
// interpreter does not collect type feedback for interface calls, so set
// compilation threshold to 0 in order to compile invoked function
diff --git a/runtime/vm/compiler/backend/il_test_helper.h b/runtime/vm/compiler/backend/il_test_helper.h
index 779c4df..1d8a121 100644
--- a/runtime/vm/compiler/backend/il_test_helper.h
+++ b/runtime/vm/compiler/backend/il_test_helper.h
@@ -50,20 +50,18 @@
class FlowGraph;
class Function;
class Library;
-class RawFunction;
-class RawLibrary;
-RawLibrary* LoadTestScript(const char* script,
- Dart_NativeEntryResolver resolver = nullptr,
- const char* lib_uri = RESOLVED_USER_TEST_URI);
+LibraryPtr LoadTestScript(const char* script,
+ Dart_NativeEntryResolver resolver = nullptr,
+ const char* lib_uri = RESOLVED_USER_TEST_URI);
-RawFunction* GetFunction(const Library& lib, const char* name);
-RawClass* GetClass(const Library& lib, const char* name);
-RawTypeParameter* GetClassTypeParameter(const Class& klass, const char* name);
-RawTypeParameter* GetFunctionTypeParameter(const Function& fun,
- const char* name);
+FunctionPtr GetFunction(const Library& lib, const char* name);
+ClassPtr GetClass(const Library& lib, const char* name);
+TypeParameterPtr GetClassTypeParameter(const Class& klass, const char* name);
+TypeParameterPtr GetFunctionTypeParameter(const Function& fun,
+ const char* name);
-RawObject* Invoke(const Library& lib, const char* name);
+ObjectPtr Invoke(const Library& lib, const char* name);
class TestPipeline : public ValueObject {
public:
@@ -291,7 +289,7 @@
static FlowGraph& MakeDummyGraph(Thread* thread) {
const Function& func = Function::ZoneHandle(Function::New(
String::Handle(Symbols::New(thread, "dummy")),
- RawFunction::kRegularFunction,
+ FunctionLayout::kRegularFunction,
/*is_static=*/true,
/*is_const=*/false,
/*is_abstract=*/false,
diff --git a/runtime/vm/compiler/backend/il_x64.cc b/runtime/vm/compiler/backend/il_x64.cc
index 1109aff..d9324dc 100644
--- a/runtime/vm/compiler/backend/il_x64.cc
+++ b/runtime/vm/compiler/backend/il_x64.cc
@@ -219,7 +219,7 @@
__ Bind(&done);
#endif
ASSERT(__ constant_pool_allowed());
- if (yield_index() != RawPcDescriptors::kInvalidYieldIndex) {
+ if (yield_index() != PcDescriptorsLayout::kInvalidYieldIndex) {
compiler->EmitYieldPositionMetadata(token_pos(), yield_index());
}
__ LeaveDartFrame(); // Disallows constant pool use.
@@ -795,7 +795,7 @@
Location right = locs()->in(1);
if (right.IsConstant()) {
ASSERT(right.constant().IsSmi());
- const int64_t imm = reinterpret_cast<int64_t>(right.constant().raw());
+ const int64_t imm = static_cast<int64_t>(right.constant().raw());
__ TestImmediate(left_reg, compiler::Immediate(imm));
} else {
__ testq(left_reg, right.reg());
@@ -920,7 +920,7 @@
__ LoadNativeEntry(RBX, &label,
compiler::ObjectPoolBuilderEntry::kPatchable);
compiler->GeneratePatchableCall(token_pos(), *stub,
- RawPcDescriptors::kOther, locs());
+ PcDescriptorsLayout::kOther, locs());
} else {
if (is_bootstrap_native()) {
stub = &StubCode::CallBootstrapNative();
@@ -933,7 +933,7 @@
reinterpret_cast<uword>(native_c_function()));
__ LoadNativeEntry(RBX, &label,
compiler::ObjectPoolBuilderEntry::kNotPatchable);
- compiler->GenerateStubCall(token_pos(), *stub, RawPcDescriptors::kOther,
+ compiler->GenerateStubCall(token_pos(), *stub, PcDescriptorsLayout::kOther,
locs());
}
__ popq(result);
@@ -971,7 +971,7 @@
// 'movq'.
__ leaq(TMP, compiler::Address::AddressRIPRelative(0));
compiler->EmitCallsiteMetadata(TokenPosition::kNoSource, DeoptId::kNone,
- RawPcDescriptors::Kind::kOther, locs());
+ PcDescriptorsLayout::Kind::kOther, locs());
__ movq(compiler::Address(FPREG, kSavedCallerPcSlotFromFp * kWordSize), TMP);
if (CanExecuteGeneratedCodeInSafepoint()) {
@@ -1301,7 +1301,7 @@
compiler->SaveLiveRegisters(locs);
compiler->GenerateStubCall(TokenPosition::kNoSource, // No token position.
- stub, RawPcDescriptors::kOther, locs);
+ stub, PcDescriptorsLayout::kOther, locs);
__ MoveRegister(result_, RAX);
compiler->RestoreLiveRegisters(locs);
__ jmp(exit_label());
@@ -2485,9 +2485,9 @@
// RDI: iterator which initially points to the start of the variable
// data area to be initialized.
if (num_elements > 0) {
- const intptr_t array_size = instance_size - sizeof(RawArray);
+ const intptr_t array_size = instance_size - sizeof(ArrayLayout);
__ LoadObject(R12, Object::null_object());
- __ leaq(RDI, compiler::FieldAddress(RAX, sizeof(RawArray)));
+ __ leaq(RDI, compiler::FieldAddress(RAX, sizeof(ArrayLayout)));
if (array_size < (kInlineArraySize * kWordSize)) {
intptr_t current_offset = 0;
while (current_offset < array_size) {
@@ -2549,7 +2549,7 @@
const auto& allocate_array_stub =
Code::ZoneHandle(compiler->zone(), object_store->allocate_array_stub());
compiler->GenerateStubCall(token_pos(), allocate_array_stub,
- RawPcDescriptors::kOther, locs(), deopt_id());
+ PcDescriptorsLayout::kOther, locs(), deopt_id());
__ Bind(&done);
ASSERT(locs()->out(0).reg() == kResultReg);
}
@@ -2800,8 +2800,8 @@
}
__ LoadObject(InstantiationABI::kUninstantiatedTypeArgumentsReg,
type_arguments());
- compiler->GenerateStubCall(token_pos(), GetStub(), RawPcDescriptors::kOther,
- locs());
+ compiler->GenerateStubCall(token_pos(), GetStub(),
+ PcDescriptorsLayout::kOther, locs());
__ Bind(&type_arguments_instantiated);
}
@@ -2842,8 +2842,8 @@
__ LoadImmediate(
R10, compiler::Immediate(instruction()->num_context_variables()));
compiler->GenerateStubCall(instruction()->token_pos(),
- allocate_context_stub, RawPcDescriptors::kOther,
- locs);
+ allocate_context_stub,
+ PcDescriptorsLayout::kOther, locs);
ASSERT(instruction()->locs()->out(0).reg() == RAX);
compiler->RestoreLiveRegisters(instruction()->locs());
__ jmp(exit_label());
@@ -2894,7 +2894,7 @@
__ LoadImmediate(R10, compiler::Immediate(num_context_variables()));
compiler->GenerateStubCall(token_pos(), allocate_context_stub,
- RawPcDescriptors::kOther, locs());
+ PcDescriptorsLayout::kOther, locs());
}
LocationSummary* CloneContextInstr::MakeLocationSummary(Zone* zone,
@@ -2916,7 +2916,7 @@
const auto& clone_context_stub =
Code::ZoneHandle(compiler->zone(), object_store->clone_context_stub());
compiler->GenerateStubCall(token_pos(), clone_context_stub,
- /*kind=*/RawPcDescriptors::kOther, locs());
+ /*kind=*/PcDescriptorsLayout::kOther, locs());
}
LocationSummary* CatchBlockEntryInstr::MakeLocationSummary(Zone* zone,
@@ -2937,7 +2937,7 @@
if (compiler->is_optimizing()) {
compiler->AddDeoptIndexAtCall(deopt_id);
} else {
- compiler->AddCurrentDescriptor(RawPcDescriptors::kDeopt, deopt_id,
+ compiler->AddCurrentDescriptor(PcDescriptorsLayout::kDeopt, deopt_id,
TokenPosition::kNoSource);
}
}
@@ -3020,7 +3020,7 @@
compiler->RecordSafepoint(instruction()->locs(), kNumSlowPathArgs);
compiler->RecordCatchEntryMoves();
compiler->AddDescriptor(
- RawPcDescriptors::kOther, compiler->assembler()->CodeSize(),
+ PcDescriptorsLayout::kOther, compiler->assembler()->CodeSize(),
instruction()->deopt_id(), instruction()->token_pos(),
compiler->CurrentTryIndex());
} else {
@@ -3032,7 +3032,7 @@
if (compiler->isolate()->use_osr() && !compiler->is_optimizing() &&
instruction()->in_loop()) {
// In unoptimized code, record loop stack checks as possible OSR entries.
- compiler->AddCurrentDescriptor(RawPcDescriptors::kOsrEntry,
+ compiler->AddCurrentDescriptor(PcDescriptorsLayout::kOsrEntry,
instruction()->deopt_id(),
TokenPosition::kNoSource);
}
@@ -3135,8 +3135,8 @@
!RangeUtils::IsWithin(right_range, 0, max_right - 1);
if (right_needs_check) {
__ CompareImmediate(
- right, compiler::Immediate(
- reinterpret_cast<int64_t>(Smi::New(max_right))));
+ right,
+ compiler::Immediate(static_cast<int64_t>(Smi::New(max_right))));
__ j(ABOVE_EQUAL, deopt);
}
__ SmiUntag(right);
@@ -3160,7 +3160,7 @@
compiler::Label done, is_not_zero;
__ CompareImmediate(
right,
- compiler::Immediate(reinterpret_cast<int64_t>(Smi::New(Smi::kBits))));
+ compiler::Immediate(static_cast<int64_t>(Smi::New(Smi::kBits))));
__ j(BELOW, &is_not_zero, compiler::Assembler::kNearJump);
__ xorq(left, left);
__ jmp(&done, compiler::Assembler::kNearJump);
@@ -3177,7 +3177,7 @@
ASSERT(shift_left->CanDeoptimize());
__ CompareImmediate(
right,
- compiler::Immediate(reinterpret_cast<int64_t>(Smi::New(Smi::kBits))));
+ compiler::Immediate(static_cast<int64_t>(Smi::New(Smi::kBits))));
__ j(ABOVE_EQUAL, deopt);
}
// Left is not a constant.
@@ -3509,8 +3509,7 @@
static bool CanBeImmediate(const Object& constant) {
return constant.IsSmi() &&
- compiler::Immediate(reinterpret_cast<int64_t>(constant.raw()))
- .is_int32();
+ compiler::Immediate(static_cast<int64_t>(constant.raw())).is_int32();
}
static bool IsSmiValue(const Object& constant, intptr_t value) {
@@ -3619,7 +3618,7 @@
if (locs()->in(1).IsConstant()) {
const Object& constant = locs()->in(1).constant();
ASSERT(constant.IsSmi());
- const int64_t imm = reinterpret_cast<int64_t>(constant.raw());
+ const int64_t imm = static_cast<int64_t>(constant.raw());
switch (op_kind()) {
case Token::kADD: {
__ AddImmediate(left, compiler::Immediate(imm));
@@ -5616,8 +5615,8 @@
if (index_loc.IsConstant()) {
Register length = length_loc.reg();
const Smi& index = Smi::Cast(index_loc.constant());
- __ CompareImmediate(
- length, compiler::Immediate(reinterpret_cast<int64_t>(index.raw())));
+ __ CompareImmediate(length,
+ compiler::Immediate(static_cast<int64_t>(index.raw())));
__ j(BELOW_EQUAL, deopt);
} else if (length_loc.IsConstant()) {
const Smi& length = Smi::Cast(length_loc.constant());
@@ -5630,7 +5629,7 @@
__ j(NEGATIVE, deopt);
} else {
__ CompareImmediate(
- index, compiler::Immediate(reinterpret_cast<int64_t>(length.raw())));
+ index, compiler::Immediate(static_cast<int64_t>(length.raw())));
__ j(ABOVE_EQUAL, deopt);
}
} else {
@@ -6514,7 +6513,7 @@
}
// Add a deoptimization descriptor for deoptimizing instructions that
// may be inserted before this instruction.
- compiler->AddCurrentDescriptor(RawPcDescriptors::kDeopt, GetDeoptId(),
+ compiler->AddCurrentDescriptor(PcDescriptorsLayout::kDeopt, GetDeoptId(),
TokenPosition::kNoSource);
}
if (HasParallelMove()) {
@@ -6645,7 +6644,7 @@
}
__ call(RCX);
compiler->EmitCallsiteMetadata(token_pos(), deopt_id(),
- RawPcDescriptors::kOther, locs());
+ PcDescriptorsLayout::kOther, locs());
__ Drop(argument_count);
}
@@ -6701,7 +6700,7 @@
}
const Code& stub = Code::ZoneHandle(
compiler->zone(), StubCode::GetAllocationStubForClass(cls()));
- compiler->GenerateStubCall(token_pos(), stub, RawPcDescriptors::kOther,
+ compiler->GenerateStubCall(token_pos(), stub, PcDescriptorsLayout::kOther,
locs());
}
diff --git a/runtime/vm/compiler/backend/inliner.cc b/runtime/vm/compiler/backend/inliner.cc
index b4365f0..169d57d 100644
--- a/runtime/vm/compiler/backend/inliner.cc
+++ b/runtime/vm/compiler/backend/inliner.cc
@@ -2285,7 +2285,7 @@
// replace them with inline FG before inlining introduces any superfluous
// AssertAssignable instructions.
if (function.IsDispatcherOrImplicitAccessor() &&
- !(function.kind() == RawFunction::kDynamicInvocationForwarder &&
+ !(function.kind() == FunctionLayout::kDynamicInvocationForwarder &&
function.IsRecognized())) {
// Smaller or same size as the call.
return true;
@@ -2298,7 +2298,7 @@
if (function.IsGetterFunction() || function.IsSetterFunction() ||
IsInlineableOperator(function) ||
- (function.kind() == RawFunction::kConstructor)) {
+ (function.kind() == FunctionLayout::kConstructor)) {
const intptr_t count = function.optimized_instruction_count();
if ((count != 0) && (count < FLAG_inline_getters_setters_smaller_than)) {
return true;
diff --git a/runtime/vm/compiler/backend/slot.h b/runtime/vm/compiler/backend/slot.h
index 8115c6a..2da369a 100644
--- a/runtime/vm/compiler/backend/slot.h
+++ b/runtime/vm/compiler/backend/slot.h
@@ -53,31 +53,31 @@
//
// Note: native slots are expected to be non-nullable.
#define NATIVE_SLOTS_LIST(V) \
- V(Array, RawArray, length, Smi, FINAL) \
- V(Context, RawContext, parent, Context, FINAL) \
- V(Closure, RawClosure, instantiator_type_arguments, TypeArguments, FINAL) \
- V(Closure, RawClosure, delayed_type_arguments, TypeArguments, FINAL) \
- V(Closure, RawClosure, function_type_arguments, TypeArguments, FINAL) \
- V(Closure, RawClosure, function, Function, FINAL) \
- V(Closure, RawClosure, context, Context, FINAL) \
- V(Closure, RawClosure, hash, Context, VAR) \
- V(GrowableObjectArray, RawGrowableObjectArray, length, Smi, VAR) \
- V(GrowableObjectArray, RawGrowableObjectArray, data, Array, VAR) \
- V(TypedDataBase, RawTypedDataBase, length, Smi, FINAL) \
- V(TypedDataView, RawTypedDataView, offset_in_bytes, Smi, FINAL) \
- V(TypedDataView, RawTypedDataView, data, Dynamic, FINAL) \
- V(String, RawString, length, Smi, FINAL) \
- V(LinkedHashMap, RawLinkedHashMap, index, TypedDataUint32Array, VAR) \
- V(LinkedHashMap, RawLinkedHashMap, data, Array, VAR) \
- V(LinkedHashMap, RawLinkedHashMap, hash_mask, Smi, VAR) \
- V(LinkedHashMap, RawLinkedHashMap, used_data, Smi, VAR) \
- V(LinkedHashMap, RawLinkedHashMap, deleted_keys, Smi, VAR) \
- V(ArgumentsDescriptor, RawArray, type_args_len, Smi, FINAL) \
- V(ArgumentsDescriptor, RawArray, positional_count, Smi, FINAL) \
- V(ArgumentsDescriptor, RawArray, count, Smi, FINAL) \
- V(ArgumentsDescriptor, RawArray, size, Smi, FINAL) \
- V(PointerBase, RawPointerBase, data_field, Dynamic, FINAL) \
- V(Type, RawType, arguments, TypeArguments, FINAL)
+ V(Array, ArrayLayout, length, Smi, FINAL) \
+ V(Context, ContextLayout, parent, Context, FINAL) \
+ V(Closure, ClosureLayout, instantiator_type_arguments, TypeArguments, FINAL) \
+ V(Closure, ClosureLayout, delayed_type_arguments, TypeArguments, FINAL) \
+ V(Closure, ClosureLayout, function_type_arguments, TypeArguments, FINAL) \
+ V(Closure, ClosureLayout, function, Function, FINAL) \
+ V(Closure, ClosureLayout, context, Context, FINAL) \
+ V(Closure, ClosureLayout, hash, Context, VAR) \
+ V(GrowableObjectArray, GrowableObjectArrayLayout, length, Smi, VAR) \
+ V(GrowableObjectArray, GrowableObjectArrayLayout, data, Array, VAR) \
+ V(TypedDataBase, TypedDataBaseLayout, length, Smi, FINAL) \
+ V(TypedDataView, TypedDataViewLayout, offset_in_bytes, Smi, FINAL) \
+ V(TypedDataView, TypedDataViewLayout, data, Dynamic, FINAL) \
+ V(String, StringLayout, length, Smi, FINAL) \
+ V(LinkedHashMap, LinkedHashMapLayout, index, TypedDataUint32Array, VAR) \
+ V(LinkedHashMap, LinkedHashMapLayout, data, Array, VAR) \
+ V(LinkedHashMap, LinkedHashMapLayout, hash_mask, Smi, VAR) \
+ V(LinkedHashMap, LinkedHashMapLayout, used_data, Smi, VAR) \
+ V(LinkedHashMap, LinkedHashMapLayout, deleted_keys, Smi, VAR) \
+ V(ArgumentsDescriptor, ArrayLayout, type_args_len, Smi, FINAL) \
+ V(ArgumentsDescriptor, ArrayLayout, positional_count, Smi, FINAL) \
+ V(ArgumentsDescriptor, ArrayLayout, count, Smi, FINAL) \
+ V(ArgumentsDescriptor, ArrayLayout, size, Smi, FINAL) \
+ V(PointerBase, PointerBaseLayout, data_field, Dynamic, FINAL) \
+ V(Type, TypeLayout, arguments, TypeArguments, FINAL)
// Slot is an abstraction that describes an readable (and possibly writeable)
// location within an object.
diff --git a/runtime/vm/compiler/backend/slot_test.cc b/runtime/vm/compiler/backend/slot_test.cc
index 7dea9b7..a506698 100644
--- a/runtime/vm/compiler/backend/slot_test.cc
+++ b/runtime/vm/compiler/backend/slot_test.cc
@@ -48,8 +48,8 @@
const Function& dummy_function = Function::ZoneHandle(
Function::New(String::Handle(Symbols::New(thread, "foo")),
- RawFunction::kRegularFunction, false, false, false, false,
- false, dummy_class, TokenPosition::kMinSource));
+ FunctionLayout::kRegularFunction, false, false, false,
+ false, false, dummy_class, TokenPosition::kMinSource));
const Field& field = Field::Handle(
Field::New(String::Handle(Symbols::New(thread, "field")),
diff --git a/runtime/vm/compiler/backend/type_propagator_test.cc b/runtime/vm/compiler/backend/type_propagator_test.cc
index b68ee83..aacaf44 100644
--- a/runtime/vm/compiler/backend/type_propagator_test.cc
+++ b/runtime/vm/compiler/backend/type_propagator_test.cc
@@ -171,7 +171,7 @@
const Function& target_func = Function::ZoneHandle(Function::New(
String::Handle(Symbols::New(thread, "dummy2")),
- RawFunction::kRegularFunction,
+ FunctionLayout::kRegularFunction,
/*is_static=*/true,
/*is_const=*/false,
/*is_abstract=*/false,
diff --git a/runtime/vm/compiler/backend/yield_position_test.cc b/runtime/vm/compiler/backend/yield_position_test.cc
index 7707468..a32bb74 100644
--- a/runtime/vm/compiler/backend/yield_position_test.cc
+++ b/runtime/vm/compiler/backend/yield_position_test.cc
@@ -26,7 +26,7 @@
while (!it.Done()) {
if (auto return_instr = it.Current()->AsReturn()) {
if (return_instr->yield_index() !=
- RawPcDescriptors::kInvalidYieldIndex) {
+ PcDescriptorsLayout::kInvalidYieldIndex) {
ASSERT(return_instr->yield_index() > 0);
array->Add(
Pair(return_instr->yield_index(), return_instr->token_pos()));
@@ -42,9 +42,9 @@
static YieldPoints* GetYieldPointsFromCode(const Code& code) {
auto array = new YieldPoints();
const auto& pc_descriptor = PcDescriptors::Handle(code.pc_descriptors());
- PcDescriptors::Iterator it(pc_descriptor, RawPcDescriptors::kOther);
+ PcDescriptors::Iterator it(pc_descriptor, PcDescriptorsLayout::kOther);
while (it.MoveNext()) {
- if (it.YieldIndex() != RawPcDescriptors::kInvalidYieldIndex) {
+ if (it.YieldIndex() != PcDescriptorsLayout::kInvalidYieldIndex) {
array->Add(Pair(it.YieldIndex(), it.TokenPos()));
}
}
diff --git a/runtime/vm/compiler/call_specializer.cc b/runtime/vm/compiler/call_specializer.cc
index b739030..cabdb7c 100644
--- a/runtime/vm/compiler/call_specializer.cc
+++ b/runtime/vm/compiler/call_specializer.cc
@@ -749,8 +749,8 @@
field = field.CloneFromOriginal();
}
- switch (
- flow_graph()->CheckForInstanceCall(call, RawFunction::kImplicitGetter)) {
+ switch (flow_graph()->CheckForInstanceCall(call,
+ FunctionLayout::kImplicitGetter)) {
case FlowGraph::ToCheck::kCheckNull:
AddCheckNull(call->Receiver(), call->function_name(), call->deopt_id(),
call->env(), call);
@@ -795,7 +795,7 @@
return false;
}
const Function& target = targets.FirstTarget();
- if (target.kind() != RawFunction::kImplicitSetter) {
+ if (target.kind() != FunctionLayout::kImplicitSetter) {
// Non-implicit setter are inlined like normal method calls.
return false;
}
@@ -805,8 +805,8 @@
field = field.CloneFromOriginal();
}
- switch (
- flow_graph()->CheckForInstanceCall(instr, RawFunction::kImplicitSetter)) {
+ switch (flow_graph()->CheckForInstanceCall(instr,
+ FunctionLayout::kImplicitSetter)) {
case FlowGraph::ToCheck::kCheckNull:
AddCheckNull(instr->Receiver(), instr->function_name(), instr->deopt_id(),
instr->env(), instr);
@@ -956,7 +956,7 @@
return false;
}
const Function& target = targets.FirstTarget();
- if (target.kind() != RawFunction::kImplicitGetter) {
+ if (target.kind() != FunctionLayout::kImplicitGetter) {
// Non-implicit getters are inlined like normal methods by conventional
// inlining in FlowGraphInliner.
return false;
@@ -1063,7 +1063,7 @@
// (ic_data.NumberOfChecks() * 2) entries
// An instance-of test returning all same results can be converted to a class
// check.
-RawBool* CallSpecializer::InstanceOfAsBool(
+BoolPtr CallSpecializer::InstanceOfAsBool(
const ICData& ic_data,
const AbstractType& type,
ZoneGrowableArray<intptr_t>* results) const {
diff --git a/runtime/vm/compiler/call_specializer.h b/runtime/vm/compiler/call_specializer.h
index c1be9a2..5bb2cb7 100644
--- a/runtime/vm/compiler/call_specializer.h
+++ b/runtime/vm/compiler/call_specializer.h
@@ -159,9 +159,9 @@
bool TryInlineImplicitInstanceGetter(InstanceCallInstr* call);
- RawBool* InstanceOfAsBool(const ICData& ic_data,
- const AbstractType& type,
- ZoneGrowableArray<intptr_t>* results) const;
+ BoolPtr InstanceOfAsBool(const ICData& ic_data,
+ const AbstractType& type,
+ ZoneGrowableArray<intptr_t>* results) const;
bool TryOptimizeInstanceOfUsingStaticTypes(InstanceCallInstr* call,
const AbstractType& type);
diff --git a/runtime/vm/compiler/ffi/call.cc b/runtime/vm/compiler/ffi/call.cc
index 40a4e6e..5cb1598 100644
--- a/runtime/vm/compiler/ffi/call.cc
+++ b/runtime/vm/compiler/ffi/call.cc
@@ -13,15 +13,15 @@
namespace ffi {
// TODO(dartbug.com/36607): Cache the trampolines.
-RawFunction* TrampolineFunction(const Function& dart_signature,
- const Function& c_signature) {
+FunctionPtr TrampolineFunction(const Function& dart_signature,
+ const Function& c_signature) {
Thread* thread = Thread::Current();
Zone* zone = thread->zone();
String& name = String::Handle(zone, Symbols::New(thread, "FfiTrampoline"));
const Library& lib = Library::Handle(zone, Library::FfiLibrary());
const Class& owner_class = Class::Handle(zone, lib.toplevel_class());
Function& function =
- Function::Handle(zone, Function::New(name, RawFunction::kFfiTrampoline,
+ Function::Handle(zone, Function::New(name, FunctionLayout::kFfiTrampoline,
/*is_static=*/true,
/*is_const=*/false,
/*is_abstract=*/false,
diff --git a/runtime/vm/compiler/ffi/call.h b/runtime/vm/compiler/ffi/call.h
index 86a986b..050b1d8 100644
--- a/runtime/vm/compiler/ffi/call.h
+++ b/runtime/vm/compiler/ffi/call.h
@@ -19,8 +19,8 @@
namespace ffi {
-RawFunction* TrampolineFunction(const Function& dart_signature,
- const Function& c_signature);
+FunctionPtr TrampolineFunction(const Function& dart_signature,
+ const Function& c_signature);
} // namespace ffi
diff --git a/runtime/vm/compiler/ffi/callback.cc b/runtime/vm/compiler/ffi/callback.cc
index 6bd722a..8d1fe95 100644
--- a/runtime/vm/compiler/ffi/callback.cc
+++ b/runtime/vm/compiler/ffi/callback.cc
@@ -12,9 +12,9 @@
namespace ffi {
-RawFunction* NativeCallbackFunction(const Function& c_signature,
- const Function& dart_target,
- const Instance& exceptional_return) {
+FunctionPtr NativeCallbackFunction(const Function& c_signature,
+ const Function& dart_target,
+ const Instance& exceptional_return) {
Thread* const thread = Thread::Current();
const int32_t callback_id = thread->AllocateFfiCallbackId();
@@ -28,7 +28,7 @@
const Library& lib = Library::Handle(zone, Library::FfiLibrary());
const Class& owner_class = Class::Handle(zone, lib.toplevel_class());
const Function& function =
- Function::Handle(zone, Function::New(name, RawFunction::kFfiTrampoline,
+ Function::Handle(zone, Function::New(name, FunctionLayout::kFfiTrampoline,
/*is_static=*/true,
/*is_const=*/false,
/*is_abstract=*/false,
diff --git a/runtime/vm/compiler/ffi/callback.h b/runtime/vm/compiler/ffi/callback.h
index 4113ffa..265143e 100644
--- a/runtime/vm/compiler/ffi/callback.h
+++ b/runtime/vm/compiler/ffi/callback.h
@@ -19,9 +19,9 @@
namespace ffi {
-RawFunction* NativeCallbackFunction(const Function& c_signature,
- const Function& dart_target,
- const Instance& exceptional_return);
+FunctionPtr NativeCallbackFunction(const Function& c_signature,
+ const Function& dart_target,
+ const Instance& exceptional_return);
} // namespace ffi
diff --git a/runtime/vm/compiler/ffi/marshaller.h b/runtime/vm/compiler/ffi/marshaller.h
index 01704c7..d8d4647 100644
--- a/runtime/vm/compiler/ffi/marshaller.h
+++ b/runtime/vm/compiler/ffi/marshaller.h
@@ -74,7 +74,7 @@
kFfiVoidCid;
}
- RawString* function_name() const { return dart_signature_.name(); }
+ StringPtr function_name() const { return dart_signature_.name(); }
protected:
BaseMarshaller(Zone* zone, const Function& dart_signature)
diff --git a/runtime/vm/compiler/ffi/native_calling_convention.cc b/runtime/vm/compiler/ffi/native_calling_convention.cc
index 032f583..fa6f4eb 100644
--- a/runtime/vm/compiler/ffi/native_calling_convention.cc
+++ b/runtime/vm/compiler/ffi/native_calling_convention.cc
@@ -279,7 +279,7 @@
return c_signature_.num_fixed_parameters() - kNativeParamsStartAt;
}
-RawAbstractType* NativeCallingConvention::CType(intptr_t arg_index) const {
+AbstractTypePtr NativeCallingConvention::CType(intptr_t arg_index) const {
if (arg_index == kResultIndex) {
return c_signature_.result_type();
}
diff --git a/runtime/vm/compiler/ffi/native_calling_convention.h b/runtime/vm/compiler/ffi/native_calling_convention.h
index 1524b6f..5eae152 100644
--- a/runtime/vm/compiler/ffi/native_calling_convention.h
+++ b/runtime/vm/compiler/ffi/native_calling_convention.h
@@ -42,7 +42,7 @@
// The C Type (expressed in a Dart Type) of the argument at `arg_index`.
//
// Excluding the #0 argument which is the function pointer.
- RawAbstractType* CType(intptr_t arg_index) const;
+ AbstractTypePtr CType(intptr_t arg_index) const;
// The location of the argument at `arg_index`.
const NativeLocation& Location(intptr_t arg_index) const {
diff --git a/runtime/vm/compiler/frontend/base_flow_graph_builder.cc b/runtime/vm/compiler/frontend/base_flow_graph_builder.cc
index a60eb07..67faab3 100644
--- a/runtime/vm/compiler/frontend/base_flow_graph_builder.cc
+++ b/runtime/vm/compiler/frontend/base_flow_graph_builder.cc
@@ -971,7 +971,7 @@
return Fragment();
#else
return Fragment(new (Z) DebugStepCheckInstr(
- position, RawPcDescriptors::kRuntimeCall, GetNextDeoptId()));
+ position, PcDescriptorsLayout::kRuntimeCall, GetNextDeoptId()));
#endif
}
diff --git a/runtime/vm/compiler/frontend/base_flow_graph_builder.h b/runtime/vm/compiler/frontend/base_flow_graph_builder.h
index 67448f0..e4ebf61 100644
--- a/runtime/vm/compiler/frontend/base_flow_graph_builder.h
+++ b/runtime/vm/compiler/frontend/base_flow_graph_builder.h
@@ -277,8 +277,9 @@
bool negate = false);
Fragment BranchIfStrictEqual(TargetEntryInstr** then_entry,
TargetEntryInstr** otherwise_entry);
- Fragment Return(TokenPosition position,
- intptr_t yield_index = RawPcDescriptors::kInvalidYieldIndex);
+ Fragment Return(
+ TokenPosition position,
+ intptr_t yield_index = PcDescriptorsLayout::kInvalidYieldIndex);
Fragment CheckStackOverflow(TokenPosition position,
intptr_t stack_depth,
intptr_t loop_depth);
diff --git a/runtime/vm/compiler/frontend/bytecode_flow_graph_builder.cc b/runtime/vm/compiler/frontend/bytecode_flow_graph_builder.cc
index 5bcc3d8..23dcf66 100644
--- a/runtime/vm/compiler/frontend/bytecode_flow_graph_builder.cc
+++ b/runtime/vm/compiler/frontend/bytecode_flow_graph_builder.cc
@@ -1637,7 +1637,7 @@
BuildDebugStepCheck();
LoadStackSlots(1);
ASSERT(code_.is_open());
- intptr_t yield_index = RawPcDescriptors::kInvalidYieldIndex;
+ intptr_t yield_index = PcDescriptorsLayout::kInvalidYieldIndex;
if (function().IsAsyncClosure() || function().IsAsyncGenClosure()) {
if (pc_ == last_yield_point_pc_) {
// The return might actually be a yield point, if so we need to attach the
@@ -1958,7 +1958,7 @@
intptr_t pc) {
const uword pc_offset =
KernelBytecode::BytecodePcToOffset(pc, /* is_return_address = */ true);
- PcDescriptors::Iterator iter(descriptors, RawPcDescriptors::kAnyKind);
+ PcDescriptors::Iterator iter(descriptors, PcDescriptorsLayout::kAnyKind);
intptr_t try_index = kInvalidTryIndex;
while (iter.MoveNext()) {
const intptr_t current_try_index = iter.TryIndex();
@@ -2050,7 +2050,7 @@
pc += (KernelBytecode::Next(instr) - instr);
}
- PcDescriptors::Iterator iter(descriptors, RawPcDescriptors::kAnyKind);
+ PcDescriptors::Iterator iter(descriptors, PcDescriptorsLayout::kAnyKind);
while (iter.MoveNext()) {
const intptr_t start_pc = KernelBytecode::OffsetToBytecodePc(
iter.PcOffset(), /* is_return_address = */ true);
diff --git a/runtime/vm/compiler/frontend/bytecode_reader.cc b/runtime/vm/compiler/frontend/bytecode_reader.cc
index d205058..4b10135 100644
--- a/runtime/vm/compiler/frontend/bytecode_reader.cc
+++ b/runtime/vm/compiler/frontend/bytecode_reader.cc
@@ -123,7 +123,7 @@
return true;
}
-RawLibrary* BytecodeMetadataHelper::GetMainLibrary() {
+LibraryPtr BytecodeMetadataHelper::GetMainLibrary() {
const intptr_t md_offset = GetComponentMetadataPayloadOffset();
if (md_offset < 0) {
return Library::null();
@@ -141,8 +141,8 @@
return bytecode_reader.ReadMain();
}
-RawArray* BytecodeMetadataHelper::GetBytecodeComponent() {
- RawArray* array = translation_helper_.GetBytecodeComponent();
+ArrayPtr BytecodeMetadataHelper::GetBytecodeComponent() {
+ ArrayPtr array = translation_helper_.GetBytecodeComponent();
if (array == Array::null()) {
array = ReadBytecodeComponent();
ASSERT(array != Array::null());
@@ -150,7 +150,7 @@
return array;
}
-RawArray* BytecodeMetadataHelper::ReadBytecodeComponent() {
+ArrayPtr BytecodeMetadataHelper::ReadBytecodeComponent() {
const intptr_t md_offset = GetComponentMetadataPayloadOffset();
if (md_offset < 0) {
return Array::null();
@@ -209,10 +209,15 @@
intptr_t num_params = reader_.ReadUInt();
ASSERT(num_params ==
function.NumParameters() - function.NumImplicitParameters());
- for (intptr_t i = 0; i < num_params; ++i) {
- reader_.ReadUInt();
+ for (intptr_t i = function.NumImplicitParameters();
+ i < function.NumParameters(); ++i) {
+ const intptr_t flags = reader_.ReadUInt();
+ if ((flags & Parameter::kIsRequiredFlag) != 0) {
+ function.SetIsRequiredAt(i);
+ }
}
}
+ function.TruncateUnusedParameterFlags();
if (has_forwarding_stub_target) {
reader_.ReadUInt();
}
@@ -338,9 +343,8 @@
return -1;
}
-RawArray* BytecodeReaderHelper::CreateForwarderChecks(
- const Function& function) {
- ASSERT(function.kind() != RawFunction::kDynamicInvocationForwarder);
+ArrayPtr BytecodeReaderHelper::CreateForwarderChecks(const Function& function) {
+ ASSERT(function.kind() != FunctionLayout::kDynamicInvocationForwarder);
ASSERT(function.is_declared_in_bytecode());
TypeArguments& default_args = TypeArguments::Handle(Z);
@@ -457,13 +461,14 @@
const int kIsSyncStarFlag = 1 << 6;
const int kIsDebuggableFlag = 1 << 7;
const int kHasAttributesFlag = 1 << 8;
+ const int kHasParameterFlagsFlag = 1 << 9;
const intptr_t flags = reader_.ReadUInt();
Object& parent = Object::Handle(Z, ReadObject());
if (!parent.IsFunction()) {
ASSERT(parent.IsField());
- ASSERT(function.kind() == RawFunction::kFieldInitializer);
+ ASSERT(function.kind() == FunctionLayout::kFieldInitializer);
// Closure in a static field initializer, so use current function as parent.
parent = function.raw();
}
@@ -485,13 +490,13 @@
closure.set_end_token_pos(end_position);
if ((flags & kIsSyncStarFlag) != 0) {
- closure.set_modifier(RawFunction::kSyncGen);
+ closure.set_modifier(FunctionLayout::kSyncGen);
} else if ((flags & kIsAsyncFlag) != 0) {
- closure.set_modifier(RawFunction::kAsync);
+ closure.set_modifier(FunctionLayout::kAsync);
closure.set_is_inlinable(!FLAG_causal_async_stacks &&
!FLAG_lazy_async_stacks);
} else if ((flags & kIsAsyncStarFlag) != 0) {
- closure.set_modifier(RawFunction::kAsyncGen);
+ closure.set_modifier(FunctionLayout::kAsyncGen);
closure.set_is_inlinable(!FLAG_causal_async_stacks &&
!FLAG_lazy_async_stacks);
}
@@ -503,12 +508,12 @@
closures_->SetAt(closureIndex, closure);
Type& signature_type = Type::Handle(
- Z, ReadFunctionSignature(closure,
- (flags & kHasOptionalPositionalParamsFlag) != 0,
- (flags & kHasOptionalNamedParamsFlag) != 0,
- (flags & kHasTypeParamsFlag) != 0,
- /* has_positional_param_names = */ true,
- Nullability::kNonNullable));
+ Z, ReadFunctionSignature(
+ closure, (flags & kHasOptionalPositionalParamsFlag) != 0,
+ (flags & kHasOptionalNamedParamsFlag) != 0,
+ (flags & kHasTypeParamsFlag) != 0,
+ /* has_positional_param_names = */ true,
+ (flags & kHasParameterFlagsFlag) != 0, Nullability::kNonNullable));
closure.SetSignatureType(signature_type);
@@ -548,12 +553,13 @@
return false;
}
-RawType* BytecodeReaderHelper::ReadFunctionSignature(
+TypePtr BytecodeReaderHelper::ReadFunctionSignature(
const Function& func,
bool has_optional_positional_params,
bool has_optional_named_params,
bool has_type_params,
bool has_positional_param_names,
+ bool has_parameter_flags,
Nullability nullability) {
FunctionTypeScope function_type_scope(this);
@@ -575,8 +581,9 @@
const Array& parameter_types =
Array::Handle(Z, Array::New(num_params, Heap::kOld));
func.set_parameter_types(parameter_types);
- const Array& parameter_names =
- Array::Handle(Z, Array::New(num_params, Heap::kOld));
+ const Array& parameter_names = Array::Handle(
+ Z, Array::New(Function::NameArrayLengthIncludingFlags(num_params),
+ Heap::kOld));
func.set_parameter_names(parameter_names);
intptr_t i = 0;
@@ -597,6 +604,16 @@
type ^= ReadObject();
parameter_types.SetAt(i, type);
}
+ if (has_parameter_flags) {
+ intptr_t num_flags = reader_.ReadUInt();
+ for (intptr_t i = 0; i < num_flags; ++i) {
+ intptr_t flag = reader_.ReadUInt();
+ if ((flag & Parameter::kIsRequiredFlag) != 0) {
+ func.SetIsRequiredAt(kImplicitClosureParam + i);
+ }
+ }
+ }
+ func.TruncateUnusedParameterFlags();
type ^= ReadObject();
func.set_result_type(type);
@@ -937,7 +954,7 @@
return obj_count - 1;
}
-RawBytecode* BytecodeReaderHelper::ReadBytecode(const ObjectPool& pool) {
+BytecodePtr BytecodeReaderHelper::ReadBytecode(const ObjectPool& pool) {
#if defined(SUPPORT_TIMELINE)
TIMELINE_DURATION(Thread::Current(), CompilerVerbose,
"BytecodeReaderHelper::ReadBytecode");
@@ -998,14 +1015,14 @@
handler_type ^= pool.ObjectAt(type_index);
handler_types.SetAt(i, handler_type);
}
- pc_descriptors_list->AddDescriptor(RawPcDescriptors::kOther, start_pc,
- DeoptId::kNone,
- TokenPosition::kNoSource, try_index,
- RawPcDescriptors::kInvalidYieldIndex);
- pc_descriptors_list->AddDescriptor(RawPcDescriptors::kOther, end_pc,
- DeoptId::kNone,
- TokenPosition::kNoSource, try_index,
- RawPcDescriptors::kInvalidYieldIndex);
+ pc_descriptors_list->AddDescriptor(
+ PcDescriptorsLayout::kOther, start_pc, DeoptId::kNone,
+ TokenPosition::kNoSource, try_index,
+ PcDescriptorsLayout::kInvalidYieldIndex);
+ pc_descriptors_list->AddDescriptor(
+ PcDescriptorsLayout::kOther, end_pc, DeoptId::kNone,
+ TokenPosition::kNoSource, try_index,
+ PcDescriptorsLayout::kInvalidYieldIndex);
// The exception handler keeps a zone handle of the types array, rather
// than a raw pointer. Do not share the handle across iterations to avoid
@@ -1049,8 +1066,8 @@
bytecode_component_->GetLocalVariablesOffset() + offset);
}
-RawTypedData* BytecodeReaderHelper::NativeEntry(const Function& function,
- const String& external_name) {
+TypedDataPtr BytecodeReaderHelper::NativeEntry(const Function& function,
+ const String& external_name) {
MethodRecognizer::Kind kind = function.recognized_kind();
// This list of recognized methods must be kept in sync with the list of
// methods handled specially by the NativeCall bytecode in the interpreter.
@@ -1128,7 +1145,7 @@
return NativeEntryData::New(kind, trampoline, native_function, argc_tag);
}
-RawArray* BytecodeReaderHelper::ReadBytecodeComponent(intptr_t md_offset) {
+ArrayPtr BytecodeReaderHelper::ReadBytecodeComponent(intptr_t md_offset) {
ASSERT(Thread::Current()->IsMutatorThread());
AlternativeReadingScope alt(&reader_, md_offset);
@@ -1261,14 +1278,14 @@
}
}
-RawObject* BytecodeReaderHelper::ReadObject() {
+ObjectPtr BytecodeReaderHelper::ReadObject() {
uint32_t header = reader_.ReadUInt();
if ((header & kReferenceBit) != 0) {
intptr_t index = header >> kIndexShift;
if (index == 0) {
return Object::null();
}
- RawObject* obj = bytecode_component_->GetObject(index);
+ ObjectPtr obj = bytecode_component_->GetObject(index);
if (obj->IsHeapObject()) {
return obj;
}
@@ -1292,8 +1309,8 @@
return ReadObjectContents(header);
}
-RawString* BytecodeReaderHelper::ConstructorName(const Class& cls,
- const String& name) {
+StringPtr BytecodeReaderHelper::ConstructorName(const Class& cls,
+ const String& name) {
GrowableHandlePtrArray<const String> pieces(Z, 3);
pieces.Add(String::Handle(Z, cls.Name()));
pieces.Add(Symbols::Dot());
@@ -1301,7 +1318,7 @@
return Symbols::FromConcatAll(thread_, pieces);
}
-RawObject* BytecodeReaderHelper::ReadObjectContents(uint32_t header) {
+ObjectPtr BytecodeReaderHelper::ReadObjectContents(uint32_t header) {
ASSERT(((header & kReferenceBit) == 0));
// Must be in sync with enum ObjectKind in
@@ -1352,7 +1369,7 @@
break;
case kLibrary: {
String& uri = String::CheckedHandle(Z, ReadObject());
- RawLibrary* library = Library::LookupLibrary(thread_, uri);
+ LibraryPtr library = Library::LookupLibrary(thread_, uri);
if (library == Library::null()) {
// We do not register expression evaluation libraries with the VM:
// The expression evaluation functions should be GC-able as soon as
@@ -1378,13 +1395,13 @@
const String& class_name = String::CheckedHandle(Z, ReadObject());
if (class_name.raw() == Symbols::Empty().raw()) {
NoSafepointScope no_safepoint_scope(thread_);
- RawClass* cls = library.toplevel_class();
+ ClassPtr cls = library.toplevel_class();
if (cls == Class::null()) {
FATAL1("Unable to find toplevel class %s", library.ToCString());
}
return cls;
}
- RawClass* cls = library.LookupLocalClass(class_name);
+ ClassPtr cls = library.LookupLocalClass(class_name);
if (cls == Class::null()) {
if (IsExpressionEvaluationLibrary(library)) {
return H.GetExpressionEvaluationRealClass();
@@ -1407,7 +1424,7 @@
const Class& cls = Class::CheckedHandle(Z, ReadObject());
String& name = String::CheckedHandle(Z, ReadObject());
if ((flags & kFlagIsField) != 0) {
- RawField* field = cls.LookupField(name);
+ FieldPtr field = cls.LookupField(name);
if (field == Field::null()) {
#if !defined(PRODUCT)
ASSERT(Isolate::Current()->HasAttemptedReload());
@@ -1430,7 +1447,7 @@
cls.raw() == scoped_function_class_.raw()) {
return scoped_function_.raw();
}
- RawFunction* function = cls.LookupFunction(name);
+ FunctionPtr function = cls.LookupFunction(name);
if (function == Function::null()) {
// When requesting a getter, also return method extractors.
if (Field::IsGetterName(name)) {
@@ -1538,7 +1555,7 @@
return Object::null();
}
-RawObject* BytecodeReaderHelper::ReadConstObject(intptr_t tag) {
+ObjectPtr BytecodeReaderHelper::ReadConstObject(intptr_t tag) {
// Must be in sync with enum ConstTag in
// pkg/vm/lib/bytecode/object_table.dart.
enum ConstTag {
@@ -1651,8 +1668,8 @@
return Object::null();
}
-RawObject* BytecodeReaderHelper::ReadType(intptr_t tag,
- Nullability nullability) {
+ObjectPtr BytecodeReaderHelper::ReadType(intptr_t tag,
+ Nullability nullability) {
// Must be in sync with enum TypeTag in
// pkg/vm/lib/bytecode/object_table.dart.
enum TypeTag {
@@ -1683,7 +1700,8 @@
case kVoid:
return AbstractType::void_type().raw();
case kNever:
- return AbstractType::never_type().ToNullability(nullability, Heap::kOld);
+ return Type::Handle(Z, Type::NeverType())
+ .ToNullability(nullability, Heap::kOld);
case kSimpleType: {
const Class& cls = Class::CheckedHandle(Z, ReadObject());
if (!cls.is_declaration_loaded()) {
@@ -1800,7 +1818,8 @@
signature_function, (flags & kFlagHasOptionalPositionalParams) != 0,
(flags & kFlagHasOptionalNamedParams) != 0,
(flags & kFlagHasTypeParams) != 0,
- /* has_positional_param_names = */ false, nullability);
+ /* has_positional_param_names = */ false,
+ /* has_parameter_flags */ false, nullability);
}
default:
UNREACHABLE();
@@ -1808,7 +1827,7 @@
return Object::null();
}
-RawString* BytecodeReaderHelper::ReadString(bool is_canonical) {
+StringPtr BytecodeReaderHelper::ReadString(bool is_canonical) {
const int kFlagTwoByteString = 1;
const int kHeaderFields = 2;
const int kUInt32Size = 4;
@@ -1858,8 +1877,8 @@
}
}
-RawScript* BytecodeReaderHelper::ReadSourceFile(const String& uri,
- intptr_t offset) {
+ScriptPtr BytecodeReaderHelper::ReadSourceFile(const String& uri,
+ intptr_t offset) {
// SourceFile flags, must be in sync with SourceFile constants in
// pkg/vm/lib/bytecode/declarations.dart.
const int kHasLineStartsFlag = 1 << 0;
@@ -1901,7 +1920,7 @@
return script.raw();
}
-RawTypeArguments* BytecodeReaderHelper::ReadTypeArguments() {
+TypeArgumentsPtr BytecodeReaderHelper::ReadTypeArguments() {
const bool is_recursive = reading_type_arguments_of_recursive_type_;
reading_type_arguments_of_recursive_type_ = false;
const intptr_t length = reader_.ReadUInt();
@@ -2088,8 +2107,8 @@
if ((flags & kHasGetterFlag) != 0) {
name ^= ReadObject();
function = Function::New(name,
- is_static ? RawFunction::kImplicitStaticGetter
- : RawFunction::kImplicitGetter,
+ is_static ? FunctionLayout::kImplicitStaticGetter
+ : FunctionLayout::kImplicitGetter,
is_static, is_const,
false, // is_abstract
false, // is_external
@@ -2112,7 +2131,7 @@
ASSERT(is_late || ((!is_static) && (!is_final)));
ASSERT(!is_const);
name ^= ReadObject();
- function = Function::New(name, RawFunction::kImplicitSetter, is_static,
+ function = Function::New(name, FunctionLayout::kImplicitSetter, is_static,
false, // is_const
false, // is_abstract
false, // is_external
@@ -2181,8 +2200,8 @@
}
}
-RawPatchClass* BytecodeReaderHelper::GetPatchClass(const Class& cls,
- const Script& script) {
+PatchClassPtr BytecodeReaderHelper::GetPatchClass(const Class& cls,
+ const Script& script) {
if (patch_class_ != nullptr && patch_class_->patched_class() == cls.raw() &&
patch_class_->script() == script.raw()) {
return patch_class_->raw();
@@ -2266,13 +2285,13 @@
end_position = reader_.ReadPosition();
}
- RawFunction::Kind kind = RawFunction::kRegularFunction;
+ FunctionLayout::Kind kind = FunctionLayout::kRegularFunction;
if ((flags & kIsGetterFlag) != 0) {
- kind = RawFunction::kGetterFunction;
+ kind = FunctionLayout::kGetterFunction;
} else if ((flags & kIsSetterFlag) != 0) {
- kind = RawFunction::kSetterFunction;
+ kind = FunctionLayout::kSetterFunction;
} else if ((flags & (kIsConstructorFlag | kIsFactoryFlag)) != 0) {
- kind = RawFunction::kConstructor;
+ kind = FunctionLayout::kConstructor;
name = ConstructorName(cls, name);
}
@@ -2307,17 +2326,17 @@
}
if ((flags & kIsSyncStarFlag) != 0) {
- function.set_modifier(RawFunction::kSyncGen);
+ function.set_modifier(FunctionLayout::kSyncGen);
function.set_is_visible(!FLAG_causal_async_stacks &&
!FLAG_lazy_async_stacks);
} else if ((flags & kIsAsyncFlag) != 0) {
- function.set_modifier(RawFunction::kAsync);
+ function.set_modifier(FunctionLayout::kAsync);
function.set_is_inlinable(!FLAG_causal_async_stacks &&
!FLAG_lazy_async_stacks);
function.set_is_visible(!FLAG_causal_async_stacks &&
!FLAG_lazy_async_stacks);
} else if ((flags & kIsAsyncStarFlag) != 0) {
- function.set_modifier(RawFunction::kAsyncGen);
+ function.set_modifier(FunctionLayout::kAsyncGen);
function.set_is_inlinable(!FLAG_causal_async_stacks &&
!FLAG_lazy_async_stacks);
function.set_is_visible(!FLAG_causal_async_stacks &&
@@ -2345,7 +2364,8 @@
parameter_types = Array::New(num_params, Heap::kOld);
function.set_parameter_types(parameter_types);
- parameter_names = Array::New(num_params, Heap::kOld);
+ parameter_names = Array::New(
+ Function::NameArrayLengthIncludingFlags(num_params), Heap::kOld);
function.set_parameter_names(parameter_names);
intptr_t param_index = 0;
@@ -2822,7 +2842,7 @@
}
}
-RawObject* BytecodeReaderHelper::BuildParameterDescriptor(
+ObjectPtr BytecodeReaderHelper::BuildParameterDescriptor(
const Function& function) {
ASSERT(function.is_declared_in_bytecode());
@@ -2947,20 +2967,20 @@
const Function& function) {
// Handle function kinds which don't have a user-defined body first.
switch (function.kind()) {
- case RawFunction::kImplicitClosureFunction:
+ case FunctionLayout::kImplicitClosureFunction:
ParseForwarderFunction(parsed_function, function,
Function::Handle(Z, function.parent_function()));
return;
- case RawFunction::kDynamicInvocationForwarder:
+ case FunctionLayout::kDynamicInvocationForwarder:
ParseForwarderFunction(parsed_function, function,
Function::Handle(Z, function.ForwardingTarget()));
return;
- case RawFunction::kImplicitGetter:
- case RawFunction::kImplicitSetter:
- case RawFunction::kMethodExtractor:
+ case FunctionLayout::kImplicitGetter:
+ case FunctionLayout::kImplicitSetter:
+ case FunctionLayout::kMethodExtractor:
BytecodeScopeBuilder(parsed_function).BuildScopes();
return;
- case RawFunction::kImplicitStaticGetter: {
+ case FunctionLayout::kImplicitStaticGetter: {
if (IsStaticFieldGetterGeneratedAsInitializer(function, Z)) {
break;
} else {
@@ -2968,18 +2988,18 @@
return;
}
}
- case RawFunction::kRegularFunction:
- case RawFunction::kGetterFunction:
- case RawFunction::kSetterFunction:
- case RawFunction::kClosureFunction:
- case RawFunction::kConstructor:
- case RawFunction::kFieldInitializer:
+ case FunctionLayout::kRegularFunction:
+ case FunctionLayout::kGetterFunction:
+ case FunctionLayout::kSetterFunction:
+ case FunctionLayout::kClosureFunction:
+ case FunctionLayout::kConstructor:
+ case FunctionLayout::kFieldInitializer:
break;
- case RawFunction::kNoSuchMethodDispatcher:
- case RawFunction::kInvokeFieldDispatcher:
- case RawFunction::kSignatureFunction:
- case RawFunction::kIrregexpFunction:
- case RawFunction::kFfiTrampoline:
+ case FunctionLayout::kNoSuchMethodDispatcher:
+ case FunctionLayout::kInvokeFieldDispatcher:
+ case FunctionLayout::kSignatureFunction:
+ case FunctionLayout::kIrregexpFunction:
+ case FunctionLayout::kFfiTrampoline:
UNREACHABLE();
break;
}
@@ -3055,6 +3075,11 @@
bool is_covariant = (flags & Parameter::kIsCovariantFlag) != 0;
bool is_generic_covariant_impl =
(flags & Parameter::kIsGenericCovariantImplFlag) != 0;
+ bool is_required = (flags & Parameter::kIsRequiredFlag) != 0;
+
+ if (is_required) {
+ function.SetIsRequiredAt(num_implicit_params + i);
+ }
LocalVariable* variable =
parsed_function->ParameterVariable(num_implicit_params + i);
@@ -3146,7 +3171,7 @@
}
}
-RawLibrary* BytecodeReaderHelper::ReadMain() {
+LibraryPtr BytecodeReaderHelper::ReadMain() {
return Library::RawCast(ReadObject());
}
@@ -3234,32 +3259,32 @@
data_.SetAt(kNumFields + index, obj);
}
-RawObject* BytecodeComponentData::GetObject(intptr_t index) const {
+ObjectPtr BytecodeComponentData::GetObject(intptr_t index) const {
return data_.At(kNumFields + index);
}
-RawArray* BytecodeComponentData::New(Zone* zone,
- intptr_t version,
- intptr_t num_objects,
- intptr_t strings_header_offset,
- intptr_t strings_contents_offset,
- intptr_t object_offsets_offset,
- intptr_t objects_contents_offset,
- intptr_t main_offset,
- intptr_t num_libraries,
- intptr_t library_index_offset,
- intptr_t libraries_offset,
- intptr_t num_classes,
- intptr_t classes_offset,
- intptr_t members_offset,
- intptr_t num_codes,
- intptr_t codes_offset,
- intptr_t source_positions_offset,
- intptr_t source_files_offset,
- intptr_t line_starts_offset,
- intptr_t local_variables_offset,
- intptr_t annotations_offset,
- Heap::Space space) {
+ArrayPtr BytecodeComponentData::New(Zone* zone,
+ intptr_t version,
+ intptr_t num_objects,
+ intptr_t strings_header_offset,
+ intptr_t strings_contents_offset,
+ intptr_t object_offsets_offset,
+ intptr_t objects_contents_offset,
+ intptr_t main_offset,
+ intptr_t num_libraries,
+ intptr_t library_index_offset,
+ intptr_t libraries_offset,
+ intptr_t num_classes,
+ intptr_t classes_offset,
+ intptr_t members_offset,
+ intptr_t num_codes,
+ intptr_t codes_offset,
+ intptr_t source_positions_offset,
+ intptr_t source_files_offset,
+ intptr_t line_starts_offset,
+ intptr_t local_variables_offset,
+ intptr_t annotations_offset,
+ Heap::Space space) {
const Array& data =
Array::Handle(zone, Array::New(kNumFields + num_objects, space));
Smi& smi_handle = Smi::Handle(zone);
@@ -3327,8 +3352,8 @@
return data.raw();
}
-RawError* BytecodeReader::ReadFunctionBytecode(Thread* thread,
- const Function& function) {
+ErrorPtr BytecodeReader::ReadFunctionBytecode(Thread* thread,
+ const Function& function) {
ASSERT(!FLAG_precompiled_mode);
ASSERT(!function.HasBytecode());
ASSERT(thread->sticky_error() == Error::null());
@@ -3356,31 +3381,31 @@
auto& bytecode = Bytecode::Handle(zone);
switch (function.kind()) {
- case RawFunction::kImplicitGetter:
+ case FunctionLayout::kImplicitGetter:
bytecode = Object::implicit_getter_bytecode().raw();
break;
- case RawFunction::kImplicitSetter:
+ case FunctionLayout::kImplicitSetter:
bytecode = Object::implicit_setter_bytecode().raw();
break;
- case RawFunction::kImplicitStaticGetter:
+ case FunctionLayout::kImplicitStaticGetter:
if (!IsStaticFieldGetterGeneratedAsInitializer(function, zone)) {
bytecode = Object::implicit_static_getter_bytecode().raw();
}
break;
- case RawFunction::kMethodExtractor:
+ case FunctionLayout::kMethodExtractor:
bytecode = Object::method_extractor_bytecode().raw();
break;
- case RawFunction::kInvokeFieldDispatcher:
+ case FunctionLayout::kInvokeFieldDispatcher:
if (Class::Handle(zone, function.Owner()).id() == kClosureCid) {
bytecode = Object::invoke_closure_bytecode().raw();
} else {
bytecode = Object::invoke_field_bytecode().raw();
}
break;
- case RawFunction::kNoSuchMethodDispatcher:
+ case FunctionLayout::kNoSuchMethodDispatcher:
bytecode = Object::nsm_dispatcher_bytecode().raw();
break;
- case RawFunction::kDynamicInvocationForwarder: {
+ case FunctionLayout::kDynamicInvocationForwarder: {
const Function& target =
Function::Handle(zone, function.ForwardingTarget());
if (!target.HasBytecode()) {
@@ -3451,7 +3476,7 @@
}
}
-RawObject* BytecodeReader::ReadAnnotation(const Field& annotation_field) {
+ObjectPtr BytecodeReader::ReadAnnotation(const Field& annotation_field) {
ASSERT(annotation_field.is_declared_in_bytecode());
Thread* thread = Thread::Current();
@@ -3476,8 +3501,8 @@
return bytecode_reader.ReadObject();
}
-RawArray* BytecodeReader::ReadExtendedAnnotations(const Field& annotation_field,
- intptr_t count) {
+ArrayPtr BytecodeReader::ReadExtendedAnnotations(const Field& annotation_field,
+ intptr_t count) {
ASSERT(annotation_field.is_declared_in_bytecode());
Thread* thread = Thread::Current();
@@ -3582,8 +3607,8 @@
bytecode_reader.ReadMembers(cls, discard_fields);
}
-RawObject* BytecodeReader::GetBytecodeAttribute(const Object& key,
- const String& name) {
+ObjectPtr BytecodeReader::GetBytecodeAttribute(const Object& key,
+ const String& name) {
Thread* thread = Thread::Current();
Zone* zone = thread->zone();
const auto* object_store = thread->isolate()->object_store();
@@ -3622,7 +3647,7 @@
}
#if !defined(PRODUCT)
-RawLocalVarDescriptors* BytecodeReader::ComputeLocalVarDescriptors(
+LocalVarDescriptorsPtr BytecodeReader::ComputeLocalVarDescriptors(
Zone* zone,
const Function& function,
const Bytecode& bytecode) {
@@ -3640,14 +3665,14 @@
const auto& parent_vars = LocalVarDescriptors::Handle(
zone, parent_bytecode.GetLocalVarDescriptors());
for (intptr_t i = 0; i < parent_vars.Length(); ++i) {
- RawLocalVarDescriptors::VarInfo var_info;
+ LocalVarDescriptorsLayout::VarInfo var_info;
parent_vars.GetInfo(i, &var_info);
// Include parent's context variable if variable's scope
// intersects with the local function range.
// It is not enough to check if local function is declared within the
// scope of variable, because in case of async functions closure has
// the same range as original function.
- if (var_info.kind() == RawLocalVarDescriptors::kContextVar &&
+ if (var_info.kind() == LocalVarDescriptorsLayout::kContextVar &&
((var_info.begin_pos <= function.token_pos() &&
function.token_pos() <= var_info.end_pos) ||
(function.token_pos() <= var_info.begin_pos &&
@@ -3672,11 +3697,11 @@
LocalVarDescriptorsBuilder::VarDesc desc;
desc.name = &String::Handle(zone, local_vars.Name());
if (local_vars.IsCaptured()) {
- desc.info.set_kind(RawLocalVarDescriptors::kContextVar);
+ desc.info.set_kind(LocalVarDescriptorsLayout::kContextVar);
desc.info.scope_id = context_level;
desc.info.set_index(local_vars.Index());
} else {
- desc.info.set_kind(RawLocalVarDescriptors::kStackVar);
+ desc.info.set_kind(LocalVarDescriptorsLayout::kStackVar);
desc.info.scope_id = scope_id;
if (local_vars.Index() < 0) {
// Parameter
@@ -3696,7 +3721,7 @@
const intptr_t context_variable_index = -local_vars.Index();
LocalVarDescriptorsBuilder::VarDesc desc;
desc.name = &Symbols::CurrentContextVar();
- desc.info.set_kind(RawLocalVarDescriptors::kSavedCurrentContext);
+ desc.info.set_kind(LocalVarDescriptorsLayout::kSavedCurrentContext);
desc.info.scope_id = 0;
desc.info.declaration_pos = TokenPosition::kMinSource;
desc.info.begin_pos = TokenPosition::kMinSource;
@@ -3714,7 +3739,7 @@
bool IsStaticFieldGetterGeneratedAsInitializer(const Function& function,
Zone* zone) {
- ASSERT(function.kind() == RawFunction::kImplicitStaticGetter);
+ ASSERT(function.kind() == FunctionLayout::kImplicitStaticGetter);
const auto& field = Field::Handle(zone, function.accessor_field());
return field.is_declared_in_bytecode() && field.is_const() &&
diff --git a/runtime/vm/compiler/frontend/bytecode_reader.h b/runtime/vm/compiler/frontend/bytecode_reader.h
index 81abc86..ee8444f 100644
--- a/runtime/vm/compiler/frontend/bytecode_reader.h
+++ b/runtime/vm/compiler/frontend/bytecode_reader.h
@@ -42,10 +42,10 @@
intptr_t* p_num_classes,
intptr_t* p_num_procedures);
- RawLibrary* GetMainLibrary();
+ LibraryPtr GetMainLibrary();
- RawArray* GetBytecodeComponent();
- RawArray* ReadBytecodeComponent();
+ ArrayPtr GetBytecodeComponent();
+ ArrayPtr ReadBytecodeComponent();
private:
ActiveClass* const active_class_;
@@ -64,7 +64,7 @@
void ReadCode(const Function& function, intptr_t code_offset);
- RawArray* CreateForwarderChecks(const Function& function);
+ ArrayPtr CreateForwarderChecks(const Function& function);
void ReadMembers(const Class& cls, bool discard_fields);
@@ -81,9 +81,9 @@
void ParseBytecodeFunction(ParsedFunction* parsed_function,
const Function& function);
- RawLibrary* ReadMain();
+ LibraryPtr ReadMain();
- RawArray* ReadBytecodeComponent(intptr_t md_offset);
+ ArrayPtr ReadBytecodeComponent(intptr_t md_offset);
void ResetObjects();
// Fills in [is_covariant] and [is_generic_covariant_impl] vectors
@@ -98,10 +98,10 @@
// Returns an flattened array of tuples {isFinal, defaultValue, metadata},
// or an Error.
- RawObject* BuildParameterDescriptor(const Function& function);
+ ObjectPtr BuildParameterDescriptor(const Function& function);
// Read bytecode PackedObject.
- RawObject* ReadObject();
+ ObjectPtr ReadObject();
private:
// These constants should match corresponding constants in class ObjectHandle
@@ -147,6 +147,7 @@
static const int kIsCovariantFlag = 1 << 0;
static const int kIsGenericCovariantImplFlag = 1 << 1;
static const int kIsFinalFlag = 1 << 2;
+ static const int kIsRequiredFlag = 1 << 3;
};
class FunctionTypeScope : public ValueObject {
@@ -192,12 +193,13 @@
};
void ReadClosureDeclaration(const Function& function, intptr_t closureIndex);
- RawType* ReadFunctionSignature(const Function& func,
- bool has_optional_positional_params,
- bool has_optional_named_params,
- bool has_type_params,
- bool has_positional_param_names,
- Nullability nullability);
+ TypePtr ReadFunctionSignature(const Function& func,
+ bool has_optional_positional_params,
+ bool has_optional_named_params,
+ bool has_type_params,
+ bool has_positional_param_names,
+ bool has_parameter_flags,
+ Nullability nullability);
void ReadTypeParametersDeclaration(const Class& parameterized_class,
const Function& parameterized_function);
@@ -208,22 +210,22 @@
const ObjectPool& pool,
intptr_t start_index);
- RawBytecode* ReadBytecode(const ObjectPool& pool);
+ BytecodePtr ReadBytecode(const ObjectPool& pool);
void ReadExceptionsTable(const Bytecode& bytecode, bool has_exceptions_table);
void ReadSourcePositions(const Bytecode& bytecode, bool has_source_positions);
void ReadLocalVariables(const Bytecode& bytecode, bool has_local_variables);
- RawTypedData* NativeEntry(const Function& function,
- const String& external_name);
- RawString* ConstructorName(const Class& cls, const String& name);
+ TypedDataPtr NativeEntry(const Function& function,
+ const String& external_name);
+ StringPtr ConstructorName(const Class& cls, const String& name);
- RawObject* ReadObjectContents(uint32_t header);
- RawObject* ReadConstObject(intptr_t tag);
- RawObject* ReadType(intptr_t tag, Nullability nullability);
- RawString* ReadString(bool is_canonical = true);
- RawScript* ReadSourceFile(const String& uri, intptr_t offset);
- RawTypeArguments* ReadTypeArguments();
+ ObjectPtr ReadObjectContents(uint32_t header);
+ ObjectPtr ReadConstObject(intptr_t tag);
+ ObjectPtr ReadType(intptr_t tag, Nullability nullability);
+ StringPtr ReadString(bool is_canonical = true);
+ ScriptPtr ReadSourceFile(const String& uri, intptr_t offset);
+ TypeArgumentsPtr ReadTypeArguments();
void ReadAttributes(const Object& key);
- RawPatchClass* GetPatchClass(const Class& cls, const Script& script);
+ PatchClassPtr GetPatchClass(const Class& cls, const Script& script);
void ParseForwarderFunction(ParsedFunction* parsed_function,
const Function& function,
const Function& target);
@@ -310,32 +312,32 @@
intptr_t GetLocalVariablesOffset() const;
intptr_t GetAnnotationsOffset() const;
void SetObject(intptr_t index, const Object& obj) const;
- RawObject* GetObject(intptr_t index) const;
+ ObjectPtr GetObject(intptr_t index) const;
bool IsNull() const { return data_.IsNull(); }
- static RawArray* New(Zone* zone,
- intptr_t version,
- intptr_t num_objects,
- intptr_t strings_header_offset,
- intptr_t strings_contents_offset,
- intptr_t object_offsets_offset,
- intptr_t objects_contents_offset,
- intptr_t main_offset,
- intptr_t num_libraries,
- intptr_t library_index_offset,
- intptr_t libraries_offset,
- intptr_t num_classes,
- intptr_t classes_offset,
- intptr_t members_offset,
- intptr_t num_codes,
- intptr_t codes_offset,
- intptr_t source_positions_offset,
- intptr_t source_files_offset,
- intptr_t line_starts_offset,
- intptr_t local_variables_offset,
- intptr_t annotations_offset,
- Heap::Space space);
+ static ArrayPtr New(Zone* zone,
+ intptr_t version,
+ intptr_t num_objects,
+ intptr_t strings_header_offset,
+ intptr_t strings_contents_offset,
+ intptr_t object_offsets_offset,
+ intptr_t objects_contents_offset,
+ intptr_t main_offset,
+ intptr_t num_libraries,
+ intptr_t library_index_offset,
+ intptr_t libraries_offset,
+ intptr_t num_classes,
+ intptr_t classes_offset,
+ intptr_t members_offset,
+ intptr_t num_codes,
+ intptr_t codes_offset,
+ intptr_t source_positions_offset,
+ intptr_t source_files_offset,
+ intptr_t line_starts_offset,
+ intptr_t local_variables_offset,
+ intptr_t annotations_offset,
+ Heap::Space space);
private:
Array& data_;
@@ -345,14 +347,14 @@
public:
// Reads bytecode for the given function and sets its bytecode field.
// Returns error (if any), or null.
- static RawError* ReadFunctionBytecode(Thread* thread,
- const Function& function);
+ static ErrorPtr ReadFunctionBytecode(Thread* thread,
+ const Function& function);
// Read annotations for the given annotation field.
- static RawObject* ReadAnnotation(const Field& annotation_field);
+ static ObjectPtr ReadAnnotation(const Field& annotation_field);
// Read the |count| annotations following given annotation field.
- static RawArray* ReadExtendedAnnotations(const Field& annotation_field,
- intptr_t count);
+ static ArrayPtr ReadExtendedAnnotations(const Field& annotation_field,
+ intptr_t count);
static void ResetObjectTable(const KernelProgramInfo& info);
@@ -366,11 +368,11 @@
static void FinishClassLoading(const Class& cls);
// Value of attribute [name] of Function/Field [key].
- static RawObject* GetBytecodeAttribute(const Object& key, const String& name);
+ static ObjectPtr GetBytecodeAttribute(const Object& key, const String& name);
#if !defined(PRODUCT)
// Compute local variable descriptors for [function] with [bytecode].
- static RawLocalVarDescriptors* ComputeLocalVarDescriptors(
+ static LocalVarDescriptorsPtr ComputeLocalVarDescriptors(
Zone* zone,
const Function& function,
const Bytecode& bytecode);
@@ -530,11 +532,11 @@
ASSERT(IsVariableDeclaration() || IsContextVariable());
return cur_index_;
}
- RawString* Name() const {
+ StringPtr Name() const {
ASSERT(IsVariableDeclaration());
return String::RawCast(object_pool_.ObjectAt(cur_name_));
}
- RawAbstractType* Type() const {
+ AbstractTypePtr Type() const {
ASSERT(IsVariableDeclaration());
return AbstractType::RawCast(object_pool_.ObjectAt(cur_type_));
}
diff --git a/runtime/vm/compiler/frontend/bytecode_scope_builder.cc b/runtime/vm/compiler/frontend/bytecode_scope_builder.cc
index 91acf20..bc1a30b 100644
--- a/runtime/vm/compiler/frontend/bytecode_scope_builder.cc
+++ b/runtime/vm/compiler/frontend/bytecode_scope_builder.cc
@@ -61,7 +61,7 @@
parsed_function_->set_scope(scope_);
switch (function.kind()) {
- case RawFunction::kImplicitClosureFunction: {
+ case FunctionLayout::kImplicitClosureFunction: {
ASSERT(function.NumImplicitParameters() == 1);
LocalVariable* closure_parameter = MakeVariable(
@@ -76,8 +76,8 @@
break;
}
- case RawFunction::kImplicitGetter:
- case RawFunction::kImplicitSetter: {
+ case FunctionLayout::kImplicitGetter:
+ case FunctionLayout::kImplicitSetter: {
const bool is_setter = function.IsImplicitSetterFunction();
const bool is_method = !function.IsStaticFunction();
const Field& field = Field::Handle(Z, function.accessor_field());
@@ -108,11 +108,11 @@
}
break;
}
- case RawFunction::kImplicitStaticGetter: {
+ case FunctionLayout::kImplicitStaticGetter: {
ASSERT(!IsStaticFieldGetterGeneratedAsInitializer(function, Z));
break;
}
- case RawFunction::kDynamicInvocationForwarder: {
+ case FunctionLayout::kDynamicInvocationForwarder: {
// Create [this] variable.
MakeReceiverVariable(/* is_parameter = */ true);
@@ -122,7 +122,7 @@
AddParameters(function, LocalVariable::kDoTypeCheck);
break;
}
- case RawFunction::kMethodExtractor: {
+ case FunctionLayout::kMethodExtractor: {
// Add a receiver parameter. Though it is captured, we emit code to
// explicitly copy it to a fixed offset in a freshly-allocated context
// instead of using the generic code for regular functions.
diff --git a/runtime/vm/compiler/frontend/constant_reader.cc b/runtime/vm/compiler/frontend/constant_reader.cc
index 08fd420..cb0c693 100644
--- a/runtime/vm/compiler/frontend/constant_reader.cc
+++ b/runtime/vm/compiler/frontend/constant_reader.cc
@@ -19,7 +19,7 @@
script_(helper->script()),
result_(Instance::Handle(zone_)) {}
-RawInstance* ConstantReader::ReadConstantExpression() {
+InstancePtr ConstantReader::ReadConstantExpression() {
Tag tag = helper_->ReadTag(); // read tag.
switch (tag) {
case kConstantExpression:
@@ -44,7 +44,7 @@
return result_.raw();
}
-RawObject* ConstantReader::ReadAnnotations() {
+ObjectPtr ConstantReader::ReadAnnotations() {
intptr_t list_length = helper_->ReadListLength(); // read list length.
const Array& metadata_values =
Array::Handle(Z, Array::New(list_length, H.allocation_space()));
@@ -57,7 +57,7 @@
return metadata_values.raw();
}
-RawInstance* ConstantReader::ReadConstant(intptr_t constant_offset) {
+InstancePtr ConstantReader::ReadConstant(intptr_t constant_offset) {
ASSERT(!H.constants().IsNull());
ASSERT(!H.constants_table().IsNull()); // raw bytes
@@ -100,7 +100,7 @@
return false;
}
-RawInstance* ConstantReader::ReadConstantInternal(intptr_t constant_offset) {
+InstancePtr ConstantReader::ReadConstantInternal(intptr_t constant_offset) {
// Get reader directly into raw bytes of constant table.
bool null_safety = H.thread()->isolate()->null_safety();
KernelReaderHelper reader(Z, &H, script_, H.constants_table(), 0);
diff --git a/runtime/vm/compiler/frontend/constant_reader.h b/runtime/vm/compiler/frontend/constant_reader.h
index 8e7a519..871b7f0 100644
--- a/runtime/vm/compiler/frontend/constant_reader.h
+++ b/runtime/vm/compiler/frontend/constant_reader.h
@@ -23,8 +23,8 @@
virtual ~ConstantReader() {}
- RawInstance* ReadConstantExpression();
- RawObject* ReadAnnotations();
+ InstancePtr ReadConstantExpression();
+ ObjectPtr ReadAnnotations();
// Peeks to see if constant at the given offset will evaluate to
// instance of the given clazz.
@@ -32,10 +32,10 @@
// Reads a constant at the given offset (possibly by recursing
// into sub-constants).
- RawInstance* ReadConstant(intptr_t constant_offset);
+ InstancePtr ReadConstant(intptr_t constant_offset);
private:
- RawInstance* ReadConstantInternal(intptr_t constant_offset);
+ InstancePtr ReadConstantInternal(intptr_t constant_offset);
KernelReaderHelper* helper_;
Zone* zone_;
@@ -67,12 +67,12 @@
static uword Hash(const intptr_t key) {
return HashValue(Smi::Value(KeyAsSmi(key)));
}
- static RawObject* NewKey(const intptr_t key) { return KeyAsSmi(key); }
+ static ObjectPtr NewKey(const intptr_t key) { return KeyAsSmi(key); }
private:
static uword HashValue(intptr_t pos) { return pos % (Smi::kMaxValue - 13); }
- static RawSmi* KeyAsSmi(const intptr_t key) {
+ static SmiPtr KeyAsSmi(const intptr_t key) {
ASSERT(key >= 0);
return Smi::New(key);
}
diff --git a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
index fbc70d0..4dcc794 100644
--- a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
+++ b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
@@ -54,6 +54,7 @@
body += Constant(
Instance::ZoneHandle(Z, constant_reader_.ReadConstantExpression()));
} else {
+ body += SetupCapturedParameters(parsed_function()->function());
body += BuildExpression(); // read initializer.
}
body += Return(TokenPosition::kNoSource);
@@ -1088,22 +1089,22 @@
bytecode_metadata_helper_.ParseBytecodeFunction(parsed_function());
switch (function.kind()) {
- case RawFunction::kImplicitClosureFunction:
+ case FunctionLayout::kImplicitClosureFunction:
return B->BuildGraphOfImplicitClosureFunction(function);
- case RawFunction::kImplicitGetter:
- case RawFunction::kImplicitSetter:
+ case FunctionLayout::kImplicitGetter:
+ case FunctionLayout::kImplicitSetter:
return B->BuildGraphOfFieldAccessor(function);
- case RawFunction::kImplicitStaticGetter: {
+ case FunctionLayout::kImplicitStaticGetter: {
if (IsStaticFieldGetterGeneratedAsInitializer(function, Z)) {
break;
}
return B->BuildGraphOfFieldAccessor(function);
}
- case RawFunction::kDynamicInvocationForwarder:
+ case FunctionLayout::kDynamicInvocationForwarder:
return B->BuildGraphOfDynamicInvocationForwarder(function);
- case RawFunction::kMethodExtractor:
+ case FunctionLayout::kMethodExtractor:
return B->BuildGraphOfMethodExtractor(function);
- case RawFunction::kNoSuchMethodDispatcher:
+ case FunctionLayout::kNoSuchMethodDispatcher:
return B->BuildGraphOfNoSuchMethodDispatcher(function);
default:
break;
@@ -1126,51 +1127,51 @@
// Certain special functions could have a VM-internal bytecode
// attached to them.
ASSERT((!function.HasBytecode()) ||
- (function.kind() == RawFunction::kImplicitGetter) ||
- (function.kind() == RawFunction::kImplicitSetter) ||
- (function.kind() == RawFunction::kImplicitStaticGetter) ||
- (function.kind() == RawFunction::kMethodExtractor) ||
- (function.kind() == RawFunction::kInvokeFieldDispatcher) ||
- (function.kind() == RawFunction::kNoSuchMethodDispatcher));
+ (function.kind() == FunctionLayout::kImplicitGetter) ||
+ (function.kind() == FunctionLayout::kImplicitSetter) ||
+ (function.kind() == FunctionLayout::kImplicitStaticGetter) ||
+ (function.kind() == FunctionLayout::kMethodExtractor) ||
+ (function.kind() == FunctionLayout::kInvokeFieldDispatcher) ||
+ (function.kind() == FunctionLayout::kNoSuchMethodDispatcher));
ParseKernelASTFunction();
switch (function.kind()) {
- case RawFunction::kRegularFunction:
- case RawFunction::kGetterFunction:
- case RawFunction::kSetterFunction:
- case RawFunction::kClosureFunction:
- case RawFunction::kConstructor: {
+ case FunctionLayout::kRegularFunction:
+ case FunctionLayout::kGetterFunction:
+ case FunctionLayout::kSetterFunction:
+ case FunctionLayout::kClosureFunction:
+ case FunctionLayout::kConstructor: {
if (B->IsRecognizedMethodForFlowGraph(function)) {
return B->BuildGraphOfRecognizedMethod(function);
}
return BuildGraphOfFunction(function.IsGenerativeConstructor());
}
- case RawFunction::kImplicitGetter:
- case RawFunction::kImplicitStaticGetter:
- case RawFunction::kImplicitSetter: {
+ case FunctionLayout::kImplicitGetter:
+ case FunctionLayout::kImplicitStaticGetter:
+ case FunctionLayout::kImplicitSetter: {
const Field& field = Field::Handle(Z, function.accessor_field());
if (field.is_const() && field.IsUninitialized()) {
EvaluateConstFieldValue(field);
}
return B->BuildGraphOfFieldAccessor(function);
}
- case RawFunction::kFieldInitializer:
+ case FunctionLayout::kFieldInitializer:
return BuildGraphOfFieldInitializer();
- case RawFunction::kDynamicInvocationForwarder:
+ case FunctionLayout::kDynamicInvocationForwarder:
return B->BuildGraphOfDynamicInvocationForwarder(function);
- case RawFunction::kMethodExtractor:
+ case FunctionLayout::kMethodExtractor:
return flow_graph_builder_->BuildGraphOfMethodExtractor(function);
- case RawFunction::kNoSuchMethodDispatcher:
+ case FunctionLayout::kNoSuchMethodDispatcher:
return flow_graph_builder_->BuildGraphOfNoSuchMethodDispatcher(function);
- case RawFunction::kInvokeFieldDispatcher:
+ case FunctionLayout::kInvokeFieldDispatcher:
return flow_graph_builder_->BuildGraphOfInvokeFieldDispatcher(function);
- case RawFunction::kImplicitClosureFunction:
+ case FunctionLayout::kImplicitClosureFunction:
return flow_graph_builder_->BuildGraphOfImplicitClosureFunction(function);
- case RawFunction::kFfiTrampoline:
+ case FunctionLayout::kFfiTrampoline:
return flow_graph_builder_->BuildGraphOfFfiTrampoline(function);
- case RawFunction::kSignatureFunction:
- case RawFunction::kIrregexpFunction:
+ case FunctionLayout::kSignatureFunction:
+ case FunctionLayout::kIrregexpFunction:
break;
}
UNREACHABLE();
@@ -1187,13 +1188,13 @@
// Mark forwarding stubs.
switch (function.kind()) {
- case RawFunction::kRegularFunction:
- case RawFunction::kImplicitClosureFunction:
- case RawFunction::kGetterFunction:
- case RawFunction::kSetterFunction:
- case RawFunction::kClosureFunction:
- case RawFunction::kConstructor:
- case RawFunction::kDynamicInvocationForwarder:
+ case FunctionLayout::kRegularFunction:
+ case FunctionLayout::kImplicitClosureFunction:
+ case FunctionLayout::kGetterFunction:
+ case FunctionLayout::kSetterFunction:
+ case FunctionLayout::kClosureFunction:
+ case FunctionLayout::kConstructor:
+ case FunctionLayout::kDynamicInvocationForwarder:
ReadForwardingStubTarget(function);
break;
default:
@@ -1203,34 +1204,34 @@
set_scopes(parsed_function()->EnsureKernelScopes());
switch (function.kind()) {
- case RawFunction::kRegularFunction:
- case RawFunction::kGetterFunction:
- case RawFunction::kSetterFunction:
- case RawFunction::kClosureFunction:
- case RawFunction::kConstructor:
- case RawFunction::kImplicitClosureFunction:
+ case FunctionLayout::kRegularFunction:
+ case FunctionLayout::kGetterFunction:
+ case FunctionLayout::kSetterFunction:
+ case FunctionLayout::kClosureFunction:
+ case FunctionLayout::kConstructor:
+ case FunctionLayout::kImplicitClosureFunction:
ReadUntilFunctionNode();
SetupDefaultParameterValues();
ReadDefaultFunctionTypeArguments(function);
break;
- case RawFunction::kImplicitGetter:
- case RawFunction::kImplicitStaticGetter:
- case RawFunction::kImplicitSetter:
- case RawFunction::kFieldInitializer:
- case RawFunction::kMethodExtractor:
- case RawFunction::kNoSuchMethodDispatcher:
- case RawFunction::kInvokeFieldDispatcher:
- case RawFunction::kFfiTrampoline:
+ case FunctionLayout::kImplicitGetter:
+ case FunctionLayout::kImplicitStaticGetter:
+ case FunctionLayout::kImplicitSetter:
+ case FunctionLayout::kFieldInitializer:
+ case FunctionLayout::kMethodExtractor:
+ case FunctionLayout::kNoSuchMethodDispatcher:
+ case FunctionLayout::kInvokeFieldDispatcher:
+ case FunctionLayout::kFfiTrampoline:
break;
- case RawFunction::kDynamicInvocationForwarder:
+ case FunctionLayout::kDynamicInvocationForwarder:
if (PeekTag() != kField) {
ReadUntilFunctionNode();
SetupDefaultParameterValues();
ReadDefaultFunctionTypeArguments(function);
}
break;
- case RawFunction::kSignatureFunction:
- case RawFunction::kIrregexpFunction:
+ case FunctionLayout::kSignatureFunction:
+ case FunctionLayout::kIrregexpFunction:
UNREACHABLE();
break;
}
@@ -1714,16 +1715,23 @@
clear_the_temp);
}
-static void BadArity() {
+static void BadArity(const Script& script,
+ TokenPosition position,
+ const String& error_message) {
#ifndef PRODUCT
// TODO(https://github.com/dart-lang/sdk/issues/37517): Should emit code to
// throw a NoSuchMethodError.
- ASSERT(Isolate::Current()->HasAttemptedReload());
- Report::LongJump(LanguageError::Handle(LanguageError::New(String::Handle(
- String::New("Unimplemented handling of static target arity change")))));
-#else
- UNREACHABLE();
+ // Correct arity is checked at compile time by CFE. However, an isolate reload
+ // after an arity change may lead here.
+ // Using strong mode with a mix of opted in and opted out libraries may
+ // also result in this error undetected by CFE.
+ Isolate* isolate = Isolate::Current();
+ ASSERT(isolate->HasAttemptedReload() || isolate->null_safety());
+ Report::MessageF(Report::kError, script, position, Report::AtLocation,
+ "Static call with invalid arguments: %s",
+ error_message.ToCString());
#endif
+ UNREACHABLE();
}
Fragment StreamingFlowGraphBuilder::StaticCall(TokenPosition position,
@@ -1732,7 +1740,7 @@
ICData::RebindRule rebind_rule) {
String& error_message = String::Handle();
if (!target.AreValidArgumentCounts(0, argument_count, 0, &error_message)) {
- BadArity();
+ BadArity(script_, position, error_message);
}
return flow_graph_builder_->StaticCall(position, target, argument_count,
rebind_rule);
@@ -1750,7 +1758,7 @@
String& error_message = String::Handle();
if (!target.AreValidArguments(type_args_count, argument_count, argument_names,
&error_message)) {
- BadArity();
+ BadArity(script_, position, error_message);
}
return flow_graph_builder_->StaticCall(
position, target, argument_count, argument_names, rebind_rule,
@@ -3365,7 +3373,8 @@
instructions +=
BuildArguments(&argument_names, NULL /* arg count */,
NULL /* positional arg count */); // read arguments.
- ASSERT(target.AreValidArguments(type_args_len, argument_count, argument_names,
+ ASSERT(!special_case ||
+ target.AreValidArguments(type_args_len, argument_count, argument_names,
NULL));
// Special case identical(x, y) call.
@@ -4497,9 +4506,8 @@
Z, klass.LookupConstructorAllowPrivate(String::ZoneHandle(
Z, Symbols::FromConcatAll(H.thread(), pieces))));
ASSERT(!constructor.IsNull());
- const String& url = H.DartString(
- parsed_function()->function().ToLibNamePrefixedQualifiedCString(),
- Heap::kOld);
+ const String& url = H.DartSymbolPlain(
+ parsed_function()->function().ToLibNamePrefixedQualifiedCString());
// Create instance of _FallThroughError
body_fragment += AllocateObject(TokenPosition::kNoSource, klass, 0);
@@ -5096,8 +5104,8 @@
// NOTE: This is not TokenPosition in the general sense!
if (!closure_owner_.IsNull()) {
function = Function::NewClosureFunctionWithKind(
- RawFunction::kClosureFunction, *name, parsed_function()->function(),
- position, closure_owner_);
+ FunctionLayout::kClosureFunction, *name,
+ parsed_function()->function(), position, closure_owner_);
} else {
function = Function::NewClosureFunction(
*name, parsed_function()->function(), position);
@@ -5107,14 +5115,14 @@
FunctionNodeHelper::kSync);
switch (function_node_helper.dart_async_marker_) {
case FunctionNodeHelper::kSyncStar:
- function.set_modifier(RawFunction::kSyncGen);
+ function.set_modifier(FunctionLayout::kSyncGen);
break;
case FunctionNodeHelper::kAsync:
- function.set_modifier(RawFunction::kAsync);
+ function.set_modifier(FunctionLayout::kAsync);
function.set_is_inlinable(!FLAG_causal_async_stacks);
break;
case FunctionNodeHelper::kAsyncStar:
- function.set_modifier(RawFunction::kAsyncGen);
+ function.set_modifier(FunctionLayout::kAsyncGen);
function.set_is_inlinable(!FLAG_causal_async_stacks);
break;
default:
diff --git a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.h b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.h
index 3b05a70..fbba4d6 100644
--- a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.h
+++ b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.h
@@ -161,8 +161,9 @@
void InlineBailout(const char* reason);
Fragment DebugStepCheck(TokenPosition position);
Fragment LoadLocal(LocalVariable* variable);
- Fragment Return(TokenPosition position,
- intptr_t yield_index = RawPcDescriptors::kInvalidYieldIndex);
+ Fragment Return(
+ TokenPosition position,
+ intptr_t yield_index = PcDescriptorsLayout::kInvalidYieldIndex);
Fragment EvaluateAssertion();
Fragment RethrowException(TokenPosition position, int catch_try_index);
Fragment ThrowNoSuchMethodError();
diff --git a/runtime/vm/compiler/frontend/kernel_to_il.cc b/runtime/vm/compiler/frontend/kernel_to_il.cc
index ba7804d..63e8987 100644
--- a/runtime/vm/compiler/frontend/kernel_to_il.cc
+++ b/runtime/vm/compiler/frontend/kernel_to_il.cc
@@ -1722,8 +1722,7 @@
return instruction_cursor;
}
-RawArray* FlowGraphBuilder::GetOptionalParameterNames(
- const Function& function) {
+ArrayPtr FlowGraphBuilder::GetOptionalParameterNames(const Function& function) {
if (!function.HasOptionalNamedParameters()) {
return Array::null();
}
diff --git a/runtime/vm/compiler/frontend/kernel_to_il.h b/runtime/vm/compiler/frontend/kernel_to_il.h
index 0d0c930..f6f08e5 100644
--- a/runtime/vm/compiler/frontend/kernel_to_il.h
+++ b/runtime/vm/compiler/frontend/kernel_to_il.h
@@ -70,7 +70,7 @@
PrologueInfo* prologue_info);
// Return names of optional named parameters of [function].
- RawArray* GetOptionalParameterNames(const Function& function);
+ ArrayPtr GetOptionalParameterNames(const Function& function);
// Generate fragment which pushes all explicit parameters of [function].
Fragment PushExplicitParameters(
@@ -142,9 +142,10 @@
Fragment InitInstanceField(const Field& field);
Fragment InitStaticField(const Field& field);
Fragment NativeCall(const String* name, const Function* function);
- Fragment Return(TokenPosition position,
- bool omit_result_type_check = false,
- intptr_t yield_index = RawPcDescriptors::kInvalidYieldIndex);
+ Fragment Return(
+ TokenPosition position,
+ bool omit_result_type_check = false,
+ intptr_t yield_index = PcDescriptorsLayout::kInvalidYieldIndex);
void SetResultTypeForStaticCall(StaticCallInstr* call,
const Function& target,
intptr_t argument_count,
diff --git a/runtime/vm/compiler/frontend/kernel_translation_helper.cc b/runtime/vm/compiler/frontend/kernel_translation_helper.cc
index 7ab661a..ad64458 100644
--- a/runtime/vm/compiler/frontend/kernel_translation_helper.cc
+++ b/runtime/vm/compiler/frontend/kernel_translation_helper.cc
@@ -86,7 +86,7 @@
SetKernelProgramInfo(info);
}
-RawGrowableObjectArray* TranslationHelper::EnsurePotentialPragmaFunctions() {
+GrowableObjectArrayPtr TranslationHelper::EnsurePotentialPragmaFunctions() {
auto& funcs =
GrowableObjectArray::Handle(Z, info_.potential_pragma_functions());
if (funcs.IsNull()) {
@@ -104,7 +104,7 @@
potential_extension_libraries_->Add(library);
}
-RawGrowableObjectArray* TranslationHelper::GetPotentialExtensionLibraries() {
+GrowableObjectArrayPtr TranslationHelper::GetPotentialExtensionLibraries() {
if (potential_extension_libraries_ != nullptr) {
GrowableObjectArray* result = potential_extension_libraries_;
potential_extension_libraries_ = nullptr;
@@ -337,11 +337,11 @@
return enclosing;
}
-RawInstance* TranslationHelper::Canonicalize(const Instance& instance) {
+InstancePtr TranslationHelper::Canonicalize(const Instance& instance) {
if (instance.IsNull()) return instance.raw();
const char* error_str = NULL;
- RawInstance* result = instance.CheckAndCanonicalize(thread(), &error_str);
+ InstancePtr result = instance.CheckAndCanonicalize(thread(), &error_str);
if (result == Object::null()) {
ReportError("Invalid const object %s", error_str);
}
@@ -533,7 +533,7 @@
}
}
-RawLibrary* TranslationHelper::LookupLibraryByKernelLibrary(
+LibraryPtr TranslationHelper::LookupLibraryByKernelLibrary(
NameIndex kernel_library) {
// We only use the string and don't rely on having any particular parent.
// This ASSERT is just a sanity check.
@@ -541,7 +541,7 @@
IsAdministrative(CanonicalNameParent(kernel_library)));
{
name_index_handle_ = Smi::New(kernel_library);
- RawLibrary* raw_lib = info_.LookupLibrary(thread_, name_index_handle_);
+ LibraryPtr raw_lib = info_.LookupLibrary(thread_, name_index_handle_);
NoSafepointScope no_safepoint_scope(thread_);
if (raw_lib != Library::null()) {
return raw_lib;
@@ -558,11 +558,11 @@
return info_.InsertLibrary(thread_, name_index_handle_, library);
}
-RawClass* TranslationHelper::LookupClassByKernelClass(NameIndex kernel_class) {
+ClassPtr TranslationHelper::LookupClassByKernelClass(NameIndex kernel_class) {
ASSERT(IsClass(kernel_class));
{
name_index_handle_ = Smi::New(kernel_class);
- RawClass* raw_class = info_.LookupClass(thread_, name_index_handle_);
+ ClassPtr raw_class = info_.LookupClass(thread_, name_index_handle_);
NoSafepointScope no_safepoint_scope(thread_);
if (raw_class != Class::null()) {
return raw_class;
@@ -585,7 +585,7 @@
return info_.InsertClass(thread_, name_index_handle_, klass);
}
-RawField* TranslationHelper::LookupFieldByKernelField(NameIndex kernel_field) {
+FieldPtr TranslationHelper::LookupFieldByKernelField(NameIndex kernel_field) {
ASSERT(IsField(kernel_field));
NameIndex enclosing = EnclosingName(kernel_field);
@@ -606,7 +606,7 @@
return field.raw();
}
-RawFunction* TranslationHelper::LookupStaticMethodByKernelProcedure(
+FunctionPtr TranslationHelper::LookupStaticMethodByKernelProcedure(
NameIndex procedure) {
const String& procedure_name = DartProcedureName(procedure);
@@ -633,7 +633,7 @@
}
}
-RawFunction* TranslationHelper::LookupConstructorByKernelConstructor(
+FunctionPtr TranslationHelper::LookupConstructorByKernelConstructor(
NameIndex constructor) {
ASSERT(IsConstructor(constructor));
Class& klass =
@@ -642,7 +642,7 @@
return LookupConstructorByKernelConstructor(klass, constructor);
}
-RawFunction* TranslationHelper::LookupConstructorByKernelConstructor(
+FunctionPtr TranslationHelper::LookupConstructorByKernelConstructor(
const Class& owner,
NameIndex constructor) {
ASSERT(IsConstructor(constructor));
@@ -652,7 +652,7 @@
return function.raw();
}
-RawFunction* TranslationHelper::LookupConstructorByKernelConstructor(
+FunctionPtr TranslationHelper::LookupConstructorByKernelConstructor(
const Class& owner,
StringIndex constructor_name) {
GrowableHandlePtrArray<const String> pieces(Z, 3);
@@ -663,14 +663,13 @@
String& new_name =
String::ZoneHandle(Z, Symbols::FromConcatAll(thread_, pieces));
- RawFunction* function = owner.LookupConstructorAllowPrivate(new_name);
+ FunctionPtr function = owner.LookupConstructorAllowPrivate(new_name);
ASSERT(function != Object::null());
return function;
}
-RawFunction* TranslationHelper::LookupMethodByMember(
- NameIndex target,
- const String& method_name) {
+FunctionPtr TranslationHelper::LookupMethodByMember(NameIndex target,
+ const String& method_name) {
NameIndex kernel_class = EnclosingName(target);
Class& klass = Class::Handle(Z, LookupClassByKernelClass(kernel_class));
@@ -687,12 +686,12 @@
return function.raw();
}
-RawFunction* TranslationHelper::LookupDynamicFunction(const Class& klass,
- const String& name) {
+FunctionPtr TranslationHelper::LookupDynamicFunction(const Class& klass,
+ const String& name) {
// Search the superclass chain for the selector.
Class& iterate_klass = Class::Handle(Z, klass.raw());
while (!iterate_klass.IsNull()) {
- RawFunction* function =
+ FunctionPtr function =
iterate_klass.LookupDynamicFunctionAllowPrivate(name);
if (function != Object::null()) {
return function;
@@ -2726,7 +2725,7 @@
}
}
-RawTypedData* KernelReaderHelper::GetLineStartsFor(intptr_t index) {
+TypedDataPtr KernelReaderHelper::GetLineStartsFor(intptr_t index) {
// Line starts are delta encoded. So get the max delta first so that we
// can store them as tighly as possible.
AlternativeReadingScope alt(&reader_);
@@ -2885,9 +2884,11 @@
break;
case kNeverType: {
const Nullability nullability = helper_->ReadNullability();
- result_ = Object::never_type().ToNullability(nullability, Heap::kOld);
- if (apply_legacy_erasure_ && result_.IsNeverType()) {
+ if (apply_legacy_erasure_) {
result_ = I->object_store()->null_type();
+ } else {
+ result_ = Type::Handle(Z, I->object_store()->never_type())
+ .ToNullability(nullability, Heap::kOld);
}
break;
}
diff --git a/runtime/vm/compiler/frontend/kernel_translation_helper.h b/runtime/vm/compiler/frontend/kernel_translation_helper.h
index 5aa3f74..e6f25bf 100644
--- a/runtime/vm/compiler/frontend/kernel_translation_helper.h
+++ b/runtime/vm/compiler/frontend/kernel_translation_helper.h
@@ -73,10 +73,10 @@
KernelProgramInfo& info() { return info_; }
- RawGrowableObjectArray* EnsurePotentialPragmaFunctions();
+ GrowableObjectArrayPtr EnsurePotentialPragmaFunctions();
void AddPotentialExtensionLibrary(const Library& library);
- RawGrowableObjectArray* GetPotentialExtensionLibraries();
+ GrowableObjectArrayPtr GetPotentialExtensionLibraries();
void SetKernelProgramInfo(const KernelProgramInfo& info);
const KernelProgramInfo& GetKernelProgramInfo() const { return info_; }
@@ -113,7 +113,7 @@
// of the enclosing class or library.
NameIndex EnclosingName(NameIndex name);
- RawInstance* Canonicalize(const Instance& instance);
+ InstancePtr Canonicalize(const Instance& instance);
const String& DartString(const char* content) {
return DartString(content, allocation_space_);
@@ -159,20 +159,19 @@
// A subclass overrides these when reading in the Kernel program in order to
// support recursive type expressions (e.g. for "implements X" ...
// annotations).
- virtual RawLibrary* LookupLibraryByKernelLibrary(NameIndex library);
- virtual RawClass* LookupClassByKernelClass(NameIndex klass);
+ virtual LibraryPtr LookupLibraryByKernelLibrary(NameIndex library);
+ virtual ClassPtr LookupClassByKernelClass(NameIndex klass);
- RawField* LookupFieldByKernelField(NameIndex field);
- RawFunction* LookupStaticMethodByKernelProcedure(NameIndex procedure);
- RawFunction* LookupConstructorByKernelConstructor(NameIndex constructor);
- RawFunction* LookupConstructorByKernelConstructor(const Class& owner,
- NameIndex constructor);
- RawFunction* LookupConstructorByKernelConstructor(
+ FieldPtr LookupFieldByKernelField(NameIndex field);
+ FunctionPtr LookupStaticMethodByKernelProcedure(NameIndex procedure);
+ FunctionPtr LookupConstructorByKernelConstructor(NameIndex constructor);
+ FunctionPtr LookupConstructorByKernelConstructor(const Class& owner,
+ NameIndex constructor);
+ FunctionPtr LookupConstructorByKernelConstructor(
const Class& owner,
StringIndex constructor_name);
- RawFunction* LookupMethodByMember(NameIndex target,
- const String& method_name);
- RawFunction* LookupDynamicFunction(const Class& klass, const String& name);
+ FunctionPtr LookupMethodByMember(NameIndex target, const String& method_name);
+ FunctionPtr LookupDynamicFunction(const Class& klass, const String& name);
Type& GetDeclarationType(const Class& klass);
@@ -193,7 +192,7 @@
const char* format,
...) PRINTF_ATTRIBUTE(5, 6);
- RawArray* GetBytecodeComponent() const { return info_.bytecode_component(); }
+ ArrayPtr GetBytecodeComponent() const { return info_.bytecode_component(); }
void SetBytecodeComponent(const Array& bytecode_component) {
info_.set_bytecode_component(bytecode_component);
}
@@ -213,7 +212,7 @@
ASSERT(!real_class.IsNull());
expression_evaluation_real_class_ = &Class::Handle(zone_, real_class.raw());
}
- RawClass* GetExpressionEvaluationRealClass() {
+ ClassPtr GetExpressionEvaluationRealClass() {
ASSERT(expression_evaluation_real_class_ != nullptr);
return expression_evaluation_real_class_->raw();
}
@@ -1228,7 +1227,7 @@
intptr_t GetOffsetForSourceInfo(intptr_t index);
String& SourceTableUriFor(intptr_t index);
const String& GetSourceFor(intptr_t index);
- RawTypedData* GetLineStartsFor(intptr_t index);
+ TypedDataPtr GetLineStartsFor(intptr_t index);
String& SourceTableImportUriFor(intptr_t index, uint32_t binaryVersion);
Zone* zone_;
@@ -1286,12 +1285,12 @@
bool MemberIsProcedure() {
ASSERT(member != NULL);
- RawFunction::Kind function_kind = member->kind();
- return function_kind == RawFunction::kRegularFunction ||
- function_kind == RawFunction::kGetterFunction ||
- function_kind == RawFunction::kSetterFunction ||
- function_kind == RawFunction::kMethodExtractor ||
- function_kind == RawFunction::kDynamicInvocationForwarder ||
+ FunctionLayout::Kind function_kind = member->kind();
+ return function_kind == FunctionLayout::kRegularFunction ||
+ function_kind == FunctionLayout::kGetterFunction ||
+ function_kind == FunctionLayout::kSetterFunction ||
+ function_kind == FunctionLayout::kMethodExtractor ||
+ function_kind == FunctionLayout::kDynamicInvocationForwarder ||
member->IsFactory();
}
diff --git a/runtime/vm/compiler/frontend/prologue_builder.h b/runtime/vm/compiler/frontend/prologue_builder.h
index 2d2d502..cef094c 100644
--- a/runtime/vm/compiler/frontend/prologue_builder.h
+++ b/runtime/vm/compiler/frontend/prologue_builder.h
@@ -77,7 +77,7 @@
}
ASSERT(parsed_function_->function().kind() ==
- RawFunction::kNoSuchMethodDispatcher);
+ FunctionLayout::kNoSuchMethodDispatcher);
return Instance::null_instance();
}
diff --git a/runtime/vm/compiler/frontend/scope_builder.cc b/runtime/vm/compiler/frontend/scope_builder.cc
index 4663bd8..78903ef 100644
--- a/runtime/vm/compiler/frontend/scope_builder.cc
+++ b/runtime/vm/compiler/frontend/scope_builder.cc
@@ -146,12 +146,12 @@
function.kernel_offset());
switch (function.kind()) {
- case RawFunction::kClosureFunction:
- case RawFunction::kImplicitClosureFunction:
- case RawFunction::kRegularFunction:
- case RawFunction::kGetterFunction:
- case RawFunction::kSetterFunction:
- case RawFunction::kConstructor: {
+ case FunctionLayout::kClosureFunction:
+ case FunctionLayout::kImplicitClosureFunction:
+ case FunctionLayout::kRegularFunction:
+ case FunctionLayout::kGetterFunction:
+ case FunctionLayout::kSetterFunction:
+ case FunctionLayout::kConstructor: {
const Tag tag = helper_.PeekTag();
helper_.ReadUntilFunctionNode();
function_node_helper.ReadUntilExcluding(
@@ -271,8 +271,8 @@
}
break;
}
- case RawFunction::kImplicitGetter:
- case RawFunction::kImplicitSetter: {
+ case FunctionLayout::kImplicitGetter:
+ case FunctionLayout::kImplicitSetter: {
ASSERT(helper_.PeekTag() == kField);
const bool is_setter = function.IsImplicitSetterFunction();
const bool is_method = !function.IsStaticFunction();
@@ -318,7 +318,7 @@
}
break;
}
- case RawFunction::kImplicitStaticGetter: {
+ case FunctionLayout::kImplicitStaticGetter: {
ASSERT(helper_.PeekTag() == kField);
ASSERT(function.IsStaticFunction());
// In addition to static field initializers, scopes/local variables
@@ -329,7 +329,7 @@
}
break;
}
- case RawFunction::kFieldInitializer: {
+ case FunctionLayout::kFieldInitializer: {
ASSERT(helper_.PeekTag() == kField);
if (!function.is_static()) {
Class& klass = Class::Handle(Z, function.Owner());
@@ -343,7 +343,7 @@
VisitNode();
break;
}
- case RawFunction::kDynamicInvocationForwarder: {
+ case FunctionLayout::kDynamicInvocationForwarder: {
if (helper_.PeekTag() == kField) {
#ifdef DEBUG
String& name = String::Handle(Z, function.name());
@@ -384,7 +384,7 @@
}
break;
}
- case RawFunction::kMethodExtractor: {
+ case FunctionLayout::kMethodExtractor: {
// Add a receiver parameter. Though it is captured, we emit code to
// explicitly copy it to a fixed offset in a freshly-allocated context
// instead of using the generic code for regular functions.
@@ -398,9 +398,9 @@
parsed_function_->set_receiver_var(variable);
break;
}
- case RawFunction::kNoSuchMethodDispatcher:
- case RawFunction::kInvokeFieldDispatcher:
- case RawFunction::kFfiTrampoline:
+ case FunctionLayout::kNoSuchMethodDispatcher:
+ case FunctionLayout::kInvokeFieldDispatcher:
+ case FunctionLayout::kFfiTrampoline:
for (intptr_t i = 0; i < function.NumParameters(); ++i) {
LocalVariable* variable = MakeVariable(
TokenPosition::kNoSource, TokenPosition::kNoSource,
@@ -423,8 +423,8 @@
--depth_.catch_;
}
break;
- case RawFunction::kSignatureFunction:
- case RawFunction::kIrregexpFunction:
+ case FunctionLayout::kSignatureFunction:
+ case FunctionLayout::kIrregexpFunction:
UNREACHABLE();
}
if (needs_expr_temp_) {
diff --git a/runtime/vm/compiler/jit/compiler.cc b/runtime/vm/compiler/jit/compiler.cc
index c8a3bf3..1364dd0 100644
--- a/runtime/vm/compiler/jit/compiler.cc
+++ b/runtime/vm/compiler/jit/compiler.cc
@@ -323,7 +323,7 @@
osr_id_(osr_id),
thread_(Thread::Current()) {}
- RawCode* Compile(CompilationPipeline* pipeline);
+ CodePtr Compile(CompilationPipeline* pipeline);
private:
ParsedFunction* parsed_function() const { return parsed_function_; }
@@ -331,9 +331,9 @@
intptr_t osr_id() const { return osr_id_; }
Thread* thread() const { return thread_; }
Isolate* isolate() const { return thread_->isolate(); }
- RawCode* FinalizeCompilation(compiler::Assembler* assembler,
- FlowGraphCompiler* graph_compiler,
- FlowGraph* flow_graph);
+ CodePtr FinalizeCompilation(compiler::Assembler* assembler,
+ FlowGraphCompiler* graph_compiler,
+ FlowGraph* flow_graph);
void CheckIfBackgroundCompilerIsBeingStopped(bool optimizing_compiler);
ParsedFunction* parsed_function_;
@@ -344,7 +344,7 @@
DISALLOW_COPY_AND_ASSIGN(CompileParsedFunctionHelper);
};
-RawCode* CompileParsedFunctionHelper::FinalizeCompilation(
+CodePtr CompileParsedFunctionHelper::FinalizeCompilation(
compiler::Assembler* assembler,
FlowGraphCompiler* graph_compiler,
FlowGraph* flow_graph) {
@@ -502,7 +502,7 @@
// Return null if bailed out.
// If optimized_result_code is not NULL then it is caller's responsibility
// to install code.
-RawCode* CompileParsedFunctionHelper::Compile(CompilationPipeline* pipeline) {
+CodePtr CompileParsedFunctionHelper::Compile(CompilationPipeline* pipeline) {
ASSERT(!FLAG_precompiled_mode);
const Function& function = parsed_function()->function();
if (optimized() && !function.IsOptimizable()) {
@@ -712,10 +712,10 @@
return result->raw();
}
-static RawObject* CompileFunctionHelper(CompilationPipeline* pipeline,
- const Function& function,
- volatile bool optimized,
- intptr_t osr_id) {
+static ObjectPtr CompileFunctionHelper(CompilationPipeline* pipeline,
+ const Function& function,
+ volatile bool optimized,
+ intptr_t osr_id) {
ASSERT(!FLAG_precompiled_mode);
ASSERT(!optimized || function.WasCompiled() || function.ForceOptimize());
ASSERT(function.is_background_optimizable() ||
@@ -860,7 +860,7 @@
return Object::null();
}
-RawObject* Compiler::CompileFunction(Thread* thread, const Function& function) {
+ObjectPtr Compiler::CompileFunction(Thread* thread, const Function& function) {
#if defined(DART_PRECOMPILER) && !defined(TARGET_ARCH_IA32)
RELEASE_ASSERT(!FLAG_precompiled_mode);
#endif
@@ -890,8 +890,8 @@
return CompileFunctionHelper(pipeline, function, optimized, kNoOSRDeoptId);
}
-RawError* Compiler::EnsureUnoptimizedCode(Thread* thread,
- const Function& function) {
+ErrorPtr Compiler::EnsureUnoptimizedCode(Thread* thread,
+ const Function& function) {
ASSERT(!function.ForceOptimize());
if (function.unoptimized_code() != Object::null()) {
return Error::null();
@@ -922,9 +922,9 @@
return Error::null();
}
-RawObject* Compiler::CompileOptimizedFunction(Thread* thread,
- const Function& function,
- intptr_t osr_id) {
+ObjectPtr Compiler::CompileOptimizedFunction(Thread* thread,
+ const Function& function,
+ intptr_t osr_id) {
VMTagScope tagScope(thread, VMTag::kCompileOptimizedTagId);
#if defined(SUPPORT_TIMELINE)
const char* event_name;
@@ -998,7 +998,7 @@
}
}
-RawError* Compiler::CompileAllFunctions(const Class& cls) {
+ErrorPtr Compiler::CompileAllFunctions(const Class& cls) {
Thread* thread = Thread::Current();
Zone* zone = thread->zone();
Object& result = Object::Handle(zone);
@@ -1020,7 +1020,7 @@
return Error::null();
}
-RawError* Compiler::ReadAllBytecode(const Class& cls) {
+ErrorPtr Compiler::ReadAllBytecode(const Class& cls) {
Thread* thread = Thread::Current();
ASSERT(thread->IsMutatorThread());
Zone* zone = thread->zone();
@@ -1034,7 +1034,7 @@
ASSERT(!func.IsNull());
if (func.IsBytecodeAllowed(zone) && !func.HasBytecode() &&
!func.HasCode()) {
- RawError* error =
+ ErrorPtr error =
kernel::BytecodeReader::ReadFunctionBytecode(thread, func);
if (error != Error::null()) {
return error;
@@ -1075,19 +1075,17 @@
function_ = Function::null();
}
- RawFunction* Function() const { return function_; }
+ FunctionPtr Function() const { return function_; }
void set_next(QueueElement* elem) { next_ = elem; }
QueueElement* next() const { return next_; }
- RawObject* function() const { return function_; }
- RawObject** function_ptr() {
- return reinterpret_cast<RawObject**>(&function_);
- }
+ ObjectPtr function() const { return function_; }
+ ObjectPtr* function_ptr() { return reinterpret_cast<ObjectPtr*>(&function_); }
private:
QueueElement* next_;
- RawFunction* function_;
+ FunctionPtr function_;
DISALLOW_COPY_AND_ASSIGN(QueueElement);
};
@@ -1126,7 +1124,7 @@
QueueElement* Peek() const { return first_; }
- RawFunction* PeekFunction() const {
+ FunctionPtr PeekFunction() const {
QueueElement* e = Peek();
if (e == NULL) {
return Function::null();
@@ -1366,20 +1364,20 @@
return false;
}
-RawObject* Compiler::CompileFunction(Thread* thread, const Function& function) {
+ObjectPtr Compiler::CompileFunction(Thread* thread, const Function& function) {
FATAL1("Attempt to compile function %s", function.ToCString());
return Error::null();
}
-RawError* Compiler::EnsureUnoptimizedCode(Thread* thread,
- const Function& function) {
+ErrorPtr Compiler::EnsureUnoptimizedCode(Thread* thread,
+ const Function& function) {
FATAL1("Attempt to compile function %s", function.ToCString());
return Error::null();
}
-RawObject* Compiler::CompileOptimizedFunction(Thread* thread,
- const Function& function,
- intptr_t osr_id) {
+ObjectPtr Compiler::CompileOptimizedFunction(Thread* thread,
+ const Function& function,
+ intptr_t osr_id) {
FATAL1("Attempt to compile function %s", function.ToCString());
return Error::null();
}
@@ -1388,7 +1386,7 @@
UNREACHABLE();
}
-RawError* Compiler::CompileAllFunctions(const Class& cls) {
+ErrorPtr Compiler::CompileAllFunctions(const Class& cls) {
FATAL1("Attempt to compile class %s", cls.ToCString());
return Error::null();
}
diff --git a/runtime/vm/compiler/jit/compiler.h b/runtime/vm/compiler/jit/compiler.h
index b859021..29029df 100644
--- a/runtime/vm/compiler/jit/compiler.h
+++ b/runtime/vm/compiler/jit/compiler.h
@@ -24,7 +24,6 @@
class Library;
class ParsedFunction;
class QueueElement;
-class RawInstance;
class Script;
class SequenceNode;
@@ -82,13 +81,13 @@
//
// Returns the raw code object if compilation succeeds. Otherwise returns a
// RawError. Also installs the generated code on the function.
- static RawObject* CompileFunction(Thread* thread, const Function& function);
+ static ObjectPtr CompileFunction(Thread* thread, const Function& function);
// Generates unoptimized code if not present, current code is unchanged.
// Bytecode is considered unoptimized code.
// TODO(regis): Revisit when deoptimizing mixed bytecode and jitted code.
- static RawError* EnsureUnoptimizedCode(Thread* thread,
- const Function& function);
+ static ErrorPtr EnsureUnoptimizedCode(Thread* thread,
+ const Function& function);
// Generates optimized code for function.
//
@@ -96,9 +95,9 @@
// there is a compilation error. If optimization fails, but there is no
// error, returns null. Any generated code is installed unless we are in
// OSR mode.
- static RawObject* CompileOptimizedFunction(Thread* thread,
- const Function& function,
- intptr_t osr_id = kNoOSRDeoptId);
+ static ObjectPtr CompileOptimizedFunction(Thread* thread,
+ const Function& function,
+ intptr_t osr_id = kNoOSRDeoptId);
// Generates local var descriptors and sets it in 'code'. Do not call if the
// local var descriptor already exists.
@@ -107,10 +106,10 @@
// Eagerly compiles all functions in a class.
//
// Returns Error::null() if there is no compilation error.
- static RawError* CompileAllFunctions(const Class& cls);
+ static ErrorPtr CompileAllFunctions(const Class& cls);
// Eagerly read all bytecode.
- static RawError* ReadAllBytecode(const Class& cls);
+ static ErrorPtr ReadAllBytecode(const Class& cls);
// Notify the compiler that background (optimized) compilation has failed
// because the mutator thread changed the state (e.g., deoptimization,
diff --git a/runtime/vm/compiler/method_recognizer.h b/runtime/vm/compiler/method_recognizer.h
index 7a34c46..30b0443 100644
--- a/runtime/vm/compiler/method_recognizer.h
+++ b/runtime/vm/compiler/method_recognizer.h
@@ -16,8 +16,6 @@
class Function;
class Library;
class Object;
-class RawFunction;
-class RawGrowableObjectArray;
class String;
class Zone;
diff --git a/runtime/vm/compiler/offsets_extractor.cc b/runtime/vm/compiler/offsets_extractor.cc
index 5e82260..fc507f0 100644
--- a/runtime/vm/compiler/offsets_extractor.cc
+++ b/runtime/vm/compiler/offsets_extractor.cc
@@ -47,10 +47,10 @@
#define PRINT_ARRAY_LAYOUT(Class, Name) \
std::cout << "static constexpr dart::compiler::target::word AOT_" #Class \
"_elements_start_offset = " \
- << Class::ArrayLayout::elements_start_offset() << ";\n"; \
+ << Class::ArrayTraits::elements_start_offset() << ";\n"; \
std::cout << "static constexpr dart::compiler::target::word AOT_" #Class \
"_element_size = " \
- << Class::ArrayLayout::kElementSize << ";\n";
+ << Class::ArrayTraits::kElementSize << ";\n";
#define PRINT_ARRAY_STRUCTFIELD_OFFSET(Class, Name, ElementOffsetName, \
FieldOffset)
@@ -92,10 +92,10 @@
#define PRINT_ARRAY_LAYOUT(Class, Name) \
std::cout << "static constexpr dart::compiler::target::word " #Class \
"_elements_start_offset = " \
- << Class::ArrayLayout::elements_start_offset() << ";\n"; \
+ << Class::ArrayTraits::elements_start_offset() << ";\n"; \
std::cout << "static constexpr dart::compiler::target::word " #Class \
"_element_size = " \
- << Class::ArrayLayout::kElementSize << ";\n";
+ << Class::ArrayTraits::kElementSize << ";\n";
#define PRINT_ARRAY_STRUCTFIELD_OFFSET(Class, Name, ElementOffsetName, \
FieldOffset)
diff --git a/runtime/vm/compiler/relocation.cc b/runtime/vm/compiler/relocation.cc
index e72a3b1..c32196be 100644
--- a/runtime/vm/compiler/relocation.cc
+++ b/runtime/vm/compiler/relocation.cc
@@ -28,7 +28,7 @@
kObjectAlignment);
CodeRelocator::CodeRelocator(Thread* thread,
- GrowableArray<RawCode*>* code_objects,
+ GrowableArray<CodePtr>* code_objects,
GrowableArray<ImageWriterCommand>* commands)
: StackResource(thread),
thread_(thread),
@@ -175,8 +175,8 @@
}
}
-bool CodeRelocator::AddInstructionsToText(RawCode* code) {
- RawInstructions* instructions = Code::InstructionsOf(code);
+bool CodeRelocator::AddInstructionsToText(CodePtr code) {
+ InstructionsPtr instructions = Code::InstructionsOf(code);
// If two [Code] objects point to the same [Instructions] object, we'll just
// use the first one (they are equivalent for all practical purposes).
@@ -220,7 +220,7 @@
return nullptr;
}
-void CodeRelocator::AddTrampolineToText(RawInstructions* destination,
+void CodeRelocator::AddTrampolineToText(InstructionsPtr destination,
uint8_t* trampoline_bytes,
intptr_t trampoline_length) {
commands_->Add(ImageWriterCommand(next_text_offset_, trampoline_bytes,
@@ -296,7 +296,7 @@
all_unresolved_calls_.Append(unresolved_call);
// Add it to callers of destination.
- RawInstructions* destination = Code::InstructionsOf(unresolved_call->callee);
+ InstructionsPtr destination = Code::InstructionsOf(unresolved_call->callee);
if (!unresolved_calls_by_destination_.HasKey(destination)) {
unresolved_calls_by_destination_.Insert(
{destination, new SameDestinationUnresolvedCallsList()});
@@ -330,7 +330,7 @@
}
void CodeRelocator::ResolveUnresolvedCallsTargeting(
- const RawInstructions* instructions) {
+ const InstructionsPtr instructions) {
if (unresolved_calls_by_destination_.HasKey(instructions)) {
SameDestinationUnresolvedCallsList* calls =
unresolved_calls_by_destination_.LookupValue(instructions);
@@ -422,7 +422,7 @@
}
}
-RawCode* CodeRelocator::GetTarget(const StaticCallsTableEntry& call) {
+CodePtr CodeRelocator::GetTarget(const StaticCallsTableEntry& call) {
// The precompiler should have already replaced all function entries
// with code entries.
ASSERT(call.Get<Code::kSCallTableFunctionTarget>() == Function::null());
@@ -472,15 +472,15 @@
uint32_t tags = 0;
#if defined(IS_SIMARM_X64)
// Account for difference in kObjectAlignment between host and target.
- tags = RawObject::SizeTag::update(trampoline_length * 2, tags);
+ tags = ObjectLayout::SizeTag::update(trampoline_length * 2, tags);
#else
- tags = RawObject::SizeTag::update(trampoline_length, tags);
+ tags = ObjectLayout::SizeTag::update(trampoline_length, tags);
#endif
- tags = RawObject::ClassIdTag::update(kFreeListElement, tags);
- tags = RawObject::OldBit::update(true, tags);
- tags = RawObject::OldAndNotMarkedBit::update(true, tags);
- tags = RawObject::OldAndNotRememberedBit::update(true, tags);
- tags = RawObject::NewBit::update(false, tags);
+ tags = ObjectLayout::ClassIdTag::update(kFreeListElement, tags);
+ tags = ObjectLayout::OldBit::update(true, tags);
+ tags = ObjectLayout::OldAndNotMarkedBit::update(true, tags);
+ tags = ObjectLayout::OldAndNotRememberedBit::update(true, tags);
+ tags = ObjectLayout::NewBit::update(false, tags);
auto header_word = reinterpret_cast<uintptr_t*>(trampoline_bytes);
*header_word = tags;
@@ -563,9 +563,8 @@
}
}
-intptr_t CodeRelocator::FindDestinationInText(
- const RawInstructions* destination,
- intptr_t offset_into_target) {
+intptr_t CodeRelocator::FindDestinationInText(const InstructionsPtr destination,
+ intptr_t offset_into_target) {
auto const destination_offset = text_offsets_.LookupValue(destination);
return destination_offset + AdjustPayloadOffset(offset_into_target);
}
diff --git a/runtime/vm/compiler/relocation.h b/runtime/vm/compiler/relocation.h
index 7094c94..e9b6d44 100644
--- a/runtime/vm/compiler/relocation.h
+++ b/runtime/vm/compiler/relocation.h
@@ -25,10 +25,10 @@
class UnresolvedCall : public IntrusiveDListEntry<UnresolvedCall>,
public IntrusiveDListEntry<UnresolvedCall, 2> {
public:
- UnresolvedCall(RawCode* caller,
+ UnresolvedCall(CodePtr caller,
intptr_t call_offset,
intptr_t text_offset,
- RawCode* callee,
+ CodePtr callee,
intptr_t offset_into_target,
bool is_tail_call)
: caller(caller),
@@ -50,13 +50,13 @@
// The caller which has an unresolved call (will be null'ed out when
// resolved).
- RawCode* caller;
+ CodePtr caller;
// The offset from the payload of the calling code which performs the call.
const intptr_t call_offset;
// The offset in the .text segment where the call happens.
const intptr_t text_offset;
// The target of the forward call (will be null'ed out when resolved).
- RawCode* callee;
+ CodePtr callee;
// The extra offset into the target.
const intptr_t offset_into_target;
// Whether this is a tail call.
@@ -78,7 +78,7 @@
// instead (which will tail-call the destination).
class UnresolvedTrampoline : public IntrusiveDListEntry<UnresolvedTrampoline> {
public:
- UnresolvedTrampoline(RawCode* callee,
+ UnresolvedTrampoline(CodePtr callee,
intptr_t offset_into_target,
uint8_t* trampoline_bytes,
intptr_t text_offset)
@@ -88,7 +88,7 @@
text_offset(text_offset) {}
// The target of the forward call.
- RawCode* callee;
+ CodePtr callee;
// The extra offset into the target.
intptr_t offset_into_target;
@@ -104,21 +104,21 @@
class InstructionsMapTraits {
public:
struct Pair {
- RawInstructions* instructions;
+ InstructionsPtr instructions;
ValueType value;
Pair() : instructions(nullptr), value(kNoValue) {}
- Pair(RawInstructions* i, const ValueType& value)
+ Pair(InstructionsPtr i, const ValueType& value)
: instructions(i), value(value) {}
};
- typedef const RawInstructions* Key;
+ typedef const InstructionsPtr Key;
typedef const ValueType Value;
static Key KeyOf(Pair kv) { return kv.instructions; }
static ValueType ValueOf(Pair kv) { return kv.value; }
static inline intptr_t Hashcode(Key key) {
- return reinterpret_cast<intptr_t>(key);
+ return static_cast<intptr_t>(key);
}
static inline bool IsKeyEqual(Pair pair, Key key) {
return pair.instructions == key;
@@ -147,7 +147,7 @@
// Populates the image writer command array which must be used later to write
// the ".text" segment.
static void Relocate(Thread* thread,
- GrowableArray<RawCode*>* code_objects,
+ GrowableArray<CodePtr>* code_objects,
GrowableArray<ImageWriterCommand>* commands,
bool is_vm_isolate) {
CodeRelocator relocator(thread, code_objects, commands);
@@ -156,20 +156,20 @@
private:
CodeRelocator(Thread* thread,
- GrowableArray<RawCode*>* code_objects,
+ GrowableArray<CodePtr>* code_objects,
GrowableArray<ImageWriterCommand>* commands);
void Relocate(bool is_vm_isolate);
void FindInstructionAndCallLimits();
- bool AddInstructionsToText(RawCode* code);
+ bool AddInstructionsToText(CodePtr code);
void ScanCallTargets(const Code& code,
const Array& call_targets,
intptr_t code_text_offset);
UnresolvedTrampoline* FindTrampolineFor(UnresolvedCall* unresolved_call);
- void AddTrampolineToText(RawInstructions* destination,
+ void AddTrampolineToText(InstructionsPtr destination,
uint8_t* trampoline_bytes,
intptr_t trampoline_length);
@@ -177,7 +177,7 @@
void EnqueueUnresolvedTrampoline(UnresolvedTrampoline* unresolved_trampoline);
bool TryResolveBackwardsCall(UnresolvedCall* unresolved_call);
- void ResolveUnresolvedCallsTargeting(const RawInstructions* instructions);
+ void ResolveUnresolvedCallsTargeting(const InstructionsPtr instructions);
void ResolveCall(UnresolvedCall* unresolved_call);
void ResolveCallToDestination(UnresolvedCall* unresolved_call,
intptr_t destination_text);
@@ -185,7 +185,7 @@
void BuildTrampolinesForAlmostOutOfRangeCalls();
- intptr_t FindDestinationInText(const RawInstructions* destination,
+ intptr_t FindDestinationInText(const InstructionsPtr destination,
intptr_t offset_into_target);
static intptr_t AdjustPayloadOffset(intptr_t payload_offset);
@@ -193,14 +193,14 @@
bool IsTargetInRangeFor(UnresolvedCall* unresolved_call,
intptr_t target_text_offset);
- RawCode* GetTarget(const StaticCallsTableEntry& entry);
+ CodePtr GetTarget(const StaticCallsTableEntry& entry);
// The code relocation happens during AOT snapshot writing and operates on raw
// objects. No allocations can be done.
NoSafepointScope no_savepoint_scope_;
Thread* thread_;
- const GrowableArray<RawCode*>* code_objects_;
+ const GrowableArray<CodePtr>* code_objects_;
GrowableArray<ImageWriterCommand>* commands_;
// The size of largest instructions object in bytes.
diff --git a/runtime/vm/compiler/runtime_api.cc b/runtime/vm/compiler/runtime_api.cc
index 3dd8271..45f0cf8 100644
--- a/runtime/vm/compiler/runtime_api.cc
+++ b/runtime/vm/compiler/runtime_api.cc
@@ -267,49 +267,50 @@
}
bool SizeFitsInSizeTag(uword instance_size) {
- return dart::RawObject::SizeTag::SizeFits(
+ return dart::ObjectLayout::SizeTag::SizeFits(
TranslateOffsetInWordsToHost(instance_size));
}
uint32_t MakeTagWordForNewSpaceObject(classid_t cid, uword instance_size) {
- return dart::RawObject::SizeTag::encode(
+ return dart::ObjectLayout::SizeTag::encode(
TranslateOffsetInWordsToHost(instance_size)) |
- dart::RawObject::ClassIdTag::encode(cid) |
- dart::RawObject::NewBit::encode(true);
+ dart::ObjectLayout::ClassIdTag::encode(cid) |
+ dart::ObjectLayout::NewBit::encode(true);
}
word Object::tags_offset() {
return 0;
}
-const word RawObject::kCardRememberedBit = dart::RawObject::kCardRememberedBit;
+const word ObjectLayout::kCardRememberedBit =
+ dart::ObjectLayout::kCardRememberedBit;
-const word RawObject::kOldAndNotRememberedBit =
- dart::RawObject::kOldAndNotRememberedBit;
+const word ObjectLayout::kOldAndNotRememberedBit =
+ dart::ObjectLayout::kOldAndNotRememberedBit;
-const word RawObject::kOldAndNotMarkedBit =
- dart::RawObject::kOldAndNotMarkedBit;
+const word ObjectLayout::kOldAndNotMarkedBit =
+ dart::ObjectLayout::kOldAndNotMarkedBit;
-const word RawObject::kSizeTagPos = dart::RawObject::kSizeTagPos;
+const word ObjectLayout::kSizeTagPos = dart::ObjectLayout::kSizeTagPos;
-const word RawObject::kSizeTagSize = dart::RawObject::kSizeTagSize;
+const word ObjectLayout::kSizeTagSize = dart::ObjectLayout::kSizeTagSize;
-const word RawObject::kClassIdTagPos = dart::RawObject::kClassIdTagPos;
+const word ObjectLayout::kClassIdTagPos = dart::ObjectLayout::kClassIdTagPos;
-const word RawObject::kClassIdTagSize = dart::RawObject::kClassIdTagSize;
+const word ObjectLayout::kClassIdTagSize = dart::ObjectLayout::kClassIdTagSize;
-const word RawObject::kSizeTagMaxSizeTag =
- dart::RawObject::SizeTag::kMaxSizeTagInUnitsOfAlignment *
+const word ObjectLayout::kSizeTagMaxSizeTag =
+ dart::ObjectLayout::SizeTag::kMaxSizeTagInUnitsOfAlignment *
ObjectAlignment::kObjectAlignment;
-const word RawObject::kTagBitsSizeTagPos =
- dart::RawObject::TagBits::kSizeTagPos;
+const word ObjectLayout::kTagBitsSizeTagPos =
+ dart::ObjectLayout::TagBits::kSizeTagPos;
-const word RawAbstractType::kTypeStateFinalizedInstantiated =
- dart::RawAbstractType::kFinalizedInstantiated;
+const word AbstractTypeLayout::kTypeStateFinalizedInstantiated =
+ dart::AbstractTypeLayout::kFinalizedInstantiated;
-const word RawObject::kBarrierOverlapShift =
- dart::RawObject::kBarrierOverlapShift;
+const word ObjectLayout::kBarrierOverlapShift =
+ dart::ObjectLayout::kBarrierOverlapShift;
bool IsTypedDataClassId(intptr_t cid) {
return dart::IsTypedDataClassId(cid);
@@ -617,7 +618,7 @@
word ToRawSmi(const dart::Object& a) {
RELEASE_ASSERT(IsSmi(a));
- return static_cast<word>(reinterpret_cast<intptr_t>(a.raw()));
+ return static_cast<word>(static_cast<intptr_t>(a.raw()));
}
word ToRawSmi(intptr_t value) {
@@ -645,7 +646,7 @@
static_assert(kHostWordSize == kWordSize,
"Can't embed raw pointers to runtime objects when host and "
"target word sizes are different");
- return reinterpret_cast<word>(a.raw());
+ return static_cast<word>(a.raw());
}
#endif // defined(TARGET_ARCH_IA32)
diff --git a/runtime/vm/compiler/runtime_api.h b/runtime/vm/compiler/runtime_api.h
index d3c21b9..5c6fcaf 100644
--- a/runtime/vm/compiler/runtime_api.h
+++ b/runtime/vm/compiler/runtime_api.h
@@ -40,7 +40,7 @@
class Zone;
#define DO(clazz) \
- class Raw##clazz; \
+ class clazz##Layout; \
class clazz;
CLASS_LIST_FOR_HANDLES(DO)
#undef DO
@@ -372,7 +372,7 @@
// Currently we use the same names for classes, constants and getters to make
// migration easier.
-class RawObject : public AllStatic {
+class ObjectLayout : public AllStatic {
public:
static const word kCardRememberedBit;
static const word kOldAndNotRememberedBit;
@@ -388,7 +388,7 @@
static bool IsTypedDataClassId(intptr_t cid);
};
-class RawAbstractType : public AllStatic {
+class AbstractTypeLayout : public AllStatic {
public:
static const word kTypeStateFinalizedInstantiated;
};
@@ -418,7 +418,7 @@
static word super_type_offset();
- // The offset of the RawObject::num_type_arguments_ field in bytes.
+ // The offset of the ObjectLayout::num_type_arguments_ field in bytes.
static word num_type_arguments_offset();
// The value used if no type arguments vector is present.
diff --git a/runtime/vm/compiler/runtime_offsets_extracted.h b/runtime/vm/compiler/runtime_offsets_extracted.h
index 7288034..67b096c 100644
--- a/runtime/vm/compiler/runtime_offsets_extracted.h
+++ b/runtime/vm/compiler/runtime_offsets_extracted.h
@@ -169,10 +169,10 @@
12;
static constexpr dart::compiler::target::word NativeArguments_thread_offset = 0;
static constexpr dart::compiler::target::word ObjectStore_double_type_offset =
- 120;
-static constexpr dart::compiler::target::word ObjectStore_int_type_offset = 60;
+ 128;
+static constexpr dart::compiler::target::word ObjectStore_int_type_offset = 68;
static constexpr dart::compiler::target::word ObjectStore_string_type_offset =
- 148;
+ 156;
static constexpr dart::compiler::target::word OneByteString_data_offset = 12;
static constexpr dart::compiler::target::word PointerBase_data_field_offset = 4;
static constexpr dart::compiler::target::word Pointer_type_arguments_offset = 8;
@@ -646,10 +646,10 @@
24;
static constexpr dart::compiler::target::word NativeArguments_thread_offset = 0;
static constexpr dart::compiler::target::word ObjectStore_double_type_offset =
- 240;
-static constexpr dart::compiler::target::word ObjectStore_int_type_offset = 120;
+ 256;
+static constexpr dart::compiler::target::word ObjectStore_int_type_offset = 136;
static constexpr dart::compiler::target::word ObjectStore_string_type_offset =
- 296;
+ 312;
static constexpr dart::compiler::target::word OneByteString_data_offset = 16;
static constexpr dart::compiler::target::word PointerBase_data_field_offset = 8;
static constexpr dart::compiler::target::word Pointer_type_arguments_offset =
@@ -1126,10 +1126,10 @@
12;
static constexpr dart::compiler::target::word NativeArguments_thread_offset = 0;
static constexpr dart::compiler::target::word ObjectStore_double_type_offset =
- 120;
-static constexpr dart::compiler::target::word ObjectStore_int_type_offset = 60;
+ 128;
+static constexpr dart::compiler::target::word ObjectStore_int_type_offset = 68;
static constexpr dart::compiler::target::word ObjectStore_string_type_offset =
- 148;
+ 156;
static constexpr dart::compiler::target::word OneByteString_data_offset = 12;
static constexpr dart::compiler::target::word PointerBase_data_field_offset = 4;
static constexpr dart::compiler::target::word Pointer_type_arguments_offset = 8;
@@ -1600,10 +1600,10 @@
24;
static constexpr dart::compiler::target::word NativeArguments_thread_offset = 0;
static constexpr dart::compiler::target::word ObjectStore_double_type_offset =
- 240;
-static constexpr dart::compiler::target::word ObjectStore_int_type_offset = 120;
+ 256;
+static constexpr dart::compiler::target::word ObjectStore_int_type_offset = 136;
static constexpr dart::compiler::target::word ObjectStore_string_type_offset =
- 296;
+ 312;
static constexpr dart::compiler::target::word OneByteString_data_offset = 16;
static constexpr dart::compiler::target::word PointerBase_data_field_offset = 8;
static constexpr dart::compiler::target::word Pointer_type_arguments_offset =
@@ -2080,10 +2080,10 @@
12;
static constexpr dart::compiler::target::word NativeArguments_thread_offset = 0;
static constexpr dart::compiler::target::word ObjectStore_double_type_offset =
- 120;
-static constexpr dart::compiler::target::word ObjectStore_int_type_offset = 60;
+ 128;
+static constexpr dart::compiler::target::word ObjectStore_int_type_offset = 68;
static constexpr dart::compiler::target::word ObjectStore_string_type_offset =
- 148;
+ 156;
static constexpr dart::compiler::target::word OneByteString_data_offset = 12;
static constexpr dart::compiler::target::word PointerBase_data_field_offset = 4;
static constexpr dart::compiler::target::word Pointer_type_arguments_offset = 8;
@@ -2551,10 +2551,10 @@
24;
static constexpr dart::compiler::target::word NativeArguments_thread_offset = 0;
static constexpr dart::compiler::target::word ObjectStore_double_type_offset =
- 240;
-static constexpr dart::compiler::target::word ObjectStore_int_type_offset = 120;
+ 256;
+static constexpr dart::compiler::target::word ObjectStore_int_type_offset = 136;
static constexpr dart::compiler::target::word ObjectStore_string_type_offset =
- 296;
+ 312;
static constexpr dart::compiler::target::word OneByteString_data_offset = 16;
static constexpr dart::compiler::target::word PointerBase_data_field_offset = 8;
static constexpr dart::compiler::target::word Pointer_type_arguments_offset =
@@ -3025,10 +3025,10 @@
12;
static constexpr dart::compiler::target::word NativeArguments_thread_offset = 0;
static constexpr dart::compiler::target::word ObjectStore_double_type_offset =
- 120;
-static constexpr dart::compiler::target::word ObjectStore_int_type_offset = 60;
+ 128;
+static constexpr dart::compiler::target::word ObjectStore_int_type_offset = 68;
static constexpr dart::compiler::target::word ObjectStore_string_type_offset =
- 148;
+ 156;
static constexpr dart::compiler::target::word OneByteString_data_offset = 12;
static constexpr dart::compiler::target::word PointerBase_data_field_offset = 4;
static constexpr dart::compiler::target::word Pointer_type_arguments_offset = 8;
@@ -3493,10 +3493,10 @@
24;
static constexpr dart::compiler::target::word NativeArguments_thread_offset = 0;
static constexpr dart::compiler::target::word ObjectStore_double_type_offset =
- 240;
-static constexpr dart::compiler::target::word ObjectStore_int_type_offset = 120;
+ 256;
+static constexpr dart::compiler::target::word ObjectStore_int_type_offset = 136;
static constexpr dart::compiler::target::word ObjectStore_string_type_offset =
- 296;
+ 312;
static constexpr dart::compiler::target::word OneByteString_data_offset = 16;
static constexpr dart::compiler::target::word PointerBase_data_field_offset = 8;
static constexpr dart::compiler::target::word Pointer_type_arguments_offset =
@@ -3979,11 +3979,11 @@
static constexpr dart::compiler::target::word
AOT_NativeArguments_thread_offset = 0;
static constexpr dart::compiler::target::word
- AOT_ObjectStore_double_type_offset = 120;
+ AOT_ObjectStore_double_type_offset = 128;
static constexpr dart::compiler::target::word AOT_ObjectStore_int_type_offset =
- 60;
+ 68;
static constexpr dart::compiler::target::word
- AOT_ObjectStore_string_type_offset = 148;
+ AOT_ObjectStore_string_type_offset = 156;
static constexpr dart::compiler::target::word AOT_OneByteString_data_offset =
12;
static constexpr dart::compiler::target::word
@@ -4498,11 +4498,11 @@
static constexpr dart::compiler::target::word
AOT_NativeArguments_thread_offset = 0;
static constexpr dart::compiler::target::word
- AOT_ObjectStore_double_type_offset = 240;
+ AOT_ObjectStore_double_type_offset = 256;
static constexpr dart::compiler::target::word AOT_ObjectStore_int_type_offset =
- 120;
+ 136;
static constexpr dart::compiler::target::word
- AOT_ObjectStore_string_type_offset = 296;
+ AOT_ObjectStore_string_type_offset = 312;
static constexpr dart::compiler::target::word AOT_OneByteString_data_offset =
16;
static constexpr dart::compiler::target::word
@@ -5023,11 +5023,11 @@
static constexpr dart::compiler::target::word
AOT_NativeArguments_thread_offset = 0;
static constexpr dart::compiler::target::word
- AOT_ObjectStore_double_type_offset = 240;
+ AOT_ObjectStore_double_type_offset = 256;
static constexpr dart::compiler::target::word AOT_ObjectStore_int_type_offset =
- 120;
+ 136;
static constexpr dart::compiler::target::word
- AOT_ObjectStore_string_type_offset = 296;
+ AOT_ObjectStore_string_type_offset = 312;
static constexpr dart::compiler::target::word AOT_OneByteString_data_offset =
16;
static constexpr dart::compiler::target::word
@@ -5544,11 +5544,11 @@
static constexpr dart::compiler::target::word
AOT_NativeArguments_thread_offset = 0;
static constexpr dart::compiler::target::word
- AOT_ObjectStore_double_type_offset = 120;
+ AOT_ObjectStore_double_type_offset = 128;
static constexpr dart::compiler::target::word AOT_ObjectStore_int_type_offset =
- 60;
+ 68;
static constexpr dart::compiler::target::word
- AOT_ObjectStore_string_type_offset = 148;
+ AOT_ObjectStore_string_type_offset = 156;
static constexpr dart::compiler::target::word AOT_OneByteString_data_offset =
12;
static constexpr dart::compiler::target::word
@@ -6056,11 +6056,11 @@
static constexpr dart::compiler::target::word
AOT_NativeArguments_thread_offset = 0;
static constexpr dart::compiler::target::word
- AOT_ObjectStore_double_type_offset = 240;
+ AOT_ObjectStore_double_type_offset = 256;
static constexpr dart::compiler::target::word AOT_ObjectStore_int_type_offset =
- 120;
+ 136;
static constexpr dart::compiler::target::word
- AOT_ObjectStore_string_type_offset = 296;
+ AOT_ObjectStore_string_type_offset = 312;
static constexpr dart::compiler::target::word AOT_OneByteString_data_offset =
16;
static constexpr dart::compiler::target::word
@@ -6574,11 +6574,11 @@
static constexpr dart::compiler::target::word
AOT_NativeArguments_thread_offset = 0;
static constexpr dart::compiler::target::word
- AOT_ObjectStore_double_type_offset = 240;
+ AOT_ObjectStore_double_type_offset = 256;
static constexpr dart::compiler::target::word AOT_ObjectStore_int_type_offset =
- 120;
+ 136;
static constexpr dart::compiler::target::word
- AOT_ObjectStore_string_type_offset = 296;
+ AOT_ObjectStore_string_type_offset = 312;
static constexpr dart::compiler::target::word AOT_OneByteString_data_offset =
16;
static constexpr dart::compiler::target::word
diff --git a/runtime/vm/compiler/runtime_offsets_list.h b/runtime/vm/compiler/runtime_offsets_list.h
index 007a84a..5c9b5e4 100644
--- a/runtime/vm/compiler/runtime_offsets_list.h
+++ b/runtime/vm/compiler/runtime_offsets_list.h
@@ -260,89 +260,89 @@
kNumberOfCpuRegisters - 1, \
[](Register reg) { return (kDartAvailableCpuRegs & (1 << reg)) != 0; })) \
\
- SIZEOF(ApiError, InstanceSize, RawApiError) \
- SIZEOF(Array, InstanceSize, RawArray) \
- SIZEOF(Array, header_size, RawArray) \
- SIZEOF(Bool, InstanceSize, RawBool) \
- SIZEOF(Bytecode, InstanceSize, RawBytecode) \
- SIZEOF(Capability, InstanceSize, RawCapability) \
- SIZEOF(Class, InstanceSize, RawClass) \
- SIZEOF(Closure, InstanceSize, RawClosure) \
- SIZEOF(ClosureData, InstanceSize, RawClosureData) \
- SIZEOF(Code, InstanceSize, RawCode) \
- SIZEOF(CodeSourceMap, InstanceSize, RawCodeSourceMap) \
- SIZEOF(CompressedStackMaps, InstanceSize, RawCompressedStackMaps) \
- SIZEOF(CompressedStackMaps, HeaderSize, RawCompressedStackMaps) \
- SIZEOF(Context, InstanceSize, RawContext) \
- SIZEOF(Context, header_size, RawContext) \
- SIZEOF(ContextScope, InstanceSize, RawContextScope) \
- SIZEOF(Double, InstanceSize, RawDouble) \
- SIZEOF(DynamicLibrary, InstanceSize, RawDynamicLibrary) \
- SIZEOF(ExceptionHandlers, InstanceSize, RawExceptionHandlers) \
- SIZEOF(ExternalOneByteString, InstanceSize, RawExternalOneByteString) \
- SIZEOF(ExternalTwoByteString, InstanceSize, RawExternalTwoByteString) \
- SIZEOF(ExternalTypedData, InstanceSize, RawExternalTypedData) \
- SIZEOF(FfiTrampolineData, InstanceSize, RawFfiTrampolineData) \
- SIZEOF(Field, InstanceSize, RawField) \
- SIZEOF(Float32x4, InstanceSize, RawFloat32x4) \
- SIZEOF(Float64x2, InstanceSize, RawFloat64x2) \
- SIZEOF(Function, InstanceSize, RawFunction) \
- SIZEOF(FutureOr, InstanceSize, RawFutureOr) \
- SIZEOF(GrowableObjectArray, InstanceSize, RawGrowableObjectArray) \
- SIZEOF(ICData, InstanceSize, RawICData) \
- SIZEOF(Instance, InstanceSize, RawInstance) \
- SIZEOF(Instructions, InstanceSize, RawInstructions) \
- SIZEOF(Instructions, UnalignedHeaderSize, RawInstructions) \
- SIZEOF(InstructionsSection, InstanceSize, RawInstructionsSection) \
- SIZEOF(InstructionsSection, UnalignedHeaderSize, RawInstructionsSection) \
- SIZEOF(Int32x4, InstanceSize, RawInt32x4) \
- SIZEOF(Integer, InstanceSize, RawInteger) \
- SIZEOF(KernelProgramInfo, InstanceSize, RawKernelProgramInfo) \
- SIZEOF(LanguageError, InstanceSize, RawLanguageError) \
- SIZEOF(Library, InstanceSize, RawLibrary) \
- SIZEOF(LibraryPrefix, InstanceSize, RawLibraryPrefix) \
- SIZEOF(LinkedHashMap, InstanceSize, RawLinkedHashMap) \
- SIZEOF(LocalVarDescriptors, InstanceSize, RawLocalVarDescriptors) \
- SIZEOF(MegamorphicCache, InstanceSize, RawMegamorphicCache) \
- SIZEOF(Mint, InstanceSize, RawMint) \
- SIZEOF(MirrorReference, InstanceSize, RawMirrorReference) \
- SIZEOF(MonomorphicSmiableCall, InstanceSize, RawMonomorphicSmiableCall) \
- SIZEOF(Namespace, InstanceSize, RawNamespace) \
+ SIZEOF(ApiError, InstanceSize, ApiErrorLayout) \
+ SIZEOF(Array, InstanceSize, ArrayLayout) \
+ SIZEOF(Array, header_size, ArrayLayout) \
+ SIZEOF(Bool, InstanceSize, BoolLayout) \
+ SIZEOF(Bytecode, InstanceSize, BytecodeLayout) \
+ SIZEOF(Capability, InstanceSize, CapabilityLayout) \
+ SIZEOF(Class, InstanceSize, ClassLayout) \
+ SIZEOF(Closure, InstanceSize, ClosureLayout) \
+ SIZEOF(ClosureData, InstanceSize, ClosureDataLayout) \
+ SIZEOF(Code, InstanceSize, CodeLayout) \
+ SIZEOF(CodeSourceMap, InstanceSize, CodeSourceMapLayout) \
+ SIZEOF(CompressedStackMaps, InstanceSize, CompressedStackMapsLayout) \
+ SIZEOF(CompressedStackMaps, HeaderSize, CompressedStackMapsLayout) \
+ SIZEOF(Context, InstanceSize, ContextLayout) \
+ SIZEOF(Context, header_size, ContextLayout) \
+ SIZEOF(ContextScope, InstanceSize, ContextScopeLayout) \
+ SIZEOF(Double, InstanceSize, DoubleLayout) \
+ SIZEOF(DynamicLibrary, InstanceSize, DynamicLibraryLayout) \
+ SIZEOF(ExceptionHandlers, InstanceSize, ExceptionHandlersLayout) \
+ SIZEOF(ExternalOneByteString, InstanceSize, ExternalOneByteStringLayout) \
+ SIZEOF(ExternalTwoByteString, InstanceSize, ExternalTwoByteStringLayout) \
+ SIZEOF(ExternalTypedData, InstanceSize, ExternalTypedDataLayout) \
+ SIZEOF(FfiTrampolineData, InstanceSize, FfiTrampolineDataLayout) \
+ SIZEOF(Field, InstanceSize, FieldLayout) \
+ SIZEOF(Float32x4, InstanceSize, Float32x4Layout) \
+ SIZEOF(Float64x2, InstanceSize, Float64x2Layout) \
+ SIZEOF(Function, InstanceSize, FunctionLayout) \
+ SIZEOF(FutureOr, InstanceSize, FutureOrLayout) \
+ SIZEOF(GrowableObjectArray, InstanceSize, GrowableObjectArrayLayout) \
+ SIZEOF(ICData, InstanceSize, ICDataLayout) \
+ SIZEOF(Instance, InstanceSize, InstanceLayout) \
+ SIZEOF(Instructions, InstanceSize, InstructionsLayout) \
+ SIZEOF(Instructions, UnalignedHeaderSize, InstructionsLayout) \
+ SIZEOF(InstructionsSection, InstanceSize, InstructionsSectionLayout) \
+ SIZEOF(InstructionsSection, UnalignedHeaderSize, InstructionsSectionLayout) \
+ SIZEOF(Int32x4, InstanceSize, Int32x4Layout) \
+ SIZEOF(Integer, InstanceSize, IntegerLayout) \
+ SIZEOF(KernelProgramInfo, InstanceSize, KernelProgramInfoLayout) \
+ SIZEOF(LanguageError, InstanceSize, LanguageErrorLayout) \
+ SIZEOF(Library, InstanceSize, LibraryLayout) \
+ SIZEOF(LibraryPrefix, InstanceSize, LibraryPrefixLayout) \
+ SIZEOF(LinkedHashMap, InstanceSize, LinkedHashMapLayout) \
+ SIZEOF(LocalVarDescriptors, InstanceSize, LocalVarDescriptorsLayout) \
+ SIZEOF(MegamorphicCache, InstanceSize, MegamorphicCacheLayout) \
+ SIZEOF(Mint, InstanceSize, MintLayout) \
+ SIZEOF(MirrorReference, InstanceSize, MirrorReferenceLayout) \
+ SIZEOF(MonomorphicSmiableCall, InstanceSize, MonomorphicSmiableCallLayout) \
+ SIZEOF(Namespace, InstanceSize, NamespaceLayout) \
SIZEOF(NativeArguments, StructSize, NativeArguments) \
- SIZEOF(Number, InstanceSize, RawNumber) \
- SIZEOF(Object, InstanceSize, RawObject) \
- SIZEOF(ObjectPool, InstanceSize, RawObjectPool) \
- SIZEOF(OneByteString, InstanceSize, RawOneByteString) \
- SIZEOF(ParameterTypeCheck, InstanceSize, RawParameterTypeCheck) \
- SIZEOF(PatchClass, InstanceSize, RawPatchClass) \
- SIZEOF(PcDescriptors, InstanceSize, RawPcDescriptors) \
- SIZEOF(Pointer, InstanceSize, RawPointer) \
- SIZEOF(ReceivePort, InstanceSize, RawReceivePort) \
- SIZEOF(RedirectionData, InstanceSize, RawRedirectionData) \
- SIZEOF(RegExp, InstanceSize, RawRegExp) \
- SIZEOF(Script, InstanceSize, RawScript) \
- SIZEOF(SendPort, InstanceSize, RawSendPort) \
- SIZEOF(SignatureData, InstanceSize, RawSignatureData) \
- SIZEOF(SingleTargetCache, InstanceSize, RawSingleTargetCache) \
- SIZEOF(Smi, InstanceSize, RawSmi) \
- SIZEOF(StackTrace, InstanceSize, RawStackTrace) \
- SIZEOF(String, InstanceSize, RawString) \
- SIZEOF(SubtypeTestCache, InstanceSize, RawSubtypeTestCache) \
- SIZEOF(TransferableTypedData, InstanceSize, RawTransferableTypedData) \
- SIZEOF(TwoByteString, InstanceSize, RawTwoByteString) \
- SIZEOF(Type, InstanceSize, RawType) \
- SIZEOF(TypeArguments, InstanceSize, RawTypeArguments) \
- SIZEOF(TypeParameter, InstanceSize, RawTypeParameter) \
- SIZEOF(TypeRef, InstanceSize, RawTypeRef) \
- SIZEOF(TypedData, InstanceSize, RawTypedData) \
- SIZEOF(TypedDataBase, InstanceSize, RawTypedDataBase) \
- SIZEOF(TypedDataView, InstanceSize, RawTypedDataView) \
- SIZEOF(UnhandledException, InstanceSize, RawUnhandledException) \
- SIZEOF(UnlinkedCall, InstanceSize, RawUnlinkedCall) \
- SIZEOF(UnwindError, InstanceSize, RawUnwindError) \
- SIZEOF(UserTag, InstanceSize, RawUserTag) \
- SIZEOF(WeakProperty, InstanceSize, RawWeakProperty) \
+ SIZEOF(Number, InstanceSize, NumberLayout) \
+ SIZEOF(Object, InstanceSize, ObjectLayout) \
+ SIZEOF(ObjectPool, InstanceSize, ObjectPoolLayout) \
+ SIZEOF(OneByteString, InstanceSize, OneByteStringLayout) \
+ SIZEOF(ParameterTypeCheck, InstanceSize, ParameterTypeCheckLayout) \
+ SIZEOF(PatchClass, InstanceSize, PatchClassLayout) \
+ SIZEOF(PcDescriptors, InstanceSize, PcDescriptorsLayout) \
+ SIZEOF(Pointer, InstanceSize, PointerLayout) \
+ SIZEOF(ReceivePort, InstanceSize, ReceivePortLayout) \
+ SIZEOF(RedirectionData, InstanceSize, RedirectionDataLayout) \
+ SIZEOF(RegExp, InstanceSize, RegExpLayout) \
+ SIZEOF(Script, InstanceSize, ScriptLayout) \
+ SIZEOF(SendPort, InstanceSize, SendPortLayout) \
+ SIZEOF(SignatureData, InstanceSize, SignatureDataLayout) \
+ SIZEOF(SingleTargetCache, InstanceSize, SingleTargetCacheLayout) \
+ SIZEOF(Smi, InstanceSize, SmiLayout) \
+ SIZEOF(StackTrace, InstanceSize, StackTraceLayout) \
+ SIZEOF(String, InstanceSize, StringLayout) \
+ SIZEOF(SubtypeTestCache, InstanceSize, SubtypeTestCacheLayout) \
+ SIZEOF(TransferableTypedData, InstanceSize, TransferableTypedDataLayout) \
+ SIZEOF(TwoByteString, InstanceSize, TwoByteStringLayout) \
+ SIZEOF(Type, InstanceSize, TypeLayout) \
+ SIZEOF(TypeArguments, InstanceSize, TypeArgumentsLayout) \
+ SIZEOF(TypeParameter, InstanceSize, TypeParameterLayout) \
+ SIZEOF(TypeRef, InstanceSize, TypeRefLayout) \
+ SIZEOF(TypedData, InstanceSize, TypedDataLayout) \
+ SIZEOF(TypedDataBase, InstanceSize, TypedDataBaseLayout) \
+ SIZEOF(TypedDataView, InstanceSize, TypedDataViewLayout) \
+ SIZEOF(UnhandledException, InstanceSize, UnhandledExceptionLayout) \
+ SIZEOF(UnlinkedCall, InstanceSize, UnlinkedCallLayout) \
+ SIZEOF(UnwindError, InstanceSize, UnwindErrorLayout) \
+ SIZEOF(UserTag, InstanceSize, UserTagLayout) \
+ SIZEOF(WeakProperty, InstanceSize, WeakPropertyLayout) \
SIZEOF(WeakSerializationReference, InstanceSize, \
- RawWeakSerializationReference)
+ WeakSerializationReferenceLayout)
#endif // RUNTIME_VM_COMPILER_RUNTIME_OFFSETS_LIST_H_
diff --git a/runtime/vm/compiler/stub_code_compiler.h b/runtime/vm/compiler/stub_code_compiler.h
index 9eb4098..6193417 100644
--- a/runtime/vm/compiler/stub_code_compiler.h
+++ b/runtime/vm/compiler/stub_code_compiler.h
@@ -14,6 +14,7 @@
#include "vm/constants.h"
#include "vm/growable_array.h"
#include "vm/stub_code_list.h"
+#include "vm/tagged_pointer.h"
namespace dart {
@@ -54,7 +55,7 @@
const Object& context_allocation_stub);
#endif
- static RawArray* BuildStaticCallsTable(
+ static ArrayPtr BuildStaticCallsTable(
Zone* zone,
compiler::UnresolvedPcRelativeCalls* unresolved_calls);
diff --git a/runtime/vm/compiler/stub_code_compiler_arm.cc b/runtime/vm/compiler/stub_code_compiler_arm.cc
index 4967874..6ce6f66 100644
--- a/runtime/vm/compiler/stub_code_compiler_arm.cc
+++ b/runtime/vm/compiler/stub_code_compiler_arm.cc
@@ -1107,10 +1107,10 @@
// R3: new object end address.
// R9: allocation size.
{
- const intptr_t shift = target::RawObject::kTagBitsSizeTagPos -
+ const intptr_t shift = target::ObjectLayout::kTagBitsSizeTagPos -
target::ObjectAlignment::kObjectAlignmentLog2;
- __ CompareImmediate(R9, target::RawObject::kSizeTagMaxSizeTag);
+ __ CompareImmediate(R9, target::ObjectLayout::kSizeTagMaxSizeTag);
__ mov(R8, Operand(R9, LSL, shift), LS);
__ mov(R8, Operand(0), HI);
@@ -1535,9 +1535,9 @@
// R1: number of context variables.
// R2: object size.
// R3: next object start.
- const intptr_t shift = target::RawObject::kTagBitsSizeTagPos -
+ const intptr_t shift = target::ObjectLayout::kTagBitsSizeTagPos -
target::ObjectAlignment::kObjectAlignmentLog2;
- __ CompareImmediate(R2, target::RawObject::kSizeTagMaxSizeTag);
+ __ CompareImmediate(R2, target::ObjectLayout::kSizeTagMaxSizeTag);
// If no size tag overflow, shift R2 left, else set R2 to zero.
__ mov(R9, Operand(R2, LSL, shift), LS);
__ mov(R9, Operand(0), HI);
@@ -1733,13 +1733,13 @@
if (cards) {
__ ldr(TMP, FieldAddress(R1, target::Object::tags_offset()));
- __ tst(TMP, Operand(1 << target::RawObject::kCardRememberedBit));
+ __ tst(TMP, Operand(1 << target::ObjectLayout::kCardRememberedBit));
__ b(&remember_card, NOT_ZERO);
} else {
#if defined(DEBUG)
Label ok;
__ ldr(TMP, FieldAddress(R1, target::Object::tags_offset()));
- __ tst(TMP, Operand(1 << target::RawObject::kCardRememberedBit));
+ __ tst(TMP, Operand(1 << target::ObjectLayout::kCardRememberedBit));
__ b(&ok, ZERO);
__ Stop("Wrong barrier");
__ Bind(&ok);
@@ -1756,7 +1756,7 @@
Label retry;
__ Bind(&retry);
__ ldrex(R2, R3);
- __ bic(R2, R2, Operand(1 << target::RawObject::kOldAndNotRememberedBit));
+ __ bic(R2, R2, Operand(1 << target::ObjectLayout::kOldAndNotRememberedBit));
__ strex(R4, R2, R3);
__ cmp(R4, Operand(1));
__ b(&retry, EQ);
@@ -1804,9 +1804,9 @@
// R3: Untagged address of header word (ldrex/strex do not support offsets).
__ Bind(&marking_retry);
__ ldrex(R2, R3);
- __ tst(R2, Operand(1 << target::RawObject::kOldAndNotMarkedBit));
+ __ tst(R2, Operand(1 << target::ObjectLayout::kOldAndNotMarkedBit));
__ b(&lost_race, ZERO);
- __ bic(R2, R2, Operand(1 << target::RawObject::kOldAndNotMarkedBit));
+ __ bic(R2, R2, Operand(1 << target::ObjectLayout::kOldAndNotMarkedBit));
__ strex(R4, R2, R3);
__ cmp(R4, Operand(1));
__ b(&marking_retry, EQ);
@@ -3177,7 +3177,7 @@
__ ldrb(kTmp, FieldAddress(TypeTestABI::kDstTypeReg,
target::Type::type_state_offset()));
__ cmp(kTmp,
- Operand(target::RawAbstractType::kTypeStateFinalizedInstantiated));
+ Operand(target::AbstractTypeLayout::kTypeStateFinalizedInstantiated));
__ BranchIf(NOT_EQUAL, &is_complex_case);
// Check whether this [Type] is a function type.
diff --git a/runtime/vm/compiler/stub_code_compiler_arm64.cc b/runtime/vm/compiler/stub_code_compiler_arm64.cc
index 49004b6..5ff469e 100644
--- a/runtime/vm/compiler/stub_code_compiler_arm64.cc
+++ b/runtime/vm/compiler/stub_code_compiler_arm64.cc
@@ -1191,9 +1191,9 @@
// R2: array length as Smi.
// R3: array size.
// R7: new object end address.
- const intptr_t shift = target::RawObject::kTagBitsSizeTagPos -
+ const intptr_t shift = target::ObjectLayout::kTagBitsSizeTagPos -
target::ObjectAlignment::kObjectAlignmentLog2;
- __ CompareImmediate(R3, target::RawObject::kSizeTagMaxSizeTag);
+ __ CompareImmediate(R3, target::ObjectLayout::kSizeTagMaxSizeTag);
// If no size tag overflow, shift R1 left, else set R1 to zero.
__ LslImmediate(TMP, R3, shift);
__ csel(R1, TMP, R1, LS);
@@ -1628,9 +1628,9 @@
// R0: new object.
// R1: number of context variables.
// R2: object size.
- const intptr_t shift = target::RawObject::kTagBitsSizeTagPos -
+ const intptr_t shift = target::ObjectLayout::kTagBitsSizeTagPos -
target::ObjectAlignment::kObjectAlignmentLog2;
- __ CompareImmediate(R2, target::RawObject::kSizeTagMaxSizeTag);
+ __ CompareImmediate(R2, target::ObjectLayout::kSizeTagMaxSizeTag);
// If no size tag overflow, shift R2 left, else set R2 to zero.
__ LslImmediate(TMP, R2, shift);
__ csel(R2, TMP, R2, LS);
@@ -1830,12 +1830,12 @@
if (cards) {
__ LoadFieldFromOffset(TMP, R1, target::Object::tags_offset(), kWord);
- __ tbnz(&remember_card, TMP, target::RawObject::kCardRememberedBit);
+ __ tbnz(&remember_card, TMP, target::ObjectLayout::kCardRememberedBit);
} else {
#if defined(DEBUG)
Label ok;
__ LoadFieldFromOffset(TMP, R1, target::Object::tags_offset(), kWord);
- __ tbz(&ok, TMP, target::RawObject::kCardRememberedBit);
+ __ tbz(&ok, TMP, target::ObjectLayout::kCardRememberedBit);
__ Stop("Wrong barrier");
__ Bind(&ok);
#endif
@@ -1855,7 +1855,8 @@
Label retry;
__ Bind(&retry);
__ ldxr(R2, R3, kWord);
- __ AndImmediate(R2, R2, ~(1 << target::RawObject::kOldAndNotRememberedBit));
+ __ AndImmediate(R2, R2,
+ ~(1 << target::ObjectLayout::kOldAndNotRememberedBit));
__ stxr(R4, R2, R3, kWord);
__ cbnz(&retry, R4);
@@ -1910,8 +1911,8 @@
// R3: Untagged address of header word (ldxr/stxr do not support offsets).
__ Bind(&marking_retry);
__ ldxr(R2, R3, kWord);
- __ tbz(&lost_race, R2, target::RawObject::kOldAndNotMarkedBit);
- __ AndImmediate(R2, R2, ~(1 << target::RawObject::kOldAndNotMarkedBit));
+ __ tbz(&lost_race, R2, target::ObjectLayout::kOldAndNotMarkedBit);
+ __ AndImmediate(R2, R2, ~(1 << target::ObjectLayout::kOldAndNotMarkedBit));
__ stxr(R4, R2, R3, kWord);
__ cbnz(&marking_retry, R4);
@@ -3302,7 +3303,7 @@
FieldAddress(TypeTestABI::kDstTypeReg, target::Type::type_state_offset()),
kByte);
__ cmp(kTmp,
- Operand(target::RawAbstractType::kTypeStateFinalizedInstantiated));
+ Operand(target::AbstractTypeLayout::kTypeStateFinalizedInstantiated));
__ BranchIf(NOT_EQUAL, &is_complex_case);
// Check whether this [Type] is a function type.
diff --git a/runtime/vm/compiler/stub_code_compiler_ia32.cc b/runtime/vm/compiler/stub_code_compiler_ia32.cc
index 1bfc1d5..73db068 100644
--- a/runtime/vm/compiler/stub_code_compiler_ia32.cc
+++ b/runtime/vm/compiler/stub_code_compiler_ia32.cc
@@ -831,9 +831,9 @@
{
Label size_tag_overflow, done;
__ movl(EDI, EBX);
- __ cmpl(EDI, Immediate(target::RawObject::kSizeTagMaxSizeTag));
+ __ cmpl(EDI, Immediate(target::ObjectLayout::kSizeTagMaxSizeTag));
__ j(ABOVE, &size_tag_overflow, Assembler::kNearJump);
- __ shll(EDI, Immediate(target::RawObject::kTagBitsSizeTagPos -
+ __ shll(EDI, Immediate(target::ObjectLayout::kTagBitsSizeTagPos -
target::ObjectAlignment::kObjectAlignmentLog2));
__ jmp(&done, Assembler::kNearJump);
@@ -1209,9 +1209,9 @@
Label size_tag_overflow, done;
__ leal(EBX, Address(EDX, TIMES_4, fixed_size_plus_alignment_padding));
__ andl(EBX, Immediate(-target::ObjectAlignment::kObjectAlignment));
- __ cmpl(EBX, Immediate(target::RawObject::kSizeTagMaxSizeTag));
+ __ cmpl(EBX, Immediate(target::ObjectLayout::kSizeTagMaxSizeTag));
__ j(ABOVE, &size_tag_overflow, Assembler::kNearJump);
- __ shll(EBX, Immediate(target::RawObject::kTagBitsSizeTagPos -
+ __ shll(EBX, Immediate(target::ObjectLayout::kTagBitsSizeTagPos -
target::ObjectAlignment::kObjectAlignmentLog2));
__ jmp(&done);
@@ -1401,7 +1401,7 @@
// Spilled: EAX, ECX
// EDX: Address being stored
__ movl(EAX, FieldAddress(EDX, target::Object::tags_offset()));
- __ testl(EAX, Immediate(1 << target::RawObject::kOldAndNotRememberedBit));
+ __ testl(EAX, Immediate(1 << target::ObjectLayout::kOldAndNotRememberedBit));
__ j(NOT_EQUAL, &add_to_buffer, Assembler::kNearJump);
__ popl(ECX);
__ popl(EAX);
@@ -1414,12 +1414,12 @@
if (cards) {
// Check if this object is using remembered cards.
- __ testl(EAX, Immediate(1 << target::RawObject::kCardRememberedBit));
+ __ testl(EAX, Immediate(1 << target::ObjectLayout::kCardRememberedBit));
__ j(NOT_EQUAL, &remember_card, Assembler::kFarJump); // Unlikely.
} else {
#if defined(DEBUG)
Label ok;
- __ testl(EAX, Immediate(1 << target::RawObject::kCardRememberedBit));
+ __ testl(EAX, Immediate(1 << target::ObjectLayout::kCardRememberedBit));
__ j(ZERO, &ok, Assembler::kFarJump); // Unlikely.
__ Stop("Wrong barrier");
__ Bind(&ok);
@@ -1429,7 +1429,7 @@
// lock+andl is an atomic read-modify-write.
__ lock();
__ andl(FieldAddress(EDX, target::Object::tags_offset()),
- Immediate(~(1 << target::RawObject::kOldAndNotRememberedBit)));
+ Immediate(~(1 << target::ObjectLayout::kOldAndNotRememberedBit)));
// Load the StoreBuffer block out of the thread. Then load top_ out of the
// StoreBufferBlock and add the address to the pointers_.
diff --git a/runtime/vm/compiler/stub_code_compiler_x64.cc b/runtime/vm/compiler/stub_code_compiler_x64.cc
index 2f662a4..0e7f495 100644
--- a/runtime/vm/compiler/stub_code_compiler_x64.cc
+++ b/runtime/vm/compiler/stub_code_compiler_x64.cc
@@ -1099,9 +1099,9 @@
// RDI: allocation size.
{
Label size_tag_overflow, done;
- __ cmpq(RDI, Immediate(target::RawObject::kSizeTagMaxSizeTag));
+ __ cmpq(RDI, Immediate(target::ObjectLayout::kSizeTagMaxSizeTag));
__ j(ABOVE, &size_tag_overflow, Assembler::kNearJump);
- __ shlq(RDI, Immediate(target::RawObject::kTagBitsSizeTagPos -
+ __ shlq(RDI, Immediate(target::ObjectLayout::kTagBitsSizeTagPos -
target::ObjectAlignment::kObjectAlignmentLog2));
__ jmp(&done, Assembler::kNearJump);
@@ -1539,9 +1539,9 @@
Label size_tag_overflow, done;
__ leaq(R13, Address(R10, TIMES_8, fixed_size_plus_alignment_padding));
__ andq(R13, Immediate(-target::ObjectAlignment::kObjectAlignment));
- __ cmpq(R13, Immediate(target::RawObject::kSizeTagMaxSizeTag));
+ __ cmpq(R13, Immediate(target::ObjectLayout::kSizeTagMaxSizeTag));
__ j(ABOVE, &size_tag_overflow, Assembler::kNearJump);
- __ shlq(R13, Immediate(target::RawObject::kTagBitsSizeTagPos -
+ __ shlq(R13, Immediate(target::ObjectLayout::kTagBitsSizeTagPos -
target::ObjectAlignment::kObjectAlignmentLog2));
__ jmp(&done);
@@ -1740,13 +1740,13 @@
if (cards) {
__ movl(TMP, FieldAddress(RDX, target::Object::tags_offset()));
- __ testl(TMP, Immediate(1 << target::RawObject::kCardRememberedBit));
+ __ testl(TMP, Immediate(1 << target::ObjectLayout::kCardRememberedBit));
__ j(NOT_ZERO, &remember_card, Assembler::kFarJump);
} else {
#if defined(DEBUG)
Label ok;
__ movl(TMP, FieldAddress(RDX, target::Object::tags_offset()));
- __ testl(TMP, Immediate(1 << target::RawObject::kCardRememberedBit));
+ __ testl(TMP, Immediate(1 << target::ObjectLayout::kCardRememberedBit));
__ j(ZERO, &ok, Assembler::kFarJump);
__ Stop("Wrong barrier");
__ Bind(&ok);
@@ -1761,7 +1761,7 @@
// lock+andl is an atomic read-modify-write.
__ lock();
__ andl(FieldAddress(RDX, target::Object::tags_offset()),
- Immediate(~(1 << target::RawObject::kOldAndNotRememberedBit)));
+ Immediate(~(1 << target::ObjectLayout::kOldAndNotRememberedBit)));
// Save registers being destroyed.
__ pushq(RAX);
@@ -1813,9 +1813,9 @@
__ movl(RAX, FieldAddress(TMP, target::Object::tags_offset()));
__ Bind(&retry);
__ movl(RCX, RAX);
- __ testl(RCX, Immediate(1 << target::RawObject::kOldAndNotMarkedBit));
+ __ testl(RCX, Immediate(1 << target::ObjectLayout::kOldAndNotMarkedBit));
__ j(ZERO, &lost_race); // Marked by another thread.
- __ andl(RCX, Immediate(~(1 << target::RawObject::kOldAndNotMarkedBit)));
+ __ andl(RCX, Immediate(~(1 << target::ObjectLayout::kOldAndNotMarkedBit)));
__ LockCmpxchgl(FieldAddress(TMP, target::Object::tags_offset()), RCX);
__ j(NOT_EQUAL, &retry, Assembler::kNearJump);
@@ -2474,7 +2474,7 @@
__ j(EQUAL, &call_target_function_through_unchecked_entry);
// Check trivial exactness.
- // Note: RawICData::receivers_static_type_ is guaranteed to be not null
+ // Note: ICDataLayout::receivers_static_type_ is guaranteed to be not null
// because we only emit calls to this stub when it is not null.
__ movq(RCX,
FieldAddress(RBX, target::ICData::receivers_static_type_offset()));
@@ -3228,7 +3228,7 @@
// Check whether this [Type] is instantiated/uninstantiated.
__ cmpb(
FieldAddress(TypeTestABI::kDstTypeReg, target::Type::type_state_offset()),
- Immediate(target::RawAbstractType::kTypeStateFinalizedInstantiated));
+ Immediate(target::AbstractTypeLayout::kTypeStateFinalizedInstantiated));
__ BranchIf(NOT_EQUAL, &is_complex_case);
// Check whether this [Type] is a function type.
diff --git a/runtime/vm/compiler/write_barrier_elimination.cc b/runtime/vm/compiler/write_barrier_elimination.cc
index 162f8e1..8dc6b3c 100644
--- a/runtime/vm/compiler/write_barrier_elimination.cc
+++ b/runtime/vm/compiler/write_barrier_elimination.cc
@@ -331,8 +331,8 @@
#define FOR_EACH_NATIVE_SLOT(class, underlying_type, field, type, modifiers) \
case Slot::Kind::k##class##_##field: \
- return std::is_base_of<RawInstance, underlying_type>::value || \
- std::is_base_of<RawContext, underlying_type>::value;
+ return std::is_base_of<InstanceLayout, underlying_type>::value || \
+ std::is_base_of<ContextLayout, underlying_type>::value;
NATIVE_SLOTS_LIST(FOR_EACH_NATIVE_SLOT)
#undef FOR_EACH_NATIVE_SLOT
diff --git a/runtime/vm/compiler_test.cc b/runtime/vm/compiler_test.cc
index 2ea85b1..e7b6d31 100644
--- a/runtime/vm/compiler_test.cc
+++ b/runtime/vm/compiler_test.cc
@@ -220,7 +220,7 @@
if (!KernelIsolate::IsRunning()) {
UNREACHABLE();
} else {
- RawLibrary* raw_library = Library::RawCast(Api::UnwrapHandle(lib));
+ LibraryPtr raw_library = Library::RawCast(Api::UnwrapHandle(lib));
Library& lib_handle = Library::ZoneHandle(raw_library);
Dart_KernelCompilationResult compilation_result =
diff --git a/runtime/vm/dart.cc b/runtime/vm/dart.cc
index f295519..4ccca2d 100644
--- a/runtime/vm/dart.cc
+++ b/runtime/vm/dart.cc
@@ -109,9 +109,9 @@
#define CHECK_FIELD(Class, Name) CHECK_OFFSET(Class::Name(), Class##_##Name)
#define CHECK_ARRAY(Class, Name) \
- CHECK_OFFSET(Class::ArrayLayout::elements_start_offset(), \
+ CHECK_OFFSET(Class::ArrayTraits::elements_start_offset(), \
Class##_elements_start_offset) \
- CHECK_OFFSET(Class::ArrayLayout::kElementSize, Class##_element_size)
+ CHECK_OFFSET(Class::ArrayTraits::kElementSize, Class##_element_size)
#define CHECK_ARRAY_STRUCTFIELD(Class, Name, ElementOffsetName, FieldOffset)
#if defined(DART_PRECOMPILED_RUNTIME)
@@ -269,6 +269,8 @@
Object::InitNullAndBool(vm_isolate_);
vm_isolate_->set_object_store(new ObjectStore());
vm_isolate_->isolate_object_store()->Init();
+ vm_isolate_->isolate_group_->object_store_ =
+ vm_isolate_->object_store_shared_ptr_;
TargetCPUFeatures::Init();
Object::Init(vm_isolate_);
ArgumentsDescriptor::Init();
@@ -314,7 +316,7 @@
return strdup(error.ToErrorCString());
}
- ReversePcLookupCache::BuildAndAttachToIsolate(vm_isolate_);
+ ReversePcLookupCache::BuildAndAttachToIsolateGroup(vm_isolate_->group());
Object::FinishInit(vm_isolate_);
#if defined(SUPPORT_TIMELINE)
@@ -674,17 +676,16 @@
I->set_saved_initial_field_table(
donor_isolate->saved_initial_field_table_shareable());
- ReversePcLookupCache::BuildAndAttachToIsolate(I);
return true;
}
#endif
-RawError* Dart::InitIsolateFromSnapshot(Thread* T,
- Isolate* I,
- const uint8_t* snapshot_data,
- const uint8_t* snapshot_instructions,
- const uint8_t* kernel_buffer,
- intptr_t kernel_buffer_size) {
+ErrorPtr Dart::InitIsolateFromSnapshot(Thread* T,
+ Isolate* I,
+ const uint8_t* snapshot_data,
+ const uint8_t* snapshot_instructions,
+ const uint8_t* kernel_buffer,
+ intptr_t kernel_buffer_size) {
Error& error = Error::Handle(T->zone());
error = Object::Init(I, kernel_buffer, kernel_buffer_size);
if (!error.IsNull()) {
@@ -718,7 +719,7 @@
return error.raw();
}
- ReversePcLookupCache::BuildAndAttachToIsolate(I);
+ ReversePcLookupCache::BuildAndAttachToIsolateGroup(I->group());
#if defined(SUPPORT_TIMELINE)
if (tbes.enabled()) {
@@ -789,12 +790,12 @@
}
#endif
-RawError* Dart::InitializeIsolate(const uint8_t* snapshot_data,
- const uint8_t* snapshot_instructions,
- const uint8_t* kernel_buffer,
- intptr_t kernel_buffer_size,
- IsolateGroup* source_isolate_group,
- void* isolate_data) {
+ErrorPtr Dart::InitializeIsolate(const uint8_t* snapshot_data,
+ const uint8_t* snapshot_instructions,
+ const uint8_t* kernel_buffer,
+ intptr_t kernel_buffer_size,
+ IsolateGroup* source_isolate_group,
+ void* isolate_data) {
// Initialize the new isolate.
Thread* T = Thread::Current();
Isolate* I = T->isolate();
diff --git a/runtime/vm/dart.h b/runtime/vm/dart.h
index 537c0a7..f254047 100644
--- a/runtime/vm/dart.h
+++ b/runtime/vm/dart.h
@@ -15,7 +15,6 @@
class DebugInfo;
class Isolate;
class LocalHandle;
-class RawError;
class ReadOnlyHandles;
class ThreadPool;
namespace kernel {
@@ -55,18 +54,18 @@
// from SDK library sources. If the snapshot_buffer is non-NULL,
// initialize from a snapshot or a Kernel binary depending on the value of
// from_kernel. Otherwise, initialize from sources.
- static RawError* InitializeIsolate(const uint8_t* snapshot_data,
- const uint8_t* snapshot_instructions,
- const uint8_t* kernel_buffer,
- intptr_t kernel_buffer_size,
- IsolateGroup* source_isolate_group,
- void* data);
- static RawError* InitIsolateFromSnapshot(Thread* T,
- Isolate* I,
- const uint8_t* snapshot_data,
- const uint8_t* snapshot_instructions,
- const uint8_t* kernel_buffer,
- intptr_t kernel_buffer_size);
+ static ErrorPtr InitializeIsolate(const uint8_t* snapshot_data,
+ const uint8_t* snapshot_instructions,
+ const uint8_t* kernel_buffer,
+ intptr_t kernel_buffer_size,
+ IsolateGroup* source_isolate_group,
+ void* data);
+ static ErrorPtr InitIsolateFromSnapshot(Thread* T,
+ Isolate* I,
+ const uint8_t* snapshot_data,
+ const uint8_t* snapshot_instructions,
+ const uint8_t* kernel_buffer,
+ intptr_t kernel_buffer_size);
static void RunShutdownCallback();
static void ShutdownIsolate(Isolate* isolate);
static void ShutdownIsolate();
diff --git a/runtime/vm/dart_api_impl.cc b/runtime/vm/dart_api_impl.cc
index 82ad6d6..4bb6f96 100644
--- a/runtime/vm/dart_api_impl.cc
+++ b/runtime/vm/dart_api_impl.cc
@@ -84,7 +84,7 @@
#define CHECK_ERROR_HANDLE(error) \
{ \
- RawError* err = (error); \
+ ErrorPtr err = (error); \
if (err != Error::null()) { \
return Api::NewHandle(T, err); \
} \
@@ -115,7 +115,7 @@
funcHandle_(Function::Handle(thread->zone())),
typeHandle_(AbstractType::Handle(thread->zone())) {}
- void VisitObject(RawObject* obj) {
+ void VisitObject(ObjectPtr obj) {
if (obj->IsFunction()) {
funcHandle_ ^= obj;
classHandle_ ^= funcHandle_.Owner();
@@ -145,7 +145,7 @@
};
#endif // #if defined(DEBUG).
-static RawInstance* GetListInstance(Zone* zone, const Object& obj) {
+static InstancePtr GetListInstance(Zone* zone, const Object& obj) {
if (obj.IsInstance()) {
ObjectStore* object_store = Isolate::Current()->object_store();
Type& list_rare_type =
@@ -169,7 +169,7 @@
return Instance::null();
}
-static RawInstance* GetMapInstance(Zone* zone, const Object& obj) {
+static InstancePtr GetMapInstance(Zone* zone, const Object& obj) {
if (obj.IsInstance()) {
ObjectStore* object_store = Isolate::Current()->object_store();
Type& map_rare_type =
@@ -294,7 +294,7 @@
current_func, field_count, num_fields);
}
-static RawObject* Send0Arg(const Instance& receiver, const String& selector) {
+static ObjectPtr Send0Arg(const Instance& receiver, const String& selector) {
const intptr_t kTypeArgsLen = 0;
const intptr_t kNumArgs = 1;
ArgumentsDescriptor args_desc(
@@ -309,9 +309,9 @@
return DartEntry::InvokeFunction(function, args);
}
-static RawObject* Send1Arg(const Instance& receiver,
- const String& selector,
- const Instance& argument) {
+static ObjectPtr Send1Arg(const Instance& receiver,
+ const String& selector,
+ const Instance& argument) {
const intptr_t kTypeArgsLen = 0;
const intptr_t kNumArgs = 2;
ArgumentsDescriptor args_desc(
@@ -346,7 +346,7 @@
}
}
-Dart_Handle Api::InitNewHandle(Thread* thread, RawObject* raw) {
+Dart_Handle Api::InitNewHandle(Thread* thread, ObjectPtr raw) {
LocalHandles* local_handles = Api::TopScope(thread)->local_handles();
ASSERT(local_handles != NULL);
LocalHandle* ref = local_handles->AllocateHandle();
@@ -354,7 +354,7 @@
return ref->apiHandle();
}
-Dart_Handle Api::NewHandle(Thread* thread, RawObject* raw) {
+Dart_Handle Api::NewHandle(Thread* thread, ObjectPtr raw) {
if (raw == Object::null()) {
return Null();
}
@@ -368,7 +368,7 @@
return InitNewHandle(thread, raw);
}
-RawObject* Api::UnwrapHandle(Dart_Handle object) {
+ObjectPtr Api::UnwrapHandle(Dart_Handle object) {
#if defined(DEBUG)
Thread* thread = Thread::Current();
ASSERT(thread->execution_state() == Thread::kThreadInVM);
@@ -520,8 +520,8 @@
ASSERT(api_native_key_ != kUnsetThreadLocalKey);
}
-static Dart_Handle InitNewReadOnlyApiHandle(RawObject* raw) {
- ASSERT(raw->InVMIsolateHeap());
+static Dart_Handle InitNewReadOnlyApiHandle(ObjectPtr raw) {
+ ASSERT(raw->ptr()->InVMIsolateHeap());
LocalHandle* ref = Dart::AllocateReadOnlyApiHandle();
ref->set_raw(raw);
return ref->apiHandle();
@@ -558,14 +558,14 @@
int arg_index,
void** peer) {
NoSafepointScope no_safepoint_scope;
- RawObject* raw_obj = arguments->NativeArgAt(arg_index);
+ ObjectPtr raw_obj = arguments->NativeArgAt(arg_index);
if (!raw_obj->IsHeapObject()) {
return false;
}
intptr_t cid = raw_obj->GetClassId();
if (cid == kExternalOneByteStringCid) {
- RawExternalOneByteString* raw_string =
- reinterpret_cast<RawExternalOneByteString*>(raw_obj);
+ ExternalOneByteStringPtr raw_string =
+ static_cast<ExternalOneByteStringPtr>(raw_obj);
*peer = raw_string->ptr()->peer_;
return true;
}
@@ -575,8 +575,8 @@
return (*peer != 0);
}
if (cid == kExternalTwoByteStringCid) {
- RawExternalTwoByteString* raw_string =
- reinterpret_cast<RawExternalTwoByteString*>(raw_obj);
+ ExternalTwoByteStringPtr raw_string =
+ static_cast<ExternalTwoByteStringPtr>(raw_obj);
*peer = raw_string->ptr()->peer_;
return true;
}
@@ -585,13 +585,13 @@
bool Api::GetNativeReceiver(NativeArguments* arguments, intptr_t* value) {
NoSafepointScope no_safepoint_scope;
- RawObject* raw_obj = arguments->NativeArg0();
+ ObjectPtr raw_obj = arguments->NativeArg0();
if (raw_obj->IsHeapObject()) {
intptr_t cid = raw_obj->GetClassId();
if (cid >= kNumPredefinedCids) {
ASSERT(Instance::Cast(Object::Handle(raw_obj)).IsValidNativeIndex(0));
- RawTypedData* native_fields = *reinterpret_cast<RawTypedData**>(
- RawObject::ToAddr(raw_obj) + sizeof(RawObject));
+ TypedDataPtr native_fields = *reinterpret_cast<TypedDataPtr*>(
+ ObjectLayout::ToAddr(raw_obj) + sizeof(ObjectLayout));
if (native_fields == TypedData::null()) {
*value = 0;
} else {
@@ -607,7 +607,7 @@
int arg_index,
bool* value) {
NoSafepointScope no_safepoint_scope;
- RawObject* raw_obj = arguments->NativeArgAt(arg_index);
+ ObjectPtr raw_obj = arguments->NativeArgAt(arg_index);
if (raw_obj->IsHeapObject()) {
intptr_t cid = raw_obj->GetClassId();
if (cid == kBoolCid) {
@@ -626,16 +626,16 @@
int arg_index,
int64_t* value) {
NoSafepointScope no_safepoint_scope;
- RawObject* raw_obj = arguments->NativeArgAt(arg_index);
+ ObjectPtr raw_obj = arguments->NativeArgAt(arg_index);
if (raw_obj->IsHeapObject()) {
intptr_t cid = raw_obj->GetClassId();
if (cid == kMintCid) {
- *value = reinterpret_cast<RawMint*>(raw_obj)->ptr()->value_;
+ *value = static_cast<MintPtr>(raw_obj)->ptr()->value_;
return true;
}
return false;
}
- *value = Smi::Value(reinterpret_cast<RawSmi*>(raw_obj));
+ *value = Smi::Value(static_cast<SmiPtr>(raw_obj));
return true;
}
@@ -643,21 +643,21 @@
int arg_index,
double* value) {
NoSafepointScope no_safepoint_scope;
- RawObject* raw_obj = arguments->NativeArgAt(arg_index);
+ ObjectPtr raw_obj = arguments->NativeArgAt(arg_index);
if (raw_obj->IsHeapObject()) {
intptr_t cid = raw_obj->GetClassId();
if (cid == kDoubleCid) {
- *value = reinterpret_cast<RawDouble*>(raw_obj)->ptr()->value_;
+ *value = static_cast<DoublePtr>(raw_obj)->ptr()->value_;
return true;
}
if (cid == kMintCid) {
- *value = static_cast<double>(
- reinterpret_cast<RawMint*>(raw_obj)->ptr()->value_);
+ *value =
+ static_cast<double>(static_cast<MintPtr>(raw_obj)->ptr()->value_);
return true;
}
return false;
}
- *value = static_cast<double>(Smi::Value(reinterpret_cast<RawSmi*>(raw_obj)));
+ *value = static_cast<double>(Smi::Value(static_cast<SmiPtr>(raw_obj)));
return true;
}
@@ -666,12 +666,12 @@
int num_fields,
intptr_t* field_values) {
NoSafepointScope no_safepoint_scope;
- RawObject* raw_obj = arguments->NativeArgAt(arg_index);
+ ObjectPtr raw_obj = arguments->NativeArgAt(arg_index);
if (raw_obj->IsHeapObject()) {
intptr_t cid = raw_obj->GetClassId();
if (cid >= kNumPredefinedCids) {
- RawTypedData* native_fields = *reinterpret_cast<RawTypedData**>(
- RawObject::ToAddr(raw_obj) + sizeof(RawObject));
+ TypedDataPtr native_fields = *reinterpret_cast<TypedDataPtr*>(
+ ObjectLayout::ToAddr(raw_obj) + sizeof(ObjectLayout));
if (native_fields == TypedData::null()) {
memset(field_values, 0, (num_fields * sizeof(field_values[0])));
} else if (num_fields == Smi::Value(native_fields->ptr()->length_)) {
@@ -865,7 +865,7 @@
// that GC won't touch the raw error object before creating a valid
// handle for it in the surviving zone.
NoSafepointScope no_safepoint;
- RawError* raw_error = Api::UnwrapErrorHandle(thread->zone(), handle).raw();
+ ErrorPtr raw_error = Api::UnwrapErrorHandle(thread->zone(), handle).raw();
thread->UnwindScopes(thread->top_exit_frame_info());
// Note that thread's zone is different here than at the beginning of this
// function.
@@ -2011,7 +2011,7 @@
const Error* error;
{
NoSafepointScope no_safepoint;
- RawError* raw_error = Error::Cast(result).raw();
+ ErrorPtr raw_error = Error::Cast(result).raw();
T->UnwindScopes(T->top_exit_frame_info());
error = &Error::Handle(T->zone(), raw_error);
}
@@ -2028,7 +2028,7 @@
const Error* error;
{
NoSafepointScope no_safepoint;
- RawError* raw_error = T->StealStickyError();
+ ErrorPtr raw_error = T->StealStickyError();
T->UnwindScopes(T->top_exit_frame_info());
error = &Error::Handle(T->zone(), raw_error);
}
@@ -2084,7 +2084,7 @@
}
// Smis and null can be sent without serialization.
- RawObject* raw_obj = Api::UnwrapHandle(handle);
+ ObjectPtr raw_obj = Api::UnwrapHandle(handle);
if (ApiObjectConverter::CanConvert(raw_obj)) {
return PortMap::PostMessage(
Message::New(port_id, raw_obj, Message::kNormalPriority));
@@ -2471,7 +2471,7 @@
RETURN_TYPE_ERROR(Z, function, Function);
}
if (func.IsNonImplicitClosureFunction()) {
- RawFunction* parent_function = func.parent_function();
+ FunctionPtr parent_function = func.parent_function();
return Api::NewHandle(T, parent_function);
}
const Class& owner = Class::Handle(Z, func.Owner());
@@ -2515,7 +2515,7 @@
ASSERT(ClassFinalizer::AllClassesFinalized());
- RawFunction* rf = Closure::Cast(closure_obj).function();
+ FunctionPtr rf = Closure::Cast(closure_obj).function();
return Api::NewHandle(T, rf);
}
@@ -2607,7 +2607,7 @@
CHECK_CALLBACK_STATE(T);
API_TIMELINE_DURATION(T);
const String& str_obj = String::Handle(Z, String::New(str));
- RawInteger* integer = Integer::New(str_obj);
+ IntegerPtr integer = Integer::New(str_obj);
if (integer == Integer::null()) {
return Api::NewError("%s: Cannot create Dart integer from string %s",
CURRENT_FUNC, str);
@@ -2733,7 +2733,7 @@
return Api::NewError("function_name must refer to a static method.");
}
- if (func.kind() != RawFunction::kRegularFunction) {
+ if (func.kind() != FunctionLayout::kRegularFunction) {
return Api::NewError(
"function_name must be the name of a regular function.");
}
@@ -3021,7 +3021,7 @@
return Dart_NewListOf(Dart_CoreType_Dynamic, length);
}
-static RawTypeArguments* TypeArgumentsForElementType(
+static TypeArgumentsPtr TypeArgumentsForElementType(
ObjectStore* store,
Dart_CoreType_Id element_type_id) {
switch (element_type_id) {
@@ -3321,13 +3321,13 @@
}
}
-static RawObject* ResolveConstructor(const char* current_func,
- const Class& cls,
- const String& class_name,
- const String& dotted_name,
- int num_args);
+static ObjectPtr ResolveConstructor(const char* current_func,
+ const Class& cls,
+ const String& class_name,
+ const String& dotted_name,
+ int num_args);
-static RawObject* ThrowArgumentError(const char* exception_message) {
+static ObjectPtr ThrowArgumentError(const char* exception_message) {
Thread* thread = Thread::Current();
Zone* zone = thread->zone();
// Lookup the class ArgumentError in dart:core.
@@ -3378,7 +3378,7 @@
const Instance* saved_exception;
{
NoSafepointScope no_safepoint;
- RawInstance* raw_exception = exception.raw();
+ InstancePtr raw_exception = exception.raw();
thread->UnwindScopes(thread->top_exit_frame_info());
saved_exception = &Instance::Handle(raw_exception);
}
@@ -3759,9 +3759,9 @@
return Dart_TypedData_kInvalid;
}
-static RawObject* GetByteDataConstructor(Thread* thread,
- const String& constructor_name,
- intptr_t num_args) {
+static ObjectPtr GetByteDataConstructor(Thread* thread,
+ const String& constructor_name,
+ intptr_t num_args) {
const Library& lib =
Library::Handle(thread->isolate()->object_store()->typed_data_library());
ASSERT(!lib.IsNull());
@@ -3982,10 +3982,10 @@
return Api::Null();
}
-static RawObject* GetByteBufferConstructor(Thread* thread,
- const String& class_name,
- const String& constructor_name,
- intptr_t num_args) {
+static ObjectPtr GetByteBufferConstructor(Thread* thread,
+ const String& class_name,
+ const String& constructor_name,
+ intptr_t num_args) {
const Library& lib =
Library::Handle(thread->isolate()->object_store()->typed_data_library());
ASSERT(!lib.IsNull());
@@ -4184,11 +4184,11 @@
// --- Invoking Constructors, Methods, and Field accessors ---
-static RawObject* ResolveConstructor(const char* current_func,
- const Class& cls,
- const String& class_name,
- const String& constr_name,
- int num_args) {
+static ObjectPtr ResolveConstructor(const char* current_func,
+ const Class& cls,
+ const String& class_name,
+ const String& constr_name,
+ int num_args) {
// The constructor must be present in the interface.
const Function& constructor =
Function::Handle(cls.LookupFunctionAllowPrivate(constr_name));
@@ -4223,7 +4223,7 @@
current_func, constr_name.ToCString(), error_message.ToCString()));
return ApiError::New(message);
}
- RawError* error = constructor.VerifyCallEntryPoint();
+ ErrorPtr error = constructor.VerifyCallEntryPoint();
if (error != Error::null()) return error;
return constructor.raw();
}
@@ -4365,7 +4365,7 @@
return Api::NewHandle(T, new_object.raw());
}
-static RawInstance* AllocateObject(Thread* thread, const Class& cls) {
+static InstancePtr AllocateObject(Thread* thread, const Class& cls) {
if (!cls.is_fields_marked_nullable()) {
// Mark all fields as nullable.
Zone* zone = thread->zone();
@@ -4841,7 +4841,7 @@
const Instance* saved_exception;
{
NoSafepointScope no_safepoint;
- RawInstance* raw_exception =
+ InstancePtr raw_exception =
Api::UnwrapInstanceHandle(zone, exception).raw();
thread->UnwindScopes(thread->top_exit_frame_info());
saved_exception = &Instance::Handle(raw_exception);
@@ -4879,9 +4879,9 @@
const StackTrace* saved_stacktrace;
{
NoSafepointScope no_safepoint;
- RawInstance* raw_exception =
+ InstancePtr raw_exception =
Api::UnwrapInstanceHandle(zone, exception).raw();
- RawStackTrace* raw_stacktrace =
+ StackTracePtr raw_stacktrace =
Api::UnwrapStackTraceHandle(zone, stacktrace).raw();
thread->UnwindScopes(thread->top_exit_frame_info());
saved_exception = &Instance::Handle(raw_exception);
@@ -5242,7 +5242,7 @@
}
// --- Environment ---
-RawString* Api::GetEnvironmentValue(Thread* thread, const String& name) {
+StringPtr Api::GetEnvironmentValue(Thread* thread, const String& name) {
String& result = String::Handle(CallEnvironmentCallback(thread, name));
if (result.IsNull()) {
// Every 'dart:X' library introduces an environment variable
@@ -5304,7 +5304,7 @@
return result.raw();
}
-RawString* Api::CallEnvironmentCallback(Thread* thread, const String& name) {
+StringPtr Api::CallEnvironmentCallback(Thread* thread, const String& name) {
Isolate* isolate = thread->isolate();
Dart_EnvironmentCallback callback = isolate->environment_callback();
if (callback != NULL) {
@@ -5903,7 +5903,7 @@
}
{
NoSafepointScope no_safepoint;
- RawObject* raw_obj = obj.raw();
+ ObjectPtr raw_obj = obj.raw();
*peer = thread->isolate()->heap()->GetPeer(raw_obj);
}
return Api::Success();
@@ -5923,7 +5923,7 @@
}
{
NoSafepointScope no_safepoint;
- RawObject* raw_obj = obj.raw();
+ ObjectPtr raw_obj = obj.raw();
thread->isolate()->heap()->SetPeer(raw_obj, peer);
}
return Api::Success();
diff --git a/runtime/vm/dart_api_impl.h b/runtime/vm/dart_api_impl.h
index 621f88b..80f0462 100644
--- a/runtime/vm/dart_api_impl.h
+++ b/runtime/vm/dart_api_impl.h
@@ -156,10 +156,10 @@
};
// Creates a new local handle.
- static Dart_Handle NewHandle(Thread* thread, RawObject* raw);
+ static Dart_Handle NewHandle(Thread* thread, ObjectPtr raw);
// Unwraps the raw object from the handle.
- static RawObject* UnwrapHandle(Dart_Handle object);
+ static ObjectPtr UnwrapHandle(Dart_Handle object);
// Unwraps a raw Type from the handle. The handle will be null if
// the object was not of the requested Type.
@@ -198,7 +198,7 @@
static bool IsSmi(Dart_Handle handle) {
// Important: we do not require current thread to be in VM state because
// we do not dereference the handle.
- RawObject* raw = *(reinterpret_cast<RawObject**>(handle));
+ ObjectPtr raw = *(reinterpret_cast<ObjectPtr*>(handle));
return !raw->IsHeapObject();
}
@@ -206,8 +206,8 @@
static intptr_t SmiValue(Dart_Handle handle) {
// Important: we do not require current thread to be in VM state because
// we do not dereference the handle.
- RawObject* value = *(reinterpret_cast<RawObject**>(handle));
- return Smi::Value(static_cast<RawSmi*>(value));
+ ObjectPtr value = *(reinterpret_cast<ObjectPtr*>(handle));
+ return Smi::Value(static_cast<SmiPtr>(value));
}
// Returns true if the handle holds a Dart Instance.
@@ -224,7 +224,7 @@
}
static intptr_t ClassId(Dart_Handle handle) {
- RawObject* raw = UnwrapHandle(handle);
+ ObjectPtr raw = UnwrapHandle(handle);
if (!raw->IsHeapObject()) {
return kSmiCid;
}
@@ -305,7 +305,7 @@
static void SetWeakHandleReturnValue(NativeArguments* args,
Dart_WeakPersistentHandle retval);
- static RawString* GetEnvironmentValue(Thread* thread, const String& name);
+ static StringPtr GetEnvironmentValue(Thread* thread, const String& name);
static bool IsFfiEnabled() {
#if defined(TAGET_OS_FUCHSIA)
@@ -316,9 +316,9 @@
}
private:
- static Dart_Handle InitNewHandle(Thread* thread, RawObject* raw);
+ static Dart_Handle InitNewHandle(Thread* thread, ObjectPtr raw);
- static RawString* CallEnvironmentCallback(Thread* thread, const String& name);
+ static StringPtr CallEnvironmentCallback(Thread* thread, const String& name);
// Thread local key used by the API. Currently holds the current
// ApiNativeScope if any.
diff --git a/runtime/vm/dart_api_impl_test.cc b/runtime/vm/dart_api_impl_test.cc
index c82582f..6106c7c 100644
--- a/runtime/vm/dart_api_impl_test.cc
+++ b/runtime/vm/dart_api_impl_test.cc
@@ -4495,7 +4495,7 @@
// (1 + 2) * kWordSize + size of object header.
// We check to make sure the instance size computed by the VM matches
// our expectations.
- intptr_t header_size = sizeof(RawObject);
+ intptr_t header_size = sizeof(ObjectLayout);
EXPECT_EQ(
Utils::RoundUp(((1 + 2) * kWordSize) + header_size, kObjectAlignment),
cls.host_instance_size());
diff --git a/runtime/vm/dart_api_message.cc b/runtime/vm/dart_api_message.cc
index 30e127d..639270c 100644
--- a/runtime/vm/dart_api_message.cc
+++ b/runtime/vm/dart_api_message.cc
@@ -15,7 +15,8 @@
static const int kNumInitialReferences = 4;
ApiMessageReader::ApiMessageReader(Message* msg)
- : BaseReader(msg->IsRaw() ? reinterpret_cast<uint8_t*>(msg->raw_obj())
+ : BaseReader(msg->IsRaw() ? reinterpret_cast<uint8_t*>(
+ static_cast<uword>(msg->raw_obj()))
: msg->snapshot(),
msg->snapshot_length()),
zone_(NULL),
@@ -49,8 +50,8 @@
// Read the object out of the message.
return ReadObject();
} else {
- const RawObject* raw_obj =
- reinterpret_cast<const RawObject*>(CurrentBufferAddress());
+ const ObjectPtr raw_obj = static_cast<const ObjectPtr>(
+ reinterpret_cast<uword>(CurrentBufferAddress()));
ASSERT(ApiObjectConverter::CanConvert(raw_obj));
Dart_CObject* cobj =
reinterpret_cast<Dart_CObject*>(allocator(sizeof(Dart_CObject)));
@@ -185,11 +186,11 @@
}
Dart_CObject* ApiMessageReader::AllocateDartCObjectVmIsolateObj(intptr_t id) {
- RawObject* raw = VmIsolateSnapshotObject(id);
+ ObjectPtr raw = VmIsolateSnapshotObject(id);
intptr_t cid = raw->GetClassId();
switch (cid) {
case kOneByteStringCid: {
- RawOneByteString* raw_str = reinterpret_cast<RawOneByteString*>(raw);
+ OneByteStringPtr raw_str = static_cast<OneByteStringPtr>(raw);
const char* str = reinterpret_cast<const char*>(raw_str->ptr()->data());
ASSERT(str != NULL);
Dart_CObject* object = NULL;
@@ -207,7 +208,7 @@
}
case kMintCid: {
- const Mint& obj = Mint::Handle(reinterpret_cast<RawMint*>(raw));
+ const Mint& obj = Mint::Handle(static_cast<MintPtr>(raw));
int64_t value64 = obj.value();
if ((kMinInt32 <= value64) && (value64 <= kMaxInt32)) {
return GetCanonicalMintObject(Dart_CObject_kInt32, value64);
@@ -323,9 +324,9 @@
return backward_references_.length() + kMaxPredefinedObjectIds;
}
-Dart_CObject* ApiMessageReader::CreateDartCObjectString(RawObject* raw) {
+Dart_CObject* ApiMessageReader::CreateDartCObjectString(ObjectPtr raw) {
ASSERT(IsOneByteStringClassId(raw->GetClassId()));
- RawOneByteString* raw_str = reinterpret_cast<RawOneByteString*>(raw);
+ OneByteStringPtr raw_str = static_cast<OneByteStringPtr>(raw);
intptr_t len = Smi::Value(raw_str->ptr()->length_);
Dart_CObject* object = AllocateDartCObjectString(len);
char* p = object->value.as_string;
@@ -848,7 +849,7 @@
void ApiMessageWriter::WriteSmi(int64_t value) {
ASSERT(Smi::IsValid(value));
- Write<RawObject*>(Smi::New(static_cast<intptr_t>(value)));
+ Write<ObjectPtr>(Smi::New(static_cast<intptr_t>(value)));
}
void ApiMessageWriter::WriteNullObject() {
diff --git a/runtime/vm/dart_api_message.h b/runtime/vm/dart_api_message.h
index 92a9a85..aa80031 100644
--- a/runtime/vm/dart_api_message.h
+++ b/runtime/vm/dart_api_message.h
@@ -128,11 +128,11 @@
return reinterpret_cast<Dart_CObject_Internal*>(object);
}
- RawObject* VmIsolateSnapshotObject(intptr_t index) const {
+ ObjectPtr VmIsolateSnapshotObject(intptr_t index) const {
return Object::vm_isolate_snapshot_object_table().At(index);
}
- Dart_CObject* CreateDartCObjectString(RawObject* raw);
+ Dart_CObject* CreateDartCObjectString(ObjectPtr raw);
Dart_CObject* GetCanonicalMintObject(Dart_CObject_Type type, int64_t value64);
uint8_t* allocator(intptr_t size) {
@@ -203,13 +203,13 @@
// as well.
class ApiObjectConverter : public AllStatic {
public:
- static bool CanConvert(const RawObject* raw_obj) {
+ static bool CanConvert(const ObjectPtr raw_obj) {
return !raw_obj->IsHeapObject() || (raw_obj == Object::null());
}
- static bool Convert(const RawObject* raw_obj, Dart_CObject* c_obj) {
+ static bool Convert(const ObjectPtr raw_obj, Dart_CObject* c_obj) {
if (!raw_obj->IsHeapObject()) {
- ConvertSmi(reinterpret_cast<const RawSmi*>(raw_obj), c_obj);
+ ConvertSmi(static_cast<const SmiPtr>(raw_obj), c_obj);
} else if (raw_obj == Object::null()) {
ConvertNull(c_obj);
} else {
@@ -219,7 +219,7 @@
}
private:
- static void ConvertSmi(const RawSmi* raw_smi, Dart_CObject* c_obj) {
+ static void ConvertSmi(const SmiPtr raw_smi, Dart_CObject* c_obj) {
ASSERT(!raw_smi->IsHeapObject());
intptr_t value = Smi::Value(raw_smi);
if (Utils::IsInt(31, value)) {
diff --git a/runtime/vm/dart_api_state.h b/runtime/vm/dart_api_state.h
index 3e48e72..a986121 100644
--- a/runtime/vm/dart_api_state.h
+++ b/runtime/vm/dart_api_state.h
@@ -127,8 +127,8 @@
class LocalHandle {
public:
// Accessors.
- RawObject* raw() const { return raw_; }
- void set_raw(RawObject* raw) { raw_ = raw; }
+ ObjectPtr raw() const { return raw_; }
+ void set_raw(ObjectPtr raw) { raw_ = raw; }
static intptr_t raw_offset() { return OFFSET_OF(LocalHandle, raw_); }
Dart_Handle apiHandle() { return reinterpret_cast<Dart_Handle>(this); }
@@ -137,7 +137,7 @@
LocalHandle() {}
~LocalHandle() {}
- RawObject* raw_;
+ ObjectPtr raw_;
DISALLOW_ALLOCATION(); // Allocated through AllocateHandle methods.
DISALLOW_COPY_AND_ASSIGN(LocalHandle);
};
@@ -151,11 +151,11 @@
class PersistentHandle {
public:
// Accessors.
- RawObject* raw() const { return raw_; }
- void set_raw(RawObject* ref) { raw_ = ref; }
+ ObjectPtr raw() const { return raw_; }
+ void set_raw(ObjectPtr ref) { raw_ = ref; }
void set_raw(const LocalHandle& ref) { raw_ = ref.raw(); }
void set_raw(const Object& object) { raw_ = object.raw(); }
- RawObject** raw_addr() { return &raw_; }
+ ObjectPtr* raw_addr() { return &raw_; }
Dart_PersistentHandle apiHandle() {
return reinterpret_cast<Dart_PersistentHandle>(this);
}
@@ -172,14 +172,16 @@
// Overload the raw_ field as a next pointer when adding freed
// handles to the free list.
- PersistentHandle* Next() { return reinterpret_cast<PersistentHandle*>(raw_); }
+ PersistentHandle* Next() {
+ return reinterpret_cast<PersistentHandle*>(static_cast<uword>(raw_));
+ }
void SetNext(PersistentHandle* free_list) {
- raw_ = reinterpret_cast<RawObject*>(free_list);
+ raw_ = static_cast<ObjectPtr>(reinterpret_cast<uword>(free_list));
ASSERT(!raw_->IsHeapObject());
}
void FreeHandle(PersistentHandle* free_list) { SetNext(free_list); }
- RawObject* raw_;
+ ObjectPtr raw_;
DISALLOW_ALLOCATION(); // Allocated through AllocateHandle methods.
DISALLOW_COPY_AND_ASSIGN(PersistentHandle);
};
@@ -196,8 +198,8 @@
intptr_t external_size);
// Accessors.
- RawObject* raw() const { return raw_; }
- RawObject** raw_addr() { return &raw_; }
+ ObjectPtr raw() const { return raw_; }
+ ObjectPtr* raw_addr() { return &raw_; }
static intptr_t raw_offset() {
return OFFSET_OF(FinalizablePersistentHandle, raw_);
}
@@ -265,7 +267,7 @@
friend class FinalizablePersistentHandles;
FinalizablePersistentHandle()
- : raw_(NULL), peer_(NULL), external_data_(0), callback_(NULL) {}
+ : raw_(nullptr), peer_(NULL), external_data_(0), callback_(NULL) {}
~FinalizablePersistentHandle() {}
static void Finalize(IsolateGroup* isolate_group,
@@ -274,10 +276,11 @@
// Overload the raw_ field as a next pointer when adding freed
// handles to the free list.
FinalizablePersistentHandle* Next() {
- return reinterpret_cast<FinalizablePersistentHandle*>(raw_);
+ return reinterpret_cast<FinalizablePersistentHandle*>(
+ static_cast<uword>(raw_));
}
void SetNext(FinalizablePersistentHandle* free_list) {
- raw_ = reinterpret_cast<RawObject*>(free_list);
+ raw_ = static_cast<ObjectPtr>(reinterpret_cast<uword>(free_list));
ASSERT(!raw_->IsHeapObject());
}
void FreeHandle(FinalizablePersistentHandle* free_list) {
@@ -292,7 +295,7 @@
callback_ = NULL;
}
- void set_raw(RawObject* raw) { raw_ = raw; }
+ void set_raw(ObjectPtr raw) { raw_ = raw; }
void set_raw(const LocalHandle& ref) { raw_ = ref.raw(); }
void set_raw(const Object& object) { raw_ = object.raw(); }
@@ -327,7 +330,7 @@
return raw_->IsSmiOrOldObject() ? Heap::kOld : Heap::kNew;
}
- RawObject* raw_;
+ ObjectPtr raw_;
void* peer_;
uword external_data_;
Dart_WeakPersistentHandleFinalizer callback_;
diff --git a/runtime/vm/dart_entry.cc b/runtime/vm/dart_entry.cc
index 88a75f6..bb992b5 100644
--- a/runtime/vm/dart_entry.cc
+++ b/runtime/vm/dart_entry.cc
@@ -28,10 +28,10 @@
DECLARE_FLAG(bool, precompiled_mode);
// A cache of VM heap allocated arguments descriptors.
-RawArray* ArgumentsDescriptor::cached_args_descriptors_[kCachedDescriptorCount];
+ArrayPtr ArgumentsDescriptor::cached_args_descriptors_[kCachedDescriptorCount];
-RawObject* DartEntry::InvokeFunction(const Function& function,
- const Array& arguments) {
+ObjectPtr DartEntry::InvokeFunction(const Function& function,
+ const Array& arguments) {
ASSERT(Thread::Current()->IsMutatorThread());
const int kTypeArgsLen = 0; // No support to pass type args to generic func.
const Array& arguments_descriptor = Array::Handle(
@@ -99,10 +99,10 @@
LongJumpScope* saved_long_jump_base_;
};
-RawObject* DartEntry::InvokeFunction(const Function& function,
- const Array& arguments,
- const Array& arguments_descriptor,
- uword current_sp) {
+ObjectPtr DartEntry::InvokeFunction(const Function& function,
+ const Array& arguments,
+ const Array& arguments_descriptor,
+ uword current_sp) {
// We use a kernel2kernel constant evaluator in Dart 2.0 AOT compilation
// and never start the VM service isolate. So we should never end up invoking
// any dart code in the Dart 2.0 AOT compiler.
@@ -136,7 +136,7 @@
if (!function.HasCode()) {
if (FLAG_enable_interpreter && function.IsBytecodeAllowed(zone)) {
if (!function.HasBytecode()) {
- RawError* error =
+ ErrorPtr error =
kernel::BytecodeReader::ReadFunctionBytecode(thread, function);
if (error != Error::null()) {
return error;
@@ -171,11 +171,21 @@
return InvokeCode(code, arguments_descriptor, arguments, thread);
}
+extern "C" {
+// Note: The invocation stub follows the C ABI, so we cannot pass C++ struct
+// values like ObjectPtr. In some calling conventions (IA32), ObjectPtr is
+// passed/returned different from a pointer.
+typedef uword /*ObjectPtr*/ (*invokestub)(const Code& target_code,
+ const Array& arguments_descriptor,
+ const Array& arguments,
+ Thread* thread);
+}
+
NO_SANITIZE_SAFE_STACK
-RawObject* DartEntry::InvokeCode(const Code& code,
- const Array& arguments_descriptor,
- const Array& arguments,
- Thread* thread) {
+ObjectPtr DartEntry::InvokeCode(const Code& code,
+ const Array& arguments_descriptor,
+ const Array& arguments,
+ Thread* thread) {
ASSERT(!code.IsNull());
ASSERT(thread->no_callback_scope_depth() == 0);
@@ -184,17 +194,18 @@
SuspendLongJumpScope suspend_long_jump_scope(thread);
TransitionToGenerated transition(thread);
#if defined(USING_SIMULATOR)
- return bit_copy<RawObject*, int64_t>(Simulator::Current()->Call(
+ return bit_copy<ObjectPtr, int64_t>(Simulator::Current()->Call(
reinterpret_cast<intptr_t>(entrypoint), reinterpret_cast<intptr_t>(&code),
reinterpret_cast<intptr_t>(&arguments_descriptor),
reinterpret_cast<intptr_t>(&arguments),
reinterpret_cast<intptr_t>(thread)));
#else
- return entrypoint(code, arguments_descriptor, arguments, thread);
+ return static_cast<ObjectPtr>(
+ entrypoint(code, arguments_descriptor, arguments, thread));
#endif
}
-RawObject* DartEntry::InvokeClosure(const Array& arguments) {
+ObjectPtr DartEntry::InvokeClosure(const Array& arguments) {
const int kTypeArgsLen = 0; // No support to pass type args to generic func.
// Closures always have boxed parameters
@@ -203,8 +214,8 @@
return InvokeClosure(arguments, arguments_descriptor);
}
-RawObject* DartEntry::InvokeClosure(const Array& arguments,
- const Array& arguments_descriptor) {
+ObjectPtr DartEntry::InvokeClosure(const Array& arguments,
+ const Array& arguments_descriptor) {
Thread* thread = Thread::Current();
Zone* zone = thread->zone();
const ArgumentsDescriptor args_desc(arguments_descriptor);
@@ -269,10 +280,10 @@
arguments_descriptor);
}
-RawObject* DartEntry::InvokeNoSuchMethod(const Instance& receiver,
- const String& target_name,
- const Array& arguments,
- const Array& arguments_descriptor) {
+ObjectPtr DartEntry::InvokeNoSuchMethod(const Instance& receiver,
+ const String& target_name,
+ const Array& arguments,
+ const Array& arguments_descriptor) {
const ArgumentsDescriptor args_desc(arguments_descriptor);
ASSERT(receiver.raw() == arguments.At(args_desc.FirstArgIndex()));
// Allocate an Invocation object.
@@ -340,7 +351,7 @@
return Smi::Value(Smi::RawCast(array_.At(kPositionalCountIndex)));
}
-RawString* ArgumentsDescriptor::NameAt(intptr_t index) const {
+StringPtr ArgumentsDescriptor::NameAt(intptr_t index) const {
const intptr_t offset =
kFirstNamedEntryIndex + (index * kNamedEntrySize) + kNameOffset;
String& result = String::Handle();
@@ -359,7 +370,7 @@
return NameAt(index) == other.raw();
}
-RawArray* ArgumentsDescriptor::GetArgumentNames() const {
+ArrayPtr ArgumentsDescriptor::GetArgumentNames() const {
const intptr_t num_named_args = NamedCount();
if (num_named_args == 0) {
return Array::null();
@@ -379,11 +390,11 @@
return names.raw();
}
-RawArray* ArgumentsDescriptor::New(intptr_t type_args_len,
- intptr_t num_arguments,
- intptr_t size_arguments,
- const Array& optional_arguments_names,
- Heap::Space space) {
+ArrayPtr ArgumentsDescriptor::New(intptr_t type_args_len,
+ intptr_t num_arguments,
+ intptr_t size_arguments,
+ const Array& optional_arguments_names,
+ Heap::Space space) {
const intptr_t num_named_args =
optional_arguments_names.IsNull() ? 0 : optional_arguments_names.Length();
if (num_named_args == 0) {
@@ -453,10 +464,10 @@
return descriptor.raw();
}
-RawArray* ArgumentsDescriptor::New(intptr_t type_args_len,
- intptr_t num_arguments,
- intptr_t size_arguments,
- Heap::Space space) {
+ArrayPtr ArgumentsDescriptor::New(intptr_t type_args_len,
+ intptr_t num_arguments,
+ intptr_t size_arguments,
+ Heap::Space space) {
ASSERT(type_args_len >= 0);
ASSERT(num_arguments >= 0);
@@ -468,11 +479,11 @@
space);
}
-RawArray* ArgumentsDescriptor::NewNonCached(intptr_t type_args_len,
- intptr_t num_arguments,
- intptr_t size_arguments,
- bool canonicalize,
- Heap::Space space) {
+ArrayPtr ArgumentsDescriptor::NewNonCached(intptr_t type_args_len,
+ intptr_t num_arguments,
+ intptr_t size_arguments,
+ bool canonicalize,
+ Heap::Space space) {
// Build the arguments descriptor array, which consists of the length of the
// type argument vector, total argument count; the positional argument count;
// and a terminating null to simplify iterating in generated code.
@@ -526,10 +537,10 @@
}
}
-RawObject* DartLibraryCalls::InstanceCreate(const Library& lib,
- const String& class_name,
- const String& constructor_name,
- const Array& arguments) {
+ObjectPtr DartLibraryCalls::InstanceCreate(const Library& lib,
+ const String& class_name,
+ const String& constructor_name,
+ const Array& arguments) {
const Class& cls = Class::Handle(lib.LookupClassAllowPrivate(class_name));
ASSERT(!cls.IsNull());
// For now, we only support a non-parameterized or raw type.
@@ -558,7 +569,7 @@
return exception_object.raw();
}
-RawObject* DartLibraryCalls::ToString(const Instance& receiver) {
+ObjectPtr DartLibraryCalls::ToString(const Instance& receiver) {
const int kTypeArgsLen = 0;
const int kNumArguments = 1; // Receiver.
ArgumentsDescriptor args_desc(Array::Handle(
@@ -574,7 +585,7 @@
return result.raw();
}
-RawObject* DartLibraryCalls::HashCode(const Instance& receiver) {
+ObjectPtr DartLibraryCalls::HashCode(const Instance& receiver) {
const int kTypeArgsLen = 0;
const int kNumArguments = 1; // Receiver.
ArgumentsDescriptor args_desc(Array::Handle(
@@ -590,8 +601,8 @@
return result.raw();
}
-RawObject* DartLibraryCalls::Equals(const Instance& left,
- const Instance& right) {
+ObjectPtr DartLibraryCalls::Equals(const Instance& left,
+ const Instance& right) {
const int kTypeArgsLen = 0;
const int kNumArguments = 2;
ArgumentsDescriptor args_desc(Array::Handle(
@@ -610,7 +621,7 @@
}
// On success, returns a RawInstance. On failure, a RawError.
-RawObject* DartLibraryCalls::IdentityHashCode(const Instance& object) {
+ObjectPtr DartLibraryCalls::IdentityHashCode(const Instance& object) {
const int kNumArguments = 1;
Thread* thread = Thread::Current();
Zone* zone = thread->zone();
@@ -627,7 +638,7 @@
return result.raw();
}
-RawObject* DartLibraryCalls::LookupHandler(Dart_Port port_id) {
+ObjectPtr DartLibraryCalls::LookupHandler(Dart_Port port_id) {
Thread* thread = Thread::Current();
Zone* zone = thread->zone();
Function& function = Function::Handle(
@@ -654,8 +665,8 @@
return result.raw();
}
-RawObject* DartLibraryCalls::HandleMessage(const Object& handler,
- const Instance& message) {
+ObjectPtr DartLibraryCalls::HandleMessage(const Object& handler,
+ const Instance& message) {
Thread* thread = Thread::Current();
Zone* zone = thread->zone();
Isolate* isolate = thread->isolate();
@@ -693,7 +704,7 @@
return result.raw();
}
-RawObject* DartLibraryCalls::DrainMicrotaskQueue() {
+ObjectPtr DartLibraryCalls::DrainMicrotaskQueue() {
Zone* zone = Thread::Current()->zone();
Library& isolate_lib = Library::Handle(zone, Library::IsolateLibrary());
ASSERT(!isolate_lib.IsNull());
@@ -706,7 +717,7 @@
return result.raw();
}
-RawObject* DartLibraryCalls::EnsureScheduleImmediate() {
+ObjectPtr DartLibraryCalls::EnsureScheduleImmediate() {
Zone* zone = Thread::Current()->zone();
const Library& async_lib = Library::Handle(zone, Library::AsyncLibrary());
ASSERT(!async_lib.IsNull());
@@ -720,9 +731,9 @@
return result.raw();
}
-RawObject* DartLibraryCalls::MapSetAt(const Instance& map,
- const Instance& key,
- const Instance& value) {
+ObjectPtr DartLibraryCalls::MapSetAt(const Instance& map,
+ const Instance& key,
+ const Instance& value) {
const int kTypeArgsLen = 0;
const int kNumArguments = 3;
ArgumentsDescriptor args_desc(Array::Handle(
diff --git a/runtime/vm/dart_entry.h b/runtime/vm/dart_entry.h
index e93c991..9ab0115 100644
--- a/runtime/vm/dart_entry.h
+++ b/runtime/vm/dart_entry.h
@@ -20,10 +20,6 @@
class Integer;
class Library;
class Object;
-class RawArray;
-class RawInstance;
-class RawObject;
-class RawString;
class String;
// An arguments descriptor array consists of the type argument vector length (0
@@ -45,11 +41,11 @@
intptr_t SizeWithTypeArgs() const { return FirstArgIndex() + Size(); }
intptr_t PositionalCount() const; // Excluding type arguments vector.
intptr_t NamedCount() const { return Count() - PositionalCount(); }
- RawString* NameAt(intptr_t i) const;
+ StringPtr NameAt(intptr_t i) const;
intptr_t PositionAt(intptr_t i) const;
bool MatchesNameAt(intptr_t i, const String& other) const;
// Returns array of argument names in the arguments order.
- RawArray* GetArgumentNames() const;
+ ArrayPtr GetArgumentNames() const;
// Generated code support.
static intptr_t type_args_len_offset() {
@@ -78,10 +74,10 @@
// Right now this is for example the case for all closure functions.
// Functions marked as entry-points may also be created by NewUnboxed because
// we rely that TFA will mark the arguments as nullable for such cases.
- static RawArray* NewBoxed(intptr_t type_args_len,
- intptr_t num_arguments,
- const Array& optional_arguments_names,
- Heap::Space space = Heap::kOld) {
+ static ArrayPtr NewBoxed(intptr_t type_args_len,
+ intptr_t num_arguments,
+ const Array& optional_arguments_names,
+ Heap::Space space = Heap::kOld) {
return New(type_args_len, num_arguments, num_arguments,
optional_arguments_names, space);
}
@@ -91,19 +87,19 @@
// positional and the remaining ones are named optional arguments.
// The presence of a type argument vector as first argument (not counted in
// num_arguments) is indicated by a non-zero type_args_len.
- static RawArray* New(intptr_t type_args_len,
- intptr_t num_arguments,
- intptr_t size_arguments,
- const Array& optional_arguments_names,
- Heap::Space space = Heap::kOld);
+ static ArrayPtr New(intptr_t type_args_len,
+ intptr_t num_arguments,
+ intptr_t size_arguments,
+ const Array& optional_arguments_names,
+ Heap::Space space = Heap::kOld);
// Constructs an argument descriptor where all arguments are boxed and
// therefore number of parameters equals parameter size.
//
// Right now this is for example the case for all closure functions.
- static RawArray* NewBoxed(intptr_t type_args_len,
- intptr_t num_arguments,
- Heap::Space space = Heap::kOld) {
+ static ArrayPtr NewBoxed(intptr_t type_args_len,
+ intptr_t num_arguments,
+ Heap::Space space = Heap::kOld) {
return New(type_args_len, num_arguments, num_arguments, space);
}
@@ -111,10 +107,10 @@
// arguments. All arguments are positional. The presence of a type argument
// vector as first argument (not counted in num_arguments) is indicated
// by a non-zero type_args_len.
- static RawArray* New(intptr_t type_args_len,
- intptr_t num_arguments,
- intptr_t size_arguments,
- Heap::Space space = Heap::kOld);
+ static ArrayPtr New(intptr_t type_args_len,
+ intptr_t num_arguments,
+ intptr_t size_arguments,
+ Heap::Space space = Heap::kOld);
// Initialize the preallocated fixed length arguments descriptors cache.
static void Init();
@@ -152,11 +148,11 @@
return kFirstNamedEntryIndex + (kNamedEntrySize * num_named_arguments) + 1;
}
- static RawArray* NewNonCached(intptr_t type_args_len,
- intptr_t num_arguments,
- intptr_t size_arguments,
- bool canonicalize,
- Heap::Space space);
+ static ArrayPtr NewNonCached(intptr_t type_args_len,
+ intptr_t num_arguments,
+ intptr_t size_arguments,
+ bool canonicalize,
+ Heap::Space space);
// Used by Simulator to parse argument descriptors.
static intptr_t name_index(intptr_t index) {
@@ -170,7 +166,7 @@
const Array& array_;
// A cache of VM heap allocated arguments descriptors.
- static RawArray* cached_args_descriptors_[kCachedDescriptorCount];
+ static ArrayPtr cached_args_descriptors_[kCachedDescriptorCount];
friend class SnapshotReader;
friend class SnapshotWriter;
@@ -187,30 +183,24 @@
// and invoke them from C++.
class DartEntry : public AllStatic {
public:
- // On success, returns a RawInstance. On failure, a RawError.
- typedef RawObject* (*invokestub)(const Code& target_code,
- const Array& arguments_descriptor,
- const Array& arguments,
- Thread* thread);
-
// Invokes the specified instance function or static function.
// The first argument of an instance function is the receiver.
// On success, returns a RawInstance. On failure, a RawError.
// This is used when there is no type argument vector and
// no named arguments in the call.
- static RawObject* InvokeFunction(const Function& function,
- const Array& arguments);
+ static ObjectPtr InvokeFunction(const Function& function,
+ const Array& arguments);
// Invokes the specified code as if it was a Dart function.
// On success, returns a RawInstance. On failure, a RawError.
- static RawObject* InvokeCode(const Code& code,
- const Array& arguments_descriptor,
- const Array& arguments,
- Thread* thread);
+ static ObjectPtr InvokeCode(const Code& code,
+ const Array& arguments_descriptor,
+ const Array& arguments,
+ Thread* thread);
// Invokes the specified instance, static, or closure function.
// On success, returns a RawInstance. On failure, a RawError.
- static RawObject* InvokeFunction(
+ static ObjectPtr InvokeFunction(
const Function& function,
const Array& arguments,
const Array& arguments_descriptor,
@@ -220,19 +210,19 @@
// On success, returns a RawInstance. On failure, a RawError.
// This is used when there is no type argument vector and
// no named arguments in the call.
- static RawObject* InvokeClosure(const Array& arguments);
+ static ObjectPtr InvokeClosure(const Array& arguments);
// Invokes the closure object given as the first argument.
// On success, returns a RawInstance. On failure, a RawError.
- static RawObject* InvokeClosure(const Array& arguments,
- const Array& arguments_descriptor);
+ static ObjectPtr InvokeClosure(const Array& arguments,
+ const Array& arguments_descriptor);
// Invokes the noSuchMethod instance function on the receiver.
// On success, returns a RawInstance. On failure, a RawError.
- static RawObject* InvokeNoSuchMethod(const Instance& receiver,
- const String& target_name,
- const Array& arguments,
- const Array& arguments_descriptor);
+ static ObjectPtr InvokeNoSuchMethod(const Instance& receiver,
+ const String& target_name,
+ const Array& arguments,
+ const Array& arguments_descriptor);
};
// Utility functions to call from VM into Dart bootstrap libraries.
@@ -240,44 +230,44 @@
class DartLibraryCalls : public AllStatic {
public:
// On success, returns a RawInstance. On failure, a RawError.
- static RawObject* InstanceCreate(const Library& library,
- const String& exception_name,
- const String& constructor_name,
- const Array& arguments);
+ static ObjectPtr InstanceCreate(const Library& library,
+ const String& exception_name,
+ const String& constructor_name,
+ const Array& arguments);
// On success, returns a RawInstance. On failure, a RawError.
- static RawObject* ToString(const Instance& receiver);
+ static ObjectPtr ToString(const Instance& receiver);
// On success, returns a RawInstance. On failure, a RawError.
- static RawObject* HashCode(const Instance& receiver);
+ static ObjectPtr HashCode(const Instance& receiver);
// On success, returns a RawInstance. On failure, a RawError.
- static RawObject* Equals(const Instance& left, const Instance& right);
+ static ObjectPtr Equals(const Instance& left, const Instance& right);
// On success, returns a RawInstance. On failure, a RawError.
- static RawObject* IdentityHashCode(const Instance& object);
+ static ObjectPtr IdentityHashCode(const Instance& object);
// Returns the handler if one has been registered for this port id.
- static RawObject* LookupHandler(Dart_Port port_id);
+ static ObjectPtr LookupHandler(Dart_Port port_id);
// Returns null on success, a RawError on failure.
- static RawObject* HandleMessage(const Object& handler,
- const Instance& dart_message);
+ static ObjectPtr HandleMessage(const Object& handler,
+ const Instance& dart_message);
// Returns null on success, a RawError on failure.
- static RawObject* DrainMicrotaskQueue();
+ static ObjectPtr DrainMicrotaskQueue();
// Ensures that the isolate's _pendingImmediateCallback is set to
// _startMicrotaskLoop from dart:async.
// Returns null on success, a RawError on failure.
- static RawObject* EnsureScheduleImmediate();
+ static ObjectPtr EnsureScheduleImmediate();
// map[key] = value;
//
// Returns null on success, a RawError on failure.
- static RawObject* MapSetAt(const Instance& map,
- const Instance& key,
- const Instance& value);
+ static ObjectPtr MapSetAt(const Instance& map,
+ const Instance& key,
+ const Instance& value);
};
} // namespace dart
diff --git a/runtime/vm/debugger.cc b/runtime/vm/debugger.cc
index adb3591..0050f4f 100644
--- a/runtime/vm/debugger.cc
+++ b/runtime/vm/debugger.cc
@@ -150,13 +150,13 @@
}
void Breakpoint::VisitObjectPointers(ObjectPointerVisitor* visitor) {
- visitor->VisitPointer(reinterpret_cast<RawObject**>(&closure_));
+ visitor->VisitPointer(reinterpret_cast<ObjectPtr*>(&closure_));
}
void BreakpointLocation::VisitObjectPointers(ObjectPointerVisitor* visitor) {
- visitor->VisitPointer(reinterpret_cast<RawObject**>(&script_));
- visitor->VisitPointer(reinterpret_cast<RawObject**>(&url_));
- visitor->VisitPointer(reinterpret_cast<RawObject**>(&function_));
+ visitor->VisitPointer(reinterpret_cast<ObjectPtr*>(&script_));
+ visitor->VisitPointer(reinterpret_cast<ObjectPtr*>(&url_));
+ visitor->VisitPointer(reinterpret_cast<ObjectPtr*>(&function_));
Breakpoint* bpt = conditions_;
while (bpt != NULL) {
@@ -183,9 +183,9 @@
}
void CodeBreakpoint::VisitObjectPointers(ObjectPointerVisitor* visitor) {
- visitor->VisitPointer(reinterpret_cast<RawObject**>(&code_));
- visitor->VisitPointer(reinterpret_cast<RawObject**>(&bytecode_));
- visitor->VisitPointer(reinterpret_cast<RawObject**>(&saved_value_));
+ visitor->VisitPointer(reinterpret_cast<ObjectPtr*>(&code_));
+ visitor->VisitPointer(reinterpret_cast<ObjectPtr*>(&bytecode_));
+ visitor->VisitPointer(reinterpret_cast<ObjectPtr*>(&saved_value_));
}
ActivationFrame::ActivationFrame(uword pc,
@@ -333,15 +333,15 @@
Service::HandleEvent(event);
}
-RawError* Debugger::PauseInterrupted() {
+ErrorPtr Debugger::PauseInterrupted() {
return PauseRequest(ServiceEvent::kPauseInterrupted);
}
-RawError* Debugger::PausePostRequest() {
+ErrorPtr Debugger::PausePostRequest() {
return PauseRequest(ServiceEvent::kPausePostRequest);
}
-RawError* Debugger::PauseRequest(ServiceEvent::EventKind kind) {
+ErrorPtr Debugger::PauseRequest(ServiceEvent::EventKind kind) {
if (ignore_breakpoints_ || IsPaused()) {
// We don't let the isolate get interrupted if we are already
// paused or ignoring breakpoints.
@@ -361,7 +361,7 @@
// If any error occurred while in the debug message loop, return it here.
NoSafepointScope no_safepoint;
- RawError* error = Thread::Current()->StealStickyError();
+ ErrorPtr error = Thread::Current()->StealStickyError();
ASSERT((error == Error::null()) || error->IsUnwindError());
return error;
}
@@ -464,14 +464,14 @@
static bool IsImplicitFunction(const Function& func) {
switch (func.kind()) {
- case RawFunction::kImplicitGetter:
- case RawFunction::kImplicitSetter:
- case RawFunction::kImplicitStaticGetter:
- case RawFunction::kFieldInitializer:
- case RawFunction::kMethodExtractor:
- case RawFunction::kNoSuchMethodDispatcher:
- case RawFunction::kInvokeFieldDispatcher:
- case RawFunction::kIrregexpFunction:
+ case FunctionLayout::kImplicitGetter:
+ case FunctionLayout::kImplicitSetter:
+ case FunctionLayout::kImplicitStaticGetter:
+ case FunctionLayout::kFieldInitializer:
+ case FunctionLayout::kMethodExtractor:
+ case FunctionLayout::kNoSuchMethodDispatcher:
+ case FunctionLayout::kInvokeFieldDispatcher:
+ case FunctionLayout::kIrregexpFunction:
return true;
default:
if (func.token_pos() == func.end_token_pos()) {
@@ -610,20 +610,20 @@
return IsCalleeFrameOf(other_fp, fp()) ? kCallee : kCaller;
}
-RawString* ActivationFrame::QualifiedFunctionName() {
+StringPtr ActivationFrame::QualifiedFunctionName() {
return String::New(Debugger::QualifiedFunctionName(function()));
}
-RawString* ActivationFrame::SourceUrl() {
+StringPtr ActivationFrame::SourceUrl() {
const Script& script = Script::Handle(SourceScript());
return script.url();
}
-RawScript* ActivationFrame::SourceScript() {
+ScriptPtr ActivationFrame::SourceScript() {
return function().script();
}
-RawLibrary* ActivationFrame::Library() {
+LibraryPtr ActivationFrame::Library() {
const Class& cls = Class::Handle(function().origin());
return cls.library();
}
@@ -648,7 +648,7 @@
}
token_pos_ = TokenPosition::kNoSource;
GetPcDescriptors();
- PcDescriptors::Iterator iter(pc_desc_, RawPcDescriptors::kAnyKind);
+ PcDescriptors::Iterator iter(pc_desc_, PcDescriptorsLayout::kAnyKind);
const uword pc_offset = pc_ - code().PayloadStart();
while (iter.MoveNext()) {
if (iter.PcOffset() == pc_offset) {
@@ -806,10 +806,10 @@
intptr_t var_desc_len = var_descriptors_.Length();
bool found = false;
for (intptr_t cur_idx = 0; cur_idx < var_desc_len; cur_idx++) {
- RawLocalVarDescriptors::VarInfo var_info;
+ LocalVarDescriptorsLayout::VarInfo var_info;
var_descriptors_.GetInfo(cur_idx, &var_info);
const int8_t kind = var_info.kind();
- if ((kind == RawLocalVarDescriptors::kContextLevel) &&
+ if ((kind == LocalVarDescriptorsLayout::kContextLevel) &&
(deopt_id >= var_info.begin_pos.value()) &&
(deopt_id <= var_info.end_pos.value())) {
context_level_ = var_info.index();
@@ -826,7 +826,7 @@
return context_level_;
}
-RawObject* ActivationFrame::GetAsyncContextVariable(const String& name) {
+ObjectPtr ActivationFrame::GetAsyncContextVariable(const String& name) {
if (!function_.IsAsyncClosure() && !function_.IsAsyncGenClosure()) {
return Object::null();
}
@@ -835,18 +835,18 @@
intptr_t ctxt_slot = -1;
intptr_t var_desc_len = var_descriptors_.Length();
for (intptr_t i = 0; i < var_desc_len; i++) {
- RawLocalVarDescriptors::VarInfo var_info;
+ LocalVarDescriptorsLayout::VarInfo var_info;
var_descriptors_.GetInfo(i, &var_info);
if (var_descriptors_.GetName(i) == name.raw()) {
const int8_t kind = var_info.kind();
if (!live_frame_) {
- ASSERT(kind == RawLocalVarDescriptors::kContextVar);
+ ASSERT(kind == LocalVarDescriptorsLayout::kContextVar);
}
const auto variable_index = VariableIndex(var_info.index());
- if (kind == RawLocalVarDescriptors::kStackVar) {
+ if (kind == LocalVarDescriptorsLayout::kStackVar) {
return GetStackVar(variable_index);
} else {
- ASSERT(kind == RawLocalVarDescriptors::kContextVar);
+ ASSERT(kind == LocalVarDescriptorsLayout::kContextVar);
// Variable descriptors constructed from bytecode have all variables of
// enclosing functions, even shadowed by the current function.
// Pick the variable with the highest context level.
@@ -873,11 +873,11 @@
return Object::null();
}
-RawObject* ActivationFrame::GetAsyncCompleter() {
+ObjectPtr ActivationFrame::GetAsyncCompleter() {
return GetAsyncContextVariable(Symbols::AsyncCompleter());
}
-RawObject* ActivationFrame::GetAsyncCompleterAwaiter(const Object& completer) {
+ObjectPtr ActivationFrame::GetAsyncCompleterAwaiter(const Object& completer) {
DEBUG_ASSERT(Thread::Current()->TopErrorHandlerIsExitFrame());
Object& future = Object::Handle();
@@ -904,11 +904,11 @@
return Instance::Cast(future).GetField(awaiter_field);
}
-RawObject* ActivationFrame::GetAsyncStreamControllerStream() {
+ObjectPtr ActivationFrame::GetAsyncStreamControllerStream() {
return GetAsyncContextVariable(Symbols::ControllerStream());
}
-RawObject* ActivationFrame::GetAsyncStreamControllerStreamAwaiter(
+ObjectPtr ActivationFrame::GetAsyncStreamControllerStreamAwaiter(
const Object& stream) {
const Class& stream_cls = Class::Handle(stream.clazz());
ASSERT(!stream_cls.IsNull());
@@ -919,7 +919,7 @@
return Instance::Cast(stream).GetField(awaiter_field);
}
-RawObject* ActivationFrame::GetAsyncAwaiter() {
+ObjectPtr ActivationFrame::GetAsyncAwaiter() {
const Object& async_stream_controller_stream =
Object::Handle(GetAsyncStreamControllerStream());
if (!async_stream_controller_stream.IsNull()) {
@@ -933,7 +933,7 @@
return Object::null();
}
-RawObject* ActivationFrame::GetCausalStack() {
+ObjectPtr ActivationFrame::GetCausalStack() {
return GetAsyncContextVariable(Symbols::AsyncStackTraceVar());
}
@@ -992,11 +992,11 @@
intptr_t var_desc_len = var_descriptors_.Length();
intptr_t await_jump_var = -1;
for (intptr_t i = 0; i < var_desc_len; i++) {
- RawLocalVarDescriptors::VarInfo var_info;
+ LocalVarDescriptorsLayout::VarInfo var_info;
var_descriptors_.GetInfo(i, &var_info);
const int8_t kind = var_info.kind();
if (var_descriptors_.GetName(i) == Symbols::AwaitJumpVar().raw()) {
- ASSERT(kind == RawLocalVarDescriptors::kContextVar);
+ ASSERT(kind == LocalVarDescriptorsLayout::kContextVar);
ASSERT(!ctx_.IsNull());
// Variable descriptors constructed from bytecode have all variables of
// enclosing functions, even shadowed by the current function.
@@ -1065,7 +1065,7 @@
const auto& pc_descriptors =
PcDescriptors::Handle(zone, code().pc_descriptors());
ASSERT(!pc_descriptors.IsNull());
- PcDescriptors::Iterator it(pc_descriptors, RawPcDescriptors::kOther);
+ PcDescriptors::Iterator it(pc_descriptors, PcDescriptorsLayout::kOther);
while (it.MoveNext()) {
if (it.YieldIndex() == await_jump_var) {
try_index_ = it.TryIndex();
@@ -1101,10 +1101,10 @@
intptr_t var_desc_len = var_descriptors_.Length();
Object& obj = Object::Handle();
for (intptr_t i = 0; i < var_desc_len; i++) {
- RawLocalVarDescriptors::VarInfo var_info;
+ LocalVarDescriptorsLayout::VarInfo var_info;
var_descriptors_.GetInfo(i, &var_info);
const int8_t kind = var_info.kind();
- if (kind == RawLocalVarDescriptors::kSavedCurrentContext) {
+ if (kind == LocalVarDescriptorsLayout::kSavedCurrentContext) {
if (FLAG_trace_debugger_stacktrace) {
OS::PrintErr("\tFound saved current ctx at index %d\n",
var_info.index());
@@ -1128,7 +1128,7 @@
return ctx_;
}
-RawObject* ActivationFrame::GetAsyncOperation() {
+ObjectPtr ActivationFrame::GetAsyncOperation() {
if (function().name() == Symbols::AsyncOperation().raw()) {
return GetParameter(0);
}
@@ -1168,16 +1168,16 @@
intptr_t var_desc_len = var_descriptors_.Length();
for (intptr_t cur_idx = 0; cur_idx < var_desc_len; cur_idx++) {
ASSERT(var_names.length() == desc_indices_.length());
- RawLocalVarDescriptors::VarInfo var_info;
+ LocalVarDescriptorsLayout::VarInfo var_info;
var_descriptors_.GetInfo(cur_idx, &var_info);
const int8_t kind = var_info.kind();
- if ((kind != RawLocalVarDescriptors::kStackVar) &&
- (kind != RawLocalVarDescriptors::kContextVar)) {
+ if ((kind != LocalVarDescriptorsLayout::kStackVar) &&
+ (kind != LocalVarDescriptorsLayout::kContextVar)) {
continue;
}
if ((var_info.begin_pos <= activation_token_pos) &&
(activation_token_pos <= var_info.end_pos)) {
- if ((kind == RawLocalVarDescriptors::kContextVar) &&
+ if ((kind == LocalVarDescriptorsLayout::kContextVar) &&
(ContextLevel() < var_info.scope_id)) {
// The variable is textually in scope but the context level
// at the activation frame's PC is lower than the context
@@ -1198,7 +1198,7 @@
// Found two local variables with the same name. Now determine
// which one is shadowed.
name_match_found = true;
- RawLocalVarDescriptors::VarInfo i_var_info;
+ LocalVarDescriptorsLayout::VarInfo i_var_info;
var_descriptors_.GetInfo(desc_indices_[i], &i_var_info);
if (i_var_info.begin_pos < var_info.begin_pos) {
// The variable we found earlier is in an outer scope
@@ -1230,12 +1230,12 @@
return desc_indices_.length();
}
-DART_FORCE_INLINE static RawObject* GetVariableValue(uword addr) {
- return *reinterpret_cast<RawObject**>(addr);
+DART_FORCE_INLINE static ObjectPtr GetVariableValue(uword addr) {
+ return *reinterpret_cast<ObjectPtr*>(addr);
}
// Caution: GetParameter only works for fixed parameters.
-RawObject* ActivationFrame::GetParameter(intptr_t index) {
+ObjectPtr ActivationFrame::GetParameter(intptr_t index) {
intptr_t num_parameters = function().num_fixed_parameters();
ASSERT(0 <= index && index < num_parameters);
@@ -1264,12 +1264,12 @@
}
}
-RawObject* ActivationFrame::GetClosure() {
+ObjectPtr ActivationFrame::GetClosure() {
ASSERT(function().IsClosureFunction());
return GetParameter(0);
}
-RawObject* ActivationFrame::GetStackVar(VariableIndex variable_index) {
+ObjectPtr ActivationFrame::GetStackVar(VariableIndex variable_index) {
if (IsInterpreted()) {
intptr_t slot_index = -variable_index.value();
if (slot_index < 0) {
@@ -1364,7 +1364,7 @@
*name = var_descriptors_.GetName(desc_index);
- RawLocalVarDescriptors::VarInfo var_info;
+ LocalVarDescriptorsLayout::VarInfo var_info;
var_descriptors_.GetInfo(desc_index, &var_info);
ASSERT(declaration_token_pos != NULL);
*declaration_token_pos = var_info.declaration_pos;
@@ -1375,25 +1375,25 @@
ASSERT(value != NULL);
const int8_t kind = var_info.kind();
const auto variable_index = VariableIndex(var_info.index());
- if (kind == RawLocalVarDescriptors::kStackVar) {
+ if (kind == LocalVarDescriptorsLayout::kStackVar) {
*value = GetStackVar(variable_index);
} else {
- ASSERT(kind == RawLocalVarDescriptors::kContextVar);
+ ASSERT(kind == LocalVarDescriptorsLayout::kContextVar);
*value = GetContextVar(var_info.scope_id, variable_index.value());
}
}
-RawObject* ActivationFrame::GetContextVar(intptr_t var_ctx_level,
- intptr_t ctx_slot) {
+ObjectPtr ActivationFrame::GetContextVar(intptr_t var_ctx_level,
+ intptr_t ctx_slot) {
// The context level at the PC/token index of this activation frame.
intptr_t frame_ctx_level = ContextLevel();
return GetRelativeContextVar(var_ctx_level, ctx_slot, frame_ctx_level);
}
-RawObject* ActivationFrame::GetRelativeContextVar(intptr_t var_ctx_level,
- intptr_t ctx_slot,
- intptr_t frame_ctx_level) {
+ObjectPtr ActivationFrame::GetRelativeContextVar(intptr_t var_ctx_level,
+ intptr_t ctx_slot,
+ intptr_t frame_ctx_level) {
const Context& ctx = GetSavedCurrentContext();
// It's possible that ctx was optimized out as no locals were captured by the
@@ -1428,7 +1428,7 @@
}
}
-RawArray* ActivationFrame::GetLocalVariables() {
+ArrayPtr ActivationFrame::GetLocalVariables() {
GetDescIndices();
intptr_t num_variables = desc_indices_.length();
String& var_name = String::Handle();
@@ -1443,7 +1443,7 @@
return list.raw();
}
-RawObject* ActivationFrame::GetReceiver() {
+ObjectPtr ActivationFrame::GetReceiver() {
GetDescIndices();
intptr_t num_variables = desc_indices_.length();
String& var_name = String::Handle();
@@ -1466,7 +1466,7 @@
return (var_name.Length() >= 1) && (var_name.CharAt(0) == '_');
}
-RawObject* ActivationFrame::EvaluateCompiledExpression(
+ObjectPtr ActivationFrame::EvaluateCompiledExpression(
const ExternalTypedData& kernel_buffer,
const Array& type_definitions,
const Array& arguments,
@@ -1488,7 +1488,7 @@
}
}
-RawTypeArguments* ActivationFrame::BuildParameters(
+TypeArgumentsPtr ActivationFrame::BuildParameters(
const GrowableObjectArray& param_names,
const GrowableObjectArray& param_values,
const GrowableObjectArray& type_params_names) {
@@ -1720,14 +1720,14 @@
}
#endif // !defined(DART_PRECOMPILED_RUNTIME)
-const uint8_t kSafepointKind = RawPcDescriptors::kIcCall |
- RawPcDescriptors::kUnoptStaticCall |
- RawPcDescriptors::kRuntimeCall;
+const uint8_t kSafepointKind = PcDescriptorsLayout::kIcCall |
+ PcDescriptorsLayout::kUnoptStaticCall |
+ PcDescriptorsLayout::kRuntimeCall;
CodeBreakpoint::CodeBreakpoint(const Code& code,
TokenPosition token_pos,
uword pc,
- RawPcDescriptors::Kind kind)
+ PcDescriptorsLayout::Kind kind)
: code_(code.raw()),
bytecode_(Bytecode::null()),
token_pos_(token_pos),
@@ -1755,7 +1755,7 @@
is_enabled_(false),
bpt_location_(NULL),
next_(NULL),
- breakpoint_kind_(RawPcDescriptors::kAnyKind),
+ breakpoint_kind_(PcDescriptorsLayout::kAnyKind),
saved_value_(Code::null()) {
ASSERT(!bytecode.IsNull());
ASSERT(FLAG_enable_interpreter);
@@ -1773,11 +1773,11 @@
pc_ = 0ul;
bpt_location_ = NULL;
next_ = NULL;
- breakpoint_kind_ = RawPcDescriptors::kOther;
+ breakpoint_kind_ = PcDescriptorsLayout::kOther;
#endif
}
-RawFunction* CodeBreakpoint::function() const {
+FunctionPtr CodeBreakpoint::function() const {
if (IsInterpreted()) {
ASSERT(Bytecode::Handle(bytecode_).function() != Function::null());
return Bytecode::Handle(bytecode_).function();
@@ -1786,12 +1786,12 @@
}
}
-RawScript* CodeBreakpoint::SourceCode() {
+ScriptPtr CodeBreakpoint::SourceCode() {
const Function& func = Function::Handle(this->function());
return func.script();
}
-RawString* CodeBreakpoint::SourceUrl() {
+StringPtr CodeBreakpoint::SourceUrl() {
const Script& script = Script::Handle(SourceCode());
return script.url();
}
@@ -2086,9 +2086,9 @@
return activation;
}
-RawArray* Debugger::DeoptimizeToArray(Thread* thread,
- StackFrame* frame,
- const Code& code) {
+ArrayPtr Debugger::DeoptimizeToArray(Thread* thread,
+ StackFrame* frame,
+ const Code& code) {
ASSERT(code.is_optimized() && !code.is_force_optimized());
Isolate* isolate = thread->isolate();
// Create the DeoptContext for this deoptimization.
@@ -3236,7 +3236,7 @@
ASSERT(!code.IsNull());
PcDescriptors& desc = PcDescriptors::Handle(code.pc_descriptors());
uword lowest_pc_offset = kUwordMax;
- RawPcDescriptors::Kind lowest_kind = RawPcDescriptors::kAnyKind;
+ PcDescriptorsLayout::Kind lowest_kind = PcDescriptorsLayout::kAnyKind;
// Find the safe point with the lowest compiled code address
// that maps to the token position of the source breakpoint.
PcDescriptors::Iterator iter(desc, kSafepointKind);
@@ -3877,7 +3877,7 @@
cbpt->VisitObjectPointers(visitor);
cbpt = cbpt->next();
}
- visitor->VisitPointer(reinterpret_cast<RawObject**>(&top_frame_awaiter_));
+ visitor->VisitPointer(reinterpret_cast<ObjectPtr*>(&top_frame_awaiter_));
}
void Debugger::Pause(ServiceEvent* event) {
@@ -4140,12 +4140,12 @@
const PcDescriptors& descriptors =
PcDescriptors::Handle(code.pc_descriptors());
PcDescriptors::Iterator iter(
- descriptors, RawPcDescriptors::kRewind | RawPcDescriptors::kIcCall |
- RawPcDescriptors::kUnoptStaticCall);
+ descriptors, PcDescriptorsLayout::kRewind | PcDescriptorsLayout::kIcCall |
+ PcDescriptorsLayout::kUnoptStaticCall);
intptr_t rewind_deopt_id = -1;
uword rewind_pc = 0;
while (iter.MoveNext()) {
- if (iter.Kind() == RawPcDescriptors::kRewind) {
+ if (iter.Kind() == PcDescriptorsLayout::kRewind) {
// Remember the last rewind so we don't need to iterator twice.
rewind_pc = code.PayloadStart() + iter.PcOffset();
rewind_deopt_id = iter.DeoptId();
@@ -4435,10 +4435,10 @@
return false;
}
const TokenPosition looking_for = top_frame->TokenPos();
- PcDescriptors::Iterator it(pc_descriptors, RawPcDescriptors::kOther);
+ PcDescriptors::Iterator it(pc_descriptors, PcDescriptorsLayout::kOther);
while (it.MoveNext()) {
if (it.TokenPos() == looking_for &&
- it.YieldIndex() != RawPcDescriptors::kInvalidYieldIndex) {
+ it.YieldIndex() != PcDescriptorsLayout::kInvalidYieldIndex) {
return true;
}
}
@@ -4446,7 +4446,7 @@
return false;
}
-RawError* Debugger::PauseStepping() {
+ErrorPtr Debugger::PauseStepping() {
ASSERT(isolate_->single_step());
// Don't pause recursively.
if (IsPaused()) {
@@ -4562,7 +4562,7 @@
return Thread::Current()->StealStickyError();
}
-RawError* Debugger::PauseBreakpoint() {
+ErrorPtr Debugger::PauseBreakpoint() {
// We ignore this breakpoint when the VM is executing code invoked
// by the debugger to evaluate variables values, or when we see a nested
// breakpoint or exception event.
@@ -4717,8 +4717,8 @@
// Return innermost closure contained in 'function' that contains
// the given token position.
-RawFunction* Debugger::FindInnermostClosure(const Function& function,
- TokenPosition token_pos) {
+FunctionPtr Debugger::FindInnermostClosure(const Function& function,
+ TokenPosition token_pos) {
Zone* zone = Thread::Current()->zone();
const Script& outer_origin = Script::Handle(zone, function.script());
const GrowableObjectArray& closures = GrowableObjectArray::Handle(
@@ -5015,7 +5015,7 @@
return NULL;
}
-RawCode* Debugger::GetPatchedStubAddress(uword breakpoint_address) {
+CodePtr Debugger::GetPatchedStubAddress(uword breakpoint_address) {
CodeBreakpoint* cbpt = GetCodeBreakpoint(breakpoint_address);
if (cbpt != NULL) {
return cbpt->OrigStubAddress();
diff --git a/runtime/vm/debugger.h b/runtime/vm/debugger.h
index 9536669..2a5bd90 100644
--- a/runtime/vm/debugger.h
+++ b/runtime/vm/debugger.h
@@ -58,7 +58,7 @@
bool IsRepeated() const { return kind_ == kRepeated; }
bool IsSingleShot() const { return kind_ == kSingleShot; }
bool IsPerClosure() const { return kind_ == kPerClosure; }
- RawInstance* closure() const { return closure_; }
+ InstancePtr closure() const { return closure_; }
void SetIsRepeated() {
ASSERT(kind_ == kNone);
@@ -97,7 +97,7 @@
intptr_t id_;
ConditionKind kind_;
Breakpoint* next_;
- RawInstance* closure_;
+ InstancePtr closure_;
BreakpointLocation* bpt_location_;
bool is_synthetic_async_;
@@ -131,12 +131,12 @@
~BreakpointLocation();
- RawFunction* function() const { return function_; }
+ FunctionPtr function() const { return function_; }
TokenPosition token_pos() const { return token_pos_; }
TokenPosition end_token_pos() const { return end_token_pos_; }
- RawScript* script() const { return script_; }
- RawString* url() const { return url_; }
+ ScriptPtr script() const { return script_; }
+ StringPtr url() const { return url_; }
intptr_t requested_line_number() const { return requested_line_number_; }
intptr_t requested_column_number() const { return requested_column_number_; }
@@ -174,8 +174,8 @@
Breakpoint* breakpoints() const { return this->conditions_; }
void set_breakpoints(Breakpoint* head) { this->conditions_ = head; }
- RawScript* script_;
- RawString* url_;
+ ScriptPtr script_;
+ StringPtr url_;
TokenPosition token_pos_;
TokenPosition end_token_pos_;
BreakpointLocation* next_;
@@ -184,7 +184,7 @@
intptr_t requested_column_number_;
// Valid for resolved breakpoints:
- RawFunction* function_;
+ FunctionPtr function_;
TokenPosition bytecode_token_pos_;
TokenPosition code_token_pos_;
@@ -200,16 +200,16 @@
CodeBreakpoint(const Code& code,
TokenPosition token_pos,
uword pc,
- RawPcDescriptors::Kind kind);
+ PcDescriptorsLayout::Kind kind);
CodeBreakpoint(const Bytecode& bytecode, TokenPosition token_pos, uword pc);
~CodeBreakpoint();
- RawFunction* function() const;
+ FunctionPtr function() const;
uword pc() const { return pc_; }
TokenPosition token_pos() const { return token_pos_; }
- RawScript* SourceCode();
- RawString* SourceUrl();
+ ScriptPtr SourceCode();
+ StringPtr SourceUrl();
intptr_t LineNumber();
void Enable();
@@ -217,7 +217,7 @@
bool IsEnabled() const { return is_enabled_; }
bool IsInterpreted() const { return bytecode_ != Bytecode::null(); }
- RawCode* OrigStubAddress() const;
+ CodePtr OrigStubAddress() const;
private:
void VisitObjectPointers(ObjectPointerVisitor* visitor);
@@ -233,8 +233,8 @@
void SetBytecodeBreakpoint();
void UnsetBytecodeBreakpoint();
- RawCode* code_;
- RawBytecode* bytecode_;
+ CodePtr code_;
+ BytecodePtr bytecode_;
TokenPosition token_pos_;
uword pc_;
intptr_t line_number_;
@@ -243,8 +243,8 @@
BreakpointLocation* bpt_location_;
CodeBreakpoint* next_;
- RawPcDescriptors::Kind breakpoint_kind_;
- RawCode* saved_value_;
+ PcDescriptorsLayout::Kind breakpoint_kind_;
+ CodePtr saved_value_;
friend class Debugger;
DISALLOW_COPY_AND_ASSIGN(CodeBreakpoint);
@@ -309,10 +309,10 @@
Relation CompareTo(uword other_fp, bool other_is_interpreted) const;
- RawString* QualifiedFunctionName();
- RawString* SourceUrl();
- RawScript* SourceScript();
- RawLibrary* Library();
+ StringPtr QualifiedFunctionName();
+ StringPtr SourceUrl();
+ ScriptPtr SourceScript();
+ LibraryPtr Library();
TokenPosition TokenPos();
intptr_t LineNumber();
intptr_t ColumnNumber();
@@ -340,28 +340,28 @@
TokenPosition* visible_end_token_pos,
Object* value);
- RawArray* GetLocalVariables();
- RawObject* GetParameter(intptr_t index);
- RawObject* GetClosure();
- RawObject* GetReceiver();
+ ArrayPtr GetLocalVariables();
+ ObjectPtr GetParameter(intptr_t index);
+ ObjectPtr GetClosure();
+ ObjectPtr GetReceiver();
const Context& GetSavedCurrentContext();
- RawObject* GetAsyncOperation();
+ ObjectPtr GetAsyncOperation();
- RawTypeArguments* BuildParameters(
+ TypeArgumentsPtr BuildParameters(
const GrowableObjectArray& param_names,
const GrowableObjectArray& param_values,
const GrowableObjectArray& type_params_names);
- RawObject* EvaluateCompiledExpression(const ExternalTypedData& kernel_data,
- const Array& arguments,
- const Array& type_definitions,
- const TypeArguments& type_arguments);
+ ObjectPtr EvaluateCompiledExpression(const ExternalTypedData& kernel_data,
+ const Array& arguments,
+ const Array& type_definitions,
+ const TypeArguments& type_arguments);
void PrintToJSONObject(JSONObject* jsobj);
- RawObject* GetAsyncAwaiter();
- RawObject* GetCausalStack();
+ ObjectPtr GetAsyncAwaiter();
+ ObjectPtr GetCausalStack();
bool HandlesException(const Instance& exc_obj);
@@ -381,11 +381,11 @@
void GetVarDescriptors();
void GetDescIndices();
- RawObject* GetAsyncContextVariable(const String& name);
- RawObject* GetAsyncStreamControllerStreamAwaiter(const Object& stream);
- RawObject* GetAsyncStreamControllerStream();
- RawObject* GetAsyncCompleterAwaiter(const Object& completer);
- RawObject* GetAsyncCompleter();
+ ObjectPtr GetAsyncContextVariable(const String& name);
+ ObjectPtr GetAsyncStreamControllerStreamAwaiter(const Object& stream);
+ ObjectPtr GetAsyncStreamControllerStream();
+ ObjectPtr GetAsyncCompleterAwaiter(const Object& completer);
+ ObjectPtr GetAsyncCompleter();
intptr_t GetAwaitJumpVariable();
void ExtractTokenPositionFromAsyncClosure();
@@ -407,11 +407,11 @@
}
}
- RawObject* GetStackVar(VariableIndex var_index);
- RawObject* GetRelativeContextVar(intptr_t ctxt_level,
- intptr_t slot_index,
- intptr_t frame_ctx_level);
- RawObject* GetContextVar(intptr_t ctxt_level, intptr_t slot_index);
+ ObjectPtr GetStackVar(VariableIndex var_index);
+ ObjectPtr GetRelativeContextVar(intptr_t ctxt_level,
+ intptr_t slot_index,
+ intptr_t frame_ctx_level);
+ ObjectPtr GetContextVar(intptr_t ctxt_level, intptr_t slot_index);
uword pc_;
uword fp_;
@@ -602,16 +602,16 @@
static const char* QualifiedFunctionName(const Function& func);
// Pause execution for a breakpoint. Called from generated code.
- RawError* PauseBreakpoint();
+ ErrorPtr PauseBreakpoint();
// Pause execution due to stepping. Called from generated code.
- RawError* PauseStepping();
+ ErrorPtr PauseStepping();
// Pause execution due to isolate interrupt.
- RawError* PauseInterrupted();
+ ErrorPtr PauseInterrupted();
// Pause after a reload request.
- RawError* PausePostRequest();
+ ErrorPtr PausePostRequest();
// Pause execution due to an uncaught exception.
void PauseException(const Instance& exc);
@@ -620,7 +620,7 @@
// Dart.
void PauseDeveloper(const String& msg);
- RawCode* GetPatchedStubAddress(uword breakpoint_address);
+ CodePtr GetPatchedStubAddress(uword breakpoint_address);
void PrintBreakpointsToJSONArray(JSONArray* jsarr) const;
void PrintSettingsToJSONObject(JSONObject* jsobj) const;
@@ -636,7 +636,7 @@
static DebuggerStackTrace* CollectAwaiterReturnStackTrace();
private:
- RawError* PauseRequest(ServiceEvent::EventKind kind);
+ ErrorPtr PauseRequest(ServiceEvent::EventKind kind);
// Finds the breakpoint we hit at |location|.
Breakpoint* FindHitBreakpoint(BreakpointLocation* location,
@@ -661,8 +661,8 @@
TokenPosition token_pos,
TokenPosition last_token_pos,
Function* best_fit);
- RawFunction* FindInnermostClosure(const Function& function,
- TokenPosition token_pos);
+ FunctionPtr FindInnermostClosure(const Function& function,
+ TokenPosition token_pos);
TokenPosition ResolveBreakpointPos(bool in_bytecode,
const Function& func,
TokenPosition requested_token_pos,
@@ -728,9 +728,9 @@
StackFrame* frame,
const Bytecode& bytecode,
ActivationFrame::Kind kind = ActivationFrame::kRegular);
- static RawArray* DeoptimizeToArray(Thread* thread,
- StackFrame* frame,
- const Code& code);
+ static ArrayPtr DeoptimizeToArray(Thread* thread,
+ StackFrame* frame,
+ const Code& code);
TokenPosition FindExactTokenPosition(const Script& script,
TokenPosition start_of_line,
intptr_t column_number);
@@ -828,7 +828,7 @@
// Used to track the current async/async* function.
uword async_stepping_fp_;
bool interpreted_async_stepping_;
- RawObject* top_frame_awaiter_;
+ ObjectPtr top_frame_awaiter_;
// If we step while at a breakpoint, we would hit the same pc twice.
// We use this field to let us skip the next single-step after a
diff --git a/runtime/vm/debugger_arm.cc b/runtime/vm/debugger_arm.cc
index 15d95ba..9862592 100644
--- a/runtime/vm/debugger_arm.cc
+++ b/runtime/vm/debugger_arm.cc
@@ -15,7 +15,7 @@
#ifndef PRODUCT
-RawCode* CodeBreakpoint::OrigStubAddress() const {
+CodePtr CodeBreakpoint::OrigStubAddress() const {
return saved_value_;
}
@@ -23,13 +23,13 @@
ASSERT(!is_enabled_);
Code& stub_target = Code::Handle();
switch (breakpoint_kind_) {
- case RawPcDescriptors::kIcCall:
+ case PcDescriptorsLayout::kIcCall:
stub_target = StubCode::ICCallBreakpoint().raw();
break;
- case RawPcDescriptors::kUnoptStaticCall:
+ case PcDescriptorsLayout::kUnoptStaticCall:
stub_target = StubCode::UnoptStaticCallBreakpoint().raw();
break;
- case RawPcDescriptors::kRuntimeCall:
+ case PcDescriptorsLayout::kRuntimeCall:
stub_target = StubCode::RuntimeCallBreakpoint().raw();
break;
default:
@@ -45,9 +45,9 @@
ASSERT(is_enabled_);
const Code& code = Code::Handle(code_);
switch (breakpoint_kind_) {
- case RawPcDescriptors::kIcCall:
- case RawPcDescriptors::kUnoptStaticCall:
- case RawPcDescriptors::kRuntimeCall: {
+ case PcDescriptorsLayout::kIcCall:
+ case PcDescriptorsLayout::kUnoptStaticCall:
+ case PcDescriptorsLayout::kRuntimeCall: {
CodePatcher::PatchStaticCallAt(pc_, code, Code::Handle(saved_value_));
break;
}
diff --git a/runtime/vm/debugger_arm64.cc b/runtime/vm/debugger_arm64.cc
index e9748ca..dc132f8 100644
--- a/runtime/vm/debugger_arm64.cc
+++ b/runtime/vm/debugger_arm64.cc
@@ -15,7 +15,7 @@
#ifndef PRODUCT
-RawCode* CodeBreakpoint::OrigStubAddress() const {
+CodePtr CodeBreakpoint::OrigStubAddress() const {
return saved_value_;
}
@@ -23,20 +23,20 @@
ASSERT(!is_enabled_);
const Code& code = Code::Handle(code_);
switch (breakpoint_kind_) {
- case RawPcDescriptors::kIcCall: {
+ case PcDescriptorsLayout::kIcCall: {
Object& data = Object::Handle();
saved_value_ = CodePatcher::GetInstanceCallAt(pc_, code, &data);
CodePatcher::PatchInstanceCallAt(pc_, code, data,
StubCode::ICCallBreakpoint());
break;
}
- case RawPcDescriptors::kUnoptStaticCall: {
+ case PcDescriptorsLayout::kUnoptStaticCall: {
saved_value_ = CodePatcher::GetStaticCallTargetAt(pc_, code);
CodePatcher::PatchPoolPointerCallAt(
pc_, code, StubCode::UnoptStaticCallBreakpoint());
break;
}
- case RawPcDescriptors::kRuntimeCall: {
+ case PcDescriptorsLayout::kRuntimeCall: {
saved_value_ = CodePatcher::GetStaticCallTargetAt(pc_, code);
CodePatcher::PatchPoolPointerCallAt(pc_, code,
StubCode::RuntimeCallBreakpoint());
@@ -52,15 +52,15 @@
ASSERT(is_enabled_);
const Code& code = Code::Handle(code_);
switch (breakpoint_kind_) {
- case RawPcDescriptors::kIcCall: {
+ case PcDescriptorsLayout::kIcCall: {
Object& data = Object::Handle();
CodePatcher::GetInstanceCallAt(pc_, code, &data);
CodePatcher::PatchInstanceCallAt(pc_, code, data,
Code::Handle(saved_value_));
break;
}
- case RawPcDescriptors::kUnoptStaticCall:
- case RawPcDescriptors::kRuntimeCall: {
+ case PcDescriptorsLayout::kUnoptStaticCall:
+ case PcDescriptorsLayout::kRuntimeCall: {
CodePatcher::PatchPoolPointerCallAt(pc_, code,
Code::Handle(saved_value_));
break;
diff --git a/runtime/vm/debugger_ia32.cc b/runtime/vm/debugger_ia32.cc
index 8b1eb8a..d580561 100644
--- a/runtime/vm/debugger_ia32.cc
+++ b/runtime/vm/debugger_ia32.cc
@@ -19,7 +19,7 @@
#ifndef PRODUCT
-RawCode* CodeBreakpoint::OrigStubAddress() const {
+CodePtr CodeBreakpoint::OrigStubAddress() const {
return saved_value_;
}
@@ -33,15 +33,15 @@
thread->isolate_group()->RunWithStoppedMutators([&]() {
WritableInstructionsScope writable(instrs.PayloadStart(), instrs.Size());
switch (breakpoint_kind_) {
- case RawPcDescriptors::kIcCall: {
+ case PcDescriptorsLayout::kIcCall: {
stub_target = StubCode::ICCallBreakpoint().raw();
break;
}
- case RawPcDescriptors::kUnoptStaticCall: {
+ case PcDescriptorsLayout::kUnoptStaticCall: {
stub_target = StubCode::UnoptStaticCallBreakpoint().raw();
break;
}
- case RawPcDescriptors::kRuntimeCall: {
+ case PcDescriptorsLayout::kRuntimeCall: {
saved_value_ = CodePatcher::GetStaticCallTargetAt(pc_, code);
stub_target = StubCode::RuntimeCallBreakpoint().raw();
break;
@@ -64,9 +64,9 @@
thread->isolate_group()->RunWithStoppedMutators([&]() {
WritableInstructionsScope writable(instrs.PayloadStart(), instrs.Size());
switch (breakpoint_kind_) {
- case RawPcDescriptors::kIcCall:
- case RawPcDescriptors::kUnoptStaticCall:
- case RawPcDescriptors::kRuntimeCall: {
+ case PcDescriptorsLayout::kIcCall:
+ case PcDescriptorsLayout::kUnoptStaticCall:
+ case PcDescriptorsLayout::kRuntimeCall: {
CodePatcher::PatchStaticCallAt(pc_, code, Code::Handle(saved_value_));
break;
}
diff --git a/runtime/vm/debugger_x64.cc b/runtime/vm/debugger_x64.cc
index 3cd1810..dfb07df 100644
--- a/runtime/vm/debugger_x64.cc
+++ b/runtime/vm/debugger_x64.cc
@@ -16,7 +16,7 @@
#ifndef PRODUCT
-RawCode* CodeBreakpoint::OrigStubAddress() const {
+CodePtr CodeBreakpoint::OrigStubAddress() const {
return saved_value_;
}
@@ -24,13 +24,13 @@
ASSERT(!is_enabled_);
Code& stub_target = Code::Handle();
switch (breakpoint_kind_) {
- case RawPcDescriptors::kIcCall:
+ case PcDescriptorsLayout::kIcCall:
stub_target = StubCode::ICCallBreakpoint().raw();
break;
- case RawPcDescriptors::kUnoptStaticCall:
+ case PcDescriptorsLayout::kUnoptStaticCall:
stub_target = StubCode::UnoptStaticCallBreakpoint().raw();
break;
- case RawPcDescriptors::kRuntimeCall:
+ case PcDescriptorsLayout::kRuntimeCall:
stub_target = StubCode::RuntimeCallBreakpoint().raw();
break;
default:
@@ -46,9 +46,9 @@
ASSERT(is_enabled_);
const Code& code = Code::Handle(code_);
switch (breakpoint_kind_) {
- case RawPcDescriptors::kIcCall:
- case RawPcDescriptors::kUnoptStaticCall:
- case RawPcDescriptors::kRuntimeCall: {
+ case PcDescriptorsLayout::kIcCall:
+ case PcDescriptorsLayout::kUnoptStaticCall:
+ case PcDescriptorsLayout::kRuntimeCall: {
CodePatcher::PatchPoolPointerCallAt(pc_, code,
Code::Handle(saved_value_));
break;
diff --git a/runtime/vm/deferred_objects.cc b/runtime/vm/deferred_objects.cc
index 2072c77..8e4b4c8 100644
--- a/runtime/vm/deferred_objects.cc
+++ b/runtime/vm/deferred_objects.cc
@@ -18,7 +18,7 @@
DECLARE_FLAG(bool, trace_deoptimization_verbose);
void DeferredDouble::Materialize(DeoptContext* deopt_context) {
- RawDouble** double_slot = reinterpret_cast<RawDouble**>(slot());
+ DoublePtr* double_slot = reinterpret_cast<DoublePtr*>(slot());
*double_slot = Double::New(value());
if (FLAG_trace_deoptimization_verbose) {
@@ -28,7 +28,7 @@
}
void DeferredMint::Materialize(DeoptContext* deopt_context) {
- RawMint** mint_slot = reinterpret_cast<RawMint**>(slot());
+ MintPtr* mint_slot = reinterpret_cast<MintPtr*>(slot());
ASSERT(!Smi::IsValid(value()));
Mint& mint = Mint::Handle();
mint ^= Integer::New(value());
@@ -41,43 +41,43 @@
}
void DeferredFloat32x4::Materialize(DeoptContext* deopt_context) {
- RawFloat32x4** float32x4_slot = reinterpret_cast<RawFloat32x4**>(slot());
- RawFloat32x4* raw_float32x4 = Float32x4::New(value());
+ Float32x4Ptr* float32x4_slot = reinterpret_cast<Float32x4Ptr*>(slot());
+ Float32x4Ptr raw_float32x4 = Float32x4::New(value());
*float32x4_slot = raw_float32x4;
if (FLAG_trace_deoptimization_verbose) {
- float x = raw_float32x4->x();
- float y = raw_float32x4->y();
- float z = raw_float32x4->z();
- float w = raw_float32x4->w();
+ float x = raw_float32x4->ptr()->x();
+ float y = raw_float32x4->ptr()->y();
+ float z = raw_float32x4->ptr()->z();
+ float w = raw_float32x4->ptr()->w();
OS::PrintErr("materializing Float32x4 at %" Px ": %g,%g,%g,%g\n",
reinterpret_cast<uword>(slot()), x, y, z, w);
}
}
void DeferredFloat64x2::Materialize(DeoptContext* deopt_context) {
- RawFloat64x2** float64x2_slot = reinterpret_cast<RawFloat64x2**>(slot());
- RawFloat64x2* raw_float64x2 = Float64x2::New(value());
+ Float64x2Ptr* float64x2_slot = reinterpret_cast<Float64x2Ptr*>(slot());
+ Float64x2Ptr raw_float64x2 = Float64x2::New(value());
*float64x2_slot = raw_float64x2;
if (FLAG_trace_deoptimization_verbose) {
- double x = raw_float64x2->x();
- double y = raw_float64x2->y();
+ double x = raw_float64x2->ptr()->x();
+ double y = raw_float64x2->ptr()->y();
OS::PrintErr("materializing Float64x2 at %" Px ": %g,%g\n",
reinterpret_cast<uword>(slot()), x, y);
}
}
void DeferredInt32x4::Materialize(DeoptContext* deopt_context) {
- RawInt32x4** int32x4_slot = reinterpret_cast<RawInt32x4**>(slot());
- RawInt32x4* raw_int32x4 = Int32x4::New(value());
+ Int32x4Ptr* int32x4_slot = reinterpret_cast<Int32x4Ptr*>(slot());
+ Int32x4Ptr raw_int32x4 = Int32x4::New(value());
*int32x4_slot = raw_int32x4;
if (FLAG_trace_deoptimization_verbose) {
- uint32_t x = raw_int32x4->x();
- uint32_t y = raw_int32x4->y();
- uint32_t z = raw_int32x4->z();
- uint32_t w = raw_int32x4->w();
+ uint32_t x = raw_int32x4->ptr()->x();
+ uint32_t y = raw_int32x4->ptr()->y();
+ uint32_t z = raw_int32x4->ptr()->z();
+ uint32_t w = raw_int32x4->ptr()->w();
OS::PrintErr("materializing Int32x4 at %" Px ": %x,%x,%x,%x\n",
reinterpret_cast<uword>(slot()), x, y, z, w);
}
@@ -107,7 +107,7 @@
const Code& code = Code::Handle(zone, function.unoptimized_code());
uword continue_at_pc =
- code.GetPcForDeoptId(deopt_id_, RawPcDescriptors::kDeopt);
+ code.GetPcForDeoptId(deopt_id_, PcDescriptorsLayout::kDeopt);
if (continue_at_pc == 0) {
FATAL2("Can't locate continuation PC for deoptid %" Pd " within %s\n",
deopt_id_, function.ToFullyQualifiedCString());
@@ -120,7 +120,7 @@
reinterpret_cast<uword>(slot()), continue_at_pc);
}
- uword pc = code.GetPcForDeoptId(deopt_id_, RawPcDescriptors::kIcCall);
+ uword pc = code.GetPcForDeoptId(deopt_id_, PcDescriptorsLayout::kIcCall);
if (pc != 0) {
// If the deoptimization happened at an IC call, update the IC data
// to avoid repeated deoptimization at the same site next time around.
@@ -160,7 +160,7 @@
const Code& code = Code::Handle(zone, function.unoptimized_code());
ASSERT(!code.IsNull());
ASSERT(function.HasCode());
- *reinterpret_cast<RawObject**>(dest_addr) = code.raw();
+ *reinterpret_cast<ObjectPtr*>(dest_addr) = code.raw();
if (FLAG_trace_deoptimization_verbose) {
THR_Print("materializing pc marker at 0x%" Px ": %s, %s\n",
@@ -205,11 +205,11 @@
if (FLAG_trace_deoptimization_verbose) {
OS::PrintErr("materializing pp at 0x%" Px ": 0x%" Px "\n",
reinterpret_cast<uword>(slot()),
- reinterpret_cast<uword>(code.GetObjectPool()));
+ static_cast<uword>(code.GetObjectPool()));
}
}
-RawObject* DeferredObject::object() {
+ObjectPtr DeferredObject::object() {
if (object_ == NULL) {
Create();
}
diff --git a/runtime/vm/deferred_objects.h b/runtime/vm/deferred_objects.h
index a46be13..f50c09a 100644
--- a/runtime/vm/deferred_objects.h
+++ b/runtime/vm/deferred_objects.h
@@ -6,13 +6,12 @@
#define RUNTIME_VM_DEFERRED_OBJECTS_H_
#include "platform/globals.h"
+#include "vm/tagged_pointer.h"
namespace dart {
// Forward declarations.
class Object;
-class RawObject;
-class RawObject;
class DeoptContext;
// Used by the deoptimization infrastructure to defer allocation of
@@ -21,17 +20,17 @@
// the materialized object.
class DeferredSlot {
public:
- DeferredSlot(RawObject** slot, DeferredSlot* next)
+ DeferredSlot(ObjectPtr* slot, DeferredSlot* next)
: slot_(slot), next_(next) {}
virtual ~DeferredSlot() {}
- RawObject** slot() const { return slot_; }
+ ObjectPtr* slot() const { return slot_; }
DeferredSlot* next() const { return next_; }
virtual void Materialize(DeoptContext* deopt_context) = 0;
private:
- RawObject** const slot_;
+ ObjectPtr* const slot_;
DeferredSlot* const next_;
DISALLOW_COPY_AND_ASSIGN(DeferredSlot);
@@ -39,7 +38,7 @@
class DeferredDouble : public DeferredSlot {
public:
- DeferredDouble(double value, RawObject** slot, DeferredSlot* next)
+ DeferredDouble(double value, ObjectPtr* slot, DeferredSlot* next)
: DeferredSlot(slot, next), value_(value) {}
virtual void Materialize(DeoptContext* deopt_context);
@@ -54,7 +53,7 @@
class DeferredMint : public DeferredSlot {
public:
- DeferredMint(int64_t value, RawObject** slot, DeferredSlot* next)
+ DeferredMint(int64_t value, ObjectPtr* slot, DeferredSlot* next)
: DeferredSlot(slot, next), value_(value) {}
virtual void Materialize(DeoptContext* deopt_context);
@@ -69,7 +68,7 @@
class DeferredFloat32x4 : public DeferredSlot {
public:
- DeferredFloat32x4(simd128_value_t value, RawObject** slot, DeferredSlot* next)
+ DeferredFloat32x4(simd128_value_t value, ObjectPtr* slot, DeferredSlot* next)
: DeferredSlot(slot, next), value_(value) {}
virtual void Materialize(DeoptContext* deopt_context);
@@ -84,7 +83,7 @@
class DeferredFloat64x2 : public DeferredSlot {
public:
- DeferredFloat64x2(simd128_value_t value, RawObject** slot, DeferredSlot* next)
+ DeferredFloat64x2(simd128_value_t value, ObjectPtr* slot, DeferredSlot* next)
: DeferredSlot(slot, next), value_(value) {}
virtual void Materialize(DeoptContext* deopt_context);
@@ -99,7 +98,7 @@
class DeferredInt32x4 : public DeferredSlot {
public:
- DeferredInt32x4(simd128_value_t value, RawObject** slot, DeferredSlot* next)
+ DeferredInt32x4(simd128_value_t value, ObjectPtr* slot, DeferredSlot* next)
: DeferredSlot(slot, next), value_(value) {}
virtual void Materialize(DeoptContext* deopt_context);
@@ -117,7 +116,7 @@
// Object itself is described and materialized by DeferredObject.
class DeferredObjectRef : public DeferredSlot {
public:
- DeferredObjectRef(intptr_t index, RawObject** slot, DeferredSlot* next)
+ DeferredObjectRef(intptr_t index, ObjectPtr* slot, DeferredSlot* next)
: DeferredSlot(slot, next), index_(index) {}
virtual void Materialize(DeoptContext* deopt_context);
@@ -134,7 +133,7 @@
public:
DeferredRetAddr(intptr_t index,
intptr_t deopt_id,
- RawObject** slot,
+ ObjectPtr* slot,
DeferredSlot* next)
: DeferredSlot(slot, next), index_(index), deopt_id_(deopt_id) {}
@@ -151,7 +150,7 @@
class DeferredPcMarker : public DeferredSlot {
public:
- DeferredPcMarker(intptr_t index, RawObject** slot, DeferredSlot* next)
+ DeferredPcMarker(intptr_t index, ObjectPtr* slot, DeferredSlot* next)
: DeferredSlot(slot, next), index_(index) {}
virtual void Materialize(DeoptContext* deopt_context);
@@ -166,7 +165,7 @@
class DeferredPp : public DeferredSlot {
public:
- DeferredPp(intptr_t index, RawObject** slot, DeferredSlot* next)
+ DeferredPp(intptr_t index, ObjectPtr* slot, DeferredSlot* next)
: DeferredSlot(slot, next), index_(index) {}
virtual void Materialize(DeoptContext* deopt_context);
@@ -187,14 +186,14 @@
public:
DeferredObject(intptr_t field_count, intptr_t* args)
: field_count_(field_count),
- args_(reinterpret_cast<RawObject**>(args)),
+ args_(reinterpret_cast<ObjectPtr*>(args)),
object_(NULL) {}
intptr_t ArgumentCount() const {
return kFieldsStartIndex + kFieldEntrySize * field_count_;
}
- RawObject* object();
+ ObjectPtr object();
// Fill object with actual field values.
void Fill();
@@ -218,19 +217,17 @@
// a graph which can contain cycles.
void Create();
- RawObject* GetArg(intptr_t index) const {
- return args_[index];
- }
+ ObjectPtr GetArg(intptr_t index) const { return args_[index]; }
- RawObject* GetClass() const { return GetArg(kClassIndex); }
+ ObjectPtr GetClass() const { return GetArg(kClassIndex); }
- RawObject* GetLength() const { return GetArg(kLengthIndex); }
+ ObjectPtr GetLength() const { return GetArg(kLengthIndex); }
- RawObject* GetFieldOffset(intptr_t index) const {
+ ObjectPtr GetFieldOffset(intptr_t index) const {
return GetArg(kFieldsStartIndex + kFieldEntrySize * index + kOffsetIndex);
}
- RawObject* GetValue(intptr_t index) const {
+ ObjectPtr GetValue(intptr_t index) const {
return GetArg(kFieldsStartIndex + kFieldEntrySize * index + kValueIndex);
}
@@ -240,7 +237,7 @@
// Pointer to the first materialization argument on the stack.
// The first argument is Class of the instance to materialize followed by
// Field, value pairs.
- RawObject** args_;
+ ObjectPtr* args_;
// Object materialized from this description.
const Object* object_;
diff --git a/runtime/vm/deopt_instructions.cc b/runtime/vm/deopt_instructions.cc
index 3057977..360929b 100644
--- a/runtime/vm/deopt_instructions.cc
+++ b/runtime/vm/deopt_instructions.cc
@@ -179,15 +179,15 @@
}
void DeoptContext::VisitObjectPointers(ObjectPointerVisitor* visitor) {
- visitor->VisitPointer(reinterpret_cast<RawObject**>(&code_));
- visitor->VisitPointer(reinterpret_cast<RawObject**>(&object_pool_));
- visitor->VisitPointer(reinterpret_cast<RawObject**>(&deopt_info_));
+ visitor->VisitPointer(reinterpret_cast<ObjectPtr*>(&code_));
+ visitor->VisitPointer(reinterpret_cast<ObjectPtr*>(&object_pool_));
+ visitor->VisitPointer(reinterpret_cast<ObjectPtr*>(&deopt_info_));
// Visit any object pointers on the destination stack.
if (dest_frame_is_allocated_) {
for (intptr_t i = 0; i < dest_frame_size_; i++) {
if (dest_frame_[i] != 0) {
- visitor->VisitPointer(reinterpret_cast<RawObject**>(&dest_frame_[i]));
+ visitor->VisitPointer(reinterpret_cast<ObjectPtr*>(&dest_frame_[i]));
}
}
}
@@ -301,7 +301,7 @@
if (!objects_only || IsObjectInstruction(instr->kind())) {
instr->Execute(this, to_addr);
} else {
- *reinterpret_cast<RawObject**>(to_addr) = Object::null();
+ *reinterpret_cast<ObjectPtr*>(to_addr) = Object::null();
}
}
@@ -397,12 +397,12 @@
return deopt_arg_count;
}
-RawArray* DeoptContext::DestFrameAsArray() {
+ArrayPtr DeoptContext::DestFrameAsArray() {
ASSERT(dest_frame_ != NULL && dest_frame_is_allocated_);
const Array& dest_array = Array::Handle(zone(), Array::New(dest_frame_size_));
PassiveObject& obj = PassiveObject::Handle(zone());
for (intptr_t i = 0; i < dest_frame_size_; i++) {
- obj = reinterpret_cast<RawObject*>(dest_frame_[i]);
+ obj = static_cast<ObjectPtr>(dest_frame_[i]);
dest_array.SetAt(i, obj);
}
return dest_array.raw();
@@ -475,7 +475,7 @@
void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) {
const PassiveObject& obj = PassiveObject::Handle(
deopt_context->zone(), deopt_context->ObjectAt(object_table_index_));
- *reinterpret_cast<RawObject**>(dest_addr) = obj.raw();
+ *reinterpret_cast<ObjectPtr*>(dest_addr) = obj.raw();
}
CatchEntryMove ToCatchEntryMove(DeoptContext* deopt_context,
@@ -534,7 +534,7 @@
} else {
*dest_addr = Smi::RawValue(0);
deopt_context->DeferMintMaterialization(
- value, reinterpret_cast<RawMint**>(dest_addr));
+ value, reinterpret_cast<MintPtr*>(dest_addr));
}
}
@@ -653,7 +653,7 @@
*dest_addr = Smi::RawValue(0);
deopt_context->DeferMaterialization(
source_.Value<Type>(deopt_context),
- reinterpret_cast<RawObjectType**>(dest_addr));
+ reinterpret_cast<RawObjectType*>(dest_addr));
}
CatchEntryMove ToCatchEntryMove(DeoptContext* deopt_context,
@@ -671,24 +671,24 @@
typedef DeoptFpuInstr<DeoptInstr::kDouble,
CatchEntryMove::SourceKind::kDoubleSlot,
double,
- RawDouble>
+ DoublePtr>
DeoptDoubleInstr;
// Simd128 types.
typedef DeoptFpuInstr<DeoptInstr::kFloat32x4,
CatchEntryMove::SourceKind::kFloat32x4Slot,
simd128_value_t,
- RawFloat32x4>
+ Float32x4Ptr>
DeoptFloat32x4Instr;
typedef DeoptFpuInstr<DeoptInstr::kFloat64x2,
CatchEntryMove::SourceKind::kFloat64x2Slot,
simd128_value_t,
- RawFloat64x2>
+ Float64x2Ptr>
DeoptFloat64x2Instr;
typedef DeoptFpuInstr<DeoptInstr::kInt32x4,
CatchEntryMove::SourceKind::kInt32x4Slot,
simd128_value_t,
- RawInt32x4>
+ Int32x4Ptr>
DeoptInt32x4Instr;
// Deoptimization instruction creating a PC marker for the code of
@@ -712,7 +712,7 @@
Function& function = Function::Handle(deopt_context->zone());
function ^= deopt_context->ObjectAt(object_table_index_);
if (function.IsNull()) {
- *reinterpret_cast<RawObject**>(dest_addr) =
+ *reinterpret_cast<ObjectPtr*>(dest_addr) =
deopt_context->is_lazy_deopt()
? StubCode::DeoptimizeLazyFromReturn().raw()
: StubCode::Deoptimize().raw();
@@ -724,7 +724,7 @@
// marker until we can recreate that Code object during deferred
// materialization to maintain the invariant that Dart frames always have
// a pc marker.
- *reinterpret_cast<RawObject**>(dest_addr) =
+ *reinterpret_cast<ObjectPtr*>(dest_addr) =
StubCode::FrameAwaitingMaterialization().raw();
deopt_context->DeferPcMarkerMaterialization(object_table_index_, dest_addr);
}
@@ -755,7 +755,7 @@
void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) {
*dest_addr = Smi::RawValue(0);
deopt_context->DeferPpMaterialization(
- object_table_index_, reinterpret_cast<RawObject**>(dest_addr));
+ object_table_index_, reinterpret_cast<ObjectPtr*>(dest_addr));
}
private:
@@ -831,7 +831,7 @@
}
void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) {
- *reinterpret_cast<RawSmi**>(dest_addr) = Smi::New(0);
+ *reinterpret_cast<SmiPtr*>(dest_addr) = Smi::New(0);
deopt_context->DeferMaterializedObjectRef(index_, dest_addr);
}
@@ -892,7 +892,7 @@
*code = function.unoptimized_code();
ASSERT(!code->IsNull());
uword res = code->GetPcForDeoptId(ret_address_instr->deopt_id(),
- RawPcDescriptors::kDeopt);
+ PcDescriptorsLayout::kDeopt);
ASSERT(res != 0);
return res;
}
@@ -1237,7 +1237,7 @@
return Thread::Current()->zone()->Realloc<uint8_t>(ptr, old_size, new_size);
}
-RawTypedData* DeoptInfoBuilder::CreateDeoptInfo(const Array& deopt_table) {
+TypedDataPtr DeoptInfoBuilder::CreateDeoptInfo(const Array& deopt_table) {
intptr_t length = instructions_.length();
// Count the number of instructions that are a shared suffix of some deopt
diff --git a/runtime/vm/deopt_instructions.h b/runtime/vm/deopt_instructions.h
index 57fff85..0c40fa9 100644
--- a/runtime/vm/deopt_instructions.h
+++ b/runtime/vm/deopt_instructions.h
@@ -70,7 +70,7 @@
intptr_t GetCallerFp() const;
void SetCallerFp(intptr_t callers_fp);
- RawObject* ObjectAt(intptr_t index) const {
+ ObjectPtr ObjectAt(intptr_t index) const {
const ObjectPool& object_pool = ObjectPool::Handle(object_pool_);
return object_pool.ObjectAt(index);
}
@@ -124,7 +124,7 @@
intptr_t source_frame_size() const { return source_frame_size_; }
intptr_t dest_frame_size() const { return dest_frame_size_; }
- RawCode* code() const { return code_; }
+ CodePtr code() const { return code_; }
bool is_lazy_deopt() const { return is_lazy_deopt_; }
@@ -135,7 +135,7 @@
return (deopt_flags_ & flag) != 0;
}
- RawTypedData* deopt_info() const { return deopt_info_; }
+ TypedDataPtr deopt_info() const { return deopt_info_; }
// Fills the destination frame but defers materialization of
// objects.
@@ -150,53 +150,53 @@
// artificial arguments used during deoptimization.
intptr_t MaterializeDeferredObjects();
- RawArray* DestFrameAsArray();
+ ArrayPtr DestFrameAsArray();
void VisitObjectPointers(ObjectPointerVisitor* visitor);
void DeferMaterializedObjectRef(intptr_t idx, intptr_t* slot) {
deferred_slots_ = new DeferredObjectRef(
- idx, reinterpret_cast<RawObject**>(slot), deferred_slots_);
+ idx, reinterpret_cast<ObjectPtr*>(slot), deferred_slots_);
}
- void DeferMaterialization(double value, RawDouble** slot) {
+ void DeferMaterialization(double value, DoublePtr* slot) {
deferred_slots_ = new DeferredDouble(
- value, reinterpret_cast<RawObject**>(slot), deferred_slots_);
+ value, reinterpret_cast<ObjectPtr*>(slot), deferred_slots_);
}
- void DeferMintMaterialization(int64_t value, RawMint** slot) {
+ void DeferMintMaterialization(int64_t value, MintPtr* slot) {
deferred_slots_ = new DeferredMint(
- value, reinterpret_cast<RawObject**>(slot), deferred_slots_);
+ value, reinterpret_cast<ObjectPtr*>(slot), deferred_slots_);
}
- void DeferMaterialization(simd128_value_t value, RawFloat32x4** slot) {
+ void DeferMaterialization(simd128_value_t value, Float32x4Ptr* slot) {
deferred_slots_ = new DeferredFloat32x4(
- value, reinterpret_cast<RawObject**>(slot), deferred_slots_);
+ value, reinterpret_cast<ObjectPtr*>(slot), deferred_slots_);
}
- void DeferMaterialization(simd128_value_t value, RawFloat64x2** slot) {
+ void DeferMaterialization(simd128_value_t value, Float64x2Ptr* slot) {
deferred_slots_ = new DeferredFloat64x2(
- value, reinterpret_cast<RawObject**>(slot), deferred_slots_);
+ value, reinterpret_cast<ObjectPtr*>(slot), deferred_slots_);
}
- void DeferMaterialization(simd128_value_t value, RawInt32x4** slot) {
+ void DeferMaterialization(simd128_value_t value, Int32x4Ptr* slot) {
deferred_slots_ = new DeferredInt32x4(
- value, reinterpret_cast<RawObject**>(slot), deferred_slots_);
+ value, reinterpret_cast<ObjectPtr*>(slot), deferred_slots_);
}
void DeferRetAddrMaterialization(intptr_t index,
intptr_t deopt_id,
intptr_t* slot) {
deferred_slots_ = new DeferredRetAddr(
- index, deopt_id, reinterpret_cast<RawObject**>(slot), deferred_slots_);
+ index, deopt_id, reinterpret_cast<ObjectPtr*>(slot), deferred_slots_);
}
void DeferPcMarkerMaterialization(intptr_t index, intptr_t* slot) {
deferred_slots_ = new DeferredPcMarker(
- index, reinterpret_cast<RawObject**>(slot), deferred_slots_);
+ index, reinterpret_cast<ObjectPtr*>(slot), deferred_slots_);
}
- void DeferPpMaterialization(intptr_t index, RawObject** slot) {
+ void DeferPpMaterialization(intptr_t index, ObjectPtr* slot) {
deferred_slots_ = new DeferredPp(index, slot, deferred_slots_);
}
@@ -229,9 +229,9 @@
intptr_t DeferredObjectsCount() const { return deferred_objects_count_; }
- RawCode* code_;
- RawObjectPool* object_pool_;
- RawTypedData* deopt_info_;
+ CodePtr code_;
+ ObjectPoolPtr object_pool_;
+ TypedDataPtr deopt_info_;
bool dest_frame_is_allocated_;
intptr_t* dest_frame_;
intptr_t dest_frame_size_;
@@ -388,7 +388,8 @@
: source_index_(source_index) {}
RegisterSource(Kind kind, intptr_t index)
- : source_index_(KindField::encode(kind) | RawIndexField::encode(index)) {}
+ : source_index_(KindField::encode(kind) |
+ IndexFieldLayout::encode(index)) {}
template <typename T>
T Value(DeoptContext* context) const {
@@ -418,13 +419,13 @@
private:
class KindField : public BitField<intptr_t, intptr_t, 0, 1> {};
- class RawIndexField
+ class IndexFieldLayout
: public BitField<intptr_t, intptr_t, 1, kBitsPerWord - 1> {};
bool is_register() const {
return KindField::decode(source_index_) == kRegister;
}
- intptr_t raw_index() const { return RawIndexField::decode(source_index_); }
+ intptr_t raw_index() const { return IndexFieldLayout::decode(source_index_); }
RegisterType reg() const { return static_cast<RegisterType>(raw_index()); }
@@ -480,7 +481,7 @@
// Returns the index of the next stack slot. Used for verification.
intptr_t EmitMaterializationArguments(intptr_t dest_index);
- RawTypedData* CreateDeoptInfo(const Array& deopt_table);
+ TypedDataPtr CreateDeoptInfo(const Array& deopt_table);
// Mark the actual start of the frame description after all materialization
// instructions were emitted. Used for verification purposes.
@@ -559,8 +560,8 @@
TypedData* info,
Smi* reason_and_flags);
- static RawSmi* EncodeReasonAndFlags(ICData::DeoptReasonId reason,
- uint32_t flags) {
+ static SmiPtr EncodeReasonAndFlags(ICData::DeoptReasonId reason,
+ uint32_t flags) {
return Smi::New(ReasonField::encode(reason) | FlagsField::encode(flags));
}
diff --git a/runtime/vm/double_conversion.cc b/runtime/vm/double_conversion.cc
index b3784ab..7357658 100644
--- a/runtime/vm/double_conversion.cc
+++ b/runtime/vm/double_conversion.cc
@@ -50,7 +50,7 @@
ASSERT(result == buffer);
}
-RawString* DoubleToStringAsFixed(double d, int fraction_digits) {
+StringPtr DoubleToStringAsFixed(double d, int fraction_digits) {
static const int kMinFractionDigits = 0;
static const int kMaxFractionDigits = 20;
static const int kMaxDigitsBeforePoint = 20;
@@ -91,7 +91,7 @@
return String::New(builder.Finalize());
}
-RawString* DoubleToStringAsExponential(double d, int fraction_digits) {
+StringPtr DoubleToStringAsExponential(double d, int fraction_digits) {
static const int kMinFractionDigits = -1; // -1 represents shortest mode.
static const int kMaxFractionDigits = 20;
static const int kConversionFlags =
@@ -122,7 +122,7 @@
return String::New(builder.Finalize());
}
-RawString* DoubleToStringAsPrecision(double d, int precision) {
+StringPtr DoubleToStringAsPrecision(double d, int precision) {
static const int kMinPrecisionDigits = 1;
static const int kMaxPrecisionDigits = 21;
static const int kMaxLeadingPaddingZeroes = 6;
diff --git a/runtime/vm/double_conversion.h b/runtime/vm/double_conversion.h
index 8793649..27a8172 100644
--- a/runtime/vm/double_conversion.h
+++ b/runtime/vm/double_conversion.h
@@ -18,9 +18,9 @@
};
void DoubleToCString(double d, char* buffer, int buffer_size);
-RawString* DoubleToStringAsFixed(double d, int fraction_digits);
-RawString* DoubleToStringAsExponential(double d, int fraction_digits);
-RawString* DoubleToStringAsPrecision(double d, int precision);
+StringPtr DoubleToStringAsFixed(double d, int fraction_digits);
+StringPtr DoubleToStringAsExponential(double d, int fraction_digits);
+StringPtr DoubleToStringAsPrecision(double d, int precision);
bool CStringToDouble(const char* str, intptr_t length, double* result);
diff --git a/runtime/vm/exceptions.cc b/runtime/vm/exceptions.cc
index 76d0097..3bcb484 100644
--- a/runtime/vm/exceptions.cc
+++ b/runtime/vm/exceptions.cc
@@ -361,8 +361,8 @@
return reinterpret_cast<T*>(fp + frame_slot * kWordSize);
}
- static RawObject** TaggedSlotAt(uword fp, int stack_slot) {
- return SlotAt<RawObject*>(fp, stack_slot);
+ static ObjectPtr* TaggedSlotAt(uword fp, int stack_slot) {
+ return SlotAt<ObjectPtr>(fp, stack_slot);
}
typedef ReadStream::Raw<sizeof(intptr_t), intptr_t> Reader;
@@ -598,7 +598,7 @@
#if defined(DEBUG)
// Ensure the frame references optimized code.
- RawObject* pc_marker = *(reinterpret_cast<RawObject**>(
+ ObjectPtr pc_marker = *(reinterpret_cast<ObjectPtr*>(
frame_pointer + runtime_frame_layout.code_from_fp * kWordSize));
Code& code = Code::Handle(Code::RawCast(pc_marker));
ASSERT(code.is_optimized() && !code.is_force_optimized());
@@ -739,7 +739,7 @@
UNREACHABLE();
}
-static RawField* LookupStackTraceField(const Instance& instance) {
+static FieldPtr LookupStackTraceField(const Instance& instance) {
if (instance.GetClassId() < kNumPredefinedCids) {
// 'class Error' is not a predefined class.
return Field::null();
@@ -771,7 +771,7 @@
return Field::null();
}
-RawStackTrace* Exceptions::CurrentStackTrace() {
+StackTracePtr Exceptions::CurrentStackTrace() {
return GetStackTraceForException();
}
@@ -891,7 +891,7 @@
// Return the script of the Dart function that called the native entry or the
// runtime entry. The frame iterator points to the callee.
-RawScript* Exceptions::GetCallerScript(DartFrameIterator* iterator) {
+ScriptPtr Exceptions::GetCallerScript(DartFrameIterator* iterator) {
StackFrame* caller_frame = iterator->NextFrame();
ASSERT(caller_frame != NULL && caller_frame->IsDartFrame());
const Function& caller = Function::Handle(caller_frame->LookupDartFunction());
@@ -906,7 +906,7 @@
// Allocate a new instance of the given class name.
// TODO(hausner): Rename this NewCoreInstance to call out the fact that
// the class name is resolved in the core library implicitly?
-RawInstance* Exceptions::NewInstance(const char* class_name) {
+InstancePtr Exceptions::NewInstance(const char* class_name) {
Thread* thread = Thread::Current();
Zone* zone = thread->zone();
const String& cls_name =
@@ -1128,7 +1128,7 @@
Exceptions::ThrowByType(Exceptions::kLateInitializationError, args);
}
-RawObject* Exceptions::Create(ExceptionType type, const Array& arguments) {
+ObjectPtr Exceptions::Create(ExceptionType type, const Array& arguments) {
Library& library = Library::Handle();
const String* class_name = NULL;
const String* constructor_name = &Symbols::Dot();
@@ -1227,4 +1227,16 @@
*constructor_name, arguments);
}
+UnhandledExceptionPtr Exceptions::CreateUnhandledException(Zone* zone,
+ ExceptionType type,
+ const char* msg) {
+ const String& error_str = String::Handle(zone, String::New(msg));
+ const Array& args = Array::Handle(zone, Array::New(1));
+ args.SetAt(0, error_str);
+
+ Object& result = Object::Handle(zone, Exceptions::Create(type, args));
+ const StackTrace& stacktrace = StackTrace::Handle(zone);
+ return UnhandledException::New(Instance::Cast(result), stacktrace);
+}
+
} // namespace dart
diff --git a/runtime/vm/exceptions.h b/runtime/vm/exceptions.h
index 1ec8e12..430d7a9 100644
--- a/runtime/vm/exceptions.h
+++ b/runtime/vm/exceptions.h
@@ -7,6 +7,7 @@
#include "vm/allocation.h"
#include "vm/bitfield.h"
+#include "vm/tagged_pointer.h"
#include "vm/token_position.h"
namespace dart {
@@ -19,10 +20,6 @@
class LanguageError;
class Instance;
class Integer;
-class RawInstance;
-class RawObject;
-class RawScript;
-class RawStackTrace;
class ReadStream;
class WriteStream;
class String;
@@ -41,9 +38,9 @@
DART_NORETURN static void PropagateToEntry(const Error& error);
// Helpers to create and throw errors.
- static RawStackTrace* CurrentStackTrace();
- static RawScript* GetCallerScript(DartFrameIterator* iterator);
- static RawInstance* NewInstance(const char* class_name);
+ static StackTracePtr CurrentStackTrace();
+ static ScriptPtr GetCallerScript(DartFrameIterator* iterator);
+ static InstancePtr NewInstance(const char* class_name);
static void CreateAndThrowTypeError(TokenPosition location,
const AbstractType& src_type,
const AbstractType& dst_type,
@@ -90,7 +87,13 @@
// Returns a RawInstance if the exception is successfully created,
// otherwise returns a RawError.
- static RawObject* Create(ExceptionType type, const Array& arguments);
+ static ObjectPtr Create(ExceptionType type, const Array& arguments);
+
+ // Returns RawUnhandledException that wraps exception of type [type] with
+ // [msg] as a single argument.
+ static UnhandledExceptionPtr CreateUnhandledException(Zone* zone,
+ ExceptionType type,
+ const char* msg);
DART_NORETURN static void JumpToFrame(Thread* thread,
uword program_counter,
diff --git a/runtime/vm/field_table.cc b/runtime/vm/field_table.cc
index 96d3f5a..8ff6f03 100644
--- a/runtime/vm/field_table.cc
+++ b/runtime/vm/field_table.cc
@@ -29,7 +29,7 @@
}
intptr_t FieldTable::FieldOffsetFor(intptr_t field_id) {
- return field_id * sizeof(RawInstance*); // NOLINT
+ return field_id * sizeof(InstancePtr); // NOLINT
}
void FieldTable::Register(const Field& field) {
@@ -62,7 +62,7 @@
free_head_ = field_id;
}
-void FieldTable::SetAt(intptr_t index, RawInstance* raw_instance) {
+void FieldTable::SetAt(intptr_t index, InstancePtr raw_instance) {
ASSERT(index < capacity_);
table_[index] = raw_instance;
}
@@ -82,10 +82,10 @@
void FieldTable::Grow(intptr_t new_capacity) {
ASSERT(new_capacity > capacity_);
- auto new_table = static_cast<RawInstance**>(
- malloc(new_capacity * sizeof(RawInstance*))); // NOLINT
- memmove(new_table, table_, top_ * sizeof(RawInstance*));
- memset(new_table + top_, 0, (new_capacity - top_) * sizeof(RawInstance*));
+ auto new_table = static_cast<InstancePtr*>(
+ malloc(new_capacity * sizeof(InstancePtr))); // NOLINT
+ memmove(new_table, table_, top_ * sizeof(InstancePtr));
+ memset(new_table + top_, 0, (new_capacity - top_) * sizeof(InstancePtr));
capacity_ = new_capacity;
old_tables_->Add(table_);
// Ensure that new_table_ is populated before it is published
@@ -97,9 +97,9 @@
FieldTable* FieldTable::Clone() {
FieldTable* clone = new FieldTable();
- auto new_table = static_cast<RawInstance**>(
- malloc(capacity_ * sizeof(RawInstance*))); // NOLINT
- memmove(new_table, table_, top_ * sizeof(RawInstance*));
+ auto new_table = static_cast<InstancePtr*>(
+ malloc(capacity_ * sizeof(InstancePtr))); // NOLINT
+ memmove(new_table, table_, top_ * sizeof(InstancePtr));
ASSERT(clone->table_ == nullptr);
clone->table_ = new_table;
clone->capacity_ = capacity_;
@@ -115,8 +115,8 @@
ASSERT(visitor != NULL);
visitor->set_gc_root_type("static fields table");
- visitor->VisitPointers(reinterpret_cast<RawObject**>(&table_[0]),
- reinterpret_cast<RawObject**>(&table_[top_ - 1]));
+ visitor->VisitPointers(reinterpret_cast<ObjectPtr*>(&table_[0]),
+ reinterpret_cast<ObjectPtr*>(&table_[top_ - 1]));
visitor->clear_gc_root_type();
}
diff --git a/runtime/vm/field_table.h b/runtime/vm/field_table.h
index 08e83d8..b4c8f23 100644
--- a/runtime/vm/field_table.h
+++ b/runtime/vm/field_table.h
@@ -12,11 +12,11 @@
#include "vm/class_id.h"
#include "vm/globals.h"
#include "vm/growable_array.h"
+#include "vm/tagged_pointer.h"
namespace dart {
class Field;
-class RawInstance;
class FieldTable {
public:
@@ -25,14 +25,14 @@
capacity_(0),
free_head_(-1),
table_(nullptr),
- old_tables_(new MallocGrowableArray<RawInstance**>()) {}
+ old_tables_(new MallocGrowableArray<InstancePtr*>()) {}
~FieldTable();
intptr_t NumFieldIds() const { return top_; }
intptr_t Capacity() const { return capacity_; }
- RawInstance** table() { return table_; }
+ InstancePtr* table() { return table_; }
void FreeOldTables();
@@ -49,11 +49,11 @@
// to an existing static field value.
void Free(intptr_t index);
- RawInstance* At(intptr_t index) const {
+ InstancePtr At(intptr_t index) const {
ASSERT(IsValidIndex(index));
return table_[index];
}
- void SetAt(intptr_t index, RawInstance* raw_instance);
+ void SetAt(intptr_t index, InstancePtr raw_instance);
FieldTable* Clone();
@@ -77,10 +77,10 @@
// element, last element contains -1.
intptr_t free_head_;
- RawInstance** table_;
+ InstancePtr* table_;
// When table_ grows and have to reallocated, keep the old one here
// so it will get freed when its are no longer in use.
- MallocGrowableArray<RawInstance**>* old_tables_;
+ MallocGrowableArray<InstancePtr*>* old_tables_;
DISALLOW_COPY_AND_ASSIGN(FieldTable);
};
diff --git a/runtime/vm/gdb_helpers.cc b/runtime/vm/gdb_helpers.cc
index 1260263..f75c89a 100644
--- a/runtime/vm/gdb_helpers.cc
+++ b/runtime/vm/gdb_helpers.cc
@@ -12,12 +12,12 @@
#if !defined(PRODUCT)
DART_EXPORT
-void _printRawObject(RawObject* object) {
+void _printRawObject(ObjectPtr object) {
OS::PrintErr("%s\n", Object::Handle(object).ToCString());
}
DART_EXPORT
-Object* _handle(RawObject* object) {
+Object* _handle(ObjectPtr object) {
return &Object::Handle(object);
}
@@ -57,15 +57,15 @@
// Must be called with the current interpreter fp, sp, and pc.
// Note that sp[0] is not modified, but sp[1] will be trashed.
DART_EXPORT
-void _printInterpreterStackTrace(RawObject** fp,
- RawObject** sp,
+void _printInterpreterStackTrace(ObjectPtr* fp,
+ ObjectPtr* sp,
const KBCInstr* pc) {
Thread* thread = Thread::Current();
sp[1] = Function::null();
sp[2] = Bytecode::null();
- sp[3] = reinterpret_cast<RawObject*>(reinterpret_cast<uword>(pc));
- sp[4] = reinterpret_cast<RawObject*>(fp);
- RawObject** exit_fp = sp + 1 + kKBCDartFrameFixedSize;
+ sp[3] = static_cast<ObjectPtr>(reinterpret_cast<uword>(pc));
+ sp[4] = static_cast<ObjectPtr>(reinterpret_cast<uword>(fp));
+ ObjectPtr* exit_fp = sp + 1 + kKBCDartFrameFixedSize;
thread->set_top_exit_frame_info(reinterpret_cast<uword>(exit_fp));
thread->set_execution_state(Thread::kThreadInVM);
_printDartStackTrace();
@@ -78,8 +78,8 @@
PrintObjectPointersVisitor()
: ObjectPointerVisitor(IsolateGroup::Current()) {}
- void VisitPointers(RawObject** first, RawObject** last) {
- for (RawObject** p = first; p <= last; p++) {
+ void VisitPointers(ObjectPtr* first, ObjectPtr* last) {
+ for (ObjectPtr* p = first; p <= last; p++) {
Object& obj = Object::Handle(*p);
OS::PrintErr("%p: %s\n", p, obj.ToCString());
}
diff --git a/runtime/vm/guard_field_test.cc b/runtime/vm/guard_field_test.cc
index be010ce..3334ea1 100644
--- a/runtime/vm/guard_field_test.cc
+++ b/runtime/vm/guard_field_test.cc
@@ -10,10 +10,10 @@
namespace dart {
-RawField* LookupField(Dart_Handle library,
- const char* class_name,
- const char* field_name) {
- RawLibrary* raw_library = Library::RawCast(Api::UnwrapHandle(library));
+FieldPtr LookupField(Dart_Handle library,
+ const char* class_name,
+ const char* field_name) {
+ LibraryPtr raw_library = Library::RawCast(Api::UnwrapHandle(library));
Library& lib = Library::ZoneHandle(raw_library);
const String& classname =
String::Handle(Symbols::New(Thread::Current(), class_name));
diff --git a/runtime/vm/handles_impl.h b/runtime/vm/handles_impl.h
index 3bbd19f..f4033dc 100644
--- a/runtime/vm/handles_impl.h
+++ b/runtime/vm/handles_impl.h
@@ -290,7 +290,7 @@
ASSERT(visitor != NULL);
for (intptr_t i = 0; i < next_handle_slot_; i += kHandleSizeInWords) {
visitor->VisitPointer(
- reinterpret_cast<RawObject**>(&data_[i + kOffsetOfRawPtr / kWordSize]));
+ reinterpret_cast<ObjectPtr*>(&data_[i + kOffsetOfRawPtr / kWordSize]));
}
}
diff --git a/runtime/vm/hash_table.h b/runtime/vm/hash_table.h
index a59fd9a..b558abe 100644
--- a/runtime/vm/hash_table.h
+++ b/runtime/vm/hash_table.h
@@ -85,7 +85,7 @@
released_data_(NULL) {}
// Uses 'zone' for handle allocation. 'Release' must be called at the end
// to obtain the final table after potential growth/shrinkage.
- HashTable(Zone* zone, RawArray* data)
+ HashTable(Zone* zone, ArrayPtr data)
: key_handle_(&Object::Handle(zone)),
smi_handle_(&Smi::Handle(zone)),
data_(&Array::Handle(zone, data)),
@@ -252,11 +252,11 @@
return InternalGetKey(entry) == DeletedMarker().raw();
}
- RawObject* GetKey(intptr_t entry) const {
+ ObjectPtr GetKey(intptr_t entry) const {
ASSERT(IsOccupied(entry));
return InternalGetKey(entry);
}
- RawObject* GetPayload(intptr_t entry, intptr_t component) const {
+ ObjectPtr GetPayload(intptr_t entry, intptr_t component) const {
ASSERT(IsOccupied(entry));
return data_->At(PayloadIndex(entry, component));
}
@@ -307,7 +307,7 @@
}
void UpdateCollisions(intptr_t collisions) const {
if (KeyTraits::ReportStats()) {
- if (data_->raw()->InVMIsolateHeap()) {
+ if (data_->raw()->ptr()->InVMIsolateHeap()) {
return;
}
AdjustSmiValueAt(kNumProbesIndex, collisions + 1);
@@ -370,7 +370,7 @@
return KeyIndex(entry) + 1 + component;
}
- RawObject* InternalGetKey(intptr_t entry) const {
+ ObjectPtr InternalGetKey(intptr_t entry) const {
return data_->At(KeyIndex(entry));
}
@@ -408,9 +408,9 @@
public:
typedef HashTable<KeyTraits, kUserPayloadSize, 0> BaseTable;
static const intptr_t kPayloadSize = kUserPayloadSize;
- explicit UnorderedHashTable(RawArray* data)
+ explicit UnorderedHashTable(ArrayPtr data)
: BaseTable(Thread::Current()->zone(), data) {}
- UnorderedHashTable(Zone* zone, RawArray* data) : BaseTable(zone, data) {}
+ UnorderedHashTable(Zone* zone, ArrayPtr data) : BaseTable(zone, data) {}
UnorderedHashTable(Object* key, Smi* value, Array* data)
: BaseTable(key, value, data) {}
// Note: Does not check for concurrent modification.
@@ -441,8 +441,8 @@
public:
// Allocates and initializes a table.
template <typename Table>
- static RawArray* New(intptr_t initial_capacity,
- Heap::Space space = Heap::kNew) {
+ static ArrayPtr New(intptr_t initial_capacity,
+ Heap::Space space = Heap::kNew) {
Table table(
Thread::Current()->zone(),
Array::New(Table::ArrayLengthForNumOccupied(initial_capacity), space));
@@ -451,7 +451,7 @@
}
template <typename Table>
- static RawArray* New(const Array& array) {
+ static ArrayPtr New(const Array& array) {
Table table(Thread::Current()->zone(), array.raw());
table.Initialize();
return table.Release().raw();
@@ -512,7 +512,7 @@
// Serializes a table by concatenating its entries as an array.
template <typename Table>
- static RawArray* ToArray(const Table& table, bool include_payload) {
+ static ArrayPtr ToArray(const Table& table, bool include_payload) {
const intptr_t entry_size = include_payload ? (1 + Table::kPayloadSize) : 1;
Array& result = Array::Handle(Array::New(table.NumOccupied() * entry_size));
typename Table::Iterator it(&table);
@@ -536,13 +536,13 @@
template <typename BaseIterTable>
class HashMap : public BaseIterTable {
public:
- explicit HashMap(RawArray* data)
+ explicit HashMap(ArrayPtr data)
: BaseIterTable(Thread::Current()->zone(), data) {}
- HashMap(Zone* zone, RawArray* data) : BaseIterTable(zone, data) {}
+ HashMap(Zone* zone, ArrayPtr data) : BaseIterTable(zone, data) {}
HashMap(Object* key, Smi* value, Array* data)
: BaseIterTable(key, value, data) {}
template <typename Key>
- RawObject* GetOrNull(const Key& key, bool* present = NULL) const {
+ ObjectPtr GetOrNull(const Key& key, bool* present = NULL) const {
intptr_t entry = BaseIterTable::FindKey(key);
if (present != NULL) {
*present = (entry != -1);
@@ -550,7 +550,7 @@
return (entry == -1) ? Object::null() : BaseIterTable::GetPayload(entry, 0);
}
template <typename Key>
- RawObject* GetOrDie(const Key& key) const {
+ ObjectPtr GetOrDie(const Key& key) const {
intptr_t entry = BaseIterTable::FindKey(key);
if (entry == -1) UNREACHABLE();
return BaseIterTable::GetPayload(entry, 0);
@@ -574,8 +574,8 @@
}
// If 'key' is not present, maps it to 'value_if_absent'. Returns the final
// value in the map.
- RawObject* InsertOrGetValue(const Object& key,
- const Object& value_if_absent) const {
+ ObjectPtr InsertOrGetValue(const Object& key,
+ const Object& value_if_absent) const {
EnsureCapacity();
intptr_t entry = -1;
if (!BaseIterTable::FindKeyOrDeletedOrUnused(key, &entry)) {
@@ -588,8 +588,8 @@
}
// Like InsertOrGetValue, but calls NewKey to allocate a key object if needed.
template <typename Key>
- RawObject* InsertNewOrGetValue(const Key& key,
- const Object& value_if_absent) const {
+ ObjectPtr InsertNewOrGetValue(const Key& key,
+ const Object& value_if_absent) const {
EnsureCapacity();
intptr_t entry = -1;
if (!BaseIterTable::FindKeyOrDeletedOrUnused(key, &entry)) {
@@ -627,9 +627,9 @@
class UnorderedHashMap : public HashMap<UnorderedHashTable<KeyTraits, 1> > {
public:
typedef HashMap<UnorderedHashTable<KeyTraits, 1> > BaseMap;
- explicit UnorderedHashMap(RawArray* data)
+ explicit UnorderedHashMap(ArrayPtr data)
: BaseMap(Thread::Current()->zone(), data) {}
- UnorderedHashMap(Zone* zone, RawArray* data) : BaseMap(zone, data) {}
+ UnorderedHashMap(Zone* zone, ArrayPtr data) : BaseMap(zone, data) {}
UnorderedHashMap(Object* key, Smi* value, Array* data)
: BaseMap(key, value, data) {}
};
@@ -637,9 +637,9 @@
template <typename BaseIterTable>
class HashSet : public BaseIterTable {
public:
- explicit HashSet(RawArray* data)
+ explicit HashSet(ArrayPtr data)
: BaseIterTable(Thread::Current()->zone(), data) {}
- HashSet(Zone* zone, RawArray* data) : BaseIterTable(zone, data) {}
+ HashSet(Zone* zone, ArrayPtr data) : BaseIterTable(zone, data) {}
HashSet(Object* key, Smi* value, Array* data)
: BaseIterTable(key, value, data) {}
bool Insert(const Object& key) {
@@ -654,7 +654,7 @@
// If 'key' is not present, insert and return it. Else, return the existing
// key in the set (useful for canonicalization).
- RawObject* InsertOrGet(const Object& key) const {
+ ObjectPtr InsertOrGet(const Object& key) const {
EnsureCapacity();
intptr_t entry = -1;
if (!BaseIterTable::FindKeyOrDeletedOrUnused(key, &entry)) {
@@ -667,7 +667,7 @@
// Like InsertOrGet, but calls NewKey to allocate a key object if needed.
template <typename Key>
- RawObject* InsertNewOrGet(const Key& key) const {
+ ObjectPtr InsertNewOrGet(const Key& key) const {
EnsureCapacity();
intptr_t entry = -1;
if (!BaseIterTable::FindKeyOrDeletedOrUnused(key, &entry)) {
@@ -681,7 +681,7 @@
}
template <typename Key>
- RawObject* GetOrNull(const Key& key, bool* present = NULL) const {
+ ObjectPtr GetOrNull(const Key& key, bool* present = NULL) const {
intptr_t entry = BaseIterTable::FindKey(key);
if (present != NULL) {
*present = (entry != -1);
@@ -713,11 +713,11 @@
class UnorderedHashSet : public HashSet<UnorderedHashTable<KeyTraits, 0> > {
public:
typedef HashSet<UnorderedHashTable<KeyTraits, 0> > BaseSet;
- explicit UnorderedHashSet(RawArray* data)
+ explicit UnorderedHashSet(ArrayPtr data)
: BaseSet(Thread::Current()->zone(), data) {
ASSERT(data != Array::null());
}
- UnorderedHashSet(Zone* zone, RawArray* data) : BaseSet(zone, data) {}
+ UnorderedHashSet(Zone* zone, ArrayPtr data) : BaseSet(zone, data) {}
UnorderedHashSet(Object* key, Smi* value, Array* data)
: BaseSet(key, value, data) {}
diff --git a/runtime/vm/hash_table_test.cc b/runtime/vm/hash_table_test.cc
index aeb8d55..6549de2 100644
--- a/runtime/vm/hash_table_test.cc
+++ b/runtime/vm/hash_table_test.cc
@@ -32,7 +32,7 @@
String::Cast(a).Equals(String::Cast(b));
}
static uword Hash(const Object& obj) { return String::Cast(obj).Length(); }
- static RawObject* NewKey(const char* key) { return String::New(key); }
+ static ObjectPtr NewKey(const char* key) { return String::New(key); }
};
template <typename Table>
diff --git a/runtime/vm/heap/become.cc b/runtime/vm/heap/become.cc
index 5f5ffba..2799db6 100644
--- a/runtime/vm/heap/become.cc
+++ b/runtime/vm/heap/become.cc
@@ -24,16 +24,16 @@
ForwardingCorpse* result = reinterpret_cast<ForwardingCorpse*>(addr);
uint32_t tags = 0;
- tags = RawObject::SizeTag::update(size, tags);
- tags = RawObject::ClassIdTag::update(kForwardingCorpse, tags);
+ tags = ObjectLayout::SizeTag::update(size, tags);
+ tags = ObjectLayout::ClassIdTag::update(kForwardingCorpse, tags);
bool is_old = (addr & kNewObjectAlignmentOffset) == kOldObjectAlignmentOffset;
- tags = RawObject::OldBit::update(is_old, tags);
- tags = RawObject::OldAndNotMarkedBit::update(is_old, tags);
- tags = RawObject::OldAndNotRememberedBit::update(is_old, tags);
- tags = RawObject::NewBit::update(!is_old, tags);
+ tags = ObjectLayout::OldBit::update(is_old, tags);
+ tags = ObjectLayout::OldAndNotMarkedBit::update(is_old, tags);
+ tags = ObjectLayout::OldAndNotRememberedBit::update(is_old, tags);
+ tags = ObjectLayout::NewBit::update(!is_old, tags);
result->tags_ = tags;
- if (size > RawObject::SizeTag::kMaxSizeTag) {
+ if (size > ObjectLayout::SizeTag::kMaxSizeTag) {
*result->SizeAddress() = size;
}
result->set_target(Object::null());
@@ -48,21 +48,21 @@
// Free list elements are used as a marker for forwarding objects. This is
// safe because we cannot reach free list elements from live objects. Ideally
// forwarding objects would have their own class id. See TODO below.
-static bool IsForwardingObject(RawObject* object) {
+static bool IsForwardingObject(ObjectPtr object) {
return object->IsHeapObject() && object->IsForwardingCorpse();
}
-static RawObject* GetForwardedObject(RawObject* object) {
+static ObjectPtr GetForwardedObject(ObjectPtr object) {
ASSERT(IsForwardingObject(object));
- uword addr = reinterpret_cast<uword>(object) - kHeapObjectTag;
+ uword addr = static_cast<uword>(object) - kHeapObjectTag;
ForwardingCorpse* forwarder = reinterpret_cast<ForwardingCorpse*>(addr);
return forwarder->target();
}
-static void ForwardObjectTo(RawObject* before_obj, RawObject* after_obj) {
- const intptr_t size_before = before_obj->HeapSize();
+static void ForwardObjectTo(ObjectPtr before_obj, ObjectPtr after_obj) {
+ const intptr_t size_before = before_obj->ptr()->HeapSize();
- uword corpse_addr = reinterpret_cast<uword>(before_obj) - kHeapObjectTag;
+ uword corpse_addr = static_cast<uword>(before_obj) - kHeapObjectTag;
ForwardingCorpse* forwarder =
ForwardingCorpse::AsForwarder(corpse_addr, size_before);
forwarder->set_target(after_obj);
@@ -70,7 +70,7 @@
FATAL("become: ForwardObjectTo failure.");
}
// Still need to be able to iterate over the forwarding corpse.
- const intptr_t size_after = before_obj->HeapSize();
+ const intptr_t size_after = before_obj->ptr()->HeapSize();
if (size_before != size_after) {
FATAL("become: Before and after sizes do not match.");
}
@@ -81,25 +81,25 @@
explicit ForwardPointersVisitor(Thread* thread)
: ObjectPointerVisitor(thread->isolate_group()),
thread_(thread),
- visiting_object_(NULL) {}
+ visiting_object_(nullptr) {}
- virtual void VisitPointers(RawObject** first, RawObject** last) {
- for (RawObject** p = first; p <= last; p++) {
- RawObject* old_target = *p;
+ virtual void VisitPointers(ObjectPtr* first, ObjectPtr* last) {
+ for (ObjectPtr* p = first; p <= last; p++) {
+ ObjectPtr old_target = *p;
if (IsForwardingObject(old_target)) {
- RawObject* new_target = GetForwardedObject(old_target);
- if (visiting_object_ == NULL) {
+ ObjectPtr new_target = GetForwardedObject(old_target);
+ if (visiting_object_ == nullptr) {
*p = new_target;
} else {
- visiting_object_->StorePointer(p, new_target);
+ visiting_object_->ptr()->StorePointer(p, new_target);
}
}
}
}
- void VisitingObject(RawObject* obj) {
+ void VisitingObject(ObjectPtr obj) {
visiting_object_ = obj;
- if ((obj != NULL) && obj->IsOldObject() && obj->IsRemembered()) {
+ if ((obj != nullptr) && obj->IsOldObject() && obj->ptr()->IsRemembered()) {
ASSERT(!obj->IsForwardingCorpse());
ASSERT(!obj->IsFreeListElement());
thread_->StoreBufferAddObjectGC(obj);
@@ -108,7 +108,7 @@
private:
Thread* thread_;
- RawObject* visiting_object_;
+ ObjectPtr visiting_object_;
DISALLOW_COPY_AND_ASSIGN(ForwardPointersVisitor);
};
@@ -118,9 +118,9 @@
explicit ForwardHeapPointersVisitor(ForwardPointersVisitor* pointer_visitor)
: pointer_visitor_(pointer_visitor) {}
- virtual void VisitObject(RawObject* obj) {
+ virtual void VisitObject(ObjectPtr obj) {
pointer_visitor_->VisitingObject(obj);
- obj->VisitPointers(pointer_visitor_);
+ obj->ptr()->VisitPointers(pointer_visitor_);
}
private:
@@ -182,25 +182,25 @@
ForwardObjectTo(instance.raw(), instance.raw());
}
-static bool IsDummyObject(RawObject* object) {
+static bool IsDummyObject(ObjectPtr object) {
if (!object->IsForwardingCorpse()) return false;
return GetForwardedObject(object) == object;
}
-void Become::CrashDump(RawObject* before_obj, RawObject* after_obj) {
+void Become::CrashDump(ObjectPtr before_obj, ObjectPtr after_obj) {
OS::PrintErr("DETECTED FATAL ISSUE IN BECOME MAPPINGS\n");
- OS::PrintErr("BEFORE ADDRESS: %p\n", before_obj);
+ OS::PrintErr("BEFORE ADDRESS: %#" Px "\n", static_cast<uword>(before_obj));
OS::PrintErr("BEFORE IS HEAP OBJECT: %s\n",
before_obj->IsHeapObject() ? "YES" : "NO");
OS::PrintErr("BEFORE IN VMISOLATE HEAP OBJECT: %s\n",
- before_obj->InVMIsolateHeap() ? "YES" : "NO");
+ before_obj->ptr()->InVMIsolateHeap() ? "YES" : "NO");
- OS::PrintErr("AFTER ADDRESS: %p\n", after_obj);
+ OS::PrintErr("AFTER ADDRESS: %#" Px "\n", static_cast<uword>(after_obj));
OS::PrintErr("AFTER IS HEAP OBJECT: %s\n",
after_obj->IsHeapObject() ? "YES" : "NO");
OS::PrintErr("AFTER IN VMISOLATE HEAP OBJECT: %s\n",
- after_obj->InVMIsolateHeap() ? "YES" : "NO");
+ after_obj->ptr()->InVMIsolateHeap() ? "YES" : "NO");
if (before_obj->IsHeapObject()) {
OS::PrintErr("BEFORE OBJECT CLASS ID=%" Pd "\n", before_obj->GetClassId());
@@ -225,8 +225,8 @@
// Setup forwarding pointers.
ASSERT(before.Length() == after.Length());
for (intptr_t i = 0; i < before.Length(); i++) {
- RawObject* before_obj = before.At(i);
- RawObject* after_obj = after.At(i);
+ ObjectPtr before_obj = before.At(i);
+ ObjectPtr after_obj = after.At(i);
if (before_obj == after_obj) {
FATAL("become: Cannot self-forward");
@@ -239,7 +239,7 @@
CrashDump(before_obj, after_obj);
FATAL("become: Cannot become immediates");
}
- if (before_obj->InVMIsolateHeap()) {
+ if (before_obj->ptr()->InVMIsolateHeap()) {
CrashDump(before_obj, after_obj);
FATAL("become: Cannot forward VM heap objects");
}
diff --git a/runtime/vm/heap/become.h b/runtime/vm/heap/become.h
index 5e98eba..ef76a45 100644
--- a/runtime/vm/heap/become.h
+++ b/runtime/vm/heap/become.h
@@ -23,11 +23,11 @@
// representation as a FreeListElement.
class ForwardingCorpse {
public:
- RawObject* target() const { return target_; }
- void set_target(RawObject* target) { target_ = target; }
+ ObjectPtr target() const { return target_; }
+ void set_target(ObjectPtr target) { target_ = target; }
intptr_t HeapSize() {
- intptr_t size = RawObject::SizeTag::decode(tags_);
+ intptr_t size = ObjectLayout::SizeTag::decode(tags_);
if (size != 0) return size;
return *SizeAddress();
}
@@ -57,7 +57,7 @@
#if defined(HASH_IN_OBJECT_HEADER)
uint32_t hash_;
#endif
- RawObject* target_;
+ ObjectPtr target_;
// Returns the address of the embedded size.
intptr_t* SizeAddress() const {
@@ -91,7 +91,7 @@
// forwarding objects' targets.
static void FollowForwardingPointers(Thread* thread);
- static void CrashDump(RawObject* before_obj, RawObject* after_obj);
+ static void CrashDump(ObjectPtr before_obj, ObjectPtr after_obj);
};
} // namespace dart
diff --git a/runtime/vm/heap/compactor.cc b/runtime/vm/heap/compactor.cc
index ce28a4b..fbea2f8 100644
--- a/runtime/vm/heap/compactor.cc
+++ b/runtime/vm/heap/compactor.cc
@@ -280,7 +280,7 @@
// store lives in C-heap and will not move. Otherwise we have to update
// the inner pointer.
if (IsTypedDataClassId(cid)) {
- raw_view->RecomputeDataFieldForInternalTypedData();
+ raw_view->ptr()->RecomputeDataFieldForInternalTypedData();
} else {
ASSERT(IsExternalTypedDataClassId(cid));
}
@@ -470,9 +470,9 @@
intptr_t block_dead_size = 0;
uword current = first_object;
while (current < block_end) {
- RawObject* obj = RawObject::FromAddr(current);
- intptr_t size = obj->HeapSize();
- if (obj->IsMarked()) {
+ ObjectPtr obj = ObjectLayout::FromAddr(current);
+ intptr_t size = obj->ptr()->HeapSize();
+ if (obj->ptr()->IsMarked()) {
forwarding_block->RecordLive(current, size);
ASSERT(static_cast<intptr_t>(forwarding_block->Lookup(current)) ==
block_live_size);
@@ -500,9 +500,9 @@
uword old_addr = first_object;
while (old_addr < block_end) {
- RawObject* old_obj = RawObject::FromAddr(old_addr);
- intptr_t size = old_obj->HeapSize();
- if (old_obj->IsMarked()) {
+ ObjectPtr old_obj = ObjectLayout::FromAddr(old_addr);
+ intptr_t size = old_obj->ptr()->HeapSize();
+ if (old_obj->ptr()->IsMarked()) {
uword new_addr = forwarding_block->Lookup(old_addr);
if (new_addr != free_current_) {
// The only situation where these two don't match is if we are moving
@@ -521,7 +521,7 @@
free_end_ = free_page_->object_end();
ASSERT(free_current_ == new_addr);
}
- RawObject* new_obj = RawObject::FromAddr(new_addr);
+ ObjectPtr new_obj = ObjectLayout::FromAddr(new_addr);
// Fast path for no movement. There's often a large block of objects at
// the beginning that don't move.
@@ -531,11 +531,11 @@
reinterpret_cast<void*>(old_addr), size);
if (IsTypedDataClassId(new_obj->GetClassId())) {
- reinterpret_cast<RawTypedData*>(new_obj)->RecomputeDataField();
+ static_cast<TypedDataPtr>(new_obj)->ptr()->RecomputeDataField();
}
}
- new_obj->ClearMarkBit();
- new_obj->VisitPointers(compactor_);
+ new_obj->ptr()->ClearMarkBit();
+ new_obj->ptr()->VisitPointers(compactor_);
ASSERT(free_current_ == new_addr);
free_current_ += size;
@@ -592,13 +592,13 @@
}
DART_FORCE_INLINE
-void GCCompactor::ForwardPointer(RawObject** ptr) {
- RawObject* old_target = *ptr;
+void GCCompactor::ForwardPointer(ObjectPtr* ptr) {
+ ObjectPtr old_target = *ptr;
if (old_target->IsSmiOrNewObject()) {
return; // Not moved.
}
- uword old_addr = RawObject::ToAddr(old_target);
+ uword old_addr = ObjectLayout::ToAddr(old_target);
for (intptr_t i = 0; i < kMaxImagePages; i++) {
if ((old_addr - image_page_ranges_[i].base) < image_page_ranges_[i].size) {
return; // Not moved (unaligned image page).
@@ -611,19 +611,19 @@
return; // Not moved (VM isolate, large page, code page).
}
- RawObject* new_target =
- RawObject::FromAddr(forwarding_page->Lookup(old_addr));
+ ObjectPtr new_target =
+ ObjectLayout::FromAddr(forwarding_page->Lookup(old_addr));
ASSERT(!new_target->IsSmiOrNewObject());
*ptr = new_target;
}
-void GCCompactor::VisitTypedDataViewPointers(RawTypedDataView* view,
- RawObject** first,
- RawObject** last) {
+void GCCompactor::VisitTypedDataViewPointers(TypedDataViewPtr view,
+ ObjectPtr* first,
+ ObjectPtr* last) {
// First we forward all fields of the typed data view.
- RawObject* old_backing = view->ptr()->typed_data_;
+ ObjectPtr old_backing = view->ptr()->typed_data_;
VisitPointers(first, last);
- RawObject* new_backing = view->ptr()->typed_data_;
+ ObjectPtr new_backing = view->ptr()->typed_data_;
const bool backing_moved = old_backing != new_backing;
if (backing_moved) {
@@ -644,8 +644,8 @@
// The backing store didn't move, we therefore don't need to update the
// inner pointer.
if (view->ptr()->data_ == 0) {
- ASSERT(ValueFromRawSmi(view->ptr()->offset_in_bytes_) == 0 &&
- ValueFromRawSmi(view->ptr()->length_) == 0 &&
+ ASSERT(RawSmiValue(view->ptr()->offset_in_bytes_) == 0 &&
+ RawSmiValue(view->ptr()->length_) == 0 &&
view->ptr()->typed_data_ == Object::null());
}
}
@@ -653,8 +653,8 @@
// N.B.: This pointer visitor is not idempotent. We must take care to visit
// each pointer exactly once.
-void GCCompactor::VisitPointers(RawObject** first, RawObject** last) {
- for (RawObject** ptr = first; ptr <= last; ptr++) {
+void GCCompactor::VisitPointers(ObjectPtr* first, ObjectPtr* last) {
+ for (ObjectPtr* ptr = first; ptr <= last; ptr++) {
ForwardPointer(ptr);
}
}
diff --git a/runtime/vm/heap/compactor.h b/runtime/vm/heap/compactor.h
index cd6b29c..e657f84 100644
--- a/runtime/vm/heap/compactor.h
+++ b/runtime/vm/heap/compactor.h
@@ -18,7 +18,6 @@
class FreeList;
class Heap;
class HeapPage;
-class RawObject;
// Implements a sliding compactor.
class GCCompactor : public ValueObject,
@@ -38,11 +37,11 @@
void SetupImagePageBoundaries();
void ForwardStackPointers();
- void ForwardPointer(RawObject** ptr);
- void VisitTypedDataViewPointers(RawTypedDataView* view,
- RawObject** first,
- RawObject** last);
- void VisitPointers(RawObject** first, RawObject** last);
+ void ForwardPointer(ObjectPtr* ptr);
+ void VisitTypedDataViewPointers(TypedDataViewPtr view,
+ ObjectPtr* first,
+ ObjectPtr* last);
+ void VisitPointers(ObjectPtr* first, ObjectPtr* last);
void VisitHandle(uword addr);
Heap* heap_;
@@ -59,7 +58,7 @@
// The typed data views whose inner pointer must be updated after sliding is
// complete.
Mutex typed_data_view_mutex_;
- MallocGrowableArray<RawTypedDataView*> typed_data_views_;
+ MallocGrowableArray<TypedDataViewPtr> typed_data_views_;
};
} // namespace dart
diff --git a/runtime/vm/heap/freelist.cc b/runtime/vm/heap/freelist.cc
index 20b02cc..3570378 100644
--- a/runtime/vm/heap/freelist.cc
+++ b/runtime/vm/heap/freelist.cc
@@ -22,20 +22,20 @@
FreeListElement* result = reinterpret_cast<FreeListElement*>(addr);
uint32_t tags = 0;
- tags = RawObject::SizeTag::update(size, tags);
- tags = RawObject::ClassIdTag::update(kFreeListElement, tags);
+ tags = ObjectLayout::SizeTag::update(size, tags);
+ tags = ObjectLayout::ClassIdTag::update(kFreeListElement, tags);
ASSERT((addr & kNewObjectAlignmentOffset) == kOldObjectAlignmentOffset);
- tags = RawObject::OldBit::update(true, tags);
- tags = RawObject::OldAndNotMarkedBit::update(true, tags);
- tags = RawObject::OldAndNotRememberedBit::update(true, tags);
- tags = RawObject::NewBit::update(false, tags);
+ tags = ObjectLayout::OldBit::update(true, tags);
+ tags = ObjectLayout::OldAndNotMarkedBit::update(true, tags);
+ tags = ObjectLayout::OldAndNotRememberedBit::update(true, tags);
+ tags = ObjectLayout::NewBit::update(false, tags);
result->tags_ = tags;
#if defined(HASH_IN_OBJECT_HEADER)
// Clearing this is mostly for neatness. The identityHashCode
// of free list entries is not used.
result->hash_ = 0;
#endif
- if (size > RawObject::SizeTag::kMaxSizeTag) {
+ if (size > ObjectLayout::SizeTag::kMaxSizeTag) {
*result->SizeAddress() = size;
}
result->set_next(NULL);
@@ -51,7 +51,7 @@
intptr_t FreeListElement::HeaderSizeFor(intptr_t size) {
if (size == 0) return 0;
- return ((size > RawObject::SizeTag::kMaxSizeTag) ? 3 : 2) * kWordSize;
+ return ((size > ObjectLayout::SizeTag::kMaxSizeTag) ? 3 : 2) * kWordSize;
}
FreeList::FreeList() : mutex_() {
diff --git a/runtime/vm/heap/freelist.h b/runtime/vm/heap/freelist.h
index 5b2c14a..1187ff3 100644
--- a/runtime/vm/heap/freelist.h
+++ b/runtime/vm/heap/freelist.h
@@ -29,7 +29,7 @@
void set_next(FreeListElement* next) { next_ = next; }
intptr_t HeapSize() {
- intptr_t size = RawObject::SizeTag::decode(tags_);
+ intptr_t size = ObjectLayout::SizeTag::decode(tags_);
if (size != 0) return size;
return *SizeAddress();
}
diff --git a/runtime/vm/heap/heap.cc b/runtime/vm/heap/heap.cc
index 1ff35e1..0f3dcd0 100644
--- a/runtime/vm/heap/heap.cc
+++ b/runtime/vm/heap/heap.cc
@@ -323,26 +323,26 @@
old_space_.VisitObjectPointers(visitor);
}
-RawInstructions* Heap::FindObjectInCodeSpace(FindObjectVisitor* visitor) const {
+InstructionsPtr Heap::FindObjectInCodeSpace(FindObjectVisitor* visitor) const {
// Only executable pages can have RawInstructions objects.
- RawObject* raw_obj = old_space_.FindObject(visitor, HeapPage::kExecutable);
+ ObjectPtr raw_obj = old_space_.FindObject(visitor, HeapPage::kExecutable);
ASSERT((raw_obj == Object::null()) ||
(raw_obj->GetClassId() == kInstructionsCid));
- return reinterpret_cast<RawInstructions*>(raw_obj);
+ return static_cast<InstructionsPtr>(raw_obj);
}
-RawObject* Heap::FindOldObject(FindObjectVisitor* visitor) const {
+ObjectPtr Heap::FindOldObject(FindObjectVisitor* visitor) const {
return old_space_.FindObject(visitor, HeapPage::kData);
}
-RawObject* Heap::FindNewObject(FindObjectVisitor* visitor) {
+ObjectPtr Heap::FindNewObject(FindObjectVisitor* visitor) {
return new_space_.FindObject(visitor);
}
-RawObject* Heap::FindObject(FindObjectVisitor* visitor) {
+ObjectPtr Heap::FindObject(FindObjectVisitor* visitor) {
// The visitor must not allocate from the heap.
NoSafepointScope no_safepoint_scope;
- RawObject* raw_obj = FindNewObject(visitor);
+ ObjectPtr raw_obj = FindNewObject(visitor);
if (raw_obj != Object::null()) {
return raw_obj;
}
@@ -871,6 +871,8 @@
return "low memory";
case kDebugging:
return "debugging";
+ case kSendAndExit:
+ return "send_and_exit";
default:
UNREACHABLE();
return "";
@@ -891,7 +893,7 @@
old_weak_tables_[kObjectIds]->Reset();
}
-intptr_t Heap::GetWeakEntry(RawObject* raw_obj, WeakSelector sel) const {
+intptr_t Heap::GetWeakEntry(ObjectPtr raw_obj, WeakSelector sel) const {
if (raw_obj->IsNewObject()) {
return new_weak_tables_[sel]->GetValue(raw_obj);
}
@@ -899,7 +901,7 @@
return old_weak_tables_[sel]->GetValue(raw_obj);
}
-void Heap::SetWeakEntry(RawObject* raw_obj, WeakSelector sel, intptr_t val) {
+void Heap::SetWeakEntry(ObjectPtr raw_obj, WeakSelector sel, intptr_t val) {
if (raw_obj->IsNewObject()) {
new_weak_tables_[sel]->SetValue(raw_obj, val);
} else {
@@ -908,8 +910,7 @@
}
}
-void Heap::ForwardWeakEntries(RawObject* before_object,
- RawObject* after_object) {
+void Heap::ForwardWeakEntries(ObjectPtr before_object, ObjectPtr after_object) {
const auto before_space =
before_object->IsNewObject() ? Heap::kNew : Heap::kOld;
const auto after_space =
diff --git a/runtime/vm/heap/heap.h b/runtime/vm/heap/heap.h
index 09f7584..49ee780 100644
--- a/runtime/vm/heap/heap.h
+++ b/runtime/vm/heap/heap.h
@@ -55,15 +55,16 @@
};
enum GCReason {
- kNewSpace, // New space is full.
- kPromotion, // Old space limit crossed after a scavenge.
- kOldSpace, // Old space limit crossed.
- kFinalize, // Concurrent marking finished.
- kFull, // Heap::CollectAllGarbage
- kExternal, // Dart_NewWeakPersistentHandle
- kIdle, // Dart_NotifyIdle
- kLowMemory, // Dart_NotifyLowMemory
- kDebugging, // service request, etc.
+ kNewSpace, // New space is full.
+ kPromotion, // Old space limit crossed after a scavenge.
+ kOldSpace, // Old space limit crossed.
+ kFinalize, // Concurrent marking finished.
+ kFull, // Heap::CollectAllGarbage
+ kExternal, // Dart_NewWeakPersistentHandle
+ kIdle, // Dart_NotifyIdle
+ kLowMemory, // Dart_NotifyLowMemory
+ kDebugging, // service request, etc.
+ kSendAndExit, // SendPort.sendAndExit
};
// Pattern for unused new space and swept old space.
@@ -114,10 +115,10 @@
// The 'visitor' function should return false if the object is not found,
// traversal through the heap space continues.
// Returns null object if nothing is found.
- RawInstructions* FindObjectInCodeSpace(FindObjectVisitor* visitor) const;
- RawObject* FindOldObject(FindObjectVisitor* visitor) const;
- RawObject* FindNewObject(FindObjectVisitor* visitor);
- RawObject* FindObject(FindObjectVisitor* visitor);
+ InstructionsPtr FindObjectInCodeSpace(FindObjectVisitor* visitor) const;
+ ObjectPtr FindOldObject(FindObjectVisitor* visitor) const;
+ ObjectPtr FindNewObject(FindObjectVisitor* visitor);
+ ObjectPtr FindObject(FindObjectVisitor* visitor);
void NotifyIdle(int64_t deadline);
void NotifyLowMemory();
@@ -198,10 +199,10 @@
static const char* GCReasonToString(GCReason reason);
// Associate a peer with an object. A non-existent peer is equal to NULL.
- void SetPeer(RawObject* raw_obj, void* peer) {
+ void SetPeer(ObjectPtr raw_obj, void* peer) {
SetWeakEntry(raw_obj, kPeers, reinterpret_cast<intptr_t>(peer));
}
- void* GetPeer(RawObject* raw_obj) const {
+ void* GetPeer(ObjectPtr raw_obj) const {
return reinterpret_cast<void*>(GetWeakEntry(raw_obj, kPeers));
}
int64_t PeerCount() const;
@@ -209,37 +210,37 @@
#if !defined(HASH_IN_OBJECT_HEADER)
// Associate an identity hashCode with an object. An non-existent hashCode
// is equal to 0.
- void SetHash(RawObject* raw_obj, intptr_t hash) {
+ void SetHash(ObjectPtr raw_obj, intptr_t hash) {
SetWeakEntry(raw_obj, kIdentityHashes, hash);
}
- intptr_t GetHash(RawObject* raw_obj) const {
+ intptr_t GetHash(ObjectPtr raw_obj) const {
return GetWeakEntry(raw_obj, kIdentityHashes);
}
#endif
- void SetCanonicalHash(RawObject* raw_obj, intptr_t hash) {
+ void SetCanonicalHash(ObjectPtr raw_obj, intptr_t hash) {
SetWeakEntry(raw_obj, kCanonicalHashes, hash);
}
- intptr_t GetCanonicalHash(RawObject* raw_obj) const {
+ intptr_t GetCanonicalHash(ObjectPtr raw_obj) const {
return GetWeakEntry(raw_obj, kCanonicalHashes);
}
void ResetCanonicalHashTable();
// Associate an id with an object (used when serializing an object).
// A non-existant id is equal to 0.
- void SetObjectId(RawObject* raw_obj, intptr_t object_id) {
+ void SetObjectId(ObjectPtr raw_obj, intptr_t object_id) {
ASSERT(Thread::Current()->IsMutatorThread());
SetWeakEntry(raw_obj, kObjectIds, object_id);
}
- intptr_t GetObjectId(RawObject* raw_obj) const {
+ intptr_t GetObjectId(ObjectPtr raw_obj) const {
ASSERT(Thread::Current()->IsMutatorThread());
return GetWeakEntry(raw_obj, kObjectIds);
}
void ResetObjectIdTable();
// Used by the GC algorithms to propagate weak entries.
- intptr_t GetWeakEntry(RawObject* raw_obj, WeakSelector sel) const;
- void SetWeakEntry(RawObject* raw_obj, WeakSelector sel, intptr_t val);
+ intptr_t GetWeakEntry(ObjectPtr raw_obj, WeakSelector sel) const;
+ void SetWeakEntry(ObjectPtr raw_obj, WeakSelector sel, intptr_t val);
WeakTable* GetWeakTable(Space space, WeakSelector selector) const {
if (space == kNew) {
@@ -257,7 +258,7 @@
}
}
- void ForwardWeakEntries(RawObject* before_object, RawObject* after_object);
+ void ForwardWeakEntries(ObjectPtr before_object, ObjectPtr after_object);
void ForwardWeakTables(ObjectPointerVisitor* visitor);
// Stats collection.
diff --git a/runtime/vm/heap/heap_test.cc b/runtime/vm/heap/heap_test.cc
index 948d6f3..33c8500 100644
--- a/runtime/vm/heap/heap_test.cc
+++ b/runtime/vm/heap/heap_test.cc
@@ -2,14 +2,22 @@
// 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.
+#include <map>
+#include <memory>
+#include <set>
+#include <string>
+
#include "platform/globals.h"
#include "platform/assert.h"
+#include "vm/class_finalizer.h"
#include "vm/dart_api_impl.h"
#include "vm/globals.h"
#include "vm/heap/become.h"
#include "vm/heap/heap.h"
+#include "vm/message_handler.h"
#include "vm/object_graph.h"
+#include "vm/port.h"
#include "vm/symbols.h"
#include "vm/unit_test.h"
@@ -82,7 +90,7 @@
}
#ifndef PRODUCT
-static RawClass* GetClass(const Library& lib, const char* name) {
+static ClassPtr GetClass(const Library& lib, const char* name) {
const Class& cls = Class::Handle(
lib.LookupClass(String::Handle(Symbols::New(Thread::Current(), name))));
EXPECT(!cls.IsNull()); // No ambiguity error expected.
@@ -200,24 +208,24 @@
class FindOnly : public FindObjectVisitor {
public:
- explicit FindOnly(RawObject* target) : target_(target) {
+ explicit FindOnly(ObjectPtr target) : target_(target) {
#if defined(DEBUG)
EXPECT_GT(Thread::Current()->no_safepoint_scope_depth(), 0);
#endif
}
virtual ~FindOnly() {}
- virtual bool FindObject(RawObject* obj) const { return obj == target_; }
+ virtual bool FindObject(ObjectPtr obj) const { return obj == target_; }
private:
- RawObject* target_;
+ ObjectPtr target_;
};
class FindNothing : public FindObjectVisitor {
public:
FindNothing() {}
virtual ~FindNothing() {}
- virtual bool FindObject(RawObject* obj) const { return false; }
+ virtual bool FindObject(ObjectPtr obj) const { return false; }
};
ISOLATE_UNIT_TEST_CASE(FindObject) {
@@ -249,11 +257,11 @@
GCTestHelper::WaitForGCTasks();
Heap* heap = Thread::Current()->isolate()->heap();
- EXPECT(heap->Contains(RawObject::ToAddr(obj.raw())));
+ EXPECT(heap->Contains(ObjectLayout::ToAddr(obj.raw())));
heap->WriteProtect(true);
- EXPECT(heap->Contains(RawObject::ToAddr(obj.raw())));
+ EXPECT(heap->Contains(ObjectLayout::ToAddr(obj.raw())));
heap->WriteProtect(false);
- EXPECT(heap->Contains(RawObject::ToAddr(obj.raw())));
+ EXPECT(heap->Contains(ObjectLayout::ToAddr(obj.raw())));
}
void TestBecomeForward(Heap::Space before_space, Heap::Space after_space) {
@@ -325,8 +333,8 @@
const Array& after_obj = Array::Handle(Array::New(1, Heap::kOld));
before_obj.SetAt(0, new_element);
after_obj.SetAt(0, old_element);
- EXPECT(before_obj.raw()->IsRemembered());
- EXPECT(!after_obj.raw()->IsRemembered());
+ EXPECT(before_obj.raw()->ptr()->IsRemembered());
+ EXPECT(!after_obj.raw()->ptr()->IsRemembered());
EXPECT(before_obj.raw() != after_obj.raw());
@@ -338,7 +346,7 @@
Become::ElementsForwardIdentity(before, after);
EXPECT(before_obj.raw() == after_obj.raw());
- EXPECT(!after_obj.raw()->IsRemembered());
+ EXPECT(!after_obj.raw()->ptr()->IsRemembered());
GCTestHelper::CollectAllGarbage();
@@ -607,6 +615,131 @@
}
};
+class MergeIsolatesHeapsHandler : public MessageHandler {
+ public:
+ explicit MergeIsolatesHeapsHandler(Isolate* owner)
+ : msg_(Utils::CreateCStringUniquePtr(nullptr)), owner_(owner) {}
+
+ const char* name() const { return "merge-isolates-heaps-handler"; }
+
+ ~MergeIsolatesHeapsHandler() { PortMap::ClosePorts(this); }
+
+ MessageStatus HandleMessage(std::unique_ptr<Message> message) {
+ // Parse the message.
+ Object& response_obj = Object::Handle();
+ if (message->IsRaw()) {
+ response_obj = message->raw_obj();
+ } else if (message->IsBequest()) {
+ Bequest* bequest = message->bequest();
+ PersistentHandle* handle = bequest->handle();
+ // Object in the receiving isolate's heap.
+ EXPECT(isolate()->heap()->Contains(ObjectLayout::ToAddr(handle->raw())));
+ response_obj = handle->raw();
+ isolate()->group()->api_state()->FreePersistentHandle(handle);
+ } else {
+ Thread* thread = Thread::Current();
+ MessageSnapshotReader reader(message.get(), thread);
+ response_obj = reader.ReadObject();
+ }
+ if (response_obj.IsString()) {
+ String& response = String::Handle();
+ response ^= response_obj.raw();
+ msg_.reset(strdup(response.ToCString()));
+ } else {
+ ASSERT(response_obj.IsArray());
+ Array& response_array = Array::Handle();
+ response_array ^= response_obj.raw();
+ ASSERT(response_array.Length() == 1);
+ ExternalTypedData& response = ExternalTypedData::Handle();
+ response ^= response_array.At(0);
+ msg_.reset(strdup(reinterpret_cast<char*>(response.DataAddr(0))));
+ }
+
+ return kOK;
+ }
+
+ const char* msg() const { return msg_.get(); }
+
+ virtual Isolate* isolate() const { return owner_; }
+
+ private:
+ Utils::CStringUniquePtr msg_;
+ Isolate* owner_;
+};
+
+VM_UNIT_TEST_CASE(CleanupBequestNeverReceived) {
+ const char* TEST_MESSAGE = "hello, world";
+ Dart_Isolate parent = TestCase::CreateTestIsolate("parent");
+ EXPECT_EQ(parent, Dart_CurrentIsolate());
+ {
+ MergeIsolatesHeapsHandler handler(Isolate::Current());
+ Dart_Port port_id = PortMap::CreatePort(&handler);
+ EXPECT_EQ(PortMap::GetIsolate(port_id), Isolate::Current());
+ Dart_ExitIsolate();
+
+ Dart_Isolate worker = TestCase::CreateTestIsolateInGroup("worker", parent);
+ EXPECT_EQ(worker, Dart_CurrentIsolate());
+ {
+ Thread* thread = Thread::Current();
+ TransitionNativeToVM transition(thread);
+ StackZone zone(thread);
+ HANDLESCOPE(thread);
+
+ String& string = String::Handle(String::New(TEST_MESSAGE));
+ PersistentHandle* handle =
+ Isolate::Current()->group()->api_state()->AllocatePersistentHandle();
+ handle->set_raw(string.raw());
+
+ reinterpret_cast<Isolate*>(worker)->bequeath(
+ std::unique_ptr<Bequest>(new Bequest(handle, port_id)));
+ }
+ }
+ Dart_ShutdownIsolate();
+ Dart_EnterIsolate(parent);
+ Dart_ShutdownIsolate();
+}
+
+VM_UNIT_TEST_CASE(ReceivesSendAndExitMessage) {
+ const char* TEST_MESSAGE = "hello, world";
+ Dart_Isolate parent = TestCase::CreateTestIsolate("parent");
+ EXPECT_EQ(parent, Dart_CurrentIsolate());
+ MergeIsolatesHeapsHandler handler(Isolate::Current());
+ Dart_Port port_id = PortMap::CreatePort(&handler);
+ EXPECT_EQ(PortMap::GetIsolate(port_id), Isolate::Current());
+ Dart_ExitIsolate();
+
+ Dart_Isolate worker = TestCase::CreateTestIsolateInGroup("worker", parent);
+ EXPECT_EQ(worker, Dart_CurrentIsolate());
+ {
+ Thread* thread = Thread::Current();
+ TransitionNativeToVM transition(thread);
+ StackZone zone(thread);
+ HANDLESCOPE(thread);
+
+ String& string = String::Handle(String::New(TEST_MESSAGE));
+
+ PersistentHandle* handle =
+ Isolate::Current()->group()->api_state()->AllocatePersistentHandle();
+ handle->set_raw(string.raw());
+
+ reinterpret_cast<Isolate*>(worker)->bequeath(
+ std::unique_ptr<Bequest>(new Bequest(handle, port_id)));
+ }
+
+ Dart_ShutdownIsolate();
+ Dart_EnterIsolate(parent);
+ {
+ Thread* thread = Thread::Current();
+ TransitionNativeToVM transition(thread);
+ StackZone zone(thread);
+ HANDLESCOPE(thread);
+
+ EXPECT_EQ(MessageHandler::kOK, handler.HandleNextMessage());
+ }
+ EXPECT_STREQ(handler.msg(), TEST_MESSAGE);
+ Dart_ShutdownIsolate();
+}
+
ISOLATE_UNIT_TEST_CASE(ExternalAllocationStats) {
Isolate* isolate = thread->isolate();
Heap* heap = thread->heap();
diff --git a/runtime/vm/heap/marker.cc b/runtime/vm/heap/marker.cc
index e30b529..716d281 100644
--- a/runtime/vm/heap/marker.cc
+++ b/runtime/vm/heap/marker.cc
@@ -34,7 +34,7 @@
page_space_(page_space),
work_list_(marking_stack),
deferred_work_list_(deferred_marking_stack),
- delayed_weak_properties_(NULL),
+ delayed_weak_properties_(nullptr),
marked_bytes_(0),
marked_micros_(0) {
ASSERT(thread_->isolate_group() == isolate_group);
@@ -47,37 +47,38 @@
bool ProcessPendingWeakProperties() {
bool marked = false;
- RawWeakProperty* cur_weak = delayed_weak_properties_;
- delayed_weak_properties_ = NULL;
- while (cur_weak != NULL) {
+ WeakPropertyPtr cur_weak = delayed_weak_properties_;
+ delayed_weak_properties_ = nullptr;
+ while (cur_weak != nullptr) {
uword next_weak = cur_weak->ptr()->next_;
- RawObject* raw_key = cur_weak->ptr()->key_;
+ ObjectPtr raw_key = cur_weak->ptr()->key_;
// Reset the next pointer in the weak property.
cur_weak->ptr()->next_ = 0;
- if (raw_key->IsMarked()) {
- RawObject* raw_val = cur_weak->ptr()->value_;
- marked = marked || (raw_val->IsHeapObject() && !raw_val->IsMarked());
+ if (raw_key->ptr()->IsMarked()) {
+ ObjectPtr raw_val = cur_weak->ptr()->value_;
+ marked =
+ marked || (raw_val->IsHeapObject() && !raw_val->ptr()->IsMarked());
// The key is marked so we make sure to properly visit all pointers
// originating from this weak property.
- cur_weak->VisitPointersNonvirtual(this);
+ cur_weak->ptr()->VisitPointersNonvirtual(this);
} else {
// Requeue this weak property to be handled later.
EnqueueWeakProperty(cur_weak);
}
// Advance to next weak property in the queue.
- cur_weak = reinterpret_cast<RawWeakProperty*>(next_weak);
+ cur_weak = static_cast<WeakPropertyPtr>(next_weak);
}
return marked;
}
void DrainMarkingStack() {
- RawObject* raw_obj = work_list_.Pop();
- if ((raw_obj == NULL) && ProcessPendingWeakProperties()) {
+ ObjectPtr raw_obj = work_list_.Pop();
+ if ((raw_obj == nullptr) && ProcessPendingWeakProperties()) {
raw_obj = work_list_.Pop();
}
- if (raw_obj == NULL) {
+ if (raw_obj == nullptr) {
return;
}
@@ -88,15 +89,15 @@
intptr_t size;
if (class_id != kWeakPropertyCid) {
- size = raw_obj->VisitPointersNonvirtual(this);
+ size = raw_obj->ptr()->VisitPointersNonvirtual(this);
} else {
- RawWeakProperty* raw_weak = static_cast<RawWeakProperty*>(raw_obj);
+ WeakPropertyPtr raw_weak = static_cast<WeakPropertyPtr>(raw_obj);
size = ProcessWeakProperty(raw_weak, /* did_mark */ true);
}
marked_bytes_ += size;
raw_obj = work_list_.Pop();
- } while (raw_obj != NULL);
+ } while (raw_obj != nullptr);
// Marking stack is empty.
ProcessPendingWeakProperties();
@@ -104,7 +105,7 @@
// Check whether any further work was pushed either by other markers or
// by the handling of weak properties.
raw_obj = work_list_.Pop();
- } while (raw_obj != NULL);
+ } while (raw_obj != nullptr);
}
// Races: The concurrent marker is racing with the mutator, but this race is
@@ -119,51 +120,51 @@
// we don't do any in-place unboxing like V8), any value we read from the slot
// is safe.
NO_SANITIZE_THREAD
- RawObject* LoadPointerIgnoreRace(RawObject** ptr) { return *ptr; }
+ ObjectPtr LoadPointerIgnoreRace(ObjectPtr* ptr) { return *ptr; }
- void VisitPointers(RawObject** first, RawObject** last) {
- for (RawObject** current = first; current <= last; current++) {
+ void VisitPointers(ObjectPtr* first, ObjectPtr* last) {
+ for (ObjectPtr* current = first; current <= last; current++) {
MarkObject(LoadPointerIgnoreRace(current));
}
}
- void EnqueueWeakProperty(RawWeakProperty* raw_weak) {
+ void EnqueueWeakProperty(WeakPropertyPtr raw_weak) {
ASSERT(raw_weak->IsHeapObject());
ASSERT(raw_weak->IsOldObject());
ASSERT(raw_weak->IsWeakProperty());
- ASSERT(raw_weak->IsMarked());
+ ASSERT(raw_weak->ptr()->IsMarked());
ASSERT(raw_weak->ptr()->next_ == 0);
- raw_weak->ptr()->next_ = reinterpret_cast<uword>(delayed_weak_properties_);
+ raw_weak->ptr()->next_ = static_cast<uword>(delayed_weak_properties_);
delayed_weak_properties_ = raw_weak;
}
- intptr_t ProcessWeakProperty(RawWeakProperty* raw_weak, bool did_mark) {
+ intptr_t ProcessWeakProperty(WeakPropertyPtr raw_weak, bool did_mark) {
// The fate of the weak property is determined by its key.
- RawObject* raw_key = LoadPointerIgnoreRace(&raw_weak->ptr()->key_);
+ ObjectPtr raw_key = LoadPointerIgnoreRace(&raw_weak->ptr()->key_);
if (raw_key->IsHeapObject() && raw_key->IsOldObject() &&
- !raw_key->IsMarked()) {
+ !raw_key->ptr()->IsMarked()) {
// Key was white. Enqueue the weak property.
if (did_mark) {
EnqueueWeakProperty(raw_weak);
}
- return raw_weak->HeapSize();
+ return raw_weak->ptr()->HeapSize();
}
// Key is gray or black. Make the weak property black.
- return raw_weak->VisitPointersNonvirtual(this);
+ return raw_weak->ptr()->VisitPointersNonvirtual(this);
}
void ProcessDeferredMarking() {
- RawObject* raw_obj;
- while ((raw_obj = deferred_work_list_.Pop()) != NULL) {
+ ObjectPtr raw_obj;
+ while ((raw_obj = deferred_work_list_.Pop()) != nullptr) {
ASSERT(raw_obj->IsHeapObject() && raw_obj->IsOldObject());
// N.B. We are scanning the object even if it is already marked.
bool did_mark = TryAcquireMarkBit(raw_obj);
const intptr_t class_id = raw_obj->GetClassId();
intptr_t size;
if (class_id != kWeakPropertyCid) {
- size = raw_obj->VisitPointersNonvirtual(this);
+ size = raw_obj->ptr()->VisitPointersNonvirtual(this);
} else {
- RawWeakProperty* raw_weak = static_cast<RawWeakProperty*>(raw_obj);
+ WeakPropertyPtr raw_weak = static_cast<WeakPropertyPtr>(raw_obj);
size = ProcessWeakProperty(raw_weak, did_mark);
}
// Add the size only if we win the marking race to prevent
@@ -183,17 +184,17 @@
void Finalize() {
work_list_.Finalize();
// Clear pending weak properties.
- RawWeakProperty* cur_weak = delayed_weak_properties_;
- delayed_weak_properties_ = NULL;
+ WeakPropertyPtr cur_weak = delayed_weak_properties_;
+ delayed_weak_properties_ = nullptr;
intptr_t weak_properties_cleared = 0;
- while (cur_weak != NULL) {
+ while (cur_weak != nullptr) {
uword next_weak = cur_weak->ptr()->next_;
cur_weak->ptr()->next_ = 0;
- RELEASE_ASSERT(!cur_weak->ptr()->key_->IsMarked());
+ RELEASE_ASSERT(!cur_weak->ptr()->key_->ptr()->IsMarked());
WeakProperty::Clear(cur_weak);
weak_properties_cleared++;
// Advance to next weak property in the queue.
- cur_weak = reinterpret_cast<RawWeakProperty*>(next_weak);
+ cur_weak = static_cast<WeakPropertyPtr>(next_weak);
}
}
@@ -203,30 +204,30 @@
}
private:
- void PushMarked(RawObject* raw_obj) {
+ void PushMarked(ObjectPtr raw_obj) {
ASSERT(raw_obj->IsHeapObject());
ASSERT(raw_obj->IsOldObject());
// Push the marked object on the marking stack.
- ASSERT(raw_obj->IsMarked());
+ ASSERT(raw_obj->ptr()->IsMarked());
work_list_.Push(raw_obj);
}
- static bool TryAcquireMarkBit(RawObject* raw_obj) {
+ static bool TryAcquireMarkBit(ObjectPtr raw_obj) {
if (FLAG_write_protect_code && raw_obj->IsInstructions()) {
// A non-writable alias mapping may exist for instruction pages.
raw_obj = HeapPage::ToWritable(raw_obj);
}
if (!sync) {
- raw_obj->SetMarkBitUnsynchronized();
+ raw_obj->ptr()->SetMarkBitUnsynchronized();
return true;
} else {
- return raw_obj->TryAcquireMarkBit();
+ return raw_obj->ptr()->TryAcquireMarkBit();
}
}
DART_FORCE_INLINE
- void MarkObject(RawObject* raw_obj) {
+ void MarkObject(ObjectPtr raw_obj) {
// Fast exit if the raw object is immediate or in new space. No memory
// access.
if (raw_obj->IsSmiOrNewObject()) {
@@ -239,7 +240,7 @@
// change in the value.
// Doing this before checking for an Instructions object avoids
// unnecessary queueing of pre-marked objects.
- if (raw_obj->IsMarked()) {
+ if (raw_obj->ptr()->IsMarked()) {
return;
}
@@ -265,7 +266,7 @@
PageSpace* page_space_;
MarkerWorkList work_list_;
MarkerWorkList deferred_work_list_;
- RawWeakProperty* delayed_weak_properties_;
+ WeakPropertyPtr delayed_weak_properties_;
uintptr_t marked_bytes_;
int64_t marked_micros_;
@@ -275,7 +276,7 @@
typedef MarkingVisitorBase<false> UnsyncMarkingVisitor;
typedef MarkingVisitorBase<true> SyncMarkingVisitor;
-static bool IsUnreachable(const RawObject* raw_obj) {
+static bool IsUnreachable(const ObjectPtr raw_obj) {
if (!raw_obj->IsHeapObject()) {
return false;
}
@@ -285,7 +286,7 @@
if (!raw_obj->IsOldObject()) {
return false;
}
- return !raw_obj->IsMarked();
+ return !raw_obj->ptr()->IsMarked();
}
class MarkingWeakVisitor : public HandleVisitor {
@@ -297,7 +298,7 @@
void VisitHandle(uword addr) {
FinalizablePersistentHandle* handle =
reinterpret_cast<FinalizablePersistentHandle*>(addr);
- RawObject* raw_obj = handle->raw();
+ ObjectPtr raw_obj = handle->raw();
if (IsUnreachable(raw_obj)) {
handle->UpdateUnreachable(thread()->isolate_group());
}
@@ -423,9 +424,9 @@
intptr_t size = table->size();
for (intptr_t i = 0; i < size; i++) {
if (table->IsValidEntryAtExclusive(i)) {
- RawObject* raw_obj = table->ObjectAtExclusive(i);
+ ObjectPtr raw_obj = table->ObjectAtExclusive(i);
ASSERT(raw_obj->IsHeapObject());
- if (!raw_obj->IsMarked()) {
+ if (!raw_obj->ptr()->IsMarked()) {
table->InvalidateAtExclusive(i);
}
}
@@ -444,10 +445,10 @@
// Generated code appends to store buffers; tell MemorySanitizer.
MSAN_UNPOISON(reading, sizeof(*reading));
while (!reading->IsEmpty()) {
- RawObject* raw_object = reading->Pop();
+ ObjectPtr raw_object = reading->Pop();
ASSERT(!raw_object->IsForwardingCorpse());
- ASSERT(raw_object->IsRemembered());
- if (raw_object->IsMarked()) {
+ ASSERT(raw_object->ptr()->IsRemembered());
+ if (raw_object->ptr()->IsMarked()) {
writing->Push(raw_object);
if (writing->IsFull()) {
store_buffer->PushBlock(writing, StoreBuffer::kIgnoreThreshold);
@@ -468,11 +469,11 @@
explicit ObjectIdRingClearPointerVisitor(IsolateGroup* isolate_group)
: ObjectPointerVisitor(isolate_group) {}
- void VisitPointers(RawObject** first, RawObject** last) {
- for (RawObject** current = first; current <= last; current++) {
- RawObject* raw_obj = *current;
+ void VisitPointers(ObjectPtr* first, ObjectPtr* last) {
+ for (ObjectPtr* current = first; current <= last; current++) {
+ ObjectPtr raw_obj = *current;
ASSERT(raw_obj->IsHeapObject());
- if (raw_obj->IsOldObject() && !raw_obj->IsMarked()) {
+ if (raw_obj->IsOldObject() && !raw_obj->ptr()->IsMarked()) {
// Object has become garbage. Replace it will null.
*current = Object::null();
}
diff --git a/runtime/vm/heap/marker.h b/runtime/vm/heap/marker.h
index a4ad4c0b..7f78a58 100644
--- a/runtime/vm/heap/marker.h
+++ b/runtime/vm/heap/marker.h
@@ -17,7 +17,6 @@
class IsolateGroup;
class ObjectPointerVisitor;
class PageSpace;
-class RawWeakProperty;
template <bool sync>
class MarkingVisitorBase;
class Thread;
diff --git a/runtime/vm/heap/pages.cc b/runtime/vm/heap/pages.cc
index 16776bd..1c6444c 100644
--- a/runtime/vm/heap/pages.cc
+++ b/runtime/vm/heap/pages.cc
@@ -97,9 +97,9 @@
uword obj_addr = object_start();
uword end_addr = object_end();
while (obj_addr < end_addr) {
- RawObject* raw_obj = RawObject::FromAddr(obj_addr);
+ ObjectPtr raw_obj = ObjectLayout::FromAddr(obj_addr);
visitor->VisitObject(raw_obj);
- obj_addr += raw_obj->HeapSize();
+ obj_addr += raw_obj->ptr()->HeapSize();
}
ASSERT(obj_addr == end_addr);
}
@@ -111,8 +111,8 @@
uword obj_addr = object_start();
uword end_addr = object_end();
while (obj_addr < end_addr) {
- RawObject* raw_obj = RawObject::FromAddr(obj_addr);
- obj_addr += raw_obj->VisitPointers(visitor);
+ ObjectPtr raw_obj = ObjectLayout::FromAddr(obj_addr);
+ obj_addr += raw_obj->ptr()->VisitPointers(visitor);
}
ASSERT(obj_addr == end_addr);
}
@@ -128,19 +128,19 @@
bool table_is_empty = false;
- RawArray* obj = static_cast<RawArray*>(RawObject::FromAddr(object_start()));
+ ArrayPtr obj = static_cast<ArrayPtr>(ObjectLayout::FromAddr(object_start()));
ASSERT(obj->IsArray());
- ASSERT(obj->IsCardRemembered());
- RawObject** obj_from = obj->from();
- RawObject** obj_to = obj->to(Smi::Value(obj->ptr()->length_));
+ ASSERT(obj->ptr()->IsCardRemembered());
+ ObjectPtr* obj_from = obj->ptr()->from();
+ ObjectPtr* obj_to = obj->ptr()->to(Smi::Value(obj->ptr()->length_));
const intptr_t size = card_table_size();
for (intptr_t i = 0; i < size; i++) {
if (card_table_[i] != 0) {
- RawObject** card_from =
- reinterpret_cast<RawObject**>(this) + (i << kSlotsPerCardLog2);
- RawObject** card_to = reinterpret_cast<RawObject**>(card_from) +
- (1 << kSlotsPerCardLog2) - 1;
+ ObjectPtr* card_from =
+ reinterpret_cast<ObjectPtr*>(this) + (i << kSlotsPerCardLog2);
+ ObjectPtr* card_to = reinterpret_cast<ObjectPtr*>(card_from) +
+ (1 << kSlotsPerCardLog2) - 1;
// Minus 1 because to is inclusive.
if (card_from < obj_from) {
@@ -156,7 +156,7 @@
visitor->VisitPointers(card_from, card_to);
bool has_new_target = false;
- for (RawObject** slot = card_from; slot <= card_to; slot++) {
+ for (ObjectPtr* slot = card_from; slot <= card_to; slot++) {
if ((*slot)->IsNewObjectMayBeSmi()) {
has_new_target = true;
break;
@@ -178,15 +178,15 @@
}
}
-RawObject* HeapPage::FindObject(FindObjectVisitor* visitor) const {
+ObjectPtr HeapPage::FindObject(FindObjectVisitor* visitor) const {
uword obj_addr = object_start();
uword end_addr = object_end();
if (visitor->VisitRange(obj_addr, end_addr)) {
while (obj_addr < end_addr) {
- RawObject* raw_obj = RawObject::FromAddr(obj_addr);
- uword next_obj_addr = obj_addr + raw_obj->HeapSize();
+ ObjectPtr raw_obj = ObjectLayout::FromAddr(obj_addr);
+ uword next_obj_addr = obj_addr + raw_obj->ptr()->HeapSize();
if (visitor->VisitRange(obj_addr, next_obj_addr) &&
- raw_obj->FindObject(visitor)) {
+ raw_obj->ptr()->FindObject(visitor)) {
return raw_obj; // Found object, return it.
}
obj_addr = next_obj_addr;
@@ -837,12 +837,12 @@
}
}
-RawObject* PageSpace::FindObject(FindObjectVisitor* visitor,
- HeapPage::PageType type) const {
+ObjectPtr PageSpace::FindObject(FindObjectVisitor* visitor,
+ HeapPage::PageType type) const {
if (type == HeapPage::kExecutable) {
// Fast path executable pages.
for (ExclusiveCodePageIterator it(this); !it.Done(); it.Advance()) {
- RawObject* obj = it.page()->FindObject(visitor);
+ ObjectPtr obj = it.page()->FindObject(visitor);
if (obj != Object::null()) {
return obj;
}
@@ -852,7 +852,7 @@
for (ExclusivePageIterator it(this); !it.Done(); it.Advance()) {
if (it.page()->type() == type) {
- RawObject* obj = it.page()->FindObject(visitor);
+ ObjectPtr obj = it.page()->FindObject(visitor);
if (obj != Object::null()) {
return obj;
}
@@ -902,8 +902,8 @@
class HeapMapAsJSONVisitor : public ObjectVisitor {
public:
explicit HeapMapAsJSONVisitor(JSONArray* array) : array_(array) {}
- virtual void VisitObject(RawObject* obj) {
- array_->AddValue(obj->HeapSize() / kObjectAlignment);
+ virtual void VisitObject(ObjectPtr obj) {
+ array_->AddValue(obj->ptr()->HeapSize() / kObjectAlignment);
array_->AddValue(obj->GetClassId());
}
@@ -1405,8 +1405,8 @@
image_pages_ = page;
}
-bool PageSpace::IsObjectFromImagePages(dart::RawObject* object) {
- uword object_addr = RawObject::ToAddr(object);
+bool PageSpace::IsObjectFromImagePages(dart::ObjectPtr object) {
+ uword object_addr = ObjectLayout::ToAddr(object);
HeapPage* image_page = image_pages_;
while (image_page != nullptr) {
if (image_page->Contains(object_addr)) {
diff --git a/runtime/vm/heap/pages.h b/runtime/vm/heap/pages.h
index 63aa158f..6460ae0 100644
--- a/runtime/vm/heap/pages.h
+++ b/runtime/vm/heap/pages.h
@@ -65,7 +65,7 @@
void VisitObjects(ObjectVisitor* visitor) const;
void VisitObjectPointers(ObjectPointerVisitor* visitor) const;
- RawObject* FindObject(FindObjectVisitor* visitor) const;
+ ObjectPtr FindObject(FindObjectVisitor* visitor) const;
void WriteProtect(bool read_only);
@@ -76,11 +76,10 @@
// Warning: This does not work for objects on image pages because image pages
// are not aligned. However, it works for objects on large pages, because
// only one object is allocated per large page.
- static HeapPage* Of(RawObject* obj) {
+ static HeapPage* Of(ObjectPtr obj) {
ASSERT(obj->IsHeapObject());
ASSERT(obj->IsOldObject());
- return reinterpret_cast<HeapPage*>(reinterpret_cast<uword>(obj) &
- kPageMask);
+ return reinterpret_cast<HeapPage*>(static_cast<uword>(obj) & kPageMask);
}
// Warning: This does not work for addresses on image pages or on large pages.
@@ -89,16 +88,16 @@
}
// Warning: This does not work for objects on image pages.
- static RawObject* ToExecutable(RawObject* obj) {
+ static ObjectPtr ToExecutable(ObjectPtr obj) {
HeapPage* page = Of(obj);
VirtualMemory* memory = page->memory_;
const intptr_t alias_offset = memory->AliasOffset();
if (alias_offset == 0) {
return obj; // Not aliased.
}
- uword addr = RawObject::ToAddr(obj);
+ uword addr = ObjectLayout::ToAddr(obj);
if (memory->Contains(addr)) {
- return RawObject::FromAddr(addr + alias_offset);
+ return ObjectLayout::FromAddr(addr + alias_offset);
}
// obj is executable.
ASSERT(memory->ContainsAlias(addr));
@@ -106,16 +105,16 @@
}
// Warning: This does not work for objects on image pages.
- static RawObject* ToWritable(RawObject* obj) {
+ static ObjectPtr ToWritable(ObjectPtr obj) {
HeapPage* page = Of(obj);
VirtualMemory* memory = page->memory_;
const intptr_t alias_offset = memory->AliasOffset();
if (alias_offset == 0) {
return obj; // Not aliased.
}
- uword addr = RawObject::ToAddr(obj);
+ uword addr = ObjectLayout::ToAddr(obj);
if (memory->ContainsAlias(addr)) {
- return RawObject::FromAddr(addr - alias_offset);
+ return ObjectLayout::FromAddr(addr - alias_offset);
}
// obj is writable.
ASSERT(memory->Contains(addr));
@@ -134,7 +133,7 @@
return OFFSET_OF(HeapPage, card_table_);
}
- void RememberCard(RawObject* const* slot) {
+ void RememberCard(ObjectPtr const* slot) {
ASSERT(Contains(reinterpret_cast<uword>(slot)));
if (card_table_ == NULL) {
card_table_ = reinterpret_cast<uint8_t*>(
@@ -362,8 +361,8 @@
void VisitRememberedCards(ObjectPointerVisitor* visitor) const;
- RawObject* FindObject(FindObjectVisitor* visitor,
- HeapPage::PageType type) const;
+ ObjectPtr FindObject(FindObjectVisitor* visitor,
+ HeapPage::PageType type) const;
// Collect the garbage in the page space using mark-sweep or mark-compact.
void CollectGarbage(bool compact, bool finalize);
@@ -471,7 +470,7 @@
enable_concurrent_mark_ = enable_concurrent_mark;
}
- bool IsObjectFromImagePages(RawObject* object);
+ bool IsObjectFromImagePages(ObjectPtr object);
void MergeOtherPageSpace(PageSpace* other);
diff --git a/runtime/vm/heap/pointer_block.h b/runtime/vm/heap/pointer_block.h
index a5505e2..73cf03b 100644
--- a/runtime/vm/heap/pointer_block.h
+++ b/runtime/vm/heap/pointer_block.h
@@ -8,15 +8,15 @@
#include "platform/assert.h"
#include "vm/globals.h"
#include "vm/os_thread.h"
+#include "vm/tagged_pointer.h"
namespace dart {
// Forward declarations.
class Isolate;
-class RawObject;
class ObjectPointerVisitor;
-// A set of RawObject*. Must be emptied before destruction (using Pop/Reset).
+// A set of ObjectPtr. Must be emptied before destruction (using Pop/Reset).
template <int Size>
class PointerBlock {
public:
@@ -33,18 +33,18 @@
bool IsFull() const { return Count() == kSize; }
bool IsEmpty() const { return Count() == 0; }
- void Push(RawObject* obj) {
+ void Push(ObjectPtr obj) {
ASSERT(!IsFull());
pointers_[top_++] = obj;
}
- RawObject* Pop() {
+ ObjectPtr Pop() {
ASSERT(!IsEmpty());
return pointers_[--top_];
}
#if defined(TESTING)
- bool Contains(RawObject* obj) const {
+ bool Contains(ObjectPtr obj) const {
// Generated code appends to store buffers; tell MemorySanitizer.
MSAN_UNPOISON(this, sizeof(*this));
for (intptr_t i = 0; i < Count(); i++) {
@@ -71,7 +71,7 @@
PointerBlock<Size>* next_;
int32_t top_;
- RawObject* pointers_[kSize];
+ ObjectPtr pointers_[kSize];
template <int>
friend class BlockStack;
@@ -159,7 +159,7 @@
}
// Returns nullptr if no more work was found.
- RawObject* Pop() {
+ ObjectPtr Pop() {
ASSERT(work_ != nullptr);
if (work_->IsEmpty()) {
// TODO(koda): Track over/underflow events and use in heuristics to
@@ -176,7 +176,7 @@
return work_->Pop();
}
- void Push(RawObject* raw_obj) {
+ void Push(ObjectPtr raw_obj) {
if (work_->IsFull()) {
// TODO(koda): Track over/underflow events and use in heuristics to
// distribute work and prevent degenerate flip-flopping.
diff --git a/runtime/vm/heap/scavenger.cc b/runtime/vm/heap/scavenger.cc
index 5c8e620..f708317 100644
--- a/runtime/vm/heap/scavenger.cc
+++ b/runtime/vm/heap/scavenger.cc
@@ -36,11 +36,11 @@
"Grow new gen when less than this percentage is garbage.");
DEFINE_FLAG(int, new_gen_growth_factor, 2, "Grow new gen by this factor.");
-// Scavenger uses RawObject::kMarkBit to distinguish forwarded and non-forwarded
-// objects. The kMarkBit does not intersect with the target address because of
-// object alignment.
+// Scavenger uses ObjectLayout::kMarkBit to distinguish forwarded and
+// non-forwarded objects. The kMarkBit does not intersect with the target
+// address because of object alignment.
enum {
- kForwardingMask = 1 << RawObject::kOldAndNotMarkedBit,
+ kForwardingMask = 1 << ObjectLayout::kOldAndNotMarkedBit,
kNotForwarded = 0,
kForwarded = kForwardingMask,
};
@@ -109,7 +109,7 @@
page_space_(scavenger->heap_->old_space()),
freelist_(freelist),
bytes_promoted_(0),
- visiting_old_object_(NULL),
+ visiting_old_object_(nullptr),
promoted_list_(promotion_stack),
labs_(8) {
ASSERT(labs_.length() == 0);
@@ -117,28 +117,28 @@
ASSERT(labs_.length() == 1);
}
- virtual void VisitTypedDataViewPointers(RawTypedDataView* view,
- RawObject** first,
- RawObject** last) {
+ virtual void VisitTypedDataViewPointers(TypedDataViewPtr view,
+ ObjectPtr* first,
+ ObjectPtr* last) {
// First we forward all fields of the typed data view.
VisitPointers(first, last);
if (view->ptr()->data_ == nullptr) {
- ASSERT(ValueFromRawSmi(view->ptr()->offset_in_bytes_) == 0 &&
- ValueFromRawSmi(view->ptr()->length_) == 0);
+ ASSERT(RawSmiValue(view->ptr()->offset_in_bytes_) == 0 &&
+ RawSmiValue(view->ptr()->length_) == 0);
return;
}
// Validate 'this' is a typed data view.
const uword view_header =
- *reinterpret_cast<uword*>(RawObject::ToAddr(view));
+ *reinterpret_cast<uword*>(ObjectLayout::ToAddr(view));
ASSERT(!IsForwarding(view_header) || view->IsOldObject());
ASSERT(IsTypedDataViewClassId(view->GetClassIdMayBeSmi()));
// Validate that the backing store is not a forwarding word.
- RawTypedDataBase* td = view->ptr()->typed_data_;
+ TypedDataBasePtr td = view->ptr()->typed_data_;
ASSERT(td->IsHeapObject());
- const uword td_header = *reinterpret_cast<uword*>(RawObject::ToAddr(td));
+ const uword td_header = *reinterpret_cast<uword*>(ObjectLayout::ToAddr(td));
ASSERT(!IsForwarding(td_header) || td->IsOldObject());
// We can always obtain the class id from the forwarded backing store.
@@ -152,23 +152,23 @@
// Now we update the inner pointer.
ASSERT(IsTypedDataClassId(cid));
- view->RecomputeDataFieldForInternalTypedData();
+ view->ptr()->RecomputeDataFieldForInternalTypedData();
}
- virtual void VisitPointers(RawObject** first, RawObject** last) {
+ virtual void VisitPointers(ObjectPtr* first, ObjectPtr* last) {
ASSERT(Utils::IsAligned(first, sizeof(*first)));
ASSERT(Utils::IsAligned(last, sizeof(*last)));
- for (RawObject** current = first; current <= last; current++) {
+ for (ObjectPtr* current = first; current <= last; current++) {
ScavengePointer(current);
}
}
- void VisitingOldObject(RawObject* obj) {
- ASSERT((obj == NULL) || obj->IsOldObject());
+ void VisitingOldObject(ObjectPtr obj) {
+ ASSERT((obj == nullptr) || obj->IsOldObject());
visiting_old_object_ = obj;
- if (obj != NULL) {
+ if (obj != nullptr) {
// Card update happens in HeapPage::VisitRememberedCards.
- ASSERT(!obj->IsCardRemembered());
+ ASSERT(!obj->ptr()->IsCardRemembered());
}
}
@@ -248,26 +248,26 @@
}
private:
- void UpdateStoreBuffer(RawObject** p, RawObject* obj) {
+ void UpdateStoreBuffer(ObjectPtr* p, ObjectPtr obj) {
ASSERT(obj->IsHeapObject());
// If the newly written object is not a new object, drop it immediately.
- if (!obj->IsNewObject() || visiting_old_object_->IsRemembered()) {
+ if (!obj->IsNewObject() || visiting_old_object_->ptr()->IsRemembered()) {
return;
}
- visiting_old_object_->SetRememberedBit();
+ visiting_old_object_->ptr()->SetRememberedBit();
thread_->StoreBufferAddObjectGC(visiting_old_object_);
}
DART_FORCE_INLINE
- void ScavengePointer(RawObject** p) {
+ void ScavengePointer(ObjectPtr* p) {
// ScavengePointer cannot be called recursively.
- RawObject* raw_obj = *p;
+ ObjectPtr raw_obj = *p;
if (raw_obj->IsSmiOrOldObject()) {
return;
}
- uword raw_addr = RawObject::ToAddr(raw_obj);
+ uword raw_addr = ObjectLayout::ToAddr(raw_obj);
// The scavenger is only expects objects located in the from space.
ASSERT(from_->Contains(raw_addr));
// Read the header word of the object and determine if the object has
@@ -279,7 +279,7 @@
// Get the new location of the object.
new_addr = ForwardedAddr(header);
} else {
- intptr_t size = raw_obj->HeapSize(header);
+ intptr_t size = raw_obj->ptr()->HeapSize(header);
// Check whether object should be promoted.
if (raw_addr >= scavenger_->survivor_end_) {
// Not a survivor of a previous scavenge. Just copy the object into the
@@ -293,7 +293,7 @@
if (LIKELY(new_addr != 0)) {
// If promotion succeeded then we need to remember it so that it can
// be traversed later.
- promoted_list_.Push(RawObject::FromAddr(new_addr));
+ promoted_list_.Push(ObjectLayout::FromAddr(new_addr));
bytes_promoted_ += size;
} else {
// Promotion did not succeed. Copy into the to space instead.
@@ -311,28 +311,28 @@
objcpy(reinterpret_cast<void*>(new_addr),
reinterpret_cast<void*>(raw_addr), size);
- RawObject* new_obj = RawObject::FromAddr(new_addr);
+ ObjectPtr new_obj = ObjectLayout::FromAddr(new_addr);
if (new_obj->IsOldObject()) {
// Promoted: update age/barrier tags.
uint32_t tags = static_cast<uint32_t>(header);
- tags = RawObject::OldBit::update(true, tags);
- tags = RawObject::OldAndNotRememberedBit::update(true, tags);
- tags = RawObject::NewBit::update(false, tags);
+ tags = ObjectLayout::OldBit::update(true, tags);
+ tags = ObjectLayout::OldAndNotRememberedBit::update(true, tags);
+ tags = ObjectLayout::NewBit::update(false, tags);
// Setting the forwarding pointer below will make this tenured object
// visible to the concurrent marker, but we haven't visited its slots
// yet. We mark the object here to prevent the concurrent marker from
// adding it to the mark stack and visiting its unprocessed slots. We
// push it to the mark stack after forwarding its slots.
- tags =
- RawObject::OldAndNotMarkedBit::update(!thread_->is_marking(), tags);
+ tags = ObjectLayout::OldAndNotMarkedBit::update(!thread_->is_marking(),
+ tags);
new_obj->ptr()->tags_ = tags;
} else {
ASSERT(scavenger_->to_->Contains(new_addr));
}
- intptr_t cid = RawObject::ClassIdTag::decode(header);
+ intptr_t cid = ObjectLayout::ClassIdTag::decode(header);
if (IsTypedDataClassId(cid)) {
- reinterpret_cast<RawTypedData*>(new_obj)->RecomputeDataField();
+ static_cast<TypedDataPtr>(new_obj)->ptr()->RecomputeDataField();
}
// Try to install forwarding address.
@@ -350,27 +350,27 @@
}
// Use the winner's forwarding target.
new_addr = ForwardedAddr(header);
- if (RawObject::FromAddr(new_addr)->IsNewObject()) {
+ if (ObjectLayout::FromAddr(new_addr)->IsNewObject()) {
ASSERT(scavenger_->to_->Contains(new_addr));
}
}
}
// Update the reference.
- RawObject* new_obj = RawObject::FromAddr(new_addr);
+ ObjectPtr new_obj = ObjectLayout::FromAddr(new_addr);
if (!new_obj->IsNewObject()) {
// Setting the mark bit above must not be ordered after a publishing store
// of this object. Note this could be a publishing store even if the
// object was promoted by an early invocation of ScavengePointer. Compare
// Object::Allocate.
- reinterpret_cast<std::atomic<RawObject*>*>(p)->store(
+ reinterpret_cast<std::atomic<ObjectPtr>*>(p)->store(
new_obj, std::memory_order_release);
} else {
- ASSERT(scavenger_->to_->Contains(RawObject::ToAddr(new_obj)));
+ ASSERT(scavenger_->to_->Contains(ObjectLayout::ToAddr(new_obj)));
*p = new_obj;
}
// Update the store buffer as needed.
- if (visiting_old_object_ != NULL) {
+ if (visiting_old_object_ != nullptr) {
UpdateStoreBuffer(p, new_obj);
}
}
@@ -415,14 +415,14 @@
if (size != 0) {
ASSERT(Utils::IsAligned(size, kObjectAlignment));
ForwardingCorpse::AsForwarder(top, size);
- ASSERT(RawObject::FromAddr(top)->HeapSize() == size);
+ ASSERT(ObjectLayout::FromAddr(top)->ptr()->HeapSize() == size);
}
}
inline void ProcessToSpace();
- DART_FORCE_INLINE intptr_t ProcessCopied(RawObject* raw_obj);
+ DART_FORCE_INLINE intptr_t ProcessCopied(ObjectPtr raw_obj);
inline void ProcessPromotedList();
- inline void EnqueueWeakProperty(RawWeakProperty* raw_weak);
+ inline void EnqueueWeakProperty(WeakPropertyPtr raw_weak);
inline void MournWeakProperties();
Thread* thread_;
@@ -431,10 +431,10 @@
PageSpace* page_space_;
FreeList* freelist_;
intptr_t bytes_promoted_;
- RawObject* visiting_old_object_;
+ ObjectPtr visiting_old_object_;
PromotionWorkList promoted_list_;
- RawWeakProperty* delayed_weak_properties_ = nullptr;
+ WeakPropertyPtr delayed_weak_properties_ = nullptr;
struct ScavengerLAB {
uword top;
@@ -463,7 +463,7 @@
void VisitHandle(uword addr) {
FinalizablePersistentHandle* handle =
reinterpret_cast<FinalizablePersistentHandle*>(addr);
- RawObject** p = handle->raw_addr();
+ ObjectPtr* p = handle->raw_addr();
if (scavenger_->IsUnreachable(p)) {
handle->UpdateUnreachable(thread()->isolate_group());
} else {
@@ -734,11 +734,11 @@
: ObjectPointerVisitor(IsolateGroup::Current()),
in_store_buffer_(in_store_buffer) {}
- void VisitPointers(RawObject** from, RawObject** to) {
- for (RawObject** ptr = from; ptr <= to; ptr++) {
- RawObject* raw_obj = *ptr;
- RELEASE_ASSERT(!raw_obj->IsCardRemembered());
- RELEASE_ASSERT(raw_obj->IsRemembered());
+ void VisitPointers(ObjectPtr* from, ObjectPtr* to) {
+ for (ObjectPtr* ptr = from; ptr <= to; ptr++) {
+ ObjectPtr raw_obj = *ptr;
+ RELEASE_ASSERT(!raw_obj->ptr()->IsCardRemembered());
+ RELEASE_ASSERT(raw_obj->ptr()->IsRemembered());
RELEASE_ASSERT(raw_obj->IsOldObject());
in_store_buffer_->Add(raw_obj);
}
@@ -757,36 +757,37 @@
in_store_buffer_(in_store_buffer),
to_(to) {}
- void VisitObject(RawObject* raw_obj) {
+ void VisitObject(ObjectPtr raw_obj) {
if (raw_obj->IsPseudoObject()) return;
RELEASE_ASSERT(raw_obj->IsOldObject());
- if (raw_obj->IsCardRemembered()) {
- RELEASE_ASSERT(!raw_obj->IsRemembered());
+ if (raw_obj->ptr()->IsCardRemembered()) {
+ RELEASE_ASSERT(!raw_obj->ptr()->IsRemembered());
// TODO(rmacnak): Verify card tables.
return;
}
- RELEASE_ASSERT(raw_obj->IsRemembered() ==
+ RELEASE_ASSERT(raw_obj->ptr()->IsRemembered() ==
in_store_buffer_->Contains(raw_obj));
visiting_ = raw_obj;
- is_remembered_ = raw_obj->IsRemembered();
- raw_obj->VisitPointers(this);
+ is_remembered_ = raw_obj->ptr()->IsRemembered();
+ raw_obj->ptr()->VisitPointers(this);
}
- void VisitPointers(RawObject** from, RawObject** to) {
- for (RawObject** ptr = from; ptr <= to; ptr++) {
- RawObject* raw_obj = *ptr;
+ void VisitPointers(ObjectPtr* from, ObjectPtr* to) {
+ for (ObjectPtr* ptr = from; ptr <= to; ptr++) {
+ ObjectPtr raw_obj = *ptr;
if (raw_obj->IsHeapObject() && raw_obj->IsNewObject()) {
if (!is_remembered_) {
FATAL3(
- "Old object %p references new object %p, but it is not in any"
- " store buffer. Consider using rr to watch the slot %p and "
- "reverse-continue to find the store with a missing barrier.\n",
- visiting_, raw_obj, ptr);
+ "Old object %#" Px "references new object %#" Px
+ ", but it is not"
+ " in any store buffer. Consider using rr to watch the slot %p and"
+ " reverse-continue to find the store with a missing barrier.\n",
+ static_cast<uword>(visiting_), static_cast<uword>(raw_obj), ptr);
}
- RELEASE_ASSERT(to_->Contains(RawObject::ToAddr(raw_obj)));
+ RELEASE_ASSERT(to_->Contains(ObjectLayout::ToAddr(raw_obj)));
}
}
}
@@ -794,7 +795,7 @@
private:
const ObjectSet* const in_store_buffer_;
const SemiSpace* const to_;
- RawObject* visiting_;
+ ObjectPtr visiting_;
bool is_remembered_;
};
@@ -845,9 +846,12 @@
OUT_OF_MEMORY();
}
UpdateMaxHeapCapacity();
- top_ = FirstObjectStart();
- resolved_top_ = top_;
- end_ = to_->end();
+ {
+ MutexLocker ml(&space_lock_);
+ top_ = FirstObjectStart();
+ resolved_top_ = top_;
+ end_ = to_->end();
+ }
return from;
}
@@ -983,14 +987,14 @@
intptr_t count = pending->Count();
total_count += count;
while (!pending->IsEmpty()) {
- RawObject* raw_object = pending->Pop();
+ ObjectPtr raw_object = pending->Pop();
ASSERT(!raw_object->IsForwardingCorpse());
- ASSERT(raw_object->IsRemembered());
- raw_object->ClearRememberedBit();
+ ASSERT(raw_object->ptr()->IsRemembered());
+ raw_object->ptr()->ClearRememberedBit();
visitor->VisitingOldObject(raw_object);
// Note that this treats old-space WeakProperties as strong. A dead key
// won't be reclaimed until after the key is promoted.
- raw_object->VisitPointersNonvirtual(visitor);
+ raw_object->ptr()->VisitPointersNonvirtual(visitor);
}
pending->Reset();
// Return the emptied block for recycling (no need to check threshold).
@@ -1059,22 +1063,22 @@
}
}
-bool Scavenger::IsUnreachable(RawObject** p) {
- RawObject* raw_obj = *p;
+bool Scavenger::IsUnreachable(ObjectPtr* p) {
+ ObjectPtr raw_obj = *p;
if (!raw_obj->IsHeapObject()) {
return false;
}
if (!raw_obj->IsNewObject()) {
return false;
}
- uword raw_addr = RawObject::ToAddr(raw_obj);
+ uword raw_addr = ObjectLayout::ToAddr(raw_obj);
if (to_->Contains(raw_addr)) {
return false;
}
uword header = *reinterpret_cast<uword*>(raw_addr);
if (IsForwarding(header)) {
uword new_addr = ForwardedAddr(header);
- *p = RawObject::FromAddr(new_addr);
+ *p = ObjectLayout::FromAddr(new_addr);
return false;
}
return true;
@@ -1093,7 +1097,7 @@
while (i <= producer_index_) {
uword resolved_top = labs_[i].resolved_top;
while (resolved_top < labs_[i].top) {
- RawObject* raw_obj = RawObject::FromAddr(resolved_top);
+ ObjectPtr raw_obj = ObjectLayout::FromAddr(resolved_top);
resolved_top += ProcessCopied(raw_obj);
}
labs_[i].resolved_top = resolved_top;
@@ -1110,14 +1114,15 @@
template <bool parallel>
void ScavengerVisitorBase<parallel>::ProcessPromotedList() {
- while (RawObject* raw_object = promoted_list_.Pop()) {
+ ObjectPtr raw_object;
+ while ((raw_object = promoted_list_.Pop()) != nullptr) {
// Resolve or copy all objects referred to by the current object. This
// can potentially push more objects on this stack as well as add more
// objects to be resolved in the to space.
- ASSERT(!raw_object->IsRemembered());
+ ASSERT(!raw_object->ptr()->IsRemembered());
VisitingOldObject(raw_object);
- raw_object->VisitPointersNonvirtual(this);
- if (raw_object->IsMarked()) {
+ raw_object->ptr()->VisitPointersNonvirtual(this);
+ if (raw_object->ptr()->IsMarked()) {
// Complete our promise from ScavengePointer. Note that marker cannot
// visit this object until it pops a block from the mark stack, which
// involves a memory fence from the mutex, so even on architectures
@@ -1134,31 +1139,31 @@
// Finished this round of scavenging. Process the pending weak properties
// for which the keys have become reachable. Potentially this adds more
// objects to the to space.
- RawWeakProperty* cur_weak = delayed_weak_properties_;
- delayed_weak_properties_ = NULL;
- while (cur_weak != NULL) {
+ WeakPropertyPtr cur_weak = delayed_weak_properties_;
+ delayed_weak_properties_ = nullptr;
+ while (cur_weak != nullptr) {
uword next_weak = cur_weak->ptr()->next_;
// Promoted weak properties are not enqueued. So we can guarantee that
// we do not need to think about store barriers here.
ASSERT(cur_weak->IsNewObject());
- RawObject* raw_key = cur_weak->ptr()->key_;
+ ObjectPtr raw_key = cur_weak->ptr()->key_;
ASSERT(raw_key->IsHeapObject());
// Key still points into from space even if the object has been
// promoted to old space by now. The key will be updated accordingly
// below when VisitPointers is run.
ASSERT(raw_key->IsNewObject());
- uword raw_addr = RawObject::ToAddr(raw_key);
+ uword raw_addr = ObjectLayout::ToAddr(raw_key);
ASSERT(from_->Contains(raw_addr));
uword header = *reinterpret_cast<uword*>(raw_addr);
// Reset the next pointer in the weak property.
cur_weak->ptr()->next_ = 0;
if (IsForwarding(header)) {
- cur_weak->VisitPointersNonvirtual(this);
+ cur_weak->ptr()->VisitPointersNonvirtual(this);
} else {
EnqueueWeakProperty(cur_weak);
}
// Advance to next weak property in the queue.
- cur_weak = reinterpret_cast<RawWeakProperty*>(next_weak);
+ cur_weak = static_cast<WeakPropertyPtr>(next_weak);
}
}
@@ -1193,39 +1198,39 @@
template <bool parallel>
void ScavengerVisitorBase<parallel>::EnqueueWeakProperty(
- RawWeakProperty* raw_weak) {
+ WeakPropertyPtr raw_weak) {
ASSERT(raw_weak->IsHeapObject());
ASSERT(raw_weak->IsNewObject());
ASSERT(raw_weak->IsWeakProperty());
#if defined(DEBUG)
- uword raw_addr = RawObject::ToAddr(raw_weak);
+ uword raw_addr = ObjectLayout::ToAddr(raw_weak);
uword header = *reinterpret_cast<uword*>(raw_addr);
ASSERT(!IsForwarding(header));
#endif // defined(DEBUG)
ASSERT(raw_weak->ptr()->next_ == 0);
- raw_weak->ptr()->next_ = reinterpret_cast<uword>(delayed_weak_properties_);
+ raw_weak->ptr()->next_ = static_cast<uword>(delayed_weak_properties_);
delayed_weak_properties_ = raw_weak;
}
template <bool parallel>
-intptr_t ScavengerVisitorBase<parallel>::ProcessCopied(RawObject* raw_obj) {
+intptr_t ScavengerVisitorBase<parallel>::ProcessCopied(ObjectPtr raw_obj) {
intptr_t class_id = raw_obj->GetClassId();
if (UNLIKELY(class_id == kWeakPropertyCid)) {
- RawWeakProperty* raw_weak = reinterpret_cast<RawWeakProperty*>(raw_obj);
+ WeakPropertyPtr raw_weak = static_cast<WeakPropertyPtr>(raw_obj);
// The fate of the weak property is determined by its key.
- RawObject* raw_key = raw_weak->ptr()->key_;
+ ObjectPtr raw_key = raw_weak->ptr()->key_;
if (raw_key->IsHeapObject() && raw_key->IsNewObject()) {
- uword raw_addr = RawObject::ToAddr(raw_key);
+ uword raw_addr = ObjectLayout::ToAddr(raw_key);
uword header = *reinterpret_cast<uword*>(raw_addr);
if (!IsForwarding(header)) {
// Key is white. Enqueue the weak property.
EnqueueWeakProperty(raw_weak);
- return raw_weak->HeapSize();
+ return raw_weak->ptr()->HeapSize();
}
}
// Key is gray or black. Make the weak property black.
}
- return raw_obj->VisitPointersNonvirtual(this);
+ return raw_obj->ptr()->VisitPointersNonvirtual(this);
}
void Scavenger::MournWeakTables() {
@@ -1236,14 +1241,14 @@
intptr_t size = table->size();
for (intptr_t i = 0; i < size; i++) {
if (table->IsValidEntryAtExclusive(i)) {
- RawObject* raw_obj = table->ObjectAtExclusive(i);
+ ObjectPtr raw_obj = table->ObjectAtExclusive(i);
ASSERT(raw_obj->IsHeapObject());
- uword raw_addr = RawObject::ToAddr(raw_obj);
+ uword raw_addr = ObjectLayout::ToAddr(raw_obj);
uword header = *reinterpret_cast<uword*>(raw_addr);
if (IsForwarding(header)) {
// The object has survived. Preserve its record.
uword new_addr = ForwardedAddr(header);
- raw_obj = RawObject::FromAddr(new_addr);
+ raw_obj = ObjectLayout::FromAddr(new_addr);
auto replacement =
raw_obj->IsNewObject() ? replacement_new : replacement_old;
replacement->SetValueExclusive(raw_obj, table->ValueAtExclusive(i));
@@ -1286,16 +1291,16 @@
void ScavengerVisitorBase<parallel>::MournWeakProperties() {
// The queued weak properties at this point do not refer to reachable keys,
// so we clear their key and value fields.
- RawWeakProperty* cur_weak = delayed_weak_properties_;
- delayed_weak_properties_ = NULL;
- while (cur_weak != NULL) {
+ WeakPropertyPtr cur_weak = delayed_weak_properties_;
+ delayed_weak_properties_ = nullptr;
+ while (cur_weak != nullptr) {
uword next_weak = cur_weak->ptr()->next_;
// Reset the next pointer in the weak property.
cur_weak->ptr()->next_ = 0;
#if defined(DEBUG)
- RawObject* raw_key = cur_weak->ptr()->key_;
- uword raw_addr = RawObject::ToAddr(raw_key);
+ ObjectPtr raw_key = cur_weak->ptr()->key_;
+ uword raw_addr = ObjectLayout::ToAddr(raw_key);
uword header = *reinterpret_cast<uword*>(raw_addr);
ASSERT(!IsForwarding(header));
ASSERT(raw_key->IsHeapObject());
@@ -1305,7 +1310,7 @@
WeakProperty::Clear(cur_weak);
// Advance to next weak property in the queue.
- cur_weak = reinterpret_cast<RawWeakProperty*>(next_weak);
+ cur_weak = static_cast<WeakPropertyPtr>(next_weak);
}
}
@@ -1381,8 +1386,8 @@
MakeNewSpaceIterable();
uword cur = FirstObjectStart();
while (cur < top_) {
- RawObject* raw_obj = RawObject::FromAddr(cur);
- cur += raw_obj->VisitPointers(visitor);
+ ObjectPtr raw_obj = ObjectLayout::FromAddr(cur);
+ cur += raw_obj->ptr()->VisitPointers(visitor);
}
}
@@ -1392,9 +1397,9 @@
MakeNewSpaceIterable();
uword cur = FirstObjectStart();
while (cur < top_) {
- RawObject* raw_obj = RawObject::FromAddr(cur);
+ ObjectPtr raw_obj = ObjectLayout::FromAddr(cur);
visitor->VisitObject(raw_obj);
- cur += raw_obj->HeapSize();
+ cur += raw_obj->ptr()->HeapSize();
}
}
@@ -1402,15 +1407,16 @@
set->AddRegion(to_->start(), to_->end());
}
-RawObject* Scavenger::FindObject(FindObjectVisitor* visitor) {
+ObjectPtr Scavenger::FindObject(FindObjectVisitor* visitor) {
ASSERT(!scavenging_);
MakeNewSpaceIterable();
uword cur = FirstObjectStart();
if (visitor->VisitRange(cur, top_)) {
while (cur < top_) {
- RawObject* raw_obj = RawObject::FromAddr(cur);
- uword next = cur + raw_obj->HeapSize();
- if (visitor->VisitRange(cur, next) && raw_obj->FindObject(visitor)) {
+ ObjectPtr raw_obj = ObjectLayout::FromAddr(cur);
+ uword next = cur + raw_obj->ptr()->HeapSize();
+ if (visitor->VisitRange(cur, next) &&
+ raw_obj->ptr()->FindObject(visitor)) {
return raw_obj; // Found object, return it.
}
cur = next;
@@ -1458,7 +1464,7 @@
if (size >= kObjectAlignment) {
// ForwardingCorpse(forwarding to default null) will work as filler.
ForwardingCorpse::AsForwarder(tlab.top, size);
- ASSERT(RawObject::FromAddr(tlab.top)->HeapSize() == size);
+ ASSERT(ObjectLayout::FromAddr(tlab.top)->ptr()->HeapSize() == size);
}
}
diff --git a/runtime/vm/heap/scavenger.h b/runtime/vm/heap/scavenger.h
index 0e23b5d..6358289 100644
--- a/runtime/vm/heap/scavenger.h
+++ b/runtime/vm/heap/scavenger.h
@@ -130,7 +130,7 @@
// be part of the surviving objects.
bool Contains(uword addr) const { return to_->Contains(addr); }
- RawObject* FindObject(FindObjectVisitor* visitor);
+ ObjectPtr FindObject(FindObjectVisitor* visitor);
uword TryAllocate(Thread* thread, intptr_t size) {
uword addr = TryAllocateFromTLAB(thread, size);
@@ -288,7 +288,7 @@
void MournWeakHandles();
void Epilogue(SemiSpace* from);
- bool IsUnreachable(RawObject** p);
+ bool IsUnreachable(ObjectPtr* p);
void VerifyStoreBuffers();
diff --git a/runtime/vm/heap/scavenger_test.cc b/runtime/vm/heap/scavenger_test.cc
index 64b2a31..8d405eb 100644
--- a/runtime/vm/heap/scavenger_test.cc
+++ b/runtime/vm/heap/scavenger_test.cc
@@ -13,14 +13,14 @@
class FailingObjectVisitor : public ObjectVisitor {
public:
FailingObjectVisitor() {}
- virtual void VisitObject(RawObject* obj) { EXPECT(false); }
+ virtual void VisitObject(ObjectPtr obj) { EXPECT(false); }
};
// Expects to visit no objects (since the space should be empty).
class FailingObjectPointerVisitor : public ObjectPointerVisitor {
public:
FailingObjectPointerVisitor() : ObjectPointerVisitor(NULL) {}
- virtual void VisitPointers(RawObject** first, RawObject** last) {
+ virtual void VisitPointers(ObjectPtr* first, ObjectPtr* last) {
EXPECT(false);
}
};
@@ -29,7 +29,7 @@
class FailingFindObjectVisitor : public FindObjectVisitor {
public:
FailingFindObjectVisitor() {}
- virtual bool FindObject(RawObject* obj) const {
+ virtual bool FindObject(ObjectPtr obj) const {
EXPECT(false);
return false;
}
diff --git a/runtime/vm/heap/sweeper.cc b/runtime/vm/heap/sweeper.cc
index 96cf844..5581e45 100644
--- a/runtime/vm/heap/sweeper.cc
+++ b/runtime/vm/heap/sweeper.cc
@@ -28,23 +28,23 @@
while (current < end) {
intptr_t obj_size;
- RawObject* raw_obj = RawObject::FromAddr(current);
+ ObjectPtr raw_obj = ObjectLayout::FromAddr(current);
ASSERT(HeapPage::Of(raw_obj) == page);
- if (raw_obj->IsMarked()) {
+ if (raw_obj->ptr()->IsMarked()) {
// Found marked object. Clear the mark bit and update swept bytes.
- raw_obj->ClearMarkBit();
- obj_size = raw_obj->HeapSize();
+ raw_obj->ptr()->ClearMarkBit();
+ obj_size = raw_obj->ptr()->HeapSize();
used_in_bytes += obj_size;
} else {
- uword free_end = current + raw_obj->HeapSize();
+ uword free_end = current + raw_obj->ptr()->HeapSize();
while (free_end < end) {
- RawObject* next_obj = RawObject::FromAddr(free_end);
- if (next_obj->IsMarked()) {
+ ObjectPtr next_obj = ObjectLayout::FromAddr(free_end);
+ if (next_obj->ptr()->IsMarked()) {
// Reached the end of the free block.
break;
}
// Expand the free block by the size of this object.
- free_end += next_obj->HeapSize();
+ free_end += next_obj->ptr()->HeapSize();
}
obj_size = free_end - current;
if (is_executable) {
@@ -80,21 +80,21 @@
ASSERT(!page->is_image_page());
intptr_t words_to_end = 0;
- RawObject* raw_obj = RawObject::FromAddr(page->object_start());
+ ObjectPtr raw_obj = ObjectLayout::FromAddr(page->object_start());
ASSERT(HeapPage::Of(raw_obj) == page);
- if (raw_obj->IsMarked()) {
- raw_obj->ClearMarkBit();
- words_to_end = (raw_obj->HeapSize() >> kWordSizeLog2);
+ if (raw_obj->ptr()->IsMarked()) {
+ raw_obj->ptr()->ClearMarkBit();
+ words_to_end = (raw_obj->ptr()->HeapSize() >> kWordSizeLog2);
}
#ifdef DEBUG
// Array::MakeFixedLength creates trailing filler objects,
// but they are always unreachable. Verify that they are not marked.
- uword current = RawObject::ToAddr(raw_obj) + raw_obj->HeapSize();
+ uword current = ObjectLayout::ToAddr(raw_obj) + raw_obj->ptr()->HeapSize();
uword end = page->object_end();
while (current < end) {
- RawObject* cur_obj = RawObject::FromAddr(current);
- ASSERT(!cur_obj->IsMarked());
- intptr_t obj_size = cur_obj->HeapSize();
+ ObjectPtr cur_obj = ObjectLayout::FromAddr(current);
+ ASSERT(!cur_obj->ptr()->IsMarked());
+ intptr_t obj_size = cur_obj->ptr()->HeapSize();
memset(reinterpret_cast<void*>(current), Heap::kZapByte, obj_size);
current += obj_size;
}
diff --git a/runtime/vm/heap/verifier.cc b/runtime/vm/heap/verifier.cc
index 12762ec..777cf33 100644
--- a/runtime/vm/heap/verifier.cc
+++ b/runtime/vm/heap/verifier.cc
@@ -16,24 +16,24 @@
namespace dart {
-void VerifyObjectVisitor::VisitObject(RawObject* raw_obj) {
+void VerifyObjectVisitor::VisitObject(ObjectPtr raw_obj) {
if (raw_obj->IsHeapObject()) {
- uword raw_addr = RawObject::ToAddr(raw_obj);
+ uword raw_addr = ObjectLayout::ToAddr(raw_obj);
if (raw_obj->IsFreeListElement() || raw_obj->IsForwardingCorpse()) {
- if (raw_obj->IsOldObject() && raw_obj->IsMarked()) {
+ if (raw_obj->IsOldObject() && raw_obj->ptr()->IsMarked()) {
FATAL1("Marked free list element encountered %#" Px "\n", raw_addr);
}
} else {
switch (mark_expectation_) {
case kForbidMarked:
- if (raw_obj->IsOldObject() && raw_obj->IsMarked()) {
+ if (raw_obj->IsOldObject() && raw_obj->ptr()->IsMarked()) {
FATAL1("Marked object encountered %#" Px "\n", raw_addr);
}
break;
case kAllowMarked:
break;
case kRequireMarked:
- if (raw_obj->IsOldObject() && !raw_obj->IsMarked()) {
+ if (raw_obj->IsOldObject() && !raw_obj->ptr()->IsMarked()) {
FATAL1("Unmarked object encountered %#" Px "\n", raw_addr);
}
break;
@@ -44,16 +44,16 @@
raw_obj->Validate(isolate_group_);
}
-void VerifyPointersVisitor::VisitPointers(RawObject** first, RawObject** last) {
- for (RawObject** current = first; current <= last; current++) {
- RawObject* raw_obj = *current;
+void VerifyPointersVisitor::VisitPointers(ObjectPtr* first, ObjectPtr* last) {
+ for (ObjectPtr* current = first; current <= last; current++) {
+ ObjectPtr raw_obj = *current;
if (raw_obj->IsHeapObject()) {
if (!allocated_set_->Contains(raw_obj)) {
if (raw_obj->IsInstructions() &&
allocated_set_->Contains(HeapPage::ToWritable(raw_obj))) {
continue;
}
- uword raw_addr = RawObject::ToAddr(raw_obj);
+ uword raw_addr = ObjectLayout::ToAddr(raw_obj);
FATAL1("Invalid object pointer encountered %#" Px "\n", raw_addr);
}
}
@@ -63,7 +63,7 @@
void VerifyWeakPointersVisitor::VisitHandle(uword addr) {
FinalizablePersistentHandle* handle =
reinterpret_cast<FinalizablePersistentHandle*>(addr);
- RawObject* raw_obj = handle->raw();
+ ObjectPtr raw_obj = handle->raw();
visitor_->VisitPointer(&raw_obj);
}
@@ -88,7 +88,7 @@
VerifyCanonicalVisitor::VerifyCanonicalVisitor(Thread* thread)
: thread_(thread), instanceHandle_(Instance::Handle(thread->zone())) {}
-void VerifyCanonicalVisitor::VisitObject(RawObject* obj) {
+void VerifyCanonicalVisitor::VisitObject(ObjectPtr obj) {
// TODO(dartbug.com/36097): The heap walk can encounter canonical objects of
// other isolates. We should either scan live objects from the roots of each
// individual isolate, or wait until we are ready to share constants across
@@ -96,7 +96,7 @@
if (!FLAG_enable_isolate_groups) {
if ((obj->GetClassId() >= kInstanceCid) &&
(obj->GetClassId() != kTypeArgumentsCid)) {
- if (obj->IsCanonical()) {
+ if (obj->ptr()->IsCanonical()) {
instanceHandle_ ^= obj;
const bool is_canonical = instanceHandle_.CheckIsCanonical(thread_);
if (!is_canonical) {
diff --git a/runtime/vm/heap/verifier.h b/runtime/vm/heap/verifier.h
index ae13e90..3733125 100644
--- a/runtime/vm/heap/verifier.h
+++ b/runtime/vm/heap/verifier.h
@@ -17,7 +17,6 @@
// Forward declarations.
class IsolateGroup;
class ObjectSet;
-class RawObject;
enum MarkExpectation { kForbidMarked, kAllowMarked, kRequireMarked };
@@ -30,7 +29,7 @@
allocated_set_(allocated_set),
mark_expectation_(mark_expectation) {}
- virtual void VisitObject(RawObject* obj);
+ virtual void VisitObject(ObjectPtr obj);
private:
IsolateGroup* isolate_group_;
@@ -48,7 +47,7 @@
ObjectSet* allocated_set)
: ObjectPointerVisitor(isolate_group), allocated_set_(allocated_set) {}
- virtual void VisitPointers(RawObject** first, RawObject** last);
+ virtual void VisitPointers(ObjectPtr* first, ObjectPtr* last);
static void VerifyPointers(MarkExpectation mark_expectation = kForbidMarked);
@@ -77,7 +76,7 @@
class VerifyCanonicalVisitor : public ObjectVisitor {
public:
explicit VerifyCanonicalVisitor(Thread* thread);
- virtual void VisitObject(RawObject* obj);
+ virtual void VisitObject(ObjectPtr obj);
private:
Thread* thread_;
diff --git a/runtime/vm/heap/weak_table.cc b/runtime/vm/heap/weak_table.cc
index 1bc9daf..159ed5a 100644
--- a/runtime/vm/heap/weak_table.cc
+++ b/runtime/vm/heap/weak_table.cc
@@ -29,18 +29,18 @@
return result;
}
-void WeakTable::SetValueExclusive(RawObject* key, intptr_t val) {
+void WeakTable::SetValueExclusive(ObjectPtr key, intptr_t val) {
intptr_t mask = size() - 1;
intptr_t idx = Hash(key) & mask;
intptr_t empty_idx = -1;
- RawObject* obj = ObjectAtExclusive(idx);
+ ObjectPtr obj = ObjectAtExclusive(idx);
- while (obj != NULL) {
+ while (obj != nullptr) {
if (obj == key) {
SetValueAt(idx, val);
return;
} else if ((empty_idx < 0) &&
- (reinterpret_cast<intptr_t>(obj) == kDeletedEntry)) {
+ (static_cast<intptr_t>(obj) == kDeletedEntry)) {
empty_idx = idx; // Insert at this location if not found.
}
idx = (idx + 1) & mask;
@@ -109,16 +109,16 @@
for (intptr_t i = 0; i < old_size; i++) {
if (IsValidEntryAtExclusive(i)) {
// Find the new hash location for this entry.
- RawObject* key = ObjectAtExclusive(i);
+ ObjectPtr key = ObjectAtExclusive(i);
intptr_t idx = Hash(key) & mask;
- RawObject* obj = reinterpret_cast<RawObject*>(new_data[ObjectIndex(idx)]);
- while (obj != NULL) {
+ ObjectPtr obj = static_cast<ObjectPtr>(new_data[ObjectIndex(idx)]);
+ while (obj != nullptr) {
ASSERT(obj != key); // Duplicate entry is not expected.
idx = (idx + 1) & mask;
- obj = reinterpret_cast<RawObject*>(new_data[ObjectIndex(idx)]);
+ obj = static_cast<ObjectPtr>(new_data[ObjectIndex(idx)]);
}
- new_data[ObjectIndex(idx)] = reinterpret_cast<intptr_t>(key);
+ new_data[ObjectIndex(idx)] = static_cast<intptr_t>(key);
new_data[ValueIndex(idx)] = ValueAtExclusive(i);
set_used(used() + 1);
}
diff --git a/runtime/vm/heap/weak_table.h b/runtime/vm/heap/weak_table.h
index 051051f..6fc01f3 100644
--- a/runtime/vm/heap/weak_table.h
+++ b/runtime/vm/heap/weak_table.h
@@ -49,12 +49,12 @@
// The following methods can be called concurrently and are guarded by a lock.
- intptr_t GetValue(RawObject* key) {
+ intptr_t GetValue(ObjectPtr key) {
MutexLocker ml(&mutex_);
return GetValueExclusive(key);
}
- void SetValue(RawObject* key, intptr_t val) {
+ void SetValue(ObjectPtr key, intptr_t val) {
MutexLocker ml(&mutex_);
return SetValueExclusive(key, val);
}
@@ -66,9 +66,9 @@
bool IsValidEntryAtExclusive(intptr_t i) const {
ASSERT((ValueAtExclusive(i) == 0 &&
- (ObjectAtExclusive(i) == NULL ||
+ (ObjectAtExclusive(i) == nullptr ||
data_[ObjectIndex(i)] == kDeletedEntry)) ||
- (ValueAtExclusive(i) != 0 && ObjectAtExclusive(i) != NULL &&
+ (ValueAtExclusive(i) != 0 && ObjectAtExclusive(i) != nullptr &&
data_[ObjectIndex(i)] != kDeletedEntry));
return (data_[ValueIndex(i)] != 0);
}
@@ -78,10 +78,10 @@
SetValueAt(i, 0);
}
- RawObject* ObjectAtExclusive(intptr_t i) const {
+ ObjectPtr ObjectAtExclusive(intptr_t i) const {
ASSERT(i >= 0);
ASSERT(i < size());
- return reinterpret_cast<RawObject*>(data_[ObjectIndex(i)]);
+ return static_cast<ObjectPtr>(data_[ObjectIndex(i)]);
}
intptr_t ValueAtExclusive(intptr_t i) const {
@@ -90,13 +90,13 @@
return data_[ValueIndex(i)];
}
- void SetValueExclusive(RawObject* key, intptr_t val);
+ void SetValueExclusive(ObjectPtr key, intptr_t val);
- intptr_t GetValueExclusive(RawObject* key) const {
+ intptr_t GetValueExclusive(ObjectPtr key) const {
intptr_t mask = size() - 1;
intptr_t idx = Hash(key) & mask;
- RawObject* obj = ObjectAtExclusive(idx);
- while (obj != NULL) {
+ ObjectPtr obj = ObjectAtExclusive(idx);
+ while (obj != nullptr) {
if (obj == key) {
return ValueAtExclusive(idx);
}
@@ -109,11 +109,11 @@
// Removes and returns the value associated with |key|. Returns 0 if there is
// no value associated with |key|.
- intptr_t RemoveValueExclusive(RawObject* key) {
+ intptr_t RemoveValueExclusive(ObjectPtr key) {
intptr_t mask = size() - 1;
intptr_t idx = Hash(key) & mask;
- RawObject* obj = ObjectAtExclusive(idx);
- while (obj != NULL) {
+ ObjectPtr obj = ObjectAtExclusive(idx);
+ while (obj != nullptr) {
if (obj == key) {
intptr_t result = ValueAtExclusive(idx);
InvalidateAtExclusive(idx);
@@ -166,16 +166,16 @@
intptr_t ValueIndex(intptr_t i) const { return index(i) + kValueOffset; }
- RawObject** ObjectPointerAt(intptr_t i) const {
+ ObjectPtr* ObjectPointerAt(intptr_t i) const {
ASSERT(i >= 0);
ASSERT(i < size());
- return reinterpret_cast<RawObject**>(&data_[ObjectIndex(i)]);
+ return reinterpret_cast<ObjectPtr*>(&data_[ObjectIndex(i)]);
}
- void SetObjectAt(intptr_t i, RawObject* key) {
+ void SetObjectAt(intptr_t i, ObjectPtr key) {
ASSERT(i >= 0);
ASSERT(i < size());
- data_[ObjectIndex(i)] = reinterpret_cast<intptr_t>(key);
+ data_[ObjectIndex(i)] = static_cast<intptr_t>(key);
}
void SetValueAt(intptr_t i, intptr_t val) {
@@ -191,8 +191,8 @@
void Rehash();
- static intptr_t Hash(RawObject* key) {
- return reinterpret_cast<uintptr_t>(key) * 92821;
+ static intptr_t Hash(ObjectPtr key) {
+ return static_cast<uintptr_t>(key) * 92821;
}
Mutex mutex_;
diff --git a/runtime/vm/image_snapshot.cc b/runtime/vm/image_snapshot.cc
index 01d5d36..ebdd6dd 100644
--- a/runtime/vm/image_snapshot.cc
+++ b/runtime/vm/image_snapshot.cc
@@ -4,6 +4,7 @@
#include "vm/image_snapshot.h"
+#include "include/dart_api.h"
#include "platform/assert.h"
#include "vm/class_id.h"
#include "vm/compiler/runtime_api.h"
@@ -40,11 +41,11 @@
#endif
intptr_t ObjectOffsetTrait::Hashcode(Key key) {
- RawObject* obj = key;
+ ObjectPtr obj = key;
ASSERT(!obj->IsSmi());
- uword body = RawObject::ToAddr(obj) + sizeof(RawObject);
- uword end = RawObject::ToAddr(obj) + obj->HeapSize();
+ uword body = ObjectLayout::ToAddr(obj) + sizeof(ObjectLayout);
+ uword end = ObjectLayout::ToAddr(obj) + obj->ptr()->HeapSize();
uint32_t hash = obj->GetClassId();
// Don't include the header. Objects in the image are pre-marked, but objects
@@ -57,8 +58,8 @@
}
bool ObjectOffsetTrait::IsKeyEqual(Pair pair, Key key) {
- RawObject* a = pair.object;
- RawObject* b = key;
+ ObjectPtr a = pair.object;
+ ObjectPtr b = key;
ASSERT(!a->IsSmi());
ASSERT(!b->IsSmi());
@@ -66,16 +67,16 @@
return false;
}
- intptr_t heap_size = a->HeapSize();
- if (b->HeapSize() != heap_size) {
+ intptr_t heap_size = a->ptr()->HeapSize();
+ if (b->ptr()->HeapSize() != heap_size) {
return false;
}
// Don't include the header. Objects in the image are pre-marked, but objects
// in the current isolate are not.
- uword body_a = RawObject::ToAddr(a) + sizeof(RawObject);
- uword body_b = RawObject::ToAddr(b) + sizeof(RawObject);
- uword body_size = heap_size - sizeof(RawObject);
+ uword body_a = ObjectLayout::ToAddr(a) + sizeof(ObjectLayout);
+ uword body_b = ObjectLayout::ToAddr(b) + sizeof(ObjectLayout);
+ uword body_size = heap_size - sizeof(ObjectLayout);
return 0 == memcmp(reinterpret_cast<const void*>(body_a),
reinterpret_cast<const void*>(body_b), body_size);
}
@@ -102,8 +103,8 @@
ASSERT((initial_offset + inst.expected_offset) == next_text_offset_);
switch (inst.op) {
case ImageWriterCommand::InsertInstructionOfCode: {
- RawCode* code = inst.insert_instruction_of_code.code;
- RawInstructions* instructions = Code::InstructionsOf(code);
+ CodePtr code = inst.insert_instruction_of_code.code;
+ InstructionsPtr instructions = Code::InstructionsOf(code);
const intptr_t offset = next_text_offset_;
instructions_.Add(InstructionsData(instructions, code, offset));
next_text_offset_ += SizeInSnapshot(instructions);
@@ -127,8 +128,8 @@
}
}
-int32_t ImageWriter::GetTextOffsetFor(RawInstructions* instructions,
- RawCode* code) {
+int32_t ImageWriter::GetTextOffsetFor(InstructionsPtr instructions,
+ CodePtr code) {
intptr_t offset = heap_->GetObjectId(instructions);
if (offset != 0) {
return offset;
@@ -143,7 +144,7 @@
return offset;
}
-static intptr_t InstructionsSizeInSnapshot(RawInstructions* raw) {
+static intptr_t InstructionsSizeInSnapshot(InstructionsPtr raw) {
if (FLAG_precompiled_mode && FLAG_use_bare_instructions) {
// Currently, we align bare instruction payloads on 4 byte boundaries.
//
@@ -158,7 +159,7 @@
compiler::target::Instructions::HeaderSize() + Instructions::Size(raw),
compiler::target::ObjectAlignment::kObjectAlignment);
#else
- return raw->HeapSize();
+ return raw->ptr()->HeapSize();
#endif
}
@@ -196,32 +197,32 @@
compiler::target::ObjectAlignment::kObjectAlignment);
}
-intptr_t ImageWriter::SizeInSnapshot(RawObject* raw_object) {
+intptr_t ImageWriter::SizeInSnapshot(ObjectPtr raw_object) {
const classid_t cid = raw_object->GetClassId();
switch (cid) {
case kCompressedStackMapsCid: {
- RawCompressedStackMaps* raw_maps =
- static_cast<RawCompressedStackMaps*>(raw_object);
+ CompressedStackMapsPtr raw_maps =
+ static_cast<CompressedStackMapsPtr>(raw_object);
auto const payload_size = CompressedStackMaps::PayloadSizeOf(raw_maps);
return CompressedStackMapsSizeInSnapshot(payload_size);
}
case kOneByteStringCid:
case kTwoByteStringCid: {
- RawString* raw_str = static_cast<RawString*>(raw_object);
+ StringPtr raw_str = static_cast<StringPtr>(raw_object);
return StringSizeInSnapshot(Smi::Value(raw_str->ptr()->length_),
cid == kOneByteStringCid);
}
case kCodeSourceMapCid: {
- RawCodeSourceMap* raw_map = static_cast<RawCodeSourceMap*>(raw_object);
+ CodeSourceMapPtr raw_map = static_cast<CodeSourceMapPtr>(raw_object);
return CodeSourceMapSizeInSnapshot(raw_map->ptr()->length_);
}
case kPcDescriptorsCid: {
- RawPcDescriptors* raw_desc = static_cast<RawPcDescriptors*>(raw_object);
+ PcDescriptorsPtr raw_desc = static_cast<PcDescriptorsPtr>(raw_object);
return PcDescriptorsSizeInSnapshot(raw_desc->ptr()->length_);
}
case kInstructionsCid: {
- RawInstructions* raw_insns = static_cast<RawInstructions*>(raw_object);
+ InstructionsPtr raw_insns = static_cast<InstructionsPtr>(raw_object);
return InstructionsSizeInSnapshot(raw_insns);
}
default: {
@@ -232,17 +233,17 @@
}
}
#else // defined(IS_SIMARM_X64)
-intptr_t ImageWriter::SizeInSnapshot(RawObject* raw) {
+intptr_t ImageWriter::SizeInSnapshot(ObjectPtr raw) {
switch (raw->GetClassId()) {
case kInstructionsCid:
- return InstructionsSizeInSnapshot(static_cast<RawInstructions*>(raw));
+ return InstructionsSizeInSnapshot(static_cast<InstructionsPtr>(raw));
default:
- return raw->HeapSize();
+ return raw->ptr()->HeapSize();
}
}
#endif // defined(IS_SIMARM_X64)
-uint32_t ImageWriter::GetDataOffsetFor(RawObject* raw_object) {
+uint32_t ImageWriter::GetDataOffsetFor(ObjectPtr raw_object) {
intptr_t snap_size = SizeInSnapshot(raw_object);
intptr_t offset = next_data_offset_;
next_data_offset_ += snap_size;
@@ -377,7 +378,7 @@
if (is_trampoline) continue;
data.insns_ = &Instructions::Handle(zone, data.raw_insns_);
- ASSERT(data.raw_code_ != NULL);
+ ASSERT(data.raw_code_ != nullptr);
data.code_ = &Code::Handle(zone, data.raw_code_);
// Reset object id as an isolate snapshot after a VM snapshot will not use
@@ -419,14 +420,15 @@
AutoTraceImage(obj, section_start, stream);
NoSafepointScope no_safepoint;
- uword start = reinterpret_cast<uword>(obj.raw()) - kHeapObjectTag;
+ uword start = static_cast<uword>(obj.raw()) - kHeapObjectTag;
// Write object header with the mark and read-only bits set.
uword marked_tags = obj.raw()->ptr()->tags_;
- marked_tags = RawObject::OldBit::update(true, marked_tags);
- marked_tags = RawObject::OldAndNotMarkedBit::update(false, marked_tags);
- marked_tags = RawObject::OldAndNotRememberedBit::update(true, marked_tags);
- marked_tags = RawObject::NewBit::update(false, marked_tags);
+ marked_tags = ObjectLayout::OldBit::update(true, marked_tags);
+ marked_tags = ObjectLayout::OldAndNotMarkedBit::update(false, marked_tags);
+ marked_tags =
+ ObjectLayout::OldAndNotRememberedBit::update(true, marked_tags);
+ marked_tags = ObjectLayout::NewBit::update(false, marked_tags);
#if defined(HASH_IN_OBJECT_HEADER)
marked_tags |= static_cast<uword>(obj.raw()->ptr()->hash_) << 32;
#endif
@@ -456,9 +458,8 @@
marked_tags = UpdateObjectSizeForTarget(size_in_bytes, marked_tags);
stream->WriteTargetWord(marked_tags);
- stream->WriteTargetWord(
- reinterpret_cast<uword>(str.raw()->ptr()->length_));
- stream->WriteTargetWord(reinterpret_cast<uword>(str.raw()->ptr()->hash_));
+ stream->WriteTargetWord(static_cast<uword>(str.raw()->ptr()->length_));
+ stream->WriteTargetWord(static_cast<uword>(str.raw()->ptr()->hash_));
stream->WriteBytes(
reinterpret_cast<const void*>(start + String::kSizeofRawString),
StringPayloadSize(str.Length(), str.IsOneByteString()));
@@ -487,7 +488,7 @@
FATAL1("Unsupported class %s in rodata section.\n", clazz.ToCString());
}
#else // defined(IS_SIMARM_X64)
- const uword end = start + obj.raw()->HeapSize();
+ const uword end = start + obj.raw()->ptr()->HeapSize();
stream->WriteWord(marked_tags);
start += sizeof(uword);
@@ -624,8 +625,8 @@
}
#endif
- const char* instructions_symbol =
- vm ? "_kDartVmSnapshotInstructions" : "_kDartIsolateSnapshotInstructions";
+ const char* instructions_symbol = vm ? kVmSnapshotInstructionsAsmSymbol
+ : kIsolateSnapshotInstructionsAsmSymbol;
assembly_stream_.Print(".text\n");
assembly_stream_.Print(".globl %s\n", instructions_symbol);
@@ -660,12 +661,12 @@
const intptr_t section_size = image_size - Image::kHeaderSize;
// Add the RawInstructionsSection header.
const compiler::target::uword marked_tags =
- RawObject::OldBit::encode(true) |
- RawObject::OldAndNotMarkedBit::encode(false) |
- RawObject::OldAndNotRememberedBit::encode(true) |
- RawObject::NewBit::encode(false) |
- RawObject::SizeTag::encode(AdjustObjectSizeForTarget(section_size)) |
- RawObject::ClassIdTag::encode(kInstructionsSectionCid);
+ ObjectLayout::OldBit::encode(true) |
+ ObjectLayout::OldAndNotMarkedBit::encode(false) |
+ ObjectLayout::OldAndNotRememberedBit::encode(true) |
+ ObjectLayout::NewBit::encode(false) |
+ ObjectLayout::SizeTag::encode(AdjustObjectSizeForTarget(section_size)) |
+ ObjectLayout::ClassIdTag::encode(kInstructionsSectionCid);
WriteWordLiteralText(marked_tags);
// Calculated using next_text_offset_, which doesn't include post-payload
// padding to object alignment.
@@ -757,11 +758,12 @@
// Write Instructions with the mark and read-only bits set.
uword marked_tags = insns.raw_ptr()->tags_;
- marked_tags = RawObject::OldBit::update(true, marked_tags);
- marked_tags = RawObject::OldAndNotMarkedBit::update(false, marked_tags);
+ marked_tags = ObjectLayout::OldBit::update(true, marked_tags);
marked_tags =
- RawObject::OldAndNotRememberedBit::update(true, marked_tags);
- marked_tags = RawObject::NewBit::update(false, marked_tags);
+ ObjectLayout::OldAndNotMarkedBit::update(false, marked_tags);
+ marked_tags =
+ ObjectLayout::OldAndNotRememberedBit::update(true, marked_tags);
+ marked_tags = ObjectLayout::NewBit::update(false, marked_tags);
#if defined(HASH_IN_OBJECT_HEADER)
// Can't use GetObjectTagsAndHash because the update methods discard the
// high bits.
@@ -813,7 +815,7 @@
#if defined(DART_PRECOMPILER)
PcDescriptors::Iterator iterator(descriptors,
- RawPcDescriptors::kBSSRelocation);
+ PcDescriptorsLayout::kBSSRelocation);
uword next_reloc_offset = iterator.MoveNext() ? iterator.PcOffset() : -1;
// We only generate BSS relocations that are word-sized and at
@@ -858,7 +860,7 @@
}
ASSERT(kWordSize != compiler::target::kWordSize ||
- (text_offset - instr_start) == insns.raw()->HeapSize());
+ (text_offset - instr_start) == insns.raw()->ptr()->HeapSize());
}
}
@@ -1067,8 +1069,8 @@
void BlobImageWriter::WriteText(WriteStream* clustered_stream, bool vm) {
const bool bare_instruction_payloads =
FLAG_precompiled_mode && FLAG_use_bare_instructions;
- const char* instructions_symbol =
- vm ? "_kDartVmSnapshotInstructions" : "_kDartIsolateSnapshotInstructions";
+ const char* instructions_symbol = vm ? kVmSnapshotInstructionsAsmSymbol
+ : kIsolateSnapshotInstructionsAsmSymbol;
auto const zone = Thread::Current()->zone();
#if defined(DART_PRECOMPILER)
@@ -1107,12 +1109,12 @@
const intptr_t section_size = image_size - Image::kHeaderSize;
// Add the RawInstructionsSection header.
const compiler::target::uword marked_tags =
- RawObject::OldBit::encode(true) |
- RawObject::OldAndNotMarkedBit::encode(false) |
- RawObject::OldAndNotRememberedBit::encode(true) |
- RawObject::NewBit::encode(false) |
- RawObject::SizeTag::encode(AdjustObjectSizeForTarget(section_size)) |
- RawObject::ClassIdTag::encode(kInstructionsSectionCid);
+ ObjectLayout::OldBit::encode(true) |
+ ObjectLayout::OldAndNotMarkedBit::encode(false) |
+ ObjectLayout::OldAndNotRememberedBit::encode(true) |
+ ObjectLayout::NewBit::encode(false) |
+ ObjectLayout::SizeTag::encode(AdjustObjectSizeForTarget(section_size)) |
+ ObjectLayout::ClassIdTag::encode(kInstructionsSectionCid);
instructions_blob_stream_.WriteTargetWord(marked_tags);
// Uses next_text_offset_ to avoid any post-payload padding.
const intptr_t instructions_length =
@@ -1183,10 +1185,11 @@
// Write Instructions with the mark and read-only bits set.
uword marked_tags = insns.raw_ptr()->tags_;
- marked_tags = RawObject::OldBit::update(true, marked_tags);
- marked_tags = RawObject::OldAndNotMarkedBit::update(false, marked_tags);
- marked_tags = RawObject::OldAndNotRememberedBit::update(true, marked_tags);
- marked_tags = RawObject::NewBit::update(false, marked_tags);
+ marked_tags = ObjectLayout::OldBit::update(true, marked_tags);
+ marked_tags = ObjectLayout::OldAndNotMarkedBit::update(false, marked_tags);
+ marked_tags =
+ ObjectLayout::OldAndNotRememberedBit::update(true, marked_tags);
+ marked_tags = ObjectLayout::NewBit::update(false, marked_tags);
#if defined(HASH_IN_OBJECT_HEADER)
// Can't use GetObjectTagsAndHash because the update methods discard the
// high bits.
@@ -1258,7 +1261,7 @@
descriptors = code.pc_descriptors();
PcDescriptors::Iterator iterator(
- descriptors, /*kind_mask=*/RawPcDescriptors::kBSSRelocation);
+ descriptors, /*kind_mask=*/PcDescriptorsLayout::kBSSRelocation);
while (iterator.MoveNext()) {
const intptr_t reloc_offset = iterator.PcOffset();
@@ -1322,7 +1325,7 @@
ASSERT(instructions_image != NULL);
}
-RawApiError* ImageReader::VerifyAlignment() const {
+ApiErrorPtr ImageReader::VerifyAlignment() const {
if (!Utils::IsAligned(data_image_, kObjectAlignment) ||
!Utils::IsAligned(instructions_image_, kMaxObjectAlignment)) {
return ApiError::New(
@@ -1344,23 +1347,23 @@
}
#endif
-RawInstructions* ImageReader::GetInstructionsAt(uint32_t offset) const {
+InstructionsPtr ImageReader::GetInstructionsAt(uint32_t offset) const {
ASSERT(Utils::IsAligned(offset, kObjectAlignment));
- RawObject* result = RawObject::FromAddr(
+ ObjectPtr result = ObjectLayout::FromAddr(
reinterpret_cast<uword>(instructions_image_) + offset);
ASSERT(result->IsInstructions());
- ASSERT(result->IsMarked());
+ ASSERT(result->ptr()->IsMarked());
return Instructions::RawCast(result);
}
-RawObject* ImageReader::GetObjectAt(uint32_t offset) const {
+ObjectPtr ImageReader::GetObjectAt(uint32_t offset) const {
ASSERT(Utils::IsAligned(offset, kObjectAlignment));
- RawObject* result =
- RawObject::FromAddr(reinterpret_cast<uword>(data_image_) + offset);
- ASSERT(result->IsMarked());
+ ObjectPtr result =
+ ObjectLayout::FromAddr(reinterpret_cast<uword>(data_image_) + offset);
+ ASSERT(result->ptr()->IsMarked());
return result;
}
diff --git a/runtime/vm/image_snapshot.h b/runtime/vm/image_snapshot.h
index 3d87113..94a57ca 100644
--- a/runtime/vm/image_snapshot.h
+++ b/runtime/vm/image_snapshot.h
@@ -28,10 +28,6 @@
class Elf;
class Instructions;
class Object;
-class RawApiError;
-class RawCode;
-class RawInstructions;
-class RawObject;
class Image : ValueObject {
public:
@@ -67,12 +63,12 @@
public:
ImageReader(const uint8_t* data_image, const uint8_t* instructions_image);
- RawApiError* VerifyAlignment() const;
+ ApiErrorPtr VerifyAlignment() const;
ONLY_IN_PRECOMPILED(uword GetBareInstructionsAt(uint32_t offset) const);
ONLY_IN_PRECOMPILED(uword GetBareInstructionsEnd() const);
- RawInstructions* GetInstructionsAt(uint32_t offset) const;
- RawObject* GetObjectAt(uint32_t offset) const;
+ InstructionsPtr GetInstructionsAt(uint32_t offset) const;
+ ObjectPtr GetObjectAt(uint32_t offset) const;
private:
const uint8_t* data_image_;
@@ -84,16 +80,16 @@
struct ObjectOffsetPair {
public:
ObjectOffsetPair() : ObjectOffsetPair(NULL, 0) {}
- ObjectOffsetPair(RawObject* obj, int32_t off) : object(obj), offset(off) {}
+ ObjectOffsetPair(ObjectPtr obj, int32_t off) : object(obj), offset(off) {}
- RawObject* object;
+ ObjectPtr object;
int32_t offset;
};
class ObjectOffsetTrait {
public:
// Typedefs needed for the DirectChainedHashMap template.
- typedef RawObject* Key;
+ typedef ObjectPtr Key;
typedef int32_t Value;
typedef ObjectOffsetPair Pair;
@@ -119,7 +115,7 @@
InsertBytesOfTrampoline,
};
- ImageWriterCommand(intptr_t expected_offset, RawCode* code)
+ ImageWriterCommand(intptr_t expected_offset, CodePtr code)
: expected_offset(expected_offset),
op(ImageWriterCommand::InsertInstructionOfCode),
insert_instruction_of_code({code}) {}
@@ -138,7 +134,7 @@
Opcode op;
union {
struct {
- RawCode* code;
+ CodePtr code;
} insert_instruction_of_code;
struct {
uint8_t* buffer;
@@ -172,8 +168,8 @@
offset_space_ == V8SnapshotProfileWriter::kIsolateData ||
offset_space_ == V8SnapshotProfileWriter::kIsolateText;
}
- int32_t GetTextOffsetFor(RawInstructions* instructions, RawCode* code);
- uint32_t GetDataOffsetFor(RawObject* raw_object);
+ int32_t GetTextOffsetFor(InstructionsPtr instructions, CodePtr code);
+ uint32_t GetDataOffsetFor(ObjectPtr raw_object);
void Write(WriteStream* clustered_stream, bool vm);
intptr_t data_size() const { return next_data_offset_; }
@@ -191,7 +187,7 @@
void TraceInstructions(const Instructions& instructions);
- static intptr_t SizeInSnapshot(RawObject* object);
+ static intptr_t SizeInSnapshot(ObjectPtr object);
static const intptr_t kBareInstructionsAlignment = 4;
static_assert(
@@ -200,9 +196,9 @@
"Target object alignment is larger than the host object alignment");
// Converts the target object size (in bytes) to an appropriate argument for
- // RawObject::SizeTag methods on the host machine.
+ // ObjectLayout::SizeTag methods on the host machine.
//
- // RawObject::SizeTag expects a size divisible by kObjectAlignment and
+ // ObjectLayout::SizeTag expects a size divisible by kObjectAlignment and
// checks this in debug mode, but the size on the target machine may not be
// divisible by the host machine's object alignment if they differ.
//
@@ -219,8 +215,8 @@
static UNLESS_DEBUG(constexpr) compiler::target::uword
UpdateObjectSizeForTarget(intptr_t size, uword marked_tags) {
- return RawObject::SizeTag::update(AdjustObjectSizeForTarget(size),
- marked_tags);
+ return ObjectLayout::SizeTag::update(AdjustObjectSizeForTarget(size),
+ marked_tags);
}
// Returns nullptr if there is no profile writer.
@@ -235,9 +231,7 @@
void DumpInstructionsSizes();
struct InstructionsData {
- InstructionsData(RawInstructions* insns,
- RawCode* code,
- intptr_t text_offset)
+ InstructionsData(InstructionsPtr insns, CodePtr code, intptr_t text_offset)
: raw_insns_(insns),
raw_code_(code),
text_offset_(text_offset),
@@ -254,11 +248,11 @@
trampoline_length(trampoline_length) {}
union {
- RawInstructions* raw_insns_;
+ InstructionsPtr raw_insns_;
const Instructions* insns_;
};
union {
- RawCode* raw_code_;
+ CodePtr raw_code_;
const Code* code_;
};
intptr_t text_offset_;
@@ -268,10 +262,10 @@
};
struct ObjectData {
- explicit ObjectData(RawObject* raw_obj) : raw_obj_(raw_obj) {}
+ explicit ObjectData(ObjectPtr raw_obj) : raw_obj_(raw_obj) {}
union {
- RawObject* raw_obj_;
+ ObjectPtr raw_obj_;
const Object* obj_;
};
};
diff --git a/runtime/vm/instructions_arm.cc b/runtime/vm/instructions_arm.cc
index 37f4113..465f888 100644
--- a/runtime/vm/instructions_arm.cc
+++ b/runtime/vm/instructions_arm.cc
@@ -64,9 +64,8 @@
ASSERT(reg == R9);
}
-RawCode* NativeCallPattern::target() const {
- return reinterpret_cast<RawCode*>(
- object_pool_.ObjectAt(target_code_pool_index_));
+CodePtr NativeCallPattern::target() const {
+ return static_cast<CodePtr>(object_pool_.ObjectAt(target_code_pool_index_));
}
void NativeCallPattern::set_target(const Code& new_target) const {
@@ -103,7 +102,7 @@
} else {
intptr_t value = 0;
start = DecodeLoadWordImmediate(end, reg, &value);
- *obj = reinterpret_cast<RawObject*>(value);
+ *obj = static_cast<ObjectPtr>(value);
}
return start;
}
@@ -259,16 +258,15 @@
return false;
}
-RawCode* CallPattern::TargetCode() const {
- return reinterpret_cast<RawCode*>(
- object_pool_.ObjectAt(target_code_pool_index_));
+CodePtr CallPattern::TargetCode() const {
+ return static_cast<CodePtr>(object_pool_.ObjectAt(target_code_pool_index_));
}
void CallPattern::SetTargetCode(const Code& target_code) const {
object_pool_.SetObjectAt(target_code_pool_index_, target_code);
}
-RawObject* ICCallPattern::Data() const {
+ObjectPtr ICCallPattern::Data() const {
return object_pool_.ObjectAt(data_pool_index_);
}
@@ -277,8 +275,8 @@
object_pool_.SetObjectAt(data_pool_index_, data);
}
-RawCode* ICCallPattern::TargetCode() const {
- return reinterpret_cast<RawCode*>(object_pool_.ObjectAt(target_pool_index_));
+CodePtr ICCallPattern::TargetCode() const {
+ return static_cast<CodePtr>(object_pool_.ObjectAt(target_pool_index_));
}
void ICCallPattern::SetTargetCode(const Code& target_code) const {
@@ -290,7 +288,7 @@
data_pool_index_(-1),
target_pool_index_(-1) {}
-RawObject* SwitchableCallPatternBase::data() const {
+ObjectPtr SwitchableCallPatternBase::data() const {
return object_pool_.ObjectAt(data_pool_index_);
}
@@ -314,8 +312,8 @@
ASSERT(reg == CODE_REG);
}
-RawCode* SwitchableCallPattern::target() const {
- return reinterpret_cast<RawCode*>(object_pool_.ObjectAt(target_pool_index_));
+CodePtr SwitchableCallPattern::target() const {
+ return static_cast<CodePtr>(object_pool_.ObjectAt(target_pool_index_));
}
void SwitchableCallPattern::SetTarget(const Code& target) const {
ASSERT(Object::Handle(object_pool_.ObjectAt(target_pool_index_)).IsCode());
@@ -338,13 +336,13 @@
ASSERT(reg == LR);
}
-RawCode* BareSwitchableCallPattern::target() const {
+CodePtr BareSwitchableCallPattern::target() const {
const uword pc = object_pool_.RawValueAt(target_pool_index_);
- auto rct = Isolate::Current()->reverse_pc_lookup_cache();
+ auto rct = IsolateGroup::Current()->reverse_pc_lookup_cache();
if (rct->Contains(pc)) {
return rct->Lookup(pc);
}
- rct = Dart::vm_isolate()->reverse_pc_lookup_cache();
+ rct = Dart::vm_isolate()->group()->reverse_pc_lookup_cache();
if (rct->Contains(pc)) {
return rct->Lookup(pc);
}
diff --git a/runtime/vm/instructions_arm.h b/runtime/vm/instructions_arm.h
index 6933278..1ddbc90 100644
--- a/runtime/vm/instructions_arm.h
+++ b/runtime/vm/instructions_arm.h
@@ -13,6 +13,7 @@
#include "vm/allocation.h"
#include "vm/constants.h"
#include "vm/native_function.h"
+#include "vm/tagged_pointer.h"
#if !defined(DART_PRECOMPILED_RUNTIME)
#include "vm/compiler/assembler/assembler.h"
@@ -24,9 +25,7 @@
class Code;
class Object;
class ObjectPool;
-class RawCode;
-class RawICData;
-class RawObject;
+class CodeLayout;
class InstructionPattern : public AllStatic {
public:
@@ -75,7 +74,7 @@
public:
CallPattern(uword pc, const Code& code);
- RawCode* TargetCode() const;
+ CodePtr TargetCode() const;
void SetTargetCode(const Code& code) const;
private:
@@ -90,10 +89,10 @@
public:
ICCallPattern(uword pc, const Code& code);
- RawObject* Data() const;
+ ObjectPtr Data() const;
void SetData(const Object& data) const;
- RawCode* TargetCode() const;
+ CodePtr TargetCode() const;
void SetTargetCode(const Code& code) const;
private:
@@ -109,7 +108,7 @@
public:
NativeCallPattern(uword pc, const Code& code);
- RawCode* target() const;
+ CodePtr target() const;
void set_target(const Code& target) const;
NativeFunction native_function() const;
@@ -134,7 +133,7 @@
public:
explicit SwitchableCallPatternBase(const Code& code);
- RawObject* data() const;
+ ObjectPtr data() const;
void SetData(const Object& data) const;
protected:
@@ -154,7 +153,7 @@
public:
SwitchableCallPattern(uword pc, const Code& code);
- RawCode* target() const;
+ CodePtr target() const;
void SetTarget(const Code& target) const;
private:
@@ -169,7 +168,7 @@
public:
BareSwitchableCallPattern(uword pc, const Code& code);
- RawCode* target() const;
+ CodePtr target() const;
void SetTarget(const Code& target) const;
private:
diff --git a/runtime/vm/instructions_arm64.cc b/runtime/vm/instructions_arm64.cc
index c83b9e2..037e777 100644
--- a/runtime/vm/instructions_arm64.cc
+++ b/runtime/vm/instructions_arm64.cc
@@ -65,9 +65,8 @@
ASSERT(reg == R5);
}
-RawCode* NativeCallPattern::target() const {
- return reinterpret_cast<RawCode*>(
- object_pool_.ObjectAt(target_code_pool_index_));
+CodePtr NativeCallPattern::target() const {
+ return static_cast<CodePtr>(object_pool_.ObjectAt(target_code_pool_index_));
}
void NativeCallPattern::set_target(const Code& target) const {
@@ -108,7 +107,7 @@
// Case 2.
intptr_t value = 0;
start = DecodeLoadWordImmediate(end, reg, &value);
- *obj = reinterpret_cast<RawObject*>(value);
+ *obj = static_cast<ObjectPtr>(value);
}
return start;
}
@@ -372,9 +371,8 @@
instr->SetInstructionBits(instr->InstructionBits() | B22);
}
-RawCode* CallPattern::TargetCode() const {
- return reinterpret_cast<RawCode*>(
- object_pool_.ObjectAt(target_code_pool_index_));
+CodePtr CallPattern::TargetCode() const {
+ return static_cast<CodePtr>(object_pool_.ObjectAt(target_code_pool_index_));
}
void CallPattern::SetTargetCode(const Code& target) const {
@@ -382,7 +380,7 @@
// No need to flush the instruction cache, since the code is not modified.
}
-RawObject* ICCallPattern::Data() const {
+ObjectPtr ICCallPattern::Data() const {
return object_pool_.ObjectAt(data_pool_index_);
}
@@ -391,8 +389,8 @@
object_pool_.SetObjectAt(data_pool_index_, data);
}
-RawCode* ICCallPattern::TargetCode() const {
- return reinterpret_cast<RawCode*>(object_pool_.ObjectAt(target_pool_index_));
+CodePtr ICCallPattern::TargetCode() const {
+ return static_cast<CodePtr>(object_pool_.ObjectAt(target_pool_index_));
}
void ICCallPattern::SetTargetCode(const Code& target) const {
@@ -405,7 +403,7 @@
data_pool_index_(-1),
target_pool_index_(-1) {}
-RawObject* SwitchableCallPatternBase::data() const {
+ObjectPtr SwitchableCallPatternBase::data() const {
return object_pool_.ObjectAt(data_pool_index_);
}
@@ -431,8 +429,8 @@
target_pool_index_ = pool_index + 1;
}
-RawCode* SwitchableCallPattern::target() const {
- return reinterpret_cast<RawCode*>(object_pool_.ObjectAt(target_pool_index_));
+CodePtr SwitchableCallPattern::target() const {
+ return static_cast<CodePtr>(object_pool_.ObjectAt(target_pool_index_));
}
void SwitchableCallPattern::SetTarget(const Code& target) const {
@@ -457,13 +455,13 @@
target_pool_index_ = pool_index + 1;
}
-RawCode* BareSwitchableCallPattern::target() const {
+CodePtr BareSwitchableCallPattern::target() const {
const uword pc = object_pool_.RawValueAt(target_pool_index_);
- auto rct = Isolate::Current()->reverse_pc_lookup_cache();
+ auto rct = IsolateGroup::Current()->reverse_pc_lookup_cache();
if (rct->Contains(pc)) {
return rct->Lookup(pc);
}
- rct = Dart::vm_isolate()->reverse_pc_lookup_cache();
+ rct = Dart::vm_isolate()->group()->reverse_pc_lookup_cache();
if (rct->Contains(pc)) {
return rct->Lookup(pc);
}
diff --git a/runtime/vm/instructions_arm64.h b/runtime/vm/instructions_arm64.h
index 2c1b62b..4a8f7e2 100644
--- a/runtime/vm/instructions_arm64.h
+++ b/runtime/vm/instructions_arm64.h
@@ -13,6 +13,7 @@
#include "vm/allocation.h"
#include "vm/constants.h"
#include "vm/native_function.h"
+#include "vm/tagged_pointer.h"
#if !defined(DART_PRECOMPILED_RUNTIME)
#include "vm/compiler/assembler/assembler.h"
@@ -24,9 +25,6 @@
class ICData;
class Object;
class ObjectPool;
-class RawCode;
-class RawICData;
-class RawObject;
class InstructionPattern : public AllStatic {
public:
@@ -86,7 +84,7 @@
public:
CallPattern(uword pc, const Code& code);
- RawCode* TargetCode() const;
+ CodePtr TargetCode() const;
void SetTargetCode(const Code& target) const;
private:
@@ -101,10 +99,10 @@
public:
ICCallPattern(uword pc, const Code& caller_code);
- RawObject* Data() const;
+ ObjectPtr Data() const;
void SetData(const Object& data) const;
- RawCode* TargetCode() const;
+ CodePtr TargetCode() const;
void SetTargetCode(const Code& target) const;
private:
@@ -120,7 +118,7 @@
public:
NativeCallPattern(uword pc, const Code& code);
- RawCode* target() const;
+ CodePtr target() const;
void set_target(const Code& target) const;
NativeFunction native_function() const;
@@ -145,7 +143,7 @@
public:
explicit SwitchableCallPatternBase(const Code& code);
- RawObject* data() const;
+ ObjectPtr data() const;
void SetData(const Object& data) const;
protected:
@@ -165,7 +163,7 @@
public:
SwitchableCallPattern(uword pc, const Code& code);
- RawCode* target() const;
+ CodePtr target() const;
void SetTarget(const Code& target) const;
private:
@@ -180,7 +178,7 @@
public:
BareSwitchableCallPattern(uword pc, const Code& code);
- RawCode* target() const;
+ CodePtr target() const;
void SetTarget(const Code& target) const;
private:
diff --git a/runtime/vm/instructions_kbc.cc b/runtime/vm/instructions_kbc.cc
index a8a3608..b427738 100644
--- a/runtime/vm/instructions_kbc.cc
+++ b/runtime/vm/instructions_kbc.cc
@@ -13,7 +13,7 @@
namespace dart {
-RawTypedData* KBCNativeCallPattern::GetNativeEntryDataAt(
+TypedDataPtr KBCNativeCallPattern::GetNativeEntryDataAt(
uword pc,
const Bytecode& bytecode) {
ASSERT(bytecode.ContainsInstructionAt(pc));
diff --git a/runtime/vm/instructions_kbc.h b/runtime/vm/instructions_kbc.h
index d210a28..5bfdb11 100644
--- a/runtime/vm/instructions_kbc.h
+++ b/runtime/vm/instructions_kbc.h
@@ -15,7 +15,7 @@
class KBCNativeCallPattern : public AllStatic {
public:
- static RawTypedData* GetNativeEntryDataAt(uword pc, const Bytecode& bytecode);
+ static TypedDataPtr GetNativeEntryDataAt(uword pc, const Bytecode& bytecode);
};
#endif // !defined(DART_PRECOMPILED_RUNTIME)
diff --git a/runtime/vm/interpreter.cc b/runtime/vm/interpreter.cc
index 21044dc..c5b27e3 100644
--- a/runtime/vm/interpreter.cc
+++ b/runtime/vm/interpreter.cc
@@ -76,7 +76,7 @@
jmp_buf buffer_;
private:
- RawObject** fp_;
+ ObjectPtr* fp_;
Interpreter* interpreter_;
InterpreterSetjmpBuffer* link_;
@@ -86,12 +86,13 @@
DISALLOW_COPY_AND_ASSIGN(InterpreterSetjmpBuffer);
};
-DART_FORCE_INLINE static RawObject** SavedCallerFP(RawObject** FP) {
- return reinterpret_cast<RawObject**>(FP[kKBCSavedCallerFpSlotFromFp]);
+DART_FORCE_INLINE static ObjectPtr* SavedCallerFP(ObjectPtr* FP) {
+ return reinterpret_cast<ObjectPtr*>(
+ static_cast<uword>(FP[kKBCSavedCallerFpSlotFromFp]));
}
-DART_FORCE_INLINE static RawObject** FrameArguments(RawObject** FP,
- intptr_t argc) {
+DART_FORCE_INLINE static ObjectPtr* FrameArguments(ObjectPtr* FP,
+ intptr_t argc) {
return FP - (kKBCDartFrameFixedSize + argc);
}
@@ -100,34 +101,34 @@
class InterpreterHelpers {
public:
#define DEFINE_CASTS(Type) \
- DART_FORCE_INLINE static Raw##Type* CastTo##Type(RawObject* obj) { \
+ DART_FORCE_INLINE static Type##Ptr CastTo##Type(ObjectPtr obj) { \
ASSERT((k##Type##Cid == kSmiCid) \
? !obj->IsHeapObject() \
: (k##Type##Cid == kIntegerCid) \
? (!obj->IsHeapObject() || obj->IsMint()) \
: obj->Is##Type()); \
- return reinterpret_cast<Raw##Type*>(obj); \
+ return static_cast<Type##Ptr>(obj); \
}
CLASS_LIST(DEFINE_CASTS)
#undef DEFINE_CASTS
- DART_FORCE_INLINE static RawSmi* GetClassIdAsSmi(RawObject* obj) {
+ DART_FORCE_INLINE static SmiPtr GetClassIdAsSmi(ObjectPtr obj) {
return Smi::New(obj->IsHeapObject() ? obj->GetClassId()
: static_cast<intptr_t>(kSmiCid));
}
- DART_FORCE_INLINE static intptr_t GetClassId(RawObject* obj) {
+ DART_FORCE_INLINE static intptr_t GetClassId(ObjectPtr obj) {
return obj->IsHeapObject() ? obj->GetClassId()
: static_cast<intptr_t>(kSmiCid);
}
- DART_FORCE_INLINE static RawTypeArguments* GetTypeArguments(
+ DART_FORCE_INLINE static TypeArgumentsPtr GetTypeArguments(
Thread* thread,
- RawInstance* instance) {
- RawClass* instance_class =
+ InstancePtr instance) {
+ ClassPtr instance_class =
thread->isolate()->class_table()->At(GetClassId(instance));
return instance_class->ptr()->num_type_arguments_ > 0
- ? reinterpret_cast<RawTypeArguments**>(instance->ptr())
+ ? reinterpret_cast<TypeArgumentsPtr*>(instance->ptr())
[instance_class->ptr()
->host_type_arguments_field_offset_in_words_]
: TypeArguments::null();
@@ -136,57 +137,56 @@
// The usage counter is actually a 'hotness' counter.
// For an instance call, both the usage counters of the caller and of the
// calle will get incremented, as well as the ICdata counter at the call site.
- DART_FORCE_INLINE static void IncrementUsageCounter(RawFunction* f) {
+ DART_FORCE_INLINE static void IncrementUsageCounter(FunctionPtr f) {
f->ptr()->usage_counter_++;
}
- DART_FORCE_INLINE static void IncrementICUsageCount(RawObject** entries,
+ DART_FORCE_INLINE static void IncrementICUsageCount(ObjectPtr* entries,
intptr_t offset,
intptr_t args_tested) {
const intptr_t count_offset = ICData::CountIndexFor(args_tested);
const intptr_t raw_smi_old =
- reinterpret_cast<intptr_t>(entries[offset + count_offset]);
+ static_cast<intptr_t>(entries[offset + count_offset]);
const intptr_t raw_smi_new = raw_smi_old + Smi::RawValue(1);
*reinterpret_cast<intptr_t*>(&entries[offset + count_offset]) = raw_smi_new;
}
- DART_FORCE_INLINE static bool CheckIndex(RawSmi* index, RawSmi* length) {
- return !index->IsHeapObject() && (reinterpret_cast<intptr_t>(index) >= 0) &&
- (reinterpret_cast<intptr_t>(index) <
- reinterpret_cast<intptr_t>(length));
+ DART_FORCE_INLINE static bool CheckIndex(SmiPtr index, SmiPtr length) {
+ return !index->IsHeapObject() && (static_cast<intptr_t>(index) >= 0) &&
+ (static_cast<intptr_t>(index) < static_cast<intptr_t>(length));
}
- DART_FORCE_INLINE static intptr_t ArgDescTypeArgsLen(RawArray* argdesc) {
- return Smi::Value(*reinterpret_cast<RawSmi**>(
+ DART_FORCE_INLINE static intptr_t ArgDescTypeArgsLen(ArrayPtr argdesc) {
+ return Smi::Value(*reinterpret_cast<SmiPtr*>(
reinterpret_cast<uword>(argdesc->ptr()) +
Array::element_offset(ArgumentsDescriptor::kTypeArgsLenIndex)));
}
- DART_FORCE_INLINE static intptr_t ArgDescArgCount(RawArray* argdesc) {
- return Smi::Value(*reinterpret_cast<RawSmi**>(
+ DART_FORCE_INLINE static intptr_t ArgDescArgCount(ArrayPtr argdesc) {
+ return Smi::Value(*reinterpret_cast<SmiPtr*>(
reinterpret_cast<uword>(argdesc->ptr()) +
Array::element_offset(ArgumentsDescriptor::kCountIndex)));
}
- DART_FORCE_INLINE static intptr_t ArgDescArgSize(RawArray* argdesc) {
- return Smi::Value(*reinterpret_cast<RawSmi**>(
+ DART_FORCE_INLINE static intptr_t ArgDescArgSize(ArrayPtr argdesc) {
+ return Smi::Value(*reinterpret_cast<SmiPtr*>(
reinterpret_cast<uword>(argdesc->ptr()) +
Array::element_offset(ArgumentsDescriptor::kSizeIndex)));
}
- DART_FORCE_INLINE static intptr_t ArgDescPosCount(RawArray* argdesc) {
- return Smi::Value(*reinterpret_cast<RawSmi**>(
+ DART_FORCE_INLINE static intptr_t ArgDescPosCount(ArrayPtr argdesc) {
+ return Smi::Value(*reinterpret_cast<SmiPtr*>(
reinterpret_cast<uword>(argdesc->ptr()) +
Array::element_offset(ArgumentsDescriptor::kPositionalCountIndex)));
}
- DART_FORCE_INLINE static RawBytecode* FrameBytecode(RawObject** FP) {
+ DART_FORCE_INLINE static BytecodePtr FrameBytecode(ObjectPtr* FP) {
ASSERT(GetClassId(FP[kKBCPcMarkerSlotFromFp]) == kBytecodeCid);
- return static_cast<RawBytecode*>(FP[kKBCPcMarkerSlotFromFp]);
+ return static_cast<BytecodePtr>(FP[kKBCPcMarkerSlotFromFp]);
}
- DART_FORCE_INLINE static bool FieldNeedsGuardUpdate(RawField* field,
- RawObject* value) {
+ DART_FORCE_INLINE static bool FieldNeedsGuardUpdate(FieldPtr field,
+ ObjectPtr value) {
// The interpreter should never see a cloned field.
ASSERT(field->ptr()->owner_->GetClassId() != kFieldCid);
@@ -232,42 +232,43 @@
return false;
}
- DART_FORCE_INLINE static bool IsFinalized(RawClass* cls) {
+ DART_FORCE_INLINE static bool IsFinalized(ClassPtr cls) {
return Class::ClassFinalizedBits::decode(cls->ptr()->state_bits_) ==
- RawClass::kFinalized;
+ ClassLayout::kFinalized;
}
};
-DART_FORCE_INLINE static const KBCInstr* SavedCallerPC(RawObject** FP) {
- return reinterpret_cast<const KBCInstr*>(FP[kKBCSavedCallerPcSlotFromFp]);
+DART_FORCE_INLINE static const KBCInstr* SavedCallerPC(ObjectPtr* FP) {
+ return reinterpret_cast<const KBCInstr*>(
+ static_cast<uword>(FP[kKBCSavedCallerPcSlotFromFp]));
}
-DART_FORCE_INLINE static RawFunction* FrameFunction(RawObject** FP) {
- RawFunction* function = static_cast<RawFunction*>(FP[kKBCFunctionSlotFromFp]);
+DART_FORCE_INLINE static FunctionPtr FrameFunction(ObjectPtr* FP) {
+ FunctionPtr function = static_cast<FunctionPtr>(FP[kKBCFunctionSlotFromFp]);
ASSERT(InterpreterHelpers::GetClassId(function) == kFunctionCid ||
InterpreterHelpers::GetClassId(function) == kNullCid);
return function;
}
-DART_FORCE_INLINE static RawObject* InitializeHeader(uword addr,
- intptr_t class_id,
- intptr_t instance_size) {
+DART_FORCE_INLINE static ObjectPtr InitializeHeader(uword addr,
+ intptr_t class_id,
+ intptr_t instance_size) {
uint32_t tags = 0;
- tags = RawObject::ClassIdTag::update(class_id, tags);
- tags = RawObject::SizeTag::update(instance_size, tags);
- tags = RawObject::OldBit::update(false, tags);
- tags = RawObject::OldAndNotMarkedBit::update(false, tags);
- tags = RawObject::OldAndNotRememberedBit::update(false, tags);
- tags = RawObject::NewBit::update(true, tags);
+ tags = ObjectLayout::ClassIdTag::update(class_id, tags);
+ tags = ObjectLayout::SizeTag::update(instance_size, tags);
+ tags = ObjectLayout::OldBit::update(false, tags);
+ tags = ObjectLayout::OldAndNotMarkedBit::update(false, tags);
+ tags = ObjectLayout::OldAndNotRememberedBit::update(false, tags);
+ tags = ObjectLayout::NewBit::update(true, tags);
// Also writes zero in the hash_ field.
*reinterpret_cast<uword*>(addr + Object::tags_offset()) = tags;
- return RawObject::FromAddr(addr);
+ return ObjectLayout::FromAddr(addr);
}
DART_FORCE_INLINE static bool TryAllocate(Thread* thread,
intptr_t class_id,
intptr_t instance_size,
- RawObject** result) {
+ ObjectPtr* result) {
ASSERT(instance_size > 0);
ASSERT(Utils::IsAligned(instance_size, kObjectAlignment));
@@ -295,14 +296,13 @@
}
bool LookupCache::Lookup(intptr_t receiver_cid,
- RawString* function_name,
- RawArray* arguments_descriptor,
- RawFunction** target) const {
+ StringPtr function_name,
+ ArrayPtr arguments_descriptor,
+ FunctionPtr* target) const {
ASSERT(receiver_cid != kIllegalCid); // Sentinel value.
- const intptr_t hash = receiver_cid ^
- reinterpret_cast<intptr_t>(function_name) ^
- reinterpret_cast<intptr_t>(arguments_descriptor);
+ const intptr_t hash = receiver_cid ^ static_cast<intptr_t>(function_name) ^
+ static_cast<intptr_t>(arguments_descriptor);
const intptr_t probe1 = hash & kTableMask;
if (entries_[probe1].receiver_cid == receiver_cid &&
entries_[probe1].function_name == function_name &&
@@ -323,17 +323,16 @@
}
void LookupCache::Insert(intptr_t receiver_cid,
- RawString* function_name,
- RawArray* arguments_descriptor,
- RawFunction* target) {
+ StringPtr function_name,
+ ArrayPtr arguments_descriptor,
+ FunctionPtr target) {
// Otherwise we have to clear the cache or rehash on scavenges too.
ASSERT(function_name->IsOldObject());
ASSERT(arguments_descriptor->IsOldObject());
ASSERT(target->IsOldObject());
- const intptr_t hash = receiver_cid ^
- reinterpret_cast<intptr_t>(function_name) ^
- reinterpret_cast<intptr_t>(arguments_descriptor);
+ const intptr_t hash = receiver_cid ^ static_cast<intptr_t>(function_name) ^
+ static_cast<intptr_t>(arguments_descriptor);
const intptr_t probe1 = hash & kTableMask;
if (entries_[probe1].receiver_cid == kIllegalCid) {
entries_[probe1].receiver_cid = receiver_cid;
@@ -359,7 +358,11 @@
}
Interpreter::Interpreter()
- : stack_(NULL), fp_(NULL), pp_(NULL), argdesc_(NULL), lookup_cache_() {
+ : stack_(NULL),
+ fp_(NULL),
+ pp_(nullptr),
+ argdesc_(nullptr),
+ lookup_cache_() {
// Setup interpreter support first. Some of this information is needed to
// setup the architecture state.
// We allocate the stack here, the size is computed as the sum of
@@ -503,15 +506,15 @@
typedef double (*InterpreterLeafFloatRuntimeCall)(double d0, double d1);
void Interpreter::Exit(Thread* thread,
- RawObject** base,
- RawObject** frame,
+ ObjectPtr* base,
+ ObjectPtr* frame,
const KBCInstr* pc) {
frame[0] = Function::null();
frame[1] = Bytecode::null();
- frame[2] = reinterpret_cast<RawObject*>(reinterpret_cast<uword>(pc));
- frame[3] = reinterpret_cast<RawObject*>(base);
+ frame[2] = static_cast<ObjectPtr>(reinterpret_cast<uword>(pc));
+ frame[3] = static_cast<ObjectPtr>(reinterpret_cast<uword>(base));
- RawObject** exit_fp = frame + kKBCDartFrameFixedSize;
+ ObjectPtr* exit_fp = frame + kKBCDartFrameFixedSize;
thread->set_top_exit_frame_info(reinterpret_cast<uword>(exit_fp));
fp_ = exit_fp;
@@ -527,8 +530,8 @@
void Interpreter::Unexit(Thread* thread) {
#if !defined(PRODUCT)
// For the profiler.
- RawObject** exit_fp =
- reinterpret_cast<RawObject**>(thread->top_exit_frame_info());
+ ObjectPtr* exit_fp =
+ reinterpret_cast<ObjectPtr*>(thread->top_exit_frame_info());
ASSERT(exit_fp != 0);
pc_ = SavedCallerPC(exit_fp);
fp_ = SavedCallerFP(exit_fp);
@@ -537,7 +540,7 @@
}
// Calling into runtime may trigger garbage collection and relocate objects,
-// so all RawObject* pointers become outdated and should not be used across
+// so all ObjectPtr pointers become outdated and should not be used across
// runtime calls.
// Note: functions below are marked DART_NOINLINE to recover performance where
// inlining these functions into the interpreter loop seemed to cause some code
@@ -576,15 +579,25 @@
}
}
+extern "C" {
+// Note: The invocation stub follows the C ABI, so we cannot pass C++ struct
+// values like ObjectPtr. In some calling conventions (IA32), ObjectPtr is
+// passed/returned different from a pointer.
+typedef uword /*ObjectPtr*/ (*invokestub)(uword /*CodePtr*/ code,
+ uword /*ArrayPtr*/ argdesc,
+ ObjectPtr* arg0,
+ Thread* thread);
+}
+
DART_NOINLINE bool Interpreter::InvokeCompiled(Thread* thread,
- RawFunction* function,
- RawObject** call_base,
- RawObject** call_top,
+ FunctionPtr function,
+ ObjectPtr* call_base,
+ ObjectPtr* call_top,
const KBCInstr** pc,
- RawObject*** FP,
- RawObject*** SP) {
+ ObjectPtr** FP,
+ ObjectPtr** SP) {
ASSERT(Function::HasCode(function));
- RawCode* volatile code = function->ptr()->code_;
+ CodePtr code = function->ptr()->code_;
ASSERT(code != StubCode::LazyCompile().raw());
// TODO(regis): Once we share the same stack, try to invoke directly.
#if defined(DEBUG)
@@ -594,11 +607,9 @@
}
#endif
// On success, returns a RawInstance. On failure, a RawError.
- typedef RawObject* (*invokestub)(RawCode * code, RawArray * argdesc,
- RawObject * *arg0, Thread * thread);
invokestub volatile entrypoint = reinterpret_cast<invokestub>(
StubCode::InvokeDartCodeFromBytecode().EntryPoint());
- RawObject* volatile result;
+ ObjectPtr result;
Exit(thread, *FP, call_top + 1, *pc);
{
InterpreterSetjmpBuffer buffer(this);
@@ -610,14 +621,15 @@
if (!thread->os_thread()->HasStackHeadroom()) {
thread->SetStackLimit(-1);
}
- result = bit_copy<RawObject*, int64_t>(
- Simulator::Current()->Call(reinterpret_cast<intptr_t>(entrypoint),
- reinterpret_cast<intptr_t>(code),
- reinterpret_cast<intptr_t>(argdesc_),
- reinterpret_cast<intptr_t>(call_base),
- reinterpret_cast<intptr_t>(thread)));
+ result = bit_copy<ObjectPtr, int64_t>(Simulator::Current()->Call(
+ reinterpret_cast<intptr_t>(entrypoint), static_cast<intptr_t>(code),
+ static_cast<intptr_t>(argdesc_),
+ reinterpret_cast<intptr_t>(call_base),
+ reinterpret_cast<intptr_t>(thread)));
#else
- result = entrypoint(code, argdesc_, call_base, thread);
+ result = static_cast<ObjectPtr>(entrypoint(static_cast<uword>(code),
+ static_cast<uword>(argdesc_),
+ call_base, thread));
#endif
ASSERT(thread->vm_tag() == VMTag::kDartInterpretedTagId);
ASSERT(thread->execution_state() == Thread::kThreadInGenerated);
@@ -665,12 +677,12 @@
}
DART_FORCE_INLINE bool Interpreter::InvokeBytecode(Thread* thread,
- RawFunction* function,
- RawObject** call_base,
- RawObject** call_top,
+ FunctionPtr function,
+ ObjectPtr* call_base,
+ ObjectPtr* call_top,
const KBCInstr** pc,
- RawObject*** FP,
- RawObject*** SP) {
+ ObjectPtr** FP,
+ ObjectPtr** SP) {
ASSERT(Function::HasBytecode(function));
#if defined(DEBUG)
if (IsTracingExecution()) {
@@ -679,13 +691,14 @@
Function::Handle(function).ToFullyQualifiedCString());
}
#endif
- RawObject** callee_fp = call_top + kKBCDartFrameFixedSize;
+ ObjectPtr* callee_fp = call_top + kKBCDartFrameFixedSize;
ASSERT(function == FrameFunction(callee_fp));
- RawBytecode* bytecode = function->ptr()->bytecode_;
+ BytecodePtr bytecode = function->ptr()->bytecode_;
callee_fp[kKBCPcMarkerSlotFromFp] = bytecode;
callee_fp[kKBCSavedCallerPcSlotFromFp] =
- reinterpret_cast<RawObject*>(reinterpret_cast<uword>(*pc));
- callee_fp[kKBCSavedCallerFpSlotFromFp] = reinterpret_cast<RawObject*>(*FP);
+ static_cast<ObjectPtr>(reinterpret_cast<uword>(*pc));
+ callee_fp[kKBCSavedCallerFpSlotFromFp] =
+ static_cast<ObjectPtr>(reinterpret_cast<uword>(*FP));
pp_ = bytecode->ptr()->object_pool_;
*pc = reinterpret_cast<const KBCInstr*>(bytecode->ptr()->instructions_);
NOT_IN_PRODUCT(pc_ = *pc); // For the profiler.
@@ -696,13 +709,13 @@
}
DART_FORCE_INLINE bool Interpreter::Invoke(Thread* thread,
- RawObject** call_base,
- RawObject** call_top,
+ ObjectPtr* call_base,
+ ObjectPtr* call_top,
const KBCInstr** pc,
- RawObject*** FP,
- RawObject*** SP) {
- RawObject** callee_fp = call_top + kKBCDartFrameFixedSize;
- RawFunction* function = FrameFunction(callee_fp);
+ ObjectPtr** FP,
+ ObjectPtr** SP) {
+ ObjectPtr* callee_fp = call_top + kKBCDartFrameFixedSize;
+ FunctionPtr function = FrameFunction(callee_fp);
for (;;) {
if (Function::HasCode(function)) {
@@ -728,12 +741,12 @@
}
DART_FORCE_INLINE bool Interpreter::InstanceCall(Thread* thread,
- RawString* target_name,
- RawObject** call_base,
- RawObject** top,
+ StringPtr target_name,
+ ObjectPtr* call_base,
+ ObjectPtr* top,
const KBCInstr** pc,
- RawObject*** FP,
- RawObject*** SP) {
+ ObjectPtr** FP,
+ ObjectPtr** SP) {
const intptr_t type_args_len =
InterpreterHelpers::ArgDescTypeArgsLen(argdesc_);
const intptr_t receiver_idx = type_args_len > 0 ? 1 : 0;
@@ -741,7 +754,7 @@
intptr_t receiver_cid =
InterpreterHelpers::GetClassId(call_base[receiver_idx]);
- RawFunction* target;
+ FunctionPtr target;
if (UNLIKELY(!lookup_cache_.Lookup(receiver_cid, target_name, argdesc_,
&target))) {
// Table lookup miss.
@@ -759,9 +772,9 @@
return false;
}
- target = static_cast<RawFunction*>(top[4]);
- target_name = static_cast<RawString*>(top[2]);
- argdesc_ = static_cast<RawArray*>(top[3]);
+ target = static_cast<FunctionPtr>(top[4]);
+ target_name = static_cast<StringPtr>(top[2]);
+ argdesc_ = static_cast<ArrayPtr>(top[3]);
ASSERT(target->IsFunction());
lookup_cache_.Insert(receiver_cid, target_name, argdesc_, target);
}
@@ -971,7 +984,7 @@
#define UNBOX_INT64(value, obj, selector) \
int64_t value; \
{ \
- word raw_value = reinterpret_cast<word>(obj); \
+ word raw_value = static_cast<word>(obj); \
if (LIKELY((raw_value & kSmiTagMask) == kSmiTag)) { \
value = raw_value >> kSmiTagShift; \
} else { \
@@ -1047,8 +1060,8 @@
bool Interpreter::CopyParameters(Thread* thread,
const KBCInstr** pc,
- RawObject*** FP,
- RawObject*** SP,
+ ObjectPtr** FP,
+ ObjectPtr** SP,
const intptr_t num_fixed_params,
const intptr_t num_opt_pos_params,
const intptr_t num_opt_named_params) {
@@ -1066,7 +1079,7 @@
}
// Copy all passed position arguments.
- RawObject** first_arg = FrameArguments(*FP, arg_count);
+ ObjectPtr* first_arg = FrameArguments(*FP, arg_count);
memmove(*FP, first_arg, pos_count * kWordSize);
if (num_opt_named_params != 0) {
@@ -1075,7 +1088,7 @@
// default values encoded as pairs of LoadConstant instructions that
// follows the entry point and find matching values via arguments
// descriptor.
- RawObject** argdesc_data = argdesc_->ptr()->data();
+ ObjectPtr* argdesc_data = argdesc_->ptr()->data();
intptr_t i = 0; // argument position
intptr_t j = 0; // parameter position
@@ -1089,11 +1102,11 @@
const uint8_t reg = KernelBytecode::DecodeA(load_name);
ASSERT(reg == KernelBytecode::DecodeA(load_value));
- RawString* name = static_cast<RawString*>(
+ StringPtr name = static_cast<StringPtr>(
LOAD_CONSTANT(KernelBytecode::DecodeE(load_name)));
if (name == argdesc_data[ArgumentsDescriptor::name_index(i)]) {
// Parameter was passed. Fetch passed value.
- const intptr_t arg_index = Smi::Value(static_cast<RawSmi*>(
+ const intptr_t arg_index = Smi::Value(static_cast<SmiPtr>(
argdesc_data[ArgumentsDescriptor::position_index(i)]));
(*FP)[reg] = first_arg[arg_index];
++i; // Consume passed argument.
@@ -1161,28 +1174,28 @@
bool Interpreter::AssertAssignable(Thread* thread,
const KBCInstr* pc,
- RawObject** FP,
- RawObject** call_top,
- RawObject** args,
- RawSubtypeTestCache* cache) {
- RawObject* null_value = Object::null();
+ ObjectPtr* FP,
+ ObjectPtr* call_top,
+ ObjectPtr* args,
+ SubtypeTestCachePtr cache) {
+ ObjectPtr null_value = Object::null();
if (cache != null_value) {
- RawInstance* instance = static_cast<RawInstance*>(args[0]);
- RawTypeArguments* instantiator_type_arguments =
- static_cast<RawTypeArguments*>(args[2]);
- RawTypeArguments* function_type_arguments =
- static_cast<RawTypeArguments*>(args[3]);
+ InstancePtr instance = static_cast<InstancePtr>(args[0]);
+ TypeArgumentsPtr instantiator_type_arguments =
+ static_cast<TypeArgumentsPtr>(args[2]);
+ TypeArgumentsPtr function_type_arguments =
+ static_cast<TypeArgumentsPtr>(args[3]);
const intptr_t cid = InterpreterHelpers::GetClassId(instance);
- RawTypeArguments* instance_type_arguments =
- static_cast<RawTypeArguments*>(null_value);
- RawObject* instance_cid_or_function;
+ TypeArgumentsPtr instance_type_arguments =
+ static_cast<TypeArgumentsPtr>(null_value);
+ ObjectPtr instance_cid_or_function;
- RawTypeArguments* parent_function_type_arguments;
- RawTypeArguments* delayed_function_type_arguments;
+ TypeArgumentsPtr parent_function_type_arguments;
+ TypeArgumentsPtr delayed_function_type_arguments;
if (cid == kClosureCid) {
- RawClosure* closure = static_cast<RawClosure*>(instance);
+ ClosurePtr closure = static_cast<ClosurePtr>(instance);
instance_type_arguments = closure->ptr()->instantiator_type_arguments_;
parent_function_type_arguments = closure->ptr()->function_type_arguments_;
delayed_function_type_arguments = closure->ptr()->delayed_type_arguments_;
@@ -1190,21 +1203,21 @@
} else {
instance_cid_or_function = Smi::New(cid);
- RawClass* instance_class = thread->isolate()->class_table()->At(cid);
+ ClassPtr instance_class = thread->isolate()->class_table()->At(cid);
if (instance_class->ptr()->num_type_arguments_ < 0) {
goto AssertAssignableCallRuntime;
} else if (instance_class->ptr()->num_type_arguments_ > 0) {
- instance_type_arguments = reinterpret_cast<RawTypeArguments**>(
+ instance_type_arguments = reinterpret_cast<TypeArgumentsPtr*>(
instance->ptr())[instance_class->ptr()
->host_type_arguments_field_offset_in_words_];
}
parent_function_type_arguments =
- static_cast<RawTypeArguments*>(null_value);
+ static_cast<TypeArgumentsPtr>(null_value);
delayed_function_type_arguments =
- static_cast<RawTypeArguments*>(null_value);
+ static_cast<TypeArgumentsPtr>(null_value);
}
- for (RawObject** entries = cache->ptr()->cache_->ptr()->data();
+ for (ObjectPtr* entries = cache->ptr()->cache_->ptr()->data();
entries[0] != null_value;
entries += SubtypeTestCache::kTestEntryLength) {
if ((entries[SubtypeTestCache::kInstanceClassIdOrFunction] ==
@@ -1245,29 +1258,29 @@
template <bool is_getter>
bool Interpreter::AssertAssignableField(Thread* thread,
const KBCInstr* pc,
- RawObject** FP,
- RawObject** SP,
- RawInstance* instance,
- RawField* field,
- RawInstance* value) {
- RawAbstractType* field_type = field->ptr()->type_;
+ ObjectPtr* FP,
+ ObjectPtr* SP,
+ InstancePtr instance,
+ FieldPtr field,
+ InstancePtr value) {
+ AbstractTypePtr field_type = field->ptr()->type_;
// Perform type test of value if field type is not one of dynamic, object,
// or void, and if the value is not null.
if (field_type->GetClassId() == kTypeCid) {
- classid_t cid = Smi::Value(reinterpret_cast<RawSmi*>(
- Type::RawCast(field_type)->ptr()->type_class_id_));
+ classid_t cid = Smi::Value(
+ static_cast<SmiPtr>(Type::RawCast(field_type)->ptr()->type_class_id_));
// TODO(regis): Revisit shortcut for NNBD.
if (cid == kDynamicCid || cid == kInstanceCid || cid == kVoidCid) {
return true;
}
}
- RawObject* null_value = Object::null();
+ ObjectPtr null_value = Object::null();
if (value == null_value) {
// TODO(regis): Revisit null shortcut for NNBD.
return true;
}
- RawSubtypeTestCache* cache = field->ptr()->type_test_cache_;
+ SubtypeTestCachePtr cache = field->ptr()->type_test_cache_;
if (UNLIKELY(cache == null_value)) {
// Allocate new cache.
SP[1] = instance; // Preserve.
@@ -1283,10 +1296,10 @@
}
// Reload objects after the call which may trigger GC.
- instance = reinterpret_cast<RawInstance*>(SP[1]);
- field = reinterpret_cast<RawField*>(SP[2]);
- value = reinterpret_cast<RawInstance*>(SP[3]);
- cache = reinterpret_cast<RawSubtypeTestCache*>(SP[4]);
+ instance = static_cast<InstancePtr>(SP[1]);
+ field = static_cast<FieldPtr>(SP[2]);
+ value = static_cast<InstancePtr>(SP[3]);
+ cache = static_cast<SubtypeTestCachePtr>(SP[4]);
field_type = field->ptr()->type_;
field->ptr()->type_test_cache_ = cache;
}
@@ -1302,10 +1315,10 @@
/* args */ SP + 1, cache);
}
-RawObject* Interpreter::Call(const Function& function,
- const Array& arguments_descriptor,
- const Array& arguments,
- Thread* thread) {
+ObjectPtr Interpreter::Call(const Function& function,
+ const Array& arguments_descriptor,
+ const Array& arguments,
+ Thread* thread) {
return Call(function.raw(), arguments_descriptor.raw(), arguments.Length(),
arguments.raw_ptr()->data(), thread);
}
@@ -1315,12 +1328,12 @@
DART_NOINLINE bool Interpreter::AllocateMint(Thread* thread,
int64_t value,
const KBCInstr* pc,
- RawObject** FP,
- RawObject** SP) {
+ ObjectPtr* FP,
+ ObjectPtr* SP) {
ASSERT(!Smi::IsValid(value));
- RawMint* result;
+ MintPtr result;
if (TryAllocate(thread, kMintCid, Mint::InstanceSize(),
- reinterpret_cast<RawObject**>(&result))) {
+ reinterpret_cast<ObjectPtr*>(&result))) {
result->ptr()->value_ = value;
SP[0] = result;
return true;
@@ -1333,7 +1346,7 @@
if (!InvokeRuntime(thread, this, DRT_AllocateObject, args)) {
return false;
}
- reinterpret_cast<RawMint*>(SP[0])->ptr()->value_ = value;
+ static_cast<MintPtr>(SP[0])->ptr()->value_ = value;
return true;
}
}
@@ -1343,11 +1356,11 @@
DART_NOINLINE bool Interpreter::AllocateDouble(Thread* thread,
double value,
const KBCInstr* pc,
- RawObject** FP,
- RawObject** SP) {
- RawDouble* result;
+ ObjectPtr* FP,
+ ObjectPtr* SP) {
+ DoublePtr result;
if (TryAllocate(thread, kDoubleCid, Double::InstanceSize(),
- reinterpret_cast<RawObject**>(&result))) {
+ reinterpret_cast<ObjectPtr*>(&result))) {
result->ptr()->value_ = value;
SP[0] = result;
return true;
@@ -1370,11 +1383,11 @@
DART_NOINLINE bool Interpreter::AllocateFloat32x4(Thread* thread,
simd128_value_t value,
const KBCInstr* pc,
- RawObject** FP,
- RawObject** SP) {
- RawFloat32x4* result;
+ ObjectPtr* FP,
+ ObjectPtr* SP) {
+ Float32x4Ptr result;
if (TryAllocate(thread, kFloat32x4Cid, Float32x4::InstanceSize(),
- reinterpret_cast<RawObject**>(&result))) {
+ reinterpret_cast<ObjectPtr*>(&result))) {
value.writeTo(result->ptr()->value_);
SP[0] = result;
return true;
@@ -1397,11 +1410,11 @@
DART_NOINLINE bool Interpreter::AllocateFloat64x2(Thread* thread,
simd128_value_t value,
const KBCInstr* pc,
- RawObject** FP,
- RawObject** SP) {
- RawFloat64x2* result;
+ ObjectPtr* FP,
+ ObjectPtr* SP) {
+ Float64x2Ptr result;
if (TryAllocate(thread, kFloat64x2Cid, Float64x2::InstanceSize(),
- reinterpret_cast<RawObject**>(&result))) {
+ reinterpret_cast<ObjectPtr*>(&result))) {
value.writeTo(result->ptr()->value_);
SP[0] = result;
return true;
@@ -1422,17 +1435,17 @@
// Allocate a _List with the given type arguments and length and put it into
// SP[0]. Returns false on exception.
bool Interpreter::AllocateArray(Thread* thread,
- RawTypeArguments* type_args,
- RawObject* length_object,
+ TypeArgumentsPtr type_args,
+ ObjectPtr length_object,
const KBCInstr* pc,
- RawObject** FP,
- RawObject** SP) {
+ ObjectPtr* FP,
+ ObjectPtr* SP) {
if (LIKELY(!length_object->IsHeapObject())) {
const intptr_t length = Smi::Value(Smi::RawCast(length_object));
if (LIKELY(Array::IsValidLength(length))) {
- RawArray* result;
+ ArrayPtr result;
if (TryAllocate(thread, kArrayCid, Array::InstanceSize(length),
- reinterpret_cast<RawObject**>(&result))) {
+ reinterpret_cast<ObjectPtr*>(&result))) {
result->ptr()->type_arguments_ = type_args;
result->ptr()->length_ = Smi::New(length);
for (intptr_t i = 0; i < length; i++) {
@@ -1457,15 +1470,15 @@
bool Interpreter::AllocateContext(Thread* thread,
intptr_t num_context_variables,
const KBCInstr* pc,
- RawObject** FP,
- RawObject** SP) {
- RawContext* result;
+ ObjectPtr* FP,
+ ObjectPtr* SP) {
+ ContextPtr result;
if (TryAllocate(thread, kContextCid,
Context::InstanceSize(num_context_variables),
- reinterpret_cast<RawObject**>(&result))) {
+ reinterpret_cast<ObjectPtr*>(&result))) {
result->ptr()->num_variables_ = num_context_variables;
- RawObject* null_value = Object::null();
- result->ptr()->parent_ = static_cast<RawContext*>(null_value);
+ ObjectPtr null_value = Object::null();
+ result->ptr()->parent_ = static_cast<ContextPtr>(null_value);
for (intptr_t i = 0; i < num_context_variables; i++) {
result->ptr()->data()[i] = null_value;
}
@@ -1484,17 +1497,17 @@
// Returns false on exception.
bool Interpreter::AllocateClosure(Thread* thread,
const KBCInstr* pc,
- RawObject** FP,
- RawObject** SP) {
+ ObjectPtr* FP,
+ ObjectPtr* SP) {
const intptr_t instance_size = Closure::InstanceSize();
- RawClosure* result;
+ ClosurePtr result;
if (TryAllocate(thread, kClosureCid, instance_size,
- reinterpret_cast<RawObject**>(&result))) {
- uword start = RawObject::ToAddr(result);
- RawObject* null_value = Object::null();
- for (intptr_t offset = sizeof(RawInstance); offset < instance_size;
+ reinterpret_cast<ObjectPtr*>(&result))) {
+ uword start = ObjectLayout::ToAddr(result);
+ ObjectPtr null_value = Object::null();
+ for (intptr_t offset = sizeof(InstanceLayout); offset < instance_size;
offset += kWordSize) {
- *reinterpret_cast<RawObject**>(start + offset) = null_value;
+ *reinterpret_cast<ObjectPtr*>(start + offset) = null_value;
}
SP[0] = result;
return true;
@@ -1508,21 +1521,21 @@
}
}
-RawObject* Interpreter::Call(RawFunction* function,
- RawArray* argdesc,
- intptr_t argc,
- RawObject* const* argv,
- Thread* thread) {
+ObjectPtr Interpreter::Call(FunctionPtr function,
+ ArrayPtr argdesc,
+ intptr_t argc,
+ ObjectPtr const* argv,
+ Thread* thread) {
// Interpreter state (see constants_kbc.h for high-level overview).
const KBCInstr* pc; // Program Counter: points to the next op to execute.
- RawObject** FP; // Frame Pointer.
- RawObject** SP; // Stack Pointer.
+ ObjectPtr* FP; // Frame Pointer.
+ ObjectPtr* SP; // Stack Pointer.
uint32_t op; // Currently executing op.
bool reentering = fp_ != NULL;
if (!reentering) {
- fp_ = reinterpret_cast<RawObject**>(stack_base_);
+ fp_ = reinterpret_cast<ObjectPtr*>(stack_base_);
}
#if defined(DEBUG)
if (IsTracingExecution()) {
@@ -1565,22 +1578,22 @@
// Save outer top_exit_frame_info, current argdesc, and current pp.
fp_[kKBCExitLinkSlotFromEntryFp] =
- reinterpret_cast<RawObject*>(thread->top_exit_frame_info());
+ static_cast<ObjectPtr>(thread->top_exit_frame_info());
thread->set_top_exit_frame_info(0);
- fp_[kKBCSavedArgDescSlotFromEntryFp] = reinterpret_cast<RawObject*>(argdesc_);
- fp_[kKBCSavedPpSlotFromEntryFp] = reinterpret_cast<RawObject*>(pp_);
+ fp_[kKBCSavedArgDescSlotFromEntryFp] = static_cast<ObjectPtr>(argdesc_);
+ fp_[kKBCSavedPpSlotFromEntryFp] = static_cast<ObjectPtr>(pp_);
// Copy arguments and setup the Dart frame.
for (intptr_t i = 0; i < arg_count; i++) {
fp_[kKBCEntrySavedSlots + i] = argv[argc < 0 ? -i : i];
}
- RawBytecode* bytecode = function->ptr()->bytecode_;
+ BytecodePtr bytecode = function->ptr()->bytecode_;
FP[kKBCFunctionSlotFromFp] = function;
FP[kKBCPcMarkerSlotFromFp] = bytecode;
- FP[kKBCSavedCallerPcSlotFromFp] =
- reinterpret_cast<RawObject*>(kEntryFramePcMarker);
- FP[kKBCSavedCallerFpSlotFromFp] = reinterpret_cast<RawObject*>(fp_);
+ FP[kKBCSavedCallerPcSlotFromFp] = static_cast<ObjectPtr>(kEntryFramePcMarker);
+ FP[kKBCSavedCallerFpSlotFromFp] =
+ static_cast<ObjectPtr>(reinterpret_cast<uword>(fp_));
// Load argument descriptor.
argdesc_ = argdesc;
@@ -1603,9 +1616,9 @@
thread->set_top_resource(NULL);
// Cache some frequently used values in the frame.
- RawBool* true_value = Bool::True().raw();
- RawBool* false_value = Bool::False().raw();
- RawObject* null_value = Object::null();
+ BoolPtr true_value = Bool::True().raw();
+ BoolPtr false_value = Bool::False().raw();
+ ObjectPtr null_value = Object::null();
#ifdef DART_HAS_COMPUTED_GOTO
static const void* dispatch[] = {
@@ -1701,7 +1714,7 @@
NativeArguments(thread, 0, nullptr, nullptr));
}
}
- RawFunction* function = FrameFunction(FP);
+ FunctionPtr function = FrameFunction(FP);
int32_t counter = ++(function->ptr()->usage_counter_);
if (UNLIKELY(FLAG_compilation_counter_threshold >= 0 &&
counter >= FLAG_compilation_counter_threshold &&
@@ -1746,7 +1759,7 @@
{
BYTECODE(InstantiateType, D);
// Stack: instantiator type args, function type args
- RawObject* type = LOAD_CONSTANT(rD);
+ ObjectPtr type = LOAD_CONSTANT(rD);
SP[1] = type;
SP[2] = SP[-1];
SP[3] = SP[0];
@@ -1762,21 +1775,21 @@
{
BYTECODE(InstantiateTypeArgumentsTOS, A_E);
// Stack: instantiator type args, function type args
- RawTypeArguments* type_arguments =
- static_cast<RawTypeArguments*>(LOAD_CONSTANT(rE));
+ TypeArgumentsPtr type_arguments =
+ static_cast<TypeArgumentsPtr>(LOAD_CONSTANT(rE));
- RawObject* instantiator_type_args = SP[-1];
- RawObject* function_type_args = SP[0];
+ ObjectPtr instantiator_type_args = SP[-1];
+ ObjectPtr function_type_args = SP[0];
// If both instantiators are null and if the type argument vector
// instantiated from null becomes a vector of dynamic, then use null as
// the type arguments.
if ((rA == 0) || (null_value != instantiator_type_args) ||
(null_value != function_type_args)) {
// First lookup in the cache.
- RawArray* instantiations = type_arguments->ptr()->instantiations_;
+ ArrayPtr instantiations = type_arguments->ptr()->instantiations_;
for (intptr_t i = 0;
instantiations->ptr()->data()[i] !=
- reinterpret_cast<RawObject*>(TypeArguments::kNoInstantiator);
+ static_cast<ObjectPtr>(TypeArguments::kNoInstantiator);
i += TypeArguments::Instantiation::kSizeInWords) {
if ((instantiations->ptr()->data()
[i +
@@ -1905,9 +1918,9 @@
InterpreterHelpers::IncrementUsageCounter(FrameFunction(FP));
*++SP = LOAD_CONSTANT(kidx);
- RawObject** call_base = SP - argc;
- RawObject** call_top = SP;
- argdesc_ = static_cast<RawArray*>(LOAD_CONSTANT(kidx + 1));
+ ObjectPtr* call_base = SP - argc;
+ ObjectPtr* call_top = SP;
+ argdesc_ = static_cast<ArrayPtr>(LOAD_CONSTANT(kidx + 1));
if (!Invoke(thread, call_base, call_top, &pc, &FP, &SP)) {
HANDLE_EXCEPTION;
}
@@ -1926,9 +1939,9 @@
InterpreterHelpers::IncrementUsageCounter(FrameFunction(FP));
*++SP = LOAD_CONSTANT(kidx);
- RawObject** call_base = SP - argc;
- RawObject** call_top = SP;
- argdesc_ = static_cast<RawArray*>(LOAD_CONSTANT(kidx + 1));
+ ObjectPtr* call_base = SP - argc;
+ ObjectPtr* call_top = SP;
+ argdesc_ = static_cast<ArrayPtr>(LOAD_CONSTANT(kidx + 1));
if (!Invoke(thread, call_base, call_top, &pc, &FP, &SP)) {
HANDLE_EXCEPTION;
}
@@ -1944,13 +1957,13 @@
const uint32_t argc = rF;
const uint32_t kidx = rD;
- RawObject** call_base = SP - argc + 1;
- RawObject** call_top = SP + 1;
+ ObjectPtr* call_base = SP - argc + 1;
+ ObjectPtr* call_top = SP + 1;
InterpreterHelpers::IncrementUsageCounter(FrameFunction(FP));
- RawString* target_name =
- static_cast<RawFunction*>(LOAD_CONSTANT(kidx))->ptr()->name_;
- argdesc_ = static_cast<RawArray*>(LOAD_CONSTANT(kidx + 1));
+ StringPtr target_name =
+ static_cast<FunctionPtr>(LOAD_CONSTANT(kidx))->ptr()->name_;
+ argdesc_ = static_cast<ArrayPtr>(LOAD_CONSTANT(kidx + 1));
if (!InstanceCall(thread, target_name, call_base, call_top, &pc, &FP,
&SP)) {
HANDLE_EXCEPTION;
@@ -1966,13 +1979,13 @@
const uint32_t argc = rF;
const uint32_t kidx = rD;
- RawObject** call_base = SP - argc + 1;
- RawObject** call_top = SP + 1;
+ ObjectPtr* call_base = SP - argc + 1;
+ ObjectPtr* call_top = SP + 1;
InterpreterHelpers::IncrementUsageCounter(FrameFunction(FP));
- RawString* target_name =
- static_cast<RawFunction*>(LOAD_CONSTANT(kidx))->ptr()->name_;
- argdesc_ = static_cast<RawArray*>(LOAD_CONSTANT(kidx + 1));
+ StringPtr target_name =
+ static_cast<FunctionPtr>(LOAD_CONSTANT(kidx))->ptr()->name_;
+ argdesc_ = static_cast<ArrayPtr>(LOAD_CONSTANT(kidx + 1));
if (!InstanceCall(thread, target_name, call_base, call_top, &pc, &FP,
&SP)) {
HANDLE_EXCEPTION;
@@ -1989,16 +2002,16 @@
const uint32_t argc = rF;
const uint32_t kidx = rD;
- RawClosure* receiver = Closure::RawCast(*SP--);
- RawObject** call_base = SP - argc + 1;
- RawObject** call_top = SP + 1;
+ ClosurePtr receiver = Closure::RawCast(*SP--);
+ ObjectPtr* call_base = SP - argc + 1;
+ ObjectPtr* call_top = SP + 1;
InterpreterHelpers::IncrementUsageCounter(FrameFunction(FP));
if (UNLIKELY(receiver == null_value)) {
SP[0] = Symbols::Call().raw();
goto ThrowNullError;
}
- argdesc_ = static_cast<RawArray*>(LOAD_CONSTANT(kidx));
+ argdesc_ = static_cast<ArrayPtr>(LOAD_CONSTANT(kidx));
call_top[0] = receiver->ptr()->function_;
if (!Invoke(thread, call_base, call_top, &pc, &FP, &SP)) {
@@ -2016,13 +2029,13 @@
const uint32_t argc = rF;
const uint32_t kidx = rD;
- RawObject** call_base = SP - argc + 1;
- RawObject** call_top = SP + 1;
+ ObjectPtr* call_base = SP - argc + 1;
+ ObjectPtr* call_top = SP + 1;
InterpreterHelpers::IncrementUsageCounter(FrameFunction(FP));
- RawString* target_name =
- static_cast<RawFunction*>(LOAD_CONSTANT(kidx))->ptr()->name_;
- argdesc_ = static_cast<RawArray*>(LOAD_CONSTANT(kidx + 1));
+ StringPtr target_name =
+ static_cast<FunctionPtr>(LOAD_CONSTANT(kidx))->ptr()->name_;
+ argdesc_ = static_cast<ArrayPtr>(LOAD_CONSTANT(kidx + 1));
if (!InstanceCall(thread, target_name, call_base, call_top, &pc, &FP,
&SP)) {
HANDLE_EXCEPTION;
@@ -2039,11 +2052,11 @@
const uint32_t argc = rF;
const uint32_t kidx = rD;
- RawObject** call_base = SP - argc + 1;
- RawObject** call_top = SP + 1;
+ ObjectPtr* call_base = SP - argc + 1;
+ ObjectPtr* call_top = SP + 1;
InterpreterHelpers::IncrementUsageCounter(FrameFunction(FP));
- RawString* target_name = String::RawCast(LOAD_CONSTANT(kidx));
+ StringPtr target_name = String::RawCast(LOAD_CONSTANT(kidx));
argdesc_ = Array::RawCast(LOAD_CONSTANT(kidx + 1));
if (!InstanceCall(thread, target_name, call_base, call_top, &pc, &FP,
&SP)) {
@@ -2056,7 +2069,7 @@
{
BYTECODE(NativeCall, D);
- RawTypedData* data = static_cast<RawTypedData*>(LOAD_CONSTANT(rD));
+ TypedDataPtr data = static_cast<TypedDataPtr>(LOAD_CONSTANT(rD));
MethodRecognizer::Kind kind = NativeEntryData::GetKind(data);
switch (kind) {
case MethodRecognizer::kObjectEquals: {
@@ -2065,8 +2078,8 @@
} break;
case MethodRecognizer::kStringBaseLength:
case MethodRecognizer::kStringBaseIsEmpty: {
- RawInstance* instance = reinterpret_cast<RawInstance*>(SP[0]);
- SP[0] = reinterpret_cast<RawObject**>(
+ InstancePtr instance = static_cast<InstancePtr>(SP[0]);
+ SP[0] = reinterpret_cast<ObjectPtr*>(
instance->ptr())[String::length_offset() / kWordSize];
if (kind == MethodRecognizer::kStringBaseIsEmpty) {
SP[0] =
@@ -2074,29 +2087,29 @@
}
} break;
case MethodRecognizer::kGrowableArrayLength: {
- RawGrowableObjectArray* instance =
- reinterpret_cast<RawGrowableObjectArray*>(SP[0]);
+ GrowableObjectArrayPtr instance =
+ static_cast<GrowableObjectArrayPtr>(SP[0]);
SP[0] = instance->ptr()->length_;
} break;
case MethodRecognizer::kObjectArrayLength:
case MethodRecognizer::kImmutableArrayLength: {
- RawArray* instance = reinterpret_cast<RawArray*>(SP[0]);
+ ArrayPtr instance = static_cast<ArrayPtr>(SP[0]);
SP[0] = instance->ptr()->length_;
} break;
case MethodRecognizer::kTypedListLength:
case MethodRecognizer::kTypedListViewLength:
case MethodRecognizer::kByteDataViewLength: {
- RawTypedDataBase* instance = reinterpret_cast<RawTypedDataBase*>(SP[0]);
+ TypedDataBasePtr instance = static_cast<TypedDataBasePtr>(SP[0]);
SP[0] = instance->ptr()->length_;
} break;
case MethodRecognizer::kByteDataViewOffsetInBytes:
case MethodRecognizer::kTypedDataViewOffsetInBytes: {
- RawTypedDataView* instance = reinterpret_cast<RawTypedDataView*>(SP[0]);
+ TypedDataViewPtr instance = static_cast<TypedDataViewPtr>(SP[0]);
SP[0] = instance->ptr()->offset_in_bytes_;
} break;
case MethodRecognizer::kByteDataViewTypedData:
case MethodRecognizer::kTypedDataViewTypedData: {
- RawTypedDataView* instance = reinterpret_cast<RawTypedDataView*>(SP[0]);
+ TypedDataViewPtr instance = static_cast<TypedDataViewPtr>(SP[0]);
SP[0] = instance->ptr()->typed_data_;
} break;
case MethodRecognizer::kClassIDgetID: {
@@ -2106,8 +2119,8 @@
SP[0] = Object::null();
} break;
case MethodRecognizer::kGrowableArrayCapacity: {
- RawGrowableObjectArray* instance =
- reinterpret_cast<RawGrowableObjectArray*>(SP[0]);
+ GrowableObjectArrayPtr instance =
+ static_cast<GrowableObjectArrayPtr>(SP[0]);
SP[0] = instance->ptr()->data_->ptr()->length_;
} break;
case MethodRecognizer::kListFactory: {
@@ -2116,8 +2129,8 @@
// : new _GrowableList<E>(0);
// }
if (InterpreterHelpers::ArgDescPosCount(argdesc_) == 2) {
- RawTypeArguments* type_args = TypeArguments::RawCast(SP[-1]);
- RawObject* length = SP[0];
+ TypeArgumentsPtr type_args = TypeArguments::RawCast(SP[-1]);
+ ObjectPtr length = SP[0];
SP--;
if (!AllocateArray(thread, type_args, length, pc, FP, SP)) {
HANDLE_EXCEPTION;
@@ -2142,72 +2155,74 @@
}
} break;
case MethodRecognizer::kObjectArrayAllocate: {
- RawTypeArguments* type_args = TypeArguments::RawCast(SP[-1]);
- RawObject* length = SP[0];
+ TypeArgumentsPtr type_args = TypeArguments::RawCast(SP[-1]);
+ ObjectPtr length = SP[0];
SP--;
if (!AllocateArray(thread, type_args, length, pc, FP, SP)) {
HANDLE_EXCEPTION;
}
} break;
case MethodRecognizer::kLinkedHashMap_getIndex: {
- RawInstance* instance = reinterpret_cast<RawInstance*>(SP[0]);
- SP[0] = reinterpret_cast<RawObject**>(
+ InstancePtr instance = static_cast<InstancePtr>(SP[0]);
+ SP[0] = reinterpret_cast<ObjectPtr*>(
instance->ptr())[LinkedHashMap::index_offset() / kWordSize];
} break;
case MethodRecognizer::kLinkedHashMap_setIndex: {
- RawInstance* instance = reinterpret_cast<RawInstance*>(SP[-1]);
- instance->StorePointer(reinterpret_cast<RawObject**>(instance->ptr()) +
- LinkedHashMap::index_offset() / kWordSize,
- SP[0]);
+ InstancePtr instance = static_cast<InstancePtr>(SP[-1]);
+ instance->ptr()->StorePointer(
+ reinterpret_cast<ObjectPtr*>(instance->ptr()) +
+ LinkedHashMap::index_offset() / kWordSize,
+ SP[0]);
*--SP = null_value;
} break;
case MethodRecognizer::kLinkedHashMap_getData: {
- RawInstance* instance = reinterpret_cast<RawInstance*>(SP[0]);
- SP[0] = reinterpret_cast<RawObject**>(
+ InstancePtr instance = static_cast<InstancePtr>(SP[0]);
+ SP[0] = reinterpret_cast<ObjectPtr*>(
instance->ptr())[LinkedHashMap::data_offset() / kWordSize];
} break;
case MethodRecognizer::kLinkedHashMap_setData: {
- RawInstance* instance = reinterpret_cast<RawInstance*>(SP[-1]);
- instance->StorePointer(reinterpret_cast<RawObject**>(instance->ptr()) +
- LinkedHashMap::data_offset() / kWordSize,
- SP[0]);
+ InstancePtr instance = static_cast<InstancePtr>(SP[-1]);
+ instance->ptr()->StorePointer(
+ reinterpret_cast<ObjectPtr*>(instance->ptr()) +
+ LinkedHashMap::data_offset() / kWordSize,
+ SP[0]);
*--SP = null_value;
} break;
case MethodRecognizer::kLinkedHashMap_getHashMask: {
- RawInstance* instance = reinterpret_cast<RawInstance*>(SP[0]);
- SP[0] = reinterpret_cast<RawObject**>(
+ InstancePtr instance = static_cast<InstancePtr>(SP[0]);
+ SP[0] = reinterpret_cast<ObjectPtr*>(
instance->ptr())[LinkedHashMap::hash_mask_offset() / kWordSize];
} break;
case MethodRecognizer::kLinkedHashMap_setHashMask: {
- RawInstance* instance = reinterpret_cast<RawInstance*>(SP[-1]);
+ InstancePtr instance = static_cast<InstancePtr>(SP[-1]);
ASSERT(!SP[0]->IsHeapObject());
- reinterpret_cast<RawObject**>(
+ reinterpret_cast<ObjectPtr*>(
instance->ptr())[LinkedHashMap::hash_mask_offset() / kWordSize] =
SP[0];
*--SP = null_value;
} break;
case MethodRecognizer::kLinkedHashMap_getUsedData: {
- RawInstance* instance = reinterpret_cast<RawInstance*>(SP[0]);
- SP[0] = reinterpret_cast<RawObject**>(
+ InstancePtr instance = static_cast<InstancePtr>(SP[0]);
+ SP[0] = reinterpret_cast<ObjectPtr*>(
instance->ptr())[LinkedHashMap::used_data_offset() / kWordSize];
} break;
case MethodRecognizer::kLinkedHashMap_setUsedData: {
- RawInstance* instance = reinterpret_cast<RawInstance*>(SP[-1]);
+ InstancePtr instance = static_cast<InstancePtr>(SP[-1]);
ASSERT(!SP[0]->IsHeapObject());
- reinterpret_cast<RawObject**>(
+ reinterpret_cast<ObjectPtr*>(
instance->ptr())[LinkedHashMap::used_data_offset() / kWordSize] =
SP[0];
*--SP = null_value;
} break;
case MethodRecognizer::kLinkedHashMap_getDeletedKeys: {
- RawInstance* instance = reinterpret_cast<RawInstance*>(SP[0]);
- SP[0] = reinterpret_cast<RawObject**>(
+ InstancePtr instance = static_cast<InstancePtr>(SP[0]);
+ SP[0] = reinterpret_cast<ObjectPtr*>(
instance->ptr())[LinkedHashMap::deleted_keys_offset() / kWordSize];
} break;
case MethodRecognizer::kLinkedHashMap_setDeletedKeys: {
- RawInstance* instance = reinterpret_cast<RawInstance*>(SP[-1]);
+ InstancePtr instance = static_cast<InstancePtr>(SP[-1]);
ASSERT(!SP[0]->IsHeapObject());
- reinterpret_cast<RawObject**>(
+ reinterpret_cast<ObjectPtr*>(
instance->ptr())[LinkedHashMap::deleted_keys_offset() / kWordSize] =
SP[0];
*--SP = null_value;
@@ -2231,8 +2246,8 @@
*++SP = null_value; // Result slot.
- RawObject** incoming_args = SP - num_arguments;
- RawObject** return_slot = SP;
+ ObjectPtr* incoming_args = SP - num_arguments;
+ ObjectPtr* return_slot = SP;
Exit(thread, FP, SP + 1, pc);
NativeArguments native_args(thread, argc_tag, incoming_args,
return_slot);
@@ -2249,10 +2264,9 @@
}
{
- RawObject* result; // result to return to the caller.
-
BYTECODE(ReturnTOS, 0);
DEBUG_CHECK;
+ ObjectPtr result; // result to return to the caller.
result = *SP;
// Restore caller PC.
pc = SavedCallerPC(FP);
@@ -2260,14 +2274,12 @@
// Check if it is a fake PC marking the entry frame.
if (IsEntryFrameMarker(pc)) {
// Pop entry frame.
- RawObject** entry_fp = SavedCallerFP(FP);
+ ObjectPtr* entry_fp = SavedCallerFP(FP);
// Restore exit frame info saved in entry frame.
- pp_ = reinterpret_cast<RawObjectPool*>(
- entry_fp[kKBCSavedPpSlotFromEntryFp]);
- argdesc_ = reinterpret_cast<RawArray*>(
- entry_fp[kKBCSavedArgDescSlotFromEntryFp]);
- uword exit_fp =
- reinterpret_cast<uword>(entry_fp[kKBCExitLinkSlotFromEntryFp]);
+ pp_ = static_cast<ObjectPoolPtr>(entry_fp[kKBCSavedPpSlotFromEntryFp]);
+ argdesc_ =
+ static_cast<ArrayPtr>(entry_fp[kKBCSavedArgDescSlotFromEntryFp]);
+ uword exit_fp = static_cast<uword>(entry_fp[kKBCExitLinkSlotFromEntryFp]);
thread->set_top_exit_frame_info(exit_fp);
thread->set_top_resource(top_resource);
thread->set_vm_tag(vm_tag);
@@ -2312,12 +2324,12 @@
{
BYTECODE(InitLateField, D);
- RawField* field = RAW_CAST(Field, LOAD_CONSTANT(rD + 1));
- RawInstance* instance = reinterpret_cast<RawInstance*>(SP[0]);
+ FieldPtr field = RAW_CAST(Field, LOAD_CONSTANT(rD + 1));
+ InstancePtr instance = static_cast<InstancePtr>(SP[0]);
intptr_t offset_in_words = field->ptr()->host_offset_or_field_id_;
- instance->StorePointer(
- reinterpret_cast<RawObject**>(instance->ptr()) + offset_in_words,
+ instance->ptr()->StorePointer(
+ reinterpret_cast<ObjectPtr*>(instance->ptr()) + offset_in_words,
Object::RawCast(Object::sentinel().raw()), thread);
SP -= 1; // Drop instance.
@@ -2341,8 +2353,8 @@
{
BYTECODE(StoreStaticTOS, D);
- RawField* field = reinterpret_cast<RawField*>(LOAD_CONSTANT(rD));
- RawInstance* value = static_cast<RawInstance*>(*SP--);
+ FieldPtr field = static_cast<FieldPtr>(LOAD_CONSTANT(rD));
+ InstancePtr value = static_cast<InstancePtr>(*SP--);
intptr_t field_id = field->ptr()->host_offset_or_field_id_;
thread->field_table_values()[field_id] = value;
DISPATCH();
@@ -2350,9 +2362,9 @@
{
BYTECODE(LoadStatic, D);
- RawField* field = reinterpret_cast<RawField*>(LOAD_CONSTANT(rD));
+ FieldPtr field = static_cast<FieldPtr>(LOAD_CONSTANT(rD));
intptr_t field_id = field->ptr()->host_offset_or_field_id_;
- RawInstance* value = thread->field_table_values()[field_id];
+ InstancePtr value = thread->field_table_values()[field_id];
ASSERT((value != Object::sentinel().raw()) &&
(value != Object::transition_sentinel().raw()));
*++SP = value;
@@ -2361,9 +2373,9 @@
{
BYTECODE(StoreFieldTOS, D);
- RawField* field = RAW_CAST(Field, LOAD_CONSTANT(rD + 1));
- RawInstance* instance = reinterpret_cast<RawInstance*>(SP[-1]);
- RawObject* value = reinterpret_cast<RawObject*>(SP[0]);
+ FieldPtr field = RAW_CAST(Field, LOAD_CONSTANT(rD + 1));
+ InstancePtr instance = static_cast<InstancePtr>(SP[-1]);
+ ObjectPtr value = static_cast<ObjectPtr>(SP[0]);
intptr_t offset_in_words = field->ptr()->host_offset_or_field_id_;
if (InterpreterHelpers::FieldNeedsGuardUpdate(field, value)) {
@@ -2379,7 +2391,7 @@
// Reload objects after the call which may trigger GC.
field = RAW_CAST(Field, LOAD_CONSTANT(rD + 1));
- instance = reinterpret_cast<RawInstance*>(SP[-1]);
+ instance = static_cast<InstancePtr>(SP[-1]);
value = SP[0];
}
@@ -2389,47 +2401,47 @@
classid_t guarded_cid = field->ptr()->guarded_cid_;
if (unboxing && (guarded_cid == kDoubleCid) && supports_unboxed_doubles_) {
double raw_value = Double::RawCast(value)->ptr()->value_;
- ASSERT(*(reinterpret_cast<RawDouble**>(instance->ptr()) +
+ ASSERT(*(reinterpret_cast<DoublePtr*>(instance->ptr()) +
offset_in_words) == null_value); // Initializing store.
if (!AllocateDouble(thread, raw_value, pc, FP, SP)) {
HANDLE_EXCEPTION;
}
- RawDouble* box = Double::RawCast(SP[0]);
- instance = reinterpret_cast<RawInstance*>(SP[-1]);
- instance->StorePointer(
- reinterpret_cast<RawDouble**>(instance->ptr()) + offset_in_words, box,
+ DoublePtr box = Double::RawCast(SP[0]);
+ instance = static_cast<InstancePtr>(SP[-1]);
+ instance->ptr()->StorePointer(
+ reinterpret_cast<DoublePtr*>(instance->ptr()) + offset_in_words, box,
thread);
} else if (unboxing && (guarded_cid == kFloat32x4Cid) &&
supports_unboxed_simd128_) {
simd128_value_t raw_value;
raw_value.readFrom(Float32x4::RawCast(value)->ptr()->value_);
- ASSERT(*(reinterpret_cast<RawFloat32x4**>(instance->ptr()) +
+ ASSERT(*(reinterpret_cast<Float32x4Ptr*>(instance->ptr()) +
offset_in_words) == null_value); // Initializing store.
if (!AllocateFloat32x4(thread, raw_value, pc, FP, SP)) {
HANDLE_EXCEPTION;
}
- RawFloat32x4* box = Float32x4::RawCast(SP[0]);
- instance = reinterpret_cast<RawInstance*>(SP[-1]);
- instance->StorePointer(
- reinterpret_cast<RawFloat32x4**>(instance->ptr()) + offset_in_words,
+ Float32x4Ptr box = Float32x4::RawCast(SP[0]);
+ instance = static_cast<InstancePtr>(SP[-1]);
+ instance->ptr()->StorePointer(
+ reinterpret_cast<Float32x4Ptr*>(instance->ptr()) + offset_in_words,
box, thread);
} else if (unboxing && (guarded_cid == kFloat64x2Cid) &&
supports_unboxed_simd128_) {
simd128_value_t raw_value;
raw_value.readFrom(Float64x2::RawCast(value)->ptr()->value_);
- ASSERT(*(reinterpret_cast<RawFloat64x2**>(instance->ptr()) +
+ ASSERT(*(reinterpret_cast<Float64x2Ptr*>(instance->ptr()) +
offset_in_words) == null_value); // Initializing store.
if (!AllocateFloat64x2(thread, raw_value, pc, FP, SP)) {
HANDLE_EXCEPTION;
}
- RawFloat64x2* box = Float64x2::RawCast(SP[0]);
- instance = reinterpret_cast<RawInstance*>(SP[-1]);
- instance->StorePointer(
- reinterpret_cast<RawFloat64x2**>(instance->ptr()) + offset_in_words,
+ Float64x2Ptr box = Float64x2::RawCast(SP[0]);
+ instance = static_cast<InstancePtr>(SP[-1]);
+ instance->ptr()->StorePointer(
+ reinterpret_cast<Float64x2Ptr*>(instance->ptr()) + offset_in_words,
box, thread);
} else {
- instance->StorePointer(
- reinterpret_cast<RawObject**>(instance->ptr()) + offset_in_words,
+ instance->ptr()->StorePointer(
+ reinterpret_cast<ObjectPtr*>(instance->ptr()) + offset_in_words,
value, thread);
}
@@ -2441,13 +2453,13 @@
BYTECODE(StoreContextParent, 0);
const uword offset_in_words =
static_cast<uword>(Context::parent_offset() / kWordSize);
- RawContext* instance = reinterpret_cast<RawContext*>(SP[-1]);
- RawContext* value = reinterpret_cast<RawContext*>(SP[0]);
+ ContextPtr instance = static_cast<ContextPtr>(SP[-1]);
+ ContextPtr value = static_cast<ContextPtr>(SP[0]);
SP -= 2; // Drop instance and value.
- instance->StorePointer(
- reinterpret_cast<RawContext**>(instance->ptr()) + offset_in_words,
- value, thread);
+ instance->ptr()->StorePointer(
+ reinterpret_cast<ContextPtr*>(instance->ptr()) + offset_in_words, value,
+ thread);
DISPATCH();
}
@@ -2456,12 +2468,12 @@
BYTECODE(StoreContextVar, A_E);
const uword offset_in_words =
static_cast<uword>(Context::variable_offset(rE) / kWordSize);
- RawContext* instance = reinterpret_cast<RawContext*>(SP[-1]);
- RawObject* value = reinterpret_cast<RawContext*>(SP[0]);
+ ContextPtr instance = static_cast<ContextPtr>(SP[-1]);
+ ObjectPtr value = static_cast<ContextPtr>(SP[0]);
SP -= 2; // Drop instance and value.
ASSERT(rE < static_cast<uint32_t>(instance->ptr()->num_variables_));
- instance->StorePointer(
- reinterpret_cast<RawObject**>(instance->ptr()) + offset_in_words, value,
+ instance->ptr()->StorePointer(
+ reinterpret_cast<ObjectPtr*>(instance->ptr()) + offset_in_words, value,
thread);
DISPATCH();
@@ -2473,7 +2485,7 @@
// Currently only used to load closure fields, which are not unboxed.
// If used for general field, code for copying the mutable box must be
// added.
- RawField* field = RAW_CAST(Field, LOAD_CONSTANT(rD + 1));
+ FieldPtr field = RAW_CAST(Field, LOAD_CONSTANT(rD + 1));
const bool unboxing =
(field->ptr()->is_nullable_ != kNullCid) &&
Field::UnboxingCandidateBit::decode(field->ptr()->kind_bits_);
@@ -2481,8 +2493,8 @@
#endif
const uword offset_in_words =
static_cast<uword>(Smi::Value(RAW_CAST(Smi, LOAD_CONSTANT(rD))));
- RawInstance* instance = static_cast<RawInstance*>(SP[0]);
- SP[0] = reinterpret_cast<RawObject**>(instance->ptr())[offset_in_words];
+ InstancePtr instance = static_cast<InstancePtr>(SP[0]);
+ SP[0] = reinterpret_cast<ObjectPtr*>(instance->ptr())[offset_in_words];
DISPATCH();
}
@@ -2490,8 +2502,8 @@
BYTECODE(LoadTypeArgumentsField, D);
const uword offset_in_words =
static_cast<uword>(Smi::Value(RAW_CAST(Smi, LOAD_CONSTANT(rD))));
- RawInstance* instance = static_cast<RawInstance*>(SP[0]);
- SP[0] = reinterpret_cast<RawObject**>(instance->ptr())[offset_in_words];
+ InstancePtr instance = static_cast<InstancePtr>(SP[0]);
+ SP[0] = reinterpret_cast<ObjectPtr*>(instance->ptr())[offset_in_words];
DISPATCH();
}
@@ -2499,8 +2511,8 @@
BYTECODE(LoadContextParent, 0);
const uword offset_in_words =
static_cast<uword>(Context::parent_offset() / kWordSize);
- RawContext* instance = static_cast<RawContext*>(SP[0]);
- SP[0] = reinterpret_cast<RawObject**>(instance->ptr())[offset_in_words];
+ ContextPtr instance = static_cast<ContextPtr>(SP[0]);
+ SP[0] = reinterpret_cast<ObjectPtr*>(instance->ptr())[offset_in_words];
DISPATCH();
}
@@ -2508,9 +2520,9 @@
BYTECODE(LoadContextVar, A_E);
const uword offset_in_words =
static_cast<uword>(Context::variable_offset(rE) / kWordSize);
- RawContext* instance = static_cast<RawContext*>(SP[0]);
+ ContextPtr instance = static_cast<ContextPtr>(SP[0]);
ASSERT(rE < static_cast<uint32_t>(instance->ptr()->num_variables_));
- SP[0] = reinterpret_cast<RawObject**>(instance->ptr())[offset_in_words];
+ SP[0] = reinterpret_cast<ObjectPtr*>(instance->ptr())[offset_in_words];
DISPATCH();
}
@@ -2536,17 +2548,17 @@
{
BYTECODE(Allocate, D);
- RawClass* cls = Class::RawCast(LOAD_CONSTANT(rD));
+ ClassPtr cls = Class::RawCast(LOAD_CONSTANT(rD));
if (LIKELY(InterpreterHelpers::IsFinalized(cls))) {
const intptr_t class_id = cls->ptr()->id_;
const intptr_t instance_size = cls->ptr()->host_instance_size_in_words_
<< kWordSizeLog2;
- RawObject* result;
+ ObjectPtr result;
if (TryAllocate(thread, class_id, instance_size, &result)) {
- uword start = RawObject::ToAddr(result);
- for (intptr_t offset = sizeof(RawInstance); offset < instance_size;
+ uword start = ObjectLayout::ToAddr(result);
+ for (intptr_t offset = sizeof(InstanceLayout); offset < instance_size;
offset += kWordSize) {
- *reinterpret_cast<RawObject**>(start + offset) = null_value;
+ *reinterpret_cast<ObjectPtr*>(start + offset) = null_value;
}
*++SP = result;
DISPATCH();
@@ -2565,23 +2577,23 @@
{
BYTECODE(AllocateT, 0);
- RawClass* cls = Class::RawCast(SP[0]);
- RawTypeArguments* type_args = TypeArguments::RawCast(SP[-1]);
+ ClassPtr cls = Class::RawCast(SP[0]);
+ TypeArgumentsPtr type_args = TypeArguments::RawCast(SP[-1]);
if (LIKELY(InterpreterHelpers::IsFinalized(cls))) {
const intptr_t class_id = cls->ptr()->id_;
const intptr_t instance_size = cls->ptr()->host_instance_size_in_words_
<< kWordSizeLog2;
- RawObject* result;
+ ObjectPtr result;
if (TryAllocate(thread, class_id, instance_size, &result)) {
- uword start = RawObject::ToAddr(result);
- for (intptr_t offset = sizeof(RawInstance); offset < instance_size;
+ uword start = ObjectLayout::ToAddr(result);
+ for (intptr_t offset = sizeof(InstanceLayout); offset < instance_size;
offset += kWordSize) {
- *reinterpret_cast<RawObject**>(start + offset) = null_value;
+ *reinterpret_cast<ObjectPtr*>(start + offset) = null_value;
}
const intptr_t type_args_offset =
cls->ptr()->host_type_arguments_field_offset_in_words_
<< kWordSizeLog2;
- *reinterpret_cast<RawObject**>(start + type_args_offset) = type_args;
+ *reinterpret_cast<ObjectPtr*>(start + type_args_offset) = type_args;
*--SP = result;
DISPATCH();
}
@@ -2598,8 +2610,8 @@
{
BYTECODE(CreateArrayTOS, 0);
- RawTypeArguments* type_args = TypeArguments::RawCast(SP[-1]);
- RawObject* length = SP[0];
+ TypeArgumentsPtr type_args = TypeArguments::RawCast(SP[-1]);
+ ObjectPtr length = SP[0];
SP--;
if (!AllocateArray(thread, type_args, length, pc, FP, SP)) {
HANDLE_EXCEPTION;
@@ -2610,14 +2622,14 @@
{
BYTECODE(AssertAssignable, A_E);
// Stack: instance, type, instantiator type args, function type args, name
- RawObject** args = SP - 4;
+ ObjectPtr* args = SP - 4;
const bool may_be_smi = (rA == 1);
const bool is_smi =
- ((reinterpret_cast<intptr_t>(args[0]) & kSmiTagMask) == kSmiTag);
+ ((static_cast<intptr_t>(args[0]) & kSmiTagMask) == kSmiTag);
const bool smi_ok = is_smi && may_be_smi;
if (!smi_ok && (args[0] != null_value)) {
- RawSubtypeTestCache* cache =
- static_cast<RawSubtypeTestCache*>(LOAD_CONSTANT(rE));
+ SubtypeTestCachePtr cache =
+ static_cast<SubtypeTestCachePtr>(LOAD_CONSTANT(rE));
if (!AssertAssignable(thread, pc, FP, SP, args, cache)) {
HANDLE_EXCEPTION;
@@ -2630,7 +2642,7 @@
{
BYTECODE(AssertSubtype, 0);
- RawObject** args = SP - 4;
+ ObjectPtr* args = SP - 4;
// TODO(kustermann): Implement fast case for common arguments.
@@ -2643,7 +2655,7 @@
// This is unused, since the negative case throws an exception.
SP++;
- RawObject** result_slot = SP;
+ ObjectPtr* result_slot = SP;
Exit(thread, FP, SP + 1, pc);
INVOKE_RUNTIME(DRT_SubtypeCheck,
@@ -2657,7 +2669,7 @@
{
BYTECODE(AssertBoolean, A);
- RawObject* value = SP[0];
+ ObjectPtr value = SP[0];
if (rA != 0u) { // Should we perform type check?
if ((value == true_value) || (value == false_value)) {
goto AssertBooleanOk;
@@ -2764,12 +2776,12 @@
{
BYTECODE(StoreIndexedTOS, 0);
SP -= 3;
- RawArray* array = RAW_CAST(Array, SP[1]);
- RawSmi* index = RAW_CAST(Smi, SP[2]);
- RawObject* value = SP[3];
+ ArrayPtr array = RAW_CAST(Array, SP[1]);
+ SmiPtr index = RAW_CAST(Smi, SP[2]);
+ ObjectPtr value = SP[3];
ASSERT(InterpreterHelpers::CheckIndex(index, array->ptr()->length_));
- array->StorePointer(array->ptr()->data() + Smi::Value(index), value,
- thread);
+ array->ptr()->StorePointer(array->ptr()->data() + Smi::Value(index), value,
+ thread);
DISPATCH();
}
@@ -3139,20 +3151,20 @@
{
BYTECODE(VMInternal_ImplicitGetter, 0);
- RawFunction* function = FrameFunction(FP);
- ASSERT(Function::kind(function) == RawFunction::kImplicitGetter);
+ FunctionPtr function = FrameFunction(FP);
+ ASSERT(Function::kind(function) == FunctionLayout::kImplicitGetter);
BUMP_USAGE_COUNTER_ON_ENTRY(function);
// Field object is cached in function's data_.
- RawField* field = reinterpret_cast<RawField*>(function->ptr()->data_);
+ FieldPtr field = static_cast<FieldPtr>(function->ptr()->data_);
intptr_t offset_in_words = field->ptr()->host_offset_or_field_id_;
const intptr_t kArgc = 1;
- RawInstance* instance =
- reinterpret_cast<RawInstance*>(FrameArguments(FP, kArgc)[0]);
- RawInstance* value =
- reinterpret_cast<RawInstance**>(instance->ptr())[offset_in_words];
+ InstancePtr instance =
+ static_cast<InstancePtr>(FrameArguments(FP, kArgc)[0]);
+ InstancePtr value =
+ reinterpret_cast<InstancePtr*>(instance->ptr())[offset_in_words];
if (UNLIKELY(value == Object::sentinel().raw())) {
SP[1] = 0; // Result slot.
@@ -3164,10 +3176,10 @@
NativeArguments(thread, 2, /* argv */ SP + 2, /* ret val */ SP + 1));
function = FrameFunction(FP);
- instance = reinterpret_cast<RawInstance*>(SP[2]);
- field = reinterpret_cast<RawField*>(SP[3]);
+ instance = static_cast<InstancePtr>(SP[2]);
+ field = static_cast<FieldPtr>(SP[3]);
offset_in_words = field->ptr()->host_offset_or_field_id_;
- value = reinterpret_cast<RawInstance**>(instance->ptr())[offset_in_words];
+ value = reinterpret_cast<InstancePtr*>(instance->ptr())[offset_in_words];
}
*++SP = value;
@@ -3179,9 +3191,9 @@
HANDLE_EXCEPTION;
}
// Reload objects after the call which may trigger GC.
- field = reinterpret_cast<RawField*>(FrameFunction(FP)->ptr()->data_);
- instance = reinterpret_cast<RawInstance*>(FrameArguments(FP, kArgc)[0]);
- value = reinterpret_cast<RawInstance**>(instance->ptr())[offset_in_words];
+ field = static_cast<FieldPtr>(FrameFunction(FP)->ptr()->data_);
+ instance = static_cast<InstancePtr>(FrameArguments(FP, kArgc)[0]);
+ value = reinterpret_cast<InstancePtr*>(instance->ptr())[offset_in_words];
}
#endif
@@ -3220,28 +3232,27 @@
{
BYTECODE(VMInternal_ImplicitSetter, 0);
- RawFunction* function = FrameFunction(FP);
- ASSERT(Function::kind(function) == RawFunction::kImplicitSetter);
+ FunctionPtr function = FrameFunction(FP);
+ ASSERT(Function::kind(function) == FunctionLayout::kImplicitSetter);
BUMP_USAGE_COUNTER_ON_ENTRY(function);
// Field object is cached in function's data_.
- RawField* field = reinterpret_cast<RawField*>(function->ptr()->data_);
+ FieldPtr field = static_cast<FieldPtr>(function->ptr()->data_);
intptr_t offset_in_words = field->ptr()->host_offset_or_field_id_;
const intptr_t kArgc = 2;
- RawInstance* instance =
- reinterpret_cast<RawInstance*>(FrameArguments(FP, kArgc)[0]);
- RawInstance* value =
- reinterpret_cast<RawInstance*>(FrameArguments(FP, kArgc)[1]);
+ InstancePtr instance =
+ static_cast<InstancePtr>(FrameArguments(FP, kArgc)[0]);
+ InstancePtr value = static_cast<InstancePtr>(FrameArguments(FP, kArgc)[1]);
if (!AssertAssignableField<false>(thread, pc, FP, SP, instance, field,
value)) {
HANDLE_EXCEPTION;
}
// Reload objects after the call which may trigger GC.
- field = reinterpret_cast<RawField*>(FrameFunction(FP)->ptr()->data_);
- instance = reinterpret_cast<RawInstance*>(FrameArguments(FP, kArgc)[0]);
- value = reinterpret_cast<RawInstance*>(FrameArguments(FP, kArgc)[1]);
+ field = static_cast<FieldPtr>(FrameFunction(FP)->ptr()->data_);
+ instance = static_cast<InstancePtr>(FrameArguments(FP, kArgc)[0]);
+ value = static_cast<InstancePtr>(FrameArguments(FP, kArgc)[1]);
if (InterpreterHelpers::FieldNeedsGuardUpdate(field, value)) {
SP[1] = 0; // Unused result of runtime call.
@@ -3255,9 +3266,9 @@
}
// Reload objects after the call which may trigger GC.
- field = reinterpret_cast<RawField*>(FrameFunction(FP)->ptr()->data_);
- instance = reinterpret_cast<RawInstance*>(FrameArguments(FP, kArgc)[0]);
- value = reinterpret_cast<RawInstance*>(FrameArguments(FP, kArgc)[1]);
+ field = static_cast<FieldPtr>(FrameFunction(FP)->ptr()->data_);
+ instance = static_cast<InstancePtr>(FrameArguments(FP, kArgc)[0]);
+ value = static_cast<InstancePtr>(FrameArguments(FP, kArgc)[1]);
}
const bool unboxing =
@@ -3266,29 +3277,29 @@
classid_t guarded_cid = field->ptr()->guarded_cid_;
if (unboxing && (guarded_cid == kDoubleCid) && supports_unboxed_doubles_) {
double raw_value = Double::RawCast(value)->ptr()->value_;
- RawDouble* box =
- *(reinterpret_cast<RawDouble**>(instance->ptr()) + offset_in_words);
+ DoublePtr box =
+ *(reinterpret_cast<DoublePtr*>(instance->ptr()) + offset_in_words);
ASSERT(box != null_value); // Non-initializing store.
box->ptr()->value_ = raw_value;
} else if (unboxing && (guarded_cid == kFloat32x4Cid) &&
supports_unboxed_simd128_) {
simd128_value_t raw_value;
raw_value.readFrom(Float32x4::RawCast(value)->ptr()->value_);
- RawFloat32x4* box = *(reinterpret_cast<RawFloat32x4**>(instance->ptr()) +
- offset_in_words);
+ Float32x4Ptr box =
+ *(reinterpret_cast<Float32x4Ptr*>(instance->ptr()) + offset_in_words);
ASSERT(box != null_value); // Non-initializing store.
raw_value.writeTo(box->ptr()->value_);
} else if (unboxing && (guarded_cid == kFloat64x2Cid) &&
supports_unboxed_simd128_) {
simd128_value_t raw_value;
raw_value.readFrom(Float64x2::RawCast(value)->ptr()->value_);
- RawFloat64x2* box = *(reinterpret_cast<RawFloat64x2**>(instance->ptr()) +
- offset_in_words);
+ Float64x2Ptr box =
+ *(reinterpret_cast<Float64x2Ptr*>(instance->ptr()) + offset_in_words);
ASSERT(box != null_value); // Non-initializing store.
raw_value.writeTo(box->ptr()->value_);
} else {
- instance->StorePointer(
- reinterpret_cast<RawInstance**>(instance->ptr()) + offset_in_words,
+ instance->ptr()->StorePointer(
+ reinterpret_cast<InstancePtr*>(instance->ptr()) + offset_in_words,
value, thread);
}
@@ -3300,15 +3311,15 @@
{
BYTECODE(VMInternal_ImplicitStaticGetter, 0);
- RawFunction* function = FrameFunction(FP);
- ASSERT(Function::kind(function) == RawFunction::kImplicitStaticGetter);
+ FunctionPtr function = FrameFunction(FP);
+ ASSERT(Function::kind(function) == FunctionLayout::kImplicitStaticGetter);
BUMP_USAGE_COUNTER_ON_ENTRY(function);
// Field object is cached in function's data_.
- RawField* field = reinterpret_cast<RawField*>(function->ptr()->data_);
+ FieldPtr field = static_cast<FieldPtr>(function->ptr()->data_);
intptr_t field_id = field->ptr()->host_offset_or_field_id_;
- RawInstance* value = thread->field_table_values()[field_id];
+ InstancePtr value = thread->field_table_values()[field_id];
if (value == Object::sentinel().raw() ||
value == Object::transition_sentinel().raw()) {
SP[1] = 0; // Unused result of invoking the initializer.
@@ -3319,7 +3330,7 @@
// Reload objects after the call which may trigger GC.
function = FrameFunction(FP);
- field = reinterpret_cast<RawField*>(function->ptr()->data_);
+ field = static_cast<FieldPtr>(function->ptr()->data_);
// The field is initialized by the runtime call, but not returned.
intptr_t field_id = field->ptr()->host_offset_or_field_id_;
value = thread->field_table_values()[field_id];
@@ -3330,9 +3341,9 @@
#if !defined(PRODUCT)
if (UNLIKELY(Field::NeedsLoadGuardBit::decode(field->ptr()->kind_bits_))) {
- if (!AssertAssignableField<true>(
- thread, pc, FP, SP, reinterpret_cast<RawInstance*>(null_value),
- field, value)) {
+ if (!AssertAssignableField<true>(thread, pc, FP, SP,
+ static_cast<InstancePtr>(null_value),
+ field, value)) {
HANDLE_EXCEPTION;
}
}
@@ -3344,8 +3355,8 @@
{
BYTECODE(VMInternal_MethodExtractor, 0);
- RawFunction* function = FrameFunction(FP);
- ASSERT(Function::kind(function) == RawFunction::kMethodExtractor);
+ FunctionPtr function = FrameFunction(FP);
+ ASSERT(Function::kind(function) == FunctionLayout::kMethodExtractor);
BUMP_USAGE_COUNTER_ON_ENTRY(function);
@@ -3361,21 +3372,22 @@
HANDLE_EXCEPTION;
}
- RawContext* context = Context::RawCast(*SP--);
- RawInstance* instance = Instance::RawCast(FrameArguments(FP, 1)[0]);
- context->StorePointer(
- reinterpret_cast<RawInstance**>(&context->ptr()->data()[0]), instance);
+ ContextPtr context = Context::RawCast(*SP--);
+ InstancePtr instance = Instance::RawCast(FrameArguments(FP, 1)[0]);
+ context->ptr()->StorePointer(
+ reinterpret_cast<InstancePtr*>(&context->ptr()->data()[0]), instance);
- RawClosure* closure = Closure::RawCast(*SP);
- closure->StorePointer(
+ ClosurePtr closure = Closure::RawCast(*SP);
+ closure->ptr()->StorePointer(
&closure->ptr()->instantiator_type_arguments_,
InterpreterHelpers::GetTypeArguments(thread, instance));
// function_type_arguments_ is already null
closure->ptr()->delayed_type_arguments_ =
Object::empty_type_arguments().raw();
- closure->StorePointer(&closure->ptr()->function_,
- Function::RawCast(FrameFunction(FP)->ptr()->data_));
- closure->StorePointer(&closure->ptr()->context_, context);
+ closure->ptr()->StorePointer(
+ &closure->ptr()->function_,
+ Function::RawCast(FrameFunction(FP)->ptr()->data_));
+ closure->ptr()->StorePointer(&closure->ptr()->context_, context);
// hash_ is already null
DISPATCH();
@@ -3384,8 +3396,8 @@
{
BYTECODE(VMInternal_InvokeClosure, 0);
- RawFunction* function = FrameFunction(FP);
- ASSERT(Function::kind(function) == RawFunction::kInvokeFieldDispatcher);
+ FunctionPtr function = FrameFunction(FP);
+ ASSERT(Function::kind(function) == FunctionLayout::kInvokeFieldDispatcher);
BUMP_USAGE_COUNTER_ON_ENTRY(function);
@@ -3395,7 +3407,7 @@
const intptr_t argc =
InterpreterHelpers::ArgDescArgCount(argdesc_) + receiver_idx;
- RawClosure* receiver =
+ ClosurePtr receiver =
Closure::RawCast(FrameArguments(FP, argc)[receiver_idx]);
function = receiver->ptr()->function_;
@@ -3406,8 +3418,8 @@
{
BYTECODE(VMInternal_InvokeField, 0);
- RawFunction* function = FrameFunction(FP);
- ASSERT(Function::kind(function) == RawFunction::kInvokeFieldDispatcher);
+ FunctionPtr function = FrameFunction(FP);
+ ASSERT(Function::kind(function) == FunctionLayout::kInvokeFieldDispatcher);
BUMP_USAGE_COUNTER_ON_ENTRY(function);
@@ -3417,7 +3429,7 @@
const intptr_t argc =
InterpreterHelpers::ArgDescArgCount(argdesc_) + receiver_idx;
- RawObject* receiver = FrameArguments(FP, argc)[receiver_idx];
+ ObjectPtr receiver = FrameArguments(FP, argc)[receiver_idx];
// Invoke field getter on receiver.
{
@@ -3482,8 +3494,8 @@
}
// Copy arguments into the newly allocated array.
- RawObject** argv = FrameArguments(FP, argc);
- RawArray* array = static_cast<RawArray*>(SP[4]);
+ ObjectPtr* argv = FrameArguments(FP, argc);
+ ArrayPtr array = static_cast<ArrayPtr>(SP[4]);
ASSERT(array->GetClassId() == kArrayCid);
for (intptr_t i = 0; i < argc; i++) {
array->ptr()->data()[i] = argv[i];
@@ -3508,16 +3520,17 @@
{
BYTECODE(VMInternal_ForwardDynamicInvocation, 0);
- RawFunction* function = FrameFunction(FP);
+ FunctionPtr function = FrameFunction(FP);
ASSERT(Function::kind(function) ==
- RawFunction::kDynamicInvocationForwarder);
+ FunctionLayout::kDynamicInvocationForwarder);
BUMP_USAGE_COUNTER_ON_ENTRY(function);
- RawArray* checks = Array::RawCast(function->ptr()->data_);
- RawFunction* target = Function::RawCast(checks->ptr()->data()[0]);
- ASSERT(Function::kind(target) != RawFunction::kDynamicInvocationForwarder);
- RawBytecode* target_bytecode = target->ptr()->bytecode_;
+ ArrayPtr checks = Array::RawCast(function->ptr()->data_);
+ FunctionPtr target = Function::RawCast(checks->ptr()->data()[0]);
+ ASSERT(Function::kind(target) !=
+ FunctionLayout::kDynamicInvocationForwarder);
+ BytecodePtr target_bytecode = target->ptr()->bytecode_;
ASSERT(target_bytecode != Bytecode::null());
ASSERT(target_bytecode->IsBytecode());
@@ -3545,7 +3558,7 @@
const intptr_t argc =
InterpreterHelpers::ArgDescArgCount(argdesc_) + receiver_idx;
- RawInstance* receiver =
+ InstancePtr receiver =
Instance::RawCast(FrameArguments(FP, argc)[receiver_idx]);
SP[5] = InterpreterHelpers::GetTypeArguments(thread, receiver);
@@ -3566,7 +3579,7 @@
}
for (intptr_t i = 2; i < len; i++) {
- RawParameterTypeCheck* check =
+ ParameterTypeCheckPtr check =
ParameterTypeCheck::RawCast(checks->ptr()->data()[i]);
if (LIKELY(check->ptr()->index_ != 0)) {
@@ -3612,35 +3625,37 @@
{
BYTECODE(VMInternal_NoSuchMethodDispatcher, 0);
- RawFunction* function = FrameFunction(FP);
- ASSERT(Function::kind(function) == RawFunction::kNoSuchMethodDispatcher);
+ FunctionPtr function = FrameFunction(FP);
+ ASSERT(Function::kind(function) == FunctionLayout::kNoSuchMethodDispatcher);
goto NoSuchMethodFromPrologue;
}
{
BYTECODE(VMInternal_ImplicitStaticClosure, 0);
- RawFunction* function = FrameFunction(FP);
- ASSERT(Function::kind(function) == RawFunction::kImplicitClosureFunction);
+ FunctionPtr function = FrameFunction(FP);
+ ASSERT(Function::kind(function) ==
+ FunctionLayout::kImplicitClosureFunction);
UNIMPLEMENTED();
DISPATCH();
}
{
BYTECODE(VMInternal_ImplicitInstanceClosure, 0);
- RawFunction* function = FrameFunction(FP);
- ASSERT(Function::kind(function) == RawFunction::kImplicitClosureFunction);
+ FunctionPtr function = FrameFunction(FP);
+ ASSERT(Function::kind(function) ==
+ FunctionLayout::kImplicitClosureFunction);
UNIMPLEMENTED();
DISPATCH();
}
{
TailCallSP1:
- RawFunction* function = Function::RawCast(SP[1]);
+ FunctionPtr function = Function::RawCast(SP[1]);
for (;;) {
if (Function::HasBytecode(function)) {
ASSERT(function->IsFunction());
- RawBytecode* bytecode = function->ptr()->bytecode_;
+ BytecodePtr bytecode = function->ptr()->bytecode_;
ASSERT(bytecode->IsBytecode());
FP[kKBCFunctionSlotFromFp] = function;
FP[kKBCPcMarkerSlotFromFp] = bytecode;
@@ -3656,13 +3671,13 @@
const intptr_t receiver_idx = type_args_len > 0 ? 1 : 0;
const intptr_t argc =
InterpreterHelpers::ArgDescArgCount(argdesc_) + receiver_idx;
- RawObject** argv = FrameArguments(FP, argc);
+ ObjectPtr* argv = FrameArguments(FP, argc);
for (intptr_t i = 0; i < argc; i++) {
*++SP = argv[i];
}
- RawObject** call_base = SP - argc + 1;
- RawObject** call_top = SP + 1;
+ ObjectPtr* call_base = SP - argc + 1;
+ ObjectPtr* call_top = SP + 1;
call_top[0] = function;
if (!InvokeCompiled(thread, function, call_base, call_top, &pc, &FP,
&SP)) {
@@ -3693,14 +3708,14 @@
// Helper used to handle noSuchMethod on closures.
{
NoSuchMethodFromPrologue:
- RawFunction* function = FrameFunction(FP);
+ FunctionPtr function = FrameFunction(FP);
const intptr_t type_args_len =
InterpreterHelpers::ArgDescTypeArgsLen(argdesc_);
const intptr_t receiver_idx = type_args_len > 0 ? 1 : 0;
const intptr_t argc =
InterpreterHelpers::ArgDescArgCount(argdesc_) + receiver_idx;
- RawObject** args = FrameArguments(FP, argc);
+ ObjectPtr* args = FrameArguments(FP, argc);
SP[1] = null_value;
SP[2] = args[receiver_idx];
@@ -3719,7 +3734,7 @@
}
// Copy arguments into the newly allocated array.
- RawArray* array = static_cast<RawArray*>(SP[5]);
+ ArrayPtr array = static_cast<ArrayPtr>(SP[5]);
ASSERT(array->GetClassId() == kArrayCid);
for (intptr_t i = 0; i < argc; i++) {
array->ptr()->data()[i] = args[i];
@@ -3776,10 +3791,9 @@
FP = fp_;
pc = pc_;
if (IsEntryFrameMarker(pc)) {
- pp_ = reinterpret_cast<RawObjectPool*>(fp_[kKBCSavedPpSlotFromEntryFp]);
- argdesc_ =
- reinterpret_cast<RawArray*>(fp_[kKBCSavedArgDescSlotFromEntryFp]);
- uword exit_fp = reinterpret_cast<uword>(fp_[kKBCExitLinkSlotFromEntryFp]);
+ pp_ = static_cast<ObjectPoolPtr>(fp_[kKBCSavedPpSlotFromEntryFp]);
+ argdesc_ = static_cast<ArrayPtr>(fp_[kKBCSavedArgDescSlotFromEntryFp]);
+ uword exit_fp = static_cast<uword>(fp_[kKBCExitLinkSlotFromEntryFp]);
thread->set_top_exit_frame_info(exit_fp);
thread->set_top_resource(top_resource);
thread->set_vm_tag(vm_tag);
@@ -3819,13 +3833,13 @@
// in the previous C++ frames.
StackResource::Unwind(thread);
- fp_ = reinterpret_cast<RawObject**>(fp);
+ fp_ = reinterpret_cast<ObjectPtr*>(fp);
if (pc == StubCode::RunExceptionHandler().EntryPoint()) {
// The RunExceptionHandler stub is a placeholder. We implement
// its behavior here.
- RawObject* raw_exception = thread->active_exception();
- RawObject* raw_stacktrace = thread->active_stacktrace();
+ ObjectPtr raw_exception = thread->active_exception();
+ ObjectPtr raw_stacktrace = thread->active_stacktrace();
ASSERT(raw_exception != Object::null());
thread->set_active_exception(Object::null_object());
thread->set_active_stacktrace(Object::null_object());
@@ -3846,8 +3860,8 @@
}
void Interpreter::VisitObjectPointers(ObjectPointerVisitor* visitor) {
- visitor->VisitPointer(reinterpret_cast<RawObject**>(&pp_));
- visitor->VisitPointer(reinterpret_cast<RawObject**>(&argdesc_));
+ visitor->VisitPointer(reinterpret_cast<ObjectPtr*>(&pp_));
+ visitor->VisitPointer(reinterpret_cast<ObjectPtr*>(&argdesc_));
}
} // namespace dart
diff --git a/runtime/vm/interpreter.h b/runtime/vm/interpreter.h
index 03d913a..bc76fc9 100644
--- a/runtime/vm/interpreter.h
+++ b/runtime/vm/interpreter.h
@@ -10,6 +10,7 @@
#include "vm/compiler/method_recognizer.h"
#include "vm/constants_kbc.h"
+#include "vm/tagged_pointer.h"
namespace dart {
@@ -18,17 +19,6 @@
class InterpreterSetjmpBuffer;
class Isolate;
class ObjectPointerVisitor;
-class RawArray;
-class RawField;
-class RawFunction;
-class RawICData;
-class RawImmutableArray;
-class RawInstance;
-class RawObject;
-class RawObjectPool;
-class RawString;
-class RawSubtypeTestCache;
-class RawTypeArguments;
class Thread;
class LookupCache : public ValueObject {
@@ -41,20 +31,20 @@
void Clear();
bool Lookup(intptr_t receiver_cid,
- RawString* function_name,
- RawArray* arguments_descriptor,
- RawFunction** target) const;
+ StringPtr function_name,
+ ArrayPtr arguments_descriptor,
+ FunctionPtr* target) const;
void Insert(intptr_t receiver_cid,
- RawString* function_name,
- RawArray* arguments_descriptor,
- RawFunction* target);
+ StringPtr function_name,
+ ArrayPtr arguments_descriptor,
+ FunctionPtr target);
private:
struct Entry {
intptr_t receiver_cid;
- RawString* function_name;
- RawArray* arguments_descriptor;
- RawFunction* target;
+ StringPtr function_name;
+ ArrayPtr arguments_descriptor;
+ FunctionPtr target;
};
static const intptr_t kNumEntries = 1024;
@@ -69,8 +59,8 @@
// instruction returning the value in result. Otherwise interpreter proceeds to
// execute the body of the function.
typedef bool (*IntrinsicHandler)(Thread* thread,
- RawObject** FP,
- RawObject** result);
+ ObjectPtr* FP,
+ ObjectPtr* result);
class Interpreter {
public:
@@ -104,16 +94,16 @@
return reinterpret_cast<word>(pc) == kEntryFramePcMarker;
}
- RawObject* Call(const Function& function,
- const Array& arguments_descriptor,
- const Array& arguments,
- Thread* thread);
+ ObjectPtr Call(const Function& function,
+ const Array& arguments_descriptor,
+ const Array& arguments,
+ Thread* thread);
- RawObject* Call(RawFunction* function,
- RawArray* argdesc,
- intptr_t argc,
- RawObject* const* argv,
- Thread* thread);
+ ObjectPtr Call(FunctionPtr function,
+ ArrayPtr argdesc,
+ intptr_t argc,
+ ObjectPtr const* argv,
+ Thread* thread);
void JumpToFrame(uword pc, uword sp, uword fp, Thread* thread);
@@ -137,113 +127,113 @@
uword overflow_stack_limit_;
uword stack_limit_;
- RawObject** volatile fp_;
+ ObjectPtr* volatile fp_;
const KBCInstr* volatile pc_;
DEBUG_ONLY(uint64_t icount_;)
InterpreterSetjmpBuffer* last_setjmp_buffer_;
- RawObjectPool* pp_; // Pool Pointer.
- RawArray* argdesc_; // Arguments Descriptor: used to pass information between
- // call instruction and the function entry.
- RawObject* special_[KernelBytecode::kSpecialIndexCount];
+ ObjectPoolPtr pp_; // Pool Pointer.
+ ArrayPtr argdesc_; // Arguments Descriptor: used to pass information between
+ // call instruction and the function entry.
+ ObjectPtr special_[KernelBytecode::kSpecialIndexCount];
LookupCache lookup_cache_;
void Exit(Thread* thread,
- RawObject** base,
- RawObject** exit_frame,
+ ObjectPtr* base,
+ ObjectPtr* exit_frame,
const KBCInstr* pc);
bool Invoke(Thread* thread,
- RawObject** call_base,
- RawObject** call_top,
+ ObjectPtr* call_base,
+ ObjectPtr* call_top,
const KBCInstr** pc,
- RawObject*** FP,
- RawObject*** SP);
+ ObjectPtr** FP,
+ ObjectPtr** SP);
bool InvokeCompiled(Thread* thread,
- RawFunction* function,
- RawObject** call_base,
- RawObject** call_top,
+ FunctionPtr function,
+ ObjectPtr* call_base,
+ ObjectPtr* call_top,
const KBCInstr** pc,
- RawObject*** FP,
- RawObject*** SP);
+ ObjectPtr** FP,
+ ObjectPtr** SP);
bool InvokeBytecode(Thread* thread,
- RawFunction* function,
- RawObject** call_base,
- RawObject** call_top,
+ FunctionPtr function,
+ ObjectPtr* call_base,
+ ObjectPtr* call_top,
const KBCInstr** pc,
- RawObject*** FP,
- RawObject*** SP);
+ ObjectPtr** FP,
+ ObjectPtr** SP);
bool InstanceCall(Thread* thread,
- RawString* target_name,
- RawObject** call_base,
- RawObject** call_top,
+ StringPtr target_name,
+ ObjectPtr* call_base,
+ ObjectPtr* call_top,
const KBCInstr** pc,
- RawObject*** FP,
- RawObject*** SP);
+ ObjectPtr** FP,
+ ObjectPtr** SP);
bool CopyParameters(Thread* thread,
const KBCInstr** pc,
- RawObject*** FP,
- RawObject*** SP,
+ ObjectPtr** FP,
+ ObjectPtr** SP,
const intptr_t num_fixed_params,
const intptr_t num_opt_pos_params,
const intptr_t num_opt_named_params);
bool AssertAssignable(Thread* thread,
const KBCInstr* pc,
- RawObject** FP,
- RawObject** call_top,
- RawObject** args,
- RawSubtypeTestCache* cache);
+ ObjectPtr* FP,
+ ObjectPtr* call_top,
+ ObjectPtr* args,
+ SubtypeTestCachePtr cache);
template <bool is_getter>
bool AssertAssignableField(Thread* thread,
const KBCInstr* pc,
- RawObject** FP,
- RawObject** SP,
- RawInstance* instance,
- RawField* field,
- RawInstance* value);
+ ObjectPtr* FP,
+ ObjectPtr* SP,
+ InstancePtr instance,
+ FieldPtr field,
+ InstancePtr value);
bool AllocateMint(Thread* thread,
int64_t value,
const KBCInstr* pc,
- RawObject** FP,
- RawObject** SP);
+ ObjectPtr* FP,
+ ObjectPtr* SP);
bool AllocateDouble(Thread* thread,
double value,
const KBCInstr* pc,
- RawObject** FP,
- RawObject** SP);
+ ObjectPtr* FP,
+ ObjectPtr* SP);
bool AllocateFloat32x4(Thread* thread,
simd128_value_t value,
const KBCInstr* pc,
- RawObject** FP,
- RawObject** SP);
+ ObjectPtr* FP,
+ ObjectPtr* SP);
bool AllocateFloat64x2(Thread* thread,
simd128_value_t value,
const KBCInstr* pc,
- RawObject** FP,
- RawObject** SP);
+ ObjectPtr* FP,
+ ObjectPtr* SP);
bool AllocateArray(Thread* thread,
- RawTypeArguments* type_args,
- RawObject* length,
+ TypeArgumentsPtr type_args,
+ ObjectPtr length,
const KBCInstr* pc,
- RawObject** FP,
- RawObject** SP);
+ ObjectPtr* FP,
+ ObjectPtr* SP);
bool AllocateContext(Thread* thread,
intptr_t num_variables,
const KBCInstr* pc,
- RawObject** FP,
- RawObject** SP);
+ ObjectPtr* FP,
+ ObjectPtr* SP);
bool AllocateClosure(Thread* thread,
const KBCInstr* pc,
- RawObject** FP,
- RawObject** SP);
+ ObjectPtr* FP,
+ ObjectPtr* SP);
#if defined(DEBUG)
// Returns true if tracing of executed instructions is enabled.
diff --git a/runtime/vm/isolate.cc b/runtime/vm/isolate.cc
index 6af9e05..1a74498 100644
--- a/runtime/vm/isolate.cc
+++ b/runtime/vm/isolate.cc
@@ -117,7 +117,7 @@
}
}
-static RawInstance* DeserializeMessage(Thread* thread, Message* message) {
+static InstancePtr DeserializeMessage(Thread* thread, Message* message) {
if (message == NULL) {
return Instance::null();
}
@@ -274,6 +274,9 @@
// Ensure we destroy the heap before the other members.
heap_ = nullptr;
ASSERT(marking_stack_ == nullptr);
+
+ delete reverse_pc_lookup_cache_;
+ reverse_pc_lookup_cache_ = nullptr;
}
void IsolateGroup::RegisterIsolate(Isolate* isolate) {
@@ -645,6 +648,15 @@
#endif // !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME)
}
+Bequest::~Bequest() {
+ IsolateGroup* isolate_group = IsolateGroup::Current();
+ CHECK_ISOLATE_GROUP(isolate_group);
+ NoSafepointScope no_safepoint_scope;
+ ApiState* state = isolate_group->api_state();
+ ASSERT(state != nullptr);
+ state->FreePersistentHandle(handle_);
+}
+
void Isolate::RegisterClass(const Class& cls) {
#if !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME)
if (group()->IsReloading()) {
@@ -755,7 +767,7 @@
private:
// A result of false indicates that the isolate should terminate the
// processing of further events.
- RawError* HandleLibMessage(const Array& message);
+ ErrorPtr HandleLibMessage(const Array& message);
MessageStatus ProcessUnhandledException(const Error& result);
Isolate* isolate_;
@@ -773,7 +785,7 @@
// Isolate library OOB messages are fixed sized arrays which have the
// following format:
// [ OOB dispatch, Isolate library dispatch, <message specific data> ]
-RawError* IsolateMessageHandler::HandleLibMessage(const Array& message) {
+ErrorPtr IsolateMessageHandler::HandleLibMessage(const Array& message) {
if (message.Length() < 2) return Error::null();
Zone* zone = T->zone();
const Object& type = Object::Handle(zone, message.At(1));
@@ -1039,6 +1051,11 @@
msg_obj = message->raw_obj();
// We should only be sending RawObjects that can be converted to CObjects.
ASSERT(ApiObjectConverter::CanConvert(msg_obj.raw()));
+ } else if (message->IsBequest()) {
+ Bequest* bequest = message->bequest();
+ PersistentHandle* handle = bequest->handle();
+ const Object& obj = Object::Handle(zone, handle->raw());
+ msg_obj = obj.raw();
} else {
MessageSnapshotReader reader(message.get(), thread);
msg_obj = reader.ReadObject();
@@ -1247,7 +1264,7 @@
// exception.
if (result.IsUnhandledException()) {
const UnhandledException& error = UnhandledException::Cast(result);
- RawInstance* exception = error.exception();
+ InstancePtr exception = error.exception();
if ((exception == I->object_store()->out_of_memory()) ||
(exception == I->object_store()->stack_overflow())) {
// We didn't notify the debugger when the stack was full. Do it now.
@@ -1452,9 +1469,6 @@
// RELEASE_ASSERT(reload_context_ == NULL);
#endif // !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME)
- delete reverse_pc_lookup_cache_;
- reverse_pc_lookup_cache_ = nullptr;
-
if (FLAG_enable_interpreter) {
delete background_compiler_;
background_compiler_ = nullptr;
@@ -1622,9 +1636,9 @@
return mutator_thread_;
}
-RawObject* Isolate::CallTagHandler(Dart_LibraryTag tag,
- const Object& arg1,
- const Object& arg2) {
+ObjectPtr Isolate::CallTagHandler(Dart_LibraryTag tag,
+ const Object& arg1,
+ const Object& arg2) {
Thread* thread = Thread::Current();
Api::Scope api_scope(thread);
Dart_Handle api_arg1 = Api::NewHandle(thread, arg1.raw());
@@ -1686,7 +1700,7 @@
#endif // !defined(PRODUCT)
}
-RawError* Isolate::PausePostRequest() {
+ErrorPtr Isolate::PausePostRequest() {
#if !defined(PRODUCT)
if (debugger_ == nullptr) {
return Error::null();
@@ -2172,7 +2186,7 @@
Dart::ShutdownIsolate(isolate);
}
-void Isolate::SetStickyError(RawError* sticky_error) {
+void Isolate::SetStickyError(ErrorPtr sticky_error) {
ASSERT(
((sticky_error_ == Error::null()) || (sticky_error == Error::null())) &&
(sticky_error != sticky_error_));
@@ -2199,8 +2213,8 @@
// collisions with this simple hash value. However, iterating over
// all closure functions becomes more difficult, especially when
// the list/map changes while iterating over it.
-RawFunction* Isolate::LookupClosureFunction(const Function& parent,
- TokenPosition token_pos) const {
+FunctionPtr Isolate::LookupClosureFunction(const Function& parent,
+ TokenPosition token_pos) const {
const GrowableObjectArray& closures =
GrowableObjectArray::Handle(object_store()->closure_functions());
ASSERT(!closures.IsNull());
@@ -2228,7 +2242,7 @@
return -1;
}
-RawFunction* Isolate::ClosureFunctionFromIndex(intptr_t idx) const {
+FunctionPtr Isolate::ClosureFunctionFromIndex(intptr_t idx) const {
const GrowableObjectArray& closures_array =
GrowableObjectArray::Handle(object_store()->closure_functions());
if ((idx < 0) || (idx >= closures_array.Length())) {
@@ -2375,6 +2389,12 @@
Isolate::UnMarkIsolateReady(this);
LowLevelShutdown();
+ if (bequest_.get() != nullptr) {
+ auto beneficiary = bequest_->beneficiary();
+ PortMap::PostMessage(Message::New(beneficiary, bequest_.release(),
+ Message::kNormalPriority));
+ }
+
// Now we can unregister from the thread, invoke cleanup callback, delete the
// isolate (and possibly the isolate group).
Isolate::LowLevelCleanup(this);
@@ -2472,30 +2492,29 @@
visitor->clear_gc_root_type();
// Visit the objects directly referenced from the isolate structure.
- visitor->VisitPointer(reinterpret_cast<RawObject**>(¤t_tag_));
- visitor->VisitPointer(reinterpret_cast<RawObject**>(&default_tag_));
- visitor->VisitPointer(reinterpret_cast<RawObject**>(&ic_miss_code_));
- visitor->VisitPointer(reinterpret_cast<RawObject**>(&tag_table_));
- visitor->VisitPointer(
- reinterpret_cast<RawObject**>(&deoptimized_code_array_));
- visitor->VisitPointer(reinterpret_cast<RawObject**>(&sticky_error_));
+ visitor->VisitPointer(reinterpret_cast<ObjectPtr*>(¤t_tag_));
+ visitor->VisitPointer(reinterpret_cast<ObjectPtr*>(&default_tag_));
+ visitor->VisitPointer(reinterpret_cast<ObjectPtr*>(&ic_miss_code_));
+ visitor->VisitPointer(reinterpret_cast<ObjectPtr*>(&tag_table_));
+ visitor->VisitPointer(reinterpret_cast<ObjectPtr*>(&deoptimized_code_array_));
+ visitor->VisitPointer(reinterpret_cast<ObjectPtr*>(&sticky_error_));
if (isolate_group_ != nullptr) {
if (isolate_group_->source()->hot_reload_blobs_ != nullptr) {
- visitor->VisitPointer(reinterpret_cast<RawObject**>(
+ visitor->VisitPointer(reinterpret_cast<ObjectPtr*>(
&(isolate_group_->source()->hot_reload_blobs_)));
}
}
#if !defined(PRODUCT)
visitor->VisitPointer(
- reinterpret_cast<RawObject**>(&pending_service_extension_calls_));
+ reinterpret_cast<ObjectPtr*>(&pending_service_extension_calls_));
visitor->VisitPointer(
- reinterpret_cast<RawObject**>(®istered_service_extension_handlers_));
+ reinterpret_cast<ObjectPtr*>(®istered_service_extension_handlers_));
#endif // !defined(PRODUCT)
// Visit the boxed_field_list_.
// 'boxed_field_list_' access via mutator and background compilation threads
// is guarded with a monitor. This means that we can visit it only
// when at safepoint or the field_list_mutex_ lock has been taken.
- visitor->VisitPointer(reinterpret_cast<RawObject**>(&boxed_field_list_));
+ visitor->VisitPointer(reinterpret_cast<ObjectPtr*>(&boxed_field_list_));
if (background_compiler() != nullptr) {
background_compiler()->VisitPointers(visitor);
@@ -2637,7 +2656,7 @@
if (object_store() != nullptr) {
object_store()->VisitObjectPointers(visitor);
}
- visitor->VisitPointer(reinterpret_cast<RawObject**>(&saved_unlinked_calls_));
+ visitor->VisitPointer(reinterpret_cast<ObjectPtr*>(&saved_unlinked_calls_));
VisitStackPointers(visitor, validate_frames);
}
@@ -2690,8 +2709,8 @@
/*at_safepoint=*/true);
}
-RawClass* Isolate::GetClassForHeapWalkAt(intptr_t cid) {
- RawClass* raw_class = nullptr;
+ClassPtr Isolate::GetClassForHeapWalkAt(intptr_t cid) {
+ ClassPtr raw_class = nullptr;
#if !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME)
if (group()->IsReloading()) {
raw_class = reload_context()->GetClassForHeapWalkAt(cid);
@@ -2961,9 +2980,9 @@
deoptimized_code.Add(code);
}
-RawError* Isolate::StealStickyError() {
+ErrorPtr Isolate::StealStickyError() {
NoSafepointScope no_safepoint;
- RawError* return_value = sticky_error_;
+ ErrorPtr return_value = sticky_error_;
sticky_error_ = Error::null();
return return_value;
}
@@ -2994,7 +3013,7 @@
array.Add(Field::Handle(field.Original()), Heap::kOld);
}
-RawField* Isolate::GetDeoptimizingBoxedField() {
+FieldPtr Isolate::GetDeoptimizingBoxedField() {
ASSERT(Thread::Current()->IsMutatorThread());
SafepointMutexLocker ml(&field_list_mutex_);
if (boxed_field_list_ == GrowableObjectArray::null()) {
@@ -3009,7 +3028,7 @@
}
#ifndef PRODUCT
-RawError* Isolate::InvokePendingServiceExtensionCalls() {
+ErrorPtr Isolate::InvokePendingServiceExtensionCalls() {
GrowableObjectArray& calls =
GrowableObjectArray::Handle(GetAndClearPendingServiceExtensionCalls());
if (calls.IsNull()) {
@@ -3082,8 +3101,8 @@
return Error::null();
}
-RawGrowableObjectArray* Isolate::GetAndClearPendingServiceExtensionCalls() {
- RawGrowableObjectArray* r = pending_service_extension_calls_;
+GrowableObjectArrayPtr Isolate::GetAndClearPendingServiceExtensionCalls() {
+ GrowableObjectArrayPtr r = pending_service_extension_calls_;
pending_service_extension_calls_ = GrowableObjectArray::null();
return r;
}
@@ -3177,7 +3196,7 @@
// operation atomically in the face of random OOB messages. Do not port
// to Dart code unless you can ensure that the operations will can be
// done atomically.
-RawInstance* Isolate::LookupServiceExtensionHandler(const String& name) {
+InstancePtr Isolate::LookupServiceExtensionHandler(const String& name) {
const GrowableObjectArray& handlers =
GrowableObjectArray::Handle(registered_service_extension_handlers());
if (handlers.IsNull()) {
@@ -3640,7 +3659,7 @@
delete[] debug_name_;
}
-RawObject* IsolateSpawnState::ResolveFunction() {
+ObjectPtr IsolateSpawnState::ResolveFunction() {
Thread* thread = Thread::Current();
Zone* zone = thread->zone();
@@ -3717,11 +3736,11 @@
return func.raw();
}
-RawInstance* IsolateSpawnState::BuildArgs(Thread* thread) {
+InstancePtr IsolateSpawnState::BuildArgs(Thread* thread) {
return DeserializeMessage(thread, serialized_args_.get());
}
-RawInstance* IsolateSpawnState::BuildMessage(Thread* thread) {
+InstancePtr IsolateSpawnState::BuildMessage(Thread* thread) {
return DeserializeMessage(thread, serialized_message_.get());
}
diff --git a/runtime/vm/isolate.h b/runtime/vm/isolate.h
index eaaf89c..7b784b9 100644
--- a/runtime/vm/isolate.h
+++ b/runtime/vm/isolate.h
@@ -71,19 +71,7 @@
class ObjectIdRing;
class ObjectPointerVisitor;
class ObjectStore;
-class RawInstance;
-class RawArray;
-class RawContext;
-class RawDouble;
-class RawError;
-class RawField;
-class RawGrowableObjectArray;
-class RawMint;
-class RawObject;
-class RawInteger;
-class RawFloat32x4;
-class RawInt32x4;
-class RawUserTag;
+class PersistentHandle;
class ReversePcLookupCache;
class RwLock;
class SafepointRwLock;
@@ -228,7 +216,7 @@
std::unique_ptr<intptr_t[]> cid_permutation_map;
// List of weak pointers to external typed data for hot reload blobs.
- RawArray* hot_reload_blobs_;
+ ArrayPtr hot_reload_blobs_;
intptr_t num_hot_reloads_;
};
@@ -502,10 +490,22 @@
void RememberLiveTemporaries();
void DeferredMarkLiveTemporaries();
- RawArray* saved_unlinked_calls() const { return saved_unlinked_calls_; }
+ ArrayPtr saved_unlinked_calls() const { return saved_unlinked_calls_; }
void set_saved_unlinked_calls(const Array& saved_unlinked_calls);
+ // Returns the pc -> code lookup cache object for this isolate.
+ ReversePcLookupCache* reverse_pc_lookup_cache() const {
+ return reverse_pc_lookup_cache_;
+ }
+
+ // Sets the pc -> code lookup cache object for this isolate.
+ void set_reverse_pc_lookup_cache(ReversePcLookupCache* table) {
+ ASSERT(reverse_pc_lookup_cache_ == nullptr);
+ reverse_pc_lookup_cache_ = table;
+ }
+
private:
+ friend class Dart; // For `object_store_ = ` in Dart::Init
friend class Heap;
friend class StackFrame; // For `[isolates_].First()`.
// For `object_store_shared_ptr()`, `class_table_shared_ptr()`
@@ -584,12 +584,29 @@
std::unique_ptr<StoreBuffer> store_buffer_;
std::unique_ptr<Heap> heap_;
std::unique_ptr<DispatchTable> dispatch_table_;
- RawArray* saved_unlinked_calls_;
+ ReversePcLookupCache* reverse_pc_lookup_cache_ = nullptr;
+ ArrayPtr saved_unlinked_calls_;
IdleTimeHandler idle_time_handler_;
uint32_t isolate_group_flags_ = 0;
};
+// When an isolate sends-and-exits this class represent things that it passed
+// to the beneficiary.
+class Bequest {
+ public:
+ Bequest(PersistentHandle* handle, Dart_Port beneficiary)
+ : handle_(handle), beneficiary_(beneficiary) {}
+ ~Bequest();
+
+ PersistentHandle* handle() { return handle_; }
+ Dart_Port beneficiary() { return beneficiary_; }
+
+ private:
+ PersistentHandle* handle_;
+ Dart_Port beneficiary_;
+};
+
class Isolate : public BaseIsolate, public IntrusiveDListEntry<Isolate> {
public:
// Keep both these enums in sync with isolate_patch.dart.
@@ -646,8 +663,8 @@
ClassTable* class_table() { return class_table_.get(); }
- RawClass** cached_class_table_table() { return cached_class_table_table_; }
- void set_cached_class_table_table(RawClass** cached_class_table_table) {
+ ClassPtr* cached_class_table_table() { return cached_class_table_table_; }
+ void set_cached_class_table_table(ClassPtr* cached_class_table_table) {
cached_class_table_table_ = cached_class_table_table;
}
static intptr_t cached_class_table_table_offset() {
@@ -693,7 +710,7 @@
}
// Prefers old classes when we are in the middle of a reload.
- RawClass* GetClassForHeapWalkAt(intptr_t cid);
+ ClassPtr GetClassForHeapWalkAt(intptr_t cid);
static intptr_t ic_miss_code_offset() {
return OFFSET_OF(Isolate, ic_miss_code_);
@@ -707,6 +724,10 @@
message_notify_callback_ = value;
}
+ void bequeath(std::unique_ptr<Bequest> bequest) {
+ bequest_ = std::move(bequest);
+ }
+
IsolateGroupSource* source() const { return isolate_group_->source(); }
IsolateGroup* group() const { return isolate_group_; }
@@ -756,9 +777,9 @@
bool HasTagHandler() const {
return group()->library_tag_handler() != nullptr;
}
- RawObject* CallTagHandler(Dart_LibraryTag tag,
- const Object& arg1,
- const Object& arg2);
+ ObjectPtr CallTagHandler(Dart_LibraryTag tag,
+ const Object& arg1,
+ const Object& arg2);
void SetupImagePage(const uint8_t* snapshot_buffer, bool is_executable);
@@ -986,7 +1007,7 @@
}
#endif // !defined(PRODUCT)
- RawError* PausePostRequest();
+ ErrorPtr PausePostRequest();
uword user_tag() const { return user_tag_; }
static intptr_t user_tag_offset() { return OFFSET_OF(Isolate, user_tag_); }
@@ -1006,28 +1027,28 @@
static intptr_t IsolateListLength();
- RawGrowableObjectArray* tag_table() const { return tag_table_; }
+ GrowableObjectArrayPtr tag_table() const { return tag_table_; }
void set_tag_table(const GrowableObjectArray& value);
- RawUserTag* current_tag() const { return current_tag_; }
+ UserTagPtr current_tag() const { return current_tag_; }
void set_current_tag(const UserTag& tag);
- RawUserTag* default_tag() const { return default_tag_; }
+ UserTagPtr default_tag() const { return default_tag_; }
void set_default_tag(const UserTag& tag);
void set_ic_miss_code(const Code& code);
- RawGrowableObjectArray* deoptimized_code_array() const {
+ GrowableObjectArrayPtr deoptimized_code_array() const {
return deoptimized_code_array_;
}
void set_deoptimized_code_array(const GrowableObjectArray& value);
void TrackDeoptimizedCode(const Code& code);
// Also sends a paused at exit event over the service protocol.
- void SetStickyError(RawError* sticky_error);
+ void SetStickyError(ErrorPtr sticky_error);
- RawError* sticky_error() const { return sticky_error_; }
- DART_WARN_UNUSED_RESULT RawError* StealStickyError();
+ ErrorPtr sticky_error() const { return sticky_error_; }
+ DART_WARN_UNUSED_RESULT ErrorPtr StealStickyError();
// In precompilation we finalize all regular classes before compiling.
bool all_classes_finalized() const {
@@ -1048,10 +1069,10 @@
// deoptimization in the mutator thread.
void AddDeoptimizingBoxedField(const Field& field);
// Returns Field::null() if none available in the list.
- RawField* GetDeoptimizingBoxedField();
+ FieldPtr GetDeoptimizingBoxedField();
#ifndef PRODUCT
- RawError* InvokePendingServiceExtensionCalls();
+ ErrorPtr InvokePendingServiceExtensionCalls();
void AppendServiceExtensionCall(const Instance& closure,
const String& method_name,
const Array& parameter_keys,
@@ -1060,7 +1081,7 @@
const Instance& id);
void RegisterServiceExtensionHandler(const String& name,
const Instance& closure);
- RawInstance* LookupServiceExtensionHandler(const String& name);
+ InstancePtr LookupServiceExtensionHandler(const String& name);
#endif
static void VisitIsolates(IsolateVisitor* visitor);
@@ -1071,10 +1092,10 @@
#endif
void AddClosureFunction(const Function& function) const;
- RawFunction* LookupClosureFunction(const Function& parent,
- TokenPosition token_pos) const;
+ FunctionPtr LookupClosureFunction(const Function& parent,
+ TokenPosition token_pos) const;
intptr_t FindClosureIndex(const Function& needle) const;
- RawFunction* ClosureFunctionFromIndex(intptr_t idx) const;
+ FunctionPtr ClosureFunctionFromIndex(intptr_t idx) const;
bool is_service_isolate() const {
return IsServiceIsolateBit::decode(isolate_flags_);
@@ -1119,17 +1140,6 @@
return group()->dispatch_table();
}
- // Returns the pc -> code lookup cache object for this isolate.
- ReversePcLookupCache* reverse_pc_lookup_cache() const {
- return reverse_pc_lookup_cache_;
- }
-
- // Sets the pc -> code lookup cache object for this isolate.
- void set_reverse_pc_lookup_cache(ReversePcLookupCache* table) {
- ASSERT(reverse_pc_lookup_cache_ == nullptr);
- reverse_pc_lookup_cache_ = table;
- }
-
// Isolate-specific flag handling.
static void FlagsInitialize(Dart_IsolateFlags* api_flags);
void FlagsCopyTo(Dart_IsolateFlags* api_flags) const;
@@ -1267,12 +1277,12 @@
void set_user_tag(uword tag) { user_tag_ = tag; }
#if !defined(PRODUCT)
- RawGrowableObjectArray* GetAndClearPendingServiceExtensionCalls();
- RawGrowableObjectArray* pending_service_extension_calls() const {
+ GrowableObjectArrayPtr GetAndClearPendingServiceExtensionCalls();
+ GrowableObjectArrayPtr pending_service_extension_calls() const {
return pending_service_extension_calls_;
}
void set_pending_service_extension_calls(const GrowableObjectArray& value);
- RawGrowableObjectArray* registered_service_extension_handlers() const {
+ GrowableObjectArrayPtr registered_service_extension_handlers() const {
return registered_service_extension_handlers_;
}
void set_registered_service_extension_handlers(
@@ -1298,14 +1308,14 @@
// We use only word-sized fields to avoid differences in struct packing on the
// different architectures. See also CheckOffsets in dart.cc.
uword user_tag_ = 0;
- RawUserTag* current_tag_;
- RawUserTag* default_tag_;
- RawCode* ic_miss_code_;
+ UserTagPtr current_tag_;
+ UserTagPtr default_tag_;
+ CodePtr ic_miss_code_;
// Cached value of object_store_shared_ptr_, here for generated code access
ObjectStore* cached_object_store_ = nullptr;
SharedClassTable* shared_class_table_ = nullptr;
// Cached value of class_table_->table_, here for generated code access
- RawClass** cached_class_table_table_ = nullptr;
+ ClassPtr* cached_class_table_table_ = nullptr;
FieldTable* field_table_ = nullptr;
bool single_step_ = false;
// End accessed from generated code.
@@ -1374,12 +1384,12 @@
enum {kPendingHandlerIndex = 0, kPendingMethodNameIndex, kPendingKeysIndex,
kPendingValuesIndex, kPendingReplyPortIndex, kPendingIdIndex,
kPendingEntrySize};
- RawGrowableObjectArray* pending_service_extension_calls_;
+ GrowableObjectArrayPtr pending_service_extension_calls_;
// We use 2 list entries for each registered extension handler.
enum {kRegisteredNameIndex = 0, kRegisteredHandlerIndex,
kRegisteredEntrySize};
- RawGrowableObjectArray* registered_service_extension_handlers_;
+ GrowableObjectArrayPtr registered_service_extension_handlers_;
// Used to wake the isolate when it is in the pause event loop.
Monitor* pause_loop_monitor_ = nullptr;
@@ -1428,16 +1438,19 @@
MallocGrowableArray<PendingLazyDeopt>* pending_deopts_;
DeoptContext* deopt_context_ = nullptr;
- RawGrowableObjectArray* tag_table_;
+ GrowableObjectArrayPtr tag_table_;
- RawGrowableObjectArray* deoptimized_code_array_;
+ GrowableObjectArrayPtr deoptimized_code_array_;
- RawError* sticky_error_;
+ ErrorPtr sticky_error_;
+
+ std::unique_ptr<Bequest> bequest_;
+ Dart_Port beneficiary_ = 0;
// Protect access to boxed_field_list_.
Mutex field_list_mutex_;
// List of fields that became boxed and that trigger deoptimization.
- RawGrowableObjectArray* boxed_field_list_;
+ GrowableObjectArrayPtr boxed_field_list_;
// This guards spawn_count_. An isolate cannot complete shutdown and be
// destroyed while there are child isolates in the midst of a spawn.
@@ -1451,7 +1464,6 @@
const char** obfuscation_map_ = nullptr;
DispatchTable* dispatch_table_ = nullptr;
- ReversePcLookupCache* reverse_pc_lookup_cache_ = nullptr;
// Used during message sending of messages between isolates.
std::unique_ptr<WeakTable> forward_table_new_;
@@ -1595,9 +1607,9 @@
bool errors_are_fatal() const { return errors_are_fatal_; }
Dart_IsolateFlags* isolate_flags() { return &isolate_flags_; }
- RawObject* ResolveFunction();
- RawInstance* BuildArgs(Thread* thread);
- RawInstance* BuildMessage(Thread* thread);
+ ObjectPtr ResolveFunction();
+ InstancePtr BuildArgs(Thread* thread);
+ InstancePtr BuildMessage(Thread* thread);
IsolateGroup* isolate_group() const { return isolate_group_; }
diff --git a/runtime/vm/isolate_reload.cc b/runtime/vm/isolate_reload.cc
index 1c936d4..faaa2ac 100644
--- a/runtime/vm/isolate_reload.cc
+++ b/runtime/vm/isolate_reload.cc
@@ -72,7 +72,7 @@
explicit ObjectLocator(IsolateGroupReloadContext* context)
: context_(context), count_(0) {}
- void VisitObject(RawObject* obj) {
+ void VisitObject(ObjectPtr obj) {
InstanceMorpher* morpher =
context_->instance_morpher_by_cid_.LookupValue(obj->GetClassId());
if (morpher != NULL) {
@@ -186,13 +186,13 @@
before_(zone, 16),
after_(zone, 16) {}
-void InstanceMorpher::AddObject(RawObject* object) {
+void InstanceMorpher::AddObject(ObjectPtr object) {
ASSERT(object->GetClassId() == cid_);
const Instance& instance = Instance::Cast(Object::Handle(Z, object));
before_.Add(&instance);
}
-RawInstance* InstanceMorpher::Morph(const Instance& instance) const {
+InstancePtr InstanceMorpher::Morph(const Instance& instance) const {
// Code can reference constants / canonical objects either directly in the
// instruction stream (ia32) or via an object pool.
//
@@ -281,13 +281,13 @@
context->ReportError(error);
}
-RawError* ReasonForCancelling::ToError() {
+ErrorPtr ReasonForCancelling::ToError() {
// By default create the error returned from ToString.
const String& message = String::Handle(ToString());
return LanguageError::New(message);
}
-RawString* ReasonForCancelling::ToString() {
+StringPtr ReasonForCancelling::ToString() {
UNREACHABLE();
return NULL;
}
@@ -314,7 +314,7 @@
jsobj.AddProperty("message", message.ToCString());
}
-RawError* IsolateGroupReloadContext::error() const {
+ErrorPtr IsolateGroupReloadContext::error() const {
ASSERT(!reasons_to_cancel_reload_.is_empty());
// Report the first error to the surroundings.
return reasons_to_cancel_reload_.At(0)->ToError();
@@ -350,7 +350,7 @@
static uword Hash(const Object& obj) {
uword class_name_hash = String::HashRawSymbol(Class::Cast(obj).Name());
- RawLibrary* raw_library = Class::Cast(obj).library();
+ LibraryPtr raw_library = Class::Cast(obj).library();
if (raw_library == Library::null()) {
return class_name_hash;
}
@@ -516,8 +516,8 @@
private:
const Error& error_;
- RawError* ToError() { return error_.raw(); }
- RawString* ToString() {
+ ErrorPtr ToError() { return error_.raw(); }
+ StringPtr ToString() {
return String::NewFormatted("%s", error_.ToErrorCString());
}
};
@@ -1040,7 +1040,7 @@
}
}
-RawObject* IsolateReloadContext::ReloadPhase2LoadKernel(
+ObjectPtr IsolateReloadContext::ReloadPhase2LoadKernel(
kernel::Program* program,
const String& root_lib_url) {
Thread* thread = Thread::Current();
@@ -1235,7 +1235,7 @@
// Copy the class table for isolate.
ClassTable* class_table = I->class_table();
- RawClass** saved_class_table = nullptr;
+ ClassPtr* saved_class_table = nullptr;
class_table->CopyBeforeHotReload(&saved_class_table, &saved_num_cids_);
// Copy classes into saved_class_table_ first. Make sure there are no
@@ -1768,8 +1768,8 @@
}
}
-RawClass* IsolateReloadContext::GetClassForHeapWalkAt(intptr_t cid) {
- RawClass** class_table = saved_class_table_.load(std::memory_order_acquire);
+ClassPtr IsolateReloadContext::GetClassForHeapWalkAt(intptr_t cid) {
+ ClassPtr* class_table = saved_class_table_.load(std::memory_order_acquire);
if (class_table != NULL) {
ASSERT(cid > 0);
ASSERT(cid < saved_num_cids_);
@@ -1791,7 +1791,7 @@
}
void IsolateReloadContext::DiscardSavedClassTable(bool is_rollback) {
- RawClass** local_saved_class_table =
+ ClassPtr* local_saved_class_table =
saved_class_table_.load(std::memory_order_relaxed);
I->class_table()->ResetAfterHotReload(local_saved_class_table,
saved_num_cids_, is_rollback);
@@ -1813,10 +1813,10 @@
void IsolateReloadContext::VisitObjectPointers(ObjectPointerVisitor* visitor) {
visitor->VisitPointers(from(), to());
- RawClass** saved_class_table =
+ ClassPtr* saved_class_table =
saved_class_table_.load(std::memory_order_relaxed);
if (saved_class_table != NULL) {
- auto class_table = reinterpret_cast<RawObject**>(&(saved_class_table[0]));
+ auto class_table = reinterpret_cast<ObjectPtr*>(&(saved_class_table[0]));
visitor->VisitPointers(class_table, saved_num_cids_);
}
}
@@ -1883,22 +1883,22 @@
instances_(instances) {}
virtual ~InvalidationCollector() {}
- void VisitObject(RawObject* obj) {
+ void VisitObject(ObjectPtr obj) {
intptr_t cid = obj->GetClassId();
if (cid == kFunctionCid) {
const Function& func =
- Function::Handle(zone_, static_cast<RawFunction*>(obj));
+ Function::Handle(zone_, static_cast<FunctionPtr>(obj));
if (!func.ForceOptimize()) {
// Force-optimized functions cannot deoptimize.
functions_->Add(&func);
}
} else if (cid == kKernelProgramInfoCid) {
kernel_infos_->Add(&KernelProgramInfo::Handle(
- zone_, static_cast<RawKernelProgramInfo*>(obj)));
+ zone_, static_cast<KernelProgramInfoPtr>(obj)));
} else if (cid == kFieldCid) {
- fields_->Add(&Field::Handle(zone_, static_cast<RawField*>(obj)));
+ fields_->Add(&Field::Handle(zone_, static_cast<FieldPtr>(obj)));
} else if (cid > kNumPredefinedCids) {
- instances_->Add(&Instance::Handle(zone_, static_cast<RawInstance*>(obj)));
+ instances_->Add(&Instance::Handle(zone_, static_cast<InstancePtr>(obj)));
}
}
@@ -2254,8 +2254,7 @@
RunInvalidationVisitors();
}
-RawClass* IsolateReloadContext::OldClassOrNull(
- const Class& replacement_or_new) {
+ClassPtr IsolateReloadContext::OldClassOrNull(const Class& replacement_or_new) {
UnorderedHashSet<ClassMapTraits> old_classes_set(old_classes_set_storage_);
Class& cls = Class::Handle();
cls ^= old_classes_set.GetOrNull(replacement_or_new);
@@ -2263,7 +2262,7 @@
return cls.raw();
}
-RawString* IsolateReloadContext::FindLibraryPrivateKey(
+StringPtr IsolateReloadContext::FindLibraryPrivateKey(
const Library& replacement_or_new) {
const Library& old = Library::Handle(OldLibraryOrNull(replacement_or_new));
if (old.IsNull()) {
@@ -2277,7 +2276,7 @@
return old.private_key();
}
-RawLibrary* IsolateReloadContext::OldLibraryOrNull(
+LibraryPtr IsolateReloadContext::OldLibraryOrNull(
const Library& replacement_or_new) {
UnorderedHashSet<LibraryMapTraits> old_libraries_set(
old_libraries_set_storage_);
@@ -2295,7 +2294,7 @@
// Attempt to find the pair to |replacement_or_new| with the knowledge that
// the base url prefix has moved.
-RawLibrary* IsolateReloadContext::OldLibraryOrNullBaseMoved(
+LibraryPtr IsolateReloadContext::OldLibraryOrNullBaseMoved(
const Library& replacement_or_new) {
const String& url_prefix =
String::Handle(group_reload_context_->root_url_prefix_);
diff --git a/runtime/vm/isolate_reload.h b/runtime/vm/isolate_reload.h
index 5bcf2a3..492b5bf 100644
--- a/runtime/vm/isolate_reload.h
+++ b/runtime/vm/isolate_reload.h
@@ -48,11 +48,6 @@
class ObjectLocator;
class ObjectPointerVisitor;
class ObjectStore;
-class RawError;
-class RawGrowableObjectArray;
-class RawLibrary;
-class RawObject;
-class RawString;
class Script;
class UpdateClassesVisitor;
@@ -74,10 +69,10 @@
virtual ~InstanceMorpher() {}
// Called on each instance that needs to be morphed.
- RawInstance* Morph(const Instance& instance) const;
+ InstancePtr Morph(const Instance& instance) const;
// Adds an object to be morphed.
- void AddObject(RawObject* object);
+ void AddObject(ObjectPtr object);
// Create the morphed objects based on the before() list.
void CreateMorphedCopies();
@@ -118,11 +113,11 @@
// Conversion to a VM error object.
// Default implementation calls ToString.
- virtual RawError* ToError();
+ virtual ErrorPtr ToError();
// Conversion to a string object.
// Default implementation calls ToError.
- virtual RawString* ToString();
+ virtual StringPtr ToString();
// Append the reason to JSON array.
virtual void AppendTo(JSONArray* array);
@@ -165,7 +160,7 @@
IsolateGroup* isolate_group() const { return isolate_group_; }
bool reload_aborted() const { return HasReasonsForCancelling(); }
bool reload_skipped() const { return reload_skipped_; }
- RawError* error() const;
+ ErrorPtr error() const;
int64_t start_time_micros() const { return start_time_micros_; }
int64_t reload_timestamp() const { return reload_timestamp_; }
@@ -278,13 +273,11 @@
BitVector* modified_libs_ = nullptr;
String& root_lib_url_;
- RawObject** from() {
- return reinterpret_cast<RawObject**>(&root_url_prefix_);
- }
- RawString* root_url_prefix_;
- RawString* old_root_url_prefix_;
- RawObject** to() {
- return reinterpret_cast<RawObject**>(&old_root_url_prefix_);
+ ObjectPtr* from() { return reinterpret_cast<ObjectPtr*>(&root_url_prefix_); }
+ StringPtr root_url_prefix_;
+ StringPtr old_root_url_prefix_;
+ ObjectPtr* to() {
+ return reinterpret_cast<ObjectPtr*>(&old_root_url_prefix_);
}
friend class Isolate;
@@ -295,7 +288,7 @@
friend class ReasonForCancelling;
friend class IsolateReloadContext;
friend class IsolateGroup; // GetClassSizeForHeapWalkAt
- friend class RawObject; // GetClassSizeForHeapWalkAt
+ friend class ObjectLayout; // GetClassSizeForHeapWalkAt
static Dart_FileModifiedCallback file_modified_callback_;
};
@@ -321,14 +314,14 @@
bool IsDirty(const Library& lib);
// Prefers old classes when we are in the middle of a reload.
- RawClass* GetClassForHeapWalkAt(intptr_t cid);
+ ClassPtr GetClassForHeapWalkAt(intptr_t cid);
void DiscardSavedClassTable(bool is_rollback);
void RegisterClass(const Class& new_cls);
// Finds the library private key for |replacement_or_new| or return null
// if |replacement_or_new| is new.
- RawString* FindLibraryPrivateKey(const Library& replacement_or_new);
+ StringPtr FindLibraryPrivateKey(const Library& replacement_or_new);
void VisitObjectPointers(ObjectPointerVisitor* visitor);
@@ -340,8 +333,8 @@
void ReloadPhase1AllocateStorageMapsAndCheckpoint();
void CheckpointClasses();
- RawObject* ReloadPhase2LoadKernel(kernel::Program* program,
- const String& root_lib_url);
+ ObjectPtr ReloadPhase2LoadKernel(kernel::Program* program,
+ const String& root_lib_url);
void ReloadPhase3FinalizeLoading();
void ReloadPhase4CommitPrepare();
void ReloadPhase4CommitFinish();
@@ -382,12 +375,12 @@
std::shared_ptr<IsolateGroupReloadContext> group_reload_context_;
Isolate* isolate_;
intptr_t saved_num_cids_ = -1;
- std::atomic<RawClass**> saved_class_table_;
+ std::atomic<ClassPtr*> saved_class_table_;
MallocGrowableArray<LibraryInfo> library_infos_;
- RawClass* OldClassOrNull(const Class& replacement_or_new);
- RawLibrary* OldLibraryOrNull(const Library& replacement_or_new);
- RawLibrary* OldLibraryOrNullBaseMoved(const Library& replacement_or_new);
+ ClassPtr OldClassOrNull(const Class& replacement_or_new);
+ LibraryPtr OldLibraryOrNull(const Library& replacement_or_new);
+ LibraryPtr OldLibraryOrNullBaseMoved(const Library& replacement_or_new);
void BuildLibraryMapping();
void BuildRemovedClassesSet();
@@ -401,19 +394,19 @@
void AddEnumBecomeMapping(const Object& old, const Object& neu);
void RebuildDirectSubclasses();
- RawObject** from() {
- return reinterpret_cast<RawObject**>(&old_classes_set_storage_);
+ ObjectPtr* from() {
+ return reinterpret_cast<ObjectPtr*>(&old_classes_set_storage_);
}
- RawArray* old_classes_set_storage_;
- RawArray* class_map_storage_;
- RawArray* removed_class_set_storage_;
- RawArray* old_libraries_set_storage_;
- RawArray* library_map_storage_;
- RawArray* become_map_storage_;
- RawGrowableObjectArray* become_enum_mappings_;
- RawLibrary* saved_root_library_;
- RawGrowableObjectArray* saved_libraries_;
- RawObject** to() { return reinterpret_cast<RawObject**>(&saved_libraries_); }
+ ArrayPtr old_classes_set_storage_;
+ ArrayPtr class_map_storage_;
+ ArrayPtr removed_class_set_storage_;
+ ArrayPtr old_libraries_set_storage_;
+ ArrayPtr library_map_storage_;
+ ArrayPtr become_map_storage_;
+ GrowableObjectArrayPtr become_enum_mappings_;
+ LibraryPtr saved_root_library_;
+ GrowableObjectArrayPtr saved_libraries_;
+ ObjectPtr* to() { return reinterpret_cast<ObjectPtr*>(&saved_libraries_); }
friend class Isolate;
friend class Class; // AddStaticFieldMapping, AddEnumBecomeMapping.
diff --git a/runtime/vm/isolate_reload_test.cc b/runtime/vm/isolate_reload_test.cc
index ed39f1a..5f16ca6 100644
--- a/runtime/vm/isolate_reload_test.cc
+++ b/runtime/vm/isolate_reload_test.cc
@@ -4002,7 +4002,7 @@
}
virtual ~FindNoInstancesOfClass() {}
- virtual bool FindObject(RawObject* obj) const {
+ virtual bool FindObject(ObjectPtr obj) const {
return obj->GetClassId() == cid_;
}
@@ -4516,7 +4516,7 @@
lib = TestCase::ReloadTestScript(kReloadScript);
EXPECT_VALID(lib);
EXPECT_ERROR(SimpleInvokeError(lib, "main"),
- "Unimplemented handling of static target arity change");
+ "Static call with invalid arguments");
}
#endif // !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME)
diff --git a/runtime/vm/json_stream.cc b/runtime/vm/json_stream.cc
index 07035fe..bae68b3 100644
--- a/runtime/vm/json_stream.cc
+++ b/runtime/vm/json_stream.cc
@@ -453,17 +453,17 @@
return parameter_keys_->Length();
}
-RawObject* JSONStream::GetObjectParameterKey(intptr_t i) const {
+ObjectPtr JSONStream::GetObjectParameterKey(intptr_t i) const {
ASSERT((i >= 0) && (i < NumObjectParameters()));
return parameter_keys_->At(i);
}
-RawObject* JSONStream::GetObjectParameterValue(intptr_t i) const {
+ObjectPtr JSONStream::GetObjectParameterValue(intptr_t i) const {
ASSERT((i >= 0) && (i < NumObjectParameters()));
return parameter_values_->At(i);
}
-RawObject* JSONStream::LookupObjectParam(const char* c_key) const {
+ObjectPtr JSONStream::LookupObjectParam(const char* c_key) const {
const String& key = String::Handle(String::New(c_key));
Object& test = Object::Handle();
const intptr_t num_object_parameters = NumObjectParameters();
diff --git a/runtime/vm/json_stream.h b/runtime/vm/json_stream.h
index f0ee450..89907d4d 100644
--- a/runtime/vm/json_stream.h
+++ b/runtime/vm/json_stream.h
@@ -108,9 +108,9 @@
Dart_Port reply_port() const { return reply_port_; }
intptr_t NumObjectParameters() const;
- RawObject* GetObjectParameterKey(intptr_t i) const;
- RawObject* GetObjectParameterValue(intptr_t i) const;
- RawObject* LookupObjectParam(const char* key) const;
+ ObjectPtr GetObjectParameterKey(intptr_t i) const;
+ ObjectPtr GetObjectParameterValue(intptr_t i) const;
+ ObjectPtr LookupObjectParam(const char* key) const;
intptr_t num_params() const { return num_params_; }
const char* GetParamKey(intptr_t i) const { return param_keys_[i]; }
diff --git a/runtime/vm/kernel.cc b/runtime/vm/kernel.cc
index 5e69eac..1b98d07 100644
--- a/runtime/vm/kernel.cc
+++ b/runtime/vm/kernel.cc
@@ -205,7 +205,7 @@
* possibly contain duplicate and unsorted data at the end.
* Otherwise (when sublist doesn't exist in list) return new empty array.
*/
-static RawArray* AsSortedDuplicateFreeArray(GrowableArray<intptr_t>* source) {
+static ArrayPtr AsSortedDuplicateFreeArray(GrowableArray<intptr_t>* source) {
intptr_t size = source->length();
if (size == 0) {
return Object::empty_array().raw();
@@ -300,7 +300,7 @@
object = pool.ObjectAt(i);
if (object.IsFunction()) {
closure ^= object.raw();
- if (closure.kind() == RawFunction::kClosureFunction &&
+ if (closure.kind() == FunctionLayout::kClosureFunction &&
closure.IsLocalFunction()) {
CollectTokenPosition(closure.token_pos(), token_positions);
CollectTokenPosition(closure.end_token_pos(), token_positions);
@@ -492,8 +492,8 @@
data_program_offset),
constant_reader_(this, active_class) {}
- RawObject* EvaluateMetadata(intptr_t kernel_offset,
- bool is_annotations_offset) {
+ ObjectPtr EvaluateMetadata(intptr_t kernel_offset,
+ bool is_annotations_offset) {
SetOffset(kernel_offset);
// Library and LibraryDependency objects do not have a tag in kernel binary.
@@ -528,8 +528,8 @@
DISALLOW_COPY_AND_ASSIGN(MetadataEvaluator);
};
-RawObject* EvaluateMetadata(const Field& metadata_field,
- bool is_annotations_offset) {
+ObjectPtr EvaluateMetadata(const Field& metadata_field,
+ bool is_annotations_offset) {
LongJumpScope jump;
if (setjmp(*jump.Set()) == 0) {
Thread* thread = Thread::Current();
@@ -570,7 +570,7 @@
data_program_offset),
constant_reader_(this, active_class) {}
- RawObject* BuildParameterDescriptor(const Function& function);
+ ObjectPtr BuildParameterDescriptor(const Function& function);
private:
ConstantReader constant_reader_;
@@ -578,7 +578,7 @@
DISALLOW_COPY_AND_ASSIGN(ParameterDescriptorBuilder);
};
-RawObject* ParameterDescriptorBuilder::BuildParameterDescriptor(
+ObjectPtr ParameterDescriptorBuilder::BuildParameterDescriptor(
const Function& function) {
SetOffset(function.kernel_offset());
ReadUntilFunctionNode();
@@ -638,7 +638,7 @@
return param_descriptor.raw();
}
-RawObject* BuildParameterDescriptor(const Function& function) {
+ObjectPtr BuildParameterDescriptor(const Function& function) {
LongJumpScope jump;
if (setjmp(*jump.Set()) == 0) {
Thread* thread = Thread::Current();
diff --git a/runtime/vm/kernel.h b/runtime/vm/kernel.h
index ca2f6e2..a0edfe7 100644
--- a/runtime/vm/kernel.h
+++ b/runtime/vm/kernel.h
@@ -203,9 +203,9 @@
void CollectTokenPositionsFor(const Script& script);
-RawObject* EvaluateMetadata(const Field& metadata_field,
- bool is_annotations_offset);
-RawObject* BuildParameterDescriptor(const Function& function);
+ObjectPtr EvaluateMetadata(const Field& metadata_field,
+ bool is_annotations_offset);
+ObjectPtr BuildParameterDescriptor(const Function& function);
// Fills in [is_covariant] and [is_generic_covariant_impl] vectors
// according to covariance attributes of [function] parameters.
@@ -225,7 +225,7 @@
// Returns a list of ParameterTypeChecks needed by a dynamic invocation
// forwarder that targets [function]. Indices in these checks correspond to
// bytecode frame indices.
-RawArray* CollectDynamicInvocationChecks(const Function& function);
+ArrayPtr CollectDynamicInvocationChecks(const Function& function);
ProcedureAttributesMetadata ProcedureAttributesOf(const Function& function,
Zone* zone);
diff --git a/runtime/vm/kernel_binary.cc b/runtime/vm/kernel_binary.cc
index 3d5a2c3..de75ae3 100644
--- a/runtime/vm/kernel_binary.cc
+++ b/runtime/vm/kernel_binary.cc
@@ -31,7 +31,7 @@
return "Unknown";
}
-RawTypedData* Reader::ReadLineStartsData(intptr_t line_start_count) {
+TypedDataPtr Reader::ReadLineStartsData(intptr_t line_start_count) {
TypedData& line_starts_data = TypedData::Handle(
TypedData::New(kTypedDataInt8ArrayCid, line_start_count, Heap::kOld));
diff --git a/runtime/vm/kernel_binary.h b/runtime/vm/kernel_binary.h
index 4ceb1c7..af2d8ba 100644
--- a/runtime/vm/kernel_binary.h
+++ b/runtime/vm/kernel_binary.h
@@ -415,7 +415,7 @@
const uint8_t* raw_buffer() const { return raw_buffer_; }
void set_raw_buffer(const uint8_t* raw_buffer) { raw_buffer_ = raw_buffer; }
- RawExternalTypedData* ExternalDataFromTo(intptr_t start, intptr_t end) {
+ ExternalTypedDataPtr ExternalDataFromTo(intptr_t start, intptr_t end) {
return ExternalTypedData::New(kExternalTypedDataUint8ArrayCid,
const_cast<uint8_t*>(buffer() + start),
end - start, Heap::kOld);
@@ -426,7 +426,7 @@
return &buffer()[offset];
}
- RawTypedData* ReadLineStartsData(intptr_t line_start_count);
+ TypedDataPtr ReadLineStartsData(intptr_t line_start_count);
private:
const uint8_t* buffer() const {
diff --git a/runtime/vm/kernel_loader.cc b/runtime/vm/kernel_loader.cc
index b4fea2c..7bfd7d7 100644
--- a/runtime/vm/kernel_loader.cc
+++ b/runtime/vm/kernel_loader.cc
@@ -115,7 +115,7 @@
DISALLOW_COPY_AND_ASSIGN(SimpleExpressionConverter);
};
-RawArray* KernelLoader::MakeFieldsArray() {
+ArrayPtr KernelLoader::MakeFieldsArray() {
const intptr_t len = fields_.length();
const Array& res = Array::Handle(zone_, Array::New(len, Heap::kOld));
for (intptr_t i = 0; i < len; i++) {
@@ -124,7 +124,7 @@
return res.raw();
}
-RawArray* KernelLoader::MakeFunctionsArray() {
+ArrayPtr KernelLoader::MakeFunctionsArray() {
const intptr_t len = functions_.length();
const Array& res = Array::Handle(zone_, Array::New(len, Heap::kOld));
for (intptr_t i = 0; i < len; i++) {
@@ -133,12 +133,12 @@
return res.raw();
}
-RawLibrary* BuildingTranslationHelper::LookupLibraryByKernelLibrary(
+LibraryPtr BuildingTranslationHelper::LookupLibraryByKernelLibrary(
NameIndex library) {
return loader_->LookupLibrary(library);
}
-RawClass* BuildingTranslationHelper::LookupClassByKernelClass(NameIndex klass) {
+ClassPtr BuildingTranslationHelper::LookupClassByKernelClass(NameIndex klass) {
#if defined(DEBUG)
LibraryLookupHandleScope library_lookup_handle_scope(library_lookup_handle_);
#endif // defined(DEBUG)
@@ -337,9 +337,9 @@
subprogram_file_starts->Reverse();
}
-RawString* KernelLoader::FindSourceForScript(const uint8_t* kernel_buffer,
- intptr_t kernel_buffer_length,
- const String& uri) {
+StringPtr KernelLoader::FindSourceForScript(const uint8_t* kernel_buffer,
+ intptr_t kernel_buffer_length,
+ const String& uri) {
Thread* thread = Thread::Current();
Zone* zone = thread->zone();
TranslationHelper translation_helper(thread);
@@ -566,7 +566,7 @@
kernel_program_info_.set_potential_natives(potential_natives_);
}
-RawString* KernelLoader::DetectExternalNameCtor() {
+StringPtr KernelLoader::DetectExternalNameCtor() {
helper_.ReadTag();
helper_.ReadPosition();
NameIndex annotation_class = H.EnclosingName(
@@ -721,7 +721,7 @@
#endif
}
-RawObject* KernelLoader::LoadProgram(bool process_pending_classes) {
+ObjectPtr KernelLoader::LoadProgram(bool process_pending_classes) {
ASSERT(kernel_program_info_.constants() == Array::null());
if (!program_->is_single_program()) {
@@ -793,7 +793,7 @@
}
}
-RawObject* KernelLoader::LoadExpressionEvaluationFunction(
+ObjectPtr KernelLoader::LoadExpressionEvaluationFunction(
const String& library_url,
const String& klass) {
// Find the original context, i.e. library/class, in which the evaluation will
@@ -986,7 +986,7 @@
field.set_has_nontrivial_initializer(false);
}
-RawLibrary* KernelLoader::LoadLibrary(intptr_t index) {
+LibraryPtr KernelLoader::LoadLibrary(intptr_t index) {
if (!program_->is_single_program()) {
FATAL(
"Trying to load a concatenated dill file at a time where that is "
@@ -1675,7 +1675,7 @@
}
Function& function = Function::ZoneHandle(
- Z, Function::New(name, RawFunction::kConstructor,
+ Z, Function::New(name, FunctionLayout::kConstructor,
false, // is_static
constructor_helper.IsConst(),
false, // is_abstract
@@ -1939,7 +1939,7 @@
procedure_helper.SetJustRead(ProcedureHelper::kAnnotations);
const Object& script_class =
ClassForScriptAt(owner, procedure_helper.source_uri_index_);
- RawFunction::Kind kind = GetFunctionType(procedure_helper.kind_);
+ FunctionLayout::Kind kind = GetFunctionType(procedure_helper.kind_);
// We do not register expression evaluation libraries with the VM:
// The expression evaluation functions should be GC-able as soon as
@@ -2006,19 +2006,19 @@
switch (function_node_helper.dart_async_marker_) {
case FunctionNodeHelper::kSyncStar:
- function.set_modifier(RawFunction::kSyncGen);
+ function.set_modifier(FunctionLayout::kSyncGen);
function.set_is_visible(!FLAG_causal_async_stacks &&
!FLAG_lazy_async_stacks);
break;
case FunctionNodeHelper::kAsync:
- function.set_modifier(RawFunction::kAsync);
+ function.set_modifier(FunctionLayout::kAsync);
function.set_is_inlinable(!FLAG_causal_async_stacks &&
!FLAG_lazy_async_stacks);
function.set_is_visible(!FLAG_causal_async_stacks &&
!FLAG_lazy_async_stacks);
break;
case FunctionNodeHelper::kAsyncStar:
- function.set_modifier(RawFunction::kAsyncGen);
+ function.set_modifier(FunctionLayout::kAsyncGen);
function.set_is_inlinable(!FLAG_causal_async_stacks &&
!FLAG_lazy_async_stacks);
function.set_is_visible(!FLAG_causal_async_stacks &&
@@ -2088,8 +2088,8 @@
return klass;
}
-RawScript* KernelLoader::LoadScriptAt(intptr_t index,
- UriToSourceTable* uri_to_source_table) {
+ScriptPtr KernelLoader::LoadScriptAt(intptr_t index,
+ UriToSourceTable* uri_to_source_table) {
const String& uri_string = helper_.SourceTableUriFor(index);
const String& import_uri_string =
helper_.SourceTableImportUriFor(index, program_->binary_version());
@@ -2189,8 +2189,8 @@
Z,
Function::New(
getter_name,
- field_helper->IsStatic() ? RawFunction::kImplicitStaticGetter
- : RawFunction::kImplicitGetter,
+ field_helper->IsStatic() ? FunctionLayout::kImplicitStaticGetter
+ : FunctionLayout::kImplicitGetter,
field_helper->IsStatic(),
// The functions created by the parser have is_const for static fields
// that are const (not just final) and they have is_const for
@@ -2216,7 +2216,7 @@
ASSERT(!field_helper->IsConst());
const String& setter_name = H.DartSetterName(field_helper->canonical_name_);
Function& setter = Function::ZoneHandle(
- Z, Function::New(setter_name, RawFunction::kImplicitSetter,
+ Z, Function::New(setter_name, FunctionLayout::kImplicitSetter,
field_helper->IsStatic(),
false, // is_const
false, // is_abstract
@@ -2234,8 +2234,8 @@
}
}
-RawLibrary* KernelLoader::LookupLibraryOrNull(NameIndex library) {
- RawLibrary* result;
+LibraryPtr KernelLoader::LookupLibraryOrNull(NameIndex library) {
+ LibraryPtr result;
name_index_handle_ = Smi::New(library);
{
result = kernel_program_info_.LookupLibrary(thread_, name_index_handle_);
@@ -2258,10 +2258,10 @@
handle);
}
-RawLibrary* KernelLoader::LookupLibrary(NameIndex library) {
+LibraryPtr KernelLoader::LookupLibrary(NameIndex library) {
name_index_handle_ = Smi::New(library);
{
- RawLibrary* result =
+ LibraryPtr result =
kernel_program_info_.LookupLibrary(thread_, name_index_handle_);
NoSafepointScope no_safepoint_scope(thread_);
if (result != Library::null()) {
@@ -2292,14 +2292,14 @@
handle);
}
-RawLibrary* KernelLoader::LookupLibraryFromClass(NameIndex klass) {
+LibraryPtr KernelLoader::LookupLibraryFromClass(NameIndex klass) {
return LookupLibrary(H.CanonicalNameParent(klass));
}
-RawClass* KernelLoader::LookupClass(const Library& library, NameIndex klass) {
+ClassPtr KernelLoader::LookupClass(const Library& library, NameIndex klass) {
name_index_handle_ = Smi::New(klass);
{
- RawClass* raw_class =
+ ClassPtr raw_class =
kernel_program_info_.LookupClass(thread_, name_index_handle_);
NoSafepointScope no_safepoint_scope(thread_);
if (raw_class != Class::null()) {
@@ -2331,23 +2331,23 @@
return handle.raw();
}
-RawFunction::Kind KernelLoader::GetFunctionType(
+FunctionLayout::Kind KernelLoader::GetFunctionType(
ProcedureHelper::Kind procedure_kind) {
intptr_t lookuptable[] = {
- RawFunction::kRegularFunction, // Procedure::kMethod
- RawFunction::kGetterFunction, // Procedure::kGetter
- RawFunction::kSetterFunction, // Procedure::kSetter
- RawFunction::kRegularFunction, // Procedure::kOperator
- RawFunction::kConstructor, // Procedure::kFactory
+ FunctionLayout::kRegularFunction, // Procedure::kMethod
+ FunctionLayout::kGetterFunction, // Procedure::kGetter
+ FunctionLayout::kSetterFunction, // Procedure::kSetter
+ FunctionLayout::kRegularFunction, // Procedure::kOperator
+ FunctionLayout::kConstructor, // Procedure::kFactory
};
intptr_t kind = static_cast<int>(procedure_kind);
ASSERT(0 <= kind && kind <= ProcedureHelper::kFactory);
- return static_cast<RawFunction::Kind>(lookuptable[kind]);
+ return static_cast<FunctionLayout::Kind>(lookuptable[kind]);
}
-RawFunction* CreateFieldInitializerFunction(Thread* thread,
- Zone* zone,
- const Field& field) {
+FunctionPtr CreateFieldInitializerFunction(Thread* thread,
+ Zone* zone,
+ const Field& field) {
ASSERT(field.InitializerFunction() == Function::null());
String& init_name = String::Handle(zone, field.name());
@@ -2372,7 +2372,7 @@
// Create a static initializer.
const Function& initializer_fun = Function::Handle(
- zone, Function::New(init_name, RawFunction::kFieldInitializer,
+ zone, Function::New(init_name, FunctionLayout::kFieldInitializer,
field.is_static(), // is_static
false, // is_const
false, // is_abstract
diff --git a/runtime/vm/kernel_loader.h b/runtime/vm/kernel_loader.h
index 3298101..8e79898 100644
--- a/runtime/vm/kernel_loader.h
+++ b/runtime/vm/kernel_loader.h
@@ -31,8 +31,8 @@
library_lookup_handle_(Library::Handle(thread->zone())) {}
virtual ~BuildingTranslationHelper() {}
- virtual RawLibrary* LookupLibraryByKernelLibrary(NameIndex library);
- virtual RawClass* LookupClassByKernelClass(NameIndex klass);
+ virtual LibraryPtr LookupLibraryByKernelLibrary(NameIndex library);
+ virtual ClassPtr LookupClassByKernelClass(NameIndex klass);
private:
KernelLoader* loader_;
@@ -188,15 +188,15 @@
// Returns the library containing the main procedure, null if there
// was no main procedure, or a failure object if there was an error.
- RawObject* LoadProgram(bool process_pending_classes = true);
+ ObjectPtr LoadProgram(bool process_pending_classes = true);
// Load given library.
void LoadLibrary(const Library& library);
// Returns the function which will evaluate the expression, or a failure
// object if there was an error.
- RawObject* LoadExpressionEvaluationFunction(const String& library_url,
- const String& klass);
+ ObjectPtr LoadExpressionEvaluationFunction(const String& library_url,
+ const String& klass);
// Finds all libraries that have been modified in this incremental
// version of the kernel program file.
@@ -212,9 +212,9 @@
intptr_t* p_num_classes,
intptr_t* p_num_procedures);
- static RawString* FindSourceForScript(const uint8_t* kernel_buffer,
- intptr_t kernel_buffer_length,
- const String& url);
+ static StringPtr FindSourceForScript(const uint8_t* kernel_buffer,
+ intptr_t kernel_buffer_length,
+ const String& url);
void FinishTopLevelClassLoading(const Class& toplevel_class,
const Library& library,
@@ -228,7 +228,7 @@
// Check for the presence of a (possibly const) constructor for the
// 'ExternalName' class. If found, returns the name parameter to the
// constructor.
- RawString* DetectExternalNameCtor();
+ StringPtr DetectExternalNameCtor();
// Check for the presence of a (possibly const) constructor for the 'pragma'
// class. Returns whether it was found (no details about the type of pragma).
@@ -255,7 +255,7 @@
void InitializeFields(
DirectChainedHashMap<UriToSourceTableTrait>* uri_to_source_table);
- RawLibrary* LoadLibrary(intptr_t index);
+ LibraryPtr LoadLibrary(intptr_t index);
const String& LibraryUri(intptr_t library_index) {
return translation_helper_.DartSymbolPlain(
@@ -316,10 +316,10 @@
bool in_class,
intptr_t procedure_end);
- RawArray* MakeFieldsArray();
- RawArray* MakeFunctionsArray();
+ ArrayPtr MakeFieldsArray();
+ ArrayPtr MakeFunctionsArray();
- RawScript* LoadScriptAt(
+ ScriptPtr LoadScriptAt(
intptr_t index,
DirectChainedHashMap<UriToSourceTableTrait>* uri_to_source_table);
@@ -327,7 +327,7 @@
// for klass whose script corresponds to the uri index.
// Otherwise return klass.
const Object& ClassForScriptAt(const Class& klass, intptr_t source_uri_index);
- RawScript* ScriptAt(intptr_t source_uri_index) {
+ ScriptPtr ScriptAt(intptr_t source_uri_index) {
return kernel_program_info_.ScriptAt(source_uri_index);
}
@@ -339,12 +339,12 @@
void LoadLibraryImportsAndExports(Library* library,
const Class& toplevel_class);
- RawLibrary* LookupLibraryOrNull(NameIndex library);
- RawLibrary* LookupLibrary(NameIndex library);
- RawLibrary* LookupLibraryFromClass(NameIndex klass);
- RawClass* LookupClass(const Library& library, NameIndex klass);
+ LibraryPtr LookupLibraryOrNull(NameIndex library);
+ LibraryPtr LookupLibrary(NameIndex library);
+ LibraryPtr LookupLibraryFromClass(NameIndex klass);
+ ClassPtr LookupClass(const Library& library, NameIndex klass);
- RawFunction::Kind GetFunctionType(ProcedureHelper::Kind procedure_kind);
+ FunctionLayout::Kind GetFunctionType(ProcedureHelper::Kind procedure_kind);
void EnsureExternalClassIsLookedUp() {
if (external_name_class_.IsNull()) {
@@ -456,9 +456,9 @@
DISALLOW_COPY_AND_ASSIGN(KernelLoader);
};
-RawFunction* CreateFieldInitializerFunction(Thread* thread,
- Zone* zone,
- const Field& field);
+FunctionPtr CreateFieldInitializerFunction(Thread* thread,
+ Zone* zone,
+ const Field& field);
} // namespace kernel
} // namespace dart
diff --git a/runtime/vm/megamorphic_cache_table.cc b/runtime/vm/megamorphic_cache_table.cc
index d0550ee3..439cccc 100644
--- a/runtime/vm/megamorphic_cache_table.cc
+++ b/runtime/vm/megamorphic_cache_table.cc
@@ -13,9 +13,9 @@
namespace dart {
-RawMegamorphicCache* MegamorphicCacheTable::Lookup(Thread* thread,
- const String& name,
- const Array& descriptor) {
+MegamorphicCachePtr MegamorphicCacheTable::Lookup(Thread* thread,
+ const String& name,
+ const Array& descriptor) {
Isolate* isolate = thread->isolate();
// Multiple compilation threads could access this lookup.
SafepointMutexLocker ml(isolate->megamorphic_mutex());
@@ -44,7 +44,7 @@
return cache.raw();
}
-RawFunction* MegamorphicCacheTable::miss_handler(Isolate* isolate) {
+FunctionPtr MegamorphicCacheTable::miss_handler(Isolate* isolate) {
ASSERT(isolate->object_store()->megamorphic_call_miss_function() !=
Function::null());
return isolate->object_store()->megamorphic_call_miss_function();
@@ -70,7 +70,7 @@
const Class& cls =
Class::Handle(Type::Handle(Type::DartFunctionType()).type_class());
const Function& function = Function::Handle(Function::New(
- Symbols::MegamorphicCallMiss(), RawFunction::kRegularFunction,
+ Symbols::MegamorphicCallMiss(), FunctionLayout::kRegularFunction,
true, // Static, but called as a method.
false, // Not const.
false, // Not abstract.
diff --git a/runtime/vm/megamorphic_cache_table.h b/runtime/vm/megamorphic_cache_table.h
index 6b68c6c..fb714a3 100644
--- a/runtime/vm/megamorphic_cache_table.h
+++ b/runtime/vm/megamorphic_cache_table.h
@@ -6,6 +6,7 @@
#define RUNTIME_VM_MEGAMORPHIC_CACHE_TABLE_H_
#include "vm/allocation.h"
+#include "vm/tagged_pointer.h"
namespace dart {
@@ -17,17 +18,12 @@
class Function;
class Isolate;
class ObjectPointerVisitor;
-class RawArray;
-class RawFunction;
-class RawCode;
-class RawMegamorphicCache;
-class RawString;
class String;
class Thread;
class MegamorphicCacheTable : public AllStatic {
public:
- static RawFunction* miss_handler(Isolate* isolate);
+ static FunctionPtr miss_handler(Isolate* isolate);
NOT_IN_PRECOMPILED(static void InitMissHandler(Isolate* isolate));
// Re-initializes the megamorphic miss handler function in the object store.
@@ -39,9 +35,9 @@
static void ReInitMissHandlerCode(Isolate* isolate,
compiler::ObjectPoolBuilder* wrapper));
- static RawMegamorphicCache* Lookup(Thread* thread,
- const String& name,
- const Array& descriptor);
+ static MegamorphicCachePtr Lookup(Thread* thread,
+ const String& name,
+ const Array& descriptor);
static void PrintSizes(Isolate* isolate);
};
diff --git a/runtime/vm/message.cc b/runtime/vm/message.cc
index 59c1917..b4d4c69 100644
--- a/runtime/vm/message.cc
+++ b/runtime/vm/message.cc
@@ -24,38 +24,57 @@
: next_(NULL),
dest_port_(dest_port),
delivery_failure_port_(delivery_failure_port),
- snapshot_(snapshot),
+ payload_(snapshot),
snapshot_length_(snapshot_length),
finalizable_data_(finalizable_data),
priority_(priority) {
ASSERT((priority == kNormalPriority) ||
(delivery_failure_port == kIllegalPort));
- ASSERT(!IsRaw());
+ ASSERT(IsSnapshot());
}
Message::Message(Dart_Port dest_port,
- RawObject* raw_obj,
+ ObjectPtr raw_obj,
Priority priority,
Dart_Port delivery_failure_port)
: next_(NULL),
dest_port_(dest_port),
delivery_failure_port_(delivery_failure_port),
- snapshot_(reinterpret_cast<uint8_t*>(raw_obj)),
+ payload_(raw_obj),
snapshot_length_(0),
finalizable_data_(NULL),
priority_(priority) {
- ASSERT(!raw_obj->IsHeapObject() || raw_obj->InVMIsolateHeap());
+ ASSERT(!raw_obj->IsHeapObject() || raw_obj->ptr()->InVMIsolateHeap());
ASSERT((priority == kNormalPriority) ||
(delivery_failure_port == kIllegalPort));
ASSERT(IsRaw());
}
+Message::Message(Dart_Port dest_port,
+ Bequest* bequest,
+ Priority priority,
+ Dart_Port delivery_failure_port)
+ : next_(nullptr),
+ dest_port_(dest_port),
+ delivery_failure_port_(delivery_failure_port),
+ payload_(bequest),
+ snapshot_length_(-1),
+ finalizable_data_(nullptr),
+ priority_(priority) {
+ ASSERT((priority == kNormalPriority) ||
+ (delivery_failure_port == kIllegalPort));
+ ASSERT(IsBequest());
+}
+
Message::~Message() {
ASSERT(delivery_failure_port_ == kIllegalPort);
- if (!IsRaw()) {
- free(snapshot_);
+ if (IsSnapshot()) {
+ free(payload_.snapshot_);
}
delete finalizable_data_;
+ if (IsBequest()) {
+ delete (payload_.bequest_);
+ }
}
bool Message::RedirectToDeliveryFailurePort() {
diff --git a/runtime/vm/message.h b/runtime/vm/message.h
index 6694940..d29e7fb 100644
--- a/runtime/vm/message.h
+++ b/runtime/vm/message.h
@@ -12,14 +12,19 @@
#include "vm/allocation.h"
#include "vm/finalizable_data.h"
#include "vm/globals.h"
+#include "vm/tagged_pointer.h"
// Duplicated from dart_api.h to avoid including the whole header.
typedef int64_t Dart_Port;
namespace dart {
+class Bequest;
class JSONStream;
-class RawObject;
+class PersistentHandle;
+class HeapPage;
+class WeakTable;
+class FreeList;
class Message {
public:
@@ -58,7 +63,12 @@
// Message objects can also carry RawObject pointers for Smis and objects in
// the VM heap. This is indicated by setting the len_ field to 0.
Message(Dart_Port dest_port,
- RawObject* raw_obj,
+ ObjectPtr raw_obj,
+ Priority priority,
+ Dart_Port delivery_failure_port = kIllegalPort);
+
+ Message(Dart_Port dest_port,
+ Bequest* bequest,
Priority priority,
Dart_Port delivery_failure_port = kIllegalPort);
@@ -72,8 +82,8 @@
Dart_Port dest_port() const { return dest_port_; }
uint8_t* snapshot() const {
- ASSERT(!IsRaw());
- return snapshot_;
+ ASSERT(IsSnapshot());
+ return payload_.snapshot_;
}
intptr_t snapshot_length() const { return snapshot_length_; }
@@ -87,14 +97,25 @@
return size;
}
- RawObject* raw_obj() const {
+ ObjectPtr raw_obj() const {
ASSERT(IsRaw());
- return reinterpret_cast<RawObject*>(snapshot_);
+ return payload_.raw_obj_;
+ }
+ Bequest* bequest() const {
+ ASSERT(IsBequest());
+ return payload_.bequest_;
}
Priority priority() const { return priority_; }
+ // A message processed at any interrupt point (stack overflow check) instead
+ // of at the top of the message loop. Control messages from dart:isolate or
+ // vm-service requests.
bool IsOOB() const { return priority_ == Message::kOOBPriority; }
+ bool IsSnapshot() const { return !IsRaw() && !IsBequest(); }
+ // A message whose object is an immortal object from the vm-isolate's heap.
bool IsRaw() const { return snapshot_length_ == 0; }
+ // A message sent from sendAndExit.
+ bool IsBequest() const { return snapshot_length_ == -1; }
bool RedirectToDeliveryFailurePort();
@@ -114,7 +135,15 @@
Message* next_;
Dart_Port dest_port_;
Dart_Port delivery_failure_port_;
- uint8_t* snapshot_;
+ union Payload {
+ Payload(uint8_t* snapshot) : snapshot_(snapshot) {}
+ Payload(ObjectPtr raw_obj) : raw_obj_(raw_obj) {}
+ Payload(Bequest* bequest) : bequest_(bequest) {}
+
+ uint8_t* snapshot_;
+ ObjectPtr raw_obj_;
+ Bequest* bequest_;
+ } payload_;
intptr_t snapshot_length_;
MessageFinalizableData* finalizable_data_;
Priority priority_;
diff --git a/runtime/vm/native_arguments.h b/runtime/vm/native_arguments.h
index 67a3599..18fdad6 100644
--- a/runtime/vm/native_arguments.h
+++ b/runtime/vm/native_arguments.h
@@ -16,7 +16,6 @@
// Forward declarations.
class BootstrapNatives;
class Object;
-class RawObject;
class Simulator;
class Thread;
@@ -83,11 +82,11 @@
// Includes type arguments vector.
int ArgCount() const { return ArgcBits::decode(argc_tag_); }
- RawObject* ArgAt(int index) const {
+ ObjectPtr ArgAt(int index) const {
ASSERT((index >= 0) && (index < ArgCount()));
- RawObject** arg_ptr =
+ ObjectPtr* arg_ptr =
&(argv_[ReverseArgOrderBit::decode(argc_tag_) ? index : -index]);
- // Tell MemorySanitizer the RawObject* was initialized (by generated code).
+ // Tell MemorySanitizer the ObjectPtr was initialized (by generated code).
MSAN_UNPOISON(arg_ptr, kWordSize);
return *arg_ptr;
}
@@ -95,7 +94,7 @@
void SetArgAt(int index, const Object& value) const {
ASSERT(thread_->execution_state() == Thread::kThreadInVM);
ASSERT((index >= 0) && (index < ArgCount()));
- RawObject** arg_ptr =
+ ObjectPtr* arg_ptr =
&(argv_[ReverseArgOrderBit::decode(argc_tag_) ? index : -index]);
*arg_ptr = value.raw();
}
@@ -106,7 +105,7 @@
return ArgCount() - NumHiddenArgs(function_bits);
}
- RawObject* NativeArg0() const {
+ ObjectPtr NativeArg0() const {
int function_bits = FunctionBits::decode(argc_tag_);
if ((function_bits & (kClosureFunctionBit | kInstanceFunctionBit)) ==
(kClosureFunctionBit | kInstanceFunctionBit)) {
@@ -121,7 +120,7 @@
return ArgAt(NumHiddenArgs(function_bits));
}
- RawObject* NativeArgAt(int index) const {
+ ObjectPtr NativeArgAt(int index) const {
ASSERT((index >= 0) && (index < NativeArgCount()));
if (index == 0) {
return NativeArg0();
@@ -131,7 +130,7 @@
return ArgAt(actual_index);
}
- RawTypeArguments* NativeTypeArgs() const {
+ TypeArgumentsPtr NativeTypeArgs() const {
ASSERT(ToGenericFunction());
return TypeArguments::RawCast(ArgAt(0));
}
@@ -148,7 +147,7 @@
return 0;
}
- RawAbstractType* NativeTypeArgAt(int index) const {
+ AbstractTypePtr NativeTypeArgAt(int index) const {
ASSERT((index >= 0) && (index < NativeTypeArgCount()));
TypeArguments& type_args = TypeArguments::Handle(NativeTypeArgs());
if (type_args.IsNull()) {
@@ -163,7 +162,7 @@
*retval_ = value.raw();
}
- RawObject* ReturnValue() const {
+ ObjectPtr ReturnValue() const {
// Tell MemorySanitizer the retval_ was initialized (by generated code).
MSAN_UNPOISON(retval_, kWordSize);
return *retval_;
@@ -242,8 +241,8 @@
// on the stack.
NativeArguments(Thread* thread,
int argc_tag,
- RawObject** argv,
- RawObject** retval)
+ ObjectPtr* argv,
+ ObjectPtr* retval)
: thread_(thread),
argc_tag_(ReverseArgOrderBit::update(true, argc_tag)),
argv_(argv),
@@ -253,7 +252,7 @@
// exceedingly careful when we use it. If there are any other side
// effects in the statement that may cause GC, it could lead to
// bugs.
- void SetReturnUnsafe(RawObject* value) const {
+ void SetReturnUnsafe(ObjectPtr value) const {
ASSERT(thread_->execution_state() == Thread::kThreadInVM);
*retval_ = value;
}
@@ -290,8 +289,8 @@
Thread* thread_; // Current thread pointer.
intptr_t argc_tag_; // Encodes argument count and invoked native call type.
- RawObject** argv_; // Pointer to an array of arguments to runtime call.
- RawObject** retval_; // Pointer to the return value area.
+ ObjectPtr* argv_; // Pointer to an array of arguments to runtime call.
+ ObjectPtr* retval_; // Pointer to the return value area.
};
} // namespace dart
diff --git a/runtime/vm/native_entry.cc b/runtime/vm/native_entry.cc
index ccfc289..44f3d91b 100644
--- a/runtime/vm/native_entry.cc
+++ b/runtime/vm/native_entry.cc
@@ -91,7 +91,7 @@
}
bool NativeEntry::ReturnValueIsError(NativeArguments* arguments) {
- RawObject* retval = arguments->ReturnValue();
+ ObjectPtr retval = arguments->ReturnValue();
return (retval->IsHeapObject() && IsErrorClassId(retval->GetClassId()));
}
@@ -136,7 +136,7 @@
// Be careful holding return_value_unsafe without a handle here.
// A return of Object::sentinel means the return value has already
// been set.
- RawObject* return_value_unsafe = reinterpret_cast<BootstrapNativeFunction>(
+ ObjectPtr return_value_unsafe = reinterpret_cast<BootstrapNativeFunction>(
func)(thread, zone.GetZone(), arguments);
if (return_value_unsafe != Object::sentinel().raw()) {
ASSERT(return_value_unsafe->IsDartInstance());
@@ -376,7 +376,7 @@
#if !defined(DART_PRECOMPILED_RUNTIME)
// Note: not GC safe. Use with care.
-NativeEntryData::Payload* NativeEntryData::FromTypedArray(RawTypedData* data) {
+NativeEntryData::Payload* NativeEntryData::FromTypedArray(TypedDataPtr data) {
return reinterpret_cast<Payload*>(data->ptr()->data());
}
@@ -388,7 +388,7 @@
FromTypedArray(data_.raw())->kind = value;
}
-MethodRecognizer::Kind NativeEntryData::GetKind(RawTypedData* data) {
+MethodRecognizer::Kind NativeEntryData::GetKind(TypedDataPtr data) {
return FromTypedArray(data)->kind;
}
@@ -400,7 +400,7 @@
FromTypedArray(data_.raw())->trampoline = value;
}
-NativeFunctionWrapper NativeEntryData::GetTrampoline(RawTypedData* data) {
+NativeFunctionWrapper NativeEntryData::GetTrampoline(TypedDataPtr data) {
return FromTypedArray(data)->trampoline;
}
@@ -412,7 +412,7 @@
FromTypedArray(data_.raw())->native_function = value;
}
-NativeFunction NativeEntryData::GetNativeFunction(RawTypedData* data) {
+NativeFunction NativeEntryData::GetNativeFunction(TypedDataPtr data) {
return FromTypedArray(data)->native_function;
}
@@ -424,14 +424,14 @@
FromTypedArray(data_.raw())->argc_tag = value;
}
-intptr_t NativeEntryData::GetArgcTag(RawTypedData* data) {
+intptr_t NativeEntryData::GetArgcTag(TypedDataPtr data) {
return FromTypedArray(data)->argc_tag;
}
-RawTypedData* NativeEntryData::New(MethodRecognizer::Kind kind,
- NativeFunctionWrapper trampoline,
- NativeFunction native_function,
- intptr_t argc_tag) {
+TypedDataPtr NativeEntryData::New(MethodRecognizer::Kind kind,
+ NativeFunctionWrapper trampoline,
+ NativeFunction native_function,
+ intptr_t argc_tag) {
const TypedData& data = TypedData::Handle(
TypedData::New(kTypedDataUint8ArrayCid, sizeof(Payload), Heap::kOld));
NativeEntryData native_entry(data);
diff --git a/runtime/vm/native_entry.h b/runtime/vm/native_entry.h
index d9d4264..fae4261 100644
--- a/runtime/vm/native_entry.h
+++ b/runtime/vm/native_entry.h
@@ -33,25 +33,25 @@
} while (0)
#endif
-typedef RawObject* (*BootstrapNativeFunction)(Thread* thread,
- Zone* zone,
- NativeArguments* arguments);
+typedef ObjectPtr (*BootstrapNativeFunction)(Thread* thread,
+ Zone* zone,
+ NativeArguments* arguments);
#define NATIVE_ENTRY_FUNCTION(name) BootstrapNatives::DN_##name
#define DEFINE_NATIVE_ENTRY(name, type_argument_count, argument_count) \
- static RawObject* DN_Helper##name(Isolate* isolate, Thread* thread, \
- Zone* zone, NativeArguments* arguments); \
- RawObject* NATIVE_ENTRY_FUNCTION(name)(Thread * thread, Zone * zone, \
- NativeArguments * arguments) { \
+ static ObjectPtr DN_Helper##name(Isolate* isolate, Thread* thread, \
+ Zone* zone, NativeArguments* arguments); \
+ ObjectPtr NATIVE_ENTRY_FUNCTION(name)(Thread * thread, Zone * zone, \
+ NativeArguments * arguments) { \
TRACE_NATIVE_CALL("%s", "" #name); \
ASSERT(arguments->NativeArgCount() == argument_count); \
/* Note: a longer type arguments vector may be passed */ \
ASSERT(arguments->NativeTypeArgCount() >= type_argument_count); \
return DN_Helper##name(thread->isolate(), thread, zone, arguments); \
} \
- static RawObject* DN_Helper##name(Isolate* isolate, Thread* thread, \
- Zone* zone, NativeArguments* arguments)
+ static ObjectPtr DN_Helper##name(Isolate* isolate, Thread* thread, \
+ Zone* zone, NativeArguments* arguments)
// Helpers that throw an argument exception.
void DartNativeThrowTypeArgumentCountException(int num_type_args,
@@ -140,24 +140,24 @@
MethodRecognizer::Kind kind() const;
void set_kind(MethodRecognizer::Kind value) const;
- static MethodRecognizer::Kind GetKind(RawTypedData* data);
+ static MethodRecognizer::Kind GetKind(TypedDataPtr data);
NativeFunctionWrapper trampoline() const;
void set_trampoline(NativeFunctionWrapper value) const;
- static NativeFunctionWrapper GetTrampoline(RawTypedData* data);
+ static NativeFunctionWrapper GetTrampoline(TypedDataPtr data);
NativeFunction native_function() const;
void set_native_function(NativeFunction value) const;
- static NativeFunction GetNativeFunction(RawTypedData* data);
+ static NativeFunction GetNativeFunction(TypedDataPtr data);
intptr_t argc_tag() const;
void set_argc_tag(intptr_t value) const;
- static intptr_t GetArgcTag(RawTypedData* data);
+ static intptr_t GetArgcTag(TypedDataPtr data);
- static RawTypedData* New(MethodRecognizer::Kind kind,
- NativeFunctionWrapper trampoline,
- NativeFunction native_function,
- intptr_t argc_tag);
+ static TypedDataPtr New(MethodRecognizer::Kind kind,
+ NativeFunctionWrapper trampoline,
+ NativeFunction native_function,
+ intptr_t argc_tag);
private:
struct Payload {
@@ -167,7 +167,7 @@
MethodRecognizer::Kind kind;
};
- static Payload* FromTypedArray(RawTypedData* data);
+ static Payload* FromTypedArray(TypedDataPtr data);
const TypedData& data_;
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc
index 373f524..ec90971 100644
--- a/runtime/vm/object.cc
+++ b/runtime/vm/object.cc
@@ -33,6 +33,7 @@
#include "vm/heap/become.h"
#include "vm/heap/heap.h"
#include "vm/heap/weak_code.h"
+#include "vm/image_snapshot.h"
#include "vm/isolate_reload.h"
#include "vm/kernel.h"
#include "vm/kernel_binary.h"
@@ -106,9 +107,9 @@
static const intptr_t kInitPrefixLength = strlen(kInitPrefix);
// A cache of VM heap allocated preinitialized empty ic data entry arrays.
-RawArray* ICData::cached_icdata_arrays_[kCachedICDataArrayCount];
+ArrayPtr ICData::cached_icdata_arrays_[kCachedICDataArrayCount];
// A VM heap allocated preinitialized empty subtype entry array.
-RawArray* SubtypeTestCache::cached_array_;
+ArrayPtr SubtypeTestCache::cached_array_;
cpp_vtable Object::builtin_vtables_[kNumPredefinedCids] = {};
@@ -117,11 +118,11 @@
#if defined(RAW_NULL)
#error RAW_NULL should not be defined.
#endif
-#define RAW_NULL kHeapObjectTag
+#define RAW_NULL static_cast<uword>(kHeapObjectTag)
#define CHECK_ERROR(error) \
{ \
- RawError* err = (error); \
+ ErrorPtr err = (error); \
if (err != Error::null()) { \
return err; \
} \
@@ -132,64 +133,50 @@
SHARED_READONLY_HANDLES_LIST(DEFINE_SHARED_READONLY_HANDLE)
#undef DEFINE_SHARED_READONLY_HANDLE
-RawObject* Object::null_ = reinterpret_cast<RawObject*>(RAW_NULL);
-RawBool* Object::true_ = reinterpret_cast<RawBool*>(RAW_NULL);
-RawBool* Object::false_ = reinterpret_cast<RawBool*>(RAW_NULL);
-RawClass* Object::class_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
-RawClass* Object::dynamic_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
-RawClass* Object::void_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
-RawClass* Object::never_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
-RawClass* Object::type_arguments_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
-RawClass* Object::patch_class_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
-RawClass* Object::function_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
-RawClass* Object::closure_data_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
-RawClass* Object::signature_data_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
-RawClass* Object::redirection_data_class_ =
- reinterpret_cast<RawClass*>(RAW_NULL);
-RawClass* Object::ffi_trampoline_data_class_ =
- reinterpret_cast<RawClass*>(RAW_NULL);
-RawClass* Object::field_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
-RawClass* Object::script_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
-RawClass* Object::library_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
-RawClass* Object::namespace_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
-RawClass* Object::kernel_program_info_class_ =
- reinterpret_cast<RawClass*>(RAW_NULL);
-RawClass* Object::code_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
-RawClass* Object::bytecode_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
-RawClass* Object::instructions_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
-RawClass* Object::instructions_section_class_ =
- reinterpret_cast<RawClass*>(RAW_NULL);
-RawClass* Object::object_pool_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
-RawClass* Object::pc_descriptors_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
-RawClass* Object::code_source_map_class_ =
- reinterpret_cast<RawClass*>(RAW_NULL);
-RawClass* Object::compressed_stackmaps_class_ =
- reinterpret_cast<RawClass*>(RAW_NULL);
-RawClass* Object::var_descriptors_class_ =
- reinterpret_cast<RawClass*>(RAW_NULL);
-RawClass* Object::exception_handlers_class_ =
- reinterpret_cast<RawClass*>(RAW_NULL);
-RawClass* Object::context_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
-RawClass* Object::context_scope_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
-RawClass* Object::dyncalltypecheck_class_ =
- reinterpret_cast<RawClass*>(RAW_NULL);
-RawClass* Object::singletargetcache_class_ =
- reinterpret_cast<RawClass*>(RAW_NULL);
-RawClass* Object::unlinkedcall_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
-RawClass* Object::monomorphicsmiablecall_class_ =
- reinterpret_cast<RawClass*>(RAW_NULL);
-RawClass* Object::icdata_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
-RawClass* Object::megamorphic_cache_class_ =
- reinterpret_cast<RawClass*>(RAW_NULL);
-RawClass* Object::subtypetestcache_class_ =
- reinterpret_cast<RawClass*>(RAW_NULL);
-RawClass* Object::api_error_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
-RawClass* Object::language_error_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
-RawClass* Object::unhandled_exception_class_ =
- reinterpret_cast<RawClass*>(RAW_NULL);
-RawClass* Object::unwind_error_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
-RawClass* Object::weak_serialization_reference_class_ =
- reinterpret_cast<RawClass*>(RAW_NULL);
+ObjectPtr Object::null_ = static_cast<ObjectPtr>(RAW_NULL);
+BoolPtr Object::true_ = static_cast<BoolPtr>(RAW_NULL);
+BoolPtr Object::false_ = static_cast<BoolPtr>(RAW_NULL);
+ClassPtr Object::class_class_ = static_cast<ClassPtr>(RAW_NULL);
+ClassPtr Object::dynamic_class_ = static_cast<ClassPtr>(RAW_NULL);
+ClassPtr Object::void_class_ = static_cast<ClassPtr>(RAW_NULL);
+ClassPtr Object::type_arguments_class_ = static_cast<ClassPtr>(RAW_NULL);
+ClassPtr Object::patch_class_class_ = static_cast<ClassPtr>(RAW_NULL);
+ClassPtr Object::function_class_ = static_cast<ClassPtr>(RAW_NULL);
+ClassPtr Object::closure_data_class_ = static_cast<ClassPtr>(RAW_NULL);
+ClassPtr Object::signature_data_class_ = static_cast<ClassPtr>(RAW_NULL);
+ClassPtr Object::redirection_data_class_ = static_cast<ClassPtr>(RAW_NULL);
+ClassPtr Object::ffi_trampoline_data_class_ = static_cast<ClassPtr>(RAW_NULL);
+ClassPtr Object::field_class_ = static_cast<ClassPtr>(RAW_NULL);
+ClassPtr Object::script_class_ = static_cast<ClassPtr>(RAW_NULL);
+ClassPtr Object::library_class_ = static_cast<ClassPtr>(RAW_NULL);
+ClassPtr Object::namespace_class_ = static_cast<ClassPtr>(RAW_NULL);
+ClassPtr Object::kernel_program_info_class_ = static_cast<ClassPtr>(RAW_NULL);
+ClassPtr Object::code_class_ = static_cast<ClassPtr>(RAW_NULL);
+ClassPtr Object::bytecode_class_ = static_cast<ClassPtr>(RAW_NULL);
+ClassPtr Object::instructions_class_ = static_cast<ClassPtr>(RAW_NULL);
+ClassPtr Object::instructions_section_class_ = static_cast<ClassPtr>(RAW_NULL);
+ClassPtr Object::object_pool_class_ = static_cast<ClassPtr>(RAW_NULL);
+ClassPtr Object::pc_descriptors_class_ = static_cast<ClassPtr>(RAW_NULL);
+ClassPtr Object::code_source_map_class_ = static_cast<ClassPtr>(RAW_NULL);
+ClassPtr Object::compressed_stackmaps_class_ = static_cast<ClassPtr>(RAW_NULL);
+ClassPtr Object::var_descriptors_class_ = static_cast<ClassPtr>(RAW_NULL);
+ClassPtr Object::exception_handlers_class_ = static_cast<ClassPtr>(RAW_NULL);
+ClassPtr Object::context_class_ = static_cast<ClassPtr>(RAW_NULL);
+ClassPtr Object::context_scope_class_ = static_cast<ClassPtr>(RAW_NULL);
+ClassPtr Object::dyncalltypecheck_class_ = static_cast<ClassPtr>(RAW_NULL);
+ClassPtr Object::singletargetcache_class_ = static_cast<ClassPtr>(RAW_NULL);
+ClassPtr Object::unlinkedcall_class_ = static_cast<ClassPtr>(RAW_NULL);
+ClassPtr Object::monomorphicsmiablecall_class_ =
+ static_cast<ClassPtr>(RAW_NULL);
+ClassPtr Object::icdata_class_ = static_cast<ClassPtr>(RAW_NULL);
+ClassPtr Object::megamorphic_cache_class_ = static_cast<ClassPtr>(RAW_NULL);
+ClassPtr Object::subtypetestcache_class_ = static_cast<ClassPtr>(RAW_NULL);
+ClassPtr Object::api_error_class_ = static_cast<ClassPtr>(RAW_NULL);
+ClassPtr Object::language_error_class_ = static_cast<ClassPtr>(RAW_NULL);
+ClassPtr Object::unhandled_exception_class_ = static_cast<ClassPtr>(RAW_NULL);
+ClassPtr Object::unwind_error_class_ = static_cast<ClassPtr>(RAW_NULL);
+ClassPtr Object::weak_serialization_reference_class_ =
+ static_cast<ClassPtr>(RAW_NULL);
const double MegamorphicCache::kLoadFactor = 0.50;
@@ -201,7 +188,7 @@
}
// Remove private keys, but retain getter/setter/constructor/mixin manglings.
-RawString* String::RemovePrivateKey(const String& name) {
+StringPtr String::RemovePrivateKey(const String& name) {
ASSERT(name.IsOneByteString());
GrowableArray<uint8_t> without_key(name.Length());
intptr_t i = 0;
@@ -399,8 +386,8 @@
return printer.buffer();
}
-RawString* String::ScrubNameRetainPrivate(const String& name,
- bool is_extension) {
+StringPtr String::ScrubNameRetainPrivate(const String& name,
+ bool is_extension) {
#if !defined(DART_PRECOMPILED_RUNTIME)
intptr_t len = name.Length();
intptr_t start = 0;
@@ -526,7 +513,7 @@
return '\0';
}
-static RawBytecode* CreateVMInternalBytecode(KernelBytecode::Opcode opcode) {
+static BytecodePtr CreateVMInternalBytecode(KernelBytecode::Opcode opcode) {
const KBCInstr* instructions = nullptr;
intptr_t instructions_size = 0;
@@ -555,7 +542,7 @@
// clear the object.
{
uword address = heap->Allocate(Instance::InstanceSize(), Heap::kOld);
- null_ = reinterpret_cast<RawInstance*>(address + kHeapObjectTag);
+ null_ = static_cast<InstancePtr>(address + kHeapObjectTag);
// The call below is using 'null_' to initialize itself.
InitializeObject(address, kNullCid, Instance::InstanceSize());
}
@@ -572,29 +559,29 @@
{
// Allocate true.
uword address = heap->Allocate(Bool::InstanceSize(), Heap::kOld);
- true_ = reinterpret_cast<RawBool*>(address + kHeapObjectTag);
+ true_ = static_cast<BoolPtr>(address + kHeapObjectTag);
InitializeObject(address, kBoolCid, Bool::InstanceSize());
true_->ptr()->value_ = true;
- true_->SetCanonical();
+ true_->ptr()->SetCanonical();
}
{
// Allocate false.
uword address = heap->Allocate(Bool::InstanceSize(), Heap::kOld);
- false_ = reinterpret_cast<RawBool*>(address + kHeapObjectTag);
+ false_ = static_cast<BoolPtr>(address + kHeapObjectTag);
InitializeObject(address, kBoolCid, Bool::InstanceSize());
false_->ptr()->value_ = false;
- false_->SetCanonical();
+ false_->ptr()->SetCanonical();
}
// Check that the objects have been allocated at appropriate addresses.
- ASSERT(reinterpret_cast<uword>(true_) ==
- reinterpret_cast<uword>(null_) + kTrueOffsetFromNull);
- ASSERT(reinterpret_cast<uword>(false_) ==
- reinterpret_cast<uword>(null_) + kFalseOffsetFromNull);
- ASSERT((reinterpret_cast<uword>(true_) & kBoolValueMask) == 0);
- ASSERT((reinterpret_cast<uword>(false_) & kBoolValueMask) != 0);
- ASSERT(reinterpret_cast<uword>(false_) ==
- (reinterpret_cast<uword>(true_) | kBoolValueMask));
+ ASSERT(static_cast<uword>(true_) ==
+ static_cast<uword>(null_) + kTrueOffsetFromNull);
+ ASSERT(static_cast<uword>(false_) ==
+ static_cast<uword>(null_) + kFalseOffsetFromNull);
+ ASSERT((static_cast<uword>(true_) & kBoolValueMask) == 0);
+ ASSERT((static_cast<uword>(false_) & kBoolValueMask) != 0);
+ ASSERT(static_cast<uword>(false_) ==
+ (static_cast<uword>(true_) | kBoolValueMask));
}
void Object::InitVtables() {
@@ -729,7 +716,7 @@
{
intptr_t size = Class::InstanceSize();
uword address = heap->Allocate(size, Heap::kOld);
- class_class_ = reinterpret_cast<RawClass*>(address + kHeapObjectTag);
+ class_class_ = static_cast<ClassPtr>(address + kHeapObjectTag);
InitializeObject(address, Class::kClassId, size);
Class fake;
@@ -762,6 +749,14 @@
cls.set_num_type_arguments(0);
isolate->object_store()->set_null_class(cls);
+ // Allocate and initialize Never class.
+ cls = Class::New<Instance, RTN::Instance>(kNeverCid, isolate);
+ cls.set_num_type_arguments(0);
+ cls.set_is_finalized();
+ cls.set_is_declaration_loaded();
+ cls.set_is_type_finalized();
+ isolate->object_store()->set_never_class(cls);
+
// Allocate and initialize the free list element class.
cls =
Class::New<FreeListElement::FakeInstance,
@@ -949,8 +944,8 @@
{
uword address = heap->Allocate(Array::InstanceSize(0), Heap::kOld);
InitializeObject(address, kImmutableArrayCid, Array::InstanceSize(0));
- Array::initializeHandle(
- empty_array_, reinterpret_cast<RawArray*>(address + kHeapObjectTag));
+ Array::initializeHandle(empty_array_,
+ static_cast<ArrayPtr>(address + kHeapObjectTag));
empty_array_->StoreSmi(&empty_array_->raw_ptr()->length_, Smi::New(0));
empty_array_->SetCanonical();
}
@@ -960,8 +955,8 @@
{
uword address = heap->Allocate(Array::InstanceSize(1), Heap::kOld);
InitializeObject(address, kImmutableArrayCid, Array::InstanceSize(1));
- Array::initializeHandle(
- zero_array_, reinterpret_cast<RawArray*>(address + kHeapObjectTag));
+ Array::initializeHandle(zero_array_,
+ static_cast<ArrayPtr>(address + kHeapObjectTag));
zero_array_->StoreSmi(&zero_array_->raw_ptr()->length_, Smi::New(1));
smi = Smi::New(0);
zero_array_->SetAt(0, smi);
@@ -974,7 +969,7 @@
InitializeObject(address, kContextScopeCid, ContextScope::InstanceSize(0));
ContextScope::initializeHandle(
empty_context_scope_,
- reinterpret_cast<RawContextScope*>(address + kHeapObjectTag));
+ static_cast<ContextScopePtr>(address + kHeapObjectTag));
empty_context_scope_->StoreNonPointer(
&empty_context_scope_->raw_ptr()->num_variables_, 0);
empty_context_scope_->StoreNonPointer(
@@ -988,7 +983,7 @@
InitializeObject(address, kObjectPoolCid, ObjectPool::InstanceSize(0));
ObjectPool::initializeHandle(
empty_object_pool_,
- reinterpret_cast<RawObjectPool*>(address + kHeapObjectTag));
+ static_cast<ObjectPoolPtr>(address + kHeapObjectTag));
empty_object_pool_->StoreNonPointer(&empty_object_pool_->raw_ptr()->length_,
0);
empty_object_pool_->SetCanonical();
@@ -1001,7 +996,7 @@
PcDescriptors::InstanceSize(0));
PcDescriptors::initializeHandle(
empty_descriptors_,
- reinterpret_cast<RawPcDescriptors*>(address + kHeapObjectTag));
+ static_cast<PcDescriptorsPtr>(address + kHeapObjectTag));
empty_descriptors_->StoreNonPointer(&empty_descriptors_->raw_ptr()->length_,
0);
empty_descriptors_->SetCanonical();
@@ -1015,7 +1010,7 @@
LocalVarDescriptors::InstanceSize(0));
LocalVarDescriptors::initializeHandle(
empty_var_descriptors_,
- reinterpret_cast<RawLocalVarDescriptors*>(address + kHeapObjectTag));
+ static_cast<LocalVarDescriptorsPtr>(address + kHeapObjectTag));
empty_var_descriptors_->StoreNonPointer(
&empty_var_descriptors_->raw_ptr()->num_entries_, 0);
empty_var_descriptors_->SetCanonical();
@@ -1031,7 +1026,7 @@
ExceptionHandlers::InstanceSize(0));
ExceptionHandlers::initializeHandle(
empty_exception_handlers_,
- reinterpret_cast<RawExceptionHandlers*>(address + kHeapObjectTag));
+ static_cast<ExceptionHandlersPtr>(address + kHeapObjectTag));
empty_exception_handlers_->StoreNonPointer(
&empty_exception_handlers_->raw_ptr()->num_entries_, 0);
empty_exception_handlers_->SetCanonical();
@@ -1044,7 +1039,7 @@
TypeArguments::InstanceSize(0));
TypeArguments::initializeHandle(
empty_type_arguments_,
- reinterpret_cast<RawTypeArguments*>(address + kHeapObjectTag));
+ static_cast<TypeArgumentsPtr>(address + kHeapObjectTag));
empty_type_arguments_->StoreSmi(&empty_type_arguments_->raw_ptr()->length_,
Smi::New(0));
empty_type_arguments_->StoreSmi(&empty_type_arguments_->raw_ptr()->hash_,
@@ -1071,13 +1066,6 @@
cls.set_is_type_finalized();
void_class_ = cls.raw();
- cls = Class::New<Instance, RTN::Instance>(kNeverCid, isolate);
- cls.set_num_type_arguments(0);
- cls.set_is_finalized();
- cls.set_is_declaration_loaded();
- cls.set_is_type_finalized();
- never_class_ = cls.raw();
-
cls = Class::New<Type, RTN::Type>(isolate);
cls.set_is_finalized();
cls.set_is_declaration_loaded();
@@ -1097,9 +1085,6 @@
void_type_->ComputeHash();
void_type_->SetCanonical();
- cls = never_class_;
- *never_type_ = Type::NewNonParameterizedType(cls);
-
// Since TypeArguments objects are passed as function arguments, make them
// behave as Dart instances, although they are just VM objects.
// Note that we cannot set the super type to ObjectType, which does not live
@@ -1249,7 +1234,7 @@
void Object::FinishInit(Isolate* isolate) {
// The type testing stubs we initialize in AbstractType objects for the
- // canonical type of kDynamicCid/kVoidCid/kNeverCid need to be set in this
+ // canonical type of kDynamicCid/kVoidCid need to be set in this
// method, which is called after StubCode::InitOnce().
Code& code = Code::Handle();
@@ -1258,54 +1243,50 @@
code = TypeTestingStubGenerator::DefaultCodeForType(*void_type_);
void_type_->SetTypeTestingStub(code);
-
- code = TypeTestingStubGenerator::DefaultCodeForType(*never_type_);
- never_type_->SetTypeTestingStub(code);
}
void Object::Cleanup() {
- null_ = reinterpret_cast<RawObject*>(RAW_NULL);
- true_ = reinterpret_cast<RawBool*>(RAW_NULL);
- false_ = reinterpret_cast<RawBool*>(RAW_NULL);
- class_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
- dynamic_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
- void_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
- never_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
- type_arguments_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
- patch_class_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
- function_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
- closure_data_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
- signature_data_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
- redirection_data_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
- ffi_trampoline_data_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
- field_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
- script_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
- library_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
- namespace_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
- kernel_program_info_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
- code_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
- bytecode_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
- instructions_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
- instructions_section_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
- object_pool_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
- pc_descriptors_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
- code_source_map_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
- compressed_stackmaps_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
- var_descriptors_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
- exception_handlers_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
- context_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
- context_scope_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
- dyncalltypecheck_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
- singletargetcache_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
- unlinkedcall_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
- monomorphicsmiablecall_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
- icdata_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
- megamorphic_cache_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
- subtypetestcache_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
- api_error_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
- language_error_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
- unhandled_exception_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
- unwind_error_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
+ null_ = static_cast<ObjectPtr>(RAW_NULL);
+ true_ = static_cast<BoolPtr>(RAW_NULL);
+ false_ = static_cast<BoolPtr>(RAW_NULL);
+ class_class_ = static_cast<ClassPtr>(RAW_NULL);
+ dynamic_class_ = static_cast<ClassPtr>(RAW_NULL);
+ void_class_ = static_cast<ClassPtr>(RAW_NULL);
+ type_arguments_class_ = static_cast<ClassPtr>(RAW_NULL);
+ patch_class_class_ = static_cast<ClassPtr>(RAW_NULL);
+ function_class_ = static_cast<ClassPtr>(RAW_NULL);
+ closure_data_class_ = static_cast<ClassPtr>(RAW_NULL);
+ signature_data_class_ = static_cast<ClassPtr>(RAW_NULL);
+ redirection_data_class_ = static_cast<ClassPtr>(RAW_NULL);
+ ffi_trampoline_data_class_ = static_cast<ClassPtr>(RAW_NULL);
+ field_class_ = static_cast<ClassPtr>(RAW_NULL);
+ script_class_ = static_cast<ClassPtr>(RAW_NULL);
+ library_class_ = static_cast<ClassPtr>(RAW_NULL);
+ namespace_class_ = static_cast<ClassPtr>(RAW_NULL);
+ kernel_program_info_class_ = static_cast<ClassPtr>(RAW_NULL);
+ code_class_ = static_cast<ClassPtr>(RAW_NULL);
+ bytecode_class_ = static_cast<ClassPtr>(RAW_NULL);
+ instructions_class_ = static_cast<ClassPtr>(RAW_NULL);
+ instructions_section_class_ = static_cast<ClassPtr>(RAW_NULL);
+ object_pool_class_ = static_cast<ClassPtr>(RAW_NULL);
+ pc_descriptors_class_ = static_cast<ClassPtr>(RAW_NULL);
+ code_source_map_class_ = static_cast<ClassPtr>(RAW_NULL);
+ compressed_stackmaps_class_ = static_cast<ClassPtr>(RAW_NULL);
+ var_descriptors_class_ = static_cast<ClassPtr>(RAW_NULL);
+ exception_handlers_class_ = static_cast<ClassPtr>(RAW_NULL);
+ context_class_ = static_cast<ClassPtr>(RAW_NULL);
+ context_scope_class_ = static_cast<ClassPtr>(RAW_NULL);
+ dyncalltypecheck_class_ = static_cast<ClassPtr>(RAW_NULL);
+ singletargetcache_class_ = static_cast<ClassPtr>(RAW_NULL);
+ unlinkedcall_class_ = static_cast<ClassPtr>(RAW_NULL);
+ monomorphicsmiablecall_class_ = static_cast<ClassPtr>(RAW_NULL);
+ icdata_class_ = static_cast<ClassPtr>(RAW_NULL);
+ megamorphic_cache_class_ = static_cast<ClassPtr>(RAW_NULL);
+ subtypetestcache_class_ = static_cast<ClassPtr>(RAW_NULL);
+ api_error_class_ = static_cast<ClassPtr>(RAW_NULL);
+ language_error_class_ = static_cast<ClassPtr>(RAW_NULL);
+ unhandled_exception_class_ = static_cast<ClassPtr>(RAW_NULL);
+ unwind_error_class_ = static_cast<ClassPtr>(RAW_NULL);
}
// An object visitor which will mark all visited objects. This is used to
@@ -1321,13 +1302,13 @@
{
}
- void VisitObject(RawObject* obj) {
+ void VisitObject(ObjectPtr obj) {
// Free list elements should never be marked.
- ASSERT(!obj->IsMarked());
+ ASSERT(!obj->ptr()->IsMarked());
// No forwarding corpses in the VM isolate.
ASSERT(!obj->IsForwardingCorpse());
if (!obj->IsFreeListElement()) {
- obj->SetMarkBitUnsynchronized();
+ obj->ptr()->SetMarkBitUnsynchronized();
Object::FinalizeReadOnlyObject(obj);
#if defined(HASH_IN_OBJECT_HEADER)
// These objects end up in the read-only VM isolate which is shared
@@ -1373,7 +1354,6 @@
SET_CLASS_NAME(class, Class);
SET_CLASS_NAME(dynamic, Dynamic);
SET_CLASS_NAME(void, Void);
- SET_CLASS_NAME(never, Never);
SET_CLASS_NAME(type_arguments, TypeArguments);
SET_CLASS_NAME(patch_class, PatchClass);
SET_CLASS_NAME(function, Function);
@@ -1410,12 +1390,13 @@
SET_CLASS_NAME(unhandled_exception, UnhandledException);
SET_CLASS_NAME(unwind_error, UnwindError);
- // Set up names for object array and one byte string class which are
- // pre-allocated in the vm isolate also.
+ // Set up names for classes which are also pre-allocated in the vm isolate.
cls = isolate->object_store()->array_class();
cls.set_name(Symbols::_List());
cls = isolate->object_store()->one_byte_string_class();
cls.set_name(Symbols::OneByteString());
+ cls = isolate->object_store()->never_class();
+ cls.set_name(Symbols::Never());
// Set up names for the pseudo-classes for free list elements and forwarding
// corpses. Mainly this makes VM debugging easier.
@@ -1437,62 +1418,62 @@
}
}
-void Object::FinalizeReadOnlyObject(RawObject* object) {
+void Object::FinalizeReadOnlyObject(ObjectPtr object) {
NoSafepointScope no_safepoint;
intptr_t cid = object->GetClassId();
if (cid == kOneByteStringCid) {
- RawOneByteString* str = static_cast<RawOneByteString*>(object);
+ OneByteStringPtr str = static_cast<OneByteStringPtr>(object);
if (String::GetCachedHash(str) == 0) {
intptr_t hash = String::Hash(str);
String::SetCachedHash(str, hash);
}
intptr_t size = OneByteString::UnroundedSize(str);
- ASSERT(size <= str->HeapSize());
- memset(reinterpret_cast<void*>(RawObject::ToAddr(str) + size), 0,
- str->HeapSize() - size);
+ ASSERT(size <= str->ptr()->HeapSize());
+ memset(reinterpret_cast<void*>(ObjectLayout::ToAddr(str) + size), 0,
+ str->ptr()->HeapSize() - size);
} else if (cid == kTwoByteStringCid) {
- RawTwoByteString* str = static_cast<RawTwoByteString*>(object);
+ TwoByteStringPtr str = static_cast<TwoByteStringPtr>(object);
if (String::GetCachedHash(str) == 0) {
intptr_t hash = String::Hash(str);
String::SetCachedHash(str, hash);
}
ASSERT(String::GetCachedHash(str) != 0);
intptr_t size = TwoByteString::UnroundedSize(str);
- ASSERT(size <= str->HeapSize());
- memset(reinterpret_cast<void*>(RawObject::ToAddr(str) + size), 0,
- str->HeapSize() - size);
+ ASSERT(size <= str->ptr()->HeapSize());
+ memset(reinterpret_cast<void*>(ObjectLayout::ToAddr(str) + size), 0,
+ str->ptr()->HeapSize() - size);
} else if (cid == kExternalOneByteStringCid) {
- RawExternalOneByteString* str =
- static_cast<RawExternalOneByteString*>(object);
+ ExternalOneByteStringPtr str =
+ static_cast<ExternalOneByteStringPtr>(object);
if (String::GetCachedHash(str) == 0) {
intptr_t hash = String::Hash(str);
String::SetCachedHash(str, hash);
}
} else if (cid == kExternalTwoByteStringCid) {
- RawExternalTwoByteString* str =
- static_cast<RawExternalTwoByteString*>(object);
+ ExternalTwoByteStringPtr str =
+ static_cast<ExternalTwoByteStringPtr>(object);
if (String::GetCachedHash(str) == 0) {
intptr_t hash = String::Hash(str);
String::SetCachedHash(str, hash);
}
} else if (cid == kCodeSourceMapCid) {
- RawCodeSourceMap* map = CodeSourceMap::RawCast(object);
+ CodeSourceMapPtr map = CodeSourceMap::RawCast(object);
intptr_t size = CodeSourceMap::UnroundedSize(map);
- ASSERT(size <= map->HeapSize());
- memset(reinterpret_cast<void*>(RawObject::ToAddr(map) + size), 0,
- map->HeapSize() - size);
+ ASSERT(size <= map->ptr()->HeapSize());
+ memset(reinterpret_cast<void*>(ObjectLayout::ToAddr(map) + size), 0,
+ map->ptr()->HeapSize() - size);
} else if (cid == kCompressedStackMapsCid) {
- RawCompressedStackMaps* maps = CompressedStackMaps::RawCast(object);
+ CompressedStackMapsPtr maps = CompressedStackMaps::RawCast(object);
intptr_t size = CompressedStackMaps::UnroundedSize(maps);
- ASSERT(size <= maps->HeapSize());
- memset(reinterpret_cast<void*>(RawObject::ToAddr(maps) + size), 0,
- maps->HeapSize() - size);
+ ASSERT(size <= maps->ptr()->HeapSize());
+ memset(reinterpret_cast<void*>(ObjectLayout::ToAddr(maps) + size), 0,
+ maps->ptr()->HeapSize() - size);
} else if (cid == kPcDescriptorsCid) {
- RawPcDescriptors* desc = PcDescriptors::RawCast(object);
+ PcDescriptorsPtr desc = PcDescriptors::RawCast(object);
intptr_t size = PcDescriptors::UnroundedSize(desc);
- ASSERT(size <= desc->HeapSize());
- memset(reinterpret_cast<void*>(RawObject::ToAddr(desc) + size), 0,
- desc->HeapSize() - size);
+ ASSERT(size <= desc->ptr()->HeapSize());
+ memset(reinterpret_cast<void*>(ObjectLayout::ToAddr(desc) + size), 0,
+ desc->ptr()->HeapSize() - size);
}
}
@@ -1514,18 +1495,19 @@
if (original_size > used_size) {
intptr_t leftover_size = original_size - used_size;
- uword addr = RawObject::ToAddr(obj.raw()) + used_size;
+ uword addr = ObjectLayout::ToAddr(obj.raw()) + used_size;
if (leftover_size >= TypedData::InstanceSize(0)) {
// Update the leftover space as a TypedDataInt8Array object.
- RawTypedData* raw =
- reinterpret_cast<RawTypedData*>(RawObject::FromAddr(addr));
- uword new_tags = RawObject::ClassIdTag::update(kTypedDataInt8ArrayCid, 0);
- new_tags = RawObject::SizeTag::update(leftover_size, new_tags);
+ TypedDataPtr raw =
+ static_cast<TypedDataPtr>(ObjectLayout::FromAddr(addr));
+ uword new_tags =
+ ObjectLayout::ClassIdTag::update(kTypedDataInt8ArrayCid, 0);
+ new_tags = ObjectLayout::SizeTag::update(leftover_size, new_tags);
const bool is_old = obj.raw()->IsOldObject();
- new_tags = RawObject::OldBit::update(is_old, new_tags);
- new_tags = RawObject::OldAndNotMarkedBit::update(is_old, new_tags);
- new_tags = RawObject::OldAndNotRememberedBit::update(is_old, new_tags);
- new_tags = RawObject::NewBit::update(!is_old, new_tags);
+ new_tags = ObjectLayout::OldBit::update(is_old, new_tags);
+ new_tags = ObjectLayout::OldAndNotMarkedBit::update(is_old, new_tags);
+ new_tags = ObjectLayout::OldAndNotRememberedBit::update(is_old, new_tags);
+ new_tags = ObjectLayout::NewBit::update(!is_old, new_tags);
// On architectures with a relaxed memory model, the concurrent marker may
// observe the write of the filler object's header before observing the
// new array length, and so treat it as a pointer. Ensure it is a Smi so
@@ -1542,19 +1524,19 @@
intptr_t leftover_len = (leftover_size - TypedData::InstanceSize(0));
ASSERT(TypedData::InstanceSize(leftover_len) == leftover_size);
- raw->StoreSmi(&(raw->ptr()->length_), Smi::New(leftover_len));
- raw->RecomputeDataField();
+ raw->ptr()->StoreSmi(&(raw->ptr()->length_), Smi::New(leftover_len));
+ raw->ptr()->RecomputeDataField();
} else {
// Update the leftover space as a basic object.
ASSERT(leftover_size == Object::InstanceSize());
- RawObject* raw = reinterpret_cast<RawObject*>(RawObject::FromAddr(addr));
- uword new_tags = RawObject::ClassIdTag::update(kInstanceCid, 0);
- new_tags = RawObject::SizeTag::update(leftover_size, new_tags);
+ ObjectPtr raw = static_cast<ObjectPtr>(ObjectLayout::FromAddr(addr));
+ uword new_tags = ObjectLayout::ClassIdTag::update(kInstanceCid, 0);
+ new_tags = ObjectLayout::SizeTag::update(leftover_size, new_tags);
const bool is_old = obj.raw()->IsOldObject();
- new_tags = RawObject::OldBit::update(is_old, new_tags);
- new_tags = RawObject::OldAndNotMarkedBit::update(is_old, new_tags);
- new_tags = RawObject::OldAndNotRememberedBit::update(is_old, new_tags);
- new_tags = RawObject::NewBit::update(!is_old, new_tags);
+ new_tags = ObjectLayout::OldBit::update(is_old, new_tags);
+ new_tags = ObjectLayout::OldAndNotMarkedBit::update(is_old, new_tags);
+ new_tags = ObjectLayout::OldAndNotRememberedBit::update(is_old, new_tags);
+ new_tags = ObjectLayout::NewBit::update(!is_old, new_tags);
// On architectures with a relaxed memory model, the concurrent marker may
// observe the write of the filler object's header before observing the
// new array length, and so treat it as a pointer. Ensure it is a Smi so
@@ -1616,9 +1598,9 @@
//
// A non-NULL kernel argument indicates (1).
// A NULL kernel indicates (2) or (3).
-RawError* Object::Init(Isolate* isolate,
- const uint8_t* kernel_buffer,
- intptr_t kernel_buffer_size) {
+ErrorPtr Object::Init(Isolate* isolate,
+ const uint8_t* kernel_buffer,
+ intptr_t kernel_buffer_size) {
Thread* thread = Thread::Current();
Zone* zone = thread->zone();
ASSERT(isolate == thread->isolate());
@@ -1852,6 +1834,14 @@
RegisterClass(cls, Symbols::Null(), core_lib);
pending_classes.Add(cls);
+ cls = Class::New<Instance, RTN::Instance>(kNeverCid, isolate);
+ cls.set_num_type_arguments(0);
+ cls.set_is_finalized();
+ cls.set_is_declaration_loaded();
+ cls.set_is_type_finalized();
+ cls.set_name(Symbols::Never());
+ object_store->set_never_class(cls);
+
ASSERT(!library_prefix_cls.IsNull());
RegisterPrivateClass(library_prefix_cls, Symbols::_LibraryPrefix(),
core_lib);
@@ -2191,6 +2181,13 @@
type = object_store->object_type();
cls.set_super_type(type);
+ cls = object_store->never_class();
+ type = Type::New(cls, Object::null_type_arguments(),
+ TokenPosition::kNoSource, Nullability::kNonNullable);
+ type.SetIsFinalized();
+ type ^= type.Canonicalize();
+ object_store->set_never_type(type);
+
// Create and cache commonly used type arguments <int>, <double>,
// <String>, <String, dynamic> and <String, String>.
type_args = TypeArguments::New(1);
@@ -2488,6 +2485,9 @@
cls = Class::New<Instance, RTN::Instance>(kNullCid, isolate);
object_store->set_null_class(cls);
+ cls = Class::New<Instance, RTN::Instance>(kNeverCid, isolate);
+ object_store->set_never_class(cls);
+
cls = Class::New<Capability, RTN::Capability>(isolate);
cls = Class::New<ReceivePort, RTN::ReceivePort>(isolate);
cls = Class::New<SendPort, RTN::SendPort>(isolate);
@@ -2509,16 +2509,16 @@
#if defined(DEBUG)
bool Object::InVMIsolateHeap() const {
- if (FLAG_verify_handles && raw()->InVMIsolateHeap()) {
+ if (FLAG_verify_handles && raw()->ptr()->InVMIsolateHeap()) {
Heap* vm_isolate_heap = Dart::vm_isolate()->heap();
- uword addr = RawObject::ToAddr(raw());
+ uword addr = ObjectLayout::ToAddr(raw());
if (!vm_isolate_heap->Contains(addr)) {
ASSERT(FLAG_write_protect_code);
- addr = RawObject::ToAddr(HeapPage::ToWritable(raw()));
+ addr = ObjectLayout::ToAddr(HeapPage::ToWritable(raw()));
ASSERT(vm_isolate_heap->Contains(addr));
}
}
- return raw()->InVMIsolateHeap();
+ return raw()->ptr()->InVMIsolateHeap();
}
#endif // DEBUG
@@ -2526,7 +2526,7 @@
THR_Print("%s\n", ToCString());
}
-RawString* Object::DictionaryName() const {
+StringPtr Object::DictionaryName() const {
return String::null();
}
@@ -2535,7 +2535,7 @@
// an 8-byte write from the this loop, but doesn't overwrite that entry with
// the 4-byte relaxed store of the header below, then reports false data races
// based on the record of the 8-byte write.
- uword cur = address + sizeof(RawObject);
+ uword cur = address + sizeof(ObjectLayout);
uword end = address + size;
if (class_id == kInstructionsCid) {
compiler::target::uword initial_value = kBreakInstructionFiller;
@@ -2554,7 +2554,7 @@
needs_init = Heap::IsAllocatableInNewSpace(size) ||
Heap::IsAllocatableViaFreeLists(size);
} else {
- initial_value = reinterpret_cast<uword>(null_);
+ initial_value = static_cast<uword>(null_);
needs_init = true;
}
if (needs_init) {
@@ -2575,17 +2575,17 @@
}
uint32_t tags = 0;
ASSERT(class_id != kIllegalCid);
- tags = RawObject::ClassIdTag::update(class_id, tags);
- tags = RawObject::SizeTag::update(size, tags);
+ tags = ObjectLayout::ClassIdTag::update(class_id, tags);
+ tags = ObjectLayout::SizeTag::update(size, tags);
const bool is_old =
(address & kNewObjectAlignmentOffset) == kOldObjectAlignmentOffset;
- tags = RawObject::OldBit::update(is_old, tags);
- tags = RawObject::OldAndNotMarkedBit::update(is_old, tags);
- tags = RawObject::OldAndNotRememberedBit::update(is_old, tags);
- tags = RawObject::NewBit::update(!is_old, tags);
- reinterpret_cast<RawObject*>(address)->tags_ = tags;
+ tags = ObjectLayout::OldBit::update(is_old, tags);
+ tags = ObjectLayout::OldAndNotMarkedBit::update(is_old, tags);
+ tags = ObjectLayout::OldAndNotRememberedBit::update(is_old, tags);
+ tags = ObjectLayout::NewBit::update(!is_old, tags);
+ reinterpret_cast<ObjectLayout*>(address)->tags_ = tags;
#if defined(HASH_IN_OBJECT_HEADER)
- reinterpret_cast<RawObject*>(address)->hash_ = 0;
+ reinterpret_cast<ObjectLayout*>(address)->hash_ = 0;
#endif
}
@@ -2601,10 +2601,10 @@
Heap* isolate_heap = IsolateGroup::Current()->heap();
if (!isolate_heap->new_space()->scavenging()) {
Heap* vm_isolate_heap = Dart::vm_isolate()->heap();
- uword addr = RawObject::ToAddr(raw_);
+ uword addr = ObjectLayout::ToAddr(raw_);
if (!isolate_heap->Contains(addr) && !vm_isolate_heap->Contains(addr)) {
ASSERT(FLAG_write_protect_code);
- addr = RawObject::ToAddr(HeapPage::ToWritable(raw_));
+ addr = ObjectLayout::ToAddr(HeapPage::ToWritable(raw_));
ASSERT(isolate_heap->Contains(addr) ||
vm_isolate_heap->Contains(addr));
}
@@ -2614,7 +2614,7 @@
#endif
}
-RawObject* Object::Allocate(intptr_t cls_id, intptr_t size, Heap::Space space) {
+ObjectPtr Object::Allocate(intptr_t cls_id, intptr_t size, Heap::Space space) {
ASSERT(Utils::IsAligned(size, kObjectAlignment));
Thread* thread = Thread::Current();
ASSERT(thread->execution_state() == Thread::kThreadInVM);
@@ -2644,14 +2644,14 @@
#endif // !PRODUCT
NoSafepointScope no_safepoint;
InitializeObject(address, cls_id, size);
- RawObject* raw_obj = reinterpret_cast<RawObject*>(address + kHeapObjectTag);
- ASSERT(cls_id == RawObject::ClassIdTag::decode(raw_obj->ptr()->tags_));
+ ObjectPtr raw_obj = static_cast<ObjectPtr>(address + kHeapObjectTag);
+ ASSERT(cls_id == ObjectLayout::ClassIdTag::decode(raw_obj->ptr()->tags_));
if (raw_obj->IsOldObject() && UNLIKELY(thread->is_marking())) {
// Black allocation. Prevents a data race between the mutator and concurrent
// marker on ARM and ARM64 (the marker may observe a publishing store of
// this object before the stores that initialize its slots), and helps the
// collection to finish sooner.
- raw_obj->SetMarkBitUnsynchronized();
+ raw_obj->ptr()->SetMarkBitUnsynchronized();
// Setting the mark bit must not be ordered after a publishing store of this
// object. Adding a barrier here is cheaper than making every store into the
// heap a store-release. Compare Scavenger::ScavengePointer.
@@ -2663,26 +2663,26 @@
class WriteBarrierUpdateVisitor : public ObjectPointerVisitor {
public:
- explicit WriteBarrierUpdateVisitor(Thread* thread, RawObject* obj)
+ explicit WriteBarrierUpdateVisitor(Thread* thread, ObjectPtr obj)
: ObjectPointerVisitor(thread->isolate()->group()),
thread_(thread),
old_obj_(obj) {
ASSERT(old_obj_->IsOldObject());
}
- void VisitPointers(RawObject** from, RawObject** to) {
+ void VisitPointers(ObjectPtr* from, ObjectPtr* to) {
if (old_obj_->IsArray()) {
- for (RawObject** slot = from; slot <= to; ++slot) {
- RawObject* value = *slot;
+ for (ObjectPtr* slot = from; slot <= to; ++slot) {
+ ObjectPtr value = *slot;
if (value->IsHeapObject()) {
- old_obj_->CheckArrayPointerStore(slot, value, thread_);
+ old_obj_->ptr()->CheckArrayPointerStore(slot, value, thread_);
}
}
} else {
- for (RawObject** slot = from; slot <= to; ++slot) {
- RawObject* value = *slot;
+ for (ObjectPtr* slot = from; slot <= to; ++slot) {
+ ObjectPtr value = *slot;
if (value->IsHeapObject()) {
- old_obj_->CheckHeapPointerStore(value, thread_);
+ old_obj_->ptr()->CheckHeapPointerStore(value, thread_);
}
}
}
@@ -2690,7 +2690,7 @@
private:
Thread* thread_;
- RawObject* old_obj_;
+ ObjectPtr old_obj_;
DISALLOW_COPY_AND_ASSIGN(WriteBarrierUpdateVisitor);
};
@@ -2703,15 +2703,15 @@
return (IsZoneHandle() || IsReadOnlyHandle());
}
-RawObject* Object::Clone(const Object& orig, Heap::Space space) {
+ObjectPtr Object::Clone(const Object& orig, Heap::Space space) {
const Class& cls = Class::Handle(orig.clazz());
- intptr_t size = orig.raw()->HeapSize();
- RawObject* raw_clone = Object::Allocate(cls.id(), size, space);
+ intptr_t size = orig.raw()->ptr()->HeapSize();
+ ObjectPtr raw_clone = Object::Allocate(cls.id(), size, space);
NoSafepointScope no_safepoint;
// Copy the body of the original into the clone.
- uword orig_addr = RawObject::ToAddr(orig.raw());
- uword clone_addr = RawObject::ToAddr(raw_clone);
- static const intptr_t kHeaderSizeInBytes = sizeof(RawObject);
+ uword orig_addr = ObjectLayout::ToAddr(orig.raw());
+ uword clone_addr = ObjectLayout::ToAddr(raw_clone);
+ static const intptr_t kHeaderSizeInBytes = sizeof(ObjectLayout);
memmove(reinterpret_cast<uint8_t*>(clone_addr + kHeaderSizeInBytes),
reinterpret_cast<uint8_t*>(orig_addr + kHeaderSizeInBytes),
size - kHeaderSizeInBytes);
@@ -2722,15 +2722,15 @@
return raw_clone;
}
WriteBarrierUpdateVisitor visitor(Thread::Current(), raw_clone);
- raw_clone->VisitPointers(&visitor);
+ raw_clone->ptr()->VisitPointers(&visitor);
return raw_clone;
}
-RawString* Class::Name() const {
+StringPtr Class::Name() const {
return raw_ptr()->name_;
}
-RawString* Class::ScrubbedName() const {
+StringPtr Class::ScrubbedName() const {
return Symbols::New(Thread::Current(), ScrubbedNameCString());
}
@@ -2738,7 +2738,7 @@
return String::ScrubName(String::Handle(Name()));
}
-RawString* Class::UserVisibleName() const {
+StringPtr Class::UserVisibleName() const {
#if !defined(PRODUCT)
ASSERT(raw_ptr()->user_name_ != String::null());
return raw_ptr()->user_name_;
@@ -2755,7 +2755,7 @@
return GenerateUserVisibleName(); // No caching in PRODUCT, regenerate.
}
-RawClass* Class::Mixin() const {
+ClassPtr Class::Mixin() const {
if (is_transformed_mixin_application()) {
const Array& interfaces = Array::Handle(this->interfaces());
const Type& mixin_type =
@@ -2771,11 +2771,11 @@
bool Class::IsInFullSnapshot() const {
NoSafepointScope no_safepoint;
- return RawLibrary::InFullSnapshotBit::decode(
+ return LibraryLayout::InFullSnapshotBit::decode(
raw_ptr()->library_->ptr()->flags_);
}
-RawAbstractType* Class::RareType() const {
+AbstractTypePtr Class::RareType() const {
if (!IsGeneric() && !IsClosureClass() && !IsTypedefClass()) {
return DeclarationType();
}
@@ -2788,11 +2788,11 @@
}
template <class FakeObject, class TargetFakeObject>
-RawClass* Class::New(Isolate* isolate, bool register_class) {
+ClassPtr Class::New(Isolate* isolate, bool register_class) {
ASSERT(Object::class_class() != Class::null());
Class& result = Class::Handle();
{
- RawObject* raw =
+ ObjectPtr raw =
Object::Allocate(Class::kClassId, Class::InstanceSize(), Heap::kOld);
NoSafepointScope no_safepoint;
result ^= raw;
@@ -2869,7 +2869,7 @@
Object::empty_array().raw());
}
-RawArray* Class::OffsetToFieldMap(bool original_classes) const {
+ArrayPtr Class::OffsetToFieldMap(bool original_classes) const {
Array& array = Array::Handle(raw_ptr()->offset_in_words_to_field_);
if (array.IsNull()) {
ASSERT(is_finalized());
@@ -2999,7 +2999,7 @@
}
}
-RawFunction* Class::FunctionFromIndex(intptr_t idx) const {
+FunctionPtr Class::FunctionFromIndex(intptr_t idx) const {
const Array& funcs = Array::Handle(functions());
if ((idx < 0) || (idx >= funcs.Length())) {
return Function::null();
@@ -3010,7 +3010,7 @@
return func.raw();
}
-RawFunction* Class::ImplicitClosureFunctionFromIndex(intptr_t idx) const {
+FunctionPtr Class::ImplicitClosureFunctionFromIndex(intptr_t idx) const {
const Array& funcs = Array::Handle(functions());
if ((idx < 0) || (idx >= funcs.Length())) {
return Function::null();
@@ -3082,7 +3082,7 @@
return -1;
}
-RawFunction* Class::InvocationDispatcherFunctionFromIndex(intptr_t idx) const {
+FunctionPtr Class::InvocationDispatcherFunctionFromIndex(intptr_t idx) const {
Thread* thread = Thread::Current();
REUSABLE_ARRAY_HANDLESCOPE(thread);
REUSABLE_OBJECT_HANDLESCOPE(thread);
@@ -3217,7 +3217,7 @@
return num_type_args;
}
-RawClass* Class::SuperClass(bool original_classes) const {
+ClassPtr Class::SuperClass(bool original_classes) const {
Thread* thread = Thread::Current();
Zone* zone = thread->zone();
Isolate* isolate = thread->isolate();
@@ -3242,7 +3242,7 @@
StorePointer(&raw_ptr()->super_type_, value.raw());
}
-RawTypeParameter* Class::LookupTypeParameter(const String& type_name) const {
+TypeParameterPtr Class::LookupTypeParameter(const String& type_name) const {
ASSERT(!type_name.IsNull());
Thread* thread = Thread::Current();
REUSABLE_TYPE_ARGUMENTS_HANDLESCOPE(thread);
@@ -3336,17 +3336,17 @@
intptr_t field_size;
switch (field.guarded_cid()) {
case kDoubleCid:
- field_size = sizeof(RawDouble::value_);
+ field_size = sizeof(DoubleLayout::value_);
break;
case kFloat32x4Cid:
- field_size = sizeof(RawFloat32x4::value_);
+ field_size = sizeof(Float32x4Layout::value_);
break;
case kFloat64x2Cid:
- field_size = sizeof(RawFloat64x2::value_);
+ field_size = sizeof(Float64x2Layout::value_);
break;
default:
if (field.is_non_nullable_integer()) {
- field_size = sizeof(RawMint::value_);
+ field_size = sizeof(MintLayout::value_);
} else {
UNREACHABLE();
field_size = 0;
@@ -3420,13 +3420,13 @@
entry.Set<Class::kInvocationDispatcherFunction>(dispatcher);
}
-RawFunction* Class::GetInvocationDispatcher(const String& target_name,
- const Array& args_desc,
- RawFunction::Kind kind,
- bool create_if_absent) const {
- ASSERT(kind == RawFunction::kNoSuchMethodDispatcher ||
- kind == RawFunction::kInvokeFieldDispatcher ||
- kind == RawFunction::kDynamicInvocationForwarder);
+FunctionPtr Class::GetInvocationDispatcher(const String& target_name,
+ const Array& args_desc,
+ FunctionLayout::Kind kind,
+ bool create_if_absent) const {
+ ASSERT(kind == FunctionLayout::kNoSuchMethodDispatcher ||
+ kind == FunctionLayout::kInvokeFieldDispatcher ||
+ kind == FunctionLayout::kDynamicInvocationForwarder);
auto Z = Thread::Current()->zone();
auto& function = Function::Handle(Z);
auto& name = String::Handle(Z);
@@ -3454,9 +3454,9 @@
return function.raw();
}
-RawFunction* Class::CreateInvocationDispatcher(const String& target_name,
- const Array& args_desc,
- RawFunction::Kind kind) const {
+FunctionPtr Class::CreateInvocationDispatcher(const String& target_name,
+ const Array& args_desc,
+ FunctionLayout::Kind kind) const {
Thread* thread = Thread::Current();
Zone* zone = thread->zone();
Function& invocation = Function::Handle(
@@ -3519,7 +3519,7 @@
// does not have a getter called M but has a method called M then an extractor
// is created and injected as a getter (under the name get:M) into the class
// owning method M.
-RawFunction* Function::CreateMethodExtractor(const String& getter_name) const {
+FunctionPtr Function::CreateMethodExtractor(const String& getter_name) const {
Thread* thread = Thread::Current();
Zone* zone = thread->zone();
ASSERT(Field::IsGetterName(getter_name));
@@ -3530,7 +3530,7 @@
Function& extractor = Function::Handle(
zone,
Function::New(String::Handle(zone, Symbols::New(thread, getter_name)),
- RawFunction::kMethodExtractor,
+ FunctionLayout::kMethodExtractor,
false, // Not static.
false, // Not const.
is_abstract(),
@@ -3557,7 +3557,7 @@
return extractor.raw();
}
-RawFunction* Function::GetMethodExtractor(const String& getter_name) const {
+FunctionPtr Function::GetMethodExtractor(const String& getter_name) const {
ASSERT(Field::IsGetterName(getter_name));
const Function& closure_function =
Function::Handle(ImplicitClosureFunction());
@@ -3566,7 +3566,7 @@
if (result.IsNull()) {
result = CreateMethodExtractor(getter_name);
}
- ASSERT(result.kind() == RawFunction::kMethodExtractor);
+ ASSERT(result.kind() == FunctionLayout::kMethodExtractor);
return result.raw();
}
@@ -3637,8 +3637,7 @@
return name.StartsWith(Symbols::DynamicPrefix());
}
-RawString* Function::DemangleDynamicInvocationForwarderName(
- const String& name) {
+StringPtr Function::DemangleDynamicInvocationForwarderName(const String& name) {
const intptr_t kDynamicPrefixLength = 4; // "dyn:"
ASSERT(Symbols::DynamicPrefix().Length() == kDynamicPrefixLength);
return Symbols::New(Thread::Current(), name, kDynamicPrefixLength,
@@ -3646,7 +3645,7 @@
}
#if !defined(DART_PRECOMPILED_RUNTIME)
-RawFunction* Function::CreateDynamicInvocationForwarder(
+FunctionPtr Function::CreateDynamicInvocationForwarder(
const String& mangled_name) const {
Thread* thread = Thread::Current();
Zone* zone = thread->zone();
@@ -3660,7 +3659,7 @@
forwarder.set_is_native(false);
// TODO(dartbug.com/37737): Currently, we intentionally keep the recognized
// kind when creating the dynamic invocation forwarder.
- forwarder.set_kind(RawFunction::kDynamicInvocationForwarder);
+ forwarder.set_kind(FunctionLayout::kDynamicInvocationForwarder);
forwarder.set_is_debuggable(false);
// TODO(vegorov) for error reporting reasons it is better to make this
@@ -3687,18 +3686,18 @@
return forwarder.raw();
}
-RawString* Function::CreateDynamicInvocationForwarderName(const String& name) {
+StringPtr Function::CreateDynamicInvocationForwarderName(const String& name) {
return Symbols::FromConcat(Thread::Current(), Symbols::DynamicPrefix(), name);
}
-RawFunction* Function::GetDynamicInvocationForwarder(
+FunctionPtr Function::GetDynamicInvocationForwarder(
const String& mangled_name,
bool allow_add /* = true */) const {
ASSERT(IsDynamicInvocationForwarderName(mangled_name));
const Class& owner = Class::Handle(Owner());
Function& result = Function::Handle(owner.GetInvocationDispatcher(
mangled_name, Array::null_array(),
- RawFunction::kDynamicInvocationForwarder, /*create_if_absent=*/false));
+ FunctionLayout::kDynamicInvocationForwarder, /*create_if_absent=*/false));
if (!result.IsNull()) {
return result.raw();
@@ -3736,7 +3735,7 @@
return subtype->IsSubtypeOf(*supertype, Heap::kOld);
}
-RawArray* Class::invocation_dispatcher_cache() const {
+ArrayPtr Class::invocation_dispatcher_cache() const {
return raw_ptr()->invocation_dispatcher_cache_;
}
@@ -3886,12 +3885,12 @@
// i.e., klass.RareType().
// * For throwing a NSM in a library, we just pass the null instance as
// receiver.
-static RawObject* ThrowNoSuchMethod(const Instance& receiver,
- const String& function_name,
- const Array& arguments,
- const Array& argument_names,
- const InvocationMirror::Level level,
- const InvocationMirror::Kind kind) {
+static ObjectPtr ThrowNoSuchMethod(const Instance& receiver,
+ const String& function_name,
+ const Array& arguments,
+ const Array& argument_names,
+ const InvocationMirror::Level level,
+ const InvocationMirror::Kind kind) {
const Smi& invocation_type =
Smi::Handle(Smi::New(InvocationMirror::EncodeType(level, kind)));
@@ -3912,10 +3911,10 @@
return DartEntry::InvokeFunction(throwNew, args);
}
-static RawObject* ThrowTypeError(const TokenPosition token_pos,
- const Instance& src_value,
- const AbstractType& dst_type,
- const String& dst_name) {
+static ObjectPtr ThrowTypeError(const TokenPosition token_pos,
+ const Instance& src_value,
+ const AbstractType& dst_type,
+ const String& dst_name) {
const Array& args = Array::Handle(Array::New(4));
const Smi& pos = Smi::Handle(Smi::New(token_pos.value()));
args.SetAt(0, pos);
@@ -3931,10 +3930,10 @@
return DartEntry::InvokeFunction(throwNew, args);
}
-RawObject* Class::InvokeGetter(const String& getter_name,
- bool throw_nsm_if_absent,
- bool respect_reflectable,
- bool check_is_entrypoint) const {
+ObjectPtr Class::InvokeGetter(const String& getter_name,
+ bool throw_nsm_if_absent,
+ bool respect_reflectable,
+ bool check_is_entrypoint) const {
Thread* thread = Thread::Current();
Zone* zone = thread->zone();
@@ -3991,10 +3990,10 @@
return field.StaticValue();
}
-RawObject* Class::InvokeSetter(const String& setter_name,
- const Instance& value,
- bool respect_reflectable,
- bool check_is_entrypoint) const {
+ObjectPtr Class::InvokeSetter(const String& setter_name,
+ const Instance& value,
+ bool respect_reflectable,
+ bool check_is_entrypoint) const {
Thread* thread = Thread::Current();
Zone* zone = thread->zone();
@@ -4060,11 +4059,11 @@
return value.raw();
}
-RawObject* Class::Invoke(const String& function_name,
- const Array& args,
- const Array& arg_names,
- bool respect_reflectable,
- bool check_is_entrypoint) const {
+ObjectPtr Class::Invoke(const String& function_name,
+ const Array& args,
+ const Array& arg_names,
+ bool respect_reflectable,
+ bool check_is_entrypoint) const {
Thread* thread = Thread::Current();
Zone* zone = thread->zone();
@@ -4115,7 +4114,7 @@
AbstractType::Handle(zone, RareType()), function_name, args, arg_names,
InvocationMirror::kStatic, InvocationMirror::kMethod);
}
- RawObject* type_error =
+ ObjectPtr type_error =
function.DoArgumentTypesMatch(args, args_descriptor, type_args);
if (type_error != Error::null()) {
return type_error;
@@ -4123,7 +4122,7 @@
return DartEntry::InvokeFunction(function, args, args_descriptor_array);
}
-static RawObject* EvaluateCompiledExpressionHelper(
+static ObjectPtr EvaluateCompiledExpressionHelper(
const ExternalTypedData& kernel_buffer,
const Array& type_definitions,
const String& library_url,
@@ -4131,7 +4130,7 @@
const Array& arguments,
const TypeArguments& type_arguments);
-RawObject* Class::EvaluateCompiledExpression(
+ObjectPtr Class::EvaluateCompiledExpression(
const ExternalTypedData& kernel_buffer,
const Array& type_definitions,
const Array& arguments,
@@ -4169,7 +4168,7 @@
}
// Ensure that top level parsing of the class has been done.
-RawError* Class::EnsureIsFinalized(Thread* thread) const {
+ErrorPtr Class::EnsureIsFinalized(Thread* thread) const {
ASSERT(!IsNull());
// Finalized classes have already been parsed.
if (is_finalized()) {
@@ -4275,11 +4274,11 @@
}
template <class FakeInstance, class TargetFakeInstance>
-RawClass* Class::NewCommon(intptr_t index) {
+ClassPtr Class::NewCommon(intptr_t index) {
ASSERT(Object::class_class() != Class::null());
Class& result = Class::Handle();
{
- RawObject* raw =
+ ObjectPtr raw =
Object::Allocate(Class::kClassId, Class::InstanceSize(), Heap::kOld);
NoSafepointScope no_safepoint;
result ^= raw;
@@ -4311,10 +4310,10 @@
}
template <class FakeInstance, class TargetFakeInstance>
-RawClass* Class::New(intptr_t index,
- Isolate* isolate,
- bool register_class,
- bool is_abstract) {
+ClassPtr Class::New(intptr_t index,
+ Isolate* isolate,
+ bool register_class,
+ bool is_abstract) {
Class& result =
Class::Handle(NewCommon<FakeInstance, TargetFakeInstance>(index));
if (is_abstract) {
@@ -4326,11 +4325,11 @@
return result.raw();
}
-RawClass* Class::New(const Library& lib,
- const String& name,
- const Script& script,
- TokenPosition token_pos,
- bool register_class) {
+ClassPtr Class::New(const Library& lib,
+ const String& name,
+ const Script& script,
+ TokenPosition token_pos,
+ bool register_class) {
Class& result =
Class::Handle(NewCommon<Instance, RTN::Instance>(kIllegalCid));
result.set_library(lib);
@@ -4349,13 +4348,13 @@
return result.raw();
}
-RawClass* Class::NewInstanceClass() {
+ClassPtr Class::NewInstanceClass() {
return Class::New<Instance, RTN::Instance>(kIllegalCid, Isolate::Current());
}
-RawClass* Class::NewNativeWrapper(const Library& library,
- const String& name,
- int field_count) {
+ClassPtr Class::NewNativeWrapper(const Library& library,
+ const String& name,
+ int field_count) {
Class& cls = Class::Handle(library.LookupClass(name));
if (cls.IsNull()) {
cls = New(library, name, Script::Handle(), TokenPosition::kNoSource);
@@ -4365,14 +4364,14 @@
cls.set_super_type(Type::Handle(Type::ObjectType()));
// Compute instance size. First word contains a pointer to a properly
// sized typed array once the first native field has been set.
- const intptr_t host_instance_size = sizeof(RawInstance) + kWordSize;
+ const intptr_t host_instance_size = sizeof(InstanceLayout) + kWordSize;
#if defined(PRECOMPILER)
const intptr_t target_instance_size =
compiler::target::Instance::InstanceSize() +
compiler::target::kWordSize;
#else
const intptr_t target_instance_size =
- sizeof(RawInstance) + compiler::target::kWordSize;
+ sizeof(InstanceLayout) + compiler::target::kWordSize;
#endif
cls.set_instance_size(
RoundedAllocationSize(host_instance_size),
@@ -4390,7 +4389,7 @@
}
}
-RawClass* Class::NewStringClass(intptr_t class_id, Isolate* isolate) {
+ClassPtr Class::NewStringClass(intptr_t class_id, Isolate* isolate) {
intptr_t host_instance_size, target_instance_size;
if (class_id == kOneByteStringCid) {
host_instance_size = OneByteString::InstanceSize();
@@ -4423,7 +4422,7 @@
return result.raw();
}
-RawClass* Class::NewTypedDataClass(intptr_t class_id, Isolate* isolate) {
+ClassPtr Class::NewTypedDataClass(intptr_t class_id, Isolate* isolate) {
ASSERT(IsTypedDataClassId(class_id));
const intptr_t host_instance_size = TypedData::InstanceSize();
const intptr_t target_instance_size =
@@ -4441,7 +4440,7 @@
return result.raw();
}
-RawClass* Class::NewTypedDataViewClass(intptr_t class_id, Isolate* isolate) {
+ClassPtr Class::NewTypedDataViewClass(intptr_t class_id, Isolate* isolate) {
ASSERT(IsTypedDataViewClassId(class_id));
const intptr_t host_instance_size = TypedDataView::InstanceSize();
const intptr_t target_instance_size = compiler::target::RoundedAllocationSize(
@@ -4460,8 +4459,7 @@
return result.raw();
}
-RawClass* Class::NewExternalTypedDataClass(intptr_t class_id,
- Isolate* isolate) {
+ClassPtr Class::NewExternalTypedDataClass(intptr_t class_id, Isolate* isolate) {
ASSERT(IsExternalTypedDataClassId(class_id));
const intptr_t host_instance_size = ExternalTypedData::InstanceSize();
const intptr_t target_instance_size = compiler::target::RoundedAllocationSize(
@@ -4480,7 +4478,7 @@
return result.raw();
}
-RawClass* Class::NewPointerClass(intptr_t class_id, Isolate* isolate) {
+ClassPtr Class::NewPointerClass(intptr_t class_id, Isolate* isolate) {
ASSERT(IsFfiPointerClassId(class_id));
intptr_t host_instance_size = Pointer::InstanceSize();
intptr_t target_instance_size =
@@ -4721,14 +4719,14 @@
void Class::set_is_declaration_loaded() const {
ASSERT(!is_declaration_loaded());
- set_state_bits(ClassLoadingBits::update(RawClass::kDeclarationLoaded,
+ set_state_bits(ClassLoadingBits::update(ClassLayout::kDeclarationLoaded,
raw_ptr()->state_bits_));
}
void Class::set_is_type_finalized() const {
ASSERT(is_declaration_loaded());
ASSERT(!is_type_finalized());
- set_state_bits(ClassLoadingBits::update(RawClass::kTypeFinalized,
+ set_state_bits(ClassLoadingBits::update(ClassLayout::kTypeFinalized,
raw_ptr()->state_bits_));
}
@@ -4767,13 +4765,13 @@
void Class::set_is_finalized() const {
ASSERT(!is_finalized());
- set_state_bits(
- ClassFinalizedBits::update(RawClass::kFinalized, raw_ptr()->state_bits_));
+ set_state_bits(ClassFinalizedBits::update(ClassLayout::kFinalized,
+ raw_ptr()->state_bits_));
}
void Class::set_is_prefinalized() const {
ASSERT(!is_finalized());
- set_state_bits(ClassFinalizedBits::update(RawClass::kPreFinalized,
+ set_state_bits(ClassFinalizedBits::update(ClassLayout::kPreFinalized,
raw_ptr()->state_bits_));
}
@@ -4835,7 +4833,7 @@
StorePointer(&raw_ptr()->direct_subclasses_, GrowableObjectArray::null());
}
-RawArray* Class::constants() const {
+ArrayPtr Class::constants() const {
return raw_ptr()->constants_;
}
@@ -4859,7 +4857,7 @@
StorePointer(&raw_ptr()->declaration_type_, value.raw());
}
-RawType* Class::DeclarationType() const {
+TypePtr Class::DeclarationType() const {
ASSERT(is_declaration_loaded());
if (IsNullClass()) {
return Type::NullType();
@@ -5099,49 +5097,48 @@
return Library::IsPrivate(String::Handle(Name()));
}
-RawFunction* Class::LookupDynamicFunction(const String& name) const {
+FunctionPtr Class::LookupDynamicFunction(const String& name) const {
return LookupFunction(name, kInstance);
}
-RawFunction* Class::LookupDynamicFunctionAllowAbstract(
+FunctionPtr Class::LookupDynamicFunctionAllowAbstract(
const String& name) const {
return LookupFunction(name, kInstanceAllowAbstract);
}
-RawFunction* Class::LookupDynamicFunctionAllowPrivate(
- const String& name) const {
+FunctionPtr Class::LookupDynamicFunctionAllowPrivate(const String& name) const {
return LookupFunctionAllowPrivate(name, kInstance);
}
-RawFunction* Class::LookupStaticFunction(const String& name) const {
+FunctionPtr Class::LookupStaticFunction(const String& name) const {
return LookupFunction(name, kStatic);
}
-RawFunction* Class::LookupStaticFunctionAllowPrivate(const String& name) const {
+FunctionPtr Class::LookupStaticFunctionAllowPrivate(const String& name) const {
return LookupFunctionAllowPrivate(name, kStatic);
}
-RawFunction* Class::LookupConstructor(const String& name) const {
+FunctionPtr Class::LookupConstructor(const String& name) const {
return LookupFunction(name, kConstructor);
}
-RawFunction* Class::LookupConstructorAllowPrivate(const String& name) const {
+FunctionPtr Class::LookupConstructorAllowPrivate(const String& name) const {
return LookupFunctionAllowPrivate(name, kConstructor);
}
-RawFunction* Class::LookupFactory(const String& name) const {
+FunctionPtr Class::LookupFactory(const String& name) const {
return LookupFunction(name, kFactory);
}
-RawFunction* Class::LookupFactoryAllowPrivate(const String& name) const {
+FunctionPtr Class::LookupFactoryAllowPrivate(const String& name) const {
return LookupFunctionAllowPrivate(name, kFactory);
}
-RawFunction* Class::LookupFunction(const String& name) const {
+FunctionPtr Class::LookupFunction(const String& name) const {
return LookupFunction(name, kAny);
}
-RawFunction* Class::LookupFunctionAllowPrivate(const String& name) const {
+FunctionPtr Class::LookupFunctionAllowPrivate(const String& name) const {
return LookupFunctionAllowPrivate(name, kAny);
}
@@ -5169,7 +5166,7 @@
return true;
}
-RawFunction* Class::CheckFunctionType(const Function& func, MemberKind kind) {
+FunctionPtr Class::CheckFunctionType(const Function& func, MemberKind kind) {
if ((kind == kInstance) || (kind == kInstanceAllowAbstract)) {
if (func.IsDynamicFunction(kind == kInstanceAllowAbstract)) {
return func.raw();
@@ -5194,7 +5191,7 @@
return Function::null();
}
-RawFunction* Class::LookupFunction(const String& name, MemberKind kind) const {
+FunctionPtr Class::LookupFunction(const String& name, MemberKind kind) const {
ASSERT(!IsNull());
Thread* thread = Thread::Current();
if (EnsureIsFinalized(thread) != Error::null()) {
@@ -5245,8 +5242,8 @@
return Function::null();
}
-RawFunction* Class::LookupFunctionAllowPrivate(const String& name,
- MemberKind kind) const {
+FunctionPtr Class::LookupFunctionAllowPrivate(const String& name,
+ MemberKind kind) const {
ASSERT(!IsNull());
Thread* thread = Thread::Current();
if (EnsureIsFinalized(thread) != Error::null()) {
@@ -5272,17 +5269,17 @@
return Function::null();
}
-RawFunction* Class::LookupGetterFunction(const String& name) const {
+FunctionPtr Class::LookupGetterFunction(const String& name) const {
return LookupAccessorFunction(kGetterPrefix, kGetterPrefixLength, name);
}
-RawFunction* Class::LookupSetterFunction(const String& name) const {
+FunctionPtr Class::LookupSetterFunction(const String& name) const {
return LookupAccessorFunction(kSetterPrefix, kSetterPrefixLength, name);
}
-RawFunction* Class::LookupAccessorFunction(const char* prefix,
- intptr_t prefix_length,
- const String& name) const {
+FunctionPtr Class::LookupAccessorFunction(const char* prefix,
+ intptr_t prefix_length,
+ const String& name) const {
ASSERT(!IsNull());
Thread* thread = Thread::Current();
if (EnsureIsFinalized(thread) != Error::null()) {
@@ -5308,19 +5305,19 @@
return Function::null();
}
-RawField* Class::LookupInstanceField(const String& name) const {
+FieldPtr Class::LookupInstanceField(const String& name) const {
return LookupField(name, kInstance);
}
-RawField* Class::LookupStaticField(const String& name) const {
+FieldPtr Class::LookupStaticField(const String& name) const {
return LookupField(name, kStatic);
}
-RawField* Class::LookupField(const String& name) const {
+FieldPtr Class::LookupField(const String& name) const {
return LookupField(name, kAny);
}
-RawField* Class::LookupField(const String& name, MemberKind kind) const {
+FieldPtr Class::LookupField(const String& name, MemberKind kind) const {
ASSERT(!IsNull());
Thread* thread = Thread::Current();
if (EnsureIsFinalized(thread) != Error::null()) {
@@ -5367,8 +5364,8 @@
return Field::null();
}
-RawField* Class::LookupFieldAllowPrivate(const String& name,
- bool instance_only) const {
+FieldPtr Class::LookupFieldAllowPrivate(const String& name,
+ bool instance_only) const {
ASSERT(!IsNull());
// Use slow string compare, ignoring privacy name mangling.
Thread* thread = Thread::Current();
@@ -5398,7 +5395,7 @@
return Field::null();
}
-RawField* Class::LookupInstanceFieldAllowPrivate(const String& name) const {
+FieldPtr Class::LookupInstanceFieldAllowPrivate(const String& name) const {
Field& field = Field::Handle(LookupFieldAllowPrivate(name, true));
if (!field.IsNull() && !field.is_static()) {
return field.raw();
@@ -5406,7 +5403,7 @@
return Field::null();
}
-RawField* Class::LookupStaticFieldAllowPrivate(const String& name) const {
+FieldPtr Class::LookupStaticFieldAllowPrivate(const String& name) const {
Field& field = Field::Handle(LookupFieldAllowPrivate(name));
if (!field.IsNull() && field.is_static()) {
return field.raw();
@@ -5493,7 +5490,7 @@
return KeyType::Hash(ObjectType::Cast(key).value());
}
static uword Hash(const KeyType& key) { return key.Hash(); }
- static RawObject* NewKey(const KeyType& obj) {
+ static ObjectPtr NewKey(const KeyType& obj) {
if (obj.key_ != NULL) {
return obj.key_->raw();
} else {
@@ -5508,7 +5505,7 @@
CanonicalMintSet;
// Returns an instance of Double or Double::null().
-RawDouble* Class::LookupCanonicalDouble(Zone* zone, double value) const {
+DoublePtr Class::LookupCanonicalDouble(Zone* zone, double value) const {
ASSERT(this->raw() == Isolate::Current()->object_store()->double_class());
if (this->constants() == Object::empty_array().raw()) return Double::null();
@@ -5520,7 +5517,7 @@
}
// Returns an instance of Mint or Mint::null().
-RawMint* Class::LookupCanonicalMint(Zone* zone, int64_t value) const {
+MintPtr Class::LookupCanonicalMint(Zone* zone, int64_t value) const {
ASSERT(this->raw() == Isolate::Current()->object_store()->mint_class());
if (this->constants() == Object::empty_array().raw()) return Mint::null();
@@ -5572,14 +5569,14 @@
return Instance::Cast(key).CanonicalizeHash();
}
static uword Hash(const CanonicalInstanceKey& key) { return key.Hash(); }
- static RawObject* NewKey(const CanonicalInstanceKey& obj) {
+ static ObjectPtr NewKey(const CanonicalInstanceKey& obj) {
return obj.key_.raw();
}
};
typedef UnorderedHashSet<CanonicalInstanceTraits> CanonicalInstancesSet;
-RawInstance* Class::LookupCanonicalInstance(Zone* zone,
- const Instance& value) const {
+InstancePtr Class::LookupCanonicalInstance(Zone* zone,
+ const Instance& value) const {
ASSERT(this->raw() == value.clazz());
ASSERT(is_finalized() || is_prefinalized());
Instance& canonical_value = Instance::Handle(zone);
@@ -5591,8 +5588,8 @@
return canonical_value.raw();
}
-RawInstance* Class::InsertCanonicalConstant(Zone* zone,
- const Instance& constant) const {
+InstancePtr Class::InsertCanonicalConstant(Zone* zone,
+ const Instance& constant) const {
ASSERT(this->raw() == constant.clazz());
Instance& canonical_value = Instance::Handle(zone);
if (this->constants() == Object::empty_array().raw()) {
@@ -5744,10 +5741,10 @@
return result;
}
-RawTypeArguments* TypeArguments::Prepend(Zone* zone,
- const TypeArguments& other,
- intptr_t other_length,
- intptr_t total_length) const {
+TypeArgumentsPtr TypeArguments::Prepend(Zone* zone,
+ const TypeArguments& other,
+ intptr_t other_length,
+ intptr_t total_length) const {
if (IsNull() && other.IsNull()) {
return TypeArguments::null();
}
@@ -5765,7 +5762,7 @@
return result.Canonicalize();
}
-RawTypeArguments* TypeArguments::ConcatenateTypeParameters(
+TypeArgumentsPtr TypeArguments::ConcatenateTypeParameters(
Zone* zone,
const TypeArguments& other) const {
ASSERT(!IsNull() && !other.IsNull());
@@ -5785,14 +5782,14 @@
return result.raw();
}
-RawString* TypeArguments::Name() const {
+StringPtr TypeArguments::Name() const {
Thread* thread = Thread::Current();
ZoneTextBuffer printer(thread->zone());
PrintSubvectorName(0, Length(), kInternalName, &printer);
return Symbols::New(thread, printer.buffer());
}
-RawString* TypeArguments::UserVisibleName() const {
+StringPtr TypeArguments::UserVisibleName() const {
Thread* thread = Thread::Current();
ZoneTextBuffer printer(thread->zone());
PrintSubvectorName(0, Length(), kUserVisibleName, &printer);
@@ -5945,7 +5942,7 @@
return num;
}
-RawArray* TypeArguments::instantiations() const {
+ArrayPtr TypeArguments::instantiations() const {
return raw_ptr()->instantiations_;
}
@@ -5968,12 +5965,12 @@
return Smi::Value(raw_ptr()->nullability_);
}
-RawAbstractType* TypeArguments::TypeAt(intptr_t index) const {
+AbstractTypePtr TypeArguments::TypeAt(intptr_t index) const {
ASSERT(!IsNull());
return *TypeAddr(index);
}
-RawAbstractType* TypeArguments::TypeAtNullSafe(intptr_t index) const {
+AbstractTypePtr TypeArguments::TypeAtNullSafe(intptr_t index) const {
if (IsNull()) {
// null vector represents infinite list of dynamics
return Type::dynamic_type().raw();
@@ -6185,7 +6182,7 @@
return true;
}
-RawTypeArguments* TypeArguments::InstantiateFrom(
+TypeArgumentsPtr TypeArguments::InstantiateFrom(
const TypeArguments& instantiator_type_arguments,
const TypeArguments& function_type_arguments,
intptr_t num_free_fun_type_params,
@@ -6225,7 +6222,7 @@
return instantiated_array.raw();
}
-RawTypeArguments* TypeArguments::InstantiateAndCanonicalizeFrom(
+TypeArgumentsPtr TypeArguments::InstantiateAndCanonicalizeFrom(
const TypeArguments& instantiator_type_arguments,
const TypeArguments& function_type_arguments) const {
ASSERT(!IsInstantiated());
@@ -6296,15 +6293,15 @@
return result.raw();
}
-RawTypeArguments* TypeArguments::New(intptr_t len, Heap::Space space) {
+TypeArgumentsPtr TypeArguments::New(intptr_t len, Heap::Space space) {
if (len < 0 || len > kMaxElements) {
// This should be caught before we reach here.
FATAL1("Fatal error in TypeArguments::New: invalid len %" Pd "\n", len);
}
TypeArguments& result = TypeArguments::Handle();
{
- RawObject* raw = Object::Allocate(TypeArguments::kClassId,
- TypeArguments::InstanceSize(len), space);
+ ObjectPtr raw = Object::Allocate(TypeArguments::kClassId,
+ TypeArguments::InstanceSize(len), space);
NoSafepointScope no_safepoint;
result ^= raw;
// Length must be set before we start storing into the array.
@@ -6319,7 +6316,7 @@
return result.raw();
}
-RawAbstractType* const* TypeArguments::TypeAddr(intptr_t index) const {
+AbstractTypePtr const* TypeArguments::TypeAddr(intptr_t index) const {
ASSERT((index >= 0) && (index < Length()));
return &raw_ptr()->types()[index];
}
@@ -6331,7 +6328,7 @@
StoreSmi(&raw_ptr()->length_, Smi::New(value));
}
-RawTypeArguments* TypeArguments::Canonicalize(TrailPtr trail) const {
+TypeArgumentsPtr TypeArguments::Canonicalize(TrailPtr trail) const {
if (IsNull() || IsCanonical()) {
ASSERT(IsOld());
return this->raw();
@@ -6436,8 +6433,8 @@
return OS::SCreate(Thread::Current()->zone(), "PatchClass for %s", cls_name);
}
-RawPatchClass* PatchClass::New(const Class& patched_class,
- const Class& origin_class) {
+PatchClassPtr PatchClass::New(const Class& patched_class,
+ const Class& origin_class) {
const PatchClass& result = PatchClass::Handle(PatchClass::New());
result.set_patched_class(patched_class);
result.set_origin_class(origin_class);
@@ -6446,8 +6443,8 @@
return result.raw();
}
-RawPatchClass* PatchClass::New(const Class& patched_class,
- const Script& script) {
+PatchClassPtr PatchClass::New(const Class& patched_class,
+ const Script& script) {
const PatchClass& result = PatchClass::Handle(PatchClass::New());
result.set_patched_class(patched_class);
result.set_origin_class(patched_class);
@@ -6456,11 +6453,11 @@
return result.raw();
}
-RawPatchClass* PatchClass::New() {
+PatchClassPtr PatchClass::New() {
ASSERT(Object::patch_class_class() != Class::null());
- RawObject* raw = Object::Allocate(PatchClass::kClassId,
- PatchClass::InstanceSize(), Heap::kOld);
- return reinterpret_cast<RawPatchClass*>(raw);
+ ObjectPtr raw = Object::Allocate(PatchClass::kClassId,
+ PatchClass::InstanceSize(), Heap::kOld);
+ return static_cast<PatchClassPtr>(raw);
}
void PatchClass::set_patched_class(const Class& value) const {
@@ -6556,11 +6553,11 @@
}
}
switch (kind()) {
- case RawFunction::kDynamicInvocationForwarder:
+ case FunctionLayout::kDynamicInvocationForwarder:
return is_declared_in_bytecode();
- case RawFunction::kImplicitClosureFunction:
- case RawFunction::kIrregexpFunction:
- case RawFunction::kFfiTrampoline:
+ case FunctionLayout::kImplicitClosureFunction:
+ case FunctionLayout::kIrregexpFunction:
+ case FunctionLayout::kFfiTrampoline:
return false;
default:
return true;
@@ -6587,7 +6584,7 @@
}
#endif // !defined(DART_PRECOMPILED_RUNTIME)
-bool Function::HasCode(RawFunction* function) {
+bool Function::HasCode(FunctionPtr function) {
NoSafepointScope no_safepoint;
ASSERT(function->ptr()->code_ != Code::null());
#if defined(DART_PRECOMPILED_RUNTIME)
@@ -6707,7 +6704,7 @@
#endif
}
-RawContextScope* Function::context_scope() const {
+ContextScopePtr Function::context_scope() const {
if (IsClosureFunction()) {
const Object& obj = Object::Handle(raw_ptr()->data_);
ASSERT(!obj.IsNull());
@@ -6726,7 +6723,7 @@
UNREACHABLE();
}
-RawInstance* Function::implicit_static_closure() const {
+InstancePtr Function::implicit_static_closure() const {
if (IsImplicitStaticClosureFunction()) {
const Object& obj = Object::Handle(raw_ptr()->data_);
ASSERT(!obj.IsNull());
@@ -6745,7 +6742,7 @@
UNREACHABLE();
}
-RawScript* Function::eval_script() const {
+ScriptPtr Function::eval_script() const {
const Object& obj = Object::Handle(raw_ptr()->data_);
if (obj.IsScript()) {
return Script::Cast(obj).raw();
@@ -6759,53 +6756,53 @@
set_data(script);
}
-RawFunction* Function::extracted_method_closure() const {
- ASSERT(kind() == RawFunction::kMethodExtractor);
+FunctionPtr Function::extracted_method_closure() const {
+ ASSERT(kind() == FunctionLayout::kMethodExtractor);
const Object& obj = Object::Handle(raw_ptr()->data_);
ASSERT(obj.IsFunction());
return Function::Cast(obj).raw();
}
void Function::set_extracted_method_closure(const Function& value) const {
- ASSERT(kind() == RawFunction::kMethodExtractor);
+ ASSERT(kind() == FunctionLayout::kMethodExtractor);
ASSERT(raw_ptr()->data_ == Object::null());
set_data(value);
}
-RawArray* Function::saved_args_desc() const {
- ASSERT(kind() == RawFunction::kNoSuchMethodDispatcher ||
- kind() == RawFunction::kInvokeFieldDispatcher);
+ArrayPtr Function::saved_args_desc() const {
+ ASSERT(kind() == FunctionLayout::kNoSuchMethodDispatcher ||
+ kind() == FunctionLayout::kInvokeFieldDispatcher);
const Object& obj = Object::Handle(raw_ptr()->data_);
ASSERT(obj.IsArray());
return Array::Cast(obj).raw();
}
void Function::set_saved_args_desc(const Array& value) const {
- ASSERT(kind() == RawFunction::kNoSuchMethodDispatcher ||
- kind() == RawFunction::kInvokeFieldDispatcher);
+ ASSERT(kind() == FunctionLayout::kNoSuchMethodDispatcher ||
+ kind() == FunctionLayout::kInvokeFieldDispatcher);
ASSERT(raw_ptr()->data_ == Object::null());
set_data(value);
}
-RawField* Function::accessor_field() const {
- ASSERT(kind() == RawFunction::kImplicitGetter ||
- kind() == RawFunction::kImplicitSetter ||
- kind() == RawFunction::kImplicitStaticGetter ||
- kind() == RawFunction::kFieldInitializer);
+FieldPtr Function::accessor_field() const {
+ ASSERT(kind() == FunctionLayout::kImplicitGetter ||
+ kind() == FunctionLayout::kImplicitSetter ||
+ kind() == FunctionLayout::kImplicitStaticGetter ||
+ kind() == FunctionLayout::kFieldInitializer);
return Field::RawCast(raw_ptr()->data_);
}
void Function::set_accessor_field(const Field& value) const {
- ASSERT(kind() == RawFunction::kImplicitGetter ||
- kind() == RawFunction::kImplicitSetter ||
- kind() == RawFunction::kImplicitStaticGetter ||
- kind() == RawFunction::kFieldInitializer);
+ ASSERT(kind() == FunctionLayout::kImplicitGetter ||
+ kind() == FunctionLayout::kImplicitSetter ||
+ kind() == FunctionLayout::kImplicitStaticGetter ||
+ kind() == FunctionLayout::kFieldInitializer);
// Top level classes may be finalized multiple times.
ASSERT(raw_ptr()->data_ == Object::null() || raw_ptr()->data_ == value.raw());
set_data(value);
}
-RawFunction* Function::parent_function() const {
+FunctionPtr Function::parent_function() const {
if (IsClosureFunction() || IsSignatureFunction()) {
const Object& obj = Object::Handle(raw_ptr()->data_);
ASSERT(!obj.IsNull());
@@ -6830,8 +6827,8 @@
}
// Enclosing outermost function of this local function.
-RawFunction* Function::GetOutermostFunction() const {
- RawFunction* parent = parent_function();
+FunctionPtr Function::GetOutermostFunction() const {
+ FunctionPtr parent = parent_function();
if (parent == Object::null()) {
return raw();
}
@@ -6859,7 +6856,7 @@
return false;
}
-RawFunction* Function::implicit_closure_function() const {
+FunctionPtr Function::implicit_closure_function() const {
if (IsClosureFunction() || IsSignatureFunction() || IsFactory() ||
IsDispatcherOrImplicitAccessor() || IsFieldInitializer()) {
return Function::null();
@@ -6897,7 +6894,7 @@
}
}
-RawType* Function::ExistingSignatureType() const {
+TypePtr Function::ExistingSignatureType() const {
const Object& obj = Object::Handle(raw_ptr()->data_);
ASSERT(!obj.IsNull());
if (IsSignatureFunction()) {
@@ -6917,7 +6914,7 @@
FfiTrampolineData::Cast(obj).set_c_signature(sig);
}
-RawFunction* Function::FfiCSignature() const {
+FunctionPtr Function::FfiCSignature() const {
ASSERT(IsFfiTrampoline());
const Object& obj = Object::Handle(raw_ptr()->data_);
ASSERT(!obj.IsNull());
@@ -6938,7 +6935,7 @@
FfiTrampolineData::Cast(obj).set_callback_id(value);
}
-RawFunction* Function::FfiCallbackTarget() const {
+FunctionPtr Function::FfiCallbackTarget() const {
ASSERT(IsFfiTrampoline());
const Object& obj = Object::Handle(raw_ptr()->data_);
ASSERT(!obj.IsNull());
@@ -6952,7 +6949,7 @@
FfiTrampolineData::Cast(obj).set_callback_target(target);
}
-RawInstance* Function::FfiCallbackExceptionalReturn() const {
+InstancePtr Function::FfiCallbackExceptionalReturn() const {
ASSERT(IsFfiTrampoline());
const Object& obj = Object::Handle(raw_ptr()->data_);
ASSERT(!obj.IsNull());
@@ -6966,7 +6963,7 @@
FfiTrampolineData::Cast(obj).set_callback_exceptional_return(value);
}
-RawType* Function::SignatureType(Nullability nullability) const {
+TypePtr Function::SignatureType(Nullability nullability) const {
Type& type = Type::Handle(ExistingSignatureType());
if (type.IsNull()) {
// The function type of this function is not yet cached and needs to be
@@ -7030,7 +7027,7 @@
return true;
}
-RawType* Function::RedirectionType() const {
+TypePtr Function::RedirectionType() const {
ASSERT(IsRedirectingFactory());
ASSERT(!is_native());
const Object& obj = Object::Handle(raw_ptr()->data_);
@@ -7038,8 +7035,8 @@
return RedirectionData::Cast(obj).type();
}
-const char* Function::KindToCString(RawFunction::Kind kind) {
- return RawFunction::KindToCString(kind);
+const char* Function::KindToCString(FunctionLayout::Kind kind) {
+ return FunctionLayout::KindToCString(kind);
}
void Function::SetRedirectionType(const Type& type) const {
@@ -7052,7 +7049,7 @@
RedirectionData::Cast(obj).set_type(type);
}
-RawString* Function::RedirectionIdentifier() const {
+StringPtr Function::RedirectionIdentifier() const {
ASSERT(IsRedirectingFactory());
const Object& obj = Object::Handle(raw_ptr()->data_);
ASSERT(!obj.IsNull());
@@ -7069,7 +7066,7 @@
RedirectionData::Cast(obj).set_identifier(identifier);
}
-RawFunction* Function::RedirectionTarget() const {
+FunctionPtr Function::RedirectionTarget() const {
ASSERT(IsRedirectingFactory());
const Object& obj = Object::Handle(raw_ptr()->data_);
ASSERT(!obj.IsNull());
@@ -7086,15 +7083,15 @@
RedirectionData::Cast(obj).set_target(target);
}
-RawFunction* Function::ForwardingTarget() const {
- ASSERT(kind() == RawFunction::kDynamicInvocationForwarder);
+FunctionPtr Function::ForwardingTarget() const {
+ ASSERT(kind() == FunctionLayout::kDynamicInvocationForwarder);
Array& checks = Array::Handle();
checks ^= raw_ptr()->data_;
return Function::RawCast(checks.At(0));
}
void Function::SetForwardingChecks(const Array& checks) const {
- ASSERT(kind() == RawFunction::kDynamicInvocationForwarder);
+ ASSERT(kind() == FunctionLayout::kDynamicInvocationForwarder);
ASSERT(checks.Length() >= 1);
ASSERT(Object::Handle(checks.At(0)).IsFunction());
set_data(checks);
@@ -7149,24 +7146,24 @@
StorePointer(&raw_ptr()->owner_, value.raw());
}
-RawRegExp* Function::regexp() const {
- ASSERT(kind() == RawFunction::kIrregexpFunction);
+RegExpPtr Function::regexp() const {
+ ASSERT(kind() == FunctionLayout::kIrregexpFunction);
const Array& pair = Array::Cast(Object::Handle(raw_ptr()->data_));
return RegExp::RawCast(pair.At(0));
}
class StickySpecialization : public BitField<intptr_t, bool, 0, 1> {};
class StringSpecializationCid
- : public BitField<intptr_t, intptr_t, 1, RawObject::kClassIdTagSize> {};
+ : public BitField<intptr_t, intptr_t, 1, ObjectLayout::kClassIdTagSize> {};
intptr_t Function::string_specialization_cid() const {
- ASSERT(kind() == RawFunction::kIrregexpFunction);
+ ASSERT(kind() == FunctionLayout::kIrregexpFunction);
const Array& pair = Array::Cast(Object::Handle(raw_ptr()->data_));
return StringSpecializationCid::decode(Smi::Value(Smi::RawCast(pair.At(1))));
}
bool Function::is_sticky_specialization() const {
- ASSERT(kind() == RawFunction::kIrregexpFunction);
+ ASSERT(kind() == FunctionLayout::kIrregexpFunction);
const Array& pair = Array::Cast(Object::Handle(raw_ptr()->data_));
return StickySpecialization::decode(Smi::Value(Smi::RawCast(pair.At(1))));
}
@@ -7174,7 +7171,7 @@
void Function::SetRegExpData(const RegExp& regexp,
intptr_t string_specialization_cid,
bool sticky) const {
- ASSERT(kind() == RawFunction::kIrregexpFunction);
+ ASSERT(kind() == FunctionLayout::kIrregexpFunction);
ASSERT(IsStringClassId(string_specialization_cid));
ASSERT(raw_ptr()->data_ == Object::null());
const Array& pair = Array::Handle(Array::New(2, Heap::kOld));
@@ -7185,7 +7182,7 @@
set_data(pair);
}
-RawString* Function::native_name() const {
+StringPtr Function::native_name() const {
ASSERT(is_native());
const Object& obj = Object::Handle(raw_ptr()->data_);
ASSERT(obj.IsArray());
@@ -7221,7 +7218,7 @@
StorePointer(&raw_ptr()->result_type_, value.raw());
}
-RawAbstractType* Function::ParameterTypeAt(intptr_t index) const {
+AbstractTypePtr Function::ParameterTypeAt(intptr_t index) const {
const Array& parameter_types = Array::Handle(raw_ptr()->parameter_types_);
return AbstractType::RawCast(parameter_types.At(index));
}
@@ -7230,7 +7227,7 @@
const AbstractType& value) const {
ASSERT(!value.IsNull());
// Method extractor parameters are shared and are in the VM heap.
- ASSERT(kind() != RawFunction::kMethodExtractor);
+ ASSERT(kind() != FunctionLayout::kMethodExtractor);
const Array& parameter_types = Array::Handle(raw_ptr()->parameter_types_);
parameter_types.SetAt(index, value);
}
@@ -7239,7 +7236,7 @@
StorePointer(&raw_ptr()->parameter_types_, value.raw());
}
-RawString* Function::ParameterNameAt(intptr_t index) const {
+StringPtr Function::ParameterNameAt(intptr_t index) const {
const Array& parameter_names = Array::Handle(raw_ptr()->parameter_names_);
return String::RawCast(parameter_names.At(index));
}
@@ -7279,7 +7276,7 @@
if (flag_index >= parameter_names.Length()) {
return false;
}
- RawObject* element = parameter_names.At(flag_index);
+ ObjectPtr element = parameter_names.At(flag_index);
if (element == Object::null()) {
return false;
}
@@ -7293,7 +7290,7 @@
const Array& parameter_names = Array::Handle(raw_ptr()->parameter_names_);
ASSERT(flag_index < parameter_names.Length());
intptr_t flag;
- RawObject* element = parameter_names.At(flag_index);
+ ObjectPtr element = parameter_names.At(flag_index);
if (element == Object::null()) {
flag = 0;
} else {
@@ -7358,9 +7355,8 @@
}
}
-RawTypeParameter* Function::LookupTypeParameter(
- const String& type_name,
- intptr_t* function_level) const {
+TypeParameterPtr Function::LookupTypeParameter(const String& type_name,
+ intptr_t* function_level) const {
ASSERT(!type_name.IsNull());
Thread* thread = Thread::Current();
REUSABLE_TYPE_ARGUMENTS_HANDLESCOPE(thread);
@@ -7398,11 +7394,11 @@
return TypeParameter::null();
}
-void Function::set_kind(RawFunction::Kind value) const {
+void Function::set_kind(FunctionLayout::Kind value) const {
set_kind_tag(KindBits::update(value, raw_ptr()->kind_tag_));
}
-void Function::set_modifier(RawFunction::AsyncModifier value) const {
+void Function::set_modifier(FunctionLayout::AsyncModifier value) const {
set_kind_tag(ModifierBits::update(value, raw_ptr()->kind_tag_));
}
@@ -7431,20 +7427,20 @@
void Function::set_num_fixed_parameters(intptr_t value) const {
ASSERT(value >= 0);
- ASSERT(Utils::IsUint(RawFunction::kMaxFixedParametersBits, value));
+ ASSERT(Utils::IsUint(FunctionLayout::kMaxFixedParametersBits, value));
const uint32_t* original = &raw_ptr()->packed_fields_;
- StoreNonPointer(original, RawFunction::PackedNumFixedParameters::update(
+ StoreNonPointer(original, FunctionLayout::PackedNumFixedParameters::update(
value, *original));
}
void Function::SetNumOptionalParameters(intptr_t value,
bool are_optional_positional) const {
- ASSERT(Utils::IsUint(RawFunction::kMaxOptionalParametersBits, value));
+ ASSERT(Utils::IsUint(FunctionLayout::kMaxOptionalParametersBits, value));
uint32_t packed_fields = raw_ptr()->packed_fields_;
- packed_fields = RawFunction::PackedHasNamedOptionalParameters::update(
+ packed_fields = FunctionLayout::PackedHasNamedOptionalParameters::update(
!are_optional_positional, packed_fields);
packed_fields =
- RawFunction::PackedNumOptionalParameters::update(value, packed_fields);
+ FunctionLayout::PackedNumOptionalParameters::update(value, packed_fields);
set_packed_fields(packed_fields);
}
@@ -7505,24 +7501,24 @@
}
intptr_t Function::NumImplicitParameters() const {
- const RawFunction::Kind k = kind();
- if (k == RawFunction::kConstructor) {
+ const FunctionLayout::Kind k = kind();
+ if (k == FunctionLayout::kConstructor) {
// Type arguments for factory; instance for generative constructor.
return 1;
}
- if ((k == RawFunction::kClosureFunction) ||
- (k == RawFunction::kImplicitClosureFunction) ||
- (k == RawFunction::kSignatureFunction) ||
- (k == RawFunction::kFfiTrampoline)) {
+ if ((k == FunctionLayout::kClosureFunction) ||
+ (k == FunctionLayout::kImplicitClosureFunction) ||
+ (k == FunctionLayout::kSignatureFunction) ||
+ (k == FunctionLayout::kFfiTrampoline)) {
return 1; // Closure object.
}
if (!is_static()) {
// Closure functions defined inside instance (i.e. non-static) functions are
// marked as non-static, but they do not have a receiver.
// Closures are handled above.
- ASSERT((k != RawFunction::kClosureFunction) &&
- (k != RawFunction::kImplicitClosureFunction) &&
- (k != RawFunction::kSignatureFunction));
+ ASSERT((k != FunctionLayout::kClosureFunction) &&
+ (k != FunctionLayout::kImplicitClosureFunction) &&
+ (k != FunctionLayout::kSignatureFunction));
return 1; // Receiver.
}
return 0; // No implicit parameters.
@@ -7686,7 +7682,7 @@
return true;
}
-RawObject* Function::DoArgumentTypesMatch(
+ObjectPtr Function::DoArgumentTypesMatch(
const Array& args,
const ArgumentsDescriptor& args_desc,
const TypeArguments& instantiator_type_args) const {
@@ -7859,7 +7855,7 @@
return chars;
}
-RawFunction* Function::InstantiateSignatureFrom(
+FunctionPtr Function::InstantiateSignatureFrom(
const TypeArguments& instantiator_type_arguments,
const TypeArguments& function_type_arguments,
intptr_t num_free_fun_type_params,
@@ -8155,32 +8151,32 @@
return IsGenerativeConstructor() && (token_pos() == end_token_pos());
}
-bool Function::IsImplicitStaticClosureFunction(RawFunction* func) {
+bool Function::IsImplicitStaticClosureFunction(FunctionPtr func) {
NoSafepointScope no_safepoint;
uint32_t kind_tag = func->ptr()->kind_tag_;
return (KindBits::decode(kind_tag) ==
- RawFunction::kImplicitClosureFunction) &&
+ FunctionLayout::kImplicitClosureFunction) &&
StaticBit::decode(kind_tag);
}
-RawFunction* Function::New(Heap::Space space) {
+FunctionPtr Function::New(Heap::Space space) {
ASSERT(Object::function_class() != Class::null());
- RawObject* raw =
+ ObjectPtr raw =
Object::Allocate(Function::kClassId, Function::InstanceSize(), space);
- return reinterpret_cast<RawFunction*>(raw);
+ return static_cast<FunctionPtr>(raw);
}
-RawFunction* Function::New(const String& name,
- RawFunction::Kind kind,
- bool is_static,
- bool is_const,
- bool is_abstract,
- bool is_external,
- bool is_native,
- const Object& owner,
- TokenPosition token_pos,
- Heap::Space space) {
- ASSERT(!owner.IsNull() || (kind == RawFunction::kSignatureFunction));
+FunctionPtr Function::New(const String& name,
+ FunctionLayout::Kind kind,
+ bool is_static,
+ bool is_const,
+ bool is_abstract,
+ bool is_external,
+ bool is_native,
+ const Object& owner,
+ TokenPosition token_pos,
+ Heap::Space space) {
+ ASSERT(!owner.IsNull() || (kind == FunctionLayout::kSignatureFunction));
const Function& result = Function::Handle(Function::New(space));
result.set_kind_tag(0);
result.set_parameter_types(Object::empty_array());
@@ -8189,7 +8185,7 @@
result.set_kind_tag(0); // Ensure determinism of uninitialized bits.
result.set_kind(kind);
result.set_recognized_kind(MethodRecognizer::kUnknown);
- result.set_modifier(RawFunction::kNoModifier);
+ result.set_modifier(FunctionLayout::kNoModifier);
result.set_is_static(is_static);
result.set_is_const(is_const);
result.set_is_abstract(is_abstract);
@@ -8222,16 +8218,16 @@
result.set_is_inlinable(true);
result.reset_unboxed_parameters_and_return();
result.SetInstructionsSafe(StubCode::LazyCompile());
- if (kind == RawFunction::kClosureFunction ||
- kind == RawFunction::kImplicitClosureFunction) {
+ if (kind == FunctionLayout::kClosureFunction ||
+ kind == FunctionLayout::kImplicitClosureFunction) {
ASSERT(space == Heap::kOld);
const ClosureData& data = ClosureData::Handle(ClosureData::New());
result.set_data(data);
- } else if (kind == RawFunction::kSignatureFunction) {
+ } else if (kind == FunctionLayout::kSignatureFunction) {
const SignatureData& data =
SignatureData::Handle(SignatureData::New(space));
result.set_data(data);
- } else if (kind == RawFunction::kFfiTrampoline) {
+ } else if (kind == FunctionLayout::kFfiTrampoline) {
const FfiTrampolineData& data =
FfiTrampolineData::Handle(FfiTrampolineData::New());
result.set_data(data);
@@ -8250,13 +8246,13 @@
return result.raw();
}
-RawFunction* Function::NewClosureFunctionWithKind(RawFunction::Kind kind,
- const String& name,
- const Function& parent,
- TokenPosition token_pos,
- const Object& owner) {
- ASSERT((kind == RawFunction::kClosureFunction) ||
- (kind == RawFunction::kImplicitClosureFunction));
+FunctionPtr Function::NewClosureFunctionWithKind(FunctionLayout::Kind kind,
+ const String& name,
+ const Function& parent,
+ TokenPosition token_pos,
+ const Object& owner) {
+ ASSERT((kind == FunctionLayout::kClosureFunction) ||
+ (kind == FunctionLayout::kImplicitClosureFunction));
ASSERT(!parent.IsNull());
ASSERT(!owner.IsNull());
const Function& result = Function::Handle(
@@ -8270,30 +8266,30 @@
return result.raw();
}
-RawFunction* Function::NewClosureFunction(const String& name,
- const Function& parent,
- TokenPosition token_pos) {
+FunctionPtr Function::NewClosureFunction(const String& name,
+ const Function& parent,
+ TokenPosition token_pos) {
// Use the owner defining the parent function and not the class containing it.
const Object& parent_owner = Object::Handle(parent.RawOwner());
- return NewClosureFunctionWithKind(RawFunction::kClosureFunction, name, parent,
- token_pos, parent_owner);
-}
-
-RawFunction* Function::NewImplicitClosureFunction(const String& name,
- const Function& parent,
- TokenPosition token_pos) {
- // Use the owner defining the parent function and not the class containing it.
- const Object& parent_owner = Object::Handle(parent.RawOwner());
- return NewClosureFunctionWithKind(RawFunction::kImplicitClosureFunction, name,
+ return NewClosureFunctionWithKind(FunctionLayout::kClosureFunction, name,
parent, token_pos, parent_owner);
}
-RawFunction* Function::NewSignatureFunction(const Object& owner,
- const Function& parent,
- TokenPosition token_pos,
- Heap::Space space) {
+FunctionPtr Function::NewImplicitClosureFunction(const String& name,
+ const Function& parent,
+ TokenPosition token_pos) {
+ // Use the owner defining the parent function and not the class containing it.
+ const Object& parent_owner = Object::Handle(parent.RawOwner());
+ return NewClosureFunctionWithKind(FunctionLayout::kImplicitClosureFunction,
+ name, parent, token_pos, parent_owner);
+}
+
+FunctionPtr Function::NewSignatureFunction(const Object& owner,
+ const Function& parent,
+ TokenPosition token_pos,
+ Heap::Space space) {
const Function& result = Function::Handle(Function::New(
- Symbols::AnonymousSignature(), RawFunction::kSignatureFunction,
+ Symbols::AnonymousSignature(), FunctionLayout::kSignatureFunction,
/* is_static = */ false,
/* is_const = */ false,
/* is_abstract = */ false,
@@ -8308,15 +8304,15 @@
return result.raw();
}
-RawFunction* Function::NewEvalFunction(const Class& owner,
- const Script& script,
- bool is_static) {
+FunctionPtr Function::NewEvalFunction(const Class& owner,
+ const Script& script,
+ bool is_static) {
Thread* thread = Thread::Current();
Zone* zone = thread->zone();
const Function& result = Function::Handle(
zone,
Function::New(String::Handle(Symbols::New(thread, ":Eval")),
- RawFunction::kRegularFunction, is_static,
+ FunctionLayout::kRegularFunction, is_static,
/* is_const = */ false,
/* is_abstract = */ false,
/* is_external = */ false,
@@ -8336,7 +8332,7 @@
#endif
}
-RawFunction* Function::ImplicitClosureFunction() const {
+FunctionPtr Function::ImplicitClosureFunction() const {
// Return the existing implicit closure function if any.
if (implicit_closure_function() != Function::null()) {
return implicit_closure_function();
@@ -8455,14 +8451,14 @@
}
}
-RawString* Function::Signature() const {
+StringPtr Function::Signature() const {
Thread* thread = Thread::Current();
ZoneTextBuffer printer(thread->zone());
PrintSignature(kInternalName, &printer);
return Symbols::New(thread, printer.buffer());
}
-RawString* Function::UserVisibleSignature() const {
+StringPtr Function::UserVisibleSignature() const {
Thread* thread = Thread::Current();
ZoneTextBuffer printer(thread->zone());
PrintSignature(kUserVisibleName, &printer);
@@ -8527,7 +8523,7 @@
}
}
-RawInstance* Function::ImplicitStaticClosure() const {
+InstancePtr Function::ImplicitStaticClosure() const {
ASSERT(IsImplicitStaticClosureFunction());
if (implicit_static_closure() == Instance::null()) {
Zone* zone = Thread::Current()->zone();
@@ -8541,7 +8537,7 @@
return implicit_static_closure();
}
-RawInstance* Function::ImplicitInstanceClosure(const Instance& receiver) const {
+InstancePtr Function::ImplicitInstanceClosure(const Instance& receiver) const {
ASSERT(IsImplicitClosureFunction());
Zone* zone = Thread::Current()->zone();
const Context& context = Context::Handle(zone, Context::New(1));
@@ -8647,7 +8643,7 @@
return true;
}
-RawClass* Function::Owner() const {
+ClassPtr Function::Owner() const {
if (raw_ptr()->owner_ == Object::null()) {
ASSERT(IsSignatureFunction());
return Class::null();
@@ -8660,7 +8656,7 @@
return PatchClass::Cast(obj).patched_class();
}
-RawClass* Function::origin() const {
+ClassPtr Function::origin() const {
if (raw_ptr()->owner_ == Object::null()) {
ASSERT(IsSignatureFunction());
return Class::null();
@@ -8705,7 +8701,7 @@
set_data(data_field);
}
-RawScript* Function::script() const {
+ScriptPtr Function::script() const {
// NOTE(turnidge): If you update this function, you probably want to
// update Class::PatchFieldsAndFunctions() at the same time.
Object& data = Object::Handle(raw_ptr()->data_);
@@ -8738,7 +8734,7 @@
return Class::Cast(obj).script();
}
-RawExternalTypedData* Function::KernelData() const {
+ExternalTypedDataPtr Function::KernelData() const {
Object& data = Object::Handle(raw_ptr()->data_);
if (data.IsArray()) {
Object& script = Object::Handle(Array::Cast(data).At(0));
@@ -8807,7 +8803,7 @@
return String::ScrubName(String::Handle(name()), is_extension_member());
}
-RawString* Function::UserVisibleName() const {
+StringPtr Function::UserVisibleName() const {
if (FLAG_show_internal_names) {
return name();
}
@@ -8816,14 +8812,14 @@
String::ScrubName(String::Handle(name()), is_extension_member()));
}
-RawString* Function::QualifiedScrubbedName() const {
+StringPtr Function::QualifiedScrubbedName() const {
Thread* thread = Thread::Current();
ZoneTextBuffer printer(thread->zone());
PrintQualifiedName(kScrubbedName, &printer);
return Symbols::New(thread, printer.buffer());
}
-RawString* Function::QualifiedUserVisibleName() const {
+StringPtr Function::QualifiedUserVisibleName() const {
Thread* thread = Thread::Current();
ZoneTextBuffer printer(thread->zone());
PrintQualifiedName(kUserVisibleName, &printer);
@@ -8865,7 +8861,7 @@
}
const Class& cls = Class::Handle(Owner());
if (!cls.IsTopLevel()) {
- if (fun.kind() == RawFunction::kConstructor) {
+ if (fun.kind() == FunctionLayout::kConstructor) {
printer->AddString("new ");
} else {
const Class& mixin = Class::Handle(cls.Mixin());
@@ -8879,7 +8875,7 @@
printer->AddString(fun.UserVisibleNameCString());
}
-RawString* Function::GetSource() const {
+StringPtr Function::GetSource() const {
if (IsImplicitConstructor() || IsSignatureFunction() || is_synthetic()) {
// We may need to handle more cases when the restrictions on mixins are
// relaxed. In particular we might start associating some source with the
@@ -9007,12 +9003,12 @@
}
void Function::set_ic_data_array(const Array& value) const {
- StorePointer<RawArray*, std::memory_order_release>(&raw_ptr()->ic_data_array_,
- value.raw());
+ StorePointer<ArrayPtr, std::memory_order_release>(&raw_ptr()->ic_data_array_,
+ value.raw());
}
-RawArray* Function::ic_data_array() const {
- return LoadPointer<RawArray*, std::memory_order_acquire>(
+ArrayPtr Function::ic_data_array() const {
+ return LoadPointer<ArrayPtr, std::memory_order_acquire>(
&raw_ptr()->ic_data_array_);
}
@@ -9020,7 +9016,7 @@
set_ic_data_array(Array::null_array());
}
-RawICData* Function::FindICData(intptr_t deopt_id) const {
+ICDataPtr Function::FindICData(intptr_t deopt_id) const {
const Array& array = Array::Handle(ic_data_array());
ICData& ic_data = ICData::Handle();
for (intptr_t i = 1; i < array.Length(); i++) {
@@ -9083,7 +9079,7 @@
return true;
}
-RawCode* Function::EnsureHasCode() const {
+CodePtr Function::EnsureHasCode() const {
if (HasCode()) return CurrentCode();
Thread* thread = Thread::Current();
ASSERT(thread->IsMutatorThread());
@@ -9156,47 +9152,47 @@
const char* kind_str = NULL;
const char* const_str = is_const() ? " const" : "";
switch (kind()) {
- case RawFunction::kRegularFunction:
- case RawFunction::kClosureFunction:
- case RawFunction::kImplicitClosureFunction:
- case RawFunction::kGetterFunction:
- case RawFunction::kSetterFunction:
+ case FunctionLayout::kRegularFunction:
+ case FunctionLayout::kClosureFunction:
+ case FunctionLayout::kImplicitClosureFunction:
+ case FunctionLayout::kGetterFunction:
+ case FunctionLayout::kSetterFunction:
kind_str = "";
break;
- case RawFunction::kSignatureFunction:
+ case FunctionLayout::kSignatureFunction:
kind_str = " signature";
break;
- case RawFunction::kConstructor:
+ case FunctionLayout::kConstructor:
kind_str = is_static() ? " factory" : " constructor";
break;
- case RawFunction::kImplicitGetter:
+ case FunctionLayout::kImplicitGetter:
kind_str = " getter";
break;
- case RawFunction::kImplicitSetter:
+ case FunctionLayout::kImplicitSetter:
kind_str = " setter";
break;
- case RawFunction::kImplicitStaticGetter:
+ case FunctionLayout::kImplicitStaticGetter:
kind_str = " static-getter";
break;
- case RawFunction::kFieldInitializer:
+ case FunctionLayout::kFieldInitializer:
kind_str = " field-initializer";
break;
- case RawFunction::kMethodExtractor:
+ case FunctionLayout::kMethodExtractor:
kind_str = " method-extractor";
break;
- case RawFunction::kNoSuchMethodDispatcher:
+ case FunctionLayout::kNoSuchMethodDispatcher:
kind_str = " no-such-method-dispatcher";
break;
- case RawFunction::kDynamicInvocationForwarder:
+ case FunctionLayout::kDynamicInvocationForwarder:
kind_str = " dynamic-invocation-forwarder";
break;
- case RawFunction::kInvokeFieldDispatcher:
+ case FunctionLayout::kInvokeFieldDispatcher:
kind_str = " invoke-field-dispatcher";
break;
- case RawFunction::kIrregexpFunction:
+ case FunctionLayout::kIrregexpFunction:
kind_str = " irregexp-function";
break;
- case RawFunction::kFfiTrampoline:
+ case FunctionLayout::kFfiTrampoline:
kind_str = " ffi-trampoline-function";
break;
default:
@@ -9226,11 +9222,11 @@
StorePointer(&raw_ptr()->signature_type_, value.raw());
}
-RawClosureData* ClosureData::New() {
+ClosureDataPtr ClosureData::New() {
ASSERT(Object::closure_data_class() != Class::null());
- RawObject* raw = Object::Allocate(ClosureData::kClassId,
- ClosureData::InstanceSize(), Heap::kOld);
- return reinterpret_cast<RawClosureData*>(raw);
+ ObjectPtr raw = Object::Allocate(ClosureData::kClassId,
+ ClosureData::InstanceSize(), Heap::kOld);
+ return static_cast<ClosureDataPtr>(raw);
}
const char* ClosureData::ToCString() const {
@@ -9243,10 +9239,10 @@
"ClosureData: context_scope: 0x%" Px
" parent_function: %s signature_type: %s"
" implicit_static_closure: 0x%" Px,
- reinterpret_cast<uword>(context_scope()),
+ static_cast<uword>(context_scope()),
parent.IsNull() ? "null" : parent.ToCString(),
type.IsNull() ? "null" : type.ToCString(),
- reinterpret_cast<uword>(implicit_static_closure()));
+ static_cast<uword>(implicit_static_closure()));
}
void SignatureData::set_parent_function(const Function& value) const {
@@ -9257,11 +9253,11 @@
StorePointer(&raw_ptr()->signature_type_, value.raw());
}
-RawSignatureData* SignatureData::New(Heap::Space space) {
+SignatureDataPtr SignatureData::New(Heap::Space space) {
ASSERT(Object::signature_data_class() != Class::null());
- RawObject* raw = Object::Allocate(SignatureData::kClassId,
- SignatureData::InstanceSize(), space);
- return reinterpret_cast<RawSignatureData*>(raw);
+ ObjectPtr raw = Object::Allocate(SignatureData::kClassId,
+ SignatureData::InstanceSize(), space);
+ return static_cast<SignatureDataPtr>(raw);
}
const char* SignatureData::ToCString() const {
@@ -9289,11 +9285,11 @@
StorePointer(&raw_ptr()->target_, value.raw());
}
-RawRedirectionData* RedirectionData::New() {
+RedirectionDataPtr RedirectionData::New() {
ASSERT(Object::redirection_data_class() != Class::null());
- RawObject* raw = Object::Allocate(
- RedirectionData::kClassId, RedirectionData::InstanceSize(), Heap::kOld);
- return reinterpret_cast<RawRedirectionData*>(raw);
+ ObjectPtr raw = Object::Allocate(RedirectionData::kClassId,
+ RedirectionData::InstanceSize(), Heap::kOld);
+ return static_cast<RedirectionDataPtr>(raw);
}
const char* RedirectionData::ToCString() const {
@@ -9331,12 +9327,12 @@
StorePointer(&raw_ptr()->callback_exceptional_return_, value.raw());
}
-RawFfiTrampolineData* FfiTrampolineData::New() {
+FfiTrampolineDataPtr FfiTrampolineData::New() {
ASSERT(Object::ffi_trampoline_data_class() != Class::null());
- RawObject* raw =
+ ObjectPtr raw =
Object::Allocate(FfiTrampolineData::kClassId,
FfiTrampolineData::InstanceSize(), Heap::kOld);
- RawFfiTrampolineData* data = reinterpret_cast<RawFfiTrampolineData*>(raw);
+ FfiTrampolineDataPtr data = static_cast<FfiTrampolineDataPtr>(raw);
data->ptr()->callback_id_ = 0;
return data;
}
@@ -9350,11 +9346,11 @@
signature_type_name.IsNull() ? "null" : signature_type_name.ToCString());
}
-RawField* Field::CloneFromOriginal() const {
+FieldPtr Field::CloneFromOriginal() const {
return this->Clone(*this);
}
-RawField* Field::Original() const {
+FieldPtr Field::Original() const {
if (IsNull()) {
return Field::null();
}
@@ -9384,44 +9380,44 @@
void Field::SetOriginal(const Field& value) const {
ASSERT(value.IsOriginal());
ASSERT(!value.IsNull());
- StorePointer(&raw_ptr()->owner_, reinterpret_cast<RawObject*>(value.raw()));
+ StorePointer(&raw_ptr()->owner_, static_cast<ObjectPtr>(value.raw()));
}
-RawString* Field::GetterName(const String& field_name) {
+StringPtr Field::GetterName(const String& field_name) {
return String::Concat(Symbols::GetterPrefix(), field_name);
}
-RawString* Field::GetterSymbol(const String& field_name) {
+StringPtr Field::GetterSymbol(const String& field_name) {
return Symbols::FromGet(Thread::Current(), field_name);
}
-RawString* Field::LookupGetterSymbol(const String& field_name) {
+StringPtr Field::LookupGetterSymbol(const String& field_name) {
return Symbols::LookupFromGet(Thread::Current(), field_name);
}
-RawString* Field::SetterName(const String& field_name) {
+StringPtr Field::SetterName(const String& field_name) {
return String::Concat(Symbols::SetterPrefix(), field_name);
}
-RawString* Field::SetterSymbol(const String& field_name) {
+StringPtr Field::SetterSymbol(const String& field_name) {
return Symbols::FromSet(Thread::Current(), field_name);
}
-RawString* Field::LookupSetterSymbol(const String& field_name) {
+StringPtr Field::LookupSetterSymbol(const String& field_name) {
return Symbols::LookupFromSet(Thread::Current(), field_name);
}
-RawString* Field::NameFromGetter(const String& getter_name) {
+StringPtr Field::NameFromGetter(const String& getter_name) {
return Symbols::New(Thread::Current(), getter_name, kGetterPrefixLength,
getter_name.Length() - kGetterPrefixLength);
}
-RawString* Field::NameFromSetter(const String& setter_name) {
+StringPtr Field::NameFromSetter(const String& setter_name) {
return Symbols::New(Thread::Current(), setter_name, kSetterPrefixLength,
setter_name.Length() - kSetterPrefixLength);
}
-RawString* Field::NameFromInit(const String& init_name) {
+StringPtr Field::NameFromInit(const String& init_name) {
return Symbols::New(Thread::Current(), init_name, kInitPrefixLength,
init_name.Length() - kInitPrefixLength);
}
@@ -9444,7 +9440,7 @@
StorePointer(&raw_ptr()->name_, value.raw());
}
-RawObject* Field::RawOwner() const {
+ObjectPtr Field::RawOwner() const {
if (IsOriginal()) {
return raw_ptr()->owner_;
} else {
@@ -9455,7 +9451,7 @@
}
}
-RawClass* Field::Owner() const {
+ClassPtr Field::Owner() const {
const Field& field = Field::Handle(Original());
ASSERT(field.IsOriginal());
const Object& obj = Object::Handle(field.raw_ptr()->owner_);
@@ -9466,7 +9462,7 @@
return PatchClass::Cast(obj).patched_class();
}
-RawClass* Field::Origin() const {
+ClassPtr Field::Origin() const {
const Field& field = Field::Handle(Original());
ASSERT(field.IsOriginal());
const Object& obj = Object::Handle(field.raw_ptr()->owner_);
@@ -9477,7 +9473,7 @@
return PatchClass::Cast(obj).origin_class();
}
-RawScript* Field::Script() const {
+ScriptPtr Field::Script() const {
// NOTE(turnidge): If you update this function, you probably want to
// update Class::PatchFieldsAndFunctions() at the same time.
const Field& field = Field::Handle(Original());
@@ -9490,7 +9486,7 @@
return PatchClass::Cast(obj).script();
}
-RawExternalTypedData* Field::KernelData() const {
+ExternalTypedDataPtr Field::KernelData() const {
const Object& obj = Object::Handle(this->raw_ptr()->owner_);
// During background JIT compilation field objects are copied
// and copy points to the original field via the owner field.
@@ -9539,11 +9535,11 @@
}
}
-RawField* Field::New() {
+FieldPtr Field::New() {
ASSERT(Object::field_class() != Class::null());
- RawObject* raw =
+ ObjectPtr raw =
Object::Allocate(Field::kClassId, Field::InstanceSize(), Heap::kOld);
- return reinterpret_cast<RawField*>(raw);
+ return static_cast<FieldPtr>(raw);
}
void Field::InitializeNew(const Field& result,
@@ -9611,16 +9607,16 @@
}
}
-RawField* Field::New(const String& name,
- bool is_static,
- bool is_final,
- bool is_const,
- bool is_reflectable,
- bool is_late,
- const Object& owner,
- const AbstractType& type,
- TokenPosition token_pos,
- TokenPosition end_token_pos) {
+FieldPtr Field::New(const String& name,
+ bool is_static,
+ bool is_final,
+ bool is_const,
+ bool is_reflectable,
+ bool is_late,
+ const Object& owner,
+ const AbstractType& type,
+ TokenPosition token_pos,
+ TokenPosition end_token_pos) {
ASSERT(!owner.IsNull());
const Field& result = Field::Handle(Field::New());
InitializeNew(result, name, is_static, is_final, is_const, is_reflectable,
@@ -9629,13 +9625,13 @@
return result.raw();
}
-RawField* Field::NewTopLevel(const String& name,
- bool is_final,
- bool is_const,
- bool is_late,
- const Object& owner,
- TokenPosition token_pos,
- TokenPosition end_token_pos) {
+FieldPtr Field::NewTopLevel(const String& name,
+ bool is_final,
+ bool is_const,
+ bool is_late,
+ const Object& owner,
+ TokenPosition token_pos,
+ TokenPosition end_token_pos) {
ASSERT(!owner.IsNull());
const Field& result = Field::Handle(Field::New());
InitializeNew(result, name, true, /* is_static */
@@ -9644,7 +9640,7 @@
return result.raw();
}
-RawField* Field::Clone(const Field& original) const {
+FieldPtr Field::Clone(const Field& original) const {
if (original.IsNull()) {
return Field::null();
}
@@ -9668,7 +9664,7 @@
#endif // !defined(DART_PRECOMPILED_RUNTIME)
}
-RawString* Field::InitializingExpression() const {
+StringPtr Field::InitializingExpression() const {
UNREACHABLE();
return String::null();
}
@@ -9681,7 +9677,7 @@
return String::ScrubName(String::Handle(name()), is_extension_member());
}
-RawString* Field::UserVisibleName() const {
+StringPtr Field::UserVisibleName() const {
if (FLAG_show_internal_names) {
return name();
}
@@ -9767,7 +9763,7 @@
// Build a closure object that gets (or sets) the contents of a static
// field f and cache the closure in a newly created static field
// named #f (or #f= in case of a setter).
-RawInstance* Field::AccessorClosure(bool make_setter) const {
+InstancePtr Field::AccessorClosure(bool make_setter) const {
Thread* thread = Thread::Current();
Zone* zone = thread->zone();
ASSERT(is_static());
@@ -9795,15 +9791,15 @@
return Instance::null();
}
-RawInstance* Field::GetterClosure() const {
+InstancePtr Field::GetterClosure() const {
return AccessorClosure(false);
}
-RawInstance* Field::SetterClosure() const {
+InstancePtr Field::SetterClosure() const {
return AccessorClosure(true);
}
-RawArray* Field::dependent_code() const {
+ArrayPtr Field::dependent_code() const {
return raw_ptr()->dependent_code_;
}
@@ -9876,12 +9872,12 @@
bool Field::IsUninitialized() const {
Thread* thread = Thread::Current();
const FieldTable* field_table = thread->isolate()->field_table();
- const RawInstance* raw_value = field_table->At(field_id());
+ const InstancePtr raw_value = field_table->At(field_id());
ASSERT(raw_value != Object::transition_sentinel().raw());
return raw_value == Object::sentinel().raw();
}
-RawFunction* Field::EnsureInitializerFunction() const {
+FunctionPtr Field::EnsureInitializerFunction() const {
ASSERT(has_nontrivial_initializer());
Thread* thread = Thread::Current();
Zone* zone = thread->zone();
@@ -9906,7 +9902,7 @@
return raw_ptr()->initializer_function_ != Function::null();
}
-RawError* Field::InitializeInstance(const Instance& instance) const {
+ErrorPtr Field::InitializeInstance(const Instance& instance) const {
ASSERT(IsOriginal());
ASSERT(is_instance());
ASSERT(instance.GetField(*this) == Object::sentinel().raw());
@@ -9940,7 +9936,7 @@
return Error::null();
}
-RawError* Field::InitializeStatic() const {
+ErrorPtr Field::InitializeStatic() const {
ASSERT(IsOriginal());
ASSERT(is_static());
if (StaticValue() == Object::sentinel().raw()) {
@@ -9981,7 +9977,7 @@
return Error::null();
}
-RawObject* Field::EvaluateInitializer() const {
+ObjectPtr Field::EvaluateInitializer() const {
Thread* const thread = Thread::Current();
ASSERT(thread->IsMutatorThread());
NoOOBMessageScope no_msg_scope(thread);
@@ -10459,7 +10455,7 @@
return raw_ptr()->source_ != String::null();
}
-RawString* Script::Source() const {
+StringPtr Script::Source() const {
return raw_ptr()->source_;
}
@@ -10491,7 +10487,7 @@
StoreNonPointer(&raw_ptr()->kernel_script_index_, kernel_script_index);
}
-RawTypedData* Script::kernel_string_offsets() const {
+TypedDataPtr Script::kernel_string_offsets() const {
KernelProgramInfo& program_info =
KernelProgramInfo::Handle(kernel_program_info());
ASSERT(!program_info.IsNull());
@@ -10530,7 +10526,7 @@
#endif // !defined(DART_PRECOMPILED_RUNTIME)
}
-RawGrowableObjectArray* Script::GenerateLineNumberArray() const {
+GrowableObjectArrayPtr Script::GenerateLineNumberArray() const {
Zone* zone = Thread::Current()->zone();
const GrowableObjectArray& info =
GrowableObjectArray::Handle(zone, GrowableObjectArray::New());
@@ -10605,11 +10601,11 @@
StorePointer(&raw_ptr()->debug_positions_, value.raw());
}
-RawTypedData* Script::line_starts() const {
+TypedDataPtr Script::line_starts() const {
return raw_ptr()->line_starts_;
}
-RawArray* Script::debug_positions() const {
+ArrayPtr Script::debug_positions() const {
#if !defined(DART_PRECOMPILED_RUNTIME)
Array& debug_positions_array = Array::Handle(raw_ptr()->debug_positions_);
if (debug_positions_array.IsNull()) {
@@ -10625,12 +10621,13 @@
}
void Script::SetLazyLookupSourceAndLineStarts(bool value) const {
- set_flags(RawScript::LazyLookupSourceAndLineStartsBit::update(
+ set_flags(ScriptLayout::LazyLookupSourceAndLineStartsBit::update(
value, raw_ptr()->flags_));
}
bool Script::IsLazyLookupSourceAndLineStarts() const {
- return RawScript::LazyLookupSourceAndLineStartsBit::decode(raw_ptr()->flags_);
+ return ScriptLayout::LazyLookupSourceAndLineStartsBit::decode(
+ raw_ptr()->flags_);
}
void Script::set_load_timestamp(int64_t value) const {
@@ -10762,7 +10759,7 @@
#endif // !defined(DART_PRECOMPILED_RUNTIME)
}
-RawString* Script::GetLine(intptr_t line_number, Heap::Space space) const {
+StringPtr Script::GetLine(intptr_t line_number, Heap::Space space) const {
const String& src = String::Handle(Source());
if (src.IsNull()) {
ASSERT(Dart::vm_snapshot_kind() == Snapshot::kFullAOT);
@@ -10797,7 +10794,7 @@
}
}
-RawString* Script::GetSnippet(TokenPosition from, TokenPosition to) const {
+StringPtr Script::GetSnippet(TokenPosition from, TokenPosition to) const {
intptr_t from_line;
intptr_t from_column;
intptr_t to_line;
@@ -10807,10 +10804,10 @@
return GetSnippet(from_line, from_column, to_line, to_column);
}
-RawString* Script::GetSnippet(intptr_t from_line,
- intptr_t from_column,
- intptr_t to_line,
- intptr_t to_column) const {
+StringPtr Script::GetSnippet(intptr_t from_line,
+ intptr_t from_column,
+ intptr_t to_line,
+ intptr_t to_column) const {
const String& src = String::Handle(Source());
if (src.IsNull()) {
return Symbols::OptimizedOut().raw();
@@ -10860,20 +10857,20 @@
return snippet.raw();
}
-RawScript* Script::New() {
+ScriptPtr Script::New() {
ASSERT(Object::script_class() != Class::null());
- RawObject* raw =
+ ObjectPtr raw =
Object::Allocate(Script::kClassId, Script::InstanceSize(), Heap::kOld);
- return reinterpret_cast<RawScript*>(raw);
+ return static_cast<ScriptPtr>(raw);
}
-RawScript* Script::New(const String& url, const String& source) {
+ScriptPtr Script::New(const String& url, const String& source) {
return Script::New(url, url, source);
}
-RawScript* Script::New(const String& url,
- const String& resolved_url,
- const String& source) {
+ScriptPtr Script::New(const String& url,
+ const String& resolved_url,
+ const String& source) {
Thread* thread = Thread::Current();
Zone* zone = thread->zone();
const Script& result = Script::Handle(zone, Script::New());
@@ -10894,7 +10891,7 @@
return OS::SCreate(Thread::Current()->zone(), "Script(%s)", name.ToCString());
}
-RawLibrary* Script::FindLibrary() const {
+LibraryPtr Script::FindLibrary() const {
Thread* thread = Thread::Current();
Zone* zone = thread->zone();
Isolate* isolate = thread->isolate();
@@ -10922,7 +10919,7 @@
MoveToNextObject();
}
-RawObject* DictionaryIterator::GetNext() {
+ObjectPtr DictionaryIterator::GetNext() {
ASSERT(HasNext());
int ix = next_ix_++;
MoveToNextObject();
@@ -10947,7 +10944,7 @@
MoveToNextClass();
}
-RawClass* ClassDictionaryIterator::GetNextClass() {
+ClassPtr ClassDictionaryIterator::GetNextClass() {
ASSERT(HasNext());
Class& cls = Class::Handle();
if (next_ix_ < size_) {
@@ -10978,7 +10975,7 @@
Advance();
}
-RawLibraryPrefix* LibraryPrefixIterator::GetNext() {
+LibraryPrefixPtr LibraryPrefixIterator::GetNext() {
ASSERT(HasNext());
int ix = next_ix_++;
Object& obj = Object::Handle(array_.At(ix));
@@ -11037,32 +11034,32 @@
void Library::SetLoadInProgress() const {
// Must not already be in the process of being loaded.
- ASSERT(raw_ptr()->load_state_ <= RawLibrary::kLoadRequested);
- StoreNonPointer(&raw_ptr()->load_state_, RawLibrary::kLoadInProgress);
+ ASSERT(raw_ptr()->load_state_ <= LibraryLayout::kLoadRequested);
+ StoreNonPointer(&raw_ptr()->load_state_, LibraryLayout::kLoadInProgress);
}
void Library::SetLoadRequested() const {
// Must not be already loaded.
- ASSERT(raw_ptr()->load_state_ == RawLibrary::kAllocated);
- StoreNonPointer(&raw_ptr()->load_state_, RawLibrary::kLoadRequested);
+ ASSERT(raw_ptr()->load_state_ == LibraryLayout::kAllocated);
+ StoreNonPointer(&raw_ptr()->load_state_, LibraryLayout::kLoadRequested);
}
void Library::SetLoaded() const {
// Should not be already loaded or just allocated.
ASSERT(LoadInProgress() || LoadRequested());
- StoreNonPointer(&raw_ptr()->load_state_, RawLibrary::kLoaded);
+ StoreNonPointer(&raw_ptr()->load_state_, LibraryLayout::kLoaded);
}
-static RawString* MakeClassMetaName(Thread* thread,
- Zone* zone,
- const Class& cls) {
+static StringPtr MakeClassMetaName(Thread* thread,
+ Zone* zone,
+ const Class& cls) {
return Symbols::FromConcat(thread, Symbols::At(),
String::Handle(zone, cls.Name()));
}
-static RawString* MakeFieldMetaName(Thread* thread,
- Zone* zone,
- const Field& field) {
+static StringPtr MakeFieldMetaName(Thread* thread,
+ Zone* zone,
+ const Field& field) {
const String& cname = String::Handle(
zone,
MakeClassMetaName(thread, zone, Class::Handle(zone, field.Origin())));
@@ -11073,9 +11070,9 @@
return Symbols::FromConcatAll(thread, pieces);
}
-static RawString* MakeFunctionMetaName(Thread* thread,
- Zone* zone,
- const Function& func) {
+static StringPtr MakeFunctionMetaName(Thread* thread,
+ Zone* zone,
+ const Function& func) {
const String& cname = String::Handle(
zone,
MakeClassMetaName(thread, zone, Class::Handle(zone, func.origin())));
@@ -11086,9 +11083,9 @@
return Symbols::FromConcatAll(thread, pieces);
}
-static RawString* MakeTypeParameterMetaName(Thread* thread,
- Zone* zone,
- const TypeParameter& param) {
+static StringPtr MakeTypeParameterMetaName(Thread* thread,
+ Zone* zone,
+ const TypeParameter& param) {
const String& cname = String::Handle(
zone,
MakeClassMetaName(thread, zone,
@@ -11189,7 +11186,7 @@
bytecode_offset);
}
-RawString* Library::MakeMetadataName(const Object& obj) const {
+StringPtr Library::MakeMetadataName(const Object& obj) const {
Thread* thread = Thread::Current();
Zone* zone = thread->zone();
if (obj.IsClass()) {
@@ -11207,7 +11204,7 @@
return String::null();
}
-RawField* Library::GetMetadataField(const String& metaname) const {
+FieldPtr Library::GetMetadataField(const String& metaname) const {
const GrowableObjectArray& metadata =
GrowableObjectArray::Handle(this->metadata());
Field& entry = Field::Handle();
@@ -11240,7 +11237,7 @@
}
}
-RawObject* Library::GetMetadata(const Object& obj) const {
+ObjectPtr Library::GetMetadata(const Object& obj) const {
#if defined(DART_PRECOMPILED_RUNTIME)
return Object::empty_array().raw();
#else
@@ -11288,8 +11285,7 @@
#endif // defined(DART_PRECOMPILED_RUNTIME)
}
-RawArray* Library::GetExtendedMetadata(const Object& obj,
- intptr_t count) const {
+ArrayPtr Library::GetExtendedMetadata(const Object& obj, intptr_t count) const {
#if defined(DART_PRECOMPILED_RUNTIME)
return Object::empty_array().raw();
#else
@@ -11314,7 +11310,7 @@
name.CharAt(3) == ':'));
}
-RawObject* Library::ResolveName(const String& name) const {
+ObjectPtr Library::ResolveName(const String& name) const {
Object& obj = Object::Handle();
if (FLAG_use_lib_cache && LookupResolvedNamesCache(name, &obj)) {
return obj.raw();
@@ -11543,8 +11539,8 @@
// Lookup a name in the library's re-export namespace.
// This lookup can occur from two different threads: background compiler and
// mutator thread.
-RawObject* Library::LookupReExport(const String& name,
- ZoneGrowableArray<intptr_t>* trail) const {
+ObjectPtr Library::LookupReExport(const String& name,
+ ZoneGrowableArray<intptr_t>* trail) const {
if (!HasExports()) {
return Object::null();
}
@@ -11582,7 +11578,7 @@
return obj.raw();
}
-RawObject* Library::LookupEntry(const String& name, intptr_t* index) const {
+ObjectPtr Library::LookupEntry(const String& name, intptr_t* index) const {
ASSERT(!IsNull());
Thread* thread = Thread::Current();
REUSABLE_ARRAY_HANDLESCOPE(thread);
@@ -11635,7 +11631,7 @@
scripts.Add(candidate);
}
-RawArray* Library::LoadedScripts() const {
+ArrayPtr Library::LoadedScripts() const {
ASSERT(Thread::Current()->IsMutatorThread());
// We compute the list of loaded scripts lazily. The result is
// cached in loaded_scripts_.
@@ -11705,8 +11701,8 @@
// TODO(hausner): we might want to add a script dictionary to the
// library class to make this lookup faster.
-RawScript* Library::LookupScript(const String& url,
- bool useResolvedUri /* = false */) const {
+ScriptPtr Library::LookupScript(const String& url,
+ bool useResolvedUri /* = false */) const {
const intptr_t url_length = url.Length();
if (url_length == 0) {
return Script::null();
@@ -11756,12 +11752,12 @@
}
}
-RawObject* Library::LookupLocalObject(const String& name) const {
+ObjectPtr Library::LookupLocalObject(const String& name) const {
intptr_t index;
return LookupEntry(name, &index);
}
-RawObject* Library::LookupLocalOrReExportObject(const String& name) const {
+ObjectPtr Library::LookupLocalOrReExportObject(const String& name) const {
intptr_t index;
EnsureTopLevelClassIsFinalized();
const Object& result = Object::Handle(LookupEntry(name, &index));
@@ -11771,7 +11767,7 @@
return LookupReExport(name);
}
-RawField* Library::LookupFieldAllowPrivate(const String& name) const {
+FieldPtr Library::LookupFieldAllowPrivate(const String& name) const {
EnsureTopLevelClassIsFinalized();
Object& obj = Object::Handle(LookupObjectAllowPrivate(name));
if (obj.IsField()) {
@@ -11780,7 +11776,7 @@
return Field::null();
}
-RawField* Library::LookupLocalField(const String& name) const {
+FieldPtr Library::LookupLocalField(const String& name) const {
EnsureTopLevelClassIsFinalized();
Object& obj = Object::Handle(LookupLocalObjectAllowPrivate(name));
if (obj.IsField()) {
@@ -11789,7 +11785,7 @@
return Field::null();
}
-RawFunction* Library::LookupFunctionAllowPrivate(const String& name) const {
+FunctionPtr Library::LookupFunctionAllowPrivate(const String& name) const {
EnsureTopLevelClassIsFinalized();
Object& obj = Object::Handle(LookupObjectAllowPrivate(name));
if (obj.IsFunction()) {
@@ -11798,7 +11794,7 @@
return Function::null();
}
-RawFunction* Library::LookupLocalFunction(const String& name) const {
+FunctionPtr Library::LookupLocalFunction(const String& name) const {
EnsureTopLevelClassIsFinalized();
Object& obj = Object::Handle(LookupLocalObjectAllowPrivate(name));
if (obj.IsFunction()) {
@@ -11807,7 +11803,7 @@
return Function::null();
}
-RawObject* Library::LookupLocalObjectAllowPrivate(const String& name) const {
+ObjectPtr Library::LookupLocalObjectAllowPrivate(const String& name) const {
Thread* thread = Thread::Current();
Zone* zone = thread->zone();
Object& obj = Object::Handle(zone, Object::null());
@@ -11819,7 +11815,7 @@
return obj.raw();
}
-RawObject* Library::LookupObjectAllowPrivate(const String& name) const {
+ObjectPtr Library::LookupObjectAllowPrivate(const String& name) const {
// First check if name is found in the local scope of the library.
Object& obj = Object::Handle(LookupLocalObjectAllowPrivate(name));
if (!obj.IsNull()) {
@@ -11835,7 +11831,7 @@
return LookupImportedObject(name);
}
-RawObject* Library::LookupImportedObject(const String& name) const {
+ObjectPtr Library::LookupImportedObject(const String& name) const {
Object& obj = Object::Handle();
Namespace& import = Namespace::Handle();
Library& import_lib = Library::Handle();
@@ -11896,7 +11892,7 @@
return found_obj.raw();
}
-RawClass* Library::LookupClass(const String& name) const {
+ClassPtr Library::LookupClass(const String& name) const {
Object& obj = Object::Handle(LookupLocalObject(name));
if (obj.IsNull() && !ShouldBePrivate(name)) {
obj = LookupImportedObject(name);
@@ -11907,7 +11903,7 @@
return Class::null();
}
-RawClass* Library::LookupLocalClass(const String& name) const {
+ClassPtr Library::LookupLocalClass(const String& name) const {
Object& obj = Object::Handle(LookupLocalObject(name));
if (obj.IsClass()) {
return Class::Cast(obj).raw();
@@ -11915,7 +11911,7 @@
return Class::null();
}
-RawClass* Library::LookupClassAllowPrivate(const String& name) const {
+ClassPtr Library::LookupClassAllowPrivate(const String& name) const {
// See if the class is available in this library or in the top level
// scope of any imported library.
Zone* zone = Thread::Current()->zone();
@@ -11937,7 +11933,7 @@
}
// Mixin applications can have multiple private keys from different libraries.
-RawClass* Library::SlowLookupClassAllowMultiPartPrivate(
+ClassPtr Library::SlowLookupClassAllowMultiPartPrivate(
const String& name) const {
Array& dict = Array::Handle(dictionary());
Object& entry = Object::Handle();
@@ -11955,7 +11951,7 @@
return Class::null();
}
-RawLibraryPrefix* Library::LookupLocalLibraryPrefix(const String& name) const {
+LibraryPrefixPtr Library::LookupLocalLibraryPrefix(const String& name) const {
const Object& obj = Object::Handle(LookupLocalObject(name));
if (obj.IsLibraryPrefix()) {
return LibraryPrefix::Cast(obj).raw();
@@ -11972,7 +11968,7 @@
StorePointer(&raw_ptr()->metadata_, value.raw());
}
-RawLibrary* Library::ImportLibraryAt(intptr_t index) const {
+LibraryPtr Library::ImportLibraryAt(intptr_t index) const {
Namespace& import = Namespace::Handle(ImportAt(index));
if (import.IsNull()) {
return Library::null();
@@ -11980,7 +11976,7 @@
return import.library();
}
-RawNamespace* Library::ImportAt(intptr_t index) const {
+NamespacePtr Library::ImportAt(intptr_t index) const {
if ((index < 0) || index >= num_imports()) {
return Namespace::null();
}
@@ -12055,7 +12051,7 @@
exports.SetAt(num_exports, ns);
}
-static RawArray* NewDictionary(intptr_t initial_size) {
+static ArrayPtr NewDictionary(intptr_t initial_size) {
const Array& dict = Array::Handle(Array::New(initial_size + 1, Heap::kOld));
// The last element of the dictionary specifies the number of in use slots.
dict.SetAt(initial_size, Object::smi_zero());
@@ -12107,22 +12103,20 @@
StoreNonPointer(&raw_ptr()->num_imports_, 0);
}
-RawLibrary* Library::New() {
+LibraryPtr Library::New() {
ASSERT(Object::library_class() != Class::null());
- RawObject* raw =
+ ObjectPtr raw =
Object::Allocate(Library::kClassId, Library::InstanceSize(), Heap::kOld);
- return reinterpret_cast<RawLibrary*>(raw);
+ return static_cast<LibraryPtr>(raw);
}
-RawLibrary* Library::NewLibraryHelper(const String& url, bool import_core_lib) {
+LibraryPtr Library::NewLibraryHelper(const String& url, bool import_core_lib) {
Thread* thread = Thread::Current();
Zone* zone = thread->zone();
ASSERT(thread->IsMutatorThread());
// Force the url to have a hash code.
url.Hash();
const bool dart_scheme = url.StartsWith(Symbols::DartScheme());
- const bool dart_private_scheme =
- dart_scheme && url.StartsWith(Symbols::DartSchemePrivate());
const Library& result = Library::Handle(zone, Library::New());
result.StorePointer(&result.raw_ptr()->name_, Symbols::Empty().raw());
result.StorePointer(&result.raw_ptr()->url_, url.raw());
@@ -12144,10 +12138,7 @@
result.set_flags(0);
result.set_is_in_fullsnapshot(false);
result.set_is_nnbd(false);
- if (dart_private_scheme) {
- // Never debug dart:_ libraries.
- result.set_debuggable(false);
- } else if (dart_scheme) {
+ if (dart_scheme) {
// Only debug dart: libraries if we have been requested to show invisible
// frames.
result.set_debuggable(FLAG_show_invisible_frames);
@@ -12159,7 +12150,7 @@
NOT_IN_PRECOMPILED(result.set_is_declared_in_bytecode(false));
NOT_IN_PRECOMPILED(result.set_binary_declaration_offset(0));
result.StoreNonPointer(&result.raw_ptr()->load_state_,
- RawLibrary::kAllocated);
+ LibraryLayout::kAllocated);
result.StoreNonPointer(&result.raw_ptr()->index_, -1);
result.InitClassDictionary();
result.InitImportList();
@@ -12175,7 +12166,7 @@
return result.raw();
}
-RawLibrary* Library::New(const String& url) {
+LibraryPtr Library::New(const String& url) {
return NewLibraryHelper(url, false);
}
@@ -12196,7 +12187,7 @@
}
// Invoke the function, or noSuchMethod if it is null.
-static RawObject* InvokeInstanceFunction(
+static ObjectPtr InvokeInstanceFunction(
const Instance& receiver,
const Function& function,
const String& target_name,
@@ -12212,18 +12203,18 @@
return DartEntry::InvokeNoSuchMethod(receiver, target_name, args,
args_descriptor_array);
}
- RawObject* type_error = function.DoArgumentTypesMatch(args, args_descriptor,
- instantiator_type_args);
+ ObjectPtr type_error = function.DoArgumentTypesMatch(args, args_descriptor,
+ instantiator_type_args);
if (type_error != Error::null()) {
return type_error;
}
return DartEntry::InvokeFunction(function, args, args_descriptor_array);
}
-RawObject* Library::InvokeGetter(const String& getter_name,
- bool throw_nsm_if_absent,
- bool respect_reflectable,
- bool check_is_entrypoint) const {
+ObjectPtr Library::InvokeGetter(const String& getter_name,
+ bool throw_nsm_if_absent,
+ bool respect_reflectable,
+ bool check_is_entrypoint) const {
Object& obj = Object::Handle(LookupLocalOrReExportObject(getter_name));
Function& getter = Function::Handle();
if (obj.IsField()) {
@@ -12288,10 +12279,10 @@
return DartEntry::InvokeFunction(getter, Object::empty_array());
}
-RawObject* Library::InvokeSetter(const String& setter_name,
- const Instance& value,
- bool respect_reflectable,
- bool check_is_entrypoint) const {
+ObjectPtr Library::InvokeSetter(const String& setter_name,
+ const Instance& value,
+ bool respect_reflectable,
+ bool check_is_entrypoint) const {
Object& obj = Object::Handle(LookupLocalOrReExportObject(setter_name));
const String& internal_setter_name =
String::Handle(Field::SetterName(setter_name));
@@ -12352,11 +12343,11 @@
return DartEntry::InvokeFunction(setter, args);
}
-RawObject* Library::Invoke(const String& function_name,
- const Array& args,
- const Array& arg_names,
- bool respect_reflectable,
- bool check_is_entrypoint) const {
+ObjectPtr Library::Invoke(const String& function_name,
+ const Array& args,
+ const Array& arg_names,
+ bool respect_reflectable,
+ bool check_is_entrypoint) const {
// TODO(regis): Support invocation of generic functions with type arguments.
const int kTypeArgsLen = 0;
@@ -12407,7 +12398,7 @@
function_name, args, arg_names, InvocationMirror::kTopLevel,
InvocationMirror::kMethod);
}
- RawObject* type_error =
+ ObjectPtr type_error =
function.DoArgumentTypesMatch(args, args_descriptor, type_args);
if (type_error != Error::null()) {
return type_error;
@@ -12415,7 +12406,7 @@
return DartEntry::InvokeFunction(function, args, args_descriptor_array);
}
-RawObject* Library::EvaluateCompiledExpression(
+ObjectPtr Library::EvaluateCompiledExpression(
const ExternalTypedData& kernel_buffer,
const Array& type_definitions,
const Array& arguments,
@@ -12475,11 +12466,11 @@
static uword Hash(const Object& key) { return String::Cast(key).Hash(); }
- static RawObject* NewKey(const String& str) { return str.raw(); }
+ static ObjectPtr NewKey(const String& str) { return str.raw(); }
};
typedef UnorderedHashMap<LibraryLookupTraits> LibraryLookupMap;
-static RawObject* EvaluateCompiledExpressionHelper(
+static ObjectPtr EvaluateCompiledExpressionHelper(
const ExternalTypedData& kernel_buffer,
const Array& type_definitions,
const String& library_url,
@@ -12548,7 +12539,7 @@
}
// Returns library with given url in current isolate, or NULL.
-RawLibrary* Library::LookupLibrary(Thread* thread, const String& url) {
+LibraryPtr Library::LookupLibrary(Thread* thread, const String& url) {
Zone* zone = thread->zone();
Isolate* isolate = thread->isolate();
ObjectStore* object_store = isolate->object_store();
@@ -12638,7 +12629,7 @@
return name.EqualsConcat(member, private_key);
}
-RawClass* Library::LookupCoreClass(const String& class_name) {
+ClassPtr Library::LookupCoreClass(const String& class_name) {
Thread* thread = Thread::Current();
Zone* zone = thread->zone();
const Library& core_lib = Library::Handle(zone, Library::CoreLibrary());
@@ -12653,7 +12644,7 @@
// Cannot handle qualified names properly as it only appends private key to
// the end (e.g. _Alfa.foo -> _Alfa.foo@...).
-RawString* Library::PrivateName(const String& name) const {
+StringPtr Library::PrivateName(const String& name) const {
Thread* thread = Thread::Current();
Zone* zone = thread->zone();
ASSERT(IsPrivate(name));
@@ -12665,7 +12656,7 @@
return str.raw();
}
-RawLibrary* Library::GetLibrary(intptr_t index) {
+LibraryPtr Library::GetLibrary(intptr_t index) {
Thread* thread = Thread::Current();
Zone* zone = thread->zone();
Isolate* isolate = thread->isolate();
@@ -12728,65 +12719,65 @@
isolate->object_store()->set_libraries_map(map.Release());
}
-RawLibrary* Library::AsyncLibrary() {
+LibraryPtr Library::AsyncLibrary() {
return Isolate::Current()->object_store()->async_library();
}
-RawLibrary* Library::ConvertLibrary() {
+LibraryPtr Library::ConvertLibrary() {
return Isolate::Current()->object_store()->convert_library();
}
-RawLibrary* Library::CoreLibrary() {
+LibraryPtr Library::CoreLibrary() {
return Isolate::Current()->object_store()->core_library();
}
-RawLibrary* Library::CollectionLibrary() {
+LibraryPtr Library::CollectionLibrary() {
return Isolate::Current()->object_store()->collection_library();
}
-RawLibrary* Library::DeveloperLibrary() {
+LibraryPtr Library::DeveloperLibrary() {
return Isolate::Current()->object_store()->developer_library();
}
-RawLibrary* Library::FfiLibrary() {
+LibraryPtr Library::FfiLibrary() {
return Isolate::Current()->object_store()->ffi_library();
}
-RawLibrary* Library::InternalLibrary() {
+LibraryPtr Library::InternalLibrary() {
return Isolate::Current()->object_store()->_internal_library();
}
-RawLibrary* Library::IsolateLibrary() {
+LibraryPtr Library::IsolateLibrary() {
return Isolate::Current()->object_store()->isolate_library();
}
-RawLibrary* Library::MathLibrary() {
+LibraryPtr Library::MathLibrary() {
return Isolate::Current()->object_store()->math_library();
}
#if !defined(DART_PRECOMPILED_RUNTIME)
-RawLibrary* Library::MirrorsLibrary() {
+LibraryPtr Library::MirrorsLibrary() {
return Isolate::Current()->object_store()->mirrors_library();
}
#endif
-RawLibrary* Library::NativeWrappersLibrary() {
+LibraryPtr Library::NativeWrappersLibrary() {
return Isolate::Current()->object_store()->native_wrappers_library();
}
-RawLibrary* Library::ProfilerLibrary() {
+LibraryPtr Library::ProfilerLibrary() {
return Isolate::Current()->object_store()->profiler_library();
}
-RawLibrary* Library::TypedDataLibrary() {
+LibraryPtr Library::TypedDataLibrary() {
return Isolate::Current()->object_store()->typed_data_library();
}
-RawLibrary* Library::VMServiceLibrary() {
+LibraryPtr Library::VMServiceLibrary() {
return Isolate::Current()->object_store()->_vmservice_library();
}
-RawLibrary* Library::WasmLibrary() {
+LibraryPtr Library::WasmLibrary() {
return Isolate::Current()->object_store()->wasm_library();
}
@@ -12797,7 +12788,7 @@
name.ToCString());
}
-RawLibrary* LibraryPrefix::GetLibrary(int index) const {
+LibraryPtr LibraryPrefix::GetLibrary(int index) const {
if ((index >= 0) || (index < num_imports())) {
const Array& imports = Array::Handle(this->imports());
Namespace& import = Namespace::Handle();
@@ -12826,16 +12817,16 @@
set_num_imports(num_current_imports + 1);
}
-RawLibraryPrefix* LibraryPrefix::New() {
- RawObject* raw = Object::Allocate(LibraryPrefix::kClassId,
- LibraryPrefix::InstanceSize(), Heap::kOld);
- return reinterpret_cast<RawLibraryPrefix*>(raw);
+LibraryPrefixPtr LibraryPrefix::New() {
+ ObjectPtr raw = Object::Allocate(LibraryPrefix::kClassId,
+ LibraryPrefix::InstanceSize(), Heap::kOld);
+ return static_cast<LibraryPrefixPtr>(raw);
}
-RawLibraryPrefix* LibraryPrefix::New(const String& name,
- const Namespace& import,
- bool deferred_load,
- const Library& importer) {
+LibraryPrefixPtr LibraryPrefix::New(const String& name,
+ const Namespace& import,
+ bool deferred_load,
+ const Library& importer) {
const LibraryPrefix& result = LibraryPrefix::Handle(LibraryPrefix::New());
result.set_name(name);
result.set_num_imports(0);
@@ -12892,7 +12883,7 @@
set_metadata_field(field);
}
-RawObject* Namespace::GetMetadata() const {
+ObjectPtr Namespace::GetMetadata() const {
#if defined(DART_PRECOMPILED_RUNTIME)
return Object::empty_array().raw();
#else
@@ -12971,8 +12962,8 @@
// Look up object with given name in library and filter out hidden
// names. Also look up getters and setters.
-RawObject* Namespace::Lookup(const String& name,
- ZoneGrowableArray<intptr_t>* trail) const {
+ObjectPtr Namespace::Lookup(const String& name,
+ ZoneGrowableArray<intptr_t>* trail) const {
Zone* zone = Thread::Current()->zone();
const Library& lib = Library::Handle(zone, library());
@@ -13028,16 +13019,16 @@
return obj.raw();
}
-RawNamespace* Namespace::New() {
+NamespacePtr Namespace::New() {
ASSERT(Object::namespace_class() != Class::null());
- RawObject* raw = Object::Allocate(Namespace::kClassId,
- Namespace::InstanceSize(), Heap::kOld);
- return reinterpret_cast<RawNamespace*>(raw);
+ ObjectPtr raw = Object::Allocate(Namespace::kClassId,
+ Namespace::InstanceSize(), Heap::kOld);
+ return static_cast<NamespacePtr>(raw);
}
-RawNamespace* Namespace::New(const Library& library,
- const Array& show_names,
- const Array& hide_names) {
+NamespacePtr Namespace::New(const Library& library,
+ const Array& show_names,
+ const Array& hide_names) {
ASSERT(show_names.IsNull() || (show_names.Length() > 0));
ASSERT(hide_names.IsNull() || (hide_names.Length() > 0));
const Namespace& result = Namespace::Handle(Namespace::New());
@@ -13047,14 +13038,14 @@
return result.raw();
}
-RawKernelProgramInfo* KernelProgramInfo::New() {
- RawObject* raw =
+KernelProgramInfoPtr KernelProgramInfo::New() {
+ ObjectPtr raw =
Object::Allocate(KernelProgramInfo::kClassId,
KernelProgramInfo::InstanceSize(), Heap::kOld);
- return reinterpret_cast<RawKernelProgramInfo*>(raw);
+ return static_cast<KernelProgramInfoPtr>(raw);
}
-RawKernelProgramInfo* KernelProgramInfo::New(
+KernelProgramInfoPtr KernelProgramInfo::New(
const TypedData& string_offsets,
const ExternalTypedData& string_data,
const TypedData& canonical_names,
@@ -13089,9 +13080,9 @@
return "[KernelProgramInfo]";
}
-RawScript* KernelProgramInfo::ScriptAt(intptr_t index) const {
+ScriptPtr KernelProgramInfo::ScriptAt(intptr_t index) const {
const Array& all_scripts = Array::Handle(scripts());
- RawObject* script = all_scripts.At(index);
+ ObjectPtr script = all_scripts.At(index);
return Script::RawCast(script);
}
@@ -13128,8 +13119,8 @@
typedef UnorderedHashMap<SmiTraits> IntHashMap;
-RawLibrary* KernelProgramInfo::LookupLibrary(Thread* thread,
- const Smi& name_index) const {
+LibraryPtr KernelProgramInfo::LookupLibrary(Thread* thread,
+ const Smi& name_index) const {
REUSABLE_ARRAY_HANDLESCOPE(thread);
REUSABLE_LIBRARY_HANDLESCOPE(thread);
REUSABLE_OBJECT_HANDLESCOPE(thread);
@@ -13150,9 +13141,9 @@
return result.raw();
}
-RawLibrary* KernelProgramInfo::InsertLibrary(Thread* thread,
- const Smi& name_index,
- const Library& lib) const {
+LibraryPtr KernelProgramInfo::InsertLibrary(Thread* thread,
+ const Smi& name_index,
+ const Library& lib) const {
REUSABLE_ARRAY_HANDLESCOPE(thread);
REUSABLE_LIBRARY_HANDLESCOPE(thread);
REUSABLE_OBJECT_HANDLESCOPE(thread);
@@ -13177,8 +13168,8 @@
StorePointer(&raw_ptr()->classes_cache_, cache.raw());
}
-RawClass* KernelProgramInfo::LookupClass(Thread* thread,
- const Smi& name_index) const {
+ClassPtr KernelProgramInfo::LookupClass(Thread* thread,
+ const Smi& name_index) const {
REUSABLE_ARRAY_HANDLESCOPE(thread);
REUSABLE_CLASS_HANDLESCOPE(thread);
REUSABLE_OBJECT_HANDLESCOPE(thread);
@@ -13199,9 +13190,9 @@
return result.raw();
}
-RawClass* KernelProgramInfo::InsertClass(Thread* thread,
- const Smi& name_index,
- const Class& klass) const {
+ClassPtr KernelProgramInfo::InsertClass(Thread* thread,
+ const Smi& name_index,
+ const Class& klass) const {
REUSABLE_ARRAY_HANDLESCOPE(thread);
REUSABLE_CLASS_HANDLESCOPE(thread);
REUSABLE_OBJECT_HANDLESCOPE(thread);
@@ -13227,7 +13218,7 @@
StorePointer(&raw_ptr()->bytecode_component_, bytecode_component.raw());
}
-RawError* Library::CompileAll(bool ignore_error /* = false */) {
+ErrorPtr Library::CompileAll(bool ignore_error /* = false */) {
Thread* thread = Thread::Current();
Zone* zone = thread->zone();
Error& error = Error::Handle(zone);
@@ -13275,7 +13266,7 @@
#if !defined(DART_PRECOMPILED_RUNTIME)
-RawError* Library::FinalizeAllClasses() {
+ErrorPtr Library::FinalizeAllClasses() {
Thread* thread = Thread::Current();
ASSERT(thread->IsMutatorThread());
Zone* zone = thread->zone();
@@ -13307,7 +13298,7 @@
return Error::null();
}
-RawError* Library::ReadAllBytecode() {
+ErrorPtr Library::ReadAllBytecode() {
Thread* thread = Thread::Current();
ASSERT(thread->IsMutatorThread());
Zone* zone = thread->zone();
@@ -13337,9 +13328,9 @@
#endif // !defined(DART_PRECOMPILED_RUNTIME)
// Return Function::null() if function does not exist in libs.
-RawFunction* Library::GetFunction(const GrowableArray<Library*>& libs,
- const char* class_name,
- const char* function_name) {
+FunctionPtr Library::GetFunction(const GrowableArray<Library*>& libs,
+ const char* class_name,
+ const char* function_name) {
Thread* thread = Thread::Current();
Zone* zone = thread->zone();
Function& func = Function::Handle(zone);
@@ -13369,7 +13360,7 @@
return Function::null();
}
-RawObject* Library::GetFunctionClosure(const String& name) const {
+ObjectPtr Library::GetFunctionClosure(const String& name) const {
Thread* thread = Thread::Current();
Zone* zone = thread->zone();
Function& func = Function::Handle(zone, LookupFunctionAllowPrivate(name));
@@ -13460,7 +13451,7 @@
}
#endif // defined(DEBUG) && !defined(DART_PRECOMPILED_RUNTIME).
-RawInstructions* Instructions::New(intptr_t size, bool has_monomorphic_entry) {
+InstructionsPtr Instructions::New(intptr_t size, bool has_monomorphic_entry) {
ASSERT(size >= 0);
ASSERT(Object::instructions_class() != Class::null());
if (size < 0 || size > kMaxElements) {
@@ -13470,7 +13461,7 @@
Instructions& result = Instructions::Handle();
{
uword aligned_size = Instructions::InstanceSize(size);
- RawObject* raw =
+ ObjectPtr raw =
Object::Allocate(Instructions::kClassId, aligned_size, Heap::kCode);
NoSafepointScope no_safepoint;
result ^= raw;
@@ -13533,7 +13524,7 @@
return Utils::DecodeSLEB128<intptr_t>(data, Length(), byte_index);
}
-RawObjectPool* ObjectPool::New(intptr_t len) {
+ObjectPoolPtr ObjectPool::New(intptr_t len) {
ASSERT(Object::object_pool_class() != Class::null());
if (len < 0 || len > kMaxElements) {
// This should be caught before we reach here.
@@ -13542,7 +13533,7 @@
ObjectPool& result = ObjectPool::Handle();
{
uword size = ObjectPool::InstanceSize(len);
- RawObject* raw = Object::Allocate(ObjectPool::kClassId, size, Heap::kOld);
+ ObjectPtr raw = Object::Allocate(ObjectPool::kClassId, size, Heap::kOld);
NoSafepointScope no_safepoint;
result ^= raw;
result.SetLength(len);
@@ -13556,7 +13547,7 @@
}
#if !defined(DART_PRECOMPILED_RUNTIME)
-RawObjectPool* ObjectPool::NewFromBuilder(
+ObjectPoolPtr ObjectPool::NewFromBuilder(
const compiler::ObjectPoolBuilder& builder) {
const intptr_t len = builder.CurrentLength();
if (len == 0) {
@@ -13653,14 +13644,13 @@
}
}
-RawPcDescriptors* PcDescriptors::New(GrowableArray<uint8_t>* data) {
+PcDescriptorsPtr PcDescriptors::New(GrowableArray<uint8_t>* data) {
ASSERT(Object::pc_descriptors_class() != Class::null());
Thread* thread = Thread::Current();
PcDescriptors& result = PcDescriptors::Handle(thread->zone());
{
uword size = PcDescriptors::InstanceSize(data->length());
- RawObject* raw =
- Object::Allocate(PcDescriptors::kClassId, size, Heap::kOld);
+ ObjectPtr raw = Object::Allocate(PcDescriptors::kClassId, size, Heap::kOld);
NoSafepointScope no_safepoint;
result ^= raw;
result.SetLength(data->length());
@@ -13669,14 +13659,13 @@
return result.raw();
}
-RawPcDescriptors* PcDescriptors::New(intptr_t length) {
+PcDescriptorsPtr PcDescriptors::New(intptr_t length) {
ASSERT(Object::pc_descriptors_class() != Class::null());
Thread* thread = Thread::Current();
PcDescriptors& result = PcDescriptors::Handle(thread->zone());
{
uword size = PcDescriptors::InstanceSize(length);
- RawObject* raw =
- Object::Allocate(PcDescriptors::kClassId, size, Heap::kOld);
+ ObjectPtr raw = Object::Allocate(PcDescriptors::kClassId, size, Heap::kOld);
NoSafepointScope no_safepoint;
result ^= raw;
result.SetLength(length);
@@ -13684,25 +13673,25 @@
return result.raw();
}
-const char* PcDescriptors::KindAsStr(RawPcDescriptors::Kind kind) {
+const char* PcDescriptors::KindAsStr(PcDescriptorsLayout::Kind kind) {
switch (kind) {
- case RawPcDescriptors::kDeopt:
+ case PcDescriptorsLayout::kDeopt:
return "deopt ";
- case RawPcDescriptors::kIcCall:
+ case PcDescriptorsLayout::kIcCall:
return "ic-call ";
- case RawPcDescriptors::kUnoptStaticCall:
+ case PcDescriptorsLayout::kUnoptStaticCall:
return "unopt-call ";
- case RawPcDescriptors::kRuntimeCall:
+ case PcDescriptorsLayout::kRuntimeCall:
return "runtime-call ";
- case RawPcDescriptors::kOsrEntry:
+ case PcDescriptorsLayout::kOsrEntry:
return "osr-entry ";
- case RawPcDescriptors::kRewind:
+ case PcDescriptorsLayout::kRewind:
return "rewind ";
- case RawPcDescriptors::kBSSRelocation:
+ case PcDescriptorsLayout::kBSSRelocation:
return "bss reloc ";
- case RawPcDescriptors::kOther:
+ case PcDescriptorsLayout::kOther:
return "other ";
- case RawPcDescriptors::kAnyKind:
+ case PcDescriptorsLayout::kAnyKind:
UNREACHABLE();
break;
}
@@ -13731,7 +13720,7 @@
// First compute the buffer size required.
intptr_t len = 1; // Trailing '\0'.
{
- Iterator iter(*this, RawPcDescriptors::kAnyKind);
+ Iterator iter(*this, PcDescriptorsLayout::kAnyKind);
while (iter.MoveNext()) {
len += Utils::SNPrint(NULL, 0, FORMAT, addr_width, iter.PcOffset(),
KindAsStr(iter.Kind()), iter.DeoptId(),
@@ -13743,7 +13732,7 @@
char* buffer = Thread::Current()->zone()->Alloc<char>(len);
// Layout the fields in the buffer.
intptr_t index = 0;
- Iterator iter(*this, RawPcDescriptors::kAnyKind);
+ Iterator iter(*this, PcDescriptorsLayout::kAnyKind);
while (iter.MoveNext()) {
index += Utils::SNPrint((buffer + index), (len - index), FORMAT, addr_width,
iter.PcOffset(), KindAsStr(iter.Kind()),
@@ -13767,7 +13756,7 @@
}
intptr_t max_deopt_id = 0;
Iterator max_iter(*this,
- RawPcDescriptors::kDeopt | RawPcDescriptors::kIcCall);
+ PcDescriptorsLayout::kDeopt | PcDescriptorsLayout::kIcCall);
while (max_iter.MoveNext()) {
if (max_iter.DeoptId() > max_deopt_id) {
max_deopt_id = max_iter.DeoptId();
@@ -13777,7 +13766,8 @@
Zone* zone = Thread::Current()->zone();
BitVector* deopt_ids = new (zone) BitVector(zone, max_deopt_id + 1);
BitVector* iccall_ids = new (zone) BitVector(zone, max_deopt_id + 1);
- Iterator iter(*this, RawPcDescriptors::kDeopt | RawPcDescriptors::kIcCall);
+ Iterator iter(*this,
+ PcDescriptorsLayout::kDeopt | PcDescriptorsLayout::kIcCall);
while (iter.MoveNext()) {
// 'deopt_id' is set for kDeopt and kIcCall and must be unique for one kind.
if (DeoptId::IsDeoptAfter(iter.DeoptId())) {
@@ -13786,7 +13776,7 @@
// lead to issues in the future. Fix that and enable verification.
continue;
}
- if (iter.Kind() == RawPcDescriptors::kDeopt) {
+ if (iter.Kind() == PcDescriptorsLayout::kDeopt) {
ASSERT(!deopt_ids->Contains(iter.DeoptId()));
deopt_ids->Add(iter.DeoptId());
} else {
@@ -13801,14 +13791,13 @@
StoreNonPointer(&raw_ptr()->length_, value);
}
-RawCodeSourceMap* CodeSourceMap::New(intptr_t length) {
+CodeSourceMapPtr CodeSourceMap::New(intptr_t length) {
ASSERT(Object::code_source_map_class() != Class::null());
Thread* thread = Thread::Current();
CodeSourceMap& result = CodeSourceMap::Handle(thread->zone());
{
uword size = CodeSourceMap::InstanceSize(length);
- RawObject* raw =
- Object::Allocate(CodeSourceMap::kClassId, size, Heap::kOld);
+ ObjectPtr raw = Object::Allocate(CodeSourceMap::kClassId, size, Heap::kOld);
NoSafepointScope no_safepoint;
result ^= raw;
result.SetLength(length);
@@ -13829,7 +13818,7 @@
return FinalizeHash(hash, kHashBits);
}
-RawCompressedStackMaps* CompressedStackMaps::New(
+CompressedStackMapsPtr CompressedStackMaps::New(
const GrowableArray<uint8_t>& payload,
bool is_global_table,
bool uses_global_table) {
@@ -13839,7 +13828,7 @@
auto& result = CompressedStackMaps::Handle();
const uintptr_t payload_size = payload.length();
- if (!RawCompressedStackMaps::SizeField::is_valid(payload_size)) {
+ if (!CompressedStackMapsLayout::SizeField::is_valid(payload_size)) {
FATAL1(
"Fatal error in CompressedStackMaps::New: "
"invalid payload size %" Pu "\n",
@@ -13848,16 +13837,16 @@
{
// CompressedStackMaps data objects are associated with a code object,
// allocate them in old generation.
- RawObject* raw = Object::Allocate(
+ ObjectPtr raw = Object::Allocate(
CompressedStackMaps::kClassId,
CompressedStackMaps::InstanceSize(payload_size), Heap::kOld);
NoSafepointScope no_safepoint;
result ^= raw;
result.StoreNonPointer(
&result.raw_ptr()->flags_and_size_,
- RawCompressedStackMaps::GlobalTableBit::encode(is_global_table) |
- RawCompressedStackMaps::UsesTableBit::encode(uses_global_table) |
- RawCompressedStackMaps::SizeField::encode(payload_size));
+ CompressedStackMapsLayout::GlobalTableBit::encode(is_global_table) |
+ CompressedStackMapsLayout::UsesTableBit::encode(uses_global_table) |
+ CompressedStackMapsLayout::SizeField::encode(payload_size));
auto cursor = result.UnsafeMutableNonPointer(result.raw_ptr()->data());
memcpy(cursor, payload.data(), payload.length()); // NOLINT
}
@@ -13877,35 +13866,37 @@
return it.ToCString(zone);
}
-RawString* LocalVarDescriptors::GetName(intptr_t var_index) const {
+StringPtr LocalVarDescriptors::GetName(intptr_t var_index) const {
ASSERT(var_index < Length());
- ASSERT(Object::Handle(*raw()->nameAddrAt(var_index)).IsString());
- return *raw()->nameAddrAt(var_index);
+ ASSERT(Object::Handle(*raw()->ptr()->nameAddrAt(var_index)).IsString());
+ return *raw()->ptr()->nameAddrAt(var_index);
}
-void LocalVarDescriptors::SetVar(intptr_t var_index,
- const String& name,
- RawLocalVarDescriptors::VarInfo* info) const {
+void LocalVarDescriptors::SetVar(
+ intptr_t var_index,
+ const String& name,
+ LocalVarDescriptorsLayout::VarInfo* info) const {
ASSERT(var_index < Length());
ASSERT(!name.IsNull());
- StorePointer(raw()->nameAddrAt(var_index), name.raw());
- raw()->data()[var_index] = *info;
+ StorePointer(raw()->ptr()->nameAddrAt(var_index), name.raw());
+ raw()->ptr()->data()[var_index] = *info;
}
-void LocalVarDescriptors::GetInfo(intptr_t var_index,
- RawLocalVarDescriptors::VarInfo* info) const {
+void LocalVarDescriptors::GetInfo(
+ intptr_t var_index,
+ LocalVarDescriptorsLayout::VarInfo* info) const {
ASSERT(var_index < Length());
- *info = raw()->data()[var_index];
+ *info = raw()->ptr()->data()[var_index];
}
static int PrintVarInfo(char* buffer,
int len,
intptr_t i,
const String& var_name,
- const RawLocalVarDescriptors::VarInfo& info) {
- const RawLocalVarDescriptors::VarInfoKind kind = info.kind();
+ const LocalVarDescriptorsLayout::VarInfo& info) {
+ const LocalVarDescriptorsLayout::VarInfoKind kind = info.kind();
const int32_t index = info.index();
- if (kind == RawLocalVarDescriptors::kContextLevel) {
+ if (kind == LocalVarDescriptorsLayout::kContextLevel) {
return Utils::SNPrint(buffer, len,
"%2" Pd
" %-13s level=%-3d"
@@ -13913,7 +13904,7 @@
i, LocalVarDescriptors::KindToCString(kind), index,
static_cast<int>(info.begin_pos.value()),
static_cast<int>(info.end_pos.value()));
- } else if (kind == RawLocalVarDescriptors::kContextVar) {
+ } else if (kind == LocalVarDescriptorsLayout::kContextVar) {
return Utils::SNPrint(
buffer, len,
"%2" Pd
@@ -13944,7 +13935,7 @@
intptr_t len = 1; // Trailing '\0'.
String& var_name = String::Handle();
for (intptr_t i = 0; i < Length(); i++) {
- RawLocalVarDescriptors::VarInfo info;
+ LocalVarDescriptorsLayout::VarInfo info;
var_name = GetName(i);
GetInfo(i, &info);
len += PrintVarInfo(NULL, 0, i, var_name, info);
@@ -13953,7 +13944,7 @@
buffer[0] = '\0';
intptr_t num_chars = 0;
for (intptr_t i = 0; i < Length(); i++) {
- RawLocalVarDescriptors::VarInfo info;
+ LocalVarDescriptorsLayout::VarInfo info;
var_name = GetName(i);
GetInfo(i, &info);
num_chars += PrintVarInfo((buffer + num_chars), (len - num_chars), i,
@@ -13963,15 +13954,15 @@
}
const char* LocalVarDescriptors::KindToCString(
- RawLocalVarDescriptors::VarInfoKind kind) {
+ LocalVarDescriptorsLayout::VarInfoKind kind) {
switch (kind) {
- case RawLocalVarDescriptors::kStackVar:
+ case LocalVarDescriptorsLayout::kStackVar:
return "StackVar";
- case RawLocalVarDescriptors::kContextVar:
+ case LocalVarDescriptorsLayout::kContextVar:
return "ContextVar";
- case RawLocalVarDescriptors::kContextLevel:
+ case LocalVarDescriptorsLayout::kContextLevel:
return "ContextLevel";
- case RawLocalVarDescriptors::kSavedCurrentContext:
+ case LocalVarDescriptorsLayout::kSavedCurrentContext:
return "CurrentCtx";
default:
UNIMPLEMENTED();
@@ -13979,19 +13970,19 @@
}
}
-RawLocalVarDescriptors* LocalVarDescriptors::New(intptr_t num_variables) {
+LocalVarDescriptorsPtr LocalVarDescriptors::New(intptr_t num_variables) {
ASSERT(Object::var_descriptors_class() != Class::null());
if (num_variables < 0 || num_variables > kMaxElements) {
// This should be caught before we reach here.
FATAL2(
"Fatal error in LocalVarDescriptors::New: "
"invalid num_variables %" Pd ". Maximum is: %d\n",
- num_variables, RawLocalVarDescriptors::kMaxIndex);
+ num_variables, LocalVarDescriptorsLayout::kMaxIndex);
}
LocalVarDescriptors& result = LocalVarDescriptors::Handle();
{
uword size = LocalVarDescriptors::InstanceSize(num_variables);
- RawObject* raw =
+ ObjectPtr raw =
Object::Allocate(LocalVarDescriptors::kClassId, size, Heap::kOld);
NoSafepointScope no_safepoint;
result ^= raw;
@@ -14070,7 +14061,7 @@
handled_types_data.SetAt(try_index, handled_types);
}
-RawArray* ExceptionHandlers::GetHandledTypes(intptr_t try_index) const {
+ArrayPtr ExceptionHandlers::GetHandledTypes(intptr_t try_index) const {
ASSERT((try_index >= 0) && (try_index < num_entries()));
Array& array = Array::Handle(raw_ptr()->handled_types_data_);
array ^= array.At(try_index);
@@ -14081,7 +14072,7 @@
StorePointer(&raw_ptr()->handled_types_data_, value.raw());
}
-RawExceptionHandlers* ExceptionHandlers::New(intptr_t num_handlers) {
+ExceptionHandlersPtr ExceptionHandlers::New(intptr_t num_handlers) {
ASSERT(Object::exception_handlers_class() != Class::null());
if ((num_handlers < 0) || (num_handlers >= kMaxHandlers)) {
FATAL1(
@@ -14092,7 +14083,7 @@
ExceptionHandlers& result = ExceptionHandlers::Handle();
{
uword size = ExceptionHandlers::InstanceSize(num_handlers);
- RawObject* raw =
+ ObjectPtr raw =
Object::Allocate(ExceptionHandlers::kClassId, size, Heap::kOld);
NoSafepointScope no_safepoint;
result ^= raw;
@@ -14105,7 +14096,7 @@
return result.raw();
}
-RawExceptionHandlers* ExceptionHandlers::New(const Array& handled_types_data) {
+ExceptionHandlersPtr ExceptionHandlers::New(const Array& handled_types_data) {
ASSERT(Object::exception_handlers_class() != Class::null());
const intptr_t num_handlers = handled_types_data.Length();
if ((num_handlers < 0) || (num_handlers >= kMaxHandlers)) {
@@ -14117,7 +14108,7 @@
ExceptionHandlers& result = ExceptionHandlers::Handle();
{
uword size = ExceptionHandlers::InstanceSize(num_handlers);
- RawObject* raw =
+ ObjectPtr raw =
Object::Allocate(ExceptionHandlers::kClassId, size, Heap::kOld);
NoSafepointScope no_safepoint;
result ^= raw;
@@ -14200,10 +14191,10 @@
Object::Handle(zone, name()).ToCString());
}
-RawParameterTypeCheck* ParameterTypeCheck::New() {
+ParameterTypeCheckPtr ParameterTypeCheck::New() {
ParameterTypeCheck& result = ParameterTypeCheck::Handle();
{
- RawObject* raw =
+ ObjectPtr raw =
Object::Allocate(ParameterTypeCheck::kClassId,
ParameterTypeCheck::InstanceSize(), Heap::kOld);
NoSafepointScope no_safepoint;
@@ -14221,11 +14212,11 @@
return "SingleTargetCache";
}
-RawSingleTargetCache* SingleTargetCache::New() {
+SingleTargetCachePtr SingleTargetCache::New() {
SingleTargetCache& result = SingleTargetCache::Handle();
{
// IC data objects are long living objects, allocate them in old generation.
- RawObject* raw =
+ ObjectPtr raw =
Object::Allocate(SingleTargetCache::kClassId,
SingleTargetCache::InstanceSize(), Heap::kOld);
NoSafepointScope no_safepoint;
@@ -14264,7 +14255,7 @@
return "UnlinkedCall";
}
-RawUnlinkedCall* UnlinkedCall::New() {
+UnlinkedCallPtr UnlinkedCall::New() {
UnlinkedCall& result = UnlinkedCall::Handle();
result ^= Object::Allocate(UnlinkedCall::kClassId,
UnlinkedCall::InstanceSize(), Heap::kOld);
@@ -14272,8 +14263,8 @@
return result.raw();
}
-RawMonomorphicSmiableCall* MonomorphicSmiableCall::New(classid_t expected_cid,
- const Code& target) {
+MonomorphicSmiableCallPtr MonomorphicSmiableCall::New(classid_t expected_cid,
+ const Code& target) {
auto& result = MonomorphicSmiableCall::Handle();
result ^=
Object::Allocate(MonomorphicSmiableCall::kClassId,
@@ -14331,7 +14322,7 @@
name.ToCString(), num_args, num_checks, type_args_len);
}
-RawFunction* ICData::Owner() const {
+FunctionPtr ICData::Owner() const {
Object& obj = Object::Handle(raw_ptr()->owner_);
if (obj.IsNull()) {
ASSERT(Dart::vm_snapshot_kind() == Snapshot::kFullAOT);
@@ -14345,7 +14336,7 @@
}
}
-RawICData* ICData::Original() const {
+ICDataPtr ICData::Original() const {
if (IsNull()) {
return ICData::null();
}
@@ -14360,11 +14351,11 @@
void ICData::SetOriginal(const ICData& value) const {
ASSERT(value.IsOriginal());
ASSERT(!value.IsNull());
- StorePointer(&raw_ptr()->owner_, reinterpret_cast<RawObject*>(value.raw()));
+ StorePointer(&raw_ptr()->owner_, static_cast<ObjectPtr>(value.raw()));
}
void ICData::set_owner(const Function& value) const {
- StorePointer(&raw_ptr()->owner_, reinterpret_cast<RawObject*>(value.raw()));
+ StorePointer(&raw_ptr()->owner_, static_cast<ObjectPtr>(value.raw()));
}
void ICData::set_deopt_id(intptr_t value) const {
@@ -14378,8 +14369,8 @@
void ICData::set_entries(const Array& value) const {
ASSERT(!value.IsNull());
- StorePointer<RawArray*, std::memory_order_release>(&raw_ptr()->entries_,
- value.raw());
+ StorePointer<ArrayPtr, std::memory_order_release>(&raw_ptr()->entries_,
+ value.raw());
}
intptr_t ICData::NumArgsTested() const {
@@ -14782,7 +14773,7 @@
set_entries(data);
}
-RawArray* ICData::Grow(intptr_t* index) const {
+ArrayPtr ICData::Grow(intptr_t* index) const {
Array& data = Array::Handle(entries());
// Last entry in array should be a sentinel and will be the new entry
// that can be updated after growing.
@@ -14968,11 +14959,11 @@
ASSERT(!IsSentinelAt(index));
const intptr_t data_pos = index * TestEntryLength();
NoSafepointScope no_safepoint;
- RawArray* raw_data = entries();
+ ArrayPtr raw_data = entries();
return Smi::Value(Smi::RawCast(raw_data->ptr()->data()[data_pos]));
}
-RawFunction* ICData::GetTargetAt(intptr_t index) const {
+FunctionPtr ICData::GetTargetAt(intptr_t index) const {
#if defined(DART_PRECOMPILED_RUNTIME)
UNREACHABLE();
return nullptr;
@@ -14982,17 +14973,17 @@
ASSERT(Object::Handle(Array::Handle(entries()).At(data_pos)).IsFunction());
NoSafepointScope no_safepoint;
- RawArray* raw_data = entries();
- return reinterpret_cast<RawFunction*>(raw_data->ptr()->data()[data_pos]);
+ ArrayPtr raw_data = entries();
+ return static_cast<FunctionPtr>(raw_data->ptr()->data()[data_pos]);
#endif
}
-RawObject* ICData::GetTargetOrCodeAt(intptr_t index) const {
+ObjectPtr ICData::GetTargetOrCodeAt(intptr_t index) const {
const intptr_t data_pos =
index * TestEntryLength() + TargetIndexFor(NumArgsTested());
NoSafepointScope no_safepoint;
- RawArray* raw_data = entries();
+ ArrayPtr raw_data = entries();
return raw_data->ptr()->data()[data_pos];
}
@@ -15075,8 +15066,8 @@
}
#if !defined(DART_PRECOMPILED_RUNTIME)
-RawICData* ICData::AsUnaryClassChecksForCid(intptr_t cid,
- const Function& target) const {
+ICDataPtr ICData::AsUnaryClassChecksForCid(intptr_t cid,
+ const Function& target) const {
ASSERT(!IsNull());
const intptr_t kNumArgsTested = 1;
ICData& result = ICData::Handle(ICData::NewFrom(*this, kNumArgsTested));
@@ -15086,7 +15077,7 @@
return result.raw();
}
-RawICData* ICData::AsUnaryClassChecksForArgNr(intptr_t arg_nr) const {
+ICDataPtr ICData::AsUnaryClassChecksForArgNr(intptr_t arg_nr) const {
ASSERT(!IsNull());
ASSERT(NumArgsTested() > arg_nr);
if ((arg_nr == 0) && (NumArgsTested() == 1)) {
@@ -15144,7 +15135,7 @@
return (a->count < b->count) ? 1 : 0;
}
-RawICData* ICData::AsUnaryClassChecksSortedByCount() const {
+ICDataPtr ICData::AsUnaryClassChecksSortedByCount() const {
ASSERT(!IsNull());
const intptr_t kNumArgsTested = 1;
const intptr_t len = NumberOfChecks();
@@ -15196,7 +15187,7 @@
return result.raw();
}
-RawUnlinkedCall* ICData::AsUnlinkedCall() const {
+UnlinkedCallPtr ICData::AsUnlinkedCall() const {
ASSERT(NumArgsTested() == 1);
ASSERT(!is_tracking_exactness());
const UnlinkedCall& result = UnlinkedCall::Handle(UnlinkedCall::New());
@@ -15255,8 +15246,8 @@
}
}
-RawArray* ICData::NewNonCachedEmptyICDataArray(intptr_t num_args_tested,
- bool tracking_exactness) {
+ArrayPtr ICData::NewNonCachedEmptyICDataArray(intptr_t num_args_tested,
+ bool tracking_exactness) {
// IC data array must be null terminated (sentinel entry).
const intptr_t len = TestEntryLengthFor(num_args_tested, tracking_exactness);
const Array& array = Array::Handle(Array::New(len, Heap::kOld));
@@ -15265,8 +15256,8 @@
return array.raw();
}
-RawArray* ICData::CachedEmptyICDataArray(intptr_t num_args_tested,
- bool tracking_exactness) {
+ArrayPtr ICData::CachedEmptyICDataArray(intptr_t num_args_tested,
+ bool tracking_exactness) {
if (tracking_exactness) {
ASSERT(num_args_tested == 1);
return cached_icdata_arrays_[kCachedICDataOneArgWithExactnessTrackingIdx];
@@ -15281,14 +15272,14 @@
}
// Does not initialize ICData array.
-RawICData* ICData::NewDescriptor(Zone* zone,
- const Function& owner,
- const String& target_name,
- const Array& arguments_descriptor,
- intptr_t deopt_id,
- intptr_t num_args_tested,
- RebindRule rebind_rule,
- const AbstractType& receivers_static_type) {
+ICDataPtr ICData::NewDescriptor(Zone* zone,
+ const Function& owner,
+ const String& target_name,
+ const Array& arguments_descriptor,
+ intptr_t deopt_id,
+ intptr_t num_args_tested,
+ RebindRule rebind_rule,
+ const AbstractType& receivers_static_type) {
#if !defined(DART_PRECOMPILED_RUNTIME)
// We should only have null owners in the precompiled runtime, if the
// owning function for a Code object was optimized out.
@@ -15301,7 +15292,7 @@
ICData& result = ICData::Handle(zone);
{
// IC data objects are long living objects, allocate them in old generation.
- RawObject* raw =
+ ObjectPtr raw =
Object::Allocate(ICData::kClassId, ICData::InstanceSize(), Heap::kOld);
NoSafepointScope no_safepoint;
result ^= raw;
@@ -15321,11 +15312,11 @@
return entries()->IsImmutableArray();
}
-RawICData* ICData::New() {
+ICDataPtr ICData::New() {
ICData& result = ICData::Handle();
{
// IC data objects are long living objects, allocate them in old generation.
- RawObject* raw =
+ ObjectPtr raw =
Object::Allocate(ICData::kClassId, ICData::InstanceSize(), Heap::kOld);
NoSafepointScope no_safepoint;
result ^= raw;
@@ -15335,13 +15326,13 @@
return result.raw();
}
-RawICData* ICData::New(const Function& owner,
- const String& target_name,
- const Array& arguments_descriptor,
- intptr_t deopt_id,
- intptr_t num_args_tested,
- RebindRule rebind_rule,
- const AbstractType& receivers_static_type) {
+ICDataPtr ICData::New(const Function& owner,
+ const String& target_name,
+ const Array& arguments_descriptor,
+ intptr_t deopt_id,
+ intptr_t num_args_tested,
+ RebindRule rebind_rule,
+ const AbstractType& receivers_static_type) {
Zone* zone = Thread::Current()->zone();
const ICData& result = ICData::Handle(
zone,
@@ -15354,7 +15345,7 @@
}
#if !defined(DART_PRECOMPILED_RUNTIME)
-RawICData* ICData::NewFrom(const ICData& from, intptr_t num_args_tested) {
+ICDataPtr ICData::NewFrom(const ICData& from, intptr_t num_args_tested) {
// See comment in [ICData::Clone] why we access the megamorphic bit first.
const bool is_megamorphic = from.is_megamorphic();
@@ -15369,7 +15360,7 @@
return result.raw();
}
-RawICData* ICData::Clone(const ICData& from) {
+ICDataPtr ICData::Clone(const ICData& from) {
Zone* zone = Thread::Current()->zone();
// We have to check the megamorphic bit before accessing the entries of the
@@ -15425,14 +15416,14 @@
object.raw()->IsHeapObject() && !object.IsWeakSerializationReference();
}
-RawObject* WeakSerializationReference::Wrap(Zone* zone, const Object& target) {
+ObjectPtr WeakSerializationReference::Wrap(Zone* zone, const Object& target) {
if (!CanWrap(target)) return target.raw();
ASSERT(Object::weak_serialization_reference_class() != Class::null());
WeakSerializationReference& result = WeakSerializationReference::Handle(zone);
{
- RawObject* raw = Object::Allocate(
- WeakSerializationReference::kClassId,
- WeakSerializationReference::InstanceSize(), Heap::kOld);
+ ObjectPtr raw = Object::Allocate(WeakSerializationReference::kClassId,
+ WeakSerializationReference::InstanceSize(),
+ Heap::kOld);
NoSafepointScope no_safepoint;
result ^= raw;
@@ -15476,7 +15467,7 @@
Smi::Handle(Smi::New(pc)));
}
-RawString* Code::Comments::CommentAt(intptr_t idx) const {
+StringPtr Code::Comments::CommentAt(intptr_t idx) const {
return String::RawCast(comments_.At(idx * kNumberOfEntries + kCommentEntry));
}
@@ -15519,7 +15510,7 @@
return false;
}
-RawLocalVarDescriptors* Code::GetLocalVarDescriptors() const {
+LocalVarDescriptorsPtr Code::GetLocalVarDescriptors() const {
const LocalVarDescriptors& v = LocalVarDescriptors::Handle(var_descriptors());
if (v.IsNull()) {
ASSERT(!is_optimized());
@@ -15575,7 +15566,7 @@
#endif
#if defined(DART_PRECOMPILED_RUNTIME) || defined(DART_PRECOMPILER)
-RawTypedData* Code::catch_entry_moves_maps() const {
+TypedDataPtr Code::catch_entry_moves_maps() const {
ASSERT(FLAG_precompiled_mode);
return TypedData::RawCast(raw_ptr()->catch_entry_);
}
@@ -15616,7 +15607,7 @@
#endif // DEBUG
}
-RawObjectPool* Code::GetObjectPool() const {
+ObjectPoolPtr Code::GetObjectPool() const {
#if defined(DART_PRECOMPILED_RUNTIME)
if (FLAG_use_bare_instructions) {
return Isolate::Current()->object_store()->global_object_pool();
@@ -15633,9 +15624,9 @@
#endif
}
-RawTypedData* Code::GetDeoptInfoAtPc(uword pc,
- ICData::DeoptReasonId* deopt_reason,
- uint32_t* deopt_flags) const {
+TypedDataPtr Code::GetDeoptInfoAtPc(uword pc,
+ ICData::DeoptReasonId* deopt_reason,
+ uint32_t* deopt_flags) const {
#if defined(DART_PRECOMPILED_RUNTIME)
ASSERT(Dart::vm_snapshot_kind() == Snapshot::kFullAOT);
return TypedData::null();
@@ -15693,7 +15684,7 @@
return -1;
}
-RawFunction* Code::GetStaticCallTargetFunctionAt(uword pc) const {
+FunctionPtr Code::GetStaticCallTargetFunctionAt(uword pc) const {
#if defined(DART_PRECOMPILED_RUNTIME)
UNREACHABLE();
return Function::null();
@@ -15780,7 +15771,7 @@
#else
ASSERT(offset >= 0);
StoreSmi(
- reinterpret_cast<RawSmi* const*>(&raw_ptr()->return_address_metadata_),
+ reinterpret_cast<SmiPtr const*>(&raw_ptr()->return_address_metadata_),
Smi::New(offset));
#endif
}
@@ -15800,7 +15791,7 @@
#endif
}
-RawArray* Code::inlined_id_to_function() const {
+ArrayPtr Code::inlined_id_to_function() const {
return raw_ptr()->inlined_id_to_function_;
}
@@ -15809,7 +15800,7 @@
StorePointer(&raw_ptr()->inlined_id_to_function_, value.raw());
}
-RawCode* Code::New(intptr_t pointer_offsets_length) {
+CodePtr Code::New(intptr_t pointer_offsets_length) {
if (pointer_offsets_length < 0 || pointer_offsets_length > kMaxElements) {
// This should be caught before we reach here.
FATAL1("Fatal error in Code::New: invalid pointer_offsets_length %" Pd "\n",
@@ -15819,7 +15810,7 @@
Code& result = Code::Handle();
{
uword size = Code::InstanceSize(pointer_offsets_length);
- RawObject* raw = Object::Allocate(Code::kClassId, size, Heap::kOld);
+ ObjectPtr raw = Object::Allocate(Code::kClassId, size, Heap::kOld);
NoSafepointScope no_safepoint;
result ^= raw;
result.set_pointer_offsets_length(pointer_offsets_length);
@@ -15834,12 +15825,12 @@
}
#if !defined(DART_PRECOMPILED_RUNTIME)
-RawCode* Code::FinalizeCodeAndNotify(const Function& function,
- FlowGraphCompiler* compiler,
- compiler::Assembler* assembler,
- PoolAttachment pool_attachment,
- bool optimized,
- CodeStatistics* stats) {
+CodePtr Code::FinalizeCodeAndNotify(const Function& function,
+ FlowGraphCompiler* compiler,
+ compiler::Assembler* assembler,
+ PoolAttachment pool_attachment,
+ bool optimized,
+ CodeStatistics* stats) {
DEBUG_ASSERT(IsMutatorOrAtSafepoint());
const auto& code = Code::Handle(
FinalizeCode(compiler, assembler, pool_attachment, optimized, stats));
@@ -15847,12 +15838,12 @@
return code.raw();
}
-RawCode* Code::FinalizeCodeAndNotify(const char* name,
- FlowGraphCompiler* compiler,
- compiler::Assembler* assembler,
- PoolAttachment pool_attachment,
- bool optimized,
- CodeStatistics* stats) {
+CodePtr Code::FinalizeCodeAndNotify(const char* name,
+ FlowGraphCompiler* compiler,
+ compiler::Assembler* assembler,
+ PoolAttachment pool_attachment,
+ bool optimized,
+ CodeStatistics* stats) {
DEBUG_ASSERT(IsMutatorOrAtSafepoint());
const auto& code = Code::Handle(
FinalizeCode(compiler, assembler, pool_attachment, optimized, stats));
@@ -15864,11 +15855,11 @@
DECLARE_FLAG(charp, write_v8_snapshot_profile_to);
#endif // defined(DART_PRECOMPILER)
-RawCode* Code::FinalizeCode(FlowGraphCompiler* compiler,
- compiler::Assembler* assembler,
- PoolAttachment pool_attachment,
- bool optimized,
- CodeStatistics* stats /* = nullptr */) {
+CodePtr Code::FinalizeCode(FlowGraphCompiler* compiler,
+ compiler::Assembler* assembler,
+ PoolAttachment pool_attachment,
+ bool optimized,
+ CodeStatistics* stats /* = nullptr */) {
DEBUG_ASSERT(IsMutatorOrAtSafepoint());
ASSERT(assembler != NULL);
@@ -15934,17 +15925,17 @@
ASSERT(object->IsOld());
// N.B. The pointer is embedded in the Instructions object, but visited
// through the Code object.
- code.raw()->StorePointer(reinterpret_cast<RawObject**>(addr),
- object->raw());
+ code.raw()->ptr()->StorePointer(reinterpret_cast<ObjectPtr*>(addr),
+ object->raw());
}
// Write protect instructions and, if supported by OS, use dual mapping
// for execution.
if (FLAG_write_protect_code) {
- uword address = RawObject::ToAddr(instrs.raw());
+ uword address = ObjectLayout::ToAddr(instrs.raw());
// Check if a dual mapping exists.
instrs = Instructions::RawCast(HeapPage::ToExecutable(instrs.raw()));
- uword exec_address = RawObject::ToAddr(instrs.raw());
+ uword exec_address = ObjectLayout::ToAddr(instrs.raw());
const bool use_dual_mapping = exec_address != address;
ASSERT(use_dual_mapping == FLAG_dual_map_code);
@@ -15953,14 +15944,14 @@
// Yet the writable mapping is still turned back from RW to R.
if (use_dual_mapping) {
VirtualMemory::Protect(reinterpret_cast<void*>(address),
- instrs.raw()->HeapSize(),
+ instrs.raw()->ptr()->HeapSize(),
VirtualMemory::kReadOnly);
address = exec_address;
} else {
// If dual mapping is disabled and we write protect then we have to
// change the single mapping from RW -> RX.
VirtualMemory::Protect(reinterpret_cast<void*>(address),
- instrs.raw()->HeapSize(),
+ instrs.raw()->ptr()->HeapSize(),
VirtualMemory::kReadExecute);
}
}
@@ -16049,34 +16040,34 @@
}
#endif // !defined(DART_PRECOMPILED_RUNTIME)
-bool Code::SlowFindRawCodeVisitor::FindObject(RawObject* raw_obj) const {
- return RawCode::ContainsPC(raw_obj, pc_);
+bool Code::SlowFindRawCodeVisitor::FindObject(ObjectPtr raw_obj) const {
+ return CodeLayout::ContainsPC(raw_obj, pc_);
}
-RawCode* Code::LookupCodeInIsolate(Isolate* isolate, uword pc) {
+CodePtr Code::LookupCodeInIsolate(Isolate* isolate, uword pc) {
ASSERT((isolate == Isolate::Current()) || (isolate == Dart::vm_isolate()));
if (isolate->heap() == NULL) {
return Code::null();
}
HeapIterationScope heap_iteration_scope(Thread::Current());
SlowFindRawCodeVisitor visitor(pc);
- RawObject* needle = isolate->heap()->FindOldObject(&visitor);
+ ObjectPtr needle = isolate->heap()->FindOldObject(&visitor);
if (needle != Code::null()) {
- return static_cast<RawCode*>(needle);
+ return static_cast<CodePtr>(needle);
}
return Code::null();
}
-RawCode* Code::LookupCode(uword pc) {
+CodePtr Code::LookupCode(uword pc) {
return LookupCodeInIsolate(Isolate::Current(), pc);
}
-RawCode* Code::LookupCodeInVmIsolate(uword pc) {
+CodePtr Code::LookupCodeInVmIsolate(uword pc) {
return LookupCodeInIsolate(Dart::vm_isolate(), pc);
}
// Given a pc and a timestamp, lookup the code.
-RawCode* Code::FindCode(uword pc, int64_t timestamp) {
+CodePtr Code::FindCode(uword pc, int64_t timestamp) {
Code& code = Code::Handle(Code::LookupCode(pc));
if (!code.IsNull() && (code.compile_timestamp() == timestamp) &&
(code.PayloadStart() == pc)) {
@@ -16095,7 +16086,7 @@
TokenPosition Code::GetTokenIndexOfPC(uword pc) const {
uword pc_offset = pc - PayloadStart();
const PcDescriptors& descriptors = PcDescriptors::Handle(pc_descriptors());
- PcDescriptors::Iterator iter(descriptors, RawPcDescriptors::kAnyKind);
+ PcDescriptors::Iterator iter(descriptors, PcDescriptorsLayout::kAnyKind);
while (iter.MoveNext()) {
if (iter.PcOffset() == pc_offset) {
return iter.TokenPos();
@@ -16105,7 +16096,7 @@
}
uword Code::GetPcForDeoptId(intptr_t deopt_id,
- RawPcDescriptors::Kind kind) const {
+ PcDescriptorsLayout::Kind kind) const {
const PcDescriptors& descriptors = PcDescriptors::Handle(pc_descriptors());
PcDescriptors::Iterator iter(descriptors, kind);
while (iter.MoveNext()) {
@@ -16122,7 +16113,7 @@
intptr_t Code::GetDeoptIdForOsr(uword pc) const {
uword pc_offset = pc - PayloadStart();
const PcDescriptors& descriptors = PcDescriptors::Handle(pc_descriptors());
- PcDescriptors::Iterator iter(descriptors, RawPcDescriptors::kOsrEntry);
+ PcDescriptors::Iterator iter(descriptors, PcDescriptorsLayout::kOsrEntry);
while (iter.MoveNext()) {
if (iter.PcOffset() == pc_offset) {
return iter.DeoptId();
@@ -16219,8 +16210,8 @@
new_code.UncheckedEntryPointOffset());
}
-void Code::InitializeCachedEntryPointsFrom(RawCode* code,
- RawInstructions* instructions,
+void Code::InitializeCachedEntryPointsFrom(CodePtr code,
+ InstructionsPtr instructions,
uint32_t unchecked_offset) {
NoSafepointScope _;
const uword entry_point = Instructions::EntryPoint(instructions);
@@ -16328,15 +16319,15 @@
#endif // !defined(PRODUCT) || defined(FORCE_INCLUDE_DISASSEMBLER)
}
-RawBytecode* Bytecode::New(uword instructions,
- intptr_t instructions_size,
- intptr_t instructions_offset,
- const ObjectPool& object_pool) {
+BytecodePtr Bytecode::New(uword instructions,
+ intptr_t instructions_size,
+ intptr_t instructions_offset,
+ const ObjectPool& object_pool) {
ASSERT(Object::bytecode_class() != Class::null());
Bytecode& result = Bytecode::Handle();
{
uword size = Bytecode::InstanceSize();
- RawObject* raw = Object::Allocate(Bytecode::kClassId, size, Heap::kOld);
+ ObjectPtr raw = Object::Allocate(Bytecode::kClassId, size, Heap::kOld);
NoSafepointScope no_safepoint;
result ^= raw;
result.set_instructions(instructions);
@@ -16350,7 +16341,7 @@
return result.raw();
}
-RawExternalTypedData* Bytecode::GetBinary(Zone* zone) const {
+ExternalTypedDataPtr Bytecode::GetBinary(Zone* zone) const {
const Function& func = Function::Handle(zone, function());
if (func.IsNull()) {
return ExternalTypedData::null();
@@ -16391,7 +16382,7 @@
intptr_t try_index = -1;
const uword pc_offset = return_address - PayloadStart();
const PcDescriptors& descriptors = PcDescriptors::Handle(pc_descriptors());
- PcDescriptors::Iterator iter(descriptors, RawPcDescriptors::kAnyKind);
+ PcDescriptors::Iterator iter(descriptors, PcDescriptorsLayout::kAnyKind);
while (iter.MoveNext()) {
// PC descriptors for try blocks in bytecode are generated in pairs,
// marking start and end of a try block.
@@ -16505,23 +16496,22 @@
return zone->PrintToString("[Bytecode] %s", function_name);
}
-bool Bytecode::SlowFindRawBytecodeVisitor::FindObject(
- RawObject* raw_obj) const {
- return RawBytecode::ContainsPC(raw_obj, pc_);
+bool Bytecode::SlowFindRawBytecodeVisitor::FindObject(ObjectPtr raw_obj) const {
+ return BytecodeLayout::ContainsPC(raw_obj, pc_);
}
-RawBytecode* Bytecode::FindCode(uword pc) {
+BytecodePtr Bytecode::FindCode(uword pc) {
Thread* thread = Thread::Current();
HeapIterationScope heap_iteration_scope(thread);
SlowFindRawBytecodeVisitor visitor(pc);
- RawObject* needle = thread->heap()->FindOldObject(&visitor);
+ ObjectPtr needle = thread->heap()->FindOldObject(&visitor);
if (needle != Bytecode::null()) {
- return static_cast<RawBytecode*>(needle);
+ return static_cast<BytecodePtr>(needle);
}
return Bytecode::null();
}
-RawLocalVarDescriptors* Bytecode::GetLocalVarDescriptors() const {
+LocalVarDescriptorsPtr Bytecode::GetLocalVarDescriptors() const {
#if defined(PRODUCT) || defined(DART_PRECOMPILED_RUNTIME)
UNREACHABLE();
return LocalVarDescriptors::null();
@@ -16550,7 +16540,7 @@
return level;
}
-RawContext* Context::New(intptr_t num_variables, Heap::Space space) {
+ContextPtr Context::New(intptr_t num_variables, Heap::Space space) {
ASSERT(num_variables >= 0);
ASSERT(Object::context_class() != Class::null());
@@ -16561,7 +16551,7 @@
}
Context& result = Context::Handle();
{
- RawObject* raw = Object::Allocate(
+ ObjectPtr raw = Object::Allocate(
Context::kClassId, Context::InstanceSize(num_variables), space);
NoSafepointScope no_safepoint;
result ^= raw;
@@ -16621,7 +16611,7 @@
THR_Print("}\n");
}
-RawContextScope* ContextScope::New(intptr_t num_variables, bool is_implicit) {
+ContextScopePtr ContextScope::New(intptr_t num_variables, bool is_implicit) {
ASSERT(Object::context_scope_class() != Class::null());
if (num_variables < 0 || num_variables > kMaxElements) {
// This should be caught before we reach here.
@@ -16631,7 +16621,7 @@
intptr_t size = ContextScope::InstanceSize(num_variables);
ContextScope& result = ContextScope::Handle();
{
- RawObject* raw = Object::Allocate(ContextScope::kClassId, size, Heap::kOld);
+ ObjectPtr raw = Object::Allocate(ContextScope::kClassId, size, Heap::kOld);
NoSafepointScope no_safepoint;
result ^= raw;
result.set_num_variables(num_variables);
@@ -16663,7 +16653,7 @@
Smi::New(declaration_token_pos.value()));
}
-RawString* ContextScope::NameAt(intptr_t scope_index) const {
+StringPtr ContextScope::NameAt(intptr_t scope_index) const {
return VariableDescAddr(scope_index)->name;
}
@@ -16688,27 +16678,27 @@
}
bool ContextScope::IsFinalAt(intptr_t scope_index) const {
- return GetFlagAt(scope_index, RawContextScope::VariableDesc::kIsFinal);
+ return GetFlagAt(scope_index, ContextScopeLayout::VariableDesc::kIsFinal);
}
void ContextScope::SetIsFinalAt(intptr_t scope_index, bool is_final) const {
- SetFlagAt(scope_index, RawContextScope::VariableDesc::kIsFinal, is_final);
+ SetFlagAt(scope_index, ContextScopeLayout::VariableDesc::kIsFinal, is_final);
}
bool ContextScope::IsLateAt(intptr_t scope_index) const {
- return GetFlagAt(scope_index, RawContextScope::VariableDesc::kIsLate);
+ return GetFlagAt(scope_index, ContextScopeLayout::VariableDesc::kIsLate);
}
void ContextScope::SetIsLateAt(intptr_t scope_index, bool is_late) const {
- SetFlagAt(scope_index, RawContextScope::VariableDesc::kIsLate, is_late);
+ SetFlagAt(scope_index, ContextScopeLayout::VariableDesc::kIsLate, is_late);
}
bool ContextScope::IsConstAt(intptr_t scope_index) const {
- return GetFlagAt(scope_index, RawContextScope::VariableDesc::kIsConst);
+ return GetFlagAt(scope_index, ContextScopeLayout::VariableDesc::kIsConst);
}
void ContextScope::SetIsConstAt(intptr_t scope_index, bool is_const) const {
- SetFlagAt(scope_index, RawContextScope::VariableDesc::kIsConst, is_const);
+ SetFlagAt(scope_index, ContextScopeLayout::VariableDesc::kIsConst, is_const);
}
intptr_t ContextScope::LateInitOffsetAt(intptr_t scope_index) const {
@@ -16721,7 +16711,7 @@
Smi::New(late_init_offset));
}
-RawAbstractType* ContextScope::TypeAt(intptr_t scope_index) const {
+AbstractTypePtr ContextScope::TypeAt(intptr_t scope_index) const {
ASSERT(!IsConstAt(scope_index));
return VariableDescAddr(scope_index)->type;
}
@@ -16731,7 +16721,7 @@
StorePointer(&(VariableDescAddr(scope_index)->type), type.raw());
}
-RawInstance* ContextScope::ConstValueAt(intptr_t scope_index) const {
+InstancePtr ContextScope::ConstValueAt(intptr_t scope_index) const {
ASSERT(IsConstAt(scope_index));
return VariableDescAddr(scope_index)->value;
}
@@ -16780,7 +16770,7 @@
return prev_cstr;
}
-RawArray* MegamorphicCache::buckets() const {
+ArrayPtr MegamorphicCache::buckets() const {
return raw_ptr()->buckets_;
}
@@ -16807,10 +16797,10 @@
StoreNonPointer(&raw_ptr()->filled_entry_count_, count);
}
-RawMegamorphicCache* MegamorphicCache::New() {
+MegamorphicCachePtr MegamorphicCache::New() {
MegamorphicCache& result = MegamorphicCache::Handle();
{
- RawObject* raw =
+ ObjectPtr raw =
Object::Allocate(MegamorphicCache::kClassId,
MegamorphicCache::InstanceSize(), Heap::kOld);
NoSafepointScope no_safepoint;
@@ -16820,11 +16810,11 @@
return result.raw();
}
-RawMegamorphicCache* MegamorphicCache::New(const String& target_name,
- const Array& arguments_descriptor) {
+MegamorphicCachePtr MegamorphicCache::New(const String& target_name,
+ const Array& arguments_descriptor) {
MegamorphicCache& result = MegamorphicCache::Handle();
{
- RawObject* raw =
+ ObjectPtr raw =
Object::Allocate(MegamorphicCache::kClassId,
MegamorphicCache::InstanceSize(), Heap::kOld);
NoSafepointScope no_safepoint;
@@ -16916,10 +16906,10 @@
intptr_t capacity = mask() + 1;
for (intptr_t i = 0; i < capacity; ++i) {
const intptr_t target_index = i * kEntryLength + kTargetFunctionIndex;
- RawObject** slot = &Array::DataOf(buckets())[target_index];
+ ObjectPtr* slot = &Array::DataOf(buckets())[target_index];
const intptr_t cid = (*slot)->GetClassIdMayBeSmi();
if (cid == kFunctionCid) {
- RawCode* code = Function::CurrentCodeOf(Function::RawCast(*slot));
+ CodePtr code = Function::CurrentCodeOf(Function::RawCast(*slot));
*slot = Smi::FromAlignedAddress(Code::EntryPointOf(code));
} else {
ASSERT(cid == kSmiCid);
@@ -16935,13 +16925,13 @@
cached_array_ = NULL;
}
-RawSubtypeTestCache* SubtypeTestCache::New() {
+SubtypeTestCachePtr SubtypeTestCache::New() {
ASSERT(Object::subtypetestcache_class() != Class::null());
SubtypeTestCache& result = SubtypeTestCache::Handle();
{
// SubtypeTestCache objects are long living objects, allocate them in the
// old generation.
- RawObject* raw =
+ ObjectPtr raw =
Object::Allocate(SubtypeTestCache::kClassId,
SubtypeTestCache::InstanceSize(), Heap::kOld);
NoSafepointScope no_safepoint;
@@ -17036,14 +17026,14 @@
return "Error";
}
-RawApiError* ApiError::New() {
+ApiErrorPtr ApiError::New() {
ASSERT(Object::api_error_class() != Class::null());
- RawObject* raw = Object::Allocate(ApiError::kClassId,
- ApiError::InstanceSize(), Heap::kOld);
- return reinterpret_cast<RawApiError*>(raw);
+ ObjectPtr raw = Object::Allocate(ApiError::kClassId, ApiError::InstanceSize(),
+ Heap::kOld);
+ return static_cast<ApiErrorPtr>(raw);
}
-RawApiError* ApiError::New(const String& message, Heap::Space space) {
+ApiErrorPtr ApiError::New(const String& message, Heap::Space space) {
#ifndef PRODUCT
if (FLAG_print_stacktrace_at_api_error) {
OS::PrintErr("ApiError: %s\n", message.ToCString());
@@ -17054,7 +17044,7 @@
ASSERT(Object::api_error_class() != Class::null());
ApiError& result = ApiError::Handle();
{
- RawObject* raw =
+ ObjectPtr raw =
Object::Allocate(ApiError::kClassId, ApiError::InstanceSize(), space);
NoSafepointScope no_safepoint;
result ^= raw;
@@ -17076,26 +17066,26 @@
return "ApiError";
}
-RawLanguageError* LanguageError::New() {
+LanguageErrorPtr LanguageError::New() {
ASSERT(Object::language_error_class() != Class::null());
- RawObject* raw = Object::Allocate(LanguageError::kClassId,
- LanguageError::InstanceSize(), Heap::kOld);
- return reinterpret_cast<RawLanguageError*>(raw);
+ ObjectPtr raw = Object::Allocate(LanguageError::kClassId,
+ LanguageError::InstanceSize(), Heap::kOld);
+ return static_cast<LanguageErrorPtr>(raw);
}
-RawLanguageError* LanguageError::NewFormattedV(const Error& prev_error,
- const Script& script,
- TokenPosition token_pos,
- bool report_after_token,
- Report::Kind kind,
- Heap::Space space,
- const char* format,
- va_list args) {
+LanguageErrorPtr LanguageError::NewFormattedV(const Error& prev_error,
+ const Script& script,
+ TokenPosition token_pos,
+ bool report_after_token,
+ Report::Kind kind,
+ Heap::Space space,
+ const char* format,
+ va_list args) {
ASSERT(Object::language_error_class() != Class::null());
LanguageError& result = LanguageError::Handle();
{
- RawObject* raw = Object::Allocate(LanguageError::kClassId,
- LanguageError::InstanceSize(), space);
+ ObjectPtr raw = Object::Allocate(LanguageError::kClassId,
+ LanguageError::InstanceSize(), space);
NoSafepointScope no_safepoint;
result ^= raw;
}
@@ -17109,17 +17099,17 @@
return result.raw();
}
-RawLanguageError* LanguageError::NewFormatted(const Error& prev_error,
- const Script& script,
- TokenPosition token_pos,
- bool report_after_token,
- Report::Kind kind,
- Heap::Space space,
- const char* format,
- ...) {
+LanguageErrorPtr LanguageError::NewFormatted(const Error& prev_error,
+ const Script& script,
+ TokenPosition token_pos,
+ bool report_after_token,
+ Report::Kind kind,
+ Heap::Space space,
+ const char* format,
+ ...) {
va_list args;
va_start(args, format);
- RawLanguageError* result = LanguageError::NewFormattedV(
+ LanguageErrorPtr result = LanguageError::NewFormattedV(
prev_error, script, token_pos, report_after_token, kind, space, format,
args);
NoSafepointScope no_safepoint;
@@ -17127,14 +17117,14 @@
return result;
}
-RawLanguageError* LanguageError::New(const String& formatted_message,
- Report::Kind kind,
- Heap::Space space) {
+LanguageErrorPtr LanguageError::New(const String& formatted_message,
+ Report::Kind kind,
+ Heap::Space space) {
ASSERT(Object::language_error_class() != Class::null());
LanguageError& result = LanguageError::Handle();
{
- RawObject* raw = Object::Allocate(LanguageError::kClassId,
- LanguageError::InstanceSize(), space);
+ ObjectPtr raw = Object::Allocate(LanguageError::kClassId,
+ LanguageError::InstanceSize(), space);
NoSafepointScope no_safepoint;
result ^= raw;
}
@@ -17172,7 +17162,7 @@
StorePointer(&raw_ptr()->formatted_message_, value.raw());
}
-RawString* LanguageError::FormatMessage() const {
+StringPtr LanguageError::FormatMessage() const {
if (formatted_message() != String::null()) {
return formatted_message();
}
@@ -17200,15 +17190,14 @@
return "LanguageError";
}
-RawUnhandledException* UnhandledException::New(const Instance& exception,
- const Instance& stacktrace,
- Heap::Space space) {
+UnhandledExceptionPtr UnhandledException::New(const Instance& exception,
+ const Instance& stacktrace,
+ Heap::Space space) {
ASSERT(Object::unhandled_exception_class() != Class::null());
UnhandledException& result = UnhandledException::Handle();
{
- RawObject* raw =
- Object::Allocate(UnhandledException::kClassId,
- UnhandledException::InstanceSize(), space);
+ ObjectPtr raw = Object::Allocate(UnhandledException::kClassId,
+ UnhandledException::InstanceSize(), space);
NoSafepointScope no_safepoint;
result ^= raw;
}
@@ -17217,13 +17206,12 @@
return result.raw();
}
-RawUnhandledException* UnhandledException::New(Heap::Space space) {
+UnhandledExceptionPtr UnhandledException::New(Heap::Space space) {
ASSERT(Object::unhandled_exception_class() != Class::null());
UnhandledException& result = UnhandledException::Handle();
{
- RawObject* raw =
- Object::Allocate(UnhandledException::kClassId,
- UnhandledException::InstanceSize(), space);
+ ObjectPtr raw = Object::Allocate(UnhandledException::kClassId,
+ UnhandledException::InstanceSize(), space);
NoSafepointScope no_safepoint;
result ^= raw;
}
@@ -17275,12 +17263,12 @@
return "UnhandledException";
}
-RawUnwindError* UnwindError::New(const String& message, Heap::Space space) {
+UnwindErrorPtr UnwindError::New(const String& message, Heap::Space space) {
ASSERT(Object::unwind_error_class() != Class::null());
UnwindError& result = UnwindError::Handle();
{
- RawObject* raw = Object::Allocate(UnwindError::kClassId,
- UnwindError::InstanceSize(), space);
+ ObjectPtr raw = Object::Allocate(UnwindError::kClassId,
+ UnwindError::InstanceSize(), space);
NoSafepointScope no_safepoint;
result ^= raw;
}
@@ -17306,9 +17294,9 @@
return "UnwindError";
}
-RawObject* Instance::InvokeGetter(const String& getter_name,
- bool respect_reflectable,
- bool check_is_entrypoint) const {
+ObjectPtr Instance::InvokeGetter(const String& getter_name,
+ bool respect_reflectable,
+ bool check_is_entrypoint) const {
Thread* thread = Thread::Current();
Zone* zone = thread->zone();
@@ -17328,7 +17316,7 @@
// The getter must correspond to either an entry-point field or a getter
// method explicitly marked.
Field& field = Field::Handle(zone);
- if (function.kind() == RawFunction::kImplicitGetter) {
+ if (function.kind() == FunctionLayout::kImplicitGetter) {
field = function.accessor_field();
}
if (!field.IsNull()) {
@@ -17366,10 +17354,10 @@
type_args);
}
-RawObject* Instance::InvokeSetter(const String& setter_name,
- const Instance& value,
- bool respect_reflectable,
- bool check_is_entrypoint) const {
+ObjectPtr Instance::InvokeSetter(const String& setter_name,
+ const Instance& value,
+ bool respect_reflectable,
+ bool check_is_entrypoint) const {
Thread* thread = Thread::Current();
Zone* zone = thread->zone();
@@ -17389,7 +17377,7 @@
// The setter must correspond to either an entry-point field or a setter
// method explicitly marked.
Field& field = Field::Handle(zone);
- if (setter.kind() == RawFunction::kImplicitSetter) {
+ if (setter.kind() == FunctionLayout::kImplicitSetter) {
field = setter.accessor_field();
}
if (!field.IsNull()) {
@@ -17413,11 +17401,11 @@
type_args);
}
-RawObject* Instance::Invoke(const String& function_name,
- const Array& args,
- const Array& arg_names,
- bool respect_reflectable,
- bool check_is_entrypoint) const {
+ObjectPtr Instance::Invoke(const String& function_name,
+ const Array& args,
+ const Array& arg_names,
+ bool respect_reflectable,
+ bool check_is_entrypoint) const {
Thread* thread = Thread::Current();
Zone* zone = thread->zone();
Class& klass = Class::Handle(zone, clazz());
@@ -17449,7 +17437,7 @@
if (check_is_entrypoint) {
CHECK_ERROR(EntryPointFieldInvocationError(function_name));
}
- ASSERT(function.kind() != RawFunction::kMethodExtractor);
+ ASSERT(function.kind() != FunctionLayout::kMethodExtractor);
// Invoke the getter.
const int kNumArgs = 1;
const Array& getter_args = Array::Handle(zone, Array::New(kNumArgs));
@@ -17477,7 +17465,7 @@
type_args);
}
-RawObject* Instance::EvaluateCompiledExpression(
+ObjectPtr Instance::EvaluateCompiledExpression(
const Class& method_cls,
const ExternalTypedData& kernel_buffer,
const Array& type_definitions,
@@ -17499,13 +17487,13 @@
type_arguments);
}
-RawObject* Instance::HashCode() const {
+ObjectPtr Instance::HashCode() const {
// TODO(koda): Optimize for all builtin classes and all classes
// that do not override hashCode.
return DartLibraryCalls::HashCode(*this);
}
-RawObject* Instance::IdentityHashCode() const {
+ObjectPtr Instance::IdentityHashCode() const {
return DartLibraryCalls::IdentityHashCode(*this);
}
@@ -17532,8 +17520,8 @@
uword other_addr = reinterpret_cast<uword>(other.raw_ptr());
for (intptr_t offset = Instance::NextFieldOffset(); offset < instance_size;
offset += kWordSize) {
- if ((*reinterpret_cast<RawObject**>(this_addr + offset)) !=
- (*reinterpret_cast<RawObject**>(other_addr + offset))) {
+ if ((*reinterpret_cast<ObjectPtr*>(this_addr + offset)) !=
+ (*reinterpret_cast<ObjectPtr*>(other_addr + offset))) {
return false;
}
}
@@ -17567,7 +17555,7 @@
hash =
CombineHashes(hash, *reinterpret_cast<intptr_t*>(this_addr + offset));
} else {
- member ^= *reinterpret_cast<RawObject**>(this_addr + offset);
+ member ^= *reinterpret_cast<ObjectPtr*>(this_addr + offset);
hash = CombineHashes(hash, member.CanonicalizeHash());
}
}
@@ -17584,7 +17572,7 @@
bool has_pointers() const { return has_pointers_; }
- void VisitPointers(RawObject** first, RawObject** last) {
+ void VisitPointers(ObjectPtr* first, ObjectPtr* last) {
if (first != last) {
has_pointers_ = true;
}
@@ -17638,19 +17626,19 @@
#if defined(DEBUG)
// Make sure that we are not missing any fields.
CheckForPointers has_pointers(Isolate::Current()->group());
- this->raw()->VisitPointers(&has_pointers);
+ this->raw()->ptr()->VisitPointers(&has_pointers);
ASSERT(!has_pointers.has_pointers());
#endif // DEBUG
}
return true;
}
-RawInstance* Instance::CopyShallowToOldSpace(Thread* thread) const {
+InstancePtr Instance::CopyShallowToOldSpace(Thread* thread) const {
return Instance::RawCast(Object::Clone(*this, Heap::kOld));
}
-RawInstance* Instance::CheckAndCanonicalize(Thread* thread,
- const char** error_str) const {
+InstancePtr Instance::CheckAndCanonicalize(Thread* thread,
+ const char** error_str) const {
ASSERT(error_str != NULL);
ASSERT(*error_str == NULL);
ASSERT(!IsNull());
@@ -17695,7 +17683,7 @@
}
#endif // DEBUG
-RawObject* Instance::GetField(const Field& field) const {
+ObjectPtr Instance::GetField(const Field& field) const {
if (FLAG_precompiled_mode && field.is_unboxing_candidate()) {
switch (field.guarded_cid()) {
case kDoubleCid:
@@ -17750,7 +17738,7 @@
}
}
-RawAbstractType* Instance::GetType(Heap::Space space) const {
+AbstractTypePtr Instance::GetType(Heap::Space space) const {
if (IsNull()) {
return Type::NullType();
}
@@ -17791,7 +17779,7 @@
return type.raw();
}
-RawTypeArguments* Instance::GetTypeArguments() const {
+TypeArgumentsPtr Instance::GetTypeArguments() const {
ASSERT(!IsType());
const Class& cls = Class::Handle(clazz());
intptr_t field_offset = cls.host_type_arguments_field_offset();
@@ -18064,8 +18052,7 @@
intptr_t* Instance::NativeFieldsDataAddr() const {
ASSERT(Thread::Current()->no_safepoint_scope_depth() > 0);
- RawTypedData* native_fields =
- reinterpret_cast<RawTypedData*>(*NativeFieldsAddr());
+ TypedDataPtr native_fields = static_cast<TypedDataPtr>(*NativeFieldsAddr());
if (native_fields == TypedData::null()) {
return NULL;
}
@@ -18123,24 +18110,24 @@
return false;
}
-RawInstance* Instance::New(const Class& cls, Heap::Space space) {
+InstancePtr Instance::New(const Class& cls, Heap::Space space) {
Thread* thread = Thread::Current();
if (cls.EnsureIsFinalized(thread) != Error::null()) {
return Instance::null();
}
intptr_t instance_size = cls.host_instance_size();
ASSERT(instance_size > 0);
- RawObject* raw = Object::Allocate(cls.id(), instance_size, space);
- return reinterpret_cast<RawInstance*>(raw);
+ ObjectPtr raw = Object::Allocate(cls.id(), instance_size, space);
+ return static_cast<InstancePtr>(raw);
}
-RawInstance* Instance::NewFromCidAndSize(SharedClassTable* shared_class_table,
- classid_t cid,
- Heap::Space heap) {
+InstancePtr Instance::NewFromCidAndSize(SharedClassTable* shared_class_table,
+ classid_t cid,
+ Heap::Space heap) {
const intptr_t instance_size = shared_class_table->SizeAt(cid);
ASSERT(instance_size > 0);
- RawObject* raw = Object::Allocate(cid, instance_size, heap);
- return reinterpret_cast<RawInstance*>(raw);
+ ObjectPtr raw = Object::Allocate(cid, instance_size, heap);
+ return static_cast<InstancePtr>(raw);
}
bool Instance::IsValidFieldOffset(intptr_t offset) const {
@@ -18229,13 +18216,13 @@
return kIllegalCid;
}
-RawClass* AbstractType::type_class() const {
+ClassPtr AbstractType::type_class() const {
// AbstractType is an abstract class.
UNREACHABLE();
return Class::null();
}
-RawTypeArguments* AbstractType::arguments() const {
+TypeArgumentsPtr AbstractType::arguments() const {
// AbstractType is an abstract class.
UNREACHABLE();
return NULL;
@@ -18284,7 +18271,7 @@
return true;
}
-RawAbstractType* AbstractType::SetInstantiatedNullability(
+AbstractTypePtr AbstractType::SetInstantiatedNullability(
const TypeParameter& type_param,
Heap::Space space) const {
Nullability result_nullability;
@@ -18321,7 +18308,7 @@
.SetInstantiatedNullability(type_param, space);
}
-RawAbstractType* AbstractType::NormalizeFutureOrType(Heap::Space space) const {
+AbstractTypePtr AbstractType::NormalizeFutureOrType(Heap::Space space) const {
if (Dart::non_nullable_flag()) {
if (IsFutureOrType()) {
const AbstractType& unwrapped_type =
@@ -18348,7 +18335,7 @@
ASSERT(!cls.IsNull());
const TypeArguments& type_args =
TypeArguments::Handle(TypeArguments::New(1));
- type_args.SetTypeAt(0, never_type());
+ type_args.SetTypeAt(0, Type::Handle(object_store->never_type()));
Type& type =
Type::Handle(Type::New(cls, type_args, TokenPosition::kNoSource,
Nullability::kNonNullable));
@@ -18430,7 +18417,7 @@
return false;
}
-RawAbstractType* AbstractType::InstantiateFrom(
+AbstractTypePtr AbstractType::InstantiateFrom(
const TypeArguments& instantiator_type_arguments,
const TypeArguments& function_type_arguments,
intptr_t num_free_fun_type_params,
@@ -18441,7 +18428,7 @@
return NULL;
}
-RawAbstractType* AbstractType::Canonicalize(TrailPtr trail) const {
+AbstractTypePtr AbstractType::Canonicalize(TrailPtr trail) const {
// AbstractType is an abstract class.
UNREACHABLE();
return NULL;
@@ -18452,7 +18439,7 @@
UNREACHABLE();
}
-RawAbstractType* AbstractType::OnlyBuddyInTrail(TrailPtr trail) const {
+AbstractTypePtr AbstractType::OnlyBuddyInTrail(TrailPtr trail) const {
if (trail == NULL) {
return AbstractType::null();
}
@@ -18547,7 +18534,7 @@
}
}
-RawString* AbstractType::PrintURIs(URIs* uris) {
+StringPtr AbstractType::PrintURIs(URIs* uris) {
ASSERT(uris != NULL);
Thread* thread = Thread::Current();
Zone* zone = thread->zone();
@@ -18588,14 +18575,14 @@
}
}
-RawString* AbstractType::Name() const {
+StringPtr AbstractType::Name() const {
Thread* thread = Thread::Current();
ZoneTextBuffer printer(thread->zone());
PrintName(kInternalName, &printer);
return Symbols::New(thread, printer.buffer());
}
-RawString* AbstractType::UserVisibleName() const {
+StringPtr AbstractType::UserVisibleName() const {
Thread* thread = Thread::Current();
ZoneTextBuffer printer(thread->zone());
PrintName(kUserVisibleName, &printer);
@@ -18683,7 +18670,7 @@
// the type.
}
-RawString* AbstractType::ClassName() const {
+StringPtr AbstractType::ClassName() const {
ASSERT(!IsFunctionType());
return Class::Handle(type_class()).Name();
}
@@ -18781,7 +18768,7 @@
return HasTypeClass() && type_class_id() == kFfiPointerCid;
}
-RawAbstractType* AbstractType::UnwrapFutureOr() const {
+AbstractTypePtr AbstractType::UnwrapFutureOr() const {
if (!IsFutureOrType()) {
return raw();
}
@@ -18957,8 +18944,7 @@
if (stub.IsNull()) {
// This only happens during bootstrapping when creating Type objects before
// we have the instructions.
- ASSERT(type_class_id() == kDynamicCid || type_class_id() == kVoidCid ||
- type_class_id() == kNeverCid);
+ ASSERT(type_class_id() == kDynamicCid || type_class_id() == kVoidCid);
StoreNonPointer(&raw_ptr()->type_test_stub_entry_point_, 0);
} else {
StoreNonPointer(&raw_ptr()->type_test_stub_entry_point_, stub.EntryPoint());
@@ -18966,87 +18952,87 @@
StorePointer(&raw_ptr()->type_test_stub_, stub.raw());
}
-RawType* Type::NullType() {
+TypePtr Type::NullType() {
return Isolate::Current()->object_store()->null_type();
}
-RawType* Type::DynamicType() {
+TypePtr Type::DynamicType() {
return Object::dynamic_type().raw();
}
-RawType* Type::VoidType() {
+TypePtr Type::VoidType() {
return Object::void_type().raw();
}
-RawType* Type::NeverType() {
- return Object::never_type().raw();
+TypePtr Type::NeverType() {
+ return Isolate::Current()->object_store()->never_type();
}
-RawType* Type::ObjectType() {
+TypePtr Type::ObjectType() {
return Isolate::Current()->object_store()->object_type();
}
-RawType* Type::BoolType() {
+TypePtr Type::BoolType() {
return Isolate::Current()->object_store()->bool_type();
}
-RawType* Type::IntType() {
+TypePtr Type::IntType() {
return Isolate::Current()->object_store()->int_type();
}
-RawType* Type::NullableIntType() {
+TypePtr Type::NullableIntType() {
return Isolate::Current()->object_store()->nullable_int_type();
}
-RawType* Type::SmiType() {
+TypePtr Type::SmiType() {
return Isolate::Current()->object_store()->smi_type();
}
-RawType* Type::MintType() {
+TypePtr Type::MintType() {
return Isolate::Current()->object_store()->mint_type();
}
-RawType* Type::Double() {
+TypePtr Type::Double() {
return Isolate::Current()->object_store()->double_type();
}
-RawType* Type::NullableDouble() {
+TypePtr Type::NullableDouble() {
return Isolate::Current()->object_store()->nullable_double_type();
}
-RawType* Type::Float32x4() {
+TypePtr Type::Float32x4() {
return Isolate::Current()->object_store()->float32x4_type();
}
-RawType* Type::Float64x2() {
+TypePtr Type::Float64x2() {
return Isolate::Current()->object_store()->float64x2_type();
}
-RawType* Type::Int32x4() {
+TypePtr Type::Int32x4() {
return Isolate::Current()->object_store()->int32x4_type();
}
-RawType* Type::Number() {
+TypePtr Type::Number() {
return Isolate::Current()->object_store()->number_type();
}
-RawType* Type::StringType() {
+TypePtr Type::StringType() {
return Isolate::Current()->object_store()->string_type();
}
-RawType* Type::ArrayType() {
+TypePtr Type::ArrayType() {
return Isolate::Current()->object_store()->array_type();
}
-RawType* Type::DartFunctionType() {
+TypePtr Type::DartFunctionType() {
return Isolate::Current()->object_store()->function_type();
}
-RawType* Type::DartTypeType() {
+TypePtr Type::DartTypeType() {
return Isolate::Current()->object_store()->type_type();
}
-RawType* Type::NewNonParameterizedType(const Class& type_class) {
+TypePtr Type::NewNonParameterizedType(const Class& type_class) {
ASSERT(type_class.NumTypeArguments() == 0);
if (type_class.IsNullClass()) {
return Type::NullType();
@@ -19076,24 +19062,24 @@
void Type::SetIsFinalized() const {
ASSERT(!IsFinalized());
if (IsInstantiated()) {
- set_type_state(RawType::kFinalizedInstantiated);
+ set_type_state(TypeLayout::kFinalizedInstantiated);
} else {
- set_type_state(RawType::kFinalizedUninstantiated);
+ set_type_state(TypeLayout::kFinalizedUninstantiated);
}
}
void Type::ResetIsFinalized() const {
ASSERT(IsFinalized());
- set_type_state(RawType::kBeingFinalized);
+ set_type_state(TypeLayout::kBeingFinalized);
SetIsFinalized();
}
void Type::SetIsBeingFinalized() const {
ASSERT(!IsFinalized() && !IsBeingFinalized());
- set_type_state(RawType::kBeingFinalized);
+ set_type_state(TypeLayout::kBeingFinalized);
}
-RawType* Type::ToNullability(Nullability value, Heap::Space space) const {
+TypePtr Type::ToNullability(Nullability value, Heap::Space space) const {
if (nullability() == value) {
return raw();
}
@@ -19126,7 +19112,7 @@
return type.raw();
}
-RawFunction* Type::signature() const {
+FunctionPtr Type::signature() const {
intptr_t cid = raw_ptr()->signature_->GetClassId();
if (cid == kNullCid) {
return Function::null();
@@ -19143,18 +19129,18 @@
return Smi::Value(raw_ptr()->type_class_id_);
}
-RawClass* Type::type_class() const {
+ClassPtr Type::type_class() const {
return Isolate::Current()->class_table()->At(type_class_id());
}
bool Type::IsInstantiated(Genericity genericity,
intptr_t num_free_fun_type_params,
TrailPtr trail) const {
- if (raw_ptr()->type_state_ == RawType::kFinalizedInstantiated) {
+ if (raw_ptr()->type_state_ == TypeLayout::kFinalizedInstantiated) {
return true;
}
if ((genericity == kAny) && (num_free_fun_type_params == kAllFree) &&
- (raw_ptr()->type_state_ == RawType::kFinalizedUninstantiated)) {
+ (raw_ptr()->type_state_ == TypeLayout::kFinalizedUninstantiated)) {
return false;
}
if (IsFunctionType()) {
@@ -19188,7 +19174,7 @@
num_free_fun_type_params, trail);
}
-RawAbstractType* Type::InstantiateFrom(
+AbstractTypePtr Type::InstantiateFrom(
const TypeArguments& instantiator_type_arguments,
const TypeArguments& function_type_arguments,
intptr_t num_free_fun_type_params,
@@ -19455,7 +19441,7 @@
return nullability() == declaration_nullability;
}
-RawAbstractType* Type::Canonicalize(TrailPtr trail) const {
+AbstractTypePtr Type::Canonicalize(TrailPtr trail) const {
ASSERT(IsFinalized());
if (IsCanonical()) {
ASSERT(TypeArguments::Handle(arguments()).IsOld());
@@ -19484,7 +19470,8 @@
ASSERT(!cls.IsNullClass() || IsNullable());
Type& type = Type::Handle(zone, cls.declaration_type());
if (type.IsNull()) {
- ASSERT(!cls.raw()->InVMIsolateHeap() || (isolate == Dart::vm_isolate()));
+ ASSERT(!cls.raw()->ptr()->InVMIsolateHeap() ||
+ (isolate == Dart::vm_isolate()));
// Canonicalize the type arguments of the supertype, if any.
TypeArguments& type_args = TypeArguments::Handle(zone, arguments());
type_args = type_args.Canonicalize(trail);
@@ -19628,9 +19615,7 @@
#endif // DEBUG
void Type::EnumerateURIs(URIs* uris) const {
- // N.B. Not all types with kNeverCid answer true to IsNeverType, but none of
- // them have a URI.
- if (IsDynamicType() || IsVoidType() || (type_class_id() == kNeverCid)) {
+ if (IsDynamicType() || IsVoidType() || IsNeverType()) {
return;
}
Thread* thread = Thread::Current();
@@ -19707,24 +19692,24 @@
StorePointer(&raw_ptr()->arguments_, value.raw());
}
-RawType* Type::New(Heap::Space space) {
- RawObject* raw =
- Object::Allocate(Type::kClassId, Type::InstanceSize(), space);
- return reinterpret_cast<RawType*>(raw);
+TypePtr Type::New(Heap::Space space) {
+ ObjectPtr raw = Object::Allocate(Type::kClassId, Type::InstanceSize(), space);
+ return static_cast<TypePtr>(raw);
}
-RawType* Type::New(const Class& clazz,
- const TypeArguments& arguments,
- TokenPosition token_pos,
- Nullability nullability,
- Heap::Space space) {
+TypePtr Type::New(const Class& clazz,
+ const TypeArguments& arguments,
+ TokenPosition token_pos,
+ Nullability nullability,
+ Heap::Space space) {
Zone* Z = Thread::Current()->zone();
const Type& result = Type::Handle(Z, Type::New(space));
result.set_type_class(clazz);
result.set_arguments(arguments);
result.SetHash(0);
result.set_token_pos(token_pos);
- result.StoreNonPointer(&result.raw_ptr()->type_state_, RawType::kAllocated);
+ result.StoreNonPointer(&result.raw_ptr()->type_state_,
+ TypeLayout::kAllocated);
result.set_nullability(nullability);
result.SetTypeTestingStub(
@@ -19738,8 +19723,8 @@
}
void Type::set_type_state(int8_t state) const {
- ASSERT((state >= RawType::kAllocated) &&
- (state <= RawType::kFinalizedUninstantiated));
+ ASSERT((state >= TypeLayout::kAllocated) &&
+ (state <= TypeLayout::kFinalizedUninstantiated));
StoreNonPointer(&raw_ptr()->type_state_, state);
}
@@ -19814,7 +19799,7 @@
return !ref_type.IsNull() && ref_type.IsEquivalent(other, kind, trail);
}
-RawTypeRef* TypeRef::InstantiateFrom(
+AbstractTypePtr TypeRef::InstantiateFrom(
const TypeArguments& instantiator_type_arguments,
const TypeArguments& function_type_arguments,
intptr_t num_free_fun_type_params,
@@ -19857,7 +19842,7 @@
// Consider the type Derived, where class Derived extends Base<Derived>.
// The first type argument of its flattened type argument vector is Derived,
// represented by a TypeRef pointing to itself.
-RawAbstractType* TypeRef::Canonicalize(TrailPtr trail) const {
+AbstractTypePtr TypeRef::Canonicalize(TrailPtr trail) const {
if (TestAndAddToTrail(&trail)) {
return raw();
}
@@ -19905,13 +19890,13 @@
return FinalizeHash(result, kHashBits);
}
-RawTypeRef* TypeRef::New() {
- RawObject* raw =
+TypeRefPtr TypeRef::New() {
+ ObjectPtr raw =
Object::Allocate(TypeRef::kClassId, TypeRef::InstanceSize(), Heap::kOld);
- return reinterpret_cast<RawTypeRef*>(raw);
+ return static_cast<TypeRefPtr>(raw);
}
-RawTypeRef* TypeRef::New(const AbstractType& type) {
+TypeRefPtr TypeRef::New(const AbstractType& type) {
Zone* Z = Thread::Current()->zone();
const TypeRef& result = TypeRef::Handle(Z, TypeRef::New());
result.set_type(type);
@@ -19939,11 +19924,11 @@
void TypeParameter::SetIsFinalized() const {
ASSERT(!IsFinalized());
- set_flags(RawTypeParameter::FinalizedBit::update(true, raw_ptr()->flags_));
+ set_flags(TypeParameterLayout::FinalizedBit::update(true, raw_ptr()->flags_));
}
void TypeParameter::SetGenericCovariantImpl(bool value) const {
- set_flags(RawTypeParameter::GenericCovariantImplBit::update(
+ set_flags(TypeParameterLayout::GenericCovariantImplBit::update(
value, raw_ptr()->flags_));
}
@@ -19951,8 +19936,8 @@
StoreNonPointer(&raw_ptr()->nullability_, static_cast<int8_t>(value));
}
-RawTypeParameter* TypeParameter::ToNullability(Nullability value,
- Heap::Space space) const {
+TypeParameterPtr TypeParameter::ToNullability(Nullability value,
+ Heap::Space space) const {
if (nullability() == value) {
return raw();
}
@@ -20069,7 +20054,7 @@
return raw_ptr()->parameterized_class_id_;
}
-RawClass* TypeParameter::parameterized_class() const {
+ClassPtr TypeParameter::parameterized_class() const {
classid_t cid = parameterized_class_id();
if (cid == kFunctionCid) {
return Class::null();
@@ -20096,7 +20081,7 @@
StorePointer(&raw_ptr()->bound_, value.raw());
}
-RawAbstractType* TypeParameter::GetFromTypeArguments(
+AbstractTypePtr TypeParameter::GetFromTypeArguments(
const TypeArguments& instantiator_type_arguments,
const TypeArguments& function_type_arguments) const {
ASSERT(IsFinalized());
@@ -20106,7 +20091,7 @@
return type_args.TypeAtNullSafe(index());
}
-RawAbstractType* TypeParameter::InstantiateFrom(
+AbstractTypePtr TypeParameter::InstantiateFrom(
const TypeArguments& instantiator_type_arguments,
const TypeArguments& function_type_arguments,
intptr_t num_free_fun_type_params,
@@ -20196,20 +20181,20 @@
return result;
}
-RawTypeParameter* TypeParameter::New() {
- RawObject* raw = Object::Allocate(TypeParameter::kClassId,
- TypeParameter::InstanceSize(), Heap::kOld);
- return reinterpret_cast<RawTypeParameter*>(raw);
+TypeParameterPtr TypeParameter::New() {
+ ObjectPtr raw = Object::Allocate(TypeParameter::kClassId,
+ TypeParameter::InstanceSize(), Heap::kOld);
+ return static_cast<TypeParameterPtr>(raw);
}
-RawTypeParameter* TypeParameter::New(const Class& parameterized_class,
- const Function& parameterized_function,
- intptr_t index,
- const String& name,
- const AbstractType& bound,
- bool is_generic_covariant_impl,
- Nullability nullability,
- TokenPosition token_pos) {
+TypeParameterPtr TypeParameter::New(const Class& parameterized_class,
+ const Function& parameterized_function,
+ intptr_t index,
+ const String& name,
+ const AbstractType& bound,
+ bool is_generic_covariant_impl,
+ Nullability nullability,
+ TokenPosition token_pos) {
ASSERT(parameterized_class.IsNull() != parameterized_function.IsNull());
Zone* Z = Thread::Current()->zone();
const TypeParameter& result = TypeParameter::Handle(Z, TypeParameter::New());
@@ -20264,12 +20249,12 @@
return printer.buffer();
}
-RawInstance* Number::CheckAndCanonicalize(Thread* thread,
- const char** error_str) const {
+InstancePtr Number::CheckAndCanonicalize(Thread* thread,
+ const char** error_str) const {
intptr_t cid = GetClassId();
switch (cid) {
case kSmiCid:
- return reinterpret_cast<RawSmi*>(raw_value());
+ return static_cast<SmiPtr>(raw_value());
case kMintCid:
return Mint::NewCanonical(Mint::Cast(*this).value());
case kDoubleCid:
@@ -20317,7 +20302,7 @@
return "NULL Integer";
}
-RawInteger* Integer::New(const String& str, Heap::Space space) {
+IntegerPtr Integer::New(const String& str, Heap::Space space) {
// We are not supposed to have integers represented as two byte strings.
ASSERT(str.IsOneByteString());
if (str.IsNull() || (str.Length() == 0)) {
@@ -20332,7 +20317,7 @@
return Integer::New(value, space);
}
-RawInteger* Integer::NewCanonical(const String& str) {
+IntegerPtr Integer::NewCanonical(const String& str) {
// We are not supposed to have integers represented as two byte strings.
ASSERT(str.IsOneByteString());
int64_t value = 0;
@@ -20344,14 +20329,14 @@
return NewCanonical(value);
}
-RawInteger* Integer::NewCanonical(int64_t value) {
+IntegerPtr Integer::NewCanonical(int64_t value) {
if (Smi::IsValid(value)) {
return Smi::New(static_cast<intptr_t>(value));
}
return Mint::NewCanonical(value);
}
-RawInteger* Integer::New(int64_t value, Heap::Space space) {
+IntegerPtr Integer::New(int64_t value, Heap::Space space) {
const bool is_smi = Smi::IsValid(value);
if (is_smi) {
return Smi::New(static_cast<intptr_t>(value));
@@ -20359,7 +20344,7 @@
return Mint::New(value, space);
}
-RawInteger* Integer::NewFromUint64(uint64_t value, Heap::Space space) {
+IntegerPtr Integer::NewFromUint64(uint64_t value, Heap::Space space) {
return Integer::New(static_cast<int64_t>(value), space);
}
@@ -20415,7 +20400,7 @@
return 0;
}
-RawInteger* Integer::AsValidInteger() const {
+IntegerPtr Integer::AsValidInteger() const {
if (IsSmi()) return raw();
if (IsMint()) {
Mint& mint = Mint::Handle();
@@ -20439,9 +20424,9 @@
}
}
-RawInteger* Integer::ArithmeticOp(Token::Kind operation,
- const Integer& other,
- Heap::Space space) const {
+IntegerPtr Integer::ArithmeticOp(Token::Kind operation,
+ const Integer& other,
+ Heap::Space space) const {
// In 32-bit mode, the result of any operation between two Smis will fit in a
// 32-bit signed result, except the product of two Smis, which will be 64-bit.
// In 64-bit mode, the result of any operation between two Smis will fit in a
@@ -20521,9 +20506,9 @@
}
}
-RawInteger* Integer::BitOp(Token::Kind kind,
- const Integer& other,
- Heap::Space space) const {
+IntegerPtr Integer::BitOp(Token::Kind kind,
+ const Integer& other,
+ Heap::Space space) const {
if (IsSmi() && other.IsSmi()) {
intptr_t op1_value = Smi::Value(Smi::RawCast(raw()));
intptr_t op2_value = Smi::Value(Smi::RawCast(other.raw()));
@@ -20560,9 +20545,9 @@
}
}
-RawInteger* Integer::ShiftOp(Token::Kind kind,
- const Integer& other,
- Heap::Space space) const {
+IntegerPtr Integer::ShiftOp(Token::Kind kind,
+ const Integer& other,
+ Heap::Space space) const {
int64_t a = AsInt64Value();
int64_t b = other.AsInt64Value();
ASSERT(b >= 0);
@@ -20622,7 +20607,7 @@
return OS::SCreate(Thread::Current()->zone(), "%" Pd "", Value());
}
-RawClass* Smi::Class() {
+ClassPtr Smi::Class() {
return Isolate::Current()->object_store()->smi_class();
}
@@ -20630,13 +20615,13 @@
StoreNonPointer(&raw_ptr()->value_, value);
}
-RawMint* Mint::New(int64_t val, Heap::Space space) {
+MintPtr Mint::New(int64_t val, Heap::Space space) {
// Do not allocate a Mint if Smi would do.
ASSERT(!Smi::IsValid(val));
ASSERT(Isolate::Current()->object_store()->mint_class() != Class::null());
Mint& result = Mint::Handle();
{
- RawObject* raw =
+ ObjectPtr raw =
Object::Allocate(Mint::kClassId, Mint::InstanceSize(), space);
NoSafepointScope no_safepoint;
result ^= raw;
@@ -20645,7 +20630,7 @@
return result.raw();
}
-RawMint* Mint::NewCanonical(int64_t value) {
+MintPtr Mint::NewCanonical(int64_t value) {
// Do not allocate a Mint if Smi would do.
ASSERT(!Smi::IsValid(value));
Thread* thread = Thread::Current();
@@ -20756,11 +20741,11 @@
return Hash64To32(bit_cast<uint64_t>(value()));
}
-RawDouble* Double::New(double d, Heap::Space space) {
+DoublePtr Double::New(double d, Heap::Space space) {
ASSERT(Isolate::Current()->object_store()->double_class() != Class::null());
Double& result = Double::Handle();
{
- RawObject* raw =
+ ObjectPtr raw =
Object::Allocate(Double::kClassId, Double::InstanceSize(), space);
NoSafepointScope no_safepoint;
result ^= raw;
@@ -20769,7 +20754,7 @@
return result.raw();
}
-RawDouble* Double::New(const String& str, Heap::Space space) {
+DoublePtr Double::New(const String& str, Heap::Space space) {
double double_value;
if (!CStringToDouble(str.ToCString(), str.Length(), &double_value)) {
return Double::Handle().raw();
@@ -20777,7 +20762,7 @@
return New(double_value, space);
}
-RawDouble* Double::NewCanonical(double value) {
+DoublePtr Double::NewCanonical(double value) {
Thread* thread = Thread::Current();
Zone* zone = thread->zone();
Isolate* isolate = thread->isolate();
@@ -20807,7 +20792,7 @@
}
}
-RawDouble* Double::NewCanonical(const String& str) {
+DoublePtr Double::NewCanonical(const String& str) {
double double_value;
if (!CStringToDouble(str.ToCString(), str.Length(), &double_value)) {
return Double::Handle().raw();
@@ -20815,7 +20800,7 @@
return NewCanonical(double_value);
}
-RawString* Number::ToString(Heap::Space space) const {
+StringPtr Number::ToString(Heap::Space space) const {
// Refactoring can avoid Zone::Alloc and strlen, but gains are insignificant.
const char* cstr = ToCString();
intptr_t len = strlen(cstr);
@@ -20915,28 +20900,26 @@
return hasher.Finalize(String::kHashBits);
}
-intptr_t String::Hash(RawString* raw) {
+intptr_t String::Hash(StringPtr raw) {
StringHasher hasher;
uword length = Smi::Value(raw->ptr()->length_);
if (raw->IsOneByteString() || raw->IsExternalOneByteString()) {
const uint8_t* data;
if (raw->IsOneByteString()) {
- data = reinterpret_cast<RawOneByteString*>(raw)->ptr()->data();
+ data = static_cast<OneByteStringPtr>(raw)->ptr()->data();
} else {
ASSERT(raw->IsExternalOneByteString());
- RawExternalOneByteString* str =
- reinterpret_cast<RawExternalOneByteString*>(raw);
+ ExternalOneByteStringPtr str = static_cast<ExternalOneByteStringPtr>(raw);
data = str->ptr()->external_data_;
}
return String::Hash(data, length);
} else {
const uint16_t* data;
if (raw->IsTwoByteString()) {
- data = reinterpret_cast<RawTwoByteString*>(raw)->ptr()->data();
+ data = static_cast<TwoByteStringPtr>(raw)->ptr()->data();
} else {
ASSERT(raw->IsExternalTwoByteString());
- RawExternalTwoByteString* str =
- reinterpret_cast<RawExternalTwoByteString*>(raw);
+ ExternalTwoByteStringPtr str = static_cast<ExternalTwoByteStringPtr>(raw);
data = str->ptr()->external_data_;
}
return String::Hash(data, length);
@@ -21157,8 +21140,8 @@
return true;
}
-RawInstance* String::CheckAndCanonicalize(Thread* thread,
- const char** error_str) const {
+InstancePtr String::CheckAndCanonicalize(Thread* thread,
+ const char** error_str) const {
if (IsCanonical()) {
return this->raw();
}
@@ -21173,16 +21156,16 @@
}
#endif // DEBUG
-RawString* String::New(const char* cstr, Heap::Space space) {
+StringPtr String::New(const char* cstr, Heap::Space space) {
ASSERT(cstr != NULL);
intptr_t array_len = strlen(cstr);
const uint8_t* utf8_array = reinterpret_cast<const uint8_t*>(cstr);
return String::FromUTF8(utf8_array, array_len, space);
}
-RawString* String::FromUTF8(const uint8_t* utf8_array,
- intptr_t array_len,
- Heap::Space space) {
+StringPtr String::FromUTF8(const uint8_t* utf8_array,
+ intptr_t array_len,
+ Heap::Space space) {
Utf8::Type type;
intptr_t len = Utf8::CodeUnitCount(utf8_array, array_len, &type);
if (type == Utf8::kLatin1) {
@@ -21208,15 +21191,15 @@
return strobj.raw();
}
-RawString* String::FromLatin1(const uint8_t* latin1_array,
- intptr_t array_len,
- Heap::Space space) {
+StringPtr String::FromLatin1(const uint8_t* latin1_array,
+ intptr_t array_len,
+ Heap::Space space) {
return OneByteString::New(latin1_array, array_len, space);
}
-RawString* String::FromUTF16(const uint16_t* utf16_array,
- intptr_t array_len,
- Heap::Space space) {
+StringPtr String::FromUTF16(const uint16_t* utf16_array,
+ intptr_t array_len,
+ Heap::Space space) {
bool is_one_byte_string = true;
for (intptr_t i = 0; i < array_len; ++i) {
if (!Utf::IsLatin1(utf16_array[i])) {
@@ -21230,9 +21213,9 @@
return TwoByteString::New(utf16_array, array_len, space);
}
-RawString* String::FromUTF32(const int32_t* utf32_array,
- intptr_t array_len,
- Heap::Space space) {
+StringPtr String::FromUTF32(const int32_t* utf32_array,
+ intptr_t array_len,
+ Heap::Space space) {
bool is_one_byte_string = true;
intptr_t utf16_len = array_len;
for (intptr_t i = 0; i < array_len; ++i) {
@@ -21249,7 +21232,7 @@
return TwoByteString::New(utf16_len, utf32_array, array_len, space);
}
-RawString* String::New(const String& str, Heap::Space space) {
+StringPtr String::New(const String& str, Heap::Space space) {
// Currently this just creates a copy of the string in the correct space.
// Once we have external string support, this will also create a heap copy of
// the string if necessary. Some optimizations are possible, such as not
@@ -21267,22 +21250,22 @@
return result.raw();
}
-RawString* String::NewExternal(const uint8_t* characters,
- intptr_t len,
- void* peer,
- intptr_t external_allocation_size,
- Dart_WeakPersistentHandleFinalizer callback,
- Heap::Space space) {
+StringPtr String::NewExternal(const uint8_t* characters,
+ intptr_t len,
+ void* peer,
+ intptr_t external_allocation_size,
+ Dart_WeakPersistentHandleFinalizer callback,
+ Heap::Space space) {
return ExternalOneByteString::New(characters, len, peer,
external_allocation_size, callback, space);
}
-RawString* String::NewExternal(const uint16_t* characters,
- intptr_t len,
- void* peer,
- intptr_t external_allocation_size,
- Dart_WeakPersistentHandleFinalizer callback,
- Heap::Space space) {
+StringPtr String::NewExternal(const uint16_t* characters,
+ intptr_t len,
+ void* peer,
+ intptr_t external_allocation_size,
+ Dart_WeakPersistentHandleFinalizer callback,
+ Heap::Space space) {
return ExternalTwoByteString::New(characters, len, peer,
external_allocation_size, callback, space);
}
@@ -21368,7 +21351,7 @@
}
}
-RawString* String::EscapeSpecialCharacters(const String& str) {
+StringPtr String::EscapeSpecialCharacters(const String& str) {
if (str.IsOneByteString()) {
return OneByteString::EscapeSpecialCharacters(str);
}
@@ -21465,7 +21448,7 @@
return cstr;
}
-RawString* String::DecodeIRI(const String& str) {
+StringPtr String::DecodeIRI(const String& str) {
CodePointIterator cpi(str);
intptr_t num_escapes = 0;
intptr_t len = str.Length();
@@ -21521,27 +21504,27 @@
return FromUTF8(utf8, utf8_len);
}
-RawString* String::NewFormatted(const char* format, ...) {
+StringPtr String::NewFormatted(const char* format, ...) {
va_list args;
va_start(args, format);
- RawString* result = NewFormattedV(format, args);
+ StringPtr result = NewFormattedV(format, args);
NoSafepointScope no_safepoint;
va_end(args);
return result;
}
-RawString* String::NewFormatted(Heap::Space space, const char* format, ...) {
+StringPtr String::NewFormatted(Heap::Space space, const char* format, ...) {
va_list args;
va_start(args, format);
- RawString* result = NewFormattedV(format, args, space);
+ StringPtr result = NewFormattedV(format, args, space);
NoSafepointScope no_safepoint;
va_end(args);
return result;
}
-RawString* String::NewFormattedV(const char* format,
- va_list args,
- Heap::Space space) {
+StringPtr String::NewFormattedV(const char* format,
+ va_list args,
+ Heap::Space space) {
va_list args_copy;
va_copy(args_copy, args);
intptr_t len = Utils::VSNPrint(NULL, 0, format, args_copy);
@@ -21554,9 +21537,9 @@
return String::New(buffer, space);
}
-RawString* String::Concat(const String& str1,
- const String& str2,
- Heap::Space space) {
+StringPtr String::Concat(const String& str1,
+ const String& str2,
+ Heap::Space space) {
ASSERT(!str1.IsNull() && !str2.IsNull());
intptr_t char_size = Utils::Maximum(str1.CharSize(), str2.CharSize());
if (char_size == kTwoByteChar) {
@@ -21565,14 +21548,14 @@
return OneByteString::Concat(str1, str2, space);
}
-RawString* String::ConcatAll(const Array& strings, Heap::Space space) {
+StringPtr String::ConcatAll(const Array& strings, Heap::Space space) {
return ConcatAllRange(strings, 0, strings.Length(), space);
}
-RawString* String::ConcatAllRange(const Array& strings,
- intptr_t start,
- intptr_t end,
- Heap::Space space) {
+StringPtr String::ConcatAllRange(const Array& strings,
+ intptr_t start,
+ intptr_t end,
+ Heap::Space space) {
ASSERT(!strings.IsNull());
ASSERT(start >= 0);
ASSERT(end <= strings.Length());
@@ -21597,9 +21580,9 @@
return TwoByteString::ConcatAll(strings, start, end, result_len, space);
}
-RawString* String::SubString(const String& str,
- intptr_t begin_index,
- Heap::Space space) {
+StringPtr String::SubString(const String& str,
+ intptr_t begin_index,
+ Heap::Space space) {
ASSERT(!str.IsNull());
if (begin_index >= str.Length()) {
return String::null();
@@ -21608,11 +21591,11 @@
space);
}
-RawString* String::SubString(Thread* thread,
- const String& str,
- intptr_t begin_index,
- intptr_t length,
- Heap::Space space) {
+StringPtr String::SubString(Thread* thread,
+ const String& str,
+ intptr_t begin_index,
+ intptr_t length,
+ Heap::Space space) {
ASSERT(!str.IsNull());
ASSERT(begin_index >= 0);
ASSERT(length >= 0);
@@ -21675,9 +21658,9 @@
callback, external_size);
}
-RawString* String::Transform(int32_t (*mapping)(int32_t ch),
- const String& str,
- Heap::Space space) {
+StringPtr String::Transform(int32_t (*mapping)(int32_t ch),
+ const String& str,
+ Heap::Space space) {
ASSERT(!str.IsNull());
bool has_mapping = false;
int32_t dst_max = 0;
@@ -21700,12 +21683,12 @@
return TwoByteString::Transform(mapping, str, space);
}
-RawString* String::ToUpperCase(const String& str, Heap::Space space) {
+StringPtr String::ToUpperCase(const String& str, Heap::Space space) {
// TODO(cshapiro): create a fast-path for OneByteString instances.
return Transform(CaseMapping::ToUpper, str, space);
}
-RawString* String::ToLowerCase(const String& str, Heap::Space space) {
+StringPtr String::ToLowerCase(const String& str, Heap::Space space) {
// TODO(cshapiro): create a fast-path for OneByteString instances.
return Transform(CaseMapping::ToLower, str, space);
}
@@ -21852,7 +21835,7 @@
return false;
}
-RawOneByteString* OneByteString::EscapeSpecialCharacters(const String& str) {
+OneByteStringPtr OneByteString::EscapeSpecialCharacters(const String& str) {
intptr_t len = str.Length();
if (len > 0) {
intptr_t num_escapes = 0;
@@ -21884,7 +21867,7 @@
return OneByteString::raw(Symbols::Empty());
}
-RawOneByteString* ExternalOneByteString::EscapeSpecialCharacters(
+OneByteStringPtr ExternalOneByteString::EscapeSpecialCharacters(
const String& str) {
intptr_t len = str.Length();
if (len > 0) {
@@ -21917,7 +21900,7 @@
return OneByteString::raw(Symbols::Empty());
}
-RawOneByteString* OneByteString::New(intptr_t len, Heap::Space space) {
+OneByteStringPtr OneByteString::New(intptr_t len, Heap::Space space) {
ASSERT((Isolate::Current() == Dart::vm_isolate()) ||
((Isolate::Current()->object_store() != NULL) &&
(Isolate::Current()->object_store()->one_byte_string_class() !=
@@ -21927,21 +21910,21 @@
FATAL1("Fatal error in OneByteString::New: invalid len %" Pd "\n", len);
}
{
- RawObject* raw = Object::Allocate(OneByteString::kClassId,
- OneByteString::InstanceSize(len), space);
+ ObjectPtr raw = Object::Allocate(OneByteString::kClassId,
+ OneByteString::InstanceSize(len), space);
NoSafepointScope no_safepoint;
- RawOneByteString* result = reinterpret_cast<RawOneByteString*>(raw);
- result->StoreSmi(&(result->ptr()->length_), Smi::New(len));
+ OneByteStringPtr result = static_cast<OneByteStringPtr>(raw);
+ result->ptr()->StoreSmi(&(result->ptr()->length_), Smi::New(len));
#if !defined(HASH_IN_OBJECT_HEADER)
- result->StoreSmi(&(result->ptr()->hash_), Smi::New(0));
+ result->ptr()->StoreSmi(&(result->ptr()->hash_), Smi::New(0));
#endif
return result;
}
}
-RawOneByteString* OneByteString::New(const uint8_t* characters,
- intptr_t len,
- Heap::Space space) {
+OneByteStringPtr OneByteString::New(const uint8_t* characters,
+ intptr_t len,
+ Heap::Space space) {
const String& result = String::Handle(OneByteString::New(len, space));
if (len > 0) {
NoSafepointScope no_safepoint;
@@ -21950,9 +21933,9 @@
return OneByteString::raw(result);
}
-RawOneByteString* OneByteString::New(const uint16_t* characters,
- intptr_t len,
- Heap::Space space) {
+OneByteStringPtr OneByteString::New(const uint16_t* characters,
+ intptr_t len,
+ Heap::Space space) {
const String& result = String::Handle(OneByteString::New(len, space));
NoSafepointScope no_safepoint;
for (intptr_t i = 0; i < len; ++i) {
@@ -21962,9 +21945,9 @@
return OneByteString::raw(result);
}
-RawOneByteString* OneByteString::New(const int32_t* characters,
- intptr_t len,
- Heap::Space space) {
+OneByteStringPtr OneByteString::New(const int32_t* characters,
+ intptr_t len,
+ Heap::Space space) {
const String& result = String::Handle(OneByteString::New(len, space));
NoSafepointScope no_safepoint;
for (intptr_t i = 0; i < len; ++i) {
@@ -21974,17 +21957,17 @@
return OneByteString::raw(result);
}
-RawOneByteString* OneByteString::New(const String& str, Heap::Space space) {
+OneByteStringPtr OneByteString::New(const String& str, Heap::Space space) {
intptr_t len = str.Length();
const String& result = String::Handle(OneByteString::New(len, space));
String::Copy(result, 0, str, 0, len);
return OneByteString::raw(result);
}
-RawOneByteString* OneByteString::New(const String& other_one_byte_string,
- intptr_t other_start_index,
- intptr_t other_len,
- Heap::Space space) {
+OneByteStringPtr OneByteString::New(const String& other_one_byte_string,
+ intptr_t other_start_index,
+ intptr_t other_len,
+ Heap::Space space) {
const String& result = String::Handle(OneByteString::New(other_len, space));
ASSERT(other_one_byte_string.IsOneByteString());
if (other_len > 0) {
@@ -21996,10 +21979,10 @@
return OneByteString::raw(result);
}
-RawOneByteString* OneByteString::New(const TypedData& other_typed_data,
- intptr_t other_start_index,
- intptr_t other_len,
- Heap::Space space) {
+OneByteStringPtr OneByteString::New(const TypedData& other_typed_data,
+ intptr_t other_start_index,
+ intptr_t other_len,
+ Heap::Space space) {
const String& result = String::Handle(OneByteString::New(other_len, space));
ASSERT(other_typed_data.ElementSizeInBytes() == 1);
if (other_len > 0) {
@@ -22010,10 +21993,10 @@
return OneByteString::raw(result);
}
-RawOneByteString* OneByteString::New(const ExternalTypedData& other_typed_data,
- intptr_t other_start_index,
- intptr_t other_len,
- Heap::Space space) {
+OneByteStringPtr OneByteString::New(const ExternalTypedData& other_typed_data,
+ intptr_t other_start_index,
+ intptr_t other_len,
+ Heap::Space space) {
const String& result = String::Handle(OneByteString::New(other_len, space));
ASSERT(other_typed_data.ElementSizeInBytes() == 1);
if (other_len > 0) {
@@ -22024,9 +22007,9 @@
return OneByteString::raw(result);
}
-RawOneByteString* OneByteString::Concat(const String& str1,
- const String& str2,
- Heap::Space space) {
+OneByteStringPtr OneByteString::Concat(const String& str1,
+ const String& str2,
+ Heap::Space space) {
intptr_t len1 = str1.Length();
intptr_t len2 = str2.Length();
intptr_t len = len1 + len2;
@@ -22036,11 +22019,11 @@
return OneByteString::raw(result);
}
-RawOneByteString* OneByteString::ConcatAll(const Array& strings,
- intptr_t start,
- intptr_t end,
- intptr_t len,
- Heap::Space space) {
+OneByteStringPtr OneByteString::ConcatAll(const Array& strings,
+ intptr_t start,
+ intptr_t end,
+ intptr_t len,
+ Heap::Space space) {
ASSERT(!strings.IsNull());
ASSERT(start >= 0);
ASSERT(end <= strings.Length());
@@ -22057,9 +22040,9 @@
return OneByteString::raw(result);
}
-RawOneByteString* OneByteString::Transform(int32_t (*mapping)(int32_t ch),
- const String& str,
- Heap::Space space) {
+OneByteStringPtr OneByteString::Transform(int32_t (*mapping)(int32_t ch),
+ const String& str,
+ Heap::Space space) {
ASSERT(!str.IsNull());
intptr_t len = str.Length();
const String& result = String::Handle(OneByteString::New(len, space));
@@ -22072,10 +22055,10 @@
return OneByteString::raw(result);
}
-RawOneByteString* OneByteString::SubStringUnchecked(const String& str,
- intptr_t begin_index,
- intptr_t length,
- Heap::Space space) {
+OneByteStringPtr OneByteString::SubStringUnchecked(const String& str,
+ intptr_t begin_index,
+ intptr_t length,
+ Heap::Space space) {
ASSERT(!str.IsNull() && str.IsOneByteString());
ASSERT(begin_index >= 0);
ASSERT(length >= 0);
@@ -22083,7 +22066,7 @@
return OneByteString::raw(Symbols::Empty());
}
ASSERT(begin_index < str.Length());
- RawOneByteString* result = OneByteString::New(length, space);
+ OneByteStringPtr result = OneByteString::New(length, space);
NoSafepointScope no_safepoint;
if (length > 0) {
uint8_t* dest = &result->ptr()->data()[0];
@@ -22093,7 +22076,7 @@
return result;
}
-RawTwoByteString* TwoByteString::EscapeSpecialCharacters(const String& str) {
+TwoByteStringPtr TwoByteString::EscapeSpecialCharacters(const String& str) {
intptr_t len = str.Length();
if (len > 0) {
intptr_t num_escapes = 0;
@@ -22125,16 +22108,17 @@
return TwoByteString::New(0, Heap::kNew);
}
-RawTwoByteString* TwoByteString::New(intptr_t len, Heap::Space space) {
- ASSERT(Isolate::Current()->object_store()->two_byte_string_class());
+TwoByteStringPtr TwoByteString::New(intptr_t len, Heap::Space space) {
+ ASSERT(Isolate::Current()->object_store()->two_byte_string_class() !=
+ nullptr);
if (len < 0 || len > kMaxElements) {
// This should be caught before we reach here.
FATAL1("Fatal error in TwoByteString::New: invalid len %" Pd "\n", len);
}
String& result = String::Handle();
{
- RawObject* raw = Object::Allocate(TwoByteString::kClassId,
- TwoByteString::InstanceSize(len), space);
+ ObjectPtr raw = Object::Allocate(TwoByteString::kClassId,
+ TwoByteString::InstanceSize(len), space);
NoSafepointScope no_safepoint;
result ^= raw;
result.SetLength(len);
@@ -22143,9 +22127,9 @@
return TwoByteString::raw(result);
}
-RawTwoByteString* TwoByteString::New(const uint16_t* utf16_array,
- intptr_t array_len,
- Heap::Space space) {
+TwoByteStringPtr TwoByteString::New(const uint16_t* utf16_array,
+ intptr_t array_len,
+ Heap::Space space) {
ASSERT(array_len > 0);
const String& result = String::Handle(TwoByteString::New(array_len, space));
{
@@ -22155,10 +22139,10 @@
return TwoByteString::raw(result);
}
-RawTwoByteString* TwoByteString::New(intptr_t utf16_len,
- const int32_t* utf32_array,
- intptr_t array_len,
- Heap::Space space) {
+TwoByteStringPtr TwoByteString::New(intptr_t utf16_len,
+ const int32_t* utf32_array,
+ intptr_t array_len,
+ Heap::Space space) {
ASSERT((array_len > 0) && (utf16_len >= array_len));
const String& result = String::Handle(TwoByteString::New(utf16_len, space));
{
@@ -22179,17 +22163,17 @@
return TwoByteString::raw(result);
}
-RawTwoByteString* TwoByteString::New(const String& str, Heap::Space space) {
+TwoByteStringPtr TwoByteString::New(const String& str, Heap::Space space) {
intptr_t len = str.Length();
const String& result = String::Handle(TwoByteString::New(len, space));
String::Copy(result, 0, str, 0, len);
return TwoByteString::raw(result);
}
-RawTwoByteString* TwoByteString::New(const TypedData& other_typed_data,
- intptr_t other_start_index,
- intptr_t other_len,
- Heap::Space space) {
+TwoByteStringPtr TwoByteString::New(const TypedData& other_typed_data,
+ intptr_t other_start_index,
+ intptr_t other_len,
+ Heap::Space space) {
const String& result = String::Handle(TwoByteString::New(other_len, space));
if (other_len > 0) {
NoSafepointScope no_safepoint;
@@ -22200,10 +22184,10 @@
return TwoByteString::raw(result);
}
-RawTwoByteString* TwoByteString::New(const ExternalTypedData& other_typed_data,
- intptr_t other_start_index,
- intptr_t other_len,
- Heap::Space space) {
+TwoByteStringPtr TwoByteString::New(const ExternalTypedData& other_typed_data,
+ intptr_t other_start_index,
+ intptr_t other_len,
+ Heap::Space space) {
const String& result = String::Handle(TwoByteString::New(other_len, space));
if (other_len > 0) {
NoSafepointScope no_safepoint;
@@ -22214,9 +22198,9 @@
return TwoByteString::raw(result);
}
-RawTwoByteString* TwoByteString::Concat(const String& str1,
- const String& str2,
- Heap::Space space) {
+TwoByteStringPtr TwoByteString::Concat(const String& str1,
+ const String& str2,
+ Heap::Space space) {
intptr_t len1 = str1.Length();
intptr_t len2 = str2.Length();
intptr_t len = len1 + len2;
@@ -22226,11 +22210,11 @@
return TwoByteString::raw(result);
}
-RawTwoByteString* TwoByteString::ConcatAll(const Array& strings,
- intptr_t start,
- intptr_t end,
- intptr_t len,
- Heap::Space space) {
+TwoByteStringPtr TwoByteString::ConcatAll(const Array& strings,
+ intptr_t start,
+ intptr_t end,
+ intptr_t len,
+ Heap::Space space) {
ASSERT(!strings.IsNull());
ASSERT(start >= 0);
ASSERT(end <= strings.Length());
@@ -22247,9 +22231,9 @@
return TwoByteString::raw(result);
}
-RawTwoByteString* TwoByteString::Transform(int32_t (*mapping)(int32_t ch),
- const String& str,
- Heap::Space space) {
+TwoByteStringPtr TwoByteString::Transform(int32_t (*mapping)(int32_t ch),
+ const String& str,
+ Heap::Space space) {
ASSERT(!str.IsNull());
intptr_t len = str.Length();
const String& result = String::Handle(TwoByteString::New(len, space));
@@ -22272,7 +22256,7 @@
return TwoByteString::raw(result);
}
-RawExternalOneByteString* ExternalOneByteString::New(
+ExternalOneByteStringPtr ExternalOneByteString::New(
const uint8_t* data,
intptr_t len,
void* peer,
@@ -22288,7 +22272,7 @@
}
String& result = String::Handle();
{
- RawObject* raw =
+ ObjectPtr raw =
Object::Allocate(ExternalOneByteString::kClassId,
ExternalOneByteString::InstanceSize(), space);
NoSafepointScope no_safepoint;
@@ -22301,7 +22285,7 @@
return ExternalOneByteString::raw(result);
}
-RawExternalTwoByteString* ExternalTwoByteString::New(
+ExternalTwoByteStringPtr ExternalTwoByteString::New(
const uint16_t* data,
intptr_t len,
void* peer,
@@ -22317,7 +22301,7 @@
}
String& result = String::Handle();
{
- RawObject* raw =
+ ObjectPtr raw =
Object::Allocate(ExternalTwoByteString::kClassId,
ExternalTwoByteString::InstanceSize(), space);
NoSafepointScope no_safepoint;
@@ -22330,13 +22314,13 @@
return ExternalTwoByteString::raw(result);
}
-RawBool* Bool::New(bool value) {
+BoolPtr Bool::New(bool value) {
ASSERT(Isolate::Current()->object_store()->bool_class() != Class::null());
Bool& result = Bool::Handle();
{
// Since the two boolean instances are singletons we allocate them straight
// in the old generation.
- RawObject* raw =
+ ObjectPtr raw =
Object::Allocate(Bool::kClassId, Bool::InstanceSize(), Heap::kOld);
NoSafepointScope no_safepoint;
result ^= raw;
@@ -22410,19 +22394,19 @@
return hash;
}
-RawArray* Array::New(intptr_t len, Heap::Space space) {
+ArrayPtr Array::New(intptr_t len, Heap::Space space) {
ASSERT(Isolate::Current()->object_store()->array_class() != Class::null());
- RawArray* result = New(kClassId, len, space);
+ ArrayPtr result = New(kClassId, len, space);
if (UseCardMarkingForAllocation(len)) {
ASSERT(result->IsOldObject());
- result->SetCardRememberedBitUnsynchronized();
+ result->ptr()->SetCardRememberedBitUnsynchronized();
}
return result;
}
-RawArray* Array::New(intptr_t len,
- const AbstractType& element_type,
- Heap::Space space) {
+ArrayPtr Array::New(intptr_t len,
+ const AbstractType& element_type,
+ Heap::Space space) {
const Array& result = Array::Handle(Array::New(len, space));
if (!element_type.IsDynamicType()) {
TypeArguments& type_args = TypeArguments::Handle(TypeArguments::New(1));
@@ -22433,23 +22417,23 @@
return result.raw();
}
-RawArray* Array::New(intptr_t class_id, intptr_t len, Heap::Space space) {
+ArrayPtr Array::New(intptr_t class_id, intptr_t len, Heap::Space space) {
if (!IsValidLength(len)) {
// This should be caught before we reach here.
FATAL1("Fatal error in Array::New: invalid len %" Pd "\n", len);
}
{
- RawArray* raw = reinterpret_cast<RawArray*>(
+ ArrayPtr raw = static_cast<ArrayPtr>(
Object::Allocate(class_id, Array::InstanceSize(len), space));
NoSafepointScope no_safepoint;
- raw->StoreSmi(&(raw->ptr()->length_), Smi::New(len));
+ raw->ptr()->StoreSmi(&(raw->ptr()->length_), Smi::New(len));
return raw;
}
}
-RawArray* Array::Slice(intptr_t start,
- intptr_t count,
- bool with_type_argument) const {
+ArrayPtr Array::Slice(intptr_t start,
+ intptr_t count,
+ bool with_type_argument) const {
// TODO(vegorov) introduce an array allocation method that fills newly
// allocated array with values from the given source array instead of
// null-initializing all elements.
@@ -22472,7 +22456,7 @@
do {
old_tags = tags;
uint32_t new_tags =
- RawObject::ClassIdTag::update(kImmutableArrayCid, old_tags);
+ ObjectLayout::ClassIdTag::update(kImmutableArrayCid, old_tags);
tags = CompareAndSwapTags(old_tags, new_tags);
} while (tags != old_tags);
}
@@ -22487,9 +22471,9 @@
return zone->PrintToString(format, Length());
}
-RawArray* Array::Grow(const Array& source,
- intptr_t new_length,
- Heap::Space space) {
+ArrayPtr Array::Grow(const Array& source,
+ intptr_t new_length,
+ Heap::Space space) {
Zone* zone = Thread::Current()->zone();
const Array& result = Array::Handle(zone, Array::New(new_length, space));
intptr_t len = 0;
@@ -22518,6 +22502,9 @@
intptr_t old_len = array.Length();
ASSERT(new_len <= old_len);
+ if (old_len == new_len) {
+ return;
+ }
intptr_t old_size = Array::InstanceSize(old_len);
intptr_t new_size = Array::InstanceSize(new_len);
@@ -22534,23 +22521,23 @@
// Update the size in the header field and length of the array object.
uint32_t tags = array.raw_ptr()->tags_;
- ASSERT(kArrayCid == RawObject::ClassIdTag::decode(tags));
+ ASSERT(kArrayCid == ObjectLayout::ClassIdTag::decode(tags));
uint32_t old_tags;
do {
old_tags = tags;
- uint32_t new_tags = RawObject::SizeTag::update(new_size, old_tags);
+ uint32_t new_tags = ObjectLayout::SizeTag::update(new_size, old_tags);
tags = CompareAndSwapTags(old_tags, new_tags);
} while (tags != old_tags);
// Between the CAS of the header above and the SetLength below, the array is
// temporarily in an inconsistent state. The header is considered the
- // overriding source of object size by RawObject::Size, but the ASSERTs in
- // RawObject::SizeFromClass must handle this special case.
+ // overriding source of object size by ObjectLayout::Size, but the ASSERTs in
+ // ObjectLayout::SizeFromClass must handle this special case.
array.SetLengthIgnoreRace(new_len);
}
-RawArray* Array::MakeFixedLength(const GrowableObjectArray& growable_array,
- bool unique) {
+ArrayPtr Array::MakeFixedLength(const GrowableObjectArray& growable_array,
+ bool unique) {
ASSERT(!growable_array.IsNull());
Thread* thread = Thread::Current();
Zone* zone = thread->zone();
@@ -22617,10 +22604,10 @@
return true;
}
-RawImmutableArray* ImmutableArray::New(intptr_t len, Heap::Space space) {
+ImmutableArrayPtr ImmutableArray::New(intptr_t len, Heap::Space space) {
ASSERT(Isolate::Current()->object_store()->immutable_array_class() !=
Class::null());
- return reinterpret_cast<RawImmutableArray*>(Array::New(kClassId, len, space));
+ return static_cast<ImmutableArrayPtr>(Array::New(kClassId, len, space));
}
void GrowableObjectArray::Add(const Object& value, Heap::Space space) const {
@@ -22648,7 +22635,7 @@
StorePointer(&(raw_ptr()->data_), new_contents.raw());
}
-RawObject* GrowableObjectArray::RemoveLast() const {
+ObjectPtr GrowableObjectArray::RemoveLast() const {
ASSERT(!IsNull());
ASSERT(Length() > 0);
intptr_t index = Length() - 1;
@@ -22659,21 +22646,21 @@
return obj.raw();
}
-RawGrowableObjectArray* GrowableObjectArray::New(intptr_t capacity,
- Heap::Space space) {
- RawArray* raw_data = (capacity == 0) ? Object::empty_array().raw()
- : Array::New(capacity, space);
+GrowableObjectArrayPtr GrowableObjectArray::New(intptr_t capacity,
+ Heap::Space space) {
+ ArrayPtr raw_data = (capacity == 0) ? Object::empty_array().raw()
+ : Array::New(capacity, space);
const Array& data = Array::Handle(raw_data);
return New(data, space);
}
-RawGrowableObjectArray* GrowableObjectArray::New(const Array& array,
- Heap::Space space) {
+GrowableObjectArrayPtr GrowableObjectArray::New(const Array& array,
+ Heap::Space space) {
ASSERT(Isolate::Current()->object_store()->growable_object_array_class() !=
Class::null());
GrowableObjectArray& result = GrowableObjectArray::Handle();
{
- RawObject* raw =
+ ObjectPtr raw =
Object::Allocate(GrowableObjectArray::kClassId,
GrowableObjectArray::InstanceSize(), space);
NoSafepointScope no_safepoint;
@@ -22727,7 +22714,7 @@
}
};
-RawLinkedHashMap* LinkedHashMap::NewDefault(Heap::Space space) {
+LinkedHashMapPtr LinkedHashMap::NewDefault(Heap::Space space) {
const Array& data = Array::Handle(Array::New(kInitialIndexSize, space));
const TypedData& index = TypedData::Handle(
TypedData::New(kTypedDataUint32ArrayCid, kInitialIndexSize, space));
@@ -22738,12 +22725,12 @@
return LinkedHashMap::New(data, index, kInitialHashMask, 0, 0, space);
}
-RawLinkedHashMap* LinkedHashMap::New(const Array& data,
- const TypedData& index,
- intptr_t hash_mask,
- intptr_t used_data,
- intptr_t deleted_keys,
- Heap::Space space) {
+LinkedHashMapPtr LinkedHashMap::New(const Array& data,
+ const TypedData& index,
+ intptr_t hash_mask,
+ intptr_t used_data,
+ intptr_t deleted_keys,
+ Heap::Space space) {
ASSERT(Isolate::Current()->object_store()->linked_hash_map_class() !=
Class::null());
LinkedHashMap& result =
@@ -22756,13 +22743,13 @@
return result.raw();
}
-RawLinkedHashMap* LinkedHashMap::NewUninitialized(Heap::Space space) {
+LinkedHashMapPtr LinkedHashMap::NewUninitialized(Heap::Space space) {
ASSERT(Isolate::Current()->object_store()->linked_hash_map_class() !=
Class::null());
LinkedHashMap& result = LinkedHashMap::Handle();
{
- RawObject* raw = Object::Allocate(LinkedHashMap::kClassId,
- LinkedHashMap::InstanceSize(), space);
+ ObjectPtr raw = Object::Allocate(LinkedHashMap::kClassId,
+ LinkedHashMap::InstanceSize(), space);
NoSafepointScope no_safepoint;
result ^= raw;
}
@@ -22779,16 +22766,16 @@
UNREACHABLE();
}
-RawFloat32x4* Float32x4::New(float v0,
- float v1,
- float v2,
- float v3,
- Heap::Space space) {
+Float32x4Ptr Float32x4::New(float v0,
+ float v1,
+ float v2,
+ float v3,
+ Heap::Space space) {
ASSERT(Isolate::Current()->object_store()->float32x4_class() !=
Class::null());
Float32x4& result = Float32x4::Handle();
{
- RawObject* raw =
+ ObjectPtr raw =
Object::Allocate(Float32x4::kClassId, Float32x4::InstanceSize(), space);
NoSafepointScope no_safepoint;
result ^= raw;
@@ -22800,12 +22787,12 @@
return result.raw();
}
-RawFloat32x4* Float32x4::New(simd128_value_t value, Heap::Space space) {
+Float32x4Ptr Float32x4::New(simd128_value_t value, Heap::Space space) {
ASSERT(Isolate::Current()->object_store()->float32x4_class() !=
Class::null());
Float32x4& result = Float32x4::Handle();
{
- RawObject* raw =
+ ObjectPtr raw =
Object::Allocate(Float32x4::kClassId, Float32x4::InstanceSize(), space);
NoSafepointScope no_safepoint;
result ^= raw;
@@ -22865,15 +22852,15 @@
_w);
}
-RawInt32x4* Int32x4::New(int32_t v0,
- int32_t v1,
- int32_t v2,
- int32_t v3,
- Heap::Space space) {
+Int32x4Ptr Int32x4::New(int32_t v0,
+ int32_t v1,
+ int32_t v2,
+ int32_t v3,
+ Heap::Space space) {
ASSERT(Isolate::Current()->object_store()->int32x4_class() != Class::null());
Int32x4& result = Int32x4::Handle();
{
- RawObject* raw =
+ ObjectPtr raw =
Object::Allocate(Int32x4::kClassId, Int32x4::InstanceSize(), space);
NoSafepointScope no_safepoint;
result ^= raw;
@@ -22885,11 +22872,11 @@
return result.raw();
}
-RawInt32x4* Int32x4::New(simd128_value_t value, Heap::Space space) {
+Int32x4Ptr Int32x4::New(simd128_value_t value, Heap::Space space) {
ASSERT(Isolate::Current()->object_store()->int32x4_class() != Class::null());
Int32x4& result = Int32x4::Handle();
{
- RawObject* raw =
+ ObjectPtr raw =
Object::Allocate(Int32x4::kClassId, Int32x4::InstanceSize(), space);
NoSafepointScope no_safepoint;
result ^= raw;
@@ -22949,12 +22936,12 @@
_y, _z, _w);
}
-RawFloat64x2* Float64x2::New(double value0, double value1, Heap::Space space) {
+Float64x2Ptr Float64x2::New(double value0, double value1, Heap::Space space) {
ASSERT(Isolate::Current()->object_store()->float64x2_class() !=
Class::null());
Float64x2& result = Float64x2::Handle();
{
- RawObject* raw =
+ ObjectPtr raw =
Object::Allocate(Float64x2::kClassId, Float64x2::InstanceSize(), space);
NoSafepointScope no_safepoint;
result ^= raw;
@@ -22964,12 +22951,12 @@
return result.raw();
}
-RawFloat64x2* Float64x2::New(simd128_value_t value, Heap::Space space) {
+Float64x2Ptr Float64x2::New(simd128_value_t value, Heap::Space space) {
ASSERT(Isolate::Current()->object_store()->float64x2_class() !=
Class::null());
Float64x2& result = Float64x2::Handle();
{
- RawObject* raw =
+ ObjectPtr raw =
Object::Allocate(Float64x2::kClassId, Float64x2::InstanceSize(), space);
NoSafepointScope no_safepoint;
result ^= raw;
@@ -23063,16 +23050,16 @@
return FinalizeHash(hash, kHashBits);
}
-RawTypedData* TypedData::New(intptr_t class_id,
- intptr_t len,
- Heap::Space space) {
+TypedDataPtr TypedData::New(intptr_t class_id,
+ intptr_t len,
+ Heap::Space space) {
if (len < 0 || len > TypedData::MaxElements(class_id)) {
FATAL1("Fatal error in TypedData::New: invalid len %" Pd "\n", len);
}
TypedData& result = TypedData::Handle();
{
const intptr_t length_in_bytes = len * ElementSizeInBytes(class_id);
- RawObject* raw = Object::Allocate(
+ ObjectPtr raw = Object::Allocate(
class_id, TypedData::InstanceSize(length_in_bytes), space);
NoSafepointScope no_safepoint;
result ^= raw;
@@ -23100,7 +23087,7 @@
return dart::AddFinalizer(*this, peer, callback, external_size);
}
-RawExternalTypedData* ExternalTypedData::New(
+ExternalTypedDataPtr ExternalTypedData::New(
intptr_t class_id,
uint8_t* data,
intptr_t len,
@@ -23118,7 +23105,7 @@
ExternalTypedData& result = ExternalTypedData::Handle();
{
- RawObject* raw =
+ ObjectPtr raw =
Object::Allocate(class_id, ExternalTypedData::InstanceSize(), space);
NoSafepointScope no_safepoint;
result ^= raw;
@@ -23128,8 +23115,8 @@
return result.raw();
}
-RawExternalTypedData* ExternalTypedData::NewFinalizeWithFree(uint8_t* data,
- intptr_t len) {
+ExternalTypedDataPtr ExternalTypedData::NewFinalizeWithFree(uint8_t* data,
+ intptr_t len) {
ExternalTypedData& result = ExternalTypedData::Handle(ExternalTypedData::New(
kExternalTypedDataUint8ArrayCid, data, len, Heap::kOld));
result.AddFinalizer(
@@ -23140,10 +23127,10 @@
return result.raw();
}
-RawTypedDataView* TypedDataView::New(intptr_t class_id, Heap::Space space) {
+TypedDataViewPtr TypedDataView::New(intptr_t class_id, Heap::Space space) {
auto& result = TypedDataView::Handle();
{
- RawObject* raw =
+ ObjectPtr raw =
Object::Allocate(class_id, TypedDataView::InstanceSize(), space);
NoSafepointScope no_safepoint;
result ^= raw;
@@ -23152,11 +23139,11 @@
return result.raw();
}
-RawTypedDataView* TypedDataView::New(intptr_t class_id,
- const TypedDataBase& typed_data,
- intptr_t offset_in_bytes,
- intptr_t length,
- Heap::Space space) {
+TypedDataViewPtr TypedDataView::New(intptr_t class_id,
+ const TypedDataBase& typed_data,
+ intptr_t offset_in_bytes,
+ intptr_t length,
+ Heap::Space space) {
auto& result = TypedDataView::Handle(TypedDataView::New(class_id, space));
result.InitializeWith(typed_data, offset_in_bytes, length);
return result.raw();
@@ -23177,9 +23164,9 @@
return "ExternalTypedData";
}
-RawPointer* Pointer::New(const AbstractType& type_arg,
- size_t native_address,
- Heap::Space space) {
+PointerPtr Pointer::New(const AbstractType& type_arg,
+ size_t native_address,
+ Heap::Space space) {
Thread* thread = Thread::Current();
Zone* zone = thread->zone();
@@ -23207,7 +23194,7 @@
type_args_name.ToCString(), NativeAddress());
}
-RawDynamicLibrary* DynamicLibrary::New(void* handle, Heap::Space space) {
+DynamicLibraryPtr DynamicLibrary::New(void* handle, Heap::Space space) {
DynamicLibrary& result = DynamicLibrary::Handle();
result ^= Object::Allocate(kFfiDynamicLibraryCid,
DynamicLibrary::InstanceSize(), space);
@@ -23229,11 +23216,11 @@
reinterpret_cast<uintptr_t>(GetHandle()));
}
-RawCapability* Capability::New(uint64_t id, Heap::Space space) {
+CapabilityPtr Capability::New(uint64_t id, Heap::Space space) {
Capability& result = Capability::Handle();
{
- RawObject* raw = Object::Allocate(Capability::kClassId,
- Capability::InstanceSize(), space);
+ ObjectPtr raw = Object::Allocate(Capability::kClassId,
+ Capability::InstanceSize(), space);
NoSafepointScope no_safepoint;
result ^= raw;
result.StoreNonPointer(&result.raw_ptr()->id_, id);
@@ -23245,9 +23232,9 @@
return "Capability";
}
-RawReceivePort* ReceivePort::New(Dart_Port id,
- bool is_control_port,
- Heap::Space space) {
+ReceivePortPtr ReceivePort::New(Dart_Port id,
+ bool is_control_port,
+ Heap::Space space) {
ASSERT(id != ILLEGAL_PORT);
Thread* thread = Thread::Current();
Zone* zone = thread->zone();
@@ -23256,8 +23243,8 @@
ReceivePort& result = ReceivePort::Handle(zone);
{
- RawObject* raw = Object::Allocate(ReceivePort::kClassId,
- ReceivePort::InstanceSize(), space);
+ ObjectPtr raw = Object::Allocate(ReceivePort::kClassId,
+ ReceivePort::InstanceSize(), space);
NoSafepointScope no_safepoint;
result ^= raw;
result.StorePointer(&result.raw_ptr()->send_port_, send_port.raw());
@@ -23274,17 +23261,17 @@
return "ReceivePort";
}
-RawSendPort* SendPort::New(Dart_Port id, Heap::Space space) {
+SendPortPtr SendPort::New(Dart_Port id, Heap::Space space) {
return New(id, Isolate::Current()->origin_id(), space);
}
-RawSendPort* SendPort::New(Dart_Port id,
- Dart_Port origin_id,
- Heap::Space space) {
+SendPortPtr SendPort::New(Dart_Port id,
+ Dart_Port origin_id,
+ Heap::Space space) {
ASSERT(id != ILLEGAL_PORT);
SendPort& result = SendPort::Handle();
{
- RawObject* raw =
+ ObjectPtr raw =
Object::Allocate(SendPort::kClassId, SendPort::InstanceSize(), space);
NoSafepointScope no_safepoint;
result ^= raw;
@@ -23304,15 +23291,15 @@
delete (reinterpret_cast<TransferableTypedDataPeer*>(peer));
}
-RawTransferableTypedData* TransferableTypedData::New(uint8_t* data,
- intptr_t length,
- Heap::Space space) {
+TransferableTypedDataPtr TransferableTypedData::New(uint8_t* data,
+ intptr_t length,
+ Heap::Space space) {
TransferableTypedDataPeer* peer = new TransferableTypedDataPeer(data, length);
Thread* thread = Thread::Current();
TransferableTypedData& result = TransferableTypedData::Handle();
{
- RawObject* raw =
+ ObjectPtr raw =
Object::Allocate(TransferableTypedData::kClassId,
TransferableTypedData::InstanceSize(), space);
NoSafepointScope no_safepoint;
@@ -23379,26 +23366,26 @@
return FinalizeHash(result, String::kHashBits);
}
-RawClosure* Closure::New(const TypeArguments& instantiator_type_arguments,
- const TypeArguments& function_type_arguments,
- const Function& function,
- const Context& context,
- Heap::Space space) {
+ClosurePtr Closure::New(const TypeArguments& instantiator_type_arguments,
+ const TypeArguments& function_type_arguments,
+ const Function& function,
+ const Context& context,
+ Heap::Space space) {
return Closure::New(instantiator_type_arguments, function_type_arguments,
function.IsGeneric() ? Object::empty_type_arguments()
: Object::null_type_arguments(),
function, context, space);
}
-RawClosure* Closure::New(const TypeArguments& instantiator_type_arguments,
- const TypeArguments& function_type_arguments,
- const TypeArguments& delayed_type_arguments,
- const Function& function,
- const Context& context,
- Heap::Space space) {
+ClosurePtr Closure::New(const TypeArguments& instantiator_type_arguments,
+ const TypeArguments& function_type_arguments,
+ const TypeArguments& delayed_type_arguments,
+ const Function& function,
+ const Context& context,
+ Heap::Space space) {
Closure& result = Closure::Handle();
{
- RawObject* raw =
+ ObjectPtr raw =
Object::Allocate(Closure::kClassId, Closure::InstanceSize(), space);
NoSafepointScope no_safepoint;
result ^= raw;
@@ -23414,13 +23401,13 @@
return result.raw();
}
-RawClosure* Closure::New() {
- RawObject* raw =
+ClosurePtr Closure::New() {
+ ObjectPtr raw =
Object::Allocate(Closure::kClassId, Closure::InstanceSize(), Heap::kOld);
- return reinterpret_cast<RawClosure*>(raw);
+ return static_cast<ClosurePtr>(raw);
}
-RawFunction* Closure::GetInstantiatedSignature(Zone* zone) const {
+FunctionPtr Closure::GetInstantiatedSignature(Zone* zone) const {
Function& sig_fun = Function::Handle(zone, function());
TypeArguments& fn_type_args =
TypeArguments::Handle(zone, function_type_arguments());
@@ -23461,7 +23448,7 @@
return code_array.Length();
}
-RawObject* StackTrace::CodeAtFrame(intptr_t frame_index) const {
+ObjectPtr StackTrace::CodeAtFrame(intptr_t frame_index) const {
const Array& code_array = Array::Handle(raw_ptr()->code_array_);
return code_array.At(frame_index);
}
@@ -23472,9 +23459,9 @@
code_array.SetAt(frame_index, code);
}
-RawSmi* StackTrace::PcOffsetAtFrame(intptr_t frame_index) const {
+SmiPtr StackTrace::PcOffsetAtFrame(intptr_t frame_index) const {
const Array& pc_offset_array = Array::Handle(raw_ptr()->pc_offset_array_);
- return reinterpret_cast<RawSmi*>(pc_offset_array.At(frame_index));
+ return static_cast<SmiPtr>(pc_offset_array.At(frame_index));
}
void StackTrace::SetPcOffsetAtFrame(intptr_t frame_index,
@@ -23503,13 +23490,13 @@
return raw_ptr()->expand_inlined_;
}
-RawStackTrace* StackTrace::New(const Array& code_array,
- const Array& pc_offset_array,
- Heap::Space space) {
+StackTracePtr StackTrace::New(const Array& code_array,
+ const Array& pc_offset_array,
+ Heap::Space space) {
StackTrace& result = StackTrace::Handle();
{
- RawObject* raw = Object::Allocate(StackTrace::kClassId,
- StackTrace::InstanceSize(), space);
+ ObjectPtr raw = Object::Allocate(StackTrace::kClassId,
+ StackTrace::InstanceSize(), space);
NoSafepointScope no_safepoint;
result ^= raw;
}
@@ -23520,15 +23507,15 @@
return result.raw();
}
-RawStackTrace* StackTrace::New(const Array& code_array,
- const Array& pc_offset_array,
- const StackTrace& async_link,
- bool skip_sync_start_in_parent_stack,
- Heap::Space space) {
+StackTracePtr StackTrace::New(const Array& code_array,
+ const Array& pc_offset_array,
+ const StackTrace& async_link,
+ bool skip_sync_start_in_parent_stack,
+ Heap::Space space) {
StackTrace& result = StackTrace::Handle();
{
- RawObject* raw = Object::Allocate(StackTrace::kClassId,
- StackTrace::InstanceSize(), space);
+ ObjectPtr raw = Object::Allocate(StackTrace::kClassId,
+ StackTrace::InstanceSize(), space);
NoSafepointScope no_safepoint;
result ^= raw;
}
@@ -23540,40 +23527,45 @@
return result.raw();
}
-#if defined(DART_PRECOMPILER) || defined(DART_PRECOMPILED_RUNTIME)
-static void PrintStackTraceFrameBodyFromDSO(ZoneTextBuffer* buffer,
- uword call_addr) {
- uword dso_base;
- char* dso_name;
- if (NativeSymbolResolver::LookupSharedObject(call_addr, &dso_base,
- &dso_name)) {
- uword symbol_start;
- if (auto const symbol_name =
- NativeSymbolResolver::LookupSymbolName(call_addr, &symbol_start)) {
- uword symbol_offset = call_addr - symbol_start;
- buffer->Printf(" %s+0x%" Px "", symbol_name, symbol_offset);
- NativeSymbolResolver::FreeSymbolName(symbol_name);
- } else {
- buffer->Printf(" %s", dso_name);
- }
- NativeSymbolResolver::FreeSymbolName(dso_name);
+#if defined(DART_PRECOMPILED_RUNTIME)
+static void PrintNonSymbolicStackFrameBody(ZoneTextBuffer* buffer,
+ uword call_addr,
+ uword isolate_instructions,
+ uword vm_instructions) {
+ const word vm_offset = call_addr - vm_instructions;
+ const word isolate_offset = call_addr - isolate_instructions;
+ // Pick the closest instructions section start before the call address.
+ if (vm_offset > 0 && (isolate_offset < 0 || vm_offset < isolate_offset)) {
+ buffer->Printf(" %s+0x%" Px "", kVmSnapshotInstructionsAsmSymbol,
+ vm_offset);
+ } else if (isolate_offset > 0) {
+ buffer->Printf(" %s+0x%" Px "", kIsolateSnapshotInstructionsAsmSymbol,
+ isolate_offset);
} else {
- buffer->Printf(" <unknown>");
+ uword dso_base;
+ char* dso_name;
+ if (NativeSymbolResolver::LookupSharedObject(call_addr, &dso_base,
+ &dso_name)) {
+ buffer->Printf(" %s", dso_name);
+ NativeSymbolResolver::FreeSymbolName(dso_name);
+ } else {
+ buffer->Printf(" <unknown>");
+ }
}
buffer->Printf("\n");
}
#endif
-static void PrintStackTraceFrameIndex(ZoneTextBuffer* buffer,
- intptr_t frame_index) {
+static void PrintSymbolicStackFrameIndex(ZoneTextBuffer* buffer,
+ intptr_t frame_index) {
buffer->Printf("#%-6" Pd "", frame_index);
}
-static void PrintStackTraceFrameBody(ZoneTextBuffer* buffer,
- const char* function_name,
- const char* url,
- intptr_t line = -1,
- intptr_t column = -1) {
+static void PrintSymbolicStackFrameBody(ZoneTextBuffer* buffer,
+ const char* function_name,
+ const char* url,
+ intptr_t line = -1,
+ intptr_t column = -1) {
buffer->Printf(" %s (%s", function_name, url);
if (line >= 0) {
buffer->Printf(":%" Pd "", line);
@@ -23584,11 +23576,11 @@
buffer->Printf(")\n");
}
-static void PrintStackTraceFrame(Zone* zone,
- ZoneTextBuffer* buffer,
- const Function& function,
- TokenPosition token_pos,
- intptr_t frame_index) {
+static void PrintSymbolicStackFrame(Zone* zone,
+ ZoneTextBuffer* buffer,
+ const Function& function,
+ TokenPosition token_pos,
+ intptr_t frame_index) {
ASSERT(!function.IsNull());
const auto& script = Script::Handle(zone, function.script());
auto& handle = String::Handle(zone, function.QualifiedUserVisibleName());
@@ -23611,13 +23603,14 @@
script.GetTokenLocation(token_pos.SourcePosition(), &line, &column);
}
- PrintStackTraceFrameIndex(buffer, frame_index);
- PrintStackTraceFrameBody(buffer, function_name, url, line, column);
+ PrintSymbolicStackFrameIndex(buffer, frame_index);
+ PrintSymbolicStackFrameBody(buffer, function_name, url, line, column);
}
-const char* StackTrace::ToDartCString(const StackTrace& stack_trace_in) {
- auto const zone = Thread::Current()->zone();
- auto& stack_trace = StackTrace::Handle(zone, stack_trace_in.raw());
+const char* StackTrace::ToCString() const {
+ auto const T = Thread::Current();
+ auto const zone = T->zone();
+ auto& stack_trace = StackTrace::Handle(zone, this->raw());
auto& function = Function::Handle(zone);
auto& code_object = Object::Handle(zone);
auto& code = Code::Handle(zone);
@@ -23627,6 +23620,30 @@
GrowableArray<TokenPosition> inlined_token_positions;
ZoneTextBuffer buffer(zone, 1024);
+#if defined(DART_PRECOMPILED_RUNTIME)
+ auto const isolate_instructions = reinterpret_cast<uword>(
+ T->isolate_group()->source()->snapshot_instructions);
+ auto const vm_instructions = reinterpret_cast<uword>(
+ Dart::vm_isolate()->group()->source()->snapshot_instructions);
+ if (FLAG_dwarf_stack_traces_mode) {
+ // The Dart standard requires the output of StackTrace.toString to include
+ // all pending activations with precise source locations (i.e., to expand
+ // inlined frames and provide line and column numbers).
+ buffer.Printf(
+ "Warning: This VM has been configured to produce stack traces "
+ "that violate the Dart standard.\n");
+ // This prologue imitates Android's debuggerd to make it possible to paste
+ // the stack trace into ndk-stack.
+ buffer.Printf(
+ "*** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***\n");
+ OSThread* thread = OSThread::Current();
+ buffer.Printf("pid: %" Pd ", tid: %" Pd ", name %s\n", OS::ProcessId(),
+ OSThread::ThreadIdToIntPtr(thread->id()), thread->name());
+ buffer.Printf("isolate_instructions: %" Px "", isolate_instructions);
+ buffer.Printf(" vm_instructions: %" Px "\n", vm_instructions);
+ }
+#endif
+
// Iterate through the stack frames and create C string description
// for each frame.
intptr_t frame_index = 0;
@@ -23653,15 +23670,45 @@
ASSERT(code.IsFunctionCode());
function = code.function();
const uword pc = code.PayloadStart() + pc_offset;
- if (function.IsNull()) {
#if defined(DART_PRECOMPILED_RUNTIME)
- PrintStackTraceFrameIndex(&buffer, frame_index);
- PrintStackTraceFrameBodyFromDSO(&buffer, pc - 1);
+ // When printing non-symbolic frames, we normally print call
+ // addresses, not return addresses, by subtracting one from the PC to
+ // get an address within the preceding instruction.
+ //
+ // The one exception is a normal closure registered as a listener on a
+ // future. In this case, the returned pc_offset is 0, as the closure
+ // is invoked with the value of the resolved future. Thus, we must
+ // report the return address, as returning a value before the closure
+ // payload will cause failures to decode the frame using DWARF info.
+ const bool is_future_listener = pc_offset == 0;
+ const uword call_addr = is_future_listener ? pc : pc - 1;
+ if (FLAG_dwarf_stack_traces_mode) {
+ // If we have access to the owning function and it would be
+ // invisible in a symbolic stack trace, don't show this frame.
+ // (We can't do the same for inlined functions, though.)
+ if (!FLAG_show_invisible_frames && !function.IsNull() &&
+ !function.is_visible()) {
+ continue;
+ }
+ // This output is formatted like Android's debuggerd. Note debuggerd
+ // prints call addresses instead of return addresses.
+ buffer.Printf(" #%02" Pd " abs %" Pp "", frame_index, call_addr);
+ PrintNonSymbolicStackFrameBody(
+ &buffer, call_addr, isolate_instructions, vm_instructions);
frame_index++;
-#else
- UNREACHABLE();
+ continue;
+ } else if (function.IsNull()) {
+ // We can't print the symbolic information since the owner was not
+ // retained, so instead print the static symbol + offset like the
+ // non-symbolic stack traces.
+ PrintSymbolicStackFrameIndex(&buffer, frame_index);
+ PrintNonSymbolicStackFrameBody(
+ &buffer, call_addr, isolate_instructions, vm_instructions);
+ frame_index++;
+ continue;
+ }
#endif
- } else if (code.is_optimized() && stack_trace.expand_inlined()) {
+ if (code.is_optimized() && stack_trace.expand_inlined()) {
code.GetInlinedFunctionsAtReturnAddress(
pc_offset, &inlined_functions, &inlined_token_positions);
ASSERT(inlined_functions.length() >= 1);
@@ -23669,13 +23716,14 @@
const auto& inlined = *inlined_functions[j];
auto const pos = inlined_token_positions[j];
if (FLAG_show_invisible_frames || function.is_visible()) {
- PrintStackTraceFrame(zone, &buffer, inlined, pos, frame_index);
+ PrintSymbolicStackFrame(zone, &buffer, inlined, pos,
+ frame_index);
frame_index++;
}
}
} else if (FLAG_show_invisible_frames || function.is_visible()) {
auto const pos = code.GetTokenIndexOfPC(pc);
- PrintStackTraceFrame(zone, &buffer, function, pos, frame_index);
+ PrintSymbolicStackFrame(zone, &buffer, function, pos, frame_index);
frame_index++;
}
} else {
@@ -23685,7 +23733,7 @@
if (FLAG_show_invisible_frames || function.is_visible()) {
uword pc = bytecode.PayloadStart() + pc_offset;
auto const pos = bytecode.GetTokenIndexOfPC(pc);
- PrintStackTraceFrame(zone, &buffer, function, pos, frame_index);
+ PrintSymbolicStackFrame(zone, &buffer, function, pos, frame_index);
frame_index++;
}
}
@@ -23701,83 +23749,6 @@
return buffer.buffer();
}
-const char* StackTrace::ToDwarfCString(const StackTrace& stack_trace_in) {
-#if defined(DART_PRECOMPILER) || defined(DART_PRECOMPILED_RUNTIME)
- auto const T = Thread::Current();
- auto const zone = T->zone();
- auto& stack_trace = StackTrace::Handle(zone, stack_trace_in.raw());
- auto& code = Object::Handle(zone);
- ZoneTextBuffer buffer(zone, 1024);
-
- // The Dart standard requires the output of StackTrace.toString to include
- // all pending activations with precise source locations (i.e., to expand
- // inlined frames and provide line and column numbers).
- buffer.Printf(
- "Warning: This VM has been configured to produce stack traces "
- "that violate the Dart standard.\n");
- // This prologue imitates Android's debuggerd to make it possible to paste
- // the stack trace into ndk-stack.
- buffer.Printf(
- "*** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***\n");
- OSThread* thread = OSThread::Current();
- buffer.Printf("pid: %" Pd ", tid: %" Pd ", name %s\n", OS::ProcessId(),
- OSThread::ThreadIdToIntPtr(thread->id()), thread->name());
- auto const isolate_instructions =
- T->isolate_group()->source()->snapshot_instructions;
- auto const vm_instructions =
- Dart::vm_isolate()->group()->source()->snapshot_instructions;
- buffer.Printf("isolate_instructions: %" Px "",
- reinterpret_cast<uintptr_t>(isolate_instructions));
- buffer.Printf(" vm_instructions: %" Px "\n",
- reinterpret_cast<uintptr_t>(vm_instructions));
- intptr_t frame_index = 0;
- uint32_t frame_skip = 0;
- do {
- for (intptr_t i = frame_skip; i < stack_trace.Length(); i++) {
- code = stack_trace.CodeAtFrame(i);
- if (code.IsNull()) {
- // Check for a null function, which indicates a gap in a StackOverflow
- // or OutOfMemory trace.
- if ((i < (stack_trace.Length() - 1)) &&
- (stack_trace.CodeAtFrame(i + 1) != Code::null())) {
- buffer.AddString("...\n...\n");
- ASSERT(stack_trace.PcOffsetAtFrame(i) != Smi::null());
- // To account for gap frames.
- frame_index += Smi::Value(stack_trace.PcOffsetAtFrame(i));
- }
- } else if (code.raw() == StubCode::AsynchronousGapMarker().raw()) {
- buffer.AddString("<asynchronous suspension>\n");
- // The frame immediately after the asynchronous gap marker is the
- // identical to the frame above the marker. Skip the frame to enhance
- // the readability of the trace.
- i++;
- } else {
- intptr_t pc_offset = Smi::Value(stack_trace.PcOffsetAtFrame(i));
- // This output is formatted like Android's debuggerd. Note debuggerd
- // prints call addresses instead of return addresses.
- uword start = code.IsBytecode() ? Bytecode::Cast(code).PayloadStart()
- : Code::Cast(code).PayloadStart();
- uword return_addr = start + pc_offset;
- uword call_addr = return_addr - 1;
- buffer.Printf(" #%02" Pd " abs %" Pp "", frame_index, call_addr);
- PrintStackTraceFrameBodyFromDSO(&buffer, call_addr);
- frame_index++;
- }
- }
- // Follow the link.
- frame_skip = stack_trace.skip_sync_start_in_parent_stack()
- ? StackTrace::kSyncAsyncCroppedFrames
- : 0;
- stack_trace = stack_trace.async_link();
- } while (!stack_trace.IsNull());
-
- return buffer.buffer();
-#else
- UNREACHABLE();
- return NULL;
-#endif // defined(DART_PRECOMPILER) || defined(DART_PRECOMPILED_RUNTIME)
-}
-
static void DwarfStackTracesHandler(bool value) {
FLAG_dwarf_stack_traces_mode = value;
@@ -23796,15 +23767,6 @@
"Omit CodeSourceMaps in precompiled snapshots and don't "
"symbolize stack traces in the precompiled runtime.");
-const char* StackTrace::ToCString() const {
-#if defined(DART_PRECOMPILED_RUNTIME)
- if (FLAG_dwarf_stack_traces_mode) {
- return ToDwarfCString(*this);
- }
-#endif
- return ToDartCString(*this);
-}
-
void RegExp::set_pattern(const String& pattern) const {
StorePointer(&raw_ptr()->pattern_, pattern.raw());
}
@@ -23841,10 +23803,10 @@
StorePointer(&raw_ptr()->capture_name_map_, array.raw());
}
-RawRegExp* RegExp::New(Heap::Space space) {
+RegExpPtr RegExp::New(Heap::Space space) {
RegExp& result = RegExp::Handle();
{
- RawObject* raw =
+ ObjectPtr raw =
Object::Allocate(RegExp::kClassId, RegExp::InstanceSize(), space);
NoSafepointScope no_safepoint;
result ^= raw;
@@ -23921,12 +23883,12 @@
str.ToCString(), flags().ToCString());
}
-RawWeakProperty* WeakProperty::New(Heap::Space space) {
+WeakPropertyPtr WeakProperty::New(Heap::Space space) {
ASSERT(Isolate::Current()->object_store()->weak_property_class() !=
Class::null());
- RawObject* raw = Object::Allocate(WeakProperty::kClassId,
- WeakProperty::InstanceSize(), space);
- RawWeakProperty* result = reinterpret_cast<RawWeakProperty*>(raw);
+ ObjectPtr raw = Object::Allocate(WeakProperty::kClassId,
+ WeakProperty::InstanceSize(), space);
+ WeakPropertyPtr result = static_cast<WeakPropertyPtr>(raw);
result->ptr()->next_ = 0; // Init the list to NULL.
return result;
}
@@ -23935,42 +23897,42 @@
return "_WeakProperty";
}
-RawAbstractType* MirrorReference::GetAbstractTypeReferent() const {
+AbstractTypePtr MirrorReference::GetAbstractTypeReferent() const {
ASSERT(Object::Handle(referent()).IsAbstractType());
return AbstractType::Cast(Object::Handle(referent())).raw();
}
-RawClass* MirrorReference::GetClassReferent() const {
+ClassPtr MirrorReference::GetClassReferent() const {
ASSERT(Object::Handle(referent()).IsClass());
return Class::Cast(Object::Handle(referent())).raw();
}
-RawField* MirrorReference::GetFieldReferent() const {
+FieldPtr MirrorReference::GetFieldReferent() const {
ASSERT(Object::Handle(referent()).IsField());
return Field::Cast(Object::Handle(referent())).raw();
}
-RawFunction* MirrorReference::GetFunctionReferent() const {
+FunctionPtr MirrorReference::GetFunctionReferent() const {
ASSERT(Object::Handle(referent()).IsFunction());
return Function::Cast(Object::Handle(referent())).raw();
}
-RawLibrary* MirrorReference::GetLibraryReferent() const {
+LibraryPtr MirrorReference::GetLibraryReferent() const {
ASSERT(Object::Handle(referent()).IsLibrary());
return Library::Cast(Object::Handle(referent())).raw();
}
-RawTypeParameter* MirrorReference::GetTypeParameterReferent() const {
+TypeParameterPtr MirrorReference::GetTypeParameterReferent() const {
ASSERT(Object::Handle(referent()).IsTypeParameter());
return TypeParameter::Cast(Object::Handle(referent())).raw();
}
-RawMirrorReference* MirrorReference::New(const Object& referent,
- Heap::Space space) {
+MirrorReferencePtr MirrorReference::New(const Object& referent,
+ Heap::Space space) {
MirrorReference& result = MirrorReference::Handle();
{
- RawObject* raw = Object::Allocate(MirrorReference::kClassId,
- MirrorReference::InstanceSize(), space);
+ ObjectPtr raw = Object::Allocate(MirrorReference::kClassId,
+ MirrorReference::InstanceSize(), space);
NoSafepointScope no_safepoint;
result ^= raw;
}
@@ -23988,7 +23950,7 @@
isolate->set_current_tag(*this);
}
-RawUserTag* UserTag::New(const String& label, Heap::Space space) {
+UserTagPtr UserTag::New(const String& label, Heap::Space space) {
Thread* thread = Thread::Current();
Isolate* isolate = thread->isolate();
ASSERT(isolate->tag_table() != GrowableObjectArray::null());
@@ -24007,7 +23969,7 @@
}
// No tag with label exists, create and register with isolate tag table.
{
- RawObject* raw =
+ ObjectPtr raw =
Object::Allocate(UserTag::kClassId, UserTag::InstanceSize(), space);
NoSafepointScope no_safepoint;
result ^= raw;
@@ -24017,7 +23979,7 @@
return result.raw();
}
-RawUserTag* UserTag::DefaultTag() {
+UserTagPtr UserTag::DefaultTag() {
Thread* thread = Thread::Current();
Zone* zone = thread->zone();
Isolate* isolate = thread->isolate();
@@ -24034,7 +23996,7 @@
return result.raw();
}
-RawUserTag* UserTag::FindTagInIsolate(Thread* thread, const String& label) {
+UserTagPtr UserTag::FindTagInIsolate(Thread* thread, const String& label) {
Isolate* isolate = thread->isolate();
Zone* zone = thread->zone();
ASSERT(isolate->tag_table() != GrowableObjectArray::null());
@@ -24088,7 +24050,7 @@
return tag_table.Length() == UserTags::kMaxUserTags;
}
-RawUserTag* UserTag::FindTagById(uword tag_id) {
+UserTagPtr UserTag::FindTagById(uword tag_id) {
Thread* thread = Thread::Current();
Zone* zone = thread->zone();
Isolate* isolate = thread->isolate();
@@ -24159,7 +24121,7 @@
}
DART_WARN_UNUSED_RESULT
-RawError* VerifyEntryPoint(
+ErrorPtr VerifyEntryPoint(
const Library& lib,
const Object& member,
const Object& annotated,
@@ -24219,7 +24181,7 @@
}
DART_WARN_UNUSED_RESULT
-RawError* EntryPointFieldInvocationError(const String& getter_name) {
+ErrorPtr EntryPointFieldInvocationError(const String& getter_name) {
if (!FLAG_verify_entry_points) return Error::null();
char const* error = OS::SCreate(
@@ -24234,31 +24196,31 @@
return ApiError::New(String::Handle(String::New(error)));
}
-RawError* Function::VerifyCallEntryPoint() const {
+ErrorPtr Function::VerifyCallEntryPoint() const {
if (!FLAG_verify_entry_points) return Error::null();
const Class& cls = Class::Handle(Owner());
const Library& lib = Library::Handle(cls.library());
switch (kind()) {
- case RawFunction::kRegularFunction:
- case RawFunction::kSetterFunction:
- case RawFunction::kConstructor:
+ case FunctionLayout::kRegularFunction:
+ case FunctionLayout::kSetterFunction:
+ case FunctionLayout::kConstructor:
return dart::VerifyEntryPoint(lib, *this, *this,
{EntryPointPragma::kCallOnly});
break;
- case RawFunction::kGetterFunction:
+ case FunctionLayout::kGetterFunction:
return dart::VerifyEntryPoint(
lib, *this, *this,
{EntryPointPragma::kCallOnly, EntryPointPragma::kGetterOnly});
break;
- case RawFunction::kImplicitGetter:
+ case FunctionLayout::kImplicitGetter:
return dart::VerifyEntryPoint(lib, *this, Field::Handle(accessor_field()),
{EntryPointPragma::kGetterOnly});
break;
- case RawFunction::kImplicitSetter:
+ case FunctionLayout::kImplicitSetter:
return dart::VerifyEntryPoint(lib, *this, Field::Handle(accessor_field()),
{EntryPointPragma::kSetterOnly});
- case RawFunction::kMethodExtractor:
+ case FunctionLayout::kMethodExtractor:
return Function::Handle(extracted_method_closure())
.VerifyClosurizedEntryPoint();
break;
@@ -24268,14 +24230,14 @@
}
}
-RawError* Function::VerifyClosurizedEntryPoint() const {
+ErrorPtr Function::VerifyClosurizedEntryPoint() const {
if (!FLAG_verify_entry_points) return Error::null();
const Class& cls = Class::Handle(Owner());
const Library& lib = Library::Handle(cls.library());
switch (kind()) {
- case RawFunction::kRegularFunction:
- case RawFunction::kImplicitClosureFunction:
+ case FunctionLayout::kRegularFunction:
+ case FunctionLayout::kImplicitClosureFunction:
return dart::VerifyEntryPoint(lib, *this, *this,
{EntryPointPragma::kGetterOnly});
default:
@@ -24283,14 +24245,14 @@
}
}
-RawError* Field::VerifyEntryPoint(EntryPointPragma pragma) const {
+ErrorPtr Field::VerifyEntryPoint(EntryPointPragma pragma) const {
if (!FLAG_verify_entry_points) return Error::null();
const Class& cls = Class::Handle(Owner());
const Library& lib = Library::Handle(cls.library());
return dart::VerifyEntryPoint(lib, *this, *this, {pragma});
}
-RawError* Class::VerifyEntryPoint() const {
+ErrorPtr Class::VerifyEntryPoint() const {
if (!FLAG_verify_entry_points) return Error::null();
const Library& lib = Library::Handle(library());
if (!lib.IsNull()) {
diff --git a/runtime/vm/object.h b/runtime/vm/object.h
index 3b6f97a..39f112a 100644
--- a/runtime/vm/object.h
+++ b/runtime/vm/object.h
@@ -80,8 +80,9 @@
#define BASE_OBJECT_IMPLEMENTATION(object, super) \
public: /* NOLINT */ \
- using RawObjectType = Raw##object; \
- Raw##object* raw() const { return reinterpret_cast<Raw##object*>(raw_); } \
+ using ObjectLayoutType = dart::object##Layout; \
+ using ObjectPtrType = dart::object##Ptr; \
+ object##Ptr raw() const { return static_cast<object##Ptr>(raw_); } \
bool Is##object() const { return true; } \
DART_NOINLINE static object& Handle() { \
return HandleImpl(Thread::Current()->zone(), object::null()); \
@@ -89,10 +90,10 @@
DART_NOINLINE static object& Handle(Zone* zone) { \
return HandleImpl(zone, object::null()); \
} \
- DART_NOINLINE static object& Handle(Raw##object* raw_ptr) { \
+ DART_NOINLINE static object& Handle(object##Ptr raw_ptr) { \
return HandleImpl(Thread::Current()->zone(), raw_ptr); \
} \
- DART_NOINLINE static object& Handle(Zone* zone, Raw##object* raw_ptr) { \
+ DART_NOINLINE static object& Handle(Zone* zone, object##Ptr raw_ptr) { \
return HandleImpl(zone, raw_ptr); \
} \
DART_NOINLINE static object& ZoneHandle() { \
@@ -101,10 +102,10 @@
DART_NOINLINE static object& ZoneHandle(Zone* zone) { \
return ZoneHandleImpl(zone, object::null()); \
} \
- DART_NOINLINE static object& ZoneHandle(Raw##object* raw_ptr) { \
+ DART_NOINLINE static object& ZoneHandle(object##Ptr raw_ptr) { \
return ZoneHandleImpl(Thread::Current()->zone(), raw_ptr); \
} \
- DART_NOINLINE static object& ZoneHandle(Zone* zone, Raw##object* raw_ptr) { \
+ DART_NOINLINE static object& ZoneHandle(Zone* zone, object##Ptr raw_ptr) { \
return ZoneHandleImpl(zone, raw_ptr); \
} \
DART_NOINLINE static object* ReadOnlyHandle() { \
@@ -112,7 +113,7 @@
initializeHandle(obj, object::null()); \
return obj; \
} \
- DART_NOINLINE static object& CheckedHandle(Zone* zone, RawObject* raw_ptr) { \
+ DART_NOINLINE static object& CheckedHandle(Zone* zone, ObjectPtr raw_ptr) { \
object* obj = reinterpret_cast<object*>(VMHandles::AllocateHandle(zone)); \
initializeHandle(obj, raw_ptr); \
if (!obj->Is##object()) { \
@@ -122,7 +123,7 @@
return *obj; \
} \
DART_NOINLINE static object& CheckedZoneHandle(Zone* zone, \
- RawObject* raw_ptr) { \
+ ObjectPtr raw_ptr) { \
object* obj = \
reinterpret_cast<object*>(VMHandles::AllocateZoneHandle(zone)); \
initializeHandle(obj, raw_ptr); \
@@ -132,7 +133,7 @@
} \
return *obj; \
} \
- DART_NOINLINE static object& CheckedZoneHandle(RawObject* raw_ptr) { \
+ DART_NOINLINE static object& CheckedZoneHandle(ObjectPtr raw_ptr) { \
return CheckedZoneHandle(Thread::Current()->zone(), raw_ptr); \
} \
/* T::Cast cannot be applied to a null Object, because the object vtable */ \
@@ -142,30 +143,30 @@
ASSERT(obj.Is##object()); \
return reinterpret_cast<const object&>(obj); \
} \
- static Raw##object* RawCast(RawObject* raw) { \
+ static object##Ptr RawCast(ObjectPtr raw) { \
ASSERT(Object::Handle(raw).IsNull() || Object::Handle(raw).Is##object()); \
- return reinterpret_cast<Raw##object*>(raw); \
+ return static_cast<object##Ptr>(raw); \
} \
- static Raw##object* null() { \
- return reinterpret_cast<Raw##object*>(Object::null()); \
+ static object##Ptr null() { \
+ return static_cast<object##Ptr>(Object::null()); \
} \
virtual const char* ToCString() const; \
static const ClassId kClassId = k##object##Cid; \
\
private: /* NOLINT */ \
- static object& HandleImpl(Zone* zone, Raw##object* raw_ptr) { \
+ static object& HandleImpl(Zone* zone, object##Ptr raw_ptr) { \
object* obj = reinterpret_cast<object*>(VMHandles::AllocateHandle(zone)); \
initializeHandle(obj, raw_ptr); \
return *obj; \
} \
- static object& ZoneHandleImpl(Zone* zone, Raw##object* raw_ptr) { \
+ static object& ZoneHandleImpl(Zone* zone, object##Ptr raw_ptr) { \
object* obj = \
reinterpret_cast<object*>(VMHandles::AllocateZoneHandle(zone)); \
initializeHandle(obj, raw_ptr); \
return *obj; \
} \
/* Initialize the handle based on the raw_ptr in the presence of null. */ \
- static void initializeHandle(object* obj, RawObject* raw_ptr) { \
+ static void initializeHandle(object* obj, ObjectPtr raw_ptr) { \
if (raw_ptr != Object::null()) { \
obj->SetRaw(raw_ptr); \
} else { \
@@ -181,7 +182,7 @@
private: /* NOLINT */ \
void* operator new(size_t size); \
object(const object& value) = delete; \
- void operator=(Raw##super* value) = delete; \
+ void operator=(super##Ptr value) = delete; \
void operator=(const object& value) = delete; \
void operator=(const super& value) = delete;
@@ -205,15 +206,15 @@
#endif // !PRODUCT
#define SNAPSHOT_READER_SUPPORT(object) \
- static Raw##object* ReadFrom(SnapshotReader* reader, intptr_t object_id, \
- intptr_t tags, Snapshot::Kind, \
- bool as_reference); \
+ static object##Ptr ReadFrom(SnapshotReader* reader, intptr_t object_id, \
+ intptr_t tags, Snapshot::Kind, \
+ bool as_reference); \
friend class SnapshotReader;
#define OBJECT_IMPLEMENTATION(object, super) \
public: /* NOLINT */ \
- void operator=(Raw##object* value) { initializeHandle(this, value); } \
- void operator^=(RawObject* value) { \
+ void operator=(object##Ptr value) { initializeHandle(this, value); } \
+ void operator^=(ObjectPtr value) { \
initializeHandle(this, value); \
ASSERT(IsNull() || Is##object()); \
} \
@@ -226,7 +227,7 @@
#define HEAP_OBJECT_IMPLEMENTATION(object, super) \
OBJECT_IMPLEMENTATION(object, super); \
- const Raw##object* raw_ptr() const { \
+ const object##Layout* raw_ptr() const { \
ASSERT(raw() != null()); \
return raw()->ptr(); \
} \
@@ -237,11 +238,11 @@
// This macro is used to denote types that do not have a sub-type.
#define FINAL_HEAP_OBJECT_IMPLEMENTATION_HELPER(object, rettype, super) \
public: /* NOLINT */ \
- void operator=(Raw##object* value) { \
+ void operator=(object##Ptr value) { \
raw_ = value; \
CHECK_HANDLE(); \
} \
- void operator^=(RawObject* value) { \
+ void operator^=(ObjectPtr value) { \
raw_ = value; \
CHECK_HANDLE(); \
} \
@@ -250,7 +251,7 @@
object() : super() {} \
BASE_OBJECT_IMPLEMENTATION(object, super) \
OBJECT_SERVICE_SUPPORT(object) \
- const Raw##object* raw_ptr() const { \
+ const object##Layout* raw_ptr() const { \
ASSERT(raw() != null()); \
return raw()->ptr(); \
} \
@@ -277,27 +278,29 @@
class Object {
public:
- using RawObjectType = RawObject;
- static RawObject* RawCast(RawObject* obj) { return obj; }
+ using ObjectLayoutType = ObjectLayout;
+ using ObjectPtrType = ObjectPtr;
+
+ static ObjectPtr RawCast(ObjectPtr obj) { return obj; }
virtual ~Object() {}
- RawObject* raw() const { return raw_; }
- void operator=(RawObject* value) { initializeHandle(this, value); }
+ ObjectPtr raw() const { return raw_; }
+ void operator=(ObjectPtr value) { initializeHandle(this, value); }
uint32_t CompareAndSwapTags(uint32_t old_tags, uint32_t new_tags) const {
raw()->ptr()->tags_.StrongCAS(old_tags, new_tags);
return old_tags;
}
- bool IsCanonical() const { return raw()->IsCanonical(); }
- void SetCanonical() const { raw()->SetCanonical(); }
- void ClearCanonical() const { raw()->ClearCanonical(); }
+ bool IsCanonical() const { return raw()->ptr()->IsCanonical(); }
+ void SetCanonical() const { raw()->ptr()->SetCanonical(); }
+ void ClearCanonical() const { raw()->ptr()->ClearCanonical(); }
intptr_t GetClassId() const {
return !raw()->IsHeapObject() ? static_cast<intptr_t>(kSmiCid)
- : raw()->GetClassId();
+ : raw()->ptr()->GetClassId();
}
- inline RawClass* clazz() const;
- static intptr_t tags_offset() { return OFFSET_OF(RawObject, tags_); }
+ inline ClassPtr clazz() const;
+ static intptr_t tags_offset() { return OFFSET_OF(ObjectLayout, tags_); }
// Class testers.
#define DEFINE_CLASS_TESTER(clazz) \
@@ -327,14 +330,14 @@
// Object::DictionaryName() returns String::null(). Only subclasses
// of Object that need to be entered in the library and library prefix
// namespaces need to provide an implementation.
- virtual RawString* DictionaryName() const;
+ virtual StringPtr DictionaryName() const;
bool IsNew() const { return raw()->IsNewObject(); }
bool IsOld() const { return raw()->IsOldObject(); }
#if defined(DEBUG)
bool InVMIsolateHeap() const;
#else
- bool InVMIsolateHeap() const { return raw()->InVMIsolateHeap(); }
+ bool InVMIsolateHeap() const { return raw()->ptr()->InVMIsolateHeap(); }
#endif // DEBUG
// Print the object on stdout for debugging.
@@ -348,7 +351,7 @@
bool IsNotTemporaryScopedHandle() const;
- static Object& Handle(Zone* zone, RawObject* raw_ptr) {
+ static Object& Handle(Zone* zone, ObjectPtr raw_ptr) {
Object* obj = reinterpret_cast<Object*>(VMHandles::AllocateHandle(zone));
initializeHandle(obj, raw_ptr);
return *obj;
@@ -363,11 +366,11 @@
static Object& Handle(Zone* zone) { return Handle(zone, null_); }
- static Object& Handle(RawObject* raw_ptr) {
+ static Object& Handle(ObjectPtr raw_ptr) {
return Handle(Thread::Current()->zone(), raw_ptr);
}
- static Object& ZoneHandle(Zone* zone, RawObject* raw_ptr) {
+ static Object& ZoneHandle(Zone* zone, ObjectPtr raw_ptr) {
Object* obj =
reinterpret_cast<Object*>(VMHandles::AllocateZoneHandle(zone));
initializeHandle(obj, raw_ptr);
@@ -380,18 +383,18 @@
return ZoneHandle(Thread::Current()->zone(), null_);
}
- static Object& ZoneHandle(RawObject* raw_ptr) {
+ static Object& ZoneHandle(ObjectPtr raw_ptr) {
return ZoneHandle(Thread::Current()->zone(), raw_ptr);
}
- static RawObject* null() { return null_; }
+ static ObjectPtr null() { return null_; }
#if defined(HASH_IN_OBJECT_HEADER)
- static uint32_t GetCachedHash(const RawObject* obj) {
+ static uint32_t GetCachedHash(const ObjectPtr obj) {
return obj->ptr()->hash_;
}
- static void SetCachedHash(RawObject* obj, uint32_t hash) {
+ static void SetCachedHash(ObjectPtr obj, uint32_t hash) {
obj->ptr()->hash_ = hash;
}
#endif
@@ -448,7 +451,6 @@
V(Array, vm_isolate_snapshot_object_table) \
V(Type, dynamic_type) \
V(Type, void_type) \
- V(Type, never_type) \
V(AbstractType, null_abstract_type)
#define DEFINE_SHARED_READONLY_HANDLE_GETTER(Type, name) \
@@ -461,65 +463,60 @@
static void set_vm_isolate_snapshot_object_table(const Array& table);
- static RawClass* class_class() { return class_class_; }
- static RawClass* dynamic_class() { return dynamic_class_; }
- static RawClass* void_class() { return void_class_; }
- static RawClass* never_class() { return never_class_; }
- static RawClass* type_arguments_class() { return type_arguments_class_; }
- static RawClass* patch_class_class() { return patch_class_class_; }
- static RawClass* function_class() { return function_class_; }
- static RawClass* closure_data_class() { return closure_data_class_; }
- static RawClass* signature_data_class() { return signature_data_class_; }
- static RawClass* redirection_data_class() { return redirection_data_class_; }
- static RawClass* ffi_trampoline_data_class() {
+ static ClassPtr class_class() { return class_class_; }
+ static ClassPtr dynamic_class() { return dynamic_class_; }
+ static ClassPtr void_class() { return void_class_; }
+ static ClassPtr type_arguments_class() { return type_arguments_class_; }
+ static ClassPtr patch_class_class() { return patch_class_class_; }
+ static ClassPtr function_class() { return function_class_; }
+ static ClassPtr closure_data_class() { return closure_data_class_; }
+ static ClassPtr signature_data_class() { return signature_data_class_; }
+ static ClassPtr redirection_data_class() { return redirection_data_class_; }
+ static ClassPtr ffi_trampoline_data_class() {
return ffi_trampoline_data_class_;
}
- static RawClass* field_class() { return field_class_; }
- static RawClass* script_class() { return script_class_; }
- static RawClass* library_class() { return library_class_; }
- static RawClass* namespace_class() { return namespace_class_; }
- static RawClass* kernel_program_info_class() {
+ static ClassPtr field_class() { return field_class_; }
+ static ClassPtr script_class() { return script_class_; }
+ static ClassPtr library_class() { return library_class_; }
+ static ClassPtr namespace_class() { return namespace_class_; }
+ static ClassPtr kernel_program_info_class() {
return kernel_program_info_class_;
}
- static RawClass* code_class() { return code_class_; }
- static RawClass* bytecode_class() { return bytecode_class_; }
- static RawClass* instructions_class() { return instructions_class_; }
- static RawClass* instructions_section_class() {
+ static ClassPtr code_class() { return code_class_; }
+ static ClassPtr bytecode_class() { return bytecode_class_; }
+ static ClassPtr instructions_class() { return instructions_class_; }
+ static ClassPtr instructions_section_class() {
return instructions_section_class_;
}
- static RawClass* object_pool_class() { return object_pool_class_; }
- static RawClass* pc_descriptors_class() { return pc_descriptors_class_; }
- static RawClass* code_source_map_class() { return code_source_map_class_; }
- static RawClass* compressed_stackmaps_class() {
+ static ClassPtr object_pool_class() { return object_pool_class_; }
+ static ClassPtr pc_descriptors_class() { return pc_descriptors_class_; }
+ static ClassPtr code_source_map_class() { return code_source_map_class_; }
+ static ClassPtr compressed_stackmaps_class() {
return compressed_stackmaps_class_;
}
- static RawClass* var_descriptors_class() { return var_descriptors_class_; }
- static RawClass* exception_handlers_class() {
+ static ClassPtr var_descriptors_class() { return var_descriptors_class_; }
+ static ClassPtr exception_handlers_class() {
return exception_handlers_class_;
}
- static RawClass* deopt_info_class() { return deopt_info_class_; }
- static RawClass* context_class() { return context_class_; }
- static RawClass* context_scope_class() { return context_scope_class_; }
- static RawClass* api_error_class() { return api_error_class_; }
- static RawClass* language_error_class() { return language_error_class_; }
- static RawClass* unhandled_exception_class() {
+ static ClassPtr deopt_info_class() { return deopt_info_class_; }
+ static ClassPtr context_class() { return context_class_; }
+ static ClassPtr context_scope_class() { return context_scope_class_; }
+ static ClassPtr api_error_class() { return api_error_class_; }
+ static ClassPtr language_error_class() { return language_error_class_; }
+ static ClassPtr unhandled_exception_class() {
return unhandled_exception_class_;
}
- static RawClass* unwind_error_class() { return unwind_error_class_; }
- static RawClass* dyncalltypecheck_class() { return dyncalltypecheck_class_; }
- static RawClass* singletargetcache_class() {
- return singletargetcache_class_;
- }
- static RawClass* unlinkedcall_class() { return unlinkedcall_class_; }
- static RawClass* monomorphicsmiablecall_class() {
+ static ClassPtr unwind_error_class() { return unwind_error_class_; }
+ static ClassPtr dyncalltypecheck_class() { return dyncalltypecheck_class_; }
+ static ClassPtr singletargetcache_class() { return singletargetcache_class_; }
+ static ClassPtr unlinkedcall_class() { return unlinkedcall_class_; }
+ static ClassPtr monomorphicsmiablecall_class() {
return monomorphicsmiablecall_class_;
}
- static RawClass* icdata_class() { return icdata_class_; }
- static RawClass* megamorphic_cache_class() {
- return megamorphic_cache_class_;
- }
- static RawClass* subtypetestcache_class() { return subtypetestcache_class_; }
- static RawClass* weak_serialization_reference_class() {
+ static ClassPtr icdata_class() { return icdata_class_; }
+ static ClassPtr megamorphic_cache_class() { return megamorphic_cache_class_; }
+ static ClassPtr subtypetestcache_class() { return subtypetestcache_class_; }
+ static ClassPtr weak_serialization_reference_class() {
return weak_serialization_reference_class_;
}
@@ -529,22 +526,22 @@
static void InitVtables();
static void FinishInit(Isolate* isolate);
static void FinalizeVMIsolate(Isolate* isolate);
- static void FinalizeReadOnlyObject(RawObject* object);
+ static void FinalizeReadOnlyObject(ObjectPtr object);
static void Cleanup();
// Initialize a new isolate either from a Kernel IR, from source, or from a
// snapshot.
- static RawError* Init(Isolate* isolate,
- const uint8_t* kernel_buffer,
- intptr_t kernel_buffer_size);
+ static ErrorPtr Init(Isolate* isolate,
+ const uint8_t* kernel_buffer,
+ intptr_t kernel_buffer_size);
static void MakeUnusedSpaceTraversable(const Object& obj,
intptr_t original_size,
intptr_t used_size);
static intptr_t InstanceSize() {
- return RoundedAllocationSize(sizeof(RawObject));
+ return RoundedAllocationSize(sizeof(ObjectLayout));
}
template <class FakeObject>
@@ -603,21 +600,21 @@
// Used for extracting the C++ vtable during bringup.
Object() : raw_(null_) {}
- uword raw_value() const { return reinterpret_cast<uword>(raw()); }
+ uword raw_value() const { return static_cast<uword>(raw()); }
- inline void SetRaw(RawObject* value);
+ inline void SetRaw(ObjectPtr value);
void CheckHandle() const;
cpp_vtable vtable() const { return bit_copy<cpp_vtable>(*this); }
void set_vtable(cpp_vtable value) { *vtable_address() = value; }
- static RawObject* Allocate(intptr_t cls_id, intptr_t size, Heap::Space space);
+ static ObjectPtr Allocate(intptr_t cls_id, intptr_t size, Heap::Space space);
static intptr_t RoundedAllocationSize(intptr_t size) {
return Utils::RoundUp(size, kObjectAlignment);
}
- bool Contains(uword addr) const { return raw()->Contains(addr); }
+ bool Contains(uword addr) const { return raw()->ptr()->Contains(addr); }
// Start of field mutator guards.
//
@@ -627,21 +624,21 @@
template <typename type, std::memory_order order = std::memory_order_relaxed>
type LoadPointer(type const* addr) const {
- return raw()->LoadPointer<type, order>(addr);
+ return raw()->ptr()->LoadPointer<type, order>(addr);
}
template <typename type, std::memory_order order = std::memory_order_relaxed>
void StorePointer(type const* addr, type value) const {
- raw()->StorePointer<type, order>(addr, value);
+ raw()->ptr()->StorePointer<type, order>(addr, value);
}
// Use for storing into an explicitly Smi-typed field of an object
// (i.e., both the previous and new value are Smis).
- void StoreSmi(RawSmi* const* addr, RawSmi* value) const {
- raw()->StoreSmi(addr, value);
+ void StoreSmi(SmiPtr const* addr, SmiPtr value) const {
+ raw()->ptr()->StoreSmi(addr, value);
}
- void StoreSmiIgnoreRace(RawSmi* const* addr, RawSmi* value) const {
- raw()->StoreSmiIgnoreRace(addr, value);
+ void StoreSmiIgnoreRace(SmiPtr const* addr, SmiPtr value) const {
+ raw()->ptr()->StoreSmiIgnoreRace(addr, value);
}
template <typename FieldType>
@@ -654,14 +651,14 @@
template <typename FieldType, typename ValueType>
void StoreNonPointer(const FieldType* addr, ValueType value) const {
// Can't use Contains, as it uses tags_, which is set through this method.
- ASSERT(reinterpret_cast<uword>(addr) >= RawObject::ToAddr(raw()));
+ ASSERT(reinterpret_cast<uword>(addr) >= ObjectLayout::ToAddr(raw()));
*const_cast<FieldType*>(addr) = value;
}
template <typename FieldType, typename ValueType, std::memory_order order>
void StoreNonPointer(const FieldType* addr, ValueType value) const {
// Can't use Contains, as it uses tags_, which is set through this method.
- ASSERT(reinterpret_cast<uword>(addr) >= RawObject::ToAddr(raw()));
+ ASSERT(reinterpret_cast<uword>(addr) >= ObjectLayout::ToAddr(raw()));
reinterpret_cast<std::atomic<FieldType>*>(const_cast<FieldType*>(addr))
->store(value, order);
}
@@ -692,10 +689,10 @@
// instantiated with an object pointer type.
#define STORE_NON_POINTER_ILLEGAL_TYPE(type) \
template <typename ValueType> \
- void StoreNonPointer(Raw##type* const* addr, ValueType value) const { \
+ void StoreNonPointer(type##Ptr const* addr, ValueType value) const { \
UnimplementedMethod(); \
} \
- Raw##type** UnsafeMutableNonPointer(Raw##type* const* addr) const { \
+ type##Ptr* UnsafeMutableNonPointer(type##Ptr const* addr) const { \
UnimplementedMethod(); \
return NULL; \
}
@@ -705,11 +702,11 @@
#undef STORE_NON_POINTER_ILLEGAL_TYPE
// Allocate an object and copy the body of 'orig'.
- static RawObject* Clone(const Object& orig, Heap::Space space);
+ static ObjectPtr Clone(const Object& orig, Heap::Space space);
// End of field mutator guards.
- RawObject* raw_; // The raw object reference.
+ ObjectPtr raw_; // The raw object reference.
protected:
void AddCommonObjectProperties(JSONObject* jsobj,
@@ -732,7 +729,7 @@
const Library& lib);
/* Initialize the handle based on the raw_ptr in the presence of null. */
- static void initializeHandle(Object* obj, RawObject* raw_ptr) {
+ static void initializeHandle(Object* obj, ObjectPtr raw_ptr) {
if (raw_ptr != Object::null()) {
obj->SetRaw(raw_ptr);
} else {
@@ -751,64 +748,61 @@
// The static values below are singletons shared between the different
// isolates. They are all allocated in the non-GC'd Dart::vm_isolate_.
- static RawObject* null_;
- static RawBool* true_;
- static RawBool* false_;
+ static ObjectPtr null_;
+ static BoolPtr true_;
+ static BoolPtr false_;
- static RawClass* class_class_; // Class of the Class vm object.
- static RawClass* dynamic_class_; // Class of the 'dynamic' type.
- static RawClass* void_class_; // Class of the 'void' type.
- static RawClass* never_class_; // Class of the 'Never' type.
- static RawClass* type_arguments_class_; // Class of TypeArguments vm object.
- static RawClass* patch_class_class_; // Class of the PatchClass vm object.
- static RawClass* function_class_; // Class of the Function vm object.
- static RawClass* closure_data_class_; // Class of ClosureData vm obj.
- static RawClass* signature_data_class_; // Class of SignatureData vm obj.
- static RawClass* redirection_data_class_; // Class of RedirectionData vm obj.
- static RawClass* ffi_trampoline_data_class_; // Class of FfiTrampolineData
- // vm obj.
- static RawClass* field_class_; // Class of the Field vm object.
- static RawClass* script_class_; // Class of the Script vm object.
- static RawClass* library_class_; // Class of the Library vm object.
- static RawClass* namespace_class_; // Class of Namespace vm object.
- static RawClass* kernel_program_info_class_; // Class of KernelProgramInfo vm
- // object.
- static RawClass* code_class_; // Class of the Code vm object.
- static RawClass* bytecode_class_; // Class of the Bytecode vm object.
- static RawClass* instructions_class_; // Class of the Instructions vm object.
- static RawClass*
- instructions_section_class_; // Class of InstructionsSection.
- static RawClass* object_pool_class_; // Class of the ObjectPool vm object.
- static RawClass* pc_descriptors_class_; // Class of PcDescriptors vm object.
- static RawClass* code_source_map_class_; // Class of CodeSourceMap vm object.
- static RawClass*
- compressed_stackmaps_class_; // Class of CompressedStackMaps.
- static RawClass* var_descriptors_class_; // Class of LocalVarDescriptors.
- static RawClass* exception_handlers_class_; // Class of ExceptionHandlers.
- static RawClass* deopt_info_class_; // Class of DeoptInfo.
- static RawClass* context_class_; // Class of the Context vm object.
- static RawClass* context_scope_class_; // Class of ContextScope vm object.
- static RawClass* dyncalltypecheck_class_; // Class of ParameterTypeCheck.
- static RawClass* singletargetcache_class_; // Class of SingleTargetCache.
- static RawClass* unlinkedcall_class_; // Class of UnlinkedCall.
- static RawClass*
- monomorphicsmiablecall_class_; // Class of MonomorphicSmiableCall.
- static RawClass* icdata_class_; // Class of ICData.
- static RawClass* megamorphic_cache_class_; // Class of MegamorphiCache.
- static RawClass* subtypetestcache_class_; // Class of SubtypeTestCache.
- static RawClass* api_error_class_; // Class of ApiError.
- static RawClass* language_error_class_; // Class of LanguageError.
- static RawClass* unhandled_exception_class_; // Class of UnhandledException.
- static RawClass* unwind_error_class_; // Class of UnwindError.
+ static ClassPtr class_class_; // Class of the Class vm object.
+ static ClassPtr dynamic_class_; // Class of the 'dynamic' type.
+ static ClassPtr void_class_; // Class of the 'void' type.
+ static ClassPtr type_arguments_class_; // Class of TypeArguments vm object.
+ static ClassPtr patch_class_class_; // Class of the PatchClass vm object.
+ static ClassPtr function_class_; // Class of the Function vm object.
+ static ClassPtr closure_data_class_; // Class of ClosureData vm obj.
+ static ClassPtr signature_data_class_; // Class of SignatureData vm obj.
+ static ClassPtr redirection_data_class_; // Class of RedirectionData vm obj.
+ static ClassPtr ffi_trampoline_data_class_; // Class of FfiTrampolineData
+ // vm obj.
+ static ClassPtr field_class_; // Class of the Field vm object.
+ static ClassPtr script_class_; // Class of the Script vm object.
+ static ClassPtr library_class_; // Class of the Library vm object.
+ static ClassPtr namespace_class_; // Class of Namespace vm object.
+ static ClassPtr kernel_program_info_class_; // Class of KernelProgramInfo vm
+ // object.
+ static ClassPtr code_class_; // Class of the Code vm object.
+ static ClassPtr bytecode_class_; // Class of the Bytecode vm object.
+ static ClassPtr instructions_class_; // Class of the Instructions vm object.
+ static ClassPtr instructions_section_class_; // Class of InstructionsSection.
+ static ClassPtr object_pool_class_; // Class of the ObjectPool vm object.
+ static ClassPtr pc_descriptors_class_; // Class of PcDescriptors vm object.
+ static ClassPtr code_source_map_class_; // Class of CodeSourceMap vm object.
+ static ClassPtr compressed_stackmaps_class_; // Class of CompressedStackMaps.
+ static ClassPtr var_descriptors_class_; // Class of LocalVarDescriptors.
+ static ClassPtr exception_handlers_class_; // Class of ExceptionHandlers.
+ static ClassPtr deopt_info_class_; // Class of DeoptInfo.
+ static ClassPtr context_class_; // Class of the Context vm object.
+ static ClassPtr context_scope_class_; // Class of ContextScope vm object.
+ static ClassPtr dyncalltypecheck_class_; // Class of ParameterTypeCheck.
+ static ClassPtr singletargetcache_class_; // Class of SingleTargetCache.
+ static ClassPtr unlinkedcall_class_; // Class of UnlinkedCall.
+ static ClassPtr
+ monomorphicsmiablecall_class_; // Class of MonomorphicSmiableCall.
+ static ClassPtr icdata_class_; // Class of ICData.
+ static ClassPtr megamorphic_cache_class_; // Class of MegamorphiCache.
+ static ClassPtr subtypetestcache_class_; // Class of SubtypeTestCache.
+ static ClassPtr api_error_class_; // Class of ApiError.
+ static ClassPtr language_error_class_; // Class of LanguageError.
+ static ClassPtr unhandled_exception_class_; // Class of UnhandledException.
+ static ClassPtr unwind_error_class_; // Class of UnwindError.
// Class of WeakSerializationReference.
- static RawClass* weak_serialization_reference_class_;
+ static ClassPtr weak_serialization_reference_class_;
#define DECLARE_SHARED_READONLY_HANDLE(Type, name) static Type* name##_;
SHARED_READONLY_HANDLES_LIST(DECLARE_SHARED_READONLY_HANDLE)
#undef DECLARE_SHARED_READONLY_HANDLE
friend void ClassTable::Register(const Class& cls);
- friend void RawObject::Validate(IsolateGroup* isolate_group) const;
+ friend void ObjectLayout::Validate(IsolateGroup* isolate_group) const;
friend class Closure;
friend class SnapshotReader;
friend class InstanceDeserializationCluster;
@@ -829,17 +823,17 @@
class PassiveObject : public Object {
public:
- void operator=(RawObject* value) { raw_ = value; }
- void operator^=(RawObject* value) { raw_ = value; }
+ void operator=(ObjectPtr value) { raw_ = value; }
+ void operator^=(ObjectPtr value) { raw_ = value; }
- static PassiveObject& Handle(Zone* zone, RawObject* raw_ptr) {
+ static PassiveObject& Handle(Zone* zone, ObjectPtr raw_ptr) {
PassiveObject* obj =
reinterpret_cast<PassiveObject*>(VMHandles::AllocateHandle(zone));
obj->raw_ = raw_ptr;
obj->set_vtable(0);
return *obj;
}
- static PassiveObject& Handle(RawObject* raw_ptr) {
+ static PassiveObject& Handle(ObjectPtr raw_ptr) {
return Handle(Thread::Current()->zone(), raw_ptr);
}
static PassiveObject& Handle() {
@@ -848,14 +842,14 @@
static PassiveObject& Handle(Zone* zone) {
return Handle(zone, Object::null());
}
- static PassiveObject& ZoneHandle(Zone* zone, RawObject* raw_ptr) {
+ static PassiveObject& ZoneHandle(Zone* zone, ObjectPtr raw_ptr) {
PassiveObject* obj =
reinterpret_cast<PassiveObject*>(VMHandles::AllocateZoneHandle(zone));
obj->raw_ = raw_ptr;
obj->set_vtable(0);
return *obj;
}
- static PassiveObject& ZoneHandle(RawObject* raw_ptr) {
+ static PassiveObject& ZoneHandle(ObjectPtr raw_ptr) {
return ZoneHandle(Thread::Current()->zone(), raw_ptr);
}
static PassiveObject& ZoneHandle() {
@@ -933,10 +927,10 @@
return host_instance_size();
#endif // !defined(DART_PRECOMPILED_RUNTIME)
}
- static intptr_t host_instance_size(RawClass* clazz) {
+ static intptr_t host_instance_size(ClassPtr clazz) {
return (clazz->ptr()->host_instance_size_in_words_ * kWordSize);
}
- static intptr_t target_instance_size(RawClass* clazz) {
+ static intptr_t target_instance_size(ClassPtr clazz) {
#if !defined(DART_PRECOMPILED_RUNTIME)
return (clazz->ptr()->target_instance_size_in_words_ *
compiler::target::kWordSize);
@@ -1005,36 +999,36 @@
}
static bool is_valid_id(intptr_t value) {
- return RawObject::ClassIdTag::is_valid(value);
+ return ObjectLayout::ClassIdTag::is_valid(value);
}
intptr_t id() const { return raw_ptr()->id_; }
void set_id(intptr_t value) const {
ASSERT(is_valid_id(value));
StoreNonPointer(&raw_ptr()->id_, value);
}
- static intptr_t id_offset() { return OFFSET_OF(RawClass, id_); }
+ static intptr_t id_offset() { return OFFSET_OF(ClassLayout, id_); }
static intptr_t num_type_arguments_offset() {
- return OFFSET_OF(RawClass, num_type_arguments_);
+ return OFFSET_OF(ClassLayout, num_type_arguments_);
}
- RawString* Name() const;
- RawString* ScrubbedName() const;
+ StringPtr Name() const;
+ StringPtr ScrubbedName() const;
const char* ScrubbedNameCString() const;
- RawString* UserVisibleName() const;
+ StringPtr UserVisibleName() const;
const char* UserVisibleNameCString() const;
// The mixin for this class if one exists. Otherwise, returns a raw pointer
// to this class.
- RawClass* Mixin() const;
+ ClassPtr Mixin() const;
// The NNBD mode of the library declaring this class.
NNBDMode nnbd_mode() const;
bool IsInFullSnapshot() const;
- virtual RawString* DictionaryName() const { return Name(); }
+ virtual StringPtr DictionaryName() const { return Name(); }
- RawScript* script() const { return raw_ptr()->script_; }
+ ScriptPtr script() const { return raw_ptr()->script_; }
void set_script(const Script& value) const;
TokenPosition token_pos() const { return raw_ptr()->token_pos_; }
@@ -1045,7 +1039,7 @@
int32_t SourceFingerprint() const;
// This class represents a typedef if the signature function is not null.
- RawFunction* signature_function() const {
+ FunctionPtr signature_function() const {
return raw_ptr()->signature_function_;
}
void set_signature_function(const Function& value) const;
@@ -1053,7 +1047,7 @@
// Return the Type with type parameters declared by this class filled in with
// dynamic and type parameters declared in superclasses filled in as declared
// in superclass clauses.
- RawAbstractType* RareType() const;
+ AbstractTypePtr RareType() const;
// Return the Type whose arguments are the type parameters declared by this
// class preceded by the type arguments declared for superclasses, etc.
@@ -1063,18 +1057,18 @@
// C.DeclarationType() --> C [R, int, R]
// The declaration type's nullability is either legacy or non-nullable when
// the non-nullable experiment is enabled.
- RawType* DeclarationType() const;
+ TypePtr DeclarationType() const;
static intptr_t declaration_type_offset() {
- return OFFSET_OF(RawClass, declaration_type_);
+ return OFFSET_OF(ClassLayout, declaration_type_);
}
- RawLibrary* library() const { return raw_ptr()->library_; }
+ LibraryPtr library() const { return raw_ptr()->library_; }
void set_library(const Library& value) const;
// The type parameters (and their bounds) are specified as an array of
// TypeParameter.
- RawTypeArguments* type_parameters() const {
+ TypeArgumentsPtr type_parameters() const {
ASSERT(is_declaration_loaded());
return raw_ptr()->type_parameters_;
}
@@ -1084,12 +1078,12 @@
return NumTypeParameters(Thread::Current());
}
static intptr_t type_parameters_offset() {
- return OFFSET_OF(RawClass, type_parameters_);
+ return OFFSET_OF(ClassLayout, type_parameters_);
}
// Return a TypeParameter if the type_name is a type parameter of this class.
// Return null otherwise.
- RawTypeParameter* LookupTypeParameter(const String& type_name) const;
+ TypeParameterPtr LookupTypeParameter(const String& type_name) const;
// The type argument vector is flattened and includes the type arguments of
// the super class.
@@ -1149,49 +1143,49 @@
#endif // !defined(DART_PRECOMPILED_RUNTIME)
}
static intptr_t host_type_arguments_field_offset_in_words_offset() {
- return OFFSET_OF(RawClass, host_type_arguments_field_offset_in_words_);
+ return OFFSET_OF(ClassLayout, host_type_arguments_field_offset_in_words_);
}
static intptr_t target_type_arguments_field_offset_in_words_offset() {
#if !defined(DART_PRECOMPILED_RUNTIME)
- return OFFSET_OF(RawClass, target_type_arguments_field_offset_in_words_);
+ return OFFSET_OF(ClassLayout, target_type_arguments_field_offset_in_words_);
#else
return host_type_arguments_field_offset_in_words_offset();
#endif // !defined(DART_PRECOMPILED_RUNTIME)
}
// The super type of this class, Object type if not explicitly specified.
- RawAbstractType* super_type() const {
+ AbstractTypePtr super_type() const {
ASSERT(is_declaration_loaded());
return raw_ptr()->super_type_;
}
void set_super_type(const AbstractType& value) const;
static intptr_t super_type_offset() {
- return OFFSET_OF(RawClass, super_type_);
+ return OFFSET_OF(ClassLayout, super_type_);
}
// Asserts that the class of the super type has been resolved.
// |original_classes| only has an effect when reloading. If true and we
// are reloading, it will prefer the original classes to the replacement
// classes.
- RawClass* SuperClass(bool original_classes = false) const;
+ ClassPtr SuperClass(bool original_classes = false) const;
// Interfaces is an array of Types.
- RawArray* interfaces() const {
+ ArrayPtr interfaces() const {
ASSERT(is_declaration_loaded());
return raw_ptr()->interfaces_;
}
void set_interfaces(const Array& value) const;
// Returns the list of classes directly implementing this class.
- RawGrowableObjectArray* direct_implementors() const {
+ GrowableObjectArrayPtr direct_implementors() const {
return raw_ptr()->direct_implementors_;
}
void AddDirectImplementor(const Class& subclass, bool is_mixin) const;
void ClearDirectImplementors() const;
// Returns the list of classes having this class as direct superclass.
- RawGrowableObjectArray* direct_subclasses() const {
+ GrowableObjectArrayPtr direct_subclasses() const {
return raw_ptr()->direct_subclasses_;
}
void AddDirectSubclass(const Class& subclass) const;
@@ -1223,7 +1217,7 @@
// Check if this class represents the 'Closure' class.
bool IsClosureClass() const { return id() == kClosureCid; }
- static bool IsClosureClass(RawClass* cls) {
+ static bool IsClosureClass(ClassPtr cls) {
NoSafepointScope no_safepoint;
return cls->ptr()->id_ == kClosureCid;
}
@@ -1231,9 +1225,9 @@
// Check if this class represents a typedef class.
bool IsTypedefClass() const { return signature_function() != Object::null(); }
- static bool IsInFullSnapshot(RawClass* cls) {
+ static bool IsInFullSnapshot(ClassPtr cls) {
NoSafepointScope no_safepoint;
- return RawLibrary::InFullSnapshotBit::decode(
+ return LibraryLayout::InFullSnapshotBit::decode(
cls->ptr()->library_->ptr()->flags_);
}
@@ -1251,10 +1245,10 @@
bool IsPrivate() const;
DART_WARN_UNUSED_RESULT
- RawError* VerifyEntryPoint() const;
+ ErrorPtr VerifyEntryPoint() const;
// Returns an array of instance and static fields defined by this class.
- RawArray* fields() const { return raw_ptr()->fields_; }
+ ArrayPtr fields() const { return raw_ptr()->fields_; }
void SetFields(const Array& value) const;
void AddField(const Field& field) const;
void AddFields(const GrowableArray<const Field*>& fields) const;
@@ -1269,49 +1263,49 @@
// |original_classes| only has an effect when reloading. If true and we
// are reloading, it will prefer the original classes to the replacement
// classes.
- RawArray* OffsetToFieldMap(bool original_classes = false) const;
+ ArrayPtr OffsetToFieldMap(bool original_classes = false) const;
// Returns true if non-static fields are defined.
bool HasInstanceFields() const;
// TODO(koda): Unite w/ hash table.
- RawArray* functions() const { return raw_ptr()->functions_; }
+ ArrayPtr functions() const { return raw_ptr()->functions_; }
void SetFunctions(const Array& value) const;
void AddFunction(const Function& function) const;
void RemoveFunction(const Function& function) const;
- RawFunction* FunctionFromIndex(intptr_t idx) const;
+ FunctionPtr FunctionFromIndex(intptr_t idx) const;
intptr_t FindImplicitClosureFunctionIndex(const Function& needle) const;
- RawFunction* ImplicitClosureFunctionFromIndex(intptr_t idx) const;
+ FunctionPtr ImplicitClosureFunctionFromIndex(intptr_t idx) const;
- RawFunction* LookupDynamicFunction(const String& name) const;
- RawFunction* LookupDynamicFunctionAllowAbstract(const String& name) const;
- RawFunction* LookupDynamicFunctionAllowPrivate(const String& name) const;
- RawFunction* LookupStaticFunction(const String& name) const;
- RawFunction* LookupStaticFunctionAllowPrivate(const String& name) const;
- RawFunction* LookupConstructor(const String& name) const;
- RawFunction* LookupConstructorAllowPrivate(const String& name) const;
- RawFunction* LookupFactory(const String& name) const;
- RawFunction* LookupFactoryAllowPrivate(const String& name) const;
- RawFunction* LookupFunction(const String& name) const;
- RawFunction* LookupFunctionAllowPrivate(const String& name) const;
- RawFunction* LookupGetterFunction(const String& name) const;
- RawFunction* LookupSetterFunction(const String& name) const;
- RawField* LookupInstanceField(const String& name) const;
- RawField* LookupStaticField(const String& name) const;
- RawField* LookupField(const String& name) const;
- RawField* LookupFieldAllowPrivate(const String& name,
- bool instance_only = false) const;
- RawField* LookupInstanceFieldAllowPrivate(const String& name) const;
- RawField* LookupStaticFieldAllowPrivate(const String& name) const;
+ FunctionPtr LookupDynamicFunction(const String& name) const;
+ FunctionPtr LookupDynamicFunctionAllowAbstract(const String& name) const;
+ FunctionPtr LookupDynamicFunctionAllowPrivate(const String& name) const;
+ FunctionPtr LookupStaticFunction(const String& name) const;
+ FunctionPtr LookupStaticFunctionAllowPrivate(const String& name) const;
+ FunctionPtr LookupConstructor(const String& name) const;
+ FunctionPtr LookupConstructorAllowPrivate(const String& name) const;
+ FunctionPtr LookupFactory(const String& name) const;
+ FunctionPtr LookupFactoryAllowPrivate(const String& name) const;
+ FunctionPtr LookupFunction(const String& name) const;
+ FunctionPtr LookupFunctionAllowPrivate(const String& name) const;
+ FunctionPtr LookupGetterFunction(const String& name) const;
+ FunctionPtr LookupSetterFunction(const String& name) const;
+ FieldPtr LookupInstanceField(const String& name) const;
+ FieldPtr LookupStaticField(const String& name) const;
+ FieldPtr LookupField(const String& name) const;
+ FieldPtr LookupFieldAllowPrivate(const String& name,
+ bool instance_only = false) const;
+ FieldPtr LookupInstanceFieldAllowPrivate(const String& name) const;
+ FieldPtr LookupStaticFieldAllowPrivate(const String& name) const;
- RawDouble* LookupCanonicalDouble(Zone* zone, double value) const;
- RawMint* LookupCanonicalMint(Zone* zone, int64_t value) const;
+ DoublePtr LookupCanonicalDouble(Zone* zone, double value) const;
+ MintPtr LookupCanonicalMint(Zone* zone, int64_t value) const;
// The methods above are more efficient than this generic one.
- RawInstance* LookupCanonicalInstance(Zone* zone, const Instance& value) const;
+ InstancePtr LookupCanonicalInstance(Zone* zone, const Instance& value) const;
- RawInstance* InsertCanonicalConstant(Zone* zone,
- const Instance& constant) const;
+ InstancePtr InsertCanonicalConstant(Zone* zone,
+ const Instance& constant) const;
void InsertCanonicalDouble(Zone* zone, const Double& constant) const;
void InsertCanonicalMint(Zone* zone, const Mint& constant) const;
@@ -1320,7 +1314,7 @@
bool RequireLegacyErasureOfConstants(Zone* zone) const;
static intptr_t InstanceSize() {
- return RoundedAllocationSize(sizeof(RawClass));
+ return RoundedAllocationSize(sizeof(ClassLayout));
}
bool is_implemented() const {
@@ -1333,17 +1327,17 @@
}
void set_is_abstract() const;
- RawClass::ClassLoadingState class_loading_state() const {
+ ClassLayout::ClassLoadingState class_loading_state() const {
return ClassLoadingBits::decode(raw_ptr()->state_bits_);
}
bool is_declaration_loaded() const {
- return class_loading_state() >= RawClass::kDeclarationLoaded;
+ return class_loading_state() >= ClassLayout::kDeclarationLoaded;
}
void set_is_declaration_loaded() const;
bool is_type_finalized() const {
- return class_loading_state() >= RawClass::kTypeFinalized;
+ return class_loading_state() >= ClassLayout::kTypeFinalized;
}
void set_is_type_finalized() const;
@@ -1360,13 +1354,13 @@
bool is_finalized() const {
return ClassFinalizedBits::decode(raw_ptr()->state_bits_) ==
- RawClass::kFinalized;
+ ClassLayout::kFinalized;
}
void set_is_finalized() const;
bool is_prefinalized() const {
return ClassFinalizedBits::decode(raw_ptr()->state_bits_) ==
- RawClass::kPreFinalized;
+ ClassLayout::kPreFinalized;
}
void set_is_prefinalized() const;
@@ -1403,18 +1397,18 @@
StoreNonPointer(&raw_ptr()->num_native_fields_, value);
}
- RawCode* allocation_stub() const { return raw_ptr()->allocation_stub_; }
+ CodePtr allocation_stub() const { return raw_ptr()->allocation_stub_; }
void set_allocation_stub(const Code& value) const;
#if !defined(DART_PRECOMPILED_RUNTIME)
intptr_t binary_declaration_offset() const {
- return RawClass::BinaryDeclarationOffset::decode(
+ return ClassLayout::BinaryDeclarationOffset::decode(
raw_ptr()->binary_declaration_);
}
void set_binary_declaration_offset(intptr_t value) const {
ASSERT(value >= 0);
StoreNonPointer(&raw_ptr()->binary_declaration_,
- RawClass::BinaryDeclarationOffset::update(
+ ClassLayout::BinaryDeclarationOffset::update(
value, raw_ptr()->binary_declaration_));
}
#endif // !defined(DART_PRECOMPILED_RUNTIME)
@@ -1459,7 +1453,7 @@
#if defined(DART_PRECOMPILED_RUNTIME)
return false;
#else
- return RawClass::IsDeclaredInBytecode::decode(
+ return ClassLayout::IsDeclaredInBytecode::decode(
raw_ptr()->binary_declaration_);
#endif
}
@@ -1467,46 +1461,46 @@
#if !defined(DART_PRECOMPILED_RUNTIME)
void set_is_declared_in_bytecode(bool value) const {
StoreNonPointer(&raw_ptr()->binary_declaration_,
- RawClass::IsDeclaredInBytecode::update(
+ ClassLayout::IsDeclaredInBytecode::update(
value, raw_ptr()->binary_declaration_));
}
#endif // !defined(DART_PRECOMPILED_RUNTIME)
void DisableAllocationStub() const;
- RawArray* constants() const;
+ ArrayPtr constants() const;
void set_constants(const Array& value) const;
intptr_t FindInvocationDispatcherFunctionIndex(const Function& needle) const;
- RawFunction* InvocationDispatcherFunctionFromIndex(intptr_t idx) const;
+ FunctionPtr InvocationDispatcherFunctionFromIndex(intptr_t idx) const;
- RawFunction* GetInvocationDispatcher(const String& target_name,
- const Array& args_desc,
- RawFunction::Kind kind,
- bool create_if_absent) const;
+ FunctionPtr GetInvocationDispatcher(const String& target_name,
+ const Array& args_desc,
+ FunctionLayout::Kind kind,
+ bool create_if_absent) const;
void Finalize() const;
- RawObject* Invoke(const String& selector,
- const Array& arguments,
- const Array& argument_names,
- bool respect_reflectable = true,
- bool check_is_entrypoint = false) const;
- RawObject* InvokeGetter(const String& selector,
- bool throw_nsm_if_absent,
- bool respect_reflectable = true,
- bool check_is_entrypoint = false) const;
- RawObject* InvokeSetter(const String& selector,
- const Instance& argument,
- bool respect_reflectable = true,
- bool check_is_entrypoint = false) const;
+ ObjectPtr Invoke(const String& selector,
+ const Array& arguments,
+ const Array& argument_names,
+ bool respect_reflectable = true,
+ bool check_is_entrypoint = false) const;
+ ObjectPtr InvokeGetter(const String& selector,
+ bool throw_nsm_if_absent,
+ bool respect_reflectable = true,
+ bool check_is_entrypoint = false) const;
+ ObjectPtr InvokeSetter(const String& selector,
+ const Instance& argument,
+ bool respect_reflectable = true,
+ bool check_is_entrypoint = false) const;
// Evaluate the given expression as if it appeared in a static method of this
// class and return the resulting value, or an error object if evaluating the
// expression fails. The method has the formal (type) parameters given in
// (type_)param_names, and is invoked with the (type)argument values given in
// (type_)param_values.
- RawObject* EvaluateCompiledExpression(
+ ObjectPtr EvaluateCompiledExpression(
const ExternalTypedData& kernel_buffer,
const Array& type_definitions,
const Array& param_values,
@@ -1516,37 +1510,37 @@
// number of type arguments) if it is not loaded yet.
void EnsureDeclarationLoaded() const;
- RawError* EnsureIsFinalized(Thread* thread) const;
+ ErrorPtr EnsureIsFinalized(Thread* thread) const;
// Allocate a class used for VM internal objects.
template <class FakeObject, class TargetFakeObject>
- static RawClass* New(Isolate* isolate, bool register_class = true);
+ static ClassPtr New(Isolate* isolate, bool register_class = true);
// Allocate instance classes.
- static RawClass* New(const Library& lib,
- const String& name,
- const Script& script,
- TokenPosition token_pos,
- bool register_class = true);
- static RawClass* NewNativeWrapper(const Library& library,
- const String& name,
- int num_fields);
+ static ClassPtr New(const Library& lib,
+ const String& name,
+ const Script& script,
+ TokenPosition token_pos,
+ bool register_class = true);
+ static ClassPtr NewNativeWrapper(const Library& library,
+ const String& name,
+ int num_fields);
// Allocate the raw string classes.
- static RawClass* NewStringClass(intptr_t class_id, Isolate* isolate);
+ static ClassPtr NewStringClass(intptr_t class_id, Isolate* isolate);
// Allocate the raw TypedData classes.
- static RawClass* NewTypedDataClass(intptr_t class_id, Isolate* isolate);
+ static ClassPtr NewTypedDataClass(intptr_t class_id, Isolate* isolate);
// Allocate the raw TypedDataView/ByteDataView classes.
- static RawClass* NewTypedDataViewClass(intptr_t class_id, Isolate* isolate);
+ static ClassPtr NewTypedDataViewClass(intptr_t class_id, Isolate* isolate);
// Allocate the raw ExternalTypedData classes.
- static RawClass* NewExternalTypedDataClass(intptr_t class_id,
- Isolate* isolate);
+ static ClassPtr NewExternalTypedDataClass(intptr_t class_id,
+ Isolate* isolate);
// Allocate the raw Pointer classes.
- static RawClass* NewPointerClass(intptr_t class_id, Isolate* isolate);
+ static ClassPtr NewPointerClass(intptr_t class_id, Isolate* isolate);
// Register code that has used CHA for optimization.
// TODO(srdjan): Also register kind of CHA optimization (e.g.: leaf class,
@@ -1562,7 +1556,7 @@
// Return the list of code objects that were compiled using CHA of this class.
// These code objects will be invalidated if new subclasses of this class
// are finalized.
- RawArray* dependent_code() const { return raw_ptr()->dependent_code_; }
+ ArrayPtr dependent_code() const { return raw_ptr()->dependent_code_; }
void set_dependent_code(const Array& array) const;
bool TraceAllocation(Isolate* isolate) const;
@@ -1584,11 +1578,11 @@
const Array& args_desc,
const Function& dispatcher) const;
- static int32_t host_instance_size_in_words(const RawClass* cls) {
+ static int32_t host_instance_size_in_words(const ClassPtr cls) {
return cls->ptr()->host_instance_size_in_words_;
}
- static int32_t target_instance_size_in_words(const RawClass* cls) {
+ static int32_t target_instance_size_in_words(const ClassPtr cls) {
#if !defined(DART_PRECOMPILED_RUNTIME)
return cls->ptr()->target_instance_size_in_words_;
#else
@@ -1596,11 +1590,11 @@
#endif // !defined(DART_PRECOMPILED_RUNTIME)
}
- static int32_t host_next_field_offset_in_words(const RawClass* cls) {
+ static int32_t host_next_field_offset_in_words(const ClassPtr cls) {
return cls->ptr()->host_next_field_offset_in_words_;
}
- static int32_t target_next_field_offset_in_words(const RawClass* cls) {
+ static int32_t target_next_field_offset_in_words(const ClassPtr cls) {
#if !defined(DART_PRECOMPILED_RUNTIME)
return cls->ptr()->target_next_field_offset_in_words_;
#else
@@ -1608,13 +1602,12 @@
#endif // !defined(DART_PRECOMPILED_RUNTIME)
}
- static int32_t host_type_arguments_field_offset_in_words(
- const RawClass* cls) {
+ static int32_t host_type_arguments_field_offset_in_words(const ClassPtr cls) {
return cls->ptr()->host_type_arguments_field_offset_in_words_;
}
static int32_t target_type_arguments_field_offset_in_words(
- const RawClass* cls) {
+ const ClassPtr cls) {
#if !defined(DART_PRECOMPILED_RUNTIME)
return cls->ptr()->target_type_arguments_field_offset_in_words_;
#else
@@ -1623,7 +1616,7 @@
}
private:
- RawType* declaration_type() const { return raw_ptr()->declaration_type_; }
+ TypePtr declaration_type() const { return raw_ptr()->declaration_type_; }
// Caches the declaration type of this class.
void set_declaration_type(const Type& type) const;
@@ -1637,7 +1630,7 @@
bool RequiresInstanceMorphing(const Class& replacement) const;
template <class FakeInstance, class TargetFakeInstance>
- static RawClass* NewCommon(intptr_t index);
+ static ClassPtr NewCommon(intptr_t index);
enum MemberKind {
kAny = 0,
@@ -1669,11 +1662,11 @@
class ConstBit : public BitField<uint32_t, bool, kConstBit, 1> {};
class ImplementedBit : public BitField<uint32_t, bool, kImplementedBit, 1> {};
class ClassFinalizedBits : public BitField<uint32_t,
- RawClass::ClassFinalizedState,
+ ClassLayout::ClassFinalizedState,
kClassFinalizedPos,
kClassFinalizedSize> {};
class ClassLoadingBits : public BitField<uint32_t,
- RawClass::ClassLoadingState,
+ ClassLayout::ClassLoadingState,
kClassLoadingPos,
kClassLoadingSize> {};
class AbstractBit : public BitField<uint32_t, bool, kAbstractBit, 1> {};
@@ -1694,11 +1687,11 @@
const char* GenerateUserVisibleName() const;
void set_state_bits(intptr_t bits) const;
- RawArray* invocation_dispatcher_cache() const;
+ ArrayPtr invocation_dispatcher_cache() const;
void set_invocation_dispatcher_cache(const Array& cache) const;
- RawFunction* CreateInvocationDispatcher(const String& target_name,
- const Array& args_desc,
- RawFunction::Kind kind) const;
+ FunctionPtr CreateInvocationDispatcher(const String& target_name,
+ const Array& args_desc,
+ FunctionLayout::Kind kind) const;
// Returns the bitmap of unboxed fields
UnboxedFieldBitmap CalculateFieldOffsets() const;
@@ -1728,25 +1721,25 @@
// Assigns empty array to all raw class array fields.
void InitEmptyFields();
- static RawFunction* CheckFunctionType(const Function& func, MemberKind kind);
- RawFunction* LookupFunction(const String& name, MemberKind kind) const;
- RawFunction* LookupFunctionAllowPrivate(const String& name,
- MemberKind kind) const;
- RawField* LookupField(const String& name, MemberKind kind) const;
+ static FunctionPtr CheckFunctionType(const Function& func, MemberKind kind);
+ FunctionPtr LookupFunction(const String& name, MemberKind kind) const;
+ FunctionPtr LookupFunctionAllowPrivate(const String& name,
+ MemberKind kind) const;
+ FieldPtr LookupField(const String& name, MemberKind kind) const;
- RawFunction* LookupAccessorFunction(const char* prefix,
- intptr_t prefix_length,
- const String& name) const;
+ FunctionPtr LookupAccessorFunction(const char* prefix,
+ intptr_t prefix_length,
+ const String& name) const;
// Allocate an instance class which has a VM implementation.
template <class FakeInstance, class TargetFakeInstance>
- static RawClass* New(intptr_t id,
- Isolate* isolate,
- bool register_class = true,
- bool is_abstract = false);
+ static ClassPtr New(intptr_t id,
+ Isolate* isolate,
+ bool register_class = true,
+ bool is_abstract = false);
// Helper that calls 'Class::New<Instance>(kIllegalCid)'.
- static RawClass* NewInstanceClass();
+ static ClassPtr NewInstanceClass();
FINAL_HEAP_OBJECT_IMPLEMENTATION(Class, Object);
friend class AbstractType;
@@ -1767,10 +1760,10 @@
class PatchClass : public Object {
public:
- RawClass* patched_class() const { return raw_ptr()->patched_class_; }
- RawClass* origin_class() const { return raw_ptr()->origin_class_; }
- RawScript* script() const { return raw_ptr()->script_; }
- RawExternalTypedData* library_kernel_data() const {
+ ClassPtr patched_class() const { return raw_ptr()->patched_class_; }
+ ClassPtr origin_class() const { return raw_ptr()->origin_class_; }
+ ScriptPtr script() const { return raw_ptr()->script_; }
+ ExternalTypedDataPtr library_kernel_data() const {
return raw_ptr()->library_kernel_data_;
}
void set_library_kernel_data(const ExternalTypedData& data) const;
@@ -1788,24 +1781,24 @@
}
static intptr_t InstanceSize() {
- return RoundedAllocationSize(sizeof(RawPatchClass));
+ return RoundedAllocationSize(sizeof(PatchClassLayout));
}
- static bool IsInFullSnapshot(RawPatchClass* cls) {
+ static bool IsInFullSnapshot(PatchClassPtr cls) {
NoSafepointScope no_safepoint;
return Class::IsInFullSnapshot(cls->ptr()->patched_class_);
}
- static RawPatchClass* New(const Class& patched_class,
- const Class& origin_class);
+ static PatchClassPtr New(const Class& patched_class,
+ const Class& origin_class);
- static RawPatchClass* New(const Class& patched_class, const Script& source);
+ static PatchClassPtr New(const Class& patched_class, const Script& source);
private:
void set_patched_class(const Class& value) const;
void set_origin_class(const Class& value) const;
void set_script(const Script& value) const;
- static RawPatchClass* New();
+ static PatchClassPtr New();
FINAL_HEAP_OBJECT_IMPLEMENTATION(PatchClass, Object);
friend class Class;
@@ -1821,25 +1814,25 @@
// The type parameter to whose bound needs to be checked, or null if this is
// an ordinary parameter check.
- RawAbstractType* param() const { return raw_ptr()->param_; }
+ AbstractTypePtr param() const { return raw_ptr()->param_; }
void set_param(const AbstractType& t) const;
// FP[index] assignable to type, OR param is subtype of bound.
- RawAbstractType* type_or_bound() const { return raw_ptr()->type_or_bound_; }
+ AbstractTypePtr type_or_bound() const { return raw_ptr()->type_or_bound_; }
void set_type_or_bound(const AbstractType& t) const;
// The parameter or type parameter's name to use in an error message.
- RawString* name() const { return raw_ptr()->name_; }
+ StringPtr name() const { return raw_ptr()->name_; }
void set_name(const String& n) const;
- RawSubtypeTestCache* cache() const { return raw_ptr()->cache_; }
+ SubtypeTestCachePtr cache() const { return raw_ptr()->cache_; }
void set_cache(const SubtypeTestCache& c) const;
static intptr_t InstanceSize() {
- return RoundedAllocationSize(sizeof(RawParameterTypeCheck));
+ return RoundedAllocationSize(sizeof(ParameterTypeCheckLayout));
}
- static RawParameterTypeCheck* New();
+ static ParameterTypeCheckPtr New();
private:
FINAL_HEAP_OBJECT_IMPLEMENTATION(ParameterTypeCheck, Object);
@@ -1848,10 +1841,10 @@
class SingleTargetCache : public Object {
public:
- RawCode* target() const { return raw_ptr()->target_; }
+ CodePtr target() const { return raw_ptr()->target_; }
void set_target(const Code& target) const;
static intptr_t target_offset() {
- return OFFSET_OF(RawSingleTargetCache, target_);
+ return OFFSET_OF(SingleTargetCacheLayout, target_);
}
#define DEFINE_NON_POINTER_FIELD_ACCESSORS(type, name) \
@@ -1860,7 +1853,7 @@
StoreNonPointer(&raw_ptr()->name##_, value); \
} \
static intptr_t name##_offset() { \
- return OFFSET_OF(RawSingleTargetCache, name##_); \
+ return OFFSET_OF(SingleTargetCacheLayout, name##_); \
}
DEFINE_NON_POINTER_FIELD_ACCESSORS(uword, entry_point);
@@ -1869,10 +1862,10 @@
#undef DEFINE_NON_POINTER_FIELD_ACCESSORS
static intptr_t InstanceSize() {
- return RoundedAllocationSize(sizeof(RawSingleTargetCache));
+ return RoundedAllocationSize(sizeof(SingleTargetCacheLayout));
}
- static RawSingleTargetCache* New();
+ static SingleTargetCachePtr New();
private:
FINAL_HEAP_OBJECT_IMPLEMENTATION(SingleTargetCache, Object);
@@ -1881,26 +1874,26 @@
class MonomorphicSmiableCall : public Object {
public:
- RawCode* target() const { return raw_ptr()->target_; }
+ CodePtr target() const { return raw_ptr()->target_; }
classid_t expected_cid() const { return raw_ptr()->expected_cid_; }
static intptr_t InstanceSize() {
- return RoundedAllocationSize(sizeof(RawMonomorphicSmiableCall));
+ return RoundedAllocationSize(sizeof(MonomorphicSmiableCallLayout));
}
- static RawMonomorphicSmiableCall* New(classid_t expected_cid,
- const Code& target);
+ static MonomorphicSmiableCallPtr New(classid_t expected_cid,
+ const Code& target);
static intptr_t expected_cid_offset() {
- return OFFSET_OF(RawMonomorphicSmiableCall, expected_cid_);
+ return OFFSET_OF(MonomorphicSmiableCallLayout, expected_cid_);
}
static intptr_t target_offset() {
- return OFFSET_OF(RawMonomorphicSmiableCall, target_);
+ return OFFSET_OF(MonomorphicSmiableCallLayout, target_);
}
static intptr_t entrypoint_offset() {
- return OFFSET_OF(RawMonomorphicSmiableCall, entrypoint_);
+ return OFFSET_OF(MonomorphicSmiableCallLayout, entrypoint_);
}
private:
@@ -1910,9 +1903,9 @@
class UnlinkedCall : public Object {
public:
- RawString* target_name() const { return raw_ptr()->target_name_; }
+ StringPtr target_name() const { return raw_ptr()->target_name_; }
void set_target_name(const String& target_name) const;
- RawArray* args_descriptor() const { return raw_ptr()->args_descriptor_; }
+ ArrayPtr args_descriptor() const { return raw_ptr()->args_descriptor_; }
void set_args_descriptor(const Array& args_descriptor) const;
bool can_patch_to_monomorphic() const {
@@ -1921,13 +1914,13 @@
void set_can_patch_to_monomorphic(bool value) const;
static intptr_t InstanceSize() {
- return RoundedAllocationSize(sizeof(RawUnlinkedCall));
+ return RoundedAllocationSize(sizeof(UnlinkedCallLayout));
}
intptr_t Hashcode() const;
bool Equals(const UnlinkedCall& other) const;
- static RawUnlinkedCall* New();
+ static UnlinkedCallPtr New();
private:
FINAL_HEAP_OBJECT_IMPLEMENTATION(UnlinkedCall, Object);
@@ -1936,16 +1929,16 @@
class CallSiteData : public Object {
public:
- RawString* target_name() const { return raw_ptr()->target_name_; }
+ StringPtr target_name() const { return raw_ptr()->target_name_; }
- RawArray* arguments_descriptor() const { return raw_ptr()->args_descriptor_; }
+ ArrayPtr arguments_descriptor() const { return raw_ptr()->args_descriptor_; }
static intptr_t target_name_offset() {
- return OFFSET_OF(RawCallSiteData, target_name_);
+ return OFFSET_OF(CallSiteDataLayout, target_name_);
}
static intptr_t arguments_descriptor_offset() {
- return OFFSET_OF(RawCallSiteData, args_descriptor_);
+ return OFFSET_OF(CallSiteDataLayout, args_descriptor_);
}
private:
@@ -1966,9 +1959,9 @@
// compilation. Code may contain only original ICData objects.
class ICData : public CallSiteData {
public:
- RawFunction* Owner() const;
+ FunctionPtr Owner() const;
- RawICData* Original() const;
+ ICDataPtr Original() const;
void SetOriginal(const ICData& value) const;
@@ -1998,7 +1991,7 @@
bool IsImmutable() const;
#if !defined(DART_PRECOMPILED_RUNTIME)
- RawAbstractType* receivers_static_type() const {
+ AbstractTypePtr receivers_static_type() const {
return raw_ptr()->receivers_static_type_;
}
void SetReceiversStaticType(const AbstractType& type) const;
@@ -2108,11 +2101,11 @@
bool NumberOfChecksIs(intptr_t n) const;
static intptr_t InstanceSize() {
- return RoundedAllocationSize(sizeof(RawICData));
+ return RoundedAllocationSize(sizeof(ICDataLayout));
}
static intptr_t state_bits_offset() {
- return OFFSET_OF(RawICData, state_bits_);
+ return OFFSET_OF(ICDataLayout, state_bits_);
}
static intptr_t NumArgsTestedShift() { return kNumArgsTestedPos; }
@@ -2121,13 +2114,13 @@
return ((1 << kNumArgsTestedSize) - 1) << kNumArgsTestedPos;
}
- static intptr_t entries_offset() { return OFFSET_OF(RawICData, entries_); }
+ static intptr_t entries_offset() { return OFFSET_OF(ICDataLayout, entries_); }
- static intptr_t owner_offset() { return OFFSET_OF(RawICData, owner_); }
+ static intptr_t owner_offset() { return OFFSET_OF(ICDataLayout, owner_); }
#if !defined(DART_PRECOMPILED_RUNTIME)
static intptr_t receivers_static_type_offset() {
- return OFFSET_OF(RawICData, receivers_static_type_);
+ return OFFSET_OF(ICDataLayout, receivers_static_type_);
}
#endif
@@ -2187,9 +2180,9 @@
intptr_t GetReceiverClassIdAt(intptr_t index) const;
intptr_t GetClassIdAt(intptr_t index, intptr_t arg_nr) const;
- RawFunction* GetTargetAt(intptr_t index) const;
+ FunctionPtr GetTargetAt(intptr_t index) const;
- RawObject* GetTargetOrCodeAt(intptr_t index) const;
+ ObjectPtr GetTargetOrCodeAt(intptr_t index) const;
void SetCodeAt(intptr_t index, const Code& value) const;
void SetEntryPointAt(intptr_t index, const Smi& value) const;
@@ -2201,20 +2194,18 @@
// Returns this->raw() if num_args_tested == 1 and arg_nr == 1, otherwise
// returns a new ICData object containing only unique arg_nr checks.
// Returns only used entries.
- RawICData* AsUnaryClassChecksForArgNr(intptr_t arg_nr) const;
- RawICData* AsUnaryClassChecks() const {
- return AsUnaryClassChecksForArgNr(0);
- }
- RawICData* AsUnaryClassChecksForCid(intptr_t cid,
- const Function& target) const;
+ ICDataPtr AsUnaryClassChecksForArgNr(intptr_t arg_nr) const;
+ ICDataPtr AsUnaryClassChecks() const { return AsUnaryClassChecksForArgNr(0); }
+ ICDataPtr AsUnaryClassChecksForCid(intptr_t cid,
+ const Function& target) const;
// Returns ICData with aggregated receiver count, sorted by highest count.
// Smi not first!! (the convention for ICData used in code generation is that
// Smi check is first)
// Used for printing and optimizations.
- RawICData* AsUnaryClassChecksSortedByCount() const;
+ ICDataPtr AsUnaryClassChecksSortedByCount() const;
- RawUnlinkedCall* AsUnlinkedCall() const;
+ UnlinkedCallPtr AsUnlinkedCall() const;
bool HasReceiverClassId(intptr_t class_id) const;
@@ -2222,7 +2213,7 @@
// the receiver type. Receiver type is expected to be a fully
// instantiated generic (but not a FutureOr).
// See StaticTypeExactnessState for more information.
- static RawICData* New(
+ static ICDataPtr New(
const Function& owner,
const String& target_name,
const Array& arguments_descriptor,
@@ -2230,10 +2221,10 @@
intptr_t num_args_tested,
RebindRule rebind_rule,
const AbstractType& receiver_type = Object::null_abstract_type());
- static RawICData* NewFrom(const ICData& from, intptr_t num_args_tested);
+ static ICDataPtr NewFrom(const ICData& from, intptr_t num_args_tested);
// Generates a new ICData with descriptor and data array copied (deep clone).
- static RawICData* Clone(const ICData& from);
+ static ICDataPtr Clone(const ICData& from);
static intptr_t TestEntryLengthFor(intptr_t num_args,
bool tracking_exactness);
@@ -2272,8 +2263,8 @@
intptr_t FindCheck(const GrowableArray<intptr_t>& cids) const;
- RawArray* entries() const {
- return LoadPointer<RawArray*, std::memory_order_acquire>(
+ ArrayPtr entries() const {
+ return LoadPointer<ArrayPtr, std::memory_order_acquire>(
&raw_ptr()->entries_);
}
@@ -2290,11 +2281,11 @@
private:
friend class FlowGraphSerializer; // For is_megamorphic()
- static RawICData* New();
+ static ICDataPtr New();
// Grows the array and also sets the argument to the index that should be used
// for the new entry.
- RawArray* Grow(intptr_t* index) const;
+ ArrayPtr Grow(intptr_t* index) const;
void set_owner(const Function& value) const;
void set_deopt_id(intptr_t value) const;
@@ -2334,7 +2325,7 @@
};
COMPILE_ASSERT(kReceiverCannotBeSmiPos + kReceiverCannotBeSmiSize <=
- sizeof(RawICData::state_bits_) * kBitsPerWord);
+ sizeof(ICDataLayout::state_bits_) * kBitsPerWord);
COMPILE_ASSERT(kNumRebindRules <= (1 << kRebindRuleSize));
class NumArgsTestedBits : public BitField<uint32_t,
@@ -2367,23 +2358,23 @@
#endif // DEBUG
intptr_t TestEntryLength() const;
- static RawArray* NewNonCachedEmptyICDataArray(intptr_t num_args_tested,
- bool tracking_exactness);
- static RawArray* CachedEmptyICDataArray(intptr_t num_args_tested,
- bool tracking_exactness);
- static RawICData* NewDescriptor(Zone* zone,
- const Function& owner,
- const String& target_name,
- const Array& arguments_descriptor,
- intptr_t deopt_id,
- intptr_t num_args_tested,
- RebindRule rebind_rule,
- const AbstractType& receiver_type);
+ static ArrayPtr NewNonCachedEmptyICDataArray(intptr_t num_args_tested,
+ bool tracking_exactness);
+ static ArrayPtr CachedEmptyICDataArray(intptr_t num_args_tested,
+ bool tracking_exactness);
+ static ICDataPtr NewDescriptor(Zone* zone,
+ const Function& owner,
+ const String& target_name,
+ const Array& arguments_descriptor,
+ intptr_t deopt_id,
+ intptr_t num_args_tested,
+ RebindRule rebind_rule,
+ const AbstractType& receiver_type);
static void WriteSentinel(const Array& data, intptr_t test_entry_length);
// A cache of VM heap allocated preinitialized empty ic data entry arrays.
- static RawArray* cached_icdata_arrays_[kCachedICDataArrayCount];
+ static ArrayPtr cached_icdata_arrays_[kCachedICDataArrayCount];
FINAL_HEAP_OBJECT_IMPLEMENTATION(ICData, CallSiteData);
friend class CallSiteResetter;
@@ -2417,18 +2408,18 @@
class Function : public Object {
public:
- RawString* name() const { return raw_ptr()->name_; }
- RawString* UserVisibleName() const; // Same as scrubbed name.
+ StringPtr name() const { return raw_ptr()->name_; }
+ StringPtr UserVisibleName() const; // Same as scrubbed name.
const char* UserVisibleNameCString() const;
void PrintQualifiedName(NameVisibility name_visibility,
ZoneTextBuffer* printer) const;
- RawString* QualifiedScrubbedName() const;
- RawString* QualifiedUserVisibleName() const;
+ StringPtr QualifiedScrubbedName() const;
+ StringPtr QualifiedUserVisibleName() const;
- virtual RawString* DictionaryName() const { return name(); }
+ virtual StringPtr DictionaryName() const { return name(); }
- RawString* GetSource() const;
+ StringPtr GetSource() const;
// Return the type of this function's signature. It may not be canonical yet.
// For example, if this function has a signature of the form
@@ -2437,9 +2428,9 @@
// function type with uninstantiated type arguments 'T' and 'R' as elements of
// its type argument vector.
// A function type is non-nullable by default.
- RawType* SignatureType(
+ TypePtr SignatureType(
Nullability nullability = Nullability::kNonNullable) const;
- RawType* ExistingSignatureType() const;
+ TypePtr ExistingSignatureType() const;
// Update the signature type (with a canonical version).
void SetSignatureType(const Type& value) const;
@@ -2450,7 +2441,7 @@
// Retrieves the "C signature" function for an FFI trampoline.
// Can only be used on FFI trampolines.
- RawFunction* FfiCSignature() const;
+ FunctionPtr FfiCSignature() const;
// Can only be called on FFI trampolines.
// -1 for Dart -> native calls.
@@ -2461,20 +2452,20 @@
// Can only be called on FFI trampolines.
// Null for Dart -> native calls.
- RawFunction* FfiCallbackTarget() const;
+ FunctionPtr FfiCallbackTarget() const;
// Can only be called on FFI trampolines.
void SetFfiCallbackTarget(const Function& target) const;
// Can only be called on FFI trampolines.
// Null for Dart -> native calls.
- RawInstance* FfiCallbackExceptionalReturn() const;
+ InstancePtr FfiCallbackExceptionalReturn() const;
// Can only be called on FFI trampolines.
void SetFfiCallbackExceptionalReturn(const Instance& value) const;
// Return a new function with instantiated result and parameter types.
- RawFunction* InstantiateSignatureFrom(
+ FunctionPtr InstantiateSignatureFrom(
const TypeArguments& instantiator_type_arguments,
const TypeArguments& function_type_arguments,
intptr_t num_free_fun_type_params,
@@ -2484,14 +2475,14 @@
// internal signature of the given function. In this example, T is a type
// parameter of this function and R is a type parameter of class C, the owner
// of the function. B and C are not type parameters.
- RawString* Signature() const;
+ StringPtr Signature() const;
// Build a string of the form '<T>(T, {B b, C c}) => R' representing the
// user visible signature of the given function. In this example, T is a type
// parameter of this function and R is a type parameter of class C, the owner
// of the function. B and C are not type parameters.
// Implicit parameters are hidden.
- RawString* UserVisibleSignature() const;
+ StringPtr UserVisibleSignature() const;
void PrintSignature(NameVisibility name_visibility,
ZoneTextBuffer* printer) const;
@@ -2505,36 +2496,36 @@
intptr_t num_free_fun_type_params = kAllFree,
TrailPtr trail = NULL) const;
- RawClass* Owner() const;
+ ClassPtr Owner() const;
void set_owner(const Object& value) const;
- RawClass* origin() const;
- RawScript* script() const;
- RawObject* RawOwner() const { return raw_ptr()->owner_; }
+ ClassPtr origin() const;
+ ScriptPtr script() const;
+ ObjectPtr RawOwner() const { return raw_ptr()->owner_; }
// The NNBD mode of the library declaring this function.
// TODO(alexmarkov): nnbd_mode() doesn't work for mixins.
// It should be either removed or fixed.
NNBDMode nnbd_mode() const { return Class::Handle(origin()).nnbd_mode(); }
- RawRegExp* regexp() const;
+ RegExpPtr regexp() const;
intptr_t string_specialization_cid() const;
bool is_sticky_specialization() const;
void SetRegExpData(const RegExp& regexp,
intptr_t string_specialization_cid,
bool sticky) const;
- RawString* native_name() const;
+ StringPtr native_name() const;
void set_native_name(const String& name) const;
- RawAbstractType* result_type() const { return raw_ptr()->result_type_; }
+ AbstractTypePtr result_type() const { return raw_ptr()->result_type_; }
void set_result_type(const AbstractType& value) const;
// The parameters, starting with NumImplicitParameters() parameters which are
// only visible to the VM, but not to Dart users.
// Note that type checks exclude implicit parameters.
- RawAbstractType* ParameterTypeAt(intptr_t index) const;
+ AbstractTypePtr ParameterTypeAt(intptr_t index) const;
void SetParameterTypeAt(intptr_t index, const AbstractType& value) const;
- RawArray* parameter_types() const { return raw_ptr()->parameter_types_; }
+ ArrayPtr parameter_types() const { return raw_ptr()->parameter_types_; }
void set_parameter_types(const Array& value) const;
// Parameter names are valid for all valid parameter indices, and are not
@@ -2542,9 +2533,9 @@
// required) they're stored at the end of this array, so the size of this
// array isn't necessarily NumParameters(), but the first NumParameters()
// elements are the names.
- RawString* ParameterNameAt(intptr_t index) const;
+ StringPtr ParameterNameAt(intptr_t index) const;
void SetParameterNameAt(intptr_t index, const String& value) const;
- RawArray* parameter_names() const { return raw_ptr()->parameter_names_; }
+ ArrayPtr parameter_names() const { return raw_ptr()->parameter_names_; }
void set_parameter_names(const Array& value) const;
// The required flags are stored at the end of the parameter_names. The flags
@@ -2563,7 +2554,7 @@
// The type parameters (and their bounds) are specified as an array of
// TypeParameter.
- RawTypeArguments* type_parameters() const {
+ TypeArgumentsPtr type_parameters() const {
return raw_ptr()->type_parameters_;
}
void set_type_parameters(const TypeArguments& value) const;
@@ -2587,8 +2578,8 @@
// function or of one of its parent functions.
// Unless NULL, adjust function_level accordingly (in and out parameter).
// Return null otherwise.
- RawTypeParameter* LookupTypeParameter(const String& type_name,
- intptr_t* function_level) const;
+ TypeParameterPtr LookupTypeParameter(const String& type_name,
+ intptr_t* function_level) const;
// Return true if this function declares type parameters.
bool IsGeneric() const { return NumTypeParameters(Thread::Current()) > 0; }
@@ -2611,7 +2602,7 @@
// unoptimized version of the code. If the code contains errors, it calls
// Exceptions::PropagateError and does not return. Normally returns the
// current code, whether it is optimized or unoptimized.
- RawCode* EnsureHasCode() const;
+ CodePtr EnsureHasCode() const;
// Disables optimized code and switches to unoptimized code (or the lazy
// compilation stub).
@@ -2622,54 +2613,54 @@
// Return the most recently compiled and installed code for this function.
// It is not the only Code object that points to this function.
- RawCode* CurrentCode() const { return CurrentCodeOf(raw()); }
+ CodePtr CurrentCode() const { return CurrentCodeOf(raw()); }
bool SafeToClosurize() const;
- static RawCode* CurrentCodeOf(const RawFunction* function) {
+ static CodePtr CurrentCodeOf(const FunctionPtr function) {
return function->ptr()->code_;
}
- RawCode* unoptimized_code() const {
+ CodePtr unoptimized_code() const {
#if defined(DART_PRECOMPILED_RUNTIME)
- return static_cast<RawCode*>(Object::null());
+ return static_cast<CodePtr>(Object::null());
#else
return raw_ptr()->unoptimized_code_;
#endif
}
void set_unoptimized_code(const Code& value) const;
bool HasCode() const;
- static bool HasCode(RawFunction* function);
+ static bool HasCode(FunctionPtr function);
#if !defined(DART_PRECOMPILED_RUNTIME)
- static inline bool HasBytecode(RawFunction* function);
+ static inline bool HasBytecode(FunctionPtr function);
#endif
- static intptr_t code_offset() { return OFFSET_OF(RawFunction, code_); }
+ static intptr_t code_offset() { return OFFSET_OF(FunctionLayout, code_); }
static intptr_t result_type_offset() {
- return OFFSET_OF(RawFunction, result_type_);
+ return OFFSET_OF(FunctionLayout, result_type_);
}
static intptr_t entry_point_offset(
CodeEntryKind entry_kind = CodeEntryKind::kNormal) {
switch (entry_kind) {
case CodeEntryKind::kNormal:
- return OFFSET_OF(RawFunction, entry_point_);
+ return OFFSET_OF(FunctionLayout, entry_point_);
case CodeEntryKind::kUnchecked:
- return OFFSET_OF(RawFunction, unchecked_entry_point_);
+ return OFFSET_OF(FunctionLayout, unchecked_entry_point_);
default:
UNREACHABLE();
}
}
static intptr_t unchecked_entry_point_offset() {
- return OFFSET_OF(RawFunction, unchecked_entry_point_);
+ return OFFSET_OF(FunctionLayout, unchecked_entry_point_);
}
#if !defined(DART_PRECOMPILED_RUNTIME)
bool IsBytecodeAllowed(Zone* zone) const;
void AttachBytecode(const Bytecode& bytecode) const;
- RawBytecode* bytecode() const { return raw_ptr()->bytecode_; }
+ BytecodePtr bytecode() const { return raw_ptr()->bytecode_; }
inline bool HasBytecode() const;
#else
inline bool HasBytecode() const { return false; }
@@ -2681,44 +2672,44 @@
// set in this function.
bool HasBreakpoint() const;
- RawContextScope* context_scope() const;
+ ContextScopePtr context_scope() const;
void set_context_scope(const ContextScope& value) const;
// Enclosing function of this local function.
- RawFunction* parent_function() const;
+ FunctionPtr parent_function() const;
// Enclosing outermost function of this local function.
- RawFunction* GetOutermostFunction() const;
+ FunctionPtr GetOutermostFunction() const;
void set_extracted_method_closure(const Function& function) const;
- RawFunction* extracted_method_closure() const;
+ FunctionPtr extracted_method_closure() const;
void set_saved_args_desc(const Array& array) const;
- RawArray* saved_args_desc() const;
+ ArrayPtr saved_args_desc() const;
void set_accessor_field(const Field& value) const;
- RawField* accessor_field() const;
+ FieldPtr accessor_field() const;
bool IsMethodExtractor() const {
- return kind() == RawFunction::kMethodExtractor;
+ return kind() == FunctionLayout::kMethodExtractor;
}
bool IsNoSuchMethodDispatcher() const {
- return kind() == RawFunction::kNoSuchMethodDispatcher;
+ return kind() == FunctionLayout::kNoSuchMethodDispatcher;
}
bool IsInvokeFieldDispatcher() const {
- return kind() == RawFunction::kInvokeFieldDispatcher;
+ return kind() == FunctionLayout::kInvokeFieldDispatcher;
}
bool IsDynamicInvocationForwarder() const {
- return kind() == RawFunction::kDynamicInvocationForwarder;
+ return kind() == FunctionLayout::kDynamicInvocationForwarder;
}
bool IsImplicitGetterOrSetter() const {
- return kind() == RawFunction::kImplicitGetter ||
- kind() == RawFunction::kImplicitSetter ||
- kind() == RawFunction::kImplicitStaticGetter;
+ return kind() == FunctionLayout::kImplicitGetter ||
+ kind() == FunctionLayout::kImplicitSetter ||
+ kind() == FunctionLayout::kImplicitStaticGetter;
}
// Returns true iff an implicit closure function has been created
@@ -2730,48 +2721,48 @@
// Returns the closure function implicitly created for this function. If none
// exists yet, create one and remember it. Implicit closure functions are
// used in VM Closure instances that represent results of tear-off operations.
- RawFunction* ImplicitClosureFunction() const;
+ FunctionPtr ImplicitClosureFunction() const;
void DropUncompiledImplicitClosureFunction() const;
// Return the closure implicitly created for this function.
// If none exists yet, create one and remember it.
- RawInstance* ImplicitStaticClosure() const;
+ InstancePtr ImplicitStaticClosure() const;
- RawInstance* ImplicitInstanceClosure(const Instance& receiver) const;
+ InstancePtr ImplicitInstanceClosure(const Instance& receiver) const;
intptr_t ComputeClosureHash() const;
// Redirection information for a redirecting factory.
bool IsRedirectingFactory() const;
- RawType* RedirectionType() const;
+ TypePtr RedirectionType() const;
void SetRedirectionType(const Type& type) const;
- RawString* RedirectionIdentifier() const;
+ StringPtr RedirectionIdentifier() const;
void SetRedirectionIdentifier(const String& identifier) const;
- RawFunction* RedirectionTarget() const;
+ FunctionPtr RedirectionTarget() const;
void SetRedirectionTarget(const Function& target) const;
- RawFunction* ForwardingTarget() const;
+ FunctionPtr ForwardingTarget() const;
void SetForwardingChecks(const Array& checks) const;
- RawFunction::Kind kind() const {
+ FunctionLayout::Kind kind() const {
return KindBits::decode(raw_ptr()->kind_tag_);
}
- static RawFunction::Kind kind(RawFunction* function) {
+ static FunctionLayout::Kind kind(FunctionPtr function) {
return KindBits::decode(function->ptr()->kind_tag_);
}
- RawFunction::AsyncModifier modifier() const {
+ FunctionLayout::AsyncModifier modifier() const {
return ModifierBits::decode(raw_ptr()->kind_tag_);
}
- static const char* KindToCString(RawFunction::Kind kind);
+ static const char* KindToCString(FunctionLayout::Kind kind);
bool IsGenerativeConstructor() const {
- return (kind() == RawFunction::kConstructor) && !is_static();
+ return (kind() == FunctionLayout::kConstructor) && !is_static();
}
bool IsImplicitConstructor() const;
bool IsFactory() const {
- return (kind() == RawFunction::kConstructor) && is_static();
+ return (kind() == FunctionLayout::kConstructor) && is_static();
}
// Whether this function can receive an invocation where the number and names
@@ -2782,7 +2773,7 @@
bool HasThisParameter() const {
return IsDynamicFunction(/*allow_abstract=*/true) ||
- IsGenerativeConstructor();
+ IsGenerativeConstructor() || (IsFieldInitializer() && !is_static());
}
bool IsDynamicFunction(bool allow_abstract = false) const {
@@ -2790,23 +2781,23 @@
return false;
}
switch (kind()) {
- case RawFunction::kRegularFunction:
- case RawFunction::kGetterFunction:
- case RawFunction::kSetterFunction:
- case RawFunction::kImplicitGetter:
- case RawFunction::kImplicitSetter:
- case RawFunction::kMethodExtractor:
- case RawFunction::kNoSuchMethodDispatcher:
- case RawFunction::kInvokeFieldDispatcher:
- case RawFunction::kDynamicInvocationForwarder:
+ case FunctionLayout::kRegularFunction:
+ case FunctionLayout::kGetterFunction:
+ case FunctionLayout::kSetterFunction:
+ case FunctionLayout::kImplicitGetter:
+ case FunctionLayout::kImplicitSetter:
+ case FunctionLayout::kMethodExtractor:
+ case FunctionLayout::kNoSuchMethodDispatcher:
+ case FunctionLayout::kInvokeFieldDispatcher:
+ case FunctionLayout::kDynamicInvocationForwarder:
return true;
- case RawFunction::kClosureFunction:
- case RawFunction::kImplicitClosureFunction:
- case RawFunction::kSignatureFunction:
- case RawFunction::kConstructor:
- case RawFunction::kImplicitStaticGetter:
- case RawFunction::kFieldInitializer:
- case RawFunction::kIrregexpFunction:
+ case FunctionLayout::kClosureFunction:
+ case FunctionLayout::kImplicitClosureFunction:
+ case FunctionLayout::kSignatureFunction:
+ case FunctionLayout::kConstructor:
+ case FunctionLayout::kImplicitStaticGetter:
+ case FunctionLayout::kFieldInitializer:
+ case FunctionLayout::kIrregexpFunction:
return false;
default:
UNREACHABLE();
@@ -2818,23 +2809,23 @@
return false;
}
switch (kind()) {
- case RawFunction::kRegularFunction:
- case RawFunction::kGetterFunction:
- case RawFunction::kSetterFunction:
- case RawFunction::kImplicitGetter:
- case RawFunction::kImplicitSetter:
- case RawFunction::kImplicitStaticGetter:
- case RawFunction::kFieldInitializer:
- case RawFunction::kIrregexpFunction:
+ case FunctionLayout::kRegularFunction:
+ case FunctionLayout::kGetterFunction:
+ case FunctionLayout::kSetterFunction:
+ case FunctionLayout::kImplicitGetter:
+ case FunctionLayout::kImplicitSetter:
+ case FunctionLayout::kImplicitStaticGetter:
+ case FunctionLayout::kFieldInitializer:
+ case FunctionLayout::kIrregexpFunction:
return true;
- case RawFunction::kClosureFunction:
- case RawFunction::kImplicitClosureFunction:
- case RawFunction::kSignatureFunction:
- case RawFunction::kConstructor:
- case RawFunction::kMethodExtractor:
- case RawFunction::kNoSuchMethodDispatcher:
- case RawFunction::kInvokeFieldDispatcher:
- case RawFunction::kDynamicInvocationForwarder:
+ case FunctionLayout::kClosureFunction:
+ case FunctionLayout::kImplicitClosureFunction:
+ case FunctionLayout::kSignatureFunction:
+ case FunctionLayout::kConstructor:
+ case FunctionLayout::kMethodExtractor:
+ case FunctionLayout::kNoSuchMethodDispatcher:
+ case FunctionLayout::kInvokeFieldDispatcher:
+ case FunctionLayout::kDynamicInvocationForwarder:
return false;
default:
UNREACHABLE();
@@ -2848,7 +2839,7 @@
return false;
}
return IsClosureFunction() ||
- !(is_static() || (kind() == RawFunction::kConstructor));
+ !(is_static() || (kind() == FunctionLayout::kConstructor));
}
bool NeedsMonomorphicCheckedEntry(Zone* zone) const;
@@ -2880,7 +2871,7 @@
}
intptr_t num_fixed_parameters() const {
- return RawFunction::PackedNumFixedParameters::decode(
+ return FunctionLayout::PackedNumFixedParameters::decode(
raw_ptr()->packed_fields_);
}
void set_num_fixed_parameters(intptr_t value) const;
@@ -2889,19 +2880,19 @@
void set_packed_fields(uint32_t packed_fields) const;
bool HasOptionalParameters() const {
- return RawFunction::PackedNumOptionalParameters::decode(
+ return FunctionLayout::PackedNumOptionalParameters::decode(
raw_ptr()->packed_fields_) > 0;
}
bool HasOptionalNamedParameters() const {
return HasOptionalParameters() &&
- RawFunction::PackedHasNamedOptionalParameters::decode(
+ FunctionLayout::PackedHasNamedOptionalParameters::decode(
raw_ptr()->packed_fields_);
}
bool HasOptionalPositionalParameters() const {
return HasOptionalParameters() && !HasOptionalNamedParameters();
}
intptr_t NumOptionalParameters() const {
- return RawFunction::PackedNumOptionalParameters::decode(
+ return FunctionLayout::PackedNumOptionalParameters::decode(
raw_ptr()->packed_fields_);
}
void SetNumOptionalParameters(intptr_t num_optional_parameters,
@@ -2930,7 +2921,9 @@
void set_##name(type value) const { UNREACHABLE(); }
#else
#define DEFINE_GETTERS_AND_SETTERS(return_type, type, name) \
- static intptr_t name##_offset() { return OFFSET_OF(RawFunction, name##_); } \
+ static intptr_t name##_offset() { \
+ return OFFSET_OF(FunctionLayout, name##_); \
+ } \
return_type name() const { return raw_ptr()->name##_; } \
\
void set_##name(type value) const { \
@@ -2944,13 +2937,13 @@
#if !defined(DART_PRECOMPILED_RUNTIME)
intptr_t binary_declaration_offset() const {
- return RawFunction::BinaryDeclarationOffset::decode(
+ return FunctionLayout::BinaryDeclarationOffset::decode(
raw_ptr()->binary_declaration_);
}
void set_binary_declaration_offset(intptr_t value) const {
ASSERT(value >= 0);
StoreNonPointer(&raw_ptr()->binary_declaration_,
- RawFunction::BinaryDeclarationOffset::update(
+ FunctionLayout::BinaryDeclarationOffset::update(
value, raw_ptr()->binary_declaration_));
}
#endif // !defined(DART_PRECOMPILED_RUNTIME)
@@ -2995,7 +2988,7 @@
#if defined(DART_PRECOMPILED_RUNTIME)
return false;
#else
- return RawFunction::IsDeclaredInBytecode::decode(
+ return FunctionLayout::IsDeclaredInBytecode::decode(
raw_ptr()->binary_declaration_);
#endif
}
@@ -3003,7 +2996,7 @@
#if !defined(DART_PRECOMPILED_RUNTIME)
void set_is_declared_in_bytecode(bool value) const {
StoreNonPointer(&raw_ptr()->binary_declaration_,
- RawFunction::IsDeclaredInBytecode::update(
+ FunctionLayout::IsDeclaredInBytecode::update(
value, raw_ptr()->binary_declaration_));
}
#endif // !defined(DART_PRECOMPILED_RUNTIME)
@@ -3029,7 +3022,7 @@
intptr_t KernelDataProgramOffset() const;
- RawExternalTypedData* KernelData() const;
+ ExternalTypedDataPtr KernelData() const;
bool IsOptimizable() const;
void SetIsOptimizable(bool value) const;
@@ -3075,7 +3068,7 @@
// Returns a TypeError if the provided arguments don't match the function
// parameter types, NULL otherwise. Assumes AreValidArguments is called first.
- RawObject* DoArgumentTypesMatch(
+ ObjectPtr DoArgumentTypesMatch(
const Array& args,
const ArgumentsDescriptor& arg_names,
const TypeArguments& instantiator_type_args) const;
@@ -3100,13 +3093,13 @@
static constexpr intptr_t maximum_unboxed_parameter_count() {
// Subtracts one that represents the return value
- return RawFunction::UnboxedParameterBitmap::kCapacity - 1;
+ return FunctionLayout::UnboxedParameterBitmap::kCapacity - 1;
}
void reset_unboxed_parameters_and_return() const {
#if !defined(DART_PRECOMPILED_RUNTIME)
StoreNonPointer(&raw_ptr()->unboxed_parameters_info_,
- RawFunction::UnboxedParameterBitmap());
+ FunctionLayout::UnboxedParameterBitmap());
#endif // !defined(DART_PRECOMPILED_RUNTIME)
}
@@ -3114,7 +3107,7 @@
#if !defined(DART_PRECOMPILED_RUNTIME)
ASSERT(index >= 0 && index < maximum_unboxed_parameter_count());
index++; // position 0 is reserved for the return value
- const_cast<RawFunction::UnboxedParameterBitmap*>(
+ const_cast<FunctionLayout::UnboxedParameterBitmap*>(
&raw_ptr()->unboxed_parameters_info_)
->SetUnboxedInteger(index);
#else
@@ -3126,7 +3119,7 @@
#if !defined(DART_PRECOMPILED_RUNTIME)
ASSERT(index >= 0 && index < maximum_unboxed_parameter_count());
index++; // position 0 is reserved for the return value
- const_cast<RawFunction::UnboxedParameterBitmap*>(
+ const_cast<FunctionLayout::UnboxedParameterBitmap*>(
&raw_ptr()->unboxed_parameters_info_)
->SetUnboxedDouble(index);
@@ -3137,7 +3130,7 @@
void set_unboxed_integer_return() const {
#if !defined(DART_PRECOMPILED_RUNTIME)
- const_cast<RawFunction::UnboxedParameterBitmap*>(
+ const_cast<FunctionLayout::UnboxedParameterBitmap*>(
&raw_ptr()->unboxed_parameters_info_)
->SetUnboxedInteger(0);
#else
@@ -3147,7 +3140,7 @@
void set_unboxed_double_return() const {
#if !defined(DART_PRECOMPILED_RUNTIME)
- const_cast<RawFunction::UnboxedParameterBitmap*>(
+ const_cast<FunctionLayout::UnboxedParameterBitmap*>(
&raw_ptr()->unboxed_parameters_info_)
->SetUnboxedDouble(0);
@@ -3216,12 +3209,12 @@
bool IsDispatcherOrImplicitAccessor() const {
switch (kind()) {
- case RawFunction::kImplicitGetter:
- case RawFunction::kImplicitSetter:
- case RawFunction::kImplicitStaticGetter:
- case RawFunction::kNoSuchMethodDispatcher:
- case RawFunction::kInvokeFieldDispatcher:
- case RawFunction::kDynamicInvocationForwarder:
+ case FunctionLayout::kImplicitGetter:
+ case FunctionLayout::kImplicitSetter:
+ case FunctionLayout::kImplicitStaticGetter:
+ case FunctionLayout::kNoSuchMethodDispatcher:
+ case FunctionLayout::kInvokeFieldDispatcher:
+ case FunctionLayout::kDynamicInvocationForwarder:
return true;
default:
return false;
@@ -3230,47 +3223,47 @@
// Returns true if this function represents an explicit getter function.
bool IsGetterFunction() const {
- return kind() == RawFunction::kGetterFunction;
+ return kind() == FunctionLayout::kGetterFunction;
}
// Returns true if this function represents an implicit getter function.
bool IsImplicitGetterFunction() const {
- return kind() == RawFunction::kImplicitGetter;
+ return kind() == FunctionLayout::kImplicitGetter;
}
// Returns true if this function represents an explicit setter function.
bool IsSetterFunction() const {
- return kind() == RawFunction::kSetterFunction;
+ return kind() == FunctionLayout::kSetterFunction;
}
// Returns true if this function represents an implicit setter function.
bool IsImplicitSetterFunction() const {
- return kind() == RawFunction::kImplicitSetter;
+ return kind() == FunctionLayout::kImplicitSetter;
}
- // Returns true if this function represents an the initializer for a static or
+ // Returns true if this function represents an initializer for a static or
// instance field. The function returns the initial value and the caller is
// responsible for setting the field.
bool IsFieldInitializer() const {
- return kind() == RawFunction::kFieldInitializer;
+ return kind() == FunctionLayout::kFieldInitializer;
}
// Returns true if this function represents a (possibly implicit) closure
// function.
bool IsClosureFunction() const {
- RawFunction::Kind k = kind();
- return (k == RawFunction::kClosureFunction) ||
- (k == RawFunction::kImplicitClosureFunction);
+ FunctionLayout::Kind k = kind();
+ return (k == FunctionLayout::kClosureFunction) ||
+ (k == FunctionLayout::kImplicitClosureFunction);
}
// Returns true if this function represents a generated irregexp function.
bool IsIrregexpFunction() const {
- return kind() == RawFunction::kIrregexpFunction;
+ return kind() == FunctionLayout::kIrregexpFunction;
}
// Returns true if this function represents an implicit closure function.
bool IsImplicitClosureFunction() const {
- return kind() == RawFunction::kImplicitClosureFunction;
+ return kind() == FunctionLayout::kImplicitClosureFunction;
}
// Returns true if this function represents a non implicit closure function.
@@ -3283,7 +3276,7 @@
bool IsImplicitStaticClosureFunction() const {
return IsImplicitClosureFunction() && is_static();
}
- static bool IsImplicitStaticClosureFunction(RawFunction* func);
+ static bool IsImplicitStaticClosureFunction(FunctionPtr func);
// Returns true if this function represents an implicit instance closure
// function.
@@ -3296,20 +3289,22 @@
// Returns true if this function represents a signature function without code.
bool IsSignatureFunction() const {
- return kind() == RawFunction::kSignatureFunction;
+ return kind() == FunctionLayout::kSignatureFunction;
}
- static bool IsSignatureFunction(RawFunction* function) {
+ static bool IsSignatureFunction(FunctionPtr function) {
NoSafepointScope no_safepoint;
return KindBits::decode(function->ptr()->kind_tag_) ==
- RawFunction::kSignatureFunction;
+ FunctionLayout::kSignatureFunction;
}
// Returns true if this function represents an ffi trampoline.
- bool IsFfiTrampoline() const { return kind() == RawFunction::kFfiTrampoline; }
- static bool IsFfiTrampoline(RawFunction* function) {
+ bool IsFfiTrampoline() const {
+ return kind() == FunctionLayout::kFfiTrampoline;
+ }
+ static bool IsFfiTrampoline(FunctionPtr function) {
NoSafepointScope no_safepoint;
return KindBits::decode(function->ptr()->kind_tag_) ==
- RawFunction::kFfiTrampoline;
+ FunctionLayout::kFfiTrampoline;
}
bool IsFfiLoad() const {
@@ -3334,7 +3329,7 @@
return kind == MethodRecognizer::kFfiGetAddress;
}
- bool IsAsyncFunction() const { return modifier() == RawFunction::kAsync; }
+ bool IsAsyncFunction() const { return modifier() == FunctionLayout::kAsync; }
bool IsAsyncClosure() const {
return is_generated_body() &&
@@ -3342,10 +3337,12 @@
}
bool IsGenerator() const {
- return (modifier() & RawFunction::kGeneratorBit) != 0;
+ return (modifier() & FunctionLayout::kGeneratorBit) != 0;
}
- bool IsSyncGenerator() const { return modifier() == RawFunction::kSyncGen; }
+ bool IsSyncGenerator() const {
+ return modifier() == FunctionLayout::kSyncGen;
+ }
bool IsSyncGenClosure() const {
return is_generated_body() &&
@@ -3357,7 +3354,9 @@
Function::Handle(parent_function()).IsGenerator();
}
- bool IsAsyncGenerator() const { return modifier() == RawFunction::kAsyncGen; }
+ bool IsAsyncGenerator() const {
+ return modifier() == FunctionLayout::kAsyncGen;
+ }
bool IsAsyncGenClosure() const {
return is_generated_body() &&
@@ -3365,11 +3364,11 @@
}
bool IsAsyncOrGenerator() const {
- return modifier() != RawFunction::kNoModifier;
+ return modifier() != FunctionLayout::kNoModifier;
}
bool IsTypedDataViewFactory() const {
- if (is_native() && kind() == RawFunction::kConstructor) {
+ if (is_native() && kind() == FunctionLayout::kConstructor) {
// This is a native factory constructor.
const Class& klass = Class::Handle(Owner());
return IsTypedDataViewClassId(klass.id());
@@ -3378,71 +3377,71 @@
}
DART_WARN_UNUSED_RESULT
- RawError* VerifyCallEntryPoint() const;
+ ErrorPtr VerifyCallEntryPoint() const;
DART_WARN_UNUSED_RESULT
- RawError* VerifyClosurizedEntryPoint() const;
+ ErrorPtr VerifyClosurizedEntryPoint() const;
static intptr_t InstanceSize() {
- return RoundedAllocationSize(sizeof(RawFunction));
+ return RoundedAllocationSize(sizeof(FunctionLayout));
}
- static RawFunction* New(const String& name,
- RawFunction::Kind kind,
- bool is_static,
- bool is_const,
- bool is_abstract,
- bool is_external,
- bool is_native,
- const Object& owner,
- TokenPosition token_pos,
- Heap::Space space = Heap::kOld);
+ static FunctionPtr New(const String& name,
+ FunctionLayout::Kind kind,
+ bool is_static,
+ bool is_const,
+ bool is_abstract,
+ bool is_external,
+ bool is_native,
+ const Object& owner,
+ TokenPosition token_pos,
+ Heap::Space space = Heap::kOld);
// Allocates a new Function object representing a closure function
// with given kind - kClosureFunction or kImplicitClosureFunction.
- static RawFunction* NewClosureFunctionWithKind(RawFunction::Kind kind,
- const String& name,
- const Function& parent,
- TokenPosition token_pos,
- const Object& owner);
+ static FunctionPtr NewClosureFunctionWithKind(FunctionLayout::Kind kind,
+ const String& name,
+ const Function& parent,
+ TokenPosition token_pos,
+ const Object& owner);
// Allocates a new Function object representing a closure function.
- static RawFunction* NewClosureFunction(const String& name,
- const Function& parent,
- TokenPosition token_pos);
+ static FunctionPtr NewClosureFunction(const String& name,
+ const Function& parent,
+ TokenPosition token_pos);
// Allocates a new Function object representing an implicit closure function.
- static RawFunction* NewImplicitClosureFunction(const String& name,
- const Function& parent,
- TokenPosition token_pos);
+ static FunctionPtr NewImplicitClosureFunction(const String& name,
+ const Function& parent,
+ TokenPosition token_pos);
// Allocates a new Function object representing a signature function.
// The owner is the scope class of the function type.
// The parent is the enclosing function or null if none.
- static RawFunction* NewSignatureFunction(const Object& owner,
- const Function& parent,
- TokenPosition token_pos,
- Heap::Space space = Heap::kOld);
+ static FunctionPtr NewSignatureFunction(const Object& owner,
+ const Function& parent,
+ TokenPosition token_pos,
+ Heap::Space space = Heap::kOld);
- static RawFunction* NewEvalFunction(const Class& owner,
- const Script& script,
- bool is_static);
+ static FunctionPtr NewEvalFunction(const Class& owner,
+ const Script& script,
+ bool is_static);
- RawFunction* CreateMethodExtractor(const String& getter_name) const;
- RawFunction* GetMethodExtractor(const String& getter_name) const;
+ FunctionPtr CreateMethodExtractor(const String& getter_name) const;
+ FunctionPtr GetMethodExtractor(const String& getter_name) const;
static bool IsDynamicInvocationForwarderName(const String& name);
- static RawString* DemangleDynamicInvocationForwarderName(const String& name);
+ static StringPtr DemangleDynamicInvocationForwarderName(const String& name);
#if !defined(DART_PRECOMPILED_RUNTIME)
- static RawString* CreateDynamicInvocationForwarderName(const String& name);
+ static StringPtr CreateDynamicInvocationForwarderName(const String& name);
- RawFunction* CreateDynamicInvocationForwarder(
+ FunctionPtr CreateDynamicInvocationForwarder(
const String& mangled_name) const;
- RawFunction* GetDynamicInvocationForwarder(const String& mangled_name,
- bool allow_add = true) const;
+ FunctionPtr GetDynamicInvocationForwarder(const String& mangled_name,
+ bool allow_add = true) const;
#endif
// Slow function, use in asserts to track changes in important library
@@ -3461,14 +3460,14 @@
void RestoreICDataMap(ZoneGrowableArray<const ICData*>* deopt_id_to_ic_data,
bool clone_ic_data) const;
- RawArray* ic_data_array() const;
+ ArrayPtr ic_data_array() const;
void ClearICDataArray() const;
- RawICData* FindICData(intptr_t deopt_id) const;
+ ICDataPtr FindICData(intptr_t deopt_id) const;
// Sets deopt reason in all ICData-s with given deopt_id.
void SetDeoptReasonForAll(intptr_t deopt_id, ICData::DeoptReasonId reason);
- void set_modifier(RawFunction::AsyncModifier value) const;
+ void set_modifier(FunctionLayout::AsyncModifier value) const;
// 'WasCompiled' is true if the function was compiled once in this
// VM instantiation. It is independent from presence of type feedback
@@ -3568,22 +3567,22 @@
// some functions known to be execute infrequently and functions
// which have been de-optimized too many times.
bool is_optimizable() const {
- return RawFunction::OptimizableBit::decode(raw_ptr()->packed_fields_);
+ return FunctionLayout::OptimizableBit::decode(raw_ptr()->packed_fields_);
}
void set_is_optimizable(bool value) const {
- set_packed_fields(
- RawFunction::OptimizableBit::update(value, raw_ptr()->packed_fields_));
+ set_packed_fields(FunctionLayout::OptimizableBit::update(
+ value, raw_ptr()->packed_fields_));
}
// Indicates whether this function can be optimized on the background compiler
// thread.
bool is_background_optimizable() const {
- return RawFunction::BackgroundOptimizableBit::decode(
+ return FunctionLayout::BackgroundOptimizableBit::decode(
raw_ptr()->packed_fields_);
}
void set_is_background_optimizable(bool value) const {
- set_packed_fields(RawFunction::BackgroundOptimizableBit::update(
+ set_packed_fields(FunctionLayout::BackgroundOptimizableBit::update(
value, raw_ptr()->packed_fields_));
}
@@ -3610,10 +3609,10 @@
(1 << kRecognizedTagSize));
COMPILE_ASSERT(kNumTagBits <=
(kBitsPerByte *
- sizeof(static_cast<RawFunction*>(0)->kind_tag_)));
+ sizeof(static_cast<FunctionLayout*>(nullptr)->kind_tag_)));
class KindBits : public BitField<uint32_t,
- RawFunction::Kind,
+ FunctionLayout::Kind,
kKindTagPos,
kKindTagSize> {};
@@ -3622,7 +3621,7 @@
kRecognizedTagPos,
kRecognizedTagSize> {};
class ModifierBits : public BitField<uint32_t,
- RawFunction::AsyncModifier,
+ FunctionLayout::AsyncModifier,
kModifierPos,
kModifierSize> {};
@@ -3632,18 +3631,18 @@
#undef DEFINE_BIT
void set_name(const String& value) const;
- void set_kind(RawFunction::Kind value) const;
+ void set_kind(FunctionLayout::Kind value) const;
void set_parent_function(const Function& value) const;
- RawFunction* implicit_closure_function() const;
+ FunctionPtr implicit_closure_function() const;
void set_implicit_closure_function(const Function& value) const;
- RawInstance* implicit_static_closure() const;
+ InstancePtr implicit_static_closure() const;
void set_implicit_static_closure(const Instance& closure) const;
- RawScript* eval_script() const;
+ ScriptPtr eval_script() const;
void set_eval_script(const Script& value) const;
void set_num_optional_parameters(intptr_t value) const; // Encoded value.
void set_kind_tag(uint32_t value) const;
void set_data(const Object& value) const;
- static RawFunction* New(Heap::Space space = Heap::kOld);
+ static FunctionPtr New(Heap::Space space = Heap::kOld);
void PrintSignatureParameters(Thread* thread,
Zone* zone,
@@ -3667,9 +3666,9 @@
friend class Class;
friend class SnapshotWriter;
friend class Parser; // For set_eval_script.
- // RawFunction::VisitFunctionPointers accesses the private constructor of
+ // FunctionLayout::VisitFunctionPointers accesses the private constructor of
// Function.
- friend class RawFunction;
+ friend class FunctionLayout;
friend class ClassFinalizer; // To reset parent_function.
friend class Type; // To adjust parent_function.
};
@@ -3677,25 +3676,25 @@
class ClosureData : public Object {
public:
static intptr_t InstanceSize() {
- return RoundedAllocationSize(sizeof(RawClosureData));
+ return RoundedAllocationSize(sizeof(ClosureDataLayout));
}
private:
- RawContextScope* context_scope() const { return raw_ptr()->context_scope_; }
+ ContextScopePtr context_scope() const { return raw_ptr()->context_scope_; }
void set_context_scope(const ContextScope& value) const;
// Enclosing function of this local function.
- RawFunction* parent_function() const { return raw_ptr()->parent_function_; }
+ FunctionPtr parent_function() const { return raw_ptr()->parent_function_; }
void set_parent_function(const Function& value) const;
// Signature type of this closure function.
- RawType* signature_type() const { return raw_ptr()->signature_type_; }
+ TypePtr signature_type() const { return raw_ptr()->signature_type_; }
void set_signature_type(const Type& value) const;
- RawInstance* implicit_static_closure() const { return raw_ptr()->closure_; }
+ InstancePtr implicit_static_closure() const { return raw_ptr()->closure_; }
void set_implicit_static_closure(const Instance& closure) const;
- static RawClosureData* New();
+ static ClosureDataPtr New();
FINAL_HEAP_OBJECT_IMPLEMENTATION(ClosureData, Object);
friend class Class;
@@ -3706,19 +3705,19 @@
class SignatureData : public Object {
public:
static intptr_t InstanceSize() {
- return RoundedAllocationSize(sizeof(RawSignatureData));
+ return RoundedAllocationSize(sizeof(SignatureDataLayout));
}
private:
// Enclosing function of this signature function.
- RawFunction* parent_function() const { return raw_ptr()->parent_function_; }
+ FunctionPtr parent_function() const { return raw_ptr()->parent_function_; }
void set_parent_function(const Function& value) const;
// Signature type of this signature function.
- RawType* signature_type() const { return raw_ptr()->signature_type_; }
+ TypePtr signature_type() const { return raw_ptr()->signature_type_; }
void set_signature_type(const Type& value) const;
- static RawSignatureData* New(Heap::Space space = Heap::kOld);
+ static SignatureDataPtr New(Heap::Space space = Heap::kOld);
FINAL_HEAP_OBJECT_IMPLEMENTATION(SignatureData, Object);
friend class Class;
@@ -3729,23 +3728,23 @@
class RedirectionData : public Object {
public:
static intptr_t InstanceSize() {
- return RoundedAllocationSize(sizeof(RawRedirectionData));
+ return RoundedAllocationSize(sizeof(RedirectionDataLayout));
}
private:
// The type specifies the class and type arguments of the target constructor.
- RawType* type() const { return raw_ptr()->type_; }
+ TypePtr type() const { return raw_ptr()->type_; }
void set_type(const Type& value) const;
// The optional identifier specifies a named constructor.
- RawString* identifier() const { return raw_ptr()->identifier_; }
+ StringPtr identifier() const { return raw_ptr()->identifier_; }
void set_identifier(const String& value) const;
// The resolved constructor or factory target of the redirection.
- RawFunction* target() const { return raw_ptr()->target_; }
+ FunctionPtr target() const { return raw_ptr()->target_; }
void set_target(const Function& value) const;
- static RawRedirectionData* New();
+ static RedirectionDataPtr New();
FINAL_HEAP_OBJECT_IMPLEMENTATION(RedirectionData, Object);
friend class Class;
@@ -3764,21 +3763,21 @@
class FfiTrampolineData : public Object {
public:
static intptr_t InstanceSize() {
- return RoundedAllocationSize(sizeof(RawFfiTrampolineData));
+ return RoundedAllocationSize(sizeof(FfiTrampolineDataLayout));
}
private:
// Signature type of this closure function.
- RawType* signature_type() const { return raw_ptr()->signature_type_; }
+ TypePtr signature_type() const { return raw_ptr()->signature_type_; }
void set_signature_type(const Type& value) const;
- RawFunction* c_signature() const { return raw_ptr()->c_signature_; }
+ FunctionPtr c_signature() const { return raw_ptr()->c_signature_; }
void set_c_signature(const Function& value) const;
- RawFunction* callback_target() const { return raw_ptr()->callback_target_; }
+ FunctionPtr callback_target() const { return raw_ptr()->callback_target_; }
void set_callback_target(const Function& value) const;
- RawInstance* callback_exceptional_return() const {
+ InstancePtr callback_exceptional_return() const {
return raw_ptr()->callback_exceptional_return_;
}
void set_callback_exceptional_return(const Instance& value) const;
@@ -3786,7 +3785,7 @@
int32_t callback_id() const { return raw_ptr()->callback_id_; }
void set_callback_id(int32_t value) const;
- static RawFfiTrampolineData* New();
+ static FfiTrampolineDataPtr New();
FINAL_HEAP_OBJECT_IMPLEMENTATION(FfiTrampolineData, Object);
friend class Class;
@@ -3799,7 +3798,7 @@
// The field that this field was cloned from, or this field itself if it isn't
// a clone. The purpose of cloning is that the fields the background compiler
// sees are consistent.
- RawField* Original() const;
+ FieldPtr Original() const;
// Set the original field that this field was cloned from.
void SetOriginal(const Field& value) const;
@@ -3815,12 +3814,12 @@
// Returns a field cloned from 'this'. 'this' is set as the
// original field of result.
- RawField* CloneFromOriginal() const;
+ FieldPtr CloneFromOriginal() const;
- RawString* name() const { return raw_ptr()->name_; }
- RawString* UserVisibleName() const; // Same as scrubbed name.
+ StringPtr name() const { return raw_ptr()->name_; }
+ StringPtr UserVisibleName() const; // Same as scrubbed name.
const char* UserVisibleNameCString() const;
- virtual RawString* DictionaryName() const { return name(); }
+ virtual StringPtr DictionaryName() const { return name(); }
bool is_static() const { return StaticBit::decode(raw_ptr()->kind_bits_); }
bool is_instance() const { return !is_static(); }
@@ -3884,13 +3883,13 @@
#if !defined(DART_PRECOMPILED_RUNTIME)
intptr_t binary_declaration_offset() const {
- return RawField::BinaryDeclarationOffset::decode(
+ return FieldLayout::BinaryDeclarationOffset::decode(
raw_ptr()->binary_declaration_);
}
void set_binary_declaration_offset(intptr_t value) const {
ASSERT(value >= 0);
StoreNonPointer(&raw_ptr()->binary_declaration_,
- RawField::BinaryDeclarationOffset::update(
+ FieldLayout::BinaryDeclarationOffset::update(
value, raw_ptr()->binary_declaration_));
}
#endif // !defined(DART_PRECOMPILED_RUNTIME)
@@ -3935,7 +3934,7 @@
#if defined(DART_PRECOMPILED_RUNTIME)
return false;
#else
- return RawField::IsDeclaredInBytecode::decode(
+ return FieldLayout::IsDeclaredInBytecode::decode(
raw_ptr()->binary_declaration_);
#endif
}
@@ -3943,14 +3942,14 @@
#if !defined(DART_PRECOMPILED_RUNTIME)
void set_is_declared_in_bytecode(bool value) const {
StoreNonPointer(&raw_ptr()->binary_declaration_,
- RawField::IsDeclaredInBytecode::update(
+ FieldLayout::IsDeclaredInBytecode::update(
value, raw_ptr()->binary_declaration_));
}
#endif // !defined(DART_PRECOMPILED_RUNTIME)
void InheritBinaryDeclarationFrom(const Field& src) const;
- RawExternalTypedData* KernelData() const;
+ ExternalTypedDataPtr KernelData() const;
intptr_t KernelDataProgramOffset() const;
@@ -3962,7 +3961,7 @@
inline intptr_t TargetOffset() const;
- inline RawInstance* StaticValue() const;
+ inline InstancePtr StaticValue() const;
void SetStaticValue(const Instance& value,
bool save_initial_value = false) const;
@@ -3970,59 +3969,61 @@
inline void set_field_id(intptr_t field_id) const;
#ifndef DART_PRECOMPILED_RUNTIME
- RawInstance* saved_initial_value() const {
+ InstancePtr saved_initial_value() const {
return raw_ptr()->saved_initial_value_;
}
inline void set_saved_initial_value(const Instance& value) const;
#endif
- RawClass* Owner() const;
- RawClass* Origin() const; // Either mixin class, or same as owner().
- RawScript* Script() const;
- RawObject* RawOwner() const;
+ ClassPtr Owner() const;
+ ClassPtr Origin() const; // Either mixin class, or same as owner().
+ ScriptPtr Script() const;
+ ObjectPtr RawOwner() const;
- RawAbstractType* type() const { return raw_ptr()->type_; }
+ AbstractTypePtr type() const { return raw_ptr()->type_; }
// Used by class finalizer, otherwise initialized in constructor.
void SetFieldType(const AbstractType& value) const;
DART_WARN_UNUSED_RESULT
- RawError* VerifyEntryPoint(EntryPointPragma kind) const;
+ ErrorPtr VerifyEntryPoint(EntryPointPragma kind) const;
static intptr_t InstanceSize() {
- return RoundedAllocationSize(sizeof(RawField));
+ return RoundedAllocationSize(sizeof(FieldLayout));
}
- static RawField* New(const String& name,
- bool is_static,
- bool is_final,
- bool is_const,
- bool is_reflectable,
- bool is_late,
- const Object& owner,
- const AbstractType& type,
- TokenPosition token_pos,
- TokenPosition end_token_pos);
+ static FieldPtr New(const String& name,
+ bool is_static,
+ bool is_final,
+ bool is_const,
+ bool is_reflectable,
+ bool is_late,
+ const Object& owner,
+ const AbstractType& type,
+ TokenPosition token_pos,
+ TokenPosition end_token_pos);
- static RawField* NewTopLevel(const String& name,
- bool is_final,
- bool is_const,
- bool is_late,
- const Object& owner,
- TokenPosition token_pos,
- TokenPosition end_token_pos);
+ static FieldPtr NewTopLevel(const String& name,
+ bool is_final,
+ bool is_const,
+ bool is_late,
+ const Object& owner,
+ TokenPosition token_pos,
+ TokenPosition end_token_pos);
// Allocate new field object, clone values from this field. The
// original is specified.
- RawField* Clone(const Field& original) const;
+ FieldPtr Clone(const Field& original) const;
- static intptr_t kind_bits_offset() { return OFFSET_OF(RawField, kind_bits_); }
+ static intptr_t kind_bits_offset() {
+ return OFFSET_OF(FieldLayout, kind_bits_);
+ }
TokenPosition token_pos() const { return raw_ptr()->token_pos_; }
TokenPosition end_token_pos() const { return raw_ptr()->end_token_pos_; }
int32_t SourceFingerprint() const;
- RawString* InitializingExpression() const;
+ StringPtr InitializingExpression() const;
bool has_nontrivial_initializer() const {
return HasNontrivialInitializerBit::decode(raw_ptr()->kind_bits_);
@@ -4070,10 +4071,10 @@
}
static intptr_t static_type_exactness_state_offset() {
- return OFFSET_OF(RawField, static_type_exactness_state_);
+ return OFFSET_OF(FieldLayout, static_type_exactness_state_);
}
- static inline intptr_t TargetOffsetOf(const RawField* field) {
+ static inline intptr_t TargetOffsetOf(const FieldPtr field) {
#if !defined(DART_PRECOMPILED_RUNTIME)
return field->ptr()->target_offset_;
#else
@@ -4106,7 +4107,7 @@
StoreNonPointer(&raw_ptr()->guarded_cid_, cid);
}
static intptr_t guarded_cid_offset() {
- return OFFSET_OF(RawField, guarded_cid_);
+ return OFFSET_OF(FieldLayout, guarded_cid_);
}
// Return the list length that any list stored in this field is guaranteed
// to have. If length is kUnknownFixedLength the length has not
@@ -4115,12 +4116,12 @@
intptr_t guarded_list_length() const;
void set_guarded_list_length(intptr_t list_length) const;
static intptr_t guarded_list_length_offset() {
- return OFFSET_OF(RawField, guarded_list_length_);
+ return OFFSET_OF(FieldLayout, guarded_list_length_);
}
intptr_t guarded_list_length_in_object_offset() const;
void set_guarded_list_length_in_object_offset(intptr_t offset) const;
static intptr_t guarded_list_length_in_object_offset_offset() {
- return OFFSET_OF(RawField, guarded_list_length_in_object_offset_);
+ return OFFSET_OF(FieldLayout, guarded_list_length_in_object_offset_);
}
bool needs_length_check() const {
@@ -4186,7 +4187,7 @@
StoreNonPointer(&raw_ptr()->is_nullable_, val ? kNullCid : kIllegalCid);
}
static intptr_t is_nullable_offset() {
- return OFFSET_OF(RawField, is_nullable_);
+ return OFFSET_OF(FieldLayout, is_nullable_);
}
// Record store of the given value into this field. May trigger
@@ -4199,7 +4200,7 @@
// assumptions about guarded class id and nullability of this field.
// These code objects must be deoptimized when field's properties change.
// Code objects are held weakly via an indirection through WeakProperty.
- RawArray* dependent_code() const;
+ ArrayPtr dependent_code() const;
void set_dependent_code(const Array& array) const;
// Add the given code object to the list of dependent ones.
@@ -4215,15 +4216,15 @@
bool IsUninitialized() const;
// Run initializer and set field value.
- DART_WARN_UNUSED_RESULT RawError* InitializeInstance(
- const Instance& instance) const;
- DART_WARN_UNUSED_RESULT RawError* InitializeStatic() const;
+ DART_WARN_UNUSED_RESULT ErrorPtr
+ InitializeInstance(const Instance& instance) const;
+ DART_WARN_UNUSED_RESULT ErrorPtr InitializeStatic() const;
// Run initializer only.
- DART_WARN_UNUSED_RESULT RawObject* EvaluateInitializer() const;
+ DART_WARN_UNUSED_RESULT ObjectPtr EvaluateInitializer() const;
- RawFunction* EnsureInitializerFunction() const;
- RawFunction* InitializerFunction() const {
+ FunctionPtr EnsureInitializerFunction() const;
+ FunctionPtr InitializerFunction() const {
return raw_ptr()->initializer_function_;
}
void SetInitializerFunction(const Function& initializer) const;
@@ -4231,28 +4232,28 @@
// For static fields only. Constructs a closure that gets/sets the
// field value.
- RawInstance* GetterClosure() const;
- RawInstance* SetterClosure() const;
- RawInstance* AccessorClosure(bool make_setter) const;
+ InstancePtr GetterClosure() const;
+ InstancePtr SetterClosure() const;
+ InstancePtr AccessorClosure(bool make_setter) const;
// Constructs getter and setter names for fields and vice versa.
- static RawString* GetterName(const String& field_name);
- static RawString* GetterSymbol(const String& field_name);
+ static StringPtr GetterName(const String& field_name);
+ static StringPtr GetterSymbol(const String& field_name);
// Returns String::null() if getter symbol does not exist.
- static RawString* LookupGetterSymbol(const String& field_name);
- static RawString* SetterName(const String& field_name);
- static RawString* SetterSymbol(const String& field_name);
+ static StringPtr LookupGetterSymbol(const String& field_name);
+ static StringPtr SetterName(const String& field_name);
+ static StringPtr SetterSymbol(const String& field_name);
// Returns String::null() if setter symbol does not exist.
- static RawString* LookupSetterSymbol(const String& field_name);
- static RawString* NameFromGetter(const String& getter_name);
- static RawString* NameFromSetter(const String& setter_name);
- static RawString* NameFromInit(const String& init_name);
+ static StringPtr LookupSetterSymbol(const String& field_name);
+ static StringPtr NameFromGetter(const String& getter_name);
+ static StringPtr NameFromSetter(const String& setter_name);
+ static StringPtr NameFromInit(const String& init_name);
static bool IsGetterName(const String& function_name);
static bool IsSetterName(const String& function_name);
static bool IsInitName(const String& function_name);
#if !defined(DART_PRECOMPILED_RUNTIME)
- RawSubtypeTestCache* type_test_cache() const {
+ SubtypeTestCachePtr type_test_cache() const {
return raw_ptr()->type_test_cache_;
}
void set_type_test_cache(const SubtypeTestCache& cache) const;
@@ -4358,29 +4359,29 @@
StoreNonPointer(&raw_ptr()->kind_bits_, value);
}
- static RawField* New();
+ static FieldPtr New();
FINAL_HEAP_OBJECT_IMPLEMENTATION(Field, Object);
friend class Class;
friend class HeapProfiler;
- friend class RawField;
+ friend class FieldLayout;
friend class FieldSerializationCluster;
friend class FieldDeserializationCluster;
};
class Script : public Object {
public:
- RawString* url() const { return raw_ptr()->url_; }
+ StringPtr url() const { return raw_ptr()->url_; }
void set_url(const String& value) const;
// The actual url which was loaded from disk, if provided by the embedder.
- RawString* resolved_url() const { return raw_ptr()->resolved_url_; }
+ StringPtr resolved_url() const { return raw_ptr()->resolved_url_; }
bool HasSource() const;
- RawString* Source() const;
+ StringPtr Source() const;
bool IsPartOfDartColonLibrary() const;
void LookupSourceAndLineStarts(Zone* zone) const;
- RawGrowableObjectArray* GenerateLineNumberArray() const;
+ GrowableObjectArrayPtr GenerateLineNumberArray() const;
intptr_t line_offset() const { return raw_ptr()->line_offset_; }
intptr_t col_offset() const { return raw_ptr()->col_offset_; }
@@ -4388,12 +4389,12 @@
// The load time in milliseconds since epoch.
int64_t load_timestamp() const { return raw_ptr()->load_timestamp_; }
- RawArray* compile_time_constants() const {
+ ArrayPtr compile_time_constants() const {
return raw_ptr()->compile_time_constants_;
}
void set_compile_time_constants(const Array& value) const;
- RawKernelProgramInfo* kernel_program_info() const {
+ KernelProgramInfoPtr kernel_program_info() const {
return raw_ptr()->kernel_program_info_;
}
void set_kernel_program_info(const KernelProgramInfo& info) const;
@@ -4403,22 +4404,21 @@
}
void set_kernel_script_index(const intptr_t kernel_script_index) const;
- RawTypedData* kernel_string_offsets() const;
+ TypedDataPtr kernel_string_offsets() const;
- RawTypedData* line_starts() const;
+ TypedDataPtr line_starts() const;
void set_line_starts(const TypedData& value) const;
void set_debug_positions(const Array& value) const;
- RawLibrary* FindLibrary() const;
- RawString* GetLine(intptr_t line_number,
- Heap::Space space = Heap::kNew) const;
- RawString* GetSnippet(TokenPosition from, TokenPosition to) const;
- RawString* GetSnippet(intptr_t from_line,
- intptr_t from_column,
- intptr_t to_line,
- intptr_t to_column) const;
+ LibraryPtr FindLibrary() const;
+ StringPtr GetLine(intptr_t line_number, Heap::Space space = Heap::kNew) const;
+ StringPtr GetSnippet(TokenPosition from, TokenPosition to) const;
+ StringPtr GetSnippet(intptr_t from_line,
+ intptr_t from_column,
+ intptr_t to_line,
+ intptr_t to_column) const;
void SetLocationOffset(intptr_t line_offset, intptr_t col_offset) const;
@@ -4437,14 +4437,14 @@
TokenPosition* last_token_index) const;
static intptr_t InstanceSize() {
- return RoundedAllocationSize(sizeof(RawScript));
+ return RoundedAllocationSize(sizeof(ScriptLayout));
}
- static RawScript* New(const String& url, const String& source);
+ static ScriptPtr New(const String& url, const String& source);
- static RawScript* New(const String& url,
- const String& resolved_url,
- const String& source);
+ static ScriptPtr New(const String& url,
+ const String& resolved_url,
+ const String& source);
#if !defined(DART_PRECOMPILED_RUNTIME)
void LoadSourceFromKernel(const uint8_t* kernel_buffer,
@@ -4459,9 +4459,9 @@
void set_source(const String& value) const;
void set_flags(uint8_t value) const;
void set_load_timestamp(int64_t value) const;
- RawArray* debug_positions() const;
+ ArrayPtr debug_positions() const;
- static RawScript* New();
+ static ScriptPtr New();
FINAL_HEAP_OBJECT_IMPLEMENTATION(Script, Object);
friend class Class;
@@ -4475,7 +4475,7 @@
bool HasNext() const { return next_ix_ < size_; }
// Returns next non-null raw object.
- RawObject* GetNext();
+ ObjectPtr GetNext();
private:
void MoveToNextObject();
@@ -4506,7 +4506,7 @@
}
// Returns a non-null raw class.
- RawClass* GetNextClass();
+ ClassPtr GetNextClass();
private:
void MoveToNextClass();
@@ -4519,7 +4519,7 @@
class LibraryPrefixIterator : public DictionaryIterator {
public:
explicit LibraryPrefixIterator(const Library& library);
- RawLibraryPrefix* GetNext();
+ LibraryPrefixPtr GetNext();
private:
void Advance();
@@ -4528,51 +4528,53 @@
class Library : public Object {
public:
- RawString* name() const { return raw_ptr()->name_; }
+ StringPtr name() const { return raw_ptr()->name_; }
void SetName(const String& name) const;
- RawString* url() const { return raw_ptr()->url_; }
- RawString* private_key() const { return raw_ptr()->private_key_; }
+ StringPtr url() const { return raw_ptr()->url_; }
+ StringPtr private_key() const { return raw_ptr()->private_key_; }
bool LoadNotStarted() const {
- return raw_ptr()->load_state_ == RawLibrary::kAllocated;
+ return raw_ptr()->load_state_ == LibraryLayout::kAllocated;
}
bool LoadRequested() const {
- return raw_ptr()->load_state_ == RawLibrary::kLoadRequested;
+ return raw_ptr()->load_state_ == LibraryLayout::kLoadRequested;
}
bool LoadInProgress() const {
- return raw_ptr()->load_state_ == RawLibrary::kLoadInProgress;
+ return raw_ptr()->load_state_ == LibraryLayout::kLoadInProgress;
}
void SetLoadRequested() const;
void SetLoadInProgress() const;
- bool Loaded() const { return raw_ptr()->load_state_ == RawLibrary::kLoaded; }
+ bool Loaded() const {
+ return raw_ptr()->load_state_ == LibraryLayout::kLoaded;
+ }
void SetLoaded() const;
static intptr_t InstanceSize() {
- return RoundedAllocationSize(sizeof(RawLibrary));
+ return RoundedAllocationSize(sizeof(LibraryLayout));
}
- static RawLibrary* New(const String& url);
+ static LibraryPtr New(const String& url);
- RawObject* Invoke(const String& selector,
- const Array& arguments,
- const Array& argument_names,
- bool respect_reflectable = true,
- bool check_is_entrypoint = false) const;
- RawObject* InvokeGetter(const String& selector,
- bool throw_nsm_if_absent,
- bool respect_reflectable = true,
- bool check_is_entrypoint = false) const;
- RawObject* InvokeSetter(const String& selector,
- const Instance& argument,
- bool respect_reflectable = true,
- bool check_is_entrypoint = false) const;
+ ObjectPtr Invoke(const String& selector,
+ const Array& arguments,
+ const Array& argument_names,
+ bool respect_reflectable = true,
+ bool check_is_entrypoint = false) const;
+ ObjectPtr InvokeGetter(const String& selector,
+ bool throw_nsm_if_absent,
+ bool respect_reflectable = true,
+ bool check_is_entrypoint = false) const;
+ ObjectPtr InvokeSetter(const String& selector,
+ const Instance& argument,
+ bool respect_reflectable = true,
+ bool check_is_entrypoint = false) const;
// Evaluate the given expression as if it appeared in an top-level method of
// this library and return the resulting value, or an error object if
// evaluating the expression fails. The method has the formal (type)
// parameters given in (type_)param_names, and is invoked with the (type)
// argument values given in (type_)param_values.
- RawObject* EvaluateCompiledExpression(
+ ObjectPtr EvaluateCompiledExpression(
const ExternalTypedData& kernel_buffer,
const Array& type_definitions,
const Array& param_values,
@@ -4585,20 +4587,20 @@
// more regular.
void AddClass(const Class& cls) const;
void AddObject(const Object& obj, const String& name) const;
- RawObject* LookupReExport(const String& name,
- ZoneGrowableArray<intptr_t>* visited = NULL) const;
- RawObject* LookupObjectAllowPrivate(const String& name) const;
- RawObject* LookupLocalOrReExportObject(const String& name) const;
- RawObject* LookupImportedObject(const String& name) const;
- RawClass* LookupClass(const String& name) const;
- RawClass* LookupClassAllowPrivate(const String& name) const;
- RawClass* SlowLookupClassAllowMultiPartPrivate(const String& name) const;
- RawClass* LookupLocalClass(const String& name) const;
- RawField* LookupFieldAllowPrivate(const String& name) const;
- RawField* LookupLocalField(const String& name) const;
- RawFunction* LookupFunctionAllowPrivate(const String& name) const;
- RawFunction* LookupLocalFunction(const String& name) const;
- RawLibraryPrefix* LookupLocalLibraryPrefix(const String& name) const;
+ ObjectPtr LookupReExport(const String& name,
+ ZoneGrowableArray<intptr_t>* visited = NULL) const;
+ ObjectPtr LookupObjectAllowPrivate(const String& name) const;
+ ObjectPtr LookupLocalOrReExportObject(const String& name) const;
+ ObjectPtr LookupImportedObject(const String& name) const;
+ ClassPtr LookupClass(const String& name) const;
+ ClassPtr LookupClassAllowPrivate(const String& name) const;
+ ClassPtr SlowLookupClassAllowMultiPartPrivate(const String& name) const;
+ ClassPtr LookupLocalClass(const String& name) const;
+ FieldPtr LookupFieldAllowPrivate(const String& name) const;
+ FieldPtr LookupLocalField(const String& name) const;
+ FunctionPtr LookupFunctionAllowPrivate(const String& name) const;
+ FunctionPtr LookupLocalFunction(const String& name) const;
+ LibraryPrefixPtr LookupLocalLibraryPrefix(const String& name) const;
// Look up a Script based on a url. If 'useResolvedUri' is not provided or is
// false, 'url' should have a 'dart:' scheme for Dart core libraries,
@@ -4606,8 +4608,8 @@
//
// If 'useResolvedUri' is true, 'url' should have a 'org-dartlang-sdk:' scheme
// for Dart core libraries and a 'file:' scheme otherwise.
- RawScript* LookupScript(const String& url, bool useResolvedUri = false) const;
- RawArray* LoadedScripts() const;
+ ScriptPtr LookupScript(const String& url, bool useResolvedUri = false) const;
+ ArrayPtr LoadedScripts() const;
// Resolve name in the scope of this library. First check the cache
// of already resolved names for this library. Then look in the
@@ -4616,7 +4618,7 @@
// If the local dictionary contains no entry for these names,
// look in the scopes of all libraries that are imported
// without a library prefix.
- RawObject* ResolveName(const String& name) const;
+ ObjectPtr ResolveName(const String& name) const;
void AddAnonymousClass(const Class& cls) const;
@@ -4644,8 +4646,8 @@
void CloneMetadataFrom(const Library& from_library,
const Function& from_fun,
const Function& to_fun) const;
- RawObject* GetMetadata(const Object& obj) const;
- RawArray* GetExtendedMetadata(const Object& obj, intptr_t count) const;
+ ObjectPtr GetMetadata(const Object& obj) const;
+ ArrayPtr GetExtendedMetadata(const Object& obj, intptr_t count) const;
// Tries to finds a @pragma annotation on [object].
//
@@ -4663,20 +4665,20 @@
const String& pragma_name,
Object* options);
- RawClass* toplevel_class() const { return raw_ptr()->toplevel_class_; }
+ ClassPtr toplevel_class() const { return raw_ptr()->toplevel_class_; }
void set_toplevel_class(const Class& value) const;
- RawGrowableObjectArray* used_scripts() const {
+ GrowableObjectArrayPtr used_scripts() const {
return raw_ptr()->used_scripts_;
}
// Library imports.
- RawArray* imports() const { return raw_ptr()->imports_; }
- RawArray* exports() const { return raw_ptr()->exports_; }
+ ArrayPtr imports() const { return raw_ptr()->imports_; }
+ ArrayPtr exports() const { return raw_ptr()->exports_; }
void AddImport(const Namespace& ns) const;
intptr_t num_imports() const { return raw_ptr()->num_imports_; }
- RawNamespace* ImportAt(intptr_t index) const;
- RawLibrary* ImportLibraryAt(intptr_t index) const;
+ NamespacePtr ImportAt(intptr_t index) const;
+ LibraryPtr ImportLibraryAt(intptr_t index) const;
void DropDependenciesAndCaches() const;
@@ -4697,17 +4699,18 @@
}
bool is_in_fullsnapshot() const {
- return RawLibrary::InFullSnapshotBit::decode(raw_ptr()->flags_);
+ return LibraryLayout::InFullSnapshotBit::decode(raw_ptr()->flags_);
}
void set_is_in_fullsnapshot(bool value) const {
- set_flags(RawLibrary::InFullSnapshotBit::update(value, raw_ptr()->flags_));
+ set_flags(
+ LibraryLayout::InFullSnapshotBit::update(value, raw_ptr()->flags_));
}
bool is_nnbd() const {
- return RawLibrary::NnbdBit::decode(raw_ptr()->flags_);
+ return LibraryLayout::NnbdBit::decode(raw_ptr()->flags_);
}
void set_is_nnbd(bool value) const {
- set_flags(RawLibrary::NnbdBit::update(value, raw_ptr()->flags_));
+ set_flags(LibraryLayout::NnbdBit::update(value, raw_ptr()->flags_));
}
NNBDMode nnbd_mode() const {
@@ -4716,14 +4719,14 @@
NNBDCompiledMode nnbd_compiled_mode() const {
return static_cast<NNBDCompiledMode>(
- RawLibrary::NnbdCompiledModeBits::decode(raw_ptr()->flags_));
+ LibraryLayout::NnbdCompiledModeBits::decode(raw_ptr()->flags_));
}
void set_nnbd_compiled_mode(NNBDCompiledMode value) const {
- set_flags(RawLibrary::NnbdCompiledModeBits::update(
+ set_flags(LibraryLayout::NnbdCompiledModeBits::update(
static_cast<uint8_t>(value), raw_ptr()->flags_));
}
- RawString* PrivateName(const String& name) const;
+ StringPtr PrivateName(const String& name) const;
intptr_t index() const { return raw_ptr()->index_; }
void set_index(intptr_t value) const {
@@ -4735,17 +4738,17 @@
const GrowableObjectArray& libs);
bool IsDebuggable() const {
- return RawLibrary::DebuggableBit::decode(raw_ptr()->flags_);
+ return LibraryLayout::DebuggableBit::decode(raw_ptr()->flags_);
}
void set_debuggable(bool value) const {
- set_flags(RawLibrary::DebuggableBit::update(value, raw_ptr()->flags_));
+ set_flags(LibraryLayout::DebuggableBit::update(value, raw_ptr()->flags_));
}
bool is_dart_scheme() const {
- return RawLibrary::DartSchemeBit::decode(raw_ptr()->flags_);
+ return LibraryLayout::DartSchemeBit::decode(raw_ptr()->flags_);
}
void set_is_dart_scheme(bool value) const {
- set_flags(RawLibrary::DartSchemeBit::update(value, raw_ptr()->flags_));
+ set_flags(LibraryLayout::DartSchemeBit::update(value, raw_ptr()->flags_));
}
// Includes 'dart:async', 'dart:typed_data', etc.
@@ -4753,18 +4756,18 @@
inline intptr_t UrlHash() const;
- RawExternalTypedData* kernel_data() const { return raw_ptr()->kernel_data_; }
+ ExternalTypedDataPtr kernel_data() const { return raw_ptr()->kernel_data_; }
void set_kernel_data(const ExternalTypedData& data) const;
#if !defined(DART_PRECOMPILED_RUNTIME)
intptr_t binary_declaration_offset() const {
- return RawLibrary::BinaryDeclarationOffset::decode(
+ return LibraryLayout::BinaryDeclarationOffset::decode(
raw_ptr()->binary_declaration_);
}
void set_binary_declaration_offset(intptr_t value) const {
ASSERT(value >= 0);
StoreNonPointer(&raw_ptr()->binary_declaration_,
- RawLibrary::BinaryDeclarationOffset::update(
+ LibraryLayout::BinaryDeclarationOffset::update(
value, raw_ptr()->binary_declaration_));
}
#endif // !defined(DART_PRECOMPILED_RUNTIME)
@@ -4809,7 +4812,7 @@
#if defined(DART_PRECOMPILED_RUNTIME)
return false;
#else
- return RawLibrary::IsDeclaredInBytecode::decode(
+ return LibraryLayout::IsDeclaredInBytecode::decode(
raw_ptr()->binary_declaration_);
#endif
}
@@ -4817,42 +4820,42 @@
#if !defined(DART_PRECOMPILED_RUNTIME)
void set_is_declared_in_bytecode(bool value) const {
StoreNonPointer(&raw_ptr()->binary_declaration_,
- RawLibrary::IsDeclaredInBytecode::update(
+ LibraryLayout::IsDeclaredInBytecode::update(
value, raw_ptr()->binary_declaration_));
}
#endif // !defined(DART_PRECOMPILED_RUNTIME)
- static RawLibrary* LookupLibrary(Thread* thread, const String& url);
- static RawLibrary* GetLibrary(intptr_t index);
+ static LibraryPtr LookupLibrary(Thread* thread, const String& url);
+ static LibraryPtr GetLibrary(intptr_t index);
static void InitCoreLibrary(Isolate* isolate);
static void InitNativeWrappersLibrary(Isolate* isolate, bool is_kernel_file);
- static RawLibrary* AsyncLibrary();
- static RawLibrary* ConvertLibrary();
- static RawLibrary* CoreLibrary();
- static RawLibrary* CollectionLibrary();
- static RawLibrary* DeveloperLibrary();
- static RawLibrary* FfiLibrary();
- static RawLibrary* InternalLibrary();
- static RawLibrary* IsolateLibrary();
- static RawLibrary* MathLibrary();
+ static LibraryPtr AsyncLibrary();
+ static LibraryPtr ConvertLibrary();
+ static LibraryPtr CoreLibrary();
+ static LibraryPtr CollectionLibrary();
+ static LibraryPtr DeveloperLibrary();
+ static LibraryPtr FfiLibrary();
+ static LibraryPtr InternalLibrary();
+ static LibraryPtr IsolateLibrary();
+ static LibraryPtr MathLibrary();
#if !defined(DART_PRECOMPILED_RUNTIME)
- static RawLibrary* MirrorsLibrary();
+ static LibraryPtr MirrorsLibrary();
#endif
- static RawLibrary* NativeWrappersLibrary();
- static RawLibrary* ProfilerLibrary();
- static RawLibrary* TypedDataLibrary();
- static RawLibrary* VMServiceLibrary();
- static RawLibrary* WasmLibrary();
+ static LibraryPtr NativeWrappersLibrary();
+ static LibraryPtr ProfilerLibrary();
+ static LibraryPtr TypedDataLibrary();
+ static LibraryPtr VMServiceLibrary();
+ static LibraryPtr WasmLibrary();
// Eagerly compile all classes and functions in the library.
- static RawError* CompileAll(bool ignore_error = false);
+ static ErrorPtr CompileAll(bool ignore_error = false);
#if !defined(DART_PRECOMPILED_RUNTIME)
// Finalize all classes in all libraries.
- static RawError* FinalizeAllClasses();
+ static ErrorPtr FinalizeAllClasses();
// Eagerly read all bytecode.
- static RawError* ReadAllBytecode();
+ static ErrorPtr ReadAllBytecode();
#endif
#if defined(DEBUG) && !defined(DART_PRECOMPILED_RUNTIME)
@@ -4871,12 +4874,12 @@
// Lookup class in the core lib which also contains various VM
// helper methods and classes. Allow look up of private classes.
- static RawClass* LookupCoreClass(const String& class_name);
+ static ClassPtr LookupCoreClass(const String& class_name);
// Return Function::null() if function does not exist in libs.
- static RawFunction* GetFunction(const GrowableArray<Library*>& libs,
- const char* class_name,
- const char* function_name);
+ static FunctionPtr GetFunction(const GrowableArray<Library*>& libs,
+ const char* class_name,
+ const char* function_name);
// Character used to indicate a private identifier.
static const char kPrivateIdentifierStart = '_';
@@ -4891,7 +4894,7 @@
// Returns a closure of top level function 'name' in the exported namespace
// of this library. If a top level function 'name' does not exist we look
// for a top level getter 'name' that returns a closure.
- RawObject* GetFunctionClosure(const String& name) const;
+ ObjectPtr GetFunctionClosure(const String& name) const;
// Ensures that all top-level functions and variables (fields) are loaded.
void EnsureTopLevelClassIsFinalized() const;
@@ -4900,7 +4903,7 @@
static const int kInitialImportsCapacity = 4;
static const int kImportsCapacityIncrement = 8;
- static RawLibrary* New();
+ static LibraryPtr New();
// These methods are only used by the Precompiler to obfuscate
// the name and url.
@@ -4910,13 +4913,13 @@
void set_num_imports(intptr_t value) const;
void set_flags(uint8_t flags) const;
bool HasExports() const;
- RawArray* loaded_scripts() const { return raw_ptr()->loaded_scripts_; }
- RawGrowableObjectArray* metadata() const { return raw_ptr()->metadata_; }
+ ArrayPtr loaded_scripts() const { return raw_ptr()->loaded_scripts_; }
+ GrowableObjectArrayPtr metadata() const { return raw_ptr()->metadata_; }
void set_metadata(const GrowableObjectArray& value) const;
- RawArray* dictionary() const { return raw_ptr()->dictionary_; }
+ ArrayPtr dictionary() const { return raw_ptr()->dictionary_; }
void InitClassDictionary() const;
- RawArray* resolved_names() const { return raw_ptr()->resolved_names_; }
+ ArrayPtr resolved_names() const { return raw_ptr()->resolved_names_; }
bool LookupResolvedNamesCache(const String& name, Object* obj) const;
void AddToResolvedNamesCache(const String& name, const Object& obj) const;
void InitResolvedNamesCache() const;
@@ -4924,7 +4927,7 @@
void InvalidateResolvedName(const String& name) const;
void InvalidateResolvedNamesCache() const;
- RawArray* exported_names() const { return raw_ptr()->exported_names_; }
+ ArrayPtr exported_names() const { return raw_ptr()->exported_names_; }
bool LookupExportedNamesCache(const String& name, Object* obj) const;
void AddToExportedNamesCache(const String& name, const Object& obj) const;
void InitExportedNamesCache() const;
@@ -4933,15 +4936,15 @@
void InitImportList() const;
void RehashDictionary(const Array& old_dict, intptr_t new_dict_size) const;
- static RawLibrary* NewLibraryHelper(const String& url, bool import_core_lib);
- RawObject* LookupEntry(const String& name, intptr_t* index) const;
- RawObject* LookupLocalObjectAllowPrivate(const String& name) const;
- RawObject* LookupLocalObject(const String& name) const;
+ static LibraryPtr NewLibraryHelper(const String& url, bool import_core_lib);
+ ObjectPtr LookupEntry(const String& name, intptr_t* index) const;
+ ObjectPtr LookupLocalObjectAllowPrivate(const String& name) const;
+ ObjectPtr LookupLocalObject(const String& name) const;
void AllocatePrivateKey() const;
- RawString* MakeMetadataName(const Object& obj) const;
- RawField* GetMetadataField(const String& metaname) const;
+ StringPtr MakeMetadataName(const Object& obj) const;
+ FieldPtr GetMetadataField(const String& metaname) const;
void AddMetadata(const Object& owner,
const String& name,
TokenPosition token_pos,
@@ -4965,31 +4968,31 @@
// the show/hide combinators.
class Namespace : public Object {
public:
- RawLibrary* library() const { return raw_ptr()->library_; }
- RawArray* show_names() const { return raw_ptr()->show_names_; }
- RawArray* hide_names() const { return raw_ptr()->hide_names_; }
+ LibraryPtr library() const { return raw_ptr()->library_; }
+ ArrayPtr show_names() const { return raw_ptr()->show_names_; }
+ ArrayPtr hide_names() const { return raw_ptr()->hide_names_; }
void AddMetadata(const Object& owner,
TokenPosition token_pos,
intptr_t kernel_offset = 0);
- RawObject* GetMetadata() const;
+ ObjectPtr GetMetadata() const;
static intptr_t InstanceSize() {
- return RoundedAllocationSize(sizeof(RawNamespace));
+ return RoundedAllocationSize(sizeof(NamespaceLayout));
}
bool HidesName(const String& name) const;
- RawObject* Lookup(const String& name,
- ZoneGrowableArray<intptr_t>* trail = NULL) const;
+ ObjectPtr Lookup(const String& name,
+ ZoneGrowableArray<intptr_t>* trail = NULL) const;
- static RawNamespace* New(const Library& library,
- const Array& show_names,
- const Array& hide_names);
+ static NamespacePtr New(const Library& library,
+ const Array& show_names,
+ const Array& hide_names);
private:
- static RawNamespace* New();
+ static NamespacePtr New();
- RawField* metadata_field() const { return raw_ptr()->metadata_field_; }
+ FieldPtr metadata_field() const { return raw_ptr()->metadata_field_; }
void set_metadata_field(const Field& value) const;
FINAL_HEAP_OBJECT_IMPLEMENTATION(Namespace, Object);
@@ -4999,46 +5002,46 @@
class KernelProgramInfo : public Object {
public:
- static RawKernelProgramInfo* New(const TypedData& string_offsets,
- const ExternalTypedData& string_data,
- const TypedData& canonical_names,
- const ExternalTypedData& metadata_payload,
- const ExternalTypedData& metadata_mappings,
- const ExternalTypedData& constants_table,
- const Array& scripts,
- const Array& libraries_cache,
- const Array& classes_cache,
- const Object& retained_kernel_blob,
- const uint32_t binary_version);
+ static KernelProgramInfoPtr New(const TypedData& string_offsets,
+ const ExternalTypedData& string_data,
+ const TypedData& canonical_names,
+ const ExternalTypedData& metadata_payload,
+ const ExternalTypedData& metadata_mappings,
+ const ExternalTypedData& constants_table,
+ const Array& scripts,
+ const Array& libraries_cache,
+ const Array& classes_cache,
+ const Object& retained_kernel_blob,
+ const uint32_t binary_version);
static intptr_t InstanceSize() {
- return RoundedAllocationSize(sizeof(RawKernelProgramInfo));
+ return RoundedAllocationSize(sizeof(KernelProgramInfoLayout));
}
- RawTypedData* string_offsets() const { return raw_ptr()->string_offsets_; }
+ TypedDataPtr string_offsets() const { return raw_ptr()->string_offsets_; }
- RawExternalTypedData* string_data() const { return raw_ptr()->string_data_; }
+ ExternalTypedDataPtr string_data() const { return raw_ptr()->string_data_; }
- RawTypedData* canonical_names() const { return raw_ptr()->canonical_names_; }
+ TypedDataPtr canonical_names() const { return raw_ptr()->canonical_names_; }
- RawExternalTypedData* metadata_payloads() const {
+ ExternalTypedDataPtr metadata_payloads() const {
return raw_ptr()->metadata_payloads_;
}
- RawExternalTypedData* metadata_mappings() const {
+ ExternalTypedDataPtr metadata_mappings() const {
return raw_ptr()->metadata_mappings_;
}
- RawExternalTypedData* constants_table() const {
+ ExternalTypedDataPtr constants_table() const {
return raw_ptr()->constants_table_;
}
void set_constants_table(const ExternalTypedData& value) const;
- RawArray* scripts() const { return raw_ptr()->scripts_; }
+ ArrayPtr scripts() const { return raw_ptr()->scripts_; }
void set_scripts(const Array& scripts) const;
- RawArray* constants() const { return raw_ptr()->constants_; }
+ ArrayPtr constants() const { return raw_ptr()->constants_; }
void set_constants(const Array& constants) const;
uint32_t kernel_binary_version() const {
@@ -5051,40 +5054,38 @@
// (since native names are encoded as constants).
//
// This array will hold the functions which might need their native name set.
- RawGrowableObjectArray* potential_natives() const {
+ GrowableObjectArrayPtr potential_natives() const {
return raw_ptr()->potential_natives_;
}
void set_potential_natives(const GrowableObjectArray& candidates) const;
- RawGrowableObjectArray* potential_pragma_functions() const {
+ GrowableObjectArrayPtr potential_pragma_functions() const {
return raw_ptr()->potential_pragma_functions_;
}
void set_potential_pragma_functions(
const GrowableObjectArray& candidates) const;
- RawScript* ScriptAt(intptr_t index) const;
+ ScriptPtr ScriptAt(intptr_t index) const;
- RawArray* libraries_cache() const { return raw_ptr()->libraries_cache_; }
+ ArrayPtr libraries_cache() const { return raw_ptr()->libraries_cache_; }
void set_libraries_cache(const Array& cache) const;
- RawLibrary* LookupLibrary(Thread* thread, const Smi& name_index) const;
- RawLibrary* InsertLibrary(Thread* thread,
- const Smi& name_index,
- const Library& lib) const;
+ LibraryPtr LookupLibrary(Thread* thread, const Smi& name_index) const;
+ LibraryPtr InsertLibrary(Thread* thread,
+ const Smi& name_index,
+ const Library& lib) const;
- RawArray* classes_cache() const { return raw_ptr()->classes_cache_; }
+ ArrayPtr classes_cache() const { return raw_ptr()->classes_cache_; }
void set_classes_cache(const Array& cache) const;
- RawClass* LookupClass(Thread* thread, const Smi& name_index) const;
- RawClass* InsertClass(Thread* thread,
- const Smi& name_index,
- const Class& klass) const;
+ ClassPtr LookupClass(Thread* thread, const Smi& name_index) const;
+ ClassPtr InsertClass(Thread* thread,
+ const Smi& name_index,
+ const Class& klass) const;
- RawArray* bytecode_component() const {
- return raw_ptr()->bytecode_component_;
- }
+ ArrayPtr bytecode_component() const { return raw_ptr()->bytecode_component_; }
void set_bytecode_component(const Array& bytecode_component) const;
private:
- static RawKernelProgramInfo* New();
+ static KernelProgramInfoPtr New();
FINAL_HEAP_OBJECT_IMPLEMENTATION(KernelProgramInfo, Object);
friend class Class;
@@ -5117,21 +5118,23 @@
StoreNonPointer(&raw_ptr()->length_, value);
}
- static intptr_t length_offset() { return OFFSET_OF(RawObjectPool, length_); }
+ static intptr_t length_offset() {
+ return OFFSET_OF(ObjectPoolLayout, length_);
+ }
static intptr_t data_offset() {
- return OFFSET_OF_RETURNED_VALUE(RawObjectPool, data);
+ return OFFSET_OF_RETURNED_VALUE(ObjectPoolLayout, data);
}
static intptr_t element_offset(intptr_t index) {
- return OFFSET_OF_RETURNED_VALUE(RawObjectPool, data) +
- sizeof(RawObjectPool::Entry) * index;
+ return OFFSET_OF_RETURNED_VALUE(ObjectPoolLayout, data) +
+ sizeof(ObjectPoolLayout::Entry) * index;
}
- struct ArrayLayout {
+ struct ArrayTraits {
static intptr_t elements_start_offset() {
return ObjectPool::data_offset();
}
- static constexpr intptr_t kElementSize = sizeof(RawObjectPool::Entry);
+ static constexpr intptr_t kElementSize = sizeof(ObjectPoolLayout::Entry);
};
EntryType TypeAt(intptr_t index) const {
@@ -5148,7 +5151,7 @@
StoreNonPointer(&raw_ptr()->entry_bits()[index], bits);
}
- RawObject* ObjectAt(intptr_t index) const {
+ ObjectPtr ObjectAt(intptr_t index) const {
ASSERT((TypeAt(index) == EntryType::kTaggedObject) ||
(TypeAt(index) == EntryType::kNativeEntryData));
return EntryAddr(index)->raw_obj_;
@@ -5170,36 +5173,37 @@
}
static intptr_t InstanceSize() {
- ASSERT(sizeof(RawObjectPool) ==
- OFFSET_OF_RETURNED_VALUE(RawObjectPool, data));
+ ASSERT(sizeof(ObjectPoolLayout) ==
+ OFFSET_OF_RETURNED_VALUE(ObjectPoolLayout, data));
return 0;
}
static const intptr_t kBytesPerElement =
- sizeof(RawObjectPool::Entry) + sizeof(uint8_t);
+ sizeof(ObjectPoolLayout::Entry) + sizeof(uint8_t);
static const intptr_t kMaxElements = kSmiMax / kBytesPerElement;
static intptr_t InstanceSize(intptr_t len) {
// Ensure that variable length data is not adding to the object length.
- ASSERT(sizeof(RawObjectPool) == (sizeof(RawObject) + (1 * kWordSize)));
+ ASSERT(sizeof(ObjectPoolLayout) ==
+ (sizeof(ObjectLayout) + (1 * kWordSize)));
ASSERT(0 <= len && len <= kMaxElements);
- return RoundedAllocationSize(sizeof(RawObjectPool) +
+ return RoundedAllocationSize(sizeof(ObjectPoolLayout) +
(len * kBytesPerElement));
}
- static RawObjectPool* NewFromBuilder(
+ static ObjectPoolPtr NewFromBuilder(
const compiler::ObjectPoolBuilder& builder);
- static RawObjectPool* New(intptr_t len);
+ static ObjectPoolPtr New(intptr_t len);
void CopyInto(compiler::ObjectPoolBuilder* builder) const;
- // Returns the pool index from the offset relative to a tagged RawObjectPool*,
+ // Returns the pool index from the offset relative to a tagged ObjectPoolPtr,
// adjusting for the tag-bit.
static intptr_t IndexFromOffset(intptr_t offset) {
ASSERT(
Utils::IsAligned(offset + kHeapObjectTag, compiler::target::kWordSize));
return (offset + kHeapObjectTag - data_offset()) /
- sizeof(RawObjectPool::Entry);
+ sizeof(ObjectPoolLayout::Entry);
}
static intptr_t OffsetFromIndex(intptr_t index) {
@@ -5209,7 +5213,7 @@
void DebugPrint() const;
private:
- RawObjectPool::Entry const* EntryAddr(intptr_t index) const {
+ ObjectPoolLayout::Entry const* EntryAddr(intptr_t index) const {
ASSERT((index >= 0) && (index < Length()));
return &raw_ptr()->data()[index];
}
@@ -5217,7 +5221,7 @@
FINAL_HEAP_OBJECT_IMPLEMENTATION(ObjectPool, Object);
friend class Class;
friend class Object;
- friend class RawObjectPool;
+ friend class ObjectPoolLayout;
};
class Instructions : public Object {
@@ -5234,21 +5238,21 @@
// Excludes HeaderSize().
intptr_t Size() const { return SizeBits::decode(raw_ptr()->size_and_flags_); }
- static intptr_t Size(const RawInstructions* instr) {
+ static intptr_t Size(const InstructionsPtr instr) {
return SizeBits::decode(instr->ptr()->size_and_flags_);
}
bool HasMonomorphicEntry() const {
return FlagsBits::decode(raw_ptr()->size_and_flags_);
}
- static bool HasMonomorphicEntry(const RawInstructions* instr) {
+ static bool HasMonomorphicEntry(const InstructionsPtr instr) {
return FlagsBits::decode(instr->ptr()->size_and_flags_);
}
uword PayloadStart() const { return PayloadStart(raw()); }
uword MonomorphicEntryPoint() const { return MonomorphicEntryPoint(raw()); }
uword EntryPoint() const { return EntryPoint(raw()); }
- static uword PayloadStart(const RawInstructions* instr) {
+ static uword PayloadStart(const InstructionsPtr instr) {
return reinterpret_cast<uword>(instr->ptr()) + HeaderSize();
}
@@ -5278,7 +5282,7 @@
#error Missing entry offsets for current architecture
#endif
- static uword MonomorphicEntryPoint(const RawInstructions* instr) {
+ static uword MonomorphicEntryPoint(const InstructionsPtr instr) {
uword entry = PayloadStart(instr);
if (HasMonomorphicEntry(instr)) {
entry += !FLAG_precompiled_mode ? kMonomorphicEntryOffsetJIT
@@ -5287,7 +5291,7 @@
return entry;
}
- static uword EntryPoint(const RawInstructions* instr) {
+ static uword EntryPoint(const InstructionsPtr instr) {
uword entry = PayloadStart(instr);
if (HasMonomorphicEntry(instr)) {
entry += !FLAG_precompiled_mode ? kPolymorphicEntryOffsetJIT
@@ -5297,12 +5301,12 @@
}
static const intptr_t kMaxElements =
- (kMaxInt32 - (sizeof(RawInstructions) + sizeof(RawObject) +
+ (kMaxInt32 - (sizeof(InstructionsLayout) + sizeof(ObjectLayout) +
(2 * kMaxObjectAlignment)));
static intptr_t InstanceSize() {
- ASSERT(sizeof(RawInstructions) ==
- OFFSET_OF_RETURNED_VALUE(RawInstructions, data));
+ ASSERT(sizeof(InstructionsLayout) ==
+ OFFSET_OF_RETURNED_VALUE(InstructionsLayout, data));
return 0;
}
@@ -5311,19 +5315,19 @@
}
static intptr_t HeaderSize() {
- return Utils::RoundUp(sizeof(RawInstructions), kWordSize);
+ return Utils::RoundUp(sizeof(InstructionsLayout), kWordSize);
}
- static RawInstructions* FromPayloadStart(uword payload_start) {
- return reinterpret_cast<RawInstructions*>(payload_start - HeaderSize() +
- kHeapObjectTag);
+ static InstructionsPtr FromPayloadStart(uword payload_start) {
+ return static_cast<InstructionsPtr>(payload_start - HeaderSize() +
+ kHeapObjectTag);
}
bool Equals(const Instructions& other) const {
return Equals(raw(), other.raw());
}
- static bool Equals(RawInstructions* a, RawInstructions* b) {
+ static bool Equals(InstructionsPtr a, InstructionsPtr b) {
if (Size(a) != Size(b)) return false;
NoSafepointScope no_safepoint;
return memcmp(a->ptr(), b->ptr(), InstanceSize(Size(a))) == 0;
@@ -5348,7 +5352,7 @@
// only be created using the Code::FinalizeCode method. This method creates
// the RawInstruction and RawCode objects, sets up the pointer offsets
// and links the two in a GC safe manner.
- static RawInstructions* New(intptr_t size, bool has_monomorphic_entry);
+ static InstructionsPtr New(intptr_t size, bool has_monomorphic_entry);
FINAL_HEAP_OBJECT_IMPLEMENTATION(Instructions, Object);
friend class Class;
@@ -5364,12 +5368,12 @@
public:
// Excludes HeaderSize().
intptr_t Size() const { return raw_ptr()->payload_length_; }
- static intptr_t Size(const RawInstructionsSection* instr) {
+ static intptr_t Size(const InstructionsSectionPtr instr) {
return instr->ptr()->payload_length_;
}
static intptr_t InstanceSize() {
- ASSERT(sizeof(RawInstructionsSection) ==
- OFFSET_OF_RETURNED_VALUE(RawInstructionsSection, data));
+ ASSERT(sizeof(InstructionsSectionLayout) ==
+ OFFSET_OF_RETURNED_VALUE(InstructionsSectionLayout, data));
return 0;
}
@@ -5378,7 +5382,7 @@
}
static intptr_t HeaderSize() {
- return Utils::RoundUp(sizeof(RawInstructionsSection), kWordSize);
+ return Utils::RoundUp(sizeof(InstructionsSectionLayout), kWordSize);
}
private:
@@ -5390,34 +5394,35 @@
public:
intptr_t Length() const;
- RawString* GetName(intptr_t var_index) const;
+ StringPtr GetName(intptr_t var_index) const;
void SetVar(intptr_t var_index,
const String& name,
- RawLocalVarDescriptors::VarInfo* info) const;
+ LocalVarDescriptorsLayout::VarInfo* info) const;
- void GetInfo(intptr_t var_index, RawLocalVarDescriptors::VarInfo* info) const;
+ void GetInfo(intptr_t var_index,
+ LocalVarDescriptorsLayout::VarInfo* info) const;
static const intptr_t kBytesPerElement =
- sizeof(RawLocalVarDescriptors::VarInfo);
- static const intptr_t kMaxElements = RawLocalVarDescriptors::kMaxIndex;
+ sizeof(LocalVarDescriptorsLayout::VarInfo);
+ static const intptr_t kMaxElements = LocalVarDescriptorsLayout::kMaxIndex;
static intptr_t InstanceSize() {
- ASSERT(sizeof(RawLocalVarDescriptors) ==
- OFFSET_OF_RETURNED_VALUE(RawLocalVarDescriptors, names));
+ ASSERT(sizeof(LocalVarDescriptorsLayout) ==
+ OFFSET_OF_RETURNED_VALUE(LocalVarDescriptorsLayout, names));
return 0;
}
static intptr_t InstanceSize(intptr_t len) {
ASSERT(0 <= len && len <= kMaxElements);
return RoundedAllocationSize(
- sizeof(RawLocalVarDescriptors) +
+ sizeof(LocalVarDescriptorsLayout) +
(len * kWordSize) // RawStrings for names.
- + (len * sizeof(RawLocalVarDescriptors::VarInfo)));
+ + (len * sizeof(LocalVarDescriptorsLayout::VarInfo)));
}
- static RawLocalVarDescriptors* New(intptr_t num_variables);
+ static LocalVarDescriptorsPtr New(intptr_t num_variables);
- static const char* KindToCString(RawLocalVarDescriptors::VarInfoKind kind);
+ static const char* KindToCString(LocalVarDescriptorsLayout::VarInfoKind kind);
private:
FINAL_HEAP_OBJECT_IMPLEMENTATION(LocalVarDescriptors, Object);
@@ -5430,15 +5435,15 @@
static const intptr_t kBytesPerElement = 1;
static const intptr_t kMaxElements = kMaxInt32 / kBytesPerElement;
- static intptr_t UnroundedSize(RawPcDescriptors* desc) {
+ static intptr_t UnroundedSize(PcDescriptorsPtr desc) {
return UnroundedSize(desc->ptr()->length_);
}
static intptr_t UnroundedSize(intptr_t len) {
- return sizeof(RawPcDescriptors) + len;
+ return sizeof(PcDescriptorsLayout) + len;
}
static intptr_t InstanceSize() {
- ASSERT(sizeof(RawPcDescriptors) ==
- OFFSET_OF_RETURNED_VALUE(RawPcDescriptors, data));
+ ASSERT(sizeof(PcDescriptorsLayout) ==
+ OFFSET_OF_RETURNED_VALUE(PcDescriptorsLayout, data));
return 0;
}
static intptr_t InstanceSize(intptr_t len) {
@@ -5446,7 +5451,7 @@
return RoundedAllocationSize(UnroundedSize(len));
}
- static RawPcDescriptors* New(GrowableArray<uint8_t>* delta_encoded_data);
+ static PcDescriptorsPtr New(GrowableArray<uint8_t>* delta_encoded_data);
// Verify (assert) assumptions about pc descriptors in debug mode.
void Verify(const Function& function) const;
@@ -5463,7 +5468,7 @@
// We would have a VisitPointers function here to traverse the
// pc descriptors table to visit objects if any in the table.
- // Note: never return a reference to a RawPcDescriptors::PcDescriptorRec
+ // Note: never return a reference to a PcDescriptorsLayout::PcDescriptorRec
// as the object can move.
class Iterator : ValueObject {
public:
@@ -5476,7 +5481,7 @@
cur_deopt_id_(0),
cur_token_pos_(0),
cur_try_index_(0),
- cur_yield_index_(RawPcDescriptors::kInvalidYieldIndex) {}
+ cur_yield_index_(PcDescriptorsLayout::kInvalidYieldIndex) {}
bool MoveNext() {
// Moves to record that matches kind_mask_.
@@ -5484,11 +5489,12 @@
const int32_t kind_and_metadata =
descriptors_.DecodeInteger(&byte_index_);
cur_kind_ =
- RawPcDescriptors::KindAndMetadata::DecodeKind(kind_and_metadata);
- cur_try_index_ = RawPcDescriptors::KindAndMetadata::DecodeTryIndex(
+ PcDescriptorsLayout::KindAndMetadata::DecodeKind(kind_and_metadata);
+ cur_try_index_ = PcDescriptorsLayout::KindAndMetadata::DecodeTryIndex(
kind_and_metadata);
- cur_yield_index_ = RawPcDescriptors::KindAndMetadata::DecodeYieldIndex(
- kind_and_metadata);
+ cur_yield_index_ =
+ PcDescriptorsLayout::KindAndMetadata::DecodeYieldIndex(
+ kind_and_metadata);
cur_pc_offset_ += descriptors_.DecodeInteger(&byte_index_);
@@ -5509,8 +5515,8 @@
TokenPosition TokenPos() const { return TokenPosition(cur_token_pos_); }
intptr_t TryIndex() const { return cur_try_index_; }
intptr_t YieldIndex() const { return cur_yield_index_; }
- RawPcDescriptors::Kind Kind() const {
- return static_cast<RawPcDescriptors::Kind>(cur_kind_);
+ PcDescriptorsLayout::Kind Kind() const {
+ return static_cast<PcDescriptorsLayout::Kind>(cur_kind_);
}
private:
@@ -5551,9 +5557,9 @@
}
private:
- static const char* KindAsStr(RawPcDescriptors::Kind kind);
+ static const char* KindAsStr(PcDescriptorsLayout::Kind kind);
- static RawPcDescriptors* New(intptr_t length);
+ static PcDescriptorsPtr New(intptr_t length);
void SetLength(intptr_t value) const;
void CopyData(GrowableArray<uint8_t>* data);
@@ -5568,15 +5574,15 @@
static const intptr_t kBytesPerElement = 1;
static const intptr_t kMaxElements = kMaxInt32 / kBytesPerElement;
- static intptr_t UnroundedSize(RawCodeSourceMap* map) {
+ static intptr_t UnroundedSize(CodeSourceMapPtr map) {
return UnroundedSize(map->ptr()->length_);
}
static intptr_t UnroundedSize(intptr_t len) {
- return sizeof(RawCodeSourceMap) + len;
+ return sizeof(CodeSourceMapLayout) + len;
}
static intptr_t InstanceSize() {
- ASSERT(sizeof(RawCodeSourceMap) ==
- OFFSET_OF_RETURNED_VALUE(RawCodeSourceMap, data));
+ ASSERT(sizeof(CodeSourceMapLayout) ==
+ OFFSET_OF_RETURNED_VALUE(CodeSourceMapLayout, data));
return 0;
}
static intptr_t InstanceSize(intptr_t len) {
@@ -5584,7 +5590,7 @@
return RoundedAllocationSize(UnroundedSize(len));
}
- static RawCodeSourceMap* New(intptr_t length);
+ static CodeSourceMapPtr New(intptr_t length);
intptr_t Length() const { return raw_ptr()->length_; }
uint8_t* Data() const {
@@ -5614,8 +5620,8 @@
static const intptr_t kHashBits = 30;
uintptr_t payload_size() const { return PayloadSizeOf(raw()); }
- static uintptr_t PayloadSizeOf(const RawCompressedStackMaps* raw) {
- return RawCompressedStackMaps::SizeField::decode(
+ static uintptr_t PayloadSizeOf(const CompressedStackMapsPtr raw) {
+ return CompressedStackMapsLayout::SizeField::decode(
raw->ptr()->flags_and_size_);
}
@@ -5633,15 +5639,15 @@
bool Equals(const CompressedStackMaps* other) const { return Equals(*other); }
intptr_t Hashcode() const;
- static intptr_t UnroundedSize(RawCompressedStackMaps* maps) {
+ static intptr_t UnroundedSize(CompressedStackMapsPtr maps) {
return UnroundedSize(CompressedStackMaps::PayloadSizeOf(maps));
}
static intptr_t UnroundedSize(intptr_t length) {
- return sizeof(RawCompressedStackMaps) + length;
+ return sizeof(CompressedStackMapsLayout) + length;
}
static intptr_t InstanceSize() {
- ASSERT(sizeof(RawCompressedStackMaps) ==
- OFFSET_OF_RETURNED_VALUE(RawCompressedStackMaps, data));
+ ASSERT(sizeof(CompressedStackMapsLayout) ==
+ OFFSET_OF_RETURNED_VALUE(CompressedStackMapsLayout, data));
return 0;
}
static intptr_t InstanceSize(intptr_t length) {
@@ -5649,35 +5655,35 @@
}
bool UsesGlobalTable() const { return !IsNull() && UsesGlobalTable(raw()); }
- static bool UsesGlobalTable(const RawCompressedStackMaps* raw) {
- return RawCompressedStackMaps::UsesTableBit::decode(
+ static bool UsesGlobalTable(const CompressedStackMapsPtr raw) {
+ return CompressedStackMapsLayout::UsesTableBit::decode(
raw->ptr()->flags_and_size_);
}
bool IsGlobalTable() const { return !IsNull() && IsGlobalTable(raw()); }
- static bool IsGlobalTable(const RawCompressedStackMaps* raw) {
- return RawCompressedStackMaps::GlobalTableBit::decode(
+ static bool IsGlobalTable(const CompressedStackMapsPtr raw) {
+ return CompressedStackMapsLayout::GlobalTableBit::decode(
raw->ptr()->flags_and_size_);
}
- static RawCompressedStackMaps* NewInlined(
+ static CompressedStackMapsPtr NewInlined(
const GrowableArray<uint8_t>& bytes) {
return New(bytes, /*is_global_table=*/false, /*uses_global_table=*/false);
}
- static RawCompressedStackMaps* NewUsingTable(
+ static CompressedStackMapsPtr NewUsingTable(
const GrowableArray<uint8_t>& bytes) {
return New(bytes, /*is_global_table=*/false, /*uses_global_table=*/true);
}
- static RawCompressedStackMaps* NewGlobalTable(
+ static CompressedStackMapsPtr NewGlobalTable(
const GrowableArray<uint8_t>& bytes) {
return New(bytes, /*is_global_table=*/true, /*uses_global_table=*/false);
}
private:
- static RawCompressedStackMaps* New(const GrowableArray<uint8_t>& bytes,
- bool is_global_table,
- bool uses_global_table);
+ static CompressedStackMapsPtr New(const GrowableArray<uint8_t>& bytes,
+ bool is_global_table,
+ bool uses_global_table);
uint8_t PayloadByte(uintptr_t offset) const {
ASSERT(offset < payload_size());
@@ -5710,22 +5716,22 @@
bool has_catch_all,
bool is_generated) const;
- RawArray* GetHandledTypes(intptr_t try_index) const;
+ ArrayPtr GetHandledTypes(intptr_t try_index) const;
void SetHandledTypes(intptr_t try_index, const Array& handled_types) const;
bool HasCatchAll(intptr_t try_index) const;
static intptr_t InstanceSize() {
- ASSERT(sizeof(RawExceptionHandlers) ==
- OFFSET_OF_RETURNED_VALUE(RawExceptionHandlers, data));
+ ASSERT(sizeof(ExceptionHandlersLayout) ==
+ OFFSET_OF_RETURNED_VALUE(ExceptionHandlersLayout, data));
return 0;
}
static intptr_t InstanceSize(intptr_t len) {
- return RoundedAllocationSize(sizeof(RawExceptionHandlers) +
+ return RoundedAllocationSize(sizeof(ExceptionHandlersLayout) +
(len * sizeof(ExceptionHandlerInfo)));
}
- static RawExceptionHandlers* New(intptr_t num_handlers);
- static RawExceptionHandlers* New(const Array& handled_types_data);
+ static ExceptionHandlersPtr New(intptr_t num_handlers);
+ static ExceptionHandlersPtr New(const Array& handled_types_data);
// We would have a VisitPointers function here to traverse the
// exception handler table to visit objects if any in the table.
@@ -5758,7 +5764,7 @@
// Object::null() from target() means the WSR represents a dropped target.
//
// Unfortunately a WSR is not a proxy for the original object, so if WSRs may
-// appear as field contents (currently only possible for RawObject* fields),
+// appear as field contents (currently only possible for ObjectPtr fields),
// then code that accesses that field must handle the case where an WSR has
// been introduced. Before serialization, Unwrap can be used to take a
// Object reference or RawObject pointer and remove any WSR wrapping before use.
@@ -5769,8 +5775,8 @@
// * Code::owner_
class WeakSerializationReference : public Object {
public:
- RawObject* target() const { return TargetOf(raw()); }
- static RawObject* TargetOf(const RawWeakSerializationReference* raw) {
+ ObjectPtr target() const { return TargetOf(raw()); }
+ static ObjectPtr TargetOf(const WeakSerializationReferencePtr raw) {
#if defined(DART_PRECOMPILED_RUNTIME)
// WSRs in the precompiled runtime only contain some remaining info about
// their old target, not a reference to the target itself..
@@ -5783,7 +5789,7 @@
}
classid_t TargetClassId() const { return TargetClassIdOf(raw()); }
- static classid_t TargetClassIdOf(const RawWeakSerializationReference* raw) {
+ static classid_t TargetClassIdOf(const WeakSerializationReferencePtr raw) {
#if defined(DART_PRECOMPILED_RUNTIME)
// No new instances of WSRs are created in the precompiled runtime, so
// this instance came from deserialization and thus must be the empty WSR.
@@ -5793,23 +5799,23 @@
#endif
}
- static RawObject* Unwrap(const Object& obj) { return Unwrap(obj.raw()); }
+ static ObjectPtr Unwrap(const Object& obj) { return Unwrap(obj.raw()); }
// Gets the underlying object from a WSR, or the original object if it is
// not one. Notably, Unwrap(Wrap(r)) == r for all raw objects r, whether
// CanWrap(r) or not. However, this will not hold if a serialization and
// deserialization step is put between the two calls.
- static RawObject* Unwrap(RawObject* obj) {
+ static ObjectPtr Unwrap(ObjectPtr obj) {
if (!obj->IsWeakSerializationReference()) return obj;
- return TargetOf(reinterpret_cast<RawWeakSerializationReference*>(obj));
+ return TargetOf(static_cast<WeakSerializationReferencePtr>(obj));
}
// An Unwrap that only unwraps if there's a valid target, otherwise the
// WSR is returned. Useful for cases where we want to call Object methods
// like ToCString() on whatever non-null object we can get.
- static RawObject* UnwrapIfTarget(const Object& obj) {
+ static ObjectPtr UnwrapIfTarget(const Object& obj) {
return UnwrapIfTarget(obj.raw());
}
- static RawObject* UnwrapIfTarget(RawObject* raw) {
+ static ObjectPtr UnwrapIfTarget(ObjectPtr raw) {
#if defined(DART_PRECOMPILED_RUNTIME)
// In the precompiled runtime, WSRs never have a target so we always return
// the argument.
@@ -5831,22 +5837,22 @@
// whether CanWrap(r) or not. Unlike Unwrap, this is still true even if
// there is a serialization and deserialization step between the two calls,
// since that information is saved in the serialized WSR.
- static classid_t UnwrappedClassIdOf(RawObject* obj) {
+ static classid_t UnwrappedClassIdOf(ObjectPtr obj) {
if (!obj->IsWeakSerializationReference()) return obj->GetClassId();
return TargetClassIdOf(WeakSerializationReference::RawCast(obj));
}
static intptr_t InstanceSize() {
- return RoundedAllocationSize(sizeof(RawWeakSerializationReference));
+ return RoundedAllocationSize(sizeof(WeakSerializationReferenceLayout));
}
#if defined(DART_PRECOMPILER)
// Returns true if a new WSR would be created when calling Wrap.
static bool CanWrap(const Object& object);
- // This returns RawObject*, not RawWeakSerializationReference*, because
+ // This returns ObjectPtr, not WeakSerializationReferencePtr, because
// target.raw() is returned when CanWrap(target) is false.
- static RawObject* Wrap(Zone* zone, const Object& target);
+ static ObjectPtr Wrap(Zone* zone, const Object& target);
#endif
private:
@@ -5857,7 +5863,7 @@
class Code : public Object {
public:
// When dual mapping, this returns the executable view.
- RawInstructions* active_instructions() const {
+ InstructionsPtr active_instructions() const {
#if defined(DART_PRECOMPILED_RUNTIME)
UNREACHABLE();
return NULL;
@@ -5867,13 +5873,13 @@
}
// When dual mapping, these return the executable view.
- RawInstructions* instructions() const { return raw_ptr()->instructions_; }
- static RawInstructions* InstructionsOf(const RawCode* code) {
+ InstructionsPtr instructions() const { return raw_ptr()->instructions_; }
+ static InstructionsPtr InstructionsOf(const CodePtr code) {
return code->ptr()->instructions_;
}
static intptr_t saved_instructions_offset() {
- return OFFSET_OF(RawCode, instructions_);
+ return OFFSET_OF(CodeLayout, instructions_);
}
using EntryKind = CodeEntryKind;
@@ -5884,21 +5890,21 @@
static intptr_t entry_point_offset(EntryKind kind = EntryKind::kNormal) {
switch (kind) {
case EntryKind::kNormal:
- return OFFSET_OF(RawCode, entry_point_);
+ return OFFSET_OF(CodeLayout, entry_point_);
case EntryKind::kUnchecked:
- return OFFSET_OF(RawCode, unchecked_entry_point_);
+ return OFFSET_OF(CodeLayout, unchecked_entry_point_);
case EntryKind::kMonomorphic:
- return OFFSET_OF(RawCode, monomorphic_entry_point_);
+ return OFFSET_OF(CodeLayout, monomorphic_entry_point_);
case EntryKind::kMonomorphicUnchecked:
- return OFFSET_OF(RawCode, monomorphic_unchecked_entry_point_);
+ return OFFSET_OF(CodeLayout, monomorphic_unchecked_entry_point_);
default:
UNREACHABLE();
}
}
- RawObjectPool* object_pool() const { return raw_ptr()->object_pool_; }
+ ObjectPoolPtr object_pool() const { return raw_ptr()->object_pool_; }
static intptr_t object_pool_offset() {
- return OFFSET_OF(RawCode, object_pool_);
+ return OFFSET_OF(CodeLayout, object_pool_);
}
intptr_t pointer_offsets_length() const {
@@ -5909,7 +5915,7 @@
return OptimizedBit::decode(raw_ptr()->state_bits_);
}
void set_is_optimized(bool value) const;
- static bool IsOptimized(RawCode* code) {
+ static bool IsOptimized(CodePtr code) {
return Code::OptimizedBit::decode(code->ptr()->state_bits_);
}
@@ -5922,7 +5928,7 @@
void set_is_alive(bool value) const;
bool HasMonomorphicEntry() const { return HasMonomorphicEntry(raw()); }
- static bool HasMonomorphicEntry(const RawCode* code) {
+ static bool HasMonomorphicEntry(const CodePtr code) {
#if defined(DART_PRECOMPILED_RUNTIME)
return code->ptr()->entry_point_ != code->ptr()->monomorphic_entry_point_;
#else
@@ -5932,7 +5938,7 @@
// Returns the payload start of [instructions()].
uword PayloadStart() const { return PayloadStartOf(raw()); }
- static uword PayloadStartOf(const RawCode* code) {
+ static uword PayloadStartOf(const CodePtr code) {
#if defined(DART_PRECOMPILED_RUNTIME)
const uword entry_offset = HasMonomorphicEntry(code)
? Instructions::kPolymorphicEntryOffsetAOT
@@ -5945,7 +5951,7 @@
// Returns the entry point of [instructions()].
uword EntryPoint() const { return EntryPointOf(raw()); }
- static uword EntryPointOf(const RawCode* code) {
+ static uword EntryPointOf(const CodePtr code) {
#if defined(DART_PRECOMPILED_RUNTIME)
return code->ptr()->entry_point_;
#else
@@ -5980,7 +5986,7 @@
// Returns the size of [instructions()].
intptr_t Size() const { return PayloadSizeOf(raw()); }
- static intptr_t PayloadSizeOf(const RawCode* code) {
+ static intptr_t PayloadSizeOf(const CodePtr code) {
#if defined(DART_PRECOMPILED_RUNTIME)
return code->ptr()->instructions_length_;
#else
@@ -5988,29 +5994,27 @@
#endif
}
- RawObjectPool* GetObjectPool() const;
+ ObjectPoolPtr GetObjectPool() const;
// Returns whether the given PC address is in [instructions()].
bool ContainsInstructionAt(uword addr) const {
return ContainsInstructionAt(raw(), addr);
}
// Returns whether the given PC address is in [InstructionsOf(code)].
- static bool ContainsInstructionAt(const RawCode* code, uword pc) {
- return RawCode::ContainsPC(code, pc);
+ static bool ContainsInstructionAt(const CodePtr code, uword pc) {
+ return CodeLayout::ContainsPC(code, pc);
}
// Returns true if there is a debugger breakpoint set in this code object.
bool HasBreakpoint() const;
- RawPcDescriptors* pc_descriptors() const {
- return raw_ptr()->pc_descriptors_;
- }
+ PcDescriptorsPtr pc_descriptors() const { return raw_ptr()->pc_descriptors_; }
void set_pc_descriptors(const PcDescriptors& descriptors) const {
ASSERT(descriptors.IsOld());
StorePointer(&raw_ptr()->pc_descriptors_, descriptors.raw());
}
- RawCodeSourceMap* code_source_map() const {
+ CodeSourceMapPtr code_source_map() const {
return raw_ptr()->code_source_map_;
}
@@ -6020,7 +6024,7 @@
}
// Array of DeoptInfo objects.
- RawArray* deopt_info_array() const {
+ ArrayPtr deopt_info_array() const {
#if defined(DART_PRECOMPILED_RUNTIME)
UNREACHABLE();
return NULL;
@@ -6036,11 +6040,11 @@
#endif
#if defined(DART_PRECOMPILED_RUNTIME) || defined(DART_PRECOMPILER)
- RawTypedData* catch_entry_moves_maps() const;
+ TypedDataPtr catch_entry_moves_maps() const;
void set_catch_entry_moves_maps(const TypedData& maps) const;
#endif
- RawCompressedStackMaps* compressed_stackmaps() const {
+ CompressedStackMapsPtr compressed_stackmaps() const {
return raw_ptr()->compressed_stackmaps_;
}
void set_compressed_stackmaps(const CompressedStackMaps& maps) const;
@@ -6076,7 +6080,7 @@
: public BitField<intptr_t, intptr_t, EntryPointField::kNextBit, 26> {};
void set_static_calls_target_table(const Array& value) const;
- RawArray* static_calls_target_table() const {
+ ArrayPtr static_calls_target_table() const {
#if defined(DART_PRECOMPILED_RUNTIME)
UNREACHABLE();
return NULL;
@@ -6085,12 +6089,12 @@
#endif
}
- RawTypedData* GetDeoptInfoAtPc(uword pc,
- ICData::DeoptReasonId* deopt_reason,
- uint32_t* deopt_flags) const;
+ TypedDataPtr GetDeoptInfoAtPc(uword pc,
+ ICData::DeoptReasonId* deopt_reason,
+ uint32_t* deopt_flags) const;
// Returns null if there is no static call at 'pc'.
- RawFunction* GetStaticCallTargetFunctionAt(uword pc) const;
+ FunctionPtr GetStaticCallTargetFunctionAt(uword pc) const;
// Aborts if there is no static call at 'pc'.
void SetStaticCallTargetCodeAt(uword pc, const Code& code) const;
void SetStubCallTargetCodeAt(uword pc, const Code& code) const;
@@ -6107,7 +6111,7 @@
void SetCommentAt(intptr_t idx, const String& comment);
intptr_t PCOffsetAt(intptr_t idx) const;
- RawString* CommentAt(intptr_t idx) const;
+ StringPtr CommentAt(intptr_t idx) const;
private:
explicit Comments(const Array& comments);
@@ -6129,7 +6133,7 @@
const Comments& comments() const;
void set_comments(const Comments& comments) const;
- RawObject* return_address_metadata() const {
+ ObjectPtr return_address_metadata() const {
#if defined(PRODUCT)
UNREACHABLE();
return NULL;
@@ -6142,7 +6146,7 @@
// Returns -1 if no prologue offset is available.
intptr_t GetPrologueOffset() const;
- RawArray* inlined_id_to_function() const;
+ ArrayPtr inlined_id_to_function() const;
void set_inlined_id_to_function(const Array& value) const;
// Provides the call stack at the given pc offset, with the top-of-stack in
@@ -6170,7 +6174,7 @@
void DumpInlineIntervals() const;
void DumpSourcePositions(bool relative_addresses = false) const;
- RawLocalVarDescriptors* var_descriptors() const {
+ LocalVarDescriptorsPtr var_descriptors() const {
#if defined(PRODUCT)
UNREACHABLE();
return NULL;
@@ -6188,9 +6192,9 @@
}
// Will compute local var descriptors if necessary.
- RawLocalVarDescriptors* GetLocalVarDescriptors() const;
+ LocalVarDescriptorsPtr GetLocalVarDescriptors() const;
- RawExceptionHandlers* exception_handlers() const {
+ ExceptionHandlersPtr exception_handlers() const {
return raw_ptr()->exception_handlers_;
}
void set_exception_handlers(const ExceptionHandlers& handlers) const {
@@ -6204,36 +6208,36 @@
// TODO(turnidge): Consider dropping this function and making
// everybody use owner(). Currently this function is misused - even
// while generating the snapshot.
- RawFunction* function() const {
+ FunctionPtr function() const {
ASSERT(IsFunctionCode());
return Function::RawCast(
WeakSerializationReference::Unwrap(raw_ptr()->owner_));
}
- RawObject* owner() const { return raw_ptr()->owner_; }
+ ObjectPtr owner() const { return raw_ptr()->owner_; }
void set_owner(const Object& owner) const;
classid_t OwnerClassId() const { return OwnerClassIdOf(raw()); }
- static classid_t OwnerClassIdOf(RawCode* raw) {
+ static classid_t OwnerClassIdOf(CodePtr raw) {
return WeakSerializationReference::UnwrappedClassIdOf(raw->ptr()->owner_);
}
- static intptr_t owner_offset() { return OFFSET_OF(RawCode, owner_); }
+ static intptr_t owner_offset() { return OFFSET_OF(CodeLayout, owner_); }
// We would have a VisitPointers function here to traverse all the
// embedded objects in the instructions using pointer_offsets.
static const intptr_t kBytesPerElement =
- sizeof(reinterpret_cast<RawCode*>(0)->data()[0]);
+ sizeof(reinterpret_cast<CodeLayout*>(0)->data()[0]);
static const intptr_t kMaxElements = kSmiMax / kBytesPerElement;
static intptr_t InstanceSize() {
- ASSERT(sizeof(RawCode) == OFFSET_OF_RETURNED_VALUE(RawCode, data));
+ ASSERT(sizeof(CodeLayout) == OFFSET_OF_RETURNED_VALUE(CodeLayout, data));
return 0;
}
static intptr_t InstanceSize(intptr_t len) {
ASSERT(0 <= len && len <= kMaxElements);
- return RoundedAllocationSize(sizeof(RawCode) + (len * kBytesPerElement));
+ return RoundedAllocationSize(sizeof(CodeLayout) + (len * kBytesPerElement));
}
#if !defined(DART_PRECOMPILED_RUNTIME)
// Finalizes the generated code, by generating various kinds of metadata (e.g.
@@ -6244,11 +6248,11 @@
// then a new [ObjectPool] will be attached to the code object as well.
// Otherwise the caller is responsible for doing this via
// `Object::set_object_pool()`.
- static RawCode* FinalizeCode(FlowGraphCompiler* compiler,
- compiler::Assembler* assembler,
- PoolAttachment pool_attachment,
- bool optimized,
- CodeStatistics* stats);
+ static CodePtr FinalizeCode(FlowGraphCompiler* compiler,
+ compiler::Assembler* assembler,
+ PoolAttachment pool_attachment,
+ bool optimized,
+ CodeStatistics* stats);
// Notifies all active [CodeObserver]s.
static void NotifyCodeObservers(const Code& code, bool optimized);
@@ -6260,23 +6264,23 @@
bool optimized);
// Calls [FinalizeCode] and also notifies [CodeObserver]s.
- static RawCode* FinalizeCodeAndNotify(const Function& function,
- FlowGraphCompiler* compiler,
- compiler::Assembler* assembler,
- PoolAttachment pool_attachment,
- bool optimized = false,
- CodeStatistics* stats = nullptr);
- static RawCode* FinalizeCodeAndNotify(const char* name,
- FlowGraphCompiler* compiler,
- compiler::Assembler* assembler,
- PoolAttachment pool_attachment,
- bool optimized = false,
- CodeStatistics* stats = nullptr);
+ static CodePtr FinalizeCodeAndNotify(const Function& function,
+ FlowGraphCompiler* compiler,
+ compiler::Assembler* assembler,
+ PoolAttachment pool_attachment,
+ bool optimized = false,
+ CodeStatistics* stats = nullptr);
+ static CodePtr FinalizeCodeAndNotify(const char* name,
+ FlowGraphCompiler* compiler,
+ compiler::Assembler* assembler,
+ PoolAttachment pool_attachment,
+ bool optimized = false,
+ CodeStatistics* stats = nullptr);
#endif
- static RawCode* LookupCode(uword pc);
- static RawCode* LookupCodeInVmIsolate(uword pc);
- static RawCode* FindCode(uword pc, int64_t timestamp);
+ static CodePtr LookupCode(uword pc);
+ static CodePtr LookupCodeInVmIsolate(uword pc);
+ static CodePtr FindCode(uword pc, int64_t timestamp);
int32_t GetPointerOffsetAt(int index) const {
NoSafepointScope no_safepoint;
@@ -6285,7 +6289,8 @@
TokenPosition GetTokenIndexOfPC(uword pc) const;
// Find pc, return 0 if not found.
- uword GetPcForDeoptId(intptr_t deopt_id, RawPcDescriptors::Kind kind) const;
+ uword GetPcForDeoptId(intptr_t deopt_id,
+ PcDescriptorsLayout::Kind kind) const;
intptr_t GetDeoptIdForOsr(uword pc) const;
const char* Name() const;
@@ -6315,7 +6320,7 @@
}
bool IsDisabled() const { return IsDisabled(raw()); }
- static bool IsDisabled(RawCode* code) {
+ static bool IsDisabled(CodePtr code) {
#if defined(DART_PRECOMPILED_RUNTIME)
UNREACHABLE();
return false;
@@ -6324,15 +6329,15 @@
#endif
}
- void set_object_pool(RawObjectPool* object_pool) const {
+ void set_object_pool(ObjectPoolPtr object_pool) const {
StorePointer(&raw_ptr()->object_pool_, object_pool);
}
private:
void set_state_bits(intptr_t bits) const;
- friend class RawObject; // For RawObject::SizeFromClass().
- friend class RawCode;
+ friend class ObjectLayout; // For ObjectLayout::SizeFromClass().
+ friend class CodeLayout;
enum {
kOptimizedBit = 0,
kForceOptimizedBit = 1,
@@ -6358,7 +6363,7 @@
virtual ~SlowFindRawCodeVisitor() {}
// Check if object matches find condition.
- virtual bool FindObject(RawObject* obj) const;
+ virtual bool FindObject(ObjectPtr obj) const;
private:
const uword pc_;
@@ -6378,8 +6383,8 @@
// Initializes the cached entrypoint addresses in [code] as calculated
// from [instructions] and [unchecked_offset].
- static void InitializeCachedEntryPointsFrom(RawCode* code,
- RawInstructions* instructions,
+ static void InitializeCachedEntryPointsFrom(CodePtr code,
+ InstructionsPtr instructions,
uint32_t unchecked_offset);
// Sets [active_instructions_] to [instructions] and updates the cached
@@ -6405,7 +6410,7 @@
uint32_t UncheckedEntryPointOffset() const {
return UncheckedEntryPointOffsetOf(raw());
}
- static uint32_t UncheckedEntryPointOffsetOf(RawCode* code) {
+ static uint32_t UncheckedEntryPointOffsetOf(CodePtr code) {
#if defined(DART_PRECOMPILED_RUNTIME)
UNREACHABLE();
#else
@@ -6430,13 +6435,13 @@
}
intptr_t BinarySearchInSCallTable(uword pc) const;
- static RawCode* LookupCodeInIsolate(Isolate* isolate, uword pc);
+ static CodePtr LookupCodeInIsolate(Isolate* isolate, uword pc);
// New is a private method as RawInstruction and RawCode objects should
// only be created using the Code::FinalizeCode method. This method creates
// the RawInstruction and RawCode objects, sets up the pointer offsets
// and links the two in a GC safe manner.
- static RawCode* New(intptr_t pointer_offsets_length);
+ static CodePtr New(intptr_t pointer_offsets_length);
FINAL_HEAP_OBJECT_IMPLEMENTATION(Code, Object);
friend class Class;
@@ -6454,7 +6459,7 @@
friend class ProgramVisitor; // for set_instructions
// So that the RawFunction pointer visitor can determine whether code the
// function points to is optimized.
- friend class RawFunction;
+ friend class FunctionLayout;
friend class CallSiteResetter;
friend class CodeKeyValueTrait; // for UncheckedEntryPointOffset
};
@@ -6466,15 +6471,13 @@
uword PayloadStart() const { return instructions(); }
intptr_t Size() const { return raw_ptr()->instructions_size_; }
- RawObjectPool* object_pool() const { return raw_ptr()->object_pool_; }
+ ObjectPoolPtr object_pool() const { return raw_ptr()->object_pool_; }
bool ContainsInstructionAt(uword addr) const {
- return RawBytecode::ContainsPC(raw(), addr);
+ return BytecodeLayout::ContainsPC(raw(), addr);
}
- RawPcDescriptors* pc_descriptors() const {
- return raw_ptr()->pc_descriptors_;
- }
+ PcDescriptorsPtr pc_descriptors() const { return raw_ptr()->pc_descriptors_; }
void set_pc_descriptors(const PcDescriptors& descriptors) const {
ASSERT(descriptors.IsOld());
StorePointer(&raw_ptr()->pc_descriptors_, descriptors.raw());
@@ -6482,7 +6485,7 @@
void Disassemble(DisassemblyFormatter* formatter = NULL) const;
- RawExceptionHandlers* exception_handlers() const {
+ ExceptionHandlersPtr exception_handlers() const {
return raw_ptr()->exception_handlers_;
}
void set_exception_handlers(const ExceptionHandlers& handlers) const {
@@ -6490,7 +6493,7 @@
StorePointer(&raw_ptr()->exception_handlers_, handlers.raw());
}
- RawFunction* function() const { return raw_ptr()->function_; }
+ FunctionPtr function() const { return raw_ptr()->function_; }
void set_function(const Function& function) const {
ASSERT(function.IsOld());
@@ -6498,14 +6501,14 @@
}
static intptr_t InstanceSize() {
- return RoundedAllocationSize(sizeof(RawBytecode));
+ return RoundedAllocationSize(sizeof(BytecodeLayout));
}
- static RawBytecode* New(uword instructions,
- intptr_t instructions_size,
- intptr_t instructions_offset,
- const ObjectPool& object_pool);
+ static BytecodePtr New(uword instructions,
+ intptr_t instructions_size,
+ intptr_t instructions_offset,
+ const ObjectPool& object_pool);
- RawExternalTypedData* GetBinary(Zone* zone) const;
+ ExternalTypedDataPtr GetBinary(Zone* zone) const;
TokenPosition GetTokenIndexOfPC(uword return_address) const;
intptr_t GetTryIndexAtPc(uword return_address) const;
@@ -6546,7 +6549,7 @@
return (local_variables_binary_offset() != 0);
}
- RawLocalVarDescriptors* var_descriptors() const {
+ LocalVarDescriptorsPtr var_descriptors() const {
#if defined(PRODUCT)
UNREACHABLE();
return nullptr;
@@ -6564,7 +6567,7 @@
}
// Will compute local var descriptors if necessary.
- RawLocalVarDescriptors* GetLocalVarDescriptors() const;
+ LocalVarDescriptorsPtr GetLocalVarDescriptors() const;
const char* Name() const;
const char* QualifiedName() const;
@@ -6576,7 +6579,7 @@
virtual ~SlowFindRawBytecodeVisitor() {}
// Check if object matches find condition.
- virtual bool FindObject(RawObject* obj) const;
+ virtual bool FindObject(ObjectPtr obj) const;
private:
const uword pc_;
@@ -6584,7 +6587,7 @@
DISALLOW_COPY_AND_ASSIGN(SlowFindRawBytecodeVisitor);
};
- static RawBytecode* FindCode(uword pc);
+ static BytecodePtr FindCode(uword pc);
private:
void set_instructions(uword instructions) const {
@@ -6598,8 +6601,8 @@
}
friend class BytecodeDeserializationCluster;
- friend class RawObject; // For RawObject::SizeFromClass().
- friend class RawBytecode;
+ friend class ObjectLayout; // For ObjectLayout::SizeFromClass().
+ friend class BytecodeLayout;
FINAL_HEAP_OBJECT_IMPLEMENTATION(Bytecode, Object);
friend class Class;
@@ -6608,21 +6611,21 @@
class Context : public Object {
public:
- RawContext* parent() const { return raw_ptr()->parent_; }
+ ContextPtr parent() const { return raw_ptr()->parent_; }
void set_parent(const Context& parent) const {
StorePointer(&raw_ptr()->parent_, parent.raw());
}
- static intptr_t parent_offset() { return OFFSET_OF(RawContext, parent_); }
+ static intptr_t parent_offset() { return OFFSET_OF(ContextLayout, parent_); }
intptr_t num_variables() const { return raw_ptr()->num_variables_; }
static intptr_t num_variables_offset() {
- return OFFSET_OF(RawContext, num_variables_);
+ return OFFSET_OF(ContextLayout, num_variables_);
}
- static intptr_t NumVariables(const RawContext* context) {
+ static intptr_t NumVariables(const ContextPtr context) {
return context->ptr()->num_variables_;
}
- RawObject* At(intptr_t context_index) const {
+ ObjectPtr At(intptr_t context_index) const {
return *ObjectAddr(context_index);
}
inline void SetAt(intptr_t context_index, const Object& value) const;
@@ -6639,7 +6642,7 @@
static const intptr_t kControllerIndex = 1;
static intptr_t variable_offset(intptr_t context_index) {
- return OFFSET_OF_RETURNED_VALUE(RawContext, data) +
+ return OFFSET_OF_RETURNED_VALUE(ContextLayout, data) +
(kWordSize * context_index);
}
@@ -6648,20 +6651,21 @@
}
static intptr_t InstanceSize() {
- ASSERT(sizeof(RawContext) == OFFSET_OF_RETURNED_VALUE(RawContext, data));
+ ASSERT(sizeof(ContextLayout) ==
+ OFFSET_OF_RETURNED_VALUE(ContextLayout, data));
return 0;
}
static intptr_t InstanceSize(intptr_t len) {
ASSERT(IsValidLength(len));
- return RoundedAllocationSize(sizeof(RawContext) + (len * kBytesPerElement));
+ return RoundedAllocationSize(sizeof(ContextLayout) +
+ (len * kBytesPerElement));
}
- static RawContext* New(intptr_t num_variables,
- Heap::Space space = Heap::kNew);
+ static ContextPtr New(intptr_t num_variables, Heap::Space space = Heap::kNew);
private:
- RawObject* const* ObjectAddr(intptr_t context_index) const {
+ ObjectPtr const* ObjectAddr(intptr_t context_index) const {
ASSERT((context_index >= 0) && (context_index < num_variables()));
return &raw_ptr()->data()[context_index];
}
@@ -6696,7 +6700,7 @@
void SetDeclarationTokenIndexAt(intptr_t scope_index,
TokenPosition declaration_token_pos) const;
- RawString* NameAt(intptr_t scope_index) const;
+ StringPtr NameAt(intptr_t scope_index) const;
void SetNameAt(intptr_t scope_index, const String& name) const;
void ClearFlagsAt(intptr_t scope_index) const;
@@ -6714,10 +6718,10 @@
bool IsConstAt(intptr_t scope_index) const;
void SetIsConstAt(intptr_t scope_index, bool is_const) const;
- RawAbstractType* TypeAt(intptr_t scope_index) const;
+ AbstractTypePtr TypeAt(intptr_t scope_index) const;
void SetTypeAt(intptr_t scope_index, const AbstractType& type) const;
- RawInstance* ConstValueAt(intptr_t scope_index) const;
+ InstancePtr ConstValueAt(intptr_t scope_index) const;
void SetConstValueAt(intptr_t scope_index, const Instance& value) const;
intptr_t ContextIndexAt(intptr_t scope_index) const;
@@ -6727,22 +6731,22 @@
void SetContextLevelAt(intptr_t scope_index, intptr_t context_level) const;
static const intptr_t kBytesPerElement =
- sizeof(RawContextScope::VariableDesc);
+ sizeof(ContextScopeLayout::VariableDesc);
static const intptr_t kMaxElements = kSmiMax / kBytesPerElement;
static intptr_t InstanceSize() {
- ASSERT(sizeof(RawContextScope) ==
- OFFSET_OF_RETURNED_VALUE(RawContextScope, data));
+ ASSERT(sizeof(ContextScopeLayout) ==
+ OFFSET_OF_RETURNED_VALUE(ContextScopeLayout, data));
return 0;
}
static intptr_t InstanceSize(intptr_t len) {
ASSERT(0 <= len && len <= kMaxElements);
- return RoundedAllocationSize(sizeof(RawContextScope) +
+ return RoundedAllocationSize(sizeof(ContextScopeLayout) +
(len * kBytesPerElement));
}
- static RawContextScope* New(intptr_t num_variables, bool is_implicit);
+ static ContextScopePtr New(intptr_t num_variables, bool is_implicit);
private:
void set_num_variables(intptr_t num_variables) const {
@@ -6753,7 +6757,8 @@
StoreNonPointer(&raw_ptr()->is_implicit_, is_implicit);
}
- const RawContextScope::VariableDesc* VariableDescAddr(intptr_t index) const {
+ const ContextScopeLayout::VariableDesc* VariableDescAddr(
+ intptr_t index) const {
ASSERT((index >= 0) && (index < num_variables()));
return raw_ptr()->VariableDescAddr(index);
}
@@ -6778,7 +6783,7 @@
kEntryLength,
};
- RawArray* buckets() const;
+ ArrayPtr buckets() const;
void set_buckets(const Array& buckets) const;
intptr_t mask() const;
@@ -6788,34 +6793,34 @@
void set_filled_entry_count(intptr_t num) const;
static intptr_t buckets_offset() {
- return OFFSET_OF(RawMegamorphicCache, buckets_);
+ return OFFSET_OF(MegamorphicCacheLayout, buckets_);
}
static intptr_t mask_offset() {
- return OFFSET_OF(RawMegamorphicCache, mask_);
+ return OFFSET_OF(MegamorphicCacheLayout, mask_);
}
static intptr_t arguments_descriptor_offset() {
- return OFFSET_OF(RawMegamorphicCache, args_descriptor_);
+ return OFFSET_OF(MegamorphicCacheLayout, args_descriptor_);
}
- static RawMegamorphicCache* New(const String& target_name,
- const Array& arguments_descriptor);
+ static MegamorphicCachePtr New(const String& target_name,
+ const Array& arguments_descriptor);
void Insert(const Smi& class_id, const Object& target) const;
void SwitchToBareInstructions();
static intptr_t InstanceSize() {
- return RoundedAllocationSize(sizeof(RawMegamorphicCache));
+ return RoundedAllocationSize(sizeof(MegamorphicCacheLayout));
}
- static RawMegamorphicCache* Clone(const MegamorphicCache& from);
+ static MegamorphicCachePtr Clone(const MegamorphicCache& from);
private:
friend class Class;
friend class MegamorphicCacheTable;
friend class ProgramVisitor;
- static RawMegamorphicCache* New();
+ static MegamorphicCachePtr New();
// The caller must hold Isolate::megamorphic_mutex().
void EnsureCapacityLocked() const;
@@ -6826,9 +6831,8 @@
const Smi& class_id,
const Object& target);
- static inline RawObject* GetClassId(const Array& array, intptr_t index);
- static inline RawObject* GetTargetFunction(const Array& array,
- intptr_t index);
+ static inline ObjectPtr GetClassId(const Array& array, intptr_t index);
+ static inline ObjectPtr GetTargetFunction(const Array& array, intptr_t index);
FINAL_HEAP_OBJECT_IMPLEMENTATION(MegamorphicCache, CallSiteData);
};
@@ -6864,24 +6868,24 @@
Bool* test_result) const;
void Reset() const;
- static RawSubtypeTestCache* New();
+ static SubtypeTestCachePtr New();
static intptr_t InstanceSize() {
- return RoundedAllocationSize(sizeof(RawSubtypeTestCache));
+ return RoundedAllocationSize(sizeof(SubtypeTestCacheLayout));
}
static intptr_t cache_offset() {
- return OFFSET_OF(RawSubtypeTestCache, cache_);
+ return OFFSET_OF(SubtypeTestCacheLayout, cache_);
}
static void Init();
static void Cleanup();
- RawArray* cache() const { return raw_ptr()->cache_; }
+ ArrayPtr cache() const { return raw_ptr()->cache_; }
private:
// A VM heap allocated preinitialized empty subtype entry array.
- static RawArray* cached_array_;
+ static ArrayPtr cached_array_;
void set_cache(const Array& value) const;
@@ -6903,21 +6907,20 @@
class ApiError : public Error {
public:
- RawString* message() const { return raw_ptr()->message_; }
+ StringPtr message() const { return raw_ptr()->message_; }
static intptr_t InstanceSize() {
- return RoundedAllocationSize(sizeof(RawApiError));
+ return RoundedAllocationSize(sizeof(ApiErrorLayout));
}
- static RawApiError* New(const String& message,
- Heap::Space space = Heap::kNew);
+ static ApiErrorPtr New(const String& message, Heap::Space space = Heap::kNew);
virtual const char* ToErrorCString() const;
private:
void set_message(const String& message) const;
- static RawApiError* New();
+ static ApiErrorPtr New();
FINAL_HEAP_OBJECT_IMPLEMENTATION(ApiError, Error);
friend class Class;
@@ -6930,44 +6933,44 @@
}
// Build, cache, and return formatted message.
- RawString* FormatMessage() const;
+ StringPtr FormatMessage() const;
static intptr_t InstanceSize() {
- return RoundedAllocationSize(sizeof(RawLanguageError));
+ return RoundedAllocationSize(sizeof(LanguageErrorLayout));
}
// A null script means no source and a negative token_pos means no position.
- static RawLanguageError* NewFormatted(const Error& prev_error,
+ static LanguageErrorPtr NewFormatted(const Error& prev_error,
+ const Script& script,
+ TokenPosition token_pos,
+ bool report_after_token,
+ Report::Kind kind,
+ Heap::Space space,
+ const char* format,
+ ...) PRINTF_ATTRIBUTE(7, 8);
+
+ static LanguageErrorPtr NewFormattedV(const Error& prev_error,
const Script& script,
TokenPosition token_pos,
bool report_after_token,
Report::Kind kind,
Heap::Space space,
const char* format,
- ...) PRINTF_ATTRIBUTE(7, 8);
+ va_list args);
- static RawLanguageError* NewFormattedV(const Error& prev_error,
- const Script& script,
- TokenPosition token_pos,
- bool report_after_token,
- Report::Kind kind,
- Heap::Space space,
- const char* format,
- va_list args);
-
- static RawLanguageError* New(const String& formatted_message,
- Report::Kind kind = Report::kError,
- Heap::Space space = Heap::kNew);
+ static LanguageErrorPtr New(const String& formatted_message,
+ Report::Kind kind = Report::kError,
+ Heap::Space space = Heap::kNew);
virtual const char* ToErrorCString() const;
TokenPosition token_pos() const { return raw_ptr()->token_pos_; }
private:
- RawError* previous_error() const { return raw_ptr()->previous_error_; }
+ ErrorPtr previous_error() const { return raw_ptr()->previous_error_; }
void set_previous_error(const Error& value) const;
- RawScript* script() const { return raw_ptr()->script_; }
+ ScriptPtr script() const { return raw_ptr()->script_; }
void set_script(const Script& value) const;
void set_token_pos(TokenPosition value) const;
@@ -6977,13 +6980,13 @@
void set_kind(uint8_t value) const;
- RawString* message() const { return raw_ptr()->message_; }
+ StringPtr message() const { return raw_ptr()->message_; }
void set_message(const String& value) const;
- RawString* formatted_message() const { return raw_ptr()->formatted_message_; }
+ StringPtr formatted_message() const { return raw_ptr()->formatted_message_; }
void set_formatted_message(const String& value) const;
- static RawLanguageError* New();
+ static LanguageErrorPtr New();
FINAL_HEAP_OBJECT_IMPLEMENTATION(LanguageError, Error);
friend class Class;
@@ -6991,28 +6994,28 @@
class UnhandledException : public Error {
public:
- RawInstance* exception() const { return raw_ptr()->exception_; }
+ InstancePtr exception() const { return raw_ptr()->exception_; }
static intptr_t exception_offset() {
- return OFFSET_OF(RawUnhandledException, exception_);
+ return OFFSET_OF(UnhandledExceptionLayout, exception_);
}
- RawInstance* stacktrace() const { return raw_ptr()->stacktrace_; }
+ InstancePtr stacktrace() const { return raw_ptr()->stacktrace_; }
static intptr_t stacktrace_offset() {
- return OFFSET_OF(RawUnhandledException, stacktrace_);
+ return OFFSET_OF(UnhandledExceptionLayout, stacktrace_);
}
static intptr_t InstanceSize() {
- return RoundedAllocationSize(sizeof(RawUnhandledException));
+ return RoundedAllocationSize(sizeof(UnhandledExceptionLayout));
}
- static RawUnhandledException* New(const Instance& exception,
- const Instance& stacktrace,
- Heap::Space space = Heap::kNew);
+ static UnhandledExceptionPtr New(const Instance& exception,
+ const Instance& stacktrace,
+ Heap::Space space = Heap::kNew);
virtual const char* ToErrorCString() const;
private:
- static RawUnhandledException* New(Heap::Space space = Heap::kNew);
+ static UnhandledExceptionPtr New(Heap::Space space = Heap::kNew);
void set_exception(const Instance& exception) const;
void set_stacktrace(const Instance& stacktrace) const;
@@ -7027,14 +7030,14 @@
bool is_user_initiated() const { return raw_ptr()->is_user_initiated_; }
void set_is_user_initiated(bool value) const;
- RawString* message() const { return raw_ptr()->message_; }
+ StringPtr message() const { return raw_ptr()->message_; }
static intptr_t InstanceSize() {
- return RoundedAllocationSize(sizeof(RawUnwindError));
+ return RoundedAllocationSize(sizeof(UnwindErrorLayout));
}
- static RawUnwindError* New(const String& message,
- Heap::Space space = Heap::kNew);
+ static UnwindErrorPtr New(const String& message,
+ Heap::Space space = Heap::kNew);
virtual const char* ToErrorCString() const;
@@ -7074,30 +7077,30 @@
// An instance cannot be canonicalized if it still contains non-canonical
// instances in its fields.
// Returns error in error_str, pass NULL if an error cannot occur.
- virtual RawInstance* CheckAndCanonicalize(Thread* thread,
- const char** error_str) const;
+ virtual InstancePtr CheckAndCanonicalize(Thread* thread,
+ const char** error_str) const;
// Returns true if all fields are OK for canonicalization.
virtual bool CheckAndCanonicalizeFields(Thread* thread,
const char** error_str) const;
- RawInstance* CopyShallowToOldSpace(Thread* thread) const;
+ InstancePtr CopyShallowToOldSpace(Thread* thread) const;
#if defined(DEBUG)
// Check if instance is canonical.
virtual bool CheckIsCanonical(Thread* thread) const;
#endif // DEBUG
- RawObject* GetField(const Field& field) const;
+ ObjectPtr GetField(const Field& field) const;
void SetField(const Field& field, const Object& value) const;
- RawAbstractType* GetType(Heap::Space space) const;
+ AbstractTypePtr GetType(Heap::Space space) const;
// Access the arguments of the [Type] of this [Instance].
// Note: for [Type]s instead of [Instance]s with a [Type] attached, use
// [arguments()] and [set_arguments()]
- virtual RawTypeArguments* GetTypeArguments() const;
+ virtual TypeArgumentsPtr GetTypeArguments() const;
virtual void SetTypeArguments(const TypeArguments& value) const;
// Check if the type of this instance is a subtype of the given other type.
@@ -7144,25 +7147,25 @@
// (if not NULL) to call.
bool IsCallable(Function* function) const;
- RawObject* Invoke(const String& selector,
- const Array& arguments,
- const Array& argument_names,
- bool respect_reflectable = true,
- bool check_is_entrypoint = false) const;
- RawObject* InvokeGetter(const String& selector,
- bool respect_reflectable = true,
- bool check_is_entrypoint = false) const;
- RawObject* InvokeSetter(const String& selector,
- const Instance& argument,
- bool respect_reflectable = true,
- bool check_is_entrypoint = false) const;
+ ObjectPtr Invoke(const String& selector,
+ const Array& arguments,
+ const Array& argument_names,
+ bool respect_reflectable = true,
+ bool check_is_entrypoint = false) const;
+ ObjectPtr InvokeGetter(const String& selector,
+ bool respect_reflectable = true,
+ bool check_is_entrypoint = false) const;
+ ObjectPtr InvokeSetter(const String& selector,
+ const Instance& argument,
+ bool respect_reflectable = true,
+ bool check_is_entrypoint = false) const;
// Evaluate the given expression as if it appeared in an instance method of
// this instance and return the resulting value, or an error object if
// evaluating the expression fails. The method has the formal (type)
// parameters given in (type_)param_names, and is invoked with the (type)
// argument values given in (type_)param_values.
- RawObject* EvaluateCompiledExpression(
+ ObjectPtr EvaluateCompiledExpression(
const Class& method_cls,
const ExternalTypedData& kernel_buffer,
const Array& type_definitions,
@@ -7170,16 +7173,16 @@
const TypeArguments& type_param_values) const;
// Equivalent to invoking hashCode on this instance.
- virtual RawObject* HashCode() const;
+ virtual ObjectPtr HashCode() const;
// Equivalent to invoking identityHashCode with this instance.
- RawObject* IdentityHashCode() const;
+ ObjectPtr IdentityHashCode() const;
static intptr_t InstanceSize() {
- return RoundedAllocationSize(sizeof(RawInstance));
+ return RoundedAllocationSize(sizeof(InstanceLayout));
}
- static RawInstance* New(const Class& cls, Heap::Space space = Heap::kNew);
+ static InstancePtr New(const Class& cls, Heap::Space space = Heap::kNew);
// Array/list element address computations.
static intptr_t DataOffsetFor(intptr_t cid);
@@ -7191,7 +7194,7 @@
// Pointer handles.
virtual bool IsPointer() const;
- static intptr_t NextFieldOffset() { return sizeof(RawInstance); }
+ static intptr_t NextFieldOffset() { return sizeof(InstanceLayout); }
protected:
#ifndef PRODUCT
@@ -7211,15 +7214,15 @@
const TypeArguments& other_instantiator_type_arguments,
const TypeArguments& other_function_type_arguments);
- RawObject** FieldAddrAtOffset(intptr_t offset) const {
+ ObjectPtr* FieldAddrAtOffset(intptr_t offset) const {
ASSERT(IsValidFieldOffset(offset));
- return reinterpret_cast<RawObject**>(raw_value() - kHeapObjectTag + offset);
+ return reinterpret_cast<ObjectPtr*>(raw_value() - kHeapObjectTag + offset);
}
- RawObject** FieldAddr(const Field& field) const {
+ ObjectPtr* FieldAddr(const Field& field) const {
return FieldAddrAtOffset(field.HostOffset());
}
- RawObject** NativeFieldsAddr() const {
- return FieldAddrAtOffset(sizeof(RawObject));
+ ObjectPtr* NativeFieldsAddr() const {
+ return FieldAddrAtOffset(sizeof(ObjectLayout));
}
void SetFieldAtOffset(intptr_t offset, const Object& value) const {
StorePointer(FieldAddrAtOffset(offset), value.raw());
@@ -7228,19 +7231,19 @@
// The following raw methods are used for morphing.
// They are needed due to the extraction of the class in IsValidFieldOffset.
- RawObject** RawFieldAddrAtOffset(intptr_t offset) const {
- return reinterpret_cast<RawObject**>(raw_value() - kHeapObjectTag + offset);
+ ObjectPtr* RawFieldAddrAtOffset(intptr_t offset) const {
+ return reinterpret_cast<ObjectPtr*>(raw_value() - kHeapObjectTag + offset);
}
- RawObject* RawGetFieldAtOffset(intptr_t offset) const {
+ ObjectPtr RawGetFieldAtOffset(intptr_t offset) const {
return *RawFieldAddrAtOffset(offset);
}
void RawSetFieldAtOffset(intptr_t offset, const Object& value) const {
StorePointer(RawFieldAddrAtOffset(offset), value.raw());
}
- static RawInstance* NewFromCidAndSize(SharedClassTable* shared_class_table,
- classid_t cid,
- Heap::Space heap = Heap::kNew);
+ static InstancePtr NewFromCidAndSize(SharedClassTable* shared_class_table,
+ classid_t cid,
+ Heap::Space heap = Heap::kNew);
// TODO(iposva): Determine if this gets in the way of Smi.
HEAP_OBJECT_IMPLEMENTATION(Instance, Object);
@@ -7262,26 +7265,26 @@
class LibraryPrefix : public Instance {
public:
- RawString* name() const { return raw_ptr()->name_; }
- virtual RawString* DictionaryName() const { return name(); }
+ StringPtr name() const { return raw_ptr()->name_; }
+ virtual StringPtr DictionaryName() const { return name(); }
- RawArray* imports() const { return raw_ptr()->imports_; }
+ ArrayPtr imports() const { return raw_ptr()->imports_; }
intptr_t num_imports() const { return raw_ptr()->num_imports_; }
- RawLibrary* importer() const { return raw_ptr()->importer_; }
+ LibraryPtr importer() const { return raw_ptr()->importer_; }
- RawLibrary* GetLibrary(int index) const;
+ LibraryPtr GetLibrary(int index) const;
void AddImport(const Namespace& import) const;
bool is_deferred_load() const { return raw_ptr()->is_deferred_load_; }
static intptr_t InstanceSize() {
- return RoundedAllocationSize(sizeof(RawLibraryPrefix));
+ return RoundedAllocationSize(sizeof(LibraryPrefixLayout));
}
- static RawLibraryPrefix* New(const String& name,
- const Namespace& import,
- bool deferred_load,
- const Library& importer);
+ static LibraryPrefixPtr New(const String& name,
+ const Namespace& import,
+ bool deferred_load,
+ const Library& importer);
private:
static const int kInitialSize = 2;
@@ -7292,7 +7295,7 @@
void set_num_imports(intptr_t value) const;
void set_importer(const Library& value) const;
- static RawLibraryPrefix* New();
+ static LibraryPrefixPtr New();
FINAL_HEAP_OBJECT_IMPLEMENTATION(LibraryPrefix, Instance);
friend class Class;
@@ -7307,15 +7310,15 @@
static const intptr_t kHashBits = 30;
intptr_t Length() const;
- RawAbstractType* TypeAt(intptr_t index) const;
- RawAbstractType* TypeAtNullSafe(intptr_t index) const;
+ AbstractTypePtr TypeAt(intptr_t index) const;
+ AbstractTypePtr TypeAtNullSafe(intptr_t index) const;
static intptr_t type_at_offset(intptr_t index) {
- return OFFSET_OF_RETURNED_VALUE(RawTypeArguments, types) +
+ return OFFSET_OF_RETURNED_VALUE(TypeArgumentsLayout, types) +
index * kWordSize;
}
void SetTypeAt(intptr_t index, const AbstractType& value) const;
- struct ArrayLayout {
+ struct ArrayTraits {
static intptr_t elements_start_offset() {
return TypeArguments::type_at_offset(0);
}
@@ -7345,15 +7348,15 @@
static const intptr_t kLegacyBits = 2;
intptr_t nullability() const;
static intptr_t nullability_offset() {
- return OFFSET_OF(RawTypeArguments, nullability_);
+ return OFFSET_OF(TypeArgumentsLayout, nullability_);
}
// The name of this type argument vector, e.g. "<T, dynamic, List<T>, Smi>".
- RawString* Name() const;
+ StringPtr Name() const;
// The name of this type argument vector, e.g. "<T, dynamic, List<T>, int>".
// Names of internal classes are mapped to their public interfaces.
- RawString* UserVisibleName() const;
+ StringPtr UserVisibleName() const;
// Print the internal or public name of a subvector of this type argument
// vector, e.g. "<T, dynamic, List<T>, int>".
@@ -7378,14 +7381,14 @@
return IsDynamicTypes(true, 0, len);
}
- RawTypeArguments* Prepend(Zone* zone,
- const TypeArguments& other,
- intptr_t other_length,
- intptr_t total_length) const;
+ TypeArgumentsPtr Prepend(Zone* zone,
+ const TypeArguments& other,
+ intptr_t other_length,
+ intptr_t total_length) const;
// Concatenate [this] and [other] vectors of type parameters.
- RawTypeArguments* ConcatenateTypeParameters(Zone* zone,
- const TypeArguments& other) const;
+ TypeArgumentsPtr ConcatenateTypeParameters(Zone* zone,
+ const TypeArguments& other) const;
// Check if the subvector of length 'len' starting at 'from_index' of this
// type argument vector consists solely of DynamicType, (nullable) ObjectType,
@@ -7450,13 +7453,13 @@
// Return true if this vector contains a recursive type argument.
bool IsRecursive() const;
- virtual RawInstance* CheckAndCanonicalize(Thread* thread,
- const char** error_str) const {
+ virtual InstancePtr CheckAndCanonicalize(Thread* thread,
+ const char** error_str) const {
return Canonicalize();
}
// Canonicalize only if instantiated, otherwise returns 'this'.
- RawTypeArguments* Canonicalize(TrailPtr trail = NULL) const;
+ TypeArgumentsPtr Canonicalize(TrailPtr trail = NULL) const;
// Add the class name and URI of each type argument of this vector to the uris
// list and mark ambiguous triplets to be printed.
@@ -7467,7 +7470,7 @@
// where each reference to a type parameter is replaced with the corresponding
// type from the various type argument vectors (class instantiator, function,
// or parent functions via the current context).
- RawTypeArguments* InstantiateFrom(
+ TypeArgumentsPtr InstantiateFrom(
const TypeArguments& instantiator_type_arguments,
const TypeArguments& function_type_arguments,
intptr_t num_free_fun_type_params,
@@ -7476,7 +7479,7 @@
// Runtime instantiation with canonicalization. Not to be used during type
// finalization at compile time.
- RawTypeArguments* InstantiateAndCanonicalizeFrom(
+ TypeArgumentsPtr InstantiateAndCanonicalizeFrom(
const TypeArguments& instantiator_type_arguments,
const TypeArguments& function_type_arguments) const;
@@ -7503,25 +7506,25 @@
intptr_t NumInstantiations() const;
static intptr_t instantiations_offset() {
- return OFFSET_OF(RawTypeArguments, instantiations_);
+ return OFFSET_OF(TypeArgumentsLayout, instantiations_);
}
static const intptr_t kBytesPerElement = kWordSize;
static const intptr_t kMaxElements = kSmiMax / kBytesPerElement;
static intptr_t InstanceSize() {
- ASSERT(sizeof(RawTypeArguments) ==
- OFFSET_OF_RETURNED_VALUE(RawTypeArguments, types));
+ ASSERT(sizeof(TypeArgumentsLayout) ==
+ OFFSET_OF_RETURNED_VALUE(TypeArgumentsLayout, types));
return 0;
}
static intptr_t InstanceSize(intptr_t len) {
// Ensure that the types() is not adding to the object size, which includes
// 4 fields: instantiations_, length_, hash_, and nullability_.
- ASSERT(sizeof(RawTypeArguments) ==
- (sizeof(RawObject) + (kNumFields * kWordSize)));
+ ASSERT(sizeof(TypeArgumentsLayout) ==
+ (sizeof(ObjectLayout) + (kNumFields * kWordSize)));
ASSERT(0 <= len && len <= kMaxElements);
- return RoundedAllocationSize(sizeof(RawTypeArguments) +
+ return RoundedAllocationSize(sizeof(TypeArgumentsLayout) +
(len * kBytesPerElement));
}
@@ -7531,7 +7534,7 @@
}
intptr_t Hash() const;
- static RawTypeArguments* New(intptr_t len, Heap::Space space = Heap::kOld);
+ static TypeArgumentsPtr New(intptr_t len, Heap::Space space = Heap::kOld);
private:
intptr_t ComputeNullability() const;
@@ -7548,9 +7551,9 @@
intptr_t from_index,
intptr_t len) const;
- RawArray* instantiations() const;
+ ArrayPtr instantiations() const;
void set_instantiations(const Array& value) const;
- RawAbstractType* const* TypeAddr(intptr_t index) const;
+ AbstractTypePtr const* TypeAddr(intptr_t index) const;
void SetLength(intptr_t value) const;
// Number of fields in the raw object is 4:
// instantiations_, length_, hash_ and nullability_.
@@ -7595,15 +7598,15 @@
// assigned to this type.
bool IsStrictlyNonNullable() const;
- virtual RawAbstractType* SetInstantiatedNullability(
+ virtual AbstractTypePtr SetInstantiatedNullability(
const TypeParameter& type_param,
Heap::Space space) const;
- virtual RawAbstractType* NormalizeFutureOrType(Heap::Space space) const;
+ virtual AbstractTypePtr NormalizeFutureOrType(Heap::Space space) const;
virtual bool HasTypeClass() const { return type_class_id() != kIllegalCid; }
virtual classid_t type_class_id() const;
- virtual RawClass* type_class() const;
- virtual RawTypeArguments* arguments() const;
+ virtual ClassPtr type_class() const;
+ virtual TypeArgumentsPtr arguments() const;
virtual void set_arguments(const TypeArguments& value) const;
virtual TokenPosition token_pos() const;
virtual bool IsInstantiated(Genericity genericity = kAny,
@@ -7635,20 +7638,20 @@
// must remain uninstantiated, because only T is a free variable in this type.
//
// Return a new type, or return 'this' if it is already instantiated.
- virtual RawAbstractType* InstantiateFrom(
+ virtual AbstractTypePtr InstantiateFrom(
const TypeArguments& instantiator_type_arguments,
const TypeArguments& function_type_arguments,
intptr_t num_free_fun_type_params,
TrailPtr instantiation_trail,
Heap::Space space) const;
- virtual RawInstance* CheckAndCanonicalize(Thread* thread,
- const char** error_str) const {
+ virtual InstancePtr CheckAndCanonicalize(Thread* thread,
+ const char** error_str) const {
return Canonicalize();
}
// Return the canonical version of this type.
- virtual RawAbstractType* Canonicalize(TrailPtr trail = NULL) const;
+ virtual AbstractTypePtr Canonicalize(TrailPtr trail = NULL) const;
#if defined(DEBUG)
// Check if abstract type is canonical.
@@ -7660,7 +7663,7 @@
// Return the object associated with the receiver in the trail or
// AbstractType::null() if the receiver is not contained in the trail.
- RawAbstractType* OnlyBuddyInTrail(TrailPtr trail) const;
+ AbstractTypePtr OnlyBuddyInTrail(TrailPtr trail) const;
// If the trail is null, allocate a trail, add the pair <receiver, buddy> to
// the trail. The receiver may only be added once with its only buddy.
@@ -7681,18 +7684,18 @@
static void AddURI(URIs* uris, const String& name, const String& uri);
// Return a formatted string of the uris.
- static RawString* PrintURIs(URIs* uris);
+ static StringPtr PrintURIs(URIs* uris);
// Returns a C-String (possibly "") representing the nullability of this type.
// Legacy and undetermined suffixes are only displayed with kInternalName.
virtual const char* NullabilitySuffix(NameVisibility name_visibility) const;
// The name of this type, including the names of its type arguments, if any.
- virtual RawString* Name() const;
+ virtual StringPtr Name() const;
// The name of this type, including the names of its type arguments, if any.
// Names of internal classes are mapped to their public interfaces.
- virtual RawString* UserVisibleName() const;
+ virtual StringPtr UserVisibleName() const;
// Return the internal or public name of this type, including the names of its
// type arguments, if any.
@@ -7706,7 +7709,7 @@
// The name of this type's class, i.e. without the type argument names of this
// type.
- RawString* ClassName() const;
+ StringPtr ClassName() const;
// Check if this type is a still uninitialized TypeRef.
bool IsNullTypeRef() const;
@@ -7777,7 +7780,7 @@
// Returns the type argument of this (possibly nested) 'FutureOr' type.
// Returns unmodified type if this type is not a 'FutureOr' type.
- RawAbstractType* UnwrapFutureOr() const;
+ AbstractTypePtr UnwrapFutureOr() const;
// Check the subtype relationship.
bool IsSubtypeOf(const AbstractType& other, Heap::Space space) const;
@@ -7791,13 +7794,13 @@
const TypeArguments& function_type_args);
static intptr_t type_test_stub_entry_point_offset() {
- return OFFSET_OF(RawAbstractType, type_test_stub_entry_point_);
+ return OFFSET_OF(AbstractTypeLayout, type_test_stub_entry_point_);
}
uword type_test_stub_entry_point() const {
return raw_ptr()->type_test_stub_entry_point_;
}
- RawCode* type_test_stub() const { return raw_ptr()->type_test_stub_; }
+ CodePtr type_test_stub() const { return raw_ptr()->type_test_stub_; }
void SetTypeTestingStub(const Code& stub) const;
@@ -7818,30 +7821,32 @@
// A Type consists of a class, possibly parameterized with type
// arguments. Example: C<T1, T2>.
//
-// Caution: 'RawType*' denotes a 'raw' pointer to a VM object of class Type, as
+// Caution: 'TypePtr' denotes a 'raw' pointer to a VM object of class Type, as
// opposed to 'Type' denoting a 'handle' to the same object. 'RawType' does not
// relate to a 'raw type', as opposed to a 'cooked type' or 'rare type'.
class Type : public AbstractType {
public:
static intptr_t type_class_id_offset() {
- return OFFSET_OF(RawType, type_class_id_);
+ return OFFSET_OF(TypeLayout, type_class_id_);
}
- static intptr_t arguments_offset() { return OFFSET_OF(RawType, arguments_); }
+ static intptr_t arguments_offset() {
+ return OFFSET_OF(TypeLayout, arguments_);
+ }
static intptr_t type_state_offset() {
- return OFFSET_OF(RawType, type_state_);
+ return OFFSET_OF(TypeLayout, type_state_);
}
- static intptr_t hash_offset() { return OFFSET_OF(RawType, hash_); }
+ static intptr_t hash_offset() { return OFFSET_OF(TypeLayout, hash_); }
static intptr_t nullability_offset() {
- return OFFSET_OF(RawType, nullability_);
+ return OFFSET_OF(TypeLayout, nullability_);
}
virtual bool IsFinalized() const {
- return (raw_ptr()->type_state_ == RawType::kFinalizedInstantiated) ||
- (raw_ptr()->type_state_ == RawType::kFinalizedUninstantiated);
+ return (raw_ptr()->type_state_ == TypeLayout::kFinalizedInstantiated) ||
+ (raw_ptr()->type_state_ == TypeLayout::kFinalizedUninstantiated);
}
virtual void SetIsFinalized() const;
void ResetIsFinalized() const; // Ignore current state and set again.
virtual bool IsBeingFinalized() const {
- return raw_ptr()->type_state_ == RawType::kBeingFinalized;
+ return raw_ptr()->type_state_ == TypeLayout::kBeingFinalized;
}
virtual void SetIsBeingFinalized() const;
virtual bool HasTypeClass() const {
@@ -7851,11 +7856,11 @@
virtual Nullability nullability() const {
return static_cast<Nullability>(raw_ptr()->nullability_);
}
- RawType* ToNullability(Nullability value, Heap::Space space) const;
+ TypePtr ToNullability(Nullability value, Heap::Space space) const;
virtual classid_t type_class_id() const;
- virtual RawClass* type_class() const;
+ virtual ClassPtr type_class() const;
void set_type_class(const Class& value) const;
- virtual RawTypeArguments* arguments() const { return raw_ptr()->arguments_; }
+ virtual TypeArgumentsPtr arguments() const { return raw_ptr()->arguments_; }
virtual void set_arguments(const TypeArguments& value) const;
virtual TokenPosition token_pos() const { return raw_ptr()->token_pos_; }
virtual bool IsInstantiated(Genericity genericity = kAny,
@@ -7874,20 +7879,22 @@
// the signature fully represents the type and type arguments can be ignored.
// However, in case of a generic typedef, they document how the typedef class
// was parameterized to obtain the actual signature.
- RawFunction* signature() const;
+ FunctionPtr signature() const;
void set_signature(const Function& value) const;
- static intptr_t signature_offset() { return OFFSET_OF(RawType, signature_); }
+ static intptr_t signature_offset() {
+ return OFFSET_OF(TypeLayout, signature_);
+ }
virtual bool IsFunctionType() const {
return signature() != Function::null();
}
- virtual RawAbstractType* InstantiateFrom(
+ virtual AbstractTypePtr InstantiateFrom(
const TypeArguments& instantiator_type_arguments,
const TypeArguments& function_type_arguments,
intptr_t num_free_fun_type_params,
TrailPtr instantiation_trail,
Heap::Space space) const;
- virtual RawAbstractType* Canonicalize(TrailPtr trail = NULL) const;
+ virtual AbstractTypePtr Canonicalize(TrailPtr trail = NULL) const;
#if defined(DEBUG)
// Check if type is canonical.
virtual bool CheckIsCanonical(Thread* thread) const;
@@ -7898,77 +7905,77 @@
intptr_t ComputeHash() const;
static intptr_t InstanceSize() {
- return RoundedAllocationSize(sizeof(RawType));
+ return RoundedAllocationSize(sizeof(TypeLayout));
}
// The type of the literal 'null'.
- static RawType* NullType();
+ static TypePtr NullType();
// The 'dynamic' type.
- static RawType* DynamicType();
+ static TypePtr DynamicType();
// The 'void' type.
- static RawType* VoidType();
+ static TypePtr VoidType();
// The 'Never' type.
- static RawType* NeverType();
+ static TypePtr NeverType();
// The 'Object' type.
- static RawType* ObjectType();
+ static TypePtr ObjectType();
// The 'bool' type.
- static RawType* BoolType();
+ static TypePtr BoolType();
// The 'int' type.
- static RawType* IntType();
+ static TypePtr IntType();
// The 'int?' type.
- static RawType* NullableIntType();
+ static TypePtr NullableIntType();
// The 'Smi' type.
- static RawType* SmiType();
+ static TypePtr SmiType();
// The 'Mint' type.
- static RawType* MintType();
+ static TypePtr MintType();
// The 'double' type.
- static RawType* Double();
+ static TypePtr Double();
// The 'double?' type.
- static RawType* NullableDouble();
+ static TypePtr NullableDouble();
// The 'Float32x4' type.
- static RawType* Float32x4();
+ static TypePtr Float32x4();
// The 'Float64x2' type.
- static RawType* Float64x2();
+ static TypePtr Float64x2();
// The 'Int32x4' type.
- static RawType* Int32x4();
+ static TypePtr Int32x4();
// The 'num' type.
- static RawType* Number();
+ static TypePtr Number();
// The 'String' type.
- static RawType* StringType();
+ static TypePtr StringType();
// The 'Array' type.
- static RawType* ArrayType();
+ static TypePtr ArrayType();
// The 'Function' type.
- static RawType* DartFunctionType();
+ static TypePtr DartFunctionType();
// The 'Type' type.
- static RawType* DartTypeType();
+ static TypePtr DartTypeType();
// The finalized type of the given non-parameterized class.
- static RawType* NewNonParameterizedType(const Class& type_class);
+ static TypePtr NewNonParameterizedType(const Class& type_class);
- static RawType* New(const Class& clazz,
- const TypeArguments& arguments,
- TokenPosition token_pos,
- Nullability nullability = Nullability::kLegacy,
- Heap::Space space = Heap::kOld);
+ static TypePtr New(const Class& clazz,
+ const TypeArguments& arguments,
+ TokenPosition token_pos,
+ Nullability nullability = Nullability::kLegacy,
+ Heap::Space space = Heap::kOld);
private:
void SetHash(intptr_t value) const;
@@ -7980,7 +7987,7 @@
StoreNonPointer(&raw_ptr()->nullability_, static_cast<int8_t>(value));
}
- static RawType* New(Heap::Space space = Heap::kOld);
+ static TypePtr New(Heap::Space space = Heap::kOld);
FINAL_HEAP_OBJECT_IMPLEMENTATION(Type, AbstractType);
friend class Class;
@@ -7994,7 +8001,7 @@
// Note that the cycle always involves type arguments.
class TypeRef : public AbstractType {
public:
- static intptr_t type_offset() { return OFFSET_OF(RawTypeRef, type_); }
+ static intptr_t type_offset() { return OFFSET_OF(TypeRefLayout, type_); }
virtual bool IsFinalized() const {
const AbstractType& ref_type = AbstractType::Handle(type());
@@ -8013,15 +8020,15 @@
return (type() != AbstractType::null()) &&
AbstractType::Handle(type()).HasTypeClass();
}
- RawAbstractType* type() const { return raw_ptr()->type_; }
+ AbstractTypePtr type() const { return raw_ptr()->type_; }
void set_type(const AbstractType& value) const;
virtual classid_t type_class_id() const {
return AbstractType::Handle(type()).type_class_id();
}
- virtual RawClass* type_class() const {
+ virtual ClassPtr type_class() const {
return AbstractType::Handle(type()).type_class();
}
- virtual RawTypeArguments* arguments() const {
+ virtual TypeArgumentsPtr arguments() const {
return AbstractType::Handle(type()).arguments();
}
virtual TokenPosition token_pos() const {
@@ -8038,13 +8045,13 @@
const AbstractType& ref_type = AbstractType::Handle(type());
return !ref_type.IsNull() && ref_type.IsFunctionType();
}
- virtual RawTypeRef* InstantiateFrom(
+ virtual AbstractTypePtr InstantiateFrom(
const TypeArguments& instantiator_type_arguments,
const TypeArguments& function_type_arguments,
intptr_t num_free_fun_type_params,
TrailPtr instantiation_trail,
Heap::Space space) const;
- virtual RawAbstractType* Canonicalize(TrailPtr trail = NULL) const;
+ virtual AbstractTypePtr Canonicalize(TrailPtr trail = NULL) const;
#if defined(DEBUG)
// Check if typeref is canonical.
virtual bool CheckIsCanonical(Thread* thread) const;
@@ -8054,13 +8061,13 @@
virtual intptr_t Hash() const;
static intptr_t InstanceSize() {
- return RoundedAllocationSize(sizeof(RawTypeRef));
+ return RoundedAllocationSize(sizeof(TypeRefLayout));
}
- static RawTypeRef* New(const AbstractType& type);
+ static TypeRefPtr New(const AbstractType& type);
private:
- static RawTypeRef* New();
+ static TypeRefPtr New();
FINAL_HEAP_OBJECT_IMPLEMENTATION(TypeRef, AbstractType);
friend class Class;
@@ -8079,23 +8086,24 @@
class TypeParameter : public AbstractType {
public:
virtual bool IsFinalized() const {
- return RawTypeParameter::FinalizedBit::decode(raw_ptr()->flags_);
+ return TypeParameterLayout::FinalizedBit::decode(raw_ptr()->flags_);
}
virtual void SetIsFinalized() const;
virtual bool IsBeingFinalized() const { return false; }
bool IsGenericCovariantImpl() const {
- return RawTypeParameter::GenericCovariantImplBit::decode(raw_ptr()->flags_);
+ return TypeParameterLayout::GenericCovariantImplBit::decode(
+ raw_ptr()->flags_);
}
void SetGenericCovariantImpl(bool value) const;
virtual Nullability nullability() const {
return static_cast<Nullability>(raw_ptr()->nullability_);
}
- RawTypeParameter* ToNullability(Nullability value, Heap::Space space) const;
+ TypeParameterPtr ToNullability(Nullability value, Heap::Space space) const;
virtual bool HasTypeClass() const { return false; }
virtual classid_t type_class_id() const { return kIllegalCid; }
classid_t parameterized_class_id() const;
- RawClass* parameterized_class() const;
- RawFunction* parameterized_function() const {
+ ClassPtr parameterized_class() const;
+ FunctionPtr parameterized_function() const {
return raw_ptr()->parameterized_function_;
}
bool IsClassTypeParameter() const {
@@ -8104,10 +8112,10 @@
bool IsFunctionTypeParameter() const {
return parameterized_function() != Function::null();
}
- RawString* name() const { return raw_ptr()->name_; }
+ StringPtr name() const { return raw_ptr()->name_; }
intptr_t index() const { return raw_ptr()->index_; }
void set_index(intptr_t value) const;
- RawAbstractType* bound() const { return raw_ptr()->bound_; }
+ AbstractTypePtr bound() const { return raw_ptr()->bound_; }
void set_bound(const AbstractType& value) const;
virtual TokenPosition token_pos() const { return raw_ptr()->token_pos_; }
virtual bool IsInstantiated(Genericity genericity = kAny,
@@ -8117,13 +8125,13 @@
TypeEquality kind,
TrailPtr trail = NULL) const;
virtual bool IsRecursive() const { return false; }
- virtual RawAbstractType* InstantiateFrom(
+ virtual AbstractTypePtr InstantiateFrom(
const TypeArguments& instantiator_type_arguments,
const TypeArguments& function_type_arguments,
intptr_t num_free_fun_type_params,
TrailPtr instantiation_trail,
Heap::Space space) const;
- virtual RawAbstractType* Canonicalize(TrailPtr trail = NULL) const {
+ virtual AbstractTypePtr Canonicalize(TrailPtr trail = NULL) const {
return raw();
}
#if defined(DEBUG)
@@ -8138,23 +8146,23 @@
// given [instantiator_type_arguments] and [function_type_arguments].
// Unlike InstantiateFrom, nullability of type parameter is not applied to
// the result.
- RawAbstractType* GetFromTypeArguments(
+ AbstractTypePtr GetFromTypeArguments(
const TypeArguments& instantiator_type_arguments,
const TypeArguments& function_type_arguments) const;
static intptr_t InstanceSize() {
- return RoundedAllocationSize(sizeof(RawTypeParameter));
+ return RoundedAllocationSize(sizeof(TypeParameterLayout));
}
// Only one of parameterized_class and parameterized_function is non-null.
- static RawTypeParameter* New(const Class& parameterized_class,
- const Function& parameterized_function,
- intptr_t index,
- const String& name,
- const AbstractType& bound,
- bool is_generic_covariant_impl,
- Nullability nullability,
- TokenPosition token_pos);
+ static TypeParameterPtr New(const Class& parameterized_class,
+ const Function& parameterized_function,
+ intptr_t index,
+ const String& name,
+ const AbstractType& bound,
+ bool is_generic_covariant_impl,
+ Nullability nullability,
+ TokenPosition token_pos);
private:
intptr_t ComputeHash() const;
@@ -8167,7 +8175,7 @@
void set_flags(uint8_t flags) const;
void set_nullability(Nullability value) const;
- static RawTypeParameter* New();
+ static TypeParameterPtr New();
FINAL_HEAP_OBJECT_IMPLEMENTATION(TypeParameter, AbstractType);
friend class Class;
@@ -8177,11 +8185,11 @@
class Number : public Instance {
public:
// TODO(iposva): Add more useful Number methods.
- RawString* ToString(Heap::Space space) const;
+ StringPtr ToString(Heap::Space space) const;
// Numbers are canonicalized differently from other instances/strings.
- virtual RawInstance* CheckAndCanonicalize(Thread* thread,
- const char** error_str) const;
+ virtual InstancePtr CheckAndCanonicalize(Thread* thread,
+ const char** error_str) const;
#if defined(DEBUG)
// Check if number is canonical.
@@ -8196,20 +8204,20 @@
class Integer : public Number {
public:
- static RawInteger* New(const String& str, Heap::Space space = Heap::kNew);
+ static IntegerPtr New(const String& str, Heap::Space space = Heap::kNew);
// Creates a new Integer by given uint64_t value.
// Silently casts value to int64_t with wrap-around if it is greater
// than kMaxInt64.
- static RawInteger* NewFromUint64(uint64_t value,
- Heap::Space space = Heap::kNew);
+ static IntegerPtr NewFromUint64(uint64_t value,
+ Heap::Space space = Heap::kNew);
// Returns a canonical Integer object allocated in the old gen space.
// Returns null if integer is out of range.
- static RawInteger* NewCanonical(const String& str);
- static RawInteger* NewCanonical(int64_t value);
+ static IntegerPtr NewCanonical(const String& str);
+ static IntegerPtr NewCanonical(int64_t value);
- static RawInteger* New(int64_t value, Heap::Space space = Heap::kNew);
+ static IntegerPtr New(int64_t value, Heap::Space space = Heap::kNew);
// Returns true iff the given uint64_t value is representable as Dart integer.
static bool IsValueInRange(uint64_t value);
@@ -8223,7 +8231,7 @@
virtual uint32_t CanonicalizeHash() const { return AsTruncatedUint32Value(); }
virtual bool Equals(const Instance& other) const;
- virtual RawObject* HashCode() const { return raw(); }
+ virtual ObjectPtr HashCode() const { return raw(); }
virtual bool IsZero() const;
virtual bool IsNegative() const;
@@ -8242,26 +8250,26 @@
const char* ToHexCString(Zone* zone) const;
// Return the most compact presentation of an integer.
- RawInteger* AsValidInteger() const;
+ IntegerPtr AsValidInteger() const;
// Returns null to indicate that a bigint operation is required.
- RawInteger* ArithmeticOp(Token::Kind operation,
- const Integer& other,
- Heap::Space space = Heap::kNew) const;
- RawInteger* BitOp(Token::Kind operation,
- const Integer& other,
- Heap::Space space = Heap::kNew) const;
- RawInteger* ShiftOp(Token::Kind operation,
- const Integer& other,
- Heap::Space space = Heap::kNew) const;
+ IntegerPtr ArithmeticOp(Token::Kind operation,
+ const Integer& other,
+ Heap::Space space = Heap::kNew) const;
+ IntegerPtr BitOp(Token::Kind operation,
+ const Integer& other,
+ Heap::Space space = Heap::kNew) const;
+ IntegerPtr ShiftOp(Token::Kind operation,
+ const Integer& other,
+ Heap::Space space = Heap::kNew) const;
- static int64_t GetInt64Value(const RawInteger* obj) {
- intptr_t raw_value = reinterpret_cast<intptr_t>(obj);
+ static int64_t GetInt64Value(const IntegerPtr obj) {
+ intptr_t raw_value = static_cast<intptr_t>(obj);
if ((raw_value & kSmiTagMask) == kSmiTag) {
return (raw_value >> kSmiTagShift);
} else {
ASSERT(obj->IsMint());
- return reinterpret_cast<const RawMint*>(obj)->ptr()->value_;
+ return static_cast<const MintPtr>(obj)->ptr()->value_;
}
}
@@ -8276,7 +8284,7 @@
static const intptr_t kMaxValue = kSmiMax;
static const intptr_t kMinValue = kSmiMin;
- intptr_t Value() const { return ValueFromRawSmi(raw()); }
+ intptr_t Value() const { return RawSmiValue(raw()); }
virtual bool Equals(const Instance& other) const;
virtual bool IsZero() const { return Value() == 0; }
@@ -8292,35 +8300,33 @@
static intptr_t InstanceSize() { return 0; }
- static RawSmi* New(intptr_t value) {
- RawSmi* raw_smi = reinterpret_cast<RawSmi*>(
+ static SmiPtr New(intptr_t value) {
+ SmiPtr raw_smi = static_cast<SmiPtr>(
(static_cast<uintptr_t>(value) << kSmiTagShift) | kSmiTag);
- ASSERT(ValueFromRawSmi(raw_smi) == value);
+ ASSERT(RawSmiValue(raw_smi) == value);
return raw_smi;
}
- static RawSmi* FromAlignedAddress(uword address) {
+ static SmiPtr FromAlignedAddress(uword address) {
ASSERT((address & kSmiTagMask) == kSmiTag);
- return reinterpret_cast<RawSmi*>(address);
+ return static_cast<SmiPtr>(address);
}
- static RawClass* Class();
+ static ClassPtr Class();
- static intptr_t Value(const RawSmi* raw_smi) {
- return ValueFromRawSmi(raw_smi);
- }
+ static intptr_t Value(const SmiPtr raw_smi) { return RawSmiValue(raw_smi); }
static intptr_t RawValue(intptr_t value) {
- return reinterpret_cast<intptr_t>(New(value));
+ return static_cast<intptr_t>(New(value));
}
static bool IsValid(int64_t value) { return compiler::target::IsSmi(value); }
- void operator=(RawSmi* value) {
+ void operator=(SmiPtr value) {
raw_ = value;
CHECK_HANDLE();
}
- void operator^=(RawObject* value) {
+ void operator^=(ObjectPtr value) {
raw_ = value;
CHECK_HANDLE();
}
@@ -8362,7 +8368,7 @@
static_cast<int64_t>(DART_2PART_UINT64_C(0x80000000, 00000000));
int64_t value() const { return raw_ptr()->value_; }
- static intptr_t value_offset() { return OFFSET_OF(RawMint, value_); }
+ static intptr_t value_offset() { return OFFSET_OF(MintLayout, value_); }
virtual bool IsZero() const { return value() == 0; }
virtual bool IsNegative() const { return value() < 0; }
@@ -8378,16 +8384,16 @@
virtual int CompareWith(const Integer& other) const;
static intptr_t InstanceSize() {
- return RoundedAllocationSize(sizeof(RawMint));
+ return RoundedAllocationSize(sizeof(MintLayout));
}
protected:
// Only Integer::NewXXX is allowed to call Mint::NewXXX directly.
friend class Integer;
- static RawMint* New(int64_t value, Heap::Space space = Heap::kNew);
+ static MintPtr New(int64_t value, Heap::Space space = Heap::kNew);
- static RawMint* NewCanonical(int64_t value);
+ static MintPtr NewCanonical(int64_t value);
private:
void set_value(int64_t value) const;
@@ -8408,23 +8414,23 @@
virtual bool CanonicalizeEquals(const Instance& other) const;
virtual uint32_t CanonicalizeHash() const;
- static RawDouble* New(double d, Heap::Space space = Heap::kNew);
+ static DoublePtr New(double d, Heap::Space space = Heap::kNew);
- static RawDouble* New(const String& str, Heap::Space space = Heap::kNew);
+ static DoublePtr New(const String& str, Heap::Space space = Heap::kNew);
// Returns a canonical double object allocated in the old gen space.
- static RawDouble* NewCanonical(double d);
+ static DoublePtr NewCanonical(double d);
// Returns a canonical double object (allocated in the old gen space) or
// Double::null() if str points to a string that does not convert to a
// double value.
- static RawDouble* NewCanonical(const String& str);
+ static DoublePtr NewCanonical(const String& str);
static intptr_t InstanceSize() {
- return RoundedAllocationSize(sizeof(RawDouble));
+ return RoundedAllocationSize(sizeof(DoubleLayout));
}
- static intptr_t value_offset() { return OFFSET_OF(RawDouble, value_); }
+ static intptr_t value_offset() { return OFFSET_OF(DoubleLayout, value_); }
private:
void set_value(double value) const;
@@ -8449,9 +8455,10 @@
// simple. We choose a value that will prevent integer overflow for
// 2 byte strings, since it is the worst case.
#if defined(HASH_IN_OBJECT_HEADER)
- static const intptr_t kSizeofRawString = sizeof(RawInstance) + kWordSize;
+ static const intptr_t kSizeofRawString = sizeof(InstanceLayout) + kWordSize;
#else
- static const intptr_t kSizeofRawString = sizeof(RawInstance) + 2 * kWordSize;
+ static const intptr_t kSizeofRawString =
+ sizeof(InstanceLayout) + 2 * kWordSize;
#endif
static const intptr_t kMaxElements = kSmiMax / kTwoByteChar;
@@ -8485,7 +8492,7 @@
};
intptr_t Length() const { return Smi::Value(raw_ptr()->length_); }
- static intptr_t length_offset() { return OFFSET_OF(RawString, length_); }
+ static intptr_t length_offset() { return OFFSET_OF(StringLayout, length_); }
intptr_t Hash() const {
intptr_t result = GetCachedHash(raw());
@@ -8497,20 +8504,20 @@
return result;
}
- static intptr_t Hash(RawString* raw);
+ static intptr_t Hash(StringPtr raw);
bool HasHash() const {
- ASSERT(Smi::New(0) == NULL);
+ ASSERT(Smi::New(0) == nullptr);
return GetCachedHash(raw()) != 0;
}
- static intptr_t hash_offset() { return OFFSET_OF(RawString, hash_); }
+ static intptr_t hash_offset() { return OFFSET_OF(StringLayout, hash_); }
static intptr_t Hash(const String& str, intptr_t begin_index, intptr_t len);
static intptr_t Hash(const char* characters, intptr_t len);
static intptr_t Hash(const uint16_t* characters, intptr_t len);
static intptr_t Hash(const int32_t* characters, intptr_t len);
- static intptr_t HashRawSymbol(const RawString* symbol) {
- ASSERT(symbol->IsCanonical());
+ static intptr_t HashRawSymbol(const StringPtr symbol) {
+ ASSERT(symbol->ptr()->IsCanonical());
intptr_t result = GetCachedHash(symbol);
ASSERT(result != 0);
return result;
@@ -8519,7 +8526,7 @@
// Returns the hash of str1 + str2.
static intptr_t HashConcat(const String& str1, const String& str2);
- virtual RawObject* HashCode() const { return Integer::New(Hash()); }
+ virtual ObjectPtr HashCode() const { return Integer::New(Hash()); }
uint16_t CharAt(intptr_t index) const;
@@ -8563,15 +8570,15 @@
bool EndsWith(const String& other) const;
// Strings are canonicalized using the symbol table.
- virtual RawInstance* CheckAndCanonicalize(Thread* thread,
- const char** error_str) const;
+ virtual InstancePtr CheckAndCanonicalize(Thread* thread,
+ const char** error_str) const;
#if defined(DEBUG)
// Check if string is canonical.
virtual bool CheckIsCanonical(Thread* thread) const;
#endif // DEBUG
- bool IsSymbol() const { return raw()->IsCanonical(); }
+ bool IsSymbol() const { return raw()->ptr()->IsCanonical(); }
bool IsOneByteString() const {
return raw()->GetClassId() == kOneByteStringCid;
@@ -8601,48 +8608,48 @@
// Creates a new String object from a C string that is assumed to contain
// UTF-8 encoded characters and '\0' is considered a termination character.
// TODO(7123) - Rename this to FromCString(....).
- static RawString* New(const char* cstr, Heap::Space space = Heap::kNew);
+ static StringPtr New(const char* cstr, Heap::Space space = Heap::kNew);
// Creates a new String object from an array of UTF-8 encoded characters.
- static RawString* FromUTF8(const uint8_t* utf8_array,
+ static StringPtr FromUTF8(const uint8_t* utf8_array,
+ intptr_t array_len,
+ Heap::Space space = Heap::kNew);
+
+ // Creates a new String object from an array of Latin-1 encoded characters.
+ static StringPtr FromLatin1(const uint8_t* latin1_array,
+ intptr_t array_len,
+ Heap::Space space = Heap::kNew);
+
+ // Creates a new String object from an array of UTF-16 encoded characters.
+ static StringPtr FromUTF16(const uint16_t* utf16_array,
intptr_t array_len,
Heap::Space space = Heap::kNew);
- // Creates a new String object from an array of Latin-1 encoded characters.
- static RawString* FromLatin1(const uint8_t* latin1_array,
- intptr_t array_len,
- Heap::Space space = Heap::kNew);
-
- // Creates a new String object from an array of UTF-16 encoded characters.
- static RawString* FromUTF16(const uint16_t* utf16_array,
- intptr_t array_len,
- Heap::Space space = Heap::kNew);
-
// Creates a new String object from an array of UTF-32 encoded characters.
- static RawString* FromUTF32(const int32_t* utf32_array,
- intptr_t array_len,
- Heap::Space space = Heap::kNew);
+ static StringPtr FromUTF32(const int32_t* utf32_array,
+ intptr_t array_len,
+ Heap::Space space = Heap::kNew);
// Create a new String object from another Dart String instance.
- static RawString* New(const String& str, Heap::Space space = Heap::kNew);
+ static StringPtr New(const String& str, Heap::Space space = Heap::kNew);
// Creates a new External String object using the specified array of
// UTF-8 encoded characters as the external reference.
- static RawString* NewExternal(const uint8_t* utf8_array,
- intptr_t array_len,
- void* peer,
- intptr_t external_allocation_size,
- Dart_WeakPersistentHandleFinalizer callback,
- Heap::Space = Heap::kNew);
+ static StringPtr NewExternal(const uint8_t* utf8_array,
+ intptr_t array_len,
+ void* peer,
+ intptr_t external_allocation_size,
+ Dart_WeakPersistentHandleFinalizer callback,
+ Heap::Space = Heap::kNew);
// Creates a new External String object using the specified array of
// UTF-16 encoded characters as the external reference.
- static RawString* NewExternal(const uint16_t* utf16_array,
- intptr_t array_len,
- void* peer,
- intptr_t external_allocation_size,
- Dart_WeakPersistentHandleFinalizer callback,
- Heap::Space = Heap::kNew);
+ static StringPtr NewExternal(const uint16_t* utf16_array,
+ intptr_t array_len,
+ void* peer,
+ intptr_t external_allocation_size,
+ Dart_WeakPersistentHandleFinalizer callback,
+ Heap::Space = Heap::kNew);
static void Copy(const String& dst,
intptr_t dst_offset,
@@ -8658,62 +8665,61 @@
intptr_t src_offset,
intptr_t len);
- static RawString* EscapeSpecialCharacters(const String& str);
+ static StringPtr EscapeSpecialCharacters(const String& str);
// Encodes 'str' for use in an Internationalized Resource Identifier (IRI),
// a generalization of URI (percent-encoding). See RFC 3987.
static const char* EncodeIRI(const String& str);
// Returns null if 'str' is not a valid encoding.
- static RawString* DecodeIRI(const String& str);
- static RawString* Concat(const String& str1,
- const String& str2,
- Heap::Space space = Heap::kNew);
- static RawString* ConcatAll(const Array& strings,
- Heap::Space space = Heap::kNew);
+ static StringPtr DecodeIRI(const String& str);
+ static StringPtr Concat(const String& str1,
+ const String& str2,
+ Heap::Space space = Heap::kNew);
+ static StringPtr ConcatAll(const Array& strings,
+ Heap::Space space = Heap::kNew);
// Concat all strings in 'strings' from 'start' to 'end' (excluding).
- static RawString* ConcatAllRange(const Array& strings,
- intptr_t start,
- intptr_t end,
- Heap::Space space = Heap::kNew);
+ static StringPtr ConcatAllRange(const Array& strings,
+ intptr_t start,
+ intptr_t end,
+ Heap::Space space = Heap::kNew);
- static RawString* SubString(const String& str,
- intptr_t begin_index,
- Heap::Space space = Heap::kNew);
- static RawString* SubString(const String& str,
- intptr_t begin_index,
- intptr_t length,
- Heap::Space space = Heap::kNew) {
+ static StringPtr SubString(const String& str,
+ intptr_t begin_index,
+ Heap::Space space = Heap::kNew);
+ static StringPtr SubString(const String& str,
+ intptr_t begin_index,
+ intptr_t length,
+ Heap::Space space = Heap::kNew) {
return SubString(Thread::Current(), str, begin_index, length, space);
}
- static RawString* SubString(Thread* thread,
- const String& str,
- intptr_t begin_index,
- intptr_t length,
- Heap::Space space = Heap::kNew);
+ static StringPtr SubString(Thread* thread,
+ const String& str,
+ intptr_t begin_index,
+ intptr_t length,
+ Heap::Space space = Heap::kNew);
- static RawString* Transform(int32_t (*mapping)(int32_t ch),
- const String& str,
- Heap::Space space = Heap::kNew);
+ static StringPtr Transform(int32_t (*mapping)(int32_t ch),
+ const String& str,
+ Heap::Space space = Heap::kNew);
- static RawString* ToUpperCase(const String& str,
- Heap::Space space = Heap::kNew);
- static RawString* ToLowerCase(const String& str,
- Heap::Space space = Heap::kNew);
+ static StringPtr ToUpperCase(const String& str,
+ Heap::Space space = Heap::kNew);
+ static StringPtr ToLowerCase(const String& str,
+ Heap::Space space = Heap::kNew);
- static RawString* RemovePrivateKey(const String& name);
+ static StringPtr RemovePrivateKey(const String& name);
static const char* ScrubName(const String& name, bool is_extension = false);
- static RawString* ScrubNameRetainPrivate(const String& name,
- bool is_extension = false);
+ static StringPtr ScrubNameRetainPrivate(const String& name,
+ bool is_extension = false);
static bool EqualsIgnoringPrivateKey(const String& str1, const String& str2);
- static RawString* NewFormatted(const char* format, ...)
- PRINTF_ATTRIBUTE(1, 2);
- static RawString* NewFormatted(Heap::Space space, const char* format, ...)
+ static StringPtr NewFormatted(const char* format, ...) PRINTF_ATTRIBUTE(1, 2);
+ static StringPtr NewFormatted(Heap::Space space, const char* format, ...)
PRINTF_ATTRIBUTE(2, 3);
- static RawString* NewFormattedV(const char* format,
- va_list args,
- Heap::Space space = Heap::kNew);
+ static StringPtr NewFormattedV(const char* format,
+ va_list args,
+ Heap::Space space = Heap::kNew);
static bool ParseDouble(const String& str,
intptr_t start,
@@ -8721,11 +8727,11 @@
double* result);
#if !defined(HASH_IN_OBJECT_HEADER)
- static uint32_t GetCachedHash(const RawString* obj) {
+ static uint32_t GetCachedHash(const StringPtr obj) {
return Smi::Value(obj->ptr()->hash_);
}
- static void SetCachedHash(RawString* obj, uintptr_t hash) {
+ static void SetCachedHash(StringPtr obj, uintptr_t hash) {
obj->ptr()->hash_ = Smi::New(hash);
}
#endif
@@ -8765,7 +8771,7 @@
friend class TwoByteString;
friend class ExternalOneByteString;
friend class ExternalTwoByteString;
- friend class RawOneByteString;
+ friend class OneByteStringLayout;
friend class RODataSerializationCluster; // SetHash
friend class Pass2Visitor; // Stack "handle"
};
@@ -8782,28 +8788,28 @@
NoSafepointScope no_safepoint;
*CharAddr(str, index) = code_unit;
}
- static RawOneByteString* EscapeSpecialCharacters(const String& str);
+ static OneByteStringPtr EscapeSpecialCharacters(const String& str);
// We use the same maximum elements for all strings.
static const intptr_t kBytesPerElement = 1;
static const intptr_t kMaxElements = String::kMaxElements;
static intptr_t data_offset() {
- return OFFSET_OF_RETURNED_VALUE(RawOneByteString, data);
+ return OFFSET_OF_RETURNED_VALUE(OneByteStringLayout, data);
}
- static intptr_t UnroundedSize(RawOneByteString* str) {
+ static intptr_t UnroundedSize(OneByteStringPtr str) {
return UnroundedSize(Smi::Value(str->ptr()->length_));
}
static intptr_t UnroundedSize(intptr_t len) {
- return sizeof(RawOneByteString) + (len * kBytesPerElement);
+ return sizeof(OneByteStringLayout) + (len * kBytesPerElement);
}
static intptr_t InstanceSize() {
- ASSERT(sizeof(RawOneByteString) ==
- OFFSET_OF_RETURNED_VALUE(RawOneByteString, data));
+ ASSERT(sizeof(OneByteStringLayout) ==
+ OFFSET_OF_RETURNED_VALUE(OneByteStringLayout, data));
return 0;
}
static intptr_t InstanceSize(intptr_t len) {
- ASSERT(sizeof(RawOneByteString) == String::kSizeofRawString);
+ ASSERT(sizeof(OneByteStringLayout) == String::kSizeofRawString);
ASSERT(0 <= len && len <= kMaxElements);
#if defined(HASH_IN_OBJECT_HEADER)
// We have to pad zero-length raw strings so that they can be externalized.
@@ -8814,57 +8820,57 @@
return String::RoundedAllocationSize(UnroundedSize(len));
}
- static RawOneByteString* New(intptr_t len, Heap::Space space);
- static RawOneByteString* New(const char* c_string,
- Heap::Space space = Heap::kNew) {
+ static OneByteStringPtr New(intptr_t len, Heap::Space space);
+ static OneByteStringPtr New(const char* c_string,
+ Heap::Space space = Heap::kNew) {
return New(reinterpret_cast<const uint8_t*>(c_string), strlen(c_string),
space);
}
- static RawOneByteString* New(const uint8_t* characters,
- intptr_t len,
- Heap::Space space);
- static RawOneByteString* New(const uint16_t* characters,
- intptr_t len,
- Heap::Space space);
- static RawOneByteString* New(const int32_t* characters,
- intptr_t len,
- Heap::Space space);
- static RawOneByteString* New(const String& str, Heap::Space space);
+ static OneByteStringPtr New(const uint8_t* characters,
+ intptr_t len,
+ Heap::Space space);
+ static OneByteStringPtr New(const uint16_t* characters,
+ intptr_t len,
+ Heap::Space space);
+ static OneByteStringPtr New(const int32_t* characters,
+ intptr_t len,
+ Heap::Space space);
+ static OneByteStringPtr New(const String& str, Heap::Space space);
// 'other' must be OneByteString.
- static RawOneByteString* New(const String& other_one_byte_string,
- intptr_t other_start_index,
- intptr_t other_len,
- Heap::Space space);
+ static OneByteStringPtr New(const String& other_one_byte_string,
+ intptr_t other_start_index,
+ intptr_t other_len,
+ Heap::Space space);
- static RawOneByteString* New(const TypedData& other_typed_data,
- intptr_t other_start_index,
- intptr_t other_len,
- Heap::Space space = Heap::kNew);
+ static OneByteStringPtr New(const TypedData& other_typed_data,
+ intptr_t other_start_index,
+ intptr_t other_len,
+ Heap::Space space = Heap::kNew);
- static RawOneByteString* New(const ExternalTypedData& other_typed_data,
- intptr_t other_start_index,
- intptr_t other_len,
- Heap::Space space = Heap::kNew);
+ static OneByteStringPtr New(const ExternalTypedData& other_typed_data,
+ intptr_t other_start_index,
+ intptr_t other_len,
+ Heap::Space space = Heap::kNew);
- static RawOneByteString* Concat(const String& str1,
- const String& str2,
- Heap::Space space);
- static RawOneByteString* ConcatAll(const Array& strings,
- intptr_t start,
- intptr_t end,
- intptr_t len,
- Heap::Space space);
+ static OneByteStringPtr Concat(const String& str1,
+ const String& str2,
+ Heap::Space space);
+ static OneByteStringPtr ConcatAll(const Array& strings,
+ intptr_t start,
+ intptr_t end,
+ intptr_t len,
+ Heap::Space space);
- static RawOneByteString* Transform(int32_t (*mapping)(int32_t ch),
- const String& str,
- Heap::Space space);
+ static OneByteStringPtr Transform(int32_t (*mapping)(int32_t ch),
+ const String& str,
+ Heap::Space space);
// High performance version of substring for one-byte strings.
// "str" must be OneByteString.
- static RawOneByteString* SubStringUnchecked(const String& str,
- intptr_t begin_index,
- intptr_t length,
- Heap::Space space);
+ static OneByteStringPtr SubStringUnchecked(const String& str,
+ intptr_t begin_index,
+ intptr_t length,
+ Heap::Space space);
static void SetPeer(const String& str,
void* peer,
@@ -8873,17 +8879,17 @@
static const ClassId kClassId = kOneByteStringCid;
- static RawOneByteString* null() {
- return reinterpret_cast<RawOneByteString*>(Object::null());
+ static OneByteStringPtr null() {
+ return static_cast<OneByteStringPtr>(Object::null());
}
private:
- static RawOneByteString* raw(const String& str) {
- return reinterpret_cast<RawOneByteString*>(str.raw());
+ static OneByteStringPtr raw(const String& str) {
+ return static_cast<OneByteStringPtr>(str.raw());
}
- static const RawOneByteString* raw_ptr(const String& str) {
- return reinterpret_cast<const RawOneByteString*>(str.raw_ptr());
+ static const OneByteStringLayout* raw_ptr(const String& str) {
+ return reinterpret_cast<const OneByteStringLayout*>(str.raw_ptr());
}
static uint8_t* CharAddr(const String& str, intptr_t index) {
@@ -8897,11 +8903,11 @@
return &str.UnsafeMutableNonPointer(raw_ptr(str)->data())[0];
}
- static RawOneByteString* ReadFrom(SnapshotReader* reader,
- intptr_t object_id,
- intptr_t tags,
- Snapshot::Kind kind,
- bool as_reference);
+ static OneByteStringPtr ReadFrom(SnapshotReader* reader,
+ intptr_t object_id,
+ intptr_t tags,
+ Snapshot::Kind kind,
+ bool as_reference);
friend class Class;
friend class String;
@@ -8925,29 +8931,29 @@
*CharAddr(str, index) = ch;
}
- static RawTwoByteString* EscapeSpecialCharacters(const String& str);
+ static TwoByteStringPtr EscapeSpecialCharacters(const String& str);
// We use the same maximum elements for all strings.
static const intptr_t kBytesPerElement = 2;
static const intptr_t kMaxElements = String::kMaxElements;
static intptr_t data_offset() {
- return OFFSET_OF_RETURNED_VALUE(RawTwoByteString, data);
+ return OFFSET_OF_RETURNED_VALUE(TwoByteStringLayout, data);
}
- static intptr_t UnroundedSize(RawTwoByteString* str) {
+ static intptr_t UnroundedSize(TwoByteStringPtr str) {
return UnroundedSize(Smi::Value(str->ptr()->length_));
}
static intptr_t UnroundedSize(intptr_t len) {
- return sizeof(RawTwoByteString) + (len * kBytesPerElement);
+ return sizeof(TwoByteStringLayout) + (len * kBytesPerElement);
}
static intptr_t InstanceSize() {
- ASSERT(sizeof(RawTwoByteString) ==
- OFFSET_OF_RETURNED_VALUE(RawTwoByteString, data));
+ ASSERT(sizeof(TwoByteStringLayout) ==
+ OFFSET_OF_RETURNED_VALUE(TwoByteStringLayout, data));
return 0;
}
static intptr_t InstanceSize(intptr_t len) {
- ASSERT(sizeof(RawTwoByteString) == String::kSizeofRawString);
+ ASSERT(sizeof(TwoByteStringLayout) == String::kSizeofRawString);
ASSERT(0 <= len && len <= kMaxElements);
// We have to pad zero-length raw strings so that they can be externalized.
// If we don't pad, then the external string object does not fit in the
@@ -8956,57 +8962,57 @@
return String::RoundedAllocationSize(UnroundedSize(len));
}
- static RawTwoByteString* New(intptr_t len, Heap::Space space);
- static RawTwoByteString* New(const uint16_t* characters,
- intptr_t len,
- Heap::Space space);
- static RawTwoByteString* New(intptr_t utf16_len,
- const int32_t* characters,
- intptr_t len,
- Heap::Space space);
- static RawTwoByteString* New(const String& str, Heap::Space space);
+ static TwoByteStringPtr New(intptr_t len, Heap::Space space);
+ static TwoByteStringPtr New(const uint16_t* characters,
+ intptr_t len,
+ Heap::Space space);
+ static TwoByteStringPtr New(intptr_t utf16_len,
+ const int32_t* characters,
+ intptr_t len,
+ Heap::Space space);
+ static TwoByteStringPtr New(const String& str, Heap::Space space);
- static RawTwoByteString* New(const TypedData& other_typed_data,
- intptr_t other_start_index,
- intptr_t other_len,
- Heap::Space space = Heap::kNew);
+ static TwoByteStringPtr New(const TypedData& other_typed_data,
+ intptr_t other_start_index,
+ intptr_t other_len,
+ Heap::Space space = Heap::kNew);
- static RawTwoByteString* New(const ExternalTypedData& other_typed_data,
- intptr_t other_start_index,
- intptr_t other_len,
- Heap::Space space = Heap::kNew);
+ static TwoByteStringPtr New(const ExternalTypedData& other_typed_data,
+ intptr_t other_start_index,
+ intptr_t other_len,
+ Heap::Space space = Heap::kNew);
- static RawTwoByteString* Concat(const String& str1,
- const String& str2,
- Heap::Space space);
- static RawTwoByteString* ConcatAll(const Array& strings,
- intptr_t start,
- intptr_t end,
- intptr_t len,
- Heap::Space space);
+ static TwoByteStringPtr Concat(const String& str1,
+ const String& str2,
+ Heap::Space space);
+ static TwoByteStringPtr ConcatAll(const Array& strings,
+ intptr_t start,
+ intptr_t end,
+ intptr_t len,
+ Heap::Space space);
- static RawTwoByteString* Transform(int32_t (*mapping)(int32_t ch),
- const String& str,
- Heap::Space space);
+ static TwoByteStringPtr Transform(int32_t (*mapping)(int32_t ch),
+ const String& str,
+ Heap::Space space);
static void SetPeer(const String& str,
void* peer,
intptr_t external_allocation_size,
Dart_WeakPersistentHandleFinalizer callback);
- static RawTwoByteString* null() {
- return reinterpret_cast<RawTwoByteString*>(Object::null());
+ static TwoByteStringPtr null() {
+ return static_cast<TwoByteStringPtr>(Object::null());
}
static const ClassId kClassId = kTwoByteStringCid;
private:
- static RawTwoByteString* raw(const String& str) {
- return reinterpret_cast<RawTwoByteString*>(str.raw());
+ static TwoByteStringPtr raw(const String& str) {
+ return static_cast<TwoByteStringPtr>(str.raw());
}
- static const RawTwoByteString* raw_ptr(const String& str) {
- return reinterpret_cast<const RawTwoByteString*>(str.raw_ptr());
+ static const TwoByteStringLayout* raw_ptr(const String& str) {
+ return reinterpret_cast<const TwoByteStringLayout*>(str.raw_ptr());
}
static uint16_t* CharAddr(const String& str, intptr_t index) {
@@ -9022,11 +9028,11 @@
return &str.UnsafeMutableNonPointer(raw_ptr(str)->data())[0];
}
- static RawTwoByteString* ReadFrom(SnapshotReader* reader,
- intptr_t object_id,
- intptr_t tags,
- Snapshot::Kind kind,
- bool as_reference);
+ static TwoByteStringPtr ReadFrom(SnapshotReader* reader,
+ intptr_t object_id,
+ intptr_t tags,
+ Snapshot::Kind kind,
+ bool as_reference);
friend class Class;
friend class String;
@@ -9044,7 +9050,7 @@
static void* GetPeer(const String& str) { return raw_ptr(str)->peer_; }
static intptr_t external_data_offset() {
- return OFFSET_OF(RawExternalOneByteString, external_data_);
+ return OFFSET_OF(ExternalOneByteStringLayout, external_data_);
}
// We use the same maximum elements for all strings.
@@ -9052,10 +9058,10 @@
static const intptr_t kMaxElements = String::kMaxElements;
static intptr_t InstanceSize() {
- return String::RoundedAllocationSize(sizeof(RawExternalOneByteString));
+ return String::RoundedAllocationSize(sizeof(ExternalOneByteStringLayout));
}
- static RawExternalOneByteString* New(
+ static ExternalOneByteStringPtr New(
const uint8_t* characters,
intptr_t len,
void* peer,
@@ -9063,23 +9069,23 @@
Dart_WeakPersistentHandleFinalizer callback,
Heap::Space space);
- static RawExternalOneByteString* null() {
- return reinterpret_cast<RawExternalOneByteString*>(Object::null());
+ static ExternalOneByteStringPtr null() {
+ return static_cast<ExternalOneByteStringPtr>(Object::null());
}
- static RawOneByteString* EscapeSpecialCharacters(const String& str);
- static RawOneByteString* EncodeIRI(const String& str);
- static RawOneByteString* DecodeIRI(const String& str);
+ static OneByteStringPtr EscapeSpecialCharacters(const String& str);
+ static OneByteStringPtr EncodeIRI(const String& str);
+ static OneByteStringPtr DecodeIRI(const String& str);
static const ClassId kClassId = kExternalOneByteStringCid;
private:
- static RawExternalOneByteString* raw(const String& str) {
- return reinterpret_cast<RawExternalOneByteString*>(str.raw());
+ static ExternalOneByteStringPtr raw(const String& str) {
+ return static_cast<ExternalOneByteStringPtr>(str.raw());
}
- static const RawExternalOneByteString* raw_ptr(const String& str) {
- return reinterpret_cast<const RawExternalOneByteString*>(str.raw_ptr());
+ static const ExternalOneByteStringLayout* raw_ptr(const String& str) {
+ return reinterpret_cast<const ExternalOneByteStringLayout*>(str.raw_ptr());
}
static const uint8_t* CharAddr(const String& str, intptr_t index) {
@@ -9107,11 +9113,11 @@
Dart_WeakPersistentHandle handle,
void* peer);
- static RawExternalOneByteString* ReadFrom(SnapshotReader* reader,
- intptr_t object_id,
- intptr_t tags,
- Snapshot::Kind kind,
- bool as_reference);
+ static ExternalOneByteStringPtr ReadFrom(SnapshotReader* reader,
+ intptr_t object_id,
+ intptr_t tags,
+ Snapshot::Kind kind,
+ bool as_reference);
static intptr_t NextFieldOffset() {
// Indicates this class cannot be extended by dart code.
@@ -9135,7 +9141,7 @@
static void* GetPeer(const String& str) { return raw_ptr(str)->peer_; }
static intptr_t external_data_offset() {
- return OFFSET_OF(RawExternalTwoByteString, external_data_);
+ return OFFSET_OF(ExternalTwoByteStringLayout, external_data_);
}
// We use the same maximum elements for all strings.
@@ -9143,10 +9149,10 @@
static const intptr_t kMaxElements = String::kMaxElements;
static intptr_t InstanceSize() {
- return String::RoundedAllocationSize(sizeof(RawExternalTwoByteString));
+ return String::RoundedAllocationSize(sizeof(ExternalTwoByteStringLayout));
}
- static RawExternalTwoByteString* New(
+ static ExternalTwoByteStringPtr New(
const uint16_t* characters,
intptr_t len,
void* peer,
@@ -9154,19 +9160,19 @@
Dart_WeakPersistentHandleFinalizer callback,
Heap::Space space = Heap::kNew);
- static RawExternalTwoByteString* null() {
- return reinterpret_cast<RawExternalTwoByteString*>(Object::null());
+ static ExternalTwoByteStringPtr null() {
+ return static_cast<ExternalTwoByteStringPtr>(Object::null());
}
static const ClassId kClassId = kExternalTwoByteStringCid;
private:
- static RawExternalTwoByteString* raw(const String& str) {
- return reinterpret_cast<RawExternalTwoByteString*>(str.raw());
+ static ExternalTwoByteStringPtr raw(const String& str) {
+ return static_cast<ExternalTwoByteStringPtr>(str.raw());
}
- static const RawExternalTwoByteString* raw_ptr(const String& str) {
- return reinterpret_cast<const RawExternalTwoByteString*>(str.raw_ptr());
+ static const ExternalTwoByteStringLayout* raw_ptr(const String& str) {
+ return reinterpret_cast<const ExternalTwoByteStringLayout*>(str.raw_ptr());
}
static const uint16_t* CharAddr(const String& str, intptr_t index) {
@@ -9194,11 +9200,11 @@
Dart_WeakPersistentHandle handle,
void* peer);
- static RawExternalTwoByteString* ReadFrom(SnapshotReader* reader,
- intptr_t object_id,
- intptr_t tags,
- Snapshot::Kind kind,
- bool as_reference);
+ static ExternalTwoByteStringPtr ReadFrom(SnapshotReader* reader,
+ intptr_t object_id,
+ intptr_t tags,
+ Snapshot::Kind kind,
+ bool as_reference);
static intptr_t NextFieldOffset() {
// Indicates this class cannot be extended by dart code.
@@ -9217,7 +9223,7 @@
bool value() const { return raw_ptr()->value_; }
static intptr_t InstanceSize() {
- return RoundedAllocationSize(sizeof(RawBool));
+ return RoundedAllocationSize(sizeof(BoolLayout));
}
static const Bool& True() { return Object::bool_true(); }
@@ -9238,7 +9244,7 @@
}
// New should only be called to initialize the two legal bool values.
- static RawBool* New(bool value);
+ static BoolPtr New(bool value);
FINAL_HEAP_OBJECT_IMPLEMENTATION(Bool, Instance);
friend class Class;
@@ -9258,25 +9264,25 @@
}
intptr_t Length() const { return LengthOf(raw()); }
- static intptr_t LengthOf(const RawArray* array) {
+ static intptr_t LengthOf(const ArrayPtr array) {
return Smi::Value(array->ptr()->length_);
}
- static intptr_t length_offset() { return OFFSET_OF(RawArray, length_); }
+ static intptr_t length_offset() { return OFFSET_OF(ArrayLayout, length_); }
static intptr_t data_offset() {
- return OFFSET_OF_RETURNED_VALUE(RawArray, data);
+ return OFFSET_OF_RETURNED_VALUE(ArrayLayout, data);
}
static intptr_t element_offset(intptr_t index) {
- return OFFSET_OF_RETURNED_VALUE(RawArray, data) + kWordSize * index;
+ return OFFSET_OF_RETURNED_VALUE(ArrayLayout, data) + kWordSize * index;
}
- struct ArrayLayout {
+ struct ArrayTraits {
static intptr_t elements_start_offset() { return Array::data_offset(); }
static constexpr intptr_t kElementSize = kWordSize;
};
- static bool Equals(RawArray* a, RawArray* b) {
+ static bool Equals(ArrayPtr a, ArrayPtr b) {
if (a == b) return true;
if (a->IsRawNull() || b->IsRawNull()) return false;
if (a->ptr()->length_ != b->ptr()->length_) return false;
@@ -9285,28 +9291,27 @@
return memcmp(a->ptr()->data(), b->ptr()->data(), kWordSize * length) == 0;
}
- static RawObject** DataOf(RawArray* array) { return array->ptr()->data(); }
+ static ObjectPtr* DataOf(ArrayPtr array) { return array->ptr()->data(); }
- RawObject* At(intptr_t index) const { return *ObjectAddr(index); }
+ ObjectPtr At(intptr_t index) const { return *ObjectAddr(index); }
void SetAt(intptr_t index, const Object& value) const {
// TODO(iposva): Add storing NoSafepointScope.
StoreArrayPointer(ObjectAddr(index), value.raw());
}
// Access to the array with acquire release semantics.
- RawObject* AtAcquire(intptr_t index) const {
- return LoadPointer<RawObject*, std::memory_order_acquire>(
- ObjectAddr(index));
+ ObjectPtr AtAcquire(intptr_t index) const {
+ return LoadPointer<ObjectPtr, std::memory_order_acquire>(ObjectAddr(index));
}
void SetAtRelease(intptr_t index, const Object& value) const {
// TODO(iposva): Add storing NoSafepointScope.
- StoreArrayPointer<RawObject*, std::memory_order_release>(ObjectAddr(index),
- value.raw());
+ StoreArrayPointer<ObjectPtr, std::memory_order_release>(ObjectAddr(index),
+ value.raw());
}
bool IsImmutable() const { return raw()->GetClassId() == kImmutableArrayCid; }
- virtual RawTypeArguments* GetTypeArguments() const {
+ virtual TypeArgumentsPtr GetTypeArguments() const {
return raw_ptr()->type_arguments_;
}
virtual void SetTypeArguments(const TypeArguments& value) const {
@@ -9327,10 +9332,10 @@
static const intptr_t kBytesPerElement = kWordSize;
static const intptr_t kMaxElements = kSmiMax / kBytesPerElement;
static const intptr_t kMaxNewSpaceElements =
- (Heap::kNewAllocatableSize - sizeof(RawArray)) / kBytesPerElement;
+ (Heap::kNewAllocatableSize - sizeof(ArrayLayout)) / kBytesPerElement;
static intptr_t type_arguments_offset() {
- return OFFSET_OF(RawArray, type_arguments_);
+ return OFFSET_OF(ArrayLayout, type_arguments_);
}
static bool IsValidLength(intptr_t len) {
@@ -9338,15 +9343,16 @@
}
static intptr_t InstanceSize() {
- ASSERT(sizeof(RawArray) == OFFSET_OF_RETURNED_VALUE(RawArray, data));
+ ASSERT(sizeof(ArrayLayout) == OFFSET_OF_RETURNED_VALUE(ArrayLayout, data));
return 0;
}
static intptr_t InstanceSize(intptr_t len) {
// Ensure that variable length data is not adding to the object length.
- ASSERT(sizeof(RawArray) == (sizeof(RawInstance) + (2 * kWordSize)));
+ ASSERT(sizeof(ArrayLayout) == (sizeof(InstanceLayout) + (2 * kWordSize)));
ASSERT(IsValidLength(len));
- return RoundedAllocationSize(sizeof(RawArray) + (len * kBytesPerElement));
+ return RoundedAllocationSize(sizeof(ArrayLayout) +
+ (len * kBytesPerElement));
}
// Returns true if all elements are OK for canonicalization.
@@ -9357,17 +9363,17 @@
// to ImmutableArray.
void MakeImmutable() const;
- static RawArray* New(intptr_t len, Heap::Space space = Heap::kNew);
- static RawArray* New(intptr_t len,
- const AbstractType& element_type,
- Heap::Space space = Heap::kNew);
+ static ArrayPtr New(intptr_t len, Heap::Space space = Heap::kNew);
+ static ArrayPtr New(intptr_t len,
+ const AbstractType& element_type,
+ Heap::Space space = Heap::kNew);
// Creates and returns a new array with 'new_length'. Copies all elements from
// 'source' to the new array. 'new_length' must be greater than or equal to
// 'source.Length()'. 'source' can be null.
- static RawArray* Grow(const Array& source,
- intptr_t new_length,
- Heap::Space space = Heap::kNew);
+ static ArrayPtr Grow(const Array& source,
+ intptr_t new_length,
+ Heap::Space space = Heap::kNew);
// Truncates the array to a given length. 'new_length' must be less than
// or equal to 'source.Length()'. The remaining unused part of the array is
@@ -9383,20 +9389,18 @@
// set to an empty array.
// If the unique parameter is false, the function is allowed to return
// a shared Array instance.
- static RawArray* MakeFixedLength(const GrowableObjectArray& growable_array,
- bool unique = false);
+ static ArrayPtr MakeFixedLength(const GrowableObjectArray& growable_array,
+ bool unique = false);
- RawArray* Slice(intptr_t start,
- intptr_t count,
- bool with_type_argument) const;
+ ArrayPtr Slice(intptr_t start, intptr_t count, bool with_type_argument) const;
protected:
- static RawArray* New(intptr_t class_id,
- intptr_t len,
- Heap::Space space = Heap::kNew);
+ static ArrayPtr New(intptr_t class_id,
+ intptr_t len,
+ Heap::Space space = Heap::kNew);
private:
- RawObject* const* ObjectAddr(intptr_t index) const {
+ ObjectPtr const* ObjectAddr(intptr_t index) const {
// TODO(iposva): Determine if we should throw an exception here.
ASSERT((index >= 0) && (index < Length()));
return &raw_ptr()->data()[index];
@@ -9411,17 +9415,17 @@
template <typename type, std::memory_order order = std::memory_order_relaxed>
void StoreArrayPointer(type const* addr, type value) const {
- raw()->StoreArrayPointer<type, order>(addr, value);
+ raw()->ptr()->StoreArrayPointer<type, order>(addr, value);
}
// Store a range of pointers [from, from + count) into [to, to + count).
// TODO(koda): Use this to fix Object::Clone's broken store buffer logic.
- void StoreArrayPointers(RawObject* const* to,
- RawObject* const* from,
+ void StoreArrayPointers(ObjectPtr const* to,
+ ObjectPtr const* from,
intptr_t count) {
ASSERT(Contains(reinterpret_cast<uword>(to)));
if (raw()->IsNewObject()) {
- memmove(const_cast<RawObject**>(to), from, count * kWordSize);
+ memmove(const_cast<ObjectPtr*>(to), from, count * kWordSize);
} else {
for (intptr_t i = 0; i < count; ++i) {
StoreArrayPointer(&to[i], from[i]);
@@ -9439,13 +9443,13 @@
class ImmutableArray : public AllStatic {
public:
- static RawImmutableArray* New(intptr_t len, Heap::Space space = Heap::kNew);
+ static ImmutableArrayPtr New(intptr_t len, Heap::Space space = Heap::kNew);
- static RawImmutableArray* ReadFrom(SnapshotReader* reader,
- intptr_t object_id,
- intptr_t tags,
- Snapshot::Kind kind,
- bool as_reference);
+ static ImmutableArrayPtr ReadFrom(SnapshotReader* reader,
+ intptr_t object_id,
+ intptr_t tags,
+ Snapshot::Kind kind,
+ bool as_reference);
static const ClassId kClassId = kImmutableArrayCid;
@@ -9461,8 +9465,8 @@
return -kWordSize;
}
- static RawImmutableArray* raw(const Array& array) {
- return reinterpret_cast<RawImmutableArray*>(array.raw());
+ static ImmutableArrayPtr raw(const Array& array) {
+ return static_cast<ImmutableArrayPtr>(array.raw());
}
friend class Class;
@@ -9485,12 +9489,12 @@
StoreSmi(&raw_ptr()->length_, Smi::New(value));
}
- RawArray* data() const { return raw_ptr()->data_; }
+ ArrayPtr data() const { return raw_ptr()->data_; }
void SetData(const Array& value) const {
StorePointer(&raw_ptr()->data_, value.raw());
}
- RawObject* At(intptr_t index) const {
+ ObjectPtr At(intptr_t index) const {
NoSafepointScope no_safepoint;
ASSERT(!IsNull());
ASSERT(index < Length());
@@ -9501,15 +9505,15 @@
ASSERT(index < Length());
// TODO(iposva): Add storing NoSafepointScope.
- data()->StoreArrayPointer(ObjectAddr(index), value.raw());
+ data()->ptr()->StoreArrayPointer(ObjectAddr(index), value.raw());
}
void Add(const Object& value, Heap::Space space = Heap::kNew) const;
void Grow(intptr_t new_capacity, Heap::Space space = Heap::kNew) const;
- RawObject* RemoveLast() const;
+ ObjectPtr RemoveLast() const;
- virtual RawTypeArguments* GetTypeArguments() const {
+ virtual TypeArgumentsPtr GetTypeArguments() const {
return raw_ptr()->type_arguments_;
}
virtual void SetTypeArguments(const TypeArguments& value) const {
@@ -9528,46 +9532,46 @@
}
// We don't expect a growable object array to be canonicalized.
- virtual RawInstance* CheckAndCanonicalize(Thread* thread,
- const char** error_str) const {
+ virtual InstancePtr CheckAndCanonicalize(Thread* thread,
+ const char** error_str) const {
UNREACHABLE();
return Instance::null();
}
static intptr_t type_arguments_offset() {
- return OFFSET_OF(RawGrowableObjectArray, type_arguments_);
+ return OFFSET_OF(GrowableObjectArrayLayout, type_arguments_);
}
static intptr_t length_offset() {
- return OFFSET_OF(RawGrowableObjectArray, length_);
+ return OFFSET_OF(GrowableObjectArrayLayout, length_);
}
static intptr_t data_offset() {
- return OFFSET_OF(RawGrowableObjectArray, data_);
+ return OFFSET_OF(GrowableObjectArrayLayout, data_);
}
static intptr_t InstanceSize() {
- return RoundedAllocationSize(sizeof(RawGrowableObjectArray));
+ return RoundedAllocationSize(sizeof(GrowableObjectArrayLayout));
}
- static RawGrowableObjectArray* New(Heap::Space space = Heap::kNew) {
+ static GrowableObjectArrayPtr New(Heap::Space space = Heap::kNew) {
return New(kDefaultInitialCapacity, space);
}
- static RawGrowableObjectArray* New(intptr_t capacity,
- Heap::Space space = Heap::kNew);
- static RawGrowableObjectArray* New(const Array& array,
- Heap::Space space = Heap::kNew);
+ static GrowableObjectArrayPtr New(intptr_t capacity,
+ Heap::Space space = Heap::kNew);
+ static GrowableObjectArrayPtr New(const Array& array,
+ Heap::Space space = Heap::kNew);
- static RawSmi* NoSafepointLength(const RawGrowableObjectArray* array) {
+ static SmiPtr NoSafepointLength(const GrowableObjectArrayPtr array) {
return array->ptr()->length_;
}
- static RawArray* NoSafepointData(const RawGrowableObjectArray* array) {
+ static ArrayPtr NoSafepointData(const GrowableObjectArrayPtr array) {
return array->ptr()->data_;
}
private:
- RawArray* DataArray() const { return data()->ptr(); }
- RawObject** ObjectAddr(intptr_t index) const {
+ ArrayLayout* DataArray() const { return data()->ptr(); }
+ ObjectPtr* ObjectAddr(intptr_t index) const {
ASSERT((index >= 0) && (index < Length()));
return &(DataArray()->data()[index]);
}
@@ -9581,13 +9585,13 @@
class Float32x4 : public Instance {
public:
- static RawFloat32x4* New(float value0,
- float value1,
- float value2,
- float value3,
- Heap::Space space = Heap::kNew);
- static RawFloat32x4* New(simd128_value_t value,
- Heap::Space space = Heap::kNew);
+ static Float32x4Ptr New(float value0,
+ float value1,
+ float value2,
+ float value3,
+ Heap::Space space = Heap::kNew);
+ static Float32x4Ptr New(simd128_value_t value,
+ Heap::Space space = Heap::kNew);
float x() const;
float y() const;
@@ -9603,10 +9607,10 @@
void set_value(simd128_value_t value) const;
static intptr_t InstanceSize() {
- return RoundedAllocationSize(sizeof(RawFloat32x4));
+ return RoundedAllocationSize(sizeof(Float32x4Layout));
}
- static intptr_t value_offset() { return OFFSET_OF(RawFloat32x4, value_); }
+ static intptr_t value_offset() { return OFFSET_OF(Float32x4Layout, value_); }
private:
FINAL_HEAP_OBJECT_IMPLEMENTATION(Float32x4, Instance);
@@ -9615,12 +9619,12 @@
class Int32x4 : public Instance {
public:
- static RawInt32x4* New(int32_t value0,
- int32_t value1,
- int32_t value2,
- int32_t value3,
- Heap::Space space = Heap::kNew);
- static RawInt32x4* New(simd128_value_t value, Heap::Space space = Heap::kNew);
+ static Int32x4Ptr New(int32_t value0,
+ int32_t value1,
+ int32_t value2,
+ int32_t value3,
+ Heap::Space space = Heap::kNew);
+ static Int32x4Ptr New(simd128_value_t value, Heap::Space space = Heap::kNew);
int32_t x() const;
int32_t y() const;
@@ -9636,10 +9640,10 @@
void set_value(simd128_value_t value) const;
static intptr_t InstanceSize() {
- return RoundedAllocationSize(sizeof(RawInt32x4));
+ return RoundedAllocationSize(sizeof(Int32x4Layout));
}
- static intptr_t value_offset() { return OFFSET_OF(RawInt32x4, value_); }
+ static intptr_t value_offset() { return OFFSET_OF(Int32x4Layout, value_); }
private:
FINAL_HEAP_OBJECT_IMPLEMENTATION(Int32x4, Instance);
@@ -9648,11 +9652,11 @@
class Float64x2 : public Instance {
public:
- static RawFloat64x2* New(double value0,
- double value1,
- Heap::Space space = Heap::kNew);
- static RawFloat64x2* New(simd128_value_t value,
- Heap::Space space = Heap::kNew);
+ static Float64x2Ptr New(double value0,
+ double value1,
+ Heap::Space space = Heap::kNew);
+ static Float64x2Ptr New(simd128_value_t value,
+ Heap::Space space = Heap::kNew);
double x() const;
double y() const;
@@ -9664,10 +9668,10 @@
void set_value(simd128_value_t value) const;
static intptr_t InstanceSize() {
- return RoundedAllocationSize(sizeof(RawFloat64x2));
+ return RoundedAllocationSize(sizeof(Float64x2Layout));
}
- static intptr_t value_offset() { return OFFSET_OF(RawFloat64x2, value_); }
+ static intptr_t value_offset() { return OFFSET_OF(Float64x2Layout, value_); }
private:
FINAL_HEAP_OBJECT_IMPLEMENTATION(Float64x2, Instance);
@@ -9677,17 +9681,17 @@
class PointerBase : public Instance {
public:
static intptr_t data_field_offset() {
- return OFFSET_OF(RawPointerBase, data_);
+ return OFFSET_OF(PointerBaseLayout, data_);
}
};
class TypedDataBase : public PointerBase {
public:
static intptr_t length_offset() {
- return OFFSET_OF(RawTypedDataBase, length_);
+ return OFFSET_OF(TypedDataBaseLayout, length_);
}
- RawSmi* length() const { return raw_ptr()->length_; }
+ SmiPtr length() const { return raw_ptr()->length_; }
intptr_t Length() const {
ASSERT(!IsNull());
@@ -9799,17 +9803,17 @@
#undef TYPED_GETTER_SETTER
- static intptr_t data_offset() { return RawTypedData::payload_offset(); }
+ static intptr_t data_offset() { return TypedDataLayout::payload_offset(); }
static intptr_t InstanceSize() {
- ASSERT(sizeof(RawTypedData) ==
- OFFSET_OF_RETURNED_VALUE(RawTypedData, internal_data));
+ ASSERT(sizeof(TypedDataLayout) ==
+ OFFSET_OF_RETURNED_VALUE(TypedDataLayout, internal_data));
return 0;
}
static intptr_t InstanceSize(intptr_t lengthInBytes) {
ASSERT(0 <= lengthInBytes && lengthInBytes <= kSmiMax);
- return RoundedAllocationSize(sizeof(RawTypedData) + lengthInBytes);
+ return RoundedAllocationSize(sizeof(TypedDataLayout) + lengthInBytes);
}
static intptr_t MaxElements(intptr_t class_id) {
@@ -9819,13 +9823,13 @@
static intptr_t MaxNewSpaceElements(intptr_t class_id) {
ASSERT(IsTypedDataClassId(class_id));
- return (Heap::kNewAllocatableSize - sizeof(RawTypedData)) /
+ return (Heap::kNewAllocatableSize - sizeof(TypedDataLayout)) /
ElementSizeInBytes(class_id);
}
- static RawTypedData* New(intptr_t class_id,
- intptr_t len,
- Heap::Space space = Heap::kNew);
+ static TypedDataPtr New(intptr_t class_id,
+ intptr_t len,
+ Heap::Space space = Heap::kNew);
template <typename DstType, typename SrcType>
static void Copy(const DstType& dst,
@@ -9881,7 +9885,7 @@
}
protected:
- void RecomputeDataField() { raw()->RecomputeDataField(); }
+ void RecomputeDataField() { raw()->ptr()->RecomputeDataField(); }
private:
// Provides const access to non-pointer, non-aligned data within the object.
@@ -9938,11 +9942,11 @@
intptr_t external_size) const;
static intptr_t data_offset() {
- return OFFSET_OF(RawExternalTypedData, data_);
+ return OFFSET_OF(ExternalTypedDataLayout, data_);
}
static intptr_t InstanceSize() {
- return RoundedAllocationSize(sizeof(RawExternalTypedData));
+ return RoundedAllocationSize(sizeof(ExternalTypedDataLayout));
}
static intptr_t MaxElements(intptr_t class_id) {
@@ -9950,14 +9954,14 @@
return (kSmiMax / ElementSizeInBytes(class_id));
}
- static RawExternalTypedData* New(
+ static ExternalTypedDataPtr New(
intptr_t class_id,
uint8_t* data,
intptr_t len,
Heap::Space space = Heap::kNew,
bool perform_eager_msan_initialization_check = true);
- static RawExternalTypedData* NewFinalizeWithFree(uint8_t* data, intptr_t len);
+ static ExternalTypedDataPtr NewFinalizeWithFree(uint8_t* data, intptr_t len);
static bool IsExternalTypedData(const Instance& obj) {
ASSERT(!obj.IsNull());
@@ -9986,23 +9990,23 @@
class TypedDataView : public TypedDataBase {
public:
- static RawTypedDataView* New(intptr_t class_id,
- Heap::Space space = Heap::kNew);
- static RawTypedDataView* New(intptr_t class_id,
- const TypedDataBase& typed_data,
- intptr_t offset_in_bytes,
- intptr_t length,
- Heap::Space space = Heap::kNew);
+ static TypedDataViewPtr New(intptr_t class_id,
+ Heap::Space space = Heap::kNew);
+ static TypedDataViewPtr New(intptr_t class_id,
+ const TypedDataBase& typed_data,
+ intptr_t offset_in_bytes,
+ intptr_t length,
+ Heap::Space space = Heap::kNew);
static intptr_t InstanceSize() {
- return RoundedAllocationSize(sizeof(RawTypedDataView));
+ return RoundedAllocationSize(sizeof(TypedDataViewLayout));
}
- static RawInstance* Data(const TypedDataView& view) {
+ static InstancePtr Data(const TypedDataView& view) {
return view.typed_data();
}
- static RawSmi* OffsetInBytes(const TypedDataView& view) {
+ static SmiPtr OffsetInBytes(const TypedDataView& view) {
return view.offset_in_bytes();
}
@@ -10014,14 +10018,14 @@
}
static intptr_t data_offset() {
- return OFFSET_OF(RawTypedDataView, typed_data_);
+ return OFFSET_OF(TypedDataViewLayout, typed_data_);
}
static intptr_t offset_in_bytes_offset() {
- return OFFSET_OF(RawTypedDataView, offset_in_bytes_);
+ return OFFSET_OF(TypedDataViewLayout, offset_in_bytes_);
}
- RawInstance* typed_data() const { return raw_ptr()->typed_data_; }
+ InstancePtr typed_data() const { return raw_ptr()->typed_data_; }
void InitializeWith(const TypedDataBase& typed_data,
intptr_t offset_in_bytes,
@@ -10036,13 +10040,13 @@
RecomputeDataField();
}
- RawSmi* offset_in_bytes() const { return raw_ptr()->offset_in_bytes_; }
+ SmiPtr offset_in_bytes() const { return raw_ptr()->offset_in_bytes_; }
protected:
virtual uint8_t* Validate(uint8_t* data) const { return data; }
private:
- void RecomputeDataField() { raw()->RecomputeDataField(); }
+ void RecomputeDataField() { raw()->ptr()->RecomputeDataField(); }
void Clear() {
StoreSmi(&raw_ptr()->length_, Smi::New(0));
@@ -10060,10 +10064,10 @@
class ByteBuffer : public AllStatic {
public:
- static RawInstance* Data(const Instance& view_obj) {
+ static InstancePtr Data(const Instance& view_obj) {
ASSERT(!view_obj.IsNull());
- return *reinterpret_cast<RawInstance* const*>(view_obj.raw_ptr() +
- kDataOffset);
+ return *reinterpret_cast<InstancePtr const*>(view_obj.raw_ptr() +
+ kDataOffset);
}
static intptr_t NumberOfFields() { return kDataOffset; }
@@ -10078,12 +10082,12 @@
class Pointer : public Instance {
public:
- static RawPointer* New(const AbstractType& type_arg,
- uword native_address,
- Heap::Space space = Heap::kNew);
+ static PointerPtr New(const AbstractType& type_arg,
+ uword native_address,
+ Heap::Space space = Heap::kNew);
static intptr_t InstanceSize() {
- return RoundedAllocationSize(sizeof(RawPointer));
+ return RoundedAllocationSize(sizeof(PointerLayout));
}
static bool IsPointer(const Instance& obj);
@@ -10098,15 +10102,15 @@
}
static intptr_t type_arguments_offset() {
- return OFFSET_OF(RawPointer, type_arguments_);
+ return OFFSET_OF(PointerLayout, type_arguments_);
}
- static intptr_t NextFieldOffset() { return sizeof(RawPointer); }
+ static intptr_t NextFieldOffset() { return sizeof(PointerLayout); }
static const intptr_t kNativeTypeArgPos = 0;
// Fetches the NativeType type argument.
- RawAbstractType* type_argument() const {
+ AbstractTypePtr type_argument() const {
TypeArguments& type_args = TypeArguments::Handle(GetTypeArguments());
return type_args.TypeAtNullSafe(Pointer::kNativeTypeArgPos);
}
@@ -10119,10 +10123,10 @@
class DynamicLibrary : public Instance {
public:
- static RawDynamicLibrary* New(void* handle, Heap::Space space = Heap::kNew);
+ static DynamicLibraryPtr New(void* handle, Heap::Space space = Heap::kNew);
static intptr_t InstanceSize() {
- return RoundedAllocationSize(sizeof(RawDynamicLibrary));
+ return RoundedAllocationSize(sizeof(DynamicLibraryLayout));
}
static bool IsDynamicLibrary(const Instance& obj) {
@@ -10153,19 +10157,19 @@
class LinkedHashMap : public Instance {
public:
static intptr_t InstanceSize() {
- return RoundedAllocationSize(sizeof(RawLinkedHashMap));
+ return RoundedAllocationSize(sizeof(LinkedHashMapLayout));
}
// Allocates a map with some default capacity, just like "new Map()".
- static RawLinkedHashMap* NewDefault(Heap::Space space = Heap::kNew);
- static RawLinkedHashMap* New(const Array& data,
- const TypedData& index,
- intptr_t hash_mask,
- intptr_t used_data,
- intptr_t deleted_keys,
- Heap::Space space = Heap::kNew);
+ static LinkedHashMapPtr NewDefault(Heap::Space space = Heap::kNew);
+ static LinkedHashMapPtr New(const Array& data,
+ const TypedData& index,
+ intptr_t hash_mask,
+ intptr_t used_data,
+ intptr_t deleted_keys,
+ Heap::Space space = Heap::kNew);
- virtual RawTypeArguments* GetTypeArguments() const {
+ virtual TypeArgumentsPtr GetTypeArguments() const {
return raw_ptr()->type_arguments_;
}
virtual void SetTypeArguments(const TypeArguments& value) const {
@@ -10177,44 +10181,48 @@
StorePointer(&raw_ptr()->type_arguments_, value.raw());
}
static intptr_t type_arguments_offset() {
- return OFFSET_OF(RawLinkedHashMap, type_arguments_);
+ return OFFSET_OF(LinkedHashMapLayout, type_arguments_);
}
- RawTypedData* index() const { return raw_ptr()->index_; }
+ TypedDataPtr index() const { return raw_ptr()->index_; }
void SetIndex(const TypedData& value) const {
ASSERT(!value.IsNull());
StorePointer(&raw_ptr()->index_, value.raw());
}
- static intptr_t index_offset() { return OFFSET_OF(RawLinkedHashMap, index_); }
+ static intptr_t index_offset() {
+ return OFFSET_OF(LinkedHashMapLayout, index_);
+ }
- RawArray* data() const { return raw_ptr()->data_; }
+ ArrayPtr data() const { return raw_ptr()->data_; }
void SetData(const Array& value) const {
StorePointer(&raw_ptr()->data_, value.raw());
}
- static intptr_t data_offset() { return OFFSET_OF(RawLinkedHashMap, data_); }
+ static intptr_t data_offset() {
+ return OFFSET_OF(LinkedHashMapLayout, data_);
+ }
- RawSmi* hash_mask() const { return raw_ptr()->hash_mask_; }
+ SmiPtr hash_mask() const { return raw_ptr()->hash_mask_; }
void SetHashMask(intptr_t value) const {
StoreSmi(&raw_ptr()->hash_mask_, Smi::New(value));
}
static intptr_t hash_mask_offset() {
- return OFFSET_OF(RawLinkedHashMap, hash_mask_);
+ return OFFSET_OF(LinkedHashMapLayout, hash_mask_);
}
- RawSmi* used_data() const { return raw_ptr()->used_data_; }
+ SmiPtr used_data() const { return raw_ptr()->used_data_; }
void SetUsedData(intptr_t value) const {
StoreSmi(&raw_ptr()->used_data_, Smi::New(value));
}
static intptr_t used_data_offset() {
- return OFFSET_OF(RawLinkedHashMap, used_data_);
+ return OFFSET_OF(LinkedHashMapLayout, used_data_);
}
- RawSmi* deleted_keys() const { return raw_ptr()->deleted_keys_; }
+ SmiPtr deleted_keys() const { return raw_ptr()->deleted_keys_; }
void SetDeletedKeys(intptr_t value) const {
StoreSmi(&raw_ptr()->deleted_keys_, Smi::New(value));
}
static intptr_t deleted_keys_offset() {
- return OFFSET_OF(RawLinkedHashMap, deleted_keys_);
+ return OFFSET_OF(LinkedHashMapLayout, deleted_keys_);
}
intptr_t Length() const {
@@ -10254,9 +10262,9 @@
}
}
- RawObject* CurrentKey() const { return data_.At(offset_); }
+ ObjectPtr CurrentKey() const { return data_.At(offset_); }
- RawObject* CurrentValue() const { return data_.At(offset_ + 1); }
+ ObjectPtr CurrentValue() const { return data_.At(offset_ + 1); }
private:
const Array& data_;
@@ -10274,7 +10282,7 @@
// Allocate a map, but leave all fields set to null.
// Used during deserialization (since map might contain itself as key/value).
- static RawLinkedHashMap* NewUninitialized(Heap::Space space = Heap::kNew);
+ static LinkedHashMapPtr NewUninitialized(Heap::Space space = Heap::kNew);
friend class Class;
friend class LinkedHashMapDeserializationCluster;
@@ -10282,38 +10290,42 @@
class Closure : public Instance {
public:
- RawTypeArguments* instantiator_type_arguments() const {
+ TypeArgumentsPtr instantiator_type_arguments() const {
return raw_ptr()->instantiator_type_arguments_;
}
static intptr_t instantiator_type_arguments_offset() {
- return OFFSET_OF(RawClosure, instantiator_type_arguments_);
+ return OFFSET_OF(ClosureLayout, instantiator_type_arguments_);
}
- RawTypeArguments* function_type_arguments() const {
+ TypeArgumentsPtr function_type_arguments() const {
return raw_ptr()->function_type_arguments_;
}
static intptr_t function_type_arguments_offset() {
- return OFFSET_OF(RawClosure, function_type_arguments_);
+ return OFFSET_OF(ClosureLayout, function_type_arguments_);
}
- RawTypeArguments* delayed_type_arguments() const {
+ TypeArgumentsPtr delayed_type_arguments() const {
return raw_ptr()->delayed_type_arguments_;
}
static intptr_t delayed_type_arguments_offset() {
- return OFFSET_OF(RawClosure, delayed_type_arguments_);
+ return OFFSET_OF(ClosureLayout, delayed_type_arguments_);
}
- RawFunction* function() const { return raw_ptr()->function_; }
- static intptr_t function_offset() { return OFFSET_OF(RawClosure, function_); }
+ FunctionPtr function() const { return raw_ptr()->function_; }
+ static intptr_t function_offset() {
+ return OFFSET_OF(ClosureLayout, function_);
+ }
- RawContext* context() const { return raw_ptr()->context_; }
- static intptr_t context_offset() { return OFFSET_OF(RawClosure, context_); }
+ ContextPtr context() const { return raw_ptr()->context_; }
+ static intptr_t context_offset() {
+ return OFFSET_OF(ClosureLayout, context_);
+ }
- RawSmi* hash() const { return raw_ptr()->hash_; }
- static intptr_t hash_offset() { return OFFSET_OF(RawClosure, hash_); }
+ SmiPtr hash() const { return raw_ptr()->hash_; }
+ static intptr_t hash_offset() { return OFFSET_OF(ClosureLayout, hash_); }
static intptr_t InstanceSize() {
- return RoundedAllocationSize(sizeof(RawClosure));
+ return RoundedAllocationSize(sizeof(ClosureLayout));
}
// Returns true if all elements are OK for canonicalization.
@@ -10327,23 +10339,23 @@
}
int64_t ComputeHash() const;
- static RawClosure* New(const TypeArguments& instantiator_type_arguments,
- const TypeArguments& function_type_arguments,
- const Function& function,
- const Context& context,
- Heap::Space space = Heap::kNew);
+ static ClosurePtr New(const TypeArguments& instantiator_type_arguments,
+ const TypeArguments& function_type_arguments,
+ const Function& function,
+ const Context& context,
+ Heap::Space space = Heap::kNew);
- static RawClosure* New(const TypeArguments& instantiator_type_arguments,
- const TypeArguments& function_type_arguments,
- const TypeArguments& delayed_type_arguments,
- const Function& function,
- const Context& context,
- Heap::Space space = Heap::kNew);
+ static ClosurePtr New(const TypeArguments& instantiator_type_arguments,
+ const TypeArguments& function_type_arguments,
+ const TypeArguments& delayed_type_arguments,
+ const Function& function,
+ const Context& context,
+ Heap::Space space = Heap::kNew);
- RawFunction* GetInstantiatedSignature(Zone* zone) const;
+ FunctionPtr GetInstantiatedSignature(Zone* zone) const;
private:
- static RawClosure* New();
+ static ClosurePtr New();
FINAL_HEAP_OBJECT_IMPLEMENTATION(Closure, Instance);
friend class Class;
@@ -10354,9 +10366,9 @@
uint64_t Id() const { return raw_ptr()->id_; }
static intptr_t InstanceSize() {
- return RoundedAllocationSize(sizeof(RawCapability));
+ return RoundedAllocationSize(sizeof(CapabilityLayout));
}
- static RawCapability* New(uint64_t id, Heap::Space space = Heap::kNew);
+ static CapabilityPtr New(uint64_t id, Heap::Space space = Heap::kNew);
private:
FINAL_HEAP_OBJECT_IMPLEMENTATION(Capability, Instance);
@@ -10365,18 +10377,18 @@
class ReceivePort : public Instance {
public:
- RawSendPort* send_port() const { return raw_ptr()->send_port_; }
+ SendPortPtr send_port() const { return raw_ptr()->send_port_; }
Dart_Port Id() const { return send_port()->ptr()->id_; }
- RawInstance* handler() const { return raw_ptr()->handler_; }
+ InstancePtr handler() const { return raw_ptr()->handler_; }
void set_handler(const Instance& value) const;
static intptr_t InstanceSize() {
- return RoundedAllocationSize(sizeof(RawReceivePort));
+ return RoundedAllocationSize(sizeof(ReceivePortLayout));
}
- static RawReceivePort* New(Dart_Port id,
- bool is_control_port,
- Heap::Space space = Heap::kNew);
+ static ReceivePortPtr New(Dart_Port id,
+ bool is_control_port,
+ Heap::Space space = Heap::kNew);
private:
FINAL_HEAP_OBJECT_IMPLEMENTATION(ReceivePort, Instance);
@@ -10394,12 +10406,12 @@
}
static intptr_t InstanceSize() {
- return RoundedAllocationSize(sizeof(RawSendPort));
+ return RoundedAllocationSize(sizeof(SendPortLayout));
}
- static RawSendPort* New(Dart_Port id, Heap::Space space = Heap::kNew);
- static RawSendPort* New(Dart_Port id,
- Dart_Port origin_id,
- Heap::Space space = Heap::kNew);
+ static SendPortPtr New(Dart_Port id, Heap::Space space = Heap::kNew);
+ static SendPortPtr New(Dart_Port id,
+ Dart_Port origin_id,
+ Heap::Space space = Heap::kNew);
private:
FINAL_HEAP_OBJECT_IMPLEMENTATION(SendPort, Instance);
@@ -10437,12 +10449,12 @@
class TransferableTypedData : public Instance {
public:
- static RawTransferableTypedData* New(uint8_t* data,
- intptr_t len,
- Heap::Space space = Heap::kNew);
+ static TransferableTypedDataPtr New(uint8_t* data,
+ intptr_t len,
+ Heap::Space space = Heap::kNew);
static intptr_t InstanceSize() {
- return RoundedAllocationSize(sizeof(RawTransferableTypedData));
+ return RoundedAllocationSize(sizeof(TransferableTypedDataLayout));
}
private:
@@ -10457,16 +10469,16 @@
intptr_t Length() const;
- RawStackTrace* async_link() const { return raw_ptr()->async_link_; }
+ StackTracePtr async_link() const { return raw_ptr()->async_link_; }
void set_async_link(const StackTrace& async_link) const;
void set_expand_inlined(bool value) const;
- RawArray* code_array() const { return raw_ptr()->code_array_; }
- RawObject* CodeAtFrame(intptr_t frame_index) const;
+ ArrayPtr code_array() const { return raw_ptr()->code_array_; }
+ ObjectPtr CodeAtFrame(intptr_t frame_index) const;
void SetCodeAtFrame(intptr_t frame_index, const Object& code) const;
- RawArray* pc_offset_array() const { return raw_ptr()->pc_offset_array_; }
- RawSmi* PcOffsetAtFrame(intptr_t frame_index) const;
+ ArrayPtr pc_offset_array() const { return raw_ptr()->pc_offset_array_; }
+ SmiPtr PcOffsetAtFrame(intptr_t frame_index) const;
void SetPcOffsetAtFrame(intptr_t frame_index, const Smi& pc_offset) const;
bool skip_sync_start_in_parent_stack() const;
@@ -10487,22 +10499,19 @@
static constexpr intptr_t kSyncAsyncCroppedFrames = 2;
static intptr_t InstanceSize() {
- return RoundedAllocationSize(sizeof(RawStackTrace));
+ return RoundedAllocationSize(sizeof(StackTraceLayout));
}
- static RawStackTrace* New(const Array& code_array,
- const Array& pc_offset_array,
- Heap::Space space = Heap::kNew);
+ static StackTracePtr New(const Array& code_array,
+ const Array& pc_offset_array,
+ Heap::Space space = Heap::kNew);
- static RawStackTrace* New(const Array& code_array,
- const Array& pc_offset_array,
- const StackTrace& async_link,
- bool skip_sync_start_in_parent_stack,
- Heap::Space space = Heap::kNew);
+ static StackTracePtr New(const Array& code_array,
+ const Array& pc_offset_array,
+ const StackTrace& async_link,
+ bool skip_sync_start_in_parent_stack,
+ Heap::Space space = Heap::kNew);
private:
- static const char* ToDartCString(const StackTrace& stack_trace_in);
- static const char* ToDwarfCString(const StackTrace& stack_trace_in);
-
void set_code_array(const Array& code_array) const;
void set_pc_offset_array(const Array& pc_offset_array) const;
bool expand_inlined() const;
@@ -10593,13 +10602,13 @@
: raw_ptr()->num_two_byte_registers_;
}
- RawString* pattern() const { return raw_ptr()->pattern_; }
- RawSmi* num_bracket_expressions() const {
+ StringPtr pattern() const { return raw_ptr()->pattern_; }
+ SmiPtr num_bracket_expressions() const {
return raw_ptr()->num_bracket_expressions_;
}
- RawArray* capture_name_map() const { return raw_ptr()->capture_name_map_; }
+ ArrayPtr capture_name_map() const { return raw_ptr()->capture_name_map_; }
- RawTypedData* bytecode(bool is_one_byte, bool sticky) const {
+ TypedDataPtr bytecode(bool is_one_byte, bool sticky) const {
if (sticky) {
return is_one_byte ? raw_ptr()->one_byte_sticky_.bytecode_
: raw_ptr()->two_byte_sticky_.bytecode_;
@@ -10613,24 +10622,24 @@
if (sticky) {
switch (cid) {
case kOneByteStringCid:
- return OFFSET_OF(RawRegExp, one_byte_sticky_.function_);
+ return OFFSET_OF(RegExpLayout, one_byte_sticky_.function_);
case kTwoByteStringCid:
- return OFFSET_OF(RawRegExp, two_byte_sticky_.function_);
+ return OFFSET_OF(RegExpLayout, two_byte_sticky_.function_);
case kExternalOneByteStringCid:
- return OFFSET_OF(RawRegExp, external_one_byte_sticky_function_);
+ return OFFSET_OF(RegExpLayout, external_one_byte_sticky_function_);
case kExternalTwoByteStringCid:
- return OFFSET_OF(RawRegExp, external_two_byte_sticky_function_);
+ return OFFSET_OF(RegExpLayout, external_two_byte_sticky_function_);
}
} else {
switch (cid) {
case kOneByteStringCid:
- return OFFSET_OF(RawRegExp, one_byte_.function_);
+ return OFFSET_OF(RegExpLayout, one_byte_.function_);
case kTwoByteStringCid:
- return OFFSET_OF(RawRegExp, two_byte_.function_);
+ return OFFSET_OF(RegExpLayout, two_byte_.function_);
case kExternalOneByteStringCid:
- return OFFSET_OF(RawRegExp, external_one_byte_function_);
+ return OFFSET_OF(RegExpLayout, external_one_byte_function_);
case kExternalTwoByteStringCid:
- return OFFSET_OF(RawRegExp, external_two_byte_function_);
+ return OFFSET_OF(RegExpLayout, external_two_byte_function_);
}
}
@@ -10638,12 +10647,12 @@
return -1;
}
- RawFunction** FunctionAddr(intptr_t cid, bool sticky) const {
- return reinterpret_cast<RawFunction**>(
+ FunctionPtr* FunctionAddr(intptr_t cid, bool sticky) const {
+ return reinterpret_cast<FunctionPtr*>(
FieldAddrAtOffset(function_offset(cid, sticky)));
}
- RawFunction* function(intptr_t cid, bool sticky) const {
+ FunctionPtr function(intptr_t cid, bool sticky) const {
return *FunctionAddr(cid, sticky);
}
@@ -10702,10 +10711,10 @@
virtual bool CanonicalizeEquals(const Instance& other) const;
static intptr_t InstanceSize() {
- return RoundedAllocationSize(sizeof(RawRegExp));
+ return RoundedAllocationSize(sizeof(RegExpLayout));
}
- static RawRegExp* New(Heap::Space space = Heap::kNew);
+ static RegExpPtr New(Heap::Space space = Heap::kNew);
private:
void set_type(RegExType type) const {
@@ -10721,25 +10730,25 @@
class WeakProperty : public Instance {
public:
- RawObject* key() const { return raw_ptr()->key_; }
+ ObjectPtr key() const { return raw_ptr()->key_; }
void set_key(const Object& key) const {
StorePointer(&raw_ptr()->key_, key.raw());
}
- RawObject* value() const { return raw_ptr()->value_; }
+ ObjectPtr value() const { return raw_ptr()->value_; }
void set_value(const Object& value) const {
StorePointer(&raw_ptr()->value_, value.raw());
}
- static RawWeakProperty* New(Heap::Space space = Heap::kNew);
+ static WeakPropertyPtr New(Heap::Space space = Heap::kNew);
static intptr_t InstanceSize() {
- return RoundedAllocationSize(sizeof(RawWeakProperty));
+ return RoundedAllocationSize(sizeof(WeakPropertyLayout));
}
- static void Clear(RawWeakProperty* raw_weak) {
+ static void Clear(WeakPropertyPtr raw_weak) {
ASSERT(raw_weak->ptr()->next_ == 0);
// This action is performed by the GC. No barrier.
raw_weak->ptr()->key_ = Object::null();
@@ -10753,29 +10762,29 @@
class MirrorReference : public Instance {
public:
- RawObject* referent() const { return raw_ptr()->referent_; }
+ ObjectPtr referent() const { return raw_ptr()->referent_; }
void set_referent(const Object& referent) const {
StorePointer(&raw_ptr()->referent_, referent.raw());
}
- RawAbstractType* GetAbstractTypeReferent() const;
+ AbstractTypePtr GetAbstractTypeReferent() const;
- RawClass* GetClassReferent() const;
+ ClassPtr GetClassReferent() const;
- RawField* GetFieldReferent() const;
+ FieldPtr GetFieldReferent() const;
- RawFunction* GetFunctionReferent() const;
+ FunctionPtr GetFunctionReferent() const;
- RawLibrary* GetLibraryReferent() const;
+ LibraryPtr GetLibraryReferent() const;
- RawTypeParameter* GetTypeParameterReferent() const;
+ TypeParameterPtr GetTypeParameterReferent() const;
- static RawMirrorReference* New(const Object& referent,
- Heap::Space space = Heap::kNew);
+ static MirrorReferencePtr New(const Object& referent,
+ Heap::Space space = Heap::kNew);
static intptr_t InstanceSize() {
- return RoundedAllocationSize(sizeof(RawMirrorReference));
+ return RoundedAllocationSize(sizeof(MirrorReferenceLayout));
}
private:
@@ -10791,24 +10800,24 @@
ASSERT(t < UserTags::kUserTagIdOffset + UserTags::kMaxUserTags);
StoreNonPointer(&raw_ptr()->tag_, t);
}
- static intptr_t tag_offset() { return OFFSET_OF(RawUserTag, tag_); }
+ static intptr_t tag_offset() { return OFFSET_OF(UserTagLayout, tag_); }
- RawString* label() const { return raw_ptr()->label_; }
+ StringPtr label() const { return raw_ptr()->label_; }
void MakeActive() const;
static intptr_t InstanceSize() {
- return RoundedAllocationSize(sizeof(RawUserTag));
+ return RoundedAllocationSize(sizeof(UserTagLayout));
}
- static RawUserTag* New(const String& label, Heap::Space space = Heap::kOld);
- static RawUserTag* DefaultTag();
+ static UserTagPtr New(const String& label, Heap::Space space = Heap::kOld);
+ static UserTagPtr DefaultTag();
static bool TagTableIsFull(Thread* thread);
- static RawUserTag* FindTagById(uword tag_id);
+ static UserTagPtr FindTagById(uword tag_id);
private:
- static RawUserTag* FindTagInIsolate(Thread* thread, const String& label);
+ static UserTagPtr FindTagInIsolate(Thread* thread, const String& label);
static void AddTagToIsolate(Thread* thread, const UserTag& tag);
void set_label(const String& tag_label) const {
@@ -10823,14 +10832,14 @@
class FutureOr : public Instance {
public:
static intptr_t InstanceSize() {
- return RoundedAllocationSize(sizeof(RawFutureOr));
+ return RoundedAllocationSize(sizeof(FutureOrLayout));
}
- virtual RawTypeArguments* GetTypeArguments() const {
+ virtual TypeArgumentsPtr GetTypeArguments() const {
return raw_ptr()->type_arguments_;
}
static intptr_t type_arguments_offset() {
- return OFFSET_OF(RawFutureOr, type_arguments_);
+ return OFFSET_OF(FutureOrLayout, type_arguments_);
}
private:
@@ -10840,8 +10849,8 @@
};
// Breaking cycles and loops.
-RawClass* Object::clazz() const {
- uword raw_value = reinterpret_cast<uword>(raw_);
+ClassPtr Object::clazz() const {
+ uword raw_value = static_cast<uword>(raw_);
if ((raw_value & kSmiTagMask) == kSmiTag) {
return Smi::Class();
}
@@ -10850,7 +10859,7 @@
}
DART_FORCE_INLINE
-void Object::SetRaw(RawObject* value) {
+void Object::SetRaw(ObjectPtr value) {
NoSafepointScope no_safepoint_scope;
raw_ = value;
intptr_t cid = value->GetClassIdMayBeSmi();
@@ -10869,10 +10878,10 @@
// to not use handles.
if (!isolate_heap->new_space()->scavenging()) {
Heap* vm_isolate_heap = Dart::vm_isolate()->heap();
- uword addr = RawObject::ToAddr(raw_);
+ uword addr = ObjectLayout::ToAddr(raw_);
if (!isolate_heap->Contains(addr) && !vm_isolate_heap->Contains(addr)) {
ASSERT(FLAG_write_protect_code);
- addr = RawObject::ToAddr(HeapPage::ToWritable(raw_));
+ addr = ObjectLayout::ToAddr(HeapPage::ToWritable(raw_));
ASSERT(isolate_heap->Contains(addr) || vm_isolate_heap->Contains(addr));
}
}
@@ -10885,7 +10894,7 @@
return raw_ptr()->bytecode_ != Bytecode::null();
}
-bool Function::HasBytecode(RawFunction* function) {
+bool Function::HasBytecode(FunctionPtr function) {
return function->ptr()->bytecode_ != Bytecode::null();
}
#endif // !defined(DART_PRECOMPILED_RUNTIME)
@@ -10919,7 +10928,7 @@
#endif // !defined(DART_PRECOMPILED_RUNTIME)
}
-RawInstance* Field::StaticValue() const {
+InstancePtr Field::StaticValue() const {
ASSERT(is_static()); // Valid only for static dart fields.
return Isolate::Current()->field_table()->At(
raw_ptr()->host_offset_or_field_id_);
@@ -10944,8 +10953,7 @@
intptr_t Instance::GetNativeField(int index) const {
ASSERT(IsValidNativeIndex(index));
NoSafepointScope no_safepoint;
- RawTypedData* native_fields =
- reinterpret_cast<RawTypedData*>(*NativeFieldsAddr());
+ TypedDataPtr native_fields = static_cast<TypedDataPtr>(*NativeFieldsAddr());
if (native_fields == TypedData::null()) {
return 0;
}
@@ -10957,8 +10965,7 @@
NoSafepointScope no_safepoint;
ASSERT(num_fields == NumNativeFields());
ASSERT(field_values != NULL);
- RawTypedData* native_fields =
- reinterpret_cast<RawTypedData*>(*NativeFieldsAddr());
+ TypedDataPtr native_fields = static_cast<TypedDataPtr>(*NativeFieldsAddr());
if (native_fields == TypedData::null()) {
for (intptr_t i = 0; i < num_fields; i++) {
field_values[i] = 0;
@@ -11012,12 +11019,12 @@
array.SetAt((index * kEntryLength) + kTargetFunctionIndex, target);
}
-RawObject* MegamorphicCache::GetClassId(const Array& array, intptr_t index) {
+ObjectPtr MegamorphicCache::GetClassId(const Array& array, intptr_t index) {
return array.At((index * kEntryLength) + kClassIdIndex);
}
-RawObject* MegamorphicCache::GetTargetFunction(const Array& array,
- intptr_t index) {
+ObjectPtr MegamorphicCache::GetTargetFunction(const Array& array,
+ intptr_t index) {
return array.At((index * kEntryLength) + kTargetFunctionIndex);
}
@@ -11117,7 +11124,7 @@
: array_(array), index_(index) {}
template <EnumType kElement>
- typename std::tuple_element<kElement, TupleT>::type::RawObjectType* Get()
+ typename std::tuple_element<kElement, TupleT>::type::ObjectPtrType Get()
const {
using object_type = typename std::tuple_element<kElement, TupleT>::type;
return object_type::RawCast(array_.At(index_ + kElement));
@@ -11217,7 +11224,7 @@
Object* reusable_object_handle);
DART_WARN_UNUSED_RESULT
-RawError* EntryPointFieldInvocationError(const String& getter_name);
+ErrorPtr EntryPointFieldInvocationError(const String& getter_name);
} // namespace dart
diff --git a/runtime/vm/object_arm64_test.cc b/runtime/vm/object_arm64_test.cc
index c71002b..640c91b 100644
--- a/runtime/vm/object_arm64_test.cc
+++ b/runtime/vm/object_arm64_test.cc
@@ -46,7 +46,7 @@
// This is used to test Embedded Smi objects in the instructions.
void GenerateEmbedSmiInCode(compiler::Assembler* assembler, intptr_t value) {
const Smi& smi_object = Smi::ZoneHandle(Smi::New(value));
- const int64_t val = reinterpret_cast<int64_t>(smi_object.raw());
+ const int64_t val = static_cast<int64_t>(smi_object.raw());
__ LoadImmediate(R0, val);
__ ret();
}
diff --git a/runtime/vm/object_graph.cc b/runtime/vm/object_graph.cc
index ff147cb..6f028d9 100644
--- a/runtime/vm/object_graph.cc
+++ b/runtime/vm/object_graph.cc
@@ -51,9 +51,9 @@
// Marks and pushes. Used to initialize this stack with roots.
// We can use ObjectIdTable normally used by serializers because it
// won't be in use while handling a service request (ObjectGraph's only use).
- virtual void VisitPointers(RawObject** first, RawObject** last) {
- for (RawObject** current = first; current <= last; ++current) {
- if ((*current)->IsHeapObject() && !(*current)->InVMIsolateHeap() &&
+ virtual void VisitPointers(ObjectPtr* first, ObjectPtr* last) {
+ for (ObjectPtr* current = first; current <= last; ++current) {
+ if ((*current)->IsHeapObject() && !(*current)->ptr()->InVMIsolateHeap() &&
object_ids_->GetValueExclusive(*current) == 0) { // not visited yet
if (!include_vm_objects_ && !IsUserClass((*current)->GetClassId())) {
continue;
@@ -78,7 +78,7 @@
data_.RemoveLast();
continue;
}
- RawObject* obj = node.obj;
+ ObjectPtr obj = node.obj;
ASSERT(obj->IsHeapObject());
Node sentinel;
sentinel.ptr = kSentinel;
@@ -91,7 +91,7 @@
}
if (direction == ObjectGraph::Visitor::kProceed) {
set_gc_root_type(node.gc_root_type);
- obj->VisitPointers(this);
+ obj->ptr()->VisitPointers(this);
clear_gc_root_type();
}
}
@@ -109,13 +109,13 @@
private:
struct Node {
- RawObject** ptr; // kSentinel for the sentinel node.
- RawObject* obj;
+ ObjectPtr* ptr; // kSentinel for the sentinel node.
+ ObjectPtr obj;
const char* gc_root_type;
};
bool visit_weak_persistent_handles_ = false;
- static RawObject** const kSentinel;
+ static ObjectPtr* const kSentinel;
static const intptr_t kInitialCapacity = 1024;
static const intptr_t kNoParent = -1;
@@ -138,9 +138,9 @@
DISALLOW_COPY_AND_ASSIGN(Stack);
};
-RawObject** const ObjectGraph::Stack::kSentinel = NULL;
+ObjectPtr* const ObjectGraph::Stack::kSentinel = NULL;
-RawObject* ObjectGraph::StackIterator::Get() const {
+ObjectPtr ObjectGraph::StackIterator::Get() const {
return stack_->data_[index_].obj;
}
@@ -160,17 +160,18 @@
return -1;
}
Stack::Node parent = stack_->data_[parent_index];
- uword parent_start = RawObject::ToAddr(parent.obj);
+ uword parent_start = ObjectLayout::ToAddr(parent.obj);
Stack::Node child = stack_->data_[index_];
ASSERT(child.obj == *child.ptr);
uword child_ptr_addr = reinterpret_cast<uword>(child.ptr);
intptr_t offset = child_ptr_addr - parent_start;
- if (offset > 0 && offset < parent.obj->HeapSize()) {
+ if (offset > 0 && offset < parent.obj->ptr()->HeapSize()) {
ASSERT(Utils::IsAligned(offset, kWordSize));
return offset >> kWordSizeLog2;
} else {
// Some internal VM objects visit pointers not contained within the parent.
- // For instance, RawCode::VisitCodePointers visits pointers in instructions.
+ // For instance, CodeLayout::VisitCodePointers visits pointers in
+ // instructions.
ASSERT(!parent.obj->IsDartInstance());
return -1;
}
@@ -199,12 +200,12 @@
fields = cls.fields();
for (intptr_t j = 0; j < fields.Length(); j++) {
field ^= fields.At(j);
- RawObject* ptr = field.raw();
+ ObjectPtr ptr = field.raw();
visitor->VisitPointer(&ptr);
}
} else if (entry.IsField()) {
field ^= entry.raw();
- RawObject* ptr = field.raw();
+ ObjectPtr ptr = field.raw();
visitor->VisitPointer(&ptr);
}
}
@@ -243,7 +244,7 @@
Stack stack(isolate_group());
stack.set_visit_weak_persistent_handles(
visitor->visit_weak_persistent_handles());
- RawObject* root_raw = root.raw();
+ ObjectPtr root_raw = root.raw();
stack.VisitPointer(&root_raw);
stack.TraverseGraph(visitor);
}
@@ -253,9 +254,9 @@
InstanceAccumulator(ObjectGraph::Stack* stack, intptr_t class_id)
: stack_(stack), class_id_(class_id) {}
- void VisitObject(RawObject* obj) {
+ void VisitObject(ObjectPtr obj) {
if (obj->GetClassId() == class_id_) {
- RawObject* rawobj = obj;
+ ObjectPtr rawobj = obj;
stack_->VisitPointer(&rawobj);
}
}
@@ -282,13 +283,13 @@
public:
SizeVisitor() : size_(0) {}
intptr_t size() const { return size_; }
- virtual bool ShouldSkip(RawObject* obj) const { return false; }
+ virtual bool ShouldSkip(ObjectPtr obj) const { return false; }
virtual Direction VisitObject(ObjectGraph::StackIterator* it) {
- RawObject* obj = it->Get();
+ ObjectPtr obj = it->Get();
if (ShouldSkip(obj)) {
return kBacktrack;
}
- size_ += obj->HeapSize();
+ size_ += obj->ptr()->HeapSize();
return kProceed;
}
@@ -299,7 +300,7 @@
class SizeExcludingObjectVisitor : public SizeVisitor {
public:
explicit SizeExcludingObjectVisitor(const Object& skip) : skip_(skip) {}
- virtual bool ShouldSkip(RawObject* obj) const { return obj == skip_.raw(); }
+ virtual bool ShouldSkip(ObjectPtr obj) const { return obj == skip_.raw(); }
private:
const Object& skip_;
@@ -308,7 +309,7 @@
class SizeExcludingClassVisitor : public SizeVisitor {
public:
explicit SizeExcludingClassVisitor(intptr_t skip) : skip_(skip) {}
- virtual bool ShouldSkip(RawObject* obj) const {
+ virtual bool ShouldSkip(ObjectPtr obj) const {
return obj->GetClassId() == skip_;
}
@@ -355,14 +356,13 @@
class RetainingPathVisitor : public ObjectGraph::Visitor {
public:
// We cannot use a GrowableObjectArray, since we must not trigger GC.
- RetainingPathVisitor(RawObject* obj, const Array& path)
- : thread_(Thread::Current()), obj_(obj), path_(path), length_(0) {
- }
+ RetainingPathVisitor(ObjectPtr obj, const Array& path)
+ : thread_(Thread::Current()), obj_(obj), path_(path), length_(0) {}
intptr_t length() const { return length_; }
virtual bool visit_weak_persistent_handles() const { return true; }
- bool ShouldSkip(RawObject* obj) {
+ bool ShouldSkip(ObjectPtr obj) {
// A retaining path through ICData is never the only retaining path,
// and it is less informative than its alternatives.
intptr_t cid = obj->GetClassId();
@@ -374,10 +374,10 @@
}
}
- bool ShouldStop(RawObject* obj) {
+ bool ShouldStop(ObjectPtr obj) {
// A static field is considered a root from a language point of view.
if (obj->IsField()) {
- const Field& field = Field::Handle(static_cast<RawField*>(obj));
+ const Field& field = Field::Handle(static_cast<FieldPtr>(obj));
return field.is_static();
}
return false;
@@ -385,7 +385,7 @@
void StartList() { was_last_array_ = false; }
- intptr_t HideNDescendant(RawObject* obj) {
+ intptr_t HideNDescendant(ObjectPtr obj) {
// A GrowableObjectArray overwrites its internal storage.
// Keeping both of them in the list is redundant.
if (was_last_array_ && obj->IsGrowableObjectArray()) {
@@ -433,7 +433,7 @@
private:
Thread* thread_;
- RawObject* obj_;
+ ObjectPtr obj_;
const Array& path_;
intptr_t length_;
bool was_last_array_;
@@ -444,7 +444,7 @@
HeapIterationScope iteration_scope(Thread::Current(), true);
// To break the trivial path, the handle 'obj' is temporarily cleared during
// the search, but restored before returning.
- RawObject* raw = obj->raw();
+ ObjectPtr raw = obj->raw();
*obj = Object::null();
RetainingPathVisitor visitor(raw, path);
IterateUserObjects(&visitor);
@@ -460,11 +460,11 @@
public:
// We cannot use a GrowableObjectArray, since we must not trigger GC.
InboundReferencesVisitor(Isolate* isolate,
- RawObject* target,
+ ObjectPtr target,
const Array& references,
Object* scratch)
: ObjectPointerVisitor(isolate->group()),
- source_(NULL),
+ source_(nullptr),
target_(target),
references_(references),
scratch_(scratch),
@@ -474,14 +474,14 @@
intptr_t length() const { return length_; }
- virtual void VisitObject(RawObject* raw_obj) {
+ virtual void VisitObject(ObjectPtr raw_obj) {
source_ = raw_obj;
- raw_obj->VisitPointers(this);
+ raw_obj->ptr()->VisitPointers(this);
}
- virtual void VisitPointers(RawObject** first, RawObject** last) {
- for (RawObject** current_ptr = first; current_ptr <= last; current_ptr++) {
- RawObject* current_obj = *current_ptr;
+ virtual void VisitPointers(ObjectPtr* first, ObjectPtr* last) {
+ for (ObjectPtr* current_ptr = first; current_ptr <= last; current_ptr++) {
+ ObjectPtr current_obj = *current_ptr;
if (current_obj == target_) {
intptr_t obj_index = length_ * 2;
intptr_t offset_index = obj_index + 1;
@@ -490,16 +490,16 @@
references_.SetAt(obj_index, *scratch_);
*scratch_ = Smi::New(0);
- uword source_start = RawObject::ToAddr(source_);
+ uword source_start = ObjectLayout::ToAddr(source_);
uword current_ptr_addr = reinterpret_cast<uword>(current_ptr);
intptr_t offset = current_ptr_addr - source_start;
- if (offset > 0 && offset < source_->HeapSize()) {
+ if (offset > 0 && offset < source_->ptr()->HeapSize()) {
ASSERT(Utils::IsAligned(offset, kWordSize));
*scratch_ = Smi::New(offset >> kWordSizeLog2);
} else {
// Some internal VM objects visit pointers not contained within the
- // parent. For instance, RawCode::VisitCodePointers visits pointers
- // in instructions.
+ // parent. For instance, CodeLayout::VisitCodePointers visits
+ // pointers in instructions.
ASSERT(!source_->IsDartInstance());
*scratch_ = Smi::New(-1);
}
@@ -511,8 +511,8 @@
}
private:
- RawObject* source_;
- RawObject* target_;
+ ObjectPtr source_;
+ ObjectPtr target_;
const Array& references_;
Object* scratch_;
intptr_t length_;
@@ -686,8 +686,8 @@
}
}
-bool HeapSnapshotWriter::OnImagePage(RawObject* obj) const {
- const uword addr = RawObject::ToAddr(obj);
+bool HeapSnapshotWriter::OnImagePage(ObjectPtr obj) const {
+ const uword addr = ObjectLayout::ToAddr(obj);
for (intptr_t i = 0; i < kMaxImagePages; i++) {
if ((addr - image_page_ranges_[i].base) < image_page_ranges_[i].size) {
return true;
@@ -696,7 +696,7 @@
return false;
}
-CountingPage* HeapSnapshotWriter::FindCountingPage(RawObject* obj) const {
+CountingPage* HeapSnapshotWriter::FindCountingPage(ObjectPtr obj) const {
if (obj->IsOldObject() && !OnImagePage(obj)) {
// On a regular or large page.
HeapPage* page = HeapPage::Of(obj);
@@ -707,20 +707,20 @@
return nullptr;
}
-void HeapSnapshotWriter::AssignObjectId(RawObject* obj) {
+void HeapSnapshotWriter::AssignObjectId(ObjectPtr obj) {
ASSERT(obj->IsHeapObject());
CountingPage* counting_page = FindCountingPage(obj);
if (counting_page != nullptr) {
// Likely: object on an ordinary page.
- counting_page->Record(RawObject::ToAddr(obj), ++object_count_);
+ counting_page->Record(ObjectLayout::ToAddr(obj), ++object_count_);
} else {
// Unlikely: new space object, or object on a large or image page.
thread()->heap()->SetObjectId(obj, ++object_count_);
}
}
-intptr_t HeapSnapshotWriter::GetObjectId(RawObject* obj) const {
+intptr_t HeapSnapshotWriter::GetObjectId(ObjectPtr obj) const {
if (!obj->IsHeapObject()) {
return 0;
}
@@ -734,7 +734,7 @@
intptr_t id;
if (counting_page != nullptr) {
// Likely: object on an ordinary page.
- id = counting_page->Lookup(RawObject::ToAddr(obj));
+ id = counting_page->Lookup(ObjectLayout::ToAddr(obj));
} else {
// Unlikely: new space object, or object on a large or image page.
id = thread()->heap()->GetObjectId(obj);
@@ -765,14 +765,14 @@
HandleVisitor(Thread::Current()),
writer_(writer) {}
- void VisitObject(RawObject* obj) {
+ void VisitObject(ObjectPtr obj) {
if (obj->IsPseudoObject()) return;
writer_->AssignObjectId(obj);
- obj->VisitPointers(this);
+ obj->ptr()->VisitPointers(this);
}
- void VisitPointers(RawObject** from, RawObject** to) {
+ void VisitPointers(ObjectPtr* from, ObjectPtr* to) {
intptr_t count = to - from + 1;
ASSERT(count >= 0);
writer_->CountReferences(count);
@@ -819,30 +819,30 @@
isolate_(thread()->isolate()),
writer_(writer) {}
- void VisitObject(RawObject* obj) {
+ void VisitObject(ObjectPtr obj) {
if (obj->IsPseudoObject()) return;
intptr_t cid = obj->GetClassId();
writer_->WriteUnsigned(cid);
- writer_->WriteUnsigned(discount_sizes_ ? 0 : obj->HeapSize());
+ writer_->WriteUnsigned(discount_sizes_ ? 0 : obj->ptr()->HeapSize());
if (cid == kNullCid) {
writer_->WriteUnsigned(kNullData);
} else if (cid == kBoolCid) {
writer_->WriteUnsigned(kBoolData);
writer_->WriteUnsigned(
- static_cast<uintptr_t>(static_cast<RawBool*>(obj)->ptr()->value_));
+ static_cast<uintptr_t>(static_cast<BoolPtr>(obj)->ptr()->value_));
} else if (cid == kSmiCid) {
UNREACHABLE();
} else if (cid == kMintCid) {
writer_->WriteUnsigned(kIntData);
- writer_->WriteSigned(static_cast<RawMint*>(obj)->ptr()->value_);
+ writer_->WriteSigned(static_cast<MintPtr>(obj)->ptr()->value_);
} else if (cid == kDoubleCid) {
writer_->WriteUnsigned(kDoubleData);
- writer_->WriteBytes(&(static_cast<RawDouble*>(obj)->ptr()->value_),
+ writer_->WriteBytes(&(static_cast<DoublePtr>(obj)->ptr()->value_),
sizeof(double));
} else if (cid == kOneByteStringCid) {
- RawOneByteString* str = static_cast<RawOneByteString*>(obj);
+ OneByteStringPtr str = static_cast<OneByteStringPtr>(obj);
intptr_t len = Smi::Value(str->ptr()->length_);
intptr_t trunc_len = Utils::Minimum(len, kMaxStringElements);
writer_->WriteUnsigned(kLatin1Data);
@@ -850,8 +850,7 @@
writer_->WriteUnsigned(trunc_len);
writer_->WriteBytes(&str->ptr()->data()[0], trunc_len);
} else if (cid == kExternalOneByteStringCid) {
- RawExternalOneByteString* str =
- static_cast<RawExternalOneByteString*>(obj);
+ ExternalOneByteStringPtr str = static_cast<ExternalOneByteStringPtr>(obj);
intptr_t len = Smi::Value(str->ptr()->length_);
intptr_t trunc_len = Utils::Minimum(len, kMaxStringElements);
writer_->WriteUnsigned(kLatin1Data);
@@ -859,7 +858,7 @@
writer_->WriteUnsigned(trunc_len);
writer_->WriteBytes(&str->ptr()->external_data_[0], trunc_len);
} else if (cid == kTwoByteStringCid) {
- RawTwoByteString* str = static_cast<RawTwoByteString*>(obj);
+ TwoByteStringPtr str = static_cast<TwoByteStringPtr>(obj);
intptr_t len = Smi::Value(str->ptr()->length_);
intptr_t trunc_len = Utils::Minimum(len, kMaxStringElements);
writer_->WriteUnsigned(kUTF16Data);
@@ -867,8 +866,7 @@
writer_->WriteUnsigned(trunc_len);
writer_->WriteBytes(&str->ptr()->data()[0], trunc_len * 2);
} else if (cid == kExternalTwoByteStringCid) {
- RawExternalTwoByteString* str =
- static_cast<RawExternalTwoByteString*>(obj);
+ ExternalTwoByteStringPtr str = static_cast<ExternalTwoByteStringPtr>(obj);
intptr_t len = Smi::Value(str->ptr()->length_);
intptr_t trunc_len = Utils::Minimum(len, kMaxStringElements);
writer_->WriteUnsigned(kUTF16Data);
@@ -878,63 +876,63 @@
} else if (cid == kArrayCid || cid == kImmutableArrayCid) {
writer_->WriteUnsigned(kLengthData);
writer_->WriteUnsigned(
- Smi::Value(static_cast<RawArray*>(obj)->ptr()->length_));
+ Smi::Value(static_cast<ArrayPtr>(obj)->ptr()->length_));
} else if (cid == kGrowableObjectArrayCid) {
writer_->WriteUnsigned(kLengthData);
- writer_->WriteUnsigned(Smi::Value(
- static_cast<RawGrowableObjectArray*>(obj)->ptr()->length_));
+ writer_->WriteUnsigned(
+ Smi::Value(static_cast<GrowableObjectArrayPtr>(obj)->ptr()->length_));
} else if (cid == kLinkedHashMapCid) {
writer_->WriteUnsigned(kLengthData);
writer_->WriteUnsigned(
- Smi::Value(static_cast<RawLinkedHashMap*>(obj)->ptr()->used_data_));
+ Smi::Value(static_cast<LinkedHashMapPtr>(obj)->ptr()->used_data_));
} else if (cid == kObjectPoolCid) {
writer_->WriteUnsigned(kLengthData);
- writer_->WriteUnsigned(static_cast<RawObjectPool*>(obj)->ptr()->length_);
+ writer_->WriteUnsigned(static_cast<ObjectPoolPtr>(obj)->ptr()->length_);
} else if (IsTypedDataClassId(cid)) {
writer_->WriteUnsigned(kLengthData);
writer_->WriteUnsigned(
- Smi::Value(static_cast<RawTypedData*>(obj)->ptr()->length_));
+ Smi::Value(static_cast<TypedDataPtr>(obj)->ptr()->length_));
} else if (IsExternalTypedDataClassId(cid)) {
writer_->WriteUnsigned(kLengthData);
writer_->WriteUnsigned(
- Smi::Value(static_cast<RawExternalTypedData*>(obj)->ptr()->length_));
+ Smi::Value(static_cast<ExternalTypedDataPtr>(obj)->ptr()->length_));
} else if (cid == kFunctionCid) {
writer_->WriteUnsigned(kNameData);
- ScrubAndWriteUtf8(static_cast<RawFunction*>(obj)->ptr()->name_);
+ ScrubAndWriteUtf8(static_cast<FunctionPtr>(obj)->ptr()->name_);
} else if (cid == kCodeCid) {
- RawObject* owner = static_cast<RawCode*>(obj)->ptr()->owner_;
+ ObjectPtr owner = static_cast<CodePtr>(obj)->ptr()->owner_;
if (owner->IsFunction()) {
writer_->WriteUnsigned(kNameData);
- ScrubAndWriteUtf8(static_cast<RawFunction*>(owner)->ptr()->name_);
+ ScrubAndWriteUtf8(static_cast<FunctionPtr>(owner)->ptr()->name_);
} else if (owner->IsClass()) {
writer_->WriteUnsigned(kNameData);
- ScrubAndWriteUtf8(static_cast<RawClass*>(owner)->ptr()->name_);
+ ScrubAndWriteUtf8(static_cast<ClassPtr>(owner)->ptr()->name_);
} else {
writer_->WriteUnsigned(kNoData);
}
} else if (cid == kFieldCid) {
writer_->WriteUnsigned(kNameData);
- ScrubAndWriteUtf8(static_cast<RawField*>(obj)->ptr()->name_);
+ ScrubAndWriteUtf8(static_cast<FieldPtr>(obj)->ptr()->name_);
} else if (cid == kClassCid) {
writer_->WriteUnsigned(kNameData);
- ScrubAndWriteUtf8(static_cast<RawClass*>(obj)->ptr()->name_);
+ ScrubAndWriteUtf8(static_cast<ClassPtr>(obj)->ptr()->name_);
} else if (cid == kLibraryCid) {
writer_->WriteUnsigned(kNameData);
- ScrubAndWriteUtf8(static_cast<RawLibrary*>(obj)->ptr()->url_);
+ ScrubAndWriteUtf8(static_cast<LibraryPtr>(obj)->ptr()->url_);
} else if (cid == kScriptCid) {
writer_->WriteUnsigned(kNameData);
- ScrubAndWriteUtf8(static_cast<RawScript*>(obj)->ptr()->url_);
+ ScrubAndWriteUtf8(static_cast<ScriptPtr>(obj)->ptr()->url_);
} else {
writer_->WriteUnsigned(kNoData);
}
DoCount();
- obj->VisitPointersPrecise(isolate_, this);
+ obj->ptr()->VisitPointersPrecise(isolate_, this);
DoWrite();
- obj->VisitPointersPrecise(isolate_, this);
+ obj->ptr()->VisitPointersPrecise(isolate_, this);
}
- void ScrubAndWriteUtf8(RawString* str) {
+ void ScrubAndWriteUtf8(StringPtr str) {
if (str == String::null()) {
writer_->WriteUtf8("null");
} else {
@@ -958,10 +956,10 @@
writer_->WriteUnsigned(counted_);
}
- void VisitPointers(RawObject** from, RawObject** to) {
+ void VisitPointers(ObjectPtr* from, ObjectPtr* to) {
if (writing_) {
- for (RawObject** ptr = from; ptr <= to; ptr++) {
- RawObject* target = *ptr;
+ for (ObjectPtr* ptr = from; ptr <= to; ptr++) {
+ ObjectPtr target = *ptr;
written_++;
total_++;
writer_->WriteUnsigned(writer_->GetObjectId(target));
@@ -1223,9 +1221,9 @@
memset(old_external_size_.get(), 0, class_count * sizeof(intptr_t));
}
-void CountObjectsVisitor::VisitObject(RawObject* obj) {
+void CountObjectsVisitor::VisitObject(ObjectPtr obj) {
intptr_t cid = obj->GetClassId();
- intptr_t size = obj->HeapSize();
+ intptr_t size = obj->ptr()->HeapSize();
if (obj->IsNewObject()) {
new_count_[cid] += 1;
new_size_[cid] += size;
@@ -1238,7 +1236,7 @@
void CountObjectsVisitor::VisitHandle(uword addr) {
FinalizablePersistentHandle* handle =
reinterpret_cast<FinalizablePersistentHandle*>(addr);
- RawObject* obj = handle->raw();
+ ObjectPtr obj = handle->raw();
if (!obj->IsHeapObject()) {
return;
}
diff --git a/runtime/vm/object_graph.h b/runtime/vm/object_graph.h
index f05af3d..9ce858e 100644
--- a/runtime/vm/object_graph.h
+++ b/runtime/vm/object_graph.h
@@ -15,7 +15,6 @@
class Array;
class Object;
-class RawObject;
class CountingPage;
#if !defined(PRODUCT)
@@ -32,7 +31,7 @@
class StackIterator {
public:
// The object this iterator currently points to.
- RawObject* Get() const;
+ ObjectPtr Get() const;
// Returns false if there is no parent.
bool MoveToParent();
// Offset into parent for the pointer to current object. -1 if no parent.
@@ -177,8 +176,8 @@
WriteBytes(value, len);
}
- void AssignObjectId(RawObject* obj);
- intptr_t GetObjectId(RawObject* obj) const;
+ void AssignObjectId(ObjectPtr obj);
+ intptr_t GetObjectId(ObjectPtr obj) const;
void ClearObjectIds();
void CountReferences(intptr_t count);
void CountExternalProperty();
@@ -190,8 +189,8 @@
static const intptr_t kPreferredChunkSize = MB;
void SetupCountingPages();
- bool OnImagePage(RawObject* obj) const;
- CountingPage* FindCountingPage(RawObject* obj) const;
+ bool OnImagePage(ObjectPtr obj) const;
+ CountingPage* FindCountingPage(ObjectPtr obj) const;
void EnsureAvailable(intptr_t needed);
void Flush(bool last = false);
@@ -222,7 +221,7 @@
CountObjectsVisitor(Thread* thread, intptr_t class_count);
~CountObjectsVisitor() {}
- void VisitObject(RawObject* obj);
+ void VisitObject(ObjectPtr obj);
void VisitHandle(uword addr);
std::unique_ptr<intptr_t[]> new_count_;
diff --git a/runtime/vm/object_graph_test.cc b/runtime/vm/object_graph_test.cc
index b371eb6..a072650 100644
--- a/runtime/vm/object_graph_test.cc
+++ b/runtime/vm/object_graph_test.cc
@@ -14,18 +14,18 @@
public:
// Records the number of objects and total size visited, excluding 'skip'
// and any objects only reachable through 'skip'.
- CounterVisitor(RawObject* skip, RawObject* expected_parent)
+ CounterVisitor(ObjectPtr skip, ObjectPtr expected_parent)
: count_(0), size_(0), skip_(skip), expected_parent_(expected_parent) {}
virtual Direction VisitObject(ObjectGraph::StackIterator* it) {
- RawObject* obj = it->Get();
+ ObjectPtr obj = it->Get();
if (obj == skip_) {
EXPECT(it->MoveToParent());
EXPECT_EQ(expected_parent_, it->Get());
return kBacktrack;
}
++count_;
- size_ += obj->HeapSize();
+ size_ += obj->ptr()->HeapSize();
return kProceed;
}
@@ -35,8 +35,8 @@
private:
int count_;
intptr_t size_;
- RawObject* skip_;
- RawObject* expected_parent_;
+ ObjectPtr skip_;
+ ObjectPtr expected_parent_;
};
ISOLATE_UNIT_TEST_CASE(ObjectGraph) {
@@ -54,14 +54,14 @@
b.SetAt(0, c);
b.SetAt(1, d);
a.SetAt(11, d);
- intptr_t a_size = a.raw()->HeapSize();
- intptr_t b_size = b.raw()->HeapSize();
- intptr_t c_size = c.raw()->HeapSize();
- intptr_t d_size = d.raw()->HeapSize();
+ intptr_t a_size = a.raw()->ptr()->HeapSize();
+ intptr_t b_size = b.raw()->ptr()->HeapSize();
+ intptr_t c_size = c.raw()->ptr()->HeapSize();
+ intptr_t d_size = d.raw()->ptr()->HeapSize();
{
// No more allocation; raw pointers ahead.
SafepointOperationScope safepoint(thread);
- RawObject* b_raw = b.raw();
+ ObjectPtr b_raw = b.raw();
// Clear handles to cut unintended retained paths.
b = Array::null();
c = Array::null();
diff --git a/runtime/vm/object_id_ring.cc b/runtime/vm/object_id_ring.cc
index 2652db3..1de2e54 100644
--- a/runtime/vm/object_id_ring.cc
+++ b/runtime/vm/object_id_ring.cc
@@ -18,7 +18,7 @@
table_ = NULL;
}
-int32_t ObjectIdRing::GetIdForObject(RawObject* object, IdPolicy policy) {
+int32_t ObjectIdRing::GetIdForObject(ObjectPtr object, IdPolicy policy) {
// We do not allow inserting null because null is how we detect as entry was
// reclaimed by the GC.
ASSERT(object != Object::null());
@@ -34,7 +34,7 @@
return AllocateNewId(object);
}
-int32_t ObjectIdRing::FindExistingIdForObject(RawObject* raw_obj) {
+int32_t ObjectIdRing::FindExistingIdForObject(ObjectPtr raw_obj) {
for (int32_t i = 0; i < capacity_; i++) {
if (table_[i] == raw_obj) {
return IdOfIndex(i);
@@ -43,7 +43,7 @@
return kInvalidId;
}
-RawObject* ObjectIdRing::GetObjectForId(int32_t id, LookupResult* kind) {
+ObjectPtr ObjectIdRing::GetObjectForId(int32_t id, LookupResult* kind) {
int32_t index = IndexOfId(id);
if (index == kInvalidId) {
*kind = kExpired;
@@ -101,7 +101,7 @@
if (table_ != NULL) {
free(table_);
}
- table_ = reinterpret_cast<RawObject**>(calloc(capacity_, kWordSize));
+ table_ = reinterpret_cast<ObjectPtr*>(calloc(capacity_, kWordSize));
for (int32_t i = 0; i < capacity_; i++) {
table_[i] = Object::null();
}
@@ -120,7 +120,7 @@
return r;
}
-int32_t ObjectIdRing::AllocateNewId(RawObject* raw_obj) {
+int32_t ObjectIdRing::AllocateNewId(ObjectPtr raw_obj) {
ASSERT(raw_obj->IsHeapObject());
int32_t id = NextSerial();
ASSERT(id != kInvalidId);
diff --git a/runtime/vm/object_id_ring.h b/runtime/vm/object_id_ring.h
index 2fe8090..63fe1a7 100644
--- a/runtime/vm/object_id_ring.h
+++ b/runtime/vm/object_id_ring.h
@@ -6,11 +6,11 @@
#define RUNTIME_VM_OBJECT_ID_RING_H_
#include "platform/globals.h"
+#include "vm/tagged_pointer.h"
namespace dart {
// Forward declarations.
-class RawObject;
class ObjectPointerVisitor;
class JSONStream;
@@ -44,10 +44,10 @@
// Adds the argument to the ring and returns its id. Note we do not allow
// adding Object::null().
- int32_t GetIdForObject(RawObject* raw_obj, IdPolicy policy = kAllocateId);
+ int32_t GetIdForObject(ObjectPtr raw_obj, IdPolicy policy = kAllocateId);
// Returns Object::null() when the result is not kValid.
- RawObject* GetObjectForId(int32_t id, LookupResult* kind);
+ ObjectPtr GetObjectForId(int32_t id, LookupResult* kind);
void VisitPointers(ObjectPointerVisitor* visitor);
@@ -57,19 +57,19 @@
friend class ObjectIdRingTestHelper;
void SetCapacityAndMaxSerial(int32_t capacity, int32_t max_serial);
- int32_t FindExistingIdForObject(RawObject* raw_obj);
+ int32_t FindExistingIdForObject(ObjectPtr raw_obj);
- RawObject** table_;
+ ObjectPtr* table_;
int32_t max_serial_;
int32_t capacity_;
int32_t serial_num_;
bool wrapped_;
- RawObject** table() { return table_; }
+ ObjectPtr* table() { return table_; }
int32_t table_size() { return capacity_; }
int32_t NextSerial();
- int32_t AllocateNewId(RawObject* object);
+ int32_t AllocateNewId(ObjectPtr object);
int32_t IndexOfId(int32_t id);
int32_t IdOfIndex(int32_t index);
bool IsValidContiguous(int32_t id);
diff --git a/runtime/vm/object_id_ring_test.cc b/runtime/vm/object_id_ring_test.cc
index 1b70a92..07fa8ea 100644
--- a/runtime/vm/object_id_ring_test.cc
+++ b/runtime/vm/object_id_ring_test.cc
@@ -38,11 +38,11 @@
EXPECT_EQ(-1, ring->IdOfIndex(index));
}
- static RawObject* MakeString(const char* s) {
+ static ObjectPtr MakeString(const char* s) {
return Symbols::New(Thread::Current(), s);
}
- static void ExpectString(RawObject* obj, const char* s) {
+ static void ExpectString(ObjectPtr obj, const char* s) {
String& str = String::Handle();
str ^= obj;
EXPECT(str.Equals(s));
@@ -142,7 +142,7 @@
{
TransitionNativeToVM to_vm(thread);
- RawObject* raw_obj = Api::UnwrapHandle(result);
+ ObjectPtr raw_obj = Api::UnwrapHandle(result);
// Located in new heap.
EXPECT(raw_obj->IsNewObject());
EXPECT_NE(Object::null(), raw_obj);
@@ -157,29 +157,29 @@
// Get id 0 again.
EXPECT_EQ(raw_obj_id1,
ring->GetIdForObject(raw_obj, ObjectIdRing::kReuseId));
- RawObject* raw_obj1 = ring->GetObjectForId(raw_obj_id1, &kind);
+ ObjectPtr raw_obj1 = ring->GetObjectForId(raw_obj_id1, &kind);
EXPECT_EQ(ObjectIdRing::kValid, kind);
- RawObject* raw_obj2 = ring->GetObjectForId(raw_obj_id2, &kind);
+ ObjectPtr raw_obj2 = ring->GetObjectForId(raw_obj_id2, &kind);
EXPECT_EQ(ObjectIdRing::kValid, kind);
EXPECT_NE(Object::null(), raw_obj1);
EXPECT_NE(Object::null(), raw_obj2);
- EXPECT_EQ(RawObject::ToAddr(raw_obj), RawObject::ToAddr(raw_obj1));
- EXPECT_EQ(RawObject::ToAddr(raw_obj), RawObject::ToAddr(raw_obj2));
+ EXPECT_EQ(ObjectLayout::ToAddr(raw_obj), ObjectLayout::ToAddr(raw_obj1));
+ EXPECT_EQ(ObjectLayout::ToAddr(raw_obj), ObjectLayout::ToAddr(raw_obj2));
// Force a scavenge.
GCTestHelper::CollectNewSpace();
- RawObject* raw_object_moved1 = ring->GetObjectForId(raw_obj_id1, &kind);
+ ObjectPtr raw_object_moved1 = ring->GetObjectForId(raw_obj_id1, &kind);
EXPECT_EQ(ObjectIdRing::kValid, kind);
- RawObject* raw_object_moved2 = ring->GetObjectForId(raw_obj_id2, &kind);
+ ObjectPtr raw_object_moved2 = ring->GetObjectForId(raw_obj_id2, &kind);
EXPECT_EQ(ObjectIdRing::kValid, kind);
EXPECT_NE(Object::null(), raw_object_moved1);
EXPECT_NE(Object::null(), raw_object_moved2);
- EXPECT_EQ(RawObject::ToAddr(raw_object_moved1),
- RawObject::ToAddr(raw_object_moved2));
+ EXPECT_EQ(ObjectLayout::ToAddr(raw_object_moved1),
+ ObjectLayout::ToAddr(raw_object_moved2));
// Test that objects have moved.
- EXPECT_NE(RawObject::ToAddr(raw_obj1),
- RawObject::ToAddr(raw_object_moved1));
- EXPECT_NE(RawObject::ToAddr(raw_obj2),
- RawObject::ToAddr(raw_object_moved2));
+ EXPECT_NE(ObjectLayout::ToAddr(raw_obj1),
+ ObjectLayout::ToAddr(raw_object_moved1));
+ EXPECT_NE(ObjectLayout::ToAddr(raw_obj2),
+ ObjectLayout::ToAddr(raw_object_moved2));
// Test that we still point at the same list.
moved_handle = Api::NewHandle(thread, raw_object_moved1);
// Test id reuse.
@@ -207,7 +207,7 @@
EXPECT(!str.IsNull());
EXPECT_EQ(3, str.Length());
- RawObject* raw_obj = Object::RawCast(str.raw());
+ ObjectPtr raw_obj = Object::RawCast(str.raw());
// Verify that it is located in old heap.
EXPECT(raw_obj->IsOldObject());
EXPECT_NE(Object::null(), raw_obj);
@@ -215,24 +215,24 @@
EXPECT_EQ(0, raw_obj_id1);
raw_obj_id2 = ring->GetIdForObject(raw_obj);
EXPECT_EQ(1, raw_obj_id2);
- RawObject* raw_obj1 = ring->GetObjectForId(raw_obj_id1, &kind);
+ ObjectPtr raw_obj1 = ring->GetObjectForId(raw_obj_id1, &kind);
EXPECT_EQ(ObjectIdRing::kValid, kind);
- RawObject* raw_obj2 = ring->GetObjectForId(raw_obj_id2, &kind);
+ ObjectPtr raw_obj2 = ring->GetObjectForId(raw_obj_id2, &kind);
EXPECT_EQ(ObjectIdRing::kValid, kind);
EXPECT_NE(Object::null(), raw_obj1);
EXPECT_NE(Object::null(), raw_obj2);
- EXPECT_EQ(RawObject::ToAddr(raw_obj), RawObject::ToAddr(raw_obj1));
- EXPECT_EQ(RawObject::ToAddr(raw_obj), RawObject::ToAddr(raw_obj2));
+ EXPECT_EQ(ObjectLayout::ToAddr(raw_obj), ObjectLayout::ToAddr(raw_obj1));
+ EXPECT_EQ(ObjectLayout::ToAddr(raw_obj), ObjectLayout::ToAddr(raw_obj2));
// Exit scope. Freeing String handle.
}
// Force a GC. No reference exist to the old string anymore. It should be
// collected and the object id ring will now return the null object for
// those ids.
GCTestHelper::CollectOldSpace();
- RawObject* raw_object_moved1 = ring->GetObjectForId(raw_obj_id1, &kind);
+ ObjectPtr raw_object_moved1 = ring->GetObjectForId(raw_obj_id1, &kind);
EXPECT_EQ(ObjectIdRing::kCollected, kind);
EXPECT_EQ(Object::null(), raw_object_moved1);
- RawObject* raw_object_moved2 = ring->GetObjectForId(raw_obj_id2, &kind);
+ ObjectPtr raw_object_moved2 = ring->GetObjectForId(raw_obj_id2, &kind);
EXPECT_EQ(ObjectIdRing::kCollected, kind);
EXPECT_EQ(Object::null(), raw_object_moved2);
}
@@ -247,7 +247,7 @@
String& obj = String::Handle(String::New("I will expire"));
intptr_t obj_id = ring->GetIdForObject(obj.raw());
ObjectIdRing::LookupResult kind = ObjectIdRing::kInvalid;
- RawObject* obj_lookup = ring->GetObjectForId(obj_id, &kind);
+ ObjectPtr obj_lookup = ring->GetObjectForId(obj_id, &kind);
EXPECT_EQ(ObjectIdRing::kValid, kind);
EXPECT_EQ(obj.raw(), obj_lookup);
@@ -257,7 +257,7 @@
new_obj = String::New("Bump");
intptr_t new_obj_id = ring->GetIdForObject(new_obj.raw());
ObjectIdRing::LookupResult kind = ObjectIdRing::kInvalid;
- RawObject* new_obj_lookup = ring->GetObjectForId(new_obj_id, &kind);
+ ObjectPtr new_obj_lookup = ring->GetObjectForId(new_obj_id, &kind);
EXPECT_EQ(ObjectIdRing::kValid, kind);
EXPECT_EQ(new_obj.raw(), new_obj_lookup);
}
diff --git a/runtime/vm/object_reload.cc b/runtime/vm/object_reload.cc
index 9bbb011..669e441 100644
--- a/runtime/vm/object_reload.cc
+++ b/runtime/vm/object_reload.cc
@@ -73,9 +73,8 @@
const int32_t* offsets = code.raw_ptr()->data();
for (intptr_t i = 0; i < offsets_length; i++) {
int32_t offset = offsets[i];
- RawObject** object_ptr =
- reinterpret_cast<RawObject**>(base_address + offset);
- RawObject* raw_object = *object_ptr;
+ ObjectPtr* object_ptr = reinterpret_cast<ObjectPtr*>(base_address + offset);
+ ObjectPtr raw_object = *object_ptr;
if (!raw_object->IsHeapObject()) {
continue;
}
@@ -127,7 +126,7 @@
}
const Function& function = Function::Cast(object_);
- if (function.kind() == RawFunction::kIrregexpFunction) {
+ if (function.kind() == FunctionLayout::kIrregexpFunction) {
// Regex matchers do not support breakpoints or stepping, and they only call
// core library functions that cannot change due to reload. As a performance
// optimization, avoid this matching of ICData to PCs for these functions'
@@ -143,7 +142,7 @@
// calls.
#if defined(DEBUG)
descriptors_ = code.pc_descriptors();
- PcDescriptors::Iterator iter(descriptors_, RawPcDescriptors::kIcCall);
+ PcDescriptors::Iterator iter(descriptors_, PcDescriptorsLayout::kIcCall);
while (iter.MoveNext()) {
FATAL1("%s has IC calls but no ic_data_array\n", object_.ToCString());
}
@@ -152,7 +151,7 @@
}
descriptors_ = code.pc_descriptors();
- PcDescriptors::Iterator iter(descriptors_, RawPcDescriptors::kIcCall);
+ PcDescriptors::Iterator iter(descriptors_, PcDescriptorsLayout::kIcCall);
while (iter.MoveNext()) {
uword pc = code.PayloadStart() + iter.PcOffset();
CodePatcher::GetInstanceCallAt(pc, code, &object_);
@@ -567,7 +566,7 @@
EnumClassConflict(Zone* zone, const Class& from, const Class& to)
: ClassReasonForCancelling(zone, from, to) {}
- RawString* ToString() {
+ StringPtr ToString() {
return String::NewFormatted(
from_.is_enum_class()
? "Enum class cannot be redefined to be a non-enum class: %s"
@@ -581,7 +580,7 @@
TypedefClassConflict(Zone* zone, const Class& from, const Class& to)
: ClassReasonForCancelling(zone, from, to) {}
- RawString* ToString() {
+ StringPtr ToString() {
return String::NewFormatted(
from_.IsTypedefClass()
? "Typedef class cannot be redefined to be a non-typedef class: %s"
@@ -601,9 +600,9 @@
private:
const Error& error_;
- RawError* ToError() { return error_.raw(); }
+ ErrorPtr ToError() { return error_.raw(); }
- RawString* ToString() { return String::New(error_.ToErrorCString()); }
+ StringPtr ToString() { return String::New(error_.ToErrorCString()); }
};
class ConstToNonConstClass : public ClassReasonForCancelling {
@@ -612,7 +611,7 @@
: ClassReasonForCancelling(zone, from, to) {}
private:
- RawString* ToString() {
+ StringPtr ToString() {
return String::NewFormatted("Const class cannot become non-const: %s",
from_.ToCString());
}
@@ -624,7 +623,7 @@
: ClassReasonForCancelling(zone, from, to) {}
private:
- RawString* ToString() {
+ StringPtr ToString() {
return String::NewFormatted("Const class cannot remove fields: %s",
from_.ToCString());
}
@@ -636,7 +635,7 @@
: ClassReasonForCancelling(zone, from, to) {}
private:
- RawString* ToString() {
+ StringPtr ToString() {
return String::NewFormatted("Number of native fields changed in %s",
from_.ToCString());
}
@@ -647,7 +646,7 @@
TypeParametersChanged(Zone* zone, const Class& from, const Class& to)
: ClassReasonForCancelling(zone, from, to) {}
- RawString* ToString() {
+ StringPtr ToString() {
return String::NewFormatted(
"Limitation: type parameters have changed for %s", from_.ToCString());
}
@@ -669,7 +668,7 @@
: ClassReasonForCancelling(zone, from, to) {}
private:
- RawString* ToString() {
+ StringPtr ToString() {
return String::NewFormatted(
"Original class ('%s') is prefinalized and replacement class "
"('%s') is not ",
@@ -683,7 +682,7 @@
: ClassReasonForCancelling(zone, from, to) {}
private:
- RawString* ToString() {
+ StringPtr ToString() {
return String::NewFormatted("Instance size mismatch between '%s' (%" Pd
") and replacement "
"'%s' ( %" Pd ")",
@@ -940,7 +939,7 @@
if (rule == ICData::kStatic) {
ASSERT(old_target_.is_static() ||
- old_target_.kind() == RawFunction::kConstructor);
+ old_target_.kind() == FunctionLayout::kConstructor);
// This can be incorrect if the call site was an unqualified invocation.
new_cls_ = old_target_.Owner();
new_target_ = new_cls_.LookupFunction(name_);
diff --git a/runtime/vm/object_service.cc b/runtime/vm/object_service.cc
index 3cf2741..5b261ca 100644
--- a/runtime/vm/object_service.cc
+++ b/runtime/vm/object_service.cc
@@ -43,7 +43,7 @@
}
if (!ref) {
if (raw()->IsHeapObject()) {
- jsobj->AddProperty("size", raw()->HeapSize());
+ jsobj->AddProperty("size", raw()->ptr()->HeapSize());
} else {
jsobj->AddProperty("size", (intptr_t)0);
}
@@ -326,10 +326,10 @@
jsobj.AddProperty("_optimizedCallSiteCount", optimized_call_site_count());
jsobj.AddProperty("_deoptimizations",
static_cast<intptr_t>(deoptimization_counter()));
- if ((kind() == RawFunction::kImplicitGetter) ||
- (kind() == RawFunction::kImplicitSetter) ||
- (kind() == RawFunction::kImplicitStaticGetter) ||
- (kind() == RawFunction::kFieldInitializer)) {
+ if ((kind() == FunctionLayout::kImplicitGetter) ||
+ (kind() == FunctionLayout::kImplicitSetter) ||
+ (kind() == FunctionLayout::kImplicitStaticGetter) ||
+ (kind() == FunctionLayout::kFieldInitializer)) {
const Field& field = Field::Handle(accessor_field());
if (!field.IsNull()) {
jsobj.AddProperty("_field", field);
@@ -619,9 +619,9 @@
entry = entries.GetNext();
if (entry.IsFunction()) {
const Function& func = Function::Cast(entry);
- if (func.kind() == RawFunction::kRegularFunction ||
- func.kind() == RawFunction::kGetterFunction ||
- func.kind() == RawFunction::kSetterFunction) {
+ if (func.kind() == FunctionLayout::kRegularFunction ||
+ func.kind() == FunctionLayout::kGetterFunction ||
+ func.kind() == FunctionLayout::kSetterFunction) {
jsarr.AddValue(func);
}
}
@@ -731,7 +731,7 @@
return;
}
JSONArray members(jsobj, "members");
- Iterator iter(*this, RawPcDescriptors::kAnyKind);
+ Iterator iter(*this, PcDescriptorsLayout::kAnyKind);
while (iter.MoveNext()) {
JSONObject descriptor(&members);
descriptor.AddPropertyF("pcOffset", "%" Px "", iter.PcOffset());
@@ -768,7 +768,7 @@
JSONArray members(&jsobj, "members");
String& var_name = String::Handle();
for (intptr_t i = 0; i < Length(); i++) {
- RawLocalVarDescriptors::VarInfo info;
+ LocalVarDescriptorsLayout::VarInfo info;
var_name = GetName(i);
GetInfo(i, &info);
JSONObject var(&members);
diff --git a/runtime/vm/object_set.h b/runtime/vm/object_set.h
index f4f0254..6d8e1ff 100644
--- a/runtime/vm/object_set.h
+++ b/runtime/vm/object_set.h
@@ -63,8 +63,8 @@
sorted_ = true;
}
- bool Contains(RawObject* raw_obj) const {
- uword raw_addr = RawObject::ToAddr(raw_obj);
+ bool Contains(ObjectPtr raw_obj) const {
+ uword raw_addr = ObjectLayout::ToAddr(raw_obj);
ObjectSetRegion* region;
if (FindRegion(raw_addr, ®ion)) {
return region->ContainsObject(raw_addr);
@@ -72,8 +72,8 @@
return false;
}
- void Add(RawObject* raw_obj) {
- uword raw_addr = RawObject::ToAddr(raw_obj);
+ void Add(ObjectPtr raw_obj) {
+ uword raw_addr = ObjectLayout::ToAddr(raw_obj);
ObjectSetRegion* region;
if (FindRegion(raw_addr, ®ion)) {
return region->AddObject(raw_addr);
diff --git a/runtime/vm/object_store.cc b/runtime/vm/object_store.cc
index 595a724..c14a52a 100644
--- a/runtime/vm/object_store.cc
+++ b/runtime/vm/object_store.cc
@@ -33,7 +33,7 @@
ISOLATE_OBJECT_STORE_FIELD_LIST(INIT_FIELD, INIT_FIELD)
#undef INIT_FIELD
- for (RawObject** current = from(); current <= to(); current++) {
+ for (ObjectPtr* current = from(); current <= to(); current++) {
ASSERT(*current == Object::null());
}
}
@@ -55,7 +55,7 @@
}
#endif // !PRODUCT
-static RawUnhandledException* CreatePreallocatedUnandledException(
+static UnhandledExceptionPtr CreatePreallocatedUnandledException(
Zone* zone,
const Object& out_of_memory) {
// Allocate pre-allocated unhandled exception object initialized with the
@@ -66,7 +66,7 @@
return unhandled_exception.raw();
}
-static RawStackTrace* CreatePreallocatedStackTrace(Zone* zone) {
+static StackTracePtr CreatePreallocatedStackTrace(Zone* zone) {
const Array& code_array = Array::Handle(
zone, Array::New(StackTrace::kPreallocatedStackdepth, Heap::kOld));
const Array& pc_offset_array = Array::Handle(
@@ -79,7 +79,7 @@
return stack_trace.raw();
}
-RawError* IsolateObjectStore::PreallocateObjects() {
+ErrorPtr IsolateObjectStore::PreallocateObjects() {
Thread* thread = Thread::Current();
Isolate* isolate = thread->isolate();
Zone* zone = thread->zone();
@@ -106,7 +106,7 @@
OBJECT_STORE_FIELD_LIST(INIT_FIELD, INIT_FIELD)
#undef INIT_FIELD
- for (RawObject** current = from(); current <= to(); current++) {
+ for (ObjectPtr* current = from(); current <= to(); current++) {
ASSERT(*current == Object::null());
}
}
@@ -142,14 +142,14 @@
}
#endif // !PRODUCT
-static RawInstance* AllocateObjectByClassName(const Library& library,
- const String& class_name) {
+static InstancePtr AllocateObjectByClassName(const Library& library,
+ const String& class_name) {
const Class& cls = Class::Handle(library.LookupClassAllowPrivate(class_name));
ASSERT(!cls.IsNull());
return Instance::New(cls);
}
-RawError* ObjectStore::PreallocateObjects() {
+ErrorPtr ObjectStore::PreallocateObjects() {
Thread* thread = Thread::Current();
IsolateGroup* isolate_group = thread->isolate_group();
Isolate* isolate = thread->isolate();
@@ -186,7 +186,7 @@
return Error::null();
}
-RawFunction* ObjectStore::PrivateObjectLookup(const String& name) {
+FunctionPtr ObjectStore::PrivateObjectLookup(const String& name) {
const Library& core_lib = Library::Handle(core_library());
const String& mangled = String::ZoneHandle(core_lib.PrivateName(name));
const Class& cls = Class::Handle(object_class());
diff --git a/runtime/vm/object_store.h b/runtime/vm/object_store.h
index 102581e..dae1ce7 100644
--- a/runtime/vm/object_store.h
+++ b/runtime/vm/object_store.h
@@ -45,6 +45,8 @@
RW(Type, nullable_object_type) \
RW(Class, null_class) \
RW(Type, null_type) \
+ RW(Class, never_class) \
+ RW(Type, never_type) \
RW(Type, function_type) \
RW(Type, legacy_function_type) \
RW(Type, non_nullable_function_type) \
@@ -262,7 +264,7 @@
~IsolateObjectStore();
#define DECLARE_GETTER(Type, name) \
- Raw##Type* name() const { return name##_; } \
+ Type##Ptr name() const { return name##_; } \
static intptr_t name##_offset() { \
return OFFSET_OF(IsolateObjectStore, name##_); \
}
@@ -280,7 +282,7 @@
// Called to initialize objects required by the vm but which invoke
// dart code. If an error occurs the error object is returned otherwise
// a null object is returned.
- RawError* PreallocateObjects();
+ ErrorPtr PreallocateObjects();
void Init();
void PostLoad();
@@ -301,16 +303,16 @@
private:
// Finds a core library private method in Object.
- RawFunction* PrivateObjectLookup(const String& name);
+ FunctionPtr PrivateObjectLookup(const String& name);
- RawObject** from() {
- return reinterpret_cast<RawObject**>(&preallocated_unhandled_exception_);
+ ObjectPtr* from() {
+ return reinterpret_cast<ObjectPtr*>(&preallocated_unhandled_exception_);
}
-#define DECLARE_OBJECT_STORE_FIELD(type, name) Raw##type* name##_;
+#define DECLARE_OBJECT_STORE_FIELD(type, name) type##Ptr name##_;
ISOLATE_OBJECT_STORE_FIELD_LIST(DECLARE_OBJECT_STORE_FIELD,
DECLARE_OBJECT_STORE_FIELD)
#undef DECLARE_OBJECT_STORE_FIELD
- RawObject** to() { return reinterpret_cast<RawObject**>(&error_listeners_); }
+ ObjectPtr* to() { return reinterpret_cast<ObjectPtr*>(&error_listeners_); }
ObjectStore* object_store_;
@@ -335,7 +337,7 @@
~ObjectStore();
#define DECLARE_GETTER(Type, name) \
- Raw##Type* name() const { return name##_; } \
+ Type##Ptr name() const { return name##_; } \
static intptr_t name##_offset() { return OFFSET_OF(ObjectStore, name##_); }
#define DECLARE_GETTER_AND_SETTER(Type, name) \
DECLARE_GETTER(Type, name) \
@@ -344,7 +346,7 @@
#undef DECLARE_GETTER
#undef DECLARE_GETTER_AND_SETTER
- RawLibrary* bootstrap_library(BootstrapLibraryId index) {
+ LibraryPtr bootstrap_library(BootstrapLibraryId index) {
switch (index) {
#define MAKE_CASE(CamelName, name) \
case k##CamelName: \
@@ -385,7 +387,7 @@
// Called to initialize objects required by the vm but which invoke
// dart code. If an error occurs the error object is returned otherwise
// a null object is returned.
- RawError* PreallocateObjects();
+ ErrorPtr PreallocateObjects();
void InitKnownObjects();
@@ -397,23 +399,23 @@
private:
// Finds a core library private method in Object.
- RawFunction* PrivateObjectLookup(const String& name);
+ FunctionPtr PrivateObjectLookup(const String& name);
- RawObject** from() { return reinterpret_cast<RawObject**>(&object_class_); }
-#define DECLARE_OBJECT_STORE_FIELD(type, name) Raw##type* name##_;
+ ObjectPtr* from() { return reinterpret_cast<ObjectPtr*>(&object_class_); }
+#define DECLARE_OBJECT_STORE_FIELD(type, name) type##Ptr name##_;
OBJECT_STORE_FIELD_LIST(DECLARE_OBJECT_STORE_FIELD,
DECLARE_OBJECT_STORE_FIELD)
#undef DECLARE_OBJECT_STORE_FIELD
- RawObject** to() {
- return reinterpret_cast<RawObject**>(&ffi_as_function_internal_);
+ ObjectPtr* to() {
+ return reinterpret_cast<ObjectPtr*>(&ffi_as_function_internal_);
}
- RawObject** to_snapshot(Snapshot::Kind kind) {
+ ObjectPtr* to_snapshot(Snapshot::Kind kind) {
switch (kind) {
case Snapshot::kFull:
- return reinterpret_cast<RawObject**>(&global_object_pool_);
+ return reinterpret_cast<ObjectPtr*>(&global_object_pool_);
case Snapshot::kFullJIT:
case Snapshot::kFullAOT:
- return reinterpret_cast<RawObject**>(&megamorphic_call_miss_function_);
+ return reinterpret_cast<ObjectPtr*>(&megamorphic_call_miss_function_);
case Snapshot::kMessage:
case Snapshot::kNone:
case Snapshot::kInvalid:
diff --git a/runtime/vm/object_test.cc b/runtime/vm/object_test.cc
index eeb5264..67fa779 100644
--- a/runtime/vm/object_test.cc
+++ b/runtime/vm/object_test.cc
@@ -30,8 +30,8 @@
DECLARE_FLAG(bool, dual_map_code);
DECLARE_FLAG(bool, write_protect_code);
-static RawClass* CreateDummyClass(const String& class_name,
- const Script& script) {
+static ClassPtr CreateDummyClass(const String& class_name,
+ const Script& script) {
const Class& cls = Class::Handle(Class::New(
Library::Handle(), class_name, script, TokenPosition::kNoSource));
cls.set_is_synthesized_class(); // Dummy class for testing.
@@ -76,13 +76,13 @@
String& function_name = String::Handle();
function_name = Symbols::New(thread, "foo");
function =
- Function::New(function_name, RawFunction::kRegularFunction, false, false,
- false, false, false, cls, TokenPosition::kMinSource);
+ Function::New(function_name, FunctionLayout::kRegularFunction, false,
+ false, false, false, false, cls, TokenPosition::kMinSource);
functions.SetAt(0, function);
function_name = Symbols::New(thread, "bar");
function =
- Function::New(function_name, RawFunction::kRegularFunction, false, false,
- false, false, false, cls, TokenPosition::kMinSource);
+ Function::New(function_name, FunctionLayout::kRegularFunction, false,
+ false, false, false, false, cls, TokenPosition::kMinSource);
const int kNumFixedParameters = 2;
const int kNumOptionalParameters = 3;
@@ -94,25 +94,25 @@
function_name = Symbols::New(thread, "baz");
function =
- Function::New(function_name, RawFunction::kRegularFunction, false, false,
- false, false, false, cls, TokenPosition::kMinSource);
+ Function::New(function_name, FunctionLayout::kRegularFunction, false,
+ false, false, false, false, cls, TokenPosition::kMinSource);
functions.SetAt(2, function);
function_name = Symbols::New(thread, "Foo");
function =
- Function::New(function_name, RawFunction::kRegularFunction, true, false,
- false, false, false, cls, TokenPosition::kMinSource);
+ Function::New(function_name, FunctionLayout::kRegularFunction, true,
+ false, false, false, false, cls, TokenPosition::kMinSource);
functions.SetAt(3, function);
function_name = Symbols::New(thread, "Bar");
function =
- Function::New(function_name, RawFunction::kRegularFunction, true, false,
- false, false, false, cls, TokenPosition::kMinSource);
+ Function::New(function_name, FunctionLayout::kRegularFunction, true,
+ false, false, false, false, cls, TokenPosition::kMinSource);
functions.SetAt(4, function);
function_name = Symbols::New(thread, "BaZ");
function =
- Function::New(function_name, RawFunction::kRegularFunction, true, false,
- false, false, false, cls, TokenPosition::kMinSource);
+ Function::New(function_name, FunctionLayout::kRegularFunction, true,
+ false, false, false, false, cls, TokenPosition::kMinSource);
functions.SetAt(5, function);
// Setup the functions in the class.
@@ -240,7 +240,7 @@
one_fields.SetAt(0, field);
one_field_class.SetFields(one_fields);
one_field_class.Finalize();
- intptr_t header_size = sizeof(RawObject);
+ intptr_t header_size = sizeof(ObjectLayout);
EXPECT_EQ(Utils::RoundUp((header_size + (1 * kWordSize)), kObjectAlignment),
one_field_class.host_instance_size());
EXPECT_EQ(header_size, field.HostOffset());
@@ -2060,13 +2060,13 @@
}
used_size = Array::InstanceSize(array.Length());
new_array = Array::MakeFixedLength(array);
- addr = RawObject::ToAddr(new_array.raw());
- obj = RawObject::FromAddr(addr);
+ addr = ObjectLayout::ToAddr(new_array.raw());
+ obj = ObjectLayout::FromAddr(addr);
EXPECT(obj.IsArray());
new_array ^= obj.raw();
EXPECT_EQ(2, new_array.Length());
addr += used_size;
- obj = RawObject::FromAddr(addr);
+ obj = ObjectLayout::FromAddr(addr);
EXPECT(obj.IsTypedData());
left_over_array ^= obj.raw();
EXPECT_EQ(4 * kWordSize - TypedData::InstanceSize(0),
@@ -2083,13 +2083,13 @@
}
used_size = Array::InstanceSize(array.Length());
new_array = Array::MakeFixedLength(array);
- addr = RawObject::ToAddr(new_array.raw());
- obj = RawObject::FromAddr(addr);
+ addr = ObjectLayout::ToAddr(new_array.raw());
+ obj = ObjectLayout::FromAddr(addr);
EXPECT(obj.IsArray());
new_array ^= obj.raw();
EXPECT_EQ(3, new_array.Length());
addr += used_size;
- obj = RawObject::FromAddr(addr);
+ obj = ObjectLayout::FromAddr(addr);
if (TypedData::InstanceSize(0) <= 2 * kWordSize) {
EXPECT(obj.IsTypedData());
left_over_array ^= obj.raw();
@@ -2109,13 +2109,13 @@
}
used_size = Array::InstanceSize(array.Length());
new_array = Array::MakeFixedLength(array);
- addr = RawObject::ToAddr(new_array.raw());
- obj = RawObject::FromAddr(addr);
+ addr = ObjectLayout::ToAddr(new_array.raw());
+ obj = ObjectLayout::FromAddr(addr);
EXPECT(obj.IsArray());
new_array ^= obj.raw();
EXPECT_EQ(1, new_array.Length());
addr += used_size;
- obj = RawObject::FromAddr(addr);
+ obj = ObjectLayout::FromAddr(addr);
EXPECT(obj.IsTypedData());
left_over_array ^= obj.raw();
EXPECT_EQ(8 * kWordSize - TypedData::InstanceSize(0),
@@ -2424,7 +2424,7 @@
Function& parent = Function::Handle();
const String& parent_name = String::Handle(Symbols::New(thread, "foo_papa"));
parent =
- Function::New(parent_name, RawFunction::kRegularFunction, false, false,
+ Function::New(parent_name, FunctionLayout::kRegularFunction, false, false,
false, false, false, cls, TokenPosition::kMinSource);
functions.SetAt(0, parent);
cls.SetFunctions(functions);
@@ -2483,11 +2483,11 @@
EXPECT(!str3.IsOneByteString());
}
-static RawLibrary* CreateDummyLibrary(const String& library_name) {
+static LibraryPtr CreateDummyLibrary(const String& library_name) {
return Library::New(library_name);
}
-static RawFunction* CreateFunction(const char* name) {
+static FunctionPtr CreateFunction(const char* name) {
Thread* thread = Thread::Current();
const String& class_name = String::Handle(Symbols::New(thread, "ownerClass"));
const String& lib_name = String::Handle(Symbols::New(thread, "ownerLibrary"));
@@ -2497,7 +2497,7 @@
const Library& owner_library = Library::Handle(CreateDummyLibrary(lib_name));
owner_class.set_library(owner_library);
const String& function_name = String::ZoneHandle(Symbols::New(thread, name));
- return Function::New(function_name, RawFunction::kRegularFunction, true,
+ return Function::New(function_name, FunctionLayout::kRegularFunction, true,
false, false, false, false, owner_class,
TokenPosition::kMinSource);
}
@@ -2705,18 +2705,18 @@
DescriptorList* builder = new DescriptorList(0);
// kind, pc_offset, deopt_id, token_pos, try_index, yield_index
- builder->AddDescriptor(RawPcDescriptors::kOther, 10, 1, TokenPosition(20), 1,
- 1);
- builder->AddDescriptor(RawPcDescriptors::kDeopt, 20, 2, TokenPosition(30), 0,
- -1);
- builder->AddDescriptor(RawPcDescriptors::kOther, 30, 3, TokenPosition(40), 1,
- 10);
- builder->AddDescriptor(RawPcDescriptors::kOther, 10, 4, TokenPosition(40), 2,
- 20);
- builder->AddDescriptor(RawPcDescriptors::kOther, 10, 5, TokenPosition(80), 3,
- 30);
- builder->AddDescriptor(RawPcDescriptors::kOther, 80, 6, TokenPosition(150), 3,
- 30);
+ builder->AddDescriptor(PcDescriptorsLayout::kOther, 10, 1, TokenPosition(20),
+ 1, 1);
+ builder->AddDescriptor(PcDescriptorsLayout::kDeopt, 20, 2, TokenPosition(30),
+ 0, -1);
+ builder->AddDescriptor(PcDescriptorsLayout::kOther, 30, 3, TokenPosition(40),
+ 1, 10);
+ builder->AddDescriptor(PcDescriptorsLayout::kOther, 10, 4, TokenPosition(40),
+ 2, 20);
+ builder->AddDescriptor(PcDescriptorsLayout::kOther, 10, 5, TokenPosition(80),
+ 3, 30);
+ builder->AddDescriptor(PcDescriptorsLayout::kOther, 80, 6, TokenPosition(150),
+ 3, 30);
PcDescriptors& descriptors = PcDescriptors::Handle();
descriptors ^= builder->FinalizePcDescriptors(0);
@@ -2732,7 +2732,7 @@
// Verify the PcDescriptor entries by accessing them.
const PcDescriptors& pc_descs = PcDescriptors::Handle(code.pc_descriptors());
- PcDescriptors::Iterator iter(pc_descs, RawPcDescriptors::kAnyKind);
+ PcDescriptors::Iterator iter(pc_descs, PcDescriptorsLayout::kAnyKind);
EXPECT_EQ(true, iter.MoveNext());
EXPECT_EQ(1, iter.YieldIndex());
@@ -2740,12 +2740,12 @@
EXPECT_EQ(1, iter.TryIndex());
EXPECT_EQ(static_cast<uword>(10), iter.PcOffset());
EXPECT_EQ(1, iter.DeoptId());
- EXPECT_EQ(RawPcDescriptors::kOther, iter.Kind());
+ EXPECT_EQ(PcDescriptorsLayout::kOther, iter.Kind());
EXPECT_EQ(true, iter.MoveNext());
EXPECT_EQ(-1, iter.YieldIndex());
EXPECT_EQ(30, iter.TokenPos().value());
- EXPECT_EQ(RawPcDescriptors::kDeopt, iter.Kind());
+ EXPECT_EQ(PcDescriptorsLayout::kDeopt, iter.Kind());
EXPECT_EQ(true, iter.MoveNext());
EXPECT_EQ(10, iter.YieldIndex());
@@ -2766,7 +2766,7 @@
EXPECT_EQ(3, iter.TryIndex());
EXPECT_EQ(static_cast<uword>(80), iter.PcOffset());
EXPECT_EQ(150, iter.TokenPos().value());
- EXPECT_EQ(RawPcDescriptors::kOther, iter.Kind());
+ EXPECT_EQ(PcDescriptorsLayout::kOther, iter.Kind());
EXPECT_EQ(false, iter.MoveNext());
}
@@ -2775,18 +2775,18 @@
DescriptorList* builder = new DescriptorList(0);
// kind, pc_offset, deopt_id, token_pos, try_index
- builder->AddDescriptor(RawPcDescriptors::kOther, 100, 1, TokenPosition(200),
- 1, 10);
- builder->AddDescriptor(RawPcDescriptors::kDeopt, 200, 2, TokenPosition(300),
- 0, -1);
- builder->AddDescriptor(RawPcDescriptors::kOther, 300, 3, TokenPosition(400),
- 1, 10);
- builder->AddDescriptor(RawPcDescriptors::kOther, 100, 4, TokenPosition(0), 2,
- 20);
- builder->AddDescriptor(RawPcDescriptors::kOther, 100, 5, TokenPosition(800),
- 3, 30);
- builder->AddDescriptor(RawPcDescriptors::kOther, 800, 6, TokenPosition(150),
- 3, 30);
+ builder->AddDescriptor(PcDescriptorsLayout::kOther, 100, 1,
+ TokenPosition(200), 1, 10);
+ builder->AddDescriptor(PcDescriptorsLayout::kDeopt, 200, 2,
+ TokenPosition(300), 0, -1);
+ builder->AddDescriptor(PcDescriptorsLayout::kOther, 300, 3,
+ TokenPosition(400), 1, 10);
+ builder->AddDescriptor(PcDescriptorsLayout::kOther, 100, 4, TokenPosition(0),
+ 2, 20);
+ builder->AddDescriptor(PcDescriptorsLayout::kOther, 100, 5,
+ TokenPosition(800), 3, 30);
+ builder->AddDescriptor(PcDescriptorsLayout::kOther, 800, 6,
+ TokenPosition(150), 3, 30);
PcDescriptors& descriptors = PcDescriptors::Handle();
descriptors ^= builder->FinalizePcDescriptors(0);
@@ -2802,7 +2802,7 @@
// Verify the PcDescriptor entries by accessing them.
const PcDescriptors& pc_descs = PcDescriptors::Handle(code.pc_descriptors());
- PcDescriptors::Iterator iter(pc_descs, RawPcDescriptors::kAnyKind);
+ PcDescriptors::Iterator iter(pc_descs, PcDescriptorsLayout::kAnyKind);
EXPECT_EQ(true, iter.MoveNext());
EXPECT_EQ(10, iter.YieldIndex());
@@ -2810,12 +2810,12 @@
EXPECT_EQ(1, iter.TryIndex());
EXPECT_EQ(static_cast<uword>(100), iter.PcOffset());
EXPECT_EQ(1, iter.DeoptId());
- EXPECT_EQ(RawPcDescriptors::kOther, iter.Kind());
+ EXPECT_EQ(PcDescriptorsLayout::kOther, iter.Kind());
EXPECT_EQ(true, iter.MoveNext());
EXPECT_EQ(-1, iter.YieldIndex());
EXPECT_EQ(300, iter.TokenPos().value());
- EXPECT_EQ(RawPcDescriptors::kDeopt, iter.Kind());
+ EXPECT_EQ(PcDescriptorsLayout::kDeopt, iter.Kind());
EXPECT_EQ(true, iter.MoveNext());
EXPECT_EQ(10, iter.YieldIndex());
@@ -2836,12 +2836,12 @@
EXPECT_EQ(3, iter.TryIndex());
EXPECT_EQ(static_cast<uword>(800), iter.PcOffset());
EXPECT_EQ(150, iter.TokenPos().value());
- EXPECT_EQ(RawPcDescriptors::kOther, iter.Kind());
+ EXPECT_EQ(PcDescriptorsLayout::kOther, iter.Kind());
EXPECT_EQ(false, iter.MoveNext());
}
-static RawClass* CreateTestClass(const char* name) {
+static ClassPtr CreateTestClass(const char* name) {
const String& class_name =
String::Handle(Symbols::New(Thread::Current(), name));
const Class& cls =
@@ -2849,7 +2849,7 @@
return cls.raw();
}
-static RawField* CreateTestField(const char* name) {
+static FieldPtr CreateTestField(const char* name) {
const Class& cls = Class::Handle(CreateTestClass("global:"));
const String& field_name =
String::Handle(Symbols::New(Thread::Current(), name));
@@ -2881,7 +2881,7 @@
EXPECT(count == 2);
}
-static RawFunction* GetDummyTarget(const char* name) {
+static FunctionPtr GetDummyTarget(const char* name) {
const String& function_name =
String::Handle(Symbols::New(Thread::Current(), name));
const Class& cls =
@@ -2891,9 +2891,9 @@
const bool is_abstract = false;
const bool is_external = false;
const bool is_native = false;
- return Function::New(function_name, RawFunction::kRegularFunction, is_static,
- is_const, is_abstract, is_external, is_native, cls,
- TokenPosition::kMinSource);
+ return Function::New(function_name, FunctionLayout::kRegularFunction,
+ is_static, is_const, is_abstract, is_external, is_native,
+ cls, TokenPosition::kMinSource);
}
ISOLATE_UNIT_TEST_CASE(ICData) {
@@ -3622,28 +3622,28 @@
EXPECT(obj.IsMirrorReference());
}
-static RawFunction* GetFunction(const Class& cls, const char* name) {
+static FunctionPtr GetFunction(const Class& cls, const char* name) {
const Function& result = Function::Handle(
cls.LookupDynamicFunction(String::Handle(String::New(name))));
EXPECT(!result.IsNull());
return result.raw();
}
-static RawFunction* GetStaticFunction(const Class& cls, const char* name) {
+static FunctionPtr GetStaticFunction(const Class& cls, const char* name) {
const Function& result = Function::Handle(
cls.LookupStaticFunction(String::Handle(String::New(name))));
EXPECT(!result.IsNull());
return result.raw();
}
-static RawField* GetField(const Class& cls, const char* name) {
+static FieldPtr GetField(const Class& cls, const char* name) {
const Field& field =
Field::Handle(cls.LookupField(String::Handle(String::New(name))));
EXPECT(!field.IsNull());
return field.raw();
}
-static RawClass* GetClass(const Library& lib, const char* name) {
+static ClassPtr GetClass(const Library& lib, const char* name) {
const Class& cls = Class::Handle(
lib.LookupClass(String::Handle(Symbols::New(Thread::Current(), name))));
EXPECT(!cls.IsNull()); // No ambiguity error expected.
@@ -3661,7 +3661,7 @@
Function& parent = Function::Handle();
const String& parent_name = String::Handle(Symbols::New(thread, "foo_papa"));
parent =
- Function::New(parent_name, RawFunction::kRegularFunction, false, false,
+ Function::New(parent_name, FunctionLayout::kRegularFunction, false, false,
false, false, false, cls, TokenPosition::kMinSource);
functions.SetAt(0, parent);
cls.SetFunctions(functions);
@@ -3697,7 +3697,7 @@
Function& parent = Function::Handle();
const String& parent_name = String::Handle(Symbols::New(thread, "foo_papa"));
parent =
- Function::New(parent_name, RawFunction::kRegularFunction, false, false,
+ Function::New(parent_name, FunctionLayout::kRegularFunction, false, false,
false, false, false, cls, TokenPosition::kMinSource);
functions.SetAt(0, parent);
cls.SetFunctions(functions);
@@ -3710,7 +3710,7 @@
Function& invocation_dispatcher = Function::Handle();
invocation_dispatcher ^= cls.GetInvocationDispatcher(
invocation_dispatcher_name, args_desc,
- RawFunction::kNoSuchMethodDispatcher, true /* create_if_absent */);
+ FunctionLayout::kNoSuchMethodDispatcher, true /* create_if_absent */);
EXPECT(!invocation_dispatcher.IsNull());
// Get index to function.
intptr_t invocation_dispatcher_index =
@@ -3987,7 +3987,7 @@
explicit ObjectAccumulator(GrowableArray<Object*>* objects)
: objects_(objects) {}
virtual ~ObjectAccumulator() {}
- virtual void VisitObject(RawObject* obj) {
+ virtual void VisitObject(ObjectPtr obj) {
if (obj->IsPseudoObject()) {
return; // Cannot be wrapped in handles.
}
diff --git a/runtime/vm/object_x64_test.cc b/runtime/vm/object_x64_test.cc
index 259305c..e8913ce 100644
--- a/runtime/vm/object_x64_test.cc
+++ b/runtime/vm/object_x64_test.cc
@@ -43,8 +43,7 @@
// This is used to test Embedded Smi objects in the instructions.
void GenerateEmbedSmiInCode(compiler::Assembler* assembler, intptr_t value) {
const Smi& smi_object = Smi::ZoneHandle(Smi::New(value));
- __ movq(RAX,
- compiler::Immediate(reinterpret_cast<int64_t>(smi_object.raw())));
+ __ movq(RAX, compiler::Immediate(static_cast<int64_t>(smi_object.raw())));
__ ret();
}
diff --git a/runtime/vm/pointer_tagging.h b/runtime/vm/pointer_tagging.h
index 70fd9d7..587bffa 100644
--- a/runtime/vm/pointer_tagging.h
+++ b/runtime/vm/pointer_tagging.h
@@ -17,8 +17,6 @@
namespace dart {
-class RawSmi;
-
// Dart VM aligns all objects by 2 words in in the old space and misaligns them
// in new space. This allows to distinguish new and old pointers by their bits.
//
@@ -86,12 +84,6 @@
kSmiTagShift = 1,
};
-inline intptr_t ValueFromRawSmi(const RawSmi* raw_value) {
- const intptr_t value = reinterpret_cast<intptr_t>(raw_value);
- ASSERT((value & kSmiTagMask) == kSmiTag);
- return (value >> kSmiTagShift);
-}
-
} // namespace dart
#endif // RUNTIME_VM_POINTER_TAGGING_H_
diff --git a/runtime/vm/port.cc b/runtime/vm/port.cc
index 140121d..9d5c331 100644
--- a/runtime/vm/port.cc
+++ b/runtime/vm/port.cc
@@ -56,7 +56,7 @@
continue;
}
- ASSERT(!reinterpret_cast<RawObject*>(result)->IsWellFormed());
+ ASSERT(!static_cast<ObjectPtr>(static_cast<uword>(result))->IsWellFormed());
} while (ports_->Contains(result));
ASSERT(result != 0);
@@ -223,6 +223,14 @@
return handler->isolate();
}
+bool PortMap::IsReceiverInThisIsolateGroup(Dart_Port receiver,
+ IsolateGroup* group) {
+ MutexLocker ml(mutex_);
+ auto it = ports_->TryLookup(receiver);
+ if (it == ports_->end()) return false;
+ return (*it).handler->isolate()->group() == group;
+}
+
void PortMap::Init() {
// TODO(bkonyi): don't keep ports_ after Dart_Cleanup.
if (mutex_ == NULL) {
diff --git a/runtime/vm/port.h b/runtime/vm/port.h
index 1d9c88e..0297f1d 100644
--- a/runtime/vm/port.h
+++ b/runtime/vm/port.h
@@ -58,6 +58,9 @@
// Returns the owning Isolate for port 'id'.
static Isolate* GetIsolate(Dart_Port id);
+ static bool IsReceiverInThisIsolateGroup(Dart_Port receiver,
+ IsolateGroup* group);
+
static void Init();
static void Cleanup();
diff --git a/runtime/vm/profiler.cc b/runtime/vm/profiler.cc
index 69eaf42..43cd2d0 100644
--- a/runtime/vm/profiler.cc
+++ b/runtime/vm/profiler.cc
@@ -1451,7 +1451,7 @@
~CodeLookupTableBuilder() {}
- void VisitObject(RawObject* raw_obj) {
+ void VisitObject(ObjectPtr raw_obj) {
if (raw_obj->IsCode()) {
table_->Add(Code::Handle(Code::RawCast(raw_obj)));
} else if (raw_obj->IsBytecode()) {
diff --git a/runtime/vm/profiler.h b/runtime/vm/profiler.h
index 49d6814..d63175b 100644
--- a/runtime/vm/profiler.h
+++ b/runtime/vm/profiler.h
@@ -456,11 +456,11 @@
class AbstractCode {
public:
- explicit AbstractCode(RawObject* code) : code_(Object::Handle(code)) {
+ explicit AbstractCode(ObjectPtr code) : code_(Object::Handle(code)) {
ASSERT(code_.IsNull() || code_.IsCode() || code_.IsBytecode());
}
- RawObject* raw() const { return code_.raw(); }
+ ObjectPtr raw() const { return code_.raw(); }
const Object* handle() const { return &code_; }
uword PayloadStart() const {
@@ -533,7 +533,7 @@
}
}
- RawObject* owner() const {
+ ObjectPtr owner() const {
if (code_.IsCode()) {
return Code::Cast(code_).owner();
} else if (code_.IsBytecode()) {
diff --git a/runtime/vm/profiler_service.h b/runtime/vm/profiler_service.h
index f34c24c..0ad1e7f 100644
--- a/runtime/vm/profiler_service.h
+++ b/runtime/vm/profiler_service.h
@@ -28,8 +28,6 @@
class JSONStream;
class ProfileFunctionTable;
class ProfileCodeTable;
-class RawCode;
-class RawFunction;
class SampleFilter;
class ProcessedSample;
class ProcessedSampleBuffer;
diff --git a/runtime/vm/profiler_test.cc b/runtime/vm/profiler_test.cc
index fdc4c54..fd6751e 100644
--- a/runtime/vm/profiler_test.cc
+++ b/runtime/vm/profiler_test.cc
@@ -155,7 +155,7 @@
delete sample_buffer;
}
-static RawLibrary* LoadTestScript(const char* script) {
+static LibraryPtr LoadTestScript(const char* script) {
Dart_Handle api_lib;
{
TransitionVMToNative transition(Thread::Current());
@@ -167,7 +167,7 @@
return lib.raw();
}
-static RawClass* GetClass(const Library& lib, const char* name) {
+static ClassPtr GetClass(const Library& lib, const char* name) {
Thread* thread = Thread::Current();
const Class& cls = Class::Handle(
lib.LookupClassAllowPrivate(String::Handle(Symbols::New(thread, name))));
@@ -175,7 +175,7 @@
return cls.raw();
}
-static RawFunction* GetFunction(const Library& lib, const char* name) {
+static FunctionPtr GetFunction(const Library& lib, const char* name) {
Thread* thread = Thread::Current();
const Function& func = Function::Handle(lib.LookupFunctionAllowPrivate(
String::Handle(Symbols::New(thread, name))));
diff --git a/runtime/vm/program_visitor.cc b/runtime/vm/program_visitor.cc
index 1080e7d..7085853 100644
--- a/runtime/vm/program_visitor.cc
+++ b/runtime/vm/program_visitor.cc
@@ -18,7 +18,7 @@
WorklistElement(Zone* zone, const Object& object)
: object_(Object::Handle(zone, object.raw())), next_(nullptr) {}
- RawObject* value() const { return object_.raw(); }
+ ObjectPtr value() const { return object_.raw(); }
void set_next(WorklistElement* elem) { next_ = elem; }
WorklistElement* next() const { return next_; }
@@ -51,7 +51,7 @@
ASSERT(first_ != nullptr && last_ != nullptr);
}
- RawObject* Remove() {
+ ObjectPtr Remove() {
ASSERT(first_ != nullptr);
WorklistElement* result = first_;
first_ = first_->next();
@@ -174,15 +174,21 @@
ASSERT(visitor_->IsCodeVisitor());
visitor_->AsCodeVisitor()->VisitCode(code);
- // If the precompiler can drop function objects not needed at runtime,
- // then some entries in the static calls table may need to be visited.
+ // In the precompiler, some entries in the static calls table may need
+ // to be visited as they may not be reachable from other sources.
+ //
+ // TODO(dartbug.com/41636): Figure out why walking the static calls table
+ // in JIT mode with the DedupInstructions visitor fails, so we can remove
+ // the check for AOT mode.
static_calls_array_ = code.static_calls_target_table();
- if (static_calls_array_.IsNull()) return;
- StaticCallsTable static_calls(static_calls_array_);
- for (auto& view : static_calls) {
- static_calls_table_entry_ = view.Get<Code::kSCallTableCodeOrTypeTarget>();
- if (static_calls_table_entry_.IsCode()) {
- AddToWorklist(Code::Cast(static_calls_table_entry_));
+ if (FLAG_precompiled_mode && !static_calls_array_.IsNull()) {
+ StaticCallsTable static_calls(static_calls_array_);
+ for (auto& view : static_calls) {
+ static_calls_table_entry_ =
+ view.Get<Code::kSCallTableCodeOrTypeTarget>();
+ if (static_calls_table_entry_.IsCode()) {
+ AddToWorklist(Code::Cast(static_calls_table_entry_));
+ }
}
}
}
@@ -316,7 +322,7 @@
}
}
- typename T::RawObjectType* Dedup(const T& obj) {
+ typename T::ObjectPtrType Dedup(const T& obj) {
if (ShouldAdd(obj)) {
if (auto const canonical = canonical_objects_.LookupValue(&obj)) {
return canonical->raw();
@@ -577,7 +583,7 @@
// Creates a new global table of stack map information. Also adds the
// offsets of encoded StackMapEntry objects to entry_offsets for use
// when normalizing CompressedStackMaps.
- RawCompressedStackMaps* CreateGlobalTable(
+ CompressedStackMapsPtr CreateGlobalTable(
StackMapEntryIntMap* entry_offsets) {
ASSERT(entry_offsets->IsEmpty());
if (collected_entries_.length() == 0) return CompressedStackMaps::null();
@@ -671,7 +677,7 @@
private:
// Creates a normalized CSM from the given non-normalized CSM.
- RawCompressedStackMaps* NormalizeEntries(const CompressedStackMaps& maps) {
+ CompressedStackMapsPtr NormalizeEntries(const CompressedStackMaps& maps) {
GrowableArray<uint8_t> new_payload;
CompressedStackMapsIterator it(maps, old_global_table_);
intptr_t last_offset = 0;
@@ -1027,7 +1033,7 @@
private:
bool IsCorrectType(const Object& obj) const { return obj.IsArray(); }
- RawArray* PrepareParameterTypes(const Function& function) {
+ ArrayPtr PrepareParameterTypes(const Function& function) {
list_ = function.parameter_types();
// Preserve parameter types in the JIT. Needed in case of recompilation
// in checked mode, or if available to mirrors, or for copied types to
@@ -1045,7 +1051,7 @@
return list_.raw();
}
- RawArray* PrepareParameterNames(const Function& function) {
+ ArrayPtr PrepareParameterNames(const Function& function) {
list_ = function.parameter_names();
// Preserve parameter names in case of recompilation for the JIT. Also
// avoid attempting to change read-only VM objects for de-duplication.
@@ -1158,7 +1164,7 @@
public:
explicit DedupInstructionsVisitor(Zone* zone)
: Dedupper(zone),
- function_(Function::Handle(zone)),
+ code_(Code::Handle(zone)),
instructions_(Instructions::Handle(zone)) {
if (Snapshot::IncludesCode(Dart::vm_snapshot_kind())) {
// Prefer existing objects in the VM isolate.
@@ -1166,12 +1172,22 @@
}
}
- void VisitObject(RawObject* obj) {
+ void VisitObject(ObjectPtr obj) {
if (!obj->IsInstructions()) return;
instructions_ = Instructions::RawCast(obj);
AddCanonical(instructions_);
}
+ void VisitFunction(const Function& function) {
+ if (!function.HasCode()) return;
+ code_ = function.CurrentCode();
+ // This causes the code to be visited once here and once directly in the
+ // ProgramWalker, but as long as the deduplication process is idempotent,
+ // the cached entry points won't change during the second visit.
+ VisitCode(code_);
+ function.SetInstructions(code_); // Update cached entry point.
+ }
+
void VisitCode(const Code& code) {
instructions_ = code.instructions();
instructions_ = Dedup(instructions_);
@@ -1182,33 +1198,32 @@
}
code.SetActiveInstructions(instructions_,
code.UncheckedEntryPointOffset());
- if (!code.IsFunctionCode()) return;
- function_ = code.function();
- if (function_.IsNull()) return;
- function_.SetInstructions(code); // Update cached entry point.
}
private:
- Function& function_;
+ Code& code_;
Instructions& instructions_;
};
#if defined(DART_PRECOMPILER)
class DedupInstructionsWithSameMetadataVisitor
: public CodeVisitor,
- public Dedupper<Code, CodeKeyValueTrait>,
- public ObjectVisitor {
+ public Dedupper<Code, CodeKeyValueTrait> {
public:
explicit DedupInstructionsWithSameMetadataVisitor(Zone* zone)
: Dedupper(zone),
canonical_(Code::Handle(zone)),
- function_(Function::Handle(zone)),
+ code_(Code::Handle(zone)),
instructions_(Instructions::Handle(zone)) {}
- void VisitObject(RawObject* obj) {
- if (!obj->IsCode()) return;
- canonical_ = Code::RawCast(obj);
- AddCanonical(canonical_);
+ void VisitFunction(const Function& function) {
+ if (!function.HasCode()) return;
+ code_ = function.CurrentCode();
+ // This causes the code to be visited once here and once directly in the
+ // ProgramWalker, but as long as the deduplication process is idempotent,
+ // the cached entry points won't change during the second visit.
+ VisitCode(code_);
+ function.SetInstructions(code_); // Update cached entry point.
}
void VisitCode(const Code& code) {
@@ -1218,17 +1233,13 @@
code.SetActiveInstructions(instructions_,
code.UncheckedEntryPointOffset());
code.set_instructions(instructions_);
- if (!code.IsFunctionCode()) return;
- function_ = code.function();
- if (function_.IsNull()) return;
- function_.SetInstructions(code); // Update cached entry point.
}
private:
bool CanCanonicalize(const Code& code) const { return !code.IsDisabled(); }
Code& canonical_;
- Function& function_;
+ Code& code_;
Instructions& instructions_;
};
diff --git a/runtime/vm/raw_object.cc b/runtime/vm/raw_object.cc
index c2270e0..ada6634 100644
--- a/runtime/vm/raw_object.cc
+++ b/runtime/vm/raw_object.cc
@@ -16,7 +16,7 @@
namespace dart {
-bool RawObject::InVMIsolateHeap() const {
+bool ObjectLayout::InVMIsolateHeap() const {
// All "vm-isolate" objects are pre-marked and in old space
// (see [Object::FinalizeVMIsolate]).
if (!IsOldObject() || !IsMarked()) return false;
@@ -26,20 +26,24 @@
return heap->old_space()->ContainsUnsafe(ToAddr(this));
}
-void RawObject::Validate(IsolateGroup* isolate_group) const {
- if (Object::void_class_ == reinterpret_cast<RawClass*>(kHeapObjectTag)) {
- // Validation relies on properly initialized class classes. Skip if the
- // VM is still being initialized.
- return;
- }
+void ObjectPtr::Validate(IsolateGroup* isolate_group) const {
// All Smi values are valid.
if (!IsHeapObject()) {
return;
}
// Slightly more readable than a segfault.
- if (this == reinterpret_cast<RawObject*>(kHeapObjectTag)) {
+ if (tagged_pointer_ == kHeapObjectTag) {
FATAL("RAW_NULL encountered");
}
+ ptr()->Validate(isolate_group);
+}
+
+void ObjectLayout::Validate(IsolateGroup* isolate_group) const {
+ if (static_cast<uword>(Object::void_class_) == kHeapObjectTag) {
+ // Validation relies on properly initialized class classes. Skip if the
+ // VM is still being initialized.
+ return;
+ }
// Validate that the tags_ field is sensible.
uint32_t tags = ptr()->tags_;
if (IsNewObject()) {
@@ -86,79 +90,75 @@
// compaction when the class objects are moving. Can use the class
// id in the header and the sizes in the Class Table.
// Cannot deference ptr()->tags_. May dereference other parts of the object.
-intptr_t RawObject::HeapSizeFromClass(uint32_t tags) const {
- // Only reasonable to be called on heap objects.
- ASSERT(IsHeapObject());
-
+intptr_t ObjectLayout::HeapSizeFromClass(uint32_t tags) const {
intptr_t class_id = ClassIdTag::decode(tags);
intptr_t instance_size = 0;
switch (class_id) {
case kCodeCid: {
- const RawCode* raw_code = reinterpret_cast<const RawCode*>(this);
+ const CodePtr raw_code = static_cast<const CodePtr>(this);
intptr_t pointer_offsets_length =
Code::PtrOffBits::decode(raw_code->ptr()->state_bits_);
instance_size = Code::InstanceSize(pointer_offsets_length);
break;
}
case kInstructionsCid: {
- const RawInstructions* raw_instructions =
- reinterpret_cast<const RawInstructions*>(this);
+ const InstructionsPtr raw_instructions =
+ static_cast<const InstructionsPtr>(this);
intptr_t instructions_size = Instructions::Size(raw_instructions);
instance_size = Instructions::InstanceSize(instructions_size);
break;
}
case kInstructionsSectionCid: {
- const RawInstructionsSection* raw_section =
- reinterpret_cast<const RawInstructionsSection*>(this);
+ const InstructionsSectionPtr raw_section =
+ static_cast<const InstructionsSectionPtr>(this);
intptr_t section_size = InstructionsSection::Size(raw_section);
instance_size = InstructionsSection::InstanceSize(section_size);
break;
}
case kContextCid: {
- const RawContext* raw_context = reinterpret_cast<const RawContext*>(this);
+ const ContextPtr raw_context = static_cast<const ContextPtr>(this);
intptr_t num_variables = raw_context->ptr()->num_variables_;
instance_size = Context::InstanceSize(num_variables);
break;
}
case kContextScopeCid: {
- const RawContextScope* raw_context_scope =
- reinterpret_cast<const RawContextScope*>(this);
+ const ContextScopePtr raw_context_scope =
+ static_cast<const ContextScopePtr>(this);
intptr_t num_variables = raw_context_scope->ptr()->num_variables_;
instance_size = ContextScope::InstanceSize(num_variables);
break;
}
case kOneByteStringCid: {
- const RawOneByteString* raw_string =
- reinterpret_cast<const RawOneByteString*>(this);
+ const OneByteStringPtr raw_string =
+ static_cast<const OneByteStringPtr>(this);
intptr_t string_length = Smi::Value(raw_string->ptr()->length_);
instance_size = OneByteString::InstanceSize(string_length);
break;
}
case kTwoByteStringCid: {
- const RawTwoByteString* raw_string =
- reinterpret_cast<const RawTwoByteString*>(this);
+ const TwoByteStringPtr raw_string =
+ static_cast<const TwoByteStringPtr>(this);
intptr_t string_length = Smi::Value(raw_string->ptr()->length_);
instance_size = TwoByteString::InstanceSize(string_length);
break;
}
case kArrayCid:
case kImmutableArrayCid: {
- const RawArray* raw_array = reinterpret_cast<const RawArray*>(this);
+ const ArrayPtr raw_array = static_cast<const ArrayPtr>(this);
intptr_t array_length = Smi::Value(raw_array->ptr()->length_);
instance_size = Array::InstanceSize(array_length);
break;
}
case kObjectPoolCid: {
- const RawObjectPool* raw_object_pool =
- reinterpret_cast<const RawObjectPool*>(this);
+ const ObjectPoolPtr raw_object_pool =
+ static_cast<const ObjectPoolPtr>(this);
intptr_t len = raw_object_pool->ptr()->length_;
instance_size = ObjectPool::InstanceSize(len);
break;
}
#define SIZE_FROM_CLASS(clazz) case kTypedData##clazz##Cid:
CLASS_LIST_TYPED_DATA(SIZE_FROM_CLASS) {
- const RawTypedData* raw_obj =
- reinterpret_cast<const RawTypedData*>(this);
+ const TypedDataPtr raw_obj = static_cast<const TypedDataPtr>(this);
intptr_t array_len = Smi::Value(raw_obj->ptr()->length_);
intptr_t lengthInBytes =
array_len * TypedData::ElementSizeInBytes(class_id);
@@ -170,55 +170,55 @@
instance_size = Pointer::InstanceSize();
break;
case kTypeArgumentsCid: {
- const RawTypeArguments* raw_array =
- reinterpret_cast<const RawTypeArguments*>(this);
+ const TypeArgumentsPtr raw_array =
+ static_cast<const TypeArgumentsPtr>(this);
intptr_t array_length = Smi::Value(raw_array->ptr()->length_);
instance_size = TypeArguments::InstanceSize(array_length);
break;
}
case kPcDescriptorsCid: {
- const RawPcDescriptors* raw_descriptors =
- reinterpret_cast<const RawPcDescriptors*>(this);
+ const PcDescriptorsPtr raw_descriptors =
+ static_cast<const PcDescriptorsPtr>(this);
intptr_t length = raw_descriptors->ptr()->length_;
instance_size = PcDescriptors::InstanceSize(length);
break;
}
case kCodeSourceMapCid: {
- const RawCodeSourceMap* raw_code_source_map =
- reinterpret_cast<const RawCodeSourceMap*>(this);
+ const CodeSourceMapPtr raw_code_source_map =
+ static_cast<const CodeSourceMapPtr>(this);
intptr_t length = raw_code_source_map->ptr()->length_;
instance_size = CodeSourceMap::InstanceSize(length);
break;
}
case kCompressedStackMapsCid: {
- const RawCompressedStackMaps* maps =
- reinterpret_cast<const RawCompressedStackMaps*>(this);
+ const CompressedStackMapsPtr maps =
+ static_cast<const CompressedStackMapsPtr>(this);
intptr_t length = CompressedStackMaps::PayloadSizeOf(maps);
instance_size = CompressedStackMaps::InstanceSize(length);
break;
}
case kLocalVarDescriptorsCid: {
- const RawLocalVarDescriptors* raw_descriptors =
- reinterpret_cast<const RawLocalVarDescriptors*>(this);
+ const LocalVarDescriptorsPtr raw_descriptors =
+ static_cast<const LocalVarDescriptorsPtr>(this);
intptr_t num_descriptors = raw_descriptors->ptr()->num_entries_;
instance_size = LocalVarDescriptors::InstanceSize(num_descriptors);
break;
}
case kExceptionHandlersCid: {
- const RawExceptionHandlers* raw_handlers =
- reinterpret_cast<const RawExceptionHandlers*>(this);
+ const ExceptionHandlersPtr raw_handlers =
+ static_cast<const ExceptionHandlersPtr>(this);
intptr_t num_handlers = raw_handlers->ptr()->num_entries_;
instance_size = ExceptionHandlers::InstanceSize(num_handlers);
break;
}
case kFreeListElement: {
- uword addr = RawObject::ToAddr(this);
+ uword addr = ObjectLayout::ToAddr(this);
FreeListElement* element = reinterpret_cast<FreeListElement*>(addr);
instance_size = element->HeapSize();
break;
}
case kForwardingCorpse: {
- uword addr = RawObject::ToAddr(this);
+ uword addr = ObjectLayout::ToAddr(this);
ForwardingCorpse* element = reinterpret_cast<ForwardingCorpse*>(addr);
instance_size = element->HeapSize();
break;
@@ -262,7 +262,7 @@
int retries_remaining = 1000; // ... but not forever.
do {
OS::Sleep(1);
- const RawArray* raw_array = reinterpret_cast<const RawArray*>(this);
+ const ArrayPtr raw_array = static_cast<const ArrayPtr>(this);
intptr_t array_length = Smi::Value(raw_array->ptr()->length_);
instance_size = Array::InstanceSize(array_length);
} while ((instance_size > tags_size) && (--retries_remaining > 0));
@@ -275,60 +275,59 @@
return instance_size;
}
-intptr_t RawObject::VisitPointersPredefined(ObjectPointerVisitor* visitor,
- intptr_t class_id) {
+intptr_t ObjectLayout::VisitPointersPredefined(ObjectPointerVisitor* visitor,
+ intptr_t class_id) {
ASSERT(class_id < kNumPredefinedCids);
intptr_t size = 0;
- // Only reasonable to be called on heap objects.
- ASSERT(IsHeapObject());
-
switch (class_id) {
#define RAW_VISITPOINTERS(clazz) \
case k##clazz##Cid: { \
- Raw##clazz* raw_obj = reinterpret_cast<Raw##clazz*>(this); \
- size = Raw##clazz::Visit##clazz##Pointers(raw_obj, visitor); \
+ clazz##Ptr raw_obj = static_cast<clazz##Ptr>(this); \
+ size = clazz##Layout::Visit##clazz##Pointers(raw_obj, visitor); \
break; \
}
CLASS_LIST_NO_OBJECT(RAW_VISITPOINTERS)
#undef RAW_VISITPOINTERS
#define RAW_VISITPOINTERS(clazz) case kTypedData##clazz##Cid:
CLASS_LIST_TYPED_DATA(RAW_VISITPOINTERS) {
- RawTypedData* raw_obj = reinterpret_cast<RawTypedData*>(this);
- size = RawTypedData::VisitTypedDataPointers(raw_obj, visitor);
+ TypedDataPtr raw_obj = static_cast<TypedDataPtr>(this);
+ size = TypedDataLayout::VisitTypedDataPointers(raw_obj, visitor);
break;
}
#undef RAW_VISITPOINTERS
#define RAW_VISITPOINTERS(clazz) case kExternalTypedData##clazz##Cid:
CLASS_LIST_TYPED_DATA(RAW_VISITPOINTERS) {
- auto raw_obj = reinterpret_cast<RawExternalTypedData*>(this);
- size = RawExternalTypedData::VisitExternalTypedDataPointers(raw_obj,
- visitor);
+ auto raw_obj = static_cast<ExternalTypedDataPtr>(this);
+ size = ExternalTypedDataLayout::VisitExternalTypedDataPointers(raw_obj,
+ visitor);
break;
}
#undef RAW_VISITPOINTERS
case kByteDataViewCid:
#define RAW_VISITPOINTERS(clazz) case kTypedData##clazz##ViewCid:
CLASS_LIST_TYPED_DATA(RAW_VISITPOINTERS) {
- auto raw_obj = reinterpret_cast<RawTypedDataView*>(this);
- size = RawTypedDataView::VisitTypedDataViewPointers(raw_obj, visitor);
+ auto raw_obj = static_cast<TypedDataViewPtr>(this);
+ size =
+ TypedDataViewLayout::VisitTypedDataViewPointers(raw_obj, visitor);
break;
}
#undef RAW_VISITPOINTERS
case kByteBufferCid: {
- RawInstance* raw_obj = reinterpret_cast<RawInstance*>(this);
- size = RawInstance::VisitInstancePointers(raw_obj, visitor);
+ InstancePtr raw_obj = static_cast<InstancePtr>(this);
+ size = InstanceLayout::VisitInstancePointers(raw_obj, visitor);
break;
}
case kFfiPointerCid: {
- RawPointer* raw_obj = reinterpret_cast<RawPointer*>(this);
- size = RawPointer::VisitPointerPointers(raw_obj, visitor);
+ PointerPtr raw_obj = static_cast<PointerPtr>(this);
+ size = PointerLayout::VisitPointerPointers(raw_obj, visitor);
break;
}
case kFfiDynamicLibraryCid: {
- RawDynamicLibrary* raw_obj = reinterpret_cast<RawDynamicLibrary*>(this);
- size = RawDynamicLibrary::VisitDynamicLibraryPointers(raw_obj, visitor);
+ DynamicLibraryPtr raw_obj = static_cast<DynamicLibraryPtr>(this);
+ size =
+ DynamicLibraryLayout::VisitDynamicLibraryPointers(raw_obj, visitor);
break;
}
#define RAW_VISITPOINTERS(clazz) case kFfi##clazz##Cid:
@@ -346,13 +345,13 @@
}
#undef RAW_VISITPOINTERS
case kFreeListElement: {
- uword addr = RawObject::ToAddr(this);
+ uword addr = ObjectLayout::ToAddr(this);
FreeListElement* element = reinterpret_cast<FreeListElement*>(addr);
size = element->HeapSize();
break;
}
case kForwardingCorpse: {
- uword addr = RawObject::ToAddr(this);
+ uword addr = ObjectLayout::ToAddr(this);
ForwardingCorpse* forwarder = reinterpret_cast<ForwardingCorpse*>(addr);
size = forwarder->HeapSize();
break;
@@ -384,8 +383,8 @@
#endif
}
-void RawObject::VisitPointersPrecise(Isolate* isolate,
- ObjectPointerVisitor* visitor) {
+void ObjectLayout::VisitPointersPrecise(Isolate* isolate,
+ ObjectPointerVisitor* visitor) {
intptr_t class_id = GetClassId();
if (class_id < kNumPredefinedCids) {
VisitPointersPredefined(visitor, class_id);
@@ -398,19 +397,19 @@
->host_next_field_offset_in_words_
<< kWordSizeLog2;
ASSERT(next_field_offset > 0);
- uword obj_addr = RawObject::ToAddr(this);
- uword from = obj_addr + sizeof(RawObject);
+ uword obj_addr = ObjectLayout::ToAddr(this);
+ uword from = obj_addr + sizeof(ObjectLayout);
uword to = obj_addr + next_field_offset - kWordSize;
- const auto first = reinterpret_cast<RawObject**>(from);
- const auto last = reinterpret_cast<RawObject**>(to);
+ const auto first = reinterpret_cast<ObjectPtr*>(from);
+ const auto last = reinterpret_cast<ObjectPtr*>(to);
#if defined(SUPPORT_UNBOXED_INSTANCE_FIELDS)
const auto unboxed_fields_bitmap =
visitor->shared_class_table()->GetUnboxedFieldsMapAt(class_id);
if (!unboxed_fields_bitmap.IsEmpty()) {
- intptr_t bit = sizeof(RawObject) / kWordSize;
- for (RawObject** current = first; current <= last; current++) {
+ intptr_t bit = sizeof(ObjectLayout) / kWordSize;
+ for (ObjectPtr* current = first; current <= last; current++) {
if (!unboxed_fields_bitmap.Get(bit++)) {
visitor->VisitPointer(current);
}
@@ -423,21 +422,21 @@
#endif // defined(SUPPORT_UNBOXED_INSTANCE_FIELDS)
}
-bool RawObject::FindObject(FindObjectVisitor* visitor) {
+bool ObjectLayout::FindObject(FindObjectVisitor* visitor) {
ASSERT(visitor != NULL);
- return visitor->FindObject(this);
+ return visitor->FindObject(static_cast<ObjectPtr>(this));
}
// Most objects are visited with this function. It calls the from() and to()
// methods on the raw object to get the first and last cells that need
// visiting.
#define REGULAR_VISITOR(Type) \
- intptr_t Raw##Type::Visit##Type##Pointers(Raw##Type* raw_obj, \
- ObjectPointerVisitor* visitor) { \
+ intptr_t Type##Layout::Visit##Type##Pointers( \
+ Type##Ptr raw_obj, ObjectPointerVisitor* visitor) { \
/* Make sure that we got here with the tagged pointer as this. */ \
ASSERT(raw_obj->IsHeapObject()); \
ASSERT_UNCOMPRESSED(Type); \
- visitor->VisitPointers(raw_obj->from(), raw_obj->to()); \
+ visitor->VisitPointers(raw_obj->ptr()->from(), raw_obj->ptr()->to()); \
return Type::InstanceSize(); \
}
@@ -447,25 +446,26 @@
// Though as opposed to Similar to [REGULAR_VISITOR] this visitor will call the
// specializd VisitTypedDataViewPointers
#define TYPED_DATA_VIEW_VISITOR(Type) \
- intptr_t Raw##Type::Visit##Type##Pointers(Raw##Type* raw_obj, \
- ObjectPointerVisitor* visitor) { \
+ intptr_t Type##Layout::Visit##Type##Pointers( \
+ Type##Ptr raw_obj, ObjectPointerVisitor* visitor) { \
/* Make sure that we got here with the tagged pointer as this. */ \
ASSERT(raw_obj->IsHeapObject()); \
ASSERT_UNCOMPRESSED(Type); \
- visitor->VisitTypedDataViewPointers(raw_obj, raw_obj->from(), \
- raw_obj->to()); \
+ visitor->VisitTypedDataViewPointers(raw_obj, raw_obj->ptr()->from(), \
+ raw_obj->ptr()->to()); \
return Type::InstanceSize(); \
}
// For variable length objects. get_length is a code snippet that gets the
// length of the object, which is passed to InstanceSize and the to() method.
#define VARIABLE_VISITOR(Type, get_length) \
- intptr_t Raw##Type::Visit##Type##Pointers(Raw##Type* raw_obj, \
- ObjectPointerVisitor* visitor) { \
+ intptr_t Type##Layout::Visit##Type##Pointers( \
+ Type##Ptr raw_obj, ObjectPointerVisitor* visitor) { \
/* Make sure that we got here with the tagged pointer as this. */ \
ASSERT(raw_obj->IsHeapObject()); \
intptr_t length = get_length; \
- visitor->VisitPointers(raw_obj->from(), raw_obj->to(length)); \
+ visitor->VisitPointers(raw_obj->ptr()->from(), \
+ raw_obj->ptr()->to(length)); \
return Type::InstanceSize(length); \
}
@@ -476,8 +476,8 @@
// For fixed-length objects that don't have any pointers that need visiting.
#define NULL_VISITOR(Type) \
- intptr_t Raw##Type::Visit##Type##Pointers(Raw##Type* raw_obj, \
- ObjectPointerVisitor* visitor) { \
+ intptr_t Type##Layout::Visit##Type##Pointers( \
+ Type##Ptr raw_obj, ObjectPointerVisitor* visitor) { \
/* Make sure that we got here with the tagged pointer as this. */ \
ASSERT(raw_obj->IsHeapObject()); \
ASSERT_NOTHING_TO_VISIT(Type); \
@@ -487,8 +487,8 @@
// For objects that don't have any pointers that need visiting, but have a
// variable length.
#define VARIABLE_NULL_VISITOR(Type, get_length) \
- intptr_t Raw##Type::Visit##Type##Pointers(Raw##Type* raw_obj, \
- ObjectPointerVisitor* visitor) { \
+ intptr_t Type##Layout::Visit##Type##Pointers( \
+ Type##Ptr raw_obj, ObjectPointerVisitor* visitor) { \
/* Make sure that we got here with the tagged pointer as this. */ \
ASSERT(raw_obj->IsHeapObject()); \
ASSERT_NOTHING_TO_VISIT(Type); \
@@ -498,8 +498,8 @@
// For objects that are never instantiated on the heap.
#define UNREACHABLE_VISITOR(Type) \
- intptr_t Raw##Type::Visit##Type##Pointers(Raw##Type* raw_obj, \
- ObjectPointerVisitor* visitor) { \
+ intptr_t Type##Layout::Visit##Type##Pointers( \
+ Type##Ptr raw_obj, ObjectPointerVisitor* visitor) { \
UNREACHABLE(); \
return 0; \
}
@@ -591,19 +591,19 @@
REGULAR_VISITOR(WeakSerializationReference)
#endif
-bool RawCode::ContainsPC(const RawObject* raw_obj, uword pc) {
+bool CodeLayout::ContainsPC(const ObjectPtr raw_obj, uword pc) {
if (!raw_obj->IsCode()) return false;
- auto const raw_code = static_cast<const RawCode*>(raw_obj);
+ auto const raw_code = static_cast<const CodePtr>(raw_obj);
const uword start = Code::PayloadStartOf(raw_code);
const uword size = Code::PayloadSizeOf(raw_code);
return (pc - start) <= size; // pc may point just past last instruction.
}
-intptr_t RawCode::VisitCodePointers(RawCode* raw_obj,
- ObjectPointerVisitor* visitor) {
- visitor->VisitPointers(raw_obj->from(), raw_obj->to());
+intptr_t CodeLayout::VisitCodePointers(CodePtr raw_obj,
+ ObjectPointerVisitor* visitor) {
+ visitor->VisitPointers(raw_obj->ptr()->from(), raw_obj->ptr()->to());
- RawCode* obj = raw_obj->ptr();
+ CodeLayout* obj = raw_obj->ptr();
intptr_t length = Code::PtrOffBits::decode(obj->state_bits_);
#if defined(TARGET_ARCH_IA32)
// On IA32 only we embed pointers to objects directly in the generated
@@ -613,8 +613,7 @@
uword entry_point = Code::PayloadStartOf(raw_obj);
for (intptr_t i = 0; i < length; i++) {
int32_t offset = obj->data()[i];
- visitor->VisitPointer(
- reinterpret_cast<RawObject**>(entry_point + offset));
+ visitor->VisitPointer(reinterpret_cast<ObjectPtr*>(entry_point + offset));
}
}
return Code::InstanceSize(length);
@@ -626,9 +625,9 @@
#endif
}
-bool RawBytecode::ContainsPC(RawObject* raw_obj, uword pc) {
+bool BytecodeLayout::ContainsPC(ObjectPtr raw_obj, uword pc) {
if (raw_obj->IsBytecode()) {
- RawBytecode* raw_bytecode = static_cast<RawBytecode*>(raw_obj);
+ BytecodePtr raw_bytecode = static_cast<BytecodePtr>(raw_obj);
uword start = raw_bytecode->ptr()->instructions_;
uword size = raw_bytecode->ptr()->instructions_size_;
return (pc - start) <= size; // pc may point past last instruction.
@@ -636,10 +635,11 @@
return false;
}
-intptr_t RawObjectPool::VisitObjectPoolPointers(RawObjectPool* raw_obj,
- ObjectPointerVisitor* visitor) {
+intptr_t ObjectPoolLayout::VisitObjectPoolPointers(
+ ObjectPoolPtr raw_obj,
+ ObjectPointerVisitor* visitor) {
const intptr_t length = raw_obj->ptr()->length_;
- RawObjectPool::Entry* entries = raw_obj->ptr()->data();
+ ObjectPoolLayout::Entry* entries = raw_obj->ptr()->data();
uint8_t* entry_bits = raw_obj->ptr()->entry_bits();
for (intptr_t i = 0; i < length; ++i) {
ObjectPool::EntryType entry_type =
@@ -652,7 +652,7 @@
return ObjectPool::InstanceSize(length);
}
-bool RawInstructions::ContainsPC(const RawInstructions* raw_instr, uword pc) {
+bool InstructionsLayout::ContainsPC(const InstructionsPtr raw_instr, uword pc) {
const uword start = Instructions::PayloadStart(raw_instr);
const uword size = Instructions::Size(raw_instr);
// We use <= instead of < here because the saved-pc can be outside the
@@ -661,8 +661,8 @@
return (pc - start) <= size;
}
-intptr_t RawInstance::VisitInstancePointers(RawInstance* raw_obj,
- ObjectPointerVisitor* visitor) {
+intptr_t InstanceLayout::VisitInstancePointers(InstancePtr raw_obj,
+ ObjectPointerVisitor* visitor) {
// Make sure that we got here with the tagged pointer as this.
ASSERT(raw_obj->IsHeapObject());
uint32_t tags = raw_obj->ptr()->tags_;
@@ -673,36 +673,37 @@
}
// Calculate the first and last raw object pointer fields.
- uword obj_addr = RawObject::ToAddr(raw_obj);
- uword from = obj_addr + sizeof(RawObject);
+ uword obj_addr = ObjectLayout::ToAddr(raw_obj);
+ uword from = obj_addr + sizeof(ObjectLayout);
uword to = obj_addr + instance_size - kWordSize;
- visitor->VisitPointers(reinterpret_cast<RawObject**>(from),
- reinterpret_cast<RawObject**>(to));
+ visitor->VisitPointers(reinterpret_cast<ObjectPtr*>(from),
+ reinterpret_cast<ObjectPtr*>(to));
return instance_size;
}
-intptr_t RawImmutableArray::VisitImmutableArrayPointers(
- RawImmutableArray* raw_obj,
+intptr_t ImmutableArrayLayout::VisitImmutableArrayPointers(
+ ImmutableArrayPtr raw_obj,
ObjectPointerVisitor* visitor) {
- return RawArray::VisitArrayPointers(raw_obj, visitor);
+ return ArrayLayout::VisitArrayPointers(raw_obj, visitor);
}
-void RawObject::RememberCard(RawObject* const* slot) {
- HeapPage::Of(this)->RememberCard(slot);
+void ObjectLayout::RememberCard(ObjectPtr const* slot) {
+ HeapPage::Of(static_cast<ObjectPtr>(this))->RememberCard(slot);
}
DEFINE_LEAF_RUNTIME_ENTRY(void,
RememberCard,
2,
- RawObject* object,
- RawObject** slot) {
+ uword /*ObjectPtr*/ object_in,
+ ObjectPtr* slot) {
+ ObjectPtr object = static_cast<ObjectPtr>(object_in);
ASSERT(object->IsOldObject());
- ASSERT(object->IsCardRemembered());
+ ASSERT(object->ptr()->IsCardRemembered());
HeapPage::Of(object)->RememberCard(slot);
}
END_LEAF_RUNTIME_ENTRY
-const char* RawPcDescriptors::KindToCString(Kind k) {
+const char* PcDescriptorsLayout::KindToCString(Kind k) {
switch (k) {
#define ENUM_CASE(name, init) \
case Kind::k##name: \
@@ -714,7 +715,7 @@
}
}
-bool RawPcDescriptors::ParseKind(const char* cstr, Kind* out) {
+bool PcDescriptorsLayout::ParseKind(const char* cstr, Kind* out) {
ASSERT(cstr != nullptr && out != nullptr);
#define ENUM_CASE(name, init) \
if (strcmp(#name, cstr) == 0) { \
diff --git a/runtime/vm/raw_object.h b/runtime/vm/raw_object.h
index 0b6e0e4..576d992 100644
--- a/runtime/vm/raw_object.h
+++ b/runtime/vm/raw_object.h
@@ -19,18 +19,19 @@
#include "vm/globals.h"
#include "vm/pointer_tagging.h"
#include "vm/snapshot.h"
+#include "vm/tagged_pointer.h"
#include "vm/token.h"
#include "vm/token_position.h"
namespace dart {
// For now there are no compressed pointers.
-typedef RawObject* RawCompressed;
+typedef ObjectPtr RawCompressed;
// Forward declarations.
class Isolate;
class IsolateGroup;
-#define DEFINE_FORWARD_DECLARATION(clazz) class Raw##clazz;
+#define DEFINE_FORWARD_DECLARATION(clazz) class clazz##Layout;
CLASS_LIST(DEFINE_FORWARD_DECLARATION)
#undef DEFINE_FORWARD_DECLARATION
class CodeStatistics;
@@ -47,15 +48,15 @@
#define VISIT_NOTHING() int NothingToVisit();
#define ASSERT_UNCOMPRESSED(Type) \
- ASSERT(SIZE_OF_DEREFERENCED_RETURNED_VALUE(Raw##Type, from) == kWordSize)
+ ASSERT(SIZE_OF_DEREFERENCED_RETURNED_VALUE(Type##Layout, from) == kWordSize)
// For now there are no compressed pointers, so this assert is the same as
// the above.
#define ASSERT_COMPRESSED(Type) \
- ASSERT(SIZE_OF_DEREFERENCED_RETURNED_VALUE(Raw##Type, from) == kWordSize)
+ ASSERT(SIZE_OF_DEREFERENCED_RETURNED_VALUE(Type##Layout, from) == kWordSize)
#define ASSERT_NOTHING_TO_VISIT(Type) \
- ASSERT(SIZE_OF_RETURNED_VALUE(Raw##Type, NothingToVisit) == sizeof(int))
+ ASSERT(SIZE_OF_RETURNED_VALUE(Type##Layout, NothingToVisit) == sizeof(int))
enum TypedDataElementType {
#define V(name) k##name##Element,
@@ -69,7 +70,7 @@
friend class SnapshotWriter;
#define VISITOR_SUPPORT(object) \
- static intptr_t Visit##object##Pointers(Raw##object* raw_obj, \
+ static intptr_t Visit##object##Pointers(object##Ptr raw_obj, \
ObjectPointerVisitor* visitor);
#define HEAP_PROFILER_SUPPORT() friend class HeapProfiler;
@@ -78,7 +79,7 @@
private: /* NOLINT */ \
VISITOR_SUPPORT(object) \
friend class object; \
- friend class RawObject; \
+ friend class ObjectLayout; \
friend class Heap; \
friend class Interpreter; \
friend class InterpreterHelpers; \
@@ -86,17 +87,13 @@
friend class SimulatorHelpers; \
friend class OffsetsTable; \
DISALLOW_ALLOCATION(); \
- DISALLOW_IMPLICIT_CONSTRUCTORS(Raw##object)
+ DISALLOW_IMPLICIT_CONSTRUCTORS(object##Layout)
// TODO(koda): Make ptr() return const*, like Object::raw_ptr().
#define RAW_HEAP_OBJECT_IMPLEMENTATION(object) \
private: \
RAW_OBJECT_IMPLEMENTATION(object); \
- Raw##object* ptr() const { \
- ASSERT(IsHeapObject()); \
- return reinterpret_cast<Raw##object*>(reinterpret_cast<uword>(this) - \
- kHeapObjectTag); \
- } \
+ object##Layout* ptr() const { return const_cast<object##Layout*>(this); } \
SNAPSHOT_WRITER_SUPPORT() \
HEAP_PROFILER_SUPPORT() \
friend class object##SerializationCluster; \
@@ -108,7 +105,7 @@
// RawObject is the base class of all raw objects; even though it carries the
// tags_ field not all raw objects are allocated in the heap and thus cannot
// be dereferenced (e.g. RawSmi).
-class RawObject {
+class ObjectLayout {
public:
// The tags field which is a part of the object header uses the following
// bit fields for storing tags.
@@ -151,7 +148,7 @@
typedef intptr_t Type;
static constexpr intptr_t kMaxSizeTagInUnitsOfAlignment =
- ((1 << RawObject::kSizeTagSize) - 1);
+ ((1 << ObjectLayout::kSizeTagSize) - 1);
static constexpr intptr_t kMaxSizeTag =
kMaxSizeTagInUnitsOfAlignment * kObjectAlignment;
@@ -274,51 +271,15 @@
COMPILE_ASSERT(sizeof(std::atomic<uint32_t>) == sizeof(uint32_t));
};
- bool IsWellFormed() const {
- uword value = reinterpret_cast<uword>(this);
- return (value & kSmiTagMask) == 0 ||
- Utils::IsAligned(value - kHeapObjectTag, kWordSize);
- }
- bool IsHeapObject() const {
- ASSERT(IsWellFormed());
- uword value = reinterpret_cast<uword>(this);
- return (value & kSmiTagMask) == kHeapObjectTag;
- }
// Assumes this is a heap object.
bool IsNewObject() const {
- ASSERT(IsHeapObject());
uword addr = reinterpret_cast<uword>(this);
- return (addr & kNewObjectAlignmentOffset) == kNewObjectAlignmentOffset;
- }
- bool IsNewObjectMayBeSmi() const {
- static const uword kNewObjectBits =
- (kNewObjectAlignmentOffset | kHeapObjectTag);
- const uword addr = reinterpret_cast<uword>(this);
- return (addr & kObjectAlignmentMask) == kNewObjectBits;
+ return (addr & kObjectAlignmentMask) == kNewObjectAlignmentOffset;
}
// Assumes this is a heap object.
bool IsOldObject() const {
- ASSERT(IsHeapObject());
uword addr = reinterpret_cast<uword>(this);
- return (addr & kNewObjectAlignmentOffset) == kOldObjectAlignmentOffset;
- }
-
- // Like !IsHeapObject() || IsOldObject(), but compiles to a single branch.
- bool IsSmiOrOldObject() const {
- ASSERT(IsWellFormed());
- static const uword kNewObjectBits =
- (kNewObjectAlignmentOffset | kHeapObjectTag);
- const uword addr = reinterpret_cast<uword>(this);
- return (addr & kObjectAlignmentMask) != kNewObjectBits;
- }
-
- // Like !IsHeapObject() || IsNewObject(), but compiles to a single branch.
- bool IsSmiOrNewObject() const {
- ASSERT(IsWellFormed());
- static const uword kOldObjectBits =
- (kOldObjectAlignmentOffset | kHeapObjectTag);
- const uword addr = reinterpret_cast<uword>(this);
- return (addr & kObjectAlignmentMask) != kOldObjectBits;
+ return (addr & kObjectAlignmentMask) == kOldObjectAlignmentOffset;
}
// Support for GC marking bit. Marked objects are either grey (not yet
@@ -376,7 +337,7 @@
void AddToRememberedSet(Thread* thread) {
ASSERT(!this->IsRemembered());
this->SetRememberedBit();
- thread->StoreBufferAddObject(this);
+ thread->StoreBufferAddObject(ObjectPtr(this));
}
bool IsCardRemembered() const {
@@ -388,51 +349,9 @@
ptr()->tags_.UpdateUnsynchronized<CardRememberedBit>(true);
}
-#define DEFINE_IS_CID(clazz) \
- bool Is##clazz() const { return ((GetClassId() == k##clazz##Cid)); }
- CLASS_LIST(DEFINE_IS_CID)
-#undef DEFINE_IS_CID
-
-#define DEFINE_IS_CID(clazz) \
- bool IsTypedData##clazz() const { \
- return ((GetClassId() == kTypedData##clazz##Cid)); \
- } \
- bool IsTypedDataView##clazz() const { \
- return ((GetClassId() == kTypedData##clazz##ViewCid)); \
- } \
- bool IsExternalTypedData##clazz() const { \
- return ((GetClassId() == kExternalTypedData##clazz##Cid)); \
- }
- CLASS_LIST_TYPED_DATA(DEFINE_IS_CID)
-#undef DEFINE_IS_CID
-
-#define DEFINE_IS_CID(clazz) \
- bool IsFfi##clazz() const { return ((GetClassId() == kFfi##clazz##Cid)); }
- CLASS_LIST_FFI(DEFINE_IS_CID)
-#undef DEFINE_IS_CID
-
- bool IsStringInstance() const { return IsStringClassId(GetClassId()); }
- bool IsRawNull() const { return GetClassId() == kNullCid; }
- bool IsDartInstance() const {
- return (!IsHeapObject() || (GetClassId() >= kInstanceCid));
- }
- bool IsFreeListElement() const {
- return ((GetClassId() == kFreeListElement));
- }
- bool IsForwardingCorpse() const {
- return ((GetClassId() == kForwardingCorpse));
- }
- bool IsPseudoObject() const {
- return IsFreeListElement() || IsForwardingCorpse();
- }
-
intptr_t GetClassId() const { return ptr()->tags_.Read<ClassIdTag>(); }
- intptr_t GetClassIdMayBeSmi() const {
- return IsHeapObject() ? GetClassId() : static_cast<intptr_t>(kSmiCid);
- }
intptr_t HeapSize() const {
- ASSERT(IsHeapObject());
uint32_t tags = ptr()->tags_;
intptr_t result = SizeTag::decode(tags);
if (result != 0) {
@@ -458,7 +377,6 @@
// This variant must not deference ptr()->tags_.
intptr_t HeapSize(uint32_t tags) const {
- ASSERT(IsHeapObject());
intptr_t result = SizeTag::decode(tags);
if (result != 0) {
return result;
@@ -470,7 +388,7 @@
bool Contains(uword addr) const {
intptr_t this_size = HeapSize();
- uword this_addr = RawObject::ToAddr(this);
+ uword this_addr = ObjectLayout::ToAddr(this);
return (addr >= this_addr) && (addr < (this_addr + this_size));
}
@@ -490,18 +408,18 @@
// Calculate the first and last raw object pointer fields.
intptr_t instance_size = HeapSize();
uword obj_addr = ToAddr(this);
- uword from = obj_addr + sizeof(RawObject);
+ uword from = obj_addr + sizeof(ObjectLayout);
uword to = obj_addr + instance_size - kWordSize;
- const auto first = reinterpret_cast<RawObject**>(from);
- const auto last = reinterpret_cast<RawObject**>(to);
+ const auto first = reinterpret_cast<ObjectPtr*>(from);
+ const auto last = reinterpret_cast<ObjectPtr*>(to);
#if defined(SUPPORT_UNBOXED_INSTANCE_FIELDS)
const auto unboxed_fields_bitmap =
visitor->shared_class_table()->GetUnboxedFieldsMapAt(class_id);
if (!unboxed_fields_bitmap.IsEmpty()) {
- intptr_t bit = sizeof(RawObject) / kWordSize;
- for (RawObject** current = first; current <= last; current++) {
+ intptr_t bit = sizeof(ObjectLayout) / kWordSize;
+ for (ObjectPtr* current = first; current <= last; current++) {
if (!unboxed_fields_bitmap.Get(bit++)) {
visitor->VisitPointer(current);
}
@@ -528,18 +446,18 @@
// Calculate the first and last raw object pointer fields.
intptr_t instance_size = HeapSize();
uword obj_addr = ToAddr(this);
- uword from = obj_addr + sizeof(RawObject);
+ uword from = obj_addr + sizeof(ObjectLayout);
uword to = obj_addr + instance_size - kWordSize;
- const auto first = reinterpret_cast<RawObject**>(from);
- const auto last = reinterpret_cast<RawObject**>(to);
+ const auto first = reinterpret_cast<ObjectPtr*>(from);
+ const auto last = reinterpret_cast<ObjectPtr*>(to);
#if defined(SUPPORT_UNBOXED_INSTANCE_FIELDS)
const auto unboxed_fields_bitmap =
visitor->shared_class_table()->GetUnboxedFieldsMapAt(class_id);
if (!unboxed_fields_bitmap.IsEmpty()) {
- intptr_t bit = sizeof(RawObject) / kWordSize;
- for (RawObject** current = first; current <= last; current++) {
+ intptr_t bit = sizeof(ObjectLayout) / kWordSize;
+ for (ObjectPtr* current = first; current <= last; current++) {
if (!unboxed_fields_bitmap.Get(bit++)) {
visitor->V::VisitPointers(current, current);
}
@@ -559,14 +477,17 @@
// rounding up instance sizes up to the allocation unit.
void VisitPointersPrecise(Isolate* isolate, ObjectPointerVisitor* visitor);
- static RawObject* FromAddr(uword addr) {
+ static ObjectPtr FromAddr(uword addr) {
// We expect the untagged address here.
ASSERT((addr & kSmiTagMask) != kHeapObjectTag);
- return reinterpret_cast<RawObject*>(addr + kHeapObjectTag);
+ return static_cast<ObjectPtr>(addr + kHeapObjectTag);
}
- static uword ToAddr(const RawObject* raw_obj) {
- return reinterpret_cast<uword>(raw_obj->ptr());
+ static uword ToAddr(const ObjectLayout* raw_obj) {
+ return reinterpret_cast<uword>(raw_obj);
+ }
+ static uword ToAddr(const ObjectPtr raw_obj) {
+ return static_cast<uword>(raw_obj) - kHeapObjectTag;
}
static bool IsCanonical(intptr_t value) {
@@ -585,11 +506,7 @@
#endif
// TODO(koda): After handling tags_, return const*, like Object::raw_ptr().
- RawObject* ptr() const {
- ASSERT(IsHeapObject());
- return reinterpret_cast<RawObject*>(reinterpret_cast<uword>(this) -
- kHeapObjectTag);
- }
+ ObjectLayout* ptr() const { return const_cast<ObjectLayout*>(this); }
intptr_t VisitPointersPredefined(ObjectPointerVisitor* visitor,
intptr_t class_id);
@@ -628,7 +545,7 @@
}
DART_FORCE_INLINE
- void CheckHeapPointerStore(RawObject* value, Thread* thread) {
+ void CheckHeapPointerStore(ObjectPtr value, Thread* thread) {
uint32_t source_tags = this->ptr()->tags_;
uint32_t target_tags = value->ptr()->tags_;
if (((source_tags >> kBarrierOverlapShift) & target_tags &
@@ -648,7 +565,7 @@
return;
}
#endif
- if (value->TryAcquireMarkBit()) {
+ if (value->ptr()->TryAcquireMarkBit()) {
thread->MarkingStackAddObject(value);
}
}
@@ -674,7 +591,7 @@
template <typename type>
DART_FORCE_INLINE void CheckArrayPointerStore(type const* addr,
- RawObject* value,
+ ObjectPtr value,
Thread* thread) {
uint32_t source_tags = this->ptr()->tags_;
uint32_t target_tags = value->ptr()->tags_;
@@ -685,10 +602,10 @@
// old-and-not-remembered -> new reference.
ASSERT(!this->IsRemembered());
if (this->IsCardRemembered()) {
- RememberCard(reinterpret_cast<RawObject* const*>(addr));
+ RememberCard(reinterpret_cast<ObjectPtr const*>(addr));
} else {
this->SetRememberedBit();
- thread->StoreBufferAddObject(this);
+ thread->StoreBufferAddObject(static_cast<ObjectPtr>(this));
}
} else {
// Incremental barrier: record when a store creates an
@@ -701,7 +618,7 @@
return;
}
#endif
- if (value->TryAcquireMarkBit()) {
+ if (value->ptr()->TryAcquireMarkBit()) {
thread->MarkingStackAddObject(value);
}
}
@@ -710,21 +627,21 @@
// Use for storing into an explicitly Smi-typed field of an object
// (i.e., both the previous and new value are Smis).
- void StoreSmi(RawSmi* const* addr, RawSmi* value) {
+ void StoreSmi(SmiPtr const* addr, SmiPtr value) {
// Can't use Contains, as array length is initialized through this method.
- ASSERT(reinterpret_cast<uword>(addr) >= RawObject::ToAddr(this));
- *const_cast<RawSmi**>(addr) = value;
+ ASSERT(reinterpret_cast<uword>(addr) >= ObjectLayout::ToAddr(this));
+ *const_cast<SmiPtr*>(addr) = value;
}
NO_SANITIZE_THREAD
- void StoreSmiIgnoreRace(RawSmi* const* addr, RawSmi* value) {
+ void StoreSmiIgnoreRace(SmiPtr const* addr, SmiPtr value) {
// Can't use Contains, as array length is initialized through this method.
- ASSERT(reinterpret_cast<uword>(addr) >= RawObject::ToAddr(this));
- *const_cast<RawSmi**>(addr) = value;
+ ASSERT(reinterpret_cast<uword>(addr) >= ObjectLayout::ToAddr(this));
+ *const_cast<SmiPtr*>(addr) = value;
}
protected:
friend class StoreBufferUpdateVisitor; // RememberCard
- void RememberCard(RawObject* const* slot);
+ void RememberCard(ObjectPtr const* slot);
friend class Array;
friend class ByteBuffer;
@@ -748,7 +665,7 @@
friend class Mint;
friend class Object;
friend class OneByteString; // StoreSmi
- friend class RawInstance;
+ friend class InstanceLayout;
friend class Scavenger;
template <bool>
friend class ScavengerVisitorBase;
@@ -774,10 +691,14 @@
friend class Object;
DISALLOW_ALLOCATION();
- DISALLOW_IMPLICIT_CONSTRUCTORS(RawObject);
+ DISALLOW_IMPLICIT_CONSTRUCTORS(ObjectLayout);
};
-class RawClass : public RawObject {
+inline intptr_t ObjectPtr::GetClassId() const {
+ return ptr()->GetClassId();
+}
+
+class ClassLayout : public ObjectLayout {
public:
enum ClassFinalizedState {
kAllocated = 0, // Initial state.
@@ -801,35 +722,35 @@
private:
RAW_HEAP_OBJECT_IMPLEMENTATION(Class);
- VISIT_FROM(RawObject*, name_);
- RawString* name_;
- RawString* user_name_;
- RawArray* functions_;
- RawArray* functions_hash_table_;
- RawArray* fields_;
- RawArray* offset_in_words_to_field_;
- RawArray* interfaces_; // Array of AbstractType.
- RawScript* script_;
- RawLibrary* library_;
- RawTypeArguments* type_parameters_; // Array of TypeParameter.
- RawAbstractType* super_type_;
- RawFunction* signature_function_; // Associated function for typedef class.
- RawArray* constants_; // Canonicalized const instances of this class.
- RawType* declaration_type_; // Declaration type for this class.
- RawArray* invocation_dispatcher_cache_; // Cache for dispatcher functions.
- RawCode* allocation_stub_; // Stub code for allocation of instances.
- RawGrowableObjectArray* direct_implementors_; // Array of Class.
- RawGrowableObjectArray* direct_subclasses_; // Array of Class.
- RawArray* dependent_code_; // CHA optimized codes.
- VISIT_TO(RawObject*, dependent_code_);
- RawObject** to_snapshot(Snapshot::Kind kind) {
+ VISIT_FROM(ObjectPtr, name_);
+ StringPtr name_;
+ StringPtr user_name_;
+ ArrayPtr functions_;
+ ArrayPtr functions_hash_table_;
+ ArrayPtr fields_;
+ ArrayPtr offset_in_words_to_field_;
+ ArrayPtr interfaces_; // Array of AbstractType.
+ ScriptPtr script_;
+ LibraryPtr library_;
+ TypeArgumentsPtr type_parameters_; // Array of TypeParameter.
+ AbstractTypePtr super_type_;
+ FunctionPtr signature_function_; // Associated function for typedef class.
+ ArrayPtr constants_; // Canonicalized const instances of this class.
+ TypePtr declaration_type_; // Declaration type for this class.
+ ArrayPtr invocation_dispatcher_cache_; // Cache for dispatcher functions.
+ CodePtr allocation_stub_; // Stub code for allocation of instances.
+ GrowableObjectArrayPtr direct_implementors_; // Array of Class.
+ GrowableObjectArrayPtr direct_subclasses_; // Array of Class.
+ ArrayPtr dependent_code_; // CHA optimized codes.
+ VISIT_TO(ObjectPtr, dependent_code_);
+ ObjectPtr* to_snapshot(Snapshot::Kind kind) {
switch (kind) {
case Snapshot::kFullAOT:
- return reinterpret_cast<RawObject**>(&ptr()->allocation_stub_);
+ return reinterpret_cast<ObjectPtr*>(&ptr()->allocation_stub_);
case Snapshot::kFull:
- return reinterpret_cast<RawObject**>(&ptr()->direct_subclasses_);
+ return reinterpret_cast<ObjectPtr*>(&ptr()->direct_subclasses_);
case Snapshot::kFullJIT:
- return reinterpret_cast<RawObject**>(&ptr()->dependent_code_);
+ return reinterpret_cast<ObjectPtr*>(&ptr()->dependent_code_);
case Snapshot::kMessage:
case Snapshot::kNone:
case Snapshot::kInvalid:
@@ -876,32 +797,32 @@
friend class Instance;
friend class Isolate;
friend class Object;
- friend class RawInstance;
- friend class RawInstructions;
- friend class RawTypeArguments;
+ friend class InstanceLayout;
+ friend class InstructionsLayout;
+ friend class TypeArgumentsLayout;
friend class SnapshotReader;
friend class InstanceSerializationCluster;
friend class CidRewriteVisitor;
};
-class RawPatchClass : public RawObject {
+class PatchClassLayout : public ObjectLayout {
private:
RAW_HEAP_OBJECT_IMPLEMENTATION(PatchClass);
- VISIT_FROM(RawObject*, patched_class_);
- RawClass* patched_class_;
- RawClass* origin_class_;
- RawScript* script_;
- RawExternalTypedData* library_kernel_data_;
- VISIT_TO(RawObject*, library_kernel_data_);
+ VISIT_FROM(ObjectPtr, patched_class_);
+ ClassPtr patched_class_;
+ ClassPtr origin_class_;
+ ScriptPtr script_;
+ ExternalTypedDataPtr library_kernel_data_;
+ VISIT_TO(ObjectPtr, library_kernel_data_);
- RawObject** to_snapshot(Snapshot::Kind kind) {
+ ObjectPtr* to_snapshot(Snapshot::Kind kind) {
switch (kind) {
case Snapshot::kFullAOT:
- return reinterpret_cast<RawObject**>(&ptr()->script_);
+ return reinterpret_cast<ObjectPtr*>(&ptr()->script_);
case Snapshot::kFull:
case Snapshot::kFullJIT:
- return reinterpret_cast<RawObject**>(&ptr()->library_kernel_data_);
+ return reinterpret_cast<ObjectPtr*>(&ptr()->library_kernel_data_);
case Snapshot::kMessage:
case Snapshot::kNone:
case Snapshot::kInvalid:
@@ -916,7 +837,7 @@
friend class Function;
};
-class RawFunction : public RawObject {
+class FunctionLayout : public ObjectLayout {
public:
// When you add a new kind, please also update the observatory to account
// for the new string returned by KindToCString().
@@ -1067,22 +988,22 @@
uword entry_point_; // Accessed from generated code.
uword unchecked_entry_point_; // Accessed from generated code.
- VISIT_FROM(RawObject*, name_);
- RawString* name_;
- RawObject* owner_; // Class or patch class or mixin class
- // where this function is defined.
- RawAbstractType* result_type_;
- RawArray* parameter_types_;
- RawArray* parameter_names_;
- RawTypeArguments* type_parameters_; // Array of TypeParameter.
- RawObject* data_; // Additional data specific to the function kind. See
- // Function::set_data() for details.
- RawObject** to_snapshot(Snapshot::Kind kind) {
+ VISIT_FROM(ObjectPtr, name_);
+ StringPtr name_;
+ ObjectPtr owner_; // Class or patch class or mixin class
+ // where this function is defined.
+ AbstractTypePtr result_type_;
+ ArrayPtr parameter_types_;
+ ArrayPtr parameter_names_;
+ TypeArgumentsPtr type_parameters_; // Array of TypeParameter.
+ ObjectPtr data_; // Additional data specific to the function kind. See
+ // Function::set_data() for details.
+ ObjectPtr* to_snapshot(Snapshot::Kind kind) {
switch (kind) {
case Snapshot::kFullAOT:
case Snapshot::kFull:
case Snapshot::kFullJIT:
- return reinterpret_cast<RawObject**>(&ptr()->data_);
+ return reinterpret_cast<ObjectPtr*>(&ptr()->data_);
case Snapshot::kMessage:
case Snapshot::kNone:
case Snapshot::kInvalid:
@@ -1091,18 +1012,18 @@
UNREACHABLE();
return NULL;
}
- RawArray* ic_data_array_; // ICData of unoptimized code.
- RawObject** to_no_code() {
- return reinterpret_cast<RawObject**>(&ptr()->ic_data_array_);
+ ArrayPtr ic_data_array_; // ICData of unoptimized code.
+ ObjectPtr* to_no_code() {
+ return reinterpret_cast<ObjectPtr*>(&ptr()->ic_data_array_);
}
- RawCode* code_; // Currently active code. Accessed from generated code.
- NOT_IN_PRECOMPILED(RawBytecode* bytecode_);
- NOT_IN_PRECOMPILED(RawCode* unoptimized_code_); // Unoptimized code, keep it
- // after optimization.
+ CodePtr code_; // Currently active code. Accessed from generated code.
+ NOT_IN_PRECOMPILED(BytecodePtr bytecode_);
+ NOT_IN_PRECOMPILED(CodePtr unoptimized_code_); // Unoptimized code, keep it
+ // after optimization.
#if defined(DART_PRECOMPILED_RUNTIME)
- VISIT_TO(RawObject*, code_);
+ VISIT_TO(ObjectPtr, code_);
#else
- VISIT_TO(RawObject*, unoptimized_code_);
+ VISIT_TO(ObjectPtr, unoptimized_code_);
#endif
NOT_IN_PRECOMPILED(TokenPosition token_pos_);
@@ -1130,7 +1051,7 @@
PackedNumOptionalParameters;
static_assert(PackedNumOptionalParameters::kNextBit <=
kBitsPerWord * sizeof(decltype(packed_fields_)),
- "RawFunction::packed_fields_ bitfields don't align.");
+ "FunctionLayout::packed_fields_ bitfields don't align.");
#define JIT_FUNCTION_COUNTERS(F) \
F(intptr_t, int32_t, usage_counter) \
@@ -1154,61 +1075,61 @@
NOT_IN_PRECOMPILED(UnboxedParameterBitmap unboxed_parameters_info_);
};
-class RawClosureData : public RawObject {
+class ClosureDataLayout : public ObjectLayout {
private:
RAW_HEAP_OBJECT_IMPLEMENTATION(ClosureData);
- VISIT_FROM(RawObject*, context_scope_);
- RawContextScope* context_scope_;
- RawFunction* parent_function_; // Enclosing function of this local function.
- RawType* signature_type_;
- RawInstance* closure_; // Closure object for static implicit closures.
- VISIT_TO(RawObject*, closure_);
+ VISIT_FROM(ObjectPtr, context_scope_);
+ ContextScopePtr context_scope_;
+ FunctionPtr parent_function_; // Enclosing function of this local function.
+ TypePtr signature_type_;
+ InstancePtr closure_; // Closure object for static implicit closures.
+ VISIT_TO(ObjectPtr, closure_);
friend class Function;
};
-class RawSignatureData : public RawObject {
+class SignatureDataLayout : public ObjectLayout {
private:
RAW_HEAP_OBJECT_IMPLEMENTATION(SignatureData);
- VISIT_FROM(RawObject*, parent_function_);
- RawFunction* parent_function_; // Enclosing function of this sig. function.
- RawType* signature_type_;
- VISIT_TO(RawObject*, signature_type_);
- RawObject** to_snapshot(Snapshot::Kind kind) { return to(); }
+ VISIT_FROM(ObjectPtr, parent_function_);
+ FunctionPtr parent_function_; // Enclosing function of this sig. function.
+ TypePtr signature_type_;
+ VISIT_TO(ObjectPtr, signature_type_);
+ ObjectPtr* to_snapshot(Snapshot::Kind kind) { return to(); }
friend class Function;
};
-class RawRedirectionData : public RawObject {
+class RedirectionDataLayout : public ObjectLayout {
private:
RAW_HEAP_OBJECT_IMPLEMENTATION(RedirectionData);
- VISIT_FROM(RawObject*, type_);
- RawType* type_;
- RawString* identifier_;
- RawFunction* target_;
- VISIT_TO(RawObject*, target_);
- RawObject** to_snapshot(Snapshot::Kind kind) { return to(); }
+ VISIT_FROM(ObjectPtr, type_);
+ TypePtr type_;
+ StringPtr identifier_;
+ FunctionPtr target_;
+ VISIT_TO(ObjectPtr, target_);
+ ObjectPtr* to_snapshot(Snapshot::Kind kind) { return to(); }
};
-class RawFfiTrampolineData : public RawObject {
+class FfiTrampolineDataLayout : public ObjectLayout {
private:
RAW_HEAP_OBJECT_IMPLEMENTATION(FfiTrampolineData);
- VISIT_FROM(RawObject*, signature_type_);
- RawType* signature_type_;
- RawFunction* c_signature_;
+ VISIT_FROM(ObjectPtr, signature_type_);
+ TypePtr signature_type_;
+ FunctionPtr c_signature_;
// Target Dart method for callbacks, otherwise null.
- RawFunction* callback_target_;
+ FunctionPtr callback_target_;
// For callbacks, value to return if Dart target throws an exception.
- RawInstance* callback_exceptional_return_;
+ InstancePtr callback_exceptional_return_;
- VISIT_TO(RawObject*, callback_exceptional_return_);
- RawObject** to_snapshot(Snapshot::Kind kind) { return to(); }
+ VISIT_TO(ObjectPtr, callback_exceptional_return_);
+ ObjectPtr* to_snapshot(Snapshot::Kind kind) { return to(); }
// Callback id for callbacks.
//
@@ -1222,29 +1143,29 @@
uint32_t callback_id_;
};
-class RawField : public RawObject {
+class FieldLayout : public ObjectLayout {
RAW_HEAP_OBJECT_IMPLEMENTATION(Field);
- VISIT_FROM(RawObject*, name_);
- RawString* name_;
- RawObject* owner_; // Class or patch class or mixin class
- // where this field is defined or original field.
- RawAbstractType* type_;
- RawFunction* initializer_function_; // Static initializer function.
+ VISIT_FROM(ObjectPtr, name_);
+ StringPtr name_;
+ ObjectPtr owner_; // Class or patch class or mixin class
+ // where this field is defined or original field.
+ AbstractTypePtr type_;
+ FunctionPtr initializer_function_; // Static initializer function.
// When generating APPJIT snapshots after running the application it is
// necessary to save the initial value of static fields so that we can
// restore the value back to the original initial value.
- NOT_IN_PRECOMPILED(RawInstance* saved_initial_value_); // Saved initial value
- RawSmi* guarded_list_length_;
- RawArray* dependent_code_;
- RawObject** to_snapshot(Snapshot::Kind kind) {
+ NOT_IN_PRECOMPILED(InstancePtr saved_initial_value_); // Saved initial value
+ SmiPtr guarded_list_length_;
+ ArrayPtr dependent_code_;
+ ObjectPtr* to_snapshot(Snapshot::Kind kind) {
switch (kind) {
case Snapshot::kFull:
- return reinterpret_cast<RawObject**>(&ptr()->guarded_list_length_);
+ return reinterpret_cast<ObjectPtr*>(&ptr()->guarded_list_length_);
case Snapshot::kFullJIT:
- return reinterpret_cast<RawObject**>(&ptr()->dependent_code_);
+ return reinterpret_cast<ObjectPtr*>(&ptr()->dependent_code_);
case Snapshot::kFullAOT:
- return reinterpret_cast<RawObject**>(&ptr()->initializer_function_);
+ return reinterpret_cast<ObjectPtr*>(&ptr()->initializer_function_);
case Snapshot::kMessage:
case Snapshot::kNone:
case Snapshot::kInvalid:
@@ -1254,10 +1175,10 @@
return NULL;
}
#if defined(DART_PRECOMPILED_RUNTIME)
- VISIT_TO(RawObject*, dependent_code_);
+ VISIT_TO(ObjectPtr, dependent_code_);
#else
- RawSubtypeTestCache* type_test_cache_; // For type test in implicit setter.
- VISIT_TO(RawObject*, type_test_cache_);
+ SubtypeTestCachePtr type_test_cache_; // For type test in implicit setter.
+ VISIT_TO(ObjectPtr, type_test_cache_);
#endif
TokenPosition token_pos_;
TokenPosition end_token_pos_;
@@ -1295,7 +1216,7 @@
friend class CidRewriteVisitor;
};
-class RawScript : public RawObject {
+class ScriptLayout : public ObjectLayout {
public:
enum {
kLazyLookupSourceAndLineStartsPos = 0,
@@ -1305,22 +1226,22 @@
private:
RAW_HEAP_OBJECT_IMPLEMENTATION(Script);
- VISIT_FROM(RawObject*, url_);
- RawString* url_;
- RawString* resolved_url_;
- RawArray* compile_time_constants_;
- RawTypedData* line_starts_;
- RawArray* debug_positions_;
- RawKernelProgramInfo* kernel_program_info_;
- RawString* source_;
- VISIT_TO(RawObject*, source_);
- RawObject** to_snapshot(Snapshot::Kind kind) {
+ VISIT_FROM(ObjectPtr, url_);
+ StringPtr url_;
+ StringPtr resolved_url_;
+ ArrayPtr compile_time_constants_;
+ TypedDataPtr line_starts_;
+ ArrayPtr debug_positions_;
+ KernelProgramInfoPtr kernel_program_info_;
+ StringPtr source_;
+ VISIT_TO(ObjectPtr, source_);
+ ObjectPtr* to_snapshot(Snapshot::Kind kind) {
switch (kind) {
case Snapshot::kFullAOT:
- return reinterpret_cast<RawObject**>(&ptr()->url_);
+ return reinterpret_cast<ObjectPtr*>(&ptr()->url_);
case Snapshot::kFull:
case Snapshot::kFullJIT:
- return reinterpret_cast<RawObject**>(&ptr()->kernel_program_info_);
+ return reinterpret_cast<ObjectPtr*>(&ptr()->kernel_program_info_);
case Snapshot::kMessage:
case Snapshot::kNone:
case Snapshot::kInvalid:
@@ -1344,7 +1265,7 @@
int64_t load_timestamp_;
};
-class RawLibrary : public RawObject {
+class LibraryLayout : public ObjectLayout {
enum LibraryState {
kAllocated, // Initial state.
kLoadRequested, // Compiler or script requested load of library.
@@ -1374,24 +1295,24 @@
RAW_HEAP_OBJECT_IMPLEMENTATION(Library);
- VISIT_FROM(RawObject*, name_);
- RawString* name_;
- RawString* url_;
- RawString* private_key_;
- RawArray* dictionary_; // Top-level names in this library.
- RawGrowableObjectArray* metadata_; // Metadata on classes, methods etc.
- RawClass* toplevel_class_; // Class containing top-level elements.
- RawGrowableObjectArray* used_scripts_;
- RawArray* imports_; // List of Namespaces imported without prefix.
- RawArray* exports_; // List of re-exported Namespaces.
- RawExternalTypedData* kernel_data_;
- RawObject** to_snapshot(Snapshot::Kind kind) {
+ VISIT_FROM(ObjectPtr, name_);
+ StringPtr name_;
+ StringPtr url_;
+ StringPtr private_key_;
+ ArrayPtr dictionary_; // Top-level names in this library.
+ GrowableObjectArrayPtr metadata_; // Metadata on classes, methods etc.
+ ClassPtr toplevel_class_; // Class containing top-level elements.
+ GrowableObjectArrayPtr used_scripts_;
+ ArrayPtr imports_; // List of Namespaces imported without prefix.
+ ArrayPtr exports_; // List of re-exported Namespaces.
+ ExternalTypedDataPtr kernel_data_;
+ ObjectPtr* to_snapshot(Snapshot::Kind kind) {
switch (kind) {
case Snapshot::kFullAOT:
- return reinterpret_cast<RawObject**>(&ptr()->exports_);
+ return reinterpret_cast<ObjectPtr*>(&ptr()->exports_);
case Snapshot::kFull:
case Snapshot::kFullJIT:
- return reinterpret_cast<RawObject**>(&ptr()->kernel_data_);
+ return reinterpret_cast<ObjectPtr*>(&ptr()->kernel_data_);
case Snapshot::kMessage:
case Snapshot::kNone:
case Snapshot::kInvalid:
@@ -1400,10 +1321,10 @@
UNREACHABLE();
return NULL;
}
- RawArray* resolved_names_; // Cache of resolved names in library scope.
- RawArray* exported_names_; // Cache of exported names by library.
- RawArray* loaded_scripts_; // Array of scripts loaded in this library.
- VISIT_TO(RawObject*, loaded_scripts_);
+ ArrayPtr resolved_names_; // Cache of resolved names in library scope.
+ ArrayPtr exported_names_; // Cache of exported names by library.
+ ArrayPtr loaded_scripts_; // Array of scripts loaded in this library.
+ VISIT_TO(ObjectPtr, loaded_scripts_);
Dart_NativeEntryResolver native_entry_resolver_; // Resolves natives.
Dart_NativeEntrySymbol native_entry_symbol_resolver_;
@@ -1422,60 +1343,60 @@
friend class Isolate;
};
-class RawNamespace : public RawObject {
+class NamespaceLayout : public ObjectLayout {
RAW_HEAP_OBJECT_IMPLEMENTATION(Namespace);
- VISIT_FROM(RawObject*, library_);
- RawLibrary* library_; // library with name dictionary.
- RawArray* show_names_; // list of names that are exported.
- RawArray* hide_names_; // blacklist of names that are not exported.
- RawField* metadata_field_; // remembers the token pos of metadata if any,
- // and the metadata values if computed.
- VISIT_TO(RawObject*, metadata_field_);
- RawObject** to_snapshot(Snapshot::Kind kind) { return to(); }
+ VISIT_FROM(ObjectPtr, library_);
+ LibraryPtr library_; // library with name dictionary.
+ ArrayPtr show_names_; // list of names that are exported.
+ ArrayPtr hide_names_; // blacklist of names that are not exported.
+ FieldPtr metadata_field_; // remembers the token pos of metadata if any,
+ // and the metadata values if computed.
+ VISIT_TO(ObjectPtr, metadata_field_);
+ ObjectPtr* to_snapshot(Snapshot::Kind kind) { return to(); }
};
-class RawKernelProgramInfo : public RawObject {
+class KernelProgramInfoLayout : public ObjectLayout {
RAW_HEAP_OBJECT_IMPLEMENTATION(KernelProgramInfo);
- VISIT_FROM(RawObject*, string_offsets_);
- RawTypedData* string_offsets_;
- RawExternalTypedData* string_data_;
- RawTypedData* canonical_names_;
- RawExternalTypedData* metadata_payloads_;
- RawExternalTypedData* metadata_mappings_;
- RawArray* scripts_;
- RawArray* constants_;
- RawArray* bytecode_component_;
- RawGrowableObjectArray* potential_natives_;
- RawGrowableObjectArray* potential_pragma_functions_;
- RawExternalTypedData* constants_table_;
- RawArray* libraries_cache_;
- RawArray* classes_cache_;
- RawObject* retained_kernel_blob_;
- VISIT_TO(RawObject*, retained_kernel_blob_);
+ VISIT_FROM(ObjectPtr, string_offsets_);
+ TypedDataPtr string_offsets_;
+ ExternalTypedDataPtr string_data_;
+ TypedDataPtr canonical_names_;
+ ExternalTypedDataPtr metadata_payloads_;
+ ExternalTypedDataPtr metadata_mappings_;
+ ArrayPtr scripts_;
+ ArrayPtr constants_;
+ ArrayPtr bytecode_component_;
+ GrowableObjectArrayPtr potential_natives_;
+ GrowableObjectArrayPtr potential_pragma_functions_;
+ ExternalTypedDataPtr constants_table_;
+ ArrayPtr libraries_cache_;
+ ArrayPtr classes_cache_;
+ ObjectPtr retained_kernel_blob_;
+ VISIT_TO(ObjectPtr, retained_kernel_blob_);
uint32_t kernel_binary_version_;
- RawObject** to_snapshot(Snapshot::Kind kind) {
- return reinterpret_cast<RawObject**>(&ptr()->constants_table_);
+ ObjectPtr* to_snapshot(Snapshot::Kind kind) {
+ return reinterpret_cast<ObjectPtr*>(&ptr()->constants_table_);
}
};
-class RawWeakSerializationReference : public RawObject {
+class WeakSerializationReferenceLayout : public ObjectLayout {
RAW_HEAP_OBJECT_IMPLEMENTATION(WeakSerializationReference);
#if defined(DART_PRECOMPILED_RUNTIME)
VISIT_NOTHING();
classid_t cid_;
#else
- VISIT_FROM(RawObject*, target_);
- RawObject* target_;
- VISIT_TO(RawObject*, target_);
+ VISIT_FROM(ObjectPtr, target_);
+ ObjectPtr target_;
+ VISIT_TO(ObjectPtr, target_);
#endif
};
-class RawCode : public RawObject {
+class CodeLayout : public ObjectLayout {
RAW_HEAP_OBJECT_IMPLEMENTATION(Code);
// When in the precompiled runtime, there is no disabling of Code objects
@@ -1524,39 +1445,39 @@
uword unchecked_entry_point_; // Accessed from generated code.
uword monomorphic_unchecked_entry_point_; // Accessed from generated code.
- VISIT_FROM(RawObject*, object_pool_);
- RawObjectPool* object_pool_; // Accessed from generated code.
- RawInstructions* instructions_; // Accessed from generated code.
+ VISIT_FROM(ObjectPtr, object_pool_);
+ ObjectPoolPtr object_pool_; // Accessed from generated code.
+ InstructionsPtr instructions_; // Accessed from generated code.
// If owner_ is Function::null() the owner is a regular stub.
// If owner_ is a Class the owner is the allocation stub for that class.
// Else, owner_ is a regular Dart Function.
- RawObject* owner_; // Function, Null, or a Class.
- RawExceptionHandlers* exception_handlers_;
- RawPcDescriptors* pc_descriptors_;
+ ObjectPtr owner_; // Function, Null, or a Class.
+ ExceptionHandlersPtr exception_handlers_;
+ PcDescriptorsPtr pc_descriptors_;
// If FLAG_precompiled_mode, then this field contains
- // RawTypedData* catch_entry_moves_maps
+ // TypedDataPtr catch_entry_moves_maps
// Otherwise, it is
- // RawSmi* num_variables
- RawObject* catch_entry_;
- RawCompressedStackMaps* compressed_stackmaps_;
- RawArray* inlined_id_to_function_;
- RawCodeSourceMap* code_source_map_;
- NOT_IN_PRECOMPILED(RawInstructions* active_instructions_);
- NOT_IN_PRECOMPILED(RawArray* deopt_info_array_);
+ // SmiPtr num_variables
+ ObjectPtr catch_entry_;
+ CompressedStackMapsPtr compressed_stackmaps_;
+ ArrayPtr inlined_id_to_function_;
+ CodeSourceMapPtr code_source_map_;
+ NOT_IN_PRECOMPILED(InstructionsPtr active_instructions_);
+ NOT_IN_PRECOMPILED(ArrayPtr deopt_info_array_);
// (code-offset, function, code) triples.
- NOT_IN_PRECOMPILED(RawArray* static_calls_target_table_);
+ NOT_IN_PRECOMPILED(ArrayPtr static_calls_target_table_);
// If return_address_metadata_ is a Smi, it is the offset to the prologue.
// Else, return_address_metadata_ is null.
- NOT_IN_PRODUCT(RawObject* return_address_metadata_);
- NOT_IN_PRODUCT(RawLocalVarDescriptors* var_descriptors_);
- NOT_IN_PRODUCT(RawArray* comments_);
+ NOT_IN_PRODUCT(ObjectPtr return_address_metadata_);
+ NOT_IN_PRODUCT(LocalVarDescriptorsPtr var_descriptors_);
+ NOT_IN_PRODUCT(ArrayPtr comments_);
#if !defined(PRODUCT)
- VISIT_TO(RawObject*, comments_);
+ VISIT_TO(ObjectPtr, comments_);
#elif defined(DART_PRECOMPILED_RUNTIME)
- VISIT_TO(RawObject*, code_source_map_);
+ VISIT_TO(ObjectPtr, code_source_map_);
#else
- VISIT_TO(RawObject*, static_calls_target_table_);
+ VISIT_TO(ObjectPtr, static_calls_target_table_);
#endif
// Compilation timestamp.
@@ -1577,7 +1498,7 @@
int32_t* data() { OPEN_ARRAY_START(int32_t, int32_t); }
const int32_t* data() const { OPEN_ARRAY_START(int32_t, int32_t); }
- static bool ContainsPC(const RawObject* raw_obj, uword pc);
+ static bool ContainsPC(const ObjectPtr raw_obj, uword pc);
friend class Function;
template <bool>
@@ -1588,47 +1509,47 @@
friend class CallSiteResetter;
};
-class RawBytecode : public RawObject {
+class BytecodeLayout : public ObjectLayout {
RAW_HEAP_OBJECT_IMPLEMENTATION(Bytecode);
uword instructions_;
intptr_t instructions_size_;
- VISIT_FROM(RawObject*, object_pool_);
- RawObjectPool* object_pool_;
- RawFunction* function_;
- RawArray* closures_;
- RawExceptionHandlers* exception_handlers_;
- RawPcDescriptors* pc_descriptors_;
- NOT_IN_PRODUCT(RawLocalVarDescriptors* var_descriptors_);
+ VISIT_FROM(ObjectPtr, object_pool_);
+ ObjectPoolPtr object_pool_;
+ FunctionPtr function_;
+ ArrayPtr closures_;
+ ExceptionHandlersPtr exception_handlers_;
+ PcDescriptorsPtr pc_descriptors_;
+ NOT_IN_PRODUCT(LocalVarDescriptorsPtr var_descriptors_);
#if defined(PRODUCT)
- VISIT_TO(RawObject*, pc_descriptors_);
+ VISIT_TO(ObjectPtr, pc_descriptors_);
#else
- VISIT_TO(RawObject*, var_descriptors_);
+ VISIT_TO(ObjectPtr, var_descriptors_);
#endif
- RawObject** to_snapshot(Snapshot::Kind kind) {
- return reinterpret_cast<RawObject**>(&ptr()->pc_descriptors_);
+ ObjectPtr* to_snapshot(Snapshot::Kind kind) {
+ return reinterpret_cast<ObjectPtr*>(&ptr()->pc_descriptors_);
}
int32_t instructions_binary_offset_;
int32_t source_positions_binary_offset_;
int32_t local_variables_binary_offset_;
- static bool ContainsPC(RawObject* raw_obj, uword pc);
+ static bool ContainsPC(ObjectPtr raw_obj, uword pc);
friend class Function;
friend class StackFrame;
};
-class RawObjectPool : public RawObject {
+class ObjectPoolLayout : public ObjectLayout {
RAW_HEAP_OBJECT_IMPLEMENTATION(ObjectPool);
intptr_t length_;
struct Entry {
union {
- RawObject* raw_obj_;
+ ObjectPtr raw_obj_;
uword raw_value_;
};
};
@@ -1646,7 +1567,7 @@
friend class CodeSerializationCluster;
};
-class RawInstructions : public RawObject {
+class InstructionsLayout : public ObjectLayout {
RAW_HEAP_OBJECT_IMPLEMENTATION(Instructions);
VISIT_NOTHING();
@@ -1660,10 +1581,10 @@
// Private helper function used while visiting stack frames. The
// code which iterates over dart frames is also called during GC and
// is not allowed to create handles.
- static bool ContainsPC(const RawInstructions* raw_instr, uword pc);
+ static bool ContainsPC(const InstructionsPtr raw_instr, uword pc);
- friend class RawCode;
- friend class RawFunction;
+ friend class CodeLayout;
+ friend class FunctionLayout;
friend class Code;
friend class StackFrame;
template <bool>
@@ -1677,7 +1598,7 @@
// Used only to provide memory accounting for the bare instruction payloads
// we serialize, since they are no longer part of RawInstructions objects.
-class RawInstructionsSection : public RawObject {
+class InstructionsSectionLayout : public ObjectLayout {
RAW_HEAP_OBJECT_IMPLEMENTATION(InstructionsSection);
VISIT_NOTHING();
@@ -1688,7 +1609,7 @@
uint8_t* data() { OPEN_ARRAY_START(uint8_t, uint8_t); }
};
-class RawPcDescriptors : public RawObject {
+class PcDescriptorsLayout : public ObjectLayout {
public:
// The macro argument V is passed two arguments, the raw name of the enum value
// and the initialization expression used within the enum definition. The uses
@@ -1795,7 +1716,7 @@
// CodeSourceMap encodes a mapping from code PC ranges to source token
// positions and the stack of inlined functions.
-class RawCodeSourceMap : public RawObject {
+class CodeSourceMapLayout : public ObjectLayout {
private:
RAW_HEAP_OBJECT_IMPLEMENTATION(CodeSourceMap);
VISIT_NOTHING();
@@ -1815,7 +1736,7 @@
// RawCompressedStackMaps is a compressed representation of the stack maps
// for certain PC offsets into a set of instructions, where a stack map is a bit
// map that marks each live object index starting from the base of the frame.
-class RawCompressedStackMaps : public RawObject {
+class CompressedStackMapsLayout : public ObjectLayout {
RAW_HEAP_OBJECT_IMPLEMENTATION(CompressedStackMaps);
VISIT_NOTHING();
@@ -1886,7 +1807,7 @@
friend class ImageWriter;
};
-class RawLocalVarDescriptors : public RawObject {
+class LocalVarDescriptorsLayout : public ObjectLayout {
public:
enum VarInfoKind {
kStackVar = 1,
@@ -1937,13 +1858,13 @@
// platforms.
uword num_entries_;
- VISIT_FROM(RawObject*, names()[0]);
- RawString** names() {
+ VISIT_FROM(ObjectPtr, names()[0]);
+ StringPtr* names() {
// Array of [num_entries_] variable names.
- OPEN_ARRAY_START(RawString*, RawString*);
+ OPEN_ARRAY_START(StringPtr, StringPtr);
}
- RawString** nameAddrAt(intptr_t i) { return &(ptr()->names()[i]); }
- VISIT_TO_LENGTH(RawObject*, nameAddrAt(length - 1));
+ StringPtr* nameAddrAt(intptr_t i) { return &(ptr()->names()[i]); }
+ VISIT_TO_LENGTH(ObjectPtr, nameAddrAt(length - 1));
// Variable info with [num_entries_] entries.
VarInfo* data() {
@@ -1953,7 +1874,7 @@
friend class Object;
};
-class RawExceptionHandlers : public RawObject {
+class ExceptionHandlersLayout : public ObjectLayout {
private:
RAW_HEAP_OBJECT_IMPLEMENTATION(ExceptionHandlers);
@@ -1962,9 +1883,9 @@
// Array with [num_entries_] entries. Each entry is an array of all handled
// exception types.
- VISIT_FROM(RawObject*, handled_types_data_)
- RawArray* handled_types_data_;
- VISIT_TO_LENGTH(RawObject*, &ptr()->handled_types_data_);
+ VISIT_FROM(ObjectPtr, handled_types_data_)
+ ArrayPtr handled_types_data_;
+ VISIT_TO_LENGTH(ObjectPtr, &ptr()->handled_types_data_);
// Exception handler info of length [num_entries_].
const ExceptionHandlerInfo* data() const {
@@ -1977,138 +1898,138 @@
friend class Object;
};
-class RawContext : public RawObject {
+class ContextLayout : public ObjectLayout {
RAW_HEAP_OBJECT_IMPLEMENTATION(Context);
int32_t num_variables_;
- VISIT_FROM(RawObject*, parent_);
- RawContext* parent_;
+ VISIT_FROM(ObjectPtr, parent_);
+ ContextPtr parent_;
// Variable length data follows here.
- RawObject** data() { OPEN_ARRAY_START(RawObject*, RawObject*); }
- RawObject* const* data() const { OPEN_ARRAY_START(RawObject*, RawObject*); }
- VISIT_TO_LENGTH(RawObject*, &ptr()->data()[length - 1]);
+ ObjectPtr* data() { OPEN_ARRAY_START(ObjectPtr, ObjectPtr); }
+ ObjectPtr const* data() const { OPEN_ARRAY_START(ObjectPtr, ObjectPtr); }
+ VISIT_TO_LENGTH(ObjectPtr, &ptr()->data()[length - 1]);
friend class Object;
friend class SnapshotReader;
};
-class RawContextScope : public RawObject {
+class ContextScopeLayout : public ObjectLayout {
RAW_HEAP_OBJECT_IMPLEMENTATION(ContextScope);
// TODO(iposva): Switch to conventional enum offset based structure to avoid
// alignment mishaps.
struct VariableDesc {
- RawSmi* declaration_token_pos;
- RawSmi* token_pos;
- RawString* name;
- RawSmi* flags;
+ SmiPtr declaration_token_pos;
+ SmiPtr token_pos;
+ StringPtr name;
+ SmiPtr flags;
static constexpr intptr_t kIsFinal = 0x1;
static constexpr intptr_t kIsConst = 0x2;
static constexpr intptr_t kIsLate = 0x4;
- RawSmi* late_init_offset;
+ SmiPtr late_init_offset;
union {
- RawAbstractType* type;
- RawInstance* value; // iff is_const is true
+ AbstractTypePtr type;
+ InstancePtr value; // iff is_const is true
};
- RawSmi* context_index;
- RawSmi* context_level;
+ SmiPtr context_index;
+ SmiPtr context_level;
};
int32_t num_variables_;
bool is_implicit_; // true, if this context scope is for an implicit closure.
- RawObject** from() {
+ ObjectPtr* from() {
VariableDesc* begin = const_cast<VariableDesc*>(ptr()->VariableDescAddr(0));
- return reinterpret_cast<RawObject**>(begin);
+ return reinterpret_cast<ObjectPtr*>(begin);
}
// Variable length data follows here.
- RawObject* const* data() const { OPEN_ARRAY_START(RawObject*, RawObject*); }
+ ObjectPtr const* data() const { OPEN_ARRAY_START(ObjectPtr, ObjectPtr); }
const VariableDesc* VariableDescAddr(intptr_t index) const {
ASSERT((index >= 0) && (index < num_variables_ + 1));
// data() points to the first component of the first descriptor.
return &(reinterpret_cast<const VariableDesc*>(data())[index]);
}
- RawObject** to(intptr_t num_vars) {
+ ObjectPtr* to(intptr_t num_vars) {
uword end = reinterpret_cast<uword>(ptr()->VariableDescAddr(num_vars));
// 'end' is the address just beyond the last descriptor, so step back.
- return reinterpret_cast<RawObject**>(end - kWordSize);
+ return reinterpret_cast<ObjectPtr*>(end - kWordSize);
}
- RawObject** to_snapshot(Snapshot::Kind kind, intptr_t num_vars) {
+ ObjectPtr* to_snapshot(Snapshot::Kind kind, intptr_t num_vars) {
return to(num_vars);
}
friend class Object;
- friend class RawClosureData;
+ friend class ClosureDataLayout;
friend class SnapshotReader;
};
-class RawParameterTypeCheck : public RawObject {
+class ParameterTypeCheckLayout : public ObjectLayout {
RAW_HEAP_OBJECT_IMPLEMENTATION(ParameterTypeCheck);
intptr_t index_;
- VISIT_FROM(RawObject*, param_);
- RawAbstractType* param_;
- RawAbstractType* type_or_bound_;
- RawString* name_;
- RawSubtypeTestCache* cache_;
- VISIT_TO(RawObject*, cache_);
- RawObject** to_snapshot(Snapshot::Kind kind) { return to(); }
+ VISIT_FROM(ObjectPtr, param_);
+ AbstractTypePtr param_;
+ AbstractTypePtr type_or_bound_;
+ StringPtr name_;
+ SubtypeTestCachePtr cache_;
+ VISIT_TO(ObjectPtr, cache_);
+ ObjectPtr* to_snapshot(Snapshot::Kind kind) { return to(); }
};
-class RawSingleTargetCache : public RawObject {
+class SingleTargetCacheLayout : public ObjectLayout {
RAW_HEAP_OBJECT_IMPLEMENTATION(SingleTargetCache);
- VISIT_FROM(RawObject*, target_);
- RawCode* target_;
- VISIT_TO(RawObject*, target_);
+ VISIT_FROM(ObjectPtr, target_);
+ CodePtr target_;
+ VISIT_TO(ObjectPtr, target_);
uword entry_point_;
classid_t lower_limit_;
classid_t upper_limit_;
};
-class RawUnlinkedCall : public RawObject {
+class UnlinkedCallLayout : public ObjectLayout {
RAW_HEAP_OBJECT_IMPLEMENTATION(UnlinkedCall);
- VISIT_FROM(RawObject*, target_name_);
- RawString* target_name_;
- RawArray* args_descriptor_;
- VISIT_TO(RawObject*, args_descriptor_);
+ VISIT_FROM(ObjectPtr, target_name_);
+ StringPtr target_name_;
+ ArrayPtr args_descriptor_;
+ VISIT_TO(ObjectPtr, args_descriptor_);
bool can_patch_to_monomorphic_;
- RawObject** to_snapshot(Snapshot::Kind kind) { return to(); }
+ ObjectPtr* to_snapshot(Snapshot::Kind kind) { return to(); }
};
-class RawMonomorphicSmiableCall : public RawObject {
+class MonomorphicSmiableCallLayout : public ObjectLayout {
RAW_HEAP_OBJECT_IMPLEMENTATION(MonomorphicSmiableCall);
- VISIT_FROM(RawObject*, target_);
- RawCode* target_; // Entrypoint PC in bare mode, Code in non-bare mode.
- VISIT_TO(RawObject*, target_);
+ VISIT_FROM(ObjectPtr, target_);
+ CodePtr target_; // Entrypoint PC in bare mode, Code in non-bare mode.
+ VISIT_TO(ObjectPtr, target_);
uword expected_cid_;
uword entrypoint_;
- RawObject** to_snapshot(Snapshot::Kind kind) { return to(); }
+ ObjectPtr* to_snapshot(Snapshot::Kind kind) { return to(); }
};
// Abstract base class for RawICData/RawMegamorphicCache
-class RawCallSiteData : public RawObject {
+class CallSiteDataLayout : public ObjectLayout {
protected:
- RawString* target_name_; // Name of target function.
+ StringPtr target_name_; // Name of target function.
// arg_descriptor in RawICData and in RawMegamorphicCache should be
// in the same position so that NoSuchMethod can access it.
- RawArray* args_descriptor_; // Arguments descriptor.
+ ArrayPtr args_descriptor_; // Arguments descriptor.
private:
RAW_HEAP_OBJECT_IMPLEMENTATION(CallSiteData)
};
-class RawICData : public RawCallSiteData {
+class ICDataLayout : public CallSiteDataLayout {
RAW_HEAP_OBJECT_IMPLEMENTATION(ICData);
- VISIT_FROM(RawObject*, target_name_);
- RawArray* entries_; // Contains class-ids, target and count.
+ VISIT_FROM(ObjectPtr, target_name_);
+ ArrayPtr entries_; // Contains class-ids, target and count.
// Static type of the receiver, if instance call and available.
- NOT_IN_PRECOMPILED(RawAbstractType* receivers_static_type_);
- RawObject* owner_; // Parent/calling function or original IC of cloned IC.
- VISIT_TO(RawObject*, owner_);
- RawObject** to_snapshot(Snapshot::Kind kind) {
+ NOT_IN_PRECOMPILED(AbstractTypePtr receivers_static_type_);
+ ObjectPtr owner_; // Parent/calling function or original IC of cloned IC.
+ VISIT_TO(ObjectPtr, owner_);
+ ObjectPtr* to_snapshot(Snapshot::Kind kind) {
switch (kind) {
case Snapshot::kFullAOT:
- return reinterpret_cast<RawObject**>(&ptr()->entries_);
+ return reinterpret_cast<ObjectPtr*>(&ptr()->entries_);
case Snapshot::kFull:
case Snapshot::kFullJIT:
return to();
@@ -2124,90 +2045,90 @@
uint32_t state_bits_; // Number of arguments tested in IC, deopt reasons.
};
-class RawMegamorphicCache : public RawCallSiteData {
+class MegamorphicCacheLayout : public CallSiteDataLayout {
RAW_HEAP_OBJECT_IMPLEMENTATION(MegamorphicCache);
- VISIT_FROM(RawObject*, target_name_)
- RawArray* buckets_;
- RawSmi* mask_;
- VISIT_TO(RawObject*, mask_)
- RawObject** to_snapshot(Snapshot::Kind kind) { return to(); }
+ VISIT_FROM(ObjectPtr, target_name_)
+ ArrayPtr buckets_;
+ SmiPtr mask_;
+ VISIT_TO(ObjectPtr, mask_)
+ ObjectPtr* to_snapshot(Snapshot::Kind kind) { return to(); }
int32_t filled_entry_count_;
};
-class RawSubtypeTestCache : public RawObject {
+class SubtypeTestCacheLayout : public ObjectLayout {
RAW_HEAP_OBJECT_IMPLEMENTATION(SubtypeTestCache);
- VISIT_FROM(RawObject*, cache_);
- RawArray* cache_;
- VISIT_TO(RawObject*, cache_);
+ VISIT_FROM(ObjectPtr, cache_);
+ ArrayPtr cache_;
+ VISIT_TO(ObjectPtr, cache_);
};
-class RawError : public RawObject {
+class ErrorLayout : public ObjectLayout {
RAW_HEAP_OBJECT_IMPLEMENTATION(Error);
};
-class RawApiError : public RawError {
+class ApiErrorLayout : public ErrorLayout {
RAW_HEAP_OBJECT_IMPLEMENTATION(ApiError);
- VISIT_FROM(RawObject*, message_)
- RawString* message_;
- VISIT_TO(RawObject*, message_)
+ VISIT_FROM(ObjectPtr, message_)
+ StringPtr message_;
+ VISIT_TO(ObjectPtr, message_)
};
-class RawLanguageError : public RawError {
+class LanguageErrorLayout : public ErrorLayout {
RAW_HEAP_OBJECT_IMPLEMENTATION(LanguageError);
- VISIT_FROM(RawObject*, previous_error_)
- RawError* previous_error_; // May be null.
- RawScript* script_;
- RawString* message_;
- RawString* formatted_message_; // Incl. previous error's formatted message.
- VISIT_TO(RawObject*, formatted_message_)
+ VISIT_FROM(ObjectPtr, previous_error_)
+ ErrorPtr previous_error_; // May be null.
+ ScriptPtr script_;
+ StringPtr message_;
+ StringPtr formatted_message_; // Incl. previous error's formatted message.
+ VISIT_TO(ObjectPtr, formatted_message_)
TokenPosition token_pos_; // Source position in script_.
bool report_after_token_; // Report message at or after the token.
int8_t kind_; // Of type Report::Kind.
- RawObject** to_snapshot(Snapshot::Kind kind) { return to(); }
+ ObjectPtr* to_snapshot(Snapshot::Kind kind) { return to(); }
};
-class RawUnhandledException : public RawError {
+class UnhandledExceptionLayout : public ErrorLayout {
RAW_HEAP_OBJECT_IMPLEMENTATION(UnhandledException);
- VISIT_FROM(RawObject*, exception_)
- RawInstance* exception_;
- RawInstance* stacktrace_;
- VISIT_TO(RawObject*, stacktrace_)
- RawObject** to_snapshot(Snapshot::Kind kind) { return to(); }
+ VISIT_FROM(ObjectPtr, exception_)
+ InstancePtr exception_;
+ InstancePtr stacktrace_;
+ VISIT_TO(ObjectPtr, stacktrace_)
+ ObjectPtr* to_snapshot(Snapshot::Kind kind) { return to(); }
};
-class RawUnwindError : public RawError {
+class UnwindErrorLayout : public ErrorLayout {
RAW_HEAP_OBJECT_IMPLEMENTATION(UnwindError);
- VISIT_FROM(RawObject*, message_)
- RawString* message_;
- VISIT_TO(RawObject*, message_)
+ VISIT_FROM(ObjectPtr, message_)
+ StringPtr message_;
+ VISIT_TO(ObjectPtr, message_)
bool is_user_initiated_;
};
-class RawInstance : public RawObject {
+class InstanceLayout : public ObjectLayout {
RAW_HEAP_OBJECT_IMPLEMENTATION(Instance);
};
-class RawLibraryPrefix : public RawInstance {
+class LibraryPrefixLayout : public InstanceLayout {
RAW_HEAP_OBJECT_IMPLEMENTATION(LibraryPrefix);
- VISIT_FROM(RawObject*, name_)
- RawString* name_; // Library prefix name.
- RawLibrary* importer_; // Library which declares this prefix.
- RawArray* imports_; // Libraries imported with this prefix.
- VISIT_TO(RawObject*, imports_)
- RawObject** to_snapshot(Snapshot::Kind kind) {
+ VISIT_FROM(ObjectPtr, name_)
+ StringPtr name_; // Library prefix name.
+ LibraryPtr importer_; // Library which declares this prefix.
+ ArrayPtr imports_; // Libraries imported with this prefix.
+ VISIT_TO(ObjectPtr, imports_)
+ ObjectPtr* to_snapshot(Snapshot::Kind kind) {
switch (kind) {
case Snapshot::kFull:
case Snapshot::kFullJIT:
- return reinterpret_cast<RawObject**>(&ptr()->imports_);
+ return reinterpret_cast<ObjectPtr*>(&ptr()->imports_);
case Snapshot::kFullAOT:
- return reinterpret_cast<RawObject**>(&ptr()->importer_);
+ return reinterpret_cast<ObjectPtr*>(&ptr()->importer_);
case Snapshot::kMessage:
case Snapshot::kNone:
case Snapshot::kInvalid:
@@ -2220,33 +2141,33 @@
bool is_deferred_load_;
};
-class RawTypeArguments : public RawInstance {
+class TypeArgumentsLayout : public InstanceLayout {
private:
RAW_HEAP_OBJECT_IMPLEMENTATION(TypeArguments);
- VISIT_FROM(RawObject*, instantiations_)
+ VISIT_FROM(ObjectPtr, instantiations_)
// The instantiations_ array remains empty for instantiated type arguments.
- RawArray* instantiations_; // Of 3-tuple: 2 instantiators, result.
- RawSmi* length_;
- RawSmi* hash_;
- RawSmi* nullability_;
+ ArrayPtr instantiations_; // Of 3-tuple: 2 instantiators, result.
+ SmiPtr length_;
+ SmiPtr hash_;
+ SmiPtr nullability_;
// Variable length data follows here.
- RawAbstractType* const* types() const {
- OPEN_ARRAY_START(RawAbstractType*, RawAbstractType*);
+ AbstractTypePtr const* types() const {
+ OPEN_ARRAY_START(AbstractTypePtr, AbstractTypePtr);
}
- RawAbstractType** types() {
- OPEN_ARRAY_START(RawAbstractType*, RawAbstractType*);
+ AbstractTypePtr* types() {
+ OPEN_ARRAY_START(AbstractTypePtr, AbstractTypePtr);
}
- RawObject** to(intptr_t length) {
- return reinterpret_cast<RawObject**>(&ptr()->types()[length - 1]);
+ ObjectPtr* to(intptr_t length) {
+ return reinterpret_cast<ObjectPtr*>(&ptr()->types()[length - 1]);
}
friend class Object;
friend class SnapshotReader;
};
-class RawAbstractType : public RawInstance {
+class AbstractTypeLayout : public InstanceLayout {
public:
enum TypeState {
kAllocated, // Initial state.
@@ -2257,8 +2178,8 @@
protected:
uword type_test_stub_entry_point_; // Accessed from generated code.
- RawCode* type_test_stub_; // Must be the last field, since subclasses use it
- // in their VISIT_FROM.
+ CodePtr type_test_stub_; // Must be the last field, since subclasses use it
+ // in their VISIT_FROM.
private:
RAW_HEAP_OBJECT_IMPLEMENTATION(AbstractType);
@@ -2267,39 +2188,39 @@
friend class StubCode;
};
-class RawType : public RawAbstractType {
+class TypeLayout : public AbstractTypeLayout {
private:
RAW_HEAP_OBJECT_IMPLEMENTATION(Type);
- VISIT_FROM(RawObject*, type_test_stub_)
- RawSmi* type_class_id_;
- RawTypeArguments* arguments_;
- RawSmi* hash_;
+ VISIT_FROM(ObjectPtr, type_test_stub_)
+ SmiPtr type_class_id_;
+ TypeArgumentsPtr arguments_;
+ SmiPtr hash_;
// This type object represents a function type if its signature field is a
// non-null function object.
- RawFunction* signature_; // If not null, this type is a function type.
- VISIT_TO(RawObject*, signature_)
+ FunctionPtr signature_; // If not null, this type is a function type.
+ VISIT_TO(ObjectPtr, signature_)
TokenPosition token_pos_;
int8_t type_state_;
int8_t nullability_;
- RawObject** to_snapshot(Snapshot::Kind kind) { return to(); }
+ ObjectPtr* to_snapshot(Snapshot::Kind kind) { return to(); }
friend class CidRewriteVisitor;
- friend class RawTypeArguments;
+ friend class TypeArgumentsLayout;
};
-class RawTypeRef : public RawAbstractType {
+class TypeRefLayout : public AbstractTypeLayout {
private:
RAW_HEAP_OBJECT_IMPLEMENTATION(TypeRef);
- VISIT_FROM(RawObject*, type_test_stub_)
- RawAbstractType* type_; // The referenced type.
- VISIT_TO(RawObject*, type_)
- RawObject** to_snapshot(Snapshot::Kind kind) { return to(); }
+ VISIT_FROM(ObjectPtr, type_test_stub_)
+ AbstractTypePtr type_; // The referenced type.
+ VISIT_TO(ObjectPtr, type_)
+ ObjectPtr* to_snapshot(Snapshot::Kind kind) { return to(); }
};
-class RawTypeParameter : public RawAbstractType {
+class TypeParameterLayout : public AbstractTypeLayout {
public:
enum {
kFinalizedBit = 0,
@@ -2312,24 +2233,24 @@
private:
RAW_HEAP_OBJECT_IMPLEMENTATION(TypeParameter);
- VISIT_FROM(RawObject*, type_test_stub_)
- RawString* name_;
- RawSmi* hash_;
- RawAbstractType* bound_; // ObjectType if no explicit bound specified.
- RawFunction* parameterized_function_;
- VISIT_TO(RawObject*, parameterized_function_)
+ VISIT_FROM(ObjectPtr, type_test_stub_)
+ StringPtr name_;
+ SmiPtr hash_;
+ AbstractTypePtr bound_; // ObjectType if no explicit bound specified.
+ FunctionPtr parameterized_function_;
+ VISIT_TO(ObjectPtr, parameterized_function_)
classid_t parameterized_class_id_;
TokenPosition token_pos_;
int16_t index_;
uint8_t flags_;
int8_t nullability_;
- RawObject** to_snapshot(Snapshot::Kind kind) { return to(); }
+ ObjectPtr* to_snapshot(Snapshot::Kind kind) { return to(); }
friend class CidRewriteVisitor;
};
-class RawClosure : public RawInstance {
+class ClosureLayout : public InstanceLayout {
private:
RAW_HEAP_OBJECT_IMPLEMENTATION(Closure);
@@ -2339,16 +2260,16 @@
// The following fields are also declared in the Dart source of class
// _Closure.
VISIT_FROM(RawCompressed, instantiator_type_arguments_)
- RawTypeArguments* instantiator_type_arguments_;
- RawTypeArguments* function_type_arguments_;
- RawTypeArguments* delayed_type_arguments_;
- RawFunction* function_;
- RawContext* context_;
- RawSmi* hash_;
+ TypeArgumentsPtr instantiator_type_arguments_;
+ TypeArgumentsPtr function_type_arguments_;
+ TypeArgumentsPtr delayed_type_arguments_;
+ FunctionPtr function_;
+ ContextPtr context_;
+ SmiPtr hash_;
VISIT_TO(RawCompressed, hash_)
- RawObject** to_snapshot(Snapshot::Kind kind) { return to(); }
+ ObjectPtr* to_snapshot(Snapshot::Kind kind) { return to(); }
// Note that instantiator_type_arguments_, function_type_arguments_ and
// delayed_type_arguments_ are used to instantiate the signature of function_
@@ -2374,19 +2295,19 @@
// any type arguments passed directly (or NSM will be invoked instead).
};
-class RawNumber : public RawInstance {
+class NumberLayout : public InstanceLayout {
RAW_OBJECT_IMPLEMENTATION(Number);
};
-class RawInteger : public RawNumber {
+class IntegerLayout : public NumberLayout {
RAW_OBJECT_IMPLEMENTATION(Integer);
};
-class RawSmi : public RawInteger {
+class SmiLayout : public IntegerLayout {
RAW_OBJECT_IMPLEMENTATION(Smi);
};
-class RawMint : public RawInteger {
+class MintLayout : public IntegerLayout {
RAW_HEAP_OBJECT_IMPLEMENTATION(Mint);
VISIT_NOTHING();
@@ -2397,9 +2318,9 @@
friend class Integer;
friend class SnapshotReader;
};
-COMPILE_ASSERT(sizeof(RawMint) == 16);
+COMPILE_ASSERT(sizeof(MintLayout) == 16);
-class RawDouble : public RawNumber {
+class DoubleLayout : public NumberLayout {
RAW_HEAP_OBJECT_IMPLEMENTATION(Double);
VISIT_NOTHING();
@@ -2409,19 +2330,19 @@
friend class SnapshotReader;
friend class Class;
};
-COMPILE_ASSERT(sizeof(RawDouble) == 16);
+COMPILE_ASSERT(sizeof(DoubleLayout) == 16);
-class RawString : public RawInstance {
+class StringLayout : public InstanceLayout {
RAW_HEAP_OBJECT_IMPLEMENTATION(String);
protected:
- VISIT_FROM(RawObject*, length_)
- RawSmi* length_;
+ VISIT_FROM(ObjectPtr, length_)
+ SmiPtr length_;
#if !defined(HASH_IN_OBJECT_HEADER)
- RawSmi* hash_;
- VISIT_TO(RawObject*, hash_)
+ SmiPtr hash_;
+ VISIT_TO(ObjectPtr, hash_)
#else
- VISIT_TO(RawObject*, length_)
+ VISIT_TO(ObjectPtr, length_)
#endif
private:
@@ -2434,7 +2355,7 @@
friend class ImageWriter;
};
-class RawOneByteString : public RawString {
+class OneByteStringLayout : public StringLayout {
RAW_HEAP_OBJECT_IMPLEMENTATION(OneByteString);
VISIT_NOTHING();
@@ -2448,7 +2369,7 @@
friend class String;
};
-class RawTwoByteString : public RawString {
+class TwoByteStringLayout : public StringLayout {
RAW_HEAP_OBJECT_IMPLEMENTATION(TwoByteString);
VISIT_NOTHING();
@@ -2466,7 +2387,7 @@
//
// TypedData extends this with a length field, while Pointer extends this with
// TypeArguments field.
-class RawPointerBase : public RawInstance {
+class PointerBaseLayout : public InstanceLayout {
protected:
// The contents of [data_] depends on what concrete subclass is used:
//
@@ -2486,23 +2407,23 @@
};
// Abstract base class for RawTypedData/RawExternalTypedData/RawTypedDataView.
-class RawTypedDataBase : public RawPointerBase {
+class TypedDataBaseLayout : public PointerBaseLayout {
protected:
// The length of the view in element sizes (obtainable via
// [TypedDataBase::ElementSizeInBytes]).
- RawSmi* length_;
+ SmiPtr length_;
private:
- friend class RawTypedDataView;
+ friend class TypedDataViewLayout;
RAW_HEAP_OBJECT_IMPLEMENTATION(TypedDataBase);
};
-class RawTypedData : public RawTypedDataBase {
+class TypedDataLayout : public TypedDataBaseLayout {
RAW_HEAP_OBJECT_IMPLEMENTATION(TypedData);
public:
static intptr_t payload_offset() {
- return OFFSET_OF_RETURNED_VALUE(RawTypedData, internal_data);
+ return OFFSET_OF_RETURNED_VALUE(TypedDataLayout, internal_data);
}
// Recompute [data_] pointer to internal data.
@@ -2533,18 +2454,18 @@
friend class ObjectPool;
friend class ObjectPoolDeserializationCluster;
friend class ObjectPoolSerializationCluster;
- friend class RawObjectPool;
+ friend class ObjectPoolLayout;
friend class SnapshotReader;
};
// All _*ArrayView/_ByteDataView classes share the same layout.
-class RawTypedDataView : public RawTypedDataBase {
+class TypedDataViewLayout : public TypedDataBaseLayout {
RAW_HEAP_OBJECT_IMPLEMENTATION(TypedDataView);
public:
// Recompute [data_] based on internal/external [typed_data_].
void RecomputeDataField() {
- const intptr_t offset_in_bytes = ValueFromRawSmi(ptr()->offset_in_bytes_);
+ const intptr_t offset_in_bytes = RawSmiValue(ptr()->offset_in_bytes_);
uint8_t* payload = ptr()->typed_data_->ptr()->data_;
ptr()->data_ = payload + offset_in_bytes;
}
@@ -2556,22 +2477,23 @@
// [typed_data_] pointer points to the new backing store. The backing store's
// fields don't need to be valid - only it's address.
void RecomputeDataFieldForInternalTypedData() {
- const intptr_t offset_in_bytes = ValueFromRawSmi(ptr()->offset_in_bytes_);
- uint8_t* payload = reinterpret_cast<uint8_t*>(
- RawObject::ToAddr(ptr()->typed_data_) + RawTypedData::payload_offset());
+ const intptr_t offset_in_bytes = RawSmiValue(ptr()->offset_in_bytes_);
+ uint8_t* payload =
+ reinterpret_cast<uint8_t*>(ObjectLayout::ToAddr(ptr()->typed_data_) +
+ TypedDataLayout::payload_offset());
ptr()->data_ = payload + offset_in_bytes;
}
void ValidateInnerPointer() {
- if (ptr()->typed_data_->GetClassId() == kNullCid) {
+ if (ptr()->typed_data_->ptr()->GetClassId() == kNullCid) {
// The view object must have gotten just initialized.
if (ptr()->data_ != nullptr ||
- ValueFromRawSmi(ptr()->offset_in_bytes_) != 0 ||
- ValueFromRawSmi(ptr()->length_) != 0) {
+ RawSmiValue(ptr()->offset_in_bytes_) != 0 ||
+ RawSmiValue(ptr()->length_) != 0) {
FATAL("RawTypedDataView has invalid inner pointer.");
}
} else {
- const intptr_t offset_in_bytes = ValueFromRawSmi(ptr()->offset_in_bytes_);
+ const intptr_t offset_in_bytes = RawSmiValue(ptr()->offset_in_bytes_);
uint8_t* payload = ptr()->typed_data_->ptr()->data_;
if ((payload + offset_in_bytes) != ptr()->data_) {
FATAL("RawTypedDataView has invalid inner pointer.");
@@ -2580,24 +2502,24 @@
}
protected:
- VISIT_FROM(RawObject*, length_)
- RawTypedDataBase* typed_data_;
- RawSmi* offset_in_bytes_;
- VISIT_TO(RawObject*, offset_in_bytes_)
- RawObject** to_snapshot(Snapshot::Kind kind) { return to(); }
+ VISIT_FROM(ObjectPtr, length_)
+ TypedDataBasePtr typed_data_;
+ SmiPtr offset_in_bytes_;
+ VISIT_TO(ObjectPtr, offset_in_bytes_)
+ ObjectPtr* to_snapshot(Snapshot::Kind kind) { return to(); }
friend class Api;
friend class Object;
friend class ObjectPoolDeserializationCluster;
friend class ObjectPoolSerializationCluster;
- friend class RawObjectPool;
+ friend class ObjectPoolLayout;
friend class GCCompactor;
template <bool>
friend class ScavengerVisitorBase;
friend class SnapshotReader;
};
-class RawExternalOneByteString : public RawString {
+class ExternalOneByteStringLayout : public StringLayout {
RAW_HEAP_OBJECT_IMPLEMENTATION(ExternalOneByteString);
const uint8_t* external_data_;
@@ -2606,7 +2528,7 @@
friend class String;
};
-class RawExternalTwoByteString : public RawString {
+class ExternalTwoByteStringLayout : public StringLayout {
RAW_HEAP_OBJECT_IMPLEMENTATION(ExternalTwoByteString);
const uint16_t* external_data_;
@@ -2615,7 +2537,7 @@
friend class String;
};
-class RawBool : public RawInstance {
+class BoolLayout : public InstanceLayout {
RAW_HEAP_OBJECT_IMPLEMENTATION(Bool);
VISIT_NOTHING();
@@ -2624,15 +2546,15 @@
friend class Object;
};
-class RawArray : public RawInstance {
+class ArrayLayout : public InstanceLayout {
RAW_HEAP_OBJECT_IMPLEMENTATION(Array);
VISIT_FROM(RawCompressed, type_arguments_)
- RawTypeArguments* type_arguments_;
- RawSmi* length_;
+ TypeArgumentsPtr type_arguments_;
+ SmiPtr length_;
// Variable length data follows here.
- RawObject** data() { OPEN_ARRAY_START(RawObject*, RawObject*); }
- RawObject* const* data() const { OPEN_ARRAY_START(RawObject*, RawObject*); }
+ ObjectPtr* data() { OPEN_ARRAY_START(ObjectPtr, ObjectPtr); }
+ ObjectPtr const* data() const { OPEN_ARRAY_START(ObjectPtr, ObjectPtr); }
VISIT_TO_LENGTH(RawCompressed, &ptr()->data()[length - 1])
friend class LinkedHashMapSerializationCluster;
@@ -2640,12 +2562,12 @@
friend class CodeSerializationCluster;
friend class CodeDeserializationCluster;
friend class Deserializer;
- friend class RawCode;
- friend class RawImmutableArray;
+ friend class CodeLayout;
+ friend class ImmutableArrayLayout;
friend class SnapshotReader;
friend class GrowableObjectArray;
friend class LinkedHashMap;
- friend class RawLinkedHashMap;
+ friend class LinkedHashMapLayout;
friend class Object;
friend class ICData; // For high performance access.
friend class SubtypeTestCache; // For high performance access.
@@ -2653,41 +2575,41 @@
friend class HeapPage;
};
-class RawImmutableArray : public RawArray {
+class ImmutableArrayLayout : public ArrayLayout {
RAW_HEAP_OBJECT_IMPLEMENTATION(ImmutableArray);
friend class SnapshotReader;
};
-class RawGrowableObjectArray : public RawInstance {
+class GrowableObjectArrayLayout : public InstanceLayout {
RAW_HEAP_OBJECT_IMPLEMENTATION(GrowableObjectArray);
VISIT_FROM(RawCompressed, type_arguments_)
- RawTypeArguments* type_arguments_;
- RawSmi* length_;
- RawArray* data_;
+ TypeArgumentsPtr type_arguments_;
+ SmiPtr length_;
+ ArrayPtr data_;
VISIT_TO(RawCompressed, data_)
- RawObject** to_snapshot(Snapshot::Kind kind) { return to(); }
+ ObjectPtr* to_snapshot(Snapshot::Kind kind) { return to(); }
friend class SnapshotReader;
};
-class RawLinkedHashMap : public RawInstance {
+class LinkedHashMapLayout : public InstanceLayout {
RAW_HEAP_OBJECT_IMPLEMENTATION(LinkedHashMap);
VISIT_FROM(RawCompressed, type_arguments_)
- RawTypeArguments* type_arguments_;
- RawTypedData* index_;
- RawSmi* hash_mask_;
- RawArray* data_;
- RawSmi* used_data_;
- RawSmi* deleted_keys_;
+ TypeArgumentsPtr type_arguments_;
+ TypedDataPtr index_;
+ SmiPtr hash_mask_;
+ ArrayPtr data_;
+ SmiPtr used_data_;
+ SmiPtr deleted_keys_;
VISIT_TO(RawCompressed, deleted_keys_)
friend class SnapshotReader;
};
-class RawFloat32x4 : public RawInstance {
+class Float32x4Layout : public InstanceLayout {
RAW_HEAP_OBJECT_IMPLEMENTATION(Float32x4);
VISIT_NOTHING();
@@ -2702,9 +2624,9 @@
float z() const { return value_[2]; }
float w() const { return value_[3]; }
};
-COMPILE_ASSERT(sizeof(RawFloat32x4) == 24);
+COMPILE_ASSERT(sizeof(Float32x4Layout) == 24);
-class RawInt32x4 : public RawInstance {
+class Int32x4Layout : public InstanceLayout {
RAW_HEAP_OBJECT_IMPLEMENTATION(Int32x4);
VISIT_NOTHING();
@@ -2718,9 +2640,9 @@
int32_t z() const { return value_[2]; }
int32_t w() const { return value_[3]; }
};
-COMPILE_ASSERT(sizeof(RawInt32x4) == 24);
+COMPILE_ASSERT(sizeof(Int32x4Layout) == 24);
-class RawFloat64x2 : public RawInstance {
+class Float64x2Layout : public InstanceLayout {
RAW_HEAP_OBJECT_IMPLEMENTATION(Float64x2);
VISIT_NOTHING();
@@ -2733,7 +2655,7 @@
double x() const { return value_[0]; }
double y() const { return value_[1]; }
};
-COMPILE_ASSERT(sizeof(RawFloat64x2) == 24);
+COMPILE_ASSERT(sizeof(Float64x2Layout) == 24);
// Define an aliases for intptr_t.
#if defined(ARCH_IS_32_BIT)
@@ -2746,27 +2668,27 @@
#error Architecture is not 32-bit or 64-bit.
#endif // ARCH_IS_32_BIT
-class RawExternalTypedData : public RawTypedDataBase {
+class ExternalTypedDataLayout : public TypedDataBaseLayout {
RAW_HEAP_OBJECT_IMPLEMENTATION(ExternalTypedData);
protected:
VISIT_FROM(RawCompressed, length_)
VISIT_TO(RawCompressed, length_)
- friend class RawBytecode;
+ friend class BytecodeLayout;
};
-class RawPointer : public RawPointerBase {
+class PointerLayout : public PointerBaseLayout {
RAW_HEAP_OBJECT_IMPLEMENTATION(Pointer);
VISIT_FROM(RawCompressed, type_arguments_)
- RawTypeArguments* type_arguments_;
+ TypeArgumentsPtr type_arguments_;
VISIT_TO(RawCompressed, type_arguments_)
friend class Pointer;
};
-class RawDynamicLibrary : public RawInstance {
+class DynamicLibraryLayout : public InstanceLayout {
RAW_HEAP_OBJECT_IMPLEMENTATION(DynamicLibrary);
VISIT_NOTHING();
void* handle_;
@@ -2775,13 +2697,13 @@
};
// VM implementations of the basic types in the isolate.
-class alignas(8) RawCapability : public RawInstance {
+class alignas(8) CapabilityLayout : public InstanceLayout {
RAW_HEAP_OBJECT_IMPLEMENTATION(Capability);
VISIT_NOTHING();
uint64_t id_;
};
-class alignas(8) RawSendPort : public RawInstance {
+class alignas(8) SendPortLayout : public InstanceLayout {
RAW_HEAP_OBJECT_IMPLEMENTATION(SendPort);
VISIT_NOTHING();
Dart_Port id_;
@@ -2790,16 +2712,16 @@
friend class ReceivePort;
};
-class RawReceivePort : public RawInstance {
+class ReceivePortLayout : public InstanceLayout {
RAW_HEAP_OBJECT_IMPLEMENTATION(ReceivePort);
- VISIT_FROM(RawObject*, send_port_)
- RawSendPort* send_port_;
- RawInstance* handler_;
- VISIT_TO(RawObject*, handler_)
+ VISIT_FROM(ObjectPtr, send_port_)
+ SendPortPtr send_port_;
+ InstancePtr handler_;
+ VISIT_TO(ObjectPtr, handler_)
};
-class RawTransferableTypedData : public RawInstance {
+class TransferableTypedDataLayout : public InstanceLayout {
RAW_HEAP_OBJECT_IMPLEMENTATION(TransferableTypedData);
VISIT_NOTHING();
};
@@ -2808,15 +2730,15 @@
// Currently we don't have any interface that this object is supposed
// to implement so we just support the 'toString' method which
// converts the stack trace into a string.
-class RawStackTrace : public RawInstance {
+class StackTraceLayout : public InstanceLayout {
RAW_HEAP_OBJECT_IMPLEMENTATION(StackTrace);
- VISIT_FROM(RawObject*, async_link_)
- RawStackTrace* async_link_; // Link to parent async stack trace.
- RawArray* code_array_; // Code object for each frame in the stack trace.
- RawArray* pc_offset_array_; // Offset of PC for each frame.
- VISIT_TO(RawObject*, pc_offset_array_)
- RawObject** to_snapshot(Snapshot::Kind kind) { return to(); }
+ VISIT_FROM(ObjectPtr, async_link_)
+ StackTracePtr async_link_; // Link to parent async stack trace.
+ ArrayPtr code_array_; // Code object for each frame in the stack trace.
+ ArrayPtr pc_offset_array_; // Offset of PC for each frame.
+ VISIT_TO(ObjectPtr, pc_offset_array_)
+ ObjectPtr* to_snapshot(Snapshot::Kind kind) { return to(); }
// False for pre-allocated stack trace (used in OOM and Stack overflow).
bool expand_inlined_;
@@ -2827,35 +2749,35 @@
};
// VM type for capturing JS regular expressions.
-class RawRegExp : public RawInstance {
+class RegExpLayout : public InstanceLayout {
RAW_HEAP_OBJECT_IMPLEMENTATION(RegExp);
- VISIT_FROM(RawObject*, num_bracket_expressions_)
- RawSmi* num_bracket_expressions_;
- RawArray* capture_name_map_;
- RawString* pattern_; // Pattern to be used for matching.
+ VISIT_FROM(ObjectPtr, num_bracket_expressions_)
+ SmiPtr num_bracket_expressions_;
+ ArrayPtr capture_name_map_;
+ StringPtr pattern_; // Pattern to be used for matching.
union {
- RawFunction* function_;
- RawTypedData* bytecode_;
+ FunctionPtr function_;
+ TypedDataPtr bytecode_;
} one_byte_;
union {
- RawFunction* function_;
- RawTypedData* bytecode_;
+ FunctionPtr function_;
+ TypedDataPtr bytecode_;
} two_byte_;
- RawFunction* external_one_byte_function_;
- RawFunction* external_two_byte_function_;
+ FunctionPtr external_one_byte_function_;
+ FunctionPtr external_two_byte_function_;
union {
- RawFunction* function_;
- RawTypedData* bytecode_;
+ FunctionPtr function_;
+ TypedDataPtr bytecode_;
} one_byte_sticky_;
union {
- RawFunction* function_;
- RawTypedData* bytecode_;
+ FunctionPtr function_;
+ TypedDataPtr bytecode_;
} two_byte_sticky_;
- RawFunction* external_one_byte_sticky_function_;
- RawFunction* external_two_byte_sticky_function_;
- VISIT_TO(RawObject*, external_two_byte_sticky_function_)
- RawObject** to_snapshot(Snapshot::Kind kind) { return to(); }
+ FunctionPtr external_one_byte_sticky_function_;
+ FunctionPtr external_two_byte_sticky_function_;
+ VISIT_TO(ObjectPtr, external_two_byte_sticky_function_)
+ ObjectPtr* to_snapshot(Snapshot::Kind kind) { return to(); }
// The same pattern may use different amount of registers if compiled
// for a one-byte target than a two-byte target. For example, we do not
@@ -2871,14 +2793,14 @@
int8_t type_flags_;
};
-class RawWeakProperty : public RawInstance {
+class WeakPropertyLayout : public InstanceLayout {
RAW_HEAP_OBJECT_IMPLEMENTATION(WeakProperty);
- VISIT_FROM(RawObject*, key_)
- RawObject* key_;
- RawObject* value_;
- VISIT_TO(RawObject*, value_)
- RawObject** to_snapshot(Snapshot::Kind kind) { return to(); }
+ VISIT_FROM(ObjectPtr, key_)
+ ObjectPtr key_;
+ ObjectPtr value_;
+ VISIT_TO(ObjectPtr, value_)
+ ObjectPtr* to_snapshot(Snapshot::Kind kind) { return to(); }
// Linked list is chaining all pending weak properties.
// Untyped to make it clear that it is not to be visited by GC.
@@ -2894,21 +2816,21 @@
// MirrorReferences are used by mirrors to hold reflectees that are VM
// internal objects, such as libraries, classes, functions or types.
-class RawMirrorReference : public RawInstance {
+class MirrorReferenceLayout : public InstanceLayout {
RAW_HEAP_OBJECT_IMPLEMENTATION(MirrorReference);
- VISIT_FROM(RawObject*, referent_)
- RawObject* referent_;
- VISIT_TO(RawObject*, referent_)
+ VISIT_FROM(ObjectPtr, referent_)
+ ObjectPtr referent_;
+ VISIT_TO(ObjectPtr, referent_)
};
// UserTag are used by the profiler to track Dart script state.
-class RawUserTag : public RawInstance {
+class UserTagLayout : public InstanceLayout {
RAW_HEAP_OBJECT_IMPLEMENTATION(UserTag);
- VISIT_FROM(RawObject*, label_)
- RawString* label_;
- VISIT_TO(RawObject*, label_)
+ VISIT_FROM(ObjectPtr, label_)
+ StringPtr label_;
+ VISIT_TO(ObjectPtr, label_)
// Isolate unique tag.
uword tag_;
@@ -2920,11 +2842,11 @@
uword tag() const { return tag_; }
};
-class RawFutureOr : public RawInstance {
+class FutureOrLayout : public InstanceLayout {
RAW_HEAP_OBJECT_IMPLEMENTATION(FutureOr);
VISIT_FROM(RawCompressed, type_arguments_)
- RawTypeArguments* type_arguments_;
+ TypeArgumentsPtr type_arguments_;
VISIT_TO(RawCompressed, type_arguments_)
friend class SnapshotReader;
diff --git a/runtime/vm/raw_object_fields.cc b/runtime/vm/raw_object_fields.cc
index 88c11a5..c594b92 100644
--- a/runtime/vm/raw_object_fields.cc
+++ b/runtime/vm/raw_object_fields.cc
@@ -230,7 +230,8 @@
}
#define DEFINE_OFFSETS_TABLE_ENTRY(class_name, field_name) \
- {class_name::kClassId, #field_name, OFFSET_OF(Raw##class_name, field_name)},
+ {class_name::kClassId, #field_name, \
+ OFFSET_OF(class_name##Layout, field_name)},
// clang-format off
OffsetsTable::OffsetsTableEntry OffsetsTable::offsets_table[] = {
diff --git a/runtime/vm/raw_object_snapshot.cc b/runtime/vm/raw_object_snapshot.cc
index 4fce40c..487ae69 100644
--- a/runtime/vm/raw_object_snapshot.cc
+++ b/runtime/vm/raw_object_snapshot.cc
@@ -24,7 +24,7 @@
" port after it exceeds certain size in bytes.");
#define OFFSET_OF_FROM(obj) \
- obj.raw()->from() - reinterpret_cast<RawObject**>(obj.raw()->ptr())
+ obj.raw()->from() - reinterpret_cast<ObjectPtr*>(obj.raw()->ptr())
// TODO(18854): Need to assert No GC can happen here, even though
// allocations may happen.
@@ -35,11 +35,11 @@
object.StorePointer(((from) + i), reader->PassiveObjectHandle()->raw()); \
}
-RawClass* Class::ReadFrom(SnapshotReader* reader,
- intptr_t object_id,
- intptr_t tags,
- Snapshot::Kind kind,
- bool as_reference) {
+ClassPtr Class::ReadFrom(SnapshotReader* reader,
+ intptr_t object_id,
+ intptr_t tags,
+ Snapshot::Kind kind,
+ bool as_reference) {
ASSERT(reader != NULL);
Class& cls = Class::ZoneHandle(reader->zone(), Class::null());
@@ -47,10 +47,10 @@
return cls.raw();
}
-void RawClass::WriteTo(SnapshotWriter* writer,
- intptr_t object_id,
- Snapshot::Kind kind,
- bool as_reference) {
+void ClassLayout::WriteTo(SnapshotWriter* writer,
+ intptr_t object_id,
+ Snapshot::Kind kind,
+ bool as_reference) {
ASSERT(writer != NULL);
// Write out the serialization header value for this object.
@@ -71,11 +71,11 @@
}
}
-RawType* Type::ReadFrom(SnapshotReader* reader,
- intptr_t object_id,
- intptr_t tags,
- Snapshot::Kind kind,
- bool as_reference) {
+TypePtr Type::ReadFrom(SnapshotReader* reader,
+ intptr_t object_id,
+ intptr_t tags,
+ Snapshot::Kind kind,
+ bool as_reference) {
ASSERT(reader != NULL);
// Determine if the type class of this type is in the full snapshot.
@@ -83,7 +83,7 @@
// Allocate type object.
Type& type = Type::ZoneHandle(reader->zone(), Type::New());
- bool is_canonical = RawObject::IsCanonical(tags);
+ bool is_canonical = ObjectLayout::IsCanonical(tags);
reader->AddBackRef(object_id, &type, kIsDeserialized);
// Set all non object fields.
@@ -96,7 +96,8 @@
reader->EnqueueTypePostprocessing(type);
// Set all the object fields.
- READ_OBJECT_FIELDS(type, type.raw()->from(), type.raw()->to(), as_reference);
+ READ_OBJECT_FIELDS(type, type.raw()->ptr()->from(), type.raw()->ptr()->to(),
+ as_reference);
// Read in the type class.
(*reader->ClassHandle()) =
@@ -115,10 +116,10 @@
return type.raw();
}
-void RawType::WriteTo(SnapshotWriter* writer,
- intptr_t object_id,
- Snapshot::Kind kind,
- bool as_reference) {
+void TypeLayout::WriteTo(SnapshotWriter* writer,
+ intptr_t object_id,
+ Snapshot::Kind kind,
+ bool as_reference) {
ASSERT(writer != NULL);
if (ptr()->signature_ != Function::null()) {
@@ -129,8 +130,8 @@
}
// Only resolved and finalized types should be written to a snapshot.
- ASSERT((ptr()->type_state_ == RawType::kFinalizedInstantiated) ||
- (ptr()->type_state_ == RawType::kFinalizedUninstantiated));
+ ASSERT((ptr()->type_state_ == TypeLayout::kFinalizedInstantiated) ||
+ (ptr()->type_state_ == TypeLayout::kFinalizedUninstantiated));
ASSERT(ptr()->type_class_id_ != Object::null());
// Write out the serialization header value for this object.
@@ -146,8 +147,8 @@
}
// Lookup the type class.
- RawSmi* raw_type_class_id = Smi::RawCast(ptr()->type_class_id_);
- RawClass* type_class =
+ SmiPtr raw_type_class_id = Smi::RawCast(ptr()->type_class_id_);
+ ClassPtr type_class =
writer->isolate()->class_table()->At(Smi::Value(raw_type_class_id));
// Write out typeclass_is_in_fullsnapshot first as this will
@@ -155,7 +156,7 @@
intptr_t tags = writer->GetObjectTags(type_class);
bool typeclass_is_in_fullsnapshot =
(ClassIdTag::decode(tags) == kClassCid) &&
- Class::IsInFullSnapshot(reinterpret_cast<RawClass*>(type_class));
+ Class::IsInFullSnapshot(static_cast<ClassPtr>(type_class));
writer->Write<bool>(typeclass_is_in_fullsnapshot);
// Write out all the non object pointer fields.
@@ -174,11 +175,11 @@
writer->WriteObjectImpl(type_class, as_reference);
}
-RawTypeRef* TypeRef::ReadFrom(SnapshotReader* reader,
- intptr_t object_id,
- intptr_t tags,
- Snapshot::Kind kind,
- bool as_reference) {
+TypeRefPtr TypeRef::ReadFrom(SnapshotReader* reader,
+ intptr_t object_id,
+ intptr_t tags,
+ Snapshot::Kind kind,
+ bool as_reference) {
ASSERT(reader != NULL);
// Allocate type ref object.
@@ -189,8 +190,8 @@
reader->EnqueueTypePostprocessing(type_ref);
// Set all the object fields.
- READ_OBJECT_FIELDS(type_ref, type_ref.raw()->from(), type_ref.raw()->to(),
- kAsReference);
+ READ_OBJECT_FIELDS(type_ref, type_ref.raw()->ptr()->from(),
+ type_ref.raw()->ptr()->to(), kAsReference);
// Fill in the type testing stub.
Code& code = *reader->CodeHandle();
@@ -200,10 +201,10 @@
return type_ref.raw();
}
-void RawTypeRef::WriteTo(SnapshotWriter* writer,
- intptr_t object_id,
- Snapshot::Kind kind,
- bool as_reference) {
+void TypeRefLayout::WriteTo(SnapshotWriter* writer,
+ intptr_t object_id,
+ Snapshot::Kind kind,
+ bool as_reference) {
ASSERT(writer != NULL);
// Write out the serialization header value for this object.
@@ -218,11 +219,11 @@
visitor.VisitPointers(from(), to());
}
-RawTypeParameter* TypeParameter::ReadFrom(SnapshotReader* reader,
- intptr_t object_id,
- intptr_t tags,
- Snapshot::Kind kind,
- bool as_reference) {
+TypeParameterPtr TypeParameter::ReadFrom(SnapshotReader* reader,
+ intptr_t object_id,
+ intptr_t tags,
+ Snapshot::Kind kind,
+ bool as_reference) {
ASSERT(reader != NULL);
// Allocate type parameter object.
@@ -242,8 +243,8 @@
reader->EnqueueTypePostprocessing(type_parameter);
// Set all the object fields.
- READ_OBJECT_FIELDS(type_parameter, type_parameter.raw()->from(),
- type_parameter.raw()->to(), kAsReference);
+ READ_OBJECT_FIELDS(type_parameter, type_parameter.raw()->ptr()->from(),
+ type_parameter.raw()->ptr()->to(), kAsReference);
// Read in the parameterized class.
(*reader->ClassHandle()) =
@@ -258,10 +259,10 @@
return type_parameter.raw();
}
-void RawTypeParameter::WriteTo(SnapshotWriter* writer,
- intptr_t object_id,
- Snapshot::Kind kind,
- bool as_reference) {
+void TypeParameterLayout::WriteTo(SnapshotWriter* writer,
+ intptr_t object_id,
+ Snapshot::Kind kind,
+ bool as_reference) {
ASSERT(writer != NULL);
// Only finalized type parameters should be written to a snapshot.
@@ -287,16 +288,16 @@
visitor.VisitPointers(from(), to());
// Write out the parameterized class.
- RawClass* param_class =
+ ClassPtr param_class =
writer->isolate()->class_table()->At(ptr()->parameterized_class_id_);
writer->WriteObjectImpl(param_class, kAsReference);
}
-RawTypeArguments* TypeArguments::ReadFrom(SnapshotReader* reader,
- intptr_t object_id,
- intptr_t tags,
- Snapshot::Kind kind,
- bool as_reference) {
+TypeArgumentsPtr TypeArguments::ReadFrom(SnapshotReader* reader,
+ intptr_t object_id,
+ intptr_t tags,
+ Snapshot::Kind kind,
+ bool as_reference) {
ASSERT(reader != NULL);
// Read the length so that we can determine instance size to allocate.
@@ -304,7 +305,7 @@
TypeArguments& type_arguments =
TypeArguments::ZoneHandle(reader->zone(), TypeArguments::New(len));
- bool is_canonical = RawObject::IsCanonical(tags);
+ bool is_canonical = ObjectLayout::IsCanonical(tags);
reader->AddBackRef(object_id, &type_arguments, kIsDeserialized);
// Set the instantiations field, which is only read from a full snapshot.
@@ -324,10 +325,10 @@
return type_arguments.raw();
}
-void RawTypeArguments::WriteTo(SnapshotWriter* writer,
- intptr_t object_id,
- Snapshot::Kind kind,
- bool as_reference) {
+void TypeArgumentsLayout::WriteTo(SnapshotWriter* writer,
+ intptr_t object_id,
+ Snapshot::Kind kind,
+ bool as_reference) {
ASSERT(writer != NULL);
// Write out the serialization header value for this object.
@@ -338,7 +339,7 @@
writer->WriteTags(writer->GetObjectTags(this));
// Write out the length field.
- writer->Write<RawObject*>(ptr()->length_);
+ writer->Write<ObjectPtr>(ptr()->length_);
// Write out the individual types.
intptr_t len = Smi::Value(ptr()->length_);
@@ -350,9 +351,9 @@
// across (isolates spawned using spawnURI) we send them as dynamic.
if (!writer->can_send_any_object()) {
// Lookup the type class.
- RawType* raw_type = Type::RawCast(ptr()->types()[i]);
- RawSmi* raw_type_class_id = Smi::RawCast(raw_type->ptr()->type_class_id_);
- RawClass* type_class =
+ TypePtr raw_type = Type::RawCast(ptr()->types()[i]);
+ SmiPtr raw_type_class_id = Smi::RawCast(raw_type->ptr()->type_class_id_);
+ ClassPtr type_class =
writer->isolate()->class_table()->At(Smi::Value(raw_type_class_id));
if (!writer->AllowObjectsInDartLibrary(type_class->ptr()->library_)) {
writer->WriteVMIsolateObject(kDynamicType);
@@ -365,24 +366,24 @@
}
}
-RawClosure* Closure::ReadFrom(SnapshotReader* reader,
- intptr_t object_id,
- intptr_t tags,
- Snapshot::Kind kind,
- bool as_reference) {
+ClosurePtr Closure::ReadFrom(SnapshotReader* reader,
+ intptr_t object_id,
+ intptr_t tags,
+ Snapshot::Kind kind,
+ bool as_reference) {
UNREACHABLE();
return Closure::null();
}
-void RawClosure::WriteTo(SnapshotWriter* writer,
- intptr_t object_id,
- Snapshot::Kind kind,
- bool as_reference) {
+void ClosureLayout::WriteTo(SnapshotWriter* writer,
+ intptr_t object_id,
+ Snapshot::Kind kind,
+ bool as_reference) {
ASSERT(writer != NULL);
ASSERT(kind == Snapshot::kMessage);
// Check if closure is serializable, throw an exception otherwise.
- RawFunction* func = writer->IsSerializableClosure(this);
+ FunctionPtr func = writer->IsSerializableClosure(ClosurePtr(this));
if (func != Function::null()) {
writer->WriteStaticImplicitClosure(object_id, func,
writer->GetObjectTags(this));
@@ -392,11 +393,11 @@
UNREACHABLE();
}
-RawContext* Context::ReadFrom(SnapshotReader* reader,
- intptr_t object_id,
- intptr_t tags,
- Snapshot::Kind kind,
- bool as_reference) {
+ContextPtr Context::ReadFrom(SnapshotReader* reader,
+ intptr_t object_id,
+ intptr_t tags,
+ Snapshot::Kind kind,
+ bool as_reference) {
ASSERT(reader != NULL);
// Allocate context object.
@@ -409,20 +410,21 @@
// Set all the object fields.
// TODO(5411462): Need to assert No GC can happen here, even though
// allocations may happen.
- intptr_t num_flds = (context.raw()->to(num_vars) - context.raw()->from());
+ intptr_t num_flds =
+ (context.raw()->ptr()->to(num_vars) - context.raw()->ptr()->from());
for (intptr_t i = 0; i <= num_flds; i++) {
(*reader->PassiveObjectHandle()) = reader->ReadObjectImpl(kAsReference);
- context.StorePointer((context.raw()->from() + i),
+ context.StorePointer((context.raw()->ptr()->from() + i),
reader->PassiveObjectHandle()->raw());
}
}
return context.raw();
}
-void RawContext::WriteTo(SnapshotWriter* writer,
- intptr_t object_id,
- Snapshot::Kind kind,
- bool as_reference) {
+void ContextLayout::WriteTo(SnapshotWriter* writer,
+ intptr_t object_id,
+ Snapshot::Kind kind,
+ bool as_reference) {
ASSERT(writer != NULL);
// Write out the serialization header value for this object.
@@ -442,11 +444,11 @@
}
}
-RawContextScope* ContextScope::ReadFrom(SnapshotReader* reader,
- intptr_t object_id,
- intptr_t tags,
- Snapshot::Kind kind,
- bool as_reference) {
+ContextScopePtr ContextScope::ReadFrom(SnapshotReader* reader,
+ intptr_t object_id,
+ intptr_t tags,
+ Snapshot::Kind kind,
+ bool as_reference) {
ASSERT(reader != NULL);
// Allocate context object.
@@ -473,10 +475,10 @@
return NULL;
}
-void RawContextScope::WriteTo(SnapshotWriter* writer,
- intptr_t object_id,
- Snapshot::Kind kind,
- bool as_reference) {
+void ContextScopeLayout::WriteTo(SnapshotWriter* writer,
+ intptr_t object_id,
+ Snapshot::Kind kind,
+ bool as_reference) {
ASSERT(writer != NULL);
if (ptr()->is_implicit_) {
@@ -502,26 +504,26 @@
}
#define MESSAGE_SNAPSHOT_UNREACHABLE(type) \
- Raw##type* type::ReadFrom(SnapshotReader* reader, intptr_t object_id, \
- intptr_t tags, Snapshot::Kind kind, \
- bool as_reference) { \
+ type##Ptr type::ReadFrom(SnapshotReader* reader, intptr_t object_id, \
+ intptr_t tags, Snapshot::Kind kind, \
+ bool as_reference) { \
UNREACHABLE(); \
return type::null(); \
} \
- void Raw##type::WriteTo(SnapshotWriter* writer, intptr_t object_id, \
- Snapshot::Kind kind, bool as_reference) { \
+ void type##Layout::WriteTo(SnapshotWriter* writer, intptr_t object_id, \
+ Snapshot::Kind kind, bool as_reference) { \
UNREACHABLE(); \
}
#define MESSAGE_SNAPSHOT_ILLEGAL(type) \
- Raw##type* type::ReadFrom(SnapshotReader* reader, intptr_t object_id, \
- intptr_t tags, Snapshot::Kind kind, \
- bool as_reference) { \
+ type##Ptr type::ReadFrom(SnapshotReader* reader, intptr_t object_id, \
+ intptr_t tags, Snapshot::Kind kind, \
+ bool as_reference) { \
UNREACHABLE(); \
return type::null(); \
} \
- void Raw##type::WriteTo(SnapshotWriter* writer, intptr_t object_id, \
- Snapshot::Kind kind, bool as_reference) { \
+ void type##Layout::WriteTo(SnapshotWriter* writer, intptr_t object_id, \
+ Snapshot::Kind kind, bool as_reference) { \
writer->SetWriteException(Exceptions::kArgument, \
"Illegal argument in isolate message" \
" : (object is a " #type ")"); \
@@ -573,11 +575,11 @@
MESSAGE_SNAPSHOT_ILLEGAL(StackTrace);
MESSAGE_SNAPSHOT_ILLEGAL(UserTag);
-RawApiError* ApiError::ReadFrom(SnapshotReader* reader,
- intptr_t object_id,
- intptr_t tags,
- Snapshot::Kind kind,
- bool as_reference) {
+ApiErrorPtr ApiError::ReadFrom(SnapshotReader* reader,
+ intptr_t object_id,
+ intptr_t tags,
+ Snapshot::Kind kind,
+ bool as_reference) {
ASSERT(reader != NULL);
// Allocate ApiError object.
@@ -585,16 +587,16 @@
reader->AddBackRef(object_id, &api_error, kIsDeserialized);
// Set all the object fields.
- READ_OBJECT_FIELDS(api_error, api_error.raw()->from(), api_error.raw()->to(),
- kAsReference);
+ READ_OBJECT_FIELDS(api_error, api_error.raw()->ptr()->from(),
+ api_error.raw()->ptr()->to(), kAsReference);
return api_error.raw();
}
-void RawApiError::WriteTo(SnapshotWriter* writer,
- intptr_t object_id,
- Snapshot::Kind kind,
- bool as_reference) {
+void ApiErrorLayout::WriteTo(SnapshotWriter* writer,
+ intptr_t object_id,
+ Snapshot::Kind kind,
+ bool as_reference) {
ASSERT(writer != NULL);
// Write out the serialization header value for this object.
@@ -609,11 +611,11 @@
visitor.VisitPointers(from(), to());
}
-RawLanguageError* LanguageError::ReadFrom(SnapshotReader* reader,
- intptr_t object_id,
- intptr_t tags,
- Snapshot::Kind kind,
- bool as_reference) {
+LanguageErrorPtr LanguageError::ReadFrom(SnapshotReader* reader,
+ intptr_t object_id,
+ intptr_t tags,
+ Snapshot::Kind kind,
+ bool as_reference) {
ASSERT(reader != NULL);
// Allocate LanguageError object.
@@ -628,16 +630,16 @@
language_error.set_kind(reader->Read<uint8_t>());
// Set all the object fields.
- READ_OBJECT_FIELDS(language_error, language_error.raw()->from(),
- language_error.raw()->to(), kAsReference);
+ READ_OBJECT_FIELDS(language_error, language_error.raw()->ptr()->from(),
+ language_error.raw()->ptr()->to(), kAsReference);
return language_error.raw();
}
-void RawLanguageError::WriteTo(SnapshotWriter* writer,
- intptr_t object_id,
- Snapshot::Kind kind,
- bool as_reference) {
+void LanguageErrorLayout::WriteTo(SnapshotWriter* writer,
+ intptr_t object_id,
+ Snapshot::Kind kind,
+ bool as_reference) {
ASSERT(writer != NULL);
// Write out the serialization header value for this object.
@@ -657,26 +659,26 @@
visitor.VisitPointers(from(), to());
}
-RawUnhandledException* UnhandledException::ReadFrom(SnapshotReader* reader,
- intptr_t object_id,
- intptr_t tags,
- Snapshot::Kind kind,
- bool as_reference) {
+UnhandledExceptionPtr UnhandledException::ReadFrom(SnapshotReader* reader,
+ intptr_t object_id,
+ intptr_t tags,
+ Snapshot::Kind kind,
+ bool as_reference) {
UnhandledException& result =
UnhandledException::ZoneHandle(reader->zone(), UnhandledException::New());
reader->AddBackRef(object_id, &result, kIsDeserialized);
// Set all the object fields.
- READ_OBJECT_FIELDS(result, result.raw()->from(), result.raw()->to(),
- kAsReference);
+ READ_OBJECT_FIELDS(result, result.raw()->ptr()->from(),
+ result.raw()->ptr()->to(), kAsReference);
return result.raw();
}
-void RawUnhandledException::WriteTo(SnapshotWriter* writer,
- intptr_t object_id,
- Snapshot::Kind kind,
- bool as_reference) {
+void UnhandledExceptionLayout::WriteTo(SnapshotWriter* writer,
+ intptr_t object_id,
+ Snapshot::Kind kind,
+ bool as_reference) {
// Write out the serialization header value for this object.
writer->WriteInlinedObjectHeader(object_id);
@@ -688,18 +690,18 @@
visitor.VisitPointers(from(), to());
}
-RawInstance* Instance::ReadFrom(SnapshotReader* reader,
- intptr_t object_id,
- intptr_t tags,
- Snapshot::Kind kind,
- bool as_reference) {
+InstancePtr Instance::ReadFrom(SnapshotReader* reader,
+ intptr_t object_id,
+ intptr_t tags,
+ Snapshot::Kind kind,
+ bool as_reference) {
ASSERT(reader != NULL);
// Create an Instance object or get canonical one if it is a canonical
// constant.
Instance& obj = Instance::ZoneHandle(reader->zone(), Instance::null());
obj ^= Object::Allocate(kInstanceCid, Instance::InstanceSize(), Heap::kNew);
- if (RawObject::IsCanonical(tags)) {
+ if (ObjectLayout::IsCanonical(tags)) {
const char* error_str = NULL;
obj = obj.CheckAndCanonicalize(reader->thread(), &error_str);
if (error_str != NULL) {
@@ -711,10 +713,10 @@
return obj.raw();
}
-void RawInstance::WriteTo(SnapshotWriter* writer,
- intptr_t object_id,
- Snapshot::Kind kind,
- bool as_reference) {
+void InstanceLayout::WriteTo(SnapshotWriter* writer,
+ intptr_t object_id,
+ Snapshot::Kind kind,
+ bool as_reference) {
ASSERT(writer != NULL);
// Write out the serialization header value for this object.
@@ -725,11 +727,11 @@
writer->WriteTags(writer->GetObjectTags(this));
}
-RawInteger* Mint::ReadFrom(SnapshotReader* reader,
- intptr_t object_id,
- intptr_t tags,
- Snapshot::Kind kind,
- bool as_reference) {
+IntegerPtr Mint::ReadFrom(SnapshotReader* reader,
+ intptr_t object_id,
+ intptr_t tags,
+ Snapshot::Kind kind,
+ bool as_reference) {
ASSERT(reader != NULL);
// Read the 64 bit value for the object.
@@ -751,7 +753,7 @@
// full snapshot). Objects that are only in the script need not be
// canonicalized as they are already canonical.
// When reading a message snapshot we always have to canonicalize.
- if (RawObject::IsCanonical(tags)) {
+ if (ObjectLayout::IsCanonical(tags)) {
mint = Mint::NewCanonical(value);
ASSERT(mint.IsCanonical());
} else {
@@ -761,10 +763,10 @@
return mint.raw();
}
-void RawMint::WriteTo(SnapshotWriter* writer,
- intptr_t object_id,
- Snapshot::Kind kind,
- bool as_reference) {
+void MintLayout::WriteTo(SnapshotWriter* writer,
+ intptr_t object_id,
+ Snapshot::Kind kind,
+ bool as_reference) {
ASSERT(writer != NULL);
// Write out the serialization header value for this object.
@@ -778,11 +780,11 @@
writer->Write<int64_t>(ptr()->value_);
}
-RawDouble* Double::ReadFrom(SnapshotReader* reader,
- intptr_t object_id,
- intptr_t tags,
- Snapshot::Kind kind,
- bool as_reference) {
+DoublePtr Double::ReadFrom(SnapshotReader* reader,
+ intptr_t object_id,
+ intptr_t tags,
+ Snapshot::Kind kind,
+ bool as_reference) {
ASSERT(reader != NULL);
ASSERT(kind != Snapshot::kMessage);
// Read the double value for the object.
@@ -794,7 +796,7 @@
// references that are objects from the core library (loaded from a
// full snapshot). Objects that are only in the script need not be
// canonicalized as they are already canonical.
- if (RawObject::IsCanonical(tags)) {
+ if (ObjectLayout::IsCanonical(tags)) {
dbl = Double::NewCanonical(value);
ASSERT(dbl.IsCanonical());
} else {
@@ -804,10 +806,10 @@
return dbl.raw();
}
-void RawDouble::WriteTo(SnapshotWriter* writer,
- intptr_t object_id,
- Snapshot::Kind kind,
- bool as_reference) {
+void DoubleLayout::WriteTo(SnapshotWriter* writer,
+ intptr_t object_id,
+ Snapshot::Kind kind,
+ bool as_reference) {
ASSERT(writer != NULL);
// Write out the serialization header value for this object.
@@ -829,7 +831,7 @@
CallbackType new_symbol,
Snapshot::Kind kind) {
ASSERT(reader != NULL);
- if (RawObject::IsCanonical(tags)) {
+ if (ObjectLayout::IsCanonical(tags)) {
// Set up canonical string object.
ASSERT(reader != NULL);
CharacterType* ptr = reader->zone()->Alloc<CharacterType>(len);
@@ -853,11 +855,11 @@
}
}
-RawOneByteString* OneByteString::ReadFrom(SnapshotReader* reader,
- intptr_t object_id,
- intptr_t tags,
- Snapshot::Kind kind,
- bool as_reference) {
+OneByteStringPtr OneByteString::ReadFrom(SnapshotReader* reader,
+ intptr_t object_id,
+ intptr_t tags,
+ Snapshot::Kind kind,
+ bool as_reference) {
// Read the length so that we can determine instance size to allocate.
ASSERT(reader != NULL);
intptr_t len = reader->ReadSmiValue();
@@ -869,11 +871,11 @@
return raw(str_obj);
}
-RawTwoByteString* TwoByteString::ReadFrom(SnapshotReader* reader,
- intptr_t object_id,
- intptr_t tags,
- Snapshot::Kind kind,
- bool as_reference) {
+TwoByteStringPtr TwoByteString::ReadFrom(SnapshotReader* reader,
+ intptr_t object_id,
+ intptr_t tags,
+ Snapshot::Kind kind,
+ bool as_reference) {
// Read the length so that we can determine instance size to allocate.
ASSERT(reader != NULL);
intptr_t len = reader->ReadSmiValue();
@@ -891,7 +893,7 @@
Snapshot::Kind kind,
intptr_t class_id,
intptr_t tags,
- RawSmi* length,
+ SmiPtr length,
T* data) {
ASSERT(writer != NULL);
intptr_t len = Smi::Value(length);
@@ -904,7 +906,7 @@
writer->WriteTags(tags);
// Write out the length field.
- writer->Write<RawObject*>(length);
+ writer->Write<ObjectPtr>(length);
// Write out the string.
if (len > 0) {
@@ -918,67 +920,65 @@
}
}
-void RawOneByteString::WriteTo(SnapshotWriter* writer,
- intptr_t object_id,
- Snapshot::Kind kind,
- bool as_reference) {
+void OneByteStringLayout::WriteTo(SnapshotWriter* writer,
+ intptr_t object_id,
+ Snapshot::Kind kind,
+ bool as_reference) {
StringWriteTo(writer, object_id, kind, kOneByteStringCid,
writer->GetObjectTags(this), ptr()->length_, ptr()->data());
}
-void RawTwoByteString::WriteTo(SnapshotWriter* writer,
- intptr_t object_id,
- Snapshot::Kind kind,
- bool as_reference) {
+void TwoByteStringLayout::WriteTo(SnapshotWriter* writer,
+ intptr_t object_id,
+ Snapshot::Kind kind,
+ bool as_reference) {
StringWriteTo(writer, object_id, kind, kTwoByteStringCid,
writer->GetObjectTags(this), ptr()->length_, ptr()->data());
}
-RawExternalOneByteString* ExternalOneByteString::ReadFrom(
- SnapshotReader* reader,
- intptr_t object_id,
- intptr_t tags,
- Snapshot::Kind kind,
- bool as_reference) {
+ExternalOneByteStringPtr ExternalOneByteString::ReadFrom(SnapshotReader* reader,
+ intptr_t object_id,
+ intptr_t tags,
+ Snapshot::Kind kind,
+ bool as_reference) {
UNREACHABLE();
return ExternalOneByteString::null();
}
-RawExternalTwoByteString* ExternalTwoByteString::ReadFrom(
- SnapshotReader* reader,
- intptr_t object_id,
- intptr_t tags,
- Snapshot::Kind kind,
- bool as_reference) {
+ExternalTwoByteStringPtr ExternalTwoByteString::ReadFrom(SnapshotReader* reader,
+ intptr_t object_id,
+ intptr_t tags,
+ Snapshot::Kind kind,
+ bool as_reference) {
UNREACHABLE();
return ExternalTwoByteString::null();
}
-void RawExternalOneByteString::WriteTo(SnapshotWriter* writer,
- intptr_t object_id,
- Snapshot::Kind kind,
- bool as_reference) {
+void ExternalOneByteStringLayout::WriteTo(SnapshotWriter* writer,
+ intptr_t object_id,
+ Snapshot::Kind kind,
+ bool as_reference) {
// Serialize as a non-external one byte string.
StringWriteTo(writer, object_id, kind, kOneByteStringCid,
writer->GetObjectTags(this), ptr()->length_,
ptr()->external_data_);
}
-void RawExternalTwoByteString::WriteTo(SnapshotWriter* writer,
- intptr_t object_id,
- Snapshot::Kind kind,
- bool as_reference) {
+void ExternalTwoByteStringLayout::WriteTo(SnapshotWriter* writer,
+ intptr_t object_id,
+ Snapshot::Kind kind,
+ bool as_reference) {
// Serialize as a non-external two byte string.
StringWriteTo(writer, object_id, kind, kTwoByteStringCid,
writer->GetObjectTags(this), ptr()->length_,
ptr()->external_data_);
}
-RawArray* Array::ReadFrom(SnapshotReader* reader,
- intptr_t object_id,
- intptr_t tags,
- Snapshot::Kind kind,
- bool as_reference) {
+ArrayPtr Array::ReadFrom(SnapshotReader* reader,
+ intptr_t object_id,
+ intptr_t tags,
+ Snapshot::Kind kind,
+ bool as_reference) {
ASSERT(reader != NULL);
// Read the length so that we can determine instance size to allocate.
@@ -997,17 +997,17 @@
}
if (!as_reference) {
// Read all the individual elements for inlined objects.
- ASSERT(!RawObject::IsCanonical(tags));
+ ASSERT(!ObjectLayout::IsCanonical(tags));
reader->ArrayReadFrom(object_id, *array, len, tags);
}
return array->raw();
}
-RawImmutableArray* ImmutableArray::ReadFrom(SnapshotReader* reader,
- intptr_t object_id,
- intptr_t tags,
- Snapshot::Kind kind,
- bool as_reference) {
+ImmutableArrayPtr ImmutableArray::ReadFrom(SnapshotReader* reader,
+ intptr_t object_id,
+ intptr_t tags,
+ Snapshot::Kind kind,
+ bool as_reference) {
ASSERT(reader != NULL);
// Read the length so that we can determine instance size to allocate.
@@ -1027,7 +1027,7 @@
if (!as_reference) {
// Read all the individual elements for inlined objects.
reader->ArrayReadFrom(object_id, *array, len, tags);
- if (RawObject::IsCanonical(tags)) {
+ if (ObjectLayout::IsCanonical(tags)) {
const char* error_str = NULL;
*array ^= array->CheckAndCanonicalize(reader->thread(), &error_str);
if (error_str != NULL) {
@@ -1038,30 +1038,30 @@
return raw(*array);
}
-void RawArray::WriteTo(SnapshotWriter* writer,
- intptr_t object_id,
- Snapshot::Kind kind,
- bool as_reference) {
+void ArrayLayout::WriteTo(SnapshotWriter* writer,
+ intptr_t object_id,
+ Snapshot::Kind kind,
+ bool as_reference) {
ASSERT(!this->IsCanonical());
writer->ArrayWriteTo(object_id, kArrayCid, writer->GetObjectTags(this),
ptr()->length_, ptr()->type_arguments_, ptr()->data(),
as_reference);
}
-void RawImmutableArray::WriteTo(SnapshotWriter* writer,
- intptr_t object_id,
- Snapshot::Kind kind,
- bool as_reference) {
+void ImmutableArrayLayout::WriteTo(SnapshotWriter* writer,
+ intptr_t object_id,
+ Snapshot::Kind kind,
+ bool as_reference) {
writer->ArrayWriteTo(object_id, kImmutableArrayCid,
writer->GetObjectTags(this), ptr()->length_,
ptr()->type_arguments_, ptr()->data(), as_reference);
}
-RawGrowableObjectArray* GrowableObjectArray::ReadFrom(SnapshotReader* reader,
- intptr_t object_id,
- intptr_t tags,
- Snapshot::Kind kind,
- bool as_reference) {
+GrowableObjectArrayPtr GrowableObjectArray::ReadFrom(SnapshotReader* reader,
+ intptr_t object_id,
+ intptr_t tags,
+ Snapshot::Kind kind,
+ bool as_reference) {
ASSERT(reader != NULL);
// Read the length so that we can determine instance size to allocate.
@@ -1085,10 +1085,10 @@
return array.raw();
}
-void RawGrowableObjectArray::WriteTo(SnapshotWriter* writer,
- intptr_t object_id,
- Snapshot::Kind kind,
- bool as_reference) {
+void GrowableObjectArrayLayout::WriteTo(SnapshotWriter* writer,
+ intptr_t object_id,
+ Snapshot::Kind kind,
+ bool as_reference) {
ASSERT(writer != NULL);
// Write out the serialization header value for this object.
@@ -1102,17 +1102,17 @@
writer->WriteObjectImpl(ptr()->type_arguments_, kAsInlinedObject);
// Write out the used length field.
- writer->Write<RawObject*>(ptr()->length_);
+ writer->Write<ObjectPtr>(ptr()->length_);
// Write out the Array object.
writer->WriteObjectImpl(ptr()->data_, kAsReference);
}
-RawLinkedHashMap* LinkedHashMap::ReadFrom(SnapshotReader* reader,
- intptr_t object_id,
- intptr_t tags,
- Snapshot::Kind kind,
- bool as_reference) {
+LinkedHashMapPtr LinkedHashMap::ReadFrom(SnapshotReader* reader,
+ intptr_t object_id,
+ intptr_t tags,
+ Snapshot::Kind kind,
+ bool as_reference) {
ASSERT(reader != NULL);
LinkedHashMap& map =
@@ -1148,7 +1148,7 @@
reader->EnqueueRehashingOfMap(map);
// Read the keys and values.
- bool read_as_reference = RawObject::IsCanonical(tags) ? false : true;
+ bool read_as_reference = ObjectLayout::IsCanonical(tags) ? false : true;
for (intptr_t i = 0; i < used_data; i++) {
*reader->PassiveObjectHandle() = reader->ReadObjectImpl(read_as_reference);
data.SetAt(i, *reader->PassiveObjectHandle());
@@ -1156,10 +1156,10 @@
return map.raw();
}
-void RawLinkedHashMap::WriteTo(SnapshotWriter* writer,
- intptr_t object_id,
- Snapshot::Kind kind,
- bool as_reference) {
+void LinkedHashMapLayout::WriteTo(SnapshotWriter* writer,
+ intptr_t object_id,
+ Snapshot::Kind kind,
+ bool as_reference) {
ASSERT(writer != NULL);
// Write out the serialization header value for this object.
@@ -1177,36 +1177,36 @@
const intptr_t deleted_keys = Smi::Value(ptr()->deleted_keys_);
// Write out the number of (not deleted) key/value pairs that will follow.
- writer->Write<RawObject*>(Smi::New((used_data >> 1) - deleted_keys));
+ writer->Write<ObjectPtr>(Smi::New((used_data >> 1) - deleted_keys));
// Write out the keys and values.
const bool write_as_reference = this->IsCanonical() ? false : true;
- RawArray* data_array = ptr()->data_;
- RawObject** data_elements = data_array->ptr()->data();
+ ArrayPtr data_array = ptr()->data_;
+ ObjectPtr* data_elements = data_array->ptr()->data();
ASSERT(used_data <= Smi::Value(data_array->ptr()->length_));
#if defined(DEBUG)
intptr_t deleted_keys_found = 0;
#endif // DEBUG
for (intptr_t i = 0; i < used_data; i += 2) {
- RawObject* key = data_elements[i];
+ ObjectPtr key = data_elements[i];
if (key == data_array) {
#if defined(DEBUG)
++deleted_keys_found;
#endif // DEBUG
continue;
}
- RawObject* value = data_elements[i + 1];
+ ObjectPtr value = data_elements[i + 1];
writer->WriteObjectImpl(key, write_as_reference);
writer->WriteObjectImpl(value, write_as_reference);
}
DEBUG_ASSERT(deleted_keys_found == deleted_keys);
}
-RawFloat32x4* Float32x4::ReadFrom(SnapshotReader* reader,
- intptr_t object_id,
- intptr_t tags,
- Snapshot::Kind kind,
- bool as_reference) {
+Float32x4Ptr Float32x4::ReadFrom(SnapshotReader* reader,
+ intptr_t object_id,
+ intptr_t tags,
+ Snapshot::Kind kind,
+ bool as_reference) {
ASSERT(reader != NULL);
// Read the values.
float value0 = reader->Read<float>();
@@ -1221,10 +1221,10 @@
return simd.raw();
}
-void RawFloat32x4::WriteTo(SnapshotWriter* writer,
- intptr_t object_id,
- Snapshot::Kind kind,
- bool as_reference) {
+void Float32x4Layout::WriteTo(SnapshotWriter* writer,
+ intptr_t object_id,
+ Snapshot::Kind kind,
+ bool as_reference) {
ASSERT(writer != NULL);
// Write out the serialization header value for this object.
@@ -1241,11 +1241,11 @@
writer->Write<float>(ptr()->value_[3]);
}
-RawInt32x4* Int32x4::ReadFrom(SnapshotReader* reader,
- intptr_t object_id,
- intptr_t tags,
- Snapshot::Kind kind,
- bool as_reference) {
+Int32x4Ptr Int32x4::ReadFrom(SnapshotReader* reader,
+ intptr_t object_id,
+ intptr_t tags,
+ Snapshot::Kind kind,
+ bool as_reference) {
ASSERT(reader != NULL);
// Read the values.
uint32_t value0 = reader->Read<uint32_t>();
@@ -1260,10 +1260,10 @@
return simd.raw();
}
-void RawInt32x4::WriteTo(SnapshotWriter* writer,
- intptr_t object_id,
- Snapshot::Kind kind,
- bool as_reference) {
+void Int32x4Layout::WriteTo(SnapshotWriter* writer,
+ intptr_t object_id,
+ Snapshot::Kind kind,
+ bool as_reference) {
ASSERT(writer != NULL);
// Write out the serialization header value for this object.
@@ -1280,11 +1280,11 @@
writer->Write<uint32_t>(ptr()->value_[3]);
}
-RawFloat64x2* Float64x2::ReadFrom(SnapshotReader* reader,
- intptr_t object_id,
- intptr_t tags,
- Snapshot::Kind kind,
- bool as_reference) {
+Float64x2Ptr Float64x2::ReadFrom(SnapshotReader* reader,
+ intptr_t object_id,
+ intptr_t tags,
+ Snapshot::Kind kind,
+ bool as_reference) {
ASSERT(reader != NULL);
// Read the values.
double value0 = reader->Read<double>();
@@ -1297,10 +1297,10 @@
return simd.raw();
}
-void RawFloat64x2::WriteTo(SnapshotWriter* writer,
- intptr_t object_id,
- Snapshot::Kind kind,
- bool as_reference) {
+void Float64x2Layout::WriteTo(SnapshotWriter* writer,
+ intptr_t object_id,
+ Snapshot::Kind kind,
+ bool as_reference) {
ASSERT(writer != NULL);
// Write out the serialization header value for this object.
@@ -1315,14 +1315,14 @@
writer->Write<double>(ptr()->value_[1]);
}
-RawTypedData* TypedData::ReadFrom(SnapshotReader* reader,
- intptr_t object_id,
- intptr_t tags,
- Snapshot::Kind kind,
- bool as_reference) {
+TypedDataPtr TypedData::ReadFrom(SnapshotReader* reader,
+ intptr_t object_id,
+ intptr_t tags,
+ Snapshot::Kind kind,
+ bool as_reference) {
ASSERT(reader != NULL);
- intptr_t cid = RawObject::ClassIdTag::decode(tags);
+ intptr_t cid = ObjectLayout::ClassIdTag::decode(tags);
intptr_t len = reader->ReadSmiValue();
TypedData& result =
TypedData::ZoneHandle(reader->zone(), TypedData::New(cid, len));
@@ -1341,7 +1341,7 @@
// as it would already be a canonical object.
// When reading a script snapshot or a message snapshot we always have
// to canonicalize the object.
- if (RawObject::IsCanonical(tags)) {
+ if (ObjectLayout::IsCanonical(tags)) {
const char* error_str = NULL;
result ^= result.CheckAndCanonicalize(reader->thread(), &error_str);
if (error_str != NULL) {
@@ -1353,13 +1353,13 @@
return result.raw();
}
-RawExternalTypedData* ExternalTypedData::ReadFrom(SnapshotReader* reader,
- intptr_t object_id,
- intptr_t tags,
- Snapshot::Kind kind,
- bool as_reference) {
+ExternalTypedDataPtr ExternalTypedData::ReadFrom(SnapshotReader* reader,
+ intptr_t object_id,
+ intptr_t tags,
+ Snapshot::Kind kind,
+ bool as_reference) {
ASSERT(!Snapshot::IsFull(kind));
- intptr_t cid = RawObject::ClassIdTag::decode(tags);
+ intptr_t cid = ObjectLayout::ClassIdTag::decode(tags);
intptr_t length = reader->ReadSmiValue();
FinalizableData finalizable_data =
@@ -1381,10 +1381,10 @@
free(buffer);
}
-void RawTypedData::WriteTo(SnapshotWriter* writer,
- intptr_t object_id,
- Snapshot::Kind kind,
- bool as_reference) {
+void TypedDataLayout::WriteTo(SnapshotWriter* writer,
+ intptr_t object_id,
+ Snapshot::Kind kind,
+ bool as_reference) {
ASSERT(writer != NULL);
intptr_t cid = this->GetClassId();
intptr_t length = Smi::Value(ptr()->length_); // In elements.
@@ -1461,7 +1461,7 @@
// Write as external.
writer->WriteIndexedObject(external_cid);
writer->WriteTags(writer->GetObjectTags(this));
- writer->Write<RawObject*>(ptr()->length_);
+ writer->Write<ObjectPtr>(ptr()->length_);
uint8_t* data = reinterpret_cast<uint8_t*>(ptr()->data());
void* passed_data = malloc(bytes);
if (passed_data == NULL) {
@@ -1477,17 +1477,17 @@
// Write as internal.
writer->WriteIndexedObject(cid);
writer->WriteTags(writer->GetObjectTags(this));
- writer->Write<RawObject*>(ptr()->length_);
+ writer->Write<ObjectPtr>(ptr()->length_);
uint8_t* data = reinterpret_cast<uint8_t*>(ptr()->data());
writer->Align(Zone::kAlignment);
writer->WriteBytes(data, bytes);
}
}
-void RawExternalTypedData::WriteTo(SnapshotWriter* writer,
- intptr_t object_id,
- Snapshot::Kind kind,
- bool as_reference) {
+void ExternalTypedDataLayout::WriteTo(SnapshotWriter* writer,
+ intptr_t object_id,
+ Snapshot::Kind kind,
+ bool as_reference) {
ASSERT(writer != NULL);
intptr_t cid = this->GetClassId();
intptr_t length = Smi::Value(ptr()->length_); // In elements.
@@ -1546,7 +1546,7 @@
// Write as external.
writer->WriteIndexedObject(cid);
writer->WriteTags(writer->GetObjectTags(this));
- writer->Write<RawObject*>(ptr()->length_);
+ writer->Write<ObjectPtr>(ptr()->length_);
uint8_t* data = reinterpret_cast<uint8_t*>(ptr()->data_);
void* passed_data = malloc(bytes);
if (passed_data == NULL) {
@@ -1560,10 +1560,10 @@
IsolateMessageTypedDataFinalizer);
}
-void RawTypedDataView::WriteTo(SnapshotWriter* writer,
- intptr_t object_id,
- Snapshot::Kind kind,
- bool as_reference) {
+void TypedDataViewLayout::WriteTo(SnapshotWriter* writer,
+ intptr_t object_id,
+ Snapshot::Kind kind,
+ bool as_reference) {
// Views have always a backing store.
ASSERT(ptr()->typed_data_ != Object::null());
@@ -1575,18 +1575,18 @@
writer->WriteTags(writer->GetObjectTags(this));
// Write members.
- writer->Write<RawObject*>(ptr()->offset_in_bytes_);
- writer->Write<RawObject*>(ptr()->length_);
+ writer->Write<ObjectPtr>(ptr()->offset_in_bytes_);
+ writer->Write<ObjectPtr>(ptr()->length_);
writer->WriteObjectImpl(ptr()->typed_data_, as_reference);
}
-RawTypedDataView* TypedDataView::ReadFrom(SnapshotReader* reader,
- intptr_t object_id,
- intptr_t tags,
- Snapshot::Kind kind,
- bool as_reference) {
+TypedDataViewPtr TypedDataView::ReadFrom(SnapshotReader* reader,
+ intptr_t object_id,
+ intptr_t tags,
+ Snapshot::Kind kind,
+ bool as_reference) {
auto& typed_data = *reader->TypedDataBaseHandle();
- const classid_t cid = RawObject::ClassIdTag::decode(tags);
+ const classid_t cid = ObjectLayout::ClassIdTag::decode(tags);
auto& view = *reader->TypedDataViewHandle();
view = TypedDataView::New(cid);
@@ -1600,11 +1600,11 @@
return view.raw();
}
-RawCapability* Capability::ReadFrom(SnapshotReader* reader,
- intptr_t object_id,
- intptr_t tags,
- Snapshot::Kind kind,
- bool as_reference) {
+CapabilityPtr Capability::ReadFrom(SnapshotReader* reader,
+ intptr_t object_id,
+ intptr_t tags,
+ Snapshot::Kind kind,
+ bool as_reference) {
uint64_t id = reader->Read<uint64_t>();
Capability& result =
@@ -1613,10 +1613,10 @@
return result.raw();
}
-void RawCapability::WriteTo(SnapshotWriter* writer,
- intptr_t object_id,
- Snapshot::Kind kind,
- bool as_reference) {
+void CapabilityLayout::WriteTo(SnapshotWriter* writer,
+ intptr_t object_id,
+ Snapshot::Kind kind,
+ bool as_reference) {
// Write out the serialization header value for this object.
writer->WriteInlinedObjectHeader(object_id);
@@ -1627,11 +1627,11 @@
writer->Write<uint64_t>(ptr()->id_);
}
-RawSendPort* SendPort::ReadFrom(SnapshotReader* reader,
- intptr_t object_id,
- intptr_t tags,
- Snapshot::Kind kind,
- bool as_reference) {
+SendPortPtr SendPort::ReadFrom(SnapshotReader* reader,
+ intptr_t object_id,
+ intptr_t tags,
+ Snapshot::Kind kind,
+ bool as_reference) {
ASSERT(kind == Snapshot::kMessage);
uint64_t id = reader->Read<uint64_t>();
@@ -1643,10 +1643,10 @@
return result.raw();
}
-void RawSendPort::WriteTo(SnapshotWriter* writer,
- intptr_t object_id,
- Snapshot::Kind kind,
- bool as_reference) {
+void SendPortLayout::WriteTo(SnapshotWriter* writer,
+ intptr_t object_id,
+ Snapshot::Kind kind,
+ bool as_reference) {
// Write out the serialization header value for this object.
writer->WriteInlinedObjectHeader(object_id);
@@ -1658,12 +1658,11 @@
writer->Write<uint64_t>(ptr()->origin_id_);
}
-RawTransferableTypedData* TransferableTypedData::ReadFrom(
- SnapshotReader* reader,
- intptr_t object_id,
- intptr_t tags,
- Snapshot::Kind kind,
- bool as_reference) {
+TransferableTypedDataPtr TransferableTypedData::ReadFrom(SnapshotReader* reader,
+ intptr_t object_id,
+ intptr_t tags,
+ Snapshot::Kind kind,
+ bool as_reference) {
ASSERT(reader != nullptr);
ASSERT(!Snapshot::IsFull(kind));
@@ -1678,13 +1677,13 @@
return transferableTypedData.raw();
}
-void RawTransferableTypedData::WriteTo(SnapshotWriter* writer,
- intptr_t object_id,
- Snapshot::Kind kind,
- bool as_reference) {
+void TransferableTypedDataLayout::WriteTo(SnapshotWriter* writer,
+ intptr_t object_id,
+ Snapshot::Kind kind,
+ bool as_reference) {
ASSERT(writer != nullptr);
ASSERT(GetClassId() == kTransferableTypedDataCid);
- void* peer = writer->thread()->heap()->GetPeer(this);
+ void* peer = writer->thread()->heap()->GetPeer(ObjectPtr(this));
// Assume that object's Peer is only used to track transferrability state.
ASSERT(peer != nullptr);
TransferableTypedDataPeer* tpeer =
@@ -1720,11 +1719,11 @@
});
}
-RawRegExp* RegExp::ReadFrom(SnapshotReader* reader,
- intptr_t object_id,
- intptr_t tags,
- Snapshot::Kind kind,
- bool as_reference) {
+RegExpPtr RegExp::ReadFrom(SnapshotReader* reader,
+ intptr_t object_id,
+ intptr_t tags,
+ Snapshot::Kind kind,
+ bool as_reference) {
ASSERT(reader != NULL);
// Allocate RegExp object.
@@ -1756,10 +1755,10 @@
return regex.raw();
}
-void RawRegExp::WriteTo(SnapshotWriter* writer,
- intptr_t object_id,
- Snapshot::Kind kind,
- bool as_reference) {
+void RegExpLayout::WriteTo(SnapshotWriter* writer,
+ intptr_t object_id,
+ Snapshot::Kind kind,
+ bool as_reference) {
ASSERT(writer != NULL);
// Write out the serialization header value for this object.
@@ -1770,18 +1769,18 @@
writer->WriteTags(writer->GetObjectTags(this));
// Write out all the other fields.
- writer->Write<RawObject*>(ptr()->num_bracket_expressions_);
+ writer->Write<ObjectPtr>(ptr()->num_bracket_expressions_);
writer->WriteObjectImpl(ptr()->pattern_, kAsInlinedObject);
writer->Write<int32_t>(ptr()->num_one_byte_registers_);
writer->Write<int32_t>(ptr()->num_two_byte_registers_);
writer->Write<int8_t>(ptr()->type_flags_);
}
-RawWeakProperty* WeakProperty::ReadFrom(SnapshotReader* reader,
- intptr_t object_id,
- intptr_t tags,
- Snapshot::Kind kind,
- bool as_reference) {
+WeakPropertyPtr WeakProperty::ReadFrom(SnapshotReader* reader,
+ intptr_t object_id,
+ intptr_t tags,
+ Snapshot::Kind kind,
+ bool as_reference) {
ASSERT(reader != NULL);
// Allocate the weak property object.
@@ -1790,16 +1789,16 @@
reader->AddBackRef(object_id, &weak_property, kIsDeserialized);
// Set all the object fields.
- READ_OBJECT_FIELDS(weak_property, weak_property.raw()->from(),
- weak_property.raw()->to(), kAsReference);
+ READ_OBJECT_FIELDS(weak_property, weak_property.raw()->ptr()->from(),
+ weak_property.raw()->ptr()->to(), kAsReference);
return weak_property.raw();
}
-void RawWeakProperty::WriteTo(SnapshotWriter* writer,
- intptr_t object_id,
- Snapshot::Kind kind,
- bool as_reference) {
+void WeakPropertyLayout::WriteTo(SnapshotWriter* writer,
+ intptr_t object_id,
+ Snapshot::Kind kind,
+ bool as_reference) {
ASSERT(writer != NULL);
// Write out the serialization header value for this object.
diff --git a/runtime/vm/regexp.cc b/runtime/vm/regexp.cc
index 08384be..8b3e30f 100644
--- a/runtime/vm/regexp.cc
+++ b/runtime/vm/regexp.cc
@@ -5515,7 +5515,7 @@
Function& fn =
Function::Handle(zone, Function::New(Symbols::ColonMatcher(),
- RawFunction::kIrregexpFunction,
+ FunctionLayout::kIrregexpFunction,
true, // Static.
false, // Not const.
false, // Not abstract.
@@ -5552,9 +5552,9 @@
// The function is compiled lazily during the first call.
}
-RawRegExp* RegExpEngine::CreateRegExp(Thread* thread,
- const String& pattern,
- RegExpFlags flags) {
+RegExpPtr RegExpEngine::CreateRegExp(Thread* thread,
+ const String& pattern,
+ RegExpFlags flags) {
Zone* zone = thread->zone();
const RegExp& regexp = RegExp::Handle(RegExp::New());
diff --git a/runtime/vm/regexp.h b/runtime/vm/regexp.h
index 7cefc38..3fed61b 100644
--- a/runtime/vm/regexp.h
+++ b/runtime/vm/regexp.h
@@ -1510,9 +1510,9 @@
bool sticky,
Zone* zone);
- static RawRegExp* CreateRegExp(Thread* thread,
- const String& pattern,
- RegExpFlags flags);
+ static RegExpPtr CreateRegExp(Thread* thread,
+ const String& pattern,
+ RegExpFlags flags);
static void DotPrint(const char* label, RegExpNode* node, bool ignore_case);
};
diff --git a/runtime/vm/regexp_assembler.cc b/runtime/vm/regexp_assembler.cc
index 8fa69ac..3c2e119 100644
--- a/runtime/vm/regexp_assembler.cc
+++ b/runtime/vm/regexp_assembler.cc
@@ -21,14 +21,14 @@
OS::PrintErr(format, c);
}
-RawBool* CaseInsensitiveCompareUCS2(RawString* str_raw,
- RawSmi* lhs_index_raw,
- RawSmi* rhs_index_raw,
- RawSmi* length_raw) {
- const String& str = String::Handle(str_raw);
- const Smi& lhs_index = Smi::Handle(lhs_index_raw);
- const Smi& rhs_index = Smi::Handle(rhs_index_raw);
- const Smi& length = Smi::Handle(length_raw);
+uword /*BoolPtr*/ CaseInsensitiveCompareUCS2(uword /*StringPtr*/ str_raw,
+ uword /*SmiPtr*/ lhs_index_raw,
+ uword /*SmiPtr*/ rhs_index_raw,
+ uword /*SmiPtr*/ length_raw) {
+ const String& str = String::Handle(static_cast<StringPtr>(str_raw));
+ const Smi& lhs_index = Smi::Handle(static_cast<SmiPtr>(lhs_index_raw));
+ const Smi& rhs_index = Smi::Handle(static_cast<SmiPtr>(rhs_index_raw));
+ const Smi& length = Smi::Handle(static_cast<SmiPtr>(length_raw));
// TODO(zerny): Optimize as single instance. V8 has this as an
// isolate member.
@@ -44,22 +44,22 @@
int32_t s2[1] = {c2};
canonicalize.get(c2, '\0', s2);
if (s1[0] != s2[0]) {
- return Bool::False().raw();
+ return static_cast<uword>(Bool::False().raw());
}
}
}
}
- return Bool::True().raw();
+ return static_cast<uword>(Bool::True().raw());
}
-RawBool* CaseInsensitiveCompareUTF16(RawString* str_raw,
- RawSmi* lhs_index_raw,
- RawSmi* rhs_index_raw,
- RawSmi* length_raw) {
- const String& str = String::Handle(str_raw);
- const Smi& lhs_index = Smi::Handle(lhs_index_raw);
- const Smi& rhs_index = Smi::Handle(rhs_index_raw);
- const Smi& length = Smi::Handle(length_raw);
+uword /*BoolPtr*/ CaseInsensitiveCompareUTF16(uword /*StringPtr*/ str_raw,
+ uword /*SmiPtr*/ lhs_index_raw,
+ uword /*SmiPtr*/ rhs_index_raw,
+ uword /*SmiPtr*/ length_raw) {
+ const String& str = String::Handle(static_cast<StringPtr>(str_raw));
+ const Smi& lhs_index = Smi::Handle(static_cast<SmiPtr>(lhs_index_raw));
+ const Smi& rhs_index = Smi::Handle(static_cast<SmiPtr>(rhs_index_raw));
+ const Smi& length = Smi::Handle(static_cast<SmiPtr>(length_raw));
for (intptr_t i = 0; i < length.Value(); i++) {
int32_t c1 = str.CharAt(lhs_index.Value() + i);
@@ -67,7 +67,8 @@
if (Utf16::IsLeadSurrogate(c1)) {
// Non-BMP characters do not have case-equivalents in the BMP.
// Both have to be non-BMP for them to be able to match.
- if (!Utf16::IsLeadSurrogate(c2)) return Bool::False().raw();
+ if (!Utf16::IsLeadSurrogate(c2))
+ return static_cast<uword>(Bool::False().raw());
if (i + 1 < length.Value()) {
uint16_t c1t = str.CharAt(lhs_index.Value() + i + 1);
uint16_t c2t = str.CharAt(rhs_index.Value() + i + 1);
@@ -80,9 +81,9 @@
}
c1 = u_foldCase(c1, U_FOLD_CASE_DEFAULT);
c2 = u_foldCase(c2, U_FOLD_CASE_DEFAULT);
- if (c1 != c2) return Bool::False().raw();
+ if (c1 != c2) return static_cast<uword>(Bool::False().raw());
}
- return Bool::True().raw();
+ return static_cast<uword>(Bool::True().raw());
}
DEFINE_RAW_LEAF_RUNTIME_ENTRY(
diff --git a/runtime/vm/regexp_assembler.h b/runtime/vm/regexp_assembler.h
index d7a460b..d858c48 100644
--- a/runtime/vm/regexp_assembler.h
+++ b/runtime/vm/regexp_assembler.h
@@ -16,19 +16,22 @@
// Utility function for the DotPrinter
void PrintUtf16(uint16_t c);
+
+extern "C" {
// Compares two-byte strings case insensitively as UCS2.
// Called from generated RegExp code.
-RawBool* CaseInsensitiveCompareUCS2(RawString* str_raw,
- RawSmi* lhs_index_raw,
- RawSmi* rhs_index_raw,
- RawSmi* length_raw);
+uword /*BoolPtr*/ CaseInsensitiveCompareUCS2(uword /*StringPtr*/ str_raw,
+ uword /*SmiPtr*/ lhs_index_raw,
+ uword /*SmiPtr*/ rhs_index_raw,
+ uword /*SmiPtr*/ length_raw);
// Compares two-byte strings case insensitively as UTF16.
// Called from generated RegExp code.
-RawBool* CaseInsensitiveCompareUTF16(RawString* str_raw,
- RawSmi* lhs_index_raw,
- RawSmi* rhs_index_raw,
- RawSmi* length_raw);
+uword /*BoolPtr*/ CaseInsensitiveCompareUTF16(uword /*StringPtr*/ str_raw,
+ uword /*SmiPtr*/ lhs_index_raw,
+ uword /*SmiPtr*/ rhs_index_raw,
+ uword /*SmiPtr*/ length_raw);
+}
/// Convenience wrapper around a BlockEntryInstr pointer.
class BlockLabel : public ValueObject {
diff --git a/runtime/vm/regexp_assembler_bytecode.cc b/runtime/vm/regexp_assembler_bytecode.cc
index 4118969..a7e2ff3 100644
--- a/runtime/vm/regexp_assembler_bytecode.cc
+++ b/runtime/vm/regexp_assembler_bytecode.cc
@@ -390,7 +390,7 @@
EmitOrLink(on_eq);
}
-RawTypedData* BytecodeRegExpMacroAssembler::GetBytecode() {
+TypedDataPtr BytecodeRegExpMacroAssembler::GetBytecode() {
BindBlock(&backtrack_);
Emit(BC_POP_BT, 0);
@@ -511,11 +511,11 @@
return result;
}
-RawInstance* BytecodeRegExpMacroAssembler::Interpret(const RegExp& regexp,
- const String& subject,
- const Smi& start_index,
- bool sticky,
- Zone* zone) {
+InstancePtr BytecodeRegExpMacroAssembler::Interpret(const RegExp& regexp,
+ const String& subject,
+ const Smi& start_index,
+ bool sticky,
+ Zone* zone) {
intptr_t required_registers = Prepare(regexp, subject, sticky, zone);
if (required_registers < 0) {
// Compiling failed with an exception.
diff --git a/runtime/vm/regexp_assembler_bytecode.h b/runtime/vm/regexp_assembler_bytecode.h
index 59cf68f..cdedaa1 100644
--- a/runtime/vm/regexp_assembler_bytecode.h
+++ b/runtime/vm/regexp_assembler_bytecode.h
@@ -95,7 +95,7 @@
virtual IrregexpImplementation Implementation();
// virtual Handle<HeapObject> GetCode(Handle<String> source);
- RawTypedData* GetBytecode();
+ TypedDataPtr GetBytecode();
// New
virtual bool IsClosed() const {
@@ -107,11 +107,11 @@
virtual void PrintBlocks() { UNIMPLEMENTED(); }
/////
- static RawInstance* Interpret(const RegExp& regexp,
- const String& str,
- const Smi& start_index,
- bool is_sticky,
- Zone* zone);
+ static InstancePtr Interpret(const RegExp& regexp,
+ const String& str,
+ const Smi& start_index,
+ bool is_sticky,
+ Zone* zone);
private:
void Expand();
diff --git a/runtime/vm/regexp_assembler_ir.cc b/runtime/vm/regexp_assembler_ir.cc
index 9183c9a..116ff0c 100644
--- a/runtime/vm/regexp_assembler_ir.cc
+++ b/runtime/vm/regexp_assembler_ir.cc
@@ -299,11 +299,11 @@
return kEnableUnalignedAccesses && !slow_safe();
}
-RawArray* IRRegExpMacroAssembler::Execute(const RegExp& regexp,
- const String& input,
- const Smi& start_offset,
- bool sticky,
- Zone* zone) {
+ArrayPtr IRRegExpMacroAssembler::Execute(const RegExp& regexp,
+ const String& input,
+ const Smi& start_offset,
+ bool sticky,
+ Zone* zone) {
const intptr_t cid = input.GetClassId();
const Function& fun = Function::Handle(regexp.function(cid, sticky));
ASSERT(!fun.IsNull());
diff --git a/runtime/vm/regexp_assembler_ir.h b/runtime/vm/regexp_assembler_ir.h
index fb92f1b..d52128d 100644
--- a/runtime/vm/regexp_assembler_ir.h
+++ b/runtime/vm/regexp_assembler_ir.h
@@ -38,11 +38,11 @@
virtual bool CanReadUnaligned();
- static RawArray* Execute(const RegExp& regexp,
- const String& input,
- const Smi& start_offset,
- bool sticky,
- Zone* zone);
+ static ArrayPtr Execute(const RegExp& regexp,
+ const String& input,
+ const Smi& start_offset,
+ bool sticky,
+ Zone* zone);
virtual bool IsClosed() const { return (current_instruction_ == NULL); }
diff --git a/runtime/vm/regexp_interpreter.cc b/runtime/vm/regexp_interpreter.cc
index 2921e3e..111c7fe 100644
--- a/runtime/vm/regexp_interpreter.cc
+++ b/runtime/vm/regexp_interpreter.cc
@@ -36,11 +36,15 @@
bool unicode) {
Bool& ret = Bool::Handle();
if (unicode) {
- ret = CaseInsensitiveCompareUTF16(subject.raw(), Smi::New(from),
- Smi::New(current), Smi::New(len));
+ ret = static_cast<BoolPtr>(CaseInsensitiveCompareUTF16(
+ static_cast<uword>(subject.raw()), static_cast<uword>(Smi::New(from)),
+ static_cast<uword>(Smi::New(current)),
+ static_cast<uword>(Smi::New(len))));
} else {
- ret = CaseInsensitiveCompareUCS2(subject.raw(), Smi::New(from),
- Smi::New(current), Smi::New(len));
+ ret = static_cast<BoolPtr>(CaseInsensitiveCompareUCS2(
+ static_cast<uword>(subject.raw()), static_cast<uword>(Smi::New(from)),
+ static_cast<uword>(Smi::New(current)),
+ static_cast<uword>(Smi::New(len))));
}
return ret.value();
}
diff --git a/runtime/vm/regexp_parser.cc b/runtime/vm/regexp_parser.cc
index c9987e3..d7f4235 100644
--- a/runtime/vm/regexp_parser.cc
+++ b/runtime/vm/regexp_parser.cc
@@ -1242,7 +1242,7 @@
return captures_->At(index - 1);
}
-RawArray* RegExpParser::CreateCaptureNameMap() {
+ArrayPtr RegExpParser::CreateCaptureNameMap() {
if (named_captures_ == nullptr || named_captures_->is_empty()) {
return Array::null();
}
diff --git a/runtime/vm/regexp_parser.h b/runtime/vm/regexp_parser.h
index 63c237a..fd456ba 100644
--- a/runtime/vm/regexp_parser.h
+++ b/runtime/vm/regexp_parser.h
@@ -228,7 +228,7 @@
// to avoid complicating cases in which references come before the capture.
void PatchNamedBackReferences();
- RawArray* CreateCaptureNameMap();
+ ArrayPtr CreateCaptureNameMap();
// Returns true iff the pattern contains named captures. May call
// ScanForCaptures to look ahead at the remaining pattern.
diff --git a/runtime/vm/regexp_test.cc b/runtime/vm/regexp_test.cc
index 5ba4056..01eca0e 100644
--- a/runtime/vm/regexp_test.cc
+++ b/runtime/vm/regexp_test.cc
@@ -12,7 +12,7 @@
namespace dart {
-static RawArray* Match(const String& pat, const String& str) {
+static ArrayPtr Match(const String& pat, const String& str) {
Thread* thread = Thread::Current();
Zone* zone = thread->zone();
const RegExp& regexp =
diff --git a/runtime/vm/report.cc b/runtime/vm/report.cc
index 5d0c407..ded367d6 100644
--- a/runtime/vm/report.cc
+++ b/runtime/vm/report.cc
@@ -17,11 +17,11 @@
DEFINE_FLAG(bool, silent_warnings, false, "Silence warnings.");
DEFINE_FLAG(bool, warning_as_error, false, "Treat warnings as errors.");
-RawString* Report::PrependSnippet(Kind kind,
- const Script& script,
- TokenPosition token_pos,
- bool report_after_token,
- const String& message) {
+StringPtr Report::PrependSnippet(Kind kind,
+ const Script& script,
+ TokenPosition token_pos,
+ bool report_after_token,
+ const String& message) {
const char* message_header;
switch (kind) {
case kWarning:
diff --git a/runtime/vm/report.h b/runtime/vm/report.h
index 30aaf5c..3af8573 100644
--- a/runtime/vm/report.h
+++ b/runtime/vm/report.h
@@ -6,6 +6,7 @@
#define RUNTIME_VM_REPORT_H_
#include "vm/allocation.h"
+#include "vm/tagged_pointer.h"
#include "vm/token_position.h"
namespace dart {
@@ -13,7 +14,6 @@
// Forward declarations.
class Error;
class ICData;
-class RawString;
class Script;
class StackFrame;
class String;
@@ -60,11 +60,11 @@
// Prepend a source snippet to the message.
// A null script means no source and a negative token_pos means no position.
- static RawString* PrependSnippet(Kind kind,
- const Script& script,
- TokenPosition token_pos,
- bool report_after_token,
- const String& message);
+ static StringPtr PrependSnippet(Kind kind,
+ const Script& script,
+ TokenPosition token_pos,
+ bool report_after_token,
+ const String& message);
private:
DISALLOW_COPY_AND_ASSIGN(Report);
diff --git a/runtime/vm/resolver.cc b/runtime/vm/resolver.cc
index 2dd5129..d05a03d 100644
--- a/runtime/vm/resolver.cc
+++ b/runtime/vm/resolver.cc
@@ -22,15 +22,15 @@
// them, since the entry code of such a method does not check for named
// arguments. The dynamic resolver actually checks that a valid number of named
// arguments is passed in.
-RawFunction* Resolver::ResolveDynamic(const Instance& receiver,
- const String& function_name,
- const ArgumentsDescriptor& args_desc) {
+FunctionPtr Resolver::ResolveDynamic(const Instance& receiver,
+ const String& function_name,
+ const ArgumentsDescriptor& args_desc) {
// Figure out type of receiver first.
const Class& cls = Class::Handle(receiver.clazz());
return ResolveDynamicForReceiverClass(cls, function_name, args_desc);
}
-RawFunction* Resolver::ResolveDynamicForReceiverClass(
+FunctionPtr Resolver::ResolveDynamicForReceiverClass(
const Class& receiver_class,
const String& function_name,
const ArgumentsDescriptor& args_desc,
@@ -60,10 +60,10 @@
return function.raw();
}
-RawFunction* Resolver::ResolveDynamicAnyArgs(Zone* zone,
- const Class& receiver_class,
- const String& function_name,
- bool allow_add) {
+FunctionPtr Resolver::ResolveDynamicAnyArgs(Zone* zone,
+ const Class& receiver_class,
+ const String& function_name,
+ bool allow_add) {
Class& cls = Class::Handle(zone, receiver_class.raw());
if (FLAG_trace_resolving) {
THR_Print("ResolveDynamic '%s' for class %s\n", function_name.ToCString(),
@@ -86,7 +86,8 @@
while (!cls.IsNull()) {
function = cls.GetInvocationDispatcher(
function_name, Array::null_array(),
- RawFunction::kDynamicInvocationForwarder, /*create_if_absent=*/false);
+ FunctionLayout::kDynamicInvocationForwarder,
+ /*create_if_absent=*/false);
if (!function.IsNull()) break;
cls = cls.SuperClass();
}
@@ -136,12 +137,12 @@
return function.raw();
}
-RawFunction* Resolver::ResolveStatic(const Library& library,
- const String& class_name,
- const String& function_name,
- intptr_t type_args_len,
- intptr_t num_arguments,
- const Array& argument_names) {
+FunctionPtr Resolver::ResolveStatic(const Library& library,
+ const String& class_name,
+ const String& function_name,
+ intptr_t type_args_len,
+ intptr_t num_arguments,
+ const Array& argument_names) {
ASSERT(!library.IsNull());
Function& function = Function::Handle();
if (class_name.IsNull() || (class_name.Length() == 0)) {
@@ -184,11 +185,11 @@
return function.raw();
}
-RawFunction* Resolver::ResolveStatic(const Class& cls,
- const String& function_name,
- intptr_t type_args_len,
- intptr_t num_arguments,
- const Array& argument_names) {
+FunctionPtr Resolver::ResolveStatic(const Class& cls,
+ const String& function_name,
+ intptr_t type_args_len,
+ intptr_t num_arguments,
+ const Array& argument_names) {
ASSERT(!cls.IsNull());
if (FLAG_trace_resolving) {
THR_Print("ResolveStatic '%s'\n", function_name.ToCString());
diff --git a/runtime/vm/resolver.h b/runtime/vm/resolver.h
index b96f581..0d9f8a9 100644
--- a/runtime/vm/resolver.h
+++ b/runtime/vm/resolver.h
@@ -6,6 +6,7 @@
#define RUNTIME_VM_RESOLVER_H_
#include "vm/allocation.h"
+#include "vm/tagged_pointer.h"
namespace dart {
@@ -14,7 +15,6 @@
class Class;
class Instance;
class Library;
-class RawFunction;
class String;
class ArgumentsDescriptor;
@@ -23,22 +23,22 @@
class Resolver : public AllStatic {
public:
// Resolve specified dart instance function.
- static RawFunction* ResolveDynamic(const Instance& receiver,
- const String& function_name,
- const ArgumentsDescriptor& args_desc);
+ static FunctionPtr ResolveDynamic(const Instance& receiver,
+ const String& function_name,
+ const ArgumentsDescriptor& args_desc);
// If 'allow_add' is true we may add a function to the class during lookup.
- static RawFunction* ResolveDynamicForReceiverClass(
+ static FunctionPtr ResolveDynamicForReceiverClass(
const Class& receiver_class,
const String& function_name,
const ArgumentsDescriptor& args_desc,
bool allow_add = true);
// If 'allow_add' is true we may add a function to the class during lookup.
- static RawFunction* ResolveDynamicAnyArgs(Zone* zone,
- const Class& receiver_class,
- const String& function_name,
- bool allow_add = true);
+ static FunctionPtr ResolveDynamicAnyArgs(Zone* zone,
+ const Class& receiver_class,
+ const String& function_name,
+ bool allow_add = true);
// Resolve specified dart static function. If library.IsNull, use
// either application library or core library if no application library
@@ -46,20 +46,20 @@
// will be resolved by name only.
// Otherwise null is returned if the number or names of arguments are not
// valid for the resolved function.
- static RawFunction* ResolveStatic(const Library& library,
- const String& cls_name,
- const String& function_name,
- intptr_t type_args_len,
- intptr_t num_arguments,
- const Array& argument_names);
+ static FunctionPtr ResolveStatic(const Library& library,
+ const String& cls_name,
+ const String& function_name,
+ intptr_t type_args_len,
+ intptr_t num_arguments,
+ const Array& argument_names);
// Resolve specified dart static function with specified arity. Only resolves
// public functions.
- static RawFunction* ResolveStatic(const Class& cls,
- const String& function_name,
- intptr_t type_args_len,
- intptr_t num_arguments,
- const Array& argument_names);
+ static FunctionPtr ResolveStatic(const Class& cls,
+ const String& function_name,
+ intptr_t type_args_len,
+ intptr_t num_arguments,
+ const Array& argument_names);
};
} // namespace dart
diff --git a/runtime/vm/reverse_pc_lookup_cache.cc b/runtime/vm/reverse_pc_lookup_cache.cc
index 4757d24..e3d45ae 100644
--- a/runtime/vm/reverse_pc_lookup_cache.cc
+++ b/runtime/vm/reverse_pc_lookup_cache.cc
@@ -10,31 +10,33 @@
#if defined(DART_PRECOMPILED_RUNTIME)
-static uword BeginPcFromCode(const RawCode* code) {
+static uword BeginPcFromCode(const CodePtr code) {
return Code::PayloadStartOf(code);
}
-static uword EndPcFromCode(const RawCode* code) {
+static uword EndPcFromCode(const CodePtr code) {
return Code::PayloadStartOf(code) + Code::PayloadSizeOf(code);
}
-void ReversePcLookupCache::BuildAndAttachToIsolate(Isolate* isolate) {
- auto object_store = isolate->object_store();
+void ReversePcLookupCache::BuildAndAttachToIsolateGroup(
+ IsolateGroup* isolate_group) {
+ // This should be called once when the isolate group is created.
+ ASSERT(isolate_group->reverse_pc_lookup_cache() == nullptr);
+
+ auto object_store = isolate_group->object_store();
auto& array = Array::Handle(object_store->code_order_table());
if (!array.IsNull()) {
const intptr_t length = array.Length();
{
NoSafepointScope no_safepoint_scope;
- const uword begin =
- BeginPcFromCode(reinterpret_cast<RawCode*>(array.At(0)));
+ const uword begin = BeginPcFromCode(static_cast<CodePtr>(array.At(0)));
const uword end =
- EndPcFromCode(reinterpret_cast<RawCode*>(array.At(length - 1)));
+ EndPcFromCode(static_cast<CodePtr>(array.At(length - 1)));
auto pc_array = new uint32_t[length];
for (intptr_t i = 0; i < length; i++) {
- const auto end_pc =
- EndPcFromCode(reinterpret_cast<RawCode*>(array.At(i)));
+ const auto end_pc = EndPcFromCode(static_cast<CodePtr>(array.At(i)));
pc_array[i] = end_pc - begin;
}
#if defined(DEBUG)
@@ -43,8 +45,8 @@
}
#endif // defined(DEBUG)
auto cache =
- new ReversePcLookupCache(isolate, pc_array, length, begin, end);
- isolate->set_reverse_pc_lookup_cache(cache);
+ new ReversePcLookupCache(isolate_group, pc_array, length, begin, end);
+ isolate_group->set_reverse_pc_lookup_cache(cache);
}
}
}
diff --git a/runtime/vm/reverse_pc_lookup_cache.h b/runtime/vm/reverse_pc_lookup_cache.h
index 7de0bff..d819956 100644
--- a/runtime/vm/reverse_pc_lookup_cache.h
+++ b/runtime/vm/reverse_pc_lookup_cache.h
@@ -43,21 +43,21 @@
// WARNING: This class cannot do memory allocation or handle allocation!
class ReversePcLookupCache {
public:
- ReversePcLookupCache(Isolate* isolate,
+ ReversePcLookupCache(IsolateGroup* isolate_group,
uint32_t* pc_array,
intptr_t length,
uword first_absolute_pc,
uword last_absolute_pc)
- : isolate_(isolate),
+ : isolate_group_(isolate_group),
pc_array_(pc_array),
length_(length),
first_absolute_pc_(first_absolute_pc),
last_absolute_pc_(last_absolute_pc) {}
~ReversePcLookupCache() { delete[] pc_array_; }
- // Builds a [ReversePcLookupCache] and attaches it to the isolate (if
+ // Builds a [ReversePcLookupCache] and attaches it to the isolate group (if
// `code_order_table` is non-`null`).
- static void BuildAndAttachToIsolate(Isolate* isolate);
+ static void BuildAndAttachToIsolateGroup(IsolateGroup* isolate_group);
// Returns `true` if the given [pc] contains can be mapped to a [Code] object
// using this cache.
@@ -70,7 +70,7 @@
// If [is_return_address] is true, then the PC may be immediately after the
// payload, if the last instruction is a call that is guaranteed not to
// return. Otherwise, the PC must be within the payload.
- inline RawCode* Lookup(uword pc, bool is_return_address = false) {
+ inline CodePtr Lookup(uword pc, bool is_return_address = false) {
NoSafepointScope no_safepoint_scope;
intptr_t left = 0;
@@ -98,8 +98,8 @@
}
}
- auto code_array = isolate_->object_store()->code_order_table();
- auto raw_code = reinterpret_cast<RawCode*>(Array::DataOf(code_array)[left]);
+ auto code_array = isolate_group_->object_store()->code_order_table();
+ auto raw_code = static_cast<CodePtr>(Array::DataOf(code_array)[left]);
#if defined(DEBUG)
ASSERT(raw_code->GetClassIdMayBeSmi() == kCodeCid);
@@ -110,7 +110,7 @@
}
private:
- Isolate* isolate_;
+ IsolateGroup* isolate_group_;
uint32_t* pc_array_;
intptr_t length_;
uword first_absolute_pc_;
@@ -124,11 +124,11 @@
ReversePcLookupCache() {}
~ReversePcLookupCache() {}
- static void BuildAndAttachToIsolate(Isolate* isolate) {}
+ static void BuildAndAttachToIsolateGroup(IsolateGroup* isolate_group) {}
inline bool Contains(uword pc) { return false; }
- inline RawCode* Lookup(uword pc, bool is_return_address = false) {
+ inline CodePtr Lookup(uword pc, bool is_return_address = false) {
UNREACHABLE();
}
};
diff --git a/runtime/vm/runtime_entry.cc b/runtime/vm/runtime_entry.cc
index ccf5867..46484be 100644
--- a/runtime/vm/runtime_entry.cc
+++ b/runtime/vm/runtime_entry.cc
@@ -115,8 +115,8 @@
Class::New(lib, class_name, script, TokenPosition::kNoSource));
const String& function_name = String::ZoneHandle(Symbols::New(thread, name));
const Function& function = Function::ZoneHandle(Function::New(
- function_name, RawFunction::kRegularFunction, true, false, false, false,
- false, owner_class, TokenPosition::kMinSource));
+ function_name, FunctionLayout::kRegularFunction, true, false, false,
+ false, false, owner_class, TokenPosition::kMinSource));
const Array& functions = Array::Handle(Array::New(1));
functions.SetAt(0, function);
owner_class.SetFunctions(functions);
@@ -323,14 +323,15 @@
}
}
-DEFINE_LEAF_RUNTIME_ENTRY(RawObject*,
+DEFINE_LEAF_RUNTIME_ENTRY(uword /*ObjectPtr*/,
AddAllocatedObjectToRememberedSet,
2,
- RawObject* object,
+ uword /*ObjectPtr*/ object_in,
Thread* thread) {
+ ObjectPtr object = static_cast<ObjectPtr>(object_in);
// The allocation stubs in will call this leaf method for newly allocated
// old space objects.
- RELEASE_ASSERT(object->IsOldObject() && !object->IsRemembered());
+ RELEASE_ASSERT(object->IsOldObject() && !object->ptr()->IsRemembered());
// If we eliminate a generational write barriers on allocations of an object
// we need to ensure it's either a new-space object or it has been added to
@@ -343,20 +344,19 @@
// in a long time).
bool add_to_remembered_set = true;
if (object->IsArray()) {
- const intptr_t length =
- Array::LengthOf(reinterpret_cast<RawArray*>(object));
+ const intptr_t length = Array::LengthOf(static_cast<ArrayPtr>(object));
add_to_remembered_set =
compiler::target::WillAllocateNewOrRememberedArray(length);
} else if (object->IsContext()) {
const intptr_t num_context_variables =
- Context::NumVariables(reinterpret_cast<RawContext*>(object));
+ Context::NumVariables(static_cast<ContextPtr>(object));
add_to_remembered_set =
compiler::target::WillAllocateNewOrRememberedContext(
num_context_variables);
}
if (add_to_remembered_set) {
- object->AddToRememberedSet(thread);
+ object->ptr()->AddToRememberedSet(thread);
}
// For incremental write barrier elimination, we need to ensure that the
@@ -366,7 +366,7 @@
thread->DeferredMarkingStackAddObject(object);
}
- return object;
+ return static_cast<uword>(object);
}
END_LEAF_RUNTIME_ENTRY
@@ -718,27 +718,36 @@
const auto& instance_class_name =
String::Handle(zone, instance_class.Name());
OS::PrintErr(
- " Updated test cache %p ix: %" Pd
- " with "
- "(cid-or-fun: %p, type-args: %p, i-type-args: %p, f-type-args: "
- "%p, "
- "p-type-args: %p, d-type-args: %p, result: %s)\n"
- " instance [class: (%p '%s' cid: %" Pd
- "), type-args: %p %s]\n"
- " test-type [class: (%p '%s' cid: %" Pd
- "), i-type-args: %p %s, f-type-args: %p %s]\n",
- new_cache.raw(), len, instance_class_id_or_function.raw(),
- instance_type_arguments.raw(), instantiator_type_arguments.raw(),
- function_type_arguments.raw(),
- instance_parent_function_type_arguments.raw(),
- instance_delayed_type_arguments.raw(), result.ToCString(),
- instance_class.raw(), instance_class_name.ToCString(),
- instance_class.id(), instance_type_arguments.raw(),
- instance_type_arguments.ToCString(), type_class.raw(),
+ " Updated test cache %#" Px " ix: %" Pd
+ " with (cid-or-fun:"
+ " %#" Px ", type-args: %#" Px ", i-type-args: %#" Px
+ ", "
+ "f-type-args: %#" Px ", p-type-args: %#" Px
+ ", "
+ "d-type-args: %#" Px
+ ", result: %s)\n"
+ " instance [class: (%#" Px " '%s' cid: %" Pd
+ "), type-args: %#" Px
+ " %s]\n"
+ " test-type [class: (%#" Px " '%s' cid: %" Pd
+ "), i-type-args: %#" Px " %s, f-type-args: %#" Px " %s]\n",
+ static_cast<uword>(new_cache.raw()), len,
+ static_cast<uword>(instance_class_id_or_function.raw()),
+ static_cast<uword>(instance_type_arguments.raw()),
+ static_cast<uword>(instantiator_type_arguments.raw()),
+ static_cast<uword>(function_type_arguments.raw()),
+ static_cast<uword>(instance_parent_function_type_arguments.raw()),
+ static_cast<uword>(instance_delayed_type_arguments.raw()),
+ result.ToCString(), static_cast<uword>(instance_class.raw()),
+ instance_class_name.ToCString(), instance_class.id(),
+ static_cast<uword>(instance_type_arguments.raw()),
+ instance_type_arguments.ToCString(),
+ static_cast<uword>(type_class.raw()),
String::Handle(zone, type_class.Name()).ToCString(),
- type_class.id(), instantiator_type_arguments.raw(),
+ type_class.id(),
+ static_cast<uword>(instantiator_type_arguments.raw()),
instantiator_type_arguments.ToCString(),
- function_type_arguments.raw(),
+ static_cast<uword>(function_type_arguments.raw()),
function_type_arguments.ToCString());
}
},
@@ -1102,7 +1111,7 @@
const Function& target_function =
Function::Handle(receiver_class.GetInvocationDispatcher(
target_name, arguments_descriptor,
- RawFunction::kInvokeFieldDispatcher, FLAG_lazy_dispatchers));
+ FunctionLayout::kInvokeFieldDispatcher, FLAG_lazy_dispatchers));
ASSERT(!target_function.IsNull() || !FLAG_lazy_dispatchers);
if (FLAG_trace_ic) {
OS::PrintErr(
@@ -1115,9 +1124,9 @@
}
// Handle other invocations (implicit closures, noSuchMethod).
-RawFunction* InlineCacheMissHelper(const Class& receiver_class,
- const Array& args_descriptor,
- const String& target_name) {
+FunctionPtr InlineCacheMissHelper(const Class& receiver_class,
+ const Array& args_descriptor,
+ const String& target_name) {
// Handle noSuchMethod for dyn:methodName by getting a noSuchMethod dispatcher
// (or a call-through getter for methodName).
if (Function::IsDynamicInvocationForwarderName(target_name)) {
@@ -1132,8 +1141,8 @@
ArgumentsDescriptor desc(args_descriptor);
const Function& target_function =
Function::Handle(receiver_class.GetInvocationDispatcher(
- target_name, args_descriptor, RawFunction::kNoSuchMethodDispatcher,
- FLAG_lazy_dispatchers));
+ target_name, args_descriptor,
+ FunctionLayout::kNoSuchMethodDispatcher, FLAG_lazy_dispatchers));
if (FLAG_trace_ic) {
OS::PrintErr(
"NoSuchMethod IC miss: adding <%s> id:%" Pd " -> <%s>\n",
@@ -1245,9 +1254,9 @@
}
// Perform the subtype and return constant function based on the result.
-static RawFunction* ComputeTypeCheckTarget(const Instance& receiver,
- const AbstractType& type,
- const ArgumentsDescriptor& desc) {
+static FunctionPtr ComputeTypeCheckTarget(const Instance& receiver,
+ const AbstractType& type,
+ const ArgumentsDescriptor& desc) {
const bool result = receiver.IsInstanceOf(type, Object::null_type_arguments(),
Object::null_type_arguments());
const ObjectStore* store = Isolate::Current()->object_store();
@@ -1258,7 +1267,7 @@
return target.raw();
}
-static RawFunction* InlineCacheMissHandler(
+static FunctionPtr InlineCacheMissHandler(
const GrowableArray<const Instance*>& args, // Checked arguments only.
const ICData& ic_data,
intptr_t count = 1) {
@@ -1502,10 +1511,10 @@
}
#if defined(DART_PRECOMPILED_RUNTIME)
-static RawUnlinkedCall* LoadUnlinkedCall(Zone* zone,
- Isolate* isolate,
- uword pc,
- bool is_monomorphic_hit) {
+static UnlinkedCallPtr LoadUnlinkedCall(Zone* zone,
+ Isolate* isolate,
+ uword pc,
+ bool is_monomorphic_hit) {
IsolateGroup* isolate_group = isolate->group();
ASSERT(isolate_group->saved_unlinked_calls() != Array::null());
@@ -1546,9 +1555,9 @@
void HandleMiss(const Object& old_data, const Code& old_target);
private:
- RawFunction* ResolveAndAddReceiverCheck(const String& name,
- const Array& descriptor,
- const ICData& ic_data);
+ FunctionPtr ResolveAndAddReceiverCheck(const String& name,
+ const Array& descriptor,
+ const ICData& ic_data);
void DoUnlinkedCall(const UnlinkedCall& unlinked);
bool CanExtendSingleTargetRange(const String& name,
const Function& old_target,
@@ -1570,7 +1579,7 @@
const Function& caller_function_;
};
-RawFunction* SwitchableCallHandler::ResolveAndAddReceiverCheck(
+FunctionPtr SwitchableCallHandler::ResolveAndAddReceiverCheck(
const String& name,
const Array& descriptor,
const ICData& ic_data) {
@@ -1691,13 +1700,13 @@
}
#if !defined(DART_PRECOMPILED_RUNTIME)
-static RawICData* FindICDataForInstanceCall(Zone* zone,
- const Code& code,
- uword pc) {
+static ICDataPtr FindICDataForInstanceCall(Zone* zone,
+ const Code& code,
+ uword pc) {
uword pc_offset = pc - code.PayloadStart();
const PcDescriptors& descriptors =
PcDescriptors::Handle(zone, code.pc_descriptors());
- PcDescriptors::Iterator iter(descriptors, RawPcDescriptors::kIcCall);
+ PcDescriptors::Iterator iter(descriptors, PcDescriptorsLayout::kIcCall);
intptr_t deopt_id = -1;
while (iter.MoveNext()) {
if (iter.PcOffset() == pc_offset) {
@@ -2235,8 +2244,8 @@
const Array& orig_arguments = Array::CheckedHandle(zone, arguments.ArgAt(3));
String& orig_function_name = String::Handle(zone);
- if ((function.kind() == RawFunction::kClosureFunction) ||
- (function.kind() == RawFunction::kImplicitClosureFunction)) {
+ if ((function.kind() == FunctionLayout::kClosureFunction) ||
+ (function.kind() == FunctionLayout::kImplicitClosureFunction)) {
// For closure the function name is always 'call'. Replace it with the
// name of the closurized function so that exception contains more
// relevant information.
@@ -2600,10 +2609,10 @@
StackFrameIterator::kNoCrossThreadIteration);
StackFrame* frame = iterator.NextFrame();
ASSERT(frame != NULL);
- OS::PrintErr("IC call @%#" Px ": ICData: %p cnt:%" Pd " nchecks: %" Pd
- " %s\n",
- frame->pc(), ic_data.raw(), function.usage_counter(),
- ic_data.NumberOfChecks(), function.ToFullyQualifiedCString());
+ OS::PrintErr(
+ "IC call @%#" Px ": ICData: %#" Px " cnt:%" Pd " nchecks: %" Pd " %s\n",
+ frame->pc(), static_cast<uword>(ic_data.raw()), function.usage_counter(),
+ ic_data.NumberOfChecks(), function.ToFullyQualifiedCString());
}
// This is called from interpreter when function usage counter reached
@@ -3247,27 +3256,20 @@
true /* is_float */,
reinterpret_cast<RuntimeFunction>(static_cast<UnaryMathCFunction>(&atan)));
-uword RuntimeEntry::InterpretCallEntry() {
- uword entry = reinterpret_cast<uword>(RuntimeEntry::InterpretCall);
-#if defined(USING_SIMULATOR)
- entry = Simulator::RedirectExternalReference(entry,
- Simulator::kLeafRuntimeCall, 5);
-#endif
- return entry;
-}
-
// Interpret a function call. Should be called only for non-jitted functions.
// argc indicates the number of arguments, including the type arguments.
// argv points to the first argument.
// If argc < 0, arguments are passed at decreasing memory addresses from argv.
-RawObject* RuntimeEntry::InterpretCall(RawFunction* function,
- RawArray* argdesc,
- intptr_t argc,
- RawObject** argv,
- Thread* thread) {
+extern "C" uword /*ObjectPtr*/ InterpretCall(uword /*FunctionPtr*/ function_in,
+ uword /*ArrayPtr*/ argdesc_in,
+ intptr_t argc,
+ ObjectPtr* argv,
+ Thread* thread) {
#if defined(DART_PRECOMPILED_RUNTIME)
UNREACHABLE();
#else
+ FunctionPtr function = static_cast<FunctionPtr>(function_in);
+ ArrayPtr argdesc = static_cast<ArrayPtr>(argdesc_in);
ASSERT(FLAG_enable_interpreter);
Interpreter* interpreter = Interpreter::Current();
#if defined(DEBUG)
@@ -3283,11 +3285,11 @@
#endif
// Tell MemorySanitizer 'argv' is initialized by generated code.
if (argc < 0) {
- MSAN_UNPOISON(argv - argc, -argc * sizeof(RawObject*));
+ MSAN_UNPOISON(argv - argc, -argc * sizeof(ObjectPtr));
} else {
- MSAN_UNPOISON(argv, argc * sizeof(RawObject*));
+ MSAN_UNPOISON(argv, argc * sizeof(ObjectPtr));
}
- RawObject* result = interpreter->Call(function, argdesc, argc, argv, thread);
+ ObjectPtr result = interpreter->Call(function, argdesc, argc, argv, thread);
DEBUG_ASSERT(thread->top_exit_frame_info() == exit_fp);
if (IsErrorClassId(result->GetClassIdMayBeSmi())) {
// Must not leak handles in the caller's zone.
@@ -3300,10 +3302,19 @@
TransitionGeneratedToVM transition(thread);
Exceptions::PropagateError(error);
}
- return result;
+ return static_cast<uword>(result);
#endif // defined(DART_PRECOMPILED_RUNTIME)
}
+uword RuntimeEntry::InterpretCallEntry() {
+ uword entry = reinterpret_cast<uword>(InterpretCall);
+#if defined(USING_SIMULATOR)
+ entry = Simulator::RedirectExternalReference(entry,
+ Simulator::kLeafRuntimeCall, 5);
+#endif
+ return entry;
+}
+
extern "C" void DFLRT_EnterSafepoint(NativeArguments __unusable_) {
CHECK_STACK_ALIGNMENT;
Thread* thread = Thread::Current();
diff --git a/runtime/vm/runtime_entry.h b/runtime/vm/runtime_entry.h
index 83d8a63..639cc8e 100644
--- a/runtime/vm/runtime_entry.h
+++ b/runtime/vm/runtime_entry.h
@@ -58,11 +58,6 @@
intptr_t argument_count) const);
static uword InterpretCallEntry();
- static RawObject* InterpretCall(RawFunction* function,
- RawArray* argdesc,
- intptr_t argc,
- RawObject** argv,
- Thread* thread);
protected:
NOT_IN_PRECOMPILED(static void CallInternal(const RuntimeEntry* runtime_entry,
diff --git a/runtime/vm/runtime_entry_list.h b/runtime/vm/runtime_entry_list.h
index e2773db..cf5ce11 100644
--- a/runtime/vm/runtime_entry_list.h
+++ b/runtime/vm/runtime_entry_list.h
@@ -57,15 +57,18 @@
V(CompileInterpretedFunction) \
V(SwitchableCallMiss)
+// Note: Leaf runtime function have C linkage, so they cannot pass C++ struct
+// values like ObjectPtr.
+
#define LEAF_RUNTIME_ENTRY_LIST(V) \
V(void, PrintStopMessage, const char*) \
V(intptr_t, DeoptimizeCopyFrame, uword, uword) \
V(void, DeoptimizeFillFrame, uword) \
V(void, StoreBufferBlockProcess, Thread*) \
V(void, MarkingStackBlockProcess, Thread*) \
- V(void, RememberCard, RawObject*, RawObject**) \
- V(RawObject*, AddAllocatedObjectToRememberedSet, RawObject* object, \
- Thread* thread) \
+ V(void, RememberCard, uword /*ObjectPtr*/, ObjectPtr*) \
+ V(uword /*ObjectPtr*/, AddAllocatedObjectToRememberedSet, \
+ uword /*ObjectPtr*/ object, Thread* thread) \
V(double, LibcPow, double, double) \
V(double, DartModulo, double, double) \
V(double, LibcFloor, double) \
@@ -79,12 +82,12 @@
V(double, LibcAsin, double) \
V(double, LibcAtan, double) \
V(double, LibcAtan2, double, double) \
- V(RawBool*, CaseInsensitiveCompareUCS2, RawString*, RawSmi*, RawSmi*, \
- RawSmi*) \
- V(RawBool*, CaseInsensitiveCompareUTF16, RawString*, RawSmi*, RawSmi*, \
- RawSmi*) \
+ V(uword /*BoolPtr*/, CaseInsensitiveCompareUCS2, uword /*StringPtr*/, \
+ uword /*SmiPtr*/, uword /*SmiPtr*/, uword /*SmiPtr*/) \
+ V(uword /*BoolPtr*/, CaseInsensitiveCompareUTF16, uword /*StringPtr*/, \
+ uword /*SmiPtr*/, uword /*SmiPtr*/, uword /*SmiPtr*/) \
V(void, EnterSafepoint) \
- V(void, ExitSafepoint) \
+ V(void, ExitSafepoint)
} // namespace dart
diff --git a/runtime/vm/scopes.cc b/runtime/vm/scopes.cc
index 99273cb..ca297b7 100644
--- a/runtime/vm/scopes.cc
+++ b/runtime/vm/scopes.cc
@@ -334,7 +334,7 @@
return str.CharAt(0) == ':';
}
-RawLocalVarDescriptors* LocalScope::GetVarDescriptors(
+LocalVarDescriptorsPtr LocalScope::GetVarDescriptors(
const Function& func,
ZoneGrowableArray<intptr_t>* context_level_array) {
LocalVarDescriptorsBuilder vars;
@@ -347,9 +347,9 @@
ASSERT(func.IsLocalFunction());
for (int i = 0; i < context_scope.num_variables(); i++) {
String& name = String::Handle(context_scope.NameAt(i));
- RawLocalVarDescriptors::VarInfoKind kind;
+ LocalVarDescriptorsLayout::VarInfoKind kind;
if (!IsFilteredIdentifier(name)) {
- kind = RawLocalVarDescriptors::kContextVar;
+ kind = LocalVarDescriptorsLayout::kContextVar;
} else {
continue;
}
@@ -386,7 +386,7 @@
// own context before calling a closure function.
LocalVarDescriptorsBuilder::VarDesc desc;
desc.name = &var->name();
- desc.info.set_kind(RawLocalVarDescriptors::kSavedCurrentContext);
+ desc.info.set_kind(LocalVarDescriptorsLayout::kSavedCurrentContext);
desc.info.scope_id = 0;
desc.info.declaration_pos = TokenPosition::kMinSource;
desc.info.begin_pos = TokenPosition::kMinSource;
@@ -398,12 +398,12 @@
LocalVarDescriptorsBuilder::VarDesc desc;
desc.name = &var->name();
if (var->is_captured()) {
- desc.info.set_kind(RawLocalVarDescriptors::kContextVar);
+ desc.info.set_kind(LocalVarDescriptorsLayout::kContextVar);
ASSERT(var->owner() != NULL);
ASSERT(var->owner()->context_level() >= 0);
desc.info.scope_id = var->owner()->context_level();
} else {
- desc.info.set_kind(RawLocalVarDescriptors::kStackVar);
+ desc.info.set_kind(LocalVarDescriptorsLayout::kStackVar);
desc.info.scope_id = *scope_id;
}
desc.info.set_index(var->index().value());
@@ -575,7 +575,7 @@
return num_captured;
}
-RawContextScope* LocalScope::PreserveOuterScope(
+ContextScopePtr LocalScope::PreserveOuterScope(
int current_context_level) const {
// Since code generation for nested functions is postponed until first
// invocation, the function level of the closure scope can only be 1.
@@ -691,7 +691,7 @@
}
}
-RawContextScope* LocalScope::CreateImplicitClosureScope(const Function& func) {
+ContextScopePtr LocalScope::CreateImplicitClosureScope(const Function& func) {
static const intptr_t kNumCapturedVars = 1;
// Create a ContextScope with space for kNumCapturedVars descriptors.
@@ -760,7 +760,7 @@
VarDesc desc;
desc.name = &Symbols::Empty(); // No name.
- desc.info.set_kind(RawLocalVarDescriptors::kContextLevel);
+ desc.info.set_kind(LocalVarDescriptorsLayout::kContextLevel);
desc.info.scope_id = 0;
desc.info.begin_pos = TokenPosition(start_deopt_id);
desc.info.end_pos = TokenPosition(end_deopt_id);
@@ -771,7 +771,7 @@
}
}
-RawLocalVarDescriptors* LocalVarDescriptorsBuilder::Done() {
+LocalVarDescriptorsPtr LocalVarDescriptorsBuilder::Done() {
if (vars_.is_empty()) {
return Object::empty_var_descriptors().raw();
}
diff --git a/runtime/vm/scopes.h b/runtime/vm/scopes.h
index a592cd6..6d6166f 100644
--- a/runtime/vm/scopes.h
+++ b/runtime/vm/scopes.h
@@ -237,7 +237,7 @@
public:
struct VarDesc {
const String* name;
- RawLocalVarDescriptors::VarInfo info;
+ LocalVarDescriptorsLayout::VarInfo info;
};
LocalVarDescriptorsBuilder() : vars_(8) {}
@@ -255,7 +255,7 @@
ZoneGrowableArray<intptr_t>* context_level_array);
// Finish building LocalVarDescriptor object.
- RawLocalVarDescriptors* Done();
+ LocalVarDescriptorsPtr Done();
private:
GrowableArray<VarDesc> vars_;
@@ -462,13 +462,13 @@
// Creates variable info for the scope and all its nested scopes.
// Must be called after AllocateVariables() has been called.
- RawLocalVarDescriptors* GetVarDescriptors(
+ LocalVarDescriptorsPtr GetVarDescriptors(
const Function& func,
ZoneGrowableArray<intptr_t>* context_level_array);
// Create a ContextScope object describing all captured variables referenced
// from this scope and belonging to outer scopes.
- RawContextScope* PreserveOuterScope(int current_context_level) const;
+ ContextScopePtr PreserveOuterScope(int current_context_level) const;
// Mark all local variables that are accessible from this scope up to
// top_scope (included) as captured unless they are marked as forced to stack.
@@ -482,7 +482,7 @@
// Create a ContextScope object which will capture "this" for an implicit
// closure object.
- static RawContextScope* CreateImplicitClosureScope(const Function& func);
+ static ContextScopePtr CreateImplicitClosureScope(const Function& func);
private:
// Allocate the variable in the current context, possibly updating the current
diff --git a/runtime/vm/service.cc b/runtime/vm/service.cc
index 4abd3ec..fafe51d 100644
--- a/runtime/vm/service.cc
+++ b/runtime/vm/service.cc
@@ -172,7 +172,7 @@
}
}
-RawObject* Service::RequestAssets() {
+ObjectPtr Service::RequestAssets() {
Thread* T = Thread::Current();
Object& object = Object::Handle();
{
@@ -223,11 +223,6 @@
param, js->LookupParam(param));
}
-static void PrintIllegalParamError(JSONStream* js, const char* param) {
- js->PrintError(kInvalidParams, "%s: illegal '%s' parameter: %s", js->method(),
- param, js->LookupParam(param));
-}
-
static void PrintUnrecognizedMethodError(JSONStream* js) {
js->PrintError(kMethodNotFound, NULL);
}
@@ -420,7 +415,7 @@
return class_table->IsValidIndex(cid) && class_table->HasValidClassAt(cid);
}
-static RawClass* GetClassForId(Isolate* isolate, intptr_t cid) {
+static ClassPtr GetClassForId(Isolate* isolate, intptr_t cid) {
ASSERT(isolate == Isolate::Current());
ASSERT(isolate != NULL);
ClassTable* class_table = isolate->class_table();
@@ -851,9 +846,9 @@
js.PostReply();
}
-RawError* Service::InvokeMethod(Isolate* I,
- const Array& msg,
- bool parameters_are_dart_objects) {
+ErrorPtr Service::InvokeMethod(Isolate* I,
+ const Array& msg,
+ bool parameters_are_dart_objects) {
Thread* T = Thread::Current();
ASSERT(I == T->isolate());
ASSERT(I != NULL);
@@ -962,17 +957,17 @@
}
}
-RawError* Service::HandleRootMessage(const Array& msg_instance) {
+ErrorPtr Service::HandleRootMessage(const Array& msg_instance) {
Isolate* isolate = Isolate::Current();
return InvokeMethod(isolate, msg_instance);
}
-RawError* Service::HandleObjectRootMessage(const Array& msg_instance) {
+ErrorPtr Service::HandleObjectRootMessage(const Array& msg_instance) {
Isolate* isolate = Isolate::Current();
return InvokeMethod(isolate, msg_instance, true);
}
-RawError* Service::HandleIsolateMessage(Isolate* isolate, const Array& msg) {
+ErrorPtr Service::HandleIsolateMessage(Isolate* isolate, const Array& msg) {
ASSERT(isolate != NULL);
const Error& error = Error::Handle(InvokeMethod(isolate, msg));
return MaybePause(isolate, error);
@@ -1668,9 +1663,9 @@
}
}
-static RawObject* LookupObjectId(Thread* thread,
- const char* arg,
- ObjectIdRing::LookupResult* kind) {
+static ObjectPtr LookupObjectId(Thread* thread,
+ const char* arg,
+ ObjectIdRing::LookupResult* kind) {
*kind = ObjectIdRing::kValid;
if (strncmp(arg, "int-", 4) == 0) {
arg += 4;
@@ -1700,9 +1695,9 @@
return ring->GetObjectForId(id, kind);
}
-static RawObject* LookupHeapObjectLibraries(Isolate* isolate,
- char** parts,
- int num_parts) {
+static ObjectPtr LookupHeapObjectLibraries(Isolate* isolate,
+ char** parts,
+ int num_parts) {
// Library ids look like "libraries/35"
if (num_parts < 2) {
return Object::sentinel().raw();
@@ -1766,9 +1761,9 @@
return Object::sentinel().raw();
}
-static RawObject* LookupHeapObjectClasses(Thread* thread,
- char** parts,
- int num_parts) {
+static ObjectPtr LookupHeapObjectClasses(Thread* thread,
+ char** parts,
+ int num_parts) {
// Class ids look like: "classes/17"
if (num_parts < 2) {
return Object::sentinel().raw();
@@ -1888,9 +1883,9 @@
return Object::sentinel().raw();
}
-static RawObject* LookupHeapObjectTypeArguments(Thread* thread,
- char** parts,
- int num_parts) {
+static ObjectPtr LookupHeapObjectTypeArguments(Thread* thread,
+ char** parts,
+ int num_parts) {
Isolate* isolate = thread->isolate();
// TypeArguments ids look like: "typearguments/17"
if (num_parts < 2) {
@@ -1911,9 +1906,9 @@
return table.At(id);
}
-static RawObject* LookupHeapObjectCode(Isolate* isolate,
- char** parts,
- int num_parts) {
+static ObjectPtr LookupHeapObjectCode(Isolate* isolate,
+ char** parts,
+ int num_parts) {
if (num_parts != 2) {
return Object::sentinel().raw();
}
@@ -1963,9 +1958,9 @@
return Object::sentinel().raw();
}
-static RawObject* LookupHeapObjectMessage(Thread* thread,
- char** parts,
- int num_parts) {
+static ObjectPtr LookupHeapObjectMessage(Thread* thread,
+ char** parts,
+ int num_parts) {
if (num_parts != 2) {
return Object::sentinel().raw();
}
@@ -1987,9 +1982,9 @@
}
}
-static RawObject* LookupHeapObject(Thread* thread,
- const char* id_original,
- ObjectIdRing::LookupResult* result) {
+static ObjectPtr LookupHeapObject(Thread* thread,
+ const char* id_original,
+ ObjectIdRing::LookupResult* result) {
char* id = thread->zone()->MakeCopyOfString(id_original);
// Parse the id by splitting at each '/'.
@@ -2202,7 +2197,7 @@
slot_offset.Value() - (Array::element_offset(0) >> kWordSizeLog2);
jselement.AddProperty("parentListIndex", element_index);
} else if (element.IsLinkedHashMap()) {
- map = static_cast<RawLinkedHashMap*>(path.At(i * 2));
+ map = static_cast<LinkedHashMapPtr>(path.At(i * 2));
map_data = map.data();
intptr_t element_index =
slot_offset.Value() - (Array::element_offset(0) >> kWordSizeLog2);
@@ -2875,7 +2870,7 @@
NULL,
};
-RawExternalTypedData* DecodeKernelBuffer(const char* kernel_buffer_base64) {
+ExternalTypedDataPtr DecodeKernelBuffer(const char* kernel_buffer_base64) {
intptr_t kernel_length;
uint8_t* kernel_buffer = DecodeBase64(kernel_buffer_base64, &kernel_length);
return ExternalTypedData::NewFinalizeWithFree(kernel_buffer, kernel_length);
@@ -3026,7 +3021,7 @@
: cls_(cls), storage_(storage), limit_(limit), count_(0) {}
virtual Direction VisitObject(ObjectGraph::StackIterator* it) {
- RawObject* raw_obj = it->Get();
+ ObjectPtr raw_obj = it->Get();
if (raw_obj->IsPseudoObject()) {
return kProceed;
}
@@ -3254,7 +3249,7 @@
BoolParameter::Parse(stream->LookupParam("pause"), false));
}
-RawError* Service::MaybePause(Isolate* isolate, const Error& error) {
+ErrorPtr Service::MaybePause(Isolate* isolate, const Error& error) {
// Don't pause twice.
if (!isolate->IsPaused()) {
if (isolate->should_pause_post_service_request()) {
@@ -3429,7 +3424,7 @@
return true;
}
-static RawClass* GetMetricsClass(Thread* thread) {
+static ClassPtr GetMetricsClass(Thread* thread) {
Zone* zone = thread->zone();
const Library& prof_lib = Library::Handle(zone, Library::DeveloperLibrary());
ASSERT(!prof_lib.IsNull());
@@ -4625,13 +4620,6 @@
BoolParameter::Parse(js->LookupParam("isDebuggable"), false);
if (obj.IsLibrary()) {
const Library& lib = Library::Cast(obj);
- if (lib.is_dart_scheme()) {
- const String& url = String::Handle(lib.url());
- if (url.StartsWith(Symbols::DartSchemePrivate())) {
- PrintIllegalParamError(js, "libraryId");
- return true;
- }
- }
lib.set_debuggable(is_debuggable);
PrintSuccess(js);
return true;
diff --git a/runtime/vm/service.h b/runtime/vm/service.h
index fdf87a4..4eedb96 100644
--- a/runtime/vm/service.h
+++ b/runtime/vm/service.h
@@ -10,11 +10,12 @@
#include "vm/allocation.h"
#include "vm/object_id_ring.h"
#include "vm/os_thread.h"
+#include "vm/tagged_pointer.h"
namespace dart {
#define SERVICE_PROTOCOL_MAJOR_VERSION 3
-#define SERVICE_PROTOCOL_MINOR_VERSION 30
+#define SERVICE_PROTOCOL_MINOR_VERSION 32
class Array;
class EmbedderServiceHandler;
@@ -27,8 +28,6 @@
class JSONStream;
class JSONObject;
class Object;
-class RawInstance;
-class RawError;
class ServiceEvent;
class String;
@@ -90,14 +89,14 @@
class Service : public AllStatic {
public:
// Handles a message which is not directed to an isolate.
- static RawError* HandleRootMessage(const Array& message);
+ static ErrorPtr HandleRootMessage(const Array& message);
// Handles a message which is not directed to an isolate and also
// expects the parameter keys and values to be actual dart objects.
- static RawError* HandleObjectRootMessage(const Array& message);
+ static ErrorPtr HandleObjectRootMessage(const Array& message);
// Handles a message which is directed to a particular isolate.
- static RawError* HandleIsolateMessage(Isolate* isolate, const Array& message);
+ static ErrorPtr HandleIsolateMessage(Isolate* isolate, const Array& message);
static void HandleEvent(ServiceEvent* event);
@@ -176,7 +175,7 @@
static bool ListenStream(const char* stream_id);
static void CancelStream(const char* stream_id);
- static RawObject* RequestAssets();
+ static ObjectPtr RequestAssets();
static Dart_ServiceStreamListenCallback stream_listen_callback() {
return stream_listen_callback_;
@@ -206,9 +205,9 @@
}
private:
- static RawError* InvokeMethod(Isolate* isolate,
- const Array& message,
- bool parameters_are_dart_objects = false);
+ static ErrorPtr InvokeMethod(Isolate* isolate,
+ const Array& message,
+ bool parameters_are_dart_objects = false);
static void EmbedderHandleMessage(EmbedderServiceHandler* handler,
JSONStream* js);
@@ -233,7 +232,7 @@
const char* kind,
JSONStream* event);
- static RawError* MaybePause(Isolate* isolate, const Error& error);
+ static ErrorPtr MaybePause(Isolate* isolate, const Error& error);
static EmbedderServiceHandler* isolate_service_handler_head_;
static EmbedderServiceHandler* root_service_handler_head_;
diff --git a/runtime/vm/service/service.md b/runtime/vm/service/service.md
index 06bec8d..4f6fcb0 100644
--- a/runtime/vm/service/service.md
+++ b/runtime/vm/service/service.md
@@ -1,8 +1,8 @@
-# Dart VM Service Protocol 3.30
+# Dart VM Service Protocol 3.32
> Please post feedback to the [observatory-discuss group][discuss-list]
-This document describes of _version 3.30_ of the Dart VM Service Protocol. This
+This document describes of _version 3.32_ of the Dart VM Service Protocol. This
protocol is used to communicate with a running Dart Virtual Machine.
To use the Service Protocol, start the VM with the *--observe* flag.
@@ -27,6 +27,7 @@
- [IDs and Names](#ids-and-names)
- [Versioning](#versioning)
- [Private RPCs, Types, and Properties](#private-rpcs-types-and-properties)
+- [Single Client Mode](#single-client-mode)
- [Public RPCs](#public-rpcs)
- [addBreakpoint](#addbreakpoint)
- [addBreakpointWithScriptUri](#addbreakpointwithscripturi)
@@ -405,6 +406,17 @@
implementation state and will never be appropriate to add to
the public api.
+## Single Client Mode
+
+The VM service allows for an extended feature set via the Dart Development
+Service (DDS) that forward all core VM service RPCs described in this
+document to the true VM service.
+
+When DDS connects to the VM service, the VM service enters single client
+mode and will no longer accept incoming web socket connections. If DDS
+disconnects from the VM service, the VM service will once again start accepting
+incoming web socket connections.
+
## Public RPCs
The following is a list of all public RPCs supported by the Service Protocol.
@@ -698,6 +710,20 @@
If _isolateId_ refers to an isolate which has exited, then the
_Collected_ [Sentinel](#sentinel) is returned.
+### getClassList
+
+```
+ClassList|Sentinel getClassList(string isolateId)
+```
+
+The _getClassList_ RPC is used to retrieve a _ClassList_ containing all
+classes for an isolate based on the isolate's _isolateId_.
+
+If _isolateId_ refers to an isolate which has exited, then the
+_Collected_ [Sentinel](#sentinel) is returned.
+
+See [ClassList](#classlist).
+
### getClientName
```
@@ -2135,18 +2161,18 @@
Inspect,
// Event from dart:developer.postEvent.
- Extension
+ Extension,
// Event from dart:developer.log.
- Logging
+ Logging,
- // Notification that a Service has been registered into the Service Protocol
+ // Notification that a Service has been registered into the Service Protocol
// from another client.
ServiceRegistered,
// Notification that a Service has been removed from the Service Protocol
// from another client.
- ServiceUnregistered
+ ServiceUnregistered,
}
```
@@ -3727,5 +3753,8 @@
3.28 | TODO(aam): document changes from 3.28
3.29 | Add `getClientName`, `setClientName`, `requireResumeApproval`
3.30 | Updated return types of RPCs which require an `isolateId` to allow for `Sentinel` results if the target isolate has shutdown.
+3.31 | Added single client mode, which allows for the Dart Development Service (DDS) to become the sole client of
+the VM service.
+3.32 | Added `getClassList` RPC and `ClassList` object.
[discuss-list]: https://groups.google.com/a/dartlang.org/forum/#!forum/observatory-discuss
diff --git a/runtime/vm/service_isolate.cc b/runtime/vm/service_isolate.cc
index 59aaf47..8b6e61a 100644
--- a/runtime/vm/service_isolate.cc
+++ b/runtime/vm/service_isolate.cc
@@ -48,9 +48,9 @@
#define VM_SERVICE_METHOD_CALL_FROM_NATIVE 5
-static RawArray* MakeServiceControlMessage(Dart_Port port_id,
- intptr_t code,
- const String& name) {
+static ArrayPtr MakeServiceControlMessage(Dart_Port port_id,
+ intptr_t code,
+ const String& name) {
const Array& list = Array::Handle(Array::New(4));
ASSERT(!list.IsNull());
const Integer& code_int = Integer::Handle(Integer::New(code));
@@ -63,9 +63,9 @@
return list.raw();
}
-static RawArray* MakeServerControlMessage(const SendPort& sp,
- intptr_t code,
- bool enable = false) {
+static ArrayPtr MakeServerControlMessage(const SendPort& sp,
+ intptr_t code,
+ bool enable = false) {
const Array& list = Array::Handle(Array::New(3));
ASSERT(!list.IsNull());
list.SetAt(0, Integer::Handle(Integer::New(code)));
diff --git a/runtime/vm/service_test.cc b/runtime/vm/service_test.cc
index 47f6060..11fb555 100644
--- a/runtime/vm/service_test.cc
+++ b/runtime/vm/service_test.cc
@@ -77,7 +77,7 @@
char* _msg;
};
-static RawArray* Eval(Dart_Handle lib, const char* expr) {
+static ArrayPtr Eval(Dart_Handle lib, const char* expr) {
const String& dummy_isolate_id = String::Handle(String::New("isolateId"));
Dart_Handle expr_val;
{
@@ -103,7 +103,7 @@
return result.raw();
}
-static RawArray* EvalF(Dart_Handle lib, const char* fmt, ...) {
+static ArrayPtr EvalF(Dart_Handle lib, const char* fmt, ...) {
va_list args;
va_start(args, fmt);
intptr_t len = Utils::VSNPrint(NULL, 0, fmt, args);
@@ -118,14 +118,14 @@
return Eval(lib, buffer);
}
-static RawFunction* GetFunction(const Class& cls, const char* name) {
+static FunctionPtr GetFunction(const Class& cls, const char* name) {
const Function& result = Function::Handle(
cls.LookupDynamicFunction(String::Handle(String::New(name))));
EXPECT(!result.IsNull());
return result.raw();
}
-static RawClass* GetClass(const Library& lib, const char* name) {
+static ClassPtr GetClass(const Library& lib, const char* name) {
const Class& cls = Class::Handle(
lib.LookupClass(String::Handle(Symbols::New(Thread::Current(), name))));
EXPECT(!cls.IsNull()); // No ambiguity error expected.
diff --git a/runtime/vm/simulator_arm.cc b/runtime/vm/simulator_arm.cc
index 4410cfb..5ceb7e4 100644
--- a/runtime/vm/simulator_arm.cc
+++ b/runtime/vm/simulator_arm.cc
@@ -230,7 +230,7 @@
uword pc_offset = pc - code.PayloadStart();
const PcDescriptors& descriptors =
PcDescriptors::Handle(code.pc_descriptors());
- PcDescriptors::Iterator iter(descriptors, RawPcDescriptors::kAnyKind);
+ PcDescriptors::Iterator iter(descriptors, PcDescriptorsLayout::kAnyKind);
while (iter.MoveNext()) {
if (iter.PcOffset() == pc_offset) {
return iter.TokenPos();
@@ -480,8 +480,7 @@
if (Isolate::Current()->heap()->Contains(value)) {
OS::PrintErr("%s: \n", arg1);
#if defined(DEBUG)
- const Object& obj =
- Object::Handle(reinterpret_cast<RawObject*>(value));
+ const Object& obj = Object::Handle(static_cast<ObjectPtr>(value));
obj.Print();
#endif // defined(DEBUG)
} else {
@@ -1394,8 +1393,8 @@
ASSERT(sizeof(NativeArguments) == 4 * kWordSize);
arguments.thread_ = reinterpret_cast<Thread*>(get_register(R0));
arguments.argc_tag_ = get_register(R1);
- arguments.argv_ = reinterpret_cast<RawObject**>(get_register(R2));
- arguments.retval_ = reinterpret_cast<RawObject**>(get_register(R3));
+ arguments.argv_ = reinterpret_cast<ObjectPtr*>(get_register(R2));
+ arguments.retval_ = reinterpret_cast<ObjectPtr*>(get_register(R3));
SimulatorRuntimeCall target =
reinterpret_cast<SimulatorRuntimeCall>(external);
target(arguments);
@@ -3646,7 +3645,7 @@
int32_t code =
*reinterpret_cast<int32_t*>(fp + kPcMarkerSlotFromFp * kWordSize);
int32_t pp = (FLAG_precompiled_mode && FLAG_use_bare_instructions)
- ? reinterpret_cast<int32_t>(thread->global_object_pool())
+ ? static_cast<int32_t>(thread->global_object_pool())
: *reinterpret_cast<int32_t*>(
(code + Code::object_pool_offset() - kHeapObjectTag));
diff --git a/runtime/vm/simulator_arm.h b/runtime/vm/simulator_arm.h
index 8f269b2..a682fb7 100644
--- a/runtime/vm/simulator_arm.h
+++ b/runtime/vm/simulator_arm.h
@@ -22,7 +22,6 @@
class Isolate;
class Mutex;
-class RawObject;
class SimulatorSetjmpBuffer;
class Thread;
diff --git a/runtime/vm/simulator_arm64.cc b/runtime/vm/simulator_arm64.cc
index 3ab2750..312c12f 100644
--- a/runtime/vm/simulator_arm64.cc
+++ b/runtime/vm/simulator_arm64.cc
@@ -258,7 +258,7 @@
uword pc_offset = pc - code.PayloadStart();
const PcDescriptors& descriptors =
PcDescriptors::Handle(code.pc_descriptors());
- PcDescriptors::Iterator iter(descriptors, RawPcDescriptors::kAnyKind);
+ PcDescriptors::Iterator iter(descriptors, PcDescriptorsLayout::kAnyKind);
while (iter.MoveNext()) {
if (iter.PcOffset() == pc_offset) {
return iter.TokenPos();
@@ -538,8 +538,7 @@
if (Isolate::Current()->heap()->Contains(value)) {
OS::PrintErr("%s: \n", arg1);
#if defined(DEBUG)
- const Object& obj =
- Object::Handle(reinterpret_cast<RawObject*>(value));
+ const Object& obj = Object::Handle(static_cast<ObjectPtr>(value));
obj.Print();
#endif // defined(DEBUG)
} else {
@@ -3585,7 +3584,7 @@
int64_t code =
*reinterpret_cast<int64_t*>(fp + kPcMarkerSlotFromFp * kWordSize);
int64_t pp = (FLAG_precompiled_mode && FLAG_use_bare_instructions)
- ? reinterpret_cast<int64_t>(thread->global_object_pool())
+ ? static_cast<int64_t>(thread->global_object_pool())
: *reinterpret_cast<int64_t*>(
code + Code::object_pool_offset() - kHeapObjectTag);
pp -= kHeapObjectTag; // In the PP register, the pool pointer is untagged.
diff --git a/runtime/vm/simulator_arm64.h b/runtime/vm/simulator_arm64.h
index 6663e32..3d00d23 100644
--- a/runtime/vm/simulator_arm64.h
+++ b/runtime/vm/simulator_arm64.h
@@ -22,7 +22,6 @@
class Isolate;
class Mutex;
-class RawObject;
class SimulatorSetjmpBuffer;
class Thread;
diff --git a/runtime/vm/snapshot.cc b/runtime/vm/snapshot.cc
index a8dbaee..7f100bb 100644
--- a/runtime/vm/snapshot.cc
+++ b/runtime/vm/snapshot.cc
@@ -34,7 +34,7 @@
// Check if this is a singleton object class which is shared by all isolates.
return ((class_id >= kClassCid && class_id <= kUnwindErrorCid) ||
(class_id == kTypeArgumentsCid) ||
- (class_id >= kNullCid && class_id <= kNeverCid));
+ (class_id >= kNullCid && class_id <= kVoidCid));
}
static bool IsBootstrapedClassId(intptr_t class_id) {
@@ -45,7 +45,7 @@
IsStringClassId(class_id) || IsTypedDataClassId(class_id) ||
IsExternalTypedDataClassId(class_id) ||
IsTypedDataViewClassId(class_id) || class_id == kNullCid ||
- class_id == kTransferableTypedDataCid);
+ class_id == kNeverCid || class_id == kTransferableTypedDataCid);
}
static bool IsObjectStoreTypeId(intptr_t index) {
@@ -75,7 +75,7 @@
return (class_id + kClassIdsOffset);
}
-static RawObject* GetType(ObjectStore* object_store, intptr_t index) {
+static ObjectPtr GetType(ObjectStore* object_store, intptr_t index) {
switch (index) {
case kLegacyObjectType:
return object_store->legacy_object_type();
@@ -83,6 +83,8 @@
return object_store->nullable_object_type();
case kNullType:
return object_store->null_type();
+ case kNeverType:
+ return object_store->never_type();
case kLegacyFunctionType:
return object_store->legacy_function_type();
case kLegacyNumberType:
@@ -150,11 +152,13 @@
}
static intptr_t GetTypeIndex(ObjectStore* object_store,
- const RawObject* raw_type) {
+ const ObjectPtr raw_type) {
if (raw_type == object_store->legacy_object_type()) {
return kLegacyObjectType;
} else if (raw_type == object_store->null_type()) {
return kNullType;
+ } else if (raw_type == object_store->never_type()) {
+ return kNeverType;
} else if (raw_type == object_store->legacy_function_type()) {
return kLegacyFunctionType;
} else if (raw_type == object_store->legacy_number_type()) {
@@ -254,9 +258,9 @@
return snapshot;
}
-RawSmi* BaseReader::ReadAsSmi() {
- RawSmi* value = Read<RawSmi*>();
- ASSERT((reinterpret_cast<uword>(value) & kSmiTagMask) == kSmiTag);
+SmiPtr BaseReader::ReadAsSmi() {
+ SmiPtr value = Read<SmiPtr>();
+ ASSERT((static_cast<uword>(value) & kSmiTagMask) == kSmiTag);
return value;
}
@@ -305,7 +309,7 @@
types_to_postprocess_(GrowableObjectArray::Handle(zone_)),
objects_to_rehash_(GrowableObjectArray::Handle(zone_)) {}
-RawObject* SnapshotReader::ReadObject() {
+ObjectPtr SnapshotReader::ReadObject() {
// Setup for long jump in case there is an exception while reading.
LongJumpScope jump;
if (setjmp(*jump.Set()) == 0) {
@@ -361,7 +365,7 @@
objects_to_rehash_.Add(map);
}
-RawObject* SnapshotReader::RunDelayedRehashingOfMaps() {
+ObjectPtr SnapshotReader::RunDelayedRehashingOfMaps() {
if (objects_to_rehash_.Length() > 0) {
const Library& collections_lib =
Library::Handle(zone_, Library::CollectionLibrary());
@@ -378,7 +382,7 @@
return Object::null();
}
-RawClass* SnapshotReader::ReadClassId(intptr_t object_id) {
+ClassPtr SnapshotReader::ReadClassId(intptr_t object_id) {
ASSERT(!Snapshot::IsFull(kind_));
// Read the class header information and lookup the class.
intptr_t class_header = Read<int32_t>();
@@ -410,8 +414,8 @@
return cls.raw();
}
-RawObject* SnapshotReader::ReadStaticImplicitClosure(intptr_t object_id,
- intptr_t class_header) {
+ObjectPtr SnapshotReader::ReadStaticImplicitClosure(intptr_t object_id,
+ intptr_t class_header) {
ASSERT(!Snapshot::IsFull(kind_));
// First create a function object and associate it with the specified
@@ -478,7 +482,7 @@
thread()->long_jump_base()->Jump(1, error);
}
-RawObject* SnapshotReader::VmIsolateSnapshotObject(intptr_t index) const {
+ObjectPtr SnapshotReader::VmIsolateSnapshotObject(intptr_t index) const {
return Object::vm_isolate_snapshot_object_table().At(index);
}
@@ -486,7 +490,7 @@
return isolate() == Dart::vm_isolate();
}
-RawObject* SnapshotReader::ReadObjectImpl(bool as_reference) {
+ObjectPtr SnapshotReader::ReadObjectImpl(bool as_reference) {
int64_t header_value = Read<int64_t>();
if ((header_value & kSmiTagMask) == kSmiTag) {
return NewInteger(header_value);
@@ -495,8 +499,8 @@
return ReadObjectImpl(static_cast<intptr_t>(header_value), as_reference);
}
-RawObject* SnapshotReader::ReadObjectImpl(intptr_t header_value,
- bool as_reference) {
+ObjectPtr SnapshotReader::ReadObjectImpl(intptr_t header_value,
+ bool as_reference) {
if (IsVMIsolateObject(header_value)) {
return ReadVMIsolateObject(header_value);
}
@@ -512,7 +516,7 @@
// Read the class header information.
intptr_t class_header = Read<int32_t>();
intptr_t tags = ReadTags();
- bool read_as_reference = as_reference && !RawObject::IsCanonical(tags);
+ bool read_as_reference = as_reference && !ObjectLayout::IsCanonical(tags);
intptr_t header_id = SerializedHeaderData::decode(class_header);
if (header_id == kInstanceObjectId) {
return ReadInstance(object_id, tags, read_as_reference);
@@ -536,7 +540,7 @@
#define SNAPSHOT_READ(clazz) case kTypedData##clazz##Cid:
CLASS_LIST_TYPED_DATA(SNAPSHOT_READ) {
- tags = RawObject::ClassIdTag::update(class_id, tags);
+ tags = ObjectLayout::ClassIdTag::update(class_id, tags);
pobj_ =
TypedData::ReadFrom(this, object_id, tags, kind_, read_as_reference);
break;
@@ -545,7 +549,7 @@
#define SNAPSHOT_READ(clazz) case kExternalTypedData##clazz##Cid:
CLASS_LIST_TYPED_DATA(SNAPSHOT_READ) {
- tags = RawObject::ClassIdTag::update(class_id, tags);
+ tags = ObjectLayout::ClassIdTag::update(class_id, tags);
pobj_ = ExternalTypedData::ReadFrom(this, object_id, tags, kind_, true);
break;
}
@@ -554,7 +558,7 @@
case kByteDataViewCid:
CLASS_LIST_TYPED_DATA(SNAPSHOT_READ) {
- tags = RawObject::ClassIdTag::update(class_id, tags);
+ tags = ObjectLayout::ClassIdTag::update(class_id, tags);
pobj_ = TypedDataView::ReadFrom(this, object_id, tags, kind_, true);
break;
}
@@ -574,9 +578,9 @@
objects_to_rehash_.Add(set);
}
-RawObject* SnapshotReader::ReadInstance(intptr_t object_id,
- intptr_t tags,
- bool as_reference) {
+ObjectPtr SnapshotReader::ReadInstance(intptr_t object_id,
+ intptr_t tags,
+ bool as_reference) {
// Object is regular dart instance.
intptr_t instance_size = 0;
Instance* result = NULL;
@@ -615,7 +619,7 @@
ASSERT(next_field_offset > 0);
// Instance::NextFieldOffset() returns the offset of the first field in
// a Dart object.
- bool read_as_reference = RawObject::IsCanonical(tags) ? false : true;
+ bool read_as_reference = ObjectLayout::IsCanonical(tags) ? false : true;
intptr_t offset = Instance::NextFieldOffset();
intptr_t result_cid = result->GetClassId();
@@ -651,7 +655,7 @@
}
offset += kWordSize;
}
- if (RawObject::IsCanonical(tags)) {
+ if (ObjectLayout::IsCanonical(tags)) {
const char* error_str = NULL;
*result = result->CheckAndCanonicalize(thread(), &error_str);
if (error_str != NULL) {
@@ -685,7 +689,7 @@
return NULL;
}
-RawApiError* SnapshotReader::VerifyVersionAndFeatures(Isolate* isolate) {
+ApiErrorPtr SnapshotReader::VerifyVersionAndFeatures(Isolate* isolate) {
// If the version string doesn't match, return an error.
// Note: New things are allocated only if we're going to return an error.
@@ -751,7 +755,7 @@
return ApiError::null();
}
-RawObject* SnapshotReader::NewInteger(int64_t value) {
+ObjectPtr SnapshotReader::NewInteger(int64_t value) {
ASSERT((value & kSmiTagMask) == kSmiTag);
value = value >> kSmiTagShift;
if (Smi::IsValid(value)) {
@@ -779,7 +783,7 @@
return obj; \
}
-RawObject* SnapshotReader::ReadVMIsolateObject(intptr_t header_value) {
+ObjectPtr SnapshotReader::ReadVMIsolateObject(intptr_t header_value) {
intptr_t object_id = GetVMIsolateObjectId(header_value);
// First check if it is one of the singleton objects.
@@ -791,7 +795,6 @@
READ_VM_SINGLETON_OBJ(kZeroArrayObject, Object::zero_array().raw());
READ_VM_SINGLETON_OBJ(kDynamicType, Object::dynamic_type().raw());
READ_VM_SINGLETON_OBJ(kVoidType, Object::void_type().raw());
- READ_VM_SINGLETON_OBJ(kNeverType, Object::never_type().raw());
READ_VM_SINGLETON_OBJ(kEmptyTypeArguments,
Object::empty_type_arguments().raw());
READ_VM_SINGLETON_OBJ(kTrueValue, Bool::True().raw());
@@ -839,7 +842,7 @@
return Symbols::GetPredefinedSymbol(object_id); // return VM symbol.
}
-RawObject* SnapshotReader::ReadIndexedObject(intptr_t object_id) {
+ObjectPtr SnapshotReader::ReadIndexedObject(intptr_t object_id) {
intptr_t class_id = ClassIdFromObjectId(object_id);
if (IsBootstrapedClassId(class_id)) {
return isolate()->class_table()->At(class_id); // get singleton class.
@@ -863,7 +866,7 @@
*TypeArgumentsHandle() ^= ReadObjectImpl(kAsInlinedObject);
result.SetTypeArguments(*TypeArgumentsHandle());
- bool as_reference = RawObject::IsCanonical(tags) ? false : true;
+ bool as_reference = ObjectLayout::IsCanonical(tags) ? false : true;
for (intptr_t i = 0; i < len; i++) {
*PassiveObjectHandle() = ReadObjectImpl(as_reference);
result.SetAt(i, *PassiveObjectHandle());
@@ -901,16 +904,20 @@
ASSERT(forward_list_ != NULL);
}
-void SnapshotWriter::WriteObject(RawObject* rawobj) {
+void SnapshotWriter::WriteObject(ObjectPtr rawobj) {
WriteObjectImpl(rawobj, kAsInlinedObject);
WriteForwardedObjects();
}
-uint32_t SnapshotWriter::GetObjectTags(RawObject* raw) {
+uint32_t SnapshotWriter::GetObjectTags(ObjectPtr raw) {
return raw->ptr()->tags_;
}
-uword SnapshotWriter::GetObjectTagsAndHash(RawObject* raw) {
+uint32_t SnapshotWriter::GetObjectTags(ObjectLayout* raw) {
+ return raw->tags_;
+}
+
+uword SnapshotWriter::GetObjectTagsAndHash(ObjectPtr raw) {
uword result = raw->ptr()->tags_;
#if defined(HASH_IN_OBJECT_HEADER)
result |= static_cast<uword>(raw->ptr()->hash_) << 32;
@@ -928,8 +935,8 @@
#define VM_OBJECT_WRITE(clazz) \
case clazz::kClassId: { \
object_id = forward_list_->AddObject(zone(), rawobj, kIsSerialized); \
- Raw##clazz* raw_obj = reinterpret_cast<Raw##clazz*>(rawobj); \
- raw_obj->WriteTo(this, object_id, kind(), false); \
+ clazz##Ptr raw_obj = static_cast<clazz##Ptr>(rawobj); \
+ raw_obj->ptr()->WriteTo(this, object_id, kind(), false); \
return true; \
}
@@ -939,7 +946,7 @@
return true; \
}
-bool SnapshotWriter::HandleVMIsolateObject(RawObject* rawobj) {
+bool SnapshotWriter::HandleVMIsolateObject(ObjectPtr rawobj) {
// Check if it is one of the singleton VM objects.
WRITE_VM_SINGLETON_OBJ(Object::null(), kNullObject);
WRITE_VM_SINGLETON_OBJ(Object::sentinel().raw(), kSentinelObject);
@@ -949,7 +956,6 @@
WRITE_VM_SINGLETON_OBJ(Object::zero_array().raw(), kZeroArrayObject);
WRITE_VM_SINGLETON_OBJ(Object::dynamic_type().raw(), kDynamicType);
WRITE_VM_SINGLETON_OBJ(Object::void_type().raw(), kVoidType);
- WRITE_VM_SINGLETON_OBJ(Object::never_type().raw(), kNeverType);
WRITE_VM_SINGLETON_OBJ(Object::empty_type_arguments().raw(),
kEmptyTypeArguments);
WRITE_VM_SINGLETON_OBJ(Bool::True().raw(), kTrueValue);
@@ -971,7 +977,7 @@
// all isolates.
intptr_t id = rawobj->GetClassId();
if (id == kClassCid) {
- RawClass* raw_class = reinterpret_cast<RawClass*>(rawobj);
+ ClassPtr raw_class = static_cast<ClassPtr>(rawobj);
intptr_t class_id = raw_class->ptr()->id_;
if (IsSingletonClassId(class_id)) {
intptr_t object_id = ObjectIdFromClassId(class_id);
@@ -1005,7 +1011,7 @@
return true;
} else {
// We do this check down here, because it's quite expensive.
- if (!rawobj->InVMIsolateHeap()) {
+ if (!rawobj->ptr()->InVMIsolateHeap()) {
return false;
}
@@ -1013,8 +1019,8 @@
VM_OBJECT_CLASS_LIST(VM_OBJECT_WRITE)
case kTypedDataUint32ArrayCid: {
object_id = forward_list_->AddObject(zone(), rawobj, kIsSerialized);
- RawTypedData* raw_obj = reinterpret_cast<RawTypedData*>(rawobj);
- raw_obj->WriteTo(this, object_id, kind(), false);
+ TypedDataPtr raw_obj = static_cast<TypedDataPtr>(rawobj);
+ raw_obj->ptr()->WriteTo(this, object_id, kind(), false);
return true;
}
default:
@@ -1046,7 +1052,7 @@
}
intptr_t ForwardList::AddObject(Zone* zone,
- RawObject* raw,
+ ObjectPtr raw,
SerializeState state) {
NoSafepointScope no_safepoint;
intptr_t object_id = next_object_id();
@@ -1060,14 +1066,14 @@
return object_id;
}
-intptr_t ForwardList::FindObject(RawObject* raw) {
+intptr_t ForwardList::FindObject(ObjectPtr raw) {
NoSafepointScope no_safepoint;
intptr_t id = GetObjectId(raw);
ASSERT(id == 0 || NodeForObjectId(id)->obj()->raw() == raw);
return (id == 0) ? static_cast<intptr_t>(kInvalidIndex) : id;
}
-void ForwardList::SetObjectId(RawObject* object, intptr_t id) {
+void ForwardList::SetObjectId(ObjectPtr object, intptr_t id) {
if (object->IsNewObject()) {
isolate()->forward_table_new()->SetValueExclusive(object, id);
} else {
@@ -1075,7 +1081,7 @@
}
}
-intptr_t ForwardList::GetObjectId(RawObject* object) {
+intptr_t ForwardList::GetObjectId(ObjectPtr object) {
if (object->IsNewObject()) {
return isolate()->forward_table_new()->GetValueExclusive(object);
} else {
@@ -1083,7 +1089,7 @@
}
}
-bool SnapshotWriter::CheckAndWritePredefinedObject(RawObject* rawobj) {
+bool SnapshotWriter::CheckAndWritePredefinedObject(ObjectPtr rawobj) {
// Check if object can be written in one of the following ways:
// - Smi: the Smi value is written as is (last bit is not tagged).
// - VM internal class (from VM isolate): (index of class in vm isolate | 0x3)
@@ -1093,7 +1099,7 @@
// First check if it is a Smi (i.e not a heap object).
if (!rawobj->IsHeapObject()) {
- Write<int64_t>(reinterpret_cast<intptr_t>(rawobj));
+ Write<int64_t>(static_cast<intptr_t>(rawobj));
return true;
}
@@ -1101,7 +1107,7 @@
if ((kind_ == Snapshot::kMessage) && (cid == kDoubleCid)) {
WriteVMIsolateObject(kDoubleObject);
- RawDouble* rd = reinterpret_cast<RawDouble*>(rawobj);
+ DoublePtr rd = static_cast<DoublePtr>(rawobj);
WriteDouble(rd->ptr()->value_);
return true;
}
@@ -1131,7 +1137,7 @@
// or a predefined internal VM class in the object store.
// Check if it is an internal VM class which is in the object store.
if (cid == kClassCid) {
- RawClass* raw_class = reinterpret_cast<RawClass*>(rawobj);
+ ClassPtr raw_class = static_cast<ClassPtr>(rawobj);
intptr_t class_id = raw_class->ptr()->id_;
if (IsBootstrapedClassId(class_id)) {
intptr_t object_id = ObjectIdFromClassId(class_id);
@@ -1150,7 +1156,7 @@
return false;
}
-void SnapshotWriter::WriteObjectImpl(RawObject* raw, bool as_reference) {
+void SnapshotWriter::WriteObjectImpl(ObjectPtr raw, bool as_reference) {
// First check if object can be written as a simple predefined type.
if (CheckAndWritePredefinedObject(raw)) {
return;
@@ -1158,7 +1164,7 @@
// When we know that we are dealing with leaf or shallow objects we write
// these objects inline even when 'as_reference' is true.
- const bool write_as_reference = as_reference && !raw->IsCanonical();
+ const bool write_as_reference = as_reference && !raw->ptr()->IsCanonical();
uintptr_t tags = GetObjectTagsAndHash(raw);
// Add object to the forward ref list and mark it so that future references
@@ -1178,14 +1184,14 @@
WriteMarkedObjectImpl(raw, tags, object_id, write_as_reference);
}
-void SnapshotWriter::WriteMarkedObjectImpl(RawObject* raw,
+void SnapshotWriter::WriteMarkedObjectImpl(ObjectPtr raw,
intptr_t tags,
intptr_t object_id,
bool as_reference) {
NoSafepointScope no_safepoint;
- RawClass* cls = class_table_->At(RawObject::ClassIdTag::decode(tags));
+ ClassPtr cls = class_table_->At(ObjectLayout::ClassIdTag::decode(tags));
intptr_t class_id = cls->ptr()->id_;
- ASSERT(class_id == RawObject::ClassIdTag::decode(tags));
+ ASSERT(class_id == ObjectLayout::ClassIdTag::decode(tags));
if (class_id >= kNumPredefinedCids || IsImplicitFieldClassId(class_id)) {
WriteInstance(raw, cls, tags, object_id, as_reference);
return;
@@ -1193,8 +1199,8 @@
switch (class_id) {
#define SNAPSHOT_WRITE(clazz) \
case clazz::kClassId: { \
- Raw##clazz* raw_obj = reinterpret_cast<Raw##clazz*>(raw); \
- raw_obj->WriteTo(this, object_id, kind_, as_reference); \
+ clazz##Ptr raw_obj = static_cast<clazz##Ptr>(raw); \
+ raw_obj->ptr()->WriteTo(this, object_id, kind_, as_reference); \
return; \
}
@@ -1203,17 +1209,16 @@
#define SNAPSHOT_WRITE(clazz) case kTypedData##clazz##Cid:
CLASS_LIST_TYPED_DATA(SNAPSHOT_WRITE) {
- RawTypedData* raw_obj = reinterpret_cast<RawTypedData*>(raw);
- raw_obj->WriteTo(this, object_id, kind_, as_reference);
+ TypedDataPtr raw_obj = static_cast<TypedDataPtr>(raw);
+ raw_obj->ptr()->WriteTo(this, object_id, kind_, as_reference);
return;
}
#undef SNAPSHOT_WRITE
#define SNAPSHOT_WRITE(clazz) case kExternalTypedData##clazz##Cid:
CLASS_LIST_TYPED_DATA(SNAPSHOT_WRITE) {
- RawExternalTypedData* raw_obj =
- reinterpret_cast<RawExternalTypedData*>(raw);
- raw_obj->WriteTo(this, object_id, kind_, as_reference);
+ ExternalTypedDataPtr raw_obj = static_cast<ExternalTypedDataPtr>(raw);
+ raw_obj->ptr()->WriteTo(this, object_id, kind_, as_reference);
return;
}
#undef SNAPSHOT_WRITE
@@ -1221,8 +1226,8 @@
case kByteDataViewCid:
CLASS_LIST_TYPED_DATA(SNAPSHOT_WRITE) {
- auto* raw_obj = reinterpret_cast<RawTypedDataView*>(raw);
- raw_obj->WriteTo(this, object_id, kind_, as_reference);
+ auto raw_obj = static_cast<TypedDataViewPtr>(raw);
+ raw_obj->ptr()->WriteTo(this, object_id, kind_, as_reference);
return;
}
#undef SNAPSHOT_WRITE
@@ -1249,10 +1254,10 @@
explicit WriteInlinedObjectVisitor(SnapshotWriter* writer)
: writer_(writer) {}
- virtual void VisitObject(RawObject* obj) {
+ virtual void VisitObject(ObjectPtr obj) {
intptr_t object_id = writer_->forward_list_->FindObject(obj);
ASSERT(object_id != kInvalidIndex);
- intptr_t tags = MessageWriter::GetObjectTagsAndHash(obj);
+ intptr_t tags = MessageWriter::GetObjectTagsAndHash(ObjectPtr(obj));
writer_->WriteMarkedObjectImpl(obj, tags, object_id, kAsInlinedObject);
}
@@ -1280,7 +1285,7 @@
++id) {
if (!NodeForObjectId(id)->is_serialized()) {
// Write the object out in the stream.
- RawObject* raw = NodeForObjectId(id)->obj()->raw();
+ ObjectPtr raw = NodeForObjectId(id)->obj()->raw();
writer->VisitObject(raw);
// Mark object as serialized.
@@ -1290,20 +1295,20 @@
first_unprocessed_object_id_ = next_object_id();
}
-void SnapshotWriter::WriteClassId(RawClass* cls) {
+void SnapshotWriter::WriteClassId(ClassLayout* cls) {
ASSERT(!Snapshot::IsFull(kind_));
int class_id = cls->ptr()->id_;
ASSERT(!IsSingletonClassId(class_id) && !IsBootstrapedClassId(class_id));
// Write out the library url and class name.
- RawLibrary* library = cls->ptr()->library_;
+ LibraryPtr library = cls->ptr()->library_;
ASSERT(library != Library::null());
WriteObjectImpl(library->ptr()->url_, kAsInlinedObject);
WriteObjectImpl(cls->ptr()->name_, kAsInlinedObject);
}
void SnapshotWriter::WriteStaticImplicitClosure(intptr_t object_id,
- RawFunction* func,
+ FunctionPtr func,
intptr_t tags) {
// Write out the serialization header value for this object.
WriteInlinedObjectHeader(object_id);
@@ -1315,9 +1320,9 @@
WriteTags(tags);
// Write out the library url, class name and signature function name.
- RawClass* cls = GetFunctionOwner(func);
+ ClassPtr cls = GetFunctionOwner(func);
ASSERT(cls != Class::null());
- RawLibrary* library = cls->ptr()->library_;
+ LibraryPtr library = cls->ptr()->library_;
ASSERT(library != Library::null());
WriteObjectImpl(library->ptr()->url_, kAsInlinedObject);
WriteObjectImpl(cls->ptr()->name_, kAsInlinedObject);
@@ -1327,9 +1332,9 @@
void SnapshotWriter::ArrayWriteTo(intptr_t object_id,
intptr_t array_kind,
intptr_t tags,
- RawSmi* length,
- RawTypeArguments* type_arguments,
- RawObject* data[],
+ SmiPtr length,
+ TypeArgumentsPtr type_arguments,
+ ObjectPtr data[],
bool as_reference) {
if (as_reference) {
// Write out the serialization header value for this object.
@@ -1340,7 +1345,7 @@
WriteTags(tags);
// Write out the length field.
- Write<RawObject*>(length);
+ Write<ObjectPtr>(length);
} else {
intptr_t len = Smi::Value(length);
@@ -1352,23 +1357,23 @@
WriteTags(tags);
// Write out the length field.
- Write<RawObject*>(length);
+ Write<ObjectPtr>(length);
// Write out the type arguments.
WriteObjectImpl(type_arguments, kAsInlinedObject);
// Write out the individual object ids.
- bool write_as_reference = RawObject::IsCanonical(tags) ? false : true;
+ bool write_as_reference = ObjectLayout::IsCanonical(tags) ? false : true;
for (intptr_t i = 0; i < len; i++) {
WriteObjectImpl(data[i], write_as_reference);
}
}
}
-RawFunction* SnapshotWriter::IsSerializableClosure(RawClosure* closure) {
+FunctionPtr SnapshotWriter::IsSerializableClosure(ClosurePtr closure) {
// Extract the function object to check if this closure
// can be sent in an isolate message.
- RawFunction* func = closure->ptr()->function_;
+ FunctionPtr func = closure->ptr()->function_;
// We only allow closure of top level methods or static functions in a
// class to be sent in isolate messages.
if (can_send_any_object() &&
@@ -1391,18 +1396,18 @@
return Function::null();
}
-RawClass* SnapshotWriter::GetFunctionOwner(RawFunction* func) {
- RawObject* owner = func->ptr()->owner_;
+ClassPtr SnapshotWriter::GetFunctionOwner(FunctionPtr func) {
+ ObjectPtr owner = func->ptr()->owner_;
uint32_t tags = GetObjectTags(owner);
- intptr_t class_id = RawObject::ClassIdTag::decode(tags);
+ intptr_t class_id = ObjectLayout::ClassIdTag::decode(tags);
if (class_id == kClassCid) {
- return reinterpret_cast<RawClass*>(owner);
+ return static_cast<ClassPtr>(owner);
}
ASSERT(class_id == kPatchClassCid);
- return reinterpret_cast<RawPatchClass*>(owner)->ptr()->patched_class_;
+ return static_cast<PatchClassPtr>(owner)->ptr()->patched_class_;
}
-void SnapshotWriter::CheckForNativeFields(RawClass* cls) {
+void SnapshotWriter::CheckForNativeFields(ClassPtr cls) {
if (cls->ptr()->num_native_fields_ != 0) {
// We do not allow objects with native fields in an isolate message.
HANDLESCOPE(thread());
@@ -1423,12 +1428,12 @@
thread()->long_jump_base()->Jump(1, Object::snapshot_writer_error());
}
-void SnapshotWriter::WriteInstance(RawObject* raw,
- RawClass* cls,
+void SnapshotWriter::WriteInstance(ObjectPtr raw,
+ ClassPtr cls,
intptr_t tags,
intptr_t object_id,
bool as_reference) {
- // Closure instances are handled by RawClosure::WriteTo().
+ // Closure instances are handled by ClosureLayout::WriteTo().
ASSERT(!Class::IsClosureClass(cls));
// Check if the instance has native fields and throw an exception if it does.
@@ -1469,7 +1474,7 @@
// Write out all the fields for the object.
// Instance::NextFieldOffset() returns the offset of the first field in
// a Dart object.
- bool write_as_reference = RawObject::IsCanonical(tags) ? false : true;
+ bool write_as_reference = ObjectLayout::IsCanonical(tags) ? false : true;
intptr_t offset = Instance::NextFieldOffset();
while (offset < next_field_offset) {
@@ -1479,7 +1484,7 @@
reinterpret_cast<uword>(raw->ptr()) + offset);
WriteWordWith32BitWrites(value);
} else {
- RawObject* raw_obj = *reinterpret_cast<RawObject**>(
+ ObjectPtr raw_obj = *reinterpret_cast<ObjectPtr*>(
reinterpret_cast<uword>(raw->ptr()) + offset);
WriteObjectImpl(raw_obj, write_as_reference);
}
@@ -1489,13 +1494,13 @@
return;
}
-bool SnapshotWriter::AllowObjectsInDartLibrary(RawLibrary* library) {
+bool SnapshotWriter::AllowObjectsInDartLibrary(LibraryPtr library) {
return (library == object_store()->collection_library() ||
library == object_store()->core_library() ||
library == object_store()->typed_data_library());
}
-intptr_t SnapshotWriter::FindVmSnapshotObject(RawObject* rawobj) {
+intptr_t SnapshotWriter::FindVmSnapshotObject(ObjectPtr rawobj) {
intptr_t length = Object::vm_isolate_snapshot_object_table().Length();
for (intptr_t i = 0; i < length; i++) {
if (Object::vm_isolate_snapshot_object_table().At(i) == rawobj) {
@@ -1509,7 +1514,7 @@
const char* msg) {
{
NoSafepointScope no_safepoint;
- RawError* error = thread()->StealStickyError();
+ ErrorPtr error = thread()->StealStickyError();
ASSERT(error == Object::snapshot_writer_error().raw());
}
@@ -1539,11 +1544,11 @@
free(const_cast<char*>(expected_features));
}
-void SnapshotWriterVisitor::VisitPointers(RawObject** first, RawObject** last) {
+void SnapshotWriterVisitor::VisitPointers(ObjectPtr* first, ObjectPtr* last) {
ASSERT(Utils::IsAligned(first, sizeof(*first)));
ASSERT(Utils::IsAligned(last, sizeof(*last)));
- for (RawObject** current = first; current <= last; current++) {
- RawObject* raw_obj = *current;
+ for (ObjectPtr* current = first; current <= last; current++) {
+ ObjectPtr raw_obj = *current;
writer_->WriteObjectImpl(raw_obj, as_references_);
}
}
diff --git a/runtime/vm/snapshot.h b/runtime/vm/snapshot.h
index ba40148..cb43fc2 100644
--- a/runtime/vm/snapshot.h
+++ b/runtime/vm/snapshot.h
@@ -43,61 +43,6 @@
class MegamorphicCache;
class PageSpace;
class TypedDataView;
-class RawApiError;
-class RawArray;
-class RawCapability;
-class RawClass;
-class RawClosure;
-class RawClosureData;
-class RawCodeSourceMap;
-class RawCompressedStackMaps;
-class RawContext;
-class RawContextScope;
-class RawDouble;
-class RawExceptionHandlers;
-class RawFfiTrampolineData;
-class RawField;
-class RawFloat32x4;
-class RawFloat64x2;
-class RawFunction;
-class RawGrowableObjectArray;
-class RawCallSiteData;
-class RawICData;
-class RawImmutableArray;
-class RawInstructions;
-class RawInt32x4;
-class RawRegExp;
-class RawLanguageError;
-class RawLibrary;
-class RawLibraryPrefix;
-class RawLinkedHashMap;
-class RawLocalVarDescriptors;
-class RawMegamorphicCache;
-class RawMint;
-class RawNamespace;
-class RawObject;
-class RawObjectPool;
-class RawOneByteString;
-class RawPatchClass;
-class RawPcDescriptors;
-class RawReceivePort;
-class RawRedirectionData;
-class RawNativeEntryData;
-class RawScript;
-class RawSignatureData;
-class RawSendPort;
-class RawSmi;
-class RawStackTrace;
-class RawSubtypeTestCache;
-class RawTwoByteString;
-class RawType;
-class RawTypeArguments;
-class RawTypedData;
-class RawTypedDataView;
-class RawTypeParameter;
-class RawTypeRef;
-class RawUnhandledException;
-class RawWeakProperty;
class String;
class TypeArguments;
class TypedData;
@@ -261,7 +206,7 @@
intptr_t PendingBytes() const { return stream_.PendingBytes(); }
- RawSmi* ReadAsSmi();
+ SmiPtr ReadAsSmi();
intptr_t ReadSmiValue();
// Negative header value indicates VM isolate object id.
@@ -325,7 +270,7 @@
Snapshot::Kind kind() const { return kind_; }
// Reads an object.
- RawObject* ReadObject();
+ ObjectPtr ReadObject();
// Add object to backward references.
void AddBackRef(intptr_t id, Object* obj, DeserializeState state);
@@ -334,9 +279,9 @@
Object* GetBackRef(intptr_t id);
// Read version number of snapshot and verify.
- RawApiError* VerifyVersionAndFeatures(Isolate* isolate);
+ ApiErrorPtr VerifyVersionAndFeatures(Isolate* isolate);
- RawObject* NewInteger(int64_t value);
+ ObjectPtr NewInteger(int64_t value);
protected:
SnapshotReader(const uint8_t* buffer,
@@ -358,24 +303,24 @@
void EnqueueRehashingOfMap(const LinkedHashMap& map);
void EnqueueRehashingOfSet(const Object& set);
- RawObject* RunDelayedRehashingOfMaps();
+ ObjectPtr RunDelayedRehashingOfMaps();
- RawClass* ReadClassId(intptr_t object_id);
- RawObject* ReadStaticImplicitClosure(intptr_t object_id, intptr_t cls_header);
+ ClassPtr ReadClassId(intptr_t object_id);
+ ObjectPtr ReadStaticImplicitClosure(intptr_t object_id, intptr_t cls_header);
// Implementation to read an object.
- RawObject* ReadObjectImpl(bool as_reference);
- RawObject* ReadObjectImpl(intptr_t header, bool as_reference);
+ ObjectPtr ReadObjectImpl(bool as_reference);
+ ObjectPtr ReadObjectImpl(intptr_t header, bool as_reference);
// Read a Dart Instance object.
- RawObject* ReadInstance(intptr_t object_id, intptr_t tags, bool as_reference);
+ ObjectPtr ReadInstance(intptr_t object_id, intptr_t tags, bool as_reference);
// Read a VM isolate object that was serialized as an Id.
- RawObject* ReadVMIsolateObject(intptr_t object_id);
+ ObjectPtr ReadVMIsolateObject(intptr_t object_id);
// Read an object that was serialized as an Id (singleton in object store,
// or an object that was already serialized before).
- RawObject* ReadIndexedObject(intptr_t object_id);
+ ObjectPtr ReadIndexedObject(intptr_t object_id);
// Decode class id from the header field.
intptr_t LookupInternalClass(intptr_t class_header);
@@ -389,7 +334,7 @@
void SetReadException(const char* msg);
- RawObject* VmIsolateSnapshotObject(intptr_t index) const;
+ ObjectPtr VmIsolateSnapshotObject(intptr_t index) const;
bool is_vm_isolate() const;
@@ -599,10 +544,10 @@
}
// Returns the id for the added object.
- intptr_t AddObject(Zone* zone, RawObject* raw, SerializeState state);
+ intptr_t AddObject(Zone* zone, ObjectPtr raw, SerializeState state);
// Returns the id for the object it it exists in the list.
- intptr_t FindObject(RawObject* raw);
+ intptr_t FindObject(ObjectPtr raw);
// Exhaustively processes all unserialized objects in this list. 'writer' may
// concurrently add more objects.
@@ -623,8 +568,8 @@
GrowableArray<Node*> nodes_;
intptr_t first_unprocessed_object_id_;
- void SetObjectId(RawObject* object, intptr_t id);
- intptr_t GetObjectId(RawObject* object);
+ void SetObjectId(ObjectPtr object, intptr_t id);
+ intptr_t GetObjectId(ObjectPtr object);
DISALLOW_COPY_AND_ASSIGN(ForwardList);
};
@@ -648,10 +593,11 @@
Heap* heap() const { return isolate()->heap(); }
// Serialize an object into the buffer.
- void WriteObject(RawObject* raw);
+ void WriteObject(ObjectPtr raw);
- static uint32_t GetObjectTags(RawObject* raw);
- static uword GetObjectTagsAndHash(RawObject* raw);
+ static uint32_t GetObjectTags(ObjectPtr raw);
+ static uint32_t GetObjectTags(ObjectLayout* raw);
+ static uword GetObjectTagsAndHash(ObjectPtr raw);
Exceptions::ExceptionType exception_type() const { return exception_type_; }
void set_exception_type(Exceptions::ExceptionType type) {
@@ -665,19 +611,19 @@
// Write a version string for the snapshot.
void WriteVersionAndFeatures();
- RawFunction* IsSerializableClosure(RawClosure* closure);
+ FunctionPtr IsSerializableClosure(ClosurePtr closure);
void WriteStaticImplicitClosure(intptr_t object_id,
- RawFunction* func,
+ FunctionPtr func,
intptr_t tags);
protected:
- bool CheckAndWritePredefinedObject(RawObject* raw);
- bool HandleVMIsolateObject(RawObject* raw);
+ bool CheckAndWritePredefinedObject(ObjectPtr raw);
+ bool HandleVMIsolateObject(ObjectPtr raw);
- void WriteClassId(RawClass* cls);
- void WriteObjectImpl(RawObject* raw, bool as_reference);
- void WriteMarkedObjectImpl(RawObject* raw,
+ void WriteClassId(ClassLayout* cls);
+ void WriteObjectImpl(ObjectPtr raw, bool as_reference);
+ void WriteMarkedObjectImpl(ObjectPtr raw,
intptr_t tags,
intptr_t object_id,
bool as_reference);
@@ -685,20 +631,20 @@
void ArrayWriteTo(intptr_t object_id,
intptr_t array_kind,
intptr_t tags,
- RawSmi* length,
- RawTypeArguments* type_arguments,
- RawObject* data[],
+ SmiPtr length,
+ TypeArgumentsPtr type_arguments,
+ ObjectPtr data[],
bool as_reference);
- RawClass* GetFunctionOwner(RawFunction* func);
- void CheckForNativeFields(RawClass* cls);
+ ClassPtr GetFunctionOwner(FunctionPtr func);
+ void CheckForNativeFields(ClassPtr cls);
void SetWriteException(Exceptions::ExceptionType type, const char* msg);
- void WriteInstance(RawObject* raw,
- RawClass* cls,
+ void WriteInstance(ObjectPtr raw,
+ ClassPtr cls,
intptr_t tags,
intptr_t object_id,
bool as_reference);
- bool AllowObjectsInDartLibrary(RawLibrary* library);
- intptr_t FindVmSnapshotObject(RawObject* rawobj);
+ bool AllowObjectsInDartLibrary(LibraryPtr library);
+ intptr_t FindVmSnapshotObject(ObjectPtr rawobj);
ObjectStore* object_store() const { return object_store_; }
@@ -712,37 +658,37 @@
const char* exception_msg_; // Message associated with exception.
bool can_send_any_object_; // True if any Dart instance can be sent.
- friend class RawArray;
- friend class RawClass;
- friend class RawClosureData;
- friend class RawCode;
- friend class RawContextScope;
- friend class RawDynamicLibrary;
- friend class RawExceptionHandlers;
- friend class RawField;
- friend class RawFunction;
- friend class RawGrowableObjectArray;
- friend class RawImmutableArray;
- friend class RawInstructions;
- friend class RawLibrary;
- friend class RawLinkedHashMap;
- friend class RawLocalVarDescriptors;
- friend class RawMirrorReference;
- friend class RawObjectPool;
- friend class RawPointer;
- friend class RawReceivePort;
- friend class RawRegExp;
- friend class RawScript;
- friend class RawStackTrace;
- friend class RawSubtypeTestCache;
- friend class RawTransferableTypedData;
- friend class RawType;
- friend class RawTypeArguments;
- friend class RawTypeParameter;
- friend class RawTypeRef;
- friend class RawTypedDataView;
- friend class RawUserTag;
- friend class RawWeakSerializationReference;
+ friend class ArrayLayout;
+ friend class ClassLayout;
+ friend class ClosureDataLayout;
+ friend class CodeLayout;
+ friend class ContextScopeLayout;
+ friend class DynamicLibraryLayout;
+ friend class ExceptionHandlersLayout;
+ friend class FieldLayout;
+ friend class FunctionLayout;
+ friend class GrowableObjectArrayLayout;
+ friend class ImmutableArrayLayout;
+ friend class InstructionsLayout;
+ friend class LibraryLayout;
+ friend class LinkedHashMapLayout;
+ friend class LocalVarDescriptorsLayout;
+ friend class MirrorReferenceLayout;
+ friend class ObjectPoolLayout;
+ friend class PointerLayout;
+ friend class ReceivePortLayout;
+ friend class RegExpLayout;
+ friend class ScriptLayout;
+ friend class StackTraceLayout;
+ friend class SubtypeTestCacheLayout;
+ friend class TransferableTypedDataLayout;
+ friend class TypeLayout;
+ friend class TypeArgumentsLayout;
+ friend class TypeParameterLayout;
+ friend class TypeRefLayout;
+ friend class TypedDataViewLayout;
+ friend class UserTagLayout;
+ friend class WeakSerializationReferenceLayout;
friend class SnapshotWriterVisitor;
friend class WriteInlinedObjectVisitor;
DISALLOW_COPY_AND_ASSIGN(SnapshotWriter);
@@ -791,7 +737,7 @@
writer_(writer),
as_references_(as_references) {}
- virtual void VisitPointers(RawObject** first, RawObject** last);
+ virtual void VisitPointers(ObjectPtr* first, ObjectPtr* last);
private:
SnapshotWriter* writer_;
diff --git a/runtime/vm/source_report.cc b/runtime/vm/source_report.cc
index 61505e1..4f5dcec 100644
--- a/runtime/vm/source_report.cc
+++ b/runtime/vm/source_report.cc
@@ -92,14 +92,14 @@
if (func.ForceOptimize()) return true;
switch (func.kind()) {
- case RawFunction::kRegularFunction:
- case RawFunction::kClosureFunction:
- case RawFunction::kImplicitClosureFunction:
- case RawFunction::kImplicitStaticGetter:
- case RawFunction::kFieldInitializer:
- case RawFunction::kGetterFunction:
- case RawFunction::kSetterFunction:
- case RawFunction::kConstructor:
+ case FunctionLayout::kRegularFunction:
+ case FunctionLayout::kClosureFunction:
+ case FunctionLayout::kImplicitClosureFunction:
+ case FunctionLayout::kImplicitStaticGetter:
+ case FunctionLayout::kFieldInitializer:
+ case FunctionLayout::kGetterFunction:
+ case FunctionLayout::kSetterFunction:
+ case FunctionLayout::kConstructor:
break;
default:
return true;
@@ -215,7 +215,7 @@
PcDescriptors::Iterator iter(
descriptors,
- RawPcDescriptors::kIcCall | RawPcDescriptors::kUnoptStaticCall);
+ PcDescriptorsLayout::kIcCall | PcDescriptorsLayout::kUnoptStaticCall);
while (iter.MoveNext()) {
HANDLESCOPE(thread());
ASSERT(iter.DeoptId() < ic_data_array->length());
@@ -266,7 +266,7 @@
PcDescriptors::Iterator iter(
descriptors,
- RawPcDescriptors::kIcCall | RawPcDescriptors::kUnoptStaticCall);
+ PcDescriptorsLayout::kIcCall | PcDescriptorsLayout::kUnoptStaticCall);
while (iter.MoveNext()) {
HANDLESCOPE(thread());
ASSERT(iter.DeoptId() < ic_data_array->length());
@@ -360,8 +360,8 @@
}
} else {
const uint8_t kSafepointKind =
- (RawPcDescriptors::kIcCall | RawPcDescriptors::kUnoptStaticCall |
- RawPcDescriptors::kRuntimeCall);
+ (PcDescriptorsLayout::kIcCall | PcDescriptorsLayout::kUnoptStaticCall |
+ PcDescriptorsLayout::kRuntimeCall);
const PcDescriptors& descriptors =
PcDescriptors::Handle(zone(), code.pc_descriptors());
@@ -572,7 +572,7 @@
for (int i = 0; i < functions.Length(); i++) {
func ^= functions.At(i);
// Skip getter functions of static const field.
- if (func.kind() == RawFunction::kImplicitStaticGetter) {
+ if (func.kind() == FunctionLayout::kImplicitStaticGetter) {
field ^= func.accessor_field();
if (field.is_const() && field.is_static()) {
continue;
diff --git a/runtime/vm/source_report_test.cc b/runtime/vm/source_report_test.cc
index 0187da5..44ae5e1 100644
--- a/runtime/vm/source_report_test.cc
+++ b/runtime/vm/source_report_test.cc
@@ -10,7 +10,7 @@
#ifndef PRODUCT
-static RawObject* ExecuteScript(const char* script, bool allow_errors = false) {
+static ObjectPtr ExecuteScript(const char* script, bool allow_errors = false) {
Dart_Handle lib;
{
TransitionVMToNative transition(Thread::Current());
diff --git a/runtime/vm/stack_frame.cc b/runtime/vm/stack_frame.cc
index 04309fe..a073259 100644
--- a/runtime/vm/stack_frame.cc
+++ b/runtime/vm/stack_frame.cc
@@ -106,28 +106,17 @@
#endif
}
-Isolate* StackFrame::IsolateOfBareInstructionsFrame(bool needed_for_gc) const {
- Isolate* isolate = Dart::vm_isolate();
- if (isolate->object_store()->code_order_table() != Object::null()) {
- auto rct = isolate->reverse_pc_lookup_cache();
- if (rct->Contains(pc())) return isolate;
+IsolateGroup* StackFrame::IsolateGroupOfBareInstructionsFrame() const {
+ IsolateGroup* isolate_group = Dart::vm_isolate()->group();
+ if (isolate_group->object_store()->code_order_table() != Object::null()) {
+ auto rct = isolate_group->reverse_pc_lookup_cache();
+ if (rct->Contains(pc())) return isolate_group;
}
- isolate = this->isolate();
- // The active isolate is null only during GC, in which case it does not matter
- // which isolate we use for the reverse-pc lookup table, since the metadata
- // is the same across all isolates.
- // TODO(dartbug.com/36097): Avoid having the [ReversePcLookupTable]
- // per-isolate. Right now we still need it per-isolate for non-GC cases, e.g.
- // for stack walking code which relies on finding owner functions of code
- // objects.
- if (isolate == nullptr) {
- ASSERT(needed_for_gc);
- isolate = isolate_group()->isolates_.First();
- }
- if (isolate->object_store()->code_order_table() != Object::null()) {
- auto rct = isolate->reverse_pc_lookup_cache();
- if (rct->Contains(pc())) return isolate;
+ isolate_group = this->isolate_group();
+ if (isolate_group->object_store()->code_order_table() != Object::null()) {
+ auto rct = isolate_group->reverse_pc_lookup_cache();
+ if (rct->Contains(pc())) return isolate_group;
}
return nullptr;
@@ -136,9 +125,9 @@
bool StackFrame::IsBareInstructionsDartFrame() const {
NoSafepointScope no_safepoint;
- if (auto isolate = IsolateOfBareInstructionsFrame(/*needed_for_gc=*/true)) {
+ if (auto isolate_group = IsolateGroupOfBareInstructionsFrame()) {
Code code;
- auto rct = isolate->reverse_pc_lookup_cache();
+ auto rct = isolate_group->reverse_pc_lookup_cache();
code = rct->Lookup(pc(), /*is_return_address=*/true);
auto const cid = code.OwnerClassId();
@@ -151,9 +140,9 @@
bool StackFrame::IsBareInstructionsStubFrame() const {
NoSafepointScope no_safepoint;
- if (auto isolate = IsolateOfBareInstructionsFrame(/*needed_for_gc=*/true)) {
+ if (auto isolate_group = IsolateGroupOfBareInstructionsFrame()) {
Code code;
- auto rct = isolate->reverse_pc_lookup_cache();
+ auto rct = isolate_group->reverse_pc_lookup_cache();
code = rct->Lookup(pc(), /*is_return_address=*/true);
auto const cid = code.OwnerClassId();
@@ -163,7 +152,7 @@
return false;
}
-bool StackFrame::IsStubFrame(bool needed_for_gc) const {
+bool StackFrame::IsStubFrame() const {
if (is_interpreted()) {
return false;
}
@@ -179,7 +168,7 @@
NoSafepointScope no_safepoint;
#endif
- RawCode* code = GetCodeObject(needed_for_gc);
+ CodePtr code = GetCodeObject();
ASSERT(code != Object::null());
auto const cid = Code::OwnerClassIdOf(code);
ASSERT(cid == kNullCid || cid == kClassCid || cid == kFunctionCid);
@@ -222,12 +211,12 @@
ASSERT(visitor != NULL);
// Visit pc marker and saved pool pointer, or, for interpreted frame, code
// object and function object.
- RawObject** last_fixed =
- reinterpret_cast<RawObject**>(fp()) +
+ ObjectPtr* last_fixed =
+ reinterpret_cast<ObjectPtr*>(fp()) +
(is_interpreted() ? kKBCLastFixedObjectSlotFromFp
: runtime_frame_layout.first_object_from_fp);
- RawObject** first_fixed =
- reinterpret_cast<RawObject**>(fp()) +
+ ObjectPtr* first_fixed =
+ reinterpret_cast<ObjectPtr*>(fp()) +
(is_interpreted() ? kKBCFirstObjectSlotFromFp
: runtime_frame_layout.last_fixed_object_from_fp);
if (first_fixed <= last_fixed) {
@@ -241,12 +230,12 @@
void EntryFrame::VisitObjectPointers(ObjectPointerVisitor* visitor) {
ASSERT(visitor != NULL);
// Visit objects between SP and (FP - callee_save_area).
- RawObject** first = is_interpreted() ? reinterpret_cast<RawObject**>(fp()) +
- kKBCSavedArgDescSlotFromEntryFp
- : reinterpret_cast<RawObject**>(sp());
- RawObject** last = is_interpreted() ? reinterpret_cast<RawObject**>(sp())
- : reinterpret_cast<RawObject**>(fp()) +
- kExitLinkSlotFromEntryFp - 1;
+ ObjectPtr* first = is_interpreted() ? reinterpret_cast<ObjectPtr*>(fp()) +
+ kKBCSavedArgDescSlotFromEntryFp
+ : reinterpret_cast<ObjectPtr*>(sp());
+ ObjectPtr* last = is_interpreted() ? reinterpret_cast<ObjectPtr*>(sp())
+ : reinterpret_cast<ObjectPtr*>(fp()) +
+ kExitLinkSlotFromEntryFp - 1;
// There may not be any pointer to visit; in this case, first > last.
visitor->VisitPointers(first, last);
}
@@ -262,11 +251,11 @@
NoSafepointScope no_safepoint;
Code code;
- if (auto isolate = IsolateOfBareInstructionsFrame(/*needed_for_gc=*/true)) {
- auto const rct = isolate->reverse_pc_lookup_cache();
+ if (auto isolate_group = IsolateGroupOfBareInstructionsFrame()) {
+ auto const rct = isolate_group->reverse_pc_lookup_cache();
code = rct->Lookup(pc(), /*is_return_address=*/true);
} else {
- RawObject* pc_marker = *(reinterpret_cast<RawObject**>(
+ ObjectPtr pc_marker = *(reinterpret_cast<ObjectPtr*>(
fp() + ((is_interpreted() ? kKBCPcMarkerSlotFromFp
: runtime_frame_layout.code_from_fp) *
kWordSize)));
@@ -305,8 +294,8 @@
if (is_interpreted()) {
UNIMPLEMENTED();
}
- RawObject** first = reinterpret_cast<RawObject**>(sp());
- RawObject** last = reinterpret_cast<RawObject**>(
+ ObjectPtr* first = reinterpret_cast<ObjectPtr*>(sp());
+ ObjectPtr* last = reinterpret_cast<ObjectPtr*>(
fp() + (runtime_frame_layout.first_local_from_fp * kWordSize));
// A stack map is present in the code object, use the stack map to
@@ -344,9 +333,9 @@
visitor->VisitPointers(first, last);
// Now visit other slots which might be part of the calling convention.
- first = reinterpret_cast<RawObject**>(
+ first = reinterpret_cast<ObjectPtr*>(
fp() + ((runtime_frame_layout.first_local_from_fp + 1) * kWordSize));
- last = reinterpret_cast<RawObject**>(
+ last = reinterpret_cast<ObjectPtr*>(
fp() + (runtime_frame_layout.first_object_from_fp * kWordSize));
visitor->VisitPointers(first, last);
return;
@@ -364,16 +353,16 @@
// between the first and last included are tagged objects.
if (is_interpreted()) {
// Do not visit caller's pc or caller's fp.
- RawObject** first =
- reinterpret_cast<RawObject**>(fp()) + kKBCFirstObjectSlotFromFp;
- RawObject** last =
- reinterpret_cast<RawObject**>(fp()) + kKBCLastFixedObjectSlotFromFp;
+ ObjectPtr* first =
+ reinterpret_cast<ObjectPtr*>(fp()) + kKBCFirstObjectSlotFromFp;
+ ObjectPtr* last =
+ reinterpret_cast<ObjectPtr*>(fp()) + kKBCLastFixedObjectSlotFromFp;
visitor->VisitPointers(first, last);
}
- RawObject** first =
- reinterpret_cast<RawObject**>(is_interpreted() ? fp() : sp());
- RawObject** last = reinterpret_cast<RawObject**>(
+ ObjectPtr* first =
+ reinterpret_cast<ObjectPtr*>(is_interpreted() ? fp() : sp());
+ ObjectPtr* last = reinterpret_cast<ObjectPtr*>(
is_interpreted()
? sp()
: fp() + (runtime_frame_layout.first_object_from_fp * kWordSize));
@@ -381,13 +370,13 @@
visitor->VisitPointers(first, last);
}
-RawFunction* StackFrame::LookupDartFunction() const {
+FunctionPtr StackFrame::LookupDartFunction() const {
if (is_interpreted()) {
- RawObject* result = *(reinterpret_cast<RawFunction**>(
+ ObjectPtr result = *(reinterpret_cast<FunctionPtr*>(
fp() + kKBCFunctionSlotFromFp * kWordSize));
ASSERT((result == Object::null()) ||
(result->GetClassId() == kFunctionCid));
- return reinterpret_cast<RawFunction*>(result);
+ return static_cast<FunctionPtr>(result);
}
const Code& code = Code::Handle(LookupDartCode());
if (!code.IsNull()) {
@@ -396,7 +385,7 @@
return Function::null();
}
-RawCode* StackFrame::LookupDartCode() const {
+CodePtr StackFrame::LookupDartCode() const {
// We add a no gc scope to ensure that the code below does not trigger
// a GC as we are handling raw object references here. It is possible
// that the code is called while a GC is in progress, that is ok.
@@ -405,33 +394,33 @@
// where Thread::Current() is NULL, so we cannot create a NoSafepointScope.
NoSafepointScope no_safepoint;
#endif
- if (auto isolate = IsolateOfBareInstructionsFrame(/*needed_for_gc=*/false)) {
- auto const rct = isolate->reverse_pc_lookup_cache();
+ if (auto isolate_group = IsolateGroupOfBareInstructionsFrame()) {
+ auto const rct = isolate_group->reverse_pc_lookup_cache();
return rct->Lookup(pc(), /*is_return_address=*/true);
}
- RawCode* code = GetCodeObject();
+ CodePtr code = GetCodeObject();
if ((code != Code::null()) && Code::OwnerClassIdOf(code) == kFunctionCid) {
return code;
}
return Code::null();
}
-RawCode* StackFrame::GetCodeObject(bool needed_for_gc) const {
+CodePtr StackFrame::GetCodeObject() const {
ASSERT(!is_interpreted());
- if (auto isolate = IsolateOfBareInstructionsFrame(needed_for_gc)) {
- auto const rct = isolate->reverse_pc_lookup_cache();
+ if (auto isolate_group = IsolateGroupOfBareInstructionsFrame()) {
+ auto const rct = isolate_group->reverse_pc_lookup_cache();
return rct->Lookup(pc(), /*is_return_address=*/true);
} else {
- RawObject* pc_marker = *(reinterpret_cast<RawObject**>(
+ ObjectPtr pc_marker = *(reinterpret_cast<ObjectPtr*>(
fp() + runtime_frame_layout.code_from_fp * kWordSize));
ASSERT((pc_marker == Object::null()) ||
(pc_marker->GetClassId() == kCodeCid));
- return reinterpret_cast<RawCode*>(pc_marker);
+ return static_cast<CodePtr>(pc_marker);
}
}
-RawBytecode* StackFrame::LookupDartBytecode() const {
+BytecodePtr StackFrame::LookupDartBytecode() const {
// We add a no gc scope to ensure that the code below does not trigger
// a GC as we are handling raw object references here. It is possible
// that the code is called while a GC is in progress, that is ok.
@@ -443,13 +432,13 @@
return GetBytecodeObject();
}
-RawBytecode* StackFrame::GetBytecodeObject() const {
+BytecodePtr StackFrame::GetBytecodeObject() const {
ASSERT(is_interpreted());
- RawObject* pc_marker = *(
- reinterpret_cast<RawObject**>(fp() + kKBCPcMarkerSlotFromFp * kWordSize));
+ ObjectPtr pc_marker = *(
+ reinterpret_cast<ObjectPtr*>(fp() + kKBCPcMarkerSlotFromFp * kWordSize));
ASSERT((pc_marker == Object::null()) ||
(pc_marker->GetClassId() == kBytecodeCid));
- return reinterpret_cast<RawBytecode*>(pc_marker);
+ return static_cast<BytecodePtr>(pc_marker);
}
bool StackFrame::FindExceptionHandler(Thread* thread,
@@ -499,7 +488,7 @@
try_index = bytecode.GetTryIndexAtPc(pc());
} else {
uword pc_offset = pc() - code.PayloadStart();
- PcDescriptors::Iterator iter(descriptors, RawPcDescriptors::kAnyKind);
+ PcDescriptors::Iterator iter(descriptors, PcDescriptorsLayout::kAnyKind);
while (iter.MoveNext()) {
const intptr_t current_try_index = iter.TryIndex();
if ((iter.PcOffset() == pc_offset) && (current_try_index != -1)) {
@@ -536,7 +525,7 @@
const PcDescriptors& descriptors =
PcDescriptors::Handle(code.pc_descriptors());
ASSERT(!descriptors.IsNull());
- PcDescriptors::Iterator iter(descriptors, RawPcDescriptors::kAnyKind);
+ PcDescriptors::Iterator iter(descriptors, PcDescriptorsLayout::kAnyKind);
while (iter.MoveNext()) {
if (iter.PcOffset() == pc_offset) {
return TokenPosition(iter.TokenPos());
@@ -545,8 +534,8 @@
return TokenPosition::kNoSource;
}
-bool StackFrame::IsValid(bool needed_for_gc) const {
- if (IsEntryFrame() || IsExitFrame() || IsStubFrame(needed_for_gc)) {
+bool StackFrame::IsValid() const {
+ if (IsEntryFrame() || IsExitFrame() || IsStubFrame()) {
return true;
}
if (is_interpreted()) {
diff --git a/runtime/vm/stack_frame.h b/runtime/vm/stack_frame.h
index 70fe3ed..1aeaa66 100644
--- a/runtime/vm/stack_frame.h
+++ b/runtime/vm/stack_frame.h
@@ -28,7 +28,6 @@
// Forward declarations.
class ObjectPointerVisitor;
-class RawContext;
class LocalVariable;
extern FrameLayout runtime_frame_layout;
@@ -81,8 +80,8 @@
pc_ = value;
}
- void set_pc_marker(RawCode* code) {
- *reinterpret_cast<RawCode**>(
+ void set_pc_marker(CodePtr code) {
+ *reinterpret_cast<CodePtr*>(
fp() + ((is_interpreted() ? kKBCPcMarkerSlotFromFp
: runtime_frame_layout.code_from_fp) *
kWordSize)) = code;
@@ -94,16 +93,14 @@
const char* ToCString() const;
// Check validity of a frame, used for assertion purposes.
- virtual bool IsValid(bool needed_for_gc = false) const;
+ virtual bool IsValid() const;
- // Returns the isolate containing the bare instructions of the current frame.
+ // Returns the isolate group containing the bare instructions of the
+ // current frame.
//
// If the frame does not belong to a bare instructions snapshot, it will
// return nullptr.
- //
- // [needed_for_gc] has to be set to `true` if the caller needs only GC
- // relevant information.
- Isolate* IsolateOfBareInstructionsFrame(bool needed_for_gc) const;
+ IsolateGroup* IsolateGroupOfBareInstructionsFrame() const;
// Returns true iff the current frame is a bare instructions dart frame.
bool IsBareInstructionsDartFrame() const;
@@ -112,20 +109,19 @@
bool IsBareInstructionsStubFrame() const;
// Frame type.
- virtual bool IsDartFrame(bool validate = true,
- bool needed_for_gc = false) const {
- ASSERT(!validate || IsValid(needed_for_gc));
- return !(IsEntryFrame() || IsExitFrame() || IsStubFrame(needed_for_gc));
+ virtual bool IsDartFrame(bool validate = true) const {
+ ASSERT(!validate || IsValid());
+ return !(IsEntryFrame() || IsExitFrame() || IsStubFrame());
}
- virtual bool IsStubFrame(bool neede_for_gc = false) const;
+ virtual bool IsStubFrame() const;
virtual bool IsEntryFrame() const { return false; }
virtual bool IsExitFrame() const { return false; }
virtual bool is_interpreted() const { return is_interpreted_; }
- RawFunction* LookupDartFunction() const;
- RawCode* LookupDartCode() const;
- RawBytecode* LookupDartBytecode() const;
+ FunctionPtr LookupDartFunction() const;
+ CodePtr LookupDartCode() const;
+ BytecodePtr LookupDartBytecode() const;
bool FindExceptionHandler(Thread* thread,
uword* handler_pc,
bool* needs_stacktrace,
@@ -159,9 +155,8 @@
Thread* thread() const { return thread_; }
private:
- RawCode* GetCodeObject(bool needed_for_gc = false) const;
- RawBytecode* GetBytecodeObject() const;
-
+ CodePtr GetCodeObject() const;
+ BytecodePtr GetBytecodeObject() const;
uword GetCallerFp() const {
return *(reinterpret_cast<uword*>(
@@ -200,11 +195,9 @@
// runtime code.
class ExitFrame : public StackFrame {
public:
- bool IsValid(bool needed_for_gc = false) const { return sp() == 0; }
- bool IsDartFrame(bool validate = true, bool needed_for_gc = false) const {
- return false;
- }
- bool IsStubFrame(bool needed_for_gc = false) const { return false; }
+ bool IsValid() const { return sp() == 0; }
+ bool IsDartFrame(bool validate = true) const { return false; }
+ bool IsStubFrame() const { return false; }
bool IsExitFrame() const { return true; }
// Visit objects in the frame.
@@ -224,13 +217,11 @@
// dart code.
class EntryFrame : public StackFrame {
public:
- bool IsValid(bool needed_for_gc = false) const {
+ bool IsValid() const {
return StubCode::InInvocationStub(pc(), is_interpreted());
}
- bool IsDartFrame(bool validate = true, bool needed_for_gc = false) const {
- return false;
- }
- bool IsStubFrame(bool needed_for_gc = false) const { return false; }
+ bool IsDartFrame(bool validate = true) const { return false; }
+ bool IsStubFrame() const { return false; }
bool IsEntryFrame() const { return true; }
// Visit objects in the frame.
@@ -416,7 +407,7 @@
bool Done() const { return index_ == -1; }
void Advance();
- RawFunction* function() const {
+ FunctionPtr function() const {
ASSERT(!Done());
return function_.raw();
}
@@ -426,7 +417,7 @@
return pc_;
}
- RawCode* code() const {
+ CodePtr code() const {
ASSERT(!Done());
return code_.raw();
}
diff --git a/runtime/vm/stack_trace.cc b/runtime/vm/stack_trace.cc
index c0d55b8..a9df9e1 100644
--- a/runtime/vm/stack_trace.cc
+++ b/runtime/vm/stack_trace.cc
@@ -18,9 +18,9 @@
// sdk/lib/async/stream_controller.dart:_StreamController._STATE_SUBSCRIBED.
const intptr_t kStreamController_StateSubscribed = 1;
-RawClosure* FindClosureInFrame(RawObject** last_object_in_caller,
- const Function& function,
- bool is_interpreted) {
+ClosurePtr FindClosureInFrame(ObjectPtr* last_object_in_caller,
+ const Function& function,
+ bool is_interpreted) {
NoSafepointScope nsp;
// The callee has function signature
@@ -32,7 +32,7 @@
auto& closure = Closure::Handle();
for (intptr_t i = 0; i < 4; i++) {
// KBC builds the stack upwards instead of the usual downwards stack.
- RawObject* arg = last_object_in_caller[(is_interpreted ? -i : i)];
+ ObjectPtr arg = last_object_in_caller[(is_interpreted ? -i : i)];
if (arg->IsHeapObject() && arg->GetClassId() == kClosureCid) {
closure = Closure::RawCast(arg);
if (closure.function() == function.raw()) {
@@ -49,7 +49,7 @@
intptr_t GetYieldIndex(const Closure& receiver_closure) {
const auto& function = Function::Handle(receiver_closure.function());
if (!function.IsAsyncClosure() && !function.IsAsyncGenClosure()) {
- return RawPcDescriptors::kInvalidYieldIndex;
+ return PcDescriptorsLayout::kInvalidYieldIndex;
}
const auto& await_jump_var =
Object::Handle(Context::Handle(receiver_closure.context())
@@ -59,10 +59,10 @@
}
intptr_t FindPcOffset(const PcDescriptors& pc_descs, intptr_t yield_index) {
- if (yield_index == RawPcDescriptors::kInvalidYieldIndex) {
+ if (yield_index == PcDescriptorsLayout::kInvalidYieldIndex) {
return 0;
}
- PcDescriptors::Iterator iter(pc_descs, RawPcDescriptors::kAnyKind);
+ PcDescriptors::Iterator iter(pc_descs, PcDescriptorsLayout::kAnyKind);
while (iter.MoveNext()) {
if (iter.YieldIndex() == yield_index) {
return iter.PcOffset();
@@ -73,7 +73,7 @@
#if !defined(DART_PRECOMPILED_RUNTIME)
intptr_t FindPcOffset(const Bytecode& bytecode, intptr_t yield_index) {
- if (yield_index == RawPcDescriptors::kInvalidYieldIndex) {
+ if (yield_index == PcDescriptorsLayout::kInvalidYieldIndex) {
return 0;
}
if (!bytecode.HasSourcePositions()) {
@@ -197,7 +197,7 @@
ASSERT(!state_data_field.IsNull());
}
- RawClosure* GetCallerInFutureImpl(const Object& future_) {
+ ClosurePtr GetCallerInFutureImpl(const Object& future_) {
ASSERT(!future_.IsNull());
ASSERT(future_.GetClassId() == future_impl_class.id());
@@ -217,7 +217,7 @@
return Closure::Cast(callback_).raw();
}
- RawClosure* FindCallerInAsyncClosure(const Context& receiver_context) {
+ ClosurePtr FindCallerInAsyncClosure(const Context& receiver_context) {
context_entry_ = receiver_context.At(Context::kAsyncCompleterIndex);
ASSERT(context_entry_.IsInstance());
ASSERT(context_entry_.GetClassId() == async_await_completer_class.id());
@@ -227,7 +227,7 @@
return GetCallerInFutureImpl(future_);
}
- RawClosure* FindCallerInAsyncGenClosure(const Context& receiver_context) {
+ ClosurePtr FindCallerInAsyncGenClosure(const Context& receiver_context) {
context_entry_ = receiver_context.At(Context::kControllerIndex);
ASSERT(context_entry_.IsInstance());
ASSERT(context_entry_.GetClassId() ==
@@ -277,7 +277,7 @@
UNREACHABLE(); // If no onData is found we have a bug.
}
- RawClosure* FindCaller(const Closure& receiver_closure) {
+ ClosurePtr FindCaller(const Closure& receiver_closure) {
receiver_function_ = receiver_closure.function();
receiver_context_ = receiver_closure.context();
@@ -401,13 +401,15 @@
if (frame->is_interpreted()) {
code_array.Add(bytecode);
const intptr_t pc_offset = frame->pc() - bytecode.PayloadStart();
- ASSERT(pc_offset >= 0 && pc_offset <= bytecode.Size());
+ ASSERT(pc_offset > 0 && pc_offset <= bytecode.Size());
offset = Smi::New(pc_offset);
} else {
code = frame->LookupDartCode();
ASSERT(function.raw() == code.function());
code_array.Add(code);
- offset = Smi::New(frame->pc() - code.PayloadStart());
+ const intptr_t pc_offset = frame->pc() - code.PayloadStart();
+ ASSERT(pc_offset > 0 && pc_offset <= code.Size());
+ offset = Smi::New(pc_offset);
}
pc_offset_array.Add(offset);
if (on_sync_frames != nullptr) {
@@ -424,8 +426,8 @@
// Next, look up caller's closure on the stack and walk backwards through
// the yields.
- RawObject** last_caller_obj = reinterpret_cast<RawObject**>(
- frame->GetCallerSp());
+ ObjectPtr* last_caller_obj =
+ reinterpret_cast<ObjectPtr*>(frame->GetCallerSp());
closure = FindClosureInFrame(last_caller_obj, function,
frame->is_interpreted());
@@ -466,6 +468,8 @@
} else {
UNREACHABLE();
}
+ // Unlike other sources of PC offsets, the offset may be 0 here if we
+ // reach a non-async closure receiving the yielded value.
ASSERT(offset.Value() >= 0);
pc_offset_array.Add(offset);
@@ -513,12 +517,13 @@
if (frame->is_interpreted()) {
bytecode = frame->LookupDartBytecode();
function = bytecode.function();
+ if (function.IsNull()) continue;
} else {
code = frame->LookupDartCode();
function = code.function();
}
- if (function.IsNull()) continue;
- if (sync_async_gap_frames > 0) {
+ const bool function_is_null = function.IsNull();
+ if (!function_is_null && sync_async_gap_frames > 0) {
function_name = function.QualifiedScrubbedName();
if (!CheckAndSkipAsync(&sync_async_gap_frames, function_name)) {
*sync_async_end = false;
@@ -527,7 +532,7 @@
} else {
frame_count++;
}
- if (!async_function_is_null &&
+ if (!async_function_is_null && !function_is_null &&
(async_function.raw() == function.parent_function())) {
sync_async_gap_frames = kSyncAsyncFrameGap;
}
diff --git a/runtime/vm/stub_code.cc b/runtime/vm/stub_code.cc
index 8f84851..bfe56d2 100644
--- a/runtime/vm/stub_code.cc
+++ b/runtime/vm/stub_code.cc
@@ -68,7 +68,7 @@
#undef STUB_CODE_GENERATE
#undef STUB_CODE_SET_OBJECT_POOL
-RawCode* StubCode::Generate(
+CodePtr StubCode::Generate(
const char* name,
compiler::ObjectPoolBuilder* object_pool_builder,
void (*GenerateStub)(compiler::Assembler* assembler)) {
@@ -128,7 +128,7 @@
}
#if !defined(DART_PRECOMPILED_RUNTIME)
-RawArray* compiler::StubCodeCompiler::BuildStaticCallsTable(
+ArrayPtr compiler::StubCodeCompiler::BuildStaticCallsTable(
Zone* zone,
compiler::UnresolvedPcRelativeCalls* unresolved_calls) {
if (unresolved_calls->length() == 0) {
@@ -156,7 +156,7 @@
}
#endif // !defined(DART_PRECOMPILED_RUNTIME)
-RawCode* StubCode::GetAllocationStubForClass(const Class& cls) {
+CodePtr StubCode::GetAllocationStubForClass(const Class& cls) {
Thread* thread = Thread::Current();
auto object_store = thread->isolate()->object_store();
Zone* zone = thread->zone();
@@ -258,7 +258,7 @@
}
#if !defined(TARGET_ARCH_IA32)
-RawCode* StubCode::GetBuildMethodExtractorStub(
+CodePtr StubCode::GetBuildMethodExtractorStub(
compiler::ObjectPoolBuilder* pool) {
#if !defined(DART_PRECOMPILED_RUNTIME)
auto thread = Thread::Current();
diff --git a/runtime/vm/stub_code.h b/runtime/vm/stub_code.h
index cffe96a..19fd413 100644
--- a/runtime/vm/stub_code.h
+++ b/runtime/vm/stub_code.h
@@ -21,7 +21,6 @@
class Code;
class Isolate;
class ObjectPointerVisitor;
-class RawCode;
class SnapshotReader;
class SnapshotWriter;
@@ -62,20 +61,18 @@
VM_STUB_CODE_LIST(STUB_CODE_ACCESSOR);
#undef STUB_CODE_ACCESSOR
- static RawCode* GetAllocationStubForClass(const Class& cls);
+ static CodePtr GetAllocationStubForClass(const Class& cls);
#if !defined(TARGET_ARCH_IA32)
- static RawCode* GetBuildMethodExtractorStub(
- compiler::ObjectPoolBuilder* pool);
+ static CodePtr GetBuildMethodExtractorStub(compiler::ObjectPoolBuilder* pool);
#endif
#if !defined(DART_PRECOMPILED_RUNTIME)
// Generate the stub and finalize the generated code into the stub
// code executable area.
- static RawCode* Generate(
- const char* name,
- compiler::ObjectPoolBuilder* object_pool_builder,
- void (*GenerateStub)(compiler::Assembler* assembler));
+ static CodePtr Generate(const char* name,
+ compiler::ObjectPoolBuilder* object_pool_builder,
+ void (*GenerateStub)(compiler::Assembler* assembler));
#endif // !defined(DART_PRECOMPILED_RUNTIME)
static const Code& UnoptimizedStaticCallEntry(intptr_t num_args_tested);
@@ -92,7 +89,7 @@
#if !defined(DART_PRECOMPILED_RUNTIME)
#define GENERATE_STUB(name) \
- static RawCode* BuildIsolateSpecific##name##Stub( \
+ static CodePtr BuildIsolateSpecific##name##Stub( \
compiler::ObjectPoolBuilder* opw) { \
return StubCode::Generate( \
"_iso_stub_" #name, opw, \
diff --git a/runtime/vm/stub_code_arm64_test.cc b/runtime/vm/stub_code_arm64_test.cc
index 76c37f0..0939ef2 100644
--- a/runtime/vm/stub_code_arm64_test.cc
+++ b/runtime/vm/stub_code_arm64_test.cc
@@ -29,8 +29,8 @@
const String& function_name =
String::ZoneHandle(Symbols::New(Thread::Current(), name));
Function& function = Function::ZoneHandle(Function::New(
- function_name, RawFunction::kRegularFunction, true, false, false, false,
- false, owner_class, TokenPosition::kNoSource));
+ function_name, FunctionLayout::kRegularFunction, true, false, false,
+ false, false, owner_class, TokenPosition::kNoSource));
return &function;
}
diff --git a/runtime/vm/stub_code_arm_test.cc b/runtime/vm/stub_code_arm_test.cc
index 6c1fcae..ea6a6bc 100644
--- a/runtime/vm/stub_code_arm_test.cc
+++ b/runtime/vm/stub_code_arm_test.cc
@@ -29,8 +29,8 @@
const String& function_name =
String::ZoneHandle(Symbols::New(Thread::Current(), name));
Function& function = Function::ZoneHandle(Function::New(
- function_name, RawFunction::kRegularFunction, true, false, false, false,
- false, owner_class, TokenPosition::kNoSource));
+ function_name, FunctionLayout::kRegularFunction, true, false, false,
+ false, false, owner_class, TokenPosition::kNoSource));
return &function;
}
diff --git a/runtime/vm/stub_code_ia32_test.cc b/runtime/vm/stub_code_ia32_test.cc
index e8f412d..b5c4388 100644
--- a/runtime/vm/stub_code_ia32_test.cc
+++ b/runtime/vm/stub_code_ia32_test.cc
@@ -29,8 +29,8 @@
const String& function_name =
String::ZoneHandle(Symbols::New(Thread::Current(), name));
Function& function = Function::ZoneHandle(Function::New(
- function_name, RawFunction::kRegularFunction, true, false, false, false,
- false, owner_class, TokenPosition::kMinSource));
+ function_name, FunctionLayout::kRegularFunction, true, false, false,
+ false, false, owner_class, TokenPosition::kMinSource));
return &function;
}
diff --git a/runtime/vm/stub_code_x64_test.cc b/runtime/vm/stub_code_x64_test.cc
index 39836c8..b41ec88 100644
--- a/runtime/vm/stub_code_x64_test.cc
+++ b/runtime/vm/stub_code_x64_test.cc
@@ -29,8 +29,8 @@
const String& function_name =
String::ZoneHandle(Symbols::New(Thread::Current(), name));
Function& function = Function::ZoneHandle(Function::New(
- function_name, RawFunction::kRegularFunction, true, false, false, false,
- false, owner_class, TokenPosition::kNoSource));
+ function_name, FunctionLayout::kRegularFunction, true, false, false,
+ false, false, owner_class, TokenPosition::kNoSource));
return &function;
}
diff --git a/runtime/vm/symbols.cc b/runtime/vm/symbols.cc
index bf4e645..04339dd 100644
--- a/runtime/vm/symbols.cc
+++ b/runtime/vm/symbols.cc
@@ -18,7 +18,7 @@
namespace dart {
-RawString* Symbols::predefined_[Symbols::kNumberOfOneCharCodeSymbols];
+StringPtr Symbols::predefined_[Symbols::kNumberOfOneCharCodeSymbols];
String* Symbols::symbol_handles_[Symbols::kMaxPredefinedId];
static const char* names[] = {
@@ -35,15 +35,15 @@
// clang-format on
};
-RawString* StringFrom(const uint8_t* data, intptr_t len, Heap::Space space) {
+StringPtr StringFrom(const uint8_t* data, intptr_t len, Heap::Space space) {
return String::FromLatin1(data, len, space);
}
-RawString* StringFrom(const uint16_t* data, intptr_t len, Heap::Space space) {
+StringPtr StringFrom(const uint16_t* data, intptr_t len, Heap::Space space) {
return String::FromUTF16(data, len, space);
}
-RawString* StringFrom(const int32_t* data, intptr_t len, Heap::Space space) {
+StringPtr StringFrom(const int32_t* data, intptr_t len, Heap::Space space) {
return String::FromUTF32(data, len, space);
}
@@ -53,7 +53,7 @@
CharArray(const CharType* data, intptr_t len) : data_(data), len_(len) {
hash_ = String::Hash(data, len);
}
- RawString* ToSymbol() const {
+ StringPtr ToSymbol() const {
String& result = String::Handle(StringFrom(data_, len_, Heap::kOld));
result.SetCanonical();
result.SetHash(hash_);
@@ -83,7 +83,7 @@
: str_(str), begin_index_(begin_index), len_(length) {
hash_ = is_all() ? str.Hash() : String::Hash(str, begin_index, length);
}
- RawString* ToSymbol() const;
+ StringPtr ToSymbol() const;
bool Equals(const String& other) const {
ASSERT(other.HasHash());
if (other.Hash() != hash_) {
@@ -101,7 +101,7 @@
intptr_t hash_;
};
-RawString* StringSlice::ToSymbol() const {
+StringPtr StringSlice::ToSymbol() const {
if (is_all() && str_.IsOld()) {
str_.SetCanonical();
return str_.raw();
@@ -118,7 +118,7 @@
public:
ConcatString(const String& str1, const String& str2)
: str1_(str1), str2_(str2), hash_(String::HashConcat(str1, str2)) {}
- RawString* ToSymbol() const;
+ StringPtr ToSymbol() const;
bool Equals(const String& other) const {
ASSERT(other.HasHash());
if (other.Hash() != hash_) {
@@ -134,7 +134,7 @@
intptr_t hash_;
};
-RawString* ConcatString::ToSymbol() const {
+StringPtr ConcatString::ToSymbol() const {
String& result = String::Handle(String::Concat(str1_, str2_, Heap::kOld));
result.SetCanonical();
result.SetHash(hash_);
@@ -179,13 +179,11 @@
static uword Hash(const StringSlice& slice) { return slice.Hash(); }
static uword Hash(const ConcatString& concat) { return concat.Hash(); }
template <typename CharType>
- static RawObject* NewKey(const CharArray<CharType>& array) {
+ static ObjectPtr NewKey(const CharArray<CharType>& array) {
return array.ToSymbol();
}
- static RawObject* NewKey(const StringSlice& slice) {
- return slice.ToSymbol();
- }
- static RawObject* NewKey(const ConcatString& concat) {
+ static ObjectPtr NewKey(const StringSlice& slice) { return slice.ToSymbol(); }
+ static ObjectPtr NewKey(const ConcatString& concat) {
return concat.ToSymbol();
}
};
@@ -242,7 +240,7 @@
*str = OneByteString::New(&ch, 1, Heap::kOld);
str->Hash();
*str ^= table.InsertOrGet(*str);
- ASSERT(predefined_[c] == NULL);
+ ASSERT(predefined_[c] == nullptr);
str->SetCanonical(); // Make canonical once entered.
predefined_[c] = str->raw();
symbol_handles_[idx] = str;
@@ -331,8 +329,8 @@
type_args_(type_args),
zone_(thread->zone()) {}
- void VisitObject(RawObject* obj) {
- if (obj->IsCanonical()) {
+ void VisitObject(ObjectPtr obj) {
+ if (obj->ptr()->IsCanonical()) {
if (obj->IsStringInstance()) {
symbols_->Add(&String::Handle(zone_, String::RawCast(obj)));
} else if (obj->IsType()) {
@@ -413,15 +411,15 @@
table.Release();
}
-RawString* Symbols::New(Thread* thread, const char* cstr, intptr_t len) {
+StringPtr Symbols::New(Thread* thread, const char* cstr, intptr_t len) {
ASSERT((cstr != NULL) && (len >= 0));
const uint8_t* utf8_array = reinterpret_cast<const uint8_t*>(cstr);
return Symbols::FromUTF8(thread, utf8_array, len);
}
-RawString* Symbols::FromUTF8(Thread* thread,
- const uint8_t* utf8_array,
- intptr_t array_len) {
+StringPtr Symbols::FromUTF8(Thread* thread,
+ const uint8_t* utf8_array,
+ intptr_t array_len) {
if (array_len == 0 || utf8_array == NULL) {
return FromLatin1(thread, reinterpret_cast<uint8_t*>(NULL), 0);
}
@@ -446,27 +444,27 @@
return FromUTF16(thread, characters, len);
}
-RawString* Symbols::FromLatin1(Thread* thread,
- const uint8_t* latin1_array,
- intptr_t len) {
+StringPtr Symbols::FromLatin1(Thread* thread,
+ const uint8_t* latin1_array,
+ intptr_t len) {
return NewSymbol(thread, Latin1Array(latin1_array, len));
}
-RawString* Symbols::FromUTF16(Thread* thread,
- const uint16_t* utf16_array,
- intptr_t len) {
+StringPtr Symbols::FromUTF16(Thread* thread,
+ const uint16_t* utf16_array,
+ intptr_t len) {
return NewSymbol(thread, UTF16Array(utf16_array, len));
}
-RawString* Symbols::FromUTF32(Thread* thread,
- const int32_t* utf32_array,
- intptr_t len) {
+StringPtr Symbols::FromUTF32(Thread* thread,
+ const int32_t* utf32_array,
+ intptr_t len) {
return NewSymbol(thread, UTF32Array(utf32_array, len));
}
-RawString* Symbols::FromConcat(Thread* thread,
- const String& str1,
- const String& str2) {
+StringPtr Symbols::FromConcat(Thread* thread,
+ const String& str1,
+ const String& str2) {
if (str1.Length() == 0) {
return New(thread, str2);
} else if (str2.Length() == 0) {
@@ -476,22 +474,22 @@
}
}
-RawString* Symbols::FromGet(Thread* thread, const String& str) {
+StringPtr Symbols::FromGet(Thread* thread, const String& str) {
return FromConcat(thread, GetterPrefix(), str);
}
-RawString* Symbols::FromSet(Thread* thread, const String& str) {
+StringPtr Symbols::FromSet(Thread* thread, const String& str) {
return FromConcat(thread, SetterPrefix(), str);
}
-RawString* Symbols::FromDot(Thread* thread, const String& str) {
+StringPtr Symbols::FromDot(Thread* thread, const String& str) {
return FromConcat(thread, str, Dot());
}
// TODO(srdjan): If this becomes performance critical code, consider looking
// up symbol from hash of pieces instead of concatenating them first into
// a string.
-RawString* Symbols::FromConcatAll(
+StringPtr Symbols::FromConcatAll(
Thread* thread,
const GrowableHandlePtrArray<const String>& strs) {
const intptr_t strs_length = strs.length();
@@ -565,7 +563,7 @@
// StringType can be StringSlice, ConcatString, or {Latin1,UTF16,UTF32}Array.
template <typename StringType>
-RawString* Symbols::NewSymbol(Thread* thread, const StringType& str) {
+StringPtr Symbols::NewSymbol(Thread* thread, const StringType& str) {
REUSABLE_OBJECT_HANDLESCOPE(thread);
REUSABLE_SMI_HANDLESCOPE(thread);
REUSABLE_ARRAY_HANDLESCOPE(thread);
@@ -613,7 +611,7 @@
}
template <typename StringType>
-RawString* Symbols::Lookup(Thread* thread, const StringType& str) {
+StringPtr Symbols::Lookup(Thread* thread, const StringType& str) {
REUSABLE_OBJECT_HANDLESCOPE(thread);
REUSABLE_SMI_HANDLESCOPE(thread);
REUSABLE_ARRAY_HANDLESCOPE(thread);
@@ -653,9 +651,9 @@
return symbol.raw();
}
-RawString* Symbols::LookupFromConcat(Thread* thread,
- const String& str1,
- const String& str2) {
+StringPtr Symbols::LookupFromConcat(Thread* thread,
+ const String& str1,
+ const String& str2) {
if (str1.Length() == 0) {
return Lookup(thread, str2);
} else if (str2.Length() == 0) {
@@ -665,44 +663,44 @@
}
}
-RawString* Symbols::LookupFromGet(Thread* thread, const String& str) {
+StringPtr Symbols::LookupFromGet(Thread* thread, const String& str) {
return LookupFromConcat(thread, GetterPrefix(), str);
}
-RawString* Symbols::LookupFromSet(Thread* thread, const String& str) {
+StringPtr Symbols::LookupFromSet(Thread* thread, const String& str) {
return LookupFromConcat(thread, SetterPrefix(), str);
}
-RawString* Symbols::LookupFromDot(Thread* thread, const String& str) {
+StringPtr Symbols::LookupFromDot(Thread* thread, const String& str) {
return LookupFromConcat(thread, str, Dot());
}
-RawString* Symbols::New(Thread* thread, const String& str) {
+StringPtr Symbols::New(Thread* thread, const String& str) {
if (str.IsSymbol()) {
return str.raw();
}
return New(thread, str, 0, str.Length());
}
-RawString* Symbols::New(Thread* thread,
- const String& str,
- intptr_t begin_index,
- intptr_t len) {
+StringPtr Symbols::New(Thread* thread,
+ const String& str,
+ intptr_t begin_index,
+ intptr_t len) {
return NewSymbol(thread, StringSlice(str, begin_index, len));
}
-RawString* Symbols::NewFormatted(Thread* thread, const char* format, ...) {
+StringPtr Symbols::NewFormatted(Thread* thread, const char* format, ...) {
va_list args;
va_start(args, format);
- RawString* result = NewFormattedV(thread, format, args);
+ StringPtr result = NewFormattedV(thread, format, args);
NoSafepointScope no_safepoint;
va_end(args);
return result;
}
-RawString* Symbols::NewFormattedV(Thread* thread,
- const char* format,
- va_list args) {
+StringPtr Symbols::NewFormattedV(Thread* thread,
+ const char* format,
+ va_list args) {
va_list args_copy;
va_copy(args_copy, args);
intptr_t len = Utils::VSNPrint(NULL, 0, format, args_copy);
@@ -715,7 +713,7 @@
return Symbols::New(thread, buffer);
}
-RawString* Symbols::FromCharCode(Thread* thread, int32_t char_code) {
+StringPtr Symbols::FromCharCode(Thread* thread, int32_t char_code) {
if (char_code > kMaxOneCharCodeSymbol) {
return FromUTF32(thread, &char_code, 1);
}
@@ -744,7 +742,7 @@
table.Release();
}
-intptr_t Symbols::LookupPredefinedSymbol(RawObject* obj) {
+intptr_t Symbols::LookupPredefinedSymbol(ObjectPtr obj) {
for (intptr_t i = 1; i < Symbols::kMaxPredefinedId; i++) {
if (symbol_handles_[i]->raw() == obj) {
return (i + kMaxPredefinedObjectIds);
@@ -753,7 +751,7 @@
return kInvalidIndex;
}
-RawObject* Symbols::GetPredefinedSymbol(intptr_t object_id) {
+ObjectPtr Symbols::GetPredefinedSymbol(intptr_t object_id) {
ASSERT(IsPredefinedSymbolId(object_id));
intptr_t i = (object_id - kMaxPredefinedObjectIds);
if ((i > kIllegal) && (i < Symbols::kMaxPredefinedId)) {
diff --git a/runtime/vm/symbols.h b/runtime/vm/symbols.h
index 73ecaaa..df9470a 100644
--- a/runtime/vm/symbols.h
+++ b/runtime/vm/symbols.h
@@ -645,62 +645,62 @@
// Creates a Symbol given a C string that is assumed to contain
// UTF-8 encoded characters and '\0' is considered a termination character.
// TODO(7123) - Rename this to FromCString(....).
- static RawString* New(Thread* thread, const char* cstr) {
+ static StringPtr New(Thread* thread, const char* cstr) {
return New(thread, cstr, strlen(cstr));
}
- static RawString* New(Thread* thread, const char* cstr, intptr_t length);
+ static StringPtr New(Thread* thread, const char* cstr, intptr_t length);
// Creates a new Symbol from an array of UTF-8 encoded characters.
- static RawString* FromUTF8(Thread* thread,
- const uint8_t* utf8_array,
- intptr_t len);
+ static StringPtr FromUTF8(Thread* thread,
+ const uint8_t* utf8_array,
+ intptr_t len);
// Creates a new Symbol from an array of Latin-1 encoded characters.
- static RawString* FromLatin1(Thread* thread,
- const uint8_t* latin1_array,
- intptr_t len);
+ static StringPtr FromLatin1(Thread* thread,
+ const uint8_t* latin1_array,
+ intptr_t len);
// Creates a new Symbol from an array of UTF-16 encoded characters.
- static RawString* FromUTF16(Thread* thread,
- const uint16_t* utf16_array,
- intptr_t len);
+ static StringPtr FromUTF16(Thread* thread,
+ const uint16_t* utf16_array,
+ intptr_t len);
// Creates a new Symbol from an array of UTF-32 encoded characters.
- static RawString* FromUTF32(Thread* thread,
- const int32_t* utf32_array,
- intptr_t len);
+ static StringPtr FromUTF32(Thread* thread,
+ const int32_t* utf32_array,
+ intptr_t len);
- static RawString* New(Thread* thread, const String& str);
- static RawString* New(Thread* thread,
- const String& str,
- intptr_t begin_index,
- intptr_t length);
+ static StringPtr New(Thread* thread, const String& str);
+ static StringPtr New(Thread* thread,
+ const String& str,
+ intptr_t begin_index,
+ intptr_t length);
- static RawString* NewFormatted(Thread* thread, const char* format, ...)
+ static StringPtr NewFormatted(Thread* thread, const char* format, ...)
PRINTF_ATTRIBUTE(2, 3);
- static RawString* NewFormattedV(Thread* thread,
- const char* format,
- va_list args);
+ static StringPtr NewFormattedV(Thread* thread,
+ const char* format,
+ va_list args);
- static RawString* FromConcat(Thread* thread,
- const String& str1,
- const String& str2);
+ static StringPtr FromConcat(Thread* thread,
+ const String& str1,
+ const String& str2);
- static RawString* FromConcatAll(
+ static StringPtr FromConcatAll(
Thread* thread,
const GrowableHandlePtrArray<const String>& strs);
- static RawString* FromGet(Thread* thread, const String& str);
- static RawString* FromSet(Thread* thread, const String& str);
- static RawString* FromDot(Thread* thread, const String& str);
+ static StringPtr FromGet(Thread* thread, const String& str);
+ static StringPtr FromSet(Thread* thread, const String& str);
+ static StringPtr FromDot(Thread* thread, const String& str);
// Returns char* of predefined symbol.
static const char* Name(SymbolId symbol);
- static RawString* FromCharCode(Thread* thread, int32_t char_code);
+ static StringPtr FromCharCode(Thread* thread, int32_t char_code);
- static RawString** PredefinedAddress() {
- return reinterpret_cast<RawString**>(&predefined_);
+ static StringPtr* PredefinedAddress() {
+ return reinterpret_cast<StringPtr*>(&predefined_);
}
static void DumpStats(Isolate* isolate);
@@ -708,16 +708,16 @@
// Returns Symbol::Null if no symbol is found.
template <typename StringType>
- static RawString* Lookup(Thread* thread, const StringType& str);
+ static StringPtr Lookup(Thread* thread, const StringType& str);
// Returns Symbol::Null if no symbol is found.
- static RawString* LookupFromConcat(Thread* thread,
- const String& str1,
- const String& str2);
+ static StringPtr LookupFromConcat(Thread* thread,
+ const String& str1,
+ const String& str2);
- static RawString* LookupFromGet(Thread* thread, const String& str);
- static RawString* LookupFromSet(Thread* thread, const String& str);
- static RawString* LookupFromDot(Thread* thread, const String& str);
+ static StringPtr LookupFromGet(Thread* thread, const String& str);
+ static StringPtr LookupFromSet(Thread* thread, const String& str);
+ static StringPtr LookupFromDot(Thread* thread, const String& str);
static void GetStats(Isolate* isolate, intptr_t* size, intptr_t* capacity);
@@ -725,10 +725,10 @@
enum { kInitialVMIsolateSymtabSize = 1024, kInitialSymtabSize = 2048 };
template <typename StringType>
- static RawString* NewSymbol(Thread* thread, const StringType& str);
+ static StringPtr NewSymbol(Thread* thread, const StringType& str);
- static intptr_t LookupPredefinedSymbol(RawObject* obj);
- static RawObject* GetPredefinedSymbol(intptr_t object_id);
+ static intptr_t LookupPredefinedSymbol(ObjectPtr obj);
+ static ObjectPtr GetPredefinedSymbol(intptr_t object_id);
static bool IsPredefinedSymbolId(intptr_t object_id) {
return (object_id >= kMaxPredefinedObjectIds &&
object_id < (kMaxPredefinedObjectIds + kMaxPredefinedId));
@@ -737,7 +737,7 @@
// List of Latin1 characters stored in the vm isolate as symbols
// in order to make Symbols::FromCharCode fast. This structure is
// used in generated dart code for direct access to these objects.
- static RawString* predefined_[kNumberOfOneCharCodeSymbols];
+ static StringPtr predefined_[kNumberOfOneCharCodeSymbols];
// List of handles for predefined symbols.
static String* symbol_handles_[kMaxPredefinedId];
diff --git a/runtime/vm/tagged_pointer.h b/runtime/vm/tagged_pointer.h
new file mode 100644
index 0000000..9b92514
--- /dev/null
+++ b/runtime/vm/tagged_pointer.h
@@ -0,0 +1,324 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+#ifndef RUNTIME_VM_TAGGED_POINTER_H_
+#define RUNTIME_VM_TAGGED_POINTER_H_
+
+#include "platform/assert.h"
+#include "platform/utils.h"
+#include "vm/class_id.h"
+#include "vm/pointer_tagging.h"
+
+namespace dart {
+
+class IsolateGroup;
+class ObjectLayout;
+
+class ObjectPtr {
+ public:
+ ObjectPtr* operator->() { return this; }
+ const ObjectPtr* operator->() const { return this; }
+ ObjectLayout* ptr() const {
+ return reinterpret_cast<ObjectLayout*>(UntaggedPointer());
+ }
+
+ bool IsWellFormed() const {
+ uword value = tagged_pointer_;
+ return (value & kSmiTagMask) == 0 ||
+ Utils::IsAligned(value - kHeapObjectTag, kWordSize);
+ }
+ bool IsHeapObject() const {
+ ASSERT(IsWellFormed());
+ uword value = tagged_pointer_;
+ return (value & kSmiTagMask) == kHeapObjectTag;
+ }
+ // Assumes this is a heap object.
+ bool IsNewObject() const {
+ ASSERT(IsHeapObject());
+ uword addr = tagged_pointer_;
+ return (addr & kNewObjectAlignmentOffset) == kNewObjectAlignmentOffset;
+ }
+ bool IsNewObjectMayBeSmi() const {
+ static const uword kNewObjectBits =
+ (kNewObjectAlignmentOffset | kHeapObjectTag);
+ const uword addr = tagged_pointer_;
+ return (addr & kObjectAlignmentMask) == kNewObjectBits;
+ }
+ // Assumes this is a heap object.
+ bool IsOldObject() const {
+ ASSERT(IsHeapObject());
+ uword addr = tagged_pointer_;
+ return (addr & kNewObjectAlignmentOffset) == kOldObjectAlignmentOffset;
+ }
+
+ // Like !IsHeapObject() || IsOldObject(), but compiles to a single branch.
+ bool IsSmiOrOldObject() const {
+ ASSERT(IsWellFormed());
+ static const uword kNewObjectBits =
+ (kNewObjectAlignmentOffset | kHeapObjectTag);
+ const uword addr = tagged_pointer_;
+ return (addr & kObjectAlignmentMask) != kNewObjectBits;
+ }
+
+ // Like !IsHeapObject() || IsNewObject(), but compiles to a single branch.
+ bool IsSmiOrNewObject() const {
+ ASSERT(IsWellFormed());
+ static const uword kOldObjectBits =
+ (kOldObjectAlignmentOffset | kHeapObjectTag);
+ const uword addr = tagged_pointer_;
+ return (addr & kObjectAlignmentMask) != kOldObjectBits;
+ }
+
+#define DEFINE_IS_CID(clazz) \
+ bool Is##clazz() const { return ((GetClassId() == k##clazz##Cid)); }
+ CLASS_LIST(DEFINE_IS_CID)
+#undef DEFINE_IS_CID
+
+#define DEFINE_IS_CID(clazz) \
+ bool IsTypedData##clazz() const { \
+ return ((GetClassId() == kTypedData##clazz##Cid)); \
+ } \
+ bool IsTypedDataView##clazz() const { \
+ return ((GetClassId() == kTypedData##clazz##ViewCid)); \
+ } \
+ bool IsExternalTypedData##clazz() const { \
+ return ((GetClassId() == kExternalTypedData##clazz##Cid)); \
+ }
+ CLASS_LIST_TYPED_DATA(DEFINE_IS_CID)
+#undef DEFINE_IS_CID
+
+#define DEFINE_IS_CID(clazz) \
+ bool IsFfi##clazz() const { return ((GetClassId() == kFfi##clazz##Cid)); }
+ CLASS_LIST_FFI(DEFINE_IS_CID)
+#undef DEFINE_IS_CID
+
+ bool IsStringInstance() const { return IsStringClassId(GetClassId()); }
+ bool IsRawNull() const { return GetClassId() == kNullCid; }
+ bool IsDartInstance() const {
+ return (!IsHeapObject() || (GetClassId() >= kInstanceCid));
+ }
+ bool IsFreeListElement() const {
+ return ((GetClassId() == kFreeListElement));
+ }
+ bool IsForwardingCorpse() const {
+ return ((GetClassId() == kForwardingCorpse));
+ }
+ bool IsPseudoObject() const {
+ return IsFreeListElement() || IsForwardingCorpse();
+ }
+
+ intptr_t GetClassId() const;
+ intptr_t GetClassIdMayBeSmi() const {
+ return IsHeapObject() ? GetClassId() : static_cast<intptr_t>(kSmiCid);
+ }
+
+ void Validate(IsolateGroup* isolate_group) const;
+
+ bool operator==(const ObjectPtr& other) {
+ return tagged_pointer_ == other.tagged_pointer_;
+ }
+ bool operator!=(const ObjectPtr& other) {
+ return tagged_pointer_ != other.tagged_pointer_;
+ }
+ constexpr bool operator==(const ObjectPtr& other) const {
+ return tagged_pointer_ == other.tagged_pointer_;
+ }
+ constexpr bool operator!=(const ObjectPtr& other) const {
+ return tagged_pointer_ != other.tagged_pointer_;
+ }
+ bool operator==(const nullptr_t& other) { return tagged_pointer_ == 0; }
+ bool operator!=(const nullptr_t& other) { return tagged_pointer_ != 0; }
+ constexpr bool operator==(const nullptr_t& other) const {
+ return tagged_pointer_ == 0;
+ }
+ constexpr bool operator!=(const nullptr_t& other) const {
+ return tagged_pointer_ != 0;
+ }
+
+ // Use explicit null comparisons instead.
+ operator bool() const = delete;
+
+ // The underlying types of int32_t/int64_t and intptr_t are sometimes
+ // different and sometimes the same, depending on the platform. With
+ // only a conversion operator for intptr_t, on 64-bit Mac a static_cast
+ // to int64_t fails because it tries conversion to bool (!) rather than
+ // intptr_t. So we exhaustive define all the valid conversions based on
+ // the underlying types.
+#if INT_MAX == INTPTR_MAX
+ explicit operator int() const { // NOLINT
+ return static_cast<int>(tagged_pointer_); // NOLINT
+ }
+#endif
+#if LONG_MAX == INTPTR_MAX
+ explicit operator long() const { // NOLINT
+ return static_cast<long>(tagged_pointer_); // NOLINT
+ }
+#endif
+#if LLONG_MAX == INTPTR_MAX
+ explicit operator long long() const { // NOLINT
+ return static_cast<long long>(tagged_pointer_); // NOLINT
+ }
+#endif
+#if UINT_MAX == UINTPTR_MAX
+ explicit operator unsigned int() const { // NOLINT
+ return static_cast<unsigned int>(tagged_pointer_); // NOLINT
+ }
+#endif
+#if ULONG_MAX == UINTPTR_MAX
+ explicit operator unsigned long() const { // NOLINT
+ return static_cast<unsigned long>(tagged_pointer_); // NOLINT
+ }
+#endif
+#if ULLONG_MAX == UINTPTR_MAX
+ explicit operator unsigned long long() const { // NOLINT
+ return static_cast<unsigned long long>(tagged_pointer_); // NOLINT
+ }
+#endif
+
+ // Must be trivially copyable for std::atomic.
+ ObjectPtr& operator=(const ObjectPtr& other) = default;
+ constexpr ObjectPtr(const ObjectPtr& other) = default;
+
+ ObjectPtr() : tagged_pointer_(0) {}
+ explicit constexpr ObjectPtr(uword tagged) : tagged_pointer_(tagged) {}
+ explicit constexpr ObjectPtr(intptr_t tagged) : tagged_pointer_(tagged) {}
+ constexpr ObjectPtr(nullptr_t) : tagged_pointer_(0) {} // NOLINT
+ explicit ObjectPtr(ObjectLayout* heap_object)
+ : tagged_pointer_(reinterpret_cast<uword>(heap_object) + kHeapObjectTag) {
+ }
+
+ protected:
+ uword UntaggedPointer() const {
+ ASSERT(IsHeapObject());
+ return tagged_pointer_ - kHeapObjectTag;
+ }
+
+ uword tagged_pointer_;
+};
+
+// Needed by the printing in the EXPECT macros.
+#if defined(DEBUG) || defined(TESTING)
+inline std::ostream& operator<<(std::ostream& os, const ObjectPtr& obj) {
+ os << reinterpret_cast<void*>(static_cast<uword>(obj));
+ return os;
+}
+#endif
+
+#define DEFINE_TAGGED_POINTER(klass, base) \
+ class klass##Layout; \
+ class klass##Ptr : public base##Ptr { \
+ public: \
+ klass##Ptr* operator->() { return this; } \
+ const klass##Ptr* operator->() const { return this; } \
+ klass##Layout* ptr() { \
+ return reinterpret_cast<klass##Layout*>(UntaggedPointer()); \
+ } \
+ /* TODO: Return const pointer */ \
+ klass##Layout* ptr() const { \
+ return reinterpret_cast<klass##Layout*>(UntaggedPointer()); \
+ } \
+ klass##Ptr& operator=(const klass##Ptr& other) = default; \
+ constexpr klass##Ptr(const klass##Ptr& other) = default; \
+ explicit constexpr klass##Ptr(const ObjectPtr& other) \
+ : base##Ptr(other) {} \
+ klass##Ptr() : base##Ptr() {} \
+ explicit constexpr klass##Ptr(uword tagged) : base##Ptr(tagged) {} \
+ explicit constexpr klass##Ptr(intptr_t tagged) : base##Ptr(tagged) {} \
+ constexpr klass##Ptr(nullptr_t) : base##Ptr(nullptr) {} /* NOLINT */ \
+ explicit klass##Ptr(const ObjectLayout* untagged) \
+ : base##Ptr(reinterpret_cast<uword>(untagged) + kHeapObjectTag) {} \
+ };
+
+DEFINE_TAGGED_POINTER(Class, Object)
+DEFINE_TAGGED_POINTER(PatchClass, Object)
+DEFINE_TAGGED_POINTER(Function, Object)
+DEFINE_TAGGED_POINTER(ClosureData, Object)
+DEFINE_TAGGED_POINTER(SignatureData, Object)
+DEFINE_TAGGED_POINTER(RedirectionData, Object)
+DEFINE_TAGGED_POINTER(FfiTrampolineData, Object)
+DEFINE_TAGGED_POINTER(Field, Object)
+DEFINE_TAGGED_POINTER(Script, Object)
+DEFINE_TAGGED_POINTER(Library, Object)
+DEFINE_TAGGED_POINTER(Namespace, Object)
+DEFINE_TAGGED_POINTER(KernelProgramInfo, Object)
+DEFINE_TAGGED_POINTER(WeakSerializationReference, Object)
+DEFINE_TAGGED_POINTER(Code, Object)
+DEFINE_TAGGED_POINTER(Bytecode, Object)
+DEFINE_TAGGED_POINTER(ObjectPool, Object)
+DEFINE_TAGGED_POINTER(Instructions, Object)
+DEFINE_TAGGED_POINTER(InstructionsSection, Object)
+DEFINE_TAGGED_POINTER(PcDescriptors, Object)
+DEFINE_TAGGED_POINTER(CodeSourceMap, Object)
+DEFINE_TAGGED_POINTER(CompressedStackMaps, Object)
+DEFINE_TAGGED_POINTER(LocalVarDescriptors, Object)
+DEFINE_TAGGED_POINTER(ExceptionHandlers, Object)
+DEFINE_TAGGED_POINTER(Context, Object)
+DEFINE_TAGGED_POINTER(ContextScope, Object)
+DEFINE_TAGGED_POINTER(ParameterTypeCheck, Object)
+DEFINE_TAGGED_POINTER(SingleTargetCache, Object)
+DEFINE_TAGGED_POINTER(UnlinkedCall, Object)
+DEFINE_TAGGED_POINTER(MonomorphicSmiableCall, Object)
+DEFINE_TAGGED_POINTER(CallSiteData, Object)
+DEFINE_TAGGED_POINTER(ICData, CallSiteData)
+DEFINE_TAGGED_POINTER(MegamorphicCache, CallSiteData)
+DEFINE_TAGGED_POINTER(SubtypeTestCache, Object)
+DEFINE_TAGGED_POINTER(Error, Object)
+DEFINE_TAGGED_POINTER(ApiError, Error)
+DEFINE_TAGGED_POINTER(LanguageError, Error)
+DEFINE_TAGGED_POINTER(UnhandledException, Error)
+DEFINE_TAGGED_POINTER(UnwindError, Error)
+DEFINE_TAGGED_POINTER(Instance, Object)
+DEFINE_TAGGED_POINTER(LibraryPrefix, Instance)
+DEFINE_TAGGED_POINTER(TypeArguments, Instance)
+DEFINE_TAGGED_POINTER(AbstractType, Instance)
+DEFINE_TAGGED_POINTER(Type, AbstractType)
+DEFINE_TAGGED_POINTER(TypeRef, AbstractType)
+DEFINE_TAGGED_POINTER(TypeParameter, AbstractType)
+DEFINE_TAGGED_POINTER(Closure, Instance)
+DEFINE_TAGGED_POINTER(Number, Instance)
+DEFINE_TAGGED_POINTER(Integer, Number)
+DEFINE_TAGGED_POINTER(Smi, Integer)
+DEFINE_TAGGED_POINTER(Mint, Integer)
+DEFINE_TAGGED_POINTER(Double, Number)
+DEFINE_TAGGED_POINTER(String, Instance)
+DEFINE_TAGGED_POINTER(OneByteString, String)
+DEFINE_TAGGED_POINTER(TwoByteString, String)
+DEFINE_TAGGED_POINTER(PointerBase, Instance)
+DEFINE_TAGGED_POINTER(TypedDataBase, PointerBase)
+DEFINE_TAGGED_POINTER(TypedData, TypedDataBase)
+DEFINE_TAGGED_POINTER(TypedDataView, TypedDataBase)
+DEFINE_TAGGED_POINTER(ExternalOneByteString, String)
+DEFINE_TAGGED_POINTER(ExternalTwoByteString, String)
+DEFINE_TAGGED_POINTER(Bool, Instance)
+DEFINE_TAGGED_POINTER(Array, Instance)
+DEFINE_TAGGED_POINTER(ImmutableArray, Array)
+DEFINE_TAGGED_POINTER(GrowableObjectArray, Instance)
+DEFINE_TAGGED_POINTER(LinkedHashMap, Instance)
+DEFINE_TAGGED_POINTER(Float32x4, Instance)
+DEFINE_TAGGED_POINTER(Int32x4, Instance)
+DEFINE_TAGGED_POINTER(Float64x2, Instance)
+DEFINE_TAGGED_POINTER(ExternalTypedData, TypedDataBase)
+DEFINE_TAGGED_POINTER(Pointer, PointerBase)
+DEFINE_TAGGED_POINTER(DynamicLibrary, Instance)
+DEFINE_TAGGED_POINTER(Capability, Instance)
+DEFINE_TAGGED_POINTER(SendPort, Instance)
+DEFINE_TAGGED_POINTER(ReceivePort, Instance)
+DEFINE_TAGGED_POINTER(TransferableTypedData, Instance)
+DEFINE_TAGGED_POINTER(StackTrace, Instance)
+DEFINE_TAGGED_POINTER(RegExp, Instance)
+DEFINE_TAGGED_POINTER(WeakProperty, Instance)
+DEFINE_TAGGED_POINTER(MirrorReference, Instance)
+DEFINE_TAGGED_POINTER(UserTag, Instance)
+DEFINE_TAGGED_POINTER(FutureOr, Instance)
+#undef DEFINE_TAGGED_POINTER
+
+inline intptr_t RawSmiValue(const SmiPtr raw_value) {
+ const intptr_t value = static_cast<intptr_t>(raw_value);
+ ASSERT((value & kSmiTagMask) == kSmiTag);
+ return (value >> kSmiTagShift);
+}
+
+} // namespace dart
+
+#endif // RUNTIME_VM_TAGGED_POINTER_H_
diff --git a/runtime/vm/thread.cc b/runtime/vm/thread.cc
index d96d81d..42c751c 100644
--- a/runtime/vm/thread.cc
+++ b/runtime/vm/thread.cc
@@ -65,7 +65,7 @@
Thread::Thread(bool is_vm_isolate)
: ThreadState(false),
stack_limit_(0),
- write_barrier_mask_(RawObject::kGenerationalBarrierMask),
+ write_barrier_mask_(ObjectLayout::kGenerationalBarrierMask),
isolate_(NULL),
dispatch_table_array_(NULL),
saved_stack_limit_(0),
@@ -235,7 +235,7 @@
}
#endif
-RawGrowableObjectArray* Thread::pending_functions() {
+GrowableObjectArrayPtr Thread::pending_functions() {
if (pending_functions_ == GrowableObjectArray::null()) {
pending_functions_ = GrowableObjectArray::New(Heap::kOld);
}
@@ -254,7 +254,7 @@
active_stacktrace_ = value.raw();
}
-RawError* Thread::sticky_error() const {
+ErrorPtr Thread::sticky_error() const {
return sticky_error_;
}
@@ -267,9 +267,9 @@
sticky_error_ = Error::null();
}
-RawError* Thread::StealStickyError() {
+ErrorPtr Thread::StealStickyError() {
NoSafepointScope no_safepoint;
- RawError* return_value = sticky_error_;
+ ErrorPtr return_value = sticky_error_;
sticky_error_ = Error::null();
return return_value;
}
@@ -292,7 +292,7 @@
}
}
-RawStackTrace* Thread::async_stack_trace() const {
+StackTracePtr Thread::async_stack_trace() const {
return async_stack_trace_;
}
@@ -301,7 +301,7 @@
async_stack_trace_ = stack_trace.raw();
}
-void Thread::set_raw_async_stack_trace(RawStackTrace* raw_stack_trace) {
+void Thread::set_raw_async_stack_trace(StackTracePtr raw_stack_trace) {
async_stack_trace_ = raw_stack_trace;
}
@@ -515,7 +515,7 @@
#endif // !defined(PRODUCT)
}
-RawError* Thread::HandleInterrupts() {
+ErrorPtr Thread::HandleInterrupts() {
uword interrupt_bits = GetAndClearInterrupts();
if ((interrupt_bits & kVMInterrupt) != 0) {
CheckForSafepoint();
@@ -539,7 +539,7 @@
isolate()->name());
}
NoSafepointScope no_safepoint;
- RawError* error = Thread::Current()->StealStickyError();
+ ErrorPtr error = Thread::Current()->StealStickyError();
ASSERT(error->IsUnwindError());
return error;
}
@@ -558,7 +558,7 @@
StoreBufferAcquire();
}
-void Thread::StoreBufferAddObject(RawObject* obj) {
+void Thread::StoreBufferAddObject(ObjectPtr obj) {
ASSERT(this == Thread::Current());
store_buffer_block_->Push(obj);
if (store_buffer_block_->IsFull()) {
@@ -566,7 +566,7 @@
}
}
-void Thread::StoreBufferAddObjectGC(RawObject* obj) {
+void Thread::StoreBufferAddObjectGC(ObjectPtr obj) {
store_buffer_block_->Push(obj);
if (store_buffer_block_->IsFull()) {
StoreBufferBlockProcess(StoreBuffer::kIgnoreThreshold);
@@ -593,14 +593,14 @@
DeferredMarkingStackAcquire();
}
-void Thread::MarkingStackAddObject(RawObject* obj) {
+void Thread::MarkingStackAddObject(ObjectPtr obj) {
marking_stack_block_->Push(obj);
if (marking_stack_block_->IsFull()) {
MarkingStackBlockProcess();
}
}
-void Thread::DeferredMarkingStackAddObject(RawObject* obj) {
+void Thread::DeferredMarkingStackAddObject(ObjectPtr obj) {
deferred_marking_stack_block_->Push(obj);
if (deferred_marking_stack_block_->IsFull()) {
DeferredMarkingStackBlockProcess();
@@ -610,14 +610,14 @@
void Thread::MarkingStackRelease() {
MarkingStackBlock* block = marking_stack_block_;
marking_stack_block_ = NULL;
- write_barrier_mask_ = RawObject::kGenerationalBarrierMask;
+ write_barrier_mask_ = ObjectLayout::kGenerationalBarrierMask;
isolate_group()->marking_stack()->PushBlock(block);
}
void Thread::MarkingStackAcquire() {
marking_stack_block_ = isolate_group()->marking_stack()->PopEmptyBlock();
- write_barrier_mask_ =
- RawObject::kGenerationalBarrierMask | RawObject::kIncrementalBarrierMask;
+ write_barrier_mask_ = ObjectLayout::kGenerationalBarrierMask |
+ ObjectLayout::kIncrementalBarrierMask;
}
void Thread::DeferredMarkingStackRelease() {
@@ -680,13 +680,13 @@
// Visit objects in thread specific handles area.
reusable_handles_.VisitObjectPointers(visitor);
- visitor->VisitPointer(reinterpret_cast<RawObject**>(&pending_functions_));
- visitor->VisitPointer(reinterpret_cast<RawObject**>(&global_object_pool_));
- visitor->VisitPointer(reinterpret_cast<RawObject**>(&active_exception_));
- visitor->VisitPointer(reinterpret_cast<RawObject**>(&active_stacktrace_));
- visitor->VisitPointer(reinterpret_cast<RawObject**>(&sticky_error_));
- visitor->VisitPointer(reinterpret_cast<RawObject**>(&async_stack_trace_));
- visitor->VisitPointer(reinterpret_cast<RawObject**>(&ffi_callback_code_));
+ visitor->VisitPointer(reinterpret_cast<ObjectPtr*>(&pending_functions_));
+ visitor->VisitPointer(reinterpret_cast<ObjectPtr*>(&global_object_pool_));
+ visitor->VisitPointer(reinterpret_cast<ObjectPtr*>(&active_exception_));
+ visitor->VisitPointer(reinterpret_cast<ObjectPtr*>(&active_stacktrace_));
+ visitor->VisitPointer(reinterpret_cast<ObjectPtr*>(&sticky_error_));
+ visitor->VisitPointer(reinterpret_cast<ObjectPtr*>(&async_stack_trace_));
+ visitor->VisitPointer(reinterpret_cast<ObjectPtr*>(&ffi_callback_code_));
#if !defined(DART_PRECOMPILED_RUNTIME)
if (interpreter() != NULL) {
@@ -740,9 +740,9 @@
current_(Thread::Current()),
op_(op) {}
- void VisitPointers(RawObject** first, RawObject** last) {
+ void VisitPointers(ObjectPtr* first, ObjectPtr* last) {
for (; first != last + 1; first++) {
- RawObject* obj = *first;
+ ObjectPtr obj = *first;
// Stores into new-space objects don't need a write barrier.
if (obj->IsSmiOrNewObject()) continue;
@@ -757,17 +757,17 @@
if (!obj->IsDartInstance() && !obj->IsContext()) continue;
// Dart code won't store into canonical instances.
- if (obj->IsCanonical()) continue;
+ if (obj->ptr()->IsCanonical()) continue;
// Objects in the VM isolate heap are immutable and won't be
// stored into. Check this condition last because there's no bit
// in the header for it.
- if (obj->InVMIsolateHeap()) continue;
+ if (obj->ptr()->InVMIsolateHeap()) continue;
switch (op_) {
case Thread::RestoreWriteBarrierInvariantOp::kAddToRememberedSet:
- if (!obj->IsRemembered()) {
- obj->AddToRememberedSet(current_);
+ if (!obj->ptr()->IsRemembered()) {
+ obj->ptr()->AddToRememberedSet(current_);
}
if (current_->is_marking()) {
current_->DeferredMarkingStackAddObject(obj);
@@ -813,7 +813,7 @@
frame = frames_iterator.NextFrame()) {
if (frame->IsExitFrame()) {
scan_next_dart_frame = true;
- } else if (frame->IsDartFrame(/*validate=*/false, /*needed_for_gc=*/true)) {
+ } else if (frame->IsDartFrame(/*validate=*/false)) {
if (scan_next_dart_frame) {
frame->VisitObjectPointers(&visitor);
}
@@ -862,7 +862,7 @@
// [object] is in fact a [Code] object.
if (object.IsCode()) {
#define COMPUTE_OFFSET(type_name, member_name, expr, default_init_value) \
- ASSERT((expr)->InVMIsolateHeap()); \
+ ASSERT((expr)->ptr()->InVMIsolateHeap()); \
if (object.raw() == expr) { \
return Thread::member_name##offset(); \
}
@@ -1137,13 +1137,12 @@
void Thread::VerifyCallbackIsolate(int32_t callback_id, uword entry) {
NoSafepointScope _;
- const RawGrowableObjectArray* const array = ffi_callback_code_;
+ const GrowableObjectArrayPtr array = ffi_callback_code_;
if (array == GrowableObjectArray::null()) {
FATAL("Cannot invoke callback on incorrect isolate.");
}
- const RawSmi* const length_smi =
- GrowableObjectArray::NoSafepointLength(array);
+ const SmiPtr length_smi = GrowableObjectArray::NoSafepointLength(array);
const intptr_t length = Smi::Value(length_smi);
if (callback_id < 0 || callback_id >= length) {
@@ -1151,11 +1150,10 @@
}
if (entry != 0) {
- RawObject** const code_array =
+ ObjectPtr* const code_array =
Array::DataOf(GrowableObjectArray::NoSafepointData(array));
// RawCast allocates handles in ASSERTs.
- const RawCode* const code =
- reinterpret_cast<RawCode*>(code_array[callback_id]);
+ const CodePtr code = static_cast<CodePtr>(code_array[callback_id]);
if (!Code::ContainsInstructionAt(code, entry)) {
FATAL("Cannot invoke callback on incorrect isolate.");
}
diff --git a/runtime/vm/thread.h b/runtime/vm/thread.h
index 9780e89..708916f 100644
--- a/runtime/vm/thread.h
+++ b/runtime/vm/thread.h
@@ -52,14 +52,6 @@
class OSThread;
class JSONObject;
class PcDescriptors;
-class RawBool;
-class RawObject;
-class RawCode;
-class RawError;
-class RawGrowableObjectArray;
-class RawObjectPool;
-class RawStackTrace;
-class RawString;
class RuntimeEntry;
class Smi;
class StackResource;
@@ -98,66 +90,66 @@
V(TypeParameter)
#define CACHED_VM_STUBS_LIST(V) \
- V(RawCode*, write_barrier_code_, StubCode::WriteBarrier().raw(), NULL) \
- V(RawCode*, array_write_barrier_code_, StubCode::ArrayWriteBarrier().raw(), \
- NULL) \
- V(RawCode*, fix_callers_target_code_, StubCode::FixCallersTarget().raw(), \
- NULL) \
- V(RawCode*, fix_allocation_stub_code_, \
- StubCode::FixAllocationStubTarget().raw(), NULL) \
- V(RawCode*, invoke_dart_code_stub_, StubCode::InvokeDartCode().raw(), NULL) \
- V(RawCode*, invoke_dart_code_from_bytecode_stub_, \
- StubCode::InvokeDartCodeFromBytecode().raw(), NULL) \
- V(RawCode*, call_to_runtime_stub_, StubCode::CallToRuntime().raw(), NULL) \
- V(RawCode*, null_error_shared_without_fpu_regs_stub_, \
- StubCode::NullErrorSharedWithoutFPURegs().raw(), NULL) \
- V(RawCode*, null_error_shared_with_fpu_regs_stub_, \
- StubCode::NullErrorSharedWithFPURegs().raw(), NULL) \
- V(RawCode*, null_arg_error_shared_without_fpu_regs_stub_, \
- StubCode::NullArgErrorSharedWithoutFPURegs().raw(), nullptr) \
- V(RawCode*, null_arg_error_shared_with_fpu_regs_stub_, \
- StubCode::NullArgErrorSharedWithFPURegs().raw(), nullptr) \
- V(RawCode*, range_error_shared_without_fpu_regs_stub_, \
- StubCode::RangeErrorSharedWithoutFPURegs().raw(), nullptr) \
- V(RawCode*, range_error_shared_with_fpu_regs_stub_, \
- StubCode::RangeErrorSharedWithFPURegs().raw(), nullptr) \
- V(RawCode*, allocate_mint_with_fpu_regs_stub_, \
- StubCode::AllocateMintSharedWithFPURegs().raw(), NULL) \
- V(RawCode*, allocate_mint_without_fpu_regs_stub_, \
- StubCode::AllocateMintSharedWithoutFPURegs().raw(), NULL) \
- V(RawCode*, allocate_object_stub_, StubCode::AllocateObject().raw(), \
+ V(CodePtr, write_barrier_code_, StubCode::WriteBarrier().raw(), nullptr) \
+ V(CodePtr, array_write_barrier_code_, StubCode::ArrayWriteBarrier().raw(), \
nullptr) \
- V(RawCode*, allocate_object_parameterized_stub_, \
+ V(CodePtr, fix_callers_target_code_, StubCode::FixCallersTarget().raw(), \
+ nullptr) \
+ V(CodePtr, fix_allocation_stub_code_, \
+ StubCode::FixAllocationStubTarget().raw(), nullptr) \
+ V(CodePtr, invoke_dart_code_stub_, StubCode::InvokeDartCode().raw(), \
+ nullptr) \
+ V(CodePtr, invoke_dart_code_from_bytecode_stub_, \
+ StubCode::InvokeDartCodeFromBytecode().raw(), nullptr) \
+ V(CodePtr, call_to_runtime_stub_, StubCode::CallToRuntime().raw(), nullptr) \
+ V(CodePtr, null_error_shared_without_fpu_regs_stub_, \
+ StubCode::NullErrorSharedWithoutFPURegs().raw(), nullptr) \
+ V(CodePtr, null_error_shared_with_fpu_regs_stub_, \
+ StubCode::NullErrorSharedWithFPURegs().raw(), nullptr) \
+ V(CodePtr, null_arg_error_shared_without_fpu_regs_stub_, \
+ StubCode::NullArgErrorSharedWithoutFPURegs().raw(), nullptr) \
+ V(CodePtr, null_arg_error_shared_with_fpu_regs_stub_, \
+ StubCode::NullArgErrorSharedWithFPURegs().raw(), nullptr) \
+ V(CodePtr, range_error_shared_without_fpu_regs_stub_, \
+ StubCode::RangeErrorSharedWithoutFPURegs().raw(), nullptr) \
+ V(CodePtr, range_error_shared_with_fpu_regs_stub_, \
+ StubCode::RangeErrorSharedWithFPURegs().raw(), nullptr) \
+ V(CodePtr, allocate_mint_with_fpu_regs_stub_, \
+ StubCode::AllocateMintSharedWithFPURegs().raw(), nullptr) \
+ V(CodePtr, allocate_mint_without_fpu_regs_stub_, \
+ StubCode::AllocateMintSharedWithoutFPURegs().raw(), nullptr) \
+ V(CodePtr, allocate_object_stub_, StubCode::AllocateObject().raw(), nullptr) \
+ V(CodePtr, allocate_object_parameterized_stub_, \
StubCode::AllocateObjectParameterized().raw(), nullptr) \
- V(RawCode*, allocate_object_slow_stub_, \
- StubCode::AllocateObjectSlow().raw(), nullptr) \
- V(RawCode*, stack_overflow_shared_without_fpu_regs_stub_, \
- StubCode::StackOverflowSharedWithoutFPURegs().raw(), NULL) \
- V(RawCode*, stack_overflow_shared_with_fpu_regs_stub_, \
- StubCode::StackOverflowSharedWithFPURegs().raw(), NULL) \
- V(RawCode*, switchable_call_miss_stub_, \
- StubCode::SwitchableCallMiss().raw(), NULL) \
- V(RawCode*, throw_stub_, StubCode::Throw().raw(), NULL) \
- V(RawCode*, re_throw_stub_, StubCode::Throw().raw(), NULL) \
- V(RawCode*, assert_boolean_stub_, StubCode::AssertBoolean().raw(), NULL) \
- V(RawCode*, optimize_stub_, StubCode::OptimizeFunction().raw(), NULL) \
- V(RawCode*, deoptimize_stub_, StubCode::Deoptimize().raw(), NULL) \
- V(RawCode*, lazy_deopt_from_return_stub_, \
- StubCode::DeoptimizeLazyFromReturn().raw(), NULL) \
- V(RawCode*, lazy_deopt_from_throw_stub_, \
- StubCode::DeoptimizeLazyFromThrow().raw(), NULL) \
- V(RawCode*, slow_type_test_stub_, StubCode::SlowTypeTest().raw(), NULL) \
- V(RawCode*, lazy_specialize_type_test_stub_, \
- StubCode::LazySpecializeTypeTest().raw(), NULL) \
- V(RawCode*, enter_safepoint_stub_, StubCode::EnterSafepoint().raw(), NULL) \
- V(RawCode*, exit_safepoint_stub_, StubCode::ExitSafepoint().raw(), NULL) \
- V(RawCode*, call_native_through_safepoint_stub_, \
- StubCode::CallNativeThroughSafepoint().raw(), NULL)
+ V(CodePtr, allocate_object_slow_stub_, StubCode::AllocateObjectSlow().raw(), \
+ nullptr) \
+ V(CodePtr, stack_overflow_shared_without_fpu_regs_stub_, \
+ StubCode::StackOverflowSharedWithoutFPURegs().raw(), nullptr) \
+ V(CodePtr, stack_overflow_shared_with_fpu_regs_stub_, \
+ StubCode::StackOverflowSharedWithFPURegs().raw(), nullptr) \
+ V(CodePtr, switchable_call_miss_stub_, StubCode::SwitchableCallMiss().raw(), \
+ nullptr) \
+ V(CodePtr, throw_stub_, StubCode::Throw().raw(), nullptr) \
+ V(CodePtr, re_throw_stub_, StubCode::Throw().raw(), nullptr) \
+ V(CodePtr, assert_boolean_stub_, StubCode::AssertBoolean().raw(), nullptr) \
+ V(CodePtr, optimize_stub_, StubCode::OptimizeFunction().raw(), nullptr) \
+ V(CodePtr, deoptimize_stub_, StubCode::Deoptimize().raw(), nullptr) \
+ V(CodePtr, lazy_deopt_from_return_stub_, \
+ StubCode::DeoptimizeLazyFromReturn().raw(), nullptr) \
+ V(CodePtr, lazy_deopt_from_throw_stub_, \
+ StubCode::DeoptimizeLazyFromThrow().raw(), nullptr) \
+ V(CodePtr, slow_type_test_stub_, StubCode::SlowTypeTest().raw(), nullptr) \
+ V(CodePtr, lazy_specialize_type_test_stub_, \
+ StubCode::LazySpecializeTypeTest().raw(), nullptr) \
+ V(CodePtr, enter_safepoint_stub_, StubCode::EnterSafepoint().raw(), nullptr) \
+ V(CodePtr, exit_safepoint_stub_, StubCode::ExitSafepoint().raw(), nullptr) \
+ V(CodePtr, call_native_through_safepoint_stub_, \
+ StubCode::CallNativeThroughSafepoint().raw(), nullptr)
#define CACHED_NON_VM_STUB_LIST(V) \
- V(RawObject*, object_null_, Object::null(), NULL) \
- V(RawBool*, bool_true_, Object::bool_true().raw(), NULL) \
- V(RawBool*, bool_false_, Object::bool_false().raw(), NULL)
+ V(ObjectPtr, object_null_, Object::null(), nullptr) \
+ V(BoolPtr, bool_true_, Object::bool_true().raw(), nullptr) \
+ V(BoolPtr, bool_false_, Object::bool_false().raw(), nullptr)
// List of VM-global objects/addresses cached in each Thread object.
// Important: constant false must immediately follow constant true.
@@ -212,7 +204,7 @@
V(uword, auto_scope_native_wrapper_entry_point_, \
NativeEntry::AutoScopeNativeCallWrapperEntry(), 0) \
V(uword, interpret_call_entry_point_, RuntimeEntry::InterpretCallEntry(), 0) \
- V(RawString**, predefined_symbols_address_, Symbols::PredefinedAddress(), \
+ V(StringPtr*, predefined_symbols_address_, Symbols::PredefinedAddress(), \
NULL) \
V(uword, double_nan_address_, reinterpret_cast<uword>(&double_nan_constant), \
0) \
@@ -375,7 +367,7 @@
void ScheduleInterrupts(uword interrupt_bits);
void ScheduleInterruptsLocked(uword interrupt_bits);
- RawError* HandleInterrupts();
+ ErrorPtr HandleInterrupts();
uword GetAndClearInterrupts();
bool HasScheduledInterrupts() const {
return (stack_limit_ & kInterruptsMask) != 0;
@@ -470,10 +462,10 @@
no_callback_scope_depth_ -= 1;
}
- void StoreBufferAddObject(RawObject* obj);
- void StoreBufferAddObjectGC(RawObject* obj);
+ void StoreBufferAddObject(ObjectPtr obj);
+ void StoreBufferAddObjectGC(ObjectPtr obj);
#if defined(TESTING)
- bool StoreBufferContains(RawObject* obj) const {
+ bool StoreBufferContains(ObjectPtr obj) const {
return store_buffer_block_->Contains(obj);
}
#endif
@@ -483,8 +475,8 @@
}
bool is_marking() const { return marking_stack_block_ != NULL; }
- void MarkingStackAddObject(RawObject* obj);
- void DeferredMarkingStackAddObject(RawObject* obj);
+ void MarkingStackAddObject(ObjectPtr obj);
+ void DeferredMarkingStackAddObject(ObjectPtr obj);
void MarkingStackBlockProcess();
void DeferredMarkingStackBlockProcess();
static intptr_t marking_stack_block_offset() {
@@ -584,8 +576,8 @@
LEAF_RUNTIME_ENTRY_LIST(DEFINE_OFFSET_METHOD)
#undef DEFINE_OFFSET_METHOD
- RawObjectPool* global_object_pool() const { return global_object_pool_; }
- void set_global_object_pool(RawObjectPool* raw_value) {
+ ObjectPoolPtr global_object_pool() const { return global_object_pool_; }
+ void set_global_object_pool(ObjectPoolPtr raw_value) {
global_object_pool_ = raw_value;
}
@@ -620,7 +612,7 @@
return OFFSET_OF(Thread, unboxed_int64_runtime_arg_);
}
- RawGrowableObjectArray* pending_functions();
+ GrowableObjectArrayPtr pending_functions();
void clear_pending_functions();
static intptr_t global_object_pool_offset() {
@@ -631,13 +623,13 @@
return OFFSET_OF(Thread, dispatch_table_array_);
}
- RawObject* active_exception() const { return active_exception_; }
+ ObjectPtr active_exception() const { return active_exception_; }
void set_active_exception(const Object& value);
static intptr_t active_exception_offset() {
return OFFSET_OF(Thread, active_exception_);
}
- RawObject* active_stacktrace() const { return active_stacktrace_; }
+ ObjectPtr active_stacktrace() const { return active_stacktrace_; }
void set_active_stacktrace(const Object& value);
static intptr_t active_stacktrace_offset() {
return OFFSET_OF(Thread, active_stacktrace_);
@@ -647,14 +639,14 @@
void set_resume_pc(uword value) { resume_pc_ = value; }
static uword resume_pc_offset() { return OFFSET_OF(Thread, resume_pc_); }
- RawError* sticky_error() const;
+ ErrorPtr sticky_error() const;
void set_sticky_error(const Error& value);
void ClearStickyError();
- DART_WARN_UNUSED_RESULT RawError* StealStickyError();
+ DART_WARN_UNUSED_RESULT ErrorPtr StealStickyError();
- RawStackTrace* async_stack_trace() const;
+ StackTracePtr async_stack_trace() const;
void set_async_stack_trace(const StackTrace& stack_trace);
- void set_raw_async_stack_trace(RawStackTrace* raw_stack_trace);
+ void set_raw_async_stack_trace(StackTracePtr raw_stack_trace);
void clear_async_stack_trace();
static intptr_t async_stack_trace_offset() {
return OFFSET_OF(Thread, async_stack_trace_);
@@ -911,14 +903,14 @@
// is important for code size (although code size on X64 is not a priority).
uword saved_stack_limit_;
uword stack_overflow_flags_;
- RawInstance** field_table_values_;
+ InstancePtr* field_table_values_;
Heap* heap_;
uword volatile top_exit_frame_info_;
StoreBufferBlock* store_buffer_block_;
MarkingStackBlock* marking_stack_block_;
MarkingStackBlock* deferred_marking_stack_block_;
uword volatile vm_tag_;
- RawStackTrace* async_stack_trace_;
+ StackTracePtr async_stack_trace_;
// Memory location dedicated for passing unboxed int64 values from
// generated code to runtime.
// TODO(dartbug.com/33549): Clean this up when unboxed values
@@ -945,14 +937,14 @@
#endif
// JumpToExceptionHandler state:
- RawObject* active_exception_;
- RawObject* active_stacktrace_;
- RawObjectPool* global_object_pool_;
+ ObjectPtr active_exception_;
+ ObjectPtr active_stacktrace_;
+ ObjectPoolPtr global_object_pool_;
uword resume_pc_;
uword saved_shadow_call_stack_ = 0;
uword execution_state_;
std::atomic<uword> safepoint_state_;
- RawGrowableObjectArray* ffi_callback_code_;
+ GrowableObjectArrayPtr ffi_callback_code_;
// ---- End accessed from generated code. ----
@@ -981,16 +973,16 @@
CompilerState* compiler_state_ = nullptr;
HierarchyInfo* hierarchy_info_;
TypeUsageInfo* type_usage_info_;
- RawGrowableObjectArray* pending_functions_;
+ GrowableObjectArrayPtr pending_functions_;
- RawError* sticky_error_;
+ ErrorPtr sticky_error_;
Random thread_random_;
intptr_t ffi_marshalled_arguments_size_ = 0;
uint64_t* ffi_marshalled_arguments_;
- RawInstance** field_table_values() const { return field_table_values_; }
+ InstancePtr* field_table_values() const { return field_table_values_; }
// Reusable handles support.
#define REUSABLE_HANDLE_FIELDS(object) object* object##_handle_;
diff --git a/runtime/vm/thread_test.cc b/runtime/vm/thread_test.cc
index 70a4da9..3465d48 100644
--- a/runtime/vm/thread_test.cc
+++ b/runtime/vm/thread_test.cc
@@ -85,8 +85,8 @@
explicit ObjectCounter(IsolateGroup* isolate_group, const Object* obj)
: ObjectPointerVisitor(isolate_group), obj_(obj), count_(0) {}
- virtual void VisitPointers(RawObject** first, RawObject** last) {
- for (RawObject** current = first; current <= last; ++current) {
+ virtual void VisitPointers(ObjectPtr* first, ObjectPtr* last) {
+ for (ObjectPtr* current = first; current <= last; ++current) {
if (*current == obj_->raw()) {
++count_;
}
@@ -465,8 +465,8 @@
const String& function_name =
String::ZoneHandle(Symbols::New(Thread::Current(), name));
Function& function = Function::ZoneHandle(Function::New(
- function_name, RawFunction::kRegularFunction, true, false, false, false,
- false, owner_class, TokenPosition::kNoSource));
+ function_name, FunctionLayout::kRegularFunction, true, false, false,
+ false, false, owner_class, TokenPosition::kNoSource));
return &function;
}
diff --git a/runtime/vm/timeline.h b/runtime/vm/timeline.h
index 8e4199f..e45b144 100644
--- a/runtime/vm/timeline.h
+++ b/runtime/vm/timeline.h
@@ -31,7 +31,6 @@
class Object;
class ObjectPointerVisitor;
class Isolate;
-class RawArray;
class Thread;
class TimelineEvent;
class TimelineEventBlock;
diff --git a/runtime/vm/type_table.h b/runtime/vm/type_table.h
index e9c21a2..003e8e8 100644
--- a/runtime/vm/type_table.h
+++ b/runtime/vm/type_table.h
@@ -44,7 +44,7 @@
return Type::Cast(key).Hash();
}
static uword Hash(const CanonicalTypeKey& key) { return key.Hash(); }
- static RawObject* NewKey(const CanonicalTypeKey& obj) {
+ static ObjectPtr NewKey(const CanonicalTypeKey& obj) {
return obj.key_.raw();
}
};
@@ -85,7 +85,7 @@
return TypeArguments::Cast(key).Hash();
}
static uword Hash(const CanonicalTypeArgumentsKey& key) { return key.Hash(); }
- static RawObject* NewKey(const CanonicalTypeArgumentsKey& obj) {
+ static ObjectPtr NewKey(const CanonicalTypeArgumentsKey& obj) {
return obj.key_.raw();
}
};
diff --git a/runtime/vm/type_testing_stubs.cc b/runtime/vm/type_testing_stubs.cc
index ca27574..aac0b9c 100644
--- a/runtime/vm/type_testing_stubs.cc
+++ b/runtime/vm/type_testing_stubs.cc
@@ -88,7 +88,7 @@
return cname;
}
-RawCode* TypeTestingStubGenerator::DefaultCodeForType(
+CodePtr TypeTestingStubGenerator::DefaultCodeForType(
const AbstractType& type,
bool lazy_specialize /* = true */) {
if (type.IsTypeRef()) {
@@ -102,7 +102,7 @@
if (!StubCode::HasBeenInitialized()) {
ASSERT(type.IsType());
const classid_t cid = type.type_class_id();
- ASSERT(cid == kDynamicCid || cid == kVoidCid || cid == kNeverCid);
+ ASSERT(cid == kDynamicCid || cid == kVoidCid);
return Code::null();
}
@@ -139,7 +139,7 @@
TypeTestingStubGenerator::TypeTestingStubGenerator()
: object_store_(Isolate::Current()->object_store()) {}
-RawCode* TypeTestingStubGenerator::OptimizedCodeForType(
+CodePtr TypeTestingStubGenerator::OptimizedCodeForType(
const AbstractType& type) {
#if !defined(TARGET_ARCH_IA32)
ASSERT(StubCode::HasBeenInitialized());
@@ -178,7 +178,7 @@
#if !defined(TARGET_ARCH_IA32)
#if !defined(DART_PRECOMPILED_RUNTIME)
-RawCode* TypeTestingStubGenerator::BuildCodeForType(const Type& type) {
+CodePtr TypeTestingStubGenerator::BuildCodeForType(const Type& type) {
auto thread = Thread::Current();
auto zone = thread->zone();
HierarchyInfo* hi = thread->hierarchy_info();
@@ -633,7 +633,7 @@
return *instantiated_type_arguments;
}
-RawAbstractType* TypeArgumentInstantiator::InstantiateType(
+AbstractTypePtr TypeArgumentInstantiator::InstantiateType(
const AbstractType& type) {
if (type.IsTypeParameter()) {
const TypeParameter& parameter = TypeParameter::Cast(type);
@@ -941,7 +941,7 @@
CollectTypes(GrowableArray<AbstractType*>* types, Zone* zone)
: types_(types), object_(Object::Handle(zone)), zone_(zone) {}
- void VisitObject(RawObject* object) {
+ void VisitObject(ObjectPtr object) {
if (object->IsPseudoObject()) {
// Cannot even be wrapped in handles.
return;
diff --git a/runtime/vm/type_testing_stubs.h b/runtime/vm/type_testing_stubs.h
index 345ef31..f4a64ff 100644
--- a/runtime/vm/type_testing_stubs.h
+++ b/runtime/vm/type_testing_stubs.h
@@ -41,8 +41,8 @@
// During bootstrapping it will return `null` for a whitelisted set of types,
// otherwise it will return a default stub which tail-calls
// subtypingtest/runtime code.
- static RawCode* DefaultCodeForType(const AbstractType& type,
- bool lazy_specialize = true);
+ static CodePtr DefaultCodeForType(const AbstractType& type,
+ bool lazy_specialize = true);
#if !defined(DART_PRECOMPILED_RUNTIME)
static void SpecializeStubFor(Thread* thread, const AbstractType& type);
@@ -52,12 +52,12 @@
// Creates new stub for [type] (and registers the tuple in object store
// array) or returns default stub.
- RawCode* OptimizedCodeForType(const AbstractType& type);
+ CodePtr OptimizedCodeForType(const AbstractType& type);
private:
#if !defined(TARGET_ARCH_IA32)
#if !defined(DART_PRECOMPILED_RUNTIME)
- RawCode* BuildCodeForType(const Type& type);
+ CodePtr BuildCodeForType(const Type& type);
static void BuildOptimizedTypeTestStub(
compiler::Assembler* assembler,
compiler::UnresolvedPcRelativeCalls* unresolved_calls,
@@ -247,7 +247,7 @@
type_arguments_handles_(zone),
type_handles_(zone) {}
- RawTypeArguments* Instantiate(
+ TypeArgumentsPtr Instantiate(
const Class& klass,
const TypeArguments& type_arguments,
const TypeArguments& instantiator_type_arguments) {
@@ -260,7 +260,7 @@
const Class& klass,
const TypeArguments& type_arguments);
- RawAbstractType* InstantiateType(const AbstractType& type);
+ AbstractTypePtr InstantiateType(const AbstractType& type);
Class& klass_;
AbstractType& type_;
diff --git a/runtime/vm/type_testing_stubs_test.cc b/runtime/vm/type_testing_stubs_test.cc
index fccb41e..57e9459 100644
--- a/runtime/vm/type_testing_stubs_test.cc
+++ b/runtime/vm/type_testing_stubs_test.cc
@@ -47,8 +47,8 @@
const auto& symbol = String::Handle(
Symbols::New(thread, OS::SCreate(thread->zone(), "TTSTest")));
const auto& function = Function::Handle(
- Function::New(symbol, RawFunction::kRegularFunction, false, false, false,
- false, false, klass, TokenPosition::kNoSource));
+ Function::New(symbol, FunctionLayout::kRegularFunction, false, false,
+ false, false, false, klass, TokenPosition::kNoSource));
compiler::ObjectPoolBuilder pool_builder;
const auto& invoke_tts = Code::Handle(
StubCode::Generate("InvokeTTS", &pool_builder, &GenerateInvokeTTSStub));
diff --git a/runtime/vm/unit_test.cc b/runtime/vm/unit_test.cc
index 29c3245..2db8a7b 100644
--- a/runtime/vm/unit_test.cc
+++ b/runtime/vm/unit_test.cc
@@ -655,9 +655,9 @@
const Library& lib = Library::Handle(Library::CoreLibrary());
const Class& cls = Class::ZoneHandle(
Class::New(lib, function_name, script, TokenPosition::kMinSource));
- Function& function = Function::ZoneHandle(
- Function::New(function_name, RawFunction::kRegularFunction, true, false,
- false, false, false, cls, TokenPosition::kMinSource));
+ Function& function = Function::ZoneHandle(Function::New(
+ function_name, FunctionLayout::kRegularFunction, true, false, false,
+ false, false, cls, TokenPosition::kMinSource));
code_ = Code::FinalizeCodeAndNotify(function, nullptr, assembler_,
Code::PoolAttachment::kAttachPool);
code_.set_owner(function);
diff --git a/runtime/vm/unit_test.h b/runtime/vm/unit_test.h
index 21fc9cb..f576b71 100644
--- a/runtime/vm/unit_test.h
+++ b/runtime/vm/unit_test.h
@@ -540,8 +540,8 @@
const bool fp_args = false;
const bool fp_return = false;
Simulator::Current()->Call(
- bit_cast<intptr_t, uword>(entry()), reinterpret_cast<intptr_t>(arg1),
- reinterpret_cast<intptr_t>(arg2), reinterpret_cast<intptr_t>(arg3), 0,
+ bit_cast<intptr_t, uword>(entry()), static_cast<intptr_t>(arg1),
+ static_cast<intptr_t>(arg2), reinterpret_cast<intptr_t>(arg3), 0,
fp_return, fp_args);
}
#else
diff --git a/runtime/vm/visitor.h b/runtime/vm/visitor.h
index 2dd68f4..93baf0d 100644
--- a/runtime/vm/visitor.h
+++ b/runtime/vm/visitor.h
@@ -15,9 +15,6 @@
// Forward declarations.
class Isolate;
class IsolateGroup;
-class RawObject;
-class RawFunction;
-class RawTypedDataView;
// An object pointer visitor interface.
class ObjectPointerVisitor {
@@ -30,21 +27,21 @@
// Visit pointers inside the given typed data [view].
//
// Range of pointers to visit 'first' <= pointer <= 'last'.
- virtual void VisitTypedDataViewPointers(RawTypedDataView* view,
- RawObject** first,
- RawObject** last) {
+ virtual void VisitTypedDataViewPointers(TypedDataViewPtr view,
+ ObjectPtr* first,
+ ObjectPtr* last) {
VisitPointers(first, last);
}
// Range of pointers to visit 'first' <= pointer <= 'last'.
- virtual void VisitPointers(RawObject** first, RawObject** last) = 0;
+ virtual void VisitPointers(ObjectPtr* first, ObjectPtr* last) = 0;
// len argument is the number of pointers to visit starting from 'p'.
- void VisitPointers(RawObject** p, intptr_t len) {
+ void VisitPointers(ObjectPtr* p, intptr_t len) {
VisitPointers(p, (p + len - 1));
}
- void VisitPointer(RawObject** p) { VisitPointers(p, p); }
+ void VisitPointer(ObjectPtr* p) { VisitPointers(p, p); }
const char* gc_root_type() const { return gc_root_type_; }
void set_gc_root_type(const char* gc_root_type) {
@@ -75,7 +72,7 @@
virtual ~ObjectVisitor() {}
// Invoked for each object.
- virtual void VisitObject(RawObject* obj) = 0;
+ virtual void VisitObject(ObjectPtr obj) = 0;
private:
DISALLOW_COPY_AND_ASSIGN(ObjectVisitor);
@@ -95,7 +92,7 @@
}
// Check if object matches find condition.
- virtual bool FindObject(RawObject* obj) const = 0;
+ virtual bool FindObject(ObjectPtr obj) const = 0;
private:
DISALLOW_COPY_AND_ASSIGN(FindObjectVisitor);
diff --git a/sdk/BUILD.gn b/sdk/BUILD.gn
index b343437..8579a96 100644
--- a/sdk/BUILD.gn
+++ b/sdk/BUILD.gn
@@ -125,7 +125,7 @@
],
[
"dartdev",
- "../utils/dartdev",
+ "../utils/dartdev:generate_dartdev_snapshot",
],
[
"dartdoc",
@@ -170,7 +170,7 @@
],
[
"dartdev",
- "../utils/dartdev",
+ "../utils/dartdev:generate_dartdev_snapshot",
],
[
"dartdevc",
diff --git a/sdk/lib/_internal/js_dev_runtime/patch/core_patch.dart b/sdk/lib/_internal/js_dev_runtime/patch/core_patch.dart
index a220dac..dea22f5 100644
--- a/sdk/lib/_internal/js_dev_runtime/patch/core_patch.dart
+++ b/sdk/lib/_internal/js_dev_runtime/patch/core_patch.dart
@@ -166,19 +166,20 @@
static int _keyCount = 0;
}
-Null _kNull(_) => null;
-
@patch
class int {
@patch
static int parse(String source,
{int radix, @deprecated int onError(String source)}) {
- return Primitives.parseInt(source, radix, onError);
+ var value = tryParse(source, radix: radix);
+ if (value != null) return value;
+ if (onError != null) return onError(source);
+ throw new FormatException(source);
}
@patch
static int tryParse(String source, {int radix}) {
- return Primitives.parseInt(source, radix, _kNull);
+ return Primitives.parseInt(source, radix);
}
@patch
@@ -209,12 +210,15 @@
@patch
static double parse(String source,
[@deprecated double onError(String source)]) {
- return Primitives.parseDouble(source, onError);
+ var value = tryParse(source);
+ if (value != null) return value;
+ if (onError != null) return onError(source);
+ throw new FormatException('Invalid double', source);
}
@patch
static double tryParse(String source) {
- return Primitives.parseDouble(source, _kNull);
+ return Primitives.parseDouble(source);
}
@JSExportName('is')
diff --git a/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/types.dart b/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/types.dart
index 22d9d3d..5a95fef 100644
--- a/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/types.dart
+++ b/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/types.dart
@@ -271,7 +271,7 @@
/// normalization doc:
/// https://github.com/dart-lang/language/blob/master/resources/type-system/normalization.md
@notNull
-Object nullable(type) {
+Object nullable(@notNull Object type) {
// Check if a nullable version of this type has already been created.
var cached = JS<Object>('', '#[#]', type, _cachedNullable);
if (JS<bool>('!', '# !== void 0', cached)) {
@@ -284,7 +284,7 @@
return cachedType;
}
-Object _computeNullable(type) {
+Object _computeNullable(@notNull Object type) {
// *? normalizes to ?.
if (_jsInstanceOf(type, LegacyType)) {
return nullable(JS<Object>('!', '#.type', type));
@@ -309,7 +309,7 @@
/// normalization doc:
/// https://github.com/dart-lang/language/blob/master/resources/type-system/normalization.md
@notNull
-Object legacy(type) {
+Object legacy(@notNull Object type) {
// Check if a legacy version of this type has already been created.
var cached = JS<Object>('', '#[#]', type, _cachedLegacy);
if (JS<bool>('!', '# !== void 0', cached)) {
@@ -322,7 +322,7 @@
return cachedType;
}
-Object _computeLegacy(type) {
+Object _computeLegacy(@notNull Object type) {
// Note: ?* normalizes to ?, so we cache type? at type?[_cachedLegacy].
if (_jsInstanceOf(type, LegacyType) ||
_jsInstanceOf(type, NullableType) ||
@@ -337,7 +337,7 @@
class NullableType extends DartType {
final Type type;
- NullableType(this.type);
+ NullableType(@notNull this.type);
@override
String get name => '$type?';
@@ -358,7 +358,7 @@
class LegacyType extends DartType {
final Type type;
- LegacyType(this.type);
+ LegacyType(@notNull this.type);
@override
String get name => '$type';
@@ -1140,7 +1140,7 @@
})()''');
/// Returns true if [ft1] <: [ft2].
-_isFunctionSubtype(ft1, ft2, bool strictMode) => JS('', '''(() => {
+_isFunctionSubtype(ft1, ft2, @notNull bool strictMode) => JS('', '''(() => {
let ret1 = $ft1.returnType;
let ret2 = $ft2.returnType;
@@ -1233,7 +1233,7 @@
/// Returns true if [t1] <: [t2].
@notNull
-bool isSubtypeOf(Object t1, Object t2) {
+bool isSubtypeOf(@notNull Object t1, @notNull Object t2) {
// TODO(jmesserly): we've optimized `is`/`as`/implicit type checks, so they're
// dispatched on the type. Can we optimize the subtype relation too?
var map = JS<Object>('!', '#[#]', t1, _subtypeCache);
@@ -1313,7 +1313,7 @@
}
@notNull
-bool _isSubtype(t1, t2, bool strictMode) => JS<bool>('!', '''(() => {
+bool _isSubtype(t1, t2, @notNull bool strictMode) => JS<bool>('!', '''(() => {
if (!$strictMode) {
// Strip nullable types when performing check in weak mode.
// TODO(nshahan) Investigate stripping off legacy types as well.
@@ -1504,7 +1504,7 @@
return ${_isFunctionSubtype(t1, t2, strictMode)};
})()''');
-bool _isInterfaceSubtype(t1, t2, strictMode) => JS('', '''(() => {
+bool _isInterfaceSubtype(t1, t2, @notNull bool strictMode) => JS('', '''(() => {
// If we have lazy JS types, unwrap them. This will effectively
// reduce to a prototype check below.
if (${_jsInstanceOf(t1, LazyJSType)}) $t1 = $t1.rawJSTypeForCheck();
diff --git a/sdk/lib/_internal/js_dev_runtime/private/js_helper.dart b/sdk/lib/_internal/js_dev_runtime/private/js_helper.dart
index d14d9ed..b7d17d0d 100644
--- a/sdk/lib/_internal/js_dev_runtime/private/js_helper.dart
+++ b/sdk/lib/_internal/js_dev_runtime/private/js_helper.dart
@@ -70,14 +70,7 @@
}
class Primitives {
- @NoInline()
- static int _parseIntError(String source, int handleError(String source)) {
- if (handleError == null) throw FormatException(source);
- return handleError(source);
- }
-
- static int parseInt(
- @nullCheck String source, int _radix, int handleError(String source)) {
+ static int parseInt(@nullCheck String source, int _radix) {
var re = JS('', r'/^\s*[+-]?((0x[a-f0-9]+)|(\d+)|([a-z0-9]+))\s*$/i');
// TODO(jmesserly): this isn't reified List<String>, but it's safe to use as
// long as we use it locally and don't expose it to user code.
@@ -89,7 +82,7 @@
// TODO(sra): It might be that the match failed due to unrecognized U+0085
// spaces. We could replace them with U+0020 spaces and try matching
// again.
- return _parseIntError(source, handleError);
+ return null;
}
String decimalMatch = match[decimalIndex];
if (_radix == null) {
@@ -101,7 +94,7 @@
// Cannot fail because we know that the digits are all hex.
return JS<int>('!', r'parseInt(#, 16)', source);
}
- return _parseIntError(source, handleError);
+ return null;
}
@notNull
var radix = _radix;
@@ -138,7 +131,7 @@
for (int i = 0; i < digitsPart.length; i++) {
int characterCode = digitsPart.codeUnitAt(i) | 0x20;
if (characterCode > maxCharCode) {
- return _parseIntError(source, handleError);
+ return null;
}
}
}
@@ -147,17 +140,7 @@
return JS<int>('!', r'parseInt(#, #)', source, radix);
}
- @NoInline()
- static double _parseDoubleError(
- String source, double handleError(String source)) {
- if (handleError == null) {
- throw FormatException('Invalid double', source);
- }
- return handleError(source);
- }
-
- static double parseDouble(
- @nullCheck String source, double handleError(String source)) {
+ static double parseDouble(@nullCheck String source) {
// Notice that JS parseFloat accepts garbage at the end of the string.
// Accept only:
// - [+/-]NaN
@@ -169,15 +152,15 @@
r'/^\s*[+-]?(?:Infinity|NaN|'
r'(?:\.\d+|\d+(?:\.\d*)?)(?:[eE][+-]?\d+)?)\s*$/.test(#)',
source)) {
- return _parseDoubleError(source, handleError);
+ return null;
}
- num result = JS('!', r'parseFloat(#)', source);
+ var result = JS<double>('!', r'parseFloat(#)', source);
if (result.isNaN) {
var trimmed = source.trim();
if (trimmed == 'NaN' || trimmed == '+NaN' || trimmed == '-NaN') {
return result;
}
- return _parseDoubleError(source, handleError);
+ return null;
}
return result;
}
diff --git a/sdk/lib/_internal/js_runtime/lib/js_helper.dart b/sdk/lib/_internal/js_runtime/lib/js_helper.dart
index 338e8cf..d0e7ee1 100644
--- a/sdk/lib/_internal/js_runtime/lib/js_helper.dart
+++ b/sdk/lib/_internal/js_runtime/lib/js_helper.dart
@@ -416,7 +416,6 @@
int digitsIndex = 1;
int hexIndex = 2;
int decimalIndex = 3;
- int nonDecimalHexIndex = 4;
if (match == null) {
// TODO(sra): It might be that the match failed due to unrecognized U+0085
// spaces. We could replace them with U+0020 spaces and try matching
diff --git a/sdk/lib/_internal/vm/bin/vmservice_io.dart b/sdk/lib/_internal/vm/bin/vmservice_io.dart
index 7e3146d..06564f5 100644
--- a/sdk/lib/_internal/vm/bin/vmservice_io.dart
+++ b/sdk/lib/_internal/vm/bin/vmservice_io.dart
@@ -7,11 +7,8 @@
library vmservice_io;
import 'dart:async';
-import 'dart:collection';
import 'dart:convert';
import 'dart:io';
-import 'dart:isolate';
-import 'dart:typed_data';
import 'dart:_vmservice';
part 'vmservice_server.dart';
@@ -209,6 +206,11 @@
}
}
+void webServerAcceptNewWebSocketConnections(bool enable) {
+ _lazyServerBoot();
+ server.acceptNewWebSocketConnections = enable;
+}
+
Null _clearFuture(_) {
serverFuture = null;
}
@@ -254,6 +256,8 @@
VMServiceEmbedderHooks.listFiles = listFilesCallback;
VMServiceEmbedderHooks.serverInformation = serverInformationCallback;
VMServiceEmbedderHooks.webServerControl = webServerControlCallback;
+ VMServiceEmbedderHooks.acceptNewWebSocketConnections =
+ webServerAcceptNewWebSocketConnections;
// Always instantiate the vmservice object so that the exit message
// can be delivered and waiting loaders can be cancelled.
new VMService();
diff --git a/sdk/lib/_internal/vm/bin/vmservice_server.dart b/sdk/lib/_internal/vm/bin/vmservice_server.dart
index 06f39b6..26111d0 100644
--- a/sdk/lib/_internal/vm/bin/vmservice_server.dart
+++ b/sdk/lib/_internal/vm/bin/vmservice_server.dart
@@ -153,6 +153,7 @@
final String _serviceInfoFilename;
HttpServer _server;
bool get running => _server != null;
+ bool acceptNewWebSocketConnections = true;
int _port = -1;
/// Returns the server address including the auth token.
@@ -352,11 +353,19 @@
final String path = result;
if (path == WEBSOCKET_PATH) {
- WebSocketTransformer.upgrade(request,
- compression: CompressionOptions.compressionOff)
- .then((WebSocket webSocket) {
- new WebSocketClient(webSocket, _service);
- });
+ if (acceptNewWebSocketConnections) {
+ WebSocketTransformer.upgrade(request,
+ compression: CompressionOptions.compressionOff)
+ .then((WebSocket webSocket) {
+ new WebSocketClient(webSocket, _service);
+ });
+ } else {
+ request.response.statusCode = HttpStatus.forbidden;
+ request.response.write('Cannot connect directly to the VM service as '
+ 'a Dart Development Service (DDS) instance has taken control and '
+ 'can be found at ${_service.ddsUri}.');
+ request.response.close();
+ }
return;
}
diff --git a/sdk/lib/_internal/vm/lib/internal_patch.dart b/sdk/lib/_internal/vm/lib/internal_patch.dart
index 515ad8b..6accfc3 100644
--- a/sdk/lib/_internal/vm/lib/internal_patch.dart
+++ b/sdk/lib/_internal/vm/lib/internal_patch.dart
@@ -11,6 +11,7 @@
import "dart:core" hide Symbol;
+import "dart:isolate" show SendPort;
import "dart:typed_data" show Int32List;
/// These are the additional parts of this patch library:
@@ -130,3 +131,6 @@
// This is implemented by a recognized method, but in bytecode through a native.
@pragma('vm:prefer-inline')
void reachabilityFence(Object object) native "Internal_reachabilityFence";
+
+void sendAndExit(SendPort sendPort, var message)
+ native "SendPortImpl_sendAndExitInternal_";
diff --git a/sdk/lib/async/future_impl.dart b/sdk/lib/async/future_impl.dart
index c7cefce..df685d5 100644
--- a/sdk/lib/async/future_impl.dart
+++ b/sdk/lib/async/future_impl.dart
@@ -551,6 +551,10 @@
_chainFuture(value);
return;
}
+ _asyncCompleteWithValue(value);
+ }
+
+ void _asyncCompleteWithValue(T value) {
_setPendingComplete();
_zone.scheduleMicrotask(() {
_completeWithValue(value);
diff --git a/sdk/lib/vmservice/vmservice.dart b/sdk/lib/vmservice/vmservice.dart
index 81a2ac7..82ef7c2 100644
--- a/sdk/lib/vmservice/vmservice.dart
+++ b/sdk/lib/vmservice/vmservice.dart
@@ -179,6 +179,10 @@
/// Called when we want to [enable] or disable the web server.
typedef Future<Uri> WebServerControlCallback(bool enable);
+/// Called when we want to [enable] or disable new websocket connections to the
+/// server.
+typedef void WebServerAcceptNewWebSocketConnectionsCallback(bool enable);
+
/// Hooks that are setup by the embedder.
class VMServiceEmbedderHooks {
static ServerStartCallback serverStart;
@@ -192,6 +196,8 @@
static ListFilesCallback listFiles;
static ServerInformationCallback serverInformation;
static WebServerControlCallback webServerControl;
+ static WebServerAcceptNewWebSocketConnectionsCallback
+ acceptNewWebSocketConnections;
}
class _ClientResumePermissions {
@@ -224,6 +230,33 @@
final devfs = new DevFS();
+ Uri get ddsUri => _ddsUri;
+ Uri _ddsUri;
+
+ Future<String> _yieldControlToDDS(Message message) async {
+ final acceptNewWebSocketConnections =
+ VMServiceEmbedderHooks.acceptNewWebSocketConnections;
+ if (acceptNewWebSocketConnections == null) {
+ return encodeRpcError(message, kFeatureDisabled,
+ details:
+ 'Embedder does not support yielding to a VM service intermediary.');
+ }
+ final uri = message.params['uri'];
+ if (uri == null) {
+ return encodeMissingParamError(message, 'uri');
+ }
+ // DDS can only take control if there is no other clients connected
+ // directly to the VM service.
+ if (clients.length > 1) {
+ return encodeRpcError(message, kFeatureDisabled,
+ details:
+ 'Existing VM service clients prevent DDS from taking control.');
+ }
+ acceptNewWebSocketConnections(false);
+ _ddsUri = Uri.parse(uri);
+ return encodeSuccess(message);
+ }
+
void _clearClientName(Client client) {
final name = client.name;
client.name = null;
@@ -362,6 +395,16 @@
for (var handle in client.serviceHandles.values) {
handle(null);
}
+ if (clients.isEmpty) {
+ // If DDS was connected, we are in single client mode and need to
+ // allow for new websocket connections.
+ final acceptNewWebSocketConnections =
+ VMServiceEmbedderHooks.acceptNewWebSocketConnections;
+ if (_ddsUri != null && acceptNewWebSocketConnections != null) {
+ acceptNewWebSocketConnections(true);
+ _ddsUri = null;
+ }
+ }
}
void _eventMessageHandler(String streamId, Response event) {
@@ -725,6 +768,9 @@
if (message.completed) {
return await message.response;
}
+ if (message.method == '_yieldControlToDDS') {
+ return await _yieldControlToDDS(message);
+ }
if (message.method == 'streamListen') {
return await _streamListen(message);
}
diff --git a/sdk_nnbd/BUILD.gn b/sdk_nnbd/BUILD.gn
index b343437..8579a96 100644
--- a/sdk_nnbd/BUILD.gn
+++ b/sdk_nnbd/BUILD.gn
@@ -125,7 +125,7 @@
],
[
"dartdev",
- "../utils/dartdev",
+ "../utils/dartdev:generate_dartdev_snapshot",
],
[
"dartdoc",
@@ -170,7 +170,7 @@
],
[
"dartdev",
- "../utils/dartdev",
+ "../utils/dartdev:generate_dartdev_snapshot",
],
[
"dartdevc",
diff --git a/sdk_nnbd/lib/_internal/js_dev_runtime/patch/core_patch.dart b/sdk_nnbd/lib/_internal/js_dev_runtime/patch/core_patch.dart
index d2c62cf..1d3e398 100644
--- a/sdk_nnbd/lib/_internal/js_dev_runtime/patch/core_patch.dart
+++ b/sdk_nnbd/lib/_internal/js_dev_runtime/patch/core_patch.dart
@@ -167,19 +167,20 @@
static int _keyCount = 0;
}
-Null _kNull(_) => null;
-
@patch
class int {
@patch
static int parse(String source,
{int? radix, @deprecated int onError(String source)?}) {
- return Primitives.parseInt(source, radix, onError)!;
+ var value = tryParse(source, radix: radix);
+ if (value != null) return value;
+ if (onError != null) return onError(source);
+ throw new FormatException(source);
}
@patch
static int? tryParse(String source, {int? radix}) {
- return Primitives.parseInt(source, radix, _kNull);
+ return Primitives.parseInt(source, radix);
}
@patch
@@ -209,12 +210,15 @@
@patch
static double parse(String source,
[@deprecated double onError(String source)?]) {
- return Primitives.parseDouble(source, onError)!;
+ var value = tryParse(source);
+ if (value != null) return value;
+ if (onError != null) return onError(source);
+ throw new FormatException('Invalid double', source);
}
@patch
static double? tryParse(String source) {
- return Primitives.parseDouble(source, _kNull);
+ return Primitives.parseDouble(source);
}
@JSExportName('is')
diff --git a/sdk_nnbd/lib/_internal/js_dev_runtime/patch/internal_patch.dart b/sdk_nnbd/lib/_internal/js_dev_runtime/patch/internal_patch.dart
index 536b653..4d6a130 100644
--- a/sdk_nnbd/lib/_internal/js_dev_runtime/patch/internal_patch.dart
+++ b/sdk_nnbd/lib/_internal/js_dev_runtime/patch/internal_patch.dart
@@ -10,6 +10,14 @@
import 'dart:_foreign_helper' show JS;
import 'dart:_runtime' as dart;
+// TODO(41657) Make a constant when CFE evaluates in the null safety mode.
+var isLegacySubtyping = const <Null>[] is List<int>;
+
+@patch
+bool typeAcceptsNull<T>() {
+ return isLegacySubtyping || null is T;
+}
+
@patch
class Symbol implements core.Symbol {
@patch
diff --git a/sdk_nnbd/lib/_internal/js_dev_runtime/private/ddc_runtime/types.dart b/sdk_nnbd/lib/_internal/js_dev_runtime/private/ddc_runtime/types.dart
index e0c6c15..4d404ae 100644
--- a/sdk_nnbd/lib/_internal/js_dev_runtime/private/ddc_runtime/types.dart
+++ b/sdk_nnbd/lib/_internal/js_dev_runtime/private/ddc_runtime/types.dart
@@ -269,7 +269,7 @@
/// normalization doc:
/// https://github.com/dart-lang/language/blob/master/resources/type-system/normalization.md
@notNull
-Object nullable(type) {
+Object nullable(@notNull Object type) {
// Check if a nullable version of this type has already been created.
var cached = JS<Object>('', '#[#]', type, _cachedNullable);
if (JS<bool>('!', '# !== void 0', cached)) {
@@ -282,7 +282,7 @@
return cachedType;
}
-Object _computeNullable(type) {
+Object _computeNullable(@notNull Object type) {
// *? normalizes to ?.
if (_jsInstanceOf(type, LegacyType)) {
return nullable(JS<Object>('!', '#.type', type));
@@ -307,7 +307,7 @@
/// normalization doc:
/// https://github.com/dart-lang/language/blob/master/resources/type-system/normalization.md
@notNull
-Object legacy(type) {
+Object legacy(@notNull Object type) {
// Check if a legacy version of this type has already been created.
var cached = JS<Object>('', '#[#]', type, _cachedLegacy);
if (JS<bool>('!', '# !== void 0', cached)) {
@@ -320,7 +320,7 @@
return cachedType;
}
-Object _computeLegacy(type) {
+Object _computeLegacy(@notNull Object type) {
// Note: ?* normalizes to ?, so we cache type? at type?[_cachedLegacy].
if (_jsInstanceOf(type, LegacyType) ||
_jsInstanceOf(type, NullableType) ||
@@ -335,7 +335,7 @@
class NullableType extends DartType {
final Type type;
- NullableType(this.type);
+ NullableType(@notNull this.type);
@override
String get name => '$type?';
@@ -356,7 +356,7 @@
class LegacyType extends DartType {
final Type type;
- LegacyType(this.type);
+ LegacyType(@notNull this.type);
@override
String get name => '$type';
@@ -1138,7 +1138,7 @@
})()''');
/// Returns true if [ft1] <: [ft2].
-_isFunctionSubtype(ft1, ft2, bool strictMode) => JS('', '''(() => {
+_isFunctionSubtype(ft1, ft2, @notNull bool strictMode) => JS('', '''(() => {
let ret1 = $ft1.returnType;
let ret2 = $ft2.returnType;
@@ -1231,7 +1231,7 @@
/// Returns true if [t1] <: [t2].
@notNull
-bool isSubtypeOf(Object t1, Object t2) {
+bool isSubtypeOf(@notNull Object t1, @notNull Object t2) {
// TODO(jmesserly): we've optimized `is`/`as`/implicit type checks, so they're
// dispatched on the type. Can we optimize the subtype relation too?
var map = JS<Object>('!', '#[#]', t1, _subtypeCache);
@@ -1311,7 +1311,7 @@
}
@notNull
-bool _isSubtype(t1, t2, bool strictMode) => JS<bool>('!', '''(() => {
+bool _isSubtype(t1, t2, @notNull bool strictMode) => JS<bool>('!', '''(() => {
if (!$strictMode) {
// Strip nullable types when performing check in weak mode.
// TODO(nshahan) Investigate stripping off legacy types as well.
@@ -1502,7 +1502,7 @@
return ${_isFunctionSubtype(t1, t2, strictMode)};
})()''');
-bool _isInterfaceSubtype(t1, t2, strictMode) => JS('', '''(() => {
+bool _isInterfaceSubtype(t1, t2, @notNull bool strictMode) => JS('', '''(() => {
// If we have lazy JS types, unwrap them. This will effectively
// reduce to a prototype check below.
if (${_jsInstanceOf(t1, LazyJSType)}) $t1 = $t1.rawJSTypeForCheck();
diff --git a/sdk_nnbd/lib/_internal/js_dev_runtime/private/js_helper.dart b/sdk_nnbd/lib/_internal/js_dev_runtime/private/js_helper.dart
index 644dba1..11a3a8e 100644
--- a/sdk_nnbd/lib/_internal/js_dev_runtime/private/js_helper.dart
+++ b/sdk_nnbd/lib/_internal/js_dev_runtime/private/js_helper.dart
@@ -68,15 +68,7 @@
}
class Primitives {
- @NoInline()
- static int? _parseIntError(
- String source, int? Function(String)? handleError) {
- if (handleError == null) throw FormatException(source);
- return handleError(source);
- }
-
- static int? parseInt(@nullCheck String source, int? _radix,
- int? Function(String)? handleError) {
+ static int? parseInt(@nullCheck String source, int? _radix) {
var re = JS('', r'/^\s*[+-]?((0x[a-f0-9]+)|(\d+)|([a-z0-9]+))\s*$/i');
// TODO(jmesserly): this isn't reified List<String>, but it's safe to use as
// long as we use it locally and don't expose it to user code.
@@ -88,7 +80,7 @@
// TODO(sra): It might be that the match failed due to unrecognized U+0085
// spaces. We could replace them with U+0020 spaces and try matching
// again.
- return _parseIntError(source, handleError);
+ return null;
}
String? decimalMatch = match[decimalIndex];
if (_radix == null) {
@@ -100,7 +92,7 @@
// Cannot fail because we know that the digits are all hex.
return JS<int>('!', r'parseInt(#, 16)', source);
}
- return _parseIntError(source, handleError);
+ return null;
}
@notNull
var radix = _radix;
@@ -137,7 +129,7 @@
for (int i = 0; i < digitsPart.length; i++) {
int characterCode = digitsPart.codeUnitAt(i) | 0x20;
if (characterCode > maxCharCode) {
- return _parseIntError(source, handleError);
+ return null;
}
}
}
@@ -146,17 +138,7 @@
return JS<int>('!', r'parseInt(#, #)', source, radix);
}
- @NoInline()
- static double? _parseDoubleError(
- String source, double? Function(String)? handleError) {
- if (handleError == null) {
- throw FormatException('Invalid double', source);
- }
- return handleError(source);
- }
-
- static double? parseDouble(
- @nullCheck String source, double? Function(String)? handleError) {
+ static double? parseDouble(@nullCheck String source) {
// Notice that JS parseFloat accepts garbage at the end of the string.
// Accept only:
// - [+/-]NaN
@@ -168,15 +150,15 @@
r'/^\s*[+-]?(?:Infinity|NaN|'
r'(?:\.\d+|\d+(?:\.\d*)?)(?:[eE][+-]?\d+)?)\s*$/.test(#)',
source)) {
- return _parseDoubleError(source, handleError);
+ return null;
}
- double result = JS('!', r'parseFloat(#)', source);
+ var result = JS<double>('!', r'parseFloat(#)', source);
if (result.isNaN) {
var trimmed = source.trim();
if (trimmed == 'NaN' || trimmed == '+NaN' || trimmed == '-NaN') {
return result;
}
- return _parseDoubleError(source, handleError);
+ return null;
}
return result;
}
diff --git a/sdk_nnbd/lib/_internal/js_runtime/lib/async_patch.dart b/sdk_nnbd/lib/_internal/js_runtime/lib/async_patch.dart
index 45c0f03..45ed0c5 100644
--- a/sdk_nnbd/lib/_internal/js_runtime/lib/async_patch.dart
+++ b/sdk_nnbd/lib/_internal/js_runtime/lib/async_patch.dart
@@ -196,10 +196,19 @@
_AsyncAwaitCompleter() : isSync = false;
void complete([FutureOr<T>? value]) {
- if (!isSync || value is Future<T>) {
- _future._asyncComplete(value as FutureOr<T>);
+ // All paths require that if value is null, null as T succeeds.
+ value = (value == null) ? value as T : value;
+ if (!isSync) {
+ _future._asyncComplete(value);
+ } else if (value is Future<T>) {
+ assert(!_future._isComplete);
+ _future._chainFuture(value);
} else {
- _future._completeWithValue(value as T);
+ // TODO(40014): Remove cast when type promotion works.
+ // This would normally be `as T` but we use `as dynamic` to make the
+ // unneeded check be implict to match dart2js unsound optimizations in the
+ // user code.
+ _future._completeWithValue(value as dynamic);
}
}
@@ -566,9 +575,7 @@
T? _current = null;
// This is the nested iterator when iterating a yield* of a non-sync iterator.
- // TODO(32956): In strong-mode, yield* takes an Iterable<T> (possibly checked
- // with an implicit downcast), so change type to Iterator<T>.
- Iterator? _nestedIterator = null;
+ Iterator<T>? _nestedIterator = null;
// Stack of suspended state machines when iterating a yield* of a sync*
// iterator.
@@ -578,9 +585,8 @@
T get current {
var nested = _nestedIterator;
- if (nested == null) return _current as T;
- // Don't merge this with above 'as T', the one above can be optimized.
- return nested.current as T;
+ if (nested == null) return _current as dynamic; // implicit: as T;
+ return nested.current;
}
_runBody() {
@@ -637,8 +643,12 @@
JS('', 'throw #', value.value);
} else {
assert(state == _IterationMarker.YIELD_STAR);
- Iterator inner = value.value.iterator;
+ Iterator<T> inner = value.value.iterator;
if (inner is _SyncStarIterator) {
+ // The test needs to be 'is _SyncStarIterator<T>' for promotion to
+ // work. However, that test is much more expensive, so we use an
+ // unsafe cast.
+ _SyncStarIterator<T> innerSyncStarIterator = JS('', '#', inner);
// Suspend the current state machine and start acting on behalf of
// the nested state machine.
//
@@ -646,7 +656,7 @@
// suspending the current body when all it will do is step without
// effect to ITERATION_ENDED.
(_suspendedBodies ??= []).add(_body);
- _body = inner._body;
+ _body = innerSyncStarIterator._body;
continue;
} else {
_nestedIterator = inner;
diff --git a/sdk_nnbd/lib/_internal/js_runtime/lib/collection_patch.dart b/sdk_nnbd/lib/_internal/js_runtime/lib/collection_patch.dart
index 2b8bd25..a1d76bf 100644
--- a/sdk_nnbd/lib/_internal/js_runtime/lib/collection_patch.dart
+++ b/sdk_nnbd/lib/_internal/js_runtime/lib/collection_patch.dart
@@ -1324,12 +1324,12 @@
if (_isStringElement(object)) {
var strings = _strings;
if (strings == null) return false;
- _LinkedHashSetCell cell = _getTableEntry(strings, object);
+ _LinkedHashSetCell? cell = _getTableEntry(strings, object);
return cell != null;
} else if (_isNumericElement(object)) {
var nums = _nums;
if (nums == null) return false;
- _LinkedHashSetCell cell = _getTableEntry(nums, object);
+ _LinkedHashSetCell? cell = _getTableEntry(nums, object);
return cell != null;
} else {
return _contains(object);
@@ -1474,7 +1474,7 @@
}
bool _addHashTableEntry(var table, E element) {
- _LinkedHashSetCell cell = _getTableEntry(table, element);
+ _LinkedHashSetCell? cell = _getTableEntry(table, element);
if (cell != null) return false;
_setTableEntry(table, element, _newLinkedCell(element));
return true;
@@ -1482,7 +1482,7 @@
bool _removeHashTableEntry(var table, Object? element) {
if (table == null) return false;
- _LinkedHashSetCell cell = _getTableEntry(table, element);
+ _LinkedHashSetCell? cell = _getTableEntry(table, element);
if (cell == null) return false;
_unlinkCell(cell);
_deleteTableEntry(table, element);
diff --git a/sdk_nnbd/lib/_internal/js_runtime/lib/core_patch.dart b/sdk_nnbd/lib/_internal/js_runtime/lib/core_patch.dart
index 9d1a8d6..232cc8d 100644
--- a/sdk_nnbd/lib/_internal/js_runtime/lib/core_patch.dart
+++ b/sdk_nnbd/lib/_internal/js_runtime/lib/core_patch.dart
@@ -639,7 +639,7 @@
return string;
}
- static String _writeOne(String string, Object obj) {
+ static String _writeOne(String string, Object? obj) {
return Primitives.stringConcatUnchecked(string, '$obj');
}
}
diff --git a/sdk_nnbd/lib/_internal/js_runtime/lib/internal_patch.dart b/sdk_nnbd/lib/_internal/js_runtime/lib/internal_patch.dart
index 8483315..e2922ca 100644
--- a/sdk_nnbd/lib/_internal/js_runtime/lib/internal_patch.dart
+++ b/sdk_nnbd/lib/_internal/js_runtime/lib/internal_patch.dart
@@ -10,6 +10,13 @@
import 'dart:_foreign_helper' show JS, JS_GET_FLAG;
@patch
+@pragma('dart2js:tryInline')
+bool typeAcceptsNull<T>() {
+ bool isLegacySubtyping = JS_GET_FLAG('LEGACY');
+ return isLegacySubtyping || null is T;
+}
+
+@patch
class Symbol implements core.Symbol {
@patch
const Symbol(String name) : this._name = name;
diff --git a/sdk_nnbd/lib/_internal/js_runtime/lib/js_helper.dart b/sdk_nnbd/lib/_internal/js_runtime/lib/js_helper.dart
index 994ea2d..9c74300 100644
--- a/sdk_nnbd/lib/_internal/js_runtime/lib/js_helper.dart
+++ b/sdk_nnbd/lib/_internal/js_runtime/lib/js_helper.dart
@@ -414,14 +414,13 @@
int digitsIndex = 1;
int hexIndex = 2;
int decimalIndex = 3;
- int nonDecimalHexIndex = 4;
if (match == null) {
// TODO(sra): It might be that the match failed due to unrecognized U+0085
// spaces. We could replace them with U+0020 spaces and try matching
// again.
return null;
}
- String decimalMatch = match[decimalIndex];
+ Object? decimalMatch = match[decimalIndex];
if (radix == null) {
if (decimalMatch != null) {
// Cannot fail because we know that the digits are all decimal.
diff --git a/sdk_nnbd/lib/_internal/vm/bin/vmservice_io.dart b/sdk_nnbd/lib/_internal/vm/bin/vmservice_io.dart
index 2dc17b1..aea026b 100644
--- a/sdk_nnbd/lib/_internal/vm/bin/vmservice_io.dart
+++ b/sdk_nnbd/lib/_internal/vm/bin/vmservice_io.dart
@@ -196,6 +196,11 @@
return _server.serverAddress;
}
+void webServerAcceptNewWebSocketConnections(bool enable) {
+ final _server = _lazyServerBoot();
+ _server.acceptNewWebSocketConnections = enable;
+}
+
void _clearFuture(_) {
serverFuture = null;
}
@@ -241,6 +246,8 @@
VMServiceEmbedderHooks.listFiles = listFilesCallback;
VMServiceEmbedderHooks.serverInformation = serverInformationCallback;
VMServiceEmbedderHooks.webServerControl = webServerControlCallback;
+ VMServiceEmbedderHooks.acceptNewWebSocketConnections =
+ webServerAcceptNewWebSocketConnections;
// Always instantiate the vmservice object so that the exit message
// can be delivered and waiting loaders can be cancelled.
VMService();
diff --git a/sdk_nnbd/lib/_internal/vm/bin/vmservice_server.dart b/sdk_nnbd/lib/_internal/vm/bin/vmservice_server.dart
index ed723fb..d1a5a7c 100644
--- a/sdk_nnbd/lib/_internal/vm/bin/vmservice_server.dart
+++ b/sdk_nnbd/lib/_internal/vm/bin/vmservice_server.dart
@@ -153,6 +153,7 @@
final String? _serviceInfoFilename;
HttpServer? _server;
bool get running => _server != null;
+ bool acceptNewWebSocketConnections = true;
int _port = -1;
/// Returns the server address including the auth token.
@@ -354,11 +355,19 @@
final String path = result;
if (path == WEBSOCKET_PATH) {
- WebSocketTransformer.upgrade(request,
- compression: CompressionOptions.compressionOff)
- .then((WebSocket webSocket) {
- WebSocketClient(webSocket, _service);
- });
+ if (acceptNewWebSocketConnections) {
+ WebSocketTransformer.upgrade(request,
+ compression: CompressionOptions.compressionOff)
+ .then((WebSocket webSocket) {
+ WebSocketClient(webSocket, _service);
+ });
+ } else {
+ request.response.statusCode = HttpStatus.forbidden;
+ request.response.write('Cannot connect directly to the VM service as '
+ 'a Dart Development Service (DDS) instance has taken control and '
+ 'can be found at ${_service.ddsUri}.');
+ request.response.close();
+ }
return;
}
diff --git a/sdk_nnbd/lib/_internal/vm/lib/async_patch.dart b/sdk_nnbd/lib/_internal/vm/lib/async_patch.dart
index 3020fea..c3201d3 100644
--- a/sdk_nnbd/lib/_internal/vm/lib/async_patch.dart
+++ b/sdk_nnbd/lib/_internal/vm/lib/async_patch.dart
@@ -28,9 +28,15 @@
@pragma("vm:entry-point")
void complete([FutureOr<T>? value]) {
- if (!isSync || value is Future<T>) {
- _future._asyncComplete(value as FutureOr<T>);
+ // All paths require that if value is null, null as T succeeds.
+ value = (value == null) ? value as T : value;
+ if (!isSync) {
+ _future._asyncComplete(value);
+ } else if (value is Future<T>) {
+ assert(!_future._isComplete);
+ _future._chainFuture(value);
} else {
+ // TODO(40014): Remove cast when type promotion works.
_future._completeWithValue(value as T);
}
}
diff --git a/sdk_nnbd/lib/_internal/vm/lib/internal_patch.dart b/sdk_nnbd/lib/_internal/vm/lib/internal_patch.dart
index ddb3992..b484a2c 100644
--- a/sdk_nnbd/lib/_internal/vm/lib/internal_patch.dart
+++ b/sdk_nnbd/lib/_internal/vm/lib/internal_patch.dart
@@ -9,6 +9,7 @@
import "dart:core" hide Symbol;
+import "dart:isolate" show SendPort;
import "dart:typed_data" show Int32List;
/// These are the additional parts of this patch library:
@@ -16,6 +17,12 @@
// part "print_patch.dart";
// part "symbol_patch.dart";
+// On the VM, we don't make the entire legacy weak mode check
+// const to avoid having a constant in the platform libraries
+// which evaluates differently in weak vs strong mode.
+@patch
+bool typeAcceptsNull<T>() => (const <Null>[]) is List<int> || null is T;
+
@patch
List<T> makeListFixedLength<T>(List<T> growableList)
native "Internal_makeListFixedLength";
@@ -128,3 +135,6 @@
// This is implemented by a recognized method, but in bytecode through a native.
@pragma('vm:prefer-inline')
void reachabilityFence(Object object) native "Internal_reachabilityFence";
+
+void sendAndExit(SendPort sendPort, var message)
+ native "SendPortImpl_sendAndExitInternal_";
diff --git a/sdk_nnbd/lib/async/async.dart b/sdk_nnbd/lib/async/async.dart
index 616375c..8cce959 100644
--- a/sdk_nnbd/lib/async/async.dart
+++ b/sdk_nnbd/lib/async/async.dart
@@ -102,7 +102,8 @@
IterableElementError,
printToZone,
printToConsole,
- Since;
+ Since,
+ typeAcceptsNull;
part 'async_error.dart';
part 'broadcast_stream_controller.dart';
diff --git a/sdk_nnbd/lib/async/broadcast_stream_controller.dart b/sdk_nnbd/lib/async/broadcast_stream_controller.dart
index 3684a7c..c362eea 100644
--- a/sdk_nnbd/lib/async/broadcast_stream_controller.dart
+++ b/sdk_nnbd/lib/async/broadcast_stream_controller.dart
@@ -380,7 +380,9 @@
if (_isEmpty) return;
if (_hasOneListener) {
_state |= _BroadcastStreamController._STATE_FIRING;
- (_firstSubscription as _BroadcastSubscription<T>)._add(data);
+ _BroadcastSubscription<T> firstSubscription =
+ _firstSubscription as dynamic;
+ firstSubscription._add(data);
_state &= ~_BroadcastStreamController._STATE_FIRING;
if (_isEmpty) {
_callOnCancel();
diff --git a/sdk_nnbd/lib/async/future.dart b/sdk_nnbd/lib/async/future.dart
index 3de7374..8a43bce 100644
--- a/sdk_nnbd/lib/async/future.dart
+++ b/sdk_nnbd/lib/async/future.dart
@@ -258,7 +258,7 @@
*/
@pragma("vm:entry-point")
factory Future.value([FutureOr<T>? value]) {
- return new _Future<T>.immediate(value as FutureOr<T>);
+ return new _Future<T>.immediate(value == null ? value as dynamic : value);
}
/**
@@ -311,7 +311,7 @@
* later time that isn't necessarily after a known fixed duration.
*/
factory Future.delayed(Duration duration, [FutureOr<T> computation()?]) {
- if (computation == null && const <Null>[] is! List<T>) {
+ if (computation == null && !typeAcceptsNull<T>()) {
throw ArgumentError.value(
null, "computation", "The type parameter is not nullable");
}
@@ -368,9 +368,7 @@
late StackTrace stackTrace; // The stackTrace that came with the error.
// Handle an error from any of the futures.
- // TODO(jmesserly): use `void` return type once it can be inferred for the
- // `then` call below.
- handleError(Object theError, StackTrace theStackTrace) {
+ void handleError(Object theError, StackTrace theStackTrace) {
remaining--;
List<T?>? valueList = values;
if (valueList != null) {
@@ -411,8 +409,6 @@
result._completeWithValue(List<T>.from(valueList));
}
} else {
- // Forced read of error to assert that it has occurred earlier.
- assert(error != null);
if (cleanUp != null && value != null) {
// Ensure errors from cleanUp are uncaught.
new Future.sync(() {
@@ -420,6 +416,8 @@
});
}
if (remaining == 0 && !eagerError) {
+ // If eagerError is false, and valueList is null, then
+ // error and stackTrace have been set in handleError above.
result._completeError(error, stackTrace);
}
}
@@ -559,6 +557,7 @@
result.then(nextIteration, onError: doneSignal._completeError);
return;
}
+ // TODO(40014): Remove cast when type promotion works.
keepGoing = result as bool;
}
doneSignal._complete(null);
diff --git a/sdk_nnbd/lib/async/future_impl.dart b/sdk_nnbd/lib/async/future_impl.dart
index 11c8f26..3f33737 100644
--- a/sdk_nnbd/lib/async/future_impl.dart
+++ b/sdk_nnbd/lib/async/future_impl.dart
@@ -41,7 +41,7 @@
class _AsyncCompleter<T> extends _Completer<T> {
void complete([FutureOr<T>? value]) {
if (!future._mayComplete) throw new StateError("Future already completed");
- future._asyncComplete(value as FutureOr<T>);
+ future._asyncComplete(value == null ? value as dynamic : value);
}
void _completeError(Object error, StackTrace stackTrace) {
@@ -52,7 +52,7 @@
class _SyncCompleter<T> extends _Completer<T> {
void complete([FutureOr<T>? value]) {
if (!future._mayComplete) throw new StateError("Future already completed");
- future._complete(value as FutureOr<T>);
+ future._complete(value == null ? value as dynamic : value);
}
void _completeError(Object error, StackTrace stackTrace) {
@@ -116,19 +116,19 @@
FutureOr<T> Function(S) get _onValue {
assert(handlesValue);
- return callback as FutureOr<T> Function(S);
+ return callback as dynamic;
}
Function? get _onError => errorCallback;
_FutureErrorTest get _errorTest {
assert(hasErrorTest);
- return callback as _FutureErrorTest;
+ return callback as dynamic;
}
_FutureAction get _whenCompleteAction {
assert(handlesComplete);
- return callback as _FutureAction;
+ return callback as dynamic;
}
/// Whether this listener has an error callback.
@@ -158,7 +158,7 @@
errorCallback, asyncError.error, asyncError.stackTrace);
} else {
return _zone.runUnary<dynamic, Object>(
- errorCallback as dynamic Function(Object), asyncError.error);
+ errorCallback as dynamic, asyncError.error);
}
}
@@ -554,13 +554,17 @@
_chainFuture(value);
return;
}
+ // TODO(40014): Remove cast when type promotion works.
+ // This would normally be `as T` but we use `as dynamic` to make the
+ // unneeded check be implict to match dart2js unsound optimizations in the
+ // user code.
+ _asyncCompleteWithValue(value as dynamic); // Value promoted to T.
+ }
+
+ void _asyncCompleteWithValue(T value) {
_setPendingComplete();
_zone.scheduleMicrotask(() {
- // TODO(40014): Remove cast when type promotion works.
- // This would normally be `as T` but we use `as dynamic` to make the
- // unneeded check be implict to match dart2js unsound optimizations in the
- // user code.
- _completeWithValue(value as dynamic); // Value promoted to T.
+ _completeWithValue(value);
});
}
@@ -669,15 +673,15 @@
listenerHasError = true;
return;
}
- if (completeResult is Future) {
- if (completeResult is _Future && completeResult._isComplete) {
- if (completeResult._hasError) {
- listenerValueOrError = completeResult._error;
- listenerHasError = true;
- }
- // Otherwise use the existing result of source.
- return;
+ if (completeResult is _Future && completeResult._isComplete) {
+ if (completeResult._hasError) {
+ listenerValueOrError = completeResult._error;
+ listenerHasError = true;
}
+ // Otherwise use the existing result of source.
+ return;
+ }
+ if (completeResult is Future) {
// We have to wait for the completeResult future to complete
// before knowing if it's an error or we should use the result
// of source.
diff --git a/sdk_nnbd/lib/async/stream.dart b/sdk_nnbd/lib/async/stream.dart
index 241c706..46ec161 100644
--- a/sdk_nnbd/lib/async/stream.dart
+++ b/sdk_nnbd/lib/async/stream.dart
@@ -263,7 +263,7 @@
*/
factory Stream.periodic(Duration period,
[T computation(int computationCount)?]) {
- if (computation == null && const <Null>[] is! List<T>) {
+ if (computation == null && !typeAcceptsNull<T>()) {
throw ArgumentError.value(null, "computation",
"Must not be omitted when the event type is non-nullable");
}
@@ -1074,7 +1074,9 @@
* The [futureValue] must not be omitted if `null` is not assignable to [E].
*/
Future<E> drain<E>([E? futureValue]) {
- futureValue = futureValue as E;
+ if (futureValue == null) {
+ futureValue = futureValue as E;
+ }
return listen(null, cancelOnError: true).asFuture<E>(futureValue);
}
diff --git a/sdk_nnbd/lib/async/stream_controller.dart b/sdk_nnbd/lib/async/stream_controller.dart
index 8b7d786..0c0a93a 100644
--- a/sdk_nnbd/lib/async/stream_controller.dart
+++ b/sdk_nnbd/lib/async/stream_controller.dart
@@ -515,9 +515,9 @@
_PendingEvents<T>? get _pendingEvents {
assert(_isInitialState);
if (!_isAddingStream) {
- return _varData as _PendingEvents<T>?;
+ return _varData as dynamic;
}
- var state = _varData as _StreamControllerAddStreamState<T>;
+ _StreamControllerAddStreamState<T> state = _varData as dynamic;
return state.varData;
}
@@ -526,17 +526,17 @@
assert(_isInitialState);
if (!_isAddingStream) {
Object? events = _varData;
- if (events is! _StreamImplEvents<T>) {
+ if (events == null) {
_varData = events = _StreamImplEvents<T>();
}
- return events;
+ return events as dynamic;
}
- var state = _varData as _StreamControllerAddStreamState<T>;
+ _StreamControllerAddStreamState<T> state = _varData as dynamic;
Object? events = state.varData;
- if (events is! _StreamImplEvents<T>) {
+ if (events == null) {
state.varData = events = _StreamImplEvents<T>();
}
- return events;
+ return events as dynamic;
}
// Get the current subscription.
@@ -546,9 +546,10 @@
assert(hasListener);
Object? varData = _varData;
if (_isAddingStream) {
- varData = (varData as _StreamControllerAddStreamState<Object?>).varData;
+ _StreamControllerAddStreamState<Object?> streamState = varData as dynamic;
+ varData = streamState.varData;
}
- return varData as _ControllerSubscription<T>;
+ return varData as dynamic;
}
/**
@@ -668,7 +669,7 @@
void _close() {
// End of addStream stream.
assert(_isAddingStream);
- var addState = _varData as _StreamControllerAddStreamState<T>;
+ _StreamControllerAddStreamState<T> addState = _varData as dynamic;
_varData = addState.varData;
_state &= ~_STATE_ADDSTREAM;
addState.complete();
@@ -687,7 +688,7 @@
_PendingEvents<T>? pendingEvents = _pendingEvents;
_state |= _STATE_SUBSCRIBED;
if (_isAddingStream) {
- var addState = _varData as _StreamControllerAddStreamState<T>;
+ _StreamControllerAddStreamState<T> addState = _varData as dynamic;
addState.varData = subscription;
addState.resume();
} else {
@@ -712,7 +713,7 @@
// returned future.
Future<void>? result;
if (_isAddingStream) {
- var addState = _varData as _StreamControllerAddStreamState<T>;
+ _StreamControllerAddStreamState<T> addState = _varData as dynamic;
result = addState.cancel();
}
_varData = null;
@@ -759,7 +760,7 @@
void _recordPause(StreamSubscription<T> subscription) {
if (_isAddingStream) {
- var addState = _varData as _StreamControllerAddStreamState<T>;
+ _StreamControllerAddStreamState<T> addState = _varData as dynamic;
addState.pause();
}
_runGuarded(onPause);
@@ -767,7 +768,7 @@
void _recordResume(StreamSubscription<T> subscription) {
if (_isAddingStream) {
- var addState = _varData as _StreamControllerAddStreamState<T>;
+ _StreamControllerAddStreamState<T> addState = _varData as dynamic;
addState.resume();
}
_runGuarded(onResume);
diff --git a/sdk_nnbd/lib/async/stream_impl.dart b/sdk_nnbd/lib/async/stream_impl.dart
index 4404d78..1c6fa50 100644
--- a/sdk_nnbd/lib/async/stream_impl.dart
+++ b/sdk_nnbd/lib/async/stream_impl.dart
@@ -213,26 +213,31 @@
}
Future<E> asFuture<E>([E? futureValue]) {
- if (futureValue is E) {
- // Overwrite the onDone and onError handlers.
- _Future<E> result = new _Future<E>();
- E resultValue = futureValue;
- _onDone = () {
- result._complete(resultValue);
- };
- _onError = (Object error, StackTrace stackTrace) {
- Future cancelFuture = cancel();
- if (!identical(cancelFuture, Future._nullFuture)) {
- cancelFuture.whenComplete(() {
- result._completeError(error, stackTrace);
- });
- } else {
- result._completeError(error, stackTrace);
- }
- };
- return result;
+ E resultValue;
+ if (futureValue == null) {
+ if (!typeAcceptsNull<E>()) {
+ throw ArgumentError.notNull("futureValue");
+ }
+ resultValue = futureValue as dynamic;
+ } else {
+ resultValue = futureValue;
}
- throw ArgumentError.notNull("futureValue");
+ // Overwrite the onDone and onError handlers.
+ _Future<E> result = new _Future<E>();
+ _onDone = () {
+ result._complete(resultValue);
+ };
+ _onError = (Object error, StackTrace stackTrace) {
+ Future cancelFuture = cancel();
+ if (!identical(cancelFuture, Future._nullFuture)) {
+ cancelFuture.whenComplete(() {
+ result._completeError(error, stackTrace);
+ });
+ } else {
+ result._completeError(error, stackTrace);
+ }
+ };
+ return result;
}
// State management.
@@ -329,7 +334,9 @@
* of pending events later (if necessary).
*/
void _addPending(_DelayedEvent event) {
- var pending = (_pending ??= _StreamImplEvents<T>()) as _StreamImplEvents<T>;
+ _StreamImplEvents<T>? pending = _pending as dynamic;
+ pending ??= _StreamImplEvents<T>();
+ _pending = pending;
pending.add(event);
if (!_hasPending) {
_state |= _STATE_HAS_PENDING;
@@ -368,7 +375,7 @@
if (onError is void Function(Object, StackTrace)) {
_zone.runBinaryGuarded<Object, StackTrace>(onError, error, stackTrace);
} else {
- _zone.runUnaryGuarded<Object>(_onError as void Function(Object), error);
+ _zone.runUnaryGuarded<Object>(_onError as dynamic, error);
}
_state &= ~_STATE_IN_CALLBACK;
}
@@ -780,15 +787,20 @@
Future cancel() => Future._nullFuture;
Future<E> asFuture<E>([E? futureValue]) {
- if (futureValue is E) {
- _Future<E> result = new _Future<E>();
- E resultValue = futureValue;
- _onDone = () {
- result._completeWithValue(resultValue);
- };
- return result;
+ E resultValue;
+ if (futureValue == null) {
+ if (!typeAcceptsNull<E>()) {
+ throw ArgumentError.notNull("futureValue");
+ }
+ resultValue = futureValue as dynamic;
+ } else {
+ resultValue = futureValue;
}
- throw ArgumentError.notNull("futureValue");
+ _Future<E> result = new _Future<E>();
+ _onDone = () {
+ result._completeWithValue(resultValue);
+ };
+ return result;
}
void _sendDone() {
@@ -806,7 +818,7 @@
final _BroadcastCallback<T>? _onCancelHandler;
final Zone _zone;
- late _AsBroadcastStreamController<T>? _controller;
+ _AsBroadcastStreamController<T>? _controller;
StreamSubscription<T>? _subscription;
_AsBroadcastStream(
@@ -996,9 +1008,9 @@
T get current {
if (_subscription != null && _isPaused) {
- return _stateData as T;
+ return _stateData as dynamic;
}
- return null as T;
+ return null as dynamic;
}
Future<bool> moveNext() {
@@ -1025,7 +1037,7 @@
assert(_subscription == null);
var stateData = _stateData;
if (stateData != null) {
- var stream = stateData as Stream<T>;
+ Stream<T> stream = stateData as dynamic;
_subscription = stream.listen(_onData,
onError: _onError, onDone: _onDone, cancelOnError: true);
var future = new _Future<bool>();
@@ -1042,7 +1054,7 @@
if (subscription != null) {
_subscription = null;
if (!_isPaused) {
- var future = stateData as _Future<bool>;
+ _Future<bool> future = stateData as dynamic;
future._asyncComplete(false);
}
return subscription.cancel();
@@ -1052,7 +1064,7 @@
void _onData(T data) {
assert(_subscription != null && !_isPaused);
- var moveNextFuture = _stateData as _Future<bool>;
+ _Future<bool> moveNextFuture = _stateData as dynamic;
_stateData = data;
_isPaused = true;
moveNextFuture._complete(true);
@@ -1061,7 +1073,7 @@
void _onError(Object error, StackTrace stackTrace) {
assert(_subscription != null && !_isPaused);
- var moveNextFuture = _stateData as _Future<bool>;
+ _Future<bool> moveNextFuture = _stateData as dynamic;
_subscription = null;
_stateData = null;
moveNextFuture._completeError(error, stackTrace);
@@ -1069,7 +1081,7 @@
void _onDone() {
assert(_subscription != null && !_isPaused);
- var moveNextFuture = _stateData as _Future<bool>;
+ _Future<bool> moveNextFuture = _stateData as dynamic;
_subscription = null;
_stateData = null;
moveNextFuture._complete(false);
diff --git a/sdk_nnbd/lib/html/dart2js/html_dart2js.dart b/sdk_nnbd/lib/html/dart2js/html_dart2js.dart
index d648c04..7330bc6 100644
--- a/sdk_nnbd/lib/html/dart2js/html_dart2js.dart
+++ b/sdk_nnbd/lib/html/dart2js/html_dart2js.dart
@@ -32714,7 +32714,7 @@
@Returns('Window|=Object')
dynamic get _get_top native;
- VisualViewport get visualViewport native;
+ VisualViewport? get visualViewport native;
/**
* The current window.
diff --git a/sdk_nnbd/lib/internal/internal.dart b/sdk_nnbd/lib/internal/internal.dart
index a18f40d..bec8b0c 100644
--- a/sdk_nnbd/lib/internal/internal.dart
+++ b/sdk_nnbd/lib/internal/internal.dart
@@ -29,6 +29,10 @@
part 'symbol.dart';
part 'linked_list.dart';
+// Returns true iff `null as T` will succeed based on the
+// execution mode.
+external bool typeAcceptsNull<T>();
+
// Powers of 10 up to 10^22 are representable as doubles.
// Powers of 10 above that are only approximate due to lack of precission.
// Used by double-parsing.
diff --git a/sdk_nnbd/lib/vmservice/vmservice.dart b/sdk_nnbd/lib/vmservice/vmservice.dart
index 807fd00..5b0ad91 100644
--- a/sdk_nnbd/lib/vmservice/vmservice.dart
+++ b/sdk_nnbd/lib/vmservice/vmservice.dart
@@ -169,6 +169,10 @@
/// Called when we want to [enable] or disable the web server.
typedef Future<Uri?> WebServerControlCallback(bool enable);
+/// Called when we want to [enable] or disable new websocket connections to the
+/// server.
+typedef void WebServerAcceptNewWebSocketConnectionsCallback(bool enable);
+
/// Hooks that are setup by the embedder.
class VMServiceEmbedderHooks {
static ServerStartCallback? serverStart;
@@ -182,6 +186,8 @@
static ListFilesCallback? listFiles;
static ServerInformationCallback? serverInformation;
static WebServerControlCallback? webServerControl;
+ static WebServerAcceptNewWebSocketConnectionsCallback?
+ acceptNewWebSocketConnections;
}
class _ClientResumePermissions {
@@ -213,6 +219,33 @@
final devfs = DevFS();
+ Uri get ddsUri => _ddsUri!;
+ Uri? _ddsUri;
+
+ Future<String> _yieldControlToDDS(Message message) async {
+ final acceptNewWebSocketConnections =
+ VMServiceEmbedderHooks.acceptNewWebSocketConnections;
+ if (acceptNewWebSocketConnections == null) {
+ return encodeRpcError(message, kFeatureDisabled,
+ details:
+ 'Embedder does not support yielding to a VM service intermediary.');
+ }
+ final uri = message.params['uri'];
+ if (uri == null) {
+ return encodeMissingParamError(message, 'uri');
+ }
+ // DDS can only take control if there is no other clients connected
+ // directly to the VM service.
+ if (clients.length > 1) {
+ return encodeRpcError(message, kFeatureDisabled,
+ details:
+ 'Existing VM service clients prevent DDS from taking control.');
+ }
+ acceptNewWebSocketConnections(false);
+ _ddsUri = Uri.parse(uri);
+ return encodeSuccess(message);
+ }
+
void _clearClientName(Client client) {
final name = client.name;
client.name = null;
@@ -351,6 +384,16 @@
for (final handle in client.serviceHandles.values) {
handle(null);
}
+ if (clients.isEmpty) {
+ // If DDS was connected, we are in single client mode and need to
+ // allow for new websocket connections.
+ final acceptNewWebSocketConnections =
+ VMServiceEmbedderHooks.acceptNewWebSocketConnections;
+ if (_ddsUri != null && acceptNewWebSocketConnections != null) {
+ acceptNewWebSocketConnections(true);
+ _ddsUri = null;
+ }
+ }
}
void _eventMessageHandler(String streamId, Response event) {
@@ -717,6 +760,9 @@
if (message.completed) {
return await message.response;
}
+ if (message.method == '_yieldControlToDDS') {
+ return await _yieldControlToDDS(message);
+ }
if (message.method == 'streamListen') {
return await _streamListen(message);
}
diff --git a/tests/compiler/dart2js/analyses/api_allowed_nnbd.json b/tests/compiler/dart2js/analyses/api_allowed_nnbd.json
new file mode 100644
index 0000000..6d84ab9
--- /dev/null
+++ b/tests/compiler/dart2js/analyses/api_allowed_nnbd.json
@@ -0,0 +1,212 @@
+{
+ "org-dartlang-sdk:///sdk_nnbd/lib/_internal/js_runtime/lib/js_number.dart": {
+ "Dynamic invocation of '[]'.": 5,
+ "Dynamic invocation of '<'.": 4,
+ "Dynamic invocation of '>='.": 1,
+ "Dynamic invocation of '<='.": 1,
+ "Dynamic invocation of '>'.": 2
+ },
+ "org-dartlang-sdk:///sdk_nnbd/lib/_internal/js_runtime/lib/js_helper.dart": {
+ "Dynamic invocation of '[]'.": 3,
+ "Dynamic access of 'isNaN'.": 3,
+ "Dynamic invocation of '<='.": 2,
+ "Dynamic invocation of '-'.": 3,
+ "Dynamic invocation of '&'.": 1,
+ "Dynamic invocation of '>>'.": 1,
+ "Dynamic invocation of '<'.": 2,
+ "Dynamic invocation of '+'.": 1,
+ "Dynamic invocation of '>'.": 1,
+ "Dynamic access of 'length'.": 1
+ },
+ "org-dartlang-sdk:///sdk_nnbd/lib/_internal/js_runtime/lib/string_helper.dart": {
+ "Dynamic invocation of '<'.": 1,
+ "Dynamic invocation of '+'.": 1,
+ "Dynamic invocation of '>='.": 1,
+ "Dynamic invocation of 'substring'.": 7,
+ "Dynamic invocation of 'allMatches'.": 3,
+ "Dynamic access of 'isNotEmpty'.": 1,
+ "Dynamic invocation of '_js_helper::_execGlobal'.": 1,
+ "Dynamic access of 'start'.": 1,
+ "Dynamic access of 'end'.": 1,
+ "Dynamic invocation of 'call'.": 13,
+ "Dynamic access of 'length'.": 3,
+ "Dynamic invocation of 'codeUnitAt'.": 2,
+ "Dynamic invocation of '[]'.": 1,
+ "Dynamic access of 'iterator'.": 2,
+ "Dynamic invocation of 'replaceRange'.": 2
+ },
+ "org-dartlang-sdk:///sdk_nnbd/lib/_internal/js_runtime/lib/linked_hash_map.dart": {
+ "Dynamic access of '_js_helper::_length'.": 2,
+ "Dynamic access of '_js_helper::_modifications'.": 4,
+ "Dynamic invocation of 'containsKey'.": 1,
+ "Dynamic access of '_js_helper::_first'.": 2
+ },
+ "org-dartlang-sdk:///sdk_nnbd/lib/_internal/js_runtime/lib/js_rti.dart": {
+ "Dynamic invocation of '<'.": 1,
+ "Dynamic invocation of '-'.": 1
+ },
+ "org-dartlang-sdk:///sdk_nnbd/lib/_internal/js_runtime/lib/native_helper.dart": {
+ "Dynamic access of 'length'.": 2,
+ "Dynamic invocation of '[]'.": 1
+ },
+ "org-dartlang-sdk:///sdk_nnbd/lib/_internal/js_runtime/lib/regexp_helper.dart": {
+ "Dynamic access of 'length'.": 1,
+ "Dynamic invocation of '-'.": 1
+ },
+ "org-dartlang-sdk:///sdk_nnbd/lib/_internal/js_runtime/lib/native_typed_data.dart": {
+ "Dynamic invocation of '>'.": 1,
+ "Dynamic invocation of '|'.": 3,
+ "Dynamic invocation of '>='.": 1
+ },
+ "org-dartlang-sdk:///sdk_nnbd/lib/_internal/js_runtime/lib/async_patch.dart": {
+ "Dynamic invocation of '-'.": 1,
+ "Dynamic access of 'iterator'.": 1,
+ "Dynamic invocation of 'call'.": 4,
+ "Dynamic invocation of 'then'.": 1
+ },
+ "org-dartlang-sdk:///sdk_nnbd/lib/_internal/js_runtime/lib/collection_patch.dart": {
+ "Dynamic access of 'dart.collection::_length'.": 2,
+ "Dynamic invocation of 'dart.collection::_computeKeys'.": 2,
+ "Dynamic invocation of 'containsKey'.": 2,
+ "Dynamic access of 'dart.collection::_keys'.": 2,
+ "Dynamic access of 'length'.": 1,
+ "Dynamic access of 'isEmpty'.": 1,
+ "Dynamic access of 'dart.collection::_modifications'.": 5,
+ "Dynamic access of 'dart.collection::_map'.": 4,
+ "Dynamic access of 'dart.collection::_elements'.": 1,
+ "Dynamic access of 'dart.collection::_element'.": 1,
+ "Dynamic access of 'dart.collection::_first'.": 1
+ },
+ "org-dartlang-sdk:///sdk_nnbd/lib/html/dart2js/html_dart2js.dart": {
+ "Dynamic access of 'style'.": 1,
+ "Dynamic invocation of 'remove'.": 2,
+ "Dynamic update to 'dart.dom.html::_innerHtml'.": 1,
+ "Dynamic access of 'firstChild'.": 2,
+ "Dynamic invocation of 'append'.": 1,
+ "Dynamic access of 'tagName'.": 2,
+ "Dynamic invocation of 'call'.": 2,
+ "Dynamic invocation of 'dart.dom.html::_initKeyboardEvent'.": 1,
+ "Dynamic access of 'attributes'.": 1,
+ "Dynamic invocation of '[]'.": 1,
+ "Dynamic invocation of 'toLowerCase'.": 1,
+ "Dynamic invocation of 'attached'.": 1,
+ "Dynamic invocation of 'detached'.": 1,
+ "Dynamic invocation of 'attributeChanged'.": 1,
+ "Dynamic invocation of 'createElement'.": 1
+ },
+ "org-dartlang-sdk:///sdk_nnbd/lib/html/html_common/conversions.dart": {
+ "Dynamic invocation of '[]='.": 1
+ },
+ "org-dartlang-sdk:///sdk_nnbd/lib/html/html_common/filtered_element_list.dart": {
+ "Dynamic invocation of 'remove'.": 1
+ },
+ "org-dartlang-sdk:///sdk_nnbd/lib/indexed_db/dart2js/indexed_db_dart2js.dart": {
+ "Dynamic access of 'onUpgradeNeeded'.": 1,
+ "Dynamic invocation of 'listen'.": 2,
+ "Dynamic access of 'onBlocked'.": 1
+ },
+ "org-dartlang-sdk:///sdk_nnbd/lib/io/directory_impl.dart": {
+ "Dynamic invocation of '[]'.": 10
+ },
+ "org-dartlang-sdk:///sdk_nnbd/lib/io/file_impl.dart": {
+ "Dynamic invocation of '[]'.": 4,
+ "Dynamic access of 'length'.": 2
+ },
+ "org-dartlang-sdk:///sdk_nnbd/lib/io/file_system_entity.dart": {
+ "Dynamic invocation of '[]'.": 7
+ },
+ "org-dartlang-sdk:///sdk_nnbd/lib/io/io_resource_info.dart": {
+ "Dynamic invocation of '[]'.": 1,
+ "Dynamic access of 'path'.": 1,
+ "Dynamic access of 'dart.io::_path'.": 1,
+ "Dynamic access of 'pid'.": 1,
+ "Dynamic access of 'dart.io::_arguments'.": 1,
+ "Dynamic access of 'dart.io::_workingDirectory'.": 2,
+ "Dynamic access of 'isListening'.": 3,
+ "Dynamic access of 'address'.": 4,
+ "Dynamic access of 'host'.": 5,
+ "Dynamic access of 'port'.": 3,
+ "Dynamic access of 'remoteAddress'.": 2,
+ "Dynamic access of 'remotePort'.": 2,
+ "Dynamic access of 'isTcp'.": 1,
+ "Dynamic access of 'type'.": 1,
+ "Dynamic access of 'name'.": 1
+ },
+ "org-dartlang-sdk:///sdk_nnbd/lib/io/link.dart": {
+ "Dynamic invocation of '[]'.": 3
+ },
+ "org-dartlang-sdk:///sdk_nnbd/lib/io/platform_impl.dart": {
+ "Dynamic invocation of 'indexOf'.": 1,
+ "Dynamic invocation of '>'.": 1,
+ "Dynamic invocation of 'substring'.": 2,
+ "Dynamic invocation of '+'.": 1
+ },
+ "org-dartlang-sdk:///sdk_nnbd/lib/io/secure_server_socket.dart": {
+ "Dynamic update to 'dart.io::_owner'.": 1
+ },
+ "org-dartlang-sdk:///sdk_nnbd/lib/io/secure_socket.dart": {
+ "Dynamic invocation of '[]'.": 10,
+ "Dynamic invocation of 'dart.io::_detachRaw'.": 2,
+ "Dynamic access of 'closedReadEventSent'.": 1,
+ "Dynamic update to 'dart.io::_owner'.": 1,
+ "Dynamic access of 'length'.": 1
+ },
+ "org-dartlang-sdk:///sdk_nnbd/lib/io/stdio.dart": {
+ "Dynamic invocation of 'writeFromSync'.": 1,
+ "Dynamic invocation of 'cancel'.": 1,
+ "Dynamic invocation of 'closeSync'.": 1
+ },
+ "org-dartlang-sdk:///sdk_nnbd/lib/io/common.dart": {
+ "Dynamic invocation of '[]'.": 3
+ },
+ "org-dartlang-sdk:///sdk_nnbd/lib/_internal/js_runtime/lib/js_patch.dart": {
+ "Dynamic invocation of '[]'.": 1
+ },
+ "org-dartlang-sdk:///sdk_nnbd/lib/svg/dart2js/svg_dart2js.dart": {
+ "Dynamic invocation of 'createFragment'.": 1,
+ "Dynamic access of 'nodes'.": 1,
+ "Dynamic invocation of 'where'.": 1,
+ "Dynamic access of 'single'.": 1
+ },
+ "org-dartlang-sdk:///sdk_nnbd/lib/core/errors.dart": {
+ "Dynamic access of 'length'.": 2
+ },
+ "org-dartlang-sdk:///sdk_nnbd/lib/_internal/js_runtime/lib/convert_patch.dart": {
+ "Dynamic invocation of 'clear'.": 1
+ },
+ "org-dartlang-sdk:///sdk_nnbd/lib/convert/json.dart": {
+ "Dynamic invocation of 'toJson'.": 1
+ },
+ "org-dartlang-sdk:///sdk_nnbd/lib/_http/crypto.dart": {
+ "Dynamic invocation of '+'.": 2,
+ "Dynamic invocation of '&'.": 3,
+ "Dynamic invocation of 'unary-'.": 1,
+ "Dynamic invocation of '-'.": 2
+ },
+ "org-dartlang-sdk:///sdk_nnbd/lib/_http/http_date.dart": {
+ "Dynamic access of 'length'.": 3,
+ "Dynamic invocation of '<'.": 1,
+ "Dynamic invocation of '>='.": 2,
+ "Dynamic invocation of '[]'.": 7
+ },
+ "org-dartlang-sdk:///sdk_nnbd/lib/_http/http_headers.dart": {
+ "Dynamic invocation of 'toLowerCase'.": 1
+ },
+ "org-dartlang-sdk:///sdk_nnbd/lib/_http/http_impl.dart": {
+ "Dynamic access of 'message'.": 3,
+ "Dynamic invocation of 'call'.": 1,
+ "Dynamic invocation of 'destroy'.": 2,
+ "Dynamic invocation of 'setOption'.": 1,
+ "Dynamic access of 'address'.": 2,
+ "Dynamic access of 'host'.": 2,
+ "Dynamic access of 'port'.": 2,
+ "Dynamic access of 'remoteAddress'.": 1,
+ "Dynamic access of 'remotePort'.": 1,
+ "Dynamic invocation of 'dart._http::_toJSON'.": 3,
+ "Dynamic invocation of 'listen'.": 1,
+ "Dynamic invocation of 'close'.": 1
+ },
+ "org-dartlang-sdk:///sdk_nnbd/lib/_http/websocket_impl.dart": {
+ "Dynamic invocation of 'dart._http::_toJSON'.": 1
+ }
+}
\ No newline at end of file
diff --git a/tests/compiler/dart2js/analyses/api_dynamic_test.dart b/tests/compiler/dart2js/analyses/api_dynamic_test.dart
index d9a0bf7..59aa11c 100644
--- a/tests/compiler/dart2js/analyses/api_dynamic_test.dart
+++ b/tests/compiler/dart2js/analyses/api_dynamic_test.dart
@@ -5,14 +5,16 @@
// @dart = 2.7
import 'package:async_helper/async_helper.dart';
+import '../helpers/compiler_helper.dart';
import 'analysis_helper.dart';
// TODO(johnniwinther): Remove unneeded dynamic accesses from platform source
// code.
main(List<String> args) {
+ var goldenFile = isDart2jsNnbd ? 'api_allowed_nnbd.json' : 'api_allowed.json';
asyncTest(() async {
await run(Uri.parse('memory:main.dart'),
- 'tests/compiler/dart2js/analyses/api_allowed.json',
+ 'tests/compiler/dart2js/analyses/$goldenFile',
analyzedUrisFilter: (Uri uri) => uri.scheme == 'dart',
memorySourceFiles: {'main.dart': 'main() {}'},
verbose: args.contains('-v'),
diff --git a/tests/compiler/dart2js/annotations/annotations_test.dart b/tests/compiler/dart2js/annotations/annotations_test.dart
index 82c35a0..a4424c6 100644
--- a/tests/compiler/dart2js/annotations/annotations_test.dart
+++ b/tests/compiler/dart2js/annotations/annotations_test.dart
@@ -24,7 +24,7 @@
asyncTest(() async {
Directory dataDir = new Directory.fromUri(Platform.script.resolve('data'));
await checkTests(dataDir, const AnnotationDataComputer(),
- args: args, testedConfigs: allStrongConfigs);
+ args: args, testedConfigs: allSpecConfigs);
});
}
diff --git a/tests/compiler/dart2js/annotations/data/marker.options b/tests/compiler/dart2js/annotations/data/marker.options
index 730d5c7..24b51f0 100644
--- a/tests/compiler/dart2js/annotations/data/marker.options
+++ b/tests/compiler/dart2js/annotations/data/marker.options
@@ -1,2 +1,4 @@
-strong=tests/compiler/dart2js/annotations/annotations_test.dart
-omit=tests/compiler/dart2js/annotations/annotations_test.dart
\ No newline at end of file
+spec:nnbd-off=tests/compiler/dart2js/annotations/annotations_test.dart
+prod:nnbd-off=tests/compiler/dart2js/annotations/annotations_test.dart
+spec:nnbd-sdk=tests/compiler/dart2js/annotations/annotations_test.dart
+prod:nnbd-sdk=tests/compiler/dart2js/annotations/annotations_test.dart
\ No newline at end of file
diff --git a/tests/compiler/dart2js/closure/data/generic.dart b/tests/compiler/dart2js/closure/data/generic.dart
index a2f552d..2ceb029 100644
--- a/tests/compiler/dart2js/closure/data/generic.dart
+++ b/tests/compiler/dart2js/closure/data/generic.dart
@@ -58,12 +58,12 @@
}
var local2 =
- /*strong.fields=[S,this],free=[S,this],hasThis*/
- /*omit.hasThis*/
+ /*spec:nnbd-off|spec:nnbd-sdk.fields=[S,this],free=[S,this],hasThis*/
+ /*prod:nnbd-off|prod:nnbd-sdk.hasThis*/
(o) {
return
- /*strong.fields=[S,this],free=[S,this],hasThis*/
- /*omit.hasThis*/
+ /*spec:nnbd-off|spec:nnbd-sdk.fields=[S,this],free=[S,this],hasThis*/
+ /*prod:nnbd-off|prod:nnbd-sdk.hasThis*/
() => new Map<T, S>();
};
return local2(local<double>());
diff --git a/tests/compiler/dart2js/closure/data/instantiation.dart b/tests/compiler/dart2js/closure/data/instantiation.dart
index 19949ff..17031f5 100644
--- a/tests/compiler/dart2js/closure/data/instantiation.dart
+++ b/tests/compiler/dart2js/closure/data/instantiation.dart
@@ -7,8 +7,8 @@
T id<T>(T t) => t;
method<S>(S s) {
- /*strong.fields=[S],free=[S]*/
- /*omit.*/
+ /*spec:nnbd-off|spec:nnbd-sdk.fields=[S],free=[S]*/
+ /*prod:nnbd-off.*/
S Function(S) getId() => id;
return getId();
}
diff --git a/tests/compiler/dart2js/closure/data/instantiation1.dart b/tests/compiler/dart2js/closure/data/instantiation1.dart
index 3f31e41..0e0d917 100644
--- a/tests/compiler/dart2js/closure/data/instantiation1.dart
+++ b/tests/compiler/dart2js/closure/data/instantiation1.dart
@@ -13,8 +13,8 @@
/*member: B.method:hasThis*/
method() {
return
- /*strong.fields=[this],free=[this],hasThis*/
- /*omit.hasThis*/
+ /*spec:nnbd-off|spec:nnbd-sdk.fields=[this],free=[this],hasThis*/
+ /*prod:nnbd-off|prod:nnbd-sdk.hasThis*/
() {
F<S> c = f;
return c;
diff --git a/tests/compiler/dart2js/closure/data/instantiation2.dart b/tests/compiler/dart2js/closure/data/instantiation2.dart
index 8e75f09..b74a15d 100644
--- a/tests/compiler/dart2js/closure/data/instantiation2.dart
+++ b/tests/compiler/dart2js/closure/data/instantiation2.dart
@@ -13,8 +13,7 @@
/*member: B.method:hasThis*/
method() {
return
- /*strong.fields=[this],free=[this],hasThis*/
- /*omit.fields=[this],free=[this],hasThis*/
+ /*fields=[this],free=[this],hasThis*/
() {
F<S> c = f;
return c;
diff --git a/tests/compiler/dart2js/closure/data/instantiation3.dart b/tests/compiler/dart2js/closure/data/instantiation3.dart
index 2157d67..c20327b 100644
--- a/tests/compiler/dart2js/closure/data/instantiation3.dart
+++ b/tests/compiler/dart2js/closure/data/instantiation3.dart
@@ -10,8 +10,8 @@
method<S>() {
return
- /*strong.fields=[S],free=[S]*/
- /*omit.*/
+ /*spec:nnbd-off|spec:nnbd-sdk.fields=[S],free=[S]*/
+ /*prod:nnbd-off.*/
() {
F<S> c = f;
return c;
diff --git a/tests/compiler/dart2js/closure/data/instantiation4.dart b/tests/compiler/dart2js/closure/data/instantiation4.dart
index 05b8caf..0da1e4b 100644
--- a/tests/compiler/dart2js/closure/data/instantiation4.dart
+++ b/tests/compiler/dart2js/closure/data/instantiation4.dart
@@ -10,8 +10,7 @@
method<S>() {
return
- /*strong.fields=[S],free=[S]*/
- /*omit.fields=[S],free=[S]*/
+ /*fields=[S],free=[S]*/
() {
F<S> c = f;
return c;
diff --git a/tests/compiler/dart2js/closure/data/list_literal_untested_class.dart b/tests/compiler/dart2js/closure/data/list_literal_untested_class.dart
index 516b390..8a7c352 100644
--- a/tests/compiler/dart2js/closure/data/list_literal_untested_class.dart
+++ b/tests/compiler/dart2js/closure/data/list_literal_untested_class.dart
@@ -11,8 +11,8 @@
/*member: A.method:hasThis*/
@pragma('dart2js:noInline')
method() {
- /*omit.hasThis*/
- /*strong.fields=[this],free=[this],hasThis*/
+ /*prod:nnbd-off|prod:nnbd-sdk.hasThis*/
+ /*spec:nnbd-off|spec:nnbd-sdk.fields=[this],free=[this],hasThis*/
dynamic local() => <T>[];
return local;
}
diff --git a/tests/compiler/dart2js/closure/data/list_literal_untested_method.dart b/tests/compiler/dart2js/closure/data/list_literal_untested_method.dart
index 42e8cf2..f389236 100644
--- a/tests/compiler/dart2js/closure/data/list_literal_untested_method.dart
+++ b/tests/compiler/dart2js/closure/data/list_literal_untested_method.dart
@@ -8,8 +8,8 @@
@pragma('dart2js:noInline')
method<T>() {
- /*omit.*/
- /*strong.fields=[T],free=[T]*/
+ /*prod:nnbd-off.*/
+ /*spec:nnbd-off|spec:nnbd-sdk.fields=[T],free=[T]*/
dynamic local() => <T>[];
return local;
}
diff --git a/tests/compiler/dart2js/closure/data/map_literal_untested_class.dart b/tests/compiler/dart2js/closure/data/map_literal_untested_class.dart
index 6ee00d3..d1b27bd 100644
--- a/tests/compiler/dart2js/closure/data/map_literal_untested_class.dart
+++ b/tests/compiler/dart2js/closure/data/map_literal_untested_class.dart
@@ -11,8 +11,8 @@
/*member: A.method:hasThis*/
@pragma('dart2js:noInline')
method() {
- /*omit.hasThis*/
- /*strong.fields=[this],free=[this],hasThis*/
+ /*prod:nnbd-off|prod:nnbd-sdk.hasThis*/
+ /*spec:nnbd-off|spec:nnbd-sdk.fields=[this],free=[this],hasThis*/
dynamic local() => <T, int>{};
return local;
}
diff --git a/tests/compiler/dart2js/closure/data/map_literal_untested_method.dart b/tests/compiler/dart2js/closure/data/map_literal_untested_method.dart
index d2adfbb..57a3dfd 100644
--- a/tests/compiler/dart2js/closure/data/map_literal_untested_method.dart
+++ b/tests/compiler/dart2js/closure/data/map_literal_untested_method.dart
@@ -8,8 +8,8 @@
@pragma('dart2js:noInline')
method<T>() {
- /*omit.*/
- /*strong.fields=[T],free=[T]*/
+ /*prod:nnbd-off.*/
+ /*spec:nnbd-off|spec:nnbd-sdk.fields=[T],free=[T]*/
dynamic local() => <T, int>{};
return local;
}
diff --git a/tests/compiler/dart2js/closure/data/marker.options b/tests/compiler/dart2js/closure/data/marker.options
index f297827..ba31510 100644
--- a/tests/compiler/dart2js/closure/data/marker.options
+++ b/tests/compiler/dart2js/closure/data/marker.options
@@ -1,2 +1,4 @@
-strong=tests/compiler/dart2js/closure/closure_test.dart
-omit=tests/compiler/dart2js/closure/closure_test.dart
\ No newline at end of file
+spec:nnbd-off=tests/compiler/dart2js/closure/closure_test.dart
+prod:nnbd-off=tests/compiler/dart2js/closure/closure_test.dart
+spec:nnbd-sdk=tests/compiler/dart2js/closure/closure_test.dart
+prod:nnbd-sdk=tests/compiler/dart2js/closure/closure_test.dart
\ No newline at end of file
diff --git a/tests/compiler/dart2js/closure/data/test_type_class.dart b/tests/compiler/dart2js/closure/data/test_type_class.dart
index ead1797..0c92250 100644
--- a/tests/compiler/dart2js/closure/data/test_type_class.dart
+++ b/tests/compiler/dart2js/closure/data/test_type_class.dart
@@ -33,15 +33,15 @@
}
////////////////////////////////////////////////////////////////////////////////
-/// Implicit as-cast is only required in strong mode.
+/// Implicit as-cast is only required in spec:nnbd-off mode.
////////////////////////////////////////////////////////////////////////////////
/*member: Class3.:hasThis*/
class Class3<T> {
/*member: Class3.method3:hasThis*/
method3(dynamic o) {
- /*omit.fields=[o],free=[o],hasThis*/
- /*strong.fields=[o,this],free=[o,this],hasThis*/
+ /*prod:nnbd-off|prod:nnbd-sdk.fields=[o],free=[o],hasThis*/
+ /*spec:nnbd-off|spec:nnbd-sdk.fields=[o,this],free=[o,this],hasThis*/
T local() => o;
return local;
}
diff --git a/tests/compiler/dart2js/closure/data/test_type_method.dart b/tests/compiler/dart2js/closure/data/test_type_method.dart
index faad952..452f6c1 100644
--- a/tests/compiler/dart2js/closure/data/test_type_method.dart
+++ b/tests/compiler/dart2js/closure/data/test_type_method.dart
@@ -27,13 +27,13 @@
}
////////////////////////////////////////////////////////////////////////////////
-/// Implicit as-cast is only required in strong mode.
+/// Implicit as-cast is only required in spec:nnbd-off mode.
////////////////////////////////////////////////////////////////////////////////
/*member: method3:*/
method3<T>(dynamic o) {
- /*strong.fields=[T,o],free=[T,o]*/
- /*omit.fields=[o],free=[o]*/
+ /*spec:nnbd-off|spec:nnbd-sdk.fields=[T,o],free=[T,o]*/
+ /*prod:nnbd-off|prod:nnbd-sdk.fields=[o],free=[o]*/
T local() => o;
return local;
}
diff --git a/tests/compiler/dart2js/closure/data/type_annotations_class.dart b/tests/compiler/dart2js/closure/data/type_annotations_class.dart
index 1732242..5d1cfdc 100644
--- a/tests/compiler/dart2js/closure/data/type_annotations_class.dart
+++ b/tests/compiler/dart2js/closure/data/type_annotations_class.dart
@@ -43,30 +43,30 @@
}
////////////////////////////////////////////////////////////////////////////////
-/// A local function parameter type is only captured in strong mode.
+/// A local function parameter type is only captured in spec:nnbd-off mode.
////////////////////////////////////////////////////////////////////////////////
/*member: Class2.:hasThis*/
class Class2<T> {
/*member: Class2.method2:hasThis*/
method2() {
- /*omit.hasThis*/
- /*strong.fields=[this],free=[this],hasThis*/
+ /*prod:nnbd-off|prod:nnbd-sdk.hasThis*/
+ /*spec:nnbd-off|spec:nnbd-sdk.fields=[this],free=[this],hasThis*/
dynamic local(T t) => t;
return local;
}
}
////////////////////////////////////////////////////////////////////////////////
-/// A local function return type is only captured in strong mode.
+/// A local function return type is only captured in spec:nnbd-off mode.
////////////////////////////////////////////////////////////////////////////////
/*member: Class3.:hasThis*/
class Class3<T> {
/*member: Class3.method3:hasThis*/
method3(dynamic o) {
- /*omit.fields=[o],free=[o],hasThis*/
- /*strong.fields=[o,this],free=[o,this],hasThis*/
+ /*prod:nnbd-off|prod:nnbd-sdk.fields=[o],free=[o],hasThis*/
+ /*spec:nnbd-off|spec:nnbd-sdk.fields=[o,this],free=[o,this],hasThis*/
T local() => o;
return local;
}
@@ -108,8 +108,8 @@
class Class6<T> {
/*member: Class6.method6:hasThis*/
method6() {
- /*omit.hasThis*/
- /*strong.fields=[this],free=[this],hasThis*/
+ /*prod:nnbd-off|prod:nnbd-sdk.hasThis*/
+ /*spec:nnbd-off|spec:nnbd-sdk.fields=[this],free=[this],hasThis*/
dynamic local(T t) {
/*fields=[t],free=[t],hasThis*/
dynamic inner() => t;
@@ -128,8 +128,8 @@
class Class7<T> {
/*member: Class7.method7:hasThis*/
method7(dynamic o) {
- /*omit.fields=[o],free=[o],hasThis*/
- /*strong.fields=[o,this],free=[o,this],hasThis*/
+ /*prod:nnbd-off|prod:nnbd-sdk.fields=[o],free=[o],hasThis*/
+ /*spec:nnbd-off|spec:nnbd-sdk.fields=[o,this],free=[o,this],hasThis*/
T local() {
/*fields=[o],free=[o],hasThis*/
dynamic inner() => o;
diff --git a/tests/compiler/dart2js/closure/data/type_annotations_method.dart b/tests/compiler/dart2js/closure/data/type_annotations_method.dart
index 4bf4396..a73576f 100644
--- a/tests/compiler/dart2js/closure/data/type_annotations_method.dart
+++ b/tests/compiler/dart2js/closure/data/type_annotations_method.dart
@@ -19,23 +19,23 @@
}
////////////////////////////////////////////////////////////////////////////////
-/// A local function parameter type is captured in strong mode.
+/// A local function parameter type is captured in spec:nnbd-off mode.
////////////////////////////////////////////////////////////////////////////////
method2<T>() {
- /*strong.fields=[T],free=[T]*/
- /*omit.*/
+ /*spec:nnbd-off|spec:nnbd-sdk.fields=[T],free=[T]*/
+ /*prod:nnbd-off.*/
dynamic local(T t) => t;
return local;
}
////////////////////////////////////////////////////////////////////////////////
-/// A local function return type is captured in strong mode.
+/// A local function return type is captured in spec:nnbd-off mode.
////////////////////////////////////////////////////////////////////////////////
method3<T>(dynamic o) {
- /*strong.fields=[T,o],free=[T,o]*/
- /*omit.fields=[o],free=[o]*/
+ /*spec:nnbd-off|spec:nnbd-sdk.fields=[T,o],free=[T,o]*/
+ /*prod:nnbd-off|prod:nnbd-sdk.fields=[o],free=[o]*/
T local() => o;
return local;
}
@@ -65,8 +65,8 @@
////////////////////////////////////////////////////////////////////////////////
method6<T>() {
- /*strong.fields=[T],free=[T]*/
- /*omit.*/
+ /*spec:nnbd-off|spec:nnbd-sdk.fields=[T],free=[T]*/
+ /*prod:nnbd-off.*/
dynamic local(T t) {
/*fields=[t],free=[t]*/
dynamic inner() => t;
@@ -81,8 +81,8 @@
////////////////////////////////////////////////////////////////////////////////
method7<T>(dynamic o) {
- /*strong.fields=[T,o],free=[T,o]*/
- /*omit.fields=[o],free=[o]*/
+ /*spec:nnbd-off|spec:nnbd-sdk.fields=[T,o],free=[T,o]*/
+ /*prod:nnbd-off|prod:nnbd-sdk.fields=[o],free=[o]*/
T local() {
/*fields=[o],free=[o]*/
dynamic inner() => o;
diff --git a/tests/compiler/dart2js/codegen/model_data/dynamic_set.dart b/tests/compiler/dart2js/codegen/model_data/dynamic_set.dart
index e5afcba..ae298ae 100644
--- a/tests/compiler/dart2js/codegen/model_data/dynamic_set.dart
+++ b/tests/compiler/dart2js/codegen/model_data/dynamic_set.dart
@@ -26,27 +26,55 @@
}
class Class2a<T> {
- /*strong.member: Class2a.field2:checked,emitted*/
- /*omit.member: Class2a.field2:emitted*/
+ /*spec:nnbd-sdk.member: Class2a.field2:
+ checked,
+ emitted
+ */
+ /*spec:nnbd-off.member: Class2a.field2:checked,emitted*/
+ /*prod:nnbd-off|prod:nnbd-sdk.member: Class2a.field2:emitted*/
T field2;
}
-/*strong.member: method2:calls=[set$field2(1)],params=1*/
-/*omit.member: method2:assign=[field2],params=1*/
+/*spec:nnbd-off.member: method2:calls=[set$field2(1)],params=1*/
+/*prod:nnbd-off.member: method2:assign=[field2],params=1*/
@pragma('dart2js:noInline')
+/*spec:nnbd-sdk.member: method2:
+ calls=[set$field2(1)],
+ params=1
+*/
+/*prod:nnbd-sdk.member: method2:
+ assign=[field2],
+ params=1
+*/
method2(dynamic c) {
c.field2 = 42;
}
class Class3a {
- /*strong.member: Class3a.field3:checked,emitted*/
- /*omit.member: Class3a.field3:emitted,set=simple*/
+ /*spec:nnbd-sdk.member: Class3a.field3:
+ checked,
+ emitted
+ */
+ /*prod:nnbd-sdk.member: Class3a.field3:
+ emitted,
+ set=simple
+ */
+ /*spec:nnbd-off.member: Class3a.field3:checked,emitted*/
+ /*prod:nnbd-off.member: Class3a.field3:emitted,set=simple*/
int field3;
}
class Class3b {
- /*strong.member: Class3b.field3:checked,emitted*/
- /*omit.member: Class3b.field3:emitted,set=simple*/
+ /*spec:nnbd-sdk.member: Class3b.field3:
+ checked,
+ emitted
+ */
+ /*prod:nnbd-sdk.member: Class3b.field3:
+ emitted,
+ set=simple
+ */
+ /*spec:nnbd-off.member: Class3b.field3:checked,emitted*/
+ /*prod:nnbd-off.member: Class3b.field3:emitted,set=simple*/
int field3;
}
@@ -57,15 +85,31 @@
}
class Class4a {
- /*strong.member: Class4a.field4:checked,emitted*/
- /*omit.member: Class4a.field4:emitted,set=simple*/
+ /*spec:nnbd-sdk.member: Class4a.field4:
+ checked,
+ emitted
+ */
+ /*prod:nnbd-sdk.member: Class4a.field4:
+ emitted,
+ set=simple
+ */
+ /*spec:nnbd-off.member: Class4a.field4:checked,emitted*/
+ /*prod:nnbd-off.member: Class4a.field4:emitted,set=simple*/
int field4;
}
class Class4b implements Class4a {
- /*strong.member: Class4b.field4:checked,emitted*/
- /*omit.member: Class4b.field4:emitted,set=simple*/
+ /*spec:nnbd-off.member: Class4b.field4:checked,emitted*/
+ /*prod:nnbd-off.member: Class4b.field4:emitted,set=simple*/
@override
+ /*spec:nnbd-sdk.member: Class4b.field4:
+ checked,
+ emitted
+ */
+ /*prod:nnbd-sdk.member: Class4b.field4:
+ emitted,
+ set=simple
+ */
int field4;
}
diff --git a/tests/compiler/dart2js/codegen/model_data/dynamic_set_unread.dart b/tests/compiler/dart2js/codegen/model_data/dynamic_set_unread.dart
index 053a59c..cef28b2 100644
--- a/tests/compiler/dart2js/codegen/model_data/dynamic_set_unread.dart
+++ b/tests/compiler/dart2js/codegen/model_data/dynamic_set_unread.dart
@@ -26,27 +26,51 @@
}
class Class2a<T> {
- /*strong.member: Class2a.field2:checked,elided*/
- /*omit.member: Class2a.field2:elided*/
+ /*spec:nnbd-sdk.member: Class2a.field2:
+ checked,
+ elided
+ */
+ /*spec:nnbd-off.member: Class2a.field2:checked,elided*/
+ /*prod:nnbd-off|prod:nnbd-sdk.member: Class2a.field2:elided*/
T field2;
}
-/*strong.member: method2:calls=[set$field2(1)],params=1*/
-/*omit.member: method2:params=1*/
+/*spec:nnbd-off.member: method2:calls=[set$field2(1)],params=1*/
+/*prod:nnbd-off|prod:nnbd-sdk.member: method2:params=1*/
@pragma('dart2js:noInline')
+/*spec:nnbd-sdk.member: method2:
+ calls=[set$field2(1)],
+ params=1
+*/
method2(dynamic c) {
c.field2 = 42;
}
class Class3a {
- /*strong.member: Class3a.field3:checked,elided*/
- /*omit.member: Class3a.field3:elided,set=simple*/
+ /*spec:nnbd-sdk.member: Class3a.field3:
+ checked,
+ elided
+ */
+ /*prod:nnbd-sdk.member: Class3a.field3:
+ elided,
+ set=simple
+ */
+ /*spec:nnbd-off.member: Class3a.field3:checked,elided*/
+ /*prod:nnbd-off.member: Class3a.field3:elided,set=simple*/
int field3;
}
class Class3b {
- /*strong.member: Class3b.field3:checked,elided*/
- /*omit.member: Class3b.field3:elided,set=simple*/
+ /*spec:nnbd-sdk.member: Class3b.field3:
+ checked,
+ elided
+ */
+ /*prod:nnbd-sdk.member: Class3b.field3:
+ elided,
+ set=simple
+ */
+ /*spec:nnbd-off.member: Class3b.field3:checked,elided*/
+ /*prod:nnbd-off.member: Class3b.field3:elided,set=simple*/
int field3;
}
@@ -57,15 +81,31 @@
}
class Class4a {
- /*strong.member: Class4a.field4:checked,elided*/
- /*omit.member: Class4a.field4:elided,set=simple*/
+ /*spec:nnbd-sdk.member: Class4a.field4:
+ checked,
+ elided
+ */
+ /*prod:nnbd-sdk.member: Class4a.field4:
+ elided,
+ set=simple
+ */
+ /*spec:nnbd-off.member: Class4a.field4:checked,elided*/
+ /*prod:nnbd-off.member: Class4a.field4:elided,set=simple*/
int field4;
}
class Class4b implements Class4a {
- /*strong.member: Class4b.field4:checked,elided*/
- /*omit.member: Class4b.field4:elided,set=simple*/
+ /*spec:nnbd-off.member: Class4b.field4:checked,elided*/
+ /*prod:nnbd-off.member: Class4b.field4:elided,set=simple*/
@override
+ /*spec:nnbd-sdk.member: Class4b.field4:
+ checked,
+ elided
+ */
+ /*prod:nnbd-sdk.member: Class4b.field4:
+ elided,
+ set=simple
+ */
int field4;
}
diff --git a/tests/compiler/dart2js/codegen/model_data/marker.options b/tests/compiler/dart2js/codegen/model_data/marker.options
index f7d45f7..ab72a7b2 100644
--- a/tests/compiler/dart2js/codegen/model_data/marker.options
+++ b/tests/compiler/dart2js/codegen/model_data/marker.options
@@ -1,2 +1,4 @@
-strong=tests/compiler/dart2js/codegen/model_test.dart
-omit=tests/compiler/dart2js/codegen/model_test.dart
\ No newline at end of file
+spec:nnbd-off=tests/compiler/dart2js/codegen/model_test.dart
+prod:nnbd-off=tests/compiler/dart2js/codegen/model_test.dart
+spec:nnbd-sdk=tests/compiler/dart2js/codegen/model_test.dart
+prod:nnbd-sdk=tests/compiler/dart2js/codegen/model_test.dart
\ No newline at end of file
diff --git a/tests/compiler/dart2js/codegen/model_data/static_tearoff.dart b/tests/compiler/dart2js/codegen/model_data/static_tearoff.dart
index e26d48d..654b5bb 100644
--- a/tests/compiler/dart2js/codegen/model_data/static_tearoff.dart
+++ b/tests/compiler/dart2js/codegen/model_data/static_tearoff.dart
@@ -20,8 +20,15 @@
@pragma('dart2js:noInline')
void bar(I2 x) {}
-/*strong.member: main:calls=[bar(1),bar(1),foo(1),foo(1)],params=0*/
-/*omit.member: main:calls=[bar(1),bar(1),foo(1),foo(1)],params=0*/
+/*spec:nnbd-off|prod:nnbd-off.member: main:calls=[bar(1),bar(1),foo(1),foo(1)],params=0*/
+/*spec:nnbd-sdk|prod:nnbd-sdk.member: main:
+ calls=[
+ bar(1),
+ bar(1),
+ foo(1),
+ foo(1)],
+ params=0
+*/
main() {
dynamic f = bar;
diff --git a/tests/compiler/dart2js/deferred_loading/data/deferred_typed_map/main.dart b/tests/compiler/dart2js/deferred_loading/data/deferred_typed_map/main.dart
index f31c25c..832e2f2 100644
--- a/tests/compiler/dart2js/deferred_loading/data/deferred_typed_map/main.dart
+++ b/tests/compiler/dart2js/deferred_loading/data/deferred_typed_map/main.dart
@@ -6,11 +6,12 @@
import 'lib1.dart' deferred as lib;
-/*member: main:
+/*spec:nnbd-off.member: main:
OutputUnit(main, {}),
constants=[
MapConstant(<int, dynamic Function({M b})>{IntConstant(1): FunctionConstant(f1), IntConstant(2): FunctionConstant(f2)})=OutputUnit(1, {lib})]
*/
+/*spec:nnbd-sdk.member: main:OutputUnit(main, {}),constants=[MapConstant(<int*, dynamic Function({M* b})*>{IntConstant(1): FunctionConstant(f1), IntConstant(2): FunctionConstant(f2)})=OutputUnit(1, {lib})]*/
main() async {
await lib.loadLibrary();
print(lib.table[1]);
diff --git a/tests/compiler/dart2js/deferred_loading/data/instantiation0/lib1.dart b/tests/compiler/dart2js/deferred_loading/data/instantiation0/lib1.dart
index 6828e57..9521da6 100644
--- a/tests/compiler/dart2js/deferred_loading/data/instantiation0/lib1.dart
+++ b/tests/compiler/dart2js/deferred_loading/data/instantiation0/lib1.dart
@@ -9,10 +9,11 @@
typedef dynamic G<T>(T v);
-/*member: m:
+/*spec:nnbd-off.member: m:
OutputUnit(1, {b}),
constants=[InstantiationConstant([int],FunctionConstant(getFoo))=OutputUnit(1, {b})]
*/
+/*spec:nnbd-sdk.member: m:OutputUnit(1, {b}),constants=[InstantiationConstant([int*],FunctionConstant(getFoo))=OutputUnit(1, {b})]*/
m(int x, {G<int> f: getFoo}) {
print(f(x));
}
diff --git a/tests/compiler/dart2js/deferred_loading/data/instantiation1/lib1.dart b/tests/compiler/dart2js/deferred_loading/data/instantiation1/lib1.dart
index 4ca1497..2f185de 100644
--- a/tests/compiler/dart2js/deferred_loading/data/instantiation1/lib1.dart
+++ b/tests/compiler/dart2js/deferred_loading/data/instantiation1/lib1.dart
@@ -9,11 +9,12 @@
typedef dynamic G<T>(T v);
-/*member: m:
+/*spec:nnbd-off.member: m:
OutputUnit(1, {b}),
constants=[
InstantiationConstant([int],FunctionConstant(getFoo))=OutputUnit(1, {b})]
*/
+/*spec:nnbd-sdk.member: m:OutputUnit(1, {b}),constants=[InstantiationConstant([int*],FunctionConstant(getFoo))=OutputUnit(1, {b})]*/
m(int x, {G<int> f: getFoo}) {
print(f(x));
}
diff --git a/tests/compiler/dart2js/deferred_loading/data/instantiation1/lib2.dart b/tests/compiler/dart2js/deferred_loading/data/instantiation1/lib2.dart
index 00caeb1..e49ee5f 100644
--- a/tests/compiler/dart2js/deferred_loading/data/instantiation1/lib2.dart
+++ b/tests/compiler/dart2js/deferred_loading/data/instantiation1/lib2.dart
@@ -9,11 +9,12 @@
typedef dynamic G<T, S>(T v, S w);
-/*member: m:
+/*spec:nnbd-off.member: m:
OutputUnit(3, {c}),
constants=[
InstantiationConstant([int, int],FunctionConstant(getFoo))=OutputUnit(3, {c})]
*/
+/*spec:nnbd-sdk.member: m:OutputUnit(3, {c}),constants=[InstantiationConstant([int*, int*],FunctionConstant(getFoo))=OutputUnit(3, {c})]*/
m(int x, int y, {G<int, int> f: getFoo}) {
print(f(x, y));
}
diff --git a/tests/compiler/dart2js/deferred_loading/data/instantiation2/lib1.dart b/tests/compiler/dart2js/deferred_loading/data/instantiation2/lib1.dart
index 89d5d6d..ecf0bc4 100644
--- a/tests/compiler/dart2js/deferred_loading/data/instantiation2/lib1.dart
+++ b/tests/compiler/dart2js/deferred_loading/data/instantiation2/lib1.dart
@@ -9,11 +9,12 @@
typedef dynamic G<T>(T v);
-/*member: m:
+/*spec:nnbd-off.member: m:
OutputUnit(2, {b}),
constants=[
InstantiationConstant([int],FunctionConstant(getFoo))=OutputUnit(2, {b})]
*/
+/*spec:nnbd-sdk.member: m:OutputUnit(2, {b}),constants=[InstantiationConstant([int*],FunctionConstant(getFoo))=OutputUnit(2, {b})]*/
m(int x, {G<int> f: getFoo}) {
print(f(x));
}
diff --git a/tests/compiler/dart2js/deferred_loading/data/instantiation2/lib2.dart b/tests/compiler/dart2js/deferred_loading/data/instantiation2/lib2.dart
index d7a9c46..714e91f 100644
--- a/tests/compiler/dart2js/deferred_loading/data/instantiation2/lib2.dart
+++ b/tests/compiler/dart2js/deferred_loading/data/instantiation2/lib2.dart
@@ -9,11 +9,12 @@
typedef dynamic G<T>(T v);
-/*member: m:
+/*spec:nnbd-off.member: m:
OutputUnit(3, {c}),
constants=[
InstantiationConstant([int],FunctionConstant(getFoo))=OutputUnit(3, {c})]
*/
+/*spec:nnbd-sdk.member: m:OutputUnit(3, {c}),constants=[InstantiationConstant([int*],FunctionConstant(getFoo))=OutputUnit(3, {c})]*/
m(int x, {G<int> f: getFoo}) {
print(f(x));
}
diff --git a/tests/compiler/dart2js/deferred_loading/data/marker.options b/tests/compiler/dart2js/deferred_loading/data/marker.options
index 94f0636..c970e11 100644
--- a/tests/compiler/dart2js/deferred_loading/data/marker.options
+++ b/tests/compiler/dart2js/deferred_loading/data/marker.options
@@ -1 +1,2 @@
-strong=tests/compiler/dart2js/deferred_loading/deferred_loading_test.dart
\ No newline at end of file
+spec:nnbd-off=tests/compiler/dart2js/deferred_loading/deferred_loading_test.dart
+spec:nnbd-sdk=tests/compiler/dart2js/deferred_loading/deferred_loading_test.dart
\ No newline at end of file
diff --git a/tests/compiler/dart2js/deferred_loading/data/static_separate/lib2.dart b/tests/compiler/dart2js/deferred_loading/data/static_separate/lib2.dart
index 016ba07..a236b19 100644
--- a/tests/compiler/dart2js/deferred_loading/data/static_separate/lib2.dart
+++ b/tests/compiler/dart2js/deferred_loading/data/static_separate/lib2.dart
@@ -9,12 +9,13 @@
import "package:expect/expect.dart";
import "lib1.dart";
-/*member: foo:
+/*spec:nnbd-off.member: foo:
OutputUnit(3, {lib2}),
constants=[
ListConstant(<Map<int,int>>[MapConstant(<int, int>{IntConstant(1): IntConstant(3)})])=OutputUnit(3, {lib2}),
MapConstant(<int, int>{IntConstant(1): IntConstant(3)})=OutputUnit(3, {lib2})]
*/
+/*spec:nnbd-sdk.member: foo:OutputUnit(3, {lib2}),constants=[ListConstant(<Map<int*,int*>*>[MapConstant(<int*, int*>{IntConstant(1): IntConstant(3)})])=OutputUnit(3, {lib2}),MapConstant(<int*, int*>{IntConstant(1): IntConstant(3)})=OutputUnit(3, {lib2})]*/
foo() {
Expect.equals(1, C.foo());
Expect.mapEquals({}, C1.foo);
diff --git a/tests/compiler/dart2js/deferred_loading/data/type_arguments/main.dart b/tests/compiler/dart2js/deferred_loading/data/type_arguments/main.dart
index d9b4bac..2423196 100644
--- a/tests/compiler/dart2js/deferred_loading/data/type_arguments/main.dart
+++ b/tests/compiler/dart2js/deferred_loading/data/type_arguments/main.dart
@@ -8,7 +8,7 @@
import 'lib2.dart' as lib2;
import 'lib3.dart' deferred as lib3;
-/*member: main:
+/*spec:nnbd-off.member: main:
OutputUnit(main, {}),
constants=[
ConstructedConstant(A<B>())=OutputUnit(1, {lib1}),
@@ -16,6 +16,7 @@
ConstructedConstant(C<D>())=OutputUnit(main, {}),
ConstructedConstant(E<F>())=OutputUnit(3, {lib3})]
*/
+/*spec:nnbd-sdk.member: main:OutputUnit(main, {}),constants=[ConstructedConstant(A<B*>())=OutputUnit(1, {lib1}),ConstructedConstant(A<F*>())=OutputUnit(1, {lib1}),ConstructedConstant(C<D*>())=OutputUnit(main, {}),ConstructedConstant(E<F*>())=OutputUnit(3, {lib3})]*/
main() async {
await lib1.loadLibrary();
lib1.field1;
diff --git a/tests/compiler/dart2js/deferred_loading/deferred_loading_test.dart b/tests/compiler/dart2js/deferred_loading/deferred_loading_test.dart
index 96b7600..f25018a 100644
--- a/tests/compiler/dart2js/deferred_loading/deferred_loading_test.dart
+++ b/tests/compiler/dart2js/deferred_loading/deferred_loading_test.dart
@@ -34,11 +34,9 @@
asyncTest(() async {
Directory dataDir = new Directory.fromUri(Platform.script.resolve('data'));
await checkTests(dataDir, const OutputUnitDataComputer(),
- options: compilerOptions,
- args: args,
- setUpFunction: () {
+ options: compilerOptions, args: args, setUpFunction: () {
importPrefixes.clear();
- }, testedConfigs: allStrongConfigs);
+ }, testedConfigs: allSpecConfigs);
});
}
diff --git a/tests/compiler/dart2js/equivalence/id_equivalence_helper.dart b/tests/compiler/dart2js/equivalence/id_equivalence_helper.dart
index 20e6173..d6da685 100644
--- a/tests/compiler/dart2js/equivalence/id_equivalence_helper.dart
+++ b/tests/compiler/dart2js/equivalence/id_equivalence_helper.dart
@@ -19,6 +19,7 @@
import 'package:expect/expect.dart';
import 'package:kernel/ast.dart' as ir;
+import '../helpers/compiler_helper.dart';
import '../helpers/memory_compiler.dart';
import '../equivalence/id_equivalence.dart';
@@ -26,42 +27,54 @@
show DataInterpreter, StringDataInterpreter;
export '../helpers/memory_compiler.dart' show CollectedMessage;
-const String strongMarker = 'strong';
-const String omitMarker = 'omit';
+const String specWithNnbdOffMarker = 'spec:nnbd-off';
+const String prodWithNnbdOffMarker = 'prod:nnbd-off';
+const String specWithNnbdSdkMarker = 'spec:nnbd-sdk';
+const String prodWithNnbdSdkMarker = 'prod:nnbd-sdk';
-const TestConfig strongConfig =
- const TestConfig(strongMarker, 'strong mode', []);
+const TestConfig specWithNnbdOffConfig = const TestConfig(
+ specWithNnbdOffMarker, 'compliance mode with nnbd off', []);
-const TestConfig omitConfig = const TestConfig(
- omitMarker,
- 'strong mode without implicit checks',
+const TestConfig prodWithNnbdOffConfig = const TestConfig(
+ prodWithNnbdOffMarker,
+ 'production mode with nnbd off',
+ [Flags.omitImplicitChecks, Flags.laxRuntimeTypeToString]);
+
+const TestConfig specWithNnbdSdkConfig = const TestConfig(
+ specWithNnbdSdkMarker, 'compliance mode with nnbd sdk', []);
+
+const TestConfig prodWithNnbdSdkConfig = const TestConfig(
+ prodWithNnbdSdkMarker,
+ 'production mode with nnbd sdk',
[Flags.omitImplicitChecks, Flags.laxRuntimeTypeToString]);
const List<String> allInternalMarkers = const [
- strongMarker,
- omitMarker,
+ specWithNnbdOffMarker,
+ prodWithNnbdOffMarker,
+ specWithNnbdSdkMarker,
+ prodWithNnbdSdkMarker
];
/// Default internal configurations not including experimental features.
-const List<TestConfig> defaultInternalConfigs = const [
- strongConfig,
- omitConfig
-];
+List<TestConfig> defaultInternalConfigs = isDart2jsNnbd
+ ? const [specWithNnbdSdkConfig, prodWithNnbdSdkConfig]
+ : const [specWithNnbdOffConfig, prodWithNnbdOffConfig];
/// All internal configurations including experimental features.
-const List<TestConfig> allInternalConfigs = const [
- strongConfig,
- omitConfig,
-];
+List<TestConfig> allInternalConfigs = isDart2jsNnbd
+ ? const [specWithNnbdSdkConfig, prodWithNnbdSdkConfig]
+ : const [specWithNnbdOffConfig, prodWithNnbdOffConfig];
/// Compliance mode configurations (with strong mode checks) including
/// experimental features.
-const List<TestConfig> allStrongConfigs = const [
- strongConfig,
-];
+List<TestConfig> allSpecConfigs = isDart2jsNnbd
+ ? const [specWithNnbdSdkConfig]
+ : const [specWithNnbdOffConfig];
/// Test configuration used in tests shared with CFE.
-const TestConfig sharedConfig = const TestConfig(dart2jsMarker, 'dart2js', []);
+TestConfig sharedConfig = isDart2jsNnbd
+ ? const TestConfig(dart2jsWithNnbdSdkMarker, 'dart2js with nnbd sdk', [])
+ : const TestConfig(dart2jsMarker, 'dart2js', []);
abstract class DataComputer<T> {
const DataComputer();
@@ -400,7 +413,8 @@
int shards: 1,
int shardIndex: 0,
void onTest(Uri uri),
- List<TestConfig> testedConfigs = defaultInternalConfigs}) async {
+ List<TestConfig> testedConfigs = const []}) async {
+ if (testedConfigs.isEmpty) testedConfigs = defaultInternalConfigs;
Set<String> testedMarkers =
testedConfigs.map((config) => config.marker).toSet();
Expect.isTrue(
diff --git a/tests/compiler/dart2js/field_analysis/jdata/constant_fields.dart b/tests/compiler/dart2js/field_analysis/jdata/constant_fields.dart
index 4c7031d..bb22f2a 100644
--- a/tests/compiler/dart2js/field_analysis/jdata/constant_fields.dart
+++ b/tests/compiler/dart2js/field_analysis/jdata/constant_fields.dart
@@ -19,7 +19,8 @@
}
class Class2 {
- /*strong.member: Class2.field2:constant=BoolConstant(true)*/
+ /*spec:nnbd-off|spec:nnbd-sdk.member: Class2.field2:constant=BoolConstant(true)*/
+ /*prod:nnbd-off|prod:nnbd-sdk.strong.member: Class2.field2:constant=BoolConstant(true)*/
final bool field2;
const Class2({this.field2: false});
diff --git a/tests/compiler/dart2js/field_analysis/jdata/marker.options b/tests/compiler/dart2js/field_analysis/jdata/marker.options
index e9de6cf..f333b74 100644
--- a/tests/compiler/dart2js/field_analysis/jdata/marker.options
+++ b/tests/compiler/dart2js/field_analysis/jdata/marker.options
@@ -1,2 +1,4 @@
-strong=tests/compiler/dart2js/field_analysis/jfield_analysis_test.dart
-omit=tests/compiler/dart2js/field_analysis/jfield_analysis_test.dart
\ No newline at end of file
+spec:nnbd-off=tests/compiler/dart2js/field_analysis/jfield_analysis_test.dart
+prod:nnbd-off=tests/compiler/dart2js/field_analysis/jfield_analysis_test.dart
+spec:nnbd-sdk=tests/compiler/dart2js/field_analysis/jfield_analysis_test.dart
+prod:nnbd-sdk=tests/compiler/dart2js/field_analysis/jfield_analysis_test.dart
\ No newline at end of file
diff --git a/tests/compiler/dart2js/field_analysis/jdata/simple_initializers.dart b/tests/compiler/dart2js/field_analysis/jdata/simple_initializers.dart
index 63c45ec..b4886b3 100644
--- a/tests/compiler/dart2js/field_analysis/jdata/simple_initializers.dart
+++ b/tests/compiler/dart2js/field_analysis/jdata/simple_initializers.dart
@@ -178,10 +178,12 @@
/*member: Class1.field9b:constant=ListConstant([])*/
var field9b = const [];
- /*member: Class1.field9c:initial=ListConstant(<int>[IntConstant(0), IntConstant(1)])*/
+ /*spec:nnbd-off|prod:nnbd-off|prod:nnbd-sdk.member: Class1.field9c:initial=ListConstant(<int>[IntConstant(0), IntConstant(1)])*/
+ /*spec:nnbd-sdk.member: Class1.field9c:initial=ListConstant(<int*>[IntConstant(0), IntConstant(1)])*/
var field9c = const [0, 1];
- /*member: Class1.field9d:constant=ListConstant(<int>[IntConstant(0), IntConstant(1), IntConstant(2)])*/
+ /*spec:nnbd-off|prod:nnbd-off|prod:nnbd-sdk.member: Class1.field9d:constant=ListConstant(<int>[IntConstant(0), IntConstant(1), IntConstant(2)])*/
+ /*spec:nnbd-sdk.member: Class1.field9d:constant=ListConstant(<int*>[IntConstant(0), IntConstant(1), IntConstant(2)])*/
var field9d = const [0, 1, 2];
/*member: Class1.field10a:initial=MapConstant({})*/
@@ -190,10 +192,12 @@
/*member: Class1.field10b:constant=MapConstant({})*/
var field10b = const {};
- /*member: Class1.field10c:initial=MapConstant(<int, int>{IntConstant(0): IntConstant(1), IntConstant(2): IntConstant(3)})*/
+ /*spec:nnbd-off|prod:nnbd-off|prod:nnbd-sdk.member: Class1.field10c:initial=MapConstant(<int, int>{IntConstant(0): IntConstant(1), IntConstant(2): IntConstant(3)})*/
+ /*spec:nnbd-sdk.member: Class1.field10c:initial=MapConstant(<int*, int*>{IntConstant(0): IntConstant(1), IntConstant(2): IntConstant(3)})*/
var field10c = const {0: 1, 2: 3};
- /*member: Class1.field10d:constant=MapConstant(<int, int>{IntConstant(0): IntConstant(1), IntConstant(2): IntConstant(3), IntConstant(4): IntConstant(5)})*/
+ /*spec:nnbd-off|prod:nnbd-off|prod:nnbd-sdk.member: Class1.field10d:constant=MapConstant(<int, int>{IntConstant(0): IntConstant(1), IntConstant(2): IntConstant(3), IntConstant(4): IntConstant(5)})*/
+ /*spec:nnbd-sdk.member: Class1.field10d:constant=MapConstant(<int*, int*>{IntConstant(0): IntConstant(1), IntConstant(2): IntConstant(3), IntConstant(4): IntConstant(5)})*/
var field10d = const {0: 1, 2: 3, 4: 5};
/*member: Class1.field11a:initial=ConstructedConstant(Symbol(_name=StringConstant("foo")))*/
@@ -270,10 +274,12 @@
/*member: Class2.field9b:constant=ListConstant([])*/
var field9b;
- /*member: Class2.field9c:initial=ListConstant(<int>[IntConstant(0), IntConstant(1)])*/
+ /*spec:nnbd-off|prod:nnbd-off|prod:nnbd-sdk.member: Class2.field9c:initial=ListConstant(<int>[IntConstant(0), IntConstant(1)])*/
+ /*spec:nnbd-sdk.member: Class2.field9c:initial=ListConstant(<int*>[IntConstant(0), IntConstant(1)])*/
var field9c;
- /*member: Class2.field9d:constant=ListConstant(<int>[IntConstant(0), IntConstant(1), IntConstant(2)])*/
+ /*spec:nnbd-off|prod:nnbd-off|prod:nnbd-sdk.member: Class2.field9d:constant=ListConstant(<int>[IntConstant(0), IntConstant(1), IntConstant(2)])*/
+ /*spec:nnbd-sdk.member: Class2.field9d:constant=ListConstant(<int*>[IntConstant(0), IntConstant(1), IntConstant(2)])*/
var field9d;
/*member: Class2.field10a:initial=MapConstant({})*/
@@ -282,10 +288,12 @@
/*member: Class2.field10b:constant=MapConstant({})*/
var field10b;
- /*member: Class2.field10c:initial=MapConstant(<int, int>{IntConstant(0): IntConstant(1), IntConstant(2): IntConstant(3)})*/
+ /*spec:nnbd-off|prod:nnbd-off|prod:nnbd-sdk.member: Class2.field10c:initial=MapConstant(<int, int>{IntConstant(0): IntConstant(1), IntConstant(2): IntConstant(3)})*/
+ /*spec:nnbd-sdk.member: Class2.field10c:initial=MapConstant(<int*, int*>{IntConstant(0): IntConstant(1), IntConstant(2): IntConstant(3)})*/
var field10c;
- /*member: Class2.field10d:constant=MapConstant(<int, int>{IntConstant(0): IntConstant(1), IntConstant(2): IntConstant(3), IntConstant(4): IntConstant(5)})*/
+ /*spec:nnbd-off|prod:nnbd-off|prod:nnbd-sdk.member: Class2.field10d:constant=MapConstant(<int, int>{IntConstant(0): IntConstant(1), IntConstant(2): IntConstant(3), IntConstant(4): IntConstant(5)})*/
+ /*spec:nnbd-sdk.member: Class2.field10d:constant=MapConstant(<int*, int*>{IntConstant(0): IntConstant(1), IntConstant(2): IntConstant(3), IntConstant(4): IntConstant(5)})*/
var field10d;
/*member: Class2.field11a:initial=ConstructedConstant(Symbol(_name=StringConstant("foo")))*/
diff --git a/tests/compiler/dart2js/field_analysis/jfield_analysis_test.dart b/tests/compiler/dart2js/field_analysis/jfield_analysis_test.dart
index e301643..857f7e8 100644
--- a/tests/compiler/dart2js/field_analysis/jfield_analysis_test.dart
+++ b/tests/compiler/dart2js/field_analysis/jfield_analysis_test.dart
@@ -20,7 +20,7 @@
asyncTest(() async {
Directory dataDir = new Directory.fromUri(Platform.script.resolve('jdata'));
await checkTests(dataDir, const JAllocatorAnalysisDataComputer(),
- args: args, testedConfigs: allStrongConfigs);
+ args: args, testedConfigs: allSpecConfigs);
});
}
diff --git a/tests/compiler/dart2js/field_analysis/kdata/marker.options b/tests/compiler/dart2js/field_analysis/kdata/marker.options
index 16bd064..19ad6c1 100644
--- a/tests/compiler/dart2js/field_analysis/kdata/marker.options
+++ b/tests/compiler/dart2js/field_analysis/kdata/marker.options
@@ -1,2 +1,4 @@
-strong=tests/compiler/dart2js/field_analysis/kfield_analysis_test.dart
-omit=tests/compiler/dart2js/field_analysis/kfield_analysis_test.dart
\ No newline at end of file
+spec:nnbd-off=tests/compiler/dart2js/field_analysis/kfield_analysis_test.dart
+prod:nnbd-off=tests/compiler/dart2js/field_analysis/kfield_analysis_test.dart
+spec:nnbd-sdk=tests/compiler/dart2js/field_analysis/kfield_analysis_test.dart
+prod:nnbd-sdk=tests/compiler/dart2js/field_analysis/kfield_analysis_test.dart
\ No newline at end of file
diff --git a/tests/compiler/dart2js/field_analysis/kfield_analysis_test.dart b/tests/compiler/dart2js/field_analysis/kfield_analysis_test.dart
index 3a8f113..22af00e 100644
--- a/tests/compiler/dart2js/field_analysis/kfield_analysis_test.dart
+++ b/tests/compiler/dart2js/field_analysis/kfield_analysis_test.dart
@@ -20,7 +20,7 @@
asyncTest(() async {
Directory dataDir = new Directory.fromUri(Platform.script.resolve('kdata'));
await checkTests(dataDir, const KAllocatorAnalysisDataComputer(),
- args: args, testedConfigs: allStrongConfigs);
+ args: args, testedConfigs: allSpecConfigs);
});
}
diff --git a/tests/compiler/dart2js/helpers/compiler_helper.dart b/tests/compiler/dart2js/helpers/compiler_helper.dart
index 9c40a59..8f4caef 100644
--- a/tests/compiler/dart2js/helpers/compiler_helper.dart
+++ b/tests/compiler/dart2js/helpers/compiler_helper.dart
@@ -7,6 +7,7 @@
library compiler_helper;
import 'dart:async';
+import 'dart:io';
import 'package:compiler/compiler_new.dart';
import 'package:compiler/src/commandline_options.dart';
import 'package:compiler/src/common_elements.dart';
@@ -237,3 +238,6 @@
RegExp _directivePattern = new RegExp(
// \1 \2 \3
r'''// *(present|absent): *(?:"([^"]*)"|'([^'']*)')''', multiLine: true);
+
+bool isDart2jsNnbd =
+ Platform.environment['DART_CONFIGURATION'] == 'ReleaseX64NNBD';
diff --git a/tests/compiler/dart2js/impact/data/marker.options b/tests/compiler/dart2js/impact/data/marker.options
index f001ac8..8ea68a6 100644
--- a/tests/compiler/dart2js/impact/data/marker.options
+++ b/tests/compiler/dart2js/impact/data/marker.options
@@ -1 +1,2 @@
-strong=tests/compiler/dart2js/impact/impact_test.dart
\ No newline at end of file
+spec:nnbd-off=tests/compiler/dart2js/impact/impact_test.dart
+spec:nnbd-sdk=tests/compiler/dart2js/impact/impact_test.dart
\ No newline at end of file
diff --git a/tests/compiler/dart2js/impact/impact_test.dart b/tests/compiler/dart2js/impact/impact_test.dart
index 1ae3981..315b9ac 100644
--- a/tests/compiler/dart2js/impact/impact_test.dart
+++ b/tests/compiler/dart2js/impact/impact_test.dart
@@ -25,15 +25,13 @@
print('==================================================================');
useImpactDataForTesting = false;
await checkTests(dataDir, const ImpactDataComputer(),
- args: args,
- testedConfigs: [strongConfig]);
+ args: args, testedConfigs: allSpecConfigs);
print('Testing computation of ResolutionImpact through ImpactData');
print('==================================================================');
useImpactDataForTesting = true;
await checkTests(dataDir, const ImpactDataComputer(),
- args: args,
- testedConfigs: [strongConfig]);
+ args: args, testedConfigs: allSpecConfigs);
});
}
diff --git a/tests/compiler/dart2js/inference/callers/marker.options b/tests/compiler/dart2js/inference/callers/marker.options
index 10b39a7..64dc9c4 100644
--- a/tests/compiler/dart2js/inference/callers/marker.options
+++ b/tests/compiler/dart2js/inference/callers/marker.options
@@ -1,2 +1,4 @@
-strong=tests/compiler/dart2js/inference/callers_test.dart
-omit=tests/compiler/dart2js/inference/callers_test.dart
\ No newline at end of file
+spec:nnbd-off=tests/compiler/dart2js/inference/callers_test.dart
+prod:nnbd-off=tests/compiler/dart2js/inference/callers_test.dart
+spec:nnbd-sdk=tests/compiler/dart2js/inference/callers_test.dart
+prod:nnbd-sdk=tests/compiler/dart2js/inference/callers_test.dart
\ No newline at end of file
diff --git a/tests/compiler/dart2js/inference/data/call_method_function_typed_value.dart b/tests/compiler/dart2js/inference/data/call_method_function_typed_value.dart
index 23487e5..48c81d4 100644
--- a/tests/compiler/dart2js/inference/data/call_method_function_typed_value.dart
+++ b/tests/compiler/dart2js/inference/data/call_method_function_typed_value.dart
@@ -11,8 +11,8 @@
/*member: f:[subclass=JSInt]*/
int f(
int
- /*strong.[null|subclass=Object]*/
- /*omit.[null|subclass=JSInt]*/
+ /*spec:nnbd-off|spec:nnbd-sdk.[null|subclass=Object]*/
+ /*prod:nnbd-off|prod:nnbd-sdk.[null|subclass=JSInt]*/
i) =>
2 /*invoke: [exact=JSUInt31]*/ * i;
diff --git a/tests/compiler/dart2js/inference/data/closure_tracer_28919.dart b/tests/compiler/dart2js/inference/data/closure_tracer_28919.dart
index b93f472..2f1dcc5 100644
--- a/tests/compiler/dart2js/inference/data/closure_tracer_28919.dart
+++ b/tests/compiler/dart2js/inference/data/closure_tracer_28919.dart
@@ -57,8 +57,8 @@
i /*invoke: [subclass=JSPositiveInt]*/ ++) {
methods. /*invoke: [exact=JSExtendableArray]*/ add(
/*[null]*/ (int
- /*strong.[null|subclass=Object]*/
- /*omit.[null|subclass=JSInt]*/
+ /*spec:nnbd-off.[null|subclass=Object]*/
+ /*prod:nnbd-off.[null|subclass=JSInt]*/
x) {
res = x;
sum = x /*invoke: [null|subclass=JSInt]*/ + i;
diff --git a/tests/compiler/dart2js/inference/data/list_tracer_typed_data_length.dart b/tests/compiler/dart2js/inference/data/list_tracer_typed_data_length.dart
index 9624438..a08ef1a 100644
--- a/tests/compiler/dart2js/inference/data/list_tracer_typed_data_length.dart
+++ b/tests/compiler/dart2js/inference/data/list_tracer_typed_data_length.dart
@@ -6,7 +6,7 @@
import 'dart:typed_data';
-// TODO(johnniwinther): Fix inference for strong mode. List elements should not
+// TODO(johnniwinther): Fix inference for spec:nnbd-off mode. List elements should not
// be [empty].
/*member: myList:Container([null|exact=NativeFloat32List], element: [subclass=JSNumber], length: 42)*/
diff --git a/tests/compiler/dart2js/inference/data/map_tracer_const.dart b/tests/compiler/dart2js/inference/data/map_tracer_const.dart
index 3ff4fbb..4e4595d 100644
--- a/tests/compiler/dart2js/inference/data/map_tracer_const.dart
+++ b/tests/compiler/dart2js/inference/data/map_tracer_const.dart
@@ -7,8 +7,8 @@
/*member: closure:[exact=JSUInt31]*/
int closure(
int
- /*strong.Union([exact=JSDouble], [exact=JSUInt31])*/
- /*omit.[exact=JSUInt31]*/
+ /*spec:nnbd-off|spec:nnbd-sdk.Union([exact=JSDouble], [exact=JSUInt31])*/
+ /*prod:nnbd-off|prod:nnbd-sdk.[exact=JSUInt31]*/
x) {
return x;
}
diff --git a/tests/compiler/dart2js/inference/data/marker.options b/tests/compiler/dart2js/inference/data/marker.options
index ed13f42..46aaaf9 100644
--- a/tests/compiler/dart2js/inference/data/marker.options
+++ b/tests/compiler/dart2js/inference/data/marker.options
@@ -1,2 +1,4 @@
-strong=tests/compiler/dart2js/inference/inference_test_helper.dart
-omit=tests/compiler/dart2js/inference/inference_test_helper.dart
\ No newline at end of file
+spec:nnbd-off=tests/compiler/dart2js/inference/inference_test_helper.dart
+prod:nnbd-off=tests/compiler/dart2js/inference/inference_test_helper.dart
+spec:nnbd-sdk=tests/compiler/dart2js/inference/inference_test_helper.dart
+prod:nnbd-sdk=tests/compiler/dart2js/inference/inference_test_helper.dart
\ No newline at end of file
diff --git a/tests/compiler/dart2js/inference/data/no_such_method.dart b/tests/compiler/dart2js/inference/data/no_such_method.dart
index daa1bdd..792f6eb 100644
--- a/tests/compiler/dart2js/inference/data/no_such_method.dart
+++ b/tests/compiler/dart2js/inference/data/no_such_method.dart
@@ -17,8 +17,8 @@
/*member: Class1.noSuchMethod:[exact=JSUInt31]*/
noSuchMethod(
Invocation
- /*strong.[null|subclass=Object]*/
- /*omit.[null|exact=JSInvocationMirror]*/
+ /*spec:nnbd-off.[null|subclass=Object]*/
+ /*prod:nnbd-off.[null|exact=JSInvocationMirror]*/
_) =>
42;
@@ -41,8 +41,8 @@
/*member: Class2.noSuchMethod:[exact=JSUInt31]*/
noSuchMethod(
Invocation
- /*strong.[null|subclass=Object]*/
- /*omit.[null|exact=JSInvocationMirror]*/
+ /*spec:nnbd-off.[null|subclass=Object]*/
+ /*prod:nnbd-off.[null|exact=JSInvocationMirror]*/
_) =>
42;
@@ -65,8 +65,8 @@
/*member: Class3.noSuchMethod:[null|subclass=Object]*/
noSuchMethod(
Invocation
- /*strong.[null|subclass=Object]*/
- /*omit.[null|exact=JSInvocationMirror]*/
+ /*spec:nnbd-off.[null|subclass=Object]*/
+ /*prod:nnbd-off.[null|exact=JSInvocationMirror]*/
invocation) {
return invocation
.
@@ -101,8 +101,8 @@
/*member: Class4.noSuchMethod:[null]*/
noSuchMethod(
Invocation
- /*strong.[null|subclass=Object]*/
- /*omit.[null|exact=JSInvocationMirror]*/
+ /*spec:nnbd-off.[null|subclass=Object]*/
+ /*prod:nnbd-off.[null|exact=JSInvocationMirror]*/
invocation) {
this. /*update: [exact=Class4]*/ field = invocation
.
diff --git a/tests/compiler/dart2js/inference/data/no_such_method1.dart b/tests/compiler/dart2js/inference/data/no_such_method1.dart
index f2bac32..2c7d7d3 100644
--- a/tests/compiler/dart2js/inference/data/no_such_method1.dart
+++ b/tests/compiler/dart2js/inference/data/no_such_method1.dart
@@ -8,8 +8,8 @@
class A {
/*member: A.noSuchMethod:[exact=JSUInt31]*/
noSuchMethod(
- /*strong.[null|subclass=Object]*/
- /*omit.[null|exact=JSInvocationMirror]*/
+ /*spec:nnbd-off.[null|subclass=Object]*/
+ /*prod:nnbd-off.[null|exact=JSInvocationMirror]*/
im) =>
42;
}
diff --git a/tests/compiler/dart2js/inference/data/no_such_method2.dart b/tests/compiler/dart2js/inference/data/no_such_method2.dart
index 8f56a10..e50ec96 100644
--- a/tests/compiler/dart2js/inference/data/no_such_method2.dart
+++ b/tests/compiler/dart2js/inference/data/no_such_method2.dart
@@ -8,8 +8,8 @@
abstract class A {
/*member: A.noSuchMethod:[exact=JSUInt31]*/
noSuchMethod(
- /*strong.[null|subclass=Object]*/
- /*omit.[null|exact=JSInvocationMirror]*/
+ /*spec:nnbd-off.[null|subclass=Object]*/
+ /*prod:nnbd-off.[null|exact=JSInvocationMirror]*/
im) =>
42;
}
@@ -33,8 +33,8 @@
/*member: D.noSuchMethod:[exact=JSDouble]*/
noSuchMethod(
- /*omit.[null|exact=JSInvocationMirror]*/
- /*strong.[null|subclass=Object]*/
+ /*prod:nnbd-off.[null|exact=JSInvocationMirror]*/
+ /*spec:nnbd-off.[null|subclass=Object]*/
im) =>
42.5;
}
diff --git a/tests/compiler/dart2js/inference/data/no_such_method3.dart b/tests/compiler/dart2js/inference/data/no_such_method3.dart
index 06a8679..275d209 100644
--- a/tests/compiler/dart2js/inference/data/no_such_method3.dart
+++ b/tests/compiler/dart2js/inference/data/no_such_method3.dart
@@ -10,8 +10,8 @@
// throws an exception.
/*member: A.noSuchMethod:[empty]*/
noSuchMethod(
- /*strong.[null|subclass=Object]*/
- /*omit.[null|exact=JSInvocationMirror]*/
+ /*spec:nnbd-off.[null|subclass=Object]*/
+ /*prod:nnbd-off.[null|exact=JSInvocationMirror]*/
im) =>
throw 'foo';
}
diff --git a/tests/compiler/dart2js/inference/data/parameters_trust.dart b/tests/compiler/dart2js/inference/data/parameters_trust.dart
index 3cdb9d4..ddf89ec 100644
--- a/tests/compiler/dart2js/inference/data/parameters_trust.dart
+++ b/tests/compiler/dart2js/inference/data/parameters_trust.dart
@@ -18,8 +18,8 @@
/*member: _trustParameters:[exact=JSUInt31]*/
_trustParameters(
int
- /*strong.Union([exact=JSString], [exact=JSUInt31])*/
- /*omit.[exact=JSUInt31]*/
+ /*spec:nnbd-off.Union([exact=JSString], [exact=JSUInt31])*/
+ /*prod:nnbd-off.[exact=JSUInt31]*/
i) {
return i;
}
diff --git a/tests/compiler/dart2js/inference/data/try_catch.dart b/tests/compiler/dart2js/inference/data/try_catch.dart
index 0a41400..0a3d09a 100644
--- a/tests/compiler/dart2js/inference/data/try_catch.dart
+++ b/tests/compiler/dart2js/inference/data/try_catch.dart
@@ -122,7 +122,7 @@
return a;
}
-/*member: returnInt6:[subclass=JSInt]*/
+/*spec:nnbd-off|prod:nnbd-off.member: returnInt6:[subclass=JSInt]*/
returnInt6() {
try {
throw 42;
diff --git a/tests/compiler/dart2js/inference/inference_data/marker.options b/tests/compiler/dart2js/inference/inference_data/marker.options
index c90afd3..1ac262c 100644
--- a/tests/compiler/dart2js/inference/inference_data/marker.options
+++ b/tests/compiler/dart2js/inference/inference_data/marker.options
@@ -1 +1,2 @@
-strong=tests/compiler/dart2js/inference/inference_data_test.dart
+spec:nnbd-off=tests/compiler/dart2js/inference/inference_data_test.dart
+spec:nnbd-sdk=tests/compiler/dart2js/inference/inference_data_test.dart
diff --git a/tests/compiler/dart2js/inference/inference_data_test.dart b/tests/compiler/dart2js/inference/inference_data_test.dart
index 48392cd..1ad073f 100644
--- a/tests/compiler/dart2js/inference/inference_data_test.dart
+++ b/tests/compiler/dart2js/inference/inference_data_test.dart
@@ -25,7 +25,7 @@
new Directory.fromUri(Platform.script.resolve('inference_data'));
await checkTests(dataDir, const InferenceDataComputer(),
args: args,
- testedConfigs: [strongConfig],
+ testedConfigs: allSpecConfigs,
options: [stopAfterTypeInference]);
});
}
diff --git a/tests/compiler/dart2js/inference/side_effects/marker.options b/tests/compiler/dart2js/inference/side_effects/marker.options
index 03ae8ce..18f405c 100644
--- a/tests/compiler/dart2js/inference/side_effects/marker.options
+++ b/tests/compiler/dart2js/inference/side_effects/marker.options
@@ -1,2 +1,4 @@
-strong=tests/compiler/dart2js/inference/side_effects_test.dart
-omit=tests/compiler/dart2js/inference/side_effects_test.dart
\ No newline at end of file
+spec:nnbd-off=tests/compiler/dart2js/inference/side_effects_test.dart
+prod:nnbd-off=tests/compiler/dart2js/inference/side_effects_test.dart
+spec:nnbd-sdk=tests/compiler/dart2js/inference/side_effects_test.dart
+prod:nnbd-sdk=tests/compiler/dart2js/inference/side_effects_test.dart
\ No newline at end of file
diff --git a/tests/compiler/dart2js/inlining/data/constructor.dart b/tests/compiler/dart2js/inlining/data/constructor.dart
index f9e0070..5e4b03e 100644
--- a/tests/compiler/dart2js/inlining/data/constructor.dart
+++ b/tests/compiler/dart2js/inlining/data/constructor.dart
@@ -51,7 +51,8 @@
////////////////////////////////////////////////////////////////////////////////
class Class3<T> {
- /*member: Class3.:[forceInlineGenericConstructor:Class3<int>]*/
+ /*spec:nnbd-off|prod:nnbd-off.member: Class3.:[forceInlineGenericConstructor:Class3<int>]*/
+ /*spec:nnbd-sdk|prod:nnbd-sdk.member: Class3.:[forceInlineGenericConstructor:Class3<int*>]*/
@pragma('dart2js:tryInline')
Class3();
}
@@ -67,13 +68,15 @@
////////////////////////////////////////////////////////////////////////////////
class Class4a<T> implements Class4b<T> {
- /*member: Class4a.:[forceInlineGenericFactory:Class4a<int>]*/
+ /*spec:nnbd-off|prod:nnbd-off.member: Class4a.:[forceInlineGenericFactory:Class4a<int>]*/
+ /*spec:nnbd-sdk|prod:nnbd-sdk.member: Class4a.:[forceInlineGenericFactory:Class4a<int*>]*/
@pragma('dart2js:tryInline')
Class4a();
}
class Class4b<T> {
- /*member: Class4b.:[forceInlineGenericFactory:Class4b<int>]*/
+ /*spec:nnbd-off|prod:nnbd-off.member: Class4b.:[forceInlineGenericFactory:Class4b<int>]*/
+ /*spec:nnbd-sdk|prod:nnbd-sdk.member: Class4b.:[forceInlineGenericFactory:Class4b<int*>]*/
@pragma('dart2js:tryInline')
factory Class4b() => new Class4a<T>();
}
diff --git a/tests/compiler/dart2js/inlining/data/marker.options b/tests/compiler/dart2js/inlining/data/marker.options
index 4750f8f..2dc3010 100644
--- a/tests/compiler/dart2js/inlining/data/marker.options
+++ b/tests/compiler/dart2js/inlining/data/marker.options
@@ -1,2 +1,4 @@
-strong=tests/compiler/dart2js/inlining/inlining_test.dart
-omit=tests/compiler/dart2js/inlining/inlining_test.dart
\ No newline at end of file
+spec:nnbd-off=tests/compiler/dart2js/inlining/inlining_test.dart
+prod:nnbd-off=tests/compiler/dart2js/inlining/inlining_test.dart
+spec:nnbd-sdk=tests/compiler/dart2js/inlining/inlining_test.dart
+prod:nnbd-sdk=tests/compiler/dart2js/inlining/inlining_test.dart
\ No newline at end of file
diff --git a/tests/compiler/dart2js/inlining/data/nested.dart b/tests/compiler/dart2js/inlining/data/nested.dart
index e735510..f1239aa 100644
--- a/tests/compiler/dart2js/inlining/data/nested.dart
+++ b/tests/compiler/dart2js/inlining/data/nested.dart
@@ -15,7 +15,8 @@
////////////////////////////////////////////////////////////////////////////////
class Class1<T> {
- /*member: Class1.:[nestedGenericInlining:Class1<int>]*/
+ /*spec:nnbd-off|prod:nnbd-off.member: Class1.:[nestedGenericInlining:Class1<int>]*/
+ /*spec:nnbd-sdk|prod:nnbd-sdk.member: Class1.:[nestedGenericInlining:Class1<int*>]*/
@pragma('dart2js:tryInline')
Class1();
@@ -29,7 +30,8 @@
class Class2<T> {
// TODO(johnniwinther): Should the type have been Class<List<int>>?
// Similarly below.
- /*member: Class2.:[nestedGenericInlining:Class2<List<Class1.T>>]*/
+ /*spec:nnbd-off|prod:nnbd-off.member: Class2.:[nestedGenericInlining:Class2<List<Class1.T>>]*/
+ /*spec:nnbd-sdk|prod:nnbd-sdk.member: Class2.:[nestedGenericInlining:Class2<List<Class1.T*>*>]*/
@pragma('dart2js:tryInline')
Class2();
@@ -49,7 +51,8 @@
////////////////////////////////////////////////////////////////////////////////
class Class3a<T> implements Class3b<T> {
- /*member: Class3a.:[nestedGenericFactoryInlining:Class3a<int>]*/
+ /*spec:nnbd-off|prod:nnbd-off.member: Class3a.:[nestedGenericFactoryInlining:Class3a<int>]*/
+ /*spec:nnbd-sdk|prod:nnbd-sdk.member: Class3a.:[nestedGenericFactoryInlining:Class3a<int*>]*/
@pragma('dart2js:tryInline')
Class3a();
@@ -61,7 +64,8 @@
}
abstract class Class3b<T> {
- /*member: Class3b.:[nestedGenericFactoryInlining:Class3b<int>]*/
+ /*spec:nnbd-off|prod:nnbd-off.member: Class3b.:[nestedGenericFactoryInlining:Class3b<int>]*/
+ /*spec:nnbd-sdk|prod:nnbd-sdk.member: Class3b.:[nestedGenericFactoryInlining:Class3b<int*>]*/
@pragma('dart2js:tryInline')
factory Class3b() => new Class3a<T>();
@@ -69,7 +73,8 @@
}
class Class4a<T> implements Class4b<T> {
- /*member: Class4a.:[nestedGenericFactoryInlining:Class4a<Class4b.T>]*/
+ /*spec:nnbd-off|prod:nnbd-off.member: Class4a.:[nestedGenericFactoryInlining:Class4a<Class4b.T>]*/
+ /*spec:nnbd-sdk|prod:nnbd-sdk.member: Class4a.:[nestedGenericFactoryInlining:Class4a<Class4b.T*>]*/
@pragma('dart2js:tryInline')
Class4a();
@@ -79,7 +84,8 @@
}
abstract class Class4b<T> {
- /*member: Class4b.:[nestedGenericFactoryInlining:Class4b<List<Class3a.T>>]*/
+ /*spec:nnbd-off|prod:nnbd-off.member: Class4b.:[nestedGenericFactoryInlining:Class4b<List<Class3a.T>>]*/
+ /*spec:nnbd-sdk|prod:nnbd-sdk.member: Class4b.:[nestedGenericFactoryInlining:Class4b<List<Class3a.T*>*>]*/
@pragma('dart2js:tryInline')
factory Class4b() => new Class4a<T>();
diff --git a/tests/compiler/dart2js/inlining/data/type_variables.dart b/tests/compiler/dart2js/inlining/data/type_variables.dart
index 14a1ce3..40fb3b1 100644
--- a/tests/compiler/dart2js/inlining/data/type_variables.dart
+++ b/tests/compiler/dart2js/inlining/data/type_variables.dart
@@ -9,12 +9,14 @@
inlineTypeTests();
}
-/*member: Mixin1.:[inlineTypeTests:Mixin1<int>]*/
+/*spec:nnbd-off|prod:nnbd-off.member: Mixin1.:[inlineTypeTests:Mixin1<int>]*/
+/*spec:nnbd-sdk|prod:nnbd-sdk.member: Mixin1.:[inlineTypeTests:Mixin1<int*>]*/
class Mixin1<S> {
var field = /*[]*/ (S s) => null;
}
-/*member: Class1.:[inlineTypeTests:Class1<int>]*/
+/*spec:nnbd-off|prod:nnbd-off.member: Class1.:[inlineTypeTests:Class1<int>]*/
+/*spec:nnbd-sdk|prod:nnbd-sdk.member: Class1.:[inlineTypeTests:Class1<int*>]*/
class Class1<T> extends Object with Mixin1<T> {}
/*member: _inlineTypeTests:[inlineTypeTests]*/
diff --git a/tests/compiler/dart2js/jumps/data/marker.options b/tests/compiler/dart2js/jumps/data/marker.options
index 37aec9d..6c8f0b4 100644
--- a/tests/compiler/dart2js/jumps/data/marker.options
+++ b/tests/compiler/dart2js/jumps/data/marker.options
@@ -1,2 +1,4 @@
-strong=tests/compiler/dart2js/jumps/jump_test.dart
-omit=tests/compiler/dart2js/jumps/jump_test.dart
\ No newline at end of file
+spec:nnbd-off=tests/compiler/dart2js/jumps/jump_test.dart
+prod:nnbd-off=tests/compiler/dart2js/jumps/jump_test.dart
+spec:nnbd-sdk=tests/compiler/dart2js/jumps/jump_test.dart
+prod:nnbd-sdk=tests/compiler/dart2js/jumps/jump_test.dart
\ No newline at end of file
diff --git a/tests/compiler/dart2js/member_usage/data/marker.options b/tests/compiler/dart2js/member_usage/data/marker.options
index 91b789d..31de344 100644
--- a/tests/compiler/dart2js/member_usage/data/marker.options
+++ b/tests/compiler/dart2js/member_usage/data/marker.options
@@ -1,2 +1,4 @@
-strong=tests/compiler/dart2js/member_usage/member_usage_test.dart
-omit=tests/compiler/dart2js/member_usage/member_usage_test.dart
\ No newline at end of file
+spec:nnbd-off=tests/compiler/dart2js/member_usage/member_usage_test.dart
+prod:nnbd-off=tests/compiler/dart2js/member_usage/member_usage_test.dart
+spec:nnbd-sdk=tests/compiler/dart2js/member_usage/member_usage_test.dart
+prod:nnbd-sdk=tests/compiler/dart2js/member_usage/member_usage_test.dart
\ No newline at end of file
diff --git a/tests/compiler/dart2js/member_usage/member_usage_test.dart b/tests/compiler/dart2js/member_usage/member_usage_test.dart
index 834cd14..ff367d6 100644
--- a/tests/compiler/dart2js/member_usage/member_usage_test.dart
+++ b/tests/compiler/dart2js/member_usage/member_usage_test.dart
@@ -25,12 +25,12 @@
print(' Test with enqueuer checks');
print('------------------------------------------------------------------');
await checkTests(dataDir, const ClosedWorldDataComputer(false),
- args: args, testedConfigs: allStrongConfigs);
+ args: args, testedConfigs: allSpecConfigs);
print('------------------------------------------------------------------');
print(' Test without enqueuer checks');
print('------------------------------------------------------------------');
await checkTests(dataDir, const ClosedWorldDataComputer(true),
- args: args, testedConfigs: allStrongConfigs);
+ args: args, testedConfigs: allSpecConfigs);
});
}
diff --git a/tests/compiler/dart2js/optimization/data/finalized_type_variable.dart b/tests/compiler/dart2js/optimization/data/finalized_type_variable.dart
index 865a2d0..4db1df3 100644
--- a/tests/compiler/dart2js/optimization/data/finalized_type_variable.dart
+++ b/tests/compiler/dart2js/optimization/data/finalized_type_variable.dart
@@ -54,8 +54,8 @@
}
}
-/*strong.member: main:*/
-/*omit.member: main:FieldSet=[name=AppView.ctx,name=AppView.ctx]*/
+/*spec:nnbd-off.member: main:*/
+/*prod:nnbd-off|prod:nnbd-sdk.member: main:FieldSet=[name=AppView.ctx,name=AppView.ctx]*/
main() {
var c1 = new ViewCardComponent();
c1.ctx = new CardComponent();
diff --git a/tests/compiler/dart2js/optimization/data/index.dart b/tests/compiler/dart2js/optimization/data/index.dart
index 7b95043..8047545 100644
--- a/tests/compiler/dart2js/optimization/data/index.dart
+++ b/tests/compiler/dart2js/optimization/data/index.dart
@@ -39,8 +39,8 @@
return list[index]; // CFE inserts an implicit cast of the index.
}
-/*strong.member: mutableDynamicListDynamicIndex:Specializer=[!Index]*/
-/*omit.member: mutableDynamicListDynamicIndex:Specializer=[Index]*/
+/*spec:nnbd-off.member: mutableDynamicListDynamicIndex:Specializer=[!Index]*/
+/*prod:nnbd-off|prod:nnbd-sdk.member: mutableDynamicListDynamicIndex:Specializer=[Index]*/
@pragma('dart2js:noInline')
@pragma('dart2js:disableFinal')
mutableDynamicListDynamicIndex(dynamic index) {
diff --git a/tests/compiler/dart2js/optimization/data/index_assign.dart b/tests/compiler/dart2js/optimization/data/index_assign.dart
index 45a88e4..67d5523 100644
--- a/tests/compiler/dart2js/optimization/data/index_assign.dart
+++ b/tests/compiler/dart2js/optimization/data/index_assign.dart
@@ -10,39 +10,39 @@
list[0] = 1;
}
-/*strong.member: unknownListIndexAssign:Specializer=[!IndexAssign]*/
-/*omit.member: unknownListIndexAssign:Specializer=[IndexAssign]*/
+/*spec:nnbd-off.member: unknownListIndexAssign:Specializer=[!IndexAssign]*/
+/*prod:nnbd-off|prod:nnbd-sdk.member: unknownListIndexAssign:Specializer=[IndexAssign]*/
@pragma('dart2js:noInline')
unknownListIndexAssign(List list) {
list[0] = 1;
}
-/*strong.member: possiblyNullMutableListIndexAssign:Specializer=[!IndexAssign]*/
-/*omit.member: possiblyNullMutableListIndexAssign:Specializer=[IndexAssign]*/
+/*spec:nnbd-off.member: possiblyNullMutableListIndexAssign:Specializer=[!IndexAssign]*/
+/*prod:nnbd-off|prod:nnbd-sdk.member: possiblyNullMutableListIndexAssign:Specializer=[IndexAssign]*/
@pragma('dart2js:noInline')
possiblyNullMutableListIndexAssign(bool b) {
var list = b ? [0] : null;
list[0] = 1;
}
-/*strong.member: mutableListIndexAssign:Specializer=[!IndexAssign]*/
-/*omit.member: mutableListIndexAssign:Specializer=[IndexAssign]*/
+/*spec:nnbd-off.member: mutableListIndexAssign:Specializer=[!IndexAssign]*/
+/*prod:nnbd-off|prod:nnbd-sdk.member: mutableListIndexAssign:Specializer=[IndexAssign]*/
@pragma('dart2js:noInline')
mutableListIndexAssign() {
var list = [0];
list[0] = 1;
}
-/*strong.member: mutableListDynamicIndexAssign:Specializer=[!IndexAssign]*/
-/*omit.member: mutableListDynamicIndexAssign:Specializer=[IndexAssign]*/
+/*spec:nnbd-off.member: mutableListDynamicIndexAssign:Specializer=[!IndexAssign]*/
+/*prod:nnbd-off|prod:nnbd-sdk.member: mutableListDynamicIndexAssign:Specializer=[IndexAssign]*/
@pragma('dart2js:noInline')
mutableListDynamicIndexAssign(dynamic index) {
var list = [0];
list[index] = 1;
}
-/*strong.member: mutableListDynamicValueIndexAssign:Specializer=[!IndexAssign]*/
-/*omit.member: mutableListDynamicValueIndexAssign:Specializer=[IndexAssign]*/
+/*spec:nnbd-off.member: mutableListDynamicValueIndexAssign:Specializer=[!IndexAssign]*/
+/*prod:nnbd-off|prod:nnbd-sdk.member: mutableListDynamicValueIndexAssign:Specializer=[IndexAssign]*/
@pragma('dart2js:noInline')
mutableListDynamicValueIndexAssign(dynamic value) {
var list = [0];
diff --git a/tests/compiler/dart2js/optimization/data/marker.options b/tests/compiler/dart2js/optimization/data/marker.options
index 3b03def..2c09b09 100644
--- a/tests/compiler/dart2js/optimization/data/marker.options
+++ b/tests/compiler/dart2js/optimization/data/marker.options
@@ -1,2 +1,4 @@
-strong=tests/compiler/dart2js/optimization/optimization_test.dart
-omit=tests/compiler/dart2js/optimization/optimization_test.dart
\ No newline at end of file
+spec:nnbd-off=tests/compiler/dart2js/optimization/optimization_test.dart
+prod:nnbd-off=tests/compiler/dart2js/optimization/optimization_test.dart
+spec:nnbd-sdk=tests/compiler/dart2js/optimization/optimization_test.dart
+prod:nnbd-sdk=tests/compiler/dart2js/optimization/optimization_test.dart
\ No newline at end of file
diff --git a/tests/compiler/dart2js/rti/data/async_foreach.dart b/tests/compiler/dart2js/rti/data/async_foreach.dart
index 22efbe0..16b3479 100644
--- a/tests/compiler/dart2js/rti/data/async_foreach.dart
+++ b/tests/compiler/dart2js/rti/data/async_foreach.dart
@@ -4,8 +4,8 @@
// @dart = 2.7
-/*strong.class: Class:direct,explicit=[Class.T],implicit=[Class.T],needsArgs*/
-/*omit.class: Class:needsArgs*/
+/*spec:nnbd-off.class: Class:direct,explicit=[Class.T],implicit=[Class.T],needsArgs*/
+/*prod:nnbd-off.class: Class:needsArgs*/
class Class<T> {
method() {
var list = <T>[];
@@ -16,8 +16,8 @@
// This happens because the closure is thought as possibly going to the
// async.errorHandler callback.
list.forEach(
- /*strong.needsSignature*/
- /*omit.needsSignature*/
+ /*spec:nnbd-off.needsSignature*/
+ /*prod:nnbd-off.needsSignature*/
(x) => print(x));
}
}
diff --git a/tests/compiler/dart2js/rti/data/async_foreach_nonasync.dart b/tests/compiler/dart2js/rti/data/async_foreach_nonasync.dart
index 7c27624..208a51d 100644
--- a/tests/compiler/dart2js/rti/data/async_foreach_nonasync.dart
+++ b/tests/compiler/dart2js/rti/data/async_foreach_nonasync.dart
@@ -4,16 +4,16 @@
// @dart = 2.7
-/*strong.class: Class:direct,explicit=[Class.T],implicit=[Class.T],needsArgs*/
-/*omit.class: Class:*/
+/*spec:nnbd-off.class: Class:direct,explicit=[Class.T],implicit=[Class.T],needsArgs*/
+/*prod:nnbd-off.class: Class:*/
class Class<T> {
method() {
var list = <T>[];
// If any method was `async`, this would have triggered the need for type
// arguments on `Class`. See the 'async_foreach.dart' test.
list.forEach(
- /*strong.needsSignature*/
- /*omit.*/
+ /*spec:nnbd-off.needsSignature*/
+ /*prod:nnbd-off.*/
(x) => print(x));
}
}
diff --git a/tests/compiler/dart2js/rti/data/async_local.dart b/tests/compiler/dart2js/rti/data/async_local.dart
index 14bd0d2..a402273 100644
--- a/tests/compiler/dart2js/rti/data/async_local.dart
+++ b/tests/compiler/dart2js/rti/data/async_local.dart
@@ -12,8 +12,8 @@
// This happens because the closure is thought as possibly going to the
// async.errorHandler callback.
- /*strong.needsSignature*/
- /*omit.needsSignature*/
+ /*spec:nnbd-off.needsSignature*/
+ /*prod:nnbd-off.needsSignature*/
local(object, stacktrace) => null;
return local;
diff --git a/tests/compiler/dart2js/rti/data/async_local_nonasync.dart b/tests/compiler/dart2js/rti/data/async_local_nonasync.dart
index e07c33e7..350559d 100644
--- a/tests/compiler/dart2js/rti/data/async_local_nonasync.dart
+++ b/tests/compiler/dart2js/rti/data/async_local_nonasync.dart
@@ -8,8 +8,8 @@
// If any method was `async`, this would have triggered the need for the
// signature on this closure. See the 'async_local.dart' test.
- /*strong.*/
- /*omit.*/
+ /*spec:nnbd-off.*/
+ /*prod:nnbd-off.*/
local(object, stacktrace) => null;
return local;
diff --git a/tests/compiler/dart2js/rti/data/async_local_typed.dart b/tests/compiler/dart2js/rti/data/async_local_typed.dart
index 5154e91..3ef5a62 100644
--- a/tests/compiler/dart2js/rti/data/async_local_typed.dart
+++ b/tests/compiler/dart2js/rti/data/async_local_typed.dart
@@ -4,8 +4,8 @@
// @dart = 2.7
-/*strong.class: Class:explicit=[Class<int>],needsArgs*/
-/*omit.class: Class:*/
+/*spec:nnbd-off.class: Class:explicit=[Class<int>],needsArgs*/
+/*prod:nnbd-off.class: Class:*/
class Class<T> {}
main() async {
@@ -14,8 +14,8 @@
// `dynamic Function(dynamic, Class<int>)`, is not a potential subtype and
// therefore doesn't need its signature.
- /*strong.needsSignature*/
- /*omit.*/
+ /*spec:nnbd-off.needsSignature*/
+ /*prod:nnbd-off.*/
local(object, Class<int> stacktrace) => null;
return local;
diff --git a/tests/compiler/dart2js/rti/data/call_typed_generic.dart b/tests/compiler/dart2js/rti/data/call_typed_generic.dart
index 3cf8ad8..2dbf94e 100644
--- a/tests/compiler/dart2js/rti/data/call_typed_generic.dart
+++ b/tests/compiler/dart2js/rti/data/call_typed_generic.dart
@@ -6,11 +6,11 @@
import 'package:expect/expect.dart';
-/*strong.class: A:direct,explicit=[A.T],needsArgs*/
-/*omit.class: A:*/
+/*spec:nnbd-off.class: A:direct,explicit=[A.T],needsArgs*/
+/*prod:nnbd-off.class: A:*/
class A<T> {
- /*strong.member: A.call:*/
- /*omit.member: A.call:*/
+ /*spec:nnbd-off.member: A.call:*/
+ /*prod:nnbd-off.member: A.call:*/
call(T t) {}
}
diff --git a/tests/compiler/dart2js/rti/data/closure.dart b/tests/compiler/dart2js/rti/data/closure.dart
index 4804c14..ab166f5 100644
--- a/tests/compiler/dart2js/rti/data/closure.dart
+++ b/tests/compiler/dart2js/rti/data/closure.dart
@@ -4,8 +4,8 @@
// @dart = 2.7
-/*omit.class: A:needsArgs*/
-/*strong.class: A:direct,explicit=[A.T],needsArgs*/
+/*prod:nnbd-off.class: A:needsArgs*/
+/*spec:nnbd-off.class: A:direct,explicit=[A.T],needsArgs*/
class A<T> {
m() {
return /*needsSignature*/ (T t) {};
@@ -16,8 +16,8 @@
// TODO(johnniwinther): Optimize local function type signature need.
return
- /*strong.needsSignature*/
- /*omit.needsSignature*/
+ /*spec:nnbd-off.needsSignature*/
+ /*prod:nnbd-off.needsSignature*/
(int t) {};
}
}
diff --git a/tests/compiler/dart2js/rti/data/closure_generic_unneeded.dart b/tests/compiler/dart2js/rti/data/closure_generic_unneeded.dart
index 6fd577d..229f8f7 100644
--- a/tests/compiler/dart2js/rti/data/closure_generic_unneeded.dart
+++ b/tests/compiler/dart2js/rti/data/closure_generic_unneeded.dart
@@ -4,8 +4,8 @@
// @dart = 2.7
-/*omit.class: A:*/
-/*strong.class: A:direct,explicit=[A.T],needsArgs*/
+/*prod:nnbd-off.class: A:*/
+/*spec:nnbd-off.class: A:direct,explicit=[A.T],needsArgs*/
class A<T> {
@pragma('dart2js:noInline')
m() {
diff --git a/tests/compiler/dart2js/rti/data/closure_unneeded.dart b/tests/compiler/dart2js/rti/data/closure_unneeded.dart
index 6fd577d..229f8f7 100644
--- a/tests/compiler/dart2js/rti/data/closure_unneeded.dart
+++ b/tests/compiler/dart2js/rti/data/closure_unneeded.dart
@@ -4,8 +4,8 @@
// @dart = 2.7
-/*omit.class: A:*/
-/*strong.class: A:direct,explicit=[A.T],needsArgs*/
+/*prod:nnbd-off.class: A:*/
+/*spec:nnbd-off.class: A:direct,explicit=[A.T],needsArgs*/
class A<T> {
@pragma('dart2js:noInline')
m() {
diff --git a/tests/compiler/dart2js/rti/data/dynamic_is2.dart b/tests/compiler/dart2js/rti/data/dynamic_is2.dart
index 09f291b..5018f3a 100644
--- a/tests/compiler/dart2js/rti/data/dynamic_is2.dart
+++ b/tests/compiler/dart2js/rti/data/dynamic_is2.dart
@@ -4,8 +4,8 @@
// @dart = 2.7
-/*omit.class: A:*/
-/*strong.class: A:explicit=[A]*/
+/*prod:nnbd-off.class: A:*/
+/*spec:nnbd-off.class: A:explicit=[A]*/
class A {
/*member: A.instanceMethod:deps=[B.instanceMethod],direct,explicit=[instanceMethod.T],needsArgs,selectors=[Selector(call, instanceMethod, arity=1, types=1)]*/
instanceMethod<T>(t) => t is T;
diff --git a/tests/compiler/dart2js/rti/data/dynamic_not2.dart b/tests/compiler/dart2js/rti/data/dynamic_not2.dart
index c8f9f6e..83b7dda 100644
--- a/tests/compiler/dart2js/rti/data/dynamic_not2.dart
+++ b/tests/compiler/dart2js/rti/data/dynamic_not2.dart
@@ -4,7 +4,7 @@
// @dart = 2.7
-/*strong.class: A:explicit=[A]*/
+/*spec:nnbd-off.class: A:explicit=[A]*/
class A {
/*member: A.instanceMethod:deps=[B.instanceMethod]*/
instanceMethod<T>(t) => t;
diff --git a/tests/compiler/dart2js/rti/data/dynamic_tear_off3.dart b/tests/compiler/dart2js/rti/data/dynamic_tear_off3.dart
index 74625dd..666f0f9 100644
--- a/tests/compiler/dart2js/rti/data/dynamic_tear_off3.dart
+++ b/tests/compiler/dart2js/rti/data/dynamic_tear_off3.dart
@@ -4,8 +4,8 @@
// @dart = 2.7
-/*omit.class: A:*/
-/*strong.class: A:explicit=[A]*/
+/*prod:nnbd-off.class: A:*/
+/*spec:nnbd-off.class: A:explicit=[A]*/
class A {
/*member: A.instanceMethod:deps=[staticMethod],direct,explicit=[instanceMethod.T],needsArgs,selectors=[Selector(call, instanceMethod, arity=1, types=1)]*/
instanceMethod<T>(t) => t is T;
diff --git a/tests/compiler/dart2js/rti/data/dynamic_type_literal2.dart b/tests/compiler/dart2js/rti/data/dynamic_type_literal2.dart
index 7bf6ce1..8812e53 100644
--- a/tests/compiler/dart2js/rti/data/dynamic_type_literal2.dart
+++ b/tests/compiler/dart2js/rti/data/dynamic_type_literal2.dart
@@ -4,7 +4,7 @@
// @dart = 2.7
-/*strong.class: A:explicit=[A]*/
+/*spec:nnbd-off.class: A:explicit=[A]*/
class A {
/*member: A.instanceMethod:deps=[B.instanceMethod],exp,needsArgs,selectors=[Selector(call, instanceMethod, arity=0, types=1)]*/
instanceMethod<T>() => T;
diff --git a/tests/compiler/dart2js/rti/data/explicit_as.dart b/tests/compiler/dart2js/rti/data/explicit_as.dart
index 8bb7f30..439b1a3 100644
--- a/tests/compiler/dart2js/rti/data/explicit_as.dart
+++ b/tests/compiler/dart2js/rti/data/explicit_as.dart
@@ -4,8 +4,8 @@
// @dart = 2.7
-/*strong.class: C:direct,explicit=[C.T,C<String>],needsArgs*/
-/*omit.class: C:*/
+/*spec:nnbd-off.class: C:direct,explicit=[C.T,C<String>],needsArgs*/
+/*prod:nnbd-off.class: C:*/
class C<T> {
T field;
}
diff --git a/tests/compiler/dart2js/rti/data/function_subtype_local5.dart b/tests/compiler/dart2js/rti/data/function_subtype_local5.dart
index 8d429b8..e45aa6c 100644
--- a/tests/compiler/dart2js/rti/data/function_subtype_local5.dart
+++ b/tests/compiler/dart2js/rti/data/function_subtype_local5.dart
@@ -21,12 +21,12 @@
void test(String nameOfT, bool expectedResult) {
// TODO(johnniwinther): Optimize local function type signature need.
- /*strong.needsSignature*/
- /*omit.needsSignature*/
+ /*spec:nnbd-off.needsSignature*/
+ /*prod:nnbd-off.needsSignature*/
int foo(bool a, [String b]) => null;
- /*strong.needsSignature*/
- /*omit.needsSignature*/
+ /*spec:nnbd-off.needsSignature*/
+ /*prod:nnbd-off.needsSignature*/
int baz(bool a, {String b}) => null;
Expect.equals(expectedResult, foo is Foo<T>, 'foo is Foo<$nameOfT>');
diff --git a/tests/compiler/dart2js/rti/data/generic_bounds.dart b/tests/compiler/dart2js/rti/data/generic_bounds.dart
index dcfdfbc..d87e5fd 100644
--- a/tests/compiler/dart2js/rti/data/generic_bounds.dart
+++ b/tests/compiler/dart2js/rti/data/generic_bounds.dart
@@ -6,46 +6,46 @@
import 'package:expect/expect.dart';
-/*strong.class: Class1a:explicit=[Class1a]*/
+/*spec:nnbd-off.class: Class1a:explicit=[Class1a]*/
class Class1a {}
class Class1b extends Class1a {}
-/*strong.class: Class2a:explicit=[Class2a<num>],needsArgs*/
+/*spec:nnbd-off.class: Class2a:explicit=[Class2a<num>],needsArgs*/
class Class2a<T> {}
class Class2b<T> extends Class2a<T> {}
-/*strong.member: method1:needsArgs,selectors=[Selector(call, call, arity=0, types=1)]*/
+/*spec:nnbd-off.member: method1:needsArgs,selectors=[Selector(call, call, arity=0, types=1)]*/
method1<T extends Class1a>() => null;
-/*strong.member: method2:needsArgs,selectors=[Selector(call, call, arity=0, types=1)]*/
+/*spec:nnbd-off.member: method2:needsArgs,selectors=[Selector(call, call, arity=0, types=1)]*/
method2<T extends Class2a<num>>() => null;
method3<T>() => null;
class Class3 {
- /*strong.member: Class3.method4:needsArgs,selectors=[Selector(call, method4, arity=0, types=1)]*/
+ /*spec:nnbd-off.member: Class3.method4:needsArgs,selectors=[Selector(call, method4, arity=0, types=1)]*/
method4<T extends Class1a>() => null;
- /*strong.member: Class3.method5:needsArgs,selectors=[Selector(call, method5, arity=0, types=1)]*/
+ /*spec:nnbd-off.member: Class3.method5:needsArgs,selectors=[Selector(call, method5, arity=0, types=1)]*/
method5<T extends Class2a<num>>() => null;
method6<T>() => null;
}
-/*strong.class: Class4:explicit=[Class4]*/
+/*spec:nnbd-off.class: Class4:explicit=[Class4]*/
class Class4 {}
-/*strong.member: method10:needsArgs*/
+/*spec:nnbd-off.member: method10:needsArgs*/
method10<T extends Class4>() => null;
main() {
- /*strong.needsArgs,selectors=[Selector(call, call, arity=0, types=1)]*/
- /*omit.*/method7<T extends Class1a>() => null;
+ /*spec:nnbd-off.needsArgs,selectors=[Selector(call, call, arity=0, types=1)]*/
+ /*prod:nnbd-off.*/method7<T extends Class1a>() => null;
- /*strong.needsArgs,selectors=[Selector(call, call, arity=0, types=1)]*/
- /*omit.*/method8<T extends Class2a<num>>() => null;
+ /*spec:nnbd-off.needsArgs,selectors=[Selector(call, call, arity=0, types=1)]*/
+ /*prod:nnbd-off.*/method8<T extends Class2a<num>>() => null;
/**/
method9<T>() => null;
diff --git a/tests/compiler/dart2js/rti/data/generic_class_is2.dart b/tests/compiler/dart2js/rti/data/generic_class_is2.dart
index 1f60af6..4801a9b 100644
--- a/tests/compiler/dart2js/rti/data/generic_class_is2.dart
+++ b/tests/compiler/dart2js/rti/data/generic_class_is2.dart
@@ -9,8 +9,8 @@
/*class: A:implicit=[List<A<C2>>,List<A<C>>]*/
class A<T> {}
-/*omit.class: A1:*/
-/*strong.class: A1:implicit=[A1]*/
+/*prod:nnbd-off.class: A1:*/
+/*spec:nnbd-off.class: A1:implicit=[A1]*/
class A1 implements A<C1> {}
/*class: B:direct,explicit=[B.T],needsArgs*/
diff --git a/tests/compiler/dart2js/rti/data/generic_creation.dart b/tests/compiler/dart2js/rti/data/generic_creation.dart
index d0a90fa..a2b5519 100644
--- a/tests/compiler/dart2js/rti/data/generic_creation.dart
+++ b/tests/compiler/dart2js/rti/data/generic_creation.dart
@@ -8,44 +8,44 @@
/*class: A:needsArgs*/
-/*strong.member: A.:*/
-/*omit.member: A.:*/
+/*spec:nnbd-off.member: A.:*/
+/*prod:nnbd-off.member: A.:*/
class A<X, Y, Z> {
- /*strong.member: A.shift:*/
- /*omit.member: A.shift:*/
+ /*spec:nnbd-off.member: A.shift:*/
+ /*prod:nnbd-off.member: A.shift:*/
shift() => new A<Z, X, Y>();
- /*strong.member: A.swap:*/
- /*omit.member: A.swap:*/
+ /*spec:nnbd-off.member: A.swap:*/
+ /*prod:nnbd-off.member: A.swap:*/
swap() => new A<Z, Y, X>();
- /*strong.member: A.first:*/
- /*omit.member: A.first:*/
+ /*spec:nnbd-off.member: A.first:*/
+ /*prod:nnbd-off.member: A.first:*/
first() => new A<X, X, X>();
- /*strong.member: A.last:*/
- /*omit.member: A.last:*/
+ /*spec:nnbd-off.member: A.last:*/
+ /*prod:nnbd-off.member: A.last:*/
last() => new A<Z, Z, Z>();
- /*strong.member: A.wrap:*/
- /*omit.member: A.wrap:*/
+ /*spec:nnbd-off.member: A.wrap:*/
+ /*prod:nnbd-off.member: A.wrap:*/
wrap() => new A<A<X, X, X>, A<Y, Y, Y>, A<Z, Z, Z>>();
}
-/*strong.member: B.:*/
-/*omit.member: B.:*/
+/*spec:nnbd-off.member: B.:*/
+/*prod:nnbd-off.member: B.:*/
class B extends A<U, V, W> {}
/*class: C:needsArgs*/
-/*strong.member: C.:*/
-/*omit.member: C.:*/
+/*spec:nnbd-off.member: C.:*/
+/*prod:nnbd-off.member: C.:*/
class C<T> extends A<U, T, W> {}
/*class: D:needsArgs*/
-/*strong.member: D.:*/
-/*omit.member: D.:*/
+/*spec:nnbd-off.member: D.:*/
+/*prod:nnbd-off.member: D.:*/
class D<X, Y, Z> extends A<Y, Z, X> {}
class U {}
@@ -54,12 +54,12 @@
class W {}
-/*strong.member: sameType:*/
-/*omit.member: sameType:*/
+/*spec:nnbd-off.member: sameType:*/
+/*prod:nnbd-off.member: sameType:*/
sameType(a, b) => Expect.equals(a.runtimeType, b.runtimeType);
-/*strong.member: main:*/
-/*omit.member: main:*/
+/*spec:nnbd-off.member: main:*/
+/*prod:nnbd-off.member: main:*/
main() {
A a = new A<U, V, W>();
sameType(new A<W, U, V>(), a.shift());
diff --git a/tests/compiler/dart2js/rti/data/generic_method_instantiate.dart b/tests/compiler/dart2js/rti/data/generic_method_instantiate.dart
index 3599e85..1b5c9bf 100644
--- a/tests/compiler/dart2js/rti/data/generic_method_instantiate.dart
+++ b/tests/compiler/dart2js/rti/data/generic_method_instantiate.dart
@@ -10,8 +10,8 @@
/*class: B:deps=[method],explicit=[B<A>],needsArgs*/
class B<T> {}
-/*strong.member: method:needsArgs*/
-/*omit.member: method:needsArgs*/
+/*spec:nnbd-off.member: method:needsArgs*/
+/*prod:nnbd-off.member: method:needsArgs*/
method<T>() => new B<T>();
main() {
diff --git a/tests/compiler/dart2js/rti/data/generic_method_is.dart b/tests/compiler/dart2js/rti/data/generic_method_is.dart
index 8f24a5d..53bf8c4 100644
--- a/tests/compiler/dart2js/rti/data/generic_method_is.dart
+++ b/tests/compiler/dart2js/rti/data/generic_method_is.dart
@@ -4,8 +4,8 @@
// @dart = 2.7
-/*strong.member: method:direct,explicit=[method.T],needsArgs*/
-/*omit.member: method:direct,explicit=[method.T],needsArgs*/
+/*spec:nnbd-off.member: method:direct,explicit=[method.T],needsArgs*/
+/*prod:nnbd-off.member: method:direct,explicit=[method.T],needsArgs*/
method<T>(T t) => t is T;
main() {
diff --git a/tests/compiler/dart2js/rti/data/generic_method_is2.dart b/tests/compiler/dart2js/rti/data/generic_method_is2.dart
index de364f3..590ae1b 100644
--- a/tests/compiler/dart2js/rti/data/generic_method_is2.dart
+++ b/tests/compiler/dart2js/rti/data/generic_method_is2.dart
@@ -7,19 +7,19 @@
/*class: A1:implicit=[A1]*/
class A1 {}
-/*strong.class: A2:implicit=[A2]*/
+/*spec:nnbd-off.class: A2:implicit=[A2]*/
class A2 {}
/*class: B1:implicit=[B1]*/
class B1 {}
-/*strong.class: B2:implicit=[B2]*/
+/*spec:nnbd-off.class: B2:implicit=[B2]*/
class B2 {}
/*class: C1:implicit=[C1]*/
class C1 {}
-/*strong.class: C2:implicit=[C2]*/
+/*spec:nnbd-off.class: C2:implicit=[C2]*/
class C2 {}
/*class: C3:implicit=[C3]*/
@@ -28,19 +28,19 @@
/*class: D1:implicit=[D1]*/
class D1 {}
-/*strong.class: D2:implicit=[D2]*/
+/*spec:nnbd-off.class: D2:implicit=[D2]*/
class D2 {}
/*class: E1:implicit=[E1]*/
class E1 {}
-/*strong.class: E2:implicit=[E2]*/
+/*spec:nnbd-off.class: E2:implicit=[E2]*/
class E2 {}
/*class: F1:implicit=[F1]*/
class F1 {}
-/*strong.class: F2:implicit=[F2]*/
+/*spec:nnbd-off.class: F2:implicit=[F2]*/
class F2 {}
/*class: F3:implicit=[F3]*/
@@ -50,7 +50,7 @@
// Calls to this imply a check of the passed type arguments.
bool topLevelMethod1<T>(T t, {a1}) => t is T;
-/*strong.member: topLevelMethod2:direct,explicit=[topLevelMethod2.T],needsArgs,selectors=[Selector(call, call, arity=2, named=[a2], types=1)]*/
+/*spec:nnbd-off.member: topLevelMethod2:direct,explicit=[topLevelMethod2.T],needsArgs,selectors=[Selector(call, call, arity=2, named=[a2], types=1)]*/
// Calls to this does _not_ imply a check of the passed type arguments.
T topLevelMethod2<T>(T t, {a2}) => t;
@@ -59,7 +59,7 @@
// Calls to this imply a check of the passed type arguments.
bool instanceMethod1<S>(S s, {b1}) => s is S;
- /*strong.member: Class.instanceMethod2:direct,explicit=[instanceMethod2.S],needsArgs,selectors=[Selector(call, call, arity=2, named=[b2], types=1),Selector(call, instanceMethod2, arity=2, named=[b2], types=1)]*/
+ /*spec:nnbd-off.member: Class.instanceMethod2:direct,explicit=[instanceMethod2.S],needsArgs,selectors=[Selector(call, call, arity=2, named=[b2], types=1),Selector(call, instanceMethod2, arity=2, named=[b2], types=1)]*/
// Calls to this does _not_ imply a check of the passed type arguments.
S instanceMethod2<S>(S s, {b2}) => s;
}
@@ -70,13 +70,13 @@
bool localFunction1<U>(U u, {c1}) => u is U;
// Calls to this does _not_ imply a check of the passed type arguments.
- /*strong.direct,explicit=[localFunction2.U],needsArgs,selectors=[Selector(call, call, arity=2, named=[c2], types=1)]*/
+ /*spec:nnbd-off.direct,explicit=[localFunction2.U],needsArgs,selectors=[Selector(call, call, arity=2, named=[c2], types=1)]*/
U localFunction2<U>(U u, {c2}) => u;
// Calls to this does _not_ imply a check of the passed type arguments. A
// call to the .call function on this will, though, since it has the same
// signature as [localFunction1] which needs its type arguments.
- /*strong.direct,explicit=[localFunction3.U],needsArgs,selectors=[Selector(call, call, arity=2, named=[c1], types=1)]*/
+ /*spec:nnbd-off.direct,explicit=[localFunction3.U],needsArgs,selectors=[Selector(call, call, arity=2, named=[c1], types=1)]*/
localFunction3<U>(U u, {c1}) => u;
var c = new Class();
diff --git a/tests/compiler/dart2js/rti/data/generic_methods_dynamic_05.dart b/tests/compiler/dart2js/rti/data/generic_methods_dynamic_05.dart
index 13c5edd..f32f4e6 100644
--- a/tests/compiler/dart2js/rti/data/generic_methods_dynamic_05.dart
+++ b/tests/compiler/dart2js/rti/data/generic_methods_dynamic_05.dart
@@ -6,22 +6,22 @@
// Test derived from language_2/generic_methods_dynamic_test/05
-/*omit.class: global#JSArray:deps=[List],explicit=[JSArray],needsArgs*/
-/*strong.class: global#JSArray:deps=[ArrayIterator,List],direct,explicit=[JSArray,JSArray.E,JSArray<ArrayIterator.E>],implicit=[JSArray.E],needsArgs*/
-/*strong.class: global#List:deps=[C.bar],explicit=[List,List<B>,List<String>],indirect,needsArgs*/
+/*prod:nnbd-off.class: global#JSArray:deps=[List],explicit=[JSArray],needsArgs*/
+/*spec:nnbd-off.class: global#JSArray:deps=[ArrayIterator,List],direct,explicit=[JSArray,JSArray.E,JSArray<ArrayIterator.E>],implicit=[JSArray.E],needsArgs*/
+/*spec:nnbd-off.class: global#List:deps=[C.bar],explicit=[List,List<B>,List<String>],indirect,needsArgs*/
-/*omit.class: global#List:deps=[C.bar],explicit=[List,List<B>],needsArgs*/
+/*prod:nnbd-off.class: global#List:deps=[C.bar],explicit=[List,List<B>],needsArgs*/
import "package:expect/expect.dart";
class A {}
-/*strong.class: B:explicit=[List<B>],implicit=[B]*/
-/*omit.class: B:explicit=[List<B>]*/
+/*spec:nnbd-off.class: B:explicit=[List<B>],implicit=[B]*/
+/*prod:nnbd-off.class: B:explicit=[List<B>]*/
class B {}
class C {
- /*strong.member: C.bar:direct,explicit=[Iterable<bar.T>],implicit=[bar.T],needsArgs,selectors=[Selector(call, bar, arity=1, types=1)]*/
- /*omit.member: C.bar:needsArgs,selectors=[Selector(call, bar, arity=1, types=1)]*/
+ /*spec:nnbd-off.member: C.bar:direct,explicit=[Iterable<bar.T>],implicit=[bar.T],needsArgs,selectors=[Selector(call, bar, arity=1, types=1)]*/
+ /*prod:nnbd-off.member: C.bar:needsArgs,selectors=[Selector(call, bar, arity=1, types=1)]*/
List<T> bar<T>(Iterable<T> t) => <T>[t.first];
}
diff --git a/tests/compiler/dart2js/rti/data/generic_methods_dynamic_05a.dart b/tests/compiler/dart2js/rti/data/generic_methods_dynamic_05a.dart
index e0575e5..b780758 100644
--- a/tests/compiler/dart2js/rti/data/generic_methods_dynamic_05a.dart
+++ b/tests/compiler/dart2js/rti/data/generic_methods_dynamic_05a.dart
@@ -8,21 +8,21 @@
import "package:expect/expect.dart";
-/*omit.class: A:deps=[C.bar],explicit=[A<B>],needsArgs*/
-/*strong.class: A:deps=[C.bar],direct,explicit=[A.T,A<B>,A<bar.T>],needsArgs*/
+/*prod:nnbd-off.class: A:deps=[C.bar],explicit=[A<B>],needsArgs*/
+/*spec:nnbd-off.class: A:deps=[C.bar],direct,explicit=[A.T,A<B>,A<bar.T>],needsArgs*/
class A<T> {
final T field;
A(this.field);
}
-/*omit.class: B:explicit=[A<B>]*/
-/*strong.class: B:explicit=[A<B>],implicit=[B]*/
+/*prod:nnbd-off.class: B:explicit=[A<B>]*/
+/*spec:nnbd-off.class: B:explicit=[A<B>],implicit=[B]*/
class B {}
class C {
- /*omit.member: C.bar:needsArgs,selectors=[Selector(call, bar, arity=1, types=1)]*/
- /*strong.member: C.bar:explicit=[A<bar.T>],implicit=[bar.T],indirect,needsArgs,selectors=[Selector(call, bar, arity=1, types=1)]*/
+ /*prod:nnbd-off.member: C.bar:needsArgs,selectors=[Selector(call, bar, arity=1, types=1)]*/
+ /*spec:nnbd-off.member: C.bar:explicit=[A<bar.T>],implicit=[bar.T],indirect,needsArgs,selectors=[Selector(call, bar, arity=1, types=1)]*/
A<T> bar<T>(A<T> t) => new A<T>(t.field);
}
diff --git a/tests/compiler/dart2js/rti/data/implicit_as.dart b/tests/compiler/dart2js/rti/data/implicit_as.dart
index 6c76287..95770b8 100644
--- a/tests/compiler/dart2js/rti/data/implicit_as.dart
+++ b/tests/compiler/dart2js/rti/data/implicit_as.dart
@@ -4,8 +4,8 @@
// @dart = 2.7
-/*strong.class: C:direct,explicit=[C.T,C<String>],needsArgs*/
-/*omit.class: C:*/
+/*spec:nnbd-off.class: C:direct,explicit=[C.T,C<String>],needsArgs*/
+/*prod:nnbd-off.class: C:*/
class C<T> {
T field;
}
diff --git a/tests/compiler/dart2js/rti/data/indirect_through_static.dart b/tests/compiler/dart2js/rti/data/indirect_through_static.dart
index f1cc990..3dd9a7c 100644
--- a/tests/compiler/dart2js/rti/data/indirect_through_static.dart
+++ b/tests/compiler/dart2js/rti/data/indirect_through_static.dart
@@ -4,19 +4,19 @@
// @dart = 2.7
-/*strong.class: A:implicit=[A]*/
-/*omit.class: A:implicit=[A]*/
+/*spec:nnbd-off.class: A:implicit=[A]*/
+/*prod:nnbd-off.class: A:implicit=[A]*/
abstract class A {}
class B implements A {}
-/*strong.class: C:
+/*spec:nnbd-off.class: C:
deps=[lookup],
explicit=[C<lookup.T>,Map<String,C>],
implicit=[C],
needsArgs
*/
-/*omit.class: C:
+/*prod:nnbd-off.class: C:
deps=[lookup],explicit=[C<lookup.T>],
needsArgs
*/
@@ -28,8 +28,8 @@
map['x'] = new C<B>();
}
-/*strong.member: lookup:direct,explicit=[C<lookup.T>],needsArgs*/
-/*omit.member: lookup:direct,explicit=[C<lookup.T>],needsArgs*/
+/*spec:nnbd-off.member: lookup:direct,explicit=[C<lookup.T>],needsArgs*/
+/*prod:nnbd-off.member: lookup:direct,explicit=[C<lookup.T>],needsArgs*/
C<T> lookup<T>(String key) {
final value = map[key];
if (value != null && value is C<T>) {
diff --git a/tests/compiler/dart2js/rti/data/instantiation1.dart b/tests/compiler/dart2js/rti/data/instantiation1.dart
index bd638dc..3ed0070 100644
--- a/tests/compiler/dart2js/rti/data/instantiation1.dart
+++ b/tests/compiler/dart2js/rti/data/instantiation1.dart
@@ -4,13 +4,13 @@
// @dart = 2.7
-/*strong.member: f:deps=[B],direct,explicit=[f.T],needsArgs,needsInst=[<B.S>]*/
-/*omit.member: f:deps=[B]*/
+/*spec:nnbd-off.member: f:deps=[B],direct,explicit=[f.T],needsArgs,needsInst=[<B.S>]*/
+/*prod:nnbd-off.member: f:deps=[B]*/
int f<T>(T a) => null;
typedef int F<R>(R a);
-/*strong.class: B:explicit=[int Function(B.S)],indirect,needsArgs*/
+/*spec:nnbd-off.class: B:explicit=[int Function(B.S)],indirect,needsArgs*/
class B<S> {
F<S> c;
diff --git a/tests/compiler/dart2js/rti/data/instantiation2.dart b/tests/compiler/dart2js/rti/data/instantiation2.dart
index 8c040bc..ee21996 100644
--- a/tests/compiler/dart2js/rti/data/instantiation2.dart
+++ b/tests/compiler/dart2js/rti/data/instantiation2.dart
@@ -4,14 +4,14 @@
// @dart = 2.7
-/*strong.member: f:deps=[B],direct,explicit=[f.T],needsArgs,needsInst=[<B.S>]*/
-/*omit.member: f:deps=[B],direct,explicit=[f.T],needsArgs,needsInst=[<B.S>]*/
+/*spec:nnbd-off.member: f:deps=[B],direct,explicit=[f.T],needsArgs,needsInst=[<B.S>]*/
+/*prod:nnbd-off.member: f:deps=[B],direct,explicit=[f.T],needsArgs,needsInst=[<B.S>]*/
bool f<T>(T a) => a is T;
typedef bool F<R>(R a);
-/*strong.class: B:explicit=[bool Function(B.S)],indirect,needsArgs*/
-/*omit.class: B:indirect,needsArgs*/
+/*spec:nnbd-off.class: B:explicit=[bool Function(B.S)],indirect,needsArgs*/
+/*prod:nnbd-off.class: B:indirect,needsArgs*/
class B<S> {
F<S> c;
diff --git a/tests/compiler/dart2js/rti/data/instantiation3.dart b/tests/compiler/dart2js/rti/data/instantiation3.dart
index 19899d9..67bfc44 100644
--- a/tests/compiler/dart2js/rti/data/instantiation3.dart
+++ b/tests/compiler/dart2js/rti/data/instantiation3.dart
@@ -4,13 +4,13 @@
// @dart = 2.7
-/*strong.member: f:deps=[B],direct,explicit=[f.T],needsArgs,needsInst=[<B.S>]*/
-/*omit.member: f:deps=[B]*/
+/*spec:nnbd-off.member: f:deps=[B],direct,explicit=[f.T],needsArgs,needsInst=[<B.S>]*/
+/*prod:nnbd-off.member: f:deps=[B]*/
int f<T>(T a) => null;
typedef int F<R>(R a);
-/*strong.class: B:direct,explicit=[int Function(B.S)],needsArgs*/
+/*spec:nnbd-off.class: B:direct,explicit=[int Function(B.S)],needsArgs*/
class B<S> {
F<S> c;
diff --git a/tests/compiler/dart2js/rti/data/instantiation4.dart b/tests/compiler/dart2js/rti/data/instantiation4.dart
index c40ca9c..57616a0 100644
--- a/tests/compiler/dart2js/rti/data/instantiation4.dart
+++ b/tests/compiler/dart2js/rti/data/instantiation4.dart
@@ -4,14 +4,14 @@
// @dart = 2.7
-/*strong.member: f:deps=[B],direct,explicit=[f.T],needsArgs,needsInst=[<B.S>]*/
-/*omit.member: f:deps=[B],direct,explicit=[f.T],needsArgs,needsInst=[<B.S>]*/
+/*spec:nnbd-off.member: f:deps=[B],direct,explicit=[f.T],needsArgs,needsInst=[<B.S>]*/
+/*prod:nnbd-off.member: f:deps=[B],direct,explicit=[f.T],needsArgs,needsInst=[<B.S>]*/
bool f<T>(T a) => a is T;
typedef bool F<R>(R a);
-/*strong.class: B:direct,explicit=[bool Function(B.S)],needsArgs*/
-/*omit.class: B:indirect,needsArgs*/
+/*spec:nnbd-off.class: B:direct,explicit=[bool Function(B.S)],needsArgs*/
+/*prod:nnbd-off.class: B:indirect,needsArgs*/
class B<S> {
F<S> c;
diff --git a/tests/compiler/dart2js/rti/data/instantiation5.dart b/tests/compiler/dart2js/rti/data/instantiation5.dart
index 8f3fb60..7ffbd29 100644
--- a/tests/compiler/dart2js/rti/data/instantiation5.dart
+++ b/tests/compiler/dart2js/rti/data/instantiation5.dart
@@ -4,13 +4,13 @@
// @dart = 2.7
-/*strong.member: f:deps=[method],direct,explicit=[f.T],needsArgs,needsInst=[<method.S>]*/
-/*omit.member: f:deps=[method]*/
+/*spec:nnbd-off.member: f:deps=[method],direct,explicit=[f.T],needsArgs,needsInst=[<method.S>]*/
+/*prod:nnbd-off.member: f:deps=[method]*/
int f<T>(T a) => null;
typedef int F<R>(R a);
-/*strong.member: method:indirect,needsArgs*/
+/*spec:nnbd-off.member: method:indirect,needsArgs*/
method<S>() {
F<S> c;
diff --git a/tests/compiler/dart2js/rti/data/instantiation6.dart b/tests/compiler/dart2js/rti/data/instantiation6.dart
index 212557f..a2e2c79 100644
--- a/tests/compiler/dart2js/rti/data/instantiation6.dart
+++ b/tests/compiler/dart2js/rti/data/instantiation6.dart
@@ -4,14 +4,14 @@
// @dart = 2.7
-/*strong.member: f:deps=[method],direct,explicit=[f.T],needsArgs,needsInst=[<method.S>]*/
-/*omit.member: f:deps=[method],direct,explicit=[f.T],needsArgs,needsInst=[<method.S>]*/
+/*spec:nnbd-off.member: f:deps=[method],direct,explicit=[f.T],needsArgs,needsInst=[<method.S>]*/
+/*prod:nnbd-off.member: f:deps=[method],direct,explicit=[f.T],needsArgs,needsInst=[<method.S>]*/
bool f<T>(T a) => a is T;
typedef bool F<R>(R a);
-/*strong.member: method:indirect,needsArgs*/
-/*omit.member: method:indirect,needsArgs*/
+/*spec:nnbd-off.member: method:indirect,needsArgs*/
+/*prod:nnbd-off.member: method:indirect,needsArgs*/
method<S>() {
F<S> c;
diff --git a/tests/compiler/dart2js/rti/data/instantiation7.dart b/tests/compiler/dart2js/rti/data/instantiation7.dart
index 2786071..71498ebb 100644
--- a/tests/compiler/dart2js/rti/data/instantiation7.dart
+++ b/tests/compiler/dart2js/rti/data/instantiation7.dart
@@ -4,23 +4,23 @@
// @dart = 2.7
-/*strong.member: f1:deps=[method],direct,explicit=[f1.T],needsArgs,needsInst=[<method.X>]*/
-/*omit.member: f1:deps=[method]*/
+/*spec:nnbd-off.member: f1:deps=[method],direct,explicit=[f1.T],needsArgs,needsInst=[<method.X>]*/
+/*prod:nnbd-off.member: f1:deps=[method]*/
int f1<T>(T a, T b, T c) => null;
-/*strong.member: f2:deps=[method],direct,explicit=[f2.S,f2.T],needsArgs,needsInst=[<method.X,method.Y>]*/
-/*omit.member: f2:deps=[method]*/
+/*spec:nnbd-off.member: f2:deps=[method],direct,explicit=[f2.S,f2.T],needsArgs,needsInst=[<method.X,method.Y>]*/
+/*prod:nnbd-off.member: f2:deps=[method]*/
int f2<T, S>(T a, S b, S c) => null;
-/*strong.member: f3:deps=[method],direct,explicit=[f3.S,f3.T,f3.U],needsArgs,needsInst=[<method.X,method.Y,method.Z>]*/
-/*omit.member: f3:deps=[method]*/
+/*spec:nnbd-off.member: f3:deps=[method],direct,explicit=[f3.S,f3.T,f3.U],needsArgs,needsInst=[<method.X,method.Y,method.Z>]*/
+/*prod:nnbd-off.member: f3:deps=[method]*/
int f3<T, S, U>(T a, S b, U c) => null;
typedef int F1<R>(R a, R b, R c);
typedef int F2<R, P>(R a, P b, P c);
typedef int F3<R, P, Q>(R a, P b, Q c);
-/*strong.member: method:indirect,needsArgs*/
+/*spec:nnbd-off.member: method:indirect,needsArgs*/
method<X, Y, Z>() {
F1<X> c1;
F2<X, Y> c2;
diff --git a/tests/compiler/dart2js/rti/data/list_literal.dart b/tests/compiler/dart2js/rti/data/list_literal.dart
index b5caf11..4baa47f 100644
--- a/tests/compiler/dart2js/rti/data/list_literal.dart
+++ b/tests/compiler/dart2js/rti/data/list_literal.dart
@@ -4,11 +4,11 @@
// @dart = 2.7
-/*strong.class: global#List:deps=[Class.m],explicit=[List,List<String>],indirect,needsArgs*/
-/*omit.class: global#List:deps=[Class.m],explicit=[List],indirect,needsArgs*/
+/*spec:nnbd-off.class: global#List:deps=[Class.m],explicit=[List,List<String>],indirect,needsArgs*/
+/*prod:nnbd-off.class: global#List:deps=[Class.m],explicit=[List],indirect,needsArgs*/
-/*strong.class: global#JSArray:deps=[ArrayIterator,List],explicit=[JSArray,JSArray.E,JSArray<ArrayIterator.E>],implicit=[JSArray.E],indirect,needsArgs*/
-/*omit.class: global#JSArray:deps=[List],explicit=[JSArray],implicit=[JSArray.E],indirect,needsArgs*/
+/*spec:nnbd-off.class: global#JSArray:deps=[ArrayIterator,List],explicit=[JSArray,JSArray.E,JSArray<ArrayIterator.E>],implicit=[JSArray.E],indirect,needsArgs*/
+/*prod:nnbd-off.class: global#JSArray:deps=[List],explicit=[JSArray],implicit=[JSArray.E],indirect,needsArgs*/
main() {
var c = new Class();
diff --git a/tests/compiler/dart2js/rti/data/list_to_set.dart b/tests/compiler/dart2js/rti/data/list_to_set.dart
index d5457ee..576528d 100644
--- a/tests/compiler/dart2js/rti/data/list_to_set.dart
+++ b/tests/compiler/dart2js/rti/data/list_to_set.dart
@@ -4,11 +4,11 @@
// @dart = 2.7
-/*strong.class: global#List:deps=[Class],explicit=[List,List<String>],indirect,needsArgs*/
-/*omit.class: global#List:deps=[Class],explicit=[List],indirect,needsArgs*/
+/*spec:nnbd-off.class: global#List:deps=[Class],explicit=[List,List<String>],indirect,needsArgs*/
+/*prod:nnbd-off.class: global#List:deps=[Class],explicit=[List],indirect,needsArgs*/
-/*strong.class: global#JSArray:deps=[ArrayIterator,List],explicit=[JSArray,JSArray.E,JSArray<ArrayIterator.E>],implicit=[JSArray.E],indirect,needsArgs*/
-/*omit.class: global#JSArray:deps=[List],explicit=[JSArray],implicit=[JSArray.E],indirect,needsArgs*/
+/*spec:nnbd-off.class: global#JSArray:deps=[ArrayIterator,List],explicit=[JSArray,JSArray.E,JSArray<ArrayIterator.E>],implicit=[JSArray.E],indirect,needsArgs*/
+/*prod:nnbd-off.class: global#JSArray:deps=[List],explicit=[JSArray],implicit=[JSArray.E],indirect,needsArgs*/
main() {
var c = new Class<int>();
diff --git a/tests/compiler/dart2js/rti/data/local_function_generic.dart b/tests/compiler/dart2js/rti/data/local_function_generic.dart
index 99ea166..c3ca915 100644
--- a/tests/compiler/dart2js/rti/data/local_function_generic.dart
+++ b/tests/compiler/dart2js/rti/data/local_function_generic.dart
@@ -7,8 +7,8 @@
import 'package:expect/expect.dart';
method1() {
- /*strong.direct,explicit=[local.T],needsArgs,needsSignature*/
- /*omit.needsSignature*/
+ /*spec:nnbd-off.direct,explicit=[local.T],needsArgs,needsSignature*/
+ /*prod:nnbd-off.needsSignature*/
T local<T>(T t) => t;
return local;
}
diff --git a/tests/compiler/dart2js/rti/data/local_function_list_literal.dart b/tests/compiler/dart2js/rti/data/local_function_list_literal.dart
index 585ab8b..66de226 100644
--- a/tests/compiler/dart2js/rti/data/local_function_list_literal.dart
+++ b/tests/compiler/dart2js/rti/data/local_function_list_literal.dart
@@ -6,10 +6,10 @@
import 'package:expect/expect.dart';
-/*strong.member: method:implicit=[method.T],indirect,needsArgs*/
-/*omit.member: method:needsArgs*/
-/*strong.class: global#JSArray:deps=[ArrayIterator,List],direct,explicit=[JSArray,JSArray.E,JSArray<ArrayIterator.E>],implicit=[JSArray.E],needsArgs*/
-/*omit.class: global#JSArray:deps=[List],explicit=[JSArray],needsArgs*/
+/*spec:nnbd-off.member: method:implicit=[method.T],indirect,needsArgs*/
+/*prod:nnbd-off.member: method:needsArgs*/
+/*spec:nnbd-off.class: global#JSArray:deps=[ArrayIterator,List],direct,explicit=[JSArray,JSArray.E,JSArray<ArrayIterator.E>],implicit=[JSArray.E],needsArgs*/
+/*prod:nnbd-off.class: global#JSArray:deps=[List],explicit=[JSArray],needsArgs*/
@pragma('dart2js:noInline')
method<T>() {
diff --git a/tests/compiler/dart2js/rti/data/local_function_map_literal.dart b/tests/compiler/dart2js/rti/data/local_function_map_literal.dart
index 2aea2bb..0fed376 100644
--- a/tests/compiler/dart2js/rti/data/local_function_map_literal.dart
+++ b/tests/compiler/dart2js/rti/data/local_function_map_literal.dart
@@ -6,11 +6,11 @@
import 'package:expect/expect.dart';
-/*strong.class: global#LinkedHashMap:deps=[Map],direct,explicit=[LinkedHashMap<LinkedHashMap.K,LinkedHashMap.V>],implicit=[LinkedHashMap.K,LinkedHashMap.V],needsArgs*/
-/*omit.class: global#LinkedHashMap:deps=[Map],needsArgs*/
+/*spec:nnbd-off.class: global#LinkedHashMap:deps=[Map],direct,explicit=[LinkedHashMap<LinkedHashMap.K,LinkedHashMap.V>],implicit=[LinkedHashMap.K,LinkedHashMap.V],needsArgs*/
+/*prod:nnbd-off.class: global#LinkedHashMap:deps=[Map],needsArgs*/
-/*strong.member: method:implicit=[method.T],indirect,needsArgs*/
-/*omit.member: method:needsArgs*/
+/*spec:nnbd-off.member: method:implicit=[method.T],indirect,needsArgs*/
+/*prod:nnbd-off.member: method:needsArgs*/
@pragma('dart2js:noInline')
method<T>() {
return () => <T, int>{};
diff --git a/tests/compiler/dart2js/rti/data/local_function_signature2.dart b/tests/compiler/dart2js/rti/data/local_function_signature2.dart
index 9d38877..48d3161 100644
--- a/tests/compiler/dart2js/rti/data/local_function_signature2.dart
+++ b/tests/compiler/dart2js/rti/data/local_function_signature2.dart
@@ -27,8 +27,8 @@
}
class Class2 {
- /*strong.member: Class2.method4:direct,explicit=[method4.T],needsArgs,selectors=[Selector(call, method4, arity=0, types=1)]*/
- /*omit.member: Class2.method4:needsArgs,selectors=[Selector(call, method4, arity=0, types=1)]*/
+ /*spec:nnbd-off.member: Class2.method4:direct,explicit=[method4.T],needsArgs,selectors=[Selector(call, method4, arity=0, types=1)]*/
+ /*prod:nnbd-off.member: Class2.method4:needsArgs,selectors=[Selector(call, method4, arity=0, types=1)]*/
method4<T>() {
/*needsSignature*/
num local(T n) => null;
@@ -46,8 +46,8 @@
}
class Class4 {
- /*strong.member: Class4.method6:direct,explicit=[method6.T],needsArgs,selectors=[Selector(call, method6, arity=0, types=1)]*/
- /*omit.member: Class4.method6:*/
+ /*spec:nnbd-off.member: Class4.method6:direct,explicit=[method6.T],needsArgs,selectors=[Selector(call, method6, arity=0, types=1)]*/
+ /*prod:nnbd-off.member: Class4.method6:*/
method6<T>() {
/**/
num local(num n, T t) => null;
@@ -55,8 +55,8 @@
}
}
-/*strong.member: method7:direct,explicit=[method7.T],needsArgs*/
-/*omit.member: method7:needsArgs*/
+/*spec:nnbd-off.member: method7:direct,explicit=[method7.T],needsArgs*/
+/*prod:nnbd-off.member: method7:needsArgs*/
method7<T>() {
/*needsSignature*/
num local(T n) => null;
@@ -70,8 +70,8 @@
return local;
}
-/*strong.member: method9:direct,explicit=[method9.T],needsArgs*/
-/*omit.member: method9:*/
+/*spec:nnbd-off.member: method9:direct,explicit=[method9.T],needsArgs*/
+/*prod:nnbd-off.member: method9:*/
method9<T>() {
/**/
num local(num n, T t) => null;
@@ -79,8 +79,8 @@
}
method10() {
- /*strong.direct,explicit=[local.T],needsArgs*/
- /*omit.*/
+ /*spec:nnbd-off.direct,explicit=[local.T],needsArgs*/
+ /*prod:nnbd-off.*/
num local<T>(T n) => null;
return local;
}
@@ -92,8 +92,8 @@
}
method12() {
- /*strong.direct,explicit=[local.T],needsArgs*/
- /*omit.*/
+ /*spec:nnbd-off.direct,explicit=[local.T],needsArgs*/
+ /*prod:nnbd-off.*/
num local<T>(num n, T t) => null;
return local;
}
diff --git a/tests/compiler/dart2js/rti/data/local_function_signatures.dart b/tests/compiler/dart2js/rti/data/local_function_signatures.dart
index f963ae0..2a2b2e9 100644
--- a/tests/compiler/dart2js/rti/data/local_function_signatures.dart
+++ b/tests/compiler/dart2js/rti/data/local_function_signatures.dart
@@ -8,8 +8,8 @@
class Class1 {
method1() {
- /*strong.needsSignature*/
- /*omit.needsSignature*/
+ /*spec:nnbd-off.needsSignature*/
+ /*prod:nnbd-off.needsSignature*/
num local(num n) => null;
return local;
}
@@ -25,8 +25,8 @@
}
}
-/*omit.class: Class2:needsArgs*/
-/*strong.class: Class2:direct,explicit=[Class2.T],needsArgs*/
+/*prod:nnbd-off.class: Class2:needsArgs*/
+/*spec:nnbd-off.class: Class2:direct,explicit=[Class2.T],needsArgs*/
class Class2<T> {
method4() {
/*needsSignature*/
@@ -44,8 +44,8 @@
}
}
-/*omit.class: Class4:*/
-/*strong.class: Class4:direct,explicit=[Class4.T],needsArgs*/
+/*prod:nnbd-off.class: Class4:*/
+/*spec:nnbd-off.class: Class4:direct,explicit=[Class4.T],needsArgs*/
class Class4<T> {
method6() {
/**/
diff --git a/tests/compiler/dart2js/rti/data/local_function_signatures_generic.dart b/tests/compiler/dart2js/rti/data/local_function_signatures_generic.dart
index 0f38f17..1a089c8 100644
--- a/tests/compiler/dart2js/rti/data/local_function_signatures_generic.dart
+++ b/tests/compiler/dart2js/rti/data/local_function_signatures_generic.dart
@@ -27,8 +27,8 @@
}
class Class2 {
- /*strong.member: Class2.method4:direct,explicit=[method4.T],needsArgs,selectors=[Selector(call, method4, arity=0, types=1)]*/
- /*omit.member: Class2.method4:needsArgs,selectors=[Selector(call, method4, arity=0, types=1)]*/
+ /*spec:nnbd-off.member: Class2.method4:direct,explicit=[method4.T],needsArgs,selectors=[Selector(call, method4, arity=0, types=1)]*/
+ /*prod:nnbd-off.member: Class2.method4:needsArgs,selectors=[Selector(call, method4, arity=0, types=1)]*/
method4<T>() {
/*needsSignature*/
num local(T n) => null;
@@ -46,8 +46,8 @@
}
class Class4 {
- /*strong.member: Class4.method6:direct,explicit=[method6.T],needsArgs,selectors=[Selector(call, method6, arity=0, types=1)]*/
- /*omit.member: Class4.method6:*/
+ /*spec:nnbd-off.member: Class4.method6:direct,explicit=[method6.T],needsArgs,selectors=[Selector(call, method6, arity=0, types=1)]*/
+ /*prod:nnbd-off.member: Class4.method6:*/
method6<T>() {
/**/
num local(num n, T t) => null;
@@ -55,8 +55,8 @@
}
}
-/*strong.member: method7:direct,explicit=[method7.T],needsArgs*/
-/*omit.member: method7:needsArgs*/
+/*spec:nnbd-off.member: method7:direct,explicit=[method7.T],needsArgs*/
+/*prod:nnbd-off.member: method7:needsArgs*/
method7<T>() {
/*needsSignature*/
num local(T n) => null;
@@ -70,8 +70,8 @@
return local;
}
-/*strong.member: method9:direct,explicit=[method9.T],needsArgs*/
-/*omit.member: method9:*/
+/*spec:nnbd-off.member: method9:direct,explicit=[method9.T],needsArgs*/
+/*prod:nnbd-off.member: method9:*/
method9<T>() {
/**/
num local(num n, T t) => null;
@@ -79,8 +79,8 @@
}
method10() {
- /*strong.direct,explicit=[local.T],needsArgs,needsInst=[<dynamic>,<num>,<num>],needsSignature*/
- /*omit.needsSignature*/
+ /*spec:nnbd-off.direct,explicit=[local.T],needsArgs,needsInst=[<dynamic>,<num>,<num>],needsSignature*/
+ /*prod:nnbd-off.needsSignature*/
num local<T>(T n) => null;
return local;
}
@@ -92,8 +92,8 @@
}
method12() {
- /*strong.direct,explicit=[local.T],needsArgs,needsInst=[<dynamic>,<num>,<num>]*/
- /*omit.*/
+ /*spec:nnbd-off.direct,explicit=[local.T],needsArgs,needsInst=[<dynamic>,<num>,<num>]*/
+ /*prod:nnbd-off.*/
num local<T>(num n, T t) => null;
return local;
}
@@ -105,8 +105,8 @@
}
num Function(num) method14() {
- /*strong.direct,explicit=[local.T],needsArgs,needsInst=[<dynamic>,<num>,<num>],needsSignature*/
- /*omit.needsSignature*/
+ /*spec:nnbd-off.direct,explicit=[local.T],needsArgs,needsInst=[<dynamic>,<num>,<num>],needsSignature*/
+ /*prod:nnbd-off.needsSignature*/
num local<T>(T n) => null;
return local;
}
diff --git a/tests/compiler/dart2js/rti/data/map_literal.dart b/tests/compiler/dart2js/rti/data/map_literal.dart
index 3472e19..47252cb 100644
--- a/tests/compiler/dart2js/rti/data/map_literal.dart
+++ b/tests/compiler/dart2js/rti/data/map_literal.dart
@@ -4,17 +4,17 @@
// @dart = 2.7
-/*omit.class: global#Map:*/
-/*strong.class: global#Map:explicit=[Map],indirect,needsArgs*/
+/*prod:nnbd-off.class: global#Map:*/
+/*spec:nnbd-off.class: global#Map:explicit=[Map],indirect,needsArgs*/
-/*omit.class: global#LinkedHashMap:deps=[Map]*/
-/*strong.class: global#LinkedHashMap:deps=[Map],direct,explicit=[LinkedHashMap<LinkedHashMap.K,LinkedHashMap.V>],implicit=[LinkedHashMap.K,LinkedHashMap.V],needsArgs*/
+/*prod:nnbd-off.class: global#LinkedHashMap:deps=[Map]*/
+/*spec:nnbd-off.class: global#LinkedHashMap:deps=[Map],direct,explicit=[LinkedHashMap<LinkedHashMap.K,LinkedHashMap.V>],implicit=[LinkedHashMap.K,LinkedHashMap.V],needsArgs*/
-/*omit.class: global#JsLinkedHashMap:deps=[LinkedHashMap]*/
-/*strong.class: global#JsLinkedHashMap:deps=[LinkedHashMap],direct,explicit=[JsLinkedHashMap.K,JsLinkedHashMap.V,void Function(JsLinkedHashMap.K,JsLinkedHashMap.V)],implicit=[JsLinkedHashMap.K,JsLinkedHashMap.V],needsArgs*/
+/*prod:nnbd-off.class: global#JsLinkedHashMap:deps=[LinkedHashMap]*/
+/*spec:nnbd-off.class: global#JsLinkedHashMap:deps=[LinkedHashMap],direct,explicit=[JsLinkedHashMap.K,JsLinkedHashMap.V,void Function(JsLinkedHashMap.K,JsLinkedHashMap.V)],implicit=[JsLinkedHashMap.K,JsLinkedHashMap.V],needsArgs*/
-/*omit.class: global#double:explicit=[double]*/
-/*strong.class: global#double:explicit=[double],implicit=[double]*/
+/*prod:nnbd-off.class: global#double:explicit=[double]*/
+/*spec:nnbd-off.class: global#double:explicit=[double],implicit=[double]*/
/*class: global#JSDouble:*/
diff --git a/tests/compiler/dart2js/rti/data/map_to_set.dart b/tests/compiler/dart2js/rti/data/map_to_set.dart
index 127552a..78dff5e 100644
--- a/tests/compiler/dart2js/rti/data/map_to_set.dart
+++ b/tests/compiler/dart2js/rti/data/map_to_set.dart
@@ -4,17 +4,17 @@
// @dart = 2.7
-/*omit.class: global#Map:deps=[Class],needsArgs*/
-/*strong.class: global#Map:deps=[Class],explicit=[Map],indirect,needsArgs*/
+/*prod:nnbd-off.class: global#Map:deps=[Class],needsArgs*/
+/*spec:nnbd-off.class: global#Map:deps=[Class],explicit=[Map],indirect,needsArgs*/
-/*omit.class: global#LinkedHashMap:deps=[Map],needsArgs*/
-/*strong.class: global#LinkedHashMap:deps=[Map],direct,explicit=[LinkedHashMap<LinkedHashMap.K,LinkedHashMap.V>],implicit=[LinkedHashMap.K,LinkedHashMap.V],needsArgs*/
+/*prod:nnbd-off.class: global#LinkedHashMap:deps=[Map],needsArgs*/
+/*spec:nnbd-off.class: global#LinkedHashMap:deps=[Map],direct,explicit=[LinkedHashMap<LinkedHashMap.K,LinkedHashMap.V>],implicit=[LinkedHashMap.K,LinkedHashMap.V],needsArgs*/
-/*omit.class: global#JsLinkedHashMap:deps=[LinkedHashMap],implicit=[JsLinkedHashMap.K],needsArgs*/
-/*strong.class: global#JsLinkedHashMap:deps=[LinkedHashMap],direct,explicit=[JsLinkedHashMap.K,JsLinkedHashMap.V,void Function(JsLinkedHashMap.K,JsLinkedHashMap.V)],implicit=[JsLinkedHashMap.K,JsLinkedHashMap.V],needsArgs*/
+/*prod:nnbd-off.class: global#JsLinkedHashMap:deps=[LinkedHashMap],implicit=[JsLinkedHashMap.K],needsArgs*/
+/*spec:nnbd-off.class: global#JsLinkedHashMap:deps=[LinkedHashMap],direct,explicit=[JsLinkedHashMap.K,JsLinkedHashMap.V,void Function(JsLinkedHashMap.K,JsLinkedHashMap.V)],implicit=[JsLinkedHashMap.K,JsLinkedHashMap.V],needsArgs*/
-/*omit.class: global#double:explicit=[double]*/
-/*strong.class: global#double:explicit=[double],implicit=[double]*/
+/*prod:nnbd-off.class: global#double:explicit=[double]*/
+/*spec:nnbd-off.class: global#double:explicit=[double],implicit=[double]*/
/*class: global#JSDouble:*/
@@ -25,8 +25,8 @@
set is Set<String>;
}
-/*omit.class: Class:needsArgs*/
-/*strong.class: Class:implicit=[Class.S,Class.T],indirect,needsArgs*/
+/*prod:nnbd-off.class: Class:needsArgs*/
+/*spec:nnbd-off.class: Class:implicit=[Class.S,Class.T],indirect,needsArgs*/
class Class<T, S> {
m() {
return <T, S>{};
diff --git a/tests/compiler/dart2js/rti/data/marker.options b/tests/compiler/dart2js/rti/data/marker.options
index b77684b..cef4600 100644
--- a/tests/compiler/dart2js/rti/data/marker.options
+++ b/tests/compiler/dart2js/rti/data/marker.options
@@ -1,2 +1,4 @@
-strong=tests/compiler/dart2js/rti/rti_need_test_helper.dart
-omit=tests/compiler/dart2js/rti/rti_need_test_helper.dart
\ No newline at end of file
+spec:nnbd-off=tests/compiler/dart2js/rti/rti_need_test_helper.dart
+prod:nnbd-off=tests/compiler/dart2js/rti/rti_need_test_helper.dart
+spec:nnbd-sdk=tests/compiler/dart2js/rti/rti_need_test_helper.dart
+prod:nnbd-sdk=tests/compiler/dart2js/rti/rti_need_test_helper.dart
\ No newline at end of file
diff --git a/tests/compiler/dart2js/rti/data/method_signatures.dart b/tests/compiler/dart2js/rti/data/method_signatures.dart
index b8332d1..77a96ee 100644
--- a/tests/compiler/dart2js/rti/data/method_signatures.dart
+++ b/tests/compiler/dart2js/rti/data/method_signatures.dart
@@ -17,11 +17,11 @@
Object method3(num n) => null;
}
-/*strong.class: Class2:direct,explicit=[Class2.T],needsArgs*/
-/*omit.class: Class2:*/
+/*spec:nnbd-off.class: Class2:direct,explicit=[Class2.T],needsArgs*/
+/*prod:nnbd-off.class: Class2:*/
class Class2<T> {
- /*strong.member: Class2.method4:*/
- /*omit.member: Class2.method4:*/
+ /*spec:nnbd-off.member: Class2.method4:*/
+ /*prod:nnbd-off.member: Class2.method4:*/
num method4(T n) => null;
}
@@ -31,8 +31,8 @@
T method5(num n) => null;
}
-/*omit.class: Class4:*/
-/*strong.class: Class4:direct,explicit=[Class4.T],needsArgs*/
+/*prod:nnbd-off.class: Class4:*/
+/*spec:nnbd-off.class: Class4:direct,explicit=[Class4.T],needsArgs*/
class Class4<T> {
/*member: Class4.method6:*/
num method6(num n, T t) => null;
diff --git a/tests/compiler/dart2js/rti/data/method_signatures_generic.dart b/tests/compiler/dart2js/rti/data/method_signatures_generic.dart
index eb0efc1..0a7024c 100644
--- a/tests/compiler/dart2js/rti/data/method_signatures_generic.dart
+++ b/tests/compiler/dart2js/rti/data/method_signatures_generic.dart
@@ -18,8 +18,8 @@
}
class Class2 {
- /*strong.member: Class2.method4:direct,explicit=[method4.T],needsArgs,needsInst=[<num>,<num>,<num>,<num>]*/
- /*omit.member: Class2.method4:*/
+ /*spec:nnbd-off.member: Class2.method4:direct,explicit=[method4.T],needsArgs,needsInst=[<num>,<num>,<num>,<num>]*/
+ /*prod:nnbd-off.member: Class2.method4:*/
num method4<T>(T n) => null;
}
@@ -29,20 +29,20 @@
}
class Class4 {
- /*strong.member: Class4.method6:direct,explicit=[method6.T],needsArgs,needsInst=[<num>,<num>,<num>,<num>]*/
- /*omit.member: Class4.method6:*/
+ /*spec:nnbd-off.member: Class4.method6:direct,explicit=[method6.T],needsArgs,needsInst=[<num>,<num>,<num>,<num>]*/
+ /*prod:nnbd-off.member: Class4.method6:*/
num method6<T>(num n, T t) => null;
}
-/*strong.member: method7:direct,explicit=[method7.T],needsArgs,needsInst=[<num>,<num>,<num>,<num>]*/
-/*omit.member: method7:*/
+/*spec:nnbd-off.member: method7:direct,explicit=[method7.T],needsArgs,needsInst=[<num>,<num>,<num>,<num>]*/
+/*prod:nnbd-off.member: method7:*/
num method7<T>(T n) => null;
/*member: method8:*/
T method8<T>(num n) => null;
-/*strong.member: method9:direct,explicit=[method9.T],needsArgs,needsInst=[<num>,<num>,<num>,<num>]*/
-/*omit.member: method9:*/
+/*spec:nnbd-off.member: method9:direct,explicit=[method9.T],needsArgs,needsInst=[<num>,<num>,<num>,<num>]*/
+/*prod:nnbd-off.member: method9:*/
num method9<T>(num n, T t) => null;
@pragma('dart2js:noInline')
diff --git a/tests/compiler/dart2js/rti/data/runtime_type_closure_equals1.dart b/tests/compiler/dart2js/rti/data/runtime_type_closure_equals1.dart
index a42deee..48bbd34 100644
--- a/tests/compiler/dart2js/rti/data/runtime_type_closure_equals1.dart
+++ b/tests/compiler/dart2js/rti/data/runtime_type_closure_equals1.dart
@@ -6,16 +6,16 @@
import 'package:expect/expect.dart';
-/*strong.class: Class:*/
-/*omit.class: Class:*/
+/*spec:nnbd-off.class: Class:*/
+/*prod:nnbd-off.class: Class:*/
class Class<T> {
- /*strong.member: Class.:*/
- /*omit.member: Class.:*/
+ /*spec:nnbd-off.member: Class.:*/
+ /*prod:nnbd-off.member: Class.:*/
Class();
}
-/*strong.member: main:*/
-/*omit.member: main:*/
+/*spec:nnbd-off.member: main:*/
+/*prod:nnbd-off.member: main:*/
main() {
/*needsSignature*/
local1a() {}
diff --git a/tests/compiler/dart2js/rti/data/runtime_type_closure_equals2.dart b/tests/compiler/dart2js/rti/data/runtime_type_closure_equals2.dart
index c44c1f7..77913d6 100644
--- a/tests/compiler/dart2js/rti/data/runtime_type_closure_equals2.dart
+++ b/tests/compiler/dart2js/rti/data/runtime_type_closure_equals2.dart
@@ -6,27 +6,27 @@
import 'package:expect/expect.dart';
-/*strong.class: Class:*/
-/*omit.class: Class:*/
+/*spec:nnbd-off.class: Class:*/
+/*prod:nnbd-off.class: Class:*/
class Class<T> {
- /*strong.member: Class.:*/
- /*omit.member: Class.:*/
+ /*spec:nnbd-off.member: Class.:*/
+ /*prod:nnbd-off.member: Class.:*/
Class();
}
-/*strong.member: main:*/
-/*omit.member: main:*/
+/*spec:nnbd-off.member: main:*/
+/*prod:nnbd-off.member: main:*/
main() {
- /*strong.needsArgs,needsSignature*/
- /*omit.needsArgs,needsSignature*/
+ /*spec:nnbd-off.needsArgs,needsSignature*/
+ /*prod:nnbd-off.needsArgs,needsSignature*/
T local1a<T>() => null;
- /*strong.needsArgs,needsSignature*/
- /*omit.needsArgs,needsSignature*/
+ /*spec:nnbd-off.needsArgs,needsSignature*/
+ /*prod:nnbd-off.needsArgs,needsSignature*/
T local1b<T>() => null;
- /*strong.direct,explicit=[local2.T],needsArgs,needsSignature*/
- /*omit.needsArgs,needsSignature*/
+ /*spec:nnbd-off.direct,explicit=[local2.T],needsArgs,needsSignature*/
+ /*prod:nnbd-off.needsArgs,needsSignature*/
T local2<T>(T t, String s) => t;
Expect.isTrue(local1a.runtimeType == local1b.runtimeType);
diff --git a/tests/compiler/dart2js/rti/data/runtime_type_closure_equals3.dart b/tests/compiler/dart2js/rti/data/runtime_type_closure_equals3.dart
index 230f46f..51e8cfc 100644
--- a/tests/compiler/dart2js/rti/data/runtime_type_closure_equals3.dart
+++ b/tests/compiler/dart2js/rti/data/runtime_type_closure_equals3.dart
@@ -8,15 +8,15 @@
String method() => null;
-/*omit.class: Class1:needsArgs*/
-/*strong.class: Class1:direct,explicit=[Class1.T],needsArgs*/
+/*prod:nnbd-off.class: Class1:needsArgs*/
+/*spec:nnbd-off.class: Class1:direct,explicit=[Class1.T],needsArgs*/
class Class1<T> {
- /*strong.member: Class1.:*/
- /*omit.member: Class1.:*/
+ /*spec:nnbd-off.member: Class1.:*/
+ /*prod:nnbd-off.member: Class1.:*/
Class1();
- /*strong.member: Class1.method:*/
- /*omit.member: Class1.method:*/
+ /*spec:nnbd-off.member: Class1.method:*/
+ /*prod:nnbd-off.member: Class1.method:*/
method() {
/*needsSignature*/
T local1a() => null;
@@ -33,16 +33,16 @@
}
}
-/*strong.class: Class2:*/
-/*omit.class: Class2:*/
+/*spec:nnbd-off.class: Class2:*/
+/*prod:nnbd-off.class: Class2:*/
class Class2<T> {
- /*strong.member: Class2.:*/
- /*omit.member: Class2.:*/
+ /*spec:nnbd-off.member: Class2.:*/
+ /*prod:nnbd-off.member: Class2.:*/
Class2();
}
-/*strong.member: main:*/
-/*omit.member: main:*/
+/*spec:nnbd-off.member: main:*/
+/*prod:nnbd-off.member: main:*/
main() {
new Class1<int>().method();
new Class2<int>();
diff --git a/tests/compiler/dart2js/rti/data/runtime_type_closure_equals4.dart b/tests/compiler/dart2js/rti/data/runtime_type_closure_equals4.dart
index 43358cb..549493b 100644
--- a/tests/compiler/dart2js/rti/data/runtime_type_closure_equals4.dart
+++ b/tests/compiler/dart2js/rti/data/runtime_type_closure_equals4.dart
@@ -6,40 +6,40 @@
import 'package:expect/expect.dart';
-/*strong.class: Class1:*/
-/*omit.class: Class1:*/
+/*spec:nnbd-off.class: Class1:*/
+/*prod:nnbd-off.class: Class1:*/
class Class1<T> {
- /*strong.member: Class1.:*/
- /*omit.member: Class1.:*/
+ /*spec:nnbd-off.member: Class1.:*/
+ /*prod:nnbd-off.member: Class1.:*/
Class1();
// TODO(johnniwinther): Currently only methods that use class type variables
// in their signature are marked as 'needs signature'. Change this to mark
// all methods that need to support access to their function type at runtime.
- /*strong.member: Class1.method1a:*/
- /*omit.member: Class1.method1a:*/
+ /*spec:nnbd-off.member: Class1.method1a:*/
+ /*prod:nnbd-off.member: Class1.method1a:*/
method1a() => null;
- /*strong.member: Class1.method1b:*/
- /*omit.member: Class1.method1b:*/
+ /*spec:nnbd-off.member: Class1.method1b:*/
+ /*prod:nnbd-off.member: Class1.method1b:*/
method1b() => null;
- /*strong.member: Class1.method2:*/
- /*omit.member: Class1.method2:*/
+ /*spec:nnbd-off.member: Class1.method2:*/
+ /*prod:nnbd-off.member: Class1.method2:*/
method2(t, s) => t;
}
-/*strong.class: Class2:*/
-/*omit.class: Class2:*/
+/*spec:nnbd-off.class: Class2:*/
+/*prod:nnbd-off.class: Class2:*/
class Class2<T> {
- /*strong.member: Class2.:*/
- /*omit.member: Class2.:*/
+ /*spec:nnbd-off.member: Class2.:*/
+ /*prod:nnbd-off.member: Class2.:*/
Class2();
}
-/*strong.member: main:*/
-/*omit.member: main:*/
+/*spec:nnbd-off.member: main:*/
+/*prod:nnbd-off.member: main:*/
main() {
var c = new Class1<int>();
diff --git a/tests/compiler/dart2js/rti/data/runtime_type_closure_equals5.dart b/tests/compiler/dart2js/rti/data/runtime_type_closure_equals5.dart
index e2cd3bd..2feedd8 100644
--- a/tests/compiler/dart2js/rti/data/runtime_type_closure_equals5.dart
+++ b/tests/compiler/dart2js/rti/data/runtime_type_closure_equals5.dart
@@ -6,36 +6,36 @@
import 'package:expect/expect.dart';
-/*omit.class: Class1:needsArgs*/
-/*strong.class: Class1:direct,explicit=[Class1.T],needsArgs*/
+/*prod:nnbd-off.class: Class1:needsArgs*/
+/*spec:nnbd-off.class: Class1:direct,explicit=[Class1.T],needsArgs*/
class Class1<T> {
- /*strong.member: Class1.:*/
- /*omit.member: Class1.:*/
+ /*spec:nnbd-off.member: Class1.:*/
+ /*prod:nnbd-off.member: Class1.:*/
Class1();
- /*strong.member: Class1.method1a:needsSignature*/
- /*omit.member: Class1.method1a:needsSignature*/
+ /*spec:nnbd-off.member: Class1.method1a:needsSignature*/
+ /*prod:nnbd-off.member: Class1.method1a:needsSignature*/
T method1a() => null;
- /*strong.member: Class1.method1b:needsSignature*/
- /*omit.member: Class1.method1b:needsSignature*/
+ /*spec:nnbd-off.member: Class1.method1b:needsSignature*/
+ /*prod:nnbd-off.member: Class1.method1b:needsSignature*/
T method1b() => null;
- /*strong.member: Class1.method2:needsSignature*/
- /*omit.member: Class1.method2:needsSignature*/
+ /*spec:nnbd-off.member: Class1.method2:needsSignature*/
+ /*prod:nnbd-off.member: Class1.method2:needsSignature*/
T method2(T t, String s) => t;
}
-/*strong.class: Class2:*/
-/*omit.class: Class2:*/
+/*spec:nnbd-off.class: Class2:*/
+/*prod:nnbd-off.class: Class2:*/
class Class2<T> {
- /*strong.member: Class2.:*/
- /*omit.member: Class2.:*/
+ /*spec:nnbd-off.member: Class2.:*/
+ /*prod:nnbd-off.member: Class2.:*/
Class2();
}
-/*strong.member: main:*/
-/*omit.member: main:*/
+/*spec:nnbd-off.member: main:*/
+/*prod:nnbd-off.member: main:*/
main() {
var c = new Class1<int>();
diff --git a/tests/compiler/dart2js/rti/data/runtime_type_closure_equals6.dart b/tests/compiler/dart2js/rti/data/runtime_type_closure_equals6.dart
index 77593d4..d08a341 100644
--- a/tests/compiler/dart2js/rti/data/runtime_type_closure_equals6.dart
+++ b/tests/compiler/dart2js/rti/data/runtime_type_closure_equals6.dart
@@ -6,28 +6,28 @@
import 'package:expect/expect.dart';
-/*strong.member: method1a:*/
-/*omit.member: method1a:*/
+/*spec:nnbd-off.member: method1a:*/
+/*prod:nnbd-off.member: method1a:*/
method1a() => null;
-/*strong.member: method1b:*/
-/*omit.member: method1b:*/
+/*spec:nnbd-off.member: method1b:*/
+/*prod:nnbd-off.member: method1b:*/
method1b() => null;
-/*strong.member: method2:*/
-/*omit.member: method2:*/
+/*spec:nnbd-off.member: method2:*/
+/*prod:nnbd-off.member: method2:*/
method2(t, s) => t;
-/*strong.class: Class:*/
-/*omit.class: Class:*/
+/*spec:nnbd-off.class: Class:*/
+/*prod:nnbd-off.class: Class:*/
class Class<T> {
- /*strong.member: Class.:*/
- /*omit.member: Class.:*/
+ /*spec:nnbd-off.member: Class.:*/
+ /*prod:nnbd-off.member: Class.:*/
Class();
}
-/*strong.member: main:*/
-/*omit.member: main:*/
+/*spec:nnbd-off.member: main:*/
+/*prod:nnbd-off.member: main:*/
main() {
Expect.isTrue(method1a.runtimeType == method1b.runtimeType);
Expect.isFalse(method1a.runtimeType == method2.runtimeType);
diff --git a/tests/compiler/dart2js/rti/data/runtime_type_closure_equals7.dart b/tests/compiler/dart2js/rti/data/runtime_type_closure_equals7.dart
index 198424c..e43e522 100644
--- a/tests/compiler/dart2js/rti/data/runtime_type_closure_equals7.dart
+++ b/tests/compiler/dart2js/rti/data/runtime_type_closure_equals7.dart
@@ -12,20 +12,20 @@
/*member: method1b:*/
T method1b<T>() => null;
-/*strong.member: method2:direct,explicit=[method2.T],needsArgs*/
-/*omit.member: method2:*/
+/*spec:nnbd-off.member: method2:direct,explicit=[method2.T],needsArgs*/
+/*prod:nnbd-off.member: method2:*/
T method2<T>(T t, String s) => t;
-/*strong.class: Class:*/
-/*omit.class: Class:*/
+/*spec:nnbd-off.class: Class:*/
+/*prod:nnbd-off.class: Class:*/
class Class<T> {
- /*strong.member: Class.:*/
- /*omit.member: Class.:*/
+ /*spec:nnbd-off.member: Class.:*/
+ /*prod:nnbd-off.member: Class.:*/
Class();
}
-/*strong.member: main:*/
-/*omit.member: main:*/
+/*spec:nnbd-off.member: main:*/
+/*prod:nnbd-off.member: main:*/
main() {
Expect.isTrue(method1a.runtimeType == method1b.runtimeType);
Expect.isFalse(method1a.runtimeType == method2.runtimeType);
diff --git a/tests/compiler/dart2js/rti/data/runtime_type_closure_equals8.dart b/tests/compiler/dart2js/rti/data/runtime_type_closure_equals8.dart
index 5656b34..ca1408e 100644
--- a/tests/compiler/dart2js/rti/data/runtime_type_closure_equals8.dart
+++ b/tests/compiler/dart2js/rti/data/runtime_type_closure_equals8.dart
@@ -6,11 +6,11 @@
import 'package:expect/expect.dart';
-/*strong.class: Class1:*/
-/*omit.class: Class1:*/
+/*spec:nnbd-off.class: Class1:*/
+/*prod:nnbd-off.class: Class1:*/
class Class1<S> {
- /*strong.member: Class1.:*/
- /*omit.member: Class1.:*/
+ /*spec:nnbd-off.member: Class1.:*/
+ /*prod:nnbd-off.member: Class1.:*/
Class1();
/*member: Class1.method1a:*/
@@ -19,21 +19,21 @@
/*member: Class1.method1b:*/
T method1b<T>() => null;
- /*strong.member: Class1.method2:direct,explicit=[method2.T],needsArgs*/
- /*omit.member: Class1.method2:*/
+ /*spec:nnbd-off.member: Class1.method2:direct,explicit=[method2.T],needsArgs*/
+ /*prod:nnbd-off.member: Class1.method2:*/
T method2<T>(T t, String s) => t;
}
-/*strong.class: Class2:*/
-/*omit.class: Class2:*/
+/*spec:nnbd-off.class: Class2:*/
+/*prod:nnbd-off.class: Class2:*/
class Class2<T> {
- /*strong.member: Class2.:*/
- /*omit.member: Class2.:*/
+ /*spec:nnbd-off.member: Class2.:*/
+ /*prod:nnbd-off.member: Class2.:*/
Class2();
}
-/*strong.member: main:*/
-/*omit.member: main:*/
+/*spec:nnbd-off.member: main:*/
+/*prod:nnbd-off.member: main:*/
main() {
var c = new Class1<int>();
diff --git a/tests/compiler/dart2js/rti/data/runtime_type_closure_to_string1.dart b/tests/compiler/dart2js/rti/data/runtime_type_closure_to_string1.dart
index cc64617..8622fed 100644
--- a/tests/compiler/dart2js/rti/data/runtime_type_closure_to_string1.dart
+++ b/tests/compiler/dart2js/rti/data/runtime_type_closure_to_string1.dart
@@ -4,23 +4,23 @@
// @dart = 2.7
-/*strong.class: Class:*/
-/*omit.class: Class:*/
+/*spec:nnbd-off.class: Class:*/
+/*prod:nnbd-off.class: Class:*/
class Class<T> {
- /*strong.member: Class.:*/
- /*omit.member: Class.:*/
+ /*spec:nnbd-off.member: Class.:*/
+ /*prod:nnbd-off.member: Class.:*/
Class();
}
-/*strong.member: main:*/
-/*omit.member: main:*/
+/*spec:nnbd-off.member: main:*/
+/*prod:nnbd-off.member: main:*/
main() {
- /*strong.needsSignature*/
- /*omit.*/
+ /*spec:nnbd-off.needsSignature*/
+ /*prod:nnbd-off.*/
local1() {}
- /*strong.needsSignature*/
- /*omit.*/
+ /*spec:nnbd-off.needsSignature*/
+ /*prod:nnbd-off.*/
local2(int i, String s) => i;
print('${local1.runtimeType}');
diff --git a/tests/compiler/dart2js/rti/data/runtime_type_closure_to_string2.dart b/tests/compiler/dart2js/rti/data/runtime_type_closure_to_string2.dart
index e79d08a..d01980c 100644
--- a/tests/compiler/dart2js/rti/data/runtime_type_closure_to_string2.dart
+++ b/tests/compiler/dart2js/rti/data/runtime_type_closure_to_string2.dart
@@ -4,23 +4,23 @@
// @dart = 2.7
-/*strong.class: Class:*/
-/*omit.class: Class:*/
+/*spec:nnbd-off.class: Class:*/
+/*prod:nnbd-off.class: Class:*/
class Class<T> {
- /*strong.member: Class.:*/
- /*omit.member: Class.:*/
+ /*spec:nnbd-off.member: Class.:*/
+ /*prod:nnbd-off.member: Class.:*/
Class();
}
-/*strong.member: main:*/
-/*omit.member: main:*/
+/*spec:nnbd-off.member: main:*/
+/*prod:nnbd-off.member: main:*/
main() {
- /*strong.needsArgs,needsSignature*/
- /*omit.*/
+ /*spec:nnbd-off.needsArgs,needsSignature*/
+ /*prod:nnbd-off.*/
local1<T>() {}
- /*strong.needsArgs,needsSignature,selectors=[Selector(call, call, arity=2, types=1)]*/
- /*omit.*/
+ /*spec:nnbd-off.needsArgs,needsSignature,selectors=[Selector(call, call, arity=2, types=1)]*/
+ /*prod:nnbd-off.*/
local2<T>(t, s) => t;
print('${local1.runtimeType}');
diff --git a/tests/compiler/dart2js/rti/data/runtime_type_closure_to_string3.dart b/tests/compiler/dart2js/rti/data/runtime_type_closure_to_string3.dart
index d1d3744..ac6dcf5 100644
--- a/tests/compiler/dart2js/rti/data/runtime_type_closure_to_string3.dart
+++ b/tests/compiler/dart2js/rti/data/runtime_type_closure_to_string3.dart
@@ -4,28 +4,28 @@
// @dart = 2.7
-/*strong.class: Class1:needsArgs*/
-/*omit.class: Class1:*/
+/*spec:nnbd-off.class: Class1:needsArgs*/
+/*prod:nnbd-off.class: Class1:*/
class Class1<T> {
- /*strong.member: Class1.:*/
- /*omit.member: Class1.:*/
+ /*spec:nnbd-off.member: Class1.:*/
+ /*prod:nnbd-off.member: Class1.:*/
Class1();
- /*strong.member: Class1.method:needsSignature*/
- /*omit.member: Class1.method:*/
+ /*spec:nnbd-off.member: Class1.method:needsSignature*/
+ /*prod:nnbd-off.member: Class1.method:*/
T method() => null;
}
-/*strong.class: Class2:*/
-/*omit.class: Class2:*/
+/*spec:nnbd-off.class: Class2:*/
+/*prod:nnbd-off.class: Class2:*/
class Class2<T> {
- /*strong.member: Class2.:*/
- /*omit.member: Class2.:*/
+ /*spec:nnbd-off.member: Class2.:*/
+ /*prod:nnbd-off.member: Class2.:*/
Class2();
}
-/*strong.member: main:*/
-/*omit.member: main:*/
+/*spec:nnbd-off.member: main:*/
+/*prod:nnbd-off.member: main:*/
main() {
Class1<int> cls1 = new Class1<int>();
print(cls1.method.runtimeType.toString());
diff --git a/tests/compiler/dart2js/rti/data/runtime_type_closure_to_string5.dart b/tests/compiler/dart2js/rti/data/runtime_type_closure_to_string5.dart
index ef8ea71..25c1942 100644
--- a/tests/compiler/dart2js/rti/data/runtime_type_closure_to_string5.dart
+++ b/tests/compiler/dart2js/rti/data/runtime_type_closure_to_string5.dart
@@ -4,24 +4,24 @@
// @dart = 2.7
-/*strong.class: Class:*/
-/*omit.class: Class:*/
+/*spec:nnbd-off.class: Class:*/
+/*prod:nnbd-off.class: Class:*/
class Class<T> {
- /*strong.member: Class.:*/
- /*omit.member: Class.:*/
+ /*spec:nnbd-off.member: Class.:*/
+ /*prod:nnbd-off.member: Class.:*/
Class();
}
-/*strong.member: method1:*/
-/*omit.member: method1:*/
+/*spec:nnbd-off.member: method1:*/
+/*prod:nnbd-off.member: method1:*/
method1() {}
-/*strong.member: method2:*/
-/*omit.member: method2:*/
+/*spec:nnbd-off.member: method2:*/
+/*prod:nnbd-off.member: method2:*/
method2(int i, String s) => i;
-/*strong.member: main:*/
-/*omit.member: main:*/
+/*spec:nnbd-off.member: main:*/
+/*prod:nnbd-off.member: main:*/
main() {
print('${method1.runtimeType}');
method2(0, '');
diff --git a/tests/compiler/dart2js/rti/data/runtime_type_equals1.dart b/tests/compiler/dart2js/rti/data/runtime_type_equals1.dart
index cc6dfc5..5f321e0 100644
--- a/tests/compiler/dart2js/rti/data/runtime_type_equals1.dart
+++ b/tests/compiler/dart2js/rti/data/runtime_type_equals1.dart
@@ -8,12 +8,12 @@
/*class: Class1a:needsArgs*/
class Class1a<T> {
- /*strong.member: Class1a.:*/
- /*omit.member: Class1a.:*/
+ /*spec:nnbd-off.member: Class1a.:*/
+ /*prod:nnbd-off.member: Class1a.:*/
Class1a();
- /*strong.member: Class1a.==:*/
- /*omit.member: Class1a.==:*/
+ /*spec:nnbd-off.member: Class1a.==:*/
+ /*prod:nnbd-off.member: Class1a.==:*/
bool operator ==(other) {
if (identical(this, other)) return true;
return runtimeType == other.runtimeType;
@@ -22,8 +22,8 @@
/*class: Class1b:needsArgs*/
class Class1b<T> extends Class1a<T> {
- /*strong.member: Class1b.:*/
- /*omit.member: Class1b.:*/
+ /*spec:nnbd-off.member: Class1b.:*/
+ /*prod:nnbd-off.member: Class1b.:*/
Class1b();
}
@@ -31,21 +31,21 @@
// this class.
/*class: Class1c:needsArgs*/
class Class1c<T> implements Class1a<T> {
- /*strong.member: Class1c.:*/
- /*omit.member: Class1c.:*/
+ /*spec:nnbd-off.member: Class1c.:*/
+ /*prod:nnbd-off.member: Class1c.:*/
Class1c();
}
-/*strong.class: Class2:*/
-/*omit.class: Class2:*/
+/*spec:nnbd-off.class: Class2:*/
+/*prod:nnbd-off.class: Class2:*/
class Class2<T> {
- /*strong.member: Class2.:*/
- /*omit.member: Class2.:*/
+ /*spec:nnbd-off.member: Class2.:*/
+ /*prod:nnbd-off.member: Class2.:*/
Class2();
}
-/*strong.member: main:*/
-/*omit.member: main:*/
+/*spec:nnbd-off.member: main:*/
+/*prod:nnbd-off.member: main:*/
main() {
Class1a<int> cls1a = new Class1a<int>();
Class1a<int> cls1b1 = new Class1b<int>();
diff --git a/tests/compiler/dart2js/rti/data/runtime_type_equals2.dart b/tests/compiler/dart2js/rti/data/runtime_type_equals2.dart
index 77abea4..9f77e4c 100644
--- a/tests/compiler/dart2js/rti/data/runtime_type_equals2.dart
+++ b/tests/compiler/dart2js/rti/data/runtime_type_equals2.dart
@@ -8,12 +8,12 @@
/*class: Class1a:needsArgs*/
class Class1a<T> {
- /*strong.member: Class1a.:*/
- /*omit.member: Class1a.:*/
+ /*spec:nnbd-off.member: Class1a.:*/
+ /*prod:nnbd-off.member: Class1a.:*/
Class1a();
- /*strong.member: Class1a.==:*/
- /*omit.member: Class1a.==:*/
+ /*spec:nnbd-off.member: Class1a.==:*/
+ /*prod:nnbd-off.member: Class1a.==:*/
bool operator ==(other) {
if (identical(this, other)) return true;
return other.runtimeType == runtimeType;
@@ -22,8 +22,8 @@
/*class: Class1b:needsArgs*/
class Class1b<T> extends Class1a<T> {
- /*strong.member: Class1b.:*/
- /*omit.member: Class1b.:*/
+ /*spec:nnbd-off.member: Class1b.:*/
+ /*prod:nnbd-off.member: Class1b.:*/
Class1b();
}
@@ -31,21 +31,21 @@
// this class.
/*class: Class1c:needsArgs*/
class Class1c<T> implements Class1a<T> {
- /*strong.member: Class1c.:*/
- /*omit.member: Class1c.:*/
+ /*spec:nnbd-off.member: Class1c.:*/
+ /*prod:nnbd-off.member: Class1c.:*/
Class1c();
}
-/*strong.class: Class2:*/
-/*omit.class: Class2:*/
+/*spec:nnbd-off.class: Class2:*/
+/*prod:nnbd-off.class: Class2:*/
class Class2<T> {
- /*strong.member: Class2.:*/
- /*omit.member: Class2.:*/
+ /*spec:nnbd-off.member: Class2.:*/
+ /*prod:nnbd-off.member: Class2.:*/
Class2();
}
-/*strong.member: main:*/
-/*omit.member: main:*/
+/*spec:nnbd-off.member: main:*/
+/*prod:nnbd-off.member: main:*/
main() {
Class1a<int> cls1a = new Class1a<int>();
Class1a<int> cls1b1 = new Class1b<int>();
diff --git a/tests/compiler/dart2js/rti/data/runtime_type_equals3.dart b/tests/compiler/dart2js/rti/data/runtime_type_equals3.dart
index 5b030ba..ccdccad 100644
--- a/tests/compiler/dart2js/rti/data/runtime_type_equals3.dart
+++ b/tests/compiler/dart2js/rti/data/runtime_type_equals3.dart
@@ -8,12 +8,12 @@
/*class: Class1a:needsArgs*/
class Class1a<T> {
- /*strong.member: Class1a.:*/
- /*omit.member: Class1a.:*/
+ /*spec:nnbd-off.member: Class1a.:*/
+ /*prod:nnbd-off.member: Class1a.:*/
Class1a();
- /*strong.member: Class1a.==:*/
- /*omit.member: Class1a.==:*/
+ /*spec:nnbd-off.member: Class1a.==:*/
+ /*prod:nnbd-off.member: Class1a.==:*/
bool operator ==(other) {
if (identical(this, other)) return true;
return runtimeType == other?.runtimeType;
@@ -22,8 +22,8 @@
/*class: Class1b:needsArgs*/
class Class1b<T> extends Class1a<T> {
- /*strong.member: Class1b.:*/
- /*omit.member: Class1b.:*/
+ /*spec:nnbd-off.member: Class1b.:*/
+ /*prod:nnbd-off.member: Class1b.:*/
Class1b();
}
@@ -31,21 +31,21 @@
// this class.
/*class: Class1c:needsArgs*/
class Class1c<T> implements Class1a<T> {
- /*strong.member: Class1c.:*/
- /*omit.member: Class1c.:*/
+ /*spec:nnbd-off.member: Class1c.:*/
+ /*prod:nnbd-off.member: Class1c.:*/
Class1c();
}
-/*strong.class: Class2:*/
-/*omit.class: Class2:*/
+/*spec:nnbd-off.class: Class2:*/
+/*prod:nnbd-off.class: Class2:*/
class Class2<T> {
- /*strong.member: Class2.:*/
- /*omit.member: Class2.:*/
+ /*spec:nnbd-off.member: Class2.:*/
+ /*prod:nnbd-off.member: Class2.:*/
Class2();
}
-/*strong.member: main:*/
-/*omit.member: main:*/
+/*spec:nnbd-off.member: main:*/
+/*prod:nnbd-off.member: main:*/
main() {
Class1a<int> cls1a = new Class1a<int>();
Class1a<int> cls1b1 = new Class1b<int>();
diff --git a/tests/compiler/dart2js/rti/data/runtime_type_equals4.dart b/tests/compiler/dart2js/rti/data/runtime_type_equals4.dart
index 9892440..fd1f0dc 100644
--- a/tests/compiler/dart2js/rti/data/runtime_type_equals4.dart
+++ b/tests/compiler/dart2js/rti/data/runtime_type_equals4.dart
@@ -8,12 +8,12 @@
/*class: Class1a:needsArgs*/
class Class1a<T> {
- /*strong.member: Class1a.:*/
- /*omit.member: Class1a.:*/
+ /*spec:nnbd-off.member: Class1a.:*/
+ /*prod:nnbd-off.member: Class1a.:*/
Class1a();
- /*strong.member: Class1a.==:*/
- /*omit.member: Class1a.==:*/
+ /*spec:nnbd-off.member: Class1a.==:*/
+ /*prod:nnbd-off.member: Class1a.==:*/
bool operator ==(other) {
if (identical(this, other)) return true;
return other?.runtimeType == runtimeType;
@@ -22,8 +22,8 @@
/*class: Class1b:needsArgs*/
class Class1b<T> extends Class1a<T> {
- /*strong.member: Class1b.:*/
- /*omit.member: Class1b.:*/
+ /*spec:nnbd-off.member: Class1b.:*/
+ /*prod:nnbd-off.member: Class1b.:*/
Class1b();
}
@@ -31,21 +31,21 @@
// this class.
/*class: Class1c:needsArgs*/
class Class1c<T> implements Class1a<T> {
- /*strong.member: Class1c.:*/
- /*omit.member: Class1c.:*/
+ /*spec:nnbd-off.member: Class1c.:*/
+ /*prod:nnbd-off.member: Class1c.:*/
Class1c();
}
-/*strong.class: Class2:*/
-/*omit.class: Class2:*/
+/*spec:nnbd-off.class: Class2:*/
+/*prod:nnbd-off.class: Class2:*/
class Class2<T> {
- /*strong.member: Class2.:*/
- /*omit.member: Class2.:*/
+ /*spec:nnbd-off.member: Class2.:*/
+ /*prod:nnbd-off.member: Class2.:*/
Class2();
}
-/*strong.member: main:*/
-/*omit.member: main:*/
+/*spec:nnbd-off.member: main:*/
+/*prod:nnbd-off.member: main:*/
main() {
Class1a<int> cls1a = new Class1a<int>();
Class1a<int> cls1b1 = new Class1b<int>();
diff --git a/tests/compiler/dart2js/rti/data/runtime_type_equals5.dart b/tests/compiler/dart2js/rti/data/runtime_type_equals5.dart
index b7b1d2c..ad20c46 100644
--- a/tests/compiler/dart2js/rti/data/runtime_type_equals5.dart
+++ b/tests/compiler/dart2js/rti/data/runtime_type_equals5.dart
@@ -6,37 +6,37 @@
import 'package:expect/expect.dart';
-/*strong.class: Class1a:explicit=[Class1a]*/
+/*spec:nnbd-off.class: Class1a:explicit=[Class1a]*/
class Class1a {
Class1a();
}
-/*strong.class: Class1b:needsArgs*/
-/*omit.class: Class1b:needsArgs*/
+/*spec:nnbd-off.class: Class1b:needsArgs*/
+/*prod:nnbd-off.class: Class1b:needsArgs*/
class Class1b<T> extends Class1a {
Class1b();
}
-/*strong.class: Class1c:needsArgs*/
-/*omit.class: Class1c:needsArgs*/
+/*spec:nnbd-off.class: Class1c:needsArgs*/
+/*prod:nnbd-off.class: Class1c:needsArgs*/
class Class1c<T> extends Class1a {
Class1c();
}
-/*strong.class: Class2:*/
-/*omit.class: Class2:*/
+/*spec:nnbd-off.class: Class2:*/
+/*prod:nnbd-off.class: Class2:*/
class Class2<T> {
Class2();
}
-/*strong.member: test:*/
-/*omit.member: test:*/
+/*spec:nnbd-off.member: test:*/
+/*prod:nnbd-off.member: test:*/
test(Class1a c, Type type) {
return c.runtimeType == type;
}
-/*strong.member: main:*/
-/*omit.member: main:*/
+/*spec:nnbd-off.member: main:*/
+/*prod:nnbd-off.member: main:*/
main() {
Expect.isTrue(test(new Class1a(), Class1a));
Expect.isFalse(test(new Class1b<int>(), Class1a));
diff --git a/tests/compiler/dart2js/rti/data/runtime_type_equals6.dart b/tests/compiler/dart2js/rti/data/runtime_type_equals6.dart
index 8482f3d..2098c62 100644
--- a/tests/compiler/dart2js/rti/data/runtime_type_equals6.dart
+++ b/tests/compiler/dart2js/rti/data/runtime_type_equals6.dart
@@ -6,38 +6,38 @@
import 'package:expect/expect.dart';
-/*strong.class: Class1a:explicit=[Class1a],needsArgs*/
-/*omit.class: Class1a:needsArgs*/
+/*spec:nnbd-off.class: Class1a:explicit=[Class1a],needsArgs*/
+/*prod:nnbd-off.class: Class1a:needsArgs*/
class Class1a<T> {
Class1a();
}
-/*strong.class: Class1b:needsArgs*/
-/*omit.class: Class1b:needsArgs*/
+/*spec:nnbd-off.class: Class1b:needsArgs*/
+/*prod:nnbd-off.class: Class1b:needsArgs*/
class Class1b<T> extends Class1a<T> {
Class1b();
}
-/*strong.class: Class1c:needsArgs*/
-/*omit.class: Class1c:needsArgs*/
+/*spec:nnbd-off.class: Class1c:needsArgs*/
+/*prod:nnbd-off.class: Class1c:needsArgs*/
class Class1c<T> extends Class1a<T> {
Class1c();
}
-/*strong.class: Class2:*/
-/*omit.class: Class2:*/
+/*spec:nnbd-off.class: Class2:*/
+/*prod:nnbd-off.class: Class2:*/
class Class2<T> {
Class2();
}
-/*strong.member: test:*/
-/*omit.member: test:*/
+/*spec:nnbd-off.member: test:*/
+/*prod:nnbd-off.member: test:*/
test(Class1a c, Type type) {
return c.runtimeType == type;
}
-/*strong.member: main:*/
-/*omit.member: main:*/
+/*spec:nnbd-off.member: main:*/
+/*prod:nnbd-off.member: main:*/
main() {
Expect.isTrue(test(new Class1a(), Class1a));
Expect.isFalse(test(new Class1b<int>(), Class1a));
diff --git a/tests/compiler/dart2js/rti/data/runtime_type_equals7.dart b/tests/compiler/dart2js/rti/data/runtime_type_equals7.dart
index 980f832..9d448cd 100644
--- a/tests/compiler/dart2js/rti/data/runtime_type_equals7.dart
+++ b/tests/compiler/dart2js/rti/data/runtime_type_equals7.dart
@@ -6,45 +6,45 @@
import 'package:expect/expect.dart';
-/*strong.class: Class1a:explicit=[Class1a]*/
+/*spec:nnbd-off.class: Class1a:explicit=[Class1a]*/
class Class1a {
Class1a();
}
-/*strong.class: Class1b:needsArgs*/
-/*omit.class: Class1b:needsArgs*/
+/*spec:nnbd-off.class: Class1b:needsArgs*/
+/*prod:nnbd-off.class: Class1b:needsArgs*/
class Class1b<T> extends Class1a {
Class1b();
}
-/*strong.class: Class1c:needsArgs*/
-/*omit.class: Class1c:needsArgs*/
+/*spec:nnbd-off.class: Class1c:needsArgs*/
+/*prod:nnbd-off.class: Class1c:needsArgs*/
class Class1c<T> extends Class1a {
Class1c();
}
-/*strong.class: Class2:*/
-/*omit.class: Class2:*/
+/*spec:nnbd-off.class: Class2:*/
+/*prod:nnbd-off.class: Class2:*/
class Class2<T> {
Class2();
}
-/*strong.class: Class3:explicit=[Class3]*/
-/*omit.class: Class3:*/
+/*spec:nnbd-off.class: Class3:explicit=[Class3]*/
+/*prod:nnbd-off.class: Class3:*/
class Class3<T> {
final Class1a field;
Class3(this.field);
}
-/*strong.member: test:*/
-/*omit.member: test:*/
+/*spec:nnbd-off.member: test:*/
+/*prod:nnbd-off.member: test:*/
test(Class3 c, Type type) {
return c.field.runtimeType == type;
}
-/*strong.member: main:*/
-/*omit.member: main:*/
+/*spec:nnbd-off.member: main:*/
+/*prod:nnbd-off.member: main:*/
main() {
Expect.isTrue(test(new Class3<int>(new Class1a()), Class1a));
Expect.isFalse(test(new Class3<int>(new Class1b<int>()), Class1a));
diff --git a/tests/compiler/dart2js/rti/data/runtime_type_instantiate_to_string1.dart b/tests/compiler/dart2js/rti/data/runtime_type_instantiate_to_string1.dart
index 36de144..a5a2214 100644
--- a/tests/compiler/dart2js/rti/data/runtime_type_instantiate_to_string1.dart
+++ b/tests/compiler/dart2js/rti/data/runtime_type_instantiate_to_string1.dart
@@ -7,7 +7,7 @@
/*member: global#instantiate1:needsArgs*/
main() {
- /*strong.direct,explicit=[id.T],needsArgs,needsInst=[<int>],needsSignature*/
+ /*spec:nnbd-off.direct,explicit=[id.T],needsArgs,needsInst=[<int>],needsSignature*/
T id<T>(T t, String s) => t;
int Function(int, String s) x = id;
print("${x.runtimeType}");
diff --git a/tests/compiler/dart2js/rti/data/runtime_type_instantiate_to_string2.dart b/tests/compiler/dart2js/rti/data/runtime_type_instantiate_to_string2.dart
index 2b1fc09..d5c35e2 100644
--- a/tests/compiler/dart2js/rti/data/runtime_type_instantiate_to_string2.dart
+++ b/tests/compiler/dart2js/rti/data/runtime_type_instantiate_to_string2.dart
@@ -6,7 +6,7 @@
/*member: global#instantiate1:needsArgs*/
-/*strong.member: id:direct,explicit=[id.T],needsArgs,needsInst=[<int>]*/
+/*spec:nnbd-off.member: id:direct,explicit=[id.T],needsArgs,needsInst=[<int>]*/
T id<T>(T t, String s) => t;
main() {
diff --git a/tests/compiler/dart2js/rti/data/runtime_type_instantiate_to_string3.dart b/tests/compiler/dart2js/rti/data/runtime_type_instantiate_to_string3.dart
index 0060b4c..49733ad 100644
--- a/tests/compiler/dart2js/rti/data/runtime_type_instantiate_to_string3.dart
+++ b/tests/compiler/dart2js/rti/data/runtime_type_instantiate_to_string3.dart
@@ -7,7 +7,7 @@
/*member: global#instantiate1:needsArgs*/
class Class {
- /*strong.member: Class.id:direct,explicit=[id.T],needsArgs,needsInst=[<int>]*/
+ /*spec:nnbd-off.member: Class.id:direct,explicit=[id.T],needsArgs,needsInst=[<int>]*/
T id<T>(T t, String s) => t;
}
diff --git a/tests/compiler/dart2js/rti/data/runtime_type_to_string1.dart b/tests/compiler/dart2js/rti/data/runtime_type_to_string1.dart
index 33499d6..a414f91 100644
--- a/tests/compiler/dart2js/rti/data/runtime_type_to_string1.dart
+++ b/tests/compiler/dart2js/rti/data/runtime_type_to_string1.dart
@@ -4,32 +4,32 @@
// @dart = 2.7
-/*strong.class: Class1:*/
-/*omit.class: Class1:*/
+/*spec:nnbd-off.class: Class1:*/
+/*prod:nnbd-off.class: Class1:*/
class Class1 {
- /*strong.member: Class1.:*/
- /*omit.member: Class1.:*/
+ /*spec:nnbd-off.member: Class1.:*/
+ /*prod:nnbd-off.member: Class1.:*/
Class1();
}
-/*strong.class: Class2:*/
-/*omit.class: Class2:*/
+/*spec:nnbd-off.class: Class2:*/
+/*prod:nnbd-off.class: Class2:*/
class Class2<T> {
- /*strong.member: Class2.:*/
- /*omit.member: Class2.:*/
+ /*spec:nnbd-off.member: Class2.:*/
+ /*prod:nnbd-off.member: Class2.:*/
Class2();
}
-/*strong.class: Class3:needsArgs*/
-/*omit.class: Class3:*/
+/*spec:nnbd-off.class: Class3:needsArgs*/
+/*prod:nnbd-off.class: Class3:*/
class Class3<T> implements Class1 {
- /*strong.member: Class3.:*/
- /*omit.member: Class3.:*/
+ /*spec:nnbd-off.member: Class3.:*/
+ /*prod:nnbd-off.member: Class3.:*/
Class3();
}
-/*strong.member: main:*/
-/*omit.member: main:*/
+/*spec:nnbd-off.member: main:*/
+/*prod:nnbd-off.member: main:*/
main() {
Class1 cls1 = new Class1();
print(cls1.runtimeType.toString());
diff --git a/tests/compiler/dart2js/rti/data/runtime_type_to_string2.dart b/tests/compiler/dart2js/rti/data/runtime_type_to_string2.dart
index b2f2adb..97d71504 100644
--- a/tests/compiler/dart2js/rti/data/runtime_type_to_string2.dart
+++ b/tests/compiler/dart2js/rti/data/runtime_type_to_string2.dart
@@ -4,24 +4,24 @@
// @dart = 2.7
-/*strong.class: Class1:needsArgs*/
-/*omit.class: Class1:*/
+/*spec:nnbd-off.class: Class1:needsArgs*/
+/*prod:nnbd-off.class: Class1:*/
class Class1<T> {
- /*strong.member: Class1.:*/
- /*omit.member: Class1.:*/
+ /*spec:nnbd-off.member: Class1.:*/
+ /*prod:nnbd-off.member: Class1.:*/
Class1();
}
-/*strong.class: Class2:*/
-/*omit.class: Class2:*/
+/*spec:nnbd-off.class: Class2:*/
+/*prod:nnbd-off.class: Class2:*/
class Class2<T> {
- /*strong.member: Class2.:*/
- /*omit.member: Class2.:*/
+ /*spec:nnbd-off.member: Class2.:*/
+ /*prod:nnbd-off.member: Class2.:*/
Class2();
}
-/*strong.member: main:*/
-/*omit.member: main:*/
+/*spec:nnbd-off.member: main:*/
+/*prod:nnbd-off.member: main:*/
main() {
Class1<int> cls1 = new Class1<int>();
print('${cls1.runtimeType}');
diff --git a/tests/compiler/dart2js/rti/data/runtime_type_to_string3.dart b/tests/compiler/dart2js/rti/data/runtime_type_to_string3.dart
index 2fa2623..c13a88b 100644
--- a/tests/compiler/dart2js/rti/data/runtime_type_to_string3.dart
+++ b/tests/compiler/dart2js/rti/data/runtime_type_to_string3.dart
@@ -4,24 +4,24 @@
// @dart = 2.7
-/*strong.class: Class1:needsArgs*/
-/*omit.class: Class1:*/
+/*spec:nnbd-off.class: Class1:needsArgs*/
+/*prod:nnbd-off.class: Class1:*/
class Class1<T> {
- /*strong.member: Class1.:*/
- /*omit.member: Class1.:*/
+ /*spec:nnbd-off.member: Class1.:*/
+ /*prod:nnbd-off.member: Class1.:*/
Class1();
}
-/*strong.class: Class2:*/
-/*omit.class: Class2:*/
+/*spec:nnbd-off.class: Class2:*/
+/*prod:nnbd-off.class: Class2:*/
class Class2<T> {
- /*strong.member: Class2.:*/
- /*omit.member: Class2.:*/
+ /*spec:nnbd-off.member: Class2.:*/
+ /*prod:nnbd-off.member: Class2.:*/
Class2();
}
-/*strong.member: main:*/
-/*omit.member: main:*/
+/*spec:nnbd-off.member: main:*/
+/*prod:nnbd-off.member: main:*/
main() {
Class1<int> cls1 = new Class1<int>();
print(cls1.runtimeType?.toString());
diff --git a/tests/compiler/dart2js/rti/data/runtime_type_to_string4.dart b/tests/compiler/dart2js/rti/data/runtime_type_to_string4.dart
index 75ce88e..d8418e1 100644
--- a/tests/compiler/dart2js/rti/data/runtime_type_to_string4.dart
+++ b/tests/compiler/dart2js/rti/data/runtime_type_to_string4.dart
@@ -4,24 +4,24 @@
// @dart = 2.7
-/*strong.class: Class1:needsArgs*/
-/*omit.class: Class1:*/
+/*spec:nnbd-off.class: Class1:needsArgs*/
+/*prod:nnbd-off.class: Class1:*/
class Class1<T> {
- /*strong.member: Class1.:*/
- /*omit.member: Class1.:*/
+ /*spec:nnbd-off.member: Class1.:*/
+ /*prod:nnbd-off.member: Class1.:*/
Class1();
}
-/*strong.class: Class2:*/
-/*omit.class: Class2:*/
+/*spec:nnbd-off.class: Class2:*/
+/*prod:nnbd-off.class: Class2:*/
class Class2<T> {
- /*strong.member: Class2.:*/
- /*omit.member: Class2.:*/
+ /*spec:nnbd-off.member: Class2.:*/
+ /*prod:nnbd-off.member: Class2.:*/
Class2();
}
-/*strong.member: main:*/
-/*omit.member: main:*/
+/*spec:nnbd-off.member: main:*/
+/*prod:nnbd-off.member: main:*/
main() {
Class1<int> cls1 = new Class1<int>();
print(cls1?.runtimeType?.toString());
diff --git a/tests/compiler/dart2js/rti/data/runtime_type_to_string5.dart b/tests/compiler/dart2js/rti/data/runtime_type_to_string5.dart
index 520fbb6..56a3c53 100644
--- a/tests/compiler/dart2js/rti/data/runtime_type_to_string5.dart
+++ b/tests/compiler/dart2js/rti/data/runtime_type_to_string5.dart
@@ -4,24 +4,24 @@
// @dart = 2.7
-/*strong.class: Class1:needsArgs*/
-/*omit.class: Class1:*/
+/*spec:nnbd-off.class: Class1:needsArgs*/
+/*prod:nnbd-off.class: Class1:*/
class Class1<T> {
- /*strong.member: Class1.:*/
- /*omit.member: Class1.:*/
+ /*spec:nnbd-off.member: Class1.:*/
+ /*prod:nnbd-off.member: Class1.:*/
Class1();
}
-/*strong.class: Class2:*/
-/*omit.class: Class2:*/
+/*spec:nnbd-off.class: Class2:*/
+/*prod:nnbd-off.class: Class2:*/
class Class2<T> {
- /*strong.member: Class2.:*/
- /*omit.member: Class2.:*/
+ /*spec:nnbd-off.member: Class2.:*/
+ /*prod:nnbd-off.member: Class2.:*/
Class2();
}
-/*strong.member: main:*/
-/*omit.member: main:*/
+/*spec:nnbd-off.member: main:*/
+/*prod:nnbd-off.member: main:*/
main() {
Class1<int> cls1 = new Class1<int>();
print('${cls1?.runtimeType}');
diff --git a/tests/compiler/dart2js/rti/data/runtime_type_to_string6.dart b/tests/compiler/dart2js/rti/data/runtime_type_to_string6.dart
index 8272616..b9a04c6 100644
--- a/tests/compiler/dart2js/rti/data/runtime_type_to_string6.dart
+++ b/tests/compiler/dart2js/rti/data/runtime_type_to_string6.dart
@@ -4,24 +4,24 @@
// @dart = 2.7
-/*strong.class: Class1:needsArgs*/
-/*omit.class: Class1:*/
+/*spec:nnbd-off.class: Class1:needsArgs*/
+/*prod:nnbd-off.class: Class1:*/
class Class1<T> {
- /*strong.member: Class1.:*/
- /*omit.member: Class1.:*/
+ /*spec:nnbd-off.member: Class1.:*/
+ /*prod:nnbd-off.member: Class1.:*/
Class1();
}
-/*strong.class: Class2:needsArgs*/
-/*omit.class: Class2:*/
+/*spec:nnbd-off.class: Class2:needsArgs*/
+/*prod:nnbd-off.class: Class2:*/
class Class2<T> {
- /*strong.member: Class2.:*/
- /*omit.member: Class2.:*/
+ /*spec:nnbd-off.member: Class2.:*/
+ /*prod:nnbd-off.member: Class2.:*/
Class2();
}
-/*strong.member: main:*/
-/*omit.member: main:*/
+/*spec:nnbd-off.member: main:*/
+/*prod:nnbd-off.member: main:*/
main() {
dynamic cls1 = new Class1<int>();
print('${cls1.runtimeType}');
diff --git a/tests/compiler/dart2js/rti/data/runtime_type_to_string7.dart b/tests/compiler/dart2js/rti/data/runtime_type_to_string7.dart
index 33499d6..a414f91 100644
--- a/tests/compiler/dart2js/rti/data/runtime_type_to_string7.dart
+++ b/tests/compiler/dart2js/rti/data/runtime_type_to_string7.dart
@@ -4,32 +4,32 @@
// @dart = 2.7
-/*strong.class: Class1:*/
-/*omit.class: Class1:*/
+/*spec:nnbd-off.class: Class1:*/
+/*prod:nnbd-off.class: Class1:*/
class Class1 {
- /*strong.member: Class1.:*/
- /*omit.member: Class1.:*/
+ /*spec:nnbd-off.member: Class1.:*/
+ /*prod:nnbd-off.member: Class1.:*/
Class1();
}
-/*strong.class: Class2:*/
-/*omit.class: Class2:*/
+/*spec:nnbd-off.class: Class2:*/
+/*prod:nnbd-off.class: Class2:*/
class Class2<T> {
- /*strong.member: Class2.:*/
- /*omit.member: Class2.:*/
+ /*spec:nnbd-off.member: Class2.:*/
+ /*prod:nnbd-off.member: Class2.:*/
Class2();
}
-/*strong.class: Class3:needsArgs*/
-/*omit.class: Class3:*/
+/*spec:nnbd-off.class: Class3:needsArgs*/
+/*prod:nnbd-off.class: Class3:*/
class Class3<T> implements Class1 {
- /*strong.member: Class3.:*/
- /*omit.member: Class3.:*/
+ /*spec:nnbd-off.member: Class3.:*/
+ /*prod:nnbd-off.member: Class3.:*/
Class3();
}
-/*strong.member: main:*/
-/*omit.member: main:*/
+/*spec:nnbd-off.member: main:*/
+/*prod:nnbd-off.member: main:*/
main() {
Class1 cls1 = new Class1();
print(cls1.runtimeType.toString());
diff --git a/tests/compiler/dart2js/rti/data/subtype_named_args.dart b/tests/compiler/dart2js/rti/data/subtype_named_args.dart
index 905ab05..bd72027 100644
--- a/tests/compiler/dart2js/rti/data/subtype_named_args.dart
+++ b/tests/compiler/dart2js/rti/data/subtype_named_args.dart
@@ -8,7 +8,7 @@
import 'package:expect/expect.dart';
-/*strong.class: A:
+/*spec:nnbd-off.class: A:
explicit=[
A,G<A,A1,A1,A1>,
dynamic Function({a:A,b:A1,c:A1,d:A1}),
@@ -20,7 +20,7 @@
dynamic Function({v:dynamic Function({a:A,b:B,c:C,d:D}),x:int,y:bool,z:List<Map>}),
dynamic Function({v:dynamic,x:A,y:G,z:dynamic Function({b:B,f:dynamic Function({f1:dynamic Function({a:A,b:B,c:C,d:D}),f2:dynamic Function({g:G<A,B,C,D>,l:List<List<B>>,m:Map<num,int>}),f3:dynamic Function({v:dynamic,x:dynamic,y:dynamic,z:dynamic})}),g:G<A,B,C,D>,x:dynamic})})]
*/
-/*omit.class: A:
+/*prod:nnbd-off.class: A:
explicit=[
dynamic Function({a:A,b:B,c:C,d:D}),
dynamic Function({f1:dynamic Function({a:A,b:B,c:C,d:D}),f2:dynamic Function({g:G<A,B,C,D>,l:List<List<B>>,m:Map<num,int>}),f3:dynamic Function({v:dynamic,x:dynamic,y:dynamic,z:dynamic})}),
@@ -28,13 +28,13 @@
*/
class A {}
-/*strong.class: A1:explicit=[A1,G<A,A1,A1,A1>,List<List<A1>>,dynamic Function({a:A,b:A1,c:A1,d:A1}),dynamic Function({g:G<A,A1,A1,A1>,l:List<List<A1>>,m:Map<num,num>})]*/
+/*spec:nnbd-off.class: A1:explicit=[A1,G<A,A1,A1,A1>,List<List<A1>>,dynamic Function({a:A,b:A1,c:A1,d:A1}),dynamic Function({g:G<A,A1,A1,A1>,l:List<List<A1>>,m:Map<num,num>})]*/
class A1 {}
-/*strong.class: A2:explicit=[A2]*/
+/*spec:nnbd-off.class: A2:explicit=[A2]*/
class A2 {}
-/*strong.class: B:
+/*spec:nnbd-off.class: B:
explicit=[
B,
dynamic Function({a:A,b:B,c:C,d:D}),
@@ -44,7 +44,7 @@
dynamic Function({v:dynamic Function({a:A,b:B,c:C,d:D}),x:int,y:bool,z:List<Map>}),
dynamic Function({v:dynamic,x:A,y:G,z:dynamic Function({b:B,f:dynamic Function({f1:dynamic Function({a:A,b:B,c:C,d:D}),f2:dynamic Function({g:G<A,B,C,D>,l:List<List<B>>,m:Map<num,int>}),f3:dynamic Function({v:dynamic,x:dynamic,y:dynamic,z:dynamic})}),g:G<A,B,C,D>,x:dynamic})})]
*/
-/*omit.class: B:
+/*prod:nnbd-off.class: B:
explicit=[
dynamic Function({a:A,b:B,c:C,d:D}),
dynamic Function({f1:dynamic Function({a:A,b:B,c:C,d:D}),f2:dynamic Function({g:G<A,B,C,D>,l:List<List<B>>,m:Map<num,int>}),f3:dynamic Function({v:dynamic,x:dynamic,y:dynamic,z:dynamic})}),
@@ -52,7 +52,7 @@
*/
class B implements A, A1, A2 {}
-/*strong.class: C:
+/*spec:nnbd-off.class: C:
explicit=[
C,
dynamic Function({a:A,b:B,c:C,d:D}),
@@ -61,7 +61,7 @@
dynamic Function({g:G<A,B,C,D>,l:List<List<B>>,m:Map<num,int>}),dynamic Function({v:dynamic Function({a:A,b:B,c:C,d:D}),x:int,y:bool,z:List<Map>}),
dynamic Function({v:dynamic,x:A,y:G,z:dynamic Function({b:B,f:dynamic Function({f1:dynamic Function({a:A,b:B,c:C,d:D}),f2:dynamic Function({g:G<A,B,C,D>,l:List<List<B>>,m:Map<num,int>}),f3:dynamic Function({v:dynamic,x:dynamic,y:dynamic,z:dynamic})}),g:G<A,B,C,D>,x:dynamic})})]
*/
-/*omit.class: C:
+/*prod:nnbd-off.class: C:
explicit=[
dynamic Function({a:A,b:B,c:C,d:D}),
dynamic Function({f1:dynamic Function({a:A,b:B,c:C,d:D}),f2:dynamic Function({g:G<A,B,C,D>,l:List<List<B>>,m:Map<num,int>}),f3:dynamic Function({v:dynamic,x:dynamic,y:dynamic,z:dynamic})}),
@@ -69,7 +69,7 @@
*/
class C implements B {}
-/*strong.class: D:
+/*spec:nnbd-off.class: D:
explicit=[
D,G<D,D,D,D>,List<List<D>>,
dynamic Function({a:A,b:B,c:C,d:D}),
@@ -78,7 +78,7 @@
dynamic Function({f1:dynamic Function({a:A,b:B,c:C,d:D}),f2:dynamic Function({g:G<A,B,C,D>,l:List<List<B>>,m:Map<num,int>}),f3:dynamic Function({v:dynamic,x:dynamic,y:dynamic,z:dynamic})}),dynamic Function({g:G<A,B,C,D>,l:List<List<B>>,m:Map<num,int>}),dynamic Function({g:G<D,D,D,D>,l:List<List<D>>,m:Map<int,int>}),
dynamic Function({v:dynamic Function({a:A,b:B,c:C,d:D}),x:int,y:bool,z:List<Map>}),dynamic Function({v:dynamic,x:A,y:G,z:dynamic Function({b:B,f:dynamic Function({f1:dynamic Function({a:A,b:B,c:C,d:D}),f2:dynamic Function({g:G<A,B,C,D>,l:List<List<B>>,m:Map<num,int>}),f3:dynamic Function({v:dynamic,x:dynamic,y:dynamic,z:dynamic})}),g:G<A,B,C,D>,x:dynamic})})]
*/
-/*omit.class: D:
+/*prod:nnbd-off.class: D:
explicit=[
dynamic Function({a:A,b:B,c:C,d:D}),
dynamic Function({f1:dynamic Function({a:A,b:B,c:C,d:D}),f2:dynamic Function({g:G<A,B,C,D>,l:List<List<B>>,m:Map<num,int>}),f3:dynamic Function({v:dynamic,x:dynamic,y:dynamic,z:dynamic})}),
@@ -86,7 +86,7 @@
*/
class D implements C {}
-/*strong.class: G:
+/*spec:nnbd-off.class: G:
explicit=[
G,G<A,A1,A1,A1>,G<D,D,D,D>,
dynamic Function({b:B,f:dynamic Function({f1:dynamic Function({a:A,b:B,c:C,d:D}),f2:dynamic Function({g:G<A,B,C,D>,l:List<List<B>>,m:Map<num,int>}),f3:dynamic Function({v:dynamic,x:dynamic,y:dynamic,z:dynamic})}),g:G<A,B,C,D>,x:dynamic}),
@@ -97,7 +97,7 @@
dynamic Function({v:dynamic,x:A,y:G,z:dynamic Function({b:B,f:dynamic Function({f1:dynamic Function({a:A,b:B,c:C,d:D}),f2:dynamic Function({g:G<A,B,C,D>,l:List<List<B>>,m:Map<num,int>}),f3:dynamic Function({v:dynamic,x:dynamic,y:dynamic,z:dynamic})}),g:G<A,B,C,D>,x:dynamic})})],
needsArgs
*/
-/*omit.class: G:
+/*prod:nnbd-off.class: G:
explicit=[
dynamic Function({f1:dynamic Function({a:A,b:B,c:C,d:D}),f2:dynamic Function({g:G<A,B,C,D>,l:List<List<B>>,m:Map<num,int>}),f3:dynamic Function({v:dynamic,x:dynamic,y:dynamic,z:dynamic})}),
dynamic Function({g:G<A,B,C,D>,l:List<List<B>>,m:Map<num,int>})]
@@ -123,19 +123,19 @@
main() {
Expect.isTrue(
- /*strong.needsSignature*/
+ /*spec:nnbd-off.needsSignature*/
({D a, B b, C c, A d}) {} is classesFunc);
Expect.isTrue(
/*needsSignature*/
({A a, A b, A c, A d}) {} is classesFunc);
Expect.isTrue(
- /*strong.needsSignature*/
+ /*spec:nnbd-off.needsSignature*/
({D a, A1 b, A1 c, A1 d}) {} is classesFunc);
Expect.isTrue(
- /*strong.needsSignature*/
+ /*spec:nnbd-off.needsSignature*/
({D a, A2 b, A2 c, A2 d}) {} is classesFunc);
Expect.isTrue(
- /*strong.needsSignature*/
+ /*spec:nnbd-off.needsSignature*/
({D a, D b, D c, D d}) {} is classesFunc);
Expect.isTrue(
/*needsSignature*/
@@ -149,7 +149,7 @@
({Map<num, num> m, List<List<A1>> l, G<A, A1, A1, A1> g}) {}
is genericsFunc);
Expect.isTrue(
- /*strong.needsSignature*/
+ /*spec:nnbd-off.needsSignature*/
({Map<int, int> m, List<List<D>> l, G<D, D, D, D> g}) {} is genericsFunc);
Expect.isTrue(
/*needsSignature*/
@@ -159,10 +159,10 @@
({Object m, Object l, Object g}) {} is genericsFunc);
Expect.isTrue(
- /*strong.needsSignature*/
+ /*spec:nnbd-off.needsSignature*/
({A x, G y, mixFunc z, var v}) {} is dynamicFunc);
Expect.isTrue(
- /*strong.needsSignature*/
+ /*spec:nnbd-off.needsSignature*/
({int x, bool y, List<Map> z, classesFunc v}) {} is dynamicFunc);
Expect.isTrue((
diff --git a/tests/compiler/dart2js/rti/data/subtype_named_args1.dart b/tests/compiler/dart2js/rti/data/subtype_named_args1.dart
index dc140e4..08e4684 100644
--- a/tests/compiler/dart2js/rti/data/subtype_named_args1.dart
+++ b/tests/compiler/dart2js/rti/data/subtype_named_args1.dart
@@ -8,18 +8,18 @@
import "package:expect/expect.dart";
-/*strong.class: A:explicit=[A,dynamic Function({a:A})]*/
+/*spec:nnbd-off.class: A:explicit=[A,dynamic Function({a:A})]*/
class A {}
-/*strong.class: B:explicit=[B,dynamic Function({a:B}),dynamic Function({f:dynamic Function({a:B})})]*/
-/*omit.class: B:explicit=[dynamic Function({a:B}),dynamic Function({f:dynamic Function({a:B})})]*/
+/*spec:nnbd-off.class: B:explicit=[B,dynamic Function({a:B}),dynamic Function({f:dynamic Function({a:B})})]*/
+/*prod:nnbd-off.class: B:explicit=[dynamic Function({a:B}),dynamic Function({f:dynamic Function({a:B})})]*/
class B implements A {}
-/*strong.class: C:explicit=[C,dynamic Function({a:C}),dynamic Function({c:C})]*/
-/*omit.class: C:explicit=[dynamic Function({c:C})]*/
+/*spec:nnbd-off.class: C:explicit=[C,dynamic Function({a:C}),dynamic Function({c:C})]*/
+/*prod:nnbd-off.class: C:explicit=[dynamic Function({c:C})]*/
class C implements B {}
-/*strong.class: D:explicit=[D,dynamic Function({a:D})]*/
+/*spec:nnbd-off.class: D:explicit=[D,dynamic Function({a:D})]*/
class D implements C {}
typedef t1({B a});
@@ -39,8 +39,8 @@
main() {
Expect.isTrue(/*needsSignature*/ ({A a}) {} is t1);
Expect.isTrue(/*needsSignature*/ ({B a}) {} is t1);
- Expect.isTrue(/*strong.needsSignature*/ ({C a}) {} is t1);
- Expect.isTrue(/*strong.needsSignature*/ ({D a}) {} is t1);
+ Expect.isTrue(/*spec:nnbd-off.needsSignature*/ ({C a}) {} is t1);
+ Expect.isTrue(/*spec:nnbd-off.needsSignature*/ ({D a}) {} is t1);
Expect.isTrue(/*needsSignature*/ ({Object a}) {} is t1);
Expect.isTrue(/*needsSignature*/ ({var a}) {} is t1);
@@ -90,8 +90,8 @@
Expect.isTrue(/*needsSignature*/ ({A a}) {} is t8);
Expect.isTrue(/*needsSignature*/ ({B a}) {} is t8);
- Expect.isTrue(/*strong.needsSignature*/ ({C a}) {} is t8);
- Expect.isTrue(/*strong.needsSignature*/ ({D a}) {} is t8);
+ Expect.isTrue(/*spec:nnbd-off.needsSignature*/ ({C a}) {} is t8);
+ Expect.isTrue(/*spec:nnbd-off.needsSignature*/ ({D a}) {} is t8);
Expect.isTrue(/*needsSignature*/ ({Object a}) {} is t8);
Expect.isTrue(/*needsSignature*/ ({var a}) {} is t8);
Expect.isTrue(({num a}) {} is t8);
diff --git a/tests/compiler/dart2js/rti/data/tear_off_generic.dart b/tests/compiler/dart2js/rti/data/tear_off_generic.dart
index fea635a..727f8be 100644
--- a/tests/compiler/dart2js/rti/data/tear_off_generic.dart
+++ b/tests/compiler/dart2js/rti/data/tear_off_generic.dart
@@ -4,11 +4,11 @@
// @dart = 2.7
-/*strong.class: A:direct,explicit=[A.T],needsArgs*/
-/*omit.class: A:*/
+/*spec:nnbd-off.class: A:direct,explicit=[A.T],needsArgs*/
+/*prod:nnbd-off.class: A:*/
class A<T> {
- /*strong.member: A.m:*/
- /*omit.member: A.m:*/
+ /*spec:nnbd-off.member: A.m:*/
+ /*prod:nnbd-off.member: A.m:*/
void m(T t) {}
/*member: A.f:*/
diff --git a/tests/compiler/dart2js/rti/emission/closure_function.dart b/tests/compiler/dart2js/rti/emission/closure_function.dart
index d478691..8e032bf 100644
--- a/tests/compiler/dart2js/rti/emission/closure_function.dart
+++ b/tests/compiler/dart2js/rti/emission/closure_function.dart
@@ -10,8 +10,7 @@
main() {
test(
- /*strong.checks=[],instance*/
- /*omit.checks=[],instance*/
+ /*checks=[],instance*/
() {});
test(null);
}
diff --git a/tests/compiler/dart2js/rti/emission/closure_function_type.dart b/tests/compiler/dart2js/rti/emission/closure_function_type.dart
index 6436a12..b40047e 100644
--- a/tests/compiler/dart2js/rti/emission/closure_function_type.dart
+++ b/tests/compiler/dart2js/rti/emission/closure_function_type.dart
@@ -11,7 +11,6 @@
test(/*checks=[$signature],instance*/ () {});
test(
- /*strong.checks=[],instance*/
- /*omit.checks=[],instance*/
+ /*checks=[],instance*/
(a) {});
}
diff --git a/tests/compiler/dart2js/rti/emission/closure_signature_unneeded.dart b/tests/compiler/dart2js/rti/emission/closure_signature_unneeded.dart
index 28e2660..15549d7 100644
--- a/tests/compiler/dart2js/rti/emission/closure_signature_unneeded.dart
+++ b/tests/compiler/dart2js/rti/emission/closure_signature_unneeded.dart
@@ -12,8 +12,7 @@
// potential subtype of the checked function types.
return
- /*strong.checks=[],instance*/
- /*omit.checks=[],instance*/
+ /*checks=[],instance*/
(T t, String s) {};
}
}
diff --git a/tests/compiler/dart2js/rti/emission/constructor_argument_static.dart b/tests/compiler/dart2js/rti/emission/constructor_argument_static.dart
index 097a0ce9..280e65d 100644
--- a/tests/compiler/dart2js/rti/emission/constructor_argument_static.dart
+++ b/tests/compiler/dart2js/rti/emission/constructor_argument_static.dart
@@ -4,14 +4,14 @@
// @dart = 2.7
-/*strong.class: A1:checkedInstance,checks=[],instance*/
-/*omit.class: A1:checks=[],instance*/
+/*spec:nnbd-off|spec:nnbd-sdk.class: A1:checkedInstance,checks=[],instance*/
+/*prod:nnbd-off|prod:nnbd-sdk.class: A1:checks=[],instance*/
class A1 {}
// Constructor calls are always statically invoked, so there is no checks at the
// entry and the `Test1` constructor does not cause any checks.
-/*strong.class: B1:checks=[$isA1],instance*/
-/*omit.class: B1:checks=[],instance*/
+/*spec:nnbd-off|spec:nnbd-sdk.class: B1:checks=[$isA1],instance*/
+/*prod:nnbd-off|prod:nnbd-sdk.class: B1:checks=[],instance*/
class B1 implements A1 {}
/*class: Test1:checks=[],instance*/
diff --git a/tests/compiler/dart2js/rti/emission/event_callback.dart b/tests/compiler/dart2js/rti/emission/event_callback.dart
index 288d1da..7402b76 100644
--- a/tests/compiler/dart2js/rti/emission/event_callback.dart
+++ b/tests/compiler/dart2js/rti/emission/event_callback.dart
@@ -6,8 +6,8 @@
import 'dart:html';
-/*strong.class: global#Event:checkedInstance,checkedTypeArgument,checks=[$isEvent],instance,typeArgument*/
-/*omit.class: global#Event:checkedTypeArgument,checks=[$isEvent],instance,typeArgument*/
+/*spec:nnbd-off.class: global#Event:checkedInstance,checkedTypeArgument,checks=[$isEvent],instance,typeArgument*/
+/*prod:nnbd-off.class: global#Event:checkedTypeArgument,checks=[$isEvent],instance,typeArgument*/
/*class: global#MouseEvent:checks=[$isMouseEvent],instance,typeArgument*/
/*class: global#KeyboardEvent:checks=[$isKeyboardEvent],instance,typeArgument*/
diff --git a/tests/compiler/dart2js/rti/emission/fixed_type_argument.dart b/tests/compiler/dart2js/rti/emission/fixed_type_argument.dart
index e636027..8e9d63f 100644
--- a/tests/compiler/dart2js/rti/emission/fixed_type_argument.dart
+++ b/tests/compiler/dart2js/rti/emission/fixed_type_argument.dart
@@ -4,12 +4,12 @@
// @dart = 2.7
-/*strong.class: A:checkedInstance,checkedTypeArgument,checks=[],typeArgument*/
-/*omit.class: A:checkedTypeArgument,checks=[],typeArgument*/
+/*spec:nnbd-off|spec:nnbd-sdk.class: A:checkedInstance,checkedTypeArgument,checks=[],typeArgument*/
+/*prod:nnbd-off|prod:nnbd-sdk.class: A:checkedTypeArgument,checks=[],typeArgument*/
class A {}
-/*strong.class: B:checkedInstance,checks=[$isA],typeArgument*/
-/*omit.class: B:checks=[$isA],typeArgument*/
+/*spec:nnbd-off|spec:nnbd-sdk.class: B:checkedInstance,checks=[$isA],typeArgument*/
+/*prod:nnbd-off|prod:nnbd-sdk.class: B:checks=[$isA],typeArgument*/
class B implements A {}
/*class: C:checks=[],indirectInstance*/
@@ -24,7 +24,7 @@
main() {
C<A> c = new D();
c.method(
- /*strong.checks=[$signature],instance*/
- /*omit.checks=[],instance*/
+ /*spec:nnbd-off|spec:nnbd-sdk.checks=[$signature],instance*/
+ /*prod:nnbd-off|prod:nnbd-sdk.checks=[],instance*/
(A a) {});
}
diff --git a/tests/compiler/dart2js/rti/emission/fixed_type_argument_implements.dart b/tests/compiler/dart2js/rti/emission/fixed_type_argument_implements.dart
index b5bdbee..9a9331c 100644
--- a/tests/compiler/dart2js/rti/emission/fixed_type_argument_implements.dart
+++ b/tests/compiler/dart2js/rti/emission/fixed_type_argument_implements.dart
@@ -7,19 +7,19 @@
// Test that we emit the relation between B and A even when B is only live
// as a type argument through the supertype of D.
-/*strong.class: A:checkedTypeArgument,checks=[],typeArgument*/
+/*spec:nnbd-off|spec:nnbd-sdk.class: A:checkedTypeArgument,checks=[],typeArgument*/
class A {}
-/*strong.class: B:checks=[$isA],typeArgument*/
-/*omit.class: B:checks=[],typeArgument*/
+/*spec:nnbd-off|spec:nnbd-sdk.class: B:checks=[$isA],typeArgument*/
+/*prod:nnbd-off|prod:nnbd-sdk.class: B:checks=[],typeArgument*/
class B implements A {}
-/*strong.class: C:checkedInstance*/
-/*omit.class: C:*/
+/*spec:nnbd-off|spec:nnbd-sdk.class: C:checkedInstance*/
+/*prod:nnbd-off.class: C:*/
class C<T> {}
-/*strong.class: D:checks=[$isC],instance*/
-/*omit.class: D:checks=[],instance*/
+/*spec:nnbd-off|spec:nnbd-sdk.class: D:checks=[$isC],instance*/
+/*prod:nnbd-off|prod:nnbd-sdk.class: D:checks=[],instance*/
class D implements C<B> {}
main() {
diff --git a/tests/compiler/dart2js/rti/emission/function_type_argument.dart b/tests/compiler/dart2js/rti/emission/function_type_argument.dart
index f674415..cf4fdc3 100644
--- a/tests/compiler/dart2js/rti/emission/function_type_argument.dart
+++ b/tests/compiler/dart2js/rti/emission/function_type_argument.dart
@@ -6,14 +6,14 @@
import 'package:expect/expect.dart';
-/*strong.class: C:checkedInstance,checks=[],instance,typeArgument*/
-/*omit.class: C:checks=[],instance,typeArgument*/
+/*spec:nnbd-off|spec:nnbd-sdk.class: C:checkedInstance,checks=[],instance,typeArgument*/
+/*prod:nnbd-off|prod:nnbd-sdk.class: C:checks=[],instance,typeArgument*/
class C {
call(int i) {}
}
-/*strong.class: D:checkedInstance,checks=[],instance,typeArgument*/
-/*omit.class: D:checks=[],instance,typeArgument*/
+/*spec:nnbd-off|spec:nnbd-sdk.class: D:checkedInstance,checks=[],instance,typeArgument*/
+/*prod:nnbd-off|prod:nnbd-sdk.class: D:checks=[],instance,typeArgument*/
class D {
call(double i) {}
}
diff --git a/tests/compiler/dart2js/rti/emission/generic_methods_dynamic_02.dart b/tests/compiler/dart2js/rti/emission/generic_methods_dynamic_02.dart
index 0241ff4..5c4b796 100644
--- a/tests/compiler/dart2js/rti/emission/generic_methods_dynamic_02.dart
+++ b/tests/compiler/dart2js/rti/emission/generic_methods_dynamic_02.dart
@@ -8,12 +8,12 @@
library generic_methods_dynamic_test;
-/*strong.class: A:checkedInstance,checks=[],typeArgument*/
-/*omit.class: A:*/
+/*spec:nnbd-off|spec:nnbd-sdk.class: A:checkedInstance,checks=[],typeArgument*/
+/*prod:nnbd-off.class: A:*/
class A {}
-/*strong.class: B:checks=[],instance*/
-/*omit.class: B:*/
+/*spec:nnbd-off|spec:nnbd-sdk.class: B:checks=[],instance*/
+/*prod:nnbd-off.class: B:*/
class B {}
/*class: C:*/
diff --git a/tests/compiler/dart2js/rti/emission/indirect_through_static.dart b/tests/compiler/dart2js/rti/emission/indirect_through_static.dart
index 5a70d24..8246072 100644
--- a/tests/compiler/dart2js/rti/emission/indirect_through_static.dart
+++ b/tests/compiler/dart2js/rti/emission/indirect_through_static.dart
@@ -4,16 +4,13 @@
// @dart = 2.7
-/*strong.class: A:checkedInstance,checks=[],typeArgument*/
-/*omit.class: A:checkedInstance,checks=[],typeArgument*/
+/*class: A:checkedInstance,checks=[],typeArgument*/
abstract class A {}
-/*strong.class: B:checks=[$isA],typeArgument*/
-/*omit.class: B:checks=[$isA],typeArgument*/
+/*class: B:checks=[$isA],typeArgument*/
class B implements A {}
-/*strong.class: C:checkedInstance,checks=[],instance,typeArgument*/
-/*omit.class: C:checkedInstance,checks=[],instance,typeArgument*/
+/*class: C:checkedInstance,checks=[],instance,typeArgument*/
class C<T> {}
final Map<String, C> map = {};
diff --git a/tests/compiler/dart2js/rti/emission/jsinterop_generic_factory_args.dart b/tests/compiler/dart2js/rti/emission/jsinterop_generic_factory_args.dart
index 65a16f8..b86d758 100644
--- a/tests/compiler/dart2js/rti/emission/jsinterop_generic_factory_args.dart
+++ b/tests/compiler/dart2js/rti/emission/jsinterop_generic_factory_args.dart
@@ -14,8 +14,8 @@
import 'package:expect/expect.dart';
import 'package:js/js.dart';
-/*strong.class: A:checkedInstance,checkedTypeArgument,checks=[],typeArgument*/
-/*omit.class: A:checkedTypeArgument,checks=[],typeArgument*/
+/*spec:nnbd-off|spec:nnbd-sdk.class: A:checkedInstance,checkedTypeArgument,checks=[],typeArgument*/
+/*prod:nnbd-off|prod:nnbd-sdk.class: A:checkedTypeArgument,checks=[],typeArgument*/
@JS()
@anonymous
class A<T> {
diff --git a/tests/compiler/dart2js/rti/emission/list.dart b/tests/compiler/dart2js/rti/emission/list.dart
index 6efdf08..ee93c8d 100644
--- a/tests/compiler/dart2js/rti/emission/list.dart
+++ b/tests/compiler/dart2js/rti/emission/list.dart
@@ -4,17 +4,17 @@
// @dart = 2.7
-/*strong.class: A:checkedInstance,checkedTypeArgument,checks=[],typeArgument*/
-/*omit.class: A:checkedTypeArgument,checks=[],typeArgument*/
-/*strong.class: global#JSArray:checkedInstance,checks=[$isIterable],instance*/
-/*omit.class: global#JSArray:checks=[$isIterable],instance*/
+/*spec:nnbd-off|spec:nnbd-sdk.class: A:checkedInstance,checkedTypeArgument,checks=[],typeArgument*/
+/*prod:nnbd-off|prod:nnbd-sdk.class: A:checkedTypeArgument,checks=[],typeArgument*/
+/*spec:nnbd-off.class: global#JSArray:checkedInstance,checks=[$isIterable],instance*/
+/*prod:nnbd-off.class: global#JSArray:checks=[$isIterable],instance*/
/*class: global#Iterable:checkedInstance*/
class A {}
-/*strong.class: B:checkedInstance,checks=[],typeArgument*/
-/*omit.class: B:checks=[],typeArgument*/
+/*spec:nnbd-off|spec:nnbd-sdk.class: B:checkedInstance,checks=[],typeArgument*/
+/*prod:nnbd-off|prod:nnbd-sdk.class: B:checks=[],typeArgument*/
class B {}
@pragma('dart2js:noInline')
diff --git a/tests/compiler/dart2js/rti/emission/local_function_list_literal.dart b/tests/compiler/dart2js/rti/emission/local_function_list_literal.dart
index 7573410..115a5d1 100644
--- a/tests/compiler/dart2js/rti/emission/local_function_list_literal.dart
+++ b/tests/compiler/dart2js/rti/emission/local_function_list_literal.dart
@@ -6,8 +6,8 @@
import 'package:expect/expect.dart';
-/*strong.class: global#JSArray:checkedInstance,checks=[$isIterable,$isList],instance*/
-/*omit.class: global#JSArray:checks=[$isList],instance*/
+/*spec:nnbd-off.class: global#JSArray:checkedInstance,checks=[$isIterable,$isList],instance*/
+/*prod:nnbd-off.class: global#JSArray:checks=[$isList],instance*/
@pragma('dart2js:noInline')
method<T>() {
diff --git a/tests/compiler/dart2js/rti/emission/map_literal.dart b/tests/compiler/dart2js/rti/emission/map_literal.dart
index 273331d..e424e80 100644
--- a/tests/compiler/dart2js/rti/emission/map_literal.dart
+++ b/tests/compiler/dart2js/rti/emission/map_literal.dart
@@ -4,12 +4,12 @@
// @dart = 2.7
-/*strong.class: global#Map:instance*/
+/*spec:nnbd-off.class: global#Map:instance*/
/*class: global#LinkedHashMap:*/
/*class: global#JsLinkedHashMap:checks=[],instance*/
-/*strong.class: global#double:checkedInstance,checks=[],instance,typeArgument*/
+/*spec:nnbd-off.class: global#double:checkedInstance,checks=[],instance,typeArgument*/
/*class: global#JSDouble:checks=[],instance*/
diff --git a/tests/compiler/dart2js/rti/emission/marker.options b/tests/compiler/dart2js/rti/emission/marker.options
index bc69057..a072260 100644
--- a/tests/compiler/dart2js/rti/emission/marker.options
+++ b/tests/compiler/dart2js/rti/emission/marker.options
@@ -1,2 +1,4 @@
-strong=tests/compiler/dart2js/rti/rti_emission_test.dart
-omit=tests/compiler/dart2js/rti/rti_emission_test.dart
\ No newline at end of file
+spec:nnbd-off=tests/compiler/dart2js/rti/rti_emission_test.dart
+prod:nnbd-off=tests/compiler/dart2js/rti/rti_emission_test.dart
+spec:nnbd-sdk=tests/compiler/dart2js/rti/rti_emission_test.dart
+prod:nnbd-sdk=tests/compiler/dart2js/rti/rti_emission_test.dart
\ No newline at end of file
diff --git a/tests/compiler/dart2js/rti/emission/pragma_directives_static.dart b/tests/compiler/dart2js/rti/emission/pragma_directives_static.dart
index 36f671d..9809bbc 100644
--- a/tests/compiler/dart2js/rti/emission/pragma_directives_static.dart
+++ b/tests/compiler/dart2js/rti/emission/pragma_directives_static.dart
@@ -28,12 +28,12 @@
// inserts an implicit cast at the call-site or we disregard the forced check
// because it is a static call.
-/*strong.class: Class1a:checkedInstance*/
-/*omit.class: Class1a:*/
+/*spec:nnbd-off|spec:nnbd-sdk.class: Class1a:checkedInstance*/
+/*prod:nnbd-off.class: Class1a:*/
class Class1a {}
-/*strong.class: Class1b:checkedInstance*/
-/*omit.class: Class1b:*/
+/*spec:nnbd-off|spec:nnbd-sdk.class: Class1b:checkedInstance*/
+/*prod:nnbd-off.class: Class1b:*/
class Class1b {}
// Checks are needed both with and without --omit-implicit-checks.
@@ -52,12 +52,12 @@
/*class: Class3b:*/
class Class3b {}
-/*strong.class: Class4a:checkedInstance*/
-/*omit.class: Class4a:*/
+/*spec:nnbd-off|spec:nnbd-sdk.class: Class4a:checkedInstance*/
+/*prod:nnbd-off.class: Class4a:*/
class Class4a<T> {}
-/*strong.class: Class4b:checkedInstance*/
-/*omit.class: Class4b:*/
+/*spec:nnbd-off|spec:nnbd-sdk.class: Class4b:checkedInstance*/
+/*prod:nnbd-off.class: Class4b:*/
class Class4b<T> {}
// Checks are needed both with and without --omit-implicit-checks.
diff --git a/tests/compiler/dart2js/rti/emission/runtime_type_instantiate_to_string1.dart b/tests/compiler/dart2js/rti/emission/runtime_type_instantiate_to_string1.dart
index 668a859..bddb58e 100644
--- a/tests/compiler/dart2js/rti/emission/runtime_type_instantiate_to_string1.dart
+++ b/tests/compiler/dart2js/rti/emission/runtime_type_instantiate_to_string1.dart
@@ -5,8 +5,8 @@
// @dart = 2.7
main() {
- /*strong.checks=[$signature],instance*/
- /*omit.checks=[],instance*/
+ /*spec:nnbd-off|spec:nnbd-sdk.checks=[$signature],instance*/
+ /*prod:nnbd-off|prod:nnbd-sdk.checks=[],instance*/
T id<T>(T t) => t;
int Function(int) x = id;
print("${x.runtimeType}");
diff --git a/tests/compiler/dart2js/rti/emission/static_argument.dart b/tests/compiler/dart2js/rti/emission/static_argument.dart
index 4230400..3730ece 100644
--- a/tests/compiler/dart2js/rti/emission/static_argument.dart
+++ b/tests/compiler/dart2js/rti/emission/static_argument.dart
@@ -4,19 +4,18 @@
// @dart = 2.7
-/*strong.class: I1:*/
-/*omit.class: I1:*/
+/*spec:nnbd-off|prod:nnbd-off.class: I1:*/
class I1 {}
-/*strong.class: I2:checkedInstance*/
+/*spec:nnbd-off|spec:nnbd-sdk.class: I2:checkedInstance*/
class I2 {}
-/*strong.class: A:checks=[$isI2],instance*/
-/*omit.class: A:checks=[],instance*/
+/*spec:nnbd-off|spec:nnbd-sdk.class: A:checks=[$isI2],instance*/
+/*prod:nnbd-off|prod:nnbd-sdk.class: A:checks=[],instance*/
class A implements I1, I2 {}
-/*strong.class: B:checks=[$isI2],instance*/
-/*omit.class: B:checks=[],instance*/
+/*spec:nnbd-off|spec:nnbd-sdk.class: B:checks=[$isI2],instance*/
+/*prod:nnbd-off|prod:nnbd-sdk.class: B:checks=[],instance*/
class B implements I1, I2 {}
@pragma('dart2js:noInline')
diff --git a/tests/compiler/dart2js/rti/emission/subtype_named_args.dart b/tests/compiler/dart2js/rti/emission/subtype_named_args.dart
index def20ab..9478512 100644
--- a/tests/compiler/dart2js/rti/emission/subtype_named_args.dart
+++ b/tests/compiler/dart2js/rti/emission/subtype_named_args.dart
@@ -8,32 +8,32 @@
import 'package:expect/expect.dart';
-/*strong.class: A:checkedInstance,checkedTypeArgument,checks=[],typeArgument*/
-/*omit.class: A:checkedTypeArgument,checks=[],typeArgument*/
+/*spec:nnbd-off|spec:nnbd-sdk.class: A:checkedInstance,checkedTypeArgument,checks=[],typeArgument*/
+/*prod:nnbd-off|prod:nnbd-sdk.class: A:checkedTypeArgument,checks=[],typeArgument*/
class A {}
-/*strong.class: A1:checkedInstance,checkedTypeArgument,checks=[],typeArgument*/
-/*omit.class: A1:checkedTypeArgument,checks=[],typeArgument*/
+/*spec:nnbd-off|spec:nnbd-sdk.class: A1:checkedInstance,checkedTypeArgument,checks=[],typeArgument*/
+/*prod:nnbd-off|prod:nnbd-sdk.class: A1:checkedTypeArgument,checks=[],typeArgument*/
class A1 {}
-/*strong.class: A2:checkedInstance,checkedTypeArgument,checks=[],typeArgument*/
-/*omit.class: A2:checkedTypeArgument,checks=[],typeArgument*/
+/*spec:nnbd-off|spec:nnbd-sdk.class: A2:checkedInstance,checkedTypeArgument,checks=[],typeArgument*/
+/*prod:nnbd-off|prod:nnbd-sdk.class: A2:checkedTypeArgument,checks=[],typeArgument*/
class A2 {}
-/*strong.class: B:checkedInstance,checkedTypeArgument,checks=[$isA,$isA1,$isA2],typeArgument*/
-/*omit.class: B:checkedTypeArgument,checks=[$isA,$isA1,$isA2],typeArgument*/
+/*spec:nnbd-off|spec:nnbd-sdk.class: B:checkedInstance,checkedTypeArgument,checks=[$isA,$isA1,$isA2],typeArgument*/
+/*prod:nnbd-off|prod:nnbd-sdk.class: B:checkedTypeArgument,checks=[$isA,$isA1,$isA2],typeArgument*/
class B implements A, A1, A2 {}
-/*strong.class: C:checkedInstance,checkedTypeArgument,checks=[$isA,$isA1,$isA2,$isB],typeArgument*/
-/*omit.class: C:checkedTypeArgument,checks=[$isA,$isA1,$isA2,$isB],typeArgument*/
+/*spec:nnbd-off|spec:nnbd-sdk.class: C:checkedInstance,checkedTypeArgument,checks=[$isA,$isA1,$isA2,$isB],typeArgument*/
+/*prod:nnbd-off|prod:nnbd-sdk.class: C:checkedTypeArgument,checks=[$isA,$isA1,$isA2,$isB],typeArgument*/
class C implements B {}
-/*strong.class: D:checkedInstance,checkedTypeArgument,checks=[$isA,$isA1,$isA2,$isB,$isC],typeArgument*/
-/*omit.class: D:checkedTypeArgument,checks=[$isA,$isA1,$isA2,$isB,$isC],typeArgument*/
+/*spec:nnbd-off|spec:nnbd-sdk.class: D:checkedInstance,checkedTypeArgument,checks=[$isA,$isA1,$isA2,$isB,$isC],typeArgument*/
+/*prod:nnbd-off|prod:nnbd-sdk.class: D:checkedTypeArgument,checks=[$isA,$isA1,$isA2,$isB,$isC],typeArgument*/
class D implements C {}
-/*strong.class: G:checkedInstance,checkedTypeArgument,checks=[],typeArgument*/
-/*omit.class: G:checkedTypeArgument,checks=[],typeArgument*/
+/*spec:nnbd-off|spec:nnbd-sdk.class: G:checkedInstance,checkedTypeArgument,checks=[],typeArgument*/
+/*prod:nnbd-off|prod:nnbd-sdk.class: G:checkedTypeArgument,checks=[],typeArgument*/
class G<T, S, U, W> {}
typedef classesFunc({A a, B b, C c, D d});
@@ -55,23 +55,23 @@
main() {
Expect.isTrue(
- /*strong.checks=[$signature],instance*/
- /*omit.checks=[],instance*/
+ /*spec:nnbd-off|spec:nnbd-sdk.checks=[$signature],instance*/
+ /*prod:nnbd-off|prod:nnbd-sdk.checks=[],instance*/
({D a, B b, C c, A d}) {} is classesFunc);
Expect.isTrue(
/*checks=[$signature],instance*/
({A a, A b, A c, A d}) {} is classesFunc);
Expect.isTrue(
- /*strong.checks=[$signature],instance*/
- /*omit.checks=[],instance*/
+ /*spec:nnbd-off|spec:nnbd-sdk.checks=[$signature],instance*/
+ /*prod:nnbd-off|prod:nnbd-sdk.checks=[],instance*/
({D a, A1 b, A1 c, A1 d}) {} is classesFunc);
Expect.isTrue(
- /*strong.checks=[$signature],instance*/
- /*omit.checks=[],instance*/
+ /*spec:nnbd-off|spec:nnbd-sdk.checks=[$signature],instance*/
+ /*prod:nnbd-off|prod:nnbd-sdk.checks=[],instance*/
({D a, A2 b, A2 c, A2 d}) {} is classesFunc);
Expect.isTrue(
- /*strong.checks=[$signature],instance*/
- /*omit.checks=[],instance*/
+ /*spec:nnbd-off|spec:nnbd-sdk.checks=[$signature],instance*/
+ /*prod:nnbd-off|prod:nnbd-sdk.checks=[],instance*/
({D a, D b, D c, D d}) {} is classesFunc);
Expect.isTrue(
/*checks=[$signature],instance*/
@@ -83,8 +83,8 @@
({Map<num, num> m, List<List<A1>> l, G<A, A1, A1, A1> g}) {}
is genericsFunc);
Expect.isTrue(
- /*strong.checks=[$signature],instance*/
- /*omit.checks=[],instance*/
+ /*spec:nnbd-off|spec:nnbd-sdk.checks=[$signature],instance*/
+ /*prod:nnbd-off|prod:nnbd-sdk.checks=[],instance*/
({Map<int, int> m, List<List<D>> l, G<D, D, D, D> g}) {} is genericsFunc);
Expect.isTrue(
/*checks=[$signature],instance*/
@@ -94,12 +94,12 @@
({Object m, Object l, Object g}) {} is genericsFunc);
Expect.isTrue(
- /*strong.checks=[$signature],instance*/
- /*omit.checks=[],instance*/
+ /*spec:nnbd-off|spec:nnbd-sdk.checks=[$signature],instance*/
+ /*prod:nnbd-off|prod:nnbd-sdk.checks=[],instance*/
({A x, G y, mixFunc z, var v}) {} is dynamicFunc);
Expect.isTrue(
- /*strong.checks=[$signature],instance*/
- /*omit.checks=[],instance*/
+ /*spec:nnbd-off|spec:nnbd-sdk.checks=[$signature],instance*/
+ /*prod:nnbd-off|prod:nnbd-sdk.checks=[],instance*/
({int x, bool y, List<Map> z, classesFunc v}) {} is dynamicFunc);
Expect.isTrue(
diff --git a/tests/compiler/dart2js/rti/emission/tear_off_types.dart b/tests/compiler/dart2js/rti/emission/tear_off_types.dart
index 4381d93..7bf619c 100644
--- a/tests/compiler/dart2js/rti/emission/tear_off_types.dart
+++ b/tests/compiler/dart2js/rti/emission/tear_off_types.dart
@@ -36,12 +36,12 @@
@pragma('dart2js:noInline')
bool _test1(f) => f is A1<int> Function();
-/*strong.class: A2:checkedInstance,checkedTypeArgument,checks=[],typeArgument*/
-/*omit.class: A2:checkedTypeArgument,checks=[],typeArgument*/
+/*spec:nnbd-off|spec:nnbd-sdk.class: A2:checkedInstance,checkedTypeArgument,checks=[],typeArgument*/
+/*prod:nnbd-off|prod:nnbd-sdk.class: A2:checkedTypeArgument,checks=[],typeArgument*/
class A2<T> {}
-/*strong.class: B2:checkedInstance,checkedTypeArgument,checks=[],typeArgument*/
-/*omit.class: B2:checkedTypeArgument,checks=[],typeArgument*/
+/*spec:nnbd-off|spec:nnbd-sdk.class: B2:checkedInstance,checkedTypeArgument,checks=[],typeArgument*/
+/*prod:nnbd-off|prod:nnbd-sdk.class: B2:checkedTypeArgument,checks=[],typeArgument*/
class B2 extends A2<int> {}
@pragma('dart2js:noInline')
@@ -58,12 +58,12 @@
@pragma('dart2js:noInline')
bool _test2(f) => f is void Function(A2<int>);
-/*strong.class: A3:checkedInstance,checkedTypeArgument,checks=[],typeArgument*/
-/*omit.class: A3:checkedTypeArgument,checks=[],typeArgument*/
+/*spec:nnbd-off|spec:nnbd-sdk.class: A3:checkedInstance,checkedTypeArgument,checks=[],typeArgument*/
+/*prod:nnbd-off|prod:nnbd-sdk.class: A3:checkedTypeArgument,checks=[],typeArgument*/
class A3<T> {}
-/*strong.class: B3:checkedInstance,checkedTypeArgument,checks=[],typeArgument*/
-/*omit.class: B3:checkedTypeArgument,checks=[],typeArgument*/
+/*spec:nnbd-off|spec:nnbd-sdk.class: B3:checkedInstance,checkedTypeArgument,checks=[],typeArgument*/
+/*prod:nnbd-off|prod:nnbd-sdk.class: B3:checkedTypeArgument,checks=[],typeArgument*/
class B3 extends A3<int> {}
@pragma('dart3js:noInline')
diff --git a/tests/compiler/dart2js/static_type/data/marker.options b/tests/compiler/dart2js/static_type/data/marker.options
index 95c2117..12bfcee 100644
--- a/tests/compiler/dart2js/static_type/data/marker.options
+++ b/tests/compiler/dart2js/static_type/data/marker.options
@@ -1,2 +1,4 @@
-strong=tests/compiler/dart2js/static_type/static_type_test.dart
-omit=tests/compiler/dart2js/static_type/static_type_test.dart
\ No newline at end of file
+spec:nnbd-off=tests/compiler/dart2js/static_type/static_type_test.dart
+prod:nnbd-off=tests/compiler/dart2js/static_type/static_type_test.dart
+spec:nnbd-sdk=tests/compiler/dart2js/static_type/static_type_test.dart
+prod:nnbd-sdk=tests/compiler/dart2js/static_type/static_type_test.dart
\ No newline at end of file
diff --git a/tests/compiler/dart2js/static_type/static_type_test.dart b/tests/compiler/dart2js/static_type/static_type_test.dart
index 250f450..a2c679e 100644
--- a/tests/compiler/dart2js/static_type/static_type_test.dart
+++ b/tests/compiler/dart2js/static_type/static_type_test.dart
@@ -27,7 +27,7 @@
asyncTest(() async {
Directory dataDir = new Directory.fromUri(Platform.script.resolve('data'));
await checkTests(dataDir, new StaticTypeDataComputer(),
- args: args, testedConfigs: [strongConfig]);
+ args: args, testedConfigs: allSpecConfigs);
});
}
diff --git a/tests/compiler/dart2js/static_type/type_promotion_data/marker.options b/tests/compiler/dart2js/static_type/type_promotion_data/marker.options
index c280594..d745ddd 100644
--- a/tests/compiler/dart2js/static_type/type_promotion_data/marker.options
+++ b/tests/compiler/dart2js/static_type/type_promotion_data/marker.options
@@ -1,2 +1,4 @@
-strong=tests/compiler/dart2js/static_type/type_promotion_test.dart
-omit=tests/compiler/dart2js/static_type/type_promotion_test.dart
\ No newline at end of file
+spec:nnbd-off=tests/compiler/dart2js/static_type/type_promotion_test.dart
+prod:nnbd-off=tests/compiler/dart2js/static_type/type_promotion_test.dart
+spec:nnbd-sdk=tests/compiler/dart2js/static_type/type_promotion_test.dart
+prod:nnbd-sdk=tests/compiler/dart2js/static_type/type_promotion_test.dart
\ No newline at end of file
diff --git a/tests/compiler/dart2js_extra/regress/unused_generator_type_parameter_test.dart b/tests/compiler/dart2js_extra/regress/unused_generator_type_parameter_test.dart
new file mode 100644
index 0000000..65dba5b
--- /dev/null
+++ b/tests/compiler/dart2js_extra/regress/unused_generator_type_parameter_test.dart
@@ -0,0 +1,21 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// @dart = 2.7
+
+import "package:expect/expect.dart";
+
+class Foo<X> {
+ // T is unused, so can be erased, but that should not break anything. The
+ // generator should still have a header and a body since it needs to compute
+ // the return type.
+ Iterable<Set<X>> bar<T>() sync* {}
+}
+
+main() {
+ var f = Foo<String>();
+ var c = f.bar<int>();
+ Expect.isFalse(c.iterator is Iterator<Set<int>>);
+ Expect.isTrue(c.iterator is Iterator<Set<String>>);
+}
diff --git a/tests/language/async_star/await_for_test.dart b/tests/language/async_star/await_for_test.dart
index 13d8fc8..9f12002 100644
--- a/tests/language/async_star/await_for_test.dart
+++ b/tests/language/async_star/await_for_test.dart
@@ -24,7 +24,7 @@
test('simple stream, await', () {
f(Stream<int> s) async {
var r = 0;
- await for (var v in s) r += await Future.microtask(() => v);
+ await for (var v in s) r += await Future<int>.microtask(() => v);
return r;
}
@@ -57,7 +57,7 @@
test('simple stream, await, reyield', () {
f(Stream<int> s) async* {
var r = 0;
- await for (var v in s) yield r += await Future.microtask(() => v);
+ await for (var v in s) yield r += await Future<int>.microtask(() => v);
}
return expectList(f(mkStream(5)), [0, 1, 3, 6, 10]);
@@ -93,7 +93,7 @@
var r = 0;
await for (var i in mkStream(5)) {
await for (var j in mkStream(3)) {
- r += await Future.microtask(() => i * j);
+ r += await Future<int>.microtask(() => i * j);
}
}
return r;
@@ -108,9 +108,9 @@
f() async {
var r = 0;
await for (var i in mkStream(5)) {
- var ai = await Future.microtask(() => i);
+ var ai = await Future<int>.microtask(() => i);
await for (var j in mkStream(3)) {
- r += await Future.microtask(() => ai * j);
+ r += await Future<int>.microtask(() => ai * j);
}
}
return r;
@@ -136,7 +136,7 @@
f(Stream<int> s) async {
var r = 0;
await for (var i in s) {
- r += await Future.delayed(ms * 10, () => i);
+ r += await Future<int>.delayed(ms * 10, () => i);
}
return r;
}
diff --git a/tests/language/constructor/constructor12_lib.dart b/tests/language/constructor/constructor12_lib.dart
new file mode 100644
index 0000000..70dfe76
--- /dev/null
+++ b/tests/language/constructor/constructor12_lib.dart
@@ -0,0 +1,40 @@
+// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// TODO(nshahan) Merge back into constructor12_test.dart along with the
+// expectation from constructor12_strong_test.dart after ending support for weak
+// mode.
+
+class B {
+ final z;
+ B(this.z);
+
+ foo() => this.z;
+}
+
+class A<T> extends B {
+ var captured, captured2;
+ var typedList;
+
+ // p must be inside a box (in dart2js).
+ A(p)
+ : captured = (() => p),
+ super(p++) {
+ // Make constructor body non-inlinable.
+ try {} catch (e) {}
+
+ captured2 = () => p++;
+
+ // In the current implementation of dart2js makes the generic type an
+ // argument to the body.
+ typedList = <T>[];
+ }
+
+ foo() => captured();
+ bar() => captured2();
+}
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(x) => x;
diff --git a/tests/language/constructor/constructor12_strong_test.dart b/tests/language/constructor/constructor12_strong_test.dart
new file mode 100644
index 0000000..bcc2672
--- /dev/null
+++ b/tests/language/constructor/constructor12_strong_test.dart
@@ -0,0 +1,17 @@
+// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Requirements=nnbd-strong
+
+// Copied from constructor12_test.dart to break out a single expectation that
+// is different in weak and strong modes.
+
+import "package:expect/expect.dart";
+
+import 'constructor12_lib.dart';
+
+main() {
+ var a2 = confuse(new A(2));
+ Expect.isFalse(a2 is A<Object>);
+}
diff --git a/tests/language/constructor/constructor12_test.dart b/tests/language/constructor/constructor12_test.dart
index 477955c..2af0ed2 100644
--- a/tests/language/constructor/constructor12_test.dart
+++ b/tests/language/constructor/constructor12_test.dart
@@ -4,38 +4,7 @@
import "package:expect/expect.dart";
-class B {
- final z;
- B(this.z);
-
- foo() => this.z;
-}
-
-class A<T> extends B {
- var captured, captured2;
- var typedList;
-
- // p must be inside a box (in dart2js).
- A(p)
- : captured = (() => p),
- super(p++) {
- // Make constructor body non-inlinable.
- try {} catch (e) {}
-
- captured2 = () => p++;
-
- // In the current implementation of dart2js makes the generic type an
- // argument to the body.
- typedList = <T>[];
- }
-
- foo() => captured();
- bar() => captured2();
-}
-
-@pragma('dart2js:noInline')
-@pragma('dart2js:assumeDynamic')
-confuse(x) => x;
+import 'constructor12_lib.dart';
main() {
var a = confuse(new A<int>(1));
@@ -51,7 +20,9 @@
Expect.isFalse(a is A<String>);
Expect.isFalse(a2 is A<int>);
Expect.isFalse(a2 is A<String>);
- Expect.isFalse(a2 is A<Object>);
+ // TODO(nshahan) Move back from constructor12_strong_test.dart after ending
+ // support for weak mode.
+ // Expect.isFalse(a2 is A<Object>);
Expect.isTrue(a2 is A<Object?>);
Expect.equals(2, a.bar());
Expect.equals(3, a2.bar());
diff --git a/tests/language/constructor/constructor12_weak_test.dart b/tests/language/constructor/constructor12_weak_test.dart
new file mode 100644
index 0000000..2a4d2f6
--- /dev/null
+++ b/tests/language/constructor/constructor12_weak_test.dart
@@ -0,0 +1,18 @@
+// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Requirements=nnbd-weak
+
+// Copied from constructor12_test.dart to break out a single expectation that
+// is different in weak and strong modes.
+
+import "package:expect/expect.dart";
+
+import 'constructor12_lib.dart';
+
+main() {
+ var a2 = confuse(new A(2));
+ // Only true in weak mode.
+ Expect.isTrue(a2 is A<Object>);
+}
diff --git a/tests/language/control_flow_collections/for_dynamic_null_weak_test.dart b/tests/language/control_flow_collections/for_dynamic_null_weak_test.dart
index 0337e9c..5904782 100644
--- a/tests/language/control_flow_collections/for_dynamic_null_weak_test.dart
+++ b/tests/language/control_flow_collections/for_dynamic_null_weak_test.dart
@@ -14,8 +14,10 @@
// Null iterable.
dynamic nullIterable = null;
- Expect.throwsAssertionError(() => <int>[for (var i in nullIterable) 1]);
- Expect.throwsAssertionError(
- () => <int, int>{for (var i in nullIterable) 1: 1});
- Expect.throwsAssertionError(() => <int>{for (var i in nullIterable) 1});
+ // The current behavior is inconsistent across the backends. The VM currently
+ // tries calling .iterable and throws a NoSuchMethodError. DDC throws a
+ // TypeError.
+ Expect.throws(() => <int>[for (var i in nullIterable) 1]);
+ Expect.throws(() => <int, int>{for (var i in nullIterable) 1: 1});
+ Expect.throws(() => <int>{for (var i in nullIterable) 1});
}
diff --git a/tests/language/dynamic_type_helper.dart b/tests/language/dynamic_type_helper.dart
new file mode 100644
index 0000000..cb14450
--- /dev/null
+++ b/tests/language/dynamic_type_helper.dart
@@ -0,0 +1,36 @@
+// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library dynamic_type_helper;
+
+import 'package:expect/expect.dart';
+
+/// Checks that a dynamic type error is thrown when [f] is executed
+/// and [expectTypeError] is `true`.
+void testDynamicTypeError(bool expectTypeError, f(), [String? message]) {
+ if (expectTypeError) {
+ checkDynamicTypeError(f, message);
+ } else {
+ checkNoDynamicTypeError(f, message);
+ }
+}
+
+/// Checks that a dynamic type error is thrown when f is executed.
+void checkDynamicTypeError(f(), [String? message]) {
+ message = message != null ? ': $message' : '';
+ try {
+ f();
+ Expect.fail('Missing type error$message.');
+ } on TypeError catch (e) {}
+}
+
+/// Checks that no dynamic type error is thrown when [f] is executed.
+void checkNoDynamicTypeError(f(), [String? message]) {
+ message = message != null ? ': $message' : '';
+ try {
+ f();
+ } on TypeError catch (e) {
+ Expect.fail('Unexpected type error$message.');
+ }
+}
diff --git a/tests/language/function/apply_generic2_test.dart b/tests/language/function/apply_generic2_test.dart
new file mode 100644
index 0000000..d45117a
--- /dev/null
+++ b/tests/language/function/apply_generic2_test.dart
@@ -0,0 +1,47 @@
+// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+makeFn() {
+ return <T extends num>({T? a1, T? a2, T? a3, T? a4, T? a5}) {
+ return <T?>[a1, a2, a3, a4, a5];
+ };
+}
+
+staticFn<T extends num>({T? a1, T? a2, T? a3, T? a4, T? a5, T? xx}) {
+ return <T?>[a1, a2, a3, a4, a5, xx];
+}
+
+class CCC {
+ memberFn<T extends num>({T? a1, T? a2, T? a3, T? a4, T? a5, T? yy}) {
+ return <T?>[a1, a2, a3, a4, a5, yy];
+ }
+}
+
+check(a, b) {
+ print('a: $a\nb: $b');
+ Expect.equals(a.toString(), b.toString());
+}
+
+main() {
+ check('[null, 33, null, 11, 22, null]',
+ Function.apply(new CCC().memberFn, [], {#a4: 11, #a5: 22, #a2: 33}));
+
+ Expect.throwsTypeError(
+ () => Function.apply(new CCC().memberFn, [], {#a3: 'hi'}));
+
+ check('[11, 22, 33, null, null]',
+ Function.apply(makeFn(), [], {#a1: 11, #a2: 22, #a3: 33}));
+
+ check('[null, 33, null, 11, 22]',
+ Function.apply(makeFn(), [], {#a4: 11, #a5: 22, #a2: 33}));
+
+ Expect.throwsTypeError(() => Function.apply(makeFn(), [], {#a3: 'hi'}));
+
+ check('[null, 33, null, 11, 22, null]',
+ Function.apply(staticFn, [], {#a4: 11, #a5: 22, #a2: 33}));
+
+ Expect.throwsTypeError(() => Function.apply(staticFn, [], {#a3: 'hi'}));
+}
diff --git a/tests/language/function/apply_generic_test.dart b/tests/language/function/apply_generic_test.dart
new file mode 100644
index 0000000..4831e5d
--- /dev/null
+++ b/tests/language/function/apply_generic_test.dart
@@ -0,0 +1,64 @@
+// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+List<T?> staticFn<T>(
+ [T? a1, T? a2, T? a3, T? a4, T? a5, T? a6, T? a7, T? a8, T? a9, T? a10]) {
+ return <T?>[a1, a2, a3, a4, a5, a6, a7, a8, a9, a10];
+}
+
+class C<CT> {
+ List<T?> memberFn<T>(
+ [T? a1, T? a2, T? a3, T? a4, T? a5, T? a6, T? a7, T? a8, T? a9, T? a10]) {
+ return <T?>[a1, a2, a3, a4, a5, a6, a7, a8, a9, a10];
+ }
+
+ // Intercepted, e.g. on JSArray.
+ List<T?> map<T>(
+ [T? a1, T? a2, T? a3, T? a4, T? a5, T? a6, T? a7, T? a8, T? a9, T? a10]) {
+ return <T?>[a1, a2, a3, a4, a5, a6, a7, a8, a9, a10];
+ }
+}
+
+check(a, b) {
+ print('a: $a\nb: $b');
+ Expect.equals(a.toString(), b.toString());
+}
+
+main() {
+ check('[1, 2, 3, null, null, null, null, null, null, null]',
+ Function.apply(staticFn, [1, 2, 3]));
+
+ check('[1, 2, 3, 4, null, null, null, null, null, null]',
+ Function.apply(staticFn, [1, 2, 3, 4]));
+
+ check('[1, 2, 3, 4, 5, 6, 7, null, null, null]',
+ Function.apply(staticFn, [1, 2, 3, 4, 5, 6, 7]));
+
+ var o = new C<num>();
+ dynamic memberFn1 = o.map;
+
+ check('[1, 2, 3, null, null, null, null, null, null, null]',
+ Function.apply(memberFn1, [1, 2, 3]));
+
+ check('[1, 2, 3, 4, null, null, null, null, null, null]',
+ Function.apply(memberFn1, [1, 2, 3, 4]));
+
+ check('[1, 2, 3, 4, 5, 6, 7, null, null, null]',
+ Function.apply(memberFn1, [1, 2, 3, 4, 5, 6, 7]));
+
+ dynamic memberFn2 = o.memberFn;
+
+ check('[1, 2, 3, null, null, null, null, null, null, null]',
+ Function.apply(memberFn2, [1, 2, 3]));
+
+ check('[1, 2, 3, 4, null, null, null, null, null, null]',
+ Function.apply(memberFn2, [1, 2, 3, 4]));
+
+ check('[1, 2, 3, 4, 5, 6, 7, null, null, null]',
+ Function.apply(memberFn2, [1, 2, 3, 4, 5, 6, 7]));
+
+ // TODO(sra): Apply of instantiations
+}
diff --git a/tests/language/function/argument_test.dart b/tests/language/function/argument_test.dart
new file mode 100644
index 0000000..f56861a
--- /dev/null
+++ b/tests/language/function/argument_test.dart
@@ -0,0 +1,22 @@
+// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// Dart test for function passing.
+
+import "package:expect/expect.dart";
+
+class FunctionArgumentTest {
+ static testMe(Function f) {
+ return f();
+ }
+
+ static void testMain() {
+ Expect.equals(42, testMe(() {
+ return 42;
+ }));
+ }
+}
+
+main() {
+ FunctionArgumentTest.testMain();
+}
diff --git a/tests/language/function/call_generic_test.dart b/tests/language/function/call_generic_test.dart
new file mode 100644
index 0000000..de3b0bd
--- /dev/null
+++ b/tests/language/function/call_generic_test.dart
@@ -0,0 +1,83 @@
+// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// dart2jsOptions=-Ddart.isdart2js=true
+
+import "package:expect/expect.dart";
+
+@pragma('dart2js:noInline')
+List staticFn<T>([T? a1, T? a2, T? a3, T? a4, T? a5]) => [T, a1, a2, a3, a4, a5];
+
+class C {
+ @pragma('dart2js:noInline')
+ List memberFn<T>([T? a1, T? a2, T? a3, T? a4, T? a5]) => [T, a1, a2, a3, a4, a5];
+
+ @pragma('dart2js:noInline')
+ // 'map' is implemented by native iterables. On dart2js, 'map' has interceptor
+ // calling convention.
+ List map<T>([T? a1, T? a2, T? a3, T? a4, T? a5]) => [T, a1, a2, a3, a4, a5];
+}
+
+check(expected, actual) {
+ print('a: $expected');
+ print('b: $actual');
+ if (((actual[0] == Object && expected[0] == dynamic) ||
+ (actual[0] == dynamic && expected[0] == Object)) &&
+ !const bool.fromEnvironment('dart.isdart2js')) {
+ // TODO(32483): dartdevk sometimes defaults type to 'Object' when 'dynamic'
+ // is required. Remove this hack when fixed.
+ // TODO(31581): dart2js needs instantiate-to-bound to generic 'dynamic'
+ // instead of 'Object'.
+ actual = actual.toList()..[0] = expected[0];
+ print('b*: $actual');
+ }
+ Expect.equals(expected.toString(), actual.toString());
+}
+
+main() {
+ check([dynamic, 1, 2, 3, null, null], staticFn(1 as dynamic, 2, 3));
+
+ check([Object, 'Z', 2, 4, null, null], staticFn('Z', 2, 4));
+
+ check([int, 3, 2, 1, null, null], staticFn(3, 2, 1));
+
+ dynamic f1 = staticFn;
+
+ check([dynamic, 4, 2, 3, null, null], f1(4 as dynamic, 2, 3));
+
+ check([dynamic, 'Q', 2, 3, null, null], f1('Q', 2, 3));
+
+ check([dynamic, 6, 2, 3, null, null], f1(6, 2, 3));
+
+ check([int, 7, 2, null, null, null], f1<int>(7, 2));
+
+ var c = new C();
+
+ check([dynamic, 8, 2, 3, null, null], c.memberFn(8 as dynamic, 2, 3));
+
+ check([Object, 'A', 2, 3, null, null], c.memberFn('A', 2, 3));
+
+ check([int, 9, 2, 3, null, null], c.memberFn<int>(9, 2, 3));
+
+ check([dynamic, 10, 2, 3, null, null], c.map(10 as dynamic, 2, 3));
+
+ check([Object, 'B', 2, 3, null, null], c.map('B', 2, 3));
+
+ check([int, 11, 2, 3, null, null], c.map(11, 2, 3));
+
+ dynamic o = new C();
+
+ check([dynamic, 12, 2, 3, null, null], o.memberFn(12 as dynamic, 2, 3));
+
+ check([dynamic, 'C', 2, 3, null, null], o.memberFn('C', 2, 3));
+
+ check([int, 13, 2, null, null, null], o.memberFn<int>(13, 2));
+
+ check([dynamic, 14, 2, 3, null, null], o.map(14 as dynamic, 2, 3));
+
+ check([dynamic, 'D', 2, 3, null, null], o.map('D', 2, 3));
+
+ check([int, 15, null, null, null, null], o.map<int>(15));
+
+ check([int, 16, 2, 3, 4, null], o.map<int>(16, 2, 3, 4));
+}
diff --git a/tests/language/function/field_test.dart b/tests/language/function/field_test.dart
new file mode 100644
index 0000000..099a11d
--- /dev/null
+++ b/tests/language/function/field_test.dart
@@ -0,0 +1,20 @@
+// 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.
+// VMOptions=--fatal-type-errors --enable_type_checks
+//
+// Test of calling Function, which is field of some class.
+
+import "package:expect/expect.dart";
+
+class Wrapper {
+ late Function f;
+}
+
+main() {
+ Wrapper w = new Wrapper();
+ w.f = () {
+ return 42;
+ };
+ Expect.equals(42, w.f());
+}
diff --git a/tests/language/function/function_test.dart b/tests/language/function/function_test.dart
new file mode 100644
index 0000000..201b8f1
--- /dev/null
+++ b/tests/language/function/function_test.dart
@@ -0,0 +1,378 @@
+// 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.
+
+import "package:expect/expect.dart";
+
+// Tests function statements and expressions.
+
+class Bug4089219 {
+ int x;
+ var f;
+
+ Bug4089219(int i) : this.x = i {
+ f = () => x;
+ }
+}
+
+class Bug4342163 {
+ final m;
+ Bug4342163(int a) : this.m = (() => a) {}
+}
+
+class StaticFunctionDef {
+ static const int one = 1;
+ static var fn1;
+ static var fn2;
+ static var fn3;
+
+ static init() {
+ fn1 = () {
+ return one;
+ };
+ fn2 = () {
+ return (() {
+ return one;
+ })();
+ };
+ fn3 = () {
+ final local = 1;
+ return (() {
+ return local;
+ })();
+ };
+ }
+}
+
+class A {
+ var ma;
+ A(a) {
+ ma = a;
+ }
+}
+
+class B1 extends A {
+ final mfn;
+ B1(int a)
+ : this.mfn = (() {
+ return a;
+ }),
+ super(a);
+}
+
+class B2 extends A {
+ final mfn;
+ B2(int a)
+ : this.mfn = (() {
+ return a;
+ }),
+ super(2);
+}
+
+class B3 extends A {
+ final mfn;
+ B3(int a)
+ : this.mfn = (() {
+ return a;
+ }),
+ super(() {
+ return a;
+ });
+}
+
+typedef void Fisk();
+
+class FunctionTest {
+ FunctionTest() {}
+
+ static void testMain() {
+ var test = new FunctionTest();
+ test.testForEach();
+ test.testVarOrder1();
+ test.testVarOrder2();
+ test.testLexicalClosureRef1();
+ test.testLexicalClosureRef2();
+ test.testLexicalClosureRef3();
+ test.testLexicalClosureRef4();
+ test.testLexicalClosureRef5();
+ test.testDefaultParametersOrder();
+ test.testParametersOrder();
+ test.testFunctionDefaults1();
+ test.testFunctionDefaults2();
+ test.testEscapingFunctions();
+ test.testThisBinding();
+ test.testFnBindingInStatics();
+ test.testFnBindingInInitLists();
+ test.testSubclassConstructorScopeAlias();
+ }
+
+ void testSubclassConstructorScopeAlias() {
+ var b1 = new B1(10);
+ Expect.equals(10, (b1.mfn)());
+ Expect.equals(10, b1.ma);
+
+ var b2 = new B2(11);
+ Expect.equals(11, (b2.mfn)());
+ Expect.equals(2, b2.ma);
+
+ var b3 = new B3(12);
+ Expect.equals(12, (b3.mfn)());
+ Expect.equals(12, (b3.ma)());
+ }
+
+ void testFnBindingInInitLists() {
+ Expect.equals(1, (new Bug4342163(1).m)());
+ }
+
+ void testFnBindingInStatics() {
+ StaticFunctionDef.init();
+ Expect.equals(1, ((StaticFunctionDef.fn1)()));
+ Expect.equals(1, ((StaticFunctionDef.fn2)()));
+ Expect.equals(1, ((StaticFunctionDef.fn3)()));
+ }
+
+ Fisk testReturnVoidFunction() {
+ void f() {}
+ Fisk x = f;
+ return f;
+ }
+
+ void testVarOrder1() {
+ var a = 0, b = a++, c = a++;
+
+ Expect.equals(a, 2);
+ Expect.equals(b, 0);
+ Expect.equals(c, 1);
+ }
+
+ void testVarOrder2() {
+ var a = 0;
+ f() {
+ return a++;
+ }
+
+ ;
+ var b = f(), c = f();
+
+ Expect.equals(a, 2);
+ Expect.equals(b, 0);
+ Expect.equals(c, 1);
+ }
+
+ void testLexicalClosureRef1() {
+ var a = 1;
+ var f, g;
+ {
+ var b = 2;
+ f = () {
+ return b - a;
+ };
+ }
+
+ {
+ var b = 3;
+ g = () {
+ return b - a;
+ };
+ }
+ Expect.equals(1, f());
+ Expect.equals(2, g());
+ }
+
+ void testLexicalClosureRef2() {
+ var a = 1;
+ var f, g;
+ {
+ var b = 2;
+ f = () {
+ return (() {
+ return b - a;
+ })();
+ };
+ }
+
+ {
+ var b = 3;
+ g = () {
+ return (() {
+ return b - a;
+ })();
+ };
+ }
+ Expect.equals(1, f());
+ Expect.equals(2, g());
+ }
+
+ void testLexicalClosureRef3() {
+ var a = [];
+ for (int i = 0; i < 10; i++) {
+ var x = i;
+ a.add(() {
+ return x;
+ });
+ }
+
+ var sum = 0;
+ for (int i = 0; i < a.length; i++) {
+ sum += (a[i])() as int;
+ }
+
+ Expect.equals(45, sum);
+ }
+
+ void testLexicalClosureRef5() {
+ {
+ var a;
+ Expect.equals(null, a);
+ a = 1;
+ Expect.equals(1, a);
+ }
+
+ {
+ var a;
+ Expect.equals(null, a);
+ a = 1;
+ Expect.equals(1, a);
+ }
+ }
+
+ // Make sure labels are preserved, and a second 'i' does influence the first.
+ void testLexicalClosureRef4() {
+ var a = [];
+ x:
+ for (int i = 0; i < 10; i++) {
+ a.add(() {
+ return i;
+ });
+ continue x;
+ }
+
+ var sum = 0;
+ for (int i = 0; i < a.length; i++) {
+ sum += (a[i])() as int;
+ }
+
+ Expect.equals(45, sum);
+ }
+
+ int tempField = -1;
+
+ void testForEach() {
+ List<int> vals = [1, 2, 3];
+ int total = 0;
+ vals.forEach((int v) {
+ total += v;
+ });
+ Expect.equals(6, total);
+ }
+
+ void testDefaultParametersOrder() {
+ f([a = 1, b = 3]) {
+ return a - b;
+ }
+
+ Expect.equals(-2, f());
+ }
+
+ void testParametersOrder() {
+ f(a, b) {
+ return a - b;
+ }
+
+ Expect.equals(-2, f(1, 3));
+ }
+
+ void testFunctionDefaults1() {
+ // TODO(jimhug): This return null shouldn't be necessary.
+ f() {
+ return null;
+ }
+
+ ;
+ (([a = 10]) {
+ Expect.equals(10, a);
+ })();
+ ((a, [b = 10]) {
+ Expect.equals(10, b);
+ })(1);
+ (([a = 10]) {
+ Expect.equals(null, a);
+ })(f());
+ // FAILS: (([a = 10]) { Expect.equals(null ,a); })( f() );
+ }
+
+ void testFunctionDefaults2() {
+ Expect.equals(10, helperFunctionDefaults2());
+ Expect.equals(1, helperFunctionDefaults2(1));
+ }
+
+ num helperFunctionDefaults2([a = 10]) {
+ return (() {
+ return a;
+ })();
+ }
+
+ void testEscapingFunctions() {
+ f() {
+ return 42;
+ }
+
+ ;
+ (() {
+ Expect.equals(42, f());
+ })();
+ var o = new Bug4089219(42);
+ Expect.equals(42, (o.f)());
+ }
+
+ void testThisBinding() {
+ Expect.equals(this, () {
+ return this;
+ }());
+ }
+}
+
+typedef void Foo<A, B>(A a, B b);
+
+class Bar<A, B> {
+ Foo<A, B> field;
+ Bar(A a, B b) : this.field = ((A a1, B b2) {}) {
+ field(a, b);
+ }
+}
+
+typedef UntypedFunction(arg);
+typedef UntypedFunction2(arg);
+
+class UseFunctionTypes {
+ void test() {
+ Function? f = null;
+ UntypedFunction? uf = null;
+ UntypedFunction2? uf2 = null;
+ Foo? foo = null;
+ Foo<int, String>? fooIntString = null;
+ Foo<Object, Object>? fooObjectObject = null;
+
+ f = uf;
+ f = uf2;
+ f = foo;
+ f = fooIntString;
+
+ uf = f as UntypedFunction?;
+ uf2 = f;
+ foo = f as Foo?;
+ fooIntString = f as Foo<int, String>?;
+
+ fooIntString = foo as Foo<int, String>?;
+
+ foo = fooObjectObject as Foo?;
+ fooObjectObject = foo as Foo<Object, Object>?;
+
+ uf = uf2;
+ uf2 = uf;
+ }
+}
+
+main() {
+ FunctionTest.testMain();
+}
diff --git a/tests/language/function/getter_test.dart b/tests/language/function/getter_test.dart
new file mode 100644
index 0000000..efc483e
--- /dev/null
+++ b/tests/language/function/getter_test.dart
@@ -0,0 +1,13 @@
+// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+class A {
+ a() => 42;
+}
+
+main() {
+ Expect.equals(new A().a(), (new A().a)());
+}
diff --git a/tests/language/function/literals2_test.dart b/tests/language/function/literals2_test.dart
new file mode 100644
index 0000000..2b5de44
--- /dev/null
+++ b/tests/language/function/literals2_test.dart
@@ -0,0 +1,113 @@
+// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+//
+// Dart test for new function type alias.
+
+import "package:expect/expect.dart";
+
+class FunctionLiteralsTest {
+ static void testMain() {
+ f(x) {
+ return x * 2;
+ }
+
+ f(42); // make sure it is parsed as a function call
+ Expect.equals(20, f(10));
+
+ int g(x) {
+ return x * 2;
+ }
+
+ g(42); // make sure it is parsed as a function call
+ Expect.equals(20, g(10));
+
+ h(x) {
+ return x * 2;
+ }
+
+ h(42); // make sure it is parsed as a function call
+ Expect.equals(20, h(10));
+
+ dynamic a = (x) {
+ return x + 2;
+ };
+ Expect.equals(7, a(5));
+
+ Expect.equals(
+ 10,
+ apply((k) {
+ return k << 1;
+ }, 5));
+ Expect.equals(20, apply((k) => k << 1, 10));
+
+ a = new A(3);
+ Expect.equals(-1, a.f);
+ Expect.equals(-3, a.f2);
+
+ a = new A.n(5);
+ Expect.equals(-2, a.f);
+ Expect.equals(2, a.f2);
+
+ Expect.equals(true, isOdd(5));
+ Expect.equals(false, isOdd(8));
+
+ var b = new B(10);
+ Expect.equals(10, b.n);
+ Expect.equals(100, (b.f)(10));
+
+ b = new B.withZ(10);
+ Expect.equals(10, b.n);
+ Expect.equals(101, (b.f)(10));
+
+ var c = new C(5);
+ Expect.equals("2*x is 10", c.s);
+
+ int x = 0;
+ int y = 1;
+ // make sure this isn't parsed as a generic type
+ Expect.isTrue(x < y, "foo");
+ }
+}
+
+int apply(f, n) {
+ return f(n) as int;
+}
+
+bool isOdd(b) => b % 2 == 1;
+
+class A {
+ int f = -1;
+ int f2 = -1;
+ A(p) : f = apply((j) => 2 - j, p) {
+ /* constr. body */
+ f2 = -p;
+ }
+ A.n(p) : f = 1 + apply((j) => 2 - j, p) {
+ /* constr. body */
+ f2 = -f;
+ }
+}
+
+class B {
+ var f;
+ int n = -1;
+ B(z) : f = ((x) => x * x) {
+ n = z;
+ }
+ B.withZ(z)
+ : f = ((x) {
+ return x * x + 1;
+ }) {
+ n = z;
+ }
+}
+
+class C {
+ String s;
+ C(x) : s = "2*x is ${() { return 2*x; }()}";
+}
+
+main() {
+ FunctionLiteralsTest.testMain();
+}
diff --git a/tests/language/function/literals_test.dart b/tests/language/function/literals_test.dart
new file mode 100644
index 0000000..e75ce3a
--- /dev/null
+++ b/tests/language/function/literals_test.dart
@@ -0,0 +1,112 @@
+// 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 various forms of function literals.
+ */
+typedef int IntFunc(int);
+
+class FunctionLiteralsTest {
+ static void checkIntFunction<T>(expected, int f(T x), arg) {
+ Expect.equals(expected, f(arg));
+ }
+
+ static void checkIntFuncFunction<T>(expected, IntFunc f(T x), arg) {
+ Expect.equals(expected, f(arg)(arg));
+ }
+
+ int func1(int x) => x;
+
+ int func2(x) => x;
+
+ int func3(int x) {
+ return x;
+ }
+
+ int func4(x) {
+ return x;
+ }
+
+ FunctionLiteralsTest() {}
+
+ static void testMain() {
+ var test = new FunctionLiteralsTest();
+ test.testArrow();
+ test.testArrowArrow();
+ test.testArrowBlock();
+ test.testBlock();
+ test.testBlockArrow();
+ test.testBlockBlock();
+ test.testFunctionRef();
+ }
+
+ void testArrow() {
+ checkIntFunction(42, (x) => x as int, 42);
+ checkIntFunction(42, (dynamic x) => x, 42);
+ }
+
+ void testArrowArrow() {
+ checkIntFuncFunction(84, (x) => (y) => (x as int) + (y as int), 42);
+ checkIntFuncFunction(84, (dynamic x) => (y) => x + y, 42);
+ }
+
+ void testArrowBlock() {
+ checkIntFuncFunction(
+ 84,
+ (x) => (y) {
+ return (x as int) + (y as int);
+ },
+ 42);
+ checkIntFuncFunction(
+ 84,
+ (int x) => (y) {
+ return (x + y) as int;
+ },
+ 42);
+ }
+
+ void testBlock() {
+ checkIntFunction(42, (x) {
+ return x as int;
+ }, 42);
+ checkIntFunction(42, (int x) {
+ return x;
+ }, 42);
+ }
+
+ void testBlockArrow() {
+ checkIntFuncFunction(84, (x) {
+ return (y) => (x as int) + (y as int);
+ }, 42);
+ checkIntFuncFunction(84, (int x) {
+ return (y) => (x + y) as int;
+ }, 42);
+ }
+
+ void testBlockBlock() {
+ checkIntFuncFunction(84, (x) {
+ return (y) {
+ return (x as int) + (y as int);
+ };
+ }, 42);
+ checkIntFuncFunction(84, (int x) {
+ return (y) {
+ return (x + y) as int;
+ };
+ }, 42);
+ }
+
+ void testFunctionRef() {
+ checkIntFunction(42, func1, 42);
+ checkIntFunction(42, func2, 42);
+ checkIntFunction(42, func3, 42);
+ checkIntFunction(42, func4, 42);
+ }
+}
+
+main() {
+ FunctionLiteralsTest.testMain();
+}
diff --git a/tests/language/function/local2_test.dart b/tests/language/function/local2_test.dart
new file mode 100644
index 0000000..44d2ef9
--- /dev/null
+++ b/tests/language/function/local2_test.dart
@@ -0,0 +1,45 @@
+// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// Dart test program testing closures.
+
+import "package:expect/expect.dart";
+
+typedef T F<T>(T t);
+
+class Parameterized<T> {
+ Parameterized() {}
+ T mul3(F<T> f, T t) {
+ return (3 as dynamic) * f(t);
+ }
+
+ T test(T t) {
+ return mul3((T t) {
+ return (3 as dynamic) * t;
+ }, t);
+ }
+}
+
+class LocalFunction2Test {
+ static int f(int n) {
+ int a = 0;
+ var g = (int n) {
+ a += n;
+ return a;
+ };
+ var h = (int n) {
+ a += 10 * n;
+ return a;
+ };
+ return g(n) + h(n);
+ }
+
+ static testMain() {
+ Expect.equals(3 + 33, f(3));
+ Expect.equals(9.0, new Parameterized<double>().test(1.0));
+ }
+}
+
+main() {
+ LocalFunction2Test.testMain();
+}
diff --git a/tests/language/function/local3_test.dart b/tests/language/function/local3_test.dart
new file mode 100644
index 0000000..46c3284
--- /dev/null
+++ b/tests/language/function/local3_test.dart
@@ -0,0 +1,39 @@
+// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// Dart test program testing closures.
+
+import "package:expect/expect.dart";
+
+class LocalFunction3Test {
+ static testExceptions() {
+ dynamic f = (int n) {
+ return n + 1;
+ };
+ Expect.equals(true, f is Object);
+ bool exception_caught = false;
+ try {
+ f.xyz(0);
+ } on NoSuchMethodError {
+ exception_caught = true;
+ }
+ Expect.equals(true, exception_caught);
+ exception_caught = false;
+ String f_string = "";
+ try {
+ f_string = f.toString();
+ } on NoSuchMethodError {
+ exception_caught = true;
+ }
+ Expect.equals(false, exception_caught);
+ Expect.equals(true, f_string.startsWith("Closure"));
+ }
+
+ static testMain() {
+ testExceptions();
+ }
+}
+
+main() {
+ LocalFunction3Test.testMain();
+}
diff --git a/tests/language/function/local_function_test.dart b/tests/language/function/local_function_test.dart
new file mode 100644
index 0000000..4ed1bff
--- /dev/null
+++ b/tests/language/function/local_function_test.dart
@@ -0,0 +1,227 @@
+// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// Dart test program testing closures.
+
+import "package:expect/expect.dart";
+
+class LocalFunctionTest {
+ LocalFunctionTest()
+ : field1 = 100,
+ field2_ = 200 {}
+ static int f(int n) {
+ int a = 0;
+ g(int m) {
+ a = 3 * n + m + 1; // Capture parameter n and local a.
+ return a;
+ }
+
+ var b = g(n);
+ return a + b;
+ }
+
+ static int h(int n) {
+ k(int n) {
+ var a = new List<dynamic>.filled(n, null);
+ var b = new List<dynamic>.filled(n, null);
+ int i;
+ for (i = 0; i < n; i++) {
+ var j = i;
+ a[i] = () => i; // Captured i is always n.
+ b[i] = () => j; // Captured j varies from 0 to n-1.
+ }
+ var a_sum = 0;
+ var b_sum = 0;
+ for (int i = 0; i < n; i++) {
+ a_sum += a[i]() as int;
+ b_sum += b[i]() as int;
+ }
+ return a_sum + b_sum;
+ }
+
+ return k(n);
+ }
+
+ static int h2(int n) {
+ k(int n) {
+ var a = new List<dynamic>.filled(n, null);
+ var b = new List<dynamic>.filled(n, null);
+ for (int i = 0; i < n; i++) {
+ var j = i;
+ a[i] = () => i; // Captured i varies from 0 to n-1.
+ b[i] = () => j; // Captured j varies from 0 to n-1.
+ }
+ var a_sum = 0;
+ var b_sum = 0;
+ for (int i = 0; i < n; i++) {
+ a_sum += a[i]() as int;
+ b_sum += b[i]() as int;
+ }
+ return a_sum + b_sum;
+ }
+
+ return k(n);
+ }
+
+ int field1;
+ int field2_;
+ int get field2 {
+ return field2_;
+ }
+
+ void set field2(int value) {
+ field2_ = value;
+ }
+
+ int method(int n) {
+ incField1() {
+ field1++;
+ }
+
+ incField2() {
+ field2++;
+ }
+
+ for (int i = 0; i < n; i++) {
+ incField1();
+ incField2();
+ }
+ return field1 + field2;
+ }
+
+ int execute(int times, apply(int x)) {
+ for (int i = 0; i < times; i++) {
+ apply(i);
+ }
+ return field1;
+ }
+
+ int testExecute(int n) {
+ execute(n, (int x) {
+ field1 += x;
+ });
+ return field1;
+ }
+
+ static int foo(int n) {
+ return -100; // Wrong foo.
+ }
+
+ static testSelfReference1(int n) {
+ int foo(int n) {
+ if (n == 0) {
+ return 0;
+ } else {
+ return 1 + foo(n - 1); // Local foo, not static foo.
+ }
+ }
+
+ ;
+ return foo(n); // Local foo, not static foo.
+ }
+
+ static void hep(Function f) {
+ f();
+ }
+
+ static testNesting(int n) {
+ var a = new List<dynamic>.filled(n * n, null);
+ f0() {
+ for (int i = 0; i < n; i++) {
+ int vi = i;
+ f1() {
+ for (int j = 0; j < n; j++) {
+ int vj = j;
+ a[i * n + j] = () => vi * n + vj;
+ }
+ }
+
+ f1();
+ }
+ }
+
+ f0();
+ int result = 0;
+ for (int k = 0; k < n * n; k++) {
+ Expect.equals(k, a[k]());
+ result += a[k]() as int;
+ }
+ return result;
+ }
+
+ static var field5;
+ static var set_field5_func;
+ static testClosureCallStatement(int x) {
+ LocalFunctionTest.set_field5_func = (int n) {
+ field5 = n * n;
+ };
+ (LocalFunctionTest.set_field5_func)(x);
+ Expect.equals(x * x, LocalFunctionTest.field5);
+ return true;
+ }
+
+ static testExceptions() {
+ dynamic f = (int n) => n + 1;
+ Expect.equals(2, f(1));
+ Expect.equals(true, f is Function);
+ Expect.equals(true, f is Object);
+ Expect.equals(true, f.toString().startsWith("Closure"));
+ bool exception_caught = false;
+ try {
+ f(1, 2);
+ } on NoSuchMethodError catch (e) {
+ exception_caught = true;
+ }
+ Expect.equals(true, exception_caught);
+ exception_caught = false;
+ try {
+ f();
+ } on NoSuchMethodError catch (e) {
+ exception_caught = true;
+ }
+ Expect.equals(true, exception_caught);
+ exception_caught = false;
+ try {
+ f.xyz(0);
+ } on NoSuchMethodError catch (e) {
+ exception_caught = true;
+ }
+ Expect.equals(true, exception_caught);
+
+ // Overwrite closure value.
+ f = 3;
+ exception_caught = false;
+ try {
+ f(1);
+ } on NoSuchMethodError catch (e) {
+ exception_caught = true;
+ }
+ Expect.equals(true, exception_caught);
+
+ // Do not expect any exceptions to be thrown.
+ var g = ([int n = 1]) => n + 1;
+ Expect.equals(2, g());
+ Expect.equals(3, g(2));
+ }
+
+ static int doThis(int n, int f(int n)) {
+ return f(n);
+ }
+
+ static testMain() {
+ Expect.equals(2 * (3 * 2 + 2 + 1), f(2));
+ Expect.equals(10 * 10 + 10 * 9 / 2, h(10));
+ Expect.equals(90, h2(10));
+ Expect.equals(320, new LocalFunctionTest().method(10));
+ Expect.equals(145, new LocalFunctionTest().testExecute(10));
+ Expect.equals(5, testSelfReference1(5));
+ Expect.equals(24 * 25 / 2, testNesting(5));
+ Expect.equals(true, testClosureCallStatement(7));
+ Expect.equals(99, doThis(10, (n) => n * n - 1));
+ testExceptions();
+ }
+}
+
+main() {
+ LocalFunctionTest.testMain();
+}
diff --git a/tests/language/function/local_non_equal_test.dart b/tests/language/function/local_non_equal_test.dart
new file mode 100644
index 0000000..5fbaf57
--- /dev/null
+++ b/tests/language/function/local_non_equal_test.dart
@@ -0,0 +1,33 @@
+// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+foo() => () => 42;
+bar() {
+ var c = () => 54;
+ return c;
+}
+
+baz() {
+ c() => 68;
+ return c;
+}
+
+main() {
+ var first = foo();
+ var second = foo();
+ Expect.isFalse(identical(first, second));
+ Expect.notEquals(first, second);
+
+ first = bar();
+ second = bar();
+ Expect.isFalse(identical(first, second));
+ Expect.notEquals(first, second);
+
+ first = baz();
+ second = baz();
+ Expect.isFalse(identical(first, second));
+ Expect.notEquals(first, second);
+}
diff --git a/tests/language/function/malformed_result_type_runtime_test.dart b/tests/language/function/malformed_result_type_runtime_test.dart
new file mode 100644
index 0000000..02b26b4
--- /dev/null
+++ b/tests/language/function/malformed_result_type_runtime_test.dart
@@ -0,0 +1,16 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// 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 for a function with a malformed result type.
+
+import "package:expect/expect.dart";
+
+class C<T, U> {}
+
+main() {
+
+}
diff --git a/tests/language/function/malformed_result_type_test.dart b/tests/language/function/malformed_result_type_test.dart
new file mode 100644
index 0000000..182258b
--- /dev/null
+++ b/tests/language/function/malformed_result_type_test.dart
@@ -0,0 +1,16 @@
+// 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 for a function with a malformed result type.
+
+import "package:expect/expect.dart";
+
+class C<T, U> {}
+
+main() {
+ C<int> f() => throw "uncalled";
+//^^^^^^
+// [analyzer] STATIC_TYPE_WARNING.WRONG_NUMBER_OF_TYPE_ARGUMENTS
+// [cfe] Expected 2 type arguments.
+}
diff --git a/tests/language/function/propagation_test.dart b/tests/language/function/propagation_test.dart
new file mode 100644
index 0000000..9c6f7e6
--- /dev/null
+++ b/tests/language/function/propagation_test.dart
@@ -0,0 +1,23 @@
+// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+class A {
+ int call(String str) => 499;
+}
+
+typedef int F(String str);
+
+main() {
+ var a = new A();
+ Expect.type<A>(a);
+ Expect.notType<F>(a);
+
+ Function a3 = new A();
+ Expect.notType<A>(a3);
+
+ F a4 = new A();
+ Expect.notType<A>(a4);
+}
diff --git a/tests/language/function/syntax_test.dart b/tests/language/function/syntax_test.dart
new file mode 100644
index 0000000..3baf2df
--- /dev/null
+++ b/tests/language/function/syntax_test.dart
@@ -0,0 +1,733 @@
+// 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.
+
+import "package:expect/expect.dart";
+
+// Tests function statement and expression syntax.
+
+class FunctionSyntaxTest {
+ static void testMain
+/* //# 00: syntax error
+ ()
+*/ //# 00: continued
+ {
+ testNestedFunctions();
+ testFunctionExpressions();
+ testPrecedence();
+ testInitializers();
+ testFunctionParameter();
+ testFunctionIdentifierExpression();
+ testFunctionIdentifierStatement();
+ }
+
+ static void testNestedFunctions
+/* //# 01: syntax error
+ ()
+*/ //# 01: continued
+ {
+ // No types - braces.
+ nb0
+/* //# 02: syntax error
+ ()
+*/ //# 02: continued
+ {
+ return 42;
+ }
+
+ nb1
+/* //# 03: syntax error
+ (a)
+*/ //# 03: continued
+ {
+ return a;
+ }
+
+ nb2
+/* //# 04: syntax error
+ (a, b)
+*/ //# 04: continued
+ {
+ return a + b;
+ }
+
+ Expect.equals(42, nb0());
+ Expect.equals(87, nb1(87));
+ Expect.equals(1 + 2, nb2(1, 2));
+
+ // No types - arrows.
+ na0
+/* //# 05: syntax error
+ ()
+*/ //# 05: continued
+ =>
+ 42;
+ na1
+/* //# 06: syntax error
+ (a)
+*/ //# 06: continued
+ =>
+ a;
+ na2
+/* //# 07: syntax error
+ (a, b)
+*/ //# 07: continued
+ =>
+ a + b;
+ Expect.equals(42, na0());
+ Expect.equals(87, na1(87));
+ Expect.equals(1 + 2, na2(1, 2));
+
+ // Return type - braces.
+ int rb0
+/* //# 08: syntax error
+ ()
+*/ //# 08: continued
+ {
+ return 42;
+ }
+
+ int rb1
+/* //# 09: syntax error
+ (a)
+*/ //# 09: continued
+ {
+ return a;
+ }
+
+ int rb2
+/* //# 10: syntax error
+ (a, b)
+*/ //# 10: continued
+ {
+ return a + b;
+ }
+
+ Expect.equals(42, rb0());
+ Expect.equals(87, rb1(87));
+ Expect.equals(1 + 2, rb2(1, 2));
+
+ // Return type - arrows.
+ int ra0
+/* //# 11: syntax error
+ ()
+*/ //# 11: continued
+ =>
+ 42;
+ int ra1
+/* //# 12: syntax error
+ (a)
+*/ //# 12: continued
+ =>
+ a;
+ int ra2
+/* //# 13: syntax error
+ (a, b)
+*/ //# 13: continued
+ =>
+ a + b;
+ Expect.equals(42, ra0());
+ Expect.equals(87, ra1(87));
+ Expect.equals(1 + 2, ra2(1, 2));
+
+ // Fully typed - braces.
+ int fb1
+/* //# 14: syntax error
+ (int a)
+*/ //# 14: continued
+ {
+ return a;
+ }
+
+ int fb2
+/* //# 15: syntax error
+ (int a, int b)
+*/ //# 15: continued
+ {
+ return a + b;
+ }
+
+ Expect.equals(42, rb0());
+ Expect.equals(87, rb1(87));
+ Expect.equals(1 + 2, rb2(1, 2));
+
+ // Fully typed - arrows.
+ int fa1
+/* //# 16: syntax error
+ (int a)
+*/ //# 16: continued
+ =>
+ a;
+ int fa2
+/* //# 17: syntax error
+ (int a, int b)
+*/ //# 17: continued
+ =>
+ a + b;
+ Expect.equals(42, ra0());
+ Expect.equals(87, ra1(87));
+ Expect.equals(1 + 2, ra2(1, 2));
+
+ // Generic types - braces.
+ List<int> gb0
+/* //# 18: syntax error
+ ()
+*/ //# 18: continued
+ {
+ return [42];
+ }
+
+ List<int> gb1
+/* //# 19: syntax error
+ (List<int> a)
+*/ //# 19: continued
+ {
+ return a;
+ }
+
+ Expect.equals(42, gb0()[0]);
+ Expect.equals(87, gb1([87])[0]);
+
+ // Generic types - arrows.
+ List<int> ga0
+/* //# 20: syntax error
+ ()
+*/ //# 20: continued
+ =>
+ [42];
+ List<int> ga1
+/* //# 21: syntax error
+ (List<int> a)
+*/ //# 21: continued
+ =>
+ a;
+ Expect.equals(42, ga0()[0]);
+ Expect.equals(87, ga1([87])[0]);
+ }
+
+ static void testFunctionExpressions
+/* //# 22: syntax error
+ ()
+*/ //# 22: continued
+ {
+ eval0
+/* //# 23: syntax error
+ (fn)
+*/ //# 23: continued
+ =>
+ fn();
+ eval1
+/* //# 24: syntax error
+ (fn, a)
+*/ //# 24: continued
+ =>
+ fn(a);
+ eval2
+/* //# 25: syntax error
+ (fn, a, b)
+*/ //# 25: continued
+ =>
+ fn(a, b);
+
+ // No types - braces.
+ Expect.equals(42, eval0(
+/* //# 26: syntax error
+ ()
+*/ //# 26: continued
+ {
+ return 42;
+ }));
+ Expect.equals(
+ 87,
+ eval1(
+/* //# 27: syntax error
+ (a)
+*/ //# 27: continued
+ {
+ return a;
+ }, 87));
+ Expect.equals(
+ 1 + 2,
+ eval2(
+/* //# 28: syntax error
+ (a, b)
+*/ //# 28: continued
+ {
+ return a + b;
+ }, 1, 2));
+ Expect.equals(42, eval0(
+/* //# 29: syntax error
+ ()
+*/ //# 29: continued
+ {
+ return 42;
+ }));
+ Expect.equals(
+ 87,
+ eval1(
+/* //# 30: syntax error
+ (a)
+*/ //# 30: continued
+ {
+ return a;
+ }, 87));
+ Expect.equals(
+ 1 + 2,
+ eval2(
+/* //# 31: syntax error
+ (a, b)
+*/ //# 31: continued
+ {
+ return a + b;
+ }, 1, 2));
+
+ // No types - arrows.
+ Expect.equals(
+ 42,
+ eval0(
+/* //# 32: syntax error
+ ()
+*/ //# 32: continued
+ =>
+ 42));
+ Expect.equals(
+ 87,
+ eval1(
+/* //# 33: syntax error
+ (a)
+*/ //# 33: continued
+ =>
+ a,
+ 87));
+ Expect.equals(
+ 1 + 2,
+ eval2(
+/* //# 34: syntax error
+ (a, b)
+*/ //# 34: continued
+ =>
+ a + b,
+ 1,
+ 2));
+ Expect.equals(
+ 42,
+ eval0(
+/* //# 35: syntax error
+ ()
+*/ //# 35: continued
+ =>
+ 42));
+ Expect.equals(
+ 87,
+ eval1(
+/* //# 36: syntax error
+ (a)
+*/ //# 36: continued
+ =>
+ a,
+ 87));
+ Expect.equals(
+ 1 + 2,
+ eval2(
+/* //# 37: syntax error
+ (a, b)
+*/ //# 37: continued
+ =>
+ a + b,
+ 1,
+ 2));
+
+ // Argument types - braces.
+ Expect.equals(42, eval0(
+/* //# 44: syntax error
+ ()
+*/ //# 44: continued
+ {
+ return 42;
+ }));
+ Expect.equals(
+ 87,
+ eval1(
+/* //# 45: syntax error
+ (int a)
+*/ //# 45: continued
+ {
+ return a;
+ }, 87));
+ Expect.equals(
+ 1 + 2,
+ eval2(
+/* //# 46: syntax error
+ (int a, int b)
+*/ //# 46: continued
+ {
+ return a + b;
+ }, 1, 2));
+ Expect.equals(42, eval0(
+/* //# 47: syntax error
+ ()
+*/ //# 47: continued
+ {
+ return 42;
+ }));
+ Expect.equals(
+ 87,
+ eval1(
+/* //# 48: syntax error
+ (int a)
+*/ //# 48: continued
+ {
+ return a;
+ }, 87));
+ Expect.equals(
+ 1 + 2,
+ eval2(
+/* //# 49: syntax error
+ (int a, int b)
+*/ //# 49: continued
+ {
+ return a + b;
+ }, 1, 2));
+
+ // Argument types - arrows.
+ Expect.equals(
+ 42,
+ eval0(
+/* //# 50: syntax error
+ ()
+*/ //# 50: continued
+ =>
+ 42));
+ Expect.equals(
+ 87,
+ eval1(
+/* //# 51: syntax error
+ (int a)
+*/ //# 51: continued
+ =>
+ a,
+ 87));
+ Expect.equals(
+ 1 + 2,
+ eval2(
+/* //# 52: syntax error
+ (int a, int b)
+*/ //# 52: continued
+ =>
+ a + b,
+ 1,
+ 2));
+ Expect.equals(
+ 42,
+ eval0(
+/* //# 53: syntax error
+ ()
+*/ //# 53: continued
+ =>
+ 42));
+ Expect.equals(
+ 87,
+ eval1(
+/* //# 54: syntax error
+ (int a)
+*/ //# 54: continued
+ =>
+ a,
+ 87));
+ Expect.equals(
+ 1 + 2,
+ eval2(
+/* //# 55: syntax error
+ (int a, int b)
+*/ //# 55: continued
+ =>
+ a + b,
+ 1,
+ 2));
+ }
+
+ static void testPrecedence
+/* //# 64: syntax error
+ ()
+*/ //# 64: continued
+ {
+ expectEvaluatesTo
+/* //# 65: syntax error
+ (value, fn)
+*/ //# 65: continued
+ {
+ Expect.equals(value, fn());
+ }
+
+ // Assignment.
+ var x;
+ expectEvaluatesTo(42, () => x = 42);
+ Expect.equals(42, x);
+ x = 1;
+ expectEvaluatesTo(100, () => x += 99);
+ Expect.equals(100, x);
+ x = 1;
+ expectEvaluatesTo(87, () => x *= 87);
+ Expect.equals(87, x);
+
+ // Conditional.
+ expectEvaluatesTo(42, () => true ? 42 : 87);
+ expectEvaluatesTo(87, () => false ? 42 : 87);
+
+ // Logical or.
+ expectEvaluatesTo(true, () => true || true);
+ expectEvaluatesTo(true, () => true || false);
+ expectEvaluatesTo(true, () => false || true);
+ expectEvaluatesTo(false, () => false || false);
+
+ // Logical and.
+ expectEvaluatesTo(true, () => true && true);
+ expectEvaluatesTo(false, () => true && false);
+ expectEvaluatesTo(false, () => false && true);
+ expectEvaluatesTo(false, () => false && false);
+
+ // Bitwise operations.
+ expectEvaluatesTo(3, () => 1 | 2);
+ expectEvaluatesTo(2, () => 3 ^ 1);
+ expectEvaluatesTo(1, () => 3 & 1);
+
+ // Equality.
+ expectEvaluatesTo(true, () => 1 == 1);
+ expectEvaluatesTo(false, () => 1 != 1);
+ expectEvaluatesTo(true, () => identical(1, 1));
+ expectEvaluatesTo(false, () => !identical(1, 1));
+
+ // Relational.
+ expectEvaluatesTo(true, () => 1 <= 1);
+ expectEvaluatesTo(false, () => 1 < 1);
+ expectEvaluatesTo(false, () => 1 > 1);
+ expectEvaluatesTo(true, () => 1 >= 1);
+
+ // Is.
+ expectEvaluatesTo(true, () => 1 is int);
+ expectEvaluatesTo(true, () => 1.0 is double);
+
+ // Shift.
+ expectEvaluatesTo(2, () => 1 << 1);
+ expectEvaluatesTo(1, () => 2 >> 1);
+
+ // Additive.
+ expectEvaluatesTo(2, () => 1 + 1);
+ expectEvaluatesTo(1, () => 2 - 1);
+
+ // Multiplicative.
+ expectEvaluatesTo(2, () => 1 * 2);
+ expectEvaluatesTo(2.0, () => 4 / 2);
+ expectEvaluatesTo(2, () => 4 ~/ 2);
+ expectEvaluatesTo(0, () => 4 % 2);
+
+ // Negate.
+ expectEvaluatesTo(false, () => !true);
+
+ // Postfix / prefix.
+ var y = 0;
+ expectEvaluatesTo(0, () => y++);
+ expectEvaluatesTo(2, () => ++y);
+ expectEvaluatesTo(1, () => --y);
+ expectEvaluatesTo(1, () => y--);
+ Expect.equals(0, y);
+
+ // Selector.
+ fn
+/* //# 66: syntax error
+ ()
+*/ //# 66: continued
+ =>
+ 42;
+ var list = [87];
+ expectEvaluatesTo(42, () => fn());
+ expectEvaluatesTo(1, () => list.length);
+ expectEvaluatesTo(87, () => list[0]);
+ expectEvaluatesTo(87, () => list.removeLast());
+ }
+
+ static void testInitializers
+/* //# 67: syntax error
+ ()
+*/ //# 67: continued
+ {
+ Expect.equals(42, (new C.cb0().fn)());
+ Expect.equals(43, (new C.ca0().fn)());
+ Expect.equals(44, (new C.cb1().fn)());
+ Expect.equals(45, (new C.ca1().fn)());
+ Expect.equals(46, (new C.cb2().fn)());
+ Expect.equals(47, (new C.ca2().fn)());
+ Expect.equals(48, (new C.cb3().fn)());
+ Expect.equals(49, (new C.ca3().fn)());
+
+ Expect.equals(52, (new C.nb0().fn)());
+ Expect.equals(53, (new C.na0().fn)());
+ Expect.equals(54, (new C.nb1().fn)());
+ Expect.equals(55, (new C.na1().fn)());
+ Expect.equals(56, (new C.nb2().fn)());
+ Expect.equals(57, (new C.na2().fn)());
+ Expect.equals(58, (new C.nb3().fn)());
+ Expect.equals(59, (new C.na3().fn)());
+
+ Expect.equals(62, (new C.rb0().fn)());
+ Expect.equals(63, (new C.ra0().fn)());
+ Expect.equals(64, (new C.rb1().fn)());
+ Expect.equals(65, (new C.ra1().fn)());
+ Expect.equals(66, (new C.rb2().fn)());
+ Expect.equals(67, (new C.ra2().fn)());
+ Expect.equals(68, (new C.rb3().fn)());
+ Expect.equals(69, (new C.ra3().fn)());
+ }
+
+ static void testFunctionParameter
+/* //# 68: syntax error
+ ()
+*/ //# 68: continued
+ {
+ f0(fn()) => fn();
+ Expect.equals(42, f0(() => 42));
+
+ f1(int fn()) => fn();
+ Expect.equals(87, f1(() => 87));
+
+ f2(fn(a)) => fn(42);
+ Expect.equals(43, f2((a) => a + 1));
+
+ f3(fn(int a)) => fn(42);
+ Expect.equals(44, f3((int a) => a + 2));
+ }
+
+ static void testFunctionIdentifierExpression
+/* //# 69: syntax error
+ ()
+*/ //# 69: continued
+ {
+ Expect.equals(
+ 87,
+ (
+/* //# 70: syntax error
+ ()
+*/ //# 70: continued
+ =>
+ 87)());
+ }
+
+ static void testFunctionIdentifierStatement
+/* //# 71: syntax error
+ ()
+*/ //# 71: continued
+ {
+ function
+/* //# 72: syntax error
+ ()
+*/ //# 72: continued
+ =>
+ 42;
+ Expect.equals(42, function());
+ Expect.equals(true, function is Function);
+ }
+}
+
+class C {
+ C.cb0()
+ : fn = (() {
+ return 42;
+ }) {}
+ C.ca0() : fn = (() => 43) {}
+
+ C.cb1()
+ : fn = wrap(() {
+ return 44;
+ }) {}
+ C.ca1() : fn = wrap(() => 45) {}
+
+ C.cb2()
+ : fn = [
+ () {
+ return 46;
+ }
+ ][0] {}
+ C.ca2() : fn = [() => 47][0] {}
+
+ C.cb3()
+ : fn = {
+ 'x': () {
+ return 48;
+ }
+ }['x'] {}
+ C.ca3() : fn = {'x': () => 49}['x'] {}
+
+ C.nb0()
+ : fn = (() {
+ return 52;
+ }) {}
+ C.na0() : fn = (() => 53) {}
+
+ C.nb1()
+ : fn = wrap(() {
+ return 54;
+ }) {}
+ C.na1() : fn = wrap(() => 55) {}
+
+ C.nb2()
+ : fn = [
+ () {
+ return 56;
+ }
+ ][0] {}
+ C.na2() : fn = [() => 57][0] {}
+
+ C.nb3()
+ : fn = {
+ 'x': () {
+ return 58;
+ }
+ }['x'] {}
+ C.na3() : fn = {'x': () => 59}['x'] {}
+
+ C.rb0()
+ : fn = (() {
+ return 62;
+ }) {}
+ C.ra0() : fn = (() => 63) {}
+
+ C.rb1()
+ : fn = wrap(() {
+ return 64;
+ }) {}
+ C.ra1() : fn = wrap(() => 65) {}
+
+ C.rb2()
+ : fn = [
+ () {
+ return 66;
+ }
+ ][0] {}
+ C.ra2() : fn = [() => 67][0] {}
+
+ C.rb3()
+ : fn = {
+ 'x': () {
+ return 68;
+ }
+ }['x'] {}
+ C.ra3() : fn = {'x': () => 69}['x'] {}
+
+ static wrap
+/* //# 73: syntax error
+ (fn)
+*/ //# 73: continued
+ {
+ return fn;
+ }
+
+ final fn;
+}
+
+main
+/* //# 74: syntax error
+ ()
+*/ //# 74: continued
+{
+ FunctionSyntaxTest.testMain();
+}
diff --git a/tests/language/function/type2_test.dart b/tests/language/function/type2_test.dart
new file mode 100644
index 0000000..42ca6ff
--- /dev/null
+++ b/tests/language/function/type2_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.
+
+import "package:expect/expect.dart";
+
+class A<T> {
+ A(f) {
+ f(42);
+ }
+}
+
+class B<T> extends A<T> {
+ B() : super((T param) => 42);
+}
+
+main() {
+ var t = new B<int>();
+ Expect.throwsTypeError(() => new B<String>());
+}
diff --git a/tests/language/function/type3_test.dart b/tests/language/function/type3_test.dart
new file mode 100644
index 0000000..b21b3e0
--- /dev/null
+++ b/tests/language/function/type3_test.dart
@@ -0,0 +1,28 @@
+// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+class A<T> {
+ @pragma('dart2js:noInline')
+ A();
+
+ @pragma('dart2js:noInline')
+ foo() => new B<T>();
+}
+
+class B<T> {
+ T bar() => throw "uncalled";
+}
+
+typedef F();
+typedef F2(x);
+
+// Dart2js realized that the generic type for A was not needed, but then used
+// it nevertheless when it constructed the closure.
+main() {
+ var f = new A<int>().foo().bar;
+ Expect.isTrue(f is F);
+ Expect.isFalse(f is F2);
+}
diff --git a/tests/language/function/type_alias10_test.dart b/tests/language/function/type_alias10_test.dart
new file mode 100644
index 0000000..664ad7a
--- /dev/null
+++ b/tests/language/function/type_alias10_test.dart
@@ -0,0 +1,23 @@
+// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Regression test for https://github.com/dart-lang/sdk/issues/30912.
+import 'package:expect/expect.dart';
+
+class Foo {}
+
+class Bar {}
+
+typedef Type Func<S extends Foo, T>(T s);
+
+class Baz<S extends Foo, T extends Bar> {
+ Func<S, Bar>? func;
+}
+
+void main() {
+ dynamic baz = new Baz();
+ Expect.isNull(baz.func);
+ baz.func = (Bar b) => b.runtimeType;
+ Expect.equals(baz.func(new Bar()), Bar);
+}
diff --git a/tests/language/function/type_alias2_test.dart b/tests/language/function/type_alias2_test.dart
new file mode 100644
index 0000000..59c3166
--- /dev/null
+++ b/tests/language/function/type_alias2_test.dart
@@ -0,0 +1,54 @@
+// 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.
+// VMOptions=--enable_type_checks
+
+// Dart test for function type alias with optional parameters.
+import "package:expect/expect.dart";
+
+typedef int f1<T>([int? a, int? b, T? c]);
+typedef int f2<T>([int? a, int? b, T? d]);
+typedef int f3<T>({int? a, int? b, T? c});
+typedef int f4<T>({int? a, int? b, T? d});
+
+class A<T> {
+ int baz([int? a, int? b, T? c]) => -1;
+ int bar({int? a, int? b, T? c}) => -1;
+}
+
+int baz([int? a, int? b, int? c]) => -1;
+
+int bar({int? a, int? b, int? c}) => -1;
+
+main() {
+ Expect.isFalse(baz is f1);
+ Expect.isFalse(baz is f3);
+ Expect.isFalse(bar is f1);
+ Expect.isFalse(bar is f3);
+ Expect.isFalse(baz is f1);
+ Expect.isTrue(baz is f1<int>);
+ Expect.isTrue(bar is f3<int>);
+ Expect.isFalse(baz is f1<double>);
+ Expect.isFalse(bar is f3<double>);
+ Expect.isFalse(baz is f2);
+ Expect.isFalse(bar is f4);
+ Expect.isTrue(baz is f2<int>);
+ Expect.isFalse(bar is f2<int>);
+
+ A<int> a = new A<int>();
+ Expect.isTrue(a.baz is f1);
+ Expect.isFalse(a.baz is f3);
+ Expect.isFalse(a.bar is f1);
+ Expect.isTrue(a.bar is f3);
+ Expect.isTrue(a.baz is f1);
+ Expect.isTrue(a.baz is f1<Object>);
+ Expect.isTrue(a.bar is f3<Object>);
+ Expect.isTrue(a.baz is f1<int>);
+ Expect.isTrue(a.bar is f3<int>);
+ Expect.isTrue(a.baz is f1<double>);
+ Expect.isTrue(a.bar is f3<double>);
+ Expect.isTrue(a.baz is f2);
+ Expect.isFalse(a.bar is f4);
+ Expect.isTrue(a.baz is f2<Object>);
+ Expect.isFalse(a.bar is f2<Object>);
+}
diff --git a/tests/language/function/type_alias3_test.dart b/tests/language/function/type_alias3_test.dart
new file mode 100644
index 0000000..69ebd6e1
--- /dev/null
+++ b/tests/language/function/type_alias3_test.dart
@@ -0,0 +1,26 @@
+// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Dart test for function type alias with an imported result type that happens
+// to have the same name as a type parameter.
+import "package:expect/expect.dart";
+import "../library11.dart" as lib11;
+
+typedef lib11.Library111<Library111> F<Library111>(
+ lib11.Library111<Library111> a, Library111 b);
+
+class A<T> {
+ T foo(T a, bool b) => throw "uncalled";
+}
+
+main() {
+ var a = new A<lib11.Library111<bool>>();
+ var b = new A<lib11.Library111<int>>();
+ Expect.isTrue(a.foo is! F);
+ Expect.isTrue(a.foo is F<bool>);
+ Expect.isTrue(a.foo is! F<int>);
+ Expect.isTrue(b.foo is! F);
+ Expect.isTrue(b.foo is! F<bool>);
+ Expect.isTrue(a.foo is! F<int>);
+}
diff --git a/tests/language/function/type_alias4_test.dart b/tests/language/function/type_alias4_test.dart
new file mode 100644
index 0000000..3bdba67
--- /dev/null
+++ b/tests/language/function/type_alias4_test.dart
@@ -0,0 +1,40 @@
+// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Dart test for function type alias with a type parameter as result type.
+import "package:expect/expect.dart";
+
+typedef bool F<bool>(bool a); // 'bool' is not the boolean type.
+
+bool bar(bool a) => false;
+
+int baz(int a) => -1;
+
+class A<T> {
+ T foo(T a) => throw "uncalled";
+}
+
+main() {
+ Expect.isTrue(bar is! F);
+ Expect.isTrue(baz is! F);
+ Expect.isTrue(bar is! F<Object>);
+ Expect.isTrue(baz is! F<Object>);
+ Expect.isTrue(bar is F<bool>);
+ Expect.isTrue(baz is F<int>);
+ Expect.isTrue(bar is! F<int>);
+ Expect.isTrue(baz is! F<bool>);
+
+ var b = new A<bool>();
+ var i = new A<int>();
+ Expect.isTrue(b.foo is F, 'runtime type of covaraint parameters is Object');
+ Expect.isTrue(i.foo is F, 'runtime type of covaraint parameters is Object');
+ Expect.isTrue(
+ b.foo is F<Object>, 'runtime type of covaraint parameters is Object');
+ Expect.isTrue(
+ i.foo is F<Object>, 'runtime type of covaraint parameters is Object');
+ Expect.isTrue(b.foo is F<bool>);
+ Expect.isTrue(i.foo is F<int>);
+ Expect.isTrue(b.foo is! F<int>);
+ Expect.isTrue(i.foo is! F<bool>);
+}
diff --git a/tests/language/function/type_alias5_test.dart b/tests/language/function/type_alias5_test.dart
new file mode 100644
index 0000000..40d6309
--- /dev/null
+++ b/tests/language/function/type_alias5_test.dart
@@ -0,0 +1,17 @@
+// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// Dart test for illegally self referencing function type alias.
+
+typedef Handle Handle(String command); //# 00: compile-time error
+
+typedef F(F x); //# 01: compile-time error
+
+typedef A(B x); //# 02: compile-time error
+typedef B(A x); //# 02: continued
+
+main() {
+ Handle h; //# 00: continued
+ F f; //# 01: continued
+ A f; //# 02: continued
+}
diff --git a/tests/language/function/type_alias6_runtime_test.dart b/tests/language/function/type_alias6_runtime_test.dart
new file mode 100644
index 0000000..362fccf
--- /dev/null
+++ b/tests/language/function/type_alias6_runtime_test.dart
@@ -0,0 +1,31 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// 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 for legally self referencing function type alias.
+
+import "package:expect/expect.dart";
+
+typedef F(
+ List
+
+ x);
+
+typedef D C();
+
+class D {
+ C foo() => throw "uncalled";
+ D bar() => throw "uncalled";
+}
+
+main() {
+ var f = (List x) {};
+ Expect.isTrue(f is F);
+ var g = (List<F> x) {};
+ Expect.isFalse(g is F);
+ var d = new D();
+ Expect.isTrue(d.foo is! C);
+ Expect.isTrue(d.bar is C);
+}
diff --git a/tests/language/function/type_alias6_test.dart b/tests/language/function/type_alias6_test.dart
new file mode 100644
index 0000000..f8e508d
--- /dev/null
+++ b/tests/language/function/type_alias6_test.dart
@@ -0,0 +1,29 @@
+// 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 for legally self referencing function type alias.
+
+import "package:expect/expect.dart";
+
+typedef F(List<F> x);
+// [error line 8, column 1, length 21]
+// [analyzer] COMPILE_TIME_ERROR.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF
+// ^
+// [cfe] The typedef 'F' has a reference to itself.
+
+typedef D C();
+
+class D {
+ C foo() => throw "uncalled";
+ D bar() => throw "uncalled";
+}
+
+main() {
+ var f = (List x) {};
+ Expect.isTrue(f is F);
+ var g = (List<F> x) {};
+ Expect.isFalse(g is F);
+ var d = new D();
+ Expect.isTrue(d.foo is! C);
+ Expect.isTrue(d.bar is C);
+}
diff --git a/tests/language/function/type_alias7_test.dart b/tests/language/function/type_alias7_test.dart
new file mode 100644
index 0000000..79bd6e7
--- /dev/null
+++ b/tests/language/function/type_alias7_test.dart
@@ -0,0 +1,19 @@
+// 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.
+
+typedef void funcType([int arg]);
+
+typedef void badFuncType([int arg = 0]); //# 00: compile-time error
+
+typedef void badFuncType({int arg: 0}); //# 02: compile-time error
+
+class A
+ extends funcType // //# 01: compile-time error
+{}
+
+main() {
+ new A();
+ badFuncType f; //# 00: continued
+ badFuncType f; //# 02: continued
+}
diff --git a/tests/language/function/type_alias8_test.dart b/tests/language/function/type_alias8_test.dart
new file mode 100644
index 0000000..b272ed7
--- /dev/null
+++ b/tests/language/function/type_alias8_test.dart
@@ -0,0 +1,19 @@
+// 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 issue 9442.
+
+typedef dynamic GetFromThing<T extends Thing>(T target);
+
+typedef GetFromThing<T>? DefGetFromThing<T extends Thing>(dynamic def);
+
+class Thing {}
+
+class Test {
+ static final DefGetFromThing<Thing> fromThing = (dynamic def) {};
+}
+
+main() {
+ Test.fromThing(10);
+}
diff --git a/tests/language/function/type_alias9_runtime_test.dart b/tests/language/function/type_alias9_runtime_test.dart
new file mode 100644
index 0000000..1aa72a3
--- /dev/null
+++ b/tests/language/function/type_alias9_runtime_test.dart
@@ -0,0 +1,18 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// 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 for legally self referencing function type alias.
+
+typedef void F(
+ List
+
+ l);
+typedef void G(List<F> l);
+
+main() {
+ F? foo(G? g) => g as F?;
+ foo(null);
+}
diff --git a/tests/language/function/type_alias9_test.dart b/tests/language/function/type_alias9_test.dart
new file mode 100644
index 0000000..71c0d7b
--- /dev/null
+++ b/tests/language/function/type_alias9_test.dart
@@ -0,0 +1,18 @@
+// 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 for legally self referencing function type alias.
+
+typedef void F(List<G> l);
+// [error line 6, column 1, length 26]
+// [analyzer] COMPILE_TIME_ERROR.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF
+// ^
+// [cfe] The typedef 'F' has a reference to itself.
+typedef void G(List<F> l);
+// [error line 11, column 1, length 26]
+// [analyzer] COMPILE_TIME_ERROR.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF
+
+main() {
+ F? foo(G? g) => g as F?;
+ foo(null);
+}
diff --git a/tests/language/function/type_alias_test.dart b/tests/language/function/type_alias_test.dart
new file mode 100644
index 0000000..9fc9f28
--- /dev/null
+++ b/tests/language/function/type_alias_test.dart
@@ -0,0 +1,125 @@
+// 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.
+// VMOptions=--enable_type_checks
+//
+// Dart test for function type alias.
+
+import "package:expect/expect.dart";
+
+typedef Fun(Never a, Never b);
+
+typedef int IntFun(Never a, Never b);
+
+typedef bool BoolFun(Never a, Never b);
+
+typedef int CompareObj(Object a, Object b);
+
+typedef int CompareInt(int a, int b);
+
+typedef int CompareString(String a, String b, [bool swap]);
+
+typedef void Test();
+
+typedef ParameterizedFun1<T, U extends bool, V>(T t, U u);
+
+typedef List<T> ParameterizedFun2<T, U, V extends Map<T, int>>(
+ Map<T, int> t, U u);
+
+typedef void BoundsCheck<T extends num>(T arg);
+
+class FunctionTypeAliasTest {
+ FunctionTypeAliasTest() {}
+ static int test<T>(int compare(T a, T b), T a, T b) {
+ return compare(a, b);
+ }
+
+ foo(Test arg) {}
+ static bar() {
+ FunctionTypeAliasTest a = new FunctionTypeAliasTest();
+ a.foo(() {});
+ return 0;
+ }
+
+ static void testMain() {
+ int compareStrLen(String a, String b) {
+ return a.length - b.length;
+ }
+
+ Expect.isTrue(compareStrLen is Fun);
+ Expect.isTrue(compareStrLen is IntFun);
+ Expect.isTrue(compareStrLen is! BoolFun);
+ Expect.isTrue(compareStrLen is! CompareObj);
+ Expect.isTrue(compareStrLen is! CompareInt);
+ Expect.isTrue(compareStrLen is! CompareString);
+ Expect.equals(3, test(compareStrLen, "abcdef", "xyz"));
+
+ int compareStrLenSwap(String a, String b, [bool swap = false]) {
+ return swap ? (a.length - b.length) : (b.length - a.length);
+ }
+
+ Expect.isTrue(compareStrLenSwap is Fun);
+ Expect.isTrue(compareStrLenSwap is IntFun);
+ Expect.isTrue(compareStrLenSwap is! BoolFun);
+ Expect.isTrue(compareStrLenSwap is! CompareObj);
+ Expect.isTrue(compareStrLenSwap is! CompareInt);
+ Expect.isTrue(compareStrLenSwap is CompareString);
+
+ int compareStrLenReverse(String a, String b, [bool reverse = false]) {
+ return reverse ? (a.length - b.length) : (b.length - a.length);
+ }
+
+ Expect.isTrue(compareStrLenReverse is Fun);
+ Expect.isTrue(compareStrLenReverse is IntFun);
+ Expect.isTrue(compareStrLenReverse is! BoolFun);
+ Expect.isTrue(compareStrLenReverse is! CompareObj);
+ Expect.isTrue(compareStrLenReverse is! CompareInt);
+ Expect.isTrue(compareStrLenReverse is CompareString);
+
+ int compareObj(Object a, Object b) {
+ return identical(a, b) ? 0 : -1;
+ }
+
+ Expect.isTrue(compareObj is Fun);
+ Expect.isTrue(compareObj is IntFun);
+ Expect.isTrue(compareObj is! BoolFun);
+ Expect.isTrue(compareObj is CompareObj);
+ Expect.isTrue(compareObj is CompareInt);
+ Expect.isTrue(compareObj is! CompareString);
+ Expect.equals(-1, test(compareObj, "abcdef", "xyz"));
+
+ CompareInt minus = (int a, int b) {
+ return a - b;
+ };
+ Expect.isTrue(minus is Fun);
+ Expect.isTrue(minus is IntFun);
+ Expect.isTrue(minus is! BoolFun);
+ Expect.isTrue(minus is! CompareObj);
+ Expect.isTrue(minus is CompareInt);
+ Expect.isTrue(minus is! CompareString);
+ Expect.equals(99, test(minus, 100, 1));
+
+ int plus(int a, [int b = 1]) {
+ return a + b;
+ }
+
+ ;
+ Expect.isTrue(plus is Fun);
+ Expect.isTrue(plus is IntFun);
+ Expect.isTrue(plus is! BoolFun);
+ Expect.isTrue(plus is! CompareObj);
+ Expect.isTrue(plus is CompareInt);
+ Expect.isTrue(plus is! CompareString);
+
+ Expect.equals(0, bar());
+
+ Function boundsTrue = (num arg) {};
+ Function boundsFalse = (String arg) {};
+ Expect.isTrue(boundsTrue is BoundsCheck<int>);
+ Expect.isFalse(boundsFalse is BoundsCheck<num>);
+ }
+}
+
+main() {
+ FunctionTypeAliasTest.testMain();
+}
diff --git a/tests/language/function/type_call_getter2_runtime_test.dart b/tests/language/function/type_call_getter2_runtime_test.dart
new file mode 100644
index 0000000..689328b
--- /dev/null
+++ b/tests/language/function/type_call_getter2_runtime_test.dart
@@ -0,0 +1,76 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+class A {
+ final call = null;
+}
+
+class B {
+ get call => null;
+}
+
+class C {
+ set call(x) {}
+}
+
+typedef int F(String str);
+
+main() {
+ A a = new A();
+ B b = new B();
+ C c = new C();
+
+ final
+
+ a2 = a;
+
+ final
+
+ a3 = a;
+
+ final
+
+ b2 = b;
+
+ final
+
+ b3 = b;
+
+ final
+
+ c2 = c;
+
+ final
+
+ c3 = c;
+
+ Expect.throwsTypeError(() {
+ Function a4 = a as dynamic;
+ });
+
+ Expect.throwsTypeError(() {
+ F a5 = a as dynamic;
+ });
+
+ Expect.throwsTypeError(() {
+ Function b4 = b as dynamic;
+ });
+
+ Expect.throwsTypeError(() {
+ F b5 = b as dynamic;
+ });
+
+ Expect.throwsTypeError(() {
+ Function c4 = c as dynamic;
+ });
+
+ Expect.throwsTypeError(() {
+ F c5 = c as dynamic;
+ });
+}
diff --git a/tests/language/function/type_call_getter2_test.dart b/tests/language/function/type_call_getter2_test.dart
new file mode 100644
index 0000000..c52cb9e
--- /dev/null
+++ b/tests/language/function/type_call_getter2_test.dart
@@ -0,0 +1,91 @@
+// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+class A {
+ final call = null;
+}
+
+class B {
+ get call => null;
+}
+
+class C {
+ set call(x) {}
+}
+
+typedef int F(String str);
+
+main() {
+ A a = new A();
+ B b = new B();
+ C c = new C();
+
+ final
+ Function
+ a2 = a;
+ // ^
+ // [analyzer] STATIC_TYPE_WARNING.INVALID_ASSIGNMENT
+ // [cfe] A value of type 'A' can't be assigned to a variable of type 'Function'.
+
+ final
+ F
+ a3 = a;
+ // ^
+ // [analyzer] STATIC_TYPE_WARNING.INVALID_ASSIGNMENT
+ // [cfe] A value of type 'A' can't be assigned to a variable of type 'int Function(String)'.
+
+ final
+ Function
+ b2 = b;
+ // ^
+ // [analyzer] STATIC_TYPE_WARNING.INVALID_ASSIGNMENT
+ // [cfe] A value of type 'B' can't be assigned to a variable of type 'Function'.
+
+ final
+ F
+ b3 = b;
+ // ^
+ // [analyzer] STATIC_TYPE_WARNING.INVALID_ASSIGNMENT
+ // [cfe] A value of type 'B' can't be assigned to a variable of type 'int Function(String)'.
+
+ final
+ Function
+ c2 = c;
+ // ^
+ // [analyzer] STATIC_TYPE_WARNING.INVALID_ASSIGNMENT
+ // [cfe] A value of type 'C' can't be assigned to a variable of type 'Function'.
+
+ final
+ F
+ c3 = c;
+ // ^
+ // [analyzer] STATIC_TYPE_WARNING.INVALID_ASSIGNMENT
+ // [cfe] A value of type 'C' can't be assigned to a variable of type 'int Function(String)'.
+
+ Expect.throwsTypeError(() {
+ Function a4 = a as dynamic;
+ });
+
+ Expect.throwsTypeError(() {
+ F a5 = a as dynamic;
+ });
+
+ Expect.throwsTypeError(() {
+ Function b4 = b as dynamic;
+ });
+
+ Expect.throwsTypeError(() {
+ F b5 = b as dynamic;
+ });
+
+ Expect.throwsTypeError(() {
+ Function c4 = c as dynamic;
+ });
+
+ Expect.throwsTypeError(() {
+ F c5 = c as dynamic;
+ });
+}
diff --git a/tests/language/function/type_call_getter_test.dart b/tests/language/function/type_call_getter_test.dart
new file mode 100644
index 0000000..52ecbaa
--- /dev/null
+++ b/tests/language/function/type_call_getter_test.dart
@@ -0,0 +1,28 @@
+// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+class A {
+ final call = null;
+}
+
+class B {
+ get call => null;
+}
+
+class C {
+ set call(x) {}
+}
+
+typedef int F(String str);
+
+main() {
+ Expect.isFalse(new A() is Function);
+ Expect.isFalse(new B() is Function);
+ Expect.isFalse(new C() is Function);
+ Expect.isFalse(new A() is F);
+ Expect.isFalse(new B() is F);
+ Expect.isFalse(new C() is F);
+}
diff --git a/tests/language/function/type_in_constant_test.dart b/tests/language/function/type_in_constant_test.dart
new file mode 100644
index 0000000..ca9db12
--- /dev/null
+++ b/tests/language/function/type_in_constant_test.dart
@@ -0,0 +1,23 @@
+// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/// Test that consts can be created with inlined function types as type
+/// arguments.
+
+import 'package:expect/expect.dart';
+
+class A<T> {
+ const A();
+}
+
+@pragma('dart2js:noInline')
+test(a, b) {
+ Expect.notEquals(a, b);
+}
+
+main() {
+ test(const A<int Function()>(), const A<String Function()>());
+ test(const A<int>(), const A<String Function()>());
+ test(const A<int Function()>(), const A<String>());
+}
diff --git a/tests/language/function/type_parameter2_test.dart b/tests/language/function/type_parameter2_test.dart
new file mode 100644
index 0000000..4a30d5a
--- /dev/null
+++ b/tests/language/function/type_parameter2_test.dart
@@ -0,0 +1,29 @@
+// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Test to check that we can parse closure type formal parameters with
+// default value.
+
+import "package:expect/expect.dart";
+
+class FunctionTypeParameterTest {
+ static var formatter;
+
+ static SetFormatter([String fmt(int i)? = null]) {
+ formatter = fmt;
+ }
+
+ static void testMain() {
+ Expect.equals(null, formatter);
+ SetFormatter((i) => "$i");
+ Expect.equals(false, null == formatter);
+ Expect.equals("1234", formatter(1230 + 4));
+ SetFormatter();
+ Expect.equals(null, formatter);
+ }
+}
+
+main() {
+ FunctionTypeParameterTest.testMain();
+}
diff --git a/tests/language/function/type_parameter3_test.dart b/tests/language/function/type_parameter3_test.dart
new file mode 100644
index 0000000..cb79201
--- /dev/null
+++ b/tests/language/function/type_parameter3_test.dart
@@ -0,0 +1,17 @@
+// 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.
+
+/// Test that we detect that a function literal is not
+/// a compile time constant.
+
+test([String fmt(int i) = (i) => "$i"]) {}
+// ^^^^^^^^^^^
+// [analyzer] COMPILE_TIME_ERROR.NON_CONSTANT_DEFAULT_VALUE
+// [cfe] Not a constant expression.
+// ^
+// [cfe] Not a constant expression.
+
+main() {
+ test();
+}
diff --git a/tests/language/function/type_parameter_bound_object_test.dart b/tests/language/function/type_parameter_bound_object_test.dart
new file mode 100644
index 0000000..61486c2f
--- /dev/null
+++ b/tests/language/function/type_parameter_bound_object_test.dart
@@ -0,0 +1,17 @@
+// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+Q hest<Q>(dynamic x) {
+ if (x is Q) return x;
+ throw "unreached";
+}
+
+Q Function<Q>(dynamic) pony = hest;
+Q Function<Q extends Object?>(dynamic) zebra = hest;
+
+main() {
+ hest(42).fisk(); //# 01: runtime error
+ pony(42).fisk(); //# 02: runtime error
+ zebra(42).fisk(); //# 03: compile-time error
+}
diff --git a/tests/language/function/type_parameter_test.dart b/tests/language/function/type_parameter_test.dart
new file mode 100644
index 0000000..4f18fb8
--- /dev/null
+++ b/tests/language/function/type_parameter_test.dart
@@ -0,0 +1,32 @@
+// 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.
+
+import "package:expect/expect.dart";
+
+// Test to check that we can parse closure type formal parameters with
+// default value.
+
+class A {
+ final f;
+ A(int this.f());
+ const A.nother(int this.f());
+
+ static Function? func;
+
+ static SetFunc([String fmt(int i)? = null]) {
+ func = fmt;
+ }
+}
+
+main() {
+ Expect.equals(null, A.func);
+ A.SetFunc((i) => "$i");
+ Expect.equals(false, null == A.func);
+ Expect.equals("1234", A.func!(1230 + 4));
+ A.SetFunc();
+ Expect.equals(null, A.func);
+
+ Expect.equals(42, new A(() => 42).f());
+ Expect.equals(42, new A.nother(() => 42).f());
+}
diff --git a/tests/language/function/type_test.dart b/tests/language/function/type_test.dart
new file mode 100644
index 0000000..0812e71
--- /dev/null
+++ b/tests/language/function/type_test.dart
@@ -0,0 +1,17 @@
+// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Dart test for a function type test that cannot be eliminated at compile time.
+import "package:expect/expect.dart";
+
+typedef FListInt(List<int> l);
+
+main() {
+ Expect.throwsTypeError(() {
+ // Static result type of f(), i.e. FList, is a subtype of FListInt.
+ // However, run time type of returned function is not a subtype of FListInt.
+ // Run time type check should not be eliminated.
+ FListInt fli = ((List<String> l) => null) as dynamic;
+ });
+}
diff --git a/tests/language/function/type_this_parameter_test.dart b/tests/language/function/type_this_parameter_test.dart
new file mode 100644
index 0000000..4ce65c7
--- /dev/null
+++ b/tests/language/function/type_this_parameter_test.dart
@@ -0,0 +1,17 @@
+// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// Check that function types are accepted for constructor arguments that
+// initialize fields.
+
+import "package:expect/expect.dart";
+
+class A {
+ Function f;
+ A(int this.f());
+}
+
+main() {
+ var a = new A(() => 499);
+ Expect.equals(499, (a.f)());
+}
diff --git a/tests/language/library1.dart b/tests/language/library1.dart
new file mode 100644
index 0000000..96cdd1b
--- /dev/null
+++ b/tests/language/library1.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.
+//
+
+library library1.dart;
+
+var foo;
+
+bar() => "library1.dart bar()";
+
+baz() => "library1.dart baz()";
+
+var bay;
+
+typedef int bax(int a, int b);
+
+class baw {}
diff --git a/tests/language/library10.dart b/tests/language/library10.dart
new file mode 100644
index 0000000..afa22f6
--- /dev/null
+++ b/tests/language/library10.dart
@@ -0,0 +1,40 @@
+// 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.
+//
+
+library library10.dart;
+
+import "library11.dart" as lib11;
+import "package:expect/expect.dart";
+
+class Library10 {
+ Library10(this.fld);
+ int func() {
+ return 2;
+ }
+
+ var fld;
+ static int static_func() {
+ var result = 0;
+ var obj = new lib11.Library11(4);
+ result = obj.fld;
+ Expect.equals(4, result);
+ result += obj.func();
+ Expect.equals(7, result);
+ result += lib11.Library11.static_func();
+ Expect.equals(9, result);
+ result += lib11.Library11.static_fld;
+ Expect.equals(10, result);
+ Expect.equals(100, lib11.top_level11);
+ Expect.equals(200, lib11.top_level_func11());
+ return 3;
+ }
+
+ static var static_fld = 4;
+}
+
+const int top_level10 = 10;
+int top_level_func10() {
+ return 20;
+}
diff --git a/tests/language/library11.dart b/tests/language/library11.dart
new file mode 100644
index 0000000..f8a4395
--- /dev/null
+++ b/tests/language/library11.dart
@@ -0,0 +1,31 @@
+// 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.
+//
+
+library library11.dart;
+
+class Library11 {
+ Library11(this.fld);
+ Library11.namedConstructor(this.fld);
+ int func() {
+ return 3;
+ }
+
+ var fld;
+ static int static_func() {
+ return 2;
+ }
+
+ static var static_fld = 1;
+}
+
+class Library111<T> {
+ Library111.namedConstructor(T this.fld);
+ T fld;
+}
+
+const int top_level11 = 100;
+int top_level_func11() {
+ return 200;
+}
diff --git a/tests/language/library12.dart b/tests/language/library12.dart
new file mode 100644
index 0000000..1eeaa0e
--- /dev/null
+++ b/tests/language/library12.dart
@@ -0,0 +1,48 @@
+// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+//
+
+library library12.dart;
+
+import 'package:expect/expect.dart';
+
+import "library11.dart";
+
+class Library12 {
+ Library12(this.fld);
+ Library12.other(fld, multiplier) {
+ this.fld = fld * multiplier;
+ }
+ func() {
+ return 2;
+ }
+
+ var fld;
+ static static_func() {
+ var result = 0;
+ var obj = new Library11(4);
+ result = obj.fld;
+ Expect.equals(4, result);
+ result += obj.func();
+ Expect.equals(7, result);
+ result += Library11.static_func();
+ Expect.equals(9, result);
+ result += Library11.static_fld;
+ Expect.equals(10, result);
+ Expect.equals(100, top_level11);
+ Expect.equals(200, top_level_func11());
+ return 3;
+ }
+
+ static var static_fld = 4;
+}
+
+abstract class Library12Interface {
+ Library12 addObjects(Library12 value1, Library12 value2);
+}
+
+const int top_level12 = 10;
+top_level_func12() {
+ return 20;
+}
diff --git a/tests/language/library2.dart b/tests/language/library2.dart
new file mode 100644
index 0000000..219303f
--- /dev/null
+++ b/tests/language/library2.dart
@@ -0,0 +1,16 @@
+// 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.
+
+var foo;
+var foo1 = 0;
+
+bar() => "library2.dart bar()";
+
+var baz;
+
+bay() => "library2.dart bay()";
+
+typedef double bax(int a, int b);
+
+var baw;
diff --git a/tests/language/nnbd/never/never_null_assignability_error_test.dart b/tests/language/nnbd/never/never_null_assignability_error_test.dart
new file mode 100644
index 0000000..634e219
--- /dev/null
+++ b/tests/language/nnbd/never/never_null_assignability_error_test.dart
@@ -0,0 +1,217 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:expect/expect.dart';
+import 'never_null_assignability_lib1.dart';
+
+// This test validates that in a null safe (opted in) library which calls out
+// to another null safe (opted in) library, the static errors around `Never`
+// and `Null` that are suppressed when calling out a null safe library from
+// a **legacy** library are correctly reported. This file is derived from
+// never_null_assignability_weak_test.dart and validates that calls to a
+// null safe library that are only permitted in that test because of legacy
+// support become errors when it is opted in.
+
+// Tests for direct calls to null safe functions.
+void testNullSafeCalls() {
+ // Test calling a null safe function expecting Null from a null safe library
+ {
+ takesNull(nil);
+ takesNull(never);
+ takesNull(3 as dynamic);
+ (takesNull as dynamic)(3);
+ }
+
+ // Test calling a null safe function expecting Never from a null safe library
+ {
+ takesNever(nil);
+ // ^^^
+ // [analyzer] STATIC_WARNING.ARGUMENT_TYPE_NOT_ASSIGNABLE
+ // [cfe] The argument type 'Null?' can't be assigned to the parameter type 'Never'.
+ takesNever(never);
+ takesNever(3 as dynamic);
+ (takesNever as dynamic)(3);
+ }
+
+ // Test calling a null safe function expecting int from a null safe library
+ {
+ takesInt(3);
+ takesInt(nil);
+ // ^^^
+ // [analyzer] STATIC_WARNING.ARGUMENT_TYPE_NOT_ASSIGNABLE
+ // [cfe] The argument type 'Null?' can't be assigned to the parameter type 'int'.
+ takesInt(nil as dynamic);
+ (takesInt as dynamic)(nil);
+ (takesInt as dynamic)("hello");
+ }
+
+ // Test calling a null safe function expecting Object from a null safe library
+ {
+ takesObject(3);
+ takesObject(nil);
+ // ^^^
+ // [analyzer] STATIC_WARNING.ARGUMENT_TYPE_NOT_ASSIGNABLE
+ // [cfe] The argument type 'Null?' can't be assigned to the parameter type 'Object'.
+ takesObject(nil as dynamic);
+ (takesObject as dynamic)(nil);
+ }
+
+ // Test calling a null safe function expecting Object? from a null safe library
+ {
+ takesAny(3);
+ takesAny(nil);
+ (takesAny as dynamic)(nil);
+ }
+}
+
+void testNullSafeApply() {
+ // Test applying a null safe function of static type void Function(Null)
+ // in a null safe library, when called with null cast to Null at the call
+ // site.
+ {
+ applyTakesNull(takesNull, nil);
+ applyTakesNull(takesNever, nil);
+ // ^^^^^^^^^^
+ // [analyzer] STATIC_WARNING.ARGUMENT_TYPE_NOT_ASSIGNABLE
+ // [cfe] The argument type 'void Function(Never)' can't be assigned to the parameter type 'void Function(Null?)'.
+ applyTakesNull(takesAny, nil);
+
+ applyTakesNull(takesInt, nil);
+ // ^^^^^^^^
+ // [analyzer] STATIC_WARNING.ARGUMENT_TYPE_NOT_ASSIGNABLE
+ // [cfe] The argument type 'void Function(int)' can't be assigned to the parameter type 'void Function(Null?)'.
+ applyTakesNull(takesObject, nil);
+ // ^^^^^^^^^^^
+ // [analyzer] STATIC_WARNING.ARGUMENT_TYPE_NOT_ASSIGNABLE
+ // [cfe] The argument type 'void Function(Object)' can't be assigned to the parameter type 'void Function(Null?)'.
+ }
+
+ // Test applying a null safe function of static type void Function(Null)
+ // in a null safe library, when called with a non-null value cast to Null
+ // at the call site.
+ {
+ applyTakesNull(takesNull, 3);
+ applyTakesNull(takesNever, 3);
+ // ^^^^^^^^^^
+ // [analyzer] STATIC_WARNING.ARGUMENT_TYPE_NOT_ASSIGNABLE
+ // [cfe] The argument type 'void Function(Never)' can't be assigned to the parameter type 'void Function(Null?)'.
+ applyTakesNull(takesInt, 3);
+ // ^^^^^^^^
+ // [analyzer] STATIC_WARNING.ARGUMENT_TYPE_NOT_ASSIGNABLE
+ // [cfe] The argument type 'void Function(int)' can't be assigned to the parameter type 'void Function(Null?)'.
+ applyTakesNull(takesObject, 3);
+ // ^^^^^^^^^^^
+ // [analyzer] STATIC_WARNING.ARGUMENT_TYPE_NOT_ASSIGNABLE
+ // [cfe] The argument type 'void Function(Object)' can't be assigned to the parameter type 'void Function(Null?)'.
+ applyTakesNull(takesAny, 3);
+ }
+
+ // Test applying a null safe function of static type void Function(Never)
+ // in a null safe library, when called with null cast to Never at the call
+ // site.
+ {
+ applyTakesNever(takesNull, nil);
+ applyTakesNever(takesNever, nil);
+ applyTakesNever(takesAny, nil);
+ applyTakesNever(takesInt, nil);
+ applyTakesNever(takesObject, nil);
+ }
+
+ // Test applying a null safe function of static type void Function(Never)
+ // in a null safe library, when called with a non-null value cast to Never
+ // at the call site.
+ {
+ applyTakesNever(takesNull, 3);
+ applyTakesNever(takesNever, 3);
+ applyTakesNever(takesInt, 3);
+ applyTakesNever(takesObject, 3);
+ applyTakesNever(takesAny, 3);
+ }
+}
+
+void testNullSafeApplyDynamically() {
+ // Test dynamically applying a null safe function of static type
+ // void Function(Null) in a null safe library, when called with
+ // null.
+ {
+ applyTakesNullDynamically(takesNull, nil);
+ applyTakesNullDynamically(takesNever, nil);
+ // ^^^^^^^^^^
+ // [analyzer] STATIC_WARNING.ARGUMENT_TYPE_NOT_ASSIGNABLE
+ // [cfe] The argument type 'void Function(Never)' can't be assigned to the parameter type 'void Function(Null?)'.
+ applyTakesNullDynamically(takesAny, nil);
+ applyTakesNullDynamically(takesInt, nil);
+ // ^^^^^^^^
+ // [analyzer] STATIC_WARNING.ARGUMENT_TYPE_NOT_ASSIGNABLE
+ // [cfe] The argument type 'void Function(int)' can't be assigned to the parameter type 'void Function(Null?)'.
+ applyTakesNullDynamically(takesObject, nil);
+ // ^^^^^^^^^^^
+ // [analyzer] STATIC_WARNING.ARGUMENT_TYPE_NOT_ASSIGNABLE
+ // [cfe] The argument type 'void Function(Object)' can't be assigned to the parameter type 'void Function(Null?)'.
+ }
+
+ // Test dynamically applying a null safe function of static type
+ // void Function(Null) in a null safe library, when called with
+ // a non-null value.
+ {
+ applyTakesNullDynamically(takesNull, 3);
+ applyTakesNullDynamically(takesNever, 3);
+ // ^^^^^^^^^^
+ // [analyzer] STATIC_WARNING.ARGUMENT_TYPE_NOT_ASSIGNABLE
+ // [cfe] The argument type 'void Function(Never)' can't be assigned to the parameter type 'void Function(Null?)'.
+ applyTakesNullDynamically(takesInt, 3);
+ // ^^^^^^^^
+ // [analyzer] STATIC_WARNING.ARGUMENT_TYPE_NOT_ASSIGNABLE
+ // [cfe] The argument type 'void Function(int)' can't be assigned to the parameter type 'void Function(Null?)'.
+ applyTakesNullDynamically(takesInt, "hello");
+ // ^^^^^^^^
+ // [analyzer] STATIC_WARNING.ARGUMENT_TYPE_NOT_ASSIGNABLE
+ // [cfe] The argument type 'void Function(int)' can't be assigned to the parameter type 'void Function(Null?)'.
+ applyTakesNullDynamically(takesObject, 3);
+ // ^^^^^^^^^^^
+ // [analyzer] STATIC_WARNING.ARGUMENT_TYPE_NOT_ASSIGNABLE
+ // [cfe] The argument type 'void Function(Object)' can't be assigned to the parameter type 'void Function(Null?)'.
+ applyTakesNullDynamically(takesAny, 3);
+ }
+
+ // Test dynamically applying a null safe function of static type
+ // void Function(Never) in a null safe library, when called with
+ // null.
+ {
+ applyTakesNeverDynamically(takesNull, nil);
+ applyTakesNeverDynamically(takesNever, nil);
+ applyTakesNeverDynamically(takesAny, nil);
+ applyTakesNeverDynamically(takesInt, nil);
+ applyTakesNeverDynamically(takesObject, nil);
+ }
+
+ // Test dynamically applying a null safe function of static type
+ // void Function(Never) in a null safe library, when called with
+ // a non-null value.
+ {
+ applyTakesNeverDynamically(takesNull, 3);
+ applyTakesNeverDynamically(takesNever, 3);
+ applyTakesNeverDynamically(takesInt, 3);
+ applyTakesNeverDynamically(takesInt, "hello");
+ applyTakesNeverDynamically(takesObject, 3);
+ applyTakesNeverDynamically(takesAny, 3);
+ }
+}
+
+void main() {
+ never = null;
+ // ^
+ // [analyzer] unspecified
+ // ^
+ // [cfe] A value of type 'Null?' can't be assigned to a variable of type 'Never'.
+ never = nil;
+ // ^
+ // [analyzer] unspecified
+ // ^
+ // [cfe] A value of type 'Null?' can't be assigned to a variable of type 'Never'.
+ nil = never;
+ testNullSafeCalls();
+ testNullSafeApply();
+ testNullSafeApplyDynamically();
+}
diff --git a/tests/language/nnbd/never/never_null_assignability_lib1.dart b/tests/language/nnbd/never/never_null_assignability_lib1.dart
new file mode 100644
index 0000000..b006476
--- /dev/null
+++ b/tests/language/nnbd/never/never_null_assignability_lib1.dart
@@ -0,0 +1,49 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+Null nil = null;
+
+Never never = throw "Never";
+
+void takesAny(Object? n) {}
+
+void takesObject(Object n) {
+ // In weak mode, we may get null. Throw AssertionError so that this
+ // can be distinguished from a dynamic call failure.
+ if (n == null) throw AssertionError("Not an Object");
+}
+
+void takesInt(int n) {
+ // In weak mode, we may get null. Throw AssertionError so that this
+ // can be distinguished from a dynamic call failure.
+ if (n == null) throw AssertionError("Not an int");
+}
+
+void takesNull(Null n) {
+ if (n != null) throw AssertionError("Not null");
+}
+
+void takesNever(Never n) {
+ // In weak mode, we may get null. Throw AssertionError so that this
+ // can be distinguished from a dynamic call failure.
+ if (n != null) throw AssertionError("Not null");
+}
+
+void applyTakesNull(void Function(Null) fn, dynamic arg) {
+ // Make the cast explicit for clarity.
+ fn(arg as Null);
+}
+
+void applyTakesNever(void Function(Never) fn, dynamic arg) {
+ // Make the cast explicit for clarity.
+ fn(arg as Never);
+}
+
+void applyTakesNullDynamically(void Function(Null) fn, dynamic arg) {
+ (fn as dynamic)(arg);
+}
+
+void applyTakesNeverDynamically(void Function(Never) fn, dynamic arg) {
+ (fn as dynamic)(arg);
+}
diff --git a/tests/language/nnbd/never/never_null_assignability_strong_test.dart b/tests/language/nnbd/never/never_null_assignability_strong_test.dart
new file mode 100644
index 0000000..a902e45
--- /dev/null
+++ b/tests/language/nnbd/never/never_null_assignability_strong_test.dart
@@ -0,0 +1,146 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Requirements=nnbd-strong
+
+import 'package:expect/expect.dart';
+import 'never_null_assignability_lib1.dart';
+
+// Tests for direct calls to null safe functions.
+void testNullSafeCalls() {
+ // Test calling a null safe function expecting Null from a null safe libary
+ {
+ takesNull(nil);
+ Expect.throws<String>(() => takesNull(never));
+ // 3 can't be cast to Null or Never
+ Expect.throwsTypeError(() => takesNull(3 as dynamic));
+ Expect.throwsTypeError(() => (takesNull as dynamic)(3));
+ }
+
+ // Test calling a null safe function expecting Never from a null safe libary
+ {
+ Expect.throws<String>(() => takesNever(never));
+ // 3 can't be cast to Null or Never
+ Expect.throwsTypeError(() => takesNever(3 as dynamic));
+ Expect.throwsTypeError(() => (takesNever as dynamic)(3));
+ }
+
+ // Test calling a null safe function expecting int from a null safe libary
+ {
+ takesInt(3);
+ Expect.throwsTypeError(() => takesInt(nil as dynamic));
+ Expect.throwsTypeError(() => (takesInt as dynamic)(nil));
+ Expect.throwsTypeError(() => (takesInt as dynamic)("hello"));
+ }
+
+ // Test calling a null safe function expecting Object from a null safe libary
+ {
+ takesObject(3);
+ Expect.throwsTypeError(() => takesObject(nil as dynamic));
+ Expect.throwsTypeError(() => (takesObject as dynamic)(nil));
+ }
+
+ // Test calling a null safe function expecting Object? from a null safe libary
+ {
+ takesAny(3);
+ takesAny(nil);
+ (takesAny as dynamic)(nil);
+ }
+}
+
+void testNullSafeApply() {
+ // Test applying a null safe function of static type void Function(Null)
+ // in a null safe library, when called with null cast to Null at the call
+ // site.
+ {
+ applyTakesNull(takesNull, nil);
+ applyTakesNull(takesAny, nil);
+ }
+
+ // Test applying a null safe function of static type void Function(Null)
+ // in a null safe library, when called with a non-null value cast to Null
+ // at the call site.
+ {
+ Expect.throwsTypeError(() => applyTakesNull(takesNull, 3));
+ Expect.throwsTypeError(() => applyTakesNull(takesAny, 3));
+ }
+
+ // Test applying a null safe function of static type void Function(Never)
+ // in a null safe library, when called with null cast to Never at the call
+ // site.
+ {
+ // Cast of null to Never should fail.
+ Expect.throwsTypeError(() => applyTakesNever(takesNull, nil));
+ // Cast of null to Never should fail.
+ Expect.throwsTypeError(() => applyTakesNever(takesNever, nil));
+ // Cast of null to Never should fail.
+ Expect.throwsTypeError(() => applyTakesNever(takesInt, nil));
+ // Cast of null to Never should fail.
+ Expect.throwsTypeError(() => applyTakesNever(takesObject, nil));
+ // Cast of null to Never should fail.
+ Expect.throwsTypeError(() => applyTakesNever(takesAny, nil));
+ }
+
+ // Test applying a null safe function of static type void Function(Never)
+ // in a null safe library, when called with a non-null value cast to Never
+ // at the call site.
+ {
+ Expect.throwsTypeError(() => applyTakesNever(takesNull, 3));
+ Expect.throwsTypeError(() => applyTakesNever(takesNever, 3));
+ Expect.throwsTypeError(() => applyTakesNever(takesInt, 3));
+ Expect.throwsTypeError(() => applyTakesNever(takesObject, 3));
+ Expect.throwsTypeError(() => applyTakesNever(takesAny, 3));
+ }
+}
+
+void testNullSafeApplyDynamically() {
+ // Test dynamically applying a null safe function of static type
+ // void Function(Null) in a null safe library, when called with
+ // null.
+ {
+ applyTakesNullDynamically(takesNull, nil);
+ applyTakesNullDynamically(takesAny, nil);
+ }
+
+ // Test dynamically applying a null safe function of static type
+ // void Function(Null) in a null safe library, when called with
+ // a non-null value.
+ {
+ Expect.throwsTypeError(() => applyTakesNullDynamically(takesNull, 3));
+ applyTakesNullDynamically(takesAny, 3);
+ }
+
+ // Test dynamically applying a null safe function of static type
+ // void Function(Never) in a null safe library, when called with
+ // null.
+ {
+ applyTakesNeverDynamically(takesNull, nil);
+ applyTakesNeverDynamically(takesAny, nil);
+
+ // Dynamic call should fail.
+ Expect.throwsTypeError(() => applyTakesNeverDynamically(takesNever, nil));
+ // Dynamic call should fail.
+ Expect.throwsTypeError(() => applyTakesNeverDynamically(takesInt, nil));
+ // Dynamic call should fail.
+ Expect.throwsTypeError(() => applyTakesNeverDynamically(takesObject, nil));
+ }
+
+ // Test dynamically applying a null safe function of static type
+ // void Function(Never) in a null safe library, when called with
+ // a non-null value.
+ {
+ Expect.throwsTypeError(() => applyTakesNeverDynamically(takesNull, 3));
+ Expect.throwsTypeError(() => applyTakesNeverDynamically(takesNever, 3));
+ applyTakesNeverDynamically(takesInt, 3);
+ Expect.throwsTypeError(() => applyTakesNeverDynamically(takesInt, "hello"));
+ applyTakesNeverDynamically(takesObject, 3);
+ applyTakesNeverDynamically(takesAny, 3);
+ }
+}
+
+void main() {
+ testNullSafeCalls();
+ testNullSafeApply();
+ testNullSafeApplyDynamically();
+}
diff --git a/tests/language/nnbd/never/never_null_assignability_weak_test.dart b/tests/language/nnbd/never/never_null_assignability_weak_test.dart
new file mode 100644
index 0000000..1c87799
--- /dev/null
+++ b/tests/language/nnbd/never/never_null_assignability_weak_test.dart
@@ -0,0 +1,316 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// @dart=2.7
+
+// Requirements=nnbd-weak
+
+import 'package:expect/expect.dart';
+import 'never_null_assignability_lib1.dart';
+
+void takesLegacyObject(Object n) {
+ // In a legacy library, we may get null. Throw AssertionError so that this
+ // can be distinguished from a dynamic call failure.
+ if (n == null) throw AssertionError("Not an Object");
+}
+
+void takesLegacyInt(int n) {
+ // In a legacy library, we may get null. Throw AssertionError so that this
+ // can be distinguished from a dynamic call failure.
+ if (n == null) throw AssertionError("Not an int");
+}
+
+void takesLegacyNull(Null n) {
+ // This should never happen!
+ if (n != null) throw AssertionError("Not null");
+}
+
+// Tests for direct calls to null safe functions.
+void testNullSafeCalls() {
+ // Test calling a null safe function expecting Null from a legacy library
+ {
+ takesNull(nil);
+ takesNull(never);
+ // Even in weak mode, 3 can't be cast to Null or Never
+ Expect.throwsTypeError(() => takesNull(3 as dynamic));
+ Expect.throwsTypeError(() => (takesNull as dynamic)(3));
+ }
+
+ // Test calling a null safe function expecting Never from a legacy library
+ {
+ takesNever(nil);
+ takesNever(never);
+ // Even in weak mode, 3 can't be cast to Null or Never
+ Expect.throwsTypeError(() => takesNever(3 as dynamic));
+ Expect.throwsTypeError(() => (takesNever as dynamic)(3));
+ }
+
+ // Test calling a null safe function expecting int from a legacy library
+ {
+ takesInt(3);
+ Expect.throwsAssertionError(() => takesInt(nil));
+ Expect.throwsAssertionError(() => takesInt(nil as dynamic));
+ Expect.throwsAssertionError(() => (takesInt as dynamic)(nil));
+ Expect.throwsTypeError(() => (takesInt as dynamic)("hello"));
+ }
+
+ // Test calling a null safe function expecting Object from a legacy library
+ {
+ takesObject(3);
+ Expect.throwsAssertionError(() => takesObject(nil));
+ Expect.throwsAssertionError(() => takesObject(nil as dynamic));
+ Expect.throwsAssertionError(() => (takesObject as dynamic)(nil));
+ }
+
+ // Test calling a null safe function expecting Object? from a legacy library
+ {
+ takesAny(3);
+ takesAny(nil);
+ (takesAny as dynamic)(nil);
+ }
+}
+
+// Tests for direct calls to legacy functions.
+void testLegacyCalls() {
+ // Test calling a legacy function expecting Null from a legacy library
+ {
+ takesLegacyNull(nil);
+ // Even in weak mode, 3 can't be cast to Null or Never
+ Expect.throwsTypeError(() => takesLegacyNull(3 as dynamic));
+ Expect.throwsTypeError(() => (takesLegacyNull as dynamic)(3));
+ }
+
+ // Test calling a legacy function expecting int from a legacy library
+ {
+ takesLegacyInt(3);
+ Expect.throwsAssertionError(() => takesLegacyInt(nil));
+ Expect.throwsAssertionError(() => (takesLegacyInt as dynamic)(nil));
+ Expect.throwsTypeError(() => (takesLegacyInt as dynamic)("hello"));
+ }
+
+ // Test calling a legacy function expecting Object from a legacy library
+ {
+ takesLegacyObject(3);
+ Expect.throwsAssertionError(() => takesLegacyObject(nil));
+ Expect.throwsAssertionError(() => (takesLegacyObject as dynamic)(nil));
+ }
+}
+
+void testNullSafeApply() {
+ // Test applying a null safe function of static type void Function(Null)
+ // in a null safe library, when called with null cast to Null at the call
+ // site.
+ {
+ applyTakesNull(takesNull, nil);
+ applyTakesNull(takesNever, nil);
+ applyTakesNull(takesAny, nil);
+
+ // Cast of null to Null shouldn't fail, check that we reach the assertion.
+ Expect.throwsAssertionError(() => applyTakesNull(takesInt, nil));
+ // Cast of null to Null shouldn't fail, check that we reach the assertion.
+ Expect.throwsAssertionError(() => applyTakesNull(takesObject, nil));
+ }
+
+ // Test applying a null safe function of static type void Function(Null)
+ // in a null safe library, when called with a non-null value cast to Null
+ // at the call site.
+ {
+ Expect.throwsTypeError(() => applyTakesNull(takesNull, 3));
+ Expect.throwsTypeError(() => applyTakesNull(takesNever, 3));
+ Expect.throwsTypeError(() => applyTakesNull(takesInt, 3));
+ Expect.throwsTypeError(() => applyTakesNull(takesObject, 3));
+ Expect.throwsTypeError(() => applyTakesNull(takesAny, 3));
+ }
+
+ // Test applying a null safe function of static type void Function(Never)
+ // in a null safe library, when called with null cast to Never at the call
+ // site.
+ {
+ applyTakesNever(takesNull, nil);
+ applyTakesNever(takesNever, nil);
+ applyTakesNever(takesAny, nil);
+
+ // Cast of null to Never shouldn't fail, check that we reach the assertion.
+ Expect.throwsAssertionError(() => applyTakesNever(takesInt, nil));
+ // Cast of null to Never shouldn't fail, check that we reach the assertion.
+ Expect.throwsAssertionError(() => applyTakesNever(takesObject, nil));
+ }
+
+ // Test applying a null safe function of static type void Function(Never)
+ // in a null safe library, when called with a non-null value cast to Never
+ // at the call site.
+ {
+ Expect.throwsTypeError(() => applyTakesNever(takesNull, 3));
+ Expect.throwsTypeError(() => applyTakesNever(takesNever, 3));
+ Expect.throwsTypeError(() => applyTakesNever(takesInt, 3));
+ Expect.throwsTypeError(() => applyTakesNever(takesObject, 3));
+ Expect.throwsTypeError(() => applyTakesNever(takesAny, 3));
+ }
+}
+
+void testLegacyApply() {
+ // Test applying a legacy function of static type void Function(Null)
+ // in a null safe library, when called with null cast to Null at the call
+ // site.
+ {
+ applyTakesNull(takesLegacyNull, nil);
+
+ // Cast of null to Null shouldn't fail, check that we reach the assertion.
+ Expect.throwsAssertionError(() => applyTakesNull(takesLegacyInt, nil));
+ // Cast of null to Null shouldn't fail, check that we reach the assertion.
+ Expect.throwsAssertionError(() => applyTakesNull(takesLegacyObject, nil));
+ }
+
+ // Test applying a legacy function of static type void Function(Null)
+ // in a null safe library, when called with a non-null value cast to Null
+ // at the call site.
+ {
+ Expect.throwsTypeError(() => applyTakesNull(takesLegacyNull, 3));
+ Expect.throwsTypeError(() => applyTakesNull(takesLegacyInt, 3));
+ Expect.throwsTypeError(() => applyTakesNull(takesLegacyObject, 3));
+ }
+
+ // Test applying a legacy function of static type void Function(Never)
+ // in a null safe library, when called with null cast to Never at the call
+ // site.
+ {
+ applyTakesNever(takesLegacyNull, nil);
+
+ // Cast of null to Never shouldn't fail, check that we reach the assertion.
+ Expect.throwsAssertionError(() => applyTakesNever(takesLegacyInt, nil));
+ // Cast of null to Never shouldn't fail, check that we reach the assertion.
+ Expect.throwsAssertionError(() => applyTakesNever(takesLegacyObject, nil));
+ }
+
+ // Test applying a legacy function of static type void Function(Never)
+ // in a null safe library, when called with a non-null value cast to Never
+ // at the call site.
+ {
+ Expect.throwsTypeError(() => applyTakesNever(takesLegacyNull, 3));
+ Expect.throwsTypeError(() => applyTakesNever(takesLegacyInt, 3));
+ Expect.throwsTypeError(() => applyTakesNever(takesLegacyObject, 3));
+ }
+}
+
+void testNullSafeApplyDynamically() {
+ // Test dynamically applying a null safe function of static type
+ // void Function(Null) in a null safe library, when called with
+ // null.
+ {
+ applyTakesNullDynamically(takesNull, nil);
+ applyTakesNullDynamically(takesNever, nil);
+ applyTakesNullDynamically(takesAny, nil);
+
+ // Dynamic call shouldn't fail, check that we reach the assertion.
+ Expect.throwsAssertionError(() => applyTakesNullDynamically(takesInt, nil));
+ // Dynamic call shouldn't fail, check that we reach the assertion.
+ Expect.throwsAssertionError(
+ () => applyTakesNullDynamically(takesObject, nil));
+ }
+
+ // Test dynamically applying a null safe function of static type
+ // void Function(Null) in a null safe library, when called with
+ // a non-null value.
+ {
+ Expect.throwsTypeError(() => applyTakesNullDynamically(takesNull, 3));
+ Expect.throwsTypeError(() => applyTakesNullDynamically(takesNever, 3));
+ applyTakesNullDynamically(takesInt, 3);
+ Expect.throwsTypeError(() => applyTakesNullDynamically(takesInt, "hello"));
+ applyTakesNullDynamically(takesObject, 3);
+ applyTakesNullDynamically(takesAny, 3);
+ }
+
+ // Test dynamically applying a null safe function of static type
+ // void Function(Never) in a null safe library, when called with
+ // null.
+ {
+ applyTakesNeverDynamically(takesNull, nil);
+ applyTakesNeverDynamically(takesNever, nil);
+ applyTakesNeverDynamically(takesAny, nil);
+
+ // Dynamic call shouldn't fail, check that we reach the assertion.
+ Expect.throwsAssertionError(
+ () => applyTakesNeverDynamically(takesInt, nil));
+ // Dynamic call shouldn't fail, check that we reach the assertion.
+ Expect.throwsAssertionError(
+ () => applyTakesNeverDynamically(takesObject, nil));
+ }
+
+ // Test dynamically applying a null safe function of static type
+ // void Function(Never) in a null safe library, when called with
+ // a non-null value.
+ {
+ Expect.throwsTypeError(() => applyTakesNeverDynamically(takesNull, 3));
+ Expect.throwsTypeError(() => applyTakesNeverDynamically(takesNever, 3));
+ applyTakesNeverDynamically(takesInt, 3);
+ Expect.throwsTypeError(() => applyTakesNeverDynamically(takesInt, "hello"));
+ applyTakesNeverDynamically(takesObject, 3);
+ applyTakesNeverDynamically(takesAny, 3);
+ }
+}
+
+void testLegacyApplyDynamically() {
+ // Test dynamically applying a legacy function of static type
+ // void Function(Null) in a null safe library, when called with
+ // null.
+ {
+ applyTakesNullDynamically(takesLegacyNull, nil);
+
+ // Dynamic call shouldn't fail, check that we reach the assertion.
+ Expect.throwsAssertionError(
+ () => applyTakesNullDynamically(takesLegacyInt, nil));
+ // Dynamic call shouldn't fail, check that we reach the assertion.
+ Expect.throwsAssertionError(
+ () => applyTakesNullDynamically(takesLegacyObject, nil));
+ }
+
+ // Test dynamically applying a legacy function of static type
+ // void Function(Null) in a null safe library, when called with
+ // a non-null value.
+ {
+ Expect.throwsTypeError(() => applyTakesNullDynamically(takesLegacyNull, 3));
+ applyTakesNullDynamically(takesLegacyInt, 3);
+ Expect.throwsTypeError(
+ () => applyTakesNullDynamically(takesLegacyInt, "hello"));
+ applyTakesNullDynamically(takesLegacyObject, 3);
+ }
+
+ // Test dynamically applying a legacy function of static type
+ // void Function(Never) in a null safe library, when called with
+ // null.
+ {
+ applyTakesNeverDynamically(takesLegacyNull, nil);
+
+ // Dynamic call shouldn't fail, check that we reach the assertion.
+ Expect.throwsAssertionError(
+ () => applyTakesNeverDynamically(takesLegacyInt, nil));
+ // Dynamic call shouldn't fail, check that we reach the assertion.
+ Expect.throwsAssertionError(
+ () => applyTakesNeverDynamically(takesLegacyObject, nil));
+ }
+
+ // Test dynamically applying a legacy function of static type
+ // void Function(Never) in a null safe library, when called with
+ // a non-null value.
+ {
+ Expect.throwsTypeError(
+ () => applyTakesNeverDynamically(takesLegacyNull, 3));
+ applyTakesNeverDynamically(takesLegacyInt, 3);
+ Expect.throwsTypeError(
+ () => applyTakesNeverDynamically(takesLegacyInt, "hello"));
+ applyTakesNeverDynamically(takesLegacyObject, 3);
+ }
+}
+
+void main() {
+ never = null;
+ never = nil;
+ nil = never;
+ testNullSafeCalls();
+ testLegacyCalls();
+ testNullSafeApply();
+ testLegacyApply();
+ testNullSafeApplyDynamically();
+ testLegacyApplyDynamically();
+}
diff --git a/tests/language/nnbd/resolution/issue41479_test.dart b/tests/language/nnbd/resolution/issue41479_test.dart
new file mode 100644
index 0000000..bf6f6cd
--- /dev/null
+++ b/tests/language/nnbd/resolution/issue41479_test.dart
@@ -0,0 +1,13 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// SharedOptions=--enable-experiment=non-nullable
+
+main() {
+ A a = A()..foo?.isEven;
+}
+
+class A {
+ int? get foo => 0;
+}
diff --git a/tests/language/nnbd/static_errors/unchecked_use_of_nullable_test.dart b/tests/language/nnbd/static_errors/unchecked_use_of_nullable_test.dart
index cee406f..4e23e5f 100644
--- a/tests/language/nnbd/static_errors/unchecked_use_of_nullable_test.dart
+++ b/tests/language/nnbd/static_errors/unchecked_use_of_nullable_test.dart
@@ -170,7 +170,7 @@
dyn.toString(); //# 124: ok
dyn.hashCode; //# 125: ok
dyn.runtimeType; //# 126: ok
- dyn.noSuchMethod(null); //# 127: ok
+ dyn.noSuchMethod(Invocation.method(#toString, [])); //# 127: ok
dyn + 1; //# 128: ok
-dyn; //# 129: ok
dyn++; //# 130: ok
diff --git a/tests/language/nnbd/type_promotion/function_expression_outer_is_type_assigned_outside_test.dart b/tests/language/nnbd/type_promotion/function_expression_outer_is_type_assigned_outside_test.dart
index a9a546f..dd1df88 100644
--- a/tests/language/nnbd/type_promotion/function_expression_outer_is_type_assigned_outside_test.dart
+++ b/tests/language/nnbd/type_promotion/function_expression_outer_is_type_assigned_outside_test.dart
@@ -5,7 +5,7 @@
// SharedOptions=--enable-experiment=non-nullable
void f(Object x) {
- void Function() g;
+ late void Function() g;
if (x is String) {
x.length;
diff --git a/tests/language/regress/regress41613_test.dart b/tests/language/regress/regress41613_test.dart
new file mode 100644
index 0000000..0ea1de0
--- /dev/null
+++ b/tests/language/regress/regress41613_test.dart
@@ -0,0 +1,16 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// @dart=2.7
+
+// Requirements=nnbd-weak
+
+import "package:expect/expect.dart";
+
+main() {
+ // In legacy Dart 2 and null safety weak mode the error handlers can
+ // return null.
+ Expect.equals(null, int.parse("foo", onError: (_) => null));
+ Expect.equals(null, double.parse("foo", (_) => null));
+}
diff --git a/tests/language_2/regress/regress41613_test.dart b/tests/language_2/regress/regress41613_test.dart
new file mode 100644
index 0000000..5c31ecb
--- /dev/null
+++ b/tests/language_2/regress/regress41613_test.dart
@@ -0,0 +1,12 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+main() {
+ // In legacy Dart 2 and null safety weak mode the error handlers can
+ // return null.
+ Expect.equals(null, int.parse("foo", onError: (_) => null));
+ Expect.equals(null, double.parse("foo", (_) => null));
+}
diff --git a/tests/lib/async/futures_test.dart b/tests/lib/async/futures_test.dart
index 88c8d7a..1cf5e0e 100644
--- a/tests/lib/async/futures_test.dart
+++ b/tests/lib/async/futures_test.dart
@@ -77,6 +77,15 @@
});
}
+// Regression test for https://github.com/dart-lang/sdk/issues/41656
+Future testWaitWithErrorAndNonErrorEager() {
+ return Future(() {
+ var f1 = Future(() => throw "Error");
+ var f2 = Future(() => 3);
+ return Future.wait([f1, f2], eagerError: true);
+ }).then((_) => 0, onError: (_) => -1);
+}
+
Future testWaitWithMultipleErrorsEager() {
final futures = <Future>[];
final c1 = new Completer();
@@ -249,6 +258,7 @@
futures.add(testWaitWithMultipleValues());
futures.add(testWaitWithSingleError());
futures.add(testWaitWithMultipleErrors());
+ futures.add(testWaitWithErrorAndNonErrorEager());
futures.add(testWaitWithMultipleErrorsEager());
futures.add(testWaitWithSingleErrorWithStackTrace());
futures.add(testWaitWithMultipleErrorsWithStackTrace());
@@ -264,7 +274,7 @@
asyncStart();
Future.wait(futures).then((List list) {
- Expect.equals(18, list.length);
+ Expect.equals(19, list.length);
asyncEnd();
});
}
diff --git a/tests/lib/async/slow_consumer2_test.dart b/tests/lib/async/slow_consumer2_test.dart
index 5722efb..15710a4 100644
--- a/tests/lib/async/slow_consumer2_test.dart
+++ b/tests/lib/async/slow_consumer2_test.dart
@@ -88,7 +88,7 @@
listSize -= sentCount - targetCount;
sentCount = targetCount;
}
- controller.add(new List(listSize));
+ controller.add(List.filled(listSize, -1));
int ms = listSize * 1000 ~/ bytesPerSecond;
Duration duration = new Duration(milliseconds: ms);
if (!controller.isPaused) new Timer(duration, send);
diff --git a/tests/lib/html/js_util_test.dart b/tests/lib/html/js_util_test.dart
index ab74e43..f06e729 100644
--- a/tests/lib/html/js_util_test.dart
+++ b/tests/lib/html/js_util_test.dart
@@ -360,12 +360,12 @@
});
});
- void testResolvedPromise() async {
+ Future<void> testResolvedPromise() async {
final String result = await js_util.promiseToFuture(resolvedPromise);
expect(result, equals('resolved'));
}
- void testRejectedPromise() async {
+ Future<void> testRejectedPromise() async {
try {
final String result = await promiseToFuture(rejectedPromise);
fail('expected Future to throw an error');
@@ -374,7 +374,7 @@
}
}
- void testReturnRejectedPromise() async {
+ Future<void> testReturnRejectedPromise() async {
final String result = await promiseToFuture(getResolvedPromise());
expect(result, equals('resolved'));
}
diff --git a/tests/lib/mirrors/relation_subclass_test.dart b/tests/lib/mirrors/relation_subclass_test.dart
index 7e83931..a80194a 100644
--- a/tests/lib/mirrors/relation_subclass_test.dart
+++ b/tests/lib/mirrors/relation_subclass_test.dart
@@ -96,12 +96,12 @@
TypeMirror IntGenRef = (IntGen as TypedefMirror).referent;
TypeMirror DubGenRef = (DubGen as TypedefMirror).referent;
- Expect.isFalse(Func.isSubclassOf(NumPredRef));
- Expect.isFalse(Func.isSubclassOf(IntPredRef));
- Expect.isFalse(Func.isSubclassOf(DubPredRef));
- Expect.isFalse(Func.isSubclassOf(NumGenRef));
- Expect.isFalse(Func.isSubclassOf(IntGenRef));
- Expect.isFalse(Func.isSubclassOf(DubGenRef));
+ Expect.isFalse(Func.isSubclassOf(NumPredRef as ClassMirror));
+ Expect.isFalse(Func.isSubclassOf(IntPredRef as ClassMirror));
+ Expect.isFalse(Func.isSubclassOf(DubPredRef as ClassMirror));
+ Expect.isFalse(Func.isSubclassOf(NumGenRef as ClassMirror));
+ Expect.isFalse(Func.isSubclassOf(IntGenRef as ClassMirror));
+ Expect.isFalse(Func.isSubclassOf(DubGenRef as ClassMirror));
// The spec doesn't require these to be either value, only that they implement
// Function.
diff --git a/tests/lib/mirrors/typedef_reflected_type_test.dart b/tests/lib/mirrors/typedef_reflected_type_test.dart
index 7b017f5..43b1378 100644
--- a/tests/lib/mirrors/typedef_reflected_type_test.dart
+++ b/tests/lib/mirrors/typedef_reflected_type_test.dart
@@ -12,7 +12,7 @@
typedef int Bar();
class C {
- Bar fun(Foo<int> x) => null;
+ Bar fun(Foo<int> x) => () => 123;
}
main() {
diff --git a/tests/lib_2/async/futures_test.dart b/tests/lib_2/async/futures_test.dart
index a98d612..26b3019 100644
--- a/tests/lib_2/async/futures_test.dart
+++ b/tests/lib_2/async/futures_test.dart
@@ -77,6 +77,15 @@
});
}
+// Regression test for https://github.com/dart-lang/sdk/issues/41656
+Future testWaitWithErrorAndNonErrorEager() {
+ return Future(() {
+ var f1 = Future(() => throw "Error");
+ var f2 = Future(() => 3);
+ return Future.wait([f1, f2], eagerError: true);
+ }).then((_) => 0, onError: (_) => -1);
+}
+
Future testWaitWithMultipleErrorsEager() {
final futures = new List<Future>();
final c1 = new Completer();
@@ -250,6 +259,7 @@
futures.add(testWaitWithMultipleValues());
futures.add(testWaitWithSingleError());
futures.add(testWaitWithMultipleErrors());
+ futures.add(testWaitWithErrorAndNonErrorEager());
futures.add(testWaitWithMultipleErrorsEager());
futures.add(testWaitWithSingleErrorWithStackTrace());
futures.add(testWaitWithMultipleErrorsWithStackTrace());
@@ -265,7 +275,7 @@
asyncStart();
Future.wait(futures).then((List list) {
- Expect.equals(18, list.length);
+ Expect.equals(19, list.length);
asyncEnd();
});
}
diff --git a/tests/lib_2/html/js_util_test.dart b/tests/lib_2/html/js_util_test.dart
index 0166e9c..d32df10 100644
--- a/tests/lib_2/html/js_util_test.dart
+++ b/tests/lib_2/html/js_util_test.dart
@@ -360,12 +360,12 @@
});
});
- void testResolvedPromise() async {
+ Future<void> testResolvedPromise() async {
final String result = await js_util.promiseToFuture(resolvedPromise);
expect(result, equals('resolved'));
}
- void testRejectedPromise() async {
+ Future<void> testRejectedPromise() async {
try {
final String result = await promiseToFuture(rejectedPromise);
fail('expected Future to throw an error');
@@ -374,7 +374,7 @@
}
}
- void testReturnRejectedPromise() async {
+ Future<void> testReturnRejectedPromise() async {
final String result = await promiseToFuture(getResolvedPromise());
expect(result, equals('resolved'));
}
diff --git a/tests/standalone/array_bounds_check_generalization_test.dart b/tests/standalone/array_bounds_check_generalization_test.dart
index 96b5946..537b0b2 100644
--- a/tests/standalone/array_bounds_check_generalization_test.dart
+++ b/tests/standalone/array_bounds_check_generalization_test.dart
@@ -72,7 +72,7 @@
main() {
var a = const [0, 1, 2, 3, 4, 5, 6, 7];
- var b = new List(a.length);
+ var b = List.filled(a.length, -1);
for (var i = 0; i < 10000; i++) {
Expect.equals(a.last, test1(a, 0, 1, a.length));
Expect.equals(a.last, test2(a, b));
@@ -84,6 +84,6 @@
test1(a, 0, 2, a.length ~/ 2);
Expect.throws(() => test1(a, 1, 1, a.length));
- Expect.throws(() => test2(a, new List(a.length - 1)));
+ Expect.throws(() => test2(a, List.filled(a.length - 1, -1)));
Expect.throws(() => test6(a, 4, 3));
}
diff --git a/tests/standalone/io/http_compression_test.dart b/tests/standalone/io/http_compression_test.dart
index ae5507c..594d5d7 100644
--- a/tests/standalone/io/http_compression_test.dart
+++ b/tests/standalone/io/http_compression_test.dart
@@ -11,8 +11,8 @@
import 'dart:io';
import 'dart:typed_data';
-void testServerCompress({bool clientAutoUncompress: true}) async {
- void test(List<int> data) async {
+Future<void> testServerCompress({bool clientAutoUncompress: true}) async {
+ Future<void> test(List<int> data) async {
final server = await HttpServer.bind("127.0.0.1", 0);
server.autoCompress = true;
server.listen((request) {
@@ -45,8 +45,8 @@
await test(longBuffer);
}
-void testAcceptEncodingHeader() async {
- void test(String encoding, bool valid) async {
+Future<void> testAcceptEncodingHeader() async {
+ Future<void> test(String encoding, bool valid) async {
final server = await HttpServer.bind("127.0.0.1", 0);
server.autoCompress = true;
server.listen((request) {
@@ -78,7 +78,7 @@
await test('gzipx;', false);
}
-void testDisableCompressTest() async {
+Future<void> testDisableCompressTest() async {
final server = await HttpServer.bind("127.0.0.1", 0);
Expect.equals(false, server.autoCompress);
server.listen((request) {
diff --git a/tests/standalone/io/http_parser_connect_method.dart b/tests/standalone/io/http_parser_connect_method.dart
new file mode 100644
index 0000000..f543bcd
--- /dev/null
+++ b/tests/standalone/io/http_parser_connect_method.dart
@@ -0,0 +1,39 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "dart:async";
+import "dart:io";
+import "package:expect/expect.dart";
+
+test(String header, value) async {
+ final connect = "CONNECT";
+ var server = await HttpServer.bind("127.0.0.1", 0);
+ server.listen((HttpRequest request) {
+ Expect.equals(connect, request.method);
+ request.response.statusCode = 200;
+ request.response.headers.add(header, value);
+ request.response.close();
+ });
+
+ var completer = Completer();
+ HttpClient client = HttpClient();
+ client
+ .open(connect, "127.0.0.1", server.port, "/")
+ .then((HttpClientRequest request) {
+ return request.close();
+ }).then((HttpClientResponse response) {
+ Expect.isTrue(response.statusCode == 200);
+ Expect.isNull(response.headers[header]);
+ client.close();
+ server.close();
+ completer.complete();
+ });
+
+ await completer.future;
+}
+
+main() async {
+ await test(HttpHeaders.contentLengthHeader, 0);
+ await test(HttpHeaders.transferEncodingHeader, 'chunked');
+}
diff --git a/tests/standalone/io/http_parser_connect_method_test.dart b/tests/standalone/io/http_parser_connect_method_test.dart
deleted file mode 100644
index ab02945..0000000
--- a/tests/standalone/io/http_parser_connect_method_test.dart
+++ /dev/null
@@ -1,56 +0,0 @@
-// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import "dart:async";
-import "dart:io";
-
-import "package:async_helper/async_helper.dart";
-import "package:expect/expect.dart";
-
-Future<void> test(String header, value) async {
- final connect = "CONNECT";
- final server = await HttpServer.bind("127.0.0.1", 0);
- server.listen((HttpRequest request) {
- Expect.equals(connect, request.method);
- request.response.statusCode = 200;
- request.response.headers.add(header, value);
- request.response.close();
- });
-
- final completer = Completer<void>();
- HttpClient client = HttpClient();
- client
- .open(connect, "127.0.0.1", server.port, "/")
- .then((HttpClientRequest request) {
- return request.close();
- }).then((HttpClientResponse response) {
- Expect.equals(200, response.statusCode);
- // Headers except Content-Length and Transfer-Encoding header will be read.
- if (header == HttpHeaders.contentLengthHeader ||
- header == HttpHeaders.transferEncodingHeader) {
- Expect.isNull(response.headers[header]);
- } else {
- final list = response.headers[header];
- Expect.isNotNull(list);
- Expect.equals(1, list!.length);
- Expect.equals(value, list[0]);
- }
-
- client.close();
- server.close();
- completer.complete();
- });
-
- await completer.future;
-}
-
-Future<void> runTests() async {
- await test(HttpHeaders.contentLengthHeader, 0);
- await test(HttpHeaders.transferEncodingHeader, 'chunked');
- await test('testHeader', 'testValue');
-}
-
-main() {
- asyncTest(runTests);
-}
diff --git a/tests/standalone/io/http_parser_header_add_test.dart b/tests/standalone/io/http_parser_header_add_test.dart
deleted file mode 100644
index ebb947b..0000000
--- a/tests/standalone/io/http_parser_header_add_test.dart
+++ /dev/null
@@ -1,25 +0,0 @@
-// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import "dart:io";
-
-import "package:async_helper/async_helper.dart";
-
-// The ’ character is U+2019 RIGHT SINGLE QUOTATION MARK.
-final value = 'Bob’s browser';
-
-// When a invalid value is added to http header, test that a FormatException is
-// thrown on an invalid user-agent header.
-Future<void> main() async {
- final client = HttpClient();
- client.userAgent = value;
-
- asyncExpectThrows<FormatException>(() async {
- try {
- await client.getUrl(Uri.parse('https://postman-echo.com/get?'));
- } finally {
- client.close(force: true);
- }
- });
-}
diff --git a/tests/standalone/io/socket_hang_test.dart b/tests/standalone/io/socket_hang_test.dart
index 810d2a1..2231844 100644
--- a/tests/standalone/io/socket_hang_test.dart
+++ b/tests/standalone/io/socket_hang_test.dart
@@ -2,12 +2,10 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-import 'dart:io';
+import 'dart:convert';
+import 'dart:io' as io;
-import 'package:expect/expect.dart';
-
-// A regression test for: https://github.com/dart-lang/sdk/issues/40589
-Future<void> main(List<String> args) async {
+void main(List<String> args) async {
if (args.length != 0) {
for (int i = 0; i < 100000; i++) {
print('line $i');
@@ -16,14 +14,11 @@
return;
} else {
// Create child process and keeps writing into stdout.
- final p = await Process.start(
- Platform.executable, [Platform.script.toFilePath(), 'child']);
- p.stdout.drain();
- p.stderr.drain();
+ final p = await io.Process.start(
+ io.Platform.executable, [io.Platform.script.toFilePath(), 'child']);
+ p.stdout.transform(utf8.decoder).listen((x) => print('stdout: $x'));
+ p.stderr.transform(utf8.decoder).listen((x) => print('stderr: $x'));
final exitCode = await p.exitCode;
- if (exitCode != 0) {
- Expect.fail('process failed with ${exitCode}');
- }
- return;
+ print('process exited with ${exitCode}');
}
}
diff --git a/tests/standalone/io/unix_socket_test.dart b/tests/standalone/io/unix_socket_test.dart
index cc6ed79..7c52777 100644
--- a/tests/standalone/io/unix_socket_test.dart
+++ b/tests/standalone/io/unix_socket_test.dart
@@ -74,7 +74,7 @@
var socket = await Socket.connect(address, server.port);
socket.write(" socket content");
- await socket.destroy();
+ socket.destroy();
await server.close();
}
@@ -138,7 +138,7 @@
}
// Create socket in temp directory
-Future withTempDir(String prefix, void test(Directory dir)) async {
+Future withTempDir(String prefix, Future<void> test(Directory dir)) async {
var tempDir = Directory.systemTemp.createTempSync(prefix);
try {
await test(tempDir);
diff --git a/tests/standalone_2/io/http_compression_test.dart b/tests/standalone_2/io/http_compression_test.dart
index 2e0b45f..ca9f2cf 100644
--- a/tests/standalone_2/io/http_compression_test.dart
+++ b/tests/standalone_2/io/http_compression_test.dart
@@ -11,8 +11,8 @@
import 'dart:io';
import 'dart:typed_data';
-void testServerCompress({bool clientAutoUncompress: true}) async {
- void test(List<int> data) async {
+Future<void> testServerCompress({bool clientAutoUncompress: true}) async {
+ Future<void> test(List<int> data) async {
final server = await HttpServer.bind("127.0.0.1", 0);
server.autoCompress = true;
server.listen((request) {
@@ -44,8 +44,8 @@
await test(longBuffer);
}
-void testAcceptEncodingHeader() async {
- void test(String encoding, bool valid) async {
+Future<void> testAcceptEncodingHeader() async {
+ Future<void> test(String encoding, bool valid) async {
final server = await HttpServer.bind("127.0.0.1", 0);
server.autoCompress = true;
server.listen((request) {
@@ -77,7 +77,7 @@
await test('gzipx;', false);
}
-void testDisableCompressTest() async {
+Future<void> testDisableCompressTest() async {
final server = await HttpServer.bind("127.0.0.1", 0);
Expect.equals(false, server.autoCompress);
server.listen((request) {
diff --git a/tests/standalone_2/io/http_parser_connect_method.dart b/tests/standalone_2/io/http_parser_connect_method.dart
new file mode 100644
index 0000000..f543bcd
--- /dev/null
+++ b/tests/standalone_2/io/http_parser_connect_method.dart
@@ -0,0 +1,39 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "dart:async";
+import "dart:io";
+import "package:expect/expect.dart";
+
+test(String header, value) async {
+ final connect = "CONNECT";
+ var server = await HttpServer.bind("127.0.0.1", 0);
+ server.listen((HttpRequest request) {
+ Expect.equals(connect, request.method);
+ request.response.statusCode = 200;
+ request.response.headers.add(header, value);
+ request.response.close();
+ });
+
+ var completer = Completer();
+ HttpClient client = HttpClient();
+ client
+ .open(connect, "127.0.0.1", server.port, "/")
+ .then((HttpClientRequest request) {
+ return request.close();
+ }).then((HttpClientResponse response) {
+ Expect.isTrue(response.statusCode == 200);
+ Expect.isNull(response.headers[header]);
+ client.close();
+ server.close();
+ completer.complete();
+ });
+
+ await completer.future;
+}
+
+main() async {
+ await test(HttpHeaders.contentLengthHeader, 0);
+ await test(HttpHeaders.transferEncodingHeader, 'chunked');
+}
diff --git a/tests/standalone_2/io/http_parser_connect_method_test.dart b/tests/standalone_2/io/http_parser_connect_method_test.dart
deleted file mode 100644
index d4ecad2..0000000
--- a/tests/standalone_2/io/http_parser_connect_method_test.dart
+++ /dev/null
@@ -1,55 +0,0 @@
-// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import "dart:async";
-import "dart:io";
-
-import "package:async_helper/async_helper.dart";
-import "package:expect/expect.dart";
-
-Future<void> test(String header, value) async {
- final connect = "CONNECT";
- final server = await HttpServer.bind("127.0.0.1", 0);
- server.listen((HttpRequest request) {
- Expect.equals(connect, request.method);
- request.response.statusCode = 200;
- request.response.headers.add(header, value);
- request.response.close();
- });
-
- final completer = Completer<void>();
- HttpClient client = HttpClient();
- client
- .open(connect, "127.0.0.1", server.port, "/")
- .then((HttpClientRequest request) {
- return request.close();
- }).then((HttpClientResponse response) {
- Expect.equals(200, response.statusCode);
- // Headers except Content-Length and Transfer-Encoding header will be read.
- if (header == HttpHeaders.contentLengthHeader ||
- header == HttpHeaders.transferEncodingHeader) {
- Expect.isNull(response.headers[header]);
- } else {
- Expect.isNotNull(response.headers[header]);
- Expect.equals(1, response.headers[header].length);
- Expect.equals(value, response.headers[header][0]);
- }
-
- client.close();
- server.close();
- completer.complete();
- });
-
- await completer.future;
-}
-
-Future<void> runTests() async {
- await test(HttpHeaders.contentLengthHeader, 0);
- await test(HttpHeaders.transferEncodingHeader, 'chunked');
- await test('testHeader', 'testValue');
-}
-
-main() {
- asyncTest(runTests);
-}
diff --git a/tests/standalone_2/io/http_parser_header_add_test.dart b/tests/standalone_2/io/http_parser_header_add_test.dart
deleted file mode 100644
index ebb947b..0000000
--- a/tests/standalone_2/io/http_parser_header_add_test.dart
+++ /dev/null
@@ -1,25 +0,0 @@
-// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import "dart:io";
-
-import "package:async_helper/async_helper.dart";
-
-// The ’ character is U+2019 RIGHT SINGLE QUOTATION MARK.
-final value = 'Bob’s browser';
-
-// When a invalid value is added to http header, test that a FormatException is
-// thrown on an invalid user-agent header.
-Future<void> main() async {
- final client = HttpClient();
- client.userAgent = value;
-
- asyncExpectThrows<FormatException>(() async {
- try {
- await client.getUrl(Uri.parse('https://postman-echo.com/get?'));
- } finally {
- client.close(force: true);
- }
- });
-}
diff --git a/tests/standalone_2/io/socket_hang_test.dart b/tests/standalone_2/io/socket_hang_test.dart
index 810d2a1..2231844 100644
--- a/tests/standalone_2/io/socket_hang_test.dart
+++ b/tests/standalone_2/io/socket_hang_test.dart
@@ -2,12 +2,10 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-import 'dart:io';
+import 'dart:convert';
+import 'dart:io' as io;
-import 'package:expect/expect.dart';
-
-// A regression test for: https://github.com/dart-lang/sdk/issues/40589
-Future<void> main(List<String> args) async {
+void main(List<String> args) async {
if (args.length != 0) {
for (int i = 0; i < 100000; i++) {
print('line $i');
@@ -16,14 +14,11 @@
return;
} else {
// Create child process and keeps writing into stdout.
- final p = await Process.start(
- Platform.executable, [Platform.script.toFilePath(), 'child']);
- p.stdout.drain();
- p.stderr.drain();
+ final p = await io.Process.start(
+ io.Platform.executable, [io.Platform.script.toFilePath(), 'child']);
+ p.stdout.transform(utf8.decoder).listen((x) => print('stdout: $x'));
+ p.stderr.transform(utf8.decoder).listen((x) => print('stderr: $x'));
final exitCode = await p.exitCode;
- if (exitCode != 0) {
- Expect.fail('process failed with ${exitCode}');
- }
- return;
+ print('process exited with ${exitCode}');
}
}
diff --git a/tests/standalone_2/io/unix_socket_test.dart b/tests/standalone_2/io/unix_socket_test.dart
index cc6ed79..7c52777 100644
--- a/tests/standalone_2/io/unix_socket_test.dart
+++ b/tests/standalone_2/io/unix_socket_test.dart
@@ -74,7 +74,7 @@
var socket = await Socket.connect(address, server.port);
socket.write(" socket content");
- await socket.destroy();
+ socket.destroy();
await server.close();
}
@@ -138,7 +138,7 @@
}
// Create socket in temp directory
-Future withTempDir(String prefix, void test(Directory dir)) async {
+Future withTempDir(String prefix, Future<void> test(Directory dir)) async {
var tempDir = Directory.systemTemp.createTempSync(prefix);
try {
await test(tempDir);
diff --git a/third_party/pkg_tested/pkg_tested.status b/third_party/pkg_tested/pkg_tested.status
index 47ab254..0b31420 100644
--- a/third_party/pkg_tested/pkg_tested.status
+++ b/third_party/pkg_tested/pkg_tested.status
@@ -15,7 +15,6 @@
pub/test/transformer/loads_a_diamond_transformer_dependency_graph_test: Pass, Slow
[ $runtime == vm ]
-dart_style/test/command_line_test: Skip # Issue 33473
http_io/test/http_cross_process_test: Skip # Fails with --no-preview-dart-2
http_io/test/http_proxy_advanced_test: Pass, RuntimeError # flaky
http_io/test/http_proxy_test: Pass, RuntimeError # flaky
diff --git a/tools/VERSION b/tools/VERSION
index aad0d9f..8324ed2 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -33,7 +33,7 @@
MAJOR 2
MINOR 9
PATCH 0
-PRERELEASE 3
+PRERELEASE 4
PRERELEASE_PATCH 0
ABI_VERSION 32
OLDEST_SUPPORTED_ABI_VERSION 32
diff --git a/tools/bots/get_builder_status.dart b/tools/bots/get_builder_status.dart
index 3612ffa..725c9f4 100755
--- a/tools/bots/get_builder_status.dart
+++ b/tools/bots/get_builder_status.dart
@@ -23,8 +23,6 @@
String builderBase;
int buildNumber;
String token;
-List<String> configurations;
-Map<String, List<Map<String, dynamic>>> failures = {};
http.Client client;
String get buildTable => builder.endsWith('-try') ? 'try_builds' : 'builds';
@@ -77,19 +75,21 @@
if (document != null) {
bool success = booleanFieldOrFalse(document, 'success');
bool completed = booleanFieldOrFalse(document, 'completed');
- bool activeFailures = booleanFieldOrFalse(document, 'active_failures');
if (completed) {
- if (success) {
- print('No unapproved new failures');
- if (activeFailures == true) {
- print('There are unapproved failures from previous builds');
- await printResults();
- }
+ print(success
+ ? 'No new unapproved failures'
+ : 'There are new unapproved failures on this build');
+ if (builder.endsWith('-try')) exit(success ? 0 : 1);
+ final configurations = await getConfigurations();
+ final failures = await fetchActiveFailures(configurations);
+ if (failures.isNotEmpty) {
+ print('There are unapproved failures');
+ printActiveFailures(failures);
+ exit(1);
} else {
- print('There are unapproved new failures on this build');
- await printResults();
+ print('There are no unapproved failures');
+ exit(0);
}
- exit((success && (activeFailures != true)) ? 0 : 1);
}
String chunks =
(document['fields']['num_chunks'] ?? const {})['integerValue'];
@@ -116,12 +116,6 @@
exit(2);
}
-void printResults() async {
- if (builder.endsWith('-try')) return;
- configurations = await getConfigurations();
- await printActiveFailures();
-}
-
Future<List<String>> getConfigurations() async {
final response = await runFirestoreQuery(configurationsQuery());
if (response.statusCode == HttpStatus.ok) {
@@ -153,7 +147,9 @@
return 'missing hash for commit $index';
}
-Future<void> printActiveFailures() async {
+Future<Map<String, List<Map<String, dynamic>>>> fetchActiveFailures(
+ List<String> configurations) async {
+ final failures = <String, List<Map<String, dynamic>>>{};
for (final configuration in configurations) {
final response =
await runFirestoreQuery(unapprovedFailuresQuery(configuration));
@@ -165,8 +161,10 @@
final fields = document['fields'];
failures.putIfAbsent(configuration, () => []).add({
'name': fields['name']['stringValue'],
- 'start': int.parse(fields['blamelist_start_index']['integerValue']),
- 'end': int.parse(fields['blamelist_end_index']['integerValue']),
+ 'start_commit': await commitHash(
+ int.parse(fields['blamelist_start_index']['integerValue'])),
+ 'end_commit': await commitHash(
+ int.parse(fields['blamelist_end_index']['integerValue'])),
'result': fields['result']['stringValue'],
'expected': fields['expected']['stringValue'],
'previous': fields['previous_result']['stringValue'],
@@ -174,6 +172,10 @@
}
}
}
+ return failures;
+}
+
+void printActiveFailures(Map<String, List<Map<String, dynamic>>> failures) {
for (final configuration in failures.keys) {
print('($configuration):');
for (final failure in failures[configuration]) {
@@ -187,10 +189,10 @@
', expected ',
failure['expected'],
') at ',
- (await commitHash(failure['start'])).substring(0, 6),
- if (failure['start'] != failure['end']) ...[
+ failure['start_commit'].substring(0, 6),
+ if (failure['end_commit'] != failure['start_commit']) ...[
'..',
- (await commitHash(failure['end'])).substring(0, 6)
+ failure['end_commit'].substring(0, 6)
]
].join(''));
}
diff --git a/tools/bots/test_matrix.json b/tools/bots/test_matrix.json
index 068c5df..32fbbf1 100644
--- a/tools/bots/test_matrix.json
+++ b/tools/bots/test_matrix.json
@@ -171,10 +171,13 @@
"tests/co19_2/co19_2-runtime.status",
"tests/compiler/",
"tests/corelib_2/",
+ "tests/corelib/",
"tests/dart/",
"tests/kernel/",
"tests/language_2/",
+ "tests/language/",
"tests/lib_2/",
+ "tests/lib/",
"tests/light_unittest.dart",
"tests/search/",
"tests/standalone_2/",
diff --git a/tools/dom/idl/dart/dart.idl b/tools/dom/idl/dart/dart.idl
index 150f727..d4f94297 100644
--- a/tools/dom/idl/dart/dart.idl
+++ b/tools/dom/idl/dart/dart.idl
@@ -4,7 +4,7 @@
interface WaveShaperNode {
// TODO(ager): Auto-generate this custom method when the info about retaining
// typed arrays is in the IDL.
- [Custom=Setter] attribute Float32Array curve;
+ [Custom=Setter] attribute Float32Array? curve;
};
[DartSupplemental]
@@ -40,14 +40,14 @@
[DartSupplemental]
interface Element {
- readonly attribute Element nextElementSibling;
- readonly attribute Element previousElementSibling;
+ readonly attribute Element? nextElementSibling;
+ readonly attribute Element? previousElementSibling;
};
[DartSupplemental]
interface CharacterData {
- readonly attribute Element nextElementSibling;
- readonly attribute Element previousElementSibling;
+ readonly attribute Element? nextElementSibling;
+ readonly attribute Element? previousElementSibling;
};
[Callback]
@@ -418,6 +418,9 @@
[DartSuppress] void scroll(long x, long y);
[DartSuppress] void scroll(long x, long y, Dictionary scrollOptions);
[RaisesException] void scroll(long x, long y, optional Dictionary scrollOptions);
+
+ [RuntimeEnabled=VisualViewportAPI, Replaceable, SameObject, DartSuppress] readonly attribute VisualViewport visualViewport;
+ [RuntimeEnabled=VisualViewportAPI, Replaceable, SameObject] readonly attribute VisualViewport? visualViewport;
};
[DartSupplemental]
diff --git a/tools/dom/scripts/databasebuilder.py b/tools/dom/scripts/databasebuilder.py
index 0636a47..e768ee4 100755
--- a/tools/dom/scripts/databasebuilder.py
+++ b/tools/dom/scripts/databasebuilder.py
@@ -271,6 +271,8 @@
res = node.id
if res.startswith('unsigned '):
res = res[len('unsigned '):]
+ if hasattr(node, 'nullable') and node.nullable:
+ res += '?'
return res
res = []
diff --git a/utils/dartdev/BUILD.gn b/utils/dartdev/BUILD.gn
index 495643d..44a5426 100644
--- a/utils/dartdev/BUILD.gn
+++ b/utils/dartdev/BUILD.gn
@@ -18,8 +18,20 @@
],
"list lines")
-application_snapshot("dartdev") {
+group("dartdev") {
+ deps = [ ":copy_dartdev_snapshot" ]
+}
+
+copy("copy_dartdev_snapshot") {
+ visibility = [ ":dartdev" ]
+ deps = [ ":generate_dartdev_snapshot" ]
+ sources = [ "$root_gen_dir/dartdev.dart.snapshot" ]
+ outputs = [ "$root_out_dir/dartdev.dart.snapshot" ]
+}
+
+application_snapshot("generate_dartdev_snapshot") {
main_dart = "../../pkg/dartdev/bin/dartdev.dart"
training_args = [ "--help" ]
inputs = dartdev_files + dartfix_files
+ output = "$root_gen_dir/dartdev.dart.snapshot"
}