| 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 2443 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2454 | 2454 |
| 2455 class ReplacementStringBuilder { | 2455 class ReplacementStringBuilder { |
| 2456 public: | 2456 public: |
| 2457 ReplacementStringBuilder(Heap* heap, | 2457 ReplacementStringBuilder(Heap* heap, |
| 2458 Handle<String> subject, | 2458 Handle<String> subject, |
| 2459 int estimated_part_count) | 2459 int estimated_part_count) |
| 2460 : heap_(heap), | 2460 : heap_(heap), |
| 2461 array_builder_(heap->isolate(), estimated_part_count), | 2461 array_builder_(heap->isolate(), estimated_part_count), |
| 2462 subject_(subject), | 2462 subject_(subject), |
| 2463 character_count_(0), | 2463 character_count_(0), |
| 2464 is_ascii_(subject->IsAsciiRepresentation()) { | 2464 is_ascii_(subject->IsOneByteRepresentation()) { |
| 2465 // Require a non-zero initial size. Ensures that doubling the size to | 2465 // Require a non-zero initial size. Ensures that doubling the size to |
| 2466 // extend the array will work. | 2466 // extend the array will work. |
| 2467 ASSERT(estimated_part_count > 0); | 2467 ASSERT(estimated_part_count > 0); |
| 2468 } | 2468 } |
| 2469 | 2469 |
| 2470 static inline void AddSubjectSlice(FixedArrayBuilder* builder, | 2470 static inline void AddSubjectSlice(FixedArrayBuilder* builder, |
| 2471 int from, | 2471 int from, |
| 2472 int to) { | 2472 int to) { |
| 2473 ASSERT(from >= 0); | 2473 ASSERT(from >= 0); |
| 2474 int length = to - from; | 2474 int length = to - from; |
| (...skipping 19 matching lines...) Expand all Loading... |
| 2494 void AddSubjectSlice(int from, int to) { | 2494 void AddSubjectSlice(int from, int to) { |
| 2495 AddSubjectSlice(&array_builder_, from, to); | 2495 AddSubjectSlice(&array_builder_, from, to); |
| 2496 IncrementCharacterCount(to - from); | 2496 IncrementCharacterCount(to - from); |
| 2497 } | 2497 } |
| 2498 | 2498 |
| 2499 | 2499 |
| 2500 void AddString(Handle<String> string) { | 2500 void AddString(Handle<String> string) { |
| 2501 int length = string->length(); | 2501 int length = string->length(); |
| 2502 ASSERT(length > 0); | 2502 ASSERT(length > 0); |
| 2503 AddElement(*string); | 2503 AddElement(*string); |
| 2504 if (!string->IsAsciiRepresentation()) { | 2504 if (!string->IsOneByteRepresentation()) { |
| 2505 is_ascii_ = false; | 2505 is_ascii_ = false; |
| 2506 } | 2506 } |
| 2507 IncrementCharacterCount(length); | 2507 IncrementCharacterCount(length); |
| 2508 } | 2508 } |
| 2509 | 2509 |
| 2510 | 2510 |
| 2511 Handle<String> ToString() { | 2511 Handle<String> ToString() { |
| 2512 if (array_builder_.length() == 0) { | 2512 if (array_builder_.length() == 0) { |
| 2513 return heap_->isolate()->factory()->empty_string(); | 2513 return heap_->isolate()->factory()->empty_string(); |
| 2514 } | 2514 } |
| (...skipping 1346 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3861 return *isolate->factory()->nan_symbol(); | 3861 return *isolate->factory()->nan_symbol(); |
| 3862 } | 3862 } |
| 3863 if (isinf(value)) { | 3863 if (isinf(value)) { |
| 3864 if (value < 0) { | 3864 if (value < 0) { |
| 3865 return *isolate->factory()->minus_infinity_symbol(); | 3865 return *isolate->factory()->minus_infinity_symbol(); |
| 3866 } | 3866 } |
| 3867 return *isolate->factory()->infinity_symbol(); | 3867 return *isolate->factory()->infinity_symbol(); |
| 3868 } | 3868 } |
| 3869 char* str = DoubleToRadixCString(value, radix); | 3869 char* str = DoubleToRadixCString(value, radix); |
| 3870 MaybeObject* result = | 3870 MaybeObject* result = |
| 3871 isolate->heap()->AllocateStringFromAscii(CStrVector(str)); | 3871 isolate->heap()->AllocateStringFromOneByte(CStrVector(str)); |
| 3872 DeleteArray(str); | 3872 DeleteArray(str); |
| 3873 return result; | 3873 return result; |
| 3874 } | 3874 } |
| 3875 | 3875 |
| 3876 | 3876 |
| 3877 RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberToFixed) { | 3877 RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberToFixed) { |
| 3878 NoHandleAllocation ha; | 3878 NoHandleAllocation ha; |
| 3879 ASSERT(args.length() == 2); | 3879 ASSERT(args.length() == 2); |
| 3880 | 3880 |
| 3881 CONVERT_DOUBLE_ARG_CHECKED(value, 0); | 3881 CONVERT_DOUBLE_ARG_CHECKED(value, 0); |
| 3882 if (isnan(value)) { | 3882 if (isnan(value)) { |
| 3883 return *isolate->factory()->nan_symbol(); | 3883 return *isolate->factory()->nan_symbol(); |
| 3884 } | 3884 } |
| 3885 if (isinf(value)) { | 3885 if (isinf(value)) { |
| 3886 if (value < 0) { | 3886 if (value < 0) { |
| 3887 return *isolate->factory()->minus_infinity_symbol(); | 3887 return *isolate->factory()->minus_infinity_symbol(); |
| 3888 } | 3888 } |
| 3889 return *isolate->factory()->infinity_symbol(); | 3889 return *isolate->factory()->infinity_symbol(); |
| 3890 } | 3890 } |
| 3891 CONVERT_DOUBLE_ARG_CHECKED(f_number, 1); | 3891 CONVERT_DOUBLE_ARG_CHECKED(f_number, 1); |
| 3892 int f = FastD2IChecked(f_number); | 3892 int f = FastD2IChecked(f_number); |
| 3893 RUNTIME_ASSERT(f >= 0); | 3893 RUNTIME_ASSERT(f >= 0); |
| 3894 char* str = DoubleToFixedCString(value, f); | 3894 char* str = DoubleToFixedCString(value, f); |
| 3895 MaybeObject* res = | 3895 MaybeObject* res = |
| 3896 isolate->heap()->AllocateStringFromAscii(CStrVector(str)); | 3896 isolate->heap()->AllocateStringFromOneByte(CStrVector(str)); |
| 3897 DeleteArray(str); | 3897 DeleteArray(str); |
| 3898 return res; | 3898 return res; |
| 3899 } | 3899 } |
| 3900 | 3900 |
| 3901 | 3901 |
| 3902 RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberToExponential) { | 3902 RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberToExponential) { |
| 3903 NoHandleAllocation ha; | 3903 NoHandleAllocation ha; |
| 3904 ASSERT(args.length() == 2); | 3904 ASSERT(args.length() == 2); |
| 3905 | 3905 |
| 3906 CONVERT_DOUBLE_ARG_CHECKED(value, 0); | 3906 CONVERT_DOUBLE_ARG_CHECKED(value, 0); |
| 3907 if (isnan(value)) { | 3907 if (isnan(value)) { |
| 3908 return *isolate->factory()->nan_symbol(); | 3908 return *isolate->factory()->nan_symbol(); |
| 3909 } | 3909 } |
| 3910 if (isinf(value)) { | 3910 if (isinf(value)) { |
| 3911 if (value < 0) { | 3911 if (value < 0) { |
| 3912 return *isolate->factory()->minus_infinity_symbol(); | 3912 return *isolate->factory()->minus_infinity_symbol(); |
| 3913 } | 3913 } |
| 3914 return *isolate->factory()->infinity_symbol(); | 3914 return *isolate->factory()->infinity_symbol(); |
| 3915 } | 3915 } |
| 3916 CONVERT_DOUBLE_ARG_CHECKED(f_number, 1); | 3916 CONVERT_DOUBLE_ARG_CHECKED(f_number, 1); |
| 3917 int f = FastD2IChecked(f_number); | 3917 int f = FastD2IChecked(f_number); |
| 3918 RUNTIME_ASSERT(f >= -1 && f <= 20); | 3918 RUNTIME_ASSERT(f >= -1 && f <= 20); |
| 3919 char* str = DoubleToExponentialCString(value, f); | 3919 char* str = DoubleToExponentialCString(value, f); |
| 3920 MaybeObject* res = | 3920 MaybeObject* res = |
| 3921 isolate->heap()->AllocateStringFromAscii(CStrVector(str)); | 3921 isolate->heap()->AllocateStringFromOneByte(CStrVector(str)); |
| 3922 DeleteArray(str); | 3922 DeleteArray(str); |
| 3923 return res; | 3923 return res; |
| 3924 } | 3924 } |
| 3925 | 3925 |
| 3926 | 3926 |
| 3927 RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberToPrecision) { | 3927 RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberToPrecision) { |
| 3928 NoHandleAllocation ha; | 3928 NoHandleAllocation ha; |
| 3929 ASSERT(args.length() == 2); | 3929 ASSERT(args.length() == 2); |
| 3930 | 3930 |
| 3931 CONVERT_DOUBLE_ARG_CHECKED(value, 0); | 3931 CONVERT_DOUBLE_ARG_CHECKED(value, 0); |
| 3932 if (isnan(value)) { | 3932 if (isnan(value)) { |
| 3933 return *isolate->factory()->nan_symbol(); | 3933 return *isolate->factory()->nan_symbol(); |
| 3934 } | 3934 } |
| 3935 if (isinf(value)) { | 3935 if (isinf(value)) { |
| 3936 if (value < 0) { | 3936 if (value < 0) { |
| 3937 return *isolate->factory()->minus_infinity_symbol(); | 3937 return *isolate->factory()->minus_infinity_symbol(); |
| 3938 } | 3938 } |
| 3939 return *isolate->factory()->infinity_symbol(); | 3939 return *isolate->factory()->infinity_symbol(); |
| 3940 } | 3940 } |
| 3941 CONVERT_DOUBLE_ARG_CHECKED(f_number, 1); | 3941 CONVERT_DOUBLE_ARG_CHECKED(f_number, 1); |
| 3942 int f = FastD2IChecked(f_number); | 3942 int f = FastD2IChecked(f_number); |
| 3943 RUNTIME_ASSERT(f >= 1 && f <= 21); | 3943 RUNTIME_ASSERT(f >= 1 && f <= 21); |
| 3944 char* str = DoubleToPrecisionCString(value, f); | 3944 char* str = DoubleToPrecisionCString(value, f); |
| 3945 MaybeObject* res = | 3945 MaybeObject* res = |
| 3946 isolate->heap()->AllocateStringFromAscii(CStrVector(str)); | 3946 isolate->heap()->AllocateStringFromOneByte(CStrVector(str)); |
| 3947 DeleteArray(str); | 3947 DeleteArray(str); |
| 3948 return res; | 3948 return res; |
| 3949 } | 3949 } |
| 3950 | 3950 |
| 3951 | 3951 |
| 3952 // Returns a single character string where first character equals | 3952 // Returns a single character string where first character equals |
| 3953 // string->Get(index). | 3953 // string->Get(index). |
| 3954 static Handle<Object> GetCharAt(Handle<String> string, uint32_t index) { | 3954 static Handle<Object> GetCharAt(Handle<String> string, uint32_t index) { |
| 3955 if (index < static_cast<uint32_t>(string->length())) { | 3955 if (index < static_cast<uint32_t>(string->length())) { |
| 3956 string->TryFlatten(); | 3956 string->TryFlatten(); |
| (...skipping 1267 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5224 // the checking of inputs in the runtime calls we check here. | 5224 // the checking of inputs in the runtime calls we check here. |
| 5225 if (!maybe_element->ToObject(&element)) return maybe_element; | 5225 if (!maybe_element->ToObject(&element)) return maybe_element; |
| 5226 } | 5226 } |
| 5227 CONVERT_NUMBER_CHECKED(int, chr, Int32, element); | 5227 CONVERT_NUMBER_CHECKED(int, chr, Int32, element); |
| 5228 if ((chr & 0xffff) > String::kMaxAsciiCharCode) | 5228 if ((chr & 0xffff) > String::kMaxAsciiCharCode) |
| 5229 break; | 5229 break; |
| 5230 } | 5230 } |
| 5231 | 5231 |
| 5232 MaybeObject* maybe_object = NULL; | 5232 MaybeObject* maybe_object = NULL; |
| 5233 if (i == length) { // The string is ASCII. | 5233 if (i == length) { // The string is ASCII. |
| 5234 maybe_object = isolate->heap()->AllocateRawAsciiString(length); | 5234 maybe_object = isolate->heap()->AllocateRawOneByteString(length); |
| 5235 } else { // The string is not ASCII. | 5235 } else { // The string is not ASCII. |
| 5236 maybe_object = isolate->heap()->AllocateRawTwoByteString(length); | 5236 maybe_object = isolate->heap()->AllocateRawTwoByteString(length); |
| 5237 } | 5237 } |
| 5238 | 5238 |
| 5239 Object* object = NULL; | 5239 Object* object = NULL; |
| 5240 if (!maybe_object->ToObject(&object)) return maybe_object; | 5240 if (!maybe_object->ToObject(&object)) return maybe_object; |
| 5241 String* result = String::cast(object); | 5241 String* result = String::cast(object); |
| 5242 for (int i = 0; i < length; i++) { | 5242 for (int i = 0; i < length; i++) { |
| 5243 Object* element; | 5243 Object* element; |
| 5244 { MaybeObject* maybe_element = codes->GetElement(i); | 5244 { MaybeObject* maybe_element = codes->GetElement(i); |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5318 return Failure::OutOfMemoryException(); | 5318 return Failure::OutOfMemoryException(); |
| 5319 } | 5319 } |
| 5320 } | 5320 } |
| 5321 } | 5321 } |
| 5322 // No length change implies no change. Return original string if no change. | 5322 // No length change implies no change. Return original string if no change. |
| 5323 if (escaped_length == length) { | 5323 if (escaped_length == length) { |
| 5324 return source; | 5324 return source; |
| 5325 } | 5325 } |
| 5326 Object* o; | 5326 Object* o; |
| 5327 { MaybeObject* maybe_o = | 5327 { MaybeObject* maybe_o = |
| 5328 isolate->heap()->AllocateRawAsciiString(escaped_length); | 5328 isolate->heap()->AllocateRawOneByteString(escaped_length); |
| 5329 if (!maybe_o->ToObject(&o)) return maybe_o; | 5329 if (!maybe_o->ToObject(&o)) return maybe_o; |
| 5330 } | 5330 } |
| 5331 String* destination = String::cast(o); | 5331 String* destination = String::cast(o); |
| 5332 int dest_position = 0; | 5332 int dest_position = 0; |
| 5333 | 5333 |
| 5334 Access<StringInputBuffer> buffer( | 5334 Access<StringInputBuffer> buffer( |
| 5335 isolate->runtime_state()->string_input_buffer()); | 5335 isolate->runtime_state()->string_input_buffer()); |
| 5336 buffer->Rewind(); | 5336 buffer->Rewind(); |
| 5337 while (buffer->has_more()) { | 5337 while (buffer->has_more()) { |
| 5338 uint16_t chr = buffer->GetNext(); | 5338 uint16_t chr = buffer->GetNext(); |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5426 i += step; | 5426 i += step; |
| 5427 } | 5427 } |
| 5428 | 5428 |
| 5429 // No length change implies no change. Return original string if no change. | 5429 // No length change implies no change. Return original string if no change. |
| 5430 if (unescaped_length == length) | 5430 if (unescaped_length == length) |
| 5431 return source; | 5431 return source; |
| 5432 | 5432 |
| 5433 Object* o; | 5433 Object* o; |
| 5434 { MaybeObject* maybe_o = | 5434 { MaybeObject* maybe_o = |
| 5435 ascii ? | 5435 ascii ? |
| 5436 isolate->heap()->AllocateRawAsciiString(unescaped_length) : | 5436 isolate->heap()->AllocateRawOneByteString(unescaped_length) : |
| 5437 isolate->heap()->AllocateRawTwoByteString(unescaped_length); | 5437 isolate->heap()->AllocateRawTwoByteString(unescaped_length); |
| 5438 if (!maybe_o->ToObject(&o)) return maybe_o; | 5438 if (!maybe_o->ToObject(&o)) return maybe_o; |
| 5439 } | 5439 } |
| 5440 String* destination = String::cast(o); | 5440 String* destination = String::cast(o); |
| 5441 | 5441 |
| 5442 int dest_position = 0; | 5442 int dest_position = 0; |
| 5443 for (int i = 0; i < length; dest_position++) { | 5443 for (int i = 0; i < length; dest_position++) { |
| 5444 int step; | 5444 int step; |
| 5445 destination->Set(dest_position, Unescape(source, i, length, &step)); | 5445 destination->Set(dest_position, Unescape(source, i, length, &step)); |
| 5446 i += step; | 5446 i += step; |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5525 | 5525 |
| 5526 | 5526 |
| 5527 template <> | 5527 template <> |
| 5528 MaybeObject* AllocateRawString<SeqTwoByteString>(Isolate* isolate, int length) { | 5528 MaybeObject* AllocateRawString<SeqTwoByteString>(Isolate* isolate, int length) { |
| 5529 return isolate->heap()->AllocateRawTwoByteString(length); | 5529 return isolate->heap()->AllocateRawTwoByteString(length); |
| 5530 } | 5530 } |
| 5531 | 5531 |
| 5532 | 5532 |
| 5533 template <> | 5533 template <> |
| 5534 MaybeObject* AllocateRawString<SeqOneByteString>(Isolate* isolate, int length) { | 5534 MaybeObject* AllocateRawString<SeqOneByteString>(Isolate* isolate, int length) { |
| 5535 return isolate->heap()->AllocateRawAsciiString(length); | 5535 return isolate->heap()->AllocateRawOneByteString(length); |
| 5536 } | 5536 } |
| 5537 | 5537 |
| 5538 | 5538 |
| 5539 template <typename Char, typename StringType, bool comma> | 5539 template <typename Char, typename StringType, bool comma> |
| 5540 static MaybeObject* SlowQuoteJsonString(Isolate* isolate, | 5540 static MaybeObject* SlowQuoteJsonString(Isolate* isolate, |
| 5541 Vector<const Char> characters) { | 5541 Vector<const Char> characters) { |
| 5542 int length = characters.length(); | 5542 int length = characters.length(); |
| 5543 const Char* read_cursor = characters.start(); | 5543 const Char* read_cursor = characters.start(); |
| 5544 const Char* end = read_cursor + length; | 5544 const Char* end = read_cursor + length; |
| 5545 const int kSpaceForQuotes = 2 + (comma ? 1 :0); | 5545 const int kSpaceForQuotes = 2 + (comma ? 1 :0); |
| (...skipping 310 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5856 // length. This may not be pretty, but it is nicer than what was here before | 5856 // length. This may not be pretty, but it is nicer than what was here before |
| 5857 // and I hereby claim my vaffel-is. | 5857 // and I hereby claim my vaffel-is. |
| 5858 // | 5858 // |
| 5859 // Allocate the resulting string. | 5859 // Allocate the resulting string. |
| 5860 // | 5860 // |
| 5861 // NOTE: This assumes that the upper/lower case of an ASCII | 5861 // NOTE: This assumes that the upper/lower case of an ASCII |
| 5862 // character is also ASCII. This is currently the case, but it | 5862 // character is also ASCII. This is currently the case, but it |
| 5863 // might break in the future if we implement more context and locale | 5863 // might break in the future if we implement more context and locale |
| 5864 // dependent upper/lower conversions. | 5864 // dependent upper/lower conversions. |
| 5865 Object* o; | 5865 Object* o; |
| 5866 { MaybeObject* maybe_o = s->IsAsciiRepresentation() | 5866 { MaybeObject* maybe_o = s->IsOneByteRepresentation() |
| 5867 ? isolate->heap()->AllocateRawAsciiString(length) | 5867 ? isolate->heap()->AllocateRawOneByteString(length) |
| 5868 : isolate->heap()->AllocateRawTwoByteString(length); | 5868 : isolate->heap()->AllocateRawTwoByteString(length); |
| 5869 if (!maybe_o->ToObject(&o)) return maybe_o; | 5869 if (!maybe_o->ToObject(&o)) return maybe_o; |
| 5870 } | 5870 } |
| 5871 String* result = String::cast(o); | 5871 String* result = String::cast(o); |
| 5872 bool has_changed_character = false; | 5872 bool has_changed_character = false; |
| 5873 | 5873 |
| 5874 // Convert all characters to upper case, assuming that they will fit | 5874 // Convert all characters to upper case, assuming that they will fit |
| 5875 // in the buffer | 5875 // in the buffer |
| 5876 Access<StringInputBuffer> buffer( | 5876 Access<StringInputBuffer> buffer( |
| 5877 isolate->runtime_state()->string_input_buffer()); | 5877 isolate->runtime_state()->string_input_buffer()); |
| (...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6090 if (length == 0) return s; | 6090 if (length == 0) return s; |
| 6091 | 6091 |
| 6092 // Simpler handling of ASCII strings. | 6092 // Simpler handling of ASCII strings. |
| 6093 // | 6093 // |
| 6094 // NOTE: This assumes that the upper/lower case of an ASCII | 6094 // NOTE: This assumes that the upper/lower case of an ASCII |
| 6095 // character is also ASCII. This is currently the case, but it | 6095 // character is also ASCII. This is currently the case, but it |
| 6096 // might break in the future if we implement more context and locale | 6096 // might break in the future if we implement more context and locale |
| 6097 // dependent upper/lower conversions. | 6097 // dependent upper/lower conversions. |
| 6098 if (s->IsSeqOneByteString()) { | 6098 if (s->IsSeqOneByteString()) { |
| 6099 Object* o; | 6099 Object* o; |
| 6100 { MaybeObject* maybe_o = isolate->heap()->AllocateRawAsciiString(length); | 6100 { MaybeObject* maybe_o = isolate->heap()->AllocateRawOneByteString(length); |
| 6101 if (!maybe_o->ToObject(&o)) return maybe_o; | 6101 if (!maybe_o->ToObject(&o)) return maybe_o; |
| 6102 } | 6102 } |
| 6103 SeqOneByteString* result = SeqOneByteString::cast(o); | 6103 SeqOneByteString* result = SeqOneByteString::cast(o); |
| 6104 bool has_changed_character = ConvertTraits::AsciiConverter::Convert( | 6104 bool has_changed_character = ConvertTraits::AsciiConverter::Convert( |
| 6105 result->GetChars(), SeqOneByteString::cast(s)->GetChars(), length); | 6105 result->GetChars(), SeqOneByteString::cast(s)->GetChars(), length); |
| 6106 return has_changed_character ? result : s; | 6106 return has_changed_character ? result : s; |
| 6107 } | 6107 } |
| 6108 | 6108 |
| 6109 Object* answer; | 6109 Object* answer; |
| 6110 { MaybeObject* maybe_answer = | 6110 { MaybeObject* maybe_answer = |
| (...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6297 HandleScope scope(isolate); | 6297 HandleScope scope(isolate); |
| 6298 ASSERT(args.length() == 2); | 6298 ASSERT(args.length() == 2); |
| 6299 CONVERT_ARG_HANDLE_CHECKED(String, s, 0); | 6299 CONVERT_ARG_HANDLE_CHECKED(String, s, 0); |
| 6300 CONVERT_NUMBER_CHECKED(uint32_t, limit, Uint32, args[1]); | 6300 CONVERT_NUMBER_CHECKED(uint32_t, limit, Uint32, args[1]); |
| 6301 | 6301 |
| 6302 s = FlattenGetString(s); | 6302 s = FlattenGetString(s); |
| 6303 const int length = static_cast<int>(Min<uint32_t>(s->length(), limit)); | 6303 const int length = static_cast<int>(Min<uint32_t>(s->length(), limit)); |
| 6304 | 6304 |
| 6305 Handle<FixedArray> elements; | 6305 Handle<FixedArray> elements; |
| 6306 int position = 0; | 6306 int position = 0; |
| 6307 if (s->IsFlat() && s->IsAsciiRepresentation()) { | 6307 if (s->IsFlat() && s->IsOneByteRepresentation()) { |
| 6308 // Try using cached chars where possible. | 6308 // Try using cached chars where possible. |
| 6309 Object* obj; | 6309 Object* obj; |
| 6310 { MaybeObject* maybe_obj = | 6310 { MaybeObject* maybe_obj = |
| 6311 isolate->heap()->AllocateUninitializedFixedArray(length); | 6311 isolate->heap()->AllocateUninitializedFixedArray(length); |
| 6312 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 6312 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 6313 } | 6313 } |
| 6314 elements = Handle<FixedArray>(FixedArray::cast(obj), isolate); | 6314 elements = Handle<FixedArray>(FixedArray::cast(obj), isolate); |
| 6315 String::FlatContent content = s->GetFlatContent(); | 6315 String::FlatContent content = s->GetFlatContent(); |
| 6316 if (content.IsAscii()) { | 6316 if (content.IsAscii()) { |
| 6317 Vector<const char> chars = content.ToAsciiVector(); | 6317 Vector<const char> chars = content.ToAsciiVector(); |
| (...skipping 352 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6670 return Failure::OutOfMemoryException(); | 6670 return Failure::OutOfMemoryException(); |
| 6671 } | 6671 } |
| 6672 position += increment; | 6672 position += increment; |
| 6673 } | 6673 } |
| 6674 | 6674 |
| 6675 int length = position; | 6675 int length = position; |
| 6676 Object* object; | 6676 Object* object; |
| 6677 | 6677 |
| 6678 if (ascii) { | 6678 if (ascii) { |
| 6679 { MaybeObject* maybe_object = | 6679 { MaybeObject* maybe_object = |
| 6680 isolate->heap()->AllocateRawAsciiString(length); | 6680 isolate->heap()->AllocateRawOneByteString(length); |
| 6681 if (!maybe_object->ToObject(&object)) return maybe_object; | 6681 if (!maybe_object->ToObject(&object)) return maybe_object; |
| 6682 } | 6682 } |
| 6683 SeqOneByteString* answer = SeqOneByteString::cast(object); | 6683 SeqOneByteString* answer = SeqOneByteString::cast(object); |
| 6684 StringBuilderConcatHelper(special, | 6684 StringBuilderConcatHelper(special, |
| 6685 answer->GetChars(), | 6685 answer->GetChars(), |
| 6686 fixed_array, | 6686 fixed_array, |
| 6687 array_length); | 6687 array_length); |
| 6688 return answer; | 6688 return answer; |
| 6689 } else { | 6689 } else { |
| 6690 { MaybeObject* maybe_object = | 6690 { MaybeObject* maybe_object = |
| (...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6832 RUNTIME_ASSERT(elements_array->HasFastSmiOrObjectElements()); | 6832 RUNTIME_ASSERT(elements_array->HasFastSmiOrObjectElements()); |
| 6833 CONVERT_NUMBER_CHECKED(uint32_t, array_length, Uint32, args[1]); | 6833 CONVERT_NUMBER_CHECKED(uint32_t, array_length, Uint32, args[1]); |
| 6834 CONVERT_ARG_CHECKED(String, separator, 2); | 6834 CONVERT_ARG_CHECKED(String, separator, 2); |
| 6835 // elements_array is fast-mode JSarray of alternating positions | 6835 // elements_array is fast-mode JSarray of alternating positions |
| 6836 // (increasing order) and strings. | 6836 // (increasing order) and strings. |
| 6837 // array_length is length of original array (used to add separators); | 6837 // array_length is length of original array (used to add separators); |
| 6838 // separator is string to put between elements. Assumed to be non-empty. | 6838 // separator is string to put between elements. Assumed to be non-empty. |
| 6839 | 6839 |
| 6840 // Find total length of join result. | 6840 // Find total length of join result. |
| 6841 int string_length = 0; | 6841 int string_length = 0; |
| 6842 bool is_ascii = separator->IsAsciiRepresentation(); | 6842 bool is_ascii = separator->IsOneByteRepresentation(); |
| 6843 int max_string_length; | 6843 int max_string_length; |
| 6844 if (is_ascii) { | 6844 if (is_ascii) { |
| 6845 max_string_length = SeqOneByteString::kMaxLength; | 6845 max_string_length = SeqOneByteString::kMaxLength; |
| 6846 } else { | 6846 } else { |
| 6847 max_string_length = SeqTwoByteString::kMaxLength; | 6847 max_string_length = SeqTwoByteString::kMaxLength; |
| 6848 } | 6848 } |
| 6849 bool overflow = false; | 6849 bool overflow = false; |
| 6850 CONVERT_NUMBER_CHECKED(int, elements_length, | 6850 CONVERT_NUMBER_CHECKED(int, elements_length, |
| 6851 Int32, elements_array->length()); | 6851 Int32, elements_array->length()); |
| 6852 RUNTIME_ASSERT((elements_length & 1) == 0); // Even length. | 6852 RUNTIME_ASSERT((elements_length & 1) == 0); // Even length. |
| 6853 FixedArray* elements = FixedArray::cast(elements_array->elements()); | 6853 FixedArray* elements = FixedArray::cast(elements_array->elements()); |
| 6854 for (int i = 0; i < elements_length; i += 2) { | 6854 for (int i = 0; i < elements_length; i += 2) { |
| 6855 RUNTIME_ASSERT(elements->get(i)->IsNumber()); | 6855 RUNTIME_ASSERT(elements->get(i)->IsNumber()); |
| 6856 RUNTIME_ASSERT(elements->get(i + 1)->IsString()); | 6856 RUNTIME_ASSERT(elements->get(i + 1)->IsString()); |
| 6857 String* string = String::cast(elements->get(i + 1)); | 6857 String* string = String::cast(elements->get(i + 1)); |
| 6858 int length = string->length(); | 6858 int length = string->length(); |
| 6859 if (is_ascii && !string->IsAsciiRepresentation()) { | 6859 if (is_ascii && !string->IsOneByteRepresentation()) { |
| 6860 is_ascii = false; | 6860 is_ascii = false; |
| 6861 max_string_length = SeqTwoByteString::kMaxLength; | 6861 max_string_length = SeqTwoByteString::kMaxLength; |
| 6862 } | 6862 } |
| 6863 if (length > max_string_length || | 6863 if (length > max_string_length || |
| 6864 max_string_length - length < string_length) { | 6864 max_string_length - length < string_length) { |
| 6865 overflow = true; | 6865 overflow = true; |
| 6866 break; | 6866 break; |
| 6867 } | 6867 } |
| 6868 string_length += length; | 6868 string_length += length; |
| 6869 } | 6869 } |
| (...skipping 15 matching lines...) Expand all Loading... |
| 6885 overflow = true; | 6885 overflow = true; |
| 6886 } | 6886 } |
| 6887 } | 6887 } |
| 6888 if (overflow) { | 6888 if (overflow) { |
| 6889 // Throw OutOfMemory exception for creating too large a string. | 6889 // Throw OutOfMemory exception for creating too large a string. |
| 6890 V8::FatalProcessOutOfMemory("Array join result too large."); | 6890 V8::FatalProcessOutOfMemory("Array join result too large."); |
| 6891 } | 6891 } |
| 6892 | 6892 |
| 6893 if (is_ascii) { | 6893 if (is_ascii) { |
| 6894 MaybeObject* result_allocation = | 6894 MaybeObject* result_allocation = |
| 6895 isolate->heap()->AllocateRawAsciiString(string_length); | 6895 isolate->heap()->AllocateRawOneByteString(string_length); |
| 6896 if (result_allocation->IsFailure()) return result_allocation; | 6896 if (result_allocation->IsFailure()) return result_allocation; |
| 6897 SeqOneByteString* result_string = | 6897 SeqOneByteString* result_string = |
| 6898 SeqOneByteString::cast(result_allocation->ToObjectUnchecked()); | 6898 SeqOneByteString::cast(result_allocation->ToObjectUnchecked()); |
| 6899 JoinSparseArrayWithSeparator<char>(elements, | 6899 JoinSparseArrayWithSeparator<char>(elements, |
| 6900 elements_length, | 6900 elements_length, |
| 6901 array_length, | 6901 array_length, |
| 6902 separator, | 6902 separator, |
| 6903 Vector<char>(result_string->GetChars(), | 6903 Vector<char>(result_string->GetChars(), |
| 6904 string_length)); | 6904 string_length)); |
| 6905 return result_string; | 6905 return result_string; |
| (...skipping 6133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 13039 | 13039 |
| 13040 | 13040 |
| 13041 // Returns V8 version as a string. | 13041 // Returns V8 version as a string. |
| 13042 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetV8Version) { | 13042 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetV8Version) { |
| 13043 ASSERT_EQ(args.length(), 0); | 13043 ASSERT_EQ(args.length(), 0); |
| 13044 | 13044 |
| 13045 NoHandleAllocation ha; | 13045 NoHandleAllocation ha; |
| 13046 | 13046 |
| 13047 const char* version_string = v8::V8::GetVersion(); | 13047 const char* version_string = v8::V8::GetVersion(); |
| 13048 | 13048 |
| 13049 return isolate->heap()->AllocateStringFromAscii(CStrVector(version_string), | 13049 return isolate->heap()->AllocateStringFromOneByte(CStrVector(version_string), |
| 13050 NOT_TENURED); | 13050 NOT_TENURED); |
| 13051 } | 13051 } |
| 13052 | 13052 |
| 13053 | 13053 |
| 13054 RUNTIME_FUNCTION(MaybeObject*, Runtime_Abort) { | 13054 RUNTIME_FUNCTION(MaybeObject*, Runtime_Abort) { |
| 13055 ASSERT(args.length() == 2); | 13055 ASSERT(args.length() == 2); |
| 13056 OS::PrintError("abort: %s\n", | 13056 OS::PrintError("abort: %s\n", |
| 13057 reinterpret_cast<char*>(args[0]) + args.smi_at(1)); | 13057 reinterpret_cast<char*>(args[0]) + args.smi_at(1)); |
| 13058 isolate->PrintStack(); | 13058 isolate->PrintStack(); |
| 13059 OS::Abort(); | 13059 OS::Abort(); |
| (...skipping 361 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 13421 // Handle last resort GC and make sure to allow future allocations | 13421 // Handle last resort GC and make sure to allow future allocations |
| 13422 // to grow the heap without causing GCs (if possible). | 13422 // to grow the heap without causing GCs (if possible). |
| 13423 isolate->counters()->gc_last_resort_from_js()->Increment(); | 13423 isolate->counters()->gc_last_resort_from_js()->Increment(); |
| 13424 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags, | 13424 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags, |
| 13425 "Runtime::PerformGC"); | 13425 "Runtime::PerformGC"); |
| 13426 } | 13426 } |
| 13427 } | 13427 } |
| 13428 | 13428 |
| 13429 | 13429 |
| 13430 } } // namespace v8::internal | 13430 } } // namespace v8::internal |
| OLD | NEW |