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
23namespace panda::ecmascript {
24
25enum AbcBufferType { NORMAL_BUFFER, SECURE_BUFFER };
26struct AbcBufferInfo {
27    void *buffer_ ;
28    size_t size_;
29    AbcBufferType bufferType_;
30
31    AbcBufferInfo(void *buffer, size_t size, AbcBufferType bufferType)
32        : buffer_(buffer), size_(size), bufferType_(bufferType) {}
33    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 */
42class AbcBufferCache {
43public:
44    AbcBufferCache() = default;
45    ~AbcBufferCache()
46    {
47        abcBufferMap_.clear();
48    }
49
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
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
64    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
73private:
74    std::unordered_map<CString, AbcBufferInfo> abcBufferMap_;
75};
76
77class AbcBufferCacheScope {
78public:
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
87    ~AbcBufferCacheScope()
88    {
89        ASSERT(abcBufferCache_ != nullptr);
90        abcBufferCache_->DeleteAbcBufferFromCache(filename_);
91    }
92
93private:
94    const CString filename_;
95    AbcBufferCache *abcBufferCache_ {nullptr};
96};
97}  // namespace panda::ecmascript
98#endif  // ECMASCRIPT_JSPANDAFILE_ABC_BUFFER_CACHE_H