Chromium Code Reviews| 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:collection'; | |
| 7 import 'dart:isolate'; | 8 import 'dart:isolate'; |
| 8 import 'dart:typed_data'; | 9 import 'dart:typed_data'; |
| 9 | 10 |
| 10 // The root library (aka the script) is imported into this library. The | 11 // The root library (aka the script) is imported into this library. The |
| 11 // standalone embedder uses this to lookup the main entrypoint in the | 12 // standalone embedder uses this to lookup the main entrypoint in the |
| 12 // root library's namespace. | 13 // root library's namespace. |
| 13 Function _getMainClosure() => main; | 14 Function _getMainClosure() => main; |
| 14 | 15 |
| 15 | 16 |
| 16 // 'print' implementation. | 17 // 'print' implementation. |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 52 const Dart_kImportTag = 0; | 53 const Dart_kImportTag = 0; |
| 53 const Dart_kSourceTag = 1; | 54 const Dart_kSourceTag = 1; |
| 54 const Dart_kCanonicalizeUrl = 2; | 55 const Dart_kCanonicalizeUrl = 2; |
| 55 | 56 |
| 56 // Embedder sets this to true if the --trace-loading flag was passed on the | 57 // Embedder sets this to true if the --trace-loading flag was passed on the |
| 57 // command line. | 58 // command line. |
| 58 bool _traceLoading = false; | 59 bool _traceLoading = false; |
| 59 | 60 |
| 60 // A port for communicating with the service isolate for I/O. | 61 // A port for communicating with the service isolate for I/O. |
| 61 SendPort _loadPort; | 62 SendPort _loadPort; |
| 62 // Maintain a number of outstanding load requests. Current loading request is | 63 // The receive port for a load request. Multiple sources can be fetched in |
| 63 // finished once there are no outstanding requests. | 64 // a single load request. |
| 64 int _numOutstandingLoadRequests = 0; | 65 RawReceivePort _receivePort; |
| 66 SendPort _sendPort; | |
| 67 // A request id valid only for the current load cycle (while the number of | |
| 68 // outstanding load requests is greater than 0). Can be reset when loading is | |
| 69 // completed. | |
| 70 int _reqId = 0; | |
| 71 // An unordered hash map mapping from request id to a particular load request. | |
| 72 // Once there are not outstanding load requests the current load has finished. | |
|
siva
2015/05/27 23:08:28
no outstanding load
Ivan Posva
2015/05/27 23:41:31
Done.
| |
| 73 HashMap _reqMap = new HashMap(); | |
| 65 | 74 |
| 66 // The current working directory when the embedder was launched. | 75 // The current working directory when the embedder was launched. |
| 67 Uri _workingDirectory; | 76 Uri _workingDirectory; |
| 68 // The URI that the root script was loaded from. Remembered so that | 77 // The URI that the root script was loaded from. Remembered so that |
| 69 // package imports can be resolved relative to it. The root script is the basis | 78 // package imports can be resolved relative to it. The root script is the basis |
| 70 // for the root library in the VM. | 79 // for the root library in the VM. |
| 71 Uri _rootScript; | 80 Uri _rootScript; |
| 72 // The directory to look in to resolve "package:" scheme URIs. By detault it is | 81 // The directory to look in to resolve "package:" scheme URIs. By detault it is |
| 73 // the 'packages' directory right next to the script. | 82 // the 'packages' directory right next to the script. |
| 74 Uri _packageRoot = _rootScript.resolve('packages/'); | 83 Uri _packageRoot = _rootScript.resolve('packages/'); |
| 75 | 84 |
| 76 // Special handling for Windows paths so that they are compatible with URI | 85 // Special handling for Windows paths so that they are compatible with URI |
| 77 // handling. | 86 // handling. |
| 78 // Embedder sets this to true if we are running on Windows. | 87 // Embedder sets this to true if we are running on Windows. |
| 79 bool _isWindows = false; | 88 bool _isWindows = false; |
| 80 | 89 |
| 81 | 90 |
| 82 // A class wrapping the load error message in an Error object. | 91 // A class wrapping the load error message in an Error object. |
| 83 class LoadError extends Error { | 92 class _LoadError extends Error { |
| 84 final String message; | 93 final String message; |
| 85 LoadError(this.message); | 94 _LoadError(this.message); |
| 86 | 95 |
| 87 String toString() => 'Load Error: $message'; | 96 String toString() => 'Load Error: $message'; |
| 88 } | 97 } |
| 89 | 98 |
| 99 // Class collecting all of the information about a particular load request. | |
| 100 class _LoadRequest { | |
| 101 final int _id; | |
| 102 final int _tag; | |
| 103 final String _uri; | |
| 104 final String _libraryUri; | |
| 105 | |
| 106 _LoadRequest(this._id, this._tag, this._uri, this._libraryUri); | |
| 107 } | |
| 108 | |
| 90 | 109 |
| 91 // Native calls provided by the embedder. | 110 // Native calls provided by the embedder. |
| 92 void _signalDoneLoading() native "Builtin_DoneLoading"; | 111 void _signalDoneLoading() native "Builtin_DoneLoading"; |
| 93 void _loadScriptCallback(int tag, String uri, String libraryUri, Uint8List data) | 112 void _loadScriptCallback(int tag, String uri, String libraryUri, Uint8List data) |
| 94 native "Builtin_LoadSource"; | 113 native "Builtin_LoadSource"; |
| 95 void _asyncLoadErrorCallback(uri, libraryUri, error) | 114 void _asyncLoadErrorCallback(uri, libraryUri, error) |
| 96 native "Builtin_AsyncLoadError"; | 115 native "Builtin_AsyncLoadError"; |
| 97 | 116 |
| 98 | 117 |
| 99 _sanitizeWindowsPath(path) { | 118 _sanitizeWindowsPath(path) { |
| (...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 222 // this location. | 241 // this location. |
| 223 _rootScript = scriptUri; | 242 _rootScript = scriptUri; |
| 224 | 243 |
| 225 if (_traceLoading) { | 244 if (_traceLoading) { |
| 226 _print('# Resolved entry point to: $_rootScript'); | 245 _print('# Resolved entry point to: $_rootScript'); |
| 227 } | 246 } |
| 228 return scriptUri; | 247 return scriptUri; |
| 229 } | 248 } |
| 230 | 249 |
| 231 | 250 |
| 232 void _finishLoadRequest(String uri) { | 251 void _finishLoadRequest(_LoadRequest req) { |
| 233 assert(_numOutstandingLoadRequests > 0); | 252 // Now that we are done with loading remove the request from the map. |
| 234 _numOutstandingLoadRequests--; | 253 var tmp = _reqMap.remove(req._id); |
| 254 assert(tmp == req); | |
| 235 if (_traceLoading) { | 255 if (_traceLoading) { |
| 236 _print("Loading of $uri finished, " | 256 _print("Loading of ${req._uri} finished, " |
| 237 "${_numOutstandingLoadRequests} requests remaining"); | 257 "${_reqMap.length} requests remaining"); |
| 238 } | 258 } |
| 239 if (_numOutstandingLoadRequests == 0) { | 259 |
| 260 if (_reqMap.isEmpty) { | |
| 261 if (_traceLoading) { | |
| 262 _print("Closing loading port."); | |
| 263 } | |
| 264 _receivePort.close(); | |
| 265 _receivePort = null; | |
| 266 _sendPort = null; | |
| 267 _reqId = 0; | |
| 240 _signalDoneLoading(); | 268 _signalDoneLoading(); |
| 241 } | 269 } |
| 242 } | 270 } |
| 243 | 271 |
| 244 | 272 |
| 245 void _startLoadRequest(String uri, Uri resourceUri) { | 273 void _handleLoaderReply(msg) { |
| 246 assert(_numOutstandingLoadRequests >= 0); | 274 int id = msg[0]; |
|
siva
2015/05/27 23:08:28
assert((id > 0) && (id < _reqMap.length));
Ivan Posva
2015/05/27 23:41:31
assert((id >= 0) && (id < _reqId));
| |
| 247 _numOutstandingLoadRequests++; | 275 var dataOrError = msg[1]; |
| 248 if (_traceLoading) { | 276 var req = _reqMap[id]; |
| 249 _print("Loading of $resourceUri for $uri started, " | 277 try { |
| 250 "${_numOutstandingLoadRequests} requests outstanding"); | 278 if (dataOrError is Uint8List) { |
| 279 _loadScript(req, dataOrError); | |
| 280 } else { | |
| 281 assert(dataOrError is String); | |
| 282 var error = new _LoadError(dataOrError.toString()); | |
| 283 _asyncLoadError(req, error); | |
| 284 } | |
| 285 } catch(e, s) { | |
| 286 // Wrap inside a _LoadError unless we are already propagating a | |
| 287 // previous _LoadError. | |
| 288 var error = (e is _LoadError) ? e : new _LoadError(e.toString()); | |
| 289 assert(req != null); | |
| 290 _asyncLoadError(req, error); | |
| 251 } | 291 } |
| 252 } | 292 } |
| 253 | 293 |
| 254 | 294 |
| 255 void _loadScript(int tag, String uri, String libraryUri, Uint8List data) { | 295 void _startLoadRequest(int tag, |
| 256 // TODO: Currently a compilation error while loading the script is | 296 String uri, |
| 257 // fatal for the isolate. _loadScriptCallback() does not return and | 297 String libraryUri, |
| 258 // the _numOutstandingLoadRequests counter remains out of sync. | 298 Uri resourceUri) { |
| 259 _loadScriptCallback(tag, uri, libraryUri, data); | 299 if (_reqMap.isEmpty) { |
| 260 _finishLoadRequest(uri); | 300 if (_traceLoading) { |
| 301 _print("Initializing load port."); | |
| 302 } | |
| 303 assert(_receivePort == null); | |
| 304 assert(_sendPort == null); | |
| 305 _receivePort = new RawReceivePort(_handleLoaderReply); | |
| 306 _sendPort = _receivePort.sendPort; | |
| 307 } | |
| 308 // Send the load request to the VM service isolate. | |
| 309 var curId = _reqId++; | |
| 310 var msg = new List(3); | |
| 311 msg[0] = _sendPort; | |
| 312 msg[1] = curId; | |
| 313 msg[2] = resourceUri.toString(); | |
| 314 _loadPort.send(msg); | |
| 315 | |
| 316 assert(_reqMap[curId] == null); | |
| 317 _reqMap[curId] = new _LoadRequest(curId, tag, uri, libraryUri); | |
|
siva
2015/05/27 23:08:28
I understand we are single threaded and adding the
Ivan Posva
2015/05/27 23:41:31
Done.
| |
| 318 | |
| 319 if (_traceLoading) { | |
| 320 _print("Loading of $resourceUri for $uri started with id: $curId, " | |
| 321 "${_reqMap.length} requests outstanding"); | |
| 322 } | |
| 261 } | 323 } |
| 262 | 324 |
| 263 | 325 |
| 264 void _asyncLoadError(int tag, String uri, String libraryUri, LoadError error) { | 326 void _loadScript(_LoadRequest req, Uint8List data) { |
| 265 if (_traceLoading) { | 327 // TODO: Currently a compilation error while loading the script is |
| 266 _print("_asyncLoadError($uri), error: $error"); | 328 // fatal for the isolate. _loadScriptCallback() does not return and |
| 267 } | 329 // the number of requests remains out of sync. |
| 268 if (tag == Dart_kImportTag) { | 330 _loadScriptCallback(req._tag, req._uri, req._libraryUri, data); |
| 269 // When importing a library, the libraryUri is the imported | 331 _finishLoadRequest(req); |
| 270 // uri. | |
| 271 libraryUri = uri; | |
| 272 } | |
| 273 _asyncLoadErrorCallback(uri, libraryUri, error); | |
| 274 _finishLoadRequest(uri); | |
| 275 } | 332 } |
| 276 | 333 |
| 277 | 334 |
| 335 void _asyncLoadError(_LoadRequest req, _LoadError error) { | |
| 336 if (_traceLoading) { | |
| 337 _print("_asyncLoadError(${req._uri}), error: $error"); | |
| 338 } | |
| 339 if (req._tag == Dart_kImportTag) { | |
| 340 // When importing a library, the libraryUri is the imported | |
| 341 // uri. | |
| 342 req._libraryUri = req._uri; | |
| 343 } | |
| 344 _asyncLoadErrorCallback(req._uri, req._libraryUri, error); | |
| 345 _finishLoadRequest(req); | |
| 346 } | |
| 347 | |
| 348 | |
| 278 _loadDataFromLoadPort(int tag, | 349 _loadDataFromLoadPort(int tag, |
| 279 String uri, | 350 String uri, |
| 280 String libraryUri, | 351 String libraryUri, |
| 281 Uri resourceUri) { | 352 Uri resourceUri) { |
| 282 var receivePort = new ReceivePort(); | |
| 283 receivePort.first.then((dataOrError) { | |
| 284 receivePort.close(); | |
| 285 if (dataOrError is Uint8List) { | |
| 286 _loadScript(tag, uri, libraryUri, dataOrError); | |
| 287 } else { | |
| 288 assert(dataOrError is String); | |
| 289 var error = new LoadError(dataOrError.toString()); | |
| 290 _asyncLoadError(tag, uri, libraryUri, error); | |
| 291 } | |
| 292 }).catchError((e) { | |
| 293 receivePort.close(); | |
| 294 // Wrap inside a LoadError unless we are already propagating a previously | |
| 295 // seen LoadError. | |
| 296 var error = (e is LoadError) ? e : new LoadError(e.toString); | |
| 297 _asyncLoadError(tag, uri, libraryUri, error); | |
| 298 }); | |
| 299 | |
| 300 try { | 353 try { |
| 301 var msg = [receivePort.sendPort, resourceUri.toString()]; | 354 _startLoadRequest(tag, uri, libraryUri, resourceUri); |
| 302 _loadPort.send(msg); | |
| 303 _startLoadRequest(uri, resourceUri); | |
| 304 } catch (e) { | 355 } catch (e) { |
| 305 if (_traceLoading) { | 356 if (_traceLoading) { |
| 306 _print("Exception when communicating with service isolate: $e"); | 357 _print("Exception when communicating with service isolate: $e"); |
| 307 } | 358 } |
| 308 // Wrap inside a LoadError unless we are already propagating a previously | 359 // Wrap inside a _LoadError unless we are already propagating a previously |
| 309 // seen LoadError. | 360 // seen _LoadError. |
| 310 var error = (e is LoadError) ? e : new LoadError(e.toString); | 361 var error = (e is _LoadError) ? e : new _LoadError(e.toString()); |
| 311 _asyncLoadError(tag, uri, libraryUri, error); | 362 _asyncLoadError(tag, uri, libraryUri, error); |
| 312 receivePort.close(); | |
| 313 } | 363 } |
| 314 } | 364 } |
| 315 | 365 |
| 316 | 366 |
| 317 // Embedder Entrypoint: | 367 // Embedder Entrypoint: |
| 318 // Asynchronously loads script data through a http[s] or file uri. | 368 // Asynchronously loads script data through a http[s] or file uri. |
| 319 _loadDataAsync(int tag, String uri, String libraryUri) { | 369 _loadDataAsync(int tag, String uri, String libraryUri) { |
| 320 var resourceUri; | 370 var resourceUri; |
| 321 if (tag == Dart_kScriptTag) { | 371 if (tag == Dart_kScriptTag) { |
| 322 resourceUri = _resolveScriptUri(uri); | 372 resourceUri = _resolveScriptUri(uri); |
| (...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 453 } else { | 503 } else { |
| 454 name = userUri.substring(index + 1); | 504 name = userUri.substring(index + 1); |
| 455 path = userUri.substring(0, index + 1); | 505 path = userUri.substring(0, index + 1); |
| 456 } | 506 } |
| 457 | 507 |
| 458 path = _filePathFromUri(path); | 508 path = _filePathFromUri(path); |
| 459 var filename = _platformExtensionFileName(name); | 509 var filename = _platformExtensionFileName(name); |
| 460 | 510 |
| 461 return [path, filename, name]; | 511 return [path, filename, name]; |
| 462 } | 512 } |
| OLD | NEW |