Index: runtime/lib/isolate_patch.dart |
diff --git a/runtime/lib/isolate_patch.dart b/runtime/lib/isolate_patch.dart |
index bb3737159a0c5c13f52dda777906b26862bd822e..de652acac29bd1541f7e6cc96f3b52a9db2ada37 100644 |
--- a/runtime/lib/isolate_patch.dart |
+++ b/runtime/lib/isolate_patch.dart |
@@ -270,26 +270,63 @@ void _startIsolate(SendPort parentPort, |
patch class Isolate { |
static final _currentIsolate = _getCurrentIsolate(); |
+ static final _rootUri = _getCurrentRootUri(); |
/* patch */ static Isolate get current => _currentIsolate; |
+ /* patch */ static Future<Uri> get packageRoot { |
+ var hook = VMLibraryHooks.packageRootUriFuture; |
+ if (hook == null) { |
+ throw new UnsupportedError("Isolate.packageRoot"); |
+ } |
+ return hook(); |
+ } |
+ |
+ /* patch */ static Future<Uri> get packageConfig { |
+ var hook = VMLibraryHooks.packageConfigUriFuture; |
+ if (hook == null) { |
+ throw new UnsupportedError("Isolate.packageConfig"); |
+ } |
+ return hook(); |
+ } |
+ |
+ /* patch */ static Future<Uri> resolvePackageUri(Uri packageUri) { |
+ var hook = VMLibraryHooks.resolvePackageUriFuture; |
+ if (hook == null) { |
+ throw new UnsupportedError("Isolate.resolvePackageUri"); |
+ } |
+ return hook(packageUri); |
+ } |
+ |
+ static bool _packageSupported() => |
+ (VMLibraryHooks.packageRootUriFuture != null) && |
+ (VMLibraryHooks.packageConfigUriFuture != null); |
+ |
/* patch */ static Future<Isolate> spawn( |
void entryPoint(message), var message, |
{bool paused: false, bool errorsAreFatal, |
- SendPort onExit, SendPort onError}) { |
+ SendPort onExit, SendPort onError}) async { |
// `paused` isn't handled yet. |
RawReceivePort readyPort; |
try { |
// The VM will invoke [_startIsolate] with entryPoint as argument. |
readyPort = new RawReceivePort(); |
+ var packageRoot = null; |
+ var packageConfig = null; |
+ if (Isolate._packageSupported()) { |
+ packageRoot = (await Isolate.packageRoot)?.toString(); |
+ packageConfig = (await Isolate.packageConfig)?.toString(); |
+ } |
+ |
_spawnFunction(readyPort.sendPort, entryPoint, message, |
- paused, errorsAreFatal, onExit, onError); |
- return _spawnCommon(readyPort); |
+ paused, errorsAreFatal, onExit, onError, |
+ packageRoot, packageConfig); |
+ return await _spawnCommon(readyPort); |
} catch (e, st) { |
if (readyPort != null) { |
readyPort.close(); |
} |
- return new Future<Isolate>.error(e, st); |
+ return await new Future<Isolate>.error(e, st); |
} |
} |
@@ -301,28 +338,63 @@ patch class Isolate { |
bool errorsAreFatal, |
bool checked, |
Map<String, String> environment, |
- Uri packageRoot}) { |
+ Uri packageRoot, |
+ Uri packageConfig, |
+ bool automaticPackageResolution: false}) async { |
RawReceivePort readyPort; |
- if (environment != null) throw new UnimplementedError("environment"); |
+ if (environment != null) { |
+ throw new UnimplementedError("environment"); |
+ } |
+ |
+ // Verify that no mutually exclusive arguments have been passed. |
+ if (automaticPackageResolution) { |
+ if (packageRoot != null) { |
+ throw new ArgumentError("Cannot simultaneously request " |
+ "automaticPackageResolution and specify a" |
+ "packageRoot."); |
+ } |
+ if (packageConfig != null) { |
+ throw new ArgumentError("Cannot simultaneously request " |
+ "automaticPackageResolution and specify a" |
+ "packageConfig."); |
+ } |
+ } else { |
+ if ((packageRoot != null) && (packageConfig != null)) { |
+ throw new ArgumentError("Cannot simultaneously specify a " |
+ "packageRoot and a packageConfig."); |
+ } |
+ } |
try { |
+ // Resolve the uri agains the current isolate's root Uri first. |
+ var spawnedUri = _rootUri.resolveUri(uri); |
+ |
+ // Inherit this isolate's package resolution setup if not overridden. |
+ if (!automaticPackageResolution && |
+ (packageRoot == null) && |
+ (packageConfig == null)) { |
+ if (Isolate._packageSupported()) { |
+ packageRoot = await Isolate.packageRoot; |
+ packageConfig = await Isolate.packageConfig; |
+ } |
+ } |
+ |
// The VM will invoke [_startIsolate] and not `main`. |
readyPort = new RawReceivePort(); |
- var packageRootString = |
- (packageRoot == null) ? null : packageRoot.toString(); |
- var packagesList = null; |
+ var packageRootString = packageRoot?.toString(); |
+ var packageConfigString = packageConfig?.toString(); |
- _spawnUri(readyPort.sendPort, uri.toString(), |
+ _spawnUri(readyPort.sendPort, spawnedUri.toString(), |
args, message, |
paused, onExit, onError, |
errorsAreFatal, checked, |
null, /* environment */ |
- packageRootString, packagesList); |
- return _spawnCommon(readyPort); |
+ packageRootString, packageConfigString); |
+ return await _spawnCommon(readyPort); |
} catch (e, st) { |
if (readyPort != null) { |
readyPort.close(); |
} |
- return new Future<Isolate>.error(e, st); |
+ return await new Future<Isolate>.error(e, st); |
} |
} |
@@ -366,7 +438,8 @@ patch class Isolate { |
static void _spawnFunction(SendPort readyPort, Function topLevelFunction, |
var message, bool paused, bool errorsAreFatal, |
- SendPort onExit, SendPort onError) |
+ SendPort onExit, SendPort onError, |
+ String packageRoot, String packageConfig) |
native "Isolate_spawnFunction"; |
static void _spawnUri(SendPort readyPort, String uri, |
@@ -374,7 +447,7 @@ patch class Isolate { |
bool paused, SendPort onExit, SendPort onError, |
bool errorsAreFatal, bool checked, |
List environment, |
- String packageRoot, List packages) |
+ String packageRoot, String packageConfig) |
native "Isolate_spawnUri"; |
static void _sendOOB(port, msg) native "Isolate_sendOOB"; |
@@ -469,4 +542,15 @@ patch class Isolate { |
static List _getPortAndCapabilitiesOfCurrentIsolate() |
native "Isolate_getPortAndCapabilitiesOfCurrentIsolate"; |
+ |
+ static Uri _getCurrentRootUri() { |
+ try { |
+ return Uri.parse(_getCurrentRootUriStr()); |
+ } catch (e, s) { |
+ return null; |
+ } |
+ } |
+ |
+ static String _getCurrentRootUriStr() |
+ native "Isolate_getCurrentRootUriStr"; |
} |