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'; |
25 import 'dart:isolate'; | 25 import 'dart:isolate'; |
26 | 26 |
| 27 import 'package:front_end/memory_file_system.dart'; |
| 28 import 'package:front_end/physical_file_system.dart'; |
27 import 'package:front_end/src/fasta/vm.dart' | 29 import 'package:front_end/src/fasta/vm.dart' |
28 show CompilationResult, Status, parseScript; | 30 show CompilationResult, Status, parseScriptInFileSystem; |
29 | 31 |
30 const bool verbose = const bool.fromEnvironment('DFE_VERBOSE'); | 32 const bool verbose = const bool.fromEnvironment('DFE_VERBOSE'); |
31 | 33 |
32 const bool strongMode = const bool.fromEnvironment('DFE_STRONG_MODE'); | 34 const bool strongMode = const bool.fromEnvironment('DFE_STRONG_MODE'); |
33 | 35 |
34 Future<CompilationResult> _processLoadRequestImpl(String inputFilePathOrUri) { | 36 Future<CompilationResult> _processLoadRequestImpl( |
| 37 String inputFilePathOrUri, FileSystem fileSystem) { |
35 Uri scriptUri = Uri.parse(inputFilePathOrUri); | 38 Uri scriptUri = Uri.parse(inputFilePathOrUri); |
36 | 39 |
37 // Because we serve both Loader and bootstrapping requests we need to | 40 // Because we serve both Loader and bootstrapping requests we need to |
38 // duplicate the logic from _resolveScriptUri(...) here and attempt to | 41 // duplicate the logic from _resolveScriptUri(...) here and attempt to |
39 // resolve schemaless uris using current working directory. | 42 // resolve schemaless uris using current working directory. |
40 if (!scriptUri.hasScheme) { | 43 if (!scriptUri.hasScheme) { |
41 // Script does not have a scheme, assume that it is a path, | 44 // Script does not have a scheme, assume that it is a path, |
42 // resolve it against the working directory. | 45 // resolve it against the working directory. |
43 scriptUri = Uri.base.resolveUri(new Uri.file(inputFilePathOrUri)); | 46 scriptUri = Uri.base.resolveUri(new Uri.file(inputFilePathOrUri)); |
44 } | 47 } |
45 | 48 |
46 if (!scriptUri.isScheme('file')) { | 49 if (!scriptUri.isScheme('file')) { |
47 // TODO(vegorov): Reuse loader code to support other schemes. | 50 // TODO(vegorov): Reuse loader code to support other schemes. |
48 return new Future<CompilationResult>.value(new CompilationResult.error( | 51 return new Future<CompilationResult>.value(new CompilationResult.error( |
49 "Expected 'file' scheme for a script uri: got ${scriptUri.scheme}")); | 52 "Expected 'file' scheme for a script uri: got ${scriptUri.scheme}")); |
50 } | 53 } |
51 | 54 return parseScriptInFileSystem(scriptUri, fileSystem, |
52 return parseScript(scriptUri, verbose: verbose, strongMode: strongMode); | 55 verbose: verbose, strongMode: strongMode); |
53 } | 56 } |
54 | 57 |
55 // Process a request from the runtime. See KernelIsolate::CompileToKernel in | 58 // Process a request from the runtime. See KernelIsolate::CompileToKernel in |
56 // kernel_isolate.cc and Loader::SendKernelRequest in loader.cc. | 59 // kernel_isolate.cc and Loader::SendKernelRequest in loader.cc. |
57 Future _processLoadRequest(request) async { | 60 Future _processLoadRequest(request) async { |
58 if (verbose) { | 61 if (verbose) { |
59 print("DFE: request: $request"); | 62 print("DFE: request: $request"); |
60 print("DFE: Platform.packageConfig: ${Platform.packageConfig}"); | 63 print("DFE: Platform.packageConfig: ${Platform.packageConfig}"); |
61 print("DFE: Platform.resolvedExecutable: ${Platform.resolvedExecutable}"); | 64 print("DFE: Platform.resolvedExecutable: ${Platform.resolvedExecutable}"); |
62 } | 65 } |
63 | 66 |
64 int tag = request[0]; | 67 int tag = request[0]; |
65 final SendPort port = request[1]; | 68 final SendPort port = request[1]; |
66 final String inputFileUrl = request[2]; | 69 final String inputFileUrl = request[2]; |
| 70 FileSystem fileSystem = request.length > 3 |
| 71 ? _buildMemoryFileSystem(request[3]) |
| 72 : PhysicalFileSystem.instance; |
67 | 73 |
68 CompilationResult result; | 74 CompilationResult result; |
69 try { | 75 try { |
70 result = await _processLoadRequestImpl(inputFileUrl); | 76 result = await _processLoadRequestImpl(inputFileUrl, fileSystem); |
71 } catch (error, stack) { | 77 } catch (error, stack) { |
72 result = new CompilationResult.crash(error, stack); | 78 result = new CompilationResult.crash(error, stack); |
73 } | 79 } |
74 | 80 |
75 if (verbose) { | 81 if (verbose) { |
76 print("DFE:> ${result}"); | 82 print("DFE:> ${result}"); |
77 } | 83 } |
78 | 84 |
79 // Check whether this is a Loader request or a bootstrapping request from | 85 // Check whether this is a Loader request or a bootstrapping request from |
80 // KernelIsolate::CompileToKernel. | 86 // KernelIsolate::CompileToKernel. |
81 final isBootstrapRequest = tag == null; | 87 final isBootstrapRequest = tag == null; |
82 if (isBootstrapRequest) { | 88 if (isBootstrapRequest) { |
83 port.send(result.toResponse()); | 89 port.send(result.toResponse()); |
84 } else { | 90 } else { |
85 // See loader.cc for the code that handles these replies. | 91 // See loader.cc for the code that handles these replies. |
86 if (result.status != Status.ok) { | 92 if (result.status != Status.ok) { |
87 tag = -tag; | 93 tag = -tag; |
88 } | 94 } |
89 port.send([tag, inputFileUrl, inputFileUrl, null, result.payload]); | 95 port.send([tag, inputFileUrl, inputFileUrl, null, result.payload]); |
90 } | 96 } |
91 } | 97 } |
92 | 98 |
| 99 // Given namedSources list of interleaved file name string and |
| 100 // raw file content Uint8List this function builds up and returns |
| 101 // MemoryFileSystem instance that can be used instead of |
| 102 // PhysicalFileSystem.instance by the frontend. |
| 103 FileSystem _buildMemoryFileSystem(List namedSources) { |
| 104 FileSystem fileSystem = new MemoryFileSystem(Uri.parse('file:///')); |
| 105 for (int i = 0; i < namedSources.length ~/ 2; i++) { |
| 106 fileSystem |
| 107 .entityForUri(Uri.parse(namedSources[i * 2])) |
| 108 .writeAsBytesSync(namedSources[i * 2 + 1]); |
| 109 } |
| 110 return fileSystem; |
| 111 } |
| 112 |
93 train(String scriptUri) { | 113 train(String scriptUri) { |
94 // TODO(28532): Enable on Windows. | 114 // TODO(28532): Enable on Windows. |
95 if (Platform.isWindows) return; | 115 if (Platform.isWindows) return; |
96 | 116 |
97 var tag = 1; | 117 var tag = 1; |
98 var responsePort = new RawReceivePort(); | 118 var responsePort = new RawReceivePort(); |
99 responsePort.handler = (response) { | 119 responsePort.handler = (response) { |
100 if (response[0] == tag) { | 120 if (response[0] == tag) { |
101 // Success. | 121 // Success. |
102 responsePort.close(); | 122 responsePort.close(); |
(...skipping 11 matching lines...) Expand all Loading... |
114 main([args]) { | 134 main([args]) { |
115 if (args?.length == 2 && args[0] == '--train') { | 135 if (args?.length == 2 && args[0] == '--train') { |
116 // This entry point is used when creating an app snapshot. The argument | 136 // This entry point is used when creating an app snapshot. The argument |
117 // provides a script to compile to warm-up generated code. | 137 // provides a script to compile to warm-up generated code. |
118 train(args[1]); | 138 train(args[1]); |
119 } else { | 139 } else { |
120 // Entry point for the Kernel isolate. | 140 // Entry point for the Kernel isolate. |
121 return new RawReceivePort()..handler = _processLoadRequest; | 141 return new RawReceivePort()..handler = _processLoadRequest; |
122 } | 142 } |
123 } | 143 } |
OLD | NEW |