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