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