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/bytecode-register-allocator.h" | 9 #include "src/interpreter/bytecode-register-allocator.h" |
10 #include "src/interpreter/control-flow-builders.h" | 10 #include "src/interpreter/control-flow-builders.h" |
(...skipping 853 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
864 } | 864 } |
865 | 865 |
866 | 866 |
867 void BytecodeGenerator::VisitSloppyBlockFunctionStatement( | 867 void BytecodeGenerator::VisitSloppyBlockFunctionStatement( |
868 SloppyBlockFunctionStatement* stmt) { | 868 SloppyBlockFunctionStatement* stmt) { |
869 Visit(stmt->statement()); | 869 Visit(stmt->statement()); |
870 } | 870 } |
871 | 871 |
872 | 872 |
873 void BytecodeGenerator::VisitContinueStatement(ContinueStatement* stmt) { | 873 void BytecodeGenerator::VisitContinueStatement(ContinueStatement* stmt) { |
| 874 builder()->SetStatementPosition(stmt); |
874 execution_control()->Continue(stmt->target()); | 875 execution_control()->Continue(stmt->target()); |
875 } | 876 } |
876 | 877 |
877 | 878 |
878 void BytecodeGenerator::VisitBreakStatement(BreakStatement* stmt) { | 879 void BytecodeGenerator::VisitBreakStatement(BreakStatement* stmt) { |
| 880 builder()->SetStatementPosition(stmt); |
879 execution_control()->Break(stmt->target()); | 881 execution_control()->Break(stmt->target()); |
880 } | 882 } |
881 | 883 |
882 | 884 |
883 void BytecodeGenerator::VisitReturnStatement(ReturnStatement* stmt) { | 885 void BytecodeGenerator::VisitReturnStatement(ReturnStatement* stmt) { |
884 builder()->SetStatementPosition(stmt); | 886 builder()->SetStatementPosition(stmt); |
885 VisitForAccumulatorValue(stmt->expression()); | 887 VisitForAccumulatorValue(stmt->expression()); |
886 execution_control()->ReturnAccumulator(); | 888 execution_control()->ReturnAccumulator(); |
887 } | 889 } |
888 | 890 |
889 | 891 |
890 void BytecodeGenerator::VisitWithStatement(WithStatement* stmt) { | 892 void BytecodeGenerator::VisitWithStatement(WithStatement* stmt) { |
| 893 builder()->SetStatementPosition(stmt); |
891 VisitForAccumulatorValue(stmt->expression()); | 894 VisitForAccumulatorValue(stmt->expression()); |
892 builder()->CastAccumulatorToJSObject(); | 895 builder()->CastAccumulatorToJSObject(); |
893 VisitNewLocalWithContext(); | 896 VisitNewLocalWithContext(); |
894 VisitInScope(stmt->statement(), stmt->scope()); | 897 VisitInScope(stmt->statement(), stmt->scope()); |
895 } | 898 } |
896 | 899 |
897 | 900 |
898 void BytecodeGenerator::VisitSwitchStatement(SwitchStatement* stmt) { | 901 void BytecodeGenerator::VisitSwitchStatement(SwitchStatement* stmt) { |
899 // We need this scope because we visit for register values. We have to | 902 // We need this scope because we visit for register values. We have to |
900 // maintain a execution result scope where registers can be allocated. | 903 // maintain a execution result scope where registers can be allocated. |
901 ZoneList<CaseClause*>* clauses = stmt->cases(); | 904 ZoneList<CaseClause*>* clauses = stmt->cases(); |
902 SwitchBuilder switch_builder(builder(), clauses->length()); | 905 SwitchBuilder switch_builder(builder(), clauses->length()); |
903 ControlScopeForBreakable scope(this, stmt, &switch_builder); | 906 ControlScopeForBreakable scope(this, stmt, &switch_builder); |
904 int default_index = -1; | 907 int default_index = -1; |
905 | 908 |
| 909 builder()->SetStatementPosition(stmt); |
| 910 |
906 // Keep the switch value in a register until a case matches. | 911 // Keep the switch value in a register until a case matches. |
907 Register tag = VisitForRegisterValue(stmt->tag()); | 912 Register tag = VisitForRegisterValue(stmt->tag()); |
908 | 913 |
909 // Iterate over all cases and create nodes for label comparison. | 914 // Iterate over all cases and create nodes for label comparison. |
910 BytecodeLabel done_label; | 915 BytecodeLabel done_label; |
911 for (int i = 0; i < clauses->length(); i++) { | 916 for (int i = 0; i < clauses->length(); i++) { |
912 CaseClause* clause = clauses->at(i); | 917 CaseClause* clause = clauses->at(i); |
913 | 918 |
914 // The default is not a test, remember index. | 919 // The default is not a test, remember index. |
915 if (clause->is_default()) { | 920 if (clause->is_default()) { |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
950 } | 955 } |
951 | 956 |
952 void BytecodeGenerator::VisitIterationBody(IterationStatement* stmt, | 957 void BytecodeGenerator::VisitIterationBody(IterationStatement* stmt, |
953 LoopBuilder* loop_builder) { | 958 LoopBuilder* loop_builder) { |
954 ControlScopeForIteration execution_control(this, stmt, loop_builder); | 959 ControlScopeForIteration execution_control(this, stmt, loop_builder); |
955 builder()->StackCheck(); | 960 builder()->StackCheck(); |
956 Visit(stmt->body()); | 961 Visit(stmt->body()); |
957 } | 962 } |
958 | 963 |
959 void BytecodeGenerator::VisitDoWhileStatement(DoWhileStatement* stmt) { | 964 void BytecodeGenerator::VisitDoWhileStatement(DoWhileStatement* stmt) { |
| 965 builder()->SetStatementPosition(stmt); |
960 LoopBuilder loop_builder(builder()); | 966 LoopBuilder loop_builder(builder()); |
961 loop_builder.LoopHeader(); | 967 loop_builder.LoopHeader(); |
962 if (stmt->cond()->ToBooleanIsFalse()) { | 968 if (stmt->cond()->ToBooleanIsFalse()) { |
963 VisitIterationBody(stmt, &loop_builder); | 969 VisitIterationBody(stmt, &loop_builder); |
964 loop_builder.Condition(); | 970 loop_builder.Condition(); |
965 } else if (stmt->cond()->ToBooleanIsTrue()) { | 971 } else if (stmt->cond()->ToBooleanIsTrue()) { |
966 loop_builder.Condition(); | 972 loop_builder.Condition(); |
967 VisitIterationBody(stmt, &loop_builder); | 973 VisitIterationBody(stmt, &loop_builder); |
968 loop_builder.JumpToHeader(); | 974 loop_builder.JumpToHeader(); |
969 } else { | 975 } else { |
970 VisitIterationBody(stmt, &loop_builder); | 976 VisitIterationBody(stmt, &loop_builder); |
971 loop_builder.Condition(); | 977 loop_builder.Condition(); |
| 978 builder()->SetExpressionAsStatementPosition(stmt->cond()); |
972 VisitForAccumulatorValue(stmt->cond()); | 979 VisitForAccumulatorValue(stmt->cond()); |
973 loop_builder.JumpToHeaderIfTrue(); | 980 loop_builder.JumpToHeaderIfTrue(); |
974 } | 981 } |
975 loop_builder.EndLoop(); | 982 loop_builder.EndLoop(); |
976 } | 983 } |
977 | 984 |
978 void BytecodeGenerator::VisitWhileStatement(WhileStatement* stmt) { | 985 void BytecodeGenerator::VisitWhileStatement(WhileStatement* stmt) { |
979 if (stmt->cond()->ToBooleanIsFalse()) { | 986 if (stmt->cond()->ToBooleanIsFalse()) { |
980 // If the condition is false there is no need to generate the loop. | 987 // If the condition is false there is no need to generate the loop. |
981 return; | 988 return; |
982 } | 989 } |
983 | 990 |
984 LoopBuilder loop_builder(builder()); | 991 LoopBuilder loop_builder(builder()); |
985 loop_builder.LoopHeader(); | 992 loop_builder.LoopHeader(); |
986 loop_builder.Condition(); | 993 loop_builder.Condition(); |
987 if (!stmt->cond()->ToBooleanIsTrue()) { | 994 if (!stmt->cond()->ToBooleanIsTrue()) { |
| 995 builder()->SetExpressionAsStatementPosition(stmt->cond()); |
988 VisitForAccumulatorValue(stmt->cond()); | 996 VisitForAccumulatorValue(stmt->cond()); |
989 loop_builder.BreakIfFalse(); | 997 loop_builder.BreakIfFalse(); |
990 } | 998 } |
991 VisitIterationBody(stmt, &loop_builder); | 999 VisitIterationBody(stmt, &loop_builder); |
992 loop_builder.JumpToHeader(); | 1000 loop_builder.JumpToHeader(); |
993 loop_builder.EndLoop(); | 1001 loop_builder.EndLoop(); |
994 } | 1002 } |
995 | 1003 |
996 | 1004 |
997 void BytecodeGenerator::VisitForStatement(ForStatement* stmt) { | 1005 void BytecodeGenerator::VisitForStatement(ForStatement* stmt) { |
998 if (stmt->init() != nullptr) { | 1006 if (stmt->init() != nullptr) { |
| 1007 builder()->SetStatementPosition(stmt->init()); |
999 Visit(stmt->init()); | 1008 Visit(stmt->init()); |
1000 } | 1009 } |
1001 if (stmt->cond() && stmt->cond()->ToBooleanIsFalse()) { | 1010 if (stmt->cond() && stmt->cond()->ToBooleanIsFalse()) { |
1002 // If the condition is known to be false there is no need to generate | 1011 // If the condition is known to be false there is no need to generate |
1003 // body, next or condition blocks. Init block should be generated. | 1012 // body, next or condition blocks. Init block should be generated. |
1004 return; | 1013 return; |
1005 } | 1014 } |
1006 | 1015 |
1007 LoopBuilder loop_builder(builder()); | 1016 LoopBuilder loop_builder(builder()); |
1008 loop_builder.LoopHeader(); | 1017 loop_builder.LoopHeader(); |
1009 loop_builder.Condition(); | 1018 loop_builder.Condition(); |
1010 if (stmt->cond() && !stmt->cond()->ToBooleanIsTrue()) { | 1019 if (stmt->cond() && !stmt->cond()->ToBooleanIsTrue()) { |
| 1020 builder()->SetExpressionAsStatementPosition(stmt->cond()); |
1011 VisitForAccumulatorValue(stmt->cond()); | 1021 VisitForAccumulatorValue(stmt->cond()); |
1012 loop_builder.BreakIfFalse(); | 1022 loop_builder.BreakIfFalse(); |
1013 } | 1023 } |
1014 VisitIterationBody(stmt, &loop_builder); | 1024 VisitIterationBody(stmt, &loop_builder); |
1015 if (stmt->next() != nullptr) { | 1025 if (stmt->next() != nullptr) { |
1016 loop_builder.Next(); | 1026 loop_builder.Next(); |
| 1027 builder()->SetStatementPosition(stmt->next()); |
1017 Visit(stmt->next()); | 1028 Visit(stmt->next()); |
1018 } | 1029 } |
1019 loop_builder.JumpToHeader(); | 1030 loop_builder.JumpToHeader(); |
1020 loop_builder.EndLoop(); | 1031 loop_builder.EndLoop(); |
1021 } | 1032 } |
1022 | 1033 |
1023 | 1034 |
1024 void BytecodeGenerator::VisitForInAssignment(Expression* expr, | 1035 void BytecodeGenerator::VisitForInAssignment(Expression* expr, |
1025 FeedbackVectorSlot slot) { | 1036 FeedbackVectorSlot slot) { |
1026 DCHECK(expr->IsValidReferenceExpression()); | 1037 DCHECK(expr->IsValidReferenceExpression()); |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1099 if (stmt->subject()->IsNullLiteral() || | 1110 if (stmt->subject()->IsNullLiteral() || |
1100 stmt->subject()->IsUndefinedLiteral(isolate())) { | 1111 stmt->subject()->IsUndefinedLiteral(isolate())) { |
1101 // ForIn generates lots of code, skip if it wouldn't produce any effects. | 1112 // ForIn generates lots of code, skip if it wouldn't produce any effects. |
1102 return; | 1113 return; |
1103 } | 1114 } |
1104 | 1115 |
1105 LoopBuilder loop_builder(builder()); | 1116 LoopBuilder loop_builder(builder()); |
1106 BytecodeLabel subject_null_label, subject_undefined_label; | 1117 BytecodeLabel subject_null_label, subject_undefined_label; |
1107 | 1118 |
1108 // Prepare the state for executing ForIn. | 1119 // Prepare the state for executing ForIn. |
| 1120 builder()->SetExpressionAsStatementPosition(stmt->subject()); |
1109 VisitForAccumulatorValue(stmt->subject()); | 1121 VisitForAccumulatorValue(stmt->subject()); |
1110 builder()->JumpIfUndefined(&subject_undefined_label); | 1122 builder()->JumpIfUndefined(&subject_undefined_label); |
1111 builder()->JumpIfNull(&subject_null_label); | 1123 builder()->JumpIfNull(&subject_null_label); |
1112 Register receiver = register_allocator()->NewRegister(); | 1124 Register receiver = register_allocator()->NewRegister(); |
1113 builder()->CastAccumulatorToJSObject(); | 1125 builder()->CastAccumulatorToJSObject(); |
1114 builder()->StoreAccumulatorInRegister(receiver); | 1126 builder()->StoreAccumulatorInRegister(receiver); |
1115 | 1127 |
1116 register_allocator()->PrepareForConsecutiveAllocations(3); | 1128 register_allocator()->PrepareForConsecutiveAllocations(3); |
1117 Register cache_type = register_allocator()->NextConsecutiveRegister(); | 1129 Register cache_type = register_allocator()->NextConsecutiveRegister(); |
1118 Register cache_array = register_allocator()->NextConsecutiveRegister(); | 1130 Register cache_array = register_allocator()->NextConsecutiveRegister(); |
1119 Register cache_length = register_allocator()->NextConsecutiveRegister(); | 1131 Register cache_length = register_allocator()->NextConsecutiveRegister(); |
1120 // Used as kRegTriple8 and kRegPair8 in ForInPrepare and ForInNext. | 1132 // Used as kRegTriple8 and kRegPair8 in ForInPrepare and ForInNext. |
1121 USE(cache_array); | 1133 USE(cache_array); |
1122 builder()->ForInPrepare(cache_type); | 1134 builder()->ForInPrepare(cache_type); |
1123 | 1135 |
1124 // Set up loop counter | 1136 // Set up loop counter |
1125 Register index = register_allocator()->NewRegister(); | 1137 Register index = register_allocator()->NewRegister(); |
1126 builder()->LoadLiteral(Smi::FromInt(0)); | 1138 builder()->LoadLiteral(Smi::FromInt(0)); |
1127 builder()->StoreAccumulatorInRegister(index); | 1139 builder()->StoreAccumulatorInRegister(index); |
1128 | 1140 |
1129 // The loop | 1141 // The loop |
1130 loop_builder.LoopHeader(); | 1142 loop_builder.LoopHeader(); |
1131 loop_builder.Condition(); | 1143 loop_builder.Condition(); |
1132 builder()->ForInDone(index, cache_length); | 1144 builder()->ForInDone(index, cache_length); |
1133 loop_builder.BreakIfTrue(); | 1145 loop_builder.BreakIfTrue(); |
1134 DCHECK(Register::AreContiguous(cache_type, cache_array)); | 1146 DCHECK(Register::AreContiguous(cache_type, cache_array)); |
1135 FeedbackVectorSlot slot = stmt->ForInFeedbackSlot(); | 1147 FeedbackVectorSlot slot = stmt->ForInFeedbackSlot(); |
1136 builder()->ForInNext(receiver, index, cache_type, feedback_index(slot)); | 1148 builder()->ForInNext(receiver, index, cache_type, feedback_index(slot)); |
1137 loop_builder.ContinueIfUndefined(); | 1149 loop_builder.ContinueIfUndefined(); |
| 1150 builder()->SetExpressionAsStatementPosition(stmt->each()); |
1138 VisitForInAssignment(stmt->each(), stmt->EachFeedbackSlot()); | 1151 VisitForInAssignment(stmt->each(), stmt->EachFeedbackSlot()); |
1139 VisitIterationBody(stmt, &loop_builder); | 1152 VisitIterationBody(stmt, &loop_builder); |
1140 loop_builder.Next(); | 1153 loop_builder.Next(); |
1141 builder()->ForInStep(index); | 1154 builder()->ForInStep(index); |
1142 builder()->StoreAccumulatorInRegister(index); | 1155 builder()->StoreAccumulatorInRegister(index); |
1143 loop_builder.JumpToHeader(); | 1156 loop_builder.JumpToHeader(); |
1144 loop_builder.EndLoop(); | 1157 loop_builder.EndLoop(); |
1145 builder()->Bind(&subject_null_label); | 1158 builder()->Bind(&subject_null_label); |
1146 builder()->Bind(&subject_undefined_label); | 1159 builder()->Bind(&subject_undefined_label); |
1147 } | 1160 } |
1148 | 1161 |
1149 | 1162 |
1150 void BytecodeGenerator::VisitForOfStatement(ForOfStatement* stmt) { | 1163 void BytecodeGenerator::VisitForOfStatement(ForOfStatement* stmt) { |
1151 LoopBuilder loop_builder(builder()); | 1164 LoopBuilder loop_builder(builder()); |
1152 ControlScopeForIteration control_scope(this, stmt, &loop_builder); | 1165 ControlScopeForIteration control_scope(this, stmt, &loop_builder); |
1153 | 1166 |
1154 VisitForEffect(stmt->assign_iterator()); | 1167 VisitForEffect(stmt->assign_iterator()); |
1155 | 1168 |
1156 loop_builder.LoopHeader(); | 1169 loop_builder.LoopHeader(); |
1157 loop_builder.Next(); | 1170 loop_builder.Next(); |
| 1171 builder()->SetExpressionAsStatementPosition(stmt->next_result()); |
1158 VisitForEffect(stmt->next_result()); | 1172 VisitForEffect(stmt->next_result()); |
1159 VisitForAccumulatorValue(stmt->result_done()); | 1173 VisitForAccumulatorValue(stmt->result_done()); |
1160 loop_builder.BreakIfTrue(); | 1174 loop_builder.BreakIfTrue(); |
1161 | 1175 |
1162 VisitForEffect(stmt->assign_each()); | 1176 VisitForEffect(stmt->assign_each()); |
1163 VisitIterationBody(stmt, &loop_builder); | 1177 VisitIterationBody(stmt, &loop_builder); |
1164 loop_builder.JumpToHeader(); | 1178 loop_builder.JumpToHeader(); |
1165 loop_builder.EndLoop(); | 1179 loop_builder.EndLoop(); |
1166 } | 1180 } |
1167 | 1181 |
(...skipping 1974 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3142 } | 3156 } |
3143 | 3157 |
3144 | 3158 |
3145 int BytecodeGenerator::feedback_index(FeedbackVectorSlot slot) const { | 3159 int BytecodeGenerator::feedback_index(FeedbackVectorSlot slot) const { |
3146 return info()->feedback_vector()->GetIndex(slot); | 3160 return info()->feedback_vector()->GetIndex(slot); |
3147 } | 3161 } |
3148 | 3162 |
3149 } // namespace interpreter | 3163 } // namespace interpreter |
3150 } // namespace internal | 3164 } // namespace internal |
3151 } // namespace v8 | 3165 } // namespace v8 |
OLD | NEW |