Chromium Code Reviews| 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 library runtime.tools.kernel_service; | 4 library runtime.tools.kernel_service; |
| 5 | 5 |
| 6 // 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 // | 7 // |
| 8 // 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 |
| 9 // Kernel binary format. | 9 // Kernel binary format. |
| 10 // | 10 // |
| 11 // This is either invoked as the root script of the Kernel isolate when used | 11 // This is either invoked as the root script of the Kernel isolate when used |
| 12 // as a part of | 12 // as a part of |
| 13 // | 13 // |
| 14 // dart --dfe=utils/kernel-service/kernel-service.dart ... | 14 // dart --dfe=utils/kernel-service/kernel-service.dart ... |
| 15 // | 15 // |
| 16 // invocation or it is invoked as a standalone script to perform batch mode | 16 // invocation or it is invoked as a standalone script to perform batch mode |
| 17 // compilation requested via an HTTP interface | 17 // compilation requested via an HTTP interface |
| 18 // | 18 // |
| 19 // dart utils/kernel-service/kernel-service.dart --batch | 19 // dart utils/kernel-service/kernel-service.dart --batch |
| 20 // | 20 // |
| 21 // The port for the batch mode worker is controlled by DFE_WORKER_PORT | 21 // The port for the batch mode worker is controlled by DFE_WORKER_PORT |
| 22 // environment declarations (set by -DDFE_WORKER_PORT=... command line flag). | 22 // environment declarations (set by -DDFE_WORKER_PORT=... command line flag). |
| 23 // When not set (or set to 0) an ephemeral port returned by the OS is used | 23 // When not set (or set to 0) an ephemeral port returned by the OS is used |
| 24 // instead. | 24 // instead. |
| 25 // | 25 // |
| 26 // When this script is used as a Kernel isolate root script and DFE_WORKER_PORT | 26 // When this script is used as a Kernel isolate root script and DFE_WORKER_PORT |
| 27 // is set to non-zero value then Kernel isolate will forward all compilation | 27 // is set to non-zero value then Kernel isolate will forward all compilation |
| 28 // requests it receives to the batch worker on the given port. | 28 // requests it receives to the batch worker on the given port. |
| 29 // | 29 // |
| 30 // Set DFE_USE_FASTA environment declaration to true to use fasta front-end | |
| 31 // instead of dartk. Note: we expect patched_sdk folder to contain | |
| 32 // platform.dill file that contains patched SDK in the Kernel binary form. | |
| 33 // This file can be created using the following command line: | |
| 34 // | |
| 35 // export DART_AOT_SDK=<path-to-patched_sdk> | |
| 36 // dart pkg/front_end/lib/src/fasta/bin/compile_platform.dart \ | |
| 37 // ${DART_AOT_SDK}/platform.dill | |
| 38 // | |
|
ahe
2017/02/08 14:13:08
Nit: this comment should probably be documentation
Vyacheslav Egorov (Google)
2017/02/08 15:46:19
Done.
| |
| 30 | 39 |
| 31 import 'dart:async'; | 40 import 'dart:async'; |
| 32 import 'dart:convert'; | 41 import 'dart:convert'; |
| 33 import 'dart:io'; | 42 import 'dart:io'; |
| 34 import 'dart:isolate'; | 43 import 'dart:isolate'; |
| 35 import 'dart:typed_data'; | 44 import 'dart:typed_data'; |
| 36 | 45 |
| 37 import 'package:kernel/analyzer/loader.dart'; | 46 import 'package:kernel/analyzer/loader.dart'; |
| 38 import 'package:kernel/binary/ast_to_binary.dart'; | 47 import 'package:kernel/binary/ast_to_binary.dart'; |
| 39 import 'package:kernel/kernel.dart'; | 48 import 'package:kernel/kernel.dart'; |
| 40 import 'package:kernel/target/targets.dart'; | 49 import 'package:kernel/target/targets.dart'; |
| 41 | 50 |
| 51 import 'package:front_end/src/fasta/dill/dill_target.dart' show DillTarget; | |
| 52 import 'package:front_end/src/fasta/translate_uri.dart' show TranslateUri; | |
| 53 import 'package:front_end/src/fasta/ticker.dart' show Ticker; | |
| 54 import 'package:front_end/src/fasta/kernel/kernel_target.dart' show KernelSource Target; | |
|
ahe
2017/02/08 14:13:08
Long line.
Vyacheslav Egorov (Google)
2017/02/08 15:46:18
Done.
| |
| 55 import 'package:front_end/src/fasta/ast_kind.dart' show AstKind; | |
| 56 import 'package:front_end/src/fasta/errors.dart' show InputError; | |
| 57 | |
| 42 const bool verbose = const bool.fromEnvironment('DFE_VERBOSE') ?? false; | 58 const bool verbose = const bool.fromEnvironment('DFE_VERBOSE') ?? false; |
| 43 const int workerPort = const int.fromEnvironment('DFE_WORKER_PORT') ?? 0; | 59 const int workerPort = const int.fromEnvironment('DFE_WORKER_PORT') ?? 0; |
| 60 const bool useFasta = const bool.fromEnvironment('DFE_USE_FASTA') ?? false; | |
|
ahe
2017/02/08 14:13:08
Don't need ?? here as "false" is the default.
Vyacheslav Egorov (Google)
2017/02/08 15:46:18
Done.
| |
| 44 | 61 |
| 45 class DataSink implements Sink<List<int>> { | 62 class DataSink implements Sink<List<int>> { |
| 46 final BytesBuilder builder = new BytesBuilder(); | 63 final BytesBuilder builder = new BytesBuilder(); |
| 47 | 64 |
| 48 void add(List<int> data) { | 65 void add(List<int> data) { |
| 49 builder.add(data); | 66 builder.add(data); |
| 50 } | 67 } |
| 51 | 68 |
| 52 void close() { | 69 void close() { |
| 53 // Nothing to do. | 70 // Nothing to do. |
| (...skipping 23 matching lines...) Expand all Loading... | |
| 77 String get errorString; | 94 String get errorString; |
| 78 | 95 |
| 79 Map<String, dynamic> toJson(); | 96 Map<String, dynamic> toJson(); |
| 80 | 97 |
| 81 static CompilationFail fromJson(Map m) { | 98 static CompilationFail fromJson(Map m) { |
| 82 switch (m['status']) { | 99 switch (m['status']) { |
| 83 case STATUS_ERROR: | 100 case STATUS_ERROR: |
| 84 return new CompilationError(m['errors']); | 101 return new CompilationError(m['errors']); |
| 85 case STATUS_CRASH: | 102 case STATUS_CRASH: |
| 86 return new CompilationCrash(m['exception'], m['stack']); | 103 return new CompilationCrash(m['exception'], m['stack']); |
| 104 default: | |
| 105 throw "can't deserialize CompilationFail from ${m}"; | |
|
ahe
2017/02/08 14:13:08
Start with uppercase and end with a period.
Vyacheslav Egorov (Google)
2017/02/08 15:46:18
Done.
| |
| 87 } | 106 } |
| 88 } | 107 } |
| 89 } | 108 } |
| 90 | 109 |
| 91 class CompilationError extends CompilationFail { | 110 class CompilationError extends CompilationFail { |
| 92 final List<String> errors; | 111 final List<String> errors; |
| 93 | 112 |
| 94 CompilationError(this.errors); | 113 CompilationError(this.errors); |
| 95 | 114 |
| 96 List toResponse() => [STATUS_ERROR, errorString]; | 115 List toResponse() => [STATUS_ERROR, errorString]; |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 117 "status": STATUS_CRASH, | 136 "status": STATUS_CRASH, |
| 118 "exception": exception, | 137 "exception": exception, |
| 119 "stack": stack, | 138 "stack": stack, |
| 120 }; | 139 }; |
| 121 | 140 |
| 122 String get errorString => "${exception}\n${stack}"; | 141 String get errorString => "${exception}\n${stack}"; |
| 123 | 142 |
| 124 String toString() => "CompilationCrash(${errorString})"; | 143 String toString() => "CompilationCrash(${errorString})"; |
| 125 } | 144 } |
| 126 | 145 |
| 146 | |
|
ahe
2017/02/08 14:13:08
Extra line.
kustermann
2017/02/08 15:10:40
no 2 line requirement here :)
Vyacheslav Egorov (Google)
2017/02/08 15:46:18
Done.
| |
| 127 Future<CompilationResult> parseScriptImpl(DartLoaderBatch batch_loader, | 147 Future<CompilationResult> parseScriptImpl(DartLoaderBatch batch_loader, |
| 128 Uri fileName, String packageConfig, String sdkPath) async { | 148 Uri fileName, String packageConfig, String sdkPath) async { |
| 129 if (!FileSystemEntity.isFileSync(fileName.path)) { | 149 if (!FileSystemEntity.isFileSync(fileName.path)) { |
| 130 throw "Input file '${fileName.path}' does not exist."; | 150 throw "Input file '${fileName.path}' does not exist."; |
| 131 } | 151 } |
| 132 | 152 |
| 133 if (!FileSystemEntity.isDirectorySync(sdkPath)) { | 153 if (!FileSystemEntity.isDirectorySync(sdkPath)) { |
| 134 throw "Patched sdk directory not found at $sdkPath"; | 154 throw "Patched sdk directory not found at $sdkPath"; |
| 135 } | 155 } |
| 136 | 156 |
| 137 Target target = getTarget("vm", new TargetFlags(strongMode: false)); | 157 Target target = getTarget("vm", new TargetFlags(strongMode: false)); |
| 138 DartOptions dartOptions = new DartOptions( | |
| 139 strongMode: false, | |
| 140 strongModeSdk: false, | |
| 141 sdk: sdkPath, | |
| 142 packagePath: packageConfig, | |
| 143 customUriMappings: const {}, | |
| 144 declaredVariables: const {}); | |
| 145 DartLoader loader = | |
| 146 await batch_loader.getLoader(new Repository(), dartOptions); | |
| 147 var program = loader.loadProgram(fileName, target: target); | |
| 148 | 158 |
| 149 var errors = loader.errors; | 159 Program program; |
| 150 if (errors.isNotEmpty) { | 160 if (useFasta) { |
| 151 return new CompilationError(loader.errors.toList()); | 161 final uriTranslator = await TranslateUri.parse(new Uri.file(packageConfig)); |
| 162 Ticker ticker = new Ticker(isVerbose: false); | |
|
kustermann
2017/02/08 15:10:41
final
Not sure what [Ticker] is but you could pas
Vyacheslav Egorov (Google)
2017/02/08 15:46:18
This is for Fasta own diagnostic messages. Great i
| |
| 163 DillTarget dillTarget = new DillTarget(ticker, uriTranslator); | |
|
kustermann
2017/02/08 15:10:40
final
Vyacheslav Egorov (Google)
2017/02/08 15:46:18
Done.
| |
| 164 dillTarget.read(new Uri.directory(sdkPath).resolve('platform.dill')); | |
| 165 KernelSourceTarget sourceTarget = | |
| 166 new KernelSourceTarget(dillTarget, uriTranslator); | |
|
ahe
2017/02/08 14:13:08
Indentation.
Vyacheslav Egorov (Google)
2017/02/08 15:46:18
Done.
| |
| 167 try { | |
| 168 sourceTarget.read(fileName); | |
| 169 await dillTarget.writeOutline(null); | |
| 170 program = await sourceTarget.writeOutline(null); | |
| 171 program = await sourceTarget.writeProgram(null, AstKind.Kernel); | |
| 172 if (sourceTarget.errors.isNotEmpty) { | |
| 173 return new CompilationError(sourceTarget.errors | |
| 174 .map((err) => err.toString()).toList(growable: false)); | |
| 175 } | |
| 176 } on InputError catch (e) { | |
| 177 return new CompilationError(<String>[e.error]); | |
| 178 } | |
|
ahe
2017/02/08 14:13:08
We need a better API for this. I think Paul and Si
Vyacheslav Egorov (Google)
2017/02/08 15:46:18
Yeah, they are working on this. But in the mean wh
| |
| 179 } else { | |
| 180 DartOptions dartOptions = new DartOptions( | |
| 181 strongMode: false, | |
| 182 strongModeSdk: false, | |
| 183 sdk: sdkPath, | |
| 184 packagePath: packageConfig, | |
| 185 customUriMappings: const {}, | |
| 186 declaredVariables: const {}); | |
| 187 DartLoader loader = | |
| 188 await batch_loader.getLoader(new Repository(), dartOptions); | |
|
kustermann
2017/02/08 15:10:41
maybe run dartfmt on this file?
Vyacheslav Egorov (Google)
2017/02/08 15:46:18
Done.
| |
| 189 program = loader.loadProgram(fileName, target: target); | |
| 190 | |
| 191 var errors = loader.errors; | |
|
kustermann
2017/02/08 15:10:41
final
Vyacheslav Egorov (Google)
2017/02/08 15:46:18
Done.
| |
| 192 if (errors.isNotEmpty) { | |
| 193 return new CompilationError(loader.errors.toList()); | |
| 194 } | |
| 152 } | 195 } |
| 153 | 196 |
| 154 // Perform target-specific transformations. | 197 // Perform target-specific transformations. |
| 155 target.performModularTransformations(program); | 198 target.performModularTransformations(program); |
| 156 target.performGlobalTransformations(program); | 199 target.performGlobalTransformations(program); |
| 157 | 200 |
| 158 // Write the program to a list of bytes and return it. | 201 // Write the program to a list of bytes and return it. |
| 159 var sink = new DataSink(); | 202 var sink = new DataSink(); |
| 160 new BinaryPrinter(sink).writeProgramFile(program); | 203 new BinaryPrinter(sink).writeProgramFile(program); |
| 161 return new CompilationOk(sink.builder.takeBytes()); | 204 return new CompilationOk(sink.builder.takeBytes()); |
| (...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 356 if (await new File.fromUri(packagesFile).exists()) { | 399 if (await new File.fromUri(packagesFile).exists()) { |
| 357 return packagesFile; | 400 return packagesFile; |
| 358 } | 401 } |
| 359 if (dir.parent.path == dir.path) { | 402 if (dir.parent.path == dir.path) { |
| 360 break; | 403 break; |
| 361 } | 404 } |
| 362 dir = dir.parent; | 405 dir = dir.parent; |
| 363 } | 406 } |
| 364 return null; | 407 return null; |
| 365 } | 408 } |
| OLD | NEW |