mirror of
https://github.com/beefytech/Beef.git
synced 2025-06-08 19:48:20 +02:00
Extensive runtime refactor to reduce generated executable sizes
This commit is contained in:
parent
4e750a7e1a
commit
ddd9b1b218
74 changed files with 2514 additions and 717 deletions
|
@ -15,12 +15,8 @@ namespace FMOD
|
||||||
*/
|
*/
|
||||||
public class VERSION
|
public class VERSION
|
||||||
{
|
{
|
||||||
public const int32 number = 0x00010803;
|
public const int32 number = 0x00020220;
|
||||||
#if BF_64_BIT
|
public const String dll = "fmod.dll";
|
||||||
public const String dll = "fmod64.dll";
|
|
||||||
#else
|
|
||||||
public const String dll = "fmod.dll";
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public class CONSTANTS
|
public class CONSTANTS
|
||||||
|
@ -1385,7 +1381,7 @@ namespace FMOD
|
||||||
public int fileuserdata; /* [w] Optional. Specify 0 to ignore. User data to be passed into the file callbacks. */
|
public int fileuserdata; /* [w] Optional. Specify 0 to ignore. User data to be passed into the file callbacks. */
|
||||||
public int32 filebuffersize; /* [w] Optional. Specify 0 to ignore. Buffer size for reading the file, -1 to disable buffering, or 0 for system default. */
|
public int32 filebuffersize; /* [w] Optional. Specify 0 to ignore. Buffer size for reading the file, -1 to disable buffering, or 0 for system default. */
|
||||||
public CHANNELORDER channelorder; /* [w] Optional. Specify 0 to ignore. Use this to differ the way fmod maps multichannel sounds to speakers. See FMOD_CHANNELORDER for more. */
|
public CHANNELORDER channelorder; /* [w] Optional. Specify 0 to ignore. Use this to differ the way fmod maps multichannel sounds to speakers. See FMOD_CHANNELORDER for more. */
|
||||||
public CHANNELMASK channelmask; /* [w] Optional. Specify 0 to ignore. Use this to differ the way fmod maps multichannel sounds to speakers. See FMOD_CHANNELMASK for more. */
|
//public CHANNELMASK channelmask; /* [w] Optional. Specify 0 to ignore. Use this to differ the way fmod maps multichannel sounds to speakers. See FMOD_CHANNELMASK for more. */
|
||||||
public int initialsoundgroup; /* [w] Optional. Specify 0 to ignore. Specify a sound group if required, to put sound in as it is created. */
|
public int initialsoundgroup; /* [w] Optional. Specify 0 to ignore. Specify a sound group if required, to put sound in as it is created. */
|
||||||
public uint32 initialseekposition; /* [w] Optional. Specify 0 to ignore. For streams. Specify an initial position to seek the stream to. */
|
public uint32 initialseekposition; /* [w] Optional. Specify 0 to ignore. For streams. Specify an initial position to seek the stream to. */
|
||||||
public TIMEUNIT initialseekpostype; /* [w] Optional. Specify 0 to ignore. For streams. Specify the time unit for the position set in initialseekposition. */
|
public TIMEUNIT initialseekpostype; /* [w] Optional. Specify 0 to ignore. For streams. Specify the time unit for the position set in initialseekposition. */
|
||||||
|
@ -1587,7 +1583,7 @@ namespace FMOD
|
||||||
RESULT result = RESULT.OK;
|
RESULT result = RESULT.OK;
|
||||||
int rawPtr = 0;
|
int rawPtr = 0;
|
||||||
|
|
||||||
result = FMOD_System_Create(out rawPtr);
|
result = FMOD_System_Create(out rawPtr, VERSION.number);
|
||||||
if (result != RESULT.OK)
|
if (result != RESULT.OK)
|
||||||
{
|
{
|
||||||
return result;
|
return result;
|
||||||
|
@ -1602,7 +1598,7 @@ namespace FMOD
|
||||||
#region importfunctions
|
#region importfunctions
|
||||||
|
|
||||||
[Import(VERSION.dll), CLink, CallingConvention(.Stdcall)]
|
[Import(VERSION.dll), CLink, CallingConvention(.Stdcall)]
|
||||||
private static extern RESULT FMOD_System_Create (out int system);
|
private static extern RESULT FMOD_System_Create (out int system, uint headerversion);
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
|
@ -2008,6 +2004,7 @@ namespace FMOD
|
||||||
stringData = name.CStr();
|
stringData = name.CStr();
|
||||||
|
|
||||||
exinfo.cbsize = (int32)sizeof(CREATESOUNDEXINFO);
|
exinfo.cbsize = (int32)sizeof(CREATESOUNDEXINFO);
|
||||||
|
//int offset = offsetof(CREATESOUNDEXINFO, channelmask);
|
||||||
|
|
||||||
int soundraw;
|
int soundraw;
|
||||||
RESULT result = FMOD_System_CreateSound(rawPtr, stringData, mode, ref exinfo, out soundraw);
|
RESULT result = FMOD_System_CreateSound(rawPtr, stringData, mode, ref exinfo, out soundraw);
|
||||||
|
|
|
@ -172,6 +172,12 @@ namespace System
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[AttributeUsage(.MemberAccess)]
|
||||||
|
public struct NoStaticCtorAttribute : Attribute
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
[AttributeUsage(.Block)]
|
[AttributeUsage(.Block)]
|
||||||
public struct ConstSkipAttribute : Attribute
|
public struct ConstSkipAttribute : Attribute
|
||||||
|
|
|
@ -13,8 +13,38 @@ namespace System
|
||||||
CtrlBreak
|
CtrlBreak
|
||||||
}
|
}
|
||||||
|
|
||||||
static Encoding InputEncoding = Encoding.ASCII;
|
public struct CancelInfo
|
||||||
static Encoding OutputEncoding = Encoding.ASCII;
|
{
|
||||||
|
public static Event<delegate void (CancelKind cancelKind, ref bool terminate)> sOnCancel ~ _.Dispose();
|
||||||
|
public static bool sCancelEventRegistered;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Encoding sInputEncoding;
|
||||||
|
static Encoding sOutputEncoding;
|
||||||
|
|
||||||
|
static Encoding InputEncoding
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return sInputEncoding ?? Encoding.ASCII;
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
sInputEncoding = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
static Encoding OutputEncoding
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return sOutputEncoding ?? Encoding.ASCII;
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
SetupOutStringEx();
|
||||||
|
sOutputEncoding = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static ConsoleColor sForegroundColor = .White;
|
static ConsoleColor sForegroundColor = .White;
|
||||||
static ConsoleColor sBackgroundColor = .Black;
|
static ConsoleColor sBackgroundColor = .Black;
|
||||||
|
@ -22,9 +52,6 @@ namespace System
|
||||||
static readonly ConsoleColor sOriginalForegroundColor = sForegroundColor;
|
static readonly ConsoleColor sOriginalForegroundColor = sForegroundColor;
|
||||||
static readonly ConsoleColor sOriginalBackgroundColor = sBackgroundColor;
|
static readonly ConsoleColor sOriginalBackgroundColor = sBackgroundColor;
|
||||||
|
|
||||||
static Event<delegate void (CancelKind cancelKind, ref bool terminate)> sOnCancel ~ _.Dispose();
|
|
||||||
static bool sCancelEventRegistered;
|
|
||||||
|
|
||||||
public static ConsoleColor ForegroundColor
|
public static ConsoleColor ForegroundColor
|
||||||
{
|
{
|
||||||
get { return sForegroundColor; }
|
get { return sForegroundColor; }
|
||||||
|
@ -56,18 +83,39 @@ namespace System
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void SetupOutStringEx()
|
||||||
|
{
|
||||||
|
OutString = => OutString_Ex;
|
||||||
|
}
|
||||||
|
|
||||||
|
static function void(StringView str) OutString = => OutString_Simple;
|
||||||
|
|
||||||
|
[CLink, CallingConvention(.Cdecl)]
|
||||||
|
static extern void putchar(char8 c);
|
||||||
|
|
||||||
|
static void OutString_Simple(StringView str)
|
||||||
|
{
|
||||||
|
for (var c in str.RawChars)
|
||||||
|
putchar(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void OutString_Ex(StringView str)
|
||||||
|
{
|
||||||
|
Out.Write(str).IgnoreError();
|
||||||
|
}
|
||||||
|
|
||||||
public static ref Event<delegate void (CancelKind cancelKind, ref bool terminate)> OnCancel
|
public static ref Event<delegate void (CancelKind cancelKind, ref bool terminate)> OnCancel
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
if (!sCancelEventRegistered)
|
if (!CancelInfo.sCancelEventRegistered)
|
||||||
{
|
{
|
||||||
sCancelEventRegistered = true;
|
CancelInfo.sCancelEventRegistered = true;
|
||||||
#if BF_PLATFORM_WINDOWS
|
#if BF_PLATFORM_WINDOWS
|
||||||
SetConsoleCtrlHandler(=> ConsoleCtrlHandler, true);
|
SetConsoleCtrlHandler(=> ConsoleCtrlHandler, true);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
return ref sOnCancel;
|
return ref CancelInfo.sOnCancel;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -77,7 +125,7 @@ namespace System
|
||||||
{
|
{
|
||||||
bool terminate = true;
|
bool terminate = true;
|
||||||
if ((ctrlType == 0) || (ctrlType == 1))
|
if ((ctrlType == 0) || (ctrlType == 1))
|
||||||
sOnCancel((.)ctrlType, ref terminate);
|
CancelInfo.sOnCancel((.)ctrlType, ref terminate);
|
||||||
return terminate ? false : true;
|
return terminate ? false : true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -286,7 +334,7 @@ namespace System
|
||||||
|
|
||||||
public static void Write(StringView line)
|
public static void Write(StringView line)
|
||||||
{
|
{
|
||||||
Out.Write(line).IgnoreError();
|
OutString(line);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void Write(StringView fmt, params Object[] args)
|
public static void Write(StringView fmt, params Object[] args)
|
||||||
|
@ -308,12 +356,13 @@ namespace System
|
||||||
|
|
||||||
public static void WriteLine()
|
public static void WriteLine()
|
||||||
{
|
{
|
||||||
Out.Write("\n").IgnoreError();
|
OutString("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void WriteLine(StringView line)
|
public static void WriteLine(StringView line)
|
||||||
{
|
{
|
||||||
Out.WriteLine(line).IgnoreError();
|
OutString(line);
|
||||||
|
OutString("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void WriteLine(StringView fmt, params Object[] args)
|
public static void WriteLine(StringView fmt, params Object[] args)
|
||||||
|
|
|
@ -14,7 +14,14 @@ namespace System.Diagnostics.Contracts
|
||||||
Assume,
|
Assume,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if !BF_RUNTIME_DISABLE
|
||||||
static extern void ReportFailure(ContractFailureKind failureKind, char8* userMessage, int32 userMessageLen, char8* conditionText, int32 conditionTextLen);
|
static extern void ReportFailure(ContractFailureKind failureKind, char8* userMessage, int32 userMessageLen, char8* conditionText, int32 conditionTextLen);
|
||||||
|
#else
|
||||||
|
static void ReportFailure(ContractFailureKind failureKind, char8* userMessage, int32 userMessageLen, char8* conditionText, int32 conditionTextLen)
|
||||||
|
{
|
||||||
|
Internal.FatalError("Contract.ReportFailure");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// This method is used internally to trigger a failure indicating to the "programmer" that he is using the interface incorrectly.
|
/// This method is used internally to trigger a failure indicating to the "programmer" that he is using the interface incorrectly.
|
||||||
|
|
|
@ -9,10 +9,16 @@ namespace System.Diagnostics
|
||||||
{
|
{
|
||||||
if (!condition)
|
if (!condition)
|
||||||
{
|
{
|
||||||
if (Runtime.CheckErrorHandlers(scope Runtime.AssertError(.Debug, error, filePath, line)) == .Ignore)
|
if ((Runtime.CheckAssertError != null) && (Runtime.CheckAssertError(.Debug, error, filePath, line) == .Ignore))
|
||||||
return;
|
return;
|
||||||
String failStr = scope .()..AppendF("Assert failed: {} at line {} in {}", error, line, filePath);
|
#if !BF_RUNTIME_REDUCED
|
||||||
|
String failStr = scope .()..Append("Assert failed: ", error, " at line ");
|
||||||
|
line.ToString(failStr);
|
||||||
|
failStr.Append(" in ", filePath);
|
||||||
Internal.FatalError(failStr, 1);
|
Internal.FatalError(failStr, 1);
|
||||||
|
#else
|
||||||
|
Internal.FatalError("Assert failed", 1);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -21,7 +27,9 @@ namespace System.Diagnostics
|
||||||
#endif
|
#endif
|
||||||
public static void FatalError(String msg = "Fatal error encountered", String filePath = Compiler.CallerFilePath, int line = Compiler.CallerLineNum)
|
public static void FatalError(String msg = "Fatal error encountered", String filePath = Compiler.CallerFilePath, int line = Compiler.CallerLineNum)
|
||||||
{
|
{
|
||||||
String failStr = scope .()..AppendF("{} at line {} in {}", msg, line, filePath);
|
String failStr = scope .()..Append(msg, " at line ");
|
||||||
|
line.ToString(failStr);
|
||||||
|
failStr.Append(" in ", filePath);
|
||||||
Internal.FatalError(failStr, 1);
|
Internal.FatalError(failStr, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -87,7 +95,7 @@ namespace System.Diagnostics
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool gIsDebuggerPresent = IsDebuggerPresent;
|
static bool gIsDebuggerPresent = IsDebuggerPresent;
|
||||||
[LinkName("IsDebuggerPresent"), CallingConvention(.Stdcall)]
|
[LinkName("IsDebuggerPresent"), CallingConvention(.Stdcall), Import("kernel32.lib")]
|
||||||
static extern int32 Internal_IsDebuggerPresent();
|
static extern int32 Internal_IsDebuggerPresent();
|
||||||
|
|
||||||
public static bool IsDebuggerPresent
|
public static bool IsDebuggerPresent
|
||||||
|
|
|
@ -199,7 +199,11 @@ namespace System
|
||||||
[CallingConvention(.Stdcall), CLink]
|
[CallingConvention(.Stdcall), CLink]
|
||||||
static extern int32 ftoa(float val, char8* str);
|
static extern int32 ftoa(float val, char8* str);
|
||||||
|
|
||||||
|
#if !BF_RUNTIME_DISABLE
|
||||||
static extern int32 ToString(double val, char8* str, bool roundTrip);
|
static extern int32 ToString(double val, char8* str, bool roundTrip);
|
||||||
|
#else
|
||||||
|
static int32 ToString(double val, char8* str, bool roundTrip) => Runtime.NotImplemented();
|
||||||
|
#endif
|
||||||
|
|
||||||
public override void ToString(String strBuffer)
|
public override void ToString(String strBuffer)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Collections;
|
using System.Collections;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
using System.Threading;
|
||||||
|
|
||||||
namespace System
|
namespace System
|
||||||
{
|
{
|
||||||
|
@ -12,7 +13,23 @@ namespace System
|
||||||
public static readonly String NewLine = "\n";
|
public static readonly String NewLine = "\n";
|
||||||
#endif // BF_PLATFORM_WINDOWS
|
#endif // BF_PLATFORM_WINDOWS
|
||||||
|
|
||||||
public static OperatingSystem OSVersion = new OperatingSystem() ~ delete _;
|
|
||||||
|
static OperatingSystem sOSVersion ~ delete _;
|
||||||
|
public static OperatingSystem OSVersion
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
var osVersion = new OperatingSystem();
|
||||||
|
let prevValue = Interlocked.CompareExchange(ref sOSVersion, null, osVersion);
|
||||||
|
if (prevValue != null)
|
||||||
|
{
|
||||||
|
// This was already set - race condition
|
||||||
|
delete osVersion;
|
||||||
|
return prevValue;
|
||||||
|
}
|
||||||
|
return osVersion;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static void* ModuleHandle => Internal.[Friend]sModuleHandle;
|
public static void* ModuleHandle => Internal.[Friend]sModuleHandle;
|
||||||
|
|
||||||
|
|
|
@ -147,7 +147,11 @@ namespace System
|
||||||
[CallingConvention(.Stdcall), CLink]
|
[CallingConvention(.Stdcall), CLink]
|
||||||
static extern int32 ftoa(float val, char8* str);
|
static extern int32 ftoa(float val, char8* str);
|
||||||
|
|
||||||
|
#if !BF_RUNTIME_DISABLE
|
||||||
static extern int32 ToString(float val, char8* str, bool roundTrip);
|
static extern int32 ToString(float val, char8* str, bool roundTrip);
|
||||||
|
#else
|
||||||
|
static int32 ToString(float val, char8* str, bool roundTrip) => Runtime.FatalError();
|
||||||
|
#endif
|
||||||
|
|
||||||
public override void ToString(String strBuffer)
|
public override void ToString(String strBuffer)
|
||||||
{
|
{
|
||||||
|
|
|
@ -91,7 +91,7 @@ namespace System
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#if BF_ENABLE_REALTIME_LEAK_CHECK || BF_DEBUG_ALLOC
|
#if (BF_ENABLE_REALTIME_LEAK_CHECK || BF_DEBUG_ALLOC) && !BF_RUNTIME_DISABLE
|
||||||
[CallingConvention(.Cdecl)]
|
[CallingConvention(.Cdecl)]
|
||||||
public extern static void Report();
|
public extern static void Report();
|
||||||
[CallingConvention(.Cdecl)]
|
[CallingConvention(.Cdecl)]
|
||||||
|
|
|
@ -13,6 +13,14 @@ namespace System
|
||||||
case InvalidChar(int partialResult);
|
case InvalidChar(int partialResult);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public struct Simple : int
|
||||||
|
{
|
||||||
|
public override void ToString(String strBuffer)
|
||||||
|
{
|
||||||
|
((int)this).ToString(strBuffer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public const int MaxValue = (sizeof(int) == 8) ? 0x7FFFFFFFFFFFFFFFL : 0x7FFFFFFF;
|
public const int MaxValue = (sizeof(int) == 8) ? 0x7FFFFFFFFFFFFFFFL : 0x7FFFFFFF;
|
||||||
public const int MinValue = (sizeof(int) == 8) ? -0x8000000000000000L : -0x80000000;
|
public const int MinValue = (sizeof(int) == 8) ? -0x8000000000000000L : -0x80000000;
|
||||||
|
|
||||||
|
|
|
@ -63,11 +63,6 @@ namespace System
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//static char8[] sHexUpperChars = new char8[]{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'} ~ delete _;
|
|
||||||
//static char8[] sHexLowerChars = new char8[]{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'} ~ delete _;
|
|
||||||
|
|
||||||
static String sHexUpperChars = "0123456789ABCDEF";
|
|
||||||
static String sHexLowerChars = "0123456789abcdef";
|
|
||||||
public void ToString(String outString, String format, IFormatProvider formatProvider)
|
public void ToString(String outString, String format, IFormatProvider formatProvider)
|
||||||
{
|
{
|
||||||
if(format == null || format.IsEmpty)
|
if(format == null || format.IsEmpty)
|
||||||
|
|
|
@ -81,12 +81,6 @@ namespace System
|
||||||
public static extern Object UnsafeCastToObject(void* ptr);
|
public static extern Object UnsafeCastToObject(void* ptr);
|
||||||
[Intrinsic("cast")]
|
[Intrinsic("cast")]
|
||||||
public static extern void* UnsafeCastToPtr(Object obj);
|
public static extern void* UnsafeCastToPtr(Object obj);
|
||||||
[CallingConvention(.Cdecl), NoReturn]
|
|
||||||
public static extern void ThrowIndexOutOfRange(int stackOffset = 0);
|
|
||||||
[CallingConvention(.Cdecl), NoReturn]
|
|
||||||
public static extern void ThrowObjectNotInitialized(int stackOffset = 0);
|
|
||||||
[CallingConvention(.Cdecl), NoReturn]
|
|
||||||
public static extern void FatalError(String error, int stackOffset = 0);
|
|
||||||
[Intrinsic("memcpy")]
|
[Intrinsic("memcpy")]
|
||||||
public static extern void MemCpy(void* dest, void* src, int length, int32 align = 1, bool isVolatile = false);
|
public static extern void MemCpy(void* dest, void* src, int length, int32 align = 1, bool isVolatile = false);
|
||||||
[Intrinsic("memmove")]
|
[Intrinsic("memmove")]
|
||||||
|
@ -103,6 +97,32 @@ namespace System
|
||||||
public static extern void StdFree(void* ptr);
|
public static extern void StdFree(void* ptr);
|
||||||
[Intrinsic("returnaddress")]
|
[Intrinsic("returnaddress")]
|
||||||
public static extern void* GetReturnAddress(int32 level = 0);
|
public static extern void* GetReturnAddress(int32 level = 0);
|
||||||
|
|
||||||
|
[CallingConvention(.Cdecl)]
|
||||||
|
static extern void Test_Init(char8* testData);
|
||||||
|
[CallingConvention(.Cdecl)]
|
||||||
|
static extern void Test_Error(char8* error);
|
||||||
|
[CallingConvention(.Cdecl)]
|
||||||
|
static extern void Test_Write(char8* str);
|
||||||
|
[CallingConvention(.Cdecl)]
|
||||||
|
static extern int32 Test_Query();
|
||||||
|
[CallingConvention(.Cdecl)]
|
||||||
|
static extern void Test_Finish();
|
||||||
|
|
||||||
|
static void* sModuleHandle;
|
||||||
|
[AlwaysInclude]
|
||||||
|
static void SetModuleHandle(void* handle)
|
||||||
|
{
|
||||||
|
sModuleHandle = handle;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if !BF_RUNTIME_DISABLE
|
||||||
|
[CallingConvention(.Cdecl), NoReturn]
|
||||||
|
public static extern void ThrowIndexOutOfRange(int stackOffset = 0);
|
||||||
|
[CallingConvention(.Cdecl), NoReturn]
|
||||||
|
public static extern void ThrowObjectNotInitialized(int stackOffset = 0);
|
||||||
|
[CallingConvention(.Cdecl), NoReturn]
|
||||||
|
public static extern void FatalError(String error, int stackOffset = 0);
|
||||||
[CallingConvention(.Cdecl)]
|
[CallingConvention(.Cdecl)]
|
||||||
public static extern void* VirtualAlloc(int size, bool canExecute, bool canWrite);
|
public static extern void* VirtualAlloc(int size, bool canExecute, bool canWrite);
|
||||||
[CallingConvention(.Cdecl)]
|
[CallingConvention(.Cdecl)]
|
||||||
|
@ -160,25 +180,236 @@ namespace System
|
||||||
[CallingConvention(.Cdecl)]
|
[CallingConvention(.Cdecl)]
|
||||||
public static extern void Dbg_RawFree(void* ptr);
|
public static extern void Dbg_RawFree(void* ptr);
|
||||||
|
|
||||||
[CallingConvention(.Cdecl), AlwaysInclude]
|
|
||||||
static extern void Shutdown();
|
|
||||||
[CallingConvention(.Cdecl)]
|
[CallingConvention(.Cdecl)]
|
||||||
static extern void Test_Init(char8* testData);
|
static extern void Shutdown_Internal();
|
||||||
[CallingConvention(.Cdecl)]
|
|
||||||
static extern void Test_Error(char8* error);
|
|
||||||
[CallingConvention(.Cdecl)]
|
|
||||||
static extern void Test_Write(char8* str);
|
|
||||||
[CallingConvention(.Cdecl)]
|
|
||||||
static extern int32 Test_Query();
|
|
||||||
[CallingConvention(.Cdecl)]
|
|
||||||
static extern void Test_Finish();
|
|
||||||
|
|
||||||
static void* sModuleHandle;
|
[CallingConvention(.Cdecl), AlwaysInclude]
|
||||||
[AlwaysInclude]
|
static void Shutdown()
|
||||||
static void SetModuleHandle(void* handle)
|
|
||||||
{
|
{
|
||||||
sModuleHandle = handle;
|
Shutdown_Internal();
|
||||||
|
Runtime.Shutdown();
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
|
||||||
|
enum BfObjectFlags : uint8
|
||||||
|
{
|
||||||
|
None = 0,
|
||||||
|
Mark1 = 0x01,
|
||||||
|
Mark2 = 0x02,
|
||||||
|
Mark3 = 0x03,
|
||||||
|
Allocated = 0x04,
|
||||||
|
StackAlloc = 0x08,
|
||||||
|
AppendAlloc = 0x10,
|
||||||
|
AllocInfo = 0x20,
|
||||||
|
AllocInfo_Short = 0x40,
|
||||||
|
Deleted = 0x80
|
||||||
|
};
|
||||||
|
|
||||||
|
[NoReturn]
|
||||||
|
static void Crash()
|
||||||
|
{
|
||||||
|
char8* ptr = null;
|
||||||
|
*ptr = 'A';
|
||||||
|
}
|
||||||
|
|
||||||
|
[AlwaysInclude, NoReturn]
|
||||||
|
public static void ThrowIndexOutOfRange(int stackOffset = 0)
|
||||||
|
{
|
||||||
|
Crash();
|
||||||
|
}
|
||||||
|
|
||||||
|
[AlwaysInclude, NoReturn]
|
||||||
|
public static void ThrowObjectNotInitialized(int stackOffset = 0)
|
||||||
|
{
|
||||||
|
Crash();
|
||||||
|
}
|
||||||
|
|
||||||
|
[AlwaysInclude, NoReturn]
|
||||||
|
public static void FatalError(String error, int stackOffset = 0)
|
||||||
|
{
|
||||||
|
Crash();
|
||||||
|
}
|
||||||
|
|
||||||
|
[AlwaysInclude]
|
||||||
|
public static void* VirtualAlloc(int size, bool canExecute, bool canWrite)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int32 CStrLen(char8* charPtr)
|
||||||
|
{
|
||||||
|
int32 len = 0;
|
||||||
|
while (charPtr[len] != 0)
|
||||||
|
len++;
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int64 GetTickCountMicro()
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
[AlwaysInclude]
|
||||||
|
public static void BfDelegateTargetCheck(void* target)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
[AlwaysInclude]
|
||||||
|
public static void* LoadSharedLibrary(char8* filePath)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
[AlwaysInclude]
|
||||||
|
public static void LoadSharedLibraryInto(char8* filePath, void** libDest)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
[AlwaysInclude]
|
||||||
|
public static void* GetSharedProcAddress(void* libHandle, char8* procName)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
[AlwaysInclude]
|
||||||
|
public static void GetSharedProcAddressInto(void* libHandle, char8* procName, void** procDest)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
[AlwaysInclude]
|
||||||
|
public static char8* GetCommandLineArgs()
|
||||||
|
{
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void ProfilerCmd(char8* str)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void ReportMemory()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void ObjectDynCheck(Object obj, int32 typeId, bool allowNull)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void ObjectDynCheckFailed(Object obj, int32 typeId)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
[DisableChecks, DisableObjectAccessChecks]
|
||||||
|
public static void Dbg_ObjectCreated(Object obj, int size, ClassVData* classVData)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
[DisableChecks, DisableObjectAccessChecks]
|
||||||
|
public static void Dbg_ObjectCreatedEx(Object obj, int size, ClassVData* classVData)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
[DisableChecks, DisableObjectAccessChecks]
|
||||||
|
public static void Dbg_ObjectAllocated(Object obj, int size, ClassVData* classVData)
|
||||||
|
{
|
||||||
|
#if BF_ENABLE_OBJECT_DEBUG_FLAGS
|
||||||
|
obj.[Friend]mClassVData = (.)(void*)classVData;
|
||||||
|
obj.[Friend]mDbgAllocInfo = (.)GetReturnAddress(0);
|
||||||
|
#else
|
||||||
|
obj.[Friend]mClassVData = classVData;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
[DisableChecks, DisableObjectAccessChecks]
|
||||||
|
public static void Dbg_ObjectAllocatedEx(Object obj, int size, ClassVData* classVData)
|
||||||
|
{
|
||||||
|
#if BF_ENABLE_OBJECT_DEBUG_FLAGS
|
||||||
|
obj.[Friend]mClassVData = (.)(void*)classVData;
|
||||||
|
obj.[Friend]mDbgAllocInfo = (.)GetReturnAddress(0);
|
||||||
|
#else
|
||||||
|
obj.[Friend]mClassVData = classVData;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int Dbg_PrepareStackTrace(int baseAllocSize, int maxStackTraceDepth)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
[DisableChecks, DisableObjectAccessChecks]
|
||||||
|
public static void Dbg_ObjectStackInit(Object obj, ClassVData* classVData)
|
||||||
|
{
|
||||||
|
#if BF_ENABLE_OBJECT_DEBUG_FLAGS
|
||||||
|
obj.[Friend]mClassVData = (.)(void*)classVData;
|
||||||
|
obj.[Friend]mClassVData |= (.)BfObjectFlags.StackAlloc;
|
||||||
|
obj.[Friend]mDbgAllocInfo = (.)GetReturnAddress(0);
|
||||||
|
#else
|
||||||
|
obj.[Friend]mClassVData = classVData;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Object Dbg_ObjectAlloc(TypeInstance typeInst, int size)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Object Dbg_ObjectAlloc(ClassVData* classVData, int size, int align, int maxStackTraceDepth)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void Dbg_ObjectPreDelete(Object obj)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void Dbg_ObjectPreCustomDelete(Object obj)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void Dbg_MarkObjectDeleted(Object obj)
|
||||||
|
{
|
||||||
|
#if BF_ENABLE_OBJECT_DEBUG_FLAGS
|
||||||
|
obj.[Friend]mClassVData |= (.)BfObjectFlags.Deleted;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void* Dbg_RawAlloc(int size)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void* Dbg_RawObjectAlloc(int size)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void* Dbg_RawAlloc(int size, DbgRawAllocData* rawAllocData)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void Dbg_RawFree(void* ptr)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
[AlwaysInclude]
|
||||||
|
static void Shutdown()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
[AlwaysInclude]
|
[AlwaysInclude]
|
||||||
static void AddRtFlags(int32 flags)
|
static void AddRtFlags(int32 flags)
|
||||||
{
|
{
|
||||||
|
@ -254,9 +485,9 @@ namespace System
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[AlwaysInclude]
|
|
||||||
public static String[] CreateParamsArray()
|
public static String[] CreateParamsArray()
|
||||||
{
|
{
|
||||||
|
#if !BF_RUNTIME_DISABLE
|
||||||
char8* cmdLine = GetCommandLineArgs();
|
char8* cmdLine = GetCommandLineArgs();
|
||||||
//Windows.MessageBoxA(default, scope String()..AppendF("CmdLine: {0}", StringView(cmdLine)), "HI", 0);
|
//Windows.MessageBoxA(default, scope String()..AppendF("CmdLine: {0}", StringView(cmdLine)), "HI", 0);
|
||||||
|
|
||||||
|
@ -357,9 +588,11 @@ namespace System
|
||||||
}
|
}
|
||||||
|
|
||||||
return strVals;
|
return strVals;
|
||||||
|
#else
|
||||||
|
return new String[0];
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
[AlwaysInclude]
|
|
||||||
public static void DeleteStringArray(String[] arr)
|
public static void DeleteStringArray(String[] arr)
|
||||||
{
|
{
|
||||||
for (var str in arr)
|
for (var str in arr)
|
||||||
|
@ -367,8 +600,10 @@ namespace System
|
||||||
delete arr;
|
delete arr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if !BF_RUNTIME_DISABLE
|
||||||
extern static this();
|
extern static this();
|
||||||
extern static ~this();
|
extern static ~this();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
struct CRTAlloc
|
struct CRTAlloc
|
||||||
|
|
|
@ -224,6 +224,7 @@ namespace System
|
||||||
return intPart;
|
return intPart;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if !BF_RUNTIME_DISABLE
|
||||||
public static extern float Sqrt(float f);
|
public static extern float Sqrt(float f);
|
||||||
public static extern double Sqrt(double d);
|
public static extern double Sqrt(double d);
|
||||||
public static extern float Cbrt(float f);
|
public static extern float Cbrt(float f);
|
||||||
|
@ -236,6 +237,20 @@ namespace System
|
||||||
public static extern double Exp(double d);
|
public static extern double Exp(double d);
|
||||||
public static extern float Pow(float x, float y);
|
public static extern float Pow(float x, float y);
|
||||||
public static extern double Pow(double x, double y);
|
public static extern double Pow(double x, double y);
|
||||||
|
#else
|
||||||
|
public static float Sqrt(float f) => Runtime.NotImplemented();
|
||||||
|
public static double Sqrt(double d) => Runtime.NotImplemented();
|
||||||
|
public static float Cbrt(float f) => Runtime.NotImplemented();
|
||||||
|
public static double Cbrt(double d) => Runtime.NotImplemented();
|
||||||
|
public static float Log(float f) => Runtime.NotImplemented();
|
||||||
|
public static double Log(double d) => Runtime.NotImplemented();
|
||||||
|
public static float Log10(float f) => Runtime.NotImplemented();
|
||||||
|
public static double Log10(double d) => Runtime.NotImplemented();
|
||||||
|
public static float Exp(float f) => Runtime.NotImplemented();
|
||||||
|
public static double Exp(double d) => Runtime.NotImplemented();
|
||||||
|
public static float Pow(float x, float y) => Runtime.NotImplemented();
|
||||||
|
public static double Pow(double x, double y) => Runtime.NotImplemented();
|
||||||
|
#endif
|
||||||
|
|
||||||
public static float IEEERemainder(float x, float y)
|
public static float IEEERemainder(float x, float y)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1130,12 +1130,14 @@ namespace System
|
||||||
// Hexadecimal digits representation.
|
// Hexadecimal digits representation.
|
||||||
private static uint32 FastToDecHex (int32 val)
|
private static uint32 FastToDecHex (int32 val)
|
||||||
{
|
{
|
||||||
|
var decHexDigits = DecHexDigits;
|
||||||
|
|
||||||
if (val < 100)
|
if (val < 100)
|
||||||
return (uint32)DecHexDigits [val];
|
return (uint32)decHexDigits[val];
|
||||||
|
|
||||||
// Uses 2^19 (524288) to compute val / 100 for val < 10000.
|
// Uses 2^19 (524288) to compute val / 100 for val < 10000.
|
||||||
int32 v = (val * 5243) >> 19;
|
int32 v = (val * 5243) >> 19;
|
||||||
return (uint32)((DecHexDigits [v] << 8) | DecHexDigits [val - v * 100]);
|
return (uint32)((decHexDigits[v] << 8) | decHexDigits[val - v * 100]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Helper to translate an int in the range 0 .. 99999999 to its
|
// Helper to translate an int in the range 0 .. 99999999 to its
|
||||||
|
@ -1741,6 +1743,31 @@ namespace System
|
||||||
inst.IntegerToString(format, fp, outString);
|
inst.IntegerToString(format, fp, outString);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void AddrToString (uint value, String outString)
|
||||||
|
{
|
||||||
|
const int bufLen = 18;
|
||||||
|
char8* strChars = scope:: char8[bufLen]* (?);
|
||||||
|
int32 curLen = 0;
|
||||||
|
uint64 valLeft = (.)value;
|
||||||
|
while (valLeft > 0)
|
||||||
|
{
|
||||||
|
if (curLen == 8)
|
||||||
|
strChars[bufLen - curLen++ - 1] = '\'';
|
||||||
|
strChars[bufLen - curLen++ - 1] = DigitUpperTable[(int)(valLeft & 0xF)];
|
||||||
|
valLeft >>= 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (curLen < 10)
|
||||||
|
{
|
||||||
|
if (curLen == 8)
|
||||||
|
strChars[bufLen - curLen++ - 1] = '\'';
|
||||||
|
strChars[bufLen - curLen++ - 1] = '0';
|
||||||
|
}
|
||||||
|
|
||||||
|
char8* char8Ptr = &strChars[bufLen - curLen];
|
||||||
|
outString.Append(char8Ptr, curLen);
|
||||||
|
}
|
||||||
|
|
||||||
public static void NumberToString (StringView format, int32 value, IFormatProvider fp, String outString)
|
public static void NumberToString (StringView format, int32 value, IFormatProvider fp, String outString)
|
||||||
{
|
{
|
||||||
NumberFormatter inst = GetInstance!(fp);
|
NumberFormatter inst = GetInstance!(fp);
|
||||||
|
|
|
@ -14,6 +14,7 @@ namespace System
|
||||||
ClassVData* mClassVData;
|
ClassVData* mClassVData;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
[AlwaysInclude]
|
||||||
public virtual ~this()
|
public virtual ~this()
|
||||||
{
|
{
|
||||||
#if BF_ENABLE_OBJECT_DEBUG_FLAGS
|
#if BF_ENABLE_OBJECT_DEBUG_FLAGS
|
||||||
|
@ -47,42 +48,79 @@ namespace System
|
||||||
if (Compiler.IsComptime)
|
if (Compiler.IsComptime)
|
||||||
return Comptime_GetType();
|
return Comptime_GetType();
|
||||||
|
|
||||||
Type type;
|
ClassVData* classVData;
|
||||||
#if BF_ENABLE_OBJECT_DEBUG_FLAGS
|
#if BF_ENABLE_OBJECT_DEBUG_FLAGS
|
||||||
ClassVData* maskedVData = (ClassVData*)(void*)(mClassVData & ~(int)0xFF);
|
classVData = (ClassVData*)(void*)(mClassVData & ~(int)0xFF);
|
||||||
type = maskedVData.mType;
|
|
||||||
#else
|
#else
|
||||||
type = mClassVData.mType;
|
classVData = mClassVData;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if BF_32_BIT
|
||||||
|
Type type = Type.[Friend]GetType_(classVData.mType2);
|
||||||
|
#else
|
||||||
|
Type type = Type.[Friend]GetType_((.)(classVData.mType >> 32));
|
||||||
#endif
|
#endif
|
||||||
if ((type.[Friend]mTypeFlags & TypeFlags.Boxed) != 0)
|
|
||||||
{
|
|
||||||
//int32 underlyingType = (int32)((TypeInstance)type).mUnderlyingType;
|
|
||||||
type = Type.[Friend]GetType(((TypeInstance)type).[Friend]mUnderlyingType);
|
|
||||||
}
|
|
||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TypeId GetTypeId()
|
||||||
|
{
|
||||||
|
ClassVData* classVData;
|
||||||
|
#if BF_ENABLE_OBJECT_DEBUG_FLAGS
|
||||||
|
classVData = (ClassVData*)(void*)(mClassVData & ~(int)0xFF);
|
||||||
|
#else
|
||||||
|
classVData = mClassVData;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if BF_32_BIT
|
||||||
|
return (.)classVData.mType2;
|
||||||
|
#else
|
||||||
|
return (.)(classVData.mType >> 32);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
[NoShow]
|
[NoShow]
|
||||||
Type RawGetType()
|
Type RawGetType()
|
||||||
{
|
{
|
||||||
if (Compiler.IsComptime)
|
if (Compiler.IsComptime)
|
||||||
return Comptime_GetType();
|
return Comptime_GetType();
|
||||||
|
|
||||||
Type type;
|
ClassVData* classVData;
|
||||||
#if BF_ENABLE_OBJECT_DEBUG_FLAGS
|
#if BF_ENABLE_OBJECT_DEBUG_FLAGS
|
||||||
ClassVData* maskedVData = (ClassVData*)(void*)(mClassVData & ~(int)0xFF);
|
classVData = (ClassVData*)(void*)(mClassVData & ~(int)0xFF);
|
||||||
type = maskedVData.mType;
|
|
||||||
#else
|
#else
|
||||||
type = mClassVData.mType;
|
classVData = mClassVData;
|
||||||
#endif
|
#endif
|
||||||
return type;
|
|
||||||
|
#if BF_32_BIT
|
||||||
|
Type type = Type.[Friend]GetType_(classVData.mType);
|
||||||
|
#else
|
||||||
|
Type type = Type.[Friend]GetType_((.)(classVData.mType & 0xFFFFFFFF));
|
||||||
|
#endif
|
||||||
|
return type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TypeId RawGetTypeId()
|
||||||
|
{
|
||||||
|
ClassVData* classVData;
|
||||||
|
#if BF_ENABLE_OBJECT_DEBUG_FLAGS
|
||||||
|
classVData = (ClassVData*)(void*)(mClassVData & ~(int)0xFF);
|
||||||
|
#else
|
||||||
|
classVData = mClassVData;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if BF_32_BIT
|
||||||
|
return (.)classVData.mType;
|
||||||
|
#else
|
||||||
|
return (.)(classVData.mType & 0xFFFFFFFF);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
#if BF_DYNAMIC_CAST_CHECK || BF_ENABLE_REALTIME_LEAK_CHECK
|
#if BF_DYNAMIC_CAST_CHECK || BF_ENABLE_REALTIME_LEAK_CHECK
|
||||||
[NoShow]
|
[NoShow]
|
||||||
public virtual Object DynamicCastToTypeId(int32 typeId)
|
public virtual Object DynamicCastToTypeId(int32 typeId)
|
||||||
{
|
{
|
||||||
if (typeId == (int32)RawGetType().[Friend]mTypeId)
|
if (typeId == (.)RawGetTypeId())
|
||||||
return this;
|
return this;
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -101,6 +139,10 @@ namespace System
|
||||||
|
|
||||||
public virtual void ToString(String strBuffer)
|
public virtual void ToString(String strBuffer)
|
||||||
{
|
{
|
||||||
|
#if BF_REFLECT_MINIMAL
|
||||||
|
strBuffer.AppendF($"Type#{(Int.Simple)GetTypeId()}@0x");
|
||||||
|
NumberFormatter.AddrToString((uint)Internal.UnsafeCastToPtr(this), strBuffer);
|
||||||
|
#else
|
||||||
let t = RawGetType();
|
let t = RawGetType();
|
||||||
if (t.IsBoxedStructPtr)
|
if (t.IsBoxedStructPtr)
|
||||||
{
|
{
|
||||||
|
@ -108,13 +150,15 @@ namespace System
|
||||||
let innerPtr = *(void**)((uint8*)Internal.UnsafeCastToPtr(this) + ti.[Friend]mMemberDataOffset);
|
let innerPtr = *(void**)((uint8*)Internal.UnsafeCastToPtr(this) + ti.[Friend]mMemberDataOffset);
|
||||||
strBuffer.Append("(");
|
strBuffer.Append("(");
|
||||||
ti.UnderlyingType.GetFullName(strBuffer);
|
ti.UnderlyingType.GetFullName(strBuffer);
|
||||||
strBuffer.AppendF("*)0x{0:A}", (uint)(void*)innerPtr);
|
//strBuffer.AppendF("*)0x{0:A}", (UInt.Simple)(uint)(void*)innerPtr);
|
||||||
|
strBuffer.Append("*)0x");
|
||||||
|
NumberFormatter.AddrToString((uint)(void*)innerPtr, strBuffer);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
t.GetFullName(strBuffer);
|
t.GetFullName(strBuffer);
|
||||||
strBuffer.Append("@0x");
|
strBuffer.Append("@0x");
|
||||||
|
NumberFormatter.AddrToString((uint)Internal.UnsafeCastToPtr(this), strBuffer);
|
||||||
((int)Internal.UnsafeCastToPtr(this)).ToString(strBuffer, "A", null);
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void ToString(Object obj, String strBuffer)
|
private static void ToString(Object obj, String strBuffer)
|
||||||
|
|
|
@ -78,7 +78,7 @@ namespace System
|
||||||
public uint32 dwFileDateLS; // e.g. 0
|
public uint32 dwFileDateLS; // e.g. 0
|
||||||
}
|
}
|
||||||
|
|
||||||
[CLink, CallingConvention(.Stdcall)]
|
[Import("kernel32.lib"), CLink, CallingConvention(.Stdcall)]
|
||||||
extern static bool GetVersionExA(OSVersionInfoExA* lpVersionInformation);
|
extern static bool GetVersionExA(OSVersionInfoExA* lpVersionInformation);
|
||||||
|
|
||||||
[CLink, CallingConvention(.Stdcall)]
|
[CLink, CallingConvention(.Stdcall)]
|
||||||
|
@ -274,9 +274,9 @@ namespace System
|
||||||
String arch = Arch32;
|
String arch = Arch32;
|
||||||
#endif
|
#endif
|
||||||
if (Version.Revision == 0)
|
if (Version.Revision == 0)
|
||||||
outVar.AppendF("{} (Version {}.{}, Build {}, {})", Name, Version.Major, Version.Minor, Version.Build, arch);
|
outVar.AppendF("{} (Version {}.{}, Build {}, {})", Name, (UInt.Simple)Version.Major, (UInt.Simple)Version.Minor, (UInt.Simple)Version.Build, arch);
|
||||||
else
|
else
|
||||||
outVar.AppendF("{} Service Pack {} (Version {}.{}, Build {}, {})", Name, Version.Revision, Version.Major, Version.Minor, Version.Build, arch);
|
outVar.AppendF("{} Service Pack {} (Version {}.{}, Build {}, {})", Name, (UInt.Simple)Version.Revision, (UInt.Simple)Version.Major, (UInt.Simple)Version.Minor, (UInt.Simple)Version.Build, arch);
|
||||||
#elif BF_PLATFORM_LINUX
|
#elif BF_PLATFORM_LINUX
|
||||||
outVar.AppendF("{} {} (Version {}.{}.{})", PrettyName, Name, Version.Major, Version.Minor, Version.Revision);
|
outVar.AppendF("{} {} (Version {}.{}.{})", PrettyName, Name, Version.Major, Version.Minor, Version.Revision);
|
||||||
#else // MACOS and ANDROID
|
#else // MACOS and ANDROID
|
||||||
|
|
|
@ -34,15 +34,29 @@ namespace System
|
||||||
NotEmpty
|
NotEmpty
|
||||||
};
|
};
|
||||||
|
|
||||||
public struct BfpCritSect {}
|
|
||||||
public struct BfpSpawn {}
|
public struct BfpSpawn {}
|
||||||
public struct BfpFile {}
|
public struct BfpFile {}
|
||||||
public struct BfpFindFileData {}
|
public struct BfpFindFileData {}
|
||||||
public struct BfpDynLib {}
|
public struct BfpDynLib {}
|
||||||
public struct BfpEvent {};
|
|
||||||
public struct BfpFileWatcher {}
|
public struct BfpFileWatcher {}
|
||||||
public struct BfpProcess {}
|
public struct BfpProcess {}
|
||||||
public struct BfpTLS;
|
public struct BfpTLS;
|
||||||
|
#if !BF_RUNTIME_DISABLE
|
||||||
|
public struct BfpCritSect {}
|
||||||
|
public struct BfpEvent {};
|
||||||
|
#else
|
||||||
|
public struct BfpCritSect
|
||||||
|
{
|
||||||
|
public int mEmpty;
|
||||||
|
}
|
||||||
|
|
||||||
|
public struct BfpEvent
|
||||||
|
{
|
||||||
|
public bool mSet;
|
||||||
|
public bool mAuto;
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
public enum BfpSystemResult : int32
|
public enum BfpSystemResult : int32
|
||||||
{
|
{
|
||||||
|
@ -51,6 +65,7 @@ namespace System
|
||||||
TempFileError = (int)Result.TempFileError
|
TempFileError = (int)Result.TempFileError
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if !BF_RUNTIME_DISABLE
|
||||||
[CallingConvention(.Stdcall), CLink]
|
[CallingConvention(.Stdcall), CLink]
|
||||||
public static extern uint32 BfpSystem_TickCount();
|
public static extern uint32 BfpSystem_TickCount();
|
||||||
[CallingConvention(.Stdcall), CLink]
|
[CallingConvention(.Stdcall), CLink]
|
||||||
|
@ -107,6 +122,62 @@ namespace System
|
||||||
public static extern void BfpTLS_SetValue(BfpTLS* tls, void* value);
|
public static extern void BfpTLS_SetValue(BfpTLS* tls, void* value);
|
||||||
[CallingConvention(.Stdcall), CLink]
|
[CallingConvention(.Stdcall), CLink]
|
||||||
public static extern void* BfpTLS_GetValue(BfpTLS* tls);
|
public static extern void* BfpTLS_GetValue(BfpTLS* tls);
|
||||||
|
#else
|
||||||
|
|
||||||
|
public static uint32 BfpSystem_TickCount() => Runtime.NotImplemented();
|
||||||
|
|
||||||
|
public static uint32 BfpSystem_SetCrashRelaunchCmd(char8* cmd) => Runtime.NotImplemented();
|
||||||
|
|
||||||
|
public static BfpTimeStamp BfpSystem_GetTimeStamp() => Runtime.NotImplemented();
|
||||||
|
|
||||||
|
public static uint8 BfpSystem_InterlockedExchange8(uint8* ptr, uint8 val) => Runtime.NotImplemented();
|
||||||
|
|
||||||
|
public static uint16 BfpSystem_InterlockedExchange16(uint16* ptr, uint16 val) => Runtime.NotImplemented();
|
||||||
|
|
||||||
|
public static uint32 BfpSystem_InterlockedExchange32(uint32* ptr, uint32 val) => Runtime.NotImplemented();
|
||||||
|
|
||||||
|
public static uint64 BfpSystem_InterlockedExchange64(uint64* ptr, uint64 val) => Runtime.NotImplemented();
|
||||||
|
|
||||||
|
public static uint8 BfpSystem_InterlockedExchangeAdd8(uint8* ptr, uint8 val) => Runtime.NotImplemented();
|
||||||
|
|
||||||
|
public static uint16 BfpSystem_InterlockedExchangeAdd16(uint16* ptr, uint16 val) => Runtime.NotImplemented(); /// Returns the initial value in 'ptr'
|
||||||
|
|
||||||
|
public static uint32 BfpSystem_InterlockedExchangeAdd32(uint32* ptr, uint32 val) => Runtime.NotImplemented(); /// Returns the initial value in 'ptr'
|
||||||
|
|
||||||
|
public static uint64 BfpSystem_InterlockedExchangeAdd64(uint64* ptr, uint64 val) => Runtime.NotImplemented();
|
||||||
|
|
||||||
|
public static uint8 BfpSystem_InterlockedCompareExchange8(uint8* ptr, uint8 oldVal, uint8 newVal) => Runtime.NotImplemented();
|
||||||
|
|
||||||
|
public static uint16 BfpSystem_InterlockedCompareExchange16(uint16* ptr, uint16 oldVal, uint16 newVal) => Runtime.NotImplemented();
|
||||||
|
|
||||||
|
public static uint32 BfpSystem_InterlockedCompareExchange32(uint32* ptr, uint32 oldVal, uint32 newVal) => Runtime.NotImplemented();
|
||||||
|
|
||||||
|
public static uint64 BfpSystem_InterlockedCompareExchange64(uint64* ptr, uint64 oldVal, uint64 newVal) => Runtime.NotImplemented();
|
||||||
|
|
||||||
|
public static void BfpSystem_GetExecutablePath(char8* outStr, int32* inOutStrSize, BfpSystemResult* outResult) => Runtime.NotImplemented();
|
||||||
|
|
||||||
|
public static void BfpSystem_GetEnvironmentStrings(char8* outStr, int32* inOutStrSize, BfpSystemResult* outResult) => Runtime.NotImplemented();
|
||||||
|
|
||||||
|
public static int32 BfpSystem_GetNumLogicalCPUs(BfpSystemResult* outResult) => Runtime.NotImplemented();
|
||||||
|
|
||||||
|
public static int64 BfpSystem_GetCPUTick() => Runtime.NotImplemented();
|
||||||
|
|
||||||
|
public static int64 BfpSystem_GetCPUTickFreq() => Runtime.NotImplemented();
|
||||||
|
|
||||||
|
public static void BfpSystem_CreateGUID(Guid* outGuid) => Runtime.NotImplemented();
|
||||||
|
|
||||||
|
public static void BfpSystem_GetComputerName(char8* outStr, int32* inOutStrSize, BfpSystemResult* outResult) => Runtime.NotImplemented();
|
||||||
|
|
||||||
|
public static int BfpThread_GetCurrentId() => Runtime.NotImplemented();
|
||||||
|
|
||||||
|
public static BfpTLS* BfpTLS_Create(function [CallingConvention(.Stdcall)] void(void*) exitProc) => Runtime.NotImplemented();
|
||||||
|
|
||||||
|
public static void BfpTLS_Release(BfpTLS* tls) => Runtime.NotImplemented();
|
||||||
|
|
||||||
|
public static void BfpTLS_SetValue(BfpTLS* tls, void* value) => Runtime.NotImplemented();
|
||||||
|
|
||||||
|
public static void* BfpTLS_GetValue(BfpTLS* tls) => Runtime.NotImplemented();
|
||||||
|
#endif
|
||||||
|
|
||||||
public enum BfpFileWatcherFlags : int32
|
public enum BfpFileWatcherFlags : int32
|
||||||
{
|
{
|
||||||
|
@ -125,10 +196,16 @@ namespace System
|
||||||
|
|
||||||
public function void BfpDirectoryChangeFunc(BfpFileWatcher* watcher, void* userData, BfpFileChangeKind changeKind, char8* directory, char8* fileName, char8* oldName);
|
public function void BfpDirectoryChangeFunc(BfpFileWatcher* watcher, void* userData, BfpFileChangeKind changeKind, char8* directory, char8* fileName, char8* oldName);
|
||||||
|
|
||||||
|
#if !BF_RUNTIME_DISABLE
|
||||||
[CallingConvention(.Stdcall), CLink]
|
[CallingConvention(.Stdcall), CLink]
|
||||||
public static extern BfpFileWatcher* BfpFileWatcher_WatchDirectory(char8* path, BfpDirectoryChangeFunc callback, BfpFileWatcherFlags flags, void* userData, BfpFileResult* outResult);
|
public static extern BfpFileWatcher* BfpFileWatcher_WatchDirectory(char8* path, BfpDirectoryChangeFunc callback, BfpFileWatcherFlags flags, void* userData, BfpFileResult* outResult);
|
||||||
[CallingConvention(.Stdcall), CLink]
|
[CallingConvention(.Stdcall), CLink]
|
||||||
public static extern void BfpFileWatcher_Release(BfpFileWatcher* fileWatcher);
|
public static extern void BfpFileWatcher_Release(BfpFileWatcher* fileWatcher);
|
||||||
|
#else
|
||||||
|
public static BfpFileWatcher* BfpFileWatcher_WatchDirectory(char8* path, BfpDirectoryChangeFunc callback, BfpFileWatcherFlags flags, void* userData, BfpFileResult* outResult) => Runtime.NotImplemented();
|
||||||
|
|
||||||
|
public static void BfpFileWatcher_Release(BfpFileWatcher* fileWatcher) => Runtime.NotImplemented();
|
||||||
|
#endif
|
||||||
|
|
||||||
public enum BfpProcessResult : int32
|
public enum BfpProcessResult : int32
|
||||||
{
|
{
|
||||||
|
@ -136,6 +213,7 @@ namespace System
|
||||||
InsufficientBuffer = (int)Result.InsufficientBuffer
|
InsufficientBuffer = (int)Result.InsufficientBuffer
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if !BF_RUNTIME_DISABLE
|
||||||
[CallingConvention(.Stdcall), CLink]
|
[CallingConvention(.Stdcall), CLink]
|
||||||
public static extern bool BfpProcess_IsRemoteMachine(char8* machineName);
|
public static extern bool BfpProcess_IsRemoteMachine(char8* machineName);
|
||||||
[CallingConvention(.Stdcall), CLink]
|
[CallingConvention(.Stdcall), CLink]
|
||||||
|
@ -150,6 +228,22 @@ namespace System
|
||||||
public static extern void BfpProcess_GetProcessName(BfpProcess* process, char8* outName, int32* inOutNameSize, BfpProcessResult* outResult);
|
public static extern void BfpProcess_GetProcessName(BfpProcess* process, char8* outName, int32* inOutNameSize, BfpProcessResult* outResult);
|
||||||
[CallingConvention(.Stdcall), CLink]
|
[CallingConvention(.Stdcall), CLink]
|
||||||
public static extern int32 BfpProcess_GetProcessId(BfpProcess* process);
|
public static extern int32 BfpProcess_GetProcessId(BfpProcess* process);
|
||||||
|
#else
|
||||||
|
|
||||||
|
public static bool BfpProcess_IsRemoteMachine(char8* machineName) => Runtime.NotImplemented();
|
||||||
|
|
||||||
|
public static BfpProcess* BfpProcess_GetById(char8* machineName, int32 processId, BfpProcessResult* outResult) => Runtime.NotImplemented();
|
||||||
|
|
||||||
|
public static void BfpProcess_Enumerate(char8* machineName, BfpProcess** outProcesses, int32* inOutProcessesSize, BfpProcessResult* outResult) => Runtime.NotImplemented();
|
||||||
|
|
||||||
|
public static void BfpProcess_Release(BfpProcess* process) => Runtime.NotImplemented();
|
||||||
|
|
||||||
|
public static void BfpProcess_GetMainWindowTitle(BfpProcess* process, char8* outTitle, int32* inOutTitleSize, BfpProcessResult* outResult) => Runtime.NotImplemented();
|
||||||
|
|
||||||
|
public static void BfpProcess_GetProcessName(BfpProcess* process, char8* outName, int32* inOutNameSize, BfpProcessResult* outResult) => Runtime.NotImplemented();
|
||||||
|
|
||||||
|
public static int32 BfpProcess_GetProcessId(BfpProcess* process) => Runtime.NotImplemented();
|
||||||
|
#endif
|
||||||
|
|
||||||
public enum BfpSpawnFlags : int32
|
public enum BfpSpawnFlags : int32
|
||||||
{
|
{
|
||||||
|
@ -181,6 +275,7 @@ namespace System
|
||||||
UnknownError = (int)Result.UnknownError
|
UnknownError = (int)Result.UnknownError
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#if !BF_RUNTIME_DISABLE
|
||||||
[CallingConvention(.Stdcall), CLink]
|
[CallingConvention(.Stdcall), CLink]
|
||||||
public static extern BfpSpawn* BfpSpawn_Create(char8* targetPath, char8* args, char8* workingDir, char8* env, BfpSpawnFlags flags, BfpSpawnResult* outResult);
|
public static extern BfpSpawn* BfpSpawn_Create(char8* targetPath, char8* args, char8* workingDir, char8* env, BfpSpawnFlags flags, BfpSpawnResult* outResult);
|
||||||
[CallingConvention(.Stdcall), CLink]
|
[CallingConvention(.Stdcall), CLink]
|
||||||
|
@ -205,6 +300,47 @@ namespace System
|
||||||
public static extern bool BfpCritSect_TryEnter(BfpCritSect* critSect, int32 waitMS);
|
public static extern bool BfpCritSect_TryEnter(BfpCritSect* critSect, int32 waitMS);
|
||||||
[CallingConvention(.Stdcall), CLink]
|
[CallingConvention(.Stdcall), CLink]
|
||||||
public static extern void BfpCritSect_Leave(BfpCritSect* critSect);
|
public static extern void BfpCritSect_Leave(BfpCritSect* critSect);
|
||||||
|
#else
|
||||||
|
|
||||||
|
public static BfpSpawn* BfpSpawn_Create(char8* targetPath, char8* args, char8* workingDir, char8* env, BfpSpawnFlags flags, BfpSpawnResult* outResult)
|
||||||
|
{
|
||||||
|
*outResult = .UnknownError;
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void BfpSpawn_Release(BfpSpawn* spawn) => Runtime.NotImplemented();
|
||||||
|
|
||||||
|
public static void BfpSpawn_Kill(BfpSpawn* spawn, int32 exitCode, BfpKillFlags killFlags, BfpSpawnResult* outResult) => Runtime.NotImplemented();
|
||||||
|
|
||||||
|
public static bool BfpSpawn_WaitFor(BfpSpawn* spawn, int waitMS, int* outExitCode, BfpSpawnResult* outResult) => Runtime.NotImplemented();
|
||||||
|
|
||||||
|
public static void BfpSpawn_GetStdHandles(BfpSpawn* spawn, BfpFile** outStdIn, BfpFile** outStdOut, BfpFile** outStdErr) => Runtime.NotImplemented();
|
||||||
|
|
||||||
|
|
||||||
|
public static int BfpProcess_GetCurrentId() => Runtime.NotImplemented();
|
||||||
|
|
||||||
|
public static BfpCritSect* BfpCritSect_Create() => new BfpCritSect();
|
||||||
|
|
||||||
|
public static void BfpCritSect_Release(BfpCritSect* critSect)
|
||||||
|
{
|
||||||
|
delete critSect;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void BfpCritSect_Enter(BfpCritSect* critSect)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool BfpCritSect_TryEnter(BfpCritSect* critSect, int32 waitMS)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void BfpCritSect_Leave(BfpCritSect* critSect)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
public enum BfpEventFlags : int32
|
public enum BfpEventFlags : int32
|
||||||
{
|
{
|
||||||
|
@ -221,6 +357,7 @@ namespace System
|
||||||
BfpEventResult_NotSupported = (int)Result.NotSupported
|
BfpEventResult_NotSupported = (int)Result.NotSupported
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#if !BF_RUNTIME_DISABLE
|
||||||
[CallingConvention(.Stdcall), CLink]
|
[CallingConvention(.Stdcall), CLink]
|
||||||
public static extern BfpEvent* BfpEvent_Create(BfpEventFlags flags);
|
public static extern BfpEvent* BfpEvent_Create(BfpEventFlags flags);
|
||||||
[CallingConvention(.Stdcall), CLink]
|
[CallingConvention(.Stdcall), CLink]
|
||||||
|
@ -231,6 +368,46 @@ namespace System
|
||||||
public static extern void BfpEvent_Reset(BfpEvent* event, BfpEventResult* outResult);
|
public static extern void BfpEvent_Reset(BfpEvent* event, BfpEventResult* outResult);
|
||||||
[CallingConvention(.Stdcall), CLink]
|
[CallingConvention(.Stdcall), CLink]
|
||||||
public static extern bool BfpEvent_WaitFor(BfpEvent* event, int32 waitMS);
|
public static extern bool BfpEvent_WaitFor(BfpEvent* event, int32 waitMS);
|
||||||
|
#else
|
||||||
|
|
||||||
|
public static BfpEvent* BfpEvent_Create(BfpEventFlags flags)
|
||||||
|
{
|
||||||
|
var result = new BfpEvent();
|
||||||
|
result.mSet = flags.HasFlag(.InitiallySet_Auto) | flags.HasFlag(.InitiallySet_Manual);
|
||||||
|
result.mAuto = flags.HasFlag(.InitiallySet_Auto);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void BfpEvent_Release(BfpEvent* event)
|
||||||
|
{
|
||||||
|
delete event;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void BfpEvent_Set(BfpEvent* event, bool requireManualReset)
|
||||||
|
{
|
||||||
|
event.mSet = true;
|
||||||
|
event.mAuto = !requireManualReset;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void BfpEvent_Reset(BfpEvent* event, BfpEventResult* outResult)
|
||||||
|
{
|
||||||
|
event.mSet = false;
|
||||||
|
event.mAuto = false;
|
||||||
|
*outResult = .BfpEventResult_Ok;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool BfpEvent_WaitFor(BfpEvent* event, int32 waitMS)
|
||||||
|
{
|
||||||
|
if (!event.mSet)
|
||||||
|
return false;
|
||||||
|
if (event.mAuto)
|
||||||
|
{
|
||||||
|
event.mSet = false;
|
||||||
|
event.mAuto = false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
public enum BfpLibResult : int32
|
public enum BfpLibResult : int32
|
||||||
{
|
{
|
||||||
|
@ -239,6 +416,7 @@ namespace System
|
||||||
InsufficientBuffer = (int)Result.InsufficientBuffer
|
InsufficientBuffer = (int)Result.InsufficientBuffer
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#if !BF_RUNTIME_DISABLE
|
||||||
[CallingConvention(.Stdcall), CLink]
|
[CallingConvention(.Stdcall), CLink]
|
||||||
public static extern BfpDynLib* BfpDynLib_Load(char8* fileName);
|
public static extern BfpDynLib* BfpDynLib_Load(char8* fileName);
|
||||||
[CallingConvention(.Stdcall), CLink]
|
[CallingConvention(.Stdcall), CLink]
|
||||||
|
@ -247,6 +425,16 @@ namespace System
|
||||||
public static extern void BfpDynLib_GetFilePath(BfpDynLib* lib, char8* outPath, int32* inOutPathSize, BfpLibResult* outResult);
|
public static extern void BfpDynLib_GetFilePath(BfpDynLib* lib, char8* outPath, int32* inOutPathSize, BfpLibResult* outResult);
|
||||||
[CallingConvention(.Stdcall), CLink]
|
[CallingConvention(.Stdcall), CLink]
|
||||||
public static extern void* BfpDynLib_GetProcAddress(BfpDynLib* lib, char8* name);
|
public static extern void* BfpDynLib_GetProcAddress(BfpDynLib* lib, char8* name);
|
||||||
|
#else
|
||||||
|
|
||||||
|
public static BfpDynLib* BfpDynLib_Load(char8* fileName) => Runtime.NotImplemented();
|
||||||
|
|
||||||
|
public static void BfpDynLib_Release(BfpDynLib* lib) => Runtime.NotImplemented();
|
||||||
|
|
||||||
|
public static void BfpDynLib_GetFilePath(BfpDynLib* lib, char8* outPath, int32* inOutPathSize, BfpLibResult* outResult) => Runtime.NotImplemented();
|
||||||
|
|
||||||
|
public static void* BfpDynLib_GetProcAddress(BfpDynLib* lib, char8* name) => Runtime.NotImplemented();
|
||||||
|
#endif
|
||||||
|
|
||||||
public enum BfpFileResult : int32
|
public enum BfpFileResult : int32
|
||||||
{
|
{
|
||||||
|
@ -265,6 +453,7 @@ namespace System
|
||||||
NotEmpty = (int)Result.NotEmpty,
|
NotEmpty = (int)Result.NotEmpty,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#if !BF_RUNTIME_DISABLE
|
||||||
[CallingConvention(.Stdcall), CLink]
|
[CallingConvention(.Stdcall), CLink]
|
||||||
public static extern void BfpDirectory_Create(char8* name, BfpFileResult* outResult);
|
public static extern void BfpDirectory_Create(char8* name, BfpFileResult* outResult);
|
||||||
[CallingConvention(.Stdcall), CLink]
|
[CallingConvention(.Stdcall), CLink]
|
||||||
|
@ -279,6 +468,22 @@ namespace System
|
||||||
public static extern bool BfpDirectory_Exists(char8* path);
|
public static extern bool BfpDirectory_Exists(char8* path);
|
||||||
[CallingConvention(.Stdcall), CLink]
|
[CallingConvention(.Stdcall), CLink]
|
||||||
public static extern void BfpDirectory_GetSysDirectory(BfpSysDirectoryKind sysDirKind, char8* outPath, int32* inOutPathLen, BfpFileResult* outResult);
|
public static extern void BfpDirectory_GetSysDirectory(BfpSysDirectoryKind sysDirKind, char8* outPath, int32* inOutPathLen, BfpFileResult* outResult);
|
||||||
|
#else
|
||||||
|
|
||||||
|
public static void BfpDirectory_Create(char8* name, BfpFileResult* outResult) => Runtime.NotImplemented();
|
||||||
|
|
||||||
|
public static void BfpDirectory_Rename(char8* oldName, char8* newName, BfpFileResult* outResult) => Runtime.NotImplemented();
|
||||||
|
|
||||||
|
public static void BfpDirectory_Delete(char8* name, BfpFileResult* outResult) => Runtime.NotImplemented();
|
||||||
|
|
||||||
|
public static void BfpDirectory_GetCurrent(char8* outPath, int32* inOutPathSize, BfpFileResult* outResult) => Runtime.NotImplemented();
|
||||||
|
|
||||||
|
public static void BfpDirectory_SetCurrent(char8* path, BfpFileResult* outResult) => Runtime.NotImplemented();
|
||||||
|
|
||||||
|
public static bool BfpDirectory_Exists(char8* path) => Runtime.NotImplemented();
|
||||||
|
|
||||||
|
public static void BfpDirectory_GetSysDirectory(BfpSysDirectoryKind sysDirKind, char8* outPath, int32* inOutPathLen, BfpFileResult* outResult) => Runtime.NotImplemented();
|
||||||
|
#endif
|
||||||
|
|
||||||
public enum BfpFileCreateKind : int32
|
public enum BfpFileCreateKind : int32
|
||||||
{
|
{
|
||||||
|
@ -347,6 +552,7 @@ namespace System
|
||||||
In
|
In
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if !BF_RUNTIME_DISABLE
|
||||||
[CallingConvention(.Stdcall), CLink]
|
[CallingConvention(.Stdcall), CLink]
|
||||||
public static extern BfpFile* BfpFile_Create(char8* name, BfpFileCreateKind createKind, BfpFileCreateFlags createFlags, BfpFileAttributes createdFileAttrs, BfpFileResult* outResult);
|
public static extern BfpFile* BfpFile_Create(char8* name, BfpFileCreateKind createKind, BfpFileCreateFlags createFlags, BfpFileAttributes createdFileAttrs, BfpFileResult* outResult);
|
||||||
[CallingConvention(.Stdcall), CLink]
|
[CallingConvention(.Stdcall), CLink]
|
||||||
|
@ -389,6 +595,50 @@ namespace System
|
||||||
public static extern void BfpFile_GetFullPath(char8* inPath, char8* outPath, int32* inOutPathSize, BfpFileResult* outResult);
|
public static extern void BfpFile_GetFullPath(char8* inPath, char8* outPath, int32* inOutPathSize, BfpFileResult* outResult);
|
||||||
[CallingConvention(.Stdcall), CLink]
|
[CallingConvention(.Stdcall), CLink]
|
||||||
public static extern void BfpFile_GetActualPath(char8* inPath, char8* outPath, int32* inOutPathSize, BfpFileResult* outResult);
|
public static extern void BfpFile_GetActualPath(char8* inPath, char8* outPath, int32* inOutPathSize, BfpFileResult* outResult);
|
||||||
|
#else
|
||||||
|
|
||||||
|
public static BfpFile* BfpFile_Create(char8* name, BfpFileCreateKind createKind, BfpFileCreateFlags createFlags, BfpFileAttributes createdFileAttrs, BfpFileResult* outResult) => Runtime.NotImplemented();
|
||||||
|
|
||||||
|
public static BfpFile* BfpFile_GetStd(BfpFileStdKind kind, BfpFileResult* outResult) => Runtime.NotImplemented();
|
||||||
|
|
||||||
|
public static int BfpFile_GetSystemHandle(BfpFile* file) => Runtime.NotImplemented();
|
||||||
|
|
||||||
|
public static void BfpFile_Release(BfpFile* file) => Runtime.NotImplemented();
|
||||||
|
|
||||||
|
public static int BfpFile_Write(BfpFile* file, void* buffer, int size, int timeoutMS, BfpFileResult* outResult) => Runtime.NotImplemented();
|
||||||
|
|
||||||
|
public static int BfpFile_Read(BfpFile* file, void* buffer, int size, int timeoutMS, BfpFileResult* outResult) => Runtime.NotImplemented();
|
||||||
|
|
||||||
|
public static void BfpFile_Flush(BfpFile* file) => Runtime.NotImplemented();
|
||||||
|
|
||||||
|
public static int64 BfpFile_GetFileSize(BfpFile* file) => Runtime.NotImplemented();
|
||||||
|
|
||||||
|
public static int64 BfpFile_Seek(BfpFile* file, int64 offset, BfpFileSeekKind seekKind) => Runtime.NotImplemented();
|
||||||
|
|
||||||
|
public static void BfpFile_Truncate(BfpFile* file, BfpFileResult* outResult) => Runtime.NotImplemented();
|
||||||
|
|
||||||
|
public static BfpTimeStamp BfpFile_GetTime_LastWrite(char8* path) => Runtime.NotImplemented();
|
||||||
|
|
||||||
|
public static BfpFileAttributes BfpFile_GetAttributes(char8* path, BfpFileResult* outResult) => Runtime.NotImplemented();
|
||||||
|
|
||||||
|
public static void BfpFile_SetAttributes(char8* path, BfpFileAttributes attribs, BfpFileResult* outResult) => Runtime.NotImplemented();
|
||||||
|
|
||||||
|
public static void BfpFile_Copy(char8* oldPath, char8* newPath, BfpFileCopyKind copyKind, BfpFileResult* outResult) => Runtime.NotImplemented();
|
||||||
|
|
||||||
|
public static void BfpFile_Rename(char8* oldPath, char8* newPath, BfpFileResult* outResult) => Runtime.NotImplemented();
|
||||||
|
|
||||||
|
public static void BfpFile_Delete(char8* path, BfpFileResult* outResult) => Runtime.NotImplemented();
|
||||||
|
|
||||||
|
public static bool BfpFile_Exists(char8* path) => Runtime.NotImplemented();
|
||||||
|
|
||||||
|
public static void BfpFile_GetTempPath(char8* outPath, int32* inOutPathSize, BfpFileResult* outResult) => Runtime.NotImplemented();
|
||||||
|
|
||||||
|
public static void BfpFile_GetTempFileName(char8* outName, int32* inOutNameSize, BfpFileResult* outResult) => Runtime.NotImplemented();
|
||||||
|
|
||||||
|
public static void BfpFile_GetFullPath(char8* inPath, char8* outPath, int32* inOutPathSize, BfpFileResult* outResult) => Runtime.NotImplemented();
|
||||||
|
|
||||||
|
public static void BfpFile_GetActualPath(char8* inPath, char8* outPath, int32* inOutPathSize, BfpFileResult* outResult) => Runtime.NotImplemented();
|
||||||
|
#endif
|
||||||
|
|
||||||
public enum BfpFindFileFlags : int32
|
public enum BfpFindFileFlags : int32
|
||||||
{
|
{
|
||||||
|
@ -397,6 +647,7 @@ namespace System
|
||||||
Directories = 2,
|
Directories = 2,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#if !BF_RUNTIME_DISABLE
|
||||||
[CallingConvention(.Stdcall), CLink]
|
[CallingConvention(.Stdcall), CLink]
|
||||||
public static extern BfpFindFileData* BfpFindFileData_FindFirstFile(char8* path, BfpFindFileFlags flags, BfpFileResult* outResult);
|
public static extern BfpFindFileData* BfpFindFileData_FindFirstFile(char8* path, BfpFindFileFlags flags, BfpFileResult* outResult);
|
||||||
[CallingConvention(.Stdcall), CLink]
|
[CallingConvention(.Stdcall), CLink]
|
||||||
|
@ -415,6 +666,26 @@ namespace System
|
||||||
public static extern int64 BfpFindFileData_GetFileSize(BfpFindFileData* findData);
|
public static extern int64 BfpFindFileData_GetFileSize(BfpFindFileData* findData);
|
||||||
[CallingConvention(.Stdcall), CLink]
|
[CallingConvention(.Stdcall), CLink]
|
||||||
public static extern void BfpFindFileData_Release(BfpFindFileData* findData);
|
public static extern void BfpFindFileData_Release(BfpFindFileData* findData);
|
||||||
|
#else
|
||||||
|
|
||||||
|
public static BfpFindFileData* BfpFindFileData_FindFirstFile(char8* path, BfpFindFileFlags flags, BfpFileResult* outResult) => Runtime.NotImplemented();
|
||||||
|
|
||||||
|
public static bool BfpFindFileData_FindNextFile(BfpFindFileData* findData) => Runtime.NotImplemented();
|
||||||
|
|
||||||
|
public static void BfpFindFileData_GetFileName(BfpFindFileData* findData, char8* outName, int32* inOutNameSize, BfpFileResult* outResult) => Runtime.NotImplemented();
|
||||||
|
|
||||||
|
public static BfpTimeStamp BfpFindFileData_GetTime_LastWrite(BfpFindFileData* findData) => Runtime.NotImplemented();
|
||||||
|
|
||||||
|
public static BfpTimeStamp BfpFindFileData_GetTime_Created(BfpFindFileData* findData) => Runtime.NotImplemented();
|
||||||
|
|
||||||
|
public static BfpTimeStamp BfpFindFileData_GetTime_Access(BfpFindFileData* findData) => Runtime.NotImplemented();
|
||||||
|
|
||||||
|
public static BfpFileAttributes BfpFindFileData_GetFileAttributes(BfpFindFileData* findData) => Runtime.NotImplemented();
|
||||||
|
|
||||||
|
public static int64 BfpFindFileData_GetFileSize(BfpFindFileData* findData) => Runtime.NotImplemented();
|
||||||
|
|
||||||
|
public static void BfpFindFileData_Release(BfpFindFileData* findData) => Runtime.NotImplemented();
|
||||||
|
#endif
|
||||||
|
|
||||||
public enum BfpSysDirectoryKind : int32
|
public enum BfpSysDirectoryKind : int32
|
||||||
{
|
{
|
||||||
|
|
|
@ -18,7 +18,7 @@ namespace System
|
||||||
|
|
||||||
public override void ToString(String strBuffer)
|
public override void ToString(String strBuffer)
|
||||||
{
|
{
|
||||||
strBuffer.AppendF("0x{0:A}", (uint)(void*)mVal);
|
strBuffer.AppendF("0x{0:A}", (UInt.Simple)(uint)(void*)mVal);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,8 +34,8 @@ namespace System
|
||||||
public override void ToString(String strBuffer)
|
public override void ToString(String strBuffer)
|
||||||
{
|
{
|
||||||
strBuffer.Append("(");
|
strBuffer.Append("(");
|
||||||
typeof(T).GetFullName(strBuffer);
|
typeof(T).ToString(strBuffer);
|
||||||
strBuffer.AppendF("*)0x{0:A}", (uint)(void*)mVal);
|
strBuffer.AppendF("*)0x{0:A}", (UInt.Simple)(uint)(void*)mVal);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,11 @@
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Collections;
|
using System.Collections;
|
||||||
#if BF_ENABLE_OBJECT_DEBUG_FLAGS || BF_DEBUG_ALLOC
|
#if (BF_ENABLE_OBJECT_DEBUG_FLAGS || BF_DEBUG_ALLOC) && !BF_RUNTIME_DISABLE
|
||||||
#define BF_DBG_RUNTIME
|
#define BF_DBG_RUNTIME
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
using internal System.Threading.Thread;
|
||||||
|
|
||||||
namespace System
|
namespace System
|
||||||
{
|
{
|
||||||
struct RuntimeFeatures
|
struct RuntimeFeatures
|
||||||
|
@ -17,7 +19,7 @@ namespace System
|
||||||
{
|
{
|
||||||
const int32 cVersion = 10;
|
const int32 cVersion = 10;
|
||||||
|
|
||||||
[CRepr, AlwaysInclude]
|
[CRepr]
|
||||||
struct BfDebugMessageData
|
struct BfDebugMessageData
|
||||||
{
|
{
|
||||||
enum MessageType : int32
|
enum MessageType : int32
|
||||||
|
@ -104,7 +106,7 @@ namespace System
|
||||||
|
|
||||||
struct BfRtCallbacks
|
struct BfRtCallbacks
|
||||||
{
|
{
|
||||||
public static BfRtCallbacks sCallbacks = .();
|
public static BfRtCallbacks sCallbacks;
|
||||||
|
|
||||||
function void* (int size) mAlloc;
|
function void* (int size) mAlloc;
|
||||||
function void (void* ptr) mFree;
|
function void (void* ptr) mFree;
|
||||||
|
@ -115,7 +117,7 @@ namespace System
|
||||||
function Object (Object obj, int32 typeId) mObject_DynamicCastToTypeId;
|
function Object (Object obj, int32 typeId) mObject_DynamicCastToTypeId;
|
||||||
function void (Type type, String str) mType_GetFullName;
|
function void (Type type, String str) mType_GetFullName;
|
||||||
function String () mString_Alloc;
|
function String () mString_Alloc;
|
||||||
function char8* (String str) mString_ToCStr;
|
function StringView (String str) mString_ToStringView;
|
||||||
function Object () mThread_Alloc;
|
function Object () mThread_Alloc;
|
||||||
function Object () mThread_GetMainThread;
|
function Object () mThread_GetMainThread;
|
||||||
function void (Object thread) mThread_ThreadProc;
|
function void (Object thread) mThread_ThreadProc;
|
||||||
|
@ -178,7 +180,7 @@ namespace System
|
||||||
static void Type_GetFullName(Type type, String str)
|
static void Type_GetFullName(Type type, String str)
|
||||||
{
|
{
|
||||||
#if BF_DBG_RUNTIME
|
#if BF_DBG_RUNTIME
|
||||||
type.GetFullName(str);
|
type.ToString(str);
|
||||||
#else
|
#else
|
||||||
//
|
//
|
||||||
#endif
|
#endif
|
||||||
|
@ -189,9 +191,9 @@ namespace System
|
||||||
return new String();
|
return new String();
|
||||||
}
|
}
|
||||||
|
|
||||||
static char8* String_ToCStr(String str)
|
static StringView String_ToStringView(String str)
|
||||||
{
|
{
|
||||||
return str.CStr();
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void GC_MarkAllStaticMembers()
|
static void GC_MarkAllStaticMembers()
|
||||||
|
@ -219,39 +221,37 @@ namespace System
|
||||||
|
|
||||||
static void DebugMessageData_SetupError(char8* str, int32 stackWindbackCount)
|
static void DebugMessageData_SetupError(char8* str, int32 stackWindbackCount)
|
||||||
{
|
{
|
||||||
|
#if !BF_RUNTIME_REDUCED
|
||||||
BfDebugMessageData.gBfDebugMessageData.SetupError(str, stackWindbackCount);
|
BfDebugMessageData.gBfDebugMessageData.SetupError(str, stackWindbackCount);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static void DebugMessageData_SetupProfilerCmd(char8* str)
|
static void DebugMessageData_SetupProfilerCmd(char8* str)
|
||||||
{
|
{
|
||||||
|
#if !BF_RUNTIME_REDUCED
|
||||||
BfDebugMessageData.gBfDebugMessageData.SetupProfilerCmd(str);
|
BfDebugMessageData.gBfDebugMessageData.SetupProfilerCmd(str);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static void DebugMessageData_Fatal()
|
static void DebugMessageData_Fatal()
|
||||||
{
|
{
|
||||||
|
#if !BF_RUNTIME_REDUCED
|
||||||
BfDebugMessageData.gBfDebugMessageData.Fatal();
|
BfDebugMessageData.gBfDebugMessageData.Fatal();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static void DebugMessageData_Clear()
|
static void DebugMessageData_Clear()
|
||||||
{
|
{
|
||||||
|
#if !BF_RUNTIME_REDUCED
|
||||||
BfDebugMessageData.gBfDebugMessageData.Clear();
|
BfDebugMessageData.gBfDebugMessageData.Clear();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32 CheckErrorHandler(char8* kind, char8* arg1, char8* arg2, int arg3)
|
static int32 CheckErrorHandle(char8* kind, char8* arg1, char8* arg2, int arg3)
|
||||||
{
|
{
|
||||||
Error error = null;
|
if (Runtime.CheckErrorHandler != null)
|
||||||
switch (StringView(kind))
|
return Runtime.CheckErrorHandler(kind, arg1, arg2, arg3);
|
||||||
{
|
return 0;
|
||||||
case "FatalError":
|
|
||||||
error = scope:: FatalError() { mError = new .(arg1) };
|
|
||||||
case "LoadSharedLibrary":
|
|
||||||
error = scope:: LoadSharedLibraryError() { mPath = new .(arg1) };
|
|
||||||
case "GetSharedProcAddress":
|
|
||||||
error = scope:: GetSharedProcAddressError() { mPath = new .(arg1), mProcName = new .(arg2) };
|
|
||||||
}
|
|
||||||
if (error == null)
|
|
||||||
return 0;
|
|
||||||
return (int32)Runtime.CheckErrorHandlers(error);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Init() mut
|
public void Init() mut
|
||||||
|
@ -264,7 +264,7 @@ namespace System
|
||||||
mObject_DynamicCastToTypeId = => Object_DynamicCastToTypeId;
|
mObject_DynamicCastToTypeId = => Object_DynamicCastToTypeId;
|
||||||
mType_GetFullName = => Type_GetFullName;
|
mType_GetFullName = => Type_GetFullName;
|
||||||
mString_Alloc = => String_Alloc;
|
mString_Alloc = => String_Alloc;
|
||||||
mString_ToCStr = => String_ToCStr;
|
mString_ToStringView = => String_ToStringView;
|
||||||
mGC_MarkAllStaticMembers = => GC_MarkAllStaticMembers;
|
mGC_MarkAllStaticMembers = => GC_MarkAllStaticMembers;
|
||||||
mGC_CallRootCallbacks = => GC_CallRootCallbacks;
|
mGC_CallRootCallbacks = => GC_CallRootCallbacks;
|
||||||
mGC_Shutdown = => GC_Shutdown;
|
mGC_Shutdown = => GC_Shutdown;
|
||||||
|
@ -277,12 +277,23 @@ namespace System
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#if !BF_RUNTIME_DISABLE
|
||||||
private static extern void Init(int32 version, int32 flags, BfRtCallbacks* callbacks);
|
private static extern void Init(int32 version, int32 flags, BfRtCallbacks* callbacks);
|
||||||
|
private static extern void InitCrashCatcher(int32 flags);
|
||||||
|
private static extern void ShutdownCrashCatcher();
|
||||||
private static extern void AddCrashInfoFunc(void* func);
|
private static extern void AddCrashInfoFunc(void* func);
|
||||||
private static extern void Dbg_Init(int32 version, int32 flags, BfRtCallbacks* callbacks);
|
private static extern void Dbg_Init(int32 version, int32 flags, BfRtCallbacks* callbacks);
|
||||||
private static extern void SetErrorString(char8* error);
|
private static extern void SetErrorString(char8* error);
|
||||||
private static extern void* Dbg_GetCrashInfoFunc();
|
private static extern void* Dbg_GetCrashInfoFunc();
|
||||||
public static extern void SetCrashReportKind(RtCrashReportKind crashReportKind);
|
public static extern void SetCrashReportKind(RtCrashReportKind crashReportKind);
|
||||||
|
#else
|
||||||
|
private static void Init(int32 version, int32 flags, BfRtCallbacks* callbacks) {}
|
||||||
|
private static void AddCrashInfoFunc(void* func) {}
|
||||||
|
private static void Dbg_Init(int32 version, int32 flags, BfRtCallbacks* callbacks) {}
|
||||||
|
private static void SetErrorString(char8* error) {}
|
||||||
|
private static void* Dbg_GetCrashInfoFunc() => null;
|
||||||
|
public static void SetCrashReportKind(RtCrashReportKind crashReportKind) {}
|
||||||
|
#endif
|
||||||
|
|
||||||
public enum RtCrashReportKind : int32
|
public enum RtCrashReportKind : int32
|
||||||
{
|
{
|
||||||
|
@ -359,18 +370,23 @@ namespace System
|
||||||
Fail
|
Fail
|
||||||
}
|
}
|
||||||
|
|
||||||
public delegate ErrorHandlerResult ErrorHandler(ErrorStage stage, Error error);
|
static struct ErrorHandlerData
|
||||||
|
{
|
||||||
|
public delegate ErrorHandlerResult ErrorHandler(ErrorStage stage, Error error);
|
||||||
|
public static AllocWrapper<Monitor> sMonitor ~ _.Dispose();
|
||||||
|
public static List<ErrorHandler> sErrorHandlers ~ DeleteContainerAndItems!(_);
|
||||||
|
public static bool sInsideErrorHandler;
|
||||||
|
}
|
||||||
|
|
||||||
static RtFlags sExtraFlags;
|
static RtFlags sExtraFlags;
|
||||||
static AllocWrapper<Monitor> sMonitor ~ _.Dispose();
|
|
||||||
static List<ErrorHandler> sErrorHandlers ~ DeleteContainerAndItems!(_);
|
|
||||||
static bool sInsideErrorHandler;
|
|
||||||
|
|
||||||
static bool sQueriedFeatures = false;
|
static bool sQueriedFeatures = false;
|
||||||
static RuntimeFeatures sFeatures;
|
static RuntimeFeatures sFeatures;
|
||||||
|
|
||||||
|
static function void() sThreadInit;
|
||||||
|
|
||||||
public static this()
|
public static this()
|
||||||
{
|
{
|
||||||
|
#if !BF_RUNTIME_DISABLE
|
||||||
BfRtCallbacks.sCallbacks.Init();
|
BfRtCallbacks.sCallbacks.Init();
|
||||||
|
|
||||||
RtFlags flags = sExtraFlags;
|
RtFlags flags = sExtraFlags;
|
||||||
|
@ -384,23 +400,36 @@ namespace System
|
||||||
flags |= .DebugAlloc;
|
flags |= .DebugAlloc;
|
||||||
#endif
|
#endif
|
||||||
Init(cVersion, (int32)flags, &BfRtCallbacks.sCallbacks);
|
Init(cVersion, (int32)flags, &BfRtCallbacks.sCallbacks);
|
||||||
|
#if !BF_RUNTIME_REDUCED && BF_PLATFORM_WINDOWS
|
||||||
|
InitCrashCatcher((int32)flags);
|
||||||
|
#endif
|
||||||
#if BF_DBG_RUNTIME
|
#if BF_DBG_RUNTIME
|
||||||
Dbg_Init(cVersion, (int32)flags, &BfRtCallbacks.sCallbacks);
|
Dbg_Init(cVersion, (int32)flags, &BfRtCallbacks.sCallbacks);
|
||||||
#endif
|
#endif
|
||||||
Thread.[Friend]Init();
|
if (sThreadInit != null)
|
||||||
|
sThreadInit();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
[NoReturn]
|
[NoReturn]
|
||||||
public static void FatalError(String msg = "Fatal error encountered", String filePath = Compiler.CallerFilePath, int line = Compiler.CallerLineNum)
|
public static void FatalError(String msg = "Fatal error encountered", String filePath = Compiler.CallerFilePath, int line = Compiler.CallerLineNum)
|
||||||
{
|
{
|
||||||
String failStr = scope .()..AppendF("{} at line {} in {}", msg, line, filePath);
|
#if !BF_RUNTIME_REDUCED
|
||||||
|
String failStr = scope .()..Append(msg, " at line ");
|
||||||
|
line.ToString(failStr);
|
||||||
|
failStr.Append(" in ", filePath);
|
||||||
Internal.FatalError(failStr, 1);
|
Internal.FatalError(failStr, 1);
|
||||||
|
#else
|
||||||
|
Internal.FatalError("Fatal error", 1);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
[NoReturn]
|
[NoReturn]
|
||||||
public static void NotImplemented(String filePath = Compiler.CallerFilePath, int line = Compiler.CallerLineNum)
|
public static void NotImplemented(String filePath = Compiler.CallerFilePath, int line = Compiler.CallerLineNum)
|
||||||
{
|
{
|
||||||
String failStr = scope .()..AppendF("Not Implemented at line {} in {}", line, filePath);
|
String failStr = scope .()..Append("Not implemented at line ");
|
||||||
|
line.ToString(failStr);
|
||||||
|
failStr.Append(" in ", filePath);
|
||||||
Internal.FatalError(failStr, 1);
|
Internal.FatalError(failStr, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -408,60 +437,97 @@ namespace System
|
||||||
{
|
{
|
||||||
if (!condition)
|
if (!condition)
|
||||||
{
|
{
|
||||||
if (Runtime.CheckErrorHandlers(scope Runtime.AssertError(.Runtime, error, filePath, line)) == .Ignore)
|
if ((Runtime.CheckAssertError != null) && (Runtime.CheckAssertError(.Runtime, error, filePath, line) == .Ignore))
|
||||||
return;
|
return;
|
||||||
String failStr = scope .()..AppendF("Assert failed: {} at line {} in {}", error, line, filePath);
|
#if !BF_RUNTIME_REDUCED
|
||||||
|
String failStr = scope .()..Append("Assert failed: ", error, " at line ");
|
||||||
|
line.ToString(failStr);
|
||||||
|
failStr.Append(" in ", filePath);
|
||||||
Internal.FatalError(failStr, 1);
|
Internal.FatalError(failStr, 1);
|
||||||
|
#else
|
||||||
|
Internal.FatalError("Assert failed", 1);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void AddErrorHandler(ErrorHandler handler)
|
public static void AddErrorHandler(ErrorHandlerData.ErrorHandler handler)
|
||||||
{
|
{
|
||||||
if (Compiler.IsComptime)
|
if (Compiler.IsComptime)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
using (sMonitor.Val.Enter())
|
using (ErrorHandlerData.sMonitor.Val.Enter())
|
||||||
{
|
{
|
||||||
if (sErrorHandlers == null)
|
if (CheckAssertError == null)
|
||||||
sErrorHandlers = new .();
|
{
|
||||||
sErrorHandlers.Add(handler);
|
CheckAssertError = => CheckAssertError_Impl;
|
||||||
|
CheckErrorHandler = => CheckErrorHandler_Impl;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ErrorHandlerData.sErrorHandlers == null)
|
||||||
|
ErrorHandlerData.sErrorHandlers = new .();
|
||||||
|
ErrorHandlerData.sErrorHandlers.Add(handler);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Result<void> RemoveErrorHandler(ErrorHandler handler)
|
public static Result<void> RemoveErrorHandler(ErrorHandlerData.ErrorHandler handler)
|
||||||
{
|
{
|
||||||
if (Compiler.IsComptime)
|
if (Compiler.IsComptime)
|
||||||
return .Ok;
|
return .Ok;
|
||||||
|
|
||||||
using (sMonitor.Val.Enter())
|
using (ErrorHandlerData.sMonitor.Val.Enter())
|
||||||
{
|
{
|
||||||
if (sErrorHandlers.RemoveStrict(handler))
|
if (ErrorHandlerData.sErrorHandlers.RemoveStrict(handler))
|
||||||
return .Ok;
|
return .Ok;
|
||||||
}
|
}
|
||||||
return .Err;
|
return .Err;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ErrorHandlerResult CheckErrorHandlers(Error error)
|
public static function ErrorHandlerResult(AssertError.Kind kind, String error, String filePath, int lineNum) CheckAssertError;
|
||||||
|
public static function int32(char8* kind, char8* arg1, char8* arg2, int arg3) CheckErrorHandler;
|
||||||
|
|
||||||
|
static ErrorHandlerResult CheckAssertError_Impl(AssertError.Kind kind, String error, String filePath, int lineNum)
|
||||||
|
{
|
||||||
|
return CheckErrorHandlers(scope AssertError(kind, error, filePath, lineNum));
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32 CheckErrorHandler_Impl(char8* kind, char8* arg1, char8* arg2, int arg3)
|
||||||
|
{
|
||||||
|
Error error = null;
|
||||||
|
switch (StringView(kind))
|
||||||
|
{
|
||||||
|
case "FatalError":
|
||||||
|
error = scope:: FatalError() { mError = new .(arg1) };
|
||||||
|
case "LoadSharedLibrary":
|
||||||
|
error = scope:: LoadSharedLibraryError() { mPath = new .(arg1) };
|
||||||
|
case "GetSharedProcAddress":
|
||||||
|
error = scope:: GetSharedProcAddressError() { mPath = new .(arg1), mProcName = new .(arg2) };
|
||||||
|
}
|
||||||
|
if (error == null)
|
||||||
|
return 0;
|
||||||
|
return (int32)CheckErrorHandlers(error);
|
||||||
|
}
|
||||||
|
|
||||||
|
static ErrorHandlerResult CheckErrorHandlers(Error error)
|
||||||
{
|
{
|
||||||
if (Compiler.IsComptime)
|
if (Compiler.IsComptime)
|
||||||
return .ContinueFailure;
|
return .ContinueFailure;
|
||||||
|
|
||||||
using (sMonitor.Val.Enter())
|
using (ErrorHandlerData.sMonitor.Val.Enter())
|
||||||
{
|
{
|
||||||
if (sInsideErrorHandler)
|
if (ErrorHandlerData.sInsideErrorHandler)
|
||||||
return .ContinueFailure;
|
return .ContinueFailure;
|
||||||
|
|
||||||
sInsideErrorHandler = true;
|
ErrorHandlerData.sInsideErrorHandler = true;
|
||||||
defer { sInsideErrorHandler = false; }
|
defer { ErrorHandlerData.sInsideErrorHandler = false; }
|
||||||
|
|
||||||
for (int pass = 0; pass < 2; pass++)
|
for (int pass = 0; pass < 2; pass++)
|
||||||
{
|
{
|
||||||
int idx = (sErrorHandlers?.Count).GetValueOrDefault() - 1;
|
int idx = (ErrorHandlerData.sErrorHandlers?.Count).GetValueOrDefault() - 1;
|
||||||
while (idx >= 0)
|
while (idx >= 0)
|
||||||
{
|
{
|
||||||
if (idx < sErrorHandlers.Count)
|
if (idx < ErrorHandlerData.sErrorHandlers.Count)
|
||||||
{
|
{
|
||||||
var handler = sErrorHandlers[idx];
|
var handler = ErrorHandlerData.sErrorHandlers[idx];
|
||||||
var result = handler((pass == 0) ? .PreFail : .Fail, error);
|
var result = handler((pass == 0) ? .PreFail : .Fail, error);
|
||||||
if (result == .Ignore)
|
if (result == .Ignore)
|
||||||
{
|
{
|
||||||
|
@ -562,5 +628,122 @@ namespace System
|
||||||
[Intrinsic("xgetbv")]
|
[Intrinsic("xgetbv")]
|
||||||
private static extern uint64 xgetbv(uint32 xcr);
|
private static extern uint64 xgetbv(uint32 xcr);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
public static void Shutdown()
|
||||||
|
{
|
||||||
|
#if !BF_RUNTIME_REDUCED && BF_PLATFORM_WINDOWS
|
||||||
|
ShutdownCrashCatcher();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if BF_RUNTIME_DISABLE
|
||||||
|
namespace System
|
||||||
|
{
|
||||||
|
[AlwaysInclude, StaticInitPriority(1000)]
|
||||||
|
static class MinRuntime
|
||||||
|
{
|
||||||
|
static function void*(int) sMallocFunc;
|
||||||
|
static function void(void*) sFreeFunc;
|
||||||
|
|
||||||
|
static this()
|
||||||
|
{
|
||||||
|
var lib = Windows.LoadLibraryA("msvcrt.dll");
|
||||||
|
sMallocFunc = (.)Windows.GetProcAddress(lib, "malloc");
|
||||||
|
sFreeFunc = (.)Windows.GetProcAddress(lib, "free");
|
||||||
|
}
|
||||||
|
|
||||||
|
/*[LinkName(.C), AlwaysInclude]
|
||||||
|
static void __chkstk()
|
||||||
|
{
|
||||||
|
|
||||||
|
}*/
|
||||||
|
|
||||||
|
[LinkName(.C), AlwaysInclude]
|
||||||
|
static void* malloc(int size)
|
||||||
|
{
|
||||||
|
return sMallocFunc(size);
|
||||||
|
}
|
||||||
|
|
||||||
|
[LinkName(.C), AlwaysInclude]
|
||||||
|
static void free(void* ptr)
|
||||||
|
{
|
||||||
|
sFreeFunc(ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
[LinkName(.C), AlwaysInclude]
|
||||||
|
static void memset(void* dest, uint8 val, int size)
|
||||||
|
{
|
||||||
|
uint8* outPtr = (.)dest;
|
||||||
|
for (int i < size)
|
||||||
|
*(outPtr++) = val;
|
||||||
|
}
|
||||||
|
|
||||||
|
[LinkName(.C), AlwaysInclude]
|
||||||
|
static void memcpy(void* dest, void* src, int size)
|
||||||
|
{
|
||||||
|
uint8* destPtr = (.)dest;
|
||||||
|
uint8* srcPtr = (.)src;
|
||||||
|
|
||||||
|
if (destPtr < srcPtr)
|
||||||
|
{
|
||||||
|
for (int i < size)
|
||||||
|
*(destPtr++) = *(srcPtr++);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
destPtr += size;
|
||||||
|
srcPtr += size;
|
||||||
|
for (int i < size)
|
||||||
|
*(--destPtr) = *(--srcPtr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[LinkName(.C), AlwaysInclude]
|
||||||
|
static void memmove(void* dest, void* src, int size)
|
||||||
|
{
|
||||||
|
uint8* destPtr = (.)dest;
|
||||||
|
uint8* srcPtr = (.)src;
|
||||||
|
|
||||||
|
if (destPtr < srcPtr)
|
||||||
|
{
|
||||||
|
for (int i < size)
|
||||||
|
*(destPtr++) = *(srcPtr++);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
destPtr += size;
|
||||||
|
srcPtr += size;
|
||||||
|
for (int i < size)
|
||||||
|
*(--destPtr) = *(--srcPtr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[LinkName(.C), AlwaysInclude]
|
||||||
|
static double strtod(char8* str, char8** endPtr)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
[LinkName(.C), AlwaysInclude]
|
||||||
|
static extern void WinMain(void* module, void* prevModule, char8* args, int32 showCmd);
|
||||||
|
|
||||||
|
[LinkName(.C), AlwaysInclude]
|
||||||
|
static extern int32 main(int argc, char8** argv);
|
||||||
|
|
||||||
|
[LinkName(.C), AlwaysInclude]
|
||||||
|
static void mainCRTStartup()
|
||||||
|
{
|
||||||
|
//WinMain(null, null, "hi", 1);
|
||||||
|
main(0, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
[LinkName(.C), Export]
|
||||||
|
static int32 _tls_index;
|
||||||
|
|
||||||
|
[LinkName(.C), Export]
|
||||||
|
static bool _fltused;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
|
@ -330,7 +330,7 @@ namespace System
|
||||||
public override void ToString(String strBuffer)
|
public override void ToString(String strBuffer)
|
||||||
{
|
{
|
||||||
strBuffer.Append("(");
|
strBuffer.Append("(");
|
||||||
typeof(T).GetFullName(strBuffer);
|
typeof(T).ToString(strBuffer);
|
||||||
strBuffer.AppendF("*)0x{0:A}[{1}]", (uint)(void*)mPtr, mLength);
|
strBuffer.AppendF("*)0x{0:A}[{1}]", (uint)(void*)mPtr, mLength);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,8 @@ using System.Threading;
|
||||||
using System.Interop;
|
using System.Interop;
|
||||||
using System;
|
using System;
|
||||||
|
|
||||||
|
using internal System.String;
|
||||||
|
|
||||||
namespace System
|
namespace System
|
||||||
{
|
{
|
||||||
// String size type
|
// String size type
|
||||||
|
@ -46,6 +48,13 @@ namespace System
|
||||||
NullTerminate = 1
|
NullTerminate = 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal struct Interns
|
||||||
|
{
|
||||||
|
public static Monitor sMonitor = new Monitor() ~ delete _;
|
||||||
|
public static HashSet<String> sInterns = new .() ~ delete _;
|
||||||
|
public static List<String> sOwnedInterns = new .() ~ DeleteContainerAndItems!(_);
|
||||||
|
}
|
||||||
|
|
||||||
int_strsize mLength;
|
int_strsize mLength;
|
||||||
uint_strsize mAllocSizeAndFlags;
|
uint_strsize mAllocSizeAndFlags;
|
||||||
char8* mPtrOrBuffer = null;
|
char8* mPtrOrBuffer = null;
|
||||||
|
@ -53,9 +62,6 @@ namespace System
|
||||||
extern const String* sStringLiterals;
|
extern const String* sStringLiterals;
|
||||||
extern const String* sIdStringLiterals;
|
extern const String* sIdStringLiterals;
|
||||||
static String* sPrevInternLinkPtr; // For detecting changes to sStringLiterals for hot loads
|
static String* sPrevInternLinkPtr; // For detecting changes to sStringLiterals for hot loads
|
||||||
static Monitor sMonitor = new Monitor() ~ delete _;
|
|
||||||
static HashSet<String> sInterns = new .() ~ delete _;
|
|
||||||
static List<String> sOwnedInterns = new .() ~ DeleteContainerAndItems!(_);
|
|
||||||
public const String Empty = "";
|
public const String Empty = "";
|
||||||
|
|
||||||
#if BF_LARGE_STRINGS
|
#if BF_LARGE_STRINGS
|
||||||
|
@ -619,7 +625,6 @@ namespace System
|
||||||
String.Quote(Ptr, mLength, outString);
|
String.Quote(Ptr, mLength, outString);
|
||||||
}
|
}
|
||||||
|
|
||||||
[AlwaysInclude]
|
|
||||||
public char8* CStr()
|
public char8* CStr()
|
||||||
{
|
{
|
||||||
EnsureNullTerminator();
|
EnsureNullTerminator();
|
||||||
|
@ -2846,15 +2851,15 @@ namespace System
|
||||||
String str = *(ptr++);
|
String str = *(ptr++);
|
||||||
if (str == null)
|
if (str == null)
|
||||||
break;
|
break;
|
||||||
sInterns.Add(str);
|
Interns.sInterns.Add(str);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public String Intern()
|
public String Intern()
|
||||||
{
|
{
|
||||||
using (sMonitor.Enter())
|
using (Interns.sMonitor.Enter())
|
||||||
{
|
{
|
||||||
bool needsLiteralPass = sInterns.Count == 0;
|
bool needsLiteralPass = Interns.sInterns.Count == 0;
|
||||||
String* internalLinkPtr = *((String**)(sStringLiterals));
|
String* internalLinkPtr = *((String**)(sStringLiterals));
|
||||||
if (internalLinkPtr != sPrevInternLinkPtr)
|
if (internalLinkPtr != sPrevInternLinkPtr)
|
||||||
{
|
{
|
||||||
|
@ -2865,13 +2870,13 @@ namespace System
|
||||||
CheckLiterals(sStringLiterals);
|
CheckLiterals(sStringLiterals);
|
||||||
|
|
||||||
String* entryPtr;
|
String* entryPtr;
|
||||||
if (sInterns.TryAdd(this, out entryPtr))
|
if (Interns.sInterns.TryAdd(this, out entryPtr))
|
||||||
{
|
{
|
||||||
String result = new String(mLength + 1);
|
String result = new String(mLength + 1);
|
||||||
result.Append(this);
|
result.Append(this);
|
||||||
result.EnsureNullTerminator();
|
result.EnsureNullTerminator();
|
||||||
*entryPtr = result;
|
*entryPtr = result;
|
||||||
sOwnedInterns.Add(result);
|
Interns.sOwnedInterns.Add(result);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
return *entryPtr;
|
return *entryPtr;
|
||||||
|
@ -4256,9 +4261,9 @@ namespace System
|
||||||
|
|
||||||
public String Intern()
|
public String Intern()
|
||||||
{
|
{
|
||||||
using (String.[Friend]sMonitor.Enter())
|
using (String.Interns.sMonitor.Enter())
|
||||||
{
|
{
|
||||||
bool needsLiteralPass = String.[Friend]sInterns.Count == 0;
|
bool needsLiteralPass = String.Interns.sInterns.Count == 0;
|
||||||
String* internalLinkPtr = *((String**)(String.[Friend]sStringLiterals));
|
String* internalLinkPtr = *((String**)(String.[Friend]sStringLiterals));
|
||||||
if (internalLinkPtr != String.[Friend]sPrevInternLinkPtr)
|
if (internalLinkPtr != String.[Friend]sPrevInternLinkPtr)
|
||||||
{
|
{
|
||||||
|
@ -4269,13 +4274,13 @@ namespace System
|
||||||
String.[Friend]CheckLiterals(String.[Friend]sStringLiterals);
|
String.[Friend]CheckLiterals(String.[Friend]sStringLiterals);
|
||||||
|
|
||||||
String* entryPtr;
|
String* entryPtr;
|
||||||
if (String.[Friend]sInterns.TryAddAlt(this, out entryPtr))
|
if (String.Interns.sInterns.TryAddAlt(this, out entryPtr))
|
||||||
{
|
{
|
||||||
String result = new String(mLength + 1);
|
String result = new String(mLength + 1);
|
||||||
result.Append(this);
|
result.Append(this);
|
||||||
result.EnsureNullTerminator();
|
result.EnsureNullTerminator();
|
||||||
*entryPtr = result;
|
*entryPtr = result;
|
||||||
String.[Friend]sOwnedInterns.Add(result);
|
String.Interns.sOwnedInterns.Add(result);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
return *entryPtr;
|
return *entryPtr;
|
||||||
|
@ -4367,7 +4372,7 @@ namespace System
|
||||||
}
|
}
|
||||||
|
|
||||||
#if TEST
|
#if TEST
|
||||||
extension String
|
class StringTest
|
||||||
{
|
{
|
||||||
[Test]
|
[Test]
|
||||||
public static void Test_Intern()
|
public static void Test_Intern()
|
||||||
|
|
|
@ -70,7 +70,7 @@ namespace System
|
||||||
{
|
{
|
||||||
if (!condition)
|
if (!condition)
|
||||||
{
|
{
|
||||||
if (Runtime.CheckErrorHandlers(scope Runtime.AssertError(.Test, error, filePath, line)) == .Ignore)
|
if ((Runtime.CheckAssertError != null) && (Runtime.CheckAssertError(.Test, error, filePath, line) == .Ignore))
|
||||||
return;
|
return;
|
||||||
String failStr = scope .()..AppendF("Assert failed: {} at line {} in {}", error, line, filePath);
|
String failStr = scope .()..AppendF("Assert failed: {} at line {} in {}", error, line, filePath);
|
||||||
Internal.[Friend]Test_Error(failStr);
|
Internal.[Friend]Test_Error(failStr);
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
|
using System.Threading;
|
||||||
namespace System.Text
|
namespace System.Text
|
||||||
{
|
{
|
||||||
[StaticInitPriority(100)]
|
[StaticInitPriority(100)]
|
||||||
|
@ -15,11 +16,39 @@ namespace System.Text
|
||||||
case PartialEncode(int inChars, int encodedBytes);
|
case PartialEncode(int inChars, int encodedBytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static readonly ASCIIEncoding ASCII = new ASCIIEncoding() ~ delete _;
|
static Encoding sASCII ~ delete _;
|
||||||
public static readonly UTF8Encoding UTF8 = new UTF8Encoding() ~ delete _;
|
static Encoding sUTF8 ~ delete _;
|
||||||
public static readonly UTF8EncodingWithBOM UTF8WithBOM = new UTF8EncodingWithBOM() ~ delete _;
|
static Encoding sUTF8WithBOM ~ delete _;
|
||||||
public static readonly UTF16Encoding UTF16 = new UTF16Encoding() ~ delete _;
|
static Encoding sUTF16 ~ delete _;
|
||||||
public static readonly UTF16EncodingWithBOM UTF16WithBOM = new UTF16EncodingWithBOM() ~ delete _;
|
static Encoding sUTF16WithBOM ~ delete _;
|
||||||
|
|
||||||
|
static T GetEncoding<T>(ref Encoding encoding) where T : Encoding, new, delete
|
||||||
|
{
|
||||||
|
if (encoding != null)
|
||||||
|
return (.)encoding;
|
||||||
|
|
||||||
|
var newEncoding = new T();
|
||||||
|
if (Compiler.IsComptime)
|
||||||
|
{
|
||||||
|
encoding = newEncoding;
|
||||||
|
return newEncoding;
|
||||||
|
}
|
||||||
|
|
||||||
|
let prevValue = Interlocked.CompareExchange(ref encoding, null, newEncoding);
|
||||||
|
if (prevValue != null)
|
||||||
|
{
|
||||||
|
// This was already set - race condition
|
||||||
|
delete newEncoding;
|
||||||
|
return (.)prevValue;
|
||||||
|
}
|
||||||
|
return newEncoding;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ASCIIEncoding ASCII => GetEncoding<ASCIIEncoding>(ref sASCII);
|
||||||
|
public static UTF8Encoding UTF8 => GetEncoding<UTF8Encoding>(ref sUTF8);
|
||||||
|
public static UTF8EncodingWithBOM UTF8WithBOM => GetEncoding<UTF8EncodingWithBOM>(ref sUTF8WithBOM);
|
||||||
|
public static UTF16Encoding UTF16 => GetEncoding<UTF16Encoding>(ref sUTF16);
|
||||||
|
public static UTF16EncodingWithBOM UTF16WithBOM => GetEncoding<UTF16EncodingWithBOM>(ref sUTF16WithBOM);
|
||||||
|
|
||||||
public abstract int GetCharUnitSize();
|
public abstract int GetCharUnitSize();
|
||||||
public abstract int GetEncodedLength(char32 c);
|
public abstract int GetEncodedLength(char32 c);
|
||||||
|
|
|
@ -26,7 +26,7 @@ namespace System.Threading
|
||||||
static Event<delegate void()> sOnExit ~ _.Dispose();
|
static Event<delegate void()> sOnExit ~ _.Dispose();
|
||||||
Event<delegate void()> mOnExit ~ _.Dispose();
|
Event<delegate void()> mOnExit ~ _.Dispose();
|
||||||
|
|
||||||
public static Thread sMainThread = new Thread() ~ delete _;
|
public static Thread sMainThread ~ delete _;
|
||||||
|
|
||||||
[StaticInitPriority(102)]
|
[StaticInitPriority(102)]
|
||||||
struct RuntimeThreadInit
|
struct RuntimeThreadInit
|
||||||
|
@ -48,8 +48,10 @@ namespace System.Threading
|
||||||
|
|
||||||
static void Thread_SetInternalThread(Object thread, void* internalThread)
|
static void Thread_SetInternalThread(Object thread, void* internalThread)
|
||||||
{
|
{
|
||||||
|
#if BF_ENABLE_REALTIME_LEAK_CHECK
|
||||||
if (internalThread != null)
|
if (internalThread != null)
|
||||||
GC.[Friend]AddPendingThread(internalThread);
|
GC.[Friend]AddPendingThread(internalThread);
|
||||||
|
#endif
|
||||||
((Thread)thread).[Friend]mInternalThread = (int)internalThread;
|
((Thread)thread).[Friend]mInternalThread = (int)internalThread;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -118,9 +120,20 @@ namespace System.Threading
|
||||||
cb.[Friend]mThread_AutoDelete = => Thread_AutoDelete;
|
cb.[Friend]mThread_AutoDelete = => Thread_AutoDelete;
|
||||||
cb.[Friend]mThread_GetMaxStackSize = => Thread_GetMaxStackSize;
|
cb.[Friend]mThread_GetMaxStackSize = => Thread_GetMaxStackSize;
|
||||||
cb.[Friend]mThread_Exiting = => Thread_Exiting;
|
cb.[Friend]mThread_Exiting = => Thread_Exiting;
|
||||||
|
|
||||||
|
Runtime.[Friend, NoStaticCtor]sThreadInit = => Thread.Init;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void Check()
|
||||||
|
{
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static this()
|
||||||
|
{
|
||||||
|
RuntimeThreadInit.Check();
|
||||||
|
}
|
||||||
|
|
||||||
private this()
|
private this()
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -170,6 +183,7 @@ namespace System.Threading
|
||||||
{
|
{
|
||||||
#unwarn
|
#unwarn
|
||||||
RuntimeThreadInit runtimeThreadInitRef = ?;
|
RuntimeThreadInit runtimeThreadInitRef = ?;
|
||||||
|
sMainThread = new Thread();
|
||||||
sMainThread.ManualThreadInit();
|
sMainThread.ManualThreadInit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -225,11 +239,6 @@ namespace System.Threading
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extern void ManualThreadInit();
|
|
||||||
extern void StartInternal();
|
|
||||||
extern void SetStackStart(void* ptr);
|
|
||||||
extern void ThreadStarted();
|
|
||||||
|
|
||||||
public void Start(bool autoDelete = true)
|
public void Start(bool autoDelete = true)
|
||||||
{
|
{
|
||||||
mAutoDelete = autoDelete;
|
mAutoDelete = autoDelete;
|
||||||
|
@ -247,7 +256,7 @@ namespace System.Threading
|
||||||
StartInternal();
|
StartInternal();
|
||||||
}
|
}
|
||||||
|
|
||||||
#if BF_PLATFORM_WINDOWS
|
#if BF_PLATFORM_WINDOWS && !BF_RUNTIME_DISABLE
|
||||||
[CLink]
|
[CLink]
|
||||||
static extern int32 _tls_index;
|
static extern int32 _tls_index;
|
||||||
#endif
|
#endif
|
||||||
|
@ -256,7 +265,7 @@ namespace System.Threading
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
#if BF_PLATFORM_WINDOWS
|
#if BF_PLATFORM_WINDOWS && !BF_RUNTIME_DISABLE
|
||||||
return _tls_index;
|
return _tls_index;
|
||||||
#else
|
#else
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -264,10 +273,6 @@ namespace System.Threading
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static extern void RequestExitNotify();
|
|
||||||
public extern void Suspend();
|
|
||||||
public extern void Resume();
|
|
||||||
|
|
||||||
public ThreadPriority Priority
|
public ThreadPriority Priority
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
|
@ -283,12 +288,7 @@ namespace System.Threading
|
||||||
SetPriorityNative((int32)value);
|
SetPriorityNative((int32)value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
[CallingConvention(.Cdecl)]
|
|
||||||
private extern int32 GetPriorityNative();
|
|
||||||
[CallingConvention(.Cdecl)]
|
|
||||||
private extern void SetPriorityNative(int32 priority);
|
|
||||||
|
|
||||||
extern bool GetIsAlive();
|
|
||||||
public bool IsAlive
|
public bool IsAlive
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
|
@ -297,8 +297,7 @@ namespace System.Threading
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[CallingConvention(.Cdecl)]
|
|
||||||
extern bool GetIsThreadPoolThread();
|
|
||||||
public bool IsThreadPoolThread
|
public bool IsThreadPoolThread
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
|
@ -307,8 +306,6 @@ namespace System.Threading
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private extern bool JoinInternal(int32 millisecondsTimeout);
|
|
||||||
|
|
||||||
public void Join()
|
public void Join()
|
||||||
{
|
{
|
||||||
JoinInternal(Timeout.Infinite);
|
JoinInternal(Timeout.Infinite);
|
||||||
|
@ -328,7 +325,6 @@ namespace System.Threading
|
||||||
return Join((int32)tm);
|
return Join((int32)tm);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static extern void SleepInternal(int32 millisecondsTimeout);
|
|
||||||
public static void Sleep(int32 millisecondsTimeout)
|
public static void Sleep(int32 millisecondsTimeout)
|
||||||
{
|
{
|
||||||
SleepInternal(millisecondsTimeout);
|
SleepInternal(millisecondsTimeout);
|
||||||
|
@ -342,15 +338,11 @@ namespace System.Threading
|
||||||
Sleep((int32)tm);
|
Sleep((int32)tm);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static extern void SpinWaitInternal(int32 iterations);
|
|
||||||
|
|
||||||
public static void SpinWait(int iterations)
|
public static void SpinWait(int iterations)
|
||||||
{
|
{
|
||||||
SpinWaitInternal((int32)iterations);
|
SpinWaitInternal((int32)iterations);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static extern bool YieldInternal();
|
|
||||||
|
|
||||||
public static bool Yield()
|
public static bool Yield()
|
||||||
{
|
{
|
||||||
return YieldInternal();
|
return YieldInternal();
|
||||||
|
@ -364,9 +356,6 @@ namespace System.Threading
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[CallingConvention(.Cdecl)]
|
|
||||||
extern int GetThreadId();
|
|
||||||
|
|
||||||
public int Id
|
public int Id
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
|
@ -377,9 +366,6 @@ namespace System.Threading
|
||||||
|
|
||||||
public static int CurrentThreadId => Platform.BfpThread_GetCurrentId();
|
public static int CurrentThreadId => Platform.BfpThread_GetCurrentId();
|
||||||
|
|
||||||
[CallingConvention(.Cdecl)]
|
|
||||||
private static extern Thread GetCurrentThreadNative();
|
|
||||||
|
|
||||||
void SetStart(Delegate ownStartDelegate, int32 maxStackSize)
|
void SetStart(Delegate ownStartDelegate, int32 maxStackSize)
|
||||||
{
|
{
|
||||||
mDelegate = ownStartDelegate;
|
mDelegate = ownStartDelegate;
|
||||||
|
@ -405,18 +391,11 @@ namespace System.Threading
|
||||||
delete mDelegate;
|
delete mDelegate;
|
||||||
}
|
}
|
||||||
|
|
||||||
[CallingConvention(.Cdecl)]
|
|
||||||
private extern void InternalFinalize();
|
|
||||||
|
|
||||||
public bool IsBackground
|
public bool IsBackground
|
||||||
{
|
{
|
||||||
get { return IsBackgroundNative(); }
|
get { return IsBackgroundNative(); }
|
||||||
set { SetBackgroundNative(value); }
|
set { SetBackgroundNative(value); }
|
||||||
}
|
}
|
||||||
[CallingConvention(.Cdecl)]
|
|
||||||
private extern bool IsBackgroundNative();
|
|
||||||
[CallingConvention(.Cdecl)]
|
|
||||||
private extern void SetBackgroundNative(bool isBackground);
|
|
||||||
|
|
||||||
public void SetJoinOnDelete(bool joinOnDelete)
|
public void SetJoinOnDelete(bool joinOnDelete)
|
||||||
{
|
{
|
||||||
|
@ -427,8 +406,6 @@ namespace System.Threading
|
||||||
{
|
{
|
||||||
get { return (ThreadState)GetThreadStateNative(); }
|
get { return (ThreadState)GetThreadStateNative(); }
|
||||||
}
|
}
|
||||||
[CallingConvention(.Cdecl)]
|
|
||||||
private extern int32 GetThreadStateNative();
|
|
||||||
|
|
||||||
public void SetName(String name)
|
public void SetName(String name)
|
||||||
{
|
{
|
||||||
|
@ -450,7 +427,63 @@ namespace System.Threading
|
||||||
if (mName != null)
|
if (mName != null)
|
||||||
outName.Append(mName);
|
outName.Append(mName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if !BF_RUNTIME_DISABLE
|
||||||
[CallingConvention(.Cdecl)]
|
[CallingConvention(.Cdecl)]
|
||||||
private extern void InformThreadNameChange(String name);
|
private extern void InformThreadNameChange(String name);
|
||||||
|
[CallingConvention(.Cdecl)]
|
||||||
|
private extern bool IsBackgroundNative();
|
||||||
|
[CallingConvention(.Cdecl)]
|
||||||
|
private extern void SetBackgroundNative(bool isBackground);
|
||||||
|
[CallingConvention(.Cdecl)]
|
||||||
|
private extern void InternalFinalize();
|
||||||
|
[CallingConvention(.Cdecl)]
|
||||||
|
private static extern Thread GetCurrentThreadNative();
|
||||||
|
[CallingConvention(.Cdecl)]
|
||||||
|
private extern int32 GetPriorityNative();
|
||||||
|
[CallingConvention(.Cdecl)]
|
||||||
|
private extern void SetPriorityNative(int32 priority);
|
||||||
|
[CallingConvention(.Cdecl)]
|
||||||
|
extern bool GetIsThreadPoolThread();
|
||||||
|
[CallingConvention(.Cdecl)]
|
||||||
|
extern int GetThreadId();
|
||||||
|
[CallingConvention(.Cdecl)]
|
||||||
|
private extern int32 GetThreadStateNative();
|
||||||
|
private static extern void SpinWaitInternal(int32 iterations);
|
||||||
|
private static extern void SleepInternal(int32 millisecondsTimeout);
|
||||||
|
private extern bool JoinInternal(int32 millisecondsTimeout);
|
||||||
|
private static extern bool YieldInternal();
|
||||||
|
extern void ManualThreadInit();
|
||||||
|
extern void StartInternal();
|
||||||
|
extern void SetStackStart(void* ptr);
|
||||||
|
extern void ThreadStarted();
|
||||||
|
public static extern void RequestExitNotify();
|
||||||
|
public extern void Suspend();
|
||||||
|
public extern void Resume();
|
||||||
|
extern bool GetIsAlive();
|
||||||
|
#else
|
||||||
|
private void InformThreadNameChange(String name) {}
|
||||||
|
private bool IsBackgroundNative() => false;
|
||||||
|
private void SetBackgroundNative(bool isBackground) {}
|
||||||
|
private void InternalFinalize() {}
|
||||||
|
private static Thread GetCurrentThreadNative() => null;
|
||||||
|
private int32 GetPriorityNative() => 0;
|
||||||
|
private void SetPriorityNative(int32 priority) {}
|
||||||
|
bool GetIsThreadPoolThread() => false;
|
||||||
|
int GetThreadId() => 0;
|
||||||
|
private int32 GetThreadStateNative() => 0;
|
||||||
|
private static void SpinWaitInternal(int32 iterations) {}
|
||||||
|
private static void SleepInternal(int32 millisecondsTimeout) {}
|
||||||
|
private bool JoinInternal(int32 millisecondsTimeout) => false;
|
||||||
|
private static bool YieldInternal() => false;
|
||||||
|
void ManualThreadInit() {}
|
||||||
|
void StartInternal() {}
|
||||||
|
void SetStackStart(void* ptr) {}
|
||||||
|
void ThreadStarted() {}
|
||||||
|
public static void RequestExitNotify() {}
|
||||||
|
public void Suspend() {}
|
||||||
|
public void Resume() {}
|
||||||
|
bool GetIsAlive() => false;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,12 +7,15 @@ namespace System
|
||||||
{
|
{
|
||||||
struct ClassVData
|
struct ClassVData
|
||||||
{
|
{
|
||||||
public Type mType;
|
public int mType;
|
||||||
|
#if BF_32_BIT
|
||||||
|
public int mType2;
|
||||||
|
#endif
|
||||||
// The rest of this structured is generated by the compiler,
|
// The rest of this structured is generated by the compiler,
|
||||||
// including the vtable and interface slots
|
// including the vtable and interface slots
|
||||||
}
|
}
|
||||||
|
|
||||||
[Ordered, AlwaysInclude(AssumeInstantiated=true)]
|
[Ordered, AlwaysInclude, Reflect(.Type)]
|
||||||
public class Type
|
public class Type
|
||||||
{
|
{
|
||||||
extern const Type* sTypes;
|
extern const Type* sTypes;
|
||||||
|
@ -746,7 +749,12 @@ namespace System
|
||||||
|
|
||||||
public override void ToString(String strBuffer)
|
public override void ToString(String strBuffer)
|
||||||
{
|
{
|
||||||
|
#if !BF_REFLECT_MINIMAL
|
||||||
GetFullName(strBuffer);
|
GetFullName(strBuffer);
|
||||||
|
#else
|
||||||
|
strBuffer.Append("Type#");
|
||||||
|
mTypeId.ToString(strBuffer);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
public struct Enumerator : IEnumerator<Type>
|
public struct Enumerator : IEnumerator<Type>
|
||||||
|
@ -890,6 +898,7 @@ namespace System.Reflection
|
||||||
public int32 mCustomAttributesIdx;
|
public int32 mCustomAttributesIdx;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[CRepr, AlwaysInclude]
|
||||||
public struct InterfaceData
|
public struct InterfaceData
|
||||||
{
|
{
|
||||||
public TypeId mInterfaceType;
|
public TypeId mInterfaceType;
|
||||||
|
@ -1272,7 +1281,7 @@ namespace System.Reflection
|
||||||
if (size == -1)
|
if (size == -1)
|
||||||
strBuffer.Append("[?]");
|
strBuffer.Append("[?]");
|
||||||
else
|
else
|
||||||
strBuffer.AppendF($"[{size}]");
|
strBuffer.AppendF($"[{(Int.Simple)size}]");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,6 +11,14 @@ namespace System
|
||||||
case InvalidChar(uint partialResult);
|
case InvalidChar(uint partialResult);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public struct Simple : uint
|
||||||
|
{
|
||||||
|
public override void ToString(String strBuffer)
|
||||||
|
{
|
||||||
|
((uint)this).ToString(strBuffer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public const uint MaxValue = (sizeof(uint) == 8) ? 0xFFFFFFFFFFFFFFFFUL : 0xFFFFFFFFL;
|
public const uint MaxValue = (sizeof(uint) == 8) ? 0xFFFFFFFFFFFFFFFFUL : 0xFFFFFFFFL;
|
||||||
public const uint MinValue = 0;
|
public const uint MinValue = 0;
|
||||||
|
|
||||||
|
|
|
@ -58,8 +58,6 @@ namespace System
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static String sHexUpperChars = "0123456789ABCDEF";
|
|
||||||
static String sHexLowerChars = "0123456789abcdef";
|
|
||||||
public void ToString(String outString, String format, IFormatProvider formatProvider)
|
public void ToString(String outString, String format, IFormatProvider formatProvider)
|
||||||
{
|
{
|
||||||
if(format == null || format.IsEmpty)
|
if(format == null || format.IsEmpty)
|
||||||
|
|
|
@ -90,7 +90,7 @@ namespace bf
|
||||||
bf::System::Object* (*Object_DynamicCastToTypeId)(bf::System::Object* obj, int typeId);
|
bf::System::Object* (*Object_DynamicCastToTypeId)(bf::System::Object* obj, int typeId);
|
||||||
void(*Type_GetFullName)(System::Type* type, bf::System::String* str);
|
void(*Type_GetFullName)(System::Type* type, bf::System::String* str);
|
||||||
bf::System::String* (*String_Alloc)();
|
bf::System::String* (*String_Alloc)();
|
||||||
const char* (*String_ToCStr)(bf::System::String* str);
|
Beefy::StringView (*String_ToStringView)(bf::System::String* str);
|
||||||
bf::System::Threading::Thread* (*Thread_Alloc)();
|
bf::System::Threading::Thread* (*Thread_Alloc)();
|
||||||
bf::System::Threading::Thread* (*Thread_GetMainThread)();
|
bf::System::Threading::Thread* (*Thread_GetMainThread)();
|
||||||
void(*Thread_ThreadProc)(bf::System::Threading::Thread* thread);
|
void(*Thread_ThreadProc)(bf::System::Threading::Thread* thread);
|
||||||
|
@ -116,6 +116,8 @@ namespace bf
|
||||||
|
|
||||||
private:
|
private:
|
||||||
BFRT_EXPORT static void Init(int version, int flags, BfRtCallbacks* callbacks);
|
BFRT_EXPORT static void Init(int version, int flags, BfRtCallbacks* callbacks);
|
||||||
|
BFRT_EXPORT static void InitCrashCatcher(int flags);
|
||||||
|
BFRT_EXPORT static void ShutdownCrashCatcher();
|
||||||
BFRT_EXPORT static void AddCrashInfoFunc(void* func);
|
BFRT_EXPORT static void AddCrashInfoFunc(void* func);
|
||||||
BFRT_EXPORT static void SetErrorString(char* errorStr);
|
BFRT_EXPORT static void SetErrorString(char* errorStr);
|
||||||
BFRT_EXPORT static void Dbg_Init(int version, int flags, BfRtCallbacks* callbacks);
|
BFRT_EXPORT static void Dbg_Init(int version, int flags, BfRtCallbacks* callbacks);
|
||||||
|
@ -252,9 +254,9 @@ namespace bf
|
||||||
uint mAllocSizeAndFlags;
|
uint mAllocSizeAndFlags;
|
||||||
char* mPtr;
|
char* mPtr;
|
||||||
|
|
||||||
const char* CStr()
|
Beefy::StringView ToStringView()
|
||||||
{
|
{
|
||||||
return BFRTCALLBACKS.String_ToCStr(this);
|
return BFRTCALLBACKS.String_ToStringView(this);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,6 +52,7 @@
|
||||||
USING_NS_BF;
|
USING_NS_BF;
|
||||||
|
|
||||||
static Beefy::StringT<0> gCmdLineString;
|
static Beefy::StringT<0> gCmdLineString;
|
||||||
|
bool gCmdLineStringHandled;
|
||||||
bf::System::Runtime::BfRtCallbacks gBfRtCallbacks;
|
bf::System::Runtime::BfRtCallbacks gBfRtCallbacks;
|
||||||
BfRtFlags gBfRtFlags = (BfRtFlags)0;
|
BfRtFlags gBfRtFlags = (BfRtFlags)0;
|
||||||
|
|
||||||
|
@ -65,7 +66,10 @@ static int gTestMethodIdx = -1;
|
||||||
static uint32 gTestStartTick = 0;
|
static uint32 gTestStartTick = 0;
|
||||||
static bool gTestBreakOnFailure = false;
|
static bool gTestBreakOnFailure = false;
|
||||||
|
|
||||||
|
typedef void(*ClientPipeErrorFunc)(const Beefy::StringView& error, int stackOffset);
|
||||||
|
|
||||||
static BfpFile* gClientPipe = NULL;
|
static BfpFile* gClientPipe = NULL;
|
||||||
|
static ClientPipeErrorFunc gClientPipeErrorFunc;
|
||||||
static Beefy::String gTestInBuffer;
|
static Beefy::String gTestInBuffer;
|
||||||
|
|
||||||
namespace bf
|
namespace bf
|
||||||
|
@ -85,7 +89,7 @@ namespace bf
|
||||||
|
|
||||||
BFRT_EXPORT static void BfStaticCtor();
|
BFRT_EXPORT static void BfStaticCtor();
|
||||||
BFRT_EXPORT static void BfStaticDtor();
|
BFRT_EXPORT static void BfStaticDtor();
|
||||||
BFRT_EXPORT static void Shutdown();
|
BFRT_EXPORT static void Shutdown_Internal();
|
||||||
public:
|
public:
|
||||||
BFRT_EXPORT static Object* UnsafeCastToObject(void* inPtr);
|
BFRT_EXPORT static Object* UnsafeCastToObject(void* inPtr);
|
||||||
BFRT_EXPORT static void* UnsafeCastToPtr(Object* obj);
|
BFRT_EXPORT static void* UnsafeCastToPtr(Object* obj);
|
||||||
|
@ -224,18 +228,8 @@ static void Internal_FatalError(const char* error)
|
||||||
if (gBfRtCallbacks.CheckErrorHandler != NULL)
|
if (gBfRtCallbacks.CheckErrorHandler != NULL)
|
||||||
gBfRtCallbacks.CheckErrorHandler("FatalError", error, NULL, 0);
|
gBfRtCallbacks.CheckErrorHandler("FatalError", error, NULL, 0);
|
||||||
|
|
||||||
if ((gClientPipe != NULL) && (!gTestBreakOnFailure))
|
if (gClientPipeErrorFunc != NULL)
|
||||||
{
|
gClientPipeErrorFunc(error, 0);
|
||||||
Beefy::String str = ":TestFatal\t";
|
|
||||||
str += error;
|
|
||||||
str.Replace('\n', '\r');
|
|
||||||
str += "\n";
|
|
||||||
TestString(str);
|
|
||||||
|
|
||||||
Beefy::String result;
|
|
||||||
TestReadCmd(result);
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
BfpSystem_FatalError(error, "BEEF FATAL ERROR");
|
BfpSystem_FatalError(error, "BEEF FATAL ERROR");
|
||||||
}
|
}
|
||||||
|
@ -304,57 +298,22 @@ void bf::System::Runtime::Init(int version, int flags, BfRtCallbacks* callbacks)
|
||||||
if ((flags & 4) != 0)
|
if ((flags & 4) != 0)
|
||||||
sysInitFlags = (BfpSystemInitFlags)(sysInitFlags | BfpSystemInitFlag_SilentCrash);
|
sysInitFlags = (BfpSystemInitFlags)(sysInitFlags | BfpSystemInitFlag_SilentCrash);
|
||||||
BfpSystem_Init(BFP_VERSION, sysInitFlags);
|
BfpSystem_Init(BFP_VERSION, sysInitFlags);
|
||||||
BfpSystem_AddCrashInfoFunc(GetCrashInfo);
|
|
||||||
|
|
||||||
if (gBfRtCallbacks.Alloc != NULL)
|
if (gBfRtCallbacks.Alloc != NULL)
|
||||||
{
|
{
|
||||||
Internal_FatalError(StrFormat("BeefRT already initialized. Multiple executable modules in the same process cannot dynamically link to the Beef runtime.").c_str());
|
Internal_FatalError("BeefRT already initialized. Multiple executable modules in the same process cannot dynamically link to the Beef runtime.");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (version != BFRT_VERSION)
|
if (version != BFRT_VERSION)
|
||||||
{
|
{
|
||||||
BfpSystem_FatalError(StrFormat("BeefRT build version '%d' does not match requested version '%d'", BFRT_VERSION, version).c_str(), "BEEF FATAL ERROR");
|
char error[256];
|
||||||
|
sprintf(error, "BeefRT build version '%d' does not match requested version '%d'", BFRT_VERSION, version);
|
||||||
|
BfpSystem_FatalError(error, "BEEF FATAL ERROR");
|
||||||
}
|
}
|
||||||
|
|
||||||
gBfRtCallbacks = *callbacks;
|
gBfRtCallbacks = *callbacks;
|
||||||
gBfRtFlags = (BfRtFlags)flags;
|
gBfRtFlags = (BfRtFlags)flags;
|
||||||
|
|
||||||
Beefy::String cmdLine;
|
|
||||||
|
|
||||||
BfpSystemResult result;
|
|
||||||
BFP_GETSTR_HELPER(cmdLine, result, BfpSystem_GetCommandLine(__STR, __STRLEN, &result));
|
|
||||||
|
|
||||||
char* cmdLineStr = (char*)cmdLine.c_str();
|
|
||||||
|
|
||||||
//::MessageBoxA(NULL, cmdLineStr, "BFRT", 0);
|
|
||||||
|
|
||||||
char* useCmdLineStr = cmdLineStr;
|
|
||||||
|
|
||||||
if (cmdLineStr[0] != 0)
|
|
||||||
{
|
|
||||||
bool nameQuoted = cmdLineStr[0] == '\"';
|
|
||||||
|
|
||||||
Beefy::String passedName;
|
|
||||||
int i;
|
|
||||||
for (i = (nameQuoted ? 1 : 0); cmdLineStr[i] != 0; i++)
|
|
||||||
{
|
|
||||||
wchar_t c = cmdLineStr[i];
|
|
||||||
|
|
||||||
if (((nameQuoted) && (c == '"')) ||
|
|
||||||
((!nameQuoted) && (c == ' ')))
|
|
||||||
{
|
|
||||||
i++;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
passedName += cmdLineStr[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
useCmdLineStr += i;
|
|
||||||
while (*useCmdLineStr == L' ')
|
|
||||||
useCmdLineStr++;
|
|
||||||
}
|
|
||||||
gCmdLineString = useCmdLineStr;
|
|
||||||
|
|
||||||
#ifdef BF_PLATFORM_WINDOWS
|
#ifdef BF_PLATFORM_WINDOWS
|
||||||
gBfTLSKey = FlsAlloc(TlsFreeFunc);
|
gBfTLSKey = FlsAlloc(TlsFreeFunc);
|
||||||
#else
|
#else
|
||||||
|
@ -362,6 +321,20 @@ void bf::System::Runtime::Init(int version, int flags, BfRtCallbacks* callbacks)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void bf::System::Runtime::InitCrashCatcher(int flags)
|
||||||
|
{
|
||||||
|
BfpSystemInitFlags sysInitFlags = BfpSystemInitFlag_InstallCrashCatcher;
|
||||||
|
if ((flags & 4) != 0)
|
||||||
|
sysInitFlags = (BfpSystemInitFlags)(sysInitFlags | BfpSystemInitFlag_SilentCrash);
|
||||||
|
BfpSystem_InitCrashCatcher(sysInitFlags);
|
||||||
|
BfpSystem_AddCrashInfoFunc(GetCrashInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
void bf::System::Runtime::ShutdownCrashCatcher()
|
||||||
|
{
|
||||||
|
BfpSystem_ShutdownCrashCatcher();
|
||||||
|
}
|
||||||
|
|
||||||
void bf::System::Runtime::SetErrorString(char* errorStr)
|
void bf::System::Runtime::SetErrorString(char* errorStr)
|
||||||
{
|
{
|
||||||
::SetErrorString(errorStr);
|
::SetErrorString(errorStr);
|
||||||
|
@ -379,7 +352,7 @@ void bf::System::Runtime::SetCrashReportKind(bf::System::Runtime::RtCrashReportK
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
void Internal::Shutdown()
|
void Internal::Shutdown_Internal()
|
||||||
{
|
{
|
||||||
BfInternalThread::WaitForAllDone();
|
BfInternalThread::WaitForAllDone();
|
||||||
if (gBfRtCallbacks.GC_Shutdown != NULL)
|
if (gBfRtCallbacks.GC_Shutdown != NULL)
|
||||||
|
@ -419,20 +392,9 @@ void* Internal::UnsafeCastToPtr(Object* obj)
|
||||||
|
|
||||||
void Internal::ThrowIndexOutOfRange(intptr stackOffset)
|
void Internal::ThrowIndexOutOfRange(intptr stackOffset)
|
||||||
{
|
{
|
||||||
if (gClientPipe != NULL)
|
if (gClientPipeErrorFunc != NULL)
|
||||||
{
|
gClientPipeErrorFunc("Index out of range", 0);
|
||||||
if (gTestBreakOnFailure)
|
else if ((stackOffset != -1) && (::IsDebuggerPresent()))
|
||||||
{
|
|
||||||
SETUP_ERROR("Index out of range", (int)(2 + stackOffset));
|
|
||||||
BF_DEBUG_BREAK();
|
|
||||||
}
|
|
||||||
|
|
||||||
Beefy::String str = ":TestFail\tIndex out of range\n";
|
|
||||||
TestString(str);
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((stackOffset != -1) && (::IsDebuggerPresent()))
|
|
||||||
{
|
{
|
||||||
SETUP_ERROR("Index out of range", (int)(2 + stackOffset));
|
SETUP_ERROR("Index out of range", (int)(2 + stackOffset));
|
||||||
BF_DEBUG_BREAK();
|
BF_DEBUG_BREAK();
|
||||||
|
@ -443,20 +405,9 @@ void Internal::ThrowIndexOutOfRange(intptr stackOffset)
|
||||||
|
|
||||||
void Internal::ThrowObjectNotInitialized(intptr stackOffset)
|
void Internal::ThrowObjectNotInitialized(intptr stackOffset)
|
||||||
{
|
{
|
||||||
if (gClientPipe != NULL)
|
if (gClientPipeErrorFunc != NULL)
|
||||||
{
|
gClientPipeErrorFunc("Object not initialized", 0);
|
||||||
if (gTestBreakOnFailure)
|
else if ((stackOffset != -1) && (::IsDebuggerPresent()))
|
||||||
{
|
|
||||||
SETUP_ERROR("Object not initialized", (int)(2 + stackOffset));
|
|
||||||
BF_DEBUG_BREAK();
|
|
||||||
}
|
|
||||||
|
|
||||||
Beefy::String str = ":TestFail\tObject not initialized\n";
|
|
||||||
TestString(str);
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((stackOffset != -1) && (::IsDebuggerPresent()))
|
|
||||||
{
|
{
|
||||||
SETUP_ERROR("Object not initialized", (int)(2 + stackOffset));
|
SETUP_ERROR("Object not initialized", (int)(2 + stackOffset));
|
||||||
BF_DEBUG_BREAK();
|
BF_DEBUG_BREAK();
|
||||||
|
@ -467,29 +418,17 @@ void Internal::ThrowObjectNotInitialized(intptr stackOffset)
|
||||||
|
|
||||||
void Internal::FatalError(bf::System::String* error, intptr stackOffset)
|
void Internal::FatalError(bf::System::String* error, intptr stackOffset)
|
||||||
{
|
{
|
||||||
if (gClientPipe != NULL)
|
Beefy::StringView errorStringView = error->ToStringView();
|
||||||
{
|
Beefy::StringSimple errorString = errorStringView;
|
||||||
if (gTestBreakOnFailure)
|
if (gClientPipeErrorFunc != NULL)
|
||||||
{
|
gClientPipeErrorFunc(errorStringView, 0);
|
||||||
SETUP_ERROR(error->CStr(), (int)(2 + stackOffset));
|
|
||||||
BF_DEBUG_BREAK();
|
|
||||||
}
|
|
||||||
|
|
||||||
Beefy::String str = ":TestFail\t";
|
|
||||||
str += error->CStr();
|
|
||||||
str.Replace('\n', '\r');
|
|
||||||
str += "\n";
|
|
||||||
TestString(str);
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((stackOffset != -1) && (::IsDebuggerPresent()))
|
if ((stackOffset != -1) && (::IsDebuggerPresent()))
|
||||||
{
|
{
|
||||||
SETUP_ERROR(error->CStr(), (int)(2 + stackOffset));
|
SETUP_ERROR(errorString.c_str(), (int)(2 + stackOffset));
|
||||||
BF_DEBUG_BREAK();
|
BF_DEBUG_BREAK();
|
||||||
}
|
}
|
||||||
|
|
||||||
Internal_FatalError(error->CStr());
|
Internal_FatalError(errorString.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
void Internal::MemCpy(void* dest, void* src, intptr length)
|
void Internal::MemCpy(void* dest, void* src, intptr length)
|
||||||
|
@ -630,6 +569,46 @@ void Internal::GetSharedProcAddressInto(void* libHandle, char* procName, void**
|
||||||
|
|
||||||
char* Internal::GetCommandLineArgs()
|
char* Internal::GetCommandLineArgs()
|
||||||
{
|
{
|
||||||
|
if (!gCmdLineStringHandled)
|
||||||
|
{
|
||||||
|
Beefy::String cmdLine;
|
||||||
|
|
||||||
|
BfpSystemResult result;
|
||||||
|
BFP_GETSTR_HELPER(cmdLine, result, BfpSystem_GetCommandLine(__STR, __STRLEN, &result));
|
||||||
|
|
||||||
|
char* cmdLineStr = (char*)cmdLine.c_str();
|
||||||
|
|
||||||
|
//::MessageBoxA(NULL, cmdLineStr, "BFRT", 0);
|
||||||
|
|
||||||
|
char* useCmdLineStr = cmdLineStr;
|
||||||
|
|
||||||
|
if (cmdLineStr[0] != 0)
|
||||||
|
{
|
||||||
|
bool nameQuoted = cmdLineStr[0] == '\"';
|
||||||
|
|
||||||
|
Beefy::String passedName;
|
||||||
|
int i;
|
||||||
|
for (i = (nameQuoted ? 1 : 0); cmdLineStr[i] != 0; i++)
|
||||||
|
{
|
||||||
|
wchar_t c = cmdLineStr[i];
|
||||||
|
|
||||||
|
if (((nameQuoted) && (c == '"')) ||
|
||||||
|
((!nameQuoted) && (c == ' ')))
|
||||||
|
{
|
||||||
|
i++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
passedName += cmdLineStr[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
useCmdLineStr += i;
|
||||||
|
while (*useCmdLineStr == L' ')
|
||||||
|
useCmdLineStr++;
|
||||||
|
}
|
||||||
|
gCmdLineString = useCmdLineStr;
|
||||||
|
gCmdLineStringHandled = true;
|
||||||
|
}
|
||||||
|
|
||||||
return (char*)gCmdLineString.c_str();
|
return (char*)gCmdLineString.c_str();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -697,6 +676,27 @@ static void TestReadCmd(Beefy::String& str)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TestFailed(const Beefy::StringView& error, int stackOffset)
|
||||||
|
{
|
||||||
|
if (gClientPipe != NULL)
|
||||||
|
{
|
||||||
|
Beefy::String errorString = error;
|
||||||
|
|
||||||
|
if (gTestBreakOnFailure)
|
||||||
|
{
|
||||||
|
SETUP_ERROR(errorString.c_str(), (int)(2 + stackOffset));
|
||||||
|
BF_DEBUG_BREAK();
|
||||||
|
}
|
||||||
|
|
||||||
|
Beefy::String str = ":TestFail\t";
|
||||||
|
str += errorString.c_str();
|
||||||
|
str.Replace('\n', '\r');
|
||||||
|
str += "\n";
|
||||||
|
TestString(str);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Internal::Test_Init(char* testData)
|
void Internal::Test_Init(char* testData)
|
||||||
{
|
{
|
||||||
BfpSystem_SetCrashReportKind(BfpCrashReportKind_None);
|
BfpSystem_SetCrashReportKind(BfpCrashReportKind_None);
|
||||||
|
@ -708,6 +708,8 @@ void Internal::Test_Init(char* testData)
|
||||||
if (fileResult != BfpFileResult_Ok)
|
if (fileResult != BfpFileResult_Ok)
|
||||||
BF_FATAL("Test_Init failed to create pipe to test manager");
|
BF_FATAL("Test_Init failed to create pipe to test manager");
|
||||||
|
|
||||||
|
gClientPipeErrorFunc = TestFailed;
|
||||||
|
|
||||||
Beefy::String outStr;
|
Beefy::String outStr;
|
||||||
outStr += ":TestInit\n";
|
outStr += ":TestInit\n";
|
||||||
outStr += testData;
|
outStr += testData;
|
||||||
|
@ -853,7 +855,6 @@ void Internal::ObjectDynCheck(bf::System::Object* object, int typeId, bool allow
|
||||||
if (result == NULL)
|
if (result == NULL)
|
||||||
{
|
{
|
||||||
Beefy::String errorStr = "Attempting invalid cast on object";
|
Beefy::String errorStr = "Attempting invalid cast on object";
|
||||||
//errorStr += StrFormat("\x1LEAK\t0x%@\n (%s)0x%@\n", object, object->GetTypeName().c_str(), object);
|
|
||||||
errorStr += StrFormat("\x1LEAK\t0x%@\n (%s)0x%@\n", object, "System.Object", object);
|
errorStr += StrFormat("\x1LEAK\t0x%@\n (%s)0x%@\n", object, "System.Object", object);
|
||||||
SETUP_ERROR(errorStr.c_str(), 2);
|
SETUP_ERROR(errorStr.c_str(), 2);
|
||||||
BF_DEBUG_BREAK();
|
BF_DEBUG_BREAK();
|
||||||
|
|
|
@ -7,7 +7,7 @@ Beefy::String bf::System::Object::GetTypeName()
|
||||||
String* strObj = BFRTCALLBACKS.String_Alloc();
|
String* strObj = BFRTCALLBACKS.String_Alloc();
|
||||||
Type* type = _GetType();
|
Type* type = _GetType();
|
||||||
BFRTCALLBACKS.Type_GetFullName(type, strObj);
|
BFRTCALLBACKS.Type_GetFullName(type, strObj);
|
||||||
Beefy::String str = strObj->CStr();
|
Beefy::String str = strObj->ToStringView();
|
||||||
BFRTCALLBACKS.Object_Delete(strObj);
|
BFRTCALLBACKS.Object_Delete(strObj);
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
@ -16,7 +16,7 @@ Beefy::String bf::System::Type::GetFullName()
|
||||||
{
|
{
|
||||||
String* strObj = BFRTCALLBACKS.String_Alloc();
|
String* strObj = BFRTCALLBACKS.String_Alloc();
|
||||||
BFRTCALLBACKS.Type_GetFullName(this, strObj);
|
BFRTCALLBACKS.Type_GetFullName(this, strObj);
|
||||||
Beefy::String str = strObj->CStr();
|
Beefy::String str = strObj->ToStringView();
|
||||||
BFRTCALLBACKS.Object_Delete(strObj);
|
BFRTCALLBACKS.Object_Delete(strObj);
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
|
@ -318,7 +318,10 @@ int Thread::GetThreadStateNative()
|
||||||
|
|
||||||
void Thread::InformThreadNameChange(String* name)
|
void Thread::InformThreadNameChange(String* name)
|
||||||
{
|
{
|
||||||
BfpThread_SetName(GetInternalThread()->mThreadHandle, (name != NULL) ? name->CStr() : "", NULL);
|
Beefy::String nameStr;
|
||||||
|
if (name != NULL)
|
||||||
|
nameStr = name->ToStringView();
|
||||||
|
BfpThread_SetName(GetInternalThread()->mThreadHandle, nameStr.c_str(), NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Thread::MemoryBarrier()
|
void Thread::MemoryBarrier()
|
||||||
|
|
|
@ -100,12 +100,14 @@ enum BfpCrashReportKind
|
||||||
};
|
};
|
||||||
|
|
||||||
BFP_EXPORT void BFP_CALLTYPE BfpSystem_Init(int version, BfpSystemInitFlags flags);
|
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_SetCommandLine(int argc, char** argv);
|
||||||
BFP_EXPORT void BFP_CALLTYPE BfpSystem_SetCrashReportKind(BfpCrashReportKind crashReportKind);
|
BFP_EXPORT void BFP_CALLTYPE BfpSystem_SetCrashReportKind(BfpCrashReportKind crashReportKind);
|
||||||
BFP_EXPORT void BFP_CALLTYPE BfpSystem_AddCrashInfoFunc(BfpCrashInfoFunc crashInfoFunc);
|
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_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_SetCrashRelaunchCmd(const char* str);
|
||||||
BFP_EXPORT void BFP_CALLTYPE BfpSystem_Shutdown();
|
BFP_EXPORT void BFP_CALLTYPE BfpSystem_Shutdown();
|
||||||
|
BFP_EXPORT void BFP_CALLTYPE BfpSystem_ShutdownCrashCatcher();
|
||||||
BFP_EXPORT uint32 BFP_CALLTYPE BfpSystem_TickCount();
|
BFP_EXPORT uint32 BFP_CALLTYPE BfpSystem_TickCount();
|
||||||
BFP_EXPORT BfpTimeStamp BFP_CALLTYPE BfpSystem_GetTimeStamp();
|
BFP_EXPORT BfpTimeStamp BFP_CALLTYPE BfpSystem_GetTimeStamp();
|
||||||
BFP_EXPORT uint16 BFP_CALLTYPE BfpSystem_EndianSwap16(uint16 val);
|
BFP_EXPORT uint16 BFP_CALLTYPE BfpSystem_EndianSwap16(uint16 val);
|
||||||
|
|
|
@ -52,7 +52,6 @@ static SYMGETMODULEBASEPROC gSymGetModuleBase = NULL;
|
||||||
static SYMGETSYMFROMADDRPROC gSymGetSymFromAddr = NULL;
|
static SYMGETSYMFROMADDRPROC gSymGetSymFromAddr = NULL;
|
||||||
static SYMGETLINEFROMADDR gSymGetLineFromAddr = NULL;
|
static SYMGETLINEFROMADDR gSymGetLineFromAddr = NULL;
|
||||||
|
|
||||||
|
|
||||||
static bool CreateMiniDump(EXCEPTION_POINTERS* pep, const StringImpl& filePath);
|
static bool CreateMiniDump(EXCEPTION_POINTERS* pep, const StringImpl& filePath);
|
||||||
|
|
||||||
static bool LoadImageHelp()
|
static bool LoadImageHelp()
|
||||||
|
@ -117,47 +116,6 @@ static bool LoadImageHelp()
|
||||||
return true;
|
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 gDebugButtonWindow = NULL;
|
||||||
static HWND gYesButtonWindow = NULL;
|
static HWND gYesButtonWindow = NULL;
|
||||||
static HWND gNoButtonWindow = 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;
|
gUseDefaultFonts = aVersionInfo.dwPlatformId != VER_PLATFORM_WIN32_NT;
|
||||||
|
|
||||||
int aHeight = -MulDiv(8, 96, 72);
|
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,
|
false, ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY,
|
||||||
DEFAULT_PITCH | FF_DONTCARE, "Tahoma");
|
DEFAULT_PITCH | FF_DONTCARE, "Tahoma");
|
||||||
|
|
||||||
aHeight = -MulDiv(10, 96, 72);
|
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,
|
false, ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY,
|
||||||
DEFAULT_PITCH | FF_DONTCARE, "Tahoma");
|
DEFAULT_PITCH | FF_DONTCARE, "Tahoma");
|
||||||
|
|
||||||
::SetCursor(::LoadCursor(NULL, IDC_ARROW));
|
::SetCursor(::LoadCursor(NULL, IDC_ARROW));
|
||||||
|
|
||||||
gErrorTitle = errorTitle;
|
String gErrorTitle = errorTitle;
|
||||||
gErrorText = errorText;
|
String gErrorText = errorText;
|
||||||
|
|
||||||
WNDCLASSW wc;
|
WNDCLASSW wc;
|
||||||
wc.style = 0;
|
wc.style = 0;
|
||||||
|
@ -935,6 +893,44 @@ static void DoHandleDebugEvent(LPEXCEPTION_POINTERS lpEP)
|
||||||
|
|
||||||
///////////////////////////
|
///////////////////////////
|
||||||
// first name the exception
|
// 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;
|
char *szName = NULL;
|
||||||
for (int i = 0; gMsgTable[i].dwExceptionCode != 0xFFFFFFFF; i++)
|
for (int i = 0; gMsgTable[i].dwExceptionCode != 0xFFFFFFFF; i++)
|
||||||
{
|
{
|
||||||
|
|
|
@ -39,9 +39,14 @@
|
||||||
|
|
||||||
USING_NS_BF;
|
USING_NS_BF;
|
||||||
|
|
||||||
|
static void Crash_Error(const char* msg);
|
||||||
|
|
||||||
|
typedef void(*BfpCrashErrorFunc)(const char* str);
|
||||||
|
|
||||||
static bool gTimerInitialized = false;
|
static bool gTimerInitialized = false;
|
||||||
static int gTimerDivisor = 0;
|
static int gTimerDivisor = 0;
|
||||||
CritSect gBfpCritSect;
|
CritSect gBfpCritSect;
|
||||||
|
BfpCrashErrorFunc gCrashErrorFunc = Crash_Error;
|
||||||
|
|
||||||
struct WindowsSharedInfo
|
struct WindowsSharedInfo
|
||||||
{
|
{
|
||||||
|
@ -415,8 +420,9 @@ void Beefy::BFFatalError(const StringImpl& message, const StringImpl& file, int
|
||||||
gBFApp->mSysDialogCnt++;
|
gBFApp->mSysDialogCnt++;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
String failMsg = StrFormat("%s in %s:%d", message.c_str(), file.c_str(), line);
|
char* failMsg = new char[message.length() + file.length() + 64];
|
||||||
BfpSystem_FatalError(failMsg.c_str(), "FATAL ERROR");
|
sprintf(failMsg, "%s in %s:%d", message.c_str(), file.c_str(), line);
|
||||||
|
BfpSystem_FatalError(failMsg, "FATAL ERROR");
|
||||||
|
|
||||||
#ifndef BF_NO_BFAPP
|
#ifndef BF_NO_BFAPP
|
||||||
if (gBFApp != NULL)
|
if (gBFApp != NULL)
|
||||||
|
@ -906,6 +912,7 @@ static void __cdecl AbortHandler(int)
|
||||||
static int64 gCPUFreq = -1;
|
static int64 gCPUFreq = -1;
|
||||||
static int64 gStartCPUTick = -1;
|
static int64 gStartCPUTick = -1;
|
||||||
static int64 gStartQPF = -1;
|
static int64 gStartQPF = -1;
|
||||||
|
static void(*sOldSIGABRTHandler)(int signal) = nullptr;
|
||||||
|
|
||||||
static void InitCPUFreq()
|
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)
|
BFP_EXPORT void BFP_CALLTYPE BfpSystem_Init(int version, BfpSystemInitFlags flags)
|
||||||
{
|
{
|
||||||
|
gCrashErrorFunc = Crash_Error;
|
||||||
InitCPUFreq();
|
InitCPUFreq();
|
||||||
|
|
||||||
::_set_error_mode(_OUT_TO_STDERR);
|
::_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)
|
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)
|
if ((flags & BfpSystemInitFlag_InstallCrashCatcher) != 0)
|
||||||
|
@ -953,13 +983,17 @@ BFP_EXPORT void BFP_CALLTYPE BfpSystem_Init(int version, BfpSystemInitFlags flag
|
||||||
sOldSIGABRTHandler = signal(SIGABRT, &AbortHandler);
|
sOldSIGABRTHandler = signal(SIGABRT, &AbortHandler);
|
||||||
if (sOldSIGABRTHandler == SIG_ERR)
|
if (sOldSIGABRTHandler == SIG_ERR)
|
||||||
sOldSIGABRTHandler = nullptr;
|
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)
|
BFP_EXPORT void BFP_CALLTYPE BfpSystem_SetCommandLine(int argc, char** argv)
|
||||||
{
|
{
|
||||||
// This isn't required on Windows, but it is on Linux
|
// This isn't required on Windows, but it is on Linux
|
||||||
|
@ -993,7 +1027,10 @@ BFP_EXPORT void BFP_CALLTYPE BfpSystem_Shutdown()
|
||||||
delete gManagerTail;
|
delete gManagerTail;
|
||||||
gManagerTail = next;
|
gManagerTail = next;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BFP_EXPORT void BFP_CALLTYPE BfpSystem_ShutdownCrashCatcher()
|
||||||
|
{
|
||||||
if (CrashCatcher::Shutdown())
|
if (CrashCatcher::Shutdown())
|
||||||
{
|
{
|
||||||
_set_purecall_handler(nullptr);
|
_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)
|
BFP_EXPORT void BFP_CALLTYPE BfpSystem_FatalError(const char* error, const char* title)
|
||||||
{
|
{
|
||||||
if (title != NULL)
|
if (title != NULL)
|
||||||
CrashCatcher::Get()->Crash(String(title) + "\n" + String(error));
|
{
|
||||||
else
|
int errorLen = (int)strlen(error);
|
||||||
CrashCatcher::Get()->Crash(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)
|
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);
|
typedef BOOL(WINAPI* SETXSTATEFEATURESMASK)(PCONTEXT Context, DWORD64 FeatureMask);
|
||||||
static SETXSTATEFEATURESMASK pfnSetXStateFeaturesMask = NULL;
|
static SETXSTATEFEATURESMASK pfnSetXStateFeaturesMask = NULL;
|
||||||
|
|
||||||
static uint8 ContextBuffer[4096];
|
static uint8* ContextBuffer;
|
||||||
static CONTEXT* CaptureRegistersEx(HANDLE hThread, intptr*& curPtr)
|
static CONTEXT* CaptureRegistersEx(HANDLE hThread, intptr*& curPtr)
|
||||||
{
|
{
|
||||||
|
if (ContextBuffer == NULL)
|
||||||
|
ContextBuffer = new uint8[4096];
|
||||||
|
|
||||||
PCONTEXT Context;
|
PCONTEXT Context;
|
||||||
DWORD ContextSize;
|
DWORD ContextSize;
|
||||||
DWORD64 FeatureMask;
|
DWORD64 FeatureMask;
|
||||||
|
|
|
@ -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>
|
class UTF16String : public Array<uint16>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -24,7 +24,7 @@ OtherLinkFlags = ""
|
||||||
TargetDirectory = "$(WorkspaceDir)/dist"
|
TargetDirectory = "$(WorkspaceDir)/dist"
|
||||||
TargetName = "BeefIDE_d"
|
TargetName = "BeefIDE_d"
|
||||||
OtherLinkFlags = "$(LinkFlags) Comdlg32.lib kernel32.lib user32.lib advapi32.lib shell32.lib IDEHelper64_d.lib"
|
OtherLinkFlags = "$(LinkFlags) Comdlg32.lib kernel32.lib user32.lib advapi32.lib shell32.lib IDEHelper64_d.lib"
|
||||||
DebugCommandArguments = "-proddir=\"$(WorkspaceDir)\\..\\IDE\""
|
DebugCommandArguments = "-proddir=\"$(WorkspaceDir)\\..\\BeefBuild\""
|
||||||
DebugWorkingDirectory = "$(WorkspaceDir)\\.."
|
DebugWorkingDirectory = "$(WorkspaceDir)\\.."
|
||||||
EnvironmentVars = ["_NO_DEBUG_HEAP=1"]
|
EnvironmentVars = ["_NO_DEBUG_HEAP=1"]
|
||||||
|
|
||||||
|
|
8
IDE/Tests/Tiny/BeefProj.toml
Normal file
8
IDE/Tests/Tiny/BeefProj.toml
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
FileVersion = 1
|
||||||
|
|
||||||
|
[Project]
|
||||||
|
Name = "Tiny"
|
||||||
|
StartupObject = "Tiny.Program"
|
||||||
|
|
||||||
|
[Configs.Release.Win64]
|
||||||
|
CLibType = "SystemMSVCRT"
|
26
IDE/Tests/Tiny/BeefSpace.toml
Normal file
26
IDE/Tests/Tiny/BeefSpace.toml
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
FileVersion = 1
|
||||||
|
Projects = {Tiny = {Path = "."}}
|
||||||
|
Unlocked = ["corlib"]
|
||||||
|
|
||||||
|
[Workspace]
|
||||||
|
StartupProject = "Tiny"
|
||||||
|
|
||||||
|
[Configs.Debug.Win64]
|
||||||
|
AllocType = "CRT"
|
||||||
|
RuntimeKind = "Reduced"
|
||||||
|
ReflectKind = "Minimal"
|
||||||
|
RuntimeChecks = false
|
||||||
|
EmitDynamicCastCheck = false
|
||||||
|
EnableObjectDebugFlags = false
|
||||||
|
EmitObjectAccessCheck = false
|
||||||
|
EnableRealtimeLeakCheck = false
|
||||||
|
AllowHotSwapping = false
|
||||||
|
IntermediateType = "ObjectAndIRCode"
|
||||||
|
|
||||||
|
[Configs.Debug.Win32]
|
||||||
|
RuntimeKind = "Reduced"
|
||||||
|
ReflectKind = "Minimal"
|
||||||
|
|
||||||
|
[Configs.Release.Win64]
|
||||||
|
RuntimeKind = "Reduced"
|
||||||
|
ReflectKind = "Minimal"
|
13
IDE/Tests/Tiny/src/Program.bf
Normal file
13
IDE/Tests/Tiny/src/Program.bf
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
using System;
|
||||||
|
using System.Diagnostics;
|
||||||
|
|
||||||
|
namespace Tiny;
|
||||||
|
|
||||||
|
class Program
|
||||||
|
{
|
||||||
|
public static int Main()
|
||||||
|
{
|
||||||
|
Console.WriteLine("Hello, World!");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
|
@ -420,6 +420,12 @@ namespace System
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[AttributeUsage(.MemberAccess)]
|
||||||
|
public struct NoStaticCtorAttribute : Attribute
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/// The [Checked] attribute is used to mark a method or a method invocation as being "checked", meaning
|
/// The [Checked] attribute is used to mark a method or a method invocation as being "checked", meaning
|
||||||
/// that the method applies extra runtime checks such as bounds checking or other parameter or state validation.
|
/// that the method applies extra runtime checks such as bounds checking or other parameter or state validation.
|
||||||
[AttributeUsage(.Invocation | .Method | .Property)]
|
[AttributeUsage(.Invocation | .Method | .Property)]
|
||||||
|
|
|
@ -92,8 +92,15 @@ namespace System
|
||||||
[CallingConvention(.Cdecl)]
|
[CallingConvention(.Cdecl)]
|
||||||
public static extern void Dbg_RawFree(void* ptr);
|
public static extern void Dbg_RawFree(void* ptr);
|
||||||
|
|
||||||
|
[CallingConvention(.Cdecl)]
|
||||||
|
static extern void Shutdown_Internal();
|
||||||
|
|
||||||
[CallingConvention(.Cdecl), AlwaysInclude]
|
[CallingConvention(.Cdecl), AlwaysInclude]
|
||||||
static extern void Shutdown();
|
static void Shutdown()
|
||||||
|
{
|
||||||
|
Shutdown_Internal();
|
||||||
|
}
|
||||||
|
|
||||||
[CallingConvention(.Cdecl)]
|
[CallingConvention(.Cdecl)]
|
||||||
static extern void Test_Init(char8* testData);
|
static extern void Test_Init(char8* testData);
|
||||||
[CallingConvention(.Cdecl)]
|
[CallingConvention(.Cdecl)]
|
||||||
|
|
|
@ -48,63 +48,122 @@ namespace System
|
||||||
|
|
||||||
class Object : IHashable
|
class Object : IHashable
|
||||||
{
|
{
|
||||||
#if BF_ENABLE_OBJECT_DEBUG_FLAGS
|
#if BF_ENABLE_OBJECT_DEBUG_FLAGS
|
||||||
int mClassVData;
|
int mClassVData;
|
||||||
int mDbgAllocInfo;
|
int mDbgAllocInfo;
|
||||||
#else
|
#else
|
||||||
ClassVData* mClassVData;
|
ClassVData* mClassVData;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
public virtual ~this()
|
public virtual ~this()
|
||||||
{
|
{
|
||||||
#if BF_ENABLE_OBJECT_DEBUG_FLAGS
|
#if BF_ENABLE_OBJECT_DEBUG_FLAGS
|
||||||
mClassVData = ((mClassVData & ~0x08) | 0x80);
|
mClassVData = ((mClassVData & ~0x08) | 0x80);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
int IHashable.GetHashCode()
|
|
||||||
{
|
|
||||||
return (int)(void*)this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Type GetType()
|
|
||||||
{
|
|
||||||
Type type;
|
|
||||||
#if BF_ENABLE_OBJECT_DEBUG_FLAGS
|
#if BF_ENABLE_OBJECT_DEBUG_FLAGS
|
||||||
ClassVData* maskedVData = (ClassVData*)(void*)(mClassVData & ~(int)0xFF);
|
[NoShow]
|
||||||
type = maskedVData.mType;
|
int32 GetFlags()
|
||||||
|
{
|
||||||
|
return (int32)mClassVData & 0xFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
[DisableObjectAccessChecks, NoShow]
|
||||||
|
public bool IsDeleted()
|
||||||
|
{
|
||||||
|
return (int32)mClassVData & 0x80 != 0;
|
||||||
|
}
|
||||||
#else
|
#else
|
||||||
type = mClassVData.mType;
|
[SkipCall]
|
||||||
|
public bool IsDeleted()
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
extern Type Comptime_GetType();
|
||||||
|
|
||||||
|
public Type GetType()
|
||||||
|
{
|
||||||
|
if (Compiler.IsComptime)
|
||||||
|
return Comptime_GetType();
|
||||||
|
|
||||||
|
ClassVData* classVData;
|
||||||
|
#if BF_ENABLE_OBJECT_DEBUG_FLAGS
|
||||||
|
classVData = (ClassVData*)(void*)(mClassVData & ~(int)0xFF);
|
||||||
|
#else
|
||||||
|
classVData = mClassVData;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if BF_32_BIT
|
||||||
|
Type type = Type.[Friend]GetType_((.)(classVData.mType2));
|
||||||
|
#else
|
||||||
|
Type type = Type.[Friend]GetType_((.)(classVData.mType >> 32));
|
||||||
#endif
|
#endif
|
||||||
if ((type.[Friend]mTypeFlags & TypeFlags.Boxed) != 0)
|
|
||||||
{
|
|
||||||
//int32 underlyingType = (int32)((TypeInstance)type).mUnderlyingType;
|
|
||||||
type = Type.[Friend]GetType(((TypeInstance)type).[Friend]mUnderlyingType);
|
|
||||||
}
|
|
||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TypeId GetTypeId()
|
||||||
|
{
|
||||||
|
ClassVData* classVData;
|
||||||
|
#if BF_ENABLE_OBJECT_DEBUG_FLAGS
|
||||||
|
classVData = (ClassVData*)(void*)(mClassVData & ~(int)0xFF);
|
||||||
|
#else
|
||||||
|
classVData = mClassVData;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if BF_32_BIT
|
||||||
|
return (.)classVData.mType2;
|
||||||
|
#else
|
||||||
|
return (.)(classVData.mType >> 32);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
[NoShow]
|
[NoShow]
|
||||||
Type RawGetType()
|
Type RawGetType()
|
||||||
{
|
{
|
||||||
Type type;
|
if (Compiler.IsComptime)
|
||||||
|
return Comptime_GetType();
|
||||||
|
|
||||||
|
ClassVData* classVData;
|
||||||
#if BF_ENABLE_OBJECT_DEBUG_FLAGS
|
#if BF_ENABLE_OBJECT_DEBUG_FLAGS
|
||||||
ClassVData* maskedVData = (ClassVData*)(void*)(mClassVData & ~(int)0xFF);
|
classVData = (ClassVData*)(void*)(mClassVData & ~(int)0xFF);
|
||||||
type = maskedVData.mType;
|
|
||||||
#else
|
#else
|
||||||
type = mClassVData.mType;
|
classVData = mClassVData;
|
||||||
#endif
|
#endif
|
||||||
return type;
|
|
||||||
|
#if BF_32_BIT
|
||||||
|
Type type = Type.[Friend]GetType_((.)(classVData.mType));
|
||||||
|
#else
|
||||||
|
Type type = Type.[Friend]GetType_((.)(classVData.mType & 0xFFFFFFFF));
|
||||||
|
#endif
|
||||||
|
return type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TypeId RawGetTypeId()
|
||||||
|
{
|
||||||
|
ClassVData* classVData;
|
||||||
|
#if BF_ENABLE_OBJECT_DEBUG_FLAGS
|
||||||
|
classVData = (ClassVData*)(void*)(mClassVData & ~(int)0xFF);
|
||||||
|
#else
|
||||||
|
classVData = mClassVData;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if BF_32_BIT
|
||||||
|
return (.)classVData.mType;
|
||||||
|
#else
|
||||||
|
return (.)(classVData.mType & 0xFFFFFFFF);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
#if BF_DYNAMIC_CAST_CHECK || BF_ENABLE_REALTIME_LEAK_CHECK
|
#if BF_DYNAMIC_CAST_CHECK || BF_ENABLE_REALTIME_LEAK_CHECK
|
||||||
[NoShow]
|
[NoShow]
|
||||||
public virtual Object DynamicCastToTypeId(int32 typeId)
|
public virtual Object DynamicCastToTypeId(int32 typeId)
|
||||||
{
|
{
|
||||||
if (typeId == (int32)RawGetType().[Friend]mTypeId)
|
if (typeId == (.)RawGetTypeId())
|
||||||
return this;
|
return this;
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
[NoShow]
|
[NoShow]
|
||||||
public virtual Object DynamicCastToInterface(int32 typeId)
|
public virtual Object DynamicCastToInterface(int32 typeId)
|
||||||
|
@ -113,10 +172,15 @@ namespace System
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
int IHashable.GetHashCode()
|
||||||
|
{
|
||||||
|
return (int)Internal.UnsafeCastToPtr(this);
|
||||||
|
}
|
||||||
|
|
||||||
public virtual void ToString(String strBuffer)
|
public virtual void ToString(String strBuffer)
|
||||||
{
|
{
|
||||||
//strBuffer.Set(stack string(GetType().mName));
|
strBuffer.Append("Type#");
|
||||||
RawGetType().GetName(strBuffer);
|
GetTypeId().ToString(strBuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*public virtual int GetHashCode()
|
/*public virtual int GetHashCode()
|
||||||
|
|
|
@ -7,7 +7,10 @@ namespace System
|
||||||
{
|
{
|
||||||
struct ClassVData
|
struct ClassVData
|
||||||
{
|
{
|
||||||
public Type mType;
|
public int mType;
|
||||||
|
#if BF_32_BIT
|
||||||
|
public int mType2;
|
||||||
|
#endif
|
||||||
// The rest of this structured is generated by the compiler,
|
// The rest of this structured is generated by the compiler,
|
||||||
// including the vtable and interface slots
|
// including the vtable and interface slots
|
||||||
}
|
}
|
||||||
|
@ -757,6 +760,7 @@ namespace System.Reflection
|
||||||
public int32 mCustomAttributesIdx;
|
public int32 mCustomAttributesIdx;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[CRepr, AlwaysInclude]
|
||||||
public struct InterfaceData
|
public struct InterfaceData
|
||||||
{
|
{
|
||||||
public TypeId mInterfaceType;
|
public TypeId mInterfaceType;
|
||||||
|
|
|
@ -46,8 +46,8 @@ namespace Hey.Dude.Bro
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
[Import(@"C:\Beef\BeefTools\TestDLL\x64\Debug\TestDLL.dll"), LinkName("Test2")]
|
//[Import(@"C:\Beef\BeefTools\TestDLL\x64\Debug\TestDLL.dll"), LinkName("Test2")]
|
||||||
public static extern void Test2(int32 a, int32 b, int32 c, int32 d, function Color(int32 a, int32 b) func);
|
//public static extern void Test2(int32 a, int32 b, int32 c, int32 d, function Color(int32 a, int32 b) func);
|
||||||
|
|
||||||
public static Color GetColor(int32 a, int32 b)
|
public static Color GetColor(int32 a, int32 b)
|
||||||
{
|
{
|
||||||
|
@ -61,7 +61,9 @@ namespace Hey.Dude.Bro
|
||||||
|
|
||||||
public static int Main(String[] args)
|
public static int Main(String[] args)
|
||||||
{
|
{
|
||||||
Test2(1, 2, 3, 4, => GetColor);
|
Debug.WriteLine("Hey!");
|
||||||
|
|
||||||
|
//Test2(1, 2, 3, 4, => GetColor);
|
||||||
|
|
||||||
//Blurg.Hey();
|
//Blurg.Hey();
|
||||||
return 1;
|
return 1;
|
||||||
|
|
|
@ -764,6 +764,9 @@ namespace IDE
|
||||||
|
|
||||||
public static void GetRtLibNames(Workspace.PlatformType platformType, Workspace.Options workspaceOptions, Project.Options options, bool dynName, String outRt, String outDbg, String outAlloc)
|
public static void GetRtLibNames(Workspace.PlatformType platformType, Workspace.Options workspaceOptions, Project.Options options, bool dynName, String outRt, String outDbg, String outAlloc)
|
||||||
{
|
{
|
||||||
|
if (workspaceOptions.mRuntimeKind == .Disabled)
|
||||||
|
return;
|
||||||
|
|
||||||
if ((platformType == .Linux) || (platformType == .macOS) || (platformType == .iOS))
|
if ((platformType == .Linux) || (platformType == .macOS) || (platformType == .iOS))
|
||||||
{
|
{
|
||||||
if (options.mBuildOptions.mBeefLibType == .DynamicDebug)
|
if (options.mBuildOptions.mBeefLibType == .DynamicDebug)
|
||||||
|
@ -1059,10 +1062,13 @@ namespace IDE
|
||||||
return false;
|
return false;
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
switch (options.mBuildOptions.mCLibType)
|
var clibType = options.mBuildOptions.mCLibType;
|
||||||
|
if (workspaceOptions.mRuntimeKind == .Disabled)
|
||||||
|
clibType = .None;
|
||||||
|
switch (clibType)
|
||||||
{
|
{
|
||||||
case .None:
|
case .None:
|
||||||
linkLine.Append("-nodefaultlib ");
|
linkLine.Append("-nodefaultlib chkstk.obj ");
|
||||||
case .Dynamic:
|
case .Dynamic:
|
||||||
//linkLine.Append((workspaceOptions.mMachineType == .x86) ? "-defaultlib:msvcprt " : "-defaultlib:msvcrt ");
|
//linkLine.Append((workspaceOptions.mMachineType == .x86) ? "-defaultlib:msvcprt " : "-defaultlib:msvcrt ");
|
||||||
linkLine.Append("-defaultlib:msvcrt ");
|
linkLine.Append("-defaultlib:msvcrt ");
|
||||||
|
|
|
@ -5,6 +5,7 @@ namespace IDE
|
||||||
{
|
{
|
||||||
class BuildOptions
|
class BuildOptions
|
||||||
{
|
{
|
||||||
|
[Reflect(.All)]
|
||||||
public enum LTOType
|
public enum LTOType
|
||||||
{
|
{
|
||||||
case None;
|
case None;
|
||||||
|
@ -18,6 +19,7 @@ namespace IDE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Reflect(.All)]
|
||||||
public enum EmitDebugInfo
|
public enum EmitDebugInfo
|
||||||
{
|
{
|
||||||
No,
|
No,
|
||||||
|
@ -25,6 +27,7 @@ namespace IDE
|
||||||
LinesOnly,
|
LinesOnly,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Reflect(.All)]
|
||||||
public enum SIMDSetting
|
public enum SIMDSetting
|
||||||
{
|
{
|
||||||
None,
|
None,
|
||||||
|
@ -38,6 +41,7 @@ namespace IDE
|
||||||
AVX2,
|
AVX2,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Reflect]
|
||||||
public enum BfOptimizationLevel
|
public enum BfOptimizationLevel
|
||||||
{
|
{
|
||||||
case O0;
|
case O0;
|
||||||
|
@ -53,6 +57,7 @@ namespace IDE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Reflect]
|
||||||
public enum RelocType
|
public enum RelocType
|
||||||
{
|
{
|
||||||
NotSet,
|
NotSet,
|
||||||
|
@ -64,6 +69,7 @@ namespace IDE
|
||||||
ROPI_RWPI
|
ROPI_RWPI
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Reflect]
|
||||||
public enum PICLevel
|
public enum PICLevel
|
||||||
{
|
{
|
||||||
NotSet,
|
NotSet,
|
||||||
|
@ -72,6 +78,7 @@ namespace IDE
|
||||||
Big
|
Big
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Reflect]
|
||||||
public enum AlwaysIncludeKind
|
public enum AlwaysIncludeKind
|
||||||
{
|
{
|
||||||
NotSet,
|
NotSet,
|
||||||
|
|
|
@ -739,9 +739,14 @@ namespace IDE.Compiler
|
||||||
SetOpt(options.mAllowHotSwapping, .EnableHotSwapping);
|
SetOpt(options.mAllowHotSwapping, .EnableHotSwapping);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
var allocType = options.mAllocType;
|
||||||
|
|
||||||
|
if ((options.mRuntimeKind == .Disabled) && (allocType == .Debug))
|
||||||
|
allocType = .CRT;
|
||||||
|
|
||||||
String mallocLinkName;
|
String mallocLinkName;
|
||||||
String freeLinkName;
|
String freeLinkName;
|
||||||
switch (options.mAllocType)
|
switch (allocType)
|
||||||
{
|
{
|
||||||
case .CRT:
|
case .CRT:
|
||||||
mallocLinkName = "malloc";
|
mallocLinkName = "malloc";
|
||||||
|
|
|
@ -366,6 +366,9 @@ namespace IDE.Debugger
|
||||||
[CallingConvention(.Stdcall),CLink]
|
[CallingConvention(.Stdcall),CLink]
|
||||||
static extern char8* Debugger_GetModulesInfo();
|
static extern char8* Debugger_GetModulesInfo();
|
||||||
|
|
||||||
|
[CallingConvention(.Stdcall),CLink]
|
||||||
|
static extern char8* Debugger_GetModuleInfo(char8* moduleName);
|
||||||
|
|
||||||
[CallingConvention(.Stdcall),CLink]
|
[CallingConvention(.Stdcall),CLink]
|
||||||
static extern bool Debugger_HasPendingDebugLoads();
|
static extern bool Debugger_HasPendingDebugLoads();
|
||||||
|
|
||||||
|
@ -1194,6 +1197,11 @@ namespace IDE.Debugger
|
||||||
modulesInfo.Append(Debugger_GetModulesInfo());
|
modulesInfo.Append(Debugger_GetModulesInfo());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void GetModuleInfo(StringView moduleName, String moduleInfo)
|
||||||
|
{
|
||||||
|
moduleInfo.Append(Debugger_GetModuleInfo(moduleName.ToScopeCStr!()));
|
||||||
|
}
|
||||||
|
|
||||||
public int32 LoadDebugInfoForModule(String moduleName)
|
public int32 LoadDebugInfoForModule(String moduleName)
|
||||||
{
|
{
|
||||||
return Debugger_LoadDebugInfoForModule(moduleName);
|
return Debugger_LoadDebugInfoForModule(moduleName);
|
||||||
|
|
|
@ -8488,6 +8488,13 @@ namespace IDE
|
||||||
macroList.Add("BF_LARGE_COLLECTIONS");
|
macroList.Add("BF_LARGE_COLLECTIONS");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (workspaceOptions.mRuntimeKind == .Disabled)
|
||||||
|
macroList.Add("BF_RUNTIME_DISABLE");
|
||||||
|
if ((workspaceOptions.mRuntimeKind == .Reduced) || (workspaceOptions.mRuntimeKind == .Disabled))
|
||||||
|
macroList.Add("BF_RUNTIME_REDUCED");
|
||||||
|
if (workspaceOptions.mReflectKind == .Minimal)
|
||||||
|
macroList.Add("BF_REFLECT_MINIMAL");
|
||||||
|
|
||||||
// Only supported on Windows at the moment
|
// Only supported on Windows at the moment
|
||||||
bool hasLeakCheck = false;
|
bool hasLeakCheck = false;
|
||||||
if (workspaceOptions.LeakCheckingEnabled)
|
if (workspaceOptions.LeakCheckingEnabled)
|
||||||
|
|
|
@ -94,6 +94,12 @@ namespace IDE
|
||||||
BitcodeAndIRCode,
|
BitcodeAndIRCode,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public enum ReflectKind
|
||||||
|
{
|
||||||
|
Normal,
|
||||||
|
Minimal
|
||||||
|
}
|
||||||
|
|
||||||
public enum PlatformType
|
public enum PlatformType
|
||||||
{
|
{
|
||||||
case Unknown;
|
case Unknown;
|
||||||
|
@ -263,6 +269,13 @@ namespace IDE
|
||||||
Custom
|
Custom
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public enum RuntimeKind
|
||||||
|
{
|
||||||
|
Default,
|
||||||
|
Reduced,
|
||||||
|
Disabled
|
||||||
|
}
|
||||||
|
|
||||||
public class BeefGlobalOptions
|
public class BeefGlobalOptions
|
||||||
{
|
{
|
||||||
[Reflect]
|
[Reflect]
|
||||||
|
@ -305,6 +318,10 @@ namespace IDE
|
||||||
[Reflect]
|
[Reflect]
|
||||||
public bool mLargeCollections;
|
public bool mLargeCollections;
|
||||||
[Reflect]
|
[Reflect]
|
||||||
|
public RuntimeKind mRuntimeKind;
|
||||||
|
[Reflect]
|
||||||
|
public ReflectKind mReflectKind;
|
||||||
|
[Reflect]
|
||||||
public AllocType mAllocType = .CRT;
|
public AllocType mAllocType = .CRT;
|
||||||
[Reflect]
|
[Reflect]
|
||||||
public String mAllocMalloc = new String() ~ delete _;
|
public String mAllocMalloc = new String() ~ delete _;
|
||||||
|
@ -352,7 +369,7 @@ namespace IDE
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
#if BF_PLATFORM_WINDOWS
|
#if BF_PLATFORM_WINDOWS
|
||||||
return mEnableRealtimeLeakCheck && mEnableObjectDebugFlags && (mAllocType == .Debug);
|
return mEnableRealtimeLeakCheck && mEnableObjectDebugFlags && (mAllocType == .Debug) && (mRuntimeKind != .Disabled);
|
||||||
#else
|
#else
|
||||||
return false;
|
return false;
|
||||||
#endif
|
#endif
|
||||||
|
@ -376,6 +393,8 @@ namespace IDE
|
||||||
mNoOmitFramePointers = prev.mNoOmitFramePointers;
|
mNoOmitFramePointers = prev.mNoOmitFramePointers;
|
||||||
mLargeStrings = prev.mLargeStrings;
|
mLargeStrings = prev.mLargeStrings;
|
||||||
mLargeCollections = prev.mLargeCollections;
|
mLargeCollections = prev.mLargeCollections;
|
||||||
|
mRuntimeKind = prev.mRuntimeKind;
|
||||||
|
mReflectKind = prev.mReflectKind;
|
||||||
mAllocType = prev.mAllocType;
|
mAllocType = prev.mAllocType;
|
||||||
mAllocMalloc.Set(prev.mAllocMalloc);
|
mAllocMalloc.Set(prev.mAllocMalloc);
|
||||||
mAllocFree.Set(prev.mAllocFree);
|
mAllocFree.Set(prev.mAllocFree);
|
||||||
|
@ -813,6 +832,8 @@ namespace IDE
|
||||||
data.ConditionalAdd("NoOmitFramePointers", options.mNoOmitFramePointers, false);
|
data.ConditionalAdd("NoOmitFramePointers", options.mNoOmitFramePointers, false);
|
||||||
data.ConditionalAdd("LargeStrings", options.mLargeStrings, false);
|
data.ConditionalAdd("LargeStrings", options.mLargeStrings, false);
|
||||||
data.ConditionalAdd("LargeCollections", options.mLargeCollections, false);
|
data.ConditionalAdd("LargeCollections", options.mLargeCollections, false);
|
||||||
|
data.ConditionalAdd("RuntimeKind", options.mRuntimeKind);
|
||||||
|
data.ConditionalAdd("ReflectKind", options.mReflectKind);
|
||||||
data.ConditionalAdd("InitLocalVariables", options.mInitLocalVariables, false);
|
data.ConditionalAdd("InitLocalVariables", options.mInitLocalVariables, false);
|
||||||
data.ConditionalAdd("RuntimeChecks", options.mRuntimeChecks, !isRelease);
|
data.ConditionalAdd("RuntimeChecks", options.mRuntimeChecks, !isRelease);
|
||||||
data.ConditionalAdd("EmitDynamicCastCheck", options.mEmitDynamicCastCheck, !isRelease);
|
data.ConditionalAdd("EmitDynamicCastCheck", options.mEmitDynamicCastCheck, !isRelease);
|
||||||
|
@ -1004,6 +1025,8 @@ namespace IDE
|
||||||
options.mNoOmitFramePointers = false;
|
options.mNoOmitFramePointers = false;
|
||||||
options.mLargeStrings = false;
|
options.mLargeStrings = false;
|
||||||
options.mLargeCollections = false;
|
options.mLargeCollections = false;
|
||||||
|
options.mRuntimeKind = .Default;
|
||||||
|
options.mReflectKind = .Normal;
|
||||||
options.mInitLocalVariables = false;
|
options.mInitLocalVariables = false;
|
||||||
options.mRuntimeChecks = !isRelease;
|
options.mRuntimeChecks = !isRelease;
|
||||||
options.mEmitDynamicCastCheck = !isRelease;
|
options.mEmitDynamicCastCheck = !isRelease;
|
||||||
|
@ -1113,6 +1136,8 @@ namespace IDE
|
||||||
options.mNoOmitFramePointers = data.GetBool("NoOmitFramePointers", false);
|
options.mNoOmitFramePointers = data.GetBool("NoOmitFramePointers", false);
|
||||||
options.mLargeStrings = data.GetBool("LargeStrings", false);
|
options.mLargeStrings = data.GetBool("LargeStrings", false);
|
||||||
options.mLargeCollections = data.GetBool("LargeCollections", false);
|
options.mLargeCollections = data.GetBool("LargeCollections", false);
|
||||||
|
options.mRuntimeKind = data.GetEnum<RuntimeKind>("RuntimeKind");
|
||||||
|
options.mReflectKind = data.GetEnum<ReflectKind>("ReflectKind");
|
||||||
options.mInitLocalVariables = data.GetBool("InitLocalVariables", false);
|
options.mInitLocalVariables = data.GetBool("InitLocalVariables", false);
|
||||||
options.mRuntimeChecks = data.GetBool("RuntimeChecks", !isRelease);
|
options.mRuntimeChecks = data.GetBool("RuntimeChecks", !isRelease);
|
||||||
options.mEmitDynamicCastCheck = data.GetBool("EmitDynamicCastCheck", !isRelease);
|
options.mEmitDynamicCastCheck = data.GetBool("EmitDynamicCastCheck", !isRelease);
|
||||||
|
|
|
@ -158,6 +158,20 @@ namespace IDE.ui
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
anItem = menu.AddItem("Copy Info to Clipboard");
|
||||||
|
anItem.mOnMenuItemSelected.Add(new (item) =>
|
||||||
|
{
|
||||||
|
String moduleInfo = scope .();
|
||||||
|
listView.GetRoot().WithSelectedItems(scope (item) =>
|
||||||
|
{
|
||||||
|
if (!moduleInfo.IsEmpty)
|
||||||
|
moduleInfo.Append("\n");
|
||||||
|
gApp.mDebugger.GetModuleInfo(item.GetSubItem(1).Label, moduleInfo);
|
||||||
|
});
|
||||||
|
gApp.SetClipboardText(moduleInfo);
|
||||||
|
});
|
||||||
|
|
||||||
MenuWidget menuWidget = ThemeFactory.mDefault.CreateMenuWidget(menu);
|
MenuWidget menuWidget = ThemeFactory.mDefault.CreateMenuWidget(menu);
|
||||||
menuWidget.Init(relWidget, x, y);
|
menuWidget.Init(relWidget, x, y);
|
||||||
}
|
}
|
||||||
|
|
|
@ -797,6 +797,8 @@ namespace IDE.ui
|
||||||
AddPropertiesItem(category, "No Omit Frame Pointers", "mNoOmitFramePointers");
|
AddPropertiesItem(category, "No Omit Frame Pointers", "mNoOmitFramePointers");
|
||||||
AddPropertiesItem(category, "Large Strings", "mLargeStrings");
|
AddPropertiesItem(category, "Large Strings", "mLargeStrings");
|
||||||
AddPropertiesItem(category, "Large Collections", "mLargeCollections");
|
AddPropertiesItem(category, "Large Collections", "mLargeCollections");
|
||||||
|
AddPropertiesItem(category, "Runtime", "mRuntimeKind");
|
||||||
|
AddPropertiesItem(category, "Reflection", "mReflectKind");
|
||||||
category.Open(true, true);
|
category.Open(true, true);
|
||||||
|
|
||||||
(category, propEntry) = AddPropertiesItem(root, "Debug");
|
(category, propEntry) = AddPropertiesItem(root, "Debug");
|
||||||
|
|
|
@ -509,7 +509,7 @@ addr_target COFF::GetSectionAddr(uint16 section, uint32 offset)
|
||||||
return hiBase + offset;
|
return hiBase + offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
int rva = mSectionRVAs[section - 1];
|
int rva = mSectionHeaders[section - 1].mVirtualAddress;
|
||||||
if (rva == 0)
|
if (rva == 0)
|
||||||
return ADDR_FLAG_ABS + offset;
|
return ADDR_FLAG_ABS + offset;
|
||||||
|
|
||||||
|
@ -5178,6 +5178,7 @@ bool COFF::CvParseDBI(int wantAge)
|
||||||
contribEntry->mLength = curSize;
|
contribEntry->mLength = curSize;
|
||||||
contribEntry->mDbgModule = this;
|
contribEntry->mDbgModule = this;
|
||||||
contribEntry->mCompileUnitId = contrib.mModule;
|
contribEntry->mCompileUnitId = contrib.mModule;
|
||||||
|
contribEntry->mSection = contrib.mSection;
|
||||||
mDebugTarget->mContribMap.Insert(contribEntry);
|
mDebugTarget->mContribMap.Insert(contribEntry);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5288,7 +5289,7 @@ bool COFF::CvParseDBI(int wantAge)
|
||||||
|
|
||||||
void COFF::ParseSectionHeader(int sectionIdx)
|
void COFF::ParseSectionHeader(int sectionIdx)
|
||||||
{
|
{
|
||||||
bool fakeRVAS = mSectionRVAs.empty();
|
bool fakeRVAS = mSectionHeaders.empty();
|
||||||
|
|
||||||
int sectionSize = 0;
|
int sectionSize = 0;
|
||||||
uint8* sectionData = CvReadStream(sectionIdx, §ionSize);
|
uint8* sectionData = CvReadStream(sectionIdx, §ionSize);
|
||||||
|
@ -5300,12 +5301,15 @@ void COFF::ParseSectionHeader(int sectionIdx)
|
||||||
auto& sectionHeader = GET(PESectionHeader);
|
auto& sectionHeader = GET(PESectionHeader);
|
||||||
if (fakeRVAS)
|
if (fakeRVAS)
|
||||||
{
|
{
|
||||||
mSectionRVAs.push_back(sectionHeader.mVirtualAddress);
|
mSectionHeaders.push_back(sectionHeader);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fakeRVAS)
|
if (fakeRVAS)
|
||||||
mSectionRVAs.push_back(0);
|
{
|
||||||
|
PESectionHeader sectionHeader = { 0 };
|
||||||
|
mSectionHeaders.push_back(sectionHeader);
|
||||||
|
}
|
||||||
|
|
||||||
delete sectionData;
|
delete sectionData;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1220,7 +1220,7 @@ void BfCompiler::CreateVData(BfVDataModule* bfModule)
|
||||||
|
|
||||||
Array<BfType*> vdataTypeList;
|
Array<BfType*> vdataTypeList;
|
||||||
HashSet<BfModule*> usedModuleSet;
|
HashSet<BfModule*> usedModuleSet;
|
||||||
HashSet<BfType*> reflectTypeSet;
|
HashSet<BfType*> reflectSkipTypeSet;
|
||||||
HashSet<BfType*> reflectFieldTypeSet;
|
HashSet<BfType*> reflectFieldTypeSet;
|
||||||
|
|
||||||
vdataHashCtx.MixinStr(project->mStartupObject);
|
vdataHashCtx.MixinStr(project->mStartupObject);
|
||||||
|
@ -1398,20 +1398,49 @@ void BfCompiler::CreateVData(BfVDataModule* bfModule)
|
||||||
bool madeBfTypeData = false;
|
bool madeBfTypeData = false;
|
||||||
|
|
||||||
auto typeDefType = mContext->mBfTypeType;
|
auto typeDefType = mContext->mBfTypeType;
|
||||||
bool needsTypeList = bfModule->IsMethodImplementedAndReified(typeDefType, "GetType");
|
bool needsFullTypeList = bfModule->IsMethodImplementedAndReified(typeDefType, "GetType");
|
||||||
|
bool needsTypeList = needsFullTypeList || bfModule->IsMethodImplementedAndReified(typeDefType, "GetType_");
|
||||||
bool needsObjectTypeData = needsTypeList || bfModule->IsMethodImplementedAndReified(vdataContext->mBfObjectType, "RawGetType") || bfModule->IsMethodImplementedAndReified(vdataContext->mBfObjectType, "GetType");
|
bool needsObjectTypeData = needsTypeList || bfModule->IsMethodImplementedAndReified(vdataContext->mBfObjectType, "RawGetType") || bfModule->IsMethodImplementedAndReified(vdataContext->mBfObjectType, "GetType");
|
||||||
bool needsTypeNames = bfModule->IsMethodImplementedAndReified(typeDefType, "GetName") || bfModule->IsMethodImplementedAndReified(typeDefType, "GetFullName");
|
bool needsTypeNames = bfModule->IsMethodImplementedAndReified(typeDefType, "GetName") || bfModule->IsMethodImplementedAndReified(typeDefType, "GetFullName");
|
||||||
bool needsStringLiteralList = (mOptions.mAllowHotSwapping) || (bfModule->IsMethodImplementedAndReified(stringType, "Intern")) || (bfModule->IsMethodImplementedAndReified(stringViewType, "Intern"));
|
bool needsStringLiteralList = (mOptions.mAllowHotSwapping) || (bfModule->IsMethodImplementedAndReified(stringType, "Intern")) || (bfModule->IsMethodImplementedAndReified(stringViewType, "Intern"));
|
||||||
|
|
||||||
Dictionary<int, int> usedStringIdMap;
|
BfCreateTypeDataContext createTypeDataCtx;
|
||||||
|
|
||||||
reflectTypeSet.Add(vdataContext->mUnreifiedModule->ResolveTypeDef(mReflectTypeInstanceTypeDef));
|
if (!needsTypeList)
|
||||||
reflectTypeSet.Add(vdataContext->mUnreifiedModule->ResolveTypeDef(mReflectSpecializedGenericType));
|
{
|
||||||
reflectTypeSet.Add(vdataContext->mUnreifiedModule->ResolveTypeDef(mReflectUnspecializedGenericType));
|
reflectSkipTypeSet.Add(vdataContext->mUnreifiedModule->ResolveTypeDef(mTypeTypeDef));
|
||||||
reflectTypeSet.Add(vdataContext->mUnreifiedModule->ResolveTypeDef(mReflectArrayType));
|
reflectSkipTypeSet.Add(vdataContext->mUnreifiedModule->ResolveTypeDef(mReflectTypeInstanceTypeDef));
|
||||||
reflectTypeSet.Add(vdataContext->mUnreifiedModule->ResolveTypeDef(mReflectGenericParamType));
|
}
|
||||||
|
|
||||||
|
if (!needsFullTypeList)
|
||||||
|
{
|
||||||
|
reflectSkipTypeSet.Add(vdataContext->mUnreifiedModule->ResolveTypeDef(mReflectSpecializedGenericType));
|
||||||
|
reflectSkipTypeSet.Add(vdataContext->mUnreifiedModule->ResolveTypeDef(mReflectUnspecializedGenericType));
|
||||||
|
reflectSkipTypeSet.Add(vdataContext->mUnreifiedModule->ResolveTypeDef(mReflectConstExprType));
|
||||||
|
reflectSkipTypeSet.Add(vdataContext->mUnreifiedModule->ResolveTypeDef(mReflectArrayType));
|
||||||
|
reflectSkipTypeSet.Add(vdataContext->mUnreifiedModule->ResolveTypeDef(mReflectGenericParamType));
|
||||||
|
reflectSkipTypeSet.Add(vdataContext->mUnreifiedModule->ResolveTypeDef(mReflectPointerType));
|
||||||
|
reflectSkipTypeSet.Add(vdataContext->mUnreifiedModule->ResolveTypeDef(mReflectSizedArrayType));
|
||||||
|
reflectSkipTypeSet.Add(vdataContext->mUnreifiedModule->ResolveTypeDef(mReflectRefType));
|
||||||
|
}
|
||||||
|
|
||||||
|
HashSet<BfType*> boxeeSet;
|
||||||
|
for (auto type : vdataTypeList)
|
||||||
|
{
|
||||||
|
auto typeInst = type->ToTypeInstance();
|
||||||
|
|
||||||
|
if ((!type->IsReified()) || (type->IsUnspecializedType()))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (type->IsBoxed())
|
||||||
|
boxeeSet.Add(typeInst->GetUnderlyingType());
|
||||||
|
}
|
||||||
|
|
||||||
|
int usedTypeCount = 0;
|
||||||
|
HashSet<BfType*> vDataTypeSet;
|
||||||
SmallVector<BfIRValue, 256> typeDataVector;
|
SmallVector<BfIRValue, 256> typeDataVector;
|
||||||
|
Array<BfType*> usedTypeDataVector;
|
||||||
|
|
||||||
for (auto type : vdataTypeList)
|
for (auto type : vdataTypeList)
|
||||||
{
|
{
|
||||||
if (type->IsTypeAlias())
|
if (type->IsTypeAlias())
|
||||||
|
@ -1425,9 +1454,12 @@ void BfCompiler::CreateVData(BfVDataModule* bfModule)
|
||||||
if ((typeInst != NULL) && (!typeInst->IsReified()) && (!typeInst->IsUnspecializedType()))
|
if ((typeInst != NULL) && (!typeInst->IsReified()) && (!typeInst->IsUnspecializedType()))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
bool needsTypeData = (needsTypeList) || ((type->IsObject()) && (needsObjectTypeData));
|
bool needsTypeData = (needsFullTypeList) || ((type->IsObject()) && (needsObjectTypeData));
|
||||||
bool needsVData = (type->IsObject()) && (typeInst->HasBeenInstantiated());
|
bool needsVData = (type->IsObject()) && (typeInst->HasBeenInstantiated());
|
||||||
|
|
||||||
|
if ((needsObjectTypeData) && (boxeeSet.Contains(typeInst)))
|
||||||
|
needsTypeData = true;
|
||||||
|
|
||||||
bool forceReflectFields = false;
|
bool forceReflectFields = false;
|
||||||
|
|
||||||
if (bfModule->mProject->mReferencedTypeData.Contains(type))
|
if (bfModule->mProject->mReferencedTypeData.Contains(type))
|
||||||
|
@ -1437,8 +1469,16 @@ void BfCompiler::CreateVData(BfVDataModule* bfModule)
|
||||||
forceReflectFields = true;
|
forceReflectFields = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
BfIRValue typeVariable;
|
if (reflectSkipTypeSet.Contains(type))
|
||||||
|
{
|
||||||
|
if (!bfModule->mProject->mReferencedTypeData.Contains(type))
|
||||||
|
{
|
||||||
|
needsTypeData = false;
|
||||||
|
needsVData = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BfIRValue typeVariable;
|
||||||
if ((needsTypeData) || (needsVData))
|
if ((needsTypeData) || (needsVData))
|
||||||
{
|
{
|
||||||
if (reflectFieldTypeSet.Contains(type))
|
if (reflectFieldTypeSet.Contains(type))
|
||||||
|
@ -1446,14 +1486,25 @@ void BfCompiler::CreateVData(BfVDataModule* bfModule)
|
||||||
needsTypeData = true;
|
needsTypeData = true;
|
||||||
forceReflectFields = true;
|
forceReflectFields = true;
|
||||||
}
|
}
|
||||||
else if (reflectTypeSet.Contains(type))
|
/*else if (reflectTypeSet.Contains(type))
|
||||||
{
|
{
|
||||||
needsTypeData = true;
|
needsTypeData = true;
|
||||||
needsVData = true;
|
needsVData = true;
|
||||||
}
|
}*/
|
||||||
|
|
||||||
typeVariable = bfModule->CreateTypeData(type, usedStringIdMap, forceReflectFields, needsTypeData, needsTypeNames, needsVData);
|
if (needsVData)
|
||||||
|
vDataTypeSet.Add(type);
|
||||||
|
|
||||||
|
typeVariable = bfModule->CreateTypeData(type, createTypeDataCtx, forceReflectFields, needsTypeData, needsTypeNames, needsVData);
|
||||||
|
if (typeVariable)
|
||||||
|
usedTypeDataVector.Add(type);
|
||||||
}
|
}
|
||||||
|
else if ((type->IsInterface()) && (typeInst->mSlotNum >= 0))
|
||||||
|
{
|
||||||
|
bfModule->CreateSlotOfs(typeInst);
|
||||||
|
}
|
||||||
|
|
||||||
|
usedTypeCount++;
|
||||||
type->mDirty = false;
|
type->mDirty = false;
|
||||||
|
|
||||||
if (needsTypeList)
|
if (needsTypeList)
|
||||||
|
@ -1573,13 +1624,13 @@ void BfCompiler::CreateVData(BfVDataModule* bfModule)
|
||||||
BfMangler::MangleStaticFieldName(stringsVariableName, GetMangleKind(), stringType->ToTypeInstance(), "sIdStringLiterals", stringPtrType);
|
BfMangler::MangleStaticFieldName(stringsVariableName, GetMangleKind(), stringType->ToTypeInstance(), "sIdStringLiterals", stringPtrType);
|
||||||
Array<BfIRValue> stringList;
|
Array<BfIRValue> stringList;
|
||||||
|
|
||||||
stringList.Resize(usedStringIdMap.size());
|
stringList.Resize(createTypeDataCtx.mUsedStringIdMap.size());
|
||||||
for (auto& kv : usedStringIdMap)
|
for (auto& kv : createTypeDataCtx.mUsedStringIdMap)
|
||||||
{
|
{
|
||||||
stringList[kv.mValue] = bfModule->mStringObjectPool[kv.mKey];
|
stringList[kv.mValue] = bfModule->mStringObjectPool[kv.mKey];
|
||||||
}
|
}
|
||||||
|
|
||||||
BfIRType stringArrayType = bfModule->mBfIRBuilder->GetSizedArrayType(stringPtrIRType, (int)usedStringIdMap.size());
|
BfIRType stringArrayType = bfModule->mBfIRBuilder->GetSizedArrayType(stringPtrIRType, (int)createTypeDataCtx.mUsedStringIdMap.size());
|
||||||
auto stringArray = bfModule->mBfIRBuilder->CreateConstAgg_Value(stringArrayType, stringList);
|
auto stringArray = bfModule->mBfIRBuilder->CreateConstAgg_Value(stringArrayType, stringList);
|
||||||
|
|
||||||
auto stringArrayVar = bfModule->mBfIRBuilder->CreateGlobalVariable(stringArrayType, true, BfIRLinkageType_External, stringArray, stringsVariableName);
|
auto stringArrayVar = bfModule->mBfIRBuilder->CreateGlobalVariable(stringArrayType, true, BfIRLinkageType_External, stringArray, stringsVariableName);
|
||||||
|
@ -3994,10 +4045,10 @@ void BfCompiler::VisitSourceExteriorNodes()
|
||||||
|
|
||||||
if (auto genericTypeRef = BfNodeDynCast<BfGenericInstanceTypeRef>(usingDirective->mTypeRef))
|
if (auto genericTypeRef = BfNodeDynCast<BfGenericInstanceTypeRef>(usingDirective->mTypeRef))
|
||||||
{
|
{
|
||||||
mContext->mScratchModule->ResolveTypeRefAllowUnboundGenerics(usingDirective->mTypeRef, BfPopulateType_Identity);
|
mContext->mScratchModule->ResolveTypeRefAllowUnboundGenerics(usingDirective->mTypeRef, BfPopulateType_Identity, BfResolveTypeRefFlag_NoReify);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
mContext->mScratchModule->ResolveTypeRef(usingDirective->mTypeRef, BfPopulateType_Identity);
|
mContext->mScratchModule->ResolveTypeRef(usingDirective->mTypeRef, BfPopulateType_Identity, BfResolveTypeRefFlag_NoReify);
|
||||||
|
|
||||||
if ((mResolvePassData != NULL) && (mResolvePassData->mAutoComplete != NULL))
|
if ((mResolvePassData != NULL) && (mResolvePassData->mAutoComplete != NULL))
|
||||||
mResolvePassData->mAutoComplete->CheckTypeRef(usingDirective->mTypeRef, false, false);
|
mResolvePassData->mAutoComplete->CheckTypeRef(usingDirective->mTypeRef, false, false);
|
||||||
|
@ -5608,12 +5659,19 @@ void BfCompiler::ClearBuildCache()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int BfCompiler::GetVDataPrefixDataCount()
|
||||||
|
{
|
||||||
|
return (mSystem->mPtrSize == 4) ? 2 : 1;
|
||||||
|
}
|
||||||
|
|
||||||
int BfCompiler::GetDynCastVDataCount()
|
int BfCompiler::GetDynCastVDataCount()
|
||||||
{
|
{
|
||||||
int dynElements = 1 + mMaxInterfaceSlots;
|
int dynElements = 1 + mMaxInterfaceSlots;
|
||||||
return ((dynElements * 4) + mSystem->mPtrSize - 1) / mSystem->mPtrSize;
|
return ((dynElements * 4) + mSystem->mPtrSize - 1) / mSystem->mPtrSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool BfCompiler::IsAutocomplete()
|
bool BfCompiler::IsAutocomplete()
|
||||||
{
|
{
|
||||||
return (mResolvePassData != NULL) && (mResolvePassData->mAutoComplete != NULL);
|
return (mResolvePassData != NULL) && (mResolvePassData->mAutoComplete != NULL);
|
||||||
|
@ -7177,6 +7235,7 @@ bool BfCompiler::DoCompile(const StringImpl& outputDirectory)
|
||||||
mActionTypeDef = _GetRequiredType("System.Action");
|
mActionTypeDef = _GetRequiredType("System.Action");
|
||||||
mEnumTypeDef = _GetRequiredType("System.Enum");
|
mEnumTypeDef = _GetRequiredType("System.Enum");
|
||||||
mFriendAttributeTypeDef = _GetRequiredType("System.FriendAttribute");
|
mFriendAttributeTypeDef = _GetRequiredType("System.FriendAttribute");
|
||||||
|
mNoStaticCtorAttributeTypeDef = _GetRequiredType("System.NoStaticCtorAttribute");
|
||||||
mComptimeAttributeTypeDef = _GetRequiredType("System.ComptimeAttribute");
|
mComptimeAttributeTypeDef = _GetRequiredType("System.ComptimeAttribute");
|
||||||
mConstEvalAttributeTypeDef = _GetRequiredType("System.ConstEvalAttribute");
|
mConstEvalAttributeTypeDef = _GetRequiredType("System.ConstEvalAttribute");
|
||||||
mNoExtensionAttributeTypeDef = _GetRequiredType("System.NoExtensionAttribute");
|
mNoExtensionAttributeTypeDef = _GetRequiredType("System.NoExtensionAttribute");
|
||||||
|
|
|
@ -442,6 +442,7 @@ public:
|
||||||
BfTypeDef* mDisableChecksAttributeTypeDef;
|
BfTypeDef* mDisableChecksAttributeTypeDef;
|
||||||
BfTypeDef* mDisableObjectAccessChecksAttributeTypeDef;
|
BfTypeDef* mDisableObjectAccessChecksAttributeTypeDef;
|
||||||
BfTypeDef* mFriendAttributeTypeDef;
|
BfTypeDef* mFriendAttributeTypeDef;
|
||||||
|
BfTypeDef* mNoStaticCtorAttributeTypeDef;
|
||||||
BfTypeDef* mComptimeAttributeTypeDef;
|
BfTypeDef* mComptimeAttributeTypeDef;
|
||||||
BfTypeDef* mConstEvalAttributeTypeDef;
|
BfTypeDef* mConstEvalAttributeTypeDef;
|
||||||
BfTypeDef* mNoExtensionAttributeTypeDef;
|
BfTypeDef* mNoExtensionAttributeTypeDef;
|
||||||
|
@ -501,6 +502,7 @@ public:
|
||||||
void MarkStringPool(BfIRConstHolder* constHolder, BfIRValue irValue);
|
void MarkStringPool(BfIRConstHolder* constHolder, BfIRValue irValue);
|
||||||
void ClearUnusedStringPoolEntries();
|
void ClearUnusedStringPoolEntries();
|
||||||
void ClearBuildCache();
|
void ClearBuildCache();
|
||||||
|
int GetVDataPrefixDataCount();
|
||||||
int GetDynCastVDataCount();
|
int GetDynCastVDataCount();
|
||||||
bool IsAutocomplete();
|
bool IsAutocomplete();
|
||||||
bool IsDataResolvePass();
|
bool IsDataResolvePass();
|
||||||
|
|
|
@ -420,55 +420,74 @@ bool BfContext::ProcessWorkList(bool onlyReifiedTypes, bool onlyReifiedMethods)
|
||||||
didWork = true;
|
didWork = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int workIdx = 0; workIdx < (int)mPopulateTypeWorkList.size(); workIdx++)
|
for (int populatePass = 0; populatePass < 2; populatePass++)
|
||||||
{
|
{
|
||||||
//BP_ZONE("PWL_PopulateType");
|
for (int workIdx = 0; workIdx < (int)mPopulateTypeWorkList.size(); workIdx++)
|
||||||
if (IsCancellingAndYield())
|
|
||||||
break;
|
|
||||||
|
|
||||||
auto workItemRef = mPopulateTypeWorkList[workIdx];
|
|
||||||
if (workItemRef == NULL)
|
|
||||||
{
|
{
|
||||||
workIdx = mPopulateTypeWorkList.RemoveAt(workIdx);
|
//BP_ZONE("PWL_PopulateType");
|
||||||
continue;
|
if (IsCancellingAndYield())
|
||||||
}
|
break;
|
||||||
|
if (!mMidCompileWorkList.IsEmpty())
|
||||||
|
{
|
||||||
|
// Let these mid-compiles occur as soon as possible
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
BfType* type = workItemRef->mType;
|
auto workItemRef = mPopulateTypeWorkList[workIdx];
|
||||||
bool rebuildType = workItemRef->mRebuildType;
|
if (workItemRef == NULL)
|
||||||
|
{
|
||||||
|
workIdx = mPopulateTypeWorkList.RemoveAt(workIdx);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if ((onlyReifiedTypes) && (!type->IsReified()))
|
BfType* type = workItemRef->mType;
|
||||||
{
|
bool rebuildType = workItemRef->mRebuildType;
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto typeInst = type->ToTypeInstance();
|
if ((onlyReifiedTypes) && (!type->IsReified()))
|
||||||
if ((typeInst != NULL) && (resolveParser != NULL))
|
|
||||||
{
|
|
||||||
if (!typeInst->mTypeDef->GetLatest()->HasSource(resolveParser))
|
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// We want to resolve type aliases first, allowing possible mMidCompileWorkList entries
|
||||||
|
int wantPass = type->IsTypeAlias() ? 0 : 1;
|
||||||
|
if (populatePass != wantPass)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
auto typeInst = type->ToTypeInstance();
|
||||||
|
if ((typeInst != NULL) && (resolveParser != NULL))
|
||||||
|
{
|
||||||
|
if (!typeInst->mTypeDef->GetLatest()->HasSource(resolveParser))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
workIdx = mPopulateTypeWorkList.RemoveAt(workIdx);
|
||||||
|
|
||||||
|
if (rebuildType)
|
||||||
|
RebuildType(type);
|
||||||
|
|
||||||
|
BF_ASSERT(this == type->mContext);
|
||||||
|
auto useModule = type->GetModule();
|
||||||
|
if (useModule == NULL)
|
||||||
|
{
|
||||||
|
if (mCompiler->mOptions.mCompileOnDemandKind == BfCompileOnDemandKind_AlwaysInclude)
|
||||||
|
useModule = mScratchModule;
|
||||||
|
else
|
||||||
|
useModule = mUnreifiedModule;
|
||||||
|
}
|
||||||
|
if (!type->IsDeleting())
|
||||||
|
useModule->PopulateType(type, BfPopulateType_Full);
|
||||||
|
mCompiler->mStats.mQueuedTypesProcessed++;
|
||||||
|
mCompiler->UpdateCompletion();
|
||||||
|
didWork = true;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
workIdx = mPopulateTypeWorkList.RemoveAt(workIdx);
|
if ((!mMidCompileWorkList.IsEmpty()) && (didWork))
|
||||||
|
{
|
||||||
if (rebuildType)
|
// Let the mid-compile occur ASAP
|
||||||
RebuildType(type);
|
continue;
|
||||||
|
|
||||||
BF_ASSERT(this == type->mContext);
|
|
||||||
auto useModule = type->GetModule();
|
|
||||||
if (useModule == NULL)
|
|
||||||
{
|
|
||||||
if (mCompiler->mOptions.mCompileOnDemandKind == BfCompileOnDemandKind_AlwaysInclude)
|
|
||||||
useModule = mScratchModule;
|
|
||||||
else
|
|
||||||
useModule = mUnreifiedModule;
|
|
||||||
}
|
|
||||||
if (!type->IsDeleting())
|
|
||||||
useModule->PopulateType(type, BfPopulateType_Full);
|
|
||||||
mCompiler->mStats.mQueuedTypesProcessed++;
|
|
||||||
mCompiler->UpdateCompletion();
|
|
||||||
didWork = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int workIdx = 0; workIdx < (int)mTypeRefVerifyWorkList.size(); workIdx++)
|
for (int workIdx = 0; workIdx < (int)mTypeRefVerifyWorkList.size(); workIdx++)
|
||||||
|
@ -1984,6 +2003,7 @@ void BfContext::DeleteType(BfType* type, bool deferDepRebuilds)
|
||||||
}
|
}
|
||||||
else if (dependentTypeInst != NULL)
|
else if (dependentTypeInst != NULL)
|
||||||
{
|
{
|
||||||
|
mGhostDependencies.Add(type);
|
||||||
// This keeps us from crashing from accessing deleted types on subsequent compiles
|
// This keeps us from crashing from accessing deleted types on subsequent compiles
|
||||||
mFailTypes.TryAdd(dependentTypeInst, BfFailKind_Normal);
|
mFailTypes.TryAdd(dependentTypeInst, BfFailKind_Normal);
|
||||||
}
|
}
|
||||||
|
@ -2396,6 +2416,38 @@ void BfContext::UpdateRevisedTypes()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Handle these "mid-compiles" now so we handle them as early-stage
|
||||||
|
BfParser* resolveParser = NULL;
|
||||||
|
if ((mCompiler->mResolvePassData != NULL) && (!mCompiler->mResolvePassData->mParsers.IsEmpty()))
|
||||||
|
resolveParser = mCompiler->mResolvePassData->mParsers[0];
|
||||||
|
for (int workIdx = 0; workIdx < (int)mMidCompileWorkList.size(); workIdx++)
|
||||||
|
{
|
||||||
|
auto workItemRef = mMidCompileWorkList[workIdx];
|
||||||
|
if (workItemRef == NULL)
|
||||||
|
{
|
||||||
|
workIdx = mMidCompileWorkList.RemoveAt(workIdx);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
BfType* type = workItemRef->mType;
|
||||||
|
String reason = workItemRef->mReason;
|
||||||
|
|
||||||
|
auto typeInst = type->ToTypeInstance();
|
||||||
|
if ((typeInst != NULL) && (resolveParser != NULL))
|
||||||
|
{
|
||||||
|
if (!typeInst->mTypeDef->GetLatest()->HasSource(resolveParser))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
workIdx = mMidCompileWorkList.RemoveAt(workIdx);
|
||||||
|
|
||||||
|
BfLogSysM("Handling prior-revision MidCompile on type %s in early-stage UpdateRevisedTypes\n", type);
|
||||||
|
RebuildDependentTypes(type->ToDependedType());
|
||||||
|
//RebuildDependentTypes_MidCompile(type->ToDependedType(), reason);
|
||||||
|
}
|
||||||
|
|
||||||
for (auto typeInst : defEmitParentCheckQueue)
|
for (auto typeInst : defEmitParentCheckQueue)
|
||||||
{
|
{
|
||||||
if (typeInst->IsDeleting())
|
if (typeInst->IsDeleting())
|
||||||
|
@ -2675,6 +2727,8 @@ void BfContext::UpdateRevisedTypes()
|
||||||
RebuildType(type);
|
RebuildType(type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BfLogSysM("BfContext::UpdateRevisedTypes done.\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
void BfContext::VerifyTypeLookups(BfTypeInstance* typeInst)
|
void BfContext::VerifyTypeLookups(BfTypeInstance* typeInst)
|
||||||
|
@ -3459,6 +3513,7 @@ void BfContext::Cleanup()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mTypeGraveyard.Clear();
|
mTypeGraveyard.Clear();
|
||||||
|
mGhostDependencies.Clear();
|
||||||
|
|
||||||
if (!mDeletingModules.IsEmpty())
|
if (!mDeletingModules.IsEmpty())
|
||||||
{
|
{
|
||||||
|
|
|
@ -382,6 +382,7 @@ public:
|
||||||
BfModule* mScratchModule;
|
BfModule* mScratchModule;
|
||||||
BfModule* mUnreifiedModule;
|
BfModule* mUnreifiedModule;
|
||||||
HashSet<String> mUsedModuleNames;
|
HashSet<String> mUsedModuleNames;
|
||||||
|
HashSet<BfType*> mGhostDependencies; // We couldn't properly rebuild our dependencies
|
||||||
Dictionary<BfProject*, BfModule*> mProjectModule;
|
Dictionary<BfProject*, BfModule*> mProjectModule;
|
||||||
Array<BfModule*> mModules;
|
Array<BfModule*> mModules;
|
||||||
Array<BfModule*> mDeletingModules;
|
Array<BfModule*> mDeletingModules;
|
||||||
|
|
|
@ -5206,7 +5206,12 @@ BfTypedValue BfExprEvaluator::LoadField(BfAstNode* targetSrc, BfTypedValue targe
|
||||||
}
|
}
|
||||||
else if (fieldDef->mIsStatic)
|
else if (fieldDef->mIsStatic)
|
||||||
{
|
{
|
||||||
mModule->CheckStaticAccess(typeInstance);
|
if ((mModule->mAttributeState == NULL) || (mModule->mAttributeState->mCustomAttributes == NULL) ||
|
||||||
|
(!mModule->mAttributeState->mCustomAttributes->Contains(mModule->mCompiler->mNoStaticCtorAttributeTypeDef)))
|
||||||
|
{
|
||||||
|
mModule->CheckStaticAccess(typeInstance);
|
||||||
|
}
|
||||||
|
|
||||||
auto retVal = mModule->ReferenceStaticField(fieldInstance);
|
auto retVal = mModule->ReferenceStaticField(fieldInstance);
|
||||||
bool isStaticCtor = (mModule->mCurMethodInstance != NULL) &&
|
bool isStaticCtor = (mModule->mCurMethodInstance != NULL) &&
|
||||||
(mModule->mCurMethodInstance->mMethodDef->IsCtorOrInit()) &&
|
(mModule->mCurMethodInstance->mMethodDef->IsCtorOrInit()) &&
|
||||||
|
@ -6684,7 +6689,8 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, BfMethodInstance*
|
||||||
#endif
|
#endif
|
||||||
int vExtOfs = typeInst->GetOrigImplBaseVTableSize();
|
int vExtOfs = typeInst->GetOrigImplBaseVTableSize();
|
||||||
|
|
||||||
vDataIdx = mModule->mBfIRBuilder->CreateConst(BfTypeCode_Int32, 1 + mModule->mCompiler->GetDynCastVDataCount() + mModule->mCompiler->mMaxInterfaceSlots);
|
|
||||||
|
vDataIdx = mModule->mBfIRBuilder->CreateConst(BfTypeCode_Int32, mModule->mCompiler->GetVDataPrefixDataCount() + mModule->mCompiler->GetDynCastVDataCount() + mModule->mCompiler->mMaxInterfaceSlots);
|
||||||
vDataIdx = mModule->mBfIRBuilder->CreateAdd(vDataIdx, mModule->mBfIRBuilder->CreateConst(BfTypeCode_Int32, vExtOfs));
|
vDataIdx = mModule->mBfIRBuilder->CreateAdd(vDataIdx, mModule->mBfIRBuilder->CreateConst(BfTypeCode_Int32, vExtOfs));
|
||||||
BfIRValue extendPtr = mModule->mBfIRBuilder->CreateInBoundsGEP(vDataPtr, vDataIdx);
|
BfIRValue extendPtr = mModule->mBfIRBuilder->CreateInBoundsGEP(vDataPtr, vDataIdx);
|
||||||
vDataPtr = mModule->mBfIRBuilder->CreateLoad(extendPtr);
|
vDataPtr = mModule->mBfIRBuilder->CreateLoad(extendPtr);
|
||||||
|
@ -7601,7 +7607,14 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, const BfTypedValu
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
mModule->CheckStaticAccess(methodInstance->mMethodInstanceGroup->mOwner);
|
if (prevBindResult.mPrevVal == NULL)
|
||||||
|
{
|
||||||
|
if ((mModule->mAttributeState == NULL) || (mModule->mAttributeState->mCustomAttributes == NULL) ||
|
||||||
|
(!mModule->mAttributeState->mCustomAttributes->Contains(mModule->mCompiler->mNoStaticCtorAttributeTypeDef)))
|
||||||
|
{
|
||||||
|
mModule->CheckStaticAccess(methodInstance->mMethodInstanceGroup->mOwner);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (target)
|
if (target)
|
||||||
{
|
{
|
||||||
|
@ -8613,7 +8626,16 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, const BfTypedValu
|
||||||
// the type has been initialized
|
// the type has been initialized
|
||||||
auto targetTypeInst = target.mType->ToTypeInstance();
|
auto targetTypeInst = target.mType->ToTypeInstance();
|
||||||
if (targetTypeInst != NULL)
|
if (targetTypeInst != NULL)
|
||||||
mModule->CheckStaticAccess(targetTypeInst);
|
{
|
||||||
|
if (prevBindResult.mPrevVal == NULL)
|
||||||
|
{
|
||||||
|
if ((mModule->mAttributeState == NULL) || (mModule->mAttributeState->mCustomAttributes == NULL) ||
|
||||||
|
(!mModule->mAttributeState->mCustomAttributes->Contains(mModule->mCompiler->mNoStaticCtorAttributeTypeDef)))
|
||||||
|
{
|
||||||
|
mModule->CheckStaticAccess(targetTypeInst);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (methodInstance->mReturnType == NULL)
|
if (methodInstance->mReturnType == NULL)
|
||||||
|
@ -12535,7 +12557,7 @@ void BfExprEvaluator::Visit(BfCheckTypeExpression* checkTypeExpr)
|
||||||
void BfExprEvaluator::Visit(BfDynamicCastExpression* dynCastExpr)
|
void BfExprEvaluator::Visit(BfDynamicCastExpression* dynCastExpr)
|
||||||
{
|
{
|
||||||
auto targetValue = mModule->CreateValueFromExpression(dynCastExpr->mTarget);
|
auto targetValue = mModule->CreateValueFromExpression(dynCastExpr->mTarget);
|
||||||
auto targetType = mModule->ResolveTypeRefAllowUnboundGenerics(dynCastExpr->mTypeRef, BfPopulateType_Data, false);
|
auto targetType = mModule->ResolveTypeRefAllowUnboundGenerics(dynCastExpr->mTypeRef, BfPopulateType_Data, BfResolveTypeRefFlag_None, false);
|
||||||
|
|
||||||
auto autoComplete = GetAutoComplete();
|
auto autoComplete = GetAutoComplete();
|
||||||
if (autoComplete != NULL)
|
if (autoComplete != NULL)
|
||||||
|
@ -18843,6 +18865,10 @@ void BfExprEvaluator::DoInvocation(BfAstNode* target, BfMethodBoundExpression* m
|
||||||
checkedKind = BfCheckedKind_Unchecked;
|
checkedKind = BfCheckedKind_Unchecked;
|
||||||
mModule->mAttributeState->mUsed = true;
|
mModule->mAttributeState->mUsed = true;
|
||||||
}
|
}
|
||||||
|
if (mModule->mAttributeState->mCustomAttributes->Contains(mModule->mCompiler->mNoStaticCtorAttributeTypeDef))
|
||||||
|
{
|
||||||
|
mModule->mAttributeState->mUsed = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((isCascade) && (cascadeOperatorToken != NULL) && ((mBfEvalExprFlags & BfEvalExprFlags_Comptime) != 0))
|
if ((isCascade) && (cascadeOperatorToken != NULL) && ((mBfEvalExprFlags & BfEvalExprFlags_Comptime) != 0))
|
||||||
|
@ -20967,7 +20993,7 @@ void BfExprEvaluator::InitializedSizedArray(BfSizedArrayType* arrayType, BfToken
|
||||||
}
|
}
|
||||||
|
|
||||||
elementValue = mModule->LoadOrAggregateValue(elementValue);
|
elementValue = mModule->LoadOrAggregateValue(elementValue);
|
||||||
if (!elementValue.mValue.IsConst())
|
if (!elemPtrValue.IsConst())
|
||||||
mModule->mBfIRBuilder->CreateAlignedStore(elementValue.mValue, elemPtrValue, checkArrayType->mElementType->mAlign);
|
mModule->mBfIRBuilder->CreateAlignedStore(elementValue.mValue, elemPtrValue, checkArrayType->mElementType->mAlign);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5391,6 +5391,8 @@ BfIRValue BfModule::CreateClassVDataGlobal(BfTypeInstance* typeInstance, int* ou
|
||||||
mClassVDataRefs.TryGetValue(typeInstance, &globalVariablePtr);
|
mClassVDataRefs.TryGetValue(typeInstance, &globalVariablePtr);
|
||||||
|
|
||||||
int numElements = 1;
|
int numElements = 1;
|
||||||
|
if (mSystem->mPtrSize == 4)
|
||||||
|
numElements++;
|
||||||
|
|
||||||
if ((outNumElements != NULL) || (globalVariablePtr == NULL))
|
if ((outNumElements != NULL) || (globalVariablePtr == NULL))
|
||||||
{
|
{
|
||||||
|
@ -5432,11 +5434,6 @@ BfIRValue BfModule::CreateClassVDataGlobal(BfTypeInstance* typeInstance, int* ou
|
||||||
if (outMangledName != NULL)
|
if (outMangledName != NULL)
|
||||||
*outMangledName = classVDataName;
|
*outMangledName = classVDataName;
|
||||||
|
|
||||||
/*if (itr != mClassVDataRefs.end())
|
|
||||||
{
|
|
||||||
globalVariable = itr->second;
|
|
||||||
}*/
|
|
||||||
|
|
||||||
BfIRValue globalVariable;
|
BfIRValue globalVariable;
|
||||||
if (globalVariablePtr != NULL)
|
if (globalVariablePtr != NULL)
|
||||||
{
|
{
|
||||||
|
@ -5937,7 +5934,21 @@ BfIRValue BfModule::CreateFieldData(BfFieldInstance* fieldInstance, int customAt
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary<int, int>& usedStringIdMap, bool forceReflectFields, bool needsTypeData, bool needsTypeNames, bool needsVData)
|
void BfModule::CreateSlotOfs(BfTypeInstance* typeInstance)
|
||||||
|
{
|
||||||
|
int virtSlotIdx = -1;
|
||||||
|
if ((typeInstance != NULL) && (typeInstance->mSlotNum >= 0))
|
||||||
|
virtSlotIdx = typeInstance->mSlotNum + mCompiler->GetVDataPrefixDataCount() + mCompiler->GetDynCastVDataCount();
|
||||||
|
|
||||||
|
// For interfaces we ONLY emit the slot num
|
||||||
|
StringT<512> slotVarName;
|
||||||
|
BfMangler::MangleStaticFieldName(slotVarName, mCompiler->GetMangleKind(), typeInstance, "sBfSlotOfs");
|
||||||
|
auto intType = GetPrimitiveType(BfTypeCode_Int32);
|
||||||
|
auto slotNumVar = mBfIRBuilder->CreateGlobalVariable(mBfIRBuilder->MapType(intType), true, BfIRLinkageType_External,
|
||||||
|
GetConstValue32(virtSlotIdx), slotVarName);
|
||||||
|
}
|
||||||
|
|
||||||
|
BfIRValue BfModule::CreateTypeData(BfType* type, BfCreateTypeDataContext& ctx, bool forceReflectFields, bool needsTypeData, bool needsTypeNames, bool needsVData)
|
||||||
{
|
{
|
||||||
if ((IsHotCompile()) && (!type->mDirty))
|
if ((IsHotCompile()) && (!type->mDirty))
|
||||||
return BfIRValue();
|
return BfIRValue();
|
||||||
|
@ -6004,13 +6015,18 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary<int, int>& usedStrin
|
||||||
|
|
||||||
if ((!mTypeDataRefs.ContainsKey(typeDataSource)) && (typeDataSource != type) && (!mIsComptimeModule))
|
if ((!mTypeDataRefs.ContainsKey(typeDataSource)) && (typeDataSource != type) && (!mIsComptimeModule))
|
||||||
{
|
{
|
||||||
CreateTypeData(typeDataSource, usedStringIdMap, false, true, needsTypeNames, true);
|
CreateTypeData(typeDataSource, ctx, false, true, needsTypeNames, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
typeTypeData = CreateClassVDataGlobal(typeDataSource);
|
typeTypeData = CreateClassVDataGlobal(typeDataSource);
|
||||||
|
|
||||||
|
ctx.mReflectTypeSet.Add(typeDataSource);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
typeTypeData = CreateClassVDataGlobal(typeInstanceType->ToTypeInstance());
|
{
|
||||||
|
//typeTypeData = CreateClassVDataGlobal(typeInstanceType->ToTypeInstance());
|
||||||
|
typeTypeData = mBfIRBuilder->CreateConstNull();
|
||||||
|
}
|
||||||
|
|
||||||
BfType* longType = GetPrimitiveType(BfTypeCode_Int64);
|
BfType* longType = GetPrimitiveType(BfTypeCode_Int64);
|
||||||
BfType* intType = GetPrimitiveType(BfTypeCode_Int32);
|
BfType* intType = GetPrimitiveType(BfTypeCode_Int32);
|
||||||
|
@ -6119,7 +6135,7 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary<int, int>& usedStrin
|
||||||
|
|
||||||
int virtSlotIdx = -1;
|
int virtSlotIdx = -1;
|
||||||
if ((typeInstance != NULL) && (typeInstance->mSlotNum >= 0))
|
if ((typeInstance != NULL) && (typeInstance->mSlotNum >= 0))
|
||||||
virtSlotIdx = typeInstance->mSlotNum + 1 + mCompiler->GetDynCastVDataCount();
|
virtSlotIdx = typeInstance->mSlotNum + mCompiler->GetVDataPrefixDataCount() + mCompiler->GetDynCastVDataCount();
|
||||||
int memberDataOffset = 0;
|
int memberDataOffset = 0;
|
||||||
if (type->IsInterface())
|
if (type->IsInterface())
|
||||||
memberDataOffset = virtSlotIdx * mSystem->mPtrSize;
|
memberDataOffset = virtSlotIdx * mSystem->mPtrSize;
|
||||||
|
@ -6316,18 +6332,13 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary<int, int>& usedStrin
|
||||||
String classVDataName;
|
String classVDataName;
|
||||||
if (typeInstance->mSlotNum >= 0)
|
if (typeInstance->mSlotNum >= 0)
|
||||||
{
|
{
|
||||||
// For interfaces we ONLY emit the slot num
|
CreateSlotOfs(typeInstance);
|
||||||
StringT<512> slotVarName;
|
|
||||||
BfMangler::MangleStaticFieldName(slotVarName, mCompiler->GetMangleKind(), typeInstance, "sBfSlotOfs");
|
|
||||||
auto intType = GetPrimitiveType(BfTypeCode_Int32);
|
|
||||||
auto slotNumVar = mBfIRBuilder->CreateGlobalVariable(mBfIRBuilder->MapType(intType), true, BfIRLinkageType_External,
|
|
||||||
GetConstValue32(virtSlotIdx), slotVarName);
|
|
||||||
}
|
}
|
||||||
else if ((typeInstance->IsObject()) && (!typeInstance->IsUnspecializedType()) && (needsVData))
|
else if ((typeInstance->IsObject()) && (!typeInstance->IsUnspecializedType()) && (needsVData))
|
||||||
{
|
{
|
||||||
int dynCastDataElems = 0;
|
int dynCastDataElems = 0;
|
||||||
int numElements = 1;
|
int numElements = 1;
|
||||||
int vDataOfs = 1; // The number of intptrs before the iface slot map
|
int vDataOfs = mCompiler->GetVDataPrefixDataCount(); // The number of intptrs before the iface slot map
|
||||||
numElements += mCompiler->mMaxInterfaceSlots;
|
numElements += mCompiler->mMaxInterfaceSlots;
|
||||||
if (!typeInstance->IsInterface())
|
if (!typeInstance->IsInterface())
|
||||||
{
|
{
|
||||||
|
@ -6342,7 +6353,8 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary<int, int>& usedStrin
|
||||||
classVDataVar = CreateClassVDataGlobal(typeInstance, &expectNumElements, &classVDataName);
|
classVDataVar = CreateClassVDataGlobal(typeInstance, &expectNumElements, &classVDataName);
|
||||||
}
|
}
|
||||||
|
|
||||||
vData.push_back(BfIRValue()); // Type*
|
for (int i = 0; i < mCompiler->GetVDataPrefixDataCount(); i++)
|
||||||
|
vData.push_back(BfIRValue()); // Type
|
||||||
|
|
||||||
SizedArray<BfIRValue, 1> extVTableData;
|
SizedArray<BfIRValue, 1> extVTableData;
|
||||||
|
|
||||||
|
@ -6752,6 +6764,9 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary<int, int>& usedStrin
|
||||||
// Force override of GetHashCode so we use the pointer address as the hash code
|
// Force override of GetHashCode so we use the pointer address as the hash code
|
||||||
for (auto& checkIFace : checkTypeInst->mInterfaces)
|
for (auto& checkIFace : checkTypeInst->mInterfaces)
|
||||||
{
|
{
|
||||||
|
if (checkIFace.mStartVirtualIdx < 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
for (int methodIdx = 0; methodIdx < (int)checkIFace.mInterfaceType->mMethodInstanceGroups.size(); methodIdx++)
|
for (int methodIdx = 0; methodIdx < (int)checkIFace.mInterfaceType->mMethodInstanceGroups.size(); methodIdx++)
|
||||||
{
|
{
|
||||||
BfIRValue pushValue;
|
BfIRValue pushValue;
|
||||||
|
@ -6976,7 +6991,7 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary<int, int>& usedStrin
|
||||||
for (auto arg : attr->mCtorArgs)
|
for (auto arg : attr->mCtorArgs)
|
||||||
{
|
{
|
||||||
auto argType = ctorMethodInstance->GetParamType(argIdx);
|
auto argType = ctorMethodInstance->GetParamType(argIdx);
|
||||||
EncodeAttributeData(typeInstance, argType, arg, data, usedStringIdMap);
|
EncodeAttributeData(typeInstance, argType, arg, data, ctx.mUsedStringIdMap);
|
||||||
argIdx++;
|
argIdx++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7494,7 +7509,7 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary<int, int>& usedStrin
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
vDataIdx = 1 + mCompiler->GetDynCastVDataCount() + mCompiler->mMaxInterfaceSlots;
|
vDataIdx = mCompiler->GetVDataPrefixDataCount() + mCompiler->GetDynCastVDataCount() + mCompiler->mMaxInterfaceSlots;
|
||||||
if ((mCompiler->mOptions.mHasVDataExtender) && (mCompiler->IsHotCompile()))
|
if ((mCompiler->mOptions.mHasVDataExtender) && (mCompiler->IsHotCompile()))
|
||||||
{
|
{
|
||||||
auto typeInst = defaultMethod->mMethodInstanceGroup->mOwner;
|
auto typeInst = defaultMethod->mMethodInstanceGroup->mOwner;
|
||||||
|
@ -7560,7 +7575,7 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary<int, int>& usedStrin
|
||||||
BfIRType interfaceDataPtrType = mBfIRBuilder->GetPointerTo(mBfIRBuilder->MapType(reflectInterfaceDataType));
|
BfIRType interfaceDataPtrType = mBfIRBuilder->GetPointerTo(mBfIRBuilder->MapType(reflectInterfaceDataType));
|
||||||
Array<bool> wantsIfaceMethod;
|
Array<bool> wantsIfaceMethod;
|
||||||
bool wantsIfaceMethods = false;
|
bool wantsIfaceMethods = false;
|
||||||
if (typeInstance->mInterfaces.IsEmpty())
|
if ((typeInstance->mInterfaces.IsEmpty()) || (!needsTypeData))
|
||||||
interfaceDataPtr = mBfIRBuilder->CreateConstNull(interfaceDataPtrType);
|
interfaceDataPtr = mBfIRBuilder->CreateConstNull(interfaceDataPtrType);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -7802,7 +7817,22 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary<int, int>& usedStrin
|
||||||
{
|
{
|
||||||
BF_ASSERT(!classVDataName.IsEmpty());
|
BF_ASSERT(!classVDataName.IsEmpty());
|
||||||
|
|
||||||
vData[0] = mBfIRBuilder->CreateBitCast(typeDataVar, voidPtrIRType);
|
//vData[0] = mBfIRBuilder->CreateBitCast(typeDataVar, voidPtrIRType);
|
||||||
|
|
||||||
|
int unboxedTypeId = type->mTypeId;
|
||||||
|
if (type->IsBoxed())
|
||||||
|
unboxedTypeId = type->GetUnderlyingType()->mTypeId;
|
||||||
|
|
||||||
|
if (mSystem->mPtrSize == 4)
|
||||||
|
{
|
||||||
|
vData[0] = mBfIRBuilder->CreateIntToPtr(GetConstValue(type->mTypeId, intPtrType), voidPtrIRType);
|
||||||
|
vData[1] = mBfIRBuilder->CreateIntToPtr(GetConstValue(unboxedTypeId, intPtrType), voidPtrIRType);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
vData[0] = mBfIRBuilder->CreateIntToPtr(GetConstValue(((int64)unboxedTypeId << 32) | type->mTypeId, intPtrType), voidPtrIRType);
|
||||||
|
}
|
||||||
|
|
||||||
auto classVDataConstDataType = mBfIRBuilder->GetSizedArrayType(voidPtrIRType, (int)vData.size());
|
auto classVDataConstDataType = mBfIRBuilder->GetSizedArrayType(voidPtrIRType, (int)vData.size());
|
||||||
auto classVDataConstData = mBfIRBuilder->CreateConstAgg_Value(classVDataConstDataType, vData);
|
auto classVDataConstData = mBfIRBuilder->CreateConstAgg_Value(classVDataConstDataType, vData);
|
||||||
|
|
||||||
|
@ -10459,18 +10489,24 @@ void BfModule::EmitObjectAccessCheck(BfTypedValue typedVal)
|
||||||
mBfIRBuilder->CreateObjectAccessCheck(typedVal.mValue, !IsOptimized());
|
mBfIRBuilder->CreateObjectAccessCheck(typedVal.mValue, !IsOptimized());
|
||||||
}
|
}
|
||||||
|
|
||||||
void BfModule::EmitEnsureInstructionAt()
|
bool BfModule::WantsDebugHelpers()
|
||||||
{
|
{
|
||||||
if (mBfIRBuilder->mIgnoreWrites)
|
if (mBfIRBuilder->mIgnoreWrites)
|
||||||
return;
|
return false;
|
||||||
|
|
||||||
if (mIsComptimeModule)
|
if (mIsComptimeModule)
|
||||||
{
|
{
|
||||||
// Always add
|
// Always add
|
||||||
}
|
}
|
||||||
else if ((mProject == NULL) || (!mHasFullDebugInfo) || (IsOptimized()) || (mCompiler->mOptions.mOmitDebugHelpers))
|
else if ((mProject == NULL) || (!mHasFullDebugInfo) || (IsOptimized()) || (mCompiler->mOptions.mOmitDebugHelpers))
|
||||||
return;
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void BfModule::EmitEnsureInstructionAt()
|
||||||
|
{
|
||||||
|
if (!WantsDebugHelpers())
|
||||||
|
return;
|
||||||
mBfIRBuilder->CreateEnsureInstructionAt();
|
mBfIRBuilder->CreateEnsureInstructionAt();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10549,7 +10585,7 @@ void BfModule::EmitDynamicCastCheck(const BfTypedValue& targetValue, BfType* tar
|
||||||
targetType = GetWrappedStructType(targetType);
|
targetType = GetWrappedStructType(targetType);
|
||||||
|
|
||||||
AddDependency(targetType, mCurTypeInstance, BfDependencyMap::DependencyFlag_ExprTypeReference);
|
AddDependency(targetType, mCurTypeInstance, BfDependencyMap::DependencyFlag_ExprTypeReference);
|
||||||
int inheritanceIdOfs = mSystem->mPtrSize;
|
int inheritanceIdOfs = mSystem->mPtrSize * mCompiler->GetVDataPrefixDataCount();
|
||||||
vDataPtr = irb->CreateAdd(vDataPtr, irb->CreateConst(BfTypeCode_IntPtr, inheritanceIdOfs));
|
vDataPtr = irb->CreateAdd(vDataPtr, irb->CreateConst(BfTypeCode_IntPtr, inheritanceIdOfs));
|
||||||
vDataPtr = irb->CreateIntToPtr(vDataPtr, irb->MapType(int32PtrType));
|
vDataPtr = irb->CreateIntToPtr(vDataPtr, irb->MapType(int32PtrType));
|
||||||
BfIRValue objInheritanceId = irb->CreateLoad(vDataPtr);
|
BfIRValue objInheritanceId = irb->CreateLoad(vDataPtr);
|
||||||
|
@ -11107,6 +11143,9 @@ BfModuleMethodInstance BfModule::GetMethodInstanceAtIdx(BfTypeInstance* typeInst
|
||||||
|
|
||||||
PopulateType(typeInstance, BfPopulateType_DataAndMethods);
|
PopulateType(typeInstance, BfPopulateType_DataAndMethods);
|
||||||
|
|
||||||
|
if (methodIdx >= typeInstance->mMethodInstanceGroups.mSize)
|
||||||
|
return BfModuleMethodInstance();
|
||||||
|
|
||||||
auto methodInstance = typeInstance->mMethodInstanceGroups[methodIdx].mDefault;
|
auto methodInstance = typeInstance->mMethodInstanceGroups[methodIdx].mDefault;
|
||||||
|
|
||||||
BfMethodDef* methodDef = NULL;
|
BfMethodDef* methodDef = NULL;
|
||||||
|
@ -14003,7 +14042,7 @@ BfModule* BfModule::GetOrCreateMethodModule(BfMethodInstance* methodInstance)
|
||||||
return declareModule;
|
return declareModule;
|
||||||
}
|
}
|
||||||
|
|
||||||
BfModuleMethodInstance BfModule::GetMethodInstance(BfTypeInstance* typeInst, BfMethodDef* methodDef, const BfTypeVector& methodGenericArguments, BfGetMethodInstanceFlags flags, BfTypeInstance* foreignType)
|
BfModuleMethodInstance BfModule::GetMethodInstance(BfTypeInstance* typeInst, BfMethodDef* methodDef, const BfTypeVector& methodGenericArguments, BfGetMethodInstanceFlags flags, BfTypeInstance* foreignType, BfModule* referencingModule)
|
||||||
{
|
{
|
||||||
if (methodDef->mMethodType == BfMethodType_Init)
|
if (methodDef->mMethodType == BfMethodType_Init)
|
||||||
return BfModuleMethodInstance();
|
return BfModuleMethodInstance();
|
||||||
|
@ -14129,6 +14168,8 @@ BfModuleMethodInstance BfModule::GetMethodInstance(BfTypeInstance* typeInst, BfM
|
||||||
instModule->mReifyQueued = true;
|
instModule->mReifyQueued = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BfLogSysM("REIFIED(GetMethodInstance QueueSpecializationRequest): %s %s MethodDef:%p RefModule:%s RefMethod:%p\n", TypeToString(typeInst).c_str(), methodDef->mName.c_str(), methodDef, mModuleName.c_str(), mCurMethodInstance);
|
||||||
|
|
||||||
// This ensures that the method will actually be created when it gets reified
|
// This ensures that the method will actually be created when it gets reified
|
||||||
BfMethodSpecializationRequest* specializationRequest = mContext->mMethodSpecializationWorkList.Alloc();
|
BfMethodSpecializationRequest* specializationRequest = mContext->mMethodSpecializationWorkList.Alloc();
|
||||||
specializationRequest->mFromModule = typeInst->mModule;
|
specializationRequest->mFromModule = typeInst->mModule;
|
||||||
|
@ -14154,7 +14195,7 @@ BfModuleMethodInstance BfModule::GetMethodInstance(BfTypeInstance* typeInst, BfM
|
||||||
|
|
||||||
// Not extern
|
// Not extern
|
||||||
// Create the instance in the proper module and then create a reference in this one
|
// Create the instance in the proper module and then create a reference in this one
|
||||||
moduleMethodInst = instModule->GetMethodInstance(typeInst, methodDef, methodGenericArguments, defFlags, foreignType);
|
moduleMethodInst = instModule->GetMethodInstance(typeInst, methodDef, methodGenericArguments, defFlags, foreignType, this);
|
||||||
if (!moduleMethodInst)
|
if (!moduleMethodInst)
|
||||||
return moduleMethodInst;
|
return moduleMethodInst;
|
||||||
tryModuleMethodLookup = true;
|
tryModuleMethodLookup = true;
|
||||||
|
@ -14549,8 +14590,18 @@ BfModuleMethodInstance BfModule::GetMethodInstance(BfTypeInstance* typeInst, BfM
|
||||||
/*if ((!mCompiler->mIsResolveOnly) && (!isReified))
|
/*if ((!mCompiler->mIsResolveOnly) && (!isReified))
|
||||||
BF_ASSERT(!methodInstance->mIsReified);*/
|
BF_ASSERT(!methodInstance->mIsReified);*/
|
||||||
|
|
||||||
|
if ((!mCompiler->mIsResolveOnly) && (isReified))
|
||||||
|
{
|
||||||
|
auto refModule = referencingModule;
|
||||||
|
if (refModule == NULL)
|
||||||
|
refModule = this;
|
||||||
|
BfLogSysM("REIFIED(GetMethodInstance Reference): %s MethodDef:%p MethodInst:%p RefModule:%s RefMethod:%p\n", methodInstance->mMethodDef->mName.c_str(), methodDef, methodInstance, refModule->mModuleName.c_str(), refModule->mCurMethodInstance);
|
||||||
|
}
|
||||||
|
|
||||||
if (methodInstance->mIsReified != isReified)
|
if (methodInstance->mIsReified != isReified)
|
||||||
|
{
|
||||||
BfLogSysM("GetMethodInstance %p Decl_AwaitingReference setting reified to %d\n", methodInstance, isReified);
|
BfLogSysM("GetMethodInstance %p Decl_AwaitingReference setting reified to %d\n", methodInstance, isReified);
|
||||||
|
}
|
||||||
|
|
||||||
if ((!isReified) &&
|
if ((!isReified) &&
|
||||||
((methodInstance->mDeclModule == NULL) || (!methodInstance->mDeclModule->mIsModuleMutable)))
|
((methodInstance->mDeclModule == NULL) || (!methodInstance->mDeclModule->mIsModuleMutable)))
|
||||||
|
@ -14975,6 +15026,9 @@ BfIRValue BfModule::GetInterfaceSlotNum(BfTypeInstance* ifaceType)
|
||||||
|
|
||||||
globalValue = mBfIRBuilder->CreateGlobalVariable(mBfIRBuilder->MapType(intType), true, BfIRLinkageType_External, value, slotVarName);
|
globalValue = mBfIRBuilder->CreateGlobalVariable(mBfIRBuilder->MapType(intType), true, BfIRLinkageType_External, value, slotVarName);
|
||||||
mInterfaceSlotRefs[ifaceType] = globalValue;
|
mInterfaceSlotRefs[ifaceType] = globalValue;
|
||||||
|
// Make sure we reify
|
||||||
|
PopulateType(ifaceType, BfPopulateType_Declaration);
|
||||||
|
AddDependency(ifaceType, mCurTypeInstance, BfDependencyMap::DependencyFlag_StaticValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
return mBfIRBuilder->CreateAlignedLoad(globalValue/*, "slotOfs"*/, 4);
|
return mBfIRBuilder->CreateAlignedLoad(globalValue/*, "slotOfs"*/, 4);
|
||||||
|
@ -20087,6 +20141,26 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup,
|
||||||
if (mAwaitingInitFinish)
|
if (mAwaitingInitFinish)
|
||||||
FinishInit();
|
FinishInit();
|
||||||
|
|
||||||
|
if ((methodInstance->mIsReified) && (!mCompiler->mIsResolveOnly))
|
||||||
|
{
|
||||||
|
BfLogSysM("REIFIED(ProcessMethod): %s %p Module: %s\n", methodInstance->mMethodDef->mName.c_str(), methodInstance, mModuleName.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reify types that are actually used - they don't get reified during method declaration
|
||||||
|
if ((!mCompiler->mIsResolveOnly) && (mIsReified))
|
||||||
|
{
|
||||||
|
auto _CheckType = [&](BfType* type)
|
||||||
|
{
|
||||||
|
if (!type->IsReified())
|
||||||
|
PopulateType(type, BfPopulateType_Declaration);
|
||||||
|
};
|
||||||
|
_CheckType(methodInstance->mReturnType);
|
||||||
|
for (auto& param : methodInstance->mParams)
|
||||||
|
{
|
||||||
|
_CheckType(param.mResolvedType);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!methodInstance->mIsReified)
|
if (!methodInstance->mIsReified)
|
||||||
BF_ASSERT(!mIsReified);
|
BF_ASSERT(!mIsReified);
|
||||||
|
|
||||||
|
@ -22047,8 +22121,11 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup,
|
||||||
if ((retVal) && (!retVal.mType->IsVar()) && (expectingType != NULL))
|
if ((retVal) && (!retVal.mType->IsVar()) && (expectingType != NULL))
|
||||||
{
|
{
|
||||||
mCurMethodState->mHadReturn = true;
|
mCurMethodState->mHadReturn = true;
|
||||||
retVal = LoadOrAggregateValue(retVal);
|
if (!mCurMethodState->mLeftBlockUncond)
|
||||||
EmitReturn(retVal);
|
{
|
||||||
|
retVal = LoadOrAggregateValue(retVal);
|
||||||
|
EmitReturn(retVal);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -23719,6 +23796,8 @@ void BfModule::DoMethodDeclaration(BfMethodDeclaration* methodDeclaration, bool
|
||||||
BfTypeState typeState(mCurTypeInstance);
|
BfTypeState typeState(mCurTypeInstance);
|
||||||
SetAndRestoreValue<BfTypeState*> prevTypeState(mContext->mCurTypeState, &typeState);
|
SetAndRestoreValue<BfTypeState*> prevTypeState(mContext->mCurTypeState, &typeState);
|
||||||
|
|
||||||
|
BfModule* resolveModule = mContext->mUnreifiedModule;
|
||||||
|
|
||||||
if (mCompiler->IsAutocomplete())
|
if (mCompiler->IsAutocomplete())
|
||||||
prevIsCapturingMethodMatchInfo.Init(mCompiler->mResolvePassData->mAutoComplete->mIsCapturingMethodMatchInfo, false);
|
prevIsCapturingMethodMatchInfo.Init(mCompiler->mResolvePassData->mAutoComplete->mIsCapturingMethodMatchInfo, false);
|
||||||
|
|
||||||
|
@ -23963,7 +24042,7 @@ void BfModule::DoMethodDeclaration(BfMethodDeclaration* methodDeclaration, bool
|
||||||
mIgnoreErrors = false;
|
mIgnoreErrors = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
BfResolveTypeRefFlags flags = (BfResolveTypeRefFlags)(BfResolveTypeRefFlag_NoResolveGenericParam | BfResolveTypeRefFlag_AllowRef | BfResolveTypeRefFlag_AllowRefGeneric);
|
BfResolveTypeRefFlags flags = (BfResolveTypeRefFlags)(BfResolveTypeRefFlag_NoResolveGenericParam | BfResolveTypeRefFlag_AllowRef | BfResolveTypeRefFlag_AllowRefGeneric | BfResolveTypeRefFlag_NoReify);
|
||||||
|
|
||||||
if ((((methodInstance->mComptimeFlags & BfComptimeFlag_ConstEval) != 0) || (methodInstance->mIsAutocompleteMethod))
|
if ((((methodInstance->mComptimeFlags & BfComptimeFlag_ConstEval) != 0) || (methodInstance->mIsAutocompleteMethod))
|
||||||
&& (methodDef->mReturnTypeRef->IsA<BfVarTypeReference>()))
|
&& (methodDef->mReturnTypeRef->IsA<BfVarTypeReference>()))
|
||||||
|
@ -24055,14 +24134,14 @@ void BfModule::DoMethodDeclaration(BfMethodDeclaration* methodDeclaration, bool
|
||||||
{
|
{
|
||||||
BfTypeUtils::SplatIterate([&](BfType* checkType)
|
BfTypeUtils::SplatIterate([&](BfType* checkType)
|
||||||
{
|
{
|
||||||
PopulateType(checkType, BfPopulateType_Data);
|
resolveModule->PopulateType(checkType, BfPopulateType_Data);
|
||||||
}, thisType);
|
}, thisType);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
thisType = mCurTypeInstance;
|
thisType = mCurTypeInstance;
|
||||||
PopulateType(thisType, BfPopulateType_Declaration);
|
resolveModule->PopulateType(thisType, BfPopulateType_Declaration);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -24137,7 +24216,7 @@ void BfModule::DoMethodDeclaration(BfMethodDeclaration* methodDeclaration, bool
|
||||||
bool wasGenericParam = false;
|
bool wasGenericParam = false;
|
||||||
if (resolvedParamType == NULL)
|
if (resolvedParamType == NULL)
|
||||||
{
|
{
|
||||||
BfResolveTypeRefFlags resolveFlags = (BfResolveTypeRefFlags)(BfResolveTypeRefFlag_NoResolveGenericParam | BfResolveTypeRefFlag_AllowRef | BfResolveTypeRefFlag_AllowRefGeneric | BfResolveTypeRefFlag_AllowGenericMethodParamConstValue);
|
BfResolveTypeRefFlags resolveFlags = (BfResolveTypeRefFlags)(BfResolveTypeRefFlag_NoResolveGenericParam | BfResolveTypeRefFlag_AllowRef | BfResolveTypeRefFlag_AllowRefGeneric | BfResolveTypeRefFlag_AllowGenericMethodParamConstValue | BfResolveTypeRefFlag_NoReify);
|
||||||
if (paramDef->mParamKind == BfParamKind_ExplicitThis)
|
if (paramDef->mParamKind == BfParamKind_ExplicitThis)
|
||||||
resolveFlags = (BfResolveTypeRefFlags)(resolveFlags | BfResolveTypeRefFlag_NoWarnOnMut);
|
resolveFlags = (BfResolveTypeRefFlags)(resolveFlags | BfResolveTypeRefFlag_NoWarnOnMut);
|
||||||
resolvedParamType = ResolveTypeRef(paramDef->mTypeRef, BfPopulateType_Declaration, resolveFlags);
|
resolvedParamType = ResolveTypeRef(paramDef->mTypeRef, BfPopulateType_Declaration, resolveFlags);
|
||||||
|
@ -24388,7 +24467,7 @@ void BfModule::DoMethodDeclaration(BfMethodDeclaration* methodDeclaration, bool
|
||||||
}
|
}
|
||||||
|
|
||||||
int argIdx = 0;
|
int argIdx = 0;
|
||||||
PopulateType(methodInstance->mReturnType, BfPopulateType_Data);
|
resolveModule->PopulateType(methodInstance->mReturnType, BfPopulateType_Data);
|
||||||
if ((!methodDef->mIsStatic) && (!methodDef->mHasExplicitThis))
|
if ((!methodDef->mIsStatic) && (!methodDef->mHasExplicitThis))
|
||||||
{
|
{
|
||||||
int thisIdx = methodDef->mHasExplicitThis ? 0 : -1;
|
int thisIdx = methodDef->mHasExplicitThis ? 0 : -1;
|
||||||
|
@ -24428,7 +24507,7 @@ void BfModule::DoMethodDeclaration(BfMethodDeclaration* methodDeclaration, bool
|
||||||
}
|
}
|
||||||
else if ((checkType->IsComposite()) && (methodInstance->AllowsSplatting(paramIdx)))
|
else if ((checkType->IsComposite()) && (methodInstance->AllowsSplatting(paramIdx)))
|
||||||
{
|
{
|
||||||
PopulateType(checkType, BfPopulateType_Data);
|
resolveModule->PopulateType(checkType, BfPopulateType_Data);
|
||||||
if (checkType->IsSplattable())
|
if (checkType->IsSplattable())
|
||||||
{
|
{
|
||||||
bool isSplat = false;
|
bool isSplat = false;
|
||||||
|
@ -24569,7 +24648,7 @@ void BfModule::DoMethodDeclaration(BfMethodDeclaration* methodDeclaration, bool
|
||||||
{
|
{
|
||||||
auto paramType = methodInstance->GetParamType(paramIdx);
|
auto paramType = methodInstance->GetParamType(paramIdx);
|
||||||
if (paramType->IsComposite())
|
if (paramType->IsComposite())
|
||||||
PopulateType(paramType, BfPopulateType_Data);
|
resolveModule->PopulateType(paramType, BfPopulateType_Data);
|
||||||
|
|
||||||
if (!methodInstance->IsParamSkipped(paramIdx))
|
if (!methodInstance->IsParamSkipped(paramIdx))
|
||||||
{
|
{
|
||||||
|
@ -24588,7 +24667,7 @@ void BfModule::DoMethodDeclaration(BfMethodDeclaration* methodDeclaration, bool
|
||||||
if (methodInstance->mIsUnspecializedVariation)
|
if (methodInstance->mIsUnspecializedVariation)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
PopulateType(resolvedReturnType, BfPopulateType_Data);
|
resolveModule->PopulateType(resolvedReturnType, BfPopulateType_Data);
|
||||||
auto retLLVMType = mBfIRBuilder->MapType(resolvedReturnType);
|
auto retLLVMType = mBfIRBuilder->MapType(resolvedReturnType);
|
||||||
if (resolvedReturnType->IsValuelessType())
|
if (resolvedReturnType->IsValuelessType())
|
||||||
retLLVMType = mBfIRBuilder->GetPrimitiveType(BfTypeCode_None);
|
retLLVMType = mBfIRBuilder->GetPrimitiveType(BfTypeCode_None);
|
||||||
|
@ -26023,21 +26102,24 @@ void BfModule::DbgFinish()
|
||||||
if (mBfIRBuilder->DbgHasInfo())
|
if (mBfIRBuilder->DbgHasInfo())
|
||||||
{
|
{
|
||||||
bool needForceLinking = false;
|
bool needForceLinking = false;
|
||||||
for (auto& ownedType : mOwnedTypeInstances)
|
if (WantsDebugHelpers())
|
||||||
{
|
{
|
||||||
bool hasConfirmedReference = false;
|
for (auto& ownedType : mOwnedTypeInstances)
|
||||||
for (auto& methodInstGroup : ownedType->mMethodInstanceGroups)
|
|
||||||
{
|
{
|
||||||
if ((methodInstGroup.IsImplemented()) && (methodInstGroup.mDefault != NULL) &&
|
bool hasConfirmedReference = false;
|
||||||
(!methodInstGroup.mDefault->mMethodDef->mIsStatic) && (methodInstGroup.mDefault->mIsReified) && (!methodInstGroup.mDefault->mAlwaysInline) &&
|
for (auto& methodInstGroup : ownedType->mMethodInstanceGroups)
|
||||||
((methodInstGroup.mOnDemandKind == BfMethodOnDemandKind_AlwaysInclude) || (methodInstGroup.mOnDemandKind == BfMethodOnDemandKind_Referenced)) &&
|
|
||||||
(methodInstGroup.mHasEmittedReference))
|
|
||||||
{
|
{
|
||||||
hasConfirmedReference = true;
|
if ((methodInstGroup.IsImplemented()) && (methodInstGroup.mDefault != NULL) &&
|
||||||
|
(!methodInstGroup.mDefault->mMethodDef->mIsStatic) && (methodInstGroup.mDefault->mIsReified) && (!methodInstGroup.mDefault->mAlwaysInline) &&
|
||||||
|
((methodInstGroup.mOnDemandKind == BfMethodOnDemandKind_AlwaysInclude) || (methodInstGroup.mOnDemandKind == BfMethodOnDemandKind_Referenced)) &&
|
||||||
|
(methodInstGroup.mHasEmittedReference))
|
||||||
|
{
|
||||||
|
hasConfirmedReference = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
if ((!hasConfirmedReference) || (ownedType->IsBoxed()))
|
||||||
|
needForceLinking = true;
|
||||||
}
|
}
|
||||||
if ((!hasConfirmedReference) || (ownedType->IsBoxed()))
|
|
||||||
needForceLinking = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((needForceLinking) && (mProject->mCodeGenOptions.mAsmKind == BfAsmKind_None))
|
if ((needForceLinking) && (mProject->mCodeGenOptions.mAsmKind == BfAsmKind_None))
|
||||||
|
@ -26153,7 +26235,7 @@ bool BfModule::Finish()
|
||||||
codeGenOptions.mWriteLLVMIR = mCompiler->mOptions.mWriteIR;
|
codeGenOptions.mWriteLLVMIR = mCompiler->mOptions.mWriteIR;
|
||||||
codeGenOptions.mWriteObj = mCompiler->mOptions.mGenerateObj;
|
codeGenOptions.mWriteObj = mCompiler->mOptions.mGenerateObj;
|
||||||
codeGenOptions.mWriteBitcode = mCompiler->mOptions.mGenerateBitcode;
|
codeGenOptions.mWriteBitcode = mCompiler->mOptions.mGenerateBitcode;
|
||||||
codeGenOptions.mVirtualMethodOfs = 1 + mCompiler->GetDynCastVDataCount() + mCompiler->mMaxInterfaceSlots;
|
codeGenOptions.mVirtualMethodOfs = mCompiler->GetVDataPrefixDataCount() + mCompiler->GetDynCastVDataCount() + mCompiler->mMaxInterfaceSlots;
|
||||||
codeGenOptions.mDynSlotOfs = mSystem->mPtrSize - mCompiler->GetDynCastVDataCount() * 4;
|
codeGenOptions.mDynSlotOfs = mSystem->mPtrSize - mCompiler->GetDynCastVDataCount() * 4;
|
||||||
|
|
||||||
mCompiler->mStats.mIRBytes += mBfIRBuilder->mStream.GetSize();
|
mCompiler->mStats.mIRBytes += mBfIRBuilder->mStream.GetSize();
|
||||||
|
|
|
@ -158,6 +158,12 @@ enum BfLocalVarAssignKind : int8
|
||||||
BfLocalVarAssignKind_Unconditional = 2
|
BfLocalVarAssignKind_Unconditional = 2
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct BfCreateTypeDataContext
|
||||||
|
{
|
||||||
|
Dictionary<int, int> mUsedStringIdMap;
|
||||||
|
HashSet<BfTypeInstance*> mReflectTypeSet;
|
||||||
|
};
|
||||||
|
|
||||||
class BfLocalVariable
|
class BfLocalVariable
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -1740,6 +1746,7 @@ public:
|
||||||
bool HasExecutedOutput();
|
bool HasExecutedOutput();
|
||||||
void SkipObjectAccessCheck(BfTypedValue typedVal);
|
void SkipObjectAccessCheck(BfTypedValue typedVal);
|
||||||
void EmitObjectAccessCheck(BfTypedValue typedVal);
|
void EmitObjectAccessCheck(BfTypedValue typedVal);
|
||||||
|
bool WantsDebugHelpers();
|
||||||
void EmitEnsureInstructionAt();
|
void EmitEnsureInstructionAt();
|
||||||
void EmitDynamicCastCheck(const BfTypedValue& targetValue, BfType* targetType, BfIRBlock trueBlock, BfIRBlock falseBlock, bool nullSucceeds = false);
|
void EmitDynamicCastCheck(const BfTypedValue& targetValue, BfType* targetType, BfIRBlock trueBlock, BfIRBlock falseBlock, bool nullSucceeds = false);
|
||||||
void EmitDynamicCastCheck(BfTypedValue typedVal, BfType* type, bool allowNull);
|
void EmitDynamicCastCheck(BfTypedValue typedVal, BfType* type, bool allowNull);
|
||||||
|
@ -1966,7 +1973,7 @@ public:
|
||||||
bool ValidateTypeWildcard(BfAstNode* typeRef, bool isAttributeRef);
|
bool ValidateTypeWildcard(BfAstNode* typeRef, bool isAttributeRef);
|
||||||
void GetDelegateTypeRefAttributes(BfDelegateTypeRef* delegateTypeRef, BfCallingConvention& callingConvention);
|
void GetDelegateTypeRefAttributes(BfDelegateTypeRef* delegateTypeRef, BfCallingConvention& callingConvention);
|
||||||
BfType* ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType populateType = BfPopulateType_Data, BfResolveTypeRefFlags resolveFlags = (BfResolveTypeRefFlags)0, int numGenericArgs = 0);
|
BfType* ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType populateType = BfPopulateType_Data, BfResolveTypeRefFlags resolveFlags = (BfResolveTypeRefFlags)0, int numGenericArgs = 0);
|
||||||
BfType* ResolveTypeRefAllowUnboundGenerics(BfTypeReference* typeRef, BfPopulateType populateType = BfPopulateType_Data, bool resolveGenericParam = true);
|
BfType* ResolveTypeRefAllowUnboundGenerics(BfTypeReference* typeRef, BfPopulateType populateType = BfPopulateType_Data, BfResolveTypeRefFlags resolveFlags = (BfResolveTypeRefFlags)0, bool resolveGenericParam = true);
|
||||||
BfType* ResolveTypeRef_Type(BfAstNode* astNode, const BfSizedArray<BfAstNode*>* genericArgs, BfPopulateType populateType = BfPopulateType_Data, BfResolveTypeRefFlags resolveFlags = (BfResolveTypeRefFlags)0);
|
BfType* ResolveTypeRef_Type(BfAstNode* astNode, const BfSizedArray<BfAstNode*>* genericArgs, BfPopulateType populateType = BfPopulateType_Data, BfResolveTypeRefFlags resolveFlags = (BfResolveTypeRefFlags)0);
|
||||||
BfType* ResolveTypeRef(BfAstNode* astNode, const BfSizedArray<BfAstNode*>* genericArgs, BfPopulateType populateType = BfPopulateType_Data, BfResolveTypeRefFlags resolveFlags = (BfResolveTypeRefFlags)0);
|
BfType* ResolveTypeRef(BfAstNode* astNode, const BfSizedArray<BfAstNode*>* genericArgs, BfPopulateType populateType = BfPopulateType_Data, BfResolveTypeRefFlags resolveFlags = (BfResolveTypeRefFlags)0);
|
||||||
BfType* ResolveTypeDef(BfTypeDef* typeDef, BfPopulateType populateType = BfPopulateType_Data, BfResolveTypeRefFlags resolveFlags = BfResolveTypeRefFlag_None);
|
BfType* ResolveTypeDef(BfTypeDef* typeDef, BfPopulateType populateType = BfPopulateType_Data, BfResolveTypeRefFlags resolveFlags = BfResolveTypeRefFlag_None);
|
||||||
|
@ -2062,7 +2069,7 @@ public:
|
||||||
void SetMethodDependency(BfMethodInstance* methodInstance);
|
void SetMethodDependency(BfMethodInstance* methodInstance);
|
||||||
BfModuleMethodInstance ReferenceExternalMethodInstance(BfMethodInstance* methodInstance, BfGetMethodInstanceFlags flags = BfGetMethodInstanceFlag_None);
|
BfModuleMethodInstance ReferenceExternalMethodInstance(BfMethodInstance* methodInstance, BfGetMethodInstanceFlags flags = BfGetMethodInstanceFlag_None);
|
||||||
BfModule* GetOrCreateMethodModule(BfMethodInstance* methodInstance);
|
BfModule* GetOrCreateMethodModule(BfMethodInstance* methodInstance);
|
||||||
BfModuleMethodInstance GetMethodInstance(BfTypeInstance* typeInst, BfMethodDef* methodDef, const BfTypeVector& methodGenericArguments, BfGetMethodInstanceFlags flags = BfGetMethodInstanceFlag_None, BfTypeInstance* foreignType = NULL);
|
BfModuleMethodInstance GetMethodInstance(BfTypeInstance* typeInst, BfMethodDef* methodDef, const BfTypeVector& methodGenericArguments, BfGetMethodInstanceFlags flags = BfGetMethodInstanceFlag_None, BfTypeInstance* foreignType = NULL, BfModule* referencingModule = NULL);
|
||||||
BfModuleMethodInstance GetMethodInstance(BfMethodInstance* methodInstance, BfGetMethodInstanceFlags flags = BfGetMethodInstanceFlag_None);
|
BfModuleMethodInstance GetMethodInstance(BfMethodInstance* methodInstance, BfGetMethodInstanceFlags flags = BfGetMethodInstanceFlag_None);
|
||||||
BfMethodInstance* GetOuterMethodInstance(BfMethodInstance* methodInstance); // Only useful for local methods
|
BfMethodInstance* GetOuterMethodInstance(BfMethodInstance* methodInstance); // Only useful for local methods
|
||||||
void SetupMethodIdHash(BfMethodInstance* methodInstance);
|
void SetupMethodIdHash(BfMethodInstance* methodInstance);
|
||||||
|
@ -2075,7 +2082,8 @@ public:
|
||||||
BfIRValue CreateTypeDataRef(BfType* type);
|
BfIRValue CreateTypeDataRef(BfType* type);
|
||||||
void EncodeAttributeData(BfTypeInstance* typeInstance, BfType* argType, BfIRValue arg, SizedArrayImpl<uint8>& data, Dictionary<int, int>& usedStringIdMap);
|
void EncodeAttributeData(BfTypeInstance* typeInstance, BfType* argType, BfIRValue arg, SizedArrayImpl<uint8>& data, Dictionary<int, int>& usedStringIdMap);
|
||||||
BfIRValue CreateFieldData(BfFieldInstance* fieldInstance, int customAttrIdx);
|
BfIRValue CreateFieldData(BfFieldInstance* fieldInstance, int customAttrIdx);
|
||||||
BfIRValue CreateTypeData(BfType* type, Dictionary<int, int>& usedStringIdMap, bool forceReflectFields, bool needsTypeData, bool needsTypeNames, bool needsVData);
|
void CreateSlotOfs(BfTypeInstance* typeInstance);
|
||||||
|
BfIRValue CreateTypeData(BfType* type, BfCreateTypeDataContext& ctx, bool forceReflectFields, bool needsTypeData, bool needsTypeNames, bool needsVData);
|
||||||
BfIRValue FixClassVData(BfIRValue value);
|
BfIRValue FixClassVData(BfIRValue value);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -410,7 +410,7 @@ bool BfModule::ValidateGenericConstraints(BfAstNode* typeRef, BfTypeInstance* ge
|
||||||
SetAndRestoreValue<bool> prevIgnoreErrors(mIgnoreErrors, mIgnoreErrors || ignoreErrors);
|
SetAndRestoreValue<bool> prevIgnoreErrors(mIgnoreErrors, mIgnoreErrors || ignoreErrors);
|
||||||
genericTypeInst->mGenericTypeInfo->mValidatedGenericConstraints = true;
|
genericTypeInst->mGenericTypeInfo->mValidatedGenericConstraints = true;
|
||||||
if (!genericTypeInst->mGenericTypeInfo->mFinishedGenericParams)
|
if (!genericTypeInst->mGenericTypeInfo->mFinishedGenericParams)
|
||||||
PopulateType(genericTypeInst, BfPopulateType_Interfaces_All);
|
mContext->mUnreifiedModule->PopulateType(genericTypeInst, BfPopulateType_Interfaces_All);
|
||||||
|
|
||||||
if (genericTypeInst->IsTypeAlias())
|
if (genericTypeInst->IsTypeAlias())
|
||||||
{
|
{
|
||||||
|
@ -418,7 +418,7 @@ bool BfModule::ValidateGenericConstraints(BfAstNode* typeRef, BfTypeInstance* ge
|
||||||
if ((underlyingType != NULL) && (underlyingType->IsGenericTypeInstance()))
|
if ((underlyingType != NULL) && (underlyingType->IsGenericTypeInstance()))
|
||||||
{
|
{
|
||||||
auto underlyingGenericType = underlyingType->ToGenericTypeInstance();
|
auto underlyingGenericType = underlyingType->ToGenericTypeInstance();
|
||||||
PopulateType(underlyingType, BfPopulateType_Declaration);
|
mContext->mUnreifiedModule->PopulateType(underlyingType, BfPopulateType_Declaration);
|
||||||
bool result = ValidateGenericConstraints(typeRef, underlyingGenericType, ignoreErrors);
|
bool result = ValidateGenericConstraints(typeRef, underlyingGenericType, ignoreErrors);
|
||||||
if (underlyingGenericType->mGenericTypeInfo->mHadValidateErrors)
|
if (underlyingGenericType->mGenericTypeInfo->mHadValidateErrors)
|
||||||
genericTypeInst->mGenericTypeInfo->mHadValidateErrors = true;
|
genericTypeInst->mGenericTypeInfo->mHadValidateErrors = true;
|
||||||
|
@ -441,7 +441,7 @@ bool BfModule::ValidateGenericConstraints(BfAstNode* typeRef, BfTypeInstance* ge
|
||||||
{
|
{
|
||||||
startGenericParamIdx = typeDef->mOuterType->mGenericParamDefs.mSize + typeDef->mOuterType->mExternalConstraints.mSize;
|
startGenericParamIdx = typeDef->mOuterType->mGenericParamDefs.mSize + typeDef->mOuterType->mExternalConstraints.mSize;
|
||||||
auto outerType = GetOuterType(genericTypeInst);
|
auto outerType = GetOuterType(genericTypeInst);
|
||||||
PopulateType(outerType, BfPopulateType_Declaration);
|
mContext->mUnreifiedModule->PopulateType(outerType, BfPopulateType_Declaration);
|
||||||
if ((outerType->mGenericTypeInfo != NULL) && (outerType->mGenericTypeInfo->mHadValidateErrors))
|
if ((outerType->mGenericTypeInfo != NULL) && (outerType->mGenericTypeInfo->mHadValidateErrors))
|
||||||
genericTypeInst->mGenericTypeInfo->mHadValidateErrors = true;
|
genericTypeInst->mGenericTypeInfo->mHadValidateErrors = true;
|
||||||
}
|
}
|
||||||
|
@ -802,6 +802,11 @@ void BfModule::InitType(BfType* resolvedTypeRef, BfPopulateType populateType)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((typeInst != NULL) && (typeInst->mIsReified) && (!mCompiler->mIsResolveOnly))
|
||||||
|
{
|
||||||
|
BfLogSysM("REIFIED(InitType): %s Type:%p FromModule:%s FromMethod:%p\n", TypeToString(resolvedTypeRef).c_str(), resolvedTypeRef, mModuleName.c_str(), prevMethodInstance.mPrevVal);
|
||||||
|
}
|
||||||
|
|
||||||
BfLogSysM("%p InitType: %s Type: %p TypeDef: %p Revision:%d\n", mContext, TypeToString(resolvedTypeRef).c_str(), resolvedTypeRef, (typeInst != NULL) ? typeInst->mTypeDef : NULL, mCompiler->mRevision);
|
BfLogSysM("%p InitType: %s Type: %p TypeDef: %p Revision:%d\n", mContext, TypeToString(resolvedTypeRef).c_str(), resolvedTypeRef, (typeInst != NULL) ? typeInst->mTypeDef : NULL, mCompiler->mRevision);
|
||||||
|
|
||||||
// When we're autocomplete, we can't do the method processing so we have to add this type to the type work list
|
// When we're autocomplete, we can't do the method processing so we have to add this type to the type work list
|
||||||
|
@ -1212,6 +1217,14 @@ void BfModule::PopulateType(BfType* resolvedTypeRef, BfPopulateType populateType
|
||||||
canFastReify = false;
|
canFastReify = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!mCompiler->mIsResolveOnly)
|
||||||
|
{
|
||||||
|
for (auto ownedTypes : typeModule->mOwnedTypeInstances)
|
||||||
|
{
|
||||||
|
BfLogSysM("REIFIED(PopulateType-Reference): %s %p FromModule:%s FromMethod: %p\n", TypeToString(ownedTypes).c_str(), ownedTypes, mModuleName.c_str(), mCurMethodInstance);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (canFastReify)
|
if (canFastReify)
|
||||||
{
|
{
|
||||||
BfLogSysM("Setting reified type %p in module %p in PopulateType on module awaiting finish\n", resolvedTypeRef, typeModule);
|
BfLogSysM("Setting reified type %p in module %p in PopulateType on module awaiting finish\n", resolvedTypeRef, typeModule);
|
||||||
|
@ -1292,7 +1305,17 @@ void BfModule::PopulateType(BfType* resolvedTypeRef, BfPopulateType populateType
|
||||||
SetAndRestoreValue<BfMethodInstance*> prevMethodInstance(mCurMethodInstance, NULL);
|
SetAndRestoreValue<BfMethodInstance*> prevMethodInstance(mCurMethodInstance, NULL);
|
||||||
SetAndRestoreValue<BfMethodState*> prevMethodState(mCurMethodState, NULL);
|
SetAndRestoreValue<BfMethodState*> prevMethodState(mCurMethodState, NULL);
|
||||||
|
|
||||||
BF_ASSERT((resolvedTypeRef->mRebuildFlags & (BfTypeRebuildFlag_Deleted | BfTypeRebuildFlag_DeleteQueued)) == 0);
|
if ((resolvedTypeRef->mRebuildFlags & (BfTypeRebuildFlag_Deleted | BfTypeRebuildFlag_DeleteQueued)) != 0)
|
||||||
|
{
|
||||||
|
if (mContext->mGhostDependencies.Contains(resolvedTypeRef))
|
||||||
|
{
|
||||||
|
// Not a nice state, but we should be able to recover
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
InternalError("Attempting PopulateType on deleted type");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
bool isNew = resolvedTypeRef->mDefineState == BfTypeDefineState_Undefined;
|
bool isNew = resolvedTypeRef->mDefineState == BfTypeDefineState_Undefined;
|
||||||
if (isNew)
|
if (isNew)
|
||||||
|
@ -8268,7 +8291,7 @@ BfType* BfModule::ResolveTypeDef(BfTypeDef* typeDef, BfPopulateType populateType
|
||||||
|
|
||||||
auto typeDefTypeRef = mContext->mTypeDefTypeRefPool.Get();
|
auto typeDefTypeRef = mContext->mTypeDefTypeRefPool.Get();
|
||||||
typeDefTypeRef->mTypeDef = typeDef;
|
typeDefTypeRef->mTypeDef = typeDef;
|
||||||
auto resolvedtypeDefType = ResolveTypeRef(typeDefTypeRef, populateType);
|
auto resolvedtypeDefType = ResolveTypeRef(typeDefTypeRef, populateType, resolveFlags);
|
||||||
if (resolvedtypeDefType == NULL)
|
if (resolvedtypeDefType == NULL)
|
||||||
{
|
{
|
||||||
mContext->mTypeDefTypeRefPool.GiveBack(typeDefTypeRef);
|
mContext->mTypeDefTypeRefPool.GiveBack(typeDefTypeRef);
|
||||||
|
@ -11347,7 +11370,7 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return ResolveTypeResult(typeRef, ResolveTypeDef(typeDef, genericArgs, populateType), populateType, resolveFlags);
|
return ResolveTypeResult(typeRef, ResolveTypeDef(typeDef, genericArgs, populateType, resolveFlags), populateType, resolveFlags);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -12635,7 +12658,7 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula
|
||||||
return ResolveTypeResult(typeRef, NULL, populateType, resolveFlags);
|
return ResolveTypeResult(typeRef, NULL, populateType, resolveFlags);
|
||||||
}
|
}
|
||||||
|
|
||||||
BfType* BfModule::ResolveTypeRefAllowUnboundGenerics(BfTypeReference* typeRef, BfPopulateType populateType, bool resolveGenericParam)
|
BfType* BfModule::ResolveTypeRefAllowUnboundGenerics(BfTypeReference* typeRef, BfPopulateType populateType, BfResolveTypeRefFlags resolveFlags, bool resolveGenericParam)
|
||||||
{
|
{
|
||||||
if (auto genericTypeRef = BfNodeDynCast<BfGenericInstanceTypeRef>(typeRef))
|
if (auto genericTypeRef = BfNodeDynCast<BfGenericInstanceTypeRef>(typeRef))
|
||||||
{
|
{
|
||||||
|
@ -12648,7 +12671,7 @@ BfType* BfModule::ResolveTypeRefAllowUnboundGenerics(BfTypeReference* typeRef, B
|
||||||
BfTypeVector typeVector;
|
BfTypeVector typeVector;
|
||||||
for (int i = 0; i < (int)genericTypeDef->mGenericParamDefs.size(); i++)
|
for (int i = 0; i < (int)genericTypeDef->mGenericParamDefs.size(); i++)
|
||||||
typeVector.push_back(GetGenericParamType(BfGenericParamKind_Type, i));
|
typeVector.push_back(GetGenericParamType(BfGenericParamKind_Type, i));
|
||||||
auto result = ResolveTypeDef(genericTypeDef, typeVector, populateType);
|
auto result = ResolveTypeDef(genericTypeDef, typeVector, populateType, resolveFlags);
|
||||||
if ((result != NULL) && (genericTypeRef->mCommas.size() + 1 != genericTypeDef->mGenericParamDefs.size()))
|
if ((result != NULL) && (genericTypeRef->mCommas.size() + 1 != genericTypeDef->mGenericParamDefs.size()))
|
||||||
{
|
{
|
||||||
SetAndRestoreValue<BfTypeInstance*> prevTypeInstance(mCurTypeInstance, result->ToTypeInstance());
|
SetAndRestoreValue<BfTypeInstance*> prevTypeInstance(mCurTypeInstance, result->ToTypeInstance());
|
||||||
|
|
|
@ -1270,11 +1270,12 @@ bool BfMethodInstance::WasGenericParam(int paramIdx)
|
||||||
|
|
||||||
bool BfMethodInstance::IsParamSkipped(int paramIdx)
|
bool BfMethodInstance::IsParamSkipped(int paramIdx)
|
||||||
{
|
{
|
||||||
|
auto resolveModule = GetModule()->mContext->mUnreifiedModule;
|
||||||
if (paramIdx == -1)
|
if (paramIdx == -1)
|
||||||
return false;
|
return false;
|
||||||
BfType* paramType = GetParamType(paramIdx);
|
BfType* paramType = GetParamType(paramIdx);
|
||||||
if ((paramType->CanBeValuelessType()) && (paramType->IsDataIncomplete()))
|
if ((paramType->CanBeValuelessType()) && (paramType->IsDataIncomplete()))
|
||||||
GetModule()->PopulateType(paramType, BfPopulateType_Data);
|
resolveModule->PopulateType(paramType, BfPopulateType_Data);
|
||||||
if ((paramType->IsValuelessType()) && (!paramType->IsMethodRef()))
|
if ((paramType->IsValuelessType()) && (!paramType->IsMethodRef()))
|
||||||
return true;
|
return true;
|
||||||
return false;
|
return false;
|
||||||
|
@ -1344,7 +1345,7 @@ int BfMethodInstance::DbgGetVirtualMethodNum()
|
||||||
module->HadSlotCountDependency();
|
module->HadSlotCountDependency();
|
||||||
|
|
||||||
int vDataIdx = -1;
|
int vDataIdx = -1;
|
||||||
vDataIdx = 1 + module->mCompiler->mMaxInterfaceSlots;
|
vDataIdx = module->mCompiler->GetVDataPrefixDataCount() + module->mCompiler->mMaxInterfaceSlots;
|
||||||
vDataIdx += module->mCompiler->GetDynCastVDataCount();
|
vDataIdx += module->mCompiler->GetDynCastVDataCount();
|
||||||
if ((module->mCompiler->mOptions.mHasVDataExtender) && (module->mCompiler->IsHotCompile()))
|
if ((module->mCompiler->mOptions.mHasVDataExtender) && (module->mCompiler->IsHotCompile()))
|
||||||
{
|
{
|
||||||
|
@ -1375,7 +1376,9 @@ int BfMethodInstance::DbgGetVirtualMethodNum()
|
||||||
|
|
||||||
void BfMethodInstance::GetIRFunctionInfo(BfModule* module, BfIRType& returnType, SizedArrayImpl<BfIRType>& paramTypes, bool forceStatic)
|
void BfMethodInstance::GetIRFunctionInfo(BfModule* module, BfIRType& returnType, SizedArrayImpl<BfIRType>& paramTypes, bool forceStatic)
|
||||||
{
|
{
|
||||||
module->PopulateType(mReturnType);
|
BfModule* resolveModule = module->mContext->mUnreifiedModule;
|
||||||
|
|
||||||
|
resolveModule->PopulateType(mReturnType);
|
||||||
|
|
||||||
BfTypeCode loweredReturnTypeCode = BfTypeCode_None;
|
BfTypeCode loweredReturnTypeCode = BfTypeCode_None;
|
||||||
BfTypeCode loweredReturnTypeCode2 = BfTypeCode_None;
|
BfTypeCode loweredReturnTypeCode2 = BfTypeCode_None;
|
||||||
|
@ -1459,7 +1462,7 @@ void BfMethodInstance::GetIRFunctionInfo(BfModule* module, BfIRType& returnType,
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if ((checkType->IsComposite()) && (checkType->IsIncomplete()))
|
if ((checkType->IsComposite()) && (checkType->IsIncomplete()))
|
||||||
module->PopulateType(checkType, BfPopulateType_Data);
|
resolveModule->PopulateType(checkType, BfPopulateType_Data);
|
||||||
|
|
||||||
if (checkType->IsMethodRef())
|
if (checkType->IsMethodRef())
|
||||||
{
|
{
|
||||||
|
@ -1492,7 +1495,7 @@ void BfMethodInstance::GetIRFunctionInfo(BfModule* module, BfIRType& returnType,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (checkType->CanBeValuelessType())
|
if (checkType->CanBeValuelessType())
|
||||||
module->PopulateType(checkType, BfPopulateType_Data);
|
resolveModule->PopulateType(checkType, BfPopulateType_Data);
|
||||||
if ((checkType->IsValuelessType()) && (!checkType->IsMethodRef()))
|
if ((checkType->IsValuelessType()) && (!checkType->IsMethodRef()))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
|
|
@ -6714,12 +6714,18 @@ void BfModule::Visit(BfForEachStatement* forEachStmt)
|
||||||
PopulateType(itrInterface, BfPopulateType_Full_Force);
|
PopulateType(itrInterface, BfPopulateType_Full_Force);
|
||||||
getNextMethodInst = GetMethodByName(itrInterface, "GetNext");
|
getNextMethodInst = GetMethodByName(itrInterface, "GetNext");
|
||||||
}
|
}
|
||||||
BF_ASSERT(getNextMethodInst);
|
if (getNextMethodInst)
|
||||||
nextResult = BfTypedValue(CreateAlloca(getNextMethodInst.mMethodInstance->mReturnType), getNextMethodInst.mMethodInstance->mReturnType, true);
|
|
||||||
|
|
||||||
if (nextResult.mType->IsGenericTypeInstance())
|
|
||||||
{
|
{
|
||||||
nextEmbeddedType = ((BfTypeInstance*)nextResult.mType)->mGenericTypeInfo->mTypeGenericArguments[0];
|
nextResult = BfTypedValue(CreateAlloca(getNextMethodInst.mMethodInstance->mReturnType), getNextMethodInst.mMethodInstance->mReturnType, true);
|
||||||
|
|
||||||
|
if (nextResult.mType->IsGenericTypeInstance())
|
||||||
|
{
|
||||||
|
nextEmbeddedType = ((BfTypeInstance*)nextResult.mType)->mGenericTypeInfo->mTypeGenericArguments[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
InternalError("Failed to find GetNext");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (nextEmbeddedType == NULL)
|
if (nextEmbeddedType == NULL)
|
||||||
|
|
|
@ -3865,8 +3865,8 @@ addr_ce CeContext::GetReflectType(int typeId)
|
||||||
if (bfType->mDefineState != BfTypeDefineState_CETypeInit)
|
if (bfType->mDefineState != BfTypeDefineState_CETypeInit)
|
||||||
ceModule->PopulateType(bfType, BfPopulateType_DataAndMethods);
|
ceModule->PopulateType(bfType, BfPopulateType_DataAndMethods);
|
||||||
|
|
||||||
Dictionary<int, int> usedStringMap;
|
BfCreateTypeDataContext createTypeDataCtx;
|
||||||
auto irData = ceModule->CreateTypeData(bfType, usedStringMap, true, true, true, false);
|
auto irData = ceModule->CreateTypeData(bfType, createTypeDataCtx, true, true, true, false);
|
||||||
|
|
||||||
BeValue* beValue = NULL;
|
BeValue* beValue = NULL;
|
||||||
if (auto constant = mCeMachine->mCeModule->mBfIRBuilder->GetConstant(irData))
|
if (auto constant = mCeMachine->mCeModule->mBfIRBuilder->GetConstant(irData))
|
||||||
|
|
|
@ -833,6 +833,11 @@ bool DbgSubprogram::IsLambda()
|
||||||
return StringView(mName).Contains('$');
|
return StringView(mName).Contains('$');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int DbgSubprogram::GetByteCount()
|
||||||
|
{
|
||||||
|
return (int)(mBlock.mHighPC - mBlock.mLowPC);
|
||||||
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
DbgSubprogram::~DbgSubprogram()
|
DbgSubprogram::~DbgSubprogram()
|
||||||
|
@ -5783,7 +5788,7 @@ bool DbgModule::ReadCOFF(DataStream* stream, DbgModuleKind moduleKind)
|
||||||
|
|
||||||
Array<PESectionHeader> sectionHeaders;
|
Array<PESectionHeader> sectionHeaders;
|
||||||
sectionHeaders.Resize(ntHdr.mFileHeader.mNumberOfSections);
|
sectionHeaders.Resize(ntHdr.mFileHeader.mNumberOfSections);
|
||||||
mSectionRVAs.Resize(sectionHeaders.size() + 1);
|
mSectionHeaders.Resize(sectionHeaders.size() + 1);
|
||||||
|
|
||||||
Array<String> sectionNames;
|
Array<String> sectionNames;
|
||||||
sectionNames.Resize(ntHdr.mFileHeader.mNumberOfSections);
|
sectionNames.Resize(ntHdr.mFileHeader.mNumberOfSections);
|
||||||
|
@ -5792,7 +5797,7 @@ bool DbgModule::ReadCOFF(DataStream* stream, DbgModuleKind moduleKind)
|
||||||
|
|
||||||
for (int sectNum = 0; sectNum < ntHdr.mFileHeader.mNumberOfSections; sectNum++)
|
for (int sectNum = 0; sectNum < ntHdr.mFileHeader.mNumberOfSections; sectNum++)
|
||||||
{
|
{
|
||||||
mSectionRVAs[sectNum] = sectionHeaders[sectNum].mVirtualAddress;
|
mSectionHeaders[sectNum] = sectionHeaders[sectNum];
|
||||||
}
|
}
|
||||||
|
|
||||||
int tlsSection = -1;
|
int tlsSection = -1;
|
||||||
|
@ -5827,6 +5832,7 @@ bool DbgModule::ReadCOFF(DataStream* stream, DbgModuleKind moduleKind)
|
||||||
}
|
}
|
||||||
|
|
||||||
DbgSection dwSection;
|
DbgSection dwSection;
|
||||||
|
dwSection.mName = name;
|
||||||
dwSection.mIsExecutable = (sectHdr.mCharacteristics & IMAGE_SCN_MEM_EXECUTE) != 0;
|
dwSection.mIsExecutable = (sectHdr.mCharacteristics & IMAGE_SCN_MEM_EXECUTE) != 0;
|
||||||
dwSection.mAddrStart = sectHdr.mVirtualAddress;
|
dwSection.mAddrStart = sectHdr.mVirtualAddress;
|
||||||
dwSection.mAddrLength = BF_MAX(sectHdr.mSizeOfRawData, sectHdr.mVirtualSize);
|
dwSection.mAddrLength = BF_MAX(sectHdr.mSizeOfRawData, sectHdr.mVirtualSize);
|
||||||
|
@ -6290,7 +6296,7 @@ bool DbgModule::ReadCOFF(DataStream* stream, DbgModuleKind moduleKind)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
targetAddr = mSectionRVAs[symInfo->mSectionNum - 1] + symInfo->mValue;
|
targetAddr = mSectionHeaders[symInfo->mSectionNum - 1].mVirtualAddress + symInfo->mValue;
|
||||||
|
|
||||||
if (((targetAddr != 0) || (isTLS)) &&
|
if (((targetAddr != 0) || (isTLS)) &&
|
||||||
(name[0] != '.'))
|
(name[0] != '.'))
|
||||||
|
|
|
@ -442,6 +442,7 @@ public:
|
||||||
bool IsGenericMethod();
|
bool IsGenericMethod();
|
||||||
bool ThisIsSplat();
|
bool ThisIsSplat();
|
||||||
bool IsLambda();
|
bool IsLambda();
|
||||||
|
int GetByteCount();
|
||||||
|
|
||||||
DbgSubprogram* GetRootInlineParent()
|
DbgSubprogram* GetRootInlineParent()
|
||||||
{
|
{
|
||||||
|
@ -823,6 +824,7 @@ public:
|
||||||
addr_target mAddress;
|
addr_target mAddress;
|
||||||
int mCompileUnitId;
|
int mCompileUnitId;
|
||||||
int mLength;
|
int mLength;
|
||||||
|
int mSection;
|
||||||
};
|
};
|
||||||
|
|
||||||
class DbgCompileUnit
|
class DbgCompileUnit
|
||||||
|
@ -874,6 +876,7 @@ public:
|
||||||
class DbgSection
|
class DbgSection
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
String mName;
|
||||||
addr_target mAddrStart;
|
addr_target mAddrStart;
|
||||||
addr_target mAddrLength;
|
addr_target mAddrLength;
|
||||||
bool mWritingEnabled;
|
bool mWritingEnabled;
|
||||||
|
@ -1183,7 +1186,7 @@ public:
|
||||||
bool mIsDwarf64;
|
bool mIsDwarf64;
|
||||||
|
|
||||||
HashSet<DbgSrcFile*> mSrcFileDeferredRefs;
|
HashSet<DbgSrcFile*> mSrcFileDeferredRefs;
|
||||||
Array<addr_target> mSectionRVAs;
|
Array<PESectionHeader> mSectionHeaders;
|
||||||
SLIList<DbgSymbol*> mDeferredSymbols;
|
SLIList<DbgSymbol*> mDeferredSymbols;
|
||||||
Beefy::OwnedVector<DbgDeferredHotResolve> mDeferredHotResolveList;
|
Beefy::OwnedVector<DbgDeferredHotResolve> mDeferredHotResolveList;
|
||||||
Array<DbgHotTargetSection*> mHotTargetSections;
|
Array<DbgHotTargetSection*> mHotTargetSections;
|
||||||
|
|
|
@ -1548,6 +1548,13 @@ BF_EXPORT const char* BF_CALLTYPE Debugger_GetModulesInfo()
|
||||||
return outString.c_str();
|
return outString.c_str();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BF_EXPORT const char* BF_CALLTYPE Debugger_GetModuleInfo(const char* moduleName)
|
||||||
|
{
|
||||||
|
String& outString = *gTLStrReturn.Get();
|
||||||
|
outString = gDebugger->GetModuleInfo(moduleName);
|
||||||
|
return outString.c_str();
|
||||||
|
}
|
||||||
|
|
||||||
BF_EXPORT void BF_CALLTYPE Debugger_CancelSymSrv()
|
BF_EXPORT void BF_CALLTYPE Debugger_CancelSymSrv()
|
||||||
{
|
{
|
||||||
gDebugger->CancelSymSrv();
|
gDebugger->CancelSymSrv();
|
||||||
|
|
|
@ -343,6 +343,7 @@ public:
|
||||||
virtual String FindLineCallAddresses(intptr address) = 0;
|
virtual String FindLineCallAddresses(intptr address) = 0;
|
||||||
virtual String GetCurrentException() = 0;
|
virtual String GetCurrentException() = 0;
|
||||||
virtual String GetModulesInfo() = 0;
|
virtual String GetModulesInfo() = 0;
|
||||||
|
virtual String GetModuleInfo(const StringImpl& moduleName) { return ""; }
|
||||||
virtual void SetAliasPath(const StringImpl& origPath, const StringImpl& localPath) = 0;
|
virtual void SetAliasPath(const StringImpl& origPath, const StringImpl& localPath) = 0;
|
||||||
virtual void CancelSymSrv() = 0;
|
virtual void CancelSymSrv() = 0;
|
||||||
virtual bool HasPendingDebugLoads() = 0;
|
virtual bool HasPendingDebugLoads() = 0;
|
||||||
|
|
|
@ -8,6 +8,8 @@ USING_NS_BF_DBG;
|
||||||
DbgHotScanner::DbgHotScanner(WinDebugger* debugger)
|
DbgHotScanner::DbgHotScanner(WinDebugger* debugger)
|
||||||
{
|
{
|
||||||
mDebugger = debugger;
|
mDebugger = debugger;
|
||||||
|
mBfTypesInfoAddr = 0;
|
||||||
|
mDbgGCData = { 0 };
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_BF_DBG_BEGIN
|
NS_BF_DBG_BEGIN
|
||||||
|
@ -255,20 +257,25 @@ void DbgHotScanner::ScanSpan(TCFake::Span* span, int expectedStartPage, int memK
|
||||||
int* typeIdPtr = NULL;
|
int* typeIdPtr = NULL;
|
||||||
if (mFoundClassVDataAddrs.TryAdd(classVDataAddr, NULL, &typeIdPtr))
|
if (mFoundClassVDataAddrs.TryAdd(classVDataAddr, NULL, &typeIdPtr))
|
||||||
{
|
{
|
||||||
addr_target typeAddr = mDebugger->ReadMemory<addr_target>(classVDataAddr);
|
if (mBfTypesInfoAddr > 0)
|
||||||
Fake_Type_Data typeData;
|
|
||||||
mDebugger->ReadMemory(typeAddr + objectSize, sizeof(typeData), &typeData);
|
|
||||||
|
|
||||||
*typeIdPtr = typeData.mTypeId;
|
|
||||||
_MarkTypeUsed(typeData.mTypeId, elementSize);
|
|
||||||
if ((typeData.mTypeFlags & BfTypeFlags_Delegate) != 0)
|
|
||||||
{
|
{
|
||||||
Fake_Delegate_Data* dlg = (Fake_Delegate_Data*)((uint8*)spanPtr + objectSize);
|
addr_target typeId = mDebugger->ReadMemory<int32>(classVDataAddr);
|
||||||
if (mFoundFuncPtrs.Add(dlg->mFuncPtr))
|
addr_target arrayAddr = mBfTypesInfoAddr + typeId * sizeof(addr_target);
|
||||||
|
addr_target typeAddr = mDebugger->ReadMemory<addr_target>(arrayAddr);
|
||||||
|
Fake_Type_Data typeData;
|
||||||
|
mDebugger->ReadMemory(typeAddr + objectSize, sizeof(typeData), &typeData);
|
||||||
|
|
||||||
|
*typeIdPtr = typeData.mTypeId;
|
||||||
|
_MarkTypeUsed(typeData.mTypeId, elementSize);
|
||||||
|
if ((typeData.mTypeFlags & BfTypeFlags_Delegate) != 0)
|
||||||
{
|
{
|
||||||
auto subProgram = mDebugger->mDebugTarget->FindSubProgram(dlg->mFuncPtr, DbgOnDemandKind_None);
|
Fake_Delegate_Data* dlg = (Fake_Delegate_Data*)((uint8*)spanPtr + objectSize);
|
||||||
if ((subProgram != NULL) && (subProgram->GetLanguage() == DbgLanguage_Beef))
|
if (mFoundFuncPtrs.Add(dlg->mFuncPtr))
|
||||||
AddSubProgram(subProgram, true, "D ");
|
{
|
||||||
|
auto subProgram = mDebugger->mDebugTarget->FindSubProgram(dlg->mFuncPtr, DbgOnDemandKind_None);
|
||||||
|
if ((subProgram != NULL) && (subProgram->GetLanguage() == DbgLanguage_Beef))
|
||||||
|
AddSubProgram(subProgram, true, "D ");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -358,6 +365,7 @@ void DbgHotScanner::Scan(DbgHotResolveFlags flags)
|
||||||
{
|
{
|
||||||
if ((module->mFilePath.Contains("Beef")) && (module->mFilePath.Contains("Dbg")))
|
if ((module->mFilePath.Contains("Beef")) && (module->mFilePath.Contains("Dbg")))
|
||||||
{
|
{
|
||||||
|
module->ParseTypeData();
|
||||||
module->ParseSymbolData();
|
module->ParseSymbolData();
|
||||||
auto entry = module->mSymbolNameMap.Find("gGCDbgData");
|
auto entry = module->mSymbolNameMap.Find("gGCDbgData");
|
||||||
if ((entry != NULL) && (entry->mValue != NULL))
|
if ((entry != NULL) && (entry->mValue != NULL))
|
||||||
|
@ -365,6 +373,44 @@ void DbgHotScanner::Scan(DbgHotResolveFlags flags)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto module = mDebugger->mDebugTarget->mTargetBinary;
|
||||||
|
if (module->mBfTypesInfoAddr == 0)
|
||||||
|
{
|
||||||
|
module->mBfTypesInfoAddr = -1;
|
||||||
|
auto typeTypeEntry = module->FindType("System.Type", DbgLanguage_Beef);
|
||||||
|
if ((typeTypeEntry != NULL) && (typeTypeEntry->mValue != NULL))
|
||||||
|
{
|
||||||
|
auto typeType = typeTypeEntry->mValue;
|
||||||
|
module->mBfTypeType = typeType;
|
||||||
|
if (typeType->mNeedsGlobalsPopulated)
|
||||||
|
typeType->mCompileUnit->mDbgModule->PopulateTypeGlobals(typeType);
|
||||||
|
|
||||||
|
for (auto member : typeType->mMemberList)
|
||||||
|
{
|
||||||
|
if ((member->mIsStatic) && (member->mName != NULL) && (strcmp(member->mName, "sTypes") == 0) && (member->mLocationData != NULL))
|
||||||
|
{
|
||||||
|
DbgAddrType addrType;
|
||||||
|
module->mBfTypesInfoAddr = member->mCompileUnit->mDbgModule->EvaluateLocation(NULL, member->mLocationData, member->mLocationLen, NULL, &addrType);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (module->mBfTypesInfoAddr <= 0)
|
||||||
|
{
|
||||||
|
auto entry = module->mSymbolNameMap.Find(
|
||||||
|
#ifdef BF_DBG_64
|
||||||
|
"?sTypes@Type@System@bf@@2PEAPEAV123@A"
|
||||||
|
#else
|
||||||
|
"?sTypes@Type@System@bf@@2PAPAV123@A"
|
||||||
|
#endif
|
||||||
|
);
|
||||||
|
|
||||||
|
if (entry)
|
||||||
|
module->mBfTypesInfoAddr = entry->mValue->mAddress;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mBfTypesInfoAddr = module->mBfTypesInfoAddr;
|
||||||
|
|
||||||
if (gcDbgDataAddr == 0)
|
if (gcDbgDataAddr == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
|
@ -84,6 +84,7 @@ class DbgHotScanner
|
||||||
public:
|
public:
|
||||||
WinDebugger* mDebugger;
|
WinDebugger* mDebugger;
|
||||||
DbgGCData mDbgGCData;
|
DbgGCData mDbgGCData;
|
||||||
|
addr_target mBfTypesInfoAddr;
|
||||||
Beefy::Dictionary<addr_target, int> mFoundClassVDataAddrs;
|
Beefy::Dictionary<addr_target, int> mFoundClassVDataAddrs;
|
||||||
Beefy::Dictionary<addr_target, int> mFoundRawAllocDataAddrs;
|
Beefy::Dictionary<addr_target, int> mFoundRawAllocDataAddrs;
|
||||||
Beefy::Dictionary<addr_target, int> mFoundTypeAddrs;
|
Beefy::Dictionary<addr_target, int> mFoundTypeAddrs;
|
||||||
|
|
|
@ -8,6 +8,9 @@ StartupProject = "Tests"
|
||||||
[Configs.Debug.Win64]
|
[Configs.Debug.Win64]
|
||||||
IntermediateType = "ObjectAndIRCode"
|
IntermediateType = "ObjectAndIRCode"
|
||||||
|
|
||||||
|
[Configs.Debug.Win32]
|
||||||
|
IntermediateType = "ObjectAndIRCode"
|
||||||
|
|
||||||
[Configs.Test.Win64]
|
[Configs.Test.Win64]
|
||||||
IntermediateType = "ObjectAndIRCode"
|
IntermediateType = "ObjectAndIRCode"
|
||||||
COptimizationLevel = "O2"
|
COptimizationLevel = "O2"
|
||||||
|
|
|
@ -12872,6 +12872,210 @@ String WinDebugger::GetModulesInfo()
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String WinDebugger::GetModuleInfo(const StringImpl& modulePath)
|
||||||
|
{
|
||||||
|
AutoCrit autoCrit(mDebugManager->mCritSect);
|
||||||
|
|
||||||
|
String result;
|
||||||
|
|
||||||
|
for (auto dbgModule : mDebugTarget->mDbgModules)
|
||||||
|
{
|
||||||
|
if (modulePath.Equals(dbgModule->mFilePath, StringImpl::CompareKind_OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
dbgModule->ParseGlobalsData();
|
||||||
|
dbgModule->PopulateStaticVariableMap();
|
||||||
|
|
||||||
|
auto coff = (COFF*)dbgModule;
|
||||||
|
coff->ParseCompileUnits();
|
||||||
|
|
||||||
|
int fileSize = 0;
|
||||||
|
//
|
||||||
|
{
|
||||||
|
FileStream fs;
|
||||||
|
fs.Open(coff->mFilePath, "rb");
|
||||||
|
fileSize = fs.GetSize();
|
||||||
|
}
|
||||||
|
|
||||||
|
result += StrFormat("Path: %s FileSize:%0.2fk MemoryImage:%0.2fk\n", coff->mFilePath.c_str(), fileSize / 1024.0f, coff->mImageSize / 1024.0f);
|
||||||
|
|
||||||
|
result += "Sections:\n";
|
||||||
|
for (auto& section : coff->mSections)
|
||||||
|
{
|
||||||
|
result += StrFormat("\t%s\t%0.2fk\n", section.mName.c_str(), (section.mAddrLength) / 1024.0f);
|
||||||
|
}
|
||||||
|
result += "\n";
|
||||||
|
|
||||||
|
result += "Compile Units:\n";
|
||||||
|
for (auto compileUnit : dbgModule->mCompileUnits)
|
||||||
|
{
|
||||||
|
coff->MapCompileUnitMethods(compileUnit);
|
||||||
|
result += StrFormat("\t%s PCRange:%0.2fk\n", compileUnit->mName.c_str(), (compileUnit->mHighPC - compileUnit->mLowPC) / 1024.0f);
|
||||||
|
}
|
||||||
|
result += "\n";
|
||||||
|
|
||||||
|
Array<CvModuleInfo*> moduleInfos;
|
||||||
|
for (auto moduleInfo : coff->mCvModuleInfo)
|
||||||
|
{
|
||||||
|
if (moduleInfo->mSectionContrib.mSize > 0)
|
||||||
|
moduleInfos.Add(moduleInfo);
|
||||||
|
}
|
||||||
|
moduleInfos.Sort([](CvModuleInfo* lhs, CvModuleInfo* rhs)
|
||||||
|
{
|
||||||
|
return lhs->mSectionContrib.mSize > rhs->mSectionContrib.mSize;
|
||||||
|
});
|
||||||
|
|
||||||
|
int totalContrib = 0;
|
||||||
|
result += "CV Module Info:\n";
|
||||||
|
for (auto moduleInfo : moduleInfos)
|
||||||
|
{
|
||||||
|
auto section = coff->mSections[moduleInfo->mSectionContrib.mSection - 1];
|
||||||
|
|
||||||
|
result += StrFormat("\t%s\t%s\t%0.2fk\t%@-%@\n", moduleInfo->mModuleName, section.mName.c_str(), (moduleInfo->mSectionContrib.mSize) / 1024.0f,
|
||||||
|
coff->GetSectionAddr(moduleInfo->mSectionContrib.mSection, moduleInfo->mSectionContrib.mOffset),
|
||||||
|
coff->GetSectionAddr(moduleInfo->mSectionContrib.mSection, moduleInfo->mSectionContrib.mOffset + moduleInfo->mSectionContrib.mSize));
|
||||||
|
totalContrib += moduleInfo->mSectionContrib.mSize;
|
||||||
|
}
|
||||||
|
result += StrFormat("\tTOTAL: %0.2fk\n", (totalContrib) / 1024.0f);
|
||||||
|
result += "\n";
|
||||||
|
|
||||||
|
addr_target minAddr = 0;
|
||||||
|
Array<DbgCompileUnitContrib*> contribs;
|
||||||
|
for (auto itr = mDebugTarget->mContribMap.begin(); itr != mDebugTarget->mContribMap.end(); ++itr)
|
||||||
|
{
|
||||||
|
auto contrib = *itr;
|
||||||
|
if (contrib->mDbgModule != coff)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (contrib->mAddress < minAddr)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
minAddr = contrib->mAddress + contrib->mLength;
|
||||||
|
|
||||||
|
auto section = &coff->mSectionHeaders[contrib->mSection - 1];
|
||||||
|
if (section->mSizeOfRawData <= 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
contribs.Add(contrib);
|
||||||
|
}
|
||||||
|
contribs.Sort([](DbgCompileUnitContrib* lhs, DbgCompileUnitContrib* rhs)
|
||||||
|
{
|
||||||
|
return lhs->mLength > rhs->mLength;
|
||||||
|
});
|
||||||
|
|
||||||
|
totalContrib = 0;
|
||||||
|
result += "Contribs:\n";
|
||||||
|
for (auto contrib : contribs)
|
||||||
|
{
|
||||||
|
auto cvModule = coff->mCvModuleInfo[contrib->mCompileUnitId];
|
||||||
|
auto section = &coff->mSectionHeaders[contrib->mSection - 1];
|
||||||
|
result += StrFormat("\t%s\t%s\t%0.2fk\t%@\n", cvModule->mModuleName, section->mName, (contrib->mLength)/1024.0f, contrib->mAddress);
|
||||||
|
totalContrib += contrib->mLength;
|
||||||
|
}
|
||||||
|
result += StrFormat("\tTOTAL: %0.2fk\n", (totalContrib) / 1024.0f);
|
||||||
|
result += "\n";
|
||||||
|
|
||||||
|
struct SymbolEntry
|
||||||
|
{
|
||||||
|
const char* mName;
|
||||||
|
addr_target mAddress;
|
||||||
|
int mSize;
|
||||||
|
};
|
||||||
|
Array<SymbolEntry> symbolEntries;
|
||||||
|
|
||||||
|
for (auto symbol : mDebugTarget->mSymbolMap)
|
||||||
|
{
|
||||||
|
if (symbol->mDbgModule != coff)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (!symbolEntries.IsEmpty())
|
||||||
|
{
|
||||||
|
auto lastSymbol = &symbolEntries.back();
|
||||||
|
if (lastSymbol->mSize == 0)
|
||||||
|
lastSymbol->mSize = symbol->mAddress - lastSymbol->mAddress;
|
||||||
|
}
|
||||||
|
|
||||||
|
SymbolEntry symbolEntry;
|
||||||
|
symbolEntry.mName = symbol->mName;
|
||||||
|
symbolEntry.mAddress = symbol->mAddress;
|
||||||
|
symbolEntry.mSize = 0;
|
||||||
|
symbolEntries.Add(symbolEntry);
|
||||||
|
}
|
||||||
|
if (!symbolEntries.IsEmpty())
|
||||||
|
{
|
||||||
|
auto lastSymbol = &symbolEntries.back();
|
||||||
|
for (auto contrib : contribs)
|
||||||
|
{
|
||||||
|
if ((lastSymbol->mAddress >= contrib->mAddress) && (lastSymbol->mAddress < contrib->mAddress + contrib->mLength))
|
||||||
|
{
|
||||||
|
lastSymbol->mSize = (contrib->mAddress + contrib->mLength) - lastSymbol->mAddress;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
symbolEntries.Sort([](const SymbolEntry& lhs, const SymbolEntry& rhs)
|
||||||
|
{
|
||||||
|
return lhs.mSize > rhs.mSize;
|
||||||
|
});
|
||||||
|
|
||||||
|
totalContrib = 0;
|
||||||
|
result += "Symbols:\n";
|
||||||
|
for (auto symbolEntry : symbolEntries)
|
||||||
|
{
|
||||||
|
result += StrFormat("\t%s\t%0.2fk\t%@\n", symbolEntry.mName, (symbolEntry.mSize) / 1024.0f, symbolEntry.mAddress);
|
||||||
|
totalContrib += symbolEntry.mSize;
|
||||||
|
}
|
||||||
|
result += StrFormat("\tTOTAL: %0.2fk\n", (totalContrib) / 1024.0f);
|
||||||
|
result += "\n";
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
totalContrib = 0;
|
||||||
|
result += "Static Variables:\n";
|
||||||
|
for (auto& variable : coff->mStaticVariables)
|
||||||
|
{
|
||||||
|
result += StrFormat("\t%s\t%0.2fk\n", variable->mName, (variable->mType->GetByteCount()) / 1024.0f);
|
||||||
|
totalContrib += variable->mType->GetByteCount();
|
||||||
|
}
|
||||||
|
result += StrFormat("\tTOTAL: %0.2fk\n", (totalContrib) / 1024.0f);
|
||||||
|
result += "\n";
|
||||||
|
|
||||||
|
totalContrib = 0;
|
||||||
|
result += "Methods:\n";
|
||||||
|
Array<DbgSubprogram*> methods;
|
||||||
|
for (int typeIdx = 0; typeIdx < coff->mTypes.mSize; typeIdx++)
|
||||||
|
{
|
||||||
|
auto type = coff->mTypes[typeIdx];
|
||||||
|
type->PopulateType();
|
||||||
|
for (auto method : type->mMethodList)
|
||||||
|
methods.Add(method);
|
||||||
|
}
|
||||||
|
for (auto compileUnit : dbgModule->mCompileUnits)
|
||||||
|
{
|
||||||
|
for (auto method : compileUnit->mOrphanMethods)
|
||||||
|
methods.Add(method);
|
||||||
|
}
|
||||||
|
methods.Sort([](DbgSubprogram* lhs, DbgSubprogram* rhs)
|
||||||
|
{
|
||||||
|
return lhs->GetByteCount() > rhs->GetByteCount();
|
||||||
|
});
|
||||||
|
for (auto method : methods)
|
||||||
|
{
|
||||||
|
int methodSize = method->GetByteCount();
|
||||||
|
if (methodSize <= 0)
|
||||||
|
continue;
|
||||||
|
auto name = method->ToString();
|
||||||
|
result += StrFormat("\t%s\t%0.2fk\n", name.c_str(), methodSize / 1024.0f);
|
||||||
|
totalContrib += methodSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
result += StrFormat("\tTOTAL: %0.2fk\n", (totalContrib) / 1024.0f);
|
||||||
|
result += "\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
void WinDebugger::CancelSymSrv()
|
void WinDebugger::CancelSymSrv()
|
||||||
{
|
{
|
||||||
AutoCrit autoCrit(mDebugManager->mCritSect);
|
AutoCrit autoCrit(mDebugManager->mCritSect);
|
||||||
|
|
|
@ -656,6 +656,7 @@ public:
|
||||||
virtual String GetCurrentException() override;
|
virtual String GetCurrentException() override;
|
||||||
virtual void SetAliasPath(const StringImpl& origPath, const StringImpl& localPath) override;
|
virtual void SetAliasPath(const StringImpl& origPath, const StringImpl& localPath) override;
|
||||||
virtual String GetModulesInfo() override;
|
virtual String GetModulesInfo() override;
|
||||||
|
virtual String GetModuleInfo(const StringImpl& moduleName) override;
|
||||||
virtual void CancelSymSrv() override;
|
virtual void CancelSymSrv() override;
|
||||||
virtual bool HasPendingDebugLoads() override;
|
virtual bool HasPendingDebugLoads() override;
|
||||||
virtual int LoadImageForModule(const StringImpl& moduleName, const StringImpl& debugFileName) override;
|
virtual int LoadImageForModule(const StringImpl& moduleName, const StringImpl& debugFileName) override;
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
|
|
||||||
@ECHO --------------------------- Beef Test_Build.Bat Version 1 ---------------------------
|
@ECHO --------------------------- Beef Test_Build.Bat Version 1 ---------------------------
|
||||||
|
|
||||||
@SET P4_CHANGELIST=%1
|
@SET P4_CHANGELIST=%1
|
||||||
|
@ -33,6 +32,20 @@ IDE\Tests\SysMSVCRT\build\Debug_Win64\SysMSVCRT\SysMSVCRT.exe 1000 234
|
||||||
IDE\dist\BeefBuild_d -proddir=BeefLibs\corlib -test
|
IDE\dist\BeefBuild_d -proddir=BeefLibs\corlib -test
|
||||||
@IF %ERRORLEVEL% NEQ 0 GOTO HADERROR
|
@IF %ERRORLEVEL% NEQ 0 GOTO HADERROR
|
||||||
|
|
||||||
|
@ECHO Building Tiny
|
||||||
|
bin\RunWithStats IDE\dist\BeefBuild -proddir=IDE\Tests\Tiny -clean -config=Release
|
||||||
|
set size=0
|
||||||
|
FOR /F "usebackq" %%A IN ('IDE\Tests\Tiny\build\Release_Win64\Tiny\Tiny.exe') DO set size=%%~zA
|
||||||
|
echo Tiny executable size: %size% (expected 13824, max 16000)
|
||||||
|
if %size% LSS 10000 (
|
||||||
|
echo TINY executable not found?
|
||||||
|
goto :HADERROR
|
||||||
|
)
|
||||||
|
if %size% GTR 16000 (
|
||||||
|
echo TINY executable is too large!
|
||||||
|
goto :HADERROR
|
||||||
|
)
|
||||||
|
|
||||||
@ECHO Building BeefIDE_d with BeefBuild_d
|
@ECHO Building BeefIDE_d with BeefBuild_d
|
||||||
bin\RunAndWait IDE\dist\BeefPerf.exe -cmd="Nop()"
|
bin\RunAndWait IDE\dist\BeefPerf.exe -cmd="Nop()"
|
||||||
@IF %ERRORLEVEL% NEQ 0 GOTO FAILPERF_START
|
@IF %ERRORLEVEL% NEQ 0 GOTO FAILPERF_START
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue