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/base/strings.h" 8 #include "src/execution/isolate.h" 9 #include "src/execution/local-isolate.h" 10 #include "src/heap/factory.h" 11 #include "src/utils/memcopy.h" 12 13 namespace v8 { 14 namespace internal { 15 16 template <typename IsolateT> Internalize(IsolateT * isolate) const17Handle<String> LiteralBuffer::Internalize(IsolateT* isolate) const { 18 if (is_one_byte()) { 19 return isolate->factory()->InternalizeString(one_byte_literal()); 20 } 21 return isolate->factory()->InternalizeString(two_byte_literal()); 22 } 23 24 template Handle<String> LiteralBuffer::Internalize(Isolate* isolate) const; 25 template Handle<String> LiteralBuffer::Internalize(LocalIsolate* isolate) const; 26 NewCapacity(int min_capacity)27int LiteralBuffer::NewCapacity(int min_capacity) { 28 return min_capacity < (kMaxGrowth / (kGrowthFactor - 1)) 29 ? min_capacity * kGrowthFactor 30 : min_capacity + kMaxGrowth; 31 } 32 ExpandBuffer()33void LiteralBuffer::ExpandBuffer() { 34 int min_capacity = std::max({kInitialCapacity, backing_store_.length()}); 35 base::Vector<byte> new_store = 36 base::Vector<byte>::New(NewCapacity(min_capacity)); 37 if (position_ > 0) { 38 MemCopy(new_store.begin(), backing_store_.begin(), position_); 39 } 40 backing_store_.Dispose(); 41 backing_store_ = new_store; 42 } 43 ConvertToTwoByte()44void LiteralBuffer::ConvertToTwoByte() { 45 DCHECK(is_one_byte()); 46 base::Vector<byte> new_store; 47 int new_content_size = position_ * base::kUC16Size; 48 if (new_content_size >= backing_store_.length()) { 49 // Ensure room for all currently read code units as UC16 as well 50 // as the code unit about to be stored. 51 new_store = base::Vector<byte>::New(NewCapacity(new_content_size)); 52 } else { 53 new_store = backing_store_; 54 } 55 uint8_t* src = backing_store_.begin(); 56 uint16_t* dst = reinterpret_cast<uint16_t*>(new_store.begin()); 57 for (int i = position_ - 1; i >= 0; i--) { 58 dst[i] = src[i]; 59 } 60 if (new_store.begin() != backing_store_.begin()) { 61 backing_store_.Dispose(); 62 backing_store_ = new_store; 63 } 64 position_ = new_content_size; 65 is_one_byte_ = false; 66 } 67 AddTwoByteChar(base::uc32 code_unit)68void LiteralBuffer::AddTwoByteChar(base::uc32 code_unit) { 69 DCHECK(!is_one_byte()); 70 if (position_ >= backing_store_.length()) ExpandBuffer(); 71 if (code_unit <= 72 static_cast<base::uc32>(unibrow::Utf16::kMaxNonSurrogateCharCode)) { 73 *reinterpret_cast<uint16_t*>(&backing_store_[position_]) = code_unit; 74 position_ += base::kUC16Size; 75 } else { 76 *reinterpret_cast<uint16_t*>(&backing_store_[position_]) = 77 unibrow::Utf16::LeadSurrogate(code_unit); 78 position_ += base::kUC16Size; 79 if (position_ >= backing_store_.length()) ExpandBuffer(); 80 *reinterpret_cast<uint16_t*>(&backing_store_[position_]) = 81 unibrow::Utf16::TrailSurrogate(code_unit); 82 position_ += base::kUC16Size; 83 } 84 } 85 86 } // namespace internal 87 } // namespace v8 88