| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 3321 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3332 // CompiledReplacement uses zone allocation. | 3332 // CompiledReplacement uses zone allocation. |
| 3333 Zone* zone = isolate->runtime_zone(); | 3333 Zone* zone = isolate->runtime_zone(); |
| 3334 ZoneScope zonescope(zone, DELETE_ON_EXIT); | 3334 ZoneScope zonescope(zone, DELETE_ON_EXIT); |
| 3335 CompiledReplacement compiled_replacement(zone); | 3335 CompiledReplacement compiled_replacement(zone); |
| 3336 bool simple_replace = compiled_replacement.Compile(replacement, | 3336 bool simple_replace = compiled_replacement.Compile(replacement, |
| 3337 capture_count, | 3337 capture_count, |
| 3338 subject_length); | 3338 subject_length); |
| 3339 | 3339 |
| 3340 // Shortcut for simple non-regexp global replacements | 3340 // Shortcut for simple non-regexp global replacements |
| 3341 if (regexp->TypeTag() == JSRegExp::ATOM && simple_replace) { | 3341 if (regexp->TypeTag() == JSRegExp::ATOM && simple_replace) { |
| 3342 if (subject->IsOneByteConvertible() && | 3342 if (subject->HasOnlyOneByteChars() && |
| 3343 replacement->IsOneByteConvertible()) { | 3343 replacement->HasOnlyOneByteChars()) { |
| 3344 return StringReplaceGlobalAtomRegExpWithString<SeqOneByteString>( | 3344 return StringReplaceGlobalAtomRegExpWithString<SeqOneByteString>( |
| 3345 isolate, subject, regexp, replacement, last_match_info); | 3345 isolate, subject, regexp, replacement, last_match_info); |
| 3346 } else { | 3346 } else { |
| 3347 return StringReplaceGlobalAtomRegExpWithString<SeqTwoByteString>( | 3347 return StringReplaceGlobalAtomRegExpWithString<SeqTwoByteString>( |
| 3348 isolate, subject, regexp, replacement, last_match_info); | 3348 isolate, subject, regexp, replacement, last_match_info); |
| 3349 } | 3349 } |
| 3350 } | 3350 } |
| 3351 | 3351 |
| 3352 RegExpImpl::GlobalCache global_cache(regexp, subject, true, isolate); | 3352 RegExpImpl::GlobalCache global_cache(regexp, subject, true, isolate); |
| 3353 if (global_cache.HasException()) return Failure::Exception(); | 3353 if (global_cache.HasException()) return Failure::Exception(); |
| (...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3515 CONVERT_ARG_HANDLE_CHECKED(String, subject, 0); | 3515 CONVERT_ARG_HANDLE_CHECKED(String, subject, 0); |
| 3516 CONVERT_ARG_HANDLE_CHECKED(String, replacement, 2); | 3516 CONVERT_ARG_HANDLE_CHECKED(String, replacement, 2); |
| 3517 CONVERT_ARG_HANDLE_CHECKED(JSRegExp, regexp, 1); | 3517 CONVERT_ARG_HANDLE_CHECKED(JSRegExp, regexp, 1); |
| 3518 CONVERT_ARG_HANDLE_CHECKED(JSArray, last_match_info, 3); | 3518 CONVERT_ARG_HANDLE_CHECKED(JSArray, last_match_info, 3); |
| 3519 | 3519 |
| 3520 ASSERT(regexp->GetFlags().is_global()); | 3520 ASSERT(regexp->GetFlags().is_global()); |
| 3521 | 3521 |
| 3522 if (!subject->IsFlat()) subject = FlattenGetString(subject); | 3522 if (!subject->IsFlat()) subject = FlattenGetString(subject); |
| 3523 | 3523 |
| 3524 if (replacement->length() == 0) { | 3524 if (replacement->length() == 0) { |
| 3525 if (subject->IsOneByteConvertible()) { | 3525 if (subject->HasOnlyOneByteChars()) { |
| 3526 return StringReplaceGlobalRegExpWithEmptyString<SeqOneByteString>( | 3526 return StringReplaceGlobalRegExpWithEmptyString<SeqOneByteString>( |
| 3527 isolate, subject, regexp, last_match_info); | 3527 isolate, subject, regexp, last_match_info); |
| 3528 } else { | 3528 } else { |
| 3529 return StringReplaceGlobalRegExpWithEmptyString<SeqTwoByteString>( | 3529 return StringReplaceGlobalRegExpWithEmptyString<SeqTwoByteString>( |
| 3530 isolate, subject, regexp, last_match_info); | 3530 isolate, subject, regexp, last_match_info); |
| 3531 } | 3531 } |
| 3532 } | 3532 } |
| 3533 | 3533 |
| 3534 if (!replacement->IsFlat()) replacement = FlattenGetString(replacement); | 3534 if (!replacement->IsFlat()) replacement = FlattenGetString(replacement); |
| 3535 | 3535 |
| (...skipping 2838 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6374 array_length = fixed_array->length(); | 6374 array_length = fixed_array->length(); |
| 6375 } | 6375 } |
| 6376 | 6376 |
| 6377 if (array_length == 0) { | 6377 if (array_length == 0) { |
| 6378 return isolate->heap()->empty_string(); | 6378 return isolate->heap()->empty_string(); |
| 6379 } else if (array_length == 1) { | 6379 } else if (array_length == 1) { |
| 6380 Object* first = fixed_array->get(0); | 6380 Object* first = fixed_array->get(0); |
| 6381 if (first->IsString()) return first; | 6381 if (first->IsString()) return first; |
| 6382 } | 6382 } |
| 6383 | 6383 |
| 6384 bool one_byte = special->IsOneByteConvertible(); | 6384 bool one_byte = special->HasOnlyOneByteChars(); |
| 6385 int position = 0; | 6385 int position = 0; |
| 6386 for (int i = 0; i < array_length; i++) { | 6386 for (int i = 0; i < array_length; i++) { |
| 6387 int increment = 0; | 6387 int increment = 0; |
| 6388 Object* elt = fixed_array->get(i); | 6388 Object* elt = fixed_array->get(i); |
| 6389 if (elt->IsSmi()) { | 6389 if (elt->IsSmi()) { |
| 6390 // Smi encoding of position and length. | 6390 // Smi encoding of position and length. |
| 6391 int smi_value = Smi::cast(elt)->value(); | 6391 int smi_value = Smi::cast(elt)->value(); |
| 6392 int pos; | 6392 int pos; |
| 6393 int len; | 6393 int len; |
| 6394 if (smi_value > 0) { | 6394 if (smi_value > 0) { |
| (...skipping 20 matching lines...) Expand all Loading... |
| 6415 ASSERT(pos >= 0); | 6415 ASSERT(pos >= 0); |
| 6416 ASSERT(len >= 0); | 6416 ASSERT(len >= 0); |
| 6417 if (pos > special_length || len > special_length - pos) { | 6417 if (pos > special_length || len > special_length - pos) { |
| 6418 return isolate->Throw(isolate->heap()->illegal_argument_string()); | 6418 return isolate->Throw(isolate->heap()->illegal_argument_string()); |
| 6419 } | 6419 } |
| 6420 increment = len; | 6420 increment = len; |
| 6421 } else if (elt->IsString()) { | 6421 } else if (elt->IsString()) { |
| 6422 String* element = String::cast(elt); | 6422 String* element = String::cast(elt); |
| 6423 int element_length = element->length(); | 6423 int element_length = element->length(); |
| 6424 increment = element_length; | 6424 increment = element_length; |
| 6425 if (one_byte && !element->IsOneByteConvertible()) { | 6425 if (one_byte && !element->HasOnlyOneByteChars()) { |
| 6426 one_byte = false; | 6426 one_byte = false; |
| 6427 } | 6427 } |
| 6428 } else { | 6428 } else { |
| 6429 ASSERT(!elt->IsTheHole()); | 6429 ASSERT(!elt->IsTheHole()); |
| 6430 return isolate->Throw(isolate->heap()->illegal_argument_string()); | 6430 return isolate->Throw(isolate->heap()->illegal_argument_string()); |
| 6431 } | 6431 } |
| 6432 if (increment > String::kMaxLength - position) { | 6432 if (increment > String::kMaxLength - position) { |
| 6433 isolate->context()->mark_out_of_memory(); | 6433 isolate->context()->mark_out_of_memory(); |
| 6434 return Failure::OutOfMemoryException(0x15); | 6434 return Failure::OutOfMemoryException(0x15); |
| 6435 } | 6435 } |
| (...skipping 6942 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 13378 // Handle last resort GC and make sure to allow future allocations | 13378 // Handle last resort GC and make sure to allow future allocations |
| 13379 // to grow the heap without causing GCs (if possible). | 13379 // to grow the heap without causing GCs (if possible). |
| 13380 isolate->counters()->gc_last_resort_from_js()->Increment(); | 13380 isolate->counters()->gc_last_resort_from_js()->Increment(); |
| 13381 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags, | 13381 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags, |
| 13382 "Runtime::PerformGC"); | 13382 "Runtime::PerformGC"); |
| 13383 } | 13383 } |
| 13384 } | 13384 } |
| 13385 | 13385 |
| 13386 | 13386 |
| 13387 } } // namespace v8::internal | 13387 } } // namespace v8::internal |
| OLD | NEW |