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