1 /*
2  * Copyright (c) 2024 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_JSPANDAFILE_ABC_BUFFER_CACHE_H
17 #define ECMASCRIPT_JSPANDAFILE_ABC_BUFFER_CACHE_H
18 
19 #include <string>
20 #include "ecmascript/ecma_context.h"
21 #include "ecmascript/js_thread.h"
22 
23 namespace panda::ecmascript {
24 
25 enum AbcBufferType { NORMAL_BUFFER, SECURE_BUFFER };
26 struct AbcBufferInfo {
27     void *buffer_ ;
28     size_t size_;
29     AbcBufferType bufferType_;
30 
AbcBufferInfopanda::ecmascript::AbcBufferInfo31     AbcBufferInfo(void *buffer, size_t size, AbcBufferType bufferType)
32         : buffer_(buffer), size_(size), bufferType_(bufferType) {}
AbcBufferInfopanda::ecmascript::AbcBufferInfo33     AbcBufferInfo()
34         : buffer_(nullptr), size_(0), bufferType_(AbcBufferType::NORMAL_BUFFER) {}
35 };
36 
37 /*
38  * If JSPandafileManager's loadedJSPandaFiles_ delete cache during sharedgc process,
39  * buffer cannot get in later module LoadJsPandafile process, which will cause crash.
40  * This map can help use buffer to get *pf again.
41  */
42 class AbcBufferCache {
43 public:
44     AbcBufferCache() = default;
~AbcBufferCache()45     ~AbcBufferCache()
46     {
47         abcBufferMap_.clear();
48     }
49 
AddAbcBufferToCache(const CString &fileName, const void *buffer, size_t size, AbcBufferType bufferType)50     void AddAbcBufferToCache(const CString &fileName, const void *buffer, size_t size, AbcBufferType bufferType)
51     {
52         abcBufferMap_.emplace(fileName, AbcBufferInfo(const_cast<void *>(buffer), size, bufferType));
53     }
54 
DeleteAbcBufferFromCache(const CString &fileName)55     void DeleteAbcBufferFromCache(const CString &fileName)
56     {
57         auto iter = abcBufferMap_.find(fileName);
58         if (iter == abcBufferMap_.end()) {
59             return;
60         }
61         abcBufferMap_.erase(iter);
62     }
63 
FindJSPandaFileInAbcBufferCache(const CString &fileName) const64     AbcBufferInfo FindJSPandaFileInAbcBufferCache(const CString &fileName) const
65     {
66         auto iter = abcBufferMap_.find(fileName);
67         if (iter == abcBufferMap_.end()) {
68             return AbcBufferInfo();
69         }
70         return iter->second;
71     }
72 
73 private:
74     std::unordered_map<CString, AbcBufferInfo> abcBufferMap_;
75 };
76 
77 class AbcBufferCacheScope {
78 public:
AbcBufferCacheScope(JSThread *thread, const CString &filename, const void *buffer, size_t size, AbcBufferType bufferType)79     AbcBufferCacheScope(JSThread *thread, const CString &filename, const void *buffer,
80         size_t size, AbcBufferType bufferType): filename_(filename)
81     {
82         abcBufferCache_ = thread->GetCurrentEcmaContext()->GetAbcBufferCache();
83         ASSERT(abcBufferCache_ != nullptr);
84         abcBufferCache_->AddAbcBufferToCache(filename_, buffer, size, bufferType);
85     }
86 
~AbcBufferCacheScope()87     ~AbcBufferCacheScope()
88     {
89         ASSERT(abcBufferCache_ != nullptr);
90         abcBufferCache_->DeleteAbcBufferFromCache(filename_);
91     }
92 
93 private:
94     const CString filename_;
95     AbcBufferCache *abcBufferCache_ {nullptr};
96 };
97 }  // namespace panda::ecmascript
98 #endif  // ECMASCRIPT_JSPANDAFILE_ABC_BUFFER_CACHE_H