| Index: sdk/lib/_internal/compiler/js_lib/js_helper.dart | 
| diff --git a/sdk/lib/_internal/compiler/js_lib/js_helper.dart b/sdk/lib/_internal/compiler/js_lib/js_helper.dart | 
| index 02ef267082e332bf5b6d1e49159a20c8eecb49e0..11cb46f07cd1f19edc53b2f5c63a88a6440f6de6 100644 | 
| --- a/sdk/lib/_internal/compiler/js_lib/js_helper.dart | 
| +++ b/sdk/lib/_internal/compiler/js_lib/js_helper.dart | 
| @@ -36,7 +36,8 @@ import 'dart:async' show | 
| StreamController, | 
| Stream, | 
| StreamSubscription, | 
| -    scheduleMicrotask; | 
| +    scheduleMicrotask, | 
| +    Zone; | 
|  | 
| import 'dart:_foreign_helper' show | 
| DART_CLOSURE_TO_JS, | 
| @@ -3740,8 +3741,8 @@ class ExceptionAndStackTrace { | 
| /// | 
| /// Returns the future of the completer for convenience of the first call. | 
| dynamic asyncHelper(dynamic object, | 
| -                    dynamic /* js function */ bodyFunctionOrErrorCode, | 
| -                    Completer completer) { | 
| +    dynamic /* int | WrappedAsyncBody */ bodyFunctionOrErrorCode, | 
| +    Completer completer) { | 
| if (identical(bodyFunctionOrErrorCode, async_error_codes.SUCCESS)) { | 
| completer.complete(object); | 
| return; | 
| @@ -3752,20 +3753,19 @@ dynamic asyncHelper(dynamic object, | 
| return; | 
| } | 
| Future future = object is Future ? object : new Future.value(object); | 
| -  future.then(_wrapJsFunctionForAsync(bodyFunctionOrErrorCode, | 
| -                                      async_error_codes.SUCCESS), | 
| +  future.then( | 
| +      (result) => bodyFunctionOrErrorCode(async_error_codes.SUCCESS, result), | 
| onError: (dynamic error, StackTrace stackTrace) { | 
| ExceptionAndStackTrace wrappedException = | 
| new ExceptionAndStackTrace(error, stackTrace); | 
| -        Function wrapped =_wrapJsFunctionForAsync(bodyFunctionOrErrorCode, | 
| -            async_error_codes.ERROR); | 
| -        wrapped(wrappedException); | 
| +        bodyFunctionOrErrorCode(async_error_codes.ERROR, wrappedException); | 
| }); | 
| return completer.future; | 
| } | 
|  | 
| -Function _wrapJsFunctionForAsync(dynamic /* js function */ function, | 
| -                                 int errorCode) { | 
| +typedef void WrappedAsyncBody(int errorCode, dynamic result); | 
| + | 
| +WrappedAsyncBody _wrapJsFunctionForAsync(dynamic /* js function */ function) { | 
| var protected = JS('', """ | 
| // Invokes [function] with [errorCode] and [result]. | 
| // | 
| @@ -3782,9 +3782,9 @@ Function _wrapJsFunctionForAsync(dynamic /* js function */ function, | 
| } | 
| } | 
| }""", function, async_error_codes.ERROR); | 
| -  return (result) { | 
| +  return Zone.current.bindBinaryCallback((int errorCode, dynamic result) { | 
| JS('', '#(#, #)', protected, errorCode, result); | 
| -  }; | 
| +  }); | 
| } | 
|  | 
| /// Implements the runtime support for async* functions. | 
| @@ -3824,8 +3824,8 @@ Function _wrapJsFunctionForAsync(dynamic /* js function */ function, | 
| /// If [object] is not a [Future], it is wrapped in a `Future.value`. | 
| /// The [asyncBody] is called on completion of the future (see [asyncHelper]. | 
| void asyncStarHelper(dynamic object, | 
| -                     dynamic /* int | js function */ bodyFunctionOrErrorCode, | 
| -                     AsyncStarStreamController controller) { | 
| +    dynamic /* int | WrappedAsyncBody */ bodyFunctionOrErrorCode, | 
| +    AsyncStarStreamController controller) { | 
| if (identical(bodyFunctionOrErrorCode, async_error_codes.SUCCESS)) { | 
| // This happens on return from the async* function. | 
| if (controller.isCanceled) { | 
| @@ -3850,9 +3850,7 @@ void asyncStarHelper(dynamic object, | 
|  | 
| if (object is IterationMarker) { | 
| if (controller.isCanceled) { | 
| -      Function wrapped = _wrapJsFunctionForAsync(bodyFunctionOrErrorCode, | 
| -          async_error_codes.STREAM_WAS_CANCELED); | 
| -      wrapped(null); | 
| +      bodyFunctionOrErrorCode(async_error_codes.STREAM_WAS_CANCELED, null); | 
| return; | 
| } | 
| if (object.state == IterationMarker.YIELD_SINGLE) { | 
| @@ -3866,9 +3864,7 @@ void asyncStarHelper(dynamic object, | 
| controller.isSuspended = true; | 
| return; | 
| } | 
| -        Function wrapped = _wrapJsFunctionForAsync(bodyFunctionOrErrorCode, | 
| -            async_error_codes.SUCCESS); | 
| -        wrapped(null); | 
| +        bodyFunctionOrErrorCode(null, async_error_codes.SUCCESS); | 
| }); | 
| return; | 
| } else if (object.state == IterationMarker.YIELD_STAR) { | 
| @@ -3884,24 +3880,20 @@ void asyncStarHelper(dynamic object, | 
| int errorCode = controller.isCanceled | 
| ? async_error_codes.STREAM_WAS_CANCELED | 
| : async_error_codes.SUCCESS; | 
| -        Function wrapped = _wrapJsFunctionForAsync(bodyFunctionOrErrorCode, | 
| -                                errorCode); | 
| -        wrapped(null); | 
| +        bodyFunctionOrErrorCode(errorCode, null); | 
| }); | 
| return; | 
| } | 
| } | 
|  | 
| Future future = object is Future ? object : new Future.value(object); | 
| -  future.then(_wrapJsFunctionForAsync(bodyFunctionOrErrorCode, | 
| -                                      async_error_codes.SUCCESS), | 
| -              onError: (error, StackTrace stackTrace) { | 
| -                ExceptionAndStackTrace wrappedException = | 
| -                    new ExceptionAndStackTrace(error, stackTrace); | 
| -                Function wrapped = _wrapJsFunctionForAsync( | 
| -                    bodyFunctionOrErrorCode, async_error_codes.ERROR); | 
| -                return wrapped(wrappedException); | 
| -              }); | 
| +  future.then( | 
| +      (result) => bodyFunctionOrErrorCode(async_error_codes.SUCCESS, result), | 
| +      onError: (error, StackTrace stackTrace) { | 
| +        ExceptionAndStackTrace wrappedException = | 
| +            new ExceptionAndStackTrace(error, stackTrace); | 
| +        bodyFunctionOrErrorCode(async_error_codes.ERROR, wrappedException); | 
| +      }); | 
| } | 
|  | 
| Stream streamOfController(AsyncStarStreamController controller) { | 
| @@ -3947,13 +3939,11 @@ class AsyncStarStreamController { | 
|  | 
| close() => controller.close(); | 
|  | 
| -  AsyncStarStreamController(body) { | 
| +  AsyncStarStreamController(WrappedAsyncBody body) { | 
|  | 
| _resumeBody() { | 
| scheduleMicrotask(() { | 
| -        Function wrapped = | 
| -            _wrapJsFunctionForAsync(body, async_error_codes.SUCCESS); | 
| -        wrapped(null); | 
| +        body(async_error_codes.SUCCESS, null); | 
| }); | 
| } | 
|  | 
| @@ -3976,9 +3966,7 @@ class AsyncStarStreamController { | 
| // Resume the suspended async* function to run finalizers. | 
| isSuspended = false; | 
| scheduleMicrotask(() { | 
| -              Function wrapped =_wrapJsFunctionForAsync(body, | 
| -                  async_error_codes.STREAM_WAS_CANCELED); | 
| -              wrapped(null); | 
| +              body(async_error_codes.STREAM_WAS_CANCELED, null); | 
| }); | 
| } | 
| return cancelationCompleter.future; | 
|  |