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 {
void IncrementNodeCount() { properties_.add_node_count(1); }
void DisableCrankshaft(BailoutReason reason) {
dont_crankshaft_reason_ = reason;
properties_.flags()->Add(kDontSelfOptimize);
DisableSelfOptimization();
}
// 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.
void DisableTurbofan(BailoutReason reason) {
dont_crankshaft_reason_ = reason;
......@@ -390,7 +390,7 @@ void AstNumberingVisitor::VisitForInStatement(ForInStatement* node) {
void AstNumberingVisitor::VisitForOfStatement(ForOfStatement* node) {
IncrementNodeCount();
DisableTurbofan(kForOfStatement);
DisableCrankshaft(kForOfStatement);
node->set_base_id(ReserveIdRange(ForOfStatement::num_ids()));
Visit(node->assign_iterator());
Visit(node->next_result());
......
......@@ -789,9 +789,17 @@ void AstGraphBuilder::VisitForInStatement(ForInStatement* stmt) {
void AstGraphBuilder::VisitForOfStatement(ForOfStatement* stmt) {
VisitForValue(stmt->subject());
environment()->Pop();
// TODO(turbofan): create and use loop builder.
LoopBuilder for_loop(this);
VisitForEffect(stmt->assign_iterator());
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) {
}
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() {
body_environment_ = environment()->CopyAsUnreachable();
label_environment_ = environment()->CopyAsUnreachable();
......
......@@ -77,8 +77,9 @@ class LoopBuilder FINAL : public ControlBuilder {
void Continue() FINAL;
void Break() FINAL;
// Compound control command for conditional break.
// Compound control commands for conditional break.
void BreakUnless(Node* condition);
void BreakWhen(Node* condition);
private:
Environment* loop_environment_; // Environment of the loop header.
......
......@@ -760,11 +760,9 @@ void Pipeline::RunPrintAndVerify(const char* phase, bool untyped) {
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 ||
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.
info()->function()->dont_optimize_reason() == kSuperReference ||
// TODO(turbofan): Make class literals work and remove this bailout.
......
......@@ -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) {
const char* src =
"(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