Revision: 22602
Author:   [email protected]
Date:     Thu Jul 24 13:40:08 2014 UTC
Log:      For-of on null or undefined is an error

The latest ES6 draft changed the behavior of for-of on null / undefined,
which for once is a simplification.

[email protected]
BUG=

Review URL: https://codereview.chromium.org/416033002

Patch from Andy Wingo <[email protected]>.
http://code.google.com/p/v8/source/detail?r=22602

Modified:
 /branches/bleeding_edge/src/arm/full-codegen-arm.cc
 /branches/bleeding_edge/src/arm64/full-codegen-arm64.cc
 /branches/bleeding_edge/src/ast-value-factory.h
 /branches/bleeding_edge/src/ast.h
 /branches/bleeding_edge/src/ia32/full-codegen-ia32.cc
 /branches/bleeding_edge/src/mips/full-codegen-mips.cc
 /branches/bleeding_edge/src/mips64/full-codegen-mips64.cc
 /branches/bleeding_edge/src/parser.cc
 /branches/bleeding_edge/src/x64/full-codegen-x64.cc
 /branches/bleeding_edge/src/x87/full-codegen-x87.cc
 /branches/bleeding_edge/test/mjsunit/harmony/iteration-semantics.js

=======================================
--- /branches/bleeding_edge/src/arm/full-codegen-arm.cc Wed Jul 23 09:35:06 2014 UTC +++ /branches/bleeding_edge/src/arm/full-codegen-arm.cc Thu Jul 24 13:40:08 2014 UTC
@@ -1276,15 +1276,6 @@
   Iteration loop_statement(this, stmt);
   increment_loop_depth();

-  // var iterable = subject
-  VisitForAccumulatorValue(stmt->assign_iterable());
-
-  // As with for-in, skip the loop if the iterator is null or undefined.
-  __ CompareRoot(r0, Heap::kUndefinedValueRootIndex);
-  __ b(eq, loop_statement.break_label());
-  __ CompareRoot(r0, Heap::kNullValueRootIndex);
-  __ b(eq, loop_statement.break_label());
-
   // var iterator = iterable[Symbol.iterator]();
   VisitForEffect(stmt->assign_iterator());

=======================================
--- /branches/bleeding_edge/src/arm64/full-codegen-arm64.cc Wed Jul 23 09:35:06 2014 UTC +++ /branches/bleeding_edge/src/arm64/full-codegen-arm64.cc Thu Jul 24 13:40:08 2014 UTC
@@ -1271,16 +1271,6 @@
   Iteration loop_statement(this, stmt);
   increment_loop_depth();

-  // var iterable = subject
-  VisitForAccumulatorValue(stmt->assign_iterable());
-
-  // As with for-in, skip the loop if the iterator is null or undefined.
-  Register iterator = x0;
-  __ JumpIfRoot(iterator, Heap::kUndefinedValueRootIndex,
-                loop_statement.break_label());
-  __ JumpIfRoot(iterator, Heap::kNullValueRootIndex,
-                loop_statement.break_label());
-
   // var iterator = iterable[Symbol.iterator]();
   VisitForEffect(stmt->assign_iterator());

=======================================
--- /branches/bleeding_edge/src/ast-value-factory.h Mon Jun 30 13:35:16 2014 UTC +++ /branches/bleeding_edge/src/ast-value-factory.h Thu Jul 24 13:40:08 2014 UTC
@@ -243,7 +243,6 @@
   F(dot_for, ".for") \
   F(dot_generator, ".generator") \
   F(dot_generator_object, ".generator_object") \
-  F(dot_iterable, ".iterable") \
   F(dot_iterator, ".iterator") \
   F(dot_module, ".module") \
   F(dot_result, ".result") \
=======================================
--- /branches/bleeding_edge/src/ast.h   Tue Jul 22 14:27:53 2014 UTC
+++ /branches/bleeding_edge/src/ast.h   Thu Jul 24 13:40:08 2014 UTC
@@ -961,13 +961,11 @@
   void Initialize(Expression* each,
                   Expression* subject,
                   Statement* body,
-                  Expression* assign_iterable,
                   Expression* assign_iterator,
                   Expression* next_result,
                   Expression* result_done,
                   Expression* assign_each) {
     ForEachStatement::Initialize(each, subject, body);
-    assign_iterable_ = assign_iterable;
     assign_iterator_ = assign_iterator;
     next_result_ = next_result;
     result_done_ = result_done;
@@ -978,12 +976,7 @@
     return subject();
   }

-  // var iterable = subject;
-  Expression* assign_iterable() const {
-    return assign_iterable_;
-  }
-
-  // var iterator = iterable[Symbol.iterator]();
+  // var iterator = subject[Symbol.iterator]();
   Expression* assign_iterator() const {
     return assign_iterator_;
   }
@@ -1018,7 +1011,6 @@
         back_edge_id_(GetNextId(zone)) {
   }

-  Expression* assign_iterable_;
   Expression* assign_iterator_;
   Expression* next_result_;
   Expression* result_done_;
=======================================
--- /branches/bleeding_edge/src/ia32/full-codegen-ia32.cc Wed Jul 23 09:35:06 2014 UTC +++ /branches/bleeding_edge/src/ia32/full-codegen-ia32.cc Thu Jul 24 13:40:08 2014 UTC
@@ -1207,15 +1207,6 @@
   Iteration loop_statement(this, stmt);
   increment_loop_depth();

-  // var iterable = subject
-  VisitForAccumulatorValue(stmt->assign_iterable());
-
-  // As with for-in, skip the loop if the iterator is null or undefined.
-  __ CompareRoot(eax, Heap::kUndefinedValueRootIndex);
-  __ j(equal, loop_statement.break_label());
-  __ CompareRoot(eax, Heap::kNullValueRootIndex);
-  __ j(equal, loop_statement.break_label());
-
   // var iterator = iterable[Symbol.iterator]();
   VisitForEffect(stmt->assign_iterator());

=======================================
--- /branches/bleeding_edge/src/mips/full-codegen-mips.cc Wed Jul 23 09:35:06 2014 UTC +++ /branches/bleeding_edge/src/mips/full-codegen-mips.cc Thu Jul 24 13:40:08 2014 UTC
@@ -1272,16 +1272,6 @@
   Iteration loop_statement(this, stmt);
   increment_loop_depth();

-  // var iterable = subject
-  VisitForAccumulatorValue(stmt->assign_iterable());
-  __ mov(a0, v0);
-
-  // As with for-in, skip the loop if the iterator is null or undefined.
-  __ LoadRoot(at, Heap::kUndefinedValueRootIndex);
-  __ Branch(loop_statement.break_label(), eq, a0, Operand(at));
-  __ LoadRoot(at, Heap::kNullValueRootIndex);
-  __ Branch(loop_statement.break_label(), eq, a0, Operand(at));
-
   // var iterator = iterable[Symbol.iterator]();
   VisitForEffect(stmt->assign_iterator());

=======================================
--- /branches/bleeding_edge/src/mips64/full-codegen-mips64.cc Wed Jul 23 09:35:06 2014 UTC +++ /branches/bleeding_edge/src/mips64/full-codegen-mips64.cc Thu Jul 24 13:40:08 2014 UTC
@@ -1267,16 +1267,6 @@
   Iteration loop_statement(this, stmt);
   increment_loop_depth();

-  // var iterable = subject
-  VisitForAccumulatorValue(stmt->assign_iterable());
-  __ mov(a0, v0);
-
-  // As with for-in, skip the loop if the iterator is null or undefined.
-  __ LoadRoot(at, Heap::kUndefinedValueRootIndex);
-  __ Branch(loop_statement.break_label(), eq, a0, Operand(at));
-  __ LoadRoot(at, Heap::kNullValueRootIndex);
-  __ Branch(loop_statement.break_label(), eq, a0, Operand(at));
-
   // var iterator = iterable[Symbol.iterator]();
   VisitForEffect(stmt->assign_iterator());

=======================================
--- /branches/bleeding_edge/src/parser.cc       Mon Jul 21 09:58:01 2014 UTC
+++ /branches/bleeding_edge/src/parser.cc       Thu Jul 24 13:40:08 2014 UTC
@@ -2749,37 +2749,26 @@
   ForOfStatement* for_of = stmt->AsForOfStatement();

   if (for_of != NULL) {
-    Variable* iterable = scope_->DeclarationScope()->NewTemporary(
-        ast_value_factory_->dot_iterable_string());
     Variable* iterator = scope_->DeclarationScope()->NewTemporary(
         ast_value_factory_->dot_iterator_string());
     Variable* result = scope_->DeclarationScope()->NewTemporary(
         ast_value_factory_->dot_result_string());

-    Expression* assign_iterable;
     Expression* assign_iterator;
     Expression* next_result;
     Expression* result_done;
     Expression* assign_each;

-    // var iterable = subject;
-    {
-      Expression* iterable_proxy = factory()->NewVariableProxy(iterable);
-      assign_iterable = factory()->NewAssignment(
-          Token::ASSIGN, iterable_proxy, subject, subject->position());
-    }
-
-    // var iterator = iterable[Symbol.iterator]();
+    // var iterator = subject[Symbol.iterator]();
     {
-      Expression* iterable_proxy = factory()->NewVariableProxy(iterable);
       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(
-          iterable_proxy, iterator_symbol_literal, pos);
+      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(
@@ -2826,7 +2815,6 @@
     }

     for_of->Initialize(each, subject, body,
-                       assign_iterable,
                        assign_iterator,
                        next_result,
                        result_done,
=======================================
--- /branches/bleeding_edge/src/x64/full-codegen-x64.cc Wed Jul 23 09:35:06 2014 UTC +++ /branches/bleeding_edge/src/x64/full-codegen-x64.cc Thu Jul 24 13:40:08 2014 UTC
@@ -1241,15 +1241,6 @@
   Iteration loop_statement(this, stmt);
   increment_loop_depth();

-  // var iterable = subject
-  VisitForAccumulatorValue(stmt->assign_iterable());
-
-  // As with for-in, skip the loop if the iterable is null or undefined.
-  __ CompareRoot(rax, Heap::kUndefinedValueRootIndex);
-  __ j(equal, loop_statement.break_label());
-  __ CompareRoot(rax, Heap::kNullValueRootIndex);
-  __ j(equal, loop_statement.break_label());
-
   // var iterator = iterable[Symbol.iterator]();
   VisitForEffect(stmt->assign_iterator());

=======================================
--- /branches/bleeding_edge/src/x87/full-codegen-x87.cc Wed Jul 23 09:35:06 2014 UTC +++ /branches/bleeding_edge/src/x87/full-codegen-x87.cc Thu Jul 24 13:40:08 2014 UTC
@@ -1204,15 +1204,6 @@
   Iteration loop_statement(this, stmt);
   increment_loop_depth();

-  // var iterable = subject
-  VisitForAccumulatorValue(stmt->assign_iterable());
-
-  // As with for-in, skip the loop if the iterator is null or undefined.
-  __ CompareRoot(eax, Heap::kUndefinedValueRootIndex);
-  __ j(equal, loop_statement.break_label());
-  __ CompareRoot(eax, Heap::kNullValueRootIndex);
-  __ j(equal, loop_statement.break_label());
-
   // var iterator = iterable[Symbol.iterator]();
   VisitForEffect(stmt->assign_iterator());

=======================================
--- /branches/bleeding_edge/test/mjsunit/harmony/iteration-semantics.js Wed Jun 25 07:43:14 2014 UTC +++ /branches/bleeding_edge/test/mjsunit/harmony/iteration-semantics.js Thu Jul 24 13:40:08 2014 UTC
@@ -213,9 +213,9 @@
                            { value: 37, done: true },
never_getter(never_getter({}, 'done'), 'value')])));

-// Null and undefined do not cause an error.
-assertEquals(0, fold(sum, 0, unreachable(null)));
-assertEquals(0, fold(sum, 0, unreachable(undefined)));
+// Unlike the case with for-in, null and undefined cause an error.
+assertThrows('fold(sum, 0, unreachable(null))', TypeError);
+assertThrows('fold(sum, 0, unreachable(undefined))', TypeError);

 // Other non-iterators do cause an error.
 assertThrows('fold(sum, 0, unreachable({}))', TypeError);

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