• 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 #ifndef V8_PARSING_LITERAL_BUFFER_H_
6 #define V8_PARSING_LITERAL_BUFFER_H_
7 
8 #include "src/base/strings.h"
9 #include "src/base/vector.h"
10 #include "src/strings/unicode-decoder.h"
11 
12 namespace v8 {
13 namespace internal {
14 
15 // LiteralBuffer -  Collector of chars of literals.
16 class LiteralBuffer final {
17  public:
LiteralBuffer()18   LiteralBuffer() : backing_store_(), position_(0), is_one_byte_(true) {}
19 
~LiteralBuffer()20   ~LiteralBuffer() { backing_store_.Dispose(); }
21 
22   LiteralBuffer(const LiteralBuffer&) = delete;
23   LiteralBuffer& operator=(const LiteralBuffer&) = delete;
24 
AddChar(char code_unit)25   V8_INLINE void AddChar(char code_unit) {
26     DCHECK(IsValidAscii(code_unit));
27     AddOneByteChar(static_cast<byte>(code_unit));
28   }
29 
AddChar(base::uc32 code_unit)30   V8_INLINE void AddChar(base::uc32 code_unit) {
31     if (is_one_byte()) {
32       if (code_unit <= static_cast<base::uc32>(unibrow::Latin1::kMaxChar)) {
33         AddOneByteChar(static_cast<byte>(code_unit));
34         return;
35       }
36       ConvertToTwoByte();
37     }
38     AddTwoByteChar(code_unit);
39   }
40 
is_one_byte()41   bool is_one_byte() const { return is_one_byte_; }
42 
Equals(base::Vector<const char> keyword)43   bool Equals(base::Vector<const char> keyword) const {
44     return is_one_byte() && keyword.length() == position_ &&
45            (memcmp(keyword.begin(), backing_store_.begin(), position_) == 0);
46   }
47 
two_byte_literal()48   base::Vector<const uint16_t> two_byte_literal() const {
49     return literal<uint16_t>();
50   }
51 
one_byte_literal()52   base::Vector<const uint8_t> one_byte_literal() const {
53     return literal<uint8_t>();
54   }
55 
56   template <typename Char>
literal()57   base::Vector<const Char> literal() const {
58     DCHECK_EQ(is_one_byte_, sizeof(Char) == 1);
59     DCHECK_EQ(position_ & (sizeof(Char) - 1), 0);
60     return base::Vector<const Char>(
61         reinterpret_cast<const Char*>(backing_store_.begin()),
62         position_ >> (sizeof(Char) - 1));
63   }
64 
length()65   int length() const { return is_one_byte() ? position_ : (position_ >> 1); }
66 
Start()67   void Start() {
68     position_ = 0;
69     is_one_byte_ = true;
70   }
71 
72   template <typename IsolateT>
73   Handle<String> Internalize(IsolateT* isolate) const;
74 
75  private:
76   static const int kInitialCapacity = 16;
77   static const int kGrowthFactor = 4;
78   static const int kMaxGrowth = 1 * MB;
79 
IsValidAscii(char code_unit)80   inline bool IsValidAscii(char code_unit) {
81     // Control characters and printable characters span the range of
82     // valid ASCII characters (0-127). Chars are unsigned on some
83     // platforms which causes compiler warnings if the validity check
84     // tests the lower bound >= 0 as it's always true.
85     return iscntrl(code_unit) || isprint(code_unit);
86   }
87 
AddOneByteChar(byte one_byte_char)88   V8_INLINE void AddOneByteChar(byte one_byte_char) {
89     DCHECK(is_one_byte());
90     if (position_ >= backing_store_.length()) ExpandBuffer();
91     backing_store_[position_] = one_byte_char;
92     position_ += kOneByteSize;
93   }
94 
95   void AddTwoByteChar(base::uc32 code_unit);
96   int NewCapacity(int min_capacity);
97   void ExpandBuffer();
98   void ConvertToTwoByte();
99 
100   base::Vector<byte> backing_store_;
101   int position_;
102 
103   bool is_one_byte_;
104 };
105 
106 }  // namespace internal
107 }  // namespace v8
108 
109 #endif  // V8_PARSING_LITERAL_BUFFER_H_
110