Chromium Code Reviews| Index: src/runtime.cc |
| diff --git a/src/runtime.cc b/src/runtime.cc |
| index 0ef654a5d10e7706bca6f15208e02edee26f41c0..a14c92fdf79214769b42080c540f5d2c67bce682 100644 |
| --- a/src/runtime.cc |
| +++ b/src/runtime.cc |
| @@ -5795,6 +5795,107 @@ static MaybeObject* Runtime_StringBuilderConcat(Arguments args) { |
| } |
| +template <typename sinkchar> |
| +static inline void StringBuilderJoinHelper(String* separator, |
| + sinkchar* sink, |
| + FixedArray* fixed_array, |
| + int array_length) { |
| + ASSERT(array_length > 0); |
| + String* s = String::cast(fixed_array->get(0)); |
| + int position = s->length(); |
| + String::WriteToFlat(s, sink, 0, position); |
| + |
| + int separator_length = separator->length(); |
| + |
| + for (int i = 1; i < array_length; i++) { |
| + String::WriteToFlat(separator, sink + position, 0, separator_length); |
| + position += separator_length; |
| + |
| + String* element = String::cast(fixed_array->get(i)); |
| + int element_length = element->length(); |
| + String::WriteToFlat(element, sink + position, 0, element_length); |
| + position += element_length; |
| + } |
| +} |
| + |
| + |
| +static MaybeObject* Runtime_StringBuilderJoin(Arguments args) { |
| + NoHandleAllocation ha; |
| + ASSERT(args.length() == 3); |
| + CONVERT_CHECKED(JSArray, array, args[0]); |
| + if (!args[1]->IsSmi()) { |
| + Top::context()->mark_out_of_memory(); |
| + return Failure::OutOfMemoryException(); |
| + } |
| + int array_length = Smi::cast(args[1])->value(); |
| + CONVERT_CHECKED(String, separator, args[2]); |
| + |
| + if (!array->HasFastElements()) { |
| + return Top::Throw(Heap::illegal_argument_symbol()); |
| + } |
| + FixedArray* fixed_array = FixedArray::cast(array->elements()); |
| + if (fixed_array->length() < array_length) { |
| + array_length = fixed_array->length(); |
| + } |
| + |
| + if (array_length == 0) { |
| + return Heap::empty_string(); |
| + } else if (array_length == 1) { |
| + Object* first = fixed_array->get(0); |
| + 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)) { |
| + Top::context()->mark_out_of_memory(); |
| + return Failure::OutOfMemoryException(); |
| + } |
| + int position = (array_length - 1) * separator_length; |
| + bool ascii = separator->HasOnlyAsciiChars(); |
|
sandholm
2011/02/14 15:23:04
You will always need a TwoByteString.
If everythin
|
| + for (int i = 0; i < array_length; i++) { |
| + int increment = 0; |
| + String* element = String::cast(fixed_array->get(i)); |
| + int element_length = element->length(); |
| + increment = element_length; |
| + if (ascii && !element->HasOnlyAsciiChars()) { |
| + ascii = false; |
| + } |
| + if (increment > String::kMaxLength - position) { |
| + Top::context()->mark_out_of_memory(); |
| + return Failure::OutOfMemoryException(); |
| + } |
| + position += increment; |
| + } |
| + |
| + int length = position; |
| + Object* object; |
| + |
| + if (ascii) { |
| + { MaybeObject* maybe_object = Heap::AllocateRawAsciiString(length); |
| + if (!maybe_object->ToObject(&object)) return maybe_object; |
| + } |
| + SeqAsciiString* answer = SeqAsciiString::cast(object); |
| + StringBuilderJoinHelper(separator, |
| + answer->GetChars(), |
| + fixed_array, |
| + array_length); |
| + return answer; |
| + } else { |
| + { MaybeObject* maybe_object = Heap::AllocateRawTwoByteString(length); |
| + if (!maybe_object->ToObject(&object)) return maybe_object; |
| + } |
| + SeqTwoByteString* answer = SeqTwoByteString::cast(object); |
| + StringBuilderJoinHelper(separator, |
| + answer->GetChars(), |
| + fixed_array, |
| + array_length); |
| + return answer; |
| + } |
| +} |
| + |
| + |
| static MaybeObject* Runtime_NumberOr(Arguments args) { |
| NoHandleAllocation ha; |
| ASSERT(args.length() == 2); |