Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 Loading... | |
| 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 } |
| OLD | NEW |