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 |