OLD | NEW |
---|---|
1 // Copyright 2006-2008 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2008 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 3872 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3883 | 3883 |
3884 // Check the hash code is there. | 3884 // Check the hash code is there. |
3885 ASSERT(length_field() & kHashComputedMask); | 3885 ASSERT(length_field() & kHashComputedMask); |
3886 return field >> kHashShift; | 3886 return field >> kHashShift; |
3887 } | 3887 } |
3888 | 3888 |
3889 | 3889 |
3890 bool String::ComputeArrayIndex(unibrow::CharacterStream* buffer, | 3890 bool String::ComputeArrayIndex(unibrow::CharacterStream* buffer, |
3891 uint32_t* index, | 3891 uint32_t* index, |
3892 int length) { | 3892 int length) { |
3893 if (length == 0) return false; | 3893 if (length == 0 || length > kMaxArrayIndexSize) return false; |
3894 uc32 ch = buffer->GetNext(); | 3894 uc32 ch = buffer->GetNext(); |
3895 | 3895 |
3896 // If the string begins with a '0' character, it must only consist | 3896 // If the string begins with a '0' character, it must only consist |
3897 // of it to be a legal array index. | 3897 // of it to be a legal array index. |
3898 if (ch == '0') { | 3898 if (ch == '0') { |
3899 *index = 0; | 3899 *index = 0; |
3900 return length == 1; | 3900 return length == 1; |
3901 } | 3901 } |
3902 | 3902 |
3903 // Convert string to uint32 array index; character by character. | 3903 // Convert string to uint32 array index; character by character. |
3904 int d = ch - '0'; | 3904 int d = ch - '0'; |
3905 if (d < 0 || d > 9) return false; | 3905 if (d < 0 || d > 9) return false; |
3906 uint32_t result = d; | 3906 uint32_t result = d; |
3907 while (buffer->has_more()) { | 3907 while (buffer->has_more()) { |
3908 d = buffer->GetNext() - '0'; | 3908 d = buffer->GetNext() - '0'; |
3909 if (d < 0 || d > 9) return false; | 3909 if (d < 0 || d > 9) return false; |
3910 // Check that the new result is below the 32 bit limit. | 3910 // Check that the new result is below the 32 bit limit. |
3911 if (result > 429496729U - ((d > 5) ? 1 : 0)) return false; | 3911 if (result > 429496729U - ((d > 5) ? 1 : 0)) return false; |
3912 result = (result * 10) + d; | 3912 result = (result * 10) + d; |
3913 } | 3913 } |
3914 | 3914 |
3915 *index = result; | 3915 *index = result; |
3916 return true; | 3916 return true; |
3917 } | 3917 } |
3918 | 3918 |
3919 | 3919 |
3920 bool String::SlowAsArrayIndex(uint32_t* index) { | 3920 bool String::SlowAsArrayIndex(uint32_t* index) { |
3921 StringInputBuffer buffer(this); | 3921 if (length() <= kMaxCachedArrayIndexLength) { |
3922 return ComputeArrayIndex(&buffer, index, length()); | 3922 Hash(); // force computation of hash code |
bak
2008/10/22 13:25:14
Capitalize to Force and add period.
| |
3923 uint32_t field = length_field(); | |
3924 if ((field & kIsArrayIndexMask) == 0) return false; | |
3925 *index = (field & ((1 << kShortLengthShift) - 1)) >> kLongLengthShift; | |
3926 return true; | |
3927 } else { | |
3928 StringInputBuffer buffer(this); | |
3929 return ComputeArrayIndex(&buffer, index, length()); | |
3930 } | |
3923 } | 3931 } |
3924 | 3932 |
3925 | 3933 |
3926 static inline uint32_t HashField(uint32_t hash, bool is_array_index) { | 3934 static inline uint32_t HashField(uint32_t hash, bool is_array_index) { |
3927 uint32_t result = | 3935 uint32_t result = |
3928 (hash << String::kLongLengthShift) | String::kHashComputedMask; | 3936 (hash << String::kLongLengthShift) | String::kHashComputedMask; |
3929 if (is_array_index) result |= String::kIsArrayIndexMask; | 3937 if (is_array_index) result |= String::kIsArrayIndexMask; |
3930 return result; | 3938 return result; |
3931 } | 3939 } |
3932 | 3940 |
(...skipping 16 matching lines...) Expand all Loading... | |
3949 } | 3957 } |
3950 } | 3958 } |
3951 | 3959 |
3952 | 3960 |
3953 uint32_t String::ComputeLengthAndHashField(unibrow::CharacterStream* buffer, | 3961 uint32_t String::ComputeLengthAndHashField(unibrow::CharacterStream* buffer, |
3954 int length) { | 3962 int length) { |
3955 StringHasher hasher(length); | 3963 StringHasher hasher(length); |
3956 | 3964 |
3957 // Very long strings have a trivial hash that doesn't inspect the | 3965 // Very long strings have a trivial hash that doesn't inspect the |
3958 // string contents. | 3966 // string contents. |
3959 if (hasher.has_trivial_hash()) | 3967 if (hasher.has_trivial_hash()) { |
3960 return hasher.GetHashField(); | 3968 return hasher.GetHashField(); |
3969 } | |
3961 | 3970 |
3962 // Do the iterative array index computation as long as there is a | 3971 // Do the iterative array index computation as long as there is a |
3963 // chance this is an array index. | 3972 // chance this is an array index. |
3964 while (buffer->has_more() && hasher.is_array_index()) | 3973 while (buffer->has_more() && hasher.is_array_index()) { |
3965 hasher.AddCharacter(buffer->GetNext()); | 3974 hasher.AddCharacter(buffer->GetNext()); |
3975 } | |
3966 | 3976 |
3967 // Process the remaining characters without updating the array | 3977 // Process the remaining characters without updating the array |
3968 // index. | 3978 // index. |
3969 while (buffer->has_more()) | 3979 while (buffer->has_more()) { |
3970 hasher.AddCharacterNoIndex(buffer->GetNext()); | 3980 hasher.AddCharacterNoIndex(buffer->GetNext()); |
3981 } | |
3971 | 3982 |
3972 return hasher.GetHashField(); | 3983 return hasher.GetHashField(); |
3973 } | 3984 } |
3974 | 3985 |
3975 | 3986 |
3976 Object* String::Slice(int start, int end) { | 3987 Object* String::Slice(int start, int end) { |
3977 if (start == 0 && end == length()) return this; | 3988 if (start == 0 && end == length()) return this; |
3978 int representation = representation_tag(); | 3989 int representation = representation_tag(); |
3979 if (representation == kSlicedStringTag) { | 3990 if (representation == kSlicedStringTag) { |
3980 // Translate slices of a SlicedString into slices of the | 3991 // Translate slices of a SlicedString into slices of the |
(...skipping 2570 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
6551 // No break point. | 6562 // No break point. |
6552 if (break_point_objects()->IsUndefined()) return 0; | 6563 if (break_point_objects()->IsUndefined()) return 0; |
6553 // Single beak point. | 6564 // Single beak point. |
6554 if (!break_point_objects()->IsFixedArray()) return 1; | 6565 if (!break_point_objects()->IsFixedArray()) return 1; |
6555 // Multiple break points. | 6566 // Multiple break points. |
6556 return FixedArray::cast(break_point_objects())->length(); | 6567 return FixedArray::cast(break_point_objects())->length(); |
6557 } | 6568 } |
6558 | 6569 |
6559 | 6570 |
6560 } } // namespace v8::internal | 6571 } } // namespace v8::internal |
OLD | NEW |