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