• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * Copyright (c) 2021-2025 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 "runtime/include/file_manager.h"
17 #include "runtime/include/runtime.h"
18 #include "libpandabase/os/filesystem.h"
19 
20 namespace ark {
21 
LoadAbcFile(std::string_view location,panda_file::File::OpenMode openMode)22 bool FileManager::LoadAbcFile(std::string_view location, panda_file::File::OpenMode openMode)
23 {
24     auto pf = panda_file::OpenPandaFile(location, "", openMode);
25     if (pf == nullptr) {
26         LOG(ERROR, PANDAFILE) << "Load panda file failed: " << location;
27         return false;
28     }
29     auto runtime = Runtime::GetCurrent();
30     if (Runtime::GetOptions().IsEnableAn() && !Runtime::GetOptions().IsArkAot()) {
31         TryLoadAnFileForLocation(location);
32         auto aotFile = runtime->GetClassLinker()->GetAotManager()->FindPandaFile(std::string(location));
33         if (aotFile != nullptr) {
34             pf->SetClassHashTable(aotFile->GetClassHashTable());
35         }
36     }
37     runtime->GetClassLinker()->AddPandaFile(std::move(pf));
38     return true;
39 }
40 
TryLoadAnFileForLocation(std::string_view abcPath)41 bool FileManager::TryLoadAnFileForLocation(std::string_view abcPath)
42 {
43     PandaString::size_type posStart = abcPath.find_last_of('/');
44     PandaString::size_type posEnd = abcPath.find_last_of('.');
45     if (posStart == std::string_view::npos || posEnd == std::string_view::npos) {
46         return true;
47     }
48     LOG(DEBUG, PANDAFILE) << "current abc file path: " << abcPath;
49     PandaString abcFilePrefix = PandaString(abcPath.substr(posStart, posEnd - posStart));
50 
51     // If set boot-an-location, load from this location first
52     std::string_view anLocation = Runtime::GetOptions().GetBootAnLocation();
53     if (!anLocation.empty()) {
54         bool res = FileManager::TryLoadAnFileFromLocation(anLocation, abcFilePrefix, abcPath);
55         if (res) {
56             return true;
57         }
58     }
59 
60     // If load failed from boot-an-location, continue try load from location of abc
61     anLocation = abcPath.substr(0, posStart);
62     FileManager::TryLoadAnFileFromLocation(anLocation, abcFilePrefix, abcPath);
63     return true;
64 }
65 
TryLoadAnFileFromLocation(std::string_view anFileLocation,PandaString & abcFilePrefix,std::string_view pandaFileLocation)66 bool FileManager::TryLoadAnFileFromLocation(std::string_view anFileLocation, PandaString &abcFilePrefix,
67                                             std::string_view pandaFileLocation)
68 {
69     const PandaString &anPathSuffix = ".an";
70     PandaString anFilePath = PandaString(anFileLocation) + abcFilePrefix + anPathSuffix;
71 
72     const char *filename = anFilePath.c_str();
73     if (access(filename, F_OK) != 0) {
74         LOG(DEBUG, PANDAFILE) << "There is no corresponding .an file for '" << pandaFileLocation << "' in '"
75                               << anFileLocation << "'";
76         return false;
77     }
78     auto res = FileManager::LoadAnFile(anFilePath, false);
79     if (res && res.Value()) {
80         LOG(INFO, PANDAFILE) << "Successfully load .an file for '" << pandaFileLocation << "': '" << anFileLocation
81                              << "'";
82         return true;
83     }
84     if (!res) {
85         LOG(INFO, PANDAFILE) << "Failed to load AOT file: '" << anFileLocation << "': " << res.Error();
86     } else {
87         LOG(INFO, PANDAFILE) << "Failed to load '" << anFileLocation << "' with unknown reason";
88     }
89     return false;
90 }
91 
LoadAnFile(std::string_view anLocation,bool force)92 Expected<bool, std::string> FileManager::LoadAnFile(std::string_view anLocation, bool force)
93 {
94     PandaRuntimeInterface runtimeIface;
95     auto runtime = Runtime::GetCurrent();
96     auto gcType = Runtime::GetGCType(Runtime::GetOptions(), plugins::RuntimeTypeToLang(runtime->GetRuntimeType()));
97     ASSERT(gcType != ark::mem::GCType::INVALID_GC);
98     auto realAnFilePath = os::GetAbsolutePath(anLocation);
99     return runtime->GetClassLinker()->GetAotManager()->AddFile(realAnFilePath, &runtimeIface,
100                                                                static_cast<uint32_t>(gcType), force);
101 }
102 
103 }  // namespace ark
104