Version 2.14.0-367.0.dev
Merge commit 'f5a98e7676030e96f55263ff987c0acb39f5256f' into 'dev'
diff --git a/CHANGELOG.md b/CHANGELOG.md
index aee53d3..b1dcdb8 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -264,6 +264,16 @@
[#46545]: https://github.com/dart-lang/sdk/issues/46545
[1]: https://dart.dev/faq#q-what-browsers-do-you-support-as-javascript-compilation-targets
+#### Dart Dev Compiler (DDC)
+
+- **Breaking Change** [#44154][]: Subtyping relations of `package:js` classes
+ have been changed to be more correct and consistent with Dart2JS.
+ Like `anonymous` classes, non-`anonymous` classes will no longer check the
+ underlying type in DDC. The internal type representation of these objects have
+ changed as well, which will affect the `toString` value of these types.
+
+[#44154]: https://github.com/dart-lang/sdk/issues/44154
+
## 2.13.4 - 2021-06-28
This is a patch release that fixes:
diff --git a/pkg/compiler/lib/src/compiler.dart b/pkg/compiler/lib/src/compiler.dart
index 9d3ca36..126df97 100644
--- a/pkg/compiler/lib/src/compiler.dart
+++ b/pkg/compiler/lib/src/compiler.dart
@@ -91,10 +91,6 @@
ImpactCacheDeleter get impactCacheDeleter => _impactCacheDeleter;
final Environment environment;
- // TODO(sigmund): delete once we migrate the rest of the compiler to use
- // `environment` directly.
- @deprecated
- fromEnvironment(String name) => environment.valueOf(name);
Entity get currentElement => _reporter.currentElement;
diff --git a/pkg/compiler/test/codegen/data_2/unused_empty_map.dart b/pkg/compiler/test/codegen/data_2/unused_empty_map.dart
index d9e0363..0ac9666 100644
--- a/pkg/compiler/test/codegen/data_2/unused_empty_map.dart
+++ b/pkg/compiler/test/codegen/data_2/unused_empty_map.dart
@@ -2,6 +2,8 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
+// ignore_for_file: unused_local_variable
+
@pragma('dart2js:noInline')
// No code to construct unused map.
/*member: foo1:function() {
diff --git a/pkg/compiler/test/deferred/load_graph_segmentation_test.dart b/pkg/compiler/test/deferred/load_graph_segmentation_test.dart
index 823899f..161a92b 100644
--- a/pkg/compiler/test/deferred/load_graph_segmentation_test.dart
+++ b/pkg/compiler/test/deferred/load_graph_segmentation_test.dart
@@ -42,6 +42,7 @@
var mainOutputUnit = closedWorld.outputUnitData.mainOutputUnit;
var backendStrategy = compiler.backendStrategy;
+ // ignore: deprecated_member_use_from_same_package
var classes = backendStrategy.emitterTask.neededClasses;
var inputElement = classes.where((e) => e.name == 'InputElement').single;
dynamic lib1 = lookupLibrary("memory:lib1.dart");
diff --git a/pkg/compiler/test/end_to_end/diagnostic_reporter_helper.dart b/pkg/compiler/test/end_to_end/diagnostic_reporter_helper.dart
index 0058660..ba061e2 100644
--- a/pkg/compiler/test/end_to_end/diagnostic_reporter_helper.dart
+++ b/pkg/compiler/test/end_to_end/diagnostic_reporter_helper.dart
@@ -56,6 +56,7 @@
@override
void reportInfoMessage(Spannable node, MessageKind errorCode,
[Map<String, String> arguments = const {}]) {
+ // ignore: deprecated_member_use_from_same_package
reporter.reportInfoMessage(node, errorCode, arguments);
}
diff --git a/pkg/compiler/test/end_to_end/library_env_test.dart b/pkg/compiler/test/end_to_end/library_env_test.dart
index ac96c89..f194f37 100644
--- a/pkg/compiler/test/end_to_end/library_env_test.dart
+++ b/pkg/compiler/test/end_to_end/library_env_test.dart
@@ -85,48 +85,57 @@
}
runTest() async {
- var compiler = new CustomCompiler([], {});
+ {
+ final compiler = new CustomCompiler([], {});
- await compiler.setupSdk();
+ await compiler.setupSdk();
+ final lookup = compiler.environment.valueOf;
- // Core libraries are always present.
- Expect.equals("true", compiler.fromEnvironment("dart.library.collection"));
- // Non-existing entries in the environment return 'null'.
- Expect.isNull(compiler.fromEnvironment("not in env"));
- // Check for client libraries (default if there are no flags to the compiler).
- Expect.equals("true", compiler.fromEnvironment("dart.library.mock.client"));
- Expect.equals("true", compiler.fromEnvironment("dart.library.html"));
- // Check for shared libraries..
- Expect.equals("true", compiler.fromEnvironment("dart.library.mock.shared"));
- // Check server libraries are not present.
- Expect.equals(null, compiler.fromEnvironment("dart.library.mock.server"));
- Expect.equals(null, compiler.fromEnvironment("dart.library.io"));
+ // Core libraries are always present.
+ Expect.equals("true", lookup("dart.library.collection"));
+ // Non-existing entries in the environment return 'null'.
+ Expect.isNull(lookup("not in env"));
+ // Check for client libraries (default if there are no flags to the compiler).
+ Expect.equals("true", lookup("dart.library.mock.client"));
+ Expect.equals("true", lookup("dart.library.html"));
+ // Check for shared libraries..
+ Expect.equals("true", lookup("dart.library.mock.shared"));
+ // Check server libraries are not present.
+ Expect.equals(null, lookup("dart.library.mock.server"));
+ Expect.equals(null, lookup("dart.library.io"));
+ }
+ {
+ final compiler = new CustomCompiler([Flags.serverMode], {});
- compiler = new CustomCompiler([Flags.serverMode], {});
+ await compiler.setupSdk();
+ final lookup = compiler.environment.valueOf;
- await compiler.setupSdk();
+ // Core libraries are always present.
+ Expect.equals("true", lookup("dart.library.collection"));
+ // Non-existing entries in the environment return 'null'.
+ Expect.isNull(lookup("not in env"));
+ // Check client libraries are not present.
+ Expect.equals(null, lookup("dart.library.mock.client"));
+ Expect.equals(null, lookup("dart.library.html"));
+ // Check for shared libraries..
+ Expect.equals("true", lookup("dart.library.mock.shared"));
+ // Check for server libraries.
+ Expect.equals("true", lookup("dart.library.mock.server"));
+ Expect.equals("true", lookup("dart.library.io"));
+ }
+ {
+ // Check that user-defined env-variables win.
+ final compiler = new CustomCompiler([], {
+ 'dart.library.collection': "false",
+ 'dart.library.mock.client': "foo"
+ });
- // Core libraries are always present.
- Expect.equals("true", compiler.fromEnvironment("dart.library.collection"));
- // Non-existing entries in the environment return 'null'.
- Expect.isNull(compiler.fromEnvironment("not in env"));
- // Check client libraries are not present.
- Expect.equals(null, compiler.fromEnvironment("dart.library.mock.client"));
- Expect.equals(null, compiler.fromEnvironment("dart.library.html"));
- // Check for shared libraries..
- Expect.equals("true", compiler.fromEnvironment("dart.library.mock.shared"));
- // Check for server libraries.
- Expect.equals("true", compiler.fromEnvironment("dart.library.mock.server"));
- Expect.equals("true", compiler.fromEnvironment("dart.library.io"));
+ await compiler.setupSdk();
+ final lookup = compiler.environment.valueOf;
- // Check that user-defined env-variables win.
- compiler = new CustomCompiler([],
- {'dart.library.collection': "false", 'dart.library.mock.client': "foo"});
-
- await compiler.setupSdk();
-
- Expect.equals("false", compiler.fromEnvironment("dart.library.collection"));
- Expect.equals("foo", compiler.fromEnvironment("dart.library.mock.client"));
+ Expect.equals("false", lookup("dart.library.collection"));
+ Expect.equals("foo", lookup("dart.library.mock.client"));
+ }
}
main() {
diff --git a/pkg/dev_compiler/lib/src/kernel/command.dart b/pkg/dev_compiler/lib/src/kernel/command.dart
index d6d428c..2de20df3 100644
--- a/pkg/dev_compiler/lib/src/kernel/command.dart
+++ b/pkg/dev_compiler/lib/src/kernel/command.dart
@@ -748,13 +748,17 @@
for (var e in compiler.classIdentifiers.entries)
e.key: identifierNames[e.value],
};
+ var procedureJsNames = <Procedure, String>{
+ for (var e in compiler.procedureIdentifiers.entries)
+ e.key: identifierNames[e.value],
+ };
var variableJsNames = <VariableDeclaration, String>{
for (var e in compiler.variableIdentifiers.entries)
e.key: identifierNames[e.value],
};
- return ModuleSymbolsCollector(
- moduleName, classJsNames, compiler.memberNames, variableJsNames)
+ return ModuleSymbolsCollector(moduleName, classJsNames, compiler.memberNames,
+ procedureJsNames, variableJsNames)
.collectSymbolInfo(component);
}
diff --git a/pkg/dev_compiler/lib/src/kernel/compiler.dart b/pkg/dev_compiler/lib/src/kernel/compiler.dart
index e1d06c4..e777ddf 100644
--- a/pkg/dev_compiler/lib/src/kernel/compiler.dart
+++ b/pkg/dev_compiler/lib/src/kernel/compiler.dart
@@ -61,6 +61,13 @@
/// module.
final memberNames = <Member, String>{};
+ /// Maps each `Procedure` node compiled in the module to the `Identifier`s
+ /// used to name the class in JavaScript.
+ ///
+ /// This mapping is used when generating the symbol information for the
+ /// module.
+ final procedureIdentifiers = <Procedure, js_ast.Identifier>{};
+
/// Maps each `VariableDeclaration` node compiled in the module to the name
/// used for the variable in JavaScript.
///
@@ -1670,7 +1677,7 @@
ctorFields = ctor.initializers
.map((c) => c is FieldInitializer ? c.field : null)
.toSet()
- ..remove(null);
+ ..remove(null);
}
var body = <js_ast.Statement>[];
@@ -2368,8 +2375,9 @@
Class memberClass}) {
// Static members skip the rename steps and may require JS interop renames.
if (isStatic) {
- // TODO(nshahan) Record the name for this member in memberNames.
- return _emitStaticMemberName(name, member);
+ var memberName = _emitStaticMemberName(name, member);
+ memberNames[member] = memberName.valueWithoutQuotes;
+ return memberName;
}
// We allow some (illegal in Dart) member names to be used in our private
@@ -2379,6 +2387,7 @@
var runtimeName = _jsExportName(member);
if (runtimeName != null) {
var parts = runtimeName.split('.');
+ // TODO(nshahan) Record the name for this member in memberNames.
if (parts.length < 2) return propertyName(runtimeName);
js_ast.Expression result = _emitIdentifier(parts[0]);
@@ -2652,8 +2661,9 @@
_currentUri = node.fileUri;
var name = node.name.text;
+ memberNames[node] = name;
var result = js_ast.Method(
- propertyName(name), _emitFunction(node.function, node.name.text),
+ propertyName(name), _emitFunction(node.function, name),
isGetter: node.isGetter, isSetter: node.isSetter)
..sourceInformation = _nodeEnd(node.fileEndOffset);
@@ -2678,8 +2688,10 @@
var nameExpr = _emitTopLevelName(p);
var jsName = _safeFunctionNameForSafari(p.name.text, fn);
- body.add(js.statement('# = #',
- [nameExpr, js_ast.NamedFunction(_emitTemporaryId(jsName), fn)]));
+ var functionName = _emitTemporaryId(jsName);
+ procedureIdentifiers[p] = functionName;
+ body.add(js.statement(
+ '# = #', [nameExpr, js_ast.NamedFunction(functionName, fn)]));
_currentUri = savedUri;
_staticTypeContext.leaveMember(p);
@@ -2872,27 +2884,15 @@
js_ast.Expression typeRep;
// Type parameters don't matter as JS interop types cannot be reified.
- // We have to use lazy JS types because until we have proper module
- // loading for JS libraries bundled with Dart libraries, we will sometimes
- // need to load Dart libraries before the corresponding JS libraries are
- // actually loaded.
- // Given a JS type such as:
- // @JS('google.maps.Location')
- // class Location { ... }
- // We can't emit a reference to MyType because the JS library that defines
- // it may be loaded after our code. So for now, we use a special lazy type
- // object to represent MyType.
- // Anonymous JS types do not have a corresponding concrete JS type so we
- // have to use a helper to define them.
- if (isJSAnonymousType(c)) {
- typeRep = runtimeCall(
- 'anonymousJSType(#)', [js.escapedString(getLocalClassName(c))]);
- } else {
- var jsName = _emitJsNameWithoutGlobal(c);
- if (jsName != null) {
- typeRep = runtimeCall('lazyJSType(() => #, #)',
- [_emitJSInteropForGlobal(jsName), js.escapedString(jsName)]);
- }
+ // package:js types fall under either named or anonymous types. Named types
+ // are used to correspond to JS types that exist, but we do not use the
+ // underlying type for type checks, so they operate virtually the same as
+ // anonymous types. We represent package:js types with a corresponding type
+ // object.
+ var jsName = isJSAnonymousType(c) ?
+ getLocalClassName(c) : _emitJsNameWithoutGlobal(c);
+ if (jsName != null) {
+ typeRep = runtimeCall('packageJSType(#)', [js.escapedString(jsName)]);
}
if (typeRep != null) {
@@ -3605,7 +3605,7 @@
}
for (var p in f.positionalParameters) {
- var jsParam = _emitVariableDef(p);
+ var jsParam = _emitVariableRef(p);
if (_checkParameters) {
initParameter(p, jsParam);
}
@@ -4510,13 +4510,9 @@
var name = v.name;
if (name == null || name.startsWith('#')) {
name = name == null ? 't${_tempVariables.length}' : name.substring(1);
- // TODO(nshahan) Record the Identifier for this variable in
- // variableIdentifiers.
return _tempVariables.putIfAbsent(v, () => _emitTemporaryId(name));
}
- var identifier = _emitIdentifier(name);
- variableIdentifiers[v] = identifier;
- return identifier;
+ return _emitIdentifier(name);
}
/// Emits the declaration of a variable.
@@ -4524,7 +4520,9 @@
/// This is similar to [_emitVariableRef] but it also attaches source
/// location information, so hover will work as expected.
js_ast.Identifier _emitVariableDef(VariableDeclaration v) {
- return _emitVariableRef(v)..sourceInformation = _nodeStart(v);
+ var identifier = _emitVariableRef(v)..sourceInformation = _nodeStart(v);
+ variableIdentifiers[v] = identifier;
+ return identifier;
}
js_ast.Statement _initLetVariables() {
@@ -6403,8 +6401,9 @@
Library library, String className, Member member,
[js_ast.TemporaryId id]) {
var name = '$className.${member.name.text}';
- // Names used in the symbols for the public fields
- // memberNames[member] = 'Symbol($name)';
+ // Wrap the name as a symbol here so it matches what you would find at
+ // runtime when you get all properties and symbols from an instance.
+ memberNames[member] = 'Symbol($name)';
return emitPrivateNameSymbol(library, name, id);
}
diff --git a/pkg/dev_compiler/lib/src/kernel/module_symbols_collector.dart b/pkg/dev_compiler/lib/src/kernel/module_symbols_collector.dart
index 2f16592..acb2bcd 100644
--- a/pkg/dev_compiler/lib/src/kernel/module_symbols_collector.dart
+++ b/pkg/dev_compiler/lib/src/kernel/module_symbols_collector.dart
@@ -14,13 +14,15 @@
/// The first scope added to the stack should always be the library scope. The
/// last element in the list represents the current scope.
final _scopes = <ScopeSymbol>[];
+
final ModuleSymbols _moduleSymbols;
final Map<Class, String> _classJsNames;
final Map<Member, String> _memberJsNames;
+ final Map<Procedure, String> _procedureJsNames;
final Map<VariableDeclaration, String> _variableJsNames;
ModuleSymbolsCollector(String moduleName, this._classJsNames,
- this._memberJsNames, this._variableJsNames)
+ this._memberJsNames, this._procedureJsNames, this._variableJsNames)
: _moduleSymbols = ModuleSymbols(
version: ModuleSymbols.current.version,
moduleName: moduleName,
@@ -28,7 +30,7 @@
scripts: <Script>[],
classes: <ClassSymbol>[],
// TODO(nshahan) functionTypes
- // TODO(nshahan) functions
+ functions: <FunctionSymbol>[],
// TODO(nshahan) scopes
variables: <VariableSymbol>[]);
@@ -142,8 +144,27 @@
// Legacy libraries contain procedures with no bodies for all Object methods
// in every class. We can ignore these unless they actually contain a body.
if (node.function.body == null) return;
- // TODO(nshahan) implement visitProcedure
- super.visitProcedure(node);
+ var functionSymbol = FunctionSymbol(
+ name: node.name.text,
+ // TODO(nshahan) typeId - probably should canonicalize but keep original
+ // type argument names.
+ isStatic: node.isStatic,
+ isConst: node.isConst,
+ localId: _memberJsNames[node] ?? _procedureJsNames[node],
+ scopeId: _scopes.last.id,
+ variableIds: <String>[],
+ scopeIds: <String>[],
+ location: SourceLocation(
+ scriptId: _scriptId(node.location.file),
+ tokenPos: node.fileOffset,
+ endTokenPos: node.fileEndOffset));
+
+ _scopes.add(functionSymbol);
+ node.visitChildren(this);
+ _scopes
+ ..removeLast()
+ ..last.scopeIds.add(functionSymbol.id);
+ _moduleSymbols.functions.add(functionSymbol);
}
@override
diff --git a/pkg/dev_compiler/test/module_symbols/class_symbols_test.dart b/pkg/dev_compiler/test/module_symbols/class_symbols_test.dart
index ee907ce..c08995f 100644
--- a/pkg/dev_compiler/test/module_symbols/class_symbols_test.dart
+++ b/pkg/dev_compiler/test/module_symbols/class_symbols_test.dart
@@ -293,6 +293,394 @@
expect(fieldSymbol.isStatic, isFalse);
});
});
+ group('class public instance method debug symbols', () {
+ TestDriver driver;
+ ClassSymbol classSymbol;
+ FunctionSymbol methodSymbol;
+ final source = '''
+ ${options.dartLangComment}
+
+ class A {
+ String publicInstanceMethod() => 'Cello';
+ }
+ ''';
+ setUpAll(() async {
+ driver = TestDriver(options, source);
+ var result = await driver.compile();
+ classSymbol = result.symbols.classes.single;
+ methodSymbol = result.symbols.functions.single;
+ });
+ tearDownAll(() {
+ driver.cleanUp();
+ });
+ test('functionId in classSymbol', () async {
+ expect(methodSymbol.id, endsWith('A|publicInstanceMethod'));
+ expect(methodSymbol.id, classSymbol.functionIds.single);
+ });
+ test('has class scopeId', () async {
+ expect(methodSymbol.scopeId, endsWith('|A'));
+ expect(methodSymbol.scopeId, classSymbol.id);
+ });
+ test('is not static', () async {
+ expect(methodSymbol.isStatic, isFalse);
+ });
+ });
+ group('class private instance method debug symbols', () {
+ TestDriver driver;
+ ClassSymbol classSymbol;
+ FunctionSymbol methodSymbol;
+ final source = '''
+ ${options.dartLangComment}
+
+ class A {
+ String _privateInstanceMethod() => 'Cello';
+ }
+ ''';
+ setUpAll(() async {
+ driver = TestDriver(options, source);
+ var result = await driver.compile();
+ classSymbol = result.symbols.classes.single;
+ methodSymbol = result.symbols.functions.single;
+ });
+ tearDownAll(() {
+ driver.cleanUp();
+ });
+ test('functionId in classSymbol', () async {
+ expect(methodSymbol.id, endsWith('A|Symbol(_privateInstanceMethod)'));
+ expect(methodSymbol.id, classSymbol.functionIds.single);
+ });
+ test('has class scopeId', () async {
+ expect(methodSymbol.scopeId, endsWith('|A'));
+ expect(methodSymbol.scopeId, classSymbol.id);
+ });
+ test('is not static', () async {
+ expect(methodSymbol.isStatic, isFalse);
+ });
+ });
+ group('class public static method debug symbols', () {
+ TestDriver driver;
+ ClassSymbol classSymbol;
+ FunctionSymbol methodSymbol;
+ final source = '''
+ ${options.dartLangComment}
+
+ class A {
+ static String publicStaticMethod() => 'Cello';
+ }
+ ''';
+ setUpAll(() async {
+ driver = TestDriver(options, source);
+ var result = await driver.compile();
+ classSymbol = result.symbols.classes.single;
+ methodSymbol = result.symbols.functions.single;
+ });
+ tearDownAll(() {
+ driver.cleanUp();
+ });
+ test('functionId in classSymbol', () async {
+ expect(methodSymbol.id, endsWith('A|publicStaticMethod'));
+ expect(methodSymbol.id, classSymbol.functionIds.single);
+ });
+ test('has class scopeId', () async {
+ expect(methodSymbol.scopeId, endsWith('|A'));
+ expect(methodSymbol.scopeId, classSymbol.id);
+ });
+ test('is static', () async {
+ expect(methodSymbol.isStatic, isTrue);
+ });
+ });
+ group('class private static method debug symbols', () {
+ TestDriver driver;
+ ClassSymbol classSymbol;
+ FunctionSymbol methodSymbol;
+ final source = '''
+ ${options.dartLangComment}
+
+ class A {
+ static String _privateStaticMethod() => 'Fosse';
+ }
+ ''';
+ setUpAll(() async {
+ driver = TestDriver(options, source);
+ var result = await driver.compile();
+ classSymbol = result.symbols.classes.single;
+ methodSymbol = result.symbols.functions.single;
+ });
+ tearDownAll(() {
+ driver.cleanUp();
+ });
+ test('functionId in classSymbol', () async {
+ expect(methodSymbol.id, endsWith('A|_privateStaticMethod'));
+ expect(methodSymbol.id, classSymbol.functionIds.single);
+ });
+ test('has class scopeId', () async {
+ expect(methodSymbol.scopeId, endsWith('|A'));
+ expect(methodSymbol.scopeId, classSymbol.id);
+ });
+ test('is static', () async {
+ expect(methodSymbol.isStatic, isTrue);
+ });
+ });
+ group('class public instance getter debug symbols', () {
+ TestDriver driver;
+ ClassSymbol classSymbol;
+ FunctionSymbol methodSymbol;
+ final source = '''
+ ${options.dartLangComment}
+
+ class A {
+ String get publicGetter() => 'Fosse';
+ }
+ ''';
+ setUpAll(() async {
+ driver = TestDriver(options, source);
+ var result = await driver.compile();
+ classSymbol = result.symbols.classes.single;
+ methodSymbol = result.symbols.functions.single;
+ });
+ tearDownAll(() {
+ driver.cleanUp();
+ });
+ test('functionId in classSymbol', () async {
+ expect(methodSymbol.id, endsWith('A|publicGetter'));
+ expect(methodSymbol.id, classSymbol.functionIds.single);
+ });
+ test('has class scopeId', () async {
+ expect(methodSymbol.scopeId, endsWith('|A'));
+ expect(methodSymbol.scopeId, classSymbol.id);
+ });
+ test('is not static', () async {
+ expect(methodSymbol.isStatic, isFalse);
+ });
+ });
+ group('class private instance getter debug symbols', () {
+ TestDriver driver;
+ ClassSymbol classSymbol;
+ FunctionSymbol methodSymbol;
+ final source = '''
+ ${options.dartLangComment}
+
+ class A {
+ String get _privateGetter() => 'Fosse';
+ }
+ ''';
+ setUpAll(() async {
+ driver = TestDriver(options, source);
+ var result = await driver.compile();
+ classSymbol = result.symbols.classes.single;
+ methodSymbol = result.symbols.functions.single;
+ });
+ tearDownAll(() {
+ driver.cleanUp();
+ });
+ test('functionId in classSymbol', () async {
+ expect(methodSymbol.id, endsWith('A|Symbol(_privateGetter)'));
+ expect(methodSymbol.id, classSymbol.functionIds.single);
+ });
+ test('has class scopeId', () async {
+ expect(methodSymbol.scopeId, endsWith('|A'));
+ expect(methodSymbol.scopeId, classSymbol.id);
+ });
+ test('is not static', () async {
+ expect(methodSymbol.isStatic, isFalse);
+ });
+ });
+ group('class public instance setter debug symbols', () {
+ TestDriver driver;
+ ClassSymbol classSymbol;
+ FunctionSymbol methodSymbol;
+ final source = '''
+ ${options.dartLangComment}
+
+ class A {
+ var _value
+ set publicSetter(String v) => _value = v;
+ }
+ ''';
+ setUpAll(() async {
+ driver = TestDriver(options, source);
+ var result = await driver.compile();
+ classSymbol = result.symbols.classes.single;
+ methodSymbol = result.symbols.functions.single;
+ });
+ tearDownAll(() {
+ driver.cleanUp();
+ });
+ test('functionId in classSymbol', () async {
+ expect(methodSymbol.id, endsWith('A|publicSetter'));
+ expect(methodSymbol.id, classSymbol.functionIds.single);
+ });
+ test('has class scopeId', () async {
+ expect(methodSymbol.scopeId, endsWith('|A'));
+ expect(methodSymbol.scopeId, classSymbol.id);
+ });
+ test('is not static', () async {
+ expect(methodSymbol.isStatic, isFalse);
+ });
+ });
+ group('class private instance setter debug symbols', () {
+ TestDriver driver;
+ ClassSymbol classSymbol;
+ FunctionSymbol methodSymbol;
+ final source = '''
+ ${options.dartLangComment}
+
+ class A {
+ var _value
+ set _privateSetter(String v) => _value = v;
+ }
+ ''';
+ setUpAll(() async {
+ driver = TestDriver(options, source);
+ var result = await driver.compile();
+ classSymbol = result.symbols.classes.single;
+ methodSymbol = result.symbols.functions.single;
+ });
+ tearDownAll(() {
+ driver.cleanUp();
+ });
+ test('functionId in classSymbol', () async {
+ expect(methodSymbol.id, endsWith('A|Symbol(_privateSetter)'));
+ expect(methodSymbol.id, classSymbol.functionIds.single);
+ });
+ test('has class scopeId', () async {
+ expect(methodSymbol.scopeId, endsWith('|A'));
+ expect(methodSymbol.scopeId, classSymbol.id);
+ });
+ test('is not static', () async {
+ expect(methodSymbol.isStatic, isFalse);
+ });
+ });
+ group('class public static getter debug symbols', () {
+ TestDriver driver;
+ ClassSymbol classSymbol;
+ FunctionSymbol methodSymbol;
+ final source = '''
+ ${options.dartLangComment}
+
+ class A {
+ static String get publicGetter() => 'Fosse';
+ }
+ ''';
+ setUpAll(() async {
+ driver = TestDriver(options, source);
+ var result = await driver.compile();
+ classSymbol = result.symbols.classes.single;
+ methodSymbol = result.symbols.functions.single;
+ });
+ tearDownAll(() {
+ driver.cleanUp();
+ });
+ test('functionId in classSymbol', () async {
+ expect(methodSymbol.id, endsWith('A|publicGetter'));
+ expect(methodSymbol.id, classSymbol.functionIds.single);
+ });
+ test('has class scopeId', () async {
+ expect(methodSymbol.scopeId, endsWith('|A'));
+ expect(methodSymbol.scopeId, classSymbol.id);
+ });
+ test('is static', () async {
+ expect(methodSymbol.isStatic, isTrue);
+ });
+ });
+ group('class private static getter debug symbols', () {
+ TestDriver driver;
+ ClassSymbol classSymbol;
+ FunctionSymbol methodSymbol;
+ final source = '''
+ ${options.dartLangComment}
+
+ class A {
+ static String get _privateGetter() => 'Fosse';
+ }
+ ''';
+ setUpAll(() async {
+ driver = TestDriver(options, source);
+ var result = await driver.compile();
+ classSymbol = result.symbols.classes.single;
+ methodSymbol = result.symbols.functions.single;
+ });
+ tearDownAll(() {
+ driver.cleanUp();
+ });
+ test('functionId in classSymbol', () async {
+ expect(methodSymbol.id, endsWith('A|_privateGetter'));
+ expect(methodSymbol.id, classSymbol.functionIds.single);
+ });
+ test('has class scopeId', () async {
+ expect(methodSymbol.scopeId, endsWith('|A'));
+ expect(methodSymbol.scopeId, classSymbol.id);
+ });
+ test('is static', () async {
+ expect(methodSymbol.isStatic, isTrue);
+ });
+ });
+ group('class public static setter debug symbols', () {
+ TestDriver driver;
+ ClassSymbol classSymbol;
+ FunctionSymbol methodSymbol;
+ final source = '''
+ ${options.dartLangComment}
+
+ class A {
+ var _value;
+ static set publicSetter(String v) => _value = v;
+ }
+ ''';
+ setUpAll(() async {
+ driver = TestDriver(options, source);
+ var result = await driver.compile();
+ classSymbol = result.symbols.classes.single;
+ methodSymbol = result.symbols.functions.single;
+ });
+ tearDownAll(() {
+ driver.cleanUp();
+ });
+ test('functionId in classSymbol', () async {
+ expect(methodSymbol.id, endsWith('A|publicSetter'));
+ expect(methodSymbol.id, classSymbol.functionIds.single);
+ });
+ test('has class scopeId', () async {
+ expect(methodSymbol.scopeId, endsWith('|A'));
+ expect(methodSymbol.scopeId, classSymbol.id);
+ });
+ test('is static', () async {
+ expect(methodSymbol.isStatic, isTrue);
+ });
+ });
+ group('class private static setter debug symbols', () {
+ TestDriver driver;
+ ClassSymbol classSymbol;
+ FunctionSymbol methodSymbol;
+ final source = '''
+ ${options.dartLangComment}
+
+ class A {
+ var _value;
+ static set _privateSetter(String v) => _value = v;
+ }
+ ''';
+ setUpAll(() async {
+ driver = TestDriver(options, source);
+ var result = await driver.compile();
+ classSymbol = result.symbols.classes.single;
+ methodSymbol = result.symbols.functions.single;
+ });
+ tearDownAll(() {
+ driver.cleanUp();
+ });
+ test('functionId in classSymbol', () async {
+ expect(methodSymbol.id, endsWith('A|_privateSetter'));
+ expect(methodSymbol.id, classSymbol.functionIds.single);
+ });
+ test('has class scopeId', () async {
+ expect(methodSymbol.scopeId, endsWith('|A'));
+ expect(methodSymbol.scopeId, classSymbol.id);
+ });
+ test('is static', () async {
+ expect(methodSymbol.isStatic, isTrue);
+ });
+ });
});
}
}
diff --git a/pkg/dev_compiler/test/module_symbols/function_symbols_test.dart b/pkg/dev_compiler/test/module_symbols/function_symbols_test.dart
new file mode 100644
index 0000000..f39f27b
--- /dev/null
+++ b/pkg/dev_compiler/test/module_symbols/function_symbols_test.dart
@@ -0,0 +1,326 @@
+// Copyright (c) 2021, 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.9
+
+import 'package:dev_compiler/src/kernel/module_symbols.dart';
+import 'package:test/test.dart';
+
+import '../shared_test_options.dart';
+import 'module_symbols_test_shared.dart';
+
+void main() async {
+ for (var mode in [
+ NullSafetyTestOption('Sound Mode:', true),
+ NullSafetyTestOption('Weak Mode:', false)
+ ]) {
+ group(mode.description, () {
+ var options = SetupCompilerOptions(soundNullSafety: mode.soundNullSafety);
+ group('top level function debug symbols', () {
+ TestDriver driver;
+ FunctionSymbol functionSymbol;
+ LibrarySymbol librarySymbol;
+ final source = '''
+ ${options.dartLangComment}
+
+ void topLevelFunction() {
+ return;
+ }
+ ''';
+ setUpAll(() async {
+ driver = TestDriver(options, source);
+ var result = await driver.compile();
+ librarySymbol = result.symbols.libraries.single;
+ functionSymbol = result.symbols.functions.single;
+ });
+ tearDownAll(() {
+ driver.cleanUp();
+ });
+ test('has name', () async {
+ expect(functionSymbol.name, equals('topLevelFunction'));
+ });
+ // TODO(nshahan) Test for typeId.
+ test('is static', () async {
+ expect(functionSymbol.isStatic, isTrue);
+ });
+ test('is not const', () async {
+ expect(functionSymbol.isConst, isFalse);
+ });
+ test('has localId', () async {
+ expect(functionSymbol.localId, 'topLevelFunction');
+ });
+ test('has library scopeId', () async {
+ expect(functionSymbol.scopeId, endsWith('package:foo/foo.dart'));
+ expect(functionSymbol.scopeId, librarySymbol.id);
+ });
+ test('no local variables', () async {
+ expect(functionSymbol.variableIds, isEmpty);
+ });
+ test('no scopes', () async {
+ expect(functionSymbol.scopeIds, isEmpty);
+ });
+ group('location', () {
+ test('has scriptId', () async {
+ expect(functionSymbol.location.scriptId, endsWith('/foo.dart'));
+ });
+ test('has start token', () async {
+ expect(functionSymbol.location.tokenPos,
+ 27 + options.dartLangComment.length);
+ });
+ test('has end token', () async {
+ expect(functionSymbol.location.endTokenPos,
+ 78 + options.dartLangComment.length);
+ });
+ });
+ test('id in LibrarySymbol scopes', () async {
+ expect(functionSymbol.id, endsWith('foo.dart|topLevelFunction'));
+ expect(functionSymbol.id, librarySymbol.scopeIds.single);
+ });
+ });
+ group('top level private function debug symbols', () {
+ TestDriver driver;
+ FunctionSymbol functionSymbol;
+ LibrarySymbol librarySymbol;
+ final source = '''
+ ${options.dartLangComment}
+
+ void _topLevelFunction() {
+ return;
+ }
+ ''';
+ setUpAll(() async {
+ driver = TestDriver(options, source);
+ var result = await driver.compile();
+ functionSymbol = result.symbols.functions.single;
+ librarySymbol = result.symbols.libraries.single;
+ });
+ tearDownAll(() {
+ driver.cleanUp();
+ });
+ test('id in LibrarySymbol scopes', () async {
+ expect(functionSymbol.id, endsWith('foo.dart|_topLevelFunction'));
+ expect(functionSymbol.id, librarySymbol.scopeIds.single);
+ });
+ test('scopeId is LibrarySymbol id', () async {
+ expect(functionSymbol.scopeId, endsWith('package:foo/foo.dart'));
+ expect(functionSymbol.scopeId, librarySymbol.id);
+ });
+ });
+ group('top level public getter debug symbols', () {
+ TestDriver driver;
+ FunctionSymbol functionSymbol;
+ LibrarySymbol librarySymbol;
+ final source = '''
+ ${options.dartLangComment}
+
+ String get topLevelGetter => 'Cello';
+ ''';
+ setUpAll(() async {
+ driver = TestDriver(options, source);
+ var result = await driver.compile();
+ functionSymbol = result.symbols.functions.single;
+ librarySymbol = result.symbols.libraries.single;
+ });
+ tearDownAll(() {
+ driver.cleanUp();
+ });
+ test('id in LibrarySymbol scopes', () async {
+ expect(functionSymbol.id, endsWith('foo.dart|topLevelGetter'));
+ expect(functionSymbol.id, librarySymbol.scopeIds.single);
+ });
+ test('scopeId is LibrarySymbol id', () async {
+ expect(functionSymbol.scopeId, endsWith('package:foo/foo.dart'));
+ expect(functionSymbol.scopeId, librarySymbol.id);
+ });
+ test('is static', () async {
+ expect(functionSymbol.isStatic, isTrue);
+ });
+ });
+ group('top level private getter debug symbols', () {
+ TestDriver driver;
+ FunctionSymbol functionSymbol;
+ LibrarySymbol librarySymbol;
+ final source = '''
+ ${options.dartLangComment}
+
+ String get _topLevelGetter => 'Cello';
+ ''';
+ setUpAll(() async {
+ driver = TestDriver(options, source);
+ var result = await driver.compile();
+ functionSymbol = result.symbols.functions.single;
+ librarySymbol = result.symbols.libraries.single;
+ });
+ tearDownAll(() {
+ driver.cleanUp();
+ });
+ test('id in LibrarySymbol scopes', () async {
+ expect(functionSymbol.id, endsWith('foo.dart|_topLevelGetter'));
+ expect(functionSymbol.id, librarySymbol.scopeIds.single);
+ });
+ test('scopeId is LibrarySymbol id', () async {
+ expect(functionSymbol.scopeId, endsWith('package:foo/foo.dart'));
+ expect(functionSymbol.scopeId, librarySymbol.id);
+ });
+ test('is static', () async {
+ expect(functionSymbol.isStatic, isTrue);
+ });
+ });
+ group('top level public setter debug symbols', () {
+ TestDriver driver;
+ FunctionSymbol functionSymbol;
+ LibrarySymbol librarySymbol;
+ final source = '''
+ ${options.dartLangComment}
+ var _value;
+ set topLevelSetter(String v) => _value = v;
+ ''';
+ setUpAll(() async {
+ driver = TestDriver(options, source);
+ var result = await driver.compile();
+ functionSymbol = result.symbols.functions.single;
+ librarySymbol = result.symbols.libraries.single;
+ });
+ tearDownAll(() {
+ driver.cleanUp();
+ });
+ test('id in LibrarySymbol scopes', () async {
+ expect(functionSymbol.id, endsWith('foo.dart|topLevelSetter'));
+ expect(functionSymbol.id, librarySymbol.scopeIds.single);
+ });
+ test('scopeId is LibrarySymbol id', () async {
+ expect(functionSymbol.scopeId, endsWith('package:foo/foo.dart'));
+ expect(functionSymbol.scopeId, librarySymbol.id);
+ });
+ test('is static', () async {
+ expect(functionSymbol.isStatic, isTrue);
+ });
+ });
+ group('top level private setter debug symbols', () {
+ TestDriver driver;
+ FunctionSymbol functionSymbol;
+ LibrarySymbol librarySymbol;
+ final source = '''
+ ${options.dartLangComment}
+
+ var _value;
+ set _topLevelSetter(String v) => _value = v;
+ ''';
+ setUpAll(() async {
+ driver = TestDriver(options, source);
+ var result = await driver.compile();
+ functionSymbol = result.symbols.functions.single;
+ librarySymbol = result.symbols.libraries.single;
+ });
+ tearDownAll(() {
+ driver.cleanUp();
+ });
+ test('id in LibrarySymbol scopes', () async {
+ expect(functionSymbol.id, endsWith('foo.dart|_topLevelSetter'));
+ expect(functionSymbol.id, librarySymbol.scopeIds.single);
+ });
+ test('scopeId is LibrarySymbol id', () async {
+ expect(functionSymbol.scopeId, endsWith('package:foo/foo.dart'));
+ expect(functionSymbol.scopeId, librarySymbol.id);
+ });
+ test('is static', () async {
+ expect(functionSymbol.isStatic, isTrue);
+ });
+ });
+ group('function arguments debug symbols', () {
+ TestDriver driver;
+ FunctionSymbol functionWithPositionalArgSymbol;
+ FunctionSymbol functionWithOptionalArgSymbol;
+ FunctionSymbol functionWithNamedArgSymbol;
+ VariableSymbol xSymbol;
+ VariableSymbol ySymbol;
+ VariableSymbol zSymbol;
+ final source = '''
+ ${options.dartLangComment}
+
+ class A {
+ const A();
+ }
+ const a = A();
+ void functionWithPositionalArg(A x) {}
+ void functionWithOptionalArg([A y = a]) {}
+ void functionWithNamedArg({A z = a}) {}
+ ''';
+ setUpAll(() async {
+ driver = TestDriver(options, source);
+ var result = await driver.compile();
+ functionWithPositionalArgSymbol = result.symbols.functions
+ .singleWhere((f) => f.name == 'functionWithPositionalArg');
+ functionWithOptionalArgSymbol = result.symbols.functions
+ .singleWhere((f) => f.name == 'functionWithOptionalArg');
+ functionWithNamedArgSymbol = result.symbols.functions
+ .singleWhere((f) => f.name == 'functionWithNamedArg');
+ xSymbol = result.symbols.variables.singleWhere((v) => v.name == 'x');
+ ySymbol = result.symbols.variables.singleWhere((v) => v.name == 'y');
+ zSymbol = result.symbols.variables.singleWhere((v) => v.name == 'z');
+ });
+ tearDownAll(() {
+ driver.cleanUp();
+ });
+ test('function has a variable id for positional argument', () async {
+ var argumentId = functionWithPositionalArgSymbol.variableIds.single;
+ expect(argumentId, endsWith('|x'));
+ expect(argumentId, xSymbol.id);
+ });
+ test('positional argument symbol has a function scope', () async {
+ expect(xSymbol.scopeId, endsWith('|functionWithPositionalArg'));
+ expect(xSymbol.scopeId, functionWithPositionalArgSymbol.id);
+ });
+ test('function has a variable id for optional argument', () async {
+ var argumentId = functionWithOptionalArgSymbol.variableIds.single;
+ expect(argumentId, endsWith('|y'));
+ expect(argumentId, ySymbol.id);
+ });
+ test('optional argument symbol has a function scope', () async {
+ expect(ySymbol.scopeId, endsWith('|functionWithOptionalArg'));
+ expect(ySymbol.scopeId, functionWithOptionalArgSymbol.id);
+ });
+ test('function has a variable id for named argument', () async {
+ var argumentId = functionWithNamedArgSymbol.variableIds.single;
+ expect(argumentId, endsWith('|z'));
+ expect(argumentId, zSymbol.id);
+ });
+ test('named argument symbol has a function scope', () async {
+ expect(zSymbol.scopeId, endsWith('|functionWithNamedArg'));
+ expect(zSymbol.scopeId, functionWithNamedArgSymbol.id);
+ });
+ });
+ group('function local variable debug symbols', () {
+ TestDriver driver;
+ FunctionSymbol functionSymbol;
+ VariableSymbol variableSymbol;
+ final source = '''
+ ${options.dartLangComment}
+
+ int topLevelFunction() {
+ int i = 42;
+ return i;
+ }
+ ''';
+ setUpAll(() async {
+ driver = TestDriver(options, source);
+ var result = await driver.compile();
+ variableSymbol = result.symbols.variables.single;
+ functionSymbol = result.symbols.functions.single;
+ });
+ tearDownAll(() {
+ driver.cleanUp();
+ });
+ test('local variableId in FunctionSymbol', () async {
+ expect(variableSymbol.id, endsWith('|i'));
+ expect(variableSymbol.id, functionSymbol.variableIds.single);
+ });
+ test('scopeId is FunctionSymbol id', () async {
+ expect(variableSymbol.scopeId, endsWith('|topLevelFunction'));
+ expect(variableSymbol.scopeId, functionSymbol.id);
+ });
+ });
+ });
+ }
+}
diff --git a/pkg/vm/lib/metadata/call_site_attributes.dart b/pkg/vm/lib/metadata/call_site_attributes.dart
index 7ef8c93..23733d8 100644
--- a/pkg/vm/lib/metadata/call_site_attributes.dart
+++ b/pkg/vm/lib/metadata/call_site_attributes.dart
@@ -2,10 +2,6 @@
// for 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.12
-
-library vm.metadata.call_site_attributes;
-
import 'package:kernel/ast.dart';
import 'package:kernel/src/printer.dart';
diff --git a/pkg/vm/lib/transformations/call_site_annotator.dart b/pkg/vm/lib/transformations/call_site_annotator.dart
index 2416787..691ba84 100644
--- a/pkg/vm/lib/transformations/call_site_annotator.dart
+++ b/pkg/vm/lib/transformations/call_site_annotator.dart
@@ -2,14 +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.
-// @dart=2.12
-
// This transformation annotates call sites with the receiver type.
// This is done to avoid reimplementing [Expression.getStaticType] in
// C++.
// We don't annotate all call-sites, but only those where VM could benefit from
// knowing static type of the receiver.
-library vm.transformations.call_site_annotator;
import 'package:kernel/ast.dart';
import 'package:kernel/class_hierarchy.dart' show ClassHierarchy;
diff --git a/pkg/vm/lib/transformations/ffi.dart b/pkg/vm/lib/transformations/ffi.dart
index 93dc309..88edf51 100644
--- a/pkg/vm/lib/transformations/ffi.dart
+++ b/pkg/vm/lib/transformations/ffi.dart
@@ -2,8 +2,6 @@
// for 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.12
-
// This file contains logic which is shared between the ffi_definition and
// ffi_use_site transformers.
diff --git a/pkg/vm/lib/transformations/ffi_native.dart b/pkg/vm/lib/transformations/ffi_native.dart
index 54bdcb6..e666652 100644
--- a/pkg/vm/lib/transformations/ffi_native.dart
+++ b/pkg/vm/lib/transformations/ffi_native.dart
@@ -2,8 +2,6 @@
// for 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.12
-
import 'package:kernel/ast.dart';
import 'package:kernel/library_index.dart' show LibraryIndex;
import 'package:kernel/reference_from_index.dart'
diff --git a/pkg/vm/lib/transformations/late_var_init_transformer.dart b/pkg/vm/lib/transformations/late_var_init_transformer.dart
index 7d245f1..48fd416 100644
--- a/pkg/vm/lib/transformations/late_var_init_transformer.dart
+++ b/pkg/vm/lib/transformations/late_var_init_transformer.dart
@@ -2,8 +2,6 @@
// for 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.12
-
import 'package:kernel/ast.dart';
/// Wraps the initializers of late local variables in closures.
diff --git a/pkg/vm/lib/transformations/mixin_deduplication.dart b/pkg/vm/lib/transformations/mixin_deduplication.dart
index ba65266..61f008b 100644
--- a/pkg/vm/lib/transformations/mixin_deduplication.dart
+++ b/pkg/vm/lib/transformations/mixin_deduplication.dart
@@ -2,10 +2,6 @@
// for 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.12
-
-library vm.transformations.mixin_deduplication;
-
import 'package:kernel/ast.dart';
/// De-duplication of identical mixin applications.
diff --git a/pkg/vm/lib/transformations/specializer/factory_specializer.dart b/pkg/vm/lib/transformations/specializer/factory_specializer.dart
index 7475638..b86c3e6 100644
--- a/pkg/vm/lib/transformations/specializer/factory_specializer.dart
+++ b/pkg/vm/lib/transformations/specializer/factory_specializer.dart
@@ -2,10 +2,6 @@
// for 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.12
-
-library vm.transformations.specializer.factory_specializer;
-
import 'package:kernel/kernel.dart';
import 'package:kernel/core_types.dart';
import 'package:vm/transformations/specializer/list_factory_specializer.dart';
diff --git a/pkg/vm/lib/transformations/specializer/list_factory_specializer.dart b/pkg/vm/lib/transformations/specializer/list_factory_specializer.dart
index 248c192..1a3f10f 100644
--- a/pkg/vm/lib/transformations/specializer/list_factory_specializer.dart
+++ b/pkg/vm/lib/transformations/specializer/list_factory_specializer.dart
@@ -2,10 +2,6 @@
// for 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.12
-
-library vm.transformations.specializer.list_factory_specializer;
-
import 'package:kernel/ast.dart';
import 'package:kernel/core_types.dart' show CoreTypes;
import 'package:vm/transformations/specializer/factory_specializer.dart';
diff --git a/pkg/vm/lib/transformations/specializer/map_factory_specializer.dart b/pkg/vm/lib/transformations/specializer/map_factory_specializer.dart
index 8a01984..55f9d52 100644
--- a/pkg/vm/lib/transformations/specializer/map_factory_specializer.dart
+++ b/pkg/vm/lib/transformations/specializer/map_factory_specializer.dart
@@ -2,10 +2,6 @@
// for 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.12
-
-library vm.transformations.specializer.map_factory_specializer;
-
import 'package:kernel/ast.dart';
import 'package:kernel/core_types.dart';
import 'dart:core';
diff --git a/pkg/vm/lib/transformations/specializer/set_factory_specializer.dart b/pkg/vm/lib/transformations/specializer/set_factory_specializer.dart
index a508435..2479e3d 100644
--- a/pkg/vm/lib/transformations/specializer/set_factory_specializer.dart
+++ b/pkg/vm/lib/transformations/specializer/set_factory_specializer.dart
@@ -2,10 +2,6 @@
// for 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.12
-
-library vm.transformations.specializer.set_factory_specializer;
-
import 'package:kernel/ast.dart';
import 'package:kernel/core_types.dart' show CoreTypes;
diff --git a/pkg/vm/lib/transformations/unreachable_code_elimination.dart b/pkg/vm/lib/transformations/unreachable_code_elimination.dart
index 10bd958..d61b8f4 100644
--- a/pkg/vm/lib/transformations/unreachable_code_elimination.dart
+++ b/pkg/vm/lib/transformations/unreachable_code_elimination.dart
@@ -2,8 +2,6 @@
// for 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.12
-
import 'package:kernel/ast.dart';
/// Simple unreachable code elimination: removes asserts and if statements
diff --git a/pkg/vm/test/transformations/type_flow/transformer_test.dart b/pkg/vm/test/transformations/type_flow/transformer_test.dart
index 507cb4b..0fee483 100644
--- a/pkg/vm/test/transformations/type_flow/transformer_test.dart
+++ b/pkg/vm/test/transformations/type_flow/transformer_test.dart
@@ -18,12 +18,11 @@
final String pkgVmDir = Platform.script.resolve('../../..').toFilePath();
-runTestCase(
- Uri source, List<String> experimentalFlags, bool enableNullSafety) async {
+runTestCase(Uri source, bool enableNullSafety) async {
final target =
new TestingVmTarget(new TargetFlags(enableNullSafety: enableNullSafety));
- Component component = await compileTestCaseToKernelProgram(source,
- target: target, experimentalFlags: experimentalFlags);
+ Component component =
+ await compileTestCaseToKernelProgram(source, target: target);
final coreTypes = new CoreTypes(component);
@@ -74,12 +73,7 @@
!path.endsWith('.pb.dart') &&
(testNameFilter == null || path.contains(testNameFilter))) {
final bool enableNullSafety = path.endsWith('_nnbd_strong.dart');
- final bool enableNNBD = enableNullSafety || path.endsWith('_nnbd.dart');
- final List<String> experimentalFlags = [
- if (enableNNBD) 'non-nullable',
- ];
- test(path,
- () => runTestCase(entry.uri, experimentalFlags, enableNullSafety));
+ test(path, () => runTestCase(entry.uri, enableNullSafety));
}
}
}, timeout: Timeout.none);
diff --git a/pkg/vm/testcases/transformations/type_flow/summary_collector/bool_expressions.dart b/pkg/vm/testcases/transformations/type_flow/summary_collector/bool_expressions.dart
index d4a77af..64dbb46 100644
--- a/pkg/vm/testcases/transformations/type_flow/summary_collector/bool_expressions.dart
+++ b/pkg/vm/testcases/transformations/type_flow/summary_collector/bool_expressions.dart
@@ -2,10 +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.
-// @dart=2.9
-
dynamic foo() => null;
-bool bar() => null;
+bool bar() => false;
void bool_expressions() {
if (foo()) {}
diff --git a/pkg/vm/testcases/transformations/type_flow/summary_collector/bool_expressions.dart.expect b/pkg/vm/testcases/transformations/type_flow/summary_collector/bool_expressions.dart.expect
index 5b8180a..85822829 100644
--- a/pkg/vm/testcases/transformations/type_flow/summary_collector/bool_expressions.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/summary_collector/bool_expressions.dart.expect
@@ -3,26 +3,26 @@
RESULT: _T {}?
------------ bar ------------
-RESULT: _T {}?
+RESULT: _T (dart.core::bool, false)
------------ bool_expressions ------------
t0* = _Call direct [#lib::foo] ()
-t1 = _TypeCheck (t0 against dart.core::bool*) (for #lib::foo() as dart.core::bool*)
+t1 = _TypeCheck (t0 against dart.core::bool) (for #lib::foo() as dart.core::bool)
t2* = _Call direct [#lib::bar] ()
t3* = _Call [dart.core::num.+] (_T (dart.core::int)+, _T (dart.core::_Smi, 1))
-i_0 = _Join [dart.core::int*] (_T (dart.core::_Smi, 0), t3)
+i_0 = _Join [dart.core::int] (_T (dart.core::_Smi, 0), t3)
t5* = _Call [dart.core::num.<] (i_0, _T (dart.core::_Smi, 10))
t6* = _Call direct [#lib::bar] ()
-t7 = _TypeCheck (t6 against dart.core::bool*) (for x is dart.core::bool*)
+t7 = _TypeCheck (t6 against dart.core::bool) (for x is dart.core::bool)
t8* = _Call direct [#lib::foo] ()
t9 = _Join [dynamic] (_T (dart.core::bool, true), t8)
-t10 = _TypeCheck (t9 against dart.core::bool*) (for (x ?{dynamic} true : #lib::foo()) as dart.core::bool*)
+t10 = _TypeCheck (t9 against dart.core::bool) (for (x ?{dynamic} true : #lib::foo()) as dart.core::bool)
t11* = _Call direct [#lib::bar] ()
t12* = _Call direct [#lib::bar] ()
t13* = _Call direct [#lib::foo] ()
-t14 = _TypeCheck (t13 against dart.core::bool*) (for #lib::foo() as dart.core::bool*)
+t14 = _TypeCheck (t13 against dart.core::bool) (for #lib::foo() as dart.core::bool)
t15* = _Call direct [#lib::foo] ()
-t16 = _TypeCheck (t15 against dart.core::bool*) (for #lib::foo() as dart.core::bool*)
-y_0 = _Join [dart.core::bool*] (_T (dart.core::bool), _T (dart.core::bool, true))
+t16 = _TypeCheck (t15 against dart.core::bool) (for #lib::foo() as dart.core::bool)
+y_0 = _Join [dart.core::bool] (_T (dart.core::bool), _T (dart.core::bool, true))
RESULT: _T {}?
------------ main ------------
diff --git a/pkg/vm/testcases/transformations/type_flow/summary_collector/calls.dart b/pkg/vm/testcases/transformations/type_flow/summary_collector/calls.dart
index 1f4d7da..d507ee0 100644
--- a/pkg/vm/testcases/transformations/type_flow/summary_collector/calls.dart
+++ b/pkg/vm/testcases/transformations/type_flow/summary_collector/calls.dart
@@ -2,8 +2,6 @@
// for 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.9
-
abstract class A {
void foo1(Object x) {}
dynamic get foo2;
@@ -13,19 +11,19 @@
class B {
void bar1(Object arg) {}
dynamic get bar2 => null;
- set bar3(int y) {}
- int bar4;
+ set bar3(int? y) {}
+ int? bar4;
}
class C {
- interfaceCalls(A aa, Object a2, Object a3, Object a4) {
+ interfaceCalls(A aa, Object a2, Object a3, Object? a4) {
aa.foo1(new B());
aa.foo3 = aa.foo2;
a4 = aa.foo2(a2, a3, aa.foo1);
return a4;
}
- dynamicCalls(dynamic aa, Object a2, Object a3, Object a4) {
+ dynamicCalls(dynamic aa, Object a2, Object a3, Object? a4) {
aa.foo1(new B());
aa.foo3 = aa.foo2;
a4 = aa.foo2(a2, a3, aa.foo1);
@@ -34,7 +32,7 @@
}
class D extends B {
- superCalls(Object a1, Object a2, Object a3, Object a4) {
+ superCalls(Object a1, Object a2, Object a3, Object? a4) {
super.bar1(a1);
super.bar3 = super.bar4;
a4 = super.bar2(a2, a3, super.bar1);
diff --git a/pkg/vm/testcases/transformations/type_flow/summary_collector/calls.dart.expect b/pkg/vm/testcases/transformations/type_flow/summary_collector/calls.dart.expect
index b9d7b32..2731094 100644
--- a/pkg/vm/testcases/transformations/type_flow/summary_collector/calls.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/summary_collector/calls.dart.expect
@@ -38,7 +38,7 @@
t6 = _Call [#lib::A.foo1] (%aa, t5)
t7 = _Narrow (%aa to _T ANY)
t8* = _Call get [#lib::A.foo2] (t7)
-t9 = _TypeCheck (t8 against dart.core::int*) (for aa.{#lib::A.foo2} as dart.core::int*)
+t9 = _TypeCheck (t8 against dart.core::int) (for aa.{#lib::A.foo2} as dart.core::int)
t10 = _Call set [#lib::A.foo3] (t7, t9)
t11* = _Call get [#lib::A.foo1] (t7)
t12* = _Call get [#lib::A.foo2] (t7)
diff --git a/pkg/vm/testcases/transformations/type_flow/summary_collector/class_generics_case1.dart b/pkg/vm/testcases/transformations/type_flow/summary_collector/class_generics_case1.dart
index 1140e51..fe65bb4 100644
--- a/pkg/vm/testcases/transformations/type_flow/summary_collector/class_generics_case1.dart
+++ b/pkg/vm/testcases/transformations/type_flow/summary_collector/class_generics_case1.dart
@@ -11,8 +11,6 @@
// call, and we want to make sure there is only one call-site in this example
// (call-site level info is not available yet).
-// @dart=2.9
-
import 'dart:collection';
class Element {}
@@ -32,10 +30,10 @@
class InheritedElement extends Element {
// The inferred type for '_dependents' needs to be concrete and have exact
// type arguments.
- final MockHashMap<Element, Object> _dependents =
- MockHashMap<Element, Object>();
+ final MockHashMap<Element, Object?> _dependents =
+ MockHashMap<Element, Object?>();
- void setDependencies(Element dependent, Object value) {
+ void setDependencies(Element dependent, Object? value) {
_dependents.setEntry(dependent, value);
}
}
diff --git a/pkg/vm/testcases/transformations/type_flow/summary_collector/class_generics_case1.dart.expect b/pkg/vm/testcases/transformations/type_flow/summary_collector/class_generics_case1.dart.expect
index ad64881..f833ff4 100644
--- a/pkg/vm/testcases/transformations/type_flow/summary_collector/class_generics_case1.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/summary_collector/class_generics_case1.dart.expect
@@ -16,10 +16,10 @@
%this = _Parameter #0 [_T (#lib::_NotRealHashMap)+]
%key = _Parameter #1
%value = _Parameter #2
-t3 = _Extract (%this[#lib::_NotRealHashMap/0]*)
-t4 = _TypeCheck (%key against t3) (for #lib::_NotRealHashMap.K* key;)
-t5 = _Extract (%this[#lib::_NotRealHashMap/1]*)
-t6 = _TypeCheck (%value against t5) (for #lib::_NotRealHashMap.V* value;)
+t3 = _Extract (%this[#lib::_NotRealHashMap/0])
+t4 = _TypeCheck (%key against t3) (for #lib::_NotRealHashMap.K% key;)
+t5 = _Extract (%this[#lib::_NotRealHashMap/1])
+t6 = _TypeCheck (%value against t5) (for #lib::_NotRealHashMap.V% value;)
RESULT: _T {}?
------------ InheritedElement. ------------
%this = _Parameter #0 [_T (#lib::InheritedElement)+]
@@ -34,7 +34,7 @@
RESULT: _T {}?
------------ InheritedElement._dependents ------------
%this = _Parameter #0 [_T (#lib::InheritedElement)+]
-t1* = _Call direct [#lib::MockHashMap.] (#lib::Element*, dart.core::Object*)
+t1* = _Call direct [#lib::MockHashMap.] (#lib::Element, dart.core::Object?)
RESULT: t1
------------ main ------------
t0* = _Call direct [#lib::InheritedElement.] (_T (#lib::InheritedElement))
diff --git a/pkg/vm/testcases/transformations/type_flow/summary_collector/implicit_return_null.dart b/pkg/vm/testcases/transformations/type_flow/summary_collector/implicit_return_null.dart
index 9526505..3757ca5 100644
--- a/pkg/vm/testcases/transformations/type_flow/summary_collector/implicit_return_null.dart
+++ b/pkg/vm/testcases/transformations/type_flow/summary_collector/implicit_return_null.dart
@@ -2,14 +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.
-// @dart=2.9
-
class T {}
empty1() {}
void empty2() {}
dynamic empty3() {} // ignore: missing_return
-Object empty4() {} // ignore: missing_return
+Object? empty4() {} // ignore: missing_return
Object return1() {
return new T();
@@ -186,7 +184,8 @@
if (c) {
return new T();
}
- try {} on ArgumentError {} finally {
+ try {} on ArgumentError {
+ } finally {
throw 'Error!';
}
}
diff --git a/pkg/vm/testcases/transformations/type_flow/summary_collector/vars.dart b/pkg/vm/testcases/transformations/type_flow/summary_collector/vars.dart
index b52da4f..4101ae0 100644
--- a/pkg/vm/testcases/transformations/type_flow/summary_collector/vars.dart
+++ b/pkg/vm/testcases/transformations/type_flow/summary_collector/vars.dart
@@ -2,15 +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.
-// @dart=2.9
-
-bool someStatic;
+late bool someStatic;
class A {}
class B {}
-Object foo(Object a1, [Object a2]) {
+Object? foo(Object a1, [Object? a2]) {
if (someStatic) {
a1 = new A();
}
diff --git a/pkg/vm/testcases/transformations/type_flow/summary_collector/vars.dart.expect b/pkg/vm/testcases/transformations/type_flow/summary_collector/vars.dart.expect
index b5c21e4..b559883 100644
--- a/pkg/vm/testcases/transformations/type_flow/summary_collector/vars.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/summary_collector/vars.dart.expect
@@ -11,21 +11,21 @@
%a2 = _Parameter #1 [_T (dart.core::Object)+?]
t2* = _Call direct get [#lib::someStatic] ()
t3* = _Call direct [#lib::A.] (_T (#lib::A))
-a1_0 = _Join [dart.core::Object*] (t3, %a1)
+a1_0 = _Join [dart.core::Object] (t3, %a1)
t5 = _Call direct [#lib::bar] (a1_0, _T (dart.core::_Smi, 42))
t6* = _Call direct [#lib::B.] (_T (#lib::B))
t7* = _Call [dart.core::Object.==] (t6, %a2)
-t8 = _Join [dart.core::Object*] (t6, %a2)
+t8 = _Join [dart.core::Object?] (t6, %a2)
t9 = _Narrow (t8 to _T (dart.core::Object)+?)
RESULT: t9
------------ bar ------------
%a1 = _Parameter #0 [_T (dart.core::Object)+?]
%a2 = _Parameter #1 [_T (dart.core::int)+?]
-t2 = _TypeCheck (%a1 against dart.core::int*) (for v1 is dart.core::int*)
+t2 = _TypeCheck (%a1 against dart.core::int) (for v1 is dart.core::int)
t3* = _Call [dart.core::num.+] (t2, %a2)
t4* = _Call [dart.core::num.*] (t3, _T (dart.core::_Smi, 3))
t5* = _Call [dart.core::int.unary-] (_T (dart.core::_Smi, 1))
-%result = _Join [dart.core::int*] (t4, t5)
+%result = _Join [dart.core::int] (t4, t5)
RESULT: %result
------------ loop1 ------------
%a1 = _Parameter #0 [_T (dart.core::Object)+?]
@@ -35,10 +35,10 @@
------------ loop2 ------------
%x = _Parameter #0 [_T (dart.core::int)+?]
t1* = _Call [dart.core::num.+] (_T (dart.core::int)+, _T (dart.core::_Smi, 1))
-i_0 = _Join [dart.core::int*] (_T (dart.core::_Smi, 0), t1)
+i_0 = _Join [dart.core::int] (_T (dart.core::_Smi, 0), t1)
t3* = _Call [dart.core::num.<] (i_0, _T (dart.core::_Smi, 5))
t4* = _Call [dart.core::num.+] (_T (dart.core::int)+?, _T (dart.core::_Smi, 10))
-x_0 = _Join [dart.core::int*] (%x, t4)
+x_0 = _Join [dart.core::int] (%x, t4)
RESULT: x_0
------------ main ------------
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/annotation.dart b/pkg/vm/testcases/transformations/type_flow/transformer/annotation.dart
index cf61eb7..5fbfc30 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/annotation.dart
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/annotation.dart
@@ -2,8 +2,6 @@
// for 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.9
-
class ClassAnnotation {
const ClassAnnotation();
}
@@ -47,7 +45,7 @@
@TypedefAnnotation([1, 2, 3])
typedef void SomeType<T>(List<T> arg);
-int foo(SomeType<int> a) {
+int foo(SomeType<int>? a) {
@VarAnnotation()
int x = 2;
return x + 2;
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/annotation.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/annotation.dart.expect
index 70239f8..a86774c 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/annotation.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/annotation.dart.expect
@@ -1,23 +1,23 @@
-library #lib;
+library #lib /*isNonNullableByDefault*/;
import self as self;
import "dart:core" as core;
-typedef SomeType<contravariant T extends core::Object* = dynamic> = (core::List<T*>*) →* void;
+typedef SomeType<contravariant T extends core::Object? = dynamic> = (core::List<T%>) → void;
abstract class A extends core::Object {
static method staticMethod() → void {}
}
class B extends core::Object {
- synthetic constructor •() → self::B*
+ synthetic constructor •() → self::B
: super core::Object::•()
;
[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2] method instanceMethod() → void {}
}
-[@vm.unboxing-info.metadata=()->i]static method foo() → core::int* {
- core::int* x = 2;
- return [@vm.direct-call.metadata=dart.core::_IntegerImplementation.+] [@vm.inferred-type.metadata=int (skip check)] x.{core::num::+}(2){(core::num*) →* core::int*};
+[@vm.unboxing-info.metadata=()->i]static method foo() → core::int {
+ core::int x = 2;
+ return [@vm.direct-call.metadata=dart.core::_IntegerImplementation.+] [@vm.inferred-type.metadata=int (skip check)] x.{core::num::+}(2){(core::num) → core::int};
}
-static method main(core::List<core::String*>* args) → dynamic {
+static method main(core::List<core::String> args) → dynamic {
self::A::staticMethod();
- [@vm.direct-call.metadata=#lib::B.instanceMethod] [@vm.inferred-type.metadata=!? (skip check)] new self::B::•().{self::B::instanceMethod}(){() →* void};
+ [@vm.direct-call.metadata=#lib::B.instanceMethod] [@vm.inferred-type.metadata=!? (skip check)] new self::B::•().{self::B::instanceMethod}(){() → void};
self::foo();
}
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/class_generics_case1.dart b/pkg/vm/testcases/transformations/type_flow/transformer/class_generics_case1.dart
index 121201d..b331cb8 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/class_generics_case1.dart
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/class_generics_case1.dart
@@ -2,16 +2,14 @@
// for 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.9
-
import 'dart:collection';
class Element {}
class InheritedElement extends Element {
- final Map<Element, Object> _dependents = <Element, Object>{};
+ final Map<Element, Object?> _dependents = <Element, Object?>{};
- void setDependencies(Element dependent, Object value) {
+ void setDependencies(Element dependent, Object? value) {
_dependents[dependent] = value;
}
}
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/class_generics_case1.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/class_generics_case1.dart.expect
index ca4d73c..4a919d4 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/class_generics_case1.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/class_generics_case1.dart.expect
@@ -1,25 +1,25 @@
-library #lib;
+library #lib /*isNonNullableByDefault*/;
import self as self;
import "dart:core" as core;
import "dart:collection";
class Element extends core::Object {
- synthetic constructor •() → self::Element*
+ synthetic constructor •() → self::Element
: super core::Object::•()
;
}
class InheritedElement extends self::Element {
-[@vm.inferred-type.metadata=dart.collection::_InternalLinkedHashMap<#lib::Element*, dart.core::Object*>] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:1] final field core::Map<self::Element*, core::Object*>* _dependents;
- synthetic constructor •() → self::InheritedElement*
- : self::InheritedElement::_dependents = <self::Element*, core::Object*>{}, super self::Element::•()
+[@vm.inferred-type.metadata=dart.collection::_InternalLinkedHashMap<#lib::Element, dart.core::Object?>] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:1] final field core::Map<self::Element, core::Object?> _dependents;
+ synthetic constructor •() → self::InheritedElement
+ : self::InheritedElement::_dependents = <self::Element, core::Object?>{}, super self::Element::•()
;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:2,getterSelectorId:3] method setDependencies([@vm.inferred-type.metadata=!] self::Element* dependent, [@vm.inferred-type.metadata=dart.core::_Smi?] core::Object* value) → void {
- [@vm.call-site-attributes.metadata=receiverType:dart.core::Map<#lib::Element*, dart.core::Object*>*] [@vm.direct-call.metadata=dart.collection::__InternalLinkedHashMap&_HashVMBase&MapMixin&_LinkedHashMapMixin.[]=] [@vm.inferred-type.metadata=!? (skip check)] [@vm.direct-call.metadata=#lib::InheritedElement._dependents] [@vm.inferred-type.metadata=dart.collection::_InternalLinkedHashMap<#lib::Element*, dart.core::Object*>] this.{self::InheritedElement::_dependents}{core::Map<self::Element*, core::Object*>*}.{core::Map::[]=}(dependent, value){(self::Element*, core::Object*) →* void};
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:2,getterSelectorId:3] method setDependencies([@vm.inferred-type.metadata=!] self::Element dependent, [@vm.inferred-type.metadata=dart.core::_Smi?] core::Object? value) → void {
+ [@vm.call-site-attributes.metadata=receiverType:dart.core::Map<#lib::Element, dart.core::Object?>] [@vm.direct-call.metadata=dart.collection::__InternalLinkedHashMap&_HashVMBase&MapMixin&_LinkedHashMapMixin.[]=] [@vm.inferred-type.metadata=!? (skip check)] [@vm.direct-call.metadata=#lib::InheritedElement._dependents] [@vm.inferred-type.metadata=dart.collection::_InternalLinkedHashMap<#lib::Element, dart.core::Object?>] this.{self::InheritedElement::_dependents}{core::Map<self::Element, core::Object?>}.{core::Map::[]=}(dependent, value){(self::Element, core::Object?) → void};
}
}
static method main() → dynamic {
- self::InheritedElement* ie = new self::InheritedElement::•();
- [@vm.direct-call.metadata=#lib::InheritedElement.setDependencies] [@vm.inferred-type.metadata=!? (skip check)] ie.{self::InheritedElement::setDependencies}(ie, 0){(self::Element*, core::Object*) →* void};
- [@vm.direct-call.metadata=#lib::InheritedElement.setDependencies] [@vm.inferred-type.metadata=!? (skip check)] ie.{self::InheritedElement::setDependencies}(new self::Element::•(), null){(self::Element*, core::Object*) →* void};
+ self::InheritedElement ie = new self::InheritedElement::•();
+ [@vm.direct-call.metadata=#lib::InheritedElement.setDependencies] [@vm.inferred-type.metadata=!? (skip check)] ie.{self::InheritedElement::setDependencies}(ie, 0){(self::Element, core::Object?) → void};
+ [@vm.direct-call.metadata=#lib::InheritedElement.setDependencies] [@vm.inferred-type.metadata=!? (skip check)] ie.{self::InheritedElement::setDependencies}(new self::Element::•(), null){(self::Element, core::Object?) → void};
}
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/devirt.dart b/pkg/vm/testcases/transformations/type_flow/transformer/devirt.dart
index 8356b38..4025830 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/devirt.dart
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/devirt.dart
@@ -2,8 +2,6 @@
// for 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.9
-
abstract class A {
int foo();
}
@@ -30,7 +28,7 @@
aa.foo();
}
-void callerA3({A aa}) {
+void callerA3({required A aa}) {
aa.foo();
}
@@ -46,7 +44,7 @@
x.toString();
}
-A dd;
+late A dd;
E ee = new E();
main(List<String> args) {
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/devirt.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/devirt.dart.expect
index ebf2078..67ffa52 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/devirt.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/devirt.dart.expect
@@ -1,65 +1,65 @@
-library #lib;
+library #lib /*isNonNullableByDefault*/;
import self as self;
import "dart:core" as core;
abstract class A extends core::Object {
- synthetic constructor •() → self::A*
+ synthetic constructor •() → self::A
: super core::Object::•()
;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2] [@vm.unboxing-info.metadata=()->i] abstract method foo() → core::int*;
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2] [@vm.unboxing-info.metadata=()->i] abstract method foo() → core::int;
}
class B extends self::A {
- synthetic constructor •() → self::B*
+ synthetic constructor •() → self::B
: super self::A::•()
;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2] [@vm.unboxing-info.metadata=()->i] method foo() → core::int*
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2] [@vm.unboxing-info.metadata=()->i] method foo() → core::int
return 1;
}
class C extends core::Object implements self::A {
- synthetic constructor •() → self::C*
+ synthetic constructor •() → self::C
: super core::Object::•()
;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2] [@vm.unboxing-info.metadata=()->i] method foo() → core::int*
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2] [@vm.unboxing-info.metadata=()->i] method foo() → core::int
return 2;
}
class D extends self::C {
- synthetic constructor •() → self::D*
+ synthetic constructor •() → self::D
: super self::C::•()
;
}
class E extends core::Object {
- synthetic constructor •() → self::E*
+ synthetic constructor •() → self::E
: super core::Object::•()
;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:3,getterSelectorId:4] method toString() → core::String*
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:3,getterSelectorId:4] method toString() → core::String
return "D";
}
-[@vm.inferred-type.metadata=#lib::D?]static field self::A* dd;
-[@vm.inferred-type.metadata=#lib::E?]static field self::E* ee = new self::E::•();
-static method callerA1([@vm.inferred-type.metadata=!] self::A* aa) → void {
- [@vm.inferred-type.metadata=!? (skip check)] aa.{self::A::foo}(){() →* core::int*};
+[@vm.inferred-type.metadata=#lib::D]late static field self::A dd;
+[@vm.inferred-type.metadata=#lib::E?]static field self::E ee = new self::E::•();
+static method callerA1([@vm.inferred-type.metadata=!] self::A aa) → void {
+ [@vm.inferred-type.metadata=!? (skip check)] aa.{self::A::foo}(){() → core::int};
}
-static method callerA2([@vm.inferred-type.metadata=#lib::B] self::A* aa) → void {
- [@vm.direct-call.metadata=#lib::B.foo] [@vm.inferred-type.metadata=!? (skip check)] aa.{self::A::foo}(){() →* core::int*};
+static method callerA2([@vm.inferred-type.metadata=#lib::B] self::A aa) → void {
+ [@vm.direct-call.metadata=#lib::B.foo] [@vm.inferred-type.metadata=!? (skip check)] aa.{self::A::foo}(){() → core::int};
}
-static method callerA3([@vm.inferred-type.metadata=#lib::C] self::A* aa) → void {
- [@vm.direct-call.metadata=#lib::C.foo] [@vm.inferred-type.metadata=!? (skip check)] aa.{self::A::foo}(){() →* core::int*};
+static method callerA3([@vm.inferred-type.metadata=#lib::C] self::A aa) → void {
+ [@vm.direct-call.metadata=#lib::C.foo] [@vm.inferred-type.metadata=!? (skip check)] aa.{self::A::foo}(){() → core::int};
}
-static method callerA4([@vm.inferred-type.metadata=#lib::D?] self::A* aa) → void {
- [@vm.direct-call.metadata=#lib::C.foo??] [@vm.inferred-type.metadata=!? (skip check)] aa.{self::A::foo}(){() →* core::int*};
+static method callerA4([@vm.inferred-type.metadata=#lib::D] self::A aa) → void {
+ [@vm.direct-call.metadata=#lib::C.foo] [@vm.inferred-type.metadata=!? (skip check)] aa.{self::A::foo}(){() → core::int};
}
static method callerE1() → void {
- [@vm.direct-call.metadata=dart.core::_StringBase.toString] [@vm.inferred-type.metadata=!? (skip check) (receiver not int)](#C1).{core::Object::toString}(){() →* core::String*};
+ [@vm.direct-call.metadata=dart.core::_StringBase.toString] [@vm.inferred-type.metadata=!? (skip check) (receiver not int)](#C1).{core::Object::toString}(){() → core::String};
}
static method callerE2([@vm.inferred-type.metadata=#lib::E?] dynamic x) → void {
- [@vm.inferred-type.metadata=!? (receiver not int)] x.{core::Object::toString}(){() →* core::String*};
+ [@vm.inferred-type.metadata=!? (receiver not int)] x.{core::Object::toString}(){() → core::String};
}
-static method main(core::List<core::String*>* args) → dynamic {
+static method main(core::List<core::String> args) → dynamic {
self::callerA1(new self::B::•());
self::callerA1(new self::C::•());
self::callerA2(new self::B::•());
- let final self::C* #t1 = new self::C::•() in self::callerA3(#t1);
- self::callerA4([@vm.inferred-type.metadata=#lib::D?] self::dd);
+ let final self::C #t1 = new self::C::•() in self::callerA3(#t1);
+ self::callerA4([@vm.inferred-type.metadata=#lib::D] self::dd);
self::dd = new self::D::•();
self::callerE1();
self::callerE2([@vm.inferred-type.metadata=#lib::E?] self::ee);
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/dynamic_list_access.dart b/pkg/vm/testcases/transformations/type_flow/transformer/dynamic_list_access.dart
index bd09bf6..5b75823 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/dynamic_list_access.dart
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/dynamic_list_access.dart
@@ -1,6 +1,8 @@
-// @dart=2.9
+// 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.
main() {
- dynamic x = List<int>.filled(10, null);
+ dynamic x = List<int?>.filled(10, null);
x[0] + 10;
}
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/dynamic_list_access.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/dynamic_list_access.dart.expect
index 17a558f..5fa7916 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/dynamic_list_access.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/dynamic_list_access.dart.expect
@@ -1,8 +1,8 @@
-library #lib;
+library #lib /*isNonNullableByDefault*/;
import self as self;
import "dart:core" as core;
static method main() → dynamic {
- dynamic x = [@vm.inferred-type.metadata=dart.core::_List<dart.core::int*>] core::_List::•<core::int*>(10);
+ dynamic x = [@vm.inferred-type.metadata=dart.core::_List<dart.core::int?>] core::_List::•<core::int?>(10);
[@vm.direct-call.metadata=dart.core::_IntegerImplementation.+??] [@vm.direct-call.metadata=dart.core::_List.[]] [@vm.inferred-type.metadata=int? (receiver not int)] x{dynamic}.[](0){dynamic}.+(10);
}
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/ffi_struct_constructors.dart b/pkg/vm/testcases/transformations/type_flow/transformer/ffi_struct_constructors.dart
index cfe006d..9cfd697 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/ffi_struct_constructors.dart
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/ffi_struct_constructors.dart
@@ -2,71 +2,69 @@
// for 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.9
-
import 'dart:ffi';
/// Retained because of being by-value return type in FFI call.
class Struct1 extends Struct {
- Pointer notEmpty;
+ external Pointer notEmpty;
}
/// Retained because of being by-value return type in FFI call.
class Struct2 extends Struct {
- Pointer notEmpty;
+ external Pointer notEmpty;
}
/// Retained because of being by-value argument type in FFI callback.
class Struct3 extends Struct {
- Pointer notEmpty;
+ external Pointer notEmpty;
}
/// Class not retained, not referenced at all.
class Struct4 extends Struct {
- Pointer notEmpty;
+ external Pointer notEmpty;
}
/// Constructor not retained, only referenced as argument type in FFI
/// call but never instantiated in Dart code.
class Struct5 extends Struct {
- Pointer notEmpty;
+ external Pointer notEmpty;
}
/// Constructor not retained, only referenced as argument type in FFI
/// call but never instantiated in Dart code.
class Struct6 extends Struct {
- Pointer notEmpty;
+ external Pointer notEmpty;
}
/// Constructor not retained, only referenced as return value type in FFI
/// callback but never instantiated in Dart code.
class Struct7 extends Struct {
- Pointer notEmpty;
+ external Pointer notEmpty;
}
/// Not retained because of FFI call not being reachable.
class Struct8 extends Struct {
- Pointer notEmpty;
+ external Pointer notEmpty;
}
/// Not retained because of FFI call not being reachable.
class Struct9 extends Struct {
- Pointer notEmpty;
+ external Pointer notEmpty;
}
/// Not tetained because of FFI callback not being reachable.
class Struct10 extends Struct {
- Pointer notEmpty;
+ external Pointer notEmpty;
}
/// Retained by CFE rewrite of load from pointer.
class Struct11 extends Struct {
- Struct12 nested;
+ external Struct12 nested;
}
/// Retained by rewrite of load from surrounding struct.
class Struct12 extends Struct {
- Pointer notEmpty;
+ external Pointer notEmpty;
}
void main() {
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/ffi_struct_constructors.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/ffi_struct_constructors.dart.expect
index f360e5e..9086aa75 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/ffi_struct_constructors.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/ffi_struct_constructors.dart.expect
@@ -1,4 +1,4 @@
-library #lib;
+library #lib /*isNonNullableByDefault*/;
import self as self;
import "dart:core" as core;
import "dart:ffi" as ffi;
@@ -39,11 +39,11 @@
constructor #fromTypedDataBase([@vm.inferred-type.metadata=dart.ffi::Pointer] core::Object #typedDataBase) → self::Struct11
: super ffi::Struct::_fromTypedDataBase(#typedDataBase)
;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:1] get nested() → self::Struct12*
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:1] get nested() → self::Struct12
return new self::Struct12::#fromTypedDataBase( block {
core::Object #typedDataBase = [@vm.direct-call.metadata=dart.ffi::_Compound._typedDataBase] this.{ffi::_Compound::_typedDataBase}{core::Object};
core::int #offset = (#C12).{core::List::[]}(ffi::_abi()){(core::int) → core::int*};
- } =>#typedDataBase is ffi::Pointer<dynamic> ?{core::Object} [@vm.inferred-type.metadata=dart.ffi::Pointer?] ffi::_fromAddress<self::Struct12*>([@vm.direct-call.metadata=dart.core::_IntegerImplementation.+??] [@vm.inferred-type.metadata=int (skip check)] [@vm.direct-call.metadata=dart.ffi::Pointer.address] [@vm.inferred-type.metadata=int?] #typedDataBase.{ffi::Pointer::address}{core::int}.{core::num::+}(#offset){(core::num) → core::num}) : let typ::TypedData #typedData = _in::unsafeCast<typ::TypedData>(#typedDataBase) in [@vm.direct-call.metadata=dart.typed_data::_ByteBuffer.asUint8List] [@vm.inferred-type.metadata=dart.typed_data::_Uint8ArrayView (skip check)] [@vm.inferred-type.metadata=dart.typed_data::_ByteBuffer] #typedData.{typ::TypedData::buffer}{typ::ByteBuffer}.{typ::ByteBuffer::asUint8List}([@vm.direct-call.metadata=dart.core::_IntegerImplementation.+] [@vm.inferred-type.metadata=int (skip check)] [@vm.inferred-type.metadata=dart.core::_Smi] #typedData.{typ::TypedData::offsetInBytes}{core::int}.{core::num::+}(#offset){(core::num) → core::num}, (#C15).{core::List::[]}(ffi::_abi()){(core::int) → core::int*}){([core::int, core::int?]) → typ::Uint8List});
+ } =>#typedDataBase is ffi::Pointer<dynamic> ?{core::Object} [@vm.inferred-type.metadata=dart.ffi::Pointer?] ffi::_fromAddress<self::Struct12>([@vm.direct-call.metadata=dart.core::_IntegerImplementation.+??] [@vm.inferred-type.metadata=int (skip check)] [@vm.direct-call.metadata=dart.ffi::Pointer.address] [@vm.inferred-type.metadata=int?] #typedDataBase.{ffi::Pointer::address}{core::int}.{core::num::+}(#offset){(core::num) → core::num}) : let typ::TypedData #typedData = _in::unsafeCast<typ::TypedData>(#typedDataBase) in [@vm.direct-call.metadata=dart.typed_data::_ByteBuffer.asUint8List] [@vm.inferred-type.metadata=dart.typed_data::_Uint8ArrayView (skip check)] [@vm.inferred-type.metadata=dart.typed_data::_ByteBuffer] #typedData.{typ::TypedData::buffer}{typ::ByteBuffer}.{typ::ByteBuffer::asUint8List}([@vm.direct-call.metadata=dart.core::_IntegerImplementation.+] [@vm.inferred-type.metadata=int (skip check)] [@vm.inferred-type.metadata=dart.core::_Smi] #typedData.{typ::TypedData::offsetInBytes}{core::int}.{core::num::+}(#offset){(core::num) → core::num}, (#C15).{core::List::[]}(ffi::_abi()){(core::int) → core::int*}){([core::int, core::int?]) → typ::Uint8List});
}
@#C6
class Struct12 extends ffi::Struct {
@@ -51,8 +51,8 @@
: super ffi::Struct::_fromTypedDataBase(#typedDataBase)
;
}
-[@vm.inferred-type.metadata=dart.ffi::Pointer?]static final field ffi::Pointer<ffi::NativeFunction<(self::Struct3*) →* ffi::Int32*>*>* _#ffiCallback0 = [@vm.inferred-type.metadata=dart.ffi::Pointer?] ffi::_pointerFromFunction<ffi::NativeFunction<(self::Struct3*) →* ffi::Int32*>*>(ffi::_nativeCallbackFunction<(self::Struct3*) →* ffi::Int32*>(#C16, 0));
-[@vm.inferred-type.metadata=dart.ffi::Pointer?]static final field ffi::Pointer<ffi::NativeFunction<() →* self::Struct7*>*>* _#ffiCallback1 = [@vm.inferred-type.metadata=dart.ffi::Pointer?] ffi::_pointerFromFunction<ffi::NativeFunction<() →* self::Struct7*>*>(ffi::_nativeCallbackFunction<() →* self::Struct7*>(#C17, null));
+[@vm.inferred-type.metadata=dart.ffi::Pointer?]static final field ffi::Pointer<ffi::NativeFunction<(self::Struct3) → ffi::Int32>*>* _#ffiCallback0 = [@vm.inferred-type.metadata=dart.ffi::Pointer?] ffi::_pointerFromFunction<ffi::NativeFunction<(self::Struct3) → ffi::Int32>*>(ffi::_nativeCallbackFunction<(self::Struct3) → ffi::Int32>(#C16, 0))/*isLegacy*/;
+[@vm.inferred-type.metadata=dart.ffi::Pointer?]static final field ffi::Pointer<ffi::NativeFunction<() → self::Struct7>*>* _#ffiCallback1 = [@vm.inferred-type.metadata=dart.ffi::Pointer?] ffi::_pointerFromFunction<ffi::NativeFunction<() → self::Struct7>*>(ffi::_nativeCallbackFunction<() → self::Struct7>(#C17, null))/*isLegacy*/;
static method main() → void {
self::testLookupFunctionReturn();
self::testLookupFunctionArgument();
@@ -64,56 +64,56 @@
self::testNestedLoad();
}
static method testLookupFunctionReturn() → void {
- final ffi::DynamicLibrary* dylib = [@vm.inferred-type.metadata=dart.ffi::DynamicLibrary?] ffi::DynamicLibrary::executable();
- final () →* self::Struct1* function1 = block {
+ final ffi::DynamicLibrary dylib = [@vm.inferred-type.metadata=dart.ffi::DynamicLibrary?] ffi::DynamicLibrary::executable();
+ final () → self::Struct1 function1 = block {
_in::_nativeEffect(new self::Struct1::#fromTypedDataBase([@vm.inferred-type.metadata=dart.typed_data::_Uint8List] typ::Uint8List::•(#C18)));
- } =>ffi::_asFunctionInternal<() →* self::Struct1*, () →* self::Struct1*>([@vm.direct-call.metadata=dart.ffi::DynamicLibrary.lookup??] [@vm.inferred-type.metadata=dart.ffi::Pointer? (skip check)] dylib.{ffi::DynamicLibrary::lookup}<ffi::NativeFunction<() →* self::Struct1*>*>("function1"){(core::String) → ffi::Pointer<ffi::NativeFunction<() →* self::Struct1*>*>}, false);
- final self::Struct1* struct1 = function1(){() →* self::Struct1*};
+ } =>ffi::_asFunctionInternal<() → self::Struct1, () → self::Struct1>([@vm.direct-call.metadata=dart.ffi::DynamicLibrary.lookup??] [@vm.inferred-type.metadata=dart.ffi::Pointer? (skip check)] dylib.{ffi::DynamicLibrary::lookup}<ffi::NativeFunction<() → self::Struct1>*>("function1"){(core::String) → ffi::Pointer<ffi::NativeFunction<() → self::Struct1>*>}, false);
+ final self::Struct1 struct1 = function1(){() → self::Struct1};
core::print(struct1);
}
static method testAsFunctionReturn() → void {
- final ffi::Pointer<ffi::NativeFunction<() →* self::Struct2*>*>* pointer = [@vm.inferred-type.metadata=dart.ffi::Pointer?] ffi::Pointer::fromAddress<ffi::NativeFunction<() →* self::Struct2*>*>(3735928559);
- final () →* self::Struct2* function2 = block {
+ final ffi::Pointer<ffi::NativeFunction<() → self::Struct2>> pointer = [@vm.inferred-type.metadata=dart.ffi::Pointer?] ffi::Pointer::fromAddress<ffi::NativeFunction<() → self::Struct2>>(3735928559);
+ final () → self::Struct2 function2 = block {
_in::_nativeEffect(new self::Struct2::#fromTypedDataBase([@vm.inferred-type.metadata=dart.typed_data::_Uint8List] typ::Uint8List::•(#C18)));
- } =>ffi::_asFunctionInternal<() →* self::Struct2*, () →* self::Struct2*>(pointer, false);
- final self::Struct2* struct2 = function2(){() →* self::Struct2*};
+ } =>ffi::_asFunctionInternal<() → self::Struct2, () → self::Struct2>(pointer, false);
+ final self::Struct2 struct2 = function2(){() → self::Struct2};
core::print(struct2);
}
-[@vm.unboxing-info.metadata=(b)->i]static method useStruct3(self::Struct3* struct3) → core::int* {
+[@vm.unboxing-info.metadata=(b)->i]static method useStruct3(self::Struct3 struct3) → core::int {
return 42;
}
static method testFromFunctionArgument() → void {
- final ffi::Pointer<ffi::NativeFunction<(self::Struct3*) →* ffi::Int32*>*>* pointer = block {
+ final ffi::Pointer<ffi::NativeFunction<(self::Struct3) → ffi::Int32>> pointer = block {
_in::_nativeEffect(new self::Struct3::#fromTypedDataBase([@vm.inferred-type.metadata=dart.typed_data::_Uint8List] typ::Uint8List::•(#C18)));
} =>[@vm.inferred-type.metadata=dart.ffi::Pointer?] self::_#ffiCallback0;
core::print(pointer);
}
static method testLookupFunctionArgument() → void {
- final ffi::DynamicLibrary* dylib = [@vm.inferred-type.metadata=dart.ffi::DynamicLibrary?] ffi::DynamicLibrary::executable();
- final (self::Struct5*) →* void function5 = [@vm.inferred-type.metadata=dart.core::_Closure?] ffi::_asFunctionInternal<(self::Struct5*) →* void, (self::Struct5*) →* ffi::Void*>([@vm.direct-call.metadata=dart.ffi::DynamicLibrary.lookup??] [@vm.inferred-type.metadata=dart.ffi::Pointer? (skip check)] dylib.{ffi::DynamicLibrary::lookup}<ffi::NativeFunction<(self::Struct5*) →* ffi::Void*>*>("function5"){(core::String) → ffi::Pointer<ffi::NativeFunction<(self::Struct5*) →* ffi::Void*>*>}, false);
+ final ffi::DynamicLibrary dylib = [@vm.inferred-type.metadata=dart.ffi::DynamicLibrary?] ffi::DynamicLibrary::executable();
+ final (self::Struct5) → void function5 = [@vm.inferred-type.metadata=dart.core::_Closure?] ffi::_asFunctionInternal<(self::Struct5) → void, (self::Struct5) → ffi::Void>([@vm.direct-call.metadata=dart.ffi::DynamicLibrary.lookup??] [@vm.inferred-type.metadata=dart.ffi::Pointer? (skip check)] dylib.{ffi::DynamicLibrary::lookup}<ffi::NativeFunction<(self::Struct5) → ffi::Void>*>("function5"){(core::String) → ffi::Pointer<ffi::NativeFunction<(self::Struct5) → ffi::Void>*>}, false);
core::print(function5);
}
static method testAsFunctionArgument() → void {
- final ffi::Pointer<ffi::NativeFunction<(self::Struct6*) →* ffi::Void*>*>* pointer = [@vm.inferred-type.metadata=dart.ffi::Pointer?] ffi::Pointer::fromAddress<ffi::NativeFunction<(self::Struct6*) →* ffi::Void*>*>(3735928559);
- final (self::Struct6*) →* void function6 = [@vm.inferred-type.metadata=dart.core::_Closure?] ffi::_asFunctionInternal<(self::Struct6*) →* void, (self::Struct6*) →* ffi::Void*>(pointer, false);
+ final ffi::Pointer<ffi::NativeFunction<(self::Struct6) → ffi::Void>> pointer = [@vm.inferred-type.metadata=dart.ffi::Pointer?] ffi::Pointer::fromAddress<ffi::NativeFunction<(self::Struct6) → ffi::Void>>(3735928559);
+ final (self::Struct6) → void function6 = [@vm.inferred-type.metadata=dart.core::_Closure?] ffi::_asFunctionInternal<(self::Struct6) → void, (self::Struct6) → ffi::Void>(pointer, false);
core::print(function6);
}
-static method returnStruct7() → self::Struct7* {
+static method returnStruct7() → self::Struct7 {
throw "I don't want to create a Struct7!";
}
static method testFromFunctionReturn() → void {
- final ffi::Pointer<ffi::NativeFunction<() →* self::Struct7*>*>* pointer = [@vm.inferred-type.metadata=dart.ffi::Pointer?] self::_#ffiCallback1;
+ final ffi::Pointer<ffi::NativeFunction<() → self::Struct7>> pointer = [@vm.inferred-type.metadata=dart.ffi::Pointer?] self::_#ffiCallback1;
core::print(pointer);
}
static method testPointerLoad() → void {
- final ffi::Pointer<self::Struct11*>* pointer = [@vm.inferred-type.metadata=dart.ffi::Pointer?] ffi::Pointer::fromAddress<self::Struct11*>(3735928559);
- final self::Struct11* struct11 = new self::Struct11::#fromTypedDataBase(pointer!);
+ final ffi::Pointer<self::Struct11> pointer = [@vm.inferred-type.metadata=dart.ffi::Pointer?] ffi::Pointer::fromAddress<self::Struct11>(3735928559);
+ final self::Struct11 struct11 = new self::Struct11::#fromTypedDataBase(pointer!);
core::print(struct11);
}
static method testNestedLoad() → void {
- final ffi::Pointer<self::Struct11*>* pointer = [@vm.inferred-type.metadata=dart.ffi::Pointer?] ffi::Pointer::fromAddress<self::Struct11*>(3735928559);
- final self::Struct11* struct11 = new self::Struct11::#fromTypedDataBase(pointer!);
- final self::Struct12* struct12 = [@vm.direct-call.metadata=#lib::Struct11.nested] [@vm.inferred-type.metadata=#lib::Struct12] struct11.{self::Struct11::nested}{self::Struct12*};
+ final ffi::Pointer<self::Struct11> pointer = [@vm.inferred-type.metadata=dart.ffi::Pointer?] ffi::Pointer::fromAddress<self::Struct11>(3735928559);
+ final self::Struct11 struct11 = new self::Struct11::#fromTypedDataBase(pointer!);
+ final self::Struct12 struct12 = [@vm.direct-call.metadata=#lib::Struct11.nested] [@vm.inferred-type.metadata=#lib::Struct12] struct11.{self::Struct11::nested}{self::Struct12};
core::print(struct12);
}
constants {
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/future_or.dart b/pkg/vm/testcases/transformations/type_flow/transformer/future_or.dart
index 03e65ae..f2136d5 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/future_or.dart
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/future_or.dart
@@ -2,8 +2,6 @@
// for 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.9
-
import 'dart:async';
dynamic usedObject;
@@ -55,14 +53,14 @@
use(x);
}
-void foo2(Future<A> a1, A a2, FutureOr<A> a3, FutureOr<A> a4) {
+void foo2(Future<A>? a1, A? a2, FutureOr<A>? a3, FutureOr<A>? a4) {
foo2_a1(a1);
foo2_a2(a2);
foo2_a3(a3);
foo2_a4(a4);
}
-Function unknown;
+late Function unknown;
getDynamic() => unknown.call();
main(List<String> args) {
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/future_or.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/future_or.dart.expect
index 4c9cbc4..c9b4c9f 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/future_or.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/future_or.dart.expect
@@ -1,4 +1,4 @@
-library #lib;
+library #lib /*isNonNullableByDefault*/;
import self as self;
import "dart:core" as core;
import "dart:async" as asy;
@@ -6,33 +6,33 @@
import "dart:async";
abstract class A extends core::Object {
- synthetic constructor •() → self::A*
+ synthetic constructor •() → self::A
: super core::Object::•()
;
}
class B extends self::A {
- synthetic constructor •() → self::B*
+ synthetic constructor •() → self::B
: super self::A::•()
;
}
static field dynamic usedObject;
-[@vm.inferred-type.metadata=dart.core::Null? (value: null)]static field core::Function* unknown;
+[@vm.inferred-type.metadata=!]late static field core::Function unknown;
static method use(dynamic object) → void {
self::usedObject == null ?{dynamic} self::usedObject = object : null;
}
-static method foo1_a1([@vm.inferred-type.metadata=dart.async::_Future<#lib::B*>] dynamic x) → void {
+static method foo1_a1([@vm.inferred-type.metadata=dart.async::_Future<#lib::B>] dynamic x) → void {
self::use(x);
}
static method foo1_a2([@vm.inferred-type.metadata=#lib::B] dynamic x) → void {
self::use(x);
}
-static method foo1_a3([@vm.inferred-type.metadata=dart.async::_Future<#lib::B*>] dynamic x) → void {
+static method foo1_a3([@vm.inferred-type.metadata=dart.async::_Future<#lib::B>] dynamic x) → void {
self::use(x);
}
static method foo1_a4([@vm.inferred-type.metadata=#lib::B] dynamic x) → void {
self::use(x);
}
-static method foo1([@vm.inferred-type.metadata=dart.async::_Future<#lib::B*>] asy::Future<self::A*>* a1, [@vm.inferred-type.metadata=#lib::B] self::A* a2, [@vm.inferred-type.metadata=dart.async::_Future<#lib::B*>] FutureOr<self::A*>* a3, [@vm.inferred-type.metadata=#lib::B] FutureOr<self::A*>* a4) → void {
+static method foo1([@vm.inferred-type.metadata=dart.async::_Future<#lib::B>] asy::Future<self::A> a1, [@vm.inferred-type.metadata=#lib::B] self::A a2, [@vm.inferred-type.metadata=dart.async::_Future<#lib::B>] FutureOr<self::A>a3, [@vm.inferred-type.metadata=#lib::B] FutureOr<self::A>a4) → void {
self::foo1_a1(a1);
self::foo1_a2(a2);
self::foo1_a3(a3);
@@ -50,7 +50,7 @@
static method foo2_a4(dynamic x) → void {
self::use(x);
}
-static method foo2([@vm.inferred-type.metadata=dart.async::_Future?] asy::Future<self::A*>* a1, [@vm.inferred-type.metadata=#lib::B?] self::A* a2, FutureOr<self::A*>* a3, FutureOr<self::A*>* a4) → void {
+static method foo2([@vm.inferred-type.metadata=dart.async::_Future?] asy::Future<self::A>? a1, [@vm.inferred-type.metadata=#lib::B?] self::A? a2, FutureOr<self::A>? a3, FutureOr<self::A>? a4) → void {
self::foo2_a1(a1);
self::foo2_a2(a2);
self::foo2_a3(a3);
@@ -58,7 +58,7 @@
}
static method getDynamic() → dynamic
return self::unknown();
-static method main(core::List<core::String*>* args) → dynamic {
- self::foo1([@vm.inferred-type.metadata=dart.async::_Future<#lib::B*>] asy::Future::value<self::B*>(new self::B::•()), new self::B::•(), [@vm.inferred-type.metadata=dart.async::_Future<#lib::B*>] asy::Future::value<self::B*>(new self::B::•()), new self::B::•());
- self::foo2(self::getDynamic() as{TypeError,ForDynamic} asy::Future<self::A*>*, self::getDynamic() as{TypeError,ForDynamic} self::A*, self::getDynamic() as{TypeError,ForDynamic} FutureOr<self::A*>*, self::getDynamic() as{TypeError,ForDynamic} FutureOr<self::A*>*);
+static method main(core::List<core::String> args) → dynamic {
+ self::foo1([@vm.inferred-type.metadata=dart.async::_Future<#lib::B>] asy::Future::value<self::B>(new self::B::•()), new self::B::•(), [@vm.inferred-type.metadata=dart.async::_Future<#lib::B>] asy::Future::value<self::B>(new self::B::•()), new self::B::•());
+ self::foo2(self::getDynamic() as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::A>?, self::getDynamic() as{TypeError,ForDynamic,ForNonNullableByDefault} self::A?, self::getDynamic() as{TypeError,ForDynamic,ForNonNullableByDefault} FutureOr<self::A>?, self::getDynamic() as{TypeError,ForDynamic,ForNonNullableByDefault} FutureOr<self::A>?);
}
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/instance_fields_with_initializers_nnbd.dart b/pkg/vm/testcases/transformations/type_flow/transformer/instance_fields_with_initializers_nnbd.dart
index bb66a2b..67c62c8 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/instance_fields_with_initializers_nnbd.dart
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/instance_fields_with_initializers_nnbd.dart
@@ -4,8 +4,6 @@
// Test for tree shaking of instance fields with initializers.
-// @dart = 2.12
-
int sideEffect(int x) {
print(x);
return x;
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_cycle.dart b/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_cycle.dart
index 7420b2c..fccae87 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_cycle.dart
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_cycle.dart
@@ -11,8 +11,6 @@
// self-induced invalidations.
//
-// @dart=2.9
-
class StreamSubscription {}
class _BufferingStreamSubscription extends StreamSubscription {}
@@ -20,11 +18,11 @@
class _BroadcastSubscription extends StreamSubscription {}
abstract class Stream {
- StreamSubscription foobar(void onData(event), {Function onError});
+ StreamSubscription foobar(void onData(event)?, {Function? onError});
}
abstract class _StreamImpl extends Stream {
- StreamSubscription foobar(void onData(data), {Function onError}) {
+ StreamSubscription foobar(void onData(data)?, {Function? onError}) {
return _createSubscription();
}
@@ -46,7 +44,7 @@
StreamView(Stream stream) : _stream = stream;
- StreamSubscription foobar(void onData(value), {Function onError}) {
+ StreamSubscription foobar(void onData(value)?, {Function? onError}) {
return _stream.foobar(onData, onError: onError);
}
}
@@ -54,15 +52,15 @@
class ByteStream extends StreamView {
ByteStream(Stream stream) : super(stream);
- super_foobar1(void onData(value)) {
+ super_foobar1(void onData(value)?) {
super.foobar(onData);
}
- super_foobar2(void onData(value)) {
+ super_foobar2(void onData(value)?) {
super.foobar(onData);
}
- super_foobar3({void onData(value), Function onError}) {
+ super_foobar3({void onData(value)?, Function? onError}) {
super.foobar(onData, onError: onError);
}
@@ -70,7 +68,7 @@
}
class _HandleErrorStream extends Stream {
- StreamSubscription foobar(void onData(event), {Function onError}) {
+ StreamSubscription foobar(void onData(event)?, {Function? onError}) {
return new _BufferingStreamSubscription();
}
}
@@ -79,26 +77,26 @@
new ByteStream(new ByteStream(new _GeneratedStreamImpl()));
}
-void round1({void onData(value)}) {
+void round1({void onData(value)?}) {
var x = new ByteStream(new ByteStream(new _GeneratedStreamImpl()));
x.super_foobar1(onData);
}
-void round2({void onData(value), Function onError}) {
+void round2({void onData(value)?, Function? onError}) {
new _ControllerStream();
Stream x = new _GeneratedStreamImpl();
x = new ByteStream(x);
x.foobar(onData, onError: onError);
}
-void round3({void onData(value), Function onError}) {
+void round3({void onData(value)?, Function? onError}) {
Stream x = new _GeneratedStreamImpl();
x = new ByteStream(x);
x = new _ControllerStream();
x.foobar(onData, onError: onError);
}
-void round4({void onData(value)}) {
+void round4({void onData(value)?}) {
var x = new ByteStream(new _ControllerStream());
var y = x.super_stream;
var z = x._stream;
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_cycle.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_cycle.dart.expect
index 4b18c73..4771de1 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_cycle.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_cycle.dart.expect
@@ -1,80 +1,79 @@
-library #lib;
+library #lib /*isNonNullableByDefault*/;
import self as self;
import "dart:core" as core;
abstract class StreamSubscription extends core::Object {
- synthetic constructor •() → self::StreamSubscription*
+ synthetic constructor •() → self::StreamSubscription
: super core::Object::•()
;
}
class _BufferingStreamSubscription extends self::StreamSubscription {
- synthetic constructor •() → self::_BufferingStreamSubscription*
+ synthetic constructor •() → self::_BufferingStreamSubscription
: super self::StreamSubscription::•()
;
}
class _BroadcastSubscription extends self::StreamSubscription {
- synthetic constructor •() → self::_BroadcastSubscription*
+ synthetic constructor •() → self::_BroadcastSubscription
: super self::StreamSubscription::•()
;
}
abstract class Stream extends core::Object {
- synthetic constructor •() → self::Stream*
+ synthetic constructor •() → self::Stream
: super core::Object::•()
;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2] abstract method foobar() → self::StreamSubscription*;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:3] abstract operator ==(dynamic other) → core::bool*;
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2] abstract method foobar() → self::StreamSubscription;
}
abstract class _StreamImpl extends self::Stream {
- synthetic constructor •() → self::_StreamImpl*
+ synthetic constructor •() → self::_StreamImpl
: super self::Stream::•()
;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2] method foobar() → self::StreamSubscription* {
- return [@vm.inferred-type.metadata=! (skip check)] this.{self::_StreamImpl::_createSubscription}(){() →* self::StreamSubscription*};
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2] method foobar() → self::StreamSubscription {
+ return [@vm.inferred-type.metadata=! (skip check)] this.{self::_StreamImpl::_createSubscription}(){() → self::StreamSubscription};
}
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:4,getterSelectorId:5] method _createSubscription() → self::StreamSubscription* {
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:3,getterSelectorId:4] method _createSubscription() → self::StreamSubscription {
return new self::_BufferingStreamSubscription::•();
}
}
class _ControllerStream extends self::_StreamImpl {
- synthetic constructor •() → self::_ControllerStream*
+ synthetic constructor •() → self::_ControllerStream
: super self::_StreamImpl::•()
;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:4,getterSelectorId:5] method _createSubscription() → self::StreamSubscription* {
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:3,getterSelectorId:4] method _createSubscription() → self::StreamSubscription {
return new self::_BroadcastSubscription::•();
}
}
class _GeneratedStreamImpl extends self::_StreamImpl {
- synthetic constructor •() → self::_GeneratedStreamImpl*
+ synthetic constructor •() → self::_GeneratedStreamImpl
: super self::_StreamImpl::•()
;
}
abstract class StreamView extends self::Stream {
-[@vm.inferred-type.metadata=!] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:6] final field self::Stream* _stream;
- constructor •([@vm.inferred-type.metadata=!] self::Stream* stream) → self::StreamView*
+[@vm.inferred-type.metadata=!] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:5] final field self::Stream _stream;
+ constructor •([@vm.inferred-type.metadata=!] self::Stream stream) → self::StreamView
: self::StreamView::_stream = stream, super self::Stream::•()
;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2] method foobar() → self::StreamSubscription* {
- return [@vm.direct-call.metadata=#lib::StreamView._stream] [@vm.inferred-type.metadata=!] this.{self::StreamView::_stream}{self::Stream*}.{self::Stream::foobar}(){((dynamic) →* void, {onError: core::Function*}) →* self::StreamSubscription*};
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2] method foobar() → self::StreamSubscription {
+ return [@vm.direct-call.metadata=#lib::StreamView._stream] [@vm.inferred-type.metadata=!] this.{self::StreamView::_stream}{self::Stream}.{self::Stream::foobar}(){((dynamic) →? void, {onError: core::Function?}) → self::StreamSubscription};
}
}
class ByteStream extends self::StreamView {
- constructor •([@vm.inferred-type.metadata=!] self::Stream* stream) → self::ByteStream*
+ constructor •([@vm.inferred-type.metadata=!] self::Stream stream) → self::ByteStream
: super self::StreamView::•(stream)
;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:7,getterSelectorId:8] method super_foobar1() → dynamic {
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:6,getterSelectorId:7] method super_foobar1() → dynamic {
super.{self::StreamView::foobar}();
}
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:9,getterSelectorId:10] method super_foobar2() → dynamic {
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:8,getterSelectorId:9] method super_foobar2() → dynamic {
super.{self::StreamView::foobar}();
}
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:11,getterSelectorId:12] method super_foobar3() → dynamic {
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:10,getterSelectorId:11] method super_foobar3() → dynamic {
super.{self::StreamView::foobar}();
}
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:13] get super_stream() → self::Stream*
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:12] get super_stream() → self::Stream
return [@vm.inferred-type.metadata=!] super.{self::StreamView::_stream};
}
class _HandleErrorStream extends self::Stream {
- synthetic constructor •() → self::_HandleErrorStream*
+ synthetic constructor •() → self::_HandleErrorStream
: super self::Stream::•()
;
}
@@ -82,35 +81,35 @@
new self::ByteStream::•(new self::ByteStream::•(new self::_GeneratedStreamImpl::•()));
}
static method round1() → void {
- self::ByteStream* x = new self::ByteStream::•(new self::ByteStream::•(new self::_GeneratedStreamImpl::•()));
- [@vm.direct-call.metadata=#lib::ByteStream.super_foobar1] [@vm.inferred-type.metadata=!? (skip check)] x.{self::ByteStream::super_foobar1}(){((dynamic) →* void) →* dynamic};
+ self::ByteStream x = new self::ByteStream::•(new self::ByteStream::•(new self::_GeneratedStreamImpl::•()));
+ [@vm.direct-call.metadata=#lib::ByteStream.super_foobar1] [@vm.inferred-type.metadata=!? (skip check)] x.{self::ByteStream::super_foobar1}(){((dynamic) →? void) → dynamic};
}
static method round2() → void {
new self::_ControllerStream::•();
- self::Stream* x = new self::_GeneratedStreamImpl::•();
+ self::Stream x = new self::_GeneratedStreamImpl::•();
x = new self::ByteStream::•(x);
- [@vm.direct-call.metadata=#lib::StreamView.foobar] [@vm.inferred-type.metadata=!? (skip check)] x.{self::Stream::foobar}(){((dynamic) →* void, {onError: core::Function*}) →* self::StreamSubscription*};
+ [@vm.direct-call.metadata=#lib::StreamView.foobar] [@vm.inferred-type.metadata=!? (skip check)] x.{self::Stream::foobar}(){((dynamic) →? void, {onError: core::Function?}) → self::StreamSubscription};
}
static method round3() → void {
- self::Stream* x = new self::_GeneratedStreamImpl::•();
+ self::Stream x = new self::_GeneratedStreamImpl::•();
x = new self::ByteStream::•(x);
x = new self::_ControllerStream::•();
- [@vm.direct-call.metadata=#lib::_StreamImpl.foobar] [@vm.inferred-type.metadata=!? (skip check)] x.{self::Stream::foobar}(){((dynamic) →* void, {onError: core::Function*}) →* self::StreamSubscription*};
+ [@vm.direct-call.metadata=#lib::_StreamImpl.foobar] [@vm.inferred-type.metadata=!? (skip check)] x.{self::Stream::foobar}(){((dynamic) →? void, {onError: core::Function?}) → self::StreamSubscription};
}
static method round4() → void {
- self::ByteStream* x = new self::ByteStream::•(new self::_ControllerStream::•());
- self::Stream* y = [@vm.direct-call.metadata=#lib::ByteStream.super_stream] [@vm.inferred-type.metadata=!] x.{self::ByteStream::super_stream}{self::Stream*};
- self::Stream* z = [@vm.direct-call.metadata=#lib::StreamView._stream] [@vm.inferred-type.metadata=!] x.{self::StreamView::_stream}{self::Stream*};
- if([@vm.direct-call.metadata=dart.core::Object.==] [@vm.inferred-type.metadata=dart.core::bool (skip check) (receiver not int)] y =={self::Stream::==}{(dynamic) →* core::bool*} z) {
- [@vm.direct-call.metadata=#lib::ByteStream.super_foobar2] [@vm.inferred-type.metadata=!? (skip check)] x.{self::ByteStream::super_foobar2}(){((dynamic) →* void) →* dynamic};
+ self::ByteStream x = new self::ByteStream::•(new self::_ControllerStream::•());
+ self::Stream y = [@vm.direct-call.metadata=#lib::ByteStream.super_stream] [@vm.inferred-type.metadata=!] x.{self::ByteStream::super_stream}{self::Stream};
+ self::Stream z = [@vm.direct-call.metadata=#lib::StreamView._stream] [@vm.inferred-type.metadata=!] x.{self::StreamView::_stream}{self::Stream};
+ if([@vm.direct-call.metadata=dart.core::Object.==] [@vm.inferred-type.metadata=dart.core::bool (skip check) (receiver not int)] y =={core::Object::==}{(core::Object) → core::bool} z) {
+ [@vm.direct-call.metadata=#lib::ByteStream.super_foobar2] [@vm.inferred-type.metadata=!? (skip check)] x.{self::ByteStream::super_foobar2}(){((dynamic) →? void) → dynamic};
}
}
static method round5() → void {
- self::ByteStream* x = new self::ByteStream::•(new self::_GeneratedStreamImpl::•());
+ self::ByteStream x = new self::ByteStream::•(new self::_GeneratedStreamImpl::•());
new self::_HandleErrorStream::•();
- [@vm.direct-call.metadata=#lib::ByteStream.super_foobar3] [@vm.inferred-type.metadata=!? (skip check)] x.{self::ByteStream::super_foobar3}(){({onData: (dynamic) →* void, onError: core::Function*}) →* dynamic};
+ [@vm.direct-call.metadata=#lib::ByteStream.super_foobar3] [@vm.inferred-type.metadata=!? (skip check)] x.{self::ByteStream::super_foobar3}(){({onData: (dynamic) →? void, onError: core::Function?}) → dynamic};
}
-static method main(core::List<core::String*>* args) → dynamic {
+static method main(core::List<core::String> args) → dynamic {
new self::_GeneratedStreamImpl::•();
self::round0();
self::round1();
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_field_initializer.dart b/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_field_initializer.dart
index b0ca102..01188a6 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_field_initializer.dart
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_field_initializer.dart
@@ -2,8 +2,6 @@
// for 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.9
-
class T1 {}
class T2 {}
@@ -20,7 +18,7 @@
Object foo() => new T2();
}
-Function unknown;
+late Function unknown;
getDynamic() => unknown.call();
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_field_initializer.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_field_initializer.dart.expect
index 43bee1f..1723808 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_field_initializer.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_field_initializer.dart.expect
@@ -1,82 +1,82 @@
-library #lib;
+library #lib /*isNonNullableByDefault*/;
import self as self;
import "dart:core" as core;
class T1 extends core::Object {
- synthetic constructor •() → self::T1*
+ synthetic constructor •() → self::T1
: super core::Object::•()
;
}
class T2 extends core::Object {
- synthetic constructor •() → self::T2*
+ synthetic constructor •() → self::T2
: super core::Object::•()
;
}
abstract class A extends core::Object {
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2] abstract method foo() → core::Object*;
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2] abstract method foo() → core::Object;
}
class B extends core::Object implements self::A {
- synthetic constructor •() → self::B*
+ synthetic constructor •() → self::B
: super core::Object::•()
;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2] method foo() → core::Object*
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2] method foo() → core::Object
return new self::T1::•();
}
class C extends core::Object implements self::A {
- synthetic constructor •() → self::C*
+ synthetic constructor •() → self::C
: super core::Object::•()
;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2] method foo() → core::Object*
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2] method foo() → core::Object
return new self::T2::•();
}
class DeepCaller1 extends core::Object {
- synthetic constructor •() → self::DeepCaller1*
+ synthetic constructor •() → self::DeepCaller1
: super core::Object::•()
;
[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:3,getterSelectorId:4] method barL1() → dynamic
- return [@vm.direct-call.metadata=#lib::DeepCaller1.barL2] [@vm.inferred-type.metadata=!? (skip check)] this.{self::DeepCaller1::barL2}(){() →* dynamic};
+ return [@vm.direct-call.metadata=#lib::DeepCaller1.barL2] [@vm.inferred-type.metadata=!? (skip check)] this.{self::DeepCaller1::barL2}(){() → dynamic};
[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:5,getterSelectorId:6] method barL2() → dynamic
- return [@vm.direct-call.metadata=#lib::DeepCaller1.barL3] [@vm.inferred-type.metadata=!? (skip check)] this.{self::DeepCaller1::barL3}(){() →* dynamic};
+ return [@vm.direct-call.metadata=#lib::DeepCaller1.barL3] [@vm.inferred-type.metadata=!? (skip check)] this.{self::DeepCaller1::barL3}(){() → dynamic};
[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:7,getterSelectorId:8] method barL3() → dynamic
- return [@vm.direct-call.metadata=#lib::DeepCaller1.barL4] [@vm.inferred-type.metadata=!? (skip check)] this.{self::DeepCaller1::barL4}(){() →* dynamic};
+ return [@vm.direct-call.metadata=#lib::DeepCaller1.barL4] [@vm.inferred-type.metadata=!? (skip check)] this.{self::DeepCaller1::barL4}(){() → dynamic};
[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:9,getterSelectorId:10] method barL4() → dynamic
return self::field1;
}
class D extends core::Object {
-[@vm.inferred-type.metadata=!] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:11,getterSelectorId:12] field core::Object* field2;
- synthetic constructor •() → self::D*
+[@vm.inferred-type.metadata=!] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:11,getterSelectorId:12] field core::Object field2;
+ synthetic constructor •() → self::D
: self::D::field2 = [@vm.inferred-type.metadata=!] self::getValue(), super core::Object::•()
;
}
class DeepCaller2 extends core::Object {
- synthetic constructor •() → self::DeepCaller2*
+ synthetic constructor •() → self::DeepCaller2
: super core::Object::•()
;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:13,getterSelectorId:14] method barL1([@vm.inferred-type.metadata=#lib::D] self::D* dd) → dynamic
- return [@vm.direct-call.metadata=#lib::DeepCaller2.barL2] [@vm.inferred-type.metadata=! (skip check)] this.{self::DeepCaller2::barL2}(dd){(self::D*) →* dynamic};
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:15,getterSelectorId:16] method barL2([@vm.inferred-type.metadata=#lib::D] self::D* dd) → dynamic
- return [@vm.direct-call.metadata=#lib::DeepCaller2.barL3] [@vm.inferred-type.metadata=! (skip check)] this.{self::DeepCaller2::barL3}(dd){(self::D*) →* dynamic};
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:17,getterSelectorId:18] method barL3([@vm.inferred-type.metadata=#lib::D] self::D* dd) → dynamic
- return [@vm.direct-call.metadata=#lib::DeepCaller2.barL4] [@vm.inferred-type.metadata=! (skip check)] this.{self::DeepCaller2::barL4}(dd){(self::D*) →* dynamic};
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:19,getterSelectorId:20] method barL4([@vm.inferred-type.metadata=#lib::D] self::D* dd) → dynamic
- return [@vm.direct-call.metadata=#lib::D.field2] [@vm.inferred-type.metadata=!] dd.{self::D::field2}{core::Object*};
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:13,getterSelectorId:14] method barL1([@vm.inferred-type.metadata=#lib::D] self::D dd) → dynamic
+ return [@vm.direct-call.metadata=#lib::DeepCaller2.barL2] [@vm.inferred-type.metadata=! (skip check)] this.{self::DeepCaller2::barL2}(dd){(self::D) → dynamic};
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:15,getterSelectorId:16] method barL2([@vm.inferred-type.metadata=#lib::D] self::D dd) → dynamic
+ return [@vm.direct-call.metadata=#lib::DeepCaller2.barL3] [@vm.inferred-type.metadata=! (skip check)] this.{self::DeepCaller2::barL3}(dd){(self::D) → dynamic};
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:17,getterSelectorId:18] method barL3([@vm.inferred-type.metadata=#lib::D] self::D dd) → dynamic
+ return [@vm.direct-call.metadata=#lib::DeepCaller2.barL4] [@vm.inferred-type.metadata=! (skip check)] this.{self::DeepCaller2::barL4}(dd){(self::D) → dynamic};
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:19,getterSelectorId:20] method barL4([@vm.inferred-type.metadata=#lib::D] self::D dd) → dynamic
+ return [@vm.direct-call.metadata=#lib::D.field2] [@vm.inferred-type.metadata=!] dd.{self::D::field2}{core::Object};
}
-[@vm.inferred-type.metadata=dart.core::Null? (value: null)]static field core::Function* unknown;
-static field core::Object* field1 = [@vm.inferred-type.metadata=!] self::getValue();
+[@vm.inferred-type.metadata=!]late static field core::Function unknown;
+static field core::Object field1 = [@vm.inferred-type.metadata=!] self::getValue();
static method getDynamic() → dynamic
return self::unknown();
-static method getValue() → core::Object* {
- self::A* aa = self::getDynamic() as{TypeError,ForDynamic} self::A*;
- return [@vm.inferred-type.metadata=!] aa.{self::A::foo}(){() →* core::Object*};
+static method getValue() → core::Object {
+ self::A aa = self::getDynamic() as{TypeError,ForDynamic,ForNonNullableByDefault} self::A;
+ return [@vm.inferred-type.metadata=!] aa.{self::A::foo}(){() → core::Object};
}
-static method use1([@vm.inferred-type.metadata=#lib::DeepCaller1] self::DeepCaller1* x) → dynamic
- return [@vm.direct-call.metadata=#lib::DeepCaller1.barL1] [@vm.inferred-type.metadata=!? (skip check)] x.{self::DeepCaller1::barL1}(){() →* dynamic};
-static method use2([@vm.inferred-type.metadata=#lib::DeepCaller2] self::DeepCaller2* x) → dynamic
- return [@vm.direct-call.metadata=#lib::DeepCaller2.barL1] [@vm.inferred-type.metadata=! (skip check)] x.{self::DeepCaller2::barL1}(new self::D::•()){(self::D*) →* dynamic};
+static method use1([@vm.inferred-type.metadata=#lib::DeepCaller1] self::DeepCaller1 x) → dynamic
+ return [@vm.direct-call.metadata=#lib::DeepCaller1.barL1] [@vm.inferred-type.metadata=!? (skip check)] x.{self::DeepCaller1::barL1}(){() → dynamic};
+static method use2([@vm.inferred-type.metadata=#lib::DeepCaller2] self::DeepCaller2 x) → dynamic
+ return [@vm.direct-call.metadata=#lib::DeepCaller2.barL1] [@vm.inferred-type.metadata=! (skip check)] x.{self::DeepCaller2::barL1}(new self::D::•()){(self::D) → dynamic};
static method createC() → dynamic {
new self::C::•();
}
-static method main(core::List<core::String*>* args) → dynamic {
+static method main(core::List<core::String> args) → dynamic {
new self::B::•();
self::use1(new self::DeepCaller1::•());
self::use2(new self::DeepCaller2::•());
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_new_class1.dart b/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_new_class1.dart
index 844a585..0bc4332 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_new_class1.dart
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_new_class1.dart
@@ -2,8 +2,6 @@
// for 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.9
-
class T1 {}
class T2 {}
@@ -27,7 +25,7 @@
use1(Intermediate i, A aa) => i.bar(aa);
use2(Intermediate i, A aa) => i.bar(aa);
-Function unknown;
+late Function unknown;
getDynamic() => unknown.call();
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_new_class1.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_new_class1.dart.expect
index 750a33e..e916e0c 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_new_class1.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_new_class1.dart.expect
@@ -1,44 +1,44 @@
-library #lib;
+library #lib /*isNonNullableByDefault*/;
import self as self;
import "dart:core" as core;
class T1 extends core::Object {
- synthetic constructor •() → self::T1*
+ synthetic constructor •() → self::T1
: super core::Object::•()
;
}
abstract class A extends core::Object {
- synthetic constructor •() → self::A*
+ synthetic constructor •() → self::A
: super core::Object::•()
;
[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2] abstract method foo() → dynamic;
}
class B extends self::A {
- synthetic constructor •() → self::B*
+ synthetic constructor •() → self::B
: super self::A::•()
;
[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2] method foo() → dynamic
return new self::T1::•();
}
class Intermediate extends core::Object {
- synthetic constructor •() → self::Intermediate*
+ synthetic constructor •() → self::Intermediate
: super core::Object::•()
;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:3,getterSelectorId:4] method bar([@vm.inferred-type.metadata=#lib::B?] self::A* aa) → dynamic
- return [@vm.direct-call.metadata=#lib::B.foo??] [@vm.inferred-type.metadata=#lib::T1 (skip check)] aa.{self::A::foo}(){() →* dynamic};
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:3,getterSelectorId:4] method bar([@vm.inferred-type.metadata=#lib::B?] self::A aa) → dynamic
+ return [@vm.direct-call.metadata=#lib::B.foo??] [@vm.inferred-type.metadata=#lib::T1 (skip check)] aa.{self::A::foo}(){() → dynamic};
}
-[@vm.inferred-type.metadata=dart.core::Null? (value: null)]static field core::Function* unknown;
-static method use1([@vm.inferred-type.metadata=#lib::Intermediate] self::Intermediate* i, [@vm.inferred-type.metadata=#lib::B?] self::A* aa) → dynamic
- return [@vm.direct-call.metadata=#lib::Intermediate.bar] [@vm.inferred-type.metadata=#lib::T1 (skip check)] i.{self::Intermediate::bar}(aa){(self::A*) →* dynamic};
-static method use2([@vm.inferred-type.metadata=#lib::Intermediate] self::Intermediate* i, [@vm.inferred-type.metadata=#lib::B?] self::A* aa) → dynamic
- return [@vm.direct-call.metadata=#lib::Intermediate.bar] [@vm.inferred-type.metadata=#lib::T1 (skip check)] i.{self::Intermediate::bar}(aa){(self::A*) →* dynamic};
+[@vm.inferred-type.metadata=!]late static field core::Function unknown;
+static method use1([@vm.inferred-type.metadata=#lib::Intermediate] self::Intermediate i, [@vm.inferred-type.metadata=#lib::B?] self::A aa) → dynamic
+ return [@vm.direct-call.metadata=#lib::Intermediate.bar] [@vm.inferred-type.metadata=#lib::T1 (skip check)] i.{self::Intermediate::bar}(aa){(self::A) → dynamic};
+static method use2([@vm.inferred-type.metadata=#lib::Intermediate] self::Intermediate i, [@vm.inferred-type.metadata=#lib::B?] self::A aa) → dynamic
+ return [@vm.direct-call.metadata=#lib::Intermediate.bar] [@vm.inferred-type.metadata=#lib::T1 (skip check)] i.{self::Intermediate::bar}(aa){(self::A) → dynamic};
static method getDynamic() → dynamic
return self::unknown();
static method allocateB() → dynamic {
new self::B::•();
}
-static method main(core::List<core::String*>* args) → dynamic {
- self::use1(new self::Intermediate::•(), self::getDynamic() as{TypeError,ForDynamic} self::A*);
+static method main(core::List<core::String> args) → dynamic {
+ self::use1(new self::Intermediate::•(), self::getDynamic() as{TypeError,ForDynamic,ForNonNullableByDefault} self::A);
self::allocateB();
- self::use2(new self::Intermediate::•(), self::getDynamic() as{TypeError,ForDynamic} self::A*);
+ self::use2(new self::Intermediate::•(), self::getDynamic() as{TypeError,ForDynamic,ForNonNullableByDefault} self::A);
}
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_new_class2.dart b/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_new_class2.dart
index d7a751a..ca439fa 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_new_class2.dart
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_new_class2.dart
@@ -2,8 +2,6 @@
// for 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.9
-
class T1 {}
class T2 {}
@@ -32,7 +30,7 @@
use2(Intermediate i, A aa) => i.bar(aa);
use3(Intermediate i, A aa) => i.bar(aa);
-Function unknown;
+late Function unknown;
getDynamic() => unknown.call();
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_new_class2.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_new_class2.dart.expect
index 50f57c2..dc456ee 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_new_class2.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_new_class2.dart.expect
@@ -1,25 +1,25 @@
-library #lib;
+library #lib /*isNonNullableByDefault*/;
import self as self;
import "dart:core" as core;
class T1 extends core::Object {
- synthetic constructor •() → self::T1*
+ synthetic constructor •() → self::T1
: super core::Object::•()
;
}
class T2 extends core::Object {
- synthetic constructor •() → self::T2*
+ synthetic constructor •() → self::T2
: super core::Object::•()
;
}
abstract class A extends core::Object {
- synthetic constructor •() → self::A*
+ synthetic constructor •() → self::A
: super core::Object::•()
;
[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2] abstract method foo() → dynamic;
}
class B extends self::A {
- synthetic constructor •() → self::B*
+ synthetic constructor •() → self::B
: super self::A::•()
;
[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2] method foo() → dynamic
@@ -28,36 +28,36 @@
abstract class C extends core::Object implements self::B {
}
abstract class D extends core::Object {
- synthetic constructor •() → self::D*
+ synthetic constructor •() → self::D
: super core::Object::•()
;
}
abstract class _E&D&C extends self::D implements self::C /*isAnonymousMixin,isEliminatedMixin*/ {
- synthetic constructor •() → self::_E&D&C*
+ synthetic constructor •() → self::_E&D&C
: super self::D::•()
;
}
class E extends self::_E&D&C {
- synthetic constructor •() → self::E*
+ synthetic constructor •() → self::E
: super self::_E&D&C::•()
;
[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2] method foo() → dynamic
return new self::T2::•();
}
class Intermediate extends core::Object {
- synthetic constructor •() → self::Intermediate*
+ synthetic constructor •() → self::Intermediate
: super core::Object::•()
;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:3,getterSelectorId:4] method bar(self::A* aa) → dynamic
- return [@vm.inferred-type.metadata=!] aa.{self::A::foo}(){() →* dynamic};
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:3,getterSelectorId:4] method bar(self::A aa) → dynamic
+ return [@vm.inferred-type.metadata=!] aa.{self::A::foo}(){() → dynamic};
}
-[@vm.inferred-type.metadata=dart.core::Null? (value: null)]static field core::Function* unknown;
-static method use1([@vm.inferred-type.metadata=#lib::Intermediate] self::Intermediate* i, self::A* aa) → dynamic
- return [@vm.direct-call.metadata=#lib::Intermediate.bar] [@vm.inferred-type.metadata=! (skip check)] i.{self::Intermediate::bar}(aa){(self::A*) →* dynamic};
-static method use2([@vm.inferred-type.metadata=#lib::Intermediate] self::Intermediate* i, self::A* aa) → dynamic
- return [@vm.direct-call.metadata=#lib::Intermediate.bar] [@vm.inferred-type.metadata=! (skip check)] i.{self::Intermediate::bar}(aa){(self::A*) →* dynamic};
-static method use3([@vm.inferred-type.metadata=#lib::Intermediate] self::Intermediate* i, self::A* aa) → dynamic
- return [@vm.direct-call.metadata=#lib::Intermediate.bar] [@vm.inferred-type.metadata=! (skip check)] i.{self::Intermediate::bar}(aa){(self::A*) →* dynamic};
+[@vm.inferred-type.metadata=!]late static field core::Function unknown;
+static method use1([@vm.inferred-type.metadata=#lib::Intermediate] self::Intermediate i, self::A aa) → dynamic
+ return [@vm.direct-call.metadata=#lib::Intermediate.bar] [@vm.inferred-type.metadata=! (skip check)] i.{self::Intermediate::bar}(aa){(self::A) → dynamic};
+static method use2([@vm.inferred-type.metadata=#lib::Intermediate] self::Intermediate i, self::A aa) → dynamic
+ return [@vm.direct-call.metadata=#lib::Intermediate.bar] [@vm.inferred-type.metadata=! (skip check)] i.{self::Intermediate::bar}(aa){(self::A) → dynamic};
+static method use3([@vm.inferred-type.metadata=#lib::Intermediate] self::Intermediate i, self::A aa) → dynamic
+ return [@vm.direct-call.metadata=#lib::Intermediate.bar] [@vm.inferred-type.metadata=! (skip check)] i.{self::Intermediate::bar}(aa){(self::A) → dynamic};
static method getDynamic() → dynamic
return self::unknown();
static method allocateB() → dynamic {
@@ -66,10 +66,10 @@
static method allocateE() → dynamic {
new self::E::•();
}
-static method main(core::List<core::String*>* args) → dynamic {
- self::use1(new self::Intermediate::•(), self::getDynamic() as{TypeError,ForDynamic} self::A*);
+static method main(core::List<core::String> args) → dynamic {
+ self::use1(new self::Intermediate::•(), self::getDynamic() as{TypeError,ForDynamic,ForNonNullableByDefault} self::A);
self::allocateB();
- self::use2(new self::Intermediate::•(), self::getDynamic() as{TypeError,ForDynamic} self::A*);
+ self::use2(new self::Intermediate::•(), self::getDynamic() as{TypeError,ForDynamic,ForNonNullableByDefault} self::A);
self::allocateE();
- self::use3(new self::Intermediate::•(), self::getDynamic() as{TypeError,ForDynamic} self::A*);
+ self::use3(new self::Intermediate::•(), self::getDynamic() as{TypeError,ForDynamic,ForNonNullableByDefault} self::A);
}
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_new_dynamic_target.dart b/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_new_dynamic_target.dart
index b91b3a3..01417ef 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_new_dynamic_target.dart
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_new_dynamic_target.dart
@@ -2,8 +2,6 @@
// for 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.9
-
class T1 {}
class T2 {}
@@ -29,7 +27,7 @@
use_bazz(dynamic x) => x.bazz();
-Function unknown;
+late Function unknown;
getDynamic() => unknown.call();
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_new_dynamic_target.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_new_dynamic_target.dart.expect
index 13a7d78b..c049955 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_new_dynamic_target.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_new_dynamic_target.dart.expect
@@ -1,24 +1,24 @@
-library #lib;
+library #lib /*isNonNullableByDefault*/;
import self as self;
import "dart:core" as core;
class T1 extends core::Object {
- synthetic constructor •() → self::T1*
+ synthetic constructor •() → self::T1
: super core::Object::•()
;
}
class T2 extends core::Object {
- synthetic constructor •() → self::T2*
+ synthetic constructor •() → self::T2
: super core::Object::•()
;
}
class T3 extends core::Object {
- synthetic constructor •() → self::T3*
+ synthetic constructor •() → self::T3
: super core::Object::•()
;
}
class A extends core::Object {
- synthetic constructor •() → self::A*
+ synthetic constructor •() → self::A
: super core::Object::•()
;
[@vm.procedure-attributes.metadata=getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2] method foo() → dynamic
@@ -29,7 +29,7 @@
return new self::T3::•();
}
class B extends core::Object {
- synthetic constructor •() → self::B*
+ synthetic constructor •() → self::B
: super core::Object::•()
;
[@vm.procedure-attributes.metadata=getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:7,getterSelectorId:8] method foo() → dynamic
@@ -39,7 +39,7 @@
[@vm.procedure-attributes.metadata=getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:11,getterSelectorId:12] method bazz() → dynamic
return new self::T3::•();
}
-[@vm.inferred-type.metadata=dart.core::Null? (value: null)]static field core::Function* unknown;
+[@vm.inferred-type.metadata=!]late static field core::Function unknown;
static method use_foo1(dynamic x) → dynamic
return [@vm.inferred-type.metadata=#lib::T1] x{dynamic}.foo();
static method use_foo2(dynamic x) → dynamic
@@ -56,7 +56,7 @@
static method allocateB() → dynamic {
new self::B::•();
}
-static method main(core::List<core::String*>* args) → dynamic {
+static method main(core::List<core::String> args) → dynamic {
self::use_foo1(self::getDynamic());
self::allocateA();
self::use_foo2(self::getDynamic());
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_set_field.dart b/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_set_field.dart
index 9a5df63..5232b28 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_set_field.dart
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_set_field.dart
@@ -2,8 +2,6 @@
// for 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.9
-
class T1 {}
class T2 {}
@@ -32,7 +30,7 @@
use1(DeepCaller1 x, A aa) => x.barL1(aa);
use2(DeepCaller2 x, A aa) => x.barL1(aa);
-Function unknown;
+late Function unknown;
getDynamic() => unknown.call();
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_set_field.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_set_field.dart.expect
index 8a434a8..03a3204 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_set_field.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_set_field.dart.expect
@@ -1,65 +1,65 @@
-library #lib;
+library #lib /*isNonNullableByDefault*/;
import self as self;
import "dart:core" as core;
class T1 extends core::Object {
- synthetic constructor •() → self::T1*
+ synthetic constructor •() → self::T1
: super core::Object::•()
;
}
class T2 extends core::Object {
- synthetic constructor •() → self::T2*
+ synthetic constructor •() → self::T2
: super core::Object::•()
;
}
class A extends core::Object {
[@vm.inferred-type.metadata=#lib::T1] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2] field dynamic field1;
[@vm.inferred-type.metadata=!] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:3,getterSelectorId:4] field dynamic field2;
- synthetic constructor •() → self::A*
+ synthetic constructor •() → self::A
: self::A::field1 = new self::T1::•(), self::A::field2 = new self::T1::•(), super core::Object::•()
;
}
class DeepCaller1 extends core::Object {
- synthetic constructor •() → self::DeepCaller1*
+ synthetic constructor •() → self::DeepCaller1
: super core::Object::•()
;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:5,getterSelectorId:6] method barL1([@vm.inferred-type.metadata=#lib::A?] self::A* aa) → dynamic
- return [@vm.direct-call.metadata=#lib::DeepCaller1.barL2] [@vm.inferred-type.metadata=#lib::T1 (skip check)] this.{self::DeepCaller1::barL2}(aa){(self::A*) →* dynamic};
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:7,getterSelectorId:8] method barL2([@vm.inferred-type.metadata=#lib::A?] self::A* aa) → dynamic
- return [@vm.direct-call.metadata=#lib::DeepCaller1.barL3] [@vm.inferred-type.metadata=#lib::T1 (skip check)] this.{self::DeepCaller1::barL3}(aa){(self::A*) →* dynamic};
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:9,getterSelectorId:10] method barL3([@vm.inferred-type.metadata=#lib::A?] self::A* aa) → dynamic
- return [@vm.direct-call.metadata=#lib::DeepCaller1.barL4] [@vm.inferred-type.metadata=#lib::T1 (skip check)] this.{self::DeepCaller1::barL4}(aa){(self::A*) →* dynamic};
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:11,getterSelectorId:12] method barL4([@vm.inferred-type.metadata=#lib::A?] self::A* aa) → dynamic
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:5,getterSelectorId:6] method barL1([@vm.inferred-type.metadata=#lib::A?] self::A aa) → dynamic
+ return [@vm.direct-call.metadata=#lib::DeepCaller1.barL2] [@vm.inferred-type.metadata=#lib::T1 (skip check)] this.{self::DeepCaller1::barL2}(aa){(self::A) → dynamic};
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:7,getterSelectorId:8] method barL2([@vm.inferred-type.metadata=#lib::A?] self::A aa) → dynamic
+ return [@vm.direct-call.metadata=#lib::DeepCaller1.barL3] [@vm.inferred-type.metadata=#lib::T1 (skip check)] this.{self::DeepCaller1::barL3}(aa){(self::A) → dynamic};
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:9,getterSelectorId:10] method barL3([@vm.inferred-type.metadata=#lib::A?] self::A aa) → dynamic
+ return [@vm.direct-call.metadata=#lib::DeepCaller1.barL4] [@vm.inferred-type.metadata=#lib::T1 (skip check)] this.{self::DeepCaller1::barL4}(aa){(self::A) → dynamic};
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:11,getterSelectorId:12] method barL4([@vm.inferred-type.metadata=#lib::A?] self::A aa) → dynamic
return [@vm.direct-call.metadata=#lib::A.field1??] [@vm.inferred-type.metadata=#lib::T1] aa.{self::A::field1}{dynamic};
}
class DeepCaller2 extends core::Object {
- synthetic constructor •() → self::DeepCaller2*
+ synthetic constructor •() → self::DeepCaller2
: super core::Object::•()
;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:13,getterSelectorId:14] method barL1([@vm.inferred-type.metadata=#lib::A?] self::A* aa) → dynamic
- return [@vm.direct-call.metadata=#lib::DeepCaller2.barL2] [@vm.inferred-type.metadata=! (skip check)] this.{self::DeepCaller2::barL2}(aa){(self::A*) →* dynamic};
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:15,getterSelectorId:16] method barL2([@vm.inferred-type.metadata=#lib::A?] self::A* aa) → dynamic
- return [@vm.direct-call.metadata=#lib::DeepCaller2.barL3] [@vm.inferred-type.metadata=! (skip check)] this.{self::DeepCaller2::barL3}(aa){(self::A*) →* dynamic};
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:17,getterSelectorId:18] method barL3([@vm.inferred-type.metadata=#lib::A?] self::A* aa) → dynamic
- return [@vm.direct-call.metadata=#lib::DeepCaller2.barL4] [@vm.inferred-type.metadata=! (skip check)] this.{self::DeepCaller2::barL4}(aa){(self::A*) →* dynamic};
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:19,getterSelectorId:20] method barL4([@vm.inferred-type.metadata=#lib::A?] self::A* aa) → dynamic
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:13,getterSelectorId:14] method barL1([@vm.inferred-type.metadata=#lib::A?] self::A aa) → dynamic
+ return [@vm.direct-call.metadata=#lib::DeepCaller2.barL2] [@vm.inferred-type.metadata=! (skip check)] this.{self::DeepCaller2::barL2}(aa){(self::A) → dynamic};
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:15,getterSelectorId:16] method barL2([@vm.inferred-type.metadata=#lib::A?] self::A aa) → dynamic
+ return [@vm.direct-call.metadata=#lib::DeepCaller2.barL3] [@vm.inferred-type.metadata=! (skip check)] this.{self::DeepCaller2::barL3}(aa){(self::A) → dynamic};
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:17,getterSelectorId:18] method barL3([@vm.inferred-type.metadata=#lib::A?] self::A aa) → dynamic
+ return [@vm.direct-call.metadata=#lib::DeepCaller2.barL4] [@vm.inferred-type.metadata=! (skip check)] this.{self::DeepCaller2::barL4}(aa){(self::A) → dynamic};
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:19,getterSelectorId:20] method barL4([@vm.inferred-type.metadata=#lib::A?] self::A aa) → dynamic
return [@vm.direct-call.metadata=#lib::A.field2??] [@vm.inferred-type.metadata=!] aa.{self::A::field2}{dynamic};
}
-[@vm.inferred-type.metadata=dart.core::Null? (value: null)]static field core::Function* unknown;
-static method use1([@vm.inferred-type.metadata=#lib::DeepCaller1] self::DeepCaller1* x, [@vm.inferred-type.metadata=#lib::A?] self::A* aa) → dynamic
- return [@vm.direct-call.metadata=#lib::DeepCaller1.barL1] [@vm.inferred-type.metadata=#lib::T1 (skip check)] x.{self::DeepCaller1::barL1}(aa){(self::A*) →* dynamic};
-static method use2([@vm.inferred-type.metadata=#lib::DeepCaller2] self::DeepCaller2* x, [@vm.inferred-type.metadata=#lib::A?] self::A* aa) → dynamic
- return [@vm.direct-call.metadata=#lib::DeepCaller2.barL1] [@vm.inferred-type.metadata=! (skip check)] x.{self::DeepCaller2::barL1}(aa){(self::A*) →* dynamic};
+[@vm.inferred-type.metadata=!]late static field core::Function unknown;
+static method use1([@vm.inferred-type.metadata=#lib::DeepCaller1] self::DeepCaller1 x, [@vm.inferred-type.metadata=#lib::A?] self::A aa) → dynamic
+ return [@vm.direct-call.metadata=#lib::DeepCaller1.barL1] [@vm.inferred-type.metadata=#lib::T1 (skip check)] x.{self::DeepCaller1::barL1}(aa){(self::A) → dynamic};
+static method use2([@vm.inferred-type.metadata=#lib::DeepCaller2] self::DeepCaller2 x, [@vm.inferred-type.metadata=#lib::A?] self::A aa) → dynamic
+ return [@vm.direct-call.metadata=#lib::DeepCaller2.barL1] [@vm.inferred-type.metadata=! (skip check)] x.{self::DeepCaller2::barL1}(aa){(self::A) → dynamic};
static method getDynamic() → dynamic
return self::unknown();
-static method setField2([@vm.inferred-type.metadata=#lib::A] self::A* aa, [@vm.inferred-type.metadata=#lib::T2] dynamic value) → void {
+static method setField2([@vm.inferred-type.metadata=#lib::A] self::A aa, [@vm.inferred-type.metadata=#lib::T2] dynamic value) → void {
[@vm.direct-call.metadata=#lib::A.field2] [@vm.inferred-type.metadata=!? (skip check)] aa.{self::A::field2} = value;
}
-static method main(core::List<core::String*>* args) → dynamic {
+static method main(core::List<core::String> args) → dynamic {
new self::A::•();
new self::T1::•();
new self::T2::•();
- self::use1(new self::DeepCaller1::•(), self::getDynamic() as{TypeError,ForDynamic} self::A*);
- self::use2(new self::DeepCaller2::•(), self::getDynamic() as{TypeError,ForDynamic} self::A*);
+ self::use1(new self::DeepCaller1::•(), self::getDynamic() as{TypeError,ForDynamic,ForNonNullableByDefault} self::A);
+ self::use2(new self::DeepCaller2::•(), self::getDynamic() as{TypeError,ForDynamic,ForNonNullableByDefault} self::A);
self::setField2(new self::A::•(), new self::T2::•());
}
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/is_test_elimination_nnbd.dart b/pkg/vm/testcases/transformations/type_flow/transformer/is_test_elimination_nnbd.dart
index fa5a893..723c228 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/is_test_elimination_nnbd.dart
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/is_test_elimination_nnbd.dart
@@ -4,8 +4,6 @@
// Tests elimination of 'is' tests.
-// @dart = 2.12
-
class A {}
class B extends A {
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/lists.dart b/pkg/vm/testcases/transformations/type_flow/transformer/lists_legacy.dart
similarity index 97%
rename from pkg/vm/testcases/transformations/type_flow/transformer/lists.dart
rename to pkg/vm/testcases/transformations/type_flow/transformer/lists_legacy.dart
index 355f41d3..dcd8253 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/lists.dart
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/lists_legacy.dart
@@ -2,6 +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.
+// This test needs pre-null-safety semantics.
// @dart=2.9
nonConstant() => int.parse('1') == 1;
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/lists.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/lists_legacy.dart.expect
similarity index 100%
rename from pkg/vm/testcases/transformations/type_flow/transformer/lists.dart.expect
rename to pkg/vm/testcases/transformations/type_flow/transformer/lists_legacy.dart.expect
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/lists_nnbd.dart b/pkg/vm/testcases/transformations/type_flow/transformer/lists_nnbd.dart
index 76fafab..82f93e6 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/lists_nnbd.dart
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/lists_nnbd.dart
@@ -2,9 +2,6 @@
// for 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 test requires non-nullable experiment.
-// @dart = 2.10
-
nonConstant() => int.parse('1') == 1;
class A {
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/named_params_shaking_test.dart b/pkg/vm/testcases/transformations/type_flow/transformer/named_params_shaking_test.dart
index b180b60..d2bc22a 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/named_params_shaking_test.dart
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/named_params_shaking_test.dart
@@ -4,8 +4,6 @@
//
// Test that optimization of named parameters doesn't change evaluation order.
-// @dart=2.9
-
import 'dart:math';
import 'package:expect/expect.dart';
@@ -17,7 +15,7 @@
// When converting named parameters to positional parameters, we
// follow alphabetical order. Ensure that argument evaluation order
// is unchanged.
-void testNamedOrder(int w, {int z, int y, int x}) {
+void testNamedOrder(int w, {int? z, int? y, int? x}) {
Expect.equals(w, 1);
Expect.equals(z, 2);
Expect.equals(y, 3);
@@ -25,7 +23,7 @@
}
class TestNamedOrderBase {
- TestNamedOrderBase(w, {int z, int y, int x}) {
+ TestNamedOrderBase(w, {int? z, int? y, int? x}) {
testNamedOrder(w, z: z, y: y, x: x);
}
}
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/named_params_shaking_test.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/named_params_shaking_test.dart.expect
index fda4bf2..76840f2 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/named_params_shaking_test.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/named_params_shaking_test.dart.expect
@@ -1,4 +1,4 @@
-library #lib;
+library #lib /*isNonNullableByDefault*/;
import self as self;
import "dart:core" as core;
import "dart:_internal" as _in;
@@ -9,31 +9,31 @@
import "package:expect/expect.dart";
abstract class TestNamedOrderBase extends core::Object {
-[@vm.unboxing-info.metadata=(i,i,i,i)->b] constructor •([@vm.inferred-type.metadata=int] dynamic w, [@vm.inferred-type.metadata=int] core::int* x, [@vm.inferred-type.metadata=int] core::int* y, [@vm.inferred-type.metadata=int] core::int* z) → self::TestNamedOrderBase*
+[@vm.unboxing-info.metadata=(i,i,i,i)->b] constructor •([@vm.inferred-type.metadata=int] dynamic w, [@vm.inferred-type.metadata=int] core::int? x, [@vm.inferred-type.metadata=int] core::int? y, [@vm.inferred-type.metadata=int] core::int? z) → self::TestNamedOrderBase
: super core::Object::•() {
- self::testNamedOrder(_in::unsafeCast<core::int*>(w), x, y, z);
+ self::testNamedOrder(_in::unsafeCast<core::int>(w), x, y, z);
}
}
class TestNamedOrderSub extends self::TestNamedOrderBase {
-[@vm.inferred-type.metadata=int] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2] [@vm.unboxing-info.metadata=(i)->i] field core::int* x;
- constructor •() → self::TestNamedOrderSub*
- : self::TestNamedOrderSub::x = [@vm.inferred-type.metadata=int] self::dec(), final core::int* #t1 = [@vm.inferred-type.metadata=int] self::inc(), final core::int* #t2 = [@vm.inferred-type.metadata=int] self::inc(), final core::int* #t3 = [@vm.inferred-type.metadata=int] self::inc(), final core::int* #t4 = [@vm.inferred-type.metadata=int] self::dec(), super self::TestNamedOrderBase::•(#t1, #t4, #t3, #t2) {
- exp::Expect::equals([@vm.direct-call.metadata=#lib::TestNamedOrderSub.x] [@vm.inferred-type.metadata=int] this.{self::TestNamedOrderSub::x}{core::int*}, 0);
+[@vm.inferred-type.metadata=int] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2] [@vm.unboxing-info.metadata=(i)->i] field core::int x;
+ constructor •() → self::TestNamedOrderSub
+ : self::TestNamedOrderSub::x = [@vm.inferred-type.metadata=int] self::dec(), final core::int #t1 = [@vm.inferred-type.metadata=int] self::inc(), final core::int #t2 = [@vm.inferred-type.metadata=int] self::inc(), final core::int #t3 = [@vm.inferred-type.metadata=int] self::inc(), final core::int #t4 = [@vm.inferred-type.metadata=int] self::dec(), super self::TestNamedOrderBase::•(#t1, #t4, #t3, #t2) {
+ exp::Expect::equals([@vm.direct-call.metadata=#lib::TestNamedOrderSub.x] [@vm.inferred-type.metadata=int] this.{self::TestNamedOrderSub::x}{core::int}, 0);
}
}
-[@vm.inferred-type.metadata=int?]static field core::int* global = 0;
-[@vm.unboxing-info.metadata=()->i]static method inc() → core::int*
- return self::global = [@vm.direct-call.metadata=dart.core::_IntegerImplementation.+??] [@vm.inferred-type.metadata=int (skip check)] [@vm.inferred-type.metadata=int?] self::global.{core::num::+}(1){(core::num*) →* core::int*};
-[@vm.unboxing-info.metadata=()->i]static method dec() → core::int*
- return self::global = [@vm.inferred-type.metadata=int] math::max<core::int*>(0, self::global = [@vm.direct-call.metadata=dart.core::_IntegerImplementation.-??] [@vm.inferred-type.metadata=int (skip check)] [@vm.inferred-type.metadata=int?] self::global.{core::num::-}(1){(core::num*) →* core::int*});
-[@vm.unboxing-info.metadata=(i,i,i,i)->b]static method testNamedOrder([@vm.inferred-type.metadata=int] core::int* w, [@vm.inferred-type.metadata=int] core::int* x, [@vm.inferred-type.metadata=int] core::int* y, [@vm.inferred-type.metadata=int] core::int* z) → void {
+[@vm.inferred-type.metadata=int?]static field core::int global = 0;
+[@vm.unboxing-info.metadata=()->i]static method inc() → core::int
+ return self::global = [@vm.direct-call.metadata=dart.core::_IntegerImplementation.+??] [@vm.inferred-type.metadata=int (skip check)] [@vm.inferred-type.metadata=int?] self::global.{core::num::+}(1){(core::num) → core::int};
+[@vm.unboxing-info.metadata=()->i]static method dec() → core::int
+ return self::global = [@vm.inferred-type.metadata=int] math::max<core::int>(0, self::global = [@vm.direct-call.metadata=dart.core::_IntegerImplementation.-??] [@vm.inferred-type.metadata=int (skip check)] [@vm.inferred-type.metadata=int?] self::global.{core::num::-}(1){(core::num) → core::int});
+[@vm.unboxing-info.metadata=(i,i,i,i)->b]static method testNamedOrder([@vm.inferred-type.metadata=int] core::int w, [@vm.inferred-type.metadata=int] core::int? x, [@vm.inferred-type.metadata=int] core::int? y, [@vm.inferred-type.metadata=int] core::int? z) → void {
exp::Expect::equals(w, 1);
exp::Expect::equals(z, 2);
exp::Expect::equals(y, 3);
exp::Expect::equals(x, 2);
}
static method main() → dynamic {
- let final core::int* #t5 = [@vm.inferred-type.metadata=int] self::inc() in let final core::int* #t6 = [@vm.inferred-type.metadata=int] self::inc() in let final core::int* #t7 = [@vm.inferred-type.metadata=int] self::inc() in let final core::int* #t8 = [@vm.inferred-type.metadata=int] self::dec() in self::testNamedOrder(#t5, #t8, #t7, #t6);
+ let final core::int #t5 = [@vm.inferred-type.metadata=int] self::inc() in let final core::int #t6 = [@vm.inferred-type.metadata=int] self::inc() in let final core::int #t7 = [@vm.inferred-type.metadata=int] self::inc() in let final core::int #t8 = [@vm.inferred-type.metadata=int] self::dec() in self::testNamedOrder(#t5, #t8, #t7, #t6);
self::global = 1;
new self::TestNamedOrderSub::•();
}
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/no_such_method.dart b/pkg/vm/testcases/transformations/type_flow/transformer/no_such_method.dart
index e0ab4922..a3c4741 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/no_such_method.dart
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/no_such_method.dart
@@ -2,8 +2,6 @@
// for 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.9
-
class T1 {}
class T2 {}
@@ -71,7 +69,7 @@
A bb = new B();
A dd = new D();
-Function unknown;
+late Function unknown;
getDynamic() => unknown.call();
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/no_such_method.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/no_such_method.dart.expect
index 719f96e..657e7ba 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/no_such_method.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/no_such_method.dart.expect
@@ -1,40 +1,40 @@
-library #lib;
+library #lib /*isNonNullableByDefault*/;
import self as self;
import "dart:core" as core;
import "dart:_internal" as _in;
class T1 extends core::Object {
- synthetic constructor •() → self::T1*
+ synthetic constructor •() → self::T1
: super core::Object::•()
;
}
class T2 extends core::Object {
- synthetic constructor •() → self::T2*
+ synthetic constructor •() → self::T2
: super core::Object::•()
;
}
class T4 extends core::Object {
- synthetic constructor •() → self::T4*
+ synthetic constructor •() → self::T4
: super core::Object::•()
;
}
class T5 extends core::Object {
- synthetic constructor •() → self::T5*
+ synthetic constructor •() → self::T5
: super core::Object::•()
;
}
class T6 extends core::Object {
- synthetic constructor •() → self::T6*
+ synthetic constructor •() → self::T6
: super core::Object::•()
;
}
class T7 extends core::Object {
- synthetic constructor •() → self::T7*
+ synthetic constructor •() → self::T7
: super core::Object::•()
;
}
abstract class A extends core::Object {
- synthetic constructor •() → self::A*
+ synthetic constructor •() → self::A
: super core::Object::•()
;
[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2] abstract method foo() → dynamic;
@@ -42,88 +42,88 @@
[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:4,getterSelectorId:5] [@vm.unboxing-info.metadata=(i,i,i,i)->b] abstract method bazz(dynamic a1, dynamic a2, dynamic a3, dynamic a4) → dynamic;
}
class B extends self::A {
- synthetic constructor •() → self::B*
+ synthetic constructor •() → self::B
: super self::A::•()
;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasTearOffUses:false,methodOrSetterSelectorId:6,getterSelectorId:7] method noSuchMethod(core::Invocation* invocation) → dynamic {
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasTearOffUses:false,methodOrSetterSelectorId:6,getterSelectorId:7] method noSuchMethod(core::Invocation invocation) → dynamic {
return new self::T1::•();
}
[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:3] no-such-method-forwarder get bar() → dynamic
- return _in::unsafeCast<dynamic>([@vm.direct-call.metadata=#lib::B.noSuchMethod] [@vm.inferred-type.metadata=#lib::T1 (skip check)] this.{self::B::noSuchMethod}(new core::_InvocationMirror::_withType(#C1, 1, #C2, #C3, [@vm.inferred-type.metadata=dart.collection::UnmodifiableMapView<dart.core::Symbol*, dynamic>] core::Map::unmodifiable<core::Symbol*, dynamic>(#C4))){(core::Invocation*) →* dynamic});
+ return _in::unsafeCast<dynamic>([@vm.direct-call.metadata=#lib::B.noSuchMethod] [@vm.inferred-type.metadata=#lib::T1 (skip check)] this.{self::B::noSuchMethod}(new core::_InvocationMirror::_withType(#C1, 1, #C2, #C3, [@vm.inferred-type.metadata=dart.collection::UnmodifiableMapView<dart.core::Symbol*, dynamic>] core::Map::unmodifiable<core::Symbol*, dynamic>(#C4))){(core::Invocation) → dynamic});
[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2] no-such-method-forwarder method foo() → dynamic
- return _in::unsafeCast<dynamic>([@vm.direct-call.metadata=#lib::B.noSuchMethod] [@vm.inferred-type.metadata=#lib::T1 (skip check)] this.{self::B::noSuchMethod}(new core::_InvocationMirror::_withType(#C5, 0, #C2, #C3, [@vm.inferred-type.metadata=dart.collection::UnmodifiableMapView<dart.core::Symbol*, dynamic>] core::Map::unmodifiable<core::Symbol*, dynamic>(#C4))){(core::Invocation*) →* dynamic});
+ return _in::unsafeCast<dynamic>([@vm.direct-call.metadata=#lib::B.noSuchMethod] [@vm.inferred-type.metadata=#lib::T1 (skip check)] this.{self::B::noSuchMethod}(new core::_InvocationMirror::_withType(#C5, 0, #C2, #C3, [@vm.inferred-type.metadata=dart.collection::UnmodifiableMapView<dart.core::Symbol*, dynamic>] core::Map::unmodifiable<core::Symbol*, dynamic>(#C4))){(core::Invocation) → dynamic});
[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:4,getterSelectorId:5] [@vm.unboxing-info.metadata=(i,i,i,i)->b] no-such-method-forwarder method bazz([@vm.inferred-type.metadata=dart.core::_Smi (value: 1)] dynamic a1, [@vm.inferred-type.metadata=dart.core::_Smi (value: 2)] dynamic a2, [@vm.inferred-type.metadata=dart.core::_Smi (value: 3)] dynamic a3, [@vm.inferred-type.metadata=dart.core::_Smi (value: 4)] dynamic a4) → dynamic
- return _in::unsafeCast<dynamic>([@vm.direct-call.metadata=#lib::B.noSuchMethod] [@vm.inferred-type.metadata=#lib::T1 (skip check)] this.{self::B::noSuchMethod}(new core::_InvocationMirror::_withType(#C6, 0, #C2, core::List::unmodifiable<dynamic>([@vm.inferred-type.metadata=dart.core::_GrowableList<dynamic>] core::_GrowableList::_literal5<dynamic>()), [@vm.inferred-type.metadata=dart.collection::UnmodifiableMapView<dart.core::Symbol*, dynamic>] core::Map::unmodifiable<core::Symbol*, dynamic>(#C4))){(core::Invocation*) →* dynamic});
+ return _in::unsafeCast<dynamic>([@vm.direct-call.metadata=#lib::B.noSuchMethod] [@vm.inferred-type.metadata=#lib::T1 (skip check)] this.{self::B::noSuchMethod}(new core::_InvocationMirror::_withType(#C6, 0, #C2, core::List::unmodifiable<dynamic>([@vm.inferred-type.metadata=dart.core::_GrowableList<dynamic>] core::_GrowableList::_literal5<dynamic>()), [@vm.inferred-type.metadata=dart.collection::UnmodifiableMapView<dart.core::Symbol*, dynamic>] core::Map::unmodifiable<core::Symbol*, dynamic>(#C4))){(core::Invocation) → dynamic});
}
abstract class C extends core::Object {
- synthetic constructor •() → self::C*
+ synthetic constructor •() → self::C
: super core::Object::•()
;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasTearOffUses:false,methodOrSetterSelectorId:6,getterSelectorId:7] method noSuchMethod(core::Invocation* invocation) → dynamic {
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasTearOffUses:false,methodOrSetterSelectorId:6,getterSelectorId:7] method noSuchMethod(core::Invocation invocation) → dynamic {
return new self::T2::•();
}
}
class D extends self::C implements self::A {
- synthetic constructor •() → self::D*
+ synthetic constructor •() → self::D
: super self::C::•()
;
[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:3] no-such-method-forwarder get bar() → dynamic
- return _in::unsafeCast<dynamic>([@vm.direct-call.metadata=#lib::C.noSuchMethod] [@vm.inferred-type.metadata=#lib::T2 (skip check)] this.{self::C::noSuchMethod}(new core::_InvocationMirror::_withType(#C1, 1, #C2, #C3, [@vm.inferred-type.metadata=dart.collection::UnmodifiableMapView<dart.core::Symbol*, dynamic>] core::Map::unmodifiable<core::Symbol*, dynamic>(#C4))){(core::Invocation*) →* dynamic});
+ return _in::unsafeCast<dynamic>([@vm.direct-call.metadata=#lib::C.noSuchMethod] [@vm.inferred-type.metadata=#lib::T2 (skip check)] this.{self::C::noSuchMethod}(new core::_InvocationMirror::_withType(#C1, 1, #C2, #C3, [@vm.inferred-type.metadata=dart.collection::UnmodifiableMapView<dart.core::Symbol*, dynamic>] core::Map::unmodifiable<core::Symbol*, dynamic>(#C4))){(core::Invocation) → dynamic});
[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2] no-such-method-forwarder method foo() → dynamic
- return _in::unsafeCast<dynamic>([@vm.direct-call.metadata=#lib::C.noSuchMethod] [@vm.inferred-type.metadata=#lib::T2 (skip check)] this.{self::C::noSuchMethod}(new core::_InvocationMirror::_withType(#C5, 0, #C2, #C3, [@vm.inferred-type.metadata=dart.collection::UnmodifiableMapView<dart.core::Symbol*, dynamic>] core::Map::unmodifiable<core::Symbol*, dynamic>(#C4))){(core::Invocation*) →* dynamic});
+ return _in::unsafeCast<dynamic>([@vm.direct-call.metadata=#lib::C.noSuchMethod] [@vm.inferred-type.metadata=#lib::T2 (skip check)] this.{self::C::noSuchMethod}(new core::_InvocationMirror::_withType(#C5, 0, #C2, #C3, [@vm.inferred-type.metadata=dart.collection::UnmodifiableMapView<dart.core::Symbol*, dynamic>] core::Map::unmodifiable<core::Symbol*, dynamic>(#C4))){(core::Invocation) → dynamic});
[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:4,getterSelectorId:5] [@vm.unboxing-info.metadata=(i,i,i,i)->b] no-such-method-forwarder method bazz([@vm.inferred-type.metadata=dart.core::_Smi (value: 1)] dynamic a1, [@vm.inferred-type.metadata=dart.core::_Smi (value: 2)] dynamic a2, [@vm.inferred-type.metadata=dart.core::_Smi (value: 3)] dynamic a3, [@vm.inferred-type.metadata=dart.core::_Smi (value: 4)] dynamic a4) → dynamic
- return _in::unsafeCast<dynamic>([@vm.direct-call.metadata=#lib::C.noSuchMethod] [@vm.inferred-type.metadata=#lib::T2 (skip check)] this.{self::C::noSuchMethod}(new core::_InvocationMirror::_withType(#C6, 0, #C2, core::List::unmodifiable<dynamic>([@vm.inferred-type.metadata=dart.core::_GrowableList<dynamic>] core::_GrowableList::_literal5<dynamic>()), [@vm.inferred-type.metadata=dart.collection::UnmodifiableMapView<dart.core::Symbol*, dynamic>] core::Map::unmodifiable<core::Symbol*, dynamic>(#C4))){(core::Invocation*) →* dynamic});
+ return _in::unsafeCast<dynamic>([@vm.direct-call.metadata=#lib::C.noSuchMethod] [@vm.inferred-type.metadata=#lib::T2 (skip check)] this.{self::C::noSuchMethod}(new core::_InvocationMirror::_withType(#C6, 0, #C2, core::List::unmodifiable<dynamic>([@vm.inferred-type.metadata=dart.core::_GrowableList<dynamic>] core::_GrowableList::_literal5<dynamic>()), [@vm.inferred-type.metadata=dart.collection::UnmodifiableMapView<dart.core::Symbol*, dynamic>] core::Map::unmodifiable<core::Symbol*, dynamic>(#C4))){(core::Invocation) → dynamic});
}
class E extends core::Object implements self::A {
- synthetic constructor •() → self::E*
+ synthetic constructor •() → self::E
: super core::Object::•()
;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasTearOffUses:false,methodOrSetterSelectorId:6,getterSelectorId:7] method noSuchMethod(core::Invocation* invocation) → dynamic {
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasTearOffUses:false,methodOrSetterSelectorId:6,getterSelectorId:7] method noSuchMethod(core::Invocation invocation) → dynamic {
return new self::T4::•();
}
[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:3] no-such-method-forwarder get bar() → dynamic
- return _in::unsafeCast<dynamic>([@vm.direct-call.metadata=#lib::E.noSuchMethod] [@vm.inferred-type.metadata=#lib::T4 (skip check)] this.{self::E::noSuchMethod}(new core::_InvocationMirror::_withType(#C1, 1, #C2, #C3, [@vm.inferred-type.metadata=dart.collection::UnmodifiableMapView<dart.core::Symbol*, dynamic>] core::Map::unmodifiable<core::Symbol*, dynamic>(#C4))){(core::Invocation*) →* dynamic});
+ return _in::unsafeCast<dynamic>([@vm.direct-call.metadata=#lib::E.noSuchMethod] [@vm.inferred-type.metadata=#lib::T4 (skip check)] this.{self::E::noSuchMethod}(new core::_InvocationMirror::_withType(#C1, 1, #C2, #C3, [@vm.inferred-type.metadata=dart.collection::UnmodifiableMapView<dart.core::Symbol*, dynamic>] core::Map::unmodifiable<core::Symbol*, dynamic>(#C4))){(core::Invocation) → dynamic});
}
class F extends core::Object {
- synthetic constructor •() → self::F*
+ synthetic constructor •() → self::F
: super core::Object::•()
;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:6,getterSelectorId:7] method noSuchMethod(core::Invocation* invocation) → dynamic {
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:6,getterSelectorId:7] method noSuchMethod(core::Invocation invocation) → dynamic {
return new self::T2::•();
}
}
class G extends core::Object {
- synthetic constructor •() → self::G*
+ synthetic constructor •() → self::G
: super core::Object::•()
;
-[@vm.procedure-attributes.metadata=getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:6,getterSelectorId:7] method noSuchMethod(core::Invocation* invocation) → dynamic {
+[@vm.procedure-attributes.metadata=getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:6,getterSelectorId:7] method noSuchMethod(core::Invocation invocation) → dynamic {
return new self::T5::•();
}
}
class H extends core::Object {
- synthetic constructor •() → self::H*
+ synthetic constructor •() → self::H
: super core::Object::•()
;
[@vm.procedure-attributes.metadata=getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:8,getterSelectorId:9] method foo({[@vm.inferred-type.metadata=dart.core::_Smi (value: 1)] dynamic left = #C7, [@vm.inferred-type.metadata=dart.core::_Smi (value: 2)] dynamic right = #C7}) → dynamic
return new self::T6::•();
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:6,getterSelectorId:7] method noSuchMethod(core::Invocation* invocation) → dynamic {
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:6,getterSelectorId:7] method noSuchMethod(core::Invocation invocation) → dynamic {
return new self::T7::•();
}
}
-[@vm.inferred-type.metadata=#lib::B?]static field self::A* bb = new self::B::•();
-[@vm.inferred-type.metadata=#lib::D?]static field self::A* dd = new self::D::•();
-[@vm.inferred-type.metadata=dart.core::Null? (value: null)]static field core::Function* unknown;
+[@vm.inferred-type.metadata=#lib::B?]static field self::A bb = new self::B::•();
+[@vm.inferred-type.metadata=#lib::D?]static field self::A dd = new self::D::•();
+[@vm.inferred-type.metadata=!]late static field core::Function unknown;
static method getDynamic() → dynamic
return self::unknown();
-static method main(core::List<core::String*>* args) → dynamic {
- core::print([@vm.direct-call.metadata=#lib::B.foo??] [@vm.inferred-type.metadata=#lib::T1 (skip check)] [@vm.inferred-type.metadata=#lib::B?] self::bb.{self::A::foo}(){() →* dynamic});
+static method main(core::List<core::String> args) → dynamic {
+ core::print([@vm.direct-call.metadata=#lib::B.foo??] [@vm.inferred-type.metadata=#lib::T1 (skip check)] [@vm.inferred-type.metadata=#lib::B?] self::bb.{self::A::foo}(){() → dynamic});
core::print([@vm.direct-call.metadata=#lib::B.bar??] [@vm.inferred-type.metadata=#lib::T1] [@vm.inferred-type.metadata=#lib::B?] self::bb.{self::A::bar}{dynamic});
- core::print([@vm.direct-call.metadata=#lib::B.bazz??] [@vm.inferred-type.metadata=#lib::T1 (skip check)] [@vm.inferred-type.metadata=#lib::B?] self::bb.{self::A::bazz}(1, 2, 3, 4){(dynamic, dynamic, dynamic, [dynamic, dynamic]) →* dynamic});
- core::print([@vm.direct-call.metadata=#lib::D.foo??] [@vm.inferred-type.metadata=#lib::T2 (skip check)] [@vm.inferred-type.metadata=#lib::D?] self::dd.{self::A::foo}(){() →* dynamic});
+ core::print([@vm.direct-call.metadata=#lib::B.bazz??] [@vm.inferred-type.metadata=#lib::T1 (skip check)] [@vm.inferred-type.metadata=#lib::B?] self::bb.{self::A::bazz}(1, 2, 3, 4){(dynamic, dynamic, dynamic, [dynamic, dynamic]) → dynamic});
+ core::print([@vm.direct-call.metadata=#lib::D.foo??] [@vm.inferred-type.metadata=#lib::T2 (skip check)] [@vm.inferred-type.metadata=#lib::D?] self::dd.{self::A::foo}(){() → dynamic});
core::print([@vm.direct-call.metadata=#lib::D.bar??] [@vm.inferred-type.metadata=#lib::T2] [@vm.inferred-type.metadata=#lib::D?] self::dd.{self::A::bar}{dynamic});
- core::print([@vm.direct-call.metadata=#lib::D.bazz??] [@vm.inferred-type.metadata=#lib::T2 (skip check)] [@vm.inferred-type.metadata=#lib::D?] self::dd.{self::A::bazz}(1, 2, 3, 4){(dynamic, dynamic, dynamic, [dynamic, dynamic]) →* dynamic});
+ core::print([@vm.direct-call.metadata=#lib::D.bazz??] [@vm.inferred-type.metadata=#lib::T2 (skip check)] [@vm.inferred-type.metadata=#lib::D?] self::dd.{self::A::bazz}(1, 2, 3, 4){(dynamic, dynamic, dynamic, [dynamic, dynamic]) → dynamic});
new self::E::•();
- self::A* xx = self::getDynamic() as{TypeError,ForDynamic} self::A*;
+ self::A xx = self::getDynamic() as{TypeError,ForDynamic,ForNonNullableByDefault} self::A;
core::print([@vm.inferred-type.metadata=!] xx.{self::A::bar}{dynamic});
dynamic yy = self::getDynamic();
core::print([@vm.inferred-type.metadata=!] yy{dynamic}.twoArg(1, 2, 3));
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/null_check_elimination_nnbd.dart b/pkg/vm/testcases/transformations/type_flow/transformer/null_check_elimination_nnbd.dart
index b529e22..016fff5 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/null_check_elimination_nnbd.dart
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/null_check_elimination_nnbd.dart
@@ -3,9 +3,6 @@
// BSD-style license that can be found in the LICENSE file.
// Tests elimination of null checks.
-// This test requires non-nullable experiment.
-
-// @dart = 2.10
class A {
String? nonNullable;
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/null_test_elimination.dart b/pkg/vm/testcases/transformations/type_flow/transformer/null_test_elimination.dart
index 121f842..e3f12b7 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/null_test_elimination.dart
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/null_test_elimination.dart
@@ -4,12 +4,10 @@
// Tests elimination of null tests.
-// @dart=2.9
-
class A {
- String nonNullable;
- String nullable;
- String alwaysNull;
+ String? nonNullable;
+ String? nullable;
+ String? alwaysNull;
A({this.nonNullable, this.nullable, this.alwaysNull});
}
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/null_test_elimination.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/null_test_elimination.dart.expect
index 11d07aa..461ce24 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/null_test_elimination.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/null_test_elimination.dart.expect
@@ -1,70 +1,70 @@
-library #lib;
+library #lib /*isNonNullableByDefault*/;
import self as self;
import "dart:core" as core;
import "dart:_internal" as _in;
class A extends core::Object {
-[@vm.inferred-type.metadata=dart.core::_OneByteString] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2] field core::String* nonNullable;
-[@vm.inferred-type.metadata=dart.core::_OneByteString?] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:3,getterSelectorId:4] field core::String* nullable;
-[@vm.inferred-type.metadata=dart.core::Null? (value: null)] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:5,getterSelectorId:6] field core::String* alwaysNull;
- constructor •([@vm.inferred-type.metadata=dart.core::_OneByteString] core::String* nonNullable, [@vm.inferred-type.metadata=dart.core::_OneByteString?] core::String* nullable) → self::A*
+[@vm.inferred-type.metadata=dart.core::_OneByteString] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2] field core::String? nonNullable;
+[@vm.inferred-type.metadata=dart.core::_OneByteString?] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:3,getterSelectorId:4] field core::String? nullable;
+[@vm.inferred-type.metadata=dart.core::Null? (value: null)] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:5,getterSelectorId:6] field core::String? alwaysNull;
+ constructor •([@vm.inferred-type.metadata=dart.core::_OneByteString] core::String? nonNullable, [@vm.inferred-type.metadata=dart.core::_OneByteString?] core::String? nullable) → self::A
: self::A::nonNullable = nonNullable, self::A::nullable = nullable, self::A::alwaysNull = #C1, super core::Object::•()
;
}
-[@vm.inferred-type.metadata=#lib::A?]static field self::A* staticField = new self::A::•("hi", "bye");
-static method testNonNullableIf1([@vm.inferred-type.metadata=#lib::A?] self::A* a) → dynamic {
+[@vm.inferred-type.metadata=#lib::A?]static field self::A staticField = new self::A::•("hi", "bye");
+static method testNonNullableIf1([@vm.inferred-type.metadata=#lib::A?] self::A a) → dynamic {
{
- [@vm.direct-call.metadata=#lib::A.nonNullable??] [@vm.inferred-type.metadata=dart.core::_OneByteString] a.{self::A::nonNullable}{core::String*};
+ [@vm.direct-call.metadata=#lib::A.nonNullable??] [@vm.inferred-type.metadata=dart.core::_OneByteString] a.{self::A::nonNullable}{core::String?};
}
}
-static method testNullableIf1([@vm.inferred-type.metadata=#lib::A?] self::A* a) → dynamic {
- if([@vm.direct-call.metadata=#lib::A.nullable??] [@vm.inferred-type.metadata=dart.core::_OneByteString?] a.{self::A::nullable}{core::String*} == null) {
+static method testNullableIf1([@vm.inferred-type.metadata=#lib::A?] self::A a) → dynamic {
+ if([@vm.direct-call.metadata=#lib::A.nullable??] [@vm.inferred-type.metadata=dart.core::_OneByteString?] a.{self::A::nullable}{core::String?} == null) {
core::print("null");
}
}
-static method testAlwaysNullIf1([@vm.inferred-type.metadata=#lib::A?] self::A* a) → dynamic {
+static method testAlwaysNullIf1([@vm.inferred-type.metadata=#lib::A?] self::A a) → dynamic {
{
- [@vm.direct-call.metadata=#lib::A.alwaysNull??] [@vm.inferred-type.metadata=dart.core::Null? (value: null)] a.{self::A::alwaysNull}{core::String*};
+ [@vm.direct-call.metadata=#lib::A.alwaysNull??] [@vm.inferred-type.metadata=dart.core::Null? (value: null)] a.{self::A::alwaysNull}{core::String?};
{
core::print("null");
}
}
}
-static method testNonNullableIf2([@vm.inferred-type.metadata=#lib::A?] self::A* a) → dynamic {
+static method testNonNullableIf2([@vm.inferred-type.metadata=#lib::A?] self::A a) → dynamic {
if(( block {
- [@vm.direct-call.metadata=#lib::A.nonNullable??] [@vm.inferred-type.metadata=dart.core::_OneByteString] a.{self::A::nonNullable}{core::String*};
- } =>true) && _in::unsafeCast<core::bool*>([@vm.inferred-type.metadata=dart.core::bool] self::someCondition())) {
+ [@vm.direct-call.metadata=#lib::A.nonNullable??] [@vm.inferred-type.metadata=dart.core::_OneByteString] a.{self::A::nonNullable}{core::String?};
+ } =>true) && _in::unsafeCast<core::bool>([@vm.inferred-type.metadata=dart.core::bool] self::someCondition())) {
core::print("not null");
}
}
-static method testNullableIf2([@vm.inferred-type.metadata=#lib::A?] self::A* a) → dynamic {
- if(!([@vm.direct-call.metadata=#lib::A.nullable??] [@vm.inferred-type.metadata=dart.core::_OneByteString?] a.{self::A::nullable}{core::String*} == null) && _in::unsafeCast<core::bool*>([@vm.inferred-type.metadata=dart.core::bool] self::someCondition())) {
+static method testNullableIf2([@vm.inferred-type.metadata=#lib::A?] self::A a) → dynamic {
+ if(!([@vm.direct-call.metadata=#lib::A.nullable??] [@vm.inferred-type.metadata=dart.core::_OneByteString?] a.{self::A::nullable}{core::String?} == null) && _in::unsafeCast<core::bool>([@vm.inferred-type.metadata=dart.core::bool] self::someCondition())) {
core::print("not null");
}
}
-static method testAlwaysNullIf2([@vm.inferred-type.metadata=#lib::A?] self::A* a) → dynamic {
+static method testAlwaysNullIf2([@vm.inferred-type.metadata=#lib::A?] self::A a) → dynamic {
{
- [@vm.direct-call.metadata=#lib::A.alwaysNull??] [@vm.inferred-type.metadata=dart.core::Null? (value: null)] a.{self::A::alwaysNull}{core::String*};
+ [@vm.direct-call.metadata=#lib::A.alwaysNull??] [@vm.inferred-type.metadata=dart.core::Null? (value: null)] a.{self::A::alwaysNull}{core::String?};
}
}
-static method testNonNullableCondExpr([@vm.inferred-type.metadata=#lib::A?] self::A* a) → dynamic
+static method testNonNullableCondExpr([@vm.inferred-type.metadata=#lib::A?] self::A a) → dynamic
return block {
- [@vm.direct-call.metadata=#lib::A.nonNullable??] [@vm.inferred-type.metadata=dart.core::_OneByteString] a.{self::A::nonNullable}{core::String*};
+ [@vm.direct-call.metadata=#lib::A.nonNullable??] [@vm.inferred-type.metadata=dart.core::_OneByteString] a.{self::A::nonNullable}{core::String?};
} =>"not null";
-static method testNullableCondExpr([@vm.inferred-type.metadata=#lib::A?] self::A* a) → dynamic
- return !([@vm.direct-call.metadata=#lib::A.nullable??] [@vm.inferred-type.metadata=dart.core::_OneByteString?] a.{self::A::nullable}{core::String*} == null) ?{core::String*} "not null" : "null";
-static method testAlwaysNullCondExpr([@vm.inferred-type.metadata=#lib::A?] self::A* a) → dynamic
+static method testNullableCondExpr([@vm.inferred-type.metadata=#lib::A?] self::A a) → dynamic
+ return !([@vm.direct-call.metadata=#lib::A.nullable??] [@vm.inferred-type.metadata=dart.core::_OneByteString?] a.{self::A::nullable}{core::String?} == null) ?{core::String} "not null" : "null";
+static method testAlwaysNullCondExpr([@vm.inferred-type.metadata=#lib::A?] self::A a) → dynamic
return block {
- [@vm.direct-call.metadata=#lib::A.alwaysNull??] [@vm.inferred-type.metadata=dart.core::Null? (value: null)] a.{self::A::alwaysNull}{core::String*};
+ [@vm.direct-call.metadata=#lib::A.alwaysNull??] [@vm.inferred-type.metadata=dart.core::Null? (value: null)] a.{self::A::alwaysNull}{core::String?};
} =>"null";
static method someCondition() → dynamic
- return [@vm.inferred-type.metadata=dart.core::bool] [@vm.inferred-type.metadata=int?] core::int::parse("1") =={core::num::==}{(core::Object*) →* core::bool*} 1;
+ return [@vm.inferred-type.metadata=dart.core::bool] [@vm.inferred-type.metadata=int?] core::int::parse("1") =={core::num::==}{(core::Object) → core::bool} 1;
static method main() → void {
- final core::List<self::A*>* list = [@vm.inferred-type.metadata=dart.core::_GrowableList<#lib::A*>] core::_GrowableList::_literal2<self::A*>(new self::A::•("foo", null), [@vm.inferred-type.metadata=#lib::A?] self::staticField);
+ final core::List<self::A> list = [@vm.inferred-type.metadata=dart.core::_GrowableList<#lib::A>] core::_GrowableList::_literal2<self::A>(new self::A::•("foo", null), [@vm.inferred-type.metadata=#lib::A?] self::staticField);
{
- core::Iterator<self::A*>* :sync-for-iterator = [@vm.direct-call.metadata=dart.core::_GrowableList.iterator] [@vm.inferred-type.metadata=dart._internal::ListIterator<#lib::A*>] list.{core::Iterable::iterator}{core::Iterator<self::A*>*};
+ core::Iterator<self::A> :sync-for-iterator = [@vm.direct-call.metadata=dart.core::_GrowableList.iterator] [@vm.inferred-type.metadata=dart._internal::ListIterator<#lib::A>] list.{core::Iterable::iterator}{core::Iterator<self::A>};
for (; [@vm.direct-call.metadata=dart._internal::ListIterator.moveNext] [@vm.inferred-type.metadata=dart.core::bool (skip check)] :sync-for-iterator.{core::Iterator::moveNext}(){() → core::bool}; ) {
- self::A* a = [@vm.direct-call.metadata=dart._internal::ListIterator.current] [@vm.inferred-type.metadata=#lib::A?] :sync-for-iterator.{core::Iterator::current}{self::A*};
+ self::A a = [@vm.direct-call.metadata=dart._internal::ListIterator.current] [@vm.inferred-type.metadata=#lib::A?] :sync-for-iterator.{core::Iterator::current}{self::A};
{
self::testNonNullableIf1(a);
self::testNullableIf1(a);
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/param_types_before_strong_mode_checks.dart b/pkg/vm/testcases/transformations/type_flow/transformer/param_types_before_strong_mode_checks.dart
index 4065205..1d07acd 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/param_types_before_strong_mode_checks.dart
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/param_types_before_strong_mode_checks.dart
@@ -5,8 +5,6 @@
// This test verifies that inferred types of parameters are valid *before*
// applying strong mode argument type checks.
-// @dart=2.9
-
abstract class T0 {
void foo();
}
@@ -56,7 +54,7 @@
}
}
-Function unknown;
+late Function unknown;
getDynamic() => unknown.call();
use(x) => unknown.call(x);
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/param_types_before_strong_mode_checks.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/param_types_before_strong_mode_checks.dart.expect
index 7317c7f3..57eda05 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/param_types_before_strong_mode_checks.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/param_types_before_strong_mode_checks.dart.expect
@@ -1,63 +1,63 @@
-library #lib;
+library #lib /*isNonNullableByDefault*/;
import self as self;
import "dart:core" as core;
abstract class T0 extends core::Object {
- synthetic constructor •() → self::T0*
+ synthetic constructor •() → self::T0
: super core::Object::•()
;
[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2] abstract method foo() → void;
}
class T2 extends self::T0 {
- synthetic constructor •() → self::T2*
+ synthetic constructor •() → self::T2
: super self::T0::•()
;
[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2] method foo() → void {}
}
class A extends core::Object {
- synthetic constructor •() → self::A*
+ synthetic constructor •() → self::A
: super core::Object::•()
;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,methodOrSetterSelectorId:3,getterSelectorId:4] method method1(self::T0* t0) → void {
- [@vm.direct-call.metadata=#lib::T2.foo??] [@vm.inferred-type.metadata=!? (skip check)] t0.{self::T0::foo}(){() →* void};
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,methodOrSetterSelectorId:3,getterSelectorId:4] method method1(self::T0 t0) → void {
+ [@vm.direct-call.metadata=#lib::T2.foo??] [@vm.inferred-type.metadata=!? (skip check)] t0.{self::T0::foo}(){() → void};
}
}
abstract class B extends core::Object {
[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:5,getterSelectorId:6] abstract method method2(covariant dynamic arg) → void;
}
class C extends core::Object implements self::B {
- synthetic constructor •() → self::C*
+ synthetic constructor •() → self::C
: super core::Object::•()
;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:5,getterSelectorId:6] method method2(covariant self::T0* t0) → void {
- [@vm.direct-call.metadata=#lib::T2.foo??] [@vm.inferred-type.metadata=!? (skip check)] t0.{self::T0::foo}(){() →* void};
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:5,getterSelectorId:6] method method2(covariant self::T0 t0) → void {
+ [@vm.direct-call.metadata=#lib::T2.foo??] [@vm.inferred-type.metadata=!? (skip check)] t0.{self::T0::foo}(){() → void};
}
}
class D extends core::Object {
- synthetic constructor •() → self::D*
+ synthetic constructor •() → self::D
: super core::Object::•()
;
-[@vm.procedure-attributes.metadata=getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:7,getterSelectorId:8] method method3(self::T0* t0) → void {
- [@vm.direct-call.metadata=#lib::T2.foo??] [@vm.inferred-type.metadata=!? (skip check)] t0.{self::T0::foo}(){() →* void};
+[@vm.procedure-attributes.metadata=getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:7,getterSelectorId:8] method method3(self::T0 t0) → void {
+ [@vm.direct-call.metadata=#lib::T2.foo??] [@vm.inferred-type.metadata=!? (skip check)] t0.{self::T0::foo}(){() → void};
}
}
-[@vm.inferred-type.metadata=dart.core::Null? (value: null)]static field core::Function* unknown;
-static method func1([@vm.inferred-type.metadata=#lib::T2?] self::T0* t0) → void {
- [@vm.direct-call.metadata=#lib::T2.foo??] [@vm.inferred-type.metadata=!? (skip check)] t0.{self::T0::foo}(){() →* void};
+[@vm.inferred-type.metadata=!]late static field core::Function unknown;
+static method func1([@vm.inferred-type.metadata=#lib::T2?] self::T0 t0) → void {
+ [@vm.direct-call.metadata=#lib::T2.foo??] [@vm.inferred-type.metadata=!? (skip check)] t0.{self::T0::foo}(){() → void};
}
-static method func2(self::T0* t0) → void {
- [@vm.direct-call.metadata=#lib::T2.foo??] [@vm.inferred-type.metadata=!? (skip check)] t0.{self::T0::foo}(){() →* void};
+static method func2(self::T0 t0) → void {
+ [@vm.direct-call.metadata=#lib::T2.foo??] [@vm.inferred-type.metadata=!? (skip check)] t0.{self::T0::foo}(){() → void};
}
static method getDynamic() → dynamic
return self::unknown();
static method use(dynamic x) → dynamic
return self::unknown(x);
-static method main(core::List<core::String*>* args) → dynamic {
- self::func1(self::getDynamic() as{TypeError,ForDynamic} self::T0*);
+static method main(core::List<core::String> args) → dynamic {
+ self::func1(self::getDynamic() as{TypeError,ForDynamic,ForNonNullableByDefault} self::T0);
self::use(#C1);
- self::use(new self::A::•().{self::A::method1}{(self::T0*) →* void});
- self::B* bb = self::getDynamic() as{TypeError,ForDynamic} self::B*;
- [@vm.direct-call.metadata=#lib::C.method2??] [@vm.inferred-type.metadata=!? (skip check)] bb.{self::B::method2}(self::getDynamic()){(dynamic) →* void};
+ self::use(new self::A::•().{self::A::method1}{(self::T0) → void});
+ self::B bb = self::getDynamic() as{TypeError,ForDynamic,ForNonNullableByDefault} self::B;
+ [@vm.direct-call.metadata=#lib::C.method2??] [@vm.inferred-type.metadata=!? (skip check)] bb.{self::B::method2}(self::getDynamic()){(dynamic) → void};
self::getDynamic(){dynamic}.method3(self::getDynamic());
new self::T2::•();
new self::A::•();
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/protobuf_handler/lib/name_mangling_test.dart b/pkg/vm/testcases/transformations/type_flow/transformer/protobuf_handler/lib/name_mangling_test.dart
index b52c5dc..c5b7bf4 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/protobuf_handler/lib/name_mangling_test.dart
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/protobuf_handler/lib/name_mangling_test.dart
@@ -2,8 +2,6 @@
// for 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:test/test.dart';
-
import 'generated/name_mangling.pb.dart';
main() {
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/protobuf_handler/lib/name_mangling_test.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/protobuf_handler/lib/name_mangling_test.dart.expect
index bc4814f..63e55db 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/protobuf_handler/lib/name_mangling_test.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/protobuf_handler/lib/name_mangling_test.dart.expect
@@ -3,7 +3,6 @@
import "generated/name_mangling.pb.dart" as pb;
import "dart:core" as core;
-import "package:test/test.dart";
import "file:pkg/vm/testcases/transformations/type_flow/transformer/protobuf_handler/lib/generated/name_mangling.pb.dart";
static method main() → dynamic {
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/regress_41452_nnbd_strong.dart b/pkg/vm/testcases/transformations/type_flow/transformer/regress_41452_nnbd_strong.dart
index bc79497..03ba604 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/regress_41452_nnbd_strong.dart
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/regress_41452_nnbd_strong.dart
@@ -4,9 +4,7 @@
// Regression test for https://github.com/dart-lang/sdk/issues/41452.
// Tests handling of null initializer of covariant field.
-// This test requires non-nullable experiment and NNBD strong mode.
-
-// @dart = 2.10
+// This test requires sound null safety.
class _SplayTreeNode<Node extends _SplayTreeNode<Node>> {
Node? left;
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/regress_42418_1_test.dart b/pkg/vm/testcases/transformations/type_flow/transformer/regress_42418_1_test.dart
index 76df937..add07b4 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/regress_42418_1_test.dart
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/regress_42418_1_test.dart
@@ -2,8 +2,6 @@
// for 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.9
-
import 'dart:math';
import 'package:expect/expect.dart';
@@ -12,12 +10,12 @@
class A {
@pragma("vm:never-inline")
- void foo(/* boxed */ int x) => Expect.isTrue(x.isOdd);
+ void foo(/* boxed */ int? x) => Expect.isTrue(x!.isOdd);
}
class B {
@pragma("vm:never-inline")
- void foo(/* unboxed */ int x) => Expect.isTrue(x.isOdd);
+ void foo(/* unboxed */ int? x) => Expect.isTrue(x!.isOdd);
}
class C extends A implements B {}
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/regress_42418_1_test.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/regress_42418_1_test.dart.expect
index 16d4a2a..9d24274 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/regress_42418_1_test.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/regress_42418_1_test.dart.expect
@@ -1,48 +1,49 @@
-library #lib;
+library #lib /*isNonNullableByDefault*/;
import self as self;
import "dart:core" as core;
import "package:expect/expect.dart" as exp;
+import "dart:_internal" as _in;
import "dart:math" as math;
import "dart:math";
import "package:expect/expect.dart";
class A extends core::Object {
- synthetic constructor •() → self::A*
+ synthetic constructor •() → self::A
: super core::Object::•()
;
[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2] @#C3
- method foo([@vm.inferred-type.metadata=int?] core::int* x) → void
- return [@vm.inferred-type.metadata=dart.core::Null? (value: null)] exp::Expect::isTrue([@vm.direct-call.metadata=dart.core::_IntegerImplementation.isOdd??] [@vm.inferred-type.metadata=dart.core::bool] x.{core::int::isOdd}{core::bool*});
+ method foo([@vm.inferred-type.metadata=int?] core::int? x) → void
+ return [@vm.inferred-type.metadata=dart.core::Null? (value: null)] exp::Expect::isTrue([@vm.direct-call.metadata=dart.core::_IntegerImplementation.isOdd] [@vm.inferred-type.metadata=dart.core::bool] x!.{core::int::isOdd}{core::bool});
}
class B extends core::Object {
- synthetic constructor •() → self::B*
+ synthetic constructor •() → self::B
: super core::Object::•()
;
[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2] @#C3
- method foo([@vm.inferred-type.metadata=int] core::int* x) → void
- return [@vm.inferred-type.metadata=dart.core::Null? (value: null)] exp::Expect::isTrue([@vm.direct-call.metadata=dart.core::_IntegerImplementation.isOdd] [@vm.inferred-type.metadata=dart.core::bool] x.{core::int::isOdd}{core::bool*});
+ method foo([@vm.inferred-type.metadata=int] core::int? x) → void
+ return [@vm.inferred-type.metadata=dart.core::Null? (value: null)] exp::Expect::isTrue([@vm.direct-call.metadata=dart.core::_IntegerImplementation.isOdd] [@vm.inferred-type.metadata=dart.core::bool] _in::unsafeCast<core::int>(x).{core::int::isOdd}{core::bool});
}
class C extends self::A implements self::B {
- synthetic constructor •() → self::C*
+ synthetic constructor •() → self::C
: super self::A::•()
;
}
-[@vm.inferred-type.metadata=dart.core::bool?]static final field core::bool* alwaysFalse = [@vm.inferred-type.metadata=dart.core::bool] [@vm.inferred-type.metadata=int?] core::int::parse("1") =={core::num::==}{(core::Object*) →* core::bool*} 2;
+[@vm.inferred-type.metadata=dart.core::bool?]static final field core::bool alwaysFalse = [@vm.inferred-type.metadata=dart.core::bool] [@vm.inferred-type.metadata=int?] core::int::parse("1") =={core::num::==}{(core::Object) → core::bool} 2;
static method main() → dynamic {
- final math::Random* r = [@vm.inferred-type.metadata=dart.math::_Random] math::Random::•();
+ final math::Random r = [@vm.inferred-type.metadata=dart.math::_Random] math::Random::•();
if([@vm.inferred-type.metadata=dart.core::bool?] self::alwaysFalse) {
- [@vm.direct-call.metadata=#lib::A.foo] [@vm.inferred-type.metadata=!? (skip check)] new self::A::•().{self::A::foo}([@vm.direct-call.metadata=dart.math::_Random.nextInt] [@vm.inferred-type.metadata=int (skip check)] r.{math::Random::nextInt}(10){(core::int*) →* core::int*}){(core::int*) →* void};
- [@vm.direct-call.metadata=#lib::B.foo] [@vm.inferred-type.metadata=!? (skip check)] new self::B::•().{self::B::foo}([@vm.direct-call.metadata=dart.math::_Random.nextInt] [@vm.inferred-type.metadata=int (skip check)] r.{math::Random::nextInt}(10){(core::int*) →* core::int*}){(core::int*) →* void};
- [@vm.direct-call.metadata=#lib::A.foo] [@vm.inferred-type.metadata=!? (skip check)] new self::A::•().{self::A::foo}(null){(core::int*) →* void};
+ [@vm.direct-call.metadata=#lib::A.foo] [@vm.inferred-type.metadata=!? (skip check)] new self::A::•().{self::A::foo}([@vm.direct-call.metadata=dart.math::_Random.nextInt] [@vm.inferred-type.metadata=int (skip check)] r.{math::Random::nextInt}(10){(core::int) → core::int}){(core::int?) → void};
+ [@vm.direct-call.metadata=#lib::B.foo] [@vm.inferred-type.metadata=!? (skip check)] new self::B::•().{self::B::foo}([@vm.direct-call.metadata=dart.math::_Random.nextInt] [@vm.inferred-type.metadata=int (skip check)] r.{math::Random::nextInt}(10){(core::int) → core::int}){(core::int?) → void};
+ [@vm.direct-call.metadata=#lib::A.foo] [@vm.inferred-type.metadata=!? (skip check)] new self::A::•().{self::A::foo}(null){(core::int?) → void};
}
- final core::List<self::B*>* l = [@vm.inferred-type.metadata=dart.core::_GrowableList<#lib::B*>] core::_GrowableList::_literal2<self::B*>(new self::B::•(), new self::C::•());
+ final core::List<self::B> l = [@vm.inferred-type.metadata=dart.core::_GrowableList<#lib::B>] core::_GrowableList::_literal2<self::B>(new self::B::•(), new self::C::•());
{
- core::Iterator<self::B*>* :sync-for-iterator = [@vm.direct-call.metadata=dart.core::_GrowableList.iterator] [@vm.inferred-type.metadata=dart._internal::ListIterator<#lib::B*>] l.{core::Iterable::iterator}{core::Iterator<self::B*>*};
+ core::Iterator<self::B> :sync-for-iterator = [@vm.direct-call.metadata=dart.core::_GrowableList.iterator] [@vm.inferred-type.metadata=dart._internal::ListIterator<#lib::B>] l.{core::Iterable::iterator}{core::Iterator<self::B>};
for (; [@vm.direct-call.metadata=dart._internal::ListIterator.moveNext] [@vm.inferred-type.metadata=dart.core::bool (skip check)] :sync-for-iterator.{core::Iterator::moveNext}(){() → core::bool}; ) {
- self::B* b = [@vm.direct-call.metadata=dart._internal::ListIterator.current] :sync-for-iterator.{core::Iterator::current}{self::B*};
+ self::B b = [@vm.direct-call.metadata=dart._internal::ListIterator.current] :sync-for-iterator.{core::Iterator::current}{self::B};
{
- b.{self::B::foo}(13){(core::int*) →* void};
+ b.{self::B::foo}(13){(core::int?) → void};
}
}
}
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/regress_42418_2_test.dart b/pkg/vm/testcases/transformations/type_flow/transformer/regress_42418_2_test.dart
index 45943ff..01bede8 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/regress_42418_2_test.dart
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/regress_42418_2_test.dart
@@ -2,8 +2,6 @@
// for 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.9
-
import 'dart:math';
import 'package:expect/expect.dart';
@@ -12,12 +10,12 @@
class A {
@pragma("vm:never-inline")
- void bar(/* unboxed */ int x) => Expect.isTrue(x.isOdd);
+ void bar(/* unboxed */ int? x) => Expect.isTrue(x!.isOdd);
}
class B {
@pragma("vm:never-inline")
- void bar(/* boxed */ int x) => Expect.isTrue(x.isOdd);
+ void bar(/* boxed */ int? x) => Expect.isTrue(x!.isOdd);
}
class C extends A implements B {}
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/regress_42418_2_test.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/regress_42418_2_test.dart.expect
index dff8e38..ae6258b 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/regress_42418_2_test.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/regress_42418_2_test.dart.expect
@@ -1,48 +1,49 @@
-library #lib;
+library #lib /*isNonNullableByDefault*/;
import self as self;
import "dart:core" as core;
import "package:expect/expect.dart" as exp;
+import "dart:_internal" as _in;
import "dart:math" as math;
import "dart:math";
import "package:expect/expect.dart";
class A extends core::Object {
- synthetic constructor •() → self::A*
+ synthetic constructor •() → self::A
: super core::Object::•()
;
[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2] @#C3
- method bar([@vm.inferred-type.metadata=int] core::int* x) → void
- return [@vm.inferred-type.metadata=dart.core::Null? (value: null)] exp::Expect::isTrue([@vm.direct-call.metadata=dart.core::_IntegerImplementation.isOdd] [@vm.inferred-type.metadata=dart.core::bool] x.{core::int::isOdd}{core::bool*});
+ method bar([@vm.inferred-type.metadata=int] core::int? x) → void
+ return [@vm.inferred-type.metadata=dart.core::Null? (value: null)] exp::Expect::isTrue([@vm.direct-call.metadata=dart.core::_IntegerImplementation.isOdd] [@vm.inferred-type.metadata=dart.core::bool] _in::unsafeCast<core::int>(x).{core::int::isOdd}{core::bool});
}
class B extends core::Object {
- synthetic constructor •() → self::B*
+ synthetic constructor •() → self::B
: super core::Object::•()
;
[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2] @#C3
- method bar([@vm.inferred-type.metadata=int?] core::int* x) → void
- return [@vm.inferred-type.metadata=dart.core::Null? (value: null)] exp::Expect::isTrue([@vm.direct-call.metadata=dart.core::_IntegerImplementation.isOdd??] [@vm.inferred-type.metadata=dart.core::bool] x.{core::int::isOdd}{core::bool*});
+ method bar([@vm.inferred-type.metadata=int?] core::int? x) → void
+ return [@vm.inferred-type.metadata=dart.core::Null? (value: null)] exp::Expect::isTrue([@vm.direct-call.metadata=dart.core::_IntegerImplementation.isOdd] [@vm.inferred-type.metadata=dart.core::bool] x!.{core::int::isOdd}{core::bool});
}
class C extends self::A implements self::B {
- synthetic constructor •() → self::C*
+ synthetic constructor •() → self::C
: super self::A::•()
;
}
-[@vm.inferred-type.metadata=dart.core::bool?]static final field core::bool* alwaysFalse = [@vm.inferred-type.metadata=dart.core::bool] [@vm.inferred-type.metadata=int?] core::int::parse("1") =={core::num::==}{(core::Object*) →* core::bool*} 2;
+[@vm.inferred-type.metadata=dart.core::bool?]static final field core::bool alwaysFalse = [@vm.inferred-type.metadata=dart.core::bool] [@vm.inferred-type.metadata=int?] core::int::parse("1") =={core::num::==}{(core::Object) → core::bool} 2;
static method main() → dynamic {
- final math::Random* r = [@vm.inferred-type.metadata=dart.math::_Random] math::Random::•();
+ final math::Random r = [@vm.inferred-type.metadata=dart.math::_Random] math::Random::•();
if([@vm.inferred-type.metadata=dart.core::bool?] self::alwaysFalse) {
- [@vm.direct-call.metadata=#lib::A.bar] [@vm.inferred-type.metadata=!? (skip check)] new self::A::•().{self::A::bar}([@vm.direct-call.metadata=dart.math::_Random.nextInt] [@vm.inferred-type.metadata=int (skip check)] r.{math::Random::nextInt}(10){(core::int*) →* core::int*}){(core::int*) →* void};
- [@vm.direct-call.metadata=#lib::B.bar] [@vm.inferred-type.metadata=!? (skip check)] new self::B::•().{self::B::bar}([@vm.direct-call.metadata=dart.math::_Random.nextInt] [@vm.inferred-type.metadata=int (skip check)] r.{math::Random::nextInt}(10){(core::int*) →* core::int*}){(core::int*) →* void};
- [@vm.direct-call.metadata=#lib::B.bar] [@vm.inferred-type.metadata=!? (skip check)] new self::B::•().{self::B::bar}(null){(core::int*) →* void};
+ [@vm.direct-call.metadata=#lib::A.bar] [@vm.inferred-type.metadata=!? (skip check)] new self::A::•().{self::A::bar}([@vm.direct-call.metadata=dart.math::_Random.nextInt] [@vm.inferred-type.metadata=int (skip check)] r.{math::Random::nextInt}(10){(core::int) → core::int}){(core::int?) → void};
+ [@vm.direct-call.metadata=#lib::B.bar] [@vm.inferred-type.metadata=!? (skip check)] new self::B::•().{self::B::bar}([@vm.direct-call.metadata=dart.math::_Random.nextInt] [@vm.inferred-type.metadata=int (skip check)] r.{math::Random::nextInt}(10){(core::int) → core::int}){(core::int?) → void};
+ [@vm.direct-call.metadata=#lib::B.bar] [@vm.inferred-type.metadata=!? (skip check)] new self::B::•().{self::B::bar}(null){(core::int?) → void};
}
- final core::List<self::B*>* l = [@vm.inferred-type.metadata=dart.core::_GrowableList<#lib::B*>] core::_GrowableList::_literal2<self::B*>(new self::B::•(), new self::C::•());
+ final core::List<self::B> l = [@vm.inferred-type.metadata=dart.core::_GrowableList<#lib::B>] core::_GrowableList::_literal2<self::B>(new self::B::•(), new self::C::•());
{
- core::Iterator<self::B*>* :sync-for-iterator = [@vm.direct-call.metadata=dart.core::_GrowableList.iterator] [@vm.inferred-type.metadata=dart._internal::ListIterator<#lib::B*>] l.{core::Iterable::iterator}{core::Iterator<self::B*>*};
+ core::Iterator<self::B> :sync-for-iterator = [@vm.direct-call.metadata=dart.core::_GrowableList.iterator] [@vm.inferred-type.metadata=dart._internal::ListIterator<#lib::B>] l.{core::Iterable::iterator}{core::Iterator<self::B>};
for (; [@vm.direct-call.metadata=dart._internal::ListIterator.moveNext] [@vm.inferred-type.metadata=dart.core::bool (skip check)] :sync-for-iterator.{core::Iterator::moveNext}(){() → core::bool}; ) {
- self::B* b = [@vm.direct-call.metadata=dart._internal::ListIterator.current] :sync-for-iterator.{core::Iterator::current}{self::B*};
+ self::B b = [@vm.direct-call.metadata=dart._internal::ListIterator.current] :sync-for-iterator.{core::Iterator::current}{self::B};
{
- b.{self::B::bar}(13){(core::int*) →* void};
+ b.{self::B::bar}(13){(core::int?) → void};
}
}
}
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/regress_45324_2.dart b/pkg/vm/testcases/transformations/type_flow/transformer/regress_45324_2.dart
index 6c4d972..a655aa5 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/regress_45324_2.dart
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/regress_45324_2.dart
@@ -2,8 +2,6 @@
// for 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.12
-
class A {
void doTest(Z a) {
print(a.appName);
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/regress_46461.dart b/pkg/vm/testcases/transformations/type_flow/transformer/regress_46461.dart
index d50e669..4b25bd4 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/regress_46461.dart
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/regress_46461.dart
@@ -2,8 +2,6 @@
// for 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.12
-
enum A { a1, a2 }
class B {
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/regress_flutter16182.dart b/pkg/vm/testcases/transformations/type_flow/transformer/regress_flutter16182.dart
index fcc1c23..f565760 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/regress_flutter16182.dart
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/regress_flutter16182.dart
@@ -5,11 +5,9 @@
// Regression test for https://github.com/flutter/flutter/issues/16182
// Verifies that TFA correctly handles calls via fields/getters.
-// @dart=2.9
-
import "package:expect/expect.dart";
-bool ok;
+bool? ok;
class T1 {
// Should be reachable.
@@ -19,7 +17,7 @@
}
class A1 {
- T1 foo;
+ T1? foo;
void call([a1, a2, a3, a4, a5]) {
foo = a5;
@@ -35,7 +33,7 @@
bb.aa1(1, 2, 3, 4, new T1());
ok = false;
- bb.aa1.foo.doTest1();
+ bb.aa1.foo!.doTest1();
Expect.isTrue(ok);
}
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/regress_flutter16182.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/regress_flutter16182.dart.expect
index 15a6a84..fa24c7a 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/regress_flutter16182.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/regress_flutter16182.dart.expect
@@ -1,4 +1,4 @@
-library #lib;
+library #lib /*isNonNullableByDefault*/;
import self as self;
import "dart:core" as core;
import "dart:_internal" as _in;
@@ -7,7 +7,7 @@
import "package:expect/expect.dart";
class T1 extends core::Object {
- synthetic constructor •() → self::T1*
+ synthetic constructor •() → self::T1
: super core::Object::•()
;
[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2] method doTest1() → void {
@@ -15,22 +15,22 @@
}
}
class A1 extends core::Object {
-[@vm.inferred-type.metadata=#lib::T1?] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:3,getterSelectorId:4] field self::T1* foo = null;
- synthetic constructor •() → self::A1*
+[@vm.inferred-type.metadata=#lib::T1?] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:3,getterSelectorId:4] field self::T1? foo = null;
+ synthetic constructor •() → self::A1
: super core::Object::•()
;
[@vm.procedure-attributes.metadata=getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:5,getterSelectorId:6] method call([dynamic a1 = #C1, dynamic a2 = #C1, dynamic a3 = #C1, [@vm.inferred-type.metadata=dart.core::_Smi?] dynamic a4 = #C1, [@vm.inferred-type.metadata=#lib::T1?] dynamic a5 = #C1]) → void {
- [@vm.direct-call.metadata=#lib::A1.foo] [@vm.inferred-type.metadata=!? (skip check)] this.{self::A1::foo} = _in::unsafeCast<self::T1*>(a5);
+ [@vm.direct-call.metadata=#lib::A1.foo] [@vm.inferred-type.metadata=!? (skip check)] this.{self::A1::foo} = _in::unsafeCast<self::T1?>(a5);
}
}
class B1 extends core::Object {
-[@vm.inferred-type.metadata=#lib::A1] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:7,getterSelectorId:8] field self::A1* aa1;
- synthetic constructor •() → self::B1*
+[@vm.inferred-type.metadata=#lib::A1] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:7,getterSelectorId:8] field self::A1 aa1;
+ synthetic constructor •() → self::B1
: self::B1::aa1 = new self::A1::•(), super core::Object::•()
;
}
class T2 extends core::Object {
- synthetic constructor •() → self::T2*
+ synthetic constructor •() → self::T2
: super core::Object::•()
;
[@vm.procedure-attributes.metadata=getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:9,getterSelectorId:10] method doTest2() → void {
@@ -39,7 +39,7 @@
}
class A2 extends core::Object {
[@vm.inferred-type.metadata=#lib::T2?] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:11,getterSelectorId:12] field dynamic foo = null;
- synthetic constructor •() → self::A2*
+ synthetic constructor •() → self::A2
: super core::Object::•()
;
[@vm.procedure-attributes.metadata=getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:13,getterSelectorId:14] method call([dynamic a1 = #C1, dynamic a2 = #C1, dynamic a3 = #C1, [@vm.inferred-type.metadata=dart.core::_Smi?] dynamic a4 = #C1, [@vm.inferred-type.metadata=dart.core::_Smi?] dynamic a5 = #C1, [@vm.inferred-type.metadata=#lib::T2?] dynamic a6 = #C1]) → void {
@@ -48,14 +48,14 @@
}
abstract class B2Base extends core::Object {
[@vm.inferred-type.metadata=#lib::A2] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:15,getterSelectorId:16] field dynamic _aa;
- synthetic constructor •() → self::B2Base*
+ synthetic constructor •() → self::B2Base
: self::B2Base::_aa = new self::A2::•(), super core::Object::•()
;
[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:17] get aa2() → dynamic
return [@vm.direct-call.metadata=#lib::B2Base._aa] [@vm.inferred-type.metadata=#lib::A2] this.{self::B2Base::_aa}{dynamic};
}
class B2 extends self::B2Base {
- synthetic constructor •() → self::B2*
+ synthetic constructor •() → self::B2
: super self::B2Base::•()
;
[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:18,getterSelectorId:19] method doSuperCall() → void {
@@ -63,7 +63,7 @@
}
}
class T3 extends core::Object {
- synthetic constructor •() → self::T3*
+ synthetic constructor •() → self::T3
: super core::Object::•()
;
[@vm.procedure-attributes.metadata=getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:20,getterSelectorId:21] method doTest3() → void {
@@ -72,7 +72,7 @@
}
class A3 extends core::Object {
[@vm.inferred-type.metadata=#lib::T3?] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:22,getterSelectorId:23] field dynamic foo = null;
- synthetic constructor •() → self::A3*
+ synthetic constructor •() → self::A3
: super core::Object::•()
;
[@vm.procedure-attributes.metadata=getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:24,getterSelectorId:25] method call([dynamic a1 = #C1, dynamic a2 = #C1, dynamic a3 = #C1, [@vm.inferred-type.metadata=dart.core::_Smi?] dynamic a4 = #C1, [@vm.inferred-type.metadata=dart.core::_Smi?] dynamic a5 = #C1, [@vm.inferred-type.metadata=dart.core::_Smi?] dynamic a6 = #C1, [@vm.inferred-type.metadata=#lib::T3?] dynamic a7 = #C1]) → void {
@@ -80,13 +80,13 @@
}
}
class B3 extends core::Object {
-[@vm.inferred-type.metadata=#lib::A3] [@vm.procedure-attributes.metadata=hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:26,getterSelectorId:27] field self::A3* aa3;
- synthetic constructor •() → self::B3*
+[@vm.inferred-type.metadata=#lib::A3] [@vm.procedure-attributes.metadata=hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:26,getterSelectorId:27] field self::A3 aa3;
+ synthetic constructor •() → self::B3
: self::B3::aa3 = new self::A3::•(), super core::Object::•()
;
}
class T4 extends core::Object {
- synthetic constructor •() → self::T4*
+ synthetic constructor •() → self::T4
: super core::Object::•()
;
[@vm.procedure-attributes.metadata=getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:28,getterSelectorId:29] method doTest4() → void {
@@ -95,7 +95,7 @@
}
class A4 extends core::Object {
[@vm.inferred-type.metadata=#lib::T4?] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:30,getterSelectorId:31] field dynamic foo = null;
- synthetic constructor •() → self::A4*
+ synthetic constructor •() → self::A4
: super core::Object::•()
;
[@vm.procedure-attributes.metadata=getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:32,getterSelectorId:33] method call([dynamic a1 = #C1, dynamic a2 = #C1, dynamic a3 = #C1, [@vm.inferred-type.metadata=dart.core::_Smi?] dynamic a4 = #C1, [@vm.inferred-type.metadata=dart.core::_Smi?] dynamic a5 = #C1, [@vm.inferred-type.metadata=dart.core::_Smi?] dynamic a6 = #C1, [@vm.inferred-type.metadata=dart.core::_Smi?] dynamic a7 = #C1, [@vm.inferred-type.metadata=#lib::T4?] dynamic a8 = #C1]) → void {
@@ -104,27 +104,27 @@
}
class B4 extends core::Object {
[@vm.inferred-type.metadata=#lib::A4] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:34,getterSelectorId:35] field dynamic _aa;
- synthetic constructor •() → self::B4*
+ synthetic constructor •() → self::B4
: self::B4::_aa = new self::A4::•(), super core::Object::•()
;
[@vm.procedure-attributes.metadata=hasThisUses:false,hasTearOffUses:false,getterSelectorId:36] get aa4() → dynamic
return [@vm.direct-call.metadata=#lib::B4._aa] [@vm.inferred-type.metadata=#lib::A4] this.{self::B4::_aa}{dynamic};
}
-[@vm.inferred-type.metadata=dart.core::bool?]static field core::bool* ok;
+[@vm.inferred-type.metadata=dart.core::bool?]static field core::bool? ok;
[@vm.inferred-type.metadata=#lib::B3?]static field dynamic bb3 = new self::B3::•();
-[@vm.inferred-type.metadata=dart.core::_Closure?]static field core::Function* unknown3 = () → dynamic => self::bb3;
+[@vm.inferred-type.metadata=dart.core::_Closure?]static field core::Function unknown3 = () → dynamic => self::bb3;
[@vm.inferred-type.metadata=#lib::B4?]static field dynamic bb4 = new self::B4::•();
-[@vm.inferred-type.metadata=dart.core::_Closure?]static field core::Function* unknown4 = () → dynamic => self::bb4;
+[@vm.inferred-type.metadata=dart.core::_Closure?]static field core::Function unknown4 = () → dynamic => self::bb4;
static method test1() → void {
- self::B1* bb = new self::B1::•();
- let final self::B1* #t1 = bb in let final core::int* #t2 = 1 in let final core::int* #t3 = 2 in let final core::int* #t4 = 3 in let final core::int* #t5 = 4 in let final self::T1* #t6 = new self::T1::•() in [@vm.direct-call.metadata=#lib::A1.call] [@vm.inferred-type.metadata=!? (skip check)] [@vm.direct-call.metadata=#lib::B1.aa1] [@vm.inferred-type.metadata=#lib::A1] #t1.{self::B1::aa1}{self::A1*}.{self::A1::call}(#t2, #t3, #t4, #t5, #t6){([dynamic, dynamic, dynamic, dynamic, dynamic]) →* void};
+ self::B1 bb = new self::B1::•();
+ let final self::B1 #t1 = bb in let final core::int #t2 = 1 in let final core::int #t3 = 2 in let final core::int #t4 = 3 in let final core::int #t5 = 4 in let final self::T1 #t6 = new self::T1::•() in [@vm.direct-call.metadata=#lib::A1.call] [@vm.inferred-type.metadata=!? (skip check)] [@vm.direct-call.metadata=#lib::B1.aa1] [@vm.inferred-type.metadata=#lib::A1] #t1.{self::B1::aa1}{self::A1}.{self::A1::call}(#t2, #t3, #t4, #t5, #t6){([dynamic, dynamic, dynamic, dynamic, dynamic]) → void};
self::ok = false;
- [@vm.direct-call.metadata=#lib::T1.doTest1??] [@vm.inferred-type.metadata=!? (skip check)] [@vm.direct-call.metadata=#lib::A1.foo] [@vm.inferred-type.metadata=#lib::T1?] [@vm.direct-call.metadata=#lib::B1.aa1] [@vm.inferred-type.metadata=#lib::A1] bb.{self::B1::aa1}{self::A1*}.{self::A1::foo}{self::T1*}.{self::T1::doTest1}(){() →* void};
+ [@vm.direct-call.metadata=#lib::T1.doTest1] [@vm.inferred-type.metadata=!? (skip check)] [@vm.direct-call.metadata=#lib::A1.foo] [@vm.inferred-type.metadata=#lib::T1?] [@vm.direct-call.metadata=#lib::B1.aa1] [@vm.inferred-type.metadata=#lib::A1] bb.{self::B1::aa1}{self::A1}.{self::A1::foo}{self::T1?}!.{self::T1::doTest1}(){() → void};
exp::Expect::isTrue([@vm.inferred-type.metadata=dart.core::bool?] self::ok);
}
static method test2() → void {
- self::B2* bb = new self::B2::•();
- [@vm.direct-call.metadata=#lib::B2.doSuperCall] [@vm.inferred-type.metadata=!? (skip check)] bb.{self::B2::doSuperCall}(){() →* void};
+ self::B2 bb = new self::B2::•();
+ [@vm.direct-call.metadata=#lib::B2.doSuperCall] [@vm.inferred-type.metadata=!? (skip check)] bb.{self::B2::doSuperCall}(){() → void};
self::ok = false;
[@vm.direct-call.metadata=#lib::T2.doTest2??] [@vm.inferred-type.metadata=!? (receiver not int)] [@vm.direct-call.metadata=#lib::A2.foo] [@vm.inferred-type.metadata=#lib::T2? (receiver not int)] [@vm.direct-call.metadata=#lib::B2Base.aa2] [@vm.inferred-type.metadata=#lib::A2] bb.{self::B2Base::aa2}{dynamic}{dynamic}.foo{dynamic}.doTest2();
exp::Expect::isTrue([@vm.inferred-type.metadata=dart.core::bool?] self::ok);
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/tear_off_dynamic_method.dart b/pkg/vm/testcases/transformations/type_flow/transformer/tear_off_dynamic_method.dart
index 717504a..e29f9dd 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/tear_off_dynamic_method.dart
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/tear_off_dynamic_method.dart
@@ -2,8 +2,6 @@
// for 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.9
-
A aa = new B();
dynamic knownResult() => new B();
@@ -13,11 +11,11 @@
}
class B extends A {
- int foo() => 1 + knownResult().foo(); // Should have metadata.
+ int foo() => 1 + knownResult().foo() as int; // Should have metadata.
}
class C implements A {
- int foo() => 2 + knownResult().foo(); // Should be unreachable.
+ int foo() => 2 + knownResult().foo() as int; // Should be unreachable.
}
class TearOffDynamicMethod {
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/tear_off_dynamic_method.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/tear_off_dynamic_method.dart.expect
index 3483f2c..582555f 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/tear_off_dynamic_method.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/tear_off_dynamic_method.dart.expect
@@ -1,29 +1,29 @@
-library #lib;
+library #lib /*isNonNullableByDefault*/;
import self as self;
import "dart:core" as core;
abstract class A extends core::Object {
- synthetic constructor •() → self::A*
+ synthetic constructor •() → self::A
: super core::Object::•()
;
}
class B extends self::A {
- synthetic constructor •() → self::B*
+ synthetic constructor •() → self::B
: super self::A::•()
;
-[@vm.procedure-attributes.metadata=hasThisUses:false,methodOrSetterSelectorId:1,getterSelectorId:2] [@vm.unboxing-info.metadata=()->i] method foo() → core::int*
- return [@vm.direct-call.metadata=dart.core::_IntegerImplementation.+] [@vm.inferred-type.metadata=! (skip check)] 1.{core::num::+}([@vm.direct-call.metadata=#lib::B.foo] [@vm.inferred-type.metadata=!? (receiver not int)] [@vm.inferred-type.metadata=#lib::B] self::knownResult(){dynamic}.foo() as{TypeError,ForDynamic} core::num*){(core::num*) →* core::num*} as{TypeError} core::int*;
+[@vm.procedure-attributes.metadata=hasThisUses:false,methodOrSetterSelectorId:1,getterSelectorId:2] [@vm.unboxing-info.metadata=()->i] method foo() → core::int
+ return [@vm.direct-call.metadata=dart.core::_IntegerImplementation.+] [@vm.inferred-type.metadata=! (skip check)] 1.{core::num::+}([@vm.direct-call.metadata=#lib::B.foo] [@vm.inferred-type.metadata=!? (receiver not int)] [@vm.inferred-type.metadata=#lib::B] self::knownResult(){dynamic}.foo() as{TypeError,ForDynamic,ForNonNullableByDefault} core::num){(core::num) → core::num} as{ForNonNullableByDefault} core::int;
}
class TearOffDynamicMethod extends core::Object {
[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:3,getterSelectorId:4] field dynamic bazz;
- constructor •(dynamic arg) → self::TearOffDynamicMethod*
+ constructor •(dynamic arg) → self::TearOffDynamicMethod
: self::TearOffDynamicMethod::bazz = arg{dynamic}.foo, super core::Object::•() {
[@vm.direct-call.metadata=#lib::TearOffDynamicMethod.bazz] this.{self::TearOffDynamicMethod::bazz}{dynamic}{dynamic}.call();
}
}
static method knownResult() → dynamic
return new self::B::•();
-static method main(core::List<core::String*>* args) → dynamic {
- core::Function* closure = () → self::B* => new self::B::•();
+static method main(core::List<core::String> args) → dynamic {
+ core::Function closure = () → self::B => new self::B::•();
new self::TearOffDynamicMethod::•(closure());
}
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/tear_off_interface_method.dart b/pkg/vm/testcases/transformations/type_flow/transformer/tear_off_interface_method.dart
index 74cf279..603bbf6 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/tear_off_interface_method.dart
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/tear_off_interface_method.dart
@@ -2,8 +2,6 @@
// for 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.9
-
A aa = new B();
dynamic knownResult() => new B();
@@ -13,12 +11,12 @@
}
class B extends A {
- int foo() => 1 + knownResult().bar(); // Should have metadata.
+ int foo() => 1 + knownResult().bar() as int; // Should have metadata.
int bar() => 3;
}
class C implements A {
- int foo() => 2 + knownResult().bar(); // Should be unreachable.
+ int foo() => 2 + knownResult().bar() as int; // Should be unreachable.
}
class TearOffInterfaceMethod {
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/tear_off_interface_method.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/tear_off_interface_method.dart.expect
index 578e8fb..b34fce5 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/tear_off_interface_method.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/tear_off_interface_method.dart.expect
@@ -1,31 +1,31 @@
-library #lib;
+library #lib /*isNonNullableByDefault*/;
import self as self;
import "dart:core" as core;
import "dart:_internal" as _in;
abstract class A extends core::Object {
- synthetic constructor •() → self::A*
+ synthetic constructor •() → self::A
: super core::Object::•()
;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2] [@vm.unboxing-info.metadata=()->i] abstract method foo() → core::int*;
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2] [@vm.unboxing-info.metadata=()->i] abstract method foo() → core::int;
}
class B extends self::A {
- synthetic constructor •() → self::B*
+ synthetic constructor •() → self::B
: super self::A::•()
;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,methodOrSetterSelectorId:1,getterSelectorId:2] [@vm.unboxing-info.metadata=()->i] method foo() → core::int*
- return _in::unsafeCast<core::int*>([@vm.direct-call.metadata=dart.core::_IntegerImplementation.+] [@vm.inferred-type.metadata=int (skip check)] 1.{core::num::+}(_in::unsafeCast<core::num*>([@vm.direct-call.metadata=#lib::B.bar] [@vm.inferred-type.metadata=dart.core::_Smi (value: 3) (receiver not int)] [@vm.inferred-type.metadata=#lib::B] self::knownResult(){dynamic}.bar())){(core::num*) →* core::num*});
-[@vm.procedure-attributes.metadata=getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:3,getterSelectorId:4] [@vm.unboxing-info.metadata=()->i] method bar() → core::int*
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,methodOrSetterSelectorId:1,getterSelectorId:2] [@vm.unboxing-info.metadata=()->i] method foo() → core::int
+ return _in::unsafeCast<core::int>([@vm.direct-call.metadata=dart.core::_IntegerImplementation.+] [@vm.inferred-type.metadata=int (skip check)] 1.{core::num::+}(_in::unsafeCast<core::num>([@vm.direct-call.metadata=#lib::B.bar] [@vm.inferred-type.metadata=dart.core::_Smi (value: 3) (receiver not int)] [@vm.inferred-type.metadata=#lib::B] self::knownResult(){dynamic}.bar())){(core::num) → core::num});
+[@vm.procedure-attributes.metadata=getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:3,getterSelectorId:4] [@vm.unboxing-info.metadata=()->i] method bar() → core::int
return 3;
}
class TearOffInterfaceMethod extends core::Object {
[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:5,getterSelectorId:6] field dynamic bazz;
- constructor •([@vm.inferred-type.metadata=#lib::B] self::A* arg) → self::TearOffInterfaceMethod*
- : self::TearOffInterfaceMethod::bazz = arg.{self::A::foo}{() →* core::int*}, super core::Object::•()
+ constructor •([@vm.inferred-type.metadata=#lib::B] self::A arg) → self::TearOffInterfaceMethod
+ : self::TearOffInterfaceMethod::bazz = arg.{self::A::foo}{() → core::int}, super core::Object::•()
;
}
static method knownResult() → dynamic
return new self::B::•();
-static method main(core::List<core::String*>* args) → dynamic {
+static method main(core::List<core::String> args) → dynamic {
[@vm.direct-call.metadata=#lib::TearOffInterfaceMethod.bazz] new self::TearOffInterfaceMethod::•(new self::B::•()).{self::TearOffInterfaceMethod::bazz}{dynamic}{dynamic}.call();
}
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/tear_off_super_method.dart b/pkg/vm/testcases/transformations/type_flow/transformer/tear_off_super_method.dart
index a63ec2a..2980835 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/tear_off_super_method.dart
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/tear_off_super_method.dart
@@ -2,8 +2,6 @@
// for 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.9
-
A aa = new B();
dynamic knownResult() => new B();
@@ -13,26 +11,26 @@
}
class B extends A {
- int foo() => 1 + knownResult().foo(); // Should have metadata.
+ int foo() => 1 + knownResult().foo() as int; // Should have metadata.
}
class C implements A {
- int foo() => 2 + knownResult().foo(); // Should be unreachable.
+ int foo() => 2 + knownResult().foo() as int; // Should be unreachable.
}
class Base {
- int foo() => 3 + knownResult().foo(); // Should have metadata.
- int doCall(x) => x();
+ int foo() => 3 + knownResult().foo() as int; // Should have metadata.
+ int? doCall(x) => x();
}
class TearOffSuperMethod extends Base {
int foo() {
// Should be unreachable.
aa = new C();
- return 4 + knownResult().foo();
+ return 4 + knownResult().foo() as int;
}
- int bar() => doCall(super.foo);
+ int? bar() => doCall(super.foo);
}
main(List<String> args) {
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/tear_off_super_method.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/tear_off_super_method.dart.expect
index bc69294..0e44dd5 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/tear_off_super_method.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/tear_off_super_method.dart.expect
@@ -1,41 +1,41 @@
-library #lib;
+library #lib /*isNonNullableByDefault*/;
import self as self;
import "dart:core" as core;
import "dart:_internal" as _in;
abstract class A extends core::Object {
- synthetic constructor •() → self::A*
+ synthetic constructor •() → self::A
: super core::Object::•()
;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2] [@vm.unboxing-info.metadata=()->i] abstract method foo() → core::int*;
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2] [@vm.unboxing-info.metadata=()->i] abstract method foo() → core::int;
}
class B extends self::A {
- synthetic constructor •() → self::B*
+ synthetic constructor •() → self::B
: super self::A::•()
;
-[@vm.procedure-attributes.metadata=getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2] [@vm.unboxing-info.metadata=()->i] method foo() → core::int*
- return _in::unsafeCast<core::int*>([@vm.direct-call.metadata=dart.core::_IntegerImplementation.+] [@vm.inferred-type.metadata=int (skip check)] 1.{core::num::+}(_in::unsafeCast<core::num*>([@vm.direct-call.metadata=#lib::B.foo] [@vm.inferred-type.metadata=int? (receiver not int)] [@vm.inferred-type.metadata=#lib::B] self::knownResult(){dynamic}.foo())){(core::num*) →* core::num*});
+[@vm.procedure-attributes.metadata=getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2] [@vm.unboxing-info.metadata=()->i] method foo() → core::int
+ return _in::unsafeCast<core::int>([@vm.direct-call.metadata=dart.core::_IntegerImplementation.+] [@vm.inferred-type.metadata=int (skip check)] 1.{core::num::+}(_in::unsafeCast<core::num>([@vm.direct-call.metadata=#lib::B.foo] [@vm.inferred-type.metadata=int? (receiver not int)] [@vm.inferred-type.metadata=#lib::B] self::knownResult(){dynamic}.foo())){(core::num) → core::num});
}
abstract class Base extends core::Object {
- synthetic constructor •() → self::Base*
+ synthetic constructor •() → self::Base
: super core::Object::•()
;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,methodOrSetterSelectorId:3,getterSelectorId:4] [@vm.unboxing-info.metadata=()->i] method foo() → core::int*
- return _in::unsafeCast<core::int*>([@vm.direct-call.metadata=dart.core::_IntegerImplementation.+] [@vm.inferred-type.metadata=int (skip check)] 3.{core::num::+}(_in::unsafeCast<core::num*>([@vm.direct-call.metadata=#lib::B.foo] [@vm.inferred-type.metadata=int? (receiver not int)] [@vm.inferred-type.metadata=#lib::B] self::knownResult(){dynamic}.foo())){(core::num*) →* core::num*});
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:5,getterSelectorId:6] method doCall(dynamic x) → core::int*
- return x{dynamic}.call() as{TypeError,ForDynamic} core::int*;
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,methodOrSetterSelectorId:3,getterSelectorId:4] [@vm.unboxing-info.metadata=()->i] method foo() → core::int
+ return _in::unsafeCast<core::int>([@vm.direct-call.metadata=dart.core::_IntegerImplementation.+] [@vm.inferred-type.metadata=int (skip check)] 3.{core::num::+}(_in::unsafeCast<core::num>([@vm.direct-call.metadata=#lib::B.foo] [@vm.inferred-type.metadata=int? (receiver not int)] [@vm.inferred-type.metadata=#lib::B] self::knownResult(){dynamic}.foo())){(core::num) → core::num});
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:5,getterSelectorId:6] method doCall(dynamic x) → core::int?
+ return x{dynamic}.call() as{TypeError,ForDynamic,ForNonNullableByDefault} core::int?;
}
class TearOffSuperMethod extends self::Base {
- synthetic constructor •() → self::TearOffSuperMethod*
+ synthetic constructor •() → self::TearOffSuperMethod
: super self::Base::•()
;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:7,getterSelectorId:8] method bar() → core::int*
- return [@vm.direct-call.metadata=#lib::Base.doCall] [@vm.inferred-type.metadata=int? (skip check)] this.{self::Base::doCall}(super.{self::Base::foo}){(dynamic) →* core::int*};
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:7,getterSelectorId:8] method bar() → core::int?
+ return [@vm.direct-call.metadata=#lib::Base.doCall] [@vm.inferred-type.metadata=int? (skip check)] this.{self::Base::doCall}(super.{self::Base::foo}){(dynamic) → core::int?};
}
-[@vm.inferred-type.metadata=#lib::B?]static field self::A* aa = new self::B::•();
+[@vm.inferred-type.metadata=#lib::B?]static field self::A aa = new self::B::•();
static method knownResult() → dynamic
return new self::B::•();
-static method main(core::List<core::String*>* args) → dynamic {
- [@vm.direct-call.metadata=#lib::TearOffSuperMethod.bar] [@vm.inferred-type.metadata=!? (skip check)] new self::TearOffSuperMethod::•().{self::TearOffSuperMethod::bar}(){() →* core::int*};
- [@vm.direct-call.metadata=#lib::B.foo??] [@vm.inferred-type.metadata=!? (skip check)] [@vm.inferred-type.metadata=#lib::B?] self::aa.{self::A::foo}(){() →* core::int*};
+static method main(core::List<core::String> args) → dynamic {
+ [@vm.direct-call.metadata=#lib::TearOffSuperMethod.bar] [@vm.inferred-type.metadata=!? (skip check)] new self::TearOffSuperMethod::•().{self::TearOffSuperMethod::bar}(){() → core::int?};
+ [@vm.direct-call.metadata=#lib::B.foo??] [@vm.inferred-type.metadata=!? (skip check)] [@vm.inferred-type.metadata=#lib::B?] self::aa.{self::A::foo}(){() → core::int};
}
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/type_cast_elimination_nnbd.dart b/pkg/vm/testcases/transformations/type_flow/transformer/type_cast_elimination_nnbd.dart
index 5f0e8e8..e3a95bd 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/type_cast_elimination_nnbd.dart
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/type_cast_elimination_nnbd.dart
@@ -3,9 +3,6 @@
// BSD-style license that can be found in the LICENSE file.
// Tests elimination of type casts.
-// This test requires non-nullable experiment.
-
-// @dart = 2.10
class A<T> {}
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/type_cast_elimination_nnbd_strong.dart b/pkg/vm/testcases/transformations/type_flow/transformer/type_cast_elimination_nnbd_strong.dart
index c828095..337a57a 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/type_cast_elimination_nnbd_strong.dart
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/type_cast_elimination_nnbd_strong.dart
@@ -3,9 +3,7 @@
// BSD-style license that can be found in the LICENSE file.
// Tests elimination of type casts.
-// This test requires non-nullable experiment and NNBD strong mode.
-
-// @dart = 2.10
+// This test requires sound null safety.
class A<T> {}
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/unboxed_getters.dart b/pkg/vm/testcases/transformations/type_flow/transformer/unboxed_getters.dart
index 65a5a2d..81af9f4 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/unboxed_getters.dart
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/unboxed_getters.dart
@@ -2,8 +2,6 @@
// for 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.9
-
final bool kTrue = int.parse('1') == 1 ? true : false;
final bool kFalse = int.parse('1') == 2 ? true : false;
int get mint => 0xaabbccddaabbccdd;
@@ -15,58 +13,58 @@
}
abstract class BI1 {
- int get value;
+ int? get value;
}
class BI1A implements BI1 {
- final int value;
+ final int? value;
BI1A(this.value);
}
class BI1B implements BI1 {
- int get value => null;
+ int? get value => null;
}
abstract class BI2 {
- int get value;
+ int? get value;
}
class BI2A implements BI2 {
- final int value;
+ final int? value;
BI2A(this.value);
}
class BI2B implements BI2 {
- int get value => smiOrMint;
+ int? get value => smiOrMint;
}
abstract class BI3 {
- int get value;
- set value(int value);
+ int? get value;
+ set value(int? value);
}
class BI3A implements BI3 {
- int value;
+ int? value;
BI3A(this.value);
}
class BI3B implements BI3 {
- int get value => smiOrMint;
- set value(int v) {}
+ int? get value => smiOrMint;
+ set value(int? v) {}
}
abstract class UBI {
- int value;
+ int? value;
}
class UBIA implements UBI {
- int value;
+ int? value;
UBIA(this.value);
}
class UBIB implements UBI {
- int get value => smiOrMint;
- set value(int v) {}
+ int? get value => smiOrMint;
+ set value(int? v) {}
}
main() {
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/unboxed_getters.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/unboxed_getters.dart.expect
index 542466c..de01101 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/unboxed_getters.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/unboxed_getters.dart.expect
@@ -1,96 +1,96 @@
-library #lib;
+library #lib /*isNonNullableByDefault*/;
import self as self;
import "dart:core" as core;
abstract class BI1 extends core::Object {
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:1] abstract get value() → core::int*;
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:1] abstract get value() → core::int?;
}
class BI1A extends core::Object implements self::BI1 {
-[@vm.inferred-type.metadata=int] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:1] final field core::int* value;
-[@vm.unboxing-info.metadata=(i)->b] constructor •([@vm.inferred-type.metadata=int] core::int* value) → self::BI1A*
+[@vm.inferred-type.metadata=int] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:1] final field core::int? value;
+[@vm.unboxing-info.metadata=(i)->b] constructor •([@vm.inferred-type.metadata=int] core::int? value) → self::BI1A
: self::BI1A::value = value, super core::Object::•()
;
}
class BI1B extends core::Object implements self::BI1 {
- synthetic constructor •() → self::BI1B*
+ synthetic constructor •() → self::BI1B
: super core::Object::•()
;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:1] get value() → core::int*
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:1] get value() → core::int?
return null;
}
abstract class BI2 extends core::Object {
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:2] abstract get value() → core::int*;
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:2] abstract get value() → core::int?;
}
class BI2A extends core::Object implements self::BI2 {
-[@vm.inferred-type.metadata=dart.core::Null? (value: null)] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:2] final field core::int* value;
- constructor •() → self::BI2A*
+[@vm.inferred-type.metadata=dart.core::Null? (value: null)] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:2] final field core::int? value;
+ constructor •() → self::BI2A
: self::BI2A::value = #C1, super core::Object::•()
;
}
class BI2B extends core::Object implements self::BI2 {
- synthetic constructor •() → self::BI2B*
+ synthetic constructor •() → self::BI2B
: super core::Object::•()
;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:2] get value() → core::int*
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:2] get value() → core::int?
return [@vm.inferred-type.metadata=int] self::smiOrMint;
}
abstract class BI3 extends core::Object {
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:3,getterSelectorId:4] abstract get value() → core::int*;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:3,getterSelectorId:4] abstract set value(core::int* value) → void;
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:3,getterSelectorId:4] abstract get value() → core::int?;
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:3,getterSelectorId:4] abstract set value(core::int? value) → void;
}
class BI3A extends core::Object implements self::BI3 {
-[@vm.inferred-type.metadata=int?] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:3,getterSelectorId:4] field core::int* value;
-[@vm.unboxing-info.metadata=(i)->b] constructor •([@vm.inferred-type.metadata=int] core::int* value) → self::BI3A*
+[@vm.inferred-type.metadata=int?] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:3,getterSelectorId:4] field core::int? value;
+[@vm.unboxing-info.metadata=(i)->b] constructor •([@vm.inferred-type.metadata=int] core::int? value) → self::BI3A
: self::BI3A::value = value, super core::Object::•()
;
}
class BI3B extends core::Object implements self::BI3 {
- synthetic constructor •() → self::BI3B*
+ synthetic constructor •() → self::BI3B
: super core::Object::•()
;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:3,getterSelectorId:4] get value() → core::int*
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:3,getterSelectorId:4] get value() → core::int?
return [@vm.inferred-type.metadata=int] self::smiOrMint;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:3,getterSelectorId:4] set value([@vm.inferred-type.metadata=dart.core::Null? (value: null)] core::int* v) → void {}
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:3,getterSelectorId:4] set value([@vm.inferred-type.metadata=dart.core::Null? (value: null)] core::int? v) → void {}
}
abstract class UBI extends core::Object {
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:5] [@vm.unboxing-info.metadata=()->i] abstract get value() → core::int*;
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:5] [@vm.unboxing-info.metadata=()->i] abstract get /*isLegacy*/ value() → core::int?;
}
class UBIA extends core::Object implements self::UBI {
-[@vm.inferred-type.metadata=int] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:6,getterSelectorId:5] [@vm.unboxing-info.metadata=(i)->i] field core::int* value;
-[@vm.unboxing-info.metadata=(i)->b] constructor •([@vm.inferred-type.metadata=int] core::int* value) → self::UBIA*
+[@vm.inferred-type.metadata=int] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:6,getterSelectorId:5] [@vm.unboxing-info.metadata=(i)->i] field core::int? value;
+[@vm.unboxing-info.metadata=(i)->b] constructor •([@vm.inferred-type.metadata=int] core::int? value) → self::UBIA
: self::UBIA::value = value, super core::Object::•()
;
}
class UBIB extends core::Object implements self::UBI {
- synthetic constructor •() → self::UBIB*
+ synthetic constructor •() → self::UBIB
: super core::Object::•()
;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:5] [@vm.unboxing-info.metadata=()->i] get value() → core::int*
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:5] [@vm.unboxing-info.metadata=()->i] get value() → core::int?
return [@vm.inferred-type.metadata=int] self::smiOrMint;
}
-[@vm.inferred-type.metadata=dart.core::bool?]static final field core::bool* kTrue = [@vm.inferred-type.metadata=dart.core::bool] [@vm.inferred-type.metadata=int?] core::int::parse("1") =={core::num::==}{(core::Object*) →* core::bool*} 1 ?{core::bool*} true : false;
+[@vm.inferred-type.metadata=dart.core::bool?]static final field core::bool kTrue = [@vm.inferred-type.metadata=dart.core::bool] [@vm.inferred-type.metadata=int?] core::int::parse("1") =={core::num::==}{(core::Object) → core::bool} 1 ?{core::bool} true : false;
[@vm.inferred-type.metadata=int?]static field dynamic usedObject;
-[@vm.unboxing-info.metadata=()->i]static get mint() → core::int*
+[@vm.unboxing-info.metadata=()->i]static get mint() → core::int
return -6144092014192636707;
-[@vm.unboxing-info.metadata=()->i]static get smiOrMint() → core::int*
- return [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::int*} 1 : [@vm.inferred-type.metadata=int] self::mint;
+[@vm.unboxing-info.metadata=()->i]static get smiOrMint() → core::int
+ return [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::int} 1 : [@vm.inferred-type.metadata=int] self::mint;
static method use([@vm.inferred-type.metadata=int?] dynamic object) → void {
[@vm.inferred-type.metadata=int?] self::usedObject == null ?{dynamic} self::usedObject = object : null;
}
static method main() → dynamic {
- final self::BI1A* bi1a = new self::BI1A::•([@vm.inferred-type.metadata=int] self::smiOrMint);
- final self::BI1B* bi1b = new self::BI1B::•();
- self::use([@vm.inferred-type.metadata=int?]([@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{self::BI1*} bi1a : bi1b).{self::BI1::value}{core::int*});
- final self::BI2A* bi2a = new self::BI2A::•();
- final self::BI2B* bi2b = new self::BI2B::•();
- self::use([@vm.inferred-type.metadata=int?]([@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{self::BI2*} bi2a : bi2b).{self::BI2::value}{core::int*});
- final self::BI3A* bi3a = new self::BI3A::•([@vm.inferred-type.metadata=int] self::smiOrMint);
- final self::BI3B* bi3b = new self::BI3B::•();
- ([@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{self::BI3*} bi3a : bi3b).{self::BI3::value} = null;
- self::use([@vm.inferred-type.metadata=int?]([@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{self::BI3*} bi3a : bi3b).{self::BI3::value}{core::int*});
- final self::UBIA* ubia = new self::UBIA::•([@vm.inferred-type.metadata=int] self::smiOrMint);
- final self::UBIB* ubib = new self::UBIB::•();
- self::use([@vm.inferred-type.metadata=int]([@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{self::UBI*} ubia : ubib).{self::UBI::value}{core::int*});
+ final self::BI1A bi1a = new self::BI1A::•([@vm.inferred-type.metadata=int] self::smiOrMint);
+ final self::BI1B bi1b = new self::BI1B::•();
+ self::use([@vm.inferred-type.metadata=int?]([@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{self::BI1} bi1a : bi1b).{self::BI1::value}{core::int?});
+ final self::BI2A bi2a = new self::BI2A::•();
+ final self::BI2B bi2b = new self::BI2B::•();
+ self::use([@vm.inferred-type.metadata=int?]([@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{self::BI2} bi2a : bi2b).{self::BI2::value}{core::int?});
+ final self::BI3A bi3a = new self::BI3A::•([@vm.inferred-type.metadata=int] self::smiOrMint);
+ final self::BI3B bi3b = new self::BI3B::•();
+ ([@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{self::BI3} bi3a : bi3b).{self::BI3::value} = null;
+ self::use([@vm.inferred-type.metadata=int?]([@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{self::BI3} bi3a : bi3b).{self::BI3::value}{core::int?});
+ final self::UBIA ubia = new self::UBIA::•([@vm.inferred-type.metadata=int] self::smiOrMint);
+ final self::UBIB ubib = new self::UBIB::•();
+ self::use([@vm.inferred-type.metadata=int]([@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{self::UBI} ubia : ubib).{self::UBI::value}{core::int?});
}
constants {
#C1 = null
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/unboxed_instance_method.dart b/pkg/vm/testcases/transformations/type_flow/transformer/unboxed_instance_method.dart
index 63321f0..f367c3e 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/unboxed_instance_method.dart
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/unboxed_instance_method.dart
@@ -2,8 +2,6 @@
// for 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.9
-
final bool kTrue = int.parse('1') == 1 ? true : false;
final bool kFalse = int.parse('1') == 2 ? true : false;
int get mint => 0xaabbccddaabbccdd;
@@ -18,7 +16,7 @@
abstract class Interface {
void takePositional(
- int unboxedSmi,
+ int? unboxedSmi,
dynamic unboxedInt,
dynamic unboxedDouble,
dynamic boxedNullableInt,
@@ -28,20 +26,20 @@
dynamic boxedNullableX,
dynamic boxedX);
- dynamic returnUnboxedSmi(X ignored);
- dynamic returnUnboxedInt(X ignored);
- dynamic returnUnboxedDouble(X ignored);
- dynamic returnBoxedNullableInt(X ignored);
- dynamic returnBoxedNullableDouble(X ignored);
- dynamic returnBoxedIntOrDouble(X ignored);
- dynamic returnBoxedNullableIntOrDouble(X ignored);
- dynamic returnBoxedNullableX(X ignored);
- dynamic returnBoxedX(X ignored);
+ dynamic returnUnboxedSmi(X? ignored);
+ dynamic returnUnboxedInt(X? ignored);
+ dynamic returnUnboxedDouble(X? ignored);
+ dynamic returnBoxedNullableInt(X? ignored);
+ dynamic returnBoxedNullableDouble(X? ignored);
+ dynamic returnBoxedIntOrDouble(X? ignored);
+ dynamic returnBoxedNullableIntOrDouble(X? ignored);
+ dynamic returnBoxedNullableX(X? ignored);
+ dynamic returnBoxedX(X? ignored);
}
class Impl1 implements Interface {
void takePositional(
- int unboxedSmi,
+ int? unboxedSmi,
dynamic unboxedInt,
dynamic unboxedDouble,
dynamic boxedNullableInt,
@@ -60,20 +58,20 @@
use(boxedX);
}
- dynamic returnUnboxedSmi(X ignored) => 1;
- dynamic returnUnboxedInt(X ignored) => 1;
- dynamic returnUnboxedDouble(X ignored) => 1.1;
- dynamic returnBoxedNullableInt(X ignored) => null;
- dynamic returnBoxedNullableDouble(X ignored) => null;
- dynamic returnBoxedIntOrDouble(X ignored) => 1;
- dynamic returnBoxedNullableIntOrDouble(X ignored) => null;
- dynamic returnBoxedNullableX(X ignored) => null;
- dynamic returnBoxedX(X ignored) => X();
+ dynamic returnUnboxedSmi(X? ignored) => 1;
+ dynamic returnUnboxedInt(X? ignored) => 1;
+ dynamic returnUnboxedDouble(X? ignored) => 1.1;
+ dynamic returnBoxedNullableInt(X? ignored) => null;
+ dynamic returnBoxedNullableDouble(X? ignored) => null;
+ dynamic returnBoxedIntOrDouble(X? ignored) => 1;
+ dynamic returnBoxedNullableIntOrDouble(X? ignored) => null;
+ dynamic returnBoxedNullableX(X? ignored) => null;
+ dynamic returnBoxedX(X? ignored) => X();
}
class BaseImpl2 {
void takePositional(
- int unboxedSmi,
+ int? unboxedSmi,
dynamic unboxedInt,
dynamic unboxedDouble,
dynamic boxedNullableInt,
@@ -92,20 +90,20 @@
use(boxedX);
}
- dynamic returnUnboxedSmi(X ignored) => 2;
- dynamic returnUnboxedInt(X ignored) => mint;
- dynamic returnUnboxedDouble(X ignored) => 2.2;
- dynamic returnBoxedNullableInt(X ignored) => 2;
- dynamic returnBoxedNullableDouble(X ignored) => 2.2;
- dynamic returnBoxedIntOrDouble(X ignored) => 2.2;
- dynamic returnBoxedNullableIntOrDouble(X ignored) => 2;
- dynamic returnBoxedNullableX(X ignored) => X();
- dynamic returnBoxedX(X ignored) => X();
+ dynamic returnUnboxedSmi(X? ignored) => 2;
+ dynamic returnUnboxedInt(X? ignored) => mint;
+ dynamic returnUnboxedDouble(X? ignored) => 2.2;
+ dynamic returnBoxedNullableInt(X? ignored) => 2;
+ dynamic returnBoxedNullableDouble(X? ignored) => 2.2;
+ dynamic returnBoxedIntOrDouble(X? ignored) => 2.2;
+ dynamic returnBoxedNullableIntOrDouble(X? ignored) => 2;
+ dynamic returnBoxedNullableX(X? ignored) => X();
+ dynamic returnBoxedX(X? ignored) => X();
}
class SubImpl3 extends BaseImpl2 implements Interface {
void takePositional(
- int unboxedSmi,
+ int? unboxedSmi,
dynamic unboxedInt,
dynamic unboxedDouble,
dynamic boxedNullableInt,
@@ -124,15 +122,15 @@
use(boxedX);
}
- dynamic returnUnboxedSmi(X ignored) => 3;
- dynamic returnUnboxedInt(X ignored) => mint;
- dynamic returnUnboxedDouble(X ignored) => 3.3;
- dynamic returnBoxedNullableInt(X ignored) => mint;
- dynamic returnBoxedNullableDouble(X ignored) => 3.3;
- dynamic returnBoxedIntOrDouble(X ignored) => 3.3;
- dynamic returnBoxedNullableIntOrDouble(X ignored) => 3.3;
- dynamic returnBoxedNullableX(X ignored) => X();
- dynamic returnBoxedX(X ignored) => X();
+ dynamic returnUnboxedSmi(X? ignored) => 3;
+ dynamic returnUnboxedInt(X? ignored) => mint;
+ dynamic returnUnboxedDouble(X? ignored) => 3.3;
+ dynamic returnBoxedNullableInt(X? ignored) => mint;
+ dynamic returnBoxedNullableDouble(X? ignored) => 3.3;
+ dynamic returnBoxedIntOrDouble(X? ignored) => 3.3;
+ dynamic returnBoxedNullableIntOrDouble(X? ignored) => 3.3;
+ dynamic returnBoxedNullableX(X? ignored) => X();
+ dynamic returnBoxedX(X? ignored) => X();
}
main() {
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/unboxed_instance_method.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/unboxed_instance_method.dart.expect
index 0811f05..40650ad 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/unboxed_instance_method.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/unboxed_instance_method.dart.expect
@@ -1,9 +1,9 @@
-library #lib;
+library #lib /*isNonNullableByDefault*/;
import self as self;
import "dart:core" as core;
class X extends core::Object {
- synthetic constructor •() → self::X*
+ synthetic constructor •() → self::X
: super core::Object::•()
;
}
@@ -20,7 +20,7 @@
[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:19,getterSelectorId:20] abstract method returnBoxedX() → dynamic;
}
class Impl1 extends core::Object implements self::Interface {
- synthetic constructor •() → self::Impl1*
+ synthetic constructor •() → self::Impl1
: super core::Object::•()
;
[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2] [@vm.unboxing-info.metadata=(i,d,b,b,b,b,b,b)->b] method takePositional([@vm.inferred-type.metadata=int] dynamic unboxedInt, [@vm.inferred-type.metadata=dart.core::_Double] dynamic unboxedDouble, [@vm.inferred-type.metadata=int?] dynamic boxedNullableInt, [@vm.inferred-type.metadata=dart.core::_Double?] dynamic boxedNullableDouble, [@vm.inferred-type.metadata=!] dynamic boxedNonNullableIntOrDouble, [@vm.inferred-type.metadata=dart.core::_Double?] dynamic boxedNullableIntOrDouble, [@vm.inferred-type.metadata=#lib::X?] dynamic boxedNullableX, [@vm.inferred-type.metadata=#lib::X] dynamic boxedX) → void {
@@ -53,7 +53,7 @@
return new self::X::•();
}
class BaseImpl2 extends core::Object {
- synthetic constructor •() → self::BaseImpl2*
+ synthetic constructor •() → self::BaseImpl2
: super core::Object::•()
;
[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2] [@vm.unboxing-info.metadata=(i,d,b,b,b,b,b,b)->b] method takePositional([@vm.inferred-type.metadata=dart.core::_Smi (value: 2)] dynamic unboxedInt, [@vm.inferred-type.metadata=dart.core::_Double (value: 2.2)] dynamic unboxedDouble, [@vm.inferred-type.metadata=dart.core::_Smi (value: 2)] dynamic boxedNullableInt, [@vm.inferred-type.metadata=dart.core::_Double (value: 2.2)] dynamic boxedNullableDouble, [@vm.inferred-type.metadata=dart.core::_Double (value: 2.2)] dynamic boxedNonNullableIntOrDouble, [@vm.inferred-type.metadata=dart.core::_Smi (value: 2)] dynamic boxedNullableIntOrDouble, [@vm.inferred-type.metadata=#lib::X] dynamic boxedNullableX, [@vm.inferred-type.metadata=#lib::X] dynamic boxedX) → void {
@@ -86,7 +86,7 @@
return new self::X::•();
}
class SubImpl3 extends self::BaseImpl2 implements self::Interface {
- synthetic constructor •() → self::SubImpl3*
+ synthetic constructor •() → self::SubImpl3
: super self::BaseImpl2::•()
;
[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2] [@vm.unboxing-info.metadata=(i,d,b,b,b,b,b,b)->b] method takePositional([@vm.inferred-type.metadata=int] dynamic unboxedInt, [@vm.inferred-type.metadata=dart.core::_Double] dynamic unboxedDouble, [@vm.inferred-type.metadata=int] dynamic boxedNullableInt, [@vm.inferred-type.metadata=dart.core::_Double] dynamic boxedNullableDouble, [@vm.inferred-type.metadata=dart.core::_Double] dynamic boxedNonNullableIntOrDouble, [@vm.inferred-type.metadata=!] dynamic boxedNullableIntOrDouble, [@vm.inferred-type.metadata=#lib::X] dynamic boxedNullableX, [@vm.inferred-type.metadata=#lib::X] dynamic boxedX) → void {
@@ -119,55 +119,55 @@
return new self::X::•();
}
static field dynamic usedObject;
-[@vm.unboxing-info.metadata=()->i]static get mint() → core::int*
+[@vm.unboxing-info.metadata=()->i]static get mint() → core::int
return -6144092014192636707;
static method use(dynamic object) → void {
self::usedObject == null ?{dynamic} self::usedObject = object : null;
}
static method main() → dynamic {
- final core::List<core::Object*>* values = [@vm.inferred-type.metadata=dart.core::_GrowableList<dart.core::Object*>] core::_GrowableList::_literal3<core::Object*>(new self::Impl1::•(), new self::BaseImpl2::•(), new self::SubImpl3::•());
- final self::Impl1* a = [@vm.direct-call.metadata=dart.core::_GrowableList.[]] [@vm.inferred-type.metadata=!? (skip check)] values.{core::List::[]}([@vm.inferred-type.metadata=int?] core::int::parse("0")){(core::int*) →* core::Object*} as self::Impl1*;
- final self::BaseImpl2* b = [@vm.direct-call.metadata=dart.core::_GrowableList.[]] [@vm.inferred-type.metadata=!? (skip check)] values.{core::List::[]}([@vm.inferred-type.metadata=int?] core::int::parse("1")){(core::int*) →* core::Object*} as self::BaseImpl2*;
- final self::SubImpl3* c = [@vm.direct-call.metadata=dart.core::_GrowableList.[]] [@vm.inferred-type.metadata=!? (skip check)] values.{core::List::[]}([@vm.inferred-type.metadata=int?] core::int::parse("2")){(core::int*) →* core::Object*} as self::SubImpl3*;
- final self::Interface* d = [@vm.direct-call.metadata=dart.core::_GrowableList.[]] [@vm.inferred-type.metadata=!? (skip check)] values.{core::List::[]}([@vm.inferred-type.metadata=int?] core::int::parse("2")){(core::int*) →* core::Object*} as self::Interface*;
- [@vm.direct-call.metadata=#lib::Impl1.takePositional??] [@vm.inferred-type.metadata=!? (skip check)] a.{self::Impl1::takePositional}(1, 1.1, null, null, 1, null, null, new self::X::•()){(core::int*, dynamic, dynamic, dynamic, dynamic, dynamic, dynamic, dynamic, dynamic) →* void};
- b.{self::BaseImpl2::takePositional}(2, 2.2, 2, 2.2, 2.2, 2, new self::X::•(), new self::X::•()){(core::int*, dynamic, dynamic, dynamic, dynamic, dynamic, dynamic, dynamic, dynamic) →* void};
- [@vm.direct-call.metadata=#lib::SubImpl3.takePositional??] [@vm.inferred-type.metadata=!? (skip check)] c.{self::SubImpl3::takePositional}([@vm.inferred-type.metadata=int] self::mint, 3.3, [@vm.inferred-type.metadata=int] self::mint, 3.3, 3.3, 3.3, new self::X::•(), new self::X::•()){(core::int*, dynamic, dynamic, dynamic, dynamic, dynamic, dynamic, dynamic, dynamic) →* void};
- d.{self::Interface::takePositional}([@vm.inferred-type.metadata=int] self::mint, 3.3, [@vm.inferred-type.metadata=int] self::mint, 3.3, 3.3, 3.3, new self::X::•(), new self::X::•()){(core::int*, dynamic, dynamic, dynamic, dynamic, dynamic, dynamic, dynamic, dynamic) →* void};
- self::use([@vm.direct-call.metadata=#lib::Impl1.returnUnboxedSmi] [@vm.inferred-type.metadata=dart.core::_Smi (skip check) (value: 1)] a.{self::Impl1::returnUnboxedSmi}(){(self::X*) →* dynamic});
- self::use([@vm.direct-call.metadata=#lib::Impl1.returnUnboxedInt] [@vm.inferred-type.metadata=dart.core::_Smi (skip check) (value: 1)] a.{self::Impl1::returnUnboxedInt}(){(self::X*) →* dynamic});
- self::use([@vm.direct-call.metadata=#lib::Impl1.returnUnboxedDouble] [@vm.inferred-type.metadata=dart.core::_Double (skip check) (value: 1.1)] a.{self::Impl1::returnUnboxedDouble}(){(self::X*) →* dynamic});
- self::use([@vm.direct-call.metadata=#lib::Impl1.returnBoxedNullableInt] [@vm.inferred-type.metadata=dart.core::Null? (skip check) (value: null)] a.{self::Impl1::returnBoxedNullableInt}(){(self::X*) →* dynamic});
- self::use([@vm.direct-call.metadata=#lib::Impl1.returnBoxedNullableDouble] [@vm.inferred-type.metadata=dart.core::Null? (skip check) (value: null)] a.{self::Impl1::returnBoxedNullableDouble}(){(self::X*) →* dynamic});
- self::use([@vm.direct-call.metadata=#lib::Impl1.returnBoxedIntOrDouble] [@vm.inferred-type.metadata=dart.core::_Smi (skip check) (value: 1)] a.{self::Impl1::returnBoxedIntOrDouble}(){(self::X*) →* dynamic});
- self::use([@vm.direct-call.metadata=#lib::Impl1.returnBoxedNullableIntOrDouble] [@vm.inferred-type.metadata=dart.core::Null? (skip check) (value: null)] a.{self::Impl1::returnBoxedNullableIntOrDouble}(){(self::X*) →* dynamic});
- self::use([@vm.direct-call.metadata=#lib::Impl1.returnBoxedNullableX] [@vm.inferred-type.metadata=dart.core::Null? (skip check) (value: null)] a.{self::Impl1::returnBoxedNullableX}(){(self::X*) →* dynamic});
- self::use([@vm.direct-call.metadata=#lib::Impl1.returnBoxedX] [@vm.inferred-type.metadata=#lib::X (skip check)] a.{self::Impl1::returnBoxedX}(){(self::X*) →* dynamic});
- self::use([@vm.inferred-type.metadata=dart.core::_Smi] b.{self::BaseImpl2::returnUnboxedSmi}(){(self::X*) →* dynamic});
- self::use([@vm.inferred-type.metadata=int] b.{self::BaseImpl2::returnUnboxedInt}(){(self::X*) →* dynamic});
- self::use([@vm.inferred-type.metadata=dart.core::_Double] b.{self::BaseImpl2::returnUnboxedDouble}(){(self::X*) →* dynamic});
- self::use([@vm.inferred-type.metadata=int] b.{self::BaseImpl2::returnBoxedNullableInt}(){(self::X*) →* dynamic});
- self::use([@vm.inferred-type.metadata=dart.core::_Double] b.{self::BaseImpl2::returnBoxedNullableDouble}(){(self::X*) →* dynamic});
- self::use([@vm.inferred-type.metadata=dart.core::_Double] b.{self::BaseImpl2::returnBoxedIntOrDouble}(){(self::X*) →* dynamic});
- self::use([@vm.inferred-type.metadata=!] b.{self::BaseImpl2::returnBoxedNullableIntOrDouble}(){(self::X*) →* dynamic});
- self::use([@vm.inferred-type.metadata=#lib::X] b.{self::BaseImpl2::returnBoxedNullableX}(){(self::X*) →* dynamic});
- self::use([@vm.inferred-type.metadata=#lib::X] b.{self::BaseImpl2::returnBoxedX}(){(self::X*) →* dynamic});
- self::use([@vm.direct-call.metadata=#lib::SubImpl3.returnUnboxedSmi] [@vm.inferred-type.metadata=dart.core::_Smi (skip check) (value: 3)] c.{self::SubImpl3::returnUnboxedSmi}(){(self::X*) →* dynamic});
- self::use([@vm.direct-call.metadata=#lib::SubImpl3.returnUnboxedInt] [@vm.inferred-type.metadata=int (skip check)] c.{self::SubImpl3::returnUnboxedInt}(){(self::X*) →* dynamic});
- self::use([@vm.direct-call.metadata=#lib::SubImpl3.returnUnboxedDouble] [@vm.inferred-type.metadata=dart.core::_Double (skip check) (value: 3.3)] c.{self::SubImpl3::returnUnboxedDouble}(){(self::X*) →* dynamic});
- self::use([@vm.direct-call.metadata=#lib::SubImpl3.returnBoxedNullableInt] [@vm.inferred-type.metadata=int (skip check)] c.{self::SubImpl3::returnBoxedNullableInt}(){(self::X*) →* dynamic});
- self::use([@vm.direct-call.metadata=#lib::SubImpl3.returnBoxedNullableDouble] [@vm.inferred-type.metadata=dart.core::_Double (skip check) (value: 3.3)] c.{self::SubImpl3::returnBoxedNullableDouble}(){(self::X*) →* dynamic});
- self::use([@vm.direct-call.metadata=#lib::SubImpl3.returnBoxedIntOrDouble] [@vm.inferred-type.metadata=dart.core::_Double (skip check) (value: 3.3)] c.{self::SubImpl3::returnBoxedIntOrDouble}(){(self::X*) →* dynamic});
- self::use([@vm.direct-call.metadata=#lib::SubImpl3.returnBoxedNullableIntOrDouble] [@vm.inferred-type.metadata=dart.core::_Double (skip check) (value: 3.3)] c.{self::SubImpl3::returnBoxedNullableIntOrDouble}(){(self::X*) →* dynamic});
- self::use([@vm.direct-call.metadata=#lib::SubImpl3.returnBoxedNullableX] [@vm.inferred-type.metadata=#lib::X (skip check)] c.{self::SubImpl3::returnBoxedNullableX}(){(self::X*) →* dynamic});
- self::use([@vm.direct-call.metadata=#lib::SubImpl3.returnBoxedX] [@vm.inferred-type.metadata=#lib::X (skip check)] c.{self::SubImpl3::returnBoxedX}(){(self::X*) →* dynamic});
- self::use([@vm.inferred-type.metadata=dart.core::_Smi] d.{self::Interface::returnUnboxedSmi}(){(self::X*) →* dynamic});
- self::use([@vm.inferred-type.metadata=int] d.{self::Interface::returnUnboxedInt}(){(self::X*) →* dynamic});
- self::use([@vm.inferred-type.metadata=dart.core::_Double] d.{self::Interface::returnUnboxedDouble}(){(self::X*) →* dynamic});
- self::use([@vm.inferred-type.metadata=int?] d.{self::Interface::returnBoxedNullableInt}(){(self::X*) →* dynamic});
- self::use([@vm.inferred-type.metadata=dart.core::_Double?] d.{self::Interface::returnBoxedNullableDouble}(){(self::X*) →* dynamic});
- self::use([@vm.inferred-type.metadata=!] d.{self::Interface::returnBoxedIntOrDouble}(){(self::X*) →* dynamic});
- self::use([@vm.inferred-type.metadata=dart.core::_Double?] d.{self::Interface::returnBoxedNullableIntOrDouble}(){(self::X*) →* dynamic});
- self::use([@vm.inferred-type.metadata=#lib::X?] d.{self::Interface::returnBoxedNullableX}(){(self::X*) →* dynamic});
- self::use([@vm.inferred-type.metadata=#lib::X] d.{self::Interface::returnBoxedX}(){(self::X*) →* dynamic});
+ final core::List<core::Object> values = [@vm.inferred-type.metadata=dart.core::_GrowableList<dart.core::Object>] core::_GrowableList::_literal3<core::Object>(new self::Impl1::•(), new self::BaseImpl2::•(), new self::SubImpl3::•());
+ final self::Impl1 a = [@vm.direct-call.metadata=dart.core::_GrowableList.[]] [@vm.inferred-type.metadata=!? (skip check)] values.{core::List::[]}([@vm.inferred-type.metadata=int?] core::int::parse("0")){(core::int) → core::Object} as{ForNonNullableByDefault} self::Impl1;
+ final self::BaseImpl2 b = [@vm.direct-call.metadata=dart.core::_GrowableList.[]] [@vm.inferred-type.metadata=!? (skip check)] values.{core::List::[]}([@vm.inferred-type.metadata=int?] core::int::parse("1")){(core::int) → core::Object} as{ForNonNullableByDefault} self::BaseImpl2;
+ final self::SubImpl3 c = [@vm.direct-call.metadata=dart.core::_GrowableList.[]] [@vm.inferred-type.metadata=!? (skip check)] values.{core::List::[]}([@vm.inferred-type.metadata=int?] core::int::parse("2")){(core::int) → core::Object} as{ForNonNullableByDefault} self::SubImpl3;
+ final self::Interface d = [@vm.direct-call.metadata=dart.core::_GrowableList.[]] [@vm.inferred-type.metadata=!? (skip check)] values.{core::List::[]}([@vm.inferred-type.metadata=int?] core::int::parse("2")){(core::int) → core::Object} as{ForNonNullableByDefault} self::Interface;
+ [@vm.direct-call.metadata=#lib::Impl1.takePositional??] [@vm.inferred-type.metadata=!? (skip check)] a.{self::Impl1::takePositional}(1, 1.1, null, null, 1, null, null, new self::X::•()){(core::int?, dynamic, dynamic, dynamic, dynamic, dynamic, dynamic, dynamic, dynamic) → void};
+ b.{self::BaseImpl2::takePositional}(2, 2.2, 2, 2.2, 2.2, 2, new self::X::•(), new self::X::•()){(core::int?, dynamic, dynamic, dynamic, dynamic, dynamic, dynamic, dynamic, dynamic) → void};
+ [@vm.direct-call.metadata=#lib::SubImpl3.takePositional??] [@vm.inferred-type.metadata=!? (skip check)] c.{self::SubImpl3::takePositional}([@vm.inferred-type.metadata=int] self::mint, 3.3, [@vm.inferred-type.metadata=int] self::mint, 3.3, 3.3, 3.3, new self::X::•(), new self::X::•()){(core::int?, dynamic, dynamic, dynamic, dynamic, dynamic, dynamic, dynamic, dynamic) → void};
+ d.{self::Interface::takePositional}([@vm.inferred-type.metadata=int] self::mint, 3.3, [@vm.inferred-type.metadata=int] self::mint, 3.3, 3.3, 3.3, new self::X::•(), new self::X::•()){(core::int?, dynamic, dynamic, dynamic, dynamic, dynamic, dynamic, dynamic, dynamic) → void};
+ self::use([@vm.direct-call.metadata=#lib::Impl1.returnUnboxedSmi] [@vm.inferred-type.metadata=dart.core::_Smi (skip check) (value: 1)] a.{self::Impl1::returnUnboxedSmi}(){(self::X?) → dynamic});
+ self::use([@vm.direct-call.metadata=#lib::Impl1.returnUnboxedInt] [@vm.inferred-type.metadata=dart.core::_Smi (skip check) (value: 1)] a.{self::Impl1::returnUnboxedInt}(){(self::X?) → dynamic});
+ self::use([@vm.direct-call.metadata=#lib::Impl1.returnUnboxedDouble] [@vm.inferred-type.metadata=dart.core::_Double (skip check) (value: 1.1)] a.{self::Impl1::returnUnboxedDouble}(){(self::X?) → dynamic});
+ self::use([@vm.direct-call.metadata=#lib::Impl1.returnBoxedNullableInt] [@vm.inferred-type.metadata=dart.core::Null? (skip check) (value: null)] a.{self::Impl1::returnBoxedNullableInt}(){(self::X?) → dynamic});
+ self::use([@vm.direct-call.metadata=#lib::Impl1.returnBoxedNullableDouble] [@vm.inferred-type.metadata=dart.core::Null? (skip check) (value: null)] a.{self::Impl1::returnBoxedNullableDouble}(){(self::X?) → dynamic});
+ self::use([@vm.direct-call.metadata=#lib::Impl1.returnBoxedIntOrDouble] [@vm.inferred-type.metadata=dart.core::_Smi (skip check) (value: 1)] a.{self::Impl1::returnBoxedIntOrDouble}(){(self::X?) → dynamic});
+ self::use([@vm.direct-call.metadata=#lib::Impl1.returnBoxedNullableIntOrDouble] [@vm.inferred-type.metadata=dart.core::Null? (skip check) (value: null)] a.{self::Impl1::returnBoxedNullableIntOrDouble}(){(self::X?) → dynamic});
+ self::use([@vm.direct-call.metadata=#lib::Impl1.returnBoxedNullableX] [@vm.inferred-type.metadata=dart.core::Null? (skip check) (value: null)] a.{self::Impl1::returnBoxedNullableX}(){(self::X?) → dynamic});
+ self::use([@vm.direct-call.metadata=#lib::Impl1.returnBoxedX] [@vm.inferred-type.metadata=#lib::X (skip check)] a.{self::Impl1::returnBoxedX}(){(self::X?) → dynamic});
+ self::use([@vm.inferred-type.metadata=dart.core::_Smi] b.{self::BaseImpl2::returnUnboxedSmi}(){(self::X?) → dynamic});
+ self::use([@vm.inferred-type.metadata=int] b.{self::BaseImpl2::returnUnboxedInt}(){(self::X?) → dynamic});
+ self::use([@vm.inferred-type.metadata=dart.core::_Double] b.{self::BaseImpl2::returnUnboxedDouble}(){(self::X?) → dynamic});
+ self::use([@vm.inferred-type.metadata=int] b.{self::BaseImpl2::returnBoxedNullableInt}(){(self::X?) → dynamic});
+ self::use([@vm.inferred-type.metadata=dart.core::_Double] b.{self::BaseImpl2::returnBoxedNullableDouble}(){(self::X?) → dynamic});
+ self::use([@vm.inferred-type.metadata=dart.core::_Double] b.{self::BaseImpl2::returnBoxedIntOrDouble}(){(self::X?) → dynamic});
+ self::use([@vm.inferred-type.metadata=!] b.{self::BaseImpl2::returnBoxedNullableIntOrDouble}(){(self::X?) → dynamic});
+ self::use([@vm.inferred-type.metadata=#lib::X] b.{self::BaseImpl2::returnBoxedNullableX}(){(self::X?) → dynamic});
+ self::use([@vm.inferred-type.metadata=#lib::X] b.{self::BaseImpl2::returnBoxedX}(){(self::X?) → dynamic});
+ self::use([@vm.direct-call.metadata=#lib::SubImpl3.returnUnboxedSmi] [@vm.inferred-type.metadata=dart.core::_Smi (skip check) (value: 3)] c.{self::SubImpl3::returnUnboxedSmi}(){(self::X?) → dynamic});
+ self::use([@vm.direct-call.metadata=#lib::SubImpl3.returnUnboxedInt] [@vm.inferred-type.metadata=int (skip check)] c.{self::SubImpl3::returnUnboxedInt}(){(self::X?) → dynamic});
+ self::use([@vm.direct-call.metadata=#lib::SubImpl3.returnUnboxedDouble] [@vm.inferred-type.metadata=dart.core::_Double (skip check) (value: 3.3)] c.{self::SubImpl3::returnUnboxedDouble}(){(self::X?) → dynamic});
+ self::use([@vm.direct-call.metadata=#lib::SubImpl3.returnBoxedNullableInt] [@vm.inferred-type.metadata=int (skip check)] c.{self::SubImpl3::returnBoxedNullableInt}(){(self::X?) → dynamic});
+ self::use([@vm.direct-call.metadata=#lib::SubImpl3.returnBoxedNullableDouble] [@vm.inferred-type.metadata=dart.core::_Double (skip check) (value: 3.3)] c.{self::SubImpl3::returnBoxedNullableDouble}(){(self::X?) → dynamic});
+ self::use([@vm.direct-call.metadata=#lib::SubImpl3.returnBoxedIntOrDouble] [@vm.inferred-type.metadata=dart.core::_Double (skip check) (value: 3.3)] c.{self::SubImpl3::returnBoxedIntOrDouble}(){(self::X?) → dynamic});
+ self::use([@vm.direct-call.metadata=#lib::SubImpl3.returnBoxedNullableIntOrDouble] [@vm.inferred-type.metadata=dart.core::_Double (skip check) (value: 3.3)] c.{self::SubImpl3::returnBoxedNullableIntOrDouble}(){(self::X?) → dynamic});
+ self::use([@vm.direct-call.metadata=#lib::SubImpl3.returnBoxedNullableX] [@vm.inferred-type.metadata=#lib::X (skip check)] c.{self::SubImpl3::returnBoxedNullableX}(){(self::X?) → dynamic});
+ self::use([@vm.direct-call.metadata=#lib::SubImpl3.returnBoxedX] [@vm.inferred-type.metadata=#lib::X (skip check)] c.{self::SubImpl3::returnBoxedX}(){(self::X?) → dynamic});
+ self::use([@vm.inferred-type.metadata=dart.core::_Smi] d.{self::Interface::returnUnboxedSmi}(){(self::X?) → dynamic});
+ self::use([@vm.inferred-type.metadata=int] d.{self::Interface::returnUnboxedInt}(){(self::X?) → dynamic});
+ self::use([@vm.inferred-type.metadata=dart.core::_Double] d.{self::Interface::returnUnboxedDouble}(){(self::X?) → dynamic});
+ self::use([@vm.inferred-type.metadata=int?] d.{self::Interface::returnBoxedNullableInt}(){(self::X?) → dynamic});
+ self::use([@vm.inferred-type.metadata=dart.core::_Double?] d.{self::Interface::returnBoxedNullableDouble}(){(self::X?) → dynamic});
+ self::use([@vm.inferred-type.metadata=!] d.{self::Interface::returnBoxedIntOrDouble}(){(self::X?) → dynamic});
+ self::use([@vm.inferred-type.metadata=dart.core::_Double?] d.{self::Interface::returnBoxedNullableIntOrDouble}(){(self::X?) → dynamic});
+ self::use([@vm.inferred-type.metadata=#lib::X?] d.{self::Interface::returnBoxedNullableX}(){(self::X?) → dynamic});
+ self::use([@vm.inferred-type.metadata=#lib::X] d.{self::Interface::returnBoxedX}(){(self::X?) → dynamic});
}
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/unboxed_instance_method_tearoff.dart b/pkg/vm/testcases/transformations/type_flow/transformer/unboxed_instance_method_tearoff.dart
index ba97287..f8637c8 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/unboxed_instance_method_tearoff.dart
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/unboxed_instance_method_tearoff.dart
@@ -2,8 +2,6 @@
// for 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.9
-
final bool kTrue = int.parse('1') == 1 ? true : false;
final bool kFalse = int.parse('1') == 2 ? true : false;
int get mint => 0xaabbccddaabbccdd;
@@ -18,7 +16,7 @@
abstract class Interface {
void takePositional(
- int unboxedSmi,
+ int? unboxedSmi,
dynamic unboxedInt,
dynamic unboxedDouble,
dynamic boxedNullableInt,
@@ -28,20 +26,20 @@
dynamic boxedNullableX,
dynamic boxedX);
- dynamic returnUnboxedSmi(X ignored);
- dynamic returnUnboxedInt(X ignored);
- dynamic returnUnboxedDouble(X ignored);
- dynamic returnBoxedNullableInt(X ignored);
- dynamic returnBoxedNullableDouble(X ignored);
- dynamic returnBoxedIntOrDouble(X ignored);
- dynamic returnBoxedNullableIntOrDouble(X ignored);
- dynamic returnBoxedNullableX(X ignored);
- dynamic returnBoxedX(X ignored);
+ dynamic returnUnboxedSmi(X? ignored);
+ dynamic returnUnboxedInt(X? ignored);
+ dynamic returnUnboxedDouble(X? ignored);
+ dynamic returnBoxedNullableInt(X? ignored);
+ dynamic returnBoxedNullableDouble(X? ignored);
+ dynamic returnBoxedIntOrDouble(X? ignored);
+ dynamic returnBoxedNullableIntOrDouble(X? ignored);
+ dynamic returnBoxedNullableX(X? ignored);
+ dynamic returnBoxedX(X? ignored);
}
class Impl1 implements Interface {
void takePositional(
- int unboxedSmi,
+ int? unboxedSmi,
dynamic unboxedInt,
dynamic unboxedDouble,
dynamic boxedNullableInt,
@@ -60,20 +58,20 @@
use(boxedX);
}
- dynamic returnUnboxedSmi(X ignored) => 1;
- dynamic returnUnboxedInt(X ignored) => 1;
- dynamic returnUnboxedDouble(X ignored) => 1.1;
- dynamic returnBoxedNullableInt(X ignored) => null;
- dynamic returnBoxedNullableDouble(X ignored) => null;
- dynamic returnBoxedIntOrDouble(X ignored) => 1;
- dynamic returnBoxedNullableIntOrDouble(X ignored) => null;
- dynamic returnBoxedNullableX(X ignored) => null;
- dynamic returnBoxedX(X ignored) => X();
+ dynamic returnUnboxedSmi(X? ignored) => 1;
+ dynamic returnUnboxedInt(X? ignored) => 1;
+ dynamic returnUnboxedDouble(X? ignored) => 1.1;
+ dynamic returnBoxedNullableInt(X? ignored) => null;
+ dynamic returnBoxedNullableDouble(X? ignored) => null;
+ dynamic returnBoxedIntOrDouble(X? ignored) => 1;
+ dynamic returnBoxedNullableIntOrDouble(X? ignored) => null;
+ dynamic returnBoxedNullableX(X? ignored) => null;
+ dynamic returnBoxedX(X? ignored) => X();
}
class BaseImpl2 {
void takePositional(
- int unboxedSmi,
+ int? unboxedSmi,
dynamic unboxedInt,
dynamic unboxedDouble,
dynamic boxedNullableInt,
@@ -92,20 +90,20 @@
use(boxedX);
}
- dynamic returnUnboxedSmi(X ignored) => 2;
- dynamic returnUnboxedInt(X ignored) => mint;
- dynamic returnUnboxedDouble(X ignored) => 2.2;
- dynamic returnBoxedNullableInt(X ignored) => 2;
- dynamic returnBoxedNullableDouble(X ignored) => 2.2;
- dynamic returnBoxedIntOrDouble(X ignored) => 2.2;
- dynamic returnBoxedNullableIntOrDouble(X ignored) => 2;
- dynamic returnBoxedNullableX(X ignored) => X();
- dynamic returnBoxedX(X ignored) => X();
+ dynamic returnUnboxedSmi(X? ignored) => 2;
+ dynamic returnUnboxedInt(X? ignored) => mint;
+ dynamic returnUnboxedDouble(X? ignored) => 2.2;
+ dynamic returnBoxedNullableInt(X? ignored) => 2;
+ dynamic returnBoxedNullableDouble(X? ignored) => 2.2;
+ dynamic returnBoxedIntOrDouble(X? ignored) => 2.2;
+ dynamic returnBoxedNullableIntOrDouble(X? ignored) => 2;
+ dynamic returnBoxedNullableX(X? ignored) => X();
+ dynamic returnBoxedX(X? ignored) => X();
}
class SubImpl3 extends BaseImpl2 implements Interface {
void takePositional(
- int unboxedSmi,
+ int? unboxedSmi,
dynamic unboxedInt,
dynamic unboxedDouble,
dynamic boxedNullableInt,
@@ -124,15 +122,15 @@
use(boxedX);
}
- dynamic returnUnboxedSmi(X ignored) => 3;
- dynamic returnUnboxedInt(X ignored) => mint;
- dynamic returnUnboxedDouble(X ignored) => 3.3;
- dynamic returnBoxedNullableInt(X ignored) => mint;
- dynamic returnBoxedNullableDouble(X ignored) => 3.3;
- dynamic returnBoxedIntOrDouble(X ignored) => 3.3;
- dynamic returnBoxedNullableIntOrDouble(X ignored) => 3.3;
- dynamic returnBoxedNullableX(X ignored) => X();
- dynamic returnBoxedX(X ignored) => X();
+ dynamic returnUnboxedSmi(X? ignored) => 3;
+ dynamic returnUnboxedInt(X? ignored) => mint;
+ dynamic returnUnboxedDouble(X? ignored) => 3.3;
+ dynamic returnBoxedNullableInt(X? ignored) => mint;
+ dynamic returnBoxedNullableDouble(X? ignored) => 3.3;
+ dynamic returnBoxedIntOrDouble(X? ignored) => 3.3;
+ dynamic returnBoxedNullableIntOrDouble(X? ignored) => 3.3;
+ dynamic returnBoxedNullableX(X? ignored) => X();
+ dynamic returnBoxedX(X? ignored) => X();
}
main() {
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/unboxed_instance_method_tearoff.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/unboxed_instance_method_tearoff.dart.expect
index d22492c..2405a88 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/unboxed_instance_method_tearoff.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/unboxed_instance_method_tearoff.dart.expect
@@ -1,29 +1,29 @@
-library #lib;
+library #lib /*isNonNullableByDefault*/;
import self as self;
import "dart:core" as core;
class X extends core::Object {
- synthetic constructor •() → self::X*
+ synthetic constructor •() → self::X
: super core::Object::•()
;
}
abstract class Interface extends core::Object {
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2] abstract method takePositional(core::int* unboxedSmi, dynamic unboxedInt, dynamic unboxedDouble, dynamic boxedNullableInt, dynamic boxedNullableDouble, dynamic boxedNonNullableIntOrDouble, dynamic boxedNullableIntOrDouble, dynamic boxedNullableX, dynamic boxedX) → void;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:3,getterSelectorId:4] [@vm.unboxing-info.metadata=(b)->i] abstract method returnUnboxedSmi(self::X* ignored) → dynamic;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:5,getterSelectorId:6] [@vm.unboxing-info.metadata=(b)->i] abstract method returnUnboxedInt(self::X* ignored) → dynamic;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:7,getterSelectorId:8] [@vm.unboxing-info.metadata=(b)->d] abstract method returnUnboxedDouble(self::X* ignored) → dynamic;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:9,getterSelectorId:10] abstract method returnBoxedNullableInt(self::X* ignored) → dynamic;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:11,getterSelectorId:12] abstract method returnBoxedNullableDouble(self::X* ignored) → dynamic;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:13,getterSelectorId:14] abstract method returnBoxedIntOrDouble(self::X* ignored) → dynamic;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:15,getterSelectorId:16] abstract method returnBoxedNullableIntOrDouble(self::X* ignored) → dynamic;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:17,getterSelectorId:18] abstract method returnBoxedNullableX(self::X* ignored) → dynamic;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:19,getterSelectorId:20] abstract method returnBoxedX(self::X* ignored) → dynamic;
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2] abstract method takePositional(core::int? unboxedSmi, dynamic unboxedInt, dynamic unboxedDouble, dynamic boxedNullableInt, dynamic boxedNullableDouble, dynamic boxedNonNullableIntOrDouble, dynamic boxedNullableIntOrDouble, dynamic boxedNullableX, dynamic boxedX) → void;
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:3,getterSelectorId:4] [@vm.unboxing-info.metadata=(b)->i] abstract method returnUnboxedSmi(self::X? ignored) → dynamic;
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:5,getterSelectorId:6] [@vm.unboxing-info.metadata=(b)->i] abstract method returnUnboxedInt(self::X? ignored) → dynamic;
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:7,getterSelectorId:8] [@vm.unboxing-info.metadata=(b)->d] abstract method returnUnboxedDouble(self::X? ignored) → dynamic;
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:9,getterSelectorId:10] abstract method returnBoxedNullableInt(self::X? ignored) → dynamic;
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:11,getterSelectorId:12] abstract method returnBoxedNullableDouble(self::X? ignored) → dynamic;
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:13,getterSelectorId:14] abstract method returnBoxedIntOrDouble(self::X? ignored) → dynamic;
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:15,getterSelectorId:16] abstract method returnBoxedNullableIntOrDouble(self::X? ignored) → dynamic;
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:17,getterSelectorId:18] abstract method returnBoxedNullableX(self::X? ignored) → dynamic;
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:19,getterSelectorId:20] abstract method returnBoxedX(self::X? ignored) → dynamic;
}
class Impl1 extends core::Object implements self::Interface {
- synthetic constructor •() → self::Impl1*
+ synthetic constructor •() → self::Impl1
: super core::Object::•()
;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,methodOrSetterSelectorId:1,getterSelectorId:2] method takePositional(core::int* unboxedSmi, dynamic unboxedInt, dynamic unboxedDouble, dynamic boxedNullableInt, dynamic boxedNullableDouble, dynamic boxedNonNullableIntOrDouble, dynamic boxedNullableIntOrDouble, dynamic boxedNullableX, dynamic boxedX) → void {
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,methodOrSetterSelectorId:1,getterSelectorId:2] method takePositional(core::int? unboxedSmi, dynamic unboxedInt, dynamic unboxedDouble, dynamic boxedNullableInt, dynamic boxedNullableDouble, dynamic boxedNonNullableIntOrDouble, dynamic boxedNullableIntOrDouble, dynamic boxedNullableX, dynamic boxedX) → void {
self::use(unboxedInt);
self::use(unboxedDouble);
self::use(boxedNullableInt);
@@ -33,30 +33,30 @@
self::use(boxedNullableX);
self::use(boxedX);
}
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,methodOrSetterSelectorId:3,getterSelectorId:4] [@vm.unboxing-info.metadata=(b)->i] method returnUnboxedSmi(self::X* ignored) → dynamic
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,methodOrSetterSelectorId:3,getterSelectorId:4] [@vm.unboxing-info.metadata=(b)->i] method returnUnboxedSmi(self::X? ignored) → dynamic
return 1;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,methodOrSetterSelectorId:5,getterSelectorId:6] [@vm.unboxing-info.metadata=(b)->i] method returnUnboxedInt(self::X* ignored) → dynamic
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,methodOrSetterSelectorId:5,getterSelectorId:6] [@vm.unboxing-info.metadata=(b)->i] method returnUnboxedInt(self::X? ignored) → dynamic
return 1;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,methodOrSetterSelectorId:7,getterSelectorId:8] [@vm.unboxing-info.metadata=(b)->d] method returnUnboxedDouble(self::X* ignored) → dynamic
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,methodOrSetterSelectorId:7,getterSelectorId:8] [@vm.unboxing-info.metadata=(b)->d] method returnUnboxedDouble(self::X? ignored) → dynamic
return 1.1;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,methodOrSetterSelectorId:9,getterSelectorId:10] method returnBoxedNullableInt(self::X* ignored) → dynamic
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,methodOrSetterSelectorId:9,getterSelectorId:10] method returnBoxedNullableInt(self::X? ignored) → dynamic
return null;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,methodOrSetterSelectorId:11,getterSelectorId:12] method returnBoxedNullableDouble(self::X* ignored) → dynamic
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,methodOrSetterSelectorId:11,getterSelectorId:12] method returnBoxedNullableDouble(self::X? ignored) → dynamic
return null;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,methodOrSetterSelectorId:13,getterSelectorId:14] method returnBoxedIntOrDouble(self::X* ignored) → dynamic
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,methodOrSetterSelectorId:13,getterSelectorId:14] method returnBoxedIntOrDouble(self::X? ignored) → dynamic
return 1;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,methodOrSetterSelectorId:15,getterSelectorId:16] method returnBoxedNullableIntOrDouble(self::X* ignored) → dynamic
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,methodOrSetterSelectorId:15,getterSelectorId:16] method returnBoxedNullableIntOrDouble(self::X? ignored) → dynamic
return null;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,methodOrSetterSelectorId:17,getterSelectorId:18] method returnBoxedNullableX(self::X* ignored) → dynamic
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,methodOrSetterSelectorId:17,getterSelectorId:18] method returnBoxedNullableX(self::X? ignored) → dynamic
return null;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,methodOrSetterSelectorId:19,getterSelectorId:20] method returnBoxedX(self::X* ignored) → dynamic
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,methodOrSetterSelectorId:19,getterSelectorId:20] method returnBoxedX(self::X? ignored) → dynamic
return new self::X::•();
}
class BaseImpl2 extends core::Object {
- synthetic constructor •() → self::BaseImpl2*
+ synthetic constructor •() → self::BaseImpl2
: super core::Object::•()
;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2] method takePositional([@vm.inferred-type.metadata=dart.core::_Smi (value: 2)] core::int* unboxedSmi, [@vm.inferred-type.metadata=dart.core::_Smi (value: 2)] dynamic unboxedInt, [@vm.inferred-type.metadata=dart.core::_Double (value: 2.2)] dynamic unboxedDouble, [@vm.inferred-type.metadata=dart.core::_Smi (value: 2)] dynamic boxedNullableInt, [@vm.inferred-type.metadata=dart.core::_Double (value: 2.2)] dynamic boxedNullableDouble, [@vm.inferred-type.metadata=dart.core::_Double (value: 2.2)] dynamic boxedNonNullableIntOrDouble, [@vm.inferred-type.metadata=dart.core::_Smi (value: 2)] dynamic boxedNullableIntOrDouble, [@vm.inferred-type.metadata=#lib::X] dynamic boxedNullableX, [@vm.inferred-type.metadata=#lib::X] dynamic boxedX) → void {
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2] method takePositional([@vm.inferred-type.metadata=dart.core::_Smi (value: 2)] core::int? unboxedSmi, [@vm.inferred-type.metadata=dart.core::_Smi (value: 2)] dynamic unboxedInt, [@vm.inferred-type.metadata=dart.core::_Double (value: 2.2)] dynamic unboxedDouble, [@vm.inferred-type.metadata=dart.core::_Smi (value: 2)] dynamic boxedNullableInt, [@vm.inferred-type.metadata=dart.core::_Double (value: 2.2)] dynamic boxedNullableDouble, [@vm.inferred-type.metadata=dart.core::_Double (value: 2.2)] dynamic boxedNonNullableIntOrDouble, [@vm.inferred-type.metadata=dart.core::_Smi (value: 2)] dynamic boxedNullableIntOrDouble, [@vm.inferred-type.metadata=#lib::X] dynamic boxedNullableX, [@vm.inferred-type.metadata=#lib::X] dynamic boxedX) → void {
self::use(unboxedInt);
self::use(unboxedDouble);
self::use(boxedNullableInt);
@@ -66,30 +66,30 @@
self::use(boxedNullableX);
self::use(boxedX);
}
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:3,getterSelectorId:4] [@vm.unboxing-info.metadata=(b)->i] method returnUnboxedSmi([@vm.inferred-type.metadata=dart.core::Null? (value: null)] self::X* ignored) → dynamic
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:3,getterSelectorId:4] [@vm.unboxing-info.metadata=(b)->i] method returnUnboxedSmi([@vm.inferred-type.metadata=dart.core::Null? (value: null)] self::X? ignored) → dynamic
return 2;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:5,getterSelectorId:6] [@vm.unboxing-info.metadata=(b)->i] method returnUnboxedInt([@vm.inferred-type.metadata=dart.core::Null? (value: null)] self::X* ignored) → dynamic
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:5,getterSelectorId:6] [@vm.unboxing-info.metadata=(b)->i] method returnUnboxedInt([@vm.inferred-type.metadata=dart.core::Null? (value: null)] self::X? ignored) → dynamic
return [@vm.inferred-type.metadata=int] self::mint;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:7,getterSelectorId:8] [@vm.unboxing-info.metadata=(b)->d] method returnUnboxedDouble([@vm.inferred-type.metadata=dart.core::Null? (value: null)] self::X* ignored) → dynamic
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:7,getterSelectorId:8] [@vm.unboxing-info.metadata=(b)->d] method returnUnboxedDouble([@vm.inferred-type.metadata=dart.core::Null? (value: null)] self::X? ignored) → dynamic
return 2.2;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:9,getterSelectorId:10] method returnBoxedNullableInt([@vm.inferred-type.metadata=dart.core::Null? (value: null)] self::X* ignored) → dynamic
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:9,getterSelectorId:10] method returnBoxedNullableInt([@vm.inferred-type.metadata=dart.core::Null? (value: null)] self::X? ignored) → dynamic
return 2;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:11,getterSelectorId:12] method returnBoxedNullableDouble([@vm.inferred-type.metadata=dart.core::Null? (value: null)] self::X* ignored) → dynamic
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:11,getterSelectorId:12] method returnBoxedNullableDouble([@vm.inferred-type.metadata=dart.core::Null? (value: null)] self::X? ignored) → dynamic
return 2.2;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:13,getterSelectorId:14] method returnBoxedIntOrDouble([@vm.inferred-type.metadata=dart.core::Null? (value: null)] self::X* ignored) → dynamic
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:13,getterSelectorId:14] method returnBoxedIntOrDouble([@vm.inferred-type.metadata=dart.core::Null? (value: null)] self::X? ignored) → dynamic
return 2.2;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:15,getterSelectorId:16] method returnBoxedNullableIntOrDouble([@vm.inferred-type.metadata=dart.core::Null? (value: null)] self::X* ignored) → dynamic
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:15,getterSelectorId:16] method returnBoxedNullableIntOrDouble([@vm.inferred-type.metadata=dart.core::Null? (value: null)] self::X? ignored) → dynamic
return 2;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:17,getterSelectorId:18] method returnBoxedNullableX([@vm.inferred-type.metadata=dart.core::Null? (value: null)] self::X* ignored) → dynamic
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:17,getterSelectorId:18] method returnBoxedNullableX([@vm.inferred-type.metadata=dart.core::Null? (value: null)] self::X? ignored) → dynamic
return new self::X::•();
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:19,getterSelectorId:20] method returnBoxedX([@vm.inferred-type.metadata=dart.core::Null? (value: null)] self::X* ignored) → dynamic
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:19,getterSelectorId:20] method returnBoxedX([@vm.inferred-type.metadata=dart.core::Null? (value: null)] self::X? ignored) → dynamic
return new self::X::•();
}
class SubImpl3 extends self::BaseImpl2 implements self::Interface {
- synthetic constructor •() → self::SubImpl3*
+ synthetic constructor •() → self::SubImpl3
: super self::BaseImpl2::•()
;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,methodOrSetterSelectorId:1,getterSelectorId:2] method takePositional(core::int* unboxedSmi, dynamic unboxedInt, dynamic unboxedDouble, dynamic boxedNullableInt, dynamic boxedNullableDouble, dynamic boxedNonNullableIntOrDouble, dynamic boxedNullableIntOrDouble, dynamic boxedNullableX, dynamic boxedX) → void {
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,methodOrSetterSelectorId:1,getterSelectorId:2] method takePositional(core::int? unboxedSmi, dynamic unboxedInt, dynamic unboxedDouble, dynamic boxedNullableInt, dynamic boxedNullableDouble, dynamic boxedNonNullableIntOrDouble, dynamic boxedNullableIntOrDouble, dynamic boxedNullableX, dynamic boxedX) → void {
self::use(unboxedInt);
self::use(unboxedDouble);
self::use(boxedNullableInt);
@@ -99,85 +99,85 @@
self::use(boxedNullableX);
self::use(boxedX);
}
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,methodOrSetterSelectorId:3,getterSelectorId:4] [@vm.unboxing-info.metadata=(b)->i] method returnUnboxedSmi(self::X* ignored) → dynamic
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,methodOrSetterSelectorId:3,getterSelectorId:4] [@vm.unboxing-info.metadata=(b)->i] method returnUnboxedSmi(self::X? ignored) → dynamic
return 3;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,methodOrSetterSelectorId:5,getterSelectorId:6] [@vm.unboxing-info.metadata=(b)->i] method returnUnboxedInt(self::X* ignored) → dynamic
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,methodOrSetterSelectorId:5,getterSelectorId:6] [@vm.unboxing-info.metadata=(b)->i] method returnUnboxedInt(self::X? ignored) → dynamic
return [@vm.inferred-type.metadata=int] self::mint;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,methodOrSetterSelectorId:7,getterSelectorId:8] [@vm.unboxing-info.metadata=(b)->d] method returnUnboxedDouble(self::X* ignored) → dynamic
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,methodOrSetterSelectorId:7,getterSelectorId:8] [@vm.unboxing-info.metadata=(b)->d] method returnUnboxedDouble(self::X? ignored) → dynamic
return 3.3;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,methodOrSetterSelectorId:9,getterSelectorId:10] method returnBoxedNullableInt(self::X* ignored) → dynamic
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,methodOrSetterSelectorId:9,getterSelectorId:10] method returnBoxedNullableInt(self::X? ignored) → dynamic
return [@vm.inferred-type.metadata=int] self::mint;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,methodOrSetterSelectorId:11,getterSelectorId:12] method returnBoxedNullableDouble(self::X* ignored) → dynamic
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,methodOrSetterSelectorId:11,getterSelectorId:12] method returnBoxedNullableDouble(self::X? ignored) → dynamic
return 3.3;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,methodOrSetterSelectorId:13,getterSelectorId:14] method returnBoxedIntOrDouble(self::X* ignored) → dynamic
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,methodOrSetterSelectorId:13,getterSelectorId:14] method returnBoxedIntOrDouble(self::X? ignored) → dynamic
return 3.3;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,methodOrSetterSelectorId:15,getterSelectorId:16] method returnBoxedNullableIntOrDouble(self::X* ignored) → dynamic
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,methodOrSetterSelectorId:15,getterSelectorId:16] method returnBoxedNullableIntOrDouble(self::X? ignored) → dynamic
return 3.3;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,methodOrSetterSelectorId:17,getterSelectorId:18] method returnBoxedNullableX(self::X* ignored) → dynamic
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,methodOrSetterSelectorId:17,getterSelectorId:18] method returnBoxedNullableX(self::X? ignored) → dynamic
return new self::X::•();
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,methodOrSetterSelectorId:19,getterSelectorId:20] method returnBoxedX(self::X* ignored) → dynamic
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,methodOrSetterSelectorId:19,getterSelectorId:20] method returnBoxedX(self::X? ignored) → dynamic
return new self::X::•();
}
static field dynamic usedObject;
-[@vm.unboxing-info.metadata=()->i]static get mint() → core::int*
+[@vm.unboxing-info.metadata=()->i]static get mint() → core::int
return -6144092014192636707;
static method use(dynamic object) → void {
self::usedObject == null ?{dynamic} self::usedObject = object : null;
}
static method main() → dynamic {
- final core::List<core::Object*>* values = [@vm.inferred-type.metadata=dart.core::_GrowableList<dart.core::Object*>] core::_GrowableList::_literal3<core::Object*>(new self::Impl1::•(), new self::BaseImpl2::•(), new self::SubImpl3::•());
- final self::Impl1* a = [@vm.direct-call.metadata=dart.core::_GrowableList.[]] [@vm.inferred-type.metadata=!? (skip check)] values.{core::List::[]}([@vm.inferred-type.metadata=int?] core::int::parse("0")){(core::int*) →* core::Object*} as self::Impl1*;
- final self::BaseImpl2* b = [@vm.direct-call.metadata=dart.core::_GrowableList.[]] [@vm.inferred-type.metadata=!? (skip check)] values.{core::List::[]}([@vm.inferred-type.metadata=int?] core::int::parse("1")){(core::int*) →* core::Object*} as self::BaseImpl2*;
- final self::SubImpl3* c = [@vm.direct-call.metadata=dart.core::_GrowableList.[]] [@vm.inferred-type.metadata=!? (skip check)] values.{core::List::[]}([@vm.inferred-type.metadata=int?] core::int::parse("2")){(core::int*) →* core::Object*} as self::SubImpl3*;
- final self::Interface* d = [@vm.direct-call.metadata=dart.core::_GrowableList.[]] [@vm.inferred-type.metadata=!? (skip check)] values.{core::List::[]}([@vm.inferred-type.metadata=int?] core::int::parse("2")){(core::int*) →* core::Object*} as self::Interface*;
- [@vm.direct-call.metadata=#lib::Impl1.takePositional??] [@vm.inferred-type.metadata=!? (skip check)] a.{self::Impl1::takePositional}(1, 1, 1.1, null, null, 1, null, null, new self::X::•()){(core::int*, dynamic, dynamic, dynamic, dynamic, dynamic, dynamic, dynamic, dynamic) →* void};
- b.{self::BaseImpl2::takePositional}(2, 2, 2.2, 2, 2.2, 2.2, 2, new self::X::•(), new self::X::•()){(core::int*, dynamic, dynamic, dynamic, dynamic, dynamic, dynamic, dynamic, dynamic) →* void};
- [@vm.direct-call.metadata=#lib::SubImpl3.takePositional??] [@vm.inferred-type.metadata=!? (skip check)] c.{self::SubImpl3::takePositional}(3, [@vm.inferred-type.metadata=int] self::mint, 3.3, [@vm.inferred-type.metadata=int] self::mint, 3.3, 3.3, 3.3, new self::X::•(), new self::X::•()){(core::int*, dynamic, dynamic, dynamic, dynamic, dynamic, dynamic, dynamic, dynamic) →* void};
- d.{self::Interface::takePositional}(3, [@vm.inferred-type.metadata=int] self::mint, 3.3, [@vm.inferred-type.metadata=int] self::mint, 3.3, 3.3, 3.3, new self::X::•(), new self::X::•()){(core::int*, dynamic, dynamic, dynamic, dynamic, dynamic, dynamic, dynamic, dynamic) →* void};
- self::use([@vm.direct-call.metadata=#lib::Impl1.returnUnboxedSmi] [@vm.inferred-type.metadata=dart.core::_Smi (skip check) (value: 1)] a.{self::Impl1::returnUnboxedSmi}(null){(self::X*) →* dynamic});
- self::use([@vm.direct-call.metadata=#lib::Impl1.returnUnboxedInt] [@vm.inferred-type.metadata=dart.core::_Smi (skip check) (value: 1)] a.{self::Impl1::returnUnboxedInt}(null){(self::X*) →* dynamic});
- self::use([@vm.direct-call.metadata=#lib::Impl1.returnUnboxedDouble] [@vm.inferred-type.metadata=dart.core::_Double (skip check) (value: 1.1)] a.{self::Impl1::returnUnboxedDouble}(null){(self::X*) →* dynamic});
- self::use([@vm.direct-call.metadata=#lib::Impl1.returnBoxedNullableInt] [@vm.inferred-type.metadata=dart.core::Null? (skip check) (value: null)] a.{self::Impl1::returnBoxedNullableInt}(null){(self::X*) →* dynamic});
- self::use([@vm.direct-call.metadata=#lib::Impl1.returnBoxedNullableDouble] [@vm.inferred-type.metadata=dart.core::Null? (skip check) (value: null)] a.{self::Impl1::returnBoxedNullableDouble}(null){(self::X*) →* dynamic});
- self::use([@vm.direct-call.metadata=#lib::Impl1.returnBoxedIntOrDouble] [@vm.inferred-type.metadata=dart.core::_Smi (skip check) (value: 1)] a.{self::Impl1::returnBoxedIntOrDouble}(null){(self::X*) →* dynamic});
- self::use([@vm.direct-call.metadata=#lib::Impl1.returnBoxedNullableIntOrDouble] [@vm.inferred-type.metadata=dart.core::Null? (skip check) (value: null)] a.{self::Impl1::returnBoxedNullableIntOrDouble}(null){(self::X*) →* dynamic});
- self::use([@vm.direct-call.metadata=#lib::Impl1.returnBoxedNullableX] [@vm.inferred-type.metadata=dart.core::Null? (skip check) (value: null)] a.{self::Impl1::returnBoxedNullableX}(null){(self::X*) →* dynamic});
- self::use([@vm.direct-call.metadata=#lib::Impl1.returnBoxedX] [@vm.inferred-type.metadata=#lib::X (skip check)] a.{self::Impl1::returnBoxedX}(null){(self::X*) →* dynamic});
- self::use([@vm.inferred-type.metadata=dart.core::_Smi] b.{self::BaseImpl2::returnUnboxedSmi}(null){(self::X*) →* dynamic});
- self::use([@vm.inferred-type.metadata=int] b.{self::BaseImpl2::returnUnboxedInt}(null){(self::X*) →* dynamic});
- self::use([@vm.inferred-type.metadata=dart.core::_Double] b.{self::BaseImpl2::returnUnboxedDouble}(null){(self::X*) →* dynamic});
- self::use([@vm.inferred-type.metadata=int] b.{self::BaseImpl2::returnBoxedNullableInt}(null){(self::X*) →* dynamic});
- self::use([@vm.inferred-type.metadata=dart.core::_Double] b.{self::BaseImpl2::returnBoxedNullableDouble}(null){(self::X*) →* dynamic});
- self::use([@vm.inferred-type.metadata=dart.core::_Double] b.{self::BaseImpl2::returnBoxedIntOrDouble}(null){(self::X*) →* dynamic});
- self::use([@vm.inferred-type.metadata=!] b.{self::BaseImpl2::returnBoxedNullableIntOrDouble}(null){(self::X*) →* dynamic});
- self::use([@vm.inferred-type.metadata=#lib::X] b.{self::BaseImpl2::returnBoxedNullableX}(null){(self::X*) →* dynamic});
- self::use([@vm.inferred-type.metadata=#lib::X] b.{self::BaseImpl2::returnBoxedX}(null){(self::X*) →* dynamic});
- self::use([@vm.direct-call.metadata=#lib::SubImpl3.returnUnboxedSmi] [@vm.inferred-type.metadata=dart.core::_Smi (skip check) (value: 3)] c.{self::SubImpl3::returnUnboxedSmi}(null){(self::X*) →* dynamic});
- self::use([@vm.direct-call.metadata=#lib::SubImpl3.returnUnboxedInt] [@vm.inferred-type.metadata=int (skip check)] c.{self::SubImpl3::returnUnboxedInt}(null){(self::X*) →* dynamic});
- self::use([@vm.direct-call.metadata=#lib::SubImpl3.returnUnboxedDouble] [@vm.inferred-type.metadata=dart.core::_Double (skip check) (value: 3.3)] c.{self::SubImpl3::returnUnboxedDouble}(null){(self::X*) →* dynamic});
- self::use([@vm.direct-call.metadata=#lib::SubImpl3.returnBoxedNullableInt] [@vm.inferred-type.metadata=int (skip check)] c.{self::SubImpl3::returnBoxedNullableInt}(null){(self::X*) →* dynamic});
- self::use([@vm.direct-call.metadata=#lib::SubImpl3.returnBoxedNullableDouble] [@vm.inferred-type.metadata=dart.core::_Double (skip check) (value: 3.3)] c.{self::SubImpl3::returnBoxedNullableDouble}(null){(self::X*) →* dynamic});
- self::use([@vm.direct-call.metadata=#lib::SubImpl3.returnBoxedIntOrDouble] [@vm.inferred-type.metadata=dart.core::_Double (skip check) (value: 3.3)] c.{self::SubImpl3::returnBoxedIntOrDouble}(null){(self::X*) →* dynamic});
- self::use([@vm.direct-call.metadata=#lib::SubImpl3.returnBoxedNullableIntOrDouble] [@vm.inferred-type.metadata=dart.core::_Double (skip check) (value: 3.3)] c.{self::SubImpl3::returnBoxedNullableIntOrDouble}(null){(self::X*) →* dynamic});
- self::use([@vm.direct-call.metadata=#lib::SubImpl3.returnBoxedNullableX] [@vm.inferred-type.metadata=#lib::X (skip check)] c.{self::SubImpl3::returnBoxedNullableX}(null){(self::X*) →* dynamic});
- self::use([@vm.direct-call.metadata=#lib::SubImpl3.returnBoxedX] [@vm.inferred-type.metadata=#lib::X (skip check)] c.{self::SubImpl3::returnBoxedX}(null){(self::X*) →* dynamic});
- self::use([@vm.inferred-type.metadata=dart.core::_Smi] d.{self::Interface::returnUnboxedSmi}(null){(self::X*) →* dynamic});
- self::use([@vm.inferred-type.metadata=int] d.{self::Interface::returnUnboxedInt}(null){(self::X*) →* dynamic});
- self::use([@vm.inferred-type.metadata=dart.core::_Double] d.{self::Interface::returnUnboxedDouble}(null){(self::X*) →* dynamic});
- self::use([@vm.inferred-type.metadata=int?] d.{self::Interface::returnBoxedNullableInt}(null){(self::X*) →* dynamic});
- self::use([@vm.inferred-type.metadata=dart.core::_Double?] d.{self::Interface::returnBoxedNullableDouble}(null){(self::X*) →* dynamic});
- self::use([@vm.inferred-type.metadata=!] d.{self::Interface::returnBoxedIntOrDouble}(null){(self::X*) →* dynamic});
- self::use([@vm.inferred-type.metadata=dart.core::_Double?] d.{self::Interface::returnBoxedNullableIntOrDouble}(null){(self::X*) →* dynamic});
- self::use([@vm.inferred-type.metadata=#lib::X?] d.{self::Interface::returnBoxedNullableX}(null){(self::X*) →* dynamic});
- self::use([@vm.inferred-type.metadata=#lib::X] d.{self::Interface::returnBoxedX}(null){(self::X*) →* dynamic});
- self::use(d.{self::Interface::takePositional}{(core::int*, dynamic, dynamic, dynamic, dynamic, dynamic, dynamic, dynamic, dynamic) →* void});
- self::use(d.{self::Interface::returnUnboxedSmi}{(self::X*) →* dynamic});
- self::use(d.{self::Interface::returnUnboxedInt}{(self::X*) →* dynamic});
- self::use(d.{self::Interface::returnUnboxedDouble}{(self::X*) →* dynamic});
- self::use(d.{self::Interface::returnBoxedNullableInt}{(self::X*) →* dynamic});
- self::use(d.{self::Interface::returnBoxedNullableDouble}{(self::X*) →* dynamic});
- self::use(d.{self::Interface::returnBoxedIntOrDouble}{(self::X*) →* dynamic});
- self::use(d.{self::Interface::returnBoxedNullableIntOrDouble}{(self::X*) →* dynamic});
- self::use(d.{self::Interface::returnBoxedNullableX}{(self::X*) →* dynamic});
- self::use(d.{self::Interface::returnBoxedX}{(self::X*) →* dynamic});
+ final core::List<core::Object> values = [@vm.inferred-type.metadata=dart.core::_GrowableList<dart.core::Object>] core::_GrowableList::_literal3<core::Object>(new self::Impl1::•(), new self::BaseImpl2::•(), new self::SubImpl3::•());
+ final self::Impl1 a = [@vm.direct-call.metadata=dart.core::_GrowableList.[]] [@vm.inferred-type.metadata=!? (skip check)] values.{core::List::[]}([@vm.inferred-type.metadata=int?] core::int::parse("0")){(core::int) → core::Object} as{ForNonNullableByDefault} self::Impl1;
+ final self::BaseImpl2 b = [@vm.direct-call.metadata=dart.core::_GrowableList.[]] [@vm.inferred-type.metadata=!? (skip check)] values.{core::List::[]}([@vm.inferred-type.metadata=int?] core::int::parse("1")){(core::int) → core::Object} as{ForNonNullableByDefault} self::BaseImpl2;
+ final self::SubImpl3 c = [@vm.direct-call.metadata=dart.core::_GrowableList.[]] [@vm.inferred-type.metadata=!? (skip check)] values.{core::List::[]}([@vm.inferred-type.metadata=int?] core::int::parse("2")){(core::int) → core::Object} as{ForNonNullableByDefault} self::SubImpl3;
+ final self::Interface d = [@vm.direct-call.metadata=dart.core::_GrowableList.[]] [@vm.inferred-type.metadata=!? (skip check)] values.{core::List::[]}([@vm.inferred-type.metadata=int?] core::int::parse("2")){(core::int) → core::Object} as{ForNonNullableByDefault} self::Interface;
+ [@vm.direct-call.metadata=#lib::Impl1.takePositional??] [@vm.inferred-type.metadata=!? (skip check)] a.{self::Impl1::takePositional}(1, 1, 1.1, null, null, 1, null, null, new self::X::•()){(core::int?, dynamic, dynamic, dynamic, dynamic, dynamic, dynamic, dynamic, dynamic) → void};
+ b.{self::BaseImpl2::takePositional}(2, 2, 2.2, 2, 2.2, 2.2, 2, new self::X::•(), new self::X::•()){(core::int?, dynamic, dynamic, dynamic, dynamic, dynamic, dynamic, dynamic, dynamic) → void};
+ [@vm.direct-call.metadata=#lib::SubImpl3.takePositional??] [@vm.inferred-type.metadata=!? (skip check)] c.{self::SubImpl3::takePositional}(3, [@vm.inferred-type.metadata=int] self::mint, 3.3, [@vm.inferred-type.metadata=int] self::mint, 3.3, 3.3, 3.3, new self::X::•(), new self::X::•()){(core::int?, dynamic, dynamic, dynamic, dynamic, dynamic, dynamic, dynamic, dynamic) → void};
+ d.{self::Interface::takePositional}(3, [@vm.inferred-type.metadata=int] self::mint, 3.3, [@vm.inferred-type.metadata=int] self::mint, 3.3, 3.3, 3.3, new self::X::•(), new self::X::•()){(core::int?, dynamic, dynamic, dynamic, dynamic, dynamic, dynamic, dynamic, dynamic) → void};
+ self::use([@vm.direct-call.metadata=#lib::Impl1.returnUnboxedSmi] [@vm.inferred-type.metadata=dart.core::_Smi (skip check) (value: 1)] a.{self::Impl1::returnUnboxedSmi}(null){(self::X?) → dynamic});
+ self::use([@vm.direct-call.metadata=#lib::Impl1.returnUnboxedInt] [@vm.inferred-type.metadata=dart.core::_Smi (skip check) (value: 1)] a.{self::Impl1::returnUnboxedInt}(null){(self::X?) → dynamic});
+ self::use([@vm.direct-call.metadata=#lib::Impl1.returnUnboxedDouble] [@vm.inferred-type.metadata=dart.core::_Double (skip check) (value: 1.1)] a.{self::Impl1::returnUnboxedDouble}(null){(self::X?) → dynamic});
+ self::use([@vm.direct-call.metadata=#lib::Impl1.returnBoxedNullableInt] [@vm.inferred-type.metadata=dart.core::Null? (skip check) (value: null)] a.{self::Impl1::returnBoxedNullableInt}(null){(self::X?) → dynamic});
+ self::use([@vm.direct-call.metadata=#lib::Impl1.returnBoxedNullableDouble] [@vm.inferred-type.metadata=dart.core::Null? (skip check) (value: null)] a.{self::Impl1::returnBoxedNullableDouble}(null){(self::X?) → dynamic});
+ self::use([@vm.direct-call.metadata=#lib::Impl1.returnBoxedIntOrDouble] [@vm.inferred-type.metadata=dart.core::_Smi (skip check) (value: 1)] a.{self::Impl1::returnBoxedIntOrDouble}(null){(self::X?) → dynamic});
+ self::use([@vm.direct-call.metadata=#lib::Impl1.returnBoxedNullableIntOrDouble] [@vm.inferred-type.metadata=dart.core::Null? (skip check) (value: null)] a.{self::Impl1::returnBoxedNullableIntOrDouble}(null){(self::X?) → dynamic});
+ self::use([@vm.direct-call.metadata=#lib::Impl1.returnBoxedNullableX] [@vm.inferred-type.metadata=dart.core::Null? (skip check) (value: null)] a.{self::Impl1::returnBoxedNullableX}(null){(self::X?) → dynamic});
+ self::use([@vm.direct-call.metadata=#lib::Impl1.returnBoxedX] [@vm.inferred-type.metadata=#lib::X (skip check)] a.{self::Impl1::returnBoxedX}(null){(self::X?) → dynamic});
+ self::use([@vm.inferred-type.metadata=dart.core::_Smi] b.{self::BaseImpl2::returnUnboxedSmi}(null){(self::X?) → dynamic});
+ self::use([@vm.inferred-type.metadata=int] b.{self::BaseImpl2::returnUnboxedInt}(null){(self::X?) → dynamic});
+ self::use([@vm.inferred-type.metadata=dart.core::_Double] b.{self::BaseImpl2::returnUnboxedDouble}(null){(self::X?) → dynamic});
+ self::use([@vm.inferred-type.metadata=int] b.{self::BaseImpl2::returnBoxedNullableInt}(null){(self::X?) → dynamic});
+ self::use([@vm.inferred-type.metadata=dart.core::_Double] b.{self::BaseImpl2::returnBoxedNullableDouble}(null){(self::X?) → dynamic});
+ self::use([@vm.inferred-type.metadata=dart.core::_Double] b.{self::BaseImpl2::returnBoxedIntOrDouble}(null){(self::X?) → dynamic});
+ self::use([@vm.inferred-type.metadata=!] b.{self::BaseImpl2::returnBoxedNullableIntOrDouble}(null){(self::X?) → dynamic});
+ self::use([@vm.inferred-type.metadata=#lib::X] b.{self::BaseImpl2::returnBoxedNullableX}(null){(self::X?) → dynamic});
+ self::use([@vm.inferred-type.metadata=#lib::X] b.{self::BaseImpl2::returnBoxedX}(null){(self::X?) → dynamic});
+ self::use([@vm.direct-call.metadata=#lib::SubImpl3.returnUnboxedSmi] [@vm.inferred-type.metadata=dart.core::_Smi (skip check) (value: 3)] c.{self::SubImpl3::returnUnboxedSmi}(null){(self::X?) → dynamic});
+ self::use([@vm.direct-call.metadata=#lib::SubImpl3.returnUnboxedInt] [@vm.inferred-type.metadata=int (skip check)] c.{self::SubImpl3::returnUnboxedInt}(null){(self::X?) → dynamic});
+ self::use([@vm.direct-call.metadata=#lib::SubImpl3.returnUnboxedDouble] [@vm.inferred-type.metadata=dart.core::_Double (skip check) (value: 3.3)] c.{self::SubImpl3::returnUnboxedDouble}(null){(self::X?) → dynamic});
+ self::use([@vm.direct-call.metadata=#lib::SubImpl3.returnBoxedNullableInt] [@vm.inferred-type.metadata=int (skip check)] c.{self::SubImpl3::returnBoxedNullableInt}(null){(self::X?) → dynamic});
+ self::use([@vm.direct-call.metadata=#lib::SubImpl3.returnBoxedNullableDouble] [@vm.inferred-type.metadata=dart.core::_Double (skip check) (value: 3.3)] c.{self::SubImpl3::returnBoxedNullableDouble}(null){(self::X?) → dynamic});
+ self::use([@vm.direct-call.metadata=#lib::SubImpl3.returnBoxedIntOrDouble] [@vm.inferred-type.metadata=dart.core::_Double (skip check) (value: 3.3)] c.{self::SubImpl3::returnBoxedIntOrDouble}(null){(self::X?) → dynamic});
+ self::use([@vm.direct-call.metadata=#lib::SubImpl3.returnBoxedNullableIntOrDouble] [@vm.inferred-type.metadata=dart.core::_Double (skip check) (value: 3.3)] c.{self::SubImpl3::returnBoxedNullableIntOrDouble}(null){(self::X?) → dynamic});
+ self::use([@vm.direct-call.metadata=#lib::SubImpl3.returnBoxedNullableX] [@vm.inferred-type.metadata=#lib::X (skip check)] c.{self::SubImpl3::returnBoxedNullableX}(null){(self::X?) → dynamic});
+ self::use([@vm.direct-call.metadata=#lib::SubImpl3.returnBoxedX] [@vm.inferred-type.metadata=#lib::X (skip check)] c.{self::SubImpl3::returnBoxedX}(null){(self::X?) → dynamic});
+ self::use([@vm.inferred-type.metadata=dart.core::_Smi] d.{self::Interface::returnUnboxedSmi}(null){(self::X?) → dynamic});
+ self::use([@vm.inferred-type.metadata=int] d.{self::Interface::returnUnboxedInt}(null){(self::X?) → dynamic});
+ self::use([@vm.inferred-type.metadata=dart.core::_Double] d.{self::Interface::returnUnboxedDouble}(null){(self::X?) → dynamic});
+ self::use([@vm.inferred-type.metadata=int?] d.{self::Interface::returnBoxedNullableInt}(null){(self::X?) → dynamic});
+ self::use([@vm.inferred-type.metadata=dart.core::_Double?] d.{self::Interface::returnBoxedNullableDouble}(null){(self::X?) → dynamic});
+ self::use([@vm.inferred-type.metadata=!] d.{self::Interface::returnBoxedIntOrDouble}(null){(self::X?) → dynamic});
+ self::use([@vm.inferred-type.metadata=dart.core::_Double?] d.{self::Interface::returnBoxedNullableIntOrDouble}(null){(self::X?) → dynamic});
+ self::use([@vm.inferred-type.metadata=#lib::X?] d.{self::Interface::returnBoxedNullableX}(null){(self::X?) → dynamic});
+ self::use([@vm.inferred-type.metadata=#lib::X] d.{self::Interface::returnBoxedX}(null){(self::X?) → dynamic});
+ self::use(d.{self::Interface::takePositional}{(core::int?, dynamic, dynamic, dynamic, dynamic, dynamic, dynamic, dynamic, dynamic) → void});
+ self::use(d.{self::Interface::returnUnboxedSmi}{(self::X?) → dynamic});
+ self::use(d.{self::Interface::returnUnboxedInt}{(self::X?) → dynamic});
+ self::use(d.{self::Interface::returnUnboxedDouble}{(self::X?) → dynamic});
+ self::use(d.{self::Interface::returnBoxedNullableInt}{(self::X?) → dynamic});
+ self::use(d.{self::Interface::returnBoxedNullableDouble}{(self::X?) → dynamic});
+ self::use(d.{self::Interface::returnBoxedIntOrDouble}{(self::X?) → dynamic});
+ self::use(d.{self::Interface::returnBoxedNullableIntOrDouble}{(self::X?) → dynamic});
+ self::use(d.{self::Interface::returnBoxedNullableX}{(self::X?) → dynamic});
+ self::use(d.{self::Interface::returnBoxedX}{(self::X?) → dynamic});
}
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/unboxed_static_method.dart b/pkg/vm/testcases/transformations/type_flow/transformer/unboxed_static_method.dart
index 0142249..3522029 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/unboxed_static_method.dart
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/unboxed_static_method.dart
@@ -2,8 +2,6 @@
// for 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.9
-
final bool kTrue = int.parse('1') == 1 ? true : false;
final bool kFalse = int.parse('1') == 2 ? true : false;
int get mint => 0xaabbccddaabbccdd;
@@ -17,7 +15,7 @@
class X {}
void takePositional(
- int unboxedSmi,
+ int? unboxedSmi,
dynamic unboxedInt,
dynamic unboxedDouble,
dynamic boxedNullableInt,
@@ -37,7 +35,7 @@
}
void takeOptional(
- [int unboxedSmi,
+ [int? unboxedSmi,
dynamic unboxedInt,
dynamic unboxedDouble,
dynamic boxedNullableInt,
@@ -57,7 +55,7 @@
}
void takeNamed(
- {int unboxedSmi,
+ {int? unboxedSmi,
dynamic unboxedInt,
dynamic unboxedDouble,
dynamic boxedNullableInt,
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/unboxed_static_method.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/unboxed_static_method.dart.expect
index 2577681..3615da2 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/unboxed_static_method.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/unboxed_static_method.dart.expect
@@ -1,19 +1,19 @@
-library #lib;
+library #lib /*isNonNullableByDefault*/;
import self as self;
import "dart:core" as core;
class X extends core::Object {
- synthetic constructor •() → self::X*
+ synthetic constructor •() → self::X
: super core::Object::•()
;
}
-[@vm.inferred-type.metadata=dart.core::bool?]static final field core::bool* kTrue = [@vm.inferred-type.metadata=dart.core::bool] [@vm.inferred-type.metadata=int?] core::int::parse("1") =={core::num::==}{(core::Object*) →* core::bool*} 1 ?{core::bool*} true : false;
-[@vm.inferred-type.metadata=dart.core::bool?]static final field core::bool* kFalse = [@vm.inferred-type.metadata=dart.core::bool] [@vm.inferred-type.metadata=int?] core::int::parse("1") =={core::num::==}{(core::Object*) →* core::bool*} 2 ?{core::bool*} true : false;
+[@vm.inferred-type.metadata=dart.core::bool?]static final field core::bool kTrue = [@vm.inferred-type.metadata=dart.core::bool] [@vm.inferred-type.metadata=int?] core::int::parse("1") =={core::num::==}{(core::Object) → core::bool} 1 ?{core::bool} true : false;
+[@vm.inferred-type.metadata=dart.core::bool?]static final field core::bool kFalse = [@vm.inferred-type.metadata=dart.core::bool] [@vm.inferred-type.metadata=int?] core::int::parse("1") =={core::num::==}{(core::Object) → core::bool} 2 ?{core::bool} true : false;
static field dynamic usedObject;
-[@vm.unboxing-info.metadata=()->i]static get mint() → core::int*
+[@vm.unboxing-info.metadata=()->i]static get mint() → core::int
return -6144092014192636707;
-[@vm.unboxing-info.metadata=()->i]static get smiOrMint() → core::int*
- return [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::int*} 1 : [@vm.inferred-type.metadata=int] self::mint;
+[@vm.unboxing-info.metadata=()->i]static get smiOrMint() → core::int
+ return [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::int} 1 : [@vm.inferred-type.metadata=int] self::mint;
static method use(dynamic object) → void {
self::usedObject == null ?{dynamic} self::usedObject = object : null;
}
@@ -48,33 +48,33 @@
self::use(boxedX);
}
[@vm.unboxing-info.metadata=()->i]static method returnUnboxedSmi() → dynamic
- return [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::int*} 1 : 2;
+ return [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::int} 1 : 2;
[@vm.unboxing-info.metadata=()->i]static method returnUnboxedInt() → dynamic
- return [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::int*} [@vm.inferred-type.metadata=int] self::smiOrMint : 2;
+ return [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::int} [@vm.inferred-type.metadata=int] self::smiOrMint : 2;
[@vm.unboxing-info.metadata=()->d]static method returnUnboxedDouble() → dynamic
- return [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::double*} 1.1 : 2.2;
+ return [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::double} 1.1 : 2.2;
static method returnBoxedNullableInt() → dynamic
- return [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::int*} [@vm.inferred-type.metadata=int] self::smiOrMint : null;
+ return [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::int?} [@vm.inferred-type.metadata=int] self::smiOrMint : null;
static method returnBoxedNullableDouble() → dynamic
- return [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::double*} 1.1 : null;
+ return [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::double?} 1.1 : null;
static method returnBoxedIntOrDouble() → dynamic
- return [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::num*} [@vm.inferred-type.metadata=int] self::smiOrMint : 1.1;
+ return [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::num} [@vm.inferred-type.metadata=int] self::smiOrMint : 1.1;
static method returnBoxedNullableIntOrDouble() → dynamic
- return [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::num*} [@vm.inferred-type.metadata=dart.core::bool?] self::kFalse ?{core::num*} [@vm.inferred-type.metadata=int] self::smiOrMint : 1.1 : null;
+ return [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::num?} [@vm.inferred-type.metadata=dart.core::bool?] self::kFalse ?{core::num} [@vm.inferred-type.metadata=int] self::smiOrMint : 1.1 : null;
static method returnBoxedNullableX() → dynamic
- return [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{self::X*} new self::X::•() : null;
+ return [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{self::X?} new self::X::•() : null;
static method returnBoxedX() → dynamic
return new self::X::•();
@#C3
-static method returnBoxedSmiFromEntryPoint() → core::int*
- return [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::int*} 1 : 2;
+static method returnBoxedSmiFromEntryPoint() → core::int
+ return [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::int} 1 : 2;
@#C3
-static method takeBoxedSmiFromEntryPoint(core::int* value) → void {}
+static method takeBoxedSmiFromEntryPoint(core::int value) → void {}
static method main() → dynamic {
- let final core::int* #t1 = [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::int*} 1 : 2 in let final core::int* #t2 = [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::int*} [@vm.inferred-type.metadata=int] self::smiOrMint : 2 in let final core::double* #t3 = [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::double*} 1.1 : 2.2 in let final core::int* #t4 = [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::int*} [@vm.inferred-type.metadata=int] self::smiOrMint : null in let final core::double* #t5 = [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::double*} 1.1 : null in let final core::num* #t6 = [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::num*} [@vm.inferred-type.metadata=int] self::smiOrMint : 1.1 in let final core::num* #t7 = [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::num*} [@vm.inferred-type.metadata=dart.core::bool?] self::kFalse ?{core::num*} [@vm.inferred-type.metadata=int] self::smiOrMint : 1.1 : null in let final self::X* #t8 = [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{self::X*} new self::X::•() : null in let final self::X* #t9 = new self::X::•() in self::takePositional(#t2, #t3, #t4, #t5, #t6, #t7, #t8, #t9);
- let final core::int* #t10 = [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::int*} 1 : 2 in let final core::int* #t11 = [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::int*} [@vm.inferred-type.metadata=int] self::smiOrMint : 2 in let final core::double* #t12 = [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::double*} 1.1 : 2.2 in let final core::int* #t13 = [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::int*} [@vm.inferred-type.metadata=int] self::smiOrMint : null in let final core::double* #t14 = [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::double*} 1.1 : null in let final core::num* #t15 = [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::num*} [@vm.inferred-type.metadata=int] self::smiOrMint : 1.1 in let final core::num* #t16 = [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::num*} [@vm.inferred-type.metadata=dart.core::bool?] self::kFalse ?{core::num*} [@vm.inferred-type.metadata=int] self::smiOrMint : 1.1 : null in let final self::X* #t17 = [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{self::X*} new self::X::•() : null in let final self::X* #t18 = new self::X::•() in self::takeOptional(#t11, #t12, #t13, #t14, #t15, #t16, #t17, #t18);
- let final core::int* #t19 = [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::int*} 1 : 2 in let final core::int* #t20 = [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::int*} [@vm.inferred-type.metadata=int] self::smiOrMint : 2 in let final core::double* #t21 = [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::double*} 1.1 : 2.2 in let final core::int* #t22 = [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::int*} [@vm.inferred-type.metadata=int] self::smiOrMint : null in let final core::double* #t23 = [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::double*} 1.1 : null in let final core::num* #t24 = [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::num*} [@vm.inferred-type.metadata=int] self::smiOrMint : 1.1 in let final core::num* #t25 = [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::num*} [@vm.inferred-type.metadata=dart.core::bool?] self::kFalse ?{core::num*} [@vm.inferred-type.metadata=int] self::smiOrMint : 1.1 : null in let final self::X* #t26 = [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{self::X*} new self::X::•() : null in let final self::X* #t27 = new self::X::•() in self::takeNamed(#t24, #t23, #t22, #t25, #t26, #t27, #t21, #t20);
- self::takeBoxedSmiFromEntryPoint([@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::int*} 1 : 2);
+ let final core::int #t1 = [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::int} 1 : 2 in let final core::int #t2 = [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::int} [@vm.inferred-type.metadata=int] self::smiOrMint : 2 in let final core::double #t3 = [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::double} 1.1 : 2.2 in let final core::int? #t4 = [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::int?} [@vm.inferred-type.metadata=int] self::smiOrMint : null in let final core::double? #t5 = [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::double?} 1.1 : null in let final core::num #t6 = [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::num} [@vm.inferred-type.metadata=int] self::smiOrMint : 1.1 in let final core::num? #t7 = [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::num?} [@vm.inferred-type.metadata=dart.core::bool?] self::kFalse ?{core::num} [@vm.inferred-type.metadata=int] self::smiOrMint : 1.1 : null in let final self::X? #t8 = [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{self::X?} new self::X::•() : null in let final self::X #t9 = new self::X::•() in self::takePositional(#t2, #t3, #t4, #t5, #t6, #t7, #t8, #t9);
+ let final core::int #t10 = [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::int} 1 : 2 in let final core::int #t11 = [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::int} [@vm.inferred-type.metadata=int] self::smiOrMint : 2 in let final core::double #t12 = [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::double} 1.1 : 2.2 in let final core::int? #t13 = [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::int?} [@vm.inferred-type.metadata=int] self::smiOrMint : null in let final core::double? #t14 = [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::double?} 1.1 : null in let final core::num #t15 = [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::num} [@vm.inferred-type.metadata=int] self::smiOrMint : 1.1 in let final core::num? #t16 = [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::num?} [@vm.inferred-type.metadata=dart.core::bool?] self::kFalse ?{core::num} [@vm.inferred-type.metadata=int] self::smiOrMint : 1.1 : null in let final self::X? #t17 = [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{self::X?} new self::X::•() : null in let final self::X #t18 = new self::X::•() in self::takeOptional(#t11, #t12, #t13, #t14, #t15, #t16, #t17, #t18);
+ let final core::int #t19 = [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::int} 1 : 2 in let final core::int #t20 = [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::int} [@vm.inferred-type.metadata=int] self::smiOrMint : 2 in let final core::double #t21 = [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::double} 1.1 : 2.2 in let final core::int? #t22 = [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::int?} [@vm.inferred-type.metadata=int] self::smiOrMint : null in let final core::double? #t23 = [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::double?} 1.1 : null in let final core::num #t24 = [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::num} [@vm.inferred-type.metadata=int] self::smiOrMint : 1.1 in let final core::num? #t25 = [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::num?} [@vm.inferred-type.metadata=dart.core::bool?] self::kFalse ?{core::num} [@vm.inferred-type.metadata=int] self::smiOrMint : 1.1 : null in let final self::X? #t26 = [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{self::X?} new self::X::•() : null in let final self::X #t27 = new self::X::•() in self::takeNamed(#t24, #t23, #t22, #t25, #t26, #t27, #t21, #t20);
+ self::takeBoxedSmiFromEntryPoint([@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::int} 1 : 2);
self::use([@vm.inferred-type.metadata=dart.core::_Smi] self::returnUnboxedSmi());
self::use([@vm.inferred-type.metadata=int] self::returnUnboxedInt());
self::use([@vm.inferred-type.metadata=dart.core::_Double] self::returnUnboxedDouble());
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/unboxed_static_method_tearoff.dart b/pkg/vm/testcases/transformations/type_flow/transformer/unboxed_static_method_tearoff.dart
index 6245c0d..21788ee 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/unboxed_static_method_tearoff.dart
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/unboxed_static_method_tearoff.dart
@@ -2,8 +2,6 @@
// for 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.9
-
final bool kTrue = int.parse('1') == 1 ? true : false;
final bool kFalse = int.parse('1') == 2 ? true : false;
int get mint => 0xaabbccddaabbccdd;
@@ -17,7 +15,7 @@
class X {}
void takePositional(
- int unboxedSmi,
+ int? unboxedSmi,
dynamic unboxedInt,
dynamic unboxedDouble,
dynamic boxedNullableInt,
@@ -37,7 +35,7 @@
}
void takeOptional(
- [int unboxedSmi,
+ [int? unboxedSmi,
dynamic unboxedInt,
dynamic unboxedDouble,
dynamic boxedNullableInt,
@@ -57,7 +55,7 @@
}
void takeNamed(
- {int unboxedSmi,
+ {int? unboxedSmi,
dynamic unboxedInt,
dynamic unboxedDouble,
dynamic boxedNullableInt,
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/unboxed_static_method_tearoff.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/unboxed_static_method_tearoff.dart.expect
index 8167df0..3ab3d19 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/unboxed_static_method_tearoff.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/unboxed_static_method_tearoff.dart.expect
@@ -1,23 +1,23 @@
-library #lib;
+library #lib /*isNonNullableByDefault*/;
import self as self;
import "dart:core" as core;
class X extends core::Object {
- synthetic constructor •() → self::X*
+ synthetic constructor •() → self::X
: super core::Object::•()
;
}
-[@vm.inferred-type.metadata=dart.core::bool?]static final field core::bool* kTrue = [@vm.inferred-type.metadata=dart.core::bool] [@vm.inferred-type.metadata=int?] core::int::parse("1") =={core::num::==}{(core::Object*) →* core::bool*} 1 ?{core::bool*} true : false;
-[@vm.inferred-type.metadata=dart.core::bool?]static final field core::bool* kFalse = [@vm.inferred-type.metadata=dart.core::bool] [@vm.inferred-type.metadata=int?] core::int::parse("1") =={core::num::==}{(core::Object*) →* core::bool*} 2 ?{core::bool*} true : false;
+[@vm.inferred-type.metadata=dart.core::bool?]static final field core::bool kTrue = [@vm.inferred-type.metadata=dart.core::bool] [@vm.inferred-type.metadata=int?] core::int::parse("1") =={core::num::==}{(core::Object) → core::bool} 1 ?{core::bool} true : false;
+[@vm.inferred-type.metadata=dart.core::bool?]static final field core::bool kFalse = [@vm.inferred-type.metadata=dart.core::bool] [@vm.inferred-type.metadata=int?] core::int::parse("1") =={core::num::==}{(core::Object) → core::bool} 2 ?{core::bool} true : false;
static field dynamic usedObject;
-[@vm.unboxing-info.metadata=()->i]static get mint() → core::int*
+[@vm.unboxing-info.metadata=()->i]static get mint() → core::int
return -6144092014192636707;
-[@vm.unboxing-info.metadata=()->i]static get smiOrMint() → core::int*
- return [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::int*} 1 : [@vm.inferred-type.metadata=int] self::mint;
+[@vm.unboxing-info.metadata=()->i]static get smiOrMint() → core::int
+ return [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::int} 1 : [@vm.inferred-type.metadata=int] self::mint;
static method use(dynamic object) → void {
self::usedObject == null ?{dynamic} self::usedObject = object : null;
}
-static method takePositional(core::int* unboxedSmi, dynamic unboxedInt, dynamic unboxedDouble, dynamic boxedNullableInt, dynamic boxedNullableDouble, dynamic boxedIntOrDouble, dynamic boxedNullableIntOrDouble, dynamic boxedNullableX, dynamic boxedX) → void {
+static method takePositional(core::int? unboxedSmi, dynamic unboxedInt, dynamic unboxedDouble, dynamic boxedNullableInt, dynamic boxedNullableDouble, dynamic boxedIntOrDouble, dynamic boxedNullableIntOrDouble, dynamic boxedNullableX, dynamic boxedX) → void {
self::use(unboxedInt);
self::use(unboxedDouble);
self::use(boxedNullableInt);
@@ -27,7 +27,7 @@
self::use(boxedNullableX);
self::use(boxedX);
}
-static method takeOptional([core::int* unboxedSmi = #C1, dynamic unboxedInt = #C1, dynamic unboxedDouble = #C1, dynamic boxedNullableInt = #C1, dynamic boxedNullableDouble = #C1, dynamic boxedIntOrDouble = #C1, dynamic boxedNullableIntOrDouble = #C1, dynamic boxedNullableX = #C1, dynamic boxedX = #C1]) → void {
+static method takeOptional([core::int? unboxedSmi = #C1, dynamic unboxedInt = #C1, dynamic unboxedDouble = #C1, dynamic boxedNullableInt = #C1, dynamic boxedNullableDouble = #C1, dynamic boxedIntOrDouble = #C1, dynamic boxedNullableIntOrDouble = #C1, dynamic boxedNullableX = #C1, dynamic boxedX = #C1]) → void {
self::use(unboxedInt);
self::use(unboxedDouble);
self::use(boxedNullableInt);
@@ -37,7 +37,7 @@
self::use(boxedNullableX);
self::use(boxedX);
}
-static method takeNamed({core::int* unboxedSmi = #C1, dynamic unboxedInt = #C1, dynamic unboxedDouble = #C1, dynamic boxedNullableInt = #C1, dynamic boxedNullableDouble = #C1, dynamic boxedIntOrDouble = #C1, dynamic boxedNullableIntOrDouble = #C1, dynamic boxedNullableX = #C1, dynamic boxedX = #C1}) → void {
+static method takeNamed({core::int? unboxedSmi = #C1, dynamic unboxedInt = #C1, dynamic unboxedDouble = #C1, dynamic boxedNullableInt = #C1, dynamic boxedNullableDouble = #C1, dynamic boxedIntOrDouble = #C1, dynamic boxedNullableIntOrDouble = #C1, dynamic boxedNullableX = #C1, dynamic boxedX = #C1}) → void {
self::use(unboxedInt);
self::use(unboxedDouble);
self::use(boxedNullableInt);
@@ -48,27 +48,27 @@
self::use(boxedX);
}
[@vm.unboxing-info.metadata=()->i]static method returnUnboxedSmi() → dynamic
- return [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::int*} 1 : 2;
+ return [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::int} 1 : 2;
[@vm.unboxing-info.metadata=()->i]static method returnUnboxedInt() → dynamic
- return [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::int*} [@vm.inferred-type.metadata=int] self::smiOrMint : 2;
+ return [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::int} [@vm.inferred-type.metadata=int] self::smiOrMint : 2;
[@vm.unboxing-info.metadata=()->d]static method returnUnboxedDouble() → dynamic
- return [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::double*} 1.1 : 2.2;
+ return [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::double} 1.1 : 2.2;
static method returnBoxedNullableInt() → dynamic
- return [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::int*} [@vm.inferred-type.metadata=int] self::smiOrMint : null;
+ return [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::int?} [@vm.inferred-type.metadata=int] self::smiOrMint : null;
static method returnBoxedNullableDouble() → dynamic
- return [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::double*} 1.1 : null;
+ return [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::double?} 1.1 : null;
static method returnBoxedIntOrDouble() → dynamic
- return [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::num*} [@vm.inferred-type.metadata=int] self::smiOrMint : 1.1;
+ return [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::num} [@vm.inferred-type.metadata=int] self::smiOrMint : 1.1;
static method returnBoxedNullableIntOrDouble() → dynamic
- return [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::num*} [@vm.inferred-type.metadata=dart.core::bool?] self::kFalse ?{core::num*} [@vm.inferred-type.metadata=int] self::smiOrMint : 1.1 : null;
+ return [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::num?} [@vm.inferred-type.metadata=dart.core::bool?] self::kFalse ?{core::num} [@vm.inferred-type.metadata=int] self::smiOrMint : 1.1 : null;
static method returnBoxedNullableX() → dynamic
- return [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{self::X*} new self::X::•() : null;
+ return [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{self::X?} new self::X::•() : null;
static method returnBoxedX() → dynamic
return new self::X::•();
static method main() → dynamic {
- self::takePositional([@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::int*} 1 : 2, [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::int*} [@vm.inferred-type.metadata=int] self::smiOrMint : 2, [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::double*} 1.1 : 2.2, [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::int*} [@vm.inferred-type.metadata=int] self::smiOrMint : null, [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::double*} 1.1 : null, [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::num*} [@vm.inferred-type.metadata=int] self::smiOrMint : 1.1, [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::num*} [@vm.inferred-type.metadata=dart.core::bool?] self::kFalse ?{core::num*} [@vm.inferred-type.metadata=int] self::smiOrMint : 1.1 : null, [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{self::X*} new self::X::•() : null, new self::X::•());
- self::takeOptional([@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::int*} 1 : 2, [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::int*} [@vm.inferred-type.metadata=int] self::smiOrMint : 2, [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::double*} 1.1 : 2.2, [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::int*} [@vm.inferred-type.metadata=int] self::smiOrMint : null, [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::double*} 1.1 : null, [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::num*} [@vm.inferred-type.metadata=int] self::smiOrMint : 1.1, [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::num*} [@vm.inferred-type.metadata=dart.core::bool?] self::kFalse ?{core::num*} [@vm.inferred-type.metadata=int] self::smiOrMint : 1.1 : null, [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{self::X*} new self::X::•() : null, new self::X::•());
- self::takeNamed(unboxedSmi: [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::int*} 1 : 2, unboxedInt: [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::int*} [@vm.inferred-type.metadata=int] self::smiOrMint : 2, unboxedDouble: [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::double*} 1.1 : 2.2, boxedNullableInt: [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::int*} [@vm.inferred-type.metadata=int] self::smiOrMint : null, boxedNullableDouble: [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::double*} 1.1 : null, boxedIntOrDouble: [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::num*} [@vm.inferred-type.metadata=int] self::smiOrMint : 1.1, boxedNullableIntOrDouble: [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::num*} [@vm.inferred-type.metadata=dart.core::bool?] self::kFalse ?{core::num*} [@vm.inferred-type.metadata=int] self::smiOrMint : 1.1 : null, boxedNullableX: [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{self::X*} new self::X::•() : null, boxedX: new self::X::•());
+ self::takePositional([@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::int} 1 : 2, [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::int} [@vm.inferred-type.metadata=int] self::smiOrMint : 2, [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::double} 1.1 : 2.2, [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::int?} [@vm.inferred-type.metadata=int] self::smiOrMint : null, [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::double?} 1.1 : null, [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::num} [@vm.inferred-type.metadata=int] self::smiOrMint : 1.1, [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::num?} [@vm.inferred-type.metadata=dart.core::bool?] self::kFalse ?{core::num} [@vm.inferred-type.metadata=int] self::smiOrMint : 1.1 : null, [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{self::X?} new self::X::•() : null, new self::X::•());
+ self::takeOptional([@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::int} 1 : 2, [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::int} [@vm.inferred-type.metadata=int] self::smiOrMint : 2, [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::double} 1.1 : 2.2, [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::int?} [@vm.inferred-type.metadata=int] self::smiOrMint : null, [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::double?} 1.1 : null, [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::num} [@vm.inferred-type.metadata=int] self::smiOrMint : 1.1, [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::num?} [@vm.inferred-type.metadata=dart.core::bool?] self::kFalse ?{core::num} [@vm.inferred-type.metadata=int] self::smiOrMint : 1.1 : null, [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{self::X?} new self::X::•() : null, new self::X::•());
+ self::takeNamed(unboxedSmi: [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::int} 1 : 2, unboxedInt: [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::int} [@vm.inferred-type.metadata=int] self::smiOrMint : 2, unboxedDouble: [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::double} 1.1 : 2.2, boxedNullableInt: [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::int?} [@vm.inferred-type.metadata=int] self::smiOrMint : null, boxedNullableDouble: [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::double?} 1.1 : null, boxedIntOrDouble: [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::num} [@vm.inferred-type.metadata=int] self::smiOrMint : 1.1, boxedNullableIntOrDouble: [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::num?} [@vm.inferred-type.metadata=dart.core::bool?] self::kFalse ?{core::num} [@vm.inferred-type.metadata=int] self::smiOrMint : 1.1 : null, boxedNullableX: [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{self::X?} new self::X::•() : null, boxedX: new self::X::•());
self::use([@vm.inferred-type.metadata=dart.core::_Smi] self::returnUnboxedSmi());
self::use([@vm.inferred-type.metadata=int] self::returnUnboxedInt());
self::use([@vm.inferred-type.metadata=dart.core::_Double] self::returnUnboxedDouble());
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/write_only_field.dart b/pkg/vm/testcases/transformations/type_flow/transformer/write_only_field.dart
index 0f85cb8..d7b90d8 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/write_only_field.dart
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/write_only_field.dart
@@ -5,15 +5,13 @@
// Tests tree shaking of field initializer for a write-only field.
// Regression test for https://github.com/dart-lang/sdk/issues/35632.
-// @dart=2.9
-
class A {
A() {
print('A');
}
}
-var field = A();
+A? field = A();
class B {
B() {
@@ -22,7 +20,7 @@
}
class C {
- var instanceField = new B();
+ B? instanceField = new B();
}
void main() {
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/write_only_field.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/write_only_field.dart.expect
index cc689dc..e544ddf 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/write_only_field.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/write_only_field.dart.expect
@@ -1,18 +1,18 @@
-library #lib;
+library #lib /*isNonNullableByDefault*/;
import self as self;
import "dart:core" as core;
class B extends core::Object {
- constructor •() → self::B*
+ constructor •() → self::B
: super core::Object::•() {
core::print("B");
}
}
class C extends core::Object {
- synthetic constructor •() → self::C*
+ synthetic constructor •() → self::C
: dynamic #t1 = new self::B::•(), super core::Object::•()
;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1] set instanceField(self::B* value) → void;
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1] set /*isLegacy*/ instanceField(self::B? value) → void;
}
static method main() → void {
null;
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/write_only_field2.dart b/pkg/vm/testcases/transformations/type_flow/transformer/write_only_field2.dart
index ec7e83f..45dd11b 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/write_only_field2.dart
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/write_only_field2.dart
@@ -4,8 +4,6 @@
// Test for tree shaking of write-only fields.
-// @dart=2.9
-
import "package:expect/expect.dart";
foo() {}
@@ -33,12 +31,12 @@
class C<T> {
// Should be replaced with setter.
- T bar;
+ T? bar;
}
class D implements C<int> {
// Should be replaced with setter.
- int bar;
+ int? bar;
}
class E {
@@ -61,7 +59,7 @@
class H {
// Should be replaced with setter.
- int unused6;
+ int? unused6;
}
class I extends H {
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/write_only_field2.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/write_only_field2.dart.expect
index 6e40a3c..057cfe3 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/write_only_field2.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/write_only_field2.dart.expect
@@ -1,4 +1,4 @@
-library #lib;
+library #lib /*isNonNullableByDefault*/;
import self as self;
import "dart:core" as core;
import "package:expect/expect.dart" as exp;
@@ -6,45 +6,45 @@
import "package:expect/expect.dart";
class A extends core::Object {
- synthetic constructor •() → self::A*
+ synthetic constructor •() → self::A
: dynamic #t1 = [@vm.inferred-type.metadata=dart.core::Null? (value: null)] self::foo(), super core::Object::•()
;
}
class B extends core::Object {
- constructor •() → self::B*
+ constructor •() → self::B
: dynamic #t2 = [@vm.inferred-type.metadata=dart.core::Null? (value: null)] self::foo(), super core::Object::•()
;
}
-abstract class C<T extends core::Object* = dynamic> extends core::Object {
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1] abstract set bar(generic-covariant-impl self::C::T* value) → void;
+abstract class C<T extends core::Object? = dynamic> extends core::Object {
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1] abstract set /*isLegacy*/ bar(generic-covariant-impl self::C::T? value) → void;
}
-class D extends core::Object implements self::C<core::int*> {
- synthetic constructor •() → self::D*
+class D extends core::Object implements self::C<core::int> {
+ synthetic constructor •() → self::D
: super core::Object::•()
;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1] set bar(generic-covariant-impl core::int* value) → void;
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1] set /*isLegacy*/ bar(generic-covariant-impl core::int? value) → void;
}
abstract class E extends core::Object {
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:2] [@vm.unboxing-info.metadata=()->i] abstract get bar() → core::int*;
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:2] [@vm.unboxing-info.metadata=()->i] abstract get /*isLegacy*/ bar() → core::int;
}
class F extends core::Object implements self::E {
- synthetic constructor •() → self::F*
+ synthetic constructor •() → self::F
: super core::Object::•()
;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:2] [@vm.unboxing-info.metadata=()->i] get bar() → core::int*
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:2] [@vm.unboxing-info.metadata=()->i] get bar() → core::int
return 42;
}
class G extends core::Object /*hasConstConstructor*/ {
-[@vm.inferred-type.metadata=dart.core::_Smi] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:3] [@vm.unboxing-info.metadata=()->i] final field core::int* bazz;
+[@vm.inferred-type.metadata=dart.core::_Smi] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:3] [@vm.unboxing-info.metadata=()->i] final field core::int bazz;
}
abstract class H extends core::Object {
- synthetic constructor •() → self::H*
+ synthetic constructor •() → self::H
: super core::Object::•()
;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:4] set unused6(core::int* value) → void;
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:4] set /*isLegacy*/ unused6(core::int? value) → void;
}
class I extends self::H {
- synthetic constructor •() → self::I*
+ synthetic constructor •() → self::I
: super self::H::•()
;
[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:5,getterSelectorId:6] method foo() → dynamic {
@@ -55,14 +55,14 @@
static method main() → void {
new self::A::•();
new self::B::•();
- self::C<core::num*>* c = new self::D::•();
- exp::Expect::throws<dynamic>(() → Null {
- [@vm.call-site-attributes.metadata=receiverType:#lib::C<dart.core::num*>*] [@vm.direct-call.metadata=#lib::D.bar] c.{self::C::bar} = 3.14;
+ self::C<core::num> c = new self::D::•();
+ exp::Expect::throws<dynamic>(() → void {
+ [@vm.call-site-attributes.metadata=receiverType:#lib::C<dart.core::num>] [@vm.direct-call.metadata=#lib::D.bar] c.{self::C::bar} = 3.14;
});
- self::E* e = new self::F::•();
- let final core::int* #t3 = [@vm.direct-call.metadata=#lib::F.bar] [@vm.inferred-type.metadata=dart.core::_Smi (value: 42)] e.{self::E::bar}{core::int*} in exp::Expect::equals();
+ self::E e = new self::F::•();
+ let final core::int #t3 = [@vm.direct-call.metadata=#lib::F.bar] [@vm.inferred-type.metadata=dart.core::_Smi (value: 42)] e.{self::E::bar}{core::int} in exp::Expect::equals();
exp::Expect::isTrue(![@vm.inferred-type.metadata=dart.core::bool] core::identical(#C2, #C4));
- [@vm.direct-call.metadata=#lib::I.foo] [@vm.inferred-type.metadata=!? (skip check)] new self::I::•().{self::I::foo}(){() →* dynamic};
+ [@vm.direct-call.metadata=#lib::I.foo] [@vm.inferred-type.metadata=!? (skip check)] new self::I::•().{self::I::foo}(){() → dynamic};
5;
}
constants {
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/write_only_field3_nnbd.dart b/pkg/vm/testcases/transformations/type_flow/transformer/write_only_field3_nnbd.dart
index ea59290..a777b1b 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/write_only_field3_nnbd.dart
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/write_only_field3_nnbd.dart
@@ -3,9 +3,6 @@
// BSD-style license that can be found in the LICENSE file.
// Test for tree shaking of write-only late fields.
-// This test requires non-nullable experiment.
-
-// @dart = 2.10
foo() {}
diff --git a/pkg/vm/testcases/transformations/unreachable_code_elimination/uce_testcases.dart b/pkg/vm/testcases/transformations/unreachable_code_elimination/uce_testcases.dart
index 41fdccc..33f4458 100644
--- a/pkg/vm/testcases/transformations/unreachable_code_elimination/uce_testcases.dart
+++ b/pkg/vm/testcases/transformations/unreachable_code_elimination/uce_testcases.dart
@@ -2,14 +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.
-// @dart=2.9
-
const bool constTrue = const bool.fromEnvironment('test.define.isTrue');
const bool constFalse = const bool.fromEnvironment('test.define.isFalse');
const bool constTrue2 = !constFalse;
const bool constFalse2 = const bool.fromEnvironment('test.define.notDefined');
-bool foo() => null;
+bool? foo() => null;
void testSimpleConditions() {
if (constTrue) {
@@ -27,10 +25,10 @@
}
void testAndConditions() {
- if (constTrue && foo()) {
+ if (constTrue && foo()!) {
print('1_yes');
}
- if (constFalse && foo()) {
+ if (constFalse && foo()!) {
print('2_no');
}
if (constTrue && constFalse) {
@@ -42,10 +40,10 @@
}
void testOrConditions() {
- if (constTrue || foo()) {
+ if (constTrue || foo()!) {
print('1_yes');
}
- if (constFalse || foo()) {
+ if (constFalse || foo()!) {
print('2_yes');
}
if (constFalse || constFalse2) {
@@ -63,54 +61,54 @@
if (!constFalse) {
print('2_yes');
}
- if (!(!(!constTrue && foo()) || foo())) {
+ if (!(!(!constTrue && foo()!) || foo()!)) {
print('3_no');
}
}
testConditionalExpressions() {
print(!constFalse && constTrue ? '1_yes' : '2_no');
- print(constFalse && foo() ? '3_no' : '4_yes ${foo()}');
+ print(constFalse && foo()! ? '3_no' : '4_yes ${foo()}');
}
void testAsserts() {
- assert(foo());
- assert(!foo(), "oops!");
+ assert(foo()!);
+ assert(!foo()!, "oops!");
}
class TestAssertInitializer {
- TestAssertInitializer() : assert(foo()) {}
+ TestAssertInitializer() : assert(foo()!) {}
}
testRemovalOfStatementBodies() {
- if (foo()) assert(foo());
- while (foo()) assert(foo());
- do assert(foo()); while (foo());
- for (;;) assert(foo());
- for (var i in [1, 2]) assert(foo());
+ if (foo()!) assert(foo()!);
+ while (foo()!) assert(foo()!);
+ do assert(foo()!); while (foo()!);
+ for (;;) assert(foo()!);
+ for (var i in [1, 2]) assert(foo()!);
try {
- assert(foo());
+ assert(foo()!);
} finally {
- assert(foo());
+ assert(foo()!);
}
try {
- assert(foo());
+ assert(foo()!);
} catch (e) {
- assert(foo());
+ assert(foo()!);
}
try {
- assert(foo());
+ assert(foo()!);
} catch (e) {
- assert(foo());
+ assert(foo()!);
rethrow;
}
switch (42) {
case 10:
- assert(foo());
+ assert(foo()!);
}
switch (42) {
default:
- assert(foo());
+ assert(foo()!);
}
}
diff --git a/pkg/vm/testcases/transformations/unreachable_code_elimination/uce_testcases.dart.expect b/pkg/vm/testcases/transformations/unreachable_code_elimination/uce_testcases.dart.expect
index e9346d5..4bf2ed9 100644
--- a/pkg/vm/testcases/transformations/unreachable_code_elimination/uce_testcases.dart.expect
+++ b/pkg/vm/testcases/transformations/unreachable_code_elimination/uce_testcases.dart.expect
@@ -1,26 +1,16 @@
-library #lib;
+library #lib /*isNonNullableByDefault*/;
import self as self;
import "dart:core" as core;
class TestAssertInitializer extends core::Object {
- constructor •() → self::TestAssertInitializer*
+ constructor •() → self::TestAssertInitializer
: super core::Object::•() {}
- abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
- abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
- abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
- abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
- abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
- abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
- abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
- abstract member-signature method toString() → core::String*; -> core::Object::toString
- abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
- abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
}
-static const field core::bool* constTrue = #C1;
-static const field core::bool* constFalse = #C2;
-static const field core::bool* constTrue2 = #C1;
-static const field core::bool* constFalse2 = #C2;
-static method foo() → core::bool*
+static const field core::bool constTrue = #C1;
+static const field core::bool constFalse = #C2;
+static const field core::bool constTrue2 = #C1;
+static const field core::bool constFalse2 = #C2;
+static method foo() → core::bool?
return null;
static method testSimpleConditions() → void {
{
@@ -31,7 +21,7 @@
}
}
static method testAndConditions() → void {
- if((#C1) && self::foo()) {
+ if((#C1) && self::foo()!) {
core::print("1_yes");
}
}
@@ -39,7 +29,7 @@
{
core::print("1_yes");
}
- if((#C2) || self::foo()) {
+ if((#C2) || self::foo()!) {
core::print("2_yes");
}
{
@@ -57,25 +47,25 @@
}
static method testAsserts() → void {}
static method testRemovalOfStatementBodies() → dynamic {
- if(self::foo()) {
+ if(self::foo()!) {
}
- while (self::foo()) {
+ while (self::foo()!) {
}
do {
}
- while (self::foo())
+ while (self::foo()!)
for (; ; ) {
}
{
- core::Iterator<core::int*>* :sync-for-iterator = core::_GrowableList::_literal2<core::int*>(1, 2).{core::Iterable::iterator}{core::Iterator<core::int*>*};
+ core::Iterator<core::int> :sync-for-iterator = core::_GrowableList::_literal2<core::int>(1, 2).{core::Iterable::iterator}{core::Iterator<core::int>};
for (; :sync-for-iterator.{core::Iterator::moveNext}(){() → core::bool}; ) {
- core::int* i = :sync-for-iterator.{core::Iterator::current}{core::int*};
+ core::int i = :sync-for-iterator.{core::Iterator::current}{core::int};
}
}
{}
try {
}
- on dynamic catch(final dynamic e) {
+ on core::Object catch(final core::Object e) {
}
{}
switch(42) {
@@ -89,7 +79,7 @@
{}
}
}
-static method main(core::List<core::String*>* args) → dynamic {
+static method main(core::List<core::String> args) → dynamic {
self::testSimpleConditions();
self::testAndConditions();
self::testOrConditions();
diff --git a/runtime/lib/isolate.cc b/runtime/lib/isolate.cc
index 0ca25ee..0b72f7f 100644
--- a/runtime/lib/isolate.cc
+++ b/runtime/lib/isolate.cc
@@ -19,6 +19,7 @@
#include "vm/lockers.h"
#include "vm/longjump.h"
#include "vm/message_handler.h"
+#include "vm/message_snapshot.h"
#include "vm/object.h"
#include "vm/object_graph_copy.h"
#include "vm/object_store.h"
@@ -123,10 +124,10 @@
new Message(destination_port_id, handle, Message::kNormalPriority));
PortMap::PostMessage(std::move(message));
} else {
- MessageWriter writer(can_send_any_object);
// TODO(turnidge): Throw an exception when the return value is false?
- PortMap::PostMessage(writer.WriteMessage(obj, destination_port_id,
- Message::kNormalPriority));
+ PortMap::PostMessage(WriteMessage(can_send_any_object, obj,
+ destination_port_id,
+ Message::kNormalPriority));
}
}
return Object::null();
@@ -572,8 +573,7 @@
if (message->IsRaw()) {
return Instance::RawCast(message->raw_obj());
} else {
- MessageSnapshotReader reader(message, thread);
- const Object& obj = Object::Handle(zone, reader.ReadObject());
+ const Object& obj = Object::Handle(zone, ReadMessage(thread, message));
ASSERT(!obj.IsError());
return Instance::RawCast(obj.ptr());
}
@@ -792,10 +792,10 @@
isolate->message_handler()->increment_paused();
}
{
- MessageWriter writer(/*can_send_any_object=*/false);
// If parent isolate died, we ignore the fact that we cannot notify it.
- PortMap::PostMessage(writer.WriteMessage(message, state_->parent_port(),
- Message::kNormalPriority));
+ PortMap::PostMessage(WriteMessage(/* can_send_any_object */ false,
+ message, state_->parent_port(),
+ Message::kNormalPriority));
}
return true;
@@ -866,9 +866,9 @@
// serializable this will throw an exception.
SerializedObjectBuffer message_buffer;
{
- MessageWriter writer(/* can_send_any_object = */ true);
- message_buffer.set_message(writer.WriteMessage(
- message, ILLEGAL_PORT, Message::kNormalPriority));
+ message_buffer.set_message(WriteMessage(
+ /* can_send_any_object */ true, message, ILLEGAL_PORT,
+ Message::kNormalPriority));
}
const char* utf8_package_config =
@@ -951,14 +951,14 @@
SerializedObjectBuffer arguments_buffer;
SerializedObjectBuffer message_buffer;
{
- MessageWriter writer(/* can_send_any_object = */ false);
- arguments_buffer.set_message(
- writer.WriteMessage(args, ILLEGAL_PORT, Message::kNormalPriority));
+ arguments_buffer.set_message(WriteMessage(/* can_send_any_object */ false,
+ args, ILLEGAL_PORT,
+ Message::kNormalPriority));
}
{
- MessageWriter writer(/* can_send_any_object = */ false);
- message_buffer.set_message(
- writer.WriteMessage(message, ILLEGAL_PORT, Message::kNormalPriority));
+ message_buffer.set_message(WriteMessage(/* can_send_any_object */ false,
+ message, ILLEGAL_PORT,
+ Message::kNormalPriority));
}
// Canonicalize the uri with respect to the current isolate.
@@ -1031,9 +1031,8 @@
// Ensure message writer (and it's resources, e.g. forwarding tables) are
// cleaned up before handling interrupts.
{
- MessageWriter writer(false);
- PortMap::PostMessage(
- writer.WriteMessage(msg, port.Id(), Message::kOOBPriority));
+ PortMap::PostMessage(WriteMessage(/* can_send_any_object */ false, msg,
+ port.Id(), Message::kOOBPriority));
}
// Drain interrupts before running so any IMMEDIATE operations on the current
diff --git a/runtime/lib/object.cc b/runtime/lib/object.cc
index f172831..10fc93a 100644
--- a/runtime/lib/object.cc
+++ b/runtime/lib/object.cc
@@ -6,6 +6,7 @@
#include "lib/invocation_mirror.h"
#include "vm/code_patcher.h"
+#include "vm/dart_entry.h"
#include "vm/exceptions.h"
#include "vm/heap/heap.h"
#include "vm/native_entry.h"
diff --git a/runtime/lib/vmservice.cc b/runtime/lib/vmservice.cc
index 44d6148..51ff5ea 100644
--- a/runtime/lib/vmservice.cc
+++ b/runtime/lib/vmservice.cc
@@ -11,6 +11,7 @@
#include "vm/kernel_isolate.h"
#include "vm/message.h"
#include "vm/message_handler.h"
+#include "vm/message_snapshot.h"
#include "vm/native_entry.h"
#include "vm/object.h"
#include "vm/port.h"
@@ -59,10 +60,10 @@
Smi::Handle(thread->zone(), Smi::New(Message::kServiceOOBMsg)));
// Serialize message.
- MessageWriter writer(false);
// TODO(turnidge): Throw an exception when the return value is false?
- bool result = PortMap::PostMessage(
- writer.WriteMessage(message, sp.Id(), Message::kOOBPriority));
+ bool result = PortMap::PostMessage(WriteMessage(
+ /* can_send_any_object */ false, message, sp.Id(),
+ Message::kOOBPriority));
return Bool::Get(result).ptr();
#else
return Object::null();
diff --git a/runtime/tools/dartfuzz/dartfuzz_test.dart b/runtime/tools/dartfuzz/dartfuzz_test.dart
index 639935b..fb826ff 100644
--- a/runtime/tools/dartfuzz/dartfuzz_test.dart
+++ b/runtime/tools/dartfuzz/dartfuzz_test.dart
@@ -420,7 +420,6 @@
timeoutSeeds.add(seed);
break;
default:
- reportDivergence(result1, result2);
// Both had an error.
numSkipped++;
skippedSeeds.add(seed);
@@ -472,9 +471,7 @@
var report = generateReport(result1, result2);
print('\n$isolate: !DIVERGENCE! $version:$seed ($report)');
if (result1.exitCode == result2.exitCode) {
- if (result1.exitCode == 254) {
- print('\ncompile-time error:\n${result1.output}\n${result1.stderr}\n');
- } else if (numOutputLines > 0) {
+ if (numOutputLines > 0) {
// Only report the actual output divergence details up to
// numOutputLines, since this output may be lengthy and should be
// reproducable anyway.
diff --git a/runtime/vm/allocation.cc b/runtime/vm/allocation.cc
index aa36221..4239026 100644
--- a/runtime/vm/allocation.cc
+++ b/runtime/vm/allocation.cc
@@ -24,7 +24,6 @@
}
void* ZoneAllocated::operator new(uword size, Zone* zone) {
- ASSERT(Thread::Current()->ZoneIsOwnedByThread(zone));
return Allocate(size, zone);
}
diff --git a/runtime/vm/benchmark_test.cc b/runtime/vm/benchmark_test.cc
index e2a6869..2b5683b 100644
--- a/runtime/vm/benchmark_test.cc
+++ b/runtime/vm/benchmark_test.cc
@@ -18,6 +18,7 @@
#include "vm/clustered_snapshot.h"
#include "vm/dart_api_impl.h"
#include "vm/datastream.h"
+#include "vm/message_snapshot.h"
#include "vm/stack_frame.h"
#include "vm/timer.h"
@@ -517,13 +518,12 @@
timer.Start();
for (intptr_t i = 0; i < kLoopCount; i++) {
StackZone zone(thread);
- MessageWriter writer(true);
- std::unique_ptr<Message> message = writer.WriteMessage(
- null_object, ILLEGAL_PORT, Message::kNormalPriority);
+ std::unique_ptr<Message> message =
+ WriteMessage(/* can_send_any_object */ true, null_object, ILLEGAL_PORT,
+ Message::kNormalPriority);
// Read object back from the snapshot.
- MessageSnapshotReader reader(message.get(), thread);
- reader.ReadObject();
+ ReadMessage(thread, message.get());
}
timer.Stop();
int64_t elapsed_time = timer.TotalElapsedTime();
@@ -540,13 +540,12 @@
timer.Start();
for (intptr_t i = 0; i < kLoopCount; i++) {
StackZone zone(thread);
- MessageWriter writer(true);
std::unique_ptr<Message> message =
- writer.WriteMessage(smi_object, ILLEGAL_PORT, Message::kNormalPriority);
+ WriteMessage(/* can_send_any_object */ true, smi_object, ILLEGAL_PORT,
+ Message::kNormalPriority);
// Read object back from the snapshot.
- MessageSnapshotReader reader(message.get(), thread);
- reader.ReadObject();
+ ReadMessage(thread, message.get());
}
timer.Stop();
int64_t elapsed_time = timer.TotalElapsedTime();
@@ -565,13 +564,12 @@
timer.Start();
for (intptr_t i = 0; i < kLoopCount; i++) {
StackZone zone(thread);
- MessageWriter writer(true);
- std::unique_ptr<Message> message = writer.WriteMessage(
- array_object, ILLEGAL_PORT, Message::kNormalPriority);
+ std::unique_ptr<Message> message = WriteMessage(
+ /* can_send_any_object */ true, array_object, ILLEGAL_PORT,
+ Message::kNormalPriority);
// Read object back from the snapshot.
- MessageSnapshotReader reader(message.get(), thread);
- reader.ReadObject();
+ ReadMessage(thread, message.get());
}
timer.Stop();
int64_t elapsed_time = timer.TotalElapsedTime();
@@ -599,13 +597,12 @@
timer.Start();
for (intptr_t i = 0; i < kLoopCount; i++) {
StackZone zone(thread);
- MessageWriter writer(true);
std::unique_ptr<Message> message =
- writer.WriteMessage(map, ILLEGAL_PORT, Message::kNormalPriority);
+ WriteMessage(/* can_send_any_object */ true, map, ILLEGAL_PORT,
+ Message::kNormalPriority);
// Read object back from the snapshot.
- MessageSnapshotReader reader(message.get(), thread);
- reader.ReadObject();
+ ReadMessage(thread, message.get());
}
timer.Stop();
int64_t elapsed_time = timer.TotalElapsedTime();
diff --git a/runtime/vm/clustered_snapshot.cc b/runtime/vm/clustered_snapshot.cc
index 9eec30d..b3beb4d 100644
--- a/runtime/vm/clustered_snapshot.cc
+++ b/runtime/vm/clustered_snapshot.cc
@@ -16,6 +16,7 @@
#include "vm/compiler/api/print_filter.h"
#include "vm/compiler/assembler/disassembler.h"
#include "vm/dart.h"
+#include "vm/dart_entry.h"
#include "vm/dispatch_table.h"
#include "vm/flag_list.h"
#include "vm/growable_array.h"
diff --git a/runtime/vm/compiler/backend/il.h b/runtime/vm/compiler/backend/il.h
index 1744e17..7699857 100644
--- a/runtime/vm/compiler/backend/il.h
+++ b/runtime/vm/compiler/backend/il.h
@@ -24,6 +24,7 @@
#include "vm/compiler/ffi/native_location.h"
#include "vm/compiler/ffi/native_type.h"
#include "vm/compiler/method_recognizer.h"
+#include "vm/dart_entry.h"
#include "vm/flags.h"
#include "vm/growable_array.h"
#include "vm/native_entry.h"
diff --git a/runtime/vm/dart.h b/runtime/vm/dart.h
index fa95787..b0776be 100644
--- a/runtime/vm/dart.h
+++ b/runtime/vm/dart.h
@@ -8,6 +8,7 @@
#include "include/dart_api.h"
#include "include/dart_tools_api.h"
#include "vm/allocation.h"
+#include "vm/isolate.h"
#include "vm/snapshot.h"
namespace dart {
diff --git a/runtime/vm/dart_api_impl.cc b/runtime/vm/dart_api_impl.cc
index 283841a..86cd097 100644
--- a/runtime/vm/dart_api_impl.cc
+++ b/runtime/vm/dart_api_impl.cc
@@ -32,6 +32,7 @@
#include "vm/lockers.h"
#include "vm/message.h"
#include "vm/message_handler.h"
+#include "vm/message_snapshot.h"
#include "vm/native_entry.h"
#include "vm/native_symbol.h"
#include "vm/object.h"
@@ -2161,17 +2162,10 @@
return false;
}
- // Smis and null can be sent without serialization.
- ObjectPtr raw_obj = Api::UnwrapHandle(handle);
- if (ApiObjectConverter::CanConvert(raw_obj)) {
- return PortMap::PostMessage(
- Message::New(port_id, raw_obj, Message::kNormalPriority));
- }
-
- const Object& object = Object::Handle(Z, raw_obj);
- MessageWriter writer(false);
- return PortMap::PostMessage(
- writer.WriteMessage(object, port_id, Message::kNormalPriority));
+ const Object& object = Object::Handle(Z, Api::UnwrapHandle(handle));
+ return PortMap::PostMessage(WriteMessage(/* can_send_any_object */ false,
+ object, port_id,
+ Message::kNormalPriority));
}
DART_EXPORT Dart_Handle Dart_NewSendPort(Dart_Port port_id) {
diff --git a/runtime/vm/dart_api_message.cc b/runtime/vm/dart_api_message.cc
deleted file mode 100644
index 73df245..0000000
--- a/runtime/vm/dart_api_message.cc
+++ /dev/null
@@ -1,1192 +0,0 @@
-// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-#include <memory>
-
-#include "vm/dart_api_message.h"
-
-#include "platform/undefined_behavior_sanitizer.h"
-#include "platform/unicode.h"
-#include "vm/object.h"
-#include "vm/snapshot_ids.h"
-#include "vm/symbols.h"
-
-namespace dart {
-
-static const int kNumInitialReferences = 4;
-
-ApiMessageReader::ApiMessageReader(Message* msg)
- : BaseReader(msg->IsRaw() ? reinterpret_cast<uint8_t*>(
- static_cast<uword>(msg->raw_obj()))
- : msg->snapshot(),
- msg->snapshot_length()),
- zone_(NULL),
- backward_references_(kNumInitialReferences),
- vm_isolate_references_(kNumInitialReferences),
- vm_symbol_references_(NULL),
- finalizable_data_(msg->finalizable_data()) {}
-
-ApiMessageReader::~ApiMessageReader() {}
-
-void ApiMessageReader::Init() {
- // We need to have an enclosing ApiNativeScope.
- ASSERT(ApiNativeScope::Current() != NULL);
- zone_ = ApiNativeScope::Current()->zone();
- ASSERT(zone_ != NULL);
-
- // Initialize marker objects used to handle Lists.
- // TODO(sjesse): Remove this when message serialization format is
- // updated.
- memset(&type_arguments_marker, 0, sizeof(type_arguments_marker));
- memset(&dynamic_type_marker, 0, sizeof(dynamic_type_marker));
- type_arguments_marker.type =
- static_cast<Dart_CObject_Type>(Dart_CObject_Internal::kTypeArguments);
- dynamic_type_marker.type =
- static_cast<Dart_CObject_Type>(Dart_CObject_Internal::kDynamicType);
-}
-
-Dart_CObject* ApiMessageReader::ReadMessage() {
- Init();
- if (PendingBytes() > 0) {
- // Read the object out of the message.
- return ReadObject();
- } else {
- 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)));
- ApiObjectConverter::Convert(raw_obj, cobj);
- return cobj;
- }
-}
-
-intptr_t ApiMessageReader::LookupInternalClass(intptr_t class_header) {
- if (IsVMIsolateObject(class_header)) {
- return GetVMIsolateObjectId(class_header);
- }
- ASSERT(SerializedHeaderTag::decode(class_header) == kObjectId);
- return SerializedHeaderData::decode(class_header);
-}
-
-Dart_CObject* ApiMessageReader::AllocateDartCObject(Dart_CObject_Type type) {
- Dart_CObject* value =
- reinterpret_cast<Dart_CObject*>(allocator(sizeof(Dart_CObject)));
- ASSERT(value != NULL);
- value->type = type;
- return value;
-}
-
-Dart_CObject* ApiMessageReader::AllocateDartCObjectUnsupported() {
- return AllocateDartCObject(Dart_CObject_kUnsupported);
-}
-
-Dart_CObject* ApiMessageReader::AllocateDartCObjectNull() {
- return AllocateDartCObject(Dart_CObject_kNull);
-}
-
-Dart_CObject* ApiMessageReader::AllocateDartCObjectBool(bool val) {
- Dart_CObject* value = AllocateDartCObject(Dart_CObject_kBool);
- value->value.as_bool = val;
- return value;
-}
-
-Dart_CObject* ApiMessageReader::AllocateDartCObjectInt32(int32_t val) {
- Dart_CObject* value = AllocateDartCObject(Dart_CObject_kInt32);
- value->value.as_int32 = val;
- return value;
-}
-
-Dart_CObject* ApiMessageReader::AllocateDartCObjectInt64(int64_t val) {
- Dart_CObject* value = AllocateDartCObject(Dart_CObject_kInt64);
- value->value.as_int64 = val;
- return value;
-}
-
-Dart_CObject* ApiMessageReader::AllocateDartCObjectDouble(double val) {
- Dart_CObject* value = AllocateDartCObject(Dart_CObject_kDouble);
- value->value.as_double = val;
- return value;
-}
-
-Dart_CObject* ApiMessageReader::AllocateDartCObjectString(intptr_t length) {
- // Allocate a Dart_CObject structure followed by an array of chars
- // for the string content. The pointer to the string content is set
- // up to this area.
- Dart_CObject* value = reinterpret_cast<Dart_CObject*>(
- allocator(sizeof(Dart_CObject) + length + 1));
- ASSERT(value != NULL);
- value->value.as_string = reinterpret_cast<char*>(value) + sizeof(*value);
- value->type = Dart_CObject_kString;
- return value;
-}
-
-static int GetTypedDataSizeInBytes(Dart_TypedData_Type type) {
- switch (type) {
- case Dart_TypedData_kInt8:
- case Dart_TypedData_kUint8:
- case Dart_TypedData_kUint8Clamped:
- return 1;
- case Dart_TypedData_kInt16:
- case Dart_TypedData_kUint16:
- return 2;
- case Dart_TypedData_kInt32:
- case Dart_TypedData_kUint32:
- case Dart_TypedData_kFloat32:
- return 4;
- case Dart_TypedData_kInt64:
- case Dart_TypedData_kUint64:
- case Dart_TypedData_kFloat64:
- return 8;
- case Dart_TypedData_kInt32x4:
- case Dart_TypedData_kFloat32x4:
- case Dart_TypedData_kFloat64x2:
- return 16;
- default:
- break;
- }
- UNREACHABLE();
- return -1;
-}
-
-Dart_CObject* ApiMessageReader::AllocateDartCObjectTypedData(
- Dart_TypedData_Type type,
- intptr_t length) {
- // Allocate a Dart_CObject structure followed by an array of bytes
- // for the byte array content. The pointer to the byte array content
- // is set up to this area.
- intptr_t length_in_bytes = GetTypedDataSizeInBytes(type) * length;
- Dart_CObject* value = reinterpret_cast<Dart_CObject*>(
- allocator(sizeof(Dart_CObject) + length_in_bytes));
- ASSERT(value != NULL);
- value->type = Dart_CObject_kTypedData;
- value->value.as_typed_data.type = type;
- value->value.as_typed_data.length = length_in_bytes;
- if (length > 0) {
- value->value.as_typed_data.values =
- reinterpret_cast<uint8_t*>(value) + sizeof(*value);
- } else {
- value->value.as_typed_data.values = NULL;
- }
- return value;
-}
-
-Dart_CObject* ApiMessageReader::AllocateDartCObjectArray(intptr_t length) {
- // Allocate a Dart_CObject structure followed by an array of
- // pointers to Dart_CObject structures. The pointer to the array
- // content is set up to this area.
- Dart_CObject* value = reinterpret_cast<Dart_CObject*>(
- allocator(sizeof(Dart_CObject) + length * sizeof(value)));
- ASSERT(value != NULL);
- value->type = Dart_CObject_kArray;
- value->value.as_array.length = length;
- if (length > 0) {
- value->value.as_array.values = reinterpret_cast<Dart_CObject**>(value + 1);
- } else {
- value->value.as_array.values = NULL;
- }
- return value;
-}
-
-Dart_CObject* ApiMessageReader::AllocateDartCObjectVmIsolateObj(intptr_t id) {
- ObjectPtr raw = VmIsolateSnapshotObject(id);
- intptr_t cid = raw->GetClassId();
- switch (cid) {
- case kOneByteStringCid: {
- OneByteStringPtr raw_str = static_cast<OneByteStringPtr>(raw);
- const char* str = reinterpret_cast<const char*>(raw_str->untag()->data());
- ASSERT(str != NULL);
- Dart_CObject* object = NULL;
- for (intptr_t i = 0; i < vm_isolate_references_.length(); i++) {
- object = vm_isolate_references_.At(i);
- if (object->type == Dart_CObject_kString) {
- if (strcmp(str, object->value.as_string) == 0) {
- return object;
- }
- }
- }
- object = CreateDartCObjectString(raw);
- vm_isolate_references_.Add(object);
- return object;
- }
-
- case kMintCid: {
- 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);
- } else {
- return GetCanonicalMintObject(Dart_CObject_kInt64, value64);
- }
- }
-
- default:
- UNREACHABLE();
- return NULL;
- }
-}
-
-Dart_CObject_Internal* ApiMessageReader::AllocateDartCObjectInternal(
- Dart_CObject_Internal::Type type) {
- Dart_CObject_Internal* value = reinterpret_cast<Dart_CObject_Internal*>(
- allocator(sizeof(Dart_CObject_Internal)));
- ASSERT(value != NULL);
- value->type = static_cast<Dart_CObject_Type>(type);
- return value;
-}
-
-Dart_CObject_Internal* ApiMessageReader::AllocateDartCObjectClass() {
- return AllocateDartCObjectInternal(Dart_CObject_Internal::kClass);
-}
-
-ApiMessageReader::BackRefNode* ApiMessageReader::AllocateBackRefNode(
- Dart_CObject* reference,
- DeserializeState state) {
- BackRefNode* value =
- reinterpret_cast<BackRefNode*>(allocator(sizeof(BackRefNode)));
- value->set_reference(reference);
- value->set_state(state);
- return value;
-}
-
-Dart_CObject* ApiMessageReader::ReadInlinedObject(intptr_t object_id) {
- // Read the class header information and lookup the class.
- intptr_t class_header = Read<int32_t>();
- intptr_t tags = ReadTags();
- USE(tags);
- intptr_t class_id;
-
- // There is limited support for reading regular dart instances. Only
- // typed data views are currently handled.
- if (SerializedHeaderData::decode(class_header) == kInstanceObjectId) {
- Dart_CObject_Internal* object =
- reinterpret_cast<Dart_CObject_Internal*>(GetBackRef(object_id));
- if (object == NULL) {
- object =
- AllocateDartCObjectInternal(Dart_CObject_Internal::kUninitialized);
- AddBackRef(object_id, object, kIsDeserialized);
- // Read class of object.
- object->cls = reinterpret_cast<Dart_CObject_Internal*>(ReadObjectImpl());
- ASSERT(object->cls->type ==
- static_cast<Dart_CObject_Type>(Dart_CObject_Internal::kClass));
- }
- ASSERT(object->type == static_cast<Dart_CObject_Type>(
- Dart_CObject_Internal::kUninitialized));
- return object;
- }
-
- ASSERT((class_header & kSmiTagMask) != 0);
- class_id = LookupInternalClass(class_header);
- if ((class_id == kArrayCid) || (class_id == kImmutableArrayCid)) {
- intptr_t len = ReadSmiValue();
- Dart_CObject* value = GetBackRef(object_id);
- if (value == NULL) {
- value = AllocateDartCObjectArray(len);
- AddBackRef(object_id, value, kIsDeserialized);
- }
- // Skip type arguments.
- // TODO(sjesse): Remove this when message serialization format is
- // updated (currently type_arguments is leaked).
- Dart_CObject* type_arguments = ReadObjectImpl();
- if (type_arguments != &type_arguments_marker &&
- type_arguments->type != Dart_CObject_kNull) {
- return AllocateDartCObjectUnsupported();
- }
- for (int i = 0; i < len; i++) {
- value->value.as_array.values[i] = ReadObjectRef();
- }
- return value;
- }
-
- return ReadInternalVMObject(class_id, object_id);
-}
-
-Dart_CObject* ApiMessageReader::ReadPredefinedSymbol(intptr_t object_id) {
- ASSERT(Symbols::IsPredefinedSymbolId(object_id));
- intptr_t symbol_id = object_id - kMaxPredefinedObjectIds;
- Dart_CObject* object;
- if (vm_symbol_references_ != NULL &&
- (object = vm_symbol_references_[symbol_id]) != NULL) {
- return object;
- }
-
- if (vm_symbol_references_ == NULL) {
- intptr_t size =
- (sizeof(*vm_symbol_references_) * Symbols::kMaxPredefinedId);
- vm_symbol_references_ = reinterpret_cast<Dart_CObject**>(allocator(size));
- memset(vm_symbol_references_, 0, size);
- }
-
- object = CreateDartCObjectString(Symbols::GetPredefinedSymbol(object_id));
- ASSERT(vm_symbol_references_[symbol_id] == NULL);
- vm_symbol_references_[symbol_id] = object;
- return object;
-}
-
-intptr_t ApiMessageReader::NextAvailableObjectId() const {
- return backward_references_.length() + kMaxPredefinedObjectIds;
-}
-
-Dart_CObject* ApiMessageReader::CreateDartCObjectString(ObjectPtr raw) {
- ASSERT(IsOneByteStringClassId(raw->GetClassId()));
- OneByteStringPtr raw_str = static_cast<OneByteStringPtr>(raw);
- intptr_t len = Smi::Value(raw_str->untag()->length());
- Dart_CObject* object = AllocateDartCObjectString(len);
- char* p = object->value.as_string;
- memmove(p, raw_str->untag()->data(), len);
- p[len] = '\0';
- return object;
-}
-
-Dart_CObject* ApiMessageReader::GetCanonicalMintObject(Dart_CObject_Type type,
- int64_t value64) {
- Dart_CObject* object = NULL;
- for (intptr_t i = 0; i < vm_isolate_references_.length(); i++) {
- object = vm_isolate_references_.At(i);
- if (object->type == type) {
- if (value64 == object->value.as_int64) {
- return object;
- }
- }
- }
- if (type == Dart_CObject_kInt32) {
- object = AllocateDartCObjectInt32(static_cast<int32_t>(value64));
- } else {
- object = AllocateDartCObjectInt64(value64);
- }
- vm_isolate_references_.Add(object);
- return object;
-}
-
-Dart_CObject* ApiMessageReader::ReadObjectRef() {
- int64_t value64 = Read<int64_t>();
- if ((value64 & kSmiTagMask) == 0) {
- int64_t untagged_value = value64 >> kSmiTagShift;
- if ((kMinInt32 <= untagged_value) && (untagged_value <= kMaxInt32)) {
- return AllocateDartCObjectInt32(static_cast<int32_t>(untagged_value));
- } else {
- return AllocateDartCObjectInt64(untagged_value);
- }
- }
- ASSERT((value64 <= kIntptrMax) && (value64 >= kIntptrMin));
- intptr_t value = static_cast<intptr_t>(value64);
- if (IsVMIsolateObject(value)) {
- return ReadVMIsolateObject(value);
- }
- if (SerializedHeaderTag::decode(value) == kObjectId) {
- return ReadIndexedObject(SerializedHeaderData::decode(value));
- }
- ASSERT(SerializedHeaderTag::decode(value) == kInlined);
- // Read the class header information and lookup the class.
- intptr_t class_header = Read<int32_t>();
-
- intptr_t object_id = SerializedHeaderData::decode(value);
- if (object_id == kOmittedObjectId) {
- object_id = NextAvailableObjectId();
- }
-
- intptr_t tags = ReadTags();
- USE(tags);
-
- // Reading of regular dart instances has limited support in order to
- // read typed data views.
- if (SerializedHeaderData::decode(class_header) == kInstanceObjectId) {
- Dart_CObject_Internal* object =
- AllocateDartCObjectInternal(Dart_CObject_Internal::kUninitialized);
- AddBackRef(object_id, object, kIsNotDeserialized);
- // Read class of object.
- object->cls = reinterpret_cast<Dart_CObject_Internal*>(ReadObjectImpl());
- ASSERT(object->cls->type ==
- static_cast<Dart_CObject_Type>(Dart_CObject_Internal::kClass));
- return object;
- }
- ASSERT((class_header & kSmiTagMask) != 0);
- intptr_t class_id = LookupInternalClass(class_header);
- if ((class_id == kArrayCid) || (class_id == kImmutableArrayCid)) {
- ASSERT(GetBackRef(object_id) == NULL);
- intptr_t len = ReadSmiValue();
- Dart_CObject* value = AllocateDartCObjectArray(len);
- AddBackRef(object_id, value, kIsNotDeserialized);
- return value;
- }
- return ReadInternalVMObject(class_id, object_id);
-}
-
-Dart_CObject* ApiMessageReader::ReadVMIsolateObject(intptr_t value) {
- intptr_t object_id = GetVMIsolateObjectId(value);
- if (object_id == kNullObject) {
- return AllocateDartCObjectNull();
- }
- if (object_id == kTrueValue) {
- return AllocateDartCObjectBool(true);
- }
- if (object_id == kFalseValue) {
- return AllocateDartCObjectBool(false);
- }
- if (object_id == kDoubleObject) {
- return AllocateDartCObjectDouble(ReadDouble());
- }
- if (Symbols::IsPredefinedSymbolId(object_id)) {
- return ReadPredefinedSymbol(object_id);
- }
- // No other VM isolate objects are supported.
- return AllocateDartCObjectNull();
-}
-
-Dart_CObject* ApiMessageReader::ReadInternalVMObject(intptr_t class_id,
- intptr_t object_id) {
- switch (class_id) {
- case kClassCid: {
- Dart_CObject_Internal* object = AllocateDartCObjectClass();
- AddBackRef(object_id, object, kIsDeserialized);
- object->internal.as_class.library_url = ReadObjectImpl();
- ASSERT(object->internal.as_class.library_url->type ==
- Dart_CObject_kString);
- object->internal.as_class.class_name = ReadObjectImpl();
- ASSERT(object->internal.as_class.class_name->type ==
- Dart_CObject_kString);
- return object;
- }
- case kTypeArgumentsCid: {
- // TODO(sjesse): Remove this when message serialization format is
- // updated (currently length is leaked).
- Dart_CObject* value = &type_arguments_marker;
- AddBackRef(object_id, value, kIsDeserialized);
- Dart_CObject* length = ReadObjectImpl();
- ASSERT(length->type == Dart_CObject_kInt32);
- // The instantiations_ field is only written to a full snapshot.
- for (int i = 0; i < length->value.as_int32; i++) {
- Dart_CObject* type = ReadObjectImpl();
- if (type != &dynamic_type_marker) {
- return AllocateDartCObjectUnsupported();
- }
- }
- return value;
- }
- case kTypeParameterCid: {
- Dart_CObject* value = &dynamic_type_marker;
- AddBackRef(object_id, value, kIsDeserialized);
- intptr_t index = Read<int32_t>();
- USE(index);
- intptr_t token_index = Read<int32_t>();
- USE(token_index);
- int8_t type_state = Read<int8_t>();
- USE(type_state);
- Dart_CObject* parameterized_class = ReadObjectImpl();
- // The type parameter is finalized, therefore parameterized_class is null.
- ASSERT(parameterized_class->type == Dart_CObject_kNull);
- Dart_CObject* name = ReadObjectImpl();
- ASSERT(name->type == Dart_CObject_kString);
- return value;
- }
- case kMintCid: {
- int64_t value64 = Read<int64_t>();
- Dart_CObject* object;
- if ((kMinInt32 <= value64) && (value64 <= kMaxInt32)) {
- object = AllocateDartCObjectInt32(static_cast<int32_t>(value64));
- } else {
- object = AllocateDartCObjectInt64(value64);
- }
- AddBackRef(object_id, object, kIsDeserialized);
- return object;
- }
- case kDoubleCid: {
- // Doubles are handled specially when being sent as part of message
- // snapshots.
- UNREACHABLE();
- }
- case kOneByteStringCid: {
- intptr_t len = ReadSmiValue();
- uint8_t* latin1 =
- reinterpret_cast<uint8_t*>(allocator(len * sizeof(uint8_t)));
- intptr_t utf8_len = 0;
- for (intptr_t i = 0; i < len; i++) {
- latin1[i] = Read<uint8_t>();
- utf8_len += Utf8::Length(latin1[i]);
- }
- Dart_CObject* object = AllocateDartCObjectString(utf8_len);
- AddBackRef(object_id, object, kIsDeserialized);
- char* p = object->value.as_string;
- for (intptr_t i = 0; i < len; i++) {
- p += Utf8::Encode(latin1[i], p);
- }
- *p = '\0';
- ASSERT(p == (object->value.as_string + utf8_len));
- return object;
- }
- case kTwoByteStringCid: {
- intptr_t len = ReadSmiValue();
- uint16_t* utf16 =
- reinterpret_cast<uint16_t*>(allocator(len * sizeof(uint16_t)));
- intptr_t utf8_len = 0;
- // Read all the UTF-16 code units.
- for (intptr_t i = 0; i < len; i++) {
- utf16[i] = Read<uint16_t>();
- }
- // Calculate the UTF-8 length and check if the string can be
- // UTF-8 encoded.
- bool valid = true;
- intptr_t i = 0;
- while (i < len && valid) {
- int32_t ch = Utf16::Next(utf16, &i, len);
- utf8_len += Utf8::Length(ch);
- valid = !Utf16::IsSurrogate(ch);
- }
- if (!valid) {
- return AllocateDartCObjectUnsupported();
- }
- Dart_CObject* object = AllocateDartCObjectString(utf8_len);
- AddBackRef(object_id, object, kIsDeserialized);
- char* p = object->value.as_string;
- i = 0;
- while (i < len) {
- p += Utf8::Encode(Utf16::Next(utf16, &i, len), p);
- }
- *p = '\0';
- ASSERT(p == (object->value.as_string + utf8_len));
- return object;
- }
- case kSendPortCid: {
- int64_t value64 = Read<int64_t>();
- int64_t originId = Read<uint64_t>();
- Dart_CObject* object = AllocateDartCObject(Dart_CObject_kSendPort);
- object->value.as_send_port.id = value64;
- object->value.as_send_port.origin_id = originId;
- AddBackRef(object_id, object, kIsDeserialized);
- return object;
- }
- case kCapabilityCid: {
- int64_t id = Read<int64_t>();
- Dart_CObject* object = AllocateDartCObject(Dart_CObject_kCapability);
- object->value.as_capability.id = id;
- AddBackRef(object_id, object, kIsDeserialized);
- return object;
- }
-
-#define READ_TYPED_DATA(tname, ctype) \
- { \
- intptr_t len = ReadSmiValue(); \
- auto type = Dart_TypedData_k##tname; \
- intptr_t length_in_bytes = GetTypedDataSizeInBytes(type) * len; \
- Dart_CObject* object = \
- reinterpret_cast<Dart_CObject*>(allocator(sizeof(Dart_CObject))); \
- ASSERT(object != NULL); \
- object->type = Dart_CObject_kTypedData; \
- object->value.as_typed_data.type = type; \
- object->value.as_typed_data.length = length_in_bytes; \
- if (len > 0) { \
- Align(Zone::kAlignment); \
- object->value.as_typed_data.values = \
- const_cast<uint8_t*>(CurrentBufferAddress()); \
- Advance(length_in_bytes); \
- } else { \
- object->value.as_typed_data.values = NULL; \
- } \
- AddBackRef(object_id, object, kIsDeserialized); \
- return object; \
- }
-
-#define READ_EXTERNAL_TYPED_DATA(tname, ctype) \
- { \
- intptr_t len = ReadSmiValue(); \
- auto type = Dart_TypedData_k##tname; \
- intptr_t length_in_bytes = GetTypedDataSizeInBytes(type) * len; \
- Dart_CObject* object = \
- reinterpret_cast<Dart_CObject*>(allocator(sizeof(Dart_CObject))); \
- ASSERT(object != NULL); \
- object->type = Dart_CObject_kTypedData; \
- object->value.as_typed_data.type = type; \
- object->value.as_typed_data.length = length_in_bytes; \
- object->value.as_typed_data.values = \
- reinterpret_cast<uint8_t*>(finalizable_data_->Get().data); \
- AddBackRef(object_id, object, kIsDeserialized); \
- return object; \
- }
-
-#define READ_TYPED_DATA_VIEW(tname, ctype) \
- { \
- Dart_CObject_Internal* object = \
- AllocateDartCObjectInternal(Dart_CObject_Internal::kUninitialized); \
- AddBackRef(object_id, object, kIsDeserialized); \
- object->type = \
- static_cast<Dart_CObject_Type>(Dart_CObject_Internal::kView); \
- object->internal.as_view.offset_in_bytes = ReadSmiValue(); \
- object->internal.as_view.length = ReadSmiValue(); \
- object->internal.as_view.buffer = ReadObjectImpl(); \
- Dart_CObject* buffer = object->internal.as_view.buffer; \
- RELEASE_ASSERT(buffer->type == Dart_CObject_kTypedData); \
- \
- /* Now turn the view into a byte array.*/ \
- const Dart_TypedData_Type type = Dart_TypedData_k##tname; \
- object->type = Dart_CObject_kTypedData; \
- object->value.as_typed_data.type = type; \
- object->value.as_typed_data.length = \
- object->internal.as_view.length * GetTypedDataSizeInBytes(type); \
- object->value.as_typed_data.values = \
- buffer->value.as_typed_data.values + \
- object->internal.as_view.offset_in_bytes; \
- return object; \
- }
-
-#define TYPED_DATA_LIST(V) \
- V(Int8, int8_t) \
- V(Uint8, uint8_t) \
- V(Uint8Clamped, uint8_t) \
- V(Int16, int16_t) \
- V(Uint16, uint16_t) \
- V(Int32, int32_t) \
- V(Uint32, uint32_t) \
- V(Int64, int64_t) \
- V(Uint64, uint64_t) \
- V(Float32, float) \
- V(Float64, double) \
- V(Int32x4, simd128_value_t) \
- V(Float32x4, simd128_value_t) \
- V(Float64x2, simd128_value_t)
-
-#define EMIT_TYPED_DATA_CASES(type, c_type) \
- case kTypedData##type##ArrayCid: \
- READ_TYPED_DATA(type, c_type); \
- case kExternalTypedData##type##ArrayCid: \
- READ_EXTERNAL_TYPED_DATA(type, c_type); \
- case kTypedData##type##ArrayViewCid: \
- READ_TYPED_DATA_VIEW(type, c_type);
-
- TYPED_DATA_LIST(EMIT_TYPED_DATA_CASES)
-#undef EMIT_TYPED_DATA_CASES
-#undef TYPED_DATA_LIST
-#undef READ_TYPED_DATA
-#undef READ_EXTERNAL_TYPED_DATA
-#undef READ_TYPED_DATA_VIEW
-
- case kGrowableObjectArrayCid: {
- // A GrowableObjectArray is serialized as its type arguments and
- // length followed by its backing store. The backing store is an
- // array with a length which might be longer than the length of
- // the GrowableObjectArray.
- Dart_CObject* value = GetBackRef(object_id);
- ASSERT(value == NULL);
- // Allocate an empty array for the GrowableObjectArray which
- // will be updated to point to the content when the backing
- // store has been deserialized.
- value = AllocateDartCObjectArray(0);
- AddBackRef(object_id, value, kIsDeserialized);
-
- // Read and skip the type arguments field.
- // TODO(sjesse): Remove this when message serialization format is
- // updated (currently type_arguments is leaked).
- Dart_CObject* type_arguments = ReadObjectImpl();
- if (type_arguments != &type_arguments_marker &&
- type_arguments->type != Dart_CObject_kNull) {
- return AllocateDartCObjectUnsupported();
- }
-
- // Read the length field.
- intptr_t len = ReadSmiValue();
-
- // Read the content of the GrowableObjectArray.
- Dart_CObject* content = ReadObjectRef();
- ASSERT(content->type == Dart_CObject_kArray);
- // Make the empty array allocated point to the backing store content.
- value->value.as_array.length = len;
- value->value.as_array.values = content->value.as_array.values;
- return value;
- }
- default:
- // Everything else not supported.
- Dart_CObject* value = AllocateDartCObjectUnsupported();
- AddBackRef(object_id, value, kIsDeserialized);
- return value;
- }
-}
-
-Dart_CObject* ApiMessageReader::ReadIndexedObject(intptr_t object_id) {
- if (object_id >= kFirstTypeSnapshotId && object_id <= kLastTypeSnapshotId) {
- // Always return dynamic type (this is only a marker).
- return &dynamic_type_marker;
- }
- if (object_id >= kFirstTypeArgumentsSnapshotId &&
- object_id <= kLastTypeArgumentsSnapshotId) {
- return &type_arguments_marker;
- }
-
- intptr_t index = object_id - kMaxPredefinedObjectIds;
- ASSERT((0 <= index) && (index < backward_references_.length()));
- ASSERT(backward_references_[index]->reference() != NULL);
- return backward_references_[index]->reference();
-}
-
-Dart_CObject* ApiMessageReader::ReadObject() {
- Dart_CObject* value = ReadObjectImpl();
- for (intptr_t i = 0; i < backward_references_.length(); i++) {
- if (!backward_references_[i]->is_deserialized()) {
- ReadObjectImpl();
- backward_references_[i]->set_state(kIsDeserialized);
- }
- }
- return value;
-}
-
-Dart_CObject* ApiMessageReader::ReadObjectImpl() {
- int64_t value64 = Read<int64_t>();
- if ((value64 & kSmiTagMask) == 0) {
- int64_t untagged_value = value64 >> kSmiTagShift;
- if ((kMinInt32 <= untagged_value) && (untagged_value <= kMaxInt32)) {
- return AllocateDartCObjectInt32(static_cast<int32_t>(untagged_value));
- } else {
- return AllocateDartCObjectInt64(untagged_value);
- }
- }
- ASSERT((value64 <= kIntptrMax) && (value64 >= kIntptrMin));
- intptr_t value = static_cast<intptr_t>(value64);
- if (IsVMIsolateObject(value)) {
- return ReadVMIsolateObject(value);
- }
- if (SerializedHeaderTag::decode(value) == kObjectId) {
- return ReadIndexedObject(SerializedHeaderData::decode(value));
- }
- ASSERT(SerializedHeaderTag::decode(value) == kInlined);
-
- intptr_t object_id = SerializedHeaderData::decode(value);
- if (object_id == kOmittedObjectId) {
- object_id = NextAvailableObjectId();
- }
- return ReadInlinedObject(object_id);
-}
-
-void ApiMessageReader::AddBackRef(intptr_t id,
- Dart_CObject* obj,
- DeserializeState state) {
- intptr_t index = (id - kMaxPredefinedObjectIds);
- ASSERT(index == backward_references_.length());
- BackRefNode* node = AllocateBackRefNode(obj, state);
- ASSERT(node != NULL);
- backward_references_.Add(node);
-}
-
-Dart_CObject* ApiMessageReader::GetBackRef(intptr_t id) {
- ASSERT(id >= kMaxPredefinedObjectIds);
- intptr_t index = (id - kMaxPredefinedObjectIds);
- if (index < backward_references_.length()) {
- return backward_references_[index]->reference();
- }
- return NULL;
-}
-
-ApiMessageWriter::ApiMessageWriter()
- : BaseWriter(kInitialSize),
- object_id_(0),
- forward_list_(NULL),
- forward_list_length_(0),
- forward_id_(0),
- finalizable_data_(new MessageFinalizableData()) {
- ASSERT(kDartCObjectTypeMask >= Dart_CObject_kNumberOfTypes - 1);
-}
-
-ApiMessageWriter::~ApiMessageWriter() {
- ::free(forward_list_);
- delete finalizable_data_;
-}
-
-NO_SANITIZE_UNDEFINED(
- "enum") // TODO(https://github.com/dart-lang/sdk/issues/39427)
-void ApiMessageWriter::MarkCObject(Dart_CObject* object, intptr_t object_id) {
- // Mark the object as serialized by adding the object id to the
- // upper bits of the type field in the Dart_CObject structure. Add
- // an offset for making marking of object id 0 possible.
- ASSERT(!IsCObjectMarked(object));
- intptr_t mark_value = object_id + kDartCObjectMarkOffset;
- object->type = static_cast<Dart_CObject_Type>(
- ((mark_value) << kDartCObjectTypeBits) | object->type);
-}
-
-NO_SANITIZE_UNDEFINED(
- "enum") // TODO(https://github.com/dart-lang/sdk/issues/39427)
-void ApiMessageWriter::UnmarkCObject(Dart_CObject* object) {
- ASSERT(IsCObjectMarked(object));
- object->type =
- static_cast<Dart_CObject_Type>(object->type & kDartCObjectTypeMask);
-}
-
-NO_SANITIZE_UNDEFINED(
- "enum") // TODO(https://github.com/dart-lang/sdk/issues/39427)
-bool ApiMessageWriter::IsCObjectMarked(Dart_CObject* object) {
- return (object->type & kDartCObjectMarkMask) != 0;
-}
-
-NO_SANITIZE_UNDEFINED(
- "enum") // TODO(https://github.com/dart-lang/sdk/issues/39427)
-intptr_t ApiMessageWriter::GetMarkedCObjectMark(Dart_CObject* object) {
- ASSERT(IsCObjectMarked(object));
- intptr_t mark_value =
- ((object->type & kDartCObjectMarkMask) >> kDartCObjectTypeBits);
- // An offset was added to object id for making marking object id 0 possible.
- return mark_value - kDartCObjectMarkOffset;
-}
-
-void ApiMessageWriter::UnmarkAllCObjects(Dart_CObject* object) {
- if (!IsCObjectMarked(object)) return;
- UnmarkCObject(object);
- if (object->type == Dart_CObject_kArray) {
- for (int i = 0; i < object->value.as_array.length; i++) {
- Dart_CObject* element = object->value.as_array.values[i];
- UnmarkAllCObjects(element);
- }
- }
-}
-
-void ApiMessageWriter::AddToForwardList(Dart_CObject* object) {
- if (forward_id_ >= forward_list_length_) {
- void* new_list = NULL;
- if (forward_list_length_ == 0) {
- forward_list_length_ = 4;
- intptr_t new_size = forward_list_length_ * sizeof(object);
- new_list = dart::malloc(new_size);
- } else {
- forward_list_length_ *= 2;
- intptr_t new_size = (forward_list_length_ * sizeof(object));
- new_list = dart::realloc(forward_list_, new_size);
- }
- ASSERT(new_list != NULL);
- forward_list_ = reinterpret_cast<Dart_CObject**>(new_list);
- }
- forward_list_[forward_id_] = object;
- forward_id_ += 1;
-}
-
-void ApiMessageWriter::WriteSmi(int64_t value) {
- ASSERT(Smi::IsValid(value));
- Write<ObjectPtr>(Smi::New(static_cast<intptr_t>(value)));
-}
-
-void ApiMessageWriter::WriteNullObject() {
- WriteVMIsolateObject(kNullObject);
-}
-
-void ApiMessageWriter::WriteMint(Dart_CObject* object, int64_t value) {
- ASSERT(!Smi::IsValid(value));
- // Write out the serialization header value for mint object.
- WriteInlinedHeader(object);
- // Write out the class and tags information.
- WriteIndexedObject(kMintCid);
- WriteTags(0);
- // Write the 64-bit value.
- Write<int64_t>(value);
-}
-
-void ApiMessageWriter::WriteInt32(Dart_CObject* object) {
- int64_t value = object->value.as_int32;
- if (Smi::IsValid(value)) {
- WriteSmi(value);
- } else {
- WriteMint(object, value);
- }
-}
-
-void ApiMessageWriter::WriteInt64(Dart_CObject* object) {
- int64_t value = object->value.as_int64;
- if (Smi::IsValid(value)) {
- WriteSmi(value);
- } else {
- WriteMint(object, value);
- }
-}
-
-void ApiMessageWriter::WriteInlinedHeader(Dart_CObject* object) {
- // Write out the serialization header value for this object.
- WriteInlinedObjectHeader(kMaxPredefinedObjectIds + object_id_);
- // Mark object with its object id.
- MarkCObject(object, object_id_);
- // Advance object id.
- object_id_++;
-}
-
-bool ApiMessageWriter::WriteCObject(Dart_CObject* object) {
- if (IsCObjectMarked(object)) {
- intptr_t object_id = GetMarkedCObjectMark(object);
- WriteIndexedObject(kMaxPredefinedObjectIds + object_id);
- return true;
- }
-
- Dart_CObject_Type type = object->type;
- if (type == Dart_CObject_kArray) {
- const intptr_t array_length = object->value.as_array.length;
- if (!Array::IsValidLength(array_length)) {
- return false;
- }
-
- // Write out the serialization header value for this object.
- WriteInlinedHeader(object);
- // Write out the class and tags information.
- WriteIndexedObject(kArrayCid);
- WriteTags(0);
- // Write out the length information.
- WriteSmi(array_length);
- // Write out the type arguments.
- WriteNullObject();
- // Write out array elements.
- for (int i = 0; i < array_length; i++) {
- bool success = WriteCObjectRef(object->value.as_array.values[i]);
- if (!success) return false;
- }
- return true;
- }
- return WriteCObjectInlined(object, type);
-}
-
-bool ApiMessageWriter::WriteCObjectRef(Dart_CObject* object) {
- if (IsCObjectMarked(object)) {
- intptr_t object_id = GetMarkedCObjectMark(object);
- WriteIndexedObject(kMaxPredefinedObjectIds + object_id);
- return true;
- }
-
- Dart_CObject_Type type = object->type;
- if (type == Dart_CObject_kArray) {
- const intptr_t array_length = object->value.as_array.length;
- if (!Array::IsValidLength(array_length)) {
- return false;
- }
- // Write out the serialization header value for this object.
- WriteInlinedHeader(object);
- // Write out the class information.
- WriteIndexedObject(kArrayCid);
- WriteTags(0);
- // Write out the length information.
- WriteSmi(array_length);
- // Add object to forward list so that this object is serialized later.
- AddToForwardList(object);
- return true;
- }
- return WriteCObjectInlined(object, type);
-}
-
-NO_SANITIZE_UNDEFINED(
- "enum") // TODO(https://github.com/dart-lang/sdk/issues/39427)
-bool ApiMessageWriter::WriteForwardedCObject(Dart_CObject* object) {
- ASSERT(IsCObjectMarked(object));
- Dart_CObject_Type type =
- static_cast<Dart_CObject_Type>(object->type & kDartCObjectTypeMask);
- ASSERT(type == Dart_CObject_kArray);
- const intptr_t array_length = object->value.as_array.length;
- if (!Array::IsValidLength(array_length)) {
- return false;
- }
-
- // Write out the serialization header value for this object.
- intptr_t object_id = GetMarkedCObjectMark(object);
- WriteInlinedObjectHeader(kMaxPredefinedObjectIds + object_id);
- // Write out the class and tags information.
- WriteIndexedObject(kArrayCid);
- WriteTags(0);
- // Write out the length information.
- WriteSmi(array_length);
- // Write out the type arguments.
- WriteNullObject();
- // Write out array elements.
- for (int i = 0; i < array_length; i++) {
- bool success = WriteCObjectRef(object->value.as_array.values[i]);
- if (!success) return false;
- }
- return true;
-}
-
-bool ApiMessageWriter::WriteCObjectInlined(Dart_CObject* object,
- Dart_CObject_Type type) {
- switch (type) {
- case Dart_CObject_kNull:
- WriteNullObject();
- break;
- case Dart_CObject_kBool:
- if (object->value.as_bool) {
- WriteVMIsolateObject(kTrueValue);
- } else {
- WriteVMIsolateObject(kFalseValue);
- }
- break;
- case Dart_CObject_kInt32:
- WriteInt32(object);
- break;
- case Dart_CObject_kInt64:
- WriteInt64(object);
- break;
- case Dart_CObject_kDouble:
- WriteVMIsolateObject(kDoubleObject);
- WriteDouble(object->value.as_double);
- break;
- case Dart_CObject_kString: {
- const uint8_t* utf8_str =
- reinterpret_cast<const uint8_t*>(object->value.as_string);
- intptr_t utf8_len = strlen(object->value.as_string);
- if (!Utf8::IsValid(utf8_str, utf8_len)) {
- return false;
- }
-
- Utf8::Type type = Utf8::kLatin1;
- intptr_t len = Utf8::CodeUnitCount(utf8_str, utf8_len, &type);
- if (len > String::kMaxElements) {
- return false;
- }
-
- // Write out the serialization header value for this object.
- WriteInlinedHeader(object);
- // Write out the class and tags information.
- WriteIndexedObject(type == Utf8::kLatin1 ? kOneByteStringCid
- : kTwoByteStringCid);
- WriteTags(0);
- // Write string length and content.
- WriteSmi(len);
- if (type == Utf8::kLatin1) {
- uint8_t* latin1_str =
- reinterpret_cast<uint8_t*>(dart::malloc(len * sizeof(uint8_t)));
- bool success =
- Utf8::DecodeToLatin1(utf8_str, utf8_len, latin1_str, len);
- ASSERT(success);
- for (intptr_t i = 0; i < len; i++) {
- Write<uint8_t>(latin1_str[i]);
- }
- ::free(latin1_str);
- } else {
- uint16_t* utf16_str =
- reinterpret_cast<uint16_t*>(dart::malloc(len * sizeof(uint16_t)));
- bool success = Utf8::DecodeToUTF16(utf8_str, utf8_len, utf16_str, len);
- ASSERT(success);
- for (intptr_t i = 0; i < len; i++) {
- Write<uint16_t>(utf16_str[i]);
- }
- ::free(utf16_str);
- }
- break;
- }
- case Dart_CObject_kTypedData: {
- // Write out the serialization header value for this object.
- WriteInlinedHeader(object);
- // Write out the class and tags information.
- intptr_t class_id;
- switch (object->value.as_typed_data.type) {
- case Dart_TypedData_kInt8:
- class_id = kTypedDataInt8ArrayCid;
- break;
- case Dart_TypedData_kUint8:
- class_id = kTypedDataUint8ArrayCid;
- break;
- case Dart_TypedData_kUint32:
- class_id = kTypedDataUint32ArrayCid;
- break;
- default:
- class_id = kTypedDataUint8ArrayCid;
- UNIMPLEMENTED();
- }
-
- intptr_t len = object->value.as_typed_data.length;
- if (len < 0 || len > TypedData::MaxElements(class_id)) {
- return false;
- }
-
- WriteIndexedObject(class_id);
- WriteTags(0);
- WriteSmi(len);
- switch (class_id) {
- case kTypedDataInt8ArrayCid:
- case kTypedDataUint8ArrayCid: {
- uint8_t* bytes = object->value.as_typed_data.values;
- Align(Zone::kAlignment);
- WriteBytes(bytes, len);
- break;
- }
- case kTypedDataUint32ArrayCid: {
- uint8_t* bytes = object->value.as_typed_data.values;
- Align(Zone::kAlignment);
- WriteBytes(bytes, len * sizeof(uint32_t));
- break;
- }
- default:
- UNIMPLEMENTED();
- }
- break;
- }
- case Dart_CObject_kExternalTypedData: {
- // TODO(ager): we are writing C pointers into the message in
- // order to post external arrays through ports. We need to make
- // sure that messages containing pointers can never be posted
- // to other processes.
-
- // Write out serialization header value for this object.
- WriteInlinedHeader(object);
- // Write out the class and tag information.
- WriteIndexedObject(kExternalTypedDataUint8ArrayCid);
- WriteTags(0);
- intptr_t length = object->value.as_external_typed_data.length;
- if (length < 0 || length > ExternalTypedData::MaxElements(
- kExternalTypedDataUint8ArrayCid)) {
- return false;
- }
- uint8_t* data = object->value.as_external_typed_data.data;
- void* peer = object->value.as_external_typed_data.peer;
- Dart_HandleFinalizer callback =
- object->value.as_external_typed_data.callback;
- if (callback == NULL) {
- return false;
- }
- WriteSmi(length);
- finalizable_data_->Put(length, reinterpret_cast<void*>(data), peer,
- callback);
- break;
- }
- case Dart_CObject_kSendPort: {
- WriteInlinedHeader(object);
- WriteIndexedObject(kSendPortCid);
- WriteTags(0);
- Write<int64_t>(object->value.as_send_port.id);
- Write<uint64_t>(object->value.as_send_port.origin_id);
- break;
- }
- case Dart_CObject_kCapability: {
- WriteInlinedHeader(object);
- WriteIndexedObject(kCapabilityCid);
- WriteTags(0);
- Write<uint64_t>(object->value.as_capability.id);
- break;
- }
- default:
- FATAL1("Unexpected Dart_CObject_Type %d\n", type);
- }
-
- return true;
-}
-
-std::unique_ptr<Message> ApiMessageWriter::WriteCMessage(
- Dart_CObject* object,
- Dart_Port dest_port,
- Message::Priority priority) {
- bool success = WriteCObject(object);
- if (!success) {
- UnmarkAllCObjects(object);
- intptr_t unused;
- free(Steal(&unused));
- return nullptr;
- }
-
- // Write out all objects that were added to the forward list and have
- // not been serialized yet. These would typically be fields of arrays.
- // NOTE: The forward list might grow as we process the list.
- for (intptr_t i = 0; i < forward_id_; i++) {
- success = WriteForwardedCObject(forward_list_[i]);
- if (!success) {
- UnmarkAllCObjects(object);
- intptr_t unused;
- free(Steal(&unused));
- return nullptr;
- }
- }
-
- UnmarkAllCObjects(object);
- MessageFinalizableData* finalizable_data = finalizable_data_;
- finalizable_data_ = nullptr;
- intptr_t size;
- uint8_t* buffer = Steal(&size);
- return Message::New(dest_port, buffer, size, finalizable_data, priority);
-}
-
-} // namespace dart
diff --git a/runtime/vm/dart_api_message.h b/runtime/vm/dart_api_message.h
index ace7dd3..f5994ce 100644
--- a/runtime/vm/dart_api_message.h
+++ b/runtime/vm/dart_api_message.h
@@ -15,185 +15,6 @@
namespace dart {
-// Use this C structure for reading internal objects in the serialized
-// data. These are objects that we need to process in order to
-// generate the Dart_CObject graph but that we don't want to expose in
-// that graph.
-struct Dart_CObject_Internal : public Dart_CObject {
- enum Type {
- kTypeArguments = Dart_CObject_kNumberOfTypes,
- kDynamicType,
- kClass,
- kView,
- kUninitialized,
- };
- struct Dart_CObject_Internal* cls;
- union {
- struct {
- struct _Dart_CObject* library_url;
- struct _Dart_CObject* class_name;
- } as_class;
- struct {
- struct _Dart_CObject* buffer;
- int offset_in_bytes;
- int length;
- } as_view;
- } internal;
-};
-
-// Reads a message snapshot into a C structure.
-class ApiMessageReader : public BaseReader {
- public:
- // The ApiMessageReader object must be enclosed by an ApiNativeScope.
- // Allocation of all C Heap objects is done in the zone associated with
- // the enclosing ApiNativeScope.
- explicit ApiMessageReader(Message* message);
- ~ApiMessageReader();
-
- Dart_CObject* ReadMessage();
-
- private:
- class BackRefNode {
- public:
- BackRefNode(Dart_CObject* reference, DeserializeState state)
- : reference_(reference), state_(state) {}
- Dart_CObject* reference() const { return reference_; }
- void set_reference(Dart_CObject* reference) { reference_ = reference; }
- bool is_deserialized() const { return state_ == kIsDeserialized; }
- void set_state(DeserializeState value) { state_ = value; }
-
- private:
- Dart_CObject* reference_;
- DeserializeState state_;
-
- DISALLOW_COPY_AND_ASSIGN(BackRefNode);
- };
-
- // Allocates a Dart_CObject object.
- Dart_CObject* AllocateDartCObject();
- // Allocates a Dart_CObject object with the specified type.
- Dart_CObject* AllocateDartCObject(Dart_CObject_Type type);
- // Allocates a Dart_CObject object representing an unsupported
- // object in the API message.
- Dart_CObject* AllocateDartCObjectUnsupported();
- // Allocates a Dart_CObject object for the null object.
- Dart_CObject* AllocateDartCObjectNull();
- // Allocates a Dart_CObject object for a boolean object.
- Dart_CObject* AllocateDartCObjectBool(bool value);
- // Allocates a Dart_CObject object for for a 32-bit integer.
- Dart_CObject* AllocateDartCObjectInt32(int32_t value);
- // Allocates a Dart_CObject object for for a 64-bit integer.
- Dart_CObject* AllocateDartCObjectInt64(int64_t value);
- // Allocates a Dart_CObject object for a double.
- Dart_CObject* AllocateDartCObjectDouble(double value);
- // Allocates a Dart_CObject object for string data.
- Dart_CObject* AllocateDartCObjectString(intptr_t length);
- // Allocates a C Dart_CObject object for a typed data.
- Dart_CObject* AllocateDartCObjectTypedData(Dart_TypedData_Type type,
- intptr_t length);
- // Allocates a C array of Dart_CObject objects.
- Dart_CObject* AllocateDartCObjectArray(intptr_t length);
- // Allocate a C Dart_CObject object for a VM isolate object.
- Dart_CObject* AllocateDartCObjectVmIsolateObj(intptr_t id);
- // Allocates a Dart_CObject_Internal object with the specified type.
- Dart_CObject_Internal* AllocateDartCObjectInternal(
- Dart_CObject_Internal::Type type);
- // Allocates a Dart_CObject_Internal object for a class object.
- Dart_CObject_Internal* AllocateDartCObjectClass();
- // Allocates a backwards reference node.
- BackRefNode* AllocateBackRefNode(Dart_CObject* ref, DeserializeState state);
-
- void Init();
-
- intptr_t LookupInternalClass(intptr_t class_header);
- Dart_CObject* ReadVMIsolateObject(intptr_t value);
- Dart_CObject* ReadInternalVMObject(intptr_t class_id, intptr_t object_id);
- Dart_CObject* ReadInlinedObject(intptr_t object_id);
- Dart_CObject* ReadObjectImpl();
- Dart_CObject* ReadIndexedObject(intptr_t object_id);
- Dart_CObject* ReadPredefinedSymbol(intptr_t object_id);
- Dart_CObject* ReadObjectRef();
- Dart_CObject* ReadObject();
-
- // Add object to backward references.
- void AddBackRef(intptr_t id, Dart_CObject* obj, DeserializeState state);
-
- // Get an object from the backward references list.
- Dart_CObject* GetBackRef(intptr_t id);
-
- intptr_t NextAvailableObjectId() const;
-
- Dart_CObject_Internal* AsInternal(Dart_CObject* object) {
- ASSERT(object->type >= Dart_CObject_kNumberOfTypes);
- return reinterpret_cast<Dart_CObject_Internal*>(object);
- }
-
- ObjectPtr VmIsolateSnapshotObject(intptr_t index) const {
- return Object::vm_isolate_snapshot_object_table().At(index);
- }
-
- Dart_CObject* CreateDartCObjectString(ObjectPtr raw);
- Dart_CObject* GetCanonicalMintObject(Dart_CObject_Type type, int64_t value64);
-
- uint8_t* allocator(intptr_t size) {
- return zone_->Realloc<uint8_t>(NULL, 0, size);
- }
-
- Zone* zone_; // Zone in which C heap objects are allocated.
- ApiGrowableArray<BackRefNode*> backward_references_;
- ApiGrowableArray<Dart_CObject*> vm_isolate_references_;
- Dart_CObject** vm_symbol_references_;
-
- Dart_CObject type_arguments_marker;
- Dart_CObject dynamic_type_marker;
-
- MessageFinalizableData* finalizable_data_;
-};
-
-class ApiMessageWriter : public BaseWriter {
- public:
- static const intptr_t kInitialSize = 512;
- ApiMessageWriter();
- ~ApiMessageWriter();
-
- // Writes a message with a single object.
- std::unique_ptr<Message> WriteCMessage(Dart_CObject* object,
- Dart_Port dest_port,
- Message::Priority priority);
-
- private:
- static const intptr_t kDartCObjectTypeBits = 4;
- static const intptr_t kDartCObjectTypeMask = (1 << kDartCObjectTypeBits) - 1;
- static const intptr_t kDartCObjectMarkMask = ~kDartCObjectTypeMask;
- static const intptr_t kDartCObjectMarkOffset = 1;
-
- void MarkCObject(Dart_CObject* object, intptr_t object_id);
- void UnmarkCObject(Dart_CObject* object);
- bool IsCObjectMarked(Dart_CObject* object);
- intptr_t GetMarkedCObjectMark(Dart_CObject* object);
- void UnmarkAllCObjects(Dart_CObject* object);
- void AddToForwardList(Dart_CObject* object);
-
- void WriteSmi(int64_t value);
- void WriteNullObject();
- void WriteMint(Dart_CObject* object, int64_t value);
- void WriteInt32(Dart_CObject* object);
- void WriteInt64(Dart_CObject* object);
- void WriteInlinedHeader(Dart_CObject* object);
- bool WriteCObject(Dart_CObject* object);
- bool WriteCObjectRef(Dart_CObject* object);
- bool WriteForwardedCObject(Dart_CObject* object);
- bool WriteCObjectInlined(Dart_CObject* object, Dart_CObject_Type type);
-
- intptr_t object_id_;
- Dart_CObject** forward_list_;
- intptr_t forward_list_length_;
- intptr_t forward_id_;
- MessageFinalizableData* finalizable_data_;
-
- DISALLOW_COPY_AND_ASSIGN(ApiMessageWriter);
-};
-
// This class handles translation of certain RawObjects to CObjects for
// NativeMessageHandlers.
//
diff --git a/runtime/vm/dart_entry.h b/runtime/vm/dart_entry.h
index 57025df..5740337 100644
--- a/runtime/vm/dart_entry.h
+++ b/runtime/vm/dart_entry.h
@@ -180,8 +180,6 @@
// A cache of VM heap allocated arguments descriptors.
static ArrayPtr cached_args_descriptors_[kCachedDescriptorCount];
- friend class SnapshotReader;
- friend class SnapshotWriter;
friend class Serializer;
friend class Deserializer;
friend class Simulator;
diff --git a/runtime/vm/handles.h b/runtime/vm/handles.h
index ca6b5f4..ed4e9db 100644
--- a/runtime/vm/handles.h
+++ b/runtime/vm/handles.h
@@ -100,6 +100,13 @@
return scoped_blocks_->AllocateHandle();
}
+ bool IsEmpty() const {
+ if (zone_blocks_ != nullptr) return false;
+ if (first_scoped_block_.HandleCount() != 0) return false;
+ if (scoped_blocks_ != &first_scoped_block_) return false;
+ return true;
+ }
+
protected:
// Returns a count of active handles (used for testing purposes).
int CountScopedHandles() const;
diff --git a/runtime/vm/heap/heap_test.cc b/runtime/vm/heap/heap_test.cc
index 20dc038..e1f9c82 100644
--- a/runtime/vm/heap/heap_test.cc
+++ b/runtime/vm/heap/heap_test.cc
@@ -16,6 +16,7 @@
#include "vm/heap/become.h"
#include "vm/heap/heap.h"
#include "vm/message_handler.h"
+#include "vm/message_snapshot.h"
#include "vm/object_graph.h"
#include "vm/port.h"
#include "vm/symbols.h"
@@ -544,8 +545,7 @@
isolate()->group()->api_state()->FreePersistentHandle(handle);
} else {
Thread* thread = Thread::Current();
- MessageSnapshotReader reader(message.get(), thread);
- response_obj = reader.ReadObject();
+ response_obj = ReadMessage(thread, message.get());
}
if (response_obj.IsString()) {
String& response = String::Handle();
diff --git a/runtime/vm/heap/scavenger.h b/runtime/vm/heap/scavenger.h
index ed36fe1..810a26e 100644
--- a/runtime/vm/heap/scavenger.h
+++ b/runtime/vm/heap/scavenger.h
@@ -12,6 +12,7 @@
#include "vm/flags.h"
#include "vm/globals.h"
#include "vm/heap/spaces.h"
+#include "vm/isolate.h"
#include "vm/lockers.h"
#include "vm/raw_object.h"
#include "vm/ring_buffer.h"
diff --git a/runtime/vm/heap/weak_table.cc b/runtime/vm/heap/weak_table.cc
index 4070590..36c903004 100644
--- a/runtime/vm/heap/weak_table.cc
+++ b/runtime/vm/heap/weak_table.cc
@@ -30,7 +30,7 @@
}
void WeakTable::SetValueExclusive(ObjectPtr key, intptr_t val) {
- intptr_t mask = size() - 1;
+ const intptr_t mask = size() - 1;
intptr_t idx = Hash(key) & mask;
intptr_t empty_idx = -1;
ObjectPtr obj = ObjectAtExclusive(idx);
@@ -74,6 +74,46 @@
}
}
+bool WeakTable::MarkValueExclusive(ObjectPtr key, intptr_t val) {
+ const intptr_t mask = size() - 1;
+ intptr_t idx = Hash(key) & mask;
+ intptr_t empty_idx = -1;
+ ObjectPtr obj = ObjectAtExclusive(idx);
+
+ while (obj != static_cast<ObjectPtr>(kNoEntry)) {
+ if (obj == key) {
+ return false;
+ } else if ((empty_idx < 0) &&
+ (static_cast<intptr_t>(obj) == kDeletedEntry)) {
+ empty_idx = idx; // Insert at this location if not found.
+ }
+ idx = (idx + 1) & mask;
+ obj = ObjectAtExclusive(idx);
+ }
+
+ ASSERT(val != 0);
+
+ if (empty_idx >= 0) {
+ // We will be reusing a slot below.
+ set_used(used() - 1);
+ idx = empty_idx;
+ }
+
+ ASSERT(!IsValidEntryAtExclusive(idx));
+ // Set the key and value.
+ SetObjectAt(idx, key);
+ SetValueAt(idx, val);
+ // Update the counts.
+ set_used(used() + 1);
+ set_count(count() + 1);
+
+ // Rehash if needed to ensure that there are empty slots available.
+ if (used_ >= limit()) {
+ Rehash();
+ }
+ return true;
+}
+
void WeakTable::Reset() {
intptr_t* old_data = data_;
used_ = 0;
diff --git a/runtime/vm/heap/weak_table.h b/runtime/vm/heap/weak_table.h
index 3062b53..ade129d 100644
--- a/runtime/vm/heap/weak_table.h
+++ b/runtime/vm/heap/weak_table.h
@@ -104,6 +104,7 @@
}
void SetValueExclusive(ObjectPtr key, intptr_t val);
+ bool MarkValueExclusive(ObjectPtr key, intptr_t val);
intptr_t GetValueExclusive(ObjectPtr key) const {
intptr_t mask = size() - 1;
@@ -203,7 +204,9 @@
void Rehash();
- static uword Hash(ObjectPtr key) { return static_cast<uword>(key) * 92821; }
+ static uword Hash(ObjectPtr key) {
+ return (static_cast<uword>(key) * 92821) ^ (static_cast<uword>(key) >> 8);
+ }
Mutex mutex_;
diff --git a/runtime/vm/isolate.cc b/runtime/vm/isolate.cc
index 2f5c24c..d7e8fcb 100644
--- a/runtime/vm/isolate.cc
+++ b/runtime/vm/isolate.cc
@@ -31,6 +31,7 @@
#include "vm/lockers.h"
#include "vm/log.h"
#include "vm/message_handler.h"
+#include "vm/message_snapshot.h"
#include "vm/object.h"
#include "vm/object_id_ring.h"
#include "vm/object_store.h"
@@ -123,18 +124,14 @@
static std::unique_ptr<Message> SerializeMessage(Dart_Port dest_port,
const Instance& obj) {
- if (ApiObjectConverter::CanConvert(obj.ptr())) {
- return Message::New(dest_port, obj.ptr(), Message::kNormalPriority);
- } else {
- MessageWriter writer(false);
- return writer.WriteMessage(obj, dest_port, Message::kNormalPriority);
- }
+ return WriteMessage(/* can_send_any_object */ false, obj, dest_port,
+ Message::kNormalPriority);
}
-static std::unique_ptr<Message> SerializeMessage(Dart_Port dest_port,
+static std::unique_ptr<Message> SerializeMessage(Zone* zone,
+ Dart_Port dest_port,
Dart_CObject* obj) {
- ApiMessageWriter writer;
- return writer.WriteCMessage(obj, dest_port, Message::kNormalPriority);
+ return WriteApiMessage(zone, obj, dest_port, Message::kNormalPriority);
}
void IsolateGroupSource::add_loaded_blob(
@@ -1008,9 +1005,8 @@
element = Capability::New(capability);
msg.SetAt(2, element);
- MessageWriter writer(false);
- PortMap::PostMessage(
- writer.WriteMessage(msg, main_port(), Message::kOOBPriority));
+ PortMap::PostMessage(WriteMessage(/* can_send_any_object */ false, msg,
+ main_port(), Message::kOOBPriority));
}
void IsolateGroup::set_object_store(ObjectStore* object_store) {
@@ -1330,11 +1326,7 @@
// Parse the message.
Object& msg_obj = Object::Handle(zone);
- if (message->IsRaw()) {
- msg_obj = message->raw_obj();
- // We should only be sending RawObjects that can be converted to CObjects.
- ASSERT(ApiObjectConverter::CanConvert(msg_obj.ptr()));
- } else if (message->IsPersistentHandle()) {
+ if (message->IsPersistentHandle()) {
// msg_array = [<message>, <object-in-message-to-rehash>]
const auto& msg_array = Array::Handle(
zone, Array::RawCast(message->persistent_handle()->ptr()));
@@ -1348,8 +1340,7 @@
}
}
} else {
- MessageSnapshotReader reader(message.get(), thread);
- msg_obj = reader.ReadObject();
+ msg_obj = ReadMessage(thread, message.get());
}
if (msg_obj.IsError()) {
// An error occurred while reading the message.
@@ -2360,7 +2351,7 @@
listener ^= listeners.At(i);
if (!listener.IsNull()) {
Dart_Port port_id = listener.Id();
- PortMap::PostMessage(SerializeMessage(port_id, &arr));
+ PortMap::PostMessage(SerializeMessage(current_zone(), port_id, &arr));
}
}
return listeners.Length() > 0;
@@ -3297,9 +3288,9 @@
msg.SetAt(1, element);
element = Smi::New(Isolate::kBeforeNextEventAction);
msg.SetAt(2, element);
- MessageWriter writer(false);
- std::unique_ptr<Message> message =
- writer.WriteMessage(msg, main_port(), Message::kOOBPriority);
+ std::unique_ptr<Message> message = WriteMessage(
+ /* can_send_any_object */ false, msg, main_port(),
+ Message::kOOBPriority);
bool posted = PortMap::PostMessage(std::move(message));
ASSERT(posted);
}
@@ -3543,9 +3534,9 @@
list_values[3] = &imm;
{
- ApiMessageWriter writer;
- std::unique_ptr<Message> message =
- writer.WriteCMessage(&kill_msg, main_port(), Message::kOOBPriority);
+ AllocOnlyStackZone zone;
+ std::unique_ptr<Message> message = WriteApiMessage(
+ zone.GetZone(), &kill_msg, main_port(), Message::kOOBPriority);
ASSERT(message != nullptr);
// Post the message at the given port.
diff --git a/runtime/vm/message_snapshot.cc b/runtime/vm/message_snapshot.cc
new file mode 100644
index 0000000..ae7a6ad
--- /dev/null
+++ b/runtime/vm/message_snapshot.cc
@@ -0,0 +1,3616 @@
+// Copyright (c) 2021, 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.
+
+#include "vm/message_snapshot.h"
+
+#include <memory>
+
+#include "platform/assert.h"
+#include "platform/unicode.h"
+#include "vm/class_finalizer.h"
+#include "vm/class_id.h"
+#include "vm/dart_api_message.h"
+#include "vm/dart_api_state.h"
+#include "vm/dart_entry.h"
+#include "vm/flags.h"
+#include "vm/growable_array.h"
+#include "vm/heap/heap.h"
+#include "vm/heap/weak_table.h"
+#include "vm/longjump.h"
+#include "vm/object.h"
+#include "vm/object_store.h"
+#include "vm/symbols.h"
+#include "vm/type_testing_stubs.h"
+
+namespace dart {
+
+static Dart_CObject cobj_null = {.type = Dart_CObject_kNull,
+ .value = {.as_int64 = 0}};
+static Dart_CObject cobj_sentinel = {.type = Dart_CObject_kUnsupported};
+static Dart_CObject cobj_transition_sentinel = {.type =
+ Dart_CObject_kUnsupported};
+static Dart_CObject cobj_empty_array = {
+ .type = Dart_CObject_kArray,
+ .value = {.as_array = {.length = 0, .values = nullptr}}};
+static Dart_CObject cobj_zero_array_element = {.type = Dart_CObject_kInt32,
+ .value = {.as_int32 = 0}};
+static Dart_CObject* cobj_zero_array_values[1] = {&cobj_zero_array_element};
+static Dart_CObject cobj_zero_array = {
+ .type = Dart_CObject_kArray,
+ .value = {.as_array = {.length = 1, .values = &cobj_zero_array_values[0]}}};
+static Dart_CObject cobj_dynamic_type = {.type = Dart_CObject_kUnsupported};
+static Dart_CObject cobj_void_type = {.type = Dart_CObject_kUnsupported};
+static Dart_CObject cobj_empty_type_arguments = {.type =
+ Dart_CObject_kUnsupported};
+static Dart_CObject cobj_true = {.type = Dart_CObject_kBool,
+ .value = {.as_bool = true}};
+static Dart_CObject cobj_false = {.type = Dart_CObject_kBool,
+ .value = {.as_bool = false}};
+
+enum class MessagePhase {
+ kBeforeTypes = 0,
+ kTypes = 1,
+ kCanonicalInstances = 2,
+ kNonCanonicalInstances = 3,
+
+ kNumPhases = 4,
+};
+
+class MessageSerializer;
+class MessageDeserializer;
+class ApiMessageSerializer;
+class ApiMessageDeserializer;
+class WeakPropertyMessageSerializationCluster;
+
+class MessageSerializationCluster : public ZoneAllocated {
+ public:
+ explicit MessageSerializationCluster(const char* name,
+ MessagePhase phase,
+ intptr_t cid,
+ bool is_canonical = false)
+ : name_(name), phase_(phase), cid_(cid), is_canonical_(is_canonical) {}
+ virtual ~MessageSerializationCluster() {}
+
+ virtual void Trace(MessageSerializer* s, Object* object) = 0;
+ virtual void WriteNodes(MessageSerializer* s) = 0;
+ virtual void WriteEdges(MessageSerializer* s) {}
+
+ virtual void TraceApi(ApiMessageSerializer* s, Dart_CObject* object) {}
+ virtual void WriteNodesApi(ApiMessageSerializer* s) {}
+ virtual void WriteEdgesApi(ApiMessageSerializer* s) {}
+
+ const char* name() const { return name_; }
+ MessagePhase phase() const { return phase_; }
+ intptr_t cid() const { return cid_; }
+ bool is_canonical() const { return is_canonical_; }
+
+ protected:
+ const char* const name_;
+ const MessagePhase phase_;
+ const intptr_t cid_;
+ const bool is_canonical_;
+
+ DISALLOW_COPY_AND_ASSIGN(MessageSerializationCluster);
+};
+
+class MessageDeserializationCluster : public ZoneAllocated {
+ public:
+ explicit MessageDeserializationCluster(const char* name,
+ bool is_canonical = false)
+ : name_(name),
+ is_canonical_(is_canonical),
+ start_index_(0),
+ stop_index_(0) {}
+ virtual ~MessageDeserializationCluster() {}
+
+ virtual void ReadNodes(MessageDeserializer* d) = 0;
+ virtual void ReadEdges(MessageDeserializer* d) {}
+ virtual ObjectPtr PostLoad(MessageDeserializer* d) { return nullptr; }
+ virtual void ReadNodesApi(ApiMessageDeserializer* d) {}
+ virtual void ReadEdgesApi(ApiMessageDeserializer* d) {}
+ virtual void PostLoadApi(ApiMessageDeserializer* d) {}
+
+ void ReadNodesWrapped(MessageDeserializer* d);
+ void ReadNodesWrappedApi(ApiMessageDeserializer* d);
+
+ const char* name() const { return name_; }
+ bool is_canonical() const { return is_canonical_; }
+
+ protected:
+ ObjectPtr PostLoadAbstractType(MessageDeserializer* d);
+ ObjectPtr PostLoadLinkedHash(MessageDeserializer* d);
+
+ const char* const name_;
+ const bool is_canonical_;
+ // The range of the ref array that belongs to this cluster.
+ intptr_t start_index_;
+ intptr_t stop_index_;
+
+ DISALLOW_COPY_AND_ASSIGN(MessageDeserializationCluster);
+};
+
+class BaseSerializer : public StackResource {
+ public:
+ BaseSerializer(Thread* thread, Zone* zone);
+ ~BaseSerializer();
+
+ // Writes raw data to the stream (basic type).
+ // sizeof(T) must be in {1,2,4,8}.
+ template <typename T>
+ void Write(T value) {
+ BaseWriteStream::Raw<sizeof(T), T>::Write(&stream_, value);
+ }
+ void WriteUnsigned(intptr_t value) { stream_.WriteUnsigned(value); }
+ void WriteWordWith32BitWrites(uword value) {
+ stream_.WriteWordWith32BitWrites(value);
+ }
+ void WriteBytes(const uint8_t* addr, intptr_t len) {
+ stream_.WriteBytes(addr, len);
+ }
+ void WriteAscii(const String& str) {
+ intptr_t len = str.Length();
+ WriteUnsigned(len);
+ for (intptr_t i = 0; i < len; i++) {
+ int64_t c = str.CharAt(i);
+ ASSERT(c < 128);
+ Write<uint8_t>(c);
+ }
+ Write<uint8_t>(0);
+ }
+
+ MessageSerializationCluster* NewClusterForClass(intptr_t cid,
+ bool is_canonical);
+ void WriteCluster(MessageSerializationCluster* cluster);
+
+ std::unique_ptr<Message> Finish(Dart_Port dest_port,
+ Message::Priority priority) {
+ MessageFinalizableData* finalizable_data = finalizable_data_;
+ finalizable_data_ = nullptr;
+ finalizable_data->SerializationSucceeded();
+ intptr_t size;
+ uint8_t* buffer = stream_.Steal(&size);
+ return Message::New(dest_port, buffer, size, finalizable_data, priority);
+ }
+
+ Zone* zone() const { return zone_; }
+ MessageFinalizableData* finalizable_data() const { return finalizable_data_; }
+ intptr_t next_ref_index() const { return next_ref_index_; }
+
+ protected:
+ Zone* const zone_;
+ MallocWriteStream stream_;
+ MessageFinalizableData* finalizable_data_;
+ GrowableArray<MessageSerializationCluster*> clusters_;
+ WeakPropertyMessageSerializationCluster* ephemeron_cluster_;
+ intptr_t num_base_objects_;
+ intptr_t num_written_objects_;
+ intptr_t next_ref_index_;
+};
+
+class MessageSerializer : public BaseSerializer {
+ public:
+ MessageSerializer(Thread* thread, bool can_send_any_object);
+ ~MessageSerializer();
+
+ bool MarkObjectId(ObjectPtr object, intptr_t id) {
+ ASSERT(id != WeakTable::kNoValue);
+ WeakTable* table;
+ if (!object->IsSmiOrOldObject()) {
+ table = isolate()->forward_table_new();
+ } else {
+ table = isolate()->forward_table_old();
+ }
+ return table->MarkValueExclusive(object, id);
+ }
+
+ void SetObjectId(ObjectPtr object, intptr_t id) {
+ ASSERT(id != WeakTable::kNoValue);
+ WeakTable* table;
+ if (!object->IsSmiOrOldObject()) {
+ table = isolate()->forward_table_new();
+ } else {
+ table = isolate()->forward_table_old();
+ }
+ table->SetValueExclusive(object, id);
+ }
+
+ intptr_t GetObjectId(ObjectPtr object) const {
+ const WeakTable* table;
+ if (!object->IsSmiOrOldObject()) {
+ table = isolate()->forward_table_new();
+ } else {
+ table = isolate()->forward_table_old();
+ }
+ return table->GetValueExclusive(object);
+ }
+
+ DART_NOINLINE void AddBaseObject(ObjectPtr base_object) {
+ AssignRef(base_object);
+ num_base_objects_++;
+ }
+ DART_NOINLINE void AssignRef(ObjectPtr object) {
+ SetObjectId(object, next_ref_index_);
+ next_ref_index_++;
+ }
+ void AssignRef(Object* object) { AssignRef(object->ptr()); }
+
+ void Push(ObjectPtr object);
+
+ void Trace(Object* object);
+
+ void IllegalObject(const Object& object, const char* message);
+
+ void AddBaseObjects();
+ void Serialize(const Object& root);
+
+ DART_NOINLINE void WriteRef(ObjectPtr object) {
+ intptr_t index = GetObjectId(object);
+ ASSERT(index != WeakTable::kNoValue);
+ WriteUnsigned(index);
+ }
+
+ bool can_send_any_object() const { return can_send_any_object_; }
+ const char* exception_message() const { return exception_message_; }
+ Thread* thread() const {
+ return static_cast<Thread*>(StackResource::thread());
+ }
+ Isolate* isolate() const { return thread()->isolate(); }
+ IsolateGroup* isolate_group() const { return thread()->isolate_group(); }
+
+ bool HasRef(ObjectPtr object) const {
+ return GetObjectId(object) != WeakTable::kNoValue;
+ }
+
+ private:
+ WeakTable* forward_table_new_;
+ WeakTable* forward_table_old_;
+ GrowableArray<Object*> stack_;
+ bool const can_send_any_object_;
+ const char* exception_message_;
+};
+
+class ApiMessageSerializer : public BaseSerializer {
+ public:
+ explicit ApiMessageSerializer(Zone* zone);
+ ~ApiMessageSerializer();
+
+ bool MarkObjectId(Dart_CObject* object, intptr_t id) {
+ ASSERT(id != WeakTable::kNoValue);
+ return forward_table_.MarkValueExclusive(
+ static_cast<ObjectPtr>(reinterpret_cast<uword>(object)), id);
+ }
+
+ void SetObjectId(Dart_CObject* object, intptr_t id) {
+ ASSERT(id != WeakTable::kNoValue);
+ forward_table_.SetValueExclusive(
+ static_cast<ObjectPtr>(reinterpret_cast<uword>(object)), id);
+ }
+
+ intptr_t GetObjectId(Dart_CObject* object) const {
+ return forward_table_.GetValueExclusive(
+ static_cast<ObjectPtr>(reinterpret_cast<uword>(object)));
+ }
+
+ DART_NOINLINE void AddBaseObject(Dart_CObject* base_object) {
+ AssignRef(base_object);
+ num_base_objects_++;
+ }
+ DART_NOINLINE intptr_t AssignRef(Dart_CObject* object) {
+ SetObjectId(object, next_ref_index_);
+ return next_ref_index_++;
+ }
+ void ForwardRef(Dart_CObject* old, Dart_CObject* nue) {
+ intptr_t id = GetObjectId(nue);
+ ASSERT(id != WeakTable::kNoValue);
+ SetObjectId(old, id);
+ num_written_objects_--;
+ }
+
+ void Push(Dart_CObject* object);
+
+ bool Trace(Dart_CObject* object);
+
+ void AddBaseObjects();
+ bool Serialize(Dart_CObject* root);
+
+ void WriteRef(Dart_CObject* object) {
+ intptr_t index = GetObjectId(object);
+ ASSERT(index != WeakTable::kNoValue);
+ WriteUnsigned(index);
+ }
+
+ bool Fail(const char* message) {
+ exception_message_ = message;
+ return false;
+ }
+
+ private:
+ WeakTable forward_table_;
+ GrowableArray<Dart_CObject*> stack_;
+ const char* exception_message_;
+};
+
+class BaseDeserializer : public ValueObject {
+ public:
+ BaseDeserializer(Zone* zone, Message* message);
+ ~BaseDeserializer();
+
+ // Reads raw data (for basic types).
+ // sizeof(T) must be in {1,2,4,8}.
+ template <typename T>
+ T Read() {
+ return ReadStream::Raw<sizeof(T), T>::Read(&stream_);
+ }
+ intptr_t ReadUnsigned() { return stream_.ReadUnsigned(); }
+ uword ReadWordWith32BitReads() { return stream_.ReadWordWith32BitReads(); }
+ void ReadBytes(uint8_t* addr, intptr_t len) { stream_.ReadBytes(addr, len); }
+ const char* ReadAscii() {
+ intptr_t len = ReadUnsigned();
+ const char* result = reinterpret_cast<const char*>(CurrentBufferAddress());
+ Advance(len + 1);
+ return result;
+ }
+
+ const uint8_t* CurrentBufferAddress() const {
+ return stream_.AddressOfCurrentPosition();
+ }
+
+ void Advance(intptr_t value) { stream_.Advance(value); }
+
+ MessageDeserializationCluster* ReadCluster();
+
+ Zone* zone() const { return zone_; }
+ intptr_t next_index() const { return next_ref_index_; }
+ MessageFinalizableData* finalizable_data() const { return finalizable_data_; }
+
+ protected:
+ Zone* zone_;
+ ReadStream stream_;
+ MessageFinalizableData* finalizable_data_;
+ intptr_t next_ref_index_;
+};
+
+class MessageDeserializer : public BaseDeserializer {
+ public:
+ MessageDeserializer(Thread* thread, Message* message)
+ : BaseDeserializer(thread->zone(), message),
+ thread_(thread),
+ refs_(Array::Handle(thread->zone())) {}
+ ~MessageDeserializer() {}
+
+ DART_NOINLINE void AddBaseObject(ObjectPtr base_object) {
+ AssignRef(base_object);
+ }
+ void AssignRef(ObjectPtr object) {
+ refs_.untag()->set_element(next_ref_index_, object);
+ next_ref_index_++;
+ }
+
+ ObjectPtr Ref(intptr_t index) const {
+ ASSERT(index > 0);
+ ASSERT(index <= next_ref_index_);
+ return refs_.At(index);
+ }
+ void UpdateRef(intptr_t index, const Object& new_object) {
+ ASSERT(index > 0);
+ ASSERT(index <= next_ref_index_);
+ refs_.SetAt(index, new_object);
+ }
+
+ ObjectPtr ReadRef() { return Ref(ReadUnsigned()); }
+
+ void AddBaseObjects();
+ ObjectPtr Deserialize();
+
+ Thread* thread() const { return thread_; }
+ IsolateGroup* isolate_group() const { return thread_->isolate_group(); }
+ ArrayPtr refs() const { return refs_.ptr(); }
+
+ private:
+ Thread* const thread_;
+ Array& refs_;
+};
+
+class ApiMessageDeserializer : public BaseDeserializer {
+ public:
+ ApiMessageDeserializer(Zone* zone, Message* message)
+ : BaseDeserializer(zone, message), refs_(nullptr) {}
+ ~ApiMessageDeserializer() {}
+
+ void AddBaseObject(Dart_CObject* base_object) { AssignRef(base_object); }
+ void AssignRef(Dart_CObject* object) {
+ refs_[next_ref_index_] = object;
+ next_ref_index_++;
+ }
+
+ Dart_CObject* Allocate(Dart_CObject_Type type) {
+ Dart_CObject* result = zone()->Alloc<Dart_CObject>(1);
+ result->type = type;
+ return result;
+ }
+
+ Dart_CObject* Ref(intptr_t index) const {
+ ASSERT(index > 0);
+ ASSERT(index <= next_ref_index_);
+ return refs_[index];
+ }
+
+ Dart_CObject* ReadRef() { return Ref(ReadUnsigned()); }
+
+ void AddBaseObjects();
+ Dart_CObject* Deserialize();
+
+ private:
+ Dart_CObject** refs_;
+};
+
+void MessageDeserializationCluster::ReadNodesWrapped(MessageDeserializer* d) {
+ start_index_ = d->next_index();
+ this->ReadNodes(d);
+ stop_index_ = d->next_index();
+}
+
+void MessageDeserializationCluster::ReadNodesWrappedApi(
+ ApiMessageDeserializer* d) {
+ start_index_ = d->next_index();
+ this->ReadNodesApi(d);
+ stop_index_ = d->next_index();
+}
+
+ObjectPtr MessageDeserializationCluster::PostLoadAbstractType(
+ MessageDeserializer* d) {
+ ClassFinalizer::FinalizationKind finalization =
+ is_canonical() ? ClassFinalizer::kCanonicalize
+ : ClassFinalizer::kFinalize;
+ AbstractType& type = AbstractType::Handle(d->zone());
+ Code& code = Code::Handle(d->zone());
+ for (intptr_t id = start_index_; id < stop_index_; id++) {
+ type ^= d->Ref(id);
+
+ code = TypeTestingStubGenerator::DefaultCodeForType(type);
+ type.InitializeTypeTestingStubNonAtomic(code);
+
+ type ^= ClassFinalizer::FinalizeType(type, finalization);
+ d->UpdateRef(id, type);
+ }
+ return nullptr;
+}
+
+ObjectPtr MessageDeserializationCluster::PostLoadLinkedHash(
+ MessageDeserializer* d) {
+ ASSERT(!is_canonical());
+ Array& maps = Array::Handle(d->zone(), d->refs());
+ maps = maps.Slice(start_index_, stop_index_ - start_index_,
+ /*with_type_argument=*/false);
+ return DartLibraryCalls::RehashObjects(d->thread(), maps);
+}
+
+class ClassMessageSerializationCluster : public MessageSerializationCluster {
+ public:
+ ClassMessageSerializationCluster()
+ : MessageSerializationCluster("Class",
+ MessagePhase::kBeforeTypes,
+ kClassCid),
+ objects_() {}
+ ~ClassMessageSerializationCluster() {}
+
+ void Trace(MessageSerializer* s, Object* object) {
+ Class* cls = static_cast<Class*>(object);
+ objects_.Add(cls);
+ }
+
+ void WriteNodes(MessageSerializer* s) {
+ intptr_t count = objects_.length();
+ s->WriteUnsigned(count);
+ Library& lib = Library::Handle(s->zone());
+ String& str = String::Handle(s->zone());
+ for (intptr_t i = 0; i < count; i++) {
+ Class* cls = objects_[i];
+ s->AssignRef(cls);
+ intptr_t cid = cls->id();
+ if (cid < kNumPredefinedCids) {
+ ASSERT(cid != 0);
+ s->WriteUnsigned(cid);
+ } else {
+ s->WriteUnsigned(0);
+ lib = cls->library();
+ str = lib.url();
+ s->WriteAscii(str);
+ str = cls->Name();
+ s->WriteAscii(str);
+ }
+ }
+ }
+
+ private:
+ GrowableArray<Class*> objects_;
+};
+
+class ClassMessageDeserializationCluster
+ : public MessageDeserializationCluster {
+ public:
+ ClassMessageDeserializationCluster()
+ : MessageDeserializationCluster("Class") {}
+ ~ClassMessageDeserializationCluster() {}
+
+ void ReadNodes(MessageDeserializer* d) {
+ auto* class_table = d->isolate_group()->class_table();
+ String& str = String::Handle(d->zone());
+ Library& lib = Library::Handle(d->zone());
+ Class& cls = Class::Handle(d->zone());
+ intptr_t count = d->ReadUnsigned();
+ for (intptr_t i = 0; i < count; i++) {
+ intptr_t cid = d->ReadUnsigned();
+ if (cid != 0) {
+ cls = class_table->At(cid);
+ } else {
+ str = String::New(d->ReadAscii()); // Library URI.
+ lib = Library::LookupLibrary(d->thread(), str);
+ RELEASE_ASSERT(!lib.IsNull());
+ str = String::New(d->ReadAscii()); // Class name.
+ if (str.Equals(Symbols::TopLevel())) {
+ cls = lib.toplevel_class();
+ } else {
+ cls = lib.LookupClass(str);
+ }
+ RELEASE_ASSERT(!cls.IsNull());
+ cls.EnsureIsFinalized(d->thread());
+ }
+ d->AssignRef(cls.ptr());
+ }
+ }
+
+ void ReadNodesApi(ApiMessageDeserializer* d) {
+ intptr_t count = d->ReadUnsigned();
+ for (intptr_t i = 0; i < count; i++) {
+ intptr_t cid = d->ReadUnsigned();
+ if (cid == 0) {
+ d->ReadAscii(); // Library URI.
+ d->ReadAscii(); // Class name.
+ }
+ d->AssignRef(nullptr);
+ }
+ }
+};
+
+class TypeArgumentsMessageSerializationCluster
+ : public MessageSerializationCluster {
+ public:
+ explicit TypeArgumentsMessageSerializationCluster(bool is_canonical)
+ : MessageSerializationCluster("TypeArguments",
+ MessagePhase::kTypes,
+ kTypeArgumentsCid,
+ is_canonical) {}
+ ~TypeArgumentsMessageSerializationCluster() {}
+
+ void Trace(MessageSerializer* s, Object* object) {
+ TypeArguments* type_args = static_cast<TypeArguments*>(object);
+ objects_.Add(type_args);
+
+ s->Push(type_args->untag()->instantiations());
+ intptr_t length = Smi::Value(type_args->untag()->length());
+ for (intptr_t i = 0; i < length; i++) {
+ s->Push(type_args->untag()->element(i));
+ }
+ }
+
+ void WriteNodes(MessageSerializer* s) {
+ intptr_t count = objects_.length();
+ s->WriteUnsigned(count);
+ for (intptr_t i = 0; i < count; i++) {
+ TypeArguments* type_args = objects_[i];
+ s->AssignRef(type_args);
+ intptr_t length = Smi::Value(type_args->untag()->length());
+ s->WriteUnsigned(length);
+ }
+ }
+
+ void WriteEdges(MessageSerializer* s) {
+ intptr_t count = objects_.length();
+ for (intptr_t i = 0; i < count; i++) {
+ TypeArguments* type_args = objects_[i];
+ intptr_t hash = Smi::Value(type_args->untag()->hash());
+ s->Write<int32_t>(hash);
+ const intptr_t nullability =
+ Smi::Value(type_args->untag()->nullability());
+ s->WriteUnsigned(nullability);
+
+ intptr_t length = Smi::Value(type_args->untag()->length());
+ s->WriteUnsigned(length);
+ for (intptr_t j = 0; j < length; j++) {
+ s->WriteRef(type_args->untag()->element(j));
+ }
+ }
+ }
+
+ private:
+ GrowableArray<TypeArguments*> objects_;
+};
+
+class TypeArgumentsMessageDeserializationCluster
+ : public MessageDeserializationCluster {
+ public:
+ explicit TypeArgumentsMessageDeserializationCluster(bool is_canonical)
+ : MessageDeserializationCluster("TypeArguments", is_canonical) {}
+ ~TypeArgumentsMessageDeserializationCluster() {}
+
+ void ReadNodes(MessageDeserializer* d) {
+ intptr_t count = d->ReadUnsigned();
+ for (intptr_t i = 0; i < count; i++) {
+ intptr_t length = d->ReadUnsigned();
+ d->AssignRef(TypeArguments::New(length));
+ }
+ }
+
+ void ReadEdges(MessageDeserializer* d) {
+ for (intptr_t id = start_index_; id < stop_index_; id++) {
+ TypeArgumentsPtr type_args = static_cast<TypeArgumentsPtr>(d->Ref(id));
+
+ type_args->untag()->hash_ = Smi::New(d->Read<int32_t>());
+ type_args->untag()->nullability_ = Smi::New(d->ReadUnsigned());
+
+ intptr_t length = d->ReadUnsigned();
+ for (intptr_t j = 0; j < length; j++) {
+ type_args->untag()->types()[j] =
+ static_cast<AbstractTypePtr>(d->ReadRef());
+ }
+ }
+ }
+
+ ObjectPtr PostLoad(MessageDeserializer* d) {
+ if (is_canonical()) {
+ TypeArguments& type_args = TypeArguments::Handle(d->zone());
+ for (intptr_t id = start_index_; id < stop_index_; id++) {
+ type_args ^= d->Ref(id);
+ type_args ^= type_args.Canonicalize(d->thread());
+ d->UpdateRef(id, type_args);
+ }
+ }
+ return nullptr;
+ }
+
+ void ReadNodesApi(ApiMessageDeserializer* d) {
+ intptr_t count = d->ReadUnsigned();
+ for (intptr_t i = 0; i < count; i++) {
+ d->ReadUnsigned(); // Length.
+ d->AssignRef(nullptr);
+ }
+ }
+
+ void ReadEdgesApi(ApiMessageDeserializer* d) {
+ for (intptr_t id = start_index_; id < stop_index_; id++) {
+ d->Read<int32_t>(); // Hash.
+ d->ReadUnsigned(); // Nullability.
+ intptr_t length = d->ReadUnsigned();
+ for (intptr_t j = 0; j < length; j++) {
+ d->ReadRef(); // Element.
+ }
+ }
+ }
+};
+
+class FunctionMessageSerializationCluster : public MessageSerializationCluster {
+ public:
+ FunctionMessageSerializationCluster()
+ : MessageSerializationCluster("Function",
+ MessagePhase::kBeforeTypes,
+ kFunctionCid) {}
+ ~FunctionMessageSerializationCluster() {}
+
+ void Trace(MessageSerializer* s, Object* object) {
+ Function* func = static_cast<Function*>(object);
+ objects_.Add(func);
+ }
+
+ void WriteNodes(MessageSerializer* s) {
+ intptr_t count = objects_.length();
+ s->WriteUnsigned(count);
+ Library& lib = Library::Handle(s->zone());
+ Class& cls = Class::Handle(s->zone());
+ String& str = String::Handle(s->zone());
+ for (intptr_t i = 0; i < count; i++) {
+ Function* func = objects_[i];
+ s->AssignRef(func);
+ cls ^= func->Owner();
+ lib = cls.library();
+ str = lib.url();
+ s->WriteAscii(str);
+ str = cls.Name();
+ s->WriteAscii(str);
+ str = func->name();
+ s->WriteAscii(str);
+ }
+ }
+
+ private:
+ GrowableArray<Function*> objects_;
+};
+
+class FunctionMessageDeserializationCluster
+ : public MessageDeserializationCluster {
+ public:
+ FunctionMessageDeserializationCluster()
+ : MessageDeserializationCluster("Function") {}
+ ~FunctionMessageDeserializationCluster() {}
+
+ void ReadNodes(MessageDeserializer* d) {
+ intptr_t count = d->ReadUnsigned();
+ String& str = String::Handle(d->zone());
+ Library& lib = Library::Handle(d->zone());
+ Class& cls = Class::Handle(d->zone());
+ Function& func = Function::Handle(d->zone());
+ for (intptr_t i = 0; i < count; i++) {
+ str = String::New(d->ReadAscii()); // Library URI.
+ lib = Library::LookupLibrary(d->thread(), str);
+ RELEASE_ASSERT(!lib.IsNull());
+ str = String::New(d->ReadAscii()); // Class name.
+ if (str.Equals(Symbols::TopLevel())) {
+ cls = lib.toplevel_class();
+ } else {
+ cls = lib.LookupClass(str);
+ }
+ RELEASE_ASSERT(!cls.IsNull());
+ cls.EnsureIsFinalized(d->thread());
+ str = String::New(d->ReadAscii()); // Function name.
+ func = cls.LookupStaticFunction(str);
+ RELEASE_ASSERT(!func.IsNull());
+ d->AssignRef(func.ptr());
+ }
+ }
+};
+
+class InstanceMessageSerializationCluster : public MessageSerializationCluster {
+ public:
+ InstanceMessageSerializationCluster(bool is_canonical, intptr_t cid)
+ : MessageSerializationCluster("Instance",
+ is_canonical
+ ? MessagePhase::kCanonicalInstances
+ : MessagePhase::kNonCanonicalInstances,
+ cid,
+ is_canonical),
+ cls_(Class::Handle()) {
+ cls_ = IsolateGroup::Current()->class_table()->At(cid);
+ next_field_offset_ = cls_.host_next_field_offset();
+ }
+ ~InstanceMessageSerializationCluster() {}
+
+ void Trace(MessageSerializer* s, Object* object) {
+ Instance* instance = static_cast<Instance*>(object);
+ objects_.Add(instance);
+
+ const intptr_t next_field_offset = next_field_offset_;
+ const auto unboxed_fields_bitmap =
+ s->isolate_group()->shared_class_table()->GetUnboxedFieldsMapAt(cid_);
+ for (intptr_t offset = Instance::NextFieldOffset();
+ offset < next_field_offset; offset += kCompressedWordSize) {
+ if (unboxed_fields_bitmap.Get(offset / kCompressedWordSize)) {
+ continue;
+ }
+ s->Push(reinterpret_cast<CompressedObjectPtr*>(
+ reinterpret_cast<uword>(instance->untag()) + offset)
+ ->Decompress(instance->untag()->heap_base()));
+ }
+ }
+
+ void WriteNodes(MessageSerializer* s) {
+ s->WriteRef(cls_.ptr());
+
+ intptr_t count = objects_.length();
+ s->WriteUnsigned(count);
+ for (intptr_t i = 0; i < count; i++) {
+ Instance* instance = objects_[i];
+ s->AssignRef(instance);
+ }
+ }
+
+ void WriteEdges(MessageSerializer* s) {
+ intptr_t count = objects_.length();
+ for (intptr_t i = 0; i < count; i++) {
+ Instance* instance = objects_[i];
+
+ const intptr_t next_field_offset = next_field_offset_;
+ const auto unboxed_fields_bitmap =
+ s->isolate_group()->shared_class_table()->GetUnboxedFieldsMapAt(cid_);
+ for (intptr_t offset = Instance::NextFieldOffset();
+ offset < next_field_offset; offset += kCompressedWordSize) {
+ if (unboxed_fields_bitmap.Get(offset / kCompressedWordSize)) {
+ // Writes 32 bits of the unboxed value at a time
+ const uword value = *reinterpret_cast<compressed_uword*>(
+ reinterpret_cast<uword>(instance->untag()) + offset);
+ s->WriteWordWith32BitWrites(value);
+ } else {
+ s->WriteRef(reinterpret_cast<CompressedObjectPtr*>(
+ reinterpret_cast<uword>(instance->untag()) + offset)
+ ->Decompress(instance->untag()->heap_base()));
+ }
+ }
+ }
+ }
+
+ private:
+ Class& cls_;
+ intptr_t next_field_offset_;
+ GrowableArray<Instance*> objects_;
+};
+
+class InstanceMessageDeserializationCluster
+ : public MessageDeserializationCluster {
+ public:
+ explicit InstanceMessageDeserializationCluster(bool is_canonical)
+ : MessageDeserializationCluster("Instance", is_canonical),
+ cls_(Class::Handle()) {}
+ ~InstanceMessageDeserializationCluster() {}
+
+ void ReadNodes(MessageDeserializer* d) {
+ cls_ ^= d->ReadRef();
+
+ intptr_t count = d->ReadUnsigned();
+ for (intptr_t i = 0; i < count; i++) {
+ d->AssignRef(Instance::New(cls_));
+ }
+ }
+
+ void ReadEdges(MessageDeserializer* d) {
+ const intptr_t next_field_offset = cls_.host_next_field_offset();
+ const intptr_t type_argument_field_offset =
+ cls_.host_type_arguments_field_offset();
+ const auto unboxed_fields_bitmap =
+ d->isolate_group()->shared_class_table()->GetUnboxedFieldsMapAt(
+ cls_.id());
+ const bool use_field_guards = d->isolate_group()->use_field_guards();
+ const Array& field_map = Array::Handle(d->zone(), cls_.OffsetToFieldMap());
+ Instance& instance = Instance::Handle(d->zone());
+ Object& value = Object::Handle(d->zone());
+ Field& field = Field::Handle(d->zone());
+
+ for (intptr_t id = start_index_; id < stop_index_; id++) {
+ instance ^= d->Ref(id);
+ for (intptr_t offset = Instance::NextFieldOffset();
+ offset < next_field_offset; offset += kCompressedWordSize) {
+ if (unboxed_fields_bitmap.Get(offset / kCompressedWordSize)) {
+ compressed_uword* p = reinterpret_cast<compressed_uword*>(
+ reinterpret_cast<uword>(instance.untag()) + offset);
+ // Reads 32 bits of the unboxed value at a time
+ *p = d->ReadWordWith32BitReads();
+ } else {
+ value = d->ReadRef();
+ instance.SetFieldAtOffset(offset, value);
+ if (use_field_guards && (offset != type_argument_field_offset) &&
+ (value.ptr() != Object::sentinel().ptr())) {
+ field ^= field_map.At(offset >> kCompressedWordSizeLog2);
+ ASSERT(!field.IsNull());
+ ASSERT(field.HostOffset() == offset);
+ field.RecordStore(value);
+ }
+ }
+ }
+ }
+ }
+
+ ObjectPtr PostLoad(MessageDeserializer* d) {
+ if (is_canonical()) {
+ SafepointMutexLocker ml(
+ d->isolate_group()->constant_canonicalization_mutex());
+ Instance& instance = Instance::Handle(d->zone());
+ for (intptr_t i = start_index_; i < stop_index_; i++) {
+ instance ^= d->Ref(i);
+ instance = instance.CanonicalizeLocked(d->thread());
+ d->UpdateRef(i, instance);
+ }
+ }
+
+ if (cls_.ptr() == d->isolate_group()->object_store()->expando_class()) {
+ Instance& instance = Instance::Handle(d->zone());
+ const String& selector = Library::PrivateCoreLibName(Symbols::_rehash());
+ Array& args = Array::Handle(d->zone(), Array::New(1));
+ for (intptr_t i = start_index_; i < stop_index_; i++) {
+ instance ^= d->Ref(i);
+ args.SetAt(0, instance);
+ ObjectPtr error = instance.Invoke(selector, args, Object::empty_array(),
+ false, false);
+ if (error != Object::null()) {
+ return error;
+ }
+ }
+ }
+ return nullptr;
+ }
+
+ private:
+ Class& cls_;
+};
+
+class TypeMessageSerializationCluster : public MessageSerializationCluster {
+ public:
+ explicit TypeMessageSerializationCluster(bool is_canonical)
+ : MessageSerializationCluster("Type",
+ MessagePhase::kTypes,
+ kTypeCid,
+ is_canonical) {}
+ ~TypeMessageSerializationCluster() {}
+
+ void Trace(MessageSerializer* s, Object* object) {
+ Type* type = static_cast<Type*>(object);
+ objects_.Add(type);
+
+ s->Push(type->type_class());
+ s->Push(type->arguments());
+ }
+
+ void WriteNodes(MessageSerializer* s) {
+ intptr_t count = objects_.length();
+ s->WriteUnsigned(count);
+ for (intptr_t i = 0; i < count; i++) {
+ Type* type = objects_[i];
+ s->AssignRef(type);
+ }
+ }
+
+ void WriteEdges(MessageSerializer* s) {
+ intptr_t count = objects_.length();
+ for (intptr_t i = 0; i < count; i++) {
+ Type* type = objects_[i];
+ s->WriteRef(type->type_class());
+ s->WriteRef(type->arguments());
+ s->Write<uint8_t>(static_cast<uint8_t>(type->nullability()));
+ }
+ }
+
+ private:
+ GrowableArray<Type*> objects_;
+};
+
+class TypeMessageDeserializationCluster : public MessageDeserializationCluster {
+ public:
+ explicit TypeMessageDeserializationCluster(bool is_canonical)
+ : MessageDeserializationCluster("Type", is_canonical) {}
+ ~TypeMessageDeserializationCluster() {}
+
+ void ReadNodes(MessageDeserializer* d) {
+ intptr_t count = d->ReadUnsigned();
+ for (intptr_t i = 0; i < count; i++) {
+ d->AssignRef(Type::New());
+ }
+ }
+
+ void ReadEdges(MessageDeserializer* d) {
+ Class& cls = Class::Handle(d->zone());
+ Type& type = Type::Handle(d->zone());
+ TypeArguments& type_args = TypeArguments::Handle(d->zone());
+ for (intptr_t id = start_index_; id < stop_index_; id++) {
+ type ^= d->Ref(id);
+ cls ^= d->ReadRef();
+ type.set_type_class(cls);
+ type_args ^= d->ReadRef();
+ type.set_arguments(type_args);
+ type.untag()->set_hash(Smi::New(0));
+ type.set_nullability(static_cast<Nullability>(d->Read<uint8_t>()));
+ type.SetIsFinalized();
+ }
+ }
+
+ ObjectPtr PostLoad(MessageDeserializer* d) { return PostLoadAbstractType(d); }
+
+ void ReadNodesApi(ApiMessageDeserializer* d) {
+ intptr_t count = d->ReadUnsigned();
+ for (intptr_t i = 0; i < count; i++) {
+ d->AssignRef(nullptr);
+ }
+ }
+
+ void ReadEdgesApi(ApiMessageDeserializer* d) {
+ for (intptr_t id = start_index_; id < stop_index_; id++) {
+ d->ReadRef(); // Class.
+ d->ReadRef(); // Type arguments.
+ d->Read<uint8_t>(); // Nullability.
+ }
+ }
+};
+
+class TypeRefMessageSerializationCluster : public MessageSerializationCluster {
+ public:
+ explicit TypeRefMessageSerializationCluster(bool is_canonical)
+ : MessageSerializationCluster("TypeRef",
+ MessagePhase::kTypes,
+ kTypeRefCid,
+ is_canonical) {}
+ ~TypeRefMessageSerializationCluster() {}
+
+ void Trace(MessageSerializer* s, Object* object) {
+ TypeRef* type = static_cast<TypeRef*>(object);
+ objects_.Add(type);
+
+ s->Push(type->type());
+ }
+
+ void WriteNodes(MessageSerializer* s) {
+ intptr_t count = objects_.length();
+ s->WriteUnsigned(count);
+ for (intptr_t i = 0; i < count; i++) {
+ TypeRef* type = objects_[i];
+ s->AssignRef(type);
+ }
+ }
+
+ void WriteEdges(MessageSerializer* s) {
+ intptr_t count = objects_.length();
+ for (intptr_t i = 0; i < count; i++) {
+ TypeRef* type = objects_[i];
+ s->WriteRef(type->type());
+ }
+ }
+
+ private:
+ GrowableArray<TypeRef*> objects_;
+};
+
+class TypeRefMessageDeserializationCluster
+ : public MessageDeserializationCluster {
+ public:
+ explicit TypeRefMessageDeserializationCluster(bool is_canonical)
+ : MessageDeserializationCluster("TypeRef", is_canonical) {}
+ ~TypeRefMessageDeserializationCluster() {}
+
+ void ReadNodes(MessageDeserializer* d) {
+ intptr_t count = d->ReadUnsigned();
+ for (intptr_t i = 0; i < count; i++) {
+ d->AssignRef(TypeRef::New());
+ }
+ }
+
+ void ReadEdges(MessageDeserializer* d) {
+ for (intptr_t id = start_index_; id < stop_index_; id++) {
+ TypeRefPtr type = static_cast<TypeRefPtr>(d->Ref(id));
+ type->untag()->set_type(static_cast<AbstractTypePtr>(d->ReadRef()));
+ }
+ }
+
+ ObjectPtr PostLoad(MessageDeserializer* d) {
+ ClassFinalizer::FinalizationKind finalization =
+ is_canonical() ? ClassFinalizer::kCanonicalize
+ : ClassFinalizer::kFinalize;
+ Code& code = Code::Handle(d->zone());
+ TypeRef& type = TypeRef::Handle(d->zone());
+ for (intptr_t id = start_index_; id < stop_index_; id++) {
+ type ^= d->Ref(id);
+ type ^= ClassFinalizer::FinalizeType(type, finalization);
+ d->UpdateRef(id, type);
+
+ code = TypeTestingStubGenerator::DefaultCodeForType(type);
+ type.InitializeTypeTestingStubNonAtomic(code);
+ }
+ return nullptr;
+ }
+
+ void ReadNodesApi(ApiMessageDeserializer* d) {
+ intptr_t count = d->ReadUnsigned();
+ for (intptr_t i = 0; i < count; i++) {
+ d->AssignRef(nullptr);
+ }
+ }
+
+ void ReadEdgesApi(ApiMessageDeserializer* d) {
+ for (intptr_t id = start_index_; id < stop_index_; id++) {
+ d->ReadRef(); // Type.
+ }
+ }
+};
+
+class ClosureMessageSerializationCluster : public MessageSerializationCluster {
+ public:
+ explicit ClosureMessageSerializationCluster(bool is_canonical)
+ : MessageSerializationCluster("Closure",
+ MessagePhase::kCanonicalInstances,
+ kClosureCid,
+ is_canonical) {}
+ ~ClosureMessageSerializationCluster() {}
+
+ void Trace(MessageSerializer* s, Object* object) {
+ Closure* closure = static_cast<Closure*>(object);
+
+ if (!s->can_send_any_object() ||
+ !Function::IsImplicitStaticClosureFunction(closure->function())) {
+ const char* message = OS::SCreate(
+ s->zone(),
+ "Illegal argument in isolate message : (object is a closure - %s)",
+ Function::Handle(closure->function()).ToCString());
+ s->IllegalObject(*object, message);
+ }
+
+ objects_.Add(closure);
+
+ s->Push(closure->function());
+ s->Push(closure->delayed_type_arguments());
+ }
+
+ void WriteNodes(MessageSerializer* s) {
+ intptr_t count = objects_.length();
+ s->WriteUnsigned(count);
+ for (intptr_t i = 0; i < count; i++) {
+ Closure* closure = objects_[i];
+ s->AssignRef(closure);
+ s->WriteRef(closure->function());
+ s->WriteRef(closure->delayed_type_arguments());
+ }
+ }
+
+ private:
+ GrowableArray<Closure*> objects_;
+};
+
+class ClosureMessageDeserializationCluster
+ : public MessageDeserializationCluster {
+ public:
+ explicit ClosureMessageDeserializationCluster(bool is_canonical)
+ : MessageDeserializationCluster("Closure", is_canonical) {}
+ ~ClosureMessageDeserializationCluster() {}
+
+ void ReadNodes(MessageDeserializer* d) {
+ const Context& null_context = Context::Handle(d->zone());
+ TypeArguments& delayed_type_arguments = TypeArguments::Handle(d->zone());
+ Function& func = Function::Handle(d->zone());
+ intptr_t count = d->ReadUnsigned();
+ for (intptr_t i = 0; i < count; i++) {
+ func ^= d->ReadRef();
+ ASSERT(func.is_static());
+ func = func.ImplicitClosureFunction();
+ delayed_type_arguments ^= d->ReadRef();
+ if (delayed_type_arguments.IsNull()) {
+ d->AssignRef(func.ImplicitStaticClosure());
+ } else {
+ // If delayed type arguments were provided, create and return new
+ // closure with those, otherwise return associated implicit static
+ // closure. Note that static closures can't have instantiator or
+ // function types since statics can't refer to class type arguments,
+ // don't have outer functions.
+ d->AssignRef(Closure::New(
+ /*instantiator_type_arguments=*/Object::null_type_arguments(),
+ /*function_type_arguments=*/Object::null_type_arguments(),
+ delayed_type_arguments, func, null_context, Heap::kOld));
+ }
+ }
+ }
+};
+
+class SmiMessageSerializationCluster : public MessageSerializationCluster {
+ public:
+ explicit SmiMessageSerializationCluster(Zone* zone)
+ : MessageSerializationCluster("Smi",
+ MessagePhase::kBeforeTypes,
+ kSmiCid,
+ true),
+ objects_(zone, 0) {}
+ ~SmiMessageSerializationCluster() {}
+
+ void Trace(MessageSerializer* s, Object* object) {
+ Smi* smi = static_cast<Smi*>(object);
+ objects_.Add(smi);
+ }
+
+ void WriteNodes(MessageSerializer* s) {
+ intptr_t count = objects_.length();
+ s->WriteUnsigned(count);
+ for (intptr_t i = 0; i < count; i++) {
+ Smi* smi = static_cast<Smi*>(objects_[i]);
+ s->AssignRef(smi);
+ s->Write<intptr_t>(smi->Value());
+ }
+ }
+
+ void TraceApi(ApiMessageSerializer* s, Dart_CObject* object) {
+ objects_.Add(reinterpret_cast<Smi*>(object));
+ }
+
+ void WriteNodesApi(ApiMessageSerializer* s) {
+ intptr_t count = objects_.length();
+ s->WriteUnsigned(count);
+ for (intptr_t i = 0; i < count; i++) {
+ Dart_CObject* smi = reinterpret_cast<Dart_CObject*>(objects_[i]);
+ s->AssignRef(smi);
+ intptr_t value = smi->type == Dart_CObject_kInt32 ? smi->value.as_int32
+ : smi->value.as_int64;
+ s->Write<intptr_t>(value);
+ }
+ }
+
+ private:
+ GrowableArray<Smi*> objects_;
+};
+
+class SmiMessageDeserializationCluster : public MessageDeserializationCluster {
+ public:
+ SmiMessageDeserializationCluster()
+ : MessageDeserializationCluster("Smi", true) {}
+ ~SmiMessageDeserializationCluster() {}
+
+ void ReadNodes(MessageDeserializer* d) {
+ intptr_t count = d->ReadUnsigned();
+ for (intptr_t i = 0; i < count; i++) {
+ d->AssignRef(Smi::New(d->Read<intptr_t>()));
+ }
+ }
+
+ void ReadNodesApi(ApiMessageDeserializer* d) {
+ intptr_t count = d->ReadUnsigned();
+ for (intptr_t i = 0; i < count; i++) {
+ intptr_t value = d->Read<intptr_t>();
+ Dart_CObject* smi;
+ if ((kMinInt32 <= value) && (value <= kMaxInt32)) {
+ smi = d->Allocate(Dart_CObject_kInt32);
+ smi->value.as_int32 = value;
+ } else {
+ smi = d->Allocate(Dart_CObject_kInt64);
+ smi->value.as_int64 = value;
+ }
+ d->AssignRef(smi);
+ }
+ }
+};
+
+class MintMessageSerializationCluster : public MessageSerializationCluster {
+ public:
+ explicit MintMessageSerializationCluster(Zone* zone, bool is_canonical)
+ : MessageSerializationCluster("Mint",
+ MessagePhase::kBeforeTypes,
+ kMintCid,
+ is_canonical),
+ objects_(zone, 0) {}
+ ~MintMessageSerializationCluster() {}
+
+ void Trace(MessageSerializer* s, Object* object) {
+ Mint* mint = static_cast<Mint*>(object);
+ objects_.Add(mint);
+ }
+
+ void WriteNodes(MessageSerializer* s) {
+ intptr_t count = objects_.length();
+ s->WriteUnsigned(count);
+ for (intptr_t i = 0; i < count; i++) {
+ Mint* mint = static_cast<Mint*>(objects_[i]);
+ s->AssignRef(mint);
+ s->Write<int64_t>(mint->value());
+ }
+ }
+
+ void TraceApi(ApiMessageSerializer* s, Dart_CObject* object) {
+ objects_.Add(reinterpret_cast<Mint*>(object));
+ }
+
+ void WriteNodesApi(ApiMessageSerializer* s) {
+ intptr_t count = objects_.length();
+ s->WriteUnsigned(count);
+ for (intptr_t i = 0; i < count; i++) {
+ Dart_CObject* mint = reinterpret_cast<Dart_CObject*>(objects_[i]);
+ s->AssignRef(mint);
+ int64_t value = mint->type == Dart_CObject_kInt32 ? mint->value.as_int32
+ : mint->value.as_int64;
+ s->Write<int64_t>(value);
+ }
+ }
+
+ private:
+ GrowableArray<Mint*> objects_;
+};
+
+class MintMessageDeserializationCluster : public MessageDeserializationCluster {
+ public:
+ explicit MintMessageDeserializationCluster(bool is_canonical)
+ : MessageDeserializationCluster("int", is_canonical) {}
+ ~MintMessageDeserializationCluster() {}
+
+ void ReadNodes(MessageDeserializer* d) {
+ intptr_t count = d->ReadUnsigned();
+ for (intptr_t i = 0; i < count; i++) {
+ int64_t value = d->Read<int64_t>();
+ d->AssignRef(is_canonical() ? Mint::NewCanonical(value)
+ : Mint::New(value));
+ }
+ }
+
+ void ReadNodesApi(ApiMessageDeserializer* d) {
+ intptr_t count = d->ReadUnsigned();
+ for (intptr_t i = 0; i < count; i++) {
+ int64_t value = d->Read<int64_t>();
+ Dart_CObject* mint;
+ if ((kMinInt32 <= value) && (value <= kMaxInt32)) {
+ mint = d->Allocate(Dart_CObject_kInt32);
+ mint->value.as_int32 = value;
+ } else {
+ mint = d->Allocate(Dart_CObject_kInt64);
+ mint->value.as_int64 = value;
+ }
+ d->AssignRef(mint);
+ }
+ }
+};
+
+class DoubleMessageSerializationCluster : public MessageSerializationCluster {
+ public:
+ explicit DoubleMessageSerializationCluster(Zone* zone, bool is_canonical)
+ : MessageSerializationCluster("double",
+ MessagePhase::kBeforeTypes,
+ kDoubleCid,
+ is_canonical),
+ objects_(zone, 0) {}
+
+ ~DoubleMessageSerializationCluster() {}
+
+ void Trace(MessageSerializer* s, Object* object) {
+ Double* dbl = static_cast<Double*>(object);
+ objects_.Add(dbl);
+ }
+
+ void WriteNodes(MessageSerializer* s) {
+ intptr_t count = objects_.length();
+ s->WriteUnsigned(count);
+ for (intptr_t i = 0; i < count; i++) {
+ Double* dbl = objects_[i];
+ s->AssignRef(dbl);
+ s->Write<double>(dbl->untag()->value_);
+ }
+ }
+
+ void TraceApi(ApiMessageSerializer* s, Dart_CObject* object) {
+ objects_.Add(reinterpret_cast<Double*>(object));
+ }
+
+ void WriteNodesApi(ApiMessageSerializer* s) {
+ intptr_t count = objects_.length();
+ s->WriteUnsigned(count);
+ for (intptr_t i = 0; i < count; i++) {
+ Dart_CObject* dbl = reinterpret_cast<Dart_CObject*>(objects_[i]);
+ s->AssignRef(dbl);
+ s->Write<double>(dbl->value.as_double);
+ }
+ }
+
+ private:
+ GrowableArray<Double*> objects_;
+};
+
+class DoubleMessageDeserializationCluster
+ : public MessageDeserializationCluster {
+ public:
+ explicit DoubleMessageDeserializationCluster(bool is_canonical)
+ : MessageDeserializationCluster("double", is_canonical) {}
+ ~DoubleMessageDeserializationCluster() {}
+
+ void ReadNodes(MessageDeserializer* d) {
+ intptr_t count = d->ReadUnsigned();
+ for (intptr_t i = 0; i < count; i++) {
+ double value = d->Read<double>();
+ d->AssignRef(is_canonical() ? Double::NewCanonical(value)
+ : Double::New(value));
+ }
+ }
+
+ void ReadNodesApi(ApiMessageDeserializer* d) {
+ intptr_t count = d->ReadUnsigned();
+ for (intptr_t i = 0; i < count; i++) {
+ Dart_CObject* dbl = d->Allocate(Dart_CObject_kDouble);
+ dbl->value.as_double = d->Read<double>();
+ d->AssignRef(dbl);
+ }
+ }
+};
+
+class GrowableObjectArrayMessageSerializationCluster
+ : public MessageSerializationCluster {
+ public:
+ GrowableObjectArrayMessageSerializationCluster()
+ : MessageSerializationCluster("GrowableObjectArray",
+ MessagePhase::kNonCanonicalInstances,
+ kGrowableObjectArrayCid) {}
+ ~GrowableObjectArrayMessageSerializationCluster() {}
+
+ void Trace(MessageSerializer* s, Object* object) {
+ GrowableObjectArray* array = static_cast<GrowableObjectArray*>(object);
+ objects_.Add(array);
+
+ s->Push(array->GetTypeArguments());
+ for (intptr_t i = 0, n = array->Length(); i < n; i++) {
+ s->Push(array->At(i));
+ }
+ }
+
+ void WriteNodes(MessageSerializer* s) {
+ intptr_t count = objects_.length();
+ s->WriteUnsigned(count);
+ for (intptr_t i = 0; i < count; i++) {
+ GrowableObjectArray* array = objects_[i];
+ s->WriteUnsigned(array->Length());
+ s->AssignRef(array);
+ }
+ }
+
+ void WriteEdges(MessageSerializer* s) {
+ intptr_t count = objects_.length();
+ for (intptr_t i = 0; i < count; i++) {
+ GrowableObjectArray* array = objects_[i];
+ s->WriteRef(array->GetTypeArguments());
+ for (intptr_t i = 0, n = array->Length(); i < n; i++) {
+ s->WriteRef(array->At(i));
+ }
+ }
+ }
+
+ private:
+ GrowableArray<GrowableObjectArray*> objects_;
+};
+
+class GrowableObjectArrayMessageDeserializationCluster
+ : public MessageDeserializationCluster {
+ public:
+ GrowableObjectArrayMessageDeserializationCluster()
+ : MessageDeserializationCluster("GrowableObjectArray") {}
+ ~GrowableObjectArrayMessageDeserializationCluster() {}
+
+ void ReadNodes(MessageDeserializer* d) {
+ intptr_t count = d->ReadUnsigned();
+ GrowableObjectArray& array = GrowableObjectArray::Handle(d->zone());
+ for (intptr_t i = 0; i < count; i++) {
+ intptr_t length = d->ReadUnsigned();
+ array = GrowableObjectArray::New(length); // Here length is capacity.
+ array.SetLength(length);
+ d->AssignRef(array.ptr());
+ }
+ }
+
+ void ReadEdges(MessageDeserializer* d) {
+ GrowableObjectArray& array = GrowableObjectArray::Handle(d->zone());
+ for (intptr_t id = start_index_; id < stop_index_; id++) {
+ array ^= d->Ref(id);
+ array.untag()->set_type_arguments(
+ static_cast<TypeArgumentsPtr>(d->ReadRef()));
+ for (intptr_t i = 0, n = array.Length(); i < n; i++) {
+ array.untag()->data()->untag()->set_element(i, d->ReadRef());
+ }
+ }
+ }
+
+ ObjectPtr PostLoad(MessageDeserializer* d) {
+ ASSERT(!is_canonical());
+ return nullptr;
+ }
+
+ void ReadNodesApi(ApiMessageDeserializer* d) {
+ intptr_t count = d->ReadUnsigned();
+ for (intptr_t i = 0; i < count; i++) {
+ Dart_CObject* array = d->Allocate(Dart_CObject_kArray);
+ intptr_t length = d->ReadUnsigned();
+ array->value.as_array.length = length;
+ if (length > 0) {
+ array->value.as_array.values = d->zone()->Alloc<Dart_CObject*>(length);
+ } else {
+ ASSERT(length == 0);
+ array->value.as_array.values = NULL;
+ }
+ d->AssignRef(array);
+ }
+ }
+
+ void ReadEdgesApi(ApiMessageDeserializer* d) {
+ for (intptr_t id = start_index_; id < stop_index_; id++) {
+ Dart_CObject* array = d->Ref(id);
+ intptr_t length = array->value.as_array.length;
+ d->ReadRef(); // type_arguments
+ for (intptr_t i = 0; i < length; i++) {
+ array->value.as_array.values[i] = d->ReadRef();
+ }
+ }
+ }
+};
+
+class TypedDataMessageSerializationCluster
+ : public MessageSerializationCluster {
+ public:
+ explicit TypedDataMessageSerializationCluster(Zone* zone, intptr_t cid)
+ : MessageSerializationCluster("TypedData",
+ MessagePhase::kNonCanonicalInstances,
+ cid),
+ objects_(zone, 0) {}
+ ~TypedDataMessageSerializationCluster() {}
+
+ void Trace(MessageSerializer* s, Object* object) {
+ TypedData* data = static_cast<TypedData*>(object);
+ objects_.Add(data);
+ }
+
+ void WriteNodes(MessageSerializer* s) {
+ intptr_t element_size = TypedData::ElementSizeInBytes(cid_);
+ intptr_t count = objects_.length();
+ s->WriteUnsigned(count);
+ for (intptr_t i = 0; i < count; i++) {
+ TypedData* data = objects_[i];
+ s->AssignRef(data);
+ intptr_t length = data->Length();
+ s->WriteUnsigned(length);
+ NoSafepointScope no_safepoint;
+ uint8_t* cdata = reinterpret_cast<uint8_t*>(data->untag()->data());
+ s->WriteBytes(cdata, length * element_size);
+ }
+ }
+
+ void TraceApi(ApiMessageSerializer* s, Dart_CObject* object) {
+ objects_.Add(reinterpret_cast<TypedData*>(object));
+ }
+
+ void WriteNodesApi(ApiMessageSerializer* s) {
+ intptr_t element_size = TypedData::ElementSizeInBytes(cid_);
+ intptr_t count = objects_.length();
+ s->WriteUnsigned(count);
+ for (intptr_t i = 0; i < count; i++) {
+ Dart_CObject* data = reinterpret_cast<Dart_CObject*>(objects_[i]);
+ s->AssignRef(data);
+ intptr_t length = data->value.as_external_typed_data.length;
+ s->WriteUnsigned(length);
+ uint8_t* cdata =
+ reinterpret_cast<uint8_t*>(data->value.as_typed_data.values);
+ s->WriteBytes(cdata, length * element_size);
+ }
+ }
+
+ private:
+ GrowableArray<TypedData*> objects_;
+};
+
+class TypedDataMessageDeserializationCluster
+ : public MessageDeserializationCluster {
+ public:
+ explicit TypedDataMessageDeserializationCluster(intptr_t cid)
+ : MessageDeserializationCluster("TypedData"), cid_(cid) {}
+ ~TypedDataMessageDeserializationCluster() {}
+
+ void ReadNodes(MessageDeserializer* d) {
+ intptr_t element_size = TypedData::ElementSizeInBytes(cid_);
+ intptr_t count = d->ReadUnsigned();
+ TypedData& data = TypedData::Handle(d->zone());
+ for (intptr_t i = 0; i < count; i++) {
+ intptr_t length = d->ReadUnsigned();
+ data = TypedData::New(cid_, length);
+ d->AssignRef(data.ptr());
+ const intptr_t length_in_bytes = length * element_size;
+ NoSafepointScope no_safepoint;
+ uint8_t* cdata = reinterpret_cast<uint8_t*>(data.untag()->data());
+ d->ReadBytes(cdata, length_in_bytes);
+ }
+ }
+
+ void ReadNodesApi(ApiMessageDeserializer* d) {
+ Dart_TypedData_Type type;
+ switch (cid_) {
+ case kTypedDataInt8ArrayCid:
+ type = Dart_TypedData_kInt8;
+ break;
+ case kTypedDataUint8ArrayCid:
+ type = Dart_TypedData_kUint8;
+ break;
+ case kTypedDataUint8ClampedArrayCid:
+ type = Dart_TypedData_kUint8Clamped;
+ break;
+ case kTypedDataInt16ArrayCid:
+ type = Dart_TypedData_kInt16;
+ break;
+ case kTypedDataUint16ArrayCid:
+ type = Dart_TypedData_kUint16;
+ break;
+ case kTypedDataInt32ArrayCid:
+ type = Dart_TypedData_kInt32;
+ break;
+ case kTypedDataUint32ArrayCid:
+ type = Dart_TypedData_kUint32;
+ break;
+ case kTypedDataInt64ArrayCid:
+ type = Dart_TypedData_kInt64;
+ break;
+ case kTypedDataUint64ArrayCid:
+ type = Dart_TypedData_kUint64;
+ break;
+ case kTypedDataFloat32ArrayCid:
+ type = Dart_TypedData_kFloat32;
+ break;
+ case kTypedDataFloat64ArrayCid:
+ type = Dart_TypedData_kFloat64;
+ break;
+ case kTypedDataInt32x4ArrayCid:
+ type = Dart_TypedData_kInt32x4;
+ break;
+ case kTypedDataFloat32x4ArrayCid:
+ type = Dart_TypedData_kFloat32x4;
+ break;
+ case kTypedDataFloat64x2ArrayCid:
+ type = Dart_TypedData_kFloat64x2;
+ break;
+ default:
+ UNREACHABLE();
+ }
+
+ intptr_t element_size = TypedData::ElementSizeInBytes(cid_);
+ intptr_t count = d->ReadUnsigned();
+ for (intptr_t i = 0; i < count; i++) {
+ Dart_CObject* data = d->Allocate(Dart_CObject_kTypedData);
+ intptr_t length = d->ReadUnsigned();
+ data->value.as_typed_data.type = type;
+ data->value.as_typed_data.length = length * element_size;
+ if (length == 0) {
+ data->value.as_typed_data.values = NULL;
+ } else {
+ const intptr_t length_in_bytes = length * element_size;
+ uint8_t* cdata = d->zone()->Alloc<uint8_t>(length_in_bytes);
+ data->value.as_typed_data.values = cdata;
+ d->ReadBytes(cdata, length_in_bytes);
+ }
+ d->AssignRef(data);
+ }
+ }
+
+ private:
+ const intptr_t cid_;
+};
+
+// This function's name can appear in Observatory.
+static void IsolateMessageTypedDataFinalizer(void* isolate_callback_data,
+ void* buffer) {
+ free(buffer);
+}
+
+class ExternalTypedDataMessageSerializationCluster
+ : public MessageSerializationCluster {
+ public:
+ explicit ExternalTypedDataMessageSerializationCluster(Zone* zone,
+ intptr_t cid)
+ : MessageSerializationCluster("ExternalTypedData",
+ MessagePhase::kNonCanonicalInstances,
+ cid),
+ objects_(zone, 0) {}
+ ~ExternalTypedDataMessageSerializationCluster() {}
+
+ void Trace(MessageSerializer* s, Object* object) {
+ ExternalTypedData* data = static_cast<ExternalTypedData*>(object);
+ objects_.Add(data);
+ }
+
+ void WriteNodes(MessageSerializer* s) {
+ intptr_t element_size = ExternalTypedData::ElementSizeInBytes(cid_);
+
+ intptr_t count = objects_.length();
+ s->WriteUnsigned(count);
+ for (intptr_t i = 0; i < count; i++) {
+ ExternalTypedData* data = objects_[i];
+ s->AssignRef(data);
+ intptr_t length = Smi::Value(data->untag()->length_);
+ s->WriteUnsigned(length);
+
+ intptr_t length_in_bytes = length * element_size;
+ void* passed_data = malloc(length_in_bytes);
+ memmove(passed_data, data->untag()->data_, length_in_bytes);
+ s->finalizable_data()->Put(length_in_bytes,
+ passed_data, // data
+ passed_data, // peer,
+ IsolateMessageTypedDataFinalizer);
+ }
+ }
+
+ void TraceApi(ApiMessageSerializer* s, Dart_CObject* object) {
+ objects_.Add(reinterpret_cast<ExternalTypedData*>(object));
+ }
+
+ void WriteNodesApi(ApiMessageSerializer* s) {
+ intptr_t element_size = ExternalTypedData::ElementSizeInBytes(cid_);
+
+ intptr_t count = objects_.length();
+ s->WriteUnsigned(count);
+ for (intptr_t i = 0; i < count; i++) {
+ Dart_CObject* data = reinterpret_cast<Dart_CObject*>(objects_[i]);
+ s->AssignRef(data);
+
+ intptr_t length = data->value.as_external_typed_data.length;
+ s->WriteUnsigned(length);
+
+ s->finalizable_data()->Put(length * element_size,
+ data->value.as_external_typed_data.data,
+ data->value.as_external_typed_data.peer,
+ data->value.as_external_typed_data.callback);
+ }
+ }
+
+ private:
+ GrowableArray<ExternalTypedData*> objects_;
+};
+
+class ExternalTypedDataMessageDeserializationCluster
+ : public MessageDeserializationCluster {
+ public:
+ explicit ExternalTypedDataMessageDeserializationCluster(intptr_t cid)
+ : MessageDeserializationCluster("ExternalTypedData"), cid_(cid) {}
+ ~ExternalTypedDataMessageDeserializationCluster() {}
+
+ void ReadNodes(MessageDeserializer* d) {
+ intptr_t element_size = ExternalTypedData::ElementSizeInBytes(cid_);
+ intptr_t count = d->ReadUnsigned();
+ ExternalTypedData& data = ExternalTypedData::Handle(d->zone());
+ for (intptr_t i = 0; i < count; i++) {
+ intptr_t length = d->ReadUnsigned();
+ FinalizableData finalizable_data = d->finalizable_data()->Take();
+ data = ExternalTypedData::New(
+ cid_, reinterpret_cast<uint8_t*>(finalizable_data.data), length);
+ intptr_t external_size = length * element_size;
+ data.AddFinalizer(finalizable_data.peer, finalizable_data.callback,
+ external_size);
+ d->AssignRef(data.ptr());
+ }
+ }
+
+ void ReadNodesApi(ApiMessageDeserializer* d) {
+ intptr_t element_size = ExternalTypedData::ElementSizeInBytes(cid_);
+ Dart_TypedData_Type type;
+ switch (cid_) {
+ case kExternalTypedDataInt8ArrayCid:
+ type = Dart_TypedData_kInt8;
+ break;
+ case kExternalTypedDataUint8ArrayCid:
+ type = Dart_TypedData_kUint8;
+ break;
+ case kExternalTypedDataUint8ClampedArrayCid:
+ type = Dart_TypedData_kUint8Clamped;
+ break;
+ case kExternalTypedDataInt16ArrayCid:
+ type = Dart_TypedData_kInt16;
+ break;
+ case kExternalTypedDataUint16ArrayCid:
+ type = Dart_TypedData_kUint16;
+ break;
+ case kExternalTypedDataInt32ArrayCid:
+ type = Dart_TypedData_kInt32;
+ break;
+ case kExternalTypedDataUint32ArrayCid:
+ type = Dart_TypedData_kUint32;
+ break;
+ case kExternalTypedDataInt64ArrayCid:
+ type = Dart_TypedData_kInt64;
+ break;
+ case kExternalTypedDataUint64ArrayCid:
+ type = Dart_TypedData_kUint64;
+ break;
+ case kExternalTypedDataFloat32ArrayCid:
+ type = Dart_TypedData_kFloat32;
+ break;
+ case kExternalTypedDataFloat64ArrayCid:
+ type = Dart_TypedData_kFloat64;
+ break;
+ case kExternalTypedDataInt32x4ArrayCid:
+ type = Dart_TypedData_kInt32x4;
+ break;
+ case kExternalTypedDataFloat32x4ArrayCid:
+ type = Dart_TypedData_kFloat32x4;
+ break;
+ case kExternalTypedDataFloat64x2ArrayCid:
+ type = Dart_TypedData_kFloat64x2;
+ break;
+ default:
+ UNREACHABLE();
+ }
+
+ intptr_t count = d->ReadUnsigned();
+ for (intptr_t i = 0; i < count; i++) {
+ Dart_CObject* data = d->Allocate(Dart_CObject_kTypedData);
+ intptr_t length = d->ReadUnsigned();
+ FinalizableData finalizable_data = d->finalizable_data()->Get();
+ data->value.as_typed_data.type = type;
+ data->value.as_typed_data.length = length * element_size;
+ data->value.as_typed_data.values =
+ reinterpret_cast<uint8_t*>(finalizable_data.data);
+ d->AssignRef(data);
+ }
+ }
+
+ private:
+ const intptr_t cid_;
+};
+
+class TypedDataViewMessageSerializationCluster
+ : public MessageSerializationCluster {
+ public:
+ explicit TypedDataViewMessageSerializationCluster(Zone* zone, intptr_t cid)
+ : MessageSerializationCluster("TypedDataView",
+ MessagePhase::kNonCanonicalInstances,
+ cid),
+ objects_(zone, 0) {}
+ ~TypedDataViewMessageSerializationCluster() {}
+
+ void Trace(MessageSerializer* s, Object* object) {
+ TypedDataView* view = static_cast<TypedDataView*>(object);
+ objects_.Add(view);
+
+ s->Push(view->untag()->length());
+ s->Push(view->untag()->typed_data());
+ s->Push(view->untag()->offset_in_bytes());
+ }
+
+ void WriteNodes(MessageSerializer* s) {
+ intptr_t count = objects_.length();
+ s->WriteUnsigned(count);
+ for (intptr_t i = 0; i < count; i++) {
+ TypedDataView* view = objects_[i];
+ s->AssignRef(view);
+ }
+ }
+
+ void WriteEdges(MessageSerializer* s) {
+ intptr_t count = objects_.length();
+ for (intptr_t i = 0; i < count; i++) {
+ TypedDataView* view = objects_[i];
+ s->WriteRef(view->untag()->length());
+ s->WriteRef(view->untag()->typed_data());
+ s->WriteRef(view->untag()->offset_in_bytes());
+ }
+ }
+
+ private:
+ GrowableArray<TypedDataView*> objects_;
+};
+
+class TypedDataViewMessageDeserializationCluster
+ : public MessageDeserializationCluster {
+ public:
+ explicit TypedDataViewMessageDeserializationCluster(intptr_t cid)
+ : MessageDeserializationCluster("TypedDataView"), cid_(cid) {}
+ ~TypedDataViewMessageDeserializationCluster() {}
+
+ void ReadNodes(MessageDeserializer* d) {
+ intptr_t count = d->ReadUnsigned();
+ for (intptr_t i = 0; i < count; i++) {
+ d->AssignRef(TypedDataView::New(cid_));
+ }
+ }
+
+ void ReadEdges(MessageDeserializer* d) {
+ for (intptr_t id = start_index_; id < stop_index_; id++) {
+ TypedDataViewPtr view = static_cast<TypedDataViewPtr>(d->Ref(id));
+ view->untag()->set_length(static_cast<SmiPtr>(d->ReadRef()));
+ view->untag()->set_typed_data(
+ static_cast<TypedDataBasePtr>(d->ReadRef()));
+ view->untag()->set_offset_in_bytes(static_cast<SmiPtr>(d->ReadRef()));
+ }
+ }
+
+ ObjectPtr PostLoad(MessageDeserializer* d) {
+ for (intptr_t id = start_index_; id < stop_index_; id++) {
+ TypedDataViewPtr view = static_cast<TypedDataViewPtr>(d->Ref(id));
+ view->untag()->RecomputeDataField();
+ }
+ return nullptr;
+ }
+
+ struct Dart_CTypedDataView : public Dart_CObject {
+ Dart_CObject* length;
+ Dart_CObject* typed_data;
+ Dart_CObject* offset_in_bytes;
+ };
+
+ void ReadNodesApi(ApiMessageDeserializer* d) {
+ intptr_t count = d->ReadUnsigned();
+ for (intptr_t i = 0; i < count; i++) {
+ Dart_CTypedDataView* view = d->zone()->Alloc<Dart_CTypedDataView>(1);
+ d->AssignRef(view);
+ }
+ }
+
+ void ReadEdgesApi(ApiMessageDeserializer* d) {
+ for (intptr_t id = start_index_; id < stop_index_; id++) {
+ Dart_CTypedDataView* view = static_cast<Dart_CTypedDataView*>(d->Ref(id));
+ view->length = d->ReadRef();
+ view->typed_data = d->ReadRef();
+ view->offset_in_bytes = d->ReadRef();
+ }
+ }
+
+ void PostLoadApi(ApiMessageDeserializer* d) {
+ intptr_t element_size = TypedDataView::ElementSizeInBytes(cid_);
+ Dart_TypedData_Type type;
+ switch (cid_) {
+ case kTypedDataInt8ArrayViewCid:
+ type = Dart_TypedData_kInt8;
+ break;
+ case kTypedDataUint8ArrayViewCid:
+ type = Dart_TypedData_kUint8;
+ break;
+ case kTypedDataUint8ClampedArrayViewCid:
+ type = Dart_TypedData_kUint8Clamped;
+ break;
+ case kTypedDataInt16ArrayViewCid:
+ type = Dart_TypedData_kInt16;
+ break;
+ case kTypedDataUint16ArrayViewCid:
+ type = Dart_TypedData_kUint16;
+ break;
+ case kTypedDataInt32ArrayViewCid:
+ type = Dart_TypedData_kInt32;
+ break;
+ case kTypedDataUint32ArrayViewCid:
+ type = Dart_TypedData_kUint32;
+ break;
+ case kTypedDataInt64ArrayViewCid:
+ type = Dart_TypedData_kInt64;
+ break;
+ case kTypedDataUint64ArrayViewCid:
+ type = Dart_TypedData_kUint64;
+ break;
+ case kTypedDataFloat32ArrayViewCid:
+ type = Dart_TypedData_kFloat32;
+ break;
+ case kTypedDataFloat64ArrayViewCid:
+ type = Dart_TypedData_kFloat64;
+ break;
+ case kTypedDataInt32x4ArrayViewCid:
+ type = Dart_TypedData_kInt32x4;
+ break;
+ case kTypedDataFloat32x4ArrayViewCid:
+ type = Dart_TypedData_kFloat32x4;
+ break;
+ case kTypedDataFloat64x2ArrayViewCid:
+ type = Dart_TypedData_kFloat64x2;
+ break;
+ default:
+ UNREACHABLE();
+ }
+
+ for (intptr_t id = start_index_; id < stop_index_; id++) {
+ Dart_CTypedDataView* view = static_cast<Dart_CTypedDataView*>(d->Ref(id));
+ if (view->typed_data->type == Dart_CObject_kTypedData) {
+ view->type = Dart_CObject_kTypedData;
+ view->value.as_typed_data.type = type;
+ // view->typed_data->value.as_typed_data.type;
+ view->value.as_typed_data.length =
+ view->length->value.as_int32 * element_size;
+ view->value.as_typed_data.values =
+ view->typed_data->value.as_typed_data.values +
+ view->offset_in_bytes->value.as_int32;
+ } else if (view->typed_data->type == Dart_CObject_kExternalTypedData) {
+ UNREACHABLE(); ///???
+ view->type = Dart_CObject_kTypedData;
+ view->value.as_typed_data.type = type;
+ // view->typed_data->value.as_external_typed_data.type;
+ view->value.as_typed_data.length =
+ view->length->value.as_int32 * element_size;
+ view->value.as_typed_data.values =
+ view->typed_data->value.as_external_typed_data.data +
+ view->offset_in_bytes->value.as_int32;
+ } else {
+ UNREACHABLE();
+ }
+ }
+ }
+
+ private:
+ const intptr_t cid_;
+};
+
+class TransferableTypedDataMessageSerializationCluster
+ : public MessageSerializationCluster {
+ public:
+ TransferableTypedDataMessageSerializationCluster()
+ : MessageSerializationCluster("TransferableTypedData",
+ MessagePhase::kNonCanonicalInstances,
+ kTransferableTypedDataCid) {}
+ ~TransferableTypedDataMessageSerializationCluster() {}
+
+ void Trace(MessageSerializer* s, Object* object) {
+ TransferableTypedData* transferable =
+ static_cast<TransferableTypedData*>(object);
+ objects_.Add(transferable);
+
+ void* peer = s->thread()->heap()->GetPeer(transferable->ptr());
+ // Assume that object's Peer is only used to track transferrability state.
+ ASSERT(peer != nullptr);
+ TransferableTypedDataPeer* tpeer =
+ reinterpret_cast<TransferableTypedDataPeer*>(peer);
+ if (tpeer->data() == nullptr) {
+ s->IllegalObject(
+ *object,
+ "Illegal argument in isolate message"
+ " : (TransferableTypedData has been transferred already)");
+ }
+ }
+
+ void WriteNodes(MessageSerializer* s) {
+ intptr_t count = objects_.length();
+ s->WriteUnsigned(count);
+ for (intptr_t i = 0; i < count; i++) {
+ TransferableTypedData* transferable = objects_[i];
+ s->AssignRef(transferable);
+
+ void* peer = s->thread()->heap()->GetPeer(transferable->ptr());
+ // Assume that object's Peer is only used to track transferrability state.
+ ASSERT(peer != nullptr);
+ TransferableTypedDataPeer* tpeer =
+ reinterpret_cast<TransferableTypedDataPeer*>(peer);
+ intptr_t length = tpeer->length(); // In bytes.
+ void* data = tpeer->data();
+ ASSERT(data != nullptr);
+ s->WriteUnsigned(length);
+ s->finalizable_data()->Put(
+ length, data, tpeer,
+ // Finalizer does nothing - in case of failure to serialize,
+ // [data] remains wrapped in sender's [TransferableTypedData].
+ [](void* data, void* peer) {},
+ // This is invoked on successful serialization of the message
+ [](void* data, void* peer) {
+ TransferableTypedDataPeer* ttpeer =
+ reinterpret_cast<TransferableTypedDataPeer*>(peer);
+ ttpeer->handle()->EnsureFreedExternal(IsolateGroup::Current());
+ ttpeer->ClearData();
+ });
+ }
+ }
+
+ private:
+ GrowableArray<TransferableTypedData*> objects_;
+};
+
+class TransferableTypedDataMessageDeserializationCluster
+ : public MessageDeserializationCluster {
+ public:
+ TransferableTypedDataMessageDeserializationCluster()
+ : MessageDeserializationCluster("TransferableTypedData") {}
+ ~TransferableTypedDataMessageDeserializationCluster() {}
+
+ void ReadNodes(MessageDeserializer* d) {
+ intptr_t count = d->ReadUnsigned();
+ for (intptr_t i = 0; i < count; i++) {
+ intptr_t length = d->ReadUnsigned();
+ const FinalizableData finalizable_data = d->finalizable_data()->Take();
+ d->AssignRef(TransferableTypedData::New(
+ reinterpret_cast<uint8_t*>(finalizable_data.data), length));
+ }
+ }
+};
+
+class RegExpMessageSerializationCluster : public MessageSerializationCluster {
+ public:
+ RegExpMessageSerializationCluster()
+ : MessageSerializationCluster("RegExp",
+ MessagePhase::kNonCanonicalInstances,
+ kRegExpCid) {}
+ ~RegExpMessageSerializationCluster() {}
+
+ void Trace(MessageSerializer* s, Object* object) {
+ RegExp* regexp = static_cast<RegExp*>(object);
+ objects_.Add(regexp);
+
+ s->Push(regexp->capture_name_map());
+ s->Push(regexp->pattern());
+ }
+
+ void WriteNodes(MessageSerializer* s) {
+ intptr_t count = objects_.length();
+ s->WriteUnsigned(count);
+ for (intptr_t i = 0; i < count; i++) {
+ RegExp* regexp = objects_[i];
+ s->AssignRef(regexp);
+ s->WriteRef(regexp->capture_name_map());
+ s->WriteRef(regexp->pattern());
+ s->Write<int32_t>(regexp->num_bracket_expressions());
+ s->Write<int32_t>(regexp->num_registers(true));
+ s->Write<int32_t>(regexp->num_registers(false));
+ s->Write<int>(regexp->flags().value());
+ }
+ }
+
+ private:
+ GrowableArray<RegExp*> objects_;
+};
+
+class RegExpMessageDeserializationCluster
+ : public MessageDeserializationCluster {
+ public:
+ RegExpMessageDeserializationCluster()
+ : MessageDeserializationCluster("RegExp") {}
+ ~RegExpMessageDeserializationCluster() {}
+
+ void ReadNodes(MessageDeserializer* d) {
+ RegExp& regexp = RegExp::Handle(d->zone());
+ intptr_t count = d->ReadUnsigned();
+ for (intptr_t i = 0; i < count; i++) {
+ regexp = RegExp::New(d->zone());
+ d->AssignRef(regexp.ptr());
+ regexp.untag()->set_capture_name_map(static_cast<ArrayPtr>(d->ReadRef()));
+ regexp.untag()->set_pattern(static_cast<StringPtr>(d->ReadRef()));
+ regexp.set_num_bracket_expressions(d->Read<int32_t>());
+ regexp.set_num_registers(true, d->Read<int32_t>());
+ regexp.set_num_registers(false, d->Read<int32_t>());
+ regexp.set_flags(RegExpFlags(d->Read<int>()));
+ }
+ }
+};
+
+class SendPortMessageSerializationCluster : public MessageSerializationCluster {
+ public:
+ explicit SendPortMessageSerializationCluster(Zone* zone)
+ : MessageSerializationCluster("SendPort",
+ MessagePhase::kNonCanonicalInstances,
+ kSendPortCid),
+ objects_(zone, 0) {}
+ ~SendPortMessageSerializationCluster() {}
+
+ void Trace(MessageSerializer* s, Object* object) {
+ SendPort* port = static_cast<SendPort*>(object);
+ objects_.Add(port);
+ }
+
+ void WriteNodes(MessageSerializer* s) {
+ intptr_t count = objects_.length();
+ s->WriteUnsigned(count);
+ for (intptr_t i = 0; i < count; i++) {
+ SendPort* port = objects_[i];
+ s->AssignRef(port);
+ s->Write<Dart_Port>(port->untag()->id_);
+ s->Write<Dart_Port>(port->untag()->origin_id_);
+ }
+ }
+
+ void TraceApi(ApiMessageSerializer* s, Dart_CObject* object) {
+ objects_.Add(reinterpret_cast<SendPort*>(object));
+ }
+
+ void WriteNodesApi(ApiMessageSerializer* s) {
+ intptr_t count = objects_.length();
+ s->WriteUnsigned(count);
+ for (intptr_t i = 0; i < count; i++) {
+ Dart_CObject* port = reinterpret_cast<Dart_CObject*>(objects_[i]);
+ s->AssignRef(port);
+ s->Write<Dart_Port>(port->value.as_send_port.id);
+ s->Write<Dart_Port>(port->value.as_send_port.origin_id);
+ }
+ }
+
+ private:
+ GrowableArray<SendPort*> objects_;
+};
+
+class SendPortMessageDeserializationCluster
+ : public MessageDeserializationCluster {
+ public:
+ SendPortMessageDeserializationCluster()
+ : MessageDeserializationCluster("SendPort") {}
+ ~SendPortMessageDeserializationCluster() {}
+
+ void ReadNodes(MessageDeserializer* d) {
+ intptr_t count = d->ReadUnsigned();
+ for (intptr_t i = 0; i < count; i++) {
+ Dart_Port id = d->Read<Dart_Port>();
+ Dart_Port origin_id = d->Read<Dart_Port>();
+ d->AssignRef(SendPort::New(id, origin_id));
+ }
+ }
+
+ void ReadNodesApi(ApiMessageDeserializer* d) {
+ intptr_t count = d->ReadUnsigned();
+ for (intptr_t i = 0; i < count; i++) {
+ Dart_CObject* port = d->Allocate(Dart_CObject_kSendPort);
+ port->value.as_send_port.id = d->Read<Dart_Port>();
+ port->value.as_send_port.origin_id = d->Read<Dart_Port>();
+ d->AssignRef(port);
+ }
+ }
+};
+
+class CapabilityMessageSerializationCluster
+ : public MessageSerializationCluster {
+ public:
+ explicit CapabilityMessageSerializationCluster(Zone* zone)
+ : MessageSerializationCluster("Capability",
+ MessagePhase::kNonCanonicalInstances,
+ kCapabilityCid),
+ objects_(zone, 0) {}
+ ~CapabilityMessageSerializationCluster() {}
+
+ void Trace(MessageSerializer* s, Object* object) {
+ Capability* cap = static_cast<Capability*>(object);
+ objects_.Add(cap);
+ }
+
+ void WriteNodes(MessageSerializer* s) {
+ intptr_t count = objects_.length();
+ s->WriteUnsigned(count);
+ for (intptr_t i = 0; i < count; i++) {
+ Capability* cap = objects_[i];
+ s->AssignRef(cap);
+ s->Write<uint64_t>(cap->untag()->id_);
+ }
+ }
+
+ void TraceApi(ApiMessageSerializer* s, Dart_CObject* object) {
+ objects_.Add(reinterpret_cast<Capability*>(object));
+ }
+
+ void WriteNodesApi(ApiMessageSerializer* s) {
+ intptr_t count = objects_.length();
+ s->WriteUnsigned(count);
+ for (intptr_t i = 0; i < count; i++) {
+ Dart_CObject* cap = reinterpret_cast<Dart_CObject*>(objects_[i]);
+ s->AssignRef(cap);
+ s->Write<Dart_Port>(cap->value.as_capability.id);
+ }
+ }
+
+ private:
+ GrowableArray<Capability*> objects_;
+};
+
+class CapabilityMessageDeserializationCluster
+ : public MessageDeserializationCluster {
+ public:
+ CapabilityMessageDeserializationCluster()
+ : MessageDeserializationCluster("Capability") {}
+ ~CapabilityMessageDeserializationCluster() {}
+
+ void ReadNodes(MessageDeserializer* d) {
+ intptr_t count = d->ReadUnsigned();
+ for (intptr_t i = 0; i < count; i++) {
+ uint64_t id = d->Read<uint64_t>();
+ d->AssignRef(Capability::New(id));
+ }
+ }
+
+ void ReadNodesApi(ApiMessageDeserializer* d) {
+ intptr_t count = d->ReadUnsigned();
+ for (intptr_t i = 0; i < count; i++) {
+ Dart_CObject* cap = d->Allocate(Dart_CObject_kCapability);
+ cap->value.as_capability.id = d->Read<uint64_t>();
+ d->AssignRef(cap);
+ }
+ }
+};
+
+class WeakPropertyMessageSerializationCluster
+ : public MessageSerializationCluster {
+ public:
+ WeakPropertyMessageSerializationCluster()
+ : MessageSerializationCluster("WeakProperty",
+ MessagePhase::kNonCanonicalInstances,
+ kWeakPropertyCid) {}
+ ~WeakPropertyMessageSerializationCluster() {}
+
+ void Trace(MessageSerializer* s, Object* object) {
+ WeakProperty* property = static_cast<WeakProperty*>(object);
+ objects_.Add(property);
+ }
+
+ void RetraceEphemerons(MessageSerializer* s) {
+ for (intptr_t i = 0; i < objects_.length(); i++) {
+ WeakProperty* property = objects_[i];
+ if (s->HasRef(property->untag()->key())) {
+ s->Push(property->untag()->value());
+ }
+ }
+ }
+
+ void WriteNodes(MessageSerializer* s) {
+ intptr_t count = objects_.length();
+ s->WriteUnsigned(count);
+ for (intptr_t i = 0; i < count; i++) {
+ WeakProperty* property = objects_[i];
+ s->AssignRef(property);
+ }
+ }
+
+ void WriteEdges(MessageSerializer* s) {
+ intptr_t count = objects_.length();
+ for (intptr_t i = 0; i < count; i++) {
+ WeakProperty* property = objects_[i];
+ if (s->HasRef(property->untag()->key())) {
+ s->WriteRef(property->untag()->key());
+ s->WriteRef(property->untag()->value());
+ } else {
+ s->WriteRef(Object::null());
+ s->WriteRef(Object::null());
+ }
+ }
+ }
+
+ private:
+ GrowableArray<WeakProperty*> objects_;
+};
+
+class WeakPropertyMessageDeserializationCluster
+ : public MessageDeserializationCluster {
+ public:
+ WeakPropertyMessageDeserializationCluster()
+ : MessageDeserializationCluster("WeakProperty") {}
+ ~WeakPropertyMessageDeserializationCluster() {}
+
+ void ReadNodes(MessageDeserializer* d) {
+ intptr_t count = d->ReadUnsigned();
+ for (intptr_t i = 0; i < count; i++) {
+ d->AssignRef(WeakProperty::New());
+ }
+ }
+
+ void ReadEdges(MessageDeserializer* d) {
+ ASSERT(!is_canonical()); // Never canonical.
+ for (intptr_t id = start_index_; id < stop_index_; id++) {
+ WeakPropertyPtr property = static_cast<WeakPropertyPtr>(d->Ref(id));
+ property->untag()->set_key(d->ReadRef());
+ property->untag()->set_value(d->ReadRef());
+ }
+ }
+};
+
+class LinkedHashMapMessageSerializationCluster
+ : public MessageSerializationCluster {
+ public:
+ LinkedHashMapMessageSerializationCluster()
+ : MessageSerializationCluster("LinkedHashMap",
+ MessagePhase::kNonCanonicalInstances,
+ kLinkedHashMapCid) {}
+ ~LinkedHashMapMessageSerializationCluster() {}
+
+ void Trace(MessageSerializer* s, Object* object) {
+ LinkedHashMap* map = static_cast<LinkedHashMap*>(object);
+ objects_.Add(map);
+
+ s->Push(map->untag()->type_arguments());
+ s->Push(map->untag()->data());
+ s->Push(map->untag()->used_data());
+ }
+
+ void WriteNodes(MessageSerializer* s) {
+ intptr_t count = objects_.length();
+ s->WriteUnsigned(count);
+ for (intptr_t i = 0; i < count; i++) {
+ LinkedHashMap* map = objects_[i];
+ s->AssignRef(map);
+ }
+ }
+
+ void WriteEdges(MessageSerializer* s) {
+ intptr_t count = objects_.length();
+ for (intptr_t i = 0; i < count; i++) {
+ LinkedHashMap* map = objects_[i];
+ s->WriteRef(map->untag()->type_arguments());
+ s->WriteRef(map->untag()->data());
+ s->WriteRef(map->untag()->used_data());
+ }
+ }
+
+ private:
+ GrowableArray<LinkedHashMap*> objects_;
+};
+
+class LinkedHashMapMessageDeserializationCluster
+ : public MessageDeserializationCluster {
+ public:
+ explicit LinkedHashMapMessageDeserializationCluster(bool is_canonical)
+ : MessageDeserializationCluster("LinkedHashMap", is_canonical) {}
+ ~LinkedHashMapMessageDeserializationCluster() {}
+
+ void ReadNodes(MessageDeserializer* d) {
+ intptr_t count = d->ReadUnsigned();
+ for (intptr_t i = 0; i < count; i++) {
+ d->AssignRef(LinkedHashMap::NewUninitialized());
+ }
+ }
+
+ void ReadEdges(MessageDeserializer* d) {
+ for (intptr_t id = start_index_; id < stop_index_; id++) {
+ LinkedHashMapPtr map = static_cast<LinkedHashMapPtr>(d->Ref(id));
+ map->untag()->set_hash_mask(Smi::New(0));
+ map->untag()->set_type_arguments(
+ static_cast<TypeArgumentsPtr>(d->ReadRef()));
+ map->untag()->set_data(static_cast<ArrayPtr>(d->ReadRef()));
+ map->untag()->set_used_data(static_cast<SmiPtr>(d->ReadRef()));
+ map->untag()->set_deleted_keys(Smi::New(0));
+ }
+ }
+
+ ObjectPtr PostLoad(MessageDeserializer* d) { return PostLoadLinkedHash(d); }
+};
+
+class LinkedHashSetMessageSerializationCluster
+ : public MessageSerializationCluster {
+ public:
+ LinkedHashSetMessageSerializationCluster()
+ : MessageSerializationCluster("LinkedHashSet",
+ MessagePhase::kNonCanonicalInstances,
+ kLinkedHashSetCid) {}
+ ~LinkedHashSetMessageSerializationCluster() {}
+
+ void Trace(MessageSerializer* s, Object* object) {
+ LinkedHashSet* map = static_cast<LinkedHashSet*>(object);
+ objects_.Add(map);
+
+ s->Push(map->untag()->type_arguments());
+ s->Push(map->untag()->data());
+ s->Push(map->untag()->used_data());
+ }
+
+ void WriteNodes(MessageSerializer* s) {
+ intptr_t count = objects_.length();
+ s->WriteUnsigned(count);
+ for (intptr_t i = 0; i < count; i++) {
+ LinkedHashSet* map = objects_[i];
+ s->AssignRef(map);
+ }
+ }
+
+ void WriteEdges(MessageSerializer* s) {
+ intptr_t count = objects_.length();
+ for (intptr_t i = 0; i < count; i++) {
+ LinkedHashSet* map = objects_[i];
+ s->WriteRef(map->untag()->type_arguments());
+ s->WriteRef(map->untag()->data());
+ s->WriteRef(map->untag()->used_data());
+ }
+ }
+
+ private:
+ GrowableArray<LinkedHashSet*> objects_;
+};
+
+class LinkedHashSetMessageDeserializationCluster
+ : public MessageDeserializationCluster {
+ public:
+ explicit LinkedHashSetMessageDeserializationCluster(bool is_canonical)
+ : MessageDeserializationCluster("LinkedHashSet", is_canonical) {}
+ ~LinkedHashSetMessageDeserializationCluster() {}
+
+ void ReadNodes(MessageDeserializer* d) {
+ intptr_t count = d->ReadUnsigned();
+ for (intptr_t i = 0; i < count; i++) {
+ d->AssignRef(LinkedHashSet::NewUninitialized());
+ }
+ }
+
+ void ReadEdges(MessageDeserializer* d) {
+ for (intptr_t id = start_index_; id < stop_index_; id++) {
+ LinkedHashSetPtr map = static_cast<LinkedHashSetPtr>(d->Ref(id));
+ map->untag()->set_hash_mask(Smi::New(0));
+ map->untag()->set_type_arguments(
+ static_cast<TypeArgumentsPtr>(d->ReadRef()));
+ map->untag()->set_data(static_cast<ArrayPtr>(d->ReadRef()));
+ map->untag()->set_used_data(static_cast<SmiPtr>(d->ReadRef()));
+ map->untag()->set_deleted_keys(Smi::New(0));
+ }
+ }
+
+ ObjectPtr PostLoad(MessageDeserializer* d) { return PostLoadLinkedHash(d); }
+};
+
+class ArrayMessageSerializationCluster : public MessageSerializationCluster {
+ public:
+ ArrayMessageSerializationCluster(Zone* zone, bool is_canonical, intptr_t cid)
+ : MessageSerializationCluster("Array",
+ is_canonical
+ ? MessagePhase::kCanonicalInstances
+ : MessagePhase::kNonCanonicalInstances,
+ cid,
+ is_canonical),
+ objects_(zone, 0) {}
+ ~ArrayMessageSerializationCluster() {}
+
+ void Trace(MessageSerializer* s, Object* object) {
+ Array* array = static_cast<Array*>(object);
+ objects_.Add(array);
+
+ s->Push(array->untag()->type_arguments());
+ intptr_t length = Smi::Value(array->untag()->length());
+ for (intptr_t i = 0; i < length; i++) {
+ s->Push(array->untag()->element(i));
+ }
+ }
+
+ void WriteNodes(MessageSerializer* s) {
+ intptr_t count = objects_.length();
+ s->WriteUnsigned(count);
+ for (intptr_t i = 0; i < count; i++) {
+ Array* array = objects_[i];
+ s->AssignRef(array);
+ intptr_t length = Smi::Value(array->untag()->length());
+ s->WriteUnsigned(length);
+ }
+ }
+
+ void WriteEdges(MessageSerializer* s) {
+ intptr_t count = objects_.length();
+ for (intptr_t i = 0; i < count; i++) {
+ Array* array = objects_[i];
+ intptr_t length = array->Length();
+ s->WriteRef(array->untag()->type_arguments());
+ for (intptr_t j = 0; j < length; j++) {
+ s->WriteRef(array->untag()->element(j));
+ }
+ }
+ }
+
+ void TraceApi(ApiMessageSerializer* s, Dart_CObject* object) {
+ objects_.Add(reinterpret_cast<Array*>(object));
+
+ for (intptr_t i = 0, n = object->value.as_array.length; i < n; i++) {
+ s->Push(object->value.as_array.values[i]);
+ }
+ }
+
+ void WriteNodesApi(ApiMessageSerializer* s) {
+ intptr_t count = objects_.length();
+ s->WriteUnsigned(count);
+ for (intptr_t i = 0; i < count; i++) {
+ Dart_CObject* array = reinterpret_cast<Dart_CObject*>(objects_[i]);
+ s->AssignRef(array);
+ s->WriteUnsigned(array->value.as_array.length);
+ }
+ }
+
+ void WriteEdgesApi(ApiMessageSerializer* s) {
+ intptr_t count = objects_.length();
+ for (intptr_t i = 0; i < count; i++) {
+ Dart_CObject* array = reinterpret_cast<Dart_CObject*>(objects_[i]);
+ intptr_t length = array->value.as_array.length;
+ s->WriteRef(&cobj_null); // TypeArguments
+ for (intptr_t j = 0; j < length; j++) {
+ s->WriteRef(array->value.as_array.values[j]);
+ }
+ }
+ }
+
+ private:
+ GrowableArray<Array*> objects_;
+};
+
+class ArrayMessageDeserializationCluster
+ : public MessageDeserializationCluster {
+ public:
+ explicit ArrayMessageDeserializationCluster(bool is_canonical, intptr_t cid)
+ : MessageDeserializationCluster("Array", is_canonical), cid_(cid) {}
+ ~ArrayMessageDeserializationCluster() {}
+
+ void ReadNodes(MessageDeserializer* d) {
+ intptr_t count = d->ReadUnsigned();
+ for (intptr_t i = 0; i < count; i++) {
+ intptr_t length = d->ReadUnsigned();
+ d->AssignRef(Array::New(cid_, length));
+ }
+ }
+
+ void ReadEdges(MessageDeserializer* d) {
+ for (intptr_t id = start_index_; id < stop_index_; id++) {
+ ArrayPtr array = static_cast<ArrayPtr>(d->Ref(id));
+ intptr_t length = Smi::Value(array->untag()->length());
+ array->untag()->set_type_arguments(
+ static_cast<TypeArgumentsPtr>(d->ReadRef()));
+ for (intptr_t j = 0; j < length; j++) {
+ array->untag()->set_element(j, d->ReadRef());
+ }
+ }
+ }
+
+ ObjectPtr PostLoad(MessageDeserializer* d) {
+ if (is_canonical()) {
+ SafepointMutexLocker ml(
+ d->isolate_group()->constant_canonicalization_mutex());
+ Instance& instance = Instance::Handle(d->zone());
+ for (intptr_t i = start_index_; i < stop_index_; i++) {
+ instance ^= d->Ref(i);
+ instance = instance.CanonicalizeLocked(d->thread());
+ d->UpdateRef(i, instance);
+ }
+ }
+ return nullptr;
+ }
+
+ void ReadNodesApi(ApiMessageDeserializer* d) {
+ intptr_t count = d->ReadUnsigned();
+ for (intptr_t i = 0; i < count; i++) {
+ Dart_CObject* array = d->Allocate(Dart_CObject_kArray);
+ intptr_t length = d->ReadUnsigned();
+ array->value.as_array.length = length;
+ if (length == 0) {
+ array->value.as_array.values = NULL;
+ } else {
+ array->value.as_array.values = d->zone()->Alloc<Dart_CObject*>(length);
+ }
+ d->AssignRef(array);
+ }
+ }
+
+ void ReadEdgesApi(ApiMessageDeserializer* d) {
+ for (intptr_t id = start_index_; id < stop_index_; id++) {
+ Dart_CObject* array = d->Ref(id);
+ intptr_t length = array->value.as_array.length;
+ d->ReadRef(); // type_arguments
+ for (intptr_t i = 0; i < length; i++) {
+ array->value.as_array.values[i] = d->ReadRef();
+ }
+ }
+ }
+
+ private:
+ const intptr_t cid_;
+};
+
+class OneByteStringMessageSerializationCluster
+ : public MessageSerializationCluster {
+ public:
+ explicit OneByteStringMessageSerializationCluster(Zone* zone,
+ bool is_canonical)
+ : MessageSerializationCluster("OneByteString",
+ MessagePhase::kBeforeTypes,
+ kOneByteStringCid,
+ is_canonical),
+ objects_(zone, 0) {}
+ ~OneByteStringMessageSerializationCluster() {}
+
+ void Trace(MessageSerializer* s, Object* object) {
+ String* str = static_cast<String*>(object);
+ objects_.Add(str);
+ }
+
+ void WriteNodes(MessageSerializer* s) {
+ intptr_t count = objects_.length();
+ s->WriteUnsigned(count);
+ for (intptr_t i = 0; i < count; i++) {
+ String* str = objects_[i];
+ s->AssignRef(str);
+ intptr_t length = str->Length();
+ s->WriteUnsigned(length);
+ NoSafepointScope no_safepoint;
+ s->WriteBytes(OneByteString::DataStart(*str), length * sizeof(uint8_t));
+ }
+ }
+
+ void TraceApi(ApiMessageSerializer* s, Dart_CObject* object) {
+ objects_.Add(reinterpret_cast<String*>(object));
+ }
+
+ void WriteNodesApi(ApiMessageSerializer* s) {
+ intptr_t count = objects_.length();
+ s->WriteUnsigned(count);
+ for (intptr_t i = 0; i < count; i++) {
+ Dart_CObject* str = reinterpret_cast<Dart_CObject*>(objects_[i]);
+ s->AssignRef(str);
+
+ const uint8_t* utf8_str =
+ reinterpret_cast<const uint8_t*>(str->value.as_string);
+ intptr_t utf8_len = strlen(str->value.as_string);
+ Utf8::Type type = Utf8::kLatin1;
+ intptr_t latin1_len = Utf8::CodeUnitCount(utf8_str, utf8_len, &type);
+
+ uint8_t* latin1_str = reinterpret_cast<uint8_t*>(
+ dart::malloc(latin1_len * sizeof(uint8_t)));
+ bool success =
+ Utf8::DecodeToLatin1(utf8_str, utf8_len, latin1_str, latin1_len);
+ ASSERT(success);
+ s->WriteUnsigned(latin1_len);
+ s->WriteBytes(latin1_str, latin1_len);
+ ::free(latin1_str);
+ }
+ }
+
+ private:
+ GrowableArray<String*> objects_;
+};
+
+class OneByteStringMessageDeserializationCluster
+ : public MessageDeserializationCluster {
+ public:
+ explicit OneByteStringMessageDeserializationCluster(bool is_canonical)
+ : MessageDeserializationCluster("OneByteString", is_canonical) {}
+ ~OneByteStringMessageDeserializationCluster() {}
+
+ void ReadNodes(MessageDeserializer* d) {
+ intptr_t count = d->ReadUnsigned();
+ for (intptr_t i = 0; i < count; i++) {
+ intptr_t length = d->ReadUnsigned();
+ const uint8_t* data = d->CurrentBufferAddress();
+ d->Advance(length * sizeof(uint8_t));
+ d->AssignRef(is_canonical()
+ ? Symbols::FromLatin1(d->thread(), data, length)
+ : String::FromLatin1(data, length));
+ }
+ }
+
+ void ReadNodesApi(ApiMessageDeserializer* d) {
+ intptr_t count = d->ReadUnsigned();
+ for (intptr_t i = 0; i < count; i++) {
+ Dart_CObject* str = d->Allocate(Dart_CObject_kString);
+ intptr_t latin1_length = d->ReadUnsigned();
+ const uint8_t* data = d->CurrentBufferAddress();
+
+ d->Advance(latin1_length * sizeof(uint8_t));
+
+ intptr_t utf8_len = 0;
+ for (intptr_t i = 0; i < latin1_length; i++) {
+ utf8_len += Utf8::Length(data[i]);
+ }
+ char* utf8_data = d->zone()->Alloc<char>(utf8_len + 1);
+ str->value.as_string = utf8_data;
+ for (intptr_t i = 0; i < latin1_length; i++) {
+ utf8_data += Utf8::Encode(data[i], utf8_data);
+ }
+ *utf8_data = '\0';
+
+ d->AssignRef(str);
+ }
+ }
+};
+
+class TwoByteStringMessageSerializationCluster
+ : public MessageSerializationCluster {
+ public:
+ explicit TwoByteStringMessageSerializationCluster(Zone* zone,
+ bool is_canonical)
+ : MessageSerializationCluster("TwoByteString",
+ MessagePhase::kBeforeTypes,
+ kTwoByteStringCid,
+ is_canonical),
+ objects_(zone, 0) {}
+ ~TwoByteStringMessageSerializationCluster() {}
+
+ void Trace(MessageSerializer* s, Object* object) {
+ String* str = static_cast<String*>(object);
+ objects_.Add(str);
+ }
+
+ void WriteNodes(MessageSerializer* s) {
+ intptr_t count = objects_.length();
+ s->WriteUnsigned(count);
+ for (intptr_t i = 0; i < count; i++) {
+ String* str = objects_[i];
+ s->AssignRef(str);
+ intptr_t length = str->Length();
+ s->WriteUnsigned(length);
+ NoSafepointScope no_safepoint;
+ uint16_t* utf16 = TwoByteString::DataStart(*str);
+ s->WriteBytes(reinterpret_cast<const uint8_t*>(utf16),
+ length * sizeof(uint16_t));
+ }
+ }
+
+ void TraceApi(ApiMessageSerializer* s, Dart_CObject* object) {
+ objects_.Add(reinterpret_cast<String*>(object));
+ }
+
+ void WriteNodesApi(ApiMessageSerializer* s) {
+ intptr_t count = objects_.length();
+ s->WriteUnsigned(count);
+ for (intptr_t i = 0; i < count; i++) {
+ Dart_CObject* str = reinterpret_cast<Dart_CObject*>(objects_[i]);
+ s->AssignRef(str);
+
+ const uint8_t* utf8_str =
+ reinterpret_cast<const uint8_t*>(str->value.as_string);
+ intptr_t utf8_len = strlen(str->value.as_string);
+ Utf8::Type type = Utf8::kLatin1;
+ intptr_t utf16_len = Utf8::CodeUnitCount(utf8_str, utf8_len, &type);
+
+ uint16_t* utf16_str = reinterpret_cast<uint16_t*>(
+ dart::malloc(utf16_len * sizeof(uint16_t)));
+ bool success =
+ Utf8::DecodeToUTF16(utf8_str, utf8_len, utf16_str, utf16_len);
+ ASSERT(success);
+ s->WriteUnsigned(utf16_len);
+ s->WriteBytes(reinterpret_cast<const uint8_t*>(utf16_str),
+ utf16_len * sizeof(uint16_t));
+ ::free(utf16_str);
+ }
+ }
+
+ private:
+ GrowableArray<String*> objects_;
+};
+
+class TwoByteStringMessageDeserializationCluster
+ : public MessageDeserializationCluster {
+ public:
+ explicit TwoByteStringMessageDeserializationCluster(bool is_canonical)
+ : MessageDeserializationCluster("TwoByteString", is_canonical) {}
+ ~TwoByteStringMessageDeserializationCluster() {}
+
+ void ReadNodes(MessageDeserializer* d) {
+ intptr_t count = d->ReadUnsigned();
+ for (intptr_t i = 0; i < count; i++) {
+ intptr_t length = d->ReadUnsigned();
+ const uint16_t* data =
+ reinterpret_cast<const uint16_t*>(d->CurrentBufferAddress());
+ d->Advance(length * sizeof(uint16_t));
+ d->AssignRef(is_canonical()
+ ? Symbols::FromUTF16(d->thread(), data, length)
+ : String::FromUTF16(data, length));
+ }
+ }
+
+ void ReadNodesApi(ApiMessageDeserializer* d) {
+ intptr_t count = d->ReadUnsigned();
+ for (intptr_t j = 0; j < count; j++) {
+ // Read all the UTF-16 code units.
+ intptr_t utf16_length = d->ReadUnsigned();
+ const uint16_t* utf16 =
+ reinterpret_cast<const uint16_t*>(d->CurrentBufferAddress());
+ d->Advance(utf16_length * sizeof(uint16_t));
+
+ // Calculate the UTF-8 length and check if the string can be
+ // UTF-8 encoded.
+ intptr_t utf8_len = 0;
+ bool valid = true;
+ intptr_t i = 0;
+ while (i < utf16_length && valid) {
+ int32_t ch = Utf16::Next(utf16, &i, utf16_length);
+ utf8_len += Utf8::Length(ch);
+ valid = !Utf16::IsSurrogate(ch);
+ }
+ if (!valid) {
+ d->AssignRef(d->Allocate(Dart_CObject_kUnsupported));
+ } else {
+ Dart_CObject* str = d->Allocate(Dart_CObject_kString);
+ char* utf8 = d->zone()->Alloc<char>(utf8_len + 1);
+ str->value.as_string = utf8;
+ i = 0;
+ while (i < utf16_length) {
+ utf8 += Utf8::Encode(Utf16::Next(utf16, &i, utf16_length), utf8);
+ }
+ *utf8 = '\0';
+ d->AssignRef(str);
+ }
+ }
+ }
+};
+
+static const intptr_t kFirstReference = 1;
+static const intptr_t kUnallocatedReference = -1;
+
+BaseSerializer::BaseSerializer(Thread* thread, Zone* zone)
+ : StackResource(thread),
+ zone_(zone),
+ stream_(100),
+ finalizable_data_(new MessageFinalizableData()),
+ clusters_(zone, 0),
+ ephemeron_cluster_(nullptr),
+ num_base_objects_(0),
+ num_written_objects_(0),
+ next_ref_index_(kFirstReference) {}
+
+BaseSerializer::~BaseSerializer() {
+ delete finalizable_data_;
+}
+
+MessageSerializer::MessageSerializer(Thread* thread, bool can_send_any_object)
+ : BaseSerializer(thread, thread->zone()),
+ forward_table_new_(),
+ forward_table_old_(),
+ stack_(thread->zone(), 0),
+ can_send_any_object_(can_send_any_object),
+ exception_message_(nullptr) {
+ isolate()->set_forward_table_new(new WeakTable());
+ isolate()->set_forward_table_old(new WeakTable());
+}
+
+MessageSerializer::~MessageSerializer() {
+ isolate()->set_forward_table_new(nullptr);
+ isolate()->set_forward_table_old(nullptr);
+}
+
+ApiMessageSerializer::ApiMessageSerializer(Zone* zone)
+ : BaseSerializer(nullptr, zone), forward_table_(), stack_(zone, 0) {}
+
+ApiMessageSerializer::~ApiMessageSerializer() {}
+
+void MessageSerializer::Push(ObjectPtr object) {
+ if (MarkObjectId(object, kUnallocatedReference)) {
+ stack_.Add(&Object::ZoneHandle(zone_, object));
+ num_written_objects_++;
+ }
+}
+
+void ApiMessageSerializer::Push(Dart_CObject* object) {
+ if (MarkObjectId(object, kUnallocatedReference)) {
+ stack_.Add(object);
+ num_written_objects_++;
+ }
+}
+
+void MessageSerializer::Trace(Object* object) {
+ intptr_t cid;
+ bool is_canonical;
+ if (!object->ptr()->IsHeapObject()) {
+ cid = kSmiCid;
+ is_canonical = true;
+ } else {
+ cid = object->GetClassId();
+ is_canonical = object->ptr()->untag()->IsCanonical();
+ }
+
+ MessageSerializationCluster* cluster = nullptr;
+ for (MessageSerializationCluster* c : clusters_) {
+ if ((c->cid() == cid) && (c->is_canonical() == is_canonical)) {
+ cluster = c;
+ break;
+ }
+ }
+ if (cluster == nullptr) {
+ if (cid >= kNumPredefinedCids || cid == kInstanceCid) {
+ const Class& clazz =
+ Class::Handle(zone(), isolate_group()->class_table()->At(cid));
+ if (!can_send_any_object()) {
+ ObjectStore* object_store = isolate_group()->object_store();
+ if ((clazz.library() != object_store->core_library()) &&
+ (clazz.library() != object_store->collection_library()) &&
+ (clazz.library() != object_store->typed_data_library())) {
+ IllegalObject(*object,
+ "Illegal argument in isolate message"
+ " : (object is a regular Dart Instance)");
+ }
+ }
+ if (clazz.num_native_fields() != 0) {
+ char* chars = OS::SCreate(thread()->zone(),
+ "Illegal argument in isolate message"
+ " : (object extends NativeWrapper - %s)",
+ clazz.ToCString());
+ IllegalObject(*object, chars);
+ }
+ }
+#define ILLEGAL(type) \
+ if (cid == k##type##Cid) { \
+ IllegalObject(*object, \
+ "Illegal argument in isolate message" \
+ " : (object is a " #type ")"); \
+ }
+
+ ILLEGAL(FunctionType)
+ ILLEGAL(DynamicLibrary)
+ ILLEGAL(MirrorReference)
+ ILLEGAL(Pointer)
+ ILLEGAL(ReceivePort)
+ ILLEGAL(StackTrace)
+ ILLEGAL(UserTag)
+#undef ILLEGAL
+
+ switch (cid) {
+#define ILLEGAL(type) case kFfi##type##Cid:
+ CLASS_LIST_FFI(ILLEGAL)
+#undef ILLEGAL
+ IllegalObject(*object,
+ "Native objects (from dart:ffi) such as Pointers and "
+ "Structs cannot be passed between isolates.");
+ }
+
+ if (cid >= kNumPredefinedCids || cid == kInstanceCid ||
+ cid == kByteBufferCid) {
+ Push(isolate_group()->class_table()->At(cid));
+ }
+ cluster = NewClusterForClass(cid, is_canonical);
+ clusters_.Add(cluster);
+ }
+
+ cluster->Trace(this, object);
+}
+
+bool ApiMessageSerializer::Trace(Dart_CObject* object) {
+ const bool is_canonical = false;
+ intptr_t cid;
+ switch (object->type) {
+ case Dart_CObject_kNull:
+ ForwardRef(object, &cobj_null);
+ return true;
+ case Dart_CObject_kBool:
+ ForwardRef(object, object->value.as_bool ? &cobj_true : &cobj_false);
+ return true;
+ case Dart_CObject_kInt32:
+ cid = Smi::IsValid(object->value.as_int32) ? kSmiCid : kMintCid;
+ break;
+ case Dart_CObject_kInt64:
+ cid = Smi::IsValid(object->value.as_int64) ? kSmiCid : kMintCid;
+ break;
+ case Dart_CObject_kDouble:
+ cid = kDoubleCid;
+ break;
+ case Dart_CObject_kString: {
+ const uint8_t* utf8_str =
+ reinterpret_cast<const uint8_t*>(object->value.as_string);
+ intptr_t utf8_len = strlen(object->value.as_string);
+ if (!Utf8::IsValid(utf8_str, utf8_len)) {
+ return Fail("invalid utf8");
+ }
+ Utf8::Type type = Utf8::kLatin1;
+ intptr_t len = Utf8::CodeUnitCount(utf8_str, utf8_len, &type);
+ if (len > String::kMaxElements) {
+ return Fail("invalid string length");
+ }
+ cid = type == Utf8::kLatin1 ? kOneByteStringCid : kTwoByteStringCid;
+ break;
+ }
+ case Dart_CObject_kArray:
+ cid = kArrayCid;
+ if (!Array::IsValidLength(object->value.as_array.length)) {
+ return Fail("invalid array length");
+ }
+ break;
+ case Dart_CObject_kTypedData:
+ switch (object->value.as_typed_data.type) {
+ case Dart_TypedData_kInt8:
+ cid = kTypedDataInt8ArrayCid;
+ break;
+ case Dart_TypedData_kUint8:
+ cid = kTypedDataUint8ArrayCid;
+ break;
+ case Dart_TypedData_kUint8Clamped:
+ cid = kTypedDataUint8ClampedArrayCid;
+ break;
+ case Dart_TypedData_kInt16:
+ cid = kTypedDataInt16ArrayCid;
+ break;
+ case Dart_TypedData_kUint16:
+ cid = kTypedDataUint16ArrayCid;
+ break;
+ case Dart_TypedData_kInt32:
+ cid = kTypedDataInt32ArrayCid;
+ break;
+ case Dart_TypedData_kUint32:
+ cid = kTypedDataUint32ArrayCid;
+ break;
+ case Dart_TypedData_kInt64:
+ cid = kTypedDataInt64ArrayCid;
+ break;
+ case Dart_TypedData_kUint64:
+ cid = kTypedDataUint64ArrayCid;
+ break;
+ case Dart_TypedData_kFloat32:
+ cid = kTypedDataFloat32ArrayCid;
+ break;
+ case Dart_TypedData_kFloat64:
+ cid = kTypedDataFloat64ArrayCid;
+ break;
+ case Dart_TypedData_kInt32x4:
+ cid = kTypedDataInt32x4ArrayCid;
+ break;
+ case Dart_TypedData_kFloat32x4:
+ cid = kTypedDataFloat32x4ArrayCid;
+ break;
+ case Dart_TypedData_kFloat64x2:
+ cid = kTypedDataFloat64x2ArrayCid;
+ break;
+ default:
+ return Fail("invalid TypedData type");
+ }
+ {
+ intptr_t len = object->value.as_typed_data.length;
+ if (len < 0 || len > TypedData::MaxElements(cid)) {
+ return Fail("invalid typeddata length");
+ }
+ }
+ break;
+ case Dart_CObject_kExternalTypedData:
+ switch (object->value.as_external_typed_data.type) {
+ case Dart_TypedData_kInt8:
+ cid = kExternalTypedDataInt8ArrayCid;
+ break;
+ case Dart_TypedData_kUint8:
+ cid = kExternalTypedDataUint8ArrayCid;
+ break;
+ case Dart_TypedData_kUint8Clamped:
+ cid = kExternalTypedDataUint8ClampedArrayCid;
+ break;
+ case Dart_TypedData_kInt16:
+ cid = kExternalTypedDataInt16ArrayCid;
+ break;
+ case Dart_TypedData_kUint16:
+ cid = kExternalTypedDataUint16ArrayCid;
+ break;
+ case Dart_TypedData_kInt32:
+ cid = kExternalTypedDataInt32ArrayCid;
+ break;
+ case Dart_TypedData_kUint32:
+ cid = kExternalTypedDataUint32ArrayCid;
+ break;
+ case Dart_TypedData_kInt64:
+ cid = kExternalTypedDataInt64ArrayCid;
+ break;
+ case Dart_TypedData_kUint64:
+ cid = kExternalTypedDataUint64ArrayCid;
+ break;
+ case Dart_TypedData_kFloat32:
+ cid = kExternalTypedDataFloat32ArrayCid;
+ break;
+ case Dart_TypedData_kFloat64:
+ cid = kExternalTypedDataFloat64ArrayCid;
+ break;
+ case Dart_TypedData_kInt32x4:
+ cid = kExternalTypedDataInt32x4ArrayCid;
+ break;
+ case Dart_TypedData_kFloat32x4:
+ cid = kExternalTypedDataFloat32x4ArrayCid;
+ break;
+ case Dart_TypedData_kFloat64x2:
+ cid = kExternalTypedDataFloat64x2ArrayCid;
+ break;
+ default:
+ return Fail("invalid TypedData type");
+ }
+ {
+ intptr_t len = object->value.as_typed_data.length;
+ if (len < 0 || len > ExternalTypedData::MaxElements(cid)) {
+ return Fail("invalid typeddata length");
+ }
+ }
+ break;
+ case Dart_CObject_kSendPort:
+ cid = kSendPortCid;
+ break;
+ case Dart_CObject_kCapability:
+ cid = kCapabilityCid;
+ break;
+ default:
+ return Fail("invalid Dart_CObject type");
+ }
+
+ MessageSerializationCluster* cluster = nullptr;
+ for (MessageSerializationCluster* c : clusters_) {
+ if (c->cid() == cid) {
+ cluster = c;
+ break;
+ }
+ }
+ if (cluster == nullptr) {
+ cluster = NewClusterForClass(cid, is_canonical);
+ clusters_.Add(cluster);
+ }
+
+ cluster->TraceApi(this, object);
+ return true;
+}
+
+void MessageSerializer::IllegalObject(const Object& object,
+ const char* message) {
+ exception_message_ = message;
+ thread()->long_jump_base()->Jump(1, Object::snapshot_writer_error());
+}
+
+BaseDeserializer::BaseDeserializer(Zone* zone, Message* message)
+ : zone_(zone),
+ stream_(message->snapshot(), message->snapshot_length()),
+ finalizable_data_(message->finalizable_data()),
+ next_ref_index_(kFirstReference) {}
+
+BaseDeserializer::~BaseDeserializer() {}
+
+MessageSerializationCluster* BaseSerializer::NewClusterForClass(
+ intptr_t cid,
+ bool is_canonical) {
+ Zone* Z = zone_;
+ if ((cid >= kNumPredefinedCids) || (cid == kInstanceCid) ||
+ (cid == kByteBufferCid)) {
+ return new (Z) InstanceMessageSerializationCluster(is_canonical, cid);
+ }
+ if (IsTypedDataViewClassId(cid) || cid == kByteDataViewCid) {
+ return new (Z) TypedDataViewMessageSerializationCluster(Z, cid);
+ }
+ if (IsExternalTypedDataClassId(cid)) {
+ return new (Z) ExternalTypedDataMessageSerializationCluster(Z, cid);
+ }
+ if (IsTypedDataClassId(cid)) {
+ return new (Z) TypedDataMessageSerializationCluster(Z, cid);
+ }
+
+ switch (cid) {
+ case kClassCid:
+ return new (Z) ClassMessageSerializationCluster();
+ case kTypeArgumentsCid:
+ return new (Z) TypeArgumentsMessageSerializationCluster(is_canonical);
+ case kFunctionCid:
+ return new (Z) FunctionMessageSerializationCluster();
+ case kTypeCid:
+ return new (Z) TypeMessageSerializationCluster(is_canonical);
+ case kTypeRefCid:
+ return new (Z) TypeRefMessageSerializationCluster(is_canonical);
+ case kClosureCid:
+ return new (Z) ClosureMessageSerializationCluster(is_canonical);
+ case kSmiCid:
+ return new (Z) SmiMessageSerializationCluster(Z);
+ case kMintCid:
+ return new (Z) MintMessageSerializationCluster(Z, is_canonical);
+ case kDoubleCid:
+ return new (Z) DoubleMessageSerializationCluster(Z, is_canonical);
+ case kGrowableObjectArrayCid:
+ return new (Z) GrowableObjectArrayMessageSerializationCluster();
+ case kRegExpCid:
+ return new (Z) RegExpMessageSerializationCluster();
+ case kSendPortCid:
+ return new (Z) SendPortMessageSerializationCluster(Z);
+ case kCapabilityCid:
+ return new (Z) CapabilityMessageSerializationCluster(Z);
+ case kTransferableTypedDataCid:
+ return new (Z) TransferableTypedDataMessageSerializationCluster();
+ case kWeakPropertyCid:
+ ephemeron_cluster_ = new (Z) WeakPropertyMessageSerializationCluster();
+ return ephemeron_cluster_;
+ case kLinkedHashMapCid:
+ return new (Z) LinkedHashMapMessageSerializationCluster();
+ case kLinkedHashSetCid:
+ return new (Z) LinkedHashSetMessageSerializationCluster();
+ case kArrayCid:
+ case kImmutableArrayCid:
+ return new (Z) ArrayMessageSerializationCluster(Z, is_canonical, cid);
+ case kOneByteStringCid:
+ return new (Z) OneByteStringMessageSerializationCluster(Z, is_canonical);
+ case kTwoByteStringCid:
+ return new (Z) TwoByteStringMessageSerializationCluster(Z, is_canonical);
+ default:
+ break;
+ }
+
+ FATAL("No cluster defined for cid %" Pd, cid);
+ return nullptr;
+}
+
+void BaseSerializer::WriteCluster(MessageSerializationCluster* cluster) {
+ uint64_t cid_and_canonical = (static_cast<uint64_t>(cluster->cid()) << 1) |
+ (cluster->is_canonical() ? 0x1 : 0x0);
+ WriteUnsigned(cid_and_canonical);
+}
+
+MessageDeserializationCluster* BaseDeserializer::ReadCluster() {
+ const uint64_t cid_and_canonical = ReadUnsigned();
+ const intptr_t cid = (cid_and_canonical >> 1) & kMaxUint32;
+ const bool is_canonical = (cid_and_canonical & 0x1) == 0x1;
+
+ Zone* Z = zone_;
+ if ((cid >= kNumPredefinedCids) || (cid == kInstanceCid) ||
+ (cid == kByteBufferCid)) {
+ return new (Z) InstanceMessageDeserializationCluster(is_canonical);
+ }
+ if (IsTypedDataViewClassId(cid) || cid == kByteDataViewCid) {
+ ASSERT(!is_canonical);
+ return new (Z) TypedDataViewMessageDeserializationCluster(cid);
+ }
+ if (IsExternalTypedDataClassId(cid)) {
+ ASSERT(!is_canonical);
+ return new (Z) ExternalTypedDataMessageDeserializationCluster(cid);
+ }
+ if (IsTypedDataClassId(cid)) {
+ ASSERT(!is_canonical);
+ return new (Z) TypedDataMessageDeserializationCluster(cid);
+ }
+
+ switch (cid) {
+ case kClassCid:
+ ASSERT(!is_canonical);
+ return new (Z) ClassMessageDeserializationCluster();
+ case kTypeArgumentsCid:
+ return new (Z) TypeArgumentsMessageDeserializationCluster(is_canonical);
+ case kFunctionCid:
+ ASSERT(!is_canonical);
+ return new (Z) FunctionMessageDeserializationCluster();
+ case kTypeCid:
+ return new (Z) TypeMessageDeserializationCluster(is_canonical);
+ case kTypeRefCid:
+ return new (Z) TypeRefMessageDeserializationCluster(is_canonical);
+ case kClosureCid:
+ return new (Z) ClosureMessageDeserializationCluster(is_canonical);
+ case kSmiCid:
+ ASSERT(is_canonical);
+ return new (Z) SmiMessageDeserializationCluster();
+ case kMintCid:
+ return new (Z) MintMessageDeserializationCluster(is_canonical);
+ case kDoubleCid:
+ return new (Z) DoubleMessageDeserializationCluster(is_canonical);
+ case kGrowableObjectArrayCid:
+ ASSERT(!is_canonical);
+ return new (Z) GrowableObjectArrayMessageDeserializationCluster();
+ case kRegExpCid:
+ ASSERT(!is_canonical);
+ return new (Z) RegExpMessageDeserializationCluster();
+ case kSendPortCid:
+ ASSERT(!is_canonical);
+ return new (Z) SendPortMessageDeserializationCluster();
+ case kCapabilityCid:
+ ASSERT(!is_canonical);
+ return new (Z) CapabilityMessageDeserializationCluster();
+ case kTransferableTypedDataCid:
+ ASSERT(!is_canonical);
+ return new (Z) TransferableTypedDataMessageDeserializationCluster();
+ case kWeakPropertyCid:
+ ASSERT(!is_canonical);
+ return new (Z) WeakPropertyMessageDeserializationCluster();
+ case kLinkedHashMapCid:
+ return new (Z) LinkedHashMapMessageDeserializationCluster(is_canonical);
+ case kLinkedHashSetCid:
+ return new (Z) LinkedHashSetMessageDeserializationCluster(is_canonical);
+ case kArrayCid:
+ case kImmutableArrayCid:
+ return new (Z) ArrayMessageDeserializationCluster(is_canonical, cid);
+ case kOneByteStringCid:
+ return new (Z) OneByteStringMessageDeserializationCluster(is_canonical);
+ case kTwoByteStringCid:
+ return new (Z) TwoByteStringMessageDeserializationCluster(is_canonical);
+ default:
+ break;
+ }
+
+ FATAL("No cluster defined for cid %" Pd, cid);
+ return nullptr;
+}
+
+void MessageSerializer::AddBaseObjects() {
+ AddBaseObject(Object::null());
+ AddBaseObject(Object::sentinel().ptr());
+ AddBaseObject(Object::transition_sentinel().ptr());
+ AddBaseObject(Object::empty_array().ptr());
+ AddBaseObject(Object::zero_array().ptr());
+ AddBaseObject(Object::dynamic_type().ptr());
+ AddBaseObject(Object::void_type().ptr());
+ AddBaseObject(Object::empty_type_arguments().ptr());
+ AddBaseObject(Bool::True().ptr());
+ AddBaseObject(Bool::False().ptr());
+}
+
+void MessageDeserializer::AddBaseObjects() {
+ AddBaseObject(Object::null());
+ AddBaseObject(Object::sentinel().ptr());
+ AddBaseObject(Object::transition_sentinel().ptr());
+ AddBaseObject(Object::empty_array().ptr());
+ AddBaseObject(Object::zero_array().ptr());
+ AddBaseObject(Object::dynamic_type().ptr());
+ AddBaseObject(Object::void_type().ptr());
+ AddBaseObject(Object::empty_type_arguments().ptr());
+ AddBaseObject(Bool::True().ptr());
+ AddBaseObject(Bool::False().ptr());
+}
+
+void ApiMessageSerializer::AddBaseObjects() {
+ AddBaseObject(&cobj_null);
+ AddBaseObject(&cobj_sentinel);
+ AddBaseObject(&cobj_transition_sentinel);
+ AddBaseObject(&cobj_empty_array);
+ AddBaseObject(&cobj_zero_array);
+ AddBaseObject(&cobj_dynamic_type);
+ AddBaseObject(&cobj_void_type);
+ AddBaseObject(&cobj_empty_type_arguments);
+ AddBaseObject(&cobj_true);
+ AddBaseObject(&cobj_false);
+}
+
+void ApiMessageDeserializer::AddBaseObjects() {
+ AddBaseObject(&cobj_null);
+ AddBaseObject(&cobj_sentinel);
+ AddBaseObject(&cobj_transition_sentinel);
+ AddBaseObject(&cobj_empty_array);
+ AddBaseObject(&cobj_zero_array);
+ AddBaseObject(&cobj_dynamic_type);
+ AddBaseObject(&cobj_void_type);
+ AddBaseObject(&cobj_empty_type_arguments);
+ AddBaseObject(&cobj_true);
+ AddBaseObject(&cobj_false);
+}
+
+void MessageSerializer::Serialize(const Object& root) {
+ AddBaseObjects();
+
+ Push(root.ptr());
+
+ while (stack_.length() > 0) {
+ // Strong references.
+ while (stack_.length() > 0) {
+ Trace(stack_.RemoveLast());
+ }
+
+ // Ephemeron references.
+ if (ephemeron_cluster_ != nullptr) {
+ ephemeron_cluster_->RetraceEphemerons(this);
+ }
+ }
+
+ intptr_t num_objects = num_base_objects_ + num_written_objects_;
+ WriteUnsigned(num_base_objects_);
+ WriteUnsigned(num_objects);
+
+ for (intptr_t i = 0; i < static_cast<intptr_t>(MessagePhase::kNumPhases);
+ i++) {
+ intptr_t num_clusters = 0;
+ for (MessageSerializationCluster* cluster : clusters_) {
+ if (static_cast<intptr_t>(cluster->phase()) != i) continue;
+ num_clusters++;
+ }
+ WriteUnsigned(num_clusters);
+ for (MessageSerializationCluster* cluster : clusters_) {
+ if (static_cast<intptr_t>(cluster->phase()) != i) continue;
+ WriteCluster(cluster);
+ cluster->WriteNodes(this);
+ }
+ for (MessageSerializationCluster* cluster : clusters_) {
+ if (static_cast<intptr_t>(cluster->phase()) != i) continue;
+ cluster->WriteEdges(this);
+ }
+ }
+
+ // We should have assigned a ref to every object we pushed.
+ ASSERT((next_ref_index_ - 1) == num_objects);
+
+ WriteRef(root.ptr());
+}
+
+bool ApiMessageSerializer::Serialize(Dart_CObject* root) {
+ AddBaseObjects();
+
+ Push(root);
+
+ // Strong references only.
+ while (stack_.length() > 0) {
+ if (!Trace(stack_.RemoveLast())) {
+ return false;
+ }
+ }
+
+ intptr_t num_objects = num_base_objects_ + num_written_objects_;
+ WriteUnsigned(num_base_objects_);
+ WriteUnsigned(num_objects);
+
+ for (intptr_t i = 0; i < static_cast<intptr_t>(MessagePhase::kNumPhases);
+ i++) {
+ intptr_t num_clusters = 0;
+ for (MessageSerializationCluster* cluster : clusters_) {
+ if (static_cast<intptr_t>(cluster->phase()) != i) continue;
+ num_clusters++;
+ }
+ WriteUnsigned(num_clusters);
+ for (MessageSerializationCluster* cluster : clusters_) {
+ if (static_cast<intptr_t>(cluster->phase()) != i) continue;
+ WriteCluster(cluster);
+ cluster->WriteNodesApi(this);
+ }
+ for (MessageSerializationCluster* cluster : clusters_) {
+ if (static_cast<intptr_t>(cluster->phase()) != i) continue;
+ cluster->WriteEdgesApi(this);
+ }
+ }
+
+ // We should have assigned a ref to every object we pushed.
+ ASSERT((next_ref_index_ - 1) == num_objects);
+
+ WriteRef(root);
+ return true;
+}
+
+ObjectPtr MessageDeserializer::Deserialize() {
+ intptr_t num_base_objects = ReadUnsigned();
+ intptr_t num_objects = ReadUnsigned();
+
+ refs_ = Array::New(num_objects + kFirstReference);
+
+ AddBaseObjects();
+
+ // Writer and reader must agree on number of base objects.
+ ASSERT_EQUAL(num_base_objects, (next_ref_index_ - kFirstReference));
+
+ Object& error = Object::Handle(zone());
+ for (intptr_t i = 0; i < static_cast<intptr_t>(MessagePhase::kNumPhases);
+ i++) {
+ intptr_t num_clusters = ReadUnsigned();
+ MessageDeserializationCluster** clusters =
+ zone()->Alloc<MessageDeserializationCluster*>(num_clusters);
+ for (intptr_t i = 0; i < num_clusters; i++) {
+ clusters[i] = ReadCluster();
+ clusters[i]->ReadNodesWrapped(this);
+ }
+ for (intptr_t i = 0; i < num_clusters; i++) {
+ clusters[i]->ReadEdges(this);
+ }
+ for (intptr_t i = 0; i < num_clusters; i++) {
+ error = clusters[i]->PostLoad(this);
+ if (error.IsError()) {
+ return error.ptr(); // E.g., an UnwindError during rehashing.
+ }
+ }
+ }
+
+ // We should have completely filled the ref array.
+ ASSERT_EQUAL(next_ref_index_ - kFirstReference, num_objects);
+
+ return ReadRef();
+}
+
+Dart_CObject* ApiMessageDeserializer::Deserialize() {
+ intptr_t num_base_objects = ReadUnsigned();
+ intptr_t num_objects = ReadUnsigned();
+
+ refs_ = zone()->Alloc<Dart_CObject*>(num_objects + kFirstReference);
+
+ AddBaseObjects();
+
+ // Writer and reader must agree on number of base objects.
+ ASSERT_EQUAL(num_base_objects, (next_ref_index_ - kFirstReference));
+
+ for (intptr_t i = 0; i < static_cast<intptr_t>(MessagePhase::kNumPhases);
+ i++) {
+ intptr_t num_clusters = ReadUnsigned();
+ MessageDeserializationCluster** clusters =
+ zone()->Alloc<MessageDeserializationCluster*>(num_clusters);
+ for (intptr_t i = 0; i < num_clusters; i++) {
+ clusters[i] = ReadCluster();
+ clusters[i]->ReadNodesWrappedApi(this);
+ }
+ for (intptr_t i = 0; i < num_clusters; i++) {
+ clusters[i]->ReadEdgesApi(this);
+ }
+ for (intptr_t i = 0; i < num_clusters; i++) {
+ clusters[i]->PostLoadApi(this);
+ }
+ }
+
+ // We should have completely filled the ref array.
+ ASSERT_EQUAL(next_ref_index_ - kFirstReference, num_objects);
+
+ return ReadRef();
+}
+
+std::unique_ptr<Message> WriteMessage(bool can_send_any_object,
+ const Object& obj,
+ Dart_Port dest_port,
+ Message::Priority priority) {
+ if (ApiObjectConverter::CanConvert(obj.ptr())) {
+ return Message::New(dest_port, obj.ptr(), priority);
+ }
+
+ Thread* thread = Thread::Current();
+ MessageSerializer serializer(thread, can_send_any_object);
+
+ volatile bool has_exception = false;
+ {
+ LongJumpScope jump;
+ if (setjmp(*jump.Set()) == 0) {
+ serializer.Serialize(obj);
+ } else {
+ has_exception = true;
+ }
+ }
+
+ if (has_exception) {
+ {
+ NoSafepointScope no_safepoint;
+ ErrorPtr error = thread->StealStickyError();
+ ASSERT(error == Object::snapshot_writer_error().ptr());
+ }
+
+ const String& msg_obj =
+ String::Handle(String::New(serializer.exception_message()));
+ const Array& args = Array::Handle(Array::New(1));
+ args.SetAt(0, msg_obj);
+ Exceptions::ThrowByType(Exceptions::kArgument, args);
+ }
+
+ return serializer.Finish(dest_port, priority);
+}
+
+std::unique_ptr<Message> WriteApiMessage(Zone* zone,
+ Dart_CObject* obj,
+ Dart_Port dest_port,
+ Message::Priority priority) {
+ ApiMessageSerializer serializer(zone);
+ if (!serializer.Serialize(obj)) {
+ return nullptr;
+ }
+ return serializer.Finish(dest_port, priority);
+}
+
+ObjectPtr ReadMessage(Thread* thread, Message* message) {
+ if (message->IsRaw()) {
+ return message->raw_obj();
+ } else {
+ RELEASE_ASSERT(message->IsSnapshot());
+ MessageDeserializer deserializer(thread, message);
+ return deserializer.Deserialize();
+ }
+}
+
+Dart_CObject* ReadApiMessage(Zone* zone, Message* message) {
+ if (message->IsRaw()) {
+ Dart_CObject* result = zone->Alloc<Dart_CObject>(1);
+ ApiObjectConverter::Convert(message->raw_obj(), result);
+ return result;
+ } else {
+ RELEASE_ASSERT(message->IsSnapshot());
+ ApiMessageDeserializer deserializer(zone, message);
+ return deserializer.Deserialize();
+ }
+}
+
+} // namespace dart
diff --git a/runtime/vm/message_snapshot.h b/runtime/vm/message_snapshot.h
new file mode 100644
index 0000000..d06640e
--- /dev/null
+++ b/runtime/vm/message_snapshot.h
@@ -0,0 +1,32 @@
+// Copyright (c) 2021, 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_MESSAGE_SNAPSHOT_H_
+#define RUNTIME_VM_MESSAGE_SNAPSHOT_H_
+
+#include <memory>
+
+#include "include/dart_native_api.h"
+#include "vm/message.h"
+#include "vm/object.h"
+
+namespace dart {
+
+std::unique_ptr<Message> WriteMessage(bool can_send_any_object,
+ const Object& obj,
+ Dart_Port dest_port,
+ Message::Priority priority);
+
+std::unique_ptr<Message> WriteApiMessage(Zone* zone,
+ Dart_CObject* obj,
+ Dart_Port dest_port,
+ Message::Priority priority);
+
+ObjectPtr ReadMessage(Thread* thread, Message* message);
+
+Dart_CObject* ReadApiMessage(Zone* zone, Message* message);
+
+} // namespace dart
+
+#endif // RUNTIME_VM_MESSAGE_SNAPSHOT_H_
diff --git a/runtime/vm/native_api_impl.cc b/runtime/vm/native_api_impl.cc
index 20f7748..132ac95 100644
--- a/runtime/vm/native_api_impl.cc
+++ b/runtime/vm/native_api_impl.cc
@@ -12,6 +12,7 @@
#include "vm/dart_api_message.h"
#include "vm/dart_api_state.h"
#include "vm/message.h"
+#include "vm/message_snapshot.h"
#include "vm/native_message_handler.h"
#include "vm/port.h"
#include "vm/service_isolate.h"
@@ -43,9 +44,9 @@
};
static bool PostCObjectHelper(Dart_Port port_id, Dart_CObject* message) {
- ApiMessageWriter writer;
- std::unique_ptr<Message> msg =
- writer.WriteCMessage(message, port_id, Message::kNormalPriority);
+ AllocOnlyStackZone zone;
+ std::unique_ptr<Message> msg = WriteApiMessage(
+ zone.GetZone(), message, port_id, Message::kNormalPriority);
if (msg == nullptr) {
return false;
diff --git a/runtime/vm/native_message_handler.cc b/runtime/vm/native_message_handler.cc
index 65d97fd..31639e9 100644
--- a/runtime/vm/native_message_handler.cc
+++ b/runtime/vm/native_message_handler.cc
@@ -9,6 +9,7 @@
#include "vm/dart_api_message.h"
#include "vm/isolate.h"
#include "vm/message.h"
+#include "vm/message_snapshot.h"
#include "vm/snapshot.h"
namespace dart {
@@ -37,9 +38,7 @@
// All allocation of objects for decoding the message is done in the
// zone associated with this scope.
ApiNativeScope scope;
- Dart_CObject* object;
- ApiMessageReader reader(message.get());
- object = reader.ReadMessage();
+ Dart_CObject* object = ReadApiMessage(scope.zone(), message.get());
(*func())(message->dest_port(), object);
return kOK;
}
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc
index 68a8470..3e1f788 100644
--- a/runtime/vm/object.cc
+++ b/runtime/vm/object.cc
@@ -11610,14 +11610,14 @@
void Field::RecordStore(const Object& value) const {
ASSERT(IsOriginal());
- if (!IsolateGroup::Current()->use_field_guards()) {
+ Thread* const thread = Thread::Current();
+ if (!thread->isolate_group()->use_field_guards()) {
return;
}
// We should never try to record a sentinel.
ASSERT(value.ptr() != Object::sentinel().ptr());
- Thread* const thread = Thread::Current();
SafepointWriteRwLocker ml(thread, thread->isolate_group()->program_lock());
if ((guarded_cid() == kDynamicCid) ||
(is_nullable() && value.ptr() == Object::null())) {
diff --git a/runtime/vm/object.h b/runtime/vm/object.h
index 5caf25f..5f0f6dc 100644
--- a/runtime/vm/object.h
+++ b/runtime/vm/object.h
@@ -215,11 +215,9 @@
#define OBJECT_SERVICE_SUPPORT(object) protected: /* NOLINT */
#endif // !PRODUCT
-#define SNAPSHOT_READER_SUPPORT(object) \
- static object##Ptr ReadFrom(SnapshotReader* reader, intptr_t object_id, \
- intptr_t tags, Snapshot::Kind, \
- bool as_reference); \
- friend class SnapshotReader;
+#define SNAPSHOT_SUPPORT(object) \
+ friend class object##MessageSerializationCluster; \
+ friend class object##MessageDeserializationCluster;
#define OBJECT_IMPLEMENTATION(object, super) \
public: /* NOLINT */ \
@@ -243,7 +241,7 @@
ASSERT(ptr() != null()); \
return const_cast<Untagged##object*>(ptr()->untag()); \
} \
- SNAPSHOT_READER_SUPPORT(object) \
+ SNAPSHOT_SUPPORT(object) \
friend class StackFrame; \
friend class Thread;
@@ -268,7 +266,7 @@
return const_cast<Untagged##object*>(ptr()->untag()); \
} \
static intptr_t NextFieldOffset() { return -kWordSize; } \
- SNAPSHOT_READER_SUPPORT(rettype) \
+ SNAPSHOT_SUPPORT(rettype) \
friend class Object; \
friend class StackFrame; \
friend class Thread;
@@ -860,7 +858,6 @@
friend void ClassTable::Register(const Class& cls);
friend void UntaggedObject::Validate(IsolateGroup* isolate_group) const;
friend class Closure;
- friend class SnapshotReader;
friend class InstanceDeserializationCluster;
friend class OneByteString;
friend class TwoByteString;
@@ -2482,7 +2479,6 @@
friend class VMDeserializationRoots;
friend class ICDataTestTask;
friend class VMSerializationRoots;
- friend class SnapshotWriter;
};
// Often used constants for number of free function type parameters.
@@ -3805,7 +3801,6 @@
FINAL_HEAP_OBJECT_IMPLEMENTATION(Function, Object);
friend class Class;
- friend class SnapshotWriter;
friend class Parser; // For set_eval_script.
// UntaggedFunction::VisitFunctionPointers accesses the private constructor of
// Function.
@@ -3849,7 +3844,6 @@
FINAL_HEAP_OBJECT_IMPLEMENTATION(ClosureData, Object);
friend class Class;
friend class Function;
- friend class HeapProfiler;
friend class Precompiler; // To wrap parent functions in WSRs.
};
@@ -3890,7 +3884,6 @@
FINAL_HEAP_OBJECT_IMPLEMENTATION(FfiTrampolineData, Object);
friend class Class;
friend class Function;
- friend class HeapProfiler;
};
class Field : public Object {
@@ -4451,7 +4444,6 @@
FINAL_HEAP_OBJECT_IMPLEMENTATION(Field, Object);
friend class Class;
- friend class HeapProfiler;
friend class UntaggedField;
friend class FieldSerializationCluster;
friend class FieldDeserializationCluster;
@@ -6703,7 +6695,6 @@
FINAL_HEAP_OBJECT_IMPLEMENTATION(Code, Object);
friend class Class;
friend class CodeTestHelper;
- friend class SnapshotWriter;
friend class StubCode; // for set_object_pool
friend class Precompiler; // for set_object_pool
friend class FunctionSerializationCluster;
@@ -7495,7 +7486,6 @@
friend class Pointer;
friend class DeferredObject;
friend class RegExp;
- friend class SnapshotWriter;
friend class StubCode;
friend class TypedDataView;
friend class InstanceSerializationCluster;
@@ -9079,6 +9069,7 @@
protected:
// Only Integer::NewXXX is allowed to call Mint::NewXXX directly.
friend class Integer;
+ friend class MintMessageDeserializationCluster;
static MintPtr New(int64_t value, Heap::Space space = Heap::kNew);
@@ -9489,14 +9480,6 @@
ASSERT(hash_set == value);
}
- template <typename HandleType, typename ElementType, typename CallbackType>
- static void ReadFromImpl(SnapshotReader* reader,
- String* str_obj,
- intptr_t len,
- intptr_t tags,
- CallbackType new_symbol,
- Snapshot::Kind kind);
-
FINAL_HEAP_OBJECT_IMPLEMENTATION(String, Instance);
friend class Class;
@@ -9666,20 +9649,14 @@
return &str.UnsafeMutableNonPointer(untag(str)->data())[0];
}
- static OneByteStringPtr ReadFrom(SnapshotReader* reader,
- intptr_t object_id,
- intptr_t tags,
- Snapshot::Kind kind,
- bool as_reference);
-
friend class Class;
friend class ExternalOneByteString;
friend class ImageWriter;
- friend class SnapshotReader;
friend class String;
friend class StringHasher;
friend class Symbols;
friend class Utf8;
+ friend class OneByteStringMessageSerializationCluster;
};
class TwoByteString : public AllStatic {
@@ -9792,18 +9769,12 @@
return &str.UnsafeMutableNonPointer(untag(str)->data())[0];
}
- static TwoByteStringPtr ReadFrom(SnapshotReader* reader,
- intptr_t object_id,
- intptr_t tags,
- Snapshot::Kind kind,
- bool as_reference);
-
friend class Class;
friend class ImageWriter;
- friend class SnapshotReader;
friend class String;
friend class StringHasher;
friend class Symbols;
+ friend class TwoByteStringMessageSerializationCluster;
};
class ExternalOneByteString : public AllStatic {
@@ -9887,12 +9858,6 @@
Dart_WeakPersistentHandle handle,
void* peer);
- 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.
return -kWordSize;
@@ -9901,7 +9866,6 @@
friend class Class;
friend class String;
friend class StringHasher;
- friend class SnapshotReader;
friend class Symbols;
friend class Utf8;
};
@@ -9983,12 +9947,6 @@
Dart_WeakPersistentHandle handle,
void* peer);
- 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.
return -kWordSize;
@@ -9997,7 +9955,6 @@
friend class Class;
friend class String;
friend class StringHasher;
- friend class SnapshotReader;
friend class Symbols;
};
@@ -10233,6 +10190,7 @@
friend class ImmutableArray;
friend class Object;
friend class String;
+ friend class MessageDeserializer;
};
class ImmutableArray : public AllStatic {
@@ -10243,12 +10201,6 @@
static ImmutableArrayPtr New(intptr_t len, Heap::Space space = Heap::kNew);
- static ImmutableArrayPtr ReadFrom(SnapshotReader* reader,
- intptr_t object_id,
- intptr_t tags,
- Snapshot::Kind kind,
- bool as_reference);
-
static const ClassId kClassId = kImmutableArrayCid;
static intptr_t InstanceSize() { return Array::InstanceSize(); }
diff --git a/runtime/vm/object_reload.cc b/runtime/vm/object_reload.cc
index 2f404f5..7fe26f1 100644
--- a/runtime/vm/object_reload.cc
+++ b/runtime/vm/object_reload.cc
@@ -6,6 +6,7 @@
#include "platform/unaligned.h"
#include "vm/code_patcher.h"
+#include "vm/dart_entry.h"
#include "vm/hash_table.h"
#include "vm/isolate_reload.h"
#include "vm/log.h"
diff --git a/runtime/vm/object_store.cc b/runtime/vm/object_store.cc
index 47e7abc..33bede3 100644
--- a/runtime/vm/object_store.cc
+++ b/runtime/vm/object_store.cc
@@ -307,6 +307,10 @@
ASSERT(!cls.IsNull());
set_error_class(cls);
+ cls = core_lib.LookupClassAllowPrivate(Symbols::Expando());
+ ASSERT(!cls.IsNull());
+ set_expando_class(cls);
+
// Cache the core private functions used for fast instance of checks.
simple_instance_of_function_ =
PrivateObjectLookup(Symbols::_simpleInstanceOf());
diff --git a/runtime/vm/object_store.h b/runtime/vm/object_store.h
index 64dabde..a944d89 100644
--- a/runtime/vm/object_store.h
+++ b/runtime/vm/object_store.h
@@ -141,6 +141,7 @@
RW(Class, int32x4_class) \
RW(Class, float64x2_class) \
RW(Class, error_class) \
+ RW(Class, expando_class) \
RW(Class, weak_property_class) \
ARW_AR(Array, symbol_table) \
RW(Array, canonical_types) \
@@ -535,7 +536,6 @@
case Snapshot::kFullJIT:
case Snapshot::kFullAOT:
return reinterpret_cast<ObjectPtr*>(&slow_tts_stub_);
- case Snapshot::kMessage:
case Snapshot::kNone:
case Snapshot::kInvalid:
break;
diff --git a/runtime/vm/raw_object.h b/runtime/vm/raw_object.h
index ac076be..3d442b2 100644
--- a/runtime/vm/raw_object.h
+++ b/runtime/vm/raw_object.h
@@ -18,8 +18,10 @@
#include "vm/pointer_tagging.h"
#include "vm/snapshot.h"
#include "vm/tagged_pointer.h"
+#include "vm/thread.h"
#include "vm/token.h"
#include "vm/token_position.h"
+#include "vm/visitor.h"
// Currently we have two different axes for offset generation:
//
@@ -118,17 +120,10 @@
#undef V
};
-#define SNAPSHOT_WRITER_SUPPORT() \
- void WriteTo(SnapshotWriter* writer, intptr_t object_id, \
- Snapshot::Kind kind, bool as_reference); \
- friend class SnapshotWriter;
-
#define VISITOR_SUPPORT(object) \
static intptr_t Visit##object##Pointers(object##Ptr raw_obj, \
ObjectPointerVisitor* visitor);
-#define HEAP_PROFILER_SUPPORT() friend class HeapProfiler;
-
#define RAW_OBJECT_IMPLEMENTATION(object) \
private: /* NOLINT */ \
VISITOR_SUPPORT(object) \
@@ -144,10 +139,10 @@
#define RAW_HEAP_OBJECT_IMPLEMENTATION(object) \
private: \
RAW_OBJECT_IMPLEMENTATION(object); \
- SNAPSHOT_WRITER_SUPPORT() \
- HEAP_PROFILER_SUPPORT() \
friend class object##SerializationCluster; \
friend class object##DeserializationCluster; \
+ friend class object##MessageSerializationCluster; \
+ friend class object##MessageDeserializationCluster; \
friend class Serializer; \
friend class Deserializer; \
template <typename Base> \
@@ -547,6 +542,8 @@
}
}
+ friend class MessageDeserializer; // bogus
+
template <typename type,
typename compressed_type,
std::memory_order order = std::memory_order_relaxed>
@@ -760,9 +757,7 @@
friend class ImageWriter;
friend class AssemblyImageWriter;
friend class BlobImageWriter;
- friend class SnapshotReader;
friend class Deserializer;
- friend class SnapshotWriter;
friend class String;
friend class WeakProperty; // StorePointer
friend class Instance; // StorePointer
@@ -840,8 +835,8 @@
} \
template <std::memory_order order = std::memory_order_relaxed> \
void set_##name(type value) { \
- StoreArrayPointer<Compressed##type, order>(&name##_, \
- Compressed##type(value)); \
+ StoreCompressedArrayPointer<type, Compressed##type, order>(&name##_, \
+ value); \
} \
\
protected: \
@@ -1015,7 +1010,6 @@
#if !defined(DART_PRECOMPILED_RUNTIME)
return reinterpret_cast<CompressedObjectPtr*>(&dependent_code_);
#endif
- case Snapshot::kMessage:
case Snapshot::kNone:
case Snapshot::kInvalid:
break;
@@ -1062,7 +1056,7 @@
friend class UntaggedInstance;
friend class UntaggedInstructions;
friend class UntaggedTypeArguments;
- friend class SnapshotReader;
+ friend class MessageSerializer;
friend class InstanceSerializationCluster;
friend class TypeSerializationCluster;
friend class CidRewriteVisitor;
@@ -1088,7 +1082,6 @@
case Snapshot::kFullCore:
case Snapshot::kFullJIT:
return reinterpret_cast<CompressedObjectPtr*>(&library_kernel_data_);
- case Snapshot::kMessage:
case Snapshot::kNone:
case Snapshot::kInvalid:
break;
@@ -1272,7 +1265,6 @@
case Snapshot::kFullCore:
case Snapshot::kFullJIT:
return reinterpret_cast<CompressedObjectPtr*>(&data_);
- case Snapshot::kMessage:
case Snapshot::kNone:
case Snapshot::kInvalid:
break;
@@ -1417,7 +1409,6 @@
case Snapshot::kFullJIT:
case Snapshot::kFullAOT:
return reinterpret_cast<CompressedObjectPtr*>(&initializer_function_);
- case Snapshot::kMessage:
case Snapshot::kNone:
case Snapshot::kInvalid:
break;
@@ -1491,7 +1482,6 @@
case Snapshot::kFullCore:
case Snapshot::kFullJIT:
return reinterpret_cast<CompressedObjectPtr*>(&kernel_program_info_);
- case Snapshot::kMessage:
case Snapshot::kNone:
case Snapshot::kInvalid:
break;
@@ -1583,7 +1573,6 @@
case Snapshot::kFullCore:
case Snapshot::kFullJIT:
return reinterpret_cast<CompressedObjectPtr*>(&kernel_data_);
- case Snapshot::kMessage:
case Snapshot::kNone:
case Snapshot::kInvalid:
break;
@@ -1636,7 +1625,6 @@
case Snapshot::kFullCore:
case Snapshot::kFullJIT:
return reinterpret_cast<CompressedObjectPtr*>(&owner_);
- case Snapshot::kMessage:
case Snapshot::kNone:
case Snapshot::kInvalid:
break;
@@ -2191,7 +2179,6 @@
VARIABLE_POINTER_FIELDS(ObjectPtr, element, data)
friend class Object;
- friend class SnapshotReader;
};
class UntaggedContextScope : public UntaggedObject {
@@ -2267,7 +2254,6 @@
friend class Object;
friend class UntaggedClosureData;
- friend class SnapshotReader;
};
class UntaggedSentinel : public UntaggedObject {
@@ -2333,7 +2319,6 @@
case Snapshot::kFullCore:
case Snapshot::kFullJIT:
return to();
- case Snapshot::kMessage:
case Snapshot::kNone:
case Snapshot::kInvalid:
break;
@@ -2428,7 +2413,6 @@
class UntaggedInstance : public UntaggedObject {
RAW_HEAP_OBJECT_IMPLEMENTATION(Instance);
friend class Object;
- friend class SnapshotReader;
public:
#if defined(DART_COMPRESSED_POINTERS)
@@ -2457,7 +2441,6 @@
case Snapshot::kFullCore:
case Snapshot::kFullJIT:
return reinterpret_cast<CompressedObjectPtr*>(&importer_);
- case Snapshot::kMessage:
case Snapshot::kNone:
case Snapshot::kInvalid:
break;
@@ -2484,7 +2467,6 @@
COMPRESSED_VARIABLE_POINTER_FIELDS(AbstractTypePtr, element, types)
friend class Object;
- friend class SnapshotReader;
};
class UntaggedTypeParameters : public UntaggedObject {
@@ -2503,7 +2485,6 @@
CompressedObjectPtr* to_snapshot(Snapshot::Kind kind) { return to(); }
friend class Object;
- friend class SnapshotReader;
};
class UntaggedAbstractType : public UntaggedInstance {
@@ -2715,7 +2696,6 @@
friend class Api;
friend class Class;
friend class Integer;
- friend class SnapshotReader;
};
COMPILE_ASSERT(sizeof(UntaggedMint) == 16);
@@ -2726,7 +2706,6 @@
ALIGN8 double value_;
friend class Api;
- friend class SnapshotReader;
friend class Class;
};
COMPILE_ASSERT(sizeof(UntaggedDouble) == 16);
@@ -2762,9 +2741,7 @@
uint8_t* data() { OPEN_ARRAY_START(uint8_t, uint8_t); }
const uint8_t* data() const { OPEN_ARRAY_START(uint8_t, uint8_t); }
- friend class ApiMessageReader;
friend class RODataSerializationCluster;
- friend class SnapshotReader;
friend class String;
};
@@ -2777,7 +2754,6 @@
const uint16_t* data() const { OPEN_ARRAY_START(uint16_t, uint16_t); }
friend class RODataSerializationCluster;
- friend class SnapshotReader;
friend class String;
};
@@ -2861,7 +2837,6 @@
friend class ObjectPoolDeserializationCluster;
friend class ObjectPoolSerializationCluster;
friend class UntaggedObjectPool;
- friend class SnapshotReader;
};
// All _*ArrayView/_ByteDataView classes share the same layout.
@@ -2925,7 +2900,6 @@
friend class GCCompactor;
template <bool>
friend class ScavengerVisitorBase;
- friend class SnapshotReader;
};
class UntaggedExternalOneByteString : public UntaggedString {
@@ -2971,7 +2945,6 @@
friend class Deserializer;
friend class UntaggedCode;
friend class UntaggedImmutableArray;
- friend class SnapshotReader;
friend class GrowableObjectArray;
friend class LinkedHashMap;
friend class UntaggedLinkedHashMap;
@@ -2988,8 +2961,6 @@
class UntaggedImmutableArray : public UntaggedArray {
RAW_HEAP_OBJECT_IMPLEMENTATION(ImmutableArray);
-
- friend class SnapshotReader;
};
class UntaggedGrowableObjectArray : public UntaggedInstance {
@@ -3002,7 +2973,6 @@
VISIT_TO(data)
CompressedObjectPtr* to_snapshot(Snapshot::Kind kind) { return to(); }
- friend class SnapshotReader;
friend class ReversePc;
};
@@ -3026,14 +2996,10 @@
class UntaggedLinkedHashMap : public UntaggedLinkedHashBase {
RAW_HEAP_OBJECT_IMPLEMENTATION(LinkedHashMap);
-
- friend class SnapshotReader;
};
class UntaggedLinkedHashSet : public UntaggedLinkedHashBase {
RAW_HEAP_OBJECT_IMPLEMENTATION(LinkedHashSet);
-
- friend class SnapshotReader;
};
class UntaggedFloat32x4 : public UntaggedInstance {
@@ -3042,7 +3008,6 @@
ALIGN8 float value_[4];
- friend class SnapshotReader;
friend class Class;
public:
@@ -3059,7 +3024,6 @@
ALIGN8 int32_t value_[4];
- friend class SnapshotReader;
public:
int32_t x() const { return value_[0]; }
@@ -3075,7 +3039,6 @@
ALIGN8 double value_[2];
- friend class SnapshotReader;
friend class Class;
public:
@@ -3264,7 +3227,6 @@
// Isolate unique tag.
uword tag_;
- friend class SnapshotReader;
friend class Object;
public:
@@ -3277,8 +3239,6 @@
COMPRESSED_POINTER_FIELD(TypeArgumentsPtr, type_arguments)
VISIT_FROM(type_arguments)
VISIT_TO(type_arguments)
-
- friend class SnapshotReader;
};
#undef WSR_COMPRESSED_POINTER_FIELD
diff --git a/runtime/vm/raw_object_snapshot.cc b/runtime/vm/raw_object_snapshot.cc
deleted file mode 100644
index 82f51c6..0000000
--- a/runtime/vm/raw_object_snapshot.cc
+++ /dev/null
@@ -1,1798 +0,0 @@
-// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-#include "vm/dart_api_state.h"
-#include "vm/message.h"
-#include "vm/native_entry.h"
-#include "vm/object.h"
-#include "vm/object_store.h"
-#include "vm/regexp.h"
-#include "vm/snapshot.h"
-#include "vm/stub_code.h"
-#include "vm/symbols.h"
-#include "vm/type_testing_stubs.h"
-#include "vm/visitor.h"
-
-namespace dart {
-
-// TODO(dartbug.com/34796): enable or remove this optimization.
-DEFINE_FLAG(
- uint64_t,
- externalize_typed_data_threshold,
- kMaxUint64,
- "Convert TypedData to ExternalTypedData when sending through a message"
- " port after it exceeds certain size in bytes.");
-
-#define OFFSET_OF_FROM(obj) \
- obj.ptr()->from() - reinterpret_cast<ObjectPtr*>(obj.ptr()->untag())
-
-#define READ_OBJECT_FIELDS(object, from, to, as_reference) \
- intptr_t num_flds = (to) - (from); \
- for (intptr_t i = 0; i <= num_flds; i++) { \
- (*reader->PassiveObjectHandle()) = reader->ReadObjectImpl(as_reference); \
- object.StorePointer(((from) + i), reader->PassiveObjectHandle()->ptr()); \
- }
-
-#define READ_COMPRESSED_OBJECT_FIELDS(object, from, to, as_reference) \
- intptr_t num_flds = (to) - (from); \
- for (intptr_t i = 0; i <= num_flds; i++) { \
- (*reader->PassiveObjectHandle()) = reader->ReadObjectImpl(as_reference); \
- object.StoreCompressedPointer(((from) + i), \
- reader->PassiveObjectHandle()->ptr()); \
- }
-
-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());
- cls = reader->ReadClassId(object_id);
- return cls.ptr();
-}
-
-void UntaggedClass::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.
- writer->WriteInlinedObjectHeader(object_id);
-
- // Write out the class and tags information.
- writer->WriteVMIsolateObject(kClassCid);
- writer->WriteTags(writer->GetObjectTags(this));
-
- if (writer->can_send_any_object() ||
- writer->AllowObjectsInDartLibrary(library())) {
- writer->WriteClassId(this);
- } else {
- // We do not allow regular dart instances in isolate messages.
- writer->SetWriteException(Exceptions::kArgument,
- "Illegal argument in isolate message"
- " : (object is a regular Dart Instance)");
- }
-}
-
-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.
- reader->Read<bool>();
-
- // Allocate type object.
- Type& type = Type::ZoneHandle(reader->zone(), Type::New());
- bool is_canonical = UntaggedObject::IsCanonical(tags);
- reader->AddBackRef(object_id, &type, kIsDeserialized);
-
- // Set all non object fields.
- const uint8_t combined = reader->Read<uint8_t>();
- type.set_type_state(combined >> 4);
- type.set_nullability(static_cast<Nullability>(combined & 0xf));
-
- // Read the code object for the type testing stub and set its entrypoint.
- reader->EnqueueTypePostprocessing(type);
-
- // Set all the object fields.
- READ_COMPRESSED_OBJECT_FIELDS(type, type.ptr()->untag()->from(),
- type.ptr()->untag()->to(), as_reference);
-
- // Read in the type class.
- (*reader->ClassHandle()) =
- Class::RawCast(reader->ReadObjectImpl(as_reference));
- type.set_type_class(*reader->ClassHandle());
-
- // Fill in the type testing stub.
- Code& code = *reader->CodeHandle();
- code = TypeTestingStubGenerator::DefaultCodeForType(type);
- type.InitializeTypeTestingStubNonAtomic(code);
-
- if (is_canonical) {
- type ^= type.Canonicalize(Thread::Current(), nullptr);
- }
-
- return type.ptr();
-}
-
-void UntaggedType::WriteTo(SnapshotWriter* writer,
- intptr_t object_id,
- Snapshot::Kind kind,
- bool as_reference) {
- ASSERT(writer != NULL);
-
- // Only resolved and finalized types should be written to a snapshot.
- ASSERT((type_state_ == UntaggedType::kFinalizedInstantiated) ||
- (type_state_ == UntaggedType::kFinalizedUninstantiated));
- ASSERT(type_class_id() != Object::null());
-
- // Write out the serialization header value for this object.
- writer->WriteInlinedObjectHeader(object_id);
-
- // Write out the class and tags information.
- writer->WriteIndexedObject(kTypeCid);
- writer->WriteTags(writer->GetObjectTags(this));
-
- if (type_class_id()->IsHeapObject()) {
- // Type class is still an unresolved class.
- UNREACHABLE();
- }
-
- // Lookup the type class.
- SmiPtr raw_type_class_id = Smi::RawCast(type_class_id());
- ClassPtr type_class =
- writer->isolate_group()->class_table()->At(Smi::Value(raw_type_class_id));
-
- // Write out typeclass_is_in_fullsnapshot first as this will
- // help the reader decide on how to canonicalize the type object.
- intptr_t tags = writer->GetObjectTags(type_class);
- bool typeclass_is_in_fullsnapshot =
- (ClassIdTag::decode(tags) == kClassCid) &&
- Class::IsInFullSnapshot(static_cast<ClassPtr>(type_class));
- writer->Write<bool>(typeclass_is_in_fullsnapshot);
-
- // Write out all the non object pointer fields.
- const uint8_t combined = (type_state_ << 4) | nullability_;
- ASSERT(type_state_ == (combined >> 4));
- ASSERT(nullability_ == (combined & 0xf));
- writer->Write<uint8_t>(combined);
-
- // Write out all the object pointer fields.
- ASSERT(type_class_id() != Object::null());
- SnapshotWriterVisitor visitor(writer, as_reference);
- visitor.VisitCompressedPointers(heap_base(), from(), to());
-
- // Write out the type class.
- writer->WriteObjectImpl(type_class, 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.
- TypeRef& type_ref = TypeRef::ZoneHandle(reader->zone(), TypeRef::New());
- reader->AddBackRef(object_id, &type_ref, kIsDeserialized);
-
- // Read the code object for the type testing stub and set its entrypoint.
- reader->EnqueueTypePostprocessing(type_ref);
-
- // Set all the object fields.
- READ_COMPRESSED_OBJECT_FIELDS(type_ref, type_ref.ptr()->untag()->from(),
- type_ref.ptr()->untag()->to(), kAsReference);
-
- // Fill in the type testing stub.
- Code& code = *reader->CodeHandle();
- code = TypeTestingStubGenerator::DefaultCodeForType(type_ref);
- type_ref.InitializeTypeTestingStubNonAtomic(code);
-
- return type_ref.ptr();
-}
-
-void UntaggedTypeRef::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.
- writer->WriteInlinedObjectHeader(object_id);
-
- // Write out the class and tags information.
- writer->WriteIndexedObject(kTypeRefCid);
- writer->WriteTags(writer->GetObjectTags(this));
-
- // Write out all the object pointer fields.
- SnapshotWriterVisitor visitor(writer, kAsReference);
- visitor.VisitCompressedPointers(heap_base(), from(), to());
-}
-
-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.
- TypeParameter& type_parameter =
- TypeParameter::ZoneHandle(reader->zone(), TypeParameter::New());
- bool is_canonical = UntaggedObject::IsCanonical(tags);
- reader->AddBackRef(object_id, &type_parameter, kIsDeserialized);
-
- // Set all non object fields.
- type_parameter.set_base(reader->Read<uint8_t>());
- type_parameter.set_index(reader->Read<uint8_t>());
- const uint8_t combined = reader->Read<uint8_t>();
- type_parameter.set_flags(combined >> 4);
- type_parameter.set_nullability(static_cast<Nullability>(combined & 0xf));
-
- // Read the code object for the type testing stub and set its entrypoint.
- reader->EnqueueTypePostprocessing(type_parameter);
-
- // Set all the object fields.
- READ_COMPRESSED_OBJECT_FIELDS(
- type_parameter, type_parameter.ptr()->untag()->from(),
- type_parameter.ptr()->untag()->to(), kAsReference);
-
- // Read in the parameterized class.
- (*reader->ClassHandle()) =
- Class::RawCast(reader->ReadObjectImpl(kAsReference));
- if (reader->ClassHandle()->id() == kFunctionCid) {
- (*reader->ClassHandle()) = Class::null();
- }
- type_parameter.set_parameterized_class(*reader->ClassHandle());
-
- // Fill in the type testing stub.
- Code& code = *reader->CodeHandle();
- code = TypeTestingStubGenerator::DefaultCodeForType(type_parameter);
- type_parameter.InitializeTypeTestingStubNonAtomic(code);
-
- if (is_canonical) {
- type_parameter ^= type_parameter.Canonicalize(Thread::Current(), nullptr);
- }
-
- return type_parameter.ptr();
-}
-
-void UntaggedTypeParameter::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.
- ASSERT(FinalizedBit::decode(flags_));
-
- // Write out the serialization header value for this object.
- writer->WriteInlinedObjectHeader(object_id);
-
- // Write out the class and tags information.
- writer->WriteIndexedObject(kTypeParameterCid);
- writer->WriteTags(writer->GetObjectTags(this));
-
- // Write out all the non object pointer fields.
- writer->Write<uint8_t>(base_);
- writer->Write<uint8_t>(index_);
- const uint8_t combined = (flags_ << 4) | nullability_;
- ASSERT(flags_ == (combined >> 4));
- ASSERT(nullability_ == (combined & 0xf));
- writer->Write<uint8_t>(combined);
-
- // Write out all the object pointer fields.
- SnapshotWriterVisitor visitor(writer, kAsReference);
- visitor.VisitCompressedPointers(heap_base(), from(), to());
-
- // Write out the parameterized class (or Function if cid == kFunctionCid).
- ClassPtr param_class =
- writer->isolate_group()->class_table()->At(parameterized_class_id_);
- writer->WriteObjectImpl(param_class, kAsReference);
-}
-
-TypeParametersPtr TypeParameters::ReadFrom(SnapshotReader* reader,
- intptr_t object_id,
- intptr_t tags,
- Snapshot::Kind kind,
- bool as_reference) {
- ASSERT(reader != NULL);
-
- TypeParameters& type_parameters =
- TypeParameters::ZoneHandle(reader->zone(), TypeParameters::New());
- reader->AddBackRef(object_id, &type_parameters, kIsDeserialized);
-
- // Set all the object fields.
- READ_COMPRESSED_OBJECT_FIELDS(
- type_parameters, type_parameters.ptr()->untag()->from(),
- type_parameters.ptr()->untag()->to(), kAsReference);
-
- return type_parameters.ptr();
-}
-
-void UntaggedTypeParameters::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.
- writer->WriteInlinedObjectHeader(object_id);
-
- // Write out the class and tags information.
- writer->WriteVMIsolateObject(kTypeParametersCid);
- writer->WriteTags(writer->GetObjectTags(this));
-
- // Write out all the object pointer fields.
- SnapshotWriterVisitor visitor(writer, kAsReference);
- visitor.VisitCompressedPointers(heap_base(), from(), to());
-}
-
-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.
- intptr_t len = reader->ReadSmiValue();
-
- TypeArguments& type_arguments =
- TypeArguments::ZoneHandle(reader->zone(), TypeArguments::New(len));
- bool is_canonical = UntaggedObject::IsCanonical(tags);
- reader->AddBackRef(object_id, &type_arguments, kIsDeserialized);
-
- // Set the instantiations field, which is only read from a full snapshot.
- type_arguments.set_instantiations(Object::zero_array());
-
- // Now set all the type fields.
- for (intptr_t i = 0; i < len; i++) {
- *reader->TypeHandle() ^= reader->ReadObjectImpl(as_reference);
- type_arguments.SetTypeAt(i, *reader->TypeHandle());
- }
-
- // Set the canonical bit.
- if (is_canonical) {
- type_arguments = type_arguments.Canonicalize(Thread::Current(), nullptr);
- }
-
- return type_arguments.ptr();
-}
-
-void UntaggedTypeArguments::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.
- writer->WriteInlinedObjectHeader(object_id);
-
- // Write out the class and tags information.
- writer->WriteVMIsolateObject(kTypeArgumentsCid);
- writer->WriteTags(writer->GetObjectTags(this));
-
- // Write out the length field.
- writer->Write<ObjectPtr>(length());
-
- // Write out the individual types.
- intptr_t len = Smi::Value(length());
- for (intptr_t i = 0; i < len; i++) {
- // The Dart VM reuses type argument lists across instances in order
- // to reduce memory footprint, this can sometimes lead to a type from
- // such a shared type argument list being sent over to another isolate.
- // In such scenarios where it is not appropriate to send the types
- // across (isolates spawned using spawnURI) we send them as dynamic.
- if (!writer->can_send_any_object()) {
- // Lookup the type class.
- TypePtr raw_type = Type::RawCast(element(i));
- SmiPtr raw_type_class_id =
- Smi::RawCast(raw_type->untag()->type_class_id());
- ClassPtr type_class = writer->isolate_group()->class_table()->At(
- Smi::Value(raw_type_class_id));
- if (!writer->AllowObjectsInDartLibrary(type_class->untag()->library())) {
- writer->WriteVMIsolateObject(kDynamicType);
- } else {
- writer->WriteObjectImpl(element(i), as_reference);
- }
- } else {
- writer->WriteObjectImpl(element(i), 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 UntaggedClosure::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.
- FunctionPtr func = writer->IsSerializableClosure(ClosurePtr(this));
- if (func != Function::null()) {
- writer->WriteStaticImplicitClosure(
- object_id, func, writer->GetObjectTags(this), delayed_type_arguments());
- return;
- }
-
- UNREACHABLE();
-}
-
-ContextPtr Context::ReadFrom(SnapshotReader* reader,
- intptr_t object_id,
- intptr_t tags,
- Snapshot::Kind kind,
- bool as_reference) {
- ASSERT(reader != NULL);
-
- // Allocate context object.
- int32_t num_vars = reader->Read<int32_t>();
- Context& context = Context::ZoneHandle(reader->zone());
- reader->AddBackRef(object_id, &context, kIsDeserialized);
- if (num_vars != 0) {
- context = Context::New(num_vars);
-
- // 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.ptr()->untag()->to(num_vars) - context.ptr()->untag()->from());
- for (intptr_t i = 0; i <= num_flds; i++) {
- (*reader->PassiveObjectHandle()) = reader->ReadObjectImpl(kAsReference);
- context.StorePointer((context.ptr()->untag()->from() + i),
- reader->PassiveObjectHandle()->ptr());
- }
- }
- return context.ptr();
-}
-
-void UntaggedContext::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.
- writer->WriteInlinedObjectHeader(object_id);
-
- // Write out the class and tags information.
- writer->WriteVMIsolateObject(kContextCid);
- writer->WriteTags(writer->GetObjectTags(this));
-
- // Write out num of variables in the context.
- const int32_t num_variables = num_variables_;
- writer->Write<int32_t>(num_variables);
- if (num_variables != 0) {
- // Write out all the object pointer fields.
- SnapshotWriterVisitor visitor(writer, kAsReference);
- visitor.VisitPointers(from(), to(num_variables));
- }
-}
-
-ContextScopePtr ContextScope::ReadFrom(SnapshotReader* reader,
- intptr_t object_id,
- intptr_t tags,
- Snapshot::Kind kind,
- bool as_reference) {
- ASSERT(reader != NULL);
-
- // Allocate context object.
- bool is_implicit = reader->Read<bool>();
- if (is_implicit) {
- ContextScope& context_scope = ContextScope::ZoneHandle(reader->zone());
- context_scope = ContextScope::New(1, true);
- reader->AddBackRef(object_id, &context_scope, kIsDeserialized);
-
- *reader->TypeHandle() ^= reader->ReadObjectImpl(kAsInlinedObject);
-
- // Create a descriptor for 'this' variable.
- context_scope.SetTokenIndexAt(0, TokenPosition::kMinSource);
- context_scope.SetDeclarationTokenIndexAt(0, TokenPosition::kMinSource);
- context_scope.SetNameAt(0, Symbols::This());
- context_scope.SetIsFinalAt(0, true);
- context_scope.SetIsConstAt(0, false);
- context_scope.SetTypeAt(0, *reader->TypeHandle());
- context_scope.SetContextIndexAt(0, 0);
- context_scope.SetContextLevelAt(0, 0);
- return context_scope.ptr();
- }
- UNREACHABLE();
- return NULL;
-}
-
-void UntaggedContextScope::WriteTo(SnapshotWriter* writer,
- intptr_t object_id,
- Snapshot::Kind kind,
- bool as_reference) {
- ASSERT(writer != NULL);
-
- if (is_implicit_) {
- ASSERT(num_variables_ == 1);
- const VariableDesc* var = VariableDescAddr(0);
-
- // Write out the serialization header value for this object.
- writer->WriteInlinedObjectHeader(object_id);
-
- // Write out the class and tags information.
- writer->WriteVMIsolateObject(kContextScopeCid);
- writer->WriteTags(writer->GetObjectTags(this));
-
- // Write out is_implicit flag for the context scope.
- writer->Write<bool>(true);
-
- // Write out the type of 'this' the variable.
- writer->WriteObjectImpl(var->type.Decompress(heap_base()),
- kAsInlinedObject);
-
- return;
- }
- UNREACHABLE();
-}
-
-#define MESSAGE_SNAPSHOT_UNREACHABLE(type) \
- type##Ptr type::ReadFrom(SnapshotReader* reader, intptr_t object_id, \
- intptr_t tags, Snapshot::Kind kind, \
- bool as_reference) { \
- UNREACHABLE(); \
- return type::null(); \
- } \
- void Untagged##type::WriteTo(SnapshotWriter* writer, intptr_t object_id, \
- Snapshot::Kind kind, bool as_reference) { \
- UNREACHABLE(); \
- }
-
-#define MESSAGE_SNAPSHOT_ILLEGAL(type) \
- type##Ptr type::ReadFrom(SnapshotReader* reader, intptr_t object_id, \
- intptr_t tags, Snapshot::Kind kind, \
- bool as_reference) { \
- UNREACHABLE(); \
- return type::null(); \
- } \
- void Untagged##type::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 ")"); \
- }
-
-MESSAGE_SNAPSHOT_UNREACHABLE(AbstractType);
-MESSAGE_SNAPSHOT_UNREACHABLE(Bool);
-MESSAGE_SNAPSHOT_UNREACHABLE(ClosureData);
-MESSAGE_SNAPSHOT_UNREACHABLE(Code);
-MESSAGE_SNAPSHOT_UNREACHABLE(CodeSourceMap);
-MESSAGE_SNAPSHOT_UNREACHABLE(CompressedStackMaps);
-MESSAGE_SNAPSHOT_UNREACHABLE(Error);
-MESSAGE_SNAPSHOT_UNREACHABLE(ExceptionHandlers);
-MESSAGE_SNAPSHOT_UNREACHABLE(FfiTrampolineData);
-MESSAGE_SNAPSHOT_UNREACHABLE(Field);
-MESSAGE_SNAPSHOT_UNREACHABLE(Function);
-MESSAGE_SNAPSHOT_UNREACHABLE(CallSiteData);
-MESSAGE_SNAPSHOT_UNREACHABLE(ICData);
-MESSAGE_SNAPSHOT_UNREACHABLE(Instructions);
-MESSAGE_SNAPSHOT_UNREACHABLE(InstructionsSection);
-MESSAGE_SNAPSHOT_UNREACHABLE(InstructionsTable);
-MESSAGE_SNAPSHOT_UNREACHABLE(KernelProgramInfo);
-MESSAGE_SNAPSHOT_UNREACHABLE(Library);
-MESSAGE_SNAPSHOT_UNREACHABLE(LibraryPrefix);
-MESSAGE_SNAPSHOT_UNREACHABLE(LocalVarDescriptors);
-MESSAGE_SNAPSHOT_UNREACHABLE(MegamorphicCache);
-MESSAGE_SNAPSHOT_UNREACHABLE(Namespace);
-MESSAGE_SNAPSHOT_UNREACHABLE(ObjectPool);
-MESSAGE_SNAPSHOT_UNREACHABLE(PatchClass);
-MESSAGE_SNAPSHOT_UNREACHABLE(PcDescriptors);
-MESSAGE_SNAPSHOT_UNREACHABLE(Script);
-MESSAGE_SNAPSHOT_UNREACHABLE(Sentinel);
-MESSAGE_SNAPSHOT_UNREACHABLE(SingleTargetCache);
-MESSAGE_SNAPSHOT_UNREACHABLE(String);
-MESSAGE_SNAPSHOT_UNREACHABLE(SubtypeTestCache);
-MESSAGE_SNAPSHOT_UNREACHABLE(LoadingUnit);
-MESSAGE_SNAPSHOT_UNREACHABLE(TypedDataBase);
-MESSAGE_SNAPSHOT_UNREACHABLE(UnlinkedCall);
-MESSAGE_SNAPSHOT_UNREACHABLE(MonomorphicSmiableCall);
-MESSAGE_SNAPSHOT_UNREACHABLE(UnwindError);
-MESSAGE_SNAPSHOT_UNREACHABLE(FutureOr);
-MESSAGE_SNAPSHOT_UNREACHABLE(WeakSerializationReference);
-
-MESSAGE_SNAPSHOT_ILLEGAL(FunctionType)
-MESSAGE_SNAPSHOT_ILLEGAL(DynamicLibrary);
-MESSAGE_SNAPSHOT_ILLEGAL(MirrorReference);
-MESSAGE_SNAPSHOT_ILLEGAL(Pointer);
-MESSAGE_SNAPSHOT_ILLEGAL(ReceivePort);
-MESSAGE_SNAPSHOT_ILLEGAL(StackTrace);
-MESSAGE_SNAPSHOT_ILLEGAL(UserTag);
-
-ApiErrorPtr ApiError::ReadFrom(SnapshotReader* reader,
- intptr_t object_id,
- intptr_t tags,
- Snapshot::Kind kind,
- bool as_reference) {
- ASSERT(reader != NULL);
-
- // Allocate ApiError object.
- ApiError& api_error = ApiError::ZoneHandle(reader->zone(), ApiError::New());
- reader->AddBackRef(object_id, &api_error, kIsDeserialized);
-
- // Set all the object fields.
- READ_COMPRESSED_OBJECT_FIELDS(api_error, api_error.ptr()->untag()->from(),
- api_error.ptr()->untag()->to(), kAsReference);
-
- return api_error.ptr();
-}
-
-void UntaggedApiError::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.
- writer->WriteInlinedObjectHeader(object_id);
-
- // Write out the class and tags information.
- writer->WriteVMIsolateObject(kApiErrorCid);
- writer->WriteTags(writer->GetObjectTags(this));
-
- // Write out all the object pointer fields.
- SnapshotWriterVisitor visitor(writer, kAsReference);
- visitor.VisitCompressedPointers(heap_base(), from(), to());
-}
-
-LanguageErrorPtr LanguageError::ReadFrom(SnapshotReader* reader,
- intptr_t object_id,
- intptr_t tags,
- Snapshot::Kind kind,
- bool as_reference) {
- ASSERT(reader != NULL);
-
- // Allocate LanguageError object.
- LanguageError& language_error =
- LanguageError::ZoneHandle(reader->zone(), LanguageError::New());
- reader->AddBackRef(object_id, &language_error, kIsDeserialized);
-
- // Set all non object fields.
- language_error.set_token_pos(
- TokenPosition::Deserialize(reader->Read<int32_t>()));
- language_error.set_report_after_token(reader->Read<bool>());
- language_error.set_kind(reader->Read<uint8_t>());
-
- // Set all the object fields.
- READ_COMPRESSED_OBJECT_FIELDS(
- language_error, language_error.ptr()->untag()->from(),
- language_error.ptr()->untag()->to(), kAsReference);
-
- return language_error.ptr();
-}
-
-void UntaggedLanguageError::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.
- writer->WriteInlinedObjectHeader(object_id);
-
- // Write out the class and tags information.
- writer->WriteVMIsolateObject(kLanguageErrorCid);
- writer->WriteTags(writer->GetObjectTags(this));
-
- // Write out all the non object fields.
- writer->Write<int32_t>(token_pos_.Serialize());
- writer->Write<bool>(report_after_token_);
- writer->Write<uint8_t>(kind_);
-
- // Write out all the object pointer fields.
- SnapshotWriterVisitor visitor(writer, kAsReference);
- visitor.VisitCompressedPointers(heap_base(), from(), to());
-}
-
-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_COMPRESSED_OBJECT_FIELDS(result, result.ptr()->untag()->from(),
- result.ptr()->untag()->to(), kAsReference);
-
- return result.ptr();
-}
-
-void UntaggedUnhandledException::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);
-
- // Write out the class and tags information.
- writer->WriteVMIsolateObject(kUnhandledExceptionCid);
- writer->WriteTags(writer->GetObjectTags(this));
- // Write out all the object pointer fields.
- SnapshotWriterVisitor visitor(writer, kAsReference);
- visitor.VisitCompressedPointers(heap_base(), from(), to());
-}
-
-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,
- Instance::ContainsCompressedPointers());
- if (UntaggedObject::IsCanonical(tags)) {
- obj = obj.Canonicalize(reader->thread());
- }
- reader->AddBackRef(object_id, &obj, kIsDeserialized);
-
- return obj.ptr();
-}
-
-void UntaggedInstance::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.
- writer->WriteInlinedObjectHeader(object_id);
-
- // Write out the class and tags information.
- writer->WriteIndexedObject(kInstanceCid);
- writer->WriteTags(writer->GetObjectTags(this));
-}
-
-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.
- int64_t value = reader->Read<int64_t>();
-
- // Check if the value could potentially fit in a Smi in our current
- // architecture, if so return the object as a Smi.
- if (Smi::IsValid(value)) {
- Smi& smi =
- Smi::ZoneHandle(reader->zone(), Smi::New(static_cast<intptr_t>(value)));
- reader->AddBackRef(object_id, &smi, kIsDeserialized);
- return smi.ptr();
- }
-
- // Create a Mint object or get canonical one if it is a canonical constant.
- Mint& mint = Mint::ZoneHandle(reader->zone(), Mint::null());
- // When reading a script snapshot we need to canonicalize only those object
- // 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.
- // When reading a message snapshot we always have to canonicalize.
- if (UntaggedObject::IsCanonical(tags)) {
- mint = Mint::NewCanonical(value);
- ASSERT(mint.IsCanonical());
- } else {
- mint = Mint::New(value);
- }
- reader->AddBackRef(object_id, &mint, kIsDeserialized);
- return mint.ptr();
-}
-
-void UntaggedMint::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.
- writer->WriteInlinedObjectHeader(object_id);
-
- // Write out the class and tags information.
- writer->WriteIndexedObject(kMintCid);
- writer->WriteTags(writer->GetObjectTags(this));
-
- // Write out the 64 bit value.
- writer->Write<int64_t>(value_);
-}
-
-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.
- double value = reader->ReadDouble();
-
- // Create a Double object or get canonical one if it is a canonical constant.
- Double& dbl = Double::ZoneHandle(reader->zone(), Double::null());
- // When reading a script snapshot we need to canonicalize only those object
- // 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 (UntaggedObject::IsCanonical(tags)) {
- dbl = Double::NewCanonical(value);
- ASSERT(dbl.IsCanonical());
- } else {
- dbl = Double::New(value);
- }
- reader->AddBackRef(object_id, &dbl, kIsDeserialized);
- return dbl.ptr();
-}
-
-void UntaggedDouble::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.
- writer->WriteInlinedObjectHeader(object_id);
-
- // Write out the class and tags information.
- writer->WriteIndexedObject(kDoubleCid);
- writer->WriteTags(writer->GetObjectTags(this));
-
- // Write out the double value.
- writer->WriteDouble(value_);
-}
-
-template <typename StringType, typename CharacterType, typename CallbackType>
-void String::ReadFromImpl(SnapshotReader* reader,
- String* str_obj,
- intptr_t len,
- intptr_t tags,
- CallbackType new_symbol,
- Snapshot::Kind kind) {
- ASSERT(reader != NULL);
- if (UntaggedObject::IsCanonical(tags)) {
- // Set up canonical string object.
- ASSERT(reader != NULL);
- CharacterType* ptr = reader->zone()->Alloc<CharacterType>(len);
- for (intptr_t i = 0; i < len; i++) {
- ptr[i] = reader->Read<CharacterType>();
- }
- *str_obj = (*new_symbol)(reader->thread(), ptr, len);
- } else {
- // Set up the string object.
- *str_obj = StringType::New(len, Heap::kNew);
- str_obj->SetHash(0); // Will get computed when needed.
- if (len == 0) {
- return;
- }
- NoSafepointScope no_safepoint;
- CharacterType* str_addr = StringType::DataStart(*str_obj);
- for (intptr_t i = 0; i < len; i++) {
- *str_addr = reader->Read<CharacterType>();
- str_addr++;
- }
- }
-}
-
-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();
- String& str_obj = String::ZoneHandle(reader->zone(), String::null());
-
- String::ReadFromImpl<OneByteString, uint8_t>(reader, &str_obj, len, tags,
- Symbols::FromLatin1, kind);
- reader->AddBackRef(object_id, &str_obj, kIsDeserialized);
- return raw(str_obj);
-}
-
-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();
- String& str_obj = String::ZoneHandle(reader->zone(), String::null());
-
- String::ReadFromImpl<TwoByteString, uint16_t>(reader, &str_obj, len, tags,
- Symbols::FromUTF16, kind);
- reader->AddBackRef(object_id, &str_obj, kIsDeserialized);
- return raw(str_obj);
-}
-
-template <typename T>
-static void StringWriteTo(SnapshotWriter* writer,
- intptr_t object_id,
- Snapshot::Kind kind,
- intptr_t class_id,
- intptr_t tags,
- SmiPtr length,
- T* data) {
- ASSERT(writer != NULL);
- intptr_t len = Smi::Value(length);
-
- // Write out the serialization header value for this object.
- writer->WriteInlinedObjectHeader(object_id);
-
- // Write out the class and tags information.
- writer->WriteIndexedObject(class_id);
- writer->WriteTags(tags);
-
- // Write out the length field.
- writer->Write<ObjectPtr>(length);
-
- // Write out the string.
- if (len > 0) {
- if (class_id == kOneByteStringCid) {
- writer->WriteBytes(reinterpret_cast<const uint8_t*>(data), len);
- } else {
- for (intptr_t i = 0; i < len; i++) {
- writer->Write(data[i]);
- }
- }
- }
-}
-
-void UntaggedOneByteString::WriteTo(SnapshotWriter* writer,
- intptr_t object_id,
- Snapshot::Kind kind,
- bool as_reference) {
- StringWriteTo(writer, object_id, kind, kOneByteStringCid,
- writer->GetObjectTags(this), length(), data());
-}
-
-void UntaggedTwoByteString::WriteTo(SnapshotWriter* writer,
- intptr_t object_id,
- Snapshot::Kind kind,
- bool as_reference) {
- StringWriteTo(writer, object_id, kind, kTwoByteStringCid,
- writer->GetObjectTags(this), length(), data());
-}
-
-ExternalOneByteStringPtr ExternalOneByteString::ReadFrom(SnapshotReader* reader,
- intptr_t object_id,
- intptr_t tags,
- Snapshot::Kind kind,
- bool as_reference) {
- UNREACHABLE();
- return ExternalOneByteString::null();
-}
-
-ExternalTwoByteStringPtr ExternalTwoByteString::ReadFrom(SnapshotReader* reader,
- intptr_t object_id,
- intptr_t tags,
- Snapshot::Kind kind,
- bool as_reference) {
- UNREACHABLE();
- return ExternalTwoByteString::null();
-}
-
-void UntaggedExternalOneByteString::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), length(), external_data_);
-}
-
-void UntaggedExternalTwoByteString::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), length(), external_data_);
-}
-
-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.
- intptr_t len = reader->ReadSmiValue();
- Array* array = NULL;
- DeserializeState state;
- if (!as_reference) {
- array = reinterpret_cast<Array*>(reader->GetBackRef(object_id));
- state = kIsDeserialized;
- } else {
- state = kIsNotDeserialized;
- }
- if (array == NULL) {
- array = &(Array::ZoneHandle(reader->zone(), Array::New(len)));
- reader->AddBackRef(object_id, array, state);
- }
- if (!as_reference) {
- // Read all the individual elements for inlined objects.
- ASSERT(!UntaggedObject::IsCanonical(tags));
- reader->ArrayReadFrom(object_id, *array, len, tags);
- }
- return array->ptr();
-}
-
-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.
- intptr_t len = reader->ReadSmiValue();
- Array* array = NULL;
- DeserializeState state;
- if (!as_reference) {
- array = reinterpret_cast<Array*>(reader->GetBackRef(object_id));
- state = kIsDeserialized;
- } else {
- state = kIsNotDeserialized;
- }
- if (array == NULL) {
- array = &(Array::ZoneHandle(reader->zone(), ImmutableArray::New(len)));
- reader->AddBackRef(object_id, array, state);
- }
- if (!as_reference) {
- // Read all the individual elements for inlined objects.
- reader->ArrayReadFrom(object_id, *array, len, tags);
- if (UntaggedObject::IsCanonical(tags)) {
- *array ^= array->Canonicalize(reader->thread());
- }
- }
- return raw(*array);
-}
-
-void UntaggedArray::WriteTo(SnapshotWriter* writer,
- intptr_t object_id,
- Snapshot::Kind kind,
- bool as_reference) {
- ASSERT(!this->IsCanonical());
- writer->ArrayWriteTo(object_id, kArrayCid, writer->GetObjectTags(this),
- length(), type_arguments(), data(), as_reference);
-}
-
-void UntaggedImmutableArray::WriteTo(SnapshotWriter* writer,
- intptr_t object_id,
- Snapshot::Kind kind,
- bool as_reference) {
- writer->ArrayWriteTo(object_id, kImmutableArrayCid,
- writer->GetObjectTags(this), length(), type_arguments(),
- data(), 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.
- GrowableObjectArray& array = GrowableObjectArray::ZoneHandle(
- reader->zone(), GrowableObjectArray::null());
- array = GrowableObjectArray::New(0);
- reader->AddBackRef(object_id, &array, kIsDeserialized);
-
- // Read type arguments of growable array object.
- *reader->TypeArgumentsHandle() ^= reader->ReadObjectImpl(kAsInlinedObject);
- array.StoreCompressedPointer(&array.untag()->type_arguments_,
- reader->TypeArgumentsHandle()->ptr());
-
- // Read length of growable array object.
- array.SetLength(reader->ReadSmiValue());
-
- // Read the backing array of growable array object.
- *(reader->ArrayHandle()) ^= reader->ReadObjectImpl(kAsReference);
- array.SetData(*(reader->ArrayHandle()));
-
- return array.ptr();
-}
-
-void UntaggedGrowableObjectArray::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.
- writer->WriteInlinedObjectHeader(object_id);
-
- // Write out the class and tags information.
- writer->WriteIndexedObject(kGrowableObjectArrayCid);
- writer->WriteTags(writer->GetObjectTags(this));
-
- // Write out the type arguments field.
- writer->WriteObjectImpl(type_arguments(), kAsInlinedObject);
-
- // Write out the used length field.
- writer->Write<ObjectPtr>(length());
-
- // Write out the Array object.
- writer->WriteObjectImpl(data(), kAsReference);
-}
-
-LinkedHashMapPtr LinkedHashMap::ReadFrom(SnapshotReader* reader,
- intptr_t object_id,
- intptr_t tags,
- Snapshot::Kind kind,
- bool as_reference) {
- ASSERT(reader != NULL);
-
- LinkedHashMap& map =
- LinkedHashMap::ZoneHandle(reader->zone(), LinkedHashMap::null());
- // Since the map might contain itself as a key or value, allocate first.
- map = LinkedHashMap::NewUninitialized();
- reader->AddBackRef(object_id, &map, kIsDeserialized);
-
- reader->MapReadFrom(object_id, map, tags);
-
- return map.ptr();
-}
-
-void UntaggedLinkedHashMap::WriteTo(SnapshotWriter* writer,
- intptr_t object_id,
- Snapshot::Kind kind,
- bool as_reference) {
- ASSERT(writer != NULL);
- ASSERT(!this->IsCanonical());
- writer->MapWriteTo(object_id, kLinkedHashMapCid, writer->GetObjectTags(this),
- type_arguments(), used_data(), deleted_keys(), data(),
- as_reference);
-}
-
-LinkedHashSetPtr LinkedHashSet::ReadFrom(SnapshotReader* reader,
- intptr_t object_id,
- intptr_t tags,
- Snapshot::Kind kind,
- bool as_reference) {
- ASSERT(reader != NULL);
-
- LinkedHashSet& set =
- LinkedHashSet::ZoneHandle(reader->zone(), LinkedHashSet::null());
- // Since the set might contain itself as a key or value, allocate first.
- set = LinkedHashSet::NewUninitialized();
- reader->AddBackRef(object_id, &set, kIsDeserialized);
-
- reader->SetReadFrom(object_id, set, tags);
-
- return set.ptr();
-}
-
-void UntaggedLinkedHashSet::WriteTo(SnapshotWriter* writer,
- intptr_t object_id,
- Snapshot::Kind kind,
- bool as_reference) {
- ASSERT(writer != NULL);
- ASSERT(!this->IsCanonical());
- writer->SetWriteTo(object_id, kLinkedHashSetCid, writer->GetObjectTags(this),
- type_arguments(), used_data(), deleted_keys(), data(),
- 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>();
- float value1 = reader->Read<float>();
- float value2 = reader->Read<float>();
- float value3 = reader->Read<float>();
-
- // Create a Float32x4 object.
- Float32x4& simd = Float32x4::ZoneHandle(reader->zone(), Float32x4::null());
- simd = Float32x4::New(value0, value1, value2, value3);
- reader->AddBackRef(object_id, &simd, kIsDeserialized);
- return simd.ptr();
-}
-
-void UntaggedFloat32x4::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.
- writer->WriteInlinedObjectHeader(object_id);
-
- // Write out the class and tags information.
- writer->WriteIndexedObject(kFloat32x4Cid);
- writer->WriteTags(writer->GetObjectTags(this));
-
- // Write out the float values.
- writer->Write<float>(value_[0]);
- writer->Write<float>(value_[1]);
- writer->Write<float>(value_[2]);
- writer->Write<float>(value_[3]);
-}
-
-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>();
- uint32_t value1 = reader->Read<uint32_t>();
- uint32_t value2 = reader->Read<uint32_t>();
- uint32_t value3 = reader->Read<uint32_t>();
-
- // Create a Float32x4 object.
- Int32x4& simd = Int32x4::ZoneHandle(reader->zone(), Int32x4::null());
- simd = Int32x4::New(value0, value1, value2, value3);
- reader->AddBackRef(object_id, &simd, kIsDeserialized);
- return simd.ptr();
-}
-
-void UntaggedInt32x4::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.
- writer->WriteInlinedObjectHeader(object_id);
-
- // Write out the class and tags information.
- writer->WriteIndexedObject(kInt32x4Cid);
- writer->WriteTags(writer->GetObjectTags(this));
-
- // Write out the mask values.
- writer->Write<uint32_t>(value_[0]);
- writer->Write<uint32_t>(value_[1]);
- writer->Write<uint32_t>(value_[2]);
- writer->Write<uint32_t>(value_[3]);
-}
-
-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>();
- double value1 = reader->Read<double>();
-
- // Create a Float64x2 object.
- Float64x2& simd = Float64x2::ZoneHandle(reader->zone(), Float64x2::null());
- simd = Float64x2::New(value0, value1);
- reader->AddBackRef(object_id, &simd, kIsDeserialized);
- return simd.ptr();
-}
-
-void UntaggedFloat64x2::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.
- writer->WriteInlinedObjectHeader(object_id);
-
- // Write out the class and tags information.
- writer->WriteIndexedObject(kFloat64x2Cid);
- writer->WriteTags(writer->GetObjectTags(this));
-
- // Write out the float values.
- writer->Write<double>(value_[0]);
- writer->Write<double>(value_[1]);
-}
-
-TypedDataPtr TypedData::ReadFrom(SnapshotReader* reader,
- intptr_t object_id,
- intptr_t tags,
- Snapshot::Kind kind,
- bool as_reference) {
- ASSERT(reader != NULL);
-
- intptr_t cid = UntaggedObject::ClassIdTag::decode(tags);
- intptr_t len = reader->ReadSmiValue();
- TypedData& result =
- TypedData::ZoneHandle(reader->zone(), TypedData::New(cid, len));
- reader->AddBackRef(object_id, &result, kIsDeserialized);
-
- // Setup the array elements.
- intptr_t element_size = ElementSizeInBytes(cid);
- intptr_t length_in_bytes = len * element_size;
- NoSafepointScope no_safepoint;
- uint8_t* data = reinterpret_cast<uint8_t*>(result.DataAddr(0));
- reader->Align(Zone::kAlignment);
- reader->ReadBytes(data, length_in_bytes);
-
- // If it is a canonical constant make it one.
- // When reading a full snapshot we don't need to canonicalize the object
- // 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 (UntaggedObject::IsCanonical(tags)) {
- result ^= result.Canonicalize(reader->thread());
- ASSERT(!result.IsNull());
- ASSERT(result.IsCanonical());
- }
- return result.ptr();
-}
-
-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 = UntaggedObject::ClassIdTag::decode(tags);
- intptr_t length = reader->ReadSmiValue();
-
- FinalizableData finalizable_data =
- static_cast<MessageSnapshotReader*>(reader)->finalizable_data()->Take();
- uint8_t* data = reinterpret_cast<uint8_t*>(finalizable_data.data);
- ExternalTypedData& obj =
- ExternalTypedData::ZoneHandle(ExternalTypedData::New(cid, data, length));
- reader->AddBackRef(object_id, &obj, kIsDeserialized);
- intptr_t external_size = obj.LengthInBytes();
- obj.AddFinalizer(finalizable_data.peer, finalizable_data.callback,
- external_size);
- return obj.ptr();
-}
-
-// This function's name can appear in Observatory.
-static void IsolateMessageTypedDataFinalizer(void* isolate_callback_data,
- void* buffer) {
- free(buffer);
-}
-
-void UntaggedTypedData::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(this->length()); // In elements.
- intptr_t external_cid;
- intptr_t bytes;
- switch (cid) {
- case kTypedDataInt8ArrayCid:
- external_cid = kExternalTypedDataInt8ArrayCid;
- bytes = length * sizeof(int8_t);
- break;
- case kTypedDataUint8ArrayCid:
- external_cid = kExternalTypedDataUint8ArrayCid;
- bytes = length * sizeof(uint8_t);
- break;
- case kTypedDataUint8ClampedArrayCid:
- external_cid = kExternalTypedDataUint8ClampedArrayCid;
- bytes = length * sizeof(uint8_t);
- break;
- case kTypedDataInt16ArrayCid:
- external_cid = kExternalTypedDataInt16ArrayCid;
- bytes = length * sizeof(int16_t);
- break;
- case kTypedDataUint16ArrayCid:
- external_cid = kExternalTypedDataUint16ArrayCid;
- bytes = length * sizeof(uint16_t);
- break;
- case kTypedDataInt32ArrayCid:
- external_cid = kExternalTypedDataInt32ArrayCid;
- bytes = length * sizeof(int32_t);
- break;
- case kTypedDataUint32ArrayCid:
- external_cid = kExternalTypedDataUint32ArrayCid;
- bytes = length * sizeof(uint32_t);
- break;
- case kTypedDataInt64ArrayCid:
- external_cid = kExternalTypedDataInt64ArrayCid;
- bytes = length * sizeof(int64_t);
- break;
- case kTypedDataUint64ArrayCid:
- external_cid = kExternalTypedDataUint64ArrayCid;
- bytes = length * sizeof(uint64_t);
- break;
- case kTypedDataFloat32ArrayCid:
- external_cid = kExternalTypedDataFloat32ArrayCid;
- bytes = length * sizeof(float);
- break;
- case kTypedDataFloat64ArrayCid:
- external_cid = kExternalTypedDataFloat64ArrayCid;
- bytes = length * sizeof(double);
- break;
- case kTypedDataInt32x4ArrayCid:
- external_cid = kExternalTypedDataInt32x4ArrayCid;
- bytes = length * sizeof(int32_t) * 4;
- break;
- case kTypedDataFloat32x4ArrayCid:
- external_cid = kExternalTypedDataFloat32x4ArrayCid;
- bytes = length * sizeof(float) * 4;
- break;
- case kTypedDataFloat64x2ArrayCid:
- external_cid = kExternalTypedDataFloat64x2ArrayCid;
- bytes = length * sizeof(double) * 2;
- break;
- default:
- external_cid = kIllegalCid;
- bytes = 0;
- UNREACHABLE();
- }
-
- // Write out the serialization header value for this object.
- writer->WriteInlinedObjectHeader(object_id);
-
- if ((kind == Snapshot::kMessage) &&
- (static_cast<uint64_t>(bytes) >= FLAG_externalize_typed_data_threshold)) {
- // Write as external.
- writer->WriteIndexedObject(external_cid);
- writer->WriteTags(writer->GetObjectTags(this));
- writer->Write<ObjectPtr>(this->length());
- uint8_t* data = reinterpret_cast<uint8_t*>(this->data());
- void* passed_data = malloc(bytes);
- memmove(passed_data, data, bytes);
- static_cast<MessageWriter*>(writer)->finalizable_data()->Put(
- bytes,
- passed_data, // data
- passed_data, // peer,
- IsolateMessageTypedDataFinalizer);
- } else {
- // Write as internal.
- writer->WriteIndexedObject(cid);
- writer->WriteTags(writer->GetObjectTags(this));
- writer->Write<ObjectPtr>(this->length());
- uint8_t* data = reinterpret_cast<uint8_t*>(this->data());
- writer->Align(Zone::kAlignment);
- writer->WriteBytes(data, bytes);
- }
-}
-
-void UntaggedExternalTypedData::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(this->length()); // In elements.
- intptr_t bytes;
- switch (cid) {
- case kExternalTypedDataInt8ArrayCid:
- bytes = length * sizeof(int8_t);
- break;
- case kExternalTypedDataUint8ArrayCid:
- bytes = length * sizeof(uint8_t);
- break;
- case kExternalTypedDataUint8ClampedArrayCid:
- bytes = length * sizeof(uint8_t);
- break;
- case kExternalTypedDataInt16ArrayCid:
- bytes = length * sizeof(int16_t);
- break;
- case kExternalTypedDataUint16ArrayCid:
- bytes = length * sizeof(uint16_t);
- break;
- case kExternalTypedDataInt32ArrayCid:
- bytes = length * sizeof(int32_t);
- break;
- case kExternalTypedDataUint32ArrayCid:
- bytes = length * sizeof(uint32_t);
- break;
- case kExternalTypedDataInt64ArrayCid:
- bytes = length * sizeof(int64_t);
- break;
- case kExternalTypedDataUint64ArrayCid:
- bytes = length * sizeof(uint64_t);
- break;
- case kExternalTypedDataFloat32ArrayCid:
- bytes = length * sizeof(float); // NOLINT.
- break;
- case kExternalTypedDataFloat64ArrayCid:
- bytes = length * sizeof(double); // NOLINT.
- break;
- case kExternalTypedDataInt32x4ArrayCid:
- bytes = length * sizeof(int32_t) * 4;
- break;
- case kExternalTypedDataFloat32x4ArrayCid:
- bytes = length * sizeof(float) * 4;
- break;
- case kExternalTypedDataFloat64x2ArrayCid:
- bytes = length * sizeof(double) * 2;
- break;
- default:
- bytes = 0;
- UNREACHABLE();
- }
-
- // Write out the serialization header value for this object.
- writer->WriteInlinedObjectHeader(object_id);
-
- // Write as external.
- writer->WriteIndexedObject(cid);
- writer->WriteTags(writer->GetObjectTags(this));
- writer->Write<ObjectPtr>(this->length());
- uint8_t* data = reinterpret_cast<uint8_t*>(data_);
- void* passed_data = malloc(bytes);
- memmove(passed_data, data, bytes);
- static_cast<MessageWriter*>(writer)->finalizable_data()->Put(
- bytes,
- passed_data, // data
- passed_data, // peer,
- IsolateMessageTypedDataFinalizer);
-}
-
-void UntaggedTypedDataView::WriteTo(SnapshotWriter* writer,
- intptr_t object_id,
- Snapshot::Kind kind,
- bool as_reference) {
- // Views have always a backing store.
- ASSERT(typed_data() != Object::null());
-
- // Write out the serialization header value for this object.
- writer->WriteInlinedObjectHeader(object_id);
-
- // Write out the class and tags information.
- writer->WriteIndexedObject(GetClassId());
- writer->WriteTags(writer->GetObjectTags(this));
-
- // Write members.
- writer->Write<ObjectPtr>(offset_in_bytes());
- writer->Write<ObjectPtr>(length());
- writer->WriteObjectImpl(typed_data(), 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 = UntaggedObject::ClassIdTag::decode(tags);
-
- auto& view = *reader->TypedDataViewHandle();
- view = TypedDataView::New(cid);
- reader->AddBackRef(object_id, &view, kIsDeserialized);
-
- const intptr_t offset_in_bytes = reader->ReadSmiValue();
- const intptr_t length = reader->ReadSmiValue();
- typed_data ^= reader->ReadObjectImpl(as_reference);
- view.InitializeWith(typed_data, offset_in_bytes, length);
-
- return view.ptr();
-}
-
-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 =
- Capability::ZoneHandle(reader->zone(), Capability::New(id));
- reader->AddBackRef(object_id, &result, kIsDeserialized);
- return result.ptr();
-}
-
-void UntaggedCapability::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);
-
- // Write out the class and tags information.
- writer->WriteIndexedObject(kCapabilityCid);
- writer->WriteTags(writer->GetObjectTags(this));
-
- writer->Write<uint64_t>(id_);
-}
-
-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>();
- uint64_t origin_id = reader->Read<uint64_t>();
-
- SendPort& result =
- SendPort::ZoneHandle(reader->zone(), SendPort::New(id, origin_id));
- reader->AddBackRef(object_id, &result, kIsDeserialized);
- return result.ptr();
-}
-
-void UntaggedSendPort::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);
-
- // Write out the class and tags information.
- writer->WriteIndexedObject(kSendPortCid);
- writer->WriteTags(writer->GetObjectTags(this));
-
- writer->Write<uint64_t>(id_);
- writer->Write<uint64_t>(origin_id_);
-}
-
-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));
- const intptr_t length = reader->Read<int64_t>();
-
- const FinalizableData finalizable_data =
- static_cast<MessageSnapshotReader*>(reader)->finalizable_data()->Take();
- uint8_t* data = reinterpret_cast<uint8_t*>(finalizable_data.data);
- auto& transferableTypedData = TransferableTypedData::ZoneHandle(
- reader->zone(), TransferableTypedData::New(data, length));
- reader->AddBackRef(object_id, &transferableTypedData, kIsDeserialized);
- return transferableTypedData.ptr();
-}
-
-void UntaggedTransferableTypedData::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(ObjectPtr(this));
- // Assume that object's Peer is only used to track transferrability state.
- ASSERT(peer != nullptr);
- TransferableTypedDataPeer* tpeer =
- reinterpret_cast<TransferableTypedDataPeer*>(peer);
- intptr_t length = tpeer->length(); // In bytes.
- void* data = tpeer->data();
- if (data == nullptr) {
- writer->SetWriteException(
- Exceptions::kArgument,
- "Illegal argument in isolate message"
- " : (TransferableTypedData has been transferred already)");
- return;
- }
-
- // Write out the serialization header value for this object.
- writer->WriteInlinedObjectHeader(object_id);
-
- writer->WriteIndexedObject(GetClassId());
- writer->WriteTags(writer->GetObjectTags(this));
- writer->Write<int64_t>(length);
-
- static_cast<MessageWriter*>(writer)->finalizable_data()->Put(
- length, data, tpeer,
- // Finalizer does nothing - in case of failure to serialize,
- // [data] remains wrapped in sender's [TransferableTypedData].
- [](void* data, void* peer) {},
- // This is invoked on successful serialization of the message
- [](void* data, void* peer) {
- TransferableTypedDataPeer* tpeer =
- reinterpret_cast<TransferableTypedDataPeer*>(peer);
- tpeer->handle()->EnsureFreedExternal(IsolateGroup::Current());
- tpeer->ClearData();
- });
-}
-
-RegExpPtr RegExp::ReadFrom(SnapshotReader* reader,
- intptr_t object_id,
- intptr_t tags,
- Snapshot::Kind kind,
- bool as_reference) {
- ASSERT(reader != NULL);
- // Allocate RegExp object.
- RegExp& regex =
- RegExp::ZoneHandle(reader->zone(), RegExp::New(reader->zone()));
- reader->AddBackRef(object_id, ®ex, kIsDeserialized);
-
- // Read and Set all the other fields.
- *reader->ArrayHandle() ^= reader->ReadObjectImpl(kAsInlinedObject);
- regex.set_capture_name_map(*reader->ArrayHandle());
- *reader->StringHandle() ^= reader->ReadObjectImpl(kAsInlinedObject);
- regex.set_pattern(*reader->StringHandle());
-
- regex.StoreNonPointer(®ex.untag()->num_bracket_expressions_,
- reader->Read<int32_t>());
- regex.StoreNonPointer(®ex.untag()->num_one_byte_registers_,
- reader->Read<int32_t>());
- regex.StoreNonPointer(®ex.untag()->num_two_byte_registers_,
- reader->Read<int32_t>());
- regex.StoreNonPointer(®ex.untag()->type_flags_, reader->Read<int8_t>());
- return regex.ptr();
-}
-
-void UntaggedRegExp::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.
- writer->WriteInlinedObjectHeader(object_id);
-
- // Write out the class and tags information.
- writer->WriteIndexedObject(kRegExpCid);
- writer->WriteTags(writer->GetObjectTags(this));
-
- // Write out all the other fields.
- writer->WriteObjectImpl(capture_name_map(), kAsInlinedObject);
- writer->WriteObjectImpl(pattern(), kAsInlinedObject);
- writer->Write<int32_t>(num_bracket_expressions_);
- writer->Write<int32_t>(num_one_byte_registers_);
- writer->Write<int32_t>(num_two_byte_registers_);
- writer->Write<int8_t>(type_flags_);
-}
-
-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.
- WeakProperty& weak_property =
- WeakProperty::ZoneHandle(reader->zone(), WeakProperty::New());
- reader->AddBackRef(object_id, &weak_property, kIsDeserialized);
-
- // Set all the object fields.
- READ_COMPRESSED_OBJECT_FIELDS(
- weak_property, weak_property.ptr()->untag()->from(),
- weak_property.ptr()->untag()->to(), kAsReference);
-
- return weak_property.ptr();
-}
-
-void UntaggedWeakProperty::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.
- writer->WriteInlinedObjectHeader(object_id);
-
- // Write out the class and tags information.
- writer->WriteIndexedObject(kWeakPropertyCid);
- writer->WriteTags(writer->GetObjectTags(this));
-
- // Write out all the object pointer fields.
- SnapshotWriterVisitor visitor(writer, kAsReference);
- visitor.VisitCompressedPointers(heap_base(), from(), to());
-}
-
-} // namespace dart
diff --git a/runtime/vm/service.cc b/runtime/vm/service.cc
index 2decacb..b9552b5 100644
--- a/runtime/vm/service.cc
+++ b/runtime/vm/service.cc
@@ -30,6 +30,7 @@
#include "vm/malloc_hooks.h"
#include "vm/message.h"
#include "vm/message_handler.h"
+#include "vm/message_snapshot.h"
#include "vm/native_arguments.h"
#include "vm/native_entry.h"
#include "vm/native_symbol.h"
@@ -1018,9 +1019,9 @@
message.value.as_array.length = 2;
message.value.as_array.values = elements;
- ApiMessageWriter writer;
- std::unique_ptr<Message> msg = writer.WriteCMessage(
- &message, ServiceIsolate::Port(), Message::kNormalPriority);
+ std::unique_ptr<Message> msg =
+ WriteApiMessage(thread->zone(), &message, ServiceIsolate::Port(),
+ Message::kNormalPriority);
if (msg == nullptr) {
result = false;
} else {
@@ -1188,9 +1189,10 @@
json_cobj.value.as_string = const_cast<char*>(event->ToCString());
list_values[1] = &json_cobj;
- ApiMessageWriter writer;
- std::unique_ptr<Message> msg = writer.WriteCMessage(
- &list_cobj, ServiceIsolate::Port(), Message::kNormalPriority);
+ AllocOnlyStackZone zone;
+ std::unique_ptr<Message> msg =
+ WriteApiMessage(zone.GetZone(), &list_cobj, ServiceIsolate::Port(),
+ Message::kNormalPriority);
if (msg != nullptr) {
PortMap::PostMessage(std::move(msg));
}
@@ -2017,8 +2019,7 @@
if (message->IsRaw()) {
return message->raw_obj();
} else {
- MessageSnapshotReader reader(message, thread);
- return reader.ReadObject();
+ return ReadMessage(thread, message);
}
}
diff --git a/runtime/vm/service_isolate.cc b/runtime/vm/service_isolate.cc
index c243b02b..d840e7b 100644
--- a/runtime/vm/service_isolate.cc
+++ b/runtime/vm/service_isolate.cc
@@ -12,6 +12,7 @@
#include "vm/lockers.h"
#include "vm/message.h"
#include "vm/message_handler.h"
+#include "vm/message_snapshot.h"
#include "vm/native_arguments.h"
#include "vm/native_entry.h"
#include "vm/object.h"
@@ -91,9 +92,8 @@
sp, VM_SERVICE_SERVER_INFO_MESSAGE_ID, false /* ignored */,
Bool::Handle() /* ignored */));
ASSERT(!message.IsNull());
- MessageWriter writer(false);
- PortMap::PostMessage(
- writer.WriteMessage(message, port_, Message::kNormalPriority));
+ PortMap::PostMessage(WriteMessage(/* can_send_any_object */ false, message,
+ port_, Message::kNormalPriority));
}
void ServiceIsolate::ControlWebServer(const SendPort& sp,
@@ -102,9 +102,8 @@
const Array& message = Array::Handle(MakeServerControlMessage(
sp, VM_SERVICE_WEB_SERVER_CONTROL_MESSAGE_ID, enable, silenceOutput));
ASSERT(!message.IsNull());
- MessageWriter writer(false);
- PortMap::PostMessage(
- writer.WriteMessage(message, port_, Message::kNormalPriority));
+ PortMap::PostMessage(WriteMessage(/* can_send_any_object */ false, message,
+ port_, Message::kNormalPriority));
}
void ServiceIsolate::SetServerAddress(const char* address) {
@@ -223,14 +222,13 @@
const Array& list = Array::Handle(MakeServiceControlMessage(
Dart_GetMainPortId(), VM_SERVICE_ISOLATE_STARTUP_MESSAGE_ID, name));
ASSERT(!list.IsNull());
- MessageWriter writer(false);
if (FLAG_trace_service) {
OS::PrintErr(DART_VM_SERVICE_ISOLATE_NAME ": Isolate %s %" Pd64
" registered.\n",
name.ToCString(), Dart_GetMainPortId());
}
- return PortMap::PostMessage(
- writer.WriteMessage(list, port_, Message::kNormalPriority));
+ return PortMap::PostMessage(WriteMessage(
+ /* can_send_any_object */ false, list, port_, Message::kNormalPriority));
}
bool ServiceIsolate::SendIsolateShutdownMessage() {
@@ -249,14 +247,13 @@
const Array& list = Array::Handle(MakeServiceControlMessage(
Dart_GetMainPortId(), VM_SERVICE_ISOLATE_SHUTDOWN_MESSAGE_ID, name));
ASSERT(!list.IsNull());
- MessageWriter writer(false);
if (FLAG_trace_service) {
OS::PrintErr(DART_VM_SERVICE_ISOLATE_NAME ": Isolate %s %" Pd64
" deregistered.\n",
name.ToCString(), Dart_GetMainPortId());
}
- return PortMap::PostMessage(
- writer.WriteMessage(list, port_, Message::kNormalPriority));
+ return PortMap::PostMessage(WriteMessage(
+ /* can_send_any_object */ false, list, port_, Message::kNormalPriority));
}
void ServiceIsolate::SendServiceExitMessage() {
@@ -278,9 +275,9 @@
message.value.as_array.length = 1;
message.value.as_array.values = values;
- ApiMessageWriter writer;
- PortMap::PostMessage(
- writer.WriteCMessage(&message, port_, Message::kNormalPriority));
+ AllocOnlyStackZone zone;
+ PortMap::PostMessage(WriteApiMessage(zone.GetZone(), &message, port_,
+ Message::kNormalPriority));
}
void ServiceIsolate::SetServicePort(Dart_Port port) {
diff --git a/runtime/vm/service_test.cc b/runtime/vm/service_test.cc
index 7dec0a8..2800565 100644
--- a/runtime/vm/service_test.cc
+++ b/runtime/vm/service_test.cc
@@ -14,6 +14,7 @@
#include "vm/globals.h"
#include "vm/heap/safepoint.h"
#include "vm/message_handler.h"
+#include "vm/message_snapshot.h"
#include "vm/object_id_ring.h"
#include "vm/os.h"
#include "vm/port.h"
@@ -50,8 +51,7 @@
response_obj = message->raw_obj();
} else {
Thread* thread = Thread::Current();
- MessageSnapshotReader reader(message.get(), thread);
- response_obj = reader.ReadObject();
+ response_obj = ReadMessage(thread, message.get());
}
if (response_obj.IsString()) {
String& response = String::Handle();
diff --git a/runtime/vm/snapshot.cc b/runtime/vm/snapshot.cc
index ca45f4d..f9b3cdc 100644
--- a/runtime/vm/snapshot.cc
+++ b/runtime/vm/snapshot.cc
@@ -5,229 +5,10 @@
#include "vm/snapshot.h"
#include "platform/assert.h"
-#include "vm/bootstrap.h"
-#include "vm/class_finalizer.h"
#include "vm/dart.h"
-#include "vm/exceptions.h"
-#include "vm/heap/heap.h"
-#include "vm/longjump.h"
-#include "vm/message.h"
-#include "vm/object.h"
-#include "vm/object_store.h"
-#include "vm/snapshot_ids.h"
-#include "vm/stub_code.h"
-#include "vm/symbols.h"
-#include "vm/timeline.h"
-#include "vm/type_testing_stubs.h"
-#include "vm/version.h"
-
-// We currently only expect the Dart mutator to read snapshots.
-#define ASSERT_NO_SAFEPOINT_SCOPE() \
- isolate()->AssertCurrentThreadIsMutator(); \
- ASSERT(thread()->no_safepoint_scope_depth() != 0)
namespace dart {
-static const int kNumInitialReferences = 32;
-
-static bool IsSingletonClassId(intptr_t class_id) {
- // 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 <= kVoidCid));
-}
-
-static bool IsBootstrapedClassId(intptr_t class_id) {
- // Check if this is a class which is created during bootstrapping.
- return (class_id == kObjectCid ||
- (class_id >= kInstanceCid && class_id <= kUserTagCid) ||
- class_id == kArrayCid || class_id == kImmutableArrayCid ||
- class_id == kLinkedHashMapCid || class_id == kLinkedHashSetCid ||
- IsStringClassId(class_id) || IsTypedDataClassId(class_id) ||
- IsExternalTypedDataClassId(class_id) ||
- IsTypedDataViewClassId(class_id) || class_id == kNullCid ||
- class_id == kNeverCid || class_id == kTransferableTypedDataCid);
-}
-
-static bool IsObjectStoreTypeId(intptr_t index) {
- // Check if this is a type which is stored in the object store.
- static_assert(kFirstTypeArgumentsSnapshotId == kLastTypeSnapshotId + 1,
- "Type and type arguments snapshot ids should be adjacent");
- return index >= kFirstTypeSnapshotId && index <= kLastTypeArgumentsSnapshotId;
-}
-
-static bool IsSplitClassId(intptr_t class_id) {
- // Return whether this class is serialized in two steps: first a reference,
- // with sufficient information to allocate a correctly sized object, and then
- // later inline with complete contents.
- return class_id >= kNumPredefinedCids || class_id == kArrayCid ||
- class_id == kImmutableArrayCid || class_id == kObjectPoolCid ||
- IsImplicitFieldClassId(class_id);
-}
-
-static intptr_t ClassIdFromObjectId(intptr_t object_id) {
- ASSERT(object_id > kClassIdsOffset);
- intptr_t class_id = (object_id - kClassIdsOffset);
- return class_id;
-}
-
-static intptr_t ObjectIdFromClassId(intptr_t class_id) {
- ASSERT((class_id > kIllegalCid) && (class_id < kNumPredefinedCids));
- return (class_id + kClassIdsOffset);
-}
-
-static ObjectPtr GetType(ObjectStore* object_store, intptr_t index) {
- switch (index) {
- case kLegacyObjectType:
- return object_store->legacy_object_type();
- case kNullableObjectType:
- 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:
- return object_store->legacy_number_type();
- case kLegacySmiType:
- return object_store->legacy_smi_type();
- case kLegacyMintType:
- return object_store->legacy_mint_type();
- case kLegacyDoubleType:
- return object_store->legacy_double_type();
- case kLegacyIntType:
- return object_store->legacy_int_type();
- case kLegacyBoolType:
- return object_store->legacy_bool_type();
- case kLegacyStringType:
- return object_store->legacy_string_type();
- case kLegacyArrayType:
- return object_store->legacy_array_type();
- case kLegacyIntTypeArguments:
- return object_store->type_argument_legacy_int();
- case kLegacyDoubleTypeArguments:
- return object_store->type_argument_legacy_double();
- case kLegacyStringTypeArguments:
- return object_store->type_argument_legacy_string();
- case kLegacyStringDynamicTypeArguments:
- return object_store->type_argument_legacy_string_dynamic();
- case kLegacyStringLegacyStringTypeArguments:
- return object_store->type_argument_legacy_string_legacy_string();
- case kNonNullableObjectType:
- return object_store->non_nullable_object_type();
- case kNonNullableFunctionType:
- return object_store->non_nullable_function_type();
- case kNonNullableNumberType:
- return object_store->non_nullable_number_type();
- case kNonNullableSmiType:
- return object_store->non_nullable_smi_type();
- case kNonNullableMintType:
- return object_store->non_nullable_mint_type();
- case kNonNullableDoubleType:
- return object_store->non_nullable_double_type();
- case kNonNullableIntType:
- return object_store->non_nullable_int_type();
- case kNonNullableBoolType:
- return object_store->non_nullable_bool_type();
- case kNonNullableStringType:
- return object_store->non_nullable_string_type();
- case kNonNullableArrayType:
- return object_store->non_nullable_array_type();
- case kNonNullableIntTypeArguments:
- return object_store->type_argument_non_nullable_int();
- case kNonNullableDoubleTypeArguments:
- return object_store->type_argument_non_nullable_double();
- case kNonNullableStringTypeArguments:
- return object_store->type_argument_non_nullable_string();
- case kNonNullableStringDynamicTypeArguments:
- return object_store->type_argument_non_nullable_string_dynamic();
- case kNonNullableStringNonNullableStringTypeArguments:
- return object_store
- ->type_argument_non_nullable_string_non_nullable_string();
- default:
- break;
- }
- UNREACHABLE();
- return Type::null();
-}
-
-static intptr_t GetTypeIndex(ObjectStore* object_store,
- const ObjectPtr raw_type) {
- if (raw_type == object_store->legacy_object_type()) {
- return kLegacyObjectType;
- } else if (raw_type == object_store->nullable_object_type()) {
- return kNullableObjectType;
- } 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()) {
- return kLegacyNumberType;
- } else if (raw_type == object_store->legacy_smi_type()) {
- return kLegacySmiType;
- } else if (raw_type == object_store->legacy_mint_type()) {
- return kLegacyMintType;
- } else if (raw_type == object_store->legacy_double_type()) {
- return kLegacyDoubleType;
- } else if (raw_type == object_store->legacy_int_type()) {
- return kLegacyIntType;
- } else if (raw_type == object_store->legacy_bool_type()) {
- return kLegacyBoolType;
- } else if (raw_type == object_store->legacy_string_type()) {
- return kLegacyStringType;
- } else if (raw_type == object_store->legacy_array_type()) {
- return kLegacyArrayType;
- } else if (raw_type == object_store->type_argument_legacy_int()) {
- return kLegacyIntTypeArguments;
- } else if (raw_type == object_store->type_argument_legacy_double()) {
- return kLegacyDoubleTypeArguments;
- } else if (raw_type == object_store->type_argument_legacy_string()) {
- return kLegacyStringTypeArguments;
- } else if (raw_type == object_store->type_argument_legacy_string_dynamic()) {
- return kLegacyStringDynamicTypeArguments;
- } else if (raw_type ==
- object_store->type_argument_legacy_string_legacy_string()) {
- return kLegacyStringLegacyStringTypeArguments;
- } else if (raw_type == object_store->non_nullable_object_type()) {
- return kNonNullableObjectType;
- } else if (raw_type == object_store->non_nullable_function_type()) {
- return kNonNullableFunctionType;
- } else if (raw_type == object_store->non_nullable_number_type()) {
- return kNonNullableNumberType;
- } else if (raw_type == object_store->non_nullable_smi_type()) {
- return kNonNullableSmiType;
- } else if (raw_type == object_store->non_nullable_mint_type()) {
- return kNonNullableMintType;
- } else if (raw_type == object_store->non_nullable_double_type()) {
- return kNonNullableDoubleType;
- } else if (raw_type == object_store->non_nullable_int_type()) {
- return kNonNullableIntType;
- } else if (raw_type == object_store->non_nullable_bool_type()) {
- return kNonNullableBoolType;
- } else if (raw_type == object_store->non_nullable_string_type()) {
- return kNonNullableStringType;
- } else if (raw_type == object_store->non_nullable_array_type()) {
- return kNonNullableArrayType;
- } else if (raw_type == object_store->type_argument_non_nullable_int()) {
- return kNonNullableIntTypeArguments;
- } else if (raw_type == object_store->type_argument_non_nullable_double()) {
- return kNonNullableDoubleTypeArguments;
- } else if (raw_type == object_store->type_argument_non_nullable_string()) {
- return kNonNullableStringTypeArguments;
- } else if (raw_type ==
- object_store->type_argument_non_nullable_string_dynamic()) {
- return kNonNullableStringDynamicTypeArguments;
- } else if (raw_type ==
- object_store
- ->type_argument_non_nullable_string_non_nullable_string()) {
- return kNonNullableStringNonNullableStringTypeArguments;
- }
- return kInvalidIndex;
-}
-
const char* Snapshot::KindToCString(Kind kind) {
switch (kind) {
case kFull:
@@ -238,8 +19,6 @@
return "full-jit";
case kFullAOT:
return "full-aot";
- case kMessage:
- return "message";
case kNone:
return "none";
case kInvalid:
@@ -263,97 +42,7 @@
return snapshot;
}
-SmiPtr BaseReader::ReadAsSmi() {
- SmiPtr value = static_cast<SmiPtr>(Read<intptr_t>());
- ASSERT((static_cast<uword>(value) & kSmiTagMask) == kSmiTag);
- return value;
-}
-
-intptr_t BaseReader::ReadSmiValue() {
- return Smi::Value(ReadAsSmi());
-}
-
-SnapshotReader::SnapshotReader(const uint8_t* buffer,
- intptr_t size,
- Snapshot::Kind kind,
- ZoneGrowableArray<BackRefNode>* backward_refs,
- Thread* thread)
- : BaseReader(buffer, size),
- kind_(kind),
- thread_(thread),
- zone_(thread->zone()),
- heap_(isolate_group()->heap()),
- old_space_(isolate_group()->heap()->old_space()),
- cls_(Class::Handle(zone_)),
- code_(Code::Handle(zone_)),
- instance_(Instance::Handle(zone_)),
- instructions_(Instructions::Handle(zone_)),
- obj_(Object::Handle(zone_)),
- pobj_(PassiveObject::Handle(zone_)),
- array_(Array::Handle(zone_)),
- field_(Field::Handle(zone_)),
- str_(String::Handle(zone_)),
- library_(Library::Handle(zone_)),
- type_(AbstractType::Handle(zone_)),
- type_arguments_(TypeArguments::Handle(zone_)),
- tokens_(GrowableObjectArray::Handle(zone_)),
- data_(ExternalTypedData::Handle(zone_)),
- typed_data_base_(TypedDataBase::Handle(zone_)),
- typed_data_(TypedData::Handle(zone_)),
- typed_data_view_(TypedDataView::Handle(zone_)),
- function_(Function::Handle(zone_)),
- smi_(Smi::Handle(zone_)),
- error_(UnhandledException::Handle(zone_)),
- set_class_(Class::ZoneHandle(
- zone_,
- thread_->isolate_group()->object_store()->linked_hash_set_class())),
- max_vm_isolate_object_id_(
- (Snapshot::IsFull(kind))
- ? Object::vm_isolate_snapshot_object_table().Length()
- : 0),
- backward_references_(backward_refs),
- types_to_postprocess_(GrowableObjectArray::Handle(zone_)),
- objects_to_rehash_(GrowableObjectArray::Handle(zone_)) {}
-
-ObjectPtr SnapshotReader::ReadObject() {
- // Setup for long jump in case there is an exception while reading.
- LongJumpScope jump;
- if (setjmp(*jump.Set()) == 0) {
- PassiveObject& obj =
- PassiveObject::Handle(zone(), ReadObjectImpl(kAsInlinedObject));
- for (intptr_t i = 0; i < backward_references_->length(); i++) {
- if (!(*backward_references_)[i].is_deserialized()) {
- ReadObjectImpl(kAsInlinedObject);
- (*backward_references_)[i].set_state(kIsDeserialized);
- }
- }
- Object& result = Object::Handle(zone_);
- if (backward_references_->length() > 0) {
- result = (*backward_references_)[0].reference()->ptr();
- } else {
- result = obj.ptr();
- }
- RunDelayedTypePostprocessing();
- const Object& ok =
- Object::Handle(zone_, RunDelayedRehashingOfMapsAndSets());
- objects_to_rehash_ = GrowableObjectArray::null();
- if (!ok.IsNull()) {
- return ok.ptr();
- }
- return result.ptr();
- } else {
- // An error occurred while reading, return the error object.
- return Thread::Current()->StealStickyError();
- }
-}
-
-void SnapshotReader::EnqueueTypePostprocessing(const AbstractType& type) {
- if (types_to_postprocess_.IsNull()) {
- types_to_postprocess_ = GrowableObjectArray::New();
- }
- types_to_postprocess_.Add(type);
-}
-
+#if 0
void SnapshotReader::RunDelayedTypePostprocessing() {
if (types_to_postprocess_.IsNull()) {
return;
@@ -367,1453 +56,6 @@
type.InitializeTypeTestingStubNonAtomic(code);
}
}
-
-void SnapshotReader::EnqueueRehashingOfMap(const LinkedHashMap& map) {
- ASSERT(!map.IsCanonical());
- if (objects_to_rehash_.IsNull()) {
- objects_to_rehash_ = GrowableObjectArray::New();
- }
- objects_to_rehash_.Add(map);
-}
-
-ObjectPtr SnapshotReader::RunDelayedRehashingOfMapsAndSets() {
- if (!objects_to_rehash_.IsNull()) {
- return DartLibraryCalls::RehashObjects(thread(), objects_to_rehash_);
- }
- return Object::null();
-}
-
-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>();
- ASSERT((class_header & kSmiTagMask) != kSmiTag);
- ASSERT(!IsVMIsolateObject(class_header) ||
- !IsSingletonClassId(GetVMIsolateObjectId(class_header)));
- ASSERT((SerializedHeaderTag::decode(class_header) != kObjectId) ||
- !IsBootstrapedClassId(SerializedHeaderData::decode(class_header)));
- Class& cls = Class::ZoneHandle(zone(), Class::null());
- AddBackRef(object_id, &cls, kIsDeserialized);
- // Read the library/class information and lookup the class.
- str_ ^= ReadObjectImpl(class_header, kAsInlinedObject);
- library_ = Library::LookupLibrary(thread(), str_);
- if (library_.IsNull() || !library_.Loaded()) {
- SetReadException(
- "Invalid object found in message: library is not found or loaded.");
- }
- str_ ^= ReadObjectImpl(kAsInlinedObject);
- if (str_.ptr() == Symbols::TopLevel().ptr()) {
- cls = library_.toplevel_class();
- } else {
- str_ = String::New(String::ScrubName(str_));
- cls = library_.LookupClassAllowPrivate(str_);
- }
- if (cls.IsNull()) {
- SetReadException("Invalid object found in message: class not found");
- }
- cls.EnsureIsFinalized(thread());
- return cls.ptr();
-}
-
-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
- // 'object_id'.
- Function& func = Function::Handle(zone(), Function::null());
- Instance& obj = Instance::ZoneHandle(zone(), Instance::null());
- AddBackRef(object_id, &obj, kIsDeserialized);
-
- // Read the library/class/function information and lookup the function.
- // Note: WriteStaticImplicitClosure is *not* scrubbing the names before
- // writing them into the snapshot, because scrubbing requires allocation.
- // This means that names we read here might be mangled with private
- // keys. These keys need to be scrubbed before performing lookups
- // otherwise lookups might fail.
- str_ ^= ReadObjectImpl(kAsInlinedObject);
- library_ = Library::LookupLibrary(thread(), str_);
- if (library_.IsNull() || !library_.Loaded()) {
- SetReadException("Invalid Library object found in message.");
- }
- str_ ^= ReadObjectImpl(kAsInlinedObject);
- if (str_.Equals(Symbols::TopLevel())) {
- str_ ^= ReadObjectImpl(kAsInlinedObject);
- str_ = String::New(String::ScrubName(str_));
- func = library_.LookupFunctionAllowPrivate(str_);
- } else {
- str_ = String::New(String::ScrubName(str_));
- cls_ = library_.LookupClassAllowPrivate(str_);
- if (cls_.IsNull()) {
- OS::PrintErr("Name of class not found %s\n", str_.ToCString());
- SetReadException("Invalid Class object found in message.");
- }
- cls_.EnsureIsFinalized(thread());
- str_ ^= ReadObjectImpl(kAsInlinedObject);
- str_ = String::New(String::ScrubName(str_));
- func = cls_.LookupFunctionAllowPrivate(str_);
- }
- if (func.IsNull()) {
- SetReadException("Invalid function object found in message.");
- }
- TypeArguments& delayed_type_arguments = TypeArguments::Handle(zone());
- delayed_type_arguments ^= ReadObjectImpl(kAsInlinedObject);
-
- func = func.ImplicitClosureFunction();
- ASSERT(!func.IsNull());
-
- // If delayedtype arguments were provided, create and return new closure with
- // those, otherwise return associated implicit static closure.
- // Note that static closures can't have instantiator or function types since
- // statics can't refer to class type arguments, don't have outer functions.
- if (!delayed_type_arguments.IsNull()) {
- const Context& context = Context::Handle(zone());
- obj = Closure::New(
- /*instantiator_type_arguments=*/Object::null_type_arguments(),
- /*function_type_arguments=*/Object::null_type_arguments(),
- delayed_type_arguments, func, context, Heap::kOld);
- } else {
- obj = func.ImplicitStaticClosure();
- }
- return obj.ptr();
-}
-
-intptr_t SnapshotReader::NextAvailableObjectId() const {
- return backward_references_->length() + kMaxPredefinedObjectIds +
- max_vm_isolate_object_id_;
-}
-
-void SnapshotReader::SetReadException(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());
- const Library& library = Library::Handle(zone(), Library::CoreLibrary());
- result = DartLibraryCalls::InstanceCreate(library, Symbols::ArgumentError(),
- Symbols::Dot(), args);
- const StackTrace& stacktrace = StackTrace::Handle(zone());
- const UnhandledException& error = UnhandledException::Handle(
- zone(), UnhandledException::New(Instance::Cast(result), stacktrace));
- thread()->long_jump_base()->Jump(1, error);
-}
-
-ObjectPtr SnapshotReader::VmIsolateSnapshotObject(intptr_t index) const {
- return Object::vm_isolate_snapshot_object_table().At(index);
-}
-
-bool SnapshotReader::is_vm_isolate() const {
- return isolate_group() == Dart::vm_isolate_group();
-}
-
-ObjectPtr SnapshotReader::ReadObjectImpl(bool as_reference) {
- int64_t header_value = Read<int64_t>();
- if ((header_value & kSmiTagMask) == kSmiTag) {
- return NewInteger(header_value);
- }
- ASSERT((header_value <= kIntptrMax) && (header_value >= kIntptrMin));
- return ReadObjectImpl(static_cast<intptr_t>(header_value), as_reference);
-}
-
-ObjectPtr SnapshotReader::ReadObjectImpl(intptr_t header_value,
- bool as_reference) {
- if (IsVMIsolateObject(header_value)) {
- return ReadVMIsolateObject(header_value);
- }
- if (SerializedHeaderTag::decode(header_value) == kObjectId) {
- return ReadIndexedObject(SerializedHeaderData::decode(header_value));
- }
- ASSERT(SerializedHeaderTag::decode(header_value) == kInlined);
- intptr_t object_id = SerializedHeaderData::decode(header_value);
- if (object_id == kOmittedObjectId) {
- object_id = NextAvailableObjectId();
- }
-
- // Read the class header information.
- intptr_t class_header = Read<int32_t>();
- intptr_t tags = ReadTags();
- bool read_as_reference = as_reference && !UntaggedObject::IsCanonical(tags);
- intptr_t header_id = SerializedHeaderData::decode(class_header);
- if (header_id == kInstanceObjectId) {
- return ReadInstance(object_id, tags, read_as_reference);
- } else if (header_id == kStaticImplicitClosureObjectId) {
- // We skip the tags that have been written as the implicit static
- // closure is going to be created in this isolate or the canonical
- // version already created in the isolate will be used.
- return ReadStaticImplicitClosure(object_id, class_header);
- }
- ASSERT((class_header & kSmiTagMask) != kSmiTag);
-
- intptr_t class_id = LookupInternalClass(class_header);
- switch (class_id) {
-#define SNAPSHOT_READ(clazz) \
- case clazz::kClassId: { \
- pobj_ = clazz::ReadFrom(this, object_id, tags, kind_, read_as_reference); \
- break; \
- }
- CLASS_LIST_NO_OBJECT(SNAPSHOT_READ)
-#undef SNAPSHOT_READ
-#define SNAPSHOT_READ(clazz) case kTypedData##clazz##Cid:
-
- CLASS_LIST_TYPED_DATA(SNAPSHOT_READ) {
- tags = UntaggedObject::ClassIdTag::update(class_id, tags);
- pobj_ =
- TypedData::ReadFrom(this, object_id, tags, kind_, read_as_reference);
- break;
- }
-#undef SNAPSHOT_READ
-#define SNAPSHOT_READ(clazz) case kExternalTypedData##clazz##Cid:
-
- CLASS_LIST_TYPED_DATA(SNAPSHOT_READ) {
- tags = UntaggedObject::ClassIdTag::update(class_id, tags);
- pobj_ = ExternalTypedData::ReadFrom(this, object_id, tags, kind_, true);
- break;
- }
-#undef SNAPSHOT_READ
-#define SNAPSHOT_READ(clazz) case kTypedData##clazz##ViewCid:
-
- case kByteDataViewCid:
- CLASS_LIST_TYPED_DATA(SNAPSHOT_READ) {
- tags = UntaggedObject::ClassIdTag::update(class_id, tags);
- pobj_ = TypedDataView::ReadFrom(this, object_id, tags, kind_, true);
- break;
- }
-#undef SNAPSHOT_READ
-#define SNAPSHOT_READ(clazz) case kFfi##clazz##Cid:
-
- CLASS_LIST_FFI(SNAPSHOT_READ) { UNREACHABLE(); }
-#undef SNAPSHOT_READ
- default:
- UNREACHABLE();
- break;
- }
- return pobj_.ptr();
-}
-
-void SnapshotReader::EnqueueRehashingOfSet(const LinkedHashSet& set) {
- ASSERT(!set.IsCanonical());
- if (objects_to_rehash_.IsNull()) {
- objects_to_rehash_ = GrowableObjectArray::New();
- }
- objects_to_rehash_.Add(set);
-}
-
-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;
- DeserializeState state;
- if (!as_reference) {
- result = reinterpret_cast<Instance*>(GetBackRef(object_id));
- state = kIsDeserialized;
- } else {
- state = kIsNotDeserialized;
- }
- if (result == NULL) {
- result = &(Instance::ZoneHandle(zone(), Instance::null()));
- AddBackRef(object_id, result, state);
- cls_ ^= ReadObjectImpl(kAsInlinedObject);
- ASSERT(!cls_.IsNull());
- // Closure instances are handled by Closure::ReadFrom().
- ASSERT(!cls_.IsClosureClass());
- instance_size = cls_.host_instance_size();
- ASSERT(instance_size > 0);
- // Allocate the instance and read in all the fields for the object.
- *result ^= Object::Allocate(cls_.id(), instance_size, Heap::kNew,
- Instance::ContainsCompressedPointers());
- } else {
- cls_ ^= ReadObjectImpl(kAsInlinedObject);
- ASSERT(!cls_.IsNull());
- instance_size = cls_.host_instance_size();
- }
- if (!as_reference) {
- // Read all the individual fields for inlined objects.
- intptr_t next_field_offset = cls_.host_next_field_offset();
-
- intptr_t type_argument_field_offset =
- cls_.host_type_arguments_field_offset();
- ASSERT(next_field_offset > 0);
- // Instance::NextFieldOffset() returns the offset of the first field in
- // a Dart object.
- bool read_as_reference = UntaggedObject::IsCanonical(tags) ? false : true;
- intptr_t offset = Instance::NextFieldOffset();
- intptr_t result_cid = result->GetClassId();
-
- const auto unboxed_fields =
- isolate_group()->shared_class_table()->GetUnboxedFieldsMapAt(
- result_cid);
-
- while (offset < next_field_offset) {
- if (unboxed_fields.Get(offset / kCompressedWordSize)) {
- compressed_uword* p = reinterpret_cast<compressed_uword*>(
- result->raw_value() - kHeapObjectTag + offset);
- // Reads 32 bits of the unboxed value at a time
- *p = ReadWordWith32BitReads();
- } else {
- pobj_ = ReadObjectImpl(read_as_reference);
- result->SetFieldAtOffset(offset, pobj_);
- if ((offset != type_argument_field_offset) &&
- (kind_ == Snapshot::kMessage) &&
- isolate_group()->use_field_guards() &&
- (pobj_.ptr() != Object::sentinel().ptr())) {
- // TODO(fschneider): Consider hoisting these lookups out of the loop.
- // This would involve creating a handle, since cls_ can't be reused
- // across the call to ReadObjectImpl.
- cls_ = isolate_group()->class_table()->At(result_cid);
- array_ = cls_.OffsetToFieldMap();
- field_ ^= array_.At(offset >> kCompressedWordSizeLog2);
- ASSERT(!field_.IsNull());
- ASSERT(field_.HostOffset() == offset);
- obj_ = pobj_.ptr();
- field_.RecordStore(obj_);
- }
- // TODO(fschneider): Verify the guarded cid and length for other kinds
- // of snapshot (kFull, kScript) with asserts.
- }
- offset += kCompressedWordSize;
- }
- if (UntaggedObject::IsCanonical(tags)) {
- *result = result->Canonicalize(thread());
- ASSERT(!result->IsNull());
- }
- }
- return result->ptr();
-}
-
-void SnapshotReader::AddBackRef(intptr_t id,
- Object* obj,
- DeserializeState state) {
- intptr_t index = (id - kMaxPredefinedObjectIds);
- ASSERT(index >= max_vm_isolate_object_id_);
- index -= max_vm_isolate_object_id_;
- ASSERT(index == backward_references_->length());
- BackRefNode node(obj, state);
- backward_references_->Add(node);
-}
-
-Object* SnapshotReader::GetBackRef(intptr_t id) {
- ASSERT(id >= kMaxPredefinedObjectIds);
- intptr_t index = (id - kMaxPredefinedObjectIds);
- ASSERT(index >= max_vm_isolate_object_id_);
- index -= max_vm_isolate_object_id_;
- if (index < backward_references_->length()) {
- return (*backward_references_)[index].reference();
- }
- return NULL;
-}
-
-ApiErrorPtr SnapshotReader::VerifyVersionAndFeatures(
- IsolateGroup* isolate_group) {
- // If the version string doesn't match, return an error.
- // Note: New things are allocated only if we're going to return an error.
-
- const char* expected_version = Version::SnapshotString();
- ASSERT(expected_version != NULL);
- const intptr_t version_len = strlen(expected_version);
- if (PendingBytes() < version_len) {
- const intptr_t kMessageBufferSize = 128;
- char message_buffer[kMessageBufferSize];
- Utils::SNPrint(message_buffer, kMessageBufferSize,
- "No full snapshot version found, expected '%s'",
- expected_version);
- // 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_buffer, Heap::kOld));
- return ApiError::New(msg, Heap::kOld);
- }
-
- const char* version = reinterpret_cast<const char*>(CurrentBufferAddress());
- ASSERT(version != NULL);
- if (strncmp(version, expected_version, version_len) != 0) {
- const intptr_t kMessageBufferSize = 256;
- char message_buffer[kMessageBufferSize];
- char* actual_version = Utils::StrNDup(version, version_len);
- Utils::SNPrint(message_buffer, kMessageBufferSize,
- "Wrong %s snapshot version, expected '%s' found '%s'",
- (Snapshot::IsFull(kind_)) ? "full" : "script",
- expected_version, actual_version);
- free(actual_version);
- // 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_buffer, Heap::kOld));
- return ApiError::New(msg, Heap::kOld);
- }
- Advance(version_len);
-
- const char* expected_features =
- Dart::FeaturesString(isolate_group, false, kind_);
- ASSERT(expected_features != NULL);
- const intptr_t expected_len = strlen(expected_features);
-
- const char* features = reinterpret_cast<const char*>(CurrentBufferAddress());
- ASSERT(features != NULL);
- intptr_t buffer_len = Utils::StrNLen(features, PendingBytes());
- if ((buffer_len != expected_len) ||
- (strncmp(features, expected_features, expected_len) != 0)) {
- const intptr_t kMessageBufferSize = 256;
- char message_buffer[kMessageBufferSize];
- char* actual_features =
- Utils::StrNDup(features, buffer_len < 128 ? buffer_len : 128);
- Utils::SNPrint(message_buffer, kMessageBufferSize,
- "Snapshot not compatible with the current VM configuration: "
- "the snapshot requires '%s' but the VM has '%s'",
- actual_features, expected_features);
- free(const_cast<char*>(expected_features));
- free(actual_features);
- // 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_buffer, Heap::kOld));
- return ApiError::New(msg, Heap::kOld);
- }
- free(const_cast<char*>(expected_features));
- Advance(expected_len + 1);
- return ApiError::null();
-}
-
-ObjectPtr SnapshotReader::NewInteger(int64_t value) {
- ASSERT((value & kSmiTagMask) == kSmiTag);
- value = value >> kSmiTagShift;
- if (Smi::IsValid(value)) {
- return Smi::New(static_cast<intptr_t>(value));
- }
- return Mint::NewCanonical(value);
-}
-
-intptr_t SnapshotReader::LookupInternalClass(intptr_t class_header) {
- // If the header is an object Id, lookup singleton VM classes or classes
- // stored in the object store.
- if (IsVMIsolateObject(class_header)) {
- intptr_t class_id = GetVMIsolateObjectId(class_header);
- ASSERT(IsSingletonClassId(class_id));
- return class_id;
- }
- ASSERT(SerializedHeaderTag::decode(class_header) == kObjectId);
- intptr_t class_id = SerializedHeaderData::decode(class_header);
- ASSERT(IsBootstrapedClassId(class_id) || IsSingletonClassId(class_id));
- return class_id;
-}
-
-#define READ_VM_SINGLETON_OBJ(id, obj) \
- if (object_id == id) { \
- return obj; \
- }
-
-ObjectPtr SnapshotReader::ReadVMIsolateObject(intptr_t header_value) {
- intptr_t object_id = GetVMIsolateObjectId(header_value);
-
- // First check if it is one of the singleton objects.
- READ_VM_SINGLETON_OBJ(kNullObject, Object::null());
- READ_VM_SINGLETON_OBJ(kSentinelObject, Object::sentinel().ptr());
- READ_VM_SINGLETON_OBJ(kTransitionSentinelObject,
- Object::transition_sentinel().ptr());
- READ_VM_SINGLETON_OBJ(kEmptyArrayObject, Object::empty_array().ptr());
- READ_VM_SINGLETON_OBJ(kZeroArrayObject, Object::zero_array().ptr());
- READ_VM_SINGLETON_OBJ(kDynamicType, Object::dynamic_type().ptr());
- READ_VM_SINGLETON_OBJ(kVoidType, Object::void_type().ptr());
- READ_VM_SINGLETON_OBJ(kEmptyTypeArguments,
- Object::empty_type_arguments().ptr());
- READ_VM_SINGLETON_OBJ(kTrueValue, Bool::True().ptr());
- READ_VM_SINGLETON_OBJ(kFalseValue, Bool::False().ptr());
- READ_VM_SINGLETON_OBJ(kExtractorParameterTypes,
- Object::extractor_parameter_types().ptr());
- READ_VM_SINGLETON_OBJ(kExtractorParameterNames,
- Object::extractor_parameter_names().ptr());
- READ_VM_SINGLETON_OBJ(kEmptyContextScopeObject,
- Object::empty_context_scope().ptr());
- READ_VM_SINGLETON_OBJ(kEmptyObjectPool, Object::empty_object_pool().ptr());
- READ_VM_SINGLETON_OBJ(kEmptyDescriptors, Object::empty_descriptors().ptr());
- READ_VM_SINGLETON_OBJ(kEmptyVarDescriptors,
- Object::empty_var_descriptors().ptr());
- READ_VM_SINGLETON_OBJ(kEmptyExceptionHandlers,
- Object::empty_exception_handlers().ptr());
-
- // Check if it is a double.
- if (object_id == kDoubleObject) {
- ASSERT(kind_ == Snapshot::kMessage);
- return Double::New(ReadDouble());
- }
-
- // Check it is a singleton class object.
- intptr_t class_id = ClassIdFromObjectId(object_id);
- if (IsSingletonClassId(class_id)) {
- return isolate_group()->class_table()->At(
- class_id); // get singleton class.
- }
-
- // Check if it is a singleton Argument descriptor object.
- for (intptr_t i = 0; i < ArgumentsDescriptor::kCachedDescriptorCount; i++) {
- if (object_id == (kCachedArgumentsDescriptor0 + i)) {
- return ArgumentsDescriptor::cached_args_descriptors_[i];
- }
- }
-
- // Check if it is a singleton ICData array object.
- for (intptr_t i = 0; i < ICData::kCachedICDataArrayCount; i++) {
- if (object_id == (kCachedICDataArray0 + i)) {
- return ICData::cached_icdata_arrays_[i];
- }
- }
-
- ASSERT(Symbols::IsPredefinedSymbolId(object_id));
- return Symbols::GetPredefinedSymbol(object_id); // return VM symbol.
-}
-
-ObjectPtr SnapshotReader::ReadIndexedObject(intptr_t object_id) {
- intptr_t class_id = ClassIdFromObjectId(object_id);
- if (IsBootstrapedClassId(class_id)) {
- return isolate_group()->class_table()->At(
- class_id); // get singleton class.
- }
- if (IsObjectStoreTypeId(object_id)) {
- return GetType(object_store(), object_id); // return type obj.
- }
- ASSERT(object_id >= kMaxPredefinedObjectIds);
- intptr_t index = (object_id - kMaxPredefinedObjectIds);
- if (index < max_vm_isolate_object_id_) {
- return VmIsolateSnapshotObject(index);
- }
- return GetBackRef(object_id)->ptr();
-}
-
-void SnapshotReader::ArrayReadFrom(intptr_t object_id,
- const Array& result,
- intptr_t len,
- intptr_t tags) {
- // Setup the object fields.
- *TypeArgumentsHandle() ^= ReadObjectImpl(kAsInlinedObject);
- result.SetTypeArguments(*TypeArgumentsHandle());
-
- bool as_reference = UntaggedObject::IsCanonical(tags) ? false : true;
- for (intptr_t i = 0; i < len; i++) {
- *PassiveObjectHandle() = ReadObjectImpl(as_reference);
- result.SetAt(i, *PassiveObjectHandle());
- }
-}
-
-void SnapshotReader::MapReadFrom(intptr_t object_id,
- const LinkedHashMap& map,
- intptr_t tags) {
- // Read the type arguments.
- *TypeArgumentsHandle() ^= ReadObjectImpl(kAsInlinedObject);
- map.SetTypeArguments(*TypeArgumentsHandle());
-
- // Read the number of key/value pairs.
- intptr_t len = ReadSmiValue();
- intptr_t used_data = (len << 1);
- map.SetUsedData(used_data);
-
- // Allocate the data array.
- intptr_t data_size =
- Utils::Maximum(Utils::RoundUpToPowerOfTwo(used_data),
- static_cast<uintptr_t>(LinkedHashMap::kInitialIndexSize));
- Array& data = Array::ZoneHandle(zone(), Array::New(data_size));
- map.SetData(data);
- map.SetDeletedKeys(0);
-
- // The index and hashMask is regenerated by the maps themselves on demand.
- // Thus, the index will probably be allocated in new space (unless it's huge).
- // TODO(koda): Eagerly rehash here when no keys have user-defined '==', and
- // in particular, if/when (const) maps are needed in the VM isolate snapshot.
- ASSERT(isolate_group() != Dart::vm_isolate_group());
- map.SetHashMask(0); // Prefer sentinel 0 over null for better type feedback.
-
- // Read the keys and values.
- bool read_as_reference = UntaggedObject::IsCanonical(tags) ? false : true;
- for (intptr_t i = 0; i < used_data; i++) {
- *PassiveObjectHandle() = ReadObjectImpl(read_as_reference);
- data.SetAt(i, *PassiveObjectHandle());
- }
-
- // TODO(http://dartbug.com/45908): Treat immutable, canonical maps.
- ASSERT(!UntaggedObject::IsCanonical(tags));
- // Can have user-defined hashCode for keys, compute in Dart.
- EnqueueRehashingOfMap(map);
-}
-
-void SnapshotReader::SetReadFrom(intptr_t object_id,
- const LinkedHashSet& set,
- intptr_t tags) {
- // Read the type arguments.
- *TypeArgumentsHandle() ^= ReadObjectImpl(kAsInlinedObject);
- set.SetTypeArguments(*TypeArgumentsHandle());
-
- intptr_t used_data = ReadSmiValue();
- set.SetUsedData(used_data);
-
- // Allocate the data array.
- intptr_t data_size =
- Utils::Maximum(Utils::RoundUpToPowerOfTwo(used_data),
- static_cast<uintptr_t>(LinkedHashSet::kInitialIndexSize));
- Array& data = Array::ZoneHandle(zone(), Array::New(data_size));
- set.SetData(data);
- set.SetDeletedKeys(0);
-
- // The index and hashMask is regenerated by the sets themselves on demand.
- // Thus, the index will probably be allocated in new space (unless it's huge).
- // TODO(koda): Eagerly rehash here when no keys have user-defined '==', and
- // in particular, if/when (const) sets are needed in the VM isolate snapshot.
- ASSERT(isolate_group() != Dart::vm_isolate_group());
- set.SetHashMask(0); // Prefer sentinel 0 over null for better type feedback.
-
- // Read the keys and values.
- bool read_as_reference = UntaggedObject::IsCanonical(tags) ? false : true;
- for (intptr_t i = 0; i < used_data; i++) {
- *PassiveObjectHandle() = ReadObjectImpl(read_as_reference);
- data.SetAt(i, *PassiveObjectHandle());
- }
-
- // TODO(http://dartbug.com/45908): Treat immutable, canonical sets.
- ASSERT(!UntaggedObject::IsCanonical(tags));
- // Can have user-defined hashCode for keys, compute in Dart.
- EnqueueRehashingOfSet(set);
-}
-
-MessageSnapshotReader::MessageSnapshotReader(Message* message, Thread* thread)
- : SnapshotReader(message->snapshot(),
- message->snapshot_length(),
- Snapshot::kMessage,
- new ZoneGrowableArray<BackRefNode>(kNumInitialReferences),
- thread),
- finalizable_data_(message->finalizable_data()) {}
-
-MessageSnapshotReader::~MessageSnapshotReader() {
- ResetBackwardReferenceTable();
-}
-
-SnapshotWriter::SnapshotWriter(Thread* thread,
- Snapshot::Kind kind,
- intptr_t initial_size,
- ForwardList* forward_list,
- bool can_send_any_object)
- : BaseWriter(initial_size),
- thread_(thread),
- kind_(kind),
- object_store_(isolate_group()->object_store()),
- class_table_(isolate_group()->class_table()),
- forward_list_(forward_list),
- exception_type_(Exceptions::kNone),
- exception_msg_(NULL),
- can_send_any_object_(can_send_any_object) {
- ASSERT(forward_list_ != NULL);
-}
-
-void SnapshotWriter::WriteObject(ObjectPtr rawobj) {
- WriteObjectImpl(rawobj, kAsInlinedObject);
- WriteForwardedObjects();
-}
-
-uint32_t SnapshotWriter::GetObjectTags(ObjectPtr raw) {
- uword tags = raw->untag()->tags_;
-#if defined(HASH_IN_OBJECT_HEADER)
- // Clear hash to make the narrowing cast safe / appease UBSAN.
- tags = UntaggedObject::HashTag::update(0, tags);
#endif
- return tags;
-}
-
-uint32_t SnapshotWriter::GetObjectTags(UntaggedObject* raw) {
- uword tags = raw->tags_;
-#if defined(HASH_IN_OBJECT_HEADER)
- // Clear hash to make the narrowing cast safe / appease UBSAN.
- tags = UntaggedObject::HashTag::update(0, tags);
-#endif
- return tags;
-}
-
-uword SnapshotWriter::GetObjectTagsAndHash(ObjectPtr raw) {
- return raw->untag()->tags_;
-}
-
-#define VM_OBJECT_CLASS_LIST(V) \
- V(OneByteString) \
- V(TwoByteString) \
- V(Mint) \
- V(Double) \
- V(ImmutableArray)
-
-#define VM_OBJECT_WRITE(clazz) \
- case clazz::kClassId: { \
- object_id = forward_list_->AddObject(zone(), rawobj, kIsSerialized); \
- clazz##Ptr raw_obj = static_cast<clazz##Ptr>(rawobj); \
- raw_obj->untag()->WriteTo(this, object_id, kind(), false); \
- return true; \
- }
-
-#define WRITE_VM_SINGLETON_OBJ(obj, id) \
- if (rawobj == obj) { \
- WriteVMIsolateObject(id); \
- return true; \
- }
-
-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().ptr(), kSentinelObject);
- WRITE_VM_SINGLETON_OBJ(Object::transition_sentinel().ptr(),
- kTransitionSentinelObject);
- WRITE_VM_SINGLETON_OBJ(Object::empty_array().ptr(), kEmptyArrayObject);
- WRITE_VM_SINGLETON_OBJ(Object::zero_array().ptr(), kZeroArrayObject);
- WRITE_VM_SINGLETON_OBJ(Object::dynamic_type().ptr(), kDynamicType);
- WRITE_VM_SINGLETON_OBJ(Object::void_type().ptr(), kVoidType);
- WRITE_VM_SINGLETON_OBJ(Object::empty_type_arguments().ptr(),
- kEmptyTypeArguments);
- WRITE_VM_SINGLETON_OBJ(Bool::True().ptr(), kTrueValue);
- WRITE_VM_SINGLETON_OBJ(Bool::False().ptr(), kFalseValue);
- WRITE_VM_SINGLETON_OBJ(Object::extractor_parameter_types().ptr(),
- kExtractorParameterTypes);
- WRITE_VM_SINGLETON_OBJ(Object::extractor_parameter_names().ptr(),
- kExtractorParameterNames);
- WRITE_VM_SINGLETON_OBJ(Object::empty_context_scope().ptr(),
- kEmptyContextScopeObject);
- WRITE_VM_SINGLETON_OBJ(Object::empty_object_pool().ptr(), kEmptyObjectPool);
- WRITE_VM_SINGLETON_OBJ(Object::empty_descriptors().ptr(), kEmptyDescriptors);
- WRITE_VM_SINGLETON_OBJ(Object::empty_var_descriptors().ptr(),
- kEmptyVarDescriptors);
- WRITE_VM_SINGLETON_OBJ(Object::empty_exception_handlers().ptr(),
- kEmptyExceptionHandlers);
-
- // Check if it is a singleton class object which is shared by
- // all isolates.
- intptr_t id = rawobj->GetClassId();
- if (id == kClassCid) {
- ClassPtr raw_class = static_cast<ClassPtr>(rawobj);
- intptr_t class_id = raw_class->untag()->id_;
- if (IsSingletonClassId(class_id)) {
- intptr_t object_id = ObjectIdFromClassId(class_id);
- WriteVMIsolateObject(object_id);
- return true;
- }
- }
-
- // Check if it is a singleton Argument descriptor object.
- for (intptr_t i = 0; i < ArgumentsDescriptor::kCachedDescriptorCount; i++) {
- if (rawobj == ArgumentsDescriptor::cached_args_descriptors_[i]) {
- WriteVMIsolateObject(kCachedArgumentsDescriptor0 + i);
- return true;
- }
- }
-
- // Check if it is a singleton ICData array object.
- for (intptr_t i = 0; i < ICData::kCachedICDataArrayCount; i++) {
- if (rawobj == ICData::cached_icdata_arrays_[i]) {
- WriteVMIsolateObject(kCachedICDataArray0 + i);
- return true;
- }
- }
-
- // In the case of script snapshots or for messages we do not use
- // the index into the vm isolate snapshot object table, instead we
- // explicitly write the object out.
- intptr_t object_id = forward_list_->FindObject(rawobj);
- if (object_id != -1) {
- WriteIndexedObject(object_id);
- return true;
- } else {
- // We do this check down here, because it's quite expensive.
- if (!rawobj->untag()->InVMIsolateHeap()) {
- return false;
- }
-
- switch (id) {
- VM_OBJECT_CLASS_LIST(VM_OBJECT_WRITE)
- case kTypedDataUint32ArrayCid: {
- object_id = forward_list_->AddObject(zone(), rawobj, kIsSerialized);
- TypedDataPtr raw_obj = static_cast<TypedDataPtr>(rawobj);
- raw_obj->untag()->WriteTo(this, object_id, kind(), false);
- return true;
- }
- default:
- OS::PrintErr("class id = %" Pd "\n", id);
- break;
- }
- }
-
- const Object& obj = Object::Handle(rawobj);
- FATAL1("Unexpected reference to object in VM isolate: %s\n", obj.ToCString());
- return false;
-}
-
-#undef VM_OBJECT_WRITE
-
-ForwardList::ForwardList(Thread* thread, intptr_t first_object_id)
- : thread_(thread),
- first_object_id_(first_object_id),
- nodes_(),
- first_unprocessed_object_id_(first_object_id) {
- ASSERT(first_object_id > 0);
- isolate()->set_forward_table_new(new WeakTable());
- isolate()->set_forward_table_old(new WeakTable());
-}
-
-ForwardList::~ForwardList() {
- isolate()->set_forward_table_new(nullptr);
- isolate()->set_forward_table_old(nullptr);
-}
-
-intptr_t ForwardList::AddObject(Zone* zone,
- ObjectPtr raw,
- SerializeState state) {
- NoSafepointScope no_safepoint;
- intptr_t object_id = next_object_id();
- ASSERT(object_id > 0 && object_id <= kMaxObjectId);
- const Object& obj = Object::ZoneHandle(zone, raw);
- Node* node = new Node(&obj, state);
- ASSERT(node != NULL);
- nodes_.Add(node);
- ASSERT(object_id != 0);
- SetObjectId(raw, object_id);
- return object_id;
-}
-
-intptr_t ForwardList::FindObject(ObjectPtr raw) {
- NoSafepointScope no_safepoint;
- intptr_t id = GetObjectId(raw);
- ASSERT(id == 0 || NodeForObjectId(id)->obj()->ptr() == raw);
- return (id == 0) ? static_cast<intptr_t>(kInvalidIndex) : id;
-}
-
-void ForwardList::SetObjectId(ObjectPtr object, intptr_t id) {
- if (object->IsNewObject()) {
- isolate()->forward_table_new()->SetValueExclusive(object, id);
- } else {
- isolate()->forward_table_old()->SetValueExclusive(object, id);
- }
-}
-
-intptr_t ForwardList::GetObjectId(ObjectPtr object) {
- if (object->IsNewObject()) {
- return isolate()->forward_table_new()->GetValueExclusive(object);
- } else {
- return isolate()->forward_table_old()->GetValueExclusive(object);
- }
-}
-
-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)
- // - Object that has already been written: (negative id in stream | 0x3)
-
- NoSafepointScope no_safepoint;
-
- // First check if it is a Smi (i.e not a heap object).
- if (!rawobj->IsHeapObject()) {
-#if !defined(DART_COMPRESSED_POINTERS)
- Write<int64_t>(static_cast<intptr_t>(rawobj));
-#else
- // One might expect this to be unnecessary because the reader will just
- // ignore the upper bits, but the upper bits affect the variable-length
- // encoding and can change lower bits in the variable-length reader.
- Write<int64_t>(static_cast<intptr_t>(rawobj) << 32 >> 32);
-#endif
- return true;
- }
-
- intptr_t cid = rawobj->GetClassId();
-
- if ((kind_ == Snapshot::kMessage) && (cid == kDoubleCid)) {
- WriteVMIsolateObject(kDoubleObject);
- DoublePtr rd = static_cast<DoublePtr>(rawobj);
- WriteDouble(rd->untag()->value_);
- return true;
- }
-
- // Check if object has already been serialized, in that case just write
- // the object id out.
- intptr_t object_id = forward_list_->FindObject(rawobj);
- if (object_id != kInvalidIndex) {
- WriteIndexedObject(object_id);
- return true;
- }
-
- // Check if it is a code object in that case just write a Null object
- // as we do not want code objects in the snapshot.
- if (cid == kCodeCid) {
- WriteVMIsolateObject(kNullObject);
- return true;
- }
-
- // Now check if it is an object from the VM isolate. These objects are shared
- // by all isolates.
- if (HandleVMIsolateObject(rawobj)) {
- return true;
- }
-
- // Check if classes are not being serialized and it is preinitialized type
- // 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) {
- ClassPtr raw_class = static_cast<ClassPtr>(rawobj);
- intptr_t class_id = raw_class->untag()->id_;
- if (IsBootstrapedClassId(class_id)) {
- intptr_t object_id = ObjectIdFromClassId(class_id);
- WriteIndexedObject(object_id);
- return true;
- }
- }
-
- // Now check it is a preinitialized type object.
- intptr_t index = GetTypeIndex(object_store(), rawobj);
- if (index != kInvalidIndex) {
- WriteIndexedObject(index);
- return true;
- }
-
- return false;
-}
-
-void SnapshotWriter::WriteObjectImpl(ObjectPtr raw, bool as_reference) {
- // First check if object can be written as a simple predefined type.
- if (CheckAndWritePredefinedObject(raw)) {
- return;
- }
-
- // 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->untag()->IsCanonical();
- uintptr_t tags = GetObjectTagsAndHash(raw);
-
- // Add object to the forward ref list and mark it so that future references
- // to this object in the snapshot will use this object id. Mark the
- // serialization state so that we do the right thing when we go through
- // the forward list.
- intptr_t class_id = raw->GetClassId();
- intptr_t object_id;
- if (write_as_reference && IsSplitClassId(class_id)) {
- object_id = forward_list_->AddObject(zone(), raw, kIsNotSerialized);
- } else {
- object_id = forward_list_->AddObject(zone(), raw, kIsSerialized);
- }
- if (write_as_reference || !IsSplitClassId(class_id)) {
- object_id = kOmittedObjectId;
- }
- WriteMarkedObjectImpl(raw, tags, object_id, write_as_reference);
-}
-
-void SnapshotWriter::WriteMarkedObjectImpl(ObjectPtr raw,
- intptr_t tags,
- intptr_t object_id,
- bool as_reference) {
- NoSafepointScope no_safepoint;
- ClassPtr cls = class_table_->At(UntaggedObject::ClassIdTag::decode(tags));
- intptr_t class_id = cls->untag()->id_;
- ASSERT(class_id == UntaggedObject::ClassIdTag::decode(tags));
- if (class_id >= kNumPredefinedCids || IsImplicitFieldClassId(class_id)) {
- WriteInstance(raw, cls, tags, object_id, as_reference);
- return;
- }
- switch (class_id) {
-#define SNAPSHOT_WRITE(clazz) \
- case clazz::kClassId: { \
- clazz##Ptr raw_obj = static_cast<clazz##Ptr>(raw); \
- raw_obj->untag()->WriteTo(this, object_id, kind_, as_reference); \
- return; \
- }
-
- CLASS_LIST_NO_OBJECT(SNAPSHOT_WRITE)
-#undef SNAPSHOT_WRITE
-#define SNAPSHOT_WRITE(clazz) case kTypedData##clazz##Cid:
-
- CLASS_LIST_TYPED_DATA(SNAPSHOT_WRITE) {
- TypedDataPtr raw_obj = static_cast<TypedDataPtr>(raw);
- raw_obj->untag()->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) {
- ExternalTypedDataPtr raw_obj = static_cast<ExternalTypedDataPtr>(raw);
- raw_obj->untag()->WriteTo(this, object_id, kind_, as_reference);
- return;
- }
-#undef SNAPSHOT_WRITE
-#define SNAPSHOT_WRITE(clazz) case kTypedData##clazz##ViewCid:
-
- case kByteDataViewCid:
- CLASS_LIST_TYPED_DATA(SNAPSHOT_WRITE) {
- auto raw_obj = static_cast<TypedDataViewPtr>(raw);
- raw_obj->untag()->WriteTo(this, object_id, kind_, as_reference);
- return;
- }
-#undef SNAPSHOT_WRITE
-
-#define SNAPSHOT_WRITE(clazz) case kFfi##clazz##Cid:
-
- CLASS_LIST_FFI(SNAPSHOT_WRITE) {
- SetWriteException(Exceptions::kArgument,
- "Native objects (from dart:ffi) such as Pointers and "
- "Structs cannot be passed between isolates.");
- UNREACHABLE();
- }
-#undef SNAPSHOT_WRITE
- default:
- break;
- }
-
- const Object& obj = Object::Handle(raw);
- FATAL1("Unexpected object: %s\n", obj.ToCString());
-}
-
-class WriteInlinedObjectVisitor : public ObjectVisitor {
- public:
- explicit WriteInlinedObjectVisitor(SnapshotWriter* writer)
- : writer_(writer) {}
-
- virtual void VisitObject(ObjectPtr obj) {
- intptr_t object_id = writer_->forward_list_->FindObject(obj);
- ASSERT(object_id != kInvalidIndex);
- intptr_t tags = MessageWriter::GetObjectTagsAndHash(ObjectPtr(obj));
- writer_->WriteMarkedObjectImpl(obj, tags, object_id, kAsInlinedObject);
- }
-
- private:
- SnapshotWriter* writer_;
-};
-
-void SnapshotWriter::WriteForwardedObjects() {
- WriteInlinedObjectVisitor visitor(this);
- forward_list_->SerializeAll(&visitor);
-}
-
-void ForwardList::SerializeAll(ObjectVisitor* writer) {
-// Write out all objects that were added to the forward list and have
-// not been serialized yet. These would typically be fields of instance
-// objects, arrays or immutable arrays (this is done in order to avoid
-// deep recursive calls to WriteObjectImpl).
-// NOTE: The forward list might grow as we process the list.
-#ifdef DEBUG
- for (intptr_t i = first_object_id(); i < first_unprocessed_object_id_; ++i) {
- ASSERT(NodeForObjectId(i)->is_serialized());
- }
-#endif // DEBUG
- for (intptr_t id = first_unprocessed_object_id_; id < next_object_id();
- ++id) {
- if (!NodeForObjectId(id)->is_serialized()) {
- // Write the object out in the stream.
- ObjectPtr raw = NodeForObjectId(id)->obj()->ptr();
- writer->VisitObject(raw);
-
- // Mark object as serialized.
- NodeForObjectId(id)->set_state(kIsSerialized);
- }
- }
- first_unprocessed_object_id_ = next_object_id();
-}
-
-void SnapshotWriter::WriteClassId(UntaggedClass* cls) {
- ASSERT(!Snapshot::IsFull(kind_));
- int class_id = cls->id_;
- ASSERT(!IsSingletonClassId(class_id) && !IsBootstrapedClassId(class_id));
-
- // Write out the library url and class name.
- LibraryPtr library = cls->library();
- ASSERT(library != Library::null());
- WriteObjectImpl(library->untag()->url(), kAsInlinedObject);
- WriteObjectImpl(cls->name(), kAsInlinedObject);
-}
-
-void SnapshotWriter::WriteStaticImplicitClosure(
- intptr_t object_id,
- FunctionPtr func,
- intptr_t tags,
- TypeArgumentsPtr delayed_type_arguments) {
- // Write out the serialization header value for this object.
- WriteInlinedObjectHeader(object_id);
-
- // Indicate this is a static implicit closure object.
- Write<int32_t>(SerializedHeaderData::encode(kStaticImplicitClosureObjectId));
-
- // Write out the tags.
- WriteTags(tags);
-
- // Write out the library url, class name and signature function name.
- ClassPtr cls = GetFunctionOwner(func);
- ASSERT(cls != Class::null());
- LibraryPtr library = cls->untag()->library();
- ASSERT(library != Library::null());
- WriteObjectImpl(library->untag()->url(), kAsInlinedObject);
- WriteObjectImpl(cls->untag()->name(), kAsInlinedObject);
- WriteObjectImpl(func->untag()->name(), kAsInlinedObject);
- WriteObjectImpl(delayed_type_arguments, kAsInlinedObject);
-}
-
-void SnapshotWriter::ArrayWriteTo(intptr_t object_id,
- intptr_t array_kind,
- intptr_t tags,
- SmiPtr length,
- TypeArgumentsPtr type_arguments,
- CompressedObjectPtr data[],
- bool as_reference) {
- if (as_reference) {
- // Write out the serialization header value for this object.
- WriteInlinedObjectHeader(kOmittedObjectId);
-
- // Write out the class information.
- WriteIndexedObject(array_kind);
- WriteTags(tags);
-
- // Write out the length field.
- Write<ObjectPtr>(length);
- } else {
- intptr_t len = Smi::Value(length);
-
- // Write out the serialization header value for this object.
- WriteInlinedObjectHeader(object_id);
-
- // Write out the class and tags information.
- WriteIndexedObject(array_kind);
- WriteTags(tags);
-
- // Write out the length field.
- Write<ObjectPtr>(length);
-
- // Write out the type arguments.
- WriteObjectImpl(type_arguments, kAsInlinedObject);
-
- // Write out the individual object ids.
- bool write_as_reference = UntaggedObject::IsCanonical(tags) ? false : true;
- uword heap_base = type_arguments.heap_base();
- for (intptr_t i = 0; i < len; i++) {
- WriteObjectImpl(data[i].Decompress(heap_base), write_as_reference);
- }
- }
-}
-
-void SnapshotWriter::MapWriteTo(intptr_t object_id,
- intptr_t class_id,
- intptr_t tags,
- TypeArgumentsPtr type_arguments,
- SmiPtr used_data_smi,
- SmiPtr deleted_keys_smi,
- ArrayPtr data,
- bool as_reference) {
- // Write out the serialization header value for this object.
- WriteInlinedObjectHeader(object_id);
-
- // Write out the class and tags information.
- WriteIndexedObject(class_id);
- WriteTags(tags);
-
- // Write out the type arguments.
- WriteObjectImpl(type_arguments, kAsInlinedObject);
-
- const intptr_t num_used_data = Smi::Value(used_data_smi);
- ASSERT((num_used_data & 1) == 0); // Keys + values, so must be even.
- const intptr_t num_deleted_keys = Smi::Value(deleted_keys_smi);
-
- // Write out the number of (not deleted) key/value pairs that will follow.
- Write<ObjectPtr>(Smi::New((num_used_data >> 1) - num_deleted_keys));
-
- // Write out the keys and values.
- const bool write_as_reference =
- UntaggedObject::IsCanonical(tags) ? false : true;
- ASSERT(num_used_data <= Smi::Value(data->untag()->length()));
-#if defined(DEBUG)
- intptr_t deleted_keys_found = 0;
-#endif // DEBUG
- for (intptr_t i = 0; i < num_used_data; i += 2) {
- ObjectPtr key = data->untag()->element(i);
- if (key == data) {
-#if defined(DEBUG)
- ++deleted_keys_found;
-#endif // DEBUG
- continue;
- }
- ObjectPtr value = data->untag()->element(i + 1);
- WriteObjectImpl(key, write_as_reference);
- WriteObjectImpl(value, write_as_reference);
- }
- DEBUG_ASSERT(deleted_keys_found == num_deleted_keys);
-}
-
-void SnapshotWriter::SetWriteTo(intptr_t object_id,
- intptr_t class_id,
- intptr_t tags,
- TypeArgumentsPtr type_arguments,
- SmiPtr used_data_smi,
- SmiPtr deleted_keys_smi,
- ArrayPtr data,
- bool as_reference) {
- // Write out the serialization header value for this object.
- WriteInlinedObjectHeader(object_id);
-
- // Write out the class and tags information.
- WriteIndexedObject(class_id);
- WriteTags(tags);
-
- // Write out the type arguments.
- WriteObjectImpl(type_arguments, kAsInlinedObject);
-
- const intptr_t num_used_data = Smi::Value(used_data_smi);
- const intptr_t num_deleted_keys = Smi::Value(deleted_keys_smi);
-
- // Write out the number of (not deleted) key/value pairs that will follow.
- Write<ObjectPtr>(Smi::New(num_used_data - num_deleted_keys));
-
- // Write out the keys and values.
- const bool write_as_reference =
- UntaggedObject::IsCanonical(tags) ? false : true;
- ASSERT(num_used_data <= Smi::Value(data->untag()->length()));
-#if defined(DEBUG)
- intptr_t deleted_keys_found = 0;
-#endif // DEBUG
- for (intptr_t i = 0; i < num_used_data; i++) {
- ObjectPtr key = data->untag()->element(i);
- if (key == data) {
-#if defined(DEBUG)
- ++deleted_keys_found;
-#endif // DEBUG
- continue;
- }
- ObjectPtr value = data->untag()->element(i + 1);
- WriteObjectImpl(key, write_as_reference);
- WriteObjectImpl(value, write_as_reference);
- }
- DEBUG_ASSERT(deleted_keys_found == num_deleted_keys);
-}
-
-FunctionPtr SnapshotWriter::IsSerializableClosure(ClosurePtr closure) {
- // Extract the function object to check if this closure
- // can be sent in an isolate message.
- FunctionPtr func = closure->untag()->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() &&
- Function::IsImplicitStaticClosureFunction(func)) {
- return func;
- }
- // Not a closure of a top level method or static function, throw an
- // exception as we do not allow these objects to be serialized.
- HANDLESCOPE(thread());
-
- const Function& errorFunc = Function::Handle(zone(), func);
- ASSERT(!errorFunc.IsNull());
-
- // All other closures are errors.
- char* chars = OS::SCreate(
- thread()->zone(),
- "Illegal argument in isolate message : (object is a closure - %s)",
- errorFunc.ToCString());
- SetWriteException(Exceptions::kArgument, chars);
- return Function::null();
-}
-
-ClassPtr SnapshotWriter::GetFunctionOwner(FunctionPtr func) {
- ObjectPtr owner = func->untag()->owner();
- uword tags = GetObjectTags(owner);
- intptr_t class_id = UntaggedObject::ClassIdTag::decode(tags);
- if (class_id == kClassCid) {
- return static_cast<ClassPtr>(owner);
- }
- ASSERT(class_id == kPatchClassCid);
- return static_cast<PatchClassPtr>(owner)->untag()->patched_class();
-}
-
-void SnapshotWriter::CheckForNativeFields(ClassPtr cls) {
- if (cls->untag()->num_native_fields_ != 0) {
- // We do not allow objects with native fields in an isolate message.
- HANDLESCOPE(thread());
- const Class& clazz = Class::Handle(zone(), cls);
- char* chars = OS::SCreate(thread()->zone(),
- "Illegal argument in isolate message"
- " : (object extends NativeWrapper - %s)",
- clazz.ToCString());
- SetWriteException(Exceptions::kArgument, chars);
- }
-}
-
-void SnapshotWriter::SetWriteException(Exceptions::ExceptionType type,
- const char* msg) {
- set_exception_type(type);
- set_exception_msg(msg);
- // The more specific error is set up in SnapshotWriter::ThrowException().
- thread()->long_jump_base()->Jump(1, Object::snapshot_writer_error());
-}
-
-void SnapshotWriter::WriteInstance(ObjectPtr raw,
- ClassPtr cls,
- intptr_t tags,
- intptr_t object_id,
- bool as_reference) {
- // Closure instances are handled by UntaggedClosure::WriteTo().
- ASSERT(!Class::IsClosureClass(cls));
-
- // Check if the instance has native fields and throw an exception if it does.
- CheckForNativeFields(cls);
-
- // Object is regular dart instance.
- if (as_reference) {
- // Write out the serialization header value for this object.
- WriteInlinedObjectHeader(kOmittedObjectId);
-
- // Indicate this is an instance object.
- Write<int32_t>(SerializedHeaderData::encode(kInstanceObjectId));
- WriteTags(tags);
-
- // Write out the class information for this object.
- WriteObjectImpl(cls, kAsInlinedObject);
- } else {
- intptr_t next_field_offset = Class::host_next_field_offset_in_words(cls)
- << kCompressedWordSizeLog2;
- ASSERT(next_field_offset > 0);
-
- // Write out the serialization header value for this object.
- WriteInlinedObjectHeader(object_id);
-
- // Indicate this is an instance object.
- Write<int32_t>(SerializedHeaderData::encode(kInstanceObjectId));
-
- // Write out the tags.
- WriteTags(tags);
-
- // Write out the class information for this object.
- WriteObjectImpl(cls, kAsInlinedObject);
-
- const auto unboxed_fields =
- isolate_group()->shared_class_table()->GetUnboxedFieldsMapAt(
- cls->untag()->id_);
-
- // 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 = UntaggedObject::IsCanonical(tags) ? false : true;
-
- intptr_t offset = Instance::NextFieldOffset();
- uword heap_base = raw->heap_base();
- while (offset < next_field_offset) {
- if (unboxed_fields.Get(offset / kCompressedWordSize)) {
- // Writes 32 bits of the unboxed value at a time
- const uword value = *reinterpret_cast<compressed_uword*>(
- reinterpret_cast<uword>(raw->untag()) + offset);
- WriteWordWith32BitWrites(value);
- } else {
- ObjectPtr raw_obj = reinterpret_cast<CompressedObjectPtr*>(
- reinterpret_cast<uword>(raw->untag()) + offset)
- ->Decompress(heap_base);
- WriteObjectImpl(raw_obj, write_as_reference);
- }
- offset += kCompressedWordSize;
- }
- }
- return;
-}
-
-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(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) {
- return (i + kMaxPredefinedObjectIds);
- }
- }
- return kInvalidIndex;
-}
-
-void SnapshotWriter::ThrowException(Exceptions::ExceptionType type,
- const char* msg) {
- {
- NoSafepointScope no_safepoint;
- ErrorPtr error = thread()->StealStickyError();
- ASSERT(error == Object::snapshot_writer_error().ptr());
- }
-
- if (msg != NULL) {
- const String& msg_obj = String::Handle(String::New(msg));
- const Array& args = Array::Handle(Array::New(1));
- args.SetAt(0, msg_obj);
- Exceptions::ThrowByType(type, args);
- } else {
- Exceptions::ThrowByType(type, Object::empty_array());
- }
- UNREACHABLE();
-}
-
-void SnapshotWriter::WriteVersionAndFeatures() {
- const char* expected_version = Version::SnapshotString();
- ASSERT(expected_version != NULL);
- const intptr_t version_len = strlen(expected_version);
- WriteBytes(reinterpret_cast<const uint8_t*>(expected_version), version_len);
-
- const char* expected_features =
- Dart::FeaturesString(IsolateGroup::Current(), false, kind_);
- ASSERT(expected_features != NULL);
- const intptr_t features_len = strlen(expected_features);
- WriteBytes(reinterpret_cast<const uint8_t*>(expected_features),
- features_len + 1);
- free(const_cast<char*>(expected_features));
-}
-
-void SnapshotWriterVisitor::VisitPointers(ObjectPtr* first, ObjectPtr* last) {
- ASSERT(Utils::IsAligned(first, sizeof(*first)));
- ASSERT(Utils::IsAligned(last, sizeof(*last)));
- for (ObjectPtr* current = first; current <= last; current++) {
- ObjectPtr raw_obj = *current;
- writer_->WriteObjectImpl(raw_obj, as_references_);
- }
-}
-
-void SnapshotWriterVisitor::VisitCompressedPointers(uword heap_base,
- CompressedObjectPtr* first,
- CompressedObjectPtr* last) {
- ASSERT(Utils::IsAligned(first, sizeof(*first)));
- ASSERT(Utils::IsAligned(last, sizeof(*last)));
- for (CompressedObjectPtr* current = first; current <= last; current++) {
- ObjectPtr raw_obj = current->Decompress(heap_base);
- writer_->WriteObjectImpl(raw_obj, as_references_);
- }
-}
-
-MessageWriter::MessageWriter(bool can_send_any_object)
- : SnapshotWriter(Thread::Current(),
- Snapshot::kMessage,
- kInitialSize,
- &forward_list_,
- can_send_any_object),
- forward_list_(thread(), kMaxPredefinedObjectIds),
- finalizable_data_(new MessageFinalizableData()) {}
-
-MessageWriter::~MessageWriter() {
- delete finalizable_data_;
-}
-
-std::unique_ptr<Message> MessageWriter::WriteMessage(
- const Object& obj,
- Dart_Port dest_port,
- Message::Priority priority) {
- ASSERT(kind() == Snapshot::kMessage);
- ASSERT(isolate() != NULL);
-
- // Setup for long jump in case there is an exception while writing
- // the message.
- volatile bool has_exception = false;
- {
- LongJumpScope jump;
- if (setjmp(*jump.Set()) == 0) {
- NoSafepointScope no_safepoint;
- WriteObject(obj.ptr());
- } else {
- FreeBuffer();
- has_exception = true;
- }
- }
- if (has_exception) {
- ThrowException(exception_type(), exception_msg());
- } else {
- finalizable_data_->SerializationSucceeded();
- }
-
- MessageFinalizableData* finalizable_data = finalizable_data_;
- finalizable_data_ = nullptr;
- intptr_t size;
- uint8_t* buffer = Steal(&size);
- return Message::New(dest_port, buffer, size, finalizable_data, priority);
-}
} // namespace dart
diff --git a/runtime/vm/snapshot.h b/runtime/vm/snapshot.h
index 8123e46..63d61a8 100644
--- a/runtime/vm/snapshot.h
+++ b/runtime/vm/snapshot.h
@@ -9,83 +9,14 @@
#include <utility>
#include "platform/assert.h"
+#include "platform/unaligned.h"
#include "vm/allocation.h"
-#include "vm/bitfield.h"
-#include "vm/datastream.h"
-#include "vm/finalizable_data.h"
#include "vm/globals.h"
-#include "vm/growable_array.h"
-#include "vm/isolate.h"
#include "vm/message.h"
-#include "vm/visitor.h"
+#include "vm/thread.h"
namespace dart {
-// Forward declarations.
-class AbstractType;
-class Array;
-class Class;
-class ClassTable;
-class Closure;
-class Code;
-class ExternalTypedData;
-class TypedDataBase;
-class GrowableObjectArray;
-class Heap;
-class Instance;
-class Instructions;
-class LanguageError;
-class Library;
-class LinkedHashMap;
-class Object;
-class PassiveObject;
-class ObjectStore;
-class MegamorphicCache;
-class PageSpace;
-class TypedDataView;
-class String;
-class TypeArguments;
-class TypedData;
-class UnhandledException;
-
-// Serialized object header encoding is as follows:
-// - Smi: the Smi value is written as is (last bit is not tagged).
-// - VM object (from VM isolate): (object id in vm isolate | 0x3)
-// This value is serialized as a negative number.
-// (note VM objects are never serialized, they are expected to be found
-// using ths unique ID assigned to them).
-// - Reference to object that has already been written: (object id | 0x3)
-// This valus is serialized as a positive number.
-// - Object that is seen for the first time (inlined in the stream):
-// (a unique id for this object | 0x1)
-enum SerializedHeaderType {
- kInlined = 0x1,
- kObjectId = 0x3,
-};
-static const int8_t kHeaderTagBits = 2;
-static const int8_t kObjectIdBits = (kBitsPerInt32 - (kHeaderTagBits + 1));
-static const intptr_t kMaxObjectId = (kMaxUint32 >> (kHeaderTagBits + 1));
-static const bool kAsReference = true;
-static const bool kAsInlinedObject = false;
-static const intptr_t kInvalidPatchIndex = -1;
-
-class SerializedHeaderTag
- : public BitField<intptr_t, enum SerializedHeaderType, 0, kHeaderTagBits> {
-};
-
-class SerializedHeaderData
- : public BitField<intptr_t, intptr_t, kHeaderTagBits, kObjectIdBits> {};
-
-enum DeserializeState {
- kIsDeserialized = 0,
- kIsNotDeserialized = 1,
-};
-
-enum SerializeState {
- kIsSerialized = 0,
- kIsNotSerialized = 1,
-};
-
// Structure capturing the raw snapshot.
//
class Snapshot {
@@ -95,7 +26,6 @@
kFullCore, // Full snapshot of core libraries. Agnostic to null safety.
kFullJIT, // Full + JIT code
kFullAOT, // Full + AOT code
- kMessage, // A partial snapshot used only for isolate messaging.
kNone, // gen_snapshot
kInvalid
};
@@ -185,555 +115,6 @@
return Snapshot::IsFull(isolate_kind);
}
-class BaseReader {
- public:
- BaseReader(const uint8_t* buffer, intptr_t size) : stream_(buffer, size) {}
- // Reads raw data (for basic types).
- // sizeof(T) must be in {1,2,4,8}.
- template <typename T>
- T Read() {
- return ReadStream::Raw<sizeof(T), T>::Read(&stream_);
- }
-
- classid_t ReadClassIDValue() {
- uint32_t value = Read<uint32_t>();
- return static_cast<classid_t>(value);
- }
- COMPILE_ASSERT(sizeof(uint32_t) >= sizeof(classid_t));
-
- void ReadBytes(uint8_t* addr, intptr_t len) { stream_.ReadBytes(addr, len); }
-
- double ReadDouble() {
- double result;
- stream_.ReadBytes(reinterpret_cast<uint8_t*>(&result), sizeof(result));
- return result;
- }
-
- intptr_t ReadTags() {
- const intptr_t tags = static_cast<intptr_t>(Read<int8_t>()) & 0xff;
- return tags;
- }
-
- const uint8_t* CurrentBufferAddress() const {
- return stream_.AddressOfCurrentPosition();
- }
-
- void Align(intptr_t value) { stream_.Align(value); }
- void Advance(intptr_t value) { stream_.Advance(value); }
-
- intptr_t PendingBytes() const { return stream_.PendingBytes(); }
-
- SmiPtr ReadAsSmi();
- intptr_t ReadSmiValue();
-
- // Negative header value indicates VM isolate object id.
- bool IsVMIsolateObject(intptr_t header_value) { return (header_value < 0); }
- intptr_t GetVMIsolateObjectId(intptr_t header_val) {
- ASSERT(IsVMIsolateObject(header_val));
- intptr_t value = -header_val; // Header is negative for VM isolate objects.
- ASSERT(SerializedHeaderTag::decode(value) == kObjectId);
- return SerializedHeaderData::decode(value);
- }
-
- uword ReadWordWith32BitReads() { return stream_.ReadWordWith32BitReads(); }
-
- private:
- ReadStream stream_; // input stream.
-};
-
-class BackRefNode : public ValueObject {
- public:
- BackRefNode(Object* reference, DeserializeState state)
- : reference_(reference), state_(state) {}
- Object* reference() const { return reference_; }
- bool is_deserialized() const { return state_ == kIsDeserialized; }
- void set_state(DeserializeState state) { state_ = state; }
-
- BackRefNode& operator=(const BackRefNode& other) {
- reference_ = other.reference_;
- state_ = other.state_;
- return *this;
- }
-
- private:
- Object* reference_;
- DeserializeState state_;
-};
-
-// Reads a snapshot into objects.
-class SnapshotReader : public BaseReader {
- public:
- Thread* thread() const { return thread_; }
- Zone* zone() const { return zone_; }
- Isolate* isolate() const { return thread_->isolate(); }
- IsolateGroup* isolate_group() const { return thread_->isolate_group(); }
- Heap* heap() const { return heap_; }
- ObjectStore* object_store() const { return isolate_group()->object_store(); }
- ClassTable* class_table() const { return isolate_group()->class_table(); }
- PassiveObject* PassiveObjectHandle() { return &pobj_; }
- Array* ArrayHandle() { return &array_; }
- Class* ClassHandle() { return &cls_; }
- Code* CodeHandle() { return &code_; }
- Instance* InstanceHandle() { return &instance_; }
- Instructions* InstructionsHandle() { return &instructions_; }
- String* StringHandle() { return &str_; }
- AbstractType* TypeHandle() { return &type_; }
- TypeArguments* TypeArgumentsHandle() { return &type_arguments_; }
- GrowableObjectArray* TokensHandle() { return &tokens_; }
- ExternalTypedData* DataHandle() { return &data_; }
- TypedDataBase* TypedDataBaseHandle() { return &typed_data_base_; }
- TypedData* TypedDataHandle() { return &typed_data_; }
- TypedDataView* TypedDataViewHandle() { return &typed_data_view_; }
- Function* FunctionHandle() { return &function_; }
- Smi* SmiHandle() { return &smi_; }
- Snapshot::Kind kind() const { return kind_; }
-
- // Reads an object.
- ObjectPtr ReadObject();
-
- // Add object to backward references.
- void AddBackRef(intptr_t id, Object* obj, DeserializeState state);
-
- // Get an object from the backward references list.
- Object* GetBackRef(intptr_t id);
-
- // Read version number of snapshot and verify.
- ApiErrorPtr VerifyVersionAndFeatures(IsolateGroup* isolate_group);
-
- ObjectPtr NewInteger(int64_t value);
-
- protected:
- SnapshotReader(const uint8_t* buffer,
- intptr_t size,
- Snapshot::Kind kind,
- ZoneGrowableArray<BackRefNode>* backward_references,
- Thread* thread);
- ~SnapshotReader() {}
-
- ZoneGrowableArray<BackRefNode>* GetBackwardReferenceTable() const {
- return backward_references_;
- }
- void ResetBackwardReferenceTable() { backward_references_ = NULL; }
- PageSpace* old_space() const { return old_space_; }
-
- private:
- void EnqueueTypePostprocessing(const AbstractType& type);
- void RunDelayedTypePostprocessing();
-
- void EnqueueRehashingOfMap(const LinkedHashMap& map);
- void EnqueueRehashingOfSet(const LinkedHashSet& set);
- ObjectPtr RunDelayedRehashingOfMapsAndSets();
-
- ClassPtr ReadClassId(intptr_t object_id);
- ObjectPtr ReadStaticImplicitClosure(intptr_t object_id, intptr_t cls_header);
-
- // Implementation to read an object.
- ObjectPtr ReadObjectImpl(bool as_reference);
- ObjectPtr ReadObjectImpl(intptr_t header, bool as_reference);
-
- // Read a Dart Instance object.
- ObjectPtr ReadInstance(intptr_t object_id, intptr_t tags, bool as_reference);
-
- // Read a VM isolate object that was serialized as an 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).
- ObjectPtr ReadIndexedObject(intptr_t object_id);
-
- // Decode class id from the header field.
- intptr_t LookupInternalClass(intptr_t class_header);
-
- void ArrayReadFrom(intptr_t object_id,
- const Array& result,
- intptr_t len,
- intptr_t tags);
-
- void MapReadFrom(intptr_t object_id,
- const LinkedHashMap& result,
- intptr_t tags);
-
- void SetReadFrom(intptr_t object_id,
- const LinkedHashSet& result,
- intptr_t tags);
-
- intptr_t NextAvailableObjectId() const;
-
- void SetReadException(const char* msg);
-
- ObjectPtr VmIsolateSnapshotObject(intptr_t index) const;
-
- bool is_vm_isolate() const;
-
- Snapshot::Kind kind_; // Indicates type of the snapshot.
- Thread* thread_; // Current thread.
- Zone* zone_; // Zone for allocations while reading.
- Heap* heap_; // Heap of the current isolate.
- PageSpace* old_space_; // Old space of the current isolate.
- Class& cls_; // Temporary Class handle.
- Code& code_; // Temporary Code handle.
- Instance& instance_; // Temporary Instance handle
- Instructions& instructions_; // Temporary Instructions handle
- Object& obj_; // Temporary Object handle.
- PassiveObject& pobj_; // Temporary PassiveObject handle.
- Array& array_; // Temporary Array handle.
- Field& field_; // Temporary Field handle.
- String& str_; // Temporary String handle.
- Library& library_; // Temporary library handle.
- AbstractType& type_; // Temporary type handle.
- TypeArguments& type_arguments_; // Temporary type argument handle.
- GrowableObjectArray& tokens_; // Temporary tokens handle.
- ExternalTypedData& data_; // Temporary stream data handle.
- TypedDataBase& typed_data_base_; // Temporary typed data base handle.
- TypedData& typed_data_; // Temporary typed data handle.
- TypedDataView& typed_data_view_; // Temporary typed data view handle.
- Function& function_; // Temporary function handle.
- Smi& smi_; // Temporary Smi handle.
- UnhandledException& error_; // Error handle.
- const Class& set_class_; // The LinkedHashSet class.
- intptr_t max_vm_isolate_object_id_;
- ZoneGrowableArray<BackRefNode>* backward_references_;
- GrowableObjectArray& types_to_postprocess_;
- GrowableObjectArray& objects_to_rehash_;
-
- friend class ApiError;
- friend class Array;
- friend class Class;
- friend class Closure;
- friend class ClosureData;
- friend class Context;
- friend class ContextScope;
- friend class ExceptionHandlers;
- friend class Field;
- friend class Function;
- friend class GrowableObjectArray;
- friend class ICData;
- friend class ImmutableArray;
- friend class KernelProgramInfo;
- friend class LanguageError;
- friend class Library;
- friend class LibraryPrefix;
- friend class LinkedHashMap;
- friend class LinkedHashSet;
- friend class MirrorReference;
- friend class Namespace;
- friend class PatchClass;
- friend class RegExp;
- friend class Script;
- friend class SubtypeTestCache;
- friend class TransferableTypedData;
- friend class Type;
- friend class FunctionType;
- friend class TypedDataView;
- friend class TypeParameters;
- friend class TypeArguments;
- friend class TypeParameter;
- friend class TypeRef;
- friend class UnhandledException;
- friend class WeakProperty;
- friend class WeakSerializationReference;
- DISALLOW_COPY_AND_ASSIGN(SnapshotReader);
-};
-
-class MessageSnapshotReader : public SnapshotReader {
- public:
- MessageSnapshotReader(Message* message, Thread* thread);
- ~MessageSnapshotReader();
-
- MessageFinalizableData* finalizable_data() const { return finalizable_data_; }
-
- private:
- MessageFinalizableData* finalizable_data_;
-
- DISALLOW_COPY_AND_ASSIGN(MessageSnapshotReader);
-};
-
-class BaseWriter : public StackResource {
- public:
- uint8_t* Steal(intptr_t* length) { return stream_.Steal(length); }
- intptr_t BytesWritten() const { return stream_.bytes_written(); }
-
- // Writes raw data to the stream (basic type).
- // sizeof(T) must be in {1,2,4,8}.
- template <typename T>
- void Write(T value) {
- MallocWriteStream::Raw<sizeof(T), T>::Write(&stream_, value);
- }
-
- void WriteClassIDValue(classid_t value) { Write<uint32_t>(value); }
- COMPILE_ASSERT(sizeof(uint32_t) >= sizeof(classid_t));
-
- // Write an object that is serialized as an Id (singleton in object store,
- // or an object that was already serialized before).
- void WriteIndexedObject(intptr_t object_id) {
- ASSERT(object_id <= kMaxObjectId);
- intptr_t value = 0;
- value = SerializedHeaderTag::update(kObjectId, value);
- value = SerializedHeaderData::update(object_id, value);
- Write<int32_t>(value);
- }
-
- // Write a VM Isolateobject that is serialized as an Id.
- void WriteVMIsolateObject(intptr_t object_id) {
- ASSERT(object_id <= kMaxObjectId);
- intptr_t value = 0;
- value = SerializedHeaderTag::update(kObjectId, value);
- value = SerializedHeaderData::update(object_id, value);
- Write<int32_t>(-value); // Write as a negative value.
- }
-
- // Write serialization header information for an object.
- void WriteInlinedObjectHeader(intptr_t id) {
- ASSERT(id <= kMaxObjectId);
- intptr_t value = 0;
- value = SerializedHeaderTag::update(kInlined, value);
- value = SerializedHeaderData::update(id, value);
- Write<int32_t>(value);
- }
-
- void WriteTags(intptr_t tags) {
- const intptr_t flags = tags & 0xff;
- Write<int8_t>(static_cast<int8_t>(flags));
- }
-
- void Align(intptr_t value) { stream_.Align(value); }
-
- // Write out a buffer of bytes.
- void WriteBytes(const uint8_t* addr, intptr_t len) {
- stream_.WriteBytes(addr, len);
- }
-
- void WriteDouble(double value) {
- stream_.WriteBytes(reinterpret_cast<const uint8_t*>(&value), sizeof(value));
- }
-
- void WriteWordWith32BitWrites(uword value) {
- stream_.WriteWordWith32BitWrites(value);
- }
-
- protected:
- explicit BaseWriter(intptr_t initial_size)
- : StackResource(Thread::Current()), stream_(initial_size) {}
- ~BaseWriter() {}
-
- void ReserveHeader() {
- // Make room for recording snapshot buffer size.
- stream_.SetPosition(Snapshot::kHeaderSize);
- }
-
- void FillHeader(Snapshot::Kind kind) {
- intptr_t length;
- Snapshot* header = reinterpret_cast<Snapshot*>(Steal(&length));
- header->set_magic();
- header->set_length(length);
- header->set_kind(kind);
- }
-
- void FreeBuffer() {
- intptr_t unused;
- free(Steal(&unused));
- }
-
- private:
- MallocWriteStream stream_;
-
- DISALLOW_IMPLICIT_CONSTRUCTORS(BaseWriter);
-};
-
-class ForwardList {
- public:
- explicit ForwardList(Thread* thread, intptr_t first_object_id);
- ~ForwardList();
-
- class Node : public ZoneAllocated {
- public:
- Node(const Object* obj, SerializeState state) : obj_(obj), state_(state) {}
- const Object* obj() const { return obj_; }
- bool is_serialized() const { return state_ == kIsSerialized; }
-
- private:
- // Private to ensure the invariant of first_unprocessed_object_id_.
- void set_state(SerializeState value) { state_ = value; }
-
- const Object* obj_;
- SerializeState state_;
-
- friend class ForwardList;
- DISALLOW_COPY_AND_ASSIGN(Node);
- };
-
- Node* NodeForObjectId(intptr_t object_id) const {
- return nodes_[object_id - first_object_id_];
- }
-
- // Returns the id for the added object.
- intptr_t AddObject(Zone* zone, ObjectPtr raw, SerializeState state);
-
- // Returns the id for the object it it exists in the list.
- intptr_t FindObject(ObjectPtr raw);
-
- // Exhaustively processes all unserialized objects in this list. 'writer' may
- // concurrently add more objects.
- void SerializeAll(ObjectVisitor* writer);
-
- // Set state of object in forward list.
- void SetState(intptr_t object_id, SerializeState state) {
- NodeForObjectId(object_id)->set_state(state);
- }
-
- private:
- intptr_t first_object_id() const { return first_object_id_; }
- intptr_t next_object_id() const { return nodes_.length() + first_object_id_; }
- Isolate* isolate() const { return thread_->isolate(); }
-
- Thread* thread_;
- const intptr_t first_object_id_;
- GrowableArray<Node*> nodes_;
- intptr_t first_unprocessed_object_id_;
-
- void SetObjectId(ObjectPtr object, intptr_t id);
- intptr_t GetObjectId(ObjectPtr object);
-
- DISALLOW_COPY_AND_ASSIGN(ForwardList);
-};
-
-class SnapshotWriter : public BaseWriter {
- protected:
- SnapshotWriter(Thread* thread,
- Snapshot::Kind kind,
- intptr_t initial_size,
- ForwardList* forward_list,
- bool can_send_any_object);
-
- public:
- // Snapshot kind.
- Snapshot::Kind kind() const { return kind_; }
- Thread* thread() const { return thread_; }
- Zone* zone() const { return thread_->zone(); }
- Isolate* isolate() const { return thread_->isolate(); }
- IsolateGroup* isolate_group() const { return thread_->isolate_group(); }
- Heap* heap() const { return isolate_group()->heap(); }
-
- // Serialize an object into the buffer.
- void WriteObject(ObjectPtr raw);
-
- static uint32_t GetObjectTags(ObjectPtr raw);
- static uint32_t GetObjectTags(UntaggedObject* raw);
- static uword GetObjectTagsAndHash(ObjectPtr raw);
-
- Exceptions::ExceptionType exception_type() const { return exception_type_; }
- void set_exception_type(Exceptions::ExceptionType type) {
- exception_type_ = type;
- }
- const char* exception_msg() const { return exception_msg_; }
- void set_exception_msg(const char* msg) { exception_msg_ = msg; }
- bool can_send_any_object() const { return can_send_any_object_; }
- void ThrowException(Exceptions::ExceptionType type, const char* msg);
-
- // Write a version string for the snapshot.
- void WriteVersionAndFeatures();
-
- FunctionPtr IsSerializableClosure(ClosurePtr closure);
-
- void WriteStaticImplicitClosure(intptr_t object_id,
- FunctionPtr func,
- intptr_t tags,
- TypeArgumentsPtr delayed_type_arguments);
-
- protected:
- bool CheckAndWritePredefinedObject(ObjectPtr raw);
- bool HandleVMIsolateObject(ObjectPtr raw);
-
- void WriteClassId(UntaggedClass* cls);
- void WriteObjectImpl(ObjectPtr raw, bool as_reference);
- void WriteMarkedObjectImpl(ObjectPtr raw,
- intptr_t tags,
- intptr_t object_id,
- bool as_reference);
- void WriteForwardedObjects();
- void ArrayWriteTo(intptr_t object_id,
- intptr_t array_kind,
- intptr_t tags,
- SmiPtr length,
- TypeArgumentsPtr type_arguments,
- CompressedObjectPtr data[],
- bool as_reference);
- void MapWriteTo(intptr_t object_id,
- intptr_t class_id,
- intptr_t tags,
- TypeArgumentsPtr type_arguments,
- SmiPtr used_data_smi,
- SmiPtr deleted_keys_smi,
- ArrayPtr data,
- bool as_reference);
- void SetWriteTo(intptr_t object_id,
- intptr_t class_id,
- intptr_t tags,
- TypeArgumentsPtr type_arguments,
- SmiPtr used_data_smi,
- SmiPtr deleted_keys_smi,
- ArrayPtr data,
- bool as_reference);
- ClassPtr GetFunctionOwner(FunctionPtr func);
- void CheckForNativeFields(ClassPtr cls);
- void SetWriteException(Exceptions::ExceptionType type, const char* msg);
- void WriteInstance(ObjectPtr raw,
- ClassPtr cls,
- intptr_t tags,
- intptr_t object_id,
- bool as_reference);
- bool AllowObjectsInDartLibrary(LibraryPtr library);
- intptr_t FindVmSnapshotObject(ObjectPtr rawobj);
-
- ObjectStore* object_store() const { return object_store_; }
-
- private:
- Thread* thread_;
- Snapshot::Kind kind_;
- ObjectStore* object_store_; // Object store for common classes.
- ClassTable* class_table_; // Class table for the class index to class lookup.
- ForwardList* forward_list_;
- Exceptions::ExceptionType exception_type_; // Exception type.
- const char* exception_msg_; // Message associated with exception.
- bool can_send_any_object_; // True if any Dart instance can be sent.
-
- friend class UntaggedArray;
- friend class UntaggedClass;
- friend class UntaggedCode;
- friend class UntaggedContextScope;
- friend class UntaggedDynamicLibrary;
- friend class UntaggedExceptionHandlers;
- friend class UntaggedField;
- friend class UntaggedFunction;
- friend class UntaggedFunctionType;
- friend class UntaggedGrowableObjectArray;
- friend class UntaggedImmutableArray;
- friend class UntaggedInstructions;
- friend class UntaggedLibrary;
- friend class UntaggedLinkedHashMap;
- friend class UntaggedLinkedHashSet;
- friend class UntaggedLocalVarDescriptors;
- friend class UntaggedMirrorReference;
- friend class UntaggedObjectPool;
- friend class UntaggedPointer;
- friend class UntaggedReceivePort;
- friend class UntaggedRegExp;
- friend class UntaggedScript;
- friend class UntaggedStackTrace;
- friend class UntaggedSubtypeTestCache;
- friend class UntaggedTransferableTypedData;
- friend class UntaggedType;
- friend class UntaggedTypeArguments;
- friend class UntaggedTypeParameter;
- friend class UntaggedTypeRef;
- friend class UntaggedTypedDataView;
- friend class UntaggedUserTag;
- friend class UntaggedWeakSerializationReference;
- friend class SnapshotWriterVisitor;
- friend class WriteInlinedObjectVisitor;
- DISALLOW_COPY_AND_ASSIGN(SnapshotWriter);
-};
-
class SerializedObjectBuffer : public StackResource {
public:
SerializedObjectBuffer()
@@ -749,46 +130,6 @@
std::unique_ptr<Message> message_;
};
-class MessageWriter : public SnapshotWriter {
- public:
- static const intptr_t kInitialSize = 512;
- explicit MessageWriter(bool can_send_any_object);
- ~MessageWriter();
-
- std::unique_ptr<Message> WriteMessage(const Object& obj,
- Dart_Port dest_port,
- Message::Priority priority);
-
- MessageFinalizableData* finalizable_data() const { return finalizable_data_; }
-
- private:
- ForwardList forward_list_;
- MessageFinalizableData* finalizable_data_;
-
- DISALLOW_COPY_AND_ASSIGN(MessageWriter);
-};
-
-// An object pointer visitor implementation which writes out
-// objects to a snapshot.
-class SnapshotWriterVisitor : public ObjectPointerVisitor {
- public:
- SnapshotWriterVisitor(SnapshotWriter* writer, bool as_references)
- : ObjectPointerVisitor(Isolate::Current()->group()),
- writer_(writer),
- as_references_(as_references) {}
-
- void VisitPointers(ObjectPtr* first, ObjectPtr* last);
- void VisitCompressedPointers(uword heap_base,
- CompressedObjectPtr* first,
- CompressedObjectPtr* last);
-
- private:
- SnapshotWriter* writer_;
- bool as_references_;
-
- DISALLOW_COPY_AND_ASSIGN(SnapshotWriterVisitor);
-};
-
} // namespace dart
#endif // RUNTIME_VM_SNAPSHOT_H_
diff --git a/runtime/vm/snapshot_ids.h b/runtime/vm/snapshot_ids.h
deleted file mode 100644
index b38bf1b..0000000
--- a/runtime/vm/snapshot_ids.h
+++ /dev/null
@@ -1,98 +0,0 @@
-// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-#ifndef RUNTIME_VM_SNAPSHOT_IDS_H_
-#define RUNTIME_VM_SNAPSHOT_IDS_H_
-
-#include "vm/dart_entry.h"
-#include "vm/raw_object.h"
-
-namespace dart {
-
-// Index for predefined singleton objects used in a snapshot.
-enum {
- kNullObject = 0,
- kSentinelObject,
- kTransitionSentinelObject,
- kEmptyArrayObject,
- kZeroArrayObject,
- kTrueValue,
- kFalseValue,
- // Marker for special encoding of double objects in message snapshots.
- kDoubleObject,
- // Object id has been optimized away; reader should use next available id.
- kOmittedObjectId,
-
- kClassIdsOffset = kOmittedObjectId,
-
- // The class ids of predefined classes are included in this list
- // at an offset of kClassIdsOffset.
-
- kFirstTypeSnapshotId = (kNumPredefinedCids + kClassIdsOffset),
- kLegacyObjectType = kFirstTypeSnapshotId,
- kNullableObjectType,
- kNullType,
- kDynamicType,
- kVoidType,
- kNeverType,
- kLegacyFunctionType,
- kLegacyNumberType,
- kLegacySmiType,
- kLegacyMintType,
- kLegacyDoubleType,
- kLegacyIntType,
- kLegacyBoolType,
- kLegacyStringType,
- kLegacyArrayType,
- kNonNullableObjectType,
- kNonNullableFunctionType,
- kNonNullableNumberType,
- kNonNullableSmiType,
- kNonNullableMintType,
- kNonNullableDoubleType,
- kNonNullableIntType,
- kNonNullableBoolType,
- kNonNullableStringType,
- kNonNullableArrayType,
- kLastTypeSnapshotId = kNonNullableArrayType,
-
- kFirstTypeArgumentsSnapshotId = kLastTypeSnapshotId + 1,
- kLegacyIntTypeArguments = kFirstTypeArgumentsSnapshotId,
- kLegacyDoubleTypeArguments,
- kLegacyStringTypeArguments,
- kLegacyStringDynamicTypeArguments,
- kLegacyStringLegacyStringTypeArguments,
- kNonNullableIntTypeArguments,
- kNonNullableDoubleTypeArguments,
- kNonNullableStringTypeArguments,
- kNonNullableStringDynamicTypeArguments,
- kNonNullableStringNonNullableStringTypeArguments,
- kEmptyTypeArguments,
- kLastTypeArgumentsSnapshotId = kEmptyTypeArguments,
-
- kExtractorParameterTypes,
- kExtractorParameterNames,
- kEmptyContextScopeObject,
- kImplicitClosureScopeObject,
- kEmptyObjectPool,
- kEmptyDescriptors,
- kEmptyVarDescriptors,
- kEmptyExceptionHandlers,
- kCachedArgumentsDescriptor0,
- kCachedArgumentsDescriptorN =
- (kCachedArgumentsDescriptor0 +
- ArgumentsDescriptor::kCachedDescriptorCount - 1),
- kCachedICDataArray0,
- kCachedICDataArrayN =
- (kCachedICDataArray0 + ICData::kCachedICDataArrayCount - 1),
-
- kInstanceObjectId,
- kStaticImplicitClosureObjectId,
- kMaxPredefinedObjectIds,
- kInvalidIndex = -1,
-};
-
-} // namespace dart
-
-#endif // RUNTIME_VM_SNAPSHOT_IDS_H_
diff --git a/runtime/vm/snapshot_test.cc b/runtime/vm/snapshot_test.cc
index 944124f..8affadb 100644
--- a/runtime/vm/snapshot_test.cc
+++ b/runtime/vm/snapshot_test.cc
@@ -15,6 +15,7 @@
#include "vm/debugger_api_impl_test.h"
#include "vm/flags.h"
#include "vm/malloc_hooks.h"
+#include "vm/message_snapshot.h"
#include "vm/snapshot.h"
#include "vm/symbols.h"
#include "vm/timer.h"
@@ -59,7 +60,6 @@
// Return immediately if entering a cycle.
if (second->type == Dart_CObject_kNumberOfTypes) return;
- EXPECT_NE(first, second);
EXPECT_EQ(first->type, second->type);
switch (first->type) {
case Dart_CObject_kNull:
@@ -106,23 +106,20 @@
}
}
-static void CheckEncodeDecodeMessage(Dart_CObject* root) {
+static void CheckEncodeDecodeMessage(Zone* zone, Dart_CObject* root) {
// Encode and decode the message.
- ApiMessageWriter writer;
std::unique_ptr<Message> message =
- writer.WriteCMessage(root, ILLEGAL_PORT, Message::kNormalPriority);
+ WriteApiMessage(zone, root, ILLEGAL_PORT, Message::kNormalPriority);
- ApiMessageReader api_reader(message.get());
- Dart_CObject* new_root = api_reader.ReadMessage();
+ Dart_CObject* new_root = ReadApiMessage(zone, message.get());
// Check that the two messages are the same.
CompareDartCObjects(root, new_root);
}
-static void ExpectEncodeFail(Dart_CObject* root) {
- ApiMessageWriter writer;
+static void ExpectEncodeFail(Zone* zone, Dart_CObject* root) {
std::unique_ptr<Message> message =
- writer.WriteCMessage(root, ILLEGAL_PORT, Message::kNormalPriority);
+ WriteApiMessage(zone, root, ILLEGAL_PORT, Message::kNormalPriority);
EXPECT(message == nullptr);
}
@@ -131,22 +128,21 @@
// Write snapshot with object content.
const Object& null_object = Object::Handle();
- MessageWriter writer(true);
std::unique_ptr<Message> message =
- writer.WriteMessage(null_object, ILLEGAL_PORT, Message::kNormalPriority);
+ WriteMessage(/* can_send_any_object */ true, null_object, ILLEGAL_PORT,
+ Message::kNormalPriority);
// Read object back from the snapshot.
- MessageSnapshotReader reader(message.get(), thread);
- const Object& serialized_object = Object::Handle(reader.ReadObject());
+ const Object& serialized_object =
+ Object::Handle(ReadMessage(thread, message.get()));
EXPECT(Equals(null_object, serialized_object));
// Read object back from the snapshot into a C structure.
ApiNativeScope scope;
- ApiMessageReader api_reader(message.get());
- Dart_CObject* root = api_reader.ReadMessage();
+ Dart_CObject* root = ReadApiMessage(scope.zone(), message.get());
EXPECT_NOTNULL(root);
EXPECT_EQ(Dart_CObject_kNull, root->type);
- CheckEncodeDecodeMessage(root);
+ CheckEncodeDecodeMessage(scope.zone(), root);
}
ISOLATE_UNIT_TEST_CASE(SerializeSmi1) {
@@ -154,23 +150,22 @@
// Write snapshot with object content.
const Smi& smi = Smi::Handle(Smi::New(124));
- MessageWriter writer(true);
std::unique_ptr<Message> message =
- writer.WriteMessage(smi, ILLEGAL_PORT, Message::kNormalPriority);
+ WriteMessage(/* can_send_any_object */ true, smi, ILLEGAL_PORT,
+ Message::kNormalPriority);
// Read object back from the snapshot.
- MessageSnapshotReader reader(message.get(), thread);
- const Object& serialized_object = Object::Handle(reader.ReadObject());
+ const Object& serialized_object =
+ Object::Handle(ReadMessage(thread, message.get()));
EXPECT(Equals(smi, serialized_object));
// Read object back from the snapshot into a C structure.
ApiNativeScope scope;
- ApiMessageReader api_reader(message.get());
- Dart_CObject* root = api_reader.ReadMessage();
+ Dart_CObject* root = ReadApiMessage(scope.zone(), message.get());
EXPECT_NOTNULL(root);
EXPECT_EQ(Dart_CObject_kInt32, root->type);
EXPECT_EQ(smi.Value(), root->value.as_int32);
- CheckEncodeDecodeMessage(root);
+ CheckEncodeDecodeMessage(scope.zone(), root);
}
ISOLATE_UNIT_TEST_CASE(SerializeSmi2) {
@@ -178,46 +173,44 @@
// Write snapshot with object content.
const Smi& smi = Smi::Handle(Smi::New(-1));
- MessageWriter writer(true);
std::unique_ptr<Message> message =
- writer.WriteMessage(smi, ILLEGAL_PORT, Message::kNormalPriority);
+ WriteMessage(/* can_send_any_object */ true, smi, ILLEGAL_PORT,
+ Message::kNormalPriority);
// Read object back from the snapshot.
- MessageSnapshotReader reader(message.get(), thread);
- const Object& serialized_object = Object::Handle(reader.ReadObject());
+ const Object& serialized_object =
+ Object::Handle(ReadMessage(thread, message.get()));
EXPECT(Equals(smi, serialized_object));
// Read object back from the snapshot into a C structure.
ApiNativeScope scope;
- ApiMessageReader api_reader(message.get());
- Dart_CObject* root = api_reader.ReadMessage();
+ Dart_CObject* root = ReadApiMessage(scope.zone(), message.get());
EXPECT_NOTNULL(root);
EXPECT_EQ(Dart_CObject_kInt32, root->type);
EXPECT_EQ(smi.Value(), root->value.as_int32);
- CheckEncodeDecodeMessage(root);
+ CheckEncodeDecodeMessage(scope.zone(), root);
}
-Dart_CObject* SerializeAndDeserializeMint(const Mint& mint) {
+Dart_CObject* SerializeAndDeserializeMint(Zone* zone, const Mint& mint) {
// Write snapshot with object content.
- MessageWriter writer(true);
std::unique_ptr<Message> message =
- writer.WriteMessage(mint, ILLEGAL_PORT, Message::kNormalPriority);
+ WriteMessage(/* can_send_any_object */ true, mint, ILLEGAL_PORT,
+ Message::kNormalPriority);
{
// Switch to a regular zone, where VM handle allocation is allowed.
Thread* thread = Thread::Current();
StackZone zone(thread);
// Read object back from the snapshot.
- MessageSnapshotReader reader(message.get(), thread);
- const Object& serialized_object = Object::Handle(reader.ReadObject());
+ const Object& serialized_object =
+ Object::Handle(ReadMessage(thread, message.get()));
EXPECT(serialized_object.IsMint());
}
// Read object back from the snapshot into a C structure.
- ApiMessageReader api_reader(message.get());
- Dart_CObject* root = api_reader.ReadMessage();
+ Dart_CObject* root = ReadApiMessage(zone, message.get());
EXPECT_NOTNULL(root);
- CheckEncodeDecodeMessage(root);
+ CheckEncodeDecodeMessage(zone, root);
return root;
}
@@ -227,7 +220,8 @@
Mint& mint = Mint::Handle();
mint ^= Integer::New(value);
- Dart_CObject* mint_cobject = SerializeAndDeserializeMint(mint);
+ Dart_CObject* mint_cobject =
+ SerializeAndDeserializeMint(zone.GetZone(), mint);
// On 64-bit platforms mints always require 64-bits as the smi range
// here covers most of the 64-bit range. On 32-bit platforms the smi
// range covers most of the 32-bit range and values outside that
@@ -270,23 +264,22 @@
// Write snapshot with object content.
const Double& dbl = Double::Handle(Double::New(101.29));
- MessageWriter writer(true);
std::unique_ptr<Message> message =
- writer.WriteMessage(dbl, ILLEGAL_PORT, Message::kNormalPriority);
+ WriteMessage(/* can_send_any_object */ true, dbl, ILLEGAL_PORT,
+ Message::kNormalPriority);
// Read object back from the snapshot.
- MessageSnapshotReader reader(message.get(), thread);
- const Object& serialized_object = Object::Handle(reader.ReadObject());
+ const Object& serialized_object =
+ Object::Handle(ReadMessage(thread, message.get()));
EXPECT(Equals(dbl, serialized_object));
// Read object back from the snapshot into a C structure.
ApiNativeScope scope;
- ApiMessageReader api_reader(message.get());
- Dart_CObject* root = api_reader.ReadMessage();
+ Dart_CObject* root = ReadApiMessage(scope.zone(), message.get());
EXPECT_NOTNULL(root);
EXPECT_EQ(Dart_CObject_kDouble, root->type);
EXPECT_EQ(dbl.value(), root->value.as_double);
- CheckEncodeDecodeMessage(root);
+ CheckEncodeDecodeMessage(scope.zone(), root);
}
ISOLATE_UNIT_TEST_CASE(SerializeTrue) {
@@ -294,25 +287,24 @@
// Write snapshot with true object.
const Bool& bl = Bool::True();
- MessageWriter writer(true);
- std::unique_ptr<Message> message =
- writer.WriteMessage(bl, ILLEGAL_PORT, Message::kNormalPriority);
+ std::unique_ptr<Message> message = WriteMessage(
+ /* can_send_any_object */ true, bl, ILLEGAL_PORT,
+ Message::kNormalPriority);
// Read object back from the snapshot.
- MessageSnapshotReader reader(message.get(), thread);
- const Object& serialized_object = Object::Handle(reader.ReadObject());
+ const Object& serialized_object =
+ Object::Handle(ReadMessage(thread, message.get()));
fprintf(stderr, "%s / %s\n", bl.ToCString(), serialized_object.ToCString());
EXPECT(Equals(bl, serialized_object));
// Read object back from the snapshot into a C structure.
ApiNativeScope scope;
- ApiMessageReader api_reader(message.get());
- Dart_CObject* root = api_reader.ReadMessage();
+ Dart_CObject* root = ReadApiMessage(scope.zone(), message.get());
EXPECT_NOTNULL(root);
EXPECT_EQ(Dart_CObject_kBool, root->type);
EXPECT_EQ(true, root->value.as_bool);
- CheckEncodeDecodeMessage(root);
+ CheckEncodeDecodeMessage(scope.zone(), root);
}
ISOLATE_UNIT_TEST_CASE(SerializeFalse) {
@@ -320,57 +312,55 @@
// Write snapshot with false object.
const Bool& bl = Bool::False();
- MessageWriter writer(true);
- std::unique_ptr<Message> message =
- writer.WriteMessage(bl, ILLEGAL_PORT, Message::kNormalPriority);
+ std::unique_ptr<Message> message = WriteMessage(
+ /* can_send_any_object */ true, bl, ILLEGAL_PORT,
+ Message::kNormalPriority);
// Read object back from the snapshot.
- MessageSnapshotReader reader(message.get(), thread);
- const Object& serialized_object = Object::Handle(reader.ReadObject());
+ const Object& serialized_object =
+ Object::Handle(ReadMessage(thread, message.get()));
EXPECT(Equals(bl, serialized_object));
// Read object back from the snapshot into a C structure.
ApiNativeScope scope;
- ApiMessageReader api_reader(message.get());
- Dart_CObject* root = api_reader.ReadMessage();
+ Dart_CObject* root = ReadApiMessage(scope.zone(), message.get());
EXPECT_NOTNULL(root);
EXPECT_EQ(Dart_CObject_kBool, root->type);
EXPECT_EQ(false, root->value.as_bool);
- CheckEncodeDecodeMessage(root);
+ CheckEncodeDecodeMessage(scope.zone(), root);
}
ISOLATE_UNIT_TEST_CASE(SerializeCapability) {
// Write snapshot with object content.
const Capability& capability = Capability::Handle(Capability::New(12345));
- MessageWriter writer(true);
std::unique_ptr<Message> message =
- writer.WriteMessage(capability, ILLEGAL_PORT, Message::kNormalPriority);
+ WriteMessage(/* can_send_any_object */ true, capability, ILLEGAL_PORT,
+ Message::kNormalPriority);
// Read object back from the snapshot.
- MessageSnapshotReader reader(message.get(), thread);
Capability& obj = Capability::Handle();
- obj ^= reader.ReadObject();
+ obj ^= ReadMessage(thread, message.get());
EXPECT_EQ(static_cast<uint64_t>(12345), obj.Id());
// Read object back from the snapshot into a C structure.
ApiNativeScope scope;
- ApiMessageReader api_reader(message.get());
- Dart_CObject* root = api_reader.ReadMessage();
+ Dart_CObject* root = ReadApiMessage(scope.zone(), message.get());
EXPECT_NOTNULL(root);
EXPECT_EQ(Dart_CObject_kCapability, root->type);
int64_t id = root->value.as_capability.id;
EXPECT_EQ(12345, id);
- CheckEncodeDecodeMessage(root);
+ CheckEncodeDecodeMessage(scope.zone(), root);
}
#define TEST_ROUND_TRIP_IDENTICAL(object) \
{ \
- MessageWriter writer(true); \
- std::unique_ptr<Message> message = writer.WriteMessage( \
- Object::Handle(object), ILLEGAL_PORT, Message::kNormalPriority); \
- MessageSnapshotReader reader(message.get(), thread); \
- EXPECT(reader.ReadObject() == object); \
+ const Object& before = Object::Handle(object); \
+ std::unique_ptr<Message> message = \
+ WriteMessage(/* can_send_any_object */ true, before, ILLEGAL_PORT, \
+ Message::kNormalPriority); \
+ const Object& after = Object::Handle(ReadMessage(thread, message.get())); \
+ EXPECT(before.ptr() == after.ptr()); \
}
ISOLATE_UNIT_TEST_CASE(SerializeSingletons) {
@@ -393,23 +383,21 @@
EXPECT(Utf8::IsValid(reinterpret_cast<const uint8_t*>(cstr), strlen(cstr)));
// Write snapshot with object content.
String& str = String::Handle(String::New(cstr));
- MessageWriter writer(true);
std::unique_ptr<Message> message =
- writer.WriteMessage(str, ILLEGAL_PORT, Message::kNormalPriority);
+ WriteMessage(/* can_send_any_object */ true, str, ILLEGAL_PORT,
+ Message::kNormalPriority);
// Read object back from the snapshot.
- MessageSnapshotReader reader(message.get(), thread);
String& serialized_str = String::Handle();
- serialized_str ^= reader.ReadObject();
+ serialized_str ^= ReadMessage(thread, message.get());
EXPECT(str.Equals(serialized_str));
// Read object back from the snapshot into a C structure.
ApiNativeScope scope;
- ApiMessageReader api_reader(message.get());
- Dart_CObject* root = api_reader.ReadMessage();
+ Dart_CObject* root = ReadApiMessage(scope.zone(), message.get());
EXPECT_EQ(Dart_CObject_kString, root->type);
EXPECT_STREQ(cstr, root->value.as_string);
- CheckEncodeDecodeMessage(root);
+ CheckEncodeDecodeMessage(scope.zone(), root);
}
ISOLATE_UNIT_TEST_CASE(SerializeString) {
@@ -436,20 +424,18 @@
smi ^= Smi::New(i);
array.SetAt(i, smi);
}
- MessageWriter writer(true);
std::unique_ptr<Message> message =
- writer.WriteMessage(array, ILLEGAL_PORT, Message::kNormalPriority);
+ WriteMessage(/* can_send_any_object */ true, array, ILLEGAL_PORT,
+ Message::kNormalPriority);
// Read object back from the snapshot.
- MessageSnapshotReader reader(message.get(), thread);
Array& serialized_array = Array::Handle();
- serialized_array ^= reader.ReadObject();
+ serialized_array ^= ReadMessage(thread, message.get());
EXPECT(array.CanonicalizeEquals(serialized_array));
// Read object back from the snapshot into a C structure.
ApiNativeScope scope;
- ApiMessageReader api_reader(message.get());
- Dart_CObject* root = api_reader.ReadMessage();
+ Dart_CObject* root = ReadApiMessage(scope.zone(), message.get());
EXPECT_EQ(Dart_CObject_kArray, root->type);
EXPECT_EQ(kArrayLength, root->value.as_array.length);
for (int i = 0; i < kArrayLength; i++) {
@@ -457,7 +443,7 @@
EXPECT_EQ(Dart_CObject_kInt32, element->type);
EXPECT_EQ(i, element->value.as_int32);
}
- CheckEncodeDecodeMessage(root);
+ CheckEncodeDecodeMessage(scope.zone(), root);
}
ISOLATE_UNIT_TEST_CASE(SerializeArrayWithTypeArgument) {
@@ -471,20 +457,18 @@
smi ^= Smi::New(i);
array.SetAt(i, smi);
}
- MessageWriter writer(true);
std::unique_ptr<Message> message =
- writer.WriteMessage(array, ILLEGAL_PORT, Message::kNormalPriority);
+ WriteMessage(/* can_send_any_object */ true, array, ILLEGAL_PORT,
+ Message::kNormalPriority);
// Read object back from the snapshot.
- MessageSnapshotReader reader(message.get(), thread);
Array& serialized_array = Array::Handle();
- serialized_array ^= reader.ReadObject();
+ serialized_array ^= ReadMessage(thread, message.get());
EXPECT(array.CanonicalizeEquals(serialized_array));
// Read object back from the snapshot into a C structure.
ApiNativeScope scope;
- ApiMessageReader api_reader(message.get());
- Dart_CObject* root = api_reader.ReadMessage();
+ Dart_CObject* root = ReadApiMessage(scope.zone(), message.get());
EXPECT_EQ(Dart_CObject_kArray, root->type);
EXPECT_EQ(kArrayLength, root->value.as_array.length);
for (int i = 0; i < kArrayLength; i++) {
@@ -492,7 +476,7 @@
EXPECT_EQ(Dart_CObject_kInt32, element->type);
EXPECT_EQ(i, element->value.as_int32);
}
- CheckEncodeDecodeMessage(root);
+ CheckEncodeDecodeMessage(scope.zone(), root);
}
TEST_CASE(FailSerializeLargeArray) {
@@ -500,7 +484,8 @@
root.type = Dart_CObject_kArray;
root.value.as_array.length = Array::kMaxElements + 1;
root.value.as_array.values = NULL;
- ExpectEncodeFail(&root);
+ ApiNativeScope scope;
+ ExpectEncodeFail(scope.zone(), &root);
}
TEST_CASE(FailSerializeLargeNestedArray) {
@@ -513,7 +498,8 @@
parent.value.as_array.values = values;
child.type = Dart_CObject_kArray;
child.value.as_array.length = Array::kMaxElements + 1;
- ExpectEncodeFail(&parent);
+ ApiNativeScope scope;
+ ExpectEncodeFail(scope.zone(), &parent);
}
TEST_CASE(FailSerializeLargeTypedDataInt8) {
@@ -522,7 +508,8 @@
root.value.as_typed_data.type = Dart_TypedData_kInt8;
root.value.as_typed_data.length =
TypedData::MaxElements(kTypedDataInt8ArrayCid) + 1;
- ExpectEncodeFail(&root);
+ ApiNativeScope scope;
+ ExpectEncodeFail(scope.zone(), &root);
}
TEST_CASE(FailSerializeLargeTypedDataUint8) {
@@ -531,39 +518,40 @@
root.value.as_typed_data.type = Dart_TypedData_kUint8;
root.value.as_typed_data.length =
TypedData::MaxElements(kTypedDataUint8ArrayCid) + 1;
- ExpectEncodeFail(&root);
+ ApiNativeScope scope;
+ ExpectEncodeFail(scope.zone(), &root);
}
TEST_CASE(FailSerializeLargeExternalTypedData) {
Dart_CObject root;
root.type = Dart_CObject_kExternalTypedData;
- root.value.as_typed_data.length =
+ root.value.as_external_typed_data.type = Dart_TypedData_kUint8;
+ root.value.as_external_typed_data.length =
ExternalTypedData::MaxElements(kExternalTypedDataUint8ArrayCid) + 1;
- ExpectEncodeFail(&root);
+ ApiNativeScope scope;
+ ExpectEncodeFail(scope.zone(), &root);
}
ISOLATE_UNIT_TEST_CASE(SerializeEmptyArray) {
// Write snapshot with object content.
const int kArrayLength = 0;
Array& array = Array::Handle(Array::New(kArrayLength));
- MessageWriter writer(true);
std::unique_ptr<Message> message =
- writer.WriteMessage(array, ILLEGAL_PORT, Message::kNormalPriority);
+ WriteMessage(/* can_send_any_object */ true, array, ILLEGAL_PORT,
+ Message::kNormalPriority);
// Read object back from the snapshot.
- MessageSnapshotReader reader(message.get(), thread);
Array& serialized_array = Array::Handle();
- serialized_array ^= reader.ReadObject();
+ serialized_array ^= ReadMessage(thread, message.get());
EXPECT(array.CanonicalizeEquals(serialized_array));
// Read object back from the snapshot into a C structure.
ApiNativeScope scope;
- ApiMessageReader api_reader(message.get());
- Dart_CObject* root = api_reader.ReadMessage();
+ Dart_CObject* root = ReadApiMessage(scope.zone(), message.get());
EXPECT_EQ(Dart_CObject_kArray, root->type);
EXPECT_EQ(kArrayLength, root->value.as_array.length);
EXPECT(root->value.as_array.values == NULL);
- CheckEncodeDecodeMessage(root);
+ CheckEncodeDecodeMessage(scope.zone(), root);
}
ISOLATE_UNIT_TEST_CASE(SerializeByteArray) {
@@ -574,26 +562,24 @@
for (int i = 0; i < kTypedDataLength; i++) {
typed_data.SetUint8(i, i);
}
- MessageWriter writer(true);
std::unique_ptr<Message> message =
- writer.WriteMessage(typed_data, ILLEGAL_PORT, Message::kNormalPriority);
+ WriteMessage(/* can_send_any_object */ true, typed_data, ILLEGAL_PORT,
+ Message::kNormalPriority);
// Read object back from the snapshot.
- MessageSnapshotReader reader(message.get(), thread);
TypedData& serialized_typed_data = TypedData::Handle();
- serialized_typed_data ^= reader.ReadObject();
+ serialized_typed_data ^= ReadMessage(thread, message.get());
EXPECT(serialized_typed_data.IsTypedData());
// Read object back from the snapshot into a C structure.
ApiNativeScope scope;
- ApiMessageReader api_reader(message.get());
- Dart_CObject* root = api_reader.ReadMessage();
+ Dart_CObject* root = ReadApiMessage(scope.zone(), message.get());
EXPECT_EQ(Dart_CObject_kTypedData, root->type);
EXPECT_EQ(kTypedDataLength, root->value.as_typed_data.length);
for (int i = 0; i < kTypedDataLength; i++) {
EXPECT(root->value.as_typed_data.values[i] == i);
}
- CheckEncodeDecodeMessage(root);
+ CheckEncodeDecodeMessage(scope.zone(), root);
}
#define TEST_TYPED_ARRAY(darttype, ctype) \
@@ -606,12 +592,11 @@
for (int i = 0; i < kArrayLength; i++) { \
array.Set##darttype((i * scale), i); \
} \
- MessageWriter writer(true); \
std::unique_ptr<Message> message = \
- writer.WriteMessage(array, ILLEGAL_PORT, Message::kNormalPriority); \
- MessageSnapshotReader reader(message.get(), thread); \
+ WriteMessage(/* can_send_any_object */ true, array, ILLEGAL_PORT, \
+ Message::kNormalPriority); \
TypedData& serialized_array = TypedData::Handle(); \
- serialized_array ^= reader.ReadObject(); \
+ serialized_array ^= ReadMessage(thread, message.get()); \
for (int i = 0; i < kArrayLength; i++) { \
EXPECT_EQ(static_cast<ctype>(i), \
serialized_array.Get##darttype(i* scale)); \
@@ -627,12 +612,11 @@
ExternalTypedData::New(kExternalTypedData##darttype##ArrayCid, \
reinterpret_cast<uint8_t*>(data), length)); \
intptr_t scale = array.ElementSizeInBytes(); \
- MessageWriter writer(true); \
std::unique_ptr<Message> message = \
- writer.WriteMessage(array, ILLEGAL_PORT, Message::kNormalPriority); \
- MessageSnapshotReader reader(message.get(), thread); \
+ WriteMessage(/* can_send_any_object */ true, array, ILLEGAL_PORT, \
+ Message::kNormalPriority); \
ExternalTypedData& serialized_array = ExternalTypedData::Handle(); \
- serialized_array ^= reader.ReadObject(); \
+ serialized_array ^= ReadMessage(thread, message.get()); \
for (int i = 0; i < length; i++) { \
EXPECT_EQ(static_cast<ctype>(data[i]), \
serialized_array.Get##darttype(i* scale)); \
@@ -670,25 +654,23 @@
const int kTypedDataLength = 0;
TypedData& typed_data = TypedData::Handle(
TypedData::New(kTypedDataUint8ArrayCid, kTypedDataLength));
- MessageWriter writer(true);
std::unique_ptr<Message> message =
- writer.WriteMessage(typed_data, ILLEGAL_PORT, Message::kNormalPriority);
+ WriteMessage(/* can_send_any_object */ true, typed_data, ILLEGAL_PORT,
+ Message::kNormalPriority);
// Read object back from the snapshot.
- MessageSnapshotReader reader(message.get(), thread);
TypedData& serialized_typed_data = TypedData::Handle();
- serialized_typed_data ^= reader.ReadObject();
+ serialized_typed_data ^= ReadMessage(thread, message.get());
EXPECT(serialized_typed_data.IsTypedData());
// Read object back from the snapshot into a C structure.
ApiNativeScope scope;
- ApiMessageReader api_reader(message.get());
- Dart_CObject* root = api_reader.ReadMessage();
+ Dart_CObject* root = ReadApiMessage(scope.zone(), message.get());
EXPECT_EQ(Dart_CObject_kTypedData, root->type);
EXPECT_EQ(Dart_TypedData_kUint8, root->value.as_typed_data.type);
EXPECT_EQ(kTypedDataLength, root->value.as_typed_data.length);
EXPECT(root->value.as_typed_data.values == NULL);
- CheckEncodeDecodeMessage(root);
+ CheckEncodeDecodeMessage(scope.zone(), root);
}
VM_UNIT_TEST_CASE(FullSnapshot) {
@@ -790,47 +772,38 @@
Object& obj = Object::Handle(Api::UnwrapHandle(result));
// Serialize the object into a message.
- MessageWriter writer(false);
- return writer.WriteMessage(obj, ILLEGAL_PORT, Message::kNormalPriority);
-}
-
-// Helper function to deserialize the result into a Dart_CObject structure.
-static Dart_CObject* GetDeserialized(Message* message) {
- // Read object back from the snapshot into a C structure.
- ApiMessageReader api_reader(message);
- return api_reader.ReadMessage();
+ return WriteMessage(/* can_send_any_object */ false, obj, ILLEGAL_PORT,
+ Message::kNormalPriority);
}
static void CheckString(Dart_Handle dart_string, const char* expected) {
StackZone zone(Thread::Current());
String& str = String::Handle();
str ^= Api::UnwrapHandle(dart_string);
- MessageWriter writer(false);
std::unique_ptr<Message> message =
- writer.WriteMessage(str, ILLEGAL_PORT, Message::kNormalPriority);
+ WriteMessage(/* can_send_any_object */ false, str, ILLEGAL_PORT,
+ Message::kNormalPriority);
// Read object back from the snapshot into a C structure.
ApiNativeScope scope;
- ApiMessageReader api_reader(message.get());
- Dart_CObject* root = api_reader.ReadMessage();
+ Dart_CObject* root = ReadApiMessage(zone.GetZone(), message.get());
EXPECT_NOTNULL(root);
EXPECT_EQ(Dart_CObject_kString, root->type);
EXPECT_STREQ(expected, root->value.as_string);
- CheckEncodeDecodeMessage(root);
+ CheckEncodeDecodeMessage(zone.GetZone(), root);
}
static void CheckStringInvalid(Dart_Handle dart_string) {
StackZone zone(Thread::Current());
String& str = String::Handle();
str ^= Api::UnwrapHandle(dart_string);
- MessageWriter writer(false);
std::unique_ptr<Message> message =
- writer.WriteMessage(str, ILLEGAL_PORT, Message::kNormalPriority);
+ WriteMessage(/* can_send_any_object */ false, str, ILLEGAL_PORT,
+ Message::kNormalPriority);
// Read object back from the snapshot into a C structure.
ApiNativeScope scope;
- ApiMessageReader api_reader(message.get());
- Dart_CObject* root = api_reader.ReadMessage();
+ Dart_CObject* root = ReadApiMessage(zone.GetZone(), message.get());
EXPECT_NOTNULL(root);
EXPECT_EQ(Dart_CObject_kUnsupported, root->type);
}
@@ -928,18 +901,17 @@
StackZone zone(thread);
Smi& smi = Smi::Handle();
smi ^= Api::UnwrapHandle(smi_result);
- MessageWriter writer(false);
std::unique_ptr<Message> message =
- writer.WriteMessage(smi, ILLEGAL_PORT, Message::kNormalPriority);
+ WriteMessage(/* can_send_any_object */ false, smi, ILLEGAL_PORT,
+ Message::kNormalPriority);
// Read object back from the snapshot into a C structure.
ApiNativeScope scope;
- ApiMessageReader api_reader(message.get());
- Dart_CObject* root = api_reader.ReadMessage();
+ Dart_CObject* root = ReadApiMessage(scope.zone(), message.get());
EXPECT_NOTNULL(root);
EXPECT_EQ(Dart_CObject_kInt32, root->type);
EXPECT_EQ(42, root->value.as_int32);
- CheckEncodeDecodeMessage(root);
+ CheckEncodeDecodeMessage(scope.zone(), root);
}
CheckString(ascii_string_result, "Hello, world!");
CheckString(non_ascii_string_result, "Blåbærgrød");
@@ -1000,20 +972,20 @@
// Generate a list of nulls from Dart code.
std::unique_ptr<Message> message = GetSerialized(lib, "getList");
ApiNativeScope scope;
- Dart_CObject* root = GetDeserialized(message.get());
+ Dart_CObject* root = ReadApiMessage(scope.zone(), message.get());
EXPECT_NOTNULL(root);
EXPECT_EQ(Dart_CObject_kArray, root->type);
EXPECT_EQ(kArrayLength, root->value.as_array.length);
for (int i = 0; i < kArrayLength; i++) {
EXPECT_EQ(Dart_CObject_kNull, root->value.as_array.values[i]->type);
}
- CheckEncodeDecodeMessage(root);
+ CheckEncodeDecodeMessage(scope.zone(), root);
}
{
// Generate a list of ints from Dart code.
std::unique_ptr<Message> message = GetSerialized(lib, "getIntList");
ApiNativeScope scope;
- Dart_CObject* root = GetDeserialized(message.get());
+ Dart_CObject* root = ReadApiMessage(scope.zone(), message.get());
EXPECT_NOTNULL(root);
EXPECT_EQ(Dart_CObject_kArray, root->type);
EXPECT_EQ(kArrayLength, root->value.as_array.length);
@@ -1021,13 +993,13 @@
EXPECT_EQ(Dart_CObject_kInt32, root->value.as_array.values[i]->type);
EXPECT_EQ(i, root->value.as_array.values[i]->value.as_int32);
}
- CheckEncodeDecodeMessage(root);
+ CheckEncodeDecodeMessage(scope.zone(), root);
}
{
// Generate a list of strings from Dart code.
std::unique_ptr<Message> message = GetSerialized(lib, "getStringList");
ApiNativeScope scope;
- Dart_CObject* root = GetDeserialized(message.get());
+ Dart_CObject* root = ReadApiMessage(scope.zone(), message.get());
EXPECT_NOTNULL(root);
EXPECT_EQ(Dart_CObject_kArray, root->type);
EXPECT_EQ(kArrayLength, root->value.as_array.length);
@@ -1042,7 +1014,7 @@
// Generate a list of objects of different types from Dart code.
std::unique_ptr<Message> message = GetSerialized(lib, "getMixedList");
ApiNativeScope scope;
- Dart_CObject* root = GetDeserialized(message.get());
+ Dart_CObject* root = ReadApiMessage(scope.zone(), message.get());
EXPECT_NOTNULL(root);
EXPECT_EQ(Dart_CObject_kArray, root->type);
EXPECT_EQ(kArrayLength, root->value.as_array.length);
@@ -1124,20 +1096,20 @@
// Generate a list of nulls from Dart code.
std::unique_ptr<Message> message = GetSerialized(lib, "getList");
ApiNativeScope scope;
- Dart_CObject* root = GetDeserialized(message.get());
+ Dart_CObject* root = ReadApiMessage(scope.zone(), message.get());
EXPECT_NOTNULL(root);
EXPECT_EQ(Dart_CObject_kArray, root->type);
EXPECT_EQ(kArrayLength, root->value.as_array.length);
for (int i = 0; i < kArrayLength; i++) {
EXPECT_EQ(Dart_CObject_kNull, root->value.as_array.values[i]->type);
}
- CheckEncodeDecodeMessage(root);
+ CheckEncodeDecodeMessage(scope.zone(), root);
}
{
// Generate a list of ints from Dart code.
std::unique_ptr<Message> message = GetSerialized(lib, "getIntList");
ApiNativeScope scope;
- Dart_CObject* root = GetDeserialized(message.get());
+ Dart_CObject* root = ReadApiMessage(scope.zone(), message.get());
EXPECT_NOTNULL(root);
EXPECT_EQ(Dart_CObject_kArray, root->type);
EXPECT_EQ(kArrayLength, root->value.as_array.length);
@@ -1145,13 +1117,13 @@
EXPECT_EQ(Dart_CObject_kInt32, root->value.as_array.values[i]->type);
EXPECT_EQ(i, root->value.as_array.values[i]->value.as_int32);
}
- CheckEncodeDecodeMessage(root);
+ CheckEncodeDecodeMessage(scope.zone(), root);
}
{
// Generate a list of strings from Dart code.
std::unique_ptr<Message> message = GetSerialized(lib, "getStringList");
ApiNativeScope scope;
- Dart_CObject* root = GetDeserialized(message.get());
+ Dart_CObject* root = ReadApiMessage(scope.zone(), message.get());
EXPECT_NOTNULL(root);
EXPECT_EQ(Dart_CObject_kArray, root->type);
EXPECT_EQ(kArrayLength, root->value.as_array.length);
@@ -1166,7 +1138,7 @@
// Generate a list of lists from Dart code.
std::unique_ptr<Message> message = GetSerialized(lib, "getListList");
ApiNativeScope scope;
- Dart_CObject* root = GetDeserialized(message.get());
+ Dart_CObject* root = ReadApiMessage(scope.zone(), message.get());
EXPECT_NOTNULL(root);
EXPECT_EQ(Dart_CObject_kArray, root->type);
EXPECT_EQ(kArrayLength, root->value.as_array.length);
@@ -1185,7 +1157,7 @@
// Generate a list of objects of different types from Dart code.
std::unique_ptr<Message> message = GetSerialized(lib, "getMixedList");
ApiNativeScope scope;
- Dart_CObject* root = GetDeserialized(message.get());
+ Dart_CObject* root = ReadApiMessage(scope.zone(), message.get());
EXPECT_NOTNULL(root);
EXPECT_EQ(Dart_CObject_kArray, root->type);
EXPECT_EQ(kArrayLength, root->value.as_array.length);
@@ -1357,7 +1329,7 @@
// Generate a list of strings from Dart code.
std::unique_ptr<Message> message = GetSerialized(lib, "getStringList");
ApiNativeScope scope;
- Dart_CObject* root = GetDeserialized(message.get());
+ Dart_CObject* root = ReadApiMessage(scope.zone(), message.get());
EXPECT_NOTNULL(root);
EXPECT_EQ(Dart_CObject_kArray, root->type);
EXPECT_EQ(kArrayLength, root->value.as_array.length);
@@ -1372,7 +1344,7 @@
// Generate a list of medium ints from Dart code.
std::unique_ptr<Message> message = GetSerialized(lib, "getMintList");
ApiNativeScope scope;
- Dart_CObject* root = GetDeserialized(message.get());
+ Dart_CObject* root = ReadApiMessage(scope.zone(), message.get());
EXPECT_NOTNULL(root);
EXPECT_EQ(Dart_CObject_kArray, root->type);
EXPECT_EQ(kArrayLength, root->value.as_array.length);
@@ -1387,7 +1359,7 @@
// Generate a list of doubles from Dart code.
std::unique_ptr<Message> message = GetSerialized(lib, "getDoubleList");
ApiNativeScope scope;
- Dart_CObject* root = GetDeserialized(message.get());
+ Dart_CObject* root = ReadApiMessage(scope.zone(), message.get());
EXPECT_NOTNULL(root);
EXPECT_EQ(Dart_CObject_kArray, root->type);
EXPECT_EQ(kArrayLength, root->value.as_array.length);
@@ -1396,8 +1368,6 @@
EXPECT_EQ(3.14, element->value.as_double);
for (int i = 1; i < kArrayLength; i++) {
element = root->value.as_array.values[i];
- // Double values are expected to not be canonicalized in messages.
- EXPECT_NE(root->value.as_array.values[0], element);
EXPECT_EQ(Dart_CObject_kDouble, element->type);
EXPECT_EQ(3.14, element->value.as_double);
}
@@ -1406,7 +1376,7 @@
// Generate a list of Uint8Lists from Dart code.
std::unique_ptr<Message> message = GetSerialized(lib, "getTypedDataList");
ApiNativeScope scope;
- Dart_CObject* root = GetDeserialized(message.get());
+ Dart_CObject* root = ReadApiMessage(scope.zone(), message.get());
EXPECT_NOTNULL(root);
EXPECT_EQ(Dart_CObject_kArray, root->type);
EXPECT_EQ(kArrayLength, root->value.as_array.length);
@@ -1423,7 +1393,7 @@
std::unique_ptr<Message> message =
GetSerialized(lib, "getTypedDataViewList");
ApiNativeScope scope;
- Dart_CObject* root = GetDeserialized(message.get());
+ Dart_CObject* root = ReadApiMessage(scope.zone(), message.get());
EXPECT_NOTNULL(root);
EXPECT_EQ(Dart_CObject_kArray, root->type);
EXPECT_EQ(kArrayLength, root->value.as_array.length);
@@ -1441,7 +1411,7 @@
// Generate a list of objects of different types from Dart code.
std::unique_ptr<Message> message = GetSerialized(lib, "getMixedList");
ApiNativeScope scope;
- Dart_CObject* root = GetDeserialized(message.get());
+ Dart_CObject* root = ReadApiMessage(scope.zone(), message.get());
EXPECT_NOTNULL(root);
EXPECT_EQ(Dart_CObject_kArray, root->type);
EXPECT_EQ(kArrayLength, root->value.as_array.length);
@@ -1458,8 +1428,6 @@
EXPECT_EQ(Dart_CObject_kString, element->type);
EXPECT_STREQ("A", element->value.as_string);
} else {
- // Double values are expected to not be canonicalized in messages.
- EXPECT_NE(root->value.as_array.values[1], element);
EXPECT_EQ(Dart_CObject_kDouble, element->type);
EXPECT_EQ(2.72, element->value.as_double);
}
@@ -1469,7 +1437,7 @@
// Generate a list of objects of different types from Dart code.
std::unique_ptr<Message> message = GetSerialized(lib, "getSelfRefList");
ApiNativeScope scope;
- Dart_CObject* root = GetDeserialized(message.get());
+ Dart_CObject* root = ReadApiMessage(scope.zone(), message.get());
EXPECT_NOTNULL(root);
EXPECT_EQ(Dart_CObject_kArray, root->type);
EXPECT_EQ(kArrayLength, root->value.as_array.length);
@@ -1560,7 +1528,7 @@
// Generate a list of strings from Dart code.
std::unique_ptr<Message> message = GetSerialized(lib, "getStringList");
ApiNativeScope scope;
- Dart_CObject* root = GetDeserialized(message.get());
+ Dart_CObject* root = ReadApiMessage(scope.zone(), message.get());
EXPECT_NOTNULL(root);
EXPECT_EQ(Dart_CObject_kArray, root->type);
EXPECT_EQ(kArrayLength, root->value.as_array.length);
@@ -1575,7 +1543,7 @@
// Generate a list of medium ints from Dart code.
std::unique_ptr<Message> message = GetSerialized(lib, "getMintList");
ApiNativeScope scope;
- Dart_CObject* root = GetDeserialized(message.get());
+ Dart_CObject* root = ReadApiMessage(scope.zone(), message.get());
EXPECT_NOTNULL(root);
EXPECT_EQ(Dart_CObject_kArray, root->type);
EXPECT_EQ(kArrayLength, root->value.as_array.length);
@@ -1590,18 +1558,15 @@
// Generate a list of doubles from Dart code.
std::unique_ptr<Message> message = GetSerialized(lib, "getDoubleList");
ApiNativeScope scope;
- Dart_CObject* root = GetDeserialized(message.get());
+ Dart_CObject* root = ReadApiMessage(scope.zone(), message.get());
EXPECT_NOTNULL(root);
EXPECT_EQ(Dart_CObject_kArray, root->type);
EXPECT_EQ(kArrayLength, root->value.as_array.length);
Dart_CObject* element = root->value.as_array.values[0];
- // Double values are expected to not be canonicalized in messages.
EXPECT_EQ(Dart_CObject_kDouble, element->type);
EXPECT_EQ(3.14, element->value.as_double);
for (int i = 1; i < kArrayLength; i++) {
element = root->value.as_array.values[i];
- // Double values are expected to not be canonicalized in messages.
- EXPECT_NE(root->value.as_array.values[0], element);
EXPECT_EQ(Dart_CObject_kDouble, element->type);
EXPECT_EQ(3.14, element->value.as_double);
}
@@ -1610,7 +1575,7 @@
// Generate a list of Uint8Lists from Dart code.
std::unique_ptr<Message> message = GetSerialized(lib, "getTypedDataList");
ApiNativeScope scope;
- Dart_CObject* root = GetDeserialized(message.get());
+ Dart_CObject* root = ReadApiMessage(scope.zone(), message.get());
EXPECT_NOTNULL(root);
EXPECT_EQ(Dart_CObject_kArray, root->type);
EXPECT_EQ(kArrayLength, root->value.as_array.length);
@@ -1627,7 +1592,7 @@
std::unique_ptr<Message> message =
GetSerialized(lib, "getTypedDataViewList");
ApiNativeScope scope;
- Dart_CObject* root = GetDeserialized(message.get());
+ Dart_CObject* root = ReadApiMessage(scope.zone(), message.get());
EXPECT_NOTNULL(root);
EXPECT_EQ(Dart_CObject_kArray, root->type);
EXPECT_EQ(kArrayLength, root->value.as_array.length);
@@ -1645,7 +1610,7 @@
// Generate a list of objects of different types from Dart code.
std::unique_ptr<Message> message = GetSerialized(lib, "getMixedList");
ApiNativeScope scope;
- Dart_CObject* root = GetDeserialized(message.get());
+ Dart_CObject* root = ReadApiMessage(scope.zone(), message.get());
EXPECT_NOTNULL(root);
EXPECT_EQ(Dart_CObject_kArray, root->type);
EXPECT_EQ(kArrayLength, root->value.as_array.length);
@@ -1662,8 +1627,6 @@
EXPECT_EQ(Dart_CObject_kString, element->type);
EXPECT_STREQ(".", element->value.as_string);
} else {
- // Double values are expected to not be canonicalized in messages.
- EXPECT_NE(root->value.as_array.values[1], element);
EXPECT_EQ(Dart_CObject_kDouble, element->type);
EXPECT_EQ(2.72, element->value.as_double);
}
@@ -1673,7 +1636,7 @@
// Generate a list of objects of different types from Dart code.
std::unique_ptr<Message> message = GetSerialized(lib, "getSelfRefList");
ApiNativeScope scope;
- Dart_CObject* root = GetDeserialized(message.get());
+ Dart_CObject* root = ReadApiMessage(scope.zone(), message.get());
EXPECT_NOTNULL(root);
EXPECT_EQ(Dart_CObject_kArray, root->type);
EXPECT_EQ(kArrayLength, root->value.as_array.length);
@@ -1806,7 +1769,7 @@
// Generate a list of Uint8Lists from Dart code.
std::unique_ptr<Message> message = GetSerialized(lib, "getTypedDataList");
ApiNativeScope scope;
- Dart_CObject* root = GetDeserialized(message.get());
+ Dart_CObject* root = ReadApiMessage(scope.zone(), message.get());
EXPECT_NOTNULL(root);
EXPECT_EQ(Dart_CObject_kArray, root->type);
struct {
@@ -1834,7 +1797,7 @@
std::unique_ptr<Message> message =
GetSerialized(lib, "getTypedDataViewList");
ApiNativeScope scope;
- Dart_CObject* root = GetDeserialized(message.get());
+ Dart_CObject* root = ReadApiMessage(scope.zone(), message.get());
EXPECT_NOTNULL(root);
EXPECT_EQ(Dart_CObject_kArray, root->type);
struct {
@@ -1882,7 +1845,7 @@
std::unique_ptr<Message> message =
GetSerialized(lib, "getMultipleTypedDataViewList");
ApiNativeScope scope;
- Dart_CObject* root = GetDeserialized(message.get());
+ Dart_CObject* root = ReadApiMessage(scope.zone(), message.get());
EXPECT_NOTNULL(root);
EXPECT_EQ(Dart_CObject_kArray, root->type);
struct {
@@ -2009,15 +1972,6 @@
Dart_ExitScope();
}
-ISOLATE_UNIT_TEST_CASE(OmittedObjectEncodingLength) {
- StackZone zone(Thread::Current());
- MessageWriter writer(true);
- writer.WriteInlinedObjectHeader(kOmittedObjectId);
- // For performance, we'd like single-byte headers when ids are omitted.
- // If this starts failing, consider renumbering the snapshot ids.
- EXPECT_EQ(1, writer.BytesWritten());
-}
-
TEST_CASE(IsKernelNegative) {
EXPECT(!Dart_IsKernel(NULL, 0));
diff --git a/runtime/vm/stub_code.h b/runtime/vm/stub_code.h
index bed573a..3eac0b6 100644
--- a/runtime/vm/stub_code.h
+++ b/runtime/vm/stub_code.h
@@ -21,8 +21,6 @@
class Code;
class Isolate;
class ObjectPointerVisitor;
-class SnapshotReader;
-class SnapshotWriter;
DECLARE_FLAG(bool, disassemble_stubs);
diff --git a/runtime/vm/symbols.cc b/runtime/vm/symbols.cc
index ae7d824..673f26e 100644
--- a/runtime/vm/symbols.cc
+++ b/runtime/vm/symbols.cc
@@ -14,7 +14,6 @@
#include "vm/object_store.h"
#include "vm/raw_object.h"
#include "vm/reusable_handles.h"
-#include "vm/snapshot_ids.h"
#include "vm/visitor.h"
namespace dart {
@@ -514,22 +513,4 @@
table.Release();
}
-intptr_t Symbols::LookupPredefinedSymbol(ObjectPtr obj) {
- for (intptr_t i = 1; i < Symbols::kMaxPredefinedId; i++) {
- if (symbol_handles_[i]->ptr() == obj) {
- return (i + kMaxPredefinedObjectIds);
- }
- }
- return kInvalidIndex;
-}
-
-ObjectPtr Symbols::GetPredefinedSymbol(intptr_t object_id) {
- ASSERT(IsPredefinedSymbolId(object_id));
- intptr_t i = (object_id - kMaxPredefinedObjectIds);
- if ((i > kIllegal) && (i < Symbols::kMaxPredefinedId)) {
- return symbol_handles_[i]->ptr();
- }
- return Object::null();
-}
-
} // namespace dart
diff --git a/runtime/vm/symbols.h b/runtime/vm/symbols.h
index 533119d..76d0070 100644
--- a/runtime/vm/symbols.h
+++ b/runtime/vm/symbols.h
@@ -7,7 +7,6 @@
#include "vm/growable_array.h"
#include "vm/object.h"
-#include "vm/snapshot_ids.h"
namespace dart {
@@ -105,6 +104,7 @@
V(ExceptionHandlers, "ExceptionHandlers") \
V(ExceptionParameter, ":exception") \
V(ExceptionVar, ":exception_var") \
+ V(Expando, "Expando") \
V(ExprTemp, ":expr_temp") \
V(ExternalName, "ExternalName") \
V(ExternalOneByteString, "_ExternalOneByteString") \
@@ -415,6 +415,7 @@
V(_objectNoSuchMethod, "_objectNoSuchMethod") \
V(_objectToString, "_objectToString") \
V(_onData, "_onData") \
+ V(_rehash, "_rehash") \
V(_rehashObjects, "_rehashObjects") \
V(_resultOrListeners, "_resultOrListeners") \
V(_runExtension, "_runExtension") \
@@ -698,13 +699,6 @@
template <typename StringType>
static StringPtr NewSymbol(Thread* thread, const StringType& str);
- 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));
- }
-
// 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.
@@ -715,11 +709,8 @@
friend class Dart;
friend class String;
- friend class SnapshotReader;
- friend class SnapshotWriter;
friend class Serializer;
friend class Deserializer;
- friend class ApiMessageReader;
DISALLOW_COPY_AND_ASSIGN(Symbols);
};
diff --git a/runtime/vm/vm_sources.gni b/runtime/vm/vm_sources.gni
index 12f776e..2f21ac1 100644
--- a/runtime/vm/vm_sources.gni
+++ b/runtime/vm/vm_sources.gni
@@ -70,7 +70,6 @@
"dart.cc",
"dart.h",
"dart_api_impl.h",
- "dart_api_message.cc",
"dart_api_message.h",
"dart_api_state.cc",
"dart_api_state.h",
@@ -169,6 +168,8 @@
"message.h",
"message_handler.cc",
"message_handler.h",
+ "message_snapshot.cc",
+ "message_snapshot.h",
"metrics.cc",
"metrics.h",
"native_arguments.h",
@@ -235,7 +236,6 @@
"raw_object.h",
"raw_object_fields.cc",
"raw_object_fields.h",
- "raw_object_snapshot.cc",
"regexp.cc",
"regexp.h",
"regexp_assembler.cc",
@@ -289,7 +289,6 @@
"simulator_arm64.h",
"snapshot.cc",
"snapshot.h",
- "snapshot_ids.h",
"source_report.cc",
"source_report.h",
"stack_frame.cc",
diff --git a/runtime/vm/zone.h b/runtime/vm/zone.h
index 2022c9d..cb45741 100644
--- a/runtime/vm/zone.h
+++ b/runtime/vm/zone.h
@@ -177,6 +177,7 @@
friend class StackZone;
friend class ApiZone;
+ friend class AllocOnlyStackZone;
template <typename T, typename B, typename Allocator>
friend class BaseGrowableArray;
template <typename T, typename B, typename Allocator>
@@ -212,6 +213,23 @@
DISALLOW_IMPLICIT_CONSTRUCTORS(StackZone);
};
+class AllocOnlyStackZone : public ValueObject {
+ public:
+ AllocOnlyStackZone() : zone_() {}
+ ~AllocOnlyStackZone() {
+ // This zone is not linked into the thread, so any handles would not be
+ // visited.
+ ASSERT(zone_.handles()->IsEmpty());
+ }
+
+ Zone* GetZone() { return &zone_; }
+
+ private:
+ Zone zone_;
+
+ DISALLOW_COPY_AND_ASSIGN(AllocOnlyStackZone);
+};
+
inline uword Zone::AllocUnsafe(intptr_t size) {
ASSERT(size >= 0);
// Round up the requested size to fit the alignment.
diff --git a/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/runtime.dart b/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/runtime.dart
index 2cd212a..6ff9de7 100644
--- a/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/runtime.dart
+++ b/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/runtime.dart
@@ -181,8 +181,8 @@
/// A list of functions to reset static fields back to their uninitialized
/// state.
///
-/// This is populated by [defineLazyField] and [LazyJSType] and only contains
-/// fields that have been initialized.
+/// This is populated by [defineLazyField] and only contains fields that have
+/// been initialized.
@notNull
final List<void Function()> _resetFields = JS('', '[]');
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 e48e530..3c0267d 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
@@ -81,6 +81,15 @@
final metadata = JS('', 'Symbol("metadata")');
+/// A javascript Symbol used to store a canonical version of T? on T.
+final _cachedNullable = JS('', 'Symbol("cachedNullable")');
+
+/// A javascript Symbol used to store a canonical version of T* on T.
+final _cachedLegacy = JS('', 'Symbol("cachedLegacy")');
+
+/// A javascript Symbol used to store prior subtype checks and their results.
+final _subtypeCache = JS('', 'Symbol("_subtypeCache")');
+
/// Types in dart are represented internally at runtime as follows.
///
/// - Normal nominal types, produced from classes, are represented
@@ -197,67 +206,17 @@
return JS('', '#', ret);
}
-/// The Dart type that represents a JavaScript class(/constructor) type.
-///
-/// The JavaScript type may not exist, either because it's not loaded yet, or
-/// because it's not available (such as with mocks). To handle this gracefully,
-/// we disable type checks for in these cases, and allow any JS object to work
-/// as if it were an instance of this JS type.
-class LazyJSType extends DartType {
- Function() _getRawJSTypeFn;
- @notNull
- final String _dartName;
- Object? _rawJSType;
-
- LazyJSType(this._getRawJSTypeFn, this._dartName);
-
- toString() {
- var raw = _getRawJSType();
- return raw != null ? typeName(raw) : "JSObject<$_dartName>";
- }
-
- Object? _getRawJSType() {
- var raw = _rawJSType;
- if (raw != null) return raw;
-
- // Try to evaluate the JS type. If this fails for any reason, we'll try
- // again next time.
- // TODO(jmesserly): is it worth trying again? It may create unnecessary
- // overhead, especially if exceptions are being thrown. Also it means the
- // behavior of a given type check can change later on.
- try {
- raw = _getRawJSTypeFn();
- } catch (e) {}
-
- if (raw == null) {
- _warn('Cannot find native JavaScript type ($_dartName) for type check');
- } else {
- _rawJSType = raw;
- JS('', '#.push(() => # = null)', _resetFields, _rawJSType);
- }
- return raw;
- }
-
- Object rawJSTypeForCheck() => _getRawJSType() ?? typeRep<JavaScriptObject>();
-
- @notNull
- @JSExportName('is')
- bool is_T(obj) =>
- obj != null &&
- (_isJsObject(obj) || isSubtypeOf(getReifiedType(obj), this));
-
- @JSExportName('as')
- as_T(obj) => is_T(obj) ? obj : castError(obj, this);
-}
-
-/// An anonymous JS type
+/// Dart type that represents a package:js class type (either anonymous or not).
///
/// For the purposes of subtype checks, these match any JS type.
-class AnonymousJSType extends DartType {
+class PackageJSType extends DartType {
final String _dartName;
- AnonymousJSType(this._dartName);
- toString() => _dartName;
+ PackageJSType(this._dartName);
+ @override
+ String toString() => _dartName;
+
+ @notNull
@JSExportName('is')
bool is_T(obj) =>
obj != null &&
@@ -299,35 +258,25 @@
}
}
-var _lazyJSTypes = JS<Object>('', 'new Map()');
-var _anonymousJSTypes = JS<Object>('', 'new Map()');
+var _packageJSTypes = JS<Object>('', 'new Map()');
-lazyJSType(Function() getJSTypeCallback, String name) {
- var ret = JS('', '#.get(#)', _lazyJSTypes, name);
+packageJSType(String name) {
+ var ret = JS('', '#.get(#)', _packageJSTypes, name);
if (ret == null) {
- ret = LazyJSType(getJSTypeCallback, name);
- JS('', '#.set(#, #)', _lazyJSTypes, name, ret);
+ ret = PackageJSType(name);
+ JS('', '#.set(#, #)', _packageJSTypes, name, ret);
}
return ret;
}
-anonymousJSType(String name) {
- var ret = JS('', '#.get(#)', _anonymousJSTypes, name);
- if (ret == null) {
- ret = AnonymousJSType(name);
- JS('', '#.set(#, #)', _anonymousJSTypes, name, ret);
- }
- return ret;
-}
-
-/// A javascript Symbol used to store a canonical version of T? on T.
-final _cachedNullable = JS('', 'Symbol("cachedNullable")');
-
-/// A javascript Symbol used to store a canonical version of T* on T.
-final _cachedLegacy = JS('', 'Symbol("cachedLegacy")');
-
-/// A javascript Symbol used to store prior subtype checks and their results.
-final _subtypeCache = JS('', 'Symbol("_subtypeCache")');
+/// Since package:js types are all subtypes of each other, we use this var to
+/// denote *some* package:js type in our subtyping logic.
+///
+/// Used only when a concrete PackageJSType is not available i.e. when neither
+/// the object nor the target type is a PackageJSType. Avoids initializating a
+/// new PackageJSType every time. Note that we don't add it to the set of JS
+/// types, since it's not an actual JS class.
+final _pkgJSTypeForSubtyping = PackageJSType('');
/// Returns a nullable (question, ?) version of [type].
///
@@ -1522,34 +1471,20 @@
//
// JavaScriptObject <: package:js types
// package:js types <: JavaScriptObject
- //
- // TODO: This doesn't allow package:js type <: another package:js type yet.
if (${_isInterfaceSubtype(t1, JavaScriptObject, strictMode)}
- && (${_jsInstanceOf(t2, LazyJSType)}
- || ${_jsInstanceOf(t2, AnonymousJSType)}
- // TODO: Since package:js types are instances of LazyJSType and
- // AnonymousJSType, we don't have a mechanism to determine if *some*
- // package:js type implements t2. This will possibly require keeping
- // a map of these relationships for this subtyping check. For now,
- // don't execute the following checks.
- // || _isInterfaceSubtype(LazyJSType, t2, strictMode)
- // || _isInterfaceSubtype(AnonymousJSType, t2, strictMode)
- )) {
+ &&
+ // TODO: Since package:js types are instances of PackageJSType and
+ // we don't have a mechanism to determine if *some* package:js type
+ // implements t2. This will possibly require keeping a map of these
+ // relationships for this subtyping check. For now, this will only
+ // work if t2 is also a PackageJSType.
+ ${_isInterfaceSubtype(_pkgJSTypeForSubtyping, t2, strictMode)}) {
return true;
}
if (${_isInterfaceSubtype(JavaScriptObject, t2, strictMode)}
- && (${_jsInstanceOf(t1, LazyJSType)}
- || ${_jsInstanceOf(t1, AnonymousJSType)}
- // TODO: We don't have a check in `isInterfaceSubtype` to check that
- // a class is a subtype of *some* package:js class. This will likely
- // require modifying `_isInterfaceSubtype` to check if the
- // interfaces of t1 include a package:js type. For now, don't
- // execute the following checks.
- // || _isInterfaceSubtype(t1, LazyJSType, strictMode)
- // || _isInterfaceSubtype(t1, AnonymousJSType, strictMode)
- )) {
+ && ${_isInterfaceSubtype(t1, _pkgJSTypeForSubtyping, strictMode)}) {
return true;
}
@@ -1617,10 +1552,11 @@
})()''');
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();
- if (${_jsInstanceOf(t2, LazyJSType)}) $t2 = $t2.rawJSTypeForCheck();
+ // Instances of PackageJSType are all subtypes of each other.
+ if (${_jsInstanceOf(t1, PackageJSType)}
+ && ${_jsInstanceOf(t2, PackageJSType)}) {
+ return true;
+ }
if ($t1 === $t2) {
return true;
diff --git a/sdk/lib/_internal/vm/lib/expando_patch.dart b/sdk/lib/_internal/vm/lib/expando_patch.dart
index cacbc02..36c65df 100644
--- a/sdk/lib/_internal/vm/lib/expando_patch.dart
+++ b/sdk/lib/_internal/vm/lib/expando_patch.dart
@@ -5,11 +5,12 @@
// part of "core_patch.dart";
@patch
+@pragma("vm:entry-point")
class Expando<T> {
@patch
Expando([String? name])
: name = name,
- _data = new List.filled(_minSize, null),
+ _data = new List<_WeakProperty?>.filled(_minSize, null),
_used = 0;
static const _minSize = 8;
@@ -95,6 +96,7 @@
this[object] = value; // Recursively add the value.
}
+ @pragma("vm:entry-point", "call")
_rehash() {
// Determine the population count of the map to allocate an appropriately
// sized map below.
@@ -119,7 +121,7 @@
// Reset the mappings to empty so that we can just add the existing
// valid entries.
- _data = new List.filled(new_size, null);
+ _data = new List<_WeakProperty?>.filled(new_size, null);
_used = 0;
for (var i = 0; i < old_data.length; i++) {
@@ -149,9 +151,9 @@
}
}
- get _size => _data.length;
- get _limit => (3 * (_size ~/ 4));
+ int get _size => _data.length;
+ int get _limit => (3 * (_size ~/ 4));
- List _data;
+ List<_WeakProperty?> _data;
int _used; // Number of used (active and deleted) slots.
}
diff --git a/sdk/lib/isolate/isolate.dart b/sdk/lib/isolate/isolate.dart
index 3e7a592..8a68d10 100644
--- a/sdk/lib/isolate/isolate.dart
+++ b/sdk/lib/isolate/isolate.dart
@@ -567,10 +567,16 @@
/// Sends an asynchronous [message] through this send port, to its
/// corresponding `ReceivePort`.
///
- /// The content of [message] can be: primitive values
- /// (null, num, bool, double, String), instances of [SendPort],
- /// and lists and maps whose elements are any of these.
- /// List and maps are also allowed to contain cyclic references.
+ /// The content of [message] can be:
+ /// - [Null]
+ /// - [bool]
+ /// - [int]
+ /// - [double]
+ /// - [String]
+ /// - [List] or [Map] (whose elements are any of these)
+ /// - [TransferableTypedData]
+ /// - [SendPort]
+ /// - [Capability]
///
/// In the special circumstances when two isolates share the same code and are
/// running in the same process (e.g. isolates created via [Isolate.spawn]),
diff --git a/tests/dartdevc/debugger/debugger_test_golden.txt b/tests/dartdevc/debugger/debugger_test_golden.txt
index 76772be..a879c6e 100644
--- a/tests/dartdevc/debugger/debugger_test_golden.txt
+++ b/tests/dartdevc/debugger/debugger_test_golden.txt
@@ -6519,7 +6519,7 @@
{
"style": "background-color: #d9edf7;color: black"
},
- "Instance of 'TestGenericClass<JSObject<ExampleJSClass>, int>'"
+ "Instance of 'TestGenericClass<ExampleJSClass, int>'"
]
-----------------------------------
Test: TestGenericClassJSInterop instance body
@@ -6616,7 +6616,7 @@
{
"style": "background-color: #d9edf7;color: black"
},
- "TestGenericClass<JSObject<ExampleJSClass>, int>"
+ "TestGenericClass<ExampleJSClass, int>"
]
-----------------------------------
Test: TestGenericClassJSInterop definition formatting body
diff --git a/tests/dartdevc_2/debugger/debugger_test_golden.txt b/tests/dartdevc_2/debugger/debugger_test_golden.txt
index 76772be..a879c6e 100644
--- a/tests/dartdevc_2/debugger/debugger_test_golden.txt
+++ b/tests/dartdevc_2/debugger/debugger_test_golden.txt
@@ -6519,7 +6519,7 @@
{
"style": "background-color: #d9edf7;color: black"
},
- "Instance of 'TestGenericClass<JSObject<ExampleJSClass>, int>'"
+ "Instance of 'TestGenericClass<ExampleJSClass, int>'"
]
-----------------------------------
Test: TestGenericClassJSInterop instance body
@@ -6616,7 +6616,7 @@
{
"style": "background-color: #d9edf7;color: black"
},
- "TestGenericClass<JSObject<ExampleJSClass>, int>"
+ "TestGenericClass<ExampleJSClass, int>"
]
-----------------------------------
Test: TestGenericClassJSInterop definition formatting body
diff --git a/tests/lib/html/js_typed_interop_lazy_test.dart b/tests/lib/html/js_typed_interop_lazy_test.dart
index 63c578d..1825174 100644
--- a/tests/lib/html/js_typed_interop_lazy_test.dart
+++ b/tests/lib/html/js_typed_interop_lazy_test.dart
@@ -142,10 +142,9 @@
expect(new Object() is! AnonClass2, isTrue);
expect(<AnonClass>[] is List<AnonClass>, isTrue);
- // TODO(jacobr): why doesn't this test pass?
- // expect(<AnonClass>[] is List<AnonClass2>, isTrue);
+ expect(<AnonClass>[] is List<AnonClass2>, isTrue);
expect(<int>[] is! List<AnonClass>, isTrue);
- expect(<AnonClass>[] is! List<LazyClass>, isTrue); //# 01: ok
+ expect(<AnonClass>[] is List<LazyClass>, isTrue);
expect(<int>[] is! List<LazyClass>, isTrue);
expect(<LazyClass>[] is List<LazyClass>, isTrue);
@@ -234,10 +233,9 @@
expect(new Object() is! AnonClass2, isTrue);
expect(<AnonClass>[] is List<AnonClass>, isTrue);
- // TODO(jacobr): why doesn't this test pass?
- // expect(<AnonClass>[] is List<AnonClass2>, isTrue);
+ expect(<AnonClass>[] is List<AnonClass2>, isTrue);
expect(<int>[] is! List<AnonClass>, isTrue);
- expect(<AnonClass>[] is! List<NestedLazyClass>, isTrue); //# 01: ok
+ expect(<AnonClass>[] is List<NestedLazyClass>, isTrue);
expect(<int>[] is! List<NestedLazyClass>, isTrue);
expect(<NestedLazyClass>[] is List<NestedLazyClass>, isTrue);
diff --git a/tests/lib/isolate/type_ref_message_test.dart b/tests/lib/isolate/type_ref_message_test.dart
new file mode 100644
index 0000000..1c47e35
--- /dev/null
+++ b/tests/lib/isolate/type_ref_message_test.dart
@@ -0,0 +1,31 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// See https://github.com/flutter/flutter/issues/84691
+
+import "dart:async";
+import "dart:isolate";
+
+import "package:async_helper/async_helper.dart";
+import "package:expect/expect.dart";
+
+
+class B<T> {}
+class D<S> extends B<D> {}
+
+main() {
+ asyncStart();
+ var port;
+ port = new RawReceivePort((message) {
+ var list = message as List<D<String>>;
+ var element = list[0] as D<String>;
+
+ port.close();
+ asyncEnd();
+ });
+
+
+ var list = <D<String>>[ new D() ];
+ port.sendPort.send(list);
+}
diff --git a/tests/lib/isolate/weak_property_message_1_test.dart b/tests/lib/isolate/weak_property_message_1_test.dart
new file mode 100644
index 0000000..2f4d344
--- /dev/null
+++ b/tests/lib/isolate/weak_property_message_1_test.dart
@@ -0,0 +1,48 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// See https://github.com/dart-lang/sdk/issues/25559
+
+import "dart:async";
+import "dart:isolate";
+
+import "package:async_helper/async_helper.dart";
+import "package:expect/expect.dart";
+
+main() {
+ asyncStart();
+ var port;
+ port = new RawReceivePort((message) {
+ var expando1 = message[0] as Expando;
+ var expando2 = message[1] as Expando;
+ var expando3 = message[2] as Expando;
+ var key1 = message[3];
+
+ var key2 = expando1[key1!];
+ Expect.isNotNull(key2);
+ var key3 = expando2[key2!];
+ Expect.isNotNull(key3);
+ var value = expando3[key3!];
+ Expect.equals(value, "value");
+
+ port.close();
+ asyncEnd();
+ });
+
+
+ var key1 = new Object();
+ var key2 = new Object();
+ var key3 = new Object();
+ var expando1 = new Expando();
+ var expando2 = new Expando();
+ var expando3 = new Expando();
+ expando1[key1] = key2;
+ expando2[key2] = key3;
+ expando3[key3] = "value";
+
+ // key1 is placed after expando1 so that its reachability is uncertain when
+ // expando1 is first encountered.
+ var message = <dynamic>[expando1, expando2, expando3, key1];
+ port.sendPort.send(message);
+}
diff --git a/tests/lib/isolate/weak_property_message_2_test.dart b/tests/lib/isolate/weak_property_message_2_test.dart
new file mode 100644
index 0000000..236bcfe3
--- /dev/null
+++ b/tests/lib/isolate/weak_property_message_2_test.dart
@@ -0,0 +1,34 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// See https://github.com/dart-lang/sdk/issues/25559
+
+import "dart:async";
+import "dart:developer";
+import "dart:isolate";
+
+import "package:async_helper/async_helper.dart";
+import "package:expect/expect.dart";
+
+main() {
+ asyncStart();
+ var port;
+ port = new RawReceivePort((message) {
+ var expando = message as Expando;
+
+ // Sent and received without error.
+
+ port.close();
+ asyncEnd();
+ });
+
+
+ var unwrittenKey = new Object();
+ var expando = new Expando();
+ expando[unwrittenKey] = new UserTag("cant send this");
+
+ port.sendPort.send(expando);
+
+ print(unwrittenKey); // Ensure [unwrittenKey] is live during [send].
+}
diff --git a/tests/lib_2/html/js_typed_interop_lazy_test.dart b/tests/lib_2/html/js_typed_interop_lazy_test.dart
index a7b49a9..918193d 100644
--- a/tests/lib_2/html/js_typed_interop_lazy_test.dart
+++ b/tests/lib_2/html/js_typed_interop_lazy_test.dart
@@ -144,10 +144,9 @@
expect(new Object() is! AnonClass2, isTrue);
expect(<AnonClass>[] is List<AnonClass>, isTrue);
- // TODO(jacobr): why doesn't this test pass?
- // expect(<AnonClass>[] is List<AnonClass2>, isTrue);
+ expect(<AnonClass>[] is List<AnonClass2>, isTrue);
expect(<int>[] is! List<AnonClass>, isTrue);
- expect(<AnonClass>[] is! List<LazyClass>, isTrue); //# 01: ok
+ expect(<AnonClass>[] is List<LazyClass>, isTrue);
expect(<int>[] is! List<LazyClass>, isTrue);
expect(<LazyClass>[] is List<LazyClass>, isTrue);
@@ -236,10 +235,9 @@
expect(new Object() is! AnonClass2, isTrue);
expect(<AnonClass>[] is List<AnonClass>, isTrue);
- // TODO(jacobr): why doesn't this test pass?
- // expect(<AnonClass>[] is List<AnonClass2>, isTrue);
+ expect(<AnonClass>[] is List<AnonClass2>, isTrue);
expect(<int>[] is! List<AnonClass>, isTrue);
- expect(<AnonClass>[] is! List<NestedLazyClass>, isTrue); //# 01: ok
+ expect(<AnonClass>[] is List<NestedLazyClass>, isTrue);
expect(<int>[] is! List<NestedLazyClass>, isTrue);
expect(<NestedLazyClass>[] is List<NestedLazyClass>, isTrue);
diff --git a/tests/lib_2/isolate/type_ref_message_test.dart b/tests/lib_2/isolate/type_ref_message_test.dart
new file mode 100644
index 0000000..8dd2a79
--- /dev/null
+++ b/tests/lib_2/isolate/type_ref_message_test.dart
@@ -0,0 +1,33 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// See https://github.com/flutter/flutter/issues/84691
+
+// @dart = 2.9
+
+import "dart:async";
+import "dart:isolate";
+
+import "package:async_helper/async_helper.dart";
+import "package:expect/expect.dart";
+
+
+class B<T> {}
+class D<S> extends B<D> {}
+
+main() {
+ asyncStart();
+ var port;
+ port = new RawReceivePort((message) {
+ var list = message as List<D<String>>;
+ var element = list[0] as D<String>;
+
+ port.close();
+ asyncEnd();
+ });
+
+
+ var list = <D<String>>[ new D() ];
+ port.sendPort.send(list);
+}
diff --git a/tests/lib_2/isolate/weak_property_message_1_test.dart b/tests/lib_2/isolate/weak_property_message_1_test.dart
new file mode 100644
index 0000000..fa8a6d1
--- /dev/null
+++ b/tests/lib_2/isolate/weak_property_message_1_test.dart
@@ -0,0 +1,50 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// See https://github.com/dart-lang/sdk/issues/25559
+
+// @dart = 2.9
+
+import "dart:async";
+import "dart:isolate";
+
+import "package:async_helper/async_helper.dart";
+import "package:expect/expect.dart";
+
+main() {
+ asyncStart();
+ var port;
+ port = new RawReceivePort((message) {
+ var expando1 = message[0] as Expando;
+ var expando2 = message[1] as Expando;
+ var expando3 = message[2] as Expando;
+ var key1 = message[3];
+
+ var key2 = expando1[key1];
+ Expect.isNotNull(key2);
+ var key3 = expando2[key2];
+ Expect.isNotNull(key3);
+ var value = expando3[key3];
+ Expect.equals(value, "value");
+
+ port.close();
+ asyncEnd();
+ });
+
+
+ var key1 = new Object();
+ var key2 = new Object();
+ var key3 = new Object();
+ var expando1 = new Expando();
+ var expando2 = new Expando();
+ var expando3 = new Expando();
+ expando1[key1] = key2;
+ expando2[key2] = key3;
+ expando3[key3] = "value";
+
+ // key1 is placed after expando1 so that its reachability is uncertain when
+ // expando1 is first encountered.
+ var message = <dynamic>[expando1, expando2, expando3, key1];
+ port.sendPort.send(message);
+}
diff --git a/tests/lib_2/isolate/weak_property_message_2_test.dart b/tests/lib_2/isolate/weak_property_message_2_test.dart
new file mode 100644
index 0000000..7b5ad95
--- /dev/null
+++ b/tests/lib_2/isolate/weak_property_message_2_test.dart
@@ -0,0 +1,36 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// See https://github.com/dart-lang/sdk/issues/25559
+
+// @dart = 2.9
+
+import "dart:async";
+import "dart:developer";
+import "dart:isolate";
+
+import "package:async_helper/async_helper.dart";
+import "package:expect/expect.dart";
+
+main() {
+ asyncStart();
+ var port;
+ port = new RawReceivePort((message) {
+ var expando = message as Expando;
+
+ // Sent and received without error.
+
+ port.close();
+ asyncEnd();
+ });
+
+
+ var unwrittenKey = new Object();
+ var expando = new Expando();
+ expando[unwrittenKey] = new UserTag("cant send this");
+
+ port.sendPort.send(expando);
+
+ print(unwrittenKey); // Ensure [unwrittenKey] is live during [send].
+}
diff --git a/tools/VERSION b/tools/VERSION
index e61aabf..7e3201e 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
MAJOR 2
MINOR 14
PATCH 0
-PRERELEASE 366
+PRERELEASE 367
PRERELEASE_PATCH 0
\ No newline at end of file
diff --git a/tools/make_version.py b/tools/make_version.py
index c99511b..bf2c9c5 100755
--- a/tools/make_version.py
+++ b/tools/make_version.py
@@ -23,7 +23,6 @@
'object.h',
'raw_object.h',
'snapshot.h',
- 'snapshot_ids.h',
'symbols.h',
# Source files.
'clustered_snapshot.cc',
@@ -32,7 +31,6 @@
'image_snapshot.cc',
'object.cc',
'raw_object.cc',
- 'raw_object_snapshot.cc',
'snapshot.cc',
'symbols.cc',
]