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

Side by Side Diff: runtime/lib/core_patch.dart

Issue 944893005: Implement async* functions in VM (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 5 years, 9 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
« no previous file with comments | « no previous file | runtime/vm/flow_graph_builder.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 import "dart:math"; 5 import "dart:math";
6 import "dart:typed_data"; 6 import "dart:typed_data";
7 7
8 // Equivalent of calling FATAL from C++ code. 8 // Equivalent of calling FATAL from C++ code.
9 _fatal(msg) native "DartCore_fatal"; 9 _fatal(msg) native "DartCore_fatal";
10 10
11 11
12 // We need to pass the exception and stack trace objects as second and third 12 // We need to pass the exception and stack trace objects as second and third
13 // parameter to the continuation. See vm/ast_transformer.cc for usage. 13 // parameter to the continuation. See vm/ast_transformer.cc for usage.
14 void _asyncCatchHelper(catchFunction, continuation) { 14 void _asyncCatchHelper(catchFunction, continuation) {
15 catchFunction((e, s) => continuation(null, e, s)); 15 catchFunction((e, s) => continuation(null, e, s));
16 } 16 }
17 17
18 // The members of this class are cloned and added to each class that 18 // The members of this class are cloned and added to each class that
19 // represents an enum type. 19 // represents an enum type.
20 class _EnumHelper { 20 class _EnumHelper {
21 // Declare the list of enum value names private. When this field is 21 // Declare the list of enum value names private. When this field is
22 // cloned into a user-defined enum class, the field will be inaccessible 22 // cloned into a user-defined enum class, the field will be inaccessible
23 // because of the library-specific name suffix. The toString() function 23 // because of the library-specific name suffix. The toString() function
24 // below can access it because it uses the same name suffix. 24 // below can access it because it uses the same name suffix.
25 static const List<String> _enum_names = null; 25 static const List<String> _enum_names = null;
26 String toString() => _enum_names[index]; 26 String toString() => _enum_names[index];
27 } 27 }
28 28
29 typedef bool SyncGeneratorCallback(Iterator iterator); 29
30 // _AsyncStarStreamController is used by the compiler to implement
31 // async* generator functions.
32 class _AsyncStarStreamController {
33 StreamController controller;
34 Function asyncStarBody;
35 bool isAdding = false;
36 bool isCancelled = false;
37 bool onListenReceived = false;
38 bool isClosed = false;
39
40 Stream get stream => controller.stream;
41
42 // Adds element to steam, returns true iff the caller should suspend
Lasse Reichstein Nielsen 2015/02/26 14:54:52 suspend -> terminate/return from?
hausner 2015/02/26 21:54:07 Correct.
43 // execution of the generator.
44 bool add(event) {
45 if (!onListenReceived) _fatal("yield before stream is listened to!");
46 // If stream is cancelled, tell caller to exit the async generator.
Lasse Reichstein Nielsen 2015/02/26 14:54:52 The spec says that you should pause first if the s
hausner 2015/02/26 21:54:07 I am leaving this as a TODO for later. The body cl
Lasse Reichstein Nielsen 2015/02/27 07:51:12 Looks fine. It basically what I did in an attempt
47 if (!controller.hasListener) {
48 return true;
49 }
50 controller.add(event);
51 if (!controller.isPaused) {
52 scheduleMicrotask(asyncStarBody);
53 }
54 return false;
55 }
56
57 // Adds stream, tells caller to suspend execution of the generator
58 // function. The generator will be scheduled again when all of the
59 // elements of the added stream have been consumed.
60 bool addStream(Stream stream) {
61 assert(onListenReceived);
62 // If stream is cancelled, tell caller to exit the async generator.
63 if (!controller.hasListener) return true;
64 isAdding = true;
65 var whenDoneAdding =
66 controller.addStream(stream as Stream, cancelOnError: false);
67 whenDoneAdding.then((_) {
68 isAdding = false;
69 if (!controller.isPaused) {
70 scheduleMicrotask(asyncStarBody);
71 }
72 });
73 return false;
74 }
75
76 addError(error, stackTrace) {
77 if (!onListenReceived) _fatal("yield before stream is listened to!");
78 // If stream is cancelled, tell caller to exit the async generator.
79 if (!controller.hasListener) return true;
Lasse Reichstein Nielsen 2015/02/26 14:54:52 I think an uncaught exception reaching the stream
hausner 2015/02/26 21:54:08 Yes, this method is only called from the implicit
80 controller.addError(error, stackTrace);
81 if (!controller.isPaused) {
82 scheduleMicrotask(asyncStarBody);
83 return false;
84 }
85
Lasse Reichstein Nielsen 2015/02/26 14:54:52 It returns null if the controller isn't paused - w
hausner 2015/02/26 21:54:07 Done.
86 }
87
88 close() {
89 isClosed = true;
90 controller.close();
91 }
92
93 _AsyncStarStreamController(this.asyncStarBody) {
94 controller = new StreamController(onListen: this.onListen,
95 onResume: this.onResume,
96 onCancel: this.onCancel);
97 }
98
99 onListen() {
100 assert(!onListenReceived);
101 onListenReceived = true;
102 scheduleMicrotask(asyncStarBody);
103 }
104
105 onResume() {
106 if (!isAdding) {
107 scheduleMicrotask(asyncStarBody);
Lasse Reichstein Nielsen 2015/02/26 14:54:52 This is still error-prone if you get another resum
hausner 2015/02/26 21:54:07 Ok, done. I was thinking about this possibility ye
108 }
109 }
110
111 onCancel() {
112 if (!isClosed) {
Lasse Reichstein Nielsen 2015/02/26 14:54:52 You can use controller.isClosed. It's set to true
hausner 2015/02/26 21:54:07 Done.
113 scheduleMicrotask(asyncStarBody);
114 }
115 }
116 }
117
30 118
31 // _SyncIterable and _syncIterator are used by the compiler to 119 // _SyncIterable and _syncIterator are used by the compiler to
32 // implement sync* generator functions. A sync* generator allocates 120 // implement sync* generator functions. A sync* generator allocates
33 // and returns a new _SyncIterable object. 121 // and returns a new _SyncIterable object.
122
123 typedef bool SyncGeneratorCallback(Iterator iterator);
124
34 class _SyncIterable extends IterableBase { 125 class _SyncIterable extends IterableBase {
35 // moveNextFn is the closurized body of the generator function. 126 // moveNextFn is the closurized body of the generator function.
36 final SyncGeneratorCallback moveNextFn; 127 final SyncGeneratorCallback moveNextFn;
37 128
38 const _SyncIterable(this.moveNextFn); 129 const _SyncIterable(this.moveNextFn);
39 130
40 get iterator { 131 get iterator {
41 return new _SyncIterator(moveNextFn._clone()); 132 return new _SyncIterator(moveNextFn._clone());
42 } 133 }
43 } 134 }
(...skipping 27 matching lines...) Expand all
71 if (isYieldEach) { 162 if (isYieldEach) {
72 // Spec mandates: it is a dynamic error if the class of [the object 163 // Spec mandates: it is a dynamic error if the class of [the object
73 // returned by yield*] does not implement Iterable. 164 // returned by yield*] does not implement Iterable.
74 yieldEachIterator = (current as Iterable).iterator; 165 yieldEachIterator = (current as Iterable).iterator;
75 continue; 166 continue;
76 } 167 }
77 return true; 168 return true;
78 } 169 }
79 } 170 }
80 } 171 }
OLDNEW
« no previous file with comments | « no previous file | runtime/vm/flow_graph_builder.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698