Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1201)

Side by Side Diff: src/interpreter/bytecode-generator.cc

Issue 1422033002: [Interpreter] Add support for for..in. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Comment nits. Created 5 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 595 matching lines...) Expand 10 before | Expand all | Expand 10 after
606 } else { 606 } else {
607 builder()->Jump(&body_label); 607 builder()->Jump(&body_label);
608 } 608 }
609 builder()->Bind(&done_label); 609 builder()->Bind(&done_label);
610 610
611 loop_builder.SetBreakTarget(done_label); 611 loop_builder.SetBreakTarget(done_label);
612 loop_builder.SetContinueTarget(next_label); 612 loop_builder.SetContinueTarget(next_label);
613 } 613 }
614 614
615 615
616 void BytecodeGenerator::VisitForInAssignment(Expression* expr,
617 FeedbackVectorSlot slot) {
618 DCHECK(expr->IsValidReferenceExpression());
619
620 // Evaluate assignment starting with the value to be stored in the
621 // accumulator.
622 Property* property = expr->AsProperty();
623 LhsKind assign_type = Property::GetAssignType(property);
624 switch (assign_type) {
625 case VARIABLE: {
626 Variable* variable = expr->AsVariableProxy()->var();
627 VisitVariableAssignment(variable, slot);
628 break;
629 }
630 case NAMED_PROPERTY: {
631 TemporaryRegisterScope temporary_register_scope(builder());
632 Register value = temporary_register_scope.NewRegister();
633 builder()->StoreAccumulatorInRegister(value);
634 Register object = VisitForRegisterValue(property->obj());
635 size_t name_index = builder()->GetConstantPoolEntry(
636 property->key()->AsLiteral()->AsPropertyName());
637 builder()->StoreNamedProperty(object, name_index, feedback_index(slot),
638 language_mode());
639 break;
640 }
641 case KEYED_PROPERTY: {
642 TemporaryRegisterScope temporary_register_scope(builder());
643 Register value = temporary_register_scope.NewRegister();
644 builder()->StoreAccumulatorInRegister(value);
645 Register object = VisitForRegisterValue(property->obj());
646 Register key = VisitForRegisterValue(property->key());
647 builder()->LoadAccumulatorWithRegister(value);
648 builder()->StoreKeyedProperty(object, key, feedback_index(slot),
649 language_mode());
650 break;
651 }
652 case NAMED_SUPER_PROPERTY:
653 case KEYED_SUPER_PROPERTY:
654 UNIMPLEMENTED();
655 }
656 }
657
658
616 void BytecodeGenerator::VisitForInStatement(ForInStatement* stmt) { 659 void BytecodeGenerator::VisitForInStatement(ForInStatement* stmt) {
617 UNIMPLEMENTED(); 660 // TODO(oth): For now we need a parent scope for paths that end up
661 // in VisitLiteral which can allocate in the parent scope. A future
662 // CL in preparation will add a StatementResultScope that will
663 // remove the need for this EffectResultScope.
664 EffectResultScope result_scope(this);
665
666 if (stmt->subject()->IsNullLiteral() ||
667 stmt->subject()->IsUndefinedLiteral(isolate())) {
668 // ForIn generates lots of code, skip if it wouldn't produce any effects.
669 return;
670 }
671
672 LoopBuilder loop_builder(builder());
673 ControlScopeForIteration control_scope(this, stmt, &loop_builder);
674
675 // Prepare the state for executing ForIn.
676 builder()->EnterBlock();
677 VisitForAccumulatorValue(stmt->subject());
678 loop_builder.BreakIfUndefined();
679 loop_builder.BreakIfNull();
680
681 Register receiver = execution_result()->NewRegister();
682 builder()->CastAccumulatorToJSObject();
683 builder()->StoreAccumulatorInRegister(receiver);
684 builder()->CallRuntime(Runtime::kGetPropertyNamesFast, receiver, 1);
685 builder()->ForInPrepare(receiver);
686 loop_builder.BreakIfUndefined();
687
688 Register for_in_state = execution_result()->NewRegister();
689 builder()->StoreAccumulatorInRegister(for_in_state);
690
691 // The loop.
692 BytecodeLabel condition_label, break_label, continue_label;
693 Register index = receiver; // Re-using register as receiver no longer used.
694 builder()->LoadLiteral(Smi::FromInt(0));
695
696 // Check loop termination (accumulator holds index).
697 builder()
698 ->Bind(&condition_label)
699 .StoreAccumulatorInRegister(index)
700 .ForInDone(for_in_state);
701 loop_builder.BreakIfTrue();
702
703 // Get the next item.
704 builder()->ForInNext(for_in_state, index);
705
706 // Start again if the item, currently in the accumulator, is undefined.
707 loop_builder.ContinueIfUndefined();
708
709 // Store the value in the each variable.
710 VisitForInAssignment(stmt->each(), stmt->EachFeedbackSlot());
711 // NB the user's loop variable will be assigned the value of each so
712 // even an empty body will have this assignment.
713 Visit(stmt->body());
714
715 // Increment the index and start loop again.
716 builder()
717 ->Bind(&continue_label)
718 .LoadAccumulatorWithRegister(index)
719 .CountOperation(Token::Value::ADD, language_mode_strength())
720 .Jump(&condition_label);
721
722 // End of loop
723 builder()->Bind(&break_label).LeaveBlock();
724
725 loop_builder.SetBreakTarget(break_label);
726 loop_builder.SetContinueTarget(continue_label);
618 } 727 }
619 728
620 729
621 void BytecodeGenerator::VisitForOfStatement(ForOfStatement* stmt) { 730 void BytecodeGenerator::VisitForOfStatement(ForOfStatement* stmt) {
622 UNIMPLEMENTED(); 731 UNIMPLEMENTED();
623 } 732 }
624 733
625 734
626 void BytecodeGenerator::VisitTryCatchStatement(TryCatchStatement* stmt) { 735 void BytecodeGenerator::VisitTryCatchStatement(TryCatchStatement* stmt) {
627 if (FLAG_ignition_fake_try_catch) { 736 if (FLAG_ignition_fake_try_catch) {
(...skipping 1319 matching lines...) Expand 10 before | Expand all | Expand 10 after
1947 } 2056 }
1948 2057
1949 2058
1950 int BytecodeGenerator::feedback_index(FeedbackVectorSlot slot) const { 2059 int BytecodeGenerator::feedback_index(FeedbackVectorSlot slot) const {
1951 return info()->feedback_vector()->GetIndex(slot); 2060 return info()->feedback_vector()->GetIndex(slot);
1952 } 2061 }
1953 2062
1954 } // namespace interpreter 2063 } // namespace interpreter
1955 } // namespace internal 2064 } // namespace internal
1956 } // namespace v8 2065 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698