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 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
171 } | 171 } |
172 | 172 |
173 // Applies all recorded control-flow commands after the finally-block again. | 173 // Applies all recorded control-flow commands after the finally-block again. |
174 // This generates a dynamic dispatch on the token from the entry point. | 174 // This generates a dynamic dispatch on the token from the entry point. |
175 void ApplyDeferredCommands() { | 175 void ApplyDeferredCommands() { |
176 // The fall-through path is covered by the default case, hence +1 here. | 176 // The fall-through path is covered by the default case, hence +1 here. |
177 SwitchBuilder dispatch(builder(), static_cast<int>(deferred_.size() + 1)); | 177 SwitchBuilder dispatch(builder(), static_cast<int>(deferred_.size() + 1)); |
178 for (size_t i = 0; i < deferred_.size(); ++i) { | 178 for (size_t i = 0; i < deferred_.size(); ++i) { |
179 Entry& entry = deferred_[i]; | 179 Entry& entry = deferred_[i]; |
180 builder()->LoadLiteral(Smi::FromInt(entry.token)); | 180 builder()->LoadLiteral(Smi::FromInt(entry.token)); |
181 builder()->CompareOperation(Token::EQ_STRICT, token_register_, | 181 builder()->CompareOperation(Token::EQ_STRICT, token_register_); |
182 Strength::WEAK); | |
183 dispatch.Case(static_cast<int>(i)); | 182 dispatch.Case(static_cast<int>(i)); |
184 } | 183 } |
185 dispatch.DefaultAt(static_cast<int>(deferred_.size())); | 184 dispatch.DefaultAt(static_cast<int>(deferred_.size())); |
186 for (size_t i = 0; i < deferred_.size(); ++i) { | 185 for (size_t i = 0; i < deferred_.size(); ++i) { |
187 Entry& entry = deferred_[i]; | 186 Entry& entry = deferred_[i]; |
188 dispatch.SetCaseTarget(static_cast<int>(i)); | 187 dispatch.SetCaseTarget(static_cast<int>(i)); |
189 builder()->LoadAccumulatorWithRegister(result_register_); | 188 builder()->LoadAccumulatorWithRegister(result_register_); |
190 execution_control()->PerformCommand(entry.command, entry.statement); | 189 execution_control()->PerformCommand(entry.command, entry.statement); |
191 } | 190 } |
192 dispatch.SetCaseTarget(static_cast<int>(deferred_.size())); | 191 dispatch.SetCaseTarget(static_cast<int>(deferred_.size())); |
(...skipping 735 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
928 CaseClause* clause = clauses->at(i); | 927 CaseClause* clause = clauses->at(i); |
929 | 928 |
930 // The default is not a test, remember index. | 929 // The default is not a test, remember index. |
931 if (clause->is_default()) { | 930 if (clause->is_default()) { |
932 default_index = i; | 931 default_index = i; |
933 continue; | 932 continue; |
934 } | 933 } |
935 | 934 |
936 // Perform label comparison as if via '===' with tag. | 935 // Perform label comparison as if via '===' with tag. |
937 VisitForAccumulatorValue(clause->label()); | 936 VisitForAccumulatorValue(clause->label()); |
938 builder()->CompareOperation(Token::Value::EQ_STRICT, tag, | 937 builder()->CompareOperation(Token::Value::EQ_STRICT, tag); |
939 language_mode_strength()); | |
940 switch_builder.Case(i); | 938 switch_builder.Case(i); |
941 } | 939 } |
942 | 940 |
943 if (default_index >= 0) { | 941 if (default_index >= 0) { |
944 // Emit default jump if there is a default case. | 942 // Emit default jump if there is a default case. |
945 switch_builder.DefaultAt(default_index); | 943 switch_builder.DefaultAt(default_index); |
946 } else { | 944 } else { |
947 // Otherwise if we have reached here none of the cases matched, so jump to | 945 // Otherwise if we have reached here none of the cases matched, so jump to |
948 // done. | 946 // done. |
949 builder()->Jump(&done_label); | 947 builder()->Jump(&done_label); |
(...skipping 476 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1426 } | 1424 } |
1427 } | 1425 } |
1428 } | 1426 } |
1429 } | 1427 } |
1430 | 1428 |
1431 void BytecodeGenerator::VisitClassLiteralStaticPrototypeWithComputedName( | 1429 void BytecodeGenerator::VisitClassLiteralStaticPrototypeWithComputedName( |
1432 Register key) { | 1430 Register key) { |
1433 BytecodeLabel done; | 1431 BytecodeLabel done; |
1434 builder() | 1432 builder() |
1435 ->LoadLiteral(isolate()->factory()->prototype_string()) | 1433 ->LoadLiteral(isolate()->factory()->prototype_string()) |
1436 .CompareOperation(Token::Value::EQ_STRICT, key, Strength::WEAK) | 1434 .CompareOperation(Token::Value::EQ_STRICT, key) |
1437 .JumpIfFalse(&done) | 1435 .JumpIfFalse(&done) |
1438 .CallRuntime(Runtime::kThrowStaticPrototypeError, Register(0), 0) | 1436 .CallRuntime(Runtime::kThrowStaticPrototypeError, Register(0), 0) |
1439 .Bind(&done); | 1437 .Bind(&done); |
1440 } | 1438 } |
1441 | 1439 |
1442 void BytecodeGenerator::VisitNativeFunctionLiteral( | 1440 void BytecodeGenerator::VisitNativeFunctionLiteral( |
1443 NativeFunctionLiteral* expr) { | 1441 NativeFunctionLiteral* expr) { |
1444 // Find or build a shared function info for the native function template. | 1442 // Find or build a shared function info for the native function template. |
1445 Handle<SharedFunctionInfo> shared_info = | 1443 Handle<SharedFunctionInfo> shared_info = |
1446 Compiler::GetSharedFunctionInfoForNative(expr->extension(), expr->name()); | 1444 Compiler::GetSharedFunctionInfoForNative(expr->extension(), expr->name()); |
(...skipping 745 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2192 break; | 2190 break; |
2193 } | 2191 } |
2194 case KEYED_SUPER_PROPERTY: { | 2192 case KEYED_SUPER_PROPERTY: { |
2195 old_value = register_allocator()->NewRegister(); | 2193 old_value = register_allocator()->NewRegister(); |
2196 BuildKeyedSuperPropertyLoad(&super_args); | 2194 BuildKeyedSuperPropertyLoad(&super_args); |
2197 builder()->StoreAccumulatorInRegister(old_value); | 2195 builder()->StoreAccumulatorInRegister(old_value); |
2198 break; | 2196 break; |
2199 } | 2197 } |
2200 } | 2198 } |
2201 VisitForAccumulatorValue(expr->value()); | 2199 VisitForAccumulatorValue(expr->value()); |
2202 builder()->BinaryOperation(expr->binary_op(), old_value, | 2200 builder()->BinaryOperation(expr->binary_op(), old_value); |
2203 language_mode_strength()); | |
2204 } else { | 2201 } else { |
2205 VisitForAccumulatorValue(expr->value()); | 2202 VisitForAccumulatorValue(expr->value()); |
2206 } | 2203 } |
2207 | 2204 |
2208 // Store the value. | 2205 // Store the value. |
2209 FeedbackVectorSlot slot = expr->AssignmentSlot(); | 2206 FeedbackVectorSlot slot = expr->AssignmentSlot(); |
2210 switch (assign_type) { | 2207 switch (assign_type) { |
2211 case VARIABLE: { | 2208 case VARIABLE: { |
2212 // TODO(oth): The VisitVariableAssignment() call is hard to reason about. | 2209 // TODO(oth): The VisitVariableAssignment() call is hard to reason about. |
2213 // Is the value in the accumulator safe? Yes, but scary. | 2210 // Is the value in the accumulator safe? Yes, but scary. |
(...skipping 505 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2719 builder()->CastAccumulatorToNumber(); | 2716 builder()->CastAccumulatorToNumber(); |
2720 } | 2717 } |
2721 | 2718 |
2722 // Save result for postfix expressions. | 2719 // Save result for postfix expressions. |
2723 if (is_postfix) { | 2720 if (is_postfix) { |
2724 old_value = register_allocator()->outer()->NewRegister(); | 2721 old_value = register_allocator()->outer()->NewRegister(); |
2725 builder()->StoreAccumulatorInRegister(old_value); | 2722 builder()->StoreAccumulatorInRegister(old_value); |
2726 } | 2723 } |
2727 | 2724 |
2728 // Perform +1/-1 operation. | 2725 // Perform +1/-1 operation. |
2729 builder()->CountOperation(expr->binary_op(), language_mode_strength()); | 2726 builder()->CountOperation(expr->binary_op()); |
2730 | 2727 |
2731 // Store the value. | 2728 // Store the value. |
2732 FeedbackVectorSlot feedback_slot = expr->CountSlot(); | 2729 FeedbackVectorSlot feedback_slot = expr->CountSlot(); |
2733 switch (assign_type) { | 2730 switch (assign_type) { |
2734 case VARIABLE: { | 2731 case VARIABLE: { |
2735 Variable* variable = expr->expression()->AsVariableProxy()->var(); | 2732 Variable* variable = expr->expression()->AsVariableProxy()->var(); |
2736 VisitVariableAssignment(variable, expr->op(), feedback_slot); | 2733 VisitVariableAssignment(variable, expr->op(), feedback_slot); |
2737 break; | 2734 break; |
2738 } | 2735 } |
2739 case NAMED_PROPERTY: { | 2736 case NAMED_PROPERTY: { |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2779 default: | 2776 default: |
2780 VisitArithmeticExpression(binop); | 2777 VisitArithmeticExpression(binop); |
2781 break; | 2778 break; |
2782 } | 2779 } |
2783 } | 2780 } |
2784 | 2781 |
2785 | 2782 |
2786 void BytecodeGenerator::VisitCompareOperation(CompareOperation* expr) { | 2783 void BytecodeGenerator::VisitCompareOperation(CompareOperation* expr) { |
2787 Register lhs = VisitForRegisterValue(expr->left()); | 2784 Register lhs = VisitForRegisterValue(expr->left()); |
2788 VisitForAccumulatorValue(expr->right()); | 2785 VisitForAccumulatorValue(expr->right()); |
2789 builder()->CompareOperation(expr->op(), lhs, language_mode_strength()); | 2786 builder()->CompareOperation(expr->op(), lhs); |
2790 execution_result()->SetResultInAccumulator(); | 2787 execution_result()->SetResultInAccumulator(); |
2791 } | 2788 } |
2792 | 2789 |
2793 | 2790 |
2794 void BytecodeGenerator::VisitArithmeticExpression(BinaryOperation* expr) { | 2791 void BytecodeGenerator::VisitArithmeticExpression(BinaryOperation* expr) { |
2795 Register lhs = VisitForRegisterValue(expr->left()); | 2792 Register lhs = VisitForRegisterValue(expr->left()); |
2796 VisitForAccumulatorValue(expr->right()); | 2793 VisitForAccumulatorValue(expr->right()); |
2797 builder()->BinaryOperation(expr->op(), lhs, language_mode_strength()); | 2794 builder()->BinaryOperation(expr->op(), lhs); |
2798 execution_result()->SetResultInAccumulator(); | 2795 execution_result()->SetResultInAccumulator(); |
2799 } | 2796 } |
2800 | 2797 |
2801 | 2798 |
2802 void BytecodeGenerator::VisitSpread(Spread* expr) { UNREACHABLE(); } | 2799 void BytecodeGenerator::VisitSpread(Spread* expr) { UNREACHABLE(); } |
2803 | 2800 |
2804 | 2801 |
2805 void BytecodeGenerator::VisitEmptyParentheses(EmptyParentheses* expr) { | 2802 void BytecodeGenerator::VisitEmptyParentheses(EmptyParentheses* expr) { |
2806 UNREACHABLE(); | 2803 UNREACHABLE(); |
2807 } | 2804 } |
(...skipping 306 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3114 DCHECK(scope->declarations()->is_empty()); | 3111 DCHECK(scope->declarations()->is_empty()); |
3115 Visit(stmt); | 3112 Visit(stmt); |
3116 } | 3113 } |
3117 | 3114 |
3118 | 3115 |
3119 LanguageMode BytecodeGenerator::language_mode() const { | 3116 LanguageMode BytecodeGenerator::language_mode() const { |
3120 return info()->language_mode(); | 3117 return info()->language_mode(); |
3121 } | 3118 } |
3122 | 3119 |
3123 | 3120 |
3124 Strength BytecodeGenerator::language_mode_strength() const { | |
3125 return strength(language_mode()); | |
3126 } | |
3127 | |
3128 | |
3129 int BytecodeGenerator::feedback_index(FeedbackVectorSlot slot) const { | 3121 int BytecodeGenerator::feedback_index(FeedbackVectorSlot slot) const { |
3130 return info()->feedback_vector()->GetIndex(slot); | 3122 return info()->feedback_vector()->GetIndex(slot); |
3131 } | 3123 } |
3132 | 3124 |
3133 } // namespace interpreter | 3125 } // namespace interpreter |
3134 } // namespace internal | 3126 } // namespace internal |
3135 } // namespace v8 | 3127 } // namespace v8 |
OLD | NEW |