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

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: Fixes for 32-bit. 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 575 matching lines...) Expand 10 before | Expand all | Expand 10 after
586 } else { 586 } else {
587 builder()->Jump(&body_label); 587 builder()->Jump(&body_label);
588 } 588 }
589 builder()->Bind(&done_label); 589 builder()->Bind(&done_label);
590 590
591 loop_builder.SetBreakTarget(done_label); 591 loop_builder.SetBreakTarget(done_label);
592 loop_builder.SetContinueTarget(next_label); 592 loop_builder.SetContinueTarget(next_label);
593 } 593 }
594 594
595 595
596 void BytecodeGenerator::VisitForInAssignment(Expression* expr,
597 FeedbackVectorSlot slot) {
598 DCHECK(expr->IsValidReferenceExpression());
599
600 // Evaluate assignment starting with the value to be stored in the
601 // accumulator.
602 Property* property = expr->AsProperty();
603 LhsKind assign_type = Property::GetAssignType(property);
604 switch (assign_type) {
605 case VARIABLE: {
606 Variable* variable = expr->AsVariableProxy()->var();
607 VisitVariableAssignment(variable, slot);
608 break;
609 }
610 case NAMED_PROPERTY: {
611 TemporaryRegisterScope temporary_register_scope(builder());
612 Register value = temporary_register_scope.NewRegister();
rmcilroy 2015/10/26 14:04:01 nit - use expression_result()->NewRegister() ?
oth 2015/10/28 11:53:12 This would cause us to allocate an extra register
613 builder()->StoreAccumulatorInRegister(value);
614 Register object = VisitForRegisterValue(property->obj());
615 size_t name_index = builder()->GetConstantPoolEntry(
616 property->key()->AsLiteral()->AsPropertyName());
617 builder()->StoreNamedProperty(object, name_index, feedback_index(slot),
618 language_mode());
619 break;
620 }
621 case KEYED_PROPERTY: {
622 TemporaryRegisterScope temporary_register_scope(builder());
623 Register value = temporary_register_scope.NewRegister();
rmcilroy 2015/10/26 14:04:01 ditto
oth 2015/10/28 11:53:12 This would cause us to allocate an extra register
624 builder()->StoreAccumulatorInRegister(value);
625 Register object = VisitForRegisterValue(property->obj());
626 Register key = VisitForRegisterValue(property->key());
627 builder()->LoadAccumulatorWithRegister(value);
628 builder()->StoreKeyedProperty(object, key, feedback_index(slot),
629 language_mode());
630 break;
631 }
632 case NAMED_SUPER_PROPERTY:
633 case KEYED_SUPER_PROPERTY:
634 UNIMPLEMENTED();
635 }
636 }
637
638
596 void BytecodeGenerator::VisitForInStatement(ForInStatement* stmt) { 639 void BytecodeGenerator::VisitForInStatement(ForInStatement* stmt) {
597 UNIMPLEMENTED(); 640 EffectResultScope result_scope(this);
rmcilroy 2015/10/26 14:04:01 Is this needed? Shouldn't we just be using VisitFo
oth 2015/10/28 11:53:12 This is needed. RegisterResultScope can allocate a
641
642 if (stmt->subject()->IsNullLiteral() ||
643 stmt->subject()->IsUndefinedLiteral(isolate())) {
644 // ForIn generates lots of code, skip if it wouldn't produce any effects.
645 return;
646 }
647
648 TemporaryRegisterScope temporary_register_scope(builder());
649 LoopBuilder loop_builder(builder());
650 ControlScopeForIteration control_scope(this, stmt, &loop_builder);
651
652 // Prepare the state for executing ForIn.
653 builder()->EnterBlock();
654 VisitForAccumulatorValue(stmt->subject());
655 builder()->ForInPrepare();
656 Register for_in_state = temporary_register_scope.NewRegister();
rmcilroy 2015/10/26 14:04:01 nit - move this up (and use execution_result()->Ne
oth 2015/10/28 11:53:11 Done.
657 builder()->StoreAccumulatorInRegister(for_in_state);
rmcilroy 2015/10/26 14:04:01 nit - use builder chaining?
oth 2015/10/28 11:53:11 Done-ish. Changed to chain in blocks that are logi
658 builder()->LoadUndefined();
659 builder()->CompareOperation(Token::Value::EQ_STRICT, for_in_state,
660 Strength::WEAK);
rmcilroy 2015/10/26 14:04:01 /s/Strength::WEAK/language_mode_strength()
oth 2015/10/28 11:53:12 Done.
661 loop_builder.BreakIfTrue();
662
663 // The loop
rmcilroy 2015/10/26 14:04:01 nit -full stop
oth 2015/10/28 11:53:11 Done.
664 BytecodeLabel condition_label, break_label, continue_label;
665
666 Register index = temporary_register_scope.NewRegister();
667 builder()->LoadLiteral(Smi::FromInt(0));
668 builder()->StoreAccumulatorInRegister(index);
669
670 // Check loop termination (accumulator holds index).
671 builder()->Bind(&condition_label);
672 builder()->ForInDone(for_in_state);
673 loop_builder.BreakIfTrue();
674
675 // Get next item
rmcilroy 2015/10/26 14:04:01 nit - full stop
oth 2015/10/28 11:53:11 Done.
676 builder()->LoadAccumulatorWithRegister(index);
677 builder()->ForInNext(for_in_state);
678
679 // Start again if item is undefined.
680 Register value = temporary_register_scope.NewRegister();
681 builder()->StoreAccumulatorInRegister(value);
682 builder()->LoadUndefined();
rmcilroy 2015/10/26 14:04:01 Would it be worth maintaining a temprorary registe
oth 2015/10/28 11:53:11 This is superb! Done.
683 builder()->CompareOperation(Token::Value::EQ_STRICT, value, Strength::WEAK);
684 loop_builder.ContinueIfTrue();
685 builder()->LoadAccumulatorWithRegister(value);
686
687 // Store the value in the each variable.
688 VisitForInAssignment(stmt->each(), stmt->EachFeedbackSlot());
689 // NB the user's loop variable will be assigned the value of each so
690 // even an empty body will have this assignment.
691 Visit(stmt->body());
692
693 // Increment index and start loop again.
694 builder()->Bind(&continue_label);
695 builder()->LoadLiteral(Smi::FromInt(1));
696 builder()->BinaryOperation(Token::Value::ADD, index, Strength::WEAK);
rmcilroy 2015/10/26 14:04:01 You could use builder()->CountOperation(Token::Val
oth 2015/10/28 11:53:12 Done.
697 builder()->StoreAccumulatorInRegister(index);
698 builder()->Jump(&condition_label);
699
700 // End of loop
701 builder()->Bind(&break_label);
702 builder()->LeaveBlock();
703
704 loop_builder.SetBreakTarget(break_label);
705 loop_builder.SetContinueTarget(continue_label);
598 } 706 }
599 707
600 708
601 void BytecodeGenerator::VisitForOfStatement(ForOfStatement* stmt) { 709 void BytecodeGenerator::VisitForOfStatement(ForOfStatement* stmt) {
602 UNIMPLEMENTED(); 710 UNIMPLEMENTED();
603 } 711 }
604 712
605 713
606 void BytecodeGenerator::VisitTryCatchStatement(TryCatchStatement* stmt) { 714 void BytecodeGenerator::VisitTryCatchStatement(TryCatchStatement* stmt) {
607 if (FLAG_ignition_fake_try_catch) { 715 if (FLAG_ignition_fake_try_catch) {
(...skipping 1208 matching lines...) Expand 10 before | Expand all | Expand 10 after
1816 } 1924 }
1817 1925
1818 1926
1819 int BytecodeGenerator::feedback_index(FeedbackVectorSlot slot) const { 1927 int BytecodeGenerator::feedback_index(FeedbackVectorSlot slot) const {
1820 return info()->feedback_vector()->GetIndex(slot); 1928 return info()->feedback_vector()->GetIndex(slot);
1821 } 1929 }
1822 1930
1823 } // namespace interpreter 1931 } // namespace interpreter
1824 } // namespace internal 1932 } // namespace internal
1825 } // namespace v8 1933 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698