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 474 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 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 | 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 | 493 // emit the then block or the else block, e.g. condition is |
| 494 // obviously true/1/false/0. | 494 // obviously true/1/false/0. |
| 495 | 495 |
|
mythria
2015/10/29 17:23:23
Are there any other cases other than the condition
oth
2015/10/30 09:46:18
I believe these are the only instances of interest
| |
| 496 BytecodeLabel else_label, end_label; | 496 BytecodeLabel else_label, end_label; |
| 497 | 497 if (stmt->condition()->ToBooleanIsTrue()) { |
| 498 VisitForAccumulatorValue(stmt->condition()); | 498 // Generate only then block. |
| 499 builder()->CastAccumulatorToBoolean(); | 499 Visit(stmt->then_statement()); |
| 500 builder()->JumpIfFalse(&else_label); | 500 } else if (stmt->condition()->ToBooleanIsFalse()) { |
| 501 Visit(stmt->then_statement()); | 501 // Generate only else block if it exists. |
| 502 if (stmt->HasElseStatement()) { | 502 if (stmt->HasElseStatement()) { |
| 503 builder()->Jump(&end_label); | 503 Visit(stmt->else_statement()); |
| 504 builder()->Bind(&else_label); | 504 } |
| 505 Visit(stmt->else_statement()); | |
| 506 } else { | 505 } else { |
| 507 builder()->Bind(&else_label); | 506 VisitForAccumulatorValue(stmt->condition()); |
| 507 builder()->CastAccumulatorToBoolean(); | |
| 508 builder()->JumpIfFalse(&else_label); | |
| 509 Visit(stmt->then_statement()); | |
| 510 if (stmt->HasElseStatement()) { | |
| 511 builder()->Jump(&end_label); | |
| 512 builder()->Bind(&else_label); | |
| 513 Visit(stmt->else_statement()); | |
| 514 } else { | |
| 515 builder()->Bind(&else_label); | |
| 516 } | |
| 517 builder()->Bind(&end_label); | |
| 508 } | 518 } |
| 509 builder()->Bind(&end_label); | |
| 510 } | 519 } |
| 511 | 520 |
| 512 | 521 |
| 513 void BytecodeGenerator::VisitSloppyBlockFunctionStatement( | 522 void BytecodeGenerator::VisitSloppyBlockFunctionStatement( |
| 514 SloppyBlockFunctionStatement* stmt) { | 523 SloppyBlockFunctionStatement* stmt) { |
| 515 Visit(stmt->statement()); | 524 Visit(stmt->statement()); |
| 516 } | 525 } |
| 517 | 526 |
| 518 | 527 |
| 519 void BytecodeGenerator::VisitContinueStatement(ContinueStatement* stmt) { | 528 void BytecodeGenerator::VisitContinueStatement(ContinueStatement* stmt) { |
| (...skipping 22 matching lines...) Expand all Loading... | |
| 542 UNIMPLEMENTED(); | 551 UNIMPLEMENTED(); |
| 543 } | 552 } |
| 544 | 553 |
| 545 | 554 |
| 546 void BytecodeGenerator::VisitCaseClause(CaseClause* clause) { UNIMPLEMENTED(); } | 555 void BytecodeGenerator::VisitCaseClause(CaseClause* clause) { UNIMPLEMENTED(); } |
| 547 | 556 |
| 548 | 557 |
| 549 void BytecodeGenerator::VisitDoWhileStatement(DoWhileStatement* stmt) { | 558 void BytecodeGenerator::VisitDoWhileStatement(DoWhileStatement* stmt) { |
| 550 LoopBuilder loop_builder(builder()); | 559 LoopBuilder loop_builder(builder()); |
| 551 ControlScopeForIteration execution_control(this, stmt, &loop_builder); | 560 ControlScopeForIteration execution_control(this, stmt, &loop_builder); |
| 561 BytecodeLabel body_label, condition_label, done_label; | |
| 552 | 562 |
| 553 BytecodeLabel body_label, condition_label, done_label; | 563 if (stmt->cond()->ToBooleanIsFalse()) { |
| 554 builder()->Bind(&body_label); | 564 Visit(stmt->body()); |
| 555 Visit(stmt->body()); | 565 // Bind condition_label and done_label for |
| 556 builder()->Bind(&condition_label); | 566 // processing continue and break. |
| 557 VisitForAccumulatorValue(stmt->cond()); | 567 builder()->Bind(&condition_label); |
| 558 builder()->JumpIfTrue(&body_label); | 568 builder()->Bind(&done_label); |
| 559 builder()->Bind(&done_label); | 569 } else { |
| 560 | 570 builder()->Bind(&body_label); |
| 571 Visit(stmt->body()); | |
| 572 builder()->Bind(&condition_label); | |
| 573 if (stmt->cond()->ToBooleanIsTrue()) { | |
| 574 builder()->Jump(&body_label); | |
| 575 } else { | |
| 576 VisitForAccumulatorValue(stmt->cond()); | |
| 577 builder()->JumpIfTrue(&body_label); | |
| 578 } | |
| 579 builder()->Bind(&done_label); | |
| 580 } | |
| 561 loop_builder.SetBreakTarget(done_label); | 581 loop_builder.SetBreakTarget(done_label); |
| 562 loop_builder.SetContinueTarget(condition_label); | 582 loop_builder.SetContinueTarget(condition_label); |
| 563 } | 583 } |
| 564 | 584 |
| 565 | 585 |
| 566 void BytecodeGenerator::VisitWhileStatement(WhileStatement* stmt) { | 586 void BytecodeGenerator::VisitWhileStatement(WhileStatement* stmt) { |
| 567 LoopBuilder loop_builder(builder()); | 587 LoopBuilder loop_builder(builder()); |
| 568 ControlScopeForIteration execution_control(this, stmt, &loop_builder); | 588 ControlScopeForIteration execution_control(this, stmt, &loop_builder); |
| 569 | 589 |
| 570 BytecodeLabel body_label, condition_label, done_label; | 590 BytecodeLabel body_label, condition_label, done_label; |
| 571 builder()->Jump(&condition_label); | 591 if (stmt->cond()->ToBooleanIsFalse()) { |
| 592 // If the condition is false no need of generating the loop. | |
| 593 return; | |
|
mythria
2015/10/29 17:23:23
Here, I am not sure if we have to call builder().E
oth
2015/10/30 09:46:19
Definitely not necessary here.
| |
| 594 } | |
| 595 | |
| 596 if (!stmt->cond()->ToBooleanIsTrue()) { | |
| 597 builder()->Jump(&condition_label); | |
| 598 } | |
| 572 builder()->Bind(&body_label); | 599 builder()->Bind(&body_label); |
| 573 Visit(stmt->body()); | 600 Visit(stmt->body()); |
| 574 builder()->Bind(&condition_label); | 601 builder()->Bind(&condition_label); |
| 575 VisitForAccumulatorValue(stmt->cond()); | 602 if (stmt->cond()->ToBooleanIsTrue()) { |
| 576 builder()->JumpIfTrue(&body_label); | 603 builder()->Jump(&body_label); |
| 604 } else { | |
| 605 VisitForAccumulatorValue(stmt->cond()); | |
| 606 builder()->JumpIfTrue(&body_label); | |
| 607 } | |
| 577 builder()->Bind(&done_label); | 608 builder()->Bind(&done_label); |
| 578 | 609 |
| 579 loop_builder.SetBreakTarget(done_label); | 610 loop_builder.SetBreakTarget(done_label); |
| 580 loop_builder.SetContinueTarget(condition_label); | 611 loop_builder.SetContinueTarget(condition_label); |
| 581 } | 612 } |
| 582 | 613 |
| 583 | 614 |
| 584 void BytecodeGenerator::VisitForStatement(ForStatement* stmt) { | 615 void BytecodeGenerator::VisitForStatement(ForStatement* stmt) { |
| 585 LoopBuilder loop_builder(builder()); | 616 LoopBuilder loop_builder(builder()); |
| 586 ControlScopeForIteration execution_control(this, stmt, &loop_builder); | 617 ControlScopeForIteration execution_control(this, stmt, &loop_builder); |
| 587 | 618 |
| 588 if (stmt->init() != nullptr) { | 619 if (stmt->init() != nullptr) { |
| 589 Visit(stmt->init()); | 620 Visit(stmt->init()); |
| 590 } | 621 } |
| 591 | 622 |
| 623 if (stmt->cond() && stmt->cond()->ToBooleanIsFalse()) { | |
| 624 // If the condition is known to be false, no need of generating | |
|
oth
2015/10/30 09:46:19
s/no need of generating/there is no need to genera
mythria
2015/10/30 15:07:47
Done.
| |
| 625 // body, next or condition blocks. Init block should be generated. | |
| 626 return; | |
| 627 } | |
| 628 | |
| 592 BytecodeLabel body_label, condition_label, next_label, done_label; | 629 BytecodeLabel body_label, condition_label, next_label, done_label; |
| 593 if (stmt->cond() != nullptr) { | 630 if (stmt->cond() && !stmt->cond()->ToBooleanIsTrue()) { |
|
oth
2015/10/30 09:46:19
For readability I'd suggest using stmt->cond()->To
mythria
2015/10/30 15:07:47
!stmt->cond()->ToBooleanIsTrue could also mean tha
oth
2015/10/30 15:31:34
Sorry, yes, reader error.
| |
| 594 builder()->Jump(&condition_label); | 631 builder()->Jump(&condition_label); |
| 595 } | 632 } |
| 596 builder()->Bind(&body_label); | 633 builder()->Bind(&body_label); |
| 597 Visit(stmt->body()); | 634 Visit(stmt->body()); |
| 598 builder()->Bind(&next_label); | 635 builder()->Bind(&next_label); |
| 599 if (stmt->next() != nullptr) { | 636 if (stmt->next() != nullptr) { |
| 600 Visit(stmt->next()); | 637 Visit(stmt->next()); |
| 601 } | 638 } |
| 602 if (stmt->cond()) { | 639 if (stmt->cond() && !stmt->cond()->ToBooleanIsTrue()) { |
|
oth
2015/10/30 09:46:18
Ditto.
mythria
2015/10/30 15:07:47
Here, I changed the condition to avoid using !stmt
| |
| 603 builder()->Bind(&condition_label); | 640 builder()->Bind(&condition_label); |
| 604 VisitForAccumulatorValue(stmt->cond()); | 641 VisitForAccumulatorValue(stmt->cond()); |
| 605 builder()->JumpIfTrue(&body_label); | 642 builder()->JumpIfTrue(&body_label); |
| 606 } else { | 643 } else { |
| 607 builder()->Jump(&body_label); | 644 builder()->Jump(&body_label); |
| 608 } | 645 } |
| 609 builder()->Bind(&done_label); | 646 builder()->Bind(&done_label); |
| 610 | 647 |
| 611 loop_builder.SetBreakTarget(done_label); | 648 loop_builder.SetBreakTarget(done_label); |
| 612 loop_builder.SetContinueTarget(next_label); | 649 loop_builder.SetContinueTarget(next_label); |
| (...skipping 1334 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1947 } | 1984 } |
| 1948 | 1985 |
| 1949 | 1986 |
| 1950 int BytecodeGenerator::feedback_index(FeedbackVectorSlot slot) const { | 1987 int BytecodeGenerator::feedback_index(FeedbackVectorSlot slot) const { |
| 1951 return info()->feedback_vector()->GetIndex(slot); | 1988 return info()->feedback_vector()->GetIndex(slot); |
| 1952 } | 1989 } |
| 1953 | 1990 |
| 1954 } // namespace interpreter | 1991 } // namespace interpreter |
| 1955 } // namespace internal | 1992 } // namespace internal |
| 1956 } // namespace v8 | 1993 } // namespace v8 |
| OLD | NEW |