• 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/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) const16 Handle<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)26 int LiteralBuffer::NewCapacity(int min_capacity) {
27   return min_capacity < (kMaxGrowth / (kGrowthFactor - 1))
28              ? min_capacity * kGrowthFactor
29              : min_capacity + kMaxGrowth;
30 }
31 
ExpandBuffer()32 void 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()42 void 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)66 void 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