1
0
Fork 0
mirror of https://github.com/beefytech/Beef.git synced 2025-06-10 20:42:21 +02:00

Extensive runtime refactor to reduce generated executable sizes

This commit is contained in:
Brian Fiete 2024-03-16 07:23:29 -04:00
parent 4e750a7e1a
commit ddd9b1b218
74 changed files with 2514 additions and 717 deletions

View file

@ -100,12 +100,14 @@ enum BfpCrashReportKind
};
BFP_EXPORT void BFP_CALLTYPE BfpSystem_Init(int version, BfpSystemInitFlags flags);
BFP_EXPORT void BFP_CALLTYPE BfpSystem_InitCrashCatcher(BfpSystemInitFlags flags);
BFP_EXPORT void BFP_CALLTYPE BfpSystem_SetCommandLine(int argc, char** argv);
BFP_EXPORT void BFP_CALLTYPE BfpSystem_SetCrashReportKind(BfpCrashReportKind crashReportKind);
BFP_EXPORT void BFP_CALLTYPE BfpSystem_AddCrashInfoFunc(BfpCrashInfoFunc crashInfoFunc);
BFP_EXPORT void BFP_CALLTYPE BfpSystem_AddCrashInfo(const char* str); // Can do at any time, or during CrashInfoFunc callbacks
BFP_EXPORT void BFP_CALLTYPE BfpSystem_SetCrashRelaunchCmd(const char* str);
BFP_EXPORT void BFP_CALLTYPE BfpSystem_Shutdown();
BFP_EXPORT void BFP_CALLTYPE BfpSystem_ShutdownCrashCatcher();
BFP_EXPORT uint32 BFP_CALLTYPE BfpSystem_TickCount();
BFP_EXPORT BfpTimeStamp BFP_CALLTYPE BfpSystem_GetTimeStamp();
BFP_EXPORT uint16 BFP_CALLTYPE BfpSystem_EndianSwap16(uint16 val);

View file

@ -52,7 +52,6 @@ static SYMGETMODULEBASEPROC gSymGetModuleBase = NULL;
static SYMGETSYMFROMADDRPROC gSymGetSymFromAddr = NULL;
static SYMGETLINEFROMADDR gSymGetLineFromAddr = NULL;
static bool CreateMiniDump(EXCEPTION_POINTERS* pep, const StringImpl& filePath);
static bool LoadImageHelp()
@ -117,47 +116,6 @@ static bool LoadImageHelp()
return true;
}
struct
{
DWORD dwExceptionCode;
char *szMessage;
} gMsgTable[] = {
{ STATUS_SEGMENT_NOTIFICATION, "Segment Notification" },
{ STATUS_BREAKPOINT, "Breakpoint" },
{ STATUS_SINGLE_STEP, "Single step" },
{ STATUS_WAIT_0, "Wait 0" },
{ STATUS_ABANDONED_WAIT_0, "Abandoned Wait 0" },
{ STATUS_USER_APC, "User APC" },
{ STATUS_TIMEOUT, "Timeout" },
{ STATUS_PENDING, "Pending" },
{ STATUS_GUARD_PAGE_VIOLATION, "Guard Page Violation" },
{ STATUS_DATATYPE_MISALIGNMENT, "Data Type Misalignment" },
{ STATUS_ACCESS_VIOLATION, "Access Violation" },
{ STATUS_IN_PAGE_ERROR, "In Page Error" },
{ STATUS_NO_MEMORY, "No Memory" },
{ STATUS_ILLEGAL_INSTRUCTION, "Illegal Instruction" },
{ STATUS_NONCONTINUABLE_EXCEPTION, "Noncontinuable Exception" },
{ STATUS_INVALID_DISPOSITION, "Invalid Disposition" },
{ STATUS_ARRAY_BOUNDS_EXCEEDED, "Array Bounds Exceeded" },
{ STATUS_FLOAT_DENORMAL_OPERAND, "Float Denormal Operand" },
{ STATUS_FLOAT_DIVIDE_BY_ZERO, "Divide by Zero" },
{ STATUS_FLOAT_INEXACT_RESULT, "Float Inexact Result" },
{ STATUS_FLOAT_INVALID_OPERATION, "Float Invalid Operation" },
{ STATUS_FLOAT_OVERFLOW, "Float Overflow" },
{ STATUS_FLOAT_STACK_CHECK, "Float Stack Check" },
{ STATUS_FLOAT_UNDERFLOW, "Float Underflow" },
{ STATUS_INTEGER_DIVIDE_BY_ZERO, "Integer Divide by Zero" },
{ STATUS_INTEGER_OVERFLOW, "Integer Overflow" },
{ STATUS_PRIVILEGED_INSTRUCTION, "Privileged Instruction" },
{ STATUS_STACK_OVERFLOW, "Stack Overflow" },
{ STATUS_CONTROL_C_EXIT, "Ctrl+C Exit" },
{ 0xFFFFFFFF, "" }
};
static HFONT gDialogFont;
static HFONT gBoldFont;
static String gErrorTitle;
static String gErrorText;
static HWND gDebugButtonWindow = NULL;
static HWND gYesButtonWindow = NULL;
static HWND gNoButtonWindow = NULL;
@ -265,19 +223,19 @@ static void ShowErrorDialog(const StringImpl& errorTitle, const StringImpl& erro
gUseDefaultFonts = aVersionInfo.dwPlatformId != VER_PLATFORM_WIN32_NT;
int aHeight = -MulDiv(8, 96, 72);
gDialogFont = ::CreateFontA(aHeight, 0, 0, 0, FW_NORMAL, FALSE, FALSE,
HFONT gDialogFont = ::CreateFontA(aHeight, 0, 0, 0, FW_NORMAL, FALSE, FALSE,
false, ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY,
DEFAULT_PITCH | FF_DONTCARE, "Tahoma");
aHeight = -MulDiv(10, 96, 72);
gBoldFont = ::CreateFontA(aHeight, 0, 0, 0, FW_BOLD, FALSE, FALSE,
HFONT gBoldFont = ::CreateFontA(aHeight, 0, 0, 0, FW_BOLD, FALSE, FALSE,
false, ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY,
DEFAULT_PITCH | FF_DONTCARE, "Tahoma");
::SetCursor(::LoadCursor(NULL, IDC_ARROW));
gErrorTitle = errorTitle;
gErrorText = errorText;
String gErrorTitle = errorTitle;
String gErrorText = errorText;
WNDCLASSW wc;
wc.style = 0;
@ -935,6 +893,44 @@ static void DoHandleDebugEvent(LPEXCEPTION_POINTERS lpEP)
///////////////////////////
// first name the exception
struct
{
DWORD dwExceptionCode;
char* szMessage;
} gMsgTable[] = {
{ STATUS_SEGMENT_NOTIFICATION, "Segment Notification" },
{ STATUS_BREAKPOINT, "Breakpoint" },
{ STATUS_SINGLE_STEP, "Single step" },
{ STATUS_WAIT_0, "Wait 0" },
{ STATUS_ABANDONED_WAIT_0, "Abandoned Wait 0" },
{ STATUS_USER_APC, "User APC" },
{ STATUS_TIMEOUT, "Timeout" },
{ STATUS_PENDING, "Pending" },
{ STATUS_GUARD_PAGE_VIOLATION, "Guard Page Violation" },
{ STATUS_DATATYPE_MISALIGNMENT, "Data Type Misalignment" },
{ STATUS_ACCESS_VIOLATION, "Access Violation" },
{ STATUS_IN_PAGE_ERROR, "In Page Error" },
{ STATUS_NO_MEMORY, "No Memory" },
{ STATUS_ILLEGAL_INSTRUCTION, "Illegal Instruction" },
{ STATUS_NONCONTINUABLE_EXCEPTION, "Noncontinuable Exception" },
{ STATUS_INVALID_DISPOSITION, "Invalid Disposition" },
{ STATUS_ARRAY_BOUNDS_EXCEEDED, "Array Bounds Exceeded" },
{ STATUS_FLOAT_DENORMAL_OPERAND, "Float Denormal Operand" },
{ STATUS_FLOAT_DIVIDE_BY_ZERO, "Divide by Zero" },
{ STATUS_FLOAT_INEXACT_RESULT, "Float Inexact Result" },
{ STATUS_FLOAT_INVALID_OPERATION, "Float Invalid Operation" },
{ STATUS_FLOAT_OVERFLOW, "Float Overflow" },
{ STATUS_FLOAT_STACK_CHECK, "Float Stack Check" },
{ STATUS_FLOAT_UNDERFLOW, "Float Underflow" },
{ STATUS_INTEGER_DIVIDE_BY_ZERO, "Integer Divide by Zero" },
{ STATUS_INTEGER_OVERFLOW, "Integer Overflow" },
{ STATUS_PRIVILEGED_INSTRUCTION, "Privileged Instruction" },
{ STATUS_STACK_OVERFLOW, "Stack Overflow" },
{ STATUS_CONTROL_C_EXIT, "Ctrl+C Exit" },
{ 0xFFFFFFFF, "" }
};
char *szName = NULL;
for (int i = 0; gMsgTable[i].dwExceptionCode != 0xFFFFFFFF; i++)
{

View file

@ -39,9 +39,14 @@
USING_NS_BF;
static void Crash_Error(const char* msg);
typedef void(*BfpCrashErrorFunc)(const char* str);
static bool gTimerInitialized = false;
static int gTimerDivisor = 0;
CritSect gBfpCritSect;
BfpCrashErrorFunc gCrashErrorFunc = Crash_Error;
struct WindowsSharedInfo
{
@ -415,8 +420,9 @@ void Beefy::BFFatalError(const StringImpl& message, const StringImpl& file, int
gBFApp->mSysDialogCnt++;
#endif
String failMsg = StrFormat("%s in %s:%d", message.c_str(), file.c_str(), line);
BfpSystem_FatalError(failMsg.c_str(), "FATAL ERROR");
char* failMsg = new char[message.length() + file.length() + 64];
sprintf(failMsg, "%s in %s:%d", message.c_str(), file.c_str(), line);
BfpSystem_FatalError(failMsg, "FATAL ERROR");
#ifndef BF_NO_BFAPP
if (gBFApp != NULL)
@ -906,6 +912,7 @@ static void __cdecl AbortHandler(int)
static int64 gCPUFreq = -1;
static int64 gStartCPUTick = -1;
static int64 gStartQPF = -1;
static void(*sOldSIGABRTHandler)(int signal) = nullptr;
static void InitCPUFreq()
{
@ -918,10 +925,31 @@ static void InitCPUFreq()
}
}
static void(*sOldSIGABRTHandler)(int signal) = nullptr;
static void Crash_Error(const char* msg)
{
HMODULE hMod = GetModuleHandleA(NULL);
PIMAGE_DOS_HEADER pDosHdr = (PIMAGE_DOS_HEADER)hMod;
PIMAGE_NT_HEADERS pNtHdr = (PIMAGE_NT_HEADERS)((uint8*)hMod + pDosHdr->e_lfanew);
bool isCLI = pNtHdr->OptionalHeader.Subsystem == IMAGE_SUBSYSTEM_WINDOWS_CUI;
if (isCLI)
fprintf(stderr, "**** FATAL APPLICATION ERROR ****\n%s\n", msg);
else
::MessageBoxA(NULL, msg, "FATAL ERROR", MB_ICONSTOP);
_set_purecall_handler(nullptr);
_set_invalid_parameter_handler(nullptr);
signal(SIGABRT, sOldSIGABRTHandler);
abort();
}
static void Crash_Error_CrashHandler(const char* msg)
{
CrashCatcher::Get()->Crash(msg);
}
BFP_EXPORT void BFP_CALLTYPE BfpSystem_Init(int version, BfpSystemInitFlags flags)
{
gCrashErrorFunc = Crash_Error;
InitCPUFreq();
::_set_error_mode(_OUT_TO_STDERR);
@ -935,7 +963,9 @@ BFP_EXPORT void BFP_CALLTYPE BfpSystem_Init(int version, BfpSystemInitFlags flag
if (version != BFP_VERSION)
{
BfpSystem_FatalError(StrFormat("Bfp build version '%d' does not match requested version '%d'", BFP_VERSION, version).c_str(), "BFP FATAL ERROR");
char msg[1024];
sprintf(msg, "Bfp build version '%d' does not match requested version '%d'", BFP_VERSION, version);
BfpSystem_FatalError(msg, "BFP FATAL ERROR");
}
if ((flags & BfpSystemInitFlag_InstallCrashCatcher) != 0)
@ -953,13 +983,17 @@ BFP_EXPORT void BFP_CALLTYPE BfpSystem_Init(int version, BfpSystemInitFlags flag
sOldSIGABRTHandler = signal(SIGABRT, &AbortHandler);
if (sOldSIGABRTHandler == SIG_ERR)
sOldSIGABRTHandler = nullptr;
CrashCatcher::Get()->Init();
if ((flags & BfpSystemInitFlag_SilentCrash) != 0)
CrashCatcher::Get()->SetCrashReportKind(BfpCrashReportKind_None);
}
}
BFP_EXPORT void BFP_CALLTYPE BfpSystem_InitCrashCatcher(BfpSystemInitFlags flags)
{
CrashCatcher::Get()->Init();
if ((flags & BfpSystemInitFlag_SilentCrash) != 0)
CrashCatcher::Get()->SetCrashReportKind(BfpCrashReportKind_None);
gCrashErrorFunc = Crash_Error_CrashHandler;
}
BFP_EXPORT void BFP_CALLTYPE BfpSystem_SetCommandLine(int argc, char** argv)
{
// This isn't required on Windows, but it is on Linux
@ -993,7 +1027,10 @@ BFP_EXPORT void BFP_CALLTYPE BfpSystem_Shutdown()
delete gManagerTail;
gManagerTail = next;
}
}
BFP_EXPORT void BFP_CALLTYPE BfpSystem_ShutdownCrashCatcher()
{
if (CrashCatcher::Shutdown())
{
_set_purecall_handler(nullptr);
@ -1092,9 +1129,17 @@ BFP_EXPORT uint64 BFP_CALLTYPE BfpSystem_InterlockedCompareExchange64(uint64* pt
BFP_EXPORT void BFP_CALLTYPE BfpSystem_FatalError(const char* error, const char* title)
{
if (title != NULL)
CrashCatcher::Get()->Crash(String(title) + "\n" + String(error));
else
CrashCatcher::Get()->Crash(error);
{
int errorLen = (int)strlen(error);
int titleLen = (int)strlen(title);
char* str = new char[errorLen + 1 + titleLen + 1];
strcpy(str, title);
strcat(str, "\n");
strcat(str, error);
gCrashErrorFunc(str);
}
else
gCrashErrorFunc(error);
}
BFP_EXPORT void BFP_CALLTYPE BfpSystem_GetCommandLine(char* outStr, int* inOutStrSize, BfpSystemResult* outResult)
@ -2245,9 +2290,12 @@ static LOCATEXSTATEFEATURE pfnLocateXStateFeature = NULL;
typedef BOOL(WINAPI* SETXSTATEFEATURESMASK)(PCONTEXT Context, DWORD64 FeatureMask);
static SETXSTATEFEATURESMASK pfnSetXStateFeaturesMask = NULL;
static uint8 ContextBuffer[4096];
static uint8* ContextBuffer;
static CONTEXT* CaptureRegistersEx(HANDLE hThread, intptr*& curPtr)
{
if (ContextBuffer == NULL)
ContextBuffer = new uint8[4096];
PCONTEXT Context;
DWORD ContextSize;
DWORD64 FeatureMask;

View file

@ -194,7 +194,7 @@ public:
this->mPtr = sv.mPtr + offset;
this->mLength = length;
}
StringView(const StringImpl& str);
StringView(const StringImpl& str, int offset);
StringView(const StringImpl& str, int offset, int length);
@ -211,7 +211,7 @@ public:
this->mPtr = ptr;
this->mLength = length;
}
const char& operator[](intptr idx) const
{
BF_ASSERT((uintptr)idx < (uintptr)this->mLength);
@ -328,9 +328,9 @@ public:
bool Contains(const StringView& str) const
{
return IndexOf(str) != -1;
}
}
StringSplitEnumerator Split(char c);
StringSplitEnumerator Split(char c);
const_iterator begin() const
{
@ -340,7 +340,7 @@ public:
const_iterator end() const
{
return mPtr + this->mLength;
}
}
};
struct StringSplitEnumerator
@ -510,7 +510,7 @@ public:
{
StringSplitEnumerator endVal = *this;
endVal.mPos = endVal.mStrLen + 1;
endVal.mMatchPos = endVal.mStrLen;
endVal.mMatchPos = endVal.mStrLen;
return endVal;
}
};
@ -543,7 +543,7 @@ public:
char* mPtr;
public:
protected:
void EnsureMutable()
@ -568,14 +568,14 @@ protected:
free(this->mPtr);
}
intptr CalcNewSize(intptr minSize);
intptr CalcNewSize(intptr minSize);
void Realloc(intptr newSize, bool copyStr = true);
void Realloc(char* newPtr, intptr newSize);
static bool EqualsHelper(const char* a, const char* b, intptr length);
static bool EqualsIgnoreCaseHelper(const char* a, const char* b, intptr length);
void Realloc(char* newPtr, intptr newSize);
static bool EqualsHelper(const char* a, const char* b, intptr length);
static bool EqualsIgnoreCaseHelper(const char* a, const char* b, intptr length);
static int CompareOrdinalIgnoreCaseHelper(const StringImpl& strA, const StringImpl& strB);
static intptr CompareOrdinalIgnoreCaseHelper(const char* strA, intptr lengthA, const char* strB, intptr lengthB);
static intptr CompareOrdinalIgnoreCaseHelper(const StringImpl& strA, intptr indexA, intptr lengthA, const StringImpl& strB, intptr indexB, intptr lengthB);
static intptr CompareOrdinalIgnoreCaseHelper(const StringImpl& strA, intptr indexA, intptr lengthA, const StringImpl& strB, intptr indexB, intptr lengthB);
static intptr CompareOrdinalHelper(const char* strA, intptr lengthA, const char* strB, intptr lengthB);
static intptr CompareOrdinalHelper(const StringImpl& strA, intptr indexA, intptr lengthA, const StringImpl& strB, intptr indexB, intptr lengthB);
@ -613,7 +613,7 @@ protected:
}
public:
public:
static StringImpl MakeRef(const char* charPtr)
{
StringImpl str;
@ -710,7 +710,7 @@ public:
this->mLength = count;
}
}
~StringImpl()
{
if (IsDynAlloc())
@ -783,11 +783,11 @@ public:
bool operator>(const StringImpl& strB) const
{
return strcmp(GetPtr(), strB.GetPtr()) > 0;
}
}
StringImpl& operator=(const StringImpl& str)
{
if (&str != this)
if (&str != this)
{
this->mLength = 0;
Append(str.GetPtr(), str.mLength);
@ -812,14 +812,14 @@ public:
{
// If there's an internal buffer then we have to copy
int_strsize count = (int_strsize)str.mLength;
int_strsize allocSize = count + 1;
int_strsize allocSize = count + 1;
if (allocSize > GetAllocSize())
Realloc(allocSize, false);
auto ptr = GetMutablePtr();
memcpy(ptr, str.GetPtr(), count + 1);
ptr[count] = 0;
ptr[count] = 0;
this->mLength = count;
}
}
return *this;
}
@ -924,12 +924,12 @@ public:
void Reserve(intptr newSize);
void Append(const char* appendPtr);
void Append(const char* appendPtr, intptr length);
void Append(const StringView& str);
void Append(const char* appendPtr, intptr length);
void Append(const StringView& str);
void Append(const StringImpl& str);
void Append(const StringImpl& str, const StringImpl& str2);
void Append(const StringImpl& str, const StringImpl& str2, const StringImpl& str3);
void Append(char c, int count = 1);
void Append(char c, int count = 1);
void Release()
{
@ -937,7 +937,7 @@ public:
DeletePtr();
this->mLength = 0;
this->mPtr = NULL;
this->mAllocSizeAndFlags = 0;
this->mAllocSizeAndFlags = 0;
}
void Clear()
@ -955,10 +955,10 @@ public:
String Substring(intptr startIdx) const;
String Substring(intptr startIdx, intptr length) const;
void Remove(intptr startIdx, intptr length);
void Remove(intptr char8Idx);
void RemoveToEnd(intptr startIdx);
void RemoveFromEnd(intptr length);
void Remove(intptr startIdx, intptr length);
void Remove(intptr char8Idx);
void RemoveToEnd(intptr startIdx);
void RemoveFromEnd(intptr length);
void Insert(intptr idx, const StringImpl& addString);
void Insert(intptr idx, const char* str, intptr len);
void Insert(intptr idx, char c);
@ -971,14 +971,14 @@ public:
}
static intptr Compare(const StringImpl& strA, const StringImpl& strB, bool ignoreCase)
{
{
if (ignoreCase)
return CompareOrdinalIgnoreCaseHelper(strA.GetPtr(), strA.GetLength(), strB.GetPtr(), strB.GetLength());
return CompareOrdinalHelper(strA.GetPtr(), strA.GetLength(), strB.GetPtr(), strB.GetLength());
}
static intptr Compare(const StringImpl& strA, intptr indexA, const StringImpl& strB, intptr indexB, intptr length, bool ignoreCase);
bool Equals(const StringImpl& b, CompareKind comparisonType = CompareKind_Ordinal) const
{
return Equals(*this, b, comparisonType);
@ -1021,16 +1021,16 @@ public:
bool EndsWith(char c) const
{
if (this->mLength == 0)
return false;
return false;
return GetPtr()[this->mLength - 1] == c;
}
void ReplaceLargerHelper(const StringView& find, const StringView& replace);
void Replace(char find, char replace);
void Replace(const StringView& find, const StringView& replace);
void TrimEnd();
void TrimStart();
void Trim();
void TrimEnd();
void TrimStart();
void Trim();
bool IsWhitespace() const;
bool IsEmpty() const
{
@ -1045,12 +1045,12 @@ public:
bool HasMultibyteChars();
intptr IndexOf(const StringView& subStr, bool ignoreCase = false) const;
intptr IndexOf(const StringView& subStr, int32 startIdx) const;
intptr IndexOf(const StringView& subStr, int64 startIdx) const;
intptr IndexOf(char c, int32 startIdx = 0) const;
intptr IndexOf(const StringView& subStr, int64 startIdx) const;
intptr IndexOf(char c, int32 startIdx = 0) const;
intptr IndexOf(char c, int64 startIdx) const;
intptr LastIndexOf(char c) const;
intptr LastIndexOf(char c) const;
intptr LastIndexOf(char c, intptr startCheck) const;
StringSplitEnumerator Split(char c)
{
return StringSplitEnumerator(GetPtr(), mLength, c, 0x7FFFFFFF, false);
@ -1060,7 +1060,7 @@ public:
{
return IndexOf(c) != -1;
}
bool Contains(const StringView& str) const
{
return IndexOf(str) != -1;
@ -1217,6 +1217,41 @@ public:
}
};
class StringSimple : public StringView
{
public:
StringSimple()
{
}
StringSimple(const StringView& sv)
{
this->mPtr = new char[sv.mLength + 1];
this->mLength = sv.mLength;
memcpy((char*)this->mPtr, sv.mPtr, this->mLength);
((char*)this->mPtr)[this->mLength] = 0;
}
StringSimple(const StringImpl& str)
{
this->mPtr = new char[str.mLength + 1];
this->mLength = str.mLength;
memcpy((char*)this->mPtr, str.GetPtr(), this->mLength);
((char*)mPtr)[this->mLength] = 0;
}
~StringSimple()
{
delete this->mPtr;
}
const char* c_str()
{
return this->mPtr;
}
};
class UTF16String : public Array<uint16>
{
public:
@ -1227,7 +1262,7 @@ public:
void Set(const wchar_t* str, int len);
void Set(const wchar_t* str);
const wchar_t* c_str() const;
size_t length() const;
size_t length() const;
};
#define BF_SPECIALIZE_STR(size) \