From 1de07d0ee426af34a28caf69dbb9909a22484b19 Mon Sep 17 00:00:00 2001 From: Brian Fiete Date: Fri, 17 Jan 2025 10:17:19 -0800 Subject: [PATCH] Static init priority changes, Platform hooking --- BeefLibs/corlib/src/FFI/Function.bf | 2 +- BeefLibs/corlib/src/IO/Directory.bf | 28 ++++--- BeefLibs/corlib/src/IO/File.bf | 53 +++++++++--- BeefLibs/corlib/src/IO/FileStream.bf | 52 ++++++------ BeefLibs/corlib/src/IO/MemoryStream.bf | 94 ++++++++++++++++++++++ BeefLibs/corlib/src/IO/Pipe.bf | 4 +- BeefLibs/corlib/src/Platform.bf | 79 +++++++++++------- BeefLibs/corlib/src/Random.bf | 2 +- BeefLibs/corlib/src/Runtime.bf | 3 +- BeefLibs/corlib/src/StaticHookAttribute.bf | 90 +++++++++++++++++++++ BeefLibs/corlib/src/Text/Encoding.bf | 2 +- BeefLibs/corlib/src/Threading/Thread.bf | 4 +- BeefLibs/corlib/src/TimeZoneInfo.bf | 2 +- 13 files changed, 328 insertions(+), 87 deletions(-) create mode 100644 BeefLibs/corlib/src/StaticHookAttribute.bf diff --git a/BeefLibs/corlib/src/FFI/Function.bf b/BeefLibs/corlib/src/FFI/Function.bf index 149f59b5..0846ad7a 100644 --- a/BeefLibs/corlib/src/FFI/Function.bf +++ b/BeefLibs/corlib/src/FFI/Function.bf @@ -1,6 +1,6 @@ namespace System.FFI { - [CRepr, StaticInitPriority(100)] + [CRepr, StaticInitPriority(200)] struct FFIType { public enum TypeKind : uint16 diff --git a/BeefLibs/corlib/src/IO/Directory.bf b/BeefLibs/corlib/src/IO/Directory.bf index d815fb9c..bc5634f7 100644 --- a/BeefLibs/corlib/src/IO/Directory.bf +++ b/BeefLibs/corlib/src/IO/Directory.bf @@ -135,7 +135,7 @@ namespace System.IO bfpFlags |= .Directories; if (flags.HasFlag(.Files)) bfpFlags |= .Files; - let findFileData = Platform.BfpFindFileData_FindFirstFile(useStr, bfpFlags, null); + let findFileData = Platform.Hook.BfpFindFileData_FindFirstFile(useStr, bfpFlags, null); return FileEnumerator(useStr, findFileData); } @@ -206,7 +206,7 @@ namespace System.IO { get { - return Platform.BfpFindFileData_GetFileAttributes(mFindFileData).HasFlag(.Directory); + return Platform.Hook.BfpFindFileData_GetFileAttributes(mFindFileData).HasFlag(.Directory); } } @@ -214,7 +214,7 @@ namespace System.IO { Platform.GetStrHelper(outFileName, scope (outPtr, outSize, outResult) => { - Platform.BfpFindFileData_GetFileName(mFindFileData, outPtr, outSize, (Platform.BfpFileResult*)outResult); + Platform.Hook.BfpFindFileData_GetFileName(mFindFileData, outPtr, outSize, (Platform.BfpFileResult*)outResult); }); } @@ -228,43 +228,45 @@ namespace System.IO public DateTime GetLastWriteTime() { - return DateTime.FromFileTime((int64)Platform.BfpFindFileData_GetTime_LastWrite(mFindFileData)); + return DateTime.FromFileTime((int64)Platform.Hook.BfpFindFileData_GetTime_LastWrite(mFindFileData)); } public DateTime GetLastWriteTimeUtc() { - return DateTime.FromFileTimeUtc((int64)Platform.BfpFindFileData_GetTime_LastWrite(mFindFileData)); + return DateTime.FromFileTimeUtc((int64)Platform.Hook.BfpFindFileData_GetTime_LastWrite(mFindFileData)); } public DateTime GetCreatedTime() { - return DateTime.FromFileTime((int64)Platform.BfpFindFileData_GetTime_Created(mFindFileData)); + return DateTime.FromFileTime((int64)Platform.Hook.BfpFindFileData_GetTime_Created(mFindFileData)); } public DateTime GetCreatedTimeUtc() { - return DateTime.FromFileTimeUtc((int64)Platform.BfpFindFileData_GetTime_Created(mFindFileData)); + return DateTime.FromFileTimeUtc((int64)Platform.Hook.BfpFindFileData_GetTime_Created(mFindFileData)); } public DateTime GetAccessedTime() { - return DateTime.FromFileTime((int64)Platform.BfpFindFileData_GetTime_Access(mFindFileData)); + return DateTime.FromFileTime((int64)Platform.Hook.BfpFindFileData_GetTime_Access(mFindFileData)); } public DateTime GetAccessedTimeUtc() { - return DateTime.FromFileTimeUtc((int64)Platform.BfpFindFileData_GetTime_Access(mFindFileData)); + return DateTime.FromFileTimeUtc((int64)Platform.Hook.BfpFindFileData_GetTime_Access(mFindFileData)); } public int64 GetFileSize() { - return Platform.BfpFindFileData_GetFileSize(mFindFileData); + return Platform.Hook.BfpFindFileData_GetFileSize(mFindFileData); } public Platform.BfpFileAttributes GetFileAttributes() { - return Platform.BfpFindFileData_GetFileAttributes(mFindFileData); + return Platform.Hook.BfpFindFileData_GetFileAttributes(mFindFileData); } + + public static bool operator implicit (Self self) => self.mFindFileData != null; } struct FileEnumerator : IEnumerator, IDisposable @@ -292,7 +294,7 @@ namespace System.IO { delete mSearchStr; if (mFindFileData != null) - Platform.BfpFindFileData_Release(mFindFileData); + Platform.Hook.BfpFindFileData_Release(mFindFileData); } public bool MoveNext() mut @@ -301,7 +303,7 @@ namespace System.IO if (mIdx == 0) return mFindFileData != null; - return Platform.BfpFindFileData_FindNextFile(mFindFileData); + return Platform.Hook.BfpFindFileData_FindNextFile(mFindFileData); } public Result GetNext() mut diff --git a/BeefLibs/corlib/src/IO/File.bf b/BeefLibs/corlib/src/IO/File.bf index e0d5a219..9e3fe409 100644 --- a/BeefLibs/corlib/src/IO/File.bf +++ b/BeefLibs/corlib/src/IO/File.bf @@ -141,13 +141,13 @@ namespace System.IO public static bool Exists(StringView fileName) { - return Platform.BfpFile_Exists(fileName.ToScopeCStr!()); + return Platform.Hook.BfpFile_Exists(fileName.ToScopeCStr!()); } public static Result Delete(StringView fileName) { Platform.BfpFileResult result = default; - Platform.BfpFile_Delete(fileName.ToScopeCStr!(), &result); + Platform.Hook.BfpFile_Delete(fileName.ToScopeCStr!(), &result); if ((result != .Ok) && (result != .NotFound)) return .Err(result); return .Ok; @@ -156,7 +156,7 @@ namespace System.IO public static Result Move(StringView fromPath, StringView toPath) { Platform.BfpFileResult result = default; - Platform.BfpFile_Rename(fromPath.ToScopeCStr!(), toPath.ToScopeCStr!(), &result); + Platform.Hook.BfpFile_Rename(fromPath.ToScopeCStr!(), toPath.ToScopeCStr!(), &result); if (result != .Ok) return .Err(result); return .Ok; @@ -165,7 +165,7 @@ namespace System.IO public static Result Copy(StringView fromPath, StringView toPath) { Platform.BfpFileResult result = default; - Platform.BfpFile_Copy(fromPath.ToScopeCStr!(), toPath.ToScopeCStr!(), .Always, &result); + Platform.Hook.BfpFile_Copy(fromPath.ToScopeCStr!(), toPath.ToScopeCStr!(), .Always, &result); if (result != .Ok) return .Err(result); return .Ok; @@ -174,7 +174,7 @@ namespace System.IO public static Result CopyIfNewer(StringView fromPath, StringView toPath) { Platform.BfpFileResult result = default; - Platform.BfpFile_Copy(fromPath.ToScopeCStr!(), toPath.ToScopeCStr!(), .IfNewer, &result); + Platform.Hook.BfpFile_Copy(fromPath.ToScopeCStr!(), toPath.ToScopeCStr!(), .IfNewer, &result); if (result != .Ok) return .Err(result); return .Ok; @@ -183,7 +183,7 @@ namespace System.IO public static Result Copy(StringView fromPath, StringView toPath, bool overwrite) { Platform.BfpFileResult result = default; - Platform.BfpFile_Copy(fromPath.ToScopeCStr!(), toPath.ToScopeCStr!(), overwrite ? .Always : .IfNotExists, &result); + Platform.Hook.BfpFile_Copy(fromPath.ToScopeCStr!(), toPath.ToScopeCStr!(), overwrite ? .Always : .IfNotExists, &result); if (result != .Ok) return .Err(result); return .Ok; @@ -192,7 +192,7 @@ namespace System.IO public static Result SetAttributes(StringView path, FileAttributes attr) { Platform.BfpFileResult result = default; - Platform.BfpFile_SetAttributes(path.ToScopeCStr!(), (Platform.BfpFileAttributes)attr, &result); + Platform.Hook.BfpFile_SetAttributes(path.ToScopeCStr!(), (Platform.BfpFileAttributes)attr, &result); if (result != .Ok) return .Err(result); return .Ok; @@ -200,12 +200,47 @@ namespace System.IO public static Result GetLastWriteTime(StringView fullPath) { - return DateTime.FromFileTime((int64)Platform.BfpFile_GetTime_LastWrite(fullPath.ToScopeCStr!())); + return DateTime.FromFileTime((int64)Platform.Hook.BfpFile_GetTime_LastWrite(fullPath.ToScopeCStr!())); } public static Result GetLastWriteTimeUtc(StringView fullPath) { - return DateTime.FromFileTimeUtc((int64)Platform.BfpFile_GetTime_LastWrite(fullPath.ToScopeCStr!())); + return DateTime.FromFileTimeUtc((int64)Platform.Hook.BfpFile_GetTime_LastWrite(fullPath.ToScopeCStr!())); } } + + class FileInfo + { + FileFindEntry mFileFindEntry; + + public this(StringView path) + { + let findFileData = Platform.Hook.BfpFindFileData_FindFirstFile(path.ToScopeCStr!(), .Files, null); + if (findFileData == null) + return; + mFileFindEntry = .(new .(path), findFileData); + } + + public ~this() + { + if (mFileFindEntry.[Friend]mSearchStr != null) + { + delete mFileFindEntry.[Friend]mSearchStr; + Platform.Hook.BfpFindFileData_Release(mFileFindEntry.[Friend]mFindFileData); + } + } + + public bool Exists => mFileFindEntry; + public bool IsDirectory => mFileFindEntry ? mFileFindEntry.IsDirectory : default; + public void GetFileName(String outFileName) { if (mFileFindEntry) mFileFindEntry.GetFileName(outFileName); } + public void GetFilePath(String outPath) { if (mFileFindEntry) mFileFindEntry.GetFilePath(outPath); } + public DateTime GetLastWriteTime() => mFileFindEntry ? mFileFindEntry.GetLastWriteTime() : default; + public DateTime GetLastWriteTimeUtc() => mFileFindEntry ? mFileFindEntry.GetLastWriteTimeUtc() : default; + public DateTime GetCreatedTime() => mFileFindEntry ? mFileFindEntry.GetCreatedTime() : default; + public DateTime GetCreatedTimeUtc() => mFileFindEntry ? mFileFindEntry.GetCreatedTimeUtc() : default; + public DateTime GetAccessedTime() => mFileFindEntry ? mFileFindEntry.GetAccessedTime() : default; + public DateTime GetAccessedTimeUtc() => mFileFindEntry ? mFileFindEntry.GetAccessedTimeUtc() : default; + public int64 GetFileSize() => mFileFindEntry ? mFileFindEntry.GetFileSize() : default; + public Platform.BfpFileAttributes GetFileAttributes() => mFileFindEntry ? mFileFindEntry.GetFileAttributes() : default; + } } diff --git a/BeefLibs/corlib/src/IO/FileStream.bf b/BeefLibs/corlib/src/IO/FileStream.bf index c95f2472..d037a64b 100644 --- a/BeefLibs/corlib/src/IO/FileStream.bf +++ b/BeefLibs/corlib/src/IO/FileStream.bf @@ -12,12 +12,12 @@ namespace System.IO { get { - return Platform.BfpFile_Seek(mBfpFile, 0, .Relative); + return Platform.Hook.BfpFile_Seek(mBfpFile, 0, .Relative); } set { - Platform.BfpFile_Seek(mBfpFile, value, .Absolute); + Platform.Hook.BfpFile_Seek(mBfpFile, value, .Absolute); } } @@ -25,7 +25,7 @@ namespace System.IO { get { - return Platform.BfpFile_GetFileSize(mBfpFile); + return Platform.Hook.BfpFile_GetFileSize(mBfpFile); } } @@ -35,7 +35,7 @@ namespace System.IO { if (mBfpFile == null) return 0; - return Platform.BfpFile_GetSystemHandle(mBfpFile); + return Platform.Hook.BfpFile_GetSystemHandle(mBfpFile); } } @@ -46,7 +46,7 @@ namespace System.IO public override Result Seek(int64 pos, SeekKind seekKind = .Absolute) { - int64 newPos = Platform.BfpFile_Seek(mBfpFile, pos, (Platform.BfpFileSeekKind)seekKind); + int64 newPos = Platform.Hook.BfpFile_Seek(mBfpFile, pos, (Platform.BfpFileSeekKind)seekKind); // Ensure position is what was requested if ((seekKind == .Absolute) && (newPos != pos)) return .Err; @@ -56,7 +56,7 @@ namespace System.IO public override Result TryRead(Span data) { Platform.BfpFileResult result = .Ok; - int numBytesRead = Platform.BfpFile_Read(mBfpFile, data.Ptr, data.Length, -1, &result); + int numBytesRead = Platform.Hook.BfpFile_Read(mBfpFile, data.Ptr, data.Length, -1, &result); if ((result != .Ok) && (result != .PartialData)) return .Err; return numBytesRead; @@ -65,7 +65,7 @@ namespace System.IO public override Result TryRead(Span data, int timeoutMS) { Platform.BfpFileResult result = .Ok; - int numBytesRead = Platform.BfpFile_Read(mBfpFile, data.Ptr, data.Length, timeoutMS, &result); + int numBytesRead = Platform.Hook.BfpFile_Read(mBfpFile, data.Ptr, data.Length, timeoutMS, &result); if ((result != .Ok) && (result != .PartialData)) { switch (result) @@ -84,7 +84,7 @@ namespace System.IO public override Result TryWrite(Span data) { Platform.BfpFileResult result = .Ok; - int numBytesWritten = Platform.BfpFile_Write(mBfpFile, data.Ptr, data.Length, -1, &result); + int numBytesWritten = Platform.Hook.BfpFile_Write(mBfpFile, data.Ptr, data.Length, -1, &result); if ((result != .Ok) && (result != .PartialData)) return .Err; return numBytesWritten; @@ -93,7 +93,7 @@ namespace System.IO public override Result Close() { if (mBfpFile != null) - Platform.BfpFile_Release(mBfpFile); + Platform.Hook.BfpFile_Release(mBfpFile); mBfpFile = null; return .Ok; } @@ -101,7 +101,7 @@ namespace System.IO public override Result Flush() { if (mBfpFile != null) - Platform.BfpFile_Flush(mBfpFile); + Platform.Hook.BfpFile_Flush(mBfpFile); return .Ok; } @@ -159,7 +159,7 @@ namespace System.IO public Result OpenStd(Platform.BfpFileStdKind stdKind) { Platform.BfpFileResult fileResult = .Ok; - mBfpFile = Platform.BfpFile_GetStd(stdKind, &fileResult); + mBfpFile = Platform.Hook.BfpFile_GetStd(stdKind, &fileResult); mFileAccess = .ReadWrite; if ((mBfpFile == null) || (fileResult != .Ok)) @@ -218,7 +218,7 @@ namespace System.IO Platform.BfpFileAttributes fileFlags = .Normal; Platform.BfpFileResult fileResult = .Ok; - mBfpFile = Platform.BfpFile_Create(path.ToScopeCStr!(128), createKind, createFlags, fileFlags, &fileResult); + mBfpFile = Platform.Hook.BfpFile_Create(path.ToScopeCStr!(128), createKind, createFlags, fileFlags, &fileResult); if ((mBfpFile == null) || (fileResult != .Ok)) { @@ -261,7 +261,7 @@ namespace System.IO Seek(length); Platform.BfpFileResult result = .Ok; - Platform.BfpFile_Truncate(mBfpFile, &result); + Platform.Hook.BfpFile_Truncate(mBfpFile, &result); if (result != .Ok) { Seek(pos); @@ -297,7 +297,7 @@ namespace System.IO { if (mBfpFile == null) return 0; - return Platform.BfpFile_GetSystemHandle(mBfpFile); + return Platform.Hook.BfpFile_GetSystemHandle(mBfpFile); } } @@ -321,7 +321,7 @@ namespace System.IO { set { - // Matches the behavior of Platform.BfpFile_Seek(mBfpFile, value, .Absolute); + // Matches the behavior of Platform.Hook.BfpFile_Seek(mBfpFile, value, .Absolute); mPos = Math.Max(value, 0); } } @@ -355,7 +355,7 @@ namespace System.IO public Result OpenStd(Platform.BfpFileStdKind stdKind) { Platform.BfpFileResult fileResult = .Ok; - mBfpFile = Platform.BfpFile_GetStd(stdKind, &fileResult); + mBfpFile = Platform.Hook.BfpFile_GetStd(stdKind, &fileResult); mFileAccess = .ReadWrite; if ((mBfpFile == null) || (fileResult != .Ok)) @@ -413,7 +413,7 @@ namespace System.IO Platform.BfpFileAttributes fileFlags = .Normal; Platform.BfpFileResult fileResult = .Ok; - mBfpFile = Platform.BfpFile_Create(path.ToScopeCStr!(128), createKind, createFlags, fileFlags, &fileResult); + mBfpFile = Platform.Hook.BfpFile_Create(path.ToScopeCStr!(128), createKind, createFlags, fileFlags, &fileResult); if ((mBfpFile == null) || (fileResult != .Ok)) { @@ -467,7 +467,7 @@ namespace System.IO newPos = mPos + pos; } - // Matches the behaviour of Platform.BfpFile_Seek(mBfpFile, value, .Absolute); + // Matches the behaviour of Platform.Hook.BfpFile_Seek(mBfpFile, value, .Absolute); mPos = Math.Max(newPos, 0); if (seekKind == .Absolute && newPos < 0) return .Err; @@ -479,7 +479,7 @@ namespace System.IO { let ret = base.Close(); if (mBfpFile != null) - Platform.BfpFile_Release(mBfpFile); + Platform.Hook.BfpFile_Release(mBfpFile); mBfpFile = null; mFileAccess = default; @@ -489,12 +489,12 @@ namespace System.IO protected override void UpdateLength() { - mUnderlyingLength = Platform.BfpFile_GetFileSize(mBfpFile); + mUnderlyingLength = Platform.Hook.BfpFile_GetFileSize(mBfpFile); } protected Result SeekUnderlying(int64 offset, Platform.BfpFileSeekKind seekKind = .Absolute) { - int64 newPos = Platform.BfpFile_Seek(mBfpFile, offset, seekKind); + int64 newPos = Platform.Hook.BfpFile_Seek(mBfpFile, offset, seekKind); Result result = ((seekKind == .Absolute) && (newPos != offset)) ? .Err(.SeekError) : .Ok; if (result case .Ok) mBfpFilePos = newPos; @@ -507,7 +507,7 @@ namespace System.IO Try!(SeekUnderlying(pos)); Platform.BfpFileResult result = .Ok; - int numBytesRead = Platform.BfpFile_Read(mBfpFile, data.Ptr, data.Length, -1, &result); + int numBytesRead = Platform.Hook.BfpFile_Read(mBfpFile, data.Ptr, data.Length, -1, &result); if ((result != .Ok) && (result != .PartialData)) return .Err; mBfpFilePos += numBytesRead; @@ -520,7 +520,7 @@ namespace System.IO Try!(SeekUnderlying(pos)); Platform.BfpFileResult result = .Ok; - int numBytesRead = Platform.BfpFile_Write(mBfpFile, data.Ptr, data.Length, -1, &result); + int numBytesRead = Platform.Hook.BfpFile_Write(mBfpFile, data.Ptr, data.Length, -1, &result); if ((result != .Ok) && (result != .PartialData)) return .Err; mBfpFilePos += numBytesRead; @@ -533,7 +533,7 @@ namespace System.IO Try!(SeekUnderlying(mPos)); Platform.BfpFileResult result = .Ok; - int numBytesRead = Platform.BfpFile_Read(mBfpFile, data.Ptr, data.Length, timeoutMS, &result); + int numBytesRead = Platform.Hook.BfpFile_Read(mBfpFile, data.Ptr, data.Length, timeoutMS, &result); if ((result != .Ok) && (result != .PartialData)) { switch (result) @@ -560,7 +560,7 @@ namespace System.IO } Platform.BfpFileResult result = .Ok; - Platform.BfpFile_Truncate(mBfpFile, &result); + Platform.Hook.BfpFile_Truncate(mBfpFile, &result); if (result != .Ok) { Try!(SeekUnderlying(pos)); @@ -585,7 +585,7 @@ namespace System.IO { var result = base.Flush(); if (mBfpFile != null) - Platform.BfpFile_Flush(mBfpFile); + Platform.Hook.BfpFile_Flush(mBfpFile); return result; } } diff --git a/BeefLibs/corlib/src/IO/MemoryStream.bf b/BeefLibs/corlib/src/IO/MemoryStream.bf index db69a873..f4f1383d 100644 --- a/BeefLibs/corlib/src/IO/MemoryStream.bf +++ b/BeefLibs/corlib/src/IO/MemoryStream.bf @@ -116,4 +116,98 @@ namespace System.IO mPosition = 0; } } + + class FixedMemoryStream : Stream + { + Span mMemory; + int mPosition = 0; + + public override int64 Position + { + get + { + return mPosition; + } + + set + { + mPosition = (.)value; + } + } + + public override int64 Length + { + get + { + return mMemory.Length; + } + } + + public override bool CanRead + { + get + { + return true; + } + } + + public override bool CanWrite + { + get + { + return true; + } + } + + + public this(Span memory) + { + mMemory = memory; + } + + public Span Memory => mMemory; + + public override Result TryRead(Span data) + { + let count = data.Length; + if (count == 0) + return .Ok(0); + int readBytes = Math.Min(count, mMemory.Length - mPosition); + if (readBytes <= 0) + return .Ok(readBytes); + + Internal.MemCpy(data.Ptr, &mMemory[mPosition], readBytes); + mPosition += readBytes; + return .Ok(readBytes); + } + + public override Result TryWrite(Span data) + { + let count = data.Length; + if (count == 0) + return .Ok(0); + int growSize = mPosition + count - mMemory.Length; + if (growSize > 0) + return .Err; + Internal.MemCpy(&mMemory[mPosition], data.Ptr, count); + mPosition += count; + return .Ok(count); + } + + public override Result Close() + { + return .Ok; + } + + public override Result SetLength(int64 length) + { + return .Err; + } + + public void Clear() + { + mMemory.Clear(); + mPosition = 0; + } + } } diff --git a/BeefLibs/corlib/src/IO/Pipe.bf b/BeefLibs/corlib/src/IO/Pipe.bf index 35b409c2..6e12d4fb 100644 --- a/BeefLibs/corlib/src/IO/Pipe.bf +++ b/BeefLibs/corlib/src/IO/Pipe.bf @@ -46,7 +46,7 @@ namespace System.IO Platform.BfpFileAttributes fileFlags = .Normal; Platform.BfpFileResult fileResult = .Ok; - mBfpFile = Platform.BfpFile_Create(path, createKind, createFlags, fileFlags, &fileResult); + mBfpFile = Platform.Hook.BfpFile_Create(path, createKind, createFlags, fileFlags, &fileResult); if ((mBfpFile == null) || (fileResult != .Ok)) { @@ -83,7 +83,7 @@ namespace System.IO Platform.BfpFileAttributes fileFlags = .Normal; Platform.BfpFileResult fileResult = .Ok; - mBfpFile = Platform.BfpFile_Create(path, createKind, createFlags, fileFlags, &fileResult); + mBfpFile = Platform.Hook.sBfpFile_Create(path, createKind, createFlags, fileFlags, &fileResult); if ((mBfpFile == null) || (fileResult != .Ok)) { diff --git a/BeefLibs/corlib/src/Platform.bf b/BeefLibs/corlib/src/Platform.bf index 75db820f..f9a56f3e 100644 --- a/BeefLibs/corlib/src/Platform.bf +++ b/BeefLibs/corlib/src/Platform.bf @@ -66,6 +66,11 @@ namespace System TempFileError = (int)Result.TempFileError } + [StaticHook(typeof(SelfOuter))] + public static struct Hook + { + } + #if !BF_RUNTIME_DISABLE [CallingConvention(.Stdcall), CLink] public static extern uint32 BfpSystem_TickCount(); @@ -565,47 +570,47 @@ namespace System } #if !BF_RUNTIME_DISABLE - [CallingConvention(.Stdcall), CLink] + [CallingConvention(.Stdcall), CLink, StaticHook] public static extern BfpFile* BfpFile_Create(char8* name, BfpFileCreateKind createKind, BfpFileCreateFlags createFlags, BfpFileAttributes createdFileAttrs, BfpFileResult* outResult); - [CallingConvention(.Stdcall), CLink] + [CallingConvention(.Stdcall), CLink, StaticHook] public static extern BfpFile* BfpFile_GetStd(BfpFileStdKind kind, BfpFileResult* outResult); - [CallingConvention(.Stdcall), CLink] + [CallingConvention(.Stdcall), CLink, StaticHook] public static extern int BfpFile_GetSystemHandle(BfpFile* file); - [CallingConvention(.Stdcall), CLink] + [CallingConvention(.Stdcall), CLink, StaticHook] public static extern void BfpFile_Release(BfpFile* file); - [CallingConvention(.Stdcall), CLink] + [CallingConvention(.Stdcall), CLink, StaticHook] public static extern int BfpFile_Write(BfpFile* file, void* buffer, int size, int timeoutMS, BfpFileResult* outResult); - [CallingConvention(.Stdcall), CLink] + [CallingConvention(.Stdcall), CLink, StaticHook] public static extern int BfpFile_Read(BfpFile* file, void* buffer, int size, int timeoutMS, BfpFileResult* outResult); - [CallingConvention(.Stdcall), CLink] + [CallingConvention(.Stdcall), CLink, StaticHook] public static extern void BfpFile_Flush(BfpFile* file); - [CallingConvention(.Stdcall), CLink] + [CallingConvention(.Stdcall), CLink, StaticHook] public static extern int64 BfpFile_GetFileSize(BfpFile* file); - [CallingConvention(.Stdcall), CLink] + [CallingConvention(.Stdcall), CLink, StaticHook] public static extern int64 BfpFile_Seek(BfpFile* file, int64 offset, BfpFileSeekKind seekKind); - [CallingConvention(.Stdcall), CLink] + [CallingConvention(.Stdcall), CLink, StaticHook] public static extern void BfpFile_Truncate(BfpFile* file, BfpFileResult* outResult); - [CallingConvention(.Stdcall), CLink] + [CallingConvention(.Stdcall), CLink, StaticHook] public static extern BfpTimeStamp BfpFile_GetTime_LastWrite(char8* path); - [CallingConvention(.Stdcall), CLink] + [CallingConvention(.Stdcall), CLink, StaticHook] public static extern BfpFileAttributes BfpFile_GetAttributes(char8* path, BfpFileResult* outResult); - [CallingConvention(.Stdcall), CLink] + [CallingConvention(.Stdcall), CLink, StaticHook] public static extern void BfpFile_SetAttributes(char8* path, BfpFileAttributes attribs, BfpFileResult* outResult); - [CallingConvention(.Stdcall), CLink] + [CallingConvention(.Stdcall), CLink, StaticHook] public static extern void BfpFile_Copy(char8* oldPath, char8* newPath, BfpFileCopyKind copyKind, BfpFileResult* outResult); - [CallingConvention(.Stdcall), CLink] + [CallingConvention(.Stdcall), CLink, StaticHook] public static extern void BfpFile_Rename(char8* oldPath, char8* newPath, BfpFileResult* outResult); - [CallingConvention(.Stdcall), CLink] + [CallingConvention(.Stdcall), CLink, StaticHook] public static extern void BfpFile_Delete(char8* path, BfpFileResult* outResult); - [CallingConvention(.Stdcall), CLink] + [CallingConvention(.Stdcall), CLink, StaticHook] public static extern bool BfpFile_Exists(char8* path); - [CallingConvention(.Stdcall), CLink] + [CallingConvention(.Stdcall), CLink, StaticHook] public static extern void BfpFile_GetTempPath(char8* outPath, int32* inOutPathSize, BfpFileResult* outResult); - [CallingConvention(.Stdcall), CLink] + [CallingConvention(.Stdcall), CLink, StaticHook] public static extern void BfpFile_GetTempFileName(char8* outName, int32* inOutNameSize, BfpFileResult* outResult); - [CallingConvention(.Stdcall), CLink] + [CallingConvention(.Stdcall), CLink, StaticHook] public static extern void BfpFile_GetFullPath(char8* inPath, char8* outPath, int32* inOutPathSize, BfpFileResult* outResult); - [CallingConvention(.Stdcall), CLink] + [CallingConvention(.Stdcall), CLink, StaticHook] public static extern void BfpFile_GetActualPath(char8* inPath, char8* outPath, int32* inOutPathSize, BfpFileResult* outResult); #else @@ -660,23 +665,23 @@ namespace System }; #if !BF_RUNTIME_DISABLE - [CallingConvention(.Stdcall), CLink] + [CallingConvention(.Stdcall), CLink, StaticHook] public static extern BfpFindFileData* BfpFindFileData_FindFirstFile(char8* path, BfpFindFileFlags flags, BfpFileResult* outResult); - [CallingConvention(.Stdcall), CLink] + [CallingConvention(.Stdcall), CLink, StaticHook] public static extern bool BfpFindFileData_FindNextFile(BfpFindFileData* findData); - [CallingConvention(.Stdcall), CLink] + [CallingConvention(.Stdcall), CLink, StaticHook] public static extern void BfpFindFileData_GetFileName(BfpFindFileData* findData, char8* outName, int32* inOutNameSize, BfpFileResult* outResult); - [CallingConvention(.Stdcall), CLink] + [CallingConvention(.Stdcall), CLink, StaticHook] public static extern BfpTimeStamp BfpFindFileData_GetTime_LastWrite(BfpFindFileData* findData); - [CallingConvention(.Stdcall), CLink] + [CallingConvention(.Stdcall), CLink, StaticHook] public static extern BfpTimeStamp BfpFindFileData_GetTime_Created(BfpFindFileData* findData); - [CallingConvention(.Stdcall), CLink] + [CallingConvention(.Stdcall), CLink, StaticHook] public static extern BfpTimeStamp BfpFindFileData_GetTime_Access(BfpFindFileData* findData); - [CallingConvention(.Stdcall), CLink] + [CallingConvention(.Stdcall), CLink, StaticHook] public static extern BfpFileAttributes BfpFindFileData_GetFileAttributes(BfpFindFileData* findData); - [CallingConvention(.Stdcall), CLink] + [CallingConvention(.Stdcall), CLink, StaticHook] public static extern int64 BfpFindFileData_GetFileSize(BfpFindFileData* findData); - [CallingConvention(.Stdcall), CLink] + [CallingConvention(.Stdcall), CLink, StaticHook] public static extern void BfpFindFileData_Release(BfpFindFileData* findData); #else @@ -714,6 +719,20 @@ namespace System Documents } + public static bool SetStrHelper(StringView str, char8* outStr, int32* inOutSize, Result* outResult) + { + if (str.Length > *inOutSize + 1) + { + *inOutSize = (.)str.Length + 1; + *outResult = .InsufficientBuffer; + return false; + } + *inOutSize = (.)str.Length + 1; + Internal.MemCpy(outStr, str.Ptr, str.Length); + outStr[str.Length] = 0; + return true; + } + public static Result GetStrHelper(String outStr, delegate void (char8* outPtr, int32* outSize, Result* outResult) func) { let initSize = 4096; diff --git a/BeefLibs/corlib/src/Random.bf b/BeefLibs/corlib/src/Random.bf index 3e46ed2d..641fcf5b 100644 --- a/BeefLibs/corlib/src/Random.bf +++ b/BeefLibs/corlib/src/Random.bf @@ -21,7 +21,7 @@ namespace System using System.Threading; // This class is thread-safe for random results, but not deterministically thread-safe - [StaticInitPriority(100)] + [StaticInitPriority(200)] public class Random { // diff --git a/BeefLibs/corlib/src/Runtime.bf b/BeefLibs/corlib/src/Runtime.bf index a93be3b7..1006535c 100644 --- a/BeefLibs/corlib/src/Runtime.bf +++ b/BeefLibs/corlib/src/Runtime.bf @@ -14,7 +14,7 @@ namespace System public bool AVX, AVX2, AVX512; } - [StaticInitPriority(101)] + [StaticInitPriority(201)] static class Runtime { const int32 cVersion = 10; @@ -484,6 +484,7 @@ namespace System 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; + public static function void*(char8* filePath) LibraryLoadCallback; static ErrorHandlerResult CheckAssertError_Impl(AssertError.Kind kind, String error, String filePath, int lineNum) { diff --git a/BeefLibs/corlib/src/StaticHookAttribute.bf b/BeefLibs/corlib/src/StaticHookAttribute.bf new file mode 100644 index 00000000..27476383 --- /dev/null +++ b/BeefLibs/corlib/src/StaticHookAttribute.bf @@ -0,0 +1,90 @@ +namespace System; + +[AttributeUsage(.Types | .Method, .AlwaysIncludeTarget)] +public struct StaticHookAttribute : Attribute, IOnTypeInit +{ + Type mSrcType; + Type mDestType; + + public this() + { + mSrcType = null; + mDestType = null; + } + + public this(Type srcType) + { + mSrcType = srcType; + mDestType = null; + } + + public this(Type srcType, Type destType) + { + mSrcType = srcType; + mDestType = destType; + } + + [Comptime] + public void OnTypeInit(Type type, Self* prev) + { + var emitStr = scope String(); + + if (mDestType != null) + { + var hookAttr = mSrcType.GetCustomAttribute().Value; + + for (var methodInfo in mDestType.GetMethods(.Static)) + { + if (!methodInfo.HasCustomAttribute()) + continue; + emitStr.AppendF($"public static function {methodInfo.ReturnType}"); + emitStr.Append("("); + methodInfo.GetParamsDecl(emitStr); + emitStr.AppendF($") s{methodInfo.Name};\n"); + } + emitStr.Append("\n"); + + emitStr.Append("static this\n{\n"); + for (var methodInfo in mDestType.GetMethods(.Static)) + { + if (!methodInfo.HasCustomAttribute()) + continue; + + emitStr.AppendF($"\ts{methodInfo.Name} = {mSrcType}.s{methodInfo.Name} ?? => {hookAttr.mSrcType}.{methodInfo.Name};\n"); + emitStr.AppendF($"\t{mSrcType}.s{methodInfo.Name} = => {mDestType}.{methodInfo.Name};\n"); + } + emitStr.Append("}\n"); + } + else + { + if (mSrcType == null) + return; + + emitStr.Append("#pragma warning disable\n"); + for (var methodInfo in mSrcType.GetMethods(.Static)) + { + if (!methodInfo.HasCustomAttribute()) + continue; + + emitStr.AppendF($"public static function {methodInfo.ReturnType}"); + emitStr.Append("("); + methodInfo.GetParamsDecl(emitStr); + emitStr.AppendF($") s{methodInfo.Name};\n"); + + emitStr.AppendF($"public static {methodInfo.ReturnType} {methodInfo.Name}"); + emitStr.Append("("); + methodInfo.GetParamsDecl(emitStr); + emitStr.Append(")\n"); + emitStr.Append("{\n"); + emitStr.AppendF($"\tif (s{methodInfo.Name} != null)\n"); + emitStr.AppendF($"\t\treturn s{methodInfo.Name}("); + methodInfo.GetArgsList(emitStr); + emitStr.AppendF($");\n\treturn {mSrcType}.{methodInfo.Name}("); + methodInfo.GetArgsList(emitStr); + emitStr.Append(");\n}\n\n"); + } + } + + Compiler.EmitTypeBody(type, emitStr); + } +} diff --git a/BeefLibs/corlib/src/Text/Encoding.bf b/BeefLibs/corlib/src/Text/Encoding.bf index acbead21..eb5f7871 100644 --- a/BeefLibs/corlib/src/Text/Encoding.bf +++ b/BeefLibs/corlib/src/Text/Encoding.bf @@ -2,7 +2,7 @@ using System.Diagnostics; using System.Threading; namespace System.Text { - [StaticInitPriority(100)] + [StaticInitPriority(200)] abstract class Encoding { public enum DecodeError diff --git a/BeefLibs/corlib/src/Threading/Thread.bf b/BeefLibs/corlib/src/Threading/Thread.bf index bcd1c318..265d61ec 100644 --- a/BeefLibs/corlib/src/Threading/Thread.bf +++ b/BeefLibs/corlib/src/Threading/Thread.bf @@ -8,7 +8,7 @@ namespace System.Threading public delegate void ThreadStart(); public delegate void ParameterizedThreadStart(Object obj); - [StaticInitPriority(100)] + [StaticInitPriority(200)] public sealed class Thread { private int mInternalThread; @@ -28,7 +28,7 @@ namespace System.Threading public static Thread sMainThread ~ delete _; - [StaticInitPriority(102)] + [StaticInitPriority(202)] struct RuntimeThreadInit { static Object Thread_Alloc() diff --git a/BeefLibs/corlib/src/TimeZoneInfo.bf b/BeefLibs/corlib/src/TimeZoneInfo.bf index f227a407..08a15b84 100644 --- a/BeefLibs/corlib/src/TimeZoneInfo.bf +++ b/BeefLibs/corlib/src/TimeZoneInfo.bf @@ -53,7 +53,7 @@ namespace System { NoThrowOnInvalidTime = 2 } - [StaticInitPriority(100)] + [StaticInitPriority(200)] sealed public class TimeZoneInfo : IEquatable { // ---- SECTION: members supporting exposed properties -------------*