Index: src/runtime.cc |
diff --git a/src/runtime.cc b/src/runtime.cc |
index 8b18e55278cb072cd89d8c43faaa34291369775f..e56b309ea5833ac0a0aa012fb5ea7b53160763bb 100644 |
--- a/src/runtime.cc |
+++ b/src/runtime.cc |
@@ -3344,8 +3344,7 @@ class ReplacementStringBuilder { |
array_builder_(heap->isolate(), estimated_part_count), |
subject_(subject), |
character_count_(0), |
- is_ascii_(subject->IsOneByteRepresentation()), |
- overflowed_(false) { |
+ is_ascii_(subject->IsOneByteRepresentation()) { |
// Require a non-zero initial size. Ensures that doubling the size to |
// extend the array will work. |
ASSERT(estimated_part_count > 0); |
@@ -3393,11 +3392,6 @@ class ReplacementStringBuilder { |
Handle<String> ToString() { |
- if (overflowed_) { |
- heap_->isolate()->ThrowInvalidStringLength(); |
- return Handle<String>(); |
- } |
- |
if (array_builder_.length() == 0) { |
return heap_->isolate()->factory()->empty_string(); |
} |
@@ -3405,6 +3399,7 @@ class ReplacementStringBuilder { |
Handle<String> joined_string; |
if (is_ascii_) { |
Handle<SeqOneByteString> seq = NewRawOneByteString(character_count_); |
+ RETURN_IF_EMPTY_HANDLE_VALUE(heap_->isolate(), seq, Handle<String>()); |
DisallowHeapAllocation no_gc; |
uint8_t* char_buffer = seq->GetChars(); |
StringBuilderConcatHelper(*subject_, |
@@ -3415,6 +3410,7 @@ class ReplacementStringBuilder { |
} else { |
// Non-ASCII. |
Handle<SeqTwoByteString> seq = NewRawTwoByteString(character_count_); |
+ RETURN_IF_EMPTY_HANDLE_VALUE(heap_->isolate(), seq, Handle<String>()); |
DisallowHeapAllocation no_gc; |
uc16* char_buffer = seq->GetChars(); |
StringBuilderConcatHelper(*subject_, |
@@ -3429,9 +3425,11 @@ class ReplacementStringBuilder { |
void IncrementCharacterCount(int by) { |
if (character_count_ > String::kMaxLength - by) { |
- overflowed_ = true; |
+ STATIC_ASSERT(String::kMaxLength < kMaxInt); |
+ character_count_ = kMaxInt; |
+ } else { |
+ character_count_ += by; |
} |
- character_count_ += by; |
} |
private: |
@@ -3456,7 +3454,6 @@ class ReplacementStringBuilder { |
Handle<String> subject_; |
int character_count_; |
bool is_ascii_; |
- bool overflowed_; |
}; |
@@ -3913,10 +3910,13 @@ MUST_USE_RESULT static MaybeObject* StringReplaceGlobalAtomRegExpWithString( |
static_cast<int64_t>(pattern_len)) * |
static_cast<int64_t>(matches) + |
static_cast<int64_t>(subject_len); |
- if (result_len_64 > INT_MAX) { |
- v8::internal::Heap::FatalProcessOutOfMemory("invalid string length", true); |
+ int result_len; |
+ if (result_len_64 > static_cast<int64_t>(String::kMaxLength)) { |
+ STATIC_ASSERT(String::kMaxLength < kMaxInt); |
+ result_len = kMaxInt; // Provoke exception. |
+ } else { |
+ result_len = static_cast<int>(result_len_64); |
} |
- int result_len = static_cast<int>(result_len_64); |
int subject_pos = 0; |
int result_pos = 0; |
@@ -3929,6 +3929,7 @@ MUST_USE_RESULT static MaybeObject* StringReplaceGlobalAtomRegExpWithString( |
result = Handle<ResultSeqString>::cast( |
isolate->factory()->NewRawTwoByteString(result_len)); |
} |
+ RETURN_IF_EMPTY_HANDLE(isolate, result); |
for (int i = 0; i < matches; i++) { |
// Copy non-matched subject content. |
@@ -4108,6 +4109,7 @@ MUST_USE_RESULT static MaybeObject* StringReplaceGlobalRegExpWithEmptyString( |
answer = Handle<ResultSeqString>::cast( |
isolate->factory()->NewRawTwoByteString(new_length)); |
} |
+ ASSERT(!answer.is_null()); |
int prev = 0; |
int position = 0; |
@@ -6558,7 +6560,7 @@ MUST_USE_RESULT static MaybeObject* ConvertCase( |
if (s->IsOneByteRepresentationUnderneath()) { |
Handle<SeqOneByteString> result = |
isolate->factory()->NewRawOneByteString(length); |
- |
+ ASSERT(!result.is_null()); // Same length as input. |
DisallowHeapAllocation no_gc; |
String::FlatContent flat_content = s->GetFlatContent(); |
ASSERT(flat_content.IsFlat()); |
@@ -6578,6 +6580,8 @@ MUST_USE_RESULT static MaybeObject* ConvertCase( |
} else { |
result = isolate->factory()->NewRawTwoByteString(length); |
} |
+ ASSERT(!result.is_null()); // Same length as input. |
+ |
MaybeObject* maybe = ConvertCaseHelper(isolate, *s, *result, length, mapping); |
Object* answer; |
if (!maybe->ToObject(&answer)) return maybe; |
@@ -6591,6 +6595,7 @@ MUST_USE_RESULT static MaybeObject* ConvertCase( |
if (length < 0) length = -length; |
result = isolate->factory()->NewRawTwoByteString(length); |
} |
+ RETURN_IF_EMPTY_HANDLE(isolate, result); |
return ConvertCaseHelper(isolate, *s, *result, length, mapping); |
} |
@@ -7235,13 +7240,16 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_StringBuilderJoin) { |
String* element = String::cast(element_obj); |
int increment = element->length(); |
if (increment > String::kMaxLength - length) { |
- return isolate->ThrowInvalidStringLength(); |
+ STATIC_ASSERT(String::kMaxLength < kMaxInt); |
+ length = kMaxInt; // Provoke exception; |
+ break; |
} |
length += increment; |
} |
Handle<SeqTwoByteString> answer = |
isolate->factory()->NewRawTwoByteString(length); |
+ RETURN_IF_EMPTY_HANDLE(isolate, answer); |
DisallowHeapAllocation no_gc; |
@@ -9486,8 +9494,9 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_ThrowMessage) { |
CONVERT_SMI_ARG_CHECKED(message_id, 0); |
const char* message = GetBailoutReason( |
static_cast<BailoutReason>(message_id)); |
- Handle<Name> message_handle = |
+ Handle<String> message_handle = |
isolate->factory()->NewStringFromAscii(CStrVector(message)); |
+ RETURN_IF_EMPTY_HANDLE(isolate, message_handle); |
return isolate->Throw(*message_handle); |
} |