1b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org// Copyright 2012 the V8 project authors. All rights reserved.
243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Redistribution and use in source and binary forms, with or without
343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// modification, are permitted provided that the following conditions are
443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// met:
543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen//
643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen//     * Redistributions of source code must retain the above copyright
743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen//       notice, this list of conditions and the following disclaimer.
843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen//     * Redistributions in binary form must reproduce the above
943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen//       copyright notice, this list of conditions and the following
1043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen//       disclaimer in the documentation and/or other materials provided
1143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen//       with the distribution.
1243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen//     * Neither the name of Google Inc. nor the names of its
1343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen//       contributors may be used to endorse or promote products derived
1443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen//       from this software without specific prior written permission.
1543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen//
1643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
1743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
1843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
1943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
2243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
2843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#include "v8.h"
2943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
30b61a0d13e9690ef4c2de424bbe82a38884d981a6ager@chromium.org#include "rewriter.h"
31b61a0d13e9690ef4c2de424bbe82a38884d981a6ager@chromium.org
3243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#include "ast.h"
33b61a0d13e9690ef4c2de424bbe82a38884d981a6ager@chromium.org#include "compiler.h"
3443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#include "scopes.h"
3543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
3671affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.orgnamespace v8 {
3771affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.orgnamespace internal {
3843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
39a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.orgclass Processor: public AstVisitor {
4043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen public:
415a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  Processor(Variable* result, Zone* zone)
4243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      : result_(result),
4343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen        result_assigned_(false),
4443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen        is_set_(false),
45b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org        in_try_(false),
468fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org        factory_(zone->isolate(), zone) {
478fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org    InitializeAstVisitor(zone->isolate());
48a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  }
49b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org
50b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org  virtual ~Processor() { }
5143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
5243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void Process(ZoneList<Statement*>* statements);
534a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org  bool result_assigned() const { return result_assigned_; }
5443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
55b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org  AstNodeFactory<AstNullVisitor>* factory() {
56b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org    return &factory_;
57b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org  }
58b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org
5943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen private:
60a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  Variable* result_;
6143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
6243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // We are not tracking result usage via the result_'s use
6343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // counts (we leave the accurate computation to the
6443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // usage analyzer). Instead we simple remember if
6543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // there was ever an assignment to result_.
6643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  bool result_assigned_;
6743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
6843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // To avoid storing to .result all the time, we eliminate some of
6943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // the stores by keeping track of whether or not we're sure .result
7043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // will be overwritten anyway. This is a bit more tricky than what I
7143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // was hoping for
7243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  bool is_set_;
7343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  bool in_try_;
7443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
75b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org  AstNodeFactory<AstNullVisitor> factory_;
76b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org
7743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Expression* SetResult(Expression* value) {
7843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    result_assigned_ = true;
79b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org    VariableProxy* result_proxy = factory()->NewVariableProxy(result_);
80b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org    return factory()->NewAssignment(
81b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org        Token::ASSIGN, result_proxy, value, RelocInfo::kNoPosition);
8243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
8343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
8443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Node visitors.
8543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#define DEF_VISIT(type) \
8643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  virtual void Visit##type(type* node);
870b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org  AST_NODE_LIST(DEF_VISIT)
8843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#undef DEF_VISIT
899d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com
909d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com  void VisitIterationStatement(IterationStatement* stmt);
91a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org
92a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  DEFINE_AST_VISITOR_SUBCLASS_MEMBERS();
9343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen};
9443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
9543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
9643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Processor::Process(ZoneList<Statement*>* statements) {
9743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  for (int i = statements->length() - 1; i >= 0; --i) {
9843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    Visit(statements->at(i));
9943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
10043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
10143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
10243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
10343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Processor::VisitBlock(Block* node) {
10443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // An initializer block is the rewritten form of a variable declaration
10543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // with initialization expressions. The initializer block contains the
10643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // list of assignments corresponding to the initialization expressions.
10743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // While unclear from the spec (ECMA-262, 3rd., 12.2), the value of
10843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // a variable declaration with initialization expression is 'undefined'
10943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // with some JS VMs: For instance, using smjs, print(eval('var x = 7'))
11043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // returns 'undefined'. To obtain the same behavior with v8, we need
11143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // to prevent rewriting in that case.
11243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (!node->is_initializer_block()) Process(node->statements());
11343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
11443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
11543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1168e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.orgvoid Processor::VisitModuleStatement(ModuleStatement* node) {
1178e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  bool set_after_body = is_set_;
1188e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  Visit(node->body());
1198e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  is_set_ = is_set_ && set_after_body;
1208e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org}
1218e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org
1228e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org
12343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Processor::VisitExpressionStatement(ExpressionStatement* node) {
12443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Rewrite : <x>; -> .result = <x>;
1257d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org  if (!is_set_ && !node->expression()->IsThrow()) {
12643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    node->set_expression(SetResult(node->expression()));
12743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    if (!in_try_) is_set_ = true;
12843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
12943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
13043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
13143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
13243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Processor::VisitIfStatement(IfStatement* node) {
13343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Rewrite both then and else parts (reversed).
13443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  bool save = is_set_;
13543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Visit(node->else_statement());
13643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  bool set_after_then = is_set_;
13743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  is_set_ = save;
13843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Visit(node->then_statement());
13943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  is_set_ = is_set_ && set_after_then;
14043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
14143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
14243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1439d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.comvoid Processor::VisitIterationStatement(IterationStatement* node) {
1449d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com  // Rewrite the body.
14543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  bool set_after_loop = is_set_;
14643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Visit(node->body());
14743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  is_set_ = is_set_ && set_after_loop;
14843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
14943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
15043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1519d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.comvoid Processor::VisitDoWhileStatement(DoWhileStatement* node) {
1529d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com  VisitIterationStatement(node);
1539d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com}
1549d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com
1559d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com
1569d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.comvoid Processor::VisitWhileStatement(WhileStatement* node) {
1579d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com  VisitIterationStatement(node);
1589d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com}
1599d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com
1609d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com
1619d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.comvoid Processor::VisitForStatement(ForStatement* node) {
1629d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com  VisitIterationStatement(node);
1639d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com}
1649d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com
1659d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com
16643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Processor::VisitForInStatement(ForInStatement* node) {
1679d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com  VisitIterationStatement(node);
16843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
16943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
17043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1711fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.orgvoid Processor::VisitForOfStatement(ForOfStatement* node) {
1721fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org  VisitIterationStatement(node);
1731fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org}
1741fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org
1751fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org
1769d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.comvoid Processor::VisitTryCatchStatement(TryCatchStatement* node) {
17743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Rewrite both try and catch blocks (reversed order).
17843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  bool set_after_catch = is_set_;
17943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Visit(node->catch_block());
18043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  is_set_ = is_set_ && set_after_catch;
18143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  bool save = in_try_;
18243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  in_try_ = true;
18343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Visit(node->try_block());
18443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  in_try_ = save;
18543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
18643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
18743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1889d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.comvoid Processor::VisitTryFinallyStatement(TryFinallyStatement* node) {
18943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Rewrite both try and finally block (reversed order).
19043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Visit(node->finally_block());
19143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  bool save = in_try_;
19243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  in_try_ = true;
19343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Visit(node->try_block());
19443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  in_try_ = save;
19543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
19643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
19743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
19843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Processor::VisitSwitchStatement(SwitchStatement* node) {
19943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Rewrite statements in all case clauses in reversed order.
20043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ZoneList<CaseClause*>* clauses = node->cases();
20143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  bool set_after_switch = is_set_;
20243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  for (int i = clauses->length() - 1; i >= 0; --i) {
20343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    CaseClause* clause = clauses->at(i);
20443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    Process(clause->statements());
20543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
20643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  is_set_ = is_set_ && set_after_switch;
20743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
20843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
20943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
210a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.orgvoid Processor::VisitCaseClause(CaseClause* clause) {
211a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org  UNREACHABLE();
212a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org}
213a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org
214a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org
21543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Processor::VisitContinueStatement(ContinueStatement* node) {
21643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  is_set_ = false;
21743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
21843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
21943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
22043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Processor::VisitBreakStatement(BreakStatement* node) {
22143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  is_set_ = false;
22243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
22343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
22443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
2254acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.orgvoid Processor::VisitWithStatement(WithStatement* node) {
2264acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org  bool set_after_body = is_set_;
2274acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org  Visit(node->statement());
2284acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org  is_set_ = is_set_ && set_after_body;
2294acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org}
2304acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org
2314acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org
23243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Do nothing:
23378d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.orgvoid Processor::VisitVariableDeclaration(VariableDeclaration* node) {}
234812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.orgvoid Processor::VisitFunctionDeclaration(FunctionDeclaration* node) {}
23578d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.orgvoid Processor::VisitModuleDeclaration(ModuleDeclaration* node) {}
236812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.orgvoid Processor::VisitImportDeclaration(ImportDeclaration* node) {}
237812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.orgvoid Processor::VisitExportDeclaration(ExportDeclaration* node) {}
23878d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.orgvoid Processor::VisitModuleLiteral(ModuleLiteral* node) {}
23978d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.orgvoid Processor::VisitModuleVariable(ModuleVariable* node) {}
24078d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.orgvoid Processor::VisitModulePath(ModulePath* node) {}
24178d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.orgvoid Processor::VisitModuleUrl(ModuleUrl* node) {}
24243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Processor::VisitEmptyStatement(EmptyStatement* node) {}
24343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Processor::VisitReturnStatement(ReturnStatement* node) {}
24443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Processor::VisitDebuggerStatement(DebuggerStatement* node) {}
24543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
24643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
24743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Expressions are never visited yet.
2486d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org#define DEF_VISIT(type)                                         \
2496d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  void Processor::Visit##type(type* expr) { UNREACHABLE(); }
2506d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.orgEXPRESSION_NODE_LIST(DEF_VISIT)
2516d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org#undef DEF_VISIT
25243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
25343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
254355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org// Assumes code has been parsed.  Mutates the AST, so the AST should not
255355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org// continue to be used in the case of failure.
256b61a0d13e9690ef4c2de424bbe82a38884d981a6ager@chromium.orgbool Rewriter::Rewrite(CompilationInfo* info) {
257b61a0d13e9690ef4c2de424bbe82a38884d981a6ager@chromium.org  FunctionLiteral* function = info->function();
258b61a0d13e9690ef4c2de424bbe82a38884d981a6ager@chromium.org  ASSERT(function != NULL);
25943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Scope* scope = function->scope();
260b61a0d13e9690ef4c2de424bbe82a38884d981a6ager@chromium.org  ASSERT(scope != NULL);
2614f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  if (!scope->is_global_scope() && !scope->is_eval_scope()) return true;
26243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
26343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ZoneList<Statement*>* body = function->body();
264b61a0d13e9690ef4c2de424bbe82a38884d981a6ager@chromium.org  if (!body->is_empty()) {
265ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    Variable* result = scope->NewTemporary(
266e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org        info->isolate()->factory()->dot_result_string());
2675a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org    Processor processor(result, info->zone());
268b61a0d13e9690ef4c2de424bbe82a38884d981a6ager@chromium.org    processor.Process(body);
269b61a0d13e9690ef4c2de424bbe82a38884d981a6ager@chromium.org    if (processor.HasStackOverflow()) return false;
27043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
271a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    if (processor.result_assigned()) {
2721b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org      ASSERT(function->end_position() != RelocInfo::kNoPosition);
2731b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org      // Set the position of the assignment statement one character past the
2741b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org      // source code, such that it definitely is not in the source code range
2751b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org      // of an immediate inner scope. For example in
2761b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org      //   eval('with ({x:1}) x = 1');
2771b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org      // the end position of the function generated for executing the eval code
2781b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org      // coincides with the end of the with scope which is the position of '1'.
279a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org      int pos = function->end_position();
280b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org      VariableProxy* result_proxy = processor.factory()->NewVariableProxy(
281a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org          result->name(), false, result->interface(), pos);
2821b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org      result_proxy->BindTo(result);
283b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org      Statement* result_statement =
284a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org          processor.factory()->NewReturnStatement(result_proxy, pos);
2855a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org      body->Add(result_statement, info->zone());
286a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    }
287b61a0d13e9690ef4c2de424bbe82a38884d981a6ager@chromium.org  }
28843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
28943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return true;
29043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
29143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
29243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
29343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} }  // namespace v8::internal
294