• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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) const17 Handle<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)27 int LiteralBuffer::NewCapacity(int min_capacity) {
28   return min_capacity < (kMaxGrowth / (kGrowthFactor - 1))
29              ? min_capacity * kGrowthFactor
30              : min_capacity + kMaxGrowth;
31 }
32 
ExpandBuffer()33 void 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()44 void 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)68 void 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