Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/rewriter.h" | 5 #include "src/rewriter.h" |
| 6 | 6 |
| 7 #include "src/ast.h" | 7 #include "src/ast.h" |
| 8 #include "src/parser.h" | 8 #include "src/parser.h" |
| 9 #include "src/scopes.h" | 9 #include "src/scopes.h" |
| 10 | 10 |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 42 bool is_set_; | 42 bool is_set_; |
| 43 | 43 |
| 44 AstNodeFactory factory_; | 44 AstNodeFactory factory_; |
| 45 | 45 |
| 46 Expression* SetResult(Expression* value) { | 46 Expression* SetResult(Expression* value) { |
| 47 VariableProxy* result_proxy = factory()->NewVariableProxy(result_); | 47 VariableProxy* result_proxy = factory()->NewVariableProxy(result_); |
| 48 return factory()->NewAssignment( | 48 return factory()->NewAssignment( |
| 49 Token::ASSIGN, result_proxy, value, RelocInfo::kNoPosition); | 49 Token::ASSIGN, result_proxy, value, RelocInfo::kNoPosition); |
| 50 } | 50 } |
| 51 | 51 |
| 52 // Inserts '.result = undefined' in front of the given statement. | |
| 53 Statement* AssignUndefinedBefore(Statement* s); | |
| 54 | |
| 52 // Node visitors. | 55 // Node visitors. |
| 53 #define DEF_VISIT(type) virtual void Visit##type(type* node) override; | 56 #define DEF_VISIT(type) virtual void Visit##type(type* node) override; |
| 54 AST_NODE_LIST(DEF_VISIT) | 57 AST_NODE_LIST(DEF_VISIT) |
| 55 #undef DEF_VISIT | 58 #undef DEF_VISIT |
| 56 | 59 |
| 57 void VisitIterationStatement(IterationStatement* stmt); | 60 void VisitIterationStatement(IterationStatement* stmt); |
| 58 | 61 |
| 59 DEFINE_AST_VISITOR_SUBCLASS_MEMBERS(); | 62 DEFINE_AST_VISITOR_SUBCLASS_MEMBERS(); |
| 60 }; | 63 }; |
| 61 | 64 |
| 62 | 65 |
| 66 Statement* Processor::AssignUndefinedBefore(Statement* s) { | |
| 67 Expression* result_proxy = factory()->NewVariableProxy(result_); | |
| 68 Expression* undef = factory()->NewUndefinedLiteral(RelocInfo::kNoPosition); | |
| 69 Expression* assignment = factory()->NewAssignment( | |
| 70 Token::ASSIGN, result_proxy, undef, RelocInfo::kNoPosition); | |
| 71 Block* b = factory()->NewBlock(NULL, 2, false, RelocInfo::kNoPosition); | |
| 72 b->AddStatement( | |
| 73 factory()->NewExpressionStatement(assignment, RelocInfo::kNoPosition), | |
| 74 zone()); | |
| 75 b->AddStatement(s, zone()); | |
| 76 return b; | |
| 77 } | |
| 78 | |
| 79 | |
| 63 void Processor::Process(ZoneList<Statement*>* statements) { | 80 void Processor::Process(ZoneList<Statement*>* statements) { |
| 64 for (int i = statements->length() - 1; i >= 0; --i) { | 81 for (int i = statements->length() - 1; i >= 0; --i) { |
| 65 Visit(statements->at(i)); | 82 Visit(statements->at(i)); |
| 66 statements->Set(i, replacement_); | 83 statements->Set(i, replacement_); |
| 67 } | 84 } |
| 68 } | 85 } |
| 69 | 86 |
| 70 | 87 |
| 71 void Processor::VisitBlock(Block* node) { | 88 void Processor::VisitBlock(Block* node) { |
| 72 // An initializer block is the rewritten form of a variable declaration | 89 // An initializer block is the rewritten form of a variable declaration |
| (...skipping 23 matching lines...) Expand all Loading... | |
| 96 // Rewrite both branches. | 113 // Rewrite both branches. |
| 97 bool set_after = is_set_; | 114 bool set_after = is_set_; |
| 98 Visit(node->then_statement()); | 115 Visit(node->then_statement()); |
| 99 node->set_then_statement(replacement_); | 116 node->set_then_statement(replacement_); |
| 100 bool set_in_then = is_set_; | 117 bool set_in_then = is_set_; |
| 101 is_set_ = set_after; | 118 is_set_ = set_after; |
| 102 Visit(node->else_statement()); | 119 Visit(node->else_statement()); |
| 103 node->set_else_statement(replacement_); | 120 node->set_else_statement(replacement_); |
| 104 is_set_ = is_set_ && set_in_then; | 121 is_set_ = is_set_ && set_in_then; |
| 105 replacement_ = node; | 122 replacement_ = node; |
| 123 | |
| 124 if (FLAG_harmony_completion && !is_set_) { | |
| 125 is_set_ = true; | |
|
rossberg
2015/09/28 14:09:22
Why not move this into AssignUndefinedBeforeNode?
neis
2015/10/05 10:57:28
I prefer the is_set_ logic to be explicit in the V
| |
| 126 replacement_ = AssignUndefinedBefore(node); | |
| 127 } | |
| 106 } | 128 } |
| 107 | 129 |
| 108 | 130 |
| 109 void Processor::VisitIterationStatement(IterationStatement* node) { | 131 void Processor::VisitIterationStatement(IterationStatement* node) { |
| 110 // Rewrite the body. | 132 // Rewrite the body. |
| 111 bool set_after = is_set_; | 133 bool set_after = is_set_; |
| 112 is_set_ = false; // We are in a loop, so we can't rely on [set_after]. | 134 is_set_ = false; // We are in a loop, so we can't rely on [set_after]. |
| 113 Visit(node->body()); | 135 Visit(node->body()); |
| 114 node->set_body(replacement_); | 136 node->set_body(replacement_); |
| 115 is_set_ = is_set_ && set_after; | 137 is_set_ = is_set_ && set_after; |
| 116 replacement_ = node; | 138 replacement_ = node; |
| 139 | |
| 140 if (FLAG_harmony_completion && !is_set_) { | |
| 141 is_set_ = true; | |
| 142 replacement_ = AssignUndefinedBefore(node); | |
| 143 } | |
| 117 } | 144 } |
| 118 | 145 |
| 119 | 146 |
| 120 void Processor::VisitDoWhileStatement(DoWhileStatement* node) { | 147 void Processor::VisitDoWhileStatement(DoWhileStatement* node) { |
| 121 VisitIterationStatement(node); | 148 VisitIterationStatement(node); |
| 122 } | 149 } |
| 123 | 150 |
| 124 | 151 |
| 125 void Processor::VisitWhileStatement(WhileStatement* node) { | 152 void Processor::VisitWhileStatement(WhileStatement* node) { |
| 126 VisitIterationStatement(node); | 153 VisitIterationStatement(node); |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 146 // Rewrite both try and catch block. | 173 // Rewrite both try and catch block. |
| 147 bool set_after = is_set_; | 174 bool set_after = is_set_; |
| 148 Visit(node->try_block()); | 175 Visit(node->try_block()); |
| 149 node->set_try_block(static_cast<Block*>(replacement_)); | 176 node->set_try_block(static_cast<Block*>(replacement_)); |
| 150 bool set_in_try = is_set_; | 177 bool set_in_try = is_set_; |
| 151 is_set_ = set_after; | 178 is_set_ = set_after; |
| 152 Visit(node->catch_block()); | 179 Visit(node->catch_block()); |
| 153 node->set_catch_block(static_cast<Block*>(replacement_)); | 180 node->set_catch_block(static_cast<Block*>(replacement_)); |
| 154 is_set_ = is_set_ && set_in_try; | 181 is_set_ = is_set_ && set_in_try; |
| 155 replacement_ = node; | 182 replacement_ = node; |
| 183 | |
| 184 if (FLAG_harmony_completion && !is_set_) { | |
| 185 is_set_ = true; | |
| 186 replacement_ = AssignUndefinedBefore(node); | |
| 187 } | |
| 156 } | 188 } |
| 157 | 189 |
| 158 | 190 |
| 159 void Processor::VisitTryFinallyStatement(TryFinallyStatement* node) { | 191 void Processor::VisitTryFinallyStatement(TryFinallyStatement* node) { |
| 160 // Rewrite both try and finally block (in reverse order). | 192 // Rewrite both try and finally block (in reverse order). |
| 161 Visit(node->finally_block()); | 193 Visit(node->finally_block()); |
| 162 node->set_finally_block(static_cast<Block*>(replacement_)); | 194 node->set_finally_block(static_cast<Block*>(replacement_)); |
| 163 Visit(node->try_block()); // Exception will not be caught. | 195 Visit(node->try_block()); // Exception will not be caught. |
| 164 node->set_try_block(static_cast<Block*>(replacement_)); | 196 node->set_try_block(static_cast<Block*>(replacement_)); |
| 165 replacement_ = node; | 197 replacement_ = node; |
| 198 | |
| 199 if (FLAG_harmony_completion && !is_set_) { | |
| 200 is_set_ = true; | |
| 201 replacement_ = AssignUndefinedBefore(node); | |
| 202 } | |
| 166 } | 203 } |
| 167 | 204 |
| 168 | 205 |
| 169 void Processor::VisitSwitchStatement(SwitchStatement* node) { | 206 void Processor::VisitSwitchStatement(SwitchStatement* node) { |
| 170 // Rewrite statements in all case clauses (in reverse order). | 207 // Rewrite statements in all case clauses (in reverse order). |
| 171 ZoneList<CaseClause*>* clauses = node->cases(); | 208 ZoneList<CaseClause*>* clauses = node->cases(); |
| 172 bool set_after = is_set_; | 209 bool set_after = is_set_; |
| 173 for (int i = clauses->length() - 1; i >= 0; --i) { | 210 for (int i = clauses->length() - 1; i >= 0; --i) { |
| 174 CaseClause* clause = clauses->at(i); | 211 CaseClause* clause = clauses->at(i); |
| 175 Process(clause->statements()); | 212 Process(clause->statements()); |
| 176 } | 213 } |
| 177 is_set_ = is_set_ && set_after; | 214 is_set_ = is_set_ && set_after; |
| 178 replacement_ = node; | 215 replacement_ = node; |
| 216 | |
| 217 if (FLAG_harmony_completion && !is_set_) { | |
| 218 is_set_ = true; | |
| 219 replacement_ = AssignUndefinedBefore(node); | |
| 220 } | |
| 179 } | 221 } |
| 180 | 222 |
| 181 | 223 |
| 182 void Processor::VisitContinueStatement(ContinueStatement* node) { | 224 void Processor::VisitContinueStatement(ContinueStatement* node) { |
| 183 is_set_ = false; | 225 is_set_ = false; |
| 184 replacement_ = node; | 226 replacement_ = node; |
| 185 } | 227 } |
| 186 | 228 |
| 187 | 229 |
| 188 void Processor::VisitBreakStatement(BreakStatement* node) { | 230 void Processor::VisitBreakStatement(BreakStatement* node) { |
| 189 is_set_ = false; | 231 is_set_ = false; |
| 190 replacement_ = node; | 232 replacement_ = node; |
| 191 } | 233 } |
| 192 | 234 |
| 193 | 235 |
| 194 void Processor::VisitWithStatement(WithStatement* node) { | 236 void Processor::VisitWithStatement(WithStatement* node) { |
| 195 Visit(node->statement()); | 237 Visit(node->statement()); |
| 196 node->set_statement(replacement_); | 238 node->set_statement(replacement_); |
| 197 replacement_ = node; | 239 replacement_ = node; |
| 240 | |
| 241 if (FLAG_harmony_completion && !is_set_) { | |
| 242 is_set_ = true; | |
| 243 replacement_ = AssignUndefinedBefore(node); | |
| 244 } | |
| 198 } | 245 } |
| 199 | 246 |
| 200 | 247 |
| 201 void Processor::VisitSloppyBlockFunctionStatement( | 248 void Processor::VisitSloppyBlockFunctionStatement( |
| 202 SloppyBlockFunctionStatement* node) { | 249 SloppyBlockFunctionStatement* node) { |
| 203 Visit(node->statement()); | 250 Visit(node->statement()); |
| 204 node->set_statement(replacement_); | 251 node->set_statement(replacement_); |
| 205 replacement_ = node; | 252 replacement_ = node; |
| 206 } | 253 } |
| 207 | 254 |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 269 processor.factory()->NewReturnStatement(result_proxy, pos); | 316 processor.factory()->NewReturnStatement(result_proxy, pos); |
| 270 body->Add(result_statement, info->zone()); | 317 body->Add(result_statement, info->zone()); |
| 271 } | 318 } |
| 272 | 319 |
| 273 return true; | 320 return true; |
| 274 } | 321 } |
| 275 | 322 |
| 276 | 323 |
| 277 } // namespace internal | 324 } // namespace internal |
| 278 } // namespace v8 | 325 } // namespace v8 |
| OLD | NEW |