| OLD | NEW |
| 1 // Copyright 2016 the V8 project authors. All rights reserved. | 1 // Copyright 2016 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 #include "src/code-stub-assembler.h" | 4 #include "src/code-stub-assembler.h" |
| 5 #include "src/code-factory.h" | 5 #include "src/code-factory.h" |
| 6 #include "src/frames-inl.h" | 6 #include "src/frames-inl.h" |
| 7 #include "src/frames.h" | 7 #include "src/frames.h" |
| 8 | 8 |
| 9 namespace v8 { | 9 namespace v8 { |
| 10 namespace internal { | 10 namespace internal { |
| (...skipping 3530 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3541 a->Goto(&end); | 3541 a->Goto(&end); |
| 3542 } | 3542 } |
| 3543 | 3543 |
| 3544 a->BIND(&end); | 3544 a->BIND(&end); |
| 3545 return var_result.value(); | 3545 return var_result.value(); |
| 3546 } | 3546 } |
| 3547 | 3547 |
| 3548 } // namespace | 3548 } // namespace |
| 3549 | 3549 |
| 3550 Node* CodeStubAssembler::SubString(Node* context, Node* string, Node* from, | 3550 Node* CodeStubAssembler::SubString(Node* context, Node* string, Node* from, |
| 3551 Node* to) { | 3551 Node* to, SubStringFlags flags) { |
| 3552 DCHECK(flags == SubStringFlags::NONE || |
| 3553 flags == SubStringFlags::FROM_TO_ARE_BOUNDED); |
| 3552 VARIABLE(var_result, MachineRepresentation::kTagged); | 3554 VARIABLE(var_result, MachineRepresentation::kTagged); |
| 3553 ToDirectStringAssembler to_direct(state(), string); | 3555 ToDirectStringAssembler to_direct(state(), string); |
| 3554 Label end(this), runtime(this); | 3556 Label end(this), runtime(this); |
| 3555 | 3557 |
| 3556 // Make sure first argument is a string. | 3558 // Make sure first argument is a string. |
| 3557 CSA_ASSERT(this, TaggedIsNotSmi(string)); | 3559 CSA_ASSERT(this, TaggedIsNotSmi(string)); |
| 3558 CSA_ASSERT(this, IsString(string)); | 3560 CSA_ASSERT(this, IsString(string)); |
| 3559 | 3561 |
| 3560 // Make sure that both from and to are non-negative smis. | 3562 // Make sure that both from and to are non-negative smis. |
| 3561 | 3563 |
| 3562 GotoIfNot(TaggedIsPositiveSmi(from), &runtime); | 3564 if (flags == SubStringFlags::NONE) { |
| 3563 GotoIfNot(TaggedIsPositiveSmi(to), &runtime); | 3565 GotoIfNot(TaggedIsPositiveSmi(from), &runtime); |
| 3566 GotoIfNot(TaggedIsPositiveSmi(to), &runtime); |
| 3567 } else { |
| 3568 CSA_ASSERT(this, TaggedIsPositiveSmi(from)); |
| 3569 CSA_ASSERT(this, TaggedIsPositiveSmi(to)); |
| 3570 } |
| 3564 | 3571 |
| 3565 Node* const substr_length = SmiSub(to, from); | 3572 Node* const substr_length = SmiSub(to, from); |
| 3566 Node* const string_length = LoadStringLength(string); | 3573 Node* const string_length = LoadStringLength(string); |
| 3567 | 3574 |
| 3568 // Begin dispatching based on substring length. | 3575 // Begin dispatching based on substring length. |
| 3569 | 3576 |
| 3570 Label original_string_or_invalid_length(this); | 3577 Label original_string_or_invalid_length(this); |
| 3571 GotoIf(SmiAboveOrEqual(substr_length, string_length), | 3578 GotoIf(SmiAboveOrEqual(substr_length, string_length), |
| 3572 &original_string_or_invalid_length); | 3579 &original_string_or_invalid_length); |
| 3573 | 3580 |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3654 // Substrings of length 1 are generated through CharCodeAt and FromCharCode. | 3661 // Substrings of length 1 are generated through CharCodeAt and FromCharCode. |
| 3655 BIND(&single_char); | 3662 BIND(&single_char); |
| 3656 { | 3663 { |
| 3657 Node* char_code = StringCharCodeAt(string, from); | 3664 Node* char_code = StringCharCodeAt(string, from); |
| 3658 var_result.Bind(StringFromCharCode(char_code)); | 3665 var_result.Bind(StringFromCharCode(char_code)); |
| 3659 Goto(&end); | 3666 Goto(&end); |
| 3660 } | 3667 } |
| 3661 | 3668 |
| 3662 BIND(&original_string_or_invalid_length); | 3669 BIND(&original_string_or_invalid_length); |
| 3663 { | 3670 { |
| 3664 // Longer than original string's length or negative: unsafe arguments. | 3671 if (flags == SubStringFlags::NONE) { |
| 3665 GotoIf(SmiAbove(substr_length, string_length), &runtime); | 3672 // Longer than original string's length or negative: unsafe arguments. |
| 3673 GotoIf(SmiAbove(substr_length, string_length), &runtime); |
| 3674 } else { |
| 3675 // with flag SubStringFlags::FROM_TO_ARE_BOUNDED, the only way we can |
| 3676 // get here is if substr_length is equal to string_length. |
| 3677 CSA_ASSERT(this, SmiEqual(substr_length, string_length)); |
| 3678 } |
| 3666 | 3679 |
| 3667 // Equal length - check if {from, to} == {0, str.length}. | 3680 // Equal length - check if {from, to} == {0, str.length}. |
| 3668 GotoIf(SmiAbove(from, SmiConstant(Smi::kZero)), &runtime); | 3681 GotoIf(SmiAbove(from, SmiConstant(Smi::kZero)), &runtime); |
| 3669 | 3682 |
| 3670 // Return the original string (substr_length == string_length). | 3683 // Return the original string (substr_length == string_length). |
| 3671 | 3684 |
| 3672 Counters* counters = isolate()->counters(); | 3685 Counters* counters = isolate()->counters(); |
| 3673 IncrementCounter(counters->sub_string_native(), 1); | 3686 IncrementCounter(counters->sub_string_native(), 1); |
| 3674 | 3687 |
| 3675 var_result.Bind(string); | 3688 var_result.Bind(string); |
| (...skipping 5404 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9080 formatted.c_str(), TENURED); | 9093 formatted.c_str(), TENURED); |
| 9081 CallRuntime(Runtime::kGlobalPrint, NoContextConstant(), | 9094 CallRuntime(Runtime::kGlobalPrint, NoContextConstant(), |
| 9082 HeapConstant(string)); | 9095 HeapConstant(string)); |
| 9083 } | 9096 } |
| 9084 CallRuntime(Runtime::kDebugPrint, NoContextConstant(), tagged_value); | 9097 CallRuntime(Runtime::kDebugPrint, NoContextConstant(), tagged_value); |
| 9085 #endif | 9098 #endif |
| 9086 } | 9099 } |
| 9087 | 9100 |
| 9088 } // namespace internal | 9101 } // namespace internal |
| 9089 } // namespace v8 | 9102 } // namespace v8 |
| OLD | NEW |