Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(47)

Side by Side Diff: sdk/lib/_internal/compiler/js_lib/js_helper.dart

Issue 1070733002: Dart2js async* functions only resume execution of the body when suspended on yield. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 5 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 library _js_helper; 5 library _js_helper;
6 6
7 import 'dart:_async_await_error_codes' as async_error_codes; 7 import 'dart:_async_await_error_codes' as async_error_codes;
8 8
9 import 'dart:_js_embedded_names' show 9 import 'dart:_js_embedded_names' show
10 DEFERRED_LIBRARY_URIS, 10 DEFERRED_LIBRARY_URIS,
(...skipping 3723 matching lines...) Expand 10 before | Expand all | Expand 10 after
3734 return; 3734 return;
3735 } 3735 }
3736 3736
3737 if (object is IterationMarker) { 3737 if (object is IterationMarker) {
3738 if (controller.cancelationCompleter != null) { 3738 if (controller.cancelationCompleter != null) {
3739 _wrapJsFunctionForAsync(bodyFunctionOrErrorCode, 3739 _wrapJsFunctionForAsync(bodyFunctionOrErrorCode,
3740 async_error_codes.STREAM_WAS_CANCELED)(null); 3740 async_error_codes.STREAM_WAS_CANCELED)(null);
3741 return; 3741 return;
3742 } 3742 }
3743 if (object.state == IterationMarker.YIELD_SINGLE) { 3743 if (object.state == IterationMarker.YIELD_SINGLE) {
3744 controller.isWaitingForYield = true;
3744 controller.add(object.value); 3745 controller.add(object.value);
3745 // If the controller is paused we stop producing more values. 3746 // If the controller is paused we stop producing more values.
3746 if (controller.isPaused) { 3747 if (controller.isPaused) {
3747 return; 3748 return;
3748 } 3749 }
3749 // TODO(sigurdm): We should not suspend here according to the spec. 3750 // TODO(sigurdm): We should not suspend here according to the spec.
Lasse Reichstein Nielsen 2015/04/08 14:12:14 Isn't the spec allowing you to do so, but not requ
sigurdm 2015/04/09 11:24:08 Yes I think so - this is an outdated comment. Remo
3750 scheduleMicrotask(() { 3751 scheduleMicrotask(() {
3752 controller.isWaitingForYield = false;
Lasse Reichstein Nielsen 2015/04/08 14:12:15 I think this line should be moved outside of the s
sigurdm 2015/04/09 11:24:08 Done.
3751 _wrapJsFunctionForAsync(bodyFunctionOrErrorCode, 3753 _wrapJsFunctionForAsync(bodyFunctionOrErrorCode,
3752 async_error_codes.SUCCESS) 3754 async_error_codes.SUCCESS)
3753 (null); 3755 (null);
3754 }); 3756 });
Lasse Reichstein Nielsen 2015/04/08 14:12:14 I think I would prefer waiting until the scheduleM
sigurdm 2015/04/09 11:24:08 Done.
3755 return; 3757 return;
3756 } else if (object.state == IterationMarker.YIELD_STAR) { 3758 } else if (object.state == IterationMarker.YIELD_STAR) {
3757 Stream stream = object.value; 3759 Stream stream = object.value;
3758 controller.isAdding = true; 3760 controller.isAdding = true;
3759 // Errors of [stream] are passed though to the main stream. (see 3761 // Errors of [stream] are passed though to the main stream. (see
3760 // [AsyncStreamController.addStream]. 3762 // [AsyncStreamController.addStream].
Lasse Reichstein Nielsen 2015/04/08 14:12:15 Missing end-paren :)
sigurdm 2015/04/09 11:24:08 Thanks!
3761 // TODO(sigurdm): The spec is not very clear here. Clarify with Gilad. 3763 // TODO(sigurdm): The spec is not very clear here. Clarify with Gilad.
3762 controller.addStream(stream).then((_) { 3764 controller.addStream(stream).then((_) {
3763 controller.isAdding = false; 3765 controller.isAdding = false;
3764 _wrapJsFunctionForAsync(bodyFunctionOrErrorCode, 3766 _wrapJsFunctionForAsync(bodyFunctionOrErrorCode,
3765 async_error_codes.SUCCESS)(null); 3767 async_error_codes.SUCCESS)(null);
3766 }); 3768 });
3767 return; 3769 return;
3768 } 3770 }
3769 } 3771 }
3770 3772
(...skipping 18 matching lines...) Expand all
3789 /// 3791 ///
3790 /// Also has a subSubscription that when not null will provide events for the 3792 /// Also has a subSubscription that when not null will provide events for the
3791 /// stream, and will be paused and resumed along with this controller. 3793 /// stream, and will be paused and resumed along with this controller.
3792 class AsyncStarStreamController { 3794 class AsyncStarStreamController {
3793 StreamController controller; 3795 StreamController controller;
3794 Stream get stream => controller.stream; 3796 Stream get stream => controller.stream;
3795 Completer cancelationCompleter = null; 3797 Completer cancelationCompleter = null;
3796 bool get isCanceled => cancelationCompleter != null; 3798 bool get isCanceled => cancelationCompleter != null;
3797 bool isAdding = false; 3799 bool isAdding = false;
3798 bool isPaused = false; 3800 bool isPaused = false;
3801 bool isWaitingForYield = false;
floitsch 2015/04/08 14:01:25 isAtYield ? Add comment what exactly this means.
sigurdm 2015/04/08 14:07:40 Done.
Lasse Reichstein Nielsen 2015/04/08 14:12:14 Consider documenting these fields, preferably by d
sigurdm 2015/04/09 11:24:08 Good advice! I realized I can leave out `isAdding`
3802
3799 add(event) => controller.add(event); 3803 add(event) => controller.add(event);
3800 addStream(Stream stream) { 3804 addStream(Stream stream) {
3801 return controller.addStream(stream, cancelOnError: false); 3805 return controller.addStream(stream, cancelOnError: false);
3802 } 3806 }
3803 addError(error, stackTrace) => controller.addError(error, stackTrace); 3807 addError(error, stackTrace) => controller.addError(error, stackTrace);
3804 close() => controller.close(); 3808 close() => controller.close();
3805 3809
3806 AsyncStarStreamController(body) { 3810 AsyncStarStreamController(body) {
3807 controller = new StreamController( 3811 controller = new StreamController(
3808 onListen: () { 3812 onListen: () {
3809 scheduleMicrotask(() { 3813 scheduleMicrotask(() {
3810 Function wrapped = _wrapJsFunctionForAsync(body, 3814 Function wrapped =
3811 async_error_codes.SUCCESS); 3815 _wrapJsFunctionForAsync(body, async_error_codes.SUCCESS);
3812 wrapped(null); 3816 wrapped(null);
3813 }); 3817 });
3814 }, 3818 },
3815 onPause: () { 3819 onPause: () {
3816 isPaused = true; 3820 isPaused = true;
3817 }, onResume: () { 3821 }, onResume: () {
3818 isPaused = false; 3822 isPaused = false;
3819 if (!isAdding) { 3823 if (!isAdding && isWaitingForYield) {
Lasse Reichstein Nielsen 2015/04/08 14:12:15 I don't think this is safe enough. If the stream
Lasse Reichstein Nielsen 2015/04/08 14:12:15 Maybe name it "isWaitingForResume"? You have alrea
sigurdm 2015/04/09 11:24:08 It is now isSuspended
3820 asyncStarHelper(null, body, this); 3824 asyncStarHelper(null, body, this);
3821 } 3825 }
3822 }, onCancel: () { 3826 }, onCancel: () {
3823 if (!controller.isClosed) { 3827 if (!controller.isClosed) {
3824 cancelationCompleter = new Completer(); 3828 cancelationCompleter = new Completer();
3825 if (isPaused) asyncStarHelper(null, body, this); 3829 if (isPaused) asyncStarHelper(null, body, this);
Lasse Reichstein Nielsen 2015/04/08 14:12:14 Are you sure this is safe? You can have a call to
sigurdm 2015/04/09 11:24:08 True - I need a better mechanism for this. Now I o
3826 3830
3827 return cancelationCompleter.future; 3831 return cancelationCompleter.future;
3828 } 3832 }
3829 }); 3833 });
3830 } 3834 }
3831 } 3835 }
3832 3836
3833 makeAsyncStarController(body) { 3837 makeAsyncStarController(body) {
3834 return new AsyncStarStreamController(body); 3838 return new AsyncStarStreamController(body);
3835 } 3839 }
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
3932 // This is a function that will return a helper function that does the 3936 // This is a function that will return a helper function that does the
3933 // iteration of the sync*. 3937 // iteration of the sync*.
3934 // 3938 //
3935 // Each invocation should give a body with fresh state. 3939 // Each invocation should give a body with fresh state.
3936 final dynamic /* js function */ _outerHelper; 3940 final dynamic /* js function */ _outerHelper;
3937 3941
3938 SyncStarIterable(this._outerHelper); 3942 SyncStarIterable(this._outerHelper);
3939 3943
3940 Iterator get iterator => new SyncStarIterator(JS('', '#()', _outerHelper)); 3944 Iterator get iterator => new SyncStarIterator(JS('', '#()', _outerHelper));
3941 } 3945 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698