Files
ft/Client/HybridCLRData/il2cpp_plus_repo/libil2cpp/hybridclr/metadata/MetadataModule.cpp
2026-06-29 21:18:33 +08:00

138 lines
4.8 KiB
C++

#include "MetadataModule.h"
#include "Baselib.h"
#include "os/Atomic.h"
#include "os/Mutex.h"
#include "os/File.h"
#include "vm/Exception.h"
#include "vm/String.h"
#include "vm/Assembly.h"
#include "vm/Class.h"
#include "vm/Object.h"
#include "vm/Image.h"
#include "vm/MetadataLock.h"
#include "utils/Logging.h"
#include "utils/MemoryMappedFile.h"
#include "utils/Memory.h"
#include "../interpreter/InterpreterModule.h"
#include "Assembly.h"
#include "InterpreterImage.h"
#include "ConsistentAOTHomologousImage.h"
#include "SuperSetAOTHomologousImage.h"
#include "ReversePInvokeMethodStub.h"
using namespace il2cpp;
namespace hybridclr
{
namespace metadata
{
Il2CppHashMap<const MethodInfo*, const ReversePInvokeInfo*, il2cpp::utils::PointerHash<MethodInfo>> MetadataModule::s_methodInfo2ReverseInfos;
Il2CppHashMap<Il2CppMethodPointer, const ReversePInvokeInfo*, il2cpp::utils::PassThroughHash<Il2CppMethodPointer>> MetadataModule::s_methodPointer2ReverseInfos;
Il2CppHashMap<const char*, int32_t, CStringHash, CStringEqualTo> MetadataModule::s_methodSig2Indexs;
std::vector<ReversePInvokeInfo> MetadataModule::s_reverseInfos;
static baselib::ReentrantLock g_reversePInvokeMethodLock;
void MetadataModule::InitReversePInvokeInfo()
{
for (int32_t i = 0; ; i++)
{
ReversePInvokeMethodData& data = g_reversePInvokeMethodStub[i];
if (data.methodPointer == nullptr)
{
break;
}
s_reverseInfos.push_back({ i, data.methodPointer, nullptr });
auto it = s_methodSig2Indexs.find(data.methodSig);
if (it == s_methodSig2Indexs.end())
{
s_methodSig2Indexs.insert({ data.methodSig, i });
}
}
s_methodInfo2ReverseInfos.resize(s_reverseInfos.size() * 2);
s_methodPointer2ReverseInfos.resize(s_reverseInfos.size() * 2);
for (ReversePInvokeInfo& rpi : s_reverseInfos)
{
s_methodPointer2ReverseInfos.insert({ rpi.methodPointer, &rpi });
}
}
void MetadataModule::Initialize()
{
InitReversePInvokeInfo();
InterpreterImage::Initialize();
Assembly::InitializePlaceHolderAssemblies();
}
Il2CppMethodPointer MetadataModule::GetReversePInvokeWrapper(const Il2CppImage* image, const MethodInfo* method)
{
if (!hybridclr::metadata::IsStaticMethod(method))
{
return nullptr;
}
il2cpp::os::FastAutoLock lock(&g_reversePInvokeMethodLock);
auto it = s_methodInfo2ReverseInfos.find(method);
if (it != s_methodInfo2ReverseInfos.end())
{
return it->second->methodPointer;
}
char sigName[1000];
interpreter::ComputeSignature(method, false, sigName, sizeof(sigName) - 1);
auto it2 = s_methodSig2Indexs.find(sigName);
if (it2 == s_methodSig2Indexs.end())
{
TEMP_FORMAT(methodSigBuf, "GetReversePInvokeWrapper fail. not find wrapper of method:%s", GetMethodNameWithSignature(method).c_str());
RaiseExecutionEngineException(methodSigBuf);
}
int32_t wrapperIndex = it2->second;
ReversePInvokeMethodData& data = g_reversePInvokeMethodStub[wrapperIndex];
if (data.methodPointer == nullptr || std::strcmp(data.methodSig, sigName))
{
TEMP_FORMAT(methodSigBuf, "GetReversePInvokeWrapper fail. exceed max wrapper num of method:%s", GetMethodNameWithSignature(method).c_str());
RaiseExecutionEngineException(methodSigBuf);
}
s_methodSig2Indexs[sigName] = wrapperIndex + 1;
ReversePInvokeInfo& rpi = s_reverseInfos[wrapperIndex];
rpi.methodInfo = method;
s_methodInfo2ReverseInfos.insert({ method, &rpi });
return rpi.methodPointer;
}
LoadImageErrorCode MetadataModule::LoadMetadataForAOTAssembly(const void* dllBytes, uint32_t dllSize, HomologousImageMode mode)
{
il2cpp::os::FastAutoLock lock(&il2cpp::vm::g_MetadataLock);
AOTHomologousImage* image = nullptr;
switch (mode)
{
case HomologousImageMode::CONSISTENT: image = new ConsistentAOTHomologousImage(); break;
case HomologousImageMode::SUPERSET: image = new SuperSetAOTHomologousImage(); break;
default: return LoadImageErrorCode::INVALID_HOMOLOGOUS_MODE;
}
LoadImageErrorCode err = image->Load((byte*)CopyBytes(dllBytes, dllSize), dllSize);
if (err != LoadImageErrorCode::OK)
{
return err;
}
if (AOTHomologousImage::FindImageByAssemblyLocked(image->GetAOTAssembly(), lock))
{
return LoadImageErrorCode::HOMOLOGOUS_ASSEMBLY_HAS_BEEN_LOADED;
}
image->InitRuntimeMetadatas();
AOTHomologousImage::RegisterLocked(image, lock);
return LoadImageErrorCode::OK;
}
}
}