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

Side by Side Diff: runtime/tools/kernel-service.dart

Issue 2651633002: VM: [Kernel] Fix bootstraping when Kernel isolate is used. (Closed)
Patch Set: Landing issue Created 3 years, 10 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 | « runtime/include/dart_native_api.h ('k') | runtime/vm/dart_api_impl.cc » ('j') | 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 library runtime.tools.kernel_service;
4 5
5 // This is an interface to the Dart Kernel parser and Kernel binary generator. 6 // This is an interface to the Dart Kernel parser and Kernel binary generator.
7 //
6 // It is used by the kernel-isolate to load Dart source code and generate 8 // It is used by the kernel-isolate to load Dart source code and generate
7 // Kernel binary format. 9 // Kernel binary format.
10 //
8 11
12 import 'dart:async';
13 import 'dart:convert';
14 import 'dart:io';
9 import 'dart:isolate'; 15 import 'dart:isolate';
10 import 'dart:async';
11 import 'dart:io';
12 import 'dart:typed_data'; 16 import 'dart:typed_data';
13 17
18 import 'package:kernel/analyzer/loader.dart';
14 import 'package:kernel/binary/ast_to_binary.dart'; 19 import 'package:kernel/binary/ast_to_binary.dart';
15 import 'package:kernel/analyzer/loader.dart';
16 import 'package:kernel/kernel.dart'; 20 import 'package:kernel/kernel.dart';
17 import 'package:kernel/target/targets.dart'; 21 import 'package:kernel/target/targets.dart';
18 22
19 const verbose = false; 23 const bool verbose = const bool.fromEnvironment('DFE_VERBOSE') ?? false;
20 24
21 class DataSink implements Sink<List<int>> { 25 class DataSink implements Sink<List<int>> {
22 final BytesBuilder builder = new BytesBuilder(); 26 final BytesBuilder builder = new BytesBuilder();
23 27
24 void add(List<int> data) { 28 void add(List<int> data) {
25 builder.add(data); 29 builder.add(data);
26 } 30 }
27 31
28 void close() { 32 void close() {
29 // Nothing to do. 33 // Nothing to do.
30 } 34 }
31 } 35 }
32 36
33 Future<Uint8List> parseScript( 37 // Note: these values must match Dart_KernelCompilationStatus in dart_api.h.
38 const int STATUS_OK = 0; // Compilation was successful.
39 const int STATUS_ERROR = 1; // Compilation failed with a compile time error.
40 const int STATUS_CRASH = 2; // Compiler crashed.
41
42 abstract class CompilationResult {
43 List toResponse();
44 }
45
46 class CompilationOk extends CompilationResult {
47 final Uint8List binary;
48
49 CompilationOk(this.binary);
50
51 List toResponse() => [STATUS_OK, binary];
52
53 String toString() => "CompilationOk(${binary.length} bytes)";
54 }
55
56 abstract class CompilationFail extends CompilationResult {
57 String get errorString;
58 }
59
60 class CompilationError extends CompilationFail {
61 final List<String> errors;
62
63 CompilationError(this.errors);
64
65 List toResponse() => [STATUS_ERROR, errorString];
66
67 String get errorString => errors.take(10).join('\n');
68
69 String toString() => "CompilationError(${errorString})";
70 }
71
72 class CompilationCrash extends CompilationFail {
73 final String exception;
74 final String stack;
75
76 CompilationCrash(this.exception, this.stack);
77
78 List toResponse() => [STATUS_CRASH, errorString];
79
80 String get errorString => "${exception}\n${stack}";
81
82 String toString() => "CompilationCrash(${errorString})";
83 }
84
85 Future<CompilationResult> parseScriptImpl(DartLoaderBatch batch_loader,
34 Uri fileName, String packageConfig, String sdkPath) async { 86 Uri fileName, String packageConfig, String sdkPath) async {
35 if (!FileSystemEntity.isFileSync(fileName.path)) { 87 if (!FileSystemEntity.isFileSync(fileName.path)) {
36 throw "Input file '${fileName.path}' does not exist."; 88 throw "Input file '${fileName.path}' does not exist.";
37 } 89 }
38 90
39 if (!FileSystemEntity.isDirectorySync(sdkPath)) { 91 if (!FileSystemEntity.isDirectorySync(sdkPath)) {
40 throw "Patched sdk directory not found at $sdkPath"; 92 throw "Patched sdk directory not found at $sdkPath";
41 } 93 }
42 94
43 Target target = getTarget("vm", new TargetFlags(strongMode: false)); 95 Target target = getTarget("vm", new TargetFlags(strongMode: false));
44 DartOptions dartOptions = new DartOptions( 96 DartOptions dartOptions = new DartOptions(
45 strongMode: false, 97 strongMode: false,
46 strongModeSdk: false, 98 strongModeSdk: false,
47 sdk: sdkPath, 99 sdk: sdkPath,
48 packagePath: packageConfig, 100 packagePath: packageConfig,
49 customUriMappings: const {}, 101 customUriMappings: const {},
50 declaredVariables: const {}); 102 declaredVariables: const {});
51 DartLoader loader = 103 DartLoader loader =
52 await new DartLoaderBatch().getLoader(new Repository(), dartOptions); 104 await batch_loader.getLoader(new Repository(), dartOptions);
53 var program = loader.loadProgram(fileName, target: target); 105 var program = loader.loadProgram(fileName, target: target);
54 106
55 var errors = loader.errors; 107 var errors = loader.errors;
56 if (errors.isNotEmpty) { 108 if (errors.isNotEmpty) {
57 throw loader.errors.first; 109 return new CompilationError(loader.errors.toList());
58 } 110 }
59 111
60 // Link program into one file, cf. --link option in dartk. 112 // Link program into one file, cf. --link option in dartk.
61 target.transformProgram(program); 113 target.transformProgram(program);
62 114
63 // Write the program to a list of bytes and return it. 115 // Write the program to a list of bytes and return it.
64 var sink = new DataSink(); 116 var sink = new DataSink();
65 new BinaryPrinter(sink).writeProgramFile(program); 117 new BinaryPrinter(sink).writeProgramFile(program);
66 return sink.builder.takeBytes(); 118 return new CompilationOk(sink.builder.takeBytes());
67 } 119 }
68 120
121 Future<CompilationResult> parseScript(DartLoaderBatch loader, Uri fileName,
122 String packageConfig, String sdkPath) async {
123 try {
124 return await parseScriptImpl(loader, fileName, packageConfig, sdkPath);
125 } catch (err, stack) {
126 return new CompilationCrash(err.toString(), stack.toString());
127 }
128 }
129
130 Future _processLoadRequestImpl(String inputFileUrl) async {
131 Uri scriptUri = Uri.parse(inputFileUrl);
132
133 // Because we serve both Loader and bootstrapping requests we need to
134 // duplicate the logic from _resolveScriptUri(...) here and attempt to
135 // resolve schemaless uris using current working directory.
136 if (scriptUri.scheme == '') {
137 // Script does not have a scheme, assume that it is a path,
138 // resolve it against the working directory.
139 scriptUri = Directory.current.uri.resolveUri(scriptUri);
140 }
141
142 if (scriptUri.scheme != 'file') {
143 // TODO: reuse loader code to support other schemes.
144 throw "Expected 'file' scheme for a script uri: got ${scriptUri.scheme}";
145 }
146
147 final Uri packagesUri = (Platform.packageConfig != null)
148 ? Uri.parse(Platform.packageConfig)
149 : await _findPackagesFile(scriptUri);
150 if (packagesUri == null) {
151 throw "Could not find .packages";
152 }
153
154 final Uri patchedSdk =
155 Uri.parse(Platform.resolvedExecutable).resolve("patched_sdk");
156
157 if (verbose) {
158 print("""DFE: Requesting compilation {
159 scriptUri: ${scriptUri}
160 packagesUri: ${packagesUri}
161 patchedSdk: ${patchedSdk}
162 }""");
163 }
164
165 return await parseScript(
166 new DartLoaderBatch(), scriptUri, packagesUri.path, patchedSdk.path);
167 }
168
169 // Process a request from the runtime. See KernelIsolate::CompileToKernel in
170 // kernel_isolate.cc and Loader::SendKernelRequest in loader.cc.
69 Future _processLoadRequest(request) async { 171 Future _processLoadRequest(request) async {
70 if (verbose) { 172 if (verbose) {
71 print("FROM DART KERNEL: load request: $request"); 173 print("DFE: request: $request");
72 print("FROM DART KERNEL: package: ${Platform.packageConfig}"); 174 print("DFE: Platform.packageConfig: ${Platform.packageConfig}");
73 print("FROM DART KERNEL: exec: ${Platform.resolvedExecutable}"); 175 print("DFE: Platform.resolvedExecutable: ${Platform.resolvedExecutable}");
74 } 176 }
75 177
76 int tag = request[0]; 178 final int tag = request[0];
77 SendPort port = request[1]; 179 final SendPort port = request[1];
78 String inputFileUrl = request[2]; 180 final String inputFileUrl = request[2];
79 Uri scriptUri = Uri.parse(inputFileUrl);
80 Uri packagesUri = Uri.parse(Platform.packageConfig ?? ".packages");
81 Uri patchedSdk =
82 Uri.parse(Platform.resolvedExecutable).resolve("patched_sdk");
83 181
84 var result; 182 var result;
85 try { 183 try {
86 result = await parseScript(scriptUri, packagesUri.path, patchedSdk.path); 184 result = await _processLoadRequestImpl(inputFileUrl);
87 } catch (error) { 185 } catch (error, stack) {
88 tag = -tag; // Mark reply as an exception. 186 result = new CompilationCrash(error.toString(), stack.toString());
89 result = error.toString();
90 } 187 }
91 188
92 port.send([tag, inputFileUrl, inputFileUrl, null, result]); 189 if (verbose) {
190 print("DFE:> ${result}");
191 }
192
193 // Check whether this is a Loader request or a bootstrapping request from
194 // KernelIsolate::CompileToKernel.
195 final isBootstrapRequest = tag == null;
196 if (isBootstrapRequest) {
197 port.send(result.toResponse());
198 } else {
199 // See loader.cc for the code that handles these replies.
200 if (result is CompilationOk) {
201 port.send([tag, inputFileUrl, inputFileUrl, null, result]);
202 } else {
203 port.send([-tag, inputFileUrl, inputFileUrl, null, result.errorString]);
204 }
205 }
93 } 206 }
94 207
95 main() => new RawReceivePort()..handler = _processLoadRequest; 208 main() => new RawReceivePort()..handler = _processLoadRequest;
209
210 // This duplicates functionality from the Loader which we can't easily
211 // access from here.
212 Uri _findPackagesFile(Uri base) async {
213 var dir = new File.fromUri(base).parent;
214 while (true) {
215 final packagesFile = dir.uri.resolve(".packages");
216 if (await new File.fromUri(packagesFile).exists()) {
217 return packagesFile;
218 }
219 if (dir.parent == dir) {
220 break;
221 }
222 dir = dir.parent;
223 }
224 return null;
225 }
OLDNEW
« no previous file with comments | « runtime/include/dart_native_api.h ('k') | runtime/vm/dart_api_impl.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698