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 2564 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2575 void BytecodeGenerator::VisitCallSuper(Call* expr) { | 2575 void BytecodeGenerator::VisitCallSuper(Call* expr) { |
2576 RegisterAllocationScope register_scope(this); | 2576 RegisterAllocationScope register_scope(this); |
2577 SuperCallReference* super = expr->expression()->AsSuperCallReference(); | 2577 SuperCallReference* super = expr->expression()->AsSuperCallReference(); |
2578 | 2578 |
2579 // Prepare the constructor to the super call. | 2579 // Prepare the constructor to the super call. |
2580 VisitForAccumulatorValue(super->this_function_var()); | 2580 VisitForAccumulatorValue(super->this_function_var()); |
2581 Register constructor = register_allocator()->NewRegister(); | 2581 Register constructor = register_allocator()->NewRegister(); |
2582 builder()->GetSuperConstructor(constructor); | 2582 builder()->GetSuperConstructor(constructor); |
2583 | 2583 |
2584 ZoneList<Expression*>* args = expr->arguments(); | 2584 ZoneList<Expression*>* args = expr->arguments(); |
| 2585 RegisterList args_regs = register_allocator()->NewGrowableRegisterList(); |
| 2586 VisitArguments(args, &args_regs); |
| 2587 // The new target is loaded into the accumulator from the |
| 2588 // {new.target} variable. |
| 2589 VisitForAccumulatorValue(super->new_target_var()); |
| 2590 builder()->SetExpressionPosition(expr); |
2585 | 2591 |
2586 // When a super call contains a spread, a CallSuper AST node is only created | 2592 // When a super call contains a spread, a CallSuper AST node is only created |
2587 // if there is exactly one spread, and it is the last argument. | 2593 // if there is exactly one spread, and it is the last argument. |
2588 if (!args->is_empty() && args->last()->IsSpread()) { | 2594 if (!args->is_empty() && args->last()->IsSpread()) { |
2589 RegisterList args_regs = register_allocator()->NewGrowableRegisterList(); | 2595 // TODO(petermarshall): Collect type on the feedback slot. |
2590 Register constructor_arg = | 2596 builder()->NewWithSpread(constructor, args_regs); |
2591 register_allocator()->GrowRegisterList(&args_regs); | |
2592 builder()->MoveRegister(constructor, constructor_arg); | |
2593 // Reserve argument reg for new.target in correct place for runtime call. | |
2594 // TODO(petermarshall): Remove this when changing bytecode to use the new | |
2595 // stub. | |
2596 Register new_target = register_allocator()->GrowRegisterList(&args_regs); | |
2597 VisitArguments(args, &args_regs); | |
2598 VisitForRegisterValue(super->new_target_var(), new_target); | |
2599 builder()->NewWithSpread(args_regs); | |
2600 } else { | 2597 } else { |
2601 RegisterList args_regs = register_allocator()->NewGrowableRegisterList(); | |
2602 VisitArguments(args, &args_regs); | |
2603 // The new target is loaded into the accumulator from the | |
2604 // {new.target} variable. | |
2605 VisitForAccumulatorValue(super->new_target_var()); | |
2606 | |
2607 // Call construct. | 2598 // Call construct. |
2608 builder()->SetExpressionPosition(expr); | |
2609 // TODO(turbofan): For now we do gather feedback on super constructor | 2599 // TODO(turbofan): For now we do gather feedback on super constructor |
2610 // calls, utilizing the existing machinery to inline the actual call | 2600 // calls, utilizing the existing machinery to inline the actual call |
2611 // target and the JSCreate for the implicit receiver allocation. This | 2601 // target and the JSCreate for the implicit receiver allocation. This |
2612 // is not an ideal solution for super constructor calls, but it gets | 2602 // is not an ideal solution for super constructor calls, but it gets |
2613 // the job done for now. In the long run we might want to revisit this | 2603 // the job done for now. In the long run we might want to revisit this |
2614 // and come up with a better way. | 2604 // and come up with a better way. |
2615 int const feedback_slot_index = feedback_index(expr->CallFeedbackICSlot()); | 2605 int const feedback_slot_index = feedback_index(expr->CallFeedbackICSlot()); |
2616 builder()->New(constructor, args_regs, feedback_slot_index); | 2606 builder()->New(constructor, args_regs, feedback_slot_index); |
2617 } | 2607 } |
2618 } | 2608 } |
(...skipping 749 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3368 } | 3358 } |
3369 | 3359 |
3370 Runtime::FunctionId BytecodeGenerator::StoreKeyedToSuperRuntimeId() { | 3360 Runtime::FunctionId BytecodeGenerator::StoreKeyedToSuperRuntimeId() { |
3371 return is_strict(language_mode()) ? Runtime::kStoreKeyedToSuper_Strict | 3361 return is_strict(language_mode()) ? Runtime::kStoreKeyedToSuper_Strict |
3372 : Runtime::kStoreKeyedToSuper_Sloppy; | 3362 : Runtime::kStoreKeyedToSuper_Sloppy; |
3373 } | 3363 } |
3374 | 3364 |
3375 } // namespace interpreter | 3365 } // namespace interpreter |
3376 } // namespace internal | 3366 } // namespace internal |
3377 } // namespace v8 | 3367 } // namespace v8 |
OLD | NEW |