Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(306)

Unified Diff: pkg/compiler/lib/src/library_loader.dart

Issue 2797443008: Reapply "Add "load from .dill" file capability and run a white-box test."" (Closed)
Patch Set: take two Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « pkg/compiler/lib/src/kernel/world_builder.dart ('k') | pkg/compiler/lib/src/options.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: pkg/compiler/lib/src/library_loader.dart
diff --git a/pkg/compiler/lib/src/library_loader.dart b/pkg/compiler/lib/src/library_loader.dart
index 15a013d54427a5bd6be139dabc7441e852c40ef4..0903f6e84aaf494005a61d4150989ddd4230f410 100644
--- a/pkg/compiler/lib/src/library_loader.dart
+++ b/pkg/compiler/lib/src/library_loader.dart
@@ -16,6 +16,7 @@ import 'elements/elements.dart'
ImportElement,
ExportElement,
LibraryElement;
+import 'elements/entities.dart' show LibraryEntity;
import 'elements/modelx.dart'
show
CompilationUnitElementX,
@@ -29,6 +30,7 @@ import 'elements/modelx.dart'
SyntheticImportElement;
import 'enqueue.dart' show DeferredAction;
import 'environment.dart';
+import 'kernel/world_builder.dart' show KernelWorldBuilder;
import 'patch_parser.dart' show PatchParserTask;
import 'resolved_uri_translator.dart';
import 'script.dart';
@@ -36,6 +38,9 @@ import 'serialization/serialization.dart' show LibraryDeserializer;
import 'tree/tree.dart';
import 'util/util.dart' show Link, LinkBuilder;
+import 'package:kernel/ast.dart' as ir;
+import 'package:kernel/binary/ast_from_binary.dart' show BinaryBuilder;
+
typedef Future<Iterable<LibraryElement>> ReuseLibrariesFunction(
Iterable<LibraryElement> libraries);
@@ -137,18 +142,32 @@ typedef Uri PatchResolverFunction(String dartLibraryPath);
*/
abstract class LibraryLoaderTask implements LibraryProvider, CompilerTask {
factory LibraryLoaderTask(
- ResolvedUriTranslator uriTranslator,
- ScriptLoader scriptLoader,
- ElementScanner scriptScanner,
- LibraryDeserializer deserializer,
- PatchResolverFunction patchResolverFunc,
- PatchParserTask patchParser,
- Environment environment,
- DiagnosticReporter reporter,
- Measurer measurer) = _LibraryLoaderTask;
+ bool loadFromDillFile,
+ ResolvedUriTranslator uriTranslator,
+ ScriptLoader scriptLoader,
+ ElementScanner scriptScanner,
+ LibraryDeserializer deserializer,
+ PatchResolverFunction patchResolverFunc,
+ PatchParserTask patchParser,
+ Environment environment,
+ DiagnosticReporter reporter,
+ Measurer measurer) =>
+ loadFromDillFile
+ ? new _DillLibraryLoaderTask(
+ uriTranslator, scriptLoader, reporter, measurer)
+ : new _LibraryLoaderTask(
+ uriTranslator,
+ scriptLoader,
+ scriptScanner,
+ deserializer,
+ patchResolverFunc,
+ patchParser,
+ environment,
+ reporter,
+ measurer);
/// Returns all libraries that have been loaded.
- Iterable<LibraryElement> get libraries;
+ Iterable<LibraryEntity> get libraries;
/// Loads the library specified by the [resolvedUri] and returns the
/// [LoadedLibraries] that were loaded to load the specified uri. The
@@ -218,7 +237,7 @@ abstract class LibraryLoaderTask implements LibraryProvider, CompilerTask {
// TODO(johnniwinther): Use this to integrate deserialized libraries better.
abstract class LibraryProvider {
/// Looks up the library with the [canonicalUri].
- LibraryElement lookupLibrary(Uri canonicalUri);
+ LibraryEntity lookupLibrary(Uri canonicalUri);
}
/// Handle for creating synthesized/patch libraries during library loading.
@@ -372,9 +391,9 @@ class _LibraryLoaderTask extends CompilerTask implements LibraryLoaderTask {
final Map<String, LibraryElement> libraryNames =
new Map<String, LibraryElement>();
- Iterable<LibraryElement> get libraries => libraryCanonicalUriMap.values;
+ Iterable<LibraryEntity> get libraries => libraryCanonicalUriMap.values;
- LibraryElement lookupLibrary(Uri canonicalUri) {
+ LibraryEntity lookupLibrary(Uri canonicalUri) {
return libraryCanonicalUriMap[canonicalUri];
}
@@ -472,7 +491,7 @@ class _LibraryLoaderTask extends CompilerTask implements LibraryLoaderTask {
return reporter.withCurrentElement(library, () {
return measure(() {
handler.computeExports();
- return new _LoadedLibraries(library, handler.newLibraries, this);
+ return new _LoadedLibraries(library, handler.newLibraries);
});
});
});
@@ -811,6 +830,89 @@ class _LibraryLoaderTask extends CompilerTask implements LibraryLoaderTask {
}
}
+/// A task for loading a pre-processed .dill file into memory rather than
+/// parsing Dart source. Use of this task only makes sense when used in
+/// conjunction with --use-kernel.
+class _DillLibraryLoaderTask extends CompilerTask implements LibraryLoaderTask {
+ final DiagnosticReporter reporter;
+
+ final ResolvedUriTranslator uriTranslator;
+
+ /// Loads the contents of a script file (a .dart file). Used when loading
+ /// libraries from source.
+ final ScriptLoader scriptLoader;
+
+ /// Holds the mapping of Kernel IR to KElements that is constructed as a
+ /// result of loading a program.
+ KernelWorldBuilder _worldBuilder;
+
+ List<LibraryEntity> _allLoadedLibraries;
+
+ _DillLibraryLoaderTask(
+ this.uriTranslator, this.scriptLoader, this.reporter, Measurer measurer)
+ : _allLoadedLibraries = new List<LibraryEntity>(),
+ super(measurer);
+
+ /// Loads an entire Kernel [Program] from a file on disk (note, not just a
+ /// library, so this name is actuall a bit of a misnomer).
+ // TODO(efortuna): Rename this once the Element library loader class goes
+ // away.
+ Future<LoadedLibraries> loadLibrary(Uri resolvedUri,
+ {bool skipFileWithPartOfTag: false}) {
+ assert(resolvedUri.pathSegments.last.endsWith('.dill'));
+ Uri readableUri = uriTranslator.translate(null, resolvedUri, null);
+ return measure(() async {
+ Script script = await scriptLoader.readScript(readableUri, null);
+ ir.Program program = new ir.Program();
+ // Hack because the existing file has a terminating 0 and the
+ // BinaryBuilder doesn't expect that.
+ var bytes = new List<int>.from(script.file.slowUtf8ZeroTerminatedBytes());
+ bytes.removeLast();
+ new BinaryBuilder(bytes).readProgram(program);
+ return measure(() {
+ _worldBuilder = new KernelWorldBuilder(reporter, program);
+ program.libraries.forEach((ir.Library library) => _allLoadedLibraries
+ .add(_worldBuilder.lookupLibrary(library.importUri)));
+ // TODO(efortuna): Handle `prgram.mainMethod == null` gracefully.
+ return new _LoadedLibrariesAdapter(
+ _worldBuilder
+ .lookupLibrary(program.mainMethod.enclosingLibrary.importUri),
+ _allLoadedLibraries,
+ _worldBuilder);
+ });
+ });
+ }
+
+ KernelWorldBuilder get worldBuilder => _worldBuilder;
+
+ void reset({bool reuseLibrary(LibraryElement library)}) {
+ throw new UnimplementedError('_DillLibraryLoaderTask.reset');
+ }
+
+ Future resetAsync(Future<bool> reuseLibrary(LibraryElement library)) {
+ throw new UnimplementedError('_DillLibraryLoaderTask.resetAsync');
+ }
+
+ Iterable<LibraryEntity> get libraries => _allLoadedLibraries;
+
+ LibraryEntity lookupLibrary(Uri canonicalUri) {
+ return _worldBuilder?.lookupLibrary(canonicalUri);
+ }
+
+ Future<Null> resetLibraries(ReuseLibrariesFunction reuseLibraries) {
+ throw new UnimplementedError('_DillLibraryLoaderTask.reuseLibraries');
+ }
+
+ void registerDeferredAction(DeferredAction action) {
+ throw new UnimplementedError(
+ '_DillLibraryLoaderTask.registerDeferredAction');
+ }
+
+ Iterable<DeferredAction> pullDeferredActions() {
+ throw new UnimplementedError('_DillLibraryLoaderTask.pullDeferredActions');
+ }
+}
+
/// A state machine for checking script tags come in the correct order.
class TagState {
/// Initial state.
@@ -1382,16 +1484,16 @@ class LibraryDependencyHandler implements LibraryLoader {
abstract class LoadedLibraries {
/// The accesss the library object created corresponding to the library
/// passed to [LibraryLoader.loadLibrary].
- LibraryElement get rootLibrary;
+ LibraryEntity get rootLibrary;
/// Returns `true` if a library with canonical [uri] was loaded in this bulk.
bool containsLibrary(Uri uri);
/// Returns the library with canonical [uri] that was loaded in this bulk.
- LibraryElement getLibrary(Uri uri);
+ LibraryEntity getLibrary(Uri uri);
/// Applies all libraries in this bulk to [f].
- void forEachLibrary(f(LibraryElement library));
+ void forEachLibrary(f(LibraryEntity library));
/// Applies all imports chains of [uri] in this bulk to [callback].
///
@@ -1406,12 +1508,11 @@ abstract class LoadedLibraries {
}
class _LoadedLibraries implements LoadedLibraries {
- final _LibraryLoaderTask task;
final LibraryElement rootLibrary;
final Map<Uri, LibraryElement> loadedLibraries = <Uri, LibraryElement>{};
final List<LibraryElement> _newLibraries;
- _LoadedLibraries(this.rootLibrary, this._newLibraries, this.task) {
+ _LoadedLibraries(this.rootLibrary, this._newLibraries) {
_newLibraries.forEach((LibraryElement loadedLibrary) {
loadedLibraries[loadedLibrary.canonicalUri] = loadedLibrary;
});
@@ -1504,6 +1605,32 @@ class _LoadedLibraries implements LoadedLibraries {
String toString() => 'root=$rootLibrary,libraries=${_newLibraries}';
}
+/// Adapter class to mimic the behavior of LoadedLibraries for Kernel element
+/// behavior. Ultimately we'll just access worldBuilder instead.
+class _LoadedLibrariesAdapter implements LoadedLibraries {
+ final LibraryEntity rootLibrary;
+ final List<LibraryEntity> _newLibraries;
+ final KernelWorldBuilder worldBuilder;
+
+ _LoadedLibrariesAdapter(
+ this.rootLibrary, this._newLibraries, this.worldBuilder) {
+ assert(rootLibrary != null);
+ }
+
+ bool containsLibrary(Uri uri) => getLibrary(uri) != null;
+
+ LibraryEntity getLibrary(Uri uri) => worldBuilder.lookupLibrary(uri);
+
+ void forEachLibrary(f(LibraryEntity library)) => _newLibraries.forEach(f);
+
+ void forEachImportChain(Uri uri,
+ {bool callback(Link<Uri> importChainReversed)}) {
+ // Currently a no-op. This seems wrong.
+ }
+
+ String toString() => 'root=$rootLibrary,libraries=${_newLibraries}';
+}
+
// TODO(sigmund): remove ScriptLoader & ElementScanner. Such abstraction seems
// rather low-level. It might be more practical to split the library-loading
// task itself. The task would continue to do the work of recursively loading
« no previous file with comments | « pkg/compiler/lib/src/kernel/world_builder.dart ('k') | pkg/compiler/lib/src/options.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698