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/code-stubs.h" | 9 #include "src/code-stubs.h" |
10 #include "src/compilation-info.h" | 10 #include "src/compilation-info.h" |
(...skipping 2470 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2481 RegisterAllocationScope register_scope(this); | 2481 RegisterAllocationScope register_scope(this); |
2482 SuperCallReference* super = expr->expression()->AsSuperCallReference(); | 2482 SuperCallReference* super = expr->expression()->AsSuperCallReference(); |
2483 | 2483 |
2484 // Prepare the constructor to the super call. | 2484 // Prepare the constructor to the super call. |
2485 Register this_function = VisitForRegisterValue(super->this_function_var()); | 2485 Register this_function = VisitForRegisterValue(super->this_function_var()); |
2486 builder()->CallRuntime(Runtime::kInlineGetSuperConstructor, this_function); | 2486 builder()->CallRuntime(Runtime::kInlineGetSuperConstructor, this_function); |
2487 | 2487 |
2488 Register constructor = this_function; // Re-use dead this_function register. | 2488 Register constructor = this_function; // Re-use dead this_function register. |
2489 builder()->StoreAccumulatorInRegister(constructor); | 2489 builder()->StoreAccumulatorInRegister(constructor); |
2490 | 2490 |
2491 RegisterList args = | 2491 ZoneList<Expression*>* args = expr->arguments(); |
2492 register_allocator()->NewRegisterList(expr->arguments()->length()); | |
2493 VisitArguments(expr->arguments(), args); | |
2494 | 2492 |
2495 // The new target is loaded into the accumulator from the | 2493 // When a super call contains a spread, a CallSuper AST node is only created |
2496 // {new.target} variable. | 2494 // if there is exactly one spread, and it is the last argument. |
2497 VisitForAccumulatorValue(super->new_target_var()); | 2495 if (!args->is_empty() && args->last()->IsSpread()) { |
| 2496 // Prepare the spread arguments. |
| 2497 RegisterList spread_prepare_args = |
| 2498 register_allocator()->NewRegisterList(args->length()); |
| 2499 VisitArguments(args, spread_prepare_args); |
2498 | 2500 |
2499 // Call construct. | 2501 builder()->CallRuntime(Runtime::kSpreadIterablePrepareVarargs, |
2500 builder()->SetExpressionPosition(expr); | 2502 spread_prepare_args); |
2501 // TODO(turbofan): For now we do gather feedback on super constructor | 2503 |
2502 // calls, utilizing the existing machinery to inline the actual call | 2504 // Call ReflectConstruct to do the actual super constructor call. |
2503 // target and the JSCreate for the implicit receiver allocation. This | 2505 RegisterList reflect_construct_args = |
2504 // is not an ideal solution for super constructor calls, but it gets | 2506 register_allocator()->NewRegisterList(4); |
2505 // the job done for now. In the long run we might want to revisit this | 2507 builder() |
2506 // and come up with a better way. | 2508 ->StoreAccumulatorInRegister(reflect_construct_args[2]) |
2507 int const feedback_slot_index = feedback_index(expr->CallFeedbackICSlot()); | 2509 .LoadUndefined() |
2508 builder()->New(constructor, args, feedback_slot_index); | 2510 .StoreAccumulatorInRegister(reflect_construct_args[0]) |
| 2511 .MoveRegister(constructor, reflect_construct_args[1]); |
| 2512 VisitForRegisterValue(super->new_target_var(), reflect_construct_args[3]); |
| 2513 builder()->CallJSRuntime(Context::REFLECT_CONSTRUCT_INDEX, |
| 2514 reflect_construct_args); |
| 2515 } else { |
| 2516 RegisterList args_regs = |
| 2517 register_allocator()->NewRegisterList(args->length()); |
| 2518 VisitArguments(args, args_regs); |
| 2519 // The new target is loaded into the accumulator from the |
| 2520 // {new.target} variable. |
| 2521 VisitForAccumulatorValue(super->new_target_var()); |
| 2522 |
| 2523 // Call construct. |
| 2524 builder()->SetExpressionPosition(expr); |
| 2525 // TODO(turbofan): For now we do gather feedback on super constructor |
| 2526 // calls, utilizing the existing machinery to inline the actual call |
| 2527 // target and the JSCreate for the implicit receiver allocation. This |
| 2528 // is not an ideal solution for super constructor calls, but it gets |
| 2529 // the job done for now. In the long run we might want to revisit this |
| 2530 // and come up with a better way. |
| 2531 int const feedback_slot_index = feedback_index(expr->CallFeedbackICSlot()); |
| 2532 builder()->New(constructor, args_regs, feedback_slot_index); |
| 2533 } |
2509 } | 2534 } |
2510 | 2535 |
2511 void BytecodeGenerator::VisitCallNew(CallNew* expr) { | 2536 void BytecodeGenerator::VisitCallNew(CallNew* expr) { |
2512 Register constructor = VisitForRegisterValue(expr->expression()); | 2537 Register constructor = VisitForRegisterValue(expr->expression()); |
2513 RegisterList args = | 2538 RegisterList args = |
2514 register_allocator()->NewRegisterList(expr->arguments()->length()); | 2539 register_allocator()->NewRegisterList(expr->arguments()->length()); |
2515 VisitArguments(expr->arguments(), args); | 2540 VisitArguments(expr->arguments(), args); |
2516 | 2541 |
2517 builder()->SetExpressionPosition(expr); | 2542 builder()->SetExpressionPosition(expr); |
2518 // The accumulator holds new target which is the same as the | 2543 // The accumulator holds new target which is the same as the |
(...skipping 287 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2806 | 2831 |
2807 void BytecodeGenerator::VisitArithmeticExpression(BinaryOperation* expr) { | 2832 void BytecodeGenerator::VisitArithmeticExpression(BinaryOperation* expr) { |
2808 // TODO(rmcilroy): Special case "x * 1.0" and "x * -1" which are generated for | 2833 // TODO(rmcilroy): Special case "x * 1.0" and "x * -1" which are generated for |
2809 // +x and -x by the parser. | 2834 // +x and -x by the parser. |
2810 Register lhs = VisitForRegisterValue(expr->left()); | 2835 Register lhs = VisitForRegisterValue(expr->left()); |
2811 VisitForAccumulatorValue(expr->right()); | 2836 VisitForAccumulatorValue(expr->right()); |
2812 FeedbackVectorSlot slot = expr->BinaryOperationFeedbackSlot(); | 2837 FeedbackVectorSlot slot = expr->BinaryOperationFeedbackSlot(); |
2813 builder()->BinaryOperation(expr->op(), lhs, feedback_index(slot)); | 2838 builder()->BinaryOperation(expr->op(), lhs, feedback_index(slot)); |
2814 } | 2839 } |
2815 | 2840 |
2816 void BytecodeGenerator::VisitSpread(Spread* expr) { UNREACHABLE(); } | 2841 void BytecodeGenerator::VisitSpread(Spread* expr) { Visit(expr->expression()); } |
2817 | 2842 |
2818 void BytecodeGenerator::VisitEmptyParentheses(EmptyParentheses* expr) { | 2843 void BytecodeGenerator::VisitEmptyParentheses(EmptyParentheses* expr) { |
2819 UNREACHABLE(); | 2844 UNREACHABLE(); |
2820 } | 2845 } |
2821 | 2846 |
2822 void BytecodeGenerator::VisitThisFunction(ThisFunction* expr) { | 2847 void BytecodeGenerator::VisitThisFunction(ThisFunction* expr) { |
2823 builder()->LoadAccumulatorWithRegister(Register::function_closure()); | 2848 builder()->LoadAccumulatorWithRegister(Register::function_closure()); |
2824 } | 2849 } |
2825 | 2850 |
2826 void BytecodeGenerator::VisitSuperCallReference(SuperCallReference* expr) { | 2851 void BytecodeGenerator::VisitSuperCallReference(SuperCallReference* expr) { |
(...skipping 371 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3198 } | 3223 } |
3199 | 3224 |
3200 Runtime::FunctionId BytecodeGenerator::StoreKeyedToSuperRuntimeId() { | 3225 Runtime::FunctionId BytecodeGenerator::StoreKeyedToSuperRuntimeId() { |
3201 return is_strict(language_mode()) ? Runtime::kStoreKeyedToSuper_Strict | 3226 return is_strict(language_mode()) ? Runtime::kStoreKeyedToSuper_Strict |
3202 : Runtime::kStoreKeyedToSuper_Sloppy; | 3227 : Runtime::kStoreKeyedToSuper_Sloppy; |
3203 } | 3228 } |
3204 | 3229 |
3205 } // namespace interpreter | 3230 } // namespace interpreter |
3206 } // namespace internal | 3231 } // namespace internal |
3207 } // namespace v8 | 3232 } // namespace v8 |
OLD | NEW |