Files
UnrealEngine/Engine/Source/Runtime/VerseCompiler/Private/uLang/Toolchain/ToolchainPluginManager.cpp
2025-05-18 13:04:45 +08:00

88 lines
3.2 KiB
C++

// Copyright Epic Games, Inc. All Rights Reserved.
#include "uLang/Toolchain/ToolchainPluginManager.h"
namespace uLang
{
class CLibAllocator : public ::uLang::CAllocatorInstance
{
public:
CLibAllocator()
: CAllocatorInstance(&Allocate, &Reallocate, &Deallocate)
{}
private:
static void* Allocate(const CAllocatorInstance* /*This*/, size_t NumBytes)
{
return CHeapRawAllocator::Allocate(NumBytes);
}
static void* Reallocate(const CAllocatorInstance* /*This*/, void* Memory, size_t NumBytes)
{
return CHeapRawAllocator::Reallocate(Memory, NumBytes);
}
static void Deallocate(const CAllocatorInstance* /*This*/, void* Memory)
{
CHeapRawAllocator::Deallocate(Memory);
}
};
IToolchainPlugin* CToolchainPluginManager::LoadPluginLib(const char* LibName)
{
ILibLoader::DyLibHandle LibHandle = _LibLoader->LoadLibrary(LibName);
IToolchainPlugin* LibInterface = nullptr;
if (ULANG_ENSUREF(LibHandle != ILibLoader::InvalidDyLibHandle, "Failed to load target library: %s", LibName))
{
SPluginInfo* ExistingDyLib = _LoadedLibs.FindByPredicate([LibHandle](const SPluginInfo* DyLib)->bool
{
return (LibHandle == DyLib->LibHandle);
});
if (ExistingDyLib)
{
LibInterface = ExistingDyLib->PluginInterface;
}
else
{
const char* GetVerProcName = ULANG_STRINGIFY(ULANG_PLUGIN_GETVER_PROCNAME);
::uLang::Private::ToolchainPluginGetVerPtr GetVerPtr = (::uLang::Private::ToolchainPluginGetVerPtr)_LibLoader->FindProcExport(LibHandle, GetVerProcName);
if (ULANG_ENSUREF(GetVerPtr, "Failed to find the expected version getter (%s), within the '%s' library.", GetVerProcName, LibName))
{
const int32_t LibVersion = GetVerPtr();
if (ULANG_ENSUREF(LibVersion == ULANG_API_VERSION,
"Mismatched API version -- %s lib (v%d) needs to be rebuilt with an updated core version (expected: v%d).",
LibName,
LibVersion,
ULANG_API_VERSION))
{
const char* InitProcName = ULANG_STRINGIFY(ULANG_PLUGIN_INIT_PROCNAME);
ILibLoader::DyLibProcPtr InitProcPtr = _LibLoader->FindProcExport(LibHandle, InitProcName);
if (ULANG_ENSUREF(InitProcPtr, "Failed to find expected entry point (%s), within the '%s' library.", InitProcName, LibName))
{
ULANG_ASSERTF(IsInitialized(), "Core should be properly initialized before loading any supplamentary libs.");
CLibAllocator Allocator;
Private::SToolchainPluginParams PluginParams(Allocator);
LibInterface = (::uLang::Private::ToolchainPluginInitPtr(InitProcPtr))(PluginParams);
if (ULANG_ENSUREF(LibInterface, "Library failed to produce the expected interface."))
{
LibInterface->OnLoad();
}
}
}
}
_LoadedLibs.AddNew(LibHandle, LibInterface);
}
}
return LibInterface;
}
} // namespace uLang