1 /* 2 * Copyright (c) 2021 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16 #ifndef ECMASCRIPT_REGEXP_DYN_BUFFER_H 17 #define ECMASCRIPT_REGEXP_DYN_BUFFER_H 18 19 #include <cstring> 20 21 #include "ecmascript/common.h" 22 #include "ecmascript/mem/chunk.h" 23 24 namespace panda::ecmascript { 25 class PUBLIC_API DynChunk { 26 public: 27 static constexpr size_t ALLOCATE_MIN_SIZE = 64; 28 static constexpr int FAILURE = -1; 29 static constexpr int SUCCESS = 0; DynChunk(Chunk * chunk)30 explicit DynChunk(Chunk *chunk) : chunk_(chunk) 31 { 32 ASSERT(chunk_ != nullptr); 33 }; 34 35 ~DynChunk() = default; 36 37 NO_COPY_SEMANTIC(DynChunk); 38 NO_MOVE_SEMANTIC(DynChunk); 39 40 int Expand(size_t newSize); 41 42 int Insert(uint32_t position, size_t len); 43 44 int Emit(const uint8_t *data, size_t len); 45 46 int EmitSelf(size_t offset, size_t len); 47 48 int EmitChar(uint8_t c); 49 50 int EmitStr(const char *str); 51 EmitU16(uint16_t data)52 inline int EmitU16(uint16_t data) 53 { 54 return Emit(reinterpret_cast<uint8_t *>(&data), U16_SIZE); 55 } 56 EmitU32(uint32_t data)57 inline int EmitU32(uint32_t data) 58 { 59 return Emit(reinterpret_cast<uint8_t *>(&data), U32_SIZE); 60 } 61 EmitU64(uint64_t data)62 inline int EmitU64(uint64_t data) 63 { 64 return Emit(reinterpret_cast<uint8_t *>(&data), U64_SIZE); 65 } 66 SetError()67 inline void SetError() 68 { 69 error_ = true; 70 } 71 GetSize()72 inline size_t GetSize() const 73 { 74 return size_; 75 } 76 GetAllocatedSize()77 inline size_t GetAllocatedSize() const 78 { 79 return allocatedSize_; 80 } 81 GetError()82 inline bool GetError() const 83 { 84 return error_; 85 } 86 GetU32(size_t offset)87 inline uint32_t GetU32(size_t offset) const 88 { 89 // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic) 90 return *reinterpret_cast<uint32_t *>(buf_ + offset); 91 } 92 PutU32(size_t offset,uint32_t data)93 inline void PutU32(size_t offset, uint32_t data) const 94 { 95 // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic) 96 *reinterpret_cast<uint32_t *>(buf_ + offset) = data; 97 } 98 GetU16(size_t offset)99 inline uint32_t GetU16(size_t offset) const 100 { 101 // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic) 102 return *reinterpret_cast<uint16_t *>(buf_ + offset); 103 } 104 PutU16(size_t offset,uint16_t data)105 inline void PutU16(size_t offset, uint16_t data) const 106 { 107 // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic) 108 *reinterpret_cast<uint16_t *>(buf_ + offset) = data; 109 } 110 GetU8(size_t offset)111 inline uint32_t GetU8(size_t offset) const 112 { 113 // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic) 114 return *(buf_ + offset); 115 } 116 PutU8(size_t offset,uint8_t data)117 inline void PutU8(size_t offset, uint8_t data) const 118 { 119 // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic) 120 *(buf_ + offset) = data; 121 } 122 GetBufferOffset()123 ALWAYS_INLINE static inline constexpr uint32_t GetBufferOffset() 124 { 125 return MEMBER_OFFSET(DynChunk, buf_); 126 } 127 GetBegin()128 uint8_t *GetBegin() const 129 { 130 return buf_; 131 } 132 133 private: 134 static constexpr size_t ALLOCATE_MULTIPLIER = 2; 135 static constexpr size_t U16_SIZE = 2; 136 static constexpr size_t U32_SIZE = 4; 137 static constexpr size_t U64_SIZE = 8; 138 friend class RegExpParser; 139 friend class RegExpOpCode; 140 friend class RegExpExecutor; 141 DynChunk(uint8_t * buf,Chunk * chunk)142 DynChunk(uint8_t *buf, Chunk *chunk) : buf_(buf), chunk_(chunk) 143 { 144 ASSERT(chunk_ != nullptr); 145 }; 146 147 uint8_t *buf_ {nullptr}; 148 size_t size_ {0}; 149 size_t allocatedSize_ {0}; 150 bool error_ {false}; 151 Chunk *chunk_ {nullptr}; 152 }; 153 } // namespace panda::ecmascript 154 #endif // ECMASCRIPT_REGEXP_DYN_BUFFER_H 155