• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include "ecmascript/regexp/dyn_chunk.h"
17 #include "securec.h"
18 
19 namespace panda::ecmascript {
Expand(size_t newSize)20 int DynChunk::Expand(size_t newSize)
21 {
22     if (newSize > allocatedSize_) {
23         if (error_) {
24             return FAILURE;
25         }
26         ASSERT(allocatedSize_ <= std::numeric_limits<size_t>::max() / ALLOCATE_MULTIPLIER);
27         size_t size = allocatedSize_ * ALLOCATE_MULTIPLIER;
28         if (size > newSize) {
29             newSize = size;
30         }
31         newSize = std::max(newSize, ALLOCATE_MIN_SIZE);
32         auto *newBuf = chunk_->NewArray<uint8_t>(newSize);
33         if (newBuf == nullptr) {
34             error_ = true;
35             return FAILURE;
36         }
37         if (memset_s(newBuf, newSize, 0, newSize) != EOK) {
38             error_ = true;
39             return FAILURE;
40         }
41         if (buf_ != nullptr) {
42             if (memcpy_s(newBuf, size_, buf_, size_) != EOK) {
43                 error_ = true;
44                 return FAILURE;
45             }
46         }
47         buf_ = newBuf;
48         allocatedSize_ = newSize;
49     }
50     return SUCCESS;
51 }
52 
Insert(uint32_t position,size_t len)53 int DynChunk::Insert(uint32_t position, size_t len)
54 {
55     if (size_ < position) {
56         return FAILURE;
57     }
58     if (Expand(size_ + len) != 0) {
59         return FAILURE;
60     }
61     size_t moveSize = size_ - position;
62     // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
63     if (memmove_s(buf_ + position + len, moveSize, buf_ + position, moveSize) != EOK) {
64         return FAILURE;
65     }
66     size_ += len;
67     return SUCCESS;
68 }
69 
Emit(const uint8_t * data,size_t length)70 int DynChunk::Emit(const uint8_t *data, size_t length)
71 {
72     if (UNLIKELY((size_ + length) > allocatedSize_)) {
73         if (Expand(size_ + length) != 0) {
74             return FAILURE;
75         }
76     }
77 
78     if (memcpy_s(buf_ + size_,  // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
79                  length, data, length) != EOK) {
80         return FAILURE;
81     }
82     size_ += length;
83     return SUCCESS;
84 }
85 
EmitChar(uint8_t c)86 int DynChunk::EmitChar(uint8_t c)
87 {
88     return Emit(&c, 1);
89 }
90 
EmitSelf(size_t offset,size_t length)91 int DynChunk::EmitSelf(size_t offset, size_t length)
92 {
93     if (UNLIKELY((size_ + length) > allocatedSize_)) {
94         if (Expand(size_ + length) != 0) {
95             return FAILURE;
96         }
97     }
98 
99     if (memcpy_s(buf_ + size_,  // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
100                  length,
101                  buf_ + offset,  // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
102                  length) != EOK) {
103         return FAILURE;
104     }
105     size_ += length;
106     return SUCCESS;
107 }
108 
EmitStr(const char * str)109 int DynChunk::EmitStr(const char *str)
110 {
111     return Emit(reinterpret_cast<const uint8_t *>(str), strlen(str) + 1);
112 }
113 }  // namespace panda::ecmascript
114