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 |