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