mirror of
https://github.com/beefytech/Beef.git
synced 2025-06-09 12:02:21 +02:00
Merge branch 'master' into FuzzyAutoComplete
This commit is contained in:
commit
62c3998521
64 changed files with 2485 additions and 598 deletions
|
@ -47,7 +47,7 @@ BF_IMPORT void BF_CALLTYPE BfSystem_ReportMemory(void* bfSystem);
|
||||||
BF_IMPORT void BF_CALLTYPE BfSystem_Delete(void* bfSystem);
|
BF_IMPORT void BF_CALLTYPE BfSystem_Delete(void* bfSystem);
|
||||||
BF_IMPORT void* BF_CALLTYPE BfSystem_CreatePassInstance(void* bfSystem);
|
BF_IMPORT void* BF_CALLTYPE BfSystem_CreatePassInstance(void* bfSystem);
|
||||||
BF_IMPORT void* BF_CALLTYPE BfSystem_CreateCompiler(void* bfSystem, bool isResolveOnly);
|
BF_IMPORT void* BF_CALLTYPE BfSystem_CreateCompiler(void* bfSystem, bool isResolveOnly);
|
||||||
BF_IMPORT void* BF_CALLTYPE BfSystem_CreateProject(void* bfSystem, const char* projectName);
|
BF_IMPORT void* BF_CALLTYPE BfSystem_CreateProject(void* bfSystem, const char* projectName, const char* projectDir);
|
||||||
BF_IMPORT void BF_CALLTYPE BfParser_Delete(void* bfParser);
|
BF_IMPORT void BF_CALLTYPE BfParser_Delete(void* bfParser);
|
||||||
BF_IMPORT void BF_CALLTYPE BfSystem_AddTypeOptions(void* bfSystem, const char* filter, int32 simdSetting, int32 optimizationLevel, int32 emitDebugInfo, int32 arrayBoundsCheck,
|
BF_IMPORT void BF_CALLTYPE BfSystem_AddTypeOptions(void* bfSystem, const char* filter, int32 simdSetting, int32 optimizationLevel, int32 emitDebugInfo, int32 arrayBoundsCheck,
|
||||||
int32 initLocalVariables, int32 emitDynamicCastCheck, int32 emitObjectAccessCheck, int32 allocStackTraceDepth);
|
int32 initLocalVariables, int32 emitDynamicCastCheck, int32 emitObjectAccessCheck, int32 allocStackTraceDepth);
|
||||||
|
@ -791,11 +791,11 @@ bool BootApp::Compile()
|
||||||
if (projectName.IsEmpty())
|
if (projectName.IsEmpty())
|
||||||
projectName.Append("BeefProject");
|
projectName.Append("BeefProject");
|
||||||
|
|
||||||
mProject = BfSystem_CreateProject(mSystem, projectName.c_str());
|
mProject = BfSystem_CreateProject(mSystem, projectName.c_str(), GetFileDir(mTargetPath).c_str());
|
||||||
|
|
||||||
if (mIsCERun)
|
if (mIsCERun)
|
||||||
{
|
{
|
||||||
mCELibProject = BfSystem_CreateProject(mSystem, "BeefLib");
|
mCELibProject = BfSystem_CreateProject(mSystem, "BeefLib", GetFileDir(mTargetPath).c_str());
|
||||||
|
|
||||||
BfProjectFlags flags = BfProjectFlags_None;
|
BfProjectFlags flags = BfProjectFlags_None;
|
||||||
BfProject_SetOptions(mCELibProject, BfTargetType_BeefLib, "", mDefines.c_str(), mOptLevel, 0, 0, 0, flags);
|
BfProject_SetOptions(mCELibProject, BfTargetType_BeefLib, "", mDefines.c_str(), mOptLevel, 0, 0, 0, flags);
|
||||||
|
|
|
@ -69,6 +69,12 @@ namespace Beefy.sys
|
||||||
Modify(mText, mHotKey, mBitmap, mEnabled, mCheckState, mRadioCheck);
|
Modify(mText, mHotKey, mBitmap, mEnabled, mCheckState, mRadioCheck);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void SetCheckState(int32 checkState)
|
||||||
|
{
|
||||||
|
mCheckState = checkState;
|
||||||
|
Modify(mText, mHotKey, mBitmap, mEnabled, mCheckState, mRadioCheck);
|
||||||
|
}
|
||||||
|
|
||||||
public void SetHotKey(StringView hotKey)
|
public void SetHotKey(StringView hotKey)
|
||||||
{
|
{
|
||||||
if (hotKey.IsNull)
|
if (hotKey.IsNull)
|
||||||
|
|
|
@ -2366,7 +2366,14 @@ namespace Beefy.widgets
|
||||||
case KeyCode.Down:
|
case KeyCode.Down:
|
||||||
{
|
{
|
||||||
int32 aDir = (keyCode == KeyCode.Up) ? -1 : 1;
|
int32 aDir = (keyCode == KeyCode.Up) ? -1 : 1;
|
||||||
bool didSelectionMove = PrepareForCursorMove(aDir);
|
if ((HasSelection()) && (!mWidgetWindow.IsKeyDown(KeyCode.Shift)))
|
||||||
|
{
|
||||||
|
var lineAndCol = CursorLineAndColumn;
|
||||||
|
var usePos = (aDir < 0) ? (int32)mSelection.Value.MinPos : mSelection.Value.MaxPos;
|
||||||
|
GetLineCharAtIdx(usePos, var selLine, var selLineChar);
|
||||||
|
CursorLineAndColumn = .(selLine, lineAndCol.mColumn);
|
||||||
|
mSelection = null;
|
||||||
|
}
|
||||||
|
|
||||||
GetCursorLineChar(out lineIdx, out lineChar);
|
GetCursorLineChar(out lineIdx, out lineChar);
|
||||||
|
|
||||||
|
@ -2403,9 +2410,6 @@ namespace Beefy.widgets
|
||||||
mCursorWantX = wantedX;
|
mCursorWantX = wantedX;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (didSelectionMove)
|
|
||||||
CursorToLineStart(false);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case KeyCode.Home:
|
case KeyCode.Home:
|
||||||
|
|
|
@ -10,6 +10,7 @@ namespace Beefy.widgets
|
||||||
public interface IMenu
|
public interface IMenu
|
||||||
{
|
{
|
||||||
void SetDisabled(bool enable);
|
void SetDisabled(bool enable);
|
||||||
|
void SetCheckState(int32 checkState);
|
||||||
}
|
}
|
||||||
|
|
||||||
public interface IMenuContainer
|
public interface IMenuContainer
|
||||||
|
|
|
@ -90,13 +90,13 @@ namespace Beefy.widgets
|
||||||
Minus = 0xBD,
|
Minus = 0xBD,
|
||||||
Period = 0xBE,
|
Period = 0xBE,
|
||||||
Slash = 0xBF,
|
Slash = 0xBF,
|
||||||
|
Tilde = 0xC0,
|
||||||
Grave = 0xC0,
|
Grave = 0xC0,
|
||||||
LBracket = 0xDB,
|
LBracket = 0xDB,
|
||||||
Backslash = 0xDC,
|
Backslash = 0xDC,
|
||||||
RBracket = 0xDD,
|
RBracket = 0xDD,
|
||||||
Apostrophe = 0xDE,
|
Apostrophe = 0xDE,
|
||||||
Backtick = 0xDF,
|
Backtick = 0xDF,
|
||||||
Tilde = 0xC0,
|
|
||||||
Command = 0xF0,
|
Command = 0xF0,
|
||||||
COUNT = 0xFF,
|
COUNT = 0xFF,
|
||||||
|
|
||||||
|
@ -141,6 +141,16 @@ namespace Beefy.widgets
|
||||||
return (KeyCode)LBracket;
|
return (KeyCode)LBracket;
|
||||||
if (c == ']')
|
if (c == ']')
|
||||||
return (KeyCode)RBracket;
|
return (KeyCode)RBracket;
|
||||||
|
if (c == '/')
|
||||||
|
return (KeyCode)Slash;
|
||||||
|
if (c == '\\')
|
||||||
|
return (KeyCode)Backslash;
|
||||||
|
if (c == '`')
|
||||||
|
return (KeyCode)Tilde;
|
||||||
|
if (c == '.')
|
||||||
|
return (KeyCode)Period;
|
||||||
|
if (c == ',')
|
||||||
|
return (KeyCode)Comma;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (str.StartsWith("0x"))
|
if (str.StartsWith("0x"))
|
||||||
|
@ -168,6 +178,10 @@ namespace Beefy.widgets
|
||||||
c = '[';
|
c = '[';
|
||||||
case RBracket:
|
case RBracket:
|
||||||
c = ']';
|
c = ']';
|
||||||
|
case .Slash:
|
||||||
|
c = '/';
|
||||||
|
case .Backslash:
|
||||||
|
c = '\\';
|
||||||
default:
|
default:
|
||||||
}
|
}
|
||||||
if (c != 0)
|
if (c != 0)
|
||||||
|
|
|
@ -616,5 +616,10 @@ namespace Beefy.widgets
|
||||||
{
|
{
|
||||||
mDisabled = disabled;
|
mDisabled = disabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void SetCheckState(int32 checkState)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -117,7 +117,7 @@ namespace SDL2
|
||||||
SDL.EventState(.JoyDeviceAdded, .Disable);
|
SDL.EventState(.JoyDeviceAdded, .Disable);
|
||||||
SDL.EventState(.JoyDeviceRemoved, .Disable);
|
SDL.EventState(.JoyDeviceRemoved, .Disable);
|
||||||
|
|
||||||
mWindow = SDL.CreateWindow(mTitle, .Undefined, .Undefined, mWidth, mHeight, .Shown);
|
mWindow = SDL.CreateWindow(mTitle, .Undefined, .Undefined, mWidth, mHeight, .Hidden); // Initially hide window
|
||||||
mRenderer = SDL.CreateRenderer(mWindow, -1, .Accelerated);
|
mRenderer = SDL.CreateRenderer(mWindow, -1, .Accelerated);
|
||||||
mScreen = SDL.GetWindowSurface(mWindow);
|
mScreen = SDL.GetWindowSurface(mWindow);
|
||||||
SDLImage.Init(.PNG | .JPG);
|
SDLImage.Init(.PNG | .JPG);
|
||||||
|
@ -247,6 +247,8 @@ namespace SDL2
|
||||||
{
|
{
|
||||||
// Initial render
|
// Initial render
|
||||||
Render();
|
Render();
|
||||||
|
// Show initially hidden window, mitigates white flash on slow startups
|
||||||
|
SDL.ShowWindow(mWindow);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -30,6 +30,8 @@ namespace System
|
||||||
Delete = 0x80000,
|
Delete = 0x80000,
|
||||||
Alias = 0x100000,
|
Alias = 0x100000,
|
||||||
Block = 0x200000,
|
Block = 0x200000,
|
||||||
|
DelegateTypeRef = 0x400000,
|
||||||
|
FunctionTypeRef = 0x800000,
|
||||||
|
|
||||||
Types = .Struct | .Enum | .Function | .Class | .Interface,
|
Types = .Struct | .Enum | .Function | .Class | .Interface,
|
||||||
ValueTypes = .Struct | .Enum | .Function,
|
ValueTypes = .Struct | .Enum | .Function,
|
||||||
|
@ -227,7 +229,7 @@ namespace System
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[AttributeUsage(.Method | .Constructor | .Delegate | .Function)]
|
[AttributeUsage(.Method | .Constructor | .Delegate | .Function | .DelegateTypeRef | .FunctionTypeRef)]
|
||||||
public struct CallingConventionAttribute : Attribute
|
public struct CallingConventionAttribute : Attribute
|
||||||
{
|
{
|
||||||
public enum Kind
|
public enum Kind
|
||||||
|
|
|
@ -17,6 +17,11 @@ namespace System
|
||||||
strBuffer.Append(((bool)this) ? TrueString : FalseString);
|
strBuffer.Append(((bool)this) ? TrueString : FalseString);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static int operator<=>(Boolean a, Boolean b)
|
||||||
|
{
|
||||||
|
return (SelfBase)a <=> (SelfBase)b;
|
||||||
|
}
|
||||||
|
|
||||||
public int GetHashCode()
|
public int GetHashCode()
|
||||||
{
|
{
|
||||||
return ((bool)this) ? 1 : 0;
|
return ((bool)this) ? 1 : 0;
|
||||||
|
|
|
@ -311,6 +311,7 @@ namespace System.Collections
|
||||||
{
|
{
|
||||||
if (sizeof(int) == 4)
|
if (sizeof(int) == 4)
|
||||||
return (int32)hashCode & 0x7FFFFFFF;
|
return (int32)hashCode & 0x7FFFFFFF;
|
||||||
|
#unwarn
|
||||||
if (sizeof(int_cosize) == 8)
|
if (sizeof(int_cosize) == 8)
|
||||||
return (int_cosize)(hashCode & 0x7FFFFFFF'FFFFFFFFL);
|
return (int_cosize)(hashCode & 0x7FFFFFFF'FFFFFFFFL);
|
||||||
return ((int32)hashCode ^ (int32)((int64)hashCode >> 33)) & 0x7FFFFFFF;
|
return ((int32)hashCode ^ (int32)((int64)hashCode >> 33)) & 0x7FFFFFFF;
|
||||||
|
|
|
@ -2,6 +2,7 @@ using System.Reflection;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Collections;
|
using System.Collections;
|
||||||
using System.Security.Cryptography;
|
using System.Security.Cryptography;
|
||||||
|
using System.IO;
|
||||||
|
|
||||||
namespace System
|
namespace System
|
||||||
{
|
{
|
||||||
|
@ -217,6 +218,12 @@ namespace System
|
||||||
[LinkName("#CallerFileDir")]
|
[LinkName("#CallerFileDir")]
|
||||||
public static extern String CallerFileDir;
|
public static extern String CallerFileDir;
|
||||||
|
|
||||||
|
[LinkName("#CallerType")]
|
||||||
|
public static extern Type CallerType;
|
||||||
|
|
||||||
|
[LinkName("#CallerTypeName")]
|
||||||
|
public static extern String CallerTypeName;
|
||||||
|
|
||||||
[LinkName("#CallerMemberName")]
|
[LinkName("#CallerMemberName")]
|
||||||
public static extern String CallerMemberName;
|
public static extern String CallerMemberName;
|
||||||
|
|
||||||
|
@ -300,5 +307,21 @@ namespace System
|
||||||
if (Compiler.IsComptime)
|
if (Compiler.IsComptime)
|
||||||
Comptime_EmitMixin(text);
|
Comptime_EmitMixin(text);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Comptime]
|
||||||
|
public static Span<uint8> ReadBinary(StringView path)
|
||||||
|
{
|
||||||
|
List<uint8> data = scope .();
|
||||||
|
File.ReadAll(path, data);
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
[Comptime]
|
||||||
|
public static String ReadText(StringView path)
|
||||||
|
{
|
||||||
|
String data = scope .();
|
||||||
|
File.ReadAllText(path, data);
|
||||||
|
return data;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -106,5 +106,24 @@ namespace System.Diagnostics
|
||||||
if (gIsDebuggerPresent)
|
if (gIsDebuggerPresent)
|
||||||
Break();
|
Break();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void WriteMemory(Span<uint8> mem)
|
||||||
|
{
|
||||||
|
String str = scope .();
|
||||||
|
for (int i < mem.Length)
|
||||||
|
{
|
||||||
|
if ((i != 0) && (i % 16 == 0))
|
||||||
|
str.Append('\n');
|
||||||
|
str.AppendF($" {mem.[Friend]mPtr[i]:X2}");
|
||||||
|
}
|
||||||
|
str.Append('\n');
|
||||||
|
Write(str);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void WriteMemory<T>(T result)
|
||||||
|
{
|
||||||
|
#unwarn
|
||||||
|
WriteMemory(.((.)&result, sizeof(T)));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,12 +10,23 @@ namespace System.Diagnostics
|
||||||
|
|
||||||
struct ProfileInstance : int32
|
struct ProfileInstance : int32
|
||||||
{
|
{
|
||||||
public void Dispose()
|
public bool HasValue
|
||||||
{
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return this != 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Dispose() mut
|
||||||
|
{
|
||||||
|
if (this == 0)
|
||||||
|
return;
|
||||||
String str = scope String();
|
String str = scope String();
|
||||||
str.Append("StopSampling\t");
|
str.Append("StopSampling\t");
|
||||||
((int32)this).ToString(str);
|
((int32)this).ToString(str);
|
||||||
Internal.ProfilerCmd(str);
|
Internal.ProfilerCmd(str);
|
||||||
|
this = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
|
using System.Collections;
|
||||||
|
|
||||||
namespace System
|
namespace System
|
||||||
{
|
{
|
||||||
|
@ -30,12 +31,157 @@ namespace System
|
||||||
return .Err;
|
return .Err;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*public override void ToString(String strBuffer) mut
|
public static bool IsDefined<T>(T value)
|
||||||
|
where T : enum
|
||||||
{
|
{
|
||||||
Type type = GetType();
|
var typeInst = (TypeInstance)typeof(T);
|
||||||
int32* iPtr = (int32*)((int)(&this) + (int)type.Size);
|
for (var field in typeInst.GetFields())
|
||||||
EnumToString(type, strBuffer, *iPtr);
|
{
|
||||||
//EnumToString(GetType(), )
|
if (field.[Friend]mFieldData.[Friend]mData == (.)value)
|
||||||
}*/
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static EnumEnumerator<TEnum> GetEnumerator<TEnum>()
|
||||||
|
where TEnum : enum
|
||||||
|
{
|
||||||
|
return .();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static EnumValuesEnumerator<TEnum> GetValues<TEnum>()
|
||||||
|
where TEnum : enum
|
||||||
|
{
|
||||||
|
return .();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static EnumNamesEnumerator<TEnum> GetNames<TEnum>()
|
||||||
|
where TEnum : enum
|
||||||
|
{
|
||||||
|
return .();
|
||||||
|
}
|
||||||
|
|
||||||
|
private struct EnumFieldsEnumerator<TEnum>
|
||||||
|
where TEnum : enum
|
||||||
|
{
|
||||||
|
TypeInstance mTypeInstance;
|
||||||
|
int32 mIdx;
|
||||||
|
|
||||||
|
public this()
|
||||||
|
{
|
||||||
|
mTypeInstance = typeof(TEnum) as TypeInstance;
|
||||||
|
mIdx = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Reset() mut
|
||||||
|
{
|
||||||
|
mIdx = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool MoveNext() mut
|
||||||
|
{
|
||||||
|
if (mTypeInstance == null)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
TypeInstance.FieldData* fieldData = null;
|
||||||
|
|
||||||
|
repeat
|
||||||
|
{
|
||||||
|
mIdx++;
|
||||||
|
if (mIdx == mTypeInstance.[Friend]mFieldDataCount)
|
||||||
|
return false;
|
||||||
|
fieldData = &mTypeInstance.[Friend]mFieldDataPtr[mIdx];
|
||||||
|
}
|
||||||
|
while (!fieldData.mFlags.HasFlag(.EnumCase));
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public FieldInfo Current
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
var fieldData = &mTypeInstance.[Friend]mFieldDataPtr[mIdx];
|
||||||
|
return FieldInfo(mTypeInstance, fieldData);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int32 Index
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return mIdx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Result<FieldInfo> GetNext() mut
|
||||||
|
{
|
||||||
|
if (!MoveNext())
|
||||||
|
return .Err;
|
||||||
|
return Current;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public struct EnumEnumerator<TEnum> : EnumFieldsEnumerator<TEnum>, IEnumerator<(StringView name, TEnum value)>
|
||||||
|
where TEnum : enum
|
||||||
|
{
|
||||||
|
public new (StringView name, TEnum value) Current
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return ((.)base.Current.[Friend]mFieldData.[Friend]mName, (.)base.Current.[Friend]mFieldData.[Friend]mData);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public new Result<(StringView name, TEnum value)> GetNext() mut
|
||||||
|
{
|
||||||
|
if (!MoveNext())
|
||||||
|
return .Err;
|
||||||
|
return Current;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public struct EnumValuesEnumerator<TEnum> : EnumFieldsEnumerator<TEnum>, IEnumerator<TEnum>
|
||||||
|
where TEnum : enum
|
||||||
|
{
|
||||||
|
public new TEnum Current
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return (.)base.Current.[Friend]mFieldData.[Friend]mData;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public new Result<TEnum> GetNext() mut
|
||||||
|
{
|
||||||
|
if (!MoveNext())
|
||||||
|
return .Err;
|
||||||
|
return Current;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public struct EnumNamesEnumerator<TEnum> : EnumFieldsEnumerator<TEnum>, IEnumerator<StringView>
|
||||||
|
where TEnum : enum
|
||||||
|
{
|
||||||
|
public new StringView Current
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return (.)base.Current.[Friend]mFieldData.[Friend]mName;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public new Result<StringView> GetNext() mut
|
||||||
|
{
|
||||||
|
if (!MoveNext())
|
||||||
|
return .Err;
|
||||||
|
return Current;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,7 @@ namespace System.IO
|
||||||
{
|
{
|
||||||
public struct VTable : COM_IUnknown.VTable
|
public struct VTable : COM_IUnknown.VTable
|
||||||
{
|
{
|
||||||
public function HResult(COM_IPersistFile* self, Guid* pClassID) GetClassID;
|
public function [CallingConvention(.Stdcall)] HResult(COM_IPersistFile* self, Guid* pClassID) GetClassID;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19,11 +19,11 @@ namespace System.IO
|
||||||
|
|
||||||
public struct VTable : COM_IPersist.VTable
|
public struct VTable : COM_IPersist.VTable
|
||||||
{
|
{
|
||||||
public function HResult(COM_IPersistFile* self) IsDirty;
|
public function [CallingConvention(.Stdcall)] HResult(COM_IPersistFile* self) IsDirty;
|
||||||
public function HResult(COM_IPersistFile* self, char16* pszFileName) Load;
|
public function [CallingConvention(.Stdcall)] HResult(COM_IPersistFile* self, char16* pszFileName) Load;
|
||||||
public function HResult(COM_IPersistFile* self, char16* pszFileName, Windows.IntBool remember) Save;
|
public function [CallingConvention(.Stdcall)] HResult(COM_IPersistFile* self, char16* pszFileName, Windows.IntBool remember) Save;
|
||||||
public function HResult(COM_IPersistFile* self, char16* pszFileName) SaveCompleted;
|
public function [CallingConvention(.Stdcall)] HResult(COM_IPersistFile* self, char16* pszFileName) SaveCompleted;
|
||||||
public function HResult(COM_IPersistFile* self, char16* pszName) GetCurFile;
|
public function [CallingConvention(.Stdcall)] HResult(COM_IPersistFile* self, char16* pszName) GetCurFile;
|
||||||
}
|
}
|
||||||
public new VTable* VT
|
public new VTable* VT
|
||||||
{
|
{
|
||||||
|
@ -43,24 +43,24 @@ namespace System.IO
|
||||||
|
|
||||||
public struct VTable : Windows.COM_IUnknown.VTable
|
public struct VTable : Windows.COM_IUnknown.VTable
|
||||||
{
|
{
|
||||||
public function HResult(COM_IShellLink* self, char16* pszFile, int32 cch, Windows.NativeFindData* pfd, uint32 fFlags) GetPath;
|
public function [CallingConvention(.Stdcall)] HResult(COM_IShellLink* self, char16* pszFile, int32 cch, Windows.NativeFindData* pfd, uint32 fFlags) GetPath;
|
||||||
public function HResult(COM_IShellLink* self, IDLIST** ppidl) GetIDList;
|
public function [CallingConvention(.Stdcall)] HResult(COM_IShellLink* self, IDLIST** ppidl) GetIDList;
|
||||||
public function HResult(COM_IShellLink* self, IDLIST* pidl) SetIDList;
|
public function [CallingConvention(.Stdcall)] HResult(COM_IShellLink* self, IDLIST* pidl) SetIDList;
|
||||||
public function HResult(COM_IShellLink* self, char16* pszName, int32 cch) GetDescription;
|
public function [CallingConvention(.Stdcall)] HResult(COM_IShellLink* self, char16* pszName, int32 cch) GetDescription;
|
||||||
public function HResult(COM_IShellLink* self, char16* pszName) SetDescription;
|
public function [CallingConvention(.Stdcall)] HResult(COM_IShellLink* self, char16* pszName) SetDescription;
|
||||||
public function HResult(COM_IShellLink* self, char16* pszDir, int32 cch) GetWorkingDirectory;
|
public function [CallingConvention(.Stdcall)] HResult(COM_IShellLink* self, char16* pszDir, int32 cch) GetWorkingDirectory;
|
||||||
public function HResult(COM_IShellLink* self, char16* pszDir) SetWorkingDirectory;
|
public function [CallingConvention(.Stdcall)] HResult(COM_IShellLink* self, char16* pszDir) SetWorkingDirectory;
|
||||||
public function HResult(COM_IShellLink* self, char16* pszArgs, int32 cch) GetArguments;
|
public function [CallingConvention(.Stdcall)] HResult(COM_IShellLink* self, char16* pszArgs, int32 cch) GetArguments;
|
||||||
public function HResult(COM_IShellLink* self, char16* pszArgs) SetArguments;
|
public function [CallingConvention(.Stdcall)] HResult(COM_IShellLink* self, char16* pszArgs) SetArguments;
|
||||||
public function HResult(COM_IShellLink* self, uint16 *pwHotkey) GetHotkey;
|
public function [CallingConvention(.Stdcall)] HResult(COM_IShellLink* self, uint16 *pwHotkey) GetHotkey;
|
||||||
public function HResult(COM_IShellLink* self, uint16 wHotkey) SetHotkey;
|
public function [CallingConvention(.Stdcall)] HResult(COM_IShellLink* self, uint16 wHotkey) SetHotkey;
|
||||||
public function HResult(COM_IShellLink* self, int32 *piShowCmd) GetShowCmd;
|
public function [CallingConvention(.Stdcall)] HResult(COM_IShellLink* self, int32 *piShowCmd) GetShowCmd;
|
||||||
public function HResult(COM_IShellLink* self, int32 iShowCmd) SetShowCmd;
|
public function [CallingConvention(.Stdcall)] HResult(COM_IShellLink* self, int32 iShowCmd) SetShowCmd;
|
||||||
public function HResult(COM_IShellLink* self, char16* pszIconPath, int32 cch, int32 *piIcon) GetIconLocation;
|
public function [CallingConvention(.Stdcall)] HResult(COM_IShellLink* self, char16* pszIconPath, int32 cch, int32 *piIcon) GetIconLocation;
|
||||||
public function HResult(COM_IShellLink* self, char16* pszIconPath, int32 iIcon) SetIconLocation;
|
public function [CallingConvention(.Stdcall)] HResult(COM_IShellLink* self, char16* pszIconPath, int32 iIcon) SetIconLocation;
|
||||||
public function HResult(COM_IShellLink* self, char16* pszPathRel, uint32 dwReserved) SetRelativePath;
|
public function [CallingConvention(.Stdcall)] HResult(COM_IShellLink* self, char16* pszPathRel, uint32 dwReserved) SetRelativePath;
|
||||||
public function HResult(COM_IShellLink* self, Windows.HWnd hwnd, uint32 fFlags) Resolve;
|
public function [CallingConvention(.Stdcall)] HResult(COM_IShellLink* self, Windows.HWnd hwnd, uint32 fFlags) Resolve;
|
||||||
public function HResult(COM_IShellLink* self, char16* pszFile) SetPath;
|
public function [CallingConvention(.Stdcall)] HResult(COM_IShellLink* self, char16* pszFile) SetPath;
|
||||||
|
|
||||||
}
|
}
|
||||||
public new VTable* VT
|
public new VTable* VT
|
||||||
|
|
|
@ -118,6 +118,9 @@ namespace System
|
||||||
|
|
||||||
public this()
|
public this()
|
||||||
{
|
{
|
||||||
|
if (Compiler.IsComptime)
|
||||||
|
return;
|
||||||
|
|
||||||
#if BF_PLATFORM_WINDOWS
|
#if BF_PLATFORM_WINDOWS
|
||||||
bool isWinSrv()
|
bool isWinSrv()
|
||||||
{
|
{
|
||||||
|
|
|
@ -105,7 +105,8 @@ namespace System.Reflection
|
||||||
argIdx++;
|
argIdx++;
|
||||||
}
|
}
|
||||||
|
|
||||||
methodInfo.Invoke(targetAttr, params args);
|
if (methodInfo.Invoke(targetAttr, params args) case .Ok(var val))
|
||||||
|
val.Dispose();
|
||||||
return .Ok;
|
return .Ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -72,7 +72,7 @@ namespace System
|
||||||
{
|
{
|
||||||
int bufferSize = (count == 0) ? 0 : (count - 1) & ~(sizeof(char8*) - 1);
|
int bufferSize = (count == 0) ? 0 : (count - 1) & ~(sizeof(char8*) - 1);
|
||||||
#unwarn
|
#unwarn
|
||||||
char8* addlPtr = append char8[bufferSize]*;
|
char8* addlPtr = append char8[bufferSize]*(?);
|
||||||
mAllocSizeAndFlags = (uint_strsize)bufferSize + (int_strsize)sizeof(char8*);
|
mAllocSizeAndFlags = (uint_strsize)bufferSize + (int_strsize)sizeof(char8*);
|
||||||
mLength = 0;
|
mLength = 0;
|
||||||
}
|
}
|
||||||
|
@ -82,7 +82,7 @@ namespace System
|
||||||
{
|
{
|
||||||
let bufferSize = 16 - sizeof(char8*);
|
let bufferSize = 16 - sizeof(char8*);
|
||||||
#unwarn
|
#unwarn
|
||||||
char8* addlPtr = append char8[bufferSize]*;
|
char8* addlPtr = append char8[bufferSize]*(?);
|
||||||
mAllocSizeAndFlags = (uint_strsize)bufferSize + (int_strsize)sizeof(char8*);
|
mAllocSizeAndFlags = (uint_strsize)bufferSize + (int_strsize)sizeof(char8*);
|
||||||
mLength = 0;
|
mLength = 0;
|
||||||
}
|
}
|
||||||
|
@ -93,7 +93,7 @@ namespace System
|
||||||
let count = str.mLength;
|
let count = str.mLength;
|
||||||
int bufferSize = (count == 0) ? 0 : (count - 1) & ~(sizeof(char8*) - 1);
|
int bufferSize = (count == 0) ? 0 : (count - 1) & ~(sizeof(char8*) - 1);
|
||||||
#unwarn
|
#unwarn
|
||||||
char8* addlPtr = append char8[bufferSize]*;
|
char8* addlPtr = append char8[bufferSize]*(?);
|
||||||
Internal.MemCpy(Ptr, str.Ptr, count);
|
Internal.MemCpy(Ptr, str.Ptr, count);
|
||||||
mLength = count;
|
mLength = count;
|
||||||
mAllocSizeAndFlags = (uint_strsize)bufferSize + (int_strsize)sizeof(char8*);
|
mAllocSizeAndFlags = (uint_strsize)bufferSize + (int_strsize)sizeof(char8*);
|
||||||
|
@ -106,7 +106,7 @@ namespace System
|
||||||
let count = str.mLength - offset;
|
let count = str.mLength - offset;
|
||||||
int bufferSize = (count == 0) ? 0 : (count - 1) & ~(sizeof(char8*) - 1);
|
int bufferSize = (count == 0) ? 0 : (count - 1) & ~(sizeof(char8*) - 1);
|
||||||
#unwarn
|
#unwarn
|
||||||
char8* addlPtr = append char8[bufferSize]*;
|
char8* addlPtr = append char8[bufferSize]*(?);
|
||||||
let ptr = Ptr;
|
let ptr = Ptr;
|
||||||
let srcPtr = str.Ptr;
|
let srcPtr = str.Ptr;
|
||||||
for (int_strsize i = 0; i < count; i++)
|
for (int_strsize i = 0; i < count; i++)
|
||||||
|
@ -123,7 +123,7 @@ namespace System
|
||||||
|
|
||||||
int bufferSize = (count == 0) ? 0 : (count - 1) & ~(sizeof(char8*) - 1);
|
int bufferSize = (count == 0) ? 0 : (count - 1) & ~(sizeof(char8*) - 1);
|
||||||
#unwarn
|
#unwarn
|
||||||
char8* addlPtr = append char8[bufferSize]*;
|
char8* addlPtr = append char8[bufferSize]*(?);
|
||||||
let ptr = Ptr;
|
let ptr = Ptr;
|
||||||
let srcPtr = str.Ptr;
|
let srcPtr = str.Ptr;
|
||||||
for (int i = 0; i < count; i++)
|
for (int i = 0; i < count; i++)
|
||||||
|
@ -137,7 +137,7 @@ namespace System
|
||||||
{
|
{
|
||||||
int bufferSize = (count == 0) ? 0 : (count - 1) & ~(sizeof(char8*) - 1);
|
int bufferSize = (count == 0) ? 0 : (count - 1) & ~(sizeof(char8*) - 1);
|
||||||
#unwarn
|
#unwarn
|
||||||
char8* addlPtr = append char8[bufferSize]*;
|
char8* addlPtr = append char8[bufferSize]*(?);
|
||||||
let ptr = Ptr;
|
let ptr = Ptr;
|
||||||
for (int_strsize i = 0; i < count; i++)
|
for (int_strsize i = 0; i < count; i++)
|
||||||
ptr[i] = c;
|
ptr[i] = c;
|
||||||
|
@ -151,7 +151,7 @@ namespace System
|
||||||
let count = Internal.CStrLen(char8Ptr);
|
let count = Internal.CStrLen(char8Ptr);
|
||||||
int bufferSize = (count == 0) ? 0 : (count - 1) & ~(sizeof(char8*) - 1);
|
int bufferSize = (count == 0) ? 0 : (count - 1) & ~(sizeof(char8*) - 1);
|
||||||
#unwarn
|
#unwarn
|
||||||
char8* addlPtr = append char8[bufferSize]*;
|
char8* addlPtr = append char8[bufferSize]*(?);
|
||||||
let ptr = Ptr;
|
let ptr = Ptr;
|
||||||
for (int_strsize i = 0; i < count; i++)
|
for (int_strsize i = 0; i < count; i++)
|
||||||
ptr[i] = char8Ptr[i];
|
ptr[i] = char8Ptr[i];
|
||||||
|
@ -164,7 +164,7 @@ namespace System
|
||||||
{
|
{
|
||||||
int bufferSize = (count == 0) ? 0 : (count - 1) & ~(sizeof(char8*) - 1);
|
int bufferSize = (count == 0) ? 0 : (count - 1) & ~(sizeof(char8*) - 1);
|
||||||
#unwarn
|
#unwarn
|
||||||
char8* addlPtr = append char8[bufferSize]*;
|
char8* addlPtr = append char8[bufferSize]*(?);
|
||||||
let ptr = Ptr;
|
let ptr = Ptr;
|
||||||
for (int i = 0; i < count; i++)
|
for (int i = 0; i < count; i++)
|
||||||
ptr[i] = char8Ptr[i];
|
ptr[i] = char8Ptr[i];
|
||||||
|
@ -178,7 +178,7 @@ namespace System
|
||||||
let count = UTF16.GetLengthAsUTF8(char16Ptr);
|
let count = UTF16.GetLengthAsUTF8(char16Ptr);
|
||||||
int bufferSize = (count == 0) ? 0 : (count - 1) & ~(sizeof(char8*) - 1);
|
int bufferSize = (count == 0) ? 0 : (count - 1) & ~(sizeof(char8*) - 1);
|
||||||
#unwarn
|
#unwarn
|
||||||
char8* addlPtr = append char8[bufferSize]*;
|
char8* addlPtr = append char8[bufferSize]*(?);
|
||||||
mAllocSizeAndFlags = (uint_strsize)bufferSize + (int_strsize)sizeof(char8*);
|
mAllocSizeAndFlags = (uint_strsize)bufferSize + (int_strsize)sizeof(char8*);
|
||||||
mLength = 0;
|
mLength = 0;
|
||||||
UTF16.Decode(char16Ptr, this);
|
UTF16.Decode(char16Ptr, this);
|
||||||
|
@ -190,7 +190,7 @@ namespace System
|
||||||
let count = UTF16.GetLengthAsUTF8(chars);
|
let count = UTF16.GetLengthAsUTF8(chars);
|
||||||
int bufferSize = (count == 0) ? 0 : (count - 1) & ~(sizeof(char8*) - 1);
|
int bufferSize = (count == 0) ? 0 : (count - 1) & ~(sizeof(char8*) - 1);
|
||||||
#unwarn
|
#unwarn
|
||||||
char8* addlPtr = append char8[bufferSize]*;
|
char8* addlPtr = append char8[bufferSize]*(?);
|
||||||
mAllocSizeAndFlags = (uint_strsize)bufferSize + (int_strsize)sizeof(char8*);
|
mAllocSizeAndFlags = (uint_strsize)bufferSize + (int_strsize)sizeof(char8*);
|
||||||
mLength = 0;
|
mLength = 0;
|
||||||
UTF16.Decode(chars, this);
|
UTF16.Decode(chars, this);
|
||||||
|
@ -202,7 +202,7 @@ namespace System
|
||||||
let tryBufferSize = strView.Length - sizeof(char8*);
|
let tryBufferSize = strView.Length - sizeof(char8*);
|
||||||
let bufferSize = (tryBufferSize >= 0) ? tryBufferSize : 0;
|
let bufferSize = (tryBufferSize >= 0) ? tryBufferSize : 0;
|
||||||
#unwarn
|
#unwarn
|
||||||
char8* addlPtr = append char8[bufferSize]*;
|
char8* addlPtr = append char8[bufferSize]*(?);
|
||||||
let ptr = Ptr;
|
let ptr = Ptr;
|
||||||
Internal.MemCpy(ptr, strView.Ptr, strView.Length);
|
Internal.MemCpy(ptr, strView.Ptr, strView.Length);
|
||||||
mAllocSizeAndFlags = (uint_strsize)bufferSize + (int_strsize)sizeof(char8*);
|
mAllocSizeAndFlags = (uint_strsize)bufferSize + (int_strsize)sizeof(char8*);
|
||||||
|
@ -215,7 +215,7 @@ namespace System
|
||||||
let count = strView.Length + (flags.HasFlag(.NullTerminate) ? 1 : 0);
|
let count = strView.Length + (flags.HasFlag(.NullTerminate) ? 1 : 0);
|
||||||
int bufferSize = (count == 0) ? 0 : (count - 1) & ~(sizeof(char8*) - 1);
|
int bufferSize = (count == 0) ? 0 : (count - 1) & ~(sizeof(char8*) - 1);
|
||||||
#unwarn
|
#unwarn
|
||||||
char8* addlPtr = append char8[bufferSize]*;
|
char8* addlPtr = append char8[bufferSize]*(?);
|
||||||
let ptr = Ptr;
|
let ptr = Ptr;
|
||||||
Internal.MemCpy(ptr, strView.Ptr, strView.Length);
|
Internal.MemCpy(ptr, strView.Ptr, strView.Length);
|
||||||
if (flags.HasFlag(.NullTerminate))
|
if (flags.HasFlag(.NullTerminate))
|
||||||
|
@ -232,7 +232,7 @@ namespace System
|
||||||
let count = strView.Length - offset;
|
let count = strView.Length - offset;
|
||||||
int bufferSize = (count == 0) ? 0 : (count - 1) & ~(sizeof(char8*) - 1);
|
int bufferSize = (count == 0) ? 0 : (count - 1) & ~(sizeof(char8*) - 1);
|
||||||
#unwarn
|
#unwarn
|
||||||
char8* addlPtr = append char8[bufferSize]*;
|
char8* addlPtr = append char8[bufferSize]*(?);
|
||||||
let ptr = Ptr;
|
let ptr = Ptr;
|
||||||
let srcPtr = strView.Ptr;
|
let srcPtr = strView.Ptr;
|
||||||
for (int i = 0; i < count; i++)
|
for (int i = 0; i < count; i++)
|
||||||
|
@ -249,7 +249,7 @@ namespace System
|
||||||
|
|
||||||
int bufferSize = (count == 0) ? 0 : (count - 1) & ~(sizeof(char8*) - 1);
|
int bufferSize = (count == 0) ? 0 : (count - 1) & ~(sizeof(char8*) - 1);
|
||||||
#unwarn
|
#unwarn
|
||||||
char8* addlPtr = append char8[bufferSize]*;
|
char8* addlPtr = append char8[bufferSize]*(?);
|
||||||
let ptr = Ptr;
|
let ptr = Ptr;
|
||||||
let srcPtr = strView.Ptr;
|
let srcPtr = strView.Ptr;
|
||||||
for (int i = 0; i < count; i++)
|
for (int i = 0; i < count; i++)
|
||||||
|
@ -263,7 +263,7 @@ namespace System
|
||||||
{
|
{
|
||||||
int bufferSize = (count == 0) ? 0 : (count - 1) & ~(sizeof(char8*) - 1);
|
int bufferSize = (count == 0) ? 0 : (count - 1) & ~(sizeof(char8*) - 1);
|
||||||
#unwarn
|
#unwarn
|
||||||
char8* addlPtr = append char8[bufferSize]*;
|
char8* addlPtr = append char8[bufferSize]*(?);
|
||||||
let ptr = Ptr;
|
let ptr = Ptr;
|
||||||
for (int i = 0; i < count; i++)
|
for (int i = 0; i < count; i++)
|
||||||
ptr[i] = chars[i + offset];
|
ptr[i] = chars[i + offset];
|
||||||
|
@ -285,7 +285,7 @@ namespace System
|
||||||
int count = StrLengths(strs);
|
int count = StrLengths(strs);
|
||||||
int bufferSize = (count == 0) ? 0 : (count - 1) & ~(sizeof(char8*) - 1);
|
int bufferSize = (count == 0) ? 0 : (count - 1) & ~(sizeof(char8*) - 1);
|
||||||
#unwarn
|
#unwarn
|
||||||
char8* addlPtr = append char8[bufferSize]*;
|
char8* addlPtr = append char8[bufferSize]*(?);
|
||||||
let ptr = Ptr;
|
let ptr = Ptr;
|
||||||
int curIdx = 0;
|
int curIdx = 0;
|
||||||
for (var str in strs)
|
for (var str in strs)
|
||||||
|
@ -1966,6 +1966,22 @@ namespace System
|
||||||
return EqualsHelper(a.Ptr, b.Ptr, a.mLength);
|
return EqualsHelper(a.Ptr, b.Ptr, a.mLength);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool Equals(StringView str)
|
||||||
|
{
|
||||||
|
if (mLength != str.[Friend]mLength)
|
||||||
|
return false;
|
||||||
|
return EqualsHelper(str.Ptr, mPtr, mLength);
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool Equals(StringView str, StringComparison comparisonType = StringComparison.Ordinal)
|
||||||
|
{
|
||||||
|
if (mLength != str.[Friend]mLength)
|
||||||
|
return false;
|
||||||
|
if (comparisonType == StringComparison.OrdinalIgnoreCase)
|
||||||
|
return EqualsIgnoreCaseHelper(str.Ptr, mPtr, mLength);
|
||||||
|
return EqualsHelper(str.Ptr, mPtr, mLength);
|
||||||
|
}
|
||||||
|
|
||||||
public bool StartsWith(StringView b, StringComparison comparisonType = StringComparison.Ordinal)
|
public bool StartsWith(StringView b, StringComparison comparisonType = StringComparison.Ordinal)
|
||||||
{
|
{
|
||||||
if (mLength < b.[Friend]mLength)
|
if (mLength < b.[Friend]mLength)
|
||||||
|
@ -2279,6 +2295,36 @@ namespace System
|
||||||
TrimEnd((.)trimChar);
|
TrimEnd((.)trimChar);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void PadLeft(int totalWidth, char8 paddingChar)
|
||||||
|
{
|
||||||
|
Insert(0, paddingChar, totalWidth - Length);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void PadLeft(int totalWidth, char32 paddingChar)
|
||||||
|
{
|
||||||
|
Insert(0, paddingChar, totalWidth - Length);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void PadLeft(int totalWidth)
|
||||||
|
{
|
||||||
|
Insert(0, ' ', totalWidth - Length);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void PadRight(int totalWidth, char8 paddingChar)
|
||||||
|
{
|
||||||
|
Append(paddingChar, totalWidth - Length);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void PadRight(int totalWidth, char32 paddingChar)
|
||||||
|
{
|
||||||
|
Append(paddingChar, totalWidth - Length);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void PadRight(int totalWidth)
|
||||||
|
{
|
||||||
|
Append(' ', totalWidth - Length);
|
||||||
|
}
|
||||||
|
|
||||||
public void Join(StringView sep, IEnumerator<String> enumerable)
|
public void Join(StringView sep, IEnumerator<String> enumerable)
|
||||||
{
|
{
|
||||||
bool isFirst = true;
|
bool isFirst = true;
|
||||||
|
|
|
@ -1250,7 +1250,8 @@ namespace System.Reflection
|
||||||
Const = 0x0040, // Value is compile time constant.
|
Const = 0x0040, // Value is compile time constant.
|
||||||
SpecialName = 0x0080, // field is special. Name describes how.
|
SpecialName = 0x0080, // field is special. Name describes how.
|
||||||
EnumPayload = 0x0100,
|
EnumPayload = 0x0100,
|
||||||
EnumDiscriminator = 0x0200
|
EnumDiscriminator = 0x0200,
|
||||||
|
EnumCase = 0x0400
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum MethodFlags : uint16
|
public enum MethodFlags : uint16
|
||||||
|
|
|
@ -2,7 +2,7 @@ using System.Diagnostics;
|
||||||
|
|
||||||
namespace System
|
namespace System
|
||||||
{
|
{
|
||||||
struct Variant
|
struct Variant : IDisposable
|
||||||
{
|
{
|
||||||
enum ObjectType
|
enum ObjectType
|
||||||
{
|
{
|
||||||
|
|
|
@ -47,9 +47,9 @@ namespace System
|
||||||
|
|
||||||
public struct VTable
|
public struct VTable
|
||||||
{
|
{
|
||||||
public function HResult(COM_IUnknown* self, ref Guid riid, void** result) QueryInterface;
|
public function [CallingConvention(.Stdcall)] HResult(COM_IUnknown* self, ref Guid riid, void** result) QueryInterface;
|
||||||
public function uint32(COM_IUnknown* self) AddRef;
|
public function [CallingConvention(.Stdcall)] uint32(COM_IUnknown* self) AddRef;
|
||||||
public function uint32(COM_IUnknown* self) Release;
|
public function [CallingConvention(.Stdcall)] uint32(COM_IUnknown* self) Release;
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum HResult : int32
|
public enum HResult : int32
|
||||||
|
@ -1124,14 +1124,13 @@ namespace System
|
||||||
|
|
||||||
public struct VTable : Windows.COM_IUnknown.VTable
|
public struct VTable : Windows.COM_IUnknown.VTable
|
||||||
{
|
{
|
||||||
public function HResult(COM_IFileDialogEvents* self, COM_IFileDialog* fileDialog) OnFileOk;
|
public function [CallingConvention(.Stdcall)] HResult(COM_IFileDialogEvents* self, COM_IFileDialog* fileDialog) OnFileOk;
|
||||||
public function HResult(COM_IFileDialogEvents* self, COM_IFileDialog* fileDialog, COM_IShellItem* psiFolder) OnFolderChanging;
|
public function [CallingConvention(.Stdcall)] HResult(COM_IFileDialogEvents* self, COM_IFileDialog* fileDialog, COM_IShellItem* psiFolder) OnFolderChanging;
|
||||||
public function HResult(COM_IFileDialogEvents* self, COM_IFileDialog* fileDialog) OnFolderChange;
|
public function [CallingConvention(.Stdcall)] HResult(COM_IFileDialogEvents* self, COM_IFileDialog* fileDialog) OnFolderChange;
|
||||||
public function HResult(COM_IFileDialogEvents* self, COM_IFileDialog* fileDialog) OnSelectionChange;
|
public function [CallingConvention(.Stdcall)] HResult(COM_IFileDialogEvents* self, COM_IFileDialog* fileDialog) OnSelectionChange;
|
||||||
public function HResult(COM_IFileDialogEvents* self, COM_IFileDialog* fileDialog, FDE_SHAREVIOLATION_RESPONSE* pResponse) OnShareViolation;
|
public function [CallingConvention(.Stdcall)] HResult(COM_IFileDialogEvents* self, COM_IFileDialog* fileDialog, FDE_SHAREVIOLATION_RESPONSE* pResponse) OnShareViolation;
|
||||||
public function HResult(COM_IFileDialogEvents* self, COM_IFileDialog* fileDialog) OnTypeChange;
|
public function [CallingConvention(.Stdcall)] HResult(COM_IFileDialogEvents* self, COM_IFileDialog* fileDialog) OnTypeChange;
|
||||||
public function HResult(COM_IFileDialogEvents* self, COM_IFileDialog* fileDialog, COM_IShellItem* shellItem, FDE_OVERWRITE_RESPONSE* response) OnOverwrite;
|
public function [CallingConvention(.Stdcall)] HResult(COM_IFileDialogEvents* self, COM_IFileDialog* fileDialog, COM_IShellItem* shellItem, FDE_OVERWRITE_RESPONSE* response) OnOverwrite;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1154,12 +1153,11 @@ namespace System
|
||||||
|
|
||||||
public struct VTable : Windows.COM_IUnknown.VTable
|
public struct VTable : Windows.COM_IUnknown.VTable
|
||||||
{
|
{
|
||||||
public function HResult(COM_IShellItem* self, void* pbc, ref Guid bhid, ref Guid riid, void** ppv) BindToHandler;
|
public function [CallingConvention(.Stdcall)] HResult(COM_IShellItem* self, void* pbc, ref Guid bhid, ref Guid riid, void** ppv) BindToHandler;
|
||||||
public function HResult(COM_IShellItem* self, out COM_IShellItem* ppsi) GetParent;
|
public function [CallingConvention(.Stdcall)] HResult(COM_IShellItem* self, out COM_IShellItem* ppsi) GetParent;
|
||||||
public function HResult(COM_IShellItem* self, SIGDN sigdnName, out char16* ppszName) GetDisplayName;
|
public function [CallingConvention(.Stdcall)] HResult(COM_IShellItem* self, SIGDN sigdnName, out char16* ppszName) GetDisplayName;
|
||||||
public function HResult(COM_IShellItem* self, uint sfgaoMask, out uint psfgaoAttribs) GetAttributes;
|
public function [CallingConvention(.Stdcall)] HResult(COM_IShellItem* self, uint sfgaoMask, out uint psfgaoAttribs) GetAttributes;
|
||||||
public function HResult(COM_IShellItem* self, COM_IShellItem* psi, uint32 hint, out int32 piOrder) Compare;
|
public function [CallingConvention(.Stdcall)] HResult(COM_IShellItem* self, COM_IShellItem* psi, uint32 hint, out int32 piOrder) Compare;
|
||||||
|
|
||||||
}
|
}
|
||||||
public new VTable* VT
|
public new VTable* VT
|
||||||
{
|
{
|
||||||
|
@ -1207,13 +1205,13 @@ namespace System
|
||||||
|
|
||||||
public struct VTable : Windows.COM_IUnknown.VTable
|
public struct VTable : Windows.COM_IUnknown.VTable
|
||||||
{
|
{
|
||||||
public function HResult(COM_IShellItemArray* self, void* pbc, ref Guid rbhid, ref Guid riid, out void* ppvOut) BindToHandler;
|
public function [CallingConvention(.Stdcall)] HResult(COM_IShellItemArray* self, void* pbc, ref Guid rbhid, ref Guid riid, out void* ppvOut) BindToHandler;
|
||||||
public function HResult(COM_IShellItemArray* self, GETPROPERTYSTOREFLAGS flags, ref Guid riid, out void* ppv) GetPropertyStore;
|
public function [CallingConvention(.Stdcall)] HResult(COM_IShellItemArray* self, GETPROPERTYSTOREFLAGS flags, ref Guid riid, out void* ppv) GetPropertyStore;
|
||||||
public function HResult(COM_IShellItemArray* self, ref PROPERTYKEY keyType, ref Guid riid, out void* ppv) GetPropertyDescriptionList;
|
public function [CallingConvention(.Stdcall)] HResult(COM_IShellItemArray* self, ref PROPERTYKEY keyType, ref Guid riid, out void* ppv) GetPropertyDescriptionList;
|
||||||
public function HResult(COM_IShellItemArray* self, SIATTRIBFLAGS dwAttribFlags, uint32 sfgaoMask, out uint32 psfgaoAttribs) GetAttributes;
|
public function [CallingConvention(.Stdcall)] HResult(COM_IShellItemArray* self, SIATTRIBFLAGS dwAttribFlags, uint32 sfgaoMask, out uint32 psfgaoAttribs) GetAttributes;
|
||||||
public function HResult(COM_IShellItemArray* self, out uint32 pdwNumItems) GetCount;
|
public function [CallingConvention(.Stdcall)] HResult(COM_IShellItemArray* self, out uint32 pdwNumItems) GetCount;
|
||||||
public function HResult(COM_IShellItemArray* self, uint32 dwIndex, out COM_IShellItem* ppsi) GetItemAt;
|
public function [CallingConvention(.Stdcall)] HResult(COM_IShellItemArray* self, uint32 dwIndex, out COM_IShellItem* ppsi) GetItemAt;
|
||||||
public function HResult(COM_IShellItemArray* self, out void* ppenumShellItems) EnumItems;
|
public function [CallingConvention(.Stdcall)] HResult(COM_IShellItemArray* self, out void* ppenumShellItems) EnumItems;
|
||||||
}
|
}
|
||||||
public new VTable* VT
|
public new VTable* VT
|
||||||
{
|
{
|
||||||
|
@ -1268,30 +1266,30 @@ namespace System
|
||||||
|
|
||||||
public struct VTable : Windows.COM_IUnknown.VTable
|
public struct VTable : Windows.COM_IUnknown.VTable
|
||||||
{
|
{
|
||||||
public function HResult(COM_IFileDialog* self, Windows.HWnd parent) Show;
|
public function [CallingConvention(.Stdcall)] HResult(COM_IFileDialog* self, Windows.HWnd parent) Show;
|
||||||
public function HResult(COM_IFileDialog* self, uint cFileTypes, COMDLG_FILTERSPEC* rgFilterSpec) SetFileTypes;
|
public function [CallingConvention(.Stdcall)] HResult(COM_IFileDialog* self, uint cFileTypes, COMDLG_FILTERSPEC* rgFilterSpec) SetFileTypes;
|
||||||
public function HResult(COM_IFileDialog* self, uint iFileType) SetFileTypeIndex;
|
public function [CallingConvention(.Stdcall)] HResult(COM_IFileDialog* self, uint iFileType) SetFileTypeIndex;
|
||||||
public function HResult(COM_IFileDialog* self, out uint piFileType) GetFileTypeIndex;
|
public function [CallingConvention(.Stdcall)] HResult(COM_IFileDialog* self, out uint piFileType) GetFileTypeIndex;
|
||||||
public function HResult(COM_IFileDialog* self, COM_IFileDialogEvents* pfde, out uint pdwCookie) Advise;
|
public function [CallingConvention(.Stdcall)] HResult(COM_IFileDialog* self, COM_IFileDialogEvents* pfde, out uint pdwCookie) Advise;
|
||||||
public function HResult(COM_IFileDialog* self, uint dwCookie) Unadvise;
|
public function [CallingConvention(.Stdcall)] HResult(COM_IFileDialog* self, uint dwCookie) Unadvise;
|
||||||
public function HResult(COM_IFileDialog* self, FOS fos) SetOptions;
|
public function [CallingConvention(.Stdcall)] HResult(COM_IFileDialog* self, FOS fos) SetOptions;
|
||||||
public function HResult(COM_IFileDialog* self, out FOS pfos) GetOptions;
|
public function [CallingConvention(.Stdcall)] HResult(COM_IFileDialog* self, out FOS pfos) GetOptions;
|
||||||
public function HResult(COM_IFileDialog* self, COM_IShellItem* psi) SetDefaultFolder;
|
public function [CallingConvention(.Stdcall)] HResult(COM_IFileDialog* self, COM_IShellItem* psi) SetDefaultFolder;
|
||||||
public function HResult(COM_IFileDialog* self, COM_IShellItem* psi) SetFolder;
|
public function [CallingConvention(.Stdcall)] HResult(COM_IFileDialog* self, COM_IShellItem* psi) SetFolder;
|
||||||
public function HResult(COM_IFileDialog* self, out COM_IShellItem* ppsi) GetFolder;
|
public function [CallingConvention(.Stdcall)] HResult(COM_IFileDialog* self, out COM_IShellItem* ppsi) GetFolder;
|
||||||
public function HResult(COM_IFileDialog* self, out COM_IShellItem* ppsi) GetCurrentSelection;
|
public function [CallingConvention(.Stdcall)] HResult(COM_IFileDialog* self, out COM_IShellItem* ppsi) GetCurrentSelection;
|
||||||
public function HResult(COM_IFileDialog* self, char16* pszName) SetFileName;
|
public function [CallingConvention(.Stdcall)] HResult(COM_IFileDialog* self, char16* pszName) SetFileName;
|
||||||
public function HResult(COM_IFileDialog* self, out char16* pszName) GetFileName;
|
public function [CallingConvention(.Stdcall)] HResult(COM_IFileDialog* self, out char16* pszName) GetFileName;
|
||||||
public function HResult(COM_IFileDialog* self, char16* pszTitle) SetTitle;
|
public function [CallingConvention(.Stdcall)] HResult(COM_IFileDialog* self, char16* pszTitle) SetTitle;
|
||||||
public function HResult(COM_IFileDialog* self, char16* pszText) SetOkButtonLabel;
|
public function [CallingConvention(.Stdcall)] HResult(COM_IFileDialog* self, char16* pszText) SetOkButtonLabel;
|
||||||
public function HResult(COM_IFileDialog* self, char16* pszLabel) SetFileNameLabel;
|
public function [CallingConvention(.Stdcall)] HResult(COM_IFileDialog* self, char16* pszLabel) SetFileNameLabel;
|
||||||
public function HResult(COM_IFileDialog* self, out COM_IShellItem* ppsi) GetResult;
|
public function [CallingConvention(.Stdcall)] HResult(COM_IFileDialog* self, out COM_IShellItem* ppsi) GetResult;
|
||||||
public function HResult(COM_IFileDialog* self, COM_IShellItem* psi, FDAP fdap) AddPlace;
|
public function [CallingConvention(.Stdcall)] HResult(COM_IFileDialog* self, COM_IShellItem* psi, FDAP fdap) AddPlace;
|
||||||
public function HResult(COM_IFileDialog* self, char16* pszDefaultExtension) SetDefaultExtension;
|
public function [CallingConvention(.Stdcall)] HResult(COM_IFileDialog* self, char16* pszDefaultExtension) SetDefaultExtension;
|
||||||
public function HResult(COM_IFileDialog* self, int hr) Close;
|
public function [CallingConvention(.Stdcall)] HResult(COM_IFileDialog* self, int hr) Close;
|
||||||
public function HResult(COM_IFileDialog* self, ref Guid guid) SetClientGuid;
|
public function [CallingConvention(.Stdcall)] HResult(COM_IFileDialog* self, ref Guid guid) SetClientGuid;
|
||||||
public function HResult(COM_IFileDialog* self) ClearClientData;
|
public function [CallingConvention(.Stdcall)] HResult(COM_IFileDialog* self) ClearClientData;
|
||||||
public function HResult(COM_IFileDialog* self, void* pFilter) SetFilter;
|
public function [CallingConvention(.Stdcall)] HResult(COM_IFileDialog* self, void* pFilter) SetFilter;
|
||||||
}
|
}
|
||||||
public new VTable* VT
|
public new VTable* VT
|
||||||
{
|
{
|
||||||
|
@ -1314,8 +1312,8 @@ namespace System
|
||||||
|
|
||||||
public struct VTable : COM_IFileDialog.VTable
|
public struct VTable : COM_IFileDialog.VTable
|
||||||
{
|
{
|
||||||
public function HResult(COM_IFileOpenDialog* self, out COM_IShellItemArray* ppenum) GetResults;
|
public function [CallingConvention(.Stdcall)] HResult(COM_IFileOpenDialog* self, out COM_IShellItemArray* ppenum) GetResults;
|
||||||
public function HResult(COM_IFileOpenDialog* self, out COM_IShellItemArray* ppsai) GetSelectedItems;
|
public function [CallingConvention(.Stdcall)] HResult(COM_IFileOpenDialog* self, out COM_IShellItemArray* ppsai) GetSelectedItems;
|
||||||
}
|
}
|
||||||
public new VTable* VT
|
public new VTable* VT
|
||||||
{
|
{
|
||||||
|
|
|
@ -505,7 +505,7 @@ namespace BeefPerf
|
||||||
subMenu = root.AddMenuItem("&Debug");
|
subMenu = root.AddMenuItem("&Debug");
|
||||||
subMenu.AddMenuItem("GC Collect", null, new (menu) =>
|
subMenu.AddMenuItem("GC Collect", null, new (menu) =>
|
||||||
{
|
{
|
||||||
if (Profiler.StartSampling() case .Ok(let id))
|
if (Profiler.StartSampling() case .Ok(var id))
|
||||||
{
|
{
|
||||||
GC.Collect();
|
GC.Collect();
|
||||||
id.Dispose();
|
id.Dispose();
|
||||||
|
|
|
@ -2909,6 +2909,12 @@ BFP_EXPORT intptr BFP_CALLTYPE BfpFile_Read(BfpFile* file, void* buffer, intptr
|
||||||
//TODO: this doesn't set file stream location. It only works for streams like pipes, sockets, etc
|
//TODO: this doesn't set file stream location. It only works for streams like pipes, sockets, etc
|
||||||
if (::ReadFileEx(file->mHandle, buffer, (uint32)size, &overlapped, OverlappedReadComplete))
|
if (::ReadFileEx(file->mHandle, buffer, (uint32)size, &overlapped, OverlappedReadComplete))
|
||||||
{
|
{
|
||||||
|
if (file->mAsyncData == NULL)
|
||||||
|
{
|
||||||
|
OUTRESULT(BfpFileResult_InvalidParameter);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (!file->mAsyncData->WaitAndResetEvent(timeoutMS))
|
if (!file->mAsyncData->WaitAndResetEvent(timeoutMS))
|
||||||
{
|
{
|
||||||
::CancelIoEx(file->mHandle, &overlapped);
|
::CancelIoEx(file->mHandle, &overlapped);
|
||||||
|
|
|
@ -624,6 +624,16 @@ public:
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static StringImpl MakeRef(const char* charPtr, intptr length)
|
||||||
|
{
|
||||||
|
StringImpl str;
|
||||||
|
// This is just a ref - called when we pass a literal to a method (for example)
|
||||||
|
str.mPtr = (char*)charPtr;
|
||||||
|
str.mLength = (int_strsize)length;
|
||||||
|
str.mAllocSizeAndFlags = str.mLength | StrPtrFlag;
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
static StringImpl MakeRef(const StringView& strView)
|
static StringImpl MakeRef(const StringView& strView)
|
||||||
{
|
{
|
||||||
StringImpl str;
|
StringImpl str;
|
||||||
|
|
|
@ -121,10 +121,21 @@ namespace IDE
|
||||||
class CommandMap : IDECommandBase
|
class CommandMap : IDECommandBase
|
||||||
{
|
{
|
||||||
public Dictionary<KeyState, IDECommandBase> mMap = new .() ~ delete _;
|
public Dictionary<KeyState, IDECommandBase> mMap = new .() ~ delete _;
|
||||||
|
public List<IDECommandBase> mFailValues ~ delete _;
|
||||||
|
|
||||||
|
public List<IDECommandBase> FailValues
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (mFailValues == null)
|
||||||
|
mFailValues = new .();
|
||||||
|
return mFailValues;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void Clear()
|
public void Clear()
|
||||||
{
|
{
|
||||||
for (let val in mMap.Values)
|
void Release(IDECommandBase val)
|
||||||
{
|
{
|
||||||
if (var cmdMap = val as CommandMap)
|
if (var cmdMap = val as CommandMap)
|
||||||
delete cmdMap;
|
delete cmdMap;
|
||||||
|
@ -136,6 +147,15 @@ namespace IDE
|
||||||
ideCommand.mNext = null;
|
ideCommand.mNext = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (let val in mMap.Values)
|
||||||
|
Release(val);
|
||||||
|
if (mFailValues != null)
|
||||||
|
{
|
||||||
|
for (var val in mFailValues)
|
||||||
|
Release(val);
|
||||||
|
mFailValues.Clear();
|
||||||
|
}
|
||||||
mMap.Clear();
|
mMap.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -194,7 +214,9 @@ namespace IDE
|
||||||
Add("Close Document", new () => { gApp.[Friend]TryCloseCurrentDocument(); });
|
Add("Close Document", new () => { gApp.[Friend]TryCloseCurrentDocument(); });
|
||||||
Add("Close Panel", new () => { gApp.[Friend]TryCloseCurrentPanel(); });
|
Add("Close Panel", new () => { gApp.[Friend]TryCloseCurrentPanel(); });
|
||||||
Add("Close Workspace", new => gApp.[Friend]Cmd_CloseWorkspaceAndSetupNew);
|
Add("Close Workspace", new => gApp.[Friend]Cmd_CloseWorkspaceAndSetupNew);
|
||||||
Add("Comment Selection", new => gApp.[Friend]CommentSelection);
|
Add("Comment Block", new => gApp.[Friend]CommentBlock, .Editor);
|
||||||
|
Add("Comment Lines", new => gApp.[Friend]CommentLines, .Editor);
|
||||||
|
Add("Comment Toggle", new => gApp.[Friend]CommentToggle, .Editor);
|
||||||
Add("Compile File", new => gApp.Cmd_CompileFile);
|
Add("Compile File", new => gApp.Cmd_CompileFile);
|
||||||
Add("Debug All Tests", new () => { gApp.[Friend]RunTests(true, true); });
|
Add("Debug All Tests", new () => { gApp.[Friend]RunTests(true, true); });
|
||||||
Add("Debug Normal Tests", new () => { gApp.[Friend]RunTests(false, true); });
|
Add("Debug Normal Tests", new () => { gApp.[Friend]RunTests(false, true); });
|
||||||
|
@ -251,6 +273,7 @@ namespace IDE
|
||||||
Add("Run Normal Tests", new () => { gApp.[Friend]RunTests(false, false); });
|
Add("Run Normal Tests", new () => { gApp.[Friend]RunTests(false, false); });
|
||||||
Add("Run To Cursor", new => gApp.[Friend]RunToCursor);
|
Add("Run To Cursor", new => gApp.[Friend]RunToCursor);
|
||||||
Add("Run Without Compiling", new => gApp.[Friend]RunWithoutCompiling);
|
Add("Run Without Compiling", new => gApp.[Friend]RunWithoutCompiling);
|
||||||
|
Add("Safe Mode Toggle", new () => { gApp.SafeModeToggle(); });
|
||||||
Add("Save All", new () => { gApp.SaveAll(); });
|
Add("Save All", new () => { gApp.SaveAll(); });
|
||||||
Add("Save As", new () => { gApp.SaveAs(); });
|
Add("Save As", new () => { gApp.SaveAs(); });
|
||||||
Add("Save File", new => gApp.SaveFile);
|
Add("Save File", new => gApp.SaveFile);
|
||||||
|
|
|
@ -76,6 +76,9 @@ namespace IDE.Compiler
|
||||||
[CallingConvention(.Stdcall), CLink]
|
[CallingConvention(.Stdcall), CLink]
|
||||||
static extern int32 BfCompiler_GetCurConstEvalExecuteId(void* bfCompiler);
|
static extern int32 BfCompiler_GetCurConstEvalExecuteId(void* bfCompiler);
|
||||||
|
|
||||||
|
[CallingConvention(.Stdcall), CLink]
|
||||||
|
static extern bool BfCompiler_GetLastHadComptimeRebuilds(void* bfCompiler);
|
||||||
|
|
||||||
[CallingConvention(.Stdcall), CLink]
|
[CallingConvention(.Stdcall), CLink]
|
||||||
static extern void BfCompiler_Delete(void* bfCompiler);
|
static extern void BfCompiler_Delete(void* bfCompiler);
|
||||||
|
|
||||||
|
@ -834,5 +837,10 @@ namespace IDE.Compiler
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool GetLastHadComptimeRebuilds()
|
||||||
|
{
|
||||||
|
return BfCompiler_GetLastHadComptimeRebuilds(mNativeBfCompiler);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -78,8 +78,9 @@ namespace IDE.Compiler
|
||||||
public bool mCancelled;
|
public bool mCancelled;
|
||||||
public int32 mTextVersion = -1;
|
public int32 mTextVersion = -1;
|
||||||
public bool mIsUserRequested;
|
public bool mIsUserRequested;
|
||||||
|
|
||||||
public bool mDoFuzzyAutoComplete;
|
public bool mDoFuzzyAutoComplete;
|
||||||
|
public Stopwatch mStopwatch ~ delete _;
|
||||||
|
public ProfileInstance mProfileInstance ~ _.Dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
public class BfParser : ILeakIdentifiable
|
public class BfParser : ILeakIdentifiable
|
||||||
|
@ -122,7 +123,7 @@ namespace IDE.Compiler
|
||||||
static extern bool BfParser_Reduce(void* bfParser, void* bfPassInstance);
|
static extern bool BfParser_Reduce(void* bfParser, void* bfPassInstance);
|
||||||
|
|
||||||
[CallingConvention(.Stdcall), CLink]
|
[CallingConvention(.Stdcall), CLink]
|
||||||
static extern char8* BfParser_Format(void* bfParser, int32 formatEnd, int32 formatStart, out int32* outCharMapping);
|
static extern char8* BfParser_Format(void* bfParser, int32 formatEnd, int32 formatStart, out int32* outCharMapping, int32 maxCol);
|
||||||
|
|
||||||
[CallingConvention(.Stdcall), CLink]
|
[CallingConvention(.Stdcall), CLink]
|
||||||
static extern char8* BfParser_GetDebugExpressionAt(void* bfParser, int32 cursorIdx);
|
static extern char8* BfParser_GetDebugExpressionAt(void* bfParser, int32 cursorIdx);
|
||||||
|
@ -209,8 +210,9 @@ namespace IDE.Compiler
|
||||||
public void Reformat(int formatStart, int formatEnd, out int32[] char8Mapping, String str)
|
public void Reformat(int formatStart, int formatEnd, out int32[] char8Mapping, String str)
|
||||||
{
|
{
|
||||||
int32* char8MappingPtr;
|
int32* char8MappingPtr;
|
||||||
var stringPtr = BfParser_Format(mNativeBfParser, (int32)formatStart, (int32)formatEnd, out char8MappingPtr);
|
var maxCol = gApp.mSettings.mEditorSettings.mWrapCommentsAt;
|
||||||
str.Append(stringPtr);
|
var stringPtr = BfParser_Format(mNativeBfParser, (int32)formatStart, (int32)formatEnd, out char8MappingPtr, maxCol);
|
||||||
|
str.Append(stringPtr);
|
||||||
|
|
||||||
char8Mapping = new int32[str.Length];
|
char8Mapping = new int32[str.Length];
|
||||||
for (int32 i = 0; i < char8Mapping.Count; i++)
|
for (int32 i = 0; i < char8Mapping.Count; i++)
|
||||||
|
|
|
@ -51,7 +51,7 @@ namespace IDE.Compiler
|
||||||
static extern char8* BfSystem_GetNamespaceSearch(void* bfSystem, char8* typeName, void* project);
|
static extern char8* BfSystem_GetNamespaceSearch(void* bfSystem, char8* typeName, void* project);
|
||||||
|
|
||||||
[CallingConvention(.Stdcall), CLink]
|
[CallingConvention(.Stdcall), CLink]
|
||||||
static extern void* BfSystem_CreateProject(void* bfSystem, char8* projectName);
|
static extern void* BfSystem_CreateProject(void* bfSystem, char8* projectName, char8* projectDir);
|
||||||
|
|
||||||
[CallingConvention(.Stdcall), CLink]
|
[CallingConvention(.Stdcall), CLink]
|
||||||
static extern void BfSystem_ClearTypeOptions(void* bfSystem);
|
static extern void BfSystem_ClearTypeOptions(void* bfSystem);
|
||||||
|
@ -142,7 +142,7 @@ namespace IDE.Compiler
|
||||||
{
|
{
|
||||||
using (mMonitor.Enter())
|
using (mMonitor.Enter())
|
||||||
{
|
{
|
||||||
var bfProject = CreateProject(project.mProjectName);
|
var bfProject = CreateProject(project.mProjectName, project.mProjectDir);
|
||||||
mProjectMap[project] = bfProject;
|
mProjectMap[project] = bfProject;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -188,10 +188,10 @@ namespace IDE.Compiler
|
||||||
outNamespaceSearch.Append(namespaceSearch);
|
outNamespaceSearch.Append(namespaceSearch);
|
||||||
}
|
}
|
||||||
|
|
||||||
public BfProject CreateProject(String projectName)
|
public BfProject CreateProject(String projectName, String projectDir)
|
||||||
{
|
{
|
||||||
BfProject project = new BfProject();
|
BfProject project = new BfProject();
|
||||||
project.mNativeBfProject = BfSystem_CreateProject(mNativeBfSystem, projectName);
|
project.mNativeBfProject = BfSystem_CreateProject(mNativeBfSystem, projectName, projectDir);
|
||||||
return project;
|
return project;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -169,6 +169,8 @@ namespace IDE
|
||||||
public bool mLastCompileHadMessages;
|
public bool mLastCompileHadMessages;
|
||||||
public bool mPauseOnExit;
|
public bool mPauseOnExit;
|
||||||
public bool mDbgDelayedAutocomplete;
|
public bool mDbgDelayedAutocomplete;
|
||||||
|
public bool mDbgTimeAutocomplete;
|
||||||
|
public bool mDbgPerfAutocomplete;
|
||||||
public BeefConfig mBeefConfig = new BeefConfig() ~ delete _;
|
public BeefConfig mBeefConfig = new BeefConfig() ~ delete _;
|
||||||
public List<String> mDeferredFails = new .() ~ DeleteContainerAndItems!(_);
|
public List<String> mDeferredFails = new .() ~ DeleteContainerAndItems!(_);
|
||||||
public String mInitialCWD = new .() ~ delete _;
|
public String mInitialCWD = new .() ~ delete _;
|
||||||
|
@ -2314,6 +2316,11 @@ namespace IDE
|
||||||
widget.RemoveSelf();
|
widget.RemoveSelf();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
WithSourceViewPanels(scope (sourceViewPanel) =>
|
||||||
|
{
|
||||||
|
sourceViewPanel.Dispose();
|
||||||
|
});
|
||||||
|
|
||||||
if (!mRunningTestScript)
|
if (!mRunningTestScript)
|
||||||
{
|
{
|
||||||
mActiveDocumentsTabbedView = null;
|
mActiveDocumentsTabbedView = null;
|
||||||
|
@ -2425,11 +2432,27 @@ namespace IDE
|
||||||
}
|
}
|
||||||
|
|
||||||
[IDECommand]
|
[IDECommand]
|
||||||
void CommentSelection()
|
void CommentBlock()
|
||||||
{
|
{
|
||||||
var sewc = GetActiveSourceEditWidgetContent();
|
var sewc = GetActiveSourceEditWidgetContent();
|
||||||
if (sewc != null)
|
if (sewc != null)
|
||||||
sewc.ToggleComment(true);
|
sewc.CommentBlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
[IDECommand]
|
||||||
|
void CommentLines()
|
||||||
|
{
|
||||||
|
var sewc = GetActiveSourceEditWidgetContent();
|
||||||
|
if (sewc != null)
|
||||||
|
sewc.CommentLines();
|
||||||
|
}
|
||||||
|
|
||||||
|
[IDECommand]
|
||||||
|
void CommentToggle()
|
||||||
|
{
|
||||||
|
var sewc = GetActiveSourceEditWidgetContent();
|
||||||
|
if (sewc != null)
|
||||||
|
sewc.ToggleComment();
|
||||||
}
|
}
|
||||||
|
|
||||||
[IDECommand]
|
[IDECommand]
|
||||||
|
@ -3936,7 +3959,7 @@ namespace IDE
|
||||||
if (sourceViewPanel != null)
|
if (sourceViewPanel != null)
|
||||||
{
|
{
|
||||||
if (sourceViewPanel.mEditWidget.mEditWidgetContent.GetCursorLineChar(var line, var lineChar))
|
if (sourceViewPanel.mEditWidget.mEditWidgetContent.GetCursorLineChar(var line, var lineChar))
|
||||||
sourceViewPanel.UpdateMouseover(true, true, line, lineChar);
|
sourceViewPanel.UpdateMouseover(true, true, line, lineChar, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4874,6 +4897,14 @@ namespace IDE
|
||||||
CreateDefaultLayout(false);
|
CreateDefaultLayout(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[IDECommand]
|
||||||
|
public void SafeModeToggle()
|
||||||
|
{
|
||||||
|
mSafeMode = !mSafeMode;
|
||||||
|
mNoResolve = mSafeMode;
|
||||||
|
mWantsBeefClean = true;
|
||||||
|
}
|
||||||
|
|
||||||
[IDECommand]
|
[IDECommand]
|
||||||
public void ShowKeyboardShortcuts()
|
public void ShowKeyboardShortcuts()
|
||||||
{
|
{
|
||||||
|
@ -5240,6 +5271,11 @@ namespace IDE
|
||||||
menu.SetDisabled(!mDebugger.mIsRunning);
|
menu.SetDisabled(!mDebugger.mIsRunning);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void UpdateMenuItem_DebugOrTestRunning(IMenu menu)
|
||||||
|
{
|
||||||
|
menu.SetDisabled(!mDebugger.mIsRunning && (mTestManager == null));
|
||||||
|
}
|
||||||
|
|
||||||
public void UpdateMenuItem_DebugStopped_HasWorkspace(IMenu menu)
|
public void UpdateMenuItem_DebugStopped_HasWorkspace(IMenu menu)
|
||||||
{
|
{
|
||||||
menu.SetDisabled(mDebugger.mIsRunning || !mWorkspace.IsInitialized);
|
menu.SetDisabled(mDebugger.mIsRunning || !mWorkspace.IsInitialized);
|
||||||
|
@ -5310,6 +5346,7 @@ namespace IDE
|
||||||
AddMenuItem(prefMenu, "&Settings", "Settings");
|
AddMenuItem(prefMenu, "&Settings", "Settings");
|
||||||
AddMenuItem(prefMenu, "Reload Settings", "Reload Settings");
|
AddMenuItem(prefMenu, "Reload Settings", "Reload Settings");
|
||||||
AddMenuItem(prefMenu, "Reset UI", "Reset UI");
|
AddMenuItem(prefMenu, "Reset UI", "Reset UI");
|
||||||
|
AddMenuItem(prefMenu, "Safe Mode", "Safe Mode Toggle", new (menu) => { menu.SetCheckState(mSafeMode ? 1 : 0); }, null, true, mSafeMode ? 1 : 0);
|
||||||
AddMenuItem(subMenu, "Close Workspace", "Close Workspace", new => UpdateMenuItem_HasWorkspace);
|
AddMenuItem(subMenu, "Close Workspace", "Close Workspace", new => UpdateMenuItem_HasWorkspace);
|
||||||
AddMenuItem(subMenu, "E&xit", "Exit");
|
AddMenuItem(subMenu, "E&xit", "Exit");
|
||||||
|
|
||||||
|
@ -5386,7 +5423,9 @@ namespace IDE
|
||||||
advancedEditMenu.AddMenuItem(null);
|
advancedEditMenu.AddMenuItem(null);
|
||||||
AddMenuItem(advancedEditMenu, "Make Uppercase", "Make Uppercase");
|
AddMenuItem(advancedEditMenu, "Make Uppercase", "Make Uppercase");
|
||||||
AddMenuItem(advancedEditMenu, "Make Lowercase", "Make Lowercase");
|
AddMenuItem(advancedEditMenu, "Make Lowercase", "Make Lowercase");
|
||||||
AddMenuItem(advancedEditMenu, "Comment Selection", "Comment Selection");
|
AddMenuItem(advancedEditMenu, "Comment Block", "Comment Block");
|
||||||
|
AddMenuItem(advancedEditMenu, "Comment Lines", "Comment Lines");
|
||||||
|
AddMenuItem(advancedEditMenu, "Comment Toggle", "Comment Toggle");
|
||||||
AddMenuItem(advancedEditMenu, "Uncomment Selection", "Uncomment Selection");
|
AddMenuItem(advancedEditMenu, "Uncomment Selection", "Uncomment Selection");
|
||||||
AddMenuItem(advancedEditMenu, "Reformat Document", "Reformat Document");
|
AddMenuItem(advancedEditMenu, "Reformat Document", "Reformat Document");
|
||||||
mViewWhiteSpace.mMenu = AddMenuItem(advancedEditMenu, "View White Space", "View White Space", null, null, true, mViewWhiteSpace.Bool ? 1 : 0);
|
mViewWhiteSpace.mMenu = AddMenuItem(advancedEditMenu, "View White Space", "View White Space", null, null, true, mViewWhiteSpace.Bool ? 1 : 0);
|
||||||
|
@ -5397,6 +5436,8 @@ namespace IDE
|
||||||
var internalEditMenu = subMenu.AddMenuItem("Internal");
|
var internalEditMenu = subMenu.AddMenuItem("Internal");
|
||||||
internalEditMenu.AddMenuItem("Hilight Cursor References", null, new (menu) => { ToggleCheck(menu, ref gApp.mSettings.mEditorSettings.mHiliteCursorReferences); }, null, null, true, gApp.mSettings.mEditorSettings.mHiliteCursorReferences ? 1 : 0);
|
internalEditMenu.AddMenuItem("Hilight Cursor References", null, new (menu) => { ToggleCheck(menu, ref gApp.mSettings.mEditorSettings.mHiliteCursorReferences); }, null, null, true, gApp.mSettings.mEditorSettings.mHiliteCursorReferences ? 1 : 0);
|
||||||
internalEditMenu.AddMenuItem("Delayed Autocomplete", null, new (menu) => { ToggleCheck(menu, ref gApp.mDbgDelayedAutocomplete); }, null, null, true, gApp.mDbgDelayedAutocomplete ? 1 : 0);
|
internalEditMenu.AddMenuItem("Delayed Autocomplete", null, new (menu) => { ToggleCheck(menu, ref gApp.mDbgDelayedAutocomplete); }, null, null, true, gApp.mDbgDelayedAutocomplete ? 1 : 0);
|
||||||
|
internalEditMenu.AddMenuItem("Time Autocomplete", null, new (menu) => { ToggleCheck(menu, ref gApp.mDbgTimeAutocomplete); }, null, null, true, gApp.mDbgTimeAutocomplete ? 1 : 0);
|
||||||
|
internalEditMenu.AddMenuItem("Perf Autocomplete", null, new (menu) => { ToggleCheck(menu, ref gApp.mDbgPerfAutocomplete); }, null, null, true, gApp.mDbgPerfAutocomplete ? 1 : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////
|
//////////
|
||||||
|
@ -5456,7 +5497,7 @@ namespace IDE
|
||||||
AddMenuItem(subMenu, "Start With&out Compiling", "Start Without Compiling", new => UpdateMenuItem_DebugStopped_HasWorkspace);
|
AddMenuItem(subMenu, "Start With&out Compiling", "Start Without Compiling", new => UpdateMenuItem_DebugStopped_HasWorkspace);
|
||||||
AddMenuItem(subMenu, "&Launch Process...", "Launch Process", new => UpdateMenuItem_DebugStopped);
|
AddMenuItem(subMenu, "&Launch Process...", "Launch Process", new => UpdateMenuItem_DebugStopped);
|
||||||
AddMenuItem(subMenu, "&Attach to Process...", "Attach to Process", new => UpdateMenuItem_DebugStopped);
|
AddMenuItem(subMenu, "&Attach to Process...", "Attach to Process", new => UpdateMenuItem_DebugStopped);
|
||||||
AddMenuItem(subMenu, "&Stop Debugging", "Stop Debugging", new => UpdateMenuItem_DebugRunning);
|
AddMenuItem(subMenu, "&Stop Debugging", "Stop Debugging", new => UpdateMenuItem_DebugOrTestRunning);
|
||||||
AddMenuItem(subMenu, "Break All", "Break All", new => UpdateMenuItem_DebugNotPaused);
|
AddMenuItem(subMenu, "Break All", "Break All", new => UpdateMenuItem_DebugNotPaused);
|
||||||
AddMenuItem(subMenu, "Remove All Breakpoints", "Remove All Breakpoints");
|
AddMenuItem(subMenu, "Remove All Breakpoints", "Remove All Breakpoints");
|
||||||
AddMenuItem(subMenu, "Show &Disassembly", "Show Disassembly");
|
AddMenuItem(subMenu, "Show &Disassembly", "Show Disassembly");
|
||||||
|
@ -5712,14 +5753,20 @@ namespace IDE
|
||||||
{
|
{
|
||||||
let sewc = editWidget.mEditWidgetContent as SourceEditWidgetContent;
|
let sewc = editWidget.mEditWidgetContent as SourceEditWidgetContent;
|
||||||
if (sewc != null)
|
if (sewc != null)
|
||||||
return sewc;
|
{
|
||||||
|
if (sewc.mEditWidget.mHasFocus)
|
||||||
|
return sewc;
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var activeTextPanel = GetActivePanel() as TextPanel;
|
var activeTextPanel = GetActivePanel() as TextPanel;
|
||||||
if (activeTextPanel != null)
|
if (activeTextPanel != null)
|
||||||
{
|
{
|
||||||
return activeTextPanel.EditWidget.mEditWidgetContent as SourceEditWidgetContent;
|
let sewc = activeTextPanel.EditWidget.mEditWidgetContent as SourceEditWidgetContent;
|
||||||
|
if ((sewc != null) && (sewc.mEditWidget.mHasFocus))
|
||||||
|
return sewc;
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
|
@ -9167,6 +9214,9 @@ namespace IDE
|
||||||
bool doCompile = false;
|
bool doCompile = false;
|
||||||
if (lastCompileHadMessages)
|
if (lastCompileHadMessages)
|
||||||
doCompile = true;
|
doCompile = true;
|
||||||
|
|
||||||
|
bool needsComptime = bfCompiler.GetLastHadComptimeRebuilds();
|
||||||
|
|
||||||
if ((!workspaceOptions.mIncrementalBuild) && (!lastCompileHadMessages))
|
if ((!workspaceOptions.mIncrementalBuild) && (!lastCompileHadMessages))
|
||||||
{
|
{
|
||||||
tryQueueFiles = false;
|
tryQueueFiles = false;
|
||||||
|
@ -9177,6 +9227,9 @@ namespace IDE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (needsComptime)
|
||||||
|
tryQueueFiles = true;
|
||||||
|
|
||||||
if (hotProject != null)
|
if (hotProject != null)
|
||||||
{
|
{
|
||||||
mWorkspace.mHadHotCompileSinceLastFullCompile = true;
|
mWorkspace.mHadHotCompileSinceLastFullCompile = true;
|
||||||
|
@ -9210,6 +9263,9 @@ namespace IDE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (needsComptime)
|
||||||
|
doCompile = true;
|
||||||
|
|
||||||
if (!success)
|
if (!success)
|
||||||
{
|
{
|
||||||
bfCompiler.QueueDeletePassInstance(passInstance);
|
bfCompiler.QueueDeletePassInstance(passInstance);
|
||||||
|
@ -10748,7 +10804,7 @@ namespace IDE
|
||||||
Beef requires the Microsoft C++ build tools for Visual Studio 2013 or later, but they don't seem to be installed.
|
Beef requires the Microsoft C++ build tools for Visual Studio 2013 or later, but they don't seem to be installed.
|
||||||
|
|
||||||
Install just Microsoft Visual C++ Build Tools or the entire Visual Studio suite from:
|
Install just Microsoft Visual C++ Build Tools or the entire Visual Studio suite from:
|
||||||
https://visualstudio.microsoft.com/downloads/#build-tools-for-visual-studio-2019
|
https://visualstudio.microsoft.com/downloads/#build-tools-for-visual-studio-2022
|
||||||
""";
|
""";
|
||||||
|
|
||||||
#if CLI
|
#if CLI
|
||||||
|
@ -10759,7 +10815,7 @@ namespace IDE
|
||||||
dlg.AddOkCancelButtons(new (dlg) =>
|
dlg.AddOkCancelButtons(new (dlg) =>
|
||||||
{
|
{
|
||||||
ProcessStartInfo psi = scope ProcessStartInfo();
|
ProcessStartInfo psi = scope ProcessStartInfo();
|
||||||
psi.SetFileName("https://visualstudio.microsoft.com/downloads/#build-tools-for-visual-studio-2019");
|
psi.SetFileName("https://visualstudio.microsoft.com/downloads/#build-tools-for-visual-studio-2022");
|
||||||
psi.UseShellExecute = true;
|
psi.UseShellExecute = true;
|
||||||
psi.SetVerb("Open");
|
psi.SetVerb("Open");
|
||||||
var process = scope SpawnedProcess();
|
var process = scope SpawnedProcess();
|
||||||
|
@ -12040,11 +12096,11 @@ namespace IDE
|
||||||
if (mErrorsPanel != null)
|
if (mErrorsPanel != null)
|
||||||
mErrorsPanel.ClearParserErrors(null);
|
mErrorsPanel.ClearParserErrors(null);
|
||||||
|
|
||||||
delete mBfResolveCompiler;
|
DeleteAndNullify!(mBfResolveCompiler);
|
||||||
delete mBfResolveSystem;
|
DeleteAndNullify!(mBfResolveSystem);
|
||||||
delete mBfResolveHelper;
|
DeleteAndNullify!(mBfResolveHelper);
|
||||||
delete mBfBuildCompiler;
|
DeleteAndNullify!(mBfBuildCompiler);
|
||||||
delete mBfBuildSystem;
|
DeleteAndNullify!(mBfBuildSystem);
|
||||||
|
|
||||||
///
|
///
|
||||||
mDebugger.FullReportMemory();
|
mDebugger.FullReportMemory();
|
||||||
|
@ -13698,7 +13754,6 @@ namespace IDE
|
||||||
[Import("user32.lib"), CLink, CallingConvention(.Stdcall)]
|
[Import("user32.lib"), CLink, CallingConvention(.Stdcall)]
|
||||||
public static extern bool MessageBeep(MessageBeepType type);
|
public static extern bool MessageBeep(MessageBeepType type);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
|
|
|
@ -626,6 +626,7 @@ namespace IDE
|
||||||
public FileRecoveryKind mEnableFileRecovery = .Yes;
|
public FileRecoveryKind mEnableFileRecovery = .Yes;
|
||||||
public bool mFormatOnSave = false;
|
public bool mFormatOnSave = false;
|
||||||
public bool mSyncWithWorkspacePanel = false;
|
public bool mSyncWithWorkspacePanel = false;
|
||||||
|
public int32 mWrapCommentsAt = 0;
|
||||||
|
|
||||||
public void Serialize(StructuredData sd)
|
public void Serialize(StructuredData sd)
|
||||||
{
|
{
|
||||||
|
@ -652,6 +653,7 @@ namespace IDE
|
||||||
sd.Add("EnableFileRecovery", mEnableFileRecovery);
|
sd.Add("EnableFileRecovery", mEnableFileRecovery);
|
||||||
sd.Add("FormatOnSave", mFormatOnSave);
|
sd.Add("FormatOnSave", mFormatOnSave);
|
||||||
sd.Add("SyncWithWorkspacePanel", mSyncWithWorkspacePanel);
|
sd.Add("SyncWithWorkspacePanel", mSyncWithWorkspacePanel);
|
||||||
|
sd.Add("WrapCommentsAt", mWrapCommentsAt);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Deserialize(StructuredData sd)
|
public void Deserialize(StructuredData sd)
|
||||||
|
@ -682,6 +684,7 @@ namespace IDE
|
||||||
sd.GetEnum<FileRecoveryKind>("EnableFileRecovery", ref mEnableFileRecovery);
|
sd.GetEnum<FileRecoveryKind>("EnableFileRecovery", ref mEnableFileRecovery);
|
||||||
sd.Get("FormatOnSave", ref mFormatOnSave);
|
sd.Get("FormatOnSave", ref mFormatOnSave);
|
||||||
sd.Get("SyncWithWorkspacePanel", ref mSyncWithWorkspacePanel);
|
sd.Get("SyncWithWorkspacePanel", ref mSyncWithWorkspacePanel);
|
||||||
|
sd.Get("WrapCommentsAt", ref mWrapCommentsAt);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetDefaults()
|
public void SetDefaults()
|
||||||
|
@ -756,7 +759,9 @@ namespace IDE
|
||||||
Add("Cancel Build", "Ctrl+Break");
|
Add("Cancel Build", "Ctrl+Break");
|
||||||
Add("Close Document", "Ctrl+W");
|
Add("Close Document", "Ctrl+W");
|
||||||
Add("Compile File", "Ctrl+F7");
|
Add("Compile File", "Ctrl+F7");
|
||||||
Add("Comment Selection", "Ctrl+K, Ctrl+C");
|
Add("Comment Block", "Ctrl+K, Ctrl+C");
|
||||||
|
Add("Comment Lines", "Ctrl+K, Ctrl+/");
|
||||||
|
Add("Comment Toggle", "Ctrl+K, Ctrl+T");
|
||||||
Add("Duplicate Line", "Ctrl+D");
|
Add("Duplicate Line", "Ctrl+D");
|
||||||
Add("Find Class", "Alt+Shift+L");
|
Add("Find Class", "Alt+Shift+L");
|
||||||
Add("Find in Document", "Ctrl+F");
|
Add("Find in Document", "Ctrl+F");
|
||||||
|
@ -892,7 +897,10 @@ namespace IDE
|
||||||
{
|
{
|
||||||
curCmdMap = (*valuePtr) as CommandMap;
|
curCmdMap = (*valuePtr) as CommandMap;
|
||||||
if (curCmdMap == null)
|
if (curCmdMap == null)
|
||||||
|
{
|
||||||
|
curCmdMap.FailValues.Add(ideCommand);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -905,7 +913,10 @@ namespace IDE
|
||||||
if (checkPrevCmd.mContextFlags == ideCommand.mContextFlags)
|
if (checkPrevCmd.mContextFlags == ideCommand.mContextFlags)
|
||||||
gApp.OutputLineSmart("ERROR: The same key is bound for '{0}' and '{1}'", checkPrevCmd.mName, entry.mCommand);
|
gApp.OutputLineSmart("ERROR: The same key is bound for '{0}' and '{1}'", checkPrevCmd.mName, entry.mCommand);
|
||||||
if (checkPrevCmd.mNext == null)
|
if (checkPrevCmd.mNext == null)
|
||||||
|
{
|
||||||
|
curCmdMap.FailValues.Add(ideCommand);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
checkPrevCmd = checkPrevCmd.mNext;
|
checkPrevCmd = checkPrevCmd.mNext;
|
||||||
}
|
}
|
||||||
checkPrevCmd.mNext = ideCommand;
|
checkPrevCmd.mNext = ideCommand;
|
||||||
|
|
|
@ -1165,6 +1165,7 @@ namespace IDE.ui
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Stopwatch mStopwatch ~ delete _;
|
||||||
public EditWidget mTargetEditWidget;
|
public EditWidget mTargetEditWidget;
|
||||||
public Event<Action> mOnAutoCompleteInserted ~ _.Dispose();
|
public Event<Action> mOnAutoCompleteInserted ~ _.Dispose();
|
||||||
public Event<Action> mOnClosed ~ _.Dispose();
|
public Event<Action> mOnClosed ~ _.Dispose();
|
||||||
|
|
|
@ -136,17 +136,15 @@ namespace IDE.ui
|
||||||
ClearAndDeleteItems(mResolveErrors);
|
ClearAndDeleteItems(mResolveErrors);
|
||||||
mResolveErrors.Capacity = mResolveErrors.Count;
|
mResolveErrors.Capacity = mResolveErrors.Count;
|
||||||
}
|
}
|
||||||
|
var bfl = scope:: List<BfPassInstance.BfError>();
|
||||||
for (int32 errorIdx = 0; errorIdx < errorCount; errorIdx++)
|
for (int32 errorIdx = 0; errorIdx < errorCount; errorIdx++)
|
||||||
{
|
{
|
||||||
BfPassInstance.BfError bfError = new BfPassInstance.BfError();
|
BfPassInstance.BfError bfError = new BfPassInstance.BfError();
|
||||||
passInstance.GetErrorData(errorIdx, bfError, true);
|
passInstance.GetErrorData(errorIdx, bfError, true);
|
||||||
|
if (bfError.mFilePath == null)
|
||||||
|
bfError.mFilePath = new String(""); //for sort below
|
||||||
|
|
||||||
if (bfError.mIsWarning)
|
bfl.Add(bfError);
|
||||||
mWarningCount++;
|
|
||||||
else
|
|
||||||
mErrorCount++;
|
|
||||||
|
|
||||||
for (int32 moreInfoIdx < bfError.mMoreInfoCount)
|
for (int32 moreInfoIdx < bfError.mMoreInfoCount)
|
||||||
{
|
{
|
||||||
BfPassInstance.BfError moreInfo = new BfPassInstance.BfError();
|
BfPassInstance.BfError moreInfo = new BfPassInstance.BfError();
|
||||||
|
@ -155,12 +153,26 @@ namespace IDE.ui
|
||||||
bfError.mMoreInfo = new List<BfPassInstance.BfError>();
|
bfError.mMoreInfo = new List<BfPassInstance.BfError>();
|
||||||
bfError.mMoreInfo.Add(moreInfo);
|
bfError.mMoreInfo.Add(moreInfo);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function int(int lhs, int rhs) ascLambda = (lhs, rhs) => lhs <=> rhs;
|
||||||
|
bfl.Sort(scope (lhs, rhs) => ascLambda(lhs.mFilePath.GetHashCode()+lhs.mSrcStart, rhs.mFilePath.GetHashCode()+rhs.mSrcStart));
|
||||||
|
|
||||||
|
for (int32 errorIdx = 0; errorIdx < bfl.Count; errorIdx++)
|
||||||
|
{
|
||||||
|
var bfError = bfl[errorIdx];
|
||||||
|
|
||||||
|
if (bfError.mIsWarning)
|
||||||
|
{
|
||||||
|
mWarningCount++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
mErrorCount++;
|
||||||
|
|
||||||
if (passKind == .Parse)
|
if (passKind == .Parse)
|
||||||
{
|
{
|
||||||
if (bfError.mFilePath == null)
|
if (bfError.mFilePath == null)
|
||||||
bfError.mFilePath = new String("");
|
bfError.mFilePath = new String("");
|
||||||
|
|
||||||
bool added = mParseErrors.TryAdd(bfError.mFilePath, var keyPtr, var valuePtr);
|
bool added = mParseErrors.TryAdd(bfError.mFilePath, var keyPtr, var valuePtr);
|
||||||
if (added)
|
if (added)
|
||||||
{
|
{
|
||||||
|
@ -170,7 +182,7 @@ namespace IDE.ui
|
||||||
(*valuePtr).Add(bfError);
|
(*valuePtr).Add(bfError);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
mResolveErrors.Add(bfError);
|
mResolveErrors.Add(bfError);
|
||||||
|
|
||||||
mDataId++;
|
mDataId++;
|
||||||
}
|
}
|
||||||
|
@ -369,7 +381,8 @@ namespace IDE.ui
|
||||||
else
|
else
|
||||||
mDirtyTicks++;
|
mDirtyTicks++;
|
||||||
|
|
||||||
ProcessErrors();
|
if(mDirtyTicks==0)
|
||||||
|
ProcessErrors();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetNeedsResolveAll()
|
public void SetNeedsResolveAll()
|
||||||
|
@ -379,7 +392,8 @@ namespace IDE.ui
|
||||||
|
|
||||||
public void ShowErrorNext()
|
public void ShowErrorNext()
|
||||||
{
|
{
|
||||||
ProcessErrors();
|
if(mDirtyTicks==0)
|
||||||
|
ProcessErrors();
|
||||||
|
|
||||||
bool foundFocused = false;
|
bool foundFocused = false;
|
||||||
let root = mErrorLV.GetRoot();
|
let root = mErrorLV.GetRoot();
|
||||||
|
|
|
@ -139,7 +139,8 @@ namespace IDE.ui
|
||||||
mOutputWidget.SetText("");
|
mOutputWidget.SetText("");
|
||||||
for (var widgetEntry in mInlineWidgets)
|
for (var widgetEntry in mInlineWidgets)
|
||||||
{
|
{
|
||||||
widgetEntry.mWidget.RemoveSelf();
|
if (widgetEntry.mWidget.mParent != null)
|
||||||
|
widgetEntry.mWidget.RemoveSelf();
|
||||||
delete widgetEntry.mWidget;
|
delete widgetEntry.mWidget;
|
||||||
}
|
}
|
||||||
mInlineWidgets.Clear();
|
mInlineWidgets.Clear();
|
||||||
|
|
|
@ -293,6 +293,10 @@ namespace IDE.ui
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct ThreadEntry : this(int32 mThreadId, int32 mCPUUsage, StringView mName)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
void PopulateThreadList(Menu menu)
|
void PopulateThreadList(Menu menu)
|
||||||
{
|
{
|
||||||
if (mProfiler == null)
|
if (mProfiler == null)
|
||||||
|
@ -307,6 +311,7 @@ namespace IDE.ui
|
||||||
var threadListStr = scope String();
|
var threadListStr = scope String();
|
||||||
mProfiler.GetThreadList(threadListStr);
|
mProfiler.GetThreadList(threadListStr);
|
||||||
|
|
||||||
|
List<ThreadEntry> entries = scope .();
|
||||||
for (var entry in threadListStr.Split('\n'))
|
for (var entry in threadListStr.Split('\n'))
|
||||||
{
|
{
|
||||||
if (entry.Length == 0)
|
if (entry.Length == 0)
|
||||||
|
@ -314,20 +319,35 @@ namespace IDE.ui
|
||||||
|
|
||||||
var dataItr = entry.Split('\t');
|
var dataItr = entry.Split('\t');
|
||||||
|
|
||||||
int32 threadId = int32.Parse(dataItr.GetNext());
|
ThreadEntry threadEntry = default;
|
||||||
StringView threadName = dataItr.GetNext();
|
threadEntry.mThreadId = int32.Parse(dataItr.GetNext());
|
||||||
|
threadEntry.mCPUUsage = int32.Parse(dataItr.GetNext());
|
||||||
|
threadEntry.mName = dataItr.GetNext();
|
||||||
|
entries.Add(threadEntry);
|
||||||
|
}
|
||||||
|
|
||||||
|
entries.Sort(scope (lhs, rhs) =>
|
||||||
|
{
|
||||||
|
int cmp = rhs.mCPUUsage <=> lhs.mCPUUsage;
|
||||||
|
if (cmp == 0)
|
||||||
|
cmp = lhs.mThreadId <=> rhs.mThreadId;
|
||||||
|
return cmp;
|
||||||
|
});
|
||||||
|
|
||||||
|
for (var entry in entries)
|
||||||
|
{
|
||||||
String threadStr = null;
|
String threadStr = null;
|
||||||
var str = scope String();
|
var str = scope String();
|
||||||
str.AppendF("{0}", threadId);
|
str.AppendF("{0}", entry.mThreadId);
|
||||||
if (!threadName.IsEmpty)
|
str.AppendF($" ({entry.mCPUUsage}%)");
|
||||||
|
if (!entry.mName.IsEmpty)
|
||||||
{
|
{
|
||||||
threadStr = new String(threadName);
|
threadStr = new String(entry.mName);
|
||||||
str.AppendF(" - {0}", threadName);
|
str.AppendF($" - {entry.mName}");
|
||||||
}
|
}
|
||||||
|
|
||||||
subItem = menu.AddItem(str);
|
subItem = menu.AddItem(str);
|
||||||
subItem.mOnMenuItemSelected.Add(new (item) => { Show(threadId, threadStr); } ~ delete threadStr);
|
subItem.mOnMenuItemSelected.Add(new (item) => { Show(entry.mThreadId, threadStr); } ~ delete threadStr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -127,6 +127,7 @@ namespace IDE.ui
|
||||||
AddPropertiesItem(category, "Enable File Recovery", "mEnableFileRecovery");
|
AddPropertiesItem(category, "Enable File Recovery", "mEnableFileRecovery");
|
||||||
AddPropertiesItem(category, "Format on Save", "mFormatOnSave");
|
AddPropertiesItem(category, "Format on Save", "mFormatOnSave");
|
||||||
AddPropertiesItem(category, "Sync with Workspace Panel", "mSyncWithWorkspacePanel");
|
AddPropertiesItem(category, "Sync with Workspace Panel", "mSyncWithWorkspacePanel");
|
||||||
|
AddPropertiesItem(category, "Wrap Comments at Column", "mWrapCommentsAt");
|
||||||
|
|
||||||
category.Open(true, true);
|
category.Open(true, true);
|
||||||
}
|
}
|
||||||
|
|
|
@ -2160,11 +2160,18 @@ namespace IDE.ui
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool ToggleComment(bool? doComment = null)
|
public bool CommentBlock()
|
||||||
{
|
{
|
||||||
|
bool? doComment = true;
|
||||||
|
|
||||||
if (CheckReadOnly())
|
if (CheckReadOnly())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
var startLineAndCol = CursorLineAndColumn;
|
||||||
|
int startTextPos = CursorTextPos;
|
||||||
|
var prevSelection = mSelection;
|
||||||
|
bool hadSelection = HasSelection();
|
||||||
|
|
||||||
if ((!HasSelection()) && (doComment != null))
|
if ((!HasSelection()) && (doComment != null))
|
||||||
{
|
{
|
||||||
CursorToLineEnd();
|
CursorToLineEnd();
|
||||||
|
@ -2173,14 +2180,15 @@ namespace IDE.ui
|
||||||
mSelection = .(CursorTextPos, cursorEndPos);
|
mSelection = .(CursorTextPos, cursorEndPos);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((HasSelection()) && (mSelection.Value.Length > 1))
|
if ((HasSelection()) && (mSelection.Value.Length > 1))
|
||||||
{
|
{
|
||||||
var startLineAndCol = CursorLineAndColumn;
|
UndoBatchStart undoBatchStart = new UndoBatchStart("embeddedCommentBlock");
|
||||||
|
|
||||||
UndoBatchStart undoBatchStart = new UndoBatchStart("embeddedToggleComment");
|
|
||||||
mData.mUndoManager.Add(undoBatchStart);
|
mData.mUndoManager.Add(undoBatchStart);
|
||||||
|
|
||||||
mData.mUndoManager.Add(new SetCursorAction(this));
|
var setCursorAction = new SetCursorAction(this);
|
||||||
|
setCursorAction.mSelection = prevSelection;
|
||||||
|
setCursorAction.mCursorTextPos = (.)startTextPos;
|
||||||
|
mData.mUndoManager.Add(setCursorAction);
|
||||||
|
|
||||||
int minPos = mSelection.GetValueOrDefault().MinPos;
|
int minPos = mSelection.GetValueOrDefault().MinPos;
|
||||||
int maxPos = mSelection.GetValueOrDefault().MaxPos;
|
int maxPos = mSelection.GetValueOrDefault().MaxPos;
|
||||||
|
@ -2200,20 +2208,7 @@ namespace IDE.ui
|
||||||
int firstCharPos = minPos + (startLen - afterTrimStart);
|
int firstCharPos = minPos + (startLen - afterTrimStart);
|
||||||
int lastCharPos = maxPos - (afterTrimStart - afterTrimEnd);
|
int lastCharPos = maxPos - (afterTrimStart - afterTrimEnd);
|
||||||
|
|
||||||
if ((doComment != true) && (trimmedStr.StartsWith("/*")))
|
if (doComment != false)
|
||||||
{
|
|
||||||
if (trimmedStr.EndsWith("*/"))
|
|
||||||
{
|
|
||||||
mSelection = EditSelection(firstCharPos, firstCharPos + 2);
|
|
||||||
DeleteChar();
|
|
||||||
mSelection = EditSelection(lastCharPos - 4, lastCharPos - 2);
|
|
||||||
DeleteChar();
|
|
||||||
|
|
||||||
if (doComment != null)
|
|
||||||
mSelection = EditSelection(firstCharPos, lastCharPos - 4);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (doComment != false)
|
|
||||||
{
|
{
|
||||||
CursorTextPos = firstCharPos;
|
CursorTextPos = firstCharPos;
|
||||||
InsertAtCursor("/*");
|
InsertAtCursor("/*");
|
||||||
|
@ -2227,13 +2222,320 @@ namespace IDE.ui
|
||||||
if (undoBatchStart != null)
|
if (undoBatchStart != null)
|
||||||
mData.mUndoManager.Add(undoBatchStart.mBatchEnd);
|
mData.mUndoManager.Add(undoBatchStart.mBatchEnd);
|
||||||
|
|
||||||
CursorLineAndColumn = startLineAndCol;
|
if (startTextPos <= minPos)
|
||||||
|
CursorLineAndColumn = startLineAndCol;
|
||||||
|
else if (startTextPos < maxPos)
|
||||||
|
CursorTextPos = startTextPos + 2;
|
||||||
|
|
||||||
if (doComment == null)
|
if ((doComment == null) || (!hadSelection))
|
||||||
mSelection = null;
|
mSelection = null;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool CommentLines()
|
||||||
|
{
|
||||||
|
if (CheckReadOnly())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
int startTextPos = CursorTextPos;
|
||||||
|
var prevSelection = mSelection;
|
||||||
|
bool hadSelection = HasSelection();
|
||||||
|
var startLineAndCol = CursorLineAndColumn;
|
||||||
|
if (!HasSelection())
|
||||||
|
{
|
||||||
|
CursorToLineEnd();
|
||||||
|
int cursorEndPos = CursorTextPos;
|
||||||
|
CursorToLineStart(false);
|
||||||
|
mSelection = .(CursorTextPos, cursorEndPos);
|
||||||
|
}
|
||||||
|
|
||||||
|
UndoBatchStart undoBatchStart = new UndoBatchStart("embeddedCommentLines");
|
||||||
|
mData.mUndoManager.Add(undoBatchStart);
|
||||||
|
|
||||||
|
var setCursorAction = new SetCursorAction(this);
|
||||||
|
setCursorAction.mSelection = prevSelection;
|
||||||
|
setCursorAction.mCursorTextPos = (.)startTextPos;
|
||||||
|
mData.mUndoManager.Add(setCursorAction);
|
||||||
|
|
||||||
|
int minPos = mSelection.GetValueOrDefault().MinPos;
|
||||||
|
int maxPos = mSelection.GetValueOrDefault().MaxPos;
|
||||||
|
mSelection = null;
|
||||||
|
|
||||||
|
while (minPos > 0)
|
||||||
|
{
|
||||||
|
var c = mData.mText[minPos - 1].mChar;
|
||||||
|
if (c == '\n')
|
||||||
|
break;
|
||||||
|
minPos--;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool hadMaxChar = false;
|
||||||
|
int checkMaxPos = maxPos;
|
||||||
|
while (checkMaxPos > 0)
|
||||||
|
{
|
||||||
|
var c = mData.mText[checkMaxPos - 1].mChar;
|
||||||
|
if (c == '\n')
|
||||||
|
break;
|
||||||
|
if ((c != '\t') && (c != ' '))
|
||||||
|
{
|
||||||
|
hadMaxChar = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
checkMaxPos--;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!hadMaxChar)
|
||||||
|
{
|
||||||
|
checkMaxPos = maxPos;
|
||||||
|
while (checkMaxPos < mData.mTextLength)
|
||||||
|
{
|
||||||
|
var c = mData.mText[checkMaxPos].mChar;
|
||||||
|
if (c == '\n')
|
||||||
|
break;
|
||||||
|
if ((c != '\t') && (c != ' '))
|
||||||
|
{
|
||||||
|
maxPos = checkMaxPos + 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
checkMaxPos++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int wantLineCol = -1;
|
||||||
|
int lineStartCol = 0;
|
||||||
|
bool didLineComment = false;
|
||||||
|
|
||||||
|
for (int i = minPos; i < maxPos; i++)
|
||||||
|
{
|
||||||
|
var c = mData.mText[i].mChar;
|
||||||
|
if (didLineComment)
|
||||||
|
{
|
||||||
|
if (c == '\n')
|
||||||
|
{
|
||||||
|
didLineComment = false;
|
||||||
|
lineStartCol = 0;
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (c == '\t')
|
||||||
|
lineStartCol += 4;
|
||||||
|
else if (c == ' ')
|
||||||
|
lineStartCol++;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (wantLineCol == -1)
|
||||||
|
wantLineCol = lineStartCol;
|
||||||
|
else
|
||||||
|
wantLineCol = Math.Min(wantLineCol, lineStartCol);
|
||||||
|
didLineComment = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
wantLineCol = Math.Max(0, wantLineCol);
|
||||||
|
|
||||||
|
didLineComment = false;
|
||||||
|
lineStartCol = 0;
|
||||||
|
for (int i = minPos; i < maxPos; i++)
|
||||||
|
{
|
||||||
|
var c = mData.mText[i].mChar;
|
||||||
|
if (didLineComment)
|
||||||
|
{
|
||||||
|
if (c == '\n')
|
||||||
|
{
|
||||||
|
didLineComment = false;
|
||||||
|
lineStartCol = 0;
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool commentNow = false;
|
||||||
|
if ((wantLineCol != -1) && (lineStartCol >= wantLineCol))
|
||||||
|
commentNow = true;
|
||||||
|
|
||||||
|
if (c == '\t')
|
||||||
|
lineStartCol += 4;
|
||||||
|
else if (c == ' ')
|
||||||
|
lineStartCol++;
|
||||||
|
else
|
||||||
|
commentNow = true;
|
||||||
|
|
||||||
|
if (commentNow)
|
||||||
|
{
|
||||||
|
CursorTextPos = i;
|
||||||
|
String str = scope .();
|
||||||
|
while (lineStartCol + 4 <= wantLineCol)
|
||||||
|
{
|
||||||
|
lineStartCol += 4;
|
||||||
|
str.Append("\t");
|
||||||
|
}
|
||||||
|
str.Append("//");
|
||||||
|
InsertAtCursor(str);
|
||||||
|
didLineComment = true;
|
||||||
|
maxPos += str.Length;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mSelection = EditSelection(minPos, maxPos);
|
||||||
|
|
||||||
|
if (undoBatchStart != null)
|
||||||
|
mData.mUndoManager.Add(undoBatchStart.mBatchEnd);
|
||||||
|
|
||||||
|
CursorLineAndColumn = startLineAndCol;
|
||||||
|
|
||||||
|
if (!hadSelection)
|
||||||
|
mSelection = null;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FixSelection()
|
||||||
|
{
|
||||||
|
if (!HasSelection())
|
||||||
|
return;
|
||||||
|
if (CursorTextPos >= mSelection.Value.MaxPos)
|
||||||
|
CursorTextPos = mSelection.Value.MaxPos;
|
||||||
|
if (mSelection.Value.MaxPos - mSelection.Value.MinPos <= 1)
|
||||||
|
{
|
||||||
|
mSelection = null;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool ToggleComment(bool? doComment = null)
|
||||||
|
{
|
||||||
|
if (CheckReadOnly())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
int startTextPos = CursorTextPos;
|
||||||
|
bool doLineComment = false;
|
||||||
|
var prevSelection = mSelection;
|
||||||
|
|
||||||
|
LineAndColumn? startLineAndCol = CursorLineAndColumn;
|
||||||
|
if (!HasSelection())
|
||||||
|
{
|
||||||
|
CursorToLineEnd();
|
||||||
|
int cursorEndPos = CursorTextPos;
|
||||||
|
CursorToLineStart(false);
|
||||||
|
mSelection = .(CursorTextPos, cursorEndPos);
|
||||||
|
doLineComment = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((HasSelection()) && (mSelection.Value.Length > 0))
|
||||||
|
{
|
||||||
|
UndoBatchStart undoBatchStart = new UndoBatchStart("embeddedToggleComment");
|
||||||
|
mData.mUndoManager.Add(undoBatchStart);
|
||||||
|
|
||||||
|
var setCursorAction = new SetCursorAction(this);
|
||||||
|
setCursorAction.mSelection = prevSelection;
|
||||||
|
setCursorAction.mCursorTextPos = (.)startTextPos;
|
||||||
|
mData.mUndoManager.Add(setCursorAction);
|
||||||
|
|
||||||
|
int minPos = mSelection.GetValueOrDefault().MinPos;
|
||||||
|
int maxPos = mSelection.GetValueOrDefault().MaxPos;
|
||||||
|
mSelection = null;
|
||||||
|
|
||||||
|
var str = scope String();
|
||||||
|
ExtractString(minPos, maxPos - minPos, str);
|
||||||
|
var trimmedStr = scope String();
|
||||||
|
trimmedStr.Append(str);
|
||||||
|
int32 startLen = (int32)trimmedStr.Length;
|
||||||
|
trimmedStr.TrimStart();
|
||||||
|
int32 afterTrimStart = (int32)trimmedStr.Length;
|
||||||
|
trimmedStr.TrimEnd();
|
||||||
|
int32 afterTrimEnd = (int32)trimmedStr.Length;
|
||||||
|
trimmedStr.Append('\n');
|
||||||
|
|
||||||
|
int firstCharPos = minPos + (startLen - afterTrimStart);
|
||||||
|
int lastCharPos = maxPos - (afterTrimStart - afterTrimEnd);
|
||||||
|
|
||||||
|
if (afterTrimEnd == 0)
|
||||||
|
{
|
||||||
|
if (undoBatchStart != null)
|
||||||
|
mData.mUndoManager.Add(undoBatchStart.mBatchEnd);
|
||||||
|
|
||||||
|
CursorLineAndColumn = startLineAndCol.Value;
|
||||||
|
|
||||||
|
if (doComment == null)
|
||||||
|
mSelection = null;
|
||||||
|
|
||||||
|
return false; // not sure if this should be false in blank/only whitespace selection case
|
||||||
|
}
|
||||||
|
else if ((doComment != true) && (trimmedStr.StartsWith("//")))
|
||||||
|
{
|
||||||
|
for (int i = firstCharPos; i <= lastCharPos; i++)
|
||||||
|
{
|
||||||
|
if ((minPos == 0 && i == 0) || (minPos>=0 && SafeGetChar(i - 1) == '\n' || SafeGetChar(i - 1) == '\t'))
|
||||||
|
if (SafeGetChar(i - 0) == '/' && SafeGetChar(i + 1) == '/')
|
||||||
|
{
|
||||||
|
mSelection = EditSelection(i - 0, i + 2);
|
||||||
|
DeleteSelection();
|
||||||
|
lastCharPos -= 2;
|
||||||
|
while (i < maxPos && SafeGetChar(i) != '\n')
|
||||||
|
{
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CursorToLineEnd();
|
||||||
|
int cursorEndPos = CursorTextPos;
|
||||||
|
mSelection = .(minPos, cursorEndPos);
|
||||||
|
}
|
||||||
|
else if ((doComment != true) && (trimmedStr.StartsWith("/*")))
|
||||||
|
{
|
||||||
|
if (trimmedStr.EndsWith("*/\n"))
|
||||||
|
{
|
||||||
|
mSelection = EditSelection(firstCharPos, firstCharPos + 2);
|
||||||
|
DeleteChar();
|
||||||
|
mSelection = EditSelection(lastCharPos - 4, lastCharPos - 2);
|
||||||
|
DeleteChar();
|
||||||
|
|
||||||
|
if (prevSelection != null)
|
||||||
|
mSelection = EditSelection(firstCharPos, lastCharPos - 4);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (doComment != false)
|
||||||
|
{ //if selection is from beginning of the line then we want to use // comment, that's why the check for line count and ' ' and tab
|
||||||
|
if (doLineComment)
|
||||||
|
{
|
||||||
|
CursorTextPos = minPos;
|
||||||
|
InsertAtCursor("//"); //goes here if no selection
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
CursorTextPos = firstCharPos;
|
||||||
|
InsertAtCursor("/*");
|
||||||
|
CursorTextPos = lastCharPos + 2;
|
||||||
|
InsertAtCursor("*/");
|
||||||
|
}
|
||||||
|
|
||||||
|
mSelection = EditSelection(firstCharPos, lastCharPos + 4);
|
||||||
|
if (startTextPos <= minPos)
|
||||||
|
CursorLineAndColumn = startLineAndCol.Value;
|
||||||
|
else
|
||||||
|
CursorTextPos = startTextPos + 2;
|
||||||
|
startLineAndCol = null;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mSelection = prevSelection;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (undoBatchStart != null)
|
||||||
|
mData.mUndoManager.Add(undoBatchStart.mBatchEnd);
|
||||||
|
|
||||||
|
if (startLineAndCol != null)
|
||||||
|
CursorLineAndColumn = startLineAndCol.Value;
|
||||||
|
|
||||||
|
if (prevSelection == null)
|
||||||
|
mSelection = null;
|
||||||
|
|
||||||
|
FixSelection();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -2275,6 +2577,9 @@ namespace IDE.ui
|
||||||
|
|
||||||
public void DuplicateLine()
|
public void DuplicateLine()
|
||||||
{
|
{
|
||||||
|
if ((CheckReadOnly()) || (!mAllowVirtualCursor))
|
||||||
|
return;
|
||||||
|
|
||||||
UndoBatchStart undoBatchStart = new UndoBatchStart("duplicateLine");
|
UndoBatchStart undoBatchStart = new UndoBatchStart("duplicateLine");
|
||||||
mData.mUndoManager.Add(undoBatchStart);
|
mData.mUndoManager.Add(undoBatchStart);
|
||||||
|
|
||||||
|
@ -3103,7 +3408,7 @@ namespace IDE.ui
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((keyChar == '/') && (ToggleComment()))
|
if ((keyChar == '/') && (HasSelection()) && (ToggleComment()))
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -160,6 +160,8 @@ namespace IDE.ui
|
||||||
{
|
{
|
||||||
public int32 mCursorPos;
|
public int32 mCursorPos;
|
||||||
public String mResult ~ delete _;
|
public String mResult ~ delete _;
|
||||||
|
public int32? mLine;
|
||||||
|
public int32? mLineChar;
|
||||||
|
|
||||||
public ~this()
|
public ~this()
|
||||||
{
|
{
|
||||||
|
@ -621,6 +623,10 @@ namespace IDE.ui
|
||||||
//Classify(options.HasFlag(.HighPriority) ? ResolveType.Autocomplete_HighPri : ResolveType.Autocomplete);
|
//Classify(options.HasFlag(.HighPriority) ? ResolveType.Autocomplete_HighPri : ResolveType.Autocomplete);
|
||||||
|
|
||||||
ResolveParams resolveParams = new ResolveParams();
|
ResolveParams resolveParams = new ResolveParams();
|
||||||
|
if (gApp.mDbgTimeAutocomplete)
|
||||||
|
resolveParams.mStopwatch = new .()..Start();
|
||||||
|
if (gApp.mDbgPerfAutocomplete)
|
||||||
|
resolveParams.mProfileInstance = Profiler.StartSampling("Autocomplete").GetValueOrDefault();
|
||||||
resolveParams.mIsUserRequested = options.HasFlag(.UserRequested);
|
resolveParams.mIsUserRequested = options.HasFlag(.UserRequested);
|
||||||
resolveParams.mDoFuzzyAutoComplete = gApp.mSettings.mEditorSettings.mFuzzyAutoComplete;
|
resolveParams.mDoFuzzyAutoComplete = gApp.mSettings.mEditorSettings.mFuzzyAutoComplete;
|
||||||
Classify(.Autocomplete, resolveParams);
|
Classify(.Autocomplete, resolveParams);
|
||||||
|
@ -1186,7 +1192,7 @@ namespace IDE.ui
|
||||||
//if (mCurParser != null)
|
//if (mCurParser != null)
|
||||||
{
|
{
|
||||||
if (gApp.mWorkspace.mProjectLoadState != .Loaded)
|
if (gApp.mWorkspace.mProjectLoadState != .Loaded)
|
||||||
return false;
|
return true;
|
||||||
|
|
||||||
if (!isHi)
|
if (!isHi)
|
||||||
Debug.Assert(!mIsPerformingBackgroundClassify);
|
Debug.Assert(!mIsPerformingBackgroundClassify);
|
||||||
|
@ -2336,6 +2342,11 @@ namespace IDE.ui
|
||||||
if (mDisposed)
|
if (mDisposed)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (mProjectSource?.mEditData?.HasTextChanged() == true)
|
||||||
|
{
|
||||||
|
mProjectSource.ClearEditData();
|
||||||
|
}
|
||||||
|
|
||||||
ProcessDeferredResolveResults(-1);
|
ProcessDeferredResolveResults(-1);
|
||||||
|
|
||||||
if (IDEApp.sApp.mLastActiveSourceViewPanel == this)
|
if (IDEApp.sApp.mLastActiveSourceViewPanel == this)
|
||||||
|
@ -4725,7 +4736,7 @@ namespace IDE.ui
|
||||||
delete parser;
|
delete parser;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void UpdateMouseover(bool mouseoverFired, bool mouseInbounds, int line, int lineChar)
|
public void UpdateMouseover(bool mouseoverFired, bool mouseInbounds, int line, int lineChar, bool isManual = false)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
|
@ -5011,6 +5022,11 @@ namespace IDE.ui
|
||||||
|
|
||||||
mHoverResolveTask = new HoverResolveTask();
|
mHoverResolveTask = new HoverResolveTask();
|
||||||
mHoverResolveTask.mCursorPos = (int32)textIdx;
|
mHoverResolveTask.mCursorPos = (int32)textIdx;
|
||||||
|
if (isManual)
|
||||||
|
{
|
||||||
|
mHoverResolveTask.mLine = (.)line;
|
||||||
|
mHoverResolveTask.mLineChar = (.)lineChar;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5204,6 +5220,16 @@ namespace IDE.ui
|
||||||
#if IDE_C_SUPPORT
|
#if IDE_C_SUPPORT
|
||||||
hasClangHoverErrorData = mClangHoverErrorData != null;
|
hasClangHoverErrorData = mClangHoverErrorData != null;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
if (mHoverResolveTask != null)
|
||||||
|
{
|
||||||
|
if (mHoverResolveTask.mLine != null)
|
||||||
|
{
|
||||||
|
UpdateMouseover(true, true, mHoverResolveTask.mLine.Value, mHoverResolveTask.mLineChar.Value, true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (((mouseoverFired) || (mHoverWatch != null) || (hasClangHoverErrorData) || (mHoverResolveTask?.mResult != null)) &&
|
if (((mouseoverFired) || (mHoverWatch != null) || (hasClangHoverErrorData) || (mHoverResolveTask?.mResult != null)) &&
|
||||||
(mousePos.x >= 0))
|
(mousePos.x >= 0))
|
||||||
{
|
{
|
||||||
|
@ -5526,6 +5552,13 @@ namespace IDE.ui
|
||||||
|
|
||||||
HandleResolveResult(resolveResult.mResolveType, resolveResult.mAutocompleteInfo, resolveResult);
|
HandleResolveResult(resolveResult.mResolveType, resolveResult.mAutocompleteInfo, resolveResult);
|
||||||
|
|
||||||
|
if (resolveResult.mStopwatch != null)
|
||||||
|
{
|
||||||
|
resolveResult.mStopwatch.Stop();
|
||||||
|
if (var autoComplete = GetAutoComplete())
|
||||||
|
Debug.WriteLine($"Autocomplete {resolveResult.mStopwatch.ElapsedMilliseconds}ms entries: {autoComplete.mAutoCompleteListWidget.mEntryList.Count}");
|
||||||
|
}
|
||||||
|
|
||||||
//Debug.WriteLine("ProcessDeferredResolveResults finished {0}", resolveResult.mResolveType);
|
//Debug.WriteLine("ProcessDeferredResolveResults finished {0}", resolveResult.mResolveType);
|
||||||
|
|
||||||
//bool checkIt = (mFilePath.Contains("Program.bf")) && (mEditWidget.mEditWidgetContent.mData.mCurTextVersionId > 3);
|
//bool checkIt = (mFilePath.Contains("Program.bf")) && (mEditWidget.mEditWidgetContent.mData.mCurTextVersionId > 3);
|
||||||
|
|
|
@ -2765,7 +2765,10 @@ namespace IDE.ui
|
||||||
{
|
{
|
||||||
String evalStr = scope String();
|
String evalStr = scope String();
|
||||||
CompactChildExpression(listViewItem, evalStr);
|
CompactChildExpression(listViewItem, evalStr);
|
||||||
evalStr.Insert(0, "&");
|
if (evalStr.StartsWith("*"))
|
||||||
|
evalStr.Remove(0, 1);
|
||||||
|
else
|
||||||
|
evalStr.Insert(0, "&");
|
||||||
gApp.mBreakpointPanel.CreateMemoryBreakpoint(evalStr);
|
gApp.mBreakpointPanel.CreateMemoryBreakpoint(evalStr);
|
||||||
gApp.MarkDirty();
|
gApp.MarkDirty();
|
||||||
});
|
});
|
||||||
|
|
|
@ -2171,6 +2171,8 @@ BeMCOperand BeMCContext::GetOperand(BeValue* value, bool allowMetaResult, bool a
|
||||||
auto vregInfo = GetVRegInfo(tlsVReg);
|
auto vregInfo = GetVRegInfo(tlsVReg);
|
||||||
vregInfo->mMustExist = true;
|
vregInfo->mMustExist = true;
|
||||||
vregInfo->mForceReg = true;
|
vregInfo->mForceReg = true;
|
||||||
|
vregInfo->mDisableR12 = true;
|
||||||
|
vregInfo->mDisableR13 = true;
|
||||||
mTLSVRegIdx = tlsVReg.mVRegIdx;
|
mTLSVRegIdx = tlsVReg.mVRegIdx;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15930,7 +15932,7 @@ void BeMCContext::Generate(BeFunction* function)
|
||||||
mDbgPreferredRegs[32] = X64Reg_R8;*/
|
mDbgPreferredRegs[32] = X64Reg_R8;*/
|
||||||
|
|
||||||
//mDbgPreferredRegs[8] = X64Reg_RAX;
|
//mDbgPreferredRegs[8] = X64Reg_RAX;
|
||||||
//mDebugging = (function->mName == "?Load@TestProgram@BeefTest@bf@@SA?AUHandle@23@XZ");
|
//mDebugging = (function->mName == "?InitThread@Foo@BeefTest@bf@@CA?AU?$Result@X@System@3@H@Z");
|
||||||
// || (function->mName == "?MethodA@TestProgram@BeefTest@bf@@CAXXZ");
|
// || (function->mName == "?MethodA@TestProgram@BeefTest@bf@@CAXXZ");
|
||||||
// || (function->mName == "?Hey@Blurg@bf@@SAXXZ")
|
// || (function->mName == "?Hey@Blurg@bf@@SAXXZ")
|
||||||
// ;
|
// ;
|
||||||
|
|
|
@ -122,7 +122,7 @@ if(MSVC)
|
||||||
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /W3 /GL /Od /Oi /Gy /EHsc")
|
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /W3 /GL /Od /Oi /Gy /EHsc")
|
||||||
endif(MSVC)
|
endif(MSVC)
|
||||||
if(NOT MSVC)
|
if(NOT MSVC)
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -fno-rtti -Wno-multichar -Wno-invalid-offsetof")
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++17 -fno-rtti -Wno-multichar -Wno-invalid-offsetof")
|
||||||
endif(NOT MSVC)
|
endif(NOT MSVC)
|
||||||
|
|
||||||
################ Files ################
|
################ Files ################
|
||||||
|
|
|
@ -360,6 +360,8 @@ BfCompiler::BfCompiler(BfSystem* bfSystem, bool isResolveOnly)
|
||||||
//mMaxInterfaceSlots = 16;
|
//mMaxInterfaceSlots = 16;
|
||||||
mMaxInterfaceSlots = -1;
|
mMaxInterfaceSlots = -1;
|
||||||
mInterfaceSlotCountChanged = false;
|
mInterfaceSlotCountChanged = false;
|
||||||
|
mLastHadComptimeRebuilds = false;
|
||||||
|
mHasComptimeRebuilds = false;
|
||||||
|
|
||||||
mHSPreserveIdx = 0;
|
mHSPreserveIdx = 0;
|
||||||
mCompileLogFP = NULL;
|
mCompileLogFP = NULL;
|
||||||
|
@ -825,7 +827,7 @@ void BfCompiler::GetTestMethods(BfVDataModule* bfModule, Array<TestMethod>& test
|
||||||
|
|
||||||
auto _CheckMethod = [&](BfTypeInstance* typeInstance, BfMethodInstance* methodInstance)
|
auto _CheckMethod = [&](BfTypeInstance* typeInstance, BfMethodInstance* methodInstance)
|
||||||
{
|
{
|
||||||
auto project = typeInstance->mTypeDef->mProject;
|
auto project = methodInstance->mMethodDef->mDeclaringType->mProject;
|
||||||
if (project->mTargetType != BfTargetType_BeefTest)
|
if (project->mTargetType != BfTargetType_BeefTest)
|
||||||
return;
|
return;
|
||||||
if (project != bfModule->mProject)
|
if (project != bfModule->mProject)
|
||||||
|
@ -913,7 +915,8 @@ void BfCompiler::EmitTestMethod(BfVDataModule* bfModule, Array<TestMethod>& test
|
||||||
auto methodInstance = testMethod.mMethodInstance;
|
auto methodInstance = testMethod.mMethodInstance;
|
||||||
auto typeInstance = methodInstance->GetOwner();
|
auto typeInstance = methodInstance->GetOwner();
|
||||||
testMethod.mName += bfModule->TypeToString(typeInstance);
|
testMethod.mName += bfModule->TypeToString(typeInstance);
|
||||||
testMethod.mName += ".";
|
if (!testMethod.mName.IsEmpty())
|
||||||
|
testMethod.mName += ".";
|
||||||
testMethod.mName += methodInstance->mMethodDef->mName;
|
testMethod.mName += methodInstance->mMethodDef->mName;
|
||||||
|
|
||||||
testMethod.mName += "\t";
|
testMethod.mName += "\t";
|
||||||
|
@ -1022,7 +1025,10 @@ void BfCompiler::EmitTestMethod(BfVDataModule* bfModule, Array<TestMethod>& test
|
||||||
{
|
{
|
||||||
for (int defaultIdx = 0; defaultIdx < (int)methodInstance->mDefaultValues.size(); defaultIdx++)
|
for (int defaultIdx = 0; defaultIdx < (int)methodInstance->mDefaultValues.size(); defaultIdx++)
|
||||||
{
|
{
|
||||||
auto castedVal = bfModule->Cast(methodInstance->mMethodDef->GetRefNode(), methodInstance->mDefaultValues[defaultIdx], methodInstance->GetParamType(defaultIdx));
|
auto constHolder = methodInstance->GetOwner()->mConstHolder;
|
||||||
|
auto defaultTypedValue = methodInstance->mDefaultValues[defaultIdx];
|
||||||
|
auto defaultVal = bfModule->ConstantToCurrent(constHolder->GetConstant(defaultTypedValue.mValue), constHolder, defaultTypedValue.mType);
|
||||||
|
auto castedVal = bfModule->Cast(methodInstance->mMethodDef->GetRefNode(), BfTypedValue(defaultVal, defaultTypedValue.mType), methodInstance->GetParamType(defaultIdx));
|
||||||
if (castedVal)
|
if (castedVal)
|
||||||
{
|
{
|
||||||
BfExprEvaluator exprEvaluator(bfModule);
|
BfExprEvaluator exprEvaluator(bfModule);
|
||||||
|
@ -2927,7 +2933,7 @@ void BfCompiler::GenerateDynCastData()
|
||||||
|
|
||||||
void BfCompiler::UpdateRevisedTypes()
|
void BfCompiler::UpdateRevisedTypes()
|
||||||
{
|
{
|
||||||
BfLogSysM("UpdateRevisedTypes\n");
|
BfLogSysM("BfCompiler::UpdateRevisedTypes\n");
|
||||||
BP_ZONE("BfCompiler::UpdateRevisedTypes");
|
BP_ZONE("BfCompiler::UpdateRevisedTypes");
|
||||||
|
|
||||||
// See if we have any name conflicts and remove those
|
// See if we have any name conflicts and remove those
|
||||||
|
@ -6561,6 +6567,7 @@ bool BfCompiler::DoCompile(const StringImpl& outputDirectory)
|
||||||
|
|
||||||
// Inc revision for next run through Compile
|
// Inc revision for next run through Compile
|
||||||
mRevision++;
|
mRevision++;
|
||||||
|
mHasComptimeRebuilds = false;
|
||||||
int revision = mRevision;
|
int revision = mRevision;
|
||||||
BfLogSysM("Compile Start. Revision: %d. HasParser:%d AutoComplete:%d\n", revision,
|
BfLogSysM("Compile Start. Revision: %d. HasParser:%d AutoComplete:%d\n", revision,
|
||||||
(mResolvePassData != NULL) && (mResolvePassData->mParser != NULL),
|
(mResolvePassData != NULL) && (mResolvePassData->mParser != NULL),
|
||||||
|
@ -7021,27 +7028,34 @@ bool BfCompiler::DoCompile(const StringImpl& outputDirectory)
|
||||||
|
|
||||||
if (hasTests)
|
if (hasTests)
|
||||||
{
|
{
|
||||||
|
HashSet<BfProject*> projectSet;
|
||||||
|
|
||||||
for (auto type : mContext->mResolvedTypes)
|
for (auto type : mContext->mResolvedTypes)
|
||||||
{
|
{
|
||||||
auto typeInstance = type->ToTypeInstance();
|
auto typeInstance = type->ToTypeInstance();
|
||||||
if ((typeInstance != NULL) &&
|
if (typeInstance != NULL)
|
||||||
(typeInstance->mTypeDef->mProject->mTargetType == BfTargetType_BeefTest))
|
|
||||||
{
|
{
|
||||||
bool typeHasTest = false;
|
|
||||||
for (auto& methodInstanceGroup : typeInstance->mMethodInstanceGroups)
|
for (auto& methodInstanceGroup : typeInstance->mMethodInstanceGroups)
|
||||||
{
|
{
|
||||||
if (methodInstanceGroup.mDefault != NULL)
|
if (methodInstanceGroup.mDefault != NULL)
|
||||||
{
|
{
|
||||||
auto methodInstance = methodInstanceGroup.mDefault;
|
auto methodInstance = methodInstanceGroup.mDefault;
|
||||||
|
auto project = methodInstance->mMethodDef->mDeclaringType->mProject;
|
||||||
|
if (project->mTargetType != BfTargetType_BeefTest)
|
||||||
|
continue;
|
||||||
if ((methodInstance->GetCustomAttributes() != NULL) &&
|
if ((methodInstance->GetCustomAttributes() != NULL) &&
|
||||||
(methodInstance->GetCustomAttributes()->Contains(mTestAttributeTypeDef)))
|
(methodInstance->GetCustomAttributes()->Contains(mTestAttributeTypeDef)))
|
||||||
{
|
{
|
||||||
typeHasTest = true;
|
projectSet.Add(project);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (typeHasTest)
|
if (!projectSet.IsEmpty())
|
||||||
mContext->MarkUsedModules(typeInstance->mTypeDef->mProject, typeInstance->mModule);
|
{
|
||||||
|
for (auto project : projectSet)
|
||||||
|
mContext->MarkUsedModules(project, typeInstance->mModule);
|
||||||
|
projectSet.Clear();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7494,6 +7508,11 @@ bool BfCompiler::DoCompile(const StringImpl& outputDirectory)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (didCancel)
|
||||||
|
mLastHadComptimeRebuilds = mHasComptimeRebuilds || mLastHadComptimeRebuilds;
|
||||||
|
else
|
||||||
|
mLastHadComptimeRebuilds = mHasComptimeRebuilds;
|
||||||
|
|
||||||
return !didCancel && !mHasQueuedTypeRebuilds;
|
return !didCancel && !mHasQueuedTypeRebuilds;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9104,6 +9123,11 @@ BF_EXPORT int BF_CALLTYPE BfCompiler_GetCurConstEvalExecuteId(BfCompiler* bfComp
|
||||||
return bfCompiler->mCEMachine->mExecuteId;
|
return bfCompiler->mCEMachine->mExecuteId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BF_EXPORT float BF_CALLTYPE BfCompiler_GetLastHadComptimeRebuilds(BfCompiler* bfCompiler)
|
||||||
|
{
|
||||||
|
return bfCompiler->mLastHadComptimeRebuilds;
|
||||||
|
}
|
||||||
|
|
||||||
BF_EXPORT void BF_CALLTYPE BfCompiler_Cancel(BfCompiler* bfCompiler)
|
BF_EXPORT void BF_CALLTYPE BfCompiler_Cancel(BfCompiler* bfCompiler)
|
||||||
{
|
{
|
||||||
bfCompiler->Cancel();
|
bfCompiler->Cancel();
|
||||||
|
|
|
@ -329,6 +329,8 @@ public:
|
||||||
bool mHasQueuedTypeRebuilds; // Infers we had a fast finish that requires a type rebuild
|
bool mHasQueuedTypeRebuilds; // Infers we had a fast finish that requires a type rebuild
|
||||||
bool mHadCancel;
|
bool mHadCancel;
|
||||||
bool mWantsDeferMethodDecls;
|
bool mWantsDeferMethodDecls;
|
||||||
|
bool mLastHadComptimeRebuilds;
|
||||||
|
bool mHasComptimeRebuilds;
|
||||||
bool mInInvalidState;
|
bool mInInvalidState;
|
||||||
float mCompletionPct;
|
float mCompletionPct;
|
||||||
int mHSPreserveIdx;
|
int mHSPreserveIdx;
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
#include "BfSourceClassifier.h"
|
#include "BfSourceClassifier.h"
|
||||||
#include "BfAutoComplete.h"
|
#include "BfAutoComplete.h"
|
||||||
#include "BfResolvePass.h"
|
#include "BfResolvePass.h"
|
||||||
|
#include "CeMachine.h"
|
||||||
|
|
||||||
#pragma warning(pop)
|
#pragma warning(pop)
|
||||||
|
|
||||||
|
@ -1850,6 +1851,7 @@ void BfContext::PreUpdateRevisedTypes()
|
||||||
void BfContext::UpdateRevisedTypes()
|
void BfContext::UpdateRevisedTypes()
|
||||||
{
|
{
|
||||||
BP_ZONE("BfContext::UpdateRevisedTypes");
|
BP_ZONE("BfContext::UpdateRevisedTypes");
|
||||||
|
BfLogSysM("BfContext::UpdateRevisedTypes\n");
|
||||||
|
|
||||||
int wantPtrSize;
|
int wantPtrSize;
|
||||||
if ((mCompiler->mOptions.mMachineType == BfMachineType_x86) |
|
if ((mCompiler->mOptions.mMachineType == BfMachineType_x86) |
|
||||||
|
@ -1889,6 +1891,9 @@ void BfContext::UpdateRevisedTypes()
|
||||||
bool wantsDebugInfo = (mCompiler->mOptions.mEmitDebugInfo);
|
bool wantsDebugInfo = (mCompiler->mOptions.mEmitDebugInfo);
|
||||||
|
|
||||||
Array<BfTypeInstance*> defStateChangedQueue;
|
Array<BfTypeInstance*> defStateChangedQueue;
|
||||||
|
Array<BfTypeInstance*> defEmitParentCheckQueue;
|
||||||
|
|
||||||
|
Dictionary<String, uint64> lastWriteTimeMap;
|
||||||
|
|
||||||
// Do primary 'rebuild' scan
|
// Do primary 'rebuild' scan
|
||||||
for (auto type : mResolvedTypes)
|
for (auto type : mResolvedTypes)
|
||||||
|
@ -1918,19 +1923,7 @@ void BfContext::UpdateRevisedTypes()
|
||||||
auto typeDef = typeInst->mTypeDef;
|
auto typeDef = typeInst->mTypeDef;
|
||||||
|
|
||||||
if (typeDef->mEmitParent != NULL)
|
if (typeDef->mEmitParent != NULL)
|
||||||
{
|
defEmitParentCheckQueue.Add(typeInst);
|
||||||
if (typeDef->mDefState == BfTypeDef::DefState_Deleted)
|
|
||||||
{
|
|
||||||
typeInst->mTypeDef = typeDef->mEmitParent;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
auto emitTypeDef = typeDef;
|
|
||||||
typeDef = typeDef->mEmitParent;
|
|
||||||
if (typeDef->mNextRevision != NULL)
|
|
||||||
emitTypeDef->mDefState = BfTypeDef::DefState_EmittedDirty;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (typeDef->mProject->mDisabled)
|
if (typeDef->mProject->mDisabled)
|
||||||
{
|
{
|
||||||
|
@ -1948,6 +1941,32 @@ void BfContext::UpdateRevisedTypes()
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (typeInst->mCeTypeInfo != NULL)
|
||||||
|
{
|
||||||
|
bool changed = false;
|
||||||
|
|
||||||
|
for (auto& kv : typeInst->mCeTypeInfo->mRebuildMap)
|
||||||
|
{
|
||||||
|
mCompiler->mHasComptimeRebuilds = true;
|
||||||
|
if (kv.mKey.mKind == CeRebuildKey::Kind_File)
|
||||||
|
{
|
||||||
|
String* keyPtr = NULL;
|
||||||
|
uint64* valuePtr = NULL;
|
||||||
|
if (lastWriteTimeMap.TryAdd(kv.mKey.mString, &keyPtr, &valuePtr))
|
||||||
|
{
|
||||||
|
*valuePtr = BfpFile_GetTime_LastWrite(kv.mKey.mString.c_str());
|
||||||
|
}
|
||||||
|
if (*valuePtr != kv.mValue.mInt)
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (changed)
|
||||||
|
{
|
||||||
|
RebuildType(typeInst);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if ((typeInst->mHotTypeData != NULL) && (!mCompiler->IsHotCompile()))
|
if ((typeInst->mHotTypeData != NULL) && (!mCompiler->IsHotCompile()))
|
||||||
{
|
{
|
||||||
if (typeInst->mHotTypeData->GetLatestVersion()->mDeclHotCompileIdx != 0)
|
if (typeInst->mHotTypeData->GetLatestVersion()->mDeclHotCompileIdx != 0)
|
||||||
|
@ -2042,6 +2061,31 @@ void BfContext::UpdateRevisedTypes()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (auto typeInst : defEmitParentCheckQueue)
|
||||||
|
{
|
||||||
|
if (typeInst->IsDeleting())
|
||||||
|
continue;
|
||||||
|
auto typeDef = typeInst->mTypeDef;
|
||||||
|
if (typeDef->mEmitParent != NULL)
|
||||||
|
{
|
||||||
|
if (typeDef->mDefState == BfTypeDef::DefState_Deleted)
|
||||||
|
{
|
||||||
|
BfLogSysM("Type %p typeDef %p deleted, setting to emitParent %p\n", typeInst, typeDef, typeDef->mEmitParent);
|
||||||
|
typeInst->mTypeDef = typeDef->mEmitParent;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
auto emitTypeDef = typeDef;
|
||||||
|
typeDef = typeDef->mEmitParent;
|
||||||
|
if (typeDef->mNextRevision != NULL)
|
||||||
|
{
|
||||||
|
BfLogSysM("Type %p typeDef %p emitparent %p has next revision, setting emittedDirty\n", typeInst, emitTypeDef, typeDef);
|
||||||
|
emitTypeDef->mDefState = BfTypeDef::DefState_EmittedDirty;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
{
|
{
|
||||||
AutoCrit autoCrit(mSystem->mDataLock);
|
AutoCrit autoCrit(mSystem->mDataLock);
|
||||||
|
|
|
@ -4919,7 +4919,10 @@ BfTypedValue BfExprEvaluator::LookupField(BfAstNode* targetSrc, BfTypedValue tar
|
||||||
if ((autoComplete != NULL) && (autoComplete->IsAutocompleteNode(targetSrc)))
|
if ((autoComplete != NULL) && (autoComplete->IsAutocompleteNode(targetSrc)))
|
||||||
{
|
{
|
||||||
if (autoComplete->mIsGetDefinition)
|
if (autoComplete->mIsGetDefinition)
|
||||||
autoComplete->SetDefinitionLocation(basePropDef->GetRefNode(), true);
|
{
|
||||||
|
//NOTE: passing 'force=true' in here causes https://github.com/beefytech/Beef/issues/1064
|
||||||
|
autoComplete->SetDefinitionLocation(basePropDef->GetRefNode());
|
||||||
|
}
|
||||||
autoComplete->mDefProp = basePropDef;
|
autoComplete->mDefProp = basePropDef;
|
||||||
autoComplete->mDefType = baseTypeInst->mTypeDef;
|
autoComplete->mDefType = baseTypeInst->mTypeDef;
|
||||||
}
|
}
|
||||||
|
@ -6990,6 +6993,24 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, const BfTypedValu
|
||||||
argValue = BfTypedValue(mModule->GetStringObjectValue(GetFileDir(filePath)),
|
argValue = BfTypedValue(mModule->GetStringObjectValue(GetFileDir(filePath)),
|
||||||
mModule->ResolveTypeDef(mModule->mCompiler->mStringTypeDef));
|
mModule->ResolveTypeDef(mModule->mCompiler->mStringTypeDef));
|
||||||
}
|
}
|
||||||
|
else if (strcmp(globalVar->mName, "#CallerTypeName") == 0)
|
||||||
|
{
|
||||||
|
String typeName = "";
|
||||||
|
if (mModule->mCurTypeInstance != NULL)
|
||||||
|
typeName = mModule->TypeToString(mModule->mCurTypeInstance);
|
||||||
|
argValue = BfTypedValue(mModule->GetStringObjectValue(typeName),
|
||||||
|
mModule->ResolveTypeDef(mModule->mCompiler->mStringTypeDef));
|
||||||
|
}
|
||||||
|
else if (strcmp(globalVar->mName, "#CallerType") == 0)
|
||||||
|
{
|
||||||
|
auto typeType = mModule->ResolveTypeDef(mModule->mCompiler->mTypeTypeDef);
|
||||||
|
BfType* type = mModule->mCurTypeInstance;
|
||||||
|
if (type != NULL)
|
||||||
|
{
|
||||||
|
mModule->AddDependency(type, mModule->mCurTypeInstance, BfDependencyMap::DependencyFlag_ExprTypeReference);
|
||||||
|
argValue = BfTypedValue(mModule->CreateTypeDataRef(type), typeType);
|
||||||
|
}
|
||||||
|
}
|
||||||
else if (strcmp(globalVar->mName, "#CallerMemberName") == 0)
|
else if (strcmp(globalVar->mName, "#CallerMemberName") == 0)
|
||||||
{
|
{
|
||||||
String memberName = "";
|
String memberName = "";
|
||||||
|
@ -7095,7 +7116,11 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, const BfTypedValu
|
||||||
if (methodRefType->WantsDataPassedAsSplat(dataIdx))
|
if (methodRefType->WantsDataPassedAsSplat(dataIdx))
|
||||||
SplatArgs(lookupVal, irArgs);
|
SplatArgs(lookupVal, irArgs);
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
if (lookupVal.mType->IsComposite())
|
||||||
|
lookupVal = mModule->MakeAddressable(lookupVal, false);
|
||||||
irArgs.push_back(lookupVal.mValue);
|
irArgs.push_back(lookupVal.mValue);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10182,6 +10207,17 @@ void BfExprEvaluator::Visit(BfInitializerExpression* initExpr)
|
||||||
|
|
||||||
if ((fieldResult) || (mPropDef != NULL))
|
if ((fieldResult) || (mPropDef != NULL))
|
||||||
{
|
{
|
||||||
|
if (mResultFieldInstance != NULL)
|
||||||
|
{
|
||||||
|
auto autoComplete = GetAutoComplete();
|
||||||
|
if ((autoComplete != NULL) && (autoComplete->IsAutocompleteNode(identifierNode)))
|
||||||
|
{
|
||||||
|
auto fieldDef = mResultFieldInstance->GetFieldDef();
|
||||||
|
if (fieldDef != NULL)
|
||||||
|
autoComplete->SetDefinitionLocation(fieldDef->GetRefNode());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
mResult = fieldResult;
|
mResult = fieldResult;
|
||||||
PerformAssignment(assignExpr, true, BfTypedValue());
|
PerformAssignment(assignExpr, true, BfTypedValue());
|
||||||
mResult = BfTypedValue();
|
mResult = BfTypedValue();
|
||||||
|
@ -11463,8 +11499,7 @@ BfTypedValue BfExprEvaluator::DoImplicitArgCapture(BfAstNode* refNode, BfMethodI
|
||||||
return lookupVal;
|
return lookupVal;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
BF_ASSERT(methodRefTarget.IsAddr());
|
if ((paramType->IsComposite()) && (methodRefTarget.IsAddr()))
|
||||||
if (paramType->IsComposite())
|
|
||||||
return BfTypedValue(mModule->mBfIRBuilder->CreateInBoundsGEP(methodRefTarget.mValue, 0, dataIdx), paramType, true);
|
return BfTypedValue(mModule->mBfIRBuilder->CreateInBoundsGEP(methodRefTarget.mValue, 0, dataIdx), paramType, true);
|
||||||
return BfTypedValue(mModule->ExtractValue(methodRefTarget, dataIdx), paramType);
|
return BfTypedValue(mModule->ExtractValue(methodRefTarget, dataIdx), paramType);
|
||||||
}
|
}
|
||||||
|
@ -11922,7 +11957,7 @@ void BfExprEvaluator::Visit(BfDelegateBindExpression* delegateBindExpr)
|
||||||
if (bindResult.mTarget.IsSplat())
|
if (bindResult.mTarget.IsSplat())
|
||||||
target = mModule->AggregateSplat(bindResult.mTarget, &bindResult.mIRArgs[0]);
|
target = mModule->AggregateSplat(bindResult.mTarget, &bindResult.mIRArgs[0]);
|
||||||
else
|
else
|
||||||
target = mModule->LoadValue(bindResult.mTarget);
|
target = bindResult.mTarget;
|
||||||
|
|
||||||
mModule->mBfIRBuilder->CreateStore(target.mValue, elemPtr);
|
mModule->mBfIRBuilder->CreateStore(target.mValue, elemPtr);
|
||||||
|
|
||||||
|
@ -14525,8 +14560,10 @@ void BfExprEvaluator::CreateObject(BfObjectCreateExpression* objCreateExpr, BfAs
|
||||||
{
|
{
|
||||||
if (typeInstance->IsObject())
|
if (typeInstance->IsObject())
|
||||||
{
|
{
|
||||||
|
bool hasRealtimeLeakCheck = (mModule->mCompiler->mOptions.mEnableRealtimeLeakCheck) && (!IsComptime());
|
||||||
|
|
||||||
bool wantsCtorClear = true;
|
bool wantsCtorClear = true;
|
||||||
if (mModule->mCompiler->mOptions.mEnableRealtimeLeakCheck)
|
if (hasRealtimeLeakCheck)
|
||||||
{
|
{
|
||||||
// Dbg_ObjectAlloc clears internally so we don't need to call CtorClear for those
|
// Dbg_ObjectAlloc clears internally so we don't need to call CtorClear for those
|
||||||
if ((!isStackAlloc) && (!allocTarget.mCustomAllocator) && (allocTarget.mScopedInvocationTarget == NULL))
|
if ((!isStackAlloc) && (!allocTarget.mCustomAllocator) && (allocTarget.mScopedInvocationTarget == NULL))
|
||||||
|
@ -14548,7 +14585,7 @@ void BfExprEvaluator::CreateObject(BfObjectCreateExpression* objCreateExpr, BfAs
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((!mModule->mIsComptimeModule) && (isStackAlloc) && (mModule->mCompiler->mOptions.mEnableRealtimeLeakCheck))
|
if ((!mModule->mIsComptimeModule) && (isStackAlloc) && (hasRealtimeLeakCheck))
|
||||||
{
|
{
|
||||||
BfMethodInstance* markMethod = mModule->GetRawMethodByName(mModule->mContext->mBfObjectType, "GCMarkMembers");
|
BfMethodInstance* markMethod = mModule->GetRawMethodByName(mModule->mContext->mBfObjectType, "GCMarkMembers");
|
||||||
BF_ASSERT(markMethod != NULL);
|
BF_ASSERT(markMethod != NULL);
|
||||||
|
@ -14750,7 +14787,7 @@ BfAllocTarget BfExprEvaluator::ResolveAllocTarget(BfAstNode* allocNode, BfTokenN
|
||||||
|
|
||||||
if (attributeDirective != NULL)
|
if (attributeDirective != NULL)
|
||||||
{
|
{
|
||||||
auto customAttrs = mModule->GetCustomAttributes(attributeDirective, BfAttributeTargets_Alloc, true, &allocTarget.mCaptureInfo);
|
auto customAttrs = mModule->GetCustomAttributes(attributeDirective, BfAttributeTargets_Alloc, BfGetCustomAttributesFlags_AllowNonConstArgs, &allocTarget.mCaptureInfo);
|
||||||
if (customAttrs != NULL)
|
if (customAttrs != NULL)
|
||||||
{
|
{
|
||||||
for (auto& attrib : customAttrs->mAttributes)
|
for (auto& attrib : customAttrs->mAttributes)
|
||||||
|
@ -19750,7 +19787,7 @@ void BfExprEvaluator::Visit(BfIndexerExpression* indexerExpr)
|
||||||
|
|
||||||
auto indexType = (BfPrimitiveType*)indexArgument.mType;
|
auto indexType = (BfPrimitiveType*)indexArgument.mType;
|
||||||
|
|
||||||
if (!mModule->mSystem->DoesLiteralFit(indexType->mTypeDef->mTypeCode, sizedArrayType->mElementCount))
|
if (!mModule->mSystem->DoesLiteralFit(indexType->mTypeDef->mTypeCode, (int64)sizedArrayType->mElementCount))
|
||||||
{
|
{
|
||||||
// We need to upsize the index so we can compare it against the larger elementCount
|
// We need to upsize the index so we can compare it against the larger elementCount
|
||||||
indexType = mModule->GetPrimitiveType(BfTypeCode_IntPtr);
|
indexType = mModule->GetPrimitiveType(BfTypeCode_IntPtr);
|
||||||
|
@ -22427,6 +22464,8 @@ void BfExprEvaluator::PerformBinaryOperation(BfType* resultType, BfIRValue convL
|
||||||
mResult = BfTypedValue(mModule->mBfIRBuilder->CreateConst(BfTypeCode_Boolean, 0),
|
mResult = BfTypedValue(mModule->mBfIRBuilder->CreateConst(BfTypeCode_Boolean, 0),
|
||||||
mModule->GetPrimitiveType(BfTypeCode_Boolean));
|
mModule->GetPrimitiveType(BfTypeCode_Boolean));
|
||||||
return;
|
return;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -22438,6 +22477,7 @@ void BfExprEvaluator::PerformBinaryOperation(BfType* resultType, BfIRValue convL
|
||||||
auto primType = (BfPrimitiveType*)resultType;
|
auto primType = (BfPrimitiveType*)resultType;
|
||||||
if (primType->mTypeDef->mTypeCode == BfTypeCode_Boolean)
|
if (primType->mTypeDef->mTypeCode == BfTypeCode_Boolean)
|
||||||
{
|
{
|
||||||
|
bool passThrough = false;
|
||||||
switch (binaryOp)
|
switch (binaryOp)
|
||||||
{
|
{
|
||||||
case BfBinaryOp_Equality:
|
case BfBinaryOp_Equality:
|
||||||
|
@ -22464,16 +22504,20 @@ void BfExprEvaluator::PerformBinaryOperation(BfType* resultType, BfIRValue convL
|
||||||
mResult = BfTypedValue(mModule->mBfIRBuilder->CreateXor(convLeftValue, convRightValue),
|
mResult = BfTypedValue(mModule->mBfIRBuilder->CreateXor(convLeftValue, convRightValue),
|
||||||
mModule->GetPrimitiveType(BfTypeCode_Boolean));
|
mModule->GetPrimitiveType(BfTypeCode_Boolean));
|
||||||
break;
|
break;
|
||||||
|
case BfBinaryOp_Compare:
|
||||||
|
passThrough = true;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
if (mModule->PreFail())
|
if (mModule->PreFail())
|
||||||
mModule->Fail("Invalid operation for booleans", opToken);
|
mModule->Fail("Invalid operation for booleans", opToken);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return;
|
if (!passThrough)
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((!resultType->IsIntegral()) && (!resultType->IsFloat()))
|
if ((!resultType->IsIntegralOrBool()) && (!resultType->IsFloat()))
|
||||||
{
|
{
|
||||||
if (mModule->PreFail())
|
if (mModule->PreFail())
|
||||||
mModule->Fail(StrFormat("Cannot perform operation on type '%s'", mModule->TypeToString(resultType).c_str()), opToken);
|
mModule->Fail(StrFormat("Cannot perform operation on type '%s'", mModule->TypeToString(resultType).c_str()), opToken);
|
||||||
|
@ -22599,7 +22643,7 @@ void BfExprEvaluator::PerformBinaryOperation(BfType* resultType, BfIRValue convL
|
||||||
mResult = BfTypedValue(mModule->GetConstValue(0, mModule->GetPrimitiveType(BfTypeCode_IntPtr)), intType);
|
mResult = BfTypedValue(mModule->GetConstValue(0, mModule->GetPrimitiveType(BfTypeCode_IntPtr)), intType);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if ((resultType->IsIntegral()) && (resultType->mSize < intType->mSize))
|
else if ((resultType->IsIntegralOrBool()) && (resultType->mSize < intType->mSize))
|
||||||
{
|
{
|
||||||
auto leftIntValue = mModule->mBfIRBuilder->CreateNumericCast(convLeftValue, resultType->IsSigned(), BfTypeCode_IntPtr);
|
auto leftIntValue = mModule->mBfIRBuilder->CreateNumericCast(convLeftValue, resultType->IsSigned(), BfTypeCode_IntPtr);
|
||||||
auto rightIntValue = mModule->mBfIRBuilder->CreateNumericCast(convRightValue, resultType->IsSigned(), BfTypeCode_IntPtr);
|
auto rightIntValue = mModule->mBfIRBuilder->CreateNumericCast(convRightValue, resultType->IsSigned(), BfTypeCode_IntPtr);
|
||||||
|
|
|
@ -2627,9 +2627,13 @@ void BfIRBuilder::CreateTypeDeclaration(BfType* type, bool forceDbgDefine)
|
||||||
BfMethodInstance* methodInstance = methodRefType->mMethodRef;
|
BfMethodInstance* methodInstance = methodRefType->mMethodRef;
|
||||||
|
|
||||||
String name = "_BF_MethodRef_";
|
String name = "_BF_MethodRef_";
|
||||||
name += BfTypeUtils::HashEncode64(methodInstance->mIdHash).c_str();
|
|
||||||
|
|
||||||
if (wantDIData)
|
if (methodInstance != NULL)
|
||||||
|
name += BfTypeUtils::HashEncode64(methodInstance->mIdHash).c_str();
|
||||||
|
|
||||||
|
BF_ASSERT(methodInstance != NULL);
|
||||||
|
|
||||||
|
if ((wantDIData) && (methodInstance != NULL))
|
||||||
{
|
{
|
||||||
auto typeDeclaration = methodInstance->GetOwner()->mTypeDef->mTypeDeclaration;
|
auto typeDeclaration = methodInstance->GetOwner()->mTypeDef->mTypeDeclaration;
|
||||||
|
|
||||||
|
|
|
@ -3913,7 +3913,7 @@ void BfModule::ResolveConstField(BfTypeInstance* typeInstance, BfFieldInstance*
|
||||||
if (isLet || isVar)
|
if (isLet || isVar)
|
||||||
fieldType = GetPrimitiveType(BfTypeCode_Var);
|
fieldType = GetPrimitiveType(BfTypeCode_Var);
|
||||||
else
|
else
|
||||||
fieldType = ResolveTypeRef(fieldDef->mTypeRef);
|
fieldType = ResolveTypeRef(fieldDef->mTypeRef,BfPopulateType_Identity, BfResolveTypeRefFlag_AllowInferredSizedArray);
|
||||||
if (fieldType == NULL)
|
if (fieldType == NULL)
|
||||||
fieldType = mContext->mBfObjectType;
|
fieldType = mContext->mBfObjectType;
|
||||||
}
|
}
|
||||||
|
@ -6368,7 +6368,8 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary<int, int>& usedStrin
|
||||||
FieldFlags_Const = 0x40,
|
FieldFlags_Const = 0x40,
|
||||||
FieldFlags_SpecialName = 0x80,
|
FieldFlags_SpecialName = 0x80,
|
||||||
FieldFlags_EnumPayload = 0x100,
|
FieldFlags_EnumPayload = 0x100,
|
||||||
FieldFlags_EnumDiscriminator = 0x200
|
FieldFlags_EnumDiscriminator = 0x200,
|
||||||
|
FieldFlags_EnumCase = 0x400
|
||||||
};
|
};
|
||||||
|
|
||||||
if ((typeInstance->IsPayloadEnum()) && (!typeInstance->IsBoxed()))
|
if ((typeInstance->IsPayloadEnum()) && (!typeInstance->IsBoxed()))
|
||||||
|
@ -6434,6 +6435,8 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary<int, int>& usedStrin
|
||||||
fieldFlags = (FieldFlags)(fieldFlags | FieldFlags_Static);
|
fieldFlags = (FieldFlags)(fieldFlags | FieldFlags_Static);
|
||||||
if (fieldDef->mIsConst)
|
if (fieldDef->mIsConst)
|
||||||
fieldFlags = (FieldFlags)(fieldFlags | FieldFlags_Const);
|
fieldFlags = (FieldFlags)(fieldFlags | FieldFlags_Const);
|
||||||
|
if (fieldDef->IsEnumCaseEntry())
|
||||||
|
fieldFlags = (FieldFlags)(fieldFlags | FieldFlags_EnumCase);
|
||||||
|
|
||||||
int customAttrIdx = _HandleCustomAttrs(fieldInstance->mCustomAttributes);
|
int customAttrIdx = _HandleCustomAttrs(fieldInstance->mCustomAttributes);
|
||||||
BfIRValue constValue;
|
BfIRValue constValue;
|
||||||
|
@ -7787,9 +7790,16 @@ bool BfModule::CheckGenericConstraints(const BfGenericParamSource& genericParamS
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (checkArgType->IsPointer())
|
||||||
|
{
|
||||||
|
auto ptrType = (BfPointerType*)checkArgType;
|
||||||
|
checkArgType = ptrType->mElementType;
|
||||||
|
}
|
||||||
|
|
||||||
if ((genericParamInst->mGenericParamFlags & BfGenericParamFlag_New) != 0)
|
if ((genericParamInst->mGenericParamFlags & BfGenericParamFlag_New) != 0)
|
||||||
{
|
{
|
||||||
bool canAlloc = false;
|
bool canAlloc = false;
|
||||||
|
|
||||||
if (auto checkTypeInst = checkArgType->ToTypeInstance())
|
if (auto checkTypeInst = checkArgType->ToTypeInstance())
|
||||||
{
|
{
|
||||||
if (checkTypeInst->IsObjectOrStruct())
|
if (checkTypeInst->IsObjectOrStruct())
|
||||||
|
@ -7859,12 +7869,6 @@ bool BfModule::CheckGenericConstraints(const BfGenericParamSource& genericParamS
|
||||||
if ((genericParamInst->mInterfaceConstraints.IsEmpty()) && (genericParamInst->mOperatorConstraints.IsEmpty()) && (genericParamInst->mTypeConstraint == NULL))
|
if ((genericParamInst->mInterfaceConstraints.IsEmpty()) && (genericParamInst->mOperatorConstraints.IsEmpty()) && (genericParamInst->mTypeConstraint == NULL))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if (checkArgType->IsPointer())
|
|
||||||
{
|
|
||||||
auto ptrType = (BfPointerType*)checkArgType;
|
|
||||||
checkArgType = ptrType->mElementType;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (genericParamInst->mTypeConstraint != NULL)
|
if (genericParamInst->mTypeConstraint != NULL)
|
||||||
{
|
{
|
||||||
bool constraintMatched = false;
|
bool constraintMatched = false;
|
||||||
|
@ -11143,8 +11147,11 @@ void BfModule::ValidateCustomAttributes(BfCustomAttributes* customAttributes, Bf
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void BfModule::GetCustomAttributes(BfCustomAttributes* customAttributes, BfAttributeDirective* attributesDirective, BfAttributeTargets attrTarget, bool allowNonConstArgs, BfCaptureInfo* captureInfo)
|
void BfModule::GetCustomAttributes(BfCustomAttributes* customAttributes, BfAttributeDirective* attributesDirective, BfAttributeTargets attrTarget, BfGetCustomAttributesFlags flags, BfCaptureInfo* captureInfo)
|
||||||
{
|
{
|
||||||
|
bool allowNonConstArgs = (flags & BfGetCustomAttributesFlags_AllowNonConstArgs) != 0;
|
||||||
|
bool keepConstsInModule = (flags & BfGetCustomAttributesFlags_KeepConstsInModule) != 0;
|
||||||
|
|
||||||
if (!mCompiler->mHasRequiredTypes)
|
if (!mCompiler->mHasRequiredTypes)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -11388,7 +11395,8 @@ void BfModule::GetCustomAttributes(BfCustomAttributes* customAttributes, BfAttri
|
||||||
BfTypedValue result = constResolver.Resolve(assignExpr->mRight, fieldTypeInst.mResolvedType, BfConstResolveFlag_NoActualizeValues);
|
BfTypedValue result = constResolver.Resolve(assignExpr->mRight, fieldTypeInst.mResolvedType, BfConstResolveFlag_NoActualizeValues);
|
||||||
if (result)
|
if (result)
|
||||||
{
|
{
|
||||||
CurrentAddToConstHolder(result.mValue);
|
if (!keepConstsInModule)
|
||||||
|
CurrentAddToConstHolder(result.mValue);
|
||||||
setField.mParam = result;
|
setField.mParam = result;
|
||||||
customAttribute.mSetField.push_back(setField);
|
customAttribute.mSetField.push_back(setField);
|
||||||
}
|
}
|
||||||
|
@ -11450,7 +11458,8 @@ void BfModule::GetCustomAttributes(BfCustomAttributes* customAttributes, BfAttri
|
||||||
if (!result.mValue.IsConst())
|
if (!result.mValue.IsConst())
|
||||||
result = GetDefaultTypedValue(result.mType);
|
result = GetDefaultTypedValue(result.mType);
|
||||||
BF_ASSERT(result.mType == propType);
|
BF_ASSERT(result.mType == propType);
|
||||||
CurrentAddToConstHolder(result.mValue);
|
if (!keepConstsInModule)
|
||||||
|
CurrentAddToConstHolder(result.mValue);
|
||||||
setProperty.mParam = result;
|
setProperty.mParam = result;
|
||||||
customAttribute.mSetProperties.push_back(setProperty);
|
customAttribute.mSetProperties.push_back(setProperty);
|
||||||
}
|
}
|
||||||
|
@ -11566,10 +11575,13 @@ void BfModule::GetCustomAttributes(BfCustomAttributes* customAttributes, BfAttri
|
||||||
}
|
}
|
||||||
|
|
||||||
// Move all those to the constHolder
|
// Move all those to the constHolder
|
||||||
for (auto& ctorArg : customAttribute.mCtorArgs)
|
if (!keepConstsInModule)
|
||||||
{
|
{
|
||||||
if (ctorArg.IsConst())
|
for (auto& ctorArg : customAttribute.mCtorArgs)
|
||||||
CurrentAddToConstHolder(ctorArg);
|
{
|
||||||
|
if (ctorArg.IsConst())
|
||||||
|
CurrentAddToConstHolder(ctorArg);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (attributesDirective->mAttributeTargetSpecifier != NULL)
|
if (attributesDirective->mAttributeTargetSpecifier != NULL)
|
||||||
|
@ -11626,10 +11638,10 @@ void BfModule::GetCustomAttributes(BfCustomAttributes* customAttributes, BfAttri
|
||||||
ValidateCustomAttributes(customAttributes, attrTarget);
|
ValidateCustomAttributes(customAttributes, attrTarget);
|
||||||
}
|
}
|
||||||
|
|
||||||
BfCustomAttributes* BfModule::GetCustomAttributes(BfAttributeDirective* attributesDirective, BfAttributeTargets attrType, bool allowNonConstArgs, BfCaptureInfo* captureInfo)
|
BfCustomAttributes* BfModule::GetCustomAttributes(BfAttributeDirective* attributesDirective, BfAttributeTargets attrType, BfGetCustomAttributesFlags flags, BfCaptureInfo* captureInfo)
|
||||||
{
|
{
|
||||||
BfCustomAttributes* customAttributes = new BfCustomAttributes();
|
BfCustomAttributes* customAttributes = new BfCustomAttributes();
|
||||||
GetCustomAttributes(customAttributes, attributesDirective, attrType, allowNonConstArgs, captureInfo);
|
GetCustomAttributes(customAttributes, attributesDirective, attrType, flags, captureInfo);
|
||||||
return customAttributes;
|
return customAttributes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11834,7 +11846,7 @@ bool BfModule::TryGetConstString(BfIRConstHolder* constHolder, BfIRValue irValue
|
||||||
BfStringPoolEntry* entry = NULL;
|
BfStringPoolEntry* entry = NULL;
|
||||||
if (mContext->mStringObjectIdMap.TryGetValue(stringId, &entry))
|
if (mContext->mStringObjectIdMap.TryGetValue(stringId, &entry))
|
||||||
{
|
{
|
||||||
str = entry->mString;
|
str += entry->mString;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -15479,7 +15491,11 @@ void BfModule::CreateDelegateInvokeMethod()
|
||||||
|
|
||||||
mBfIRBuilder->AddBlock(doneBB);
|
mBfIRBuilder->AddBlock(doneBB);
|
||||||
mBfIRBuilder->SetInsertPoint(doneBB);
|
mBfIRBuilder->SetInsertPoint(doneBB);
|
||||||
if ((mCurMethodInstance->mReturnType->IsValuelessType()) ||
|
if (mCurMethodInstance->mReturnType->IsVar())
|
||||||
|
{
|
||||||
|
// Do nothing
|
||||||
|
}
|
||||||
|
else if ((mCurMethodInstance->mReturnType->IsValuelessType()) ||
|
||||||
((!mIsComptimeModule) && (mCurMethodInstance->GetStructRetIdx() != -1)))
|
((!mIsComptimeModule) && (mCurMethodInstance->GetStructRetIdx() != -1)))
|
||||||
{
|
{
|
||||||
mBfIRBuilder->CreateRetVoid();
|
mBfIRBuilder->CreateRetVoid();
|
||||||
|
@ -18477,6 +18493,11 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup)
|
||||||
{
|
{
|
||||||
BP_ZONE_F("BfModule::ProcessMethod %s", BP_DYN_STR(methodInstance->mMethodDef->mName.c_str()));
|
BP_ZONE_F("BfModule::ProcessMethod %s", BP_DYN_STR(methodInstance->mMethodDef->mName.c_str()));
|
||||||
|
|
||||||
|
if (mIsComptimeModule)
|
||||||
|
{
|
||||||
|
BF_ASSERT(!mCompiler->IsAutocomplete());
|
||||||
|
}
|
||||||
|
|
||||||
if (mAwaitingInitFinish)
|
if (mAwaitingInitFinish)
|
||||||
FinishInit();
|
FinishInit();
|
||||||
|
|
||||||
|
@ -21547,6 +21568,10 @@ void BfModule::GetMethodCustomAttributes(BfMethodInstance* methodInstance)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto delegateInfo = typeInstance->GetDelegateInfo();
|
||||||
|
if ((delegateInfo != NULL) && (methodInstance->mMethodDef->mMethodType == BfMethodType_Normal) && (methodInstance->mMethodDef->mName == "Invoke"))
|
||||||
|
methodInstance->mCallingConvention = delegateInfo->mCallingConvention;
|
||||||
}
|
}
|
||||||
|
|
||||||
void BfModule::SetupIRFunction(BfMethodInstance* methodInstance, StringImpl& mangledName, bool isTemporaryFunc, bool* outIsIntrinsic)
|
void BfModule::SetupIRFunction(BfMethodInstance* methodInstance, StringImpl& mangledName, bool isTemporaryFunc, bool* outIsIntrinsic)
|
||||||
|
@ -22157,6 +22182,13 @@ void BfModule::DoMethodDeclaration(BfMethodDeclaration* methodDeclaration, bool
|
||||||
|
|
||||||
if (resolvedReturnType == NULL)
|
if (resolvedReturnType == NULL)
|
||||||
resolvedReturnType = GetPrimitiveType(BfTypeCode_Var);
|
resolvedReturnType = GetPrimitiveType(BfTypeCode_Var);
|
||||||
|
|
||||||
|
if ((methodDef->mIsReadOnly) && (!resolvedReturnType->IsRef()))
|
||||||
|
{
|
||||||
|
if (auto methodDeclaration = BfNodeDynCast<BfMethodDeclaration>(methodInstance->mMethodDef->mMethodDeclaration))
|
||||||
|
if (methodDeclaration->mReadOnlySpecifier != NULL)
|
||||||
|
Fail("Readonly specifier is only valid on 'ref' return types", methodDeclaration->mReadOnlySpecifier);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -1383,6 +1383,13 @@ enum BfDeferredBlockFlags
|
||||||
BfDeferredBlockFlag_MoveNewBlocksToEnd = 8,
|
BfDeferredBlockFlag_MoveNewBlocksToEnd = 8,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum BfGetCustomAttributesFlags
|
||||||
|
{
|
||||||
|
BfGetCustomAttributesFlags_None = 0,
|
||||||
|
BfGetCustomAttributesFlags_AllowNonConstArgs = 1,
|
||||||
|
BfGetCustomAttributesFlags_KeepConstsInModule = 2
|
||||||
|
};
|
||||||
|
|
||||||
class BfVDataExtEntry
|
class BfVDataExtEntry
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -1567,8 +1574,8 @@ public:
|
||||||
BfTypedValue GetTypedValueFromConstant(BfConstant* constant, BfIRConstHolder* constHolder, BfType* wantType);
|
BfTypedValue GetTypedValueFromConstant(BfConstant* constant, BfIRConstHolder* constHolder, BfType* wantType);
|
||||||
BfIRValue ConstantToCurrent(BfConstant* constant, BfIRConstHolder* constHolder, BfType* wantType, bool allowUnactualized = false);
|
BfIRValue ConstantToCurrent(BfConstant* constant, BfIRConstHolder* constHolder, BfType* wantType, bool allowUnactualized = false);
|
||||||
void ValidateCustomAttributes(BfCustomAttributes* customAttributes, BfAttributeTargets attrTarget);
|
void ValidateCustomAttributes(BfCustomAttributes* customAttributes, BfAttributeTargets attrTarget);
|
||||||
void GetCustomAttributes(BfCustomAttributes* customAttributes, BfAttributeDirective* attributesDirective, BfAttributeTargets attrType, bool allowNonConstArgs = false, BfCaptureInfo* captureInfo = NULL);
|
void GetCustomAttributes(BfCustomAttributes* customAttributes, BfAttributeDirective* attributesDirective, BfAttributeTargets attrType, BfGetCustomAttributesFlags flags = BfGetCustomAttributesFlags_None, BfCaptureInfo* captureInfo = NULL);
|
||||||
BfCustomAttributes* GetCustomAttributes(BfAttributeDirective* attributesDirective, BfAttributeTargets attrType, bool allowNonConstArgs = false, BfCaptureInfo* captureInfo = NULL);
|
BfCustomAttributes* GetCustomAttributes(BfAttributeDirective* attributesDirective, BfAttributeTargets attrType, BfGetCustomAttributesFlags flags = BfGetCustomAttributesFlags_None, BfCaptureInfo* captureInfo = NULL);
|
||||||
BfCustomAttributes* GetCustomAttributes(BfTypeDef* typeDef);
|
BfCustomAttributes* GetCustomAttributes(BfTypeDef* typeDef);
|
||||||
void FinishAttributeState(BfAttributeState* attributeState);
|
void FinishAttributeState(BfAttributeState* attributeState);
|
||||||
void ProcessTypeInstCustomAttributes(bool& isPacked, bool& isUnion, bool& isCRepr, bool& isOrdered, int& alignOverride, BfType*& underlyingArrayType, int& underlyingArraySize);
|
void ProcessTypeInstCustomAttributes(bool& isPacked, bool& isUnion, bool& isCRepr, bool& isOrdered, int& alignOverride, BfType*& underlyingArrayType, int& underlyingArraySize);
|
||||||
|
@ -1744,13 +1751,15 @@ public:
|
||||||
void FinishCEParseContext(BfAstNode* refNode, BfTypeInstance* typeInstance, BfCEParseContext* ceParseContext);
|
void FinishCEParseContext(BfAstNode* refNode, BfTypeInstance* typeInstance, BfCEParseContext* ceParseContext);
|
||||||
BfCEParseContext CEEmitParse(BfTypeInstance* typeInstance, const StringImpl& src);
|
BfCEParseContext CEEmitParse(BfTypeInstance* typeInstance, const StringImpl& src);
|
||||||
void UpdateCEEmit(CeEmitContext* ceEmitContext, BfTypeInstance* typeInstance, const StringImpl& ctxString, BfAstNode* refNode);
|
void UpdateCEEmit(CeEmitContext* ceEmitContext, BfTypeInstance* typeInstance, const StringImpl& ctxString, BfAstNode* refNode);
|
||||||
void HandleCEAttributes(CeEmitContext* ceEmitContext, BfTypeInstance* typeInst, BfCustomAttributes* customAttributes, HashSet<BfTypeInstance*> foundAttributes);
|
void HandleCEAttributes(CeEmitContext* ceEmitContext, BfTypeInstance* typeInst, BfCustomAttributes* customAttributes, HashSet<BfTypeInstance*> foundAttributes, bool underlyingTypeDeferred);
|
||||||
void CEMixin(BfAstNode* refNode, const StringImpl& src);
|
void CEMixin(BfAstNode* refNode, const StringImpl& src);
|
||||||
void ExecuteCEOnCompile(CeEmitContext* ceEmitContext, BfTypeInstance* typeInst, BfCEOnCompileKind onCompileKind);
|
void ExecuteCEOnCompile(CeEmitContext* ceEmitContext, BfTypeInstance* typeInst, BfCEOnCompileKind onCompileKind, bool underlyingTypeDeferred);
|
||||||
void DoCEEmit(BfTypeInstance* typeInstance, bool& hadNewMembers);
|
void DoCEEmit(BfTypeInstance* typeInstance, bool& hadNewMembers, bool underlyingTypeDeferred);
|
||||||
void DoCEEmit(BfMethodInstance* methodInstance);
|
void DoCEEmit(BfMethodInstance* methodInstance);
|
||||||
void DoPopulateType_TypeAlias(BfTypeInstance* typeAlias);
|
void DoPopulateType_TypeAlias(BfTypeInstance* typeAlias);
|
||||||
void DoPopulateType_SetGenericDependencies(BfTypeInstance* genericTypeInstance);
|
void DoPopulateType_SetGenericDependencies(BfTypeInstance* genericTypeInstance);
|
||||||
|
void DoPopulateType_FinishEnum(BfTypeInstance* typeInstance, bool underlyingTypeDeferred, HashContext* dataMemberHashCtx, BfType* unionInnerType);
|
||||||
|
void DoPopulateType_CeCheckEnum(BfTypeInstance* typeInstance, bool underlyingTypeDeferred);
|
||||||
void DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateType = BfPopulateType_Data);
|
void DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateType = BfPopulateType_Data);
|
||||||
static BfModule* GetModuleFor(BfType* type);
|
static BfModule* GetModuleFor(BfType* type);
|
||||||
void DoTypeInstanceMethodProcessing(BfTypeInstance* typeInstance);
|
void DoTypeInstanceMethodProcessing(BfTypeInstance* typeInstance);
|
||||||
|
@ -1844,6 +1853,7 @@ public:
|
||||||
void CheckIdentifierFixit(BfAstNode* node);
|
void CheckIdentifierFixit(BfAstNode* node);
|
||||||
void TypeRefNotFound(BfTypeReference* typeRef, const char* appendName = NULL);
|
void TypeRefNotFound(BfTypeReference* typeRef, const char* appendName = NULL);
|
||||||
bool ValidateTypeWildcard(BfTypeReference* typeRef, bool isAttributeRef);
|
bool ValidateTypeWildcard(BfTypeReference* typeRef, bool isAttributeRef);
|
||||||
|
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, bool resolveGenericParam = true);
|
||||||
BfType* ResolveTypeRef(BfAstNode* astNode, const BfSizedArray<BfTypeReference*>* genericArgs, BfPopulateType populateType = BfPopulateType_Data, BfResolveTypeRefFlags resolveFlags = (BfResolveTypeRefFlags)0);
|
BfType* ResolveTypeRef(BfAstNode* astNode, const BfSizedArray<BfTypeReference*>* genericArgs, BfPopulateType populateType = BfPopulateType_Data, BfResolveTypeRefFlags resolveFlags = (BfResolveTypeRefFlags)0);
|
||||||
|
|
|
@ -704,23 +704,13 @@ void BfModule::InitType(BfType* resolvedTypeRef, BfPopulateType populateType)
|
||||||
|
|
||||||
void BfModule::AddFieldDependency(BfTypeInstance* typeInstance, BfFieldInstance* fieldInstance, BfType* fieldType)
|
void BfModule::AddFieldDependency(BfTypeInstance* typeInstance, BfFieldInstance* fieldInstance, BfType* fieldType)
|
||||||
{
|
{
|
||||||
auto fieldTypeInstance = fieldType->ToTypeInstance();
|
auto depFlag = fieldType->IsValueType() ? BfDependencyMap::DependencyFlag_ValueTypeMemberData : BfDependencyMap::DependencyFlag_PtrMemberData;
|
||||||
|
AddDependency(fieldType, typeInstance, depFlag);
|
||||||
|
|
||||||
if (fieldTypeInstance == NULL)
|
if ((fieldType->IsStruct()) && (fieldType->IsGenericTypeInstance()))
|
||||||
{
|
|
||||||
auto underlyingType = fieldType->GetUnderlyingType();
|
|
||||||
if (underlyingType != NULL)
|
|
||||||
AddFieldDependency(typeInstance, fieldInstance, underlyingType);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto depFlag = fieldTypeInstance->IsValueType() ? BfDependencyMap::DependencyFlag_ValueTypeMemberData : BfDependencyMap::DependencyFlag_PtrMemberData;
|
|
||||||
AddDependency(fieldTypeInstance, typeInstance, depFlag);
|
|
||||||
|
|
||||||
if ((fieldTypeInstance->IsStruct()) && (fieldTypeInstance->IsGenericTypeInstance()))
|
|
||||||
{
|
{
|
||||||
// When we're a generic struct, our data layout can depend on our generic parameters as well
|
// When we're a generic struct, our data layout can depend on our generic parameters as well
|
||||||
auto genericTypeInstance = (BfTypeInstance*)fieldTypeInstance;
|
auto genericTypeInstance = (BfTypeInstance*)fieldType;
|
||||||
for (auto typeGenericArg : genericTypeInstance->mGenericTypeInfo->mTypeGenericArguments)
|
for (auto typeGenericArg : genericTypeInstance->mGenericTypeInfo->mTypeGenericArguments)
|
||||||
AddFieldDependency(typeInstance, fieldInstance, typeGenericArg);
|
AddFieldDependency(typeInstance, fieldInstance, typeGenericArg);
|
||||||
}
|
}
|
||||||
|
@ -1189,7 +1179,10 @@ void BfModule::PopulateType(BfType* resolvedTypeRef, BfPopulateType populateType
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
BfLogSysM("PopulateType: %p %s populateType:%d ResolveOnly:%d Reified:%d AutoComplete:%d Ctx:%p Mod:%p TypeId:%d\n", resolvedTypeRef, TypeToString(resolvedTypeRef, BfTypeNameFlags_None).c_str(), populateType, mCompiler->mIsResolveOnly, mIsReified, mCompiler->IsAutocomplete(), mContext, this, resolvedTypeRef->mTypeId);
|
BfTypeDef* typeDef = NULL;
|
||||||
|
if (typeInstance != NULL)
|
||||||
|
typeDef = typeInstance->mTypeDef;
|
||||||
|
BfLogSysM("PopulateType: %p %s populateType:%d ResolveOnly:%d Reified:%d AutoComplete:%d Ctx:%p Mod:%p TypeId:%d TypeDef:%p\n", resolvedTypeRef, TypeToString(resolvedTypeRef, BfTypeNameFlags_None).c_str(), populateType, mCompiler->mIsResolveOnly, mIsReified, mCompiler->IsAutocomplete(), mContext, this, resolvedTypeRef->mTypeId, typeDef);
|
||||||
|
|
||||||
BF_ASSERT(!resolvedTypeRef->IsDeleting());
|
BF_ASSERT(!resolvedTypeRef->IsDeleting());
|
||||||
}
|
}
|
||||||
|
@ -2133,7 +2126,7 @@ void BfModule::UpdateCEEmit(CeEmitContext* ceEmitContext, BfTypeInstance* typeIn
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void BfModule::HandleCEAttributes(CeEmitContext* ceEmitContext, BfTypeInstance* typeInstance, BfCustomAttributes* customAttributes, HashSet<BfTypeInstance*> foundAttributes)
|
void BfModule::HandleCEAttributes(CeEmitContext* ceEmitContext, BfTypeInstance* typeInstance, BfCustomAttributes* customAttributes, HashSet<BfTypeInstance*> foundAttributes, bool underlyingTypeDeferred)
|
||||||
{
|
{
|
||||||
BfTypeInstance* iComptimeTypeApply = NULL;
|
BfTypeInstance* iComptimeTypeApply = NULL;
|
||||||
for (auto& customAttribute : customAttributes->mAttributes)
|
for (auto& customAttribute : customAttributes->mAttributes)
|
||||||
|
@ -2167,11 +2160,7 @@ void BfModule::HandleCEAttributes(CeEmitContext* ceEmitContext, BfTypeInstance*
|
||||||
args.Add(attrVal);
|
args.Add(attrVal);
|
||||||
args.Add(mBfIRBuilder->CreateTypeOf(typeInstance));
|
args.Add(mBfIRBuilder->CreateTypeOf(typeInstance));
|
||||||
|
|
||||||
//TESTING
|
DoPopulateType_CeCheckEnum(typeInstance, underlyingTypeDeferred);
|
||||||
// mCompiler->mCEMachine->ReleaseContext(ceContext);
|
|
||||||
// ceContext = mCompiler->mCEMachine->AllocContext();
|
|
||||||
// ceContext->mMemory.mSize = ceContext->mMemory.mAllocSize;
|
|
||||||
|
|
||||||
auto result = ceContext->Call(customAttribute.mRef, this, methodInstance, args, CeEvalFlags_None, NULL);
|
auto result = ceContext->Call(customAttribute.mRef, this, methodInstance, args, CeEvalFlags_None, NULL);
|
||||||
|
|
||||||
if (typeInstance->mDefineState == BfTypeDefineState_DefinedAndMethodsSlotted)
|
if (typeInstance->mDefineState == BfTypeDefineState_DefinedAndMethodsSlotted)
|
||||||
|
@ -2302,18 +2291,18 @@ void BfModule::CEMixin(BfAstNode* refNode, const StringImpl& code)
|
||||||
FinishCEParseContext(refNode, mCurTypeInstance, &ceParseContext);
|
FinishCEParseContext(refNode, mCurTypeInstance, &ceParseContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BfModule::ExecuteCEOnCompile(CeEmitContext* ceEmitContext, BfTypeInstance* typeInstance, BfCEOnCompileKind onCompileKind)
|
void BfModule::ExecuteCEOnCompile(CeEmitContext* ceEmitContext, BfTypeInstance* typeInstance, BfCEOnCompileKind onCompileKind, bool underlyingTypeDeferred)
|
||||||
{
|
{
|
||||||
HashSet<BfTypeInstance*> foundAttributes;
|
HashSet<BfTypeInstance*> foundAttributes;
|
||||||
if (ceEmitContext != NULL)
|
if (ceEmitContext != NULL)
|
||||||
{
|
{
|
||||||
if (typeInstance->mCustomAttributes != NULL)
|
if (typeInstance->mCustomAttributes != NULL)
|
||||||
HandleCEAttributes(ceEmitContext, typeInstance, typeInstance->mCustomAttributes, foundAttributes);
|
HandleCEAttributes(ceEmitContext, typeInstance, typeInstance->mCustomAttributes, foundAttributes, underlyingTypeDeferred);
|
||||||
|
|
||||||
for (auto& fieldInstance : typeInstance->mFieldInstances)
|
for (auto& fieldInstance : typeInstance->mFieldInstances)
|
||||||
{
|
{
|
||||||
if (fieldInstance.mCustomAttributes != NULL)
|
if (fieldInstance.mCustomAttributes != NULL)
|
||||||
HandleCEAttributes(ceEmitContext, typeInstance, fieldInstance.mCustomAttributes, foundAttributes);
|
HandleCEAttributes(ceEmitContext, typeInstance, fieldInstance.mCustomAttributes, foundAttributes, underlyingTypeDeferred);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2355,7 +2344,7 @@ void BfModule::ExecuteCEOnCompile(CeEmitContext* ceEmitContext, BfTypeInstance*
|
||||||
if (onCompileAttribute == NULL)
|
if (onCompileAttribute == NULL)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
HandleCEAttributes(ceEmitContext, typeInstance, customAttributes, foundAttributes);
|
HandleCEAttributes(ceEmitContext, typeInstance, customAttributes, foundAttributes, underlyingTypeDeferred);
|
||||||
|
|
||||||
if (onCompileAttribute->mCtorArgs.size() < 1)
|
if (onCompileAttribute->mCtorArgs.size() < 1)
|
||||||
continue;
|
continue;
|
||||||
|
@ -2383,6 +2372,7 @@ void BfModule::ExecuteCEOnCompile(CeEmitContext* ceEmitContext, BfTypeInstance*
|
||||||
mCompiler->mCEMachine->mCurEmitContext = ceEmitContext;
|
mCompiler->mCEMachine->mCurEmitContext = ceEmitContext;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DoPopulateType_CeCheckEnum(typeInstance, underlyingTypeDeferred);
|
||||||
auto methodInstance = GetRawMethodInstanceAtIdx(typeInstance, methodDef->mIdx);
|
auto methodInstance = GetRawMethodInstanceAtIdx(typeInstance, methodDef->mIdx);
|
||||||
auto result = mCompiler->mCEMachine->Call(methodDef->GetRefNode(), this, methodInstance, {}, (CeEvalFlags)(CeEvalFlags_PersistantError | CeEvalFlags_DeferIfNotOnlyError), NULL);
|
auto result = mCompiler->mCEMachine->Call(methodDef->GetRefNode(), this, methodInstance, {}, (CeEvalFlags)(CeEvalFlags_PersistantError | CeEvalFlags_DeferIfNotOnlyError), NULL);
|
||||||
|
|
||||||
|
@ -2451,11 +2441,11 @@ void BfModule::ExecuteCEOnCompile(CeEmitContext* ceEmitContext, BfTypeInstance*
|
||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
void BfModule::DoCEEmit(BfTypeInstance* typeInstance, bool& hadNewMembers)
|
void BfModule::DoCEEmit(BfTypeInstance* typeInstance, bool& hadNewMembers, bool underlyingTypeDeferred)
|
||||||
{
|
{
|
||||||
CeEmitContext ceEmitContext;
|
CeEmitContext ceEmitContext;
|
||||||
ceEmitContext.mType = typeInstance;
|
ceEmitContext.mType = typeInstance;
|
||||||
ExecuteCEOnCompile(&ceEmitContext, typeInstance, BfCEOnCompileKind_TypeInit);
|
ExecuteCEOnCompile(&ceEmitContext, typeInstance, BfCEOnCompileKind_TypeInit, underlyingTypeDeferred);
|
||||||
hadNewMembers = (typeInstance->mTypeDef->mEmitParent != NULL);
|
hadNewMembers = (typeInstance->mTypeDef->mEmitParent != NULL);
|
||||||
|
|
||||||
if (ceEmitContext.mFailed)
|
if (ceEmitContext.mFailed)
|
||||||
|
@ -2685,6 +2675,176 @@ void BfModule::DoPopulateType_TypeAlias(BfTypeInstance* typeAlias)
|
||||||
DoPopulateType_SetGenericDependencies(typeAlias);
|
DoPopulateType_SetGenericDependencies(typeAlias);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void BfModule::DoPopulateType_FinishEnum(BfTypeInstance* typeInstance, bool underlyingTypeDeferred, HashContext* dataMemberHashCtx, BfType* unionInnerType)
|
||||||
|
{
|
||||||
|
if (typeInstance->IsEnum())
|
||||||
|
{
|
||||||
|
int64 min = 0;
|
||||||
|
int64 max = 0;
|
||||||
|
|
||||||
|
bool isFirst = true;
|
||||||
|
|
||||||
|
if (typeInstance->mTypeInfoEx == NULL)
|
||||||
|
typeInstance->mTypeInfoEx = new BfTypeInfoEx();
|
||||||
|
|
||||||
|
for (auto& fieldInstanceRef : typeInstance->mFieldInstances)
|
||||||
|
{
|
||||||
|
auto fieldInstance = &fieldInstanceRef;
|
||||||
|
auto fieldDef = fieldInstance->GetFieldDef();
|
||||||
|
if ((fieldDef != NULL) && (fieldDef->IsEnumCaseEntry()))
|
||||||
|
{
|
||||||
|
if (fieldInstance->mConstIdx == -1)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
auto constant = typeInstance->mConstHolder->GetConstantById(fieldInstance->mConstIdx);
|
||||||
|
BF_ASSERT((constant->mTypeCode == BfTypeCode_Int64) || (!underlyingTypeDeferred));
|
||||||
|
|
||||||
|
if (isFirst)
|
||||||
|
{
|
||||||
|
min = constant->mInt64;
|
||||||
|
max = constant->mInt64;
|
||||||
|
isFirst = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
min = BF_MIN(constant->mInt64, min);
|
||||||
|
max = BF_MAX(constant->mInt64, max);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
typeInstance->mTypeInfoEx->mMinValue = min;
|
||||||
|
typeInstance->mTypeInfoEx->mMaxValue = max;
|
||||||
|
|
||||||
|
if (underlyingTypeDeferred)
|
||||||
|
{
|
||||||
|
BfTypeCode typeCode;
|
||||||
|
|
||||||
|
if ((min >= -0x80) && (max <= 0x7F))
|
||||||
|
typeCode = BfTypeCode_Int8;
|
||||||
|
else if ((min >= 0) && (max <= 0xFF))
|
||||||
|
typeCode = BfTypeCode_UInt8;
|
||||||
|
else if ((min >= -0x8000) && (max <= 0x7FFF))
|
||||||
|
typeCode = BfTypeCode_Int16;
|
||||||
|
else if ((min >= 0) && (max <= 0xFFFF))
|
||||||
|
typeCode = BfTypeCode_UInt16;
|
||||||
|
else if ((min >= -0x80000000LL) && (max <= 0x7FFFFFFF))
|
||||||
|
typeCode = BfTypeCode_Int32;
|
||||||
|
else if ((min >= 0) && (max <= 0xFFFFFFFFLL))
|
||||||
|
typeCode = BfTypeCode_UInt32;
|
||||||
|
else
|
||||||
|
typeCode = BfTypeCode_Int64;
|
||||||
|
|
||||||
|
if (typeCode != BfTypeCode_Int64)
|
||||||
|
{
|
||||||
|
for (auto& fieldInstanceRef : typeInstance->mFieldInstances)
|
||||||
|
{
|
||||||
|
auto fieldInstance = &fieldInstanceRef;
|
||||||
|
if (fieldInstance->mConstIdx == -1)
|
||||||
|
continue;
|
||||||
|
if (!fieldInstance->GetFieldDef()->IsEnumCaseEntry())
|
||||||
|
continue;
|
||||||
|
auto constant = typeInstance->mConstHolder->GetConstantById(fieldInstance->mConstIdx);
|
||||||
|
BfIRValue newConstant = typeInstance->mConstHolder->CreateConst(typeCode, constant->mUInt64);
|
||||||
|
fieldInstance->mConstIdx = newConstant.mId;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BfType* underlyingType = GetPrimitiveType(typeCode);
|
||||||
|
auto fieldInstance = &typeInstance->mFieldInstances.back();
|
||||||
|
fieldInstance->mResolvedType = underlyingType;
|
||||||
|
fieldInstance->mDataSize = underlyingType->mSize;
|
||||||
|
|
||||||
|
typeInstance->mTypeInfoEx->mUnderlyingType = underlyingType;
|
||||||
|
|
||||||
|
typeInstance->mSize = underlyingType->mSize;
|
||||||
|
typeInstance->mAlign = underlyingType->mAlign;
|
||||||
|
typeInstance->mInstSize = underlyingType->mSize;
|
||||||
|
typeInstance->mInstAlign = underlyingType->mAlign;
|
||||||
|
|
||||||
|
typeInstance->mRebuildFlags = (BfTypeRebuildFlags)(typeInstance->mRebuildFlags & ~BfTypeRebuildFlag_UnderlyingTypeDeferred);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
BF_ASSERT(!underlyingTypeDeferred);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((typeInstance->IsPayloadEnum()) && (!typeInstance->IsBoxed()))
|
||||||
|
{
|
||||||
|
typeInstance->mAlign = unionInnerType->mAlign;
|
||||||
|
|
||||||
|
int lastTagId = -1;
|
||||||
|
for (auto& fieldInstanceRef : typeInstance->mFieldInstances)
|
||||||
|
{
|
||||||
|
auto fieldInstance = &fieldInstanceRef;
|
||||||
|
auto fieldDef = fieldInstance->GetFieldDef();
|
||||||
|
if ((fieldDef != NULL) && (fieldInstance->mDataIdx < 0))
|
||||||
|
{
|
||||||
|
BF_ASSERT(fieldInstance->mResolvedType->mAlign >= 1);
|
||||||
|
typeInstance->mAlign = BF_MAX(typeInstance->mAlign, fieldInstance->mResolvedType->mAlign);
|
||||||
|
lastTagId = -fieldInstance->mDataIdx - 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
auto fieldInstance = &typeInstance->mFieldInstances.back();
|
||||||
|
//BF_ASSERT(fieldInstance->mResolvedType == NULL);
|
||||||
|
BfPrimitiveType* discriminatorType;
|
||||||
|
if (lastTagId > 0x7FFFFFFF) // HOW?
|
||||||
|
discriminatorType = GetPrimitiveType(BfTypeCode_Int64);
|
||||||
|
else if (lastTagId > 0x7FFF)
|
||||||
|
discriminatorType = GetPrimitiveType(BfTypeCode_Int32);
|
||||||
|
else if (lastTagId > 0x7F)
|
||||||
|
discriminatorType = GetPrimitiveType(BfTypeCode_Int16);
|
||||||
|
else
|
||||||
|
discriminatorType = GetPrimitiveType(BfTypeCode_Int8);
|
||||||
|
fieldInstance->mResolvedType = discriminatorType;
|
||||||
|
|
||||||
|
fieldInstance->mDataOffset = unionInnerType->mSize;
|
||||||
|
fieldInstance->mDataIdx = 2; // 0 = base, 1 = payload, 2 = discriminator
|
||||||
|
if (!typeInstance->mIsPacked)
|
||||||
|
{
|
||||||
|
if ((fieldInstance->mDataOffset % discriminatorType->mAlign) != 0)
|
||||||
|
{
|
||||||
|
fieldInstance->mDataOffset = BF_ALIGN(fieldInstance->mDataOffset, discriminatorType->mAlign);
|
||||||
|
fieldInstance->mDataIdx++; // Add room for explicit padding
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
typeInstance->mAlign = BF_MAX(typeInstance->mAlign, discriminatorType->mAlign);
|
||||||
|
typeInstance->mSize = fieldInstance->mDataOffset + discriminatorType->mSize;
|
||||||
|
|
||||||
|
typeInstance->mInstSize = typeInstance->mSize;
|
||||||
|
typeInstance->mInstAlign = typeInstance->mAlign;
|
||||||
|
|
||||||
|
if (dataMemberHashCtx != NULL)
|
||||||
|
{
|
||||||
|
dataMemberHashCtx->Mixin(unionInnerType->mTypeId);
|
||||||
|
dataMemberHashCtx->Mixin(discriminatorType->mTypeId);
|
||||||
|
}
|
||||||
|
|
||||||
|
typeInstance->mMergedFieldDataCount = 1; // Track it as a single entry
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void BfModule::DoPopulateType_CeCheckEnum(BfTypeInstance* typeInstance, bool underlyingTypeDeferred)
|
||||||
|
{
|
||||||
|
if (!typeInstance->IsEnum())
|
||||||
|
return;
|
||||||
|
if ((!underlyingTypeDeferred) && (!typeInstance->IsPayloadEnum()))
|
||||||
|
return;
|
||||||
|
if ((typeInstance->mCeTypeInfo != NULL) && (typeInstance->mCeTypeInfo->mNext != NULL))
|
||||||
|
return;
|
||||||
|
|
||||||
|
BfType* unionInnerType = NULL;
|
||||||
|
if (typeInstance->mIsUnion)
|
||||||
|
{
|
||||||
|
SetAndRestoreValue<BfTypeState::ResolveKind> prevResolveKind(mContext->mCurTypeState->mResolveKind, BfTypeState::ResolveKind_UnionInnerType);
|
||||||
|
unionInnerType = typeInstance->GetUnionInnerType();
|
||||||
|
}
|
||||||
|
DoPopulateType_FinishEnum(typeInstance, underlyingTypeDeferred, NULL, unionInnerType);
|
||||||
|
}
|
||||||
|
|
||||||
void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateType)
|
void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateType)
|
||||||
{
|
{
|
||||||
if (populateType == BfPopulateType_Identity)
|
if (populateType == BfPopulateType_Identity)
|
||||||
|
@ -3732,6 +3892,7 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy
|
||||||
if (typeInstance->mTypeDef != innerTypeInst->mTypeDef)
|
if (typeInstance->mTypeDef != innerTypeInst->mTypeDef)
|
||||||
{
|
{
|
||||||
// Rebuild with proper typedef (generally from inner type comptime emission)
|
// Rebuild with proper typedef (generally from inner type comptime emission)
|
||||||
|
BfLogSysM("Boxed type %p overriding typeDef to %p from inner type %p\n", typeInstance, innerTypeInst->mTypeDef, innerType);
|
||||||
typeInstance->mTypeDef = innerTypeInst->mTypeDef;
|
typeInstance->mTypeDef = innerTypeInst->mTypeDef;
|
||||||
DoPopulateType(resolvedTypeRef, populateType);
|
DoPopulateType(resolvedTypeRef, populateType);
|
||||||
return;
|
return;
|
||||||
|
@ -4056,7 +4217,7 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy
|
||||||
|
|
||||||
typeInstance->mDefineState = BfTypeDefineState_CETypeInit;
|
typeInstance->mDefineState = BfTypeDefineState_CETypeInit;
|
||||||
bool hadNewMembers = false;
|
bool hadNewMembers = false;
|
||||||
DoCEEmit(typeInstance, hadNewMembers);
|
DoCEEmit(typeInstance, hadNewMembers, underlyingTypeDeferred);
|
||||||
|
|
||||||
if (typeInstance->mDefineState < BfTypeDefineState_CEPostTypeInit)
|
if (typeInstance->mDefineState < BfTypeDefineState_CEPostTypeInit)
|
||||||
typeInstance->mDefineState = BfTypeDefineState_CEPostTypeInit;
|
typeInstance->mDefineState = BfTypeDefineState_CEPostTypeInit;
|
||||||
|
@ -4660,7 +4821,7 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy
|
||||||
typeInstance->mDefineState = BfTypeDefineState_Defined;
|
typeInstance->mDefineState = BfTypeDefineState_Defined;
|
||||||
if (!typeInstance->IsBoxed())
|
if (!typeInstance->IsBoxed())
|
||||||
{
|
{
|
||||||
ExecuteCEOnCompile(NULL, typeInstance, BfCEOnCompileKind_TypeDone);
|
ExecuteCEOnCompile(NULL, typeInstance, BfCEOnCompileKind_TypeDone, underlyingTypeDeferred);
|
||||||
if (typeInstance->mDefineState == BfTypeDefineState_DefinedAndMethodsSlotted)
|
if (typeInstance->mDefineState == BfTypeDefineState_DefinedAndMethodsSlotted)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -4831,151 +4992,7 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy
|
||||||
BfLogSysM("Setting underlying type %p %d\n", typeInstance, underlyingTypeDeferred);
|
BfLogSysM("Setting underlying type %p %d\n", typeInstance, underlyingTypeDeferred);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (typeInstance->IsEnum())
|
DoPopulateType_FinishEnum(typeInstance, underlyingTypeDeferred, &dataMemberHashCtx, unionInnerType);
|
||||||
{
|
|
||||||
int64 min = 0;
|
|
||||||
int64 max = 0;
|
|
||||||
|
|
||||||
bool isFirst = true;
|
|
||||||
|
|
||||||
if (typeInstance->mTypeInfoEx == NULL)
|
|
||||||
typeInstance->mTypeInfoEx = new BfTypeInfoEx();
|
|
||||||
|
|
||||||
for (auto& fieldInstanceRef : typeInstance->mFieldInstances)
|
|
||||||
{
|
|
||||||
auto fieldInstance = &fieldInstanceRef;
|
|
||||||
auto fieldDef = fieldInstance->GetFieldDef();
|
|
||||||
if ((fieldDef != NULL) && (fieldDef->IsEnumCaseEntry()))
|
|
||||||
{
|
|
||||||
if (fieldInstance->mConstIdx == -1)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
auto constant = typeInstance->mConstHolder->GetConstantById(fieldInstance->mConstIdx);
|
|
||||||
BF_ASSERT((constant->mTypeCode == BfTypeCode_Int64) || (!underlyingTypeDeferred));
|
|
||||||
|
|
||||||
if (isFirst)
|
|
||||||
{
|
|
||||||
min = constant->mInt64;
|
|
||||||
max = constant->mInt64;
|
|
||||||
isFirst = false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
min = BF_MIN(constant->mInt64, min);
|
|
||||||
max = BF_MAX(constant->mInt64, max);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
typeInstance->mTypeInfoEx->mMinValue = min;
|
|
||||||
typeInstance->mTypeInfoEx->mMaxValue = max;
|
|
||||||
|
|
||||||
if (underlyingTypeDeferred)
|
|
||||||
{
|
|
||||||
BfTypeCode typeCode;
|
|
||||||
|
|
||||||
if ((min >= -0x80) && (max <= 0x7F))
|
|
||||||
typeCode = BfTypeCode_Int8;
|
|
||||||
else if ((min >= 0) && (max <= 0xFF))
|
|
||||||
typeCode = BfTypeCode_UInt8;
|
|
||||||
else if ((min >= -0x8000) && (max <= 0x7FFF))
|
|
||||||
typeCode = BfTypeCode_Int16;
|
|
||||||
else if ((min >= 0) && (max <= 0xFFFF))
|
|
||||||
typeCode = BfTypeCode_UInt16;
|
|
||||||
else if ((min >= -0x80000000LL) && (max <= 0x7FFFFFFF))
|
|
||||||
typeCode = BfTypeCode_Int32;
|
|
||||||
else if ((min >= 0) && (max <= 0xFFFFFFFFLL))
|
|
||||||
typeCode = BfTypeCode_UInt32;
|
|
||||||
else
|
|
||||||
typeCode = BfTypeCode_Int64;
|
|
||||||
|
|
||||||
if (typeCode != BfTypeCode_Int64)
|
|
||||||
{
|
|
||||||
for (auto& fieldInstanceRef : typeInstance->mFieldInstances)
|
|
||||||
{
|
|
||||||
auto fieldInstance = &fieldInstanceRef;
|
|
||||||
if (fieldInstance->mConstIdx == -1)
|
|
||||||
continue;
|
|
||||||
if (!fieldInstance->GetFieldDef()->IsEnumCaseEntry())
|
|
||||||
continue;
|
|
||||||
auto constant = typeInstance->mConstHolder->GetConstantById(fieldInstance->mConstIdx);
|
|
||||||
BfIRValue newConstant = typeInstance->mConstHolder->CreateConst(typeCode, constant->mUInt64);
|
|
||||||
fieldInstance->mConstIdx = newConstant.mId;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
underlyingType = GetPrimitiveType(typeCode);
|
|
||||||
auto fieldInstance = &typeInstance->mFieldInstances.back();
|
|
||||||
fieldInstance->mResolvedType = underlyingType;
|
|
||||||
fieldInstance->mDataSize = underlyingType->mSize;
|
|
||||||
|
|
||||||
typeInstance->mTypeInfoEx->mUnderlyingType = underlyingType;
|
|
||||||
|
|
||||||
typeInstance->mSize = underlyingType->mSize;
|
|
||||||
typeInstance->mAlign = underlyingType->mAlign;
|
|
||||||
typeInstance->mInstSize = underlyingType->mSize;
|
|
||||||
typeInstance->mInstAlign = underlyingType->mAlign;
|
|
||||||
|
|
||||||
typeInstance->mRebuildFlags = (BfTypeRebuildFlags)(typeInstance->mRebuildFlags & ~BfTypeRebuildFlag_UnderlyingTypeDeferred);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
BF_ASSERT(!underlyingTypeDeferred);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((typeInstance->IsPayloadEnum()) && (!typeInstance->IsBoxed()))
|
|
||||||
{
|
|
||||||
typeInstance->mAlign = unionInnerType->mAlign;
|
|
||||||
|
|
||||||
int lastTagId = -1;
|
|
||||||
for (auto& fieldInstanceRef : typeInstance->mFieldInstances)
|
|
||||||
{
|
|
||||||
auto fieldInstance = &fieldInstanceRef;
|
|
||||||
auto fieldDef = fieldInstance->GetFieldDef();
|
|
||||||
if ((fieldDef != NULL) && (fieldInstance->mDataIdx < 0))
|
|
||||||
{
|
|
||||||
BF_ASSERT(fieldInstance->mResolvedType->mAlign >= 1);
|
|
||||||
typeInstance->mAlign = BF_MAX(typeInstance->mAlign, fieldInstance->mResolvedType->mAlign);
|
|
||||||
lastTagId = -fieldInstance->mDataIdx - 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
auto fieldInstance = &typeInstance->mFieldInstances.back();
|
|
||||||
BF_ASSERT(fieldInstance->mResolvedType == NULL);
|
|
||||||
BfPrimitiveType* discriminatorType;
|
|
||||||
if (lastTagId > 0x7FFFFFFF) // HOW?
|
|
||||||
discriminatorType = GetPrimitiveType(BfTypeCode_Int64);
|
|
||||||
else if (lastTagId > 0x7FFF)
|
|
||||||
discriminatorType = GetPrimitiveType(BfTypeCode_Int32);
|
|
||||||
else if (lastTagId > 0x7F)
|
|
||||||
discriminatorType = GetPrimitiveType(BfTypeCode_Int16);
|
|
||||||
else
|
|
||||||
discriminatorType = GetPrimitiveType(BfTypeCode_Int8);
|
|
||||||
fieldInstance->mResolvedType = discriminatorType;
|
|
||||||
|
|
||||||
fieldInstance->mDataOffset = unionInnerType->mSize;
|
|
||||||
fieldInstance->mDataIdx = 2; // 0 = base, 1 = payload, 2 = discriminator
|
|
||||||
if (!isPacked)
|
|
||||||
{
|
|
||||||
if ((fieldInstance->mDataOffset % discriminatorType->mAlign) != 0)
|
|
||||||
{
|
|
||||||
fieldInstance->mDataOffset = BF_ALIGN(fieldInstance->mDataOffset, discriminatorType->mAlign);
|
|
||||||
fieldInstance->mDataIdx++; // Add room for explicit padding
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
typeInstance->mAlign = BF_MAX(typeInstance->mAlign, discriminatorType->mAlign);
|
|
||||||
typeInstance->mSize = fieldInstance->mDataOffset + discriminatorType->mSize;
|
|
||||||
|
|
||||||
typeInstance->mInstSize = typeInstance->mSize;
|
|
||||||
typeInstance->mInstAlign = typeInstance->mAlign;
|
|
||||||
|
|
||||||
dataMemberHashCtx.Mixin(unionInnerType->mTypeId);
|
|
||||||
dataMemberHashCtx.Mixin(discriminatorType->mTypeId);
|
|
||||||
|
|
||||||
typeInstance->mMergedFieldDataCount = 1; // Track it as a single entry
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!typeInstance->IsBoxed())
|
if (!typeInstance->IsBoxed())
|
||||||
{
|
{
|
||||||
|
@ -5633,7 +5650,7 @@ void BfModule::DoTypeInstanceMethodProcessing(BfTypeInstance* typeInstance)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (typeInstance->mTypeDef->mProject->mTargetType == BfTargetType_BeefTest)
|
if (methodInstance->mMethodDef->mDeclaringType->mProject->mTargetType == BfTargetType_BeefTest)
|
||||||
{
|
{
|
||||||
if ((customAttributes != NULL) && (customAttributes->Contains(mCompiler->mTestAttributeTypeDef)))
|
if ((customAttributes != NULL) && (customAttributes->Contains(mCompiler->mTestAttributeTypeDef)))
|
||||||
{
|
{
|
||||||
|
@ -7556,7 +7573,7 @@ BfTypeDef* BfModule::ResolveGenericInstanceDef(BfGenericInstanceTypeRef* generic
|
||||||
{
|
{
|
||||||
BfTypeLookupError error;
|
BfTypeLookupError error;
|
||||||
error.mRefNode = typeRef;
|
error.mRefNode = typeRef;
|
||||||
BfTypeDef* typeDef = FindTypeDef(typeRef, NULL, &error, numGenericParams);
|
BfTypeDef* typeDef = FindTypeDef(typeRef, NULL, &error, numGenericParams, resolveFlags);
|
||||||
if (typeDef != NULL)
|
if (typeDef != NULL)
|
||||||
{
|
{
|
||||||
BfAutoComplete* autoComplete = NULL;
|
BfAutoComplete* autoComplete = NULL;
|
||||||
|
@ -7587,6 +7604,8 @@ BfTypeDef* BfModule::ResolveGenericInstanceDef(BfGenericInstanceTypeRef* generic
|
||||||
if (typeRef->IsA<BfNamedTypeReference>())
|
if (typeRef->IsA<BfNamedTypeReference>())
|
||||||
{
|
{
|
||||||
String findName = typeRef->ToString();
|
String findName = typeRef->ToString();
|
||||||
|
if ((resolveFlags & BfResolveTypeRefFlag_Attribute) != 0)
|
||||||
|
findName += "Attribute";
|
||||||
if ((mCurTypeInstance != NULL) && (mCurTypeInstance->IsGenericTypeInstance()))
|
if ((mCurTypeInstance != NULL) && (mCurTypeInstance->IsGenericTypeInstance()))
|
||||||
{
|
{
|
||||||
auto genericTypeInst = (BfTypeInstance*)mCurTypeInstance;
|
auto genericTypeInst = (BfTypeInstance*)mCurTypeInstance;
|
||||||
|
@ -9341,6 +9360,28 @@ BfTypedValue BfModule::TryLookupGenericConstVaue(BfIdentifierNode* identifierNod
|
||||||
return BfTypedValue();
|
return BfTypedValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void BfModule::GetDelegateTypeRefAttributes(BfDelegateTypeRef* delegateTypeRef, BfCallingConvention& callingConvention)
|
||||||
|
{
|
||||||
|
if (delegateTypeRef->mAttributes == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
BfCaptureInfo captureInfo;
|
||||||
|
auto customAttributes = GetCustomAttributes(delegateTypeRef->mAttributes, (BfAttributeTargets)(BfAttributeTargets_DelegateTypeRef | BfAttributeTargets_FunctionTypeRef), BfGetCustomAttributesFlags_KeepConstsInModule);
|
||||||
|
if (customAttributes != NULL)
|
||||||
|
{
|
||||||
|
auto linkNameAttr = customAttributes->Get(mCompiler->mCallingConventionAttributeTypeDef);
|
||||||
|
if (linkNameAttr != NULL)
|
||||||
|
{
|
||||||
|
if (linkNameAttr->mCtorArgs.size() == 1)
|
||||||
|
{
|
||||||
|
auto constant = mBfIRBuilder->GetConstant(linkNameAttr->mCtorArgs[0]);
|
||||||
|
if (constant != NULL)
|
||||||
|
callingConvention = (BfCallingConvention)constant->mInt32;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType populateType, BfResolveTypeRefFlags resolveFlags, int numGenericArgs)
|
BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType populateType, BfResolveTypeRefFlags resolveFlags, int numGenericArgs)
|
||||||
{
|
{
|
||||||
BP_ZONE("BfModule::ResolveTypeRef");
|
BP_ZONE("BfModule::ResolveTypeRef");
|
||||||
|
@ -10078,11 +10119,15 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula
|
||||||
}
|
}
|
||||||
|
|
||||||
BfResolvedTypeSet::LookupContext lookupCtx;
|
BfResolvedTypeSet::LookupContext lookupCtx;
|
||||||
lookupCtx.mResolveFlags = (BfResolveTypeRefFlags)(resolveFlags & (BfResolveTypeRefFlag_NoCreate | BfResolveTypeRefFlag_IgnoreLookupError | BfResolveTypeRefFlag_DisallowComptime | BfResolveTypeRefFlag_AllowInferredSizedArray));
|
lookupCtx.mResolveFlags = (BfResolveTypeRefFlags)(resolveFlags & (BfResolveTypeRefFlag_NoCreate | BfResolveTypeRefFlag_IgnoreLookupError |
|
||||||
|
BfResolveTypeRefFlag_DisallowComptime | BfResolveTypeRefFlag_AllowInferredSizedArray | BfResolveTypeRefFlag_Attribute));
|
||||||
lookupCtx.mRootTypeRef = typeRef;
|
lookupCtx.mRootTypeRef = typeRef;
|
||||||
lookupCtx.mRootTypeDef = typeDef;
|
lookupCtx.mRootTypeDef = typeDef;
|
||||||
lookupCtx.mModule = this;
|
lookupCtx.mModule = this;
|
||||||
BfResolvedTypeSet::Entry* resolvedEntry = NULL;
|
BfResolvedTypeSet::Entry* resolvedEntry = NULL;
|
||||||
|
if (auto delegateTypeRef = BfNodeDynCastExact<BfDelegateTypeRef>(typeRef))
|
||||||
|
GetDelegateTypeRefAttributes(delegateTypeRef, lookupCtx.mCallingConvention);
|
||||||
|
|
||||||
auto inserted = mContext->mResolvedTypes.Insert(typeRef, &lookupCtx, &resolvedEntry);
|
auto inserted = mContext->mResolvedTypes.Insert(typeRef, &lookupCtx, &resolvedEntry);
|
||||||
|
|
||||||
if (resolvedEntry == NULL)
|
if (resolvedEntry == NULL)
|
||||||
|
@ -10355,7 +10400,7 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula
|
||||||
BfTypeVector genericArgs;
|
BfTypeVector genericArgs;
|
||||||
|
|
||||||
BfType* type = NULL;
|
BfType* type = NULL;
|
||||||
BfTypeDef* typeDef = ResolveGenericInstanceDef(genericTypeInstRef, &type);
|
BfTypeDef* typeDef = ResolveGenericInstanceDef(genericTypeInstRef, &type, resolveFlags);
|
||||||
if(ambiguousTypeDef != NULL)
|
if(ambiguousTypeDef != NULL)
|
||||||
ShowAmbiguousTypeError(typeRef, typeDef, ambiguousTypeDef);
|
ShowAmbiguousTypeError(typeRef, typeDef, ambiguousTypeDef);
|
||||||
if (typeDef == NULL)
|
if (typeDef == NULL)
|
||||||
|
@ -10542,8 +10587,11 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula
|
||||||
wantGeneric = true;
|
wantGeneric = true;
|
||||||
if (type->IsUnspecializedType())
|
if (type->IsUnspecializedType())
|
||||||
isUnspecialized = true;
|
isUnspecialized = true;
|
||||||
BF_ASSERT(!type->IsVar());
|
if (type->IsVar())
|
||||||
|
{
|
||||||
|
mContext->mResolvedTypes.RemoveEntry(resolvedEntry);
|
||||||
|
return ResolveTypeResult(typeRef, NULL, populateType, resolveFlags);
|
||||||
|
}
|
||||||
types.push_back(type);
|
types.push_back(type);
|
||||||
names.push_back(fieldName);
|
names.push_back(fieldName);
|
||||||
}
|
}
|
||||||
|
@ -10835,6 +10883,8 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula
|
||||||
delegateType = dlgType;
|
delegateType = dlgType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
delegateInfo->mCallingConvention = lookupCtx.mCallingConvention;
|
||||||
|
|
||||||
Val128 hashContext;
|
Val128 hashContext;
|
||||||
|
|
||||||
BfTypeDef* typeDef = new BfTypeDef();
|
BfTypeDef* typeDef = new BfTypeDef();
|
||||||
|
@ -13091,8 +13141,10 @@ BfTypedValue BfModule::Cast(BfAstNode* srcNode, const BfTypedValue& typedVal, Bf
|
||||||
auto fromMethodInst = GetRawMethodByName(fromTypeInst, "Invoke", -1, true);
|
auto fromMethodInst = GetRawMethodByName(fromTypeInst, "Invoke", -1, true);
|
||||||
auto toMethodInst = GetRawMethodByName(toTypeInst, "Invoke", -1, true);
|
auto toMethodInst = GetRawMethodByName(toTypeInst, "Invoke", -1, true);
|
||||||
|
|
||||||
|
auto toDelegateInfo = toTypeInst->GetDelegateInfo();
|
||||||
|
|
||||||
if ((fromMethodInst != NULL) && (toMethodInst != NULL) &&
|
if ((fromMethodInst != NULL) && (toMethodInst != NULL) &&
|
||||||
(fromMethodInst->mMethodDef->mCallingConvention == toMethodInst->mMethodDef->mCallingConvention) &&
|
(fromMethodInst->mCallingConvention == toMethodInst->mCallingConvention) &&
|
||||||
(fromMethodInst->mMethodDef->mIsMutating == toMethodInst->mMethodDef->mIsMutating) &&
|
(fromMethodInst->mMethodDef->mIsMutating == toMethodInst->mMethodDef->mIsMutating) &&
|
||||||
(fromMethodInst->mReturnType == toMethodInst->mReturnType) &&
|
(fromMethodInst->mReturnType == toMethodInst->mReturnType) &&
|
||||||
(fromMethodInst->GetParamCount() == toMethodInst->GetParamCount()))
|
(fromMethodInst->GetParamCount() == toMethodInst->GetParamCount()))
|
||||||
|
@ -13673,6 +13725,25 @@ void BfModule::DoTypeToString(StringImpl& str, BfType* resolvedType, BfTypeNameF
|
||||||
str += "delegate ";
|
str += "delegate ";
|
||||||
else
|
else
|
||||||
str += "function ";
|
str += "function ";
|
||||||
|
|
||||||
|
if (delegateInfo->mCallingConvention != BfCallingConvention_Unspecified)
|
||||||
|
{
|
||||||
|
str += "[CallingConvention(";
|
||||||
|
switch (delegateInfo->mCallingConvention)
|
||||||
|
{
|
||||||
|
case BfCallingConvention_Cdecl:
|
||||||
|
str += ".Cdecl";
|
||||||
|
break;
|
||||||
|
case BfCallingConvention_Stdcall:
|
||||||
|
str += ".Stdcall";
|
||||||
|
break;
|
||||||
|
case BfCallingConvention_Fastcall:
|
||||||
|
str += ".Fastcall";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
str += ")] ";
|
||||||
|
}
|
||||||
|
|
||||||
DoTypeToString(str, delegateInfo->mReturnType, typeNameFlags, genericMethodNameOverrides);
|
DoTypeToString(str, delegateInfo->mReturnType, typeNameFlags, genericMethodNameOverrides);
|
||||||
str += "(";
|
str += "(";
|
||||||
|
|
||||||
|
|
|
@ -3800,13 +3800,14 @@ BF_EXPORT bool BF_CALLTYPE BfParser_Reduce(BfParser* bfParser, BfPassInstance* b
|
||||||
}
|
}
|
||||||
|
|
||||||
static Array<int> gCharMapping;
|
static Array<int> gCharMapping;
|
||||||
BF_EXPORT const char* BF_CALLTYPE BfParser_Format(BfParser* bfParser, int formatStart, int formatEnd, int** outCharMapping)
|
BF_EXPORT const char* BF_CALLTYPE BfParser_Format(BfParser* bfParser, int formatStart, int formatEnd, int** outCharMapping, int maxCol)
|
||||||
{
|
{
|
||||||
BP_ZONE("BfParser_Reduce");
|
BP_ZONE("BfParser_Reduce");
|
||||||
String& outString = *gTLStrReturn.Get();
|
String& outString = *gTLStrReturn.Get();
|
||||||
outString.clear();
|
outString.clear();
|
||||||
gCharMapping.Clear();
|
gCharMapping.Clear();
|
||||||
BfPrinter bfPrinter(bfParser->mRootNode, bfParser->mSidechannelRootNode, bfParser->mErrorRootNode);
|
BfPrinter bfPrinter(bfParser->mRootNode, bfParser->mSidechannelRootNode, bfParser->mErrorRootNode);
|
||||||
|
bfPrinter.mMaxCol = maxCol;
|
||||||
bfPrinter.mFormatStart = formatStart;
|
bfPrinter.mFormatStart = formatStart;
|
||||||
bfPrinter.mFormatEnd = formatEnd;
|
bfPrinter.mFormatEnd = formatEnd;
|
||||||
bfPrinter.mCharMapping = &gCharMapping;
|
bfPrinter.mCharMapping = &gCharMapping;
|
||||||
|
|
|
@ -300,10 +300,7 @@ int BfPrinter::CalcOrigLineSpacing(BfAstNode* bfAstNode, int* lineStartIdx)
|
||||||
|
|
||||||
void BfPrinter::WriteIgnoredNode(BfAstNode* node)
|
void BfPrinter::WriteIgnoredNode(BfAstNode* node)
|
||||||
{
|
{
|
||||||
if ((!mOutString.IsEmpty()) && (!isspace((uint8)mOutString[mOutString.mLength - 1])))
|
bool startsWithSpace = false;
|
||||||
{
|
|
||||||
Write(" ");
|
|
||||||
}
|
|
||||||
|
|
||||||
bool wasExpectingNewLine = mExpectingNewLine;
|
bool wasExpectingNewLine = mExpectingNewLine;
|
||||||
|
|
||||||
|
@ -315,12 +312,17 @@ void BfPrinter::WriteIgnoredNode(BfAstNode* node)
|
||||||
for (int i = mTriviaIdx; i < srcEnd; i++)
|
for (int i = mTriviaIdx; i < srcEnd; i++)
|
||||||
{
|
{
|
||||||
char c = astNodeSrc->mSrc[i];
|
char c = astNodeSrc->mSrc[i];
|
||||||
|
if ((i == mTriviaIdx) && (isspace((uint8)c)))
|
||||||
|
startsWithSpace = true;
|
||||||
|
|
||||||
if ((c == '\n') && (i < node->GetSrcStart()))
|
if ((c == '\n') && (i < node->GetSrcStart()))
|
||||||
crCount++;
|
crCount++;
|
||||||
if (((c != ' ') && (c != '\t')) || (!mReformatting))
|
if (((c != ' ') && (c != '\t')) || (!mReformatting))
|
||||||
endIdx = i + 1;
|
endIdx = i + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool wantsPrefixSpace = (!mOutString.IsEmpty()) && (!isspace((uint8)mOutString[mOutString.mLength - 1]));
|
||||||
|
|
||||||
bool expectingNewLine = mNextStateModify.mWantNewLineIdx != mVirtualNewLineIdx;
|
bool expectingNewLine = mNextStateModify.mWantNewLineIdx != mVirtualNewLineIdx;
|
||||||
|
|
||||||
int startIdx = mTriviaIdx;
|
int startIdx = mTriviaIdx;
|
||||||
|
@ -333,7 +335,10 @@ void BfPrinter::WriteIgnoredNode(BfAstNode* node)
|
||||||
if ((origLineSpacing != -1) && (lineStart != -1))
|
if ((origLineSpacing != -1) && (lineStart != -1))
|
||||||
{
|
{
|
||||||
for (int i = 0; i < crCount; i++)
|
for (int i = 0; i < crCount; i++)
|
||||||
|
{
|
||||||
Write("\n");
|
Write("\n");
|
||||||
|
wantsPrefixSpace = false;
|
||||||
|
}
|
||||||
startIdx = node->GetSrcStart();
|
startIdx = node->GetSrcStart();
|
||||||
// Leave left-aligned preprocessor nodes
|
// Leave left-aligned preprocessor nodes
|
||||||
if ((node->GetSourceData()->mSrc[node->GetSrcStart()] != '#') || (origLineSpacing > 0))
|
if ((node->GetSourceData()->mSrc[node->GetSrcStart()] != '#') || (origLineSpacing > 0))
|
||||||
|
@ -439,6 +444,10 @@ void BfPrinter::WriteIgnoredNode(BfAstNode* node)
|
||||||
bool emitChar = true;
|
bool emitChar = true;
|
||||||
|
|
||||||
char c = astNodeSrc->mSrc[srcIdx];
|
char c = astNodeSrc->mSrc[srcIdx];
|
||||||
|
|
||||||
|
if ((wantsPrefixSpace) && (isspace((uint8)c)))
|
||||||
|
wantsPrefixSpace = false;
|
||||||
|
|
||||||
if (c == '\n')
|
if (c == '\n')
|
||||||
{
|
{
|
||||||
isNewLine = true;
|
isNewLine = true;
|
||||||
|
@ -592,6 +601,11 @@ void BfPrinter::WriteIgnoredNode(BfAstNode* node)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (wantsPrefixSpace)
|
||||||
|
{
|
||||||
|
mQueuedSpaceCount++;
|
||||||
|
wantsPrefixSpace = false;
|
||||||
|
}
|
||||||
FlushIndent();
|
FlushIndent();
|
||||||
|
|
||||||
for (int idx = startIdx; idx <= BF_MIN(srcIdx, endIdx - 1); idx++)
|
for (int idx = startIdx; idx <= BF_MIN(srcIdx, endIdx - 1); idx++)
|
||||||
|
@ -1038,6 +1052,8 @@ void BfPrinter::Visit(BfLabelableStatement* labelableStmt)
|
||||||
void BfPrinter::Visit(BfCommentNode* commentNode)
|
void BfPrinter::Visit(BfCommentNode* commentNode)
|
||||||
{
|
{
|
||||||
WriteIgnoredNode(commentNode);
|
WriteIgnoredNode(commentNode);
|
||||||
|
if (commentNode->mCommentKind == BfCommentKind_Line)
|
||||||
|
ExpectNewLine();
|
||||||
}
|
}
|
||||||
|
|
||||||
void BfPrinter::Visit(BfPreprocesorIgnoredSectionNode* preprocesorIgnoredSection)
|
void BfPrinter::Visit(BfPreprocesorIgnoredSectionNode* preprocesorIgnoredSection)
|
||||||
|
@ -1569,8 +1585,9 @@ void BfPrinter::Visit(BfDelegateTypeRef* typeRef)
|
||||||
|
|
||||||
VisitChild(typeRef->mTypeToken);
|
VisitChild(typeRef->mTypeToken);
|
||||||
ExpectSpace();
|
ExpectSpace();
|
||||||
VisitChild(typeRef->mReturnType);
|
|
||||||
VisitChild(typeRef->mAttributes);
|
VisitChild(typeRef->mAttributes);
|
||||||
|
ExpectSpace();
|
||||||
|
VisitChild(typeRef->mReturnType);
|
||||||
VisitChild(typeRef->mOpenParen);
|
VisitChild(typeRef->mOpenParen);
|
||||||
|
|
||||||
for (int i = 0; i < (int)typeRef->mParams.size(); i++)
|
for (int i = 0; i < (int)typeRef->mParams.size(); i++)
|
||||||
|
|
|
@ -281,9 +281,52 @@ bool BfReducer::IsTypeReference(BfAstNode* checkNode, BfToken successToken, int*
|
||||||
|
|
||||||
int endNode = -1;
|
int endNode = -1;
|
||||||
|
|
||||||
|
bool failed = false;
|
||||||
|
|
||||||
// Return type
|
// Return type
|
||||||
auto checkNode = mVisitorPos.GetCurrent();
|
auto checkNode = mVisitorPos.GetCurrent();
|
||||||
if ((checkNode == NULL) || (!IsTypeReference(checkNode, BfToken_LParen, &endNode, couldBeExpr, isGenericType, isTuple)))
|
if (auto checkToken = BfNodeDynCast<BfTokenNode>(checkNode))
|
||||||
|
{
|
||||||
|
if (checkToken->mToken == BfToken_LBracket)
|
||||||
|
{
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
mVisitorPos.mReadPos++;
|
||||||
|
checkNode = mVisitorPos.GetCurrent();
|
||||||
|
if (checkNode == NULL)
|
||||||
|
{
|
||||||
|
failed = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (BfNodeIsA<BfBlock>(checkNode))
|
||||||
|
{
|
||||||
|
failed = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (checkToken = BfNodeDynCast<BfTokenNode>(checkNode))
|
||||||
|
{
|
||||||
|
if (checkToken->mToken == BfToken_RBracket)
|
||||||
|
{
|
||||||
|
mVisitorPos.mReadPos++;
|
||||||
|
checkNode = mVisitorPos.GetCurrent();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if ((checkToken->mToken != BfToken_Comma) &&
|
||||||
|
(checkToken->mToken != BfToken_Dot) &&
|
||||||
|
(checkToken->mToken != BfToken_LParen) &&
|
||||||
|
(checkToken->mToken != BfToken_RParen))
|
||||||
|
{
|
||||||
|
failed = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((failed) || (checkNode == NULL) || (!IsTypeReference(checkNode, BfToken_LParen, &endNode, couldBeExpr, isGenericType, isTuple)))
|
||||||
{
|
{
|
||||||
if (outEndNode != NULL)
|
if (outEndNode != NULL)
|
||||||
*outEndNode = endNode;
|
*outEndNode = endNode;
|
||||||
|
@ -4806,6 +4849,14 @@ BfTypeReference* BfReducer::DoCreateTypeRef(BfAstNode* firstNode, CreateTypeRefF
|
||||||
ReplaceNode(firstNode, delegateTypeRef);
|
ReplaceNode(firstNode, delegateTypeRef);
|
||||||
MEMBER_SET(delegateTypeRef, mTypeToken, tokenNode);
|
MEMBER_SET(delegateTypeRef, mTypeToken, tokenNode);
|
||||||
|
|
||||||
|
auto nextToken = BfNodeDynCast<BfTokenNode>(mVisitorPos.GetNext());
|
||||||
|
if ((nextToken != NULL) && (nextToken->mToken == BfToken_LBracket))
|
||||||
|
{
|
||||||
|
mVisitorPos.MoveNext();
|
||||||
|
auto attribs = CreateAttributeDirective(nextToken);
|
||||||
|
MEMBER_SET_CHECKED(delegateTypeRef, mAttributes, attribs);
|
||||||
|
}
|
||||||
|
|
||||||
auto returnType = CreateTypeRefAfter(delegateTypeRef);
|
auto returnType = CreateTypeRefAfter(delegateTypeRef);
|
||||||
MEMBER_SET_CHECKED(delegateTypeRef, mReturnType, returnType);
|
MEMBER_SET_CHECKED(delegateTypeRef, mReturnType, returnType);
|
||||||
|
|
||||||
|
|
|
@ -2664,6 +2664,8 @@ int BfArrayType::GetLengthBitCount()
|
||||||
|
|
||||||
int BfMethodRefType::GetCaptureDataCount()
|
int BfMethodRefType::GetCaptureDataCount()
|
||||||
{
|
{
|
||||||
|
if (mMethodRef == NULL)
|
||||||
|
return 0;
|
||||||
return (int)mDataToParamIdx.size();
|
return (int)mDataToParamIdx.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3021,7 +3023,8 @@ int BfResolvedTypeSet::DirectHash(BfTypeReference* typeRef, LookupContext* ctx,
|
||||||
BfResolveTypeRefFlags resolveFlags = ctx->mResolveFlags;
|
BfResolveTypeRefFlags resolveFlags = ctx->mResolveFlags;
|
||||||
if ((flags & BfHashFlag_AllowGenericParamConstValue) != 0)
|
if ((flags & BfHashFlag_AllowGenericParamConstValue) != 0)
|
||||||
resolveFlags = (BfResolveTypeRefFlags)(resolveFlags | BfResolveTypeRefFlag_AllowGenericParamConstValue);
|
resolveFlags = (BfResolveTypeRefFlags)(resolveFlags | BfResolveTypeRefFlag_AllowGenericParamConstValue);
|
||||||
|
if (!isHeadType)
|
||||||
|
resolveFlags = (BfResolveTypeRefFlags)(resolveFlags &~ BfResolveTypeRefFlag_Attribute);
|
||||||
auto resolvedType = ctx->mModule->ResolveTypeRef(typeRef, BfPopulateType_Identity, resolveFlags);
|
auto resolvedType = ctx->mModule->ResolveTypeRef(typeRef, BfPopulateType_Identity, resolveFlags);
|
||||||
if (resolvedType == NULL)
|
if (resolvedType == NULL)
|
||||||
{
|
{
|
||||||
|
@ -3669,6 +3672,8 @@ bool BfResolvedTypeSet::Equals(BfType* lhs, BfType* rhs, LookupContext* ctx)
|
||||||
BfDelegateInfo* rhsDelegateInfo = rhs->GetDelegateInfo();
|
BfDelegateInfo* rhsDelegateInfo = rhs->GetDelegateInfo();
|
||||||
if (lhsInst->mTypeDef->mIsDelegate != rhsInst->mTypeDef->mIsDelegate)
|
if (lhsInst->mTypeDef->mIsDelegate != rhsInst->mTypeDef->mIsDelegate)
|
||||||
return false;
|
return false;
|
||||||
|
if (lhsDelegateInfo->mCallingConvention != rhsDelegateInfo->mCallingConvention)
|
||||||
|
return false;
|
||||||
|
|
||||||
auto lhsMethodDef = lhsInst->mTypeDef->mMethods[0];
|
auto lhsMethodDef = lhsInst->mTypeDef->mMethods[0];
|
||||||
auto rhsMethodDef = rhsInst->mTypeDef->mMethods[0];
|
auto rhsMethodDef = rhsInst->mTypeDef->mMethods[0];
|
||||||
|
@ -3917,7 +3922,9 @@ bool BfResolvedTypeSet::GenericTypeEquals(BfTypeInstance* lhsGenericType, BfType
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
BfTypeDef* elementTypeDef = ctx->mModule->ResolveGenericInstanceDef(rhsGenericTypeInstRef);
|
BfTypeDef* elementTypeDef = ctx->mModule->ResolveGenericInstanceDef(rhsGenericTypeInstRef, NULL, ctx->mResolveFlags);
|
||||||
|
if (elementTypeDef == NULL)
|
||||||
|
return false;
|
||||||
if (elementTypeDef->GetDefinition() != lhsGenericType->mTypeDef->GetDefinition())
|
if (elementTypeDef->GetDefinition() != lhsGenericType->mTypeDef->GetDefinition())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
@ -4088,6 +4095,14 @@ bool BfResolvedTypeSet::Equals(BfType* lhs, BfTypeReference* rhs, LookupContext*
|
||||||
|
|
||||||
if ((lhs->IsDelegate()) != rhsIsDelegate)
|
if ((lhs->IsDelegate()) != rhsIsDelegate)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
BfCallingConvention rhsCallingConvention = BfCallingConvention_Unspecified;
|
||||||
|
if (ctx->mRootTypeRef == rhsDelegateType)
|
||||||
|
rhsCallingConvention = ctx->mCallingConvention;
|
||||||
|
else
|
||||||
|
ctx->mModule->GetDelegateTypeRefAttributes(rhsDelegateType, rhsCallingConvention);
|
||||||
|
if (lhsDelegateInfo->mCallingConvention != rhsCallingConvention)
|
||||||
|
return false;
|
||||||
if (!Equals(lhsDelegateInfo->mReturnType, rhsDelegateType->mReturnType, ctx))
|
if (!Equals(lhsDelegateInfo->mReturnType, rhsDelegateType->mReturnType, ctx))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
|
|
@ -452,6 +452,7 @@ public:
|
||||||
Array<BfType*> mParams;
|
Array<BfType*> mParams;
|
||||||
bool mHasExplicitThis;
|
bool mHasExplicitThis;
|
||||||
bool mHasVarArgs;
|
bool mHasVarArgs;
|
||||||
|
BfCallingConvention mCallingConvention;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
BfDelegateInfo()
|
BfDelegateInfo()
|
||||||
|
@ -459,6 +460,7 @@ public:
|
||||||
mReturnType = NULL;
|
mReturnType = NULL;
|
||||||
mHasExplicitThis = false;
|
mHasExplicitThis = false;
|
||||||
mHasVarArgs = false;
|
mHasVarArgs = false;
|
||||||
|
mCallingConvention = BfCallingConvention_Unspecified;
|
||||||
}
|
}
|
||||||
|
|
||||||
~BfDelegateInfo()
|
~BfDelegateInfo()
|
||||||
|
@ -569,6 +571,7 @@ public:
|
||||||
virtual bool IsBoolean() { return false; }
|
virtual bool IsBoolean() { return false; }
|
||||||
virtual bool IsInteger() { return false; }
|
virtual bool IsInteger() { return false; }
|
||||||
virtual bool IsIntegral() { return false; }
|
virtual bool IsIntegral() { return false; }
|
||||||
|
virtual bool IsIntegralOrBool() { return false; }
|
||||||
virtual bool IsIntPtr() { return false; }
|
virtual bool IsIntPtr() { return false; }
|
||||||
virtual bool IsSigned() { return false; }
|
virtual bool IsSigned() { return false; }
|
||||||
virtual bool IsSignedInt() { return false; }
|
virtual bool IsSignedInt() { return false; }
|
||||||
|
@ -625,6 +628,7 @@ public:
|
||||||
virtual bool IsValueTypeOrValueTypePtr() override { return true; }
|
virtual bool IsValueTypeOrValueTypePtr() override { return true; }
|
||||||
virtual bool IsBoolean() override { return mTypeDef->mTypeCode == BfTypeCode_Boolean; }
|
virtual bool IsBoolean() override { return mTypeDef->mTypeCode == BfTypeCode_Boolean; }
|
||||||
virtual bool IsIntegral() override { return (mTypeDef->mTypeCode >= BfTypeCode_Int8) && (mTypeDef->mTypeCode <= BfTypeCode_Char32); }
|
virtual bool IsIntegral() override { return (mTypeDef->mTypeCode >= BfTypeCode_Int8) && (mTypeDef->mTypeCode <= BfTypeCode_Char32); }
|
||||||
|
virtual bool IsIntegralOrBool() override { return (mTypeDef->mTypeCode >= BfTypeCode_Boolean) && (mTypeDef->mTypeCode <= BfTypeCode_Char32); }
|
||||||
virtual bool IsInteger() override { return (mTypeDef->mTypeCode >= BfTypeCode_Int8) && (mTypeDef->mTypeCode <= BfTypeCode_UIntUnknown); }
|
virtual bool IsInteger() override { return (mTypeDef->mTypeCode >= BfTypeCode_Int8) && (mTypeDef->mTypeCode <= BfTypeCode_UIntUnknown); }
|
||||||
virtual bool IsIntPtr() override { return (mTypeDef->mTypeCode == BfTypeCode_IntPtr) || (mTypeDef->mTypeCode == BfTypeCode_UIntPtr); }
|
virtual bool IsIntPtr() override { return (mTypeDef->mTypeCode == BfTypeCode_IntPtr) || (mTypeDef->mTypeCode == BfTypeCode_UIntPtr); }
|
||||||
virtual bool IsIntPtrable() override
|
virtual bool IsIntPtrable() override
|
||||||
|
@ -1582,7 +1586,9 @@ enum BfAttributeTargets : int32
|
||||||
BfAttributeTargets_Delete = 0x80000,
|
BfAttributeTargets_Delete = 0x80000,
|
||||||
BfAttributeTargets_Alias = 0x100000,
|
BfAttributeTargets_Alias = 0x100000,
|
||||||
BfAttributeTargets_Block = 0x200000,
|
BfAttributeTargets_Block = 0x200000,
|
||||||
BfAttributeTargets_All = 0x3FFFFF
|
BfAttributeTargets_DelegateTypeRef = 0x400000,
|
||||||
|
BfAttributeTargets_FunctionTypeRef = 0x800000,
|
||||||
|
BfAttributeTargets_All = 0xFFFFFF
|
||||||
};
|
};
|
||||||
|
|
||||||
enum BfAttributeFlags : int8
|
enum BfAttributeFlags : int8
|
||||||
|
@ -1823,23 +1829,7 @@ public:
|
||||||
String mEmitData;
|
String mEmitData;
|
||||||
};
|
};
|
||||||
|
|
||||||
class BfCeTypeInfo
|
class BfCeTypeInfo;
|
||||||
{
|
|
||||||
public:
|
|
||||||
Dictionary<int, BfCeTypeEmitEntry> mOnCompileMap;
|
|
||||||
Dictionary<int, BfCeTypeEmitEntry> mTypeIFaceMap;
|
|
||||||
Array<int> mPendingInterfaces;
|
|
||||||
Val128 mHash;
|
|
||||||
bool mFailed;
|
|
||||||
BfCeTypeInfo* mNext;
|
|
||||||
|
|
||||||
public:
|
|
||||||
BfCeTypeInfo()
|
|
||||||
{
|
|
||||||
mFailed = false;
|
|
||||||
mNext = NULL;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Instance of struct or class
|
// Instance of struct or class
|
||||||
class BfTypeInstance : public BfDependedType
|
class BfTypeInstance : public BfDependedType
|
||||||
|
@ -2526,6 +2516,7 @@ public:
|
||||||
BfType* mRootResolvedType;
|
BfType* mRootResolvedType;
|
||||||
Dictionary<BfTypeReference*, BfType*> mResolvedTypeMap;
|
Dictionary<BfTypeReference*, BfType*> mResolvedTypeMap;
|
||||||
BfResolveTypeRefFlags mResolveFlags;
|
BfResolveTypeRefFlags mResolveFlags;
|
||||||
|
BfCallingConvention mCallingConvention;
|
||||||
bool mHadVar;
|
bool mHadVar;
|
||||||
bool mFailed;
|
bool mFailed;
|
||||||
|
|
||||||
|
@ -2540,6 +2531,7 @@ public:
|
||||||
mFailed = false;
|
mFailed = false;
|
||||||
mHadVar = false;
|
mHadVar = false;
|
||||||
mResolveFlags = BfResolveTypeRefFlag_None;
|
mResolveFlags = BfResolveTypeRefFlag_None;
|
||||||
|
mCallingConvention = BfCallingConvention_Unspecified;
|
||||||
}
|
}
|
||||||
|
|
||||||
BfType* GetCachedResolvedType(BfTypeReference* typeReference);
|
BfType* GetCachedResolvedType(BfTypeReference* typeReference);
|
||||||
|
|
|
@ -3455,7 +3455,9 @@ void BfModule::VisitCodeBlock(BfBlock* block)
|
||||||
}
|
}
|
||||||
else if ((mCurMethodInstance->IsMixin()) && (mCurMethodState->mCurScope == &mCurMethodState->mHeadScope))
|
else if ((mCurMethodInstance->IsMixin()) && (mCurMethodState->mCurScope == &mCurMethodState->mHeadScope))
|
||||||
{
|
{
|
||||||
// Silently allow...
|
// Only in mixin definition - result ignored
|
||||||
|
CreateValueFromExpression(expr);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -3925,6 +3927,10 @@ void BfModule::Visit(BfDeleteStatement* deleteStmt)
|
||||||
{
|
{
|
||||||
if (genericParamInst->mGenericParamFlags & (BfGenericParamFlag_Delete | BfGenericParamFlag_Var))
|
if (genericParamInst->mGenericParamFlags & (BfGenericParamFlag_Delete | BfGenericParamFlag_Var))
|
||||||
return;
|
return;
|
||||||
|
if (genericParamInst->mGenericParamFlags & BfGenericParamFlag_StructPtr)
|
||||||
|
return;
|
||||||
|
if ((genericParamInst->mGenericParamFlags & BfGenericParamFlag_Struct) && (checkType->IsPointer()))
|
||||||
|
return;
|
||||||
Fail(StrFormat("Must add 'where %s : delete' constraint to generic parameter to delete generic type '%s'",
|
Fail(StrFormat("Must add 'where %s : delete' constraint to generic parameter to delete generic type '%s'",
|
||||||
genericParamInst->GetGenericParamDef()->mName.c_str(), TypeToString(val.mType).c_str()), deleteStmt->mExpression);
|
genericParamInst->GetGenericParamDef()->mName.c_str(), TypeToString(val.mType).c_str()), deleteStmt->mExpression);
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -498,7 +498,9 @@ BfImportKind BfMethodDef::GetImportKindFromPath(const StringImpl& filePath)
|
||||||
{
|
{
|
||||||
String fileExt = GetFileExtension(filePath);
|
String fileExt = GetFileExtension(filePath);
|
||||||
|
|
||||||
if ((fileExt.Equals(".DLL", StringImpl::CompareKind_OrdinalIgnoreCase)) ||
|
if ((fileExt.Equals(".DYLIB", StringImpl::CompareKind_OrdinalIgnoreCase)) ||
|
||||||
|
(fileExt.Equals(".SO", StringImpl::CompareKind_OrdinalIgnoreCase)) ||
|
||||||
|
(fileExt.Equals(".DLL", StringImpl::CompareKind_OrdinalIgnoreCase)) ||
|
||||||
(fileExt.Equals(".EXE", StringImpl::CompareKind_OrdinalIgnoreCase)))
|
(fileExt.Equals(".EXE", StringImpl::CompareKind_OrdinalIgnoreCase)))
|
||||||
{
|
{
|
||||||
return BfImportKind_Import_Dynamic;
|
return BfImportKind_Import_Dynamic;
|
||||||
|
@ -4159,11 +4161,12 @@ BF_EXPORT const char* BF_CALLTYPE BfSystem_GetNamespaceSearch(BfSystem* bfSystem
|
||||||
return outString.c_str();
|
return outString.c_str();
|
||||||
}
|
}
|
||||||
|
|
||||||
BF_EXPORT BfProject* BF_CALLTYPE BfSystem_CreateProject(BfSystem* bfSystem, const char* projectName)
|
BF_EXPORT BfProject* BF_CALLTYPE BfSystem_CreateProject(BfSystem* bfSystem, const char* projectName, const char* projectDir)
|
||||||
{
|
{
|
||||||
AutoCrit autoCrit(bfSystem->mDataLock);
|
AutoCrit autoCrit(bfSystem->mDataLock);
|
||||||
BfProject* bfProject = new BfProject();
|
BfProject* bfProject = new BfProject();
|
||||||
bfProject->mName = projectName;
|
bfProject->mName = projectName;
|
||||||
|
bfProject->mDirectory = projectDir;
|
||||||
bfProject->mSystem = bfSystem;
|
bfProject->mSystem = bfSystem;
|
||||||
bfProject->mIdx = (int)bfSystem->mProjects.size();
|
bfProject->mIdx = (int)bfSystem->mProjects.size();
|
||||||
bfSystem->mProjects.push_back(bfProject);
|
bfSystem->mProjects.push_back(bfProject);
|
||||||
|
|
|
@ -1180,6 +1180,7 @@ public:
|
||||||
BfSystem* mSystem;
|
BfSystem* mSystem;
|
||||||
String mName;
|
String mName;
|
||||||
String mSafeName;
|
String mSafeName;
|
||||||
|
String mDirectory;
|
||||||
Array<BfProject*> mDependencies;
|
Array<BfProject*> mDependencies;
|
||||||
BfTargetType mTargetType;
|
BfTargetType mTargetType;
|
||||||
BfCodeGenOptions mCodeGenOptions;
|
BfCodeGenOptions mCodeGenOptions;
|
||||||
|
|
|
@ -5,7 +5,10 @@
|
||||||
#include "BfParser.h"
|
#include "BfParser.h"
|
||||||
#include "BfReducer.h"
|
#include "BfReducer.h"
|
||||||
#include "BfExprEvaluator.h"
|
#include "BfExprEvaluator.h"
|
||||||
|
#include "BfResolvePass.h"
|
||||||
#include "../Backend/BeIRCodeGen.h"
|
#include "../Backend/BeIRCodeGen.h"
|
||||||
|
#include "BeefySysLib/platform/PlatformHelper.h"
|
||||||
|
|
||||||
extern "C"
|
extern "C"
|
||||||
{
|
{
|
||||||
#include "BeefySysLib/third_party/utf8proc/utf8proc.h"
|
#include "BeefySysLib/third_party/utf8proc/utf8proc.h"
|
||||||
|
@ -301,6 +304,24 @@ static int DoubleToString(double d, char* outStr)
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
CeInternalData::~CeInternalData()
|
||||||
|
{
|
||||||
|
switch (mKind)
|
||||||
|
{
|
||||||
|
case Kind_File:
|
||||||
|
BfpFile_Release(mFile);
|
||||||
|
break;
|
||||||
|
case Kind_FindFileData:
|
||||||
|
BfpFindFileData_Release(mFindFileData);
|
||||||
|
break;
|
||||||
|
case Kind_Spawn:
|
||||||
|
BfpSpawn_Release(mSpawn);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
CeFunction::~CeFunction()
|
CeFunction::~CeFunction()
|
||||||
{
|
{
|
||||||
BF_ASSERT(mId == -1);
|
BF_ASSERT(mId == -1);
|
||||||
|
@ -1261,6 +1282,12 @@ void CeBuilder::HandleParams()
|
||||||
void CeBuilder::ProcessMethod(BfMethodInstance* methodInstance, BfMethodInstance* dupMethodInstance)
|
void CeBuilder::ProcessMethod(BfMethodInstance* methodInstance, BfMethodInstance* dupMethodInstance)
|
||||||
{
|
{
|
||||||
SetAndRestoreValue<BfMethodState*> prevMethodStateInConstEval(mCeMachine->mCeModule->mCurMethodState, NULL);
|
SetAndRestoreValue<BfMethodState*> prevMethodStateInConstEval(mCeMachine->mCeModule->mCurMethodState, NULL);
|
||||||
|
BfAutoComplete* prevAutoComplete = NULL;
|
||||||
|
if (mCeMachine->mCeModule->mCompiler->mResolvePassData != NULL)
|
||||||
|
{
|
||||||
|
prevAutoComplete = mCeMachine->mCeModule->mCompiler->mResolvePassData->mAutoComplete;
|
||||||
|
mCeMachine->mCeModule->mCompiler->mResolvePassData->mAutoComplete = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
auto irCodeGen = mCeMachine->mCeModule->mBfIRBuilder->mBeIRCodeGen;
|
auto irCodeGen = mCeMachine->mCeModule->mBfIRBuilder->mBeIRCodeGen;
|
||||||
auto irBuilder = mCeMachine->mCeModule->mBfIRBuilder;
|
auto irBuilder = mCeMachine->mCeModule->mBfIRBuilder;
|
||||||
|
@ -1275,6 +1302,9 @@ void CeBuilder::ProcessMethod(BfMethodInstance* methodInstance, BfMethodInstance
|
||||||
mCeMachine->mCeModule->ProcessMethod(dupMethodInstance, true);
|
mCeMachine->mCeModule->ProcessMethod(dupMethodInstance, true);
|
||||||
irCodeGen->SetState(beState);
|
irCodeGen->SetState(beState);
|
||||||
irBuilder->SetState(irState);
|
irBuilder->SetState(irState);
|
||||||
|
|
||||||
|
if (mCeMachine->mCeModule->mCompiler->mResolvePassData != NULL)
|
||||||
|
mCeMachine->mCeModule->mCompiler->mResolvePassData->mAutoComplete = prevAutoComplete;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CeBuilder::Build()
|
void CeBuilder::Build()
|
||||||
|
@ -2873,6 +2903,7 @@ CeContext::CeContext()
|
||||||
mCeMachine = NULL;
|
mCeMachine = NULL;
|
||||||
mReflectTypeIdOffset = -1;
|
mReflectTypeIdOffset = -1;
|
||||||
mExecuteId = -1;
|
mExecuteId = -1;
|
||||||
|
mStackSize = -1;
|
||||||
|
|
||||||
mCurTargetSrc = NULL;
|
mCurTargetSrc = NULL;
|
||||||
mHeap = new ContiguousHeap();
|
mHeap = new ContiguousHeap();
|
||||||
|
@ -2886,6 +2917,7 @@ CeContext::CeContext()
|
||||||
CeContext::~CeContext()
|
CeContext::~CeContext()
|
||||||
{
|
{
|
||||||
delete mHeap;
|
delete mHeap;
|
||||||
|
BF_ASSERT(mInternalDataMap.IsEmpty());
|
||||||
}
|
}
|
||||||
|
|
||||||
BfError* CeContext::Fail(const StringImpl& error)
|
BfError* CeContext::Fail(const StringImpl& error)
|
||||||
|
@ -2996,11 +3028,23 @@ BfError* CeContext::Fail(const CeFrame& curFrame, const StringImpl& str)
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
void CeContext::AddRebuild(const CeRebuildKey& key, const CeRebuildValue& value)
|
||||||
|
{
|
||||||
|
if (mCurModule == NULL)
|
||||||
|
return;
|
||||||
|
if (mCurModule->mCurTypeInstance == NULL)
|
||||||
|
return;
|
||||||
|
if (mCurModule->mCurTypeInstance->mCeTypeInfo == NULL)
|
||||||
|
mCurModule->mCurTypeInstance->mCeTypeInfo = new BfCeTypeInfo();
|
||||||
|
mCurModule->mCurTypeInstance->mCeTypeInfo->mRebuildMap[key] = value;
|
||||||
|
mCurModule->mCompiler->mHasComptimeRebuilds = true;
|
||||||
|
}
|
||||||
|
|
||||||
uint8* CeContext::CeMalloc(int size)
|
uint8* CeContext::CeMalloc(int size)
|
||||||
{
|
{
|
||||||
#ifdef CE_ENABLE_HEAP
|
#ifdef CE_ENABLE_HEAP
|
||||||
auto heapRef = mHeap->Alloc(size);
|
auto heapRef = mHeap->Alloc(size);
|
||||||
auto ceAddr = BF_CE_STACK_SIZE + heapRef;
|
auto ceAddr = mStackSize + heapRef;
|
||||||
int sizeDelta = (ceAddr + size) - mMemory.mSize;
|
int sizeDelta = (ceAddr + size) - mMemory.mSize;
|
||||||
if (sizeDelta > 0)
|
if (sizeDelta > 0)
|
||||||
mMemory.GrowUninitialized(sizeDelta);
|
mMemory.GrowUninitialized(sizeDelta);
|
||||||
|
@ -3013,7 +3057,7 @@ uint8* CeContext::CeMalloc(int size)
|
||||||
bool CeContext::CeFree(addr_ce addr)
|
bool CeContext::CeFree(addr_ce addr)
|
||||||
{
|
{
|
||||||
#ifdef CE_ENABLE_HEAP
|
#ifdef CE_ENABLE_HEAP
|
||||||
ContiguousHeap::AllocRef heapRef = addr - BF_CE_STACK_SIZE;
|
ContiguousHeap::AllocRef heapRef = addr - mStackSize;
|
||||||
return mHeap->Free(heapRef);
|
return mHeap->Free(heapRef);
|
||||||
#else
|
#else
|
||||||
return true;
|
return true;
|
||||||
|
@ -3702,6 +3746,19 @@ BfIRValue CeContext::CreateConstant(BfModule* module, uint8* ptr, BfType* bfType
|
||||||
charPtr = (char*)(instData + ptrOffset);
|
charPtr = (char*)(instData + ptrOffset);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int64 allocSizeVal = *(int64*)(instData + allocSizeOffset);
|
||||||
|
if ((allocSizeVal & 0x4000000000000000LL) != 0)
|
||||||
|
{
|
||||||
|
int32 ptrVal = *(int32*)(instData + ptrOffset);
|
||||||
|
charPtr = (char*)(ptrVal + memStart);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
charPtr = (char*)(instData + ptrOffset);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
CE_CREATECONST_CHECKPTR(charPtr, lenVal);
|
CE_CREATECONST_CHECKPTR(charPtr, lenVal);
|
||||||
String str(charPtr, lenVal);
|
String str(charPtr, lenVal);
|
||||||
|
@ -4085,7 +4142,7 @@ BfTypedValue CeContext::Call(BfAstNode* targetSrc, BfModule* module, BfMethodIns
|
||||||
if (ceFunction->mInitializeState < CeFunction::InitializeState_Initialized)
|
if (ceFunction->mInitializeState < CeFunction::InitializeState_Initialized)
|
||||||
mCeMachine->PrepareFunction(ceFunction, NULL);
|
mCeMachine->PrepareFunction(ceFunction, NULL);
|
||||||
|
|
||||||
auto stackPtr = &mMemory[0] + BF_CE_STACK_SIZE;
|
auto stackPtr = &mMemory[0] + mStackSize;
|
||||||
auto* memStart = &mMemory[0];
|
auto* memStart = &mMemory[0];
|
||||||
|
|
||||||
BfTypeInstance* thisType = methodInstance->GetOwner();
|
BfTypeInstance* thisType = methodInstance->GetOwner();
|
||||||
|
@ -4107,6 +4164,23 @@ BfTypedValue CeContext::Call(BfAstNode* targetSrc, BfModule* module, BfMethodIns
|
||||||
allocThisSize += appendSizeConstant->mInt32;
|
allocThisSize += appendSizeConstant->mInt32;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (allocThisSize >= mStackSize / 4)
|
||||||
|
{
|
||||||
|
// Resize stack a reasonable size
|
||||||
|
mStackSize = BF_ALIGN(allocThisSize, 0x100000) + BF_CE_DEFAULT_STACK_SIZE;
|
||||||
|
int64 memSize = mStackSize + BF_CE_DEFAULT_HEAP_SIZE;
|
||||||
|
if (memSize > BF_CE_MAX_MEMORY)
|
||||||
|
{
|
||||||
|
Fail("Return value too large (>2GB)");
|
||||||
|
return BfTypedValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (memSize > mMemory.mSize)
|
||||||
|
mMemory.Resize(memSize);
|
||||||
|
stackPtr = &mMemory[0] + mStackSize;
|
||||||
|
memStart = &mMemory[0];
|
||||||
|
}
|
||||||
|
|
||||||
stackPtr -= allocThisSize;
|
stackPtr -= allocThisSize;
|
||||||
auto allocThisPtr = stackPtr;
|
auto allocThisPtr = stackPtr;
|
||||||
memset(allocThisPtr, 0, allocThisSize);
|
memset(allocThisPtr, 0, allocThisSize);
|
||||||
|
@ -4123,6 +4197,7 @@ BfTypedValue CeContext::Call(BfAstNode* targetSrc, BfModule* module, BfMethodIns
|
||||||
{
|
{
|
||||||
stackPtr -= ceModule->mSystem->mPtrSize;
|
stackPtr -= ceModule->mSystem->mPtrSize;
|
||||||
memset(stackPtr, 0, ceModule->mSystem->mPtrSize);
|
memset(stackPtr, 0, ceModule->mSystem->mPtrSize);
|
||||||
|
*(addr_ce*)(stackPtr) = (addr_ce)(allocThisInstAddr + thisType->mInstSize);
|
||||||
allocAppendIdxAddr = stackPtr - memStart;
|
allocAppendIdxAddr = stackPtr - memStart;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4256,7 +4331,14 @@ BfTypedValue CeContext::Call(BfAstNode* targetSrc, BfModule* module, BfMethodIns
|
||||||
}
|
}
|
||||||
|
|
||||||
BfType* usedReturnType = returnType;
|
BfType* usedReturnType = returnType;
|
||||||
BfIRValue constVal = CreateConstant(module, retPtr, returnType, &usedReturnType);
|
BfIRValue constVal;
|
||||||
|
if (returnType->IsObject())
|
||||||
|
{
|
||||||
|
addr_ce retAddr = retPtr - memStart;
|
||||||
|
constVal = CreateConstant(module, (uint8*)&retAddr, returnType, &usedReturnType);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
constVal = CreateConstant(module, retPtr, returnType, &usedReturnType);
|
||||||
if (constVal)
|
if (constVal)
|
||||||
returnValue = BfTypedValue(constVal, usedReturnType);
|
returnValue = BfTypedValue(constVal, usedReturnType);
|
||||||
else
|
else
|
||||||
|
@ -4289,9 +4371,10 @@ BfTypedValue CeContext::Call(BfAstNode* targetSrc, BfModule* module, BfMethodIns
|
||||||
}
|
}
|
||||||
|
|
||||||
#define CE_CHECKALLOC(SIZE) \
|
#define CE_CHECKALLOC(SIZE) \
|
||||||
if ((SIZE < 0) || (uintptr)memSize + (uintptr)SIZE > BF_CE_MAX_MEMORY) \
|
if ((SIZE < 0) || (SIZE >= 0x80000000LL) || ((uintptr)memSize + (uintptr)SIZE > BF_CE_MAX_MEMORY)) \
|
||||||
{ \
|
{ \
|
||||||
_Fail("Maximum memory size exceeded"); \
|
_Fail("Maximum memory size exceeded (2GB)"); \
|
||||||
|
return false; \
|
||||||
}
|
}
|
||||||
|
|
||||||
// This check will fail for addresses < 64K (null pointer), or out-of-bounds
|
// This check will fail for addresses < 64K (null pointer), or out-of-bounds
|
||||||
|
@ -4302,12 +4385,65 @@ BfTypedValue CeContext::Call(BfAstNode* targetSrc, BfModule* module, BfMethodIns
|
||||||
return false; \
|
return false; \
|
||||||
}
|
}
|
||||||
#define CE_CHECKADDR(ADDR, SIZE) \
|
#define CE_CHECKADDR(ADDR, SIZE) \
|
||||||
if (((ADDR) - 0x10000) + (SIZE) > (memSize - 0x10000)) \
|
if (((ADDR) < 0x10000) || ((ADDR) + (SIZE) > memSize)) \
|
||||||
{ \
|
{ \
|
||||||
_Fail("Access violation"); \
|
_Fail("Access violation"); \
|
||||||
return false; \
|
return false; \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define CE_CHECKADDR_STR(STRNAME, ADDR) \
|
||||||
|
{ \
|
||||||
|
addr_ce checkAddr = ADDR; \
|
||||||
|
while (true) \
|
||||||
|
{ \
|
||||||
|
if ((uintptr)checkAddr >= (uintptr)memSize) \
|
||||||
|
{ \
|
||||||
|
break; \
|
||||||
|
} \
|
||||||
|
if (memStart[checkAddr] == 0) \
|
||||||
|
{ \
|
||||||
|
CE_CHECKADDR(ADDR, checkAddr - ADDR + 1); \
|
||||||
|
STRNAME = String::MakeRef((char*)memStart + ADDR, checkAddr - ADDR + 1); \
|
||||||
|
break; \
|
||||||
|
} \
|
||||||
|
checkAddr++; \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define CE_GET_INTERNAL(VAR, ID, KIND) \
|
||||||
|
if (!mInternalDataMap.TryGetValue((int)ID, &VAR)) \
|
||||||
|
{ \
|
||||||
|
_Fail("Invalid internal resource id"); \
|
||||||
|
return false; \
|
||||||
|
} \
|
||||||
|
if (VAR->mKind != KIND) \
|
||||||
|
{ \
|
||||||
|
_Fail("Invalid internal resource kind"); \
|
||||||
|
return false; \
|
||||||
|
} \
|
||||||
|
if (VAR->mReleased) \
|
||||||
|
{ \
|
||||||
|
_Fail("Resource already released"); \
|
||||||
|
return false; \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define CE_REMOVE_INTERNAL(VAR, ID, KIND) \
|
||||||
|
if (!mInternalDataMap.Remove((int)ID, &VAR)) \
|
||||||
|
{ \
|
||||||
|
_Fail("Invalid internal resource id"); \
|
||||||
|
return false; \
|
||||||
|
} \
|
||||||
|
if (VAR->mKind != KIND) \
|
||||||
|
{ \
|
||||||
|
_Fail("Invalid internal resource kind"); \
|
||||||
|
return false; \
|
||||||
|
} \
|
||||||
|
if (VAR->mReleased) \
|
||||||
|
{ \
|
||||||
|
_Fail("Resource already released"); \
|
||||||
|
return false; \
|
||||||
|
}
|
||||||
|
|
||||||
#define CE_GETINST(T) *((T*)(instPtr += sizeof(T)) - 1)
|
#define CE_GETINST(T) *((T*)(instPtr += sizeof(T)) - 1)
|
||||||
#define CE_GETFRAME(T) *(T*)(framePtr + *((int32*)(instPtr += sizeof(int32)) - 1))
|
#define CE_GETFRAME(T) *(T*)(framePtr + *((int32*)(instPtr += sizeof(int32)) - 1))
|
||||||
#define CEOP_BIN(OP, T) \
|
#define CEOP_BIN(OP, T) \
|
||||||
|
@ -4422,7 +4558,7 @@ BfTypedValue CeContext::Call(BfAstNode* targetSrc, BfModule* module, BfMethodIns
|
||||||
instPtr = &ceFunction->mCode[0]; \
|
instPtr = &ceFunction->mCode[0]; \
|
||||||
CE_CHECKSTACK();
|
CE_CHECKSTACK();
|
||||||
|
|
||||||
static void CeSetAddrVal(void* ptr, addr_ce val, int32 ptrSize)
|
static void CeSetAddrVal(void* ptr, int64 val, int32 ptrSize)
|
||||||
{
|
{
|
||||||
if (ptrSize == 4)
|
if (ptrSize == 4)
|
||||||
*(int32*)(ptr) = (int32)val;
|
*(int32*)(ptr) = (int32)val;
|
||||||
|
@ -4490,7 +4626,11 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
|
||||||
}
|
}
|
||||||
else if (checkFunction->mFunctionKind == CeFunctionKind_Malloc)
|
else if (checkFunction->mFunctionKind == CeFunctionKind_Malloc)
|
||||||
{
|
{
|
||||||
int32 size = *(int32*)((uint8*)stackPtr + 4);
|
int64 size;
|
||||||
|
if (ptrSize == 4)
|
||||||
|
size = *(int32*)((uint8*)stackPtr + 4);
|
||||||
|
else
|
||||||
|
size = *(int64*)((uint8*)stackPtr + 8);
|
||||||
CE_CHECKALLOC(size);
|
CE_CHECKALLOC(size);
|
||||||
uint8* ptr = CeMalloc(size);
|
uint8* ptr = CeMalloc(size);
|
||||||
CeSetAddrVal(stackPtr + 0, ptr - memStart, ptrSize);
|
CeSetAddrVal(stackPtr + 0, ptr - memStart, ptrSize);
|
||||||
|
@ -4532,6 +4672,19 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
|
||||||
charPtr = (char*)(strInst + ptrOffset);
|
charPtr = (char*)(strInst + ptrOffset);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int64 allocSizeVal = *(int64*)(strInst + allocSizeOffset);
|
||||||
|
if ((allocSizeVal & 0x4000000000000000LL) != 0)
|
||||||
|
{
|
||||||
|
int32 ptrVal = *(int32*)(strInst + ptrOffset);
|
||||||
|
charPtr = (char*)(ptrVal + memStart);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
charPtr = (char*)(strInst + ptrOffset);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int32 ptrVal = *(int32*)(strInst + ptrOffset);
|
int32 ptrVal = *(int32*)(strInst + ptrOffset);
|
||||||
|
|
||||||
|
@ -4559,13 +4712,21 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
|
||||||
}
|
}
|
||||||
else if (checkFunction->mFunctionKind == CeFunctionKind_DebugWrite_Int)
|
else if (checkFunction->mFunctionKind == CeFunctionKind_DebugWrite_Int)
|
||||||
{
|
{
|
||||||
int32 intVal = *(int32*)((uint8*)stackPtr + 0);
|
if (ceModule->mSystem->mPtrSize == 4)
|
||||||
OutputDebugStrF("Debug Val: %d\n", intVal);
|
{
|
||||||
|
int32 intVal = *(int32*)((uint8*)stackPtr + 0);
|
||||||
|
OutputDebugStrF("Debug Val: %d %X\n", intVal, intVal);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int64 intVal = *(int64*)((uint8*)stackPtr + 0);
|
||||||
|
OutputDebugStrF("Debug Val: %lld %llX\n", intVal, intVal);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (checkFunction->mFunctionKind == CeFunctionKind_GetReflectType)
|
else if (checkFunction->mFunctionKind == CeFunctionKind_GetReflectType)
|
||||||
{
|
{
|
||||||
addr_ce objAddr = *(addr_ce*)((uint8*)stackPtr + ceModule->mSystem->mPtrSize);
|
addr_ce objAddr = *(addr_ce*)((uint8*)stackPtr + ceModule->mSystem->mPtrSize);
|
||||||
CE_CHECKADDR(addr_ce, 4);
|
CE_CHECKADDR(objAddr, 4);
|
||||||
int32 typeId = *(int32*)(objAddr + memStart);
|
int32 typeId = *(int32*)(objAddr + memStart);
|
||||||
|
|
||||||
auto reflectType = GetReflectType(typeId);
|
auto reflectType = GetReflectType(typeId);
|
||||||
|
@ -4921,6 +5082,7 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
|
||||||
}
|
}
|
||||||
if (memStart[checkAddr] == 0)
|
if (memStart[checkAddr] == 0)
|
||||||
break;
|
break;
|
||||||
|
checkAddr++;
|
||||||
}
|
}
|
||||||
CE_CHECKADDR(strAddr, checkAddr - strAddr + 1);
|
CE_CHECKADDR(strAddr, checkAddr - strAddr + 1);
|
||||||
|
|
||||||
|
@ -4959,6 +5121,291 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
|
||||||
memcpy(memStart + strAddr, str, count + 1);
|
memcpy(memStart + strAddr, str, count + 1);
|
||||||
result = count;
|
result = count;
|
||||||
}
|
}
|
||||||
|
else if (checkFunction->mFunctionKind == CeFunctionKind_BfpFile_Close)
|
||||||
|
{
|
||||||
|
addr_ce fileId = *(addr_ce*)((uint8*)stackPtr + 0);
|
||||||
|
addr_ce outResultAddr = *(addr_ce*)((uint8*)stackPtr + ptrSize);
|
||||||
|
|
||||||
|
CE_CHECKADDR(outResultAddr, 4);
|
||||||
|
|
||||||
|
CeInternalData* internalData = NULL;
|
||||||
|
CE_GET_INTERNAL(internalData, (int)fileId, CeInternalData::Kind_File);
|
||||||
|
BfpFile_Close(internalData->mFile, (BfpFileResult*)(memStart + outResultAddr));
|
||||||
|
}
|
||||||
|
else if (checkFunction->mFunctionKind == CeFunctionKind_BfpFile_Create)
|
||||||
|
{
|
||||||
|
void* resultPtr = ((uint8*)stackPtr + 0);
|
||||||
|
addr_ce nameAddr = *(addr_ce*)((uint8*)stackPtr + ptrSize);
|
||||||
|
int createKind = *(int*)((uint8*)stackPtr + ptrSize + ptrSize);
|
||||||
|
int createFlags = *(int*)((uint8*)stackPtr + ptrSize + ptrSize + 4);
|
||||||
|
int createFileAttrs = *(int*)((uint8*)stackPtr + ptrSize + ptrSize + 4 + 4);
|
||||||
|
addr_ce outResultAddr = *(addr_ce*)((uint8*)stackPtr + ptrSize + ptrSize + 4 + 4 + 4);
|
||||||
|
|
||||||
|
String path;
|
||||||
|
CE_CHECKADDR_STR(path, nameAddr);
|
||||||
|
CE_CHECKADDR(outResultAddr, 4);
|
||||||
|
|
||||||
|
BfProject* activeProject = NULL;
|
||||||
|
auto activeTypeDef = mCurModule->GetActiveTypeDef();
|
||||||
|
if (activeTypeDef != NULL)
|
||||||
|
activeProject = activeTypeDef->mProject;
|
||||||
|
if (activeProject != NULL)
|
||||||
|
path = GetAbsPath(path, activeProject->mDirectory);
|
||||||
|
|
||||||
|
auto bfpFile = BfpFile_Create(path.c_str(), (BfpFileCreateKind)createKind, (BfpFileCreateFlags)createFlags, (BfpFileAttributes)createFileAttrs, (BfpFileResult*)(memStart + outResultAddr));
|
||||||
|
if (bfpFile != NULL)
|
||||||
|
{
|
||||||
|
if ((createKind == BfpFileCreateKind_OpenExisting) || (createKind == BfpFileCreateKind_OpenAlways))
|
||||||
|
{
|
||||||
|
auto timeStamp = BfpFile_GetTime_LastWrite(path.c_str());
|
||||||
|
if (timeStamp != 0)
|
||||||
|
{
|
||||||
|
CeRebuildKey rebuildKey;
|
||||||
|
rebuildKey.mKind = CeRebuildKey::Kind_File;
|
||||||
|
rebuildKey.mString = path;
|
||||||
|
|
||||||
|
CeRebuildValue rebuildValue;
|
||||||
|
rebuildValue.mInt = timeStamp;
|
||||||
|
|
||||||
|
AddRebuild(rebuildKey, rebuildValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CeInternalData* internalData = new CeInternalData();
|
||||||
|
internalData->mKind = CeInternalData::Kind_File;
|
||||||
|
internalData->mFile = bfpFile;
|
||||||
|
mInternalDataMap[++mCurHandleId] = internalData;
|
||||||
|
CeSetAddrVal(resultPtr, mCurHandleId, ptrSize);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
CeSetAddrVal(resultPtr, 0, ptrSize);
|
||||||
|
}
|
||||||
|
else if (checkFunction->mFunctionKind == CeFunctionKind_BfpFile_Flush)
|
||||||
|
{
|
||||||
|
addr_ce fileId = *(addr_ce*)((uint8*)stackPtr + 0);
|
||||||
|
CeInternalData* internalData = NULL;
|
||||||
|
CE_GET_INTERNAL(internalData, (int)fileId, CeInternalData::Kind_File);
|
||||||
|
BfpFile_Flush(internalData->mFile);
|
||||||
|
}
|
||||||
|
else if (checkFunction->mFunctionKind == CeFunctionKind_BfpFile_GetFileSize)
|
||||||
|
{
|
||||||
|
int64& result = *(int64*)((uint8*)stackPtr + 0);
|
||||||
|
addr_ce fileId = *(addr_ce*)((uint8*)stackPtr + 8);
|
||||||
|
CeInternalData* internalData = NULL;
|
||||||
|
CE_GET_INTERNAL(internalData, (int)fileId, CeInternalData::Kind_File);
|
||||||
|
result = BfpFile_GetFileSize(internalData->mFile);
|
||||||
|
}
|
||||||
|
else if (checkFunction->mFunctionKind == CeFunctionKind_BfpFile_Read)
|
||||||
|
{
|
||||||
|
void* resultPtr = ((uint8*)stackPtr + 0);
|
||||||
|
addr_ce fileId = *(addr_ce*)((uint8*)stackPtr + ptrSize);
|
||||||
|
addr_ce bufferPtr = *(addr_ce*)((uint8*)stackPtr + ptrSize + ptrSize);
|
||||||
|
intptr bufferSize = *(addr_ce*)((uint8*)stackPtr + ptrSize + ptrSize + ptrSize);
|
||||||
|
int timeoutMS = *(int32*)((uint8*)stackPtr + ptrSize + ptrSize + ptrSize + ptrSize);
|
||||||
|
addr_ce outResultAddr = *(addr_ce*)((uint8*)stackPtr + ptrSize + ptrSize + ptrSize + ptrSize + ptrSize);
|
||||||
|
|
||||||
|
CE_CHECKADDR(bufferPtr, bufferSize);
|
||||||
|
CE_CHECKADDR(outResultAddr, 4);
|
||||||
|
|
||||||
|
CeInternalData* internalData = NULL;
|
||||||
|
CE_GET_INTERNAL(internalData, (int)fileId, CeInternalData::Kind_File);
|
||||||
|
int64 result = BfpFile_Read(internalData->mFile, memStart + bufferPtr, bufferSize, timeoutMS, (BfpFileResult*)(memStart + outResultAddr));
|
||||||
|
CeSetAddrVal(resultPtr, result, ptrSize);
|
||||||
|
}
|
||||||
|
else if (checkFunction->mFunctionKind == CeFunctionKind_BfpFile_Release)
|
||||||
|
{
|
||||||
|
addr_ce fileId = *(addr_ce*)((uint8*)stackPtr + 0);
|
||||||
|
|
||||||
|
CeInternalData* internalData = NULL;
|
||||||
|
CE_REMOVE_INTERNAL(internalData, (int)fileId, CeInternalData::Kind_File);
|
||||||
|
delete internalData;
|
||||||
|
}
|
||||||
|
else if (checkFunction->mFunctionKind == CeFunctionKind_BfpFile_Seek)
|
||||||
|
{
|
||||||
|
int64& result = *(int64*)((uint8*)stackPtr + 0);
|
||||||
|
addr_ce fileId = *(addr_ce*)((uint8*)stackPtr + 8);
|
||||||
|
int64 offset = *(int64*)((uint8*)stackPtr + 8 + ptrSize);
|
||||||
|
int seekKind = *(int*)((uint8*)stackPtr + 8 + ptrSize + 8);
|
||||||
|
CeInternalData* internalData = NULL;
|
||||||
|
CE_GET_INTERNAL(internalData, (int)fileId, CeInternalData::Kind_File);
|
||||||
|
result = BfpFile_Seek(internalData->mFile, offset, (BfpFileSeekKind)seekKind);
|
||||||
|
}
|
||||||
|
else if (checkFunction->mFunctionKind == CeFunctionKind_BfpFile_Truncate)
|
||||||
|
{
|
||||||
|
addr_ce fileId = *(addr_ce*)((uint8*)stackPtr + 0);
|
||||||
|
addr_ce outResultAddr = *(addr_ce*)((uint8*)stackPtr + ptrSize);
|
||||||
|
|
||||||
|
CE_CHECKADDR(outResultAddr, 4);
|
||||||
|
|
||||||
|
CeInternalData* internalData = NULL;
|
||||||
|
CE_GET_INTERNAL(internalData, (int)fileId, CeInternalData::Kind_File);
|
||||||
|
BfpFile_Truncate(internalData->mFile, (BfpFileResult*)(memStart + outResultAddr));
|
||||||
|
}
|
||||||
|
else if (checkFunction->mFunctionKind == CeFunctionKind_BfpFile_Write)
|
||||||
|
{
|
||||||
|
void* resultPtr = ((uint8*)stackPtr + 0);
|
||||||
|
addr_ce fileId = *(addr_ce*)((uint8*)stackPtr + ptrSize);
|
||||||
|
addr_ce bufferPtr = *(addr_ce*)((uint8*)stackPtr + ptrSize + ptrSize);
|
||||||
|
intptr bufferSize = *(addr_ce*)((uint8*)stackPtr + ptrSize + ptrSize + ptrSize);
|
||||||
|
int timeoutMS = *(int32*)((uint8*)stackPtr + ptrSize + ptrSize + ptrSize + ptrSize);
|
||||||
|
addr_ce outResultAddr = *(addr_ce*)((uint8*)stackPtr + ptrSize + ptrSize + ptrSize + ptrSize + ptrSize);
|
||||||
|
|
||||||
|
CE_CHECKADDR(bufferPtr, bufferSize);
|
||||||
|
CE_CHECKADDR(outResultAddr, 4);
|
||||||
|
|
||||||
|
CeInternalData* internalData = NULL;
|
||||||
|
CE_GET_INTERNAL(internalData, (int)fileId, CeInternalData::Kind_File);
|
||||||
|
int64 result = BfpFile_Write(internalData->mFile, memStart + bufferPtr, bufferSize, timeoutMS, (outResultAddr == 0) ? NULL : (BfpFileResult*)(memStart + outResultAddr));
|
||||||
|
CeSetAddrVal(resultPtr, result, ptrSize);
|
||||||
|
}
|
||||||
|
else if (checkFunction->mFunctionKind == CeFunctionKind_BfpSpawn_Create)
|
||||||
|
{
|
||||||
|
void* resultPtr = ((uint8*)stackPtr + 0);
|
||||||
|
addr_ce targetPathAddr = *(addr_ce*)((uint8*)stackPtr + ptrSize);
|
||||||
|
addr_ce argsAddr = *(addr_ce*)((uint8*)stackPtr + ptrSize + ptrSize);
|
||||||
|
addr_ce workingDirAddr = *(addr_ce*)((uint8*)stackPtr + ptrSize + ptrSize + ptrSize);
|
||||||
|
addr_ce envAddr = *(addr_ce*)((uint8*)stackPtr + ptrSize + ptrSize + ptrSize + ptrSize);
|
||||||
|
int flags = *(int*)((uint8*)stackPtr + ptrSize + ptrSize + ptrSize + ptrSize + ptrSize);
|
||||||
|
addr_ce outResultAddr = *(addr_ce*)((uint8*)stackPtr + ptrSize + ptrSize + ptrSize + ptrSize + ptrSize + 4);
|
||||||
|
|
||||||
|
String targetPath;
|
||||||
|
CE_CHECKADDR_STR(targetPath, targetPathAddr);
|
||||||
|
String args;
|
||||||
|
if (argsAddr != 0)
|
||||||
|
CE_CHECKADDR_STR(args, argsAddr);
|
||||||
|
String workingDir;
|
||||||
|
if (workingDirAddr != 0)
|
||||||
|
CE_CHECKADDR_STR(workingDir, workingDirAddr);
|
||||||
|
String env;
|
||||||
|
if (envAddr != 0)
|
||||||
|
CE_CHECKADDR_STR(env, envAddr);
|
||||||
|
CE_CHECKADDR(outResultAddr, 4);
|
||||||
|
|
||||||
|
if ((targetPath.Contains('/')) || (targetPath.Contains('\\')))
|
||||||
|
{
|
||||||
|
BfProject* activeProject = NULL;
|
||||||
|
auto activeTypeDef = mCurModule->GetActiveTypeDef();
|
||||||
|
if (activeTypeDef != NULL)
|
||||||
|
activeProject = activeTypeDef->mProject;
|
||||||
|
if (activeProject != NULL)
|
||||||
|
targetPath = GetAbsPath(targetPath, activeProject->mDirectory);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto bfpSpawn = BfpSpawn_Create(targetPath.c_str(),
|
||||||
|
(argsAddr == 0) ? NULL : args.c_str(),
|
||||||
|
(workingDirAddr == 0) ? NULL : workingDir.c_str(),
|
||||||
|
(envAddr == 0) ? NULL : env.c_str(), (BfpSpawnFlags)flags, (outResultAddr == 0) ? NULL : (BfpSpawnResult*)(memStart + outResultAddr));
|
||||||
|
if (bfpSpawn != NULL)
|
||||||
|
{
|
||||||
|
CeInternalData* internalData = new CeInternalData();
|
||||||
|
internalData->mKind = CeInternalData::Kind_Spawn;
|
||||||
|
internalData->mSpawn = bfpSpawn;
|
||||||
|
mInternalDataMap[++mCurHandleId] = internalData;
|
||||||
|
CeSetAddrVal(resultPtr, mCurHandleId, ptrSize);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
CeSetAddrVal(resultPtr, 0, ptrSize);
|
||||||
|
}
|
||||||
|
else if (checkFunction->mFunctionKind == CeFunctionKind_BfpSpawn_GetStdHandles)
|
||||||
|
{
|
||||||
|
addr_ce spawnId = *(addr_ce*)((uint8*)stackPtr + 0);
|
||||||
|
addr_ce outStdInAddr = *(addr_ce*)((uint8*)stackPtr + ptrSize);
|
||||||
|
addr_ce outStdOutAddr = *(addr_ce*)((uint8*)stackPtr + ptrSize + ptrSize);
|
||||||
|
addr_ce outStdErrAddr = *(addr_ce*)((uint8*)stackPtr + ptrSize + ptrSize + ptrSize);
|
||||||
|
|
||||||
|
CE_CHECKADDR(outStdInAddr, ptrSize);
|
||||||
|
CE_CHECKADDR(outStdOutAddr, ptrSize);
|
||||||
|
CE_CHECKADDR(outStdErrAddr, ptrSize);
|
||||||
|
|
||||||
|
BfpFile* outStdIn = NULL;
|
||||||
|
BfpFile* outStdOut = NULL;
|
||||||
|
BfpFile* outStdErr = NULL;
|
||||||
|
|
||||||
|
CeInternalData* internalData = NULL;
|
||||||
|
CE_GET_INTERNAL(internalData, (int)spawnId, CeInternalData::Kind_Spawn);
|
||||||
|
BfpSpawn_GetStdHandles(internalData->mSpawn,
|
||||||
|
(outStdInAddr != 0) ? &outStdIn : NULL,
|
||||||
|
(outStdOutAddr != 0) ? &outStdOut : NULL,
|
||||||
|
(outStdErrAddr != 0) ? &outStdErr : NULL);
|
||||||
|
|
||||||
|
auto _SetHandle = [&](addr_ce addr, BfpFile* file)
|
||||||
|
{
|
||||||
|
if (addr == 0)
|
||||||
|
return;
|
||||||
|
if (file != NULL)
|
||||||
|
{
|
||||||
|
CeInternalData* internalData = new CeInternalData();
|
||||||
|
internalData->mKind = CeInternalData::Kind_File;
|
||||||
|
internalData->mFile = file;
|
||||||
|
mInternalDataMap[++mCurHandleId] = internalData;
|
||||||
|
CeSetAddrVal(memStart + addr, mCurHandleId, ptrSize);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
_SetHandle(outStdInAddr, outStdIn);
|
||||||
|
_SetHandle(outStdOutAddr, outStdOut);
|
||||||
|
_SetHandle(outStdErrAddr, outStdErr);
|
||||||
|
}
|
||||||
|
else if (checkFunction->mFunctionKind == CeFunctionKind_BfpSpawn_Kill)
|
||||||
|
{
|
||||||
|
addr_ce spawnId = *(addr_ce*)((uint8*)stackPtr + 0);
|
||||||
|
int exitCode = *(int*)((uint8*)stackPtr + ptrSize);
|
||||||
|
int killFlags = *(int*)((uint8*)stackPtr + ptrSize + ptrSize);
|
||||||
|
addr_ce outResultAddr = *(addr_ce*)((uint8*)stackPtr + ptrSize + ptrSize + ptrSize);
|
||||||
|
|
||||||
|
CE_CHECKADDR(outResultAddr, 4);
|
||||||
|
|
||||||
|
CeInternalData* internalData = NULL;
|
||||||
|
CE_GET_INTERNAL(internalData, (int)spawnId, CeInternalData::Kind_Spawn);
|
||||||
|
BfpSpawn_Kill(internalData->mSpawn, exitCode, (BfpKillFlags)killFlags, (BfpSpawnResult*)(memStart + outResultAddr));
|
||||||
|
}
|
||||||
|
else if (checkFunction->mFunctionKind == CeFunctionKind_BfpSpawn_Release)
|
||||||
|
{
|
||||||
|
addr_ce spawnId = *(addr_ce*)((uint8*)stackPtr + 0);
|
||||||
|
CeInternalData* internalData = NULL;
|
||||||
|
CE_GET_INTERNAL(internalData, (int)spawnId, CeInternalData::Kind_Spawn);
|
||||||
|
internalData->mReleased = true;
|
||||||
|
}
|
||||||
|
else if (checkFunction->mFunctionKind == CeFunctionKind_BfpSpawn_WaitFor)
|
||||||
|
{
|
||||||
|
bool& result = *(bool*)((uint8*)stackPtr + 0);
|
||||||
|
addr_ce spawnId = *(addr_ce*)((uint8*)stackPtr + 1);
|
||||||
|
int waitMS = *(int*)((uint8*)stackPtr + 1 + ptrSize);
|
||||||
|
addr_ce outExitCodeAddr = *(addr_ce*)((uint8*)stackPtr + 1 + ptrSize + ptrSize);
|
||||||
|
addr_ce outResultAddr = *(addr_ce*)((uint8*)stackPtr + 1 + ptrSize + ptrSize + ptrSize);
|
||||||
|
|
||||||
|
CE_CHECKADDR(outExitCodeAddr, ptrSize);
|
||||||
|
if (outResultAddr != 0)
|
||||||
|
CE_CHECKADDR(outResultAddr, 4);
|
||||||
|
|
||||||
|
CeInternalData* internalData = NULL;
|
||||||
|
CE_GET_INTERNAL(internalData, (int)spawnId, CeInternalData::Kind_Spawn);
|
||||||
|
|
||||||
|
int outExitCode = 0;
|
||||||
|
int timeLeft = waitMS;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
if (*fastFinishPtr)
|
||||||
|
{
|
||||||
|
result = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
int waitTime = 20;
|
||||||
|
if (timeLeft >= 0)
|
||||||
|
{
|
||||||
|
waitTime = BF_MIN(timeLeft, 20);
|
||||||
|
timeLeft -= waitTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
result = BfpSpawn_WaitFor(internalData->mSpawn, waitTime, &outExitCode, (outResultAddr == 0) ? NULL : (BfpSpawnResult*)(memStart + outResultAddr));
|
||||||
|
if (result)
|
||||||
|
break;
|
||||||
|
if (waitTime == 0)
|
||||||
|
break;
|
||||||
|
} while (true);
|
||||||
|
*(int*)(memStart + outExitCodeAddr) = outExitCode;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Fail(_GetCurFrame(), StrFormat("Unable to invoke extern method '%s'", ceModule->MethodToString(checkFunction->mMethodInstance).c_str()));
|
Fail(_GetCurFrame(), StrFormat("Unable to invoke extern method '%s'", ceModule->MethodToString(checkFunction->mMethodInstance).c_str()));
|
||||||
|
@ -4989,6 +5436,8 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
|
||||||
int callCount = 0;
|
int callCount = 0;
|
||||||
int instIdx = 0;
|
int instIdx = 0;
|
||||||
|
|
||||||
|
CE_CHECKSTACK();
|
||||||
|
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
if (*fastFinishPtr)
|
if (*fastFinishPtr)
|
||||||
|
@ -5004,7 +5453,6 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
|
||||||
}
|
}
|
||||||
|
|
||||||
++instIdx;
|
++instIdx;
|
||||||
|
|
||||||
CeOp op = CE_GETINST(CeOp);
|
CeOp op = CE_GETINST(CeOp);
|
||||||
switch (op)
|
switch (op)
|
||||||
{
|
{
|
||||||
|
@ -5132,7 +5580,11 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
|
||||||
case CeOp_Malloc:
|
case CeOp_Malloc:
|
||||||
{
|
{
|
||||||
auto frameOfs = CE_GETINST(int32);
|
auto frameOfs = CE_GETINST(int32);
|
||||||
int32 size = CE_GETFRAME(int32);
|
int64 size;
|
||||||
|
if (ptrSize == 4)
|
||||||
|
size = CE_GETFRAME(int32);
|
||||||
|
else
|
||||||
|
size = CE_GETFRAME(int64);
|
||||||
CE_CHECKALLOC(size);
|
CE_CHECKALLOC(size);
|
||||||
uint8* mem = CeMalloc(size);
|
uint8* mem = CeMalloc(size);
|
||||||
_FixVariables();
|
_FixVariables();
|
||||||
|
@ -5580,7 +6032,12 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
|
||||||
|
|
||||||
auto valueType = bfType->ToTypeInstance();
|
auto valueType = bfType->ToTypeInstance();
|
||||||
if (valueType->mVirtualMethodTable.IsEmpty())
|
if (valueType->mVirtualMethodTable.IsEmpty())
|
||||||
ceModule->PopulateType(valueType, BfPopulateType_DataAndMethods);
|
ceModule->PopulateType(valueType, BfPopulateType_Full_Force);
|
||||||
|
if (valueType->mVirtualMethodTable.IsEmpty())
|
||||||
|
{
|
||||||
|
_Fail("Empty virtual table");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
auto methodInstance = (BfMethodInstance*)valueType->mVirtualMethodTable[virtualIdx].mImplementingMethod;
|
auto methodInstance = (BfMethodInstance*)valueType->mVirtualMethodTable[virtualIdx].mImplementingMethod;
|
||||||
|
|
||||||
auto callFunction = mCeMachine->GetPreparedFunction(methodInstance);
|
auto callFunction = mCeMachine->GetPreparedFunction(methodInstance);
|
||||||
|
@ -5624,6 +6081,13 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
|
||||||
{
|
{
|
||||||
if (iface.mInterfaceType == ifaceType)
|
if (iface.mInterfaceType == ifaceType)
|
||||||
{
|
{
|
||||||
|
if (valueType->mInterfaceMethodTable.IsEmpty())
|
||||||
|
ceModule->PopulateType(valueType, BfPopulateType_Full_Force);
|
||||||
|
if (valueType->mInterfaceMethodTable.IsEmpty())
|
||||||
|
{
|
||||||
|
_Fail("Empty interface table");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
methodInstance = valueType->mInterfaceMethodTable[iface.mStartInterfaceTableIdx + methodIdx].mMethodRef;
|
methodInstance = valueType->mInterfaceMethodTable[iface.mStartInterfaceTableIdx + methodIdx].mMethodRef;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -6338,6 +6802,8 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
|
||||||
_Fail("Unhandled op");
|
_Fail("Unhandled op");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//BF_ASSERT(_CrtCheckMemory() != 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -6893,6 +7359,34 @@ void CeMachine::CheckFunctionKind(CeFunction* ceFunction)
|
||||||
{
|
{
|
||||||
if (methodDef->mName == "BfpSystem_GetTimeStamp")
|
if (methodDef->mName == "BfpSystem_GetTimeStamp")
|
||||||
ceFunction->mFunctionKind = CeFunctionKind_BfpSystem_GetTimeStamp;
|
ceFunction->mFunctionKind = CeFunctionKind_BfpSystem_GetTimeStamp;
|
||||||
|
else if (methodDef->mName == "BfpFile_Close")
|
||||||
|
ceFunction->mFunctionKind = CeFunctionKind_BfpFile_Close;
|
||||||
|
else if (methodDef->mName == "BfpFile_Create")
|
||||||
|
ceFunction->mFunctionKind = CeFunctionKind_BfpFile_Create;
|
||||||
|
else if (methodDef->mName == "BfpFile_Flush")
|
||||||
|
ceFunction->mFunctionKind = CeFunctionKind_BfpFile_Flush;
|
||||||
|
else if (methodDef->mName == "BfpFile_GetFileSize")
|
||||||
|
ceFunction->mFunctionKind = CeFunctionKind_BfpFile_GetFileSize;
|
||||||
|
else if (methodDef->mName == "BfpFile_Read")
|
||||||
|
ceFunction->mFunctionKind = CeFunctionKind_BfpFile_Read;
|
||||||
|
else if (methodDef->mName == "BfpFile_Release")
|
||||||
|
ceFunction->mFunctionKind = CeFunctionKind_BfpFile_Release;
|
||||||
|
else if (methodDef->mName == "BfpFile_Seek")
|
||||||
|
ceFunction->mFunctionKind = CeFunctionKind_BfpFile_Seek;
|
||||||
|
else if (methodDef->mName == "BfpFile_Truncate")
|
||||||
|
ceFunction->mFunctionKind = CeFunctionKind_BfpFile_Truncate;
|
||||||
|
else if (methodDef->mName == "BfpFile_Write")
|
||||||
|
ceFunction->mFunctionKind = CeFunctionKind_BfpFile_Write;
|
||||||
|
else if (methodDef->mName == "BfpSpawn_Create")
|
||||||
|
ceFunction->mFunctionKind = CeFunctionKind_BfpSpawn_Create;
|
||||||
|
else if (methodDef->mName == "BfpSpawn_GetStdHandles")
|
||||||
|
ceFunction->mFunctionKind = CeFunctionKind_BfpSpawn_GetStdHandles;
|
||||||
|
else if (methodDef->mName == "BfpSpawn_Kill")
|
||||||
|
ceFunction->mFunctionKind = CeFunctionKind_BfpSpawn_Kill;
|
||||||
|
else if (methodDef->mName == "BfpSpawn_Release")
|
||||||
|
ceFunction->mFunctionKind = CeFunctionKind_BfpSpawn_Release;
|
||||||
|
else if (methodDef->mName == "BfpSpawn_WaitFor")
|
||||||
|
ceFunction->mFunctionKind = CeFunctionKind_BfpSpawn_WaitFor;
|
||||||
}
|
}
|
||||||
else if (owner->IsInstanceOf(mCeModule->mCompiler->mChar32TypeDef))
|
else if (owner->IsInstanceOf(mCeModule->mCompiler->mChar32TypeDef))
|
||||||
{
|
{
|
||||||
|
@ -6926,43 +7420,43 @@ void CeMachine::CheckFunctionKind(CeFunction* ceFunction)
|
||||||
{
|
{
|
||||||
if (methodDef->mName == "Abs")
|
if (methodDef->mName == "Abs")
|
||||||
ceFunction->mFunctionKind = CeFunctionKind_Math_Abs;
|
ceFunction->mFunctionKind = CeFunctionKind_Math_Abs;
|
||||||
if (methodDef->mName == "Acos")
|
else if (methodDef->mName == "Acos")
|
||||||
ceFunction->mFunctionKind = CeFunctionKind_Math_Acos;
|
ceFunction->mFunctionKind = CeFunctionKind_Math_Acos;
|
||||||
if (methodDef->mName == "Asin")
|
else if (methodDef->mName == "Asin")
|
||||||
ceFunction->mFunctionKind = CeFunctionKind_Math_Asin;
|
ceFunction->mFunctionKind = CeFunctionKind_Math_Asin;
|
||||||
if (methodDef->mName == "Atan")
|
else if (methodDef->mName == "Atan")
|
||||||
ceFunction->mFunctionKind = CeFunctionKind_Math_Atan;
|
ceFunction->mFunctionKind = CeFunctionKind_Math_Atan;
|
||||||
if (methodDef->mName == "Atan2")
|
else if (methodDef->mName == "Atan2")
|
||||||
ceFunction->mFunctionKind = CeFunctionKind_Math_Atan2;
|
ceFunction->mFunctionKind = CeFunctionKind_Math_Atan2;
|
||||||
if (methodDef->mName == "Ceiling")
|
else if (methodDef->mName == "Ceiling")
|
||||||
ceFunction->mFunctionKind = CeFunctionKind_Math_Ceiling;
|
ceFunction->mFunctionKind = CeFunctionKind_Math_Ceiling;
|
||||||
if (methodDef->mName == "Cos")
|
else if (methodDef->mName == "Cos")
|
||||||
ceFunction->mFunctionKind = CeFunctionKind_Math_Cos;
|
ceFunction->mFunctionKind = CeFunctionKind_Math_Cos;
|
||||||
if (methodDef->mName == "Cosh")
|
else if (methodDef->mName == "Cosh")
|
||||||
ceFunction->mFunctionKind = CeFunctionKind_Math_Cosh;
|
ceFunction->mFunctionKind = CeFunctionKind_Math_Cosh;
|
||||||
if (methodDef->mName == "Exp")
|
else if (methodDef->mName == "Exp")
|
||||||
ceFunction->mFunctionKind = CeFunctionKind_Math_Exp;
|
ceFunction->mFunctionKind = CeFunctionKind_Math_Exp;
|
||||||
if (methodDef->mName == "Floor")
|
else if (methodDef->mName == "Floor")
|
||||||
ceFunction->mFunctionKind = CeFunctionKind_Math_Floor;
|
ceFunction->mFunctionKind = CeFunctionKind_Math_Floor;
|
||||||
if (methodDef->mName == "Log")
|
else if (methodDef->mName == "Log")
|
||||||
ceFunction->mFunctionKind = CeFunctionKind_Math_Log;
|
ceFunction->mFunctionKind = CeFunctionKind_Math_Log;
|
||||||
if (methodDef->mName == "Log10")
|
else if (methodDef->mName == "Log10")
|
||||||
ceFunction->mFunctionKind = CeFunctionKind_Math_Log10;
|
ceFunction->mFunctionKind = CeFunctionKind_Math_Log10;
|
||||||
if (methodDef->mName == "Mod")
|
else if (methodDef->mName == "Mod")
|
||||||
ceFunction->mFunctionKind = CeFunctionKind_Math_Mod;
|
ceFunction->mFunctionKind = CeFunctionKind_Math_Mod;
|
||||||
if (methodDef->mName == "Pow")
|
else if (methodDef->mName == "Pow")
|
||||||
ceFunction->mFunctionKind = CeFunctionKind_Math_Pow;
|
ceFunction->mFunctionKind = CeFunctionKind_Math_Pow;
|
||||||
if (methodDef->mName == "Round")
|
else if (methodDef->mName == "Round")
|
||||||
ceFunction->mFunctionKind = CeFunctionKind_Math_Round;
|
ceFunction->mFunctionKind = CeFunctionKind_Math_Round;
|
||||||
if (methodDef->mName == "Sin")
|
else if (methodDef->mName == "Sin")
|
||||||
ceFunction->mFunctionKind = CeFunctionKind_Math_Sin;
|
ceFunction->mFunctionKind = CeFunctionKind_Math_Sin;
|
||||||
if (methodDef->mName == "Sinh")
|
else if (methodDef->mName == "Sinh")
|
||||||
ceFunction->mFunctionKind = CeFunctionKind_Math_Sinh;
|
ceFunction->mFunctionKind = CeFunctionKind_Math_Sinh;
|
||||||
if (methodDef->mName == "Sqrt")
|
else if (methodDef->mName == "Sqrt")
|
||||||
ceFunction->mFunctionKind = CeFunctionKind_Math_Sqrt;
|
ceFunction->mFunctionKind = CeFunctionKind_Math_Sqrt;
|
||||||
if (methodDef->mName == "Tan")
|
else if (methodDef->mName == "Tan")
|
||||||
ceFunction->mFunctionKind = CeFunctionKind_Math_Tan;
|
ceFunction->mFunctionKind = CeFunctionKind_Math_Tan;
|
||||||
if (methodDef->mName == "Tanh")
|
else if (methodDef->mName == "Tanh")
|
||||||
ceFunction->mFunctionKind = CeFunctionKind_Math_Tanh;
|
ceFunction->mFunctionKind = CeFunctionKind_Math_Tanh;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7217,8 +7711,10 @@ CeContext* CeMachine::AllocContext()
|
||||||
ceContext->mCurEmitContext = mCurEmitContext;
|
ceContext->mCurEmitContext = mCurEmitContext;
|
||||||
mCurEmitContext = NULL;
|
mCurEmitContext = NULL;
|
||||||
mExecuteId++;
|
mExecuteId++;
|
||||||
ceContext->mMemory.Resize(BF_CE_STACK_SIZE);
|
ceContext->mStackSize = BF_CE_DEFAULT_STACK_SIZE;
|
||||||
|
ceContext->mMemory.Resize(ceContext->mStackSize);
|
||||||
ceContext->mExecuteId = mExecuteId;
|
ceContext->mExecuteId = mExecuteId;
|
||||||
|
ceContext->mCurHandleId = 0;
|
||||||
return ceContext;
|
return ceContext;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7237,6 +7733,9 @@ void CeMachine::ReleaseContext(CeContext* ceContext)
|
||||||
mCurEmitContext = ceContext->mCurEmitContext;
|
mCurEmitContext = ceContext->mCurEmitContext;
|
||||||
ceContext->mCurEmitContext = NULL;
|
ceContext->mCurEmitContext = NULL;
|
||||||
mContextList.Add(ceContext);
|
mContextList.Add(ceContext);
|
||||||
|
for (auto kv : ceContext->mInternalDataMap)
|
||||||
|
delete kv.mValue;
|
||||||
|
ceContext->mInternalDataMap.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
BfTypedValue CeMachine::Call(BfAstNode* targetSrc, BfModule* module, BfMethodInstance* methodInstance, const BfSizedArray<BfIRValue>& args, CeEvalFlags flags, BfType* expectingType)
|
BfTypedValue CeMachine::Call(BfAstNode* targetSrc, BfModule* module, BfMethodInstance* methodInstance, const BfSizedArray<BfIRValue>& args, CeEvalFlags flags, BfType* expectingType)
|
||||||
|
@ -7246,3 +7745,5 @@ BfTypedValue CeMachine::Call(BfAstNode* targetSrc, BfModule* module, BfMethodIns
|
||||||
ReleaseContext(ceContext);
|
ReleaseContext(ceContext);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -264,6 +264,37 @@ public:
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class CeInternalData
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
enum Kind
|
||||||
|
{
|
||||||
|
Kind_None,
|
||||||
|
Kind_File,
|
||||||
|
Kind_FindFileData,
|
||||||
|
Kind_Spawn
|
||||||
|
};
|
||||||
|
|
||||||
|
public:
|
||||||
|
Kind mKind;
|
||||||
|
bool mReleased;
|
||||||
|
|
||||||
|
union
|
||||||
|
{
|
||||||
|
BfpFile* mFile;
|
||||||
|
BfpFindFileData* mFindFileData;
|
||||||
|
BfpSpawn* mSpawn;
|
||||||
|
};
|
||||||
|
|
||||||
|
CeInternalData()
|
||||||
|
{
|
||||||
|
mKind = Kind_None;
|
||||||
|
mReleased = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
~CeInternalData();
|
||||||
|
};
|
||||||
|
|
||||||
enum CeFunctionKind
|
enum CeFunctionKind
|
||||||
{
|
{
|
||||||
CeFunctionKind_NotSet,
|
CeFunctionKind_NotSet,
|
||||||
|
@ -294,6 +325,21 @@ enum CeFunctionKind
|
||||||
CeFunctionKind_EmitMethodExit,
|
CeFunctionKind_EmitMethodExit,
|
||||||
CeFunctionKind_EmitMixin,
|
CeFunctionKind_EmitMixin,
|
||||||
|
|
||||||
|
CeFunctionKind_BfpFile_Close,
|
||||||
|
CeFunctionKind_BfpFile_Create,
|
||||||
|
CeFunctionKind_BfpFile_Flush,
|
||||||
|
CeFunctionKind_BfpFile_GetFileSize,
|
||||||
|
CeFunctionKind_BfpFile_Read,
|
||||||
|
CeFunctionKind_BfpFile_Release,
|
||||||
|
CeFunctionKind_BfpFile_Seek,
|
||||||
|
CeFunctionKind_BfpFile_Truncate,
|
||||||
|
CeFunctionKind_BfpFile_Write,
|
||||||
|
CeFunctionKind_BfpSpawn_Create,
|
||||||
|
CeFunctionKind_BfpSpawn_GetStdHandles,
|
||||||
|
CeFunctionKind_BfpSpawn_Kill,
|
||||||
|
CeFunctionKind_BfpSpawn_Release,
|
||||||
|
CeFunctionKind_BfpSpawn_WaitFor,
|
||||||
|
|
||||||
CeFunctionKind_BfpSystem_GetTimeStamp,
|
CeFunctionKind_BfpSystem_GetTimeStamp,
|
||||||
CeFunctionKind_Sleep,
|
CeFunctionKind_Sleep,
|
||||||
|
|
||||||
|
@ -501,10 +547,11 @@ public:
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#define BF_CE_STACK_SIZE 4*1024*1024
|
#define BF_CE_DEFAULT_STACK_SIZE 4*1024*1024
|
||||||
#define BF_CE_INITIAL_MEMORY BF_CE_STACK_SIZE + 128*1024
|
#define BF_CE_DEFAULT_HEAP_SIZE 128*1024
|
||||||
#define BF_CE_MAX_MEMORY 128*1024*1024
|
#define BF_CE_INITIAL_MEMORY BF_CE_DEFAULT_STACK_SIZE + BF_CE_DEFAULT_HEAP_SIZE
|
||||||
#define BF_CE_MAX_CARRYOVER_MEMORY BF_CE_STACK_SIZE * 2
|
#define BF_CE_MAX_MEMORY 0x7FFFFFFF
|
||||||
|
#define BF_CE_MAX_CARRYOVER_MEMORY BF_CE_DEFAULT_STACK_SIZE * 2
|
||||||
#define BF_CE_MAX_CARRYOVER_HEAP 1024*1024
|
#define BF_CE_MAX_CARRYOVER_HEAP 1024*1024
|
||||||
|
|
||||||
enum CeOperandInfoKind
|
enum CeOperandInfoKind
|
||||||
|
@ -683,6 +730,34 @@ public:
|
||||||
BfIRValue mAppendSizeValue;
|
BfIRValue mAppendSizeValue;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class CeRebuildKey
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
enum Kind
|
||||||
|
{
|
||||||
|
Kind_None,
|
||||||
|
Kind_File
|
||||||
|
};
|
||||||
|
|
||||||
|
public:
|
||||||
|
Kind mKind;
|
||||||
|
String mString;
|
||||||
|
|
||||||
|
bool operator==(const CeRebuildKey& other) const
|
||||||
|
{
|
||||||
|
return (mKind == other.mKind) && (mString == other.mString);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class CeRebuildValue
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
union
|
||||||
|
{
|
||||||
|
uint64 mInt;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
class CeEmitContext
|
class CeEmitContext
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -706,6 +781,25 @@ public:
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class BfCeTypeInfo
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Dictionary<int, BfCeTypeEmitEntry> mOnCompileMap;
|
||||||
|
Dictionary<int, BfCeTypeEmitEntry> mTypeIFaceMap;
|
||||||
|
Array<int> mPendingInterfaces;
|
||||||
|
Dictionary<CeRebuildKey, CeRebuildValue> mRebuildMap;
|
||||||
|
Val128 mHash;
|
||||||
|
bool mFailed;
|
||||||
|
BfCeTypeInfo* mNext;
|
||||||
|
|
||||||
|
public:
|
||||||
|
BfCeTypeInfo()
|
||||||
|
{
|
||||||
|
mFailed = false;
|
||||||
|
mNext = NULL;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
class CeContext
|
class CeContext
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -719,12 +813,14 @@ public:
|
||||||
ContiguousHeap* mHeap;
|
ContiguousHeap* mHeap;
|
||||||
Array<CeFrame> mCallStack;
|
Array<CeFrame> mCallStack;
|
||||||
Array<uint8> mMemory;
|
Array<uint8> mMemory;
|
||||||
|
int mStackSize;
|
||||||
Dictionary<int, addr_ce> mStringMap;
|
Dictionary<int, addr_ce> mStringMap;
|
||||||
Dictionary<int, addr_ce> mReflectMap;
|
Dictionary<int, addr_ce> mReflectMap;
|
||||||
Dictionary<Val128, addr_ce> mConstDataMap;
|
Dictionary<Val128, addr_ce> mConstDataMap;
|
||||||
HashSet<int> mStaticCtorExecSet;
|
HashSet<int> mStaticCtorExecSet;
|
||||||
Dictionary<String, CeStaticFieldInfo> mStaticFieldMap;
|
Dictionary<String, CeStaticFieldInfo> mStaticFieldMap;
|
||||||
Dictionary<void*, addr_ce> mMemToCtxMap;
|
Dictionary<int, CeInternalData*> mInternalDataMap;
|
||||||
|
int mCurHandleId;
|
||||||
|
|
||||||
BfMethodInstance* mCurMethodInstance;
|
BfMethodInstance* mCurMethodInstance;
|
||||||
BfType* mCurExpectingType;
|
BfType* mCurExpectingType;
|
||||||
|
@ -740,6 +836,7 @@ public:
|
||||||
BfError* Fail(const StringImpl& error);
|
BfError* Fail(const StringImpl& error);
|
||||||
BfError* Fail(const CeFrame& curFrame, const StringImpl& error);
|
BfError* Fail(const CeFrame& curFrame, const StringImpl& error);
|
||||||
|
|
||||||
|
void AddRebuild(const CeRebuildKey& key, const CeRebuildValue& value);
|
||||||
uint8* CeMalloc(int size);
|
uint8* CeMalloc(int size);
|
||||||
bool CeFree(addr_ce addr);
|
bool CeFree(addr_ce addr);
|
||||||
addr_ce CeAllocArray(BfArrayType* arrayType, int count, addr_ce& elemsAddr);
|
addr_ce CeAllocArray(BfArrayType* arrayType, int count, addr_ce& elemsAddr);
|
||||||
|
@ -838,3 +935,15 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
NS_BF_END
|
NS_BF_END
|
||||||
|
|
||||||
|
namespace std
|
||||||
|
{
|
||||||
|
template <>
|
||||||
|
struct hash<Beefy::CeRebuildKey>
|
||||||
|
{
|
||||||
|
size_t operator()(const Beefy::CeRebuildKey& key) const
|
||||||
|
{
|
||||||
|
return BeefHash<Beefy::String>()(key.mString) ^ (size_t)key.mKind;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
|
@ -81,7 +81,7 @@ struct SYSTEM_PROCESS_INFORMATION
|
||||||
SYSTEM_THREAD Threads[1];
|
SYSTEM_THREAD Threads[1];
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef NTSTATUS(NTAPI *NtQuerySystemInformation_t)(SYSTEM_INFORMATION_CLASS, PVOID, ULONG, PULONG);
|
typedef NTSTATUS(NTAPI* NtQuerySystemInformation_t)(SYSTEM_INFORMATION_CLASS, PVOID, ULONG, PULONG);
|
||||||
static NtQuerySystemInformation_t NtQuerySystemInformation = NULL;
|
static NtQuerySystemInformation_t NtQuerySystemInformation = NULL;
|
||||||
static HMODULE ntdll = NULL;
|
static HMODULE ntdll = NULL;
|
||||||
|
|
||||||
|
@ -101,6 +101,13 @@ DbgProfiler::DbgProfiler(WinDebugger* debugger) : mShutdownEvent(true)
|
||||||
mEndTick = 0;
|
mEndTick = 0;
|
||||||
|
|
||||||
mDebugger->AddProfiler(this);
|
mDebugger->AddProfiler(this);
|
||||||
|
|
||||||
|
mIdleSymbolNames.Add("ZwDelayExecution");
|
||||||
|
mIdleSymbolNames.Add("ZwWaitForWorkViaWorkerFactory");
|
||||||
|
mIdleSymbolNames.Add("NtWaitForAlertByThreadId");
|
||||||
|
mIdleSymbolNames.Add("NtWaitForSingleObject");
|
||||||
|
mIdleSymbolNames.Add("NtWaitForMultipleObjects");
|
||||||
|
mIdleSymbolNames.Add("ZwRemoveIoCompletion");
|
||||||
}
|
}
|
||||||
|
|
||||||
DbgProfiler::~DbgProfiler()
|
DbgProfiler::~DbgProfiler()
|
||||||
|
@ -148,7 +155,7 @@ void DbgProfiler::DoClear()
|
||||||
delete val.mProcId;
|
delete val.mProcId;
|
||||||
}
|
}
|
||||||
|
|
||||||
ProfileProcId* DbgProfiler::Get(const StringImpl& str)
|
ProfileProcId* DbgProfiler::Get(const StringImpl& str, bool* outIsNew)
|
||||||
{
|
{
|
||||||
ProfileProdIdEntry checkEntry;
|
ProfileProdIdEntry checkEntry;
|
||||||
checkEntry.mProcId = (ProfileProcId*)&str;
|
checkEntry.mProcId = (ProfileProcId*)&str;
|
||||||
|
@ -158,11 +165,16 @@ ProfileProcId* DbgProfiler::Get(const StringImpl& str)
|
||||||
{
|
{
|
||||||
auto procId = new ProfileProcId();
|
auto procId = new ProfileProcId();
|
||||||
procId->mProcName = str;
|
procId->mProcName = str;
|
||||||
|
procId->mIsIdle = false;
|
||||||
entryPtr->mProcId = procId;
|
entryPtr->mProcId = procId;
|
||||||
|
if (outIsNew != NULL)
|
||||||
|
*outIsNew = true;
|
||||||
return procId;
|
return procId;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
if (outIsNew != NULL)
|
||||||
|
*outIsNew = false;
|
||||||
return entryPtr->mProcId;
|
return entryPtr->mProcId;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -184,7 +196,7 @@ void DbgProfiler::ThreadProc()
|
||||||
uint32 accumMS = 0;
|
uint32 accumMS = 0;
|
||||||
|
|
||||||
int totalWait = 0;
|
int totalWait = 0;
|
||||||
int totalWait2 = 0;
|
int totalWait2 = 0;
|
||||||
int iterations = 0;
|
int iterations = 0;
|
||||||
HashSet<int> idleThreadSet;
|
HashSet<int> idleThreadSet;
|
||||||
|
|
||||||
|
@ -222,6 +234,8 @@ void DbgProfiler::ThreadProc()
|
||||||
SYSTEM_PROCESS_INFORMATION* processData = NULL;
|
SYSTEM_PROCESS_INFORMATION* processData = NULL;
|
||||||
std::unique_ptr<SYSTEM_PROCESS_INFORMATION> ptrDelete(processData);
|
std::unique_ptr<SYSTEM_PROCESS_INFORMATION> ptrDelete(processData);
|
||||||
|
|
||||||
|
//processData = CaptureProcessInfo();
|
||||||
|
|
||||||
auto curProcessData = processData;
|
auto curProcessData = processData;
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
|
@ -235,6 +249,7 @@ void DbgProfiler::ThreadProc()
|
||||||
auto& threadInfo = curProcessData->Threads[threadIdx];
|
auto& threadInfo = curProcessData->Threads[threadIdx];
|
||||||
if ((threadInfo.State == StateWait) || (threadInfo.State == StateTerminated))
|
if ((threadInfo.State == StateWait) || (threadInfo.State == StateTerminated))
|
||||||
idleThreadSet.Add((int)(intptr)threadInfo.ClientId.UniqueThread);
|
idleThreadSet.Add((int)(intptr)threadInfo.ClientId.UniqueThread);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -321,10 +336,12 @@ void DbgProfiler::ThreadProc()
|
||||||
profileThreadInfo = *profileThreadInfoPtr;
|
profileThreadInfo = *profileThreadInfoPtr;
|
||||||
}
|
}
|
||||||
|
|
||||||
profileThreadInfo->mTotalSamples += curSampleCount;
|
|
||||||
|
|
||||||
bool isThreadIdle = idleThreadSet.Contains(thread->mThreadId);
|
bool isThreadIdle = idleThreadSet.Contains(thread->mThreadId);
|
||||||
|
|
||||||
|
profileThreadInfo->mTotalSamples += curSampleCount;
|
||||||
|
if (isThreadIdle)
|
||||||
|
profileThreadInfo->mTotalIdleSamples += curSampleCount;
|
||||||
|
|
||||||
mDebugger->mActiveThread = thread;
|
mDebugger->mActiveThread = thread;
|
||||||
|
|
||||||
::SuspendThread(thread->mHThread);
|
::SuspendThread(thread->mHThread);
|
||||||
|
@ -333,7 +350,7 @@ void DbgProfiler::ThreadProc()
|
||||||
mDebugger->PopulateRegisters(®isters);
|
mDebugger->PopulateRegisters(®isters);
|
||||||
|
|
||||||
int stackSize = 0;
|
int stackSize = 0;
|
||||||
for (int stackIdx = 0 ; stackIdx < maxStackTrace; stackIdx++)
|
for (int stackIdx = 0; stackIdx < maxStackTrace; stackIdx++)
|
||||||
{
|
{
|
||||||
auto pc = registers.GetPC();
|
auto pc = registers.GetPC();
|
||||||
if (pc <= 0xFFFF)
|
if (pc <= 0xFFFF)
|
||||||
|
@ -439,7 +456,10 @@ String DbgProfiler::GetThreadList()
|
||||||
for (auto threadId : mThreadIdList)
|
for (auto threadId : mThreadIdList)
|
||||||
{
|
{
|
||||||
auto threadInfo = mThreadInfo[threadId];
|
auto threadInfo = mThreadInfo[threadId];
|
||||||
result += StrFormat("%d\t%s\n", threadId, threadInfo->mName.c_str());
|
int cpuUsage = 0;
|
||||||
|
if (threadInfo->mTotalSamples > 0)
|
||||||
|
cpuUsage = 100 - (threadInfo->mTotalIdleSamples * 100 / threadInfo->mTotalSamples);
|
||||||
|
result += StrFormat("%d\t%d\t%s\n", threadId, cpuUsage, threadInfo->mName.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
@ -608,7 +628,10 @@ void DbgProfiler::HandlePendingEntries()
|
||||||
symbolName += StrFormat("0x%@", addr);
|
symbolName += StrFormat("0x%@", addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
procId = Get(symbolName);
|
bool isNew = false;
|
||||||
|
procId = Get(symbolName, &isNew);
|
||||||
|
if (isNew)
|
||||||
|
procId->mIsIdle = mIdleSymbolNames.Contains(symbolName);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (reverse)
|
if (reverse)
|
||||||
|
@ -654,6 +677,25 @@ void DbgProfiler::Process()
|
||||||
for (auto& val : mProfileProcEntrySet)
|
for (auto& val : mProfileProcEntrySet)
|
||||||
mProfileProcEntries[val.mEntryIdx] = &val;
|
mProfileProcEntries[val.mEntryIdx] = &val;
|
||||||
|
|
||||||
|
for (auto threadKV : mThreadInfo)
|
||||||
|
{
|
||||||
|
auto threadInfo = threadKV.mValue;
|
||||||
|
|
||||||
|
for (auto addrEntryIdx : threadInfo->mProfileAddrEntries)
|
||||||
|
{
|
||||||
|
if (addrEntryIdx < 0)
|
||||||
|
{
|
||||||
|
addrEntryIdx = -addrEntryIdx;
|
||||||
|
}
|
||||||
|
|
||||||
|
int procEntryIdx = mProfileAddrToProcMap[addrEntryIdx];
|
||||||
|
auto procEntry = mProfileProcEntries[procEntryIdx];
|
||||||
|
|
||||||
|
auto curProc = procEntry->mData[0];
|
||||||
|
if (curProc->mIsIdle)
|
||||||
|
threadInfo->mTotalIdleSamples++;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
String DbgProfiler::GetCallTree(int threadId, bool reverse)
|
String DbgProfiler::GetCallTree(int threadId, bool reverse)
|
||||||
|
|
|
@ -67,6 +67,7 @@ class ProfileProcId
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
String mProcName;
|
String mProcName;
|
||||||
|
bool mIsIdle;
|
||||||
};
|
};
|
||||||
|
|
||||||
class ProfileProdIdEntry
|
class ProfileProdIdEntry
|
||||||
|
@ -104,12 +105,14 @@ class ProfileThreadInfo
|
||||||
public:
|
public:
|
||||||
Array<int> mProfileAddrEntries;
|
Array<int> mProfileAddrEntries;
|
||||||
int mTotalSamples;
|
int mTotalSamples;
|
||||||
|
int mTotalIdleSamples;
|
||||||
String mName;
|
String mName;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ProfileThreadInfo()
|
ProfileThreadInfo()
|
||||||
{
|
{
|
||||||
mTotalSamples = 0;
|
mTotalSamples = 0;
|
||||||
|
mTotalIdleSamples = 0;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -143,6 +146,7 @@ public:
|
||||||
|
|
||||||
Dictionary<void*, ProfileProcId*> mProcMap; // Keyed on either DwSubprogram or DwSymbol. Multiple pointers can reference the same ProfileProcId (in the case of inlined functions, for example)
|
Dictionary<void*, ProfileProcId*> mProcMap; // Keyed on either DwSubprogram or DwSymbol. Multiple pointers can reference the same ProfileProcId (in the case of inlined functions, for example)
|
||||||
HashSet<ProfileProdIdEntry> mUniqueProcSet;
|
HashSet<ProfileProdIdEntry> mUniqueProcSet;
|
||||||
|
HashSet<String> mIdleSymbolNames;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void ThreadProc();
|
void ThreadProc();
|
||||||
|
@ -171,7 +175,7 @@ public:
|
||||||
void HandlePendingEntries();
|
void HandlePendingEntries();
|
||||||
void Process();
|
void Process();
|
||||||
void DoClear();
|
void DoClear();
|
||||||
ProfileProcId* Get(const StringImpl& str);
|
ProfileProcId* Get(const StringImpl& str, bool* outIsNew = NULL);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
DbgProfiler(WinDebugger* debugger);
|
DbgProfiler(WinDebugger* debugger);
|
||||||
|
|
2
IDEHelper/Tests/Test0.txt
Normal file
2
IDEHelper/Tests/Test0.txt
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
Test
|
||||||
|
0
|
|
@ -229,6 +229,43 @@ namespace Tests
|
||||||
GC.Mark!((*ptr));
|
GC.Mark!((*ptr));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[CheckEnum]
|
||||||
|
enum EnumA
|
||||||
|
{
|
||||||
|
case A(int64 aa);
|
||||||
|
case B(float bb);
|
||||||
|
}
|
||||||
|
|
||||||
|
[AttributeUsage(.All)]
|
||||||
|
public struct CheckEnumAttribute : Attribute, IComptimeTypeApply
|
||||||
|
{
|
||||||
|
public void ApplyToType(Type type)
|
||||||
|
{
|
||||||
|
int fieldIdx = 0;
|
||||||
|
for (var field in type.GetFields())
|
||||||
|
{
|
||||||
|
switch (fieldIdx)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
Test.Assert(field.Name == "$payload");
|
||||||
|
Test.Assert(field.MemberOffset == 0);
|
||||||
|
Test.Assert(field.FieldType == typeof(int64));
|
||||||
|
case 1:
|
||||||
|
Test.Assert(field.Name == "$discriminator");
|
||||||
|
Test.Assert(field.MemberOffset == 8);
|
||||||
|
Test.Assert(field.FieldType == typeof(int8));
|
||||||
|
}
|
||||||
|
fieldIdx++;
|
||||||
|
}
|
||||||
|
Test.Assert(fieldIdx == 4);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const String cTest0 = Compiler.ReadText("Test0.txt");
|
||||||
|
const String cTest1 = new String('A', 12);
|
||||||
|
const uint8[?] cTest0Binary = Compiler.ReadBinary("Test0.txt");
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public static void TestBasics()
|
public static void TestBasics()
|
||||||
{
|
{
|
||||||
|
@ -269,6 +306,11 @@ namespace Tests
|
||||||
SerializationContext serCtx = scope .();
|
SerializationContext serCtx = scope .();
|
||||||
iSer.Serialize(serCtx);
|
iSer.Serialize(serCtx);
|
||||||
Test.Assert(serCtx.mStr == "x 10\ny 2\n");
|
Test.Assert(serCtx.mStr == "x 10\ny 2\n");
|
||||||
|
|
||||||
|
Test.Assert(cTest0 == "Test\n0");
|
||||||
|
Test.Assert(cTest1 == "AAAAAAAAAAAA");
|
||||||
|
Test.Assert((Object)cTest1 == (Object)"AAAAAAAAAAAA");
|
||||||
|
Test.Assert((cTest0Binary[0] == (.)'T') && ((cTest0Binary.Count == 6) || (cTest0Binary.Count == 7)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,6 +57,65 @@ namespace Tests
|
||||||
return dlg(val[0]);
|
return dlg(val[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void TestWrap<T>(T del, bool b = false) where T : delegate void()
|
||||||
|
{
|
||||||
|
Action ac = scope () => {
|
||||||
|
del();
|
||||||
|
};
|
||||||
|
ac();
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Vector2 : this(float x, float y)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
class Invoker
|
||||||
|
{
|
||||||
|
public int mA = 111;
|
||||||
|
|
||||||
|
public void Invoke()
|
||||||
|
{
|
||||||
|
mA += 222;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class TestA
|
||||||
|
{
|
||||||
|
Vector2 mVec = .(11, 22);
|
||||||
|
Event<Action> mEvt ~ _.Dispose();
|
||||||
|
Action mAct;
|
||||||
|
|
||||||
|
public Vector2 Vec
|
||||||
|
{
|
||||||
|
set
|
||||||
|
{
|
||||||
|
DoIt(() =>
|
||||||
|
{
|
||||||
|
Test.Assert(mVec.x == 11);
|
||||||
|
Test.Assert(mVec.y == 22);
|
||||||
|
Test.Assert(value.x == 33);
|
||||||
|
Test.Assert(value.y == 44);
|
||||||
|
});
|
||||||
|
Invoker invoker = scope .();
|
||||||
|
mEvt.Add(new => invoker);
|
||||||
|
DoIt(=> mEvt);
|
||||||
|
Test.Assert(invoker.mA == 333);
|
||||||
|
DoIt(=> invoker);
|
||||||
|
Test.Assert(invoker.mA == 555);
|
||||||
|
mAct = scope => invoker;
|
||||||
|
mAct();
|
||||||
|
Test.Assert(invoker.mA == 777);
|
||||||
|
DoIt(=> mAct);
|
||||||
|
Test.Assert(invoker.mA == 999);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void DoIt<TDlg>(TDlg dlg) where TDlg : delegate void()
|
||||||
|
{
|
||||||
|
dlg();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public static void TestBasics()
|
public static void TestBasics()
|
||||||
{
|
{
|
||||||
|
@ -78,6 +137,13 @@ namespace Tests
|
||||||
List<float> fList = scope .() { 1.2f, 2.3f };
|
List<float> fList = scope .() { 1.2f, 2.3f };
|
||||||
Test.Assert(DoOnListA(fList, (val) => val + 100) == 101.2f);
|
Test.Assert(DoOnListA(fList, (val) => val + 100) == 101.2f);
|
||||||
Test.Assert(DoOnListB((val) => val + 200, fList) == 201.2f);
|
Test.Assert(DoOnListB((val) => val + 200, fList) == 201.2f);
|
||||||
|
|
||||||
|
int a = 222;
|
||||||
|
TestWrap(() => { a += 100; });
|
||||||
|
Test.Assert(a == 322);
|
||||||
|
|
||||||
|
TestA ta = scope .();
|
||||||
|
ta.Vec = .(33, 44);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct MethodRefHolder<T> where T : delegate int(int num)
|
struct MethodRefHolder<T> where T : delegate int(int num)
|
||||||
|
|
|
@ -23,6 +23,16 @@ namespace Tests
|
||||||
{
|
{
|
||||||
class Generics
|
class Generics
|
||||||
{
|
{
|
||||||
|
struct StructA : IDisposable
|
||||||
|
{
|
||||||
|
int mA = 123;
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class ClassA : IDisposable, LibA.IVal
|
class ClassA : IDisposable, LibA.IVal
|
||||||
{
|
{
|
||||||
int LibA.IVal.Val
|
int LibA.IVal.Val
|
||||||
|
@ -172,7 +182,7 @@ namespace Tests
|
||||||
delete val;
|
delete val;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void Alloc2<T>() where T : new, delete, IDisposable, struct
|
public static void Alloc2<T>() where T : new, IDisposable, struct
|
||||||
{
|
{
|
||||||
alloctype(T) val = new T();
|
alloctype(T) val = new T();
|
||||||
T* val2 = val;
|
T* val2 = val;
|
||||||
|
@ -180,6 +190,14 @@ namespace Tests
|
||||||
delete val;
|
delete val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void Alloc3<T>() where T : new, IDisposable, struct*
|
||||||
|
{
|
||||||
|
T val2 = default;
|
||||||
|
if (val2 != null)
|
||||||
|
val2.Dispose();
|
||||||
|
delete val2;
|
||||||
|
}
|
||||||
|
|
||||||
public class ClassE
|
public class ClassE
|
||||||
{
|
{
|
||||||
public static Self Instance = new ClassE() ~ delete _;
|
public static Self Instance = new ClassE() ~ delete _;
|
||||||
|
@ -311,6 +329,9 @@ namespace Tests
|
||||||
[Test]
|
[Test]
|
||||||
public static void TestBasics()
|
public static void TestBasics()
|
||||||
{
|
{
|
||||||
|
Alloc2<StructA>();
|
||||||
|
Alloc3<StructA*>();
|
||||||
|
|
||||||
MethodD(scope => MethodC);
|
MethodD(scope => MethodC);
|
||||||
|
|
||||||
List<Entry> list = scope .();
|
List<Entry> list = scope .();
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue