1 // Copyright 2019 the V8 project authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "src/parsing/literal-buffer.h" 6 7 #include "src/execution/isolate.h" 8 #include "src/execution/local-isolate.h" 9 #include "src/heap/factory.h" 10 #include "src/utils/memcopy.h" 11 12 namespace v8 { 13 namespace internal { 14 15 template <typename LocalIsolate> Internalize(LocalIsolate * isolate) const16Handle<String> LiteralBuffer::Internalize(LocalIsolate* isolate) const { 17 if (is_one_byte()) { 18 return isolate->factory()->InternalizeString(one_byte_literal()); 19 } 20 return isolate->factory()->InternalizeString(two_byte_literal()); 21 } 22 23 template Handle<String> LiteralBuffer::Internalize(Isolate* isolate) const; 24 template Handle<String> LiteralBuffer::Internalize(LocalIsolate* isolate) const; 25 NewCapacity(int min_capacity)26int LiteralBuffer::NewCapacity(int min_capacity) { 27 return min_capacity < (kMaxGrowth / (kGrowthFactor - 1)) 28 ? min_capacity * kGrowthFactor 29 : min_capacity + kMaxGrowth; 30 } 31 ExpandBuffer()32void LiteralBuffer::ExpandBuffer() { 33 int min_capacity = Max(kInitialCapacity, backing_store_.length()); 34 Vector<byte> new_store = Vector<byte>::New(NewCapacity(min_capacity)); 35 if (position_ > 0) { 36 MemCopy(new_store.begin(), backing_store_.begin(), position_); 37 } 38 backing_store_.Dispose(); 39 backing_store_ = new_store; 40 } 41 ConvertToTwoByte()42void LiteralBuffer::ConvertToTwoByte() { 43 DCHECK(is_one_byte()); 44 Vector<byte> new_store; 45 int new_content_size = position_ * kUC16Size; 46 if (new_content_size >= backing_store_.length()) { 47 // Ensure room for all currently read code units as UC16 as well 48 // as the code unit about to be stored. 49 new_store = Vector<byte>::New(NewCapacity(new_content_size)); 50 } else { 51 new_store = backing_store_; 52 } 53 uint8_t* src = backing_store_.begin(); 54 uint16_t* dst = reinterpret_cast<uint16_t*>(new_store.begin()); 55 for (int i = position_ - 1; i >= 0; i--) { 56 dst[i] = src[i]; 57 } 58 if (new_store.begin() != backing_store_.begin()) { 59 backing_store_.Dispose(); 60 backing_store_ = new_store; 61 } 62 position_ = new_content_size; 63 is_one_byte_ = false; 64 } 65 AddTwoByteChar(uc32 code_unit)66void LiteralBuffer::AddTwoByteChar(uc32 code_unit) { 67 DCHECK(!is_one_byte()); 68 if (position_ >= backing_store_.length()) ExpandBuffer(); 69 if (code_unit <= 70 static_cast<uc32>(unibrow::Utf16::kMaxNonSurrogateCharCode)) { 71 *reinterpret_cast<uint16_t*>(&backing_store_[position_]) = code_unit; 72 position_ += kUC16Size; 73 } else { 74 *reinterpret_cast<uint16_t*>(&backing_store_[position_]) = 75 unibrow::Utf16::LeadSurrogate(code_unit); 76 position_ += kUC16Size; 77 if (position_ >= backing_store_.length()) ExpandBuffer(); 78 *reinterpret_cast<uint16_t*>(&backing_store_[position_]) = 79 unibrow::Utf16::TrailSurrogate(code_unit); 80 position_ += kUC16Size; 81 } 82 } 83 84 } // namespace internal 85 } // namespace v8 86