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 |