| 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 1786 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1797 // Map has changed, so use generic, but slower, method. | 1797 // Map has changed, so use generic, but slower, method. |
| 1798 PropertyAttributes final = | 1798 PropertyAttributes final = |
| 1799 static_cast<PropertyAttributes>(READ_ONLY | DONT_ENUM | DONT_DELETE); | 1799 static_cast<PropertyAttributes>(READ_ONLY | DONT_ENUM | DONT_DELETE); |
| 1800 PropertyAttributes writable = | 1800 PropertyAttributes writable = |
| 1801 static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE); | 1801 static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE); |
| 1802 Heap* heap = isolate->heap(); | 1802 Heap* heap = isolate->heap(); |
| 1803 MaybeObject* result; | 1803 MaybeObject* result; |
| 1804 result = regexp->SetLocalPropertyIgnoreAttributes(heap->source_symbol(), | 1804 result = regexp->SetLocalPropertyIgnoreAttributes(heap->source_symbol(), |
| 1805 source, | 1805 source, |
| 1806 final); | 1806 final); |
| 1807 ASSERT(!result->IsFailure()); | 1807 // TODO(jkummerow): Turn these back into ASSERTs when we can be certain |
| 1808 // that it never fires in Release mode in the wild. |
| 1809 CHECK(!result->IsFailure()); |
| 1808 result = regexp->SetLocalPropertyIgnoreAttributes(heap->global_symbol(), | 1810 result = regexp->SetLocalPropertyIgnoreAttributes(heap->global_symbol(), |
| 1809 global, | 1811 global, |
| 1810 final); | 1812 final); |
| 1811 ASSERT(!result->IsFailure()); | 1813 CHECK(!result->IsFailure()); |
| 1812 result = | 1814 result = |
| 1813 regexp->SetLocalPropertyIgnoreAttributes(heap->ignore_case_symbol(), | 1815 regexp->SetLocalPropertyIgnoreAttributes(heap->ignore_case_symbol(), |
| 1814 ignoreCase, | 1816 ignoreCase, |
| 1815 final); | 1817 final); |
| 1816 ASSERT(!result->IsFailure()); | 1818 CHECK(!result->IsFailure()); |
| 1817 result = regexp->SetLocalPropertyIgnoreAttributes(heap->multiline_symbol(), | 1819 result = regexp->SetLocalPropertyIgnoreAttributes(heap->multiline_symbol(), |
| 1818 multiline, | 1820 multiline, |
| 1819 final); | 1821 final); |
| 1820 ASSERT(!result->IsFailure()); | 1822 CHECK(!result->IsFailure()); |
| 1821 result = | 1823 result = |
| 1822 regexp->SetLocalPropertyIgnoreAttributes(heap->last_index_symbol(), | 1824 regexp->SetLocalPropertyIgnoreAttributes(heap->last_index_symbol(), |
| 1823 Smi::FromInt(0), | 1825 Smi::FromInt(0), |
| 1824 writable); | 1826 writable); |
| 1825 ASSERT(!result->IsFailure()); | 1827 CHECK(!result->IsFailure()); |
| 1826 USE(result); | 1828 USE(result); |
| 1827 return regexp; | 1829 return regexp; |
| 1828 } | 1830 } |
| 1829 | 1831 |
| 1830 | 1832 |
| 1831 RUNTIME_FUNCTION(MaybeObject*, Runtime_FinishArrayPrototypeSetup) { | 1833 RUNTIME_FUNCTION(MaybeObject*, Runtime_FinishArrayPrototypeSetup) { |
| 1832 HandleScope scope(isolate); | 1834 HandleScope scope(isolate); |
| 1833 ASSERT(args.length() == 1); | 1835 ASSERT(args.length() == 1); |
| 1834 CONVERT_ARG_HANDLE_CHECKED(JSArray, prototype, 0); | 1836 CONVERT_ARG_HANDLE_CHECKED(JSArray, prototype, 0); |
| 1835 // This is necessary to enable fast checks for absence of elements | 1837 // This is necessary to enable fast checks for absence of elements |
| (...skipping 1070 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2906 pattern_regexp->ResetLastIndex(); | 2908 pattern_regexp->ResetLastIndex(); |
| 2907 return *subject; | 2909 return *subject; |
| 2908 } | 2910 } |
| 2909 | 2911 |
| 2910 // Detect integer overflow. | 2912 // Detect integer overflow. |
| 2911 int64_t result_len_64 = | 2913 int64_t result_len_64 = |
| 2912 (static_cast<int64_t>(replacement_len) - | 2914 (static_cast<int64_t>(replacement_len) - |
| 2913 static_cast<int64_t>(pattern_len)) * | 2915 static_cast<int64_t>(pattern_len)) * |
| 2914 static_cast<int64_t>(matches) + | 2916 static_cast<int64_t>(matches) + |
| 2915 static_cast<int64_t>(subject_len); | 2917 static_cast<int64_t>(subject_len); |
| 2916 if (result_len_64 > INT_MAX) return Failure::OutOfMemoryException(); | 2918 if (result_len_64 > INT_MAX) return Failure::OutOfMemoryException(0x11); |
| 2917 int result_len = static_cast<int>(result_len_64); | 2919 int result_len = static_cast<int>(result_len_64); |
| 2918 | 2920 |
| 2919 int subject_pos = 0; | 2921 int subject_pos = 0; |
| 2920 int result_pos = 0; | 2922 int result_pos = 0; |
| 2921 | 2923 |
| 2922 Handle<ResultSeqString> result; | 2924 Handle<ResultSeqString> result; |
| 2923 if (ResultSeqString::kHasAsciiEncoding) { | 2925 if (ResultSeqString::kHasAsciiEncoding) { |
| 2924 result = Handle<ResultSeqString>::cast( | 2926 result = Handle<ResultSeqString>::cast( |
| 2925 isolate->factory()->NewRawOneByteString(result_len)); | 2927 isolate->factory()->NewRawOneByteString(result_len)); |
| 2926 } else { | 2928 } else { |
| (...skipping 2225 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5152 escaped_length += 6; | 5154 escaped_length += 6; |
| 5153 } else if (IsNotEscaped(character)) { | 5155 } else if (IsNotEscaped(character)) { |
| 5154 escaped_length++; | 5156 escaped_length++; |
| 5155 } else { | 5157 } else { |
| 5156 escaped_length += 3; | 5158 escaped_length += 3; |
| 5157 } | 5159 } |
| 5158 // We don't allow strings that are longer than a maximal length. | 5160 // We don't allow strings that are longer than a maximal length. |
| 5159 ASSERT(String::kMaxLength < 0x7fffffff - 6); // Cannot overflow. | 5161 ASSERT(String::kMaxLength < 0x7fffffff - 6); // Cannot overflow. |
| 5160 if (escaped_length > String::kMaxLength) { | 5162 if (escaped_length > String::kMaxLength) { |
| 5161 isolate->context()->mark_out_of_memory(); | 5163 isolate->context()->mark_out_of_memory(); |
| 5162 return Failure::OutOfMemoryException(); | 5164 return Failure::OutOfMemoryException(0x12); |
| 5163 } | 5165 } |
| 5164 } | 5166 } |
| 5165 } | 5167 } |
| 5166 // No length change implies no change. Return original string if no change. | 5168 // No length change implies no change. Return original string if no change. |
| 5167 if (escaped_length == length) { | 5169 if (escaped_length == length) { |
| 5168 return source; | 5170 return source; |
| 5169 } | 5171 } |
| 5170 Object* o; | 5172 Object* o; |
| 5171 { MaybeObject* maybe_o = | 5173 { MaybeObject* maybe_o = |
| 5172 isolate->heap()->AllocateRawOneByteString(escaped_length); | 5174 isolate->heap()->AllocateRawOneByteString(escaped_length); |
| (...skipping 586 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5759 current = stream.GetNext(); | 5761 current = stream.GetNext(); |
| 5760 // NOTE: we use 0 as the next character here because, while | 5762 // NOTE: we use 0 as the next character here because, while |
| 5761 // the next character may affect what a character converts to, | 5763 // the next character may affect what a character converts to, |
| 5762 // it does not in any case affect the length of what it convert | 5764 // it does not in any case affect the length of what it convert |
| 5763 // to. | 5765 // to. |
| 5764 int char_length = mapping->get(current, 0, chars); | 5766 int char_length = mapping->get(current, 0, chars); |
| 5765 if (char_length == 0) char_length = 1; | 5767 if (char_length == 0) char_length = 1; |
| 5766 current_length += char_length; | 5768 current_length += char_length; |
| 5767 if (current_length > Smi::kMaxValue) { | 5769 if (current_length > Smi::kMaxValue) { |
| 5768 isolate->context()->mark_out_of_memory(); | 5770 isolate->context()->mark_out_of_memory(); |
| 5769 return Failure::OutOfMemoryException(); | 5771 return Failure::OutOfMemoryException(0x13); |
| 5770 } | 5772 } |
| 5771 } | 5773 } |
| 5772 // Try again with the real length. | 5774 // Try again with the real length. |
| 5773 return Smi::FromInt(current_length); | 5775 return Smi::FromInt(current_length); |
| 5774 } else { | 5776 } else { |
| 5775 for (int j = 0; j < char_length; j++) { | 5777 for (int j = 0; j < char_length; j++) { |
| 5776 result->Set(i, chars[j]); | 5778 result->Set(i, chars[j]); |
| 5777 i++; | 5779 i++; |
| 5778 } | 5780 } |
| 5779 has_changed_character = true; | 5781 has_changed_character = true; |
| (...skipping 647 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6427 } | 6429 } |
| 6428 } | 6430 } |
| 6429 | 6431 |
| 6430 | 6432 |
| 6431 RUNTIME_FUNCTION(MaybeObject*, Runtime_StringBuilderConcat) { | 6433 RUNTIME_FUNCTION(MaybeObject*, Runtime_StringBuilderConcat) { |
| 6432 NoHandleAllocation ha; | 6434 NoHandleAllocation ha; |
| 6433 ASSERT(args.length() == 3); | 6435 ASSERT(args.length() == 3); |
| 6434 CONVERT_ARG_CHECKED(JSArray, array, 0); | 6436 CONVERT_ARG_CHECKED(JSArray, array, 0); |
| 6435 if (!args[1]->IsSmi()) { | 6437 if (!args[1]->IsSmi()) { |
| 6436 isolate->context()->mark_out_of_memory(); | 6438 isolate->context()->mark_out_of_memory(); |
| 6437 return Failure::OutOfMemoryException(); | 6439 return Failure::OutOfMemoryException(0x14); |
| 6438 } | 6440 } |
| 6439 int array_length = args.smi_at(1); | 6441 int array_length = args.smi_at(1); |
| 6440 CONVERT_ARG_CHECKED(String, special, 2); | 6442 CONVERT_ARG_CHECKED(String, special, 2); |
| 6441 | 6443 |
| 6442 // This assumption is used by the slice encoding in one or two smis. | 6444 // This assumption is used by the slice encoding in one or two smis. |
| 6443 ASSERT(Smi::kMaxValue >= String::kMaxLength); | 6445 ASSERT(Smi::kMaxValue >= String::kMaxLength); |
| 6444 | 6446 |
| 6445 MaybeObject* maybe_result = array->EnsureCanContainHeapObjectElements(); | 6447 MaybeObject* maybe_result = array->EnsureCanContainHeapObjectElements(); |
| 6446 if (maybe_result->IsFailure()) return maybe_result; | 6448 if (maybe_result->IsFailure()) return maybe_result; |
| 6447 | 6449 |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6504 increment = element_length; | 6506 increment = element_length; |
| 6505 if (ascii && !element->HasOnlyAsciiChars()) { | 6507 if (ascii && !element->HasOnlyAsciiChars()) { |
| 6506 ascii = false; | 6508 ascii = false; |
| 6507 } | 6509 } |
| 6508 } else { | 6510 } else { |
| 6509 ASSERT(!elt->IsTheHole()); | 6511 ASSERT(!elt->IsTheHole()); |
| 6510 return isolate->Throw(isolate->heap()->illegal_argument_symbol()); | 6512 return isolate->Throw(isolate->heap()->illegal_argument_symbol()); |
| 6511 } | 6513 } |
| 6512 if (increment > String::kMaxLength - position) { | 6514 if (increment > String::kMaxLength - position) { |
| 6513 isolate->context()->mark_out_of_memory(); | 6515 isolate->context()->mark_out_of_memory(); |
| 6514 return Failure::OutOfMemoryException(); | 6516 return Failure::OutOfMemoryException(0x15); |
| 6515 } | 6517 } |
| 6516 position += increment; | 6518 position += increment; |
| 6517 } | 6519 } |
| 6518 | 6520 |
| 6519 int length = position; | 6521 int length = position; |
| 6520 Object* object; | 6522 Object* object; |
| 6521 | 6523 |
| 6522 if (ascii) { | 6524 if (ascii) { |
| 6523 { MaybeObject* maybe_object = | 6525 { MaybeObject* maybe_object = |
| 6524 isolate->heap()->AllocateRawOneByteString(length); | 6526 isolate->heap()->AllocateRawOneByteString(length); |
| (...skipping 19 matching lines...) Expand all Loading... |
| 6544 } | 6546 } |
| 6545 } | 6547 } |
| 6546 | 6548 |
| 6547 | 6549 |
| 6548 RUNTIME_FUNCTION(MaybeObject*, Runtime_StringBuilderJoin) { | 6550 RUNTIME_FUNCTION(MaybeObject*, Runtime_StringBuilderJoin) { |
| 6549 NoHandleAllocation ha; | 6551 NoHandleAllocation ha; |
| 6550 ASSERT(args.length() == 3); | 6552 ASSERT(args.length() == 3); |
| 6551 CONVERT_ARG_CHECKED(JSArray, array, 0); | 6553 CONVERT_ARG_CHECKED(JSArray, array, 0); |
| 6552 if (!args[1]->IsSmi()) { | 6554 if (!args[1]->IsSmi()) { |
| 6553 isolate->context()->mark_out_of_memory(); | 6555 isolate->context()->mark_out_of_memory(); |
| 6554 return Failure::OutOfMemoryException(); | 6556 return Failure::OutOfMemoryException(0x16); |
| 6555 } | 6557 } |
| 6556 int array_length = args.smi_at(1); | 6558 int array_length = args.smi_at(1); |
| 6557 CONVERT_ARG_CHECKED(String, separator, 2); | 6559 CONVERT_ARG_CHECKED(String, separator, 2); |
| 6558 | 6560 |
| 6559 if (!array->HasFastObjectElements()) { | 6561 if (!array->HasFastObjectElements()) { |
| 6560 return isolate->Throw(isolate->heap()->illegal_argument_symbol()); | 6562 return isolate->Throw(isolate->heap()->illegal_argument_symbol()); |
| 6561 } | 6563 } |
| 6562 FixedArray* fixed_array = FixedArray::cast(array->elements()); | 6564 FixedArray* fixed_array = FixedArray::cast(array->elements()); |
| 6563 if (fixed_array->length() < array_length) { | 6565 if (fixed_array->length() < array_length) { |
| 6564 array_length = fixed_array->length(); | 6566 array_length = fixed_array->length(); |
| 6565 } | 6567 } |
| 6566 | 6568 |
| 6567 if (array_length == 0) { | 6569 if (array_length == 0) { |
| 6568 return isolate->heap()->empty_string(); | 6570 return isolate->heap()->empty_string(); |
| 6569 } else if (array_length == 1) { | 6571 } else if (array_length == 1) { |
| 6570 Object* first = fixed_array->get(0); | 6572 Object* first = fixed_array->get(0); |
| 6571 if (first->IsString()) return first; | 6573 if (first->IsString()) return first; |
| 6572 } | 6574 } |
| 6573 | 6575 |
| 6574 int separator_length = separator->length(); | 6576 int separator_length = separator->length(); |
| 6575 int max_nof_separators = | 6577 int max_nof_separators = |
| 6576 (String::kMaxLength + separator_length - 1) / separator_length; | 6578 (String::kMaxLength + separator_length - 1) / separator_length; |
| 6577 if (max_nof_separators < (array_length - 1)) { | 6579 if (max_nof_separators < (array_length - 1)) { |
| 6578 isolate->context()->mark_out_of_memory(); | 6580 isolate->context()->mark_out_of_memory(); |
| 6579 return Failure::OutOfMemoryException(); | 6581 return Failure::OutOfMemoryException(0x17); |
| 6580 } | 6582 } |
| 6581 int length = (array_length - 1) * separator_length; | 6583 int length = (array_length - 1) * separator_length; |
| 6582 for (int i = 0; i < array_length; i++) { | 6584 for (int i = 0; i < array_length; i++) { |
| 6583 Object* element_obj = fixed_array->get(i); | 6585 Object* element_obj = fixed_array->get(i); |
| 6584 if (!element_obj->IsString()) { | 6586 if (!element_obj->IsString()) { |
| 6585 // TODO(1161): handle this case. | 6587 // TODO(1161): handle this case. |
| 6586 return isolate->Throw(isolate->heap()->illegal_argument_symbol()); | 6588 return isolate->Throw(isolate->heap()->illegal_argument_symbol()); |
| 6587 } | 6589 } |
| 6588 String* element = String::cast(element_obj); | 6590 String* element = String::cast(element_obj); |
| 6589 int increment = element->length(); | 6591 int increment = element->length(); |
| 6590 if (increment > String::kMaxLength - length) { | 6592 if (increment > String::kMaxLength - length) { |
| 6591 isolate->context()->mark_out_of_memory(); | 6593 isolate->context()->mark_out_of_memory(); |
| 6592 return Failure::OutOfMemoryException(); | 6594 return Failure::OutOfMemoryException(0x18); |
| 6593 } | 6595 } |
| 6594 length += increment; | 6596 length += increment; |
| 6595 } | 6597 } |
| 6596 | 6598 |
| 6597 Object* object; | 6599 Object* object; |
| 6598 { MaybeObject* maybe_object = | 6600 { MaybeObject* maybe_object = |
| 6599 isolate->heap()->AllocateRawTwoByteString(length); | 6601 isolate->heap()->AllocateRawTwoByteString(length); |
| 6600 if (!maybe_object->ToObject(&object)) return maybe_object; | 6602 if (!maybe_object->ToObject(&object)) return maybe_object; |
| 6601 } | 6603 } |
| 6602 SeqTwoByteString* answer = SeqTwoByteString::cast(object); | 6604 SeqTwoByteString* answer = SeqTwoByteString::cast(object); |
| (...skipping 7017 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 13620 // Handle last resort GC and make sure to allow future allocations | 13622 // Handle last resort GC and make sure to allow future allocations |
| 13621 // to grow the heap without causing GCs (if possible). | 13623 // to grow the heap without causing GCs (if possible). |
| 13622 isolate->counters()->gc_last_resort_from_js()->Increment(); | 13624 isolate->counters()->gc_last_resort_from_js()->Increment(); |
| 13623 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags, | 13625 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags, |
| 13624 "Runtime::PerformGC"); | 13626 "Runtime::PerformGC"); |
| 13625 } | 13627 } |
| 13626 } | 13628 } |
| 13627 | 13629 |
| 13628 | 13630 |
| 13629 } } // namespace v8::internal | 13631 } } // namespace v8::internal |
| OLD | NEW |