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/ast/scopes.h" | 7 #include "src/ast/scopes.h" |
8 #include "src/compiler.h" | 8 #include "src/compiler.h" |
9 #include "src/interpreter/control-flow-builders.h" | 9 #include "src/interpreter/control-flow-builders.h" |
10 #include "src/objects.h" | 10 #include "src/objects.h" |
(...skipping 837 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
848 } | 848 } |
849 case NAMED_SUPER_PROPERTY: | 849 case NAMED_SUPER_PROPERTY: |
850 case KEYED_SUPER_PROPERTY: | 850 case KEYED_SUPER_PROPERTY: |
851 UNIMPLEMENTED(); | 851 UNIMPLEMENTED(); |
852 } | 852 } |
853 } | 853 } |
854 | 854 |
855 | 855 |
856 void BytecodeGenerator::VisitForInStatement(ForInStatement* stmt) { | 856 void BytecodeGenerator::VisitForInStatement(ForInStatement* stmt) { |
857 EffectResultScope statement_result_scope(this); | 857 EffectResultScope statement_result_scope(this); |
858 | |
859 if (stmt->subject()->IsNullLiteral() || | 858 if (stmt->subject()->IsNullLiteral() || |
860 stmt->subject()->IsUndefinedLiteral(isolate())) { | 859 stmt->subject()->IsUndefinedLiteral(isolate())) { |
861 // ForIn generates lots of code, skip if it wouldn't produce any effects. | 860 // ForIn generates lots of code, skip if it wouldn't produce any effects. |
862 return; | 861 return; |
863 } | 862 } |
864 | 863 |
865 LoopBuilder loop_builder(builder()); | 864 LoopBuilder loop_builder(builder()); |
866 ControlScopeForIteration control_scope(this, stmt, &loop_builder); | 865 ControlScopeForIteration control_scope(this, stmt, &loop_builder); |
867 | 866 |
868 // Prepare the state for executing ForIn. | 867 // Prepare the state for executing ForIn. |
869 VisitForAccumulatorValue(stmt->subject()); | 868 VisitForAccumulatorValue(stmt->subject()); |
870 loop_builder.BreakIfUndefined(); | 869 loop_builder.BreakIfUndefined(); |
871 loop_builder.BreakIfNull(); | 870 loop_builder.BreakIfNull(); |
872 | |
873 Register receiver = execution_result()->NewRegister(); | 871 Register receiver = execution_result()->NewRegister(); |
874 builder()->CastAccumulatorToJSObject(); | 872 builder()->CastAccumulatorToJSObject(); |
| 873 loop_builder.BreakIfNull(); |
875 builder()->StoreAccumulatorInRegister(receiver); | 874 builder()->StoreAccumulatorInRegister(receiver); |
876 builder()->CallRuntime(Runtime::kGetPropertyNamesFast, receiver, 1); | 875 Register cache_type = execution_result()->NewRegister(); |
877 builder()->ForInPrepare(receiver); | 876 Register cache_array = execution_result()->NewRegister(); |
878 loop_builder.BreakIfUndefined(); | 877 Register cache_length = execution_result()->NewRegister(); |
879 | 878 builder()->ForInPrepare(receiver, cache_type, cache_array, cache_length); |
880 Register for_in_state = execution_result()->NewRegister(); | |
881 builder()->StoreAccumulatorInRegister(for_in_state); | |
882 | 879 |
883 // Check loop termination (accumulator holds index). | 880 // Check loop termination (accumulator holds index). |
884 Register index = receiver; // Re-using register as receiver no longer used. | 881 Register index = execution_result()->NewRegister(); |
885 builder()->LoadLiteral(Smi::FromInt(0)); | 882 builder()->LoadLiteral(Smi::FromInt(0)); |
| 883 builder()->StoreAccumulatorInRegister(index); |
886 loop_builder.LoopHeader(); | 884 loop_builder.LoopHeader(); |
887 loop_builder.Condition(); | 885 loop_builder.Condition(); |
888 builder()->StoreAccumulatorInRegister(index).ForInDone(for_in_state); | 886 builder()->ForInDone(index, cache_length); |
889 loop_builder.BreakIfTrue(); | 887 loop_builder.BreakIfTrue(); |
890 builder()->ForInNext(for_in_state, index); | 888 builder()->ForInNext(receiver, cache_type, cache_array, index); |
891 loop_builder.ContinueIfUndefined(); | 889 loop_builder.ContinueIfUndefined(); |
892 | |
893 VisitForInAssignment(stmt->each(), stmt->EachFeedbackSlot()); | 890 VisitForInAssignment(stmt->each(), stmt->EachFeedbackSlot()); |
894 Visit(stmt->body()); | 891 Visit(stmt->body()); |
895 | |
896 // TODO(oth): replace CountOperation here with ForInStep. | |
897 loop_builder.Next(); | 892 loop_builder.Next(); |
898 builder()->LoadAccumulatorWithRegister(index).CountOperation( | 893 builder()->ForInStep(index); |
899 Token::Value::ADD, language_mode_strength()); | |
900 loop_builder.JumpToHeader(); | 894 loop_builder.JumpToHeader(); |
901 loop_builder.EndLoop(); | 895 loop_builder.EndLoop(); |
902 } | 896 } |
903 | 897 |
904 | 898 |
905 void BytecodeGenerator::VisitForOfStatement(ForOfStatement* stmt) { | 899 void BytecodeGenerator::VisitForOfStatement(ForOfStatement* stmt) { |
906 UNIMPLEMENTED(); | 900 UNIMPLEMENTED(); |
907 } | 901 } |
908 | 902 |
909 | 903 |
(...skipping 1297 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2207 } | 2201 } |
2208 | 2202 |
2209 | 2203 |
2210 int BytecodeGenerator::feedback_index(FeedbackVectorSlot slot) const { | 2204 int BytecodeGenerator::feedback_index(FeedbackVectorSlot slot) const { |
2211 return info()->feedback_vector()->GetIndex(slot); | 2205 return info()->feedback_vector()->GetIndex(slot); |
2212 } | 2206 } |
2213 | 2207 |
2214 } // namespace interpreter | 2208 } // namespace interpreter |
2215 } // namespace internal | 2209 } // namespace internal |
2216 } // namespace v8 | 2210 } // namespace v8 |
OLD | NEW |