Revision: 3199 Author: [email protected] Date: Mon Nov 2 06:12:48 2009 Log: Add support for for loops to the toplevel code generator.
Review URL: http://codereview.chromium.org/340059 http://code.google.com/p/v8/source/detail?r=3199 Added: /branches/bleeding_edge/test/mjsunit/compiler/loops.js Modified: /branches/bleeding_edge/src/compiler.cc /branches/bleeding_edge/src/fast-codegen.cc ======================================= --- /dev/null +++ /branches/bleeding_edge/test/mjsunit/compiler/loops.js Mon Nov 2 06:12:48 2009 @@ -0,0 +1,35 @@ +// Copyright 2009 the V8 project authors. All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Test compilation of loops. + +var n = 1; +for (var i = 1; (6 - i); i++) { + // Factorial! + n = n * i; +} +assertEquals(120, n); ======================================= --- /branches/bleeding_edge/src/compiler.cc Mon Nov 2 05:30:24 2009 +++ /branches/bleeding_edge/src/compiler.cc Mon Nov 2 06:12:48 2009 @@ -587,7 +587,21 @@ void CodeGenSelector::VisitForStatement(ForStatement* stmt) { - BAILOUT("ForStatement"); + // We do not handle loops with breaks or continue statements in their + // body. We will bailout when we hit those statements in the body. + if (stmt->init() != NULL) { + Visit(stmt->init()); + CHECK_BAILOUT; + } + if (stmt->cond() != NULL) { + ProcessExpression(stmt->cond(), Expression::kTest); + CHECK_BAILOUT; + } + Visit(stmt->body()); + if (stmt->next() != NULL) { + CHECK_BAILOUT; + Visit(stmt->next()); + } } ======================================= --- /branches/bleeding_edge/src/fast-codegen.cc Mon Nov 2 05:30:24 2009 +++ /branches/bleeding_edge/src/fast-codegen.cc Mon Nov 2 06:12:48 2009 @@ -298,6 +298,7 @@ // Do not worry about optimizing for empty then or else bodies. true_label_ = &then_part; false_label_ = &else_part; + ASSERT(stmt->condition()->context() == Expression::kTest); Visit(stmt->condition()); true_label_ = NULL; false_label_ = NULL; @@ -349,7 +350,33 @@ void FastCodeGenerator::VisitForStatement(ForStatement* stmt) { - UNREACHABLE(); + Label test, body, exit; + if (stmt->init() != NULL) Visit(stmt->init()); + + // Emit the test at the bottom of the loop (even if empty). + __ jmp(&test); + __ bind(&body); + Visit(stmt->body()); + if (stmt->next() != NULL) Visit(stmt->next()); + + __ bind(&test); + if (stmt->cond() == NULL) { + // For an empty test jump to the top of the loop. + __ jmp(&body); + } else { + // We are not in an expression context because we have been compiling + // statements. Set up a test expression context for the condition. + ASSERT_EQ(NULL, true_label_); + ASSERT_EQ(NULL, false_label_); + true_label_ = &body; + false_label_ = &exit; + ASSERT(stmt->cond()->context() == Expression::kTest); + Visit(stmt->cond()); + true_label_ = NULL; + false_label_ = NULL; + } + + __ bind(&exit); } --~--~---------~--~----~------------~-------~--~----~ v8-dev mailing list [email protected] http://groups.google.com/group/v8-dev -~----------~----~----~----~------~----~------~--~---
