| 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 |