OLD | NEW |
1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 /// This is an interface to the Dart Kernel parser and Kernel binary generator. | 5 /// This is an interface to the Dart Kernel parser and Kernel binary generator. |
6 /// | 6 /// |
7 /// It is used by the kernel-isolate to load Dart source code and generate | 7 /// It is used by the kernel-isolate to load Dart source code and generate |
8 /// Kernel binary format. | 8 /// Kernel binary format. |
9 /// | 9 /// |
10 /// This is either invoked as the root script of the Kernel isolate when used | 10 /// This is either invoked as the root script of the Kernel isolate when used |
11 /// as a part of | 11 /// as a part of |
12 /// | 12 /// |
13 /// dart --dfe=utils/kernel-service/kernel-service.dart ... | 13 /// dart --dfe=utils/kernel-service/kernel-service.dart ... |
14 /// | 14 /// |
15 /// invocation or it is invoked as a standalone script to perform training for | 15 /// invocation or it is invoked as a standalone script to perform training for |
16 /// the app-jit snapshot | 16 /// the app-jit snapshot |
17 /// | 17 /// |
18 /// dart utils/kernel-service/kernel-service.dart --train <source-file> | 18 /// dart utils/kernel-service/kernel-service.dart --train <source-file> |
19 /// | 19 /// |
20 /// | 20 /// |
21 library runtime.tools.kernel_service; | 21 library runtime.tools.kernel_service; |
22 | 22 |
23 import 'dart:async'; | 23 import 'dart:async'; |
24 import 'dart:io'; | 24 import 'dart:io' hide FileSystemEntity; |
25 import 'dart:isolate'; | 25 import 'dart:isolate'; |
26 | 26 |
27 import 'package:front_end/file_system.dart'; | 27 import 'package:front_end/file_system.dart'; |
28 import 'package:front_end/memory_file_system.dart'; | 28 import 'package:front_end/memory_file_system.dart'; |
29 import 'package:front_end/physical_file_system.dart'; | 29 import 'package:front_end/physical_file_system.dart'; |
30 import 'package:front_end/src/fasta/vm.dart' | 30 import 'package:front_end/src/fasta/vm.dart' |
31 show CompilationResult, Status, parseScriptInFileSystem; | 31 show CompilationResult, Status, parseScriptInFileSystem; |
32 | 32 |
33 const bool verbose = const bool.fromEnvironment('DFE_VERBOSE'); | 33 const bool verbose = const bool.fromEnvironment('DFE_VERBOSE'); |
34 | 34 |
(...skipping 27 matching lines...) Expand all Loading... |
62 if (verbose) { | 62 if (verbose) { |
63 print("DFE: request: $request"); | 63 print("DFE: request: $request"); |
64 print("DFE: Platform.packageConfig: ${Platform.packageConfig}"); | 64 print("DFE: Platform.packageConfig: ${Platform.packageConfig}"); |
65 print("DFE: Platform.resolvedExecutable: ${Platform.resolvedExecutable}"); | 65 print("DFE: Platform.resolvedExecutable: ${Platform.resolvedExecutable}"); |
66 } | 66 } |
67 | 67 |
68 int tag = request[0]; | 68 int tag = request[0]; |
69 final SendPort port = request[1]; | 69 final SendPort port = request[1]; |
70 final String inputFileUrl = request[2]; | 70 final String inputFileUrl = request[2]; |
71 FileSystem fileSystem = request.length > 3 | 71 FileSystem fileSystem = request.length > 3 |
72 ? _buildMemoryFileSystem(request[3]) | 72 ? _buildFileSystem(request[3]) |
73 : PhysicalFileSystem.instance; | 73 : PhysicalFileSystem.instance; |
74 | 74 |
75 CompilationResult result; | 75 CompilationResult result; |
76 try { | 76 try { |
77 result = await _processLoadRequestImpl(inputFileUrl, fileSystem); | 77 result = await _processLoadRequestImpl(inputFileUrl, fileSystem); |
78 } catch (error, stack) { | 78 } catch (error, stack) { |
79 result = new CompilationResult.crash(error, stack); | 79 result = new CompilationResult.crash(error, stack); |
80 } | 80 } |
81 | 81 |
82 if (verbose) { | 82 if (verbose) { |
83 print("DFE:> ${result}"); | 83 print("DFE:> ${result}"); |
84 } | 84 } |
85 | 85 |
86 // Check whether this is a Loader request or a bootstrapping request from | 86 // Check whether this is a Loader request or a bootstrapping request from |
87 // KernelIsolate::CompileToKernel. | 87 // KernelIsolate::CompileToKernel. |
88 final isBootstrapRequest = tag == null; | 88 final isBootstrapRequest = tag == null; |
89 if (isBootstrapRequest) { | 89 if (isBootstrapRequest) { |
90 port.send(result.toResponse()); | 90 port.send(result.toResponse()); |
91 } else { | 91 } else { |
92 // See loader.cc for the code that handles these replies. | 92 // See loader.cc for the code that handles these replies. |
93 if (result.status != Status.ok) { | 93 if (result.status != Status.ok) { |
94 tag = -tag; | 94 tag = -tag; |
95 } | 95 } |
96 port.send([tag, inputFileUrl, inputFileUrl, null, result.payload]); | 96 port.send([tag, inputFileUrl, inputFileUrl, null, result.payload]); |
97 } | 97 } |
98 } | 98 } |
99 | 99 |
100 // Given namedSources list of interleaved file name string and | 100 /// Creates a file system containing the files specified in [namedSources] and |
101 // raw file content Uint8List this function builds up and returns | 101 /// that delegates to the underlying file system for any other file request. |
102 // MemoryFileSystem instance that can be used instead of | 102 /// The [namedSources] list interleaves file name string and |
103 // PhysicalFileSystem.instance by the frontend. | 103 /// raw file content Uint8List. |
104 MemoryFileSystem _buildMemoryFileSystem(List namedSources) { | 104 /// |
| 105 /// The result can be used instead of PhysicalFileSystem.instance by the |
| 106 /// frontend. |
| 107 FileSystem _buildFileSystem(List namedSources) { |
105 MemoryFileSystem fileSystem = new MemoryFileSystem(Uri.parse('file:///')); | 108 MemoryFileSystem fileSystem = new MemoryFileSystem(Uri.parse('file:///')); |
106 for (int i = 0; i < namedSources.length ~/ 2; i++) { | 109 for (int i = 0; i < namedSources.length ~/ 2; i++) { |
107 fileSystem | 110 fileSystem |
108 .entityForUri(Uri.parse(namedSources[i * 2])) | 111 .entityForUri(Uri.parse(namedSources[i * 2])) |
109 .writeAsBytesSync(namedSources[i * 2 + 1]); | 112 .writeAsBytesSync(namedSources[i * 2 + 1]); |
110 } | 113 } |
111 return fileSystem; | 114 return new HybridFileSystem(fileSystem); |
| 115 } |
| 116 |
| 117 /// A file system that mixes files from memory and a physical file system. All |
| 118 /// memory entities take priotity over file system entities. |
| 119 class HybridFileSystem implements FileSystem { |
| 120 final MemoryFileSystem memory; |
| 121 final PhysicalFileSystem physical = PhysicalFileSystem.instance; |
| 122 |
| 123 HybridFileSystem(this.memory); |
| 124 |
| 125 @override |
| 126 FileSystemEntity entityForUri(Uri uri) => new HybridFileSystemEntity( |
| 127 memory.entityForUri(uri), physical.entityForUri(uri)); |
| 128 } |
| 129 |
| 130 /// Entity that delegates to an underlying memory or phisical file system |
| 131 /// entity. |
| 132 class HybridFileSystemEntity implements FileSystemEntity { |
| 133 final FileSystemEntity memory; |
| 134 final FileSystemEntity physical; |
| 135 |
| 136 HybridFileSystemEntity(this.memory, this.physical); |
| 137 |
| 138 FileSystemEntity _delegate; |
| 139 Future<FileSystemEntity> get delegate async { |
| 140 return _delegate ??= (await memory.exists()) ? memory : physical; |
| 141 } |
| 142 |
| 143 @override |
| 144 Uri get uri => memory.uri; |
| 145 |
| 146 @override |
| 147 Future<bool> exists() async => (await delegate).exists(); |
| 148 |
| 149 @override |
| 150 Future<DateTime> lastModified() async => (await delegate).lastModified(); |
| 151 |
| 152 @override |
| 153 Future<List<int>> readAsBytes() async => (await delegate).readAsBytes(); |
| 154 |
| 155 @override |
| 156 Future<String> readAsString() async => (await delegate).readAsString(); |
112 } | 157 } |
113 | 158 |
114 train(String scriptUri) { | 159 train(String scriptUri) { |
115 // TODO(28532): Enable on Windows. | 160 // TODO(28532): Enable on Windows. |
116 if (Platform.isWindows) return; | 161 if (Platform.isWindows) return; |
117 | 162 |
118 var tag = 1; | 163 var tag = 1; |
119 var responsePort = new RawReceivePort(); | 164 var responsePort = new RawReceivePort(); |
120 responsePort.handler = (response) { | 165 responsePort.handler = (response) { |
121 if (response[0] == tag) { | 166 if (response[0] == tag) { |
(...skipping 13 matching lines...) Expand all Loading... |
135 main([args]) { | 180 main([args]) { |
136 if (args?.length == 2 && args[0] == '--train') { | 181 if (args?.length == 2 && args[0] == '--train') { |
137 // This entry point is used when creating an app snapshot. The argument | 182 // This entry point is used when creating an app snapshot. The argument |
138 // provides a script to compile to warm-up generated code. | 183 // provides a script to compile to warm-up generated code. |
139 train(args[1]); | 184 train(args[1]); |
140 } else { | 185 } else { |
141 // Entry point for the Kernel isolate. | 186 // Entry point for the Kernel isolate. |
142 return new RawReceivePort()..handler = _processLoadRequest; | 187 return new RawReceivePort()..handler = _processLoadRequest; |
143 } | 188 } |
144 } | 189 } |
OLD | NEW |