Revision: 22872
Author:   [email protected]
Date:     Tue Aug  5 13:17:49 2014 UTC
Log:      yield* calls @@iterator on iterable

[email protected]
BUG=v8:3422
LOG=N

Review URL: https://codereview.chromium.org/430693003
http://code.google.com/p/v8/source/detail?r=22872

Modified:
 /branches/bleeding_edge/src/parser.cc
 /branches/bleeding_edge/src/parser.h
 /branches/bleeding_edge/src/preparser.h
 /branches/bleeding_edge/test/mjsunit/harmony/generators-iteration.js

=======================================
--- /branches/bleeding_edge/src/parser.cc       Mon Aug  4 11:34:54 2014 UTC
+++ /branches/bleeding_edge/src/parser.cc       Tue Aug  5 13:17:49 2014 UTC
@@ -663,6 +663,19 @@
   if (parser_->fni_ != NULL) parser_->fni_->PushLiteralName(symbol);
   return factory->NewStringLiteral(symbol, pos);
 }
+
+
+Expression* ParserTraits::GetIterator(
+ Expression* iterable, AstNodeFactory<AstConstructionVisitor>* factory) {
+  Expression* iterator_symbol_literal =
+      factory->NewSymbolLiteral("symbolIterator", RelocInfo::kNoPosition);
+  int pos = iterable->position();
+  Expression* prop =
+      factory->NewProperty(iterable, iterator_symbol_literal, pos);
+  Zone* zone = parser_->zone();
+  ZoneList<Expression*>* args = new (zone) ZoneList<Expression*>(0, zone);
+  return factory->NewCall(prop, args, pos);
+}


 Literal* ParserTraits::GetLiteralTheHole(
@@ -2773,23 +2786,9 @@
     Expression* assign_each;

     // var iterator = subject[Symbol.iterator]();
-    {
-      Expression* iterator_symbol_literal =
- factory()->NewSymbolLiteral("symbolIterator", RelocInfo::kNoPosition); - // FIXME(wingo): Unhappily, it will be a common error that the RHS of a - // for-of doesn't have a Symbol.iterator property. We should do better
-      // than informing the user that "undefined is not a function".
-      int pos = subject->position();
-      Expression* iterator_property =
-          factory()->NewProperty(subject, iterator_symbol_literal, pos);
-      ZoneList<Expression*>* iterator_arguments =
-          new(zone()) ZoneList<Expression*>(0, zone());
-      Expression* iterator_call = factory()->NewCall(
-          iterator_property, iterator_arguments, pos);
-      Expression* iterator_proxy = factory()->NewVariableProxy(iterator);
-      assign_iterator = factory()->NewAssignment(
- Token::ASSIGN, iterator_proxy, iterator_call, RelocInfo::kNoPosition);
-    }
+    assign_iterator = factory()->NewAssignment(
+        Token::ASSIGN, factory()->NewVariableProxy(iterator),
+        GetIterator(subject, factory()), RelocInfo::kNoPosition);

     // var result = iterator.next();
     {
=======================================
--- /branches/bleeding_edge/src/parser.h        Mon Aug  4 11:34:54 2014 UTC
+++ /branches/bleeding_edge/src/parser.h        Tue Aug  5 13:17:49 2014 UTC
@@ -543,6 +543,8 @@
   Expression* ExpressionFromString(
       int pos, Scanner* scanner,
       AstNodeFactory<AstConstructionVisitor>* factory);
+  Expression* GetIterator(Expression* iterable,
+                          AstNodeFactory<AstConstructionVisitor>* factory);
ZoneList<v8::internal::Expression*>* NewExpressionList(int size, Zone* zone) {
     return new(zone) ZoneList<v8::internal::Expression*>(size, zone);
   }
=======================================
--- /branches/bleeding_edge/src/preparser.h     Mon Aug  4 11:34:54 2014 UTC
+++ /branches/bleeding_edge/src/preparser.h     Tue Aug  5 13:17:49 2014 UTC
@@ -1231,6 +1231,11 @@
   PreParserExpression ExpressionFromString(int pos,
                                            Scanner* scanner,
PreParserFactory* factory = NULL);
+
+  PreParserExpression GetIterator(PreParserExpression iterable,
+                                  PreParserFactory* factory) {
+    return PreParserExpression::Default();
+  }

   static PreParserExpressionList NewExpressionList(int size, void* zone) {
     return PreParserExpressionList();
@@ -2094,6 +2099,10 @@
         break;
     }
   }
+  if (kind == Yield::DELEGATING) {
+    // var iterator = subject[Symbol.iterator]();
+    expression = this->GetIterator(expression, factory());
+  }
   typename Traits::Type::YieldExpression yield =
       factory()->NewYield(generator_object, expression, kind, pos);
   if (kind == Yield::DELEGATING) {
=======================================
--- /branches/bleeding_edge/test/mjsunit/harmony/generators-iteration.js Wed Jul 2 13:48:28 2014 UTC +++ /branches/bleeding_edge/test/mjsunit/harmony/generators-iteration.js Tue Aug 5 13:17:49 2014 UTC
@@ -25,7 +25,7 @@
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

-// Flags: --harmony-generators --expose-gc
+// Flags: --harmony-generators --expose-gc --harmony-iteration

 // Test generator iteration.

@@ -355,6 +355,32 @@
     "foo",
     [undefined, undefined]);

+// TODO(wingo): We should use TestGenerator for these, except that
+// currently yield* will unconditionally propagate a throw() to the
+// delegate iterator, which fails for these iterators that don't have
+// throw().  See http://code.google.com/p/v8/issues/detail?id=3484.
+(function() {
+    function* g28() {
+      yield* [1, 2, 3];
+    }
+    var iter = g28();
+    assertIteratorResult(1, false, iter.next());
+    assertIteratorResult(2, false, iter.next());
+    assertIteratorResult(3, false, iter.next());
+    assertIteratorResult(undefined, true, iter.next());
+})();
+
+(function() {
+    function* g29() {
+      yield* "abc";
+    }
+    var iter = g29();
+    assertIteratorResult("a", false, iter.next());
+    assertIteratorResult("b", false, iter.next());
+    assertIteratorResult("c", false, iter.next());
+    assertIteratorResult(undefined, true, iter.next());
+})();
+
 // Generator function instances.
 TestGenerator(GeneratorFunction(),
               [undefined],
@@ -393,12 +419,16 @@
     function next() {
       return results[i++];
     }
-    return { next: next }
+    var iter = { next: next };
+    var ret = {};
+    ret[Symbol.iterator] = function() { return iter; };
+    return ret;
   }
   function* yield_results(expected) {
     return yield* results(expected);
   }
-  function collect_results(iter) {
+  function collect_results(iterable) {
+    var iter = iterable[Symbol.iterator]();
     var ret = [];
     var result;
     do {

--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
--- You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to