| OLD | NEW |
| 1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/runtime/runtime-utils.h" | 5 #include "src/runtime/runtime-utils.h" |
| 6 | 6 |
| 7 #include "src/arguments.h" | 7 #include "src/arguments.h" |
| 8 #include "src/regexp/jsregexp-inl.h" | 8 #include "src/regexp/jsregexp-inl.h" |
| 9 #include "src/string-builder.h" | 9 #include "src/string-builder.h" |
| 10 #include "src/string-case.h" | 10 #include "src/string-case.h" |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 54 String); | 54 String); |
| 55 Handle<String> second = | 55 Handle<String> second = |
| 56 isolate->factory()->NewSubString(subject, index + 1, subject->length()); | 56 isolate->factory()->NewSubString(subject, index + 1, subject->length()); |
| 57 return isolate->factory()->NewConsString(cons1, second); | 57 return isolate->factory()->NewConsString(cons1, second); |
| 58 } | 58 } |
| 59 } | 59 } |
| 60 | 60 |
| 61 | 61 |
| 62 RUNTIME_FUNCTION(Runtime_StringReplaceOneCharWithString) { | 62 RUNTIME_FUNCTION(Runtime_StringReplaceOneCharWithString) { |
| 63 HandleScope scope(isolate); | 63 HandleScope scope(isolate); |
| 64 DCHECK(args.length() == 3); | 64 DCHECK_EQ(3, args.length()); |
| 65 CONVERT_ARG_HANDLE_CHECKED(String, subject, 0); | 65 CONVERT_ARG_HANDLE_CHECKED(String, subject, 0); |
| 66 CONVERT_ARG_HANDLE_CHECKED(String, search, 1); | 66 CONVERT_ARG_HANDLE_CHECKED(String, search, 1); |
| 67 CONVERT_ARG_HANDLE_CHECKED(String, replace, 2); | 67 CONVERT_ARG_HANDLE_CHECKED(String, replace, 2); |
| 68 | 68 |
| 69 // If the cons string tree is too deep, we simply abort the recursion and | 69 // If the cons string tree is too deep, we simply abort the recursion and |
| 70 // retry with a flattened subject string. | 70 // retry with a flattened subject string. |
| 71 const int kRecursionLimit = 0x1000; | 71 const int kRecursionLimit = 0x1000; |
| 72 bool found = false; | 72 bool found = false; |
| 73 Handle<String> result; | 73 Handle<String> result; |
| 74 if (StringReplaceOneCharWithString(isolate, subject, search, replace, &found, | 74 if (StringReplaceOneCharWithString(isolate, subject, search, replace, &found, |
| 75 kRecursionLimit).ToHandle(&result)) { | 75 kRecursionLimit).ToHandle(&result)) { |
| 76 return *result; | 76 return *result; |
| 77 } | 77 } |
| 78 if (isolate->has_pending_exception()) return isolate->heap()->exception(); | 78 if (isolate->has_pending_exception()) return isolate->heap()->exception(); |
| 79 | 79 |
| 80 subject = String::Flatten(subject); | 80 subject = String::Flatten(subject); |
| 81 if (StringReplaceOneCharWithString(isolate, subject, search, replace, &found, | 81 if (StringReplaceOneCharWithString(isolate, subject, search, replace, &found, |
| 82 kRecursionLimit).ToHandle(&result)) { | 82 kRecursionLimit).ToHandle(&result)) { |
| 83 return *result; | 83 return *result; |
| 84 } | 84 } |
| 85 if (isolate->has_pending_exception()) return isolate->heap()->exception(); | 85 if (isolate->has_pending_exception()) return isolate->heap()->exception(); |
| 86 // In case of empty handle and no pending exception we have stack overflow. | 86 // In case of empty handle and no pending exception we have stack overflow. |
| 87 return isolate->StackOverflow(); | 87 return isolate->StackOverflow(); |
| 88 } | 88 } |
| 89 | 89 |
| 90 // ES6 #sec-string.prototype.indexof | 90 // ES6 #sec-string.prototype.indexof |
| 91 // String.prototype.indexOf(searchString [, position]) | 91 // String.prototype.indexOf(searchString [, position]) |
| 92 RUNTIME_FUNCTION(Runtime_StringIndexOf) { | 92 RUNTIME_FUNCTION(Runtime_StringIndexOf) { |
| 93 HandleScope scope(isolate); | 93 HandleScope scope(isolate); |
| 94 DCHECK(args.length() == 3); | 94 DCHECK_EQ(3, args.length()); |
| 95 return String::IndexOf(isolate, args.at(0), args.at(1), args.at(2)); | 95 return String::IndexOf(isolate, args.at(0), args.at(1), args.at(2)); |
| 96 } | 96 } |
| 97 | 97 |
| 98 // ES6 #sec-string.prototype.indexof | 98 // ES6 #sec-string.prototype.indexof |
| 99 // String.prototype.indexOf(searchString, position) | 99 // String.prototype.indexOf(searchString, position) |
| 100 // Fast version that assumes that does not perform conversions of the incoming | 100 // Fast version that assumes that does not perform conversions of the incoming |
| 101 // arguments. | 101 // arguments. |
| 102 RUNTIME_FUNCTION(Runtime_StringIndexOfUnchecked) { | 102 RUNTIME_FUNCTION(Runtime_StringIndexOfUnchecked) { |
| 103 HandleScope scope(isolate); | 103 HandleScope scope(isolate); |
| 104 DCHECK(args.length() == 3); | 104 DCHECK_EQ(3, args.length()); |
| 105 Handle<String> receiver_string = args.at<String>(0); | 105 Handle<String> receiver_string = args.at<String>(0); |
| 106 Handle<String> search_string = args.at<String>(1); | 106 Handle<String> search_string = args.at<String>(1); |
| 107 int index = std::min(std::max(args.smi_at(2), 0), receiver_string->length()); | 107 int index = std::min(std::max(args.smi_at(2), 0), receiver_string->length()); |
| 108 | 108 |
| 109 return Smi::FromInt(String::IndexOf(isolate, receiver_string, search_string, | 109 return Smi::FromInt(String::IndexOf(isolate, receiver_string, search_string, |
| 110 static_cast<uint32_t>(index))); | 110 static_cast<uint32_t>(index))); |
| 111 } | 111 } |
| 112 | 112 |
| 113 RUNTIME_FUNCTION(Runtime_StringLastIndexOf) { | 113 RUNTIME_FUNCTION(Runtime_StringLastIndexOf) { |
| 114 HandleScope handle_scope(isolate); | 114 HandleScope handle_scope(isolate); |
| 115 return String::LastIndexOf(isolate, args.at(0), args.at(1), | 115 return String::LastIndexOf(isolate, args.at(0), args.at(1), |
| 116 isolate->factory()->undefined_value()); | 116 isolate->factory()->undefined_value()); |
| 117 } | 117 } |
| 118 | 118 |
| 119 RUNTIME_FUNCTION(Runtime_SubString) { | 119 RUNTIME_FUNCTION(Runtime_SubString) { |
| 120 HandleScope scope(isolate); | 120 HandleScope scope(isolate); |
| 121 DCHECK(args.length() == 3); | 121 DCHECK_EQ(3, args.length()); |
| 122 | 122 |
| 123 CONVERT_ARG_HANDLE_CHECKED(String, string, 0); | 123 CONVERT_ARG_HANDLE_CHECKED(String, string, 0); |
| 124 int start, end; | 124 int start, end; |
| 125 // We have a fast integer-only case here to avoid a conversion to double in | 125 // We have a fast integer-only case here to avoid a conversion to double in |
| 126 // the common case where from and to are Smis. | 126 // the common case where from and to are Smis. |
| 127 if (args[1]->IsSmi() && args[2]->IsSmi()) { | 127 if (args[1]->IsSmi() && args[2]->IsSmi()) { |
| 128 CONVERT_SMI_ARG_CHECKED(from_number, 1); | 128 CONVERT_SMI_ARG_CHECKED(from_number, 1); |
| 129 CONVERT_SMI_ARG_CHECKED(to_number, 2); | 129 CONVERT_SMI_ARG_CHECKED(to_number, 2); |
| 130 start = from_number; | 130 start = from_number; |
| 131 end = to_number; | 131 end = to_number; |
| (...skipping 11 matching lines...) Expand all Loading... |
| 143 return isolate->ThrowIllegalOperation(); | 143 return isolate->ThrowIllegalOperation(); |
| 144 } | 144 } |
| 145 isolate->counters()->sub_string_runtime()->Increment(); | 145 isolate->counters()->sub_string_runtime()->Increment(); |
| 146 | 146 |
| 147 return *isolate->factory()->NewSubString(string, start, end); | 147 return *isolate->factory()->NewSubString(string, start, end); |
| 148 } | 148 } |
| 149 | 149 |
| 150 | 150 |
| 151 RUNTIME_FUNCTION(Runtime_StringAdd) { | 151 RUNTIME_FUNCTION(Runtime_StringAdd) { |
| 152 HandleScope scope(isolate); | 152 HandleScope scope(isolate); |
| 153 DCHECK(args.length() == 2); | 153 DCHECK_EQ(2, args.length()); |
| 154 CONVERT_ARG_HANDLE_CHECKED(Object, obj1, 0); | 154 CONVERT_ARG_HANDLE_CHECKED(Object, obj1, 0); |
| 155 CONVERT_ARG_HANDLE_CHECKED(Object, obj2, 1); | 155 CONVERT_ARG_HANDLE_CHECKED(Object, obj2, 1); |
| 156 isolate->counters()->string_add_runtime()->Increment(); | 156 isolate->counters()->string_add_runtime()->Increment(); |
| 157 MaybeHandle<String> maybe_str1(Object::ToString(isolate, obj1)); | 157 MaybeHandle<String> maybe_str1(Object::ToString(isolate, obj1)); |
| 158 MaybeHandle<String> maybe_str2(Object::ToString(isolate, obj2)); | 158 MaybeHandle<String> maybe_str2(Object::ToString(isolate, obj2)); |
| 159 Handle<String> str1; | 159 Handle<String> str1; |
| 160 Handle<String> str2; | 160 Handle<String> str2; |
| 161 maybe_str1.ToHandle(&str1); | 161 maybe_str1.ToHandle(&str1); |
| 162 maybe_str2.ToHandle(&str2); | 162 maybe_str2.ToHandle(&str2); |
| 163 RETURN_RESULT_OR_FAILURE(isolate, | 163 RETURN_RESULT_OR_FAILURE(isolate, |
| 164 isolate->factory()->NewConsString(str1, str2)); | 164 isolate->factory()->NewConsString(str1, str2)); |
| 165 } | 165 } |
| 166 | 166 |
| 167 | 167 |
| 168 RUNTIME_FUNCTION(Runtime_InternalizeString) { | 168 RUNTIME_FUNCTION(Runtime_InternalizeString) { |
| 169 HandleScope handles(isolate); | 169 HandleScope handles(isolate); |
| 170 DCHECK(args.length() == 1); | 170 DCHECK_EQ(1, args.length()); |
| 171 CONVERT_ARG_HANDLE_CHECKED(String, string, 0); | 171 CONVERT_ARG_HANDLE_CHECKED(String, string, 0); |
| 172 return *isolate->factory()->InternalizeString(string); | 172 return *isolate->factory()->InternalizeString(string); |
| 173 } | 173 } |
| 174 | 174 |
| 175 | 175 |
| 176 RUNTIME_FUNCTION(Runtime_StringCharCodeAtRT) { | 176 RUNTIME_FUNCTION(Runtime_StringCharCodeAtRT) { |
| 177 HandleScope handle_scope(isolate); | 177 HandleScope handle_scope(isolate); |
| 178 DCHECK(args.length() == 2); | 178 DCHECK_EQ(2, args.length()); |
| 179 | 179 |
| 180 CONVERT_ARG_HANDLE_CHECKED(String, subject, 0); | 180 CONVERT_ARG_HANDLE_CHECKED(String, subject, 0); |
| 181 CONVERT_NUMBER_CHECKED(uint32_t, i, Uint32, args[1]); | 181 CONVERT_NUMBER_CHECKED(uint32_t, i, Uint32, args[1]); |
| 182 | 182 |
| 183 // Flatten the string. If someone wants to get a char at an index | 183 // Flatten the string. If someone wants to get a char at an index |
| 184 // in a cons string, it is likely that more indices will be | 184 // in a cons string, it is likely that more indices will be |
| 185 // accessed. | 185 // accessed. |
| 186 subject = String::Flatten(subject); | 186 subject = String::Flatten(subject); |
| 187 | 187 |
| 188 if (i >= static_cast<uint32_t>(subject->length())) { | 188 if (i >= static_cast<uint32_t>(subject->length())) { |
| (...skipping 20 matching lines...) Expand all Loading... |
| 209 case ComparisonResult::kUndefined: | 209 case ComparisonResult::kUndefined: |
| 210 break; | 210 break; |
| 211 } | 211 } |
| 212 UNREACHABLE(); | 212 UNREACHABLE(); |
| 213 return Smi::kZero; | 213 return Smi::kZero; |
| 214 } | 214 } |
| 215 | 215 |
| 216 | 216 |
| 217 RUNTIME_FUNCTION(Runtime_StringBuilderConcat) { | 217 RUNTIME_FUNCTION(Runtime_StringBuilderConcat) { |
| 218 HandleScope scope(isolate); | 218 HandleScope scope(isolate); |
| 219 DCHECK(args.length() == 3); | 219 DCHECK_EQ(3, args.length()); |
| 220 CONVERT_ARG_HANDLE_CHECKED(JSArray, array, 0); | 220 CONVERT_ARG_HANDLE_CHECKED(JSArray, array, 0); |
| 221 int32_t array_length; | 221 int32_t array_length; |
| 222 if (!args[1]->ToInt32(&array_length)) { | 222 if (!args[1]->ToInt32(&array_length)) { |
| 223 THROW_NEW_ERROR_RETURN_FAILURE(isolate, NewInvalidStringLengthError()); | 223 THROW_NEW_ERROR_RETURN_FAILURE(isolate, NewInvalidStringLengthError()); |
| 224 } | 224 } |
| 225 CONVERT_ARG_HANDLE_CHECKED(String, special, 2); | 225 CONVERT_ARG_HANDLE_CHECKED(String, special, 2); |
| 226 | 226 |
| 227 size_t actual_array_length = 0; | 227 size_t actual_array_length = 0; |
| 228 CHECK(TryNumberToSize(array->length(), &actual_array_length)); | 228 CHECK(TryNumberToSize(array->length(), &actual_array_length)); |
| 229 CHECK(array_length >= 0); | 229 CHECK(array_length >= 0); |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 279 StringBuilderConcatHelper(*special, answer->GetChars(), | 279 StringBuilderConcatHelper(*special, answer->GetChars(), |
| 280 FixedArray::cast(array->elements()), | 280 FixedArray::cast(array->elements()), |
| 281 array_length); | 281 array_length); |
| 282 return *answer; | 282 return *answer; |
| 283 } | 283 } |
| 284 } | 284 } |
| 285 | 285 |
| 286 | 286 |
| 287 RUNTIME_FUNCTION(Runtime_StringBuilderJoin) { | 287 RUNTIME_FUNCTION(Runtime_StringBuilderJoin) { |
| 288 HandleScope scope(isolate); | 288 HandleScope scope(isolate); |
| 289 DCHECK(args.length() == 3); | 289 DCHECK_EQ(3, args.length()); |
| 290 CONVERT_ARG_HANDLE_CHECKED(JSArray, array, 0); | 290 CONVERT_ARG_HANDLE_CHECKED(JSArray, array, 0); |
| 291 int32_t array_length; | 291 int32_t array_length; |
| 292 if (!args[1]->ToInt32(&array_length)) { | 292 if (!args[1]->ToInt32(&array_length)) { |
| 293 THROW_NEW_ERROR_RETURN_FAILURE(isolate, NewInvalidStringLengthError()); | 293 THROW_NEW_ERROR_RETURN_FAILURE(isolate, NewInvalidStringLengthError()); |
| 294 } | 294 } |
| 295 CONVERT_ARG_HANDLE_CHECKED(String, separator, 2); | 295 CONVERT_ARG_HANDLE_CHECKED(String, separator, 2); |
| 296 CHECK(array->HasFastObjectElements()); | 296 CHECK(array->HasFastObjectElements()); |
| 297 CHECK(array_length >= 0); | 297 CHECK(array_length >= 0); |
| 298 | 298 |
| 299 Handle<FixedArray> fixed_array(FixedArray::cast(array->elements())); | 299 Handle<FixedArray> fixed_array(FixedArray::cast(array->elements())); |
| (...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 420 DCHECK(array_length <= 0x7fffffff); // Is int32_t. | 420 DCHECK(array_length <= 0x7fffffff); // Is int32_t. |
| 421 int repeat = last_array_index - previous_separator_position; | 421 int repeat = last_array_index - previous_separator_position; |
| 422 WriteRepeatToFlat<Char>(separator, buffer, cursor, repeat, separator_length); | 422 WriteRepeatToFlat<Char>(separator, buffer, cursor, repeat, separator_length); |
| 423 cursor += repeat * separator_length; | 423 cursor += repeat * separator_length; |
| 424 DCHECK(cursor <= buffer.length()); | 424 DCHECK(cursor <= buffer.length()); |
| 425 } | 425 } |
| 426 | 426 |
| 427 | 427 |
| 428 RUNTIME_FUNCTION(Runtime_SparseJoinWithSeparator) { | 428 RUNTIME_FUNCTION(Runtime_SparseJoinWithSeparator) { |
| 429 HandleScope scope(isolate); | 429 HandleScope scope(isolate); |
| 430 DCHECK(args.length() == 3); | 430 DCHECK_EQ(3, args.length()); |
| 431 CONVERT_ARG_HANDLE_CHECKED(JSArray, elements_array, 0); | 431 CONVERT_ARG_HANDLE_CHECKED(JSArray, elements_array, 0); |
| 432 CONVERT_NUMBER_CHECKED(uint32_t, array_length, Uint32, args[1]); | 432 CONVERT_NUMBER_CHECKED(uint32_t, array_length, Uint32, args[1]); |
| 433 CONVERT_ARG_HANDLE_CHECKED(String, separator, 2); | 433 CONVERT_ARG_HANDLE_CHECKED(String, separator, 2); |
| 434 // elements_array is fast-mode JSarray of alternating positions | 434 // elements_array is fast-mode JSarray of alternating positions |
| 435 // (increasing order) and strings. | 435 // (increasing order) and strings. |
| 436 CHECK(elements_array->HasFastSmiOrObjectElements()); | 436 CHECK(elements_array->HasFastSmiOrObjectElements()); |
| 437 // array_length is length of original array (used to add separators); | 437 // array_length is length of original array (used to add separators); |
| 438 // separator is string to put between elements. Assumed to be non-empty. | 438 // separator is string to put between elements. Assumed to be non-empty. |
| 439 CHECK(array_length > 0); | 439 CHECK(array_length > 0); |
| 440 | 440 |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 538 } | 538 } |
| 539 #endif | 539 #endif |
| 540 return i; | 540 return i; |
| 541 } | 541 } |
| 542 | 542 |
| 543 | 543 |
| 544 // Converts a String to JSArray. | 544 // Converts a String to JSArray. |
| 545 // For example, "foo" => ["f", "o", "o"]. | 545 // For example, "foo" => ["f", "o", "o"]. |
| 546 RUNTIME_FUNCTION(Runtime_StringToArray) { | 546 RUNTIME_FUNCTION(Runtime_StringToArray) { |
| 547 HandleScope scope(isolate); | 547 HandleScope scope(isolate); |
| 548 DCHECK(args.length() == 2); | 548 DCHECK_EQ(2, args.length()); |
| 549 CONVERT_ARG_HANDLE_CHECKED(String, s, 0); | 549 CONVERT_ARG_HANDLE_CHECKED(String, s, 0); |
| 550 CONVERT_NUMBER_CHECKED(uint32_t, limit, Uint32, args[1]); | 550 CONVERT_NUMBER_CHECKED(uint32_t, limit, Uint32, args[1]); |
| 551 | 551 |
| 552 s = String::Flatten(s); | 552 s = String::Flatten(s); |
| 553 const int length = static_cast<int>(Min<uint32_t>(s->length(), limit)); | 553 const int length = static_cast<int>(Min<uint32_t>(s->length(), limit)); |
| 554 | 554 |
| 555 Handle<FixedArray> elements; | 555 Handle<FixedArray> elements; |
| 556 int position = 0; | 556 int position = 0; |
| 557 if (s->IsFlat() && s->IsOneByteRepresentation()) { | 557 if (s->IsFlat() && s->IsOneByteRepresentation()) { |
| 558 // Try using cached chars where possible. | 558 // Try using cached chars where possible. |
| (...skipping 289 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 848 RUNTIME_FUNCTION(Runtime_StringNotEqual) { | 848 RUNTIME_FUNCTION(Runtime_StringNotEqual) { |
| 849 HandleScope handle_scope(isolate); | 849 HandleScope handle_scope(isolate); |
| 850 DCHECK_EQ(2, args.length()); | 850 DCHECK_EQ(2, args.length()); |
| 851 CONVERT_ARG_HANDLE_CHECKED(String, x, 0); | 851 CONVERT_ARG_HANDLE_CHECKED(String, x, 0); |
| 852 CONVERT_ARG_HANDLE_CHECKED(String, y, 1); | 852 CONVERT_ARG_HANDLE_CHECKED(String, y, 1); |
| 853 return isolate->heap()->ToBoolean(!String::Equals(x, y)); | 853 return isolate->heap()->ToBoolean(!String::Equals(x, y)); |
| 854 } | 854 } |
| 855 | 855 |
| 856 RUNTIME_FUNCTION(Runtime_FlattenString) { | 856 RUNTIME_FUNCTION(Runtime_FlattenString) { |
| 857 HandleScope scope(isolate); | 857 HandleScope scope(isolate); |
| 858 DCHECK(args.length() == 1); | 858 DCHECK_EQ(1, args.length()); |
| 859 CONVERT_ARG_HANDLE_CHECKED(String, str, 0); | 859 CONVERT_ARG_HANDLE_CHECKED(String, str, 0); |
| 860 return *String::Flatten(str); | 860 return *String::Flatten(str); |
| 861 } | 861 } |
| 862 | 862 |
| 863 | 863 |
| 864 RUNTIME_FUNCTION(Runtime_StringCharFromCode) { | 864 RUNTIME_FUNCTION(Runtime_StringCharFromCode) { |
| 865 HandleScope handlescope(isolate); | 865 HandleScope handlescope(isolate); |
| 866 DCHECK_EQ(1, args.length()); | 866 DCHECK_EQ(1, args.length()); |
| 867 if (args[0]->IsNumber()) { | 867 if (args[0]->IsNumber()) { |
| 868 CONVERT_NUMBER_CHECKED(uint32_t, code, Uint32, args[0]); | 868 CONVERT_NUMBER_CHECKED(uint32_t, code, Uint32, args[0]); |
| 869 code &= 0xffff; | 869 code &= 0xffff; |
| 870 return *isolate->factory()->LookupSingleCharacterStringFromCode(code); | 870 return *isolate->factory()->LookupSingleCharacterStringFromCode(code); |
| 871 } | 871 } |
| 872 return isolate->heap()->empty_string(); | 872 return isolate->heap()->empty_string(); |
| 873 } | 873 } |
| 874 | 874 |
| 875 RUNTIME_FUNCTION(Runtime_ExternalStringGetChar) { | 875 RUNTIME_FUNCTION(Runtime_ExternalStringGetChar) { |
| 876 SealHandleScope shs(isolate); | 876 SealHandleScope shs(isolate); |
| 877 DCHECK_EQ(2, args.length()); | 877 DCHECK_EQ(2, args.length()); |
| 878 CONVERT_ARG_CHECKED(ExternalString, string, 0); | 878 CONVERT_ARG_CHECKED(ExternalString, string, 0); |
| 879 CONVERT_INT32_ARG_CHECKED(index, 1); | 879 CONVERT_INT32_ARG_CHECKED(index, 1); |
| 880 return Smi::FromInt(string->Get(index)); | 880 return Smi::FromInt(string->Get(index)); |
| 881 } | 881 } |
| 882 | 882 |
| 883 RUNTIME_FUNCTION(Runtime_StringCharCodeAt) { | 883 RUNTIME_FUNCTION(Runtime_StringCharCodeAt) { |
| 884 SealHandleScope shs(isolate); | 884 SealHandleScope shs(isolate); |
| 885 DCHECK(args.length() == 2); | 885 DCHECK_EQ(2, args.length()); |
| 886 if (!args[0]->IsString()) return isolate->heap()->undefined_value(); | 886 if (!args[0]->IsString()) return isolate->heap()->undefined_value(); |
| 887 if (!args[1]->IsNumber()) return isolate->heap()->undefined_value(); | 887 if (!args[1]->IsNumber()) return isolate->heap()->undefined_value(); |
| 888 if (std::isinf(args.number_at(1))) return isolate->heap()->nan_value(); | 888 if (std::isinf(args.number_at(1))) return isolate->heap()->nan_value(); |
| 889 return __RT_impl_Runtime_StringCharCodeAtRT(args, isolate); | 889 return __RT_impl_Runtime_StringCharCodeAtRT(args, isolate); |
| 890 } | 890 } |
| 891 | 891 |
| 892 } // namespace internal | 892 } // namespace internal |
| 893 } // namespace v8 | 893 } // namespace v8 |
| OLD | NEW |