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 2258 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2269 schar pattern_char, | 2269 schar pattern_char, |
2270 int start_index) { | 2270 int start_index) { |
2271 for (int i = start_index, n = string.length(); i < n; i++) { | 2271 for (int i = start_index, n = string.length(); i < n; i++) { |
2272 if (pattern_char == string[i]) { | 2272 if (pattern_char == string[i]) { |
2273 return i; | 2273 return i; |
2274 } | 2274 } |
2275 } | 2275 } |
2276 return -1; | 2276 return -1; |
2277 } | 2277 } |
2278 | 2278 |
| 2279 |
| 2280 template <typename schar> |
| 2281 static int SingleCharLastIndexOf(Vector<const schar> string, |
| 2282 schar pattern_char, |
| 2283 int start_index) { |
| 2284 for (int i = start_index; i >= 0; i--) { |
| 2285 if (pattern_char == string[i]) { |
| 2286 return i; |
| 2287 } |
| 2288 } |
| 2289 return -1; |
| 2290 } |
| 2291 |
| 2292 |
2279 // Trivial string search for shorter strings. | 2293 // Trivial string search for shorter strings. |
2280 // On return, if "complete" is set to true, the return value is the | 2294 // On return, if "complete" is set to true, the return value is the |
2281 // final result of searching for the patter in the subject. | 2295 // final result of searching for the patter in the subject. |
2282 // If "complete" is set to false, the return value is the index where | 2296 // If "complete" is set to false, the return value is the index where |
2283 // further checking should start, i.e., it's guaranteed that the pattern | 2297 // further checking should start, i.e., it's guaranteed that the pattern |
2284 // does not occur at a position prior to the returned index. | 2298 // does not occur at a position prior to the returned index. |
2285 template <typename pchar, typename schar> | 2299 template <typename pchar, typename schar> |
2286 static int SimpleIndexOf(Vector<const schar> subject, | 2300 static int SimpleIndexOf(Vector<const schar> subject, |
2287 Vector<const pchar> pattern, | 2301 Vector<const pchar> pattern, |
2288 int idx, | 2302 int idx, |
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2452 RUNTIME_ASSERT(start_index <= static_cast<uint32_t>(sub->length())); | 2466 RUNTIME_ASSERT(start_index <= static_cast<uint32_t>(sub->length())); |
2453 int position = Runtime::StringMatch(sub, pat, start_index); | 2467 int position = Runtime::StringMatch(sub, pat, start_index); |
2454 return Smi::FromInt(position); | 2468 return Smi::FromInt(position); |
2455 } | 2469 } |
2456 | 2470 |
2457 | 2471 |
2458 static Object* Runtime_StringLastIndexOf(Arguments args) { | 2472 static Object* Runtime_StringLastIndexOf(Arguments args) { |
2459 NoHandleAllocation ha; | 2473 NoHandleAllocation ha; |
2460 ASSERT(args.length() == 3); | 2474 ASSERT(args.length() == 3); |
2461 | 2475 |
2462 CONVERT_CHECKED(String, sub, args[0]); | 2476 CONVERT_ARG_CHECKED(String, sub, 0); |
2463 CONVERT_CHECKED(String, pat, args[1]); | 2477 CONVERT_ARG_CHECKED(String, pat, 1); |
2464 Object* index = args[2]; | 2478 Object* index = args[2]; |
2465 | 2479 |
2466 sub->TryFlattenIfNotFlat(); | |
2467 pat->TryFlattenIfNotFlat(); | |
2468 | |
2469 uint32_t start_index; | 2480 uint32_t start_index; |
2470 if (!Array::IndexFromObject(index, &start_index)) return Smi::FromInt(-1); | 2481 if (!Array::IndexFromObject(index, &start_index)) return Smi::FromInt(-1); |
2471 | 2482 |
| 2483 if (!sub->IsFlat()) { |
| 2484 FlattenString(sub); |
| 2485 } |
| 2486 |
2472 uint32_t pattern_length = pat->length(); | 2487 uint32_t pattern_length = pat->length(); |
2473 uint32_t sub_length = sub->length(); | 2488 uint32_t sub_length = sub->length(); |
2474 | 2489 |
2475 if (start_index + pattern_length > sub_length) { | 2490 if (start_index + pattern_length > sub_length) { |
2476 start_index = sub_length - pattern_length; | 2491 start_index = sub_length - pattern_length; |
2477 } | 2492 } |
2478 | 2493 |
| 2494 if (pattern_length == 1) { |
| 2495 AssertNoAllocation no_heap_allocation; // ensure vectors stay valid |
| 2496 if (sub->IsAsciiRepresentation()) { |
| 2497 uc16 pchar = pat->Get(0); |
| 2498 if (pchar > String::kMaxAsciiCharCode) { |
| 2499 return Smi::FromInt(-1); |
| 2500 } |
| 2501 return Smi::FromInt(SingleCharLastIndexOf(sub->ToAsciiVector(), |
| 2502 static_cast<char>(pat->Get(0)), |
| 2503 start_index)); |
| 2504 } else { |
| 2505 return Smi::FromInt(SingleCharLastIndexOf(sub->ToUC16Vector(), |
| 2506 pat->Get(0), |
| 2507 start_index)); |
| 2508 } |
| 2509 } |
| 2510 |
| 2511 pat->TryFlattenIfNotFlat(); |
| 2512 |
2479 for (int i = start_index; i >= 0; i--) { | 2513 for (int i = start_index; i >= 0; i--) { |
2480 bool found = true; | 2514 bool found = true; |
2481 for (uint32_t j = 0; j < pattern_length; j++) { | 2515 for (uint32_t j = 0; j < pattern_length; j++) { |
2482 if (sub->Get(i + j) != pat->Get(j)) { | 2516 if (sub->Get(i + j) != pat->Get(j)) { |
2483 found = false; | 2517 found = false; |
2484 break; | 2518 break; |
2485 } | 2519 } |
2486 } | 2520 } |
2487 if (found) return Smi::FromInt(i); | 2521 if (found) return Smi::FromInt(i); |
2488 } | 2522 } |
(...skipping 5693 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8182 } else { | 8216 } else { |
8183 // Handle last resort GC and make sure to allow future allocations | 8217 // Handle last resort GC and make sure to allow future allocations |
8184 // to grow the heap without causing GCs (if possible). | 8218 // to grow the heap without causing GCs (if possible). |
8185 Counters::gc_last_resort_from_js.Increment(); | 8219 Counters::gc_last_resort_from_js.Increment(); |
8186 Heap::CollectAllGarbage(false); | 8220 Heap::CollectAllGarbage(false); |
8187 } | 8221 } |
8188 } | 8222 } |
8189 | 8223 |
8190 | 8224 |
8191 } } // namespace v8::internal | 8225 } } // namespace v8::internal |
OLD | NEW |