| 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); | 
| } | 
|  | 
|  |