1 /*
2 * Copyright (c) 2022 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/jspandafile/js_pandafile_manager.h"
17
18 #include "ecmascript/compiler/aot_file/an_file_data_manager.h"
19 #include "ecmascript/compiler/aot_file/aot_file_manager.h"
20 #include "ecmascript/js_file_path.h"
21 #include "ecmascript/jspandafile/program_object.h"
22 #include "ecmascript/module/module_path_helper.h"
23 #include "ecmascript/pgo_profiler/pgo_profiler_manager.h"
24 #include "file.h"
25
26 namespace panda::ecmascript {
27 static const size_t MALLOC_SIZE_LIMIT = 2147483648; // Max internal memory used by the VM declared in options
28
GetInstance()29 JSPandaFileManager *JSPandaFileManager::GetInstance()
30 {
31 static JSPandaFileManager *jsFileManager = new JSPandaFileManager();
32 return jsFileManager;
33 }
34
~JSPandaFileManager()35 JSPandaFileManager::~JSPandaFileManager()
36 {
37 os::memory::LockHolder lock(jsPandaFileLock_);
38 extractors_.clear();
39 oldJSPandaFiles_.clear();
40 loadedJSPandaFiles_.clear();
41 }
42
LoadJSPandaFile(JSThread * thread,const CString & filename,std::string_view entryPoint,bool needUpdate)43 std::shared_ptr<JSPandaFile> JSPandaFileManager::LoadJSPandaFile(JSThread *thread, const CString &filename,
44 std::string_view entryPoint, bool needUpdate)
45 {
46 {
47 os::memory::LockHolder lock(jsPandaFileLock_);
48 std::shared_ptr<JSPandaFile> jsPandaFile;
49 if (needUpdate) {
50 auto pf = panda_file::OpenPandaFileOrZip(filename, panda_file::File::READ_WRITE);
51 if (pf == nullptr) {
52 LOG_ECMA(ERROR) << "open file " << filename << " error";
53 return nullptr;
54 }
55 jsPandaFile = FindJSPandaFileWithChecksum(filename, pf->GetHeader()->checksum);
56 } else {
57 jsPandaFile = FindJSPandaFileUnlocked(filename);
58 }
59 if (jsPandaFile != nullptr) {
60 InsertJSPandaFileVmUnlocked(thread->GetEcmaVM(), jsPandaFile);
61 return jsPandaFile;
62 }
63 }
64
65 EcmaVM *vm = thread->GetEcmaVM();
66 ModuleManager *moduleManager = thread->GetCurrentEcmaContext()->GetModuleManager();
67 std::unique_ptr<const panda_file::File> pf;
68 if (!vm->IsBundlePack() && moduleManager->GetExecuteMode()) {
69 ResolveBufferCallback resolveBufferCallback = vm->GetResolveBufferCallback();
70 if (resolveBufferCallback == nullptr) {
71 LOG_ECMA(ERROR) << "resolveBufferCallback is nullptr";
72 #if defined(PANDA_TARGET_WINDOWS) || defined(PANDA_TARGET_MACOS)
73 if (vm->EnableReportModuleResolvingFailure()) {
74 LOG_NO_TAG(ERROR) << "[ArkRuntime Log] Importing shared package is not supported in the Previewer.";
75 }
76 #endif
77 return nullptr;
78 }
79 uint8_t *data = nullptr;
80 size_t dataSize = 0;
81 bool getBuffer = resolveBufferCallback(ModulePathHelper::ParseHapPath(filename), &data, &dataSize);
82 if (!getBuffer) {
83 #if defined(PANDA_TARGET_WINDOWS) || defined(PANDA_TARGET_MACOS)
84 if (vm->EnableReportModuleResolvingFailure()) {
85 LOG_NO_TAG(INFO) << "[ArkRuntime Log] Importing shared package in the Previewer.";
86 }
87 #endif
88 LOG_ECMA(ERROR) << "resolveBufferCallback get buffer failed";
89 return nullptr;
90 }
91 #if defined(PANDA_TARGET_ANDROID) || defined(PANDA_TARGET_IOS)
92 pf = panda_file::OpenPandaFileFromMemory(data, dataSize);
93 #else
94 pf = panda_file::OpenPandaFileFromSecureMemory(data, dataSize);
95 #endif
96 } else {
97 pf = panda_file::OpenPandaFileOrZip(filename, panda_file::File::READ_WRITE);
98 }
99
100 if (pf == nullptr) {
101 LOG_ECMA(ERROR) << "open file " << filename << " error";
102 return nullptr;
103 }
104
105 std::shared_ptr<JSPandaFile> jsPandaFile = GenerateJSPandaFile(thread, pf.release(), filename, entryPoint);
106 #if defined(ECMASCRIPT_SUPPORT_CPUPROFILER)
107 if (thread->GetIsProfiling()) {
108 GetJSPtExtractorAndExtract(jsPandaFile.get());
109 }
110 #endif
111 return jsPandaFile;
112 }
113
114 // The security interface needs to be modified accordingly.
LoadJSPandaFile(JSThread * thread,const CString & filename,std::string_view entryPoint,const void * buffer,size_t size,bool needUpdate)115 std::shared_ptr<JSPandaFile> JSPandaFileManager::LoadJSPandaFile(JSThread *thread, const CString &filename,
116 std::string_view entryPoint, const void *buffer, size_t size, bool needUpdate)
117 {
118 if (buffer == nullptr || size == 0) {
119 LOG_FULL(ERROR) << "Input buffer is empty";
120 return nullptr;
121 }
122 {
123 os::memory::LockHolder lock(jsPandaFileLock_);
124 std::shared_ptr<JSPandaFile> jsPandaFile;
125 if (needUpdate) {
126 auto pf = panda_file::OpenPandaFileFromMemory(buffer, size);
127 if (pf == nullptr) {
128 LOG_ECMA(ERROR) << "open file buffer " << filename << " error";
129 return nullptr;
130 }
131 jsPandaFile = FindJSPandaFileWithChecksum(filename, pf->GetHeader()->checksum);
132 } else {
133 jsPandaFile = FindJSPandaFileUnlocked(filename);
134 }
135 if (jsPandaFile != nullptr) {
136 InsertJSPandaFileVmUnlocked(thread->GetEcmaVM(), jsPandaFile);
137 return jsPandaFile;
138 }
139 }
140
141 auto pf = panda_file::OpenPandaFileFromMemory(buffer, size);
142 if (pf == nullptr) {
143 LOG_ECMA(ERROR) << "open file " << filename << " error";
144 return nullptr;
145 }
146
147 // JSPandaFile desc cannot be empty, if buffer with empty filename, use pf filename as a descriptor.
148 const CString &desc = filename.empty() ? pf->GetFilename().c_str() : filename;
149
150 std::shared_ptr<JSPandaFile> jsPandaFile = GenerateJSPandaFile(thread, pf.release(), desc, entryPoint);
151 #if defined(ECMASCRIPT_SUPPORT_CPUPROFILER)
152 if (thread->GetIsProfiling()) {
153 GetJSPtExtractorAndExtract(jsPandaFile.get());
154 }
155 #endif
156 return jsPandaFile;
157 }
158
LoadJSPandaFileSecure(JSThread * thread,const CString & filename,std::string_view entryPoint,uint8_t * buffer,size_t size,bool needUpdate)159 std::shared_ptr<JSPandaFile> JSPandaFileManager::LoadJSPandaFileSecure(JSThread *thread, const CString &filename,
160 std::string_view entryPoint, uint8_t *buffer, size_t size, bool needUpdate)
161 {
162 if (buffer == nullptr || size == 0) {
163 LOG_FULL(ERROR) << "Input buffer is empty";
164 return nullptr;
165 }
166 {
167 os::memory::LockHolder lock(jsPandaFileLock_);
168 std::shared_ptr<JSPandaFile> jsPandaFile;
169 if (needUpdate) {
170 auto pf = panda_file::OpenPandaFileFromSecureMemory(buffer, size);
171 if (pf == nullptr) {
172 LOG_ECMA(ERROR) << "open file buffer " << filename << " error";
173 return nullptr;
174 }
175 jsPandaFile = FindJSPandaFileWithChecksum(filename, pf->GetHeader()->checksum);
176 } else {
177 jsPandaFile = FindJSPandaFileUnlocked(filename);
178 }
179 if (jsPandaFile != nullptr) {
180 InsertJSPandaFileVmUnlocked(thread->GetEcmaVM(), jsPandaFile);
181 return jsPandaFile;
182 }
183 }
184
185 auto pf = panda_file::OpenPandaFileFromSecureMemory(buffer, size);
186 if (pf == nullptr) {
187 LOG_ECMA(ERROR) << "open file " << filename << " error";
188 return nullptr;
189 }
190
191 // JSPandaFile desc cannot be empty, if buffer with empty filename, use pf filename as a descriptor.
192 const CString &desc = filename.empty() ? pf->GetFilename().c_str() : filename;
193
194 std::shared_ptr<JSPandaFile> jsPandaFile = GenerateJSPandaFile(thread, pf.release(), desc, entryPoint);
195 #if defined(ECMASCRIPT_SUPPORT_CPUPROFILER)
196 if (thread->GetIsProfiling()) {
197 GetJSPtExtractorAndExtract(jsPandaFile.get());
198 }
199 #endif
200 return jsPandaFile;
201 }
202
GenerateProgram(EcmaVM * vm,const JSPandaFile * jsPandaFile,std::string_view entryPoint)203 JSHandle<Program> JSPandaFileManager::GenerateProgram(EcmaVM *vm, const JSPandaFile *jsPandaFile,
204 std::string_view entryPoint)
205 {
206 ASSERT(GetJSPandaFile(jsPandaFile->GetPandaFile()) != nullptr);
207 if (AnFileDataManager::GetInstance()->IsEnable()) {
208 vm->GetJSThread()->GetCurrentEcmaContext()->GetAOTFileManager()->LoadAiFile(jsPandaFile);
209 }
210
211 return PandaFileTranslator::GenerateProgram(vm, jsPandaFile, entryPoint);
212 }
213
FindJSPandaFileWithChecksum(const CString & filename,uint32_t checksum)214 std::shared_ptr<JSPandaFile> JSPandaFileManager::FindJSPandaFileWithChecksum(const CString &filename, uint32_t checksum)
215 {
216 std::shared_ptr<JSPandaFile> jsPandaFile = FindJSPandaFileUnlocked(filename);
217 if (jsPandaFile == nullptr) {
218 return nullptr;
219 }
220
221 if (checksum == jsPandaFile->GetChecksum()) {
222 return jsPandaFile;
223 }
224
225 LOG_FULL(INFO) << "reload " << filename << " with new checksum";
226 ObsoleteLoadedJSPandaFile(filename);
227 return nullptr;
228 }
229
FindMergedJSPandaFile()230 std::shared_ptr<JSPandaFile> JSPandaFileManager::FindMergedJSPandaFile()
231 {
232 os::memory::LockHolder lock(jsPandaFileLock_);
233 for (const auto &iter : loadedJSPandaFiles_) {
234 const std::shared_ptr<JSPandaFile> &jsPandafile = iter.second.first;
235 if (jsPandafile->IsFirstMergedAbc()) {
236 return jsPandafile;
237 }
238 }
239 return nullptr;
240 }
241
FindJSPandaFileUnlocked(const CString & filename)242 std::shared_ptr<JSPandaFile> JSPandaFileManager::FindJSPandaFileUnlocked(const CString &filename)
243 {
244 if (filename.empty()) {
245 return nullptr;
246 }
247 const auto iter = loadedJSPandaFiles_.find(filename);
248 if (iter == loadedJSPandaFiles_.end()) {
249 return nullptr;
250 }
251 return iter->second.first;
252 }
253
FindJSPandaFile(const CString & filename)254 std::shared_ptr<JSPandaFile> JSPandaFileManager::FindJSPandaFile(const CString &filename)
255 {
256 os::memory::LockHolder lock(jsPandaFileLock_);
257 return FindJSPandaFileUnlocked(filename);
258 }
259
GetJSPandaFile(const panda_file::File * pf)260 std::shared_ptr<JSPandaFile> JSPandaFileManager::GetJSPandaFile(const panda_file::File *pf)
261 {
262 os::memory::LockHolder lock(jsPandaFileLock_);
263 for (const auto &iter : loadedJSPandaFiles_) {
264 const std::shared_ptr<JSPandaFile> &jsPandafile = iter.second.first;
265 if (jsPandafile->GetPandaFile() == pf) {
266 return jsPandafile;
267 }
268 }
269 return nullptr;
270 }
271
AddJSPandaFileVm(const EcmaVM * vm,const std::shared_ptr<JSPandaFile> & jsPandaFile)272 void JSPandaFileManager::AddJSPandaFileVm(const EcmaVM *vm, const std::shared_ptr<JSPandaFile> &jsPandaFile)
273 {
274 const auto &filename = jsPandaFile->GetJSPandaFileDesc();
275 os::memory::LockHolder lock(jsPandaFileLock_);
276 if (loadedJSPandaFiles_.find(filename) != loadedJSPandaFiles_.end()) {
277 LOG_ECMA(FATAL) << "add failed, file already exist: " << filename;
278 UNREACHABLE();
279 }
280
281 std::set<const EcmaVM *> vmSet {vm};
282 JSPandaFileVmsPair pandaFileRecord = std::make_pair(jsPandaFile, std::move(vmSet));
283 loadedJSPandaFiles_[filename] = std::move(pandaFileRecord);
284 LOG_ECMA(DEBUG) << "add file: " << filename;
285 }
286
InsertJSPandaFileVmUnlocked(const EcmaVM * vm,const std::shared_ptr<JSPandaFile> & jsPandaFile)287 void JSPandaFileManager::InsertJSPandaFileVmUnlocked(const EcmaVM *vm,
288 const std::shared_ptr<JSPandaFile> &jsPandaFile)
289 {
290 const auto &filename = jsPandaFile->GetJSPandaFileDesc();
291 auto iter = loadedJSPandaFiles_.find(filename);
292 if (iter == loadedJSPandaFiles_.end()) {
293 LOG_ECMA(FATAL) << "insert vm failed, file not exist: " << filename;
294 UNREACHABLE();
295 }
296
297 auto &vmSet = iter->second.second;
298 vmSet.emplace(vm);
299 }
300
RemoveJSPandaFileVm(const EcmaVM * vm,const JSPandaFile * jsPandaFile)301 void JSPandaFileManager::RemoveJSPandaFileVm(const EcmaVM *vm, const JSPandaFile *jsPandaFile)
302 {
303 if (jsPandaFile == nullptr) {
304 return;
305 }
306
307 os::memory::LockHolder lock(jsPandaFileLock_);
308 auto iterOld = oldJSPandaFiles_.begin();
309 while (iterOld != oldJSPandaFiles_.end()) {
310 if (iterOld->first.get() == jsPandaFile) {
311 auto &vmSet = iterOld->second;
312 vmSet.erase(vm);
313 if (vmSet.empty()) {
314 extractors_.erase(jsPandaFile);
315 oldJSPandaFiles_.erase(iterOld);
316 }
317 return;
318 }
319 iterOld++;
320 }
321 const auto &filename = jsPandaFile->GetJSPandaFileDesc();
322 auto iter = loadedJSPandaFiles_.find(filename);
323 if (iter != loadedJSPandaFiles_.end()) {
324 auto &vmSet = iter->second.second;
325 vmSet.erase(vm);
326 if (vmSet.empty()) {
327 extractors_.erase(jsPandaFile);
328 // erase shared_ptr from map, the ref count -1.
329 loadedJSPandaFiles_.erase(iter);
330 }
331 }
332 }
333
ObsoleteLoadedJSPandaFile(const CString & filename)334 void JSPandaFileManager::ObsoleteLoadedJSPandaFile(const CString &filename)
335 {
336 auto iter = loadedJSPandaFiles_.find(filename);
337 ASSERT(iter != loadedJSPandaFiles_.end());
338 std::shared_ptr<JSPandaFile> &jsPandaFile = iter->second.first;
339 if (oldJSPandaFiles_.find(jsPandaFile) == oldJSPandaFiles_.end()) {
340 oldJSPandaFiles_.emplace(jsPandaFile, iter->second.second);
341 } else {
342 auto &oldVmSet = oldJSPandaFiles_[jsPandaFile];
343 auto &vmSet = iter->second.second;
344 oldVmSet.insert(vmSet.begin(), vmSet.end());
345 }
346 loadedJSPandaFiles_.erase(iter);
347 }
348
OpenJSPandaFile(const CString & filename)349 std::shared_ptr<JSPandaFile> JSPandaFileManager::OpenJSPandaFile(const CString &filename)
350 {
351 auto pf = panda_file::OpenPandaFileOrZip(filename, panda_file::File::READ_WRITE);
352 if (pf == nullptr) {
353 LOG_ECMA(ERROR) << "open file " << filename << " error";
354 return nullptr;
355 }
356
357 return NewJSPandaFile(pf.release(), filename);
358 }
359
OpenJSPandaFileFromBuffer(uint8_t * buffer,size_t size,const CString & filename)360 std::shared_ptr<JSPandaFile> JSPandaFileManager::OpenJSPandaFileFromBuffer(uint8_t *buffer,
361 size_t size,
362 const CString &filename)
363 {
364 auto pf = panda_file::OpenPandaFileFromMemory(buffer, size);
365 if (pf == nullptr) {
366 LOG_ECMA(ERROR) << "open file " << filename << " error";
367 return nullptr;
368 }
369
370 return NewJSPandaFile(pf.release(), filename);
371 }
372
NewJSPandaFile(const panda_file::File * pf,const CString & desc)373 std::shared_ptr<JSPandaFile> JSPandaFileManager::NewJSPandaFile(const panda_file::File *pf, const CString &desc)
374 {
375 std::shared_ptr<JSPandaFile> jsPandaFile = std::make_shared<JSPandaFile>(pf, desc);
376 PGOProfilerManager::GetInstance()->SamplePandaFileInfo(jsPandaFile->GetChecksum());
377 return jsPandaFile;
378 }
379
GetJSPtExtractor(const JSPandaFile * jsPandaFile)380 DebugInfoExtractor *JSPandaFileManager::GetJSPtExtractor(const JSPandaFile *jsPandaFile)
381 {
382 LOG_ECMA_IF(jsPandaFile == nullptr, FATAL) << "GetJSPtExtractor error, js pandafile is nullptr";
383
384 os::memory::LockHolder lock(jsPandaFileLock_);
385 const auto &filename = jsPandaFile->GetJSPandaFileDesc();
386 if (loadedJSPandaFiles_.find(filename) == loadedJSPandaFiles_.end()) {
387 LOG_ECMA(FATAL) << "get extractor failed, file not exist: " << filename;
388 UNREACHABLE();
389 }
390
391 auto iter = extractors_.find(jsPandaFile);
392 if (iter == extractors_.end()) {
393 auto extractorPtr = std::make_unique<DebugInfoExtractor>(jsPandaFile);
394 DebugInfoExtractor *extractor = extractorPtr.get();
395 extractors_[jsPandaFile] = std::move(extractorPtr);
396 return extractor;
397 }
398
399 return iter->second.get();
400 }
401
GetJSPtExtractorAndExtract(const JSPandaFile * jsPandaFile)402 DebugInfoExtractor *JSPandaFileManager::GetJSPtExtractorAndExtract(const JSPandaFile *jsPandaFile)
403 {
404 LOG_ECMA_IF(jsPandaFile == nullptr, FATAL) << "GetJSPtExtractor error, js pandafile is nullptr";
405
406 os::memory::LockHolder lock(jsPandaFileLock_);
407 const auto &filename = jsPandaFile->GetJSPandaFileDesc();
408 if (loadedJSPandaFiles_.find(filename) == loadedJSPandaFiles_.end()) {
409 LOG_ECMA(FATAL) << "get extractor failed, file not exist: " << filename;
410 UNREACHABLE();
411 }
412
413 auto iter = extractors_.find(jsPandaFile);
414 if (iter == extractors_.end()) {
415 auto extractorPtr = std::make_unique<DebugInfoExtractor>(jsPandaFile);
416 DebugInfoExtractor *extractor = extractorPtr.get();
417 extractor->Extract();
418 extractors_[jsPandaFile] = std::move(extractorPtr);
419 return extractor;
420 }
421
422 return iter->second.get();
423 }
424
CpuProfilerGetJSPtExtractor(const JSPandaFile * jsPandaFile)425 DebugInfoExtractor *JSPandaFileManager::CpuProfilerGetJSPtExtractor(const JSPandaFile *jsPandaFile)
426 {
427 LOG_ECMA_IF(jsPandaFile == nullptr, FATAL) << "GetJSPtExtractor error, js pandafile is nullptr";
428
429 os::memory::LockHolder lock(jsPandaFileLock_);
430 const auto &filename = jsPandaFile->GetJSPandaFileDesc();
431 if (loadedJSPandaFiles_.find(filename) == loadedJSPandaFiles_.end()) {
432 LOG_ECMA(FATAL) << "get extractor failed, file not exist: " << filename;
433 UNREACHABLE();
434 }
435
436 DebugInfoExtractor *extractor = nullptr;
437 auto iter = extractors_.find(jsPandaFile);
438 if (iter == extractors_.end()) {
439 auto extractorPtr = std::make_unique<DebugInfoExtractor>(jsPandaFile);
440 extractor = extractorPtr.get();
441 extractors_[jsPandaFile] = std::move(extractorPtr);
442 } else {
443 extractor = iter->second.get();
444 }
445
446 extractor->Extract();
447 return extractor;
448 }
449
GenerateJSPandaFile(JSThread * thread,const panda_file::File * pf,const CString & desc,std::string_view entryPoint)450 std::shared_ptr<JSPandaFile> JSPandaFileManager::GenerateJSPandaFile(JSThread *thread, const panda_file::File *pf,
451 const CString &desc, std::string_view entryPoint)
452 {
453 ASSERT(GetJSPandaFile(pf) == nullptr);
454 std::shared_ptr<JSPandaFile> newJsPandaFile = NewJSPandaFile(pf, desc);
455 EcmaVM *vm = thread->GetEcmaVM();
456
457 CString methodName = entryPoint.data();
458 if (newJsPandaFile->IsBundlePack()) {
459 // entryPoint maybe is _GLOBAL::func_main_watch to execute func_main_watch
460 auto pos = entryPoint.find_last_of("::");
461 if (pos != std::string_view::npos) {
462 methodName = entryPoint.substr(pos + 1);
463 } else {
464 // default use func_main_0 as entryPoint
465 methodName = JSPandaFile::ENTRY_FUNCTION_NAME;
466 }
467 }
468 PandaFileTranslator::TranslateClasses(newJsPandaFile.get(), methodName);
469
470 {
471 // For worker, JSPandaFile may be created by another vm.
472 os::memory::LockHolder lock(jsPandaFileLock_);
473 std::shared_ptr<JSPandaFile> jsPandaFile = FindJSPandaFileUnlocked(desc);
474 if (jsPandaFile != nullptr) {
475 InsertJSPandaFileVmUnlocked(vm, jsPandaFile);
476 newJsPandaFile.reset();
477 return jsPandaFile;
478 } else {
479 AddJSPandaFileVm(vm, newJsPandaFile);
480 return newJsPandaFile;
481 }
482 }
483 }
484
AllocateBuffer(size_t size)485 void *JSPandaFileManager::AllocateBuffer(size_t size)
486 {
487 return JSPandaFileAllocator::AllocateBuffer(size);
488 }
489
AllocateBuffer(size_t size)490 void *JSPandaFileManager::JSPandaFileAllocator::AllocateBuffer(size_t size)
491 {
492 if (size == 0) {
493 LOG_ECMA_MEM(FATAL) << "size must have a size bigger than 0";
494 UNREACHABLE();
495 }
496 if (size >= MALLOC_SIZE_LIMIT) {
497 LOG_ECMA_MEM(FATAL) << "size must be less than the maximum";
498 UNREACHABLE();
499 }
500 // NOLINTNEXTLINE(cppcoreguidelines-no-malloc)
501 void *ptr = malloc(size);
502 if (ptr == nullptr) {
503 LOG_ECMA_MEM(FATAL) << "malloc failed";
504 UNREACHABLE();
505 }
506 #if ECMASCRIPT_ENABLE_ZAP_MEM
507 if (memset_s(ptr, size, INVALID_VALUE, size) != EOK) {
508 LOG_ECMA_MEM(FATAL) << "memset_s failed";
509 UNREACHABLE();
510 }
511 #endif
512 return ptr;
513 }
514
FreeBuffer(void * mem)515 void JSPandaFileManager::FreeBuffer(void *mem)
516 {
517 JSPandaFileAllocator::FreeBuffer(mem);
518 }
519
FreeBuffer(void * mem)520 void JSPandaFileManager::JSPandaFileAllocator::FreeBuffer(void *mem)
521 {
522 if (mem == nullptr) {
523 return;
524 }
525 // NOLINTNEXTLINE(cppcoreguidelines-no-malloc)
526 free(mem);
527 }
528 } // namespace panda::ecmascript
529