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() const73 inline size_t GetSize() const 74 { 75 return size_; 76 } 77 GetAllocatedSize() const78 inline size_t GetAllocatedSize() const 79 { 80 return allocatedSize_; 81 } 82 GetError() const83 inline bool GetError() const 84 { 85 return error_; 86 } 87 GetU64(size_t offset) const88 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) const94 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) const100 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) const106 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) const112 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) const118 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) const124 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() const135 uint8_t *GetBegin() const 136 { 137 return buf_; 138 } 139 140 private: 141 static constexpr size_t ALLOCATE_MULTIPLIER = 2; 142 static constexpr size_t U16_SIZE = 2; 143 static constexpr size_t U32_SIZE = 4; 144 static constexpr size_t U64_SIZE = 8; 145 friend class RegExpParser; 146 friend class RegExpOpCode; 147 friend class RegExpExecutor; 148 DynChunk(uint8_t *buf, RegExpCachedChunk *regExpCachedChunk)149 DynChunk(uint8_t *buf, RegExpCachedChunk *regExpCachedChunk) : buf_(buf), regExpCachedChunk_(regExpCachedChunk) 150 { 151 ASSERT(regExpCachedChunk_ != nullptr); 152 }; 153 154 uint8_t *buf_ {nullptr}; 155 size_t size_ {0}; 156 size_t allocatedSize_ {0}; 157 bool error_ {false}; 158 RegExpCachedChunk *regExpCachedChunk_ {nullptr}; 159 Chunk *chunk_ {nullptr}; 160 }; 161 } // namespace panda::ecmascript 162 #endif // ECMASCRIPT_REGEXP_DYN_BUFFER_H 163