OLD | NEW |
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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 library builtin; | 5 library builtin; |
6 // NOTE: Do not import 'dart:io' in builtin. | 6 // NOTE: Do not import 'dart:io' in builtin. |
| 7 import 'dart:async'; |
7 import 'dart:collection'; | 8 import 'dart:collection'; |
| 9 import 'dart:_internal'; |
8 import 'dart:isolate'; | 10 import 'dart:isolate'; |
9 import 'dart:typed_data'; | 11 import 'dart:typed_data'; |
10 | 12 |
| 13 |
| 14 // Before handling an embedder entrypoint we finalize the setup of the |
| 15 // dart:_builtin library. |
| 16 bool _setupCompleted = false; |
| 17 |
| 18 |
11 // The root library (aka the script) is imported into this library. The | 19 // The root library (aka the script) is imported into this library. The |
12 // standalone embedder uses this to lookup the main entrypoint in the | 20 // standalone embedder uses this to lookup the main entrypoint in the |
13 // root library's namespace. | 21 // root library's namespace. |
14 Function _getMainClosure() => main; | 22 Function _getMainClosure() => main; |
15 | 23 |
16 | 24 |
17 // 'print' implementation. | 25 // 'print' implementation. |
18 // The standalone embedder registers the closurized _print function with the | 26 // The standalone embedder registers the closurized _print function with the |
19 // dart:core library. | 27 // dart:core library. |
20 void _printString(String s) native "Builtin_PrintString"; | 28 void _printString(String s) native "Builtin_PrintString"; |
(...skipping 21 matching lines...) Expand all Loading... |
42 } | 50 } |
43 | 51 |
44 | 52 |
45 _getUriBaseClosure() => _uriBase; | 53 _getUriBaseClosure() => _uriBase; |
46 | 54 |
47 | 55 |
48 // Asynchronous loading of resources. | 56 // Asynchronous loading of resources. |
49 // The embedder forwards most loading requests to this library. | 57 // The embedder forwards most loading requests to this library. |
50 | 58 |
51 // See Dart_LibraryTag in dart_api.h | 59 // See Dart_LibraryTag in dart_api.h |
52 const Dart_kScriptTag = null; | 60 const _Dart_kScriptTag = null; |
53 const Dart_kImportTag = 0; | 61 const _Dart_kImportTag = 0; |
54 const Dart_kSourceTag = 1; | 62 const _Dart_kSourceTag = 1; |
55 const Dart_kCanonicalizeUrl = 2; | 63 const _Dart_kCanonicalizeUrl = 2; |
| 64 const _Dart_kResourceLoad = 3; |
56 | 65 |
57 // Embedder sets this to true if the --trace-loading flag was passed on the | 66 // Embedder sets this to true if the --trace-loading flag was passed on the |
58 // command line. | 67 // command line. |
59 bool _traceLoading = false; | 68 bool _traceLoading = false; |
60 | 69 |
61 // A port for communicating with the service isolate for I/O. | 70 // A port for communicating with the service isolate for I/O. |
62 SendPort _loadPort; | 71 SendPort _loadPort; |
63 // The receive port for a load request. Multiple sources can be fetched in | 72 // The receive port for a load request. Multiple sources can be fetched in |
64 // a single load request. | 73 // a single load request. |
65 RawReceivePort _receivePort; | 74 RawReceivePort _receivePort; |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
112 _LoadError(this.uri, this.message); | 121 _LoadError(this.uri, this.message); |
113 | 122 |
114 String toString() => 'Load Error for "$uri": $message'; | 123 String toString() => 'Load Error for "$uri": $message'; |
115 } | 124 } |
116 | 125 |
117 // Class collecting all of the information about a particular load request. | 126 // Class collecting all of the information about a particular load request. |
118 class _LoadRequest { | 127 class _LoadRequest { |
119 final int _id; | 128 final int _id; |
120 final int _tag; | 129 final int _tag; |
121 final String _uri; | 130 final String _uri; |
122 final String _libraryUri; | |
123 final Uri _resourceUri; | 131 final Uri _resourceUri; |
| 132 final _context; |
124 | 133 |
125 _LoadRequest(this._id, | 134 _LoadRequest(this._id, |
126 this._tag, | 135 this._tag, |
127 this._uri, | 136 this._uri, |
128 this._libraryUri, | 137 this._resourceUri, |
129 this._resourceUri); | 138 this._context); |
130 | 139 |
131 toString() => "LoadRequest($_id, $_tag, $_uri, $_libraryUri, $_resourceUri)"; | 140 toString() => "LoadRequest($_id, $_tag, $_uri, $_resourceUri, $_context)"; |
132 } | 141 } |
133 | 142 |
134 | 143 |
135 // Native calls provided by the embedder. | 144 // Native calls provided by the embedder. |
136 void _signalDoneLoading() native "Builtin_DoneLoading"; | 145 void _signalDoneLoading() native "Builtin_DoneLoading"; |
137 void _loadScriptCallback(int tag, String uri, String libraryUri, Uint8List data) | 146 void _loadScriptCallback(int tag, String uri, String libraryUri, Uint8List data) |
138 native "Builtin_LoadSource"; | 147 native "Builtin_LoadSource"; |
139 void _asyncLoadErrorCallback(uri, libraryUri, error) | 148 void _asyncLoadErrorCallback(uri, libraryUri, error) |
140 native "Builtin_AsyncLoadError"; | 149 native "Builtin_AsyncLoadError"; |
141 | 150 |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
188 if (!uri.endsWith('/')) { | 197 if (!uri.endsWith('/')) { |
189 return '$uri/'; | 198 return '$uri/'; |
190 } | 199 } |
191 return uri; | 200 return uri; |
192 } | 201 } |
193 | 202 |
194 | 203 |
195 // Embedder Entrypoint: | 204 // Embedder Entrypoint: |
196 // The embedder calls this method with the current working directory. | 205 // The embedder calls this method with the current working directory. |
197 void _setWorkingDirectory(cwd) { | 206 void _setWorkingDirectory(cwd) { |
| 207 if (!_setupCompleted) { |
| 208 _setupHooks(); |
| 209 } |
198 if (_traceLoading) { | 210 if (_traceLoading) { |
199 _log('Setting working directory: $cwd'); | 211 _log('Setting working directory: $cwd'); |
200 } | 212 } |
201 _workingDirectory = new Uri.directory(cwd); | 213 _workingDirectory = new Uri.directory(cwd); |
202 if (_traceLoading) { | 214 if (_traceLoading) { |
203 _log('Working directory URI: $_workingDirectory'); | 215 _log('Working directory URI: $_workingDirectory'); |
204 } | 216 } |
205 } | 217 } |
206 | 218 |
207 | 219 |
208 // Embedder Entrypoint: | 220 // Embedder Entrypoint: |
209 // The embedder calls this method with a custom package root. | 221 // The embedder calls this method with a custom package root. |
210 _setPackageRoot(String packageRoot) { | 222 _setPackageRoot(String packageRoot) { |
| 223 if (!_setupCompleted) { |
| 224 _setupHooks(); |
| 225 } |
211 if (_traceLoading) { | 226 if (_traceLoading) { |
212 _log('Setting package root: $packageRoot'); | 227 _log('Setting package root: $packageRoot'); |
213 } | 228 } |
214 packageRoot = _enforceTrailingSlash(packageRoot); | 229 packageRoot = _enforceTrailingSlash(packageRoot); |
215 if (packageRoot.startsWith('file:') || | 230 if (packageRoot.startsWith('file:') || |
216 packageRoot.startsWith('http:') || | 231 packageRoot.startsWith('http:') || |
217 packageRoot.startsWith('https:')) { | 232 packageRoot.startsWith('https:')) { |
218 _packageRoot = _workingDirectory.resolve(packageRoot); | 233 _packageRoot = _workingDirectory.resolve(packageRoot); |
219 } else { | 234 } else { |
220 packageRoot = _sanitizeWindowsPath(packageRoot); | 235 packageRoot = _sanitizeWindowsPath(packageRoot); |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
316 } | 331 } |
317 | 332 |
318 | 333 |
319 void _handleLoaderReply(msg) { | 334 void _handleLoaderReply(msg) { |
320 int id = msg[0]; | 335 int id = msg[0]; |
321 var dataOrError = msg[1]; | 336 var dataOrError = msg[1]; |
322 assert((id >= 0) && (id < _reqId)); | 337 assert((id >= 0) && (id < _reqId)); |
323 var req = _reqMap[id]; | 338 var req = _reqMap[id]; |
324 try { | 339 try { |
325 if (dataOrError is Uint8List) { | 340 if (dataOrError is Uint8List) { |
326 _loadScript(req, dataOrError); | 341 // Successfully loaded the data. |
| 342 if (req._tag == _Dart_kResourceLoad) { |
| 343 Completer c = req._context; |
| 344 c.complete(dataOrError); |
| 345 } else { |
| 346 // TODO: Currently a compilation error while loading the script is |
| 347 // fatal for the isolate. _loadScriptCallback() does not return and |
| 348 // the number of requests remains out of sync. |
| 349 _loadScriptCallback(req._tag, req._uri, req._context, dataOrError); |
| 350 } |
| 351 _finishLoadRequest(req); |
327 } else { | 352 } else { |
328 assert(dataOrError is String); | 353 assert(dataOrError is String); |
329 var error = new _LoadError(req._uri, dataOrError.toString()); | 354 var error = new _LoadError(req._uri, dataOrError.toString()); |
330 _asyncLoadError(req, error); | 355 _asyncLoadError(req, error, null); |
331 } | 356 } |
332 } catch(e, s) { | 357 } catch(e, s) { |
333 // Wrap inside a _LoadError unless we are already propagating a | 358 // Wrap inside a _LoadError unless we are already propagating a |
334 // previous _LoadError. | 359 // previous _LoadError. |
335 var error = (e is _LoadError) ? e : new _LoadError(req._uri, e.toString()); | 360 var error = (e is _LoadError) ? e : new _LoadError(req._uri, e.toString()); |
336 assert(req != null); | 361 assert(req != null); |
337 _asyncLoadError(req, error); | 362 _asyncLoadError(req, error, s); |
338 } | 363 } |
339 } | 364 } |
340 | 365 |
341 | 366 |
342 void _startLoadRequest(int tag, | 367 void _startLoadRequest(int tag, String uri, Uri resourceUri, context) { |
343 String uri, | |
344 String libraryUri, | |
345 Uri resourceUri) { | |
346 if (_receivePort == null) { | 368 if (_receivePort == null) { |
347 if (_traceLoading) { | 369 if (_traceLoading) { |
348 _log("Initializing load port."); | 370 _log("Initializing load port."); |
349 } | 371 } |
350 assert(_receivePort == null); | 372 assert(_receivePort == null); |
351 assert(_sendPort == null); | 373 assert(_sendPort == null); |
352 _receivePort = new RawReceivePort(_handleLoaderReply); | 374 _receivePort = new RawReceivePort(_handleLoaderReply); |
353 _sendPort = _receivePort.sendPort; | 375 _sendPort = _receivePort.sendPort; |
354 } | 376 } |
355 // Register the load request and send it to the VM service isolate. | 377 // Register the load request and send it to the VM service isolate. |
356 var curId = _reqId++; | 378 var curId = _reqId++; |
357 | 379 |
358 assert(_reqMap[curId] == null); | 380 assert(_reqMap[curId] == null); |
359 _reqMap[curId] = new _LoadRequest(curId, tag, uri, libraryUri, resourceUri); | 381 _reqMap[curId] = new _LoadRequest(curId, tag, uri, resourceUri, context); |
360 | 382 |
361 assert(_receivePort != null); | 383 assert(_receivePort != null); |
362 assert(_sendPort != null); | 384 assert(_sendPort != null); |
363 | 385 |
364 var msg = new List(4); | 386 var msg = new List(4); |
365 msg[0] = _sendPort; | 387 msg[0] = _sendPort; |
366 msg[1] = _traceLoading; | 388 msg[1] = _traceLoading; |
367 msg[2] = curId; | 389 msg[2] = curId; |
368 msg[3] = resourceUri.toString(); | 390 msg[3] = resourceUri.toString(); |
369 _loadPort.send(msg); | 391 _loadPort.send(msg); |
370 | 392 |
371 if (_traceLoading) { | 393 if (_traceLoading) { |
372 _log("Loading of $resourceUri for $uri started with id: $curId, " | 394 _log("Loading of $resourceUri for $uri started with id: $curId. " |
373 "${_reqMap.length} requests outstanding"); | 395 "${_reqMap.length} requests remaining, " |
| 396 "${_pendingPackageLoads.length} packages pending."); |
374 } | 397 } |
375 } | 398 } |
376 | 399 |
377 | 400 |
378 RawReceivePort _packagesPort; | 401 RawReceivePort _packagesPort; |
379 | 402 |
380 void _handlePackagesReply(msg) { | 403 void _handlePackagesReply(msg) { |
381 // Make sure to close the _packagePort before any other action. | 404 // Make sure to close the _packagePort before any other action. |
382 _packagesPort.close(); | 405 _packagesPort.close(); |
383 | 406 |
(...skipping 17 matching lines...) Expand all Loading... |
401 for (var i = 0; i < msg.length; i+=2) { | 424 for (var i = 0; i < msg.length; i+=2) { |
402 // TODO(iposva): Complain about duplicate entries. | 425 // TODO(iposva): Complain about duplicate entries. |
403 _packageMap[msg[i]] = Uri.parse(msg[i+1]); | 426 _packageMap[msg[i]] = Uri.parse(msg[i+1]); |
404 } | 427 } |
405 if (_traceLoading) { | 428 if (_traceLoading) { |
406 _log("Setup package map: $_packageMap"); | 429 _log("Setup package map: $_packageMap"); |
407 } | 430 } |
408 } | 431 } |
409 | 432 |
410 // Resolve all pending package loads now that we know how to resolve them. | 433 // Resolve all pending package loads now that we know how to resolve them. |
411 for (var i = 0; i < _pendingPackageLoads.length; i++) { | 434 while (_pendingPackageLoads.length > 0) { |
412 var req = _pendingPackageLoads[i]; | 435 var req = _pendingPackageLoads.removeLast(); |
413 if (req != null) { | 436 if (req != null) { |
414 if (_traceLoading) { | 437 if (_traceLoading) { |
415 _log("Handling deferred load request: $req"); | 438 _log("Handling deferred load request: $req"); |
416 } | 439 } |
417 _loadPackage(req._tag, req._uri, req._libraryUri, req._resourceUri); | 440 _loadPackage(req._tag, req._uri, req._resourceUri, req._context); |
| 441 } else { |
| 442 if (_traceLoading) { |
| 443 _log("Skipping dummy deferred request."); |
| 444 } |
418 } | 445 } |
419 } | 446 } |
420 // Reset the pending package loads to empty. So that we eventually can | 447 // Reset the pending package loads to empty. So that we eventually can |
421 // finish loading. | 448 // finish loading. |
422 _pendingPackageLoads = []; | 449 _pendingPackageLoads = []; |
423 } | 450 } |
424 | 451 |
425 | 452 |
426 void _requestPackagesMap() { | 453 void _requestPackagesMap() { |
427 assert(_packagesPort == null); | 454 assert(_packagesPort == null); |
(...skipping 11 matching lines...) Expand all Loading... |
439 | 466 |
440 if (_traceLoading) { | 467 if (_traceLoading) { |
441 _log("Requested packages map for '$_rootScript'."); | 468 _log("Requested packages map for '$_rootScript'."); |
442 } | 469 } |
443 } | 470 } |
444 | 471 |
445 | 472 |
446 // Embedder Entrypoint: | 473 // Embedder Entrypoint: |
447 // Request the load of a particular packages map. | 474 // Request the load of a particular packages map. |
448 void _loadPackagesMap(String packagesParam) { | 475 void _loadPackagesMap(String packagesParam) { |
| 476 if (!_setupCompleted) { |
| 477 _setupHooks(); |
| 478 } |
449 // First convert the packages parameter from the command line to a URI which | 479 // First convert the packages parameter from the command line to a URI which |
450 // can be handled by the loader code. | 480 // can be handled by the loader code. |
451 // TODO(iposva): Consider refactoring the common code below which is almost | 481 // TODO(iposva): Consider refactoring the common code below which is almost |
452 // shared with resolution of the root script. | 482 // shared with resolution of the root script. |
453 if (_traceLoading) { | 483 if (_traceLoading) { |
454 _log("Resolving packages map: $packagesParam"); | 484 _log("Resolving packages map: $packagesParam"); |
455 } | 485 } |
456 if (_workingDirectory == null) { | 486 if (_workingDirectory == null) { |
457 throw 'No current working directory set.'; | 487 throw 'No current working directory set.'; |
458 } | 488 } |
(...skipping 24 matching lines...) Expand all Loading... |
483 // Signal that the resolution of the packages map has started. But in this | 513 // Signal that the resolution of the packages map has started. But in this |
484 // case it is not tied to a particular request. | 514 // case it is not tied to a particular request. |
485 _pendingPackageLoads.add(null); | 515 _pendingPackageLoads.add(null); |
486 | 516 |
487 if (_traceLoading) { | 517 if (_traceLoading) { |
488 _log("Requested packages map at '$packagesUri'."); | 518 _log("Requested packages map at '$packagesUri'."); |
489 } | 519 } |
490 } | 520 } |
491 | 521 |
492 | 522 |
493 void _loadScript(_LoadRequest req, Uint8List data) { | 523 void _asyncLoadError(_LoadRequest req, _LoadError error, StackTrace stack) { |
494 // TODO: Currently a compilation error while loading the script is | 524 if (_traceLoading) { |
495 // fatal for the isolate. _loadScriptCallback() does not return and | 525 _log("_asyncLoadError(${req._uri}), error: $error\nstack: $stack"); |
496 // the number of requests remains out of sync. | 526 } |
497 _loadScriptCallback(req._tag, req._uri, req._libraryUri, data); | 527 if (req._tag == _Dart_kResourceLoad) { |
| 528 Completer c = req._context; |
| 529 c.completeError(error, stack); |
| 530 } else { |
| 531 Uri libraryUri = req._context; |
| 532 if (req._tag == _Dart_kImportTag) { |
| 533 // When importing a library, the libraryUri is the imported |
| 534 // uri. |
| 535 libraryUri = req._uri; |
| 536 } |
| 537 _asyncLoadErrorCallback(req._uri, libraryUri, error); |
| 538 } |
498 _finishLoadRequest(req); | 539 _finishLoadRequest(req); |
499 } | 540 } |
500 | 541 |
501 | 542 |
502 void _asyncLoadError(_LoadRequest req, _LoadError error) { | 543 _loadDataFromLoadPort(int tag, String uri, Uri resourceUri, context) { |
503 if (_traceLoading) { | |
504 _log("_asyncLoadError(${req._uri}), error: $error"); | |
505 } | |
506 var libraryUri = req._libraryUri; | |
507 if (req._tag == Dart_kImportTag) { | |
508 // When importing a library, the libraryUri is the imported | |
509 // uri. | |
510 libraryUri = req._uri; | |
511 } | |
512 _asyncLoadErrorCallback(req._uri, libraryUri, error); | |
513 _finishLoadRequest(req); | |
514 } | |
515 | |
516 | |
517 _loadDataFromLoadPort(int tag, | |
518 String uri, | |
519 String libraryUri, | |
520 Uri resourceUri) { | |
521 try { | 544 try { |
522 _startLoadRequest(tag, uri, libraryUri, resourceUri); | 545 _startLoadRequest(tag, uri, resourceUri, context); |
523 } catch (e) { | 546 } catch (e, s) { |
524 if (_traceLoading) { | 547 if (_traceLoading) { |
525 _log("Exception when communicating with service isolate: $e"); | 548 _log("Exception when communicating with service isolate: $e"); |
526 } | 549 } |
527 // Wrap inside a _LoadError unless we are already propagating a previously | 550 // Wrap inside a _LoadError unless we are already propagating a previously |
528 // seen _LoadError. | 551 // seen _LoadError. |
529 var error = (e is _LoadError) ? e : new _LoadError(e.toString()); | 552 var error = (e is _LoadError) ? e : new _LoadError(e.toString()); |
530 _asyncLoadError(tag, uri, libraryUri, error); | 553 _asyncLoadError(tag, uri, context, error, s); |
531 } | 554 } |
532 } | 555 } |
533 | 556 |
534 | 557 |
535 // Loading a package URI needs to first map the package name to a loadable | 558 // Loading a package URI needs to first map the package name to a loadable |
536 // URI. | 559 // URI. |
537 _loadPackage(int tag, String uri, String libraryUri, Uri resourceUri) { | 560 _loadPackage(int tag, String uri, Uri resourceUri, context) { |
538 if (_packagesReady()) { | 561 if (_packagesReady()) { |
539 _loadData(tag, uri, libraryUri, _resolvePackageUri(resourceUri)); | 562 _loadData(tag, uri, _resolvePackageUri(resourceUri), context); |
540 } else { | 563 } else { |
541 if (_pendingPackageLoads.isEmpty) { | 564 if (_pendingPackageLoads.isEmpty) { |
542 // Package resolution has not been setup yet, and this is the first | 565 // Package resolution has not been setup yet, and this is the first |
543 // request for package resolution & loading. | 566 // request for package resolution & loading. |
544 _requestPackagesMap(); | 567 _requestPackagesMap(); |
545 } | 568 } |
546 var req = new _LoadRequest(-1, tag, uri, libraryUri, resourceUri); | 569 var req = new _LoadRequest(-1, tag, uri, resourceUri, context); |
547 _pendingPackageLoads.add(req); | 570 _pendingPackageLoads.add(req); |
548 if (_traceLoading) { | 571 if (_traceLoading) { |
549 _log("Pending package load of '$uri': " | 572 _log("Pending package load of '$uri': " |
550 "${_pendingPackageLoads.length} pending"); | 573 "${_pendingPackageLoads.length} pending"); |
551 } | 574 } |
552 } | 575 } |
553 } | 576 } |
554 | 577 |
555 | 578 |
556 // Load the data associated with the resourceUri. | 579 // Load the data associated with the resourceUri. |
557 _loadData(int tag, String uri, String libraryUri, Uri resourceUri) { | 580 _loadData(int tag, String uri, Uri resourceUri, context) { |
558 if (resourceUri.scheme == 'package') { | 581 if (resourceUri.scheme == 'package') { |
559 // package based uris need to be resolved to the correct loadable location. | 582 // package based uris need to be resolved to the correct loadable location. |
560 // The logic of which is handled seperately, and then _loadData is called | 583 // The logic of which is handled seperately, and then _loadData is called |
561 // recursively. | 584 // recursively. |
562 _loadPackage(tag, uri, libraryUri, resourceUri); | 585 _loadPackage(tag, uri, resourceUri, context); |
563 } else { | 586 } else { |
564 _loadDataFromLoadPort(tag, uri, libraryUri, resourceUri); | 587 _loadDataFromLoadPort(tag, uri, resourceUri, context); |
565 } | 588 } |
566 } | 589 } |
567 | 590 |
568 | 591 |
569 // Embedder Entrypoint: | 592 // Embedder Entrypoint: |
570 // Asynchronously loads script data through a http[s] or file uri. | 593 // Asynchronously loads script data through a http[s] or file uri. |
571 _loadDataAsync(int tag, String uri, String libraryUri) { | 594 _loadDataAsync(int tag, String uri, String libraryUri) { |
| 595 if (!_setupCompleted) { |
| 596 _setupHooks(); |
| 597 } |
572 var resourceUri; | 598 var resourceUri; |
573 if (tag == Dart_kScriptTag) { | 599 if (tag == _Dart_kScriptTag) { |
574 resourceUri = _resolveScriptUri(uri); | 600 resourceUri = _resolveScriptUri(uri); |
575 uri = resourceUri.toString(); | 601 uri = resourceUri.toString(); |
576 } else { | 602 } else { |
577 resourceUri = Uri.parse(uri); | 603 resourceUri = Uri.parse(uri); |
578 } | 604 } |
579 _loadData(tag, uri, libraryUri, resourceUri); | 605 _loadData(tag, uri, resourceUri, libraryUri); |
580 } | 606 } |
581 | 607 |
582 | 608 |
583 // Embedder Entrypoint: | 609 // Embedder Entrypoint: |
584 // Function called by standalone embedder to resolve uris when the VM requests | 610 // Function called by standalone embedder to resolve uris when the VM requests |
585 // Dart_kCanonicalizeUrl from the tag handler. | 611 // Dart_kCanonicalizeUrl from the tag handler. |
586 String _resolveUri(String base, String userString) { | 612 String _resolveUri(String base, String userString) { |
| 613 if (!_setupCompleted) { |
| 614 _setupHooks(); |
| 615 } |
587 if (_traceLoading) { | 616 if (_traceLoading) { |
588 _log('Resolving: $userString from $base'); | 617 _log('Resolving: $userString from $base'); |
589 } | 618 } |
590 var baseUri = Uri.parse(base); | 619 var baseUri = Uri.parse(base); |
591 var result; | 620 var result; |
592 if (userString.startsWith(_DART_EXT)) { | 621 if (userString.startsWith(_DART_EXT)) { |
593 var uri = userString.substring(_DART_EXT.length); | 622 var uri = userString.substring(_DART_EXT.length); |
594 result = '$_DART_EXT${baseUri.resolve(uri)}'; | 623 result = '$_DART_EXT${baseUri.resolve(uri)}'; |
595 } else { | 624 } else { |
596 result = baseUri.resolve(userString).toString(); | 625 result = baseUri.resolve(userString).toString(); |
597 } | 626 } |
598 if (_traceLoading) { | 627 if (_traceLoading) { |
599 _log('Resolved $userString in $base to $result'); | 628 _log('Resolved $userString in $base to $result'); |
600 } | 629 } |
601 return result; | 630 return result; |
602 } | 631 } |
603 | 632 |
604 | 633 |
| 634 // Handling of Resource class by dispatching to the load port. |
| 635 Future<List<int>> _resourceReadAsBytes(Uri uri) { |
| 636 var completer = new Completer<List<int>>(); |
| 637 // Request the load of the resource associating the completer as the context |
| 638 // for the load. |
| 639 _loadData(_Dart_kResourceLoad, uri.toString(), uri, completer); |
| 640 // Return the future that will be triggered once the resource has been loaded. |
| 641 return completer.future; |
| 642 } |
| 643 |
| 644 |
605 // Embedder Entrypoint (gen_snapshot): | 645 // Embedder Entrypoint (gen_snapshot): |
606 // Resolve relative paths relative to working directory. | 646 // Resolve relative paths relative to working directory. |
607 String _resolveInWorkingDirectory(String fileName) { | 647 String _resolveInWorkingDirectory(String fileName) { |
| 648 if (!_setupCompleted) { |
| 649 _setupHooks(); |
| 650 } |
608 if (_workingDirectory == null) { | 651 if (_workingDirectory == null) { |
609 throw 'No current working directory set.'; | 652 throw 'No current working directory set.'; |
610 } | 653 } |
611 var name = _sanitizeWindowsPath(fileName); | 654 var name = _sanitizeWindowsPath(fileName); |
612 | 655 |
613 var uri = Uri.parse(name); | 656 var uri = Uri.parse(name); |
614 if (uri.scheme != '') { | 657 if (uri.scheme != '') { |
615 throw 'Schemes are not supported when resolving filenames.'; | 658 throw 'Schemes are not supported when resolving filenames.'; |
616 } | 659 } |
617 uri = _workingDirectory.resolveUri(uri); | 660 uri = _workingDirectory.resolveUri(uri); |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
672 | 715 |
673 // Embedder Entrypoint: | 716 // Embedder Entrypoint: |
674 // When loading an extension the embedder calls this method to get the | 717 // When loading an extension the embedder calls this method to get the |
675 // different components. | 718 // different components. |
676 // Returns the directory part, the filename part, and the name | 719 // Returns the directory part, the filename part, and the name |
677 // of a native extension URL as a list [directory, filename, name]. | 720 // of a native extension URL as a list [directory, filename, name]. |
678 // The directory part is either a file system path or an HTTP(S) URL. | 721 // The directory part is either a file system path or an HTTP(S) URL. |
679 // The filename part is the extension name, with the platform-dependent | 722 // The filename part is the extension name, with the platform-dependent |
680 // prefixes and extensions added. | 723 // prefixes and extensions added. |
681 _extensionPathFromUri(String userUri) { | 724 _extensionPathFromUri(String userUri) { |
| 725 if (!_setupCompleted) { |
| 726 _setupHooks(); |
| 727 } |
682 if (!userUri.startsWith(_DART_EXT)) { | 728 if (!userUri.startsWith(_DART_EXT)) { |
683 throw 'Unexpected internal error: Extension URI $userUri missing dart-ext:'; | 729 throw 'Unexpected internal error: Extension URI $userUri missing dart-ext:'; |
684 } | 730 } |
685 userUri = userUri.substring(_DART_EXT.length); | 731 userUri = userUri.substring(_DART_EXT.length); |
686 | 732 |
687 if (userUri.contains('\\')) { | 733 if (userUri.contains('\\')) { |
688 throw 'Unexpected internal error: Extension URI $userUri contains \\'; | 734 throw 'Unexpected internal error: Extension URI $userUri contains \\'; |
689 } | 735 } |
690 | 736 |
691 String name; | 737 String name; |
692 String path; // Will end in '/'. | 738 String path; // Will end in '/'. |
693 int index = userUri.lastIndexOf('/'); | 739 int index = userUri.lastIndexOf('/'); |
694 if (index == -1) { | 740 if (index == -1) { |
695 name = userUri; | 741 name = userUri; |
696 path = './'; | 742 path = './'; |
697 } else if (index == userUri.length - 1) { | 743 } else if (index == userUri.length - 1) { |
698 throw 'Extension name missing in $extensionUri'; | 744 throw 'Extension name missing in $extensionUri'; |
699 } else { | 745 } else { |
700 name = userUri.substring(index + 1); | 746 name = userUri.substring(index + 1); |
701 path = userUri.substring(0, index + 1); | 747 path = userUri.substring(0, index + 1); |
702 } | 748 } |
703 | 749 |
704 path = _filePathFromUri(path); | 750 path = _filePathFromUri(path); |
705 var filename = _platformExtensionFileName(name); | 751 var filename = _platformExtensionFileName(name); |
706 | 752 |
707 return [path, filename, name]; | 753 return [path, filename, name]; |
708 } | 754 } |
| 755 |
| 756 |
| 757 // Register callbacks and hooks with the rest of the core libraries. |
| 758 _setupHooks() { |
| 759 _setupCompleted = true; |
| 760 VMLibraryHooks.resourceReadAsBytes = _resourceReadAsBytes; |
| 761 } |
OLD | NEW |