#ifndef MRT_CJFILELOADER_H
#define MRT_CJFILELOADER_H
#include <functional>
#include <list>
#include <mutex>
#include <unordered_set>
#include "Base/HashUtils.h"
#include "Base/Types.h"
#include "Loader/ILoader.h"
#include "os/Loader.h"
#include "Loader/CjSemanticVersion/CjSemanticVersion.h"
#include "RuntimeConfig.h"
namespace MapleRuntime {
class CJFileLoader : public ILoader {
public:
CJFileLoader()
{
binLoadApi.binLoad = &Os::Loader::LoadBinaryFile;
binLoadApi.binUnload = &Os::Loader::UnloadBinaryFile;
binLoadApi.getBinaryInfoFromAddress = &Os::Loader::GetBinaryInfoFromAddress;
binLoadApi.findSymbol = &Os::Loader::FindSymbol;
}
~CJFileLoader() override
{
binLoadApi.binLoad = nullptr;
binLoadApi.binUnload = nullptr;
binLoadApi.getBinaryInfoFromAddress = nullptr;
binLoadApi.findSymbol = nullptr;
}
void Init() override {}
void Fini() override;
void RegisterLoadFile(Uptr address) override;
void UnregisterLoadFile(Uptr address) override;
void AddLoadedFiles(BaseFile* baseFile);
void AddPackageInfos(BaseFile* baseFile);
void RemoveLoadedFiles(BaseFile* baseFile);
void ClearLoadedFiles();
void VisitBaseFile(const std::function<bool(BaseFile*)>& f) const override;
bool LibInit(const char* libName) override;
void* LoadCJLibrary(const char* libName) override;
int UnloadLibrary(const char* libName) override;
Uptr FindSymbol(const CString libName, const CString symName) const override;
bool DoInitImage(BaseFile* baseFile) const override;
BaseFile* GetBaseFile(CString fileName) const override;
auto GetBinaryInfoFromAddressFunc() const { return binLoadApi.getBinaryInfoFromAddress; }
TypeInfo* FindTypeInfoFromLoadedFiles(const char* className) override;
TypeTemplate* FindTypeTemplateFromLoadedFiles(const char* className) override;
void RecordTypeInfo(TypeInfo* ti) override;
PackageInfo* GetPackageInfo(const char* packageName) const override;
PackageInfo* GetPackageInfoByPath(const char* path) override;
void RemovePackageInfo(const char* path) override;
bool FileHasLoaded(const char* path) override;
bool FileHasMultiPackage(const char* path) override;
void GetSubPackages(PackageInfo* packageInfo, std::vector<PackageInfo*> &subPackages) override;
void VisitExtensionData(
TypeInfo* ti, const std::function<bool(ExtensionData* ed)>& f, TypeTemplate* tt) const override;
bool CheckPackageCompatibility(BaseFile* file) override;
void TryThrowException(Uptr fileMetaAddr) override;
BaseFile* GetBaseFileByMetaAddr(Uptr fileMetaAddr);
BaseFile* CreateFileRefFromAddr(Uptr address) override;
U32 GetNumOfInterface(TypeInfo* typeInfo) override;
TypeInfo* GetInterface(TypeInfo* typeInfo, U32 idx) override;
TypeExt* GetTypeExt(void* type) override;
void RegisterTypeExt(BaseFile* baseFile) override;
#ifdef __OHOS__
void RegisterLoadFunc(void* loadFunc) override;
#endif
protected:
struct BinLoadApi binLoadApi;
private:
void ParseEnumCtor(TypeInfo* ti);
void RegisterTypeInfoCreatedByFE(BaseFile* baseFile);
void RegisterOuterTypeExtensions(BaseFile* baseFile);
int InitCJFile(const char* libName);
struct LibNameToHandler {
CString baseName;
void* handler;
};
std::mutex libCjsoHandlersMutex;
std::list<LibNameToHandler> cjLibHandlers;
std::list<BaseFile*> loadedFiles;
std::unordered_map<const char*, PackageInfo*, HashString, EqualString> packageInfos;
std::unordered_map<const char*, TypeInfo*, HashString, EqualString> typeInfoCache;
std::unordered_map<const char*, TypeTemplate*, HashString, EqualString> typeTemplateCache;
std::unordered_map<PackageInfo*, std::vector<PackageInfo*>> subPackageMap;
std::unordered_map<const char*, std::vector<PackageInfo*>, HashString, EqualString> filePackageMap;
std::unordered_map<BaseFile*, std::unordered_multimap<TypeTemplate*, ExtensionData*>> extensionDatas;
std::unordered_map<void*, TypeExt*> typeExts;
std::unordered_set<U32> lazyInitStaticGIs;
std::mutex lazyStaticGIMutex;
std::vector<TypeInfo*> staticGIs;
CjSemanticVersion compatibility;
};
}
#endif