Index: pkg/dev_compiler/tool/input_sdk/patch/isolate_patch.dart |
diff --git a/pkg/dev_compiler/tool/input_sdk/patch/isolate_patch.dart b/pkg/dev_compiler/tool/input_sdk/patch/isolate_patch.dart |
index 3498c7adfd89b81054c42db7639f0611cec9b612..637943b44eacd224c3784d107741c8f1911621fe 100644 |
--- a/pkg/dev_compiler/tool/input_sdk/patch/isolate_patch.dart |
+++ b/pkg/dev_compiler/tool/input_sdk/patch/isolate_patch.dart |
@@ -6,12 +6,12 @@ |
import 'dart:_js_helper' show patch; |
import 'dart:_isolate_helper' show CapabilityImpl, |
- CloseToken, |
IsolateNatives, |
- JsIsolateSink, |
ReceivePortImpl, |
RawReceivePortImpl; |
+typedef _UnaryFunction(arg); |
+ |
@patch |
class Isolate { |
static final _currentIsolateCache = IsolateNatives.currentIsolate; |
@@ -22,13 +22,61 @@ class Isolate { |
static Isolate get current => _currentIsolateCache; |
@patch |
+ static Future<Uri> get packageRoot { |
+ throw new UnsupportedError("Isolate.packageRoot"); |
+ } |
+ |
+ @patch |
+ static Future<Uri> get packageConfig { |
+ throw new UnsupportedError("Isolate.packageConfig"); |
+ } |
+ |
+ static Uri _packageBase = Uri.base.resolve(IsolateNatives.packagesBase); |
+ |
+ @patch |
+ static Future<Uri> resolvePackageUri(Uri packageUri) async { |
+ if (packageUri.scheme != 'package') return packageUri; |
+ return _packageBase.resolveUri(packageUri.replace(scheme: '')); |
+ } |
+ |
+ @patch |
static Future<Isolate> spawn(void entryPoint(message), var message, |
- { bool paused: false }) { |
+ {bool paused: false, bool errorsAreFatal, |
+ SendPort onExit, SendPort onError}) { |
+ bool forcePause = (errorsAreFatal != null) || |
+ (onExit != null) || |
+ (onError != null); |
try { |
- return IsolateNatives.spawnFunction(entryPoint, message, paused) |
- .then((msg) => new Isolate(msg[1], |
- pauseCapability: msg[2], |
- terminateCapability: msg[3])); |
+ // Check for the type of `entryPoint` on the spawning isolate to make |
+ // error-handling easier. |
+ if (entryPoint is! _UnaryFunction) { |
+ throw new ArgumentError(entryPoint); |
+ } |
+ // TODO: Consider passing the errorsAreFatal/onExit/onError values |
+ // as arguments to the internal spawnUri instead of setting |
+ // them after the isolate has been created. |
+ return IsolateNatives.spawnFunction(entryPoint, message, |
+ paused || forcePause) |
+ .then((msg) { |
+ var isolate = new Isolate(msg[1], |
+ pauseCapability: msg[2], |
+ terminateCapability: msg[3]); |
+ if (forcePause) { |
+ if (errorsAreFatal != null) { |
+ isolate.setErrorsFatal(errorsAreFatal); |
+ } |
+ if (onExit != null) { |
+ isolate.addOnExitListener(onExit); |
+ } |
+ if (onError != null) { |
+ isolate.addErrorListener(onError); |
+ } |
+ if (!paused) { |
+ isolate.resume(isolate.pauseCapability); |
+ } |
+ } |
+ return isolate; |
+ }); |
} catch (e, st) { |
return new Future<Isolate>.error(e, st); |
} |
@@ -36,11 +84,26 @@ class Isolate { |
@patch |
static Future<Isolate> spawnUri( |
- Uri uri, List<String> args, var message, { bool paused: false, |
- Uri packageRoot }) { |
+ Uri uri, List<String> args, var message, |
+ {bool paused: false, |
+ SendPort onExit, |
+ SendPort onError, |
+ bool errorsAreFatal, |
+ bool checked, |
+ Map<String, String> environment, |
+ Uri packageRoot, |
+ Uri packageConfig, |
+ bool automaticPackageResolution: false}) { |
+ if (environment != null) throw new UnimplementedError("environment"); |
if (packageRoot != null) throw new UnimplementedError("packageRoot"); |
+ if (packageConfig != null) throw new UnimplementedError("packageConfig"); |
+ // TODO(lrn): Figure out how to handle the automaticPackageResolution |
+ // parameter. |
+ bool forcePause = (errorsAreFatal != null) || |
+ (onExit != null) || |
+ (onError != null); |
try { |
- if (args is List) { |
+ if (args is List<String>) { |
for (int i = 0; i < args.length; i++) { |
if (args[i] is! String) { |
throw new ArgumentError("Args must be a list of Strings $args"); |
@@ -49,10 +112,31 @@ class Isolate { |
} else if (args != null) { |
throw new ArgumentError("Args must be a list of Strings $args"); |
} |
- return IsolateNatives.spawnUri(uri, args, message, paused) |
- .then((msg) => new Isolate(msg[1], |
- pauseCapability: msg[2], |
- terminateCapability: msg[3])); |
+ // TODO: Handle [packageRoot] somehow, possibly by throwing. |
+ // TODO: Consider passing the errorsAreFatal/onExit/onError values |
+ // as arguments to the internal spawnUri instead of setting |
+ // them after the isolate has been created. |
+ return IsolateNatives.spawnUri(uri, args, message, paused || forcePause) |
+ .then((msg) { |
+ var isolate = new Isolate(msg[1], |
+ pauseCapability: msg[2], |
+ terminateCapability: msg[3]); |
+ if (forcePause) { |
+ if (errorsAreFatal != null) { |
+ isolate.setErrorsFatal(errorsAreFatal); |
+ } |
+ if (onExit != null) { |
+ isolate.addOnExitListener(onExit); |
+ } |
+ if (onError != null) { |
+ isolate.addErrorListener(onError); |
+ } |
+ if (!paused) { |
+ isolate.resume(isolate.pauseCapability); |
+ } |
+ } |
+ return isolate; |
+ }); |
} catch (e, st) { |
return new Future<Isolate>.error(e, st); |
} |
@@ -76,12 +160,13 @@ class Isolate { |
} |
@patch |
- void addOnExitListener(SendPort responsePort) { |
+ void addOnExitListener(SendPort responsePort, {Object response}) { |
// TODO(lrn): Can we have an internal method that checks if the receiving |
// isolate of a SendPort is still alive? |
- var message = new List(2) |
+ var message = new List(3) |
..[0] = "add-ondone" |
- ..[1] = responsePort; |
+ ..[1] = responsePort |
+ ..[2] = response; |
controlPort.send(message); |
} |
@@ -103,16 +188,18 @@ class Isolate { |
} |
@patch |
- void kill([int priority = BEFORE_NEXT_EVENT]) { |
+ void kill({int priority: BEFORE_NEXT_EVENT}) { |
controlPort.send(["kill", terminateCapability, priority]); |
} |
@patch |
- void ping(SendPort responsePort, [int pingType = IMMEDIATE]) { |
- var message = new List(3) |
+ void ping(SendPort responsePort, {Object response, |
+ int priority: IMMEDIATE}) { |
+ var message = new List(4) |
..[0] = "ping" |
..[1] = responsePort |
- ..[2] = pingType; |
+ ..[2] = priority |
+ ..[3] = response; |
controlPort.send(message); |
} |