Index: src/runtime.cc |
diff --git a/src/runtime.cc b/src/runtime.cc |
index 762b7a58b9f28fea2dd57f0d6b3f35bdfd7971cd..85b47cab2afc4f4df0bc81b84b185e3ff6f1c2a4 100644 |
--- a/src/runtime.cc |
+++ b/src/runtime.cc |
@@ -3330,7 +3330,8 @@ class ReplacementStringBuilder { |
array_builder_(heap->isolate(), estimated_part_count), |
subject_(subject), |
character_count_(0), |
- is_ascii_(subject->IsOneByteRepresentation()) { |
+ is_ascii_(subject->IsOneByteRepresentation()), |
+ overflowed_(false) { |
// Require a non-zero initial size. Ensures that doubling the size to |
// extend the array will work. |
ASSERT(estimated_part_count > 0); |
@@ -3378,6 +3379,11 @@ class ReplacementStringBuilder { |
Handle<String> ToString() { |
+ if (overflowed_) { |
+ heap_->isolate()->ThrowInvalidStringLength(); |
+ return Handle<String>(); |
+ } |
+ |
if (array_builder_.length() == 0) { |
return heap_->isolate()->factory()->empty_string(); |
} |
@@ -3409,7 +3415,7 @@ class ReplacementStringBuilder { |
void IncrementCharacterCount(int by) { |
if (character_count_ > String::kMaxLength - by) { |
- V8::FatalProcessOutOfMemory("String.replace result too large."); |
+ overflowed_ = true; |
} |
character_count_ += by; |
} |
@@ -3436,6 +3442,7 @@ class ReplacementStringBuilder { |
Handle<String> subject_; |
int character_count_; |
bool is_ascii_; |
+ bool overflowed_; |
}; |
@@ -4034,7 +4041,9 @@ MUST_USE_RESULT static MaybeObject* StringReplaceGlobalRegExpWithString( |
capture_count, |
global_cache.LastSuccessfulMatch()); |
- return *(builder.ToString()); |
+ Handle<String> result = builder.ToString(); |
+ RETURN_IF_EMPTY_HANDLE(isolate, result); |
+ return *result; |
} |
@@ -4180,8 +4189,8 @@ Handle<String> StringReplaceOneCharWithString(Isolate* isolate, |
replace, |
found, |
recursion_limit - 1); |
- if (*found) return isolate->factory()->NewConsString(new_first, second); |
if (new_first.is_null()) return new_first; |
+ if (*found) return isolate->factory()->NewConsString(new_first, second); |
Handle<String> new_second = |
StringReplaceOneCharWithString(isolate, |
@@ -4190,8 +4199,8 @@ Handle<String> StringReplaceOneCharWithString(Isolate* isolate, |
replace, |
found, |
recursion_limit - 1); |
- if (*found) return isolate->factory()->NewConsString(first, new_second); |
if (new_second.is_null()) return new_second; |
+ if (*found) return isolate->factory()->NewConsString(first, new_second); |
return subject; |
} else { |
@@ -4200,6 +4209,7 @@ Handle<String> StringReplaceOneCharWithString(Isolate* isolate, |
*found = true; |
Handle<String> first = isolate->factory()->NewSubString(subject, 0, index); |
Handle<String> cons1 = isolate->factory()->NewConsString(first, replace); |
+ RETURN_IF_EMPTY_HANDLE_VALUE(isolate, cons1, Handle<String>()); |
Handle<String> second = |
isolate->factory()->NewSubString(subject, index + 1, subject->length()); |
return isolate->factory()->NewConsString(cons1, second); |
@@ -4225,6 +4235,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_StringReplaceOneCharWithString) { |
&found, |
kRecursionLimit); |
if (!result.is_null()) return *result; |
+ if (isolate->has_pending_exception()) return Failure::Exception(); |
return *StringReplaceOneCharWithString(isolate, |
FlattenGetString(subject), |
search, |
@@ -6225,7 +6236,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_URIEscape) { |
Handle<String> result = string->IsOneByteRepresentationUnderneath() |
? URIEscape::Escape<uint8_t>(isolate, source) |
: URIEscape::Escape<uc16>(isolate, source); |
- if (result.is_null()) return Failure::OutOfMemoryException(0x12); |
+ RETURN_IF_EMPTY_HANDLE(isolate, result); |
return *result; |
} |
@@ -6359,9 +6370,8 @@ MUST_USE_RESULT static MaybeObject* ConvertCaseHelper( |
int char_length = mapping->get(current, 0, chars); |
if (char_length == 0) char_length = 1; |
current_length += char_length; |
- if (current_length > Smi::kMaxValue) { |
- isolate->context()->mark_out_of_memory(); |
- return Failure::OutOfMemoryException(0x13); |
+ if (current_length > String::kMaxLength) { |
+ return isolate->ThrowInvalidStringLength(); |
} |
} |
// Try again with the real length. Return signed if we need |
@@ -7016,7 +7026,9 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_StringAdd) { |
CONVERT_ARG_HANDLE_CHECKED(String, str1, 0); |
CONVERT_ARG_HANDLE_CHECKED(String, str2, 1); |
isolate->counters()->string_add_runtime()->Increment(); |
- return *isolate->factory()->NewConsString(str1, str2); |
+ Handle<String> result = isolate->factory()->NewConsString(str1, str2); |
+ RETURN_IF_EMPTY_HANDLE(isolate, result); |
+ return *result; |
} |
@@ -7063,10 +7075,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_StringBuilderConcat) { |
HandleScope scope(isolate); |
ASSERT(args.length() == 3); |
CONVERT_ARG_HANDLE_CHECKED(JSArray, array, 0); |
- if (!args[1]->IsSmi()) { |
- isolate->context()->mark_out_of_memory(); |
- return Failure::OutOfMemoryException(0x14); |
- } |
+ if (!args[1]->IsSmi()) return isolate->ThrowInvalidStringLength(); |
int array_length = args.smi_at(1); |
CONVERT_ARG_HANDLE_CHECKED(String, special, 2); |
@@ -7140,8 +7149,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_StringBuilderConcat) { |
return isolate->Throw(isolate->heap()->illegal_argument_string()); |
} |
if (increment > String::kMaxLength - position) { |
- isolate->context()->mark_out_of_memory(); |
- return Failure::OutOfMemoryException(0x15); |
+ return isolate->ThrowInvalidStringLength(); |
} |
position += increment; |
} |
@@ -7179,10 +7187,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_StringBuilderJoin) { |
SealHandleScope shs(isolate); |
ASSERT(args.length() == 3); |
CONVERT_ARG_CHECKED(JSArray, array, 0); |
- if (!args[1]->IsSmi()) { |
- isolate->context()->mark_out_of_memory(); |
- return Failure::OutOfMemoryException(0x16); |
- } |
+ if (!args[1]->IsSmi()) return isolate->ThrowInvalidStringLength(); |
int array_length = args.smi_at(1); |
CONVERT_ARG_CHECKED(String, separator, 2); |
@@ -7205,8 +7210,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_StringBuilderJoin) { |
int max_nof_separators = |
(String::kMaxLength + separator_length - 1) / separator_length; |
if (max_nof_separators < (array_length - 1)) { |
- isolate->context()->mark_out_of_memory(); |
- return Failure::OutOfMemoryException(0x17); |
+ return isolate->ThrowInvalidStringLength(); |
} |
int length = (array_length - 1) * separator_length; |
for (int i = 0; i < array_length; i++) { |
@@ -7218,8 +7222,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_StringBuilderJoin) { |
String* element = String::cast(element_obj); |
int increment = element->length(); |
if (increment > String::kMaxLength - length) { |
- isolate->context()->mark_out_of_memory(); |
- return Failure::OutOfMemoryException(0x18); |
+ return isolate->ThrowInvalidStringLength(); |
} |
length += increment; |
} |
@@ -7357,9 +7360,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_SparseJoinWithSeparator) { |
// Throw an exception if the resulting string is too large. See |
// https://code.google.com/p/chromium/issues/detail?id=336820 |
// for details. |
- return isolate->Throw(*isolate->factory()-> |
- NewRangeError("invalid_string_length", |
- HandleVector<Object>(NULL, 0))); |
+ return isolate->ThrowInvalidStringLength(); |
} |
if (is_ascii) { |