| Index: src/runtime.cc
|
| diff --git a/src/runtime.cc b/src/runtime.cc
|
| index 0ef654a5d10e7706bca6f15208e02edee26f41c0..729c2feb0d12679ac27f4ed5b1029dbcd94a5d0d 100644
|
| --- a/src/runtime.cc
|
| +++ b/src/runtime.cc
|
| @@ -5795,6 +5795,84 @@ static MaybeObject* Runtime_StringBuilderConcat(Arguments args) {
|
| }
|
|
|
|
|
| +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 length = (array_length - 1) * separator_length;
|
| + for (int i = 0; i < array_length; i++) {
|
| + String* element = String::cast(fixed_array->get(i));
|
| + int increment = element->length();
|
| + if (increment > String::kMaxLength - length) {
|
| + Top::context()->mark_out_of_memory();
|
| + return Failure::OutOfMemoryException();
|
| + }
|
| + length += increment;
|
| + }
|
| +
|
| + Object* object;
|
| + { MaybeObject* maybe_object = Heap::AllocateRawTwoByteString(length);
|
| + if (!maybe_object->ToObject(&object)) return maybe_object;
|
| + }
|
| + SeqTwoByteString* answer = SeqTwoByteString::cast(object);
|
| +
|
| + uc16* sink = answer->GetChars();
|
| +#ifdef DEBUG
|
| + uc16* end = sink + length;
|
| +#endif
|
| +
|
| + String* first = String::cast(fixed_array->get(0));
|
| + 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(separator, sink, 0, separator_length);
|
| + sink += separator_length;
|
| +
|
| + String* element = String::cast(fixed_array->get(i));
|
| + int element_length = element->length();
|
| + ASSERT(sink + element_length <= end);
|
| + String::WriteToFlat(element, sink, 0, element_length);
|
| + sink += element_length;
|
| + }
|
| + ASSERT(sink == end);
|
| +
|
| + ASSERT(!answer->HasOnlyAsciiChars()); // Use %_FastAsciiArrayJoin instead.
|
| + return answer;
|
| +}
|
| +
|
| +
|
| static MaybeObject* Runtime_NumberOr(Arguments args) {
|
| NoHandleAllocation ha;
|
| ASSERT(args.length() == 2);
|
|
|