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 3526 matching lines...) Loading... | |
3537 a->Goto(&end); | 3537 a->Goto(&end); |
3538 } | 3538 } |
3539 | 3539 |
3540 a->BIND(&end); | 3540 a->BIND(&end); |
3541 return var_result.value(); | 3541 return var_result.value(); |
3542 } | 3542 } |
3543 | 3543 |
3544 } // namespace | 3544 } // namespace |
3545 | 3545 |
3546 Node* CodeStubAssembler::SubString(Node* context, Node* string, Node* from, | 3546 Node* CodeStubAssembler::SubString(Node* context, Node* string, Node* from, |
3547 Node* to) { | 3547 Node* to, SubStringFlags flags) { |
3548 DCHECK(flags == SubStringFlags::NONE || | |
3549 flags == SubStringFlags::FROM_TO_ARE_BOUNDED); | |
3548 VARIABLE(var_result, MachineRepresentation::kTagged); | 3550 VARIABLE(var_result, MachineRepresentation::kTagged); |
3549 ToDirectStringAssembler to_direct(state(), string); | 3551 ToDirectStringAssembler to_direct(state(), string); |
3550 Label end(this), runtime(this); | 3552 Label end(this), runtime(this); |
3551 | 3553 |
3552 // Make sure first argument is a string. | 3554 // Make sure first argument is a string. |
3553 CSA_ASSERT(this, TaggedIsNotSmi(string)); | 3555 CSA_ASSERT(this, TaggedIsNotSmi(string)); |
3554 CSA_ASSERT(this, IsString(string)); | 3556 CSA_ASSERT(this, IsString(string)); |
3555 | 3557 |
3556 // Make sure that both from and to are non-negative smis. | 3558 // Make sure that both from and to are non-negative smis. |
3557 | 3559 |
3558 GotoIfNot(TaggedIsPositiveSmi(from), &runtime); | 3560 if (flags == SubStringFlags::NONE) { |
3559 GotoIfNot(TaggedIsPositiveSmi(to), &runtime); | 3561 GotoIfNot(TaggedIsPositiveSmi(from), &runtime); |
jgruber
2017/05/11 08:57:41
We should assert the conditions otherwise, same be
mvstanton
2017/05/12 11:00:43
Done.
| |
3562 GotoIfNot(TaggedIsPositiveSmi(to), &runtime); | |
3563 } | |
3560 | 3564 |
3561 Node* const substr_length = SmiSub(to, from); | 3565 Node* const substr_length = SmiSub(to, from); |
3562 Node* const string_length = LoadStringLength(string); | 3566 Node* const string_length = LoadStringLength(string); |
3563 | 3567 |
3564 // Begin dispatching based on substring length. | 3568 // Begin dispatching based on substring length. |
3565 | 3569 |
3566 Label original_string_or_invalid_length(this); | 3570 Label original_string_or_invalid_length(this); |
3567 GotoIf(SmiAboveOrEqual(substr_length, string_length), | 3571 GotoIf(SmiAboveOrEqual(substr_length, string_length), |
3568 &original_string_or_invalid_length); | 3572 &original_string_or_invalid_length); |
3569 | 3573 |
(...skipping 80 matching lines...) Loading... | |
3650 // Substrings of length 1 are generated through CharCodeAt and FromCharCode. | 3654 // Substrings of length 1 are generated through CharCodeAt and FromCharCode. |
3651 BIND(&single_char); | 3655 BIND(&single_char); |
3652 { | 3656 { |
3653 Node* char_code = StringCharCodeAt(string, from); | 3657 Node* char_code = StringCharCodeAt(string, from); |
3654 var_result.Bind(StringFromCharCode(char_code)); | 3658 var_result.Bind(StringFromCharCode(char_code)); |
3655 Goto(&end); | 3659 Goto(&end); |
3656 } | 3660 } |
3657 | 3661 |
3658 BIND(&original_string_or_invalid_length); | 3662 BIND(&original_string_or_invalid_length); |
3659 { | 3663 { |
3660 // Longer than original string's length or negative: unsafe arguments. | 3664 if (flags == SubStringFlags::NONE) { |
3661 GotoIf(SmiAbove(substr_length, string_length), &runtime); | 3665 // Longer than original string's length or negative: unsafe arguments. |
3666 GotoIf(SmiAbove(substr_length, string_length), &runtime); | |
3667 } | |
3662 | 3668 |
3663 // Equal length - check if {from, to} == {0, str.length}. | 3669 // Equal length - check if {from, to} == {0, str.length}. |
3664 GotoIf(SmiAbove(from, SmiConstant(Smi::kZero)), &runtime); | 3670 GotoIf(SmiAbove(from, SmiConstant(Smi::kZero)), &runtime); |
3665 | 3671 |
3666 // Return the original string (substr_length == string_length). | 3672 // Return the original string (substr_length == string_length). |
3667 | 3673 |
3668 Counters* counters = isolate()->counters(); | 3674 Counters* counters = isolate()->counters(); |
3669 IncrementCounter(counters->sub_string_native(), 1); | 3675 IncrementCounter(counters->sub_string_native(), 1); |
3670 | 3676 |
3671 var_result.Bind(string); | 3677 var_result.Bind(string); |
(...skipping 5404 matching lines...) Loading... | |
9076 formatted.c_str(), TENURED); | 9082 formatted.c_str(), TENURED); |
9077 CallRuntime(Runtime::kGlobalPrint, NoContextConstant(), | 9083 CallRuntime(Runtime::kGlobalPrint, NoContextConstant(), |
9078 HeapConstant(string)); | 9084 HeapConstant(string)); |
9079 } | 9085 } |
9080 CallRuntime(Runtime::kDebugPrint, NoContextConstant(), tagged_value); | 9086 CallRuntime(Runtime::kDebugPrint, NoContextConstant(), tagged_value); |
9081 #endif | 9087 #endif |
9082 } | 9088 } |
9083 | 9089 |
9084 } // namespace internal | 9090 } // namespace internal |
9085 } // namespace v8 | 9091 } // namespace v8 |
OLD | NEW |