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