Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2015 the V8 project authors. All rights reserved. | 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 | 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/interpreter/bytecode-generator.h" | 5 #include "src/interpreter/bytecode-generator.h" |
| 6 | 6 |
| 7 #include "src/compiler.h" | 7 #include "src/compiler.h" |
| 8 #include "src/interpreter/control-flow-builders.h" | 8 #include "src/interpreter/control-flow-builders.h" |
| 9 #include "src/objects.h" | 9 #include "src/objects.h" |
| 10 #include "src/parser.h" | 10 #include "src/parser.h" |
| (...skipping 471 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 482 EffectResultScope effect_scope(this); | 482 EffectResultScope effect_scope(this); |
| 483 VisitForEffect(stmt->expression()); | 483 VisitForEffect(stmt->expression()); |
| 484 } | 484 } |
| 485 | 485 |
| 486 | 486 |
| 487 void BytecodeGenerator::VisitEmptyStatement(EmptyStatement* stmt) { | 487 void BytecodeGenerator::VisitEmptyStatement(EmptyStatement* stmt) { |
| 488 } | 488 } |
| 489 | 489 |
| 490 | 490 |
| 491 void BytecodeGenerator::VisitIfStatement(IfStatement* stmt) { | 491 void BytecodeGenerator::VisitIfStatement(IfStatement* stmt) { |
| 492 // TODO(oth): Spot easy cases where there code would not need to | |
| 493 // emit the then block or the else block, e.g. condition is | |
| 494 // obviously true/1/false/0. | |
| 495 | |
| 496 BytecodeLabel else_label, end_label; | 492 BytecodeLabel else_label, end_label; |
| 497 | 493 if (stmt->condition()->ToBooleanIsTrue()) { |
| 498 VisitForAccumulatorValue(stmt->condition()); | 494 // Generate only then block. |
| 499 builder()->CastAccumulatorToBoolean(); | 495 Visit(stmt->then_statement()); |
| 500 builder()->JumpIfFalse(&else_label); | 496 } else if (stmt->condition()->ToBooleanIsFalse()) { |
| 501 Visit(stmt->then_statement()); | 497 // Generate only else block if it exists. |
| 502 if (stmt->HasElseStatement()) { | 498 if (stmt->HasElseStatement()) { |
| 503 builder()->Jump(&end_label); | 499 Visit(stmt->else_statement()); |
| 504 builder()->Bind(&else_label); | 500 } |
| 505 Visit(stmt->else_statement()); | |
| 506 } else { | 501 } else { |
| 507 builder()->Bind(&else_label); | 502 VisitForAccumulatorValue(stmt->condition()); |
| 503 builder()->CastAccumulatorToBoolean(); | |
| 504 builder()->JumpIfFalse(&else_label); | |
| 505 Visit(stmt->then_statement()); | |
| 506 if (stmt->HasElseStatement()) { | |
| 507 builder()->Jump(&end_label); | |
| 508 builder()->Bind(&else_label); | |
| 509 Visit(stmt->else_statement()); | |
| 510 } else { | |
| 511 builder()->Bind(&else_label); | |
| 512 } | |
| 513 builder()->Bind(&end_label); | |
| 508 } | 514 } |
| 509 builder()->Bind(&end_label); | |
| 510 } | 515 } |
| 511 | 516 |
| 512 | 517 |
| 513 void BytecodeGenerator::VisitSloppyBlockFunctionStatement( | 518 void BytecodeGenerator::VisitSloppyBlockFunctionStatement( |
| 514 SloppyBlockFunctionStatement* stmt) { | 519 SloppyBlockFunctionStatement* stmt) { |
| 515 Visit(stmt->statement()); | 520 Visit(stmt->statement()); |
| 516 } | 521 } |
| 517 | 522 |
| 518 | 523 |
| 519 void BytecodeGenerator::VisitContinueStatement(ContinueStatement* stmt) { | 524 void BytecodeGenerator::VisitContinueStatement(ContinueStatement* stmt) { |
| (...skipping 22 matching lines...) Expand all Loading... | |
| 542 UNIMPLEMENTED(); | 547 UNIMPLEMENTED(); |
| 543 } | 548 } |
| 544 | 549 |
| 545 | 550 |
| 546 void BytecodeGenerator::VisitCaseClause(CaseClause* clause) { UNIMPLEMENTED(); } | 551 void BytecodeGenerator::VisitCaseClause(CaseClause* clause) { UNIMPLEMENTED(); } |
| 547 | 552 |
| 548 | 553 |
| 549 void BytecodeGenerator::VisitDoWhileStatement(DoWhileStatement* stmt) { | 554 void BytecodeGenerator::VisitDoWhileStatement(DoWhileStatement* stmt) { |
| 550 LoopBuilder loop_builder(builder()); | 555 LoopBuilder loop_builder(builder()); |
| 551 ControlScopeForIteration execution_control(this, stmt, &loop_builder); | 556 ControlScopeForIteration execution_control(this, stmt, &loop_builder); |
| 557 BytecodeLabel body_label, condition_label, done_label; | |
| 552 | 558 |
| 553 BytecodeLabel body_label, condition_label, done_label; | 559 if (stmt->cond()->ToBooleanIsFalse()) { |
| 554 builder()->Bind(&body_label); | 560 Visit(stmt->body()); |
| 555 Visit(stmt->body()); | 561 // Bind condition_label and done_label for processing continue and break. |
| 556 builder()->Bind(&condition_label); | 562 builder()->Bind(&condition_label); |
| 557 VisitForAccumulatorValue(stmt->cond()); | 563 builder()->Bind(&done_label); |
| 558 builder()->JumpIfTrue(&body_label); | 564 } else { |
| 559 builder()->Bind(&done_label); | 565 builder()->Bind(&body_label); |
| 560 | 566 Visit(stmt->body()); |
|
rmcilroy
2015/10/30 15:49:53
nit - add line of whitespace here between body and
mythria
2015/11/02 10:46:07
Done.
| |
| 567 builder()->Bind(&condition_label); | |
| 568 if (stmt->cond()->ToBooleanIsTrue()) { | |
| 569 builder()->Jump(&body_label); | |
| 570 } else { | |
| 571 VisitForAccumulatorValue(stmt->cond()); | |
| 572 builder()->JumpIfTrue(&body_label); | |
| 573 } | |
| 574 builder()->Bind(&done_label); | |
| 575 } | |
| 561 loop_builder.SetBreakTarget(done_label); | 576 loop_builder.SetBreakTarget(done_label); |
| 562 loop_builder.SetContinueTarget(condition_label); | 577 loop_builder.SetContinueTarget(condition_label); |
| 563 } | 578 } |
| 564 | 579 |
| 565 | 580 |
| 566 void BytecodeGenerator::VisitWhileStatement(WhileStatement* stmt) { | 581 void BytecodeGenerator::VisitWhileStatement(WhileStatement* stmt) { |
| 567 LoopBuilder loop_builder(builder()); | 582 LoopBuilder loop_builder(builder()); |
| 568 ControlScopeForIteration execution_control(this, stmt, &loop_builder); | 583 ControlScopeForIteration execution_control(this, stmt, &loop_builder); |
| 569 | 584 |
| 570 BytecodeLabel body_label, condition_label, done_label; | 585 BytecodeLabel body_label, condition_label, done_label; |
| 571 builder()->Jump(&condition_label); | 586 if (stmt->cond()->ToBooleanIsFalse()) { |
| 587 // If the condition is false there is no need to generating the loop. | |
| 588 return; | |
| 589 } | |
| 590 | |
| 591 if (!stmt->cond()->ToBooleanIsTrue()) { | |
| 592 builder()->Jump(&condition_label); | |
| 593 } | |
| 572 builder()->Bind(&body_label); | 594 builder()->Bind(&body_label); |
| 573 Visit(stmt->body()); | 595 Visit(stmt->body()); |
|
rmcilroy
2015/10/30 15:49:53
nit - add a line of whitespace here between body
mythria
2015/11/02 10:46:07
Done.
| |
| 574 builder()->Bind(&condition_label); | 596 builder()->Bind(&condition_label); |
| 575 VisitForAccumulatorValue(stmt->cond()); | 597 if (stmt->cond()->ToBooleanIsTrue()) { |
| 576 builder()->JumpIfTrue(&body_label); | 598 builder()->Jump(&body_label); |
| 599 } else { | |
| 600 VisitForAccumulatorValue(stmt->cond()); | |
| 601 builder()->JumpIfTrue(&body_label); | |
| 602 } | |
| 577 builder()->Bind(&done_label); | 603 builder()->Bind(&done_label); |
| 578 | 604 |
| 579 loop_builder.SetBreakTarget(done_label); | 605 loop_builder.SetBreakTarget(done_label); |
| 580 loop_builder.SetContinueTarget(condition_label); | 606 loop_builder.SetContinueTarget(condition_label); |
| 581 } | 607 } |
| 582 | 608 |
| 583 | 609 |
| 584 void BytecodeGenerator::VisitForStatement(ForStatement* stmt) { | 610 void BytecodeGenerator::VisitForStatement(ForStatement* stmt) { |
| 585 LoopBuilder loop_builder(builder()); | 611 LoopBuilder loop_builder(builder()); |
| 586 ControlScopeForIteration execution_control(this, stmt, &loop_builder); | 612 ControlScopeForIteration execution_control(this, stmt, &loop_builder); |
| 587 | 613 |
| 588 if (stmt->init() != nullptr) { | 614 if (stmt->init() != nullptr) { |
| 589 Visit(stmt->init()); | 615 Visit(stmt->init()); |
| 590 } | 616 } |
| 591 | 617 |
| 618 if (stmt->cond() && stmt->cond()->ToBooleanIsFalse()) { | |
| 619 // If the condition is known to be false there is no need to generate | |
| 620 // body, next or condition blocks. Init block should be generated. | |
| 621 return; | |
| 622 } | |
| 623 | |
| 592 BytecodeLabel body_label, condition_label, next_label, done_label; | 624 BytecodeLabel body_label, condition_label, next_label, done_label; |
| 593 if (stmt->cond() != nullptr) { | 625 if (stmt->cond() && !stmt->cond()->ToBooleanIsTrue()) { |
| 594 builder()->Jump(&condition_label); | 626 builder()->Jump(&condition_label); |
| 595 } | 627 } |
| 596 builder()->Bind(&body_label); | 628 builder()->Bind(&body_label); |
| 597 Visit(stmt->body()); | 629 Visit(stmt->body()); |
| 598 builder()->Bind(&next_label); | 630 builder()->Bind(&next_label); |
| 599 if (stmt->next() != nullptr) { | 631 if (stmt->next() != nullptr) { |
| 600 Visit(stmt->next()); | 632 Visit(stmt->next()); |
| 601 } | 633 } |
| 602 if (stmt->cond()) { | 634 if ((stmt->cond() == nullptr) || stmt->cond()->ToBooleanIsTrue()) { |
|
rmcilroy
2015/10/30 15:49:53
nit - you removed the '== nullptr' above and added
mythria
2015/11/02 10:46:07
Done.
| |
| 635 builder()->Jump(&body_label); | |
| 636 } else { | |
| 603 builder()->Bind(&condition_label); | 637 builder()->Bind(&condition_label); |
| 604 VisitForAccumulatorValue(stmt->cond()); | 638 VisitForAccumulatorValue(stmt->cond()); |
| 605 builder()->JumpIfTrue(&body_label); | 639 builder()->JumpIfTrue(&body_label); |
| 606 } else { | |
| 607 builder()->Jump(&body_label); | |
| 608 } | 640 } |
| 609 builder()->Bind(&done_label); | 641 builder()->Bind(&done_label); |
| 610 | 642 |
| 611 loop_builder.SetBreakTarget(done_label); | 643 loop_builder.SetBreakTarget(done_label); |
| 612 loop_builder.SetContinueTarget(next_label); | 644 loop_builder.SetContinueTarget(next_label); |
| 613 } | 645 } |
| 614 | 646 |
| 615 | 647 |
| 616 void BytecodeGenerator::VisitForInStatement(ForInStatement* stmt) { | 648 void BytecodeGenerator::VisitForInStatement(ForInStatement* stmt) { |
| 617 UNIMPLEMENTED(); | 649 UNIMPLEMENTED(); |
| (...skipping 1329 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1947 } | 1979 } |
| 1948 | 1980 |
| 1949 | 1981 |
| 1950 int BytecodeGenerator::feedback_index(FeedbackVectorSlot slot) const { | 1982 int BytecodeGenerator::feedback_index(FeedbackVectorSlot slot) const { |
| 1951 return info()->feedback_vector()->GetIndex(slot); | 1983 return info()->feedback_vector()->GetIndex(slot); |
| 1952 } | 1984 } |
| 1953 | 1985 |
| 1954 } // namespace interpreter | 1986 } // namespace interpreter |
| 1955 } // namespace internal | 1987 } // namespace internal |
| 1956 } // namespace v8 | 1988 } // namespace v8 |
| OLD | NEW |