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

Side by Side Diff: utils/kernel-service/kernel-service.dart

Issue 2738253003: Move most of kernel-service.dart to package:front_end. (Closed)
Patch Set: Move vm.dart to fasta directory to avoid changning subpackage_relationships_test until the API has … Created 3 years, 9 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 unified diff | Download patch
« no previous file with comments | « pkg/front_end/lib/src/fasta/vm.dart ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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';
25 import 'dart:isolate'; 25 import 'dart:isolate';
26 import 'dart:typed_data';
27 26
28 import 'package:kernel/binary/ast_to_binary.dart'; 27 import 'package:front_end/src/fasta/vm.dart'
29 import 'package:kernel/kernel.dart'; 28 show CompilationResult, Status, parseScript;
30 import 'package:kernel/target/targets.dart';
31
32 import 'package:front_end/src/fasta/dill/dill_target.dart' show DillTarget;
33 import 'package:front_end/src/fasta/translate_uri.dart' show TranslateUri;
34 import 'package:front_end/src/fasta/ticker.dart' show Ticker;
35 import 'package:front_end/src/fasta/kernel/kernel_target.dart'
36 show KernelTarget;
37 import 'package:front_end/src/fasta/errors.dart' show InputError;
38 29
39 const bool verbose = const bool.fromEnvironment('DFE_VERBOSE'); 30 const bool verbose = const bool.fromEnvironment('DFE_VERBOSE');
40 31
41 class DataSink implements Sink<List<int>> { 32 Future<CompilationResult> _processLoadRequestImpl(String inputFilePathOrUri) {
42 final BytesBuilder builder = new BytesBuilder(); 33 Uri scriptUri = Uri.parse(inputFilePathOrUri);
43
44 void add(List<int> data) {
45 builder.add(data);
46 }
47
48 void close() {
49 // Nothing to do.
50 }
51 }
52
53 // Note: these values must match Dart_KernelCompilationStatus in dart_api.h.
54 const int STATUS_OK = 0; // Compilation was successful.
55 const int STATUS_ERROR = 1; // Compilation failed with a compile time error.
56 const int STATUS_CRASH = 2; // Compiler crashed.
57
58 abstract class CompilationResult {
59 List toResponse();
60 }
61
62 class CompilationOk extends CompilationResult {
63 final Uint8List binary;
64
65 CompilationOk(this.binary);
66
67 List toResponse() => [STATUS_OK, binary];
68
69 String toString() => "CompilationOk(${binary.length} bytes)";
70 }
71
72 abstract class CompilationFail extends CompilationResult {
73 String get errorString;
74 }
75
76 class CompilationError extends CompilationFail {
77 final List<String> errors;
78
79 CompilationError(this.errors);
80
81 List toResponse() => [STATUS_ERROR, errorString];
82
83 String get errorString => errors.take(10).join('\n');
84
85 String toString() => "CompilationError(${errorString})";
86 }
87
88 class CompilationCrash extends CompilationFail {
89 final String exception;
90 final String stack;
91
92 CompilationCrash(this.exception, this.stack);
93
94 List toResponse() => [STATUS_CRASH, errorString];
95
96 String get errorString => "${exception}\n${stack}";
97
98 String toString() => "CompilationCrash(${errorString})";
99 }
100
101 Future<CompilationResult> parseScriptImpl(
102 Uri fileName, String packageConfig, String sdkPath) async {
103 if (!FileSystemEntity.isFileSync(fileName.path)) {
104 throw "Input file '${fileName.path}' does not exist.";
105 }
106
107 if (!FileSystemEntity.isDirectorySync(sdkPath)) {
108 throw "Patched sdk directory not found at $sdkPath";
109 }
110
111 Target target = getTarget("vm", new TargetFlags(strongMode: false));
112
113 Program program;
114 final uriTranslator =
115 await TranslateUri.parse(null, new Uri.file(packageConfig));
116 final Ticker ticker = new Ticker(isVerbose: verbose);
117 final DillTarget dillTarget = new DillTarget(ticker, uriTranslator);
118 dillTarget.read(new Uri.directory(sdkPath).resolve('platform.dill'));
119 final KernelTarget kernelTarget = new KernelTarget(dillTarget, uriTranslator);
120 try {
121 kernelTarget.read(fileName);
122 await dillTarget.writeOutline(null);
123 program = await kernelTarget.writeOutline(null);
124 program = await kernelTarget.writeProgram(null);
125 if (kernelTarget.errors.isNotEmpty) {
126 return new CompilationError(kernelTarget.errors
127 .map((err) => err.toString())
128 .toList(growable: false));
129 }
130 } on InputError catch (e) {
131 return new CompilationError(<String>[e.format()]);
132 }
133
134 // Perform target-specific transformations.
135 target.performModularTransformations(program);
136 target.performGlobalTransformations(program);
137
138 // Write the program to a list of bytes and return it.
139 var sink = new DataSink();
140 new BinaryPrinter(sink).writeProgramFile(program);
141 return new CompilationOk(sink.builder.takeBytes());
142 }
143
144 Future<CompilationResult> parseScript(
145 Uri fileName, String packageConfig, String sdkPath) async {
146 try {
147 return await parseScriptImpl(fileName, packageConfig, sdkPath);
148 } catch (err, stack) {
149 return new CompilationCrash(err.toString(), stack.toString());
150 }
151 }
152
153 Future _processLoadRequestImpl(String inputFileUrl) async {
154 Uri scriptUri = Uri.parse(inputFileUrl);
155 34
156 // Because we serve both Loader and bootstrapping requests we need to 35 // Because we serve both Loader and bootstrapping requests we need to
157 // duplicate the logic from _resolveScriptUri(...) here and attempt to 36 // duplicate the logic from _resolveScriptUri(...) here and attempt to
158 // resolve schemaless uris using current working directory. 37 // resolve schemaless uris using current working directory.
159 if (scriptUri.scheme == '') { 38 if (!scriptUri.hasScheme) {
160 // Script does not have a scheme, assume that it is a path, 39 // Script does not have a scheme, assume that it is a path,
161 // resolve it against the working directory. 40 // resolve it against the working directory.
162 scriptUri = Directory.current.uri.resolveUri(scriptUri); 41 scriptUri = Uri.base.resolveUri(new Uri.file(inputFilePathOrUri));
163 } 42 }
164 43
165 if (scriptUri.scheme != 'file') { 44 if (!scriptUri.isScheme('file')) {
166 // TODO: reuse loader code to support other schemes. 45 // TODO(vegorov): Reuse loader code to support other schemes.
167 throw "Expected 'file' scheme for a script uri: got ${scriptUri.scheme}"; 46 return new Future<CompilationResult>.value(new CompilationResult.error(
47 ["Expected 'file' scheme for a script uri: got ${scriptUri.scheme}"]));
168 } 48 }
169 49
170 final Uri packagesUri = (Platform.packageConfig != null) 50 return parseScript(scriptUri, verbose: verbose);
171 ? Uri.parse(Platform.packageConfig)
172 : await _findPackagesFile(scriptUri);
173 if (packagesUri == null) {
174 throw "Could not find .packages";
175 }
176
177 final Uri patchedSdk =
178 Uri.parse(Platform.resolvedExecutable).resolve("patched_sdk");
179
180 if (verbose) {
181 print("""DFE: Requesting compilation {
182 scriptUri: ${scriptUri}
183 packagesUri: ${packagesUri}
184 patchedSdk: ${patchedSdk}
185 }""");
186 }
187
188 return await parseScript(scriptUri, packagesUri.path, patchedSdk.path);
189 } 51 }
190 52
191 // Process a request from the runtime. See KernelIsolate::CompileToKernel in 53 // Process a request from the runtime. See KernelIsolate::CompileToKernel in
192 // kernel_isolate.cc and Loader::SendKernelRequest in loader.cc. 54 // kernel_isolate.cc and Loader::SendKernelRequest in loader.cc.
193 Future _processLoadRequest(request) async { 55 Future _processLoadRequest(request) async {
194 if (verbose) { 56 if (verbose) {
195 print("DFE: request: $request"); 57 print("DFE: request: $request");
196 print("DFE: Platform.packageConfig: ${Platform.packageConfig}"); 58 print("DFE: Platform.packageConfig: ${Platform.packageConfig}");
197 print("DFE: Platform.resolvedExecutable: ${Platform.resolvedExecutable}"); 59 print("DFE: Platform.resolvedExecutable: ${Platform.resolvedExecutable}");
198 } 60 }
199 61
200 final int tag = request[0]; 62 int tag = request[0];
201 final SendPort port = request[1]; 63 final SendPort port = request[1];
202 final String inputFileUrl = request[2]; 64 final String inputFileUrl = request[2];
203 65
204 var result; 66 CompilationResult result;
205 try { 67 try {
206 result = await _processLoadRequestImpl(inputFileUrl); 68 result = await _processLoadRequestImpl(inputFileUrl);
207 } catch (error, stack) { 69 } catch (error, stack) {
208 result = new CompilationCrash(error.toString(), stack.toString()); 70 result = new CompilationResult.crash(error, stack);
209 } 71 }
210 72
211 if (verbose) { 73 if (verbose) {
212 print("DFE:> ${result}"); 74 print("DFE:> ${result}");
213 } 75 }
214 76
215 // Check whether this is a Loader request or a bootstrapping request from 77 // Check whether this is a Loader request or a bootstrapping request from
216 // KernelIsolate::CompileToKernel. 78 // KernelIsolate::CompileToKernel.
217 final isBootstrapRequest = tag == null; 79 final isBootstrapRequest = tag == null;
218 if (isBootstrapRequest) { 80 if (isBootstrapRequest) {
219 port.send(result.toResponse()); 81 port.send(result.toResponse());
220 } else { 82 } else {
221 // See loader.cc for the code that handles these replies. 83 // See loader.cc for the code that handles these replies.
222 if (result is CompilationOk) { 84 if (result.status != Status.ok) {
223 port.send([tag, inputFileUrl, inputFileUrl, null, result]); 85 tag = -tag;
224 } else {
225 port.send([-tag, inputFileUrl, inputFileUrl, null, result.errorString]);
226 } 86 }
87 port.send([tag, inputFileUrl, inputFileUrl, null, result.payload]);
227 } 88 }
228 } 89 }
229 90
230 train(String scriptUri) { 91 train(String scriptUri) {
231 // TODO(28532): Enable on Windows. 92 // TODO(28532): Enable on Windows.
232 if (Platform.isWindows) return; 93 if (Platform.isWindows) return;
233 94
234 var tag = 1; 95 var tag = 1;
235 var responsePort = new RawReceivePort(); 96 var responsePort = new RawReceivePort();
236 responsePort.handler = (response) { 97 responsePort.handler = (response) {
(...skipping 14 matching lines...) Expand all
251 main([args]) { 112 main([args]) {
252 if (args?.length == 2 && args[0] == '--train') { 113 if (args?.length == 2 && args[0] == '--train') {
253 // This entry point is used when creating an app snapshot. The argument 114 // This entry point is used when creating an app snapshot. The argument
254 // provides a script to compile to warm-up generated code. 115 // provides a script to compile to warm-up generated code.
255 train(args[1]); 116 train(args[1]);
256 } else { 117 } else {
257 // Entry point for the Kernel isolate. 118 // Entry point for the Kernel isolate.
258 return new RawReceivePort()..handler = _processLoadRequest; 119 return new RawReceivePort()..handler = _processLoadRequest;
259 } 120 }
260 } 121 }
261
262 // This duplicates functionality from the Loader which we can't easily
263 // access from here.
264 Future<Uri> _findPackagesFile(Uri base) async {
265 var dir = new File.fromUri(base).parent;
266 while (true) {
267 final packagesFile = dir.uri.resolve(".packages");
268 if (await new File.fromUri(packagesFile).exists()) {
269 return packagesFile;
270 }
271 if (dir.parent.path == dir.path) {
272 break;
273 }
274 dir = dir.parent;
275 }
276 return null;
277 }
OLDNEW
« no previous file with comments | « pkg/front_end/lib/src/fasta/vm.dart ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698