Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(61)

Side by Side Diff: src/parsing/parser.cc

Issue 2629363002: [Ignition/turbo] Add a CallWithSpread bytecode. (Closed)
Patch Set: Remove case for 1 arg only from PrepareSpreadArguments Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 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/parsing/parser.h" 5 #include "src/parsing/parser.h"
6 6
7 #include <memory> 7 #include <memory>
8 8
9 #include "src/api.h" 9 #include "src/api.h"
10 #include "src/ast/ast-expression-rewriter.h" 10 #include "src/ast/ast-expression-rewriter.h"
(...skipping 3674 matching lines...) Expand 10 before | Expand all | Expand 10 after
3685 } else { 3685 } else {
3686 const uc16* data = reinterpret_cast<const uc16*>(raw_string->raw_data()); 3686 const uc16* data = reinterpret_cast<const uc16*>(raw_string->raw_data());
3687 running_hash = StringHasher::ComputeRunningHash(running_hash, data, 3687 running_hash = StringHasher::ComputeRunningHash(running_hash, data,
3688 raw_string->length()); 3688 raw_string->length());
3689 } 3689 }
3690 } 3690 }
3691 3691
3692 return running_hash; 3692 return running_hash;
3693 } 3693 }
3694 3694
3695 namespace {
3696
3697 bool OnlyLastArgIsSpread(ZoneList<Expression*>* args) {
3698 for (int i = 0; i < args->length() - 1; i++) {
3699 if (args->at(i)->IsSpread()) {
3700 return false;
3701 }
3702 }
3703 return args->at(args->length() - 1)->IsSpread();
3704 }
3705
3706 } // namespace
3707
3695 ZoneList<Expression*>* Parser::PrepareSpreadArguments( 3708 ZoneList<Expression*>* Parser::PrepareSpreadArguments(
3696 ZoneList<Expression*>* list) { 3709 ZoneList<Expression*>* list) {
3710 // Here we only deal with multiple arguments where the spread is not at the
3711 // end, or there are multiple spreads.
3712 DCHECK_GT(list->length(), 1);
3713 DCHECK(!OnlyLastArgIsSpread(list));
3714
3697 ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(1, zone()); 3715 ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(1, zone());
3698 if (list->length() == 1) { 3716 // Spread-call with multiple arguments produces array literals for each
3699 // Spread-call with single spread argument produces an InternalArray 3717 // sequences of unspread arguments, and converts each spread iterable to
3700 // containing the values from the array. 3718 // an Internal array. Finally, all of these produced arrays are flattened
3701 // 3719 // into a single InternalArray, containing the arguments for the call.
3702 // Function is called or constructed with the produced array of arguments 3720 //
3703 // 3721 // EG: Apply(Func, Flatten([unspread0, unspread1], Spread(spread0),
3704 // EG: Apply(Func, Spread(spread0)) 3722 // Spread(spread1), [unspread2, unspread3]))
3723 int i = 0;
3724 int n = list->length();
3725 while (i < n) {
3726 if (!list->at(i)->IsSpread()) {
3727 ZoneList<Expression*>* unspread =
3728 new (zone()) ZoneList<Expression*>(1, zone());
3729
3730 // Push array of unspread parameters
3731 while (i < n && !list->at(i)->IsSpread()) {
3732 unspread->Add(list->at(i++), zone());
3733 }
3734 int literal_index = function_state_->NextMaterializedLiteralIndex();
3735 args->Add(factory()->NewArrayLiteral(unspread, literal_index,
3736 kNoSourcePosition),
3737 zone());
3738
3739 if (i == n) break;
3740 }
3741
3742 // Push eagerly spread argument
3705 ZoneList<Expression*>* spread_list = 3743 ZoneList<Expression*>* spread_list =
3706 new (zone()) ZoneList<Expression*>(0, zone()); 3744 new (zone()) ZoneList<Expression*>(1, zone());
3707 spread_list->Add(list->at(0)->AsSpread()->expression(), zone()); 3745 spread_list->Add(list->at(i++)->AsSpread()->expression(), zone());
3708 args->Add(factory()->NewCallRuntime(Runtime::kSpreadIterablePrepare, 3746 args->Add(factory()->NewCallRuntime(Context::SPREAD_ITERABLE_INDEX,
3709 spread_list, kNoSourcePosition), 3747 spread_list, kNoSourcePosition),
3710 zone()); 3748 zone());
3711 return args; 3749 }
3712 } else {
3713 // Spread-call with multiple arguments produces array literals for each
3714 // sequences of unspread arguments, and converts each spread iterable to
3715 // an Internal array. Finally, all of these produced arrays are flattened
3716 // into a single InternalArray, containing the arguments for the call.
3717 //
3718 // EG: Apply(Func, Flatten([unspread0, unspread1], Spread(spread0),
3719 // Spread(spread1), [unspread2, unspread3]))
3720 int i = 0;
3721 int n = list->length();
3722 while (i < n) {
3723 if (!list->at(i)->IsSpread()) {
3724 ZoneList<Expression*>* unspread =
3725 new (zone()) ZoneList<Expression*>(1, zone());
3726 3750
3727 // Push array of unspread parameters 3751 list = new (zone()) ZoneList<Expression*>(1, zone());
3728 while (i < n && !list->at(i)->IsSpread()) { 3752 list->Add(factory()->NewCallRuntime(Context::SPREAD_ARGUMENTS_INDEX, args,
3729 unspread->Add(list->at(i++), zone()); 3753 kNoSourcePosition),
3730 } 3754 zone());
3731 int literal_index = function_state_->NextMaterializedLiteralIndex(); 3755 return list;
3732 args->Add(factory()->NewArrayLiteral(unspread, literal_index,
3733 kNoSourcePosition),
3734 zone());
3735
3736 if (i == n) break;
3737 }
3738
3739 // Push eagerly spread argument
3740 ZoneList<Expression*>* spread_list =
3741 new (zone()) ZoneList<Expression*>(1, zone());
3742 spread_list->Add(list->at(i++)->AsSpread()->expression(), zone());
3743 args->Add(factory()->NewCallRuntime(Context::SPREAD_ITERABLE_INDEX,
3744 spread_list, kNoSourcePosition),
3745 zone());
3746 }
3747
3748 list = new (zone()) ZoneList<Expression*>(1, zone());
3749 list->Add(factory()->NewCallRuntime(Context::SPREAD_ARGUMENTS_INDEX, args,
3750 kNoSourcePosition),
3751 zone());
3752 return list;
3753 }
3754 UNREACHABLE();
3755 } 3756 }
3756 3757
3757 Expression* Parser::SpreadCall(Expression* function, 3758 Expression* Parser::SpreadCall(Expression* function,
3758 ZoneList<Expression*>* args, int pos) { 3759 ZoneList<Expression*>* args, int pos,
3760 Call::PossiblyEval is_possibly_eval) {
3761 // Handle these cases in BytecodeGenerator.
3762 if (OnlyLastArgIsSpread(args)) {
3763 if (function->IsSuperCallReference()) {
3764 function = NewSuperCallReference(pos);
3765 }
3766 return factory()->NewCall(function, args, pos);
3767 }
3768
3759 if (function->IsSuperCallReference()) { 3769 if (function->IsSuperCallReference()) {
3760 // Super calls 3770 // Super calls
3761 // $super_constructor = %_GetSuperConstructor(<this-function>) 3771 // $super_constructor = %_GetSuperConstructor(<this-function>)
3762 // %reflect_construct($super_constructor, args, new.target) 3772 // %reflect_construct($super_constructor, args, new.target)
3763 3773
3764 bool only_last_arg_is_spread = false;
3765 for (int i = 0; i < args->length(); i++) {
3766 if (args->at(i)->IsSpread()) {
3767 if (i == args->length() - 1) {
3768 only_last_arg_is_spread = true;
3769 }
3770 break;
3771 }
3772 }
3773
3774 if (only_last_arg_is_spread) {
3775 // Handle in BytecodeGenerator.
3776 Expression* super_call_ref = NewSuperCallReference(pos);
3777 return factory()->NewCall(super_call_ref, args, pos);
3778 }
3779 args = PrepareSpreadArguments(args); 3774 args = PrepareSpreadArguments(args);
3780 ZoneList<Expression*>* tmp = new (zone()) ZoneList<Expression*>(1, zone()); 3775 ZoneList<Expression*>* tmp = new (zone()) ZoneList<Expression*>(1, zone());
3781 tmp->Add(function->AsSuperCallReference()->this_function_var(), zone()); 3776 tmp->Add(function->AsSuperCallReference()->this_function_var(), zone());
3782 Expression* super_constructor = factory()->NewCallRuntime( 3777 Expression* super_constructor = factory()->NewCallRuntime(
3783 Runtime::kInlineGetSuperConstructor, tmp, pos); 3778 Runtime::kInlineGetSuperConstructor, tmp, pos);
3784 args->InsertAt(0, super_constructor, zone()); 3779 args->InsertAt(0, super_constructor, zone());
3785 args->Add(function->AsSuperCallReference()->new_target_var(), zone()); 3780 args->Add(function->AsSuperCallReference()->new_target_var(), zone());
3786 return factory()->NewCallRuntime(Context::REFLECT_CONSTRUCT_INDEX, args, 3781 return factory()->NewCallRuntime(Context::REFLECT_CONSTRUCT_INDEX, args,
3787 pos); 3782 pos);
3788 } else { 3783 } else {
(...skipping 21 matching lines...) Expand all
3810 args->InsertAt(0, function, zone()); 3805 args->InsertAt(0, function, zone());
3811 args->InsertAt(1, factory()->NewUndefinedLiteral(kNoSourcePosition), 3806 args->InsertAt(1, factory()->NewUndefinedLiteral(kNoSourcePosition),
3812 zone()); 3807 zone());
3813 } 3808 }
3814 return factory()->NewCallRuntime(Context::REFLECT_APPLY_INDEX, args, pos); 3809 return factory()->NewCallRuntime(Context::REFLECT_APPLY_INDEX, args, pos);
3815 } 3810 }
3816 } 3811 }
3817 3812
3818 Expression* Parser::SpreadCallNew(Expression* function, 3813 Expression* Parser::SpreadCallNew(Expression* function,
3819 ZoneList<Expression*>* args, int pos) { 3814 ZoneList<Expression*>* args, int pos) {
3815 if (OnlyLastArgIsSpread(args)) {
3816 // Handle in BytecodeGenerator.
3817 return factory()->NewCallNew(function, args, pos);
3818 }
3820 args = PrepareSpreadArguments(args); 3819 args = PrepareSpreadArguments(args);
3821 args->InsertAt(0, function, zone()); 3820 args->InsertAt(0, function, zone());
3822 3821
3823 return factory()->NewCallRuntime(Context::REFLECT_CONSTRUCT_INDEX, args, pos); 3822 return factory()->NewCallRuntime(Context::REFLECT_CONSTRUCT_INDEX, args, pos);
3824 } 3823 }
3825 3824
3826 3825
3827 void Parser::SetLanguageMode(Scope* scope, LanguageMode mode) { 3826 void Parser::SetLanguageMode(Scope* scope, LanguageMode mode) {
3828 v8::Isolate::UseCounterFeature feature; 3827 v8::Isolate::UseCounterFeature feature;
3829 if (is_sloppy(mode)) 3828 if (is_sloppy(mode))
(...skipping 1299 matching lines...) Expand 10 before | Expand all | Expand 10 after
5129 5128
5130 return final_loop; 5129 return final_loop;
5131 } 5130 }
5132 5131
5133 #undef CHECK_OK 5132 #undef CHECK_OK
5134 #undef CHECK_OK_VOID 5133 #undef CHECK_OK_VOID
5135 #undef CHECK_FAILED 5134 #undef CHECK_FAILED
5136 5135
5137 } // namespace internal 5136 } // namespace internal
5138 } // namespace v8 5137 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698