| OLD | NEW |
| 1 // Copyright 2009 the V8 project authors. All rights reserved. | 1 // Copyright 2009 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 24 matching lines...) Expand all Loading... |
| 35 namespace v8 { | 35 namespace v8 { |
| 36 namespace internal { | 36 namespace internal { |
| 37 | 37 |
| 38 | 38 |
| 39 CfgGlobals* CfgGlobals::top_ = NULL; | 39 CfgGlobals* CfgGlobals::top_ = NULL; |
| 40 | 40 |
| 41 | 41 |
| 42 CfgGlobals::CfgGlobals(FunctionLiteral* fun) | 42 CfgGlobals::CfgGlobals(FunctionLiteral* fun) |
| 43 : global_fun_(fun), | 43 : global_fun_(fun), |
| 44 global_exit_(new ExitNode()), | 44 global_exit_(new ExitNode()), |
| 45 effect_(new Effect()), | 45 nowhere_(new Nowhere()), |
| 46 #ifdef DEBUG | 46 #ifdef DEBUG |
| 47 node_counter_(0), | 47 node_counter_(0), |
| 48 temp_counter_(0), | 48 temp_counter_(0), |
| 49 #endif | 49 #endif |
| 50 previous_(top_) { | 50 previous_(top_) { |
| 51 top_ = this; | 51 top_ = this; |
| 52 } | 52 } |
| 53 | 53 |
| 54 | 54 |
| 55 #define BAILOUT(reason) \ | 55 #define BAILOUT(reason) \ |
| 56 do { return NULL; } while (false) | 56 do { return NULL; } while (false) |
| 57 | 57 |
| 58 Cfg* Cfg::Build() { | 58 Cfg* Cfg::Build() { |
| 59 FunctionLiteral* fun = CfgGlobals::current()->fun(); | 59 FunctionLiteral* fun = CfgGlobals::current()->fun(); |
| 60 if (fun->scope()->num_heap_slots() > 0) { | 60 if (fun->scope()->num_heap_slots() > 0) { |
| 61 BAILOUT("function has context slots"); | 61 BAILOUT("function has context slots"); |
| 62 } | 62 } |
| 63 if (fun->scope()->num_stack_slots() > kPointerSize) { |
| 64 BAILOUT("function has too many locals"); |
| 65 } |
| 66 if (fun->scope()->num_parameters() > kPointerSize - 1) { |
| 67 BAILOUT("function has too many parameters"); |
| 68 } |
| 63 if (fun->scope()->arguments() != NULL) { | 69 if (fun->scope()->arguments() != NULL) { |
| 64 BAILOUT("function uses .arguments"); | 70 BAILOUT("function uses .arguments"); |
| 65 } | 71 } |
| 66 | 72 |
| 67 ZoneList<Statement*>* body = fun->body(); | 73 ZoneList<Statement*>* body = fun->body(); |
| 68 if (body->is_empty()) { | 74 if (body->is_empty()) { |
| 69 BAILOUT("empty function body"); | 75 BAILOUT("empty function body"); |
| 70 } | 76 } |
| 71 | 77 |
| 72 StatementBuilder builder; | 78 StatementBuilder builder; |
| 73 builder.VisitStatements(body); | 79 builder.VisitStatements(body); |
| 74 Cfg* cfg = builder.cfg(); | 80 Cfg* graph = builder.graph(); |
| 75 if (cfg == NULL) { | 81 if (graph == NULL) { |
| 76 BAILOUT("unsupported statement type"); | 82 BAILOUT("unsupported statement type"); |
| 77 } | 83 } |
| 78 if (cfg->is_empty()) { | 84 if (graph->is_empty()) { |
| 79 BAILOUT("function body produces empty cfg"); | 85 BAILOUT("function body produces empty cfg"); |
| 80 } | 86 } |
| 81 if (cfg->has_exit()) { | 87 if (graph->has_exit()) { |
| 82 BAILOUT("control path without explicit return"); | 88 BAILOUT("control path without explicit return"); |
| 83 } | 89 } |
| 84 cfg->PrependEntryNode(); | 90 graph->PrependEntryNode(); |
| 85 return cfg; | 91 return graph; |
| 86 } | 92 } |
| 87 | 93 |
| 88 #undef BAILOUT | 94 #undef BAILOUT |
| 89 | 95 |
| 90 | 96 |
| 91 void Cfg::PrependEntryNode() { | 97 void Cfg::PrependEntryNode() { |
| 92 ASSERT(!is_empty()); | 98 ASSERT(!is_empty()); |
| 93 entry_ = new EntryNode(InstructionBlock::cast(entry())); | 99 entry_ = new EntryNode(InstructionBlock::cast(entry())); |
| 94 } | 100 } |
| 95 | 101 |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 187 } | 193 } |
| 188 PrintF("--- Code ---\n"); | 194 PrintF("--- Code ---\n"); |
| 189 code->Disassemble(*fun->name()->ToCString()); | 195 code->Disassemble(*fun->name()->ToCString()); |
| 190 } | 196 } |
| 191 #endif | 197 #endif |
| 192 | 198 |
| 193 return code; | 199 return code; |
| 194 } | 200 } |
| 195 | 201 |
| 196 | 202 |
| 203 void MoveInstr::FastAllocate(TempLocation* temp) { |
| 204 ASSERT(temp->where() == TempLocation::NOT_ALLOCATED); |
| 205 if (temp == value()) { |
| 206 temp->set_where(TempLocation::ACCUMULATOR); |
| 207 } else { |
| 208 temp->set_where(TempLocation::STACK); |
| 209 } |
| 210 } |
| 211 |
| 212 |
| 197 void BinaryOpInstr::FastAllocate(TempLocation* temp) { | 213 void BinaryOpInstr::FastAllocate(TempLocation* temp) { |
| 198 ASSERT(temp->where() == TempLocation::NOWHERE); | 214 ASSERT(temp->where() == TempLocation::NOT_ALLOCATED); |
| 199 if (temp == val0_ || temp == val1_) { | 215 if (temp == value0() || temp == value1()) { |
| 200 temp->set_where(TempLocation::ACCUMULATOR); | 216 temp->set_where(TempLocation::ACCUMULATOR); |
| 201 } else { | 217 } else { |
| 202 temp->set_where(TempLocation::STACK); | 218 temp->set_where(TempLocation::STACK); |
| 203 } | 219 } |
| 204 } | 220 } |
| 205 | 221 |
| 206 | 222 |
| 207 void ReturnInstr::FastAllocate(TempLocation* temp) { | 223 void ReturnInstr::FastAllocate(TempLocation* temp) { |
| 208 ASSERT(temp->where() == TempLocation::NOWHERE); | 224 ASSERT(temp->where() == TempLocation::NOT_ALLOCATED); |
| 209 if (temp == value_) { | 225 if (temp == value_) { |
| 210 temp->set_where(TempLocation::ACCUMULATOR); | 226 temp->set_where(TempLocation::ACCUMULATOR); |
| 211 } else { | 227 } else { |
| 212 temp->set_where(TempLocation::STACK); | 228 temp->set_where(TempLocation::STACK); |
| 213 } | 229 } |
| 214 } | 230 } |
| 215 | 231 |
| 216 | 232 |
| 217 // The expression builder should not be used for declarations or statements. | 233 // The expression builder should not be used for declarations or statements. |
| 218 void ExpressionBuilder::VisitDeclaration(Declaration* decl) { UNREACHABLE(); } | 234 void ExpressionBuilder::VisitDeclaration(Declaration* decl) { UNREACHABLE(); } |
| 219 | 235 |
| 220 #define DEFINE_VISIT(type) \ | 236 #define DEFINE_VISIT(type) \ |
| 221 void ExpressionBuilder::Visit##type(type* stmt) { UNREACHABLE(); } | 237 void ExpressionBuilder::Visit##type(type* stmt) { UNREACHABLE(); } |
| 222 STATEMENT_NODE_LIST(DEFINE_VISIT) | 238 STATEMENT_NODE_LIST(DEFINE_VISIT) |
| 223 #undef DEFINE_VISIT | 239 #undef DEFINE_VISIT |
| 224 | 240 |
| 225 | 241 |
| 226 // Macros (temporarily) handling unsupported expression types. | 242 // Macros (temporarily) handling unsupported expression types. |
| 227 #define BAILOUT(reason) \ | 243 #define BAILOUT(reason) \ |
| 228 do { \ | 244 do { \ |
| 229 cfg_ = NULL; \ | 245 graph_ = NULL; \ |
| 230 return; \ | 246 return; \ |
| 231 } while (false) | 247 } while (false) |
| 232 | 248 |
| 233 void ExpressionBuilder::VisitFunctionLiteral(FunctionLiteral* expr) { | 249 void ExpressionBuilder::VisitFunctionLiteral(FunctionLiteral* expr) { |
| 234 BAILOUT("FunctionLiteral"); | 250 BAILOUT("FunctionLiteral"); |
| 235 } | 251 } |
| 236 | 252 |
| 237 | 253 |
| 238 void ExpressionBuilder::VisitFunctionBoilerplateLiteral( | 254 void ExpressionBuilder::VisitFunctionBoilerplateLiteral( |
| 239 FunctionBoilerplateLiteral* expr) { | 255 FunctionBoilerplateLiteral* expr) { |
| (...skipping 13 matching lines...) Expand all Loading... |
| 253 | 269 |
| 254 void ExpressionBuilder::VisitVariableProxy(VariableProxy* expr) { | 270 void ExpressionBuilder::VisitVariableProxy(VariableProxy* expr) { |
| 255 Expression* rewrite = expr->var()->rewrite(); | 271 Expression* rewrite = expr->var()->rewrite(); |
| 256 if (rewrite == NULL || rewrite->AsSlot() == NULL) { | 272 if (rewrite == NULL || rewrite->AsSlot() == NULL) { |
| 257 BAILOUT("unsupported variable (not a slot)"); | 273 BAILOUT("unsupported variable (not a slot)"); |
| 258 } | 274 } |
| 259 Slot* slot = rewrite->AsSlot(); | 275 Slot* slot = rewrite->AsSlot(); |
| 260 if (slot->type() != Slot::PARAMETER && slot->type() != Slot::LOCAL) { | 276 if (slot->type() != Slot::PARAMETER && slot->type() != Slot::LOCAL) { |
| 261 BAILOUT("unsupported slot type (not a parameter or local)"); | 277 BAILOUT("unsupported slot type (not a parameter or local)"); |
| 262 } | 278 } |
| 279 // Ignore the passed destination. |
| 263 value_ = new SlotLocation(slot->type(), slot->index()); | 280 value_ = new SlotLocation(slot->type(), slot->index()); |
| 264 } | 281 } |
| 265 | 282 |
| 266 | 283 |
| 267 void ExpressionBuilder::VisitLiteral(Literal* expr) { | 284 void ExpressionBuilder::VisitLiteral(Literal* expr) { |
| 285 // Ignore the passed destination. |
| 268 value_ = new Constant(expr->handle()); | 286 value_ = new Constant(expr->handle()); |
| 269 } | 287 } |
| 270 | 288 |
| 271 | 289 |
| 272 void ExpressionBuilder::VisitRegExpLiteral(RegExpLiteral* expr) { | 290 void ExpressionBuilder::VisitRegExpLiteral(RegExpLiteral* expr) { |
| 273 BAILOUT("RegExpLiteral"); | 291 BAILOUT("RegExpLiteral"); |
| 274 } | 292 } |
| 275 | 293 |
| 276 | 294 |
| 277 void ExpressionBuilder::VisitObjectLiteral(ObjectLiteral* expr) { | 295 void ExpressionBuilder::VisitObjectLiteral(ObjectLiteral* expr) { |
| 278 BAILOUT("ObjectLiteral"); | 296 BAILOUT("ObjectLiteral"); |
| 279 } | 297 } |
| 280 | 298 |
| 281 | 299 |
| 282 void ExpressionBuilder::VisitArrayLiteral(ArrayLiteral* expr) { | 300 void ExpressionBuilder::VisitArrayLiteral(ArrayLiteral* expr) { |
| 283 BAILOUT("ArrayLiteral"); | 301 BAILOUT("ArrayLiteral"); |
| 284 } | 302 } |
| 285 | 303 |
| 286 | 304 |
| 287 void ExpressionBuilder::VisitCatchExtensionObject(CatchExtensionObject* expr) { | 305 void ExpressionBuilder::VisitCatchExtensionObject(CatchExtensionObject* expr) { |
| 288 BAILOUT("CatchExtensionObject"); | 306 BAILOUT("CatchExtensionObject"); |
| 289 } | 307 } |
| 290 | 308 |
| 291 | 309 |
| 292 void ExpressionBuilder::VisitAssignment(Assignment* expr) { | 310 void ExpressionBuilder::VisitAssignment(Assignment* expr) { |
| 293 BAILOUT("Assignment"); | 311 if (expr->op() != Token::ASSIGN && expr->op() != Token::INIT_VAR) { |
| 312 BAILOUT("unsupported compound assignment"); |
| 313 } |
| 314 Expression* lhs = expr->target(); |
| 315 if (lhs->AsProperty() != NULL) { |
| 316 BAILOUT("unsupported property assignment"); |
| 317 } |
| 318 Variable* var = lhs->AsVariableProxy()->AsVariable(); |
| 319 if (var == NULL) { |
| 320 BAILOUT("unsupported invalid left-hand side"); |
| 321 } |
| 322 if (var->is_global()) { |
| 323 BAILOUT("unsupported global variable"); |
| 324 } |
| 325 Slot* slot = var->slot(); |
| 326 ASSERT(slot != NULL); |
| 327 if (slot->type() != Slot::PARAMETER && slot->type() != Slot::LOCAL) { |
| 328 BAILOUT("unsupported slot lhs (not a parameter or local)"); |
| 329 } |
| 330 |
| 331 ExpressionBuilder builder; |
| 332 SlotLocation* loc = new SlotLocation(slot->type(), slot->index()); |
| 333 builder.Build(expr->value(), loc); |
| 334 if (builder.graph() == NULL) { |
| 335 BAILOUT("unsupported expression in assignment"); |
| 336 } |
| 337 // If the expression did not come back in the slot location, append |
| 338 // a move to the CFG. |
| 339 graph_ = builder.graph(); |
| 340 if (builder.value() != loc) { |
| 341 graph()->Append(new MoveInstr(loc, builder.value())); |
| 342 } |
| 343 // Record the assignment. |
| 344 assigned_vars_.AddElement(loc); |
| 345 // Ignore the destination passed to us. |
| 346 value_ = loc; |
| 294 } | 347 } |
| 295 | 348 |
| 296 | 349 |
| 297 void ExpressionBuilder::VisitThrow(Throw* expr) { | 350 void ExpressionBuilder::VisitThrow(Throw* expr) { |
| 298 BAILOUT("Throw"); | 351 BAILOUT("Throw"); |
| 299 } | 352 } |
| 300 | 353 |
| 301 | 354 |
| 302 void ExpressionBuilder::VisitProperty(Property* expr) { | 355 void ExpressionBuilder::VisitProperty(Property* expr) { |
| 303 BAILOUT("Property"); | 356 BAILOUT("Property"); |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 347 case Token::BIT_AND: | 400 case Token::BIT_AND: |
| 348 case Token::SHL: | 401 case Token::SHL: |
| 349 case Token::SAR: | 402 case Token::SAR: |
| 350 case Token::SHR: | 403 case Token::SHR: |
| 351 case Token::ADD: | 404 case Token::ADD: |
| 352 case Token::SUB: | 405 case Token::SUB: |
| 353 case Token::MUL: | 406 case Token::MUL: |
| 354 case Token::DIV: | 407 case Token::DIV: |
| 355 case Token::MOD: { | 408 case Token::MOD: { |
| 356 ExpressionBuilder left, right; | 409 ExpressionBuilder left, right; |
| 357 left.Build(expr->left()); | 410 left.Build(expr->left(), NULL); |
| 358 if (left.cfg() == NULL) { | 411 if (left.graph() == NULL) { |
| 359 BAILOUT("unsupported left subexpression in binop"); | 412 BAILOUT("unsupported left subexpression in binop"); |
| 360 } | 413 } |
| 361 right.Build(expr->right()); | 414 right.Build(expr->right(), NULL); |
| 362 if (right.cfg() == NULL) { | 415 if (right.graph() == NULL) { |
| 363 BAILOUT("unsupported right subexpression in binop"); | 416 BAILOUT("unsupported right subexpression in binop"); |
| 364 } | 417 } |
| 365 | 418 |
| 366 Location* temp = new TempLocation(); | 419 if (destination_ == NULL) destination_ = new TempLocation(); |
| 367 cfg_ = left.cfg(); | |
| 368 cfg_->Concatenate(right.cfg()); | |
| 369 cfg_->Append(new BinaryOpInstr(temp, op, left.value(), right.value())); | |
| 370 | 420 |
| 371 value_ = temp; | 421 graph_ = left.graph(); |
| 422 // Insert a move to a fresh temporary if the left value is in a |
| 423 // slot that's assigned on the right. |
| 424 Location* temp = NULL; |
| 425 if (left.value()->is_slot() && |
| 426 right.assigned_vars()->Contains(SlotLocation::cast(left.value()))) { |
| 427 temp = new TempLocation(); |
| 428 graph()->Append(new MoveInstr(temp, left.value())); |
| 429 } |
| 430 graph()->Concatenate(right.graph()); |
| 431 graph()->Append(new BinaryOpInstr(destination_, op, |
| 432 temp == NULL ? left.value() : temp, |
| 433 right.value())); |
| 434 |
| 435 assigned_vars_ = *left.assigned_vars(); |
| 436 assigned_vars()->Union(right.assigned_vars()); |
| 437 |
| 438 value_ = destination_; |
| 372 return; | 439 return; |
| 373 } | 440 } |
| 374 | 441 |
| 375 default: | 442 default: |
| 376 UNREACHABLE(); | 443 UNREACHABLE(); |
| 377 } | 444 } |
| 378 } | 445 } |
| 379 | 446 |
| 380 | 447 |
| 381 void ExpressionBuilder::VisitCompareOperation(CompareOperation* expr) { | 448 void ExpressionBuilder::VisitCompareOperation(CompareOperation* expr) { |
| 382 BAILOUT("CompareOperation"); | 449 BAILOUT("CompareOperation"); |
| 383 } | 450 } |
| 384 | 451 |
| 385 | 452 |
| 386 void ExpressionBuilder::VisitThisFunction(ThisFunction* expr) { | 453 void ExpressionBuilder::VisitThisFunction(ThisFunction* expr) { |
| 387 BAILOUT("ThisFunction"); | 454 BAILOUT("ThisFunction"); |
| 388 } | 455 } |
| 389 | 456 |
| 390 #undef BAILOUT | 457 #undef BAILOUT |
| 391 | 458 |
| 392 | 459 |
| 393 // Macros (temporarily) handling unsupported statement types. | 460 // Macros (temporarily) handling unsupported statement types. |
| 394 #define BAILOUT(reason) \ | 461 #define BAILOUT(reason) \ |
| 395 do { \ | 462 do { \ |
| 396 cfg_ = NULL; \ | 463 graph_ = NULL; \ |
| 397 return; \ | 464 return; \ |
| 398 } while (false) | 465 } while (false) |
| 399 | 466 |
| 400 #define CHECK_BAILOUT() \ | 467 #define CHECK_BAILOUT() \ |
| 401 if (cfg_ == NULL) { return; } else {} | 468 if (graph() == NULL) { return; } else {} |
| 402 | 469 |
| 403 void StatementBuilder::VisitStatements(ZoneList<Statement*>* stmts) { | 470 void StatementBuilder::VisitStatements(ZoneList<Statement*>* stmts) { |
| 404 for (int i = 0, len = stmts->length(); i < len; i++) { | 471 for (int i = 0, len = stmts->length(); i < len; i++) { |
| 405 Visit(stmts->at(i)); | 472 Visit(stmts->at(i)); |
| 406 CHECK_BAILOUT(); | 473 CHECK_BAILOUT(); |
| 407 if (!cfg_->has_exit()) return; | 474 if (!graph()->has_exit()) return; |
| 408 } | 475 } |
| 409 } | 476 } |
| 410 | 477 |
| 411 | 478 |
| 412 // The statement builder should not be used for declarations or expressions. | 479 // The statement builder should not be used for declarations or expressions. |
| 413 void StatementBuilder::VisitDeclaration(Declaration* decl) { UNREACHABLE(); } | 480 void StatementBuilder::VisitDeclaration(Declaration* decl) { UNREACHABLE(); } |
| 414 | 481 |
| 415 #define DEFINE_VISIT(type) \ | 482 #define DEFINE_VISIT(type) \ |
| 416 void StatementBuilder::Visit##type(type* expr) { UNREACHABLE(); } | 483 void StatementBuilder::Visit##type(type* expr) { UNREACHABLE(); } |
| 417 EXPRESSION_NODE_LIST(DEFINE_VISIT) | 484 EXPRESSION_NODE_LIST(DEFINE_VISIT) |
| 418 #undef DEFINE_VISIT | 485 #undef DEFINE_VISIT |
| 419 | 486 |
| 420 | 487 |
| 421 void StatementBuilder::VisitBlock(Block* stmt) { | 488 void StatementBuilder::VisitBlock(Block* stmt) { |
| 422 VisitStatements(stmt->statements()); | 489 VisitStatements(stmt->statements()); |
| 423 } | 490 } |
| 424 | 491 |
| 425 | 492 |
| 426 void StatementBuilder::VisitExpressionStatement(ExpressionStatement* stmt) { | 493 void StatementBuilder::VisitExpressionStatement(ExpressionStatement* stmt) { |
| 427 ExpressionBuilder builder; | 494 ExpressionBuilder builder; |
| 428 builder.Build(stmt->expression()); | 495 builder.Build(stmt->expression(), CfgGlobals::current()->nowhere()); |
| 429 if (builder.cfg() == NULL) { | 496 if (builder.graph() == NULL) { |
| 430 BAILOUT("unsupported expression in expression statement"); | 497 BAILOUT("unsupported expression in expression statement"); |
| 431 } | 498 } |
| 432 // Here's a temporary hack: we bang on the last instruction of the | 499 graph()->Append(new PositionInstr(stmt->statement_pos())); |
| 433 // expression (if any) to set its location to Effect. | 500 graph()->Concatenate(builder.graph()); |
| 434 if (!builder.cfg()->is_empty()) { | |
| 435 InstructionBlock* block = InstructionBlock::cast(builder.cfg()->exit()); | |
| 436 Instruction* instr = block->instructions()->last(); | |
| 437 instr->set_location(CfgGlobals::current()->effect_location()); | |
| 438 } | |
| 439 cfg_->Append(new PositionInstr(stmt->statement_pos())); | |
| 440 cfg_->Concatenate(builder.cfg()); | |
| 441 } | 501 } |
| 442 | 502 |
| 443 | 503 |
| 444 void StatementBuilder::VisitEmptyStatement(EmptyStatement* stmt) { | 504 void StatementBuilder::VisitEmptyStatement(EmptyStatement* stmt) { |
| 445 // Nothing to do. | 505 // Nothing to do. |
| 446 } | 506 } |
| 447 | 507 |
| 448 | 508 |
| 449 void StatementBuilder::VisitIfStatement(IfStatement* stmt) { | 509 void StatementBuilder::VisitIfStatement(IfStatement* stmt) { |
| 450 BAILOUT("IfStatement"); | 510 BAILOUT("IfStatement"); |
| 451 } | 511 } |
| 452 | 512 |
| 453 | 513 |
| 454 void StatementBuilder::VisitContinueStatement(ContinueStatement* stmt) { | 514 void StatementBuilder::VisitContinueStatement(ContinueStatement* stmt) { |
| 455 BAILOUT("ContinueStatement"); | 515 BAILOUT("ContinueStatement"); |
| 456 } | 516 } |
| 457 | 517 |
| 458 | 518 |
| 459 void StatementBuilder::VisitBreakStatement(BreakStatement* stmt) { | 519 void StatementBuilder::VisitBreakStatement(BreakStatement* stmt) { |
| 460 BAILOUT("BreakStatement"); | 520 BAILOUT("BreakStatement"); |
| 461 } | 521 } |
| 462 | 522 |
| 463 | 523 |
| 464 void StatementBuilder::VisitReturnStatement(ReturnStatement* stmt) { | 524 void StatementBuilder::VisitReturnStatement(ReturnStatement* stmt) { |
| 465 ExpressionBuilder builder; | 525 ExpressionBuilder builder; |
| 466 builder.Build(stmt->expression()); | 526 builder.Build(stmt->expression(), NULL); |
| 467 if (builder.cfg() == NULL) { | 527 if (builder.graph() == NULL) { |
| 468 BAILOUT("unsupported expression in return statement"); | 528 BAILOUT("unsupported expression in return statement"); |
| 469 } | 529 } |
| 470 | 530 |
| 471 cfg_->Append(new PositionInstr(stmt->statement_pos())); | 531 graph()->Append(new PositionInstr(stmt->statement_pos())); |
| 472 cfg_->Concatenate(builder.cfg()); | 532 graph()->Concatenate(builder.graph()); |
| 473 cfg_->AppendReturnInstruction(builder.value()); | 533 graph()->AppendReturnInstruction(builder.value()); |
| 474 } | 534 } |
| 475 | 535 |
| 476 | 536 |
| 477 void StatementBuilder::VisitWithEnterStatement(WithEnterStatement* stmt) { | 537 void StatementBuilder::VisitWithEnterStatement(WithEnterStatement* stmt) { |
| 478 BAILOUT("WithEnterStatement"); | 538 BAILOUT("WithEnterStatement"); |
| 479 } | 539 } |
| 480 | 540 |
| 481 | 541 |
| 482 void StatementBuilder::VisitWithExitStatement(WithExitStatement* stmt) { | 542 void StatementBuilder::VisitWithExitStatement(WithExitStatement* stmt) { |
| 483 BAILOUT("WithExitStatement"); | 543 BAILOUT("WithExitStatement"); |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 523 } | 583 } |
| 524 | 584 |
| 525 | 585 |
| 526 void Constant::Print() { | 586 void Constant::Print() { |
| 527 PrintF("Constant("); | 587 PrintF("Constant("); |
| 528 handle_->Print(); | 588 handle_->Print(); |
| 529 PrintF(")"); | 589 PrintF(")"); |
| 530 } | 590 } |
| 531 | 591 |
| 532 | 592 |
| 533 void Effect::Print() { | 593 void Nowhere::Print() { |
| 534 PrintF("Effect"); | 594 PrintF("Nowhere"); |
| 535 } | 595 } |
| 536 | 596 |
| 537 | 597 |
| 538 void SlotLocation::Print() { | 598 void SlotLocation::Print() { |
| 539 PrintF("Slot("); | 599 PrintF("Slot("); |
| 540 switch (type_) { | 600 switch (type_) { |
| 541 case Slot::PARAMETER: | 601 case Slot::PARAMETER: |
| 542 PrintF("PARAMETER, %d)", index_); | 602 PrintF("PARAMETER, %d)", index_); |
| 543 break; | 603 break; |
| 544 case Slot::LOCAL: | 604 case Slot::LOCAL: |
| 545 PrintF("LOCAL, %d)", index_); | 605 PrintF("LOCAL, %d)", index_); |
| 546 break; | 606 break; |
| 547 default: | 607 default: |
| 548 UNREACHABLE(); | 608 UNREACHABLE(); |
| 549 } | 609 } |
| 550 } | 610 } |
| 551 | 611 |
| 552 | 612 |
| 553 void TempLocation::Print() { | 613 void TempLocation::Print() { |
| 554 PrintF("Temp(%d)", number()); | 614 PrintF("Temp(%d)", number()); |
| 555 } | 615 } |
| 556 | 616 |
| 557 | 617 |
| 618 void MoveInstr::Print() { |
| 619 PrintF("Move("); |
| 620 location()->Print(); |
| 621 PrintF(", "); |
| 622 value_->Print(); |
| 623 PrintF(")\n"); |
| 624 } |
| 625 |
| 626 |
| 558 void BinaryOpInstr::Print() { | 627 void BinaryOpInstr::Print() { |
| 559 PrintF("BinaryOp("); | 628 PrintF("BinaryOp("); |
| 560 loc_->Print(); | 629 location()->Print(); |
| 561 PrintF(", %s, ", Token::Name(op_)); | 630 PrintF(", %s, ", Token::Name(op())); |
| 562 val0_->Print(); | 631 value0()->Print(); |
| 563 PrintF(", "); | 632 PrintF(", "); |
| 564 val1_->Print(); | 633 value1()->Print(); |
| 565 PrintF(")\n"); | 634 PrintF(")\n"); |
| 566 } | 635 } |
| 567 | 636 |
| 568 | 637 |
| 569 void ReturnInstr::Print() { | 638 void ReturnInstr::Print() { |
| 570 PrintF("Return("); | 639 PrintF("Return("); |
| 571 value_->Print(); | 640 value_->Print(); |
| 572 PrintF(")\n"); | 641 PrintF(")\n"); |
| 573 } | 642 } |
| 574 | 643 |
| (...skipping 22 matching lines...) Expand all Loading... |
| 597 void ExitNode::Print() { | 666 void ExitNode::Print() { |
| 598 if (!is_marked_) { | 667 if (!is_marked_) { |
| 599 is_marked_ = true; | 668 is_marked_ = true; |
| 600 PrintF("L%d:\nExit\n\n", number()); | 669 PrintF("L%d:\nExit\n\n", number()); |
| 601 } | 670 } |
| 602 } | 671 } |
| 603 | 672 |
| 604 #endif // DEBUG | 673 #endif // DEBUG |
| 605 | 674 |
| 606 } } // namespace v8::internal | 675 } } // namespace v8::internal |
| OLD | NEW |