| 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 934 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 945 uint32_t code; | 945 uint32_t code; |
| 946 if (Array::IndexFromObject(args[0], &code)) { | 946 if (Array::IndexFromObject(args[0], &code)) { |
| 947 if (code <= 0xffff) { | 947 if (code <= 0xffff) { |
| 948 return Heap::LookupSingleCharacterStringFromCode(code); | 948 return Heap::LookupSingleCharacterStringFromCode(code); |
| 949 } | 949 } |
| 950 } | 950 } |
| 951 return Heap::empty_string(); | 951 return Heap::empty_string(); |
| 952 } | 952 } |
| 953 | 953 |
| 954 | 954 |
| 955 static Vector<const char> ToAsciiVector(String *string) { | |
| 956 ASSERT(string->IsAscii()); | |
| 957 ASSERT(string->IsFlat()); | |
| 958 | |
| 959 int offset = 0; | |
| 960 int length = string->length(); | |
| 961 StringRepresentationTag string_tag = string->representation_tag(); | |
| 962 if (string_tag == kSlicedStringTag) { | |
| 963 SlicedString* sliced = SlicedString::cast(string); | |
| 964 offset += sliced->start(); | |
| 965 string = String::cast(sliced->buffer()); | |
| 966 string_tag = string->representation_tag(); | |
| 967 } else if (string_tag == kConsStringTag) { | |
| 968 ConsString* cons = ConsString::cast(string); | |
| 969 ASSERT(String::cast(cons->second())->length() == 0); | |
| 970 string = String::cast(cons->first()); | |
| 971 string_tag = string->representation_tag(); | |
| 972 } | |
| 973 if (string_tag == kSeqStringTag) { | |
| 974 AsciiString* seq = AsciiString::cast(string); | |
| 975 char* start = reinterpret_cast<char*>(seq->GetCharsAddress()); | |
| 976 return Vector<const char>(start + offset, length); | |
| 977 } | |
| 978 ASSERT(string_tag == kExternalStringTag); | |
| 979 ExternalAsciiString* ext = ExternalAsciiString::cast(string); | |
| 980 const char* start = ext->resource()->data(); | |
| 981 return Vector<const char>(start + offset, length); | |
| 982 } | |
| 983 | |
| 984 | |
| 985 static Vector<const uc16> ToUC16Vector(String *string) { | |
| 986 ASSERT(string->IsTwoByteString()); | |
| 987 ASSERT(string->IsFlat()); | |
| 988 | |
| 989 int offset = 0; | |
| 990 int length = string->length(); | |
| 991 | |
| 992 StringRepresentationTag string_tag = string->representation_tag(); | |
| 993 if (string_tag == kSlicedStringTag) { | |
| 994 SlicedString* sliced = SlicedString::cast(string); | |
| 995 offset += sliced->start(); | |
| 996 string = String::cast(sliced->buffer()); | |
| 997 string_tag = string->representation_tag(); | |
| 998 } else if (string_tag == kConsStringTag) { | |
| 999 ConsString* cons = ConsString::cast(string); | |
| 1000 ASSERT(String::cast(cons->second())->length() == 0); | |
| 1001 string = String::cast(cons->first()); | |
| 1002 string_tag = string->representation_tag(); | |
| 1003 } | |
| 1004 if (string_tag == kSeqStringTag) { | |
| 1005 TwoByteString* seq = TwoByteString::cast(string); | |
| 1006 uc16* start = reinterpret_cast<uc16*>(seq->GetCharsAddress()); | |
| 1007 return Vector<const uc16>(start + offset, length); | |
| 1008 } | |
| 1009 ASSERT(string_tag == kExternalStringTag); | |
| 1010 ExternalTwoByteString* ext = ExternalTwoByteString::cast(string); | |
| 1011 const uc16* start = | |
| 1012 reinterpret_cast<const uc16*>(ext->resource()->data()); | |
| 1013 return Vector<const uc16>(start + offset, length); | |
| 1014 } | |
| 1015 | |
| 1016 | |
| 1017 template <typename schar, typename pchar> | 955 template <typename schar, typename pchar> |
| 1018 static int SingleCharIndexOf(Vector<const schar> string, | 956 static int SingleCharIndexOf(Vector<const schar> string, |
| 1019 pchar pattern_char, | 957 pchar pattern_char, |
| 1020 int start_index) { | 958 int start_index) { |
| 1021 for (int i = start_index, n = string.length(); i < n; i++) { | 959 for (int i = start_index, n = string.length(); i < n; i++) { |
| 1022 if (pattern_char == string[i]) { | 960 if (pattern_char == string[i]) { |
| 1023 return i; | 961 return i; |
| 1024 } | 962 } |
| 1025 } | 963 } |
| 1026 return -1; | 964 return -1; |
| (...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1195 if (pattern_length == 0) return start_index; | 1133 if (pattern_length == 0) return start_index; |
| 1196 | 1134 |
| 1197 int subject_length = sub->length(); | 1135 int subject_length = sub->length(); |
| 1198 if (start_index + pattern_length > subject_length) return -1; | 1136 if (start_index + pattern_length > subject_length) return -1; |
| 1199 | 1137 |
| 1200 FlattenString(sub); | 1138 FlattenString(sub); |
| 1201 FlattenString(pat); | 1139 FlattenString(pat); |
| 1202 | 1140 |
| 1203 AssertNoAllocation no_heap_allocation; // ensure vectors stay valid | 1141 AssertNoAllocation no_heap_allocation; // ensure vectors stay valid |
| 1204 // dispatch on type of strings | 1142 // dispatch on type of strings |
| 1205 if (pat->is_ascii()) { | 1143 if (pat->is_ascii_representation()) { |
| 1206 Vector<const char> pat_vector = ToAsciiVector(*pat); | 1144 Vector<const char> pat_vector = pat->ToAsciiVector(); |
| 1207 if (sub->is_ascii()) { | 1145 if (sub->is_ascii_representation()) { |
| 1208 return StringMatchStrategy(ToAsciiVector(*sub), pat_vector, start_index); | 1146 return StringMatchStrategy(sub->ToAsciiVector(), pat_vector, start_index); |
| 1209 } | 1147 } |
| 1210 return StringMatchStrategy(ToUC16Vector(*sub), pat_vector, start_index); | 1148 return StringMatchStrategy(sub->ToUC16Vector(), pat_vector, start_index); |
| 1211 } | 1149 } |
| 1212 Vector<const uc16> pat_vector = ToUC16Vector(*pat); | 1150 Vector<const uc16> pat_vector = pat->ToUC16Vector(); |
| 1213 if (sub->is_ascii()) { | 1151 if (sub->is_ascii_representation()) { |
| 1214 return StringMatchStrategy(ToAsciiVector(*sub), pat_vector, start_index); | 1152 return StringMatchStrategy(sub->ToAsciiVector(), pat_vector, start_index); |
| 1215 } | 1153 } |
| 1216 return StringMatchStrategy(ToUC16Vector(*sub), pat_vector, start_index); | 1154 return StringMatchStrategy(sub->ToUC16Vector(), pat_vector, start_index); |
| 1217 } | 1155 } |
| 1218 | 1156 |
| 1219 | 1157 |
| 1220 static Object* Runtime_StringIndexOf(Arguments args) { | 1158 static Object* Runtime_StringIndexOf(Arguments args) { |
| 1221 HandleScope scope; // create a new handle scope | 1159 HandleScope scope; // create a new handle scope |
| 1222 ASSERT(args.length() == 3); | 1160 ASSERT(args.length() == 3); |
| 1223 | 1161 |
| 1224 CONVERT_ARG_CHECKED(String, sub, 0); | 1162 CONVERT_ARG_CHECKED(String, sub, 0); |
| 1225 CONVERT_ARG_CHECKED(String, pat, 1); | 1163 CONVERT_ARG_CHECKED(String, pat, 1); |
| 1226 | 1164 |
| (...skipping 921 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2148 // I apologize sincerely for this and will give a vaffel-is to | 2086 // I apologize sincerely for this and will give a vaffel-is to |
| 2149 // the first person who can implement it in a nicer way. | 2087 // the first person who can implement it in a nicer way. |
| 2150 try_convert: | 2088 try_convert: |
| 2151 | 2089 |
| 2152 // Allocate the resulting string. | 2090 // Allocate the resulting string. |
| 2153 // | 2091 // |
| 2154 // NOTE: This assumes that the upper/lower case of an ascii | 2092 // NOTE: This assumes that the upper/lower case of an ascii |
| 2155 // character is also ascii. This is currently the case, but it | 2093 // character is also ascii. This is currently the case, but it |
| 2156 // might break in the future if we implement more context and locale | 2094 // might break in the future if we implement more context and locale |
| 2157 // dependent upper/lower conversions. | 2095 // dependent upper/lower conversions. |
| 2158 Object* o = s->IsAscii() | 2096 Object* o = s->IsAsciiRepresentation() |
| 2159 ? Heap::AllocateRawAsciiString(length) | 2097 ? Heap::AllocateRawAsciiString(length) |
| 2160 : Heap::AllocateRawTwoByteString(length); | 2098 : Heap::AllocateRawTwoByteString(length); |
| 2161 if (o->IsFailure()) return o; | 2099 if (o->IsFailure()) return o; |
| 2162 String* result = String::cast(o); | 2100 String* result = String::cast(o); |
| 2163 bool has_changed_character = false; | 2101 bool has_changed_character = false; |
| 2164 | 2102 |
| 2165 // Convert all characters to upper case, assuming that they will fit | 2103 // Convert all characters to upper case, assuming that they will fit |
| 2166 // in the buffer | 2104 // in the buffer |
| 2167 Access<StringInputBuffer> buffer(&string_input_buffer); | 2105 Access<StringInputBuffer> buffer(&string_input_buffer); |
| 2168 buffer->Reset(s); | 2106 buffer->Reset(s); |
| (...skipping 256 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2425 array_length = fixed_array->length(); | 2363 array_length = fixed_array->length(); |
| 2426 } | 2364 } |
| 2427 | 2365 |
| 2428 if (array_length == 0) { | 2366 if (array_length == 0) { |
| 2429 return Heap::empty_string(); | 2367 return Heap::empty_string(); |
| 2430 } else if (array_length == 1) { | 2368 } else if (array_length == 1) { |
| 2431 Object* first = fixed_array->get(0); | 2369 Object* first = fixed_array->get(0); |
| 2432 if (first->IsString()) return first; | 2370 if (first->IsString()) return first; |
| 2433 } | 2371 } |
| 2434 | 2372 |
| 2435 bool ascii = special->IsAscii(); | 2373 bool ascii = special->IsAsciiRepresentation(); |
| 2436 int position = 0; | 2374 int position = 0; |
| 2437 for (int i = 0; i < array_length; i++) { | 2375 for (int i = 0; i < array_length; i++) { |
| 2438 Object* elt = fixed_array->get(i); | 2376 Object* elt = fixed_array->get(i); |
| 2439 if (elt->IsSmi()) { | 2377 if (elt->IsSmi()) { |
| 2440 int len = Smi::cast(elt)->value(); | 2378 int len = Smi::cast(elt)->value(); |
| 2441 int pos = len >> 11; | 2379 int pos = len >> 11; |
| 2442 len &= 0x7ff; | 2380 len &= 0x7ff; |
| 2443 if (pos + len > special_length) { | 2381 if (pos + len > special_length) { |
| 2444 return Top::Throw(Heap::illegal_argument_symbol()); | 2382 return Top::Throw(Heap::illegal_argument_symbol()); |
| 2445 } | 2383 } |
| 2446 position += len; | 2384 position += len; |
| 2447 } else if (elt->IsString()) { | 2385 } else if (elt->IsString()) { |
| 2448 String* element = String::cast(elt); | 2386 String* element = String::cast(elt); |
| 2449 int element_length = element->length(); | 2387 int element_length = element->length(); |
| 2450 if (!Smi::IsValid(element_length + position)) { | 2388 if (!Smi::IsValid(element_length + position)) { |
| 2451 Top::context()->mark_out_of_memory(); | 2389 Top::context()->mark_out_of_memory(); |
| 2452 return Failure::OutOfMemoryException(); | 2390 return Failure::OutOfMemoryException(); |
| 2453 } | 2391 } |
| 2454 position += element_length; | 2392 position += element_length; |
| 2455 if (ascii && !element->IsAscii()) { | 2393 if (ascii && !element->IsAsciiRepresentation()) { |
| 2456 ascii = false; | 2394 ascii = false; |
| 2457 } | 2395 } |
| 2458 } else { | 2396 } else { |
| 2459 return Top::Throw(Heap::illegal_argument_symbol()); | 2397 return Top::Throw(Heap::illegal_argument_symbol()); |
| 2460 } | 2398 } |
| 2461 } | 2399 } |
| 2462 | 2400 |
| 2463 int length = position; | 2401 int length = position; |
| 2464 position = 0; | 2402 position = 0; |
| 2465 Object* object; | 2403 Object* object; |
| (...skipping 2795 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5261 | 5199 |
| 5262 void Runtime::PerformGC(Object* result) { | 5200 void Runtime::PerformGC(Object* result) { |
| 5263 Failure* failure = Failure::cast(result); | 5201 Failure* failure = Failure::cast(result); |
| 5264 // Try to do a garbage collection; ignore it if it fails. The C | 5202 // Try to do a garbage collection; ignore it if it fails. The C |
| 5265 // entry stub will throw an out-of-memory exception in that case. | 5203 // entry stub will throw an out-of-memory exception in that case. |
| 5266 Heap::CollectGarbage(failure->requested(), failure->allocation_space()); | 5204 Heap::CollectGarbage(failure->requested(), failure->allocation_space()); |
| 5267 } | 5205 } |
| 5268 | 5206 |
| 5269 | 5207 |
| 5270 } } // namespace v8::internal | 5208 } } // namespace v8::internal |
| OLD | NEW |