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

Side by Side Diff: runtime/bin/vmservice/loader.dart

Issue 1998963003: Rework standalone to use a synchronous loader that does not invoke Dart code (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 4 years, 6 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/bin/main.cc ('k') | runtime/bin/vmservice/vmservice_io.dart » ('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) 2015, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2015, 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 part of vmservice_io; 5 part of vmservice_io;
6 6
7 _sanitizeWindowsPath(path) {
8 // For Windows we need to massage the paths a bit according to
9 // http://blogs.msdn.com/b/ie/archive/2006/12/06/file-uris-in-windows.aspx
10 //
11 // Convert
12 // C:\one\two\three
13 // to
14 // /C:/one/two/three
15
16 if (_isWindows == false) {
17 // Do nothing when not running Windows.
18 return path;
19 }
20
21 var fixedPath = "${path.replaceAll('\\', '/')}";
22
23 if ((path.length > 2) && (path[1] == ':')) {
24 // Path begins with a drive letter.
25 return '/$fixedPath';
26 }
27
28 return fixedPath;
29 }
30
31 _trimWindowsPath(path) {
32 // Convert /X:/ to X:/.
33 if (_isWindows == false) {
34 // Do nothing when not running Windows.
35 return path;
36 }
37 if (!path.startsWith('/') || (path.length < 3)) {
38 return path;
39 }
40 // Match '/?:'.
41 if ((path[0] == '/') && (path[2] == ':')) {
42 // Remove leading '/'.
43 return path.substring(1);
44 }
45 return path;
46 }
47
48 // Ensure we have a trailing slash character.
49 _enforceTrailingSlash(uri) {
50 if (!uri.endsWith('/')) {
51 return '$uri/';
52 }
53 return uri;
54 }
55
56 // State associated with the isolate that is used for loading.
57 class IsolateLoaderState extends IsolateEmbedderData {
58 IsolateLoaderState(this.isolateId);
59
60 final int isolateId;
61
62 SendPort sp;
63
64 void init(String packageRootFlag,
65 String packagesConfigFlag,
66 String workingDirectory,
67 String rootScript) {
68 // _workingDirectory must be set first.
69 _workingDirectory = new Uri.directory(workingDirectory);
70 if (rootScript != null) {
71 _rootScript = Uri.parse(rootScript);
72 }
73 // If the --package-root flag was passed.
74 if (packageRootFlag != null) {
75 _setPackageRoot(packageRootFlag);
76 }
77 // If the --packages flag was passed.
78 if (packagesConfigFlag != null) {
79 _setPackagesConfig(packagesConfigFlag);
80 }
81 }
82
83 void cleanup() {
84 if (_packagesPort != null) {
85 _packagesPort.close();
86 _packagesPort = null;
87 }
88 }
89
90 // The working directory when the embedder started.
91 Uri _workingDirectory;
92
93 // The root script's uri.
94 Uri _rootScript;
95
96 bool _traceLoading = false;
97
98 // Packages are either resolved looking up in a map or resolved from within a
99 // package root.
100 bool get _packagesReady => (_packageRoot != null) ||
101 (_packageMap != null) ||
102 (_packageError != null);
103
104 // Error string set if there was an error resolving package configuration.
105 // For example not finding a .packages file or packages/ directory, malformed
106 // .packages file or any other related error.
107 String _packageError = null;
108
109 // The directory to look in to resolve "package:" scheme URIs. By default it
110 // is the 'packages' directory right next to the script.
111 Uri _packageRoot = null;
112
113 // The map describing how certain package names are mapped to Uris.
114 Uri _packageConfig = null;
115 Map<String, Uri> _packageMap = null;
116
117 _setPackageRoot(String packageRoot) {
118 packageRoot = _enforceTrailingSlash(packageRoot);
119 if (packageRoot.startsWith('file:') ||
120 packageRoot.startsWith('http:') ||
121 packageRoot.startsWith('https:')) {
122 _packageRoot = _workingDirectory.resolve(packageRoot);
123 } else {
124 packageRoot = _sanitizeWindowsPath(packageRoot);
125 packageRoot = _trimWindowsPath(packageRoot);
126 _packageRoot = _workingDirectory.resolveUri(new Uri.file(packageRoot));
127 }
128 }
129
130 _setPackagesConfig(String packagesParam) {
131 var packagesName = _sanitizeWindowsPath(packagesParam);
132 var packagesUri = Uri.parse(packagesName);
133 if (packagesUri.scheme == '') {
134 // Script does not have a scheme, assume that it is a path,
135 // resolve it against the working directory.
136 packagesUri = _workingDirectory.resolveUri(packagesUri);
137 }
138 _requestPackagesMap(packagesUri);
139 _pendingPackageLoads.add(() {
140 // Dummy action.
141 });
142 }
143
144 // Handling of access to the package root or package map from user code.
145 _triggerPackageResolution(action) {
146 if (_packagesReady) {
147 // Packages are ready. Execute the action now.
148 action();
149 } else {
150 if (_pendingPackageLoads.isEmpty) {
151 // Package resolution has not been setup yet, and this is the first
152 // request for package resolution & loading.
153 _requestPackagesMap();
154 }
155 // Register the action for when the package resolution is ready.
156 _pendingPackageLoads.add(action);
157 }
158 }
159
160 // A list of callbacks which should be invoked after the package map has been
161 // loaded.
162 List<Function> _pendingPackageLoads = [];
163
164 // Given a uri with a 'package' scheme, return a Uri that is prefixed with
165 // the package root.
166 Uri _resolvePackageUri(Uri uri) {
167 assert(uri.scheme == "package");
168 assert(_packagesReady);
169
170 if (!uri.host.isEmpty) {
171 var path = '${uri.host}${uri.path}';
172 var right = 'package:$path';
173 var wrong = 'package://$path';
174
175 throw "URIs using the 'package:' scheme should look like "
176 "'$right', not '$wrong'.";
177 }
178
179 if (_traceLoading) {
180 _log('Resolving package with uri path: ${uri.path}');
181 }
182 var resolvedUri;
183 if (_packageError != null) {
184 if (_traceLoading) {
185 _log("Resolving package with pending resolution error: $_packageError");
186 }
187 throw _packageError;
188 } else if (_packageRoot != null) {
189 resolvedUri = _packageRoot.resolve(uri.path);
190 } else {
191 var packageName = uri.pathSegments[0];
192 var mapping = _packageMap[packageName];
193 if (_traceLoading) {
194 _log("Mapped '$packageName' package to '$mapping'");
195 }
196 if (mapping == null) {
197 throw "No mapping for '$packageName' package when resolving '$uri'.";
198 }
199 var path;
200 if (uri.path.length > packageName.length) {
201 path = uri.path.substring(packageName.length + 1);
202 } else {
203 // Handle naked package resolution to the default package name:
204 // package:foo is equivalent to package:foo/foo.dart
205 assert(uri.path.length == packageName.length);
206 path = "$packageName.dart";
207 }
208 if (_traceLoading) {
209 _log("Path to be resolved in package: $path");
210 }
211 resolvedUri = mapping.resolve(path);
212 }
213 if (_traceLoading) {
214 _log("Resolved '$uri' to '$resolvedUri'.");
215 }
216 return resolvedUri;
217 }
218
219 RawReceivePort _packagesPort;
220
221 void _requestPackagesMap([Uri packageConfig]) {
222 assert(_packagesPort == null);
223 assert(_rootScript != null);
224 // Create a port to receive the packages map on.
225 _packagesPort = new RawReceivePort(_handlePackagesReply);
226 var sp = _packagesPort.sendPort;
227
228 if (packageConfig != null) {
229 // Explicitly specified .packages path.
230 _handlePackagesRequest(sp,
231 _traceLoading,
232 -2,
233 packageConfig);
234 } else {
235 // Search for .packages or packages/ starting at the root script.
236 _handlePackagesRequest(sp,
237 _traceLoading,
238 -1,
239 _rootScript);
240 }
241
242 if (_traceLoading) {
243 _log("Requested packages map for '$_rootScript'.");
244 }
245 }
246
247 void _handlePackagesReply(msg) {
248 assert(_packagesPort != null);
249 // Make sure to close the _packagePort before any other action.
250 _packagesPort.close();
251 _packagesPort = null;
252
253 if (_traceLoading) {
254 _log("Got packages reply: $msg");
255 }
256 if (msg is String) {
257 if (_traceLoading) {
258 _log("Got failure response on package port: '$msg'");
259 }
260 // Remember the error message.
261 _packageError = msg;
262 } else if (msg is List) {
263 if (msg.length == 1) {
264 if (_traceLoading) {
265 _log("Received package root: '${msg[0]}'");
266 }
267 _packageRoot = Uri.parse(msg[0]);
268 } else {
269 // First entry contains the location of the loaded .packages file.
270 assert((msg.length % 2) == 0);
271 assert(msg.length >= 2);
272 assert(msg[1] == null);
273 _packageConfig = Uri.parse(msg[0]);
274 _packageMap = new Map<String, Uri>();
275 for (var i = 2; i < msg.length; i+=2) {
276 // TODO(iposva): Complain about duplicate entries.
277 _packageMap[msg[i]] = Uri.parse(msg[i+1]);
278 }
279 if (_traceLoading) {
280 _log("Setup package map: $_packageMap");
281 }
282 }
283 } else {
284 _packageError = "Bad type of packages reply: ${msg.runtimeType}";
285 if (_traceLoading) {
286 _log(_packageError);
287 }
288 }
289
290 // Resolve all pending package loads now that we know how to resolve them.
291 while (_pendingPackageLoads.length > 0) {
292 // Order does not matter as we queue all of the requests up right now.
293 var req = _pendingPackageLoads.removeLast();
294 // Call the registered closure, to handle the delayed action.
295 req();
296 }
297 // Reset the pending package loads to empty. So that we eventually can
298 // finish loading.
299 _pendingPackageLoads = [];
300 }
301
302 }
303
7 _log(msg) { 304 _log(msg) {
8 print("% $msg"); 305 print("% $msg");
9 } 306 }
10 307
11 var _httpClient; 308 var _httpClient;
12 309
13 // Send a response to the requesting isolate. 310 // Send a response to the requesting isolate.
14 void _sendResourceResponse(SendPort sp, int id, dynamic data) { 311 void _sendResourceResponse(SendPort sp,
312 int tag,
313 Uri uri,
314 String libraryUrl,
315 dynamic data) {
15 assert((data is List<int>) || (data is String)); 316 assert((data is List<int>) || (data is String));
16 var msg = new List(2); 317 var msg = new List(4);
17 msg[0] = id; 318 if (data is String) {
18 msg[1] = data; 319 // We encountered an error, flip the sign of the tag to indicate that.
320 tag = -tag;
321 if (libraryUrl == null) {
322 data = 'Could not load "$uri": $data';
323 } else {
324 data = 'Could not import "$uri" from "$libraryUrl": $data';
325 }
326 }
327 msg[0] = tag;
328 msg[1] = uri.toString();
329 msg[2] = libraryUrl;
330 msg[3] = data;
19 sp.send(msg); 331 sp.send(msg);
20 } 332 }
21 333
22 void _loadHttp(SendPort sp, int id, Uri uri) { 334 void _loadHttp(SendPort sp,
335 int tag,
336 Uri uri,
337 Uri resolvedUri,
338 String libraryUrl) {
23 if (_httpClient == null) { 339 if (_httpClient == null) {
24 _httpClient = new HttpClient()..maxConnectionsPerHost = 6; 340 _httpClient = new HttpClient()..maxConnectionsPerHost = 6;
25 } 341 }
26 _httpClient.getUrl(uri) 342 _httpClient.getUrl(resolvedUri)
27 .then((HttpClientRequest request) => request.close()) 343 .then((HttpClientRequest request) => request.close())
28 .then((HttpClientResponse response) { 344 .then((HttpClientResponse response) {
29 var builder = new BytesBuilder(copy: false); 345 var builder = new BytesBuilder(copy: false);
30 response.listen( 346 response.listen(
31 builder.add, 347 builder.add,
32 onDone: () { 348 onDone: () {
33 if (response.statusCode != 200) { 349 if (response.statusCode != 200) {
34 var msg = "Failure getting $uri:\n" 350 var msg = "Failure getting $resolvedUri:\n"
35 " ${response.statusCode} ${response.reasonPhrase}"; 351 " ${response.statusCode} ${response.reasonPhrase}";
36 _sendResourceResponse(sp, id, msg); 352 _sendResourceResponse(sp, tag, uri, libraryUrl, msg);
37 } else { 353 } else {
38 _sendResourceResponse(sp, id, builder.takeBytes()); 354 _sendResourceResponse(sp, tag, uri, libraryUrl,
355 builder.takeBytes());
39 } 356 }
40 }, 357 },
41 onError: (e) { 358 onError: (e) {
42 _sendResourceResponse(sp, id, e.toString()); 359 _sendResourceResponse(sp, tag, uri, libraryUrl, e.toString());
43 }); 360 });
44 }) 361 })
45 .catchError((e) { 362 .catchError((e) {
46 _sendResourceResponse(sp, id, e.toString()); 363 _sendResourceResponse(sp, tag, uri, libraryUrl, e.toString());
47 }); 364 });
48 // It's just here to push an event on the event loop so that we invoke the 365 // It's just here to push an event on the event loop so that we invoke the
49 // scheduled microtasks. 366 // scheduled microtasks.
50 Timer.run(() {}); 367 Timer.run(() {});
51 } 368 }
52 369
53 void _loadFile(SendPort sp, int id, Uri uri) { 370 void _loadFile(SendPort sp,
54 var path = uri.toFilePath(); 371 int tag,
372 Uri uri,
373 Uri resolvedUri,
374 String libraryUrl) {
375 var path = resolvedUri.toFilePath();
55 var sourceFile = new File(path); 376 var sourceFile = new File(path);
56 sourceFile.readAsBytes().then((data) { 377 sourceFile.readAsBytes().then((data) {
57 _sendResourceResponse(sp, id, data); 378 _sendResourceResponse(sp, tag, uri, libraryUrl, data);
58 }, 379 },
59 onError: (e) { 380 onError: (e) {
60 _sendResourceResponse(sp, id, e.toString()); 381 _sendResourceResponse(sp, tag, uri, libraryUrl, e.toString());
61 }); 382 });
62 } 383 }
63 384
64 void _loadDataUri(SendPort sp, int id, Uri uri) { 385 void _loadDataUri(SendPort sp,
386 int tag,
387 Uri uri,
388 Uri resolvedUri,
389 String libraryUrl) {
65 try { 390 try {
66 var mime = uri.data.mimeType; 391 var mime = uri.data.mimeType;
67 if ((mime != "application/dart") && 392 if ((mime != "application/dart") &&
68 (mime != "text/plain")) { 393 (mime != "text/plain")) {
69 throw "MIME-type must be application/dart or text/plain: $mime given."; 394 throw "MIME-type must be application/dart or text/plain: $mime given.";
70 } 395 }
71 var charset = uri.data.charset; 396 var charset = uri.data.charset;
72 if ((charset != "utf-8") && 397 if ((charset != "utf-8") &&
73 (charset != "US-ASCII")) { 398 (charset != "US-ASCII")) {
74 // The C++ portion of the embedder assumes UTF-8. 399 // The C++ portion of the embedder assumes UTF-8.
75 throw "Only utf-8 or US-ASCII encodings are supported: $charset given."; 400 throw "Only utf-8 or US-ASCII encodings are supported: $charset given.";
76 } 401 }
77 _sendResourceResponse(sp, id, uri.data.contentAsBytes()); 402 _sendResourceResponse(sp, tag, uri, libraryUrl, uri.data.contentAsBytes());
78 } catch (e) { 403 } catch (e) {
79 _sendResourceResponse(sp, id, "Invalid data uri ($uri):\n $e"); 404 _sendResourceResponse(sp, tag, uri, libraryUrl,
405 "Invalid data uri ($uri):\n $e");
80 } 406 }
81 } 407 }
82 408
83 _handleResourceRequest(SendPort sp, bool traceLoading, int id, Uri resource) { 409 // Loading a package URI needs to first map the package name to a loadable
84 if (resource.scheme == 'file') { 410 // URI.
85 _loadFile(sp, id, resource); 411 _loadPackage(IsolateLoaderState loaderState,
86 } else if ((resource.scheme == 'http') || (resource.scheme == 'https')) { 412 SendPort sp,
87 _loadHttp(sp, id, resource); 413 bool traceLoading,
88 } else if ((resource.scheme == 'data')) { 414 int tag,
89 _loadDataUri(sp, id, resource); 415 Uri uri,
416 Uri resolvedUri,
417 String libraryUrl) {
418 if (loaderState._packagesReady) {
419 var resolvedUri;
420 try {
421 resolvedUri = loaderState._resolvePackageUri(uri);
422 } catch (e, s) {
423 if (traceLoading) {
424 _log("Exception ($e) when resolving package URI: $uri");
425 }
426 // Report error.
427 _sendResourceResponse(sp,
428 tag,
429 uri,
430 libraryUrl,
431 e.toString());
432 return;
433 }
434 // Recursively call with the new resolved uri.
435 _handleResourceRequest(loaderState,
436 sp,
437 traceLoading,
438 tag,
439 uri,
440 resolvedUri,
441 libraryUrl);
90 } else { 442 } else {
91 _sendResourceResponse(sp, id, 443 if (loaderState._pendingPackageLoads.isEmpty) {
92 'Unknown scheme (${resource.scheme}) for $resource'); 444 // Package resolution has not been setup yet, and this is the first
445 // request for package resolution & loading.
446 loaderState._requestPackagesMap();
447 }
448 // Register the action of loading this package once the package resolution
449 // is ready.
450 loaderState._pendingPackageLoads.add(() {
451 _handleResourceRequest(loaderState,
452 sp,
453 traceLoading,
454 tag,
455 uri,
456 uri,
457 libraryUrl);
458 });
459 if (traceLoading) {
460 _log("Pending package load of '$uri': "
461 "${loaderState._pendingPackageLoads.length} pending");
462 }
93 } 463 }
94 } 464 }
95 465
466 // TODO(johnmccutchan): This and most other top level functions in this file
467 // should be turned into methods on the IsolateLoaderState class.
468 _handleResourceRequest(IsolateLoaderState loaderState,
469 SendPort sp,
470 bool traceLoading,
471 int tag,
472 Uri uri,
473 Uri resolvedUri,
474 String libraryUrl) {
475 if (resolvedUri.scheme == 'file') {
476 _loadFile(sp, tag, uri, resolvedUri, libraryUrl);
477 } else if ((resolvedUri.scheme == 'http') ||
478 (resolvedUri.scheme == 'https')) {
479 _loadHttp(sp, tag, uri, resolvedUri, libraryUrl);
480 } else if ((resolvedUri.scheme == 'data')) {
481 _loadDataUri(sp, tag, uri, resolvedUri, libraryUrl);
482 } else if ((resolvedUri.scheme == 'package')) {
483 _loadPackage(loaderState,
484 sp,
485 traceLoading,
486 tag,
487 uri,
488 resolvedUri,
489 libraryUrl);
490 } else {
491 _sendResourceResponse(sp, tag,
492 uri,
493 libraryUrl,
494 'Unknown scheme (${resolvedUri.scheme}) for '
495 '$resolvedUri');
496 }
497 }
96 498
97 // Handling of packages requests. Finding and parsing of .packages file or 499 // Handling of packages requests. Finding and parsing of .packages file or
98 // packages/ directories. 500 // packages/ directories.
99 const _LF = 0x0A; 501 const _LF = 0x0A;
100 const _CR = 0x0D; 502 const _CR = 0x0D;
101 const _SPACE = 0x20; 503 const _SPACE = 0x20;
102 const _HASH = 0x23; 504 const _HASH = 0x23;
103 const _DOT = 0x2E; 505 const _DOT = 0x2E;
104 const _COLON = 0x3A; 506 const _COLON = 0x3A;
105 const _DEL = 0x7F; 507 const _DEL = 0x7F;
(...skipping 216 matching lines...) Expand 10 before | Expand all | Expand 10 after
322 } 724 }
323 sp.send("Could not resolve a package location for base at $base"); 725 sp.send("Could not resolve a package location for base at $base");
324 } catch (e, s) { 726 } catch (e, s) {
325 if (traceLoading) { 727 if (traceLoading) {
326 _log("Error loading packages: $e\n$s"); 728 _log("Error loading packages: $e\n$s");
327 } 729 }
328 sp.send("Uncaught error ($e) loading packages file."); 730 sp.send("Uncaught error ($e) loading packages file.");
329 } 731 }
330 } 732 }
331 733
332
333 Future<bool> _loadHttpPackagesFile(SendPort sp, 734 Future<bool> _loadHttpPackagesFile(SendPort sp,
334 bool traceLoading, 735 bool traceLoading,
335 Uri resource) async { 736 Uri resource) async {
336 try { 737 try {
337 if (_httpClient == null) { 738 if (_httpClient == null) {
338 _httpClient = new HttpClient()..maxConnectionsPerHost = 6; 739 _httpClient = new HttpClient()..maxConnectionsPerHost = 6;
339 } 740 }
340 if (traceLoading) { 741 if (traceLoading) {
341 _log("Fetching packages file from '$resource'."); 742 _log("Fetching packages file from '$resource'.");
342 } 743 }
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
379 (charset != "US-ASCII")) { 780 (charset != "US-ASCII")) {
380 // The C++ portion of the embedder assumes UTF-8. 781 // The C++ portion of the embedder assumes UTF-8.
381 throw "Only utf-8 or US-ASCII encodings are supported: $charset given."; 782 throw "Only utf-8 or US-ASCII encodings are supported: $charset given.";
382 } 783 }
383 _parsePackagesFile(sp, traceLoading, resource, data.contentAsBytes()); 784 _parsePackagesFile(sp, traceLoading, resource, data.contentAsBytes());
384 } catch (e) { 785 } catch (e) {
385 sp.send("Uncaught error ($e) loading packages data."); 786 sp.send("Uncaught error ($e) loading packages data.");
386 } 787 }
387 } 788 }
388 789
389 790 // This code used to exist in a second isolate and so it uses a SendPort to
791 // report it's return value. This could be refactored so that it returns it's
792 // value and the caller could wait on the future rather than a message on
793 // SendPort.
390 _handlePackagesRequest(SendPort sp, 794 _handlePackagesRequest(SendPort sp,
391 bool traceLoading, 795 bool traceLoading,
392 int id, 796 int tag,
393 Uri resource) async { 797 Uri resource) async {
394 try { 798 try {
395 if (id == -1) { 799 if (tag == -1) {
396 if (resource.scheme == 'file') { 800 if (resource.scheme == 'file') {
397 _findPackagesFile(sp, traceLoading, resource); 801 _findPackagesFile(sp, traceLoading, resource);
398 } else if ((resource.scheme == 'http') || (resource.scheme == 'https')) { 802 } else if ((resource.scheme == 'http') || (resource.scheme == 'https')) {
399 // Try to load the .packages file next to the resource. 803 // Try to load the .packages file next to the resource.
400 var packagesUri = resource.resolve(".packages"); 804 var packagesUri = resource.resolve(".packages");
401 var exists = await _loadHttpPackagesFile(sp, traceLoading, packagesUri); 805 var exists = await _loadHttpPackagesFile(sp, traceLoading, packagesUri);
402 if (!exists) { 806 if (!exists) {
403 // If the loading of the .packages file failed for http/https based 807 // If the loading of the .packages file failed for http/https based
404 // scripts then setup the package root. 808 // scripts then setup the package root.
405 var packageRoot = resource.resolve('packages/'); 809 var packageRoot = resource.resolve('packages/');
406 sp.send([packageRoot.toString()]); 810 sp.send([packageRoot.toString()]);
407 } 811 }
408 } else { 812 } else {
409 sp.send("Unsupported scheme used to locate .packages file: " 813 sp.send("Unsupported scheme used to locate .packages file: "
410 "'$resource'."); 814 "'$resource'.");
411 } 815 }
412 } else if (id == -2) { 816 } else if (tag == -2) {
413 if (traceLoading) { 817 if (traceLoading) {
414 _log("Handling load of packages map: '$resource'."); 818 _log("Handling load of packages map: '$resource'.");
415 } 819 }
416 if (resource.scheme == 'file') { 820 if (resource.scheme == 'file') {
417 var exists = await new File.fromUri(resource).exists(); 821 var exists = await new File.fromUri(resource).exists();
418 if (exists) { 822 if (exists) {
419 _loadPackagesFile(sp, traceLoading, resource); 823 _loadPackagesFile(sp, traceLoading, resource);
420 } else { 824 } else {
421 sp.send("Packages file '$resource' not found."); 825 sp.send("Packages file '$resource' not found.");
422 } 826 }
423 } else if ((resource.scheme == 'http') || (resource.scheme == 'https')) { 827 } else if ((resource.scheme == 'http') || (resource.scheme == 'https')) {
424 var exists = await _loadHttpPackagesFile(sp, traceLoading, resource); 828 var exists = await _loadHttpPackagesFile(sp, traceLoading, resource);
425 if (!exists) { 829 if (!exists) {
426 sp.send("Packages file '$resource' not found."); 830 sp.send("Packages file '$resource' not found.");
427 } 831 }
428 } else if (resource.scheme == 'data') { 832 } else if (resource.scheme == 'data') {
429 _loadPackagesData(sp, traceLoading, resource); 833 _loadPackagesData(sp, traceLoading, resource);
430 } else { 834 } else {
431 sp.send("Unknown scheme (${resource.scheme}) for package file at " 835 sp.send("Unknown scheme (${resource.scheme}) for package file at "
432 "'$resource'."); 836 "'$resource'.");
433 } 837 }
434 } else { 838 } else {
435 sp.send("Unknown packages request id: $id for '$resource'."); 839 sp.send("Unknown packages request tag: $tag for '$resource'.");
436 } 840 }
437 } catch (e, s) { 841 } catch (e, s) {
438 if (traceLoading) { 842 if (traceLoading) {
439 _log("Error handling packages request: $e\n$s"); 843 _log("Error handling packages request: $e\n$s");
440 } 844 }
441 sp.send("Uncaught error ($e) handling packages request."); 845 sp.send("Uncaught error ($e) handling packages request.");
442 } 846 }
443 } 847 }
444 848
849 // Shutdown all active loaders by sending an error message.
850 void shutdownLoaders() {
851 String message = 'Service shutdown';
852 if (_httpClient != null) {
853 _httpClient.close(force: true);
854 _httpClient = null;
855 }
856 isolateEmbedderData.values.toList().forEach((IsolateLoaderState ils) {
857 ils.cleanup();
858 assert(ils.sp != null);
859 _sendResourceResponse(ils.sp, 1, null, null, message);
860 });
861 }
862
863 // See Dart_LibraryTag in dart_api.h
864 const _Dart_kCanonicalizeUrl = 0; // Canonicalize the URL.
865 const _Dart_kScriptTag = 1; // Load the root script.
866 const _Dart_kSourceTag = 2; // Load a part source.
867 const _Dart_kImportTag = 3; // Import a library.
868
869 // Extra requests. Keep these in sync between loader.dart and builtin.dart.
870 const _Dart_kInitLoader = 4; // Initialize the loader.
871 const _Dart_kResourceLoad = 5; // Resource class support.
872 const _Dart_kGetPackageRootUri = 6; // Uri of the packages/ directory.
873 const _Dart_kGetPackageConfigUri = 7; // Uri of the .packages file.
874 const _Dart_kResolvePackageUri = 8; // Resolve a package: uri.
445 875
446 // External entry point for loader requests. 876 // External entry point for loader requests.
447 _processLoadRequest(request) { 877 _processLoadRequest(request) {
448 SendPort sp = request[0]; 878 assert(request is List);
449 assert(sp != null); 879 assert(request.length > 4);
450 bool traceLoading = request[1]; 880
451 assert(traceLoading != null); 881 // Should we trace loading?
452 int id = request[2]; 882 bool traceLoading = request[0];
453 assert(id != null); 883
454 String resource = request[3]; 884 // This is the sending isolate's Dart_GetMainPortId().
455 assert(resource != null); 885 int isolateId = request[1];
456 var uri = Uri.parse(resource); 886
457 if (id >= 0) { 887 // The tag describing the operation.
458 _handleResourceRequest(sp, traceLoading, id, uri); 888 int tag = request[2];
459 } else { 889
460 _handlePackagesRequest(sp, traceLoading, id, uri); 890 // The send port to send the response on.
891 SendPort sp = request[3];
892
893 // Grab the loader state for the requesting isolate.
894 IsolateLoaderState loaderState = isolateEmbedderData[isolateId];
895
896 // We are either about to initialize the loader, or, we already have.
897 assert((tag == _Dart_kInitLoader) || (loaderState != null));
898
899 // Handle the request specified in the tag.
900 switch (tag) {
901 case _Dart_kScriptTag: {
902 Uri uri = Uri.parse(request[4]);
903 // Remember the root script.
904 loaderState._rootScript = uri;
905 _handleResourceRequest(loaderState,
906 sp,
907 traceLoading,
908 tag,
909 uri,
910 uri,
911 null);
912 }
913 break;
914 case _Dart_kSourceTag:
915 case _Dart_kImportTag: {
916 // The url of the file being loaded.
917 var uri = Uri.parse(request[4]);
918 // The library that is importing/parting the file.
919 String libraryUrl = request[5];
920 _handleResourceRequest(loaderState,
921 sp,
922 traceLoading,
923 tag,
924 uri,
925 uri,
926 libraryUrl);
927 }
928 break;
929 case _Dart_kInitLoader: {
930 String packageRoot = request[4];
931 String packagesFile = request[5];
932 String workingDirectory = request[6];
933 String rootScript = request[7];
934 if (loaderState == null) {
935 loaderState = new IsolateLoaderState(isolateId);
936 isolateEmbedderData[isolateId] = loaderState;
937 loaderState.init(packageRoot,
938 packagesFile,
939 workingDirectory,
940 rootScript);
941 }
942 loaderState.sp = sp;
943 assert(isolateEmbedderData[isolateId] == loaderState);
944 }
945 break;
946 case _Dart_kResourceLoad: {
947 Uri uri = Uri.parse(request[4]);
948 _handleResourceRequest(loaderState,
949 sp,
950 traceLoading,
951 tag,
952 uri,
953 uri,
954 null);
955 }
956 break;
957 case _Dart_kGetPackageRootUri:
958 loaderState._triggerPackageResolution(() {
959 // Respond with the package root (if any) after package resolution.
960 sp.send(loaderState._packageRoot);
961 });
962 break;
963 case _Dart_kGetPackageConfigUri:
964 loaderState._triggerPackageResolution(() {
965 // Respond with the packages config (if any) after package resolution.
966 sp.send(loaderState._packageConfig);
967 });
968 break;
969 case _Dart_kResolvePackageUri:
970 Uri uri = Uri.parse(request[4]);
971 loaderState._triggerPackageResolution(() {
972 // Respond with the resolved package uri after package resolution.
973 Uri resolvedUri;
974 try {
975 resolvedUri = loaderState._resolvePackageUri(uri);
976 } catch (e, s) {
977 if (traceLoading) {
978 _log("Exception ($e) when resolving package URI: $uri");
979 }
980 resolvedUri = null;
981 }
982 sp.send(resolvedUri);
983 });
984 break;
985 default:
986 _log('Unknown loader request tag=$tag from $isolateId');
461 } 987 }
462 } 988 }
OLDNEW
« no previous file with comments | « runtime/bin/main.cc ('k') | runtime/bin/vmservice/vmservice_io.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698