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 3416 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3427 int length = string->length(); | 3427 int length = string->length(); |
3428 ASSERT(length > 0); | 3428 ASSERT(length > 0); |
3429 AddElement(*string); | 3429 AddElement(*string); |
3430 if (!string->IsOneByteRepresentation()) { | 3430 if (!string->IsOneByteRepresentation()) { |
3431 is_ascii_ = false; | 3431 is_ascii_ = false; |
3432 } | 3432 } |
3433 IncrementCharacterCount(length); | 3433 IncrementCharacterCount(length); |
3434 } | 3434 } |
3435 | 3435 |
3436 | 3436 |
3437 Handle<String> ToString() { | 3437 MaybeHandle<String> ToString() { |
| 3438 Isolate* isolate = heap_->isolate(); |
3438 if (array_builder_.length() == 0) { | 3439 if (array_builder_.length() == 0) { |
3439 return heap_->isolate()->factory()->empty_string(); | 3440 return isolate->factory()->empty_string(); |
3440 } | 3441 } |
3441 | 3442 |
3442 Handle<String> joined_string; | 3443 Handle<String> joined_string; |
3443 if (is_ascii_) { | 3444 if (is_ascii_) { |
3444 Handle<SeqOneByteString> seq = NewRawOneByteString(character_count_); | 3445 Handle<SeqOneByteString> seq; |
3445 RETURN_IF_EMPTY_HANDLE_VALUE(heap_->isolate(), seq, Handle<String>()); | 3446 ASSIGN_RETURN_ON_EXCEPTION( |
| 3447 isolate, seq, |
| 3448 isolate->factory()->NewRawOneByteString(character_count_), |
| 3449 String); |
| 3450 |
3446 DisallowHeapAllocation no_gc; | 3451 DisallowHeapAllocation no_gc; |
3447 uint8_t* char_buffer = seq->GetChars(); | 3452 uint8_t* char_buffer = seq->GetChars(); |
3448 StringBuilderConcatHelper(*subject_, | 3453 StringBuilderConcatHelper(*subject_, |
3449 char_buffer, | 3454 char_buffer, |
3450 *array_builder_.array(), | 3455 *array_builder_.array(), |
3451 array_builder_.length()); | 3456 array_builder_.length()); |
3452 joined_string = Handle<String>::cast(seq); | 3457 joined_string = Handle<String>::cast(seq); |
3453 } else { | 3458 } else { |
3454 // Non-ASCII. | 3459 // Non-ASCII. |
3455 Handle<SeqTwoByteString> seq = NewRawTwoByteString(character_count_); | 3460 Handle<SeqTwoByteString> seq; |
3456 RETURN_IF_EMPTY_HANDLE_VALUE(heap_->isolate(), seq, Handle<String>()); | 3461 ASSIGN_RETURN_ON_EXCEPTION( |
| 3462 isolate, seq, |
| 3463 isolate->factory()->NewRawTwoByteString(character_count_), |
| 3464 String); |
| 3465 |
3457 DisallowHeapAllocation no_gc; | 3466 DisallowHeapAllocation no_gc; |
3458 uc16* char_buffer = seq->GetChars(); | 3467 uc16* char_buffer = seq->GetChars(); |
3459 StringBuilderConcatHelper(*subject_, | 3468 StringBuilderConcatHelper(*subject_, |
3460 char_buffer, | 3469 char_buffer, |
3461 *array_builder_.array(), | 3470 *array_builder_.array(), |
3462 array_builder_.length()); | 3471 array_builder_.length()); |
3463 joined_string = Handle<String>::cast(seq); | 3472 joined_string = Handle<String>::cast(seq); |
3464 } | 3473 } |
3465 return joined_string; | 3474 return joined_string; |
3466 } | 3475 } |
3467 | 3476 |
3468 | 3477 |
3469 void IncrementCharacterCount(int by) { | 3478 void IncrementCharacterCount(int by) { |
3470 if (character_count_ > String::kMaxLength - by) { | 3479 if (character_count_ > String::kMaxLength - by) { |
3471 STATIC_ASSERT(String::kMaxLength < kMaxInt); | 3480 STATIC_ASSERT(String::kMaxLength < kMaxInt); |
3472 character_count_ = kMaxInt; | 3481 character_count_ = kMaxInt; |
3473 } else { | 3482 } else { |
3474 character_count_ += by; | 3483 character_count_ += by; |
3475 } | 3484 } |
3476 } | 3485 } |
3477 | 3486 |
3478 private: | 3487 private: |
3479 Handle<SeqOneByteString> NewRawOneByteString(int length) { | |
3480 return heap_->isolate()->factory()->NewRawOneByteString(length); | |
3481 } | |
3482 | |
3483 | |
3484 Handle<SeqTwoByteString> NewRawTwoByteString(int length) { | |
3485 return heap_->isolate()->factory()->NewRawTwoByteString(length); | |
3486 } | |
3487 | |
3488 | |
3489 void AddElement(Object* element) { | 3488 void AddElement(Object* element) { |
3490 ASSERT(element->IsSmi() || element->IsString()); | 3489 ASSERT(element->IsSmi() || element->IsString()); |
3491 ASSERT(array_builder_.capacity() > array_builder_.length()); | 3490 ASSERT(array_builder_.capacity() > array_builder_.length()); |
3492 array_builder_.Add(element); | 3491 array_builder_.Add(element); |
3493 } | 3492 } |
3494 | 3493 |
3495 Heap* heap_; | 3494 Heap* heap_; |
3496 FixedArrayBuilder array_builder_; | 3495 FixedArrayBuilder array_builder_; |
3497 Handle<String> subject_; | 3496 Handle<String> subject_; |
3498 int character_count_; | 3497 int character_count_; |
(...skipping 458 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3957 if (result_len_64 > static_cast<int64_t>(String::kMaxLength)) { | 3956 if (result_len_64 > static_cast<int64_t>(String::kMaxLength)) { |
3958 STATIC_ASSERT(String::kMaxLength < kMaxInt); | 3957 STATIC_ASSERT(String::kMaxLength < kMaxInt); |
3959 result_len = kMaxInt; // Provoke exception. | 3958 result_len = kMaxInt; // Provoke exception. |
3960 } else { | 3959 } else { |
3961 result_len = static_cast<int>(result_len_64); | 3960 result_len = static_cast<int>(result_len_64); |
3962 } | 3961 } |
3963 | 3962 |
3964 int subject_pos = 0; | 3963 int subject_pos = 0; |
3965 int result_pos = 0; | 3964 int result_pos = 0; |
3966 | 3965 |
3967 Handle<String> result_seq; | 3966 MaybeHandle<SeqString> maybe_res; |
3968 if (ResultSeqString::kHasAsciiEncoding) { | 3967 if (ResultSeqString::kHasAsciiEncoding) { |
3969 result_seq = isolate->factory()->NewRawOneByteString(result_len); | 3968 maybe_res = isolate->factory()->NewRawOneByteString(result_len); |
3970 } else { | 3969 } else { |
3971 result_seq = isolate->factory()->NewRawTwoByteString(result_len); | 3970 maybe_res = isolate->factory()->NewRawTwoByteString(result_len); |
3972 } | 3971 } |
3973 RETURN_IF_EMPTY_HANDLE(isolate, result_seq); | 3972 Handle<SeqString> untyped_res; |
3974 Handle<ResultSeqString> result = Handle<ResultSeqString>::cast(result_seq); | 3973 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, untyped_res, maybe_res); |
| 3974 Handle<ResultSeqString> result = Handle<ResultSeqString>::cast(untyped_res); |
3975 | 3975 |
3976 for (int i = 0; i < matches; i++) { | 3976 for (int i = 0; i < matches; i++) { |
3977 // Copy non-matched subject content. | 3977 // Copy non-matched subject content. |
3978 if (subject_pos < indices.at(i)) { | 3978 if (subject_pos < indices.at(i)) { |
3979 String::WriteToFlat(*subject, | 3979 String::WriteToFlat(*subject, |
3980 result->GetChars() + result_pos, | 3980 result->GetChars() + result_pos, |
3981 subject_pos, | 3981 subject_pos, |
3982 indices.at(i)); | 3982 indices.at(i)); |
3983 result_pos += indices.at(i) - subject_pos; | 3983 result_pos += indices.at(i) - subject_pos; |
3984 } | 3984 } |
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4093 if (prev < subject_length) { | 4093 if (prev < subject_length) { |
4094 builder.EnsureCapacity(2); | 4094 builder.EnsureCapacity(2); |
4095 builder.AddSubjectSlice(prev, subject_length); | 4095 builder.AddSubjectSlice(prev, subject_length); |
4096 } | 4096 } |
4097 | 4097 |
4098 RegExpImpl::SetLastMatchInfo(last_match_info, | 4098 RegExpImpl::SetLastMatchInfo(last_match_info, |
4099 subject, | 4099 subject, |
4100 capture_count, | 4100 capture_count, |
4101 global_cache.LastSuccessfulMatch()); | 4101 global_cache.LastSuccessfulMatch()); |
4102 | 4102 |
4103 Handle<String> result = builder.ToString(); | 4103 Handle<String> result; |
4104 RETURN_IF_EMPTY_HANDLE(isolate, result); | 4104 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, builder.ToString()); |
4105 return *result; | 4105 return *result; |
4106 } | 4106 } |
4107 | 4107 |
4108 | 4108 |
4109 template <typename ResultSeqString> | 4109 template <typename ResultSeqString> |
4110 MUST_USE_RESULT static MaybeObject* StringReplaceGlobalRegExpWithEmptyString( | 4110 MUST_USE_RESULT static MaybeObject* StringReplaceGlobalRegExpWithEmptyString( |
4111 Isolate* isolate, | 4111 Isolate* isolate, |
4112 Handle<String> subject, | 4112 Handle<String> subject, |
4113 Handle<JSRegExp> regexp, | 4113 Handle<JSRegExp> regexp, |
4114 Handle<JSArray> last_match_info) { | 4114 Handle<JSArray> last_match_info) { |
(...skipping 24 matching lines...) Expand all Loading... |
4139 int end = current_match[1]; | 4139 int end = current_match[1]; |
4140 int capture_count = regexp->CaptureCount(); | 4140 int capture_count = regexp->CaptureCount(); |
4141 int subject_length = subject->length(); | 4141 int subject_length = subject->length(); |
4142 | 4142 |
4143 int new_length = subject_length - (end - start); | 4143 int new_length = subject_length - (end - start); |
4144 if (new_length == 0) return isolate->heap()->empty_string(); | 4144 if (new_length == 0) return isolate->heap()->empty_string(); |
4145 | 4145 |
4146 Handle<ResultSeqString> answer; | 4146 Handle<ResultSeqString> answer; |
4147 if (ResultSeqString::kHasAsciiEncoding) { | 4147 if (ResultSeqString::kHasAsciiEncoding) { |
4148 answer = Handle<ResultSeqString>::cast( | 4148 answer = Handle<ResultSeqString>::cast( |
4149 isolate->factory()->NewRawOneByteString(new_length)); | 4149 isolate->factory()->NewRawOneByteString(new_length).ToHandleChecked()); |
4150 } else { | 4150 } else { |
4151 answer = Handle<ResultSeqString>::cast( | 4151 answer = Handle<ResultSeqString>::cast( |
4152 isolate->factory()->NewRawTwoByteString(new_length)); | 4152 isolate->factory()->NewRawTwoByteString(new_length).ToHandleChecked()); |
4153 } | 4153 } |
4154 ASSERT(!answer.is_null()); | |
4155 | 4154 |
4156 int prev = 0; | 4155 int prev = 0; |
4157 int position = 0; | 4156 int position = 0; |
4158 | 4157 |
4159 do { | 4158 do { |
4160 start = current_match[0]; | 4159 start = current_match[0]; |
4161 end = current_match[1]; | 4160 end = current_match[1]; |
4162 if (prev < start) { | 4161 if (prev < start) { |
4163 // Add substring subject[prev;start] to answer string. | 4162 // Add substring subject[prev;start] to answer string. |
4164 String::WriteToFlat(*subject, answer->GetChars() + position, prev, start); | 4163 String::WriteToFlat(*subject, answer->GetChars() + position, prev, start); |
(...skipping 2109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6274 return *SeqString::Truncate(string, new_length); | 6273 return *SeqString::Truncate(string, new_length); |
6275 } | 6274 } |
6276 | 6275 |
6277 | 6276 |
6278 RUNTIME_FUNCTION(MaybeObject*, Runtime_URIEscape) { | 6277 RUNTIME_FUNCTION(MaybeObject*, Runtime_URIEscape) { |
6279 HandleScope scope(isolate); | 6278 HandleScope scope(isolate); |
6280 ASSERT(args.length() == 1); | 6279 ASSERT(args.length() == 1); |
6281 CONVERT_ARG_HANDLE_CHECKED(String, source, 0); | 6280 CONVERT_ARG_HANDLE_CHECKED(String, source, 0); |
6282 Handle<String> string = FlattenGetString(source); | 6281 Handle<String> string = FlattenGetString(source); |
6283 ASSERT(string->IsFlat()); | 6282 ASSERT(string->IsFlat()); |
6284 Handle<String> result = string->IsOneByteRepresentationUnderneath() | 6283 Handle<String> result; |
6285 ? URIEscape::Escape<uint8_t>(isolate, source) | 6284 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( |
6286 : URIEscape::Escape<uc16>(isolate, source); | 6285 isolate, result, |
6287 RETURN_IF_EMPTY_HANDLE(isolate, result); | 6286 string->IsOneByteRepresentationUnderneath() |
| 6287 ? URIEscape::Escape<uint8_t>(isolate, source) |
| 6288 : URIEscape::Escape<uc16>(isolate, source)); |
6288 return *result; | 6289 return *result; |
6289 } | 6290 } |
6290 | 6291 |
6291 | 6292 |
6292 RUNTIME_FUNCTION(MaybeObject*, Runtime_URIUnescape) { | 6293 RUNTIME_FUNCTION(MaybeObject*, Runtime_URIUnescape) { |
6293 HandleScope scope(isolate); | 6294 HandleScope scope(isolate); |
6294 ASSERT(args.length() == 1); | 6295 ASSERT(args.length() == 1); |
6295 CONVERT_ARG_HANDLE_CHECKED(String, source, 0); | 6296 CONVERT_ARG_HANDLE_CHECKED(String, source, 0); |
6296 Handle<String> string = FlattenGetString(source); | 6297 Handle<String> string = FlattenGetString(source); |
6297 ASSERT(string->IsFlat()); | 6298 ASSERT(string->IsFlat()); |
(...skipping 290 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6588 // Assume that the string is not empty; we need this assumption later | 6589 // Assume that the string is not empty; we need this assumption later |
6589 if (length == 0) return *s; | 6590 if (length == 0) return *s; |
6590 | 6591 |
6591 // Simpler handling of ASCII strings. | 6592 // Simpler handling of ASCII strings. |
6592 // | 6593 // |
6593 // NOTE: This assumes that the upper/lower case of an ASCII | 6594 // NOTE: This assumes that the upper/lower case of an ASCII |
6594 // character is also ASCII. This is currently the case, but it | 6595 // character is also ASCII. This is currently the case, but it |
6595 // might break in the future if we implement more context and locale | 6596 // might break in the future if we implement more context and locale |
6596 // dependent upper/lower conversions. | 6597 // dependent upper/lower conversions. |
6597 if (s->IsOneByteRepresentationUnderneath()) { | 6598 if (s->IsOneByteRepresentationUnderneath()) { |
| 6599 // Same length as input. |
6598 Handle<SeqOneByteString> result = | 6600 Handle<SeqOneByteString> result = |
6599 isolate->factory()->NewRawOneByteString(length); | 6601 isolate->factory()->NewRawOneByteString(length).ToHandleChecked(); |
6600 ASSERT(!result.is_null()); // Same length as input. | |
6601 DisallowHeapAllocation no_gc; | 6602 DisallowHeapAllocation no_gc; |
6602 String::FlatContent flat_content = s->GetFlatContent(); | 6603 String::FlatContent flat_content = s->GetFlatContent(); |
6603 ASSERT(flat_content.IsFlat()); | 6604 ASSERT(flat_content.IsFlat()); |
6604 bool has_changed_character = false; | 6605 bool has_changed_character = false; |
6605 bool is_ascii = FastAsciiConvert<Converter>( | 6606 bool is_ascii = FastAsciiConvert<Converter>( |
6606 reinterpret_cast<char*>(result->GetChars()), | 6607 reinterpret_cast<char*>(result->GetChars()), |
6607 reinterpret_cast<const char*>(flat_content.ToOneByteVector().start()), | 6608 reinterpret_cast<const char*>(flat_content.ToOneByteVector().start()), |
6608 length, | 6609 length, |
6609 &has_changed_character); | 6610 &has_changed_character); |
6610 // If not ASCII, we discard the result and take the 2 byte path. | 6611 // If not ASCII, we discard the result and take the 2 byte path. |
6611 if (is_ascii) return has_changed_character ? *result : *s; | 6612 if (is_ascii) return has_changed_character ? *result : *s; |
6612 } | 6613 } |
6613 | 6614 |
6614 Handle<SeqString> result; | 6615 Handle<SeqString> result; // Same length as input. |
6615 if (s->IsOneByteRepresentation()) { | 6616 if (s->IsOneByteRepresentation()) { |
6616 result = isolate->factory()->NewRawOneByteString(length); | 6617 result = isolate->factory()->NewRawOneByteString(length).ToHandleChecked(); |
6617 } else { | 6618 } else { |
6618 result = isolate->factory()->NewRawTwoByteString(length); | 6619 result = isolate->factory()->NewRawTwoByteString(length).ToHandleChecked(); |
6619 } | 6620 } |
6620 ASSERT(!result.is_null()); // Same length as input. | |
6621 | 6621 |
6622 MaybeObject* maybe = ConvertCaseHelper(isolate, *s, *result, length, mapping); | 6622 MaybeObject* maybe = ConvertCaseHelper(isolate, *s, *result, length, mapping); |
6623 Object* answer; | 6623 Object* answer; |
6624 if (!maybe->ToObject(&answer)) return maybe; | 6624 if (!maybe->ToObject(&answer)) return maybe; |
6625 if (answer->IsString()) return answer; | 6625 if (answer->IsString()) return answer; |
6626 | 6626 |
6627 ASSERT(answer->IsSmi()); | 6627 ASSERT(answer->IsSmi()); |
6628 length = Smi::cast(answer)->value(); | 6628 length = Smi::cast(answer)->value(); |
6629 if (s->IsOneByteRepresentation() && length > 0) { | 6629 if (s->IsOneByteRepresentation() && length > 0) { |
6630 result = isolate->factory()->NewRawOneByteString(length); | 6630 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( |
| 6631 isolate, result, isolate->factory()->NewRawOneByteString(length)); |
6631 } else { | 6632 } else { |
6632 if (length < 0) length = -length; | 6633 if (length < 0) length = -length; |
6633 result = isolate->factory()->NewRawTwoByteString(length); | 6634 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( |
| 6635 isolate, result, isolate->factory()->NewRawTwoByteString(length)); |
6634 } | 6636 } |
6635 RETURN_IF_EMPTY_HANDLE(isolate, result); | |
6636 return ConvertCaseHelper(isolate, *s, *result, length, mapping); | 6637 return ConvertCaseHelper(isolate, *s, *result, length, mapping); |
6637 } | 6638 } |
6638 | 6639 |
6639 | 6640 |
6640 RUNTIME_FUNCTION(MaybeObject*, Runtime_StringToLowerCase) { | 6641 RUNTIME_FUNCTION(MaybeObject*, Runtime_StringToLowerCase) { |
6641 return ConvertCase( | 6642 return ConvertCase( |
6642 args, isolate, isolate->runtime_state()->to_lower_mapping()); | 6643 args, isolate, isolate->runtime_state()->to_lower_mapping()); |
6643 } | 6644 } |
6644 | 6645 |
6645 | 6646 |
(...skipping 613 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7259 String* element = String::cast(element_obj); | 7260 String* element = String::cast(element_obj); |
7260 int increment = element->length(); | 7261 int increment = element->length(); |
7261 if (increment > String::kMaxLength - length) { | 7262 if (increment > String::kMaxLength - length) { |
7262 STATIC_ASSERT(String::kMaxLength < kMaxInt); | 7263 STATIC_ASSERT(String::kMaxLength < kMaxInt); |
7263 length = kMaxInt; // Provoke exception; | 7264 length = kMaxInt; // Provoke exception; |
7264 break; | 7265 break; |
7265 } | 7266 } |
7266 length += increment; | 7267 length += increment; |
7267 } | 7268 } |
7268 | 7269 |
7269 Handle<SeqTwoByteString> answer = | 7270 Handle<SeqTwoByteString> answer; |
7270 isolate->factory()->NewRawTwoByteString(length); | 7271 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( |
7271 RETURN_IF_EMPTY_HANDLE(isolate, answer); | 7272 isolate, answer, |
| 7273 isolate->factory()->NewRawTwoByteString(length)); |
7272 | 7274 |
7273 DisallowHeapAllocation no_gc; | 7275 DisallowHeapAllocation no_gc; |
7274 | 7276 |
7275 uc16* sink = answer->GetChars(); | 7277 uc16* sink = answer->GetChars(); |
7276 #ifdef DEBUG | 7278 #ifdef DEBUG |
7277 uc16* end = sink + length; | 7279 uc16* end = sink + length; |
7278 #endif | 7280 #endif |
7279 | 7281 |
7280 String* first = String::cast(fixed_array->get(0)); | 7282 String* first = String::cast(fixed_array->get(0)); |
7281 String* seperator_raw = *separator; | 7283 String* seperator_raw = *separator; |
(...skipping 7940 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
15222 } | 15224 } |
15223 } | 15225 } |
15224 | 15226 |
15225 | 15227 |
15226 void Runtime::OutOfMemory() { | 15228 void Runtime::OutOfMemory() { |
15227 Heap::FatalProcessOutOfMemory("CALL_AND_RETRY_LAST", true); | 15229 Heap::FatalProcessOutOfMemory("CALL_AND_RETRY_LAST", true); |
15228 UNREACHABLE(); | 15230 UNREACHABLE(); |
15229 } | 15231 } |
15230 | 15232 |
15231 } } // namespace v8::internal | 15233 } } // namespace v8::internal |
OLD | NEW |