Skip to content

Commit 6d066c7

Browse files
committed
Add package config support to dart:isolate
- Add "static Future<Uri> get packageRoot;", "static Future<Uri> get packageConfig;" and "static Future<Uri> resolvePackageUri(Uri packageUri)" to Isolate class. - Added "Uri packageRoot, Uri packageConfig, bool automaticPackageResolution: false" parameters to spawnUri. BUG= [email protected] Review URL: https://codereview.chromium.org/1553233002 .
1 parent d4ce7f1 commit 6d066c7

29 files changed

+648
-222
lines changed

runtime/bin/builtin.dart

Lines changed: 106 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -89,12 +89,19 @@ Uri _rootScript;
8989

9090
// Packages are either resolved looking up in a map or resolved from within a
9191
// package root.
92-
bool _packagesReady() => (_packageRoot != null) || (_packageMap != null);
92+
bool get _packagesReady =>
93+
(_packageRoot != null) || (_packageMap != null) || (_packageError != null);
94+
// Error string set if there was an error resolving package configuration.
95+
// For example not finding a .packages file or packages/ directory, malformed
96+
// .packages file or any other related error.
97+
String _packageError = null;
9398
// The directory to look in to resolve "package:" scheme URIs. By detault it is
9499
// the 'packages' directory right next to the script.
95100
Uri _packageRoot = null; // Used to be _rootScript.resolve('packages/');
96101
// The map describing how certain package names are mapped to Uris.
102+
Uri _packageConfig = null;
97103
Map<String, Uri> _packageMap = null;
104+
98105
// A list of pending packags which have been requested while resolving the
99106
// location of the package root or the contents of the package map.
100107
List<_LoadRequest> _pendingPackageLoads = [];
@@ -109,8 +116,9 @@ bool _pendingLoads() => !_reqMap.isEmpty || !_pendingPackageLoads.isEmpty;
109116
bool _isWindows = false;
110117

111118
// Logging from builtin.dart is prefixed with a '*'.
119+
String _logId = (Isolate.current.hashCode % 0x100000).toRadixString(16);
112120
_log(msg) {
113-
_print("* $msg");
121+
_print("* $_logId $msg");
114122
}
115123

116124
// A class wrapping the load error message in an Error object.
@@ -235,8 +243,10 @@ _setPackageRoot(String packageRoot) {
235243
_packageRoot = _workingDirectory.resolveUri(new Uri.file(packageRoot));
236244
}
237245
// Now that we have determined the packageRoot value being used, set it
238-
// up for use in Platform.packageRoot.
239-
VMLibraryHooks.packageRoot = _packageRoot.toString();
246+
// up for use in Platform.packageRoot. This is only set when the embedder
247+
// sets up the package root. Automatically discovered package root will
248+
// not update the VMLibraryHooks value.
249+
VMLibraryHooks.packageRootString = _packageRoot.toString();
240250
if (_traceLoading) {
241251
_log('Package root URI: $_packageRoot');
242252
}
@@ -246,6 +256,9 @@ _setPackageRoot(String packageRoot) {
246256
// Given a uri with a 'package' scheme, return a Uri that is prefixed with
247257
// the package root.
248258
Uri _resolvePackageUri(Uri uri) {
259+
assert(uri.scheme == "package");
260+
assert(_packagesReady);
261+
249262
if (!uri.host.isEmpty) {
250263
var path = '${uri.host}${uri.path}';
251264
var right = 'package:$path';
@@ -259,7 +272,12 @@ Uri _resolvePackageUri(Uri uri) {
259272
_log('Resolving package with uri path: ${uri.path}');
260273
}
261274
var resolvedUri;
262-
if (_packageRoot != null) {
275+
if (_packageError != null) {
276+
if (_traceLoading) {
277+
_log("Resolving package with pending resolution error: $_packageError");
278+
}
279+
throw _packageError;
280+
} else if (_packageRoot != null) {
263281
resolvedUri = _packageRoot.resolve(uri.path);
264282
} else {
265283
var packageName = uri.pathSegments[0];
@@ -408,22 +426,33 @@ void _handlePackagesReply(msg) {
408426
if (_traceLoading) {
409427
_log("Got failure response on package port: '$msg'");
410428
}
411-
throw msg;
412-
}
413-
if (msg.length == 1) {
414-
if (_traceLoading) {
415-
_log("Received package root: '${msg[0]}'");
429+
// Remember the error message.
430+
_packageError = msg;
431+
} else if (msg is List) {
432+
if (msg.length == 1) {
433+
if (_traceLoading) {
434+
_log("Received package root: '${msg[0]}'");
435+
}
436+
_packageRoot = Uri.parse(msg[0]);
437+
} else {
438+
// First entry contains the location of the loaded .packages file.
439+
assert((msg.length % 2) == 0);
440+
assert(msg.length >= 2);
441+
assert(msg[1] == null);
442+
_packageConfig = Uri.parse(msg[0]);
443+
_packageMap = new Map<String, Uri>();
444+
for (var i = 2; i < msg.length; i+=2) {
445+
// TODO(iposva): Complain about duplicate entries.
446+
_packageMap[msg[i]] = Uri.parse(msg[i+1]);
447+
}
448+
if (_traceLoading) {
449+
_log("Setup package map: $_packageMap");
450+
}
416451
}
417-
_packageRoot = Uri.parse(msg[0]);
418452
} else {
419-
assert((msg.length % 2) == 0);
420-
_packageMap = new Map<String, Uri>();
421-
for (var i = 0; i < msg.length; i+=2) {
422-
// TODO(iposva): Complain about duplicate entries.
423-
_packageMap[msg[i]] = Uri.parse(msg[i+1]);
424-
}
453+
_packageError = "Bad type of packages reply: ${msg.runtimeType}";
425454
if (_traceLoading) {
426-
_log("Setup package map: $_packageMap");
455+
_log(_packageError);
427456
}
428457
}
429458

@@ -485,7 +514,8 @@ void _loadPackagesMap(String packagesParam) {
485514
// resolve it against the working directory.
486515
packagesUri = _workingDirectory.resolveUri(packagesUri);
487516
}
488-
VMLibraryHooks.packageConfig = packagesUri.toString();
517+
var packagesUriStr = packagesUri.toString();
518+
VMLibraryHooks.packageConfigString = packagesUriStr;
489519
if (_traceLoading) {
490520
_log('Resolved packages map to: $packagesUri');
491521
}
@@ -500,7 +530,7 @@ void _loadPackagesMap(String packagesParam) {
500530
msg[0] = sp;
501531
msg[1] = _traceLoading;
502532
msg[2] = -2;
503-
msg[3] = packagesUri.toString();
533+
msg[3] = packagesUriStr;
504534
_loadPort.send(msg);
505535

506536
// Signal that the resolution of the packages map has started. But in this
@@ -519,34 +549,6 @@ void _loadPackagesMap(String packagesParam) {
519549
}
520550

521551

522-
// Embedder Entrypoint:
523-
// Add mapping from package name to URI.
524-
void _addPackageMapEntry(String key, String value) {
525-
if (!_setupCompleted) {
526-
_setupHooks();
527-
}
528-
if (_traceLoading) {
529-
_log("Adding packages map entry: $key -> $value");
530-
}
531-
if (_packageRoot != null) {
532-
if (_traceLoading) {
533-
_log("_packageRoot already set: $_packageRoot");
534-
}
535-
throw "Cannot add package map entry to an exisiting package root.";
536-
}
537-
if (_packagesPort != null) {
538-
if (_traceLoading) {
539-
_log("Package map load request already pending.");
540-
}
541-
throw "Cannot add package map entry during package map resolution.";
542-
}
543-
if (_packageMap == null) {
544-
_packageMap = new Map<String, Uri>();
545-
}
546-
_packageMap[key] = _workingDirectory.resolve(value);
547-
}
548-
549-
550552
void _asyncLoadError(_LoadRequest req, _LoadError error, StackTrace stack) {
551553
if (_traceLoading) {
552554
_log("_asyncLoadError(${req._uri}), error: $error\nstack: $stack");
@@ -587,8 +589,22 @@ _loadDataFromLoadPort(int tag, String uri, Uri resourceUri, context) {
587589
// Loading a package URI needs to first map the package name to a loadable
588590
// URI.
589591
_loadPackage(int tag, String uri, Uri resourceUri, context) {
590-
if (_packagesReady()) {
591-
_loadData(tag, uri, _resolvePackageUri(resourceUri), context);
592+
if (_packagesReady) {
593+
var resolvedUri;
594+
try {
595+
resolvedUri = _resolvePackageUri(resourceUri);
596+
} catch (e, s) {
597+
if (_traceLoading) {
598+
_log("Exception ($e) when resolving package URI: $resourceUri");
599+
}
600+
// Wrap inside a _LoadError unless we are already propagating a previously
601+
// seen _LoadError.
602+
var error = (e is _LoadError) ? e : new _LoadError(uri, e.toString());
603+
// Register a dummy load request and fail to load it.
604+
var req = new _LoadRequest(tag, uri, resourceUri, context);
605+
_asyncLoadError(req, error, s);
606+
}
607+
_loadData(tag, uri, resolvedUri, context);
592608
} else {
593609
if (_pendingPackageLoads.isEmpty) {
594610
// Package resolution has not been setup yet, and this is the first
@@ -606,7 +622,7 @@ _loadPackage(int tag, String uri, Uri resourceUri, context) {
606622
});
607623
if (_traceLoading) {
608624
_log("Pending package load of '$uri': "
609-
"${_pendingPackageLoads.length} pending");
625+
"${_pendingPackageLoads.length} pending");
610626
}
611627
}
612628
}
@@ -669,7 +685,7 @@ String _resolveUri(String base, String userString) {
669685

670686
// Handling of access to the package root or package map from user code.
671687
_triggerPackageResolution(action) {
672-
if (_packagesReady()) {
688+
if (_packagesReady) {
673689
// Packages are ready. Execute the action now.
674690
action();
675691
} else {
@@ -684,7 +700,7 @@ _triggerPackageResolution(action) {
684700
}
685701

686702

687-
Future<Uri> _getPackageRoot() {
703+
Future<Uri> _getPackageRootFuture() {
688704
if (_traceLoading) {
689705
_log("Request for package root from user code.");
690706
}
@@ -696,19 +712,47 @@ Future<Uri> _getPackageRoot() {
696712
}
697713

698714

699-
Future<Map<String, Uri>> _getPackageMap() {
715+
Future<Uri> _getPackageConfigFuture() {
700716
if (_traceLoading) {
701-
_log("Request for package map from user code.");
717+
_log("Request for package config from user code.");
702718
}
703-
var completer = new Completer<Map<String, Uri>>();
719+
var completer = new Completer<Uri>();
704720
_triggerPackageResolution(() {
705-
var result = (_packageMap != null) ? new Map.from(_packageMap) : {};
706-
completer.complete(result);
721+
completer.complete(_packageConfig);
707722
});
708723
return completer.future;
709724
}
710725

711726

727+
Future<Uri> _resolvePackageUriFuture(Uri packageUri) async {
728+
if (_traceLoading) {
729+
_log("Request for package Uri resolution from user code: $packageUri");
730+
}
731+
if (packageUri.scheme != "package") {
732+
if (_traceLoading) {
733+
_log("Non-package Uri, returning unmodified: $packageUri");
734+
}
735+
// Return the incoming parameter if not passed a package: URI.
736+
return packageUri;
737+
}
738+
739+
if (!_packagesReady) {
740+
if (_traceLoading) {
741+
_log("Trigger loading by requesting the package config.");
742+
}
743+
// Make sure to trigger package resolution.
744+
var dummy = await _getPackageConfigFuture();
745+
}
746+
assert(_packagesReady);
747+
748+
var result = _resolvePackageUri(packageUri);
749+
if (_traceLoading) {
750+
_log("Resolved '$packageUri' to '$result'");
751+
}
752+
return result;
753+
}
754+
755+
712756
// Handling of Resource class by dispatching to the load port.
713757
Future<List<int>> _resourceReadAsBytes(Uri uri) {
714758
var completer = new Completer<List<int>>();
@@ -836,6 +880,8 @@ _extensionPathFromUri(String userUri) {
836880
_setupHooks() {
837881
_setupCompleted = true;
838882
VMLibraryHooks.resourceReadAsBytes = _resourceReadAsBytes;
839-
VMLibraryHooks.getPackageRoot = _getPackageRoot;
840-
VMLibraryHooks.getPackageMap = _getPackageMap;
883+
884+
VMLibraryHooks.packageRootUriFuture = _getPackageRootFuture;
885+
VMLibraryHooks.packageConfigUriFuture = _getPackageConfigFuture;
886+
VMLibraryHooks.resolvePackageUriFuture = _resolvePackageUriFuture;
841887
}

runtime/bin/dartutils.cc

Lines changed: 6 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -658,8 +658,7 @@ Dart_Handle DartUtils::PrepareBuiltinLibrary(Dart_Handle builtin_lib,
658658
bool is_service_isolate,
659659
bool trace_loading,
660660
const char* package_root,
661-
const char** package_map,
662-
const char* packages_file) {
661+
const char* packages_config) {
663662
// Setup the internal library's 'internalPrint' function.
664663
Dart_Handle print = Dart_Invoke(
665664
builtin_lib, NewString("_getPrintClosure"), 0, NULL);
@@ -693,8 +692,7 @@ Dart_Handle DartUtils::PrepareBuiltinLibrary(Dart_Handle builtin_lib,
693692

694693
// Set up package root if specified.
695694
if (package_root != NULL) {
696-
ASSERT(package_map == NULL);
697-
ASSERT(packages_file == NULL);
695+
ASSERT(packages_config == NULL);
698696
result = NewString(package_root);
699697
RETURN_IF_ERROR(result);
700698
const int kNumArgs = 1;
@@ -705,35 +703,8 @@ Dart_Handle DartUtils::PrepareBuiltinLibrary(Dart_Handle builtin_lib,
705703
kNumArgs,
706704
dart_args);
707705
RETURN_IF_ERROR(result);
708-
} else if (package_map != NULL) {
709-
ASSERT(packages_file == NULL);
710-
Dart_Handle func_name = NewString("_addPackageMapEntry");
711-
RETURN_IF_ERROR(func_name);
712-
713-
for (int i = 0; package_map[i] != NULL; i +=2) {
714-
const int kNumArgs = 2;
715-
Dart_Handle dart_args[kNumArgs];
716-
// Get the key.
717-
result = NewString(package_map[i]);
718-
RETURN_IF_ERROR(result);
719-
dart_args[0] = result;
720-
if (package_map[i + 1] == NULL) {
721-
return Dart_NewUnhandledExceptionError(
722-
NewDartArgumentError("Adding package map entry without value."));
723-
}
724-
// Get the value.
725-
result = NewString(package_map[i + 1]);
726-
RETURN_IF_ERROR(result);
727-
dart_args[1] = result;
728-
// Setup the next package map entry.
729-
result = Dart_Invoke(builtin_lib,
730-
func_name,
731-
kNumArgs,
732-
dart_args);
733-
RETURN_IF_ERROR(result);
734-
}
735-
} else if (packages_file != NULL) {
736-
result = NewString(packages_file);
706+
} else if (packages_config != NULL) {
707+
result = NewString(packages_config);
737708
RETURN_IF_ERROR(result);
738709
const int kNumArgs = 1;
739710
Dart_Handle dart_args[kNumArgs];
@@ -789,8 +760,7 @@ Dart_Handle DartUtils::PrepareIsolateLibrary(Dart_Handle isolate_lib) {
789760

790761

791762
Dart_Handle DartUtils::PrepareForScriptLoading(const char* package_root,
792-
const char** package_map,
793-
const char* packages_file,
763+
const char* packages_config,
794764
bool is_service_isolate,
795765
bool trace_loading,
796766
Dart_Handle builtin_lib) {
@@ -824,8 +794,7 @@ Dart_Handle DartUtils::PrepareForScriptLoading(const char* package_root,
824794
is_service_isolate,
825795
trace_loading,
826796
package_root,
827-
package_map,
828-
packages_file);
797+
packages_config);
829798
RETURN_IF_ERROR(result);
830799

831800
RETURN_IF_ERROR(PrepareAsyncLibrary(async_lib, isolate_lib));

runtime/bin/dartutils.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,6 @@ class DartUtils {
130130
bool is_service_isolate,
131131
bool trace_loading,
132132
const char* package_root,
133-
const char** package_map,
134133
const char* packages_file);
135134
static Dart_Handle PrepareCoreLibrary(Dart_Handle core_lib,
136135
Dart_Handle builtin_lib,
@@ -140,7 +139,6 @@ class DartUtils {
140139
static Dart_Handle PrepareIOLibrary(Dart_Handle io_lib);
141140
static Dart_Handle PrepareIsolateLibrary(Dart_Handle isolate_lib);
142141
static Dart_Handle PrepareForScriptLoading(const char* package_root,
143-
const char** package_map,
144142
const char* packages_file,
145143
bool is_service_isolate,
146144
bool trace_loading,

runtime/bin/gen_snapshot.cc

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -955,7 +955,7 @@ static void SetupForGenericSnapshotCreation() {
955955
static Dart_Isolate CreateServiceIsolate(const char* script_uri,
956956
const char* main,
957957
const char* package_root,
958-
const char** package_map,
958+
const char* package_config,
959959
Dart_IsolateFlags* flags,
960960
void* data,
961961
char** error) {
@@ -1094,7 +1094,6 @@ int main(int argc, char** argv) {
10941094
// closures and setting up 'package root' for URI resolution.
10951095
result =
10961096
DartUtils::PrepareForScriptLoading(package_root,
1097-
NULL,
10981097
NULL,
10991098
false,
11001099
false,

0 commit comments

Comments
 (0)