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/regexp_cached_chunk.h" 23 #include "ecmascript/mem/chunk.h" 24 25 namespace panda::ecmascript { 26 class PUBLIC_API DynChunk { 27 public: 28 static constexpr size_t ALLOCATE_MIN_SIZE = 256; 29 static constexpr int FAILURE = -1; 30 static constexpr int SUCCESS = 0; DynChunk(Chunk * chunk)31 explicit DynChunk(Chunk *chunk) : chunk_(chunk) 32 { 33 ASSERT(chunk_ != nullptr); 34 }; 35 36 ~DynChunk() = default; 37 38 NO_COPY_SEMANTIC(DynChunk); 39 NO_MOVE_SEMANTIC(DynChunk); 40 41 int Expand(size_t newSize); 42 43 int Insert(uint32_t position, size_t len); 44 45 int PUBLIC_API Emit(const uint8_t *data, size_t len); 46 47 int EmitSelf(size_t offset, size_t len); 48 49 int PUBLIC_API EmitChar(uint8_t c); 50 51 int EmitStr(const char *str); 52 EmitU16(uint16_t data)53 inline int EmitU16(uint16_t data) 54 { 55 return Emit(reinterpret_cast<uint8_t *>(&data), U16_SIZE); 56 } 57 EmitU32(uint32_t data)58 inline int EmitU32(uint32_t data) 59 { 60 return Emit(reinterpret_cast<uint8_t *>(&data), U32_SIZE); 61 } 62 EmitU64(uint64_t data)63 inline int EmitU64(uint64_t data) 64 { 65 return Emit(reinterpret_cast<uint8_t *>(&data), U64_SIZE); 66 } 67 SetError()68 inline void SetError() 69 { 70 error_ = true; 71 } 72 GetSize()73 inline size_t GetSize() const 74 { 75 return size_; 76 } 77 GetAllocatedSize()78 inline size_t GetAllocatedSize() const 79 { 80 return allocatedSize_; 81 } 82 GetError()83 inline bool GetError() const 84 { 85 return error_; 86 } 87 GetU64(size_t offset)88 inline uint64_t GetU64(size_t offset) const 89 { 90 // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic) 91 return *reinterpret_cast<uint64_t *>(buf_ + offset); 92 } 93 GetU32(size_t offset)94 inline uint32_t GetU32(size_t offset) const 95 { 96 // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic) 97 return *reinterpret_cast<uint32_t *>(buf_ + offset); 98 } 99 PutU32(size_t offset,uint32_t data)100 inline void PutU32(size_t offset, uint32_t data) const 101 { 102 // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic) 103 *reinterpret_cast<uint32_t *>(buf_ + offset) = data; 104 } 105 GetU16(size_t offset)106 inline uint32_t GetU16(size_t offset) const 107 { 108 // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic) 109 return *reinterpret_cast<uint16_t *>(buf_ + offset); 110 } 111 PutU16(size_t offset,uint16_t data)112 inline void PutU16(size_t offset, uint16_t data) const 113 { 114 // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic) 115 *reinterpret_cast<uint16_t *>(buf_ + offset) = data; 116 } 117 GetU8(size_t offset)118 inline uint32_t GetU8(size_t offset) const 119 { 120 // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic) 121 return *(buf_ + offset); 122 } 123 PutU8(size_t offset,uint8_t data)124 inline void PutU8(size_t offset, uint8_t data) const 125 { 126 // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic) 127 *(buf_ + offset) = data; 128 } 129 GetBufferOffset()130 ALWAYS_INLINE static inline constexpr uint32_t GetBufferOffset() 131 { 132 return MEMBER_OFFSET(DynChunk, buf_); 133 } 134 GetBegin()135 uint8_t *GetBegin() const 136 { 137 return buf_; 138 } 139 GetCurrPos()140 size_t GetCurrPos() const 141 { 142 return size_; 143 } 144 145 private: 146 static constexpr size_t ALLOCATE_MULTIPLIER = 2; 147 static constexpr size_t U16_SIZE = 2; 148 static constexpr size_t U32_SIZE = 4; 149 static constexpr size_t U64_SIZE = 8; 150 friend class RegExpParser; 151 friend class RegExpOpCode; 152 friend class RegExpExecutor; 153 DynChunk(uint8_t * buf,RegExpCachedChunk * regExpCachedChunk)154 DynChunk(uint8_t *buf, RegExpCachedChunk *regExpCachedChunk) : buf_(buf), regExpCachedChunk_(regExpCachedChunk) 155 { 156 ASSERT(regExpCachedChunk_ != nullptr); 157 }; 158 159 uint8_t *buf_ {nullptr}; 160 size_t size_ {0}; 161 size_t allocatedSize_ {0}; 162 bool error_ {false}; 163 RegExpCachedChunk *regExpCachedChunk_ {nullptr}; 164 Chunk *chunk_ {nullptr}; 165 }; 166 } // namespace panda::ecmascript 167 #endif // ECMASCRIPT_REGEXP_DYN_BUFFER_H 168