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); |
| 866 BytecodeLabel subject_null_label, subject_undefined_label, not_object_label; |
867 | 867 |
868 // Prepare the state for executing ForIn. | 868 // Prepare the state for executing ForIn. |
869 VisitForAccumulatorValue(stmt->subject()); | 869 VisitForAccumulatorValue(stmt->subject()); |
870 loop_builder.BreakIfUndefined(); | 870 builder()->JumpIfUndefined(&subject_undefined_label); |
871 loop_builder.BreakIfNull(); | 871 builder()->JumpIfNull(&subject_null_label); |
872 | |
873 Register receiver = execution_result()->NewRegister(); | 872 Register receiver = execution_result()->NewRegister(); |
874 builder()->CastAccumulatorToJSObject(); | 873 builder()->CastAccumulatorToJSObject(); |
| 874 builder()->JumpIfNull(¬_object_label); |
875 builder()->StoreAccumulatorInRegister(receiver); | 875 builder()->StoreAccumulatorInRegister(receiver); |
876 builder()->CallRuntime(Runtime::kGetPropertyNamesFast, receiver, 1); | 876 Register cache_type = execution_result()->NewRegister(); |
877 builder()->ForInPrepare(receiver); | 877 Register cache_array = execution_result()->NewRegister(); |
878 loop_builder.BreakIfUndefined(); | 878 Register cache_length = execution_result()->NewRegister(); |
| 879 builder()->ForInPrepare(cache_type, cache_array, cache_length); |
879 | 880 |
880 Register for_in_state = execution_result()->NewRegister(); | 881 // Set up loop counter |
881 builder()->StoreAccumulatorInRegister(for_in_state); | 882 Register index = execution_result()->NewRegister(); |
| 883 builder()->LoadLiteral(Smi::FromInt(0)); |
| 884 builder()->StoreAccumulatorInRegister(index); |
882 | 885 |
883 // Check loop termination (accumulator holds index). | 886 // The loop |
884 Register index = receiver; // Re-using register as receiver no longer used. | |
885 builder()->LoadLiteral(Smi::FromInt(0)); | |
886 loop_builder.LoopHeader(); | 887 loop_builder.LoopHeader(); |
887 loop_builder.Condition(); | 888 loop_builder.Condition(); |
888 builder()->StoreAccumulatorInRegister(index).ForInDone(for_in_state); | 889 builder()->ForInDone(index, cache_length); |
889 loop_builder.BreakIfTrue(); | 890 loop_builder.BreakIfTrue(); |
890 builder()->ForInNext(for_in_state, index); | 891 builder()->ForInNext(receiver, cache_type, cache_array, index); |
891 loop_builder.ContinueIfUndefined(); | 892 loop_builder.ContinueIfUndefined(); |
892 | |
893 VisitForInAssignment(stmt->each(), stmt->EachFeedbackSlot()); | 893 VisitForInAssignment(stmt->each(), stmt->EachFeedbackSlot()); |
894 Visit(stmt->body()); | 894 Visit(stmt->body()); |
895 | |
896 // TODO(oth): replace CountOperation here with ForInStep. | |
897 loop_builder.Next(); | 895 loop_builder.Next(); |
898 builder()->LoadAccumulatorWithRegister(index).CountOperation( | 896 builder()->ForInStep(index); |
899 Token::Value::ADD, language_mode_strength()); | 897 builder()->StoreAccumulatorInRegister(index); |
900 loop_builder.JumpToHeader(); | 898 loop_builder.JumpToHeader(); |
901 loop_builder.EndLoop(); | 899 loop_builder.EndLoop(); |
| 900 builder()->Bind(¬_object_label); |
| 901 builder()->Bind(&subject_null_label); |
| 902 builder()->Bind(&subject_undefined_label); |
902 } | 903 } |
903 | 904 |
904 | 905 |
905 void BytecodeGenerator::VisitForOfStatement(ForOfStatement* stmt) { | 906 void BytecodeGenerator::VisitForOfStatement(ForOfStatement* stmt) { |
906 UNIMPLEMENTED(); | 907 UNIMPLEMENTED(); |
907 } | 908 } |
908 | 909 |
909 | 910 |
910 void BytecodeGenerator::VisitTryCatchStatement(TryCatchStatement* stmt) { | 911 void BytecodeGenerator::VisitTryCatchStatement(TryCatchStatement* stmt) { |
911 if (FLAG_ignition_fake_try_catch) { | 912 if (FLAG_ignition_fake_try_catch) { |
(...skipping 1295 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2207 } | 2208 } |
2208 | 2209 |
2209 | 2210 |
2210 int BytecodeGenerator::feedback_index(FeedbackVectorSlot slot) const { | 2211 int BytecodeGenerator::feedback_index(FeedbackVectorSlot slot) const { |
2211 return info()->feedback_vector()->GetIndex(slot); | 2212 return info()->feedback_vector()->GetIndex(slot); |
2212 } | 2213 } |
2213 | 2214 |
2214 } // namespace interpreter | 2215 } // namespace interpreter |
2215 } // namespace internal | 2216 } // namespace internal |
2216 } // namespace v8 | 2217 } // namespace v8 |
OLD | NEW |