[kernel] Recursively number constants, avoid swallowing exceptions

Change-Id: Ie4beed397a2632e7dde9b93a9f09aa658bf4b585
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/114841
Commit-Queue: Martin Kustermann <kustermann@google.com>
Reviewed-by: Jens Johansen <jensj@google.com>
This commit is contained in:
Martin Kustermann 2019-09-02 16:20:46 +00:00 committed by commit-bot@chromium.org
parent 4b5893f9cf
commit 97b1c64efb
4 changed files with 99 additions and 33 deletions

View file

@ -208,6 +208,8 @@ demands
demangle
demangled
deps
dereferenced
dereferencing
descent
deserializer
deserializers

View file

@ -6070,10 +6070,11 @@ class TearOffConstant extends Constant {
return '${runtimeType}(${procedure})';
}
int get hashCode => procedure.hashCode;
int get hashCode => procedureReference.hashCode;
bool operator ==(Object other) {
return other is TearOffConstant && other.procedure == procedure;
return other is TearOffConstant &&
other.procedureReference == procedureReference;
}
FunctionType getType(TypeEnvironment types) =>

View file

@ -8,8 +8,6 @@ import 'dart:core' as core show MapEntry;
import 'dart:convert' show json;
import 'package:kernel/type_environment.dart' show TypeEnvironment;
import '../ast.dart';
import '../import_table.dart';
@ -27,49 +25,48 @@ class NormalNamer<T> extends Namer<T> {
NormalNamer(this.prefix);
}
class FakePrintingConstant extends Constant {
final String id;
FakePrintingConstant(this.id);
@override
accept(ConstantVisitor v) {}
@override
acceptReference(Visitor v) {}
@override
DartType getType(TypeEnvironment types) => null;
@override
void visitChildren(Visitor v) {}
@override
String toString() {
return "FakePrintingConstant[$id]";
}
}
class ConstantNamer extends RecursiveVisitor<Null> with Namer<Constant> {
final String prefix;
ConstantNamer(this.prefix);
String getName(Constant constant) {
try {
if (!map.containsKey(constant)) {
if (!map.containsKey(constant)) {
// When printing a non-fully linked kernel AST (i.e. some [Reference]s
// are not bound) to text, we need to avoid dereferencing any
// references.
//
// The normal visitor API causes references to be dereferenced in order
// to call the `visit<name>(<name>)` / `visit<name>Reference(<name>)`.
//
// We therefore handle any subclass of [Constant] which has [Reference]s
// specially here.
//
if (constant is InstanceConstant) {
// Avoid visiting `InstanceConstant.classReference`.
for (final value in constant.fieldValues.values) {
// Name everything in post-order visit of DAG.
getName(value);
}
} else if (constant is TearOffConstant) {
// We only care about naming the constants themselves. [TearOffConstant]
// has no Constant children.
// Avoid visiting `TearOffConstant.procedureReference`.
} else {
// Name everything in post-order visit of DAG.
constant.visitChildren(this);
}
return super.getName(constant);
} catch (e) {
// Partial dill. Name anyway.
String id = "${constant.runtimeType.toString()}";
return super.getName(new FakePrintingConstant(id));
}
return super.getName(constant);
}
defaultConstantReference(Constant constant) {
getName(constant);
}
defaultDartType(DartType type) {
// No need to recurse into dart types, we only care about naming the
// constants themselves.
}
}
class Disambiguator<T, U> {

View file

@ -0,0 +1,66 @@
// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
import 'dart:io';
import 'package:args/args.dart';
import 'package:expect/expect.dart';
import 'package:kernel/kernel.dart';
import 'package:kernel/binary/limited_ast_to_binary.dart';
import 'package:vm/kernel_front_end.dart';
main() async {
final outDir =
Directory.systemTemp.createTempSync("incremental_load_from_dill_test");
final dillFile = outDir.uri.resolve("dart2js.dart.dill").toFilePath();
final unlinkedDillFile =
outDir.uri.resolve("dart2js.dart.unlinked.dill").toFilePath();
final unlinkedDillTxtFile =
outDir.uri.resolve("dart2js.dart.unlinked dill.txt").toFilePath();
final executable = Platform.executable;
if (!executable.endsWith('out/ReleaseX64/dart')) {
return;
}
final platformDill = Uri.parse(executable).resolve('vm_platform.dill');
try {
final arguments = <String>[
'--no-link-platform',
'--platform=$platformDill',
'--output=$dillFile',
'pkg/compiler/lib/src/dart2js.dart',
];
// Compile dart2js.dart.
final ArgParser argParser = createCompilerArgParser();
final int exitCode =
await runCompiler(argParser.parse(arguments), '<usage>');
Expect.equals(0, exitCode);
// Load the dart2js.dart.dill and write the unlinked version.
final component = loadComponentFromBinary(dillFile);
final IOSink sink = new File(unlinkedDillFile).openWrite();
final printer = new LimitedBinaryPrinter(
sink, (lib) => lib.importUri.scheme != 'dart', false);
printer.writeComponentFile(component);
await sink.close();
// Ensure we can load the unlinked dill file and ensure it doesn't include
// core libraries.
final unlinkedComponent = loadComponentFromBinary(unlinkedDillFile);
final coreLibraryCount = unlinkedComponent.libraries
.where(
(lib) => lib.importUri.scheme == 'dart' && lib.members.isNotEmpty)
.length;
Expect.equals(0, coreLibraryCount);
// Ensure we can print the unlinked kernel to text.
writeComponentToText(unlinkedComponent, path: unlinkedDillTxtFile);
} finally {
outDir.deleteSync(recursive: true);
}
}