| OLD | NEW |
| 1 // Copyright 2006-2009 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2009 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 3283 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3294 ASSERT(cons->second()->length() == 0); | 3294 ASSERT(cons->second()->length() == 0); |
| 3295 string = cons->first(); | 3295 string = cons->first(); |
| 3296 string_tag = StringShape(string).representation_tag(); | 3296 string_tag = StringShape(string).representation_tag(); |
| 3297 } | 3297 } |
| 3298 if (string_tag == kSeqStringTag) { | 3298 if (string_tag == kSeqStringTag) { |
| 3299 SeqTwoByteString* seq = SeqTwoByteString::cast(string); | 3299 SeqTwoByteString* seq = SeqTwoByteString::cast(string); |
| 3300 return Vector<const uc16>(seq->GetChars() + offset, length); | 3300 return Vector<const uc16>(seq->GetChars() + offset, length); |
| 3301 } | 3301 } |
| 3302 ASSERT(string_tag == kExternalStringTag); | 3302 ASSERT(string_tag == kExternalStringTag); |
| 3303 ExternalTwoByteString* ext = ExternalTwoByteString::cast(string); | 3303 ExternalTwoByteString* ext = ExternalTwoByteString::cast(string); |
| 3304 // This is a workaround for Chromium bug 9746: http://crbug.com/9746 |
| 3305 // For external strings with a deleted resource we return a special |
| 3306 // Vector which will not compare to any string when doing SymbolTable |
| 3307 // lookups. |
| 3308 if (ext->resource() == NULL) { |
| 3309 return Vector<const uc16>(NULL, length); |
| 3310 } |
| 3304 const uc16* start = | 3311 const uc16* start = |
| 3305 reinterpret_cast<const uc16*>(ext->resource()->data()); | 3312 reinterpret_cast<const uc16*>(ext->resource()->data()); |
| 3306 return Vector<const uc16>(start + offset, length); | 3313 return Vector<const uc16>(start + offset, length); |
| 3307 } | 3314 } |
| 3308 | 3315 |
| 3309 | 3316 |
| 3310 SmartPointer<char> String::ToCString(AllowNullsFlag allow_nulls, | 3317 SmartPointer<char> String::ToCString(AllowNullsFlag allow_nulls, |
| 3311 RobustnessFlag robust_flag, | 3318 RobustnessFlag robust_flag, |
| 3312 int offset, | 3319 int offset, |
| 3313 int length, | 3320 int length, |
| (...skipping 796 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4110 // Compare the remaining characters that didn't fit into a block. | 4117 // Compare the remaining characters that didn't fit into a block. |
| 4111 for (; i < length; i++) { | 4118 for (; i < length; i++) { |
| 4112 if (a[i] != b[i]) { | 4119 if (a[i] != b[i]) { |
| 4113 return false; | 4120 return false; |
| 4114 } | 4121 } |
| 4115 } | 4122 } |
| 4116 return true; | 4123 return true; |
| 4117 } | 4124 } |
| 4118 | 4125 |
| 4119 | 4126 |
| 4127 // This is a workaround for Chromium bug 9746: http://crbug.com/9746 |
| 4128 // Returns true if this Vector matches the problem exposed in the bug. |
| 4129 template <typename T> |
| 4130 static bool CheckVectorForBug9746(Vector<T> vec) { |
| 4131 // The problem is that somehow external string entries in the symbol |
| 4132 // table can have their resources collected while they are still in the |
| 4133 // table. This should not happen according to the test in the function |
| 4134 // DisposeExternalString in api.cc, but we have evidence that it does. |
| 4135 return (vec.start() == NULL) ? true : false; |
| 4136 } |
| 4137 |
| 4138 |
| 4120 static StringInputBuffer string_compare_buffer_b; | 4139 static StringInputBuffer string_compare_buffer_b; |
| 4121 | 4140 |
| 4122 | 4141 |
| 4123 template <typename IteratorA> | 4142 template <typename IteratorA> |
| 4124 static inline bool CompareStringContentsPartial(IteratorA* ia, String* b) { | 4143 static inline bool CompareStringContentsPartial(IteratorA* ia, String* b) { |
| 4125 if (b->IsFlat()) { | 4144 if (b->IsFlat()) { |
| 4126 if (StringShape(b).IsAsciiRepresentation()) { | 4145 if (StringShape(b).IsAsciiRepresentation()) { |
| 4127 VectorIterator<char> ib(b->ToAsciiVector()); | 4146 VectorIterator<char> ib(b->ToAsciiVector()); |
| 4128 return CompareStringContents(ia, &ib); | 4147 return CompareStringContents(ia, &ib); |
| 4129 } else { | 4148 } else { |
| 4130 VectorIterator<uc16> ib(b->ToUC16Vector()); | 4149 Vector<const uc16> vb = b->ToUC16Vector(); |
| 4150 if (CheckVectorForBug9746(vb)) return false; |
| 4151 VectorIterator<uc16> ib(vb); |
| 4131 return CompareStringContents(ia, &ib); | 4152 return CompareStringContents(ia, &ib); |
| 4132 } | 4153 } |
| 4133 } else { | 4154 } else { |
| 4134 string_compare_buffer_b.Reset(0, b); | 4155 string_compare_buffer_b.Reset(0, b); |
| 4135 return CompareStringContents(ia, &string_compare_buffer_b); | 4156 return CompareStringContents(ia, &string_compare_buffer_b); |
| 4136 } | 4157 } |
| 4137 } | 4158 } |
| 4138 | 4159 |
| 4139 | 4160 |
| 4140 static StringInputBuffer string_compare_buffer_a; | 4161 static StringInputBuffer string_compare_buffer_a; |
| (...skipping 21 matching lines...) Expand all Loading... |
| 4162 | 4183 |
| 4163 if (this->IsFlat()) { | 4184 if (this->IsFlat()) { |
| 4164 if (StringShape(this).IsAsciiRepresentation()) { | 4185 if (StringShape(this).IsAsciiRepresentation()) { |
| 4165 Vector<const char> vec1 = this->ToAsciiVector(); | 4186 Vector<const char> vec1 = this->ToAsciiVector(); |
| 4166 if (other->IsFlat()) { | 4187 if (other->IsFlat()) { |
| 4167 if (StringShape(other).IsAsciiRepresentation()) { | 4188 if (StringShape(other).IsAsciiRepresentation()) { |
| 4168 Vector<const char> vec2 = other->ToAsciiVector(); | 4189 Vector<const char> vec2 = other->ToAsciiVector(); |
| 4169 return CompareRawStringContents(vec1, vec2); | 4190 return CompareRawStringContents(vec1, vec2); |
| 4170 } else { | 4191 } else { |
| 4171 VectorIterator<char> buf1(vec1); | 4192 VectorIterator<char> buf1(vec1); |
| 4172 VectorIterator<uc16> ib(other->ToUC16Vector()); | 4193 Vector<const uc16> vec2 = other->ToUC16Vector(); |
| 4194 if (CheckVectorForBug9746(vec2)) return false; |
| 4195 VectorIterator<uc16> ib(vec2); |
| 4173 return CompareStringContents(&buf1, &ib); | 4196 return CompareStringContents(&buf1, &ib); |
| 4174 } | 4197 } |
| 4175 } else { | 4198 } else { |
| 4176 VectorIterator<char> buf1(vec1); | 4199 VectorIterator<char> buf1(vec1); |
| 4177 string_compare_buffer_b.Reset(0, other); | 4200 string_compare_buffer_b.Reset(0, other); |
| 4178 return CompareStringContents(&buf1, &string_compare_buffer_b); | 4201 return CompareStringContents(&buf1, &string_compare_buffer_b); |
| 4179 } | 4202 } |
| 4180 } else { | 4203 } else { |
| 4181 Vector<const uc16> vec1 = this->ToUC16Vector(); | 4204 Vector<const uc16> vec1 = this->ToUC16Vector(); |
| 4205 if (CheckVectorForBug9746(vec1)) return false; |
| 4182 if (other->IsFlat()) { | 4206 if (other->IsFlat()) { |
| 4183 if (StringShape(other).IsAsciiRepresentation()) { | 4207 if (StringShape(other).IsAsciiRepresentation()) { |
| 4184 VectorIterator<uc16> buf1(vec1); | 4208 VectorIterator<uc16> buf1(vec1); |
| 4185 VectorIterator<char> ib(other->ToAsciiVector()); | 4209 VectorIterator<char> ib(other->ToAsciiVector()); |
| 4186 return CompareStringContents(&buf1, &ib); | 4210 return CompareStringContents(&buf1, &ib); |
| 4187 } else { | 4211 } else { |
| 4188 Vector<const uc16> vec2(other->ToUC16Vector()); | 4212 Vector<const uc16> vec2 = other->ToUC16Vector(); |
| 4213 if (CheckVectorForBug9746(vec2)) return false; |
| 4189 return CompareRawStringContents(vec1, vec2); | 4214 return CompareRawStringContents(vec1, vec2); |
| 4190 } | 4215 } |
| 4191 } else { | 4216 } else { |
| 4192 VectorIterator<uc16> buf1(vec1); | 4217 VectorIterator<uc16> buf1(vec1); |
| 4193 string_compare_buffer_b.Reset(0, other); | 4218 string_compare_buffer_b.Reset(0, other); |
| 4194 return CompareStringContents(&buf1, &string_compare_buffer_b); | 4219 return CompareStringContents(&buf1, &string_compare_buffer_b); |
| 4195 } | 4220 } |
| 4196 } | 4221 } |
| 4197 } else { | 4222 } else { |
| 4198 string_compare_buffer_a.Reset(0, this); | 4223 string_compare_buffer_a.Reset(0, this); |
| (...skipping 24 matching lines...) Expand all Loading... |
| 4223 } else if (map == Heap::long_ascii_string_map()) { | 4248 } else if (map == Heap::long_ascii_string_map()) { |
| 4224 this->set_map(Heap::undetectable_long_ascii_string_map()); | 4249 this->set_map(Heap::undetectable_long_ascii_string_map()); |
| 4225 return true; | 4250 return true; |
| 4226 } | 4251 } |
| 4227 // Rest cannot be marked as undetectable | 4252 // Rest cannot be marked as undetectable |
| 4228 return false; | 4253 return false; |
| 4229 } | 4254 } |
| 4230 | 4255 |
| 4231 | 4256 |
| 4232 bool String::IsEqualTo(Vector<const char> str) { | 4257 bool String::IsEqualTo(Vector<const char> str) { |
| 4258 // This is a workaround for Chromium bug 9746: http://crbug.com/9746 |
| 4259 // The problem is that somehow external string entries in the symbol |
| 4260 // table can have their resources deleted while they are still in the |
| 4261 // table. This should not happen according to the test in the function |
| 4262 // DisposeExternalString in api.cc but we have evidence that it does. |
| 4263 // Thus we add this bailout here. |
| 4264 StringShape shape(this); |
| 4265 if (shape.IsExternalTwoByte()) { |
| 4266 ExternalTwoByteString* ext = ExternalTwoByteString::cast(this); |
| 4267 if (ext->resource() == NULL) return false; |
| 4268 } |
| 4269 |
| 4233 int slen = length(); | 4270 int slen = length(); |
| 4234 Access<Scanner::Utf8Decoder> decoder(Scanner::utf8_decoder()); | 4271 Access<Scanner::Utf8Decoder> decoder(Scanner::utf8_decoder()); |
| 4235 decoder->Reset(str.start(), str.length()); | 4272 decoder->Reset(str.start(), str.length()); |
| 4236 int i; | 4273 int i; |
| 4237 for (i = 0; i < slen && decoder->has_more(); i++) { | 4274 for (i = 0; i < slen && decoder->has_more(); i++) { |
| 4238 uc32 r = decoder->GetNext(); | 4275 uc32 r = decoder->GetNext(); |
| 4239 if (Get(i) != r) return false; | 4276 if (Get(i) != r) return false; |
| 4240 } | 4277 } |
| 4241 return i == slen && !decoder->has_more(); | 4278 return i == slen && !decoder->has_more(); |
| 4242 } | 4279 } |
| (...skipping 3137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7380 // No break point. | 7417 // No break point. |
| 7381 if (break_point_objects()->IsUndefined()) return 0; | 7418 if (break_point_objects()->IsUndefined()) return 0; |
| 7382 // Single beak point. | 7419 // Single beak point. |
| 7383 if (!break_point_objects()->IsFixedArray()) return 1; | 7420 if (!break_point_objects()->IsFixedArray()) return 1; |
| 7384 // Multiple break points. | 7421 // Multiple break points. |
| 7385 return FixedArray::cast(break_point_objects())->length(); | 7422 return FixedArray::cast(break_point_objects())->length(); |
| 7386 } | 7423 } |
| 7387 | 7424 |
| 7388 | 7425 |
| 7389 } } // namespace v8::internal | 7426 } } // namespace v8::internal |
| OLD | NEW |