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/compile-time-value.h" | 7 #include "src/ast/compile-time-value.h" |
8 #include "src/ast/scopes.h" | 8 #include "src/ast/scopes.h" |
9 #include "src/builtins/builtins-constructor.h" | 9 #include "src/builtins/builtins-constructor.h" |
10 #include "src/code-stubs.h" | 10 #include "src/code-stubs.h" |
(...skipping 754 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
765 info_(info), | 765 info_(info), |
766 ast_string_constants_(info->isolate()->ast_string_constants()), | 766 ast_string_constants_(info->isolate()->ast_string_constants()), |
767 closure_scope_(info->scope()), | 767 closure_scope_(info->scope()), |
768 current_scope_(info->scope()), | 768 current_scope_(info->scope()), |
769 globals_builder_(new (zone()) GlobalDeclarationsBuilder(info->zone())), | 769 globals_builder_(new (zone()) GlobalDeclarationsBuilder(info->zone())), |
770 global_declarations_(0, info->zone()), | 770 global_declarations_(0, info->zone()), |
771 function_literals_(0, info->zone()), | 771 function_literals_(0, info->zone()), |
772 native_function_literals_(0, info->zone()), | 772 native_function_literals_(0, info->zone()), |
773 object_literals_(0, info->zone()), | 773 object_literals_(0, info->zone()), |
774 array_literals_(0, info->zone()), | 774 array_literals_(0, info->zone()), |
| 775 block_coverage_slots_(0, info->zone()), |
775 execution_control_(nullptr), | 776 execution_control_(nullptr), |
776 execution_context_(nullptr), | 777 execution_context_(nullptr), |
777 execution_result_(nullptr), | 778 execution_result_(nullptr), |
778 generator_jump_table_(nullptr), | 779 generator_jump_table_(nullptr), |
779 generator_state_(), | 780 generator_state_(), |
780 loop_depth_(0) { | 781 loop_depth_(0) { |
781 DCHECK_EQ(closure_scope(), closure_scope()->GetClosureScope()); | 782 DCHECK_EQ(closure_scope(), closure_scope()->GetClosureScope()); |
782 } | 783 } |
783 | 784 |
784 Handle<BytecodeArray> BytecodeGenerator::FinalizeBytecode(Isolate* isolate) { | 785 Handle<BytecodeArray> BytecodeGenerator::FinalizeBytecode(Isolate* isolate) { |
785 AllocateDeferredConstants(isolate); | 786 AllocateDeferredConstants(isolate); |
| 787 |
| 788 if (is_block_coverage()) { |
| 789 info()->set_coverage_info( |
| 790 isolate->factory()->NewCoverageInfo(block_coverage_slots_)); |
| 791 } |
| 792 |
786 if (HasStackOverflow()) return Handle<BytecodeArray>(); | 793 if (HasStackOverflow()) return Handle<BytecodeArray>(); |
787 return builder()->ToBytecodeArray(isolate); | 794 return builder()->ToBytecodeArray(isolate); |
788 } | 795 } |
789 | 796 |
790 void BytecodeGenerator::AllocateDeferredConstants(Isolate* isolate) { | 797 void BytecodeGenerator::AllocateDeferredConstants(Isolate* isolate) { |
791 // Build global declaration pair arrays. | 798 // Build global declaration pair arrays. |
792 for (GlobalDeclarationsBuilder* globals_builder : global_declarations_) { | 799 for (GlobalDeclarationsBuilder* globals_builder : global_declarations_) { |
793 Handle<FixedArray> declarations = | 800 Handle<FixedArray> declarations = |
794 globals_builder->AllocateDeclarations(info()); | 801 globals_builder->AllocateDeclarations(info()); |
795 if (declarations.is_null()) return SetStackOverflow(); | 802 if (declarations.is_null()) return SetStackOverflow(); |
(...skipping 381 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1177 void BytecodeGenerator::VisitExpressionStatement(ExpressionStatement* stmt) { | 1184 void BytecodeGenerator::VisitExpressionStatement(ExpressionStatement* stmt) { |
1178 builder()->SetStatementPosition(stmt); | 1185 builder()->SetStatementPosition(stmt); |
1179 VisitForEffect(stmt->expression()); | 1186 VisitForEffect(stmt->expression()); |
1180 } | 1187 } |
1181 | 1188 |
1182 void BytecodeGenerator::VisitEmptyStatement(EmptyStatement* stmt) { | 1189 void BytecodeGenerator::VisitEmptyStatement(EmptyStatement* stmt) { |
1183 } | 1190 } |
1184 | 1191 |
1185 void BytecodeGenerator::VisitIfStatement(IfStatement* stmt) { | 1192 void BytecodeGenerator::VisitIfStatement(IfStatement* stmt) { |
1186 builder()->SetStatementPosition(stmt); | 1193 builder()->SetStatementPosition(stmt); |
| 1194 |
| 1195 int then_slot = AllocateBlockCoverageSlot(stmt->then_range()); |
| 1196 int else_slot = AllocateBlockCoverageSlot(stmt->else_range()); |
| 1197 |
1187 if (stmt->condition()->ToBooleanIsTrue()) { | 1198 if (stmt->condition()->ToBooleanIsTrue()) { |
1188 // Generate then block unconditionally as always true. | 1199 // Generate then block unconditionally as always true. |
| 1200 IncBlockCounter(then_slot); |
1189 Visit(stmt->then_statement()); | 1201 Visit(stmt->then_statement()); |
1190 } else if (stmt->condition()->ToBooleanIsFalse()) { | 1202 } else if (stmt->condition()->ToBooleanIsFalse()) { |
1191 // Generate else block unconditionally if it exists. | 1203 // Generate else block unconditionally if it exists. |
1192 if (stmt->HasElseStatement()) { | 1204 if (stmt->HasElseStatement()) { |
| 1205 IncBlockCounter(else_slot); |
1193 Visit(stmt->else_statement()); | 1206 Visit(stmt->else_statement()); |
1194 } | 1207 } |
1195 } else { | 1208 } else { |
1196 // TODO(oth): If then statement is BreakStatement or | 1209 // TODO(oth): If then statement is BreakStatement or |
1197 // ContinueStatement we can reduce number of generated | 1210 // ContinueStatement we can reduce number of generated |
1198 // jump/jump_ifs here. See BasicLoops test. | 1211 // jump/jump_ifs here. See BasicLoops test. |
1199 BytecodeLabel end_label; | 1212 BytecodeLabel end_label; |
1200 BytecodeLabels then_labels(zone()), else_labels(zone()); | 1213 BytecodeLabels then_labels(zone()), else_labels(zone()); |
1201 VisitForTest(stmt->condition(), &then_labels, &else_labels, | 1214 VisitForTest(stmt->condition(), &then_labels, &else_labels, |
1202 TestFallthrough::kThen); | 1215 TestFallthrough::kThen); |
1203 | 1216 |
1204 then_labels.Bind(builder()); | 1217 then_labels.Bind(builder()); |
| 1218 IncBlockCounter(then_slot); |
1205 Visit(stmt->then_statement()); | 1219 Visit(stmt->then_statement()); |
1206 | 1220 |
1207 if (stmt->HasElseStatement()) { | 1221 if (stmt->HasElseStatement()) { |
1208 builder()->Jump(&end_label); | 1222 builder()->Jump(&end_label); |
1209 else_labels.Bind(builder()); | 1223 else_labels.Bind(builder()); |
| 1224 IncBlockCounter(else_slot); |
1210 Visit(stmt->else_statement()); | 1225 Visit(stmt->else_statement()); |
1211 } else { | 1226 } else { |
1212 else_labels.Bind(builder()); | 1227 else_labels.Bind(builder()); |
1213 } | 1228 } |
1214 builder()->Bind(&end_label); | 1229 builder()->Bind(&end_label); |
1215 } | 1230 } |
1216 } | 1231 } |
1217 | 1232 |
1218 void BytecodeGenerator::VisitSloppyBlockFunctionStatement( | 1233 void BytecodeGenerator::VisitSloppyBlockFunctionStatement( |
1219 SloppyBlockFunctionStatement* stmt) { | 1234 SloppyBlockFunctionStatement* stmt) { |
(...skipping 2672 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3892 } | 3907 } |
3893 | 3908 |
3894 LanguageMode BytecodeGenerator::language_mode() const { | 3909 LanguageMode BytecodeGenerator::language_mode() const { |
3895 return current_scope()->language_mode(); | 3910 return current_scope()->language_mode(); |
3896 } | 3911 } |
3897 | 3912 |
3898 int BytecodeGenerator::feedback_index(FeedbackSlot slot) const { | 3913 int BytecodeGenerator::feedback_index(FeedbackSlot slot) const { |
3899 return FeedbackVector::GetIndex(slot); | 3914 return FeedbackVector::GetIndex(slot); |
3900 } | 3915 } |
3901 | 3916 |
| 3917 bool BytecodeGenerator::is_block_coverage() const { |
| 3918 DCHECK_IMPLIES(info()->is_block_coverage_enabled(), FLAG_block_coverage); |
| 3919 return info()->is_block_coverage_enabled(); |
| 3920 } |
| 3921 |
3902 Runtime::FunctionId BytecodeGenerator::StoreToSuperRuntimeId() { | 3922 Runtime::FunctionId BytecodeGenerator::StoreToSuperRuntimeId() { |
3903 return is_strict(language_mode()) ? Runtime::kStoreToSuper_Strict | 3923 return is_strict(language_mode()) ? Runtime::kStoreToSuper_Strict |
3904 : Runtime::kStoreToSuper_Sloppy; | 3924 : Runtime::kStoreToSuper_Sloppy; |
3905 } | 3925 } |
3906 | 3926 |
3907 Runtime::FunctionId BytecodeGenerator::StoreKeyedToSuperRuntimeId() { | 3927 Runtime::FunctionId BytecodeGenerator::StoreKeyedToSuperRuntimeId() { |
3908 return is_strict(language_mode()) ? Runtime::kStoreKeyedToSuper_Strict | 3928 return is_strict(language_mode()) ? Runtime::kStoreKeyedToSuper_Strict |
3909 : Runtime::kStoreKeyedToSuper_Sloppy; | 3929 : Runtime::kStoreKeyedToSuper_Sloppy; |
3910 } | 3930 } |
3911 | 3931 |
3912 } // namespace interpreter | 3932 } // namespace interpreter |
3913 } // namespace internal | 3933 } // namespace internal |
3914 } // namespace v8 | 3934 } // namespace v8 |
OLD | NEW |