| 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 |