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 591 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
602 | 602 |
603 // Visit illegal re-declaration and bail out if it exists. | 603 // Visit illegal re-declaration and bail out if it exists. |
604 if (scope()->HasIllegalRedeclaration()) { | 604 if (scope()->HasIllegalRedeclaration()) { |
605 VisitForEffect(scope()->GetIllegalRedeclaration()); | 605 VisitForEffect(scope()->GetIllegalRedeclaration()); |
606 return; | 606 return; |
607 } | 607 } |
608 | 608 |
609 // Visit declarations within the function scope. | 609 // Visit declarations within the function scope. |
610 VisitDeclarations(scope()->declarations()); | 610 VisitDeclarations(scope()->declarations()); |
611 | 611 |
| 612 // Perform a stack-check before the body. |
| 613 builder()->StackCheck(); |
| 614 |
612 // Visit statements in the function body. | 615 // Visit statements in the function body. |
613 VisitStatements(info()->literal()->body()); | 616 VisitStatements(info()->literal()->body()); |
614 } | 617 } |
615 | 618 |
616 | 619 |
617 void BytecodeGenerator::VisitBlock(Block* stmt) { | 620 void BytecodeGenerator::VisitBlock(Block* stmt) { |
618 // Visit declarations and statements. | 621 // Visit declarations and statements. |
619 if (stmt->scope() != nullptr && stmt->scope()->NeedsContext()) { | 622 if (stmt->scope() != nullptr && stmt->scope()->NeedsContext()) { |
620 VisitNewLocalBlockContext(stmt->scope()); | 623 VisitNewLocalBlockContext(stmt->scope()); |
621 ContextScope scope(this, stmt->scope()); | 624 ContextScope scope(this, stmt->scope()); |
(...skipping 292 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
914 | 917 |
915 switch_builder.SetBreakTarget(done_label); | 918 switch_builder.SetBreakTarget(done_label); |
916 } | 919 } |
917 | 920 |
918 | 921 |
919 void BytecodeGenerator::VisitCaseClause(CaseClause* clause) { | 922 void BytecodeGenerator::VisitCaseClause(CaseClause* clause) { |
920 // Handled entirely in VisitSwitchStatement. | 923 // Handled entirely in VisitSwitchStatement. |
921 UNREACHABLE(); | 924 UNREACHABLE(); |
922 } | 925 } |
923 | 926 |
| 927 void BytecodeGenerator::VisitIterationBody(IterationStatement* stmt, |
| 928 LoopBuilder* loop_builder) { |
| 929 ControlScopeForIteration execution_control(this, stmt, loop_builder); |
| 930 builder()->StackCheck(); |
| 931 Visit(stmt->body()); |
| 932 } |
924 | 933 |
925 void BytecodeGenerator::VisitDoWhileStatement(DoWhileStatement* stmt) { | 934 void BytecodeGenerator::VisitDoWhileStatement(DoWhileStatement* stmt) { |
926 LoopBuilder loop_builder(builder()); | 935 LoopBuilder loop_builder(builder()); |
927 ControlScopeForIteration execution_control(this, stmt, &loop_builder); | |
928 loop_builder.LoopHeader(); | 936 loop_builder.LoopHeader(); |
929 if (stmt->cond()->ToBooleanIsFalse()) { | 937 if (stmt->cond()->ToBooleanIsFalse()) { |
930 Visit(stmt->body()); | 938 VisitIterationBody(stmt, &loop_builder); |
931 loop_builder.Condition(); | 939 loop_builder.Condition(); |
932 } else if (stmt->cond()->ToBooleanIsTrue()) { | 940 } else if (stmt->cond()->ToBooleanIsTrue()) { |
933 loop_builder.Condition(); | 941 loop_builder.Condition(); |
934 Visit(stmt->body()); | 942 VisitIterationBody(stmt, &loop_builder); |
935 loop_builder.JumpToHeader(); | 943 loop_builder.JumpToHeader(); |
936 } else { | 944 } else { |
937 Visit(stmt->body()); | 945 VisitIterationBody(stmt, &loop_builder); |
938 loop_builder.Condition(); | 946 loop_builder.Condition(); |
939 VisitForAccumulatorValue(stmt->cond()); | 947 VisitForAccumulatorValue(stmt->cond()); |
940 loop_builder.JumpToHeaderIfTrue(); | 948 loop_builder.JumpToHeaderIfTrue(); |
941 } | 949 } |
942 loop_builder.EndLoop(); | 950 loop_builder.EndLoop(); |
943 } | 951 } |
944 | 952 |
945 | |
946 void BytecodeGenerator::VisitWhileStatement(WhileStatement* stmt) { | 953 void BytecodeGenerator::VisitWhileStatement(WhileStatement* stmt) { |
947 if (stmt->cond()->ToBooleanIsFalse()) { | 954 if (stmt->cond()->ToBooleanIsFalse()) { |
948 // If the condition is false there is no need to generate the loop. | 955 // If the condition is false there is no need to generate the loop. |
949 return; | 956 return; |
950 } | 957 } |
951 | 958 |
952 LoopBuilder loop_builder(builder()); | 959 LoopBuilder loop_builder(builder()); |
953 ControlScopeForIteration execution_control(this, stmt, &loop_builder); | |
954 loop_builder.LoopHeader(); | 960 loop_builder.LoopHeader(); |
955 loop_builder.Condition(); | 961 loop_builder.Condition(); |
956 if (!stmt->cond()->ToBooleanIsTrue()) { | 962 if (!stmt->cond()->ToBooleanIsTrue()) { |
957 VisitForAccumulatorValue(stmt->cond()); | 963 VisitForAccumulatorValue(stmt->cond()); |
958 loop_builder.BreakIfFalse(); | 964 loop_builder.BreakIfFalse(); |
959 } | 965 } |
960 Visit(stmt->body()); | 966 VisitIterationBody(stmt, &loop_builder); |
961 loop_builder.JumpToHeader(); | 967 loop_builder.JumpToHeader(); |
962 loop_builder.EndLoop(); | 968 loop_builder.EndLoop(); |
963 } | 969 } |
964 | 970 |
965 | 971 |
966 void BytecodeGenerator::VisitForStatement(ForStatement* stmt) { | 972 void BytecodeGenerator::VisitForStatement(ForStatement* stmt) { |
967 if (stmt->init() != nullptr) { | 973 if (stmt->init() != nullptr) { |
968 Visit(stmt->init()); | 974 Visit(stmt->init()); |
969 } | 975 } |
970 if (stmt->cond() && stmt->cond()->ToBooleanIsFalse()) { | 976 if (stmt->cond() && stmt->cond()->ToBooleanIsFalse()) { |
971 // If the condition is known to be false there is no need to generate | 977 // If the condition is known to be false there is no need to generate |
972 // body, next or condition blocks. Init block should be generated. | 978 // body, next or condition blocks. Init block should be generated. |
973 return; | 979 return; |
974 } | 980 } |
975 | 981 |
976 LoopBuilder loop_builder(builder()); | 982 LoopBuilder loop_builder(builder()); |
977 ControlScopeForIteration execution_control(this, stmt, &loop_builder); | |
978 | |
979 loop_builder.LoopHeader(); | 983 loop_builder.LoopHeader(); |
980 loop_builder.Condition(); | 984 loop_builder.Condition(); |
981 if (stmt->cond() && !stmt->cond()->ToBooleanIsTrue()) { | 985 if (stmt->cond() && !stmt->cond()->ToBooleanIsTrue()) { |
982 VisitForAccumulatorValue(stmt->cond()); | 986 VisitForAccumulatorValue(stmt->cond()); |
983 loop_builder.BreakIfFalse(); | 987 loop_builder.BreakIfFalse(); |
984 } | 988 } |
985 Visit(stmt->body()); | 989 VisitIterationBody(stmt, &loop_builder); |
986 if (stmt->next() != nullptr) { | 990 if (stmt->next() != nullptr) { |
987 loop_builder.Next(); | 991 loop_builder.Next(); |
988 Visit(stmt->next()); | 992 Visit(stmt->next()); |
989 } | 993 } |
990 loop_builder.JumpToHeader(); | 994 loop_builder.JumpToHeader(); |
991 loop_builder.EndLoop(); | 995 loop_builder.EndLoop(); |
992 } | 996 } |
993 | 997 |
994 | 998 |
995 void BytecodeGenerator::VisitForInAssignment(Expression* expr, | 999 void BytecodeGenerator::VisitForInAssignment(Expression* expr, |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1036 | 1040 |
1037 | 1041 |
1038 void BytecodeGenerator::VisitForInStatement(ForInStatement* stmt) { | 1042 void BytecodeGenerator::VisitForInStatement(ForInStatement* stmt) { |
1039 if (stmt->subject()->IsNullLiteral() || | 1043 if (stmt->subject()->IsNullLiteral() || |
1040 stmt->subject()->IsUndefinedLiteral(isolate())) { | 1044 stmt->subject()->IsUndefinedLiteral(isolate())) { |
1041 // ForIn generates lots of code, skip if it wouldn't produce any effects. | 1045 // ForIn generates lots of code, skip if it wouldn't produce any effects. |
1042 return; | 1046 return; |
1043 } | 1047 } |
1044 | 1048 |
1045 LoopBuilder loop_builder(builder()); | 1049 LoopBuilder loop_builder(builder()); |
1046 ControlScopeForIteration control_scope(this, stmt, &loop_builder); | |
1047 BytecodeLabel subject_null_label, subject_undefined_label, not_object_label; | 1050 BytecodeLabel subject_null_label, subject_undefined_label, not_object_label; |
1048 | 1051 |
1049 // Prepare the state for executing ForIn. | 1052 // Prepare the state for executing ForIn. |
1050 VisitForAccumulatorValue(stmt->subject()); | 1053 VisitForAccumulatorValue(stmt->subject()); |
1051 builder()->JumpIfUndefined(&subject_undefined_label); | 1054 builder()->JumpIfUndefined(&subject_undefined_label); |
1052 builder()->JumpIfNull(&subject_null_label); | 1055 builder()->JumpIfNull(&subject_null_label); |
1053 Register receiver = register_allocator()->NewRegister(); | 1056 Register receiver = register_allocator()->NewRegister(); |
1054 builder()->CastAccumulatorToJSObject(); | 1057 builder()->CastAccumulatorToJSObject(); |
1055 builder()->JumpIfNull(¬_object_label); | 1058 builder()->JumpIfNull(¬_object_label); |
1056 builder()->StoreAccumulatorInRegister(receiver); | 1059 builder()->StoreAccumulatorInRegister(receiver); |
(...skipping 13 matching lines...) Expand all Loading... |
1070 | 1073 |
1071 // The loop | 1074 // The loop |
1072 loop_builder.LoopHeader(); | 1075 loop_builder.LoopHeader(); |
1073 loop_builder.Condition(); | 1076 loop_builder.Condition(); |
1074 builder()->ForInDone(index, cache_length); | 1077 builder()->ForInDone(index, cache_length); |
1075 loop_builder.BreakIfTrue(); | 1078 loop_builder.BreakIfTrue(); |
1076 DCHECK(Register::AreContiguous(cache_type, cache_array)); | 1079 DCHECK(Register::AreContiguous(cache_type, cache_array)); |
1077 builder()->ForInNext(receiver, index, cache_type); | 1080 builder()->ForInNext(receiver, index, cache_type); |
1078 loop_builder.ContinueIfUndefined(); | 1081 loop_builder.ContinueIfUndefined(); |
1079 VisitForInAssignment(stmt->each(), stmt->EachFeedbackSlot()); | 1082 VisitForInAssignment(stmt->each(), stmt->EachFeedbackSlot()); |
1080 Visit(stmt->body()); | 1083 VisitIterationBody(stmt, &loop_builder); |
1081 loop_builder.Next(); | 1084 loop_builder.Next(); |
1082 builder()->ForInStep(index); | 1085 builder()->ForInStep(index); |
1083 builder()->StoreAccumulatorInRegister(index); | 1086 builder()->StoreAccumulatorInRegister(index); |
1084 loop_builder.JumpToHeader(); | 1087 loop_builder.JumpToHeader(); |
1085 loop_builder.EndLoop(); | 1088 loop_builder.EndLoop(); |
1086 builder()->Bind(¬_object_label); | 1089 builder()->Bind(¬_object_label); |
1087 builder()->Bind(&subject_null_label); | 1090 builder()->Bind(&subject_null_label); |
1088 builder()->Bind(&subject_undefined_label); | 1091 builder()->Bind(&subject_undefined_label); |
1089 } | 1092 } |
1090 | 1093 |
1091 | 1094 |
1092 void BytecodeGenerator::VisitForOfStatement(ForOfStatement* stmt) { | 1095 void BytecodeGenerator::VisitForOfStatement(ForOfStatement* stmt) { |
1093 LoopBuilder loop_builder(builder()); | 1096 LoopBuilder loop_builder(builder()); |
1094 ControlScopeForIteration control_scope(this, stmt, &loop_builder); | 1097 ControlScopeForIteration control_scope(this, stmt, &loop_builder); |
1095 | 1098 |
1096 VisitForEffect(stmt->assign_iterator()); | 1099 VisitForEffect(stmt->assign_iterator()); |
1097 | 1100 |
1098 loop_builder.LoopHeader(); | 1101 loop_builder.LoopHeader(); |
1099 loop_builder.Next(); | 1102 loop_builder.Next(); |
1100 VisitForEffect(stmt->next_result()); | 1103 VisitForEffect(stmt->next_result()); |
1101 VisitForAccumulatorValue(stmt->result_done()); | 1104 VisitForAccumulatorValue(stmt->result_done()); |
1102 loop_builder.BreakIfTrue(); | 1105 loop_builder.BreakIfTrue(); |
1103 | 1106 |
1104 VisitForEffect(stmt->assign_each()); | 1107 VisitForEffect(stmt->assign_each()); |
1105 Visit(stmt->body()); | 1108 VisitIterationBody(stmt, &loop_builder); |
1106 loop_builder.JumpToHeader(); | 1109 loop_builder.JumpToHeader(); |
1107 loop_builder.EndLoop(); | 1110 loop_builder.EndLoop(); |
1108 } | 1111 } |
1109 | 1112 |
1110 | 1113 |
1111 void BytecodeGenerator::VisitTryCatchStatement(TryCatchStatement* stmt) { | 1114 void BytecodeGenerator::VisitTryCatchStatement(TryCatchStatement* stmt) { |
1112 TryCatchBuilder try_control_builder(builder()); | 1115 TryCatchBuilder try_control_builder(builder()); |
1113 Register no_reg; | 1116 Register no_reg; |
1114 | 1117 |
1115 // Preserve the context in a dedicated register, so that it can be restored | 1118 // Preserve the context in a dedicated register, so that it can be restored |
(...skipping 1433 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2549 } | 2552 } |
2550 | 2553 |
2551 | 2554 |
2552 int BytecodeGenerator::feedback_index(FeedbackVectorSlot slot) const { | 2555 int BytecodeGenerator::feedback_index(FeedbackVectorSlot slot) const { |
2553 return info()->feedback_vector()->GetIndex(slot); | 2556 return info()->feedback_vector()->GetIndex(slot); |
2554 } | 2557 } |
2555 | 2558 |
2556 } // namespace interpreter | 2559 } // namespace interpreter |
2557 } // namespace internal | 2560 } // namespace internal |
2558 } // namespace v8 | 2561 } // namespace v8 |
OLD | NEW |