| 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 | 
|---|