| 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 2387 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2398 | 2398 |
| 2399 Handle<String> ToString() { | 2399 Handle<String> ToString() { |
| 2400 if (array_builder_.length() == 0) { | 2400 if (array_builder_.length() == 0) { |
| 2401 return heap_->isolate()->factory()->empty_string(); | 2401 return heap_->isolate()->factory()->empty_string(); |
| 2402 } | 2402 } |
| 2403 | 2403 |
| 2404 Handle<String> joined_string; | 2404 Handle<String> joined_string; |
| 2405 if (is_ascii_) { | 2405 if (is_ascii_) { |
| 2406 Handle<SeqOneByteString> seq = NewRawOneByteString(character_count_); | 2406 Handle<SeqOneByteString> seq = NewRawOneByteString(character_count_); |
| 2407 AssertNoAllocation no_alloc; | 2407 AssertNoAllocation no_alloc; |
| 2408 char* char_buffer = seq->GetChars(); | 2408 uint8_t* char_buffer = seq->GetChars(); |
| 2409 StringBuilderConcatHelper(*subject_, | 2409 StringBuilderConcatHelper(*subject_, |
| 2410 char_buffer, | 2410 char_buffer, |
| 2411 *array_builder_.array(), | 2411 *array_builder_.array(), |
| 2412 array_builder_.length()); | 2412 array_builder_.length()); |
| 2413 joined_string = Handle<String>::cast(seq); | 2413 joined_string = Handle<String>::cast(seq); |
| 2414 } else { | 2414 } else { |
| 2415 // Non-ASCII. | 2415 // Non-ASCII. |
| 2416 Handle<SeqTwoByteString> seq = NewRawTwoByteString(character_count_); | 2416 Handle<SeqTwoByteString> seq = NewRawTwoByteString(character_count_); |
| 2417 AssertNoAllocation no_alloc; | 2417 AssertNoAllocation no_alloc; |
| 2418 uc16* char_buffer = seq->GetChars(); | 2418 uc16* char_buffer = seq->GetChars(); |
| (...skipping 236 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2655 bool CompiledReplacement::Compile(Handle<String> replacement, | 2655 bool CompiledReplacement::Compile(Handle<String> replacement, |
| 2656 int capture_count, | 2656 int capture_count, |
| 2657 int subject_length) { | 2657 int subject_length) { |
| 2658 { | 2658 { |
| 2659 AssertNoAllocation no_alloc; | 2659 AssertNoAllocation no_alloc; |
| 2660 String::FlatContent content = replacement->GetFlatContent(); | 2660 String::FlatContent content = replacement->GetFlatContent(); |
| 2661 ASSERT(content.IsFlat()); | 2661 ASSERT(content.IsFlat()); |
| 2662 bool simple = false; | 2662 bool simple = false; |
| 2663 if (content.IsAscii()) { | 2663 if (content.IsAscii()) { |
| 2664 simple = ParseReplacementPattern(&parts_, | 2664 simple = ParseReplacementPattern(&parts_, |
| 2665 content.ToAsciiVector(), | 2665 content.ToOneByteVector(), |
| 2666 capture_count, | 2666 capture_count, |
| 2667 subject_length, | 2667 subject_length, |
| 2668 zone()); | 2668 zone()); |
| 2669 } else { | 2669 } else { |
| 2670 ASSERT(content.IsTwoByte()); | 2670 ASSERT(content.IsTwoByte()); |
| 2671 simple = ParseReplacementPattern(&parts_, | 2671 simple = ParseReplacementPattern(&parts_, |
| 2672 content.ToUC16Vector(), | 2672 content.ToUC16Vector(), |
| 2673 capture_count, | 2673 capture_count, |
| 2674 subject_length, | 2674 subject_length, |
| 2675 zone()); | 2675 zone()); |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2731 case REPLACEMENT_STRING: | 2731 case REPLACEMENT_STRING: |
| 2732 builder->AddString(replacement_substrings_[part.data]); | 2732 builder->AddString(replacement_substrings_[part.data]); |
| 2733 break; | 2733 break; |
| 2734 default: | 2734 default: |
| 2735 UNREACHABLE(); | 2735 UNREACHABLE(); |
| 2736 } | 2736 } |
| 2737 } | 2737 } |
| 2738 } | 2738 } |
| 2739 | 2739 |
| 2740 | 2740 |
| 2741 void FindAsciiStringIndices(Vector<const char> subject, | 2741 void FindAsciiStringIndices(Vector<const uint8_t> subject, |
| 2742 char pattern, | 2742 char pattern, |
| 2743 ZoneList<int>* indices, | 2743 ZoneList<int>* indices, |
| 2744 unsigned int limit, | 2744 unsigned int limit, |
| 2745 Zone* zone) { | 2745 Zone* zone) { |
| 2746 ASSERT(limit > 0); | 2746 ASSERT(limit > 0); |
| 2747 // Collect indices of pattern in subject using memchr. | 2747 // Collect indices of pattern in subject using memchr. |
| 2748 // Stop after finding at most limit values. | 2748 // Stop after finding at most limit values. |
| 2749 const char* subject_start = reinterpret_cast<const char*>(subject.start()); | 2749 const uint8_t* subject_start = subject.start(); |
| 2750 const char* subject_end = subject_start + subject.length(); | 2750 const uint8_t* subject_end = subject_start + subject.length(); |
| 2751 const char* pos = subject_start; | 2751 const uint8_t* pos = subject_start; |
| 2752 while (limit > 0) { | 2752 while (limit > 0) { |
| 2753 pos = reinterpret_cast<const char*>( | 2753 pos = reinterpret_cast<const uint8_t*>( |
| 2754 memchr(pos, pattern, subject_end - pos)); | 2754 memchr(pos, pattern, subject_end - pos)); |
| 2755 if (pos == NULL) return; | 2755 if (pos == NULL) return; |
| 2756 indices->Add(static_cast<int>(pos - subject_start), zone); | 2756 indices->Add(static_cast<int>(pos - subject_start), zone); |
| 2757 pos++; | 2757 pos++; |
| 2758 limit--; | 2758 limit--; |
| 2759 } | 2759 } |
| 2760 } | 2760 } |
| 2761 | 2761 |
| 2762 | 2762 |
| 2763 void FindTwoByteStringIndices(const Vector<const uc16> subject, | 2763 void FindTwoByteStringIndices(const Vector<const uc16> subject, |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2806 ZoneList<int>* indices, | 2806 ZoneList<int>* indices, |
| 2807 unsigned int limit, | 2807 unsigned int limit, |
| 2808 Zone* zone) { | 2808 Zone* zone) { |
| 2809 { | 2809 { |
| 2810 AssertNoAllocation no_gc; | 2810 AssertNoAllocation no_gc; |
| 2811 String::FlatContent subject_content = subject->GetFlatContent(); | 2811 String::FlatContent subject_content = subject->GetFlatContent(); |
| 2812 String::FlatContent pattern_content = pattern->GetFlatContent(); | 2812 String::FlatContent pattern_content = pattern->GetFlatContent(); |
| 2813 ASSERT(subject_content.IsFlat()); | 2813 ASSERT(subject_content.IsFlat()); |
| 2814 ASSERT(pattern_content.IsFlat()); | 2814 ASSERT(pattern_content.IsFlat()); |
| 2815 if (subject_content.IsAscii()) { | 2815 if (subject_content.IsAscii()) { |
| 2816 Vector<const char> subject_vector = subject_content.ToAsciiVector(); | 2816 Vector<const uint8_t> subject_vector = subject_content.ToOneByteVector(); |
| 2817 if (pattern_content.IsAscii()) { | 2817 if (pattern_content.IsAscii()) { |
| 2818 Vector<const char> pattern_vector = pattern_content.ToAsciiVector(); | 2818 Vector<const uint8_t> pattern_vector = |
| 2819 pattern_content.ToOneByteVector(); |
| 2819 if (pattern_vector.length() == 1) { | 2820 if (pattern_vector.length() == 1) { |
| 2820 FindAsciiStringIndices(subject_vector, | 2821 FindAsciiStringIndices(subject_vector, |
| 2821 pattern_vector[0], | 2822 pattern_vector[0], |
| 2822 indices, | 2823 indices, |
| 2823 limit, | 2824 limit, |
| 2824 zone); | 2825 zone); |
| 2825 } else { | 2826 } else { |
| 2826 FindStringIndices(isolate, | 2827 FindStringIndices(isolate, |
| 2827 subject_vector, | 2828 subject_vector, |
| 2828 pattern_vector, | 2829 pattern_vector, |
| 2829 indices, | 2830 indices, |
| 2830 limit, | 2831 limit, |
| 2831 zone); | 2832 zone); |
| 2832 } | 2833 } |
| 2833 } else { | 2834 } else { |
| 2834 FindStringIndices(isolate, | 2835 FindStringIndices(isolate, |
| 2835 subject_vector, | 2836 subject_vector, |
| 2836 pattern_content.ToUC16Vector(), | 2837 pattern_content.ToUC16Vector(), |
| 2837 indices, | 2838 indices, |
| 2838 limit, | 2839 limit, |
| 2839 zone); | 2840 zone); |
| 2840 } | 2841 } |
| 2841 } else { | 2842 } else { |
| 2842 Vector<const uc16> subject_vector = subject_content.ToUC16Vector(); | 2843 Vector<const uc16> subject_vector = subject_content.ToUC16Vector(); |
| 2843 if (pattern_content.IsAscii()) { | 2844 if (pattern_content.IsAscii()) { |
| 2844 Vector<const char> pattern_vector = pattern_content.ToAsciiVector(); | 2845 Vector<const uint8_t> pattern_vector = |
| 2846 pattern_content.ToOneByteVector(); |
| 2845 if (pattern_vector.length() == 1) { | 2847 if (pattern_vector.length() == 1) { |
| 2846 FindTwoByteStringIndices(subject_vector, | 2848 FindTwoByteStringIndices(subject_vector, |
| 2847 pattern_vector[0], | 2849 pattern_vector[0], |
| 2848 indices, | 2850 indices, |
| 2849 limit, | 2851 limit, |
| 2850 zone); | 2852 zone); |
| 2851 } else { | 2853 } else { |
| 2852 FindStringIndices(isolate, | 2854 FindStringIndices(isolate, |
| 2853 subject_vector, | 2855 subject_vector, |
| 2854 pattern_vector, | 2856 pattern_vector, |
| (...skipping 461 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3316 if (!sub->IsFlat()) FlattenString(sub); | 3318 if (!sub->IsFlat()) FlattenString(sub); |
| 3317 if (!pat->IsFlat()) FlattenString(pat); | 3319 if (!pat->IsFlat()) FlattenString(pat); |
| 3318 | 3320 |
| 3319 AssertNoAllocation no_heap_allocation; // ensure vectors stay valid | 3321 AssertNoAllocation no_heap_allocation; // ensure vectors stay valid |
| 3320 // Extract flattened substrings of cons strings before determining asciiness. | 3322 // Extract flattened substrings of cons strings before determining asciiness. |
| 3321 String::FlatContent seq_sub = sub->GetFlatContent(); | 3323 String::FlatContent seq_sub = sub->GetFlatContent(); |
| 3322 String::FlatContent seq_pat = pat->GetFlatContent(); | 3324 String::FlatContent seq_pat = pat->GetFlatContent(); |
| 3323 | 3325 |
| 3324 // dispatch on type of strings | 3326 // dispatch on type of strings |
| 3325 if (seq_pat.IsAscii()) { | 3327 if (seq_pat.IsAscii()) { |
| 3326 Vector<const char> pat_vector = seq_pat.ToAsciiVector(); | 3328 Vector<const uint8_t> pat_vector = seq_pat.ToOneByteVector(); |
| 3327 if (seq_sub.IsAscii()) { | 3329 if (seq_sub.IsAscii()) { |
| 3328 return SearchString(isolate, | 3330 return SearchString(isolate, |
| 3329 seq_sub.ToAsciiVector(), | 3331 seq_sub.ToOneByteVector(), |
| 3330 pat_vector, | 3332 pat_vector, |
| 3331 start_index); | 3333 start_index); |
| 3332 } | 3334 } |
| 3333 return SearchString(isolate, | 3335 return SearchString(isolate, |
| 3334 seq_sub.ToUC16Vector(), | 3336 seq_sub.ToUC16Vector(), |
| 3335 pat_vector, | 3337 pat_vector, |
| 3336 start_index); | 3338 start_index); |
| 3337 } | 3339 } |
| 3338 Vector<const uc16> pat_vector = seq_pat.ToUC16Vector(); | 3340 Vector<const uc16> pat_vector = seq_pat.ToUC16Vector(); |
| 3339 if (seq_sub.IsAscii()) { | 3341 if (seq_sub.IsAscii()) { |
| 3340 return SearchString(isolate, | 3342 return SearchString(isolate, |
| 3341 seq_sub.ToAsciiVector(), | 3343 seq_sub.ToOneByteVector(), |
| 3342 pat_vector, | 3344 pat_vector, |
| 3343 start_index); | 3345 start_index); |
| 3344 } | 3346 } |
| 3345 return SearchString(isolate, | 3347 return SearchString(isolate, |
| 3346 seq_sub.ToUC16Vector(), | 3348 seq_sub.ToUC16Vector(), |
| 3347 pat_vector, | 3349 pat_vector, |
| 3348 start_index); | 3350 start_index); |
| 3349 } | 3351 } |
| 3350 | 3352 |
| 3351 | 3353 |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3426 if (!sub->IsFlat()) FlattenString(sub); | 3428 if (!sub->IsFlat()) FlattenString(sub); |
| 3427 if (!pat->IsFlat()) FlattenString(pat); | 3429 if (!pat->IsFlat()) FlattenString(pat); |
| 3428 | 3430 |
| 3429 int position = -1; | 3431 int position = -1; |
| 3430 AssertNoAllocation no_heap_allocation; // ensure vectors stay valid | 3432 AssertNoAllocation no_heap_allocation; // ensure vectors stay valid |
| 3431 | 3433 |
| 3432 String::FlatContent sub_content = sub->GetFlatContent(); | 3434 String::FlatContent sub_content = sub->GetFlatContent(); |
| 3433 String::FlatContent pat_content = pat->GetFlatContent(); | 3435 String::FlatContent pat_content = pat->GetFlatContent(); |
| 3434 | 3436 |
| 3435 if (pat_content.IsAscii()) { | 3437 if (pat_content.IsAscii()) { |
| 3436 Vector<const char> pat_vector = pat_content.ToAsciiVector(); | 3438 Vector<const uint8_t> pat_vector = pat_content.ToOneByteVector(); |
| 3437 if (sub_content.IsAscii()) { | 3439 if (sub_content.IsAscii()) { |
| 3438 position = StringMatchBackwards(sub_content.ToAsciiVector(), | 3440 position = StringMatchBackwards(sub_content.ToOneByteVector(), |
| 3439 pat_vector, | 3441 pat_vector, |
| 3440 start_index); | 3442 start_index); |
| 3441 } else { | 3443 } else { |
| 3442 position = StringMatchBackwards(sub_content.ToUC16Vector(), | 3444 position = StringMatchBackwards(sub_content.ToUC16Vector(), |
| 3443 pat_vector, | 3445 pat_vector, |
| 3444 start_index); | 3446 start_index); |
| 3445 } | 3447 } |
| 3446 } else { | 3448 } else { |
| 3447 Vector<const uc16> pat_vector = pat_content.ToUC16Vector(); | 3449 Vector<const uc16> pat_vector = pat_content.ToUC16Vector(); |
| 3448 if (sub_content.IsAscii()) { | 3450 if (sub_content.IsAscii()) { |
| 3449 position = StringMatchBackwards(sub_content.ToAsciiVector(), | 3451 position = StringMatchBackwards(sub_content.ToOneByteVector(), |
| 3450 pat_vector, | 3452 pat_vector, |
| 3451 start_index); | 3453 start_index); |
| 3452 } else { | 3454 } else { |
| 3453 position = StringMatchBackwards(sub_content.ToUC16Vector(), | 3455 position = StringMatchBackwards(sub_content.ToUC16Vector(), |
| 3454 pat_vector, | 3456 pat_vector, |
| 3455 start_index); | 3457 start_index); |
| 3456 } | 3458 } |
| 3457 } | 3459 } |
| 3458 | 3460 |
| 3459 return Smi::FromInt(position); | 3461 return Smi::FromInt(position); |
| (...skipping 1533 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4993 case JS_FUNCTION_PROXY_TYPE: | 4995 case JS_FUNCTION_PROXY_TYPE: |
| 4994 return isolate->heap()->function_symbol(); | 4996 return isolate->heap()->function_symbol(); |
| 4995 default: | 4997 default: |
| 4996 // For any kind of object not handled above, the spec rule for | 4998 // For any kind of object not handled above, the spec rule for |
| 4997 // host objects gives that it is okay to return "object" | 4999 // host objects gives that it is okay to return "object" |
| 4998 return isolate->heap()->object_symbol(); | 5000 return isolate->heap()->object_symbol(); |
| 4999 } | 5001 } |
| 5000 } | 5002 } |
| 5001 | 5003 |
| 5002 | 5004 |
| 5003 static bool AreDigits(const char*s, int from, int to) { | 5005 static bool AreDigits(const uint8_t*s, int from, int to) { |
| 5004 for (int i = from; i < to; i++) { | 5006 for (int i = from; i < to; i++) { |
| 5005 if (s[i] < '0' || s[i] > '9') return false; | 5007 if (s[i] < '0' || s[i] > '9') return false; |
| 5006 } | 5008 } |
| 5007 | 5009 |
| 5008 return true; | 5010 return true; |
| 5009 } | 5011 } |
| 5010 | 5012 |
| 5011 | 5013 |
| 5012 static int ParseDecimalInteger(const char*s, int from, int to) { | 5014 static int ParseDecimalInteger(const uint8_t*s, int from, int to) { |
| 5013 ASSERT(to - from < 10); // Overflow is not possible. | 5015 ASSERT(to - from < 10); // Overflow is not possible. |
| 5014 ASSERT(from < to); | 5016 ASSERT(from < to); |
| 5015 int d = s[from] - '0'; | 5017 int d = s[from] - '0'; |
| 5016 | 5018 |
| 5017 for (int i = from + 1; i < to; i++) { | 5019 for (int i = from + 1; i < to; i++) { |
| 5018 d = 10 * d + (s[i] - '0'); | 5020 d = 10 * d + (s[i] - '0'); |
| 5019 } | 5021 } |
| 5020 | 5022 |
| 5021 return d; | 5023 return d; |
| 5022 } | 5024 } |
| 5023 | 5025 |
| 5024 | 5026 |
| 5025 RUNTIME_FUNCTION(MaybeObject*, Runtime_StringToNumber) { | 5027 RUNTIME_FUNCTION(MaybeObject*, Runtime_StringToNumber) { |
| 5026 NoHandleAllocation ha; | 5028 NoHandleAllocation ha; |
| 5027 ASSERT(args.length() == 1); | 5029 ASSERT(args.length() == 1); |
| 5028 CONVERT_ARG_CHECKED(String, subject, 0); | 5030 CONVERT_ARG_CHECKED(String, subject, 0); |
| 5029 subject->TryFlatten(); | 5031 subject->TryFlatten(); |
| 5030 | 5032 |
| 5031 // Fast case: short integer or some sorts of junk values. | 5033 // Fast case: short integer or some sorts of junk values. |
| 5032 int len = subject->length(); | 5034 int len = subject->length(); |
| 5033 if (subject->IsSeqOneByteString()) { | 5035 if (subject->IsSeqOneByteString()) { |
| 5034 if (len == 0) return Smi::FromInt(0); | 5036 if (len == 0) return Smi::FromInt(0); |
| 5035 | 5037 |
| 5036 char const* data = SeqOneByteString::cast(subject)->GetChars(); | 5038 uint8_t const* data = SeqOneByteString::cast(subject)->GetChars(); |
| 5037 bool minus = (data[0] == '-'); | 5039 bool minus = (data[0] == '-'); |
| 5038 int start_pos = (minus ? 1 : 0); | 5040 int start_pos = (minus ? 1 : 0); |
| 5039 | 5041 |
| 5040 if (start_pos == len) { | 5042 if (start_pos == len) { |
| 5041 return isolate->heap()->nan_value(); | 5043 return isolate->heap()->nan_value(); |
| 5042 } else if (data[start_pos] > '9') { | 5044 } else if (data[start_pos] > '9') { |
| 5043 // Fast check for a junk value. A valid string may start from a | 5045 // Fast check for a junk value. A valid string may start from a |
| 5044 // whitespace, a sign ('+' or '-'), the decimal point, a decimal digit or | 5046 // whitespace, a sign ('+' or '-'), the decimal point, a decimal digit or |
| 5045 // the 'I' character ('Infinity'). All of that have codes not greater than | 5047 // the 'I' character ('Infinity'). All of that have codes not greater than |
| 5046 // '9' except 'I'. | 5048 // '9' except 'I'. |
| (...skipping 474 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5521 } | 5523 } |
| 5522 str = String::cast(flat); | 5524 str = String::cast(flat); |
| 5523 ASSERT(str->IsFlat()); | 5525 ASSERT(str->IsFlat()); |
| 5524 } | 5526 } |
| 5525 String::FlatContent flat = str->GetFlatContent(); | 5527 String::FlatContent flat = str->GetFlatContent(); |
| 5526 ASSERT(flat.IsFlat()); | 5528 ASSERT(flat.IsFlat()); |
| 5527 if (flat.IsTwoByte()) { | 5529 if (flat.IsTwoByte()) { |
| 5528 return QuoteJsonString<uc16, SeqTwoByteString, false>(isolate, | 5530 return QuoteJsonString<uc16, SeqTwoByteString, false>(isolate, |
| 5529 flat.ToUC16Vector()); | 5531 flat.ToUC16Vector()); |
| 5530 } else { | 5532 } else { |
| 5531 return QuoteJsonString<char, SeqOneByteString, false>(isolate, | 5533 return QuoteJsonString<uint8_t, SeqOneByteString, false>( |
| 5532 flat.ToAsciiVector()); | 5534 isolate, |
| 5535 flat.ToOneByteVector()); |
| 5533 } | 5536 } |
| 5534 } | 5537 } |
| 5535 | 5538 |
| 5536 | 5539 |
| 5537 RUNTIME_FUNCTION(MaybeObject*, Runtime_QuoteJSONStringComma) { | 5540 RUNTIME_FUNCTION(MaybeObject*, Runtime_QuoteJSONStringComma) { |
| 5538 NoHandleAllocation ha; | 5541 NoHandleAllocation ha; |
| 5539 CONVERT_ARG_CHECKED(String, str, 0); | 5542 CONVERT_ARG_CHECKED(String, str, 0); |
| 5540 if (!str->IsFlat()) { | 5543 if (!str->IsFlat()) { |
| 5541 MaybeObject* try_flatten = str->TryFlatten(); | 5544 MaybeObject* try_flatten = str->TryFlatten(); |
| 5542 Object* flat; | 5545 Object* flat; |
| 5543 if (!try_flatten->ToObject(&flat)) { | 5546 if (!try_flatten->ToObject(&flat)) { |
| 5544 return try_flatten; | 5547 return try_flatten; |
| 5545 } | 5548 } |
| 5546 str = String::cast(flat); | 5549 str = String::cast(flat); |
| 5547 ASSERT(str->IsFlat()); | 5550 ASSERT(str->IsFlat()); |
| 5548 } | 5551 } |
| 5549 String::FlatContent flat = str->GetFlatContent(); | 5552 String::FlatContent flat = str->GetFlatContent(); |
| 5550 if (flat.IsTwoByte()) { | 5553 if (flat.IsTwoByte()) { |
| 5551 return QuoteJsonString<uc16, SeqTwoByteString, true>(isolate, | 5554 return QuoteJsonString<uc16, SeqTwoByteString, true>(isolate, |
| 5552 flat.ToUC16Vector()); | 5555 flat.ToUC16Vector()); |
| 5553 } else { | 5556 } else { |
| 5554 return QuoteJsonString<char, SeqOneByteString, true>(isolate, | 5557 return QuoteJsonString<uint8_t, SeqOneByteString, true>( |
| 5555 flat.ToAsciiVector()); | 5558 isolate, |
| 5559 flat.ToOneByteVector()); |
| 5556 } | 5560 } |
| 5557 } | 5561 } |
| 5558 | 5562 |
| 5559 | 5563 |
| 5560 template <typename Char, typename StringType> | 5564 template <typename Char, typename StringType> |
| 5561 static MaybeObject* QuoteJsonStringArray(Isolate* isolate, | 5565 static MaybeObject* QuoteJsonStringArray(Isolate* isolate, |
| 5562 FixedArray* array, | 5566 FixedArray* array, |
| 5563 int worst_case_length) { | 5567 int worst_case_length) { |
| 5564 int length = array->length(); | 5568 int length = array->length(); |
| 5565 | 5569 |
| (...skipping 20 matching lines...) Expand all Loading... |
| 5586 for (int i = 0; i < length; i++) { | 5590 for (int i = 0; i < length; i++) { |
| 5587 if (i != 0) *(write_cursor++) = ','; | 5591 if (i != 0) *(write_cursor++) = ','; |
| 5588 String* str = String::cast(array->get(i)); | 5592 String* str = String::cast(array->get(i)); |
| 5589 String::FlatContent content = str->GetFlatContent(); | 5593 String::FlatContent content = str->GetFlatContent(); |
| 5590 ASSERT(content.IsFlat()); | 5594 ASSERT(content.IsFlat()); |
| 5591 if (content.IsTwoByte()) { | 5595 if (content.IsTwoByte()) { |
| 5592 write_cursor = WriteQuoteJsonString<Char, uc16>(isolate, | 5596 write_cursor = WriteQuoteJsonString<Char, uc16>(isolate, |
| 5593 write_cursor, | 5597 write_cursor, |
| 5594 content.ToUC16Vector()); | 5598 content.ToUC16Vector()); |
| 5595 } else { | 5599 } else { |
| 5596 write_cursor = WriteQuoteJsonString<Char, char>(isolate, | 5600 write_cursor = |
| 5597 write_cursor, | 5601 WriteQuoteJsonString<Char, uint8_t>(isolate, |
| 5598 content.ToAsciiVector()); | 5602 write_cursor, |
| 5603 content.ToOneByteVector()); |
| 5599 } | 5604 } |
| 5600 } | 5605 } |
| 5601 *(write_cursor++) = ']'; | 5606 *(write_cursor++) = ']'; |
| 5602 | 5607 |
| 5603 int final_length = static_cast<int>( | 5608 int final_length = static_cast<int>( |
| 5604 write_cursor - reinterpret_cast<Char*>( | 5609 write_cursor - reinterpret_cast<Char*>( |
| 5605 new_string->address() + SeqString::kHeaderSize)); | 5610 new_string->address() + SeqString::kHeaderSize)); |
| 5606 isolate->heap()->new_space()-> | 5611 isolate->heap()->new_space()-> |
| 5607 template ShrinkStringAtAllocationBoundary<StringType>( | 5612 template ShrinkStringAtAllocationBoundary<StringType>( |
| 5608 new_string, final_length); | 5613 new_string, final_length); |
| (...skipping 332 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5941 // character is also ASCII. This is currently the case, but it | 5946 // character is also ASCII. This is currently the case, but it |
| 5942 // might break in the future if we implement more context and locale | 5947 // might break in the future if we implement more context and locale |
| 5943 // dependent upper/lower conversions. | 5948 // dependent upper/lower conversions. |
| 5944 if (s->IsSeqOneByteString()) { | 5949 if (s->IsSeqOneByteString()) { |
| 5945 Object* o; | 5950 Object* o; |
| 5946 { MaybeObject* maybe_o = isolate->heap()->AllocateRawOneByteString(length); | 5951 { MaybeObject* maybe_o = isolate->heap()->AllocateRawOneByteString(length); |
| 5947 if (!maybe_o->ToObject(&o)) return maybe_o; | 5952 if (!maybe_o->ToObject(&o)) return maybe_o; |
| 5948 } | 5953 } |
| 5949 SeqOneByteString* result = SeqOneByteString::cast(o); | 5954 SeqOneByteString* result = SeqOneByteString::cast(o); |
| 5950 bool has_changed_character = ConvertTraits::AsciiConverter::Convert( | 5955 bool has_changed_character = ConvertTraits::AsciiConverter::Convert( |
| 5951 result->GetChars(), SeqOneByteString::cast(s)->GetChars(), length); | 5956 reinterpret_cast<char*>(result->GetChars()), |
| 5957 reinterpret_cast<char*>(SeqOneByteString::cast(s)->GetChars()), |
| 5958 length); |
| 5952 return has_changed_character ? result : s; | 5959 return has_changed_character ? result : s; |
| 5953 } | 5960 } |
| 5954 #endif | 5961 #endif |
| 5955 | 5962 |
| 5956 Object* answer; | 5963 Object* answer; |
| 5957 { MaybeObject* maybe_answer = | 5964 { MaybeObject* maybe_answer = |
| 5958 ConvertCaseHelper(isolate, s, length, length, mapping); | 5965 ConvertCaseHelper(isolate, s, length, length, mapping); |
| 5959 if (!maybe_answer->ToObject(&answer)) return maybe_answer; | 5966 if (!maybe_answer->ToObject(&answer)) return maybe_answer; |
| 5960 } | 5967 } |
| 5961 if (answer->IsSmi()) { | 5968 if (answer->IsSmi()) { |
| (...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6103 | 6110 |
| 6104 return *result; | 6111 return *result; |
| 6105 } | 6112 } |
| 6106 | 6113 |
| 6107 | 6114 |
| 6108 // Copies ASCII characters to the given fixed array looking up | 6115 // Copies ASCII characters to the given fixed array looking up |
| 6109 // one-char strings in the cache. Gives up on the first char that is | 6116 // one-char strings in the cache. Gives up on the first char that is |
| 6110 // not in the cache and fills the remainder with smi zeros. Returns | 6117 // not in the cache and fills the remainder with smi zeros. Returns |
| 6111 // the length of the successfully copied prefix. | 6118 // the length of the successfully copied prefix. |
| 6112 static int CopyCachedAsciiCharsToArray(Heap* heap, | 6119 static int CopyCachedAsciiCharsToArray(Heap* heap, |
| 6113 const char* chars, | 6120 const uint8_t* chars, |
| 6114 FixedArray* elements, | 6121 FixedArray* elements, |
| 6115 int length) { | 6122 int length) { |
| 6116 AssertNoAllocation no_gc; | 6123 AssertNoAllocation no_gc; |
| 6117 FixedArray* ascii_cache = heap->single_character_string_cache(); | 6124 FixedArray* ascii_cache = heap->single_character_string_cache(); |
| 6118 Object* undefined = heap->undefined_value(); | 6125 Object* undefined = heap->undefined_value(); |
| 6119 int i; | 6126 int i; |
| 6120 WriteBarrierMode mode = elements->GetWriteBarrierMode(no_gc); | 6127 WriteBarrierMode mode = elements->GetWriteBarrierMode(no_gc); |
| 6121 for (i = 0; i < length; ++i) { | 6128 for (i = 0; i < length; ++i) { |
| 6122 Object* value = ascii_cache->get(chars[i]); | 6129 Object* value = ascii_cache->get(chars[i]); |
| 6123 if (value == undefined) break; | 6130 if (value == undefined) break; |
| (...skipping 30 matching lines...) Expand all Loading... |
| 6154 if (s->IsFlat() && s->IsOneByteRepresentation()) { | 6161 if (s->IsFlat() && s->IsOneByteRepresentation()) { |
| 6155 // Try using cached chars where possible. | 6162 // Try using cached chars where possible. |
| 6156 Object* obj; | 6163 Object* obj; |
| 6157 { MaybeObject* maybe_obj = | 6164 { MaybeObject* maybe_obj = |
| 6158 isolate->heap()->AllocateUninitializedFixedArray(length); | 6165 isolate->heap()->AllocateUninitializedFixedArray(length); |
| 6159 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 6166 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 6160 } | 6167 } |
| 6161 elements = Handle<FixedArray>(FixedArray::cast(obj), isolate); | 6168 elements = Handle<FixedArray>(FixedArray::cast(obj), isolate); |
| 6162 String::FlatContent content = s->GetFlatContent(); | 6169 String::FlatContent content = s->GetFlatContent(); |
| 6163 if (content.IsAscii()) { | 6170 if (content.IsAscii()) { |
| 6164 Vector<const char> chars = content.ToAsciiVector(); | 6171 Vector<const uint8_t> chars = content.ToOneByteVector(); |
| 6165 // Note, this will initialize all elements (not only the prefix) | 6172 // Note, this will initialize all elements (not only the prefix) |
| 6166 // to prevent GC from seeing partially initialized array. | 6173 // to prevent GC from seeing partially initialized array. |
| 6167 position = CopyCachedAsciiCharsToArray(isolate->heap(), | 6174 position = CopyCachedAsciiCharsToArray(isolate->heap(), |
| 6168 chars.start(), | 6175 chars.start(), |
| 6169 *elements, | 6176 *elements, |
| 6170 length); | 6177 length); |
| 6171 } else { | 6178 } else { |
| 6172 MemsetPointer(elements->data_start(), | 6179 MemsetPointer(elements->data_start(), |
| 6173 isolate->heap()->undefined_value(), | 6180 isolate->heap()->undefined_value(), |
| 6174 length); | 6181 length); |
| (...skipping 562 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6737 // Throw OutOfMemory exception for creating too large a string. | 6744 // Throw OutOfMemory exception for creating too large a string. |
| 6738 V8::FatalProcessOutOfMemory("Array join result too large."); | 6745 V8::FatalProcessOutOfMemory("Array join result too large."); |
| 6739 } | 6746 } |
| 6740 | 6747 |
| 6741 if (is_ascii) { | 6748 if (is_ascii) { |
| 6742 MaybeObject* result_allocation = | 6749 MaybeObject* result_allocation = |
| 6743 isolate->heap()->AllocateRawOneByteString(string_length); | 6750 isolate->heap()->AllocateRawOneByteString(string_length); |
| 6744 if (result_allocation->IsFailure()) return result_allocation; | 6751 if (result_allocation->IsFailure()) return result_allocation; |
| 6745 SeqOneByteString* result_string = | 6752 SeqOneByteString* result_string = |
| 6746 SeqOneByteString::cast(result_allocation->ToObjectUnchecked()); | 6753 SeqOneByteString::cast(result_allocation->ToObjectUnchecked()); |
| 6747 JoinSparseArrayWithSeparator<char>(elements, | 6754 JoinSparseArrayWithSeparator<uint8_t>(elements, |
| 6748 elements_length, | 6755 elements_length, |
| 6749 array_length, | 6756 array_length, |
| 6750 separator, | 6757 separator, |
| 6751 Vector<char>(result_string->GetChars(), | 6758 Vector<uint8_t>( |
| 6752 string_length)); | 6759 result_string->GetChars(), |
| 6760 string_length)); |
| 6753 return result_string; | 6761 return result_string; |
| 6754 } else { | 6762 } else { |
| 6755 MaybeObject* result_allocation = | 6763 MaybeObject* result_allocation = |
| 6756 isolate->heap()->AllocateRawTwoByteString(string_length); | 6764 isolate->heap()->AllocateRawTwoByteString(string_length); |
| 6757 if (result_allocation->IsFailure()) return result_allocation; | 6765 if (result_allocation->IsFailure()) return result_allocation; |
| 6758 SeqTwoByteString* result_string = | 6766 SeqTwoByteString* result_string = |
| 6759 SeqTwoByteString::cast(result_allocation->ToObjectUnchecked()); | 6767 SeqTwoByteString::cast(result_allocation->ToObjectUnchecked()); |
| 6760 JoinSparseArrayWithSeparator<uc16>(elements, | 6768 JoinSparseArrayWithSeparator<uc16>(elements, |
| 6761 elements_length, | 6769 elements_length, |
| 6762 array_length, | 6770 array_length, |
| (...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6990 if (y->length() < prefix_length) { | 6998 if (y->length() < prefix_length) { |
| 6991 prefix_length = y->length(); | 6999 prefix_length = y->length(); |
| 6992 equal_prefix_result = Smi::FromInt(GREATER); | 7000 equal_prefix_result = Smi::FromInt(GREATER); |
| 6993 } else if (y->length() > prefix_length) { | 7001 } else if (y->length() > prefix_length) { |
| 6994 equal_prefix_result = Smi::FromInt(LESS); | 7002 equal_prefix_result = Smi::FromInt(LESS); |
| 6995 } | 7003 } |
| 6996 int r; | 7004 int r; |
| 6997 String::FlatContent x_content = x->GetFlatContent(); | 7005 String::FlatContent x_content = x->GetFlatContent(); |
| 6998 String::FlatContent y_content = y->GetFlatContent(); | 7006 String::FlatContent y_content = y->GetFlatContent(); |
| 6999 if (x_content.IsAscii()) { | 7007 if (x_content.IsAscii()) { |
| 7000 Vector<const char> x_chars = x_content.ToAsciiVector(); | 7008 Vector<const uint8_t> x_chars = x_content.ToOneByteVector(); |
| 7001 if (y_content.IsAscii()) { | 7009 if (y_content.IsAscii()) { |
| 7002 Vector<const char> y_chars = y_content.ToAsciiVector(); | 7010 Vector<const uint8_t> y_chars = y_content.ToOneByteVector(); |
| 7003 r = CompareChars(x_chars.start(), y_chars.start(), prefix_length); | 7011 r = CompareChars(x_chars.start(), y_chars.start(), prefix_length); |
| 7004 } else { | 7012 } else { |
| 7005 Vector<const uc16> y_chars = y_content.ToUC16Vector(); | 7013 Vector<const uc16> y_chars = y_content.ToUC16Vector(); |
| 7006 r = CompareChars(x_chars.start(), y_chars.start(), prefix_length); | 7014 r = CompareChars(x_chars.start(), y_chars.start(), prefix_length); |
| 7007 } | 7015 } |
| 7008 } else { | 7016 } else { |
| 7009 Vector<const uc16> x_chars = x_content.ToUC16Vector(); | 7017 Vector<const uc16> x_chars = x_content.ToUC16Vector(); |
| 7010 if (y_content.IsAscii()) { | 7018 if (y_content.IsAscii()) { |
| 7011 Vector<const char> y_chars = y_content.ToAsciiVector(); | 7019 Vector<const uint8_t> y_chars = y_content.ToOneByteVector(); |
| 7012 r = CompareChars(x_chars.start(), y_chars.start(), prefix_length); | 7020 r = CompareChars(x_chars.start(), y_chars.start(), prefix_length); |
| 7013 } else { | 7021 } else { |
| 7014 Vector<const uc16> y_chars = y_content.ToUC16Vector(); | 7022 Vector<const uc16> y_chars = y_content.ToUC16Vector(); |
| 7015 r = CompareChars(x_chars.start(), y_chars.start(), prefix_length); | 7023 r = CompareChars(x_chars.start(), y_chars.start(), prefix_length); |
| 7016 } | 7024 } |
| 7017 } | 7025 } |
| 7018 Object* result; | 7026 Object* result; |
| 7019 if (r == 0) { | 7027 if (r == 0) { |
| 7020 result = equal_prefix_result; | 7028 result = equal_prefix_result; |
| 7021 } else { | 7029 } else { |
| (...skipping 1929 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8951 if (maybe_result_array->IsFailure()) return maybe_result_array; | 8959 if (maybe_result_array->IsFailure()) return maybe_result_array; |
| 8952 RUNTIME_ASSERT(output->HasFastObjectElements()); | 8960 RUNTIME_ASSERT(output->HasFastObjectElements()); |
| 8953 | 8961 |
| 8954 AssertNoAllocation no_allocation; | 8962 AssertNoAllocation no_allocation; |
| 8955 | 8963 |
| 8956 FixedArray* output_array = FixedArray::cast(output->elements()); | 8964 FixedArray* output_array = FixedArray::cast(output->elements()); |
| 8957 RUNTIME_ASSERT(output_array->length() >= DateParser::OUTPUT_SIZE); | 8965 RUNTIME_ASSERT(output_array->length() >= DateParser::OUTPUT_SIZE); |
| 8958 bool result; | 8966 bool result; |
| 8959 String::FlatContent str_content = str->GetFlatContent(); | 8967 String::FlatContent str_content = str->GetFlatContent(); |
| 8960 if (str_content.IsAscii()) { | 8968 if (str_content.IsAscii()) { |
| 8961 result = DateParser::Parse(str_content.ToAsciiVector(), | 8969 result = DateParser::Parse(str_content.ToOneByteVector(), |
| 8962 output_array, | 8970 output_array, |
| 8963 isolate->unicode_cache()); | 8971 isolate->unicode_cache()); |
| 8964 } else { | 8972 } else { |
| 8965 ASSERT(str_content.IsTwoByte()); | 8973 ASSERT(str_content.IsTwoByte()); |
| 8966 result = DateParser::Parse(str_content.ToUC16Vector(), | 8974 result = DateParser::Parse(str_content.ToUC16Vector(), |
| 8967 output_array, | 8975 output_array, |
| 8968 isolate->unicode_cache()); | 8976 isolate->unicode_cache()); |
| 8969 } | 8977 } |
| 8970 | 8978 |
| 8971 if (result) { | 8979 if (result) { |
| (...skipping 4437 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 13409 } | 13417 } |
| 13410 #endif | 13418 #endif |
| 13411 | 13419 |
| 13412 | 13420 |
| 13413 RUNTIME_FUNCTION(MaybeObject*, Runtime_Log) { | 13421 RUNTIME_FUNCTION(MaybeObject*, Runtime_Log) { |
| 13414 ASSERT(args.length() == 2); | 13422 ASSERT(args.length() == 2); |
| 13415 CONVERT_ARG_CHECKED(String, format, 0); | 13423 CONVERT_ARG_CHECKED(String, format, 0); |
| 13416 CONVERT_ARG_CHECKED(JSArray, elms, 1); | 13424 CONVERT_ARG_CHECKED(JSArray, elms, 1); |
| 13417 String::FlatContent format_content = format->GetFlatContent(); | 13425 String::FlatContent format_content = format->GetFlatContent(); |
| 13418 RUNTIME_ASSERT(format_content.IsAscii()); | 13426 RUNTIME_ASSERT(format_content.IsAscii()); |
| 13419 Vector<const char> chars = format_content.ToAsciiVector(); | 13427 Vector<const uint8_t> chars = format_content.ToOneByteVector(); |
| 13420 LOGGER->LogRuntime(chars, elms); | 13428 LOGGER->LogRuntime(Vector<const char>::cast(chars), elms); |
| 13421 return isolate->heap()->undefined_value(); | 13429 return isolate->heap()->undefined_value(); |
| 13422 } | 13430 } |
| 13423 | 13431 |
| 13424 | 13432 |
| 13425 RUNTIME_FUNCTION(MaybeObject*, Runtime_IS_VAR) { | 13433 RUNTIME_FUNCTION(MaybeObject*, Runtime_IS_VAR) { |
| 13426 UNREACHABLE(); // implemented as macro in the parser | 13434 UNREACHABLE(); // implemented as macro in the parser |
| 13427 return NULL; | 13435 return NULL; |
| 13428 } | 13436 } |
| 13429 | 13437 |
| 13430 | 13438 |
| (...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 13633 // Handle last resort GC and make sure to allow future allocations | 13641 // Handle last resort GC and make sure to allow future allocations |
| 13634 // to grow the heap without causing GCs (if possible). | 13642 // to grow the heap without causing GCs (if possible). |
| 13635 isolate->counters()->gc_last_resort_from_js()->Increment(); | 13643 isolate->counters()->gc_last_resort_from_js()->Increment(); |
| 13636 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags, | 13644 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags, |
| 13637 "Runtime::PerformGC"); | 13645 "Runtime::PerformGC"); |
| 13638 } | 13646 } |
| 13639 } | 13647 } |
| 13640 | 13648 |
| 13641 | 13649 |
| 13642 } } // namespace v8::internal | 13650 } } // namespace v8::internal |
| OLD | NEW |