| 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 2497 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2508 } | 2508 } |
| 2509 | 2509 |
| 2510 | 2510 |
| 2511 Handle<String> ToString() { | 2511 Handle<String> ToString() { |
| 2512 if (array_builder_.length() == 0) { | 2512 if (array_builder_.length() == 0) { |
| 2513 return heap_->isolate()->factory()->empty_string(); | 2513 return heap_->isolate()->factory()->empty_string(); |
| 2514 } | 2514 } |
| 2515 | 2515 |
| 2516 Handle<String> joined_string; | 2516 Handle<String> joined_string; |
| 2517 if (is_ascii_) { | 2517 if (is_ascii_) { |
| 2518 Handle<SeqAsciiString> seq = NewRawAsciiString(character_count_); | 2518 Handle<SeqOneByteString> seq = NewRawOneByteString(character_count_); |
| 2519 AssertNoAllocation no_alloc; | 2519 AssertNoAllocation no_alloc; |
| 2520 char* char_buffer = seq->GetChars(); | 2520 char* char_buffer = seq->GetChars(); |
| 2521 StringBuilderConcatHelper(*subject_, | 2521 StringBuilderConcatHelper(*subject_, |
| 2522 char_buffer, | 2522 char_buffer, |
| 2523 *array_builder_.array(), | 2523 *array_builder_.array(), |
| 2524 array_builder_.length()); | 2524 array_builder_.length()); |
| 2525 joined_string = Handle<String>::cast(seq); | 2525 joined_string = Handle<String>::cast(seq); |
| 2526 } else { | 2526 } else { |
| 2527 // Non-ASCII. | 2527 // Non-ASCII. |
| 2528 Handle<SeqTwoByteString> seq = NewRawTwoByteString(character_count_); | 2528 Handle<SeqTwoByteString> seq = NewRawTwoByteString(character_count_); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 2539 | 2539 |
| 2540 | 2540 |
| 2541 void IncrementCharacterCount(int by) { | 2541 void IncrementCharacterCount(int by) { |
| 2542 if (character_count_ > String::kMaxLength - by) { | 2542 if (character_count_ > String::kMaxLength - by) { |
| 2543 V8::FatalProcessOutOfMemory("String.replace result too large."); | 2543 V8::FatalProcessOutOfMemory("String.replace result too large."); |
| 2544 } | 2544 } |
| 2545 character_count_ += by; | 2545 character_count_ += by; |
| 2546 } | 2546 } |
| 2547 | 2547 |
| 2548 private: | 2548 private: |
| 2549 Handle<SeqAsciiString> NewRawAsciiString(int length) { | 2549 Handle<SeqOneByteString> NewRawOneByteString(int length) { |
| 2550 return heap_->isolate()->factory()->NewRawAsciiString(length); | 2550 return heap_->isolate()->factory()->NewRawOneByteString(length); |
| 2551 } | 2551 } |
| 2552 | 2552 |
| 2553 | 2553 |
| 2554 Handle<SeqTwoByteString> NewRawTwoByteString(int length) { | 2554 Handle<SeqTwoByteString> NewRawTwoByteString(int length) { |
| 2555 return heap_->isolate()->factory()->NewRawTwoByteString(length); | 2555 return heap_->isolate()->factory()->NewRawTwoByteString(length); |
| 2556 } | 2556 } |
| 2557 | 2557 |
| 2558 | 2558 |
| 2559 void AddElement(Object* element) { | 2559 void AddElement(Object* element) { |
| 2560 ASSERT(element->IsSmi() || element->IsString()); | 2560 ASSERT(element->IsSmi() || element->IsString()); |
| (...skipping 428 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2989 static_cast<int64_t>(subject_len); | 2989 static_cast<int64_t>(subject_len); |
| 2990 if (result_len_64 > INT_MAX) return Failure::OutOfMemoryException(); | 2990 if (result_len_64 > INT_MAX) return Failure::OutOfMemoryException(); |
| 2991 int result_len = static_cast<int>(result_len_64); | 2991 int result_len = static_cast<int>(result_len_64); |
| 2992 | 2992 |
| 2993 int subject_pos = 0; | 2993 int subject_pos = 0; |
| 2994 int result_pos = 0; | 2994 int result_pos = 0; |
| 2995 | 2995 |
| 2996 Handle<ResultSeqString> result; | 2996 Handle<ResultSeqString> result; |
| 2997 if (ResultSeqString::kHasAsciiEncoding) { | 2997 if (ResultSeqString::kHasAsciiEncoding) { |
| 2998 result = Handle<ResultSeqString>::cast( | 2998 result = Handle<ResultSeqString>::cast( |
| 2999 isolate->factory()->NewRawAsciiString(result_len)); | 2999 isolate->factory()->NewRawOneByteString(result_len)); |
| 3000 } else { | 3000 } else { |
| 3001 result = Handle<ResultSeqString>::cast( | 3001 result = Handle<ResultSeqString>::cast( |
| 3002 isolate->factory()->NewRawTwoByteString(result_len)); | 3002 isolate->factory()->NewRawTwoByteString(result_len)); |
| 3003 } | 3003 } |
| 3004 | 3004 |
| 3005 for (int i = 0; i < matches; i++) { | 3005 for (int i = 0; i < matches; i++) { |
| 3006 // Copy non-matched subject content. | 3006 // Copy non-matched subject content. |
| 3007 if (subject_pos < indices.at(i)) { | 3007 if (subject_pos < indices.at(i)) { |
| 3008 String::WriteToFlat(*subject, | 3008 String::WriteToFlat(*subject, |
| 3009 result->GetChars() + result_pos, | 3009 result->GetChars() + result_pos, |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3058 CompiledReplacement compiled_replacement(zone); | 3058 CompiledReplacement compiled_replacement(zone); |
| 3059 bool simple_replace = compiled_replacement.Compile(replacement, | 3059 bool simple_replace = compiled_replacement.Compile(replacement, |
| 3060 capture_count, | 3060 capture_count, |
| 3061 subject_length); | 3061 subject_length); |
| 3062 | 3062 |
| 3063 // Shortcut for simple non-regexp global replacements | 3063 // Shortcut for simple non-regexp global replacements |
| 3064 if (is_global && | 3064 if (is_global && |
| 3065 regexp->TypeTag() == JSRegExp::ATOM && | 3065 regexp->TypeTag() == JSRegExp::ATOM && |
| 3066 simple_replace) { | 3066 simple_replace) { |
| 3067 if (subject->HasOnlyAsciiChars() && replacement->HasOnlyAsciiChars()) { | 3067 if (subject->HasOnlyAsciiChars() && replacement->HasOnlyAsciiChars()) { |
| 3068 return StringReplaceAtomRegExpWithString<SeqAsciiString>( | 3068 return StringReplaceAtomRegExpWithString<SeqOneByteString>( |
| 3069 isolate, subject, regexp, replacement, last_match_info); | 3069 isolate, subject, regexp, replacement, last_match_info); |
| 3070 } else { | 3070 } else { |
| 3071 return StringReplaceAtomRegExpWithString<SeqTwoByteString>( | 3071 return StringReplaceAtomRegExpWithString<SeqTwoByteString>( |
| 3072 isolate, subject, regexp, replacement, last_match_info); | 3072 isolate, subject, regexp, replacement, last_match_info); |
| 3073 } | 3073 } |
| 3074 } | 3074 } |
| 3075 | 3075 |
| 3076 RegExpImpl::GlobalCache global_cache(regexp, subject, is_global, isolate); | 3076 RegExpImpl::GlobalCache global_cache(regexp, subject, is_global, isolate); |
| 3077 if (global_cache.HasException()) return Failure::Exception(); | 3077 if (global_cache.HasException()) return Failure::Exception(); |
| 3078 | 3078 |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3148 Handle<JSArray> last_match_info) { | 3148 Handle<JSArray> last_match_info) { |
| 3149 ASSERT(subject->IsFlat()); | 3149 ASSERT(subject->IsFlat()); |
| 3150 | 3150 |
| 3151 bool is_global = regexp->GetFlags().is_global(); | 3151 bool is_global = regexp->GetFlags().is_global(); |
| 3152 | 3152 |
| 3153 // Shortcut for simple non-regexp global replacements | 3153 // Shortcut for simple non-regexp global replacements |
| 3154 if (is_global && | 3154 if (is_global && |
| 3155 regexp->TypeTag() == JSRegExp::ATOM) { | 3155 regexp->TypeTag() == JSRegExp::ATOM) { |
| 3156 Handle<String> empty_string(HEAP->empty_string()); | 3156 Handle<String> empty_string(HEAP->empty_string()); |
| 3157 if (subject->HasOnlyAsciiChars()) { | 3157 if (subject->HasOnlyAsciiChars()) { |
| 3158 return StringReplaceAtomRegExpWithString<SeqAsciiString>( | 3158 return StringReplaceAtomRegExpWithString<SeqOneByteString>( |
| 3159 isolate, | 3159 isolate, |
| 3160 subject, | 3160 subject, |
| 3161 regexp, | 3161 regexp, |
| 3162 empty_string, | 3162 empty_string, |
| 3163 last_match_info); | 3163 last_match_info); |
| 3164 } else { | 3164 } else { |
| 3165 return StringReplaceAtomRegExpWithString<SeqTwoByteString>( | 3165 return StringReplaceAtomRegExpWithString<SeqTwoByteString>( |
| 3166 isolate, | 3166 isolate, |
| 3167 subject, | 3167 subject, |
| 3168 regexp, | 3168 regexp, |
| (...skipping 15 matching lines...) Expand all Loading... |
| 3184 int end = current_match[1]; | 3184 int end = current_match[1]; |
| 3185 int capture_count = regexp->CaptureCount(); | 3185 int capture_count = regexp->CaptureCount(); |
| 3186 int subject_length = subject->length(); | 3186 int subject_length = subject->length(); |
| 3187 | 3187 |
| 3188 int new_length = subject_length - (end - start); | 3188 int new_length = subject_length - (end - start); |
| 3189 if (new_length == 0) return isolate->heap()->empty_string(); | 3189 if (new_length == 0) return isolate->heap()->empty_string(); |
| 3190 | 3190 |
| 3191 Handle<ResultSeqString> answer; | 3191 Handle<ResultSeqString> answer; |
| 3192 if (ResultSeqString::kHasAsciiEncoding) { | 3192 if (ResultSeqString::kHasAsciiEncoding) { |
| 3193 answer = Handle<ResultSeqString>::cast( | 3193 answer = Handle<ResultSeqString>::cast( |
| 3194 isolate->factory()->NewRawAsciiString(new_length)); | 3194 isolate->factory()->NewRawOneByteString(new_length)); |
| 3195 } else { | 3195 } else { |
| 3196 answer = Handle<ResultSeqString>::cast( | 3196 answer = Handle<ResultSeqString>::cast( |
| 3197 isolate->factory()->NewRawTwoByteString(new_length)); | 3197 isolate->factory()->NewRawTwoByteString(new_length)); |
| 3198 } | 3198 } |
| 3199 | 3199 |
| 3200 if (!is_global) { | 3200 if (!is_global) { |
| 3201 RegExpImpl::SetLastMatchInfo( | 3201 RegExpImpl::SetLastMatchInfo( |
| 3202 last_match_info, subject, capture_count, current_match); | 3202 last_match_info, subject, capture_count, current_match); |
| 3203 if (start == end) { | 3203 if (start == end) { |
| 3204 return *subject; | 3204 return *subject; |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3276 CONVERT_ARG_HANDLE_CHECKED(JSArray, last_match_info, 3); | 3276 CONVERT_ARG_HANDLE_CHECKED(JSArray, last_match_info, 3); |
| 3277 | 3277 |
| 3278 if (!subject->IsFlat()) subject = FlattenGetString(subject); | 3278 if (!subject->IsFlat()) subject = FlattenGetString(subject); |
| 3279 | 3279 |
| 3280 if (!replacement->IsFlat()) replacement = FlattenGetString(replacement); | 3280 if (!replacement->IsFlat()) replacement = FlattenGetString(replacement); |
| 3281 | 3281 |
| 3282 ASSERT(last_match_info->HasFastObjectElements()); | 3282 ASSERT(last_match_info->HasFastObjectElements()); |
| 3283 | 3283 |
| 3284 if (replacement->length() == 0) { | 3284 if (replacement->length() == 0) { |
| 3285 if (subject->HasOnlyAsciiChars()) { | 3285 if (subject->HasOnlyAsciiChars()) { |
| 3286 return StringReplaceRegExpWithEmptyString<SeqAsciiString>( | 3286 return StringReplaceRegExpWithEmptyString<SeqOneByteString>( |
| 3287 isolate, subject, regexp, last_match_info); | 3287 isolate, subject, regexp, last_match_info); |
| 3288 } else { | 3288 } else { |
| 3289 return StringReplaceRegExpWithEmptyString<SeqTwoByteString>( | 3289 return StringReplaceRegExpWithEmptyString<SeqTwoByteString>( |
| 3290 isolate, subject, regexp, last_match_info); | 3290 isolate, subject, regexp, last_match_info); |
| 3291 } | 3291 } |
| 3292 } | 3292 } |
| 3293 | 3293 |
| 3294 return StringReplaceRegExpWithString( | 3294 return StringReplaceRegExpWithString( |
| 3295 isolate, subject, regexp, replacement, last_match_info); | 3295 isolate, subject, regexp, replacement, last_match_info); |
| 3296 } | 3296 } |
| (...skipping 1857 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5154 | 5154 |
| 5155 | 5155 |
| 5156 RUNTIME_FUNCTION(MaybeObject*, Runtime_StringToNumber) { | 5156 RUNTIME_FUNCTION(MaybeObject*, Runtime_StringToNumber) { |
| 5157 NoHandleAllocation ha; | 5157 NoHandleAllocation ha; |
| 5158 ASSERT(args.length() == 1); | 5158 ASSERT(args.length() == 1); |
| 5159 CONVERT_ARG_CHECKED(String, subject, 0); | 5159 CONVERT_ARG_CHECKED(String, subject, 0); |
| 5160 subject->TryFlatten(); | 5160 subject->TryFlatten(); |
| 5161 | 5161 |
| 5162 // Fast case: short integer or some sorts of junk values. | 5162 // Fast case: short integer or some sorts of junk values. |
| 5163 int len = subject->length(); | 5163 int len = subject->length(); |
| 5164 if (subject->IsSeqAsciiString()) { | 5164 if (subject->IsSeqOneByteString()) { |
| 5165 if (len == 0) return Smi::FromInt(0); | 5165 if (len == 0) return Smi::FromInt(0); |
| 5166 | 5166 |
| 5167 char const* data = SeqAsciiString::cast(subject)->GetChars(); | 5167 char const* data = SeqOneByteString::cast(subject)->GetChars(); |
| 5168 bool minus = (data[0] == '-'); | 5168 bool minus = (data[0] == '-'); |
| 5169 int start_pos = (minus ? 1 : 0); | 5169 int start_pos = (minus ? 1 : 0); |
| 5170 | 5170 |
| 5171 if (start_pos == len) { | 5171 if (start_pos == len) { |
| 5172 return isolate->heap()->nan_value(); | 5172 return isolate->heap()->nan_value(); |
| 5173 } else if (data[start_pos] > '9') { | 5173 } else if (data[start_pos] > '9') { |
| 5174 // Fast check for a junk value. A valid string may start from a | 5174 // Fast check for a junk value. A valid string may start from a |
| 5175 // whitespace, a sign ('+' or '-'), the decimal point, a decimal digit or | 5175 // whitespace, a sign ('+' or '-'), the decimal point, a decimal digit or |
| 5176 // the 'I' character ('Infinity'). All of that have codes not greater than | 5176 // the 'I' character ('Infinity'). All of that have codes not greater than |
| 5177 // '9' except 'I'. | 5177 // '9' except 'I'. |
| (...skipping 346 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5524 MaybeObject* AllocateRawString(Isolate* isolate, int length); | 5524 MaybeObject* AllocateRawString(Isolate* isolate, int length); |
| 5525 | 5525 |
| 5526 | 5526 |
| 5527 template <> | 5527 template <> |
| 5528 MaybeObject* AllocateRawString<SeqTwoByteString>(Isolate* isolate, int length) { | 5528 MaybeObject* AllocateRawString<SeqTwoByteString>(Isolate* isolate, int length) { |
| 5529 return isolate->heap()->AllocateRawTwoByteString(length); | 5529 return isolate->heap()->AllocateRawTwoByteString(length); |
| 5530 } | 5530 } |
| 5531 | 5531 |
| 5532 | 5532 |
| 5533 template <> | 5533 template <> |
| 5534 MaybeObject* AllocateRawString<SeqAsciiString>(Isolate* isolate, int length) { | 5534 MaybeObject* AllocateRawString<SeqOneByteString>(Isolate* isolate, int length) { |
| 5535 return isolate->heap()->AllocateRawAsciiString(length); | 5535 return isolate->heap()->AllocateRawAsciiString(length); |
| 5536 } | 5536 } |
| 5537 | 5537 |
| 5538 | 5538 |
| 5539 template <typename Char, typename StringType, bool comma> | 5539 template <typename Char, typename StringType, bool comma> |
| 5540 static MaybeObject* SlowQuoteJsonString(Isolate* isolate, | 5540 static MaybeObject* SlowQuoteJsonString(Isolate* isolate, |
| 5541 Vector<const Char> characters) { | 5541 Vector<const Char> characters) { |
| 5542 int length = characters.length(); | 5542 int length = characters.length(); |
| 5543 const Char* read_cursor = characters.start(); | 5543 const Char* read_cursor = characters.start(); |
| 5544 const Char* end = read_cursor + length; | 5544 const Char* end = read_cursor + length; |
| (...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5676 } | 5676 } |
| 5677 str = String::cast(flat); | 5677 str = String::cast(flat); |
| 5678 ASSERT(str->IsFlat()); | 5678 ASSERT(str->IsFlat()); |
| 5679 } | 5679 } |
| 5680 String::FlatContent flat = str->GetFlatContent(); | 5680 String::FlatContent flat = str->GetFlatContent(); |
| 5681 ASSERT(flat.IsFlat()); | 5681 ASSERT(flat.IsFlat()); |
| 5682 if (flat.IsTwoByte()) { | 5682 if (flat.IsTwoByte()) { |
| 5683 return QuoteJsonString<uc16, SeqTwoByteString, false>(isolate, | 5683 return QuoteJsonString<uc16, SeqTwoByteString, false>(isolate, |
| 5684 flat.ToUC16Vector()); | 5684 flat.ToUC16Vector()); |
| 5685 } else { | 5685 } else { |
| 5686 return QuoteJsonString<char, SeqAsciiString, false>(isolate, | 5686 return QuoteJsonString<char, SeqOneByteString, false>(isolate, |
| 5687 flat.ToAsciiVector()); | 5687 flat.ToAsciiVector()); |
| 5688 } | 5688 } |
| 5689 } | 5689 } |
| 5690 | 5690 |
| 5691 | 5691 |
| 5692 RUNTIME_FUNCTION(MaybeObject*, Runtime_QuoteJSONStringComma) { | 5692 RUNTIME_FUNCTION(MaybeObject*, Runtime_QuoteJSONStringComma) { |
| 5693 NoHandleAllocation ha; | 5693 NoHandleAllocation ha; |
| 5694 CONVERT_ARG_CHECKED(String, str, 0); | 5694 CONVERT_ARG_CHECKED(String, str, 0); |
| 5695 if (!str->IsFlat()) { | 5695 if (!str->IsFlat()) { |
| 5696 MaybeObject* try_flatten = str->TryFlatten(); | 5696 MaybeObject* try_flatten = str->TryFlatten(); |
| 5697 Object* flat; | 5697 Object* flat; |
| 5698 if (!try_flatten->ToObject(&flat)) { | 5698 if (!try_flatten->ToObject(&flat)) { |
| 5699 return try_flatten; | 5699 return try_flatten; |
| 5700 } | 5700 } |
| 5701 str = String::cast(flat); | 5701 str = String::cast(flat); |
| 5702 ASSERT(str->IsFlat()); | 5702 ASSERT(str->IsFlat()); |
| 5703 } | 5703 } |
| 5704 String::FlatContent flat = str->GetFlatContent(); | 5704 String::FlatContent flat = str->GetFlatContent(); |
| 5705 if (flat.IsTwoByte()) { | 5705 if (flat.IsTwoByte()) { |
| 5706 return QuoteJsonString<uc16, SeqTwoByteString, true>(isolate, | 5706 return QuoteJsonString<uc16, SeqTwoByteString, true>(isolate, |
| 5707 flat.ToUC16Vector()); | 5707 flat.ToUC16Vector()); |
| 5708 } else { | 5708 } else { |
| 5709 return QuoteJsonString<char, SeqAsciiString, true>(isolate, | 5709 return QuoteJsonString<char, SeqOneByteString, true>(isolate, |
| 5710 flat.ToAsciiVector()); | 5710 flat.ToAsciiVector()); |
| 5711 } | 5711 } |
| 5712 } | 5712 } |
| 5713 | 5713 |
| 5714 | 5714 |
| 5715 template <typename Char, typename StringType> | 5715 template <typename Char, typename StringType> |
| 5716 static MaybeObject* QuoteJsonStringArray(Isolate* isolate, | 5716 static MaybeObject* QuoteJsonStringArray(Isolate* isolate, |
| 5717 FixedArray* array, | 5717 FixedArray* array, |
| 5718 int worst_case_length) { | 5718 int worst_case_length) { |
| 5719 int length = array->length(); | 5719 int length = array->length(); |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5791 | 5791 |
| 5792 int worst_case_length = | 5792 int worst_case_length = |
| 5793 kSpaceForBrackets + n * kSpaceForQuotesAndComma | 5793 kSpaceForBrackets + n * kSpaceForQuotesAndComma |
| 5794 + total_length * kJsonQuoteWorstCaseBlowup; | 5794 + total_length * kJsonQuoteWorstCaseBlowup; |
| 5795 | 5795 |
| 5796 if (worst_case_length > kMaxGuaranteedNewSpaceString) { | 5796 if (worst_case_length > kMaxGuaranteedNewSpaceString) { |
| 5797 return isolate->heap()->undefined_value(); | 5797 return isolate->heap()->undefined_value(); |
| 5798 } | 5798 } |
| 5799 | 5799 |
| 5800 if (ascii) { | 5800 if (ascii) { |
| 5801 return QuoteJsonStringArray<char, SeqAsciiString>(isolate, | 5801 return QuoteJsonStringArray<char, SeqOneByteString>(isolate, |
| 5802 elements, | 5802 elements, |
| 5803 worst_case_length); | 5803 worst_case_length); |
| 5804 } else { | 5804 } else { |
| 5805 return QuoteJsonStringArray<uc16, SeqTwoByteString>(isolate, | 5805 return QuoteJsonStringArray<uc16, SeqTwoByteString>(isolate, |
| 5806 elements, | 5806 elements, |
| 5807 worst_case_length); | 5807 worst_case_length); |
| 5808 } | 5808 } |
| 5809 } | 5809 } |
| 5810 | 5810 |
| 5811 | 5811 |
| (...skipping 276 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6088 const int length = s->length(); | 6088 const int length = s->length(); |
| 6089 // Assume that the string is not empty; we need this assumption later | 6089 // Assume that the string is not empty; we need this assumption later |
| 6090 if (length == 0) return s; | 6090 if (length == 0) return s; |
| 6091 | 6091 |
| 6092 // Simpler handling of ASCII strings. | 6092 // Simpler handling of ASCII strings. |
| 6093 // | 6093 // |
| 6094 // NOTE: This assumes that the upper/lower case of an ASCII | 6094 // NOTE: This assumes that the upper/lower case of an ASCII |
| 6095 // character is also ASCII. This is currently the case, but it | 6095 // character is also ASCII. This is currently the case, but it |
| 6096 // might break in the future if we implement more context and locale | 6096 // might break in the future if we implement more context and locale |
| 6097 // dependent upper/lower conversions. | 6097 // dependent upper/lower conversions. |
| 6098 if (s->IsSeqAsciiString()) { | 6098 if (s->IsSeqOneByteString()) { |
| 6099 Object* o; | 6099 Object* o; |
| 6100 { MaybeObject* maybe_o = isolate->heap()->AllocateRawAsciiString(length); | 6100 { MaybeObject* maybe_o = isolate->heap()->AllocateRawAsciiString(length); |
| 6101 if (!maybe_o->ToObject(&o)) return maybe_o; | 6101 if (!maybe_o->ToObject(&o)) return maybe_o; |
| 6102 } | 6102 } |
| 6103 SeqAsciiString* result = SeqAsciiString::cast(o); | 6103 SeqOneByteString* result = SeqOneByteString::cast(o); |
| 6104 bool has_changed_character = ConvertTraits::AsciiConverter::Convert( | 6104 bool has_changed_character = ConvertTraits::AsciiConverter::Convert( |
| 6105 result->GetChars(), SeqAsciiString::cast(s)->GetChars(), length); | 6105 result->GetChars(), SeqOneByteString::cast(s)->GetChars(), length); |
| 6106 return has_changed_character ? result : s; | 6106 return has_changed_character ? result : s; |
| 6107 } | 6107 } |
| 6108 | 6108 |
| 6109 Object* answer; | 6109 Object* answer; |
| 6110 { MaybeObject* maybe_answer = | 6110 { MaybeObject* maybe_answer = |
| 6111 ConvertCaseHelper(isolate, s, length, length, mapping); | 6111 ConvertCaseHelper(isolate, s, length, length, mapping); |
| 6112 if (!maybe_answer->ToObject(&answer)) return maybe_answer; | 6112 if (!maybe_answer->ToObject(&answer)) return maybe_answer; |
| 6113 } | 6113 } |
| 6114 if (answer->IsSmi()) { | 6114 if (answer->IsSmi()) { |
| 6115 // Retry with correct length. | 6115 // Retry with correct length. |
| (...skipping 557 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6673 } | 6673 } |
| 6674 | 6674 |
| 6675 int length = position; | 6675 int length = position; |
| 6676 Object* object; | 6676 Object* object; |
| 6677 | 6677 |
| 6678 if (ascii) { | 6678 if (ascii) { |
| 6679 { MaybeObject* maybe_object = | 6679 { MaybeObject* maybe_object = |
| 6680 isolate->heap()->AllocateRawAsciiString(length); | 6680 isolate->heap()->AllocateRawAsciiString(length); |
| 6681 if (!maybe_object->ToObject(&object)) return maybe_object; | 6681 if (!maybe_object->ToObject(&object)) return maybe_object; |
| 6682 } | 6682 } |
| 6683 SeqAsciiString* answer = SeqAsciiString::cast(object); | 6683 SeqOneByteString* answer = SeqOneByteString::cast(object); |
| 6684 StringBuilderConcatHelper(special, | 6684 StringBuilderConcatHelper(special, |
| 6685 answer->GetChars(), | 6685 answer->GetChars(), |
| 6686 fixed_array, | 6686 fixed_array, |
| 6687 array_length); | 6687 array_length); |
| 6688 return answer; | 6688 return answer; |
| 6689 } else { | 6689 } else { |
| 6690 { MaybeObject* maybe_object = | 6690 { MaybeObject* maybe_object = |
| 6691 isolate->heap()->AllocateRawTwoByteString(length); | 6691 isolate->heap()->AllocateRawTwoByteString(length); |
| 6692 if (!maybe_object->ToObject(&object)) return maybe_object; | 6692 if (!maybe_object->ToObject(&object)) return maybe_object; |
| 6693 } | 6693 } |
| (...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6835 // elements_array is fast-mode JSarray of alternating positions | 6835 // elements_array is fast-mode JSarray of alternating positions |
| 6836 // (increasing order) and strings. | 6836 // (increasing order) and strings. |
| 6837 // array_length is length of original array (used to add separators); | 6837 // array_length is length of original array (used to add separators); |
| 6838 // separator is string to put between elements. Assumed to be non-empty. | 6838 // separator is string to put between elements. Assumed to be non-empty. |
| 6839 | 6839 |
| 6840 // Find total length of join result. | 6840 // Find total length of join result. |
| 6841 int string_length = 0; | 6841 int string_length = 0; |
| 6842 bool is_ascii = separator->IsAsciiRepresentation(); | 6842 bool is_ascii = separator->IsAsciiRepresentation(); |
| 6843 int max_string_length; | 6843 int max_string_length; |
| 6844 if (is_ascii) { | 6844 if (is_ascii) { |
| 6845 max_string_length = SeqAsciiString::kMaxLength; | 6845 max_string_length = SeqOneByteString::kMaxLength; |
| 6846 } else { | 6846 } else { |
| 6847 max_string_length = SeqTwoByteString::kMaxLength; | 6847 max_string_length = SeqTwoByteString::kMaxLength; |
| 6848 } | 6848 } |
| 6849 bool overflow = false; | 6849 bool overflow = false; |
| 6850 CONVERT_NUMBER_CHECKED(int, elements_length, | 6850 CONVERT_NUMBER_CHECKED(int, elements_length, |
| 6851 Int32, elements_array->length()); | 6851 Int32, elements_array->length()); |
| 6852 RUNTIME_ASSERT((elements_length & 1) == 0); // Even length. | 6852 RUNTIME_ASSERT((elements_length & 1) == 0); // Even length. |
| 6853 FixedArray* elements = FixedArray::cast(elements_array->elements()); | 6853 FixedArray* elements = FixedArray::cast(elements_array->elements()); |
| 6854 for (int i = 0; i < elements_length; i += 2) { | 6854 for (int i = 0; i < elements_length; i += 2) { |
| 6855 RUNTIME_ASSERT(elements->get(i)->IsNumber()); | 6855 RUNTIME_ASSERT(elements->get(i)->IsNumber()); |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6887 } | 6887 } |
| 6888 if (overflow) { | 6888 if (overflow) { |
| 6889 // Throw OutOfMemory exception for creating too large a string. | 6889 // Throw OutOfMemory exception for creating too large a string. |
| 6890 V8::FatalProcessOutOfMemory("Array join result too large."); | 6890 V8::FatalProcessOutOfMemory("Array join result too large."); |
| 6891 } | 6891 } |
| 6892 | 6892 |
| 6893 if (is_ascii) { | 6893 if (is_ascii) { |
| 6894 MaybeObject* result_allocation = | 6894 MaybeObject* result_allocation = |
| 6895 isolate->heap()->AllocateRawAsciiString(string_length); | 6895 isolate->heap()->AllocateRawAsciiString(string_length); |
| 6896 if (result_allocation->IsFailure()) return result_allocation; | 6896 if (result_allocation->IsFailure()) return result_allocation; |
| 6897 SeqAsciiString* result_string = | 6897 SeqOneByteString* result_string = |
| 6898 SeqAsciiString::cast(result_allocation->ToObjectUnchecked()); | 6898 SeqOneByteString::cast(result_allocation->ToObjectUnchecked()); |
| 6899 JoinSparseArrayWithSeparator<char>(elements, | 6899 JoinSparseArrayWithSeparator<char>(elements, |
| 6900 elements_length, | 6900 elements_length, |
| 6901 array_length, | 6901 array_length, |
| 6902 separator, | 6902 separator, |
| 6903 Vector<char>(result_string->GetChars(), | 6903 Vector<char>(result_string->GetChars(), |
| 6904 string_length)); | 6904 string_length)); |
| 6905 return result_string; | 6905 return result_string; |
| 6906 } else { | 6906 } else { |
| 6907 MaybeObject* result_allocation = | 6907 MaybeObject* result_allocation = |
| 6908 isolate->heap()->AllocateRawTwoByteString(string_length); | 6908 isolate->heap()->AllocateRawTwoByteString(string_length); |
| (...skipping 2150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9059 | 9059 |
| 9060 RUNTIME_FUNCTION(MaybeObject*, Runtime_ParseJson) { | 9060 RUNTIME_FUNCTION(MaybeObject*, Runtime_ParseJson) { |
| 9061 HandleScope scope(isolate); | 9061 HandleScope scope(isolate); |
| 9062 ASSERT_EQ(1, args.length()); | 9062 ASSERT_EQ(1, args.length()); |
| 9063 CONVERT_ARG_HANDLE_CHECKED(String, source, 0); | 9063 CONVERT_ARG_HANDLE_CHECKED(String, source, 0); |
| 9064 | 9064 |
| 9065 Zone* zone = isolate->runtime_zone(); | 9065 Zone* zone = isolate->runtime_zone(); |
| 9066 source = Handle<String>(source->TryFlattenGetString()); | 9066 source = Handle<String>(source->TryFlattenGetString()); |
| 9067 // Optimized fast case where we only have ASCII characters. | 9067 // Optimized fast case where we only have ASCII characters. |
| 9068 Handle<Object> result; | 9068 Handle<Object> result; |
| 9069 if (source->IsSeqAsciiString()) { | 9069 if (source->IsSeqOneByteString()) { |
| 9070 result = JsonParser<true>::Parse(source, zone); | 9070 result = JsonParser<true>::Parse(source, zone); |
| 9071 } else { | 9071 } else { |
| 9072 result = JsonParser<false>::Parse(source, zone); | 9072 result = JsonParser<false>::Parse(source, zone); |
| 9073 } | 9073 } |
| 9074 if (result.is_null()) { | 9074 if (result.is_null()) { |
| 9075 // Syntax error or stack overflow in scanner. | 9075 // Syntax error or stack overflow in scanner. |
| 9076 ASSERT(isolate->has_pending_exception()); | 9076 ASSERT(isolate->has_pending_exception()); |
| 9077 return Failure::Exception(); | 9077 return Failure::Exception(); |
| 9078 } | 9078 } |
| 9079 return *result; | 9079 return *result; |
| (...skipping 4341 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 13421 // Handle last resort GC and make sure to allow future allocations | 13421 // Handle last resort GC and make sure to allow future allocations |
| 13422 // to grow the heap without causing GCs (if possible). | 13422 // to grow the heap without causing GCs (if possible). |
| 13423 isolate->counters()->gc_last_resort_from_js()->Increment(); | 13423 isolate->counters()->gc_last_resort_from_js()->Increment(); |
| 13424 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags, | 13424 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags, |
| 13425 "Runtime::PerformGC"); | 13425 "Runtime::PerformGC"); |
| 13426 } | 13426 } |
| 13427 } | 13427 } |
| 13428 | 13428 |
| 13429 | 13429 |
| 13430 } } // namespace v8::internal | 13430 } } // namespace v8::internal |
| OLD | NEW |