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