1958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// Copyright 2014 the V8 project authors. All rights reserved. 2958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// Use of this source code is governed by a BSD-style license that can be 3958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// found in the LICENSE file. 4958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 5958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#ifndef V8_STRING_BUILDER_H_ 6958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#define V8_STRING_BUILDER_H_ 7958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 8014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/assert-scope.h" 9014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/factory.h" 10014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/handles.h" 11014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/isolate.h" 12014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/objects.h" 13014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/utils.h" 14958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 15958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniernamespace v8 { 16958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniernamespace internal { 17958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 18958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierconst int kStringBuilderConcatHelperLengthBits = 11; 19958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierconst int kStringBuilderConcatHelperPositionBits = 19; 20958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 21958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniertypedef BitField<int, 0, kStringBuilderConcatHelperLengthBits> 22958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier StringBuilderSubstringLength; 23958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniertypedef BitField<int, kStringBuilderConcatHelperLengthBits, 24958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier kStringBuilderConcatHelperPositionBits> 25958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier StringBuilderSubstringPosition; 26958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 27958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 28958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniertemplate <typename sinkchar> 29958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierstatic inline void StringBuilderConcatHelper(String* special, sinkchar* sink, 30958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier FixedArray* fixed_array, 31958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int array_length) { 32958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DisallowHeapAllocation no_gc; 33958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int position = 0; 34958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier for (int i = 0; i < array_length; i++) { 35958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Object* element = fixed_array->get(i); 36958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (element->IsSmi()) { 37958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Smi encoding of position and length. 38958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int encoded_slice = Smi::cast(element)->value(); 39958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int pos; 40958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int len; 41958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (encoded_slice > 0) { 42958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Position and length encoded in one smi. 43958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier pos = StringBuilderSubstringPosition::decode(encoded_slice); 44958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier len = StringBuilderSubstringLength::decode(encoded_slice); 45958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else { 46958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Position and length encoded in two smis. 47958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Object* obj = fixed_array->get(++i); 48958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(obj->IsSmi()); 49958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier pos = Smi::cast(obj)->value(); 50958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier len = -encoded_slice; 51958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 52958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier String::WriteToFlat(special, sink + position, pos, pos + len); 53958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier position += len; 54958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else { 55958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier String* string = String::cast(element); 56958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int element_length = string->length(); 57958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier String::WriteToFlat(string, sink + position, 0, element_length); 58958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier position += element_length; 59958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 60958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 61958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 62958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 63958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 64958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// Returns the result length of the concatenation. 65958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// On illegal argument, -1 is returned. 66958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierstatic inline int StringBuilderConcatLength(int special_length, 67958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier FixedArray* fixed_array, 68958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int array_length, bool* one_byte) { 69958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DisallowHeapAllocation no_gc; 70958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int position = 0; 71958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier for (int i = 0; i < array_length; i++) { 72958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int increment = 0; 73958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Object* elt = fixed_array->get(i); 74958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (elt->IsSmi()) { 75958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Smi encoding of position and length. 76958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int smi_value = Smi::cast(elt)->value(); 77958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int pos; 78958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int len; 79958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (smi_value > 0) { 80958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Position and length encoded in one smi. 81958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier pos = StringBuilderSubstringPosition::decode(smi_value); 82958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier len = StringBuilderSubstringLength::decode(smi_value); 83958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else { 84958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Position and length encoded in two smis. 85958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier len = -smi_value; 86958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Get the position and check that it is a positive smi. 87958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier i++; 88958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (i >= array_length) return -1; 89958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Object* next_smi = fixed_array->get(i); 90958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (!next_smi->IsSmi()) return -1; 91958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier pos = Smi::cast(next_smi)->value(); 92958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (pos < 0) return -1; 93958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 94958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(pos >= 0); 95958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(len >= 0); 96958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (pos > special_length || len > special_length - pos) return -1; 97958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier increment = len; 98958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else if (elt->IsString()) { 99958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier String* element = String::cast(elt); 100958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int element_length = element->length(); 101958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier increment = element_length; 102958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (*one_byte && !element->HasOnlyOneByteChars()) { 103958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier *one_byte = false; 104958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 105958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else { 106958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return -1; 107958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 108958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (increment > String::kMaxLength - position) { 109958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return kMaxInt; // Provoke throw on allocation. 110958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 111958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier position += increment; 112958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 113958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return position; 114958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 115958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 116958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 117958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierclass FixedArrayBuilder { 118958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier public: 119958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier explicit FixedArrayBuilder(Isolate* isolate, int initial_capacity) 120958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier : array_(isolate->factory()->NewFixedArrayWithHoles(initial_capacity)), 121958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier length_(0), 122958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier has_non_smi_elements_(false) { 123958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Require a non-zero initial size. Ensures that doubling the size to 124958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // extend the array will work. 125958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(initial_capacity > 0); 126958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 127958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 128958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier explicit FixedArrayBuilder(Handle<FixedArray> backing_store) 129958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier : array_(backing_store), length_(0), has_non_smi_elements_(false) { 130958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Require a non-zero initial size. Ensures that doubling the size to 131958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // extend the array will work. 132958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(backing_store->length() > 0); 133958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 134958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 135958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier bool HasCapacity(int elements) { 136958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int length = array_->length(); 137958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int required_length = length_ + elements; 138958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return (length >= required_length); 139958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 140958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 141958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void EnsureCapacity(int elements) { 142958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int length = array_->length(); 143958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int required_length = length_ + elements; 144958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (length < required_length) { 145958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int new_length = length; 146958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier do { 147958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier new_length *= 2; 148958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } while (new_length < required_length); 149958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Handle<FixedArray> extended_array = 150958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier array_->GetIsolate()->factory()->NewFixedArrayWithHoles(new_length); 151958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier array_->CopyTo(0, *extended_array, 0, length_); 152958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier array_ = extended_array; 153958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 154958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 155958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 156958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void Add(Object* value) { 157958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(!value->IsSmi()); 158958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(length_ < capacity()); 159958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier array_->set(length_, value); 160958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier length_++; 161958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier has_non_smi_elements_ = true; 162958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 163958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 164958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void Add(Smi* value) { 165958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(value->IsSmi()); 166958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(length_ < capacity()); 167958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier array_->set(length_, value); 168958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier length_++; 169958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 170958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 171958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Handle<FixedArray> array() { return array_; } 172958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 173958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int length() { return length_; } 174958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 175958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int capacity() { return array_->length(); } 176958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 177958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Handle<JSArray> ToJSArray(Handle<JSArray> target_array) { 178958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier JSArray::SetContent(target_array, array_); 179958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier target_array->set_length(Smi::FromInt(length_)); 180958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return target_array; 181958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 182958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 183958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier private: 184958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Handle<FixedArray> array_; 185958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int length_; 186958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier bool has_non_smi_elements_; 187958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}; 188958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 189958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 190958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierclass ReplacementStringBuilder { 191958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier public: 192958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier ReplacementStringBuilder(Heap* heap, Handle<String> subject, 193958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int estimated_part_count) 194958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier : heap_(heap), 195958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier array_builder_(heap->isolate(), estimated_part_count), 196958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier subject_(subject), 197958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier character_count_(0), 198958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier is_one_byte_(subject->IsOneByteRepresentation()) { 199958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Require a non-zero initial size. Ensures that doubling the size to 200958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // extend the array will work. 201958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(estimated_part_count > 0); 202958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 203958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 204958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier static inline void AddSubjectSlice(FixedArrayBuilder* builder, int from, 205958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int to) { 206958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(from >= 0); 207958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int length = to - from; 208958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(length > 0); 209958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (StringBuilderSubstringLength::is_valid(length) && 210958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier StringBuilderSubstringPosition::is_valid(from)) { 211958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int encoded_slice = StringBuilderSubstringLength::encode(length) | 212958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier StringBuilderSubstringPosition::encode(from); 213958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier builder->Add(Smi::FromInt(encoded_slice)); 214958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else { 215958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Otherwise encode as two smis. 216958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier builder->Add(Smi::FromInt(-length)); 217958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier builder->Add(Smi::FromInt(from)); 218958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 219958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 220958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 221958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 222958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void EnsureCapacity(int elements) { array_builder_.EnsureCapacity(elements); } 223958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 224958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 225958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void AddSubjectSlice(int from, int to) { 226958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier AddSubjectSlice(&array_builder_, from, to); 227958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier IncrementCharacterCount(to - from); 228958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 229958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 230958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 231958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void AddString(Handle<String> string) { 232958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int length = string->length(); 233958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(length > 0); 234958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier AddElement(*string); 235958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (!string->IsOneByteRepresentation()) { 236958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier is_one_byte_ = false; 237958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 238958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier IncrementCharacterCount(length); 239958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 240958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 241958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 242958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier MaybeHandle<String> ToString(); 243958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 244958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 245958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void IncrementCharacterCount(int by) { 246958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (character_count_ > String::kMaxLength - by) { 247958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier STATIC_ASSERT(String::kMaxLength < kMaxInt); 248958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier character_count_ = kMaxInt; 249958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else { 250958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier character_count_ += by; 251958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 252958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 253958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 254958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier private: 255958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void AddElement(Object* element) { 256958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(element->IsSmi() || element->IsString()); 257958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(array_builder_.capacity() > array_builder_.length()); 258958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier array_builder_.Add(element); 259958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 260958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 261958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Heap* heap_; 262958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier FixedArrayBuilder array_builder_; 263958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Handle<String> subject_; 264958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int character_count_; 265958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier bool is_one_byte_; 266958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}; 267958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 268958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 269958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierclass IncrementalStringBuilder { 270958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier public: 271958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier explicit IncrementalStringBuilder(Isolate* isolate); 272958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 273958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier INLINE(String::Encoding CurrentEncoding()) { return encoding_; } 274958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 275958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier template <typename SrcChar, typename DestChar> 276958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier INLINE(void Append(SrcChar c)); 277958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 278958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier INLINE(void AppendCharacter(uint8_t c)) { 279958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (encoding_ == String::ONE_BYTE_ENCODING) { 280958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Append<uint8_t, uint8_t>(c); 281958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else { 282958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Append<uint8_t, uc16>(c); 283958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 284958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 285958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 286958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier INLINE(void AppendCString(const char* s)) { 287958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier const uint8_t* u = reinterpret_cast<const uint8_t*>(s); 288958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (encoding_ == String::ONE_BYTE_ENCODING) { 289958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier while (*u != '\0') Append<uint8_t, uint8_t>(*(u++)); 290958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else { 291958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier while (*u != '\0') Append<uint8_t, uc16>(*(u++)); 292958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 293958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 294958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 29513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch INLINE(void AppendCString(const uc16* s)) { 29613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch if (encoding_ == String::ONE_BYTE_ENCODING) { 29713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch while (*s != '\0') Append<uc16, uint8_t>(*(s++)); 29813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch } else { 29913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch while (*s != '\0') Append<uc16, uc16>(*(s++)); 30013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch } 30113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch } 30213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 303958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier INLINE(bool CurrentPartCanFit(int length)) { 304958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return part_length_ - current_index_ > length; 305958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 306958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 307958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void AppendString(Handle<String> string); 308958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 309958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier MaybeHandle<String> Finish(); 310958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 31113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch INLINE(bool HasOverflowed()) const { return overflowed_; } 31213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 313958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Change encoding to two-byte. 314958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void ChangeEncoding() { 315958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK_EQ(String::ONE_BYTE_ENCODING, encoding_); 316958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier ShrinkCurrentPart(); 317958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier encoding_ = String::TWO_BYTE_ENCODING; 318958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Extend(); 319958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 320958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 321958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier template <typename DestChar> 322958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier class NoExtend { 323958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier public: 324958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier explicit NoExtend(Handle<String> string, int offset) { 325958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(string->IsSeqOneByteString() || string->IsSeqTwoByteString()); 326958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (sizeof(DestChar) == 1) { 327958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier start_ = reinterpret_cast<DestChar*>( 328958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Handle<SeqOneByteString>::cast(string)->GetChars() + offset); 329958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else { 330958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier start_ = reinterpret_cast<DestChar*>( 331958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Handle<SeqTwoByteString>::cast(string)->GetChars() + offset); 332958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 333958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier cursor_ = start_; 334958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 335958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 336958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier INLINE(void Append(DestChar c)) { *(cursor_++) = c; } 337958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier INLINE(void AppendCString(const char* s)) { 338958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier const uint8_t* u = reinterpret_cast<const uint8_t*>(s); 339958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier while (*u != '\0') Append(*(u++)); 340958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 341958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 342958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int written() { return static_cast<int>(cursor_ - start_); } 343958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 344958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier private: 345958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DestChar* start_; 346958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DestChar* cursor_; 347958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DisallowHeapAllocation no_gc_; 348958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier }; 349958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 350958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier template <typename DestChar> 351958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier class NoExtendString : public NoExtend<DestChar> { 352958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier public: 353958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier NoExtendString(Handle<String> string, int required_length) 354958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier : NoExtend<DestChar>(string, 0), string_(string) { 355958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(string->length() >= required_length); 356958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 357958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 358014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<String> Finalize() { 359958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Handle<SeqString> string = Handle<SeqString>::cast(string_); 360958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int length = NoExtend<DestChar>::written(); 361014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<String> result = SeqString::Truncate(string, length); 362014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch string_ = Handle<String>(); 363014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return result; 364958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 365958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 366958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier private: 367958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Handle<String> string_; 368958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier }; 369958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 370958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier template <typename DestChar> 371958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier class NoExtendBuilder : public NoExtend<DestChar> { 372958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier public: 373958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier NoExtendBuilder(IncrementalStringBuilder* builder, int required_length) 374958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier : NoExtend<DestChar>(builder->current_part(), builder->current_index_), 375958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier builder_(builder) { 376958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(builder->CurrentPartCanFit(required_length)); 377958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 378958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 379958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier ~NoExtendBuilder() { 380958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier builder_->current_index_ += NoExtend<DestChar>::written(); 381958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 382958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 383958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier private: 384958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier IncrementalStringBuilder* builder_; 385958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier }; 386958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 387958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier private: 388958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Factory* factory() { return isolate_->factory(); } 389958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 390958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier INLINE(Handle<String> accumulator()) { return accumulator_; } 391958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 392958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier INLINE(void set_accumulator(Handle<String> string)) { 393958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier *accumulator_.location() = *string; 394958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 395958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 396958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier INLINE(Handle<String> current_part()) { return current_part_; } 397958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 398958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier INLINE(void set_current_part(Handle<String> string)) { 399958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier *current_part_.location() = *string; 400958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 401958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 402958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Add the current part to the accumulator. 403014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void Accumulate(Handle<String> new_part); 404958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 405958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Finish the current part and allocate a new part. 406958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void Extend(); 407958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 408958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Shrink current part to the right size. 409958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void ShrinkCurrentPart() { 410958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(current_index_ < part_length_); 411958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier set_current_part(SeqString::Truncate( 412958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Handle<SeqString>::cast(current_part()), current_index_)); 413958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 414958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 415958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier static const int kInitialPartLength = 32; 416958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier static const int kMaxPartLength = 16 * 1024; 417958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier static const int kPartLengthGrowthFactor = 2; 418958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 419958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Isolate* isolate_; 420958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier String::Encoding encoding_; 421958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier bool overflowed_; 422958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int part_length_; 423958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int current_index_; 424958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Handle<String> accumulator_; 425958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Handle<String> current_part_; 426958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}; 427958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 428958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 429958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniertemplate <typename SrcChar, typename DestChar> 430958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid IncrementalStringBuilder::Append(SrcChar c) { 431958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK_EQ(encoding_ == String::ONE_BYTE_ENCODING, sizeof(DestChar) == 1); 432958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (sizeof(DestChar) == 1) { 433958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK_EQ(String::ONE_BYTE_ENCODING, encoding_); 434958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier SeqOneByteString::cast(*current_part_) 435958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier ->SeqOneByteStringSet(current_index_++, c); 436958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else { 437958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK_EQ(String::TWO_BYTE_ENCODING, encoding_); 438958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier SeqTwoByteString::cast(*current_part_) 439958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier ->SeqTwoByteStringSet(current_index_++, c); 440958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 441958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (current_index_ == part_length_) Extend(); 442958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 443014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} // namespace internal 444014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} // namespace v8 445958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 446958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#endif // V8_STRING_BUILDER_H_ 447