| OLD | NEW |
| 1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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 1151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1162 ObjectVisitor* v) { | 1162 ObjectVisitor* v) { |
| 1163 // Avoiding <Type>::cast(this) because it accesses the map pointer field. | 1163 // Avoiding <Type>::cast(this) because it accesses the map pointer field. |
| 1164 // During GC, the map pointer field is encoded. | 1164 // During GC, the map pointer field is encoded. |
| 1165 if (type < FIRST_NONSTRING_TYPE) { | 1165 if (type < FIRST_NONSTRING_TYPE) { |
| 1166 switch (type & kStringRepresentationMask) { | 1166 switch (type & kStringRepresentationMask) { |
| 1167 case kSeqStringTag: | 1167 case kSeqStringTag: |
| 1168 break; | 1168 break; |
| 1169 case kConsStringTag: | 1169 case kConsStringTag: |
| 1170 ConsString::BodyDescriptor::IterateBody(this, v); | 1170 ConsString::BodyDescriptor::IterateBody(this, v); |
| 1171 break; | 1171 break; |
| 1172 case kSlicedStringTag: |
| 1173 SlicedString::BodyDescriptor::IterateBody(this, v); |
| 1174 break; |
| 1172 case kExternalStringTag: | 1175 case kExternalStringTag: |
| 1173 if ((type & kStringEncodingMask) == kAsciiStringTag) { | 1176 if ((type & kStringEncodingMask) == kAsciiStringTag) { |
| 1174 reinterpret_cast<ExternalAsciiString*>(this)-> | 1177 reinterpret_cast<ExternalAsciiString*>(this)-> |
| 1175 ExternalAsciiStringIterateBody(v); | 1178 ExternalAsciiStringIterateBody(v); |
| 1176 } else { | 1179 } else { |
| 1177 reinterpret_cast<ExternalTwoByteString*>(this)-> | 1180 reinterpret_cast<ExternalTwoByteString*>(this)-> |
| 1178 ExternalTwoByteStringIterateBody(v); | 1181 ExternalTwoByteStringIterateBody(v); |
| 1179 } | 1182 } |
| 1180 break; | 1183 break; |
| 1181 } | 1184 } |
| (...skipping 4057 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5239 int offset = 0; | 5242 int offset = 0; |
| 5240 int length = this->length(); | 5243 int length = this->length(); |
| 5241 StringRepresentationTag string_tag = StringShape(this).representation_tag(); | 5244 StringRepresentationTag string_tag = StringShape(this).representation_tag(); |
| 5242 String* string = this; | 5245 String* string = this; |
| 5243 if (string_tag == kConsStringTag) { | 5246 if (string_tag == kConsStringTag) { |
| 5244 ConsString* cons = ConsString::cast(string); | 5247 ConsString* cons = ConsString::cast(string); |
| 5245 ASSERT(cons->second()->length() == 0); | 5248 ASSERT(cons->second()->length() == 0); |
| 5246 string = cons->first(); | 5249 string = cons->first(); |
| 5247 string_tag = StringShape(string).representation_tag(); | 5250 string_tag = StringShape(string).representation_tag(); |
| 5248 } | 5251 } |
| 5249 if (string_tag == kSeqStringTag) { | 5252 if (string_tag == kExternalStringTag) { |
| 5250 SeqAsciiString* seq = SeqAsciiString::cast(string); | 5253 // Note that a sliced string cannot contain an external string. |
| 5251 char* start = seq->GetChars(); | 5254 ExternalAsciiString* ext = ExternalAsciiString::cast(string); |
| 5255 const char* start = ext->resource()->data(); |
| 5252 return Vector<const char>(start + offset, length); | 5256 return Vector<const char>(start + offset, length); |
| 5253 } | 5257 } |
| 5254 ASSERT(string_tag == kExternalStringTag); | 5258 if (string_tag == kSlicedStringTag) { |
| 5255 ExternalAsciiString* ext = ExternalAsciiString::cast(string); | 5259 SlicedString* slice = SlicedString::cast(string); |
| 5256 const char* start = ext->resource()->data(); | 5260 offset = slice->offset(); |
| 5261 string = slice->parent(); |
| 5262 string_tag = StringShape(string).representation_tag(); |
| 5263 } |
| 5264 ASSERT(string_tag == kSeqStringTag); |
| 5265 SeqAsciiString* seq = SeqAsciiString::cast(string); |
| 5266 char* start = seq->GetChars(); |
| 5257 return Vector<const char>(start + offset, length); | 5267 return Vector<const char>(start + offset, length); |
| 5258 } | 5268 } |
| 5259 | 5269 |
| 5260 | 5270 |
| 5261 Vector<const uc16> String::ToUC16Vector() { | 5271 Vector<const uc16> String::ToUC16Vector() { |
| 5262 ASSERT(IsTwoByteRepresentation()); | 5272 ASSERT(IsTwoByteRepresentation()); |
| 5263 ASSERT(IsFlat()); | 5273 ASSERT(IsFlat()); |
| 5264 | 5274 |
| 5265 int offset = 0; | 5275 int offset = 0; |
| 5266 int length = this->length(); | 5276 int length = this->length(); |
| 5267 StringRepresentationTag string_tag = StringShape(this).representation_tag(); | 5277 StringRepresentationTag string_tag = StringShape(this).representation_tag(); |
| 5268 String* string = this; | 5278 String* string = this; |
| 5269 if (string_tag == kConsStringTag) { | 5279 if (string_tag == kConsStringTag) { |
| 5270 ConsString* cons = ConsString::cast(string); | 5280 ConsString* cons = ConsString::cast(string); |
| 5271 ASSERT(cons->second()->length() == 0); | 5281 ASSERT(cons->second()->length() == 0); |
| 5272 string = cons->first(); | 5282 string = cons->first(); |
| 5273 string_tag = StringShape(string).representation_tag(); | 5283 string_tag = StringShape(string).representation_tag(); |
| 5274 } | 5284 } |
| 5275 if (string_tag == kSeqStringTag) { | 5285 if (string_tag == kExternalStringTag) { |
| 5276 SeqTwoByteString* seq = SeqTwoByteString::cast(string); | 5286 // Note that a sliced string cannot contain an external string. |
| 5277 return Vector<const uc16>(seq->GetChars() + offset, length); | 5287 ExternalTwoByteString* ext = ExternalTwoByteString::cast(string); |
| 5288 const uc16* start = |
| 5289 reinterpret_cast<const uc16*>(ext->resource()->data()); |
| 5290 return Vector<const uc16>(start + offset, length); |
| 5278 } | 5291 } |
| 5279 ASSERT(string_tag == kExternalStringTag); | 5292 if (string_tag == kSlicedStringTag) { |
| 5280 ExternalTwoByteString* ext = ExternalTwoByteString::cast(string); | 5293 SlicedString* slice = SlicedString::cast(string); |
| 5281 const uc16* start = | 5294 offset = slice->offset(); |
| 5282 reinterpret_cast<const uc16*>(ext->resource()->data()); | 5295 string = slice->parent(); |
| 5283 return Vector<const uc16>(start + offset, length); | 5296 string_tag = StringShape(string).representation_tag(); |
| 5297 } |
| 5298 ASSERT(string_tag == kSeqStringTag); |
| 5299 SeqTwoByteString* seq = SeqTwoByteString::cast(string); |
| 5300 return Vector<const uc16>(seq->GetChars() + offset, length); |
| 5284 } | 5301 } |
| 5285 | 5302 |
| 5286 | 5303 |
| 5287 SmartPointer<char> String::ToCString(AllowNullsFlag allow_nulls, | 5304 SmartPointer<char> String::ToCString(AllowNullsFlag allow_nulls, |
| 5288 RobustnessFlag robust_flag, | 5305 RobustnessFlag robust_flag, |
| 5289 int offset, | 5306 int offset, |
| 5290 int length, | 5307 int length, |
| 5291 int* length_return) { | 5308 int* length_return) { |
| 5292 if (robust_flag == ROBUST_STRING_TRAVERSAL && !LooksValid()) { | 5309 if (robust_flag == ROBUST_STRING_TRAVERSAL && !LooksValid()) { |
| 5293 return SmartPointer<char>(NULL); | 5310 return SmartPointer<char>(NULL); |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5351 | 5368 |
| 5352 | 5369 |
| 5353 const uc16* String::GetTwoByteData(unsigned start) { | 5370 const uc16* String::GetTwoByteData(unsigned start) { |
| 5354 ASSERT(!IsAsciiRepresentation()); | 5371 ASSERT(!IsAsciiRepresentation()); |
| 5355 switch (StringShape(this).representation_tag()) { | 5372 switch (StringShape(this).representation_tag()) { |
| 5356 case kSeqStringTag: | 5373 case kSeqStringTag: |
| 5357 return SeqTwoByteString::cast(this)->SeqTwoByteStringGetData(start); | 5374 return SeqTwoByteString::cast(this)->SeqTwoByteStringGetData(start); |
| 5358 case kExternalStringTag: | 5375 case kExternalStringTag: |
| 5359 return ExternalTwoByteString::cast(this)-> | 5376 return ExternalTwoByteString::cast(this)-> |
| 5360 ExternalTwoByteStringGetData(start); | 5377 ExternalTwoByteStringGetData(start); |
| 5378 case kSlicedStringTag: { |
| 5379 SlicedString* slice = SlicedString::cast(this); |
| 5380 return slice->parent()->GetTwoByteData(start + slice->offset()); |
| 5381 } |
| 5361 case kConsStringTag: | 5382 case kConsStringTag: |
| 5362 UNREACHABLE(); | 5383 UNREACHABLE(); |
| 5363 return NULL; | 5384 return NULL; |
| 5364 } | 5385 } |
| 5365 UNREACHABLE(); | 5386 UNREACHABLE(); |
| 5366 return NULL; | 5387 return NULL; |
| 5367 } | 5388 } |
| 5368 | 5389 |
| 5369 | 5390 |
| 5370 SmartPointer<uc16> String::ToWideCString(RobustnessFlag robust_flag) { | 5391 SmartPointer<uc16> String::ToWideCString(RobustnessFlag robust_flag) { |
| (...skipping 257 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5628 SeqTwoByteString* str = SeqTwoByteString::cast(input); | 5649 SeqTwoByteString* str = SeqTwoByteString::cast(input); |
| 5629 str->SeqTwoByteStringReadBlockIntoBuffer(rbb, | 5650 str->SeqTwoByteStringReadBlockIntoBuffer(rbb, |
| 5630 offset_ptr, | 5651 offset_ptr, |
| 5631 max_chars); | 5652 max_chars); |
| 5632 return rbb->util_buffer; | 5653 return rbb->util_buffer; |
| 5633 } | 5654 } |
| 5634 case kConsStringTag: | 5655 case kConsStringTag: |
| 5635 return ConsString::cast(input)->ConsStringReadBlock(rbb, | 5656 return ConsString::cast(input)->ConsStringReadBlock(rbb, |
| 5636 offset_ptr, | 5657 offset_ptr, |
| 5637 max_chars); | 5658 max_chars); |
| 5659 case kSlicedStringTag: |
| 5660 return SlicedString::cast(input)->SlicedStringReadBlock(rbb, |
| 5661 offset_ptr, |
| 5662 max_chars); |
| 5638 case kExternalStringTag: | 5663 case kExternalStringTag: |
| 5639 if (input->IsAsciiRepresentation()) { | 5664 if (input->IsAsciiRepresentation()) { |
| 5640 return ExternalAsciiString::cast(input)->ExternalAsciiStringReadBlock( | 5665 return ExternalAsciiString::cast(input)->ExternalAsciiStringReadBlock( |
| 5641 &rbb->remaining, | 5666 &rbb->remaining, |
| 5642 offset_ptr, | 5667 offset_ptr, |
| 5643 max_chars); | 5668 max_chars); |
| 5644 } else { | 5669 } else { |
| 5645 ExternalTwoByteString::cast(input)-> | 5670 ExternalTwoByteString::cast(input)-> |
| 5646 ExternalTwoByteStringReadBlockIntoBuffer(rbb, | 5671 ExternalTwoByteStringReadBlockIntoBuffer(rbb, |
| 5647 offset_ptr, | 5672 offset_ptr, |
| (...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5771 SeqTwoByteString::cast(input)->SeqTwoByteStringReadBlockIntoBuffer(rbb, | 5796 SeqTwoByteString::cast(input)->SeqTwoByteStringReadBlockIntoBuffer(rbb, |
| 5772 offset_ptr, | 5797 offset_ptr, |
| 5773 max_chars); | 5798 max_chars); |
| 5774 return; | 5799 return; |
| 5775 } | 5800 } |
| 5776 case kConsStringTag: | 5801 case kConsStringTag: |
| 5777 ConsString::cast(input)->ConsStringReadBlockIntoBuffer(rbb, | 5802 ConsString::cast(input)->ConsStringReadBlockIntoBuffer(rbb, |
| 5778 offset_ptr, | 5803 offset_ptr, |
| 5779 max_chars); | 5804 max_chars); |
| 5780 return; | 5805 return; |
| 5806 case kSlicedStringTag: |
| 5807 SlicedString::cast(input)->SlicedStringReadBlockIntoBuffer(rbb, |
| 5808 offset_ptr, |
| 5809 max_chars); |
| 5810 return; |
| 5781 case kExternalStringTag: | 5811 case kExternalStringTag: |
| 5782 if (input->IsAsciiRepresentation()) { | 5812 if (input->IsAsciiRepresentation()) { |
| 5783 ExternalAsciiString::cast(input)-> | 5813 ExternalAsciiString::cast(input)-> |
| 5784 ExternalAsciiStringReadBlockIntoBuffer(rbb, offset_ptr, max_chars); | 5814 ExternalAsciiStringReadBlockIntoBuffer(rbb, offset_ptr, max_chars); |
| 5785 } else { | 5815 } else { |
| 5786 ExternalTwoByteString::cast(input)-> | 5816 ExternalTwoByteString::cast(input)-> |
| 5787 ExternalTwoByteStringReadBlockIntoBuffer(rbb, | 5817 ExternalTwoByteStringReadBlockIntoBuffer(rbb, |
| 5788 offset_ptr, | 5818 offset_ptr, |
| 5789 max_chars); | 5819 max_chars); |
| 5790 } | 5820 } |
| (...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5916 } else { | 5946 } else { |
| 5917 return string->Get(index); | 5947 return string->Get(index); |
| 5918 } | 5948 } |
| 5919 } | 5949 } |
| 5920 | 5950 |
| 5921 UNREACHABLE(); | 5951 UNREACHABLE(); |
| 5922 return 0; | 5952 return 0; |
| 5923 } | 5953 } |
| 5924 | 5954 |
| 5925 | 5955 |
| 5956 uint16_t SlicedString::SlicedStringGet(int index) { |
| 5957 return parent()->Get(offset() + index); |
| 5958 } |
| 5959 |
| 5960 |
| 5961 const unibrow::byte* SlicedString::SlicedStringReadBlock( |
| 5962 ReadBlockBuffer* buffer, unsigned* offset_ptr, unsigned chars) { |
| 5963 unsigned offset = this->offset(); |
| 5964 *offset_ptr += offset; |
| 5965 const unibrow::byte* answer = String::ReadBlock(String::cast(parent()), |
| 5966 buffer, offset_ptr, chars); |
| 5967 *offset_ptr -= offset; |
| 5968 return answer; |
| 5969 } |
| 5970 |
| 5971 |
| 5972 void SlicedString::SlicedStringReadBlockIntoBuffer( |
| 5973 ReadBlockBuffer* buffer, unsigned* offset_ptr, unsigned chars) { |
| 5974 unsigned offset = this->offset(); |
| 5975 *offset_ptr += offset; |
| 5976 String::ReadBlockIntoBuffer(String::cast(parent()), |
| 5977 buffer, offset_ptr, chars); |
| 5978 *offset_ptr -= offset; |
| 5979 } |
| 5980 |
| 5926 template <typename sinkchar> | 5981 template <typename sinkchar> |
| 5927 void String::WriteToFlat(String* src, | 5982 void String::WriteToFlat(String* src, |
| 5928 sinkchar* sink, | 5983 sinkchar* sink, |
| 5929 int f, | 5984 int f, |
| 5930 int t) { | 5985 int t) { |
| 5931 String* source = src; | 5986 String* source = src; |
| 5932 int from = f; | 5987 int from = f; |
| 5933 int to = t; | 5988 int to = t; |
| 5934 while (true) { | 5989 while (true) { |
| 5935 ASSERT(0 <= from && from <= to && to <= source->length()); | 5990 ASSERT(0 <= from && from <= to && to <= source->length()); |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5983 WriteToFlat(second, | 6038 WriteToFlat(second, |
| 5984 sink + boundary - from, | 6039 sink + boundary - from, |
| 5985 0, | 6040 0, |
| 5986 to - boundary); | 6041 to - boundary); |
| 5987 to = boundary; | 6042 to = boundary; |
| 5988 } | 6043 } |
| 5989 source = first; | 6044 source = first; |
| 5990 } | 6045 } |
| 5991 break; | 6046 break; |
| 5992 } | 6047 } |
| 6048 case kAsciiStringTag | kSlicedStringTag: |
| 6049 case kTwoByteStringTag | kSlicedStringTag: { |
| 6050 SlicedString* slice = SlicedString::cast(source); |
| 6051 unsigned offset = slice->offset(); |
| 6052 WriteToFlat(slice->parent(), sink, from + offset, to + offset); |
| 6053 return; |
| 6054 } |
| 5993 } | 6055 } |
| 5994 } | 6056 } |
| 5995 } | 6057 } |
| 5996 | 6058 |
| 5997 | 6059 |
| 5998 template <typename IteratorA, typename IteratorB> | 6060 template <typename IteratorA, typename IteratorB> |
| 5999 static inline bool CompareStringContents(IteratorA* ia, IteratorB* ib) { | 6061 static inline bool CompareStringContents(IteratorA* ia, IteratorB* ib) { |
| 6000 // General slow case check. We know that the ia and ib iterators | 6062 // General slow case check. We know that the ia and ib iterators |
| 6001 // have the same length. | 6063 // have the same length. |
| 6002 while (ia->has_more()) { | 6064 while (ia->has_more()) { |
| (...skipping 5935 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11938 if (break_point_objects()->IsUndefined()) return 0; | 12000 if (break_point_objects()->IsUndefined()) return 0; |
| 11939 // Single beak point. | 12001 // Single beak point. |
| 11940 if (!break_point_objects()->IsFixedArray()) return 1; | 12002 if (!break_point_objects()->IsFixedArray()) return 1; |
| 11941 // Multiple break points. | 12003 // Multiple break points. |
| 11942 return FixedArray::cast(break_point_objects())->length(); | 12004 return FixedArray::cast(break_point_objects())->length(); |
| 11943 } | 12005 } |
| 11944 #endif | 12006 #endif |
| 11945 | 12007 |
| 11946 | 12008 |
| 11947 } } // namespace v8::internal | 12009 } } // namespace v8::internal |
| OLD | NEW |