Index: runtime/bin/builtin.dart |
diff --git a/runtime/bin/builtin.dart b/runtime/bin/builtin.dart |
index 42a5e1e9c4122cbe110a0cd9a559f3852b247efc..44779f9ba0f870985a111ac7648f0c8f680f7707 100644 |
--- a/runtime/bin/builtin.dart |
+++ b/runtime/bin/builtin.dart |
@@ -4,10 +4,18 @@ |
library builtin; |
// NOTE: Do not import 'dart:io' in builtin. |
+import 'dart:async'; |
import 'dart:collection'; |
+import 'dart:_internal'; |
import 'dart:isolate'; |
import 'dart:typed_data'; |
+ |
+// Before handling an embedder entrypoint we finalize the setup of the |
+// dart:_builtin library. |
+bool _setupCompleted = false; |
+ |
+ |
// The root library (aka the script) is imported into this library. The |
// standalone embedder uses this to lookup the main entrypoint in the |
// root library's namespace. |
@@ -49,10 +57,11 @@ _getUriBaseClosure() => _uriBase; |
// The embedder forwards most loading requests to this library. |
// See Dart_LibraryTag in dart_api.h |
-const Dart_kScriptTag = null; |
-const Dart_kImportTag = 0; |
-const Dart_kSourceTag = 1; |
-const Dart_kCanonicalizeUrl = 2; |
+const _Dart_kScriptTag = null; |
+const _Dart_kImportTag = 0; |
+const _Dart_kSourceTag = 1; |
+const _Dart_kCanonicalizeUrl = 2; |
+const _Dart_kResourceLoad = 3; |
// Embedder sets this to true if the --trace-loading flag was passed on the |
// command line. |
@@ -119,16 +128,16 @@ class _LoadRequest { |
final int _id; |
final int _tag; |
final String _uri; |
- final String _libraryUri; |
final Uri _resourceUri; |
+ final _context; |
_LoadRequest(this._id, |
this._tag, |
this._uri, |
- this._libraryUri, |
- this._resourceUri); |
+ this._resourceUri, |
+ this._context); |
- toString() => "LoadRequest($_id, $_tag, $_uri, $_libraryUri, $_resourceUri)"; |
+ toString() => "LoadRequest($_id, $_tag, $_uri, $_resourceUri, $_context)"; |
} |
@@ -195,6 +204,9 @@ _enforceTrailingSlash(uri) { |
// Embedder Entrypoint: |
// The embedder calls this method with the current working directory. |
void _setWorkingDirectory(cwd) { |
+ if (!_setupCompleted) { |
+ _setupHooks(); |
+ } |
if (_traceLoading) { |
_log('Setting working directory: $cwd'); |
} |
@@ -208,6 +220,9 @@ void _setWorkingDirectory(cwd) { |
// Embedder Entrypoint: |
// The embedder calls this method with a custom package root. |
_setPackageRoot(String packageRoot) { |
+ if (!_setupCompleted) { |
+ _setupHooks(); |
+ } |
if (_traceLoading) { |
_log('Setting package root: $packageRoot'); |
} |
@@ -323,7 +338,17 @@ void _handleLoaderReply(msg) { |
var req = _reqMap[id]; |
try { |
if (dataOrError is Uint8List) { |
- _loadScript(req, dataOrError); |
+ // Successfully loaded the data. |
+ if (req._tag == _Dart_kResourceLoad) { |
+ Completer c = req._context; |
+ c.complete(dataOrError); |
+ } else { |
+ // TODO: Currently a compilation error while loading the script is |
+ // fatal for the isolate. _loadScriptCallback() does not return and |
+ // the number of requests remains out of sync. |
+ _loadScriptCallback(req._tag, req._uri, req._context, dataOrError); |
+ } |
+ _finishLoadRequest(req); |
} else { |
assert(dataOrError is String); |
var error = new _LoadError(req._uri, dataOrError.toString()); |
@@ -339,10 +364,7 @@ void _handleLoaderReply(msg) { |
} |
-void _startLoadRequest(int tag, |
- String uri, |
- String libraryUri, |
- Uri resourceUri) { |
+void _startLoadRequest(int tag, String uri, Uri resourceUri, context) { |
if (_receivePort == null) { |
if (_traceLoading) { |
_log("Initializing load port."); |
@@ -356,7 +378,7 @@ void _startLoadRequest(int tag, |
var curId = _reqId++; |
assert(_reqMap[curId] == null); |
- _reqMap[curId] = new _LoadRequest(curId, tag, uri, libraryUri, resourceUri); |
+ _reqMap[curId] = new _LoadRequest(curId, tag, uri, resourceUri, context); |
assert(_receivePort != null); |
assert(_sendPort != null); |
@@ -369,8 +391,9 @@ void _startLoadRequest(int tag, |
_loadPort.send(msg); |
if (_traceLoading) { |
- _log("Loading of $resourceUri for $uri started with id: $curId, " |
- "${_reqMap.length} requests outstanding"); |
+ _log("Loading of $resourceUri for $uri started with id: $curId. " |
+ "${_reqMap.length} requests remaining, " |
+ "${_pendingPackageLoads.length} packages pending."); |
} |
} |
@@ -408,13 +431,17 @@ void _handlePackagesReply(msg) { |
} |
// Resolve all pending package loads now that we know how to resolve them. |
- for (var i = 0; i < _pendingPackageLoads.length; i++) { |
- var req = _pendingPackageLoads[i]; |
+ while (_pendingPackageLoads.length > 0) { |
+ var req = _pendingPackageLoads.removeLast(); |
if (req != null) { |
if (_traceLoading) { |
_log("Handling deferred load request: $req"); |
} |
- _loadPackage(req._tag, req._uri, req._libraryUri, req._resourceUri); |
+ _loadPackage(req._tag, req._uri, req._resourceUri, req._context); |
+ } else { |
+ if (_traceLoading) { |
+ _log("Skipping dummy deferred request."); |
+ } |
} |
} |
// Reset the pending package loads to empty. So that we eventually can |
@@ -446,6 +473,9 @@ void _requestPackagesMap() { |
// Embedder Entrypoint: |
// Request the load of a particular packages map. |
void _loadPackagesMap(String packagesParam) { |
+ if (!_setupCompleted) { |
+ _setupHooks(); |
+ } |
// First convert the packages parameter from the command line to a URI which |
// can be handled by the loader code. |
// TODO(iposva): Consider refactoring the common code below which is almost |
@@ -490,21 +520,12 @@ void _loadPackagesMap(String packagesParam) { |
} |
-void _loadScript(_LoadRequest req, Uint8List data) { |
- // TODO: Currently a compilation error while loading the script is |
- // fatal for the isolate. _loadScriptCallback() does not return and |
- // the number of requests remains out of sync. |
- _loadScriptCallback(req._tag, req._uri, req._libraryUri, data); |
- _finishLoadRequest(req); |
-} |
- |
- |
void _asyncLoadError(_LoadRequest req, _LoadError error) { |
if (_traceLoading) { |
_log("_asyncLoadError(${req._uri}), error: $error"); |
} |
- var libraryUri = req._libraryUri; |
- if (req._tag == Dart_kImportTag) { |
+ var libraryUri = req._context; |
+ if (req._tag == _Dart_kImportTag) { |
// When importing a library, the libraryUri is the imported |
// uri. |
libraryUri = req._uri; |
@@ -514,36 +535,39 @@ void _asyncLoadError(_LoadRequest req, _LoadError error) { |
} |
-_loadDataFromLoadPort(int tag, |
- String uri, |
- String libraryUri, |
- Uri resourceUri) { |
+_loadDataFromLoadPort(int tag, String uri, Uri resourceUri, context) { |
try { |
- _startLoadRequest(tag, uri, libraryUri, resourceUri); |
- } catch (e) { |
+ _startLoadRequest(tag, uri, resourceUri, context); |
+ } catch (e, s) { |
+ // For resource loads we need to complete with an error. |
+ if (tag == _Dart_kResourceLoad) { |
+ assert(context is Completer); |
+ context.completeError(e, s); |
+ } |
+ |
if (_traceLoading) { |
_log("Exception when communicating with service isolate: $e"); |
} |
// Wrap inside a _LoadError unless we are already propagating a previously |
// seen _LoadError. |
var error = (e is _LoadError) ? e : new _LoadError(e.toString()); |
- _asyncLoadError(tag, uri, libraryUri, error); |
+ _asyncLoadError(tag, uri, context, error); |
} |
} |
// Loading a package URI needs to first map the package name to a loadable |
// URI. |
-_loadPackage(int tag, String uri, String libraryUri, Uri resourceUri) { |
+_loadPackage(int tag, String uri, Uri resourceUri, context) { |
if (_packagesReady()) { |
- _loadData(tag, uri, libraryUri, _resolvePackageUri(resourceUri)); |
+ _loadData(tag, uri, _resolvePackageUri(resourceUri), context); |
} else { |
if (_pendingPackageLoads.isEmpty) { |
// Package resolution has not been setup yet, and this is the first |
// request for package resolution & loading. |
_requestPackagesMap(); |
} |
- var req = new _LoadRequest(-1, tag, uri, libraryUri, resourceUri); |
+ var req = new _LoadRequest(-1, tag, uri, resourceUri, context); |
_pendingPackageLoads.add(req); |
if (_traceLoading) { |
_log("Pending package load of '$uri': " |
@@ -554,14 +578,14 @@ _loadPackage(int tag, String uri, String libraryUri, Uri resourceUri) { |
// Load the data associated with the resourceUri. |
-_loadData(int tag, String uri, String libraryUri, Uri resourceUri) { |
+_loadData(int tag, String uri, Uri resourceUri, context) { |
if (resourceUri.scheme == 'package') { |
// package based uris need to be resolved to the correct loadable location. |
// The logic of which is handled seperately, and then _loadData is called |
// recursively. |
- _loadPackage(tag, uri, libraryUri, resourceUri); |
+ _loadPackage(tag, uri, resourceUri, context); |
} else { |
- _loadDataFromLoadPort(tag, uri, libraryUri, resourceUri); |
+ _loadDataFromLoadPort(tag, uri, resourceUri, context); |
} |
} |
@@ -569,14 +593,17 @@ _loadData(int tag, String uri, String libraryUri, Uri resourceUri) { |
// Embedder Entrypoint: |
// Asynchronously loads script data through a http[s] or file uri. |
_loadDataAsync(int tag, String uri, String libraryUri) { |
+ if (!_setupCompleted) { |
+ _setupHooks(); |
+ } |
var resourceUri; |
- if (tag == Dart_kScriptTag) { |
+ if (tag == _Dart_kScriptTag) { |
resourceUri = _resolveScriptUri(uri); |
uri = resourceUri.toString(); |
} else { |
resourceUri = Uri.parse(uri); |
} |
- _loadData(tag, uri, libraryUri, resourceUri); |
+ _loadData(tag, uri, resourceUri, libraryUri); |
} |
@@ -584,6 +611,9 @@ _loadDataAsync(int tag, String uri, String libraryUri) { |
// Function called by standalone embedder to resolve uris when the VM requests |
// Dart_kCanonicalizeUrl from the tag handler. |
String _resolveUri(String base, String userString) { |
+ if (!_setupCompleted) { |
+ _setupHooks(); |
+ } |
if (_traceLoading) { |
_log('Resolving: $userString from $base'); |
} |
@@ -602,9 +632,23 @@ String _resolveUri(String base, String userString) { |
} |
+// Handling of Resource class by dispatching to the load port. |
+Future<List<int>> _resourceReadAsBytes(Uri uri) { |
+ var completer = new Completer<List<int>>(); |
+ // Request the load of the resource associating the completer as the context |
+ // for the load. |
+ _loadData(_Dart_kResourceLoad, uri.toString(), uri, completer); |
+ // Return the future that will be triggered once the resource has been loaded. |
+ return completer.future; |
+} |
+ |
+ |
// Embedder Entrypoint (gen_snapshot): |
// Resolve relative paths relative to working directory. |
String _resolveInWorkingDirectory(String fileName) { |
+ if (!_setupCompleted) { |
+ _setupHooks(); |
+ } |
if (_workingDirectory == null) { |
throw 'No current working directory set.'; |
} |
@@ -679,6 +723,9 @@ String _filePathFromUri(String userUri) { |
// The filename part is the extension name, with the platform-dependent |
// prefixes and extensions added. |
_extensionPathFromUri(String userUri) { |
+ if (!_setupCompleted) { |
+ _setupHooks(); |
+ } |
if (!userUri.startsWith(_DART_EXT)) { |
throw 'Unexpected internal error: Extension URI $userUri missing dart-ext:'; |
} |
@@ -706,3 +753,10 @@ _extensionPathFromUri(String userUri) { |
return [path, filename, name]; |
} |
+ |
+ |
+// |
siva
2015/08/04 21:48:23
Dangling comment start ?
|
+_setupHooks() { |
+ _setupCompleted = true; |
+ VMLibraryHooks.resourceReadAsBytes = _resourceReadAsBytes; |
+} |