Commit 2ebe24c9 authored by mstarzinger's avatar mstarzinger Committed by Commit bot

First simple implementation of for-of in TurboFan.

R=rossberg@chromium.org
TEST=cctest/test-run-jsbranches/ForOfContinueStatement

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

Cr-Commit-Position: refs/heads/master@{#26060}
parent 6586bd19
...@@ -47,10 +47,10 @@ class AstNumberingVisitor FINAL : public AstVisitor { ...@@ -47,10 +47,10 @@ class AstNumberingVisitor FINAL : public AstVisitor {
void IncrementNodeCount() { properties_.add_node_count(1); } void IncrementNodeCount() { properties_.add_node_count(1); }
void DisableCrankshaft(BailoutReason reason) { void DisableCrankshaft(BailoutReason reason) {
dont_crankshaft_reason_ = reason; dont_crankshaft_reason_ = reason;
properties_.flags()->Add(kDontSelfOptimize); DisableSelfOptimization();
} }
// TODO(turbofan): Remove the dont_turbofan_reason once no nodes are // TODO(turbofan): Remove the dont_turbofan_reason once no nodes are
// DontTurbofanNode. That set of nodes must be kept in sync with // DisableTurbofan. That set of nodes must be kept in sync with
// Pipeline::GenerateCode. // Pipeline::GenerateCode.
void DisableTurbofan(BailoutReason reason) { void DisableTurbofan(BailoutReason reason) {
dont_crankshaft_reason_ = reason; dont_crankshaft_reason_ = reason;
...@@ -390,7 +390,7 @@ void AstNumberingVisitor::VisitForInStatement(ForInStatement* node) { ...@@ -390,7 +390,7 @@ void AstNumberingVisitor::VisitForInStatement(ForInStatement* node) {
void AstNumberingVisitor::VisitForOfStatement(ForOfStatement* node) { void AstNumberingVisitor::VisitForOfStatement(ForOfStatement* node) {
IncrementNodeCount(); IncrementNodeCount();
DisableTurbofan(kForOfStatement); DisableCrankshaft(kForOfStatement);
node->set_base_id(ReserveIdRange(ForOfStatement::num_ids())); node->set_base_id(ReserveIdRange(ForOfStatement::num_ids()));
Visit(node->assign_iterator()); Visit(node->assign_iterator());
Visit(node->next_result()); Visit(node->next_result());
......
...@@ -789,9 +789,17 @@ void AstGraphBuilder::VisitForInStatement(ForInStatement* stmt) { ...@@ -789,9 +789,17 @@ void AstGraphBuilder::VisitForInStatement(ForInStatement* stmt) {
void AstGraphBuilder::VisitForOfStatement(ForOfStatement* stmt) { void AstGraphBuilder::VisitForOfStatement(ForOfStatement* stmt) {
VisitForValue(stmt->subject()); LoopBuilder for_loop(this);
environment()->Pop(); VisitForEffect(stmt->assign_iterator());
// TODO(turbofan): create and use loop builder. for_loop.BeginLoop(GetVariablesAssignedInLoop(stmt), IsOsrLoopEntry(stmt));
VisitForEffect(stmt->next_result());
VisitForTest(stmt->result_done());
Node* condition = environment()->Pop();
for_loop.BreakWhen(condition);
VisitForEffect(stmt->assign_each());
VisitIterationBody(stmt, &for_loop, 0);
for_loop.EndBody();
for_loop.EndLoop();
} }
......
...@@ -73,6 +73,16 @@ void LoopBuilder::BreakUnless(Node* condition) { ...@@ -73,6 +73,16 @@ void LoopBuilder::BreakUnless(Node* condition) {
} }
void LoopBuilder::BreakWhen(Node* condition) {
IfBuilder control_if(builder_);
control_if.If(condition);
control_if.Then();
Break();
control_if.Else();
control_if.End();
}
void SwitchBuilder::BeginSwitch() { void SwitchBuilder::BeginSwitch() {
body_environment_ = environment()->CopyAsUnreachable(); body_environment_ = environment()->CopyAsUnreachable();
label_environment_ = environment()->CopyAsUnreachable(); label_environment_ = environment()->CopyAsUnreachable();
......
...@@ -77,8 +77,9 @@ class LoopBuilder FINAL : public ControlBuilder { ...@@ -77,8 +77,9 @@ class LoopBuilder FINAL : public ControlBuilder {
void Continue() FINAL; void Continue() FINAL;
void Break() FINAL; void Break() FINAL;
// Compound control command for conditional break. // Compound control commands for conditional break.
void BreakUnless(Node* condition); void BreakUnless(Node* condition);
void BreakWhen(Node* condition);
private: private:
Environment* loop_environment_; // Environment of the loop header. Environment* loop_environment_; // Environment of the loop header.
......
...@@ -760,11 +760,9 @@ void Pipeline::RunPrintAndVerify(const char* phase, bool untyped) { ...@@ -760,11 +760,9 @@ void Pipeline::RunPrintAndVerify(const char* phase, bool untyped) {
Handle<Code> Pipeline::GenerateCode() { Handle<Code> Pipeline::GenerateCode() {
// This list must be kept in sync with DONT_TURBOFAN_NODE in ast.cc. // This list must be kept in sync with DisableTurbofan in ast-numbering.cc.
if (info()->function()->dont_optimize_reason() == kTryCatchStatement || if (info()->function()->dont_optimize_reason() == kTryCatchStatement ||
info()->function()->dont_optimize_reason() == kTryFinallyStatement || info()->function()->dont_optimize_reason() == kTryFinallyStatement ||
// TODO(turbofan): Make ES6 for-of work and remove this bailout.
info()->function()->dont_optimize_reason() == kForOfStatement ||
// TODO(turbofan): Make super work and remove this bailout. // TODO(turbofan): Make super work and remove this bailout.
info()->function()->dont_optimize_reason() == kSuperReference || info()->function()->dont_optimize_reason() == kSuperReference ||
// TODO(turbofan): Make class literals work and remove this bailout. // TODO(turbofan): Make class literals work and remove this bailout.
......
...@@ -168,6 +168,33 @@ TEST(ForInContinueStatement) { ...@@ -168,6 +168,33 @@ TEST(ForInContinueStatement) {
} }
TEST(ForOfContinueStatement) {
const char* src =
"(function(a,b) {"
" var r = '-';"
" for (var x of a) {"
" r += x + '-';"
" if (b) continue;"
" r += 'X-';"
" }"
" return r;"
"})";
FunctionTester T(src);
CompileRun(
"function wrap(v) {"
" var iterable = {};"
" function next() { return { done:!v.length, value:v.shift() }; };"
" iterable[Symbol.iterator] = function() { return { next:next }; };"
" return iterable;"
"}");
T.CheckCall(T.Val("-"), T.NewObject("wrap([])"), T.true_value());
T.CheckCall(T.Val("-1-2-"), T.NewObject("wrap([1,2])"), T.true_value());
T.CheckCall(T.Val("-1-X-2-X-"), T.NewObject("wrap([1,2])"), T.false_value());
}
TEST(SwitchStatement) { TEST(SwitchStatement) {
const char* src = const char* src =
"(function(a,b) {" "(function(a,b) {"
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment