| Index: src/runtime.cc
|
| diff --git a/src/runtime.cc b/src/runtime.cc
|
| index 00bbdfd40bcc7d0a013598ffb8c7ed747c2bf7dd..762b7a58b9f28fea2dd57f0d6b3f35bdfd7971cd 100644
|
| --- a/src/runtime.cc
|
| +++ b/src/runtime.cc
|
| @@ -3330,8 +3330,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);
|
| @@ -3379,11 +3378,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();
|
| }
|
| @@ -3415,7 +3409,7 @@ class ReplacementStringBuilder {
|
|
|
| void IncrementCharacterCount(int by) {
|
| if (character_count_ > String::kMaxLength - by) {
|
| - overflowed_ = true;
|
| + V8::FatalProcessOutOfMemory("String.replace result too large.");
|
| }
|
| character_count_ += by;
|
| }
|
| @@ -3442,7 +3436,6 @@ class ReplacementStringBuilder {
|
| Handle<String> subject_;
|
| int character_count_;
|
| bool is_ascii_;
|
| - bool overflowed_;
|
| };
|
|
|
|
|
| @@ -4041,9 +4034,7 @@ MUST_USE_RESULT static MaybeObject* StringReplaceGlobalRegExpWithString(
|
| capture_count,
|
| global_cache.LastSuccessfulMatch());
|
|
|
| - Handle<String> result = builder.ToString();
|
| - RETURN_IF_EMPTY_HANDLE(isolate, result);
|
| - return *result;
|
| + return *(builder.ToString());
|
| }
|
|
|
|
|
| @@ -4189,8 +4180,8 @@ Handle<String> StringReplaceOneCharWithString(Isolate* isolate,
|
| replace,
|
| found,
|
| recursion_limit - 1);
|
| - if (new_first.is_null()) return new_first;
|
| if (*found) return isolate->factory()->NewConsString(new_first, second);
|
| + if (new_first.is_null()) return new_first;
|
|
|
| Handle<String> new_second =
|
| StringReplaceOneCharWithString(isolate,
|
| @@ -4199,8 +4190,8 @@ Handle<String> StringReplaceOneCharWithString(Isolate* isolate,
|
| replace,
|
| found,
|
| recursion_limit - 1);
|
| - if (new_second.is_null()) return new_second;
|
| if (*found) return isolate->factory()->NewConsString(first, new_second);
|
| + if (new_second.is_null()) return new_second;
|
|
|
| return subject;
|
| } else {
|
| @@ -4209,7 +4200,6 @@ 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);
|
| @@ -4235,7 +4225,6 @@ 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,
|
| @@ -6236,7 +6225,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_URIEscape) {
|
| Handle<String> result = string->IsOneByteRepresentationUnderneath()
|
| ? URIEscape::Escape<uint8_t>(isolate, source)
|
| : URIEscape::Escape<uc16>(isolate, source);
|
| - RETURN_IF_EMPTY_HANDLE(isolate, result);
|
| + if (result.is_null()) return Failure::OutOfMemoryException(0x12);
|
| return *result;
|
| }
|
|
|
| @@ -6370,9 +6359,9 @@ 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 > String::kMaxLength) {
|
| - AllowHeapAllocation allocate_error_and_return;
|
| - return isolate->ThrowInvalidStringLength();
|
| + if (current_length > Smi::kMaxValue) {
|
| + isolate->context()->mark_out_of_memory();
|
| + return Failure::OutOfMemoryException(0x13);
|
| }
|
| }
|
| // Try again with the real length. Return signed if we need
|
| @@ -7027,9 +7016,7 @@ 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();
|
| - Handle<String> result = isolate->factory()->NewConsString(str1, str2);
|
| - RETURN_IF_EMPTY_HANDLE(isolate, result);
|
| - return *result;
|
| + return *isolate->factory()->NewConsString(str1, str2);
|
| }
|
|
|
|
|
| @@ -7076,7 +7063,10 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_StringBuilderConcat) {
|
| HandleScope scope(isolate);
|
| ASSERT(args.length() == 3);
|
| CONVERT_ARG_HANDLE_CHECKED(JSArray, array, 0);
|
| - if (!args[1]->IsSmi()) return isolate->ThrowInvalidStringLength();
|
| + if (!args[1]->IsSmi()) {
|
| + isolate->context()->mark_out_of_memory();
|
| + return Failure::OutOfMemoryException(0x14);
|
| + }
|
| int array_length = args.smi_at(1);
|
| CONVERT_ARG_HANDLE_CHECKED(String, special, 2);
|
|
|
| @@ -7150,7 +7140,8 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_StringBuilderConcat) {
|
| return isolate->Throw(isolate->heap()->illegal_argument_string());
|
| }
|
| if (increment > String::kMaxLength - position) {
|
| - return isolate->ThrowInvalidStringLength();
|
| + isolate->context()->mark_out_of_memory();
|
| + return Failure::OutOfMemoryException(0x15);
|
| }
|
| position += increment;
|
| }
|
| @@ -7185,15 +7176,20 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_StringBuilderConcat) {
|
|
|
|
|
| RUNTIME_FUNCTION(MaybeObject*, Runtime_StringBuilderJoin) {
|
| - HandleScope scope(isolate);
|
| + SealHandleScope shs(isolate);
|
| ASSERT(args.length() == 3);
|
| - CONVERT_ARG_HANDLE_CHECKED(JSArray, array, 0);
|
| - if (!args[1]->IsSmi()) return isolate->ThrowInvalidStringLength();
|
| + CONVERT_ARG_CHECKED(JSArray, array, 0);
|
| + if (!args[1]->IsSmi()) {
|
| + isolate->context()->mark_out_of_memory();
|
| + return Failure::OutOfMemoryException(0x16);
|
| + }
|
| int array_length = args.smi_at(1);
|
| - CONVERT_ARG_HANDLE_CHECKED(String, separator, 2);
|
| - RUNTIME_ASSERT(array->HasFastObjectElements());
|
| + CONVERT_ARG_CHECKED(String, separator, 2);
|
|
|
| - Handle<FixedArray> fixed_array(FixedArray::cast(array->elements()));
|
| + if (!array->HasFastObjectElements()) {
|
| + return isolate->Throw(isolate->heap()->illegal_argument_string());
|
| + }
|
| + FixedArray* fixed_array = FixedArray::cast(array->elements());
|
| if (fixed_array->length() < array_length) {
|
| array_length = fixed_array->length();
|
| }
|
| @@ -7202,32 +7198,38 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_StringBuilderJoin) {
|
| return isolate->heap()->empty_string();
|
| } else if (array_length == 1) {
|
| Object* first = fixed_array->get(0);
|
| - RUNTIME_ASSERT(first->IsString());
|
| - return first;
|
| + if (first->IsString()) return first;
|
| }
|
|
|
| int separator_length = separator->length();
|
| int max_nof_separators =
|
| (String::kMaxLength + separator_length - 1) / separator_length;
|
| if (max_nof_separators < (array_length - 1)) {
|
| - return isolate->ThrowInvalidStringLength();
|
| + isolate->context()->mark_out_of_memory();
|
| + return Failure::OutOfMemoryException(0x17);
|
| }
|
| int length = (array_length - 1) * separator_length;
|
| for (int i = 0; i < array_length; i++) {
|
| Object* element_obj = fixed_array->get(i);
|
| - RUNTIME_ASSERT(element_obj->IsString());
|
| + if (!element_obj->IsString()) {
|
| + // TODO(1161): handle this case.
|
| + return isolate->Throw(isolate->heap()->illegal_argument_string());
|
| + }
|
| String* element = String::cast(element_obj);
|
| int increment = element->length();
|
| if (increment > String::kMaxLength - length) {
|
| - return isolate->ThrowInvalidStringLength();
|
| + isolate->context()->mark_out_of_memory();
|
| + return Failure::OutOfMemoryException(0x18);
|
| }
|
| length += increment;
|
| }
|
|
|
| - Handle<SeqTwoByteString> answer =
|
| - isolate->factory()->NewRawTwoByteString(length);
|
| -
|
| - DisallowHeapAllocation no_gc;
|
| + Object* object;
|
| + { MaybeObject* maybe_object =
|
| + isolate->heap()->AllocateRawTwoByteString(length);
|
| + if (!maybe_object->ToObject(&object)) return maybe_object;
|
| + }
|
| + SeqTwoByteString* answer = SeqTwoByteString::cast(object);
|
|
|
| uc16* sink = answer->GetChars();
|
| #ifdef DEBUG
|
| @@ -7235,14 +7237,13 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_StringBuilderJoin) {
|
| #endif
|
|
|
| String* first = String::cast(fixed_array->get(0));
|
| - String* seperator_raw = *separator;
|
| int first_length = first->length();
|
| String::WriteToFlat(first, sink, 0, first_length);
|
| sink += first_length;
|
|
|
| for (int i = 1; i < array_length; i++) {
|
| ASSERT(sink + separator_length <= end);
|
| - String::WriteToFlat(seperator_raw, sink, 0, separator_length);
|
| + String::WriteToFlat(separator, sink, 0, separator_length);
|
| sink += separator_length;
|
|
|
| String* element = String::cast(fixed_array->get(i));
|
| @@ -7255,7 +7256,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_StringBuilderJoin) {
|
|
|
| // Use %_FastAsciiArrayJoin instead.
|
| ASSERT(!answer->IsOneByteRepresentation());
|
| - return *answer;
|
| + return answer;
|
| }
|
|
|
| template <typename Char>
|
| @@ -7356,7 +7357,9 @@ 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->ThrowInvalidStringLength();
|
| + return isolate->Throw(*isolate->factory()->
|
| + NewRangeError("invalid_string_length",
|
| + HandleVector<Object>(NULL, 0)));
|
| }
|
|
|
| if (is_ascii) {
|
|
|