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 |