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