1 // Copyright 2015 the V8 project authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "src/ast/ast-expression-rewriter.h" 6 #include "src/ast/ast.h" 7 #include "src/objects-inl.h" 8 9 namespace v8 { 10 namespace internal { 11 12 // ---------------------------------------------------------------------------- 13 // Implementation of AstExpressionRewriter 14 // The AST is traversed but no actual rewriting takes place, unless the 15 // Visit methods are overriden in subclasses. 16 17 #define REWRITE_THIS(node) \ 18 do { \ 19 if (!RewriteExpression(node)) return; \ 20 } while (false) 21 #define NOTHING() DCHECK_NULL(replacement_) 22 23 void AstExpressionRewriter::VisitDeclarations(Declaration::List* declarations) { 24 for (Declaration::List::Iterator it = declarations->begin(); 25 it != declarations->end(); ++it) { 26 AST_REWRITE(Declaration, *it, it = replacement); 27 } 28 } 29 30 31 void AstExpressionRewriter::VisitStatements(ZoneList<Statement*>* statements) { 32 for (int i = 0; i < statements->length(); i++) { 33 AST_REWRITE_LIST_ELEMENT(Statement, statements, i); 34 // Not stopping when a jump statement is found. 35 } 36 } 37 38 39 void AstExpressionRewriter::VisitExpressions( 40 ZoneList<Expression*>* expressions) { 41 for (int i = 0; i < expressions->length(); i++) { 42 // The variable statement visiting code may pass NULL expressions 43 // to this code. Maybe this should be handled by introducing an 44 // undefined expression or literal? Revisit this code if this 45 // changes 46 if (expressions->at(i) != nullptr) { 47 AST_REWRITE_LIST_ELEMENT(Expression, expressions, i); 48 } 49 } 50 } 51 52 53 void AstExpressionRewriter::VisitVariableDeclaration( 54 VariableDeclaration* node) { 55 // Not visiting `proxy_`. 56 NOTHING(); 57 } 58 59 60 void AstExpressionRewriter::VisitFunctionDeclaration( 61 FunctionDeclaration* node) { 62 // Not visiting `proxy_`. 63 AST_REWRITE_PROPERTY(FunctionLiteral, node, fun); 64 } 65 66 67 void AstExpressionRewriter::VisitBlock(Block* node) { 68 VisitStatements(node->statements()); 69 } 70 71 72 void AstExpressionRewriter::VisitExpressionStatement( 73 ExpressionStatement* node) { 74 AST_REWRITE_PROPERTY(Expression, node, expression); 75 } 76 77 78 void AstExpressionRewriter::VisitEmptyStatement(EmptyStatement* node) { 79 NOTHING(); 80 } 81 82 83 void AstExpressionRewriter::VisitSloppyBlockFunctionStatement( 84 SloppyBlockFunctionStatement* node) { 85 AST_REWRITE_PROPERTY(Statement, node, statement); 86 } 87 88 89 void AstExpressionRewriter::VisitIfStatement(IfStatement* node) { 90 AST_REWRITE_PROPERTY(Expression, node, condition); 91 AST_REWRITE_PROPERTY(Statement, node, then_statement); 92 AST_REWRITE_PROPERTY(Statement, node, else_statement); 93 } 94 95 96 void AstExpressionRewriter::VisitContinueStatement(ContinueStatement* node) { 97 NOTHING(); 98 } 99 100 101 void AstExpressionRewriter::VisitBreakStatement(BreakStatement* node) { 102 NOTHING(); 103 } 104 105 106 void AstExpressionRewriter::VisitReturnStatement(ReturnStatement* node) { 107 AST_REWRITE_PROPERTY(Expression, node, expression); 108 } 109 110 111 void AstExpressionRewriter::VisitWithStatement(WithStatement* node) { 112 AST_REWRITE_PROPERTY(Expression, node, expression); 113 AST_REWRITE_PROPERTY(Statement, node, statement); 114 } 115 116 117 void AstExpressionRewriter::VisitSwitchStatement(SwitchStatement* node) { 118 AST_REWRITE_PROPERTY(Expression, node, tag); 119 ZoneList<CaseClause*>* clauses = node->cases(); 120 for (int i = 0; i < clauses->length(); i++) { 121 AST_REWRITE_LIST_ELEMENT(CaseClause, clauses, i); 122 } 123 } 124 125 126 void AstExpressionRewriter::VisitDoWhileStatement(DoWhileStatement* node) { 127 AST_REWRITE_PROPERTY(Expression, node, cond); 128 AST_REWRITE_PROPERTY(Statement, node, body); 129 } 130 131 132 void AstExpressionRewriter::VisitWhileStatement(WhileStatement* node) { 133 AST_REWRITE_PROPERTY(Expression, node, cond); 134 AST_REWRITE_PROPERTY(Statement, node, body); 135 } 136 137 138 void AstExpressionRewriter::VisitForStatement(ForStatement* node) { 139 if (node->init() != nullptr) { 140 AST_REWRITE_PROPERTY(Statement, node, init); 141 } 142 if (node->cond() != nullptr) { 143 AST_REWRITE_PROPERTY(Expression, node, cond); 144 } 145 if (node->next() != nullptr) { 146 AST_REWRITE_PROPERTY(Statement, node, next); 147 } 148 AST_REWRITE_PROPERTY(Statement, node, body); 149 } 150 151 152 void AstExpressionRewriter::VisitForInStatement(ForInStatement* node) { 153 AST_REWRITE_PROPERTY(Expression, node, each); 154 AST_REWRITE_PROPERTY(Expression, node, subject); 155 AST_REWRITE_PROPERTY(Statement, node, body); 156 } 157 158 159 void AstExpressionRewriter::VisitForOfStatement(ForOfStatement* node) { 160 AST_REWRITE_PROPERTY(Expression, node, assign_iterator); 161 AST_REWRITE_PROPERTY(Expression, node, next_result); 162 AST_REWRITE_PROPERTY(Expression, node, result_done); 163 AST_REWRITE_PROPERTY(Expression, node, assign_each); 164 AST_REWRITE_PROPERTY(Statement, node, body); 165 } 166 167 168 void AstExpressionRewriter::VisitTryCatchStatement(TryCatchStatement* node) { 169 AST_REWRITE_PROPERTY(Block, node, try_block); 170 // Not visiting the variable. 171 AST_REWRITE_PROPERTY(Block, node, catch_block); 172 } 173 174 175 void AstExpressionRewriter::VisitTryFinallyStatement( 176 TryFinallyStatement* node) { 177 AST_REWRITE_PROPERTY(Block, node, try_block); 178 AST_REWRITE_PROPERTY(Block, node, finally_block); 179 } 180 181 182 void AstExpressionRewriter::VisitDebuggerStatement(DebuggerStatement* node) { 183 NOTHING(); 184 } 185 186 187 void AstExpressionRewriter::VisitFunctionLiteral(FunctionLiteral* node) { 188 REWRITE_THIS(node); 189 VisitDeclarations(node->scope()->declarations()); 190 ZoneList<Statement*>* body = node->body(); 191 if (body != nullptr) VisitStatements(body); 192 } 193 194 195 void AstExpressionRewriter::VisitClassLiteral(ClassLiteral* node) { 196 REWRITE_THIS(node); 197 // Not visiting `class_variable_proxy_`. 198 if (node->extends() != nullptr) { 199 AST_REWRITE_PROPERTY(Expression, node, extends); 200 } 201 AST_REWRITE_PROPERTY(FunctionLiteral, node, constructor); 202 ZoneList<typename ClassLiteral::Property*>* properties = node->properties(); 203 for (int i = 0; i < properties->length(); i++) { 204 VisitLiteralProperty(properties->at(i)); 205 } 206 } 207 208 void AstExpressionRewriter::VisitNativeFunctionLiteral( 209 NativeFunctionLiteral* node) { 210 REWRITE_THIS(node); 211 NOTHING(); 212 } 213 214 215 void AstExpressionRewriter::VisitConditional(Conditional* node) { 216 REWRITE_THIS(node); 217 AST_REWRITE_PROPERTY(Expression, node, condition); 218 AST_REWRITE_PROPERTY(Expression, node, then_expression); 219 AST_REWRITE_PROPERTY(Expression, node, else_expression); 220 } 221 222 223 void AstExpressionRewriter::VisitVariableProxy(VariableProxy* node) { 224 REWRITE_THIS(node); 225 NOTHING(); 226 } 227 228 229 void AstExpressionRewriter::VisitLiteral(Literal* node) { 230 REWRITE_THIS(node); 231 NOTHING(); 232 } 233 234 235 void AstExpressionRewriter::VisitRegExpLiteral(RegExpLiteral* node) { 236 REWRITE_THIS(node); 237 NOTHING(); 238 } 239 240 241 void AstExpressionRewriter::VisitObjectLiteral(ObjectLiteral* node) { 242 REWRITE_THIS(node); 243 ZoneList<typename ObjectLiteral::Property*>* properties = node->properties(); 244 for (int i = 0; i < properties->length(); i++) { 245 VisitLiteralProperty(properties->at(i)); 246 } 247 } 248 249 void AstExpressionRewriter::VisitLiteralProperty(LiteralProperty* property) { 250 if (property == nullptr) return; 251 AST_REWRITE_PROPERTY(Expression, property, key); 252 AST_REWRITE_PROPERTY(Expression, property, value); 253 } 254 255 256 void AstExpressionRewriter::VisitArrayLiteral(ArrayLiteral* node) { 257 REWRITE_THIS(node); 258 VisitExpressions(node->values()); 259 } 260 261 262 void AstExpressionRewriter::VisitAssignment(Assignment* node) { 263 REWRITE_THIS(node); 264 AST_REWRITE_PROPERTY(Expression, node, target); 265 AST_REWRITE_PROPERTY(Expression, node, value); 266 } 267 268 269 void AstExpressionRewriter::VisitYield(Yield* node) { 270 REWRITE_THIS(node); 271 AST_REWRITE_PROPERTY(Expression, node, generator_object); 272 AST_REWRITE_PROPERTY(Expression, node, expression); 273 } 274 275 276 void AstExpressionRewriter::VisitThrow(Throw* node) { 277 REWRITE_THIS(node); 278 AST_REWRITE_PROPERTY(Expression, node, exception); 279 } 280 281 282 void AstExpressionRewriter::VisitProperty(Property* node) { 283 REWRITE_THIS(node); 284 if (node == nullptr) return; 285 AST_REWRITE_PROPERTY(Expression, node, obj); 286 AST_REWRITE_PROPERTY(Expression, node, key); 287 } 288 289 290 void AstExpressionRewriter::VisitCall(Call* node) { 291 REWRITE_THIS(node); 292 AST_REWRITE_PROPERTY(Expression, node, expression); 293 VisitExpressions(node->arguments()); 294 } 295 296 297 void AstExpressionRewriter::VisitCallNew(CallNew* node) { 298 REWRITE_THIS(node); 299 AST_REWRITE_PROPERTY(Expression, node, expression); 300 VisitExpressions(node->arguments()); 301 } 302 303 304 void AstExpressionRewriter::VisitCallRuntime(CallRuntime* node) { 305 REWRITE_THIS(node); 306 VisitExpressions(node->arguments()); 307 } 308 309 310 void AstExpressionRewriter::VisitUnaryOperation(UnaryOperation* node) { 311 REWRITE_THIS(node); 312 AST_REWRITE_PROPERTY(Expression, node, expression); 313 } 314 315 316 void AstExpressionRewriter::VisitCountOperation(CountOperation* node) { 317 REWRITE_THIS(node); 318 AST_REWRITE_PROPERTY(Expression, node, expression); 319 } 320 321 322 void AstExpressionRewriter::VisitBinaryOperation(BinaryOperation* node) { 323 REWRITE_THIS(node); 324 AST_REWRITE_PROPERTY(Expression, node, left); 325 AST_REWRITE_PROPERTY(Expression, node, right); 326 } 327 328 329 void AstExpressionRewriter::VisitCompareOperation(CompareOperation* node) { 330 REWRITE_THIS(node); 331 AST_REWRITE_PROPERTY(Expression, node, left); 332 AST_REWRITE_PROPERTY(Expression, node, right); 333 } 334 335 336 void AstExpressionRewriter::VisitSpread(Spread* node) { 337 REWRITE_THIS(node); 338 AST_REWRITE_PROPERTY(Expression, node, expression); 339 } 340 341 342 void AstExpressionRewriter::VisitThisFunction(ThisFunction* node) { 343 REWRITE_THIS(node); 344 NOTHING(); 345 } 346 347 348 void AstExpressionRewriter::VisitSuperPropertyReference( 349 SuperPropertyReference* node) { 350 REWRITE_THIS(node); 351 AST_REWRITE_PROPERTY(VariableProxy, node, this_var); 352 AST_REWRITE_PROPERTY(Expression, node, home_object); 353 } 354 355 356 void AstExpressionRewriter::VisitSuperCallReference(SuperCallReference* node) { 357 REWRITE_THIS(node); 358 AST_REWRITE_PROPERTY(VariableProxy, node, this_var); 359 AST_REWRITE_PROPERTY(VariableProxy, node, new_target_var); 360 AST_REWRITE_PROPERTY(VariableProxy, node, this_function_var); 361 } 362 363 364 void AstExpressionRewriter::VisitCaseClause(CaseClause* node) { 365 if (!node->is_default()) { 366 AST_REWRITE_PROPERTY(Expression, node, label); 367 } 368 VisitStatements(node->statements()); 369 } 370 371 372 void AstExpressionRewriter::VisitEmptyParentheses(EmptyParentheses* node) { 373 NOTHING(); 374 } 375 376 void AstExpressionRewriter::VisitGetIterator(GetIterator* node) { 377 AST_REWRITE_PROPERTY(Expression, node, iterable); 378 } 379 380 void AstExpressionRewriter::VisitDoExpression(DoExpression* node) { 381 REWRITE_THIS(node); 382 AST_REWRITE_PROPERTY(Block, node, block); 383 AST_REWRITE_PROPERTY(VariableProxy, node, result); 384 } 385 386 387 void AstExpressionRewriter::VisitRewritableExpression( 388 RewritableExpression* node) { 389 REWRITE_THIS(node); 390 AST_REWRITE(Expression, node->expression(), node->Rewrite(replacement)); 391 } 392 393 394 } // namespace internal 395 } // namespace v8 396