diff --git a/External/FEXCore/Source/Interface/Config/Config.cpp b/External/FEXCore/Source/Interface/Config/Config.cpp index 209d6ead5..9341dfc90 100644 --- a/External/FEXCore/Source/Interface/Config/Config.cpp +++ b/External/FEXCore/Source/Interface/Config/Config.cpp @@ -30,7 +30,7 @@ #include namespace FEXCore::Context { - struct Context; + class Context; } namespace FEXCore::Config { diff --git a/External/FEXCore/Source/Interface/Context/Context.cpp b/External/FEXCore/Source/Interface/Context/Context.cpp index 6433804b6..e1a1c6c4b 100644 --- a/External/FEXCore/Source/Interface/Context/Context.cpp +++ b/External/FEXCore/Source/Interface/Context/Context.cpp @@ -28,208 +28,108 @@ namespace FEXCore::Context { FEXCore::Paths::ShutdownPaths(); } - FEXCore::Context::Context *CreateNewContext() { - return new FEXCore::Context::Context{}; + FEXCore::Context::Context *FEXCore::Context::Context::CreateNewContext() { + return new FEXCore::Context::ContextImpl{}; } - bool InitializeContext(FEXCore::Context::Context *CTX) { - return FEXCore::CPU::CreateCPUCore(CTX); - } - - void DestroyContext(FEXCore::Context::Context *CTX) { - if (CTX->ParentThread) { - CTX->DestroyThread(CTX->ParentThread); - } + void FEXCore::Context::Context::DestroyContext(FEXCore::Context::Context *CTX) { + CTX->DestroyContext(); delete CTX; } - FEXCore::Core::InternalThreadState* InitCore(FEXCore::Context::Context *CTX, uint64_t InitialRIP, uint64_t StackPointer) { - return CTX->InitCore(InitialRIP, StackPointer); + bool FEXCore::Context::ContextImpl::InitializeContext() { + return FEXCore::CPU::CreateCPUCore(this); } - void SetExitHandler(FEXCore::Context::Context *CTX, ExitHandler handler) { - CTX->CustomExitHandler = std::move(handler); + void FEXCore::Context::ContextImpl::DestroyContext() { + if (ParentThread) { + DestroyThread(ParentThread); + } } - ExitHandler GetExitHandler(const FEXCore::Context::Context *CTX) { - return CTX->CustomExitHandler; + void FEXCore::Context::ContextImpl::SetExitHandler(ExitHandler handler) { + CustomExitHandler = std::move(handler); } - void Run(FEXCore::Context::Context *CTX) { - CTX->Run(); + ExitHandler FEXCore::Context::ContextImpl::GetExitHandler() const { + return CustomExitHandler; } - void Step(FEXCore::Context::Context *CTX) { - CTX->Step(); + void FEXCore::Context::ContextImpl::Stop() { + Stop(false); } - void CompileRIP(FEXCore::Core::InternalThreadState *Thread, uint64_t GuestRIP) { - Thread->CTX->CompileBlock(Thread->CurrentFrame, GuestRIP); + void FEXCore::Context::ContextImpl::CompileRIP(FEXCore::Core::InternalThreadState *Thread, uint64_t GuestRIP) { + CompileBlock(Thread->CurrentFrame, GuestRIP); } - FEXCore::Context::ExitReason RunUntilExit(FEXCore::Context::Context *CTX) { - return CTX->RunUntilExit(); + FEXCore::Context::ExitReason FEXCore::Context::ContextImpl::GetExitReason() { + return ParentThread->ExitReason; } - int GetProgramStatus(const FEXCore::Context::Context *CTX) { - return CTX->GetProgramStatus(); + bool FEXCore::Context::ContextImpl::IsDone() const { + return IsPaused(); } - FEXCore::Context::ExitReason GetExitReason(const FEXCore::Context::Context *CTX) { - return CTX->ParentThread->ExitReason; + void FEXCore::Context::ContextImpl::GetCPUState(FEXCore::Core::CPUState *State) const { + memcpy(State, ParentThread->CurrentFrame, sizeof(FEXCore::Core::CPUState)); } - bool IsDone(const FEXCore::Context::Context *CTX) { - return CTX->IsPaused(); + void FEXCore::Context::ContextImpl::SetCPUState(const FEXCore::Core::CPUState *State) { + memcpy(ParentThread->CurrentFrame, State, sizeof(FEXCore::Core::CPUState)); } - void GetCPUState(const FEXCore::Context::Context *CTX, FEXCore::Core::CPUState *State) { - memcpy(State, CTX->ParentThread->CurrentFrame, sizeof(FEXCore::Core::CPUState)); + void FEXCore::Context::ContextImpl::SetCustomCPUBackendFactory(CustomCPUFactoryType Factory) { + CustomCPUFactory = std::move(Factory); } - void SetCPUState(FEXCore::Context::Context *CTX, const FEXCore::Core::CPUState *State) { - memcpy(CTX->ParentThread->CurrentFrame, State, sizeof(FEXCore::Core::CPUState)); - } - - void Pause(FEXCore::Context::Context *CTX) { - CTX->Pause(); - } - - void Stop(FEXCore::Context::Context *CTX) { - CTX->Stop(false); - } - - void SetCustomCPUBackendFactory(FEXCore::Context::Context *CTX, CustomCPUFactoryType Factory) { - CTX->CustomCPUFactory = std::move(Factory); - } - - bool AddVirtualMemoryMapping([[maybe_unused]] FEXCore::Context::Context *CTX, [[maybe_unused]] uint64_t VirtualAddress, [[maybe_unused]] uint64_t PhysicalAddress, [[maybe_unused]] uint64_t Size) { + bool FEXCore::Context::ContextImpl::AddVirtualMemoryMapping([[maybe_unused]] uint64_t VirtualAddress, [[maybe_unused]] uint64_t PhysicalAddress, [[maybe_unused]] uint64_t Size) { return false; } - void RegisterExternalSyscallVisitor(FEXCore::Context::Context *CTX, [[maybe_unused]] uint64_t Syscall, [[maybe_unused]] FEXCore::HLE::SyscallVisitor *Visitor) { + HostFeatures FEXCore::Context::ContextImpl::GetHostFeatures() const { + return HostFeatures; } - HostFeatures GetHostFeatures(const FEXCore::Context::Context *CTX) { - return CTX->HostFeatures; + void FEXCore::Context::ContextImpl::SetSignalDelegator(FEXCore::SignalDelegator *_SignalDelegation) { + SignalDelegation = _SignalDelegation; } - void HandleCallback(FEXCore::Context::Context *CTX, FEXCore::Core::InternalThreadState *Thread, uint64_t RIP) { - CTX->HandleCallback(Thread, RIP); - } - void HandleSignalHandlerReturn(FEXCore::Context::Context *CTX, bool RT) { - CTX->HandleSignalHandlerReturn(RT); - } - void RegisterHostSignalHandler(FEXCore::Context::Context *CTX, int Signal, HostSignalDelegatorFunction Func, bool Required) { - CTX->RegisterHostSignalHandler(Signal, std::move(Func), Required); + void FEXCore::Context::ContextImpl::SetSyscallHandler(FEXCore::HLE::SyscallHandler *Handler) { + SyscallHandler = Handler; + SourcecodeResolver = Handler->GetSourcecodeResolver(); } - void RegisterFrontendHostSignalHandler(FEXCore::Context::Context *CTX, int Signal, HostSignalDelegatorFunction Func, bool Required) { - CTX->RegisterFrontendHostSignalHandler(Signal, std::move(Func), Required); + FEXCore::CPUID::FunctionResults FEXCore::Context::ContextImpl::RunCPUIDFunction(uint32_t Function, uint32_t Leaf) { + return CPUID.RunFunction(Function, Leaf); } - FEXCore::Core::InternalThreadState* CreateThread(FEXCore::Context::Context *CTX, FEXCore::Core::CPUState *NewThreadState, uint64_t ParentTID) { - return CTX->CreateThread(NewThreadState, ParentTID); - } - - void ExecutionThread(FEXCore::Context::Context *CTX, FEXCore::Core::InternalThreadState *Thread) { - return CTX->ExecutionThread(Thread); - } - - void InitializeThread(FEXCore::Context::Context *CTX, FEXCore::Core::InternalThreadState *Thread) { - return CTX->InitializeThread(Thread); - } - - void RunThread(FEXCore::Context::Context *CTX, FEXCore::Core::InternalThreadState *Thread) { - CTX->RunThread(Thread); - } - - void StopThread(FEXCore::Context::Context *CTX, FEXCore::Core::InternalThreadState *Thread) { - CTX->StopThread(Thread); - } - - void DestroyThread(FEXCore::Context::Context *CTX, FEXCore::Core::InternalThreadState *Thread) { - CTX->DestroyThread(Thread); - } - - void CleanupAfterFork(FEXCore::Context::Context *CTX, FEXCore::Core::InternalThreadState *Thread) { - CTX->CleanupAfterFork(Thread); - } - - void SetSignalDelegator(FEXCore::Context::Context *CTX, FEXCore::SignalDelegator *SignalDelegation) { - CTX->SignalDelegation = SignalDelegation; - } - - void SetSyscallHandler(FEXCore::Context::Context *CTX, FEXCore::HLE::SyscallHandler *Handler) { - CTX->SyscallHandler = Handler; - CTX->SourcecodeResolver = Handler->GetSourcecodeResolver(); - } - - FEXCore::CPUID::FunctionResults RunCPUIDFunction(FEXCore::Context::Context *CTX, uint32_t Function, uint32_t Leaf) { - return CTX->CPUID.RunFunction(Function, Leaf); - } - - FEX_DEFAULT_VISIBILITY FEXCore::CPUID::FunctionResults RunCPUIDFunctionName(FEXCore::Context::Context *CTX, uint32_t Function, uint32_t Leaf, uint32_t CPU) { - return CTX->CPUID.RunFunctionName(Function, Leaf, CPU); - } - - void SetAOTIRLoader(FEXCore::Context::Context *CTX, std::function CacheReader) { - CTX->SetAOTIRLoader(CacheReader); - } - - void SetAOTIRWriter(FEXCore::Context::Context *CTX, std::function(const std::string&)> CacheWriter) { - CTX->SetAOTIRWriter(CacheWriter); - } - - void SetAOTIRRenamer(FEXCore::Context::Context *CTX, std::function CacheRenamer) { - CTX->SetAOTIRRenamer(CacheRenamer); - } - - void FinalizeAOTIRCache(FEXCore::Context::Context *CTX) { - CTX->FinalizeAOTIRCache(); - } - - void WriteFilesWithCode(FEXCore::Context::Context *CTX, std::function Writer) { - CTX->WriteFilesWithCode(Writer); - } - - IR::AOTIRCacheEntry *LoadAOTIRCacheEntry(FEXCore::Context::Context *CTX, const std::string &Name) { - return CTX->LoadAOTIRCacheEntry(Name); - } - void UnloadAOTIRCacheEntry(FEXCore::Context::Context *CTX, IR::AOTIRCacheEntry *Entry) { - return CTX->UnloadAOTIRCacheEntry(Entry); - } - - CustomIRResult AddCustomIREntrypoint(FEXCore::Context::Context *CTX, uintptr_t Entrypoint, std::function Handler, void *Creator, void *Data) { - return CTX->AddCustomIREntrypoint(Entrypoint, Handler, Creator, Data); - } - - void AppendThunkDefinitions(FEXCore::Context::Context *CTX, std::vector const& Definitions) { - CTX->AppendThunkDefinitions(Definitions); + FEXCore::CPUID::FunctionResults FEXCore::Context::ContextImpl::RunCPUIDFunctionName(uint32_t Function, uint32_t Leaf, uint32_t CPU) { + return CPUID.RunFunctionName(Function, Leaf, CPU); } void SetVDSOSigReturn(FEXCore::Context::Context *CTX, const VDSOSigReturn &Pointers) { CTX->SetVDSOSigReturn(Pointers); } namespace Debug { - void CompileRIP(FEXCore::Context::Context *CTX, uint64_t RIP) { - CTX->CompileRIP(CTX->ParentThread, RIP); - } - uint64_t GetThreadCount(FEXCore::Context::Context *CTX) { - return CTX->GetThreadCount(); - } + //void CompileRIP(FEXCore::Context::Context *CTX, uint64_t RIP) { + // CTX->CompileRIP(CTX->ParentThread, RIP); + //} + //uint64_t GetThreadCount(FEXCore::Context::Context *CTX) { + // return CTX->GetThreadCount(); + //} - FEXCore::Core::RuntimeStats *GetRuntimeStatsForThread(FEXCore::Context::Context *CTX, uint64_t Thread) { - return CTX->GetRuntimeStatsForThread(Thread); - } + //FEXCore::Core::RuntimeStats *GetRuntimeStatsForThread(FEXCore::Context::Context *CTX, uint64_t Thread) { + // return CTX->GetRuntimeStatsForThread(Thread); + //} - bool GetDebugDataForRIP(FEXCore::Context::Context *CTX, uint64_t RIP, FEXCore::Core::DebugData *Data) { - return CTX->GetDebugDataForRIP(RIP, Data); - } + //bool GetDebugDataForRIP(FEXCore::Context::Context *CTX, uint64_t RIP, FEXCore::Core::DebugData *Data) { + // return CTX->GetDebugDataForRIP(RIP, Data); + //} - bool FindHostCodeForRIP(FEXCore::Context::Context *CTX, uint64_t RIP, uint8_t **Code) { - return CTX->FindHostCodeForRIP(RIP, Code); - } + //bool FindHostCodeForRIP(FEXCore::Context::Context *CTX, uint64_t RIP, uint8_t **Code) { + // return CTX->FindHostCodeForRIP(RIP, Code); + //} // XXX: // bool FindIRForRIP(FEXCore::Context::Context *CTX, uint64_t RIP, FEXCore::IR::IntrusiveIRList **ir) { diff --git a/External/FEXCore/Source/Interface/Context/Context.h b/External/FEXCore/Source/Interface/Context/Context.h index 317504749..d4ae72324 100644 --- a/External/FEXCore/Source/Interface/Context/Context.h +++ b/External/FEXCore/Source/Interface/Context/Context.h @@ -70,7 +70,130 @@ namespace FEXCore::Context { MODE_SINGLESTEP = 1, }; - struct Context { + class ContextImpl final : public FEXCore::Context::Context { + public: + // Context base class implementation. + bool InitializeContext() override; + + void DestroyContext() override; + + FEXCore::Core::InternalThreadState* InitCore(uint64_t InitialRIP, uint64_t StackPointer) override; + + void SetExitHandler(ExitHandler handler) override; + ExitHandler GetExitHandler() const override; + + void Pause() override; + void Run() override; + void Stop() override; + void Step() override; + + ExitReason RunUntilExit() override; + + void CompileRIP(FEXCore::Core::InternalThreadState *Thread, uint64_t GuestRIP) override; + + int GetProgramStatus() const override; + + ExitReason GetExitReason() override; + + bool IsDone() const override; + + void GetCPUState(FEXCore::Core::CPUState *State) const override; + void SetCPUState(const FEXCore::Core::CPUState *State) override; + + void SetCustomCPUBackendFactory(CustomCPUFactoryType Factory) override; + + bool AddVirtualMemoryMapping(uint64_t VirtualAddress, uint64_t PhysicalAddress, uint64_t Size) override; + + HostFeatures GetHostFeatures() const override; + + void HandleCallback(FEXCore::Core::InternalThreadState *Thread, uint64_t RIP) override; + + void RegisterHostSignalHandler(int Signal, HostSignalDelegatorFunction Func, bool Required) override; + [[noreturn]] void HandleSignalHandlerReturn(bool RT) override ; + void RegisterFrontendHostSignalHandler(int Signal, HostSignalDelegatorFunction Func, bool Required) override; + + /** + * @brief Used to create FEX thread objects in preparation for creating a true OS thread. Does set a TID or PID. + * + * @param NewThreadState The initial thread state to setup for our state + * @param ParentTID The PID that was the parent thread that created this + * + * @return The InternalThreadState object that tracks all of the emulated thread's state + * + * Usecases: + * OS thread Creation: + * - Thread = CreateThread(NewState, PPID); + * - InitializeThread(Thread); + * OS fork (New thread created with a clone of thread state): + * - clone{2, 3} + * - Thread = CreateThread(CopyOfThreadState, PPID); + * - ExecutionThread(Thread); // Starts executing without creating another host thread + * Thunk callback executing guest code from native host thread + * - Thread = CreateThread(NewState, PPID); + * - InitializeThreadTLSData(Thread); + * - HandleCallback(Thread, RIP); + */ + FEXCore::Core::InternalThreadState* CreateThread(FEXCore::Core::CPUState *NewThreadState, uint64_t ParentTID) override; + + // Public for threading + void ExecutionThread(FEXCore::Core::InternalThreadState *Thread) override; + /** + * @brief Initializes the OS thread object and prepares to start executing on that new OS thread + * + * @param Thread The internal FEX thread state object + * + * The OS thread will wait until RunThread is executed + */ + void InitializeThread(FEXCore::Core::InternalThreadState *Thread) override; + /** + * @brief Starts the OS thread object to start executing guest code + * + * @param Thread The internal FEX thread state object + */ + void RunThread(FEXCore::Core::InternalThreadState *Thread) override; + void StopThread(FEXCore::Core::InternalThreadState *Thread) override; + /** + * @brief Destroys this FEX thread object and stops tracking it internally + * + * @param Thread The internal FEX thread state object + */ + void DestroyThread(FEXCore::Core::InternalThreadState *Thread) override; + void CleanupAfterFork(FEXCore::Core::InternalThreadState *Thread) override; + void SetSignalDelegator(FEXCore::SignalDelegator *SignalDelegation) override; + void SetSyscallHandler(FEXCore::HLE::SyscallHandler *Handler) override; + FEXCore::CPUID::FunctionResults RunCPUIDFunction(uint32_t Function, uint32_t Leaf) override; + FEXCore::CPUID::FunctionResults RunCPUIDFunctionName(uint32_t Function, uint32_t Leaf, uint32_t CPU) override; + + FEXCore::IR::AOTIRCacheEntry *LoadAOTIRCacheEntry(const std::string& Name) override; + void UnloadAOTIRCacheEntry(FEXCore::IR::AOTIRCacheEntry *Entry) override; + + void SetAOTIRLoader(std::function CacheReader) override { + IRCaptureCache.SetAOTIRLoader(CacheReader); + } + void SetAOTIRWriter(std::function(const std::string&)> CacheWriter) override { + IRCaptureCache.SetAOTIRWriter(CacheWriter); + } + void SetAOTIRRenamer(std::function CacheRenamer) override { + IRCaptureCache.SetAOTIRRenamer(CacheRenamer); + } + + void FinalizeAOTIRCache() override { + IRCaptureCache.FinalizeAOTIRCache(); + } + void WriteFilesWithCode(std::function Writer) override { + IRCaptureCache.WriteFilesWithCode(Writer); + } + void InvalidateGuestCodeRange(uint64_t Start, uint64_t Length) override; + void InvalidateGuestCodeRange(uint64_t Start, uint64_t Length, std::function callback) override; + void MarkMemoryShared() override; + + void ConfigureAOTGen(FEXCore::Core::InternalThreadState *Thread, std::set *ExternalBranches, uint64_t SectionMaxAddress) override; + // returns false if a handler was already registered + CustomIRResult AddCustomIREntrypoint(uintptr_t Entrypoint, std::function Handler, void *Creator = nullptr, void *Data = nullptr) override; + + void AppendThunkDefinitions(std::vector const& Definitions) override; + + public: friend class FEXCore::HLE::SyscallHandler; #ifdef JIT_ARM64 friend class FEXCore::CPU::Arm64JITCore; @@ -154,36 +277,25 @@ namespace FEXCore::Context { X86GeneratedCode X86CodeGen; VDSOSigReturn VDSOPointers{}; - Context(); - ~Context(); + ContextImpl(); + ~ContextImpl(); - FEXCore::Core::InternalThreadState* InitCore(uint64_t InitialRIP, uint64_t StackPointer); - FEXCore::Context::ExitReason RunUntilExit(); - int GetProgramStatus() const; bool IsPaused() const { return !Running; } - void Pause(); - void Run(); void WaitForThreadsToRun(); - void Step(); void Stop(bool IgnoreCurrentThread); void WaitForIdle(); - void StopThread(FEXCore::Core::InternalThreadState *Thread); void SignalThread(FEXCore::Core::InternalThreadState *Thread, FEXCore::Core::SignalEvent Event); bool GetGdbServerStatus() const { return DebugServer != nullptr; } void StartGdbServer(); void StopGdbServer(); - void HandleCallback(FEXCore::Core::InternalThreadState *Thread, uint64_t RIP); - [[noreturn]] void HandleSignalHandlerReturn(bool RT); - void RegisterHostSignalHandler(int Signal, HostSignalDelegatorFunction Func, bool Required); - void RegisterFrontendHostSignalHandler(int Signal, HostSignalDelegatorFunction Func, bool Required); static void ThreadRemoveCodeEntry(FEXCore::Core::InternalThreadState *Thread, uint64_t GuestRIP); static void ThreadAddBlockLink(FEXCore::Core::InternalThreadState *Thread, uint64_t GuestDestination, uintptr_t HostLink, const std::function &delinker); template static uint64_t ThreadExitFunctionLink(FEXCore::Core::CpuStateFrame *Frame, uint64_t *record) { - FHU::ScopedSignalMaskWithSharedLock lk(Frame->Thread->CTX->CodeInvalidationMutex); + FHU::ScopedSignalMaskWithSharedLock lk(static_cast(Frame->Thread->CTX)->CodeInvalidationMutex); return Fn(Frame, record); } @@ -192,21 +304,17 @@ namespace FEXCore::Context { // Must be called from owning thread static void ThreadRemoveCodeEntryFromJit(FEXCore::Core::CpuStateFrame *Frame, uint64_t GuestRIP) { auto Thread = Frame->Thread; - + LogMan::Throw::AFmt(Thread->ThreadManager.GetTID() == FHU::Syscalls::gettid(), "Must be called from owning thread {}, not {}", Thread->ThreadManager.GetTID(), FHU::Syscalls::gettid()); - FHU::ScopedSignalMaskWithUniqueLock lk(Thread->CTX->CodeInvalidationMutex); + FHU::ScopedSignalMaskWithUniqueLock lk(static_cast(Thread->CTX)->CodeInvalidationMutex); ThreadRemoveCodeEntry(Thread, GuestRIP); } - // returns false if a handler was already registered - CustomIRResult AddCustomIREntrypoint(uintptr_t Entrypoint, std::function Handler, void *Creator, void *Data); - void RemoveCustomIREntrypoint(uintptr_t Entrypoint); // Debugger interface - void CompileRIP(FEXCore::Core::InternalThreadState *Thread, uint64_t RIP); uint64_t GetThreadCount() const; FEXCore::Core::RuntimeStats *GetRuntimeStatsForThread(uint64_t Thread); bool GetDebugDataForRIP(uint64_t RIP, FEXCore::Core::DebugData *Data); @@ -238,29 +346,6 @@ namespace FEXCore::Context { void CompileBlockJit(FEXCore::Core::CpuStateFrame *Frame, uint64_t GuestRIP); // Used for thread creation from syscalls - /** - * @brief Used to create FEX thread objects in preparation for creating a true OS thread. Does set a TID or PID. - * - * @param NewThreadState The initial thread state to setup for our state - * @param ParentTID The PID that was the parent thread that created this - * - * @return The InternalThreadState object that tracks all of the emulated thread's state - * - * Usecases: - * OS thread Creation: - * - Thread = CreateThread(NewState, PPID); - * - InitializeThread(Thread); - * OS fork (New thread created with a clone of thread state): - * - clone{2, 3} - * - Thread = CreateThread(CopyOfThreadState, PPID); - * - ExecutionThread(Thread); // Starts executing without creating another host thread - * Thunk callback executing guest code from native host thread - * - Thread = CreateThread(NewState, PPID); - * - InitializeThreadTLSData(Thread); - * - HandleCallback(Thread, RIP); - */ - FEXCore::Core::InternalThreadState* CreateThread(FEXCore::Core::CPUState *NewThreadState, uint64_t ParentTID); - /** * @brief Initializes TID, PID and TLS data for a thread * @@ -268,67 +353,15 @@ namespace FEXCore::Context { */ void InitializeThreadTLSData(FEXCore::Core::InternalThreadState *Thread); - /** - * @brief Initializes the OS thread object and prepares to start executing on that new OS thread - * - * @param Thread The internal FEX thread state object - * - * The OS thread will wait until RunThread is executed - */ - void InitializeThread(FEXCore::Core::InternalThreadState *Thread); - - /** - * @brief Starts the OS thread object to start executing guest code - * - * @param Thread The internal FEX thread state object - */ - void RunThread(FEXCore::Core::InternalThreadState *Thread); - - /** - * @brief Destroys this FEX thread object and stops tracking it internally - * - * @param Thread The internal FEX thread state object - */ - void DestroyThread(FEXCore::Core::InternalThreadState *Thread); void CopyMemoryMapping(FEXCore::Core::InternalThreadState *ParentThread, FEXCore::Core::InternalThreadState *ChildThread); - void CleanupAfterFork(FEXCore::Core::InternalThreadState *ExceptForThread); - std::vector* GetThreads() { return &Threads; } uint8_t GetGPRSize() const { return Config.Is64BitMode ? 8 : 4; } - IR::AOTIRCacheEntry *LoadAOTIRCacheEntry(const std::string &filename); - void UnloadAOTIRCacheEntry(IR::AOTIRCacheEntry *Entry); - FEXCore::JITSymbols Symbols; - // Public for threading - void ExecutionThread(FEXCore::Core::InternalThreadState *Thread); - - void FinalizeAOTIRCache() { - IRCaptureCache.FinalizeAOTIRCache(); - } - - void WriteFilesWithCode(std::function Writer) { - IRCaptureCache.WriteFilesWithCode(Writer); - } - - void SetAOTIRLoader(std::function CacheReader) { - IRCaptureCache.SetAOTIRLoader(CacheReader); - } - - void SetAOTIRWriter(std::function(const std::string&)> CacheWriter) { - IRCaptureCache.SetAOTIRWriter(CacheWriter); - } - - void SetAOTIRRenamer(std::function CacheRenamer) { - IRCaptureCache.SetAOTIRRenamer(CacheRenamer); - } - - void AppendThunkDefinitions(std::vector const& Definitions); - - void SetVDSOSigReturn(const VDSOSigReturn &Pointers) { + void SetVDSOSigReturn(const VDSOSigReturn &Pointers) override { VDSOPointers = Pointers; if (VDSOPointers.VDSO_kernel_sigreturn == nullptr) { VDSOPointers.VDSO_kernel_sigreturn = reinterpret_cast(X86CodeGen.sigreturn_32); @@ -342,8 +375,6 @@ namespace FEXCore::Context { FEXCore::Utils::PooledAllocatorMMap OpDispatcherAllocator; FEXCore::Utils::PooledAllocatorMMap FrontendAllocator; - void MarkMemoryShared(); - bool IsTSOEnabled() { return (IsMemoryShared || !Config.TSOAutoMigration) && Config.TSOEnabled; } protected: diff --git a/External/FEXCore/Source/Interface/Core/ArchHelpers/Arm64Emitter.cpp b/External/FEXCore/Source/Interface/Core/ArchHelpers/Arm64Emitter.cpp index 5aa24e539..63c210102 100644 --- a/External/FEXCore/Source/Interface/Core/ArchHelpers/Arm64Emitter.cpp +++ b/External/FEXCore/Source/Interface/Core/ArchHelpers/Arm64Emitter.cpp @@ -20,7 +20,7 @@ namespace FEXCore::CPU { // We want vixl to not allocate a default buffer. Jit and dispatcher will manually create one. -Arm64Emitter::Arm64Emitter(FEXCore::Context::Context *ctx, size_t size) +Arm64Emitter::Arm64Emitter(FEXCore::Context::ContextImpl *ctx, size_t size) : Emitter(size ? (uint8_t*)FEXCore::Allocator::mmap(nullptr, size, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0) : nullptr, size) , EmitterCTX {ctx} { CPU.SetUp(); diff --git a/External/FEXCore/Source/Interface/Core/ArchHelpers/Arm64Emitter.h b/External/FEXCore/Source/Interface/Core/ArchHelpers/Arm64Emitter.h index 32c8c0eba..ddf2810b0 100644 --- a/External/FEXCore/Source/Interface/Core/ArchHelpers/Arm64Emitter.h +++ b/External/FEXCore/Source/Interface/Core/ArchHelpers/Arm64Emitter.h @@ -85,10 +85,10 @@ constexpr FEXCore::ARMEmitter::PRegister PRED_TMP_32B = FEXCore::ARMEmitter::PRe // be used by both Arm64 JIT and ARM64 Dispatcher class Arm64Emitter : public FEXCore::ARMEmitter::Emitter { protected: - Arm64Emitter(FEXCore::Context::Context *ctx, size_t size); + Arm64Emitter(FEXCore::Context::ContextImpl *ctx, size_t size); ~Arm64Emitter(); - FEXCore::Context::Context *EmitterCTX; + FEXCore::Context::ContextImpl *EmitterCTX; vixl::aarch64::CPU CPU; void LoadConstant(FEXCore::ARMEmitter::Size s, FEXCore::ARMEmitter::Register Reg, uint64_t Constant, bool NOPPad = false); diff --git a/External/FEXCore/Source/Interface/Core/CPUBackend.cpp b/External/FEXCore/Source/Interface/Core/CPUBackend.cpp index 59cc7e659..2f6bc20ea 100644 --- a/External/FEXCore/Source/Interface/Core/CPUBackend.cpp +++ b/External/FEXCore/Source/Interface/Core/CPUBackend.cpp @@ -60,8 +60,8 @@ auto CPUBackend::AllocateNewCodeBuffer(size_t Size) -> CodeBuffer { FEXCore::Allocator::mmap(nullptr, Buffer.Size, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0)); LOGMAN_THROW_AA_FMT(!!Buffer.Ptr, "Couldn't allocate code buffer"); - if (ThreadState->CTX->Config.GlobalJITNaming()) { - ThreadState->CTX->Symbols.RegisterJITSpace(Buffer.Ptr, Buffer.Size); + if (static_cast(ThreadState->CTX)->Config.GlobalJITNaming()) { + static_cast(ThreadState->CTX)->Symbols.RegisterJITSpace(Buffer.Ptr, Buffer.Size); } return Buffer; } diff --git a/External/FEXCore/Source/Interface/Core/CPUID.cpp b/External/FEXCore/Source/Interface/Core/CPUID.cpp index 01e33a203..f2201acf6 100644 --- a/External/FEXCore/Source/Interface/Core/CPUID.cpp +++ b/External/FEXCore/Source/Interface/Core/CPUID.cpp @@ -1210,7 +1210,7 @@ FEXCore::CPUID::FunctionResults CPUIDEmu::Function_Reserved(uint32_t Leaf) { return Res; } -void CPUIDEmu::Init(FEXCore::Context::Context *ctx) { +void CPUIDEmu::Init(FEXCore::Context::ContextImpl *ctx) { CTX = ctx; // Setup some state tracking diff --git a/External/FEXCore/Source/Interface/Core/CPUID.h b/External/FEXCore/Source/Interface/Core/CPUID.h index 6ec72991e..dfa8ca2a5 100644 --- a/External/FEXCore/Source/Interface/Core/CPUID.h +++ b/External/FEXCore/Source/Interface/Core/CPUID.h @@ -10,7 +10,7 @@ namespace FEXCore { namespace Context { - struct Context; + class ContextImpl; } // Debugging define to switch what family of CPU we execute as. @@ -31,7 +31,7 @@ public: // if we report anything differently then applications are likely to break constexpr static uint64_t CACHELINE_SIZE = 64; - void Init(FEXCore::Context::Context *ctx); + void Init(FEXCore::Context::ContextImpl *ctx); FEXCore::CPUID::FunctionResults RunFunction(uint32_t Function, uint32_t Leaf) { if (Function < Primary.size()) { @@ -64,7 +64,7 @@ public: } private: - FEXCore::Context::Context *CTX; + FEXCore::Context::ContextImpl *CTX; bool Hybrid{}; FEX_CONFIG_OPT(Cores, THREADS); diff --git a/External/FEXCore/Source/Interface/Core/Core.cpp b/External/FEXCore/Source/Interface/Core/Core.cpp index bf1228578..41164f0e7 100644 --- a/External/FEXCore/Source/Interface/Core/Core.cpp +++ b/External/FEXCore/Source/Interface/Core/Core.cpp @@ -79,7 +79,7 @@ $end_info$ namespace FEXCore::CPU { - bool CreateCPUCore(FEXCore::Context::Context *CTX) { + bool CreateCPUCore(Context::ContextImpl *CTX) { // This should be used for generating things that are shared between threads CTX->CPUID.Init(CTX); return true; @@ -147,7 +147,7 @@ std::string_view const& GetGRegName(unsigned Reg) { } // namespace FEXCore::Core namespace FEXCore::Context { - Context::Context() + ContextImpl::ContextImpl() : IRCaptureCache {this} { #ifdef BLOCKSTATS BlockData = std::make_unique(); @@ -172,7 +172,7 @@ namespace FEXCore::Context { } } - Context::~Context() { + ContextImpl::~ContextImpl() { { if (CodeObjectCacheService) { CodeObjectCacheService->Shutdown(); @@ -214,7 +214,7 @@ namespace FEXCore::Context { return NewThreadState; } - FEXCore::Core::InternalThreadState* Context::InitCore(uint64_t InitialRIP, uint64_t StackPointer) { + FEXCore::Core::InternalThreadState* ContextImpl::InitCore(uint64_t InitialRIP, uint64_t StackPointer) { // Initialize the CPU core signal handlers & DispatcherConfig switch (Config.Core) { #ifdef INTERPRETER_ENABLED @@ -255,13 +255,13 @@ namespace FEXCore::Context { // Initialize common signal handlers auto PauseHandler = [](FEXCore::Core::InternalThreadState *Thread, int Signal, void *info, void *ucontext) -> bool { - return Thread->CTX->Dispatcher->HandleSignalPause(Thread, Signal, info, ucontext); + return static_cast(Thread->CTX)->Dispatcher->HandleSignalPause(Thread, Signal, info, ucontext); }; SignalDelegation->RegisterHostSignalHandler(SignalDelegator::SIGNAL_FOR_PAUSE, PauseHandler, true); auto GuestSignalHandler = [](FEXCore::Core::InternalThreadState *Thread, int Signal, void *info, void *ucontext, GuestSigAction *GuestAction, stack_t *GuestStack) -> bool { - return Thread->CTX->Dispatcher->HandleGuestSignal(Thread, Signal, info, ucontext, GuestAction, GuestStack); + return static_cast(Thread->CTX)->Dispatcher->HandleGuestSignal(Thread, Signal, info, ucontext, GuestAction, GuestStack); }; for (uint32_t Signal = 0; Signal <= SignalDelegator::MAX_SIGNALS; ++Signal) { @@ -295,22 +295,22 @@ namespace FEXCore::Context { return Thread; } - void Context::StartGdbServer() { + void ContextImpl::StartGdbServer() { if (!DebugServer) { DebugServer = std::make_unique(this); StartPaused = true; } } - void Context::StopGdbServer() { + void ContextImpl::StopGdbServer() { DebugServer.reset(); } - void Context::HandleCallback(FEXCore::Core::InternalThreadState *Thread, uint64_t RIP) { - Thread->CTX->Dispatcher->ExecuteJITCallback(Thread->CurrentFrame, RIP); + void ContextImpl::HandleCallback(FEXCore::Core::InternalThreadState *Thread, uint64_t RIP) { + static_cast(Thread->CTX)->Dispatcher->ExecuteJITCallback(Thread->CurrentFrame, RIP); } - void Context::HandleSignalHandlerReturn(bool RT) { + void ContextImpl::HandleSignalHandlerReturn(bool RT) { using SignalHandlerReturnFunc = void(*)(); SignalHandlerReturnFunc SignalHandlerReturn{}; @@ -325,15 +325,15 @@ namespace FEXCore::Context { FEX_UNREACHABLE; } - void Context::RegisterHostSignalHandler(int Signal, HostSignalDelegatorFunction Func, bool Required) { + void ContextImpl::RegisterHostSignalHandler(int Signal, HostSignalDelegatorFunction Func, bool Required) { SignalDelegation->RegisterHostSignalHandler(Signal, Func, Required); } - void Context::RegisterFrontendHostSignalHandler(int Signal, HostSignalDelegatorFunction Func, bool Required) { + void ContextImpl::RegisterFrontendHostSignalHandler(int Signal, HostSignalDelegatorFunction Func, bool Required) { SignalDelegation->RegisterFrontendHostSignalHandler(Signal, Func, Required); } - void Context::WaitForIdle() { + void ContextImpl::WaitForIdle() { std::unique_lock lk(IdleWaitMutex); IdleWaitCV.wait(lk, [this] { return IdleWaitRefCount.load() == 0; @@ -342,7 +342,7 @@ namespace FEXCore::Context { Running = false; } - void Context::WaitForIdleWithTimeout() { + void ContextImpl::WaitForIdleWithTimeout() { std::unique_lock lk(IdleWaitMutex); bool WaitResult = IdleWaitCV.wait_for(lk, std::chrono::milliseconds(1500), [this] { @@ -360,7 +360,7 @@ namespace FEXCore::Context { WaitForIdle(); } - void Context::NotifyPause() { + void ContextImpl::NotifyPause() { // Tell all the threads that they should pause std::lock_guard lk(ThreadCreationMutex); @@ -373,7 +373,7 @@ namespace FEXCore::Context { } } - void Context::Pause() { + void ContextImpl::Pause() { // If we aren't running, WaitForIdle will never compete. if (Running) { NotifyPause(); @@ -382,7 +382,7 @@ namespace FEXCore::Context { } } - void Context::Run() { + void ContextImpl::Run() { // Spin up all the threads std::lock_guard lk(ThreadCreationMutex); for (auto &Thread : Threads) { @@ -394,7 +394,7 @@ namespace FEXCore::Context { } } - void Context::WaitForThreadsToRun() { + void ContextImpl::WaitForThreadsToRun() { size_t NumThreads{}; { std::lock_guard lk(ThreadCreationMutex); @@ -410,7 +410,7 @@ namespace FEXCore::Context { Running = true; } - void Context::Step() { + void ContextImpl::Step() { { std::lock_guard lk(ThreadCreationMutex); // Walk the threads and tell them to clear their caches @@ -430,7 +430,7 @@ namespace FEXCore::Context { this->Config.MaxInstPerBlock = PreviousMaxIntPerBlock; } - void Context::Stop(bool IgnoreCurrentThread) { + void ContextImpl::Stop(bool IgnoreCurrentThread) { pid_t tid = FHU::Syscalls::gettid(); FEXCore::Core::InternalThreadState* CurrentThread{}; @@ -468,21 +468,21 @@ namespace FEXCore::Context { } } - void Context::StopThread(FEXCore::Core::InternalThreadState *Thread) { + void ContextImpl::StopThread(FEXCore::Core::InternalThreadState *Thread) { if (Thread->RunningEvents.Running.exchange(false)) { Thread->SignalReason.store(FEXCore::Core::SignalEvent::Stop); FHU::Syscalls::tgkill(Thread->ThreadManager.PID, Thread->ThreadManager.TID, SignalDelegator::SIGNAL_FOR_PAUSE); } } - void Context::SignalThread(FEXCore::Core::InternalThreadState *Thread, FEXCore::Core::SignalEvent Event) { + void ContextImpl::SignalThread(FEXCore::Core::InternalThreadState *Thread, FEXCore::Core::SignalEvent Event) { if (Thread->RunningEvents.Running.load()) { Thread->SignalReason.store(Event); FHU::Syscalls::tgkill(Thread->ThreadManager.PID, Thread->ThreadManager.TID, SignalDelegator::SIGNAL_FOR_PAUSE); } } - FEXCore::Context::ExitReason Context::RunUntilExit() { + FEXCore::Context::ExitReason ContextImpl::RunUntilExit() { if(!StartPaused) { // We will only have one thread at this point, but just in case run notify everything std::lock_guard lk(ThreadCreationMutex); @@ -503,16 +503,16 @@ namespace FEXCore::Context { } } - int Context::GetProgramStatus() const { + int ContextImpl::GetProgramStatus() const { return ParentThread->StatusCode; } - void Context::InitializeThreadData(FEXCore::Core::InternalThreadState *Thread) { + void ContextImpl::InitializeThreadData(FEXCore::Core::InternalThreadState *Thread) { Thread->CPUBackend->Initialize(); } struct ExecutionThreadHandler { - FEXCore::Context::Context *This; + ContextImpl *This; FEXCore::Core::InternalThreadState *Thread; }; @@ -523,7 +523,7 @@ namespace FEXCore::Context { return nullptr; } - void Context::InitializeThread(FEXCore::Core::InternalThreadState *Thread) { + void ContextImpl::InitializeThread(FEXCore::Core::InternalThreadState *Thread) { // This will create the execution thread but it won't actually start executing ExecutionThreadHandler *Arg = reinterpret_cast(FEXCore::Allocator::malloc(sizeof(ExecutionThreadHandler))); Arg->This = this; @@ -545,7 +545,7 @@ namespace FEXCore::Context { } } - void Context::InitializeThreadTLSData(FEXCore::Core::InternalThreadState *Thread) { + void ContextImpl::InitializeThreadTLSData(FEXCore::Core::InternalThreadState *Thread) { // Let's do some initial bookkeeping here Thread->ThreadManager.TID = FHU::Syscalls::gettid(); Thread->ThreadManager.PID = ::getpid(); @@ -553,12 +553,12 @@ namespace FEXCore::Context { ThunkHandler->RegisterTLSState(Thread); } - void Context::RunThread(FEXCore::Core::InternalThreadState *Thread) { + void ContextImpl::RunThread(FEXCore::Core::InternalThreadState *Thread) { // Tell the thread to start executing Thread->StartRunning.NotifyAll(); } - void Context::InitializeCompiler(FEXCore::Core::InternalThreadState* Thread) { + void ContextImpl::InitializeCompiler(FEXCore::Core::InternalThreadState* Thread) { Thread->OpDispatcher = std::make_unique(this); Thread->OpDispatcher->SetMultiblock(Config.Multiblock); Thread->LookupCache = std::make_unique(this); @@ -610,7 +610,7 @@ namespace FEXCore::Context { } } - FEXCore::Core::InternalThreadState* Context::CreateThread(FEXCore::Core::CPUState *NewThreadState, uint64_t ParentTID) { + FEXCore::Core::InternalThreadState* ContextImpl::CreateThread(FEXCore::Core::CPUState *NewThreadState, uint64_t ParentTID) { FEXCore::Core::InternalThreadState *Thread = new FEXCore::Core::InternalThreadState{}; // Copy over the new thread state to the new object @@ -632,7 +632,7 @@ namespace FEXCore::Context { return Thread; } - void Context::DestroyThread(FEXCore::Core::InternalThreadState *Thread) { + void ContextImpl::DestroyThread(FEXCore::Core::InternalThreadState *Thread) { // remove new thread object { std::lock_guard lk(ThreadCreationMutex); @@ -651,7 +651,7 @@ namespace FEXCore::Context { delete Thread; } - void Context::CleanupAfterFork(FEXCore::Core::InternalThreadState *LiveThread) { + void ContextImpl::CleanupAfterFork(FEXCore::Core::InternalThreadState *LiveThread) { // This function is called after fork // We need to cleanup some of the thread data that is dead for (auto &DeadThread : Threads) { @@ -690,11 +690,11 @@ namespace FEXCore::Context { FEXCore::Threads::Thread::CleanupAfterFork(); } - void Context::AddBlockMapping(FEXCore::Core::InternalThreadState *Thread, uint64_t Address, void *Ptr) { + void ContextImpl::AddBlockMapping(FEXCore::Core::InternalThreadState *Thread, uint64_t Address, void *Ptr) { Thread->LookupCache->AddBlockMapping(Address, Ptr); } - void Context::ClearCodeCache(FEXCore::Core::InternalThreadState *Thread) { + void ContextImpl::ClearCodeCache(FEXCore::Core::InternalThreadState *Thread) { FEXCORE_PROFILE_INSTANT("ClearCodeCache"); { @@ -712,7 +712,7 @@ namespace FEXCore::Context { static void IRDumper(FEXCore::Core::InternalThreadState *Thread, IR::IREmitter *IREmitter, uint64_t GuestRIP, IR::RegisterAllocationData* RA) { FILE* f = nullptr; bool CloseAfter = false; - const auto DumpIRStr = Thread->CTX->Config.DumpIR(); + const auto DumpIRStr = static_cast(Thread->CTX)->Config.DumpIR(); // DumpIRStr might be no if not dumping but ShouldDump is set in OpDisp if (DumpIRStr =="stderr" || DumpIRStr =="no") { @@ -739,7 +739,7 @@ namespace FEXCore::Context { } }; - static void ValidateIR(FEXCore::Context::Context *ctx, IR::IREmitter *IREmitter) { + static void ValidateIR(ContextImpl *ctx, IR::IREmitter *IREmitter) { // Convert to text, Parse, Convert to text again and make sure the texts match std::stringstream out; static auto compaction = IR::CreateIRCompaction(ctx->OpDispatcherAllocator); @@ -763,7 +763,7 @@ namespace FEXCore::Context { } } - Context::GenerateIRResult Context::GenerateIR(FEXCore::Core::InternalThreadState *Thread, uint64_t GuestRIP, bool ExtendedDebugInfo) { + ContextImpl::GenerateIRResult ContextImpl::GenerateIR(FEXCore::Core::InternalThreadState *Thread, uint64_t GuestRIP, bool ExtendedDebugInfo) { FEXCORE_PROFILE_SCOPED("GenerateIR"); Thread->OpDispatcher->ReownOrClaimBuffer(); @@ -790,7 +790,7 @@ namespace FEXCore::Context { Thread->FrontendDecoder->DecodeInstructionsAtEntry(GuestCode, GuestRIP, [Thread](uint64_t BlockEntry, uint64_t Start, uint64_t Length) { if (Thread->LookupCache->AddBlockExecutableRange(BlockEntry, Start, Length)) { - Thread->CTX->SyscallHandler->MarkGuestExecutableRange(Start, Length); + static_cast(Thread->CTX)->SyscallHandler->MarkGuestExecutableRange(Start, Length); } }); @@ -908,14 +908,14 @@ namespace FEXCore::Context { IR::IREmitter *IREmitter = Thread->OpDispatcher.get(); - auto ShouldDump = Thread->CTX->Config.DumpIR() != "no" || Thread->OpDispatcher->ShouldDump; + auto ShouldDump = static_cast(Thread->CTX)->Config.DumpIR() != "no" || Thread->OpDispatcher->ShouldDump; // Debug { if (ShouldDump) { IRDumper(Thread, IREmitter, GuestRIP, nullptr); } - if (Thread->CTX->Config.ValidateIRarser) { + if (static_cast(Thread->CTX)->Config.ValidateIRarser) { ValidateIR(this, IREmitter); } } @@ -945,7 +945,7 @@ namespace FEXCore::Context { }; } - Context::CompileCodeResult Context::CompileCode(FEXCore::Core::InternalThreadState *Thread, uint64_t GuestRIP) { + ContextImpl::CompileCodeResult ContextImpl::CompileCode(FEXCore::Core::InternalThreadState *Thread, uint64_t GuestRIP) { FEXCore::IR::IRListView *IRList {}; FEXCore::Core::DebugData *DebugData {}; FEXCore::IR::RegisterAllocationData::UniquePtr RAData {}; @@ -1030,7 +1030,7 @@ namespace FEXCore::Context { }; } - void Context::CompileBlockJit(FEXCore::Core::CpuStateFrame *Frame, uint64_t GuestRIP) { + void ContextImpl::CompileBlockJit(FEXCore::Core::CpuStateFrame *Frame, uint64_t GuestRIP) { auto NewBlock = CompileBlock(Frame, GuestRIP); if (NewBlock == 0) { @@ -1041,7 +1041,7 @@ namespace FEXCore::Context { } } - uintptr_t Context::CompileBlock(FEXCore::Core::CpuStateFrame *Frame, uint64_t GuestRIP) { + uintptr_t ContextImpl::CompileBlock(FEXCore::Core::CpuStateFrame *Frame, uint64_t GuestRIP) { FEXCORE_PROFILE_SCOPED("CompileBlock"); auto Thread = Frame->Thread; @@ -1141,7 +1141,7 @@ namespace FEXCore::Context { return (uintptr_t)CodePtr; } - void Context::ExecutionThread(FEXCore::Core::InternalThreadState *Thread) { + void ContextImpl::ExecutionThread(FEXCore::Core::InternalThreadState *Thread) { Core::ThreadData.Thread = Thread; Thread->ExitReason = FEXCore::Context::ExitReason::EXIT_WAITING; @@ -1152,7 +1152,7 @@ namespace FEXCore::Context { // Now notify the thread that we are initialized Thread->ThreadWaiting.NotifyAll(); - if (Thread != Thread->CTX->ParentThread || StartPaused || Thread->StartPaused) { + if (Thread != static_cast(Thread->CTX)->ParentThread || StartPaused || Thread->StartPaused) { // Parent thread doesn't need to wait to run Thread->StartRunning.Wait(); } @@ -1164,7 +1164,7 @@ namespace FEXCore::Context { Thread->RunningEvents.Running = true; - Thread->CTX->Dispatcher->ExecuteDispatch(Thread->CurrentFrame); + static_cast(Thread->CTX)->Dispatcher->ExecuteDispatch(Thread->CurrentFrame); Thread->RunningEvents.Running = false; } @@ -1193,7 +1193,7 @@ namespace FEXCore::Context { SignalDelegation->UninstallTLSState(Thread); // If the parent thread is waiting to join, then we can't destroy our thread object - if (!Thread->DestroyedByParent && Thread != Thread->CTX->ParentThread) { + if (!Thread->DestroyedByParent && Thread != static_cast(Thread->CTX)->ParentThread) { Thread->CTX->DestroyThread(Thread); } } @@ -1206,34 +1206,34 @@ namespace FEXCore::Context { for (auto it = lower; it != upper; it++) { for (auto Address: it->second) { - Context::ThreadRemoveCodeEntry(Thread, Address); + ContextImpl::ThreadRemoveCodeEntry(Thread, Address); } it->second.clear(); } } - static void InvalidateGuestCodeRangeInternal(FEXCore::Context::Context *CTX, uint64_t Start, uint64_t Length) { - std::lock_guard lk(CTX->ThreadCreationMutex); + static void InvalidateGuestCodeRangeInternal(ContextImpl *CTX, uint64_t Start, uint64_t Length) { + std::lock_guard lk(static_cast(CTX)->ThreadCreationMutex); - for (auto &Thread : CTX->Threads) { + for (auto &Thread : static_cast(CTX)->Threads) { InvalidateGuestThreadCodeRange(Thread, Start, Length); } } - void InvalidateGuestCodeRange(FEXCore::Context::Context *CTX, uint64_t Start, uint64_t Length) { - FHU::ScopedSignalMaskWithUniqueLock CodeInvalidationLock(CTX->CodeInvalidationMutex); + void ContextImpl::InvalidateGuestCodeRange(uint64_t Start, uint64_t Length) { + FHU::ScopedSignalMaskWithUniqueLock CodeInvalidationLock(CodeInvalidationMutex); - InvalidateGuestCodeRangeInternal(CTX, Start, Length); + InvalidateGuestCodeRangeInternal(this, Start, Length); } - void InvalidateGuestCodeRange(FEXCore::Context::Context *CTX, uint64_t Start, uint64_t Length, std::function CallAfter) { - FHU::ScopedSignalMaskWithUniqueLock CodeInvalidationLock(CTX->CodeInvalidationMutex); + void ContextImpl::InvalidateGuestCodeRange(uint64_t Start, uint64_t Length, std::function CallAfter) { + FHU::ScopedSignalMaskWithUniqueLock CodeInvalidationLock(CodeInvalidationMutex); - InvalidateGuestCodeRangeInternal(CTX, Start, Length); + InvalidateGuestCodeRangeInternal(this, Start, Length); CallAfter(Start, Length); } - void Context::MarkMemoryShared() { + void ContextImpl::MarkMemoryShared() { if (!IsMemoryShared) { IsMemoryShared = true; @@ -1253,18 +1253,14 @@ namespace FEXCore::Context { } } - void MarkMemoryShared(FEXCore::Context::Context *CTX) { - CTX->MarkMemoryShared(); - } - - void Context::ThreadAddBlockLink(FEXCore::Core::InternalThreadState *Thread, uint64_t GuestDestination, uintptr_t HostLink, const std::function &delinker) { - std::shared_lock lk(Thread->CTX->CodeInvalidationMutex); + void ContextImpl::ThreadAddBlockLink(FEXCore::Core::InternalThreadState *Thread, uint64_t GuestDestination, uintptr_t HostLink, const std::function &delinker) { + std::shared_lock lk(static_cast(Thread->CTX)->CodeInvalidationMutex); Thread->LookupCache->AddBlockLink(GuestDestination, HostLink, delinker); } - void Context::ThreadRemoveCodeEntry(FEXCore::Core::InternalThreadState *Thread, uint64_t GuestRIP) { - LogMan::Throw::AFmt(Thread->CTX->CodeInvalidationMutex.try_lock() == false, "CodeInvalidationMutex needs to be unique_locked here"); + void ContextImpl::ThreadRemoveCodeEntry(FEXCore::Core::InternalThreadState *Thread, uint64_t GuestRIP) { + LogMan::Throw::AFmt(static_cast(Thread->CTX)->CodeInvalidationMutex.try_lock() == false, "CodeInvalidationMutex needs to be unique_locked here"); std::lock_guard lk(Thread->LookupCache->WriteLock); @@ -1272,7 +1268,7 @@ namespace FEXCore::Context { Thread->LookupCache->Erase(GuestRIP); } - CustomIRResult Context::AddCustomIREntrypoint(uintptr_t Entrypoint, std::function Handler, void *Creator, void *Data) { + CustomIRResult ContextImpl::AddCustomIREntrypoint(uintptr_t Entrypoint, std::function Handler, void *Creator, void *Data) { LOGMAN_THROW_A_FMT(Config.Is64BitMode || !(Entrypoint >> 32), "64-bit Entrypoint in 32-bit mode {:x}", Entrypoint); std::unique_lock lk(CustomIRMutex); @@ -1288,12 +1284,12 @@ namespace FEXCore::Context { } } - void Context::RemoveCustomIREntrypoint(uintptr_t Entrypoint) { + void ContextImpl::RemoveCustomIREntrypoint(uintptr_t Entrypoint) { LOGMAN_THROW_A_FMT(Config.Is64BitMode || !(Entrypoint >> 32), "64-bit Entrypoint in 32-bit mode {:x}", Entrypoint); std::scoped_lock lk(CustomIRMutex); - InvalidateGuestCodeRange(this, Entrypoint, 1, [this](uint64_t Entrypoint, uint64_t) { + InvalidateGuestCodeRange(Entrypoint, 1, [this](uint64_t Entrypoint, uint64_t) { CustomIRHandlers.erase(Entrypoint); }); } @@ -1303,24 +1299,26 @@ namespace FEXCore::Context { uint64_t RIPBackup = Thread->CurrentFrame->State.rip; Thread->CurrentFrame->State.rip = RIP; + auto CTX = static_cast(Thread->CTX); + // Erase the RIP from all the storage backings if it exists - ThreadRemoveCodeEntry(Thread, RIP); + CTX->ThreadRemoveCodeEntry(Thread, RIP); // We don't care if compilation passes or not - CompileBlock(Thread->CurrentFrame, RIP); + CTX->CompileBlock(Thread->CurrentFrame, RIP); Thread->CurrentFrame->State.rip = RIPBackup; } - uint64_t Context::GetThreadCount() const { + uint64_t ContextImpl::GetThreadCount() const { return Threads.size(); } - FEXCore::Core::RuntimeStats *Context::GetRuntimeStatsForThread(uint64_t Thread) { + FEXCore::Core::RuntimeStats *ContextImpl::GetRuntimeStatsForThread(uint64_t Thread) { return &Threads[Thread]->Stats; } - bool Context::GetDebugDataForRIP(uint64_t RIP, FEXCore::Core::DebugData *Data) { + bool ContextImpl::GetDebugDataForRIP(uint64_t RIP, FEXCore::Core::DebugData *Data) { std::lock_guard lk(ParentThread->LookupCache->WriteLock); auto it = ParentThread->DebugStore.find(RIP); if (it == ParentThread->DebugStore.end()) { @@ -1331,7 +1329,7 @@ namespace FEXCore::Context { return true; } - bool Context::FindHostCodeForRIP(uint64_t RIP, uint8_t **Code) { + bool ContextImpl::FindHostCodeForRIP(uint64_t RIP, uint8_t **Code) { uintptr_t HostCode = ParentThread->LookupCache->FindBlock(RIP); if (!HostCode) { return false; @@ -1347,7 +1345,7 @@ namespace FEXCore::Context { return Result; } - IR::AOTIRCacheEntry *Context::LoadAOTIRCacheEntry(const std::string &filename) { + IR::AOTIRCacheEntry *ContextImpl::LoadAOTIRCacheEntry(const std::string &filename) { auto rv = IRCaptureCache.LoadAOTIRCacheEntry(filename); if (DebugServer) { DebugServer->AlertLibrariesChanged(); @@ -1355,19 +1353,18 @@ namespace FEXCore::Context { return rv; } - void Context::UnloadAOTIRCacheEntry(IR::AOTIRCacheEntry *Entry) { + void ContextImpl::UnloadAOTIRCacheEntry(IR::AOTIRCacheEntry *Entry) { IRCaptureCache.UnloadAOTIRCacheEntry(Entry); if (DebugServer) { DebugServer->AlertLibrariesChanged(); } } - - void Context::AppendThunkDefinitions(std::vector const& Definitions) { + void ContextImpl::AppendThunkDefinitions(std::vector const& Definitions) { ThunkHandler->AppendThunkDefinitions(Definitions); } - void ConfigureAOTGen(FEXCore::Core::InternalThreadState *Thread, std::set *ExternalBranches, uint64_t SectionMaxAddress) { + void ContextImpl::ConfigureAOTGen(FEXCore::Core::InternalThreadState *Thread, std::set *ExternalBranches, uint64_t SectionMaxAddress) { Thread->FrontendDecoder->SetExternalBranches(ExternalBranches); Thread->FrontendDecoder->SetSectionMaxAddress(SectionMaxAddress); } diff --git a/External/FEXCore/Source/Interface/Core/Core.h b/External/FEXCore/Source/Interface/Core/Core.h index 3279042b8..64c3d4b37 100644 --- a/External/FEXCore/Source/Interface/Core/Core.h +++ b/External/FEXCore/Source/Interface/Core/Core.h @@ -5,7 +5,7 @@ namespace FEXCore { } namespace FEXCore::Context { - struct Context; + class ContextImpl; } namespace FEXCore::CPU { @@ -17,7 +17,7 @@ namespace FEXCore::CPU { * * @return true if core was able to be create */ - bool CreateCPUCore(FEXCore::Context::Context *CTX); + bool CreateCPUCore(FEXCore::Context::ContextImpl *CTX); - bool LoadCode(FEXCore::Context::Context *CTX, FEXCore::CodeLoader *Loader); + bool LoadCode(FEXCore::Context::ContextImpl *CTX, FEXCore::CodeLoader *Loader); } diff --git a/External/FEXCore/Source/Interface/Core/Dispatcher/Arm64Dispatcher.cpp b/External/FEXCore/Source/Interface/Core/Dispatcher/Arm64Dispatcher.cpp index 025198559..057d1c2a3 100644 --- a/External/FEXCore/Source/Interface/Core/Dispatcher/Arm64Dispatcher.cpp +++ b/External/FEXCore/Source/Interface/Core/Dispatcher/Arm64Dispatcher.cpp @@ -35,7 +35,7 @@ namespace FEXCore::CPU { constexpr size_t MAX_DISPATCHER_CODE_SIZE = 4096; -Arm64Dispatcher::Arm64Dispatcher(FEXCore::Context::Context *ctx, const DispatcherConfig &config) +Arm64Dispatcher::Arm64Dispatcher(FEXCore::Context::ContextImpl *ctx, const DispatcherConfig &config) : FEXCore::CPU::Dispatcher(ctx, config), Arm64Emitter(ctx, MAX_DISPATCHER_CODE_SIZE) #ifdef VIXL_SIMULATOR , Simulator {&Decoder} @@ -578,10 +578,10 @@ size_t Arm64Dispatcher::GenerateGDBPauseCheck(uint8_t *CodeBuffer, uint64_t Gues // If we have a gdb server running then run in a less efficient mode that checks if we need to exit // This happens when single stepping - static_assert(sizeof(FEXCore::Context::Context::Config.RunningMode) == 4, "This is expected to be size of 4"); + static_assert(sizeof(FEXCore::Context::ContextImpl::Config.RunningMode) == 4, "This is expected to be size of 4"); emit.ldr(ARMEmitter::XReg::x0, STATE_PTR(CpuStateFrame, Thread)); emit.ldr(ARMEmitter::XReg::x0, ARMEmitter::Reg::r0, offsetof(FEXCore::Core::InternalThreadState, CTX)); // Get Context - emit.ldr(ARMEmitter::WReg::w0, ARMEmitter::Reg::r0, offsetof(FEXCore::Context::Context, Config.RunningMode)); + emit.ldr(ARMEmitter::WReg::w0, ARMEmitter::Reg::r0, offsetof(FEXCore::Context::ContextImpl, Config.RunningMode)); // If the value == 0 then we don't need to stop emit.cbz(ARMEmitter::Size::i32Bit, ARMEmitter::Reg::r0, &RunBlock); @@ -672,7 +672,7 @@ void Arm64Dispatcher::InitThreadPointers(FEXCore::Core::InternalThreadState *Thr } } -std::unique_ptr Dispatcher::CreateArm64(FEXCore::Context::Context *CTX, const DispatcherConfig &Config) { +std::unique_ptr Dispatcher::CreateArm64(FEXCore::Context::ContextImpl *CTX, const DispatcherConfig &Config) { return std::make_unique(CTX, Config); } diff --git a/External/FEXCore/Source/Interface/Core/Dispatcher/Arm64Dispatcher.h b/External/FEXCore/Source/Interface/Core/Dispatcher/Arm64Dispatcher.h index fc52a541c..bb9e00a58 100644 --- a/External/FEXCore/Source/Interface/Core/Dispatcher/Arm64Dispatcher.h +++ b/External/FEXCore/Source/Interface/Core/Dispatcher/Arm64Dispatcher.h @@ -7,10 +7,6 @@ #include #endif -namespace FEXCore::Context { -struct Context; -} - namespace FEXCore::Core { struct InternalThreadState; } @@ -22,7 +18,7 @@ namespace FEXCore::CPU { class Arm64Dispatcher final : public Dispatcher, public Arm64Emitter { public: - Arm64Dispatcher(FEXCore::Context::Context *ctx, const DispatcherConfig &config); + Arm64Dispatcher(FEXCore::Context::ContextImpl *ctx, const DispatcherConfig &config); void InitThreadPointers(FEXCore::Core::InternalThreadState *Thread) override; size_t GenerateGDBPauseCheck(uint8_t *CodeBuffer, uint64_t GuestRIP) override; size_t GenerateInterpreterTrampoline(uint8_t *CodeBuffer) override; diff --git a/External/FEXCore/Source/Interface/Core/Dispatcher/Dispatcher.cpp b/External/FEXCore/Source/Interface/Core/Dispatcher/Dispatcher.cpp index bcb4563aa..c2a2f8122 100644 --- a/External/FEXCore/Source/Interface/Core/Dispatcher/Dispatcher.cpp +++ b/External/FEXCore/Source/Interface/Core/Dispatcher/Dispatcher.cpp @@ -22,7 +22,7 @@ namespace FEXCore::CPU { -void Dispatcher::SleepThread(FEXCore::Context::Context *ctx, FEXCore::Core::CpuStateFrame *Frame) { +void Dispatcher::SleepThread(FEXCore::Context::ContextImpl *ctx, FEXCore::Core::CpuStateFrame *Frame) { auto Thread = Frame->Thread; --ctx->IdleWaitRefCount; @@ -1185,7 +1185,7 @@ bool Dispatcher::HandleSignalPause(FEXCore::Core::InternalThreadState *Thread, i if (Thread->RunningEvents.ThreadSleeping) { // If the thread was sleeping then its idle counter was decremented // Reincrement it here to not break logic - ++Thread->CTX->IdleWaitRefCount; + ++static_cast(Thread->CTX)->IdleWaitRefCount; } Thread->SignalReason.store(FEXCore::Core::SignalEvent::Nothing); @@ -1207,14 +1207,14 @@ bool Dispatcher::HandleSignalPause(FEXCore::Core::InternalThreadState *Thread, i } uint64_t Dispatcher::GetCompileBlockPtr() { - using ClassPtrType = void (FEXCore::Context::Context::*)(FEXCore::Core::CpuStateFrame *, uint64_t); + using ClassPtrType = void (FEXCore::Context::ContextImpl::*)(FEXCore::Core::CpuStateFrame *, uint64_t); union PtrCast { ClassPtrType ClassPtr; uintptr_t Data; }; PtrCast CompileBlockPtr; - CompileBlockPtr.ClassPtr = &FEXCore::Context::Context::CompileBlockJit; + CompileBlockPtr.ClassPtr = &FEXCore::Context::ContextImpl::CompileBlockJit; return CompileBlockPtr.Data; } diff --git a/External/FEXCore/Source/Interface/Core/Dispatcher/Dispatcher.h b/External/FEXCore/Source/Interface/Core/Dispatcher/Dispatcher.h index a1724642a..6a8381800 100644 --- a/External/FEXCore/Source/Interface/Core/Dispatcher/Dispatcher.h +++ b/External/FEXCore/Source/Interface/Core/Dispatcher/Dispatcher.h @@ -20,7 +20,7 @@ struct InternalThreadState; } namespace FEXCore::Context { -struct Context; +class ContextImpl; } namespace FEXCore::CPU { @@ -74,8 +74,8 @@ public: virtual size_t GenerateGDBPauseCheck(uint8_t *CodeBuffer, uint64_t GuestRIP) = 0; virtual size_t GenerateInterpreterTrampoline(uint8_t *CodeBuffer) = 0; - static std::unique_ptr CreateX86(FEXCore::Context::Context *CTX, const DispatcherConfig &Config); - static std::unique_ptr CreateArm64(FEXCore::Context::Context *CTX, const DispatcherConfig &Config); + static std::unique_ptr CreateX86(FEXCore::Context::ContextImpl *CTX, const DispatcherConfig &Config); + static std::unique_ptr CreateArm64(FEXCore::Context::ContextImpl *CTX, const DispatcherConfig &Config); virtual void ExecuteDispatch(FEXCore::Core::CpuStateFrame *Frame) { DispatchPtr(Frame); @@ -86,7 +86,7 @@ public: } protected: - Dispatcher(FEXCore::Context::Context *ctx, const DispatcherConfig &Config) + Dispatcher(FEXCore::Context::ContextImpl *ctx, const DispatcherConfig &Config) : CTX {ctx} , config {Config} {} @@ -158,10 +158,10 @@ protected: virtual void SpillSRA(FEXCore::Core::InternalThreadState *Thread, void *ucontext, uint32_t IgnoreMask) {} - FEXCore::Context::Context *CTX; + FEXCore::Context::ContextImpl *CTX; DispatcherConfig config; - static void SleepThread(FEXCore::Context::Context *ctx, FEXCore::Core::CpuStateFrame *Frame); + static void SleepThread(FEXCore::Context::ContextImpl *ctx, FEXCore::Core::CpuStateFrame *Frame); static uint64_t GetCompileBlockPtr(); diff --git a/External/FEXCore/Source/Interface/Core/Dispatcher/X86Dispatcher.cpp b/External/FEXCore/Source/Interface/Core/Dispatcher/X86Dispatcher.cpp index d903265d0..1308a7ea9 100644 --- a/External/FEXCore/Source/Interface/Core/Dispatcher/X86Dispatcher.cpp +++ b/External/FEXCore/Source/Interface/Core/Dispatcher/X86Dispatcher.cpp @@ -27,7 +27,7 @@ namespace FEXCore::CPU { static constexpr size_t MAX_DISPATCHER_CODE_SIZE = 4096; #define STATE r14 -X86Dispatcher::X86Dispatcher(FEXCore::Context::Context *ctx, const DispatcherConfig &config) +X86Dispatcher::X86Dispatcher(FEXCore::Context::ContextImpl *ctx, const DispatcherConfig &config) : Dispatcher(ctx, config) , Xbyak::CodeGenerator(MAX_DISPATCHER_CODE_SIZE, FEXCore::Allocator::mmap(nullptr, MAX_DISPATCHER_CODE_SIZE, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0), @@ -433,7 +433,7 @@ size_t X86Dispatcher::GenerateGDBPauseCheck(uint8_t *CodeBuffer, uint64_t GuestR emit.mov(rax, reinterpret_cast(CTX)); // If the value == 0 then we don't need to stop - emit.cmp(dword [rax + (offsetof(FEXCore::Context::Context, Config.RunningMode))], 0); + emit.cmp(dword [rax + (offsetof(FEXCore::Context::ContextImpl, Config.RunningMode))], 0); emit.je(RunBlock); { // Make sure RIP is syncronized to the context @@ -499,7 +499,7 @@ void X86Dispatcher::InitThreadPointers(FEXCore::Core::InternalThreadState *Threa } } -std::unique_ptr Dispatcher::CreateX86(FEXCore::Context::Context *CTX, const DispatcherConfig &Config) { +std::unique_ptr Dispatcher::CreateX86(FEXCore::Context::ContextImpl *CTX, const DispatcherConfig &Config) { return std::make_unique(CTX, Config); } diff --git a/External/FEXCore/Source/Interface/Core/Dispatcher/X86Dispatcher.h b/External/FEXCore/Source/Interface/Core/Dispatcher/X86Dispatcher.h index 22a676003..46001fcc9 100644 --- a/External/FEXCore/Source/Interface/Core/Dispatcher/X86Dispatcher.h +++ b/External/FEXCore/Source/Interface/Core/Dispatcher/X86Dispatcher.h @@ -5,10 +5,6 @@ #define XBYAK64 #include -namespace FEXCore::Context { - struct Context; -} - namespace FEXCore::Core { struct InternalThreadState; } @@ -17,7 +13,7 @@ namespace FEXCore::CPU { class X86Dispatcher final : public Dispatcher, public Xbyak::CodeGenerator { public: - X86Dispatcher(FEXCore::Context::Context *ctx, const DispatcherConfig &config); + X86Dispatcher(FEXCore::Context::ContextImpl *ctx, const DispatcherConfig &config); void InitThreadPointers(FEXCore::Core::InternalThreadState *Thread) override; size_t GenerateGDBPauseCheck(uint8_t *CodeBuffer, uint64_t GuestRIP) override; size_t GenerateInterpreterTrampoline(uint8_t *CodeBuffer) override; diff --git a/External/FEXCore/Source/Interface/Core/Frontend.cpp b/External/FEXCore/Source/Interface/Core/Frontend.cpp index c74fec855..c3f372092 100644 --- a/External/FEXCore/Source/Interface/Core/Frontend.cpp +++ b/External/FEXCore/Source/Interface/Core/Frontend.cpp @@ -79,7 +79,7 @@ static uint32_t MapVEXToReg(uint8_t vvvv, bool HasXMM) { } } -Decoder::Decoder(FEXCore::Context::Context *ctx) +Decoder::Decoder(FEXCore::Context::ContextImpl *ctx) : CTX {ctx} , OSABI { ctx->SyscallHandler ? ctx->SyscallHandler->GetOSABI() : FEXCore::HLE::SyscallOSABI::OS_UNKNOWN } , PoolObject {ctx->FrontendAllocator, sizeof(FEXCore::X86Tables::DecodedInst) * DefaultDecodedBufferSize} { diff --git a/External/FEXCore/Source/Interface/Core/Frontend.h b/External/FEXCore/Source/Interface/Core/Frontend.h index 8a1a3c4b2..6e7310ef5 100644 --- a/External/FEXCore/Source/Interface/Core/Frontend.h +++ b/External/FEXCore/Source/Interface/Core/Frontend.h @@ -11,7 +11,7 @@ #include namespace FEXCore::Context { -struct Context; +class ContextImpl; } namespace FEXCore::Frontend { @@ -25,7 +25,7 @@ public: bool HasInvalidInstruction{}; }; - Decoder(FEXCore::Context::Context *ctx); + Decoder(FEXCore::Context::ContextImpl *ctx); ~Decoder(); void DecodeInstructionsAtEntry(uint8_t const* InstStream, uint64_t PC, std::function AddContainedCodePage); @@ -52,7 +52,7 @@ private: bool L; // VEX.L bit (if set then 256 bit operation, if unset then scalar or 128-bit operation) }; - FEXCore::Context::Context *CTX; + FEXCore::Context::ContextImpl *CTX; const FEXCore::HLE::SyscallOSABI OSABI{}; bool DecodeInstruction(uint64_t PC); diff --git a/External/FEXCore/Source/Interface/Core/GdbServer.cpp b/External/FEXCore/Source/Interface/Core/GdbServer.cpp index a884dd684..b50ca0858 100644 --- a/External/FEXCore/Source/Interface/Core/GdbServer.cpp +++ b/External/FEXCore/Source/Interface/Core/GdbServer.cpp @@ -68,11 +68,11 @@ void GdbServer::WaitForThreadWakeup() { ThreadBreakEvent.Wait(); } -GdbServer::GdbServer(FEXCore::Context::Context *ctx) : CTX(ctx) { +GdbServer::GdbServer(FEXCore::Context::ContextImpl *ctx) : CTX(ctx) { // Pass all signals by default std::fill(PassSignals.begin(), PassSignals.end(), true); - Context::SetExitHandler(ctx, [this](uint64_t ThreadId, FEXCore::Context::ExitReason ExitReason) { + ctx->SetExitHandler([this](uint64_t ThreadId, FEXCore::Context::ExitReason ExitReason) { if (ExitReason == FEXCore::Context::ExitReason::EXIT_DEBUG) { this->Break(SIGTRAP); } diff --git a/External/FEXCore/Source/Interface/Core/GdbServer.h b/External/FEXCore/Source/Interface/Core/GdbServer.h index 9ce3c8669..9b6f8dfa0 100644 --- a/External/FEXCore/Source/Interface/Core/GdbServer.h +++ b/External/FEXCore/Source/Interface/Core/GdbServer.h @@ -19,12 +19,12 @@ $end_info$ namespace FEXCore { namespace Context { - struct Context; + class ContextImpl; } class GdbServer { public: - GdbServer(FEXCore::Context::Context *ctx); + GdbServer(FEXCore::Context::ContextImpl *ctx); // Public for threading void GdbServerLoop(); @@ -75,7 +75,7 @@ private: std::string readRegs(); HandledPacketType readReg(const std::string& packet); - FEXCore::Context::Context *CTX; + FEXCore::Context::ContextImpl *CTX; std::unique_ptr gdbServerThread; std::unique_ptr CommsStream; std::mutex sendMutex; diff --git a/External/FEXCore/Source/Interface/Core/Interpreter/BranchOps.cpp b/External/FEXCore/Source/Interface/Core/Interpreter/BranchOps.cpp index 9b24cb9c4..d84e4fdb3 100644 --- a/External/FEXCore/Source/Interface/Core/Interpreter/BranchOps.cpp +++ b/External/FEXCore/Source/Interface/Core/Interpreter/BranchOps.cpp @@ -79,7 +79,7 @@ DEF_OP(Syscall) { Args.Argument[j] = *GetSrc(Data->SSAData, Op->Header.Args[j]); } - uint64_t Res = FEXCore::Context::HandleSyscall(Data->State->CTX->SyscallHandler, Data->State->CurrentFrame, &Args); + uint64_t Res = FEXCore::Context::HandleSyscall(static_cast(Data->State->CTX)->SyscallHandler, Data->State->CurrentFrame, &Args); GD = Res; } @@ -114,7 +114,7 @@ DEF_OP(InlineSyscall) { DEF_OP(Thunk) { auto Op = IROp->C(); - auto thunkFn = Data->State->CTX->ThunkHandler->LookupThunk(Op->ThunkNameHash); + auto thunkFn = static_cast(Data->State->CTX)->ThunkHandler->LookupThunk(Op->ThunkNameHash); thunkFn(*GetSrc(Data->SSAData, Op->ArgPtr)); } @@ -130,7 +130,7 @@ DEF_OP(ValidateCode) { } DEF_OP(ThreadRemoveCodeEntry) { - Data->State->CTX->ThreadRemoveCodeEntryFromJit(Data->State->CurrentFrame, Data->CurrentEntry); + static_cast(Data->State->CTX)->ThreadRemoveCodeEntryFromJit(Data->State->CurrentFrame, Data->CurrentEntry); } DEF_OP(CPUID) { @@ -139,7 +139,7 @@ DEF_OP(CPUID) { const uint64_t Arg = *GetSrc(Data->SSAData, Op->Function); const uint64_t Leaf = *GetSrc(Data->SSAData, Op->Leaf); - auto Results = Data->State->CTX->CPUID.RunFunction(Arg, Leaf); + auto Results = Data->State->CTX->RunCPUIDFunction(Arg, Leaf); memcpy(DstPtr, &Results, sizeof(uint32_t) * 4); } diff --git a/External/FEXCore/Source/Interface/Core/Interpreter/InterpreterClass.h b/External/FEXCore/Source/Interface/Core/Interpreter/InterpreterClass.h index 626137b1f..5190d9432 100644 --- a/External/FEXCore/Source/Interface/Core/Interpreter/InterpreterClass.h +++ b/External/FEXCore/Source/Interface/Core/Interpreter/InterpreterClass.h @@ -35,7 +35,7 @@ public: [[nodiscard]] bool NeedsOpDispatch() override { return true; } - static void InitializeSignalHandlers(FEXCore::Context::Context *CTX); + static void InitializeSignalHandlers(FEXCore::Context::ContextImpl *CTX); void ClearCache() override; diff --git a/External/FEXCore/Source/Interface/Core/Interpreter/InterpreterCore.cpp b/External/FEXCore/Source/Interface/Core/Interpreter/InterpreterCore.cpp index 9a3472997..0b3d25ca3 100644 --- a/External/FEXCore/Source/Interface/Core/Interpreter/InterpreterCore.cpp +++ b/External/FEXCore/Source/Interface/Core/Interpreter/InterpreterCore.cpp @@ -49,9 +49,9 @@ InterpreterCore::InterpreterCore(Dispatcher *Dispatcher, FEXCore::Core::Internal ClearCache(); } -void InterpreterCore::InitializeSignalHandlers(FEXCore::Context::Context *CTX) { +void InterpreterCore::InitializeSignalHandlers(FEXCore::Context::ContextImpl *CTX) { CTX->SignalDelegation->RegisterHostSignalHandler(SIGILL, [](FEXCore::Core::InternalThreadState *Thread, int Signal, void *info, void *ucontext) -> bool { - return Thread->CTX->Dispatcher->HandleSIGILL(Thread, Signal, info, ucontext); + return reinterpret_cast(Thread->CTX)->Dispatcher->HandleSIGILL(Thread, Signal, info, ucontext); }, true); #ifdef _M_ARM_64 @@ -67,7 +67,7 @@ CPUBackend::CompiledCode InterpreterCore::CompileCode(uint64_t Entry, [[maybe_un const auto MaxSize = IRSize + Dispatcher::MaxInterpreterTrampolineSize + GDBEnabled * Dispatcher::MaxGDBPauseCheckSize; if ((BufferUsed + MaxSize) > CurrentCodeBuffer->Size) { - ThreadState->CTX->ClearCodeCache(ThreadState); + static_cast(ThreadState->CTX)->ClearCodeCache(ThreadState); } CPUBackend::CompiledCode CodeData{}; @@ -103,11 +103,11 @@ void InterpreterCore::ClearCache() { BufferUsed = 0; } -std::unique_ptr CreateInterpreterCore(FEXCore::Context::Context *ctx, FEXCore::Core::InternalThreadState *Thread) { +std::unique_ptr CreateInterpreterCore(FEXCore::Context::ContextImpl *ctx, FEXCore::Core::InternalThreadState *Thread) { return std::make_unique(ctx->Dispatcher.get(), Thread); } -void InitializeInterpreterSignalHandlers(FEXCore::Context::Context *CTX) { +void InitializeInterpreterSignalHandlers(FEXCore::Context::ContextImpl *CTX) { InterpreterCore::InitializeSignalHandlers(CTX); } diff --git a/External/FEXCore/Source/Interface/Core/Interpreter/InterpreterCore.h b/External/FEXCore/Source/Interface/Core/Interpreter/InterpreterCore.h index 8cd6d7f33..a59731bd4 100644 --- a/External/FEXCore/Source/Interface/Core/Interpreter/InterpreterCore.h +++ b/External/FEXCore/Source/Interface/Core/Interpreter/InterpreterCore.h @@ -3,7 +3,7 @@ #include namespace FEXCore::Context { -struct Context; +class ContextImpl; } namespace FEXCore::Core { @@ -14,9 +14,9 @@ namespace FEXCore::CPU { class CPUBackend; struct DispatcherConfig; -[[nodiscard]] std::unique_ptr CreateInterpreterCore(FEXCore::Context::Context *ctx, +[[nodiscard]] std::unique_ptr CreateInterpreterCore(FEXCore::Context::ContextImpl *ctx, FEXCore::Core::InternalThreadState *Thread); -void InitializeInterpreterSignalHandlers(FEXCore::Context::Context *CTX); +void InitializeInterpreterSignalHandlers(FEXCore::Context::ContextImpl *CTX); CPUBackendFeatures GetInterpreterBackendFeatures(); } // namespace FEXCore::CPU diff --git a/External/FEXCore/Source/Interface/Core/JIT/Arm64/BranchOps.cpp b/External/FEXCore/Source/Interface/Core/JIT/Arm64/BranchOps.cpp index b71160a79..cc9537cc7 100644 --- a/External/FEXCore/Source/Interface/Core/JIT/Arm64/BranchOps.cpp +++ b/External/FEXCore/Source/Interface/Core/JIT/Arm64/BranchOps.cpp @@ -324,7 +324,7 @@ DEF_OP(Thunk) { mov(ARMEmitter::Size::i64Bit, ARMEmitter::Reg::r0, GetReg(Op->ArgPtr.ID())); - auto thunkFn = ThreadState->CTX->ThunkHandler->LookupThunk(Op->ThunkNameHash); + auto thunkFn = static_cast(ThreadState->CTX)->ThunkHandler->LookupThunk(Op->ThunkNameHash); LoadConstant(ARMEmitter::Size::i64Bit, ARMEmitter::Reg::r2, (uintptr_t)thunkFn); #ifdef VIXL_SIMULATOR GenerateIndirectRuntimeCall(ARMEmitter::Reg::r2); diff --git a/External/FEXCore/Source/Interface/Core/JIT/Arm64/JIT.cpp b/External/FEXCore/Source/Interface/Core/JIT/Arm64/JIT.cpp index 1ac8c87dd..e38d4be5c 100644 --- a/External/FEXCore/Source/Interface/Core/JIT/Arm64/JIT.cpp +++ b/External/FEXCore/Source/Interface/Core/JIT/Arm64/JIT.cpp @@ -484,7 +484,7 @@ static uint64_t Arm64JITCore_ExitFunctionLink(FEXCore::Core::CpuStateFrame *Fram FEXCore::ARMEmitter::Emitter::ClearICache((void*)branch, 24); // Add de-linking handler - Context::Context::ThreadAddBlockLink(Thread, GuestRip, (uintptr_t)record, [branch, LinkerAddress]{ + Context::ContextImpl::ThreadAddBlockLink(Thread, GuestRip, (uintptr_t)record, [branch, LinkerAddress]{ FEXCore::ARMEmitter::Emitter emit((uint8_t*)(branch), 24); FEXCore::ARMEmitter::ForwardLabel l_BranchHost; emit.ldr(FEXCore::ARMEmitter::XReg::x0, &l_BranchHost); @@ -498,7 +498,7 @@ static uint64_t Arm64JITCore_ExitFunctionLink(FEXCore::Core::CpuStateFrame *Fram record[0] = HostCode; // Add de-linking handler - Context::Context::ThreadAddBlockLink(Thread, GuestRip, (uintptr_t)record, [record, LinkerAddress]{ + Context::ContextImpl::ThreadAddBlockLink(Thread, GuestRip, (uintptr_t)record, [record, LinkerAddress]{ record[0] = LinkerAddress; }); } @@ -509,7 +509,7 @@ static uint64_t Arm64JITCore_ExitFunctionLink(FEXCore::Core::CpuStateFrame *Fram void Arm64JITCore::Op_NoOp(IR::IROp_Header const *IROp, IR::NodeID Node) { } -Arm64JITCore::Arm64JITCore(FEXCore::Context::Context *ctx, FEXCore::Core::InternalThreadState *Thread) +Arm64JITCore::Arm64JITCore(FEXCore::Context::ContextImpl *ctx, FEXCore::Core::InternalThreadState *Thread) : CPUBackend(Thread, INITIAL_CODE_SIZE, MAX_CODE_SIZE) , Arm64Emitter(ctx, 0) , HostSupportsSVE{ctx->HostFeatures.SupportsAVX} @@ -543,7 +543,7 @@ Arm64JITCore::Arm64JITCore(FEXCore::Context::Context *ctx, FEXCore::Core::Intern Common.PrintValue = reinterpret_cast(PrintValue); Common.PrintVectorValue = reinterpret_cast(PrintVectorValue); - Common.ThreadRemoveCodeEntryFromJIT = reinterpret_cast(&Context::Context::ThreadRemoveCodeEntryFromJit); + Common.ThreadRemoveCodeEntryFromJIT = reinterpret_cast(&Context::ContextImpl::ThreadRemoveCodeEntryFromJit); Common.CPUIDObj = reinterpret_cast(&CTX->CPUID); { @@ -553,7 +553,7 @@ Arm64JITCore::Arm64JITCore(FEXCore::Context::Context *ctx, FEXCore::Core::Intern Common.SyscallHandlerObj = reinterpret_cast(CTX->SyscallHandler); Common.SyscallHandlerFunc = reinterpret_cast(FEXCore::Context::HandleSyscall); - Common.ExitFunctionLink = reinterpret_cast(&Context::Context::ThreadExitFunctionLink); + Common.ExitFunctionLink = reinterpret_cast(&Context::ContextImpl::ThreadExitFunctionLink); // Fill in the fallback handlers @@ -572,9 +572,9 @@ Arm64JITCore::Arm64JITCore(FEXCore::Context::Context *ctx, FEXCore::Core::Intern ClearCache(); } -void Arm64JITCore::InitializeSignalHandlers(FEXCore::Context::Context *CTX) { +void Arm64JITCore::InitializeSignalHandlers(FEXCore::Context::ContextImpl *CTX) { CTX->SignalDelegation->RegisterHostSignalHandler(SIGILL, [](FEXCore::Core::InternalThreadState *Thread, int Signal, void *info, void *ucontext) -> bool { - return Thread->CTX->Dispatcher->HandleSIGILL(Thread, Signal, info, ucontext); + return reinterpret_cast(Thread->CTX)->Dispatcher->HandleSIGILL(Thread, Signal, info, ucontext); }, true); #ifdef _M_ARM_64 @@ -584,7 +584,7 @@ void Arm64JITCore::InitializeSignalHandlers(FEXCore::Context::Context *CTX) { return false; } - return FEXCore::ArchHelpers::Arm64::HandleSIGBUS(Thread->CTX->Config.ParanoidTSO(), Signal, info, ucontext); + return FEXCore::ArchHelpers::Arm64::HandleSIGBUS(static_cast(Thread->CTX)->Config.ParanoidTSO(), Signal, info, ucontext); }, true); #endif } @@ -1081,11 +1081,11 @@ void Arm64JITCore::ResetStack() { } } -std::unique_ptr CreateArm64JITCore(FEXCore::Context::Context *ctx, FEXCore::Core::InternalThreadState *Thread) { +std::unique_ptr CreateArm64JITCore(FEXCore::Context::ContextImpl *ctx, FEXCore::Core::InternalThreadState *Thread) { return std::make_unique(ctx, Thread); } -void InitializeArm64JITSignalHandlers(FEXCore::Context::Context *CTX) { +void InitializeArm64JITSignalHandlers(FEXCore::Context::ContextImpl *CTX) { Arm64JITCore::InitializeSignalHandlers(CTX); } diff --git a/External/FEXCore/Source/Interface/Core/JIT/Arm64/JITClass.h b/External/FEXCore/Source/Interface/Core/JIT/Arm64/JITClass.h index 89802422d..f97ddda36 100644 --- a/External/FEXCore/Source/Interface/Core/JIT/Arm64/JITClass.h +++ b/External/FEXCore/Source/Interface/Core/JIT/Arm64/JITClass.h @@ -31,7 +31,7 @@ namespace FEXCore::Core { namespace FEXCore::CPU { class Arm64JITCore final : public CPUBackend, public Arm64Emitter { public: - explicit Arm64JITCore(FEXCore::Context::Context *ctx, + explicit Arm64JITCore(FEXCore::Context::ContextImpl *ctx, FEXCore::Core::InternalThreadState *Thread); ~Arm64JITCore() override; @@ -48,7 +48,7 @@ public: void ClearCache() override; - static void InitializeSignalHandlers(FEXCore::Context::Context *CTX); + static void InitializeSignalHandlers(FEXCore::Context::ContextImpl *CTX); void ClearRelocations() override { Relocations.clear(); } @@ -57,7 +57,7 @@ private: const bool HostSupportsSVE{}; ARMEmitter::BiDirectionalLabel *PendingTargetLabel; - FEXCore::Context::Context *CTX; + FEXCore::Context::ContextImpl *CTX; FEXCore::IR::IRListView const *IR; uint64_t Entry; CPUBackend::CompiledCode CodeData{}; diff --git a/External/FEXCore/Source/Interface/Core/JIT/JITCore.h b/External/FEXCore/Source/Interface/Core/JIT/JITCore.h index f1a54bb06..0dcf8aa25 100644 --- a/External/FEXCore/Source/Interface/Core/JIT/JITCore.h +++ b/External/FEXCore/Source/Interface/Core/JIT/JITCore.h @@ -3,7 +3,7 @@ #include namespace FEXCore::Context { -struct Context; +class ContextImpl; } namespace FEXCore::Core { @@ -13,14 +13,14 @@ struct InternalThreadState; namespace FEXCore::CPU { class CPUBackend; -[[nodiscard]] std::unique_ptr CreateX86JITCore(FEXCore::Context::Context *ctx, +[[nodiscard]] std::unique_ptr CreateX86JITCore(FEXCore::Context::ContextImpl *ctx, FEXCore::Core::InternalThreadState *Thread); -void InitializeX86JITSignalHandlers(FEXCore::Context::Context *CTX); +void InitializeX86JITSignalHandlers(FEXCore::Context::ContextImpl *CTX); CPUBackendFeatures GetX86JITBackendFeatures(); -[[nodiscard]] std::unique_ptr CreateArm64JITCore(FEXCore::Context::Context *ctx, +[[nodiscard]] std::unique_ptr CreateArm64JITCore(FEXCore::Context::ContextImpl *ctx, FEXCore::Core::InternalThreadState *Thread); -void InitializeArm64JITSignalHandlers(FEXCore::Context::Context *CTX); +void InitializeArm64JITSignalHandlers(FEXCore::Context::ContextImpl *CTX); CPUBackendFeatures GetArm64JITBackendFeatures(); } // namespace FEXCore::CPU diff --git a/External/FEXCore/Source/Interface/Core/JIT/x86_64/BranchOps.cpp b/External/FEXCore/Source/Interface/Core/JIT/x86_64/BranchOps.cpp index 5a3ef05b0..eed5cf270 100644 --- a/External/FEXCore/Source/Interface/Core/JIT/x86_64/BranchOps.cpp +++ b/External/FEXCore/Source/Interface/Core/JIT/x86_64/BranchOps.cpp @@ -202,7 +202,7 @@ DEF_OP(Thunk) { mov(rdi, GetSrc(Op->ArgPtr.ID())); - auto thunkFn = ThreadState->CTX->ThunkHandler->LookupThunk(Op->ThunkNameHash); + auto thunkFn = static_cast(ThreadState->CTX)->ThunkHandler->LookupThunk(Op->ThunkNameHash); mov(rax, reinterpret_cast(thunkFn)); call(rax); diff --git a/External/FEXCore/Source/Interface/Core/JIT/x86_64/JIT.cpp b/External/FEXCore/Source/Interface/Core/JIT/x86_64/JIT.cpp index 071309737..527401cc3 100644 --- a/External/FEXCore/Source/Interface/Core/JIT/x86_64/JIT.cpp +++ b/External/FEXCore/Source/Interface/Core/JIT/x86_64/JIT.cpp @@ -330,7 +330,7 @@ static uint64_t X86JITCore_ExitFunctionLink(FEXCore::Core::CpuStateFrame *Frame, } auto LinkerAddress = Frame->Pointers.Common.ExitFunctionLinker; - Context::Context::ThreadAddBlockLink(Thread, GuestRip, (uintptr_t)record, [record, LinkerAddress]{ + Context::ContextImpl::ThreadAddBlockLink(Thread, GuestRip, (uintptr_t)record, [record, LinkerAddress]{ // undo the link record[0] = LinkerAddress; }); @@ -342,7 +342,7 @@ static uint64_t X86JITCore_ExitFunctionLink(FEXCore::Core::CpuStateFrame *Frame, void X86JITCore::Op_NoOp(IR::IROp_Header *IROp, IR::NodeID Node) { } -X86JITCore::X86JITCore(FEXCore::Context::Context *ctx, FEXCore::Core::InternalThreadState *Thread) +X86JITCore::X86JITCore(FEXCore::Context::ContextImpl *ctx, FEXCore::Core::InternalThreadState *Thread) : CPUBackend(Thread, INITIAL_CODE_SIZE, MAX_CODE_SIZE) , CodeGenerator(0, this, nullptr) // this is not used here , CTX {ctx} { @@ -379,7 +379,7 @@ X86JITCore::X86JITCore(FEXCore::Context::Context *ctx, FEXCore::Core::InternalTh Common.PrintValue = reinterpret_cast(PrintValue); Common.PrintVectorValue = reinterpret_cast(PrintVectorValue); - Common.ThreadRemoveCodeEntryFromJIT = reinterpret_cast(&Context::Context::ThreadRemoveCodeEntryFromJit); + Common.ThreadRemoveCodeEntryFromJIT = reinterpret_cast(&Context::ContextImpl::ThreadRemoveCodeEntryFromJit); Common.CPUIDObj = reinterpret_cast(&CTX->CPUID); { @@ -389,7 +389,7 @@ X86JITCore::X86JITCore(FEXCore::Context::Context *ctx, FEXCore::Core::InternalTh Common.SyscallHandlerObj = reinterpret_cast(CTX->SyscallHandler); Common.SyscallHandlerFunc = reinterpret_cast(FEXCore::Context::HandleSyscall); - Common.ExitFunctionLink = reinterpret_cast(&Context::Context::ThreadExitFunctionLink); + Common.ExitFunctionLink = reinterpret_cast(&Context::ContextImpl::ThreadExitFunctionLink); // Fill in the fallback handlers InterpreterOps::FillFallbackIndexPointers(Common.FallbackHandlerPointers); @@ -399,9 +399,9 @@ X86JITCore::X86JITCore(FEXCore::Context::Context *ctx, FEXCore::Core::InternalTh ClearCache(); } -void X86JITCore::InitializeSignalHandlers(FEXCore::Context::Context *CTX) { +void X86JITCore::InitializeSignalHandlers(FEXCore::Context::ContextImpl *CTX) { CTX->SignalDelegation->RegisterHostSignalHandler(SIGILL, [](FEXCore::Core::InternalThreadState *Thread, int Signal, void *info, void *ucontext) -> bool { - return Thread->CTX->Dispatcher->HandleSIGILL(Thread, Signal, info, ucontext); + return static_cast(Thread->CTX)->Dispatcher->HandleSIGILL(Thread, Signal, info, ucontext); }, true); } @@ -786,7 +786,7 @@ CPUBackend::CompiledCode X86JITCore::CompileCode(uint64_t Entry, [[maybe_unused] return CodeData; } -std::unique_ptr CreateX86JITCore(FEXCore::Context::Context *ctx, FEXCore::Core::InternalThreadState *Thread) { +std::unique_ptr CreateX86JITCore(FEXCore::Context::ContextImpl *ctx, FEXCore::Core::InternalThreadState *Thread) { return std::make_unique(ctx, Thread); } @@ -794,7 +794,7 @@ CPUBackendFeatures GetX86JITBackendFeatures() { return CPUBackendFeatures { }; } -void InitializeX86JITSignalHandlers(FEXCore::Context::Context *CTX) { +void InitializeX86JITSignalHandlers(FEXCore::Context::ContextImpl *CTX) { X86JITCore::InitializeSignalHandlers(CTX); } diff --git a/External/FEXCore/Source/Interface/Core/JIT/x86_64/JITClass.h b/External/FEXCore/Source/Interface/Core/JIT/x86_64/JITClass.h index f16558868..f694a3988 100644 --- a/External/FEXCore/Source/Interface/Core/JIT/x86_64/JITClass.h +++ b/External/FEXCore/Source/Interface/Core/JIT/x86_64/JITClass.h @@ -51,7 +51,7 @@ const std::array RAXMM_x = { xmm1, xmm2, xmm3, xmm4, xmm5, xmm6 class X86JITCore final : public CPUBackend, public Xbyak::CodeGenerator { public: - explicit X86JITCore(FEXCore::Context::Context *ctx, + explicit X86JITCore(FEXCore::Context::ContextImpl *ctx, FEXCore::Core::InternalThreadState *Thread); ~X86JITCore() override; @@ -68,7 +68,7 @@ public: void ClearCache() override; - static void InitializeSignalHandlers(FEXCore::Context::Context *CTX); + static void InitializeSignalHandlers(FEXCore::Context::ContextImpl *CTX); void ClearRelocations() override { Relocations.clear(); } @@ -135,7 +135,7 @@ private: /** @} */ Label* PendingTargetLabel{}; - FEXCore::Context::Context *CTX; + FEXCore::Context::ContextImpl *CTX; FEXCore::IR::IRListView const *IR; uint64_t Entry; CPUBackend::CompiledCode CodeData{}; diff --git a/External/FEXCore/Source/Interface/Core/LookupCache.cpp b/External/FEXCore/Source/Interface/Core/LookupCache.cpp index 72fe153f4..16b32d65b 100644 --- a/External/FEXCore/Source/Interface/Core/LookupCache.cpp +++ b/External/FEXCore/Source/Interface/Core/LookupCache.cpp @@ -14,7 +14,7 @@ $end_info$ #include namespace FEXCore { -LookupCache::LookupCache(FEXCore::Context::Context *CTX) +LookupCache::LookupCache(FEXCore::Context::ContextImpl *CTX) : ctx {CTX} { TotalCacheSize = ctx->Config.VirtualMemSize / 4096 * 8 + CODE_SIZE + L1_SIZE; diff --git a/External/FEXCore/Source/Interface/Core/LookupCache.h b/External/FEXCore/Source/Interface/Core/LookupCache.h index da011c657..0ecb452c5 100644 --- a/External/FEXCore/Source/Interface/Core/LookupCache.h +++ b/External/FEXCore/Source/Interface/Core/LookupCache.h @@ -1,4 +1,5 @@ #pragma once +#include "Interface/Context/Context.h" #include #include @@ -12,9 +13,6 @@ #include namespace FEXCore { -namespace Context { - struct Context; -} class LookupCache { public: @@ -24,7 +22,7 @@ public: uintptr_t GuestCode; }; - LookupCache(FEXCore::Context::Context *CTX); + LookupCache(FEXCore::Context::ContextImpl *CTX); ~LookupCache(); uintptr_t FindBlock(uint64_t Address) { @@ -260,7 +258,7 @@ private: size_t AllocateOffset {}; - FEXCore::Context::Context *ctx; + FEXCore::Context::ContextImpl *ctx; uint64_t VirtualMemSize{}; }; } diff --git a/External/FEXCore/Source/Interface/Core/ObjectCache/NamedRegionObjectHandler.cpp b/External/FEXCore/Source/Interface/Core/ObjectCache/NamedRegionObjectHandler.cpp index 75fbe0a9e..4df4f56b3 100644 --- a/External/FEXCore/Source/Interface/Core/ObjectCache/NamedRegionObjectHandler.cpp +++ b/External/FEXCore/Source/Interface/Core/ObjectCache/NamedRegionObjectHandler.cpp @@ -4,7 +4,7 @@ #include namespace FEXCore::CodeSerialize { - NamedRegionObjectHandler::NamedRegionObjectHandler(FEXCore::Context::Context *ctx) { + NamedRegionObjectHandler::NamedRegionObjectHandler(FEXCore::Context::ContextImpl *ctx) { DefaultSerializationConfig.Cookie = CODE_COOKIE; // Initialize the Arch from CPUID diff --git a/External/FEXCore/Source/Interface/Core/ObjectCache/ObjectCacheService.cpp b/External/FEXCore/Source/Interface/Core/ObjectCache/ObjectCacheService.cpp index 8443f01a9..55ce8c239 100644 --- a/External/FEXCore/Source/Interface/Core/ObjectCache/ObjectCacheService.cpp +++ b/External/FEXCore/Source/Interface/Core/ObjectCache/ObjectCacheService.cpp @@ -13,7 +13,7 @@ namespace { } namespace FEXCore::CodeSerialize { - CodeObjectSerializeService::CodeObjectSerializeService(FEXCore::Context::Context *ctx) + CodeObjectSerializeService::CodeObjectSerializeService(FEXCore::Context::ContextImpl *ctx) : CTX {ctx} , AsyncHandler { &NamedRegionHandler , this } , NamedRegionHandler { ctx } { diff --git a/External/FEXCore/Source/Interface/Core/ObjectCache/ObjectCacheService.h b/External/FEXCore/Source/Interface/Core/ObjectCache/ObjectCacheService.h index 6ad4e56bc..58e6cc89d 100644 --- a/External/FEXCore/Source/Interface/Core/ObjectCache/ObjectCacheService.h +++ b/External/FEXCore/Source/Interface/Core/ObjectCache/ObjectCacheService.h @@ -253,7 +253,7 @@ namespace FEXCore::CodeSerialize { class NamedRegionObjectHandler final { public: - NamedRegionObjectHandler(FEXCore::Context::Context *ctx); + NamedRegionObjectHandler(FEXCore::Context::ContextImpl *ctx); void HandleNamedRegionObjectJobs(); @@ -338,7 +338,7 @@ namespace FEXCore::CodeSerialize { */ class CodeObjectSerializeService final { public: - CodeObjectSerializeService(FEXCore::Context::Context *ctx); + CodeObjectSerializeService(FEXCore::Context::ContextImpl *ctx); /** * @brief Initialize the internal interface @@ -440,7 +440,7 @@ namespace FEXCore::CodeSerialize { void NotifyWork() { WorkAvailable.NotifyOne(); } private: - FEXCore::Context::Context *CTX; + FEXCore::Context::ContextImpl *CTX; Event WorkAvailable{}; std::unique_ptr WorkerThread; diff --git a/External/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp b/External/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp index 0dcd25824..2b62d0f70 100644 --- a/External/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp +++ b/External/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp @@ -5318,7 +5318,7 @@ void OpDispatchBuilder::StoreResult(FEXCore::IR::RegisterClassType Class, FEXCor StoreResult(Class, Op, Op->Dest, Src, Align, AccessType); } -OpDispatchBuilder::OpDispatchBuilder(FEXCore::Context::Context *ctx) +OpDispatchBuilder::OpDispatchBuilder(FEXCore::Context::ContextImpl *ctx) : IREmitter {ctx->OpDispatcherAllocator} , CTX {ctx} { ResetWorkingList(); diff --git a/External/FEXCore/Source/Interface/Core/OpcodeDispatcher.h b/External/FEXCore/Source/Interface/Core/OpcodeDispatcher.h index 8f1143209..11d2935da 100644 --- a/External/FEXCore/Source/Interface/Core/OpcodeDispatcher.h +++ b/External/FEXCore/Source/Interface/Core/OpcodeDispatcher.h @@ -75,7 +75,7 @@ public: OrderedNode* flagsOpDestSigned{}; OrderedNode* flagsOpSrcSigned{}; - FEXCore::Context::Context *CTX{}; + FEXCore::Context::ContextImpl *CTX{}; // Used during new op bringup bool ShouldDump {false}; @@ -149,7 +149,7 @@ public: return false; } - OpDispatchBuilder(FEXCore::Context::Context *ctx); + OpDispatchBuilder(FEXCore::Context::ContextImpl *ctx); OpDispatchBuilder(FEXCore::Utils::IntrusivePooledAllocator &Allocator); void ResetWorkingList(); diff --git a/External/FEXCore/Source/Interface/HLE/Thunks/Thunks.cpp b/External/FEXCore/Source/Interface/HLE/Thunks/Thunks.cpp index 0ee4f568a..1b859f624 100644 --- a/External/FEXCore/Source/Interface/HLE/Thunks/Thunks.cpp +++ b/External/FEXCore/Source/Interface/HLE/Thunks/Thunks.cpp @@ -179,7 +179,7 @@ namespace FEXCore { }; auto args = reinterpret_cast(argsv); - auto CTX = Thread->CTX; + auto CTX = static_cast(Thread->CTX); LOGMAN_THROW_AA_FMT(args->original_callee, "Tried to link null pointer address to guest function"); LOGMAN_THROW_AA_FMT(args->target_addr, "Tried to link address to null pointer guest function"); @@ -264,7 +264,7 @@ namespace FEXCore { } static void LoadLib(void *ArgsV) { - auto CTX = Thread->CTX; + auto CTX = static_cast(Thread->CTX); auto Args = reinterpret_cast(ArgsV); @@ -321,7 +321,7 @@ namespace FEXCore { auto &[Name, rv] = *reinterpret_cast(ArgsRV); - auto CTX = Thread->CTX; + auto CTX = static_cast(Thread->CTX); auto That = reinterpret_cast(CTX->ThunkHandler.get()); { @@ -385,7 +385,7 @@ namespace FEXCore { HostToGuestTrampolinePtr* MakeHostTrampolineForGuestFunction(void* HostPacker, uintptr_t GuestTarget, uintptr_t GuestUnpacker) { LOGMAN_THROW_AA_FMT(GuestTarget, "Tried to create host-trampoline to null pointer guest function"); - const auto CTX = Thread->CTX; + const auto CTX = static_cast(Thread->CTX); const auto ThunkHandler = reinterpret_cast(CTX->ThunkHandler.get()); const GuestcallInfo gci = { GuestUnpacker, GuestTarget }; diff --git a/External/FEXCore/Source/Interface/HLE/Thunks/Thunks.h b/External/FEXCore/Source/Interface/HLE/Thunks/Thunks.h index 83d0cc1eb..0a3416b67 100644 --- a/External/FEXCore/Source/Interface/HLE/Thunks/Thunks.h +++ b/External/FEXCore/Source/Interface/HLE/Thunks/Thunks.h @@ -11,7 +11,7 @@ $end_info$ #include namespace FEXCore::Context { - struct Context; + class ContextImpl; } namespace FEXCore::Core { diff --git a/External/FEXCore/Source/Interface/IR/AOTIR.h b/External/FEXCore/Source/Interface/IR/AOTIR.h index 238c5b4b5..81084ba8d 100644 --- a/External/FEXCore/Source/Interface/IR/AOTIR.h +++ b/External/FEXCore/Source/Interface/IR/AOTIR.h @@ -17,6 +17,9 @@ namespace FEXCore::Core { struct DebugData; } +namespace FEXCore::Context { + class ContextImpl; +} namespace FEXCore::IR { class RegisterAllocationData; @@ -87,7 +90,7 @@ namespace FEXCore::IR { class AOTIRCaptureCache final { public: - AOTIRCaptureCache(FEXCore::Context::Context *ctx) : CTX {ctx} {} + AOTIRCaptureCache(FEXCore::Context::ContextImpl *ctx) : CTX {ctx} {} void FinalizeAOTIRCache(); void AOTIRCaptureCacheWriteoutQueue_Flush(); @@ -131,7 +134,7 @@ namespace FEXCore::IR { } private: - FEXCore::Context::Context *CTX; + FEXCore::Context::ContextImpl *CTX; std::shared_mutex AOTIRCacheLock; std::shared_mutex AOTIRCaptureCacheWriteoutLock; diff --git a/External/FEXCore/Source/Interface/IR/PassManager.cpp b/External/FEXCore/Source/Interface/IR/PassManager.cpp index fdf4ca203..41464f7f4 100644 --- a/External/FEXCore/Source/Interface/IR/PassManager.cpp +++ b/External/FEXCore/Source/Interface/IR/PassManager.cpp @@ -17,7 +17,7 @@ $end_info$ namespace FEXCore::IR { class IREmitter; -void PassManager::AddDefaultPasses(FEXCore::Context::Context *ctx, bool InlineConstants, bool StaticRegisterAllocation) { +void PassManager::AddDefaultPasses(FEXCore::Context::ContextImpl *ctx, bool InlineConstants, bool StaticRegisterAllocation) { FEX_CONFIG_OPT(DisablePasses, O0); if (!DisablePasses()) { diff --git a/External/FEXCore/Source/Interface/IR/PassManager.h b/External/FEXCore/Source/Interface/IR/PassManager.h index 400b52e4f..5c37c985b 100644 --- a/External/FEXCore/Source/Interface/IR/PassManager.h +++ b/External/FEXCore/Source/Interface/IR/PassManager.h @@ -14,6 +14,10 @@ $end_info$ #include #include +namespace FEXCore::Context { + class ContextImpl; +} + namespace FEXCore::HLE { class SyscallHandler; } @@ -40,7 +44,7 @@ protected: class PassManager final { friend class SyscallOptimization; public: - void AddDefaultPasses(FEXCore::Context::Context *ctx, bool InlineConstants, bool StaticRegisterAllocation); + void AddDefaultPasses(FEXCore::Context::ContextImpl *ctx, bool InlineConstants, bool StaticRegisterAllocation); void AddDefaultValidationPasses(); Pass* InsertPass(std::unique_ptr Pass, std::string Name = "") { Pass->RegisterPassManager(this); diff --git a/External/FEXCore/include/FEXCore/Core/Context.h b/External/FEXCore/include/FEXCore/Core/Context.h index 86a4c718a..c8561a6eb 100644 --- a/External/FEXCore/include/FEXCore/Core/Context.h +++ b/External/FEXCore/include/FEXCore/Core/Context.h @@ -41,7 +41,7 @@ namespace FEXCore::IR { } namespace FEXCore::Context { - struct Context; + class Context; enum ExitReason { EXIT_NONE, EXIT_WAITING, @@ -78,224 +78,217 @@ namespace FEXCore::Context { using ExitHandler = std::function; + class Context { + public: + virtual ~Context() = default; + /** + * @brief [[threadsafe]] Create a new FEXCore context object + * + * This is necessary to do when running threaded contexts + * + * @return a new context object + */ + FEX_DEFAULT_VISIBILITY static FEXCore::Context::Context *CreateNewContext(); + + /** + * @brief Post creation context initialization + * Once configurations have been set, do the post-creation initialization with that configuration + * + * @param CTX The context that we created + * + * @return true if we managed to initialize correctly + */ + FEX_DEFAULT_VISIBILITY virtual bool InitializeContext() = 0; + + /** + * @brief Destroy the context object + * + * @param CTX + */ + FEX_DEFAULT_VISIBILITY static void DestroyContext(FEXCore::Context::Context * CTX); + FEX_DEFAULT_VISIBILITY virtual void DestroyContext() = 0; + + /** + * @brief Allows setting up in memory code and other things prior to launchign code execution + * + * @param CTX The context that we created + * @param Loader The loader that will be doing all the code loading + * + * @return true if we loaded code + */ + FEX_DEFAULT_VISIBILITY virtual FEXCore::Core::InternalThreadState* InitCore(uint64_t InitialRIP, uint64_t StackPointer) = 0; + + FEX_DEFAULT_VISIBILITY virtual void SetExitHandler(ExitHandler handler) = 0; + FEX_DEFAULT_VISIBILITY virtual ExitHandler GetExitHandler() const = 0; + + /** + * @brief Pauses execution on the CPU core + * + * Blocks until all threads have paused. + */ + FEX_DEFAULT_VISIBILITY virtual void Pause() = 0; + + /** + * @brief Starts (or continues) the CPU core + * + * This function is async and returns immediately. + * Use RunUntilExit() for synchonous executions + * + */ + FEX_DEFAULT_VISIBILITY virtual void Run() = 0; + + /** + * @brief Tells the core to shutdown + * + * Blocks until shutdown + */ + FEX_DEFAULT_VISIBILITY virtual void Stop() = 0; + + /** + * @brief Executes one instruction + * + * Returns once execution is complete. + */ + FEX_DEFAULT_VISIBILITY virtual void Step() = 0; + + /** + * @brief Runs the CPU core until it exits + * + * If an Exit handler has been registered, this function won't return until the core + * has shutdown. + * + * @param CTX The context that we created + * + * @return The ExitReason for the parentthread. + */ + FEX_DEFAULT_VISIBILITY virtual ExitReason RunUntilExit() = 0; + + FEX_DEFAULT_VISIBILITY virtual void CompileRIP(FEXCore::Core::InternalThreadState *Thread, uint64_t GuestRIP) = 0; + + /** + * @brief Gets the program exit status + * + * + * @param CTX The context that we created + * + * @return The program exit status + */ + FEX_DEFAULT_VISIBILITY virtual int GetProgramStatus() const = 0; + + /** + * @brief [[threadsafe]] Returns the ExitReason of the parent thread. Typically used for async result status + * + * @param CTX The context that we created + * + * @return The ExitReason for the parentthread + */ + FEX_DEFAULT_VISIBILITY virtual ExitReason GetExitReason() = 0; + + /** + * @brief [[theadsafe]] Checks if the Context is either done working or paused(in the case of single stepping) + * + * Use this when the context is async running to determine if it is done + * + * @param CTX the context that we created + * + * @return true if the core is done or paused + */ + FEX_DEFAULT_VISIBILITY virtual bool IsDone() const = 0; + + /** + * @brief Gets a copy the CPUState of the parent thread + * + * @param CTX The context that we created + * @param State The state object to populate + */ + FEX_DEFAULT_VISIBILITY virtual void GetCPUState(FEXCore::Core::CPUState *State) const = 0; + + /** + * @brief Copies the CPUState provided to the parent thread + * + * @param CTX The context that we created + * @param State The satate object to copy from + */ + FEX_DEFAULT_VISIBILITY virtual void SetCPUState(const FEXCore::Core::CPUState *State) = 0; + + /** + * @brief Allows the frontend to pass in a custom CPUBackend creation factory + * + * This allows the frontend to have its own frontend. Typically for debugging + * + * @param CTX The context that we created + * @param Factory The factory that the context will call if the DefaultCore config ise set to CUSTOM + */ + FEX_DEFAULT_VISIBILITY virtual void SetCustomCPUBackendFactory(CustomCPUFactoryType Factory) = 0; + + /** + * @brief Sets up memory regions on the guest for mirroring within the guest's VM space + * + * @param VirtualAddress The address we want to set to mirror a physical memory region + * @param PhysicalAddress The physical memory region we are mapping + * @param Size Size of the region to mirror + * + * @return true when successfully mapped. false if there was an error adding + */ + FEX_DEFAULT_VISIBILITY virtual bool AddVirtualMemoryMapping(uint64_t VirtualAddress, uint64_t PhysicalAddress, uint64_t Size) = 0; + + /** + * @brief Retrieves a feature struct indicating certain supported aspects from + * the hose. + * + * @param CTX A valid non-null context instance. + */ + FEX_DEFAULT_VISIBILITY virtual HostFeatures GetHostFeatures() const = 0; + + FEX_DEFAULT_VISIBILITY virtual void HandleCallback(FEXCore::Core::InternalThreadState *Thread, uint64_t RIP) = 0; + + FEX_DEFAULT_VISIBILITY virtual void RegisterHostSignalHandler(int Signal, HostSignalDelegatorFunction Func, bool Required) = 0; + [[noreturn]] FEX_DEFAULT_VISIBILITY virtual void HandleSignalHandlerReturn(bool RT) = 0; + FEX_DEFAULT_VISIBILITY virtual void RegisterFrontendHostSignalHandler(int Signal, HostSignalDelegatorFunction Func, bool Required) = 0; + + FEX_DEFAULT_VISIBILITY virtual FEXCore::Core::InternalThreadState* CreateThread(FEXCore::Core::CPUState *NewThreadState, uint64_t ParentTID) = 0; + FEX_DEFAULT_VISIBILITY virtual void ExecutionThread(FEXCore::Core::InternalThreadState *Thread) = 0; + FEX_DEFAULT_VISIBILITY virtual void InitializeThread(FEXCore::Core::InternalThreadState *Thread) = 0; + FEX_DEFAULT_VISIBILITY virtual void RunThread(FEXCore::Core::InternalThreadState *Thread) = 0; + FEX_DEFAULT_VISIBILITY virtual void StopThread(FEXCore::Core::InternalThreadState *Thread) = 0; + FEX_DEFAULT_VISIBILITY virtual void DestroyThread(FEXCore::Core::InternalThreadState *Thread) = 0; + FEX_DEFAULT_VISIBILITY virtual void CleanupAfterFork(FEXCore::Core::InternalThreadState *Thread) = 0; + FEX_DEFAULT_VISIBILITY virtual void SetSignalDelegator(FEXCore::SignalDelegator *SignalDelegation) = 0; + FEX_DEFAULT_VISIBILITY virtual void SetSyscallHandler(FEXCore::HLE::SyscallHandler *Handler) = 0; + FEX_DEFAULT_VISIBILITY virtual FEXCore::CPUID::FunctionResults RunCPUIDFunction(uint32_t Function, uint32_t Leaf) = 0; + FEX_DEFAULT_VISIBILITY virtual FEXCore::CPUID::FunctionResults RunCPUIDFunctionName(uint32_t Function, uint32_t Leaf, uint32_t CPU) = 0; + + FEX_DEFAULT_VISIBILITY virtual FEXCore::IR::AOTIRCacheEntry *LoadAOTIRCacheEntry(const std::string& Name) = 0; + FEX_DEFAULT_VISIBILITY virtual void UnloadAOTIRCacheEntry(FEXCore::IR::AOTIRCacheEntry *Entry) = 0; + + FEX_DEFAULT_VISIBILITY virtual void SetAOTIRLoader(std::function CacheReader) = 0; + FEX_DEFAULT_VISIBILITY virtual void SetAOTIRWriter(std::function(const std::string&)> CacheWriter) = 0; + FEX_DEFAULT_VISIBILITY virtual void SetAOTIRRenamer(std::function CacheRenamer) = 0; + + FEX_DEFAULT_VISIBILITY virtual void FinalizeAOTIRCache() = 0; + FEX_DEFAULT_VISIBILITY virtual void WriteFilesWithCode(std::function Writer) = 0; + FEX_DEFAULT_VISIBILITY virtual void InvalidateGuestCodeRange(uint64_t Start, uint64_t Length) = 0; + FEX_DEFAULT_VISIBILITY virtual void InvalidateGuestCodeRange(uint64_t Start, uint64_t Length, std::function callback) = 0; + FEX_DEFAULT_VISIBILITY virtual void MarkMemoryShared() = 0; + + FEX_DEFAULT_VISIBILITY virtual void ConfigureAOTGen(FEXCore::Core::InternalThreadState *Thread, std::set *ExternalBranches, uint64_t SectionMaxAddress) = 0; + FEX_DEFAULT_VISIBILITY virtual CustomIRResult AddCustomIREntrypoint(uintptr_t Entrypoint, std::function Handler, void *Creator = nullptr, void *Data = nullptr) = 0; + + /** + * @brief Allows the frontend to register its own thunk handlers independent of what is controlled in the backend. + * + * @param CTX A valid non-null context instance. + * @param Definitions A vector of thunk definitions that the frontend controls + */ + FEX_DEFAULT_VISIBILITY virtual void AppendThunkDefinitions(std::vector const& Definitions) = 0; + + FEX_DEFAULT_VISIBILITY virtual void SetVDSOSigReturn(const VDSOSigReturn &Pointers) = 0; + private: + }; + /** * @brief This initializes internal FEXCore state that is shared between contexts and requires overhead to setup */ FEX_DEFAULT_VISIBILITY void InitializeStaticTables(OperatingMode Mode = MODE_64BIT); FEX_DEFAULT_VISIBILITY void ShutdownStaticTables(); - - /** - * @brief [[threadsafe]] Create a new FEXCore context object - * - * This is necessary to do when running threaded contexts - * - * @return a new context object - */ - FEX_DEFAULT_VISIBILITY FEXCore::Context::Context *CreateNewContext(); - - /** - * @brief Post creation context initialization - * Once configurations have been set, do the post-creation initialization with that configuration - * - * @param CTX The context that we created - * - * @return true if we managed to initialize correctly - */ - FEX_DEFAULT_VISIBILITY bool InitializeContext(FEXCore::Context::Context *CTX); - - /** - * @brief Destroy the context object - * - * @param CTX - */ - FEX_DEFAULT_VISIBILITY void DestroyContext(FEXCore::Context::Context *CTX); - - /** - * @brief Allows setting up in memory code and other things prior to launchign code execution - * - * @param CTX The context that we created - * @param Loader The loader that will be doing all the code loading - * - * @return true if we loaded code - */ - FEX_DEFAULT_VISIBILITY FEXCore::Core::InternalThreadState* InitCore(FEXCore::Context::Context *CTX, uint64_t InitialRIP, uint64_t StackPointer); - - FEX_DEFAULT_VISIBILITY void SetExitHandler(FEXCore::Context::Context *CTX, ExitHandler handler); - FEX_DEFAULT_VISIBILITY ExitHandler GetExitHandler(const FEXCore::Context::Context *CTX); - - /** - * @brief Pauses execution on the CPU core - * - * Blocks until all threads have paused. - */ - FEX_DEFAULT_VISIBILITY void Pause(FEXCore::Context::Context *CTX); - - /** - * @brief Starts (or continues) the CPU core - * - * This function is async and returns immediately. - * Use RunUntilExit() for synchonous executions - * - */ - FEX_DEFAULT_VISIBILITY void Run(FEXCore::Context::Context *CTX); - - /** - * @brief Runs the CPU core until it exits - * - * If an Exit handler has been registered, this function won't return until the core - * has shutdown. - * - * @param CTX The context that we created - * - * @return The ExitReason for the parentthread. - */ - FEX_DEFAULT_VISIBILITY ExitReason RunUntilExit(FEXCore::Context::Context *CTX); - - FEX_DEFAULT_VISIBILITY void CompileRIP(FEXCore::Core::InternalThreadState *Thread, uint64_t GuestRIP); - - /** - * @brief Gets the program exit status - * - * - * @param CTX The context that we created - * - * @return The program exit status - */ - FEX_DEFAULT_VISIBILITY int GetProgramStatus(const FEXCore::Context::Context *CTX); - - /** - * @brief Tells the core to shutdown - * - * Blocks until shutdown - */ - FEX_DEFAULT_VISIBILITY void Stop(FEXCore::Context::Context *CTX); - - /** - * @brief Executes one instruction - * - * Returns once execution is complete. - */ - FEX_DEFAULT_VISIBILITY void Step(FEXCore::Context::Context *CTX); - - /** - * @brief [[threadsafe]] Returns the ExitReason of the parent thread. Typically used for async result status - * - * @param CTX The context that we created - * - * @return The ExitReason for the parentthread - */ - FEX_DEFAULT_VISIBILITY ExitReason GetExitReason(const FEXCore::Context::Context *CTX); - - /** - * @brief [[theadsafe]] Checks if the Context is either done working or paused(in the case of single stepping) - * - * Use this when the context is async running to determine if it is done - * - * @param CTX the context that we created - * - * @return true if the core is done or paused - */ - FEX_DEFAULT_VISIBILITY bool IsDone(const FEXCore::Context::Context *CTX); - - /** - * @brief Gets a copy the CPUState of the parent thread - * - * @param CTX The context that we created - * @param State The state object to populate - */ - FEX_DEFAULT_VISIBILITY void GetCPUState(const FEXCore::Context::Context *CTX, - FEXCore::Core::CPUState *State); - - /** - * @brief Copies the CPUState provided to the parent thread - * - * @param CTX The context that we created - * @param State The satate object to copy from - */ - FEX_DEFAULT_VISIBILITY void SetCPUState(FEXCore::Context::Context *CTX, - const FEXCore::Core::CPUState *State); - - /** - * @brief Allows the frontend to pass in a custom CPUBackend creation factory - * - * This allows the frontend to have its own frontend. Typically for debugging - * - * @param CTX The context that we created - * @param Factory The factory that the context will call if the DefaultCore config ise set to CUSTOM - */ - FEX_DEFAULT_VISIBILITY void SetCustomCPUBackendFactory(FEXCore::Context::Context *CTX, CustomCPUFactoryType Factory); - - /** - * @brief Sets up memory regions on the guest for mirroring within the guest's VM space - * - * @param VirtualAddress The address we want to set to mirror a physical memory region - * @param PhysicalAddress The physical memory region we are mapping - * @param Size Size of the region to mirror - * - * @return true when successfully mapped. false if there was an error adding - */ - FEX_DEFAULT_VISIBILITY bool AddVirtualMemoryMapping(FEXCore::Context::Context *CTX, uint64_t VirtualAddress, uint64_t PhysicalAddress, uint64_t Size); - - /** - * @brief Allows the frontend to set a custom syscall handler - * - * Useful for debugging purposes. May not work if the syscall ID exceeds the maximum number of syscalls in the lookup table - * - * @param Syscall Which syscall ID to install a visitor to - * @param Visitor The Visitor to install - */ - FEX_DEFAULT_VISIBILITY void RegisterExternalSyscallVisitor(FEXCore::Context::Context *CTX, uint64_t Syscall, FEXCore::HLE::SyscallVisitor *Visitor); - - /** - * @brief Retrieves a feature struct indicating certain supported aspects from - * the hose. - * - * @param CTX A valid non-null context instance. - */ - FEX_DEFAULT_VISIBILITY HostFeatures GetHostFeatures(const FEXCore::Context::Context *CTX); - - FEX_DEFAULT_VISIBILITY void HandleCallback(FEXCore::Context::Context *CTX, FEXCore::Core::InternalThreadState *Thread, uint64_t RIP); - - FEX_DEFAULT_VISIBILITY void RegisterHostSignalHandler(FEXCore::Context::Context *CTX, int Signal, HostSignalDelegatorFunction Func, bool Required); - [[noreturn]] FEX_DEFAULT_VISIBILITY void HandleSignalHandlerReturn(FEXCore::Context::Context *CTX, bool RT); - FEX_DEFAULT_VISIBILITY void RegisterFrontendHostSignalHandler(FEXCore::Context::Context *CTX, int Signal, HostSignalDelegatorFunction Func, bool Required); - - FEX_DEFAULT_VISIBILITY FEXCore::Core::InternalThreadState* CreateThread(FEXCore::Context::Context *CTX, FEXCore::Core::CPUState *NewThreadState, uint64_t ParentTID); - FEX_DEFAULT_VISIBILITY void ExecutionThread(FEXCore::Context::Context *CTX, FEXCore::Core::InternalThreadState *Thread); - FEX_DEFAULT_VISIBILITY void InitializeThread(FEXCore::Context::Context *CTX, FEXCore::Core::InternalThreadState *Thread); - FEX_DEFAULT_VISIBILITY void RunThread(FEXCore::Context::Context *CTX, FEXCore::Core::InternalThreadState *Thread); - FEX_DEFAULT_VISIBILITY void StopThread(FEXCore::Context::Context *CTX, FEXCore::Core::InternalThreadState *Thread); - FEX_DEFAULT_VISIBILITY void DestroyThread(FEXCore::Context::Context *CTX, FEXCore::Core::InternalThreadState *Thread); - FEX_DEFAULT_VISIBILITY void CleanupAfterFork(FEXCore::Context::Context *CTX, FEXCore::Core::InternalThreadState *Thread); - FEX_DEFAULT_VISIBILITY void SetSignalDelegator(FEXCore::Context::Context *CTX, FEXCore::SignalDelegator *SignalDelegation); - FEX_DEFAULT_VISIBILITY void SetSyscallHandler(FEXCore::Context::Context *CTX, FEXCore::HLE::SyscallHandler *Handler); - FEX_DEFAULT_VISIBILITY FEXCore::CPUID::FunctionResults RunCPUIDFunction(FEXCore::Context::Context *CTX, uint32_t Function, uint32_t Leaf); - FEX_DEFAULT_VISIBILITY FEXCore::CPUID::FunctionResults RunCPUIDFunctionName(FEXCore::Context::Context *CTX, uint32_t Function, uint32_t Leaf, uint32_t CPU); - - FEX_DEFAULT_VISIBILITY FEXCore::IR::AOTIRCacheEntry *LoadAOTIRCacheEntry(FEXCore::Context::Context *CTX, const std::string& Name); - FEX_DEFAULT_VISIBILITY void UnloadAOTIRCacheEntry(FEXCore::Context::Context *CTX, FEXCore::IR::AOTIRCacheEntry *Entry); - - FEX_DEFAULT_VISIBILITY void SetAOTIRLoader(FEXCore::Context::Context *CTX, std::function CacheReader); - FEX_DEFAULT_VISIBILITY void SetAOTIRWriter(FEXCore::Context::Context *CTX, std::function(const std::string&)> CacheWriter); - FEX_DEFAULT_VISIBILITY void SetAOTIRRenamer(FEXCore::Context::Context *CTX, std::function CacheRenamer); - - FEX_DEFAULT_VISIBILITY void FinalizeAOTIRCache(FEXCore::Context::Context *CTX); - FEX_DEFAULT_VISIBILITY void WriteFilesWithCode(FEXCore::Context::Context *CTX, std::function Writer); - FEX_DEFAULT_VISIBILITY void InvalidateGuestCodeRange(FEXCore::Context::Context *CTX, uint64_t Start, uint64_t Length); - FEX_DEFAULT_VISIBILITY void InvalidateGuestCodeRange(FEXCore::Context::Context *CTX, uint64_t Start, uint64_t Length, std::function callback); - FEX_DEFAULT_VISIBILITY void MarkMemoryShared(FEXCore::Context::Context *CTX); - - FEX_DEFAULT_VISIBILITY void ConfigureAOTGen(FEXCore::Core::InternalThreadState *Thread, std::set *ExternalBranches, uint64_t SectionMaxAddress); - FEX_DEFAULT_VISIBILITY CustomIRResult AddCustomIREntrypoint(FEXCore::Context::Context *CTX, uintptr_t Entrypoint, std::function Handler, void *Creator = nullptr, void *Data = nullptr); - - /** - * @brief Allows the frontend to register its own thunk handlers independent of what is controlled in the backend. - * - * @param CTX A valid non-null context instance. - * @param Definitions A vector of thunk definitions that the frontend controls - */ - FEX_DEFAULT_VISIBILITY void AppendThunkDefinitions(FEXCore::Context::Context *CTX, std::vector const& Definitions); - - FEX_DEFAULT_VISIBILITY void SetVDSOSigReturn(FEXCore::Context::Context *CTX, const VDSOSigReturn &Pointers); - } diff --git a/External/FEXCore/include/FEXCore/Debug/ContextDebug.h b/External/FEXCore/include/FEXCore/Debug/ContextDebug.h index 595005ae3..67cd8cebf 100644 --- a/External/FEXCore/include/FEXCore/Debug/ContextDebug.h +++ b/External/FEXCore/include/FEXCore/Debug/ContextDebug.h @@ -10,7 +10,7 @@ namespace FEXCore::Core { } namespace FEXCore::Context { - struct Context; + class Context; namespace Debug { diff --git a/External/FEXCore/include/FEXCore/Debug/InternalThreadState.h b/External/FEXCore/include/FEXCore/Debug/InternalThreadState.h index 3e8a91dfb..21cc35faf 100644 --- a/External/FEXCore/include/FEXCore/Debug/InternalThreadState.h +++ b/External/FEXCore/include/FEXCore/Debug/InternalThreadState.h @@ -18,7 +18,7 @@ namespace FEXCore { } namespace FEXCore::Context { - struct Context; + class Context; } namespace FEXCore::CPU { diff --git a/External/FEXCore/include/FEXCore/HLE/SyscallHandler.h b/External/FEXCore/include/FEXCore/HLE/SyscallHandler.h index cab09c4b1..cc3042ca3 100644 --- a/External/FEXCore/include/FEXCore/HLE/SyscallHandler.h +++ b/External/FEXCore/include/FEXCore/HLE/SyscallHandler.h @@ -15,7 +15,7 @@ namespace FEXCore::IR { } namespace FEXCore::Context { - struct Context; + class Context; } namespace FEXCore::Core { diff --git a/Source/Tests/AOT/AOTGenerator.cpp b/Source/Tests/AOT/AOTGenerator.cpp index ab9c8db6e..05c3e867a 100644 --- a/Source/Tests/AOT/AOTGenerator.cpp +++ b/Source/Tests/AOT/AOTGenerator.cpp @@ -102,10 +102,9 @@ void AOTGenSection(FEXCore::Context::Context *CTX, ELFCodeLoader2::LoadedSection // Setup thread - Each compilation thread uses its own backing FEX thread FEXCore::Core::CPUState state; - auto Thread = FEXCore::Context::CreateThread(CTX, &state, FHU::Syscalls::gettid()); + auto Thread = CTX->CreateThread(&state, FHU::Syscalls::gettid()); std::set ExternalBranchesLocal; - FEXCore::Context::ConfigureAOTGen(Thread, &ExternalBranchesLocal, SectionMaxAddress); - + CTX->ConfigureAOTGen(Thread, &ExternalBranchesLocal, SectionMaxAddress); for (;;) { uint64_t BranchTarget; @@ -123,7 +122,7 @@ void AOTGenSection(FEXCore::Context::Context *CTX, ELFCodeLoader2::LoadedSection // Compile entrypoint counter++; - FEXCore::Context::CompileRIP(Thread, BranchTarget); + CTX->CompileRIP(Thread, BranchTarget); // Are there more branches? if (ExternalBranchesLocal.size() > 0) { @@ -143,7 +142,7 @@ void AOTGenSection(FEXCore::Context::Context *CTX, ELFCodeLoader2::LoadedSection } // All entryproints processed, cleanup this thread - FEXCore::Context::DestroyThread(CTX, Thread); + CTX->DestroyThread(Thread); }); // Add to the thread pool diff --git a/Source/Tests/ELFCodeLoader2.h b/Source/Tests/ELFCodeLoader2.h index 572202347..22fe7ac81 100644 --- a/Source/Tests/ELFCodeLoader2.h +++ b/Source/Tests/ELFCodeLoader2.h @@ -836,7 +836,7 @@ class ELFCodeLoader2 final : public FEXCore::CodeLoader { void CalculateHWCaps(FEXCore::Context::Context *ctx) { // HWCAP is just CPUID function 0x1, the EDX result - auto res_1 = FEXCore::Context::RunCPUIDFunction(ctx, 1, 0); + auto res_1 = ctx->RunCPUIDFunction(1, 0); HWCap = res_1.edx; // HWCAP2 is as follows: diff --git a/Source/Tests/FEXLoader.cpp b/Source/Tests/FEXLoader.cpp index 9baaad6e1..ffc78669a 100644 --- a/Source/Tests/FEXLoader.cpp +++ b/Source/Tests/FEXLoader.cpp @@ -377,8 +377,8 @@ int main(int argc, char **argv, char **const envp) { // System allocator is now system allocator or FEX FEXCore::Context::InitializeStaticTables(Loader.Is64BitMode() ? FEXCore::Context::MODE_64BIT : FEXCore::Context::MODE_32BIT); - auto CTX = FEXCore::Context::CreateNewContext(); - FEXCore::Context::InitializeContext(CTX); + auto CTX = FEXCore::Context::Context::CreateNewContext(); + CTX->InitializeContext(); auto SignalDelegation = std::make_unique(); @@ -423,22 +423,22 @@ int main(int argc, char **argv, char **const envp) { SyscallHandler->DefaultProgramBreak(BRKInfo.Base, BRKInfo.Size); - FEXCore::Context::SetSignalDelegator(CTX, SignalDelegation.get()); - FEXCore::Context::SetSyscallHandler(CTX, SyscallHandler.get()); - FEXCore::Context::InitCore(CTX, Loader.DefaultRIP(), Loader.GetStackPointer()); + CTX->SetSignalDelegator(SignalDelegation.get()); + CTX->SetSyscallHandler(SyscallHandler.get()); + CTX->InitCore(Loader.DefaultRIP(), Loader.GetStackPointer()); // Pass in our VDSO thunks - FEXCore::Context::AppendThunkDefinitions(CTX, FEX::VDSO::GetVDSOThunkDefinitions()); - FEXCore::Context::SetVDSOSigReturn(CTX, FEX::VDSO::GetVDSOSymbols()); + CTX->AppendThunkDefinitions(FEX::VDSO::GetVDSOThunkDefinitions()); + CTX->SetVDSOSigReturn(FEX::VDSO::GetVDSOSymbols()); FEXCore::Context::ExitReason ShutdownReason = FEXCore::Context::ExitReason::EXIT_SHUTDOWN; // There might already be an exit handler, leave it installed - if(!FEXCore::Context::GetExitHandler(CTX)) { - FEXCore::Context::SetExitHandler(CTX, [&](uint64_t thread, FEXCore::Context::ExitReason reason) { + if(!CTX->GetExitHandler()) { + CTX->SetExitHandler([&](uint64_t thread, FEXCore::Context::ExitReason reason) { if (reason != FEXCore::Context::ExitReason::EXIT_DEBUG) { ShutdownReason = reason; - FEXCore::Context::Stop(CTX); + CTX->Stop(); } }); } @@ -448,13 +448,13 @@ int main(int argc, char **argv, char **const envp) { LogMan::Msg::IFmt("Warning: AOTIR is experimental, and might lead to crashes. " "Capture doesn't work with programs that fork."); - FEXCore::Context::SetAOTIRLoader(CTX, [](const std::string &fileid) -> int { + CTX->SetAOTIRLoader([](const std::string &fileid) -> int { auto filepath = std::filesystem::path(FEXCore::Config::GetDataDirectory()) / "aotir" / (fileid + ".aotir"); return open(filepath.c_str(), O_RDONLY); }); - FEXCore::Context::SetAOTIRWriter(CTX, [](const std::string& fileid) -> std::unique_ptr { + CTX->SetAOTIRWriter([](const std::string& fileid) -> std::unique_ptr { auto filepath = std::filesystem::path(FEXCore::Config::GetDataDirectory()) / "aotir" / (fileid + ".aotir.tmp"); auto AOTWrite = std::make_unique(filepath, std::ios::out | std::ios::binary); if (*AOTWrite) { @@ -467,7 +467,7 @@ int main(int argc, char **argv, char **const envp) { return AOTWrite; }); - FEXCore::Context::SetAOTIRRenamer(CTX, [](const std::string& fileid) -> void { + CTX->SetAOTIRRenamer([](const std::string& fileid) -> void { auto TmpFilepath = std::filesystem::path(FEXCore::Config::GetDataDirectory()) / "aotir" / (fileid + ".aotir.tmp"); auto NewFilepath = std::filesystem::path(FEXCore::Config::GetDataDirectory()) / "aotir" / (fileid + ".aotir"); @@ -481,13 +481,13 @@ int main(int argc, char **argv, char **const envp) { FEX::AOT::AOTGenSection(CTX, Section); } } else { - FEXCore::Context::RunUntilExit(CTX); + CTX->RunUntilExit(); } if (AOTEnabled) { std::filesystem::create_directories(std::filesystem::path(FEXCore::Config::GetDataDirectory()) / "aotir", ec); if (!ec) { - FEXCore::Context::WriteFilesWithCode(CTX, [](const std::string& fileid, const std::string& filename) { + CTX->WriteFilesWithCode([](const std::string& fileid, const std::string& filename) { auto filepath = std::filesystem::path(FEXCore::Config::GetDataDirectory()) / "aotir" / (fileid + ".path"); int fd = open(filepath.c_str(), O_CREAT | O_EXCL | O_WRONLY, 0644); if (fd != -1) { @@ -498,16 +498,16 @@ int main(int argc, char **argv, char **const envp) { } if (AOTIRCapture() || AOTIRGenerate()) { - FEXCore::Context::FinalizeAOTIRCache(CTX); + CTX->FinalizeAOTIRCache(); LogMan::Msg::IFmt("AOTIR Cache Stored"); } } - auto ProgramStatus = FEXCore::Context::GetProgramStatus(CTX); + auto ProgramStatus = CTX->GetProgramStatus(); SyscallHandler.reset(); SignalDelegation.reset(); - FEXCore::Context::DestroyContext(CTX); + FEXCore::Context::Context::DestroyContext(CTX); FEXCore::Context::ShutdownStaticTables(); FEXCore::Threads::Shutdown(); diff --git a/Source/Tests/IRLoader.cpp b/Source/Tests/IRLoader.cpp index 08cb3c628..ceb573ba0 100644 --- a/Source/Tests/IRLoader.cpp +++ b/Source/Tests/IRLoader.cpp @@ -33,7 +33,7 @@ $end_info$ #include "HarnessHelpers.h" namespace FEXCore::Context { - struct Context; + class Context; } void MsgHandler(LogMan::DebugLevels Level, char const *Message) @@ -108,12 +108,12 @@ public: } } - bool LoadIR(FEXCore::Context::Context *CTX) const { + bool LoadIR(FEXCore::Context::Context *CTX) const { if (!ParsedCode) { return false; } - return !!AddCustomIREntrypoint(CTX, EntryRIP, [ParsedCodePtr = ParsedCode.get()](uintptr_t Entrypoint, FEXCore::IR::IREmitter *emit) { + return !!CTX->AddCustomIREntrypoint(EntryRIP, [ParsedCodePtr = ParsedCode.get()](uintptr_t Entrypoint, FEXCore::IR::IREmitter *emit) { emit->CopyData(*ParsedCodePtr); }); } @@ -181,20 +181,20 @@ int main(int argc, char **argv, char **const envp) LOGMAN_THROW_A_FMT(Args.size() > 1, "Not enough arguments"); FEXCore::Context::InitializeStaticTables(); - auto CTX = FEXCore::Context::CreateNewContext(); - FEXCore::Context::InitializeContext(CTX); + auto CTX = FEXCore::Context::Context::CreateNewContext(); + CTX->InitializeContext(); std::unique_ptr SignalDelegation = std::make_unique(); - FEXCore::Context::SetSignalDelegator(CTX, SignalDelegation.get()); - FEXCore::Context::SetSyscallHandler(CTX, new DummySyscallHandler()); + CTX->SetSignalDelegator(SignalDelegation.get()); + CTX->SetSyscallHandler(new DummySyscallHandler()); IRCodeLoader Loader(Args[0], Args[1]); // Skip tests that require AVX on hosts that don't support it. - const bool SupportsAVX = FEXCore::Context::GetHostFeatures(CTX).SupportsAVX; + const bool SupportsAVX = CTX->GetHostFeatures().SupportsAVX; if (!SupportsAVX && Loader.RequiresAVX()) { - FEXCore::Context::DestroyContext(CTX); + FEXCore::Context::Context::DestroyContext(CTX); return 0; } @@ -202,18 +202,18 @@ int main(int argc, char **argv, char **const envp) if (Loader.LoadIR(CTX)) { - FEXCore::Context::InitCore(CTX, Loader.DefaultRIP(), Loader.GetStackPointer()); + CTX->InitCore(Loader.DefaultRIP(), Loader.GetStackPointer()); auto ShutdownReason = FEXCore::Context::ExitReason::EXIT_SHUTDOWN; // There might already be an exit handler, leave it installed - if (!FEXCore::Context::GetExitHandler(CTX)) + if (!CTX->GetExitHandler()) { - FEXCore::Context::SetExitHandler(CTX, [&](uint64_t thread, FEXCore::Context::ExitReason reason) { + CTX->SetExitHandler([&](uint64_t thread, FEXCore::Context::ExitReason reason) { if (reason != FEXCore::Context::ExitReason::EXIT_DEBUG) { ShutdownReason = reason; - FEXCore::Context::Stop(CTX); + CTX->Stop(); } }); } @@ -228,14 +228,14 @@ int main(int argc, char **argv, char **const envp) LongJumpVal = setjmp(LongJump); if (!LongJumpVal) { - FEXCore::Context::RunUntilExit(CTX); + CTX->RunUntilExit(); } LogMan::Msg::DFmt("Reason we left VM: {}", FEXCore::ToUnderlying(ShutdownReason)); // Just re-use compare state. It also checks against the expected values in config. FEXCore::Core::CPUState State; - FEXCore::Context::GetCPUState(CTX, &State); + CTX->GetCPUState(&State); const bool Passed = Loader.CompareStates(&State, SupportsAVX); @@ -249,7 +249,6 @@ int main(int argc, char **argv, char **const envp) Return = -1; } - FEXCore::Context::DestroyContext(CTX); - + FEXCore::Context::Context::DestroyContext(CTX); return Return; } diff --git a/Source/Tests/LinuxSyscalls/EmulatedFiles/EmulatedFiles.cpp b/Source/Tests/LinuxSyscalls/EmulatedFiles/EmulatedFiles.cpp index ae6cd9884..939a7e52d 100644 --- a/Source/Tests/LinuxSyscalls/EmulatedFiles/EmulatedFiles.cpp +++ b/Source/Tests/LinuxSyscalls/EmulatedFiles/EmulatedFiles.cpp @@ -52,17 +52,17 @@ namespace FEX::EmulatedFile { std::string GenerateCPUInfo(FEXCore::Context::Context *ctx, uint32_t CPUCores) { std::ostringstream cpu_stream{}; - auto res_0 = FEXCore::Context::RunCPUIDFunction(ctx, 0, 0); - auto res_1 = FEXCore::Context::RunCPUIDFunction(ctx, 1, 0); - auto res_6 = FEXCore::Context::RunCPUIDFunction(ctx, 6, 0); - auto res_7 = FEXCore::Context::RunCPUIDFunction(ctx, 7, 0); - auto res_10 = FEXCore::Context::RunCPUIDFunction(ctx, 0x10, 0); + auto res_0 = ctx->RunCPUIDFunction(0, 0); + auto res_1 = ctx->RunCPUIDFunction(1, 0); + auto res_6 = ctx->RunCPUIDFunction(6, 0); + auto res_7 = ctx->RunCPUIDFunction(7, 0); + auto res_10 = ctx->RunCPUIDFunction(0x10, 0); - auto res_8000_0001 = FEXCore::Context::RunCPUIDFunction(ctx, 0x8000'0001, 0); - auto res_8000_0007 = FEXCore::Context::RunCPUIDFunction(ctx, 0x8000'0007, 0); - auto res_8000_0008 = FEXCore::Context::RunCPUIDFunction(ctx, 0x8000'0008, 0); - auto res_8000_000a = FEXCore::Context::RunCPUIDFunction(ctx, 0x8000'000a, 0); - auto res_8000_001f = FEXCore::Context::RunCPUIDFunction(ctx, 0x8000'001f, 0); + auto res_8000_0001 = ctx->RunCPUIDFunction(0x8000'0001, 0); + auto res_8000_0007 = ctx->RunCPUIDFunction(0x8000'0007, 0); + auto res_8000_0008 = ctx->RunCPUIDFunction(0x8000'0008, 0); + auto res_8000_000a = ctx->RunCPUIDFunction(0x8000'000a, 0); + auto res_8000_001f = ctx->RunCPUIDFunction(0x8000'001f, 0); union VendorID { struct { @@ -573,9 +573,9 @@ namespace FEX::EmulatedFile { cpu_stream << "cpu family\t: " << Family << std::endl; cpu_stream << "model\t\t: " << (info.Model + (info.FamilyID >= 6 ? (info.ExModelID << 4) : 0)) << std::endl; ModelName modelname {}; - auto res_8000_0002 = FEXCore::Context::RunCPUIDFunctionName(ctx, 0x8000'0002, 0, i); - auto res_8000_0003 = FEXCore::Context::RunCPUIDFunctionName(ctx, 0x8000'0003, 0, i); - auto res_8000_0004 = FEXCore::Context::RunCPUIDFunctionName(ctx, 0x8000'0004, 0, i); + auto res_8000_0002 = ctx->RunCPUIDFunctionName(0x8000'0002, 0, i); + auto res_8000_0003 = ctx->RunCPUIDFunctionName(0x8000'0003, 0, i); + auto res_8000_0004 = ctx->RunCPUIDFunctionName(0x8000'0004, 0, i); modelname.cpuid_2 = res_8000_0002; modelname.cpuid_3 = res_8000_0003; modelname.cpuid_4 = res_8000_0004; diff --git a/Source/Tests/LinuxSyscalls/EmulatedFiles/EmulatedFiles.h b/Source/Tests/LinuxSyscalls/EmulatedFiles/EmulatedFiles.h index af15bd54d..bc776f84f 100644 --- a/Source/Tests/LinuxSyscalls/EmulatedFiles/EmulatedFiles.h +++ b/Source/Tests/LinuxSyscalls/EmulatedFiles/EmulatedFiles.h @@ -14,7 +14,7 @@ $end_info$ #include namespace FEXCore::Context { - struct Context; + class Context; } namespace FEX::EmulatedFile { diff --git a/Source/Tests/LinuxSyscalls/FileManagement.cpp b/Source/Tests/LinuxSyscalls/FileManagement.cpp index 8fb458bbe..cd521dc55 100644 --- a/Source/Tests/LinuxSyscalls/FileManagement.cpp +++ b/Source/Tests/LinuxSyscalls/FileManagement.cpp @@ -55,10 +55,6 @@ namespace JSON { } } -namespace FEXCore::Context { - struct Context; -} - namespace FEX::HLE { struct open_how; diff --git a/Source/Tests/LinuxSyscalls/FileManagement.h b/Source/Tests/LinuxSyscalls/FileManagement.h index f28fa24aa..c9e5d38b7 100644 --- a/Source/Tests/LinuxSyscalls/FileManagement.h +++ b/Source/Tests/LinuxSyscalls/FileManagement.h @@ -24,7 +24,7 @@ $end_info$ #include "Tests/LinuxSyscalls/EmulatedFiles/EmulatedFiles.h" namespace FEXCore::Context { -struct Context; +class Context; } namespace FEX::HLE { diff --git a/Source/Tests/LinuxSyscalls/Syscalls.cpp b/Source/Tests/LinuxSyscalls/Syscalls.cpp index a6a71ca0f..52eccef33 100644 --- a/Source/Tests/LinuxSyscalls/Syscalls.cpp +++ b/Source/Tests/LinuxSyscalls/Syscalls.cpp @@ -53,10 +53,6 @@ $end_info$ #include #include -namespace FEXCore::Context { - struct Context; -} - namespace FEX::HLE { class SignalDelegator; SyscallHandler *_SyscallHandler{}; @@ -607,7 +603,7 @@ uint64_t CloneHandler(FEXCore::Core::CpuStateFrame *Frame, FEX::HLE::clone3_args }; if (flags & CLONE_VM) { - MarkMemoryShared(Frame->Thread->CTX); + Frame->Thread->CTX->MarkMemoryShared(); } // If there are flags that can't be handled regularly then we need to hand off to the true clone handler @@ -666,14 +662,14 @@ uint64_t CloneHandler(FEXCore::Core::CpuStateFrame *Frame, FEX::HLE::clone3_args } // Actually start the thread - FEXCore::Context::RunThread(Thread->CTX, NewThread); + Thread->CTX->RunThread(NewThread); if (flags & CLONE_VFORK) { // If VFORK is set then the calling process is suspended until the thread exits with execve or exit NewThread->ExecutionThread->join(nullptr); // Normally a thread cleans itself up on exit. But because we need to join, we are now responsible - FEXCore::Context::DestroyThread(Thread->CTX, NewThread); + Thread->CTX->DestroyThread(NewThread); } SYSCALL_ERRNO(); } @@ -708,7 +704,7 @@ uint64_t SyscallHandler::HandleBRK(FEXCore::Core::CpuStateFrame *Frame, void *Ad // We have pages we can unmap auto ok = GuestMunmap(reinterpret_cast(DataSpace + NewSizeAligned), RemainingSize); LOGMAN_THROW_A_FMT(ok != -1, "Munmap failed"); - + DataSpaceMaxSize = NewSizeAligned; } else if (NewSize > DataSpaceMaxSize) { @@ -864,8 +860,8 @@ void SyscallHandler::UnlockAfterFork() { // XXX shared_mutex has issues with locking and forks // VMATracking.Mutex.unlock(); - - FM.GetFDLock()->unlock(); + + FM.GetFDLock()->unlock(); } static bool isHEX(char c) { @@ -880,7 +876,7 @@ std::unique_ptr SyscallHandler::GenerateMap(const s LogMan::Msg::DFmt("GenerateMap: '{}' is not an elf file?", GuestBinaryFile); return {}; } - + struct stat GuestBinaryFileStat; if (stat(GuestBinaryFile.data(), &GuestBinaryFileStat)) { @@ -903,7 +899,7 @@ std::unique_ptr SyscallHandler::GenerateMap(const s if (stat(GuestSourceFile.data(), &GuestSourceFileStat) != 0 || GuestBinaryFileStat.st_mtime > GuestSourceFileStat.st_mtime) { LogMan::Msg::DFmt("GenerateMap: Generating source for '{}'", GuestBinaryFile); - auto command = fmt::format("x86_64-linux-gnu-objdump -SC \'{}\' > '{}'", GuestBinaryFile, GuestSourceFile); + auto command = fmt::format("x86_64-linux-gnu-objdump -SC \'{}\' > '{}'", GuestBinaryFile, GuestSourceFile); if (system(command.c_str()) != 0) { LogMan::Msg::DFmt("GenerateMap: '{}' failed", command); return {}; @@ -918,7 +914,7 @@ std::unique_ptr SyscallHandler::GenerateMap(const s if (!GenerateIndex) { // Index file de-serialization LogMan::Msg::DFmt("GenerateMap: Reading index '{}'", GuestIndexFile); - + std::ifstream Stream(GuestIndexFile); if (!Stream) { @@ -945,7 +941,7 @@ std::unique_ptr SyscallHandler::GenerateMap(const s { auto len = rv->SortedLineMappings.size(); - + Stream.read((char*)&len, sizeof(len)); rv->SortedLineMappings.resize(len); @@ -959,7 +955,7 @@ std::unique_ptr SyscallHandler::GenerateMap(const s { auto len = rv->SortedSymbolMappings.size(); - + Stream.read((char*)&len, sizeof(len)); rv->SortedSymbolMappings.resize(len); @@ -1000,7 +996,7 @@ std::unique_ptr SyscallHandler::GenerateMap(const s // objdump parsing std::string Line; int LineNum = 0; - + bool PreviousLineWasEmpty = false; uintptr_t LastSymbolOffset{}; @@ -1143,7 +1139,7 @@ std::unique_ptr SyscallHandler::GenerateMap(const s { auto len = rv->SortedLineMappings.size(); - + IndexStream.write((const char*)&len, sizeof(len)); for (const auto &Mapping: rv->SortedLineMappings) { @@ -1155,7 +1151,7 @@ std::unique_ptr SyscallHandler::GenerateMap(const s { auto len = rv->SortedSymbolMappings.size(); - + IndexStream.write((char*)&len, sizeof(len)); for (const auto &Mapping: rv->SortedSymbolMappings) { @@ -1174,7 +1170,7 @@ std::unique_ptr SyscallHandler::GenerateMap(const s return rv; } - + } } diff --git a/Source/Tests/LinuxSyscalls/Syscalls.h b/Source/Tests/LinuxSyscalls/Syscalls.h index 595374444..f80babdf0 100644 --- a/Source/Tests/LinuxSyscalls/Syscalls.h +++ b/Source/Tests/LinuxSyscalls/Syscalls.h @@ -42,7 +42,7 @@ $end_info$ namespace FEXCore { class CodeLoader; namespace Context { - struct Context; + class Context; } namespace Core { struct CpuStateFrame; diff --git a/Source/Tests/LinuxSyscalls/Syscalls/Thread.cpp b/Source/Tests/LinuxSyscalls/Syscalls/Thread.cpp index be34765b3..2844c729a 100644 --- a/Source/Tests/LinuxSyscalls/Syscalls/Thread.cpp +++ b/Source/Tests/LinuxSyscalls/Syscalls/Thread.cpp @@ -55,8 +55,8 @@ namespace FEX::HLE { NewThreadState.gregs[FEXCore::X86State::REG_RSP] = args->args.stack; } - auto NewThread = FEXCore::Context::CreateThread(CTX, &NewThreadState, args->args.parent_tid); - FEXCore::Context::InitializeThread(CTX, NewThread); + auto NewThread = CTX->CreateThread(&NewThreadState, args->args.parent_tid); + CTX->InitializeThread(NewThread); if (FEX::HLE::_SyscallHandler->Is64BitMode()) { if (flags & CLONE_SETTLS) { @@ -128,7 +128,7 @@ namespace FEX::HLE { } // Overwrite thread - NewThread = FEXCore::Context::CreateThread(CTX, &NewThreadState, GuestArgs->parent_tid); + NewThread = CTX->CreateThread(&NewThreadState, GuestArgs->parent_tid); // CLONE_PARENT_SETTID, CLONE_CHILD_SETTID, CLONE_CHILD_CLEARTID, CLONE_PIDFD will be handled by kernel // Call execution thread directly since we already are on the new thread @@ -138,7 +138,7 @@ namespace FEX::HLE { // If we don't have CLONE_THREAD then we are effectively a fork // Clear all the other threads that are being tracked // Frame->Thread is /ONLY/ safe to access when CLONE_THREAD flag is not set - FEXCore::Context::CleanupAfterFork(CTX, Frame->Thread); + CTX->CleanupAfterFork(Frame->Thread); Thread->CurrentFrame->State.gregs[FEXCore::X86State::REG_RAX] = 0; Thread->CurrentFrame->State.gregs[FEXCore::X86State::REG_RBX] = 0; @@ -177,7 +177,7 @@ namespace FEX::HLE { // Start exuting the thread directly // Our host clone starts in a new stack space, so it can't return back to the JIT space - FEXCore::Context::ExecutionThread(CTX, Thread); + CTX->ExecutionThread(Thread); // The rest of the context remains as is and the thread will continue executing return Thread->StatusCode; @@ -209,7 +209,7 @@ namespace FEX::HLE { Thread->ThreadManager.clear_child_tid = nullptr; // Clear all the other threads that are being tracked - FEXCore::Context::CleanupAfterFork(Thread->CTX, Frame->Thread); + Thread->CTX->CleanupAfterFork(Frame->Thread); // only a single thread running so no need to remove anything from the thread array @@ -264,7 +264,7 @@ namespace FEX::HLE { using namespace FEXCore::IR; REGISTER_SYSCALL_IMPL(rt_sigreturn, [](FEXCore::Core::CpuStateFrame *Frame) -> uint64_t { - FEXCore::Context::HandleSignalHandlerReturn(Frame->Thread->CTX, true); + Frame->Thread->CTX->HandleSignalHandlerReturn(true); FEX_UNREACHABLE; }); @@ -305,7 +305,7 @@ namespace FEX::HLE { } Thread->StatusCode = status; - FEXCore::Context::StopThread(Thread->CTX, Thread); + Thread->CTX->StopThread(Thread); return 0; }); @@ -513,7 +513,7 @@ namespace FEX::HLE { [](FEXCore::Core::CpuStateFrame *Frame, int status) -> uint64_t { auto Thread = Frame->Thread; Thread->StatusCode = status; - FEXCore::Context::Stop(Thread->CTX); + Thread->CTX->Stop(); // This will never be reached std::terminate(); }); diff --git a/Source/Tests/LinuxSyscalls/SyscallsSMCTracking.cpp b/Source/Tests/LinuxSyscalls/SyscallsSMCTracking.cpp index 8aaed027d..cd32a69bd 100644 --- a/Source/Tests/LinuxSyscalls/SyscallsSMCTracking.cpp +++ b/Source/Tests/LinuxSyscalls/SyscallsSMCTracking.cpp @@ -79,17 +79,17 @@ bool SyscallHandler::HandleSegfault(FEXCore::Core::InternalThreadState *Thread, auto FaultBaseMirrored = Offset - VMA->Offset + VMA->Base; if (VMA->Prot.Writable) { - FEXCore::Context::InvalidateGuestCodeRange(CTX, FaultBaseMirrored, FHU::FEX_PAGE_SIZE, [](uintptr_t Start, uintptr_t Length) { + CTX->InvalidateGuestCodeRange(FaultBaseMirrored, FHU::FEX_PAGE_SIZE, [](uintptr_t Start, uintptr_t Length) { auto rv = mprotect((void *)Start, Length, PROT_READ | PROT_WRITE); LogMan::Throw::AAFmt(rv == 0, "mprotect({}, {}) failed", Start, Length); }); } else { - FEXCore::Context::InvalidateGuestCodeRange(CTX, FaultBaseMirrored, FHU::FEX_PAGE_SIZE); + CTX->InvalidateGuestCodeRange(FaultBaseMirrored, FHU::FEX_PAGE_SIZE); } } } while ((VMA = VMA->ResourceNextVMA)); } else { - FEXCore::Context::InvalidateGuestCodeRange(CTX, FaultBase, FHU::FEX_PAGE_SIZE, [](uintptr_t Start, uintptr_t Length) { + CTX->InvalidateGuestCodeRange(FaultBase, FHU::FEX_PAGE_SIZE, [](uintptr_t Start, uintptr_t Length) { auto rv = mprotect((void *)Start, Length, PROT_READ | PROT_WRITE); LogMan::Throw::AAFmt(rv == 0, "mprotect({}, {}) failed", Start, Length); }); @@ -184,7 +184,7 @@ void SyscallHandler::TrackMmap(uintptr_t Base, uintptr_t Size, int Prot, int Fla Size = FEXCore::AlignUp(Size, FHU::FEX_PAGE_SIZE); if (Flags & MAP_SHARED) { - MarkMemoryShared(CTX); + CTX->MarkMemoryShared(); } { @@ -206,7 +206,7 @@ void SyscallHandler::TrackMmap(uintptr_t Base, uintptr_t Size, int Prot, int Fla Resource = &Iter->second; if (Inserted) { - Resource->AOTIRCacheEntry = FEXCore::Context::LoadAOTIRCacheEntry(CTX, filename.value()); + Resource->AOTIRCacheEntry = CTX->LoadAOTIRCacheEntry(filename.value()); Resource->Iterator = Iter; } } @@ -225,7 +225,7 @@ void SyscallHandler::TrackMmap(uintptr_t Base, uintptr_t Size, int Prot, int Fla } if (SMCChecks != FEXCore::Config::CONFIG_SMC_NONE) { - FEXCore::Context::InvalidateGuestCodeRange(CTX, (uintptr_t)Base, Size); + CTX->InvalidateGuestCodeRange((uintptr_t)Base, Size); } } @@ -239,7 +239,7 @@ void SyscallHandler::TrackMunmap(uintptr_t Base, uintptr_t Size) { } if (SMCChecks != FEXCore::Config::CONFIG_SMC_NONE) { - FEXCore::Context::InvalidateGuestCodeRange(CTX, (uintptr_t)Base, Size); + CTX->InvalidateGuestCodeRange((uintptr_t)Base, Size); } } @@ -253,7 +253,7 @@ void SyscallHandler::TrackMprotect(uintptr_t Base, uintptr_t Size, int Prot) { } if (SMCChecks != FEXCore::Config::CONFIG_SMC_NONE) { - FEXCore::Context::InvalidateGuestCodeRange(CTX, Base, Size); + CTX->InvalidateGuestCodeRange(Base, Size); } } @@ -299,19 +299,19 @@ void SyscallHandler::TrackMremap(uintptr_t OldAddress, size_t OldSize, size_t Ne if (OldAddress != NewAddress) { if (OldSize != 0) { // This also handles the MREMAP_DONTUNMAP case - FEXCore::Context::InvalidateGuestCodeRange(CTX, OldAddress, OldSize); + CTX->InvalidateGuestCodeRange(OldAddress, OldSize); } } else { // If mapping shrunk, flush the unmapped region if (OldSize > NewSize) { - FEXCore::Context::InvalidateGuestCodeRange(CTX, OldAddress + NewSize, OldSize - NewSize); + CTX->InvalidateGuestCodeRange(OldAddress + NewSize, OldSize - NewSize); } } } } void SyscallHandler::TrackShmat(int shmid, uintptr_t Base, int shmflg) { - MarkMemoryShared(CTX); + CTX->MarkMemoryShared(); shmid_ds stat; @@ -336,7 +336,7 @@ void SyscallHandler::TrackShmat(int shmid, uintptr_t Base, int shmflg) { ); } if (SMCChecks != FEXCore::Config::CONFIG_SMC_NONE) { - FEXCore::Context::InvalidateGuestCodeRange(CTX, Base, Length); + CTX->InvalidateGuestCodeRange(Base, Length); } } @@ -350,7 +350,7 @@ void SyscallHandler::TrackShmdt(uintptr_t Base) { if (SMCChecks != FEXCore::Config::CONFIG_SMC_NONE) { // This might over flush if the shm has holes in it - FEXCore::Context::InvalidateGuestCodeRange(CTX, Base, Length); + CTX->InvalidateGuestCodeRange(Base, Length); } } diff --git a/Source/Tests/LinuxSyscalls/SyscallsVMATracking.cpp b/Source/Tests/LinuxSyscalls/SyscallsVMATracking.cpp index b66db2657..99f88848c 100644 --- a/Source/Tests/LinuxSyscalls/SyscallsVMATracking.cpp +++ b/Source/Tests/LinuxSyscalls/SyscallsVMATracking.cpp @@ -198,7 +198,7 @@ void SyscallHandler::VMATracking::ClearUnsafe(FEXCore::Context::Context *CTX, ui if (Current->Resource) { if (ListRemove(Current) && Current->Resource != PreservedMappedResource) { if (Current->Resource->AOTIRCacheEntry) { - FEXCore::Context::UnloadAOTIRCacheEntry(CTX, Current->Resource->AOTIRCacheEntry); + CTX->UnloadAOTIRCacheEntry(Current->Resource->AOTIRCacheEntry); } MappedResources.erase(Current->Resource->Iterator); } @@ -351,7 +351,7 @@ uintptr_t SyscallHandler::VMATracking::ClearShmUnsafe(FEXCore::Context::Context if (Entry->second.Resource == Resource) { if (ListRemove(&Entry->second)) { if (Entry->second.Resource->AOTIRCacheEntry) { - FEXCore::Context::UnloadAOTIRCacheEntry(CTX, Entry->second.Resource->AOTIRCacheEntry); + CTX->UnloadAOTIRCacheEntry(Entry->second.Resource->AOTIRCacheEntry); } MappedResources.erase(Entry->second.Resource->Iterator); } @@ -363,4 +363,4 @@ uintptr_t SyscallHandler::VMATracking::ClearShmUnsafe(FEXCore::Context::Context return ShmLength; } -} \ No newline at end of file +} diff --git a/Source/Tests/LinuxSyscalls/x32/Syscalls.cpp b/Source/Tests/LinuxSyscalls/x32/Syscalls.cpp index ff4eb44da..802c2b55d 100644 --- a/Source/Tests/LinuxSyscalls/x32/Syscalls.cpp +++ b/Source/Tests/LinuxSyscalls/x32/Syscalls.cpp @@ -23,10 +23,6 @@ $end_info$ #include #include -namespace FEXCore::Context { - struct Context; -} - namespace FEX::HLE::x32 { void RegisterEpoll(FEX::HLE::SyscallHandler *Handler); void RegisterFD(FEX::HLE::SyscallHandler *Handler); diff --git a/Source/Tests/LinuxSyscalls/x32/Syscalls.h b/Source/Tests/LinuxSyscalls/x32/Syscalls.h index 8e7bdeed9..1bdb88edc 100644 --- a/Source/Tests/LinuxSyscalls/x32/Syscalls.h +++ b/Source/Tests/LinuxSyscalls/x32/Syscalls.h @@ -15,7 +15,7 @@ $end_info$ namespace FEXCore { namespace Context { - struct Context; + class Context; } namespace Core { struct CpuStateFrame; diff --git a/Source/Tests/LinuxSyscalls/x32/Thread.cpp b/Source/Tests/LinuxSyscalls/x32/Thread.cpp index dcaadfe38..0912b0d3a 100644 --- a/Source/Tests/LinuxSyscalls/x32/Thread.cpp +++ b/Source/Tests/LinuxSyscalls/x32/Thread.cpp @@ -100,7 +100,7 @@ namespace FEX::HLE::x32 { void RegisterThread(FEX::HLE::SyscallHandler *Handler) { REGISTER_SYSCALL_IMPL_X32(sigreturn, [](FEXCore::Core::CpuStateFrame *Frame) -> uint64_t { - FEXCore::Context::HandleSignalHandlerReturn(Frame->Thread->CTX, false); + Frame->Thread->CTX->HandleSignalHandlerReturn(false); FEX_UNREACHABLE; }); diff --git a/Source/Tests/TestHarnessRunner.cpp b/Source/Tests/TestHarnessRunner.cpp index f34c7f8be..c972dfe0f 100644 --- a/Source/Tests/TestHarnessRunner.cpp +++ b/Source/Tests/TestHarnessRunner.cpp @@ -162,12 +162,12 @@ int main(int argc, char **argv, char **const envp) { FEXCore::Context::InitializeStaticTables(Loader.Is64BitMode() ? FEXCore::Context::MODE_64BIT : FEXCore::Context::MODE_32BIT); - auto CTX = FEXCore::Context::CreateNewContext(); + auto CTX = FEXCore::Context::Context::CreateNewContext(); - FEXCore::Context::InitializeContext(CTX); + CTX->InitializeContext(); // Skip any tests that the host doesn't support features for - auto HostFeatures = FEXCore::Context::GetHostFeatures(CTX); + auto HostFeatures = CTX->GetHostFeatures(); SupportsAVX = HostFeatures.SupportsAVX; bool TestUnsupported = @@ -182,7 +182,7 @@ int main(int argc, char **argv, char **const envp) { (!HostFeatures.SupportsCLWB && Loader.RequiresCLWB()); if (TestUnsupported) { - FEXCore::Context::DestroyContext(CTX); + FEXCore::Context::Context::DestroyContext(CTX); return 0; } @@ -214,10 +214,10 @@ int main(int argc, char **argv, char **const envp) { return -ENOEXEC; } - FEXCore::Context::SetSignalDelegator(CTX, SignalDelegation.get()); - FEXCore::Context::SetSyscallHandler(CTX, SyscallHandler.get()); + CTX->SetSignalDelegator(SignalDelegation.get()); + CTX->SetSyscallHandler(SyscallHandler.get()); - bool Result1 = FEXCore::Context::InitCore(CTX, Loader.DefaultRIP(), Loader.GetStackPointer()); + bool Result1 = CTX->InitCore(Loader.DefaultRIP(), Loader.GetStackPointer()); if (!Result1) { return 1; @@ -225,11 +225,11 @@ int main(int argc, char **argv, char **const envp) { LongJumpVal = setjmp(LongJump); if (!LongJumpVal) { - FEXCore::Context::RunUntilExit(CTX); + CTX->RunUntilExit(); } // Just re-use compare state. It also checks against the expected values in config. - FEXCore::Context::GetCPUState(CTX, &State); + CTX->GetCPUState(&State); SyscallHandler.reset(); } else { @@ -245,7 +245,7 @@ int main(int argc, char **argv, char **const envp) { RunAsHost(SignalDelegation, Loader.DefaultRIP(), Loader.GetStackPointer(), &State); } - FEXCore::Context::DestroyContext(CTX); + FEXCore::Context::Context::DestroyContext(CTX); FEXCore::Context::ShutdownStaticTables(); bool Passed = !DidFault && Loader.CompareStates(&State, nullptr, SupportsAVX); diff --git a/Source/Tests/TestHarnessRunner/HostRunner.h b/Source/Tests/TestHarnessRunner/HostRunner.h index 784b2d73d..e32c80d8c 100644 --- a/Source/Tests/TestHarnessRunner/HostRunner.h +++ b/Source/Tests/TestHarnessRunner/HostRunner.h @@ -6,7 +6,7 @@ namespace FEXCore::CPU { class CPUBackend; } namespace FEXCore::Context{ - struct Context; + class Context; } namespace FEXCore::Core { struct InternalThreadState; @@ -17,4 +17,4 @@ namespace FEX::HLE { class SignalDelegator; } -void RunAsHost(std::unique_ptr &SignalDelegation, uintptr_t InitialRip, uintptr_t StackPointer, FEXCore::Core::CPUState *OutputState); \ No newline at end of file +void RunAsHost(std::unique_ptr &SignalDelegation, uintptr_t InitialRip, uintptr_t StackPointer, FEXCore::Core::CPUState *OutputState);