Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(154)

Side by Side Diff: src/runtime.cc

Issue 1578036: Add missing check to StringBuilderConcat runtime function. (Closed)
Patch Set: Created 10 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | src/string.js » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2006-2009 the V8 project authors. All rights reserved. 1 // Copyright 2006-2009 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 1734 matching lines...) Expand 10 before | Expand all | Expand 10 after
1745 // Forward declarations. 1745 // Forward declarations.
1746 const int kStringBuilderConcatHelperLengthBits = 11; 1746 const int kStringBuilderConcatHelperLengthBits = 11;
1747 const int kStringBuilderConcatHelperPositionBits = 19; 1747 const int kStringBuilderConcatHelperPositionBits = 19;
1748 1748
1749 template <typename schar> 1749 template <typename schar>
1750 static inline void StringBuilderConcatHelper(String*, 1750 static inline void StringBuilderConcatHelper(String*,
1751 schar*, 1751 schar*,
1752 FixedArray*, 1752 FixedArray*,
1753 int); 1753 int);
1754 1754
1755 STATIC_ASSERT(kStringBuilderConcatHelperLengthBits +
1756 kStringBuilderConcatHelperPositionBits <= kSmiValueSize);
1755 typedef BitField<int, 0, kStringBuilderConcatHelperLengthBits> 1757 typedef BitField<int, 0, kStringBuilderConcatHelperLengthBits>
1756 StringBuilderSubstringLength; 1758 StringBuilderSubstringLength;
1757 typedef BitField<int, 1759 typedef BitField<int,
1758 kStringBuilderConcatHelperLengthBits, 1760 kStringBuilderConcatHelperLengthBits,
1759 kStringBuilderConcatHelperPositionBits> 1761 kStringBuilderConcatHelperPositionBits>
1760 StringBuilderSubstringPosition; 1762 StringBuilderSubstringPosition;
1761 1763
1762 1764
1763 class ReplacementStringBuilder { 1765 class ReplacementStringBuilder {
1764 public: 1766 public:
(...skipping 26 matching lines...) Expand all
1791 } 1793 }
1792 1794
1793 1795
1794 void EnsureCapacity(int elements) { 1796 void EnsureCapacity(int elements) {
1795 array_builder_.EnsureCapacity(elements); 1797 array_builder_.EnsureCapacity(elements);
1796 } 1798 }
1797 1799
1798 1800
1799 void AddSubjectSlice(int from, int to) { 1801 void AddSubjectSlice(int from, int to) {
1800 AddSubjectSlice(&array_builder_, from, to); 1802 AddSubjectSlice(&array_builder_, from, to);
1801 // Can we encode the slice in 11 bits for length and 19 bits for
1802 // start position - as used by StringBuilderConcatHelper?
1803 IncrementCharacterCount(to - from); 1803 IncrementCharacterCount(to - from);
1804 } 1804 }
1805 1805
1806 1806
1807 void AddString(Handle<String> string) { 1807 void AddString(Handle<String> string) {
1808 int length = string->length(); 1808 int length = string->length();
1809 ASSERT(length > 0); 1809 ASSERT(length > 0);
1810 AddElement(*string); 1810 AddElement(*string);
1811 if (!string->IsAsciiRepresentation()) { 1811 if (!string->IsAsciiRepresentation()) {
1812 is_ascii_ = false; 1812 is_ascii_ = false;
(...skipping 3607 matching lines...) Expand 10 before | Expand all | Expand 10 after
5420 static Object* Runtime_StringAdd(Arguments args) { 5420 static Object* Runtime_StringAdd(Arguments args) {
5421 NoHandleAllocation ha; 5421 NoHandleAllocation ha;
5422 ASSERT(args.length() == 2); 5422 ASSERT(args.length() == 2);
5423 CONVERT_CHECKED(String, str1, args[0]); 5423 CONVERT_CHECKED(String, str1, args[0]);
5424 CONVERT_CHECKED(String, str2, args[1]); 5424 CONVERT_CHECKED(String, str2, args[1]);
5425 Counters::string_add_runtime.Increment(); 5425 Counters::string_add_runtime.Increment();
5426 return Heap::AllocateConsString(str1, str2); 5426 return Heap::AllocateConsString(str1, str2);
5427 } 5427 }
5428 5428
5429 5429
5430 template<typename sinkchar> 5430 template <typename sinkchar>
5431 static inline void StringBuilderConcatHelper(String* special, 5431 static inline void StringBuilderConcatHelper(String* special,
5432 sinkchar* sink, 5432 sinkchar* sink,
5433 FixedArray* fixed_array, 5433 FixedArray* fixed_array,
5434 int array_length) { 5434 int array_length) {
5435 int position = 0; 5435 int position = 0;
5436 for (int i = 0; i < array_length; i++) { 5436 for (int i = 0; i < array_length; i++) {
5437 Object* element = fixed_array->get(i); 5437 Object* element = fixed_array->get(i);
5438 if (element->IsSmi()) { 5438 if (element->IsSmi()) {
5439 // Smi encoding of position and length. 5439 // Smi encoding of position and length.
5440 int encoded_slice = Smi::cast(element)->value(); 5440 int encoded_slice = Smi::cast(element)->value();
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
5491 5491
5492 if (array_length == 0) { 5492 if (array_length == 0) {
5493 return Heap::empty_string(); 5493 return Heap::empty_string();
5494 } else if (array_length == 1) { 5494 } else if (array_length == 1) {
5495 Object* first = fixed_array->get(0); 5495 Object* first = fixed_array->get(0);
5496 if (first->IsString()) return first; 5496 if (first->IsString()) return first;
5497 } 5497 }
5498 5498
5499 bool ascii = special->IsAsciiRepresentation(); 5499 bool ascii = special->IsAsciiRepresentation();
5500 int position = 0; 5500 int position = 0;
5501 int increment = 0;
5502 for (int i = 0; i < array_length; i++) { 5501 for (int i = 0; i < array_length; i++) {
5502 int increment = 0;
5503 Object* elt = fixed_array->get(i); 5503 Object* elt = fixed_array->get(i);
5504 if (elt->IsSmi()) { 5504 if (elt->IsSmi()) {
5505 // Smi encoding of position and length. 5505 // Smi encoding of position and length.
5506 int len = Smi::cast(elt)->value(); 5506 int smi_value = Smi::cast(elt)->value();
5507 if (len > 0) { 5507 int pos;
5508 int len;
5509 if (smi_value > 0) {
5508 // Position and length encoded in one smi. 5510 // Position and length encoded in one smi.
5509 int pos = len >> 11; 5511 pos = StringBuilderSubstringPosition::decode(smi_value);
5510 len &= 0x7ff; 5512 len = StringBuilderSubstringLength::decode(smi_value);
5511 if (pos + len > special_length) {
5512 return Top::Throw(Heap::illegal_argument_symbol());
5513 }
5514 increment = len;
5515 } else { 5513 } else {
5516 // Position and length encoded in two smis. 5514 // Position and length encoded in two smis.
5517 increment = (-len); 5515 len = -smi_value;
5518 // Get the position and check that it is also a smi. 5516 // Get the position and check that it is a positive smi.
5519 i++; 5517 i++;
5520 if (i >= array_length) { 5518 if (i >= array_length) {
5521 return Top::Throw(Heap::illegal_argument_symbol()); 5519 return Top::Throw(Heap::illegal_argument_symbol());
5522 } 5520 }
5523 Object* pos = fixed_array->get(i); 5521 Object* next_smi = fixed_array->get(i);
5524 if (!pos->IsSmi()) { 5522 if (!next_smi->IsSmi()) {
5523 return Top::Throw(Heap::illegal_argument_symbol());
5524 }
5525 pos = Smi::cast(next_smi)->value();
5526 if (pos < 0) {
5525 return Top::Throw(Heap::illegal_argument_symbol()); 5527 return Top::Throw(Heap::illegal_argument_symbol());
5526 } 5528 }
5527 } 5529 }
5530 ASSERT(pos >= 0);
5531 ASSERT(len >= 0);
5532 if (pos > special_length || len > special_length - pos) {
5533 return Top::Throw(Heap::illegal_argument_symbol());
5534 }
5535 increment = len;
5528 } else if (elt->IsString()) { 5536 } else if (elt->IsString()) {
5529 String* element = String::cast(elt); 5537 String* element = String::cast(elt);
5530 int element_length = element->length(); 5538 int element_length = element->length();
5531 increment = element_length; 5539 increment = element_length;
5532 if (ascii && !element->IsAsciiRepresentation()) { 5540 if (ascii && !element->IsAsciiRepresentation()) {
5533 ascii = false; 5541 ascii = false;
5534 } 5542 }
5535 } else { 5543 } else {
5536 return Top::Throw(Heap::illegal_argument_symbol()); 5544 return Top::Throw(Heap::illegal_argument_symbol());
5537 } 5545 }
(...skipping 4655 matching lines...) Expand 10 before | Expand all | Expand 10 after
10193 } else { 10201 } else {
10194 // Handle last resort GC and make sure to allow future allocations 10202 // Handle last resort GC and make sure to allow future allocations
10195 // to grow the heap without causing GCs (if possible). 10203 // to grow the heap without causing GCs (if possible).
10196 Counters::gc_last_resort_from_js.Increment(); 10204 Counters::gc_last_resort_from_js.Increment();
10197 Heap::CollectAllGarbage(false); 10205 Heap::CollectAllGarbage(false);
10198 } 10206 }
10199 } 10207 }
10200 10208
10201 10209
10202 } } // namespace v8::internal 10210 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « no previous file | src/string.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698