OLD | NEW |
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 3573 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3584 } else { | 3584 } else { |
3585 const uc16* data = reinterpret_cast<const uc16*>(raw_string->raw_data()); | 3585 const uc16* data = reinterpret_cast<const uc16*>(raw_string->raw_data()); |
3586 running_hash = StringHasher::ComputeRunningHash(running_hash, data, | 3586 running_hash = StringHasher::ComputeRunningHash(running_hash, data, |
3587 raw_string->length()); | 3587 raw_string->length()); |
3588 } | 3588 } |
3589 } | 3589 } |
3590 | 3590 |
3591 return running_hash; | 3591 return running_hash; |
3592 } | 3592 } |
3593 | 3593 |
| 3594 namespace { |
| 3595 |
| 3596 bool OnlyLastArgIsSpread(ZoneList<Expression*>* args) { |
| 3597 for (int i = 0; i < args->length() - 1; i++) { |
| 3598 if (args->at(i)->IsSpread()) { |
| 3599 return false; |
| 3600 } |
| 3601 } |
| 3602 return args->at(args->length() - 1)->IsSpread(); |
| 3603 } |
| 3604 |
| 3605 } // namespace |
| 3606 |
3594 ZoneList<Expression*>* Parser::PrepareSpreadArguments( | 3607 ZoneList<Expression*>* Parser::PrepareSpreadArguments( |
3595 ZoneList<Expression*>* list) { | 3608 ZoneList<Expression*>* list) { |
3596 ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(1, zone()); | 3609 ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(1, zone()); |
3597 if (list->length() == 1) { | 3610 if (list->length() == 1) { |
3598 // Spread-call with single spread argument produces an InternalArray | 3611 // Spread-call with single spread argument produces an InternalArray |
3599 // containing the values from the array. | 3612 // containing the values from the array. |
3600 // | 3613 // |
3601 // Function is called or constructed with the produced array of arguments | 3614 // Function is called or constructed with the produced array of arguments |
3602 // | 3615 // |
3603 // EG: Apply(Func, Spread(spread0)) | 3616 // EG: Apply(Func, Spread(spread0)) |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3647 list = new (zone()) ZoneList<Expression*>(1, zone()); | 3660 list = new (zone()) ZoneList<Expression*>(1, zone()); |
3648 list->Add(factory()->NewCallRuntime(Context::SPREAD_ARGUMENTS_INDEX, args, | 3661 list->Add(factory()->NewCallRuntime(Context::SPREAD_ARGUMENTS_INDEX, args, |
3649 kNoSourcePosition), | 3662 kNoSourcePosition), |
3650 zone()); | 3663 zone()); |
3651 return list; | 3664 return list; |
3652 } | 3665 } |
3653 UNREACHABLE(); | 3666 UNREACHABLE(); |
3654 } | 3667 } |
3655 | 3668 |
3656 Expression* Parser::SpreadCall(Expression* function, | 3669 Expression* Parser::SpreadCall(Expression* function, |
3657 ZoneList<Expression*>* args, int pos) { | 3670 ZoneList<Expression*>* args, int pos, |
| 3671 Call::PossiblyEval is_possibly_eval) { |
| 3672 // Handle these cases in BytecodeGenerator. |
| 3673 // [Call,New]WithSpread bytecodes aren't used with tailcalls - see |
| 3674 // https://crbug.com/v8/5867 |
| 3675 if (!allow_tailcalls() && OnlyLastArgIsSpread(args)) { |
| 3676 return factory()->NewCall(function, args, pos); |
| 3677 } |
| 3678 |
3658 if (function->IsSuperCallReference()) { | 3679 if (function->IsSuperCallReference()) { |
3659 // Super calls | 3680 // Super calls |
3660 // $super_constructor = %_GetSuperConstructor(<this-function>) | 3681 // $super_constructor = %_GetSuperConstructor(<this-function>) |
3661 // %reflect_construct($super_constructor, args, new.target) | 3682 // %reflect_construct($super_constructor, args, new.target) |
3662 | 3683 |
3663 bool only_last_arg_is_spread = false; | |
3664 for (int i = 0; i < args->length(); i++) { | |
3665 if (args->at(i)->IsSpread()) { | |
3666 if (i == args->length() - 1) { | |
3667 only_last_arg_is_spread = true; | |
3668 } | |
3669 break; | |
3670 } | |
3671 } | |
3672 | |
3673 if (only_last_arg_is_spread) { | |
3674 // Handle in BytecodeGenerator. | |
3675 Expression* super_call_ref = NewSuperCallReference(pos); | |
3676 return factory()->NewCall(super_call_ref, args, pos); | |
3677 } | |
3678 args = PrepareSpreadArguments(args); | 3684 args = PrepareSpreadArguments(args); |
3679 ZoneList<Expression*>* tmp = new (zone()) ZoneList<Expression*>(1, zone()); | 3685 ZoneList<Expression*>* tmp = new (zone()) ZoneList<Expression*>(1, zone()); |
3680 tmp->Add(function->AsSuperCallReference()->this_function_var(), zone()); | 3686 tmp->Add(function->AsSuperCallReference()->this_function_var(), zone()); |
3681 Expression* super_constructor = factory()->NewCallRuntime( | 3687 Expression* super_constructor = factory()->NewCallRuntime( |
3682 Runtime::kInlineGetSuperConstructor, tmp, pos); | 3688 Runtime::kInlineGetSuperConstructor, tmp, pos); |
3683 args->InsertAt(0, super_constructor, zone()); | 3689 args->InsertAt(0, super_constructor, zone()); |
3684 args->Add(function->AsSuperCallReference()->new_target_var(), zone()); | 3690 args->Add(function->AsSuperCallReference()->new_target_var(), zone()); |
3685 return factory()->NewCallRuntime(Context::REFLECT_CONSTRUCT_INDEX, args, | 3691 return factory()->NewCallRuntime(Context::REFLECT_CONSTRUCT_INDEX, args, |
3686 pos); | 3692 pos); |
3687 } else { | 3693 } else { |
(...skipping 21 matching lines...) Expand all Loading... |
3709 args->InsertAt(0, function, zone()); | 3715 args->InsertAt(0, function, zone()); |
3710 args->InsertAt(1, factory()->NewUndefinedLiteral(kNoSourcePosition), | 3716 args->InsertAt(1, factory()->NewUndefinedLiteral(kNoSourcePosition), |
3711 zone()); | 3717 zone()); |
3712 } | 3718 } |
3713 return factory()->NewCallRuntime(Context::REFLECT_APPLY_INDEX, args, pos); | 3719 return factory()->NewCallRuntime(Context::REFLECT_APPLY_INDEX, args, pos); |
3714 } | 3720 } |
3715 } | 3721 } |
3716 | 3722 |
3717 Expression* Parser::SpreadCallNew(Expression* function, | 3723 Expression* Parser::SpreadCallNew(Expression* function, |
3718 ZoneList<Expression*>* args, int pos) { | 3724 ZoneList<Expression*>* args, int pos) { |
| 3725 if (OnlyLastArgIsSpread(args)) { |
| 3726 // Handle in BytecodeGenerator. |
| 3727 return factory()->NewCallNew(function, args, pos); |
| 3728 } |
3719 args = PrepareSpreadArguments(args); | 3729 args = PrepareSpreadArguments(args); |
3720 args->InsertAt(0, function, zone()); | 3730 args->InsertAt(0, function, zone()); |
3721 | 3731 |
3722 return factory()->NewCallRuntime(Context::REFLECT_CONSTRUCT_INDEX, args, pos); | 3732 return factory()->NewCallRuntime(Context::REFLECT_CONSTRUCT_INDEX, args, pos); |
3723 } | 3733 } |
3724 | 3734 |
3725 | 3735 |
3726 void Parser::SetLanguageMode(Scope* scope, LanguageMode mode) { | 3736 void Parser::SetLanguageMode(Scope* scope, LanguageMode mode) { |
3727 v8::Isolate::UseCounterFeature feature; | 3737 v8::Isolate::UseCounterFeature feature; |
3728 if (is_sloppy(mode)) | 3738 if (is_sloppy(mode)) |
(...skipping 1296 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5025 | 5035 |
5026 return final_loop; | 5036 return final_loop; |
5027 } | 5037 } |
5028 | 5038 |
5029 #undef CHECK_OK | 5039 #undef CHECK_OK |
5030 #undef CHECK_OK_VOID | 5040 #undef CHECK_OK_VOID |
5031 #undef CHECK_FAILED | 5041 #undef CHECK_FAILED |
5032 | 5042 |
5033 } // namespace internal | 5043 } // namespace internal |
5034 } // namespace v8 | 5044 } // namespace v8 |
OLD | NEW |