OLD | NEW |
1 // Copyright 2006-2009 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2009 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 2590 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2601 } | 2601 } |
2602 | 2602 |
2603 int end = str1_length < str2_length ? str1_length : str2_length; | 2603 int end = str1_length < str2_length ? str1_length : str2_length; |
2604 | 2604 |
2605 // No need to flatten if we are going to find the answer on the first | 2605 // No need to flatten if we are going to find the answer on the first |
2606 // character. At this point we know there is at least one character | 2606 // character. At this point we know there is at least one character |
2607 // in each string, due to the trivial case handling above. | 2607 // in each string, due to the trivial case handling above. |
2608 int d = str1->Get(0) - str2->Get(0); | 2608 int d = str1->Get(0) - str2->Get(0); |
2609 if (d != 0) return Smi::FromInt(d); | 2609 if (d != 0) return Smi::FromInt(d); |
2610 | 2610 |
2611 str1->TryFlattenIfNotFlat(); | 2611 str1->TryFlatten(); |
2612 str2->TryFlattenIfNotFlat(); | 2612 str2->TryFlatten(); |
2613 | 2613 |
2614 static StringInputBuffer buf1; | 2614 static StringInputBuffer buf1; |
2615 static StringInputBuffer buf2; | 2615 static StringInputBuffer buf2; |
2616 | 2616 |
2617 buf1.Reset(str1); | 2617 buf1.Reset(str1); |
2618 buf2.Reset(str2); | 2618 buf2.Reset(str2); |
2619 | 2619 |
2620 for (int i = 0; i < end; i++) { | 2620 for (int i = 0; i < end; i++) { |
2621 uint16_t char1 = buf1.GetNext(); | 2621 uint16_t char1 = buf1.GetNext(); |
2622 uint16_t char2 = buf2.GetNext(); | 2622 uint16_t char2 = buf2.GetNext(); |
(...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2811 Object* res = Heap::AllocateStringFromAscii(CStrVector(str)); | 2811 Object* res = Heap::AllocateStringFromAscii(CStrVector(str)); |
2812 DeleteArray(str); | 2812 DeleteArray(str); |
2813 return res; | 2813 return res; |
2814 } | 2814 } |
2815 | 2815 |
2816 | 2816 |
2817 // Returns a single character string where first character equals | 2817 // Returns a single character string where first character equals |
2818 // string->Get(index). | 2818 // string->Get(index). |
2819 static Handle<Object> GetCharAt(Handle<String> string, uint32_t index) { | 2819 static Handle<Object> GetCharAt(Handle<String> string, uint32_t index) { |
2820 if (index < static_cast<uint32_t>(string->length())) { | 2820 if (index < static_cast<uint32_t>(string->length())) { |
2821 string->TryFlattenIfNotFlat(); | 2821 string->TryFlatten(); |
2822 return LookupSingleCharacterStringFromCode( | 2822 return LookupSingleCharacterStringFromCode( |
2823 string->Get(index)); | 2823 string->Get(index)); |
2824 } | 2824 } |
2825 return Execution::CharAt(string, index); | 2825 return Execution::CharAt(string, index); |
2826 } | 2826 } |
2827 | 2827 |
2828 | 2828 |
2829 Object* Runtime::GetElementOrCharAt(Handle<Object> object, uint32_t index) { | 2829 Object* Runtime::GetElementOrCharAt(Handle<Object> object, uint32_t index) { |
2830 // Handle [] indexing on Strings | 2830 // Handle [] indexing on Strings |
2831 if (object->IsString()) { | 2831 if (object->IsString()) { |
(...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3065 if (result.is_null()) return Failure::Exception(); | 3065 if (result.is_null()) return Failure::Exception(); |
3066 return *value; | 3066 return *value; |
3067 } | 3067 } |
3068 | 3068 |
3069 if (key->IsString()) { | 3069 if (key->IsString()) { |
3070 Handle<Object> result; | 3070 Handle<Object> result; |
3071 if (Handle<String>::cast(key)->AsArrayIndex(&index)) { | 3071 if (Handle<String>::cast(key)->AsArrayIndex(&index)) { |
3072 result = SetElement(js_object, index, value); | 3072 result = SetElement(js_object, index, value); |
3073 } else { | 3073 } else { |
3074 Handle<String> key_string = Handle<String>::cast(key); | 3074 Handle<String> key_string = Handle<String>::cast(key); |
3075 key_string->TryFlattenIfNotFlat(); | 3075 key_string->TryFlatten(); |
3076 result = SetProperty(js_object, key_string, value, attr); | 3076 result = SetProperty(js_object, key_string, value, attr); |
3077 } | 3077 } |
3078 if (result.is_null()) return Failure::Exception(); | 3078 if (result.is_null()) return Failure::Exception(); |
3079 return *value; | 3079 return *value; |
3080 } | 3080 } |
3081 | 3081 |
3082 // Call-back into JavaScript to convert the key to a string. | 3082 // Call-back into JavaScript to convert the key to a string. |
3083 bool has_pending_exception = false; | 3083 bool has_pending_exception = false; |
3084 Handle<Object> converted = Execution::ToString(key, &has_pending_exception); | 3084 Handle<Object> converted = Execution::ToString(key, &has_pending_exception); |
3085 if (has_pending_exception) return Failure::Exception(); | 3085 if (has_pending_exception) return Failure::Exception(); |
(...skipping 28 matching lines...) Expand all Loading... |
3114 } | 3114 } |
3115 | 3115 |
3116 return js_object->SetElement(index, *value); | 3116 return js_object->SetElement(index, *value); |
3117 } | 3117 } |
3118 | 3118 |
3119 if (key->IsString()) { | 3119 if (key->IsString()) { |
3120 if (Handle<String>::cast(key)->AsArrayIndex(&index)) { | 3120 if (Handle<String>::cast(key)->AsArrayIndex(&index)) { |
3121 return js_object->SetElement(index, *value); | 3121 return js_object->SetElement(index, *value); |
3122 } else { | 3122 } else { |
3123 Handle<String> key_string = Handle<String>::cast(key); | 3123 Handle<String> key_string = Handle<String>::cast(key); |
3124 key_string->TryFlattenIfNotFlat(); | 3124 key_string->TryFlatten(); |
3125 return js_object->IgnoreAttributesAndSetLocalProperty(*key_string, | 3125 return js_object->IgnoreAttributesAndSetLocalProperty(*key_string, |
3126 *value, | 3126 *value, |
3127 attr); | 3127 attr); |
3128 } | 3128 } |
3129 } | 3129 } |
3130 | 3130 |
3131 // Call-back into JavaScript to convert the key to a string. | 3131 // Call-back into JavaScript to convert the key to a string. |
3132 bool has_pending_exception = false; | 3132 bool has_pending_exception = false; |
3133 Handle<Object> converted = Execution::ToString(key, &has_pending_exception); | 3133 Handle<Object> converted = Execution::ToString(key, &has_pending_exception); |
3134 if (has_pending_exception) return Failure::Exception(); | 3134 if (has_pending_exception) return Failure::Exception(); |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3166 if (key->IsString()) { | 3166 if (key->IsString()) { |
3167 key_string = Handle<String>::cast(key); | 3167 key_string = Handle<String>::cast(key); |
3168 } else { | 3168 } else { |
3169 // Call-back into JavaScript to convert the key to a string. | 3169 // Call-back into JavaScript to convert the key to a string. |
3170 bool has_pending_exception = false; | 3170 bool has_pending_exception = false; |
3171 Handle<Object> converted = Execution::ToString(key, &has_pending_exception); | 3171 Handle<Object> converted = Execution::ToString(key, &has_pending_exception); |
3172 if (has_pending_exception) return Failure::Exception(); | 3172 if (has_pending_exception) return Failure::Exception(); |
3173 key_string = Handle<String>::cast(converted); | 3173 key_string = Handle<String>::cast(converted); |
3174 } | 3174 } |
3175 | 3175 |
3176 key_string->TryFlattenIfNotFlat(); | 3176 key_string->TryFlatten(); |
3177 return js_object->DeleteProperty(*key_string, JSObject::FORCE_DELETION); | 3177 return js_object->DeleteProperty(*key_string, JSObject::FORCE_DELETION); |
3178 } | 3178 } |
3179 | 3179 |
3180 | 3180 |
3181 static Object* Runtime_SetProperty(Arguments args) { | 3181 static Object* Runtime_SetProperty(Arguments args) { |
3182 NoHandleAllocation ha; | 3182 NoHandleAllocation ha; |
3183 RUNTIME_ASSERT(args.length() == 3 || args.length() == 4); | 3183 RUNTIME_ASSERT(args.length() == 3 || args.length() == 4); |
3184 | 3184 |
3185 Handle<Object> object = args.at<Object>(0); | 3185 Handle<Object> object = args.at<Object>(0); |
3186 Handle<Object> key = args.at<Object>(1); | 3186 Handle<Object> key = args.at<Object>(1); |
(...skipping 475 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3662 // host objects gives that it is okay to return "object" | 3662 // host objects gives that it is okay to return "object" |
3663 return Heap::object_symbol(); | 3663 return Heap::object_symbol(); |
3664 } | 3664 } |
3665 } | 3665 } |
3666 | 3666 |
3667 | 3667 |
3668 static Object* Runtime_StringToNumber(Arguments args) { | 3668 static Object* Runtime_StringToNumber(Arguments args) { |
3669 NoHandleAllocation ha; | 3669 NoHandleAllocation ha; |
3670 ASSERT(args.length() == 1); | 3670 ASSERT(args.length() == 1); |
3671 CONVERT_CHECKED(String, subject, args[0]); | 3671 CONVERT_CHECKED(String, subject, args[0]); |
3672 subject->TryFlattenIfNotFlat(); | 3672 subject->TryFlatten(); |
3673 return Heap::NumberFromDouble(StringToDouble(subject, ALLOW_HEX)); | 3673 return Heap::NumberFromDouble(StringToDouble(subject, ALLOW_HEX)); |
3674 } | 3674 } |
3675 | 3675 |
3676 | 3676 |
3677 static Object* Runtime_StringFromCharCodeArray(Arguments args) { | 3677 static Object* Runtime_StringFromCharCodeArray(Arguments args) { |
3678 NoHandleAllocation ha; | 3678 NoHandleAllocation ha; |
3679 ASSERT(args.length() == 1); | 3679 ASSERT(args.length() == 1); |
3680 | 3680 |
3681 CONVERT_CHECKED(JSArray, codes, args[0]); | 3681 CONVERT_CHECKED(JSArray, codes, args[0]); |
3682 int length = Smi::cast(codes->length())->value(); | 3682 int length = Smi::cast(codes->length())->value(); |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3744 return kNotEscaped[character] != 0; | 3744 return kNotEscaped[character] != 0; |
3745 } | 3745 } |
3746 | 3746 |
3747 | 3747 |
3748 static Object* Runtime_URIEscape(Arguments args) { | 3748 static Object* Runtime_URIEscape(Arguments args) { |
3749 const char hex_chars[] = "0123456789ABCDEF"; | 3749 const char hex_chars[] = "0123456789ABCDEF"; |
3750 NoHandleAllocation ha; | 3750 NoHandleAllocation ha; |
3751 ASSERT(args.length() == 1); | 3751 ASSERT(args.length() == 1); |
3752 CONVERT_CHECKED(String, source, args[0]); | 3752 CONVERT_CHECKED(String, source, args[0]); |
3753 | 3753 |
3754 source->TryFlattenIfNotFlat(); | 3754 source->TryFlatten(); |
3755 | 3755 |
3756 int escaped_length = 0; | 3756 int escaped_length = 0; |
3757 int length = source->length(); | 3757 int length = source->length(); |
3758 { | 3758 { |
3759 Access<StringInputBuffer> buffer(&runtime_string_input_buffer); | 3759 Access<StringInputBuffer> buffer(&runtime_string_input_buffer); |
3760 buffer->Reset(source); | 3760 buffer->Reset(source); |
3761 while (buffer->has_more()) { | 3761 while (buffer->has_more()) { |
3762 uint16_t character = buffer->GetNext(); | 3762 uint16_t character = buffer->GetNext(); |
3763 if (character >= 256) { | 3763 if (character >= 256) { |
3764 escaped_length += 6; | 3764 escaped_length += 6; |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3857 return character; | 3857 return character; |
3858 } | 3858 } |
3859 } | 3859 } |
3860 | 3860 |
3861 | 3861 |
3862 static Object* Runtime_URIUnescape(Arguments args) { | 3862 static Object* Runtime_URIUnescape(Arguments args) { |
3863 NoHandleAllocation ha; | 3863 NoHandleAllocation ha; |
3864 ASSERT(args.length() == 1); | 3864 ASSERT(args.length() == 1); |
3865 CONVERT_CHECKED(String, source, args[0]); | 3865 CONVERT_CHECKED(String, source, args[0]); |
3866 | 3866 |
3867 source->TryFlattenIfNotFlat(); | 3867 source->TryFlatten(); |
3868 | 3868 |
3869 bool ascii = true; | 3869 bool ascii = true; |
3870 int length = source->length(); | 3870 int length = source->length(); |
3871 | 3871 |
3872 int unescaped_length = 0; | 3872 int unescaped_length = 0; |
3873 for (int i = 0; i < length; unescaped_length++) { | 3873 for (int i = 0; i < length; unescaped_length++) { |
3874 int step; | 3874 int step; |
3875 if (Unescape(source, i, length, &step) > String::kMaxAsciiCharCode) { | 3875 if (Unescape(source, i, length, &step) > String::kMaxAsciiCharCode) { |
3876 ascii = false; | 3876 ascii = false; |
3877 } | 3877 } |
(...skipping 19 matching lines...) Expand all Loading... |
3897 return destination; | 3897 return destination; |
3898 } | 3898 } |
3899 | 3899 |
3900 | 3900 |
3901 static Object* Runtime_StringParseInt(Arguments args) { | 3901 static Object* Runtime_StringParseInt(Arguments args) { |
3902 NoHandleAllocation ha; | 3902 NoHandleAllocation ha; |
3903 | 3903 |
3904 CONVERT_CHECKED(String, s, args[0]); | 3904 CONVERT_CHECKED(String, s, args[0]); |
3905 CONVERT_SMI_CHECKED(radix, args[1]); | 3905 CONVERT_SMI_CHECKED(radix, args[1]); |
3906 | 3906 |
3907 s->TryFlattenIfNotFlat(); | 3907 s->TryFlatten(); |
3908 | 3908 |
3909 int len = s->length(); | 3909 int len = s->length(); |
3910 int i; | 3910 int i; |
3911 | 3911 |
3912 // Skip leading white space. | 3912 // Skip leading white space. |
3913 for (i = 0; i < len && Scanner::kIsWhiteSpace.get(s->Get(i)); i++) ; | 3913 for (i = 0; i < len && Scanner::kIsWhiteSpace.get(s->Get(i)); i++) ; |
3914 if (i == len) return Heap::nan_value(); | 3914 if (i == len) return Heap::nan_value(); |
3915 | 3915 |
3916 // Compute the sign (default to +). | 3916 // Compute the sign (default to +). |
3917 int sign = 1; | 3917 int sign = 1; |
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4067 } | 4067 } |
4068 } | 4068 } |
4069 | 4069 |
4070 | 4070 |
4071 template <class Converter> | 4071 template <class Converter> |
4072 static Object* ConvertCase(Arguments args, | 4072 static Object* ConvertCase(Arguments args, |
4073 unibrow::Mapping<Converter, 128>* mapping) { | 4073 unibrow::Mapping<Converter, 128>* mapping) { |
4074 NoHandleAllocation ha; | 4074 NoHandleAllocation ha; |
4075 | 4075 |
4076 CONVERT_CHECKED(String, s, args[0]); | 4076 CONVERT_CHECKED(String, s, args[0]); |
4077 s->TryFlattenIfNotFlat(); | 4077 s->TryFlatten(); |
4078 | 4078 |
4079 int input_string_length = s->length(); | 4079 int input_string_length = s->length(); |
4080 // Assume that the string is not empty; we need this assumption later | 4080 // Assume that the string is not empty; we need this assumption later |
4081 if (input_string_length == 0) return s; | 4081 if (input_string_length == 0) return s; |
4082 int length = input_string_length; | 4082 int length = input_string_length; |
4083 | 4083 |
4084 Object* answer = ConvertCaseHelper(s, length, length, mapping); | 4084 Object* answer = ConvertCaseHelper(s, length, length, mapping); |
4085 if (answer->IsSmi()) { | 4085 if (answer->IsSmi()) { |
4086 // Retry with correct length. | 4086 // Retry with correct length. |
4087 answer = ConvertCaseHelper(s, Smi::cast(answer)->value(), length, mapping); | 4087 answer = ConvertCaseHelper(s, Smi::cast(answer)->value(), length, mapping); |
(...skipping 16 matching lines...) Expand all Loading... |
4104 } | 4104 } |
4105 | 4105 |
4106 static Object* Runtime_StringTrim(Arguments args) { | 4106 static Object* Runtime_StringTrim(Arguments args) { |
4107 NoHandleAllocation ha; | 4107 NoHandleAllocation ha; |
4108 ASSERT(args.length() == 3); | 4108 ASSERT(args.length() == 3); |
4109 | 4109 |
4110 CONVERT_CHECKED(String, s, args[0]); | 4110 CONVERT_CHECKED(String, s, args[0]); |
4111 CONVERT_BOOLEAN_CHECKED(trimLeft, args[1]); | 4111 CONVERT_BOOLEAN_CHECKED(trimLeft, args[1]); |
4112 CONVERT_BOOLEAN_CHECKED(trimRight, args[2]); | 4112 CONVERT_BOOLEAN_CHECKED(trimRight, args[2]); |
4113 | 4113 |
4114 s->TryFlattenIfNotFlat(); | 4114 s->TryFlatten(); |
4115 int length = s->length(); | 4115 int length = s->length(); |
4116 | 4116 |
4117 int left = 0; | 4117 int left = 0; |
4118 if (trimLeft) { | 4118 if (trimLeft) { |
4119 while (left < length && IsTrimWhiteSpace(s->Get(left))) { | 4119 while (left < length && IsTrimWhiteSpace(s->Get(left))) { |
4120 left++; | 4120 left++; |
4121 } | 4121 } |
4122 } | 4122 } |
4123 | 4123 |
4124 int right = length; | 4124 int right = length; |
(...skipping 547 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4672 if (x->length() == 0) return Smi::FromInt(EQUAL); | 4672 if (x->length() == 0) return Smi::FromInt(EQUAL); |
4673 return Smi::FromInt(GREATER); | 4673 return Smi::FromInt(GREATER); |
4674 } else if (x->length() == 0) { | 4674 } else if (x->length() == 0) { |
4675 return Smi::FromInt(LESS); | 4675 return Smi::FromInt(LESS); |
4676 } | 4676 } |
4677 | 4677 |
4678 int d = x->Get(0) - y->Get(0); | 4678 int d = x->Get(0) - y->Get(0); |
4679 if (d < 0) return Smi::FromInt(LESS); | 4679 if (d < 0) return Smi::FromInt(LESS); |
4680 else if (d > 0) return Smi::FromInt(GREATER); | 4680 else if (d > 0) return Smi::FromInt(GREATER); |
4681 | 4681 |
4682 x->TryFlattenIfNotFlat(); | 4682 x->TryFlatten(); |
4683 y->TryFlattenIfNotFlat(); | 4683 y->TryFlatten(); |
4684 | 4684 |
4685 return (x->IsFlat() && y->IsFlat()) ? FlatStringCompare(x, y) | 4685 return (x->IsFlat() && y->IsFlat()) ? FlatStringCompare(x, y) |
4686 : StringInputBufferCompare(x, y); | 4686 : StringInputBufferCompare(x, y); |
4687 } | 4687 } |
4688 | 4688 |
4689 | 4689 |
4690 static Object* Runtime_Math_abs(Arguments args) { | 4690 static Object* Runtime_Math_abs(Arguments args) { |
4691 NoHandleAllocation ha; | 4691 NoHandleAllocation ha; |
4692 ASSERT(args.length() == 1); | 4692 ASSERT(args.length() == 1); |
4693 Counters::math_abs.Increment(); | 4693 Counters::math_abs.Increment(); |
(...skipping 3653 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8347 } else { | 8347 } else { |
8348 // Handle last resort GC and make sure to allow future allocations | 8348 // Handle last resort GC and make sure to allow future allocations |
8349 // to grow the heap without causing GCs (if possible). | 8349 // to grow the heap without causing GCs (if possible). |
8350 Counters::gc_last_resort_from_js.Increment(); | 8350 Counters::gc_last_resort_from_js.Increment(); |
8351 Heap::CollectAllGarbage(false); | 8351 Heap::CollectAllGarbage(false); |
8352 } | 8352 } |
8353 } | 8353 } |
8354 | 8354 |
8355 | 8355 |
8356 } } // namespace v8::internal | 8356 } } // namespace v8::internal |
OLD | NEW |