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 |