mirror of
https://github.com/beefytech/Beef.git
synced 2025-06-08 11:38:21 +02:00
Comptime updates, start of metaprogramming support
This commit is contained in:
parent
be1c099f19
commit
3bbf2d8313
43 changed files with 1562 additions and 885 deletions
|
@ -274,10 +274,36 @@ namespace System
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[AttributeUsage(.Method | .Invocation)]
|
[AttributeUsage(.Method)]
|
||||||
|
public struct ComptimeAttribute : Attribute
|
||||||
|
{
|
||||||
|
public this()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool OnlyFromComptime
|
||||||
|
{
|
||||||
|
set
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool ConstEval
|
||||||
|
{
|
||||||
|
set
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[AttributeUsage(.Invocation)]
|
||||||
public struct ConstEvalAttribute : Attribute
|
public struct ConstEvalAttribute : Attribute
|
||||||
{
|
{
|
||||||
|
public this()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[AttributeUsage(.Method /*2*/)]
|
[AttributeUsage(.Method /*2*/)]
|
||||||
|
|
|
@ -1,7 +1,38 @@
|
||||||
|
using System.Reflection;
|
||||||
namespace System
|
namespace System
|
||||||
{
|
{
|
||||||
|
[AttributeUsage(.Method)]
|
||||||
|
struct OnCompileAttribute : Attribute
|
||||||
|
{
|
||||||
|
public enum Kind
|
||||||
|
{
|
||||||
|
None,
|
||||||
|
TypeInit,
|
||||||
|
TypeDone
|
||||||
|
}
|
||||||
|
|
||||||
|
public this(Kind kind)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static class Compiler
|
static class Compiler
|
||||||
{
|
{
|
||||||
|
public struct MethodBuilder
|
||||||
|
{
|
||||||
|
void* mNative;
|
||||||
|
|
||||||
|
public void Emit(String str)
|
||||||
|
{
|
||||||
|
Comptime_MethodBuilder_EmitStr(mNative, str);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Emit(Type type)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
[LinkName("#CallerLineNum")]
|
[LinkName("#CallerLineNum")]
|
||||||
public static extern int CallerLineNum;
|
public static extern int CallerLineNum;
|
||||||
|
|
||||||
|
@ -32,8 +63,8 @@ namespace System
|
||||||
[LinkName("#TimeLocal")]
|
[LinkName("#TimeLocal")]
|
||||||
public static extern String TimeLocal;
|
public static extern String TimeLocal;
|
||||||
|
|
||||||
[LinkName("#IsConstEval")]
|
[LinkName("#IsComptime")]
|
||||||
public static extern bool IsConstEval;
|
public static extern bool IsComptime;
|
||||||
|
|
||||||
[LinkName("#IsBuilding")]
|
[LinkName("#IsBuilding")]
|
||||||
public static extern bool IsBuilding;
|
public static extern bool IsBuilding;
|
||||||
|
@ -44,11 +75,39 @@ namespace System
|
||||||
[LinkName("#CompileRev")]
|
[LinkName("#CompileRev")]
|
||||||
public static extern int32 CompileRev;
|
public static extern int32 CompileRev;
|
||||||
|
|
||||||
[ConstEval]
|
[Comptime]
|
||||||
public static void Assert(bool cond)
|
public static void Assert(bool cond)
|
||||||
{
|
{
|
||||||
if (!cond)
|
if (!cond)
|
||||||
Runtime.FatalError("Assert failed");
|
Runtime.FatalError("Assert failed");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static extern void* Comptime_MethodBuilder_EmitStr(void* native, StringView str);
|
||||||
|
static extern void* Comptime_CreateMethod(int32 typeId, StringView methodName, Type returnType, MethodFlags methodFlags);
|
||||||
|
static extern void Comptime_EmitDefinition(int32 typeId, StringView text);
|
||||||
|
|
||||||
|
[Comptime(OnlyFromComptime=true)]
|
||||||
|
public static MethodBuilder CreateMethod(Type owner, StringView methodName, Type returnType, MethodFlags methodFlags)
|
||||||
|
{
|
||||||
|
MethodBuilder builder = .();
|
||||||
|
builder.[Friend]mNative = Comptime_CreateMethod((.)owner.TypeId, methodName, returnType, methodFlags);
|
||||||
|
return builder;
|
||||||
|
}
|
||||||
|
|
||||||
|
[Comptime(OnlyFromComptime=true)]
|
||||||
|
public static void EmitDefinition(Type owner, StringView text)
|
||||||
|
{
|
||||||
|
Comptime_EmitDefinition((.)owner.TypeId, text);
|
||||||
|
}
|
||||||
|
|
||||||
|
interface IComptimeTypeApply
|
||||||
|
{
|
||||||
|
void ApplyToType(Type type);
|
||||||
|
}
|
||||||
|
|
||||||
|
interface IComptimeMethodApply
|
||||||
|
{
|
||||||
|
void ApplyToMethod(Type type);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -83,7 +83,7 @@ namespace System.Globalization
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
if (Compiler.IsConstEval)
|
if (Compiler.IsComptime)
|
||||||
return InitUserDefaultCulture();
|
return InitUserDefaultCulture();
|
||||||
if (tlCurrentCulture == null)
|
if (tlCurrentCulture == null)
|
||||||
tlCurrentCulture = CultureInfo.DefaultThreadCurrentCulture ?? CultureInfo.UserDefaultCulture;
|
tlCurrentCulture = CultureInfo.DefaultThreadCurrentCulture ?? CultureInfo.UserDefaultCulture;
|
||||||
|
|
|
@ -131,7 +131,7 @@ namespace System
|
||||||
public static T* AllocRawArrayUnmarked<T>(int size)
|
public static T* AllocRawArrayUnmarked<T>(int size)
|
||||||
{
|
{
|
||||||
#if BF_ENABLE_REALTIME_LEAK_CHECK
|
#if BF_ENABLE_REALTIME_LEAK_CHECK
|
||||||
if (Compiler.IsConstEval)
|
if (Compiler.IsComptime)
|
||||||
return new T[size]*(?);
|
return new T[size]*(?);
|
||||||
// We don't want to use the default mark function because the GC will mark the entire array,
|
// We don't want to use the default mark function because the GC will mark the entire array,
|
||||||
// whereas we have a custom marking routine because we only want to mark up to mSize
|
// whereas we have a custom marking routine because we only want to mark up to mSize
|
||||||
|
|
|
@ -1235,7 +1235,7 @@ namespace System
|
||||||
// _isCustomFormat, _specifierIsUpper, _specifier & _precision.
|
// _isCustomFormat, _specifierIsUpper, _specifier & _precision.
|
||||||
this(CultureInfo cultureInfo)
|
this(CultureInfo cultureInfo)
|
||||||
{
|
{
|
||||||
if (Compiler.IsConstEval)
|
if (Compiler.IsComptime)
|
||||||
_cbuf = new char8[0];
|
_cbuf = new char8[0];
|
||||||
else
|
else
|
||||||
_cbuf = sEmtpyBuf;
|
_cbuf = sEmtpyBuf;
|
||||||
|
|
|
@ -40,12 +40,12 @@ namespace System
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
extern Type ConstEval_GetType();
|
extern Type Comptime_GetType();
|
||||||
|
|
||||||
public Type GetType()
|
public Type GetType()
|
||||||
{
|
{
|
||||||
if (Compiler.IsConstEval)
|
if (Compiler.IsComptime)
|
||||||
return ConstEval_GetType();
|
return Comptime_GetType();
|
||||||
|
|
||||||
Type type;
|
Type type;
|
||||||
#if BF_ENABLE_OBJECT_DEBUG_FLAGS
|
#if BF_ENABLE_OBJECT_DEBUG_FLAGS
|
||||||
|
@ -65,8 +65,8 @@ namespace System
|
||||||
[NoShow]
|
[NoShow]
|
||||||
Type RawGetType()
|
Type RawGetType()
|
||||||
{
|
{
|
||||||
if (Compiler.IsConstEval)
|
if (Compiler.IsComptime)
|
||||||
return ConstEval_GetType();
|
return Comptime_GetType();
|
||||||
|
|
||||||
Type type;
|
Type type;
|
||||||
#if BF_ENABLE_OBJECT_DEBUG_FLAGS
|
#if BF_ENABLE_OBJECT_DEBUG_FLAGS
|
||||||
|
|
|
@ -35,6 +35,11 @@ namespace System
|
||||||
return .Ok(matched);
|
return .Ok(matched);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public virtual Result<MethodInfo, MethodError> GetMethod(int methodIdx)
|
||||||
|
{
|
||||||
|
return .Err(.NoResults);
|
||||||
|
}
|
||||||
|
|
||||||
public virtual Result<Object> CreateObject()
|
public virtual Result<Object> CreateObject()
|
||||||
{
|
{
|
||||||
return .Err;
|
return .Err;
|
||||||
|
@ -61,6 +66,13 @@ namespace System.Reflection
|
||||||
return MethodInfo.Enumerator(this, bindingFlags);
|
return MethodInfo.Enumerator(this, bindingFlags);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override Result<MethodInfo, MethodError> GetMethod(int methodIdx)
|
||||||
|
{
|
||||||
|
if ((methodIdx < 0) || (methodIdx >= mMethodDataCount))
|
||||||
|
return .Err(.NoResults);
|
||||||
|
return MethodInfo(this, &mMethodDataPtr[methodIdx]);
|
||||||
|
}
|
||||||
|
|
||||||
public override Result<Object> CreateObject()
|
public override Result<Object> CreateObject()
|
||||||
{
|
{
|
||||||
if (mTypeClassVData == null)
|
if (mTypeClassVData == null)
|
||||||
|
|
|
@ -471,19 +471,19 @@ namespace System
|
||||||
return (int32)mTypeId;
|
return (int32)mTypeId;
|
||||||
}
|
}
|
||||||
|
|
||||||
static extern Type ConstEval_GetTypeById(int32 typeId);
|
static extern Type Comptime_GetTypeById(int32 typeId);
|
||||||
|
|
||||||
protected static Type GetType(TypeId typeId)
|
protected static Type GetType(TypeId typeId)
|
||||||
{
|
{
|
||||||
if (Compiler.IsConstEval)
|
if (Compiler.IsComptime)
|
||||||
return ConstEval_GetTypeById((.)typeId);
|
return Comptime_GetTypeById((.)typeId);
|
||||||
return sTypes[(int32)typeId];
|
return sTypes[(int32)typeId];
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static Type GetType_(int32 typeId)
|
protected static Type GetType_(int32 typeId)
|
||||||
{
|
{
|
||||||
if (Compiler.IsConstEval)
|
if (Compiler.IsComptime)
|
||||||
return ConstEval_GetTypeById(typeId);
|
return Comptime_GetTypeById(typeId);
|
||||||
return sTypes[typeId];
|
return sTypes[typeId];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -547,6 +547,11 @@ namespace System
|
||||||
return .Err;
|
return .Err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public virtual Result<FieldInfo> GetField(int idx)
|
||||||
|
{
|
||||||
|
return .Err;
|
||||||
|
}
|
||||||
|
|
||||||
public virtual FieldInfo.Enumerator GetFields(BindingFlags bindingFlags = cDefaultLookup)
|
public virtual FieldInfo.Enumerator GetFields(BindingFlags bindingFlags = cDefaultLookup)
|
||||||
{
|
{
|
||||||
return FieldInfo.Enumerator(null, bindingFlags);
|
return FieldInfo.Enumerator(null, bindingFlags);
|
||||||
|
@ -912,6 +917,13 @@ namespace System.Reflection
|
||||||
return .Err;
|
return .Err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override Result<FieldInfo> GetField(int fieldIdx)
|
||||||
|
{
|
||||||
|
if ((fieldIdx < 0) || (fieldIdx >= mFieldDataCount))
|
||||||
|
return .Err;
|
||||||
|
return FieldInfo(this, &mFieldDataPtr[fieldIdx]);
|
||||||
|
}
|
||||||
|
|
||||||
public override FieldInfo.Enumerator GetFields(BindingFlags bindingFlags = cDefaultLookup)
|
public override FieldInfo.Enumerator GetFields(BindingFlags bindingFlags = cDefaultLookup)
|
||||||
{
|
{
|
||||||
return FieldInfo.Enumerator(this, bindingFlags);
|
return FieldInfo.Enumerator(this, bindingFlags);
|
||||||
|
|
|
@ -132,6 +132,11 @@ namespace IDE
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public virtual void RequestFastFinish()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
public void CancelBackground()
|
public void CancelBackground()
|
||||||
{
|
{
|
||||||
RequestCancelBackground();
|
RequestCancelBackground();
|
||||||
|
|
|
@ -61,6 +61,9 @@ namespace IDE.Compiler
|
||||||
[CallingConvention(.Stdcall), CLink]
|
[CallingConvention(.Stdcall), CLink]
|
||||||
static extern void BfCompiler_Cancel(void* bfCompiler);
|
static extern void BfCompiler_Cancel(void* bfCompiler);
|
||||||
|
|
||||||
|
[CallingConvention(.Stdcall), CLink]
|
||||||
|
static extern void BfCompiler_RequestFastFinish(void* bfCompiler);
|
||||||
|
|
||||||
[CallingConvention(.Stdcall), CLink]
|
[CallingConvention(.Stdcall), CLink]
|
||||||
static extern void BfCompiler_ClearCompletionPercentage(void* bfCompiler);
|
static extern void BfCompiler_ClearCompletionPercentage(void* bfCompiler);
|
||||||
|
|
||||||
|
@ -111,6 +114,12 @@ namespace IDE.Compiler
|
||||||
[CallingConvention(.Stdcall), CLink]
|
[CallingConvention(.Stdcall), CLink]
|
||||||
static extern void BfCompiler_ForceRebuild(void* bfCompiler);
|
static extern void BfCompiler_ForceRebuild(void* bfCompiler);
|
||||||
|
|
||||||
|
[CallingConvention(.Stdcall), CLink]
|
||||||
|
static extern char8* BfCompiler_GetEmitSource(void* bfCompiler, char8* fileName);
|
||||||
|
|
||||||
|
[CallingConvention(.Stdcall), CLink]
|
||||||
|
static extern int32 BfCompiler_GetEmitSourceVersion(void* bfCompiler, char8* fileName);
|
||||||
|
|
||||||
public enum HotTypeFlags
|
public enum HotTypeFlags
|
||||||
{
|
{
|
||||||
None = 0,
|
None = 0,
|
||||||
|
@ -267,6 +276,20 @@ namespace IDE.Compiler
|
||||||
BfCompiler_ForceRebuild(mNativeBfCompiler);
|
BfCompiler_ForceRebuild(mNativeBfCompiler);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool GetEmitSource(StringView fileName, String outText)
|
||||||
|
{
|
||||||
|
char8* str = BfCompiler_GetEmitSource(mNativeBfCompiler, fileName.ToScopeCStr!());
|
||||||
|
if (str == null)
|
||||||
|
return false;
|
||||||
|
outText.Append(str);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int32 GetEmitVersion(StringView fileName)
|
||||||
|
{
|
||||||
|
return BfCompiler_GetEmitSourceVersion(mNativeBfCompiler, fileName.ToScopeCStr!());
|
||||||
|
}
|
||||||
|
|
||||||
public void QueueSetPassInstance(BfPassInstance passInstance)
|
public void QueueSetPassInstance(BfPassInstance passInstance)
|
||||||
{
|
{
|
||||||
SetPassInstanceCommand command = new SetPassInstanceCommand();
|
SetPassInstanceCommand command = new SetPassInstanceCommand();
|
||||||
|
@ -658,6 +681,15 @@ namespace IDE.Compiler
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override void RequestFastFinish()
|
||||||
|
{
|
||||||
|
if ([Friend]mThreadWorker.mThreadRunning || [Friend]mThreadWorkerHi.mThreadRunning)
|
||||||
|
{
|
||||||
|
if (mNativeBfCompiler != null)
|
||||||
|
BfCompiler_RequestFastFinish(mNativeBfCompiler);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void ClearCompletionPercentage()
|
public void ClearCompletionPercentage()
|
||||||
{
|
{
|
||||||
BfCompiler_ClearCompletionPercentage(mNativeBfCompiler);
|
BfCompiler_ClearCompletionPercentage(mNativeBfCompiler);
|
||||||
|
|
|
@ -1407,6 +1407,23 @@ namespace IDE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BfCompiler compiler = null;
|
||||||
|
|
||||||
|
if (fileName.Contains("$EmitR$"))
|
||||||
|
compiler = mBfResolveCompiler;
|
||||||
|
else if (fileName.Contains("$Emit$"))
|
||||||
|
compiler = mBfBuildCompiler;
|
||||||
|
|
||||||
|
if (compiler != null)
|
||||||
|
{
|
||||||
|
if (compiler.GetEmitSource(fileName, outBuffer))
|
||||||
|
{
|
||||||
|
if (onPreFilter != null)
|
||||||
|
onPreFilter();
|
||||||
|
return .Ok;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return Utils.LoadTextFile(fileName, outBuffer, autoRetry, onPreFilter);
|
return Utils.LoadTextFile(fileName, outBuffer, autoRetry, onPreFilter);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6145,6 +6162,16 @@ namespace IDE
|
||||||
useFilePath = scope:: String(useFilePath);
|
useFilePath = scope:: String(useFilePath);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int32 emitRevision = -1;
|
||||||
|
//
|
||||||
|
{
|
||||||
|
int barPos = useFilePath.IndexOf('|');
|
||||||
|
if (barPos != -1)
|
||||||
|
{
|
||||||
|
emitRevision = int32.Parse(useFilePath.Substring(barPos + 1)).Value;
|
||||||
|
useFilePath.RemoveToEnd(barPos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if ((useFilePath != null) && (!IDEUtils.FixFilePath(useFilePath)))
|
if ((useFilePath != null) && (!IDEUtils.FixFilePath(useFilePath)))
|
||||||
return null;
|
return null;
|
||||||
|
@ -6219,6 +6246,8 @@ namespace IDE
|
||||||
sourceViewPanelTab.mTabbedView.FinishTabAnim();
|
sourceViewPanelTab.mTabbedView.FinishTabAnim();
|
||||||
if (setFocus)
|
if (setFocus)
|
||||||
sourceViewPanel.FocusEdit();
|
sourceViewPanel.FocusEdit();
|
||||||
|
|
||||||
|
sourceViewPanel.CheckEmitRevision();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6236,6 +6265,7 @@ namespace IDE
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
success = sourceViewPanel.Show(useFilePath, !mInitialized);
|
success = sourceViewPanel.Show(useFilePath, !mInitialized);
|
||||||
|
sourceViewPanel.mEmitRevision = emitRevision;
|
||||||
|
|
||||||
if (!success)
|
if (!success)
|
||||||
{
|
{
|
||||||
|
|
|
@ -153,6 +153,17 @@ namespace IDE.ui
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class HoverResolveTask
|
||||||
|
{
|
||||||
|
public int32 mCursorPos;
|
||||||
|
public String mResult ~ delete _;
|
||||||
|
|
||||||
|
public ~this()
|
||||||
|
{
|
||||||
|
NOP!();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public class SourceFindTask
|
public class SourceFindTask
|
||||||
{
|
{
|
||||||
public WaitEvent mDoneEvent = new WaitEvent() ~ delete _;
|
public WaitEvent mDoneEvent = new WaitEvent() ~ delete _;
|
||||||
|
@ -306,6 +317,7 @@ namespace IDE.ui
|
||||||
public List<ResolveParams> mDeferredResolveResults = new .() ~ DeleteContainerAndItems!(_);
|
public List<ResolveParams> mDeferredResolveResults = new .() ~ DeleteContainerAndItems!(_);
|
||||||
public bool mTrackedTextElementViewListDirty;
|
public bool mTrackedTextElementViewListDirty;
|
||||||
public String mFilePath ~ delete _;
|
public String mFilePath ~ delete _;
|
||||||
|
public int32 mEmitRevision = -1;
|
||||||
public bool mIsBinary;
|
public bool mIsBinary;
|
||||||
public String mAliasFilePath ~ delete _;
|
public String mAliasFilePath ~ delete _;
|
||||||
#if IDE_C_SUPPORT
|
#if IDE_C_SUPPORT
|
||||||
|
@ -321,6 +333,7 @@ namespace IDE.ui
|
||||||
HTTPRequest mOldVerHTTPRequest ~ delete _;
|
HTTPRequest mOldVerHTTPRequest ~ delete _;
|
||||||
IDEApp.ExecutionInstance mOldVerLoadExecutionInstance ~ { if (_ != null) _.mAutoDelete = true; };
|
IDEApp.ExecutionInstance mOldVerLoadExecutionInstance ~ { if (_ != null) _.mAutoDelete = true; };
|
||||||
SourceFindTask mSourceFindTask ~ delete _;
|
SourceFindTask mSourceFindTask ~ delete _;
|
||||||
|
HoverResolveTask mHoverResolveTask ~ delete _;
|
||||||
bool mWantsFastClassify;
|
bool mWantsFastClassify;
|
||||||
bool mWantsFullClassify; // This triggers a classify
|
bool mWantsFullClassify; // This triggers a classify
|
||||||
bool mWantsFullRefresh; // If mWantsFullClassify is set, mWantsFullRefresh makes the whole thing refresh
|
bool mWantsFullRefresh; // If mWantsFullClassify is set, mWantsFullRefresh makes the whole thing refresh
|
||||||
|
@ -579,6 +592,8 @@ namespace IDE.ui
|
||||||
|
|
||||||
if (ResolveCompiler.mThreadWorkerHi.mThreadRunning)
|
if (ResolveCompiler.mThreadWorkerHi.mThreadRunning)
|
||||||
{
|
{
|
||||||
|
ResolveCompiler.RequestFastFinish();
|
||||||
|
|
||||||
//Debug.WriteLine("Deferred DoAutoComplete");
|
//Debug.WriteLine("Deferred DoAutoComplete");
|
||||||
DeleteAndNullify!(mQueuedAutoComplete);
|
DeleteAndNullify!(mQueuedAutoComplete);
|
||||||
mQueuedAutoComplete = new .();
|
mQueuedAutoComplete = new .();
|
||||||
|
@ -968,6 +983,11 @@ namespace IDE.ui
|
||||||
//return;
|
//return;
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
|
if (compiler.IsPerformingBackgroundOperation())
|
||||||
|
{
|
||||||
|
compiler.RequestFastFinish();
|
||||||
|
}
|
||||||
|
|
||||||
if (bfSystem == null)
|
if (bfSystem == null)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
@ -1023,7 +1043,7 @@ namespace IDE.ui
|
||||||
bool doBackground = (useResolveType == ResolveType.Classify) || (useResolveType == ResolveType.ClassifyFullRefresh);
|
bool doBackground = (useResolveType == ResolveType.Classify) || (useResolveType == ResolveType.ClassifyFullRefresh);
|
||||||
if (mAsyncAutocomplete)
|
if (mAsyncAutocomplete)
|
||||||
{
|
{
|
||||||
if ((useResolveType == .Autocomplete) || (useResolveType == .GetCurrentLocation) || (useResolveType == .GetSymbolInfo))
|
if ((useResolveType == .Autocomplete) || (useResolveType == .GetCurrentLocation) || (useResolveType == .GetSymbolInfo) || (useResolveType == .GetResultString))
|
||||||
doBackground = true;
|
doBackground = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1111,7 +1131,9 @@ namespace IDE.ui
|
||||||
|
|
||||||
bool isHi = (resolveType != .ClassifyFullRefresh) && (resolveType != .Classify);
|
bool isHi = (resolveType != .ClassifyFullRefresh) && (resolveType != .Classify);
|
||||||
if (isHi)
|
if (isHi)
|
||||||
|
{
|
||||||
Debug.Assert(!bfCompiler.mThreadWorkerHi.mThreadRunning);
|
Debug.Assert(!bfCompiler.mThreadWorkerHi.mThreadRunning);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
Debug.Assert(!bfCompiler.mThreadWorker.mThreadRunning);
|
Debug.Assert(!bfCompiler.mThreadWorker.mThreadRunning);
|
||||||
|
|
||||||
|
@ -1209,7 +1231,10 @@ namespace IDE.ui
|
||||||
var bfCompiler = BfResolveCompiler;
|
var bfCompiler = BfResolveCompiler;
|
||||||
//var bfSystem = IDEApp.sApp.mBfResolveSystem;
|
//var bfSystem = IDEApp.sApp.mBfResolveSystem;
|
||||||
//bfCompiler.StartTiming();
|
//bfCompiler.StartTiming();
|
||||||
DoClassify(ResolveType.Classify, resolveParams);
|
ResolveType resolveType = ResolveType.Classify;
|
||||||
|
if (resolveParams != null)
|
||||||
|
resolveType = resolveParams.mResolveType;
|
||||||
|
DoClassify(resolveType, resolveParams);
|
||||||
//bfCompiler.StopTiming();
|
//bfCompiler.StopTiming();
|
||||||
if (bfCompiler != null)
|
if (bfCompiler != null)
|
||||||
bfCompiler.QueueDeferredResolveAll();
|
bfCompiler.QueueDeferredResolveAll();
|
||||||
|
@ -1600,6 +1625,11 @@ namespace IDE.ui
|
||||||
}
|
}
|
||||||
else if (resolveType == ResolveType.GetResultString)
|
else if (resolveType == ResolveType.GetResultString)
|
||||||
{
|
{
|
||||||
|
if ((mHoverResolveTask != null) && (mHoverResolveTask.mCursorPos == resolveParams.mOverrideCursorPos))
|
||||||
|
{
|
||||||
|
mHoverResolveTask.mResult = new String(autocompleteInfo);
|
||||||
|
}
|
||||||
|
|
||||||
resolveParams.mResultString = new String(autocompleteInfo);
|
resolveParams.mResultString = new String(autocompleteInfo);
|
||||||
}
|
}
|
||||||
else if (resolveType == ResolveType.GetCurrentLocation)
|
else if (resolveType == ResolveType.GetCurrentLocation)
|
||||||
|
@ -1664,7 +1694,7 @@ namespace IDE.ui
|
||||||
var bfCompiler = BfResolveCompiler;
|
var bfCompiler = BfResolveCompiler;
|
||||||
//var compiler = ResolveCompiler;
|
//var compiler = ResolveCompiler;
|
||||||
|
|
||||||
bool isBackground = (resolveType == ResolveType.Classify) || (resolveType == ResolveType.ClassifyFullRefresh);
|
bool isBackground = (resolveType == ResolveType.Classify) || (resolveType == ResolveType.ClassifyFullRefresh) || (resolveType == .GetResultString);
|
||||||
bool fullRefresh = resolveType == ResolveType.ClassifyFullRefresh;
|
bool fullRefresh = resolveType == ResolveType.ClassifyFullRefresh;
|
||||||
|
|
||||||
if (!isBackground)
|
if (!isBackground)
|
||||||
|
@ -1775,15 +1805,18 @@ namespace IDE.ui
|
||||||
int cursorPos = mEditWidget.mEditWidgetContent.CursorTextPos;
|
int cursorPos = mEditWidget.mEditWidgetContent.CursorTextPos;
|
||||||
/*if (resolveType == ResolveType.Autocomplete)
|
/*if (resolveType == ResolveType.Autocomplete)
|
||||||
cursorPos--;*/
|
cursorPos--;*/
|
||||||
if ((resolveParams != null) && (resolveParams.mOverrideCursorPos != -1))
|
if (resolveParams != null)
|
||||||
cursorPos = resolveParams.mOverrideCursorPos;
|
{
|
||||||
|
if (resolveParams.mOverrideCursorPos != -1)
|
||||||
|
cursorPos = resolveParams.mOverrideCursorPos;
|
||||||
|
}
|
||||||
|
|
||||||
if ((resolveType == ResolveType.GetNavigationData) || (resolveType == ResolveType.GetFixits))
|
if ((resolveType == ResolveType.GetNavigationData) || (resolveType == ResolveType.GetFixits))
|
||||||
parser.SetAutocomplete(-1);
|
parser.SetAutocomplete(-1);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
bool setAutocomplete = ((!isBackground) && (resolveType != ResolveType.RenameSymbol));
|
bool setAutocomplete = ((!isBackground) && (resolveType != ResolveType.RenameSymbol));
|
||||||
if ((resolveType == .Autocomplete) || (resolveType == .GetCurrentLocation) || (resolveType == .GetSymbolInfo))
|
if ((resolveType == .Autocomplete) || (resolveType == .GetCurrentLocation) || (resolveType == .GetSymbolInfo) || (resolveType == .GetResultString))
|
||||||
setAutocomplete = true;
|
setAutocomplete = true;
|
||||||
if (setAutocomplete)
|
if (setAutocomplete)
|
||||||
parser.SetAutocomplete(Math.Max(0, cursorPos));
|
parser.SetAutocomplete(Math.Max(0, cursorPos));
|
||||||
|
@ -1866,7 +1899,9 @@ namespace IDE.ui
|
||||||
|
|
||||||
resolveParams.mCancelled = true;
|
resolveParams.mCancelled = true;
|
||||||
if (resolveType == ResolveType.ClassifyFullRefresh)
|
if (resolveType == ResolveType.ClassifyFullRefresh)
|
||||||
|
{
|
||||||
QueueFullRefresh(false);
|
QueueFullRefresh(false);
|
||||||
|
}
|
||||||
bfCompiler.QueueDeferredResolveAll();
|
bfCompiler.QueueDeferredResolveAll();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4639,6 +4674,7 @@ namespace IDE.ui
|
||||||
|
|
||||||
public void UpdateMouseover(bool mouseoverFired, bool mouseInbounds, int line, int lineChar)
|
public void UpdateMouseover(bool mouseoverFired, bool mouseInbounds, int line, int lineChar)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
#unwarn
|
#unwarn
|
||||||
CompilerBase compiler = ResolveCompiler;
|
CompilerBase compiler = ResolveCompiler;
|
||||||
|
@ -4839,7 +4875,7 @@ namespace IDE.ui
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (((mHoverWatch == null) && (mouseoverFired)) || (debugExpr == null) || (hasClangHoverErrorData))
|
if (((mHoverWatch == null) && (mouseoverFired)) || (debugExpr == null) || (hasClangHoverErrorData) || (mHoverResolveTask?.mResult != null))
|
||||||
{
|
{
|
||||||
float x;
|
float x;
|
||||||
float y;
|
float y;
|
||||||
|
@ -4857,18 +4893,22 @@ namespace IDE.ui
|
||||||
|
|
||||||
String origDebugExpr = null;
|
String origDebugExpr = null;
|
||||||
|
|
||||||
|
bool handlingHoverResolveTask = false;
|
||||||
|
|
||||||
if ((debugExpr != null) || (isOverMessage))
|
if ((debugExpr != null) || (isOverMessage))
|
||||||
{
|
{
|
||||||
let resolveParams = scope ResolveParams();
|
if (mHoverResolveTask != null)
|
||||||
resolveParams.mOverrideCursorPos = (int32)textIdx;
|
{
|
||||||
if (!gApp.mDebugger.IsPaused())
|
if (mHoverResolveTask.mCursorPos != textIdx)
|
||||||
Classify(ResolveType.GetResultString, resolveParams);
|
DeleteAndNullify!(mHoverResolveTask);
|
||||||
if (!String.IsNullOrEmpty(resolveParams.mResultString))
|
}
|
||||||
|
|
||||||
|
if ((!String.IsNullOrEmpty(mHoverResolveTask?.mResult)))
|
||||||
{
|
{
|
||||||
origDebugExpr = scope:: String();
|
origDebugExpr = scope:: String();
|
||||||
origDebugExpr.Set(debugExpr);
|
origDebugExpr.Set(debugExpr);
|
||||||
|
|
||||||
debugExpr.Set(resolveParams.mResultString);
|
debugExpr.Set(mHoverResolveTask.mResult);
|
||||||
|
|
||||||
if (debugExpr.StartsWith(':'))
|
if (debugExpr.StartsWith(':'))
|
||||||
{
|
{
|
||||||
|
@ -4889,6 +4929,12 @@ namespace IDE.ui
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (mHoverResolveTask?.mResult != null)
|
||||||
|
{
|
||||||
|
handlingHoverResolveTask = true;
|
||||||
|
DeleteAndNullify!(mHoverResolveTask);
|
||||||
|
}
|
||||||
|
|
||||||
if (!triedShow)
|
if (!triedShow)
|
||||||
{
|
{
|
||||||
mHoverWatch.Show(this, x, y, debugExpr, debugExpr);
|
mHoverWatch.Show(this, x, y, debugExpr, debugExpr);
|
||||||
|
@ -4899,6 +4945,22 @@ namespace IDE.ui
|
||||||
if ((!didShow) &&
|
if ((!didShow) &&
|
||||||
((debugExpr == null) || (isOverMessage) || (!mHoverWatch.Show(this, x, y, origDebugExpr ?? debugExpr, debugExpr))))
|
((debugExpr == null) || (isOverMessage) || (!mHoverWatch.Show(this, x, y, origDebugExpr ?? debugExpr, debugExpr))))
|
||||||
{
|
{
|
||||||
|
if (mHoverResolveTask == null)
|
||||||
|
{
|
||||||
|
if ((!handlingHoverResolveTask) && (!ResolveCompiler.mThreadWorkerHi.mThreadRunning))
|
||||||
|
{
|
||||||
|
ResolveParams resolveParams = new .();
|
||||||
|
resolveParams.mOverrideCursorPos = (int32)textIdx;
|
||||||
|
Classify(ResolveType.GetResultString, resolveParams);
|
||||||
|
//Debug.WriteLine($"GetResultString {resolveParams} {resolveParams.mInDeferredList}");
|
||||||
|
if (!resolveParams.mInDeferredList)
|
||||||
|
delete resolveParams;
|
||||||
|
|
||||||
|
mHoverResolveTask = new HoverResolveTask();
|
||||||
|
mHoverResolveTask.mCursorPos = (int32)textIdx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#if IDE_C_SUPPORT
|
#if IDE_C_SUPPORT
|
||||||
if ((mIsClang) && (textIdx != -1))
|
if ((mIsClang) && (textIdx != -1))
|
||||||
{
|
{
|
||||||
|
@ -4994,7 +5056,6 @@ namespace IDE.ui
|
||||||
{
|
{
|
||||||
mWantsFullRefresh = true;
|
mWantsFullRefresh = true;
|
||||||
mRefireMouseOverAfterRefresh = true;
|
mRefireMouseOverAfterRefresh = true;
|
||||||
//Debug.WriteLine("Full refresh...");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5026,7 +5087,6 @@ namespace IDE.ui
|
||||||
{
|
{
|
||||||
if (mHoverWatch.mCloseDelay > 0)
|
if (mHoverWatch.mCloseDelay > 0)
|
||||||
{
|
{
|
||||||
//Debug.WriteLine("mHoverWatch.mCloseCountdown = 20");
|
|
||||||
mHoverWatch.mCloseDelay--;
|
mHoverWatch.mCloseDelay--;
|
||||||
mHoverWatch.mCloseCountdown = 20;
|
mHoverWatch.mCloseCountdown = 20;
|
||||||
}
|
}
|
||||||
|
@ -5042,7 +5102,6 @@ namespace IDE.ui
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
//Debug.WriteLine("mCloseCountdown = 0");
|
|
||||||
mHoverWatch.mCloseCountdown = 0;
|
mHoverWatch.mCloseCountdown = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5088,7 +5147,7 @@ namespace IDE.ui
|
||||||
#if IDE_C_SUPPORT
|
#if IDE_C_SUPPORT
|
||||||
hasClangHoverErrorData = mClangHoverErrorData != null;
|
hasClangHoverErrorData = mClangHoverErrorData != null;
|
||||||
#endif
|
#endif
|
||||||
if (((mouseoverFired) || (mHoverWatch != null) || (hasClangHoverErrorData)) &&
|
if (((mouseoverFired) || (mHoverWatch != null) || (hasClangHoverErrorData) || (mHoverResolveTask?.mResult != null)) &&
|
||||||
(mousePos.x >= 0))
|
(mousePos.x >= 0))
|
||||||
{
|
{
|
||||||
int line;
|
int line;
|
||||||
|
@ -5105,455 +5164,6 @@ namespace IDE.ui
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void UpdateMouseover2()
|
|
||||||
{
|
|
||||||
if (mWidgetWindow == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (CheckLeftMouseover())
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((DarkTooltipManager.sTooltip != null) && (DarkTooltipManager.sTooltip.mRelWidget == this))
|
|
||||||
DarkTooltipManager.CloseTooltip();
|
|
||||||
|
|
||||||
if (!CheckAllowHoverWatch())
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*if ((mHoverWatch != null) && (mHoverWatch.mCloseDelay > 0))
|
|
||||||
return;*/
|
|
||||||
var editWidgetContent = mEditWidget.Content;
|
|
||||||
Point mousePos;
|
|
||||||
bool mouseoverFired = DarkTooltipManager.CheckMouseover(editWidgetContent, 10, out mousePos);
|
|
||||||
|
|
||||||
#unwarn
|
|
||||||
CompilerBase compiler = ResolveCompiler;
|
|
||||||
|
|
||||||
bool hasClangHoverErrorData = false;
|
|
||||||
|
|
||||||
#if IDE_C_SUPPORT
|
|
||||||
hasClangHoverErrorData = mClangHoverErrorData != null;
|
|
||||||
#endif
|
|
||||||
if (((mouseoverFired) || (mHoverWatch != null) || (hasClangHoverErrorData)) &&
|
|
||||||
(mousePos.x >= 0))
|
|
||||||
{
|
|
||||||
int line;
|
|
||||||
int lineChar;
|
|
||||||
String debugExpr = null;
|
|
||||||
|
|
||||||
BfSystem bfSystem = IDEApp.sApp.mBfResolveSystem;
|
|
||||||
BfPassInstance passInstance = null;
|
|
||||||
BfParser parser = null;
|
|
||||||
int textIdx = -1;
|
|
||||||
|
|
||||||
bool isOverMessage = false;
|
|
||||||
float overflowX;
|
|
||||||
if (editWidgetContent.GetLineCharAtCoord(mousePos.x, mousePos.y, out line, out lineChar, out overflowX))
|
|
||||||
{
|
|
||||||
textIdx = editWidgetContent.GetTextIdx(line, lineChar);
|
|
||||||
|
|
||||||
int startIdx = editWidgetContent.GetTextIdx(line, lineChar);
|
|
||||||
|
|
||||||
uint8 checkFlags = (uint8)SourceElementFlags.Error;
|
|
||||||
if (!IDEApp.sApp.mDebugger.mIsRunning)
|
|
||||||
{
|
|
||||||
// Prioritize debug info over warning when we are debugging
|
|
||||||
checkFlags |= (uint8)SourceElementFlags.Warning;
|
|
||||||
}
|
|
||||||
if ((editWidgetContent.mData.mText[startIdx].mDisplayFlags & checkFlags) != 0)
|
|
||||||
isOverMessage = true;
|
|
||||||
|
|
||||||
bool doSimpleMouseover = false;
|
|
||||||
|
|
||||||
if ((editWidgetContent.mSelection != null) &&
|
|
||||||
(textIdx >= editWidgetContent.mSelection.Value.MinPos) &&
|
|
||||||
(textIdx < editWidgetContent.mSelection.Value.MaxPos))
|
|
||||||
{
|
|
||||||
debugExpr = scope:: String();
|
|
||||||
editWidgetContent.GetSelectionText(debugExpr);
|
|
||||||
}
|
|
||||||
else if (mIsBeefSource)
|
|
||||||
{
|
|
||||||
if (bfSystem != null)
|
|
||||||
{
|
|
||||||
parser = bfSystem.CreateEmptyParser(null);
|
|
||||||
|
|
||||||
var text = scope String();
|
|
||||||
mEditWidget.GetText(text);
|
|
||||||
parser.SetSource(text, mFilePath);
|
|
||||||
parser.SetAutocomplete(textIdx);
|
|
||||||
passInstance = bfSystem.CreatePassInstance("Mouseover");
|
|
||||||
parser.SetCompleteParse();
|
|
||||||
parser.Parse(passInstance, !mIsBeefSource);
|
|
||||||
parser.Reduce(passInstance);
|
|
||||||
debugExpr = scope:: String();
|
|
||||||
if (parser.GetDebugExpressionAt(textIdx, debugExpr))
|
|
||||||
{
|
|
||||||
if (debugExpr.StartsWith("`"))
|
|
||||||
debugExpr[0] = ':';
|
|
||||||
else if (debugExpr.StartsWith(":"))
|
|
||||||
debugExpr = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (mIsClang)
|
|
||||||
doSimpleMouseover = true;
|
|
||||||
|
|
||||||
if (doSimpleMouseover)
|
|
||||||
SimpleMouseover: do
|
|
||||||
{
|
|
||||||
int endIdx = startIdx;
|
|
||||||
String sb = scope:: String();
|
|
||||||
bool isInvalid = false;
|
|
||||||
bool prevWasSpace = false;
|
|
||||||
|
|
||||||
if (editWidgetContent.mData.mText[startIdx].mChar.IsWhiteSpace)
|
|
||||||
break;
|
|
||||||
|
|
||||||
startIdx--;
|
|
||||||
while (startIdx > 0)
|
|
||||||
{
|
|
||||||
var char8Data = editWidgetContent.mData.mText[startIdx];
|
|
||||||
if (char8Data.mDisplayTypeId == (uint8)SourceElementType.Comment)
|
|
||||||
{
|
|
||||||
if (startIdx == endIdx - 1)
|
|
||||||
{
|
|
||||||
// Inside comment
|
|
||||||
isInvalid = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
char8 c = (char8)char8Data.mChar;
|
|
||||||
if ((c == ' ') || (c == '\t'))
|
|
||||||
{
|
|
||||||
// Ignore
|
|
||||||
prevWasSpace = true;
|
|
||||||
}
|
|
||||||
else if (c == '\n')
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (c == '>')
|
|
||||||
{
|
|
||||||
// Is this "->"?
|
|
||||||
if ((startIdx > 1) && ((char8)editWidgetContent.mData.mText[startIdx - 1].mChar == '-'))
|
|
||||||
{
|
|
||||||
sb.Insert(0, "->");
|
|
||||||
startIdx--;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else if (c == ':')
|
|
||||||
{
|
|
||||||
// Is this "::"?
|
|
||||||
if ((startIdx > 1) && ((char8)editWidgetContent.mData.mText[startIdx - 1].mChar == ':'))
|
|
||||||
{
|
|
||||||
sb.Insert(0, "::");
|
|
||||||
startIdx--;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else if (c == '.')
|
|
||||||
sb.Insert(0, c);
|
|
||||||
else if ((c == '_') || (c.IsLetterOrDigit))
|
|
||||||
{
|
|
||||||
if (prevWasSpace)
|
|
||||||
break;
|
|
||||||
sb.Insert(0, c);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
break;
|
|
||||||
|
|
||||||
prevWasSpace = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
startIdx--;
|
|
||||||
}
|
|
||||||
|
|
||||||
prevWasSpace = false;
|
|
||||||
while ((endIdx < editWidgetContent.mData.mTextLength) && (endIdx > startIdx))
|
|
||||||
{
|
|
||||||
var char8Data = editWidgetContent.mData.mText[endIdx];
|
|
||||||
if (char8Data.mDisplayTypeId == (uint8)SourceElementType.Comment)
|
|
||||||
{
|
|
||||||
// Ignore
|
|
||||||
prevWasSpace = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
char8 c = (char8)char8Data.mChar;
|
|
||||||
if ((c == ' ') || (c == '\t'))
|
|
||||||
{
|
|
||||||
// Ignore
|
|
||||||
prevWasSpace = true;
|
|
||||||
}
|
|
||||||
else if ((c == '_') || (c.IsLetterOrDigit))
|
|
||||||
{
|
|
||||||
if (prevWasSpace)
|
|
||||||
break;
|
|
||||||
|
|
||||||
sb.Append(c);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
break;
|
|
||||||
|
|
||||||
prevWasSpace = false;
|
|
||||||
}
|
|
||||||
endIdx++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!isInvalid)
|
|
||||||
debugExpr = sb;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool triedShow = false;
|
|
||||||
|
|
||||||
if (mHoverWatch != null)
|
|
||||||
{
|
|
||||||
if (debugExpr != null)
|
|
||||||
{
|
|
||||||
if (mHoverWatch.mEvalString != debugExpr)
|
|
||||||
{
|
|
||||||
mHoverWatch.Close();
|
|
||||||
mHoverWatch = null;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
triedShow = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (((mHoverWatch == null) && (mouseoverFired)) || (debugExpr == null) || (hasClangHoverErrorData))
|
|
||||||
{
|
|
||||||
float x;
|
|
||||||
float y;
|
|
||||||
editWidgetContent.GetTextCoordAtLineChar(line, lineChar, out x, out y);
|
|
||||||
|
|
||||||
bool hasHoverWatchOpen = (mHoverWatch != null) && (mHoverWatch.mListView != null);
|
|
||||||
if (mHoverWatch == null)
|
|
||||||
mHoverWatch = new HoverWatch();
|
|
||||||
|
|
||||||
if (debugExpr != null)
|
|
||||||
triedShow = true;
|
|
||||||
|
|
||||||
bool didShow = false;
|
|
||||||
//if ((debugExpr == "var") || (debugExpr == "let"))
|
|
||||||
|
|
||||||
String origDebugExpr = null;
|
|
||||||
|
|
||||||
if ((debugExpr != null) || (isOverMessage))
|
|
||||||
{
|
|
||||||
let resolveParams = scope ResolveParams();
|
|
||||||
resolveParams.mOverrideCursorPos = (int32)textIdx;
|
|
||||||
Classify(ResolveType.GetResultString, resolveParams);
|
|
||||||
if (!String.IsNullOrEmpty(resolveParams.mResultString))
|
|
||||||
{
|
|
||||||
origDebugExpr = scope:: String();
|
|
||||||
origDebugExpr.Set(debugExpr);
|
|
||||||
|
|
||||||
debugExpr.Set(resolveParams.mResultString);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!triedShow)
|
|
||||||
{
|
|
||||||
mHoverWatch.Show(this, x, y, debugExpr, debugExpr);
|
|
||||||
triedShow = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((!didShow) &&
|
|
||||||
((debugExpr == null) || (isOverMessage) || (!mHoverWatch.Show(this, x, y, origDebugExpr ?? debugExpr, debugExpr))))
|
|
||||||
{
|
|
||||||
#if IDE_C_SUPPORT
|
|
||||||
if ((mIsClang) && (textIdx != -1))
|
|
||||||
{
|
|
||||||
bool hasErrorFlag = (mEditWidget.Content.mData.mText[textIdx].mDisplayFlags != 0);
|
|
||||||
|
|
||||||
if (hasErrorFlag)
|
|
||||||
{
|
|
||||||
if (!compiler.IsPerformingBackgroundOperation())
|
|
||||||
{
|
|
||||||
bool hadValidError = false;
|
|
||||||
if (mClangHoverErrorData != null)
|
|
||||||
{
|
|
||||||
String[] stringParts = String.StackSplit!(mClangHoverErrorData, '\t');
|
|
||||||
int startIdx = (int32)int32.Parse(stringParts[0]);
|
|
||||||
int endIdx = (int32)int32.Parse(stringParts[1]);
|
|
||||||
if ((textIdx >= startIdx) && (textIdx < endIdx))
|
|
||||||
{
|
|
||||||
hadValidError = true;
|
|
||||||
triedShow = true;
|
|
||||||
mHoverWatch.Show(this, x, y, scope String(":", stringParts[2]));
|
|
||||||
if (debugExpr != null)
|
|
||||||
mHoverWatch.mEvalString.Set(debugExpr); // Set to old debugStr for comparison
|
|
||||||
else
|
|
||||||
mHoverWatch.mEvalString.Clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!hadValidError)
|
|
||||||
{
|
|
||||||
mErrorLookupTextIdx = (int32)textIdx;
|
|
||||||
Classify(ResolveType.Classify);
|
|
||||||
triedShow = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
triedShow = false;
|
|
||||||
delete mClangHoverErrorData;
|
|
||||||
mClangHoverErrorData = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if ((parser != null) && (mIsBeefSource))
|
|
||||||
ErrorScope:
|
|
||||||
{
|
|
||||||
//TODO: Needed this?
|
|
||||||
/*var resolvePassData = parser.CreateResolvePassData();
|
|
||||||
defer (scope) delete resolvePassData;
|
|
||||||
bfSystem.NotifyWillRequestLock(1);
|
|
||||||
bfSystem.Lock(1);
|
|
||||||
parser.BuildDefs(passInstance, resolvePassData, false);
|
|
||||||
BfResolveCompiler.ClassifySource(passInstance, parser, resolvePassData, null);*/
|
|
||||||
|
|
||||||
BfPassInstance.BfError bestError = scope BfPassInstance.BfError();
|
|
||||||
|
|
||||||
for (var bfError in mErrorList)
|
|
||||||
{
|
|
||||||
if (bfError.mIsWhileSpecializing)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if ((textIdx >= bfError.mSrcStart) && (textIdx < bfError.mSrcEnd))
|
|
||||||
{
|
|
||||||
if ((bestError.mError == null) || (bestError.mIsWarning) || (bestError.mIsPersistent))
|
|
||||||
bestError = bfError;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
String showMouseoverString = null;
|
|
||||||
if (bestError.mError != null)
|
|
||||||
{
|
|
||||||
showMouseoverString = scope:: String(":", bestError.mError);
|
|
||||||
|
|
||||||
if (bestError.mMoreInfo != null)
|
|
||||||
{
|
|
||||||
for (var moreInfo in bestError.mMoreInfo)
|
|
||||||
{
|
|
||||||
showMouseoverString.AppendF("\n@{0}\t{1}\t{2}", moreInfo.mFilePath, moreInfo.mSrcStart, moreInfo.mError);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
var flags = (SourceElementFlags)editWidgetContent.mData.mText[textIdx].mDisplayFlags;
|
|
||||||
if ((flags.HasFlag(.Error)) || (flags.HasFlag(.Warning)))
|
|
||||||
{
|
|
||||||
mWantsFullRefresh = true;
|
|
||||||
mRefireMouseOverAfterRefresh = true;
|
|
||||||
//Debug.WriteLine("Full refresh...");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (showMouseoverString != null)
|
|
||||||
{
|
|
||||||
triedShow = true;
|
|
||||||
mHoverWatch.Show(this, x, y, showMouseoverString, showMouseoverString);
|
|
||||||
if (debugExpr != null)
|
|
||||||
mHoverWatch.mEvalString.Set(debugExpr); // Set to old debugStr for comparison
|
|
||||||
}
|
|
||||||
else
|
|
||||||
triedShow = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!hasHoverWatchOpen)
|
|
||||||
mHoverWatch.mOpenMousePos = DarkTooltipManager.sLastRelMousePos;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Not used?
|
|
||||||
if ((mHoverWatch != null) && (mHoverWatch.mTextPanel != this))
|
|
||||||
{
|
|
||||||
mHoverWatch.Close();
|
|
||||||
mHoverWatch = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mHoverWatch != null)
|
|
||||||
{
|
|
||||||
if ((!triedShow) && (!IDEApp.sApp.HasPopupMenus()))
|
|
||||||
{
|
|
||||||
if (mHoverWatch.mCloseDelay > 0)
|
|
||||||
{
|
|
||||||
//Debug.WriteLine("mHoverWatch.mCloseCountdown = 20");
|
|
||||||
mHoverWatch.mCloseDelay--;
|
|
||||||
mHoverWatch.mCloseCountdown = 20;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
mHoverWatch.Close();
|
|
||||||
mHoverWatch = null;
|
|
||||||
#if IDE_C_SUPPORT
|
|
||||||
delete mClangHoverErrorData;
|
|
||||||
mClangHoverErrorData = null;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
//Debug.WriteLine("mCloseCountdown = 0");
|
|
||||||
mHoverWatch.mCloseCountdown = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (passInstance != null)
|
|
||||||
delete passInstance;
|
|
||||||
if (parser != null)
|
|
||||||
{
|
|
||||||
delete parser;
|
|
||||||
mWantsParserCleanup = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#if IDE_C_SUPPORT
|
|
||||||
delete mClangHoverErrorData;
|
|
||||||
mClangHoverErrorData = null;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*if ((mIsClang) && (!compiler.IsPerformingBackgroundOperation()))
|
|
||||||
{
|
|
||||||
bool hadValidError = false;
|
|
||||||
if (mClangHoverErrorData != null)
|
|
||||||
{
|
|
||||||
int textIdx = -1;
|
|
||||||
int line;
|
|
||||||
int lineChar;
|
|
||||||
if (editWidgetContent.GetLineCharAtCoord(mousePos.x, mousePos.y, out line, out lineChar))
|
|
||||||
textIdx = editWidgetContent.GetTextIdx(line, lineChar);
|
|
||||||
|
|
||||||
string[] stringParts = mClangHoverErrorData.Split('\t');
|
|
||||||
int startIdx = int.Parse(stringParts[0]);
|
|
||||||
int endIdx = int.Parse(stringParts[1]);
|
|
||||||
if ((textIdx >= startIdx) && (textIdx < endIdx))
|
|
||||||
{
|
|
||||||
hadValidError = true;
|
|
||||||
mHoverWatch.Show(this, x, y, ":" + stringParts[2]);
|
|
||||||
mHoverWatch.mEvalString.Set(debugExpr); // Set to old debugStr for comparison
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}*/
|
|
||||||
}
|
|
||||||
|
|
||||||
void DuplicateEditState(out EditWidgetContent.CharData[] char8Data, out IdSpan char8IdData)
|
void DuplicateEditState(out EditWidgetContent.CharData[] char8Data, out IdSpan char8IdData)
|
||||||
{
|
{
|
||||||
var srcCharData = mEditWidget.Content.mData.mText;
|
var srcCharData = mEditWidget.Content.mData.mText;
|
||||||
|
@ -5840,6 +5450,13 @@ namespace IDE.ui
|
||||||
checkIdx++;
|
checkIdx++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!resolveResult.mWaitEvent.WaitFor(0))
|
||||||
|
{
|
||||||
|
if (waitTime != 0)
|
||||||
|
ResolveCompiler.RequestFastFinish();
|
||||||
|
}
|
||||||
|
|
||||||
if (!resolveResult.mWaitEvent.WaitFor(waitTime))
|
if (!resolveResult.mWaitEvent.WaitFor(waitTime))
|
||||||
{
|
{
|
||||||
checkIdx++;
|
checkIdx++;
|
||||||
|
@ -5847,6 +5464,9 @@ namespace IDE.ui
|
||||||
}
|
}
|
||||||
mDeferredResolveResults.RemoveAt(checkIdx);
|
mDeferredResolveResults.RemoveAt(checkIdx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Debug.WriteLine($"HandleResolveResult {resolveResult}");
|
||||||
|
|
||||||
HandleResolveResult(resolveResult.mResolveType, resolveResult.mAutocompleteInfo, resolveResult);
|
HandleResolveResult(resolveResult.mResolveType, resolveResult.mAutocompleteInfo, resolveResult);
|
||||||
|
|
||||||
//Debug.WriteLine("ProcessDeferredResolveResults finished {0}", resolveResult.mResolveType);
|
//Debug.WriteLine("ProcessDeferredResolveResults finished {0}", resolveResult.mResolveType);
|
||||||
|
@ -5887,12 +5507,15 @@ namespace IDE.ui
|
||||||
{
|
{
|
||||||
MarkDirty();
|
MarkDirty();
|
||||||
if (resolveResult.mPassInstance.HadSignatureChanges())
|
if (resolveResult.mPassInstance.HadSignatureChanges())
|
||||||
|
{
|
||||||
mWantsFullRefresh = true;
|
mWantsFullRefresh = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*if (checkIt)
|
/*if (checkIt)
|
||||||
Debug.Assert(data.mDisplayTypeId == 8);*/
|
Debug.Assert(data.mDisplayTypeId == 8);*/
|
||||||
|
|
||||||
|
//Debug.WriteLine($"Deleting {resolveResult}");
|
||||||
delete resolveResult;
|
delete resolveResult;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6368,6 +5991,9 @@ namespace IDE.ui
|
||||||
mLockFlashPct = 0;
|
mLockFlashPct = 0;
|
||||||
MarkDirty();
|
MarkDirty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((mEmitRevision >= 0) && ((mUpdateCnt % 30) == 0))
|
||||||
|
CheckEmitRevision();
|
||||||
}
|
}
|
||||||
|
|
||||||
void InjectErrors(BfPassInstance processingPassInstance, EditWidgetContent.CharData[] processResolveCharData, IdSpan processCharIdSpan, bool keepPersistentErrors)
|
void InjectErrors(BfPassInstance processingPassInstance, EditWidgetContent.CharData[] processResolveCharData, IdSpan processCharIdSpan, bool keepPersistentErrors)
|
||||||
|
@ -6396,10 +6022,14 @@ namespace IDE.ui
|
||||||
int32 errorCount = processingPassInstance.GetErrorCount();
|
int32 errorCount = processingPassInstance.GetErrorCount();
|
||||||
mErrorList.Capacity = mErrorList.Count + errorCount;
|
mErrorList.Capacity = mErrorList.Count + errorCount;
|
||||||
|
|
||||||
|
bool hadNonDeferredErrors = false;
|
||||||
|
|
||||||
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();
|
||||||
processingPassInstance.GetErrorData(errorIdx, bfError);
|
processingPassInstance.GetErrorData(errorIdx, bfError);
|
||||||
|
if (!bfError.mIsDeferred)
|
||||||
|
hadNonDeferredErrors = true;
|
||||||
|
|
||||||
for (int32 moreInfoIdx < bfError.mMoreInfoCount)
|
for (int32 moreInfoIdx < bfError.mMoreInfoCount)
|
||||||
{
|
{
|
||||||
|
@ -6425,6 +6055,9 @@ namespace IDE.ui
|
||||||
if (bfError.mIsWhileSpecializing)
|
if (bfError.mIsWhileSpecializing)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
if ((bfError.mIsDeferred) && (hadNonDeferredErrors))
|
||||||
|
continue;
|
||||||
|
|
||||||
if (bfError.mIsPersistent)
|
if (bfError.mIsPersistent)
|
||||||
{
|
{
|
||||||
if (bfError.mIdSpan.IsEmpty)
|
if (bfError.mIdSpan.IsEmpty)
|
||||||
|
@ -6823,5 +6456,27 @@ namespace IDE.ui
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void CheckEmitRevision()
|
||||||
|
{
|
||||||
|
if (mEmitRevision != -1)
|
||||||
|
{
|
||||||
|
BfCompiler compiler = null;
|
||||||
|
if (mFilePath.Contains("$EmitR$"))
|
||||||
|
compiler = gApp.mBfResolveCompiler;
|
||||||
|
else if (mFilePath.Contains("$Emit$"))
|
||||||
|
compiler = gApp.mBfBuildCompiler;
|
||||||
|
|
||||||
|
if (compiler != null)
|
||||||
|
{
|
||||||
|
int32 version = compiler.GetEmitVersion(mFilePath);
|
||||||
|
if ((version >= 0) && (version != mEmitRevision))
|
||||||
|
{
|
||||||
|
mEmitRevision = version;
|
||||||
|
Reload();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -880,6 +880,21 @@ void BeIRCodeGen::Read(BeValue*& beValue)
|
||||||
beValue = mBeModule->CreateUndefValue(type);
|
beValue = mBeModule->CreateUndefValue(type);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
else if (constType == BfConstType_TypeOf)
|
||||||
|
{
|
||||||
|
CMD_PARAM(BeType*, type);
|
||||||
|
beValue = mReflectDataMap[type];
|
||||||
|
BF_ASSERT(beValue != NULL);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else if (constType == BfConstType_TypeOf_WithData)
|
||||||
|
{
|
||||||
|
CMD_PARAM(BeType*, type);
|
||||||
|
CMD_PARAM(BeValue*, value);
|
||||||
|
mReflectDataMap[type] = value;
|
||||||
|
beValue = value;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
bool isSigned = false;
|
bool isSigned = false;
|
||||||
BeType* llvmConstType = GetBeType(typeCode, isSigned);
|
BeType* llvmConstType = GetBeType(typeCode, isSigned);
|
||||||
|
@ -1969,6 +1984,13 @@ void BeIRCodeGen::HandleNextCmd()
|
||||||
//SetResult(curId, globalVariable);
|
//SetResult(curId, globalVariable);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case BfIRCmd_SetReflectTypeData:
|
||||||
|
{
|
||||||
|
CMD_PARAM(BeType*, type);
|
||||||
|
CMD_PARAM(BeValue*, value);
|
||||||
|
mReflectDataMap[type] = value;
|
||||||
|
}
|
||||||
|
break;
|
||||||
case BfIRCmd_CreateBlock:
|
case BfIRCmd_CreateBlock:
|
||||||
{
|
{
|
||||||
CMD_PARAM(String, name);
|
CMD_PARAM(String, name);
|
||||||
|
|
|
@ -89,6 +89,7 @@ public:
|
||||||
Dictionary<int, BeIRTypeEntry> mTypes;
|
Dictionary<int, BeIRTypeEntry> mTypes;
|
||||||
|
|
||||||
Dictionary<BeType*, BeDbgType*> mOnDemandTypeMap;
|
Dictionary<BeType*, BeDbgType*> mOnDemandTypeMap;
|
||||||
|
Dictionary<BeType*, BeValue*> mReflectDataMap;
|
||||||
Array<int> mConfigConsts;
|
Array<int> mConfigConsts;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -946,6 +946,14 @@ BfParser* BfAstNode::GetParser()
|
||||||
return sourceData->ToParser();
|
return sourceData->ToParser();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool BfAstNode::IsEmitted()
|
||||||
|
{
|
||||||
|
auto parser = GetParser();
|
||||||
|
if (parser == NULL)
|
||||||
|
return false;
|
||||||
|
return parser->mIsEmitted;
|
||||||
|
}
|
||||||
|
|
||||||
bool BfAstNode::IsFromParser(BfParser* parser)
|
bool BfAstNode::IsFromParser(BfParser* parser)
|
||||||
{
|
{
|
||||||
if (parser == NULL)
|
if (parser == NULL)
|
||||||
|
|
|
@ -1088,6 +1088,7 @@ public:
|
||||||
BfSourceData* GetSourceData();
|
BfSourceData* GetSourceData();
|
||||||
BfParserData* GetParserData();
|
BfParserData* GetParserData();
|
||||||
BfParser* GetParser();
|
BfParser* GetParser();
|
||||||
|
bool IsEmitted();
|
||||||
bool IsFromParser(BfParser* parser);
|
bool IsFromParser(BfParser* parser);
|
||||||
String ToString();
|
String ToString();
|
||||||
StringView ToStringView();
|
StringView ToStringView();
|
||||||
|
|
|
@ -346,6 +346,8 @@ BfCompiler::BfCompiler(BfSystem* bfSystem, bool isResolveOnly)
|
||||||
memset(&mStats, 0, sizeof(mStats));
|
memset(&mStats, 0, sizeof(mStats));
|
||||||
mCompletionPct = 0;
|
mCompletionPct = 0;
|
||||||
mCanceling = false;
|
mCanceling = false;
|
||||||
|
mFastFinish = false;
|
||||||
|
mHasQueuedTypeRebuilds = false;
|
||||||
mIsResolveOnly = isResolveOnly;
|
mIsResolveOnly = isResolveOnly;
|
||||||
mResolvePassData = NULL;
|
mResolvePassData = NULL;
|
||||||
mPassInstance = NULL;
|
mPassInstance = NULL;
|
||||||
|
@ -397,6 +399,7 @@ BfCompiler::BfCompiler(BfSystem* bfSystem, bool isResolveOnly)
|
||||||
mActionTypeDef = NULL;
|
mActionTypeDef = NULL;
|
||||||
mEnumTypeDef = NULL;
|
mEnumTypeDef = NULL;
|
||||||
mFriendAttributeTypeDef = NULL;
|
mFriendAttributeTypeDef = NULL;
|
||||||
|
mComptimeAttributeTypeDef = NULL;
|
||||||
mConstEvalAttributeTypeDef = NULL;
|
mConstEvalAttributeTypeDef = NULL;
|
||||||
mNoExtensionAttributeTypeDef = NULL;
|
mNoExtensionAttributeTypeDef = NULL;
|
||||||
mCheckedAttributeTypeDef = NULL;
|
mCheckedAttributeTypeDef = NULL;
|
||||||
|
@ -408,11 +411,14 @@ BfCompiler::BfCompiler(BfSystem* bfSystem, bool isResolveOnly)
|
||||||
mGenericIRefEnumeratorTypeDef = NULL;
|
mGenericIRefEnumeratorTypeDef = NULL;
|
||||||
mInlineAttributeTypeDef = NULL;
|
mInlineAttributeTypeDef = NULL;
|
||||||
mThreadTypeDef = NULL;
|
mThreadTypeDef = NULL;
|
||||||
mInternalTypeDef = NULL;
|
mInternalTypeDef = NULL;
|
||||||
|
mCompilerTypeDef = NULL;
|
||||||
mDiagnosticsDebugTypeDef = NULL;
|
mDiagnosticsDebugTypeDef = NULL;
|
||||||
mIDisposableTypeDef = NULL;
|
mIDisposableTypeDef = NULL;
|
||||||
mIPrintableTypeDef = NULL;
|
mIPrintableTypeDef = NULL;
|
||||||
mIHashableTypeDef = NULL;
|
mIHashableTypeDef = NULL;
|
||||||
|
mIComptimeTypeApply = NULL;
|
||||||
|
mIComptimeMethodApply = NULL;
|
||||||
mLinkNameAttributeTypeDef = NULL;
|
mLinkNameAttributeTypeDef = NULL;
|
||||||
mCallingConventionAttributeTypeDef = NULL;
|
mCallingConventionAttributeTypeDef = NULL;
|
||||||
mMethodRefTypeDef = NULL;
|
mMethodRefTypeDef = NULL;
|
||||||
|
@ -447,6 +453,7 @@ BfCompiler::BfCompiler(BfSystem* bfSystem, bool isResolveOnly)
|
||||||
mWarnAttributeTypeDef = NULL;
|
mWarnAttributeTypeDef = NULL;
|
||||||
mIgnoreErrorsAttributeTypeDef = NULL;
|
mIgnoreErrorsAttributeTypeDef = NULL;
|
||||||
mReflectAttributeTypeDef = NULL;
|
mReflectAttributeTypeDef = NULL;
|
||||||
|
mOnCompileAttributeTypeDef = NULL;
|
||||||
|
|
||||||
mLastAutocompleteModule = NULL;
|
mLastAutocompleteModule = NULL;
|
||||||
|
|
||||||
|
@ -3919,6 +3926,8 @@ void BfCompiler::ProcessAutocompleteTempType()
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mFastFinish = false;
|
||||||
|
|
||||||
SetAndRestoreValue<BfMethodState*> prevMethodState(module->mCurMethodState, NULL);
|
SetAndRestoreValue<BfMethodState*> prevMethodState(module->mCurMethodState, NULL);
|
||||||
SetAndRestoreValue<BfTypeInstance*> prevTypeInstance(module->mCurTypeInstance, NULL);
|
SetAndRestoreValue<BfTypeInstance*> prevTypeInstance(module->mCurTypeInstance, NULL);
|
||||||
SetAndRestoreValue<BfMethodInstance*> prevMethodInstance(module->mCurMethodInstance, NULL);
|
SetAndRestoreValue<BfMethodInstance*> prevMethodInstance(module->mCurMethodInstance, NULL);
|
||||||
|
@ -6522,13 +6531,15 @@ bool BfCompiler::DoCompile(const StringImpl& outputDirectory)
|
||||||
|
|
||||||
|
|
||||||
if (IsHotCompile())
|
if (IsHotCompile())
|
||||||
{
|
{
|
||||||
mContext->EnsureHotMangledVirtualMethodNames();
|
mContext->EnsureHotMangledVirtualMethodNames();
|
||||||
}
|
}
|
||||||
|
|
||||||
mOutputDirectory = outputDirectory;
|
mOutputDirectory = outputDirectory;
|
||||||
mSystem->StartYieldSection();
|
mSystem->StartYieldSection();
|
||||||
|
|
||||||
|
mFastFinish = false;
|
||||||
|
mHasQueuedTypeRebuilds = false;
|
||||||
mCanceling = false;
|
mCanceling = false;
|
||||||
mSystem->CheckLockYield();
|
mSystem->CheckLockYield();
|
||||||
|
|
||||||
|
@ -6611,6 +6622,7 @@ bool BfCompiler::DoCompile(const StringImpl& outputDirectory)
|
||||||
mActionTypeDef = _GetRequiredType("System.Action");
|
mActionTypeDef = _GetRequiredType("System.Action");
|
||||||
mEnumTypeDef = _GetRequiredType("System.Enum");
|
mEnumTypeDef = _GetRequiredType("System.Enum");
|
||||||
mFriendAttributeTypeDef = _GetRequiredType("System.FriendAttribute");
|
mFriendAttributeTypeDef = _GetRequiredType("System.FriendAttribute");
|
||||||
|
mComptimeAttributeTypeDef = _GetRequiredType("System.ComptimeAttribute");
|
||||||
mConstEvalAttributeTypeDef = _GetRequiredType("System.ConstEvalAttribute");
|
mConstEvalAttributeTypeDef = _GetRequiredType("System.ConstEvalAttribute");
|
||||||
mNoExtensionAttributeTypeDef = _GetRequiredType("System.NoExtensionAttribute");
|
mNoExtensionAttributeTypeDef = _GetRequiredType("System.NoExtensionAttribute");
|
||||||
mCheckedAttributeTypeDef = _GetRequiredType("System.CheckedAttribute");
|
mCheckedAttributeTypeDef = _GetRequiredType("System.CheckedAttribute");
|
||||||
|
@ -6624,10 +6636,13 @@ bool BfCompiler::DoCompile(const StringImpl& outputDirectory)
|
||||||
mInlineAttributeTypeDef = _GetRequiredType("System.InlineAttribute");
|
mInlineAttributeTypeDef = _GetRequiredType("System.InlineAttribute");
|
||||||
mThreadTypeDef = _GetRequiredType("System.Threading.Thread");
|
mThreadTypeDef = _GetRequiredType("System.Threading.Thread");
|
||||||
mInternalTypeDef = _GetRequiredType("System.Internal");
|
mInternalTypeDef = _GetRequiredType("System.Internal");
|
||||||
|
mCompilerTypeDef = _GetRequiredType("System.Compiler");
|
||||||
mDiagnosticsDebugTypeDef = _GetRequiredType("System.Diagnostics.Debug");
|
mDiagnosticsDebugTypeDef = _GetRequiredType("System.Diagnostics.Debug");
|
||||||
mIDisposableTypeDef = _GetRequiredType("System.IDisposable");
|
mIDisposableTypeDef = _GetRequiredType("System.IDisposable");
|
||||||
mIPrintableTypeDef = _GetRequiredType("System.IPrintable");
|
mIPrintableTypeDef = _GetRequiredType("System.IPrintable");
|
||||||
mIHashableTypeDef = _GetRequiredType("System.IHashable");
|
mIHashableTypeDef = _GetRequiredType("System.IHashable");
|
||||||
|
mIComptimeTypeApply = _GetRequiredType("System.IComptimeTypeApply");
|
||||||
|
mIComptimeMethodApply = _GetRequiredType("System.IComptimeMethodApply");
|
||||||
mLinkNameAttributeTypeDef = _GetRequiredType("System.LinkNameAttribute");
|
mLinkNameAttributeTypeDef = _GetRequiredType("System.LinkNameAttribute");
|
||||||
mCallingConventionAttributeTypeDef = _GetRequiredType("System.CallingConventionAttribute");
|
mCallingConventionAttributeTypeDef = _GetRequiredType("System.CallingConventionAttribute");
|
||||||
mMethodRefTypeDef = _GetRequiredType("System.MethodReference", 1);
|
mMethodRefTypeDef = _GetRequiredType("System.MethodReference", 1);
|
||||||
|
@ -6662,6 +6677,7 @@ bool BfCompiler::DoCompile(const StringImpl& outputDirectory)
|
||||||
mWarnAttributeTypeDef = _GetRequiredType("System.WarnAttribute");
|
mWarnAttributeTypeDef = _GetRequiredType("System.WarnAttribute");
|
||||||
mIgnoreErrorsAttributeTypeDef = _GetRequiredType("System.IgnoreErrorsAttribute");
|
mIgnoreErrorsAttributeTypeDef = _GetRequiredType("System.IgnoreErrorsAttribute");
|
||||||
mReflectAttributeTypeDef = _GetRequiredType("System.ReflectAttribute");
|
mReflectAttributeTypeDef = _GetRequiredType("System.ReflectAttribute");
|
||||||
|
mOnCompileAttributeTypeDef = _GetRequiredType("System.OnCompileAttribute");
|
||||||
|
|
||||||
for (int i = 0; i < BfTypeCode_Length; i++)
|
for (int i = 0; i < BfTypeCode_Length; i++)
|
||||||
mContext->mPrimitiveStructTypes[i] = NULL;
|
mContext->mPrimitiveStructTypes[i] = NULL;
|
||||||
|
@ -7213,6 +7229,8 @@ bool BfCompiler::DoCompile(const StringImpl& outputDirectory)
|
||||||
}
|
}
|
||||||
mCodeGen.ProcessErrors(mPassInstance, mCanceling);
|
mCodeGen.ProcessErrors(mPassInstance, mCanceling);
|
||||||
|
|
||||||
|
mCEMachine->CompileDone();
|
||||||
|
|
||||||
// This has to happen after codegen because we may delete modules that are referenced in codegen
|
// This has to happen after codegen because we may delete modules that are referenced in codegen
|
||||||
mContext->Cleanup();
|
mContext->Cleanup();
|
||||||
if ((!IsHotCompile()) && (!mIsResolveOnly) && (!mCanceling))
|
if ((!IsHotCompile()) && (!mIsResolveOnly) && (!mCanceling))
|
||||||
|
@ -7346,7 +7364,7 @@ bool BfCompiler::DoCompile(const StringImpl& outputDirectory)
|
||||||
|
|
||||||
mContext->ValidateDependencies();
|
mContext->ValidateDependencies();
|
||||||
|
|
||||||
return !didCancel;
|
return !didCancel && !mHasQueuedTypeRebuilds;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BfCompiler::Compile(const StringImpl& outputDirectory)
|
bool BfCompiler::Compile(const StringImpl& outputDirectory)
|
||||||
|
@ -7380,11 +7398,19 @@ void BfCompiler::ClearResults()
|
||||||
void BfCompiler::Cancel()
|
void BfCompiler::Cancel()
|
||||||
{
|
{
|
||||||
mCanceling = true;
|
mCanceling = true;
|
||||||
|
mFastFinish = true;
|
||||||
mHadCancel = true;
|
mHadCancel = true;
|
||||||
BfLogSysM("BfCompiler::Cancel\n");
|
BfLogSysM("BfCompiler::Cancel\n");
|
||||||
BpEvent("BfCompiler::Cancel", "");
|
BpEvent("BfCompiler::Cancel", "");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void BfCompiler::RequestFastFinish()
|
||||||
|
{
|
||||||
|
mFastFinish = true;
|
||||||
|
BfLogSysM("BfCompiler::RequestFastFinish\n");
|
||||||
|
BpEvent("BfCompiler::RequestFastFinish", "");
|
||||||
|
}
|
||||||
|
|
||||||
//#define WANT_COMPILE_LOG
|
//#define WANT_COMPILE_LOG
|
||||||
|
|
||||||
void BfCompiler::CompileLog(const char* fmt ...)
|
void BfCompiler::CompileLog(const char* fmt ...)
|
||||||
|
@ -8538,6 +8564,38 @@ String BfCompiler::GetTypeDefInfo(const StringImpl& inTypeName)
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int BfCompiler::GetEmitSource(const StringImpl& fileName, StringImpl* outBuffer)
|
||||||
|
{
|
||||||
|
int lastDollarPos = (int)fileName.LastIndexOf('$');
|
||||||
|
if (lastDollarPos == -1)
|
||||||
|
return -1;
|
||||||
|
int dotPos = (int)fileName.LastIndexOf('.');
|
||||||
|
if (dotPos == -1)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
String typeIdStr = fileName.Substring(lastDollarPos + 1, dotPos - lastDollarPos - 1);
|
||||||
|
|
||||||
|
int revisionId = (int)atoi(typeIdStr.c_str());
|
||||||
|
int typeId = (int)atoi(typeIdStr.c_str());
|
||||||
|
if ((typeId <= 0) || (typeId >= mContext->mTypes.mSize))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
auto type = mContext->mTypes[typeId];
|
||||||
|
if (type == NULL)
|
||||||
|
return -1;
|
||||||
|
auto typeInst = type->ToTypeInstance();
|
||||||
|
if (typeInst == NULL)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
auto typeDef = typeInst->mTypeDef;
|
||||||
|
|
||||||
|
if (typeDef->mEmitParser == NULL)
|
||||||
|
return -1;
|
||||||
|
if (outBuffer != NULL)
|
||||||
|
outBuffer->Append(typeDef->mEmitParser->mSrc, typeDef->mEmitParser->mSrcLength);
|
||||||
|
return typeInst->mRevision;
|
||||||
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
PerfManager* BfGetPerfManager(BfParser* bfParser);
|
PerfManager* BfGetPerfManager(BfParser* bfParser);
|
||||||
|
@ -8738,6 +8796,11 @@ BF_EXPORT void BF_CALLTYPE BfCompiler_Cancel(BfCompiler* bfCompiler)
|
||||||
bfCompiler->Cancel();
|
bfCompiler->Cancel();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BF_EXPORT void BF_CALLTYPE BfCompiler_RequestFastFinish(BfCompiler* bfCompiler)
|
||||||
|
{
|
||||||
|
bfCompiler->RequestFastFinish();
|
||||||
|
}
|
||||||
|
|
||||||
BF_EXPORT void BF_CALLTYPE BfCompiler_ClearBuildCache(BfCompiler* bfCompiler)
|
BF_EXPORT void BF_CALLTYPE BfCompiler_ClearBuildCache(BfCompiler* bfCompiler)
|
||||||
{
|
{
|
||||||
bfCompiler->ClearBuildCache();
|
bfCompiler->ClearBuildCache();
|
||||||
|
@ -9251,3 +9314,17 @@ BF_EXPORT void BF_CALLTYPE BfCompiler_ForceRebuild(BfCompiler* bfCompiler)
|
||||||
bfCompiler->mOptions.mForceRebuildIdx++;
|
bfCompiler->mOptions.mForceRebuildIdx++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BF_EXPORT const char* BF_CALLTYPE BfCompiler_GetEmitSource(BfCompiler* bfCompiler, char* fileName)
|
||||||
|
{
|
||||||
|
String& outString = *gTLStrReturn.Get();
|
||||||
|
outString.clear();
|
||||||
|
bfCompiler->GetEmitSource(fileName, &outString);
|
||||||
|
if (outString.IsEmpty())
|
||||||
|
return NULL;
|
||||||
|
return outString.c_str();
|
||||||
|
}
|
||||||
|
|
||||||
|
BF_EXPORT int32 BF_CALLTYPE BfCompiler_GetEmitSourceVersion(BfCompiler* bfCompiler, char* fileName)
|
||||||
|
{
|
||||||
|
return bfCompiler->GetEmitSource(fileName, NULL);
|
||||||
|
}
|
||||||
|
|
|
@ -323,6 +323,8 @@ public:
|
||||||
BfCodeGen mCodeGen;
|
BfCodeGen mCodeGen;
|
||||||
String mOutputDirectory;
|
String mOutputDirectory;
|
||||||
bool mCanceling;
|
bool mCanceling;
|
||||||
|
bool mFastFinish;
|
||||||
|
bool mHasQueuedTypeRebuilds; // Infers we had a fast finish that requires a type rebuild
|
||||||
bool mHadCancel;
|
bool mHadCancel;
|
||||||
bool mWantsDeferMethodDecls;
|
bool mWantsDeferMethodDecls;
|
||||||
bool mInInvalidState;
|
bool mInInvalidState;
|
||||||
|
@ -362,10 +364,13 @@ public:
|
||||||
|
|
||||||
BfTypeDef* mThreadTypeDef;
|
BfTypeDef* mThreadTypeDef;
|
||||||
BfTypeDef* mInternalTypeDef;
|
BfTypeDef* mInternalTypeDef;
|
||||||
|
BfTypeDef* mCompilerTypeDef;
|
||||||
BfTypeDef* mDiagnosticsDebugTypeDef;
|
BfTypeDef* mDiagnosticsDebugTypeDef;
|
||||||
BfTypeDef* mIDisposableTypeDef;
|
BfTypeDef* mIDisposableTypeDef;
|
||||||
BfTypeDef* mIPrintableTypeDef;
|
BfTypeDef* mIPrintableTypeDef;
|
||||||
BfTypeDef* mIHashableTypeDef;
|
BfTypeDef* mIHashableTypeDef;
|
||||||
|
BfTypeDef* mIComptimeTypeApply;
|
||||||
|
BfTypeDef* mIComptimeMethodApply;
|
||||||
|
|
||||||
BfTypeDef* mMethodRefTypeDef;
|
BfTypeDef* mMethodRefTypeDef;
|
||||||
BfTypeDef* mNullableTypeDef;
|
BfTypeDef* mNullableTypeDef;
|
||||||
|
@ -403,6 +408,7 @@ public:
|
||||||
BfTypeDef* mDisableChecksAttributeTypeDef;
|
BfTypeDef* mDisableChecksAttributeTypeDef;
|
||||||
BfTypeDef* mDisableObjectAccessChecksAttributeTypeDef;
|
BfTypeDef* mDisableObjectAccessChecksAttributeTypeDef;
|
||||||
BfTypeDef* mFriendAttributeTypeDef;
|
BfTypeDef* mFriendAttributeTypeDef;
|
||||||
|
BfTypeDef* mComptimeAttributeTypeDef;
|
||||||
BfTypeDef* mConstEvalAttributeTypeDef;
|
BfTypeDef* mConstEvalAttributeTypeDef;
|
||||||
BfTypeDef* mNoExtensionAttributeTypeDef;
|
BfTypeDef* mNoExtensionAttributeTypeDef;
|
||||||
BfTypeDef* mCheckedAttributeTypeDef;
|
BfTypeDef* mCheckedAttributeTypeDef;
|
||||||
|
@ -417,6 +423,7 @@ public:
|
||||||
BfTypeDef* mWarnAttributeTypeDef;
|
BfTypeDef* mWarnAttributeTypeDef;
|
||||||
BfTypeDef* mIgnoreErrorsAttributeTypeDef;
|
BfTypeDef* mIgnoreErrorsAttributeTypeDef;
|
||||||
BfTypeDef* mReflectAttributeTypeDef;
|
BfTypeDef* mReflectAttributeTypeDef;
|
||||||
|
BfTypeDef* mOnCompileAttributeTypeDef;
|
||||||
|
|
||||||
int mCurTypeId;
|
int mCurTypeId;
|
||||||
int mTypeInitCount;
|
int mTypeInitCount;
|
||||||
|
@ -493,9 +500,11 @@ public:
|
||||||
void ProcessAutocompleteTempType();
|
void ProcessAutocompleteTempType();
|
||||||
void GetSymbolReferences();
|
void GetSymbolReferences();
|
||||||
void Cancel();
|
void Cancel();
|
||||||
|
void RequestFastFinish();
|
||||||
String GetTypeDefList();
|
String GetTypeDefList();
|
||||||
String GetTypeDefMatches(const StringImpl& searchSrc);
|
String GetTypeDefMatches(const StringImpl& searchSrc);
|
||||||
String GetTypeDefInfo(const StringImpl& typeName);
|
String GetTypeDefInfo(const StringImpl& typeName);
|
||||||
|
int GetEmitSource(const StringImpl& fileName, StringImpl* outBuffer);
|
||||||
|
|
||||||
void CompileLog(const char* fmt ...);
|
void CompileLog(const char* fmt ...);
|
||||||
void ReportMemory(MemReporter* memReporter);
|
void ReportMemory(MemReporter* memReporter);
|
||||||
|
|
|
@ -36,7 +36,7 @@ BfConstResolver::BfConstResolver(BfModule* bfModule) : BfExprEvaluator(bfModule)
|
||||||
|
|
||||||
BfTypedValue BfConstResolver::Resolve(BfExpression* expr, BfType* wantType, BfConstResolveFlags flags)
|
BfTypedValue BfConstResolver::Resolve(BfExpression* expr, BfType* wantType, BfConstResolveFlags flags)
|
||||||
{
|
{
|
||||||
mBfEvalExprFlags = (BfEvalExprFlags)(mBfEvalExprFlags | BfEvalExprFlags_ConstEval);
|
mBfEvalExprFlags = (BfEvalExprFlags)(mBfEvalExprFlags | BfEvalExprFlags_Comptime);
|
||||||
|
|
||||||
// Handle the 'int[?] val = .(1, 2, 3)' case
|
// Handle the 'int[?] val = .(1, 2, 3)' case
|
||||||
if ((flags & BfConstResolveFlag_ArrayInitSize) != 0)
|
if ((flags & BfConstResolveFlag_ArrayInitSize) != 0)
|
||||||
|
|
|
@ -737,7 +737,7 @@ void BfContext::HandleChangedTypeDef(BfTypeDef* typeDef, bool isAutoCompleteTemp
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!typeDef->mIsPartial)
|
if ((!typeDef->mIsPartial) && (!isAutoCompleteTempType))
|
||||||
{
|
{
|
||||||
if ((typeDef->mDefState == BfTypeDef::DefState_New) ||
|
if ((typeDef->mDefState == BfTypeDef::DefState_New) ||
|
||||||
(typeDef->mDefState == BfTypeDef::DefState_Deleted) ||
|
(typeDef->mDefState == BfTypeDef::DefState_Deleted) ||
|
||||||
|
@ -1025,6 +1025,11 @@ void BfContext::RebuildType(BfType* type, bool deleteOnDemandTypes, bool rebuild
|
||||||
typeInst->mHasDeclError = false;
|
typeInst->mHasDeclError = false;
|
||||||
delete typeInst->mTypeInfoEx;
|
delete typeInst->mTypeInfoEx;
|
||||||
typeInst->mTypeInfoEx = NULL;
|
typeInst->mTypeInfoEx = NULL;
|
||||||
|
|
||||||
|
typeInst->mTypeDef->ClearEmitted();
|
||||||
|
for (auto localMethod : typeInst->mOwnedLocalMethods)
|
||||||
|
delete localMethod;
|
||||||
|
typeInst->mOwnedLocalMethods.Clear();
|
||||||
|
|
||||||
if (typeInst->IsGenericTypeInstance())
|
if (typeInst->IsGenericTypeInstance())
|
||||||
{
|
{
|
||||||
|
@ -2851,7 +2856,24 @@ void BfContext::Cleanup()
|
||||||
|
|
||||||
for (auto localMethod : mLocalMethodGraveyard)
|
for (auto localMethod : mLocalMethodGraveyard)
|
||||||
{
|
{
|
||||||
if ((localMethod->mMethodInstanceGroup != NULL) && (localMethod->mMethodInstanceGroup->mRefCount > 0))
|
bool inCEMachine = false;
|
||||||
|
if (localMethod->mMethodInstanceGroup != NULL)
|
||||||
|
{
|
||||||
|
if ((localMethod->mMethodInstanceGroup->mDefault != NULL) && (localMethod->mMethodInstanceGroup->mDefault->mInCEMachine))
|
||||||
|
inCEMachine = true;
|
||||||
|
if (localMethod->mMethodInstanceGroup->mMethodSpecializationMap != NULL)
|
||||||
|
{
|
||||||
|
for (auto& kv : *localMethod->mMethodInstanceGroup->mMethodSpecializationMap)
|
||||||
|
if (kv.mValue->mInCEMachine)
|
||||||
|
inCEMachine = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (inCEMachine)
|
||||||
|
{
|
||||||
|
localMethod->mMethodInstanceGroup->mOwner->mOwnedLocalMethods.Add(localMethod);
|
||||||
|
}
|
||||||
|
else if ((localMethod->mMethodInstanceGroup != NULL) && (localMethod->mMethodInstanceGroup->mRefCount > 0))
|
||||||
{
|
{
|
||||||
localMethod->Dispose();
|
localMethod->Dispose();
|
||||||
survivingLocalMethods.push_back(localMethod);
|
survivingLocalMethods.push_back(localMethod);
|
||||||
|
|
|
@ -861,8 +861,10 @@ void BfDefBuilder::ParseAttributes(BfAttributeDirective* attributes, BfMethodDef
|
||||||
methodDef->mIsNoReturn = true;
|
methodDef->mIsNoReturn = true;
|
||||||
else if (typeRefName == "SkipCall")
|
else if (typeRefName == "SkipCall")
|
||||||
methodDef->mIsSkipCall = true;
|
methodDef->mIsSkipCall = true;
|
||||||
else if (typeRefName == "ConstEval")
|
else if (typeRefName == "Comptime")
|
||||||
methodDef->mIsConstEval = true;
|
{
|
||||||
|
methodDef->mHasComptime = true;
|
||||||
|
}
|
||||||
else if (typeRefName == "NoShow")
|
else if (typeRefName == "NoShow")
|
||||||
methodDef->mIsNoShow = true;
|
methodDef->mIsNoShow = true;
|
||||||
else if (typeRefName == "NoDiscard")
|
else if (typeRefName == "NoDiscard")
|
||||||
|
@ -883,6 +885,10 @@ void BfDefBuilder::ParseAttributes(BfAttributeDirective* attributes, BfMethodDef
|
||||||
methodDef->mCommutableKind = BfCommutableKind_Forward;
|
methodDef->mCommutableKind = BfCommutableKind_Forward;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (typeRefName == "OnCompile")
|
||||||
|
{
|
||||||
|
mCurTypeDef->mHasCEOnCompile = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
attributes = attributes->mNextAttribute;
|
attributes = attributes->mNextAttribute;
|
||||||
|
@ -900,7 +906,7 @@ void BfDefBuilder::ParseAttributes(BfAttributeDirective* attributes, BfTypeDef*
|
||||||
if (typeRefName == "AlwaysInclude")
|
if (typeRefName == "AlwaysInclude")
|
||||||
typeDef->mIsAlwaysInclude = true;
|
typeDef->mIsAlwaysInclude = true;
|
||||||
else if (typeRefName == "NoDiscard")
|
else if (typeRefName == "NoDiscard")
|
||||||
typeDef->mIsNoDiscard = true;
|
typeDef->mIsNoDiscard = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
attributes = attributes->mNextAttribute;
|
attributes = attributes->mNextAttribute;
|
||||||
|
@ -927,7 +933,8 @@ void BfDefBuilder::Visit(BfPropertyDeclaration* propertyDeclaration)
|
||||||
Fail("Const properties are not allowed", propertyDeclaration->mConstSpecifier);
|
Fail("Const properties are not allowed", propertyDeclaration->mConstSpecifier);
|
||||||
}
|
}
|
||||||
|
|
||||||
HashNode(*mSignatureHashCtx, propertyDeclaration, propertyDeclaration->mDefinitionBlock);
|
if (mSignatureHashCtx != NULL)
|
||||||
|
HashNode(*mSignatureHashCtx, propertyDeclaration, propertyDeclaration->mDefinitionBlock);
|
||||||
|
|
||||||
BfPropertyDef* propertyDef = new BfPropertyDef();
|
BfPropertyDef* propertyDef = new BfPropertyDef();
|
||||||
mCurTypeDef->mProperties.push_back(propertyDef);
|
mCurTypeDef->mProperties.push_back(propertyDef);
|
||||||
|
@ -956,7 +963,8 @@ void BfDefBuilder::Visit(BfPropertyDeclaration* propertyDeclaration)
|
||||||
if (propertyDeclaration->mDefinitionBlock == NULL) // To differentiate between autocompleting partial property if it transitions to a field
|
if (propertyDeclaration->mDefinitionBlock == NULL) // To differentiate between autocompleting partial property if it transitions to a field
|
||||||
{
|
{
|
||||||
//mCurTypeDef->mSignatureHash = HashString("nullprop", mCurTypeDef->mSignatureHash);
|
//mCurTypeDef->mSignatureHash = HashString("nullprop", mCurTypeDef->mSignatureHash);
|
||||||
mSignatureHashCtx->MixinStr("nullprop");
|
if (mSignatureHashCtx != NULL)
|
||||||
|
mSignatureHashCtx->MixinStr("nullprop");
|
||||||
}
|
}
|
||||||
|
|
||||||
auto indexerDeclaration = BfNodeDynCast<BfIndexerDeclaration>(propertyDeclaration);
|
auto indexerDeclaration = BfNodeDynCast<BfIndexerDeclaration>(propertyDeclaration);
|
||||||
|
@ -985,10 +993,13 @@ void BfDefBuilder::Visit(BfPropertyDeclaration* propertyDeclaration)
|
||||||
|
|
||||||
for (auto methodDeclaration : propertyDeclaration->mMethods)
|
for (auto methodDeclaration : propertyDeclaration->mMethods)
|
||||||
{
|
{
|
||||||
HashNode(*mSignatureHashCtx, methodDeclaration->mAttributes);
|
if (mSignatureHashCtx != NULL)
|
||||||
HashNode(*mSignatureHashCtx, methodDeclaration->mProtectionSpecifier);
|
{
|
||||||
HashNode(*mSignatureHashCtx, methodDeclaration->mNameNode);
|
HashNode(*mSignatureHashCtx, methodDeclaration->mAttributes);
|
||||||
HashNode(*mSignatureHashCtx, methodDeclaration->mMutSpecifier);
|
HashNode(*mSignatureHashCtx, methodDeclaration->mProtectionSpecifier);
|
||||||
|
HashNode(*mSignatureHashCtx, methodDeclaration->mNameNode);
|
||||||
|
HashNode(*mSignatureHashCtx, methodDeclaration->mMutSpecifier);
|
||||||
|
}
|
||||||
|
|
||||||
if (!wantsBody)
|
if (!wantsBody)
|
||||||
continue;
|
continue;
|
||||||
|
@ -1096,7 +1107,7 @@ void BfDefBuilder::Visit(BfPropertyDeclaration* propertyDeclaration)
|
||||||
}
|
}
|
||||||
|
|
||||||
void BfDefBuilder::Visit(BfFieldDeclaration* fieldDeclaration)
|
void BfDefBuilder::Visit(BfFieldDeclaration* fieldDeclaration)
|
||||||
{
|
{
|
||||||
mSystem->CheckLockYield();
|
mSystem->CheckLockYield();
|
||||||
|
|
||||||
int endingAdd = 1;// Add '1' for autocompletion of 'new' initializer
|
int endingAdd = 1;// Add '1' for autocompletion of 'new' initializer
|
||||||
|
@ -1141,7 +1152,8 @@ void BfDefBuilder::Visit(BfFieldDeclaration* fieldDeclaration)
|
||||||
fieldDef->mInitializer = fieldDeclaration->mInitializer;
|
fieldDef->mInitializer = fieldDeclaration->mInitializer;
|
||||||
|
|
||||||
//mCurTypeDef->mSignatureHash = HashNode(fieldDeclaration, mCurTypeDef->mSignatureHash);
|
//mCurTypeDef->mSignatureHash = HashNode(fieldDeclaration, mCurTypeDef->mSignatureHash);
|
||||||
HashNode(*mSignatureHashCtx, fieldDeclaration);
|
if (mSignatureHashCtx != NULL)
|
||||||
|
HashNode(*mSignatureHashCtx, fieldDeclaration);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BfDefBuilder::Visit(BfEnumCaseDeclaration* enumCaseDeclaration)
|
void BfDefBuilder::Visit(BfEnumCaseDeclaration* enumCaseDeclaration)
|
||||||
|
@ -1918,26 +1930,35 @@ void BfDefBuilder::FinishTypeDef(bool wantsToString)
|
||||||
bool hasCtor = false;
|
bool hasCtor = false;
|
||||||
bool needsDefaultCtor = (mCurTypeDef->mTypeCode != BfTypeCode_Interface) && (!mCurTypeDef->mIsStatic) && (!isAlias);
|
bool needsDefaultCtor = (mCurTypeDef->mTypeCode != BfTypeCode_Interface) && (!mCurTypeDef->mIsStatic) && (!isAlias);
|
||||||
bool hasDefaultCtor = false;
|
bool hasDefaultCtor = false;
|
||||||
bool hasStaticCtor = false;
|
BfMethodDef* ctorClear = NULL;
|
||||||
bool hasDtor = false;
|
BfMethodDef* staticCtor = NULL;
|
||||||
bool hasStaticDtor = false;
|
BfMethodDef* dtor = NULL;
|
||||||
bool hasMarkMethod = false;
|
BfMethodDef* staticDtor = NULL;
|
||||||
bool hasStaticMarkMethod = false;
|
BfMethodDef* markMethod = NULL;
|
||||||
bool hasDynamicCastMethod = false;
|
BfMethodDef* staticMarkMethod = NULL;
|
||||||
bool hasToStringMethod = false;
|
BfMethodDef* dynamicCastMethod = NULL;
|
||||||
bool needsEqualsMethod = ((mCurTypeDef->mTypeCode == BfTypeCode_Struct) || (mCurTypeDef->mTypeCode == BfTypeCode_Enum)) && (!mCurTypeDef->mIsStatic);
|
BfMethodDef* toStringMethod = NULL;
|
||||||
bool hasEqualsMethod = false;
|
bool needsEqualsMethod = ((mCurTypeDef->mTypeCode == BfTypeCode_Struct) || (mCurTypeDef->mTypeCode == BfTypeCode_Enum)) && (!mCurTypeDef->mIsStatic);
|
||||||
|
BfMethodDef* equalsMethod = NULL;
|
||||||
|
BfMethodDef* strictEqualsMethod = NULL;
|
||||||
|
|
||||||
bool needsStaticInit = false;
|
bool needsStaticInit = false;
|
||||||
for (int methodIdx = 0; methodIdx < (int)mCurTypeDef->mMethods.size(); methodIdx++)
|
for (int methodIdx = 0; methodIdx < (int)mCurTypeDef->mMethods.size(); methodIdx++)
|
||||||
{
|
{
|
||||||
auto method = mCurTypeDef->mMethods[methodIdx];
|
auto method = mCurTypeDef->mMethods[methodIdx];
|
||||||
|
|
||||||
|
auto _SetMethod = [&](BfMethodDef*& setMethodDef, BfMethodDef* methodDef)
|
||||||
|
{
|
||||||
|
if ((setMethodDef != NULL) && (setMethodDef->mMethodDeclaration == NULL))
|
||||||
|
setMethodDef->mProtection = BfProtection_Hidden;
|
||||||
|
setMethodDef = methodDef;
|
||||||
|
};
|
||||||
|
|
||||||
if (method->mMethodType == BfMethodType_Ctor)
|
if (method->mMethodType == BfMethodType_Ctor)
|
||||||
{
|
{
|
||||||
if (method->mIsStatic)
|
if (method->mIsStatic)
|
||||||
{
|
{
|
||||||
if (hasStaticCtor)
|
if ((staticCtor != NULL) && (staticCtor->mMethodDeclaration != NULL))
|
||||||
{
|
{
|
||||||
Fail("Only one static constructor is allowed", method->mMethodDeclaration);
|
Fail("Only one static constructor is allowed", method->mMethodDeclaration);
|
||||||
method->mIsStatic = false;
|
method->mIsStatic = false;
|
||||||
|
@ -1950,9 +1971,9 @@ void BfDefBuilder::FinishTypeDef(bool wantsToString)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (method->mName == BF_METHODNAME_MARKMEMBERS_STATIC)
|
if (method->mName == BF_METHODNAME_MARKMEMBERS_STATIC)
|
||||||
hasStaticMarkMethod = true;
|
_SetMethod(staticMarkMethod, method);
|
||||||
|
|
||||||
hasStaticCtor = true;
|
_SetMethod(staticCtor, method);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1997,6 +2018,10 @@ void BfDefBuilder::FinishTypeDef(bool wantsToString)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (method->mMethodType == BfMethodType_CtorClear)
|
||||||
|
{
|
||||||
|
ctorClear = method;
|
||||||
|
}
|
||||||
else if (method->mMethodType == BfMethodType_Init)
|
else if (method->mMethodType == BfMethodType_Init)
|
||||||
{
|
{
|
||||||
if (method->mIsStatic)
|
if (method->mIsStatic)
|
||||||
|
@ -2006,22 +2031,22 @@ void BfDefBuilder::FinishTypeDef(bool wantsToString)
|
||||||
{
|
{
|
||||||
if (method->mIsStatic)
|
if (method->mIsStatic)
|
||||||
{
|
{
|
||||||
if (hasStaticDtor)
|
if ((staticDtor != NULL) && (staticDtor->mMethodDeclaration != NULL))
|
||||||
{
|
{
|
||||||
Fail("Only one static constructor is allowed", method->mMethodDeclaration);
|
Fail("Only one static constructor is allowed", method->mMethodDeclaration);
|
||||||
method->mIsStatic = false;
|
method->mIsStatic = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
hasStaticDtor = true;
|
_SetMethod(staticDtor, method);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (hasDtor)
|
if ((dtor != NULL) && (dtor->mMethodDeclaration != NULL))
|
||||||
{
|
{
|
||||||
Fail("Only one destructor is allowed", method->mMethodDeclaration);
|
Fail("Only one destructor is allowed", method->mMethodDeclaration);
|
||||||
method->mIsStatic = false;
|
method->mIsStatic = false;
|
||||||
}
|
}
|
||||||
hasDtor = true;
|
_SetMethod(dtor, method);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (method->mParams.size() != 0)
|
if (method->mParams.size() != 0)
|
||||||
|
@ -2032,16 +2057,16 @@ void BfDefBuilder::FinishTypeDef(bool wantsToString)
|
||||||
if (method->mIsStatic)
|
if (method->mIsStatic)
|
||||||
{
|
{
|
||||||
if (method->mName == BF_METHODNAME_MARKMEMBERS_STATIC)
|
if (method->mName == BF_METHODNAME_MARKMEMBERS_STATIC)
|
||||||
hasStaticMarkMethod = true;
|
_SetMethod(staticMarkMethod, method);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (method->mName == BF_METHODNAME_MARKMEMBERS)
|
if (method->mName == BF_METHODNAME_MARKMEMBERS)
|
||||||
hasMarkMethod = true;
|
_SetMethod(markMethod, method);
|
||||||
if (method->mName == BF_METHODNAME_DYNAMICCAST)
|
if (method->mName == BF_METHODNAME_DYNAMICCAST)
|
||||||
hasDynamicCastMethod = true;
|
_SetMethod(dynamicCastMethod, method);
|
||||||
if (method->mName == BF_METHODNAME_TO_STRING)
|
if (method->mName == BF_METHODNAME_TO_STRING)
|
||||||
hasToStringMethod = true;
|
_SetMethod(toStringMethod, method);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if ((method->mMethodType == BfMethodType_Operator) &&
|
else if ((method->mMethodType == BfMethodType_Operator) &&
|
||||||
|
@ -2056,7 +2081,7 @@ void BfDefBuilder::FinishTypeDef(bool wantsToString)
|
||||||
if ((method->mParams[0]->mTypeRef->ToString() == mCurTypeDef->mName->ToString()) &&
|
if ((method->mParams[0]->mTypeRef->ToString() == mCurTypeDef->mName->ToString()) &&
|
||||||
(method->mParams[1]->mTypeRef->ToString() == mCurTypeDef->mName->ToString()))
|
(method->mParams[1]->mTypeRef->ToString() == mCurTypeDef->mName->ToString()))
|
||||||
{
|
{
|
||||||
hasEqualsMethod = true;
|
_SetMethod(equalsMethod, method);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2121,7 +2146,7 @@ void BfDefBuilder::FinishTypeDef(bool wantsToString)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool needsDynamicCastMethod = !hasDynamicCastMethod;
|
bool needsDynamicCastMethod = dynamicCastMethod == NULL;
|
||||||
|
|
||||||
if (mCurTypeDef->mIsFunction)
|
if (mCurTypeDef->mIsFunction)
|
||||||
{
|
{
|
||||||
|
@ -2131,24 +2156,24 @@ void BfDefBuilder::FinishTypeDef(bool wantsToString)
|
||||||
needsDynamicCastMethod = false;
|
needsDynamicCastMethod = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((mCurTypeDef->mTypeCode == BfTypeCode_Object) && (!mCurTypeDef->mIsStatic))
|
if ((mCurTypeDef->mTypeCode == BfTypeCode_Object) && (!mCurTypeDef->mIsStatic) && (ctorClear == NULL))
|
||||||
{
|
{
|
||||||
auto methodDef = AddMethod(mCurTypeDef, BfMethodType_CtorClear, BfProtection_Private, false, "");
|
auto methodDef = AddMethod(mCurTypeDef, BfMethodType_CtorClear, BfProtection_Private, false, "");
|
||||||
methodDef->mIsMutating = true;
|
methodDef->mIsMutating = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((needsDtor) && (!hasDtor))
|
if ((needsDtor) && (dtor == NULL))
|
||||||
{
|
{
|
||||||
auto methodDef = AddMethod(mCurTypeDef, BfMethodType_Dtor, BfProtection_Public, false, "");
|
auto methodDef = AddMethod(mCurTypeDef, BfMethodType_Dtor, BfProtection_Public, false, "");
|
||||||
BF_ASSERT(mCurTypeDef->mDtorDef == methodDef);
|
BF_ASSERT(mCurTypeDef->mDtorDef == methodDef);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((needsStaticDtor) && (!hasStaticDtor))
|
if ((needsStaticDtor) && (staticDtor == NULL))
|
||||||
{
|
{
|
||||||
auto methodDef = AddMethod(mCurTypeDef, BfMethodType_Dtor, BfProtection_Public, true, "");
|
auto methodDef = AddMethod(mCurTypeDef, BfMethodType_Dtor, BfProtection_Public, true, "");
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((needsStaticInit) && (!hasStaticCtor))
|
if ((needsStaticInit) && (staticCtor == NULL))
|
||||||
{
|
{
|
||||||
auto methodDef = AddMethod(mCurTypeDef, BfMethodType_Ctor, BfProtection_Public, true, "");
|
auto methodDef = AddMethod(mCurTypeDef, BfMethodType_Ctor, BfProtection_Public, true, "");
|
||||||
}
|
}
|
||||||
|
@ -2202,7 +2227,7 @@ void BfDefBuilder::FinishTypeDef(bool wantsToString)
|
||||||
|
|
||||||
if (mCurTypeDef->mTypeCode != BfTypeCode_Interface)
|
if (mCurTypeDef->mTypeCode != BfTypeCode_Interface)
|
||||||
{
|
{
|
||||||
if ((hasStaticField) && (!hasStaticMarkMethod))
|
if ((hasStaticField) && (staticMarkMethod == NULL))
|
||||||
{
|
{
|
||||||
auto methodDef = AddMethod(mCurTypeDef, BfMethodType_Normal, BfProtection_Protected, true, BF_METHODNAME_MARKMEMBERS_STATIC);
|
auto methodDef = AddMethod(mCurTypeDef, BfMethodType_Normal, BfProtection_Protected, true, BF_METHODNAME_MARKMEMBERS_STATIC);
|
||||||
methodDef->mIsNoReflect = true;
|
methodDef->mIsNoReflect = true;
|
||||||
|
@ -2214,7 +2239,7 @@ void BfDefBuilder::FinishTypeDef(bool wantsToString)
|
||||||
methodDef->mIsNoReflect = true;
|
methodDef->mIsNoReflect = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((hasNonStaticField) && (!hasMarkMethod))
|
if ((hasNonStaticField) && (markMethod == NULL))
|
||||||
{
|
{
|
||||||
auto methodDef = AddMethod(mCurTypeDef, BfMethodType_Normal, BfProtection_Protected, false, BF_METHODNAME_MARKMEMBERS);
|
auto methodDef = AddMethod(mCurTypeDef, BfMethodType_Normal, BfProtection_Protected, false, BF_METHODNAME_MARKMEMBERS);
|
||||||
methodDef->mIsVirtual = true;
|
methodDef->mIsVirtual = true;
|
||||||
|
@ -2225,7 +2250,7 @@ void BfDefBuilder::FinishTypeDef(bool wantsToString)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hasToStringMethod)
|
if (toStringMethod != NULL)
|
||||||
wantsToString = false;
|
wantsToString = false;
|
||||||
|
|
||||||
if ((mCurTypeDef->mTypeCode == BfTypeCode_Enum) && (!isPayloadEnum))
|
if ((mCurTypeDef->mTypeCode == BfTypeCode_Enum) && (!isPayloadEnum))
|
||||||
|
@ -2292,7 +2317,7 @@ void BfDefBuilder::FinishTypeDef(bool wantsToString)
|
||||||
mCurTypeDef->mHasOverrideMethods = true;
|
mCurTypeDef->mHasOverrideMethods = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((needsEqualsMethod) && (!hasEqualsMethod))
|
if ((needsEqualsMethod) && (equalsMethod == NULL))
|
||||||
{
|
{
|
||||||
auto methodDef = new BfMethodDef();
|
auto methodDef = new BfMethodDef();
|
||||||
mCurTypeDef->mMethods.push_back(methodDef);
|
mCurTypeDef->mMethods.push_back(methodDef);
|
||||||
|
|
|
@ -799,7 +799,8 @@ void BfMethodMatcher::CompareMethods(BfMethodInstance* prevMethodInstance, BfTyp
|
||||||
SET_BETTER_OR_WORSE((!isUnspecializedParam) && (!paramType->IsVar()),
|
SET_BETTER_OR_WORSE((!isUnspecializedParam) && (!paramType->IsVar()),
|
||||||
(!isPrevUnspecializedParam) && (!prevParamType->IsVar()));
|
(!isPrevUnspecializedParam) && (!prevParamType->IsVar()));
|
||||||
|
|
||||||
if ((!isBetter) && (!isWorse) && (!isUnspecializedParam) && (!isPrevUnspecializedParam))
|
// Why did we have this !isUnspecializedParam check? We need the 'canCast' logic still
|
||||||
|
if ((!isBetter) && (!isWorse) /*&& (!isUnspecializedParam) && (!isPrevUnspecializedParam)*/)
|
||||||
{
|
{
|
||||||
SET_BETTER_OR_WORSE((paramType != NULL) && (!paramType->IsUnspecializedType()),
|
SET_BETTER_OR_WORSE((paramType != NULL) && (!paramType->IsUnspecializedType()),
|
||||||
(prevParamType != NULL) && (!prevParamType->IsUnspecializedType()));
|
(prevParamType != NULL) && (!prevParamType->IsUnspecializedType()));
|
||||||
|
@ -851,7 +852,7 @@ void BfMethodMatcher::CompareMethods(BfMethodInstance* prevMethodInstance, BfTyp
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((!isBetter) & (!isWorse) && (paramsEquivalent))
|
if ((!isBetter) && (!isWorse) && (paramsEquivalent))
|
||||||
{
|
{
|
||||||
if ((origParamType != origPrevParamType) && (paramWasConstExpr) && (!prevParamWasConstExpr))
|
if ((origParamType != origPrevParamType) && (paramWasConstExpr) && (!prevParamWasConstExpr))
|
||||||
betterByConstExprParam = true;
|
betterByConstExprParam = true;
|
||||||
|
@ -2698,21 +2699,21 @@ BfAutoComplete* BfExprEvaluator::GetAutoComplete()
|
||||||
return mModule->mCompiler->mResolvePassData->mAutoComplete;
|
return mModule->mCompiler->mResolvePassData->mAutoComplete;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BfExprEvaluator::IsConstEval()
|
bool BfExprEvaluator::IsComptime()
|
||||||
{
|
{
|
||||||
return (mModule->mIsConstModule) || ((mBfEvalExprFlags & BfEvalExprFlags_ConstEval) != 0);
|
return (mModule->mIsComptimeModule) || ((mBfEvalExprFlags & BfEvalExprFlags_Comptime) != 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BfExprEvaluator::IsConstEvalEntry()
|
bool BfExprEvaluator::IsComptimeEntry()
|
||||||
{
|
{
|
||||||
if (mModule->mIsConstModule)
|
if (mModule->mIsComptimeModule)
|
||||||
return false;
|
return false;
|
||||||
return ((mBfEvalExprFlags & BfEvalExprFlags_ConstEval) != 0);
|
return ((mBfEvalExprFlags & BfEvalExprFlags_Comptime) != 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int BfExprEvaluator::GetStructRetIdx(BfMethodInstance* methodInstance, bool forceStatic)
|
int BfExprEvaluator::GetStructRetIdx(BfMethodInstance* methodInstance, bool forceStatic)
|
||||||
{
|
{
|
||||||
if (IsConstEval())
|
if (IsComptime())
|
||||||
return -1;
|
return -1;
|
||||||
return methodInstance->GetStructRetIdx(forceStatic);
|
return methodInstance->GetStructRetIdx(forceStatic);
|
||||||
}
|
}
|
||||||
|
@ -3333,7 +3334,7 @@ void BfExprEvaluator::Visit(BfLiteralExpression* literalExpr)
|
||||||
|
|
||||||
void BfExprEvaluator::Visit(BfStringInterpolationExpression* stringInterpolationExpression)
|
void BfExprEvaluator::Visit(BfStringInterpolationExpression* stringInterpolationExpression)
|
||||||
{
|
{
|
||||||
if (IsConstEvalEntry())
|
if (IsComptimeEntry())
|
||||||
{
|
{
|
||||||
mModule->Fail("Const evaluation of string interpolation not allowed", stringInterpolationExpression);
|
mModule->Fail("Const evaluation of string interpolation not allowed", stringInterpolationExpression);
|
||||||
}
|
}
|
||||||
|
@ -5075,43 +5076,57 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, BfMethodInstance*
|
||||||
|
|
||||||
if ((mModule->mCompiler->mResolvePassData != NULL) && (mModule->mCompiler->mResolvePassData->mAutoComplete != NULL))
|
if ((mModule->mCompiler->mResolvePassData != NULL) && (mModule->mCompiler->mResolvePassData->mAutoComplete != NULL))
|
||||||
{
|
{
|
||||||
// In an autocomplete pass we may have stale method references that need to be resolved
|
bool wantQuickEval = true;
|
||||||
// in the full classify pass, and in the full classify pass while just refreshing internals, we
|
|
||||||
// may have NULL funcs temporarily. We simply skip generating the method call here.
|
if (IsComptime())
|
||||||
if (methodInstance->mVirtualTableIdx == -1)
|
{
|
||||||
{
|
auto autoComplete = mModule->mCompiler->mResolvePassData->mAutoComplete;
|
||||||
if (methodInstance->GetOwner()->IsInterface())
|
wantQuickEval =
|
||||||
{
|
((autoComplete->mResolveType != BfResolveType_Autocomplete) &&
|
||||||
// We're attempting to directly invoke a non-virtual interface method, if we're return an interface then
|
(autoComplete->mResolveType != BfResolveType_Autocomplete_HighPri) &&
|
||||||
// it is a concrete interface
|
(autoComplete->mResolveType != BfResolveType_GetResultString));
|
||||||
if (returnType->IsInterface())
|
|
||||||
returnType = mModule->CreateConcreteInterfaceType(returnType->ToTypeInstance());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((mBfEvalExprFlags & BfEvalExprFlags_ConstEval) != 0)
|
if (wantQuickEval)
|
||||||
{
|
{
|
||||||
if (methodInstance->mReturnType->IsInstanceOf(mModule->mCompiler->mSpanTypeDef))
|
// In an autocomplete pass we may have stale method references that need to be resolved
|
||||||
|
// in the full classify pass, and in the full classify pass while just refreshing internals, we
|
||||||
|
// may have NULL funcs temporarily. We simply skip generating the method call here.
|
||||||
|
if (methodInstance->mVirtualTableIdx == -1)
|
||||||
{
|
{
|
||||||
if ((mExpectingType != NULL) && (mExpectingType->IsSizedArray()))
|
if (methodInstance->GetOwner()->IsInterface())
|
||||||
{
|
{
|
||||||
return BfTypedValue(mModule->mBfIRBuilder->GetUndefConstValue(mModule->mBfIRBuilder->MapType(mExpectingType)), mExpectingType);
|
// We're attempting to directly invoke a non-virtual interface method, if we're return an interface then
|
||||||
|
// it is a concrete interface
|
||||||
|
if (returnType->IsInterface())
|
||||||
|
returnType = mModule->CreateConcreteInterfaceType(returnType->ToTypeInstance());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
auto returnType = methodInstance->mReturnType;
|
|
||||||
if ((returnType->IsVar()) && (mExpectingType != NULL))
|
|
||||||
returnType = mExpectingType;
|
|
||||||
if (methodInstance->mReturnType->IsValuelessType())
|
|
||||||
return BfTypedValue(mModule->mBfIRBuilder->GetFakeVal(), returnType);
|
|
||||||
return BfTypedValue(mModule->mBfIRBuilder->GetUndefConstValue(mModule->mBfIRBuilder->MapType(returnType)), returnType);
|
|
||||||
}
|
|
||||||
|
|
||||||
BfTypedValue result;
|
if ((mBfEvalExprFlags & BfEvalExprFlags_Comptime) != 0)
|
||||||
if (sret != NULL)
|
{
|
||||||
result = *sret;
|
if (methodInstance->mReturnType->IsInstanceOf(mModule->mCompiler->mSpanTypeDef))
|
||||||
else
|
{
|
||||||
result = _GetDefaultReturnValue();
|
if ((mExpectingType != NULL) && (mExpectingType->IsSizedArray()))
|
||||||
return result;
|
{
|
||||||
|
return BfTypedValue(mModule->mBfIRBuilder->GetUndefConstValue(mModule->mBfIRBuilder->MapType(mExpectingType)), mExpectingType);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
auto returnType = methodInstance->mReturnType;
|
||||||
|
if ((returnType->IsVar()) && (mExpectingType != NULL))
|
||||||
|
returnType = mExpectingType;
|
||||||
|
if (methodInstance->mReturnType->IsValuelessType())
|
||||||
|
return BfTypedValue(mModule->mBfIRBuilder->GetFakeVal(), returnType);
|
||||||
|
return BfTypedValue(mModule->mBfIRBuilder->GetUndefConstValue(mModule->mBfIRBuilder->MapType(returnType)), returnType);
|
||||||
|
}
|
||||||
|
|
||||||
|
BfTypedValue result;
|
||||||
|
if (sret != NULL)
|
||||||
|
result = *sret;
|
||||||
|
else
|
||||||
|
result = _GetDefaultReturnValue();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool forceBind = false;
|
bool forceBind = false;
|
||||||
|
@ -5120,7 +5135,7 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, BfMethodInstance*
|
||||||
{
|
{
|
||||||
bool doConstReturn = false;
|
bool doConstReturn = false;
|
||||||
|
|
||||||
if ((mBfEvalExprFlags & BfEvalExprFlags_ConstEval) != 0)
|
if ((mBfEvalExprFlags & BfEvalExprFlags_Comptime) != 0)
|
||||||
{
|
{
|
||||||
if (mFunctionBindResult != NULL)
|
if (mFunctionBindResult != NULL)
|
||||||
{
|
{
|
||||||
|
@ -5134,6 +5149,11 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, BfMethodInstance*
|
||||||
{
|
{
|
||||||
doConstReturn = true;
|
doConstReturn = true;
|
||||||
}
|
}
|
||||||
|
else if (((methodInstance->mComptimeFlags & BfComptimeFlag_OnlyFromComptime) != 0) && (!mModule->mIsComptimeModule))
|
||||||
|
{
|
||||||
|
// This either generated an error already or this is just the non-const type check pass for a comptime-only method
|
||||||
|
doConstReturn = true;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
CeEvalFlags evalFlags = CeEvalFlags_None;
|
CeEvalFlags evalFlags = CeEvalFlags_None;
|
||||||
|
@ -5143,9 +5163,20 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, BfMethodInstance*
|
||||||
BF_ASSERT(!constRet.mType->IsVar());
|
BF_ASSERT(!constRet.mType->IsVar());
|
||||||
return constRet;
|
return constRet;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (mModule->mCompiler->mFastFinish)
|
||||||
|
{
|
||||||
|
if ((mModule->mCurMethodInstance == NULL) || (!mModule->mCurMethodInstance->mIsAutocompleteMethod))
|
||||||
|
{
|
||||||
|
// We didn't properly resolve this so queue for a rebuild later
|
||||||
|
mModule->DeferRebuildType(mModule->mCurTypeInstance);
|
||||||
|
}
|
||||||
|
|
||||||
|
doConstReturn = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (mModule->mIsConstModule)
|
else if (mModule->mIsComptimeModule)
|
||||||
{
|
{
|
||||||
if (methodInstance->mIsUnspecialized)
|
if (methodInstance->mIsUnspecialized)
|
||||||
{
|
{
|
||||||
|
@ -5206,7 +5237,7 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, BfMethodInstance*
|
||||||
|
|
||||||
if (methodInstance->mMethodInstanceGroup->mOwner->IsInterface())
|
if (methodInstance->mMethodInstanceGroup->mOwner->IsInterface())
|
||||||
{
|
{
|
||||||
if (mModule->mIsConstModule)
|
if (mModule->mIsComptimeModule)
|
||||||
{
|
{
|
||||||
funcCallInst = mModule->mBfIRBuilder->ConstEval_GetInterfaceFunc(irArgs[0], methodInstance->mMethodInstanceGroup->mOwner->mTypeId, methodInstance->mMethodDef->mIdx, funcPtrType1);
|
funcCallInst = mModule->mBfIRBuilder->ConstEval_GetInterfaceFunc(irArgs[0], methodInstance->mMethodInstanceGroup->mOwner->mTypeId, methodInstance->mMethodDef->mIdx, funcPtrType1);
|
||||||
}
|
}
|
||||||
|
@ -5226,7 +5257,7 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, BfMethodInstance*
|
||||||
funcCallInst = mModule->mBfIRBuilder->CreateLoad(funcPtr);
|
funcCallInst = mModule->mBfIRBuilder->CreateLoad(funcPtr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (mModule->mIsConstModule)
|
else if (mModule->mIsComptimeModule)
|
||||||
{
|
{
|
||||||
funcCallInst = mModule->mBfIRBuilder->ConstEval_GetVirtualFunc(irArgs[0], methodInstance->mVirtualTableIdx, funcPtrType1);
|
funcCallInst = mModule->mBfIRBuilder->ConstEval_GetVirtualFunc(irArgs[0], methodInstance->mVirtualTableIdx, funcPtrType1);
|
||||||
}
|
}
|
||||||
|
@ -5323,7 +5354,7 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, BfMethodInstance*
|
||||||
if (irArgs.size() != 0)
|
if (irArgs.size() != 0)
|
||||||
{
|
{
|
||||||
auto targetType = methodInstance->mMethodInstanceGroup->mOwner;
|
auto targetType = methodInstance->mMethodInstanceGroup->mOwner;
|
||||||
if ((targetType->IsValueType()) && (targetType->IsSplattable()) && (!methodDef->HasNoThisSplat()) && (!IsConstEval()))
|
if ((targetType->IsValueType()) && (targetType->IsSplattable()) && (!methodDef->HasNoThisSplat()) && (!IsComptime()))
|
||||||
mFunctionBindResult->mTarget = BfTypedValue(irArgs[0], targetType, BfTypedValueKind_SplatHead);
|
mFunctionBindResult->mTarget = BfTypedValue(irArgs[0], targetType, BfTypedValueKind_SplatHead);
|
||||||
else
|
else
|
||||||
mFunctionBindResult->mTarget = BfTypedValue(irArgs[0], targetType, targetType->IsComposite() ? BfTypedValueKind_Addr : BfTypedValueKind_Value);
|
mFunctionBindResult->mTarget = BfTypedValue(irArgs[0], targetType, targetType->IsComposite() ? BfTypedValueKind_Addr : BfTypedValueKind_Value);
|
||||||
|
@ -5484,7 +5515,7 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, BfMethodInstance*
|
||||||
mModule->PopulateType(paramType, BfPopulateType_Data);
|
mModule->PopulateType(paramType, BfPopulateType_Data);
|
||||||
|
|
||||||
auto typeInst = paramType->ToTypeInstance();
|
auto typeInst = paramType->ToTypeInstance();
|
||||||
if ((typeInst != NULL) && (typeInst->mIsCRepr) && (typeInst->IsSplattable()) && (!IsConstEval()))
|
if ((typeInst != NULL) && (typeInst->mIsCRepr) && (typeInst->IsSplattable()) && (!IsComptime()))
|
||||||
{
|
{
|
||||||
// We're splatting
|
// We're splatting
|
||||||
}
|
}
|
||||||
|
@ -5527,7 +5558,7 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, BfMethodInstance*
|
||||||
doingThis = false;
|
doingThis = false;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
bool isSplatted = methodInstance->GetParamIsSplat(thisIdx) && (!IsConstEval()); // (resolvedTypeRef->IsSplattable()) && (!methodDef->mIsMutating);
|
bool isSplatted = methodInstance->GetParamIsSplat(thisIdx) && (!IsComptime()); // (resolvedTypeRef->IsSplattable()) && (!methodDef->mIsMutating);
|
||||||
if (isSplatted)
|
if (isSplatted)
|
||||||
{
|
{
|
||||||
BfTypeUtils::SplatIterate(_HandleParamType, paramType);
|
BfTypeUtils::SplatIterate(_HandleParamType, paramType);
|
||||||
|
@ -5561,7 +5592,7 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, BfMethodInstance*
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((methodInstance->GetParamIsSplat(paramIdx)) && (!IsConstEval()))
|
if ((methodInstance->GetParamIsSplat(paramIdx)) && (!IsComptime()))
|
||||||
{
|
{
|
||||||
BfTypeUtils::SplatIterate(_HandleParamType, paramType);
|
BfTypeUtils::SplatIterate(_HandleParamType, paramType);
|
||||||
paramIdx++;
|
paramIdx++;
|
||||||
|
@ -5614,7 +5645,7 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, BfMethodInstance*
|
||||||
{
|
{
|
||||||
BfTypeCode loweredRetType = BfTypeCode_None;
|
BfTypeCode loweredRetType = BfTypeCode_None;
|
||||||
BfTypeCode loweredRetType2 = BfTypeCode_None;
|
BfTypeCode loweredRetType2 = BfTypeCode_None;
|
||||||
if ((!IsConstEval()) && (methodInstance->GetLoweredReturnType(&loweredRetType, &loweredRetType2)))
|
if ((!IsComptime()) && (methodInstance->GetLoweredReturnType(&loweredRetType, &loweredRetType2)))
|
||||||
{
|
{
|
||||||
auto retVal = mModule->CreateAlloca(methodInstance->mReturnType);
|
auto retVal = mModule->CreateAlloca(methodInstance->mReturnType);
|
||||||
BfIRType loweredIRType = mModule->GetIRLoweredType(loweredRetType, loweredRetType2);
|
BfIRType loweredIRType = mModule->GetIRLoweredType(loweredRetType, loweredRetType2);
|
||||||
|
@ -5780,7 +5811,7 @@ void BfExprEvaluator::PushArg(BfTypedValue argVal, SizedArrayImpl<BfIRValue>& ir
|
||||||
return;
|
return;
|
||||||
|
|
||||||
bool wantSplat = false;
|
bool wantSplat = false;
|
||||||
if ((argVal.mType->IsSplattable()) && (!disableSplat) && (!IsConstEval()))
|
if ((argVal.mType->IsSplattable()) && (!disableSplat) && (!IsComptime()))
|
||||||
{
|
{
|
||||||
disableLowering = true;
|
disableLowering = true;
|
||||||
auto argTypeInstance = argVal.mType->ToTypeInstance();
|
auto argTypeInstance = argVal.mType->ToTypeInstance();
|
||||||
|
@ -5801,7 +5832,7 @@ void BfExprEvaluator::PushArg(BfTypedValue argVal, SizedArrayImpl<BfIRValue>& ir
|
||||||
{
|
{
|
||||||
if (argVal.mType->IsComposite())
|
if (argVal.mType->IsComposite())
|
||||||
{
|
{
|
||||||
if ((mBfEvalExprFlags & BfEvalExprFlags_ConstEval) != 0)
|
if ((mBfEvalExprFlags & BfEvalExprFlags_Comptime) != 0)
|
||||||
{
|
{
|
||||||
// Const eval entry - we want any incoming consts as they are
|
// Const eval entry - we want any incoming consts as they are
|
||||||
}
|
}
|
||||||
|
@ -5812,7 +5843,7 @@ void BfExprEvaluator::PushArg(BfTypedValue argVal, SizedArrayImpl<BfIRValue>& ir
|
||||||
else
|
else
|
||||||
argVal = mModule->MakeAddressable(argVal);
|
argVal = mModule->MakeAddressable(argVal);
|
||||||
|
|
||||||
if ((!IsConstEval()) && (!disableLowering) && (!isIntrinsic))
|
if ((!IsComptime()) && (!disableLowering) && (!isIntrinsic))
|
||||||
{
|
{
|
||||||
BfTypeCode loweredTypeCode = BfTypeCode_None;
|
BfTypeCode loweredTypeCode = BfTypeCode_None;
|
||||||
BfTypeCode loweredTypeCode2 = BfTypeCode_None;
|
BfTypeCode loweredTypeCode2 = BfTypeCode_None;
|
||||||
|
@ -5906,7 +5937,7 @@ void BfExprEvaluator::PushThis(BfAstNode* targetSrc, BfTypedValue argVal, BfMeth
|
||||||
auto owner = methodInstance->GetOwner();
|
auto owner = methodInstance->GetOwner();
|
||||||
|
|
||||||
bool allowThisSplatting;
|
bool allowThisSplatting;
|
||||||
if (mModule->mIsConstModule)
|
if (mModule->mIsComptimeModule)
|
||||||
allowThisSplatting = owner->IsTypedPrimitive() || owner->IsValuelessType();
|
allowThisSplatting = owner->IsTypedPrimitive() || owner->IsValuelessType();
|
||||||
else
|
else
|
||||||
allowThisSplatting = methodInstance->AllowsSplatting(-1);
|
allowThisSplatting = methodInstance->AllowsSplatting(-1);
|
||||||
|
@ -6210,7 +6241,7 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, const BfTypedValu
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
wantsSplat = methodInstance->GetParamIsSplat(paramIdx) && (!IsConstEval());
|
wantsSplat = methodInstance->GetParamIsSplat(paramIdx) && (!IsComptime());
|
||||||
if (methodInstance->IsImplicitCapture(paramIdx))
|
if (methodInstance->IsImplicitCapture(paramIdx))
|
||||||
{
|
{
|
||||||
auto paramType = methodInstance->GetParamType(paramIdx);
|
auto paramType = methodInstance->GetParamType(paramIdx);
|
||||||
|
@ -6275,7 +6306,7 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, const BfTypedValu
|
||||||
if (methodDef->mMethodType == BfMethodType_Extension)
|
if (methodDef->mMethodType == BfMethodType_Extension)
|
||||||
numElements++;
|
numElements++;
|
||||||
|
|
||||||
if (IsConstEvalEntry())
|
if (IsComptimeEntry())
|
||||||
{
|
{
|
||||||
if ((wantType->IsArray()) || (wantType->IsInstanceOf(mModule->mCompiler->mSpanTypeDef)))
|
if ((wantType->IsArray()) || (wantType->IsInstanceOf(mModule->mCompiler->mSpanTypeDef)))
|
||||||
{
|
{
|
||||||
|
@ -6694,7 +6725,7 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, const BfTypedValu
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// We need to make a temp and get the addr of that
|
// We need to make a temp and get the addr of that
|
||||||
if ((!wantsSplat) && (!argValue.IsValuelessType()) && (!argValue.IsAddr()) && (!IsConstEvalEntry()))
|
if ((!wantsSplat) && (!argValue.IsValuelessType()) && (!argValue.IsAddr()) && (!IsComptimeEntry()))
|
||||||
{
|
{
|
||||||
argValue = mModule->MakeAddressable(argValue);
|
argValue = mModule->MakeAddressable(argValue);
|
||||||
}
|
}
|
||||||
|
@ -6714,7 +6745,7 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, const BfTypedValu
|
||||||
{
|
{
|
||||||
if (argValue)
|
if (argValue)
|
||||||
{
|
{
|
||||||
if (IsConstEvalEntry())
|
if (IsComptimeEntry())
|
||||||
{
|
{
|
||||||
auto constant = mModule->mBfIRBuilder->GetConstant(expandedParamsArray.mValue);
|
auto constant = mModule->mBfIRBuilder->GetConstant(expandedParamsArray.mValue);
|
||||||
BF_ASSERT(constant->mConstType == BfConstType_Agg);
|
BF_ASSERT(constant->mConstType == BfConstType_Agg);
|
||||||
|
@ -8588,15 +8619,28 @@ BfTypedValue BfExprEvaluator::MatchMethod(BfAstNode* targetSrc, BfMethodBoundExp
|
||||||
//
|
//
|
||||||
{
|
{
|
||||||
SetAndRestoreValue<BfEvalExprFlags> prevEvalExprFlag(mBfEvalExprFlags);
|
SetAndRestoreValue<BfEvalExprFlags> prevEvalExprFlag(mBfEvalExprFlags);
|
||||||
|
|
||||||
if ((mModule->mAttributeState != NULL) && (mModule->mAttributeState->mCustomAttributes != NULL) && (mModule->mAttributeState->mCustomAttributes->Contains(mModule->mCompiler->mConstEvalAttributeTypeDef)))
|
if ((mModule->mAttributeState != NULL) && (mModule->mAttributeState->mCustomAttributes != NULL) && (mModule->mAttributeState->mCustomAttributes->Contains(mModule->mCompiler->mConstEvalAttributeTypeDef)))
|
||||||
{
|
{
|
||||||
mModule->mAttributeState->mUsed = true;
|
mModule->mAttributeState->mUsed = true;
|
||||||
mBfEvalExprFlags = (BfEvalExprFlags)(mBfEvalExprFlags | BfEvalExprFlags_ConstEval);
|
mBfEvalExprFlags = (BfEvalExprFlags)(mBfEvalExprFlags | BfEvalExprFlags_Comptime);
|
||||||
}
|
}
|
||||||
else if (moduleMethodInstance.mMethodInstance->mMethodDef->mIsConstEval)
|
else if ((moduleMethodInstance.mMethodInstance->mComptimeFlags & BfComptimeFlag_ConstEval) != 0)
|
||||||
{
|
{
|
||||||
mBfEvalExprFlags = (BfEvalExprFlags)(mBfEvalExprFlags | BfEvalExprFlags_ConstEval);
|
mBfEvalExprFlags = (BfEvalExprFlags)(mBfEvalExprFlags | BfEvalExprFlags_Comptime);
|
||||||
|
}
|
||||||
|
else if (((moduleMethodInstance.mMethodInstance->mComptimeFlags & BfComptimeFlag_Comptime) != 0) && (!mModule->mIsComptimeModule))
|
||||||
|
{
|
||||||
|
mBfEvalExprFlags = (BfEvalExprFlags)(mBfEvalExprFlags | BfEvalExprFlags_Comptime);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (((moduleMethodInstance.mMethodInstance->mComptimeFlags & BfComptimeFlag_OnlyFromComptime) != 0) &&
|
||||||
|
((mBfEvalExprFlags & BfEvalExprFlags_Comptime) != 0) &&
|
||||||
|
(mModule->mCurMethodInstance->mComptimeFlags == BfComptimeFlag_None) &&
|
||||||
|
(!mModule->mIsComptimeModule))
|
||||||
|
{
|
||||||
|
mBfEvalExprFlags = (BfEvalExprFlags)(mBfEvalExprFlags &~ BfEvalExprFlags_Comptime);
|
||||||
|
mModule->Fail(StrFormat("Method '%s' can only be invoked at comptime. Consider adding [Comptime] to the current method.", mModule->MethodToString(moduleMethodInstance.mMethodInstance).c_str()), targetSrc);
|
||||||
}
|
}
|
||||||
|
|
||||||
result = CreateCall(targetSrc, callTarget, origTarget, methodDef, moduleMethodInstance, bypassVirtual, argValues.mResolvedArgs, &argCascade, skipThis);
|
result = CreateCall(targetSrc, callTarget, origTarget, methodDef, moduleMethodInstance, bypassVirtual, argValues.mResolvedArgs, &argCascade, skipThis);
|
||||||
|
@ -11314,7 +11358,7 @@ void BfExprEvaluator::Visit(BfDelegateBindExpression* delegateBindExpr)
|
||||||
for (int paramIdx = 0; paramIdx < methodInstance->GetParamCount(); paramIdx++)
|
for (int paramIdx = 0; paramIdx < methodInstance->GetParamCount(); paramIdx++)
|
||||||
{
|
{
|
||||||
auto paramType = methodInstance->GetParamType(paramIdx);
|
auto paramType = methodInstance->GetParamType(paramIdx);
|
||||||
if ((paramType->IsSplattable()) && (!IsConstEval()))
|
if ((paramType->IsSplattable()) && (!IsComptime()))
|
||||||
{
|
{
|
||||||
BfTypeUtils::SplatIterate([&](BfType* checkType) { irArgs.push_back(mModule->mBfIRBuilder->GetArgument(argIdx++)); }, paramType);
|
BfTypeUtils::SplatIterate([&](BfType* checkType) { irArgs.push_back(mModule->mBfIRBuilder->GetArgument(argIdx++)); }, paramType);
|
||||||
}
|
}
|
||||||
|
@ -13180,7 +13224,7 @@ void BfExprEvaluator::CreateObject(BfObjectCreateExpression* objCreateExpr, BfAs
|
||||||
|
|
||||||
// Actually leave it alone?
|
// Actually leave it alone?
|
||||||
if ((isUninit) &&
|
if ((isUninit) &&
|
||||||
((mModule->IsOptimized()) || (mModule->mIsConstModule) || (mModule->mBfIRBuilder->mIgnoreWrites)))
|
((mModule->IsOptimized()) || (mModule->mIsComptimeModule) || (mModule->mBfIRBuilder->mIgnoreWrites)))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
bool doClear = true;
|
bool doClear = true;
|
||||||
|
@ -13564,7 +13608,7 @@ void BfExprEvaluator::CreateObject(BfObjectCreateExpression* objCreateExpr, BfAs
|
||||||
{
|
{
|
||||||
allocValue = mModule->AllocFromType(resolvedTypeRef, allocTarget, appendSizeValue, BfIRValue(), 0, BfAllocFlags_None, allocAlign);
|
allocValue = mModule->AllocFromType(resolvedTypeRef, allocTarget, appendSizeValue, BfIRValue(), 0, BfAllocFlags_None, allocAlign);
|
||||||
}
|
}
|
||||||
if (((mBfEvalExprFlags & BfEvalExprFlags_ConstEval) != 0) && (mModule->mCompiler->mCEMachine != NULL))
|
if (((mBfEvalExprFlags & BfEvalExprFlags_Comptime) != 0) && (mModule->mCompiler->mCEMachine != NULL))
|
||||||
{
|
{
|
||||||
mModule->mCompiler->mCEMachine->SetAppendAllocInfo(mModule, allocValue, appendSizeValue);
|
mModule->mCompiler->mCEMachine->SetAppendAllocInfo(mModule, allocValue, appendSizeValue);
|
||||||
}
|
}
|
||||||
|
@ -13615,7 +13659,7 @@ void BfExprEvaluator::CreateObject(BfObjectCreateExpression* objCreateExpr, BfAs
|
||||||
{
|
{
|
||||||
mModule->AssertErrorState();
|
mModule->AssertErrorState();
|
||||||
}
|
}
|
||||||
else if ((mBfEvalExprFlags & BfEvalExprFlags_ConstEval) == 0)
|
else if ((mBfEvalExprFlags & BfEvalExprFlags_Comptime) == 0)
|
||||||
{
|
{
|
||||||
SizedArray<BfIRValue, 1> irArgs;
|
SizedArray<BfIRValue, 1> irArgs;
|
||||||
irArgs.push_back(mResult.mValue);
|
irArgs.push_back(mResult.mValue);
|
||||||
|
@ -13623,7 +13667,7 @@ void BfExprEvaluator::CreateObject(BfObjectCreateExpression* objCreateExpr, BfAs
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((!mModule->mIsConstModule) && (isStackAlloc) && (mModule->mCompiler->mOptions.mEnableRealtimeLeakCheck))
|
if ((!mModule->mIsComptimeModule) && (isStackAlloc) && (mModule->mCompiler->mOptions.mEnableRealtimeLeakCheck))
|
||||||
{
|
{
|
||||||
BfMethodInstance* markMethod = mModule->GetRawMethodByName(mModule->mContext->mBfObjectType, "GCMarkMembers");
|
BfMethodInstance* markMethod = mModule->GetRawMethodByName(mModule->mContext->mBfObjectType, "GCMarkMembers");
|
||||||
BF_ASSERT(markMethod != NULL);
|
BF_ASSERT(markMethod != NULL);
|
||||||
|
@ -13693,7 +13737,7 @@ void BfExprEvaluator::CreateObject(BfObjectCreateExpression* objCreateExpr, BfAs
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (((mBfEvalExprFlags & BfEvalExprFlags_ConstEval) != 0) && (mModule->mCompiler->mCEMachine != NULL))
|
if (((mBfEvalExprFlags & BfEvalExprFlags_Comptime) != 0) && (mModule->mCompiler->mCEMachine != NULL))
|
||||||
{
|
{
|
||||||
mModule->mCompiler->mCEMachine->ClearAppendAllocInfo();
|
mModule->mCompiler->mCEMachine->ClearAppendAllocInfo();
|
||||||
}
|
}
|
||||||
|
@ -13887,7 +13931,7 @@ BfTypedValue BfExprEvaluator::MakeCallableTarget(BfAstNode* targetSrc, BfTypedVa
|
||||||
|
|
||||||
if ((target.mType->IsStruct()) && (!target.IsAddr()))
|
if ((target.mType->IsStruct()) && (!target.IsAddr()))
|
||||||
{
|
{
|
||||||
if (IsConstEvalEntry())
|
if (IsComptimeEntry())
|
||||||
return target;
|
return target;
|
||||||
target = mModule->MakeAddressable(target);
|
target = mModule->MakeAddressable(target);
|
||||||
}
|
}
|
||||||
|
@ -13923,7 +13967,7 @@ BfTypedValue BfExprEvaluator::MakeCallableTarget(BfAstNode* targetSrc, BfTypedVa
|
||||||
auto ptrType = mModule->CreatePointerType(primStructType);
|
auto ptrType = mModule->CreatePointerType(primStructType);
|
||||||
target = BfTypedValue(mModule->mBfIRBuilder->CreateBitCast(target.mValue, mModule->mBfIRBuilder->MapType(ptrType)), primStructType, true);
|
target = BfTypedValue(mModule->mBfIRBuilder->CreateBitCast(target.mValue, mModule->mBfIRBuilder->MapType(ptrType)), primStructType, true);
|
||||||
}
|
}
|
||||||
else if ((primStructType->IsSplattable()) && (target.IsSplat()) && (!IsConstEval()))
|
else if ((primStructType->IsSplattable()) && (target.IsSplat()) && (!IsComptime()))
|
||||||
{
|
{
|
||||||
target.mType = primStructType;
|
target.mType = primStructType;
|
||||||
target.mKind = BfTypedValueKind_SplatHead;
|
target.mKind = BfTypedValueKind_SplatHead;
|
||||||
|
@ -15739,7 +15783,7 @@ void BfExprEvaluator::DoInvocation(BfAstNode* target, BfMethodBoundExpression* m
|
||||||
|
|
||||||
int methodCount = 0;
|
int methodCount = 0;
|
||||||
bool mayBeSkipCall = false;
|
bool mayBeSkipCall = false;
|
||||||
bool mayBeConstEvalCall = false;
|
bool mayBeComptimeCall = false;
|
||||||
if (thisValue.mType != NULL)
|
if (thisValue.mType != NULL)
|
||||||
{
|
{
|
||||||
if (thisValue.mType->IsAllocType())
|
if (thisValue.mType->IsAllocType())
|
||||||
|
@ -15757,8 +15801,8 @@ void BfExprEvaluator::DoInvocation(BfAstNode* target, BfMethodBoundExpression* m
|
||||||
{
|
{
|
||||||
if (methodDef->mIsSkipCall)
|
if (methodDef->mIsSkipCall)
|
||||||
mayBeSkipCall = true;
|
mayBeSkipCall = true;
|
||||||
if (methodDef->mIsConstEval)
|
if (methodDef->mHasComptime)
|
||||||
mayBeConstEvalCall = true;
|
mayBeComptimeCall = true;
|
||||||
methodDef = methodDef->mNextWithSameName;
|
methodDef = methodDef->mNextWithSameName;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -15784,7 +15828,7 @@ void BfExprEvaluator::DoInvocation(BfAstNode* target, BfMethodBoundExpression* m
|
||||||
|
|
||||||
BfResolveArgsFlags resolveArgsFlags = (BfResolveArgsFlags)(BfResolveArgsFlag_DeferFixits | BfResolveArgsFlag_AllowUnresolvedTypes);
|
BfResolveArgsFlags resolveArgsFlags = (BfResolveArgsFlags)(BfResolveArgsFlag_DeferFixits | BfResolveArgsFlag_AllowUnresolvedTypes);
|
||||||
resolveArgsFlags = (BfResolveArgsFlags)(resolveArgsFlags | BfResolveArgsFlag_DeferParamEval);
|
resolveArgsFlags = (BfResolveArgsFlags)(resolveArgsFlags | BfResolveArgsFlag_DeferParamEval);
|
||||||
if ((mayBeSkipCall) || (mayBeConstEvalCall))
|
if ((mayBeSkipCall) || (mayBeComptimeCall))
|
||||||
resolveArgsFlags = (BfResolveArgsFlags)(resolveArgsFlags | BfResolveArgsFlag_DeferParamValues);
|
resolveArgsFlags = (BfResolveArgsFlags)(resolveArgsFlags | BfResolveArgsFlag_DeferParamValues);
|
||||||
|
|
||||||
static int sCallIdx = 0;
|
static int sCallIdx = 0;
|
||||||
|
@ -15810,7 +15854,7 @@ void BfExprEvaluator::DoInvocation(BfAstNode* target, BfMethodBoundExpression* m
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((isCascade) && (cascadeOperatorToken != NULL) && ((mBfEvalExprFlags & BfEvalExprFlags_ConstEval) != 0))
|
if ((isCascade) && (cascadeOperatorToken != NULL) && ((mBfEvalExprFlags & BfEvalExprFlags_Comptime) != 0))
|
||||||
mModule->Fail("Cascade operator cannot be used in const evaluation", cascadeOperatorToken);
|
mModule->Fail("Cascade operator cannot be used in const evaluation", cascadeOperatorToken);
|
||||||
|
|
||||||
SetAndRestoreValue<bool> prevUsedAsStatement(mUsedAsStatement, mUsedAsStatement || isCascade);
|
SetAndRestoreValue<bool> prevUsedAsStatement(mUsedAsStatement, mUsedAsStatement || isCascade);
|
||||||
|
@ -16061,7 +16105,7 @@ BfModuleMethodInstance BfExprEvaluator::GetPropertyMethodInstance(BfMethodDef* m
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((mOrigPropTarget) && (mOrigPropTarget.mType != mPropTarget.mType) &&
|
if ((mOrigPropTarget) && (mOrigPropTarget.mType != mPropTarget.mType) &&
|
||||||
((!mOrigPropTarget.mType->IsGenericParam()) && (mPropTarget.mType->IsInterface())))
|
((!mOrigPropTarget.mType->IsGenericParam()) && (mPropTarget.mType->IsInterface())))
|
||||||
{
|
{
|
||||||
|
@ -16080,6 +16124,10 @@ BfModuleMethodInstance BfExprEvaluator::GetPropertyMethodInstance(BfMethodDef* m
|
||||||
while (checkTypeInst != NULL)
|
while (checkTypeInst != NULL)
|
||||||
{
|
{
|
||||||
mModule->PopulateType(checkTypeInst, BfPopulateType_DataAndMethods);
|
mModule->PopulateType(checkTypeInst, BfPopulateType_DataAndMethods);
|
||||||
|
BF_ASSERT((checkTypeInst->mDefineState >= BfTypeDefineState_DefinedAndMethodsSlotted) || (mModule->mCompiler->IsAutocomplete()));
|
||||||
|
|
||||||
|
if (checkTypeInst->mDefineState != BfTypeDefineState_DefinedAndMethodsSlotted)
|
||||||
|
break;
|
||||||
|
|
||||||
for (auto& iface : checkTypeInst->mInterfaces)
|
for (auto& iface : checkTypeInst->mInterfaces)
|
||||||
{
|
{
|
||||||
|
@ -16132,7 +16180,7 @@ BfModuleMethodInstance BfExprEvaluator::GetPropertyMethodInstance(BfMethodDef* m
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bestIFaceEntry != NULL)
|
if (bestIFaceEntry != NULL)
|
||||||
{
|
{
|
||||||
auto ifaceMethodEntry = checkTypeInst->mInterfaceMethodTable[bestIFaceEntry->mStartInterfaceTableIdx + methodDef->mIdx];
|
auto ifaceMethodEntry = checkTypeInst->mInterfaceMethodTable[bestIFaceEntry->mStartInterfaceTableIdx + methodDef->mIdx];
|
||||||
BfMethodInstance* bestMethodInstance = ifaceMethodEntry.mMethodRef;
|
BfMethodInstance* bestMethodInstance = ifaceMethodEntry.mMethodRef;
|
||||||
if (bestMethodInstance != NULL)
|
if (bestMethodInstance != NULL)
|
||||||
|
@ -18735,7 +18783,7 @@ void BfExprEvaluator::Visit(BfIndexerExpression* indexerExpr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (((mModule->HasCompiledOutput()) || (mModule->mIsConstModule)) &&
|
else if (((mModule->HasCompiledOutput()) || (mModule->mIsComptimeModule)) &&
|
||||||
(wantsChecks))
|
(wantsChecks))
|
||||||
{
|
{
|
||||||
if (checkedKind == BfCheckedKind_NotSet)
|
if (checkedKind == BfCheckedKind_NotSet)
|
||||||
|
@ -18767,7 +18815,7 @@ void BfExprEvaluator::Visit(BfIndexerExpression* indexerExpr)
|
||||||
OutputDebugStrF("-OOB %d %d\n", oobFunc.mFunc.mId, oobFunc.mFunc.mFlags);
|
OutputDebugStrF("-OOB %d %d\n", oobFunc.mFunc.mId, oobFunc.mFunc.mFlags);
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
if (mModule->mIsConstModule)
|
if (mModule->mIsComptimeModule)
|
||||||
mModule->mCompiler->mCEMachine->QueueMethod(oobFunc.mMethodInstance, oobFunc.mFunc);
|
mModule->mCompiler->mCEMachine->QueueMethod(oobFunc.mMethodInstance, oobFunc.mFunc);
|
||||||
|
|
||||||
SizedArray<BfIRValue, 1> args;
|
SizedArray<BfIRValue, 1> args;
|
||||||
|
|
|
@ -390,8 +390,8 @@ public:
|
||||||
void FinishExpressionResult();
|
void FinishExpressionResult();
|
||||||
virtual bool CheckAllowValue(const BfTypedValue& typedValue, BfAstNode* refNode);
|
virtual bool CheckAllowValue(const BfTypedValue& typedValue, BfAstNode* refNode);
|
||||||
BfAutoComplete* GetAutoComplete();
|
BfAutoComplete* GetAutoComplete();
|
||||||
bool IsConstEval();
|
bool IsComptime();
|
||||||
bool IsConstEvalEntry();
|
bool IsComptimeEntry();
|
||||||
int GetStructRetIdx(BfMethodInstance* methodInstance, bool forceStatic = false);
|
int GetStructRetIdx(BfMethodInstance* methodInstance, bool forceStatic = false);
|
||||||
BfTypedValue SetupNullConditional(BfTypedValue target, BfTokenNode* dotToken);
|
BfTypedValue SetupNullConditional(BfTypedValue target, BfTokenNode* dotToken);
|
||||||
void Evaluate(BfAstNode* astNode, bool propogateNullConditional = false, bool ignoreNullConditional = false, bool allowSplat = true);
|
void Evaluate(BfAstNode* astNode, bool propogateNullConditional = false, bool ignoreNullConditional = false, bool allowSplat = true);
|
||||||
|
|
|
@ -634,6 +634,12 @@ BfIRValue BfIRConstHolder::CreateConst(BfConstant* fromConst, BfIRConstHolder* f
|
||||||
auto typeOf = (BfTypeOf_Const*)fromConst;
|
auto typeOf = (BfTypeOf_Const*)fromConst;
|
||||||
return CreateTypeOf(typeOf->mType);
|
return CreateTypeOf(typeOf->mType);
|
||||||
}
|
}
|
||||||
|
else if (fromConst->mConstType == BfConstType_TypeOf_WithData)
|
||||||
|
{
|
||||||
|
auto typeOf = (BfTypeOf_WithData_Const*)fromConst;
|
||||||
|
auto dataConstant = fromHolder->GetConstant(typeOf->mTypeData);
|
||||||
|
return CreateTypeOf(typeOf->mType, CreateConst(dataConstant, fromHolder));
|
||||||
|
}
|
||||||
else if (fromConst->mConstType == BfConstType_AggZero)
|
else if (fromConst->mConstType == BfConstType_AggZero)
|
||||||
{
|
{
|
||||||
auto aggZero = (BfConstant*)fromConst;
|
auto aggZero = (BfConstant*)fromConst;
|
||||||
|
@ -783,7 +789,20 @@ BfIRValue BfIRConstHolder::CreateTypeOf(BfType* type)
|
||||||
{
|
{
|
||||||
BfTypeOf_Const* typeOf = mTempAlloc.Alloc<BfTypeOf_Const>();
|
BfTypeOf_Const* typeOf = mTempAlloc.Alloc<BfTypeOf_Const>();
|
||||||
typeOf->mConstType = BfConstType_TypeOf;
|
typeOf->mConstType = BfConstType_TypeOf;
|
||||||
|
typeOf->mType = type;
|
||||||
|
auto irValue = BfIRValue(BfIRValueFlags_Const, mTempAlloc.GetChunkedId(typeOf));
|
||||||
|
#ifdef CHECK_CONSTHOLDER
|
||||||
|
irValue.mHolder = this;
|
||||||
|
#endif
|
||||||
|
return irValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
BfIRValue BfIRConstHolder::CreateTypeOf(BfType* type, BfIRValue typeData)
|
||||||
|
{
|
||||||
|
BfTypeOf_WithData_Const* typeOf = mTempAlloc.Alloc<BfTypeOf_WithData_Const>();
|
||||||
|
typeOf->mConstType = BfConstType_TypeOf_WithData;
|
||||||
typeOf->mType = type;
|
typeOf->mType = type;
|
||||||
|
typeOf->mTypeData = typeData;
|
||||||
auto irValue = BfIRValue(BfIRValueFlags_Const, mTempAlloc.GetChunkedId(typeOf));
|
auto irValue = BfIRValue(BfIRValueFlags_Const, mTempAlloc.GetChunkedId(typeOf));
|
||||||
#ifdef CHECK_CONSTHOLDER
|
#ifdef CHECK_CONSTHOLDER
|
||||||
irValue.mHolder = this;
|
irValue.mHolder = this;
|
||||||
|
@ -1949,11 +1968,18 @@ void BfIRBuilder::Write(const BfIRValue& irValue)
|
||||||
{
|
{
|
||||||
Write(constant->mInt64);
|
Write(constant->mInt64);
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
case (int)BfConstType_TypeOf:
|
||||||
|
{
|
||||||
|
auto typeofConst = (BfTypeOf_Const*)constant;
|
||||||
|
Write(MapType(typeofConst->mType, BfIRPopulateType_Identity));
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case (int)BfConstType_Undef:
|
case (int)BfConstType_TypeOf_WithData:
|
||||||
{
|
{
|
||||||
auto undefConst = (BfConstantUndef*)constant;
|
auto typeofConst = (BfTypeOf_WithData_Const*)constant;
|
||||||
Write(undefConst->mType);
|
Write(MapType(typeofConst->mType, BfIRPopulateType_Identity));
|
||||||
|
Write(typeofConst->mTypeData);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -4476,6 +4502,12 @@ BfIRValue BfIRBuilder::CreateGlobalStringPtr(const StringImpl& str)
|
||||||
return retVal;
|
return retVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void BfIRBuilder::SetReflectTypeData(BfIRType type, BfIRValue globalVar)
|
||||||
|
{
|
||||||
|
BfIRValue retVal = WriteCmd(BfIRCmd_SetReflectTypeData, type, globalVar);
|
||||||
|
NEW_CMD_INSERTED_IRVALUE;
|
||||||
|
}
|
||||||
|
|
||||||
BfIRBlock BfIRBuilder::CreateBlock(const StringImpl& name, bool addNow)
|
BfIRBlock BfIRBuilder::CreateBlock(const StringImpl& name, bool addNow)
|
||||||
{
|
{
|
||||||
if (addNow)
|
if (addNow)
|
||||||
|
|
|
@ -120,6 +120,7 @@ enum BfConstType
|
||||||
BfConstType_PtrToInt,
|
BfConstType_PtrToInt,
|
||||||
BfConstType_IntToPtr,
|
BfConstType_IntToPtr,
|
||||||
BfConstType_TypeOf,
|
BfConstType_TypeOf,
|
||||||
|
BfConstType_TypeOf_WithData,
|
||||||
BfConstType_AggZero,
|
BfConstType_AggZero,
|
||||||
BfConstType_Agg,
|
BfConstType_Agg,
|
||||||
BfConstType_ArrayZero,
|
BfConstType_ArrayZero,
|
||||||
|
@ -235,6 +236,7 @@ enum BfIRCmd : uint8
|
||||||
BfIRCmd_GlobalVar_SetAlignment,
|
BfIRCmd_GlobalVar_SetAlignment,
|
||||||
BfIRCmd_GlobalVar_SetStorageKind,
|
BfIRCmd_GlobalVar_SetStorageKind,
|
||||||
BfIRCmd_GlobalStringPtr,
|
BfIRCmd_GlobalStringPtr,
|
||||||
|
BfIRCmd_SetReflectTypeData,
|
||||||
|
|
||||||
BfIRCmd_CreateBlock,
|
BfIRCmd_CreateBlock,
|
||||||
BfIRCmd_MaybeChainNewBlock,
|
BfIRCmd_MaybeChainNewBlock,
|
||||||
|
@ -771,6 +773,14 @@ struct BfTypeOf_Const
|
||||||
{
|
{
|
||||||
BfConstType mConstType;
|
BfConstType mConstType;
|
||||||
BfType* mType;
|
BfType* mType;
|
||||||
|
BfIRValue mTypeData;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct BfTypeOf_WithData_Const
|
||||||
|
{
|
||||||
|
BfConstType mConstType;
|
||||||
|
BfType* mType;
|
||||||
|
BfIRValue mTypeData;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct BfConstant
|
struct BfConstant
|
||||||
|
@ -906,6 +916,7 @@ public:
|
||||||
BfIRValue CreateConstArrayZero(BfIRType type, int count);
|
BfIRValue CreateConstArrayZero(BfIRType type, int count);
|
||||||
BfIRValue CreateConstArrayZero(int count);
|
BfIRValue CreateConstArrayZero(int count);
|
||||||
BfIRValue CreateTypeOf(BfType* type);
|
BfIRValue CreateTypeOf(BfType* type);
|
||||||
|
BfIRValue CreateTypeOf(BfType* type, BfIRValue typeData);
|
||||||
BfIRValue GetUndefConstValue(BfIRType type);
|
BfIRValue GetUndefConstValue(BfIRType type);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1199,6 +1210,7 @@ public:
|
||||||
void GlobalVar_SetAlignment(BfIRValue globalVar, int alignment);
|
void GlobalVar_SetAlignment(BfIRValue globalVar, int alignment);
|
||||||
void GlobalVar_SetStorageKind(BfIRValue globalVar, BfIRStorageKind storageKind);
|
void GlobalVar_SetStorageKind(BfIRValue globalVar, BfIRStorageKind storageKind);
|
||||||
BfIRValue CreateGlobalStringPtr(const StringImpl& str);
|
BfIRValue CreateGlobalStringPtr(const StringImpl& str);
|
||||||
|
void SetReflectTypeData(BfIRType type, BfIRValue globalVar);
|
||||||
|
|
||||||
BfIRBlock CreateBlock(const StringImpl& name, bool addNow = false);
|
BfIRBlock CreateBlock(const StringImpl& name, bool addNow = false);
|
||||||
BfIRBlock MaybeChainNewBlock(const StringImpl& name); // Creates new block if current block isn't empty
|
BfIRBlock MaybeChainNewBlock(const StringImpl& name); // Creates new block if current block isn't empty
|
||||||
|
|
|
@ -941,6 +941,21 @@ void BfIRCodeGen::Read(llvm::Value*& llvmValue, BfIRCodeGenEntry** codeGenEntry)
|
||||||
llvmValue = llvm::UndefValue::get(type);
|
llvmValue = llvm::UndefValue::get(type);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
else if (constType == BfConstType_TypeOf)
|
||||||
|
{
|
||||||
|
CMD_PARAM(llvm::Type*, type);
|
||||||
|
llvmValue = mReflectDataMap[type];
|
||||||
|
BF_ASSERT(llvmValue != NULL);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else if (constType == BfConstType_TypeOf_WithData)
|
||||||
|
{
|
||||||
|
CMD_PARAM(llvm::Type*, type);
|
||||||
|
CMD_PARAM(llvm::Value*, value);
|
||||||
|
mReflectDataMap[type] = value;
|
||||||
|
llvmValue = value;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
bool isSigned;
|
bool isSigned;
|
||||||
llvm::Type* llvmConstType = GetLLVMType(typeCode, isSigned);
|
llvm::Type* llvmConstType = GetLLVMType(typeCode, isSigned);
|
||||||
|
@ -2266,6 +2281,13 @@ void BfIRCodeGen::HandleNextCmd()
|
||||||
SetResult(curId, mIRBuilder->CreateGlobalStringPtr(llvm::StringRef(str.c_str(), str.length())));
|
SetResult(curId, mIRBuilder->CreateGlobalStringPtr(llvm::StringRef(str.c_str(), str.length())));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case BfIRCmd_SetReflectTypeData:
|
||||||
|
{
|
||||||
|
CMD_PARAM(llvm::Type*, type);
|
||||||
|
CMD_PARAM(llvm::Value*, value);
|
||||||
|
mReflectDataMap[type] = value;
|
||||||
|
}
|
||||||
|
break;
|
||||||
case BfIRCmd_CreateBlock:
|
case BfIRCmd_CreateBlock:
|
||||||
{
|
{
|
||||||
CMD_PARAM(String, name);
|
CMD_PARAM(String, name);
|
||||||
|
|
|
@ -107,7 +107,8 @@ public:
|
||||||
Dictionary<int, llvm::Function*> mIntrinsicMap;
|
Dictionary<int, llvm::Function*> mIntrinsicMap;
|
||||||
Dictionary<llvm::Function*, int> mIntrinsicReverseMap;
|
Dictionary<llvm::Function*, int> mIntrinsicReverseMap;
|
||||||
Array<llvm::Constant*> mConfigConsts32;
|
Array<llvm::Constant*> mConfigConsts32;
|
||||||
Array<llvm::Constant*> mConfigConsts64;
|
Array<llvm::Constant*> mConfigConsts64;
|
||||||
|
Dictionary<llvm::Type*, llvm::Value*> mReflectDataMap;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void InitTarget();
|
void InitTarget();
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -32,6 +32,7 @@ NS_BF_BEGIN
|
||||||
class BfType;
|
class BfType;
|
||||||
class BfResolvedType;
|
class BfResolvedType;
|
||||||
class BfExprEvaluator;
|
class BfExprEvaluator;
|
||||||
|
class CeEmitContext;
|
||||||
|
|
||||||
enum BfPopulateType
|
enum BfPopulateType
|
||||||
{
|
{
|
||||||
|
@ -71,7 +72,7 @@ enum BfEvalExprFlags
|
||||||
BfEvalExprFlags_AllowNonConst = 0x10000,
|
BfEvalExprFlags_AllowNonConst = 0x10000,
|
||||||
BfEvalExprFlags_StringInterpolateFormat = 0x20000,
|
BfEvalExprFlags_StringInterpolateFormat = 0x20000,
|
||||||
BfEvalExprFlags_NoLookupError = 0x40000,
|
BfEvalExprFlags_NoLookupError = 0x40000,
|
||||||
BfEvalExprFlags_ConstEval = 0x80000,
|
BfEvalExprFlags_Comptime = 0x80000,
|
||||||
BfEvalExprFlags_InCascade = 0x100000,
|
BfEvalExprFlags_InCascade = 0x100000,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1450,7 +1451,7 @@ public:
|
||||||
bool mWantsIRIgnoreWrites;
|
bool mWantsIRIgnoreWrites;
|
||||||
bool mHasGenericMethods;
|
bool mHasGenericMethods;
|
||||||
bool mIsSpecialModule; // vdata, unspecialized, external
|
bool mIsSpecialModule; // vdata, unspecialized, external
|
||||||
bool mIsConstModule;
|
bool mIsComptimeModule;
|
||||||
bool mIsScratchModule;
|
bool mIsScratchModule;
|
||||||
bool mIsSpecializedMethodModuleRoot;
|
bool mIsSpecializedMethodModuleRoot;
|
||||||
bool mIsModuleMutable; // Set to false after writing module to disk, can be set back to true after doing extension module
|
bool mIsModuleMutable; // Set to false after writing module to disk, can be set back to true after doing extension module
|
||||||
|
@ -1686,6 +1687,7 @@ public:
|
||||||
BfInternalAccessSet* GetInternalAccessSet();
|
BfInternalAccessSet* GetInternalAccessSet();
|
||||||
bool CheckInternalProtection(BfTypeDef* usingTypeDef);
|
bool CheckInternalProtection(BfTypeDef* usingTypeDef);
|
||||||
void AddFailType(BfTypeInstance* typeInstance);
|
void AddFailType(BfTypeInstance* typeInstance);
|
||||||
|
void DeferRebuildType(BfTypeInstance* typeInstance);
|
||||||
void MarkDerivedDirty(BfTypeInstance* typeInst);
|
void MarkDerivedDirty(BfTypeInstance* typeInst);
|
||||||
void CheckAddFailType();
|
void CheckAddFailType();
|
||||||
void PopulateType(BfType* resolvedTypeRef, BfPopulateType populateType = BfPopulateType_Data);
|
void PopulateType(BfType* resolvedTypeRef, BfPopulateType populateType = BfPopulateType_Data);
|
||||||
|
@ -1695,6 +1697,9 @@ public:
|
||||||
void SetTypeOptions(BfTypeInstance* typeInstance);
|
void SetTypeOptions(BfTypeInstance* typeInstance);
|
||||||
BfModuleOptions GetModuleOptions();
|
BfModuleOptions GetModuleOptions();
|
||||||
BfCheckedKind GetDefaultCheckedKind();
|
BfCheckedKind GetDefaultCheckedKind();
|
||||||
|
void UpdateCEEmit(CeEmitContext* ceEmitContext, BfTypeInstance* typeInstance, BfTypeDef* activeTypeDef, const StringImpl& ctxString, BfAstNode* refNode);
|
||||||
|
void ExecuteCEOnCompile(BfTypeInstance* typeInst, BfCEOnCompileKind onCompileKind, CeEmitContext* ceEmitContext);
|
||||||
|
void DoCEEmit(BfTypeInstance* typeInstance, bool& hadNewMembers);
|
||||||
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);
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
#include "BfCompiler.h"
|
#include "BfCompiler.h"
|
||||||
#include "BfSystem.h"
|
#include "BfSystem.h"
|
||||||
#include "BfParser.h"
|
#include "BfParser.h"
|
||||||
|
#include "BfReducer.h"
|
||||||
#include "BfCodeGen.h"
|
#include "BfCodeGen.h"
|
||||||
#include "BfExprEvaluator.h"
|
#include "BfExprEvaluator.h"
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
@ -17,6 +18,7 @@
|
||||||
#include "BfFixits.h"
|
#include "BfFixits.h"
|
||||||
#include "BfIRCodeGen.h"
|
#include "BfIRCodeGen.h"
|
||||||
#include "BfDefBuilder.h"
|
#include "BfDefBuilder.h"
|
||||||
|
#include "CeMachine.h"
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
@ -1931,6 +1933,177 @@ void BfModule::SetTypeOptions(BfTypeInstance* typeInstance)
|
||||||
typeInstance->mTypeOptionsIdx = GenerateTypeOptions(typeInstance->mCustomAttributes, typeInstance, true);
|
typeInstance->mTypeOptionsIdx = GenerateTypeOptions(typeInstance->mCustomAttributes, typeInstance, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void BfModule::UpdateCEEmit(CeEmitContext* ceEmitContext, BfTypeInstance* typeInstance, BfTypeDef* activeTypeDef, const StringImpl& ctxString, BfAstNode* refNode)
|
||||||
|
{
|
||||||
|
if (ceEmitContext->mEmitData.IsEmpty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
int prevFailIdx = mCompiler->mPassInstance->mFailedIdx;
|
||||||
|
int prevWarnIdx = mCompiler->mPassInstance->mWarnIdx;
|
||||||
|
|
||||||
|
String src;
|
||||||
|
|
||||||
|
if (activeTypeDef->mEmitParser != NULL)
|
||||||
|
src += "\n\n";
|
||||||
|
|
||||||
|
src += "// Code emission in ";
|
||||||
|
src += ctxString;
|
||||||
|
src += "\n\n";
|
||||||
|
src += ceEmitContext->mEmitData;
|
||||||
|
ceEmitContext->mEmitData.Clear();
|
||||||
|
|
||||||
|
int startSrcIdx = 0;
|
||||||
|
if (activeTypeDef->mEmitParser == NULL)
|
||||||
|
{
|
||||||
|
BfParser* parser = new BfParser(mSystem, typeInstance->mTypeDef->mProject);
|
||||||
|
parser->mIsEmitted = true;
|
||||||
|
parser->mFileName = typeInstance->mTypeDef->mName->ToString();
|
||||||
|
|
||||||
|
BfLogSys(mSystem, "CreateParser (emit): %p\n", parser);
|
||||||
|
|
||||||
|
if (mCompiler->mIsResolveOnly)
|
||||||
|
parser->mFileName += "$EmitR$";
|
||||||
|
else
|
||||||
|
parser->mFileName += "$Emit$";
|
||||||
|
|
||||||
|
parser->mFileName += StrFormat("%d", typeInstance->mTypeId);
|
||||||
|
if (activeTypeDef->mPartialIdx != -1)
|
||||||
|
parser->mFileName + StrFormat(":%d", activeTypeDef->mPartialIdx);
|
||||||
|
|
||||||
|
parser->mFileName += StrFormat(".bf|%d", typeInstance->mRevision);
|
||||||
|
activeTypeDef->mEmitParser = parser;
|
||||||
|
parser->mRefCount++;
|
||||||
|
parser->SetSource(src.c_str(), src.mLength);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int idx = activeTypeDef->mEmitParser->AllocChars(src.mLength + 1);
|
||||||
|
memcpy((uint8*)activeTypeDef->mEmitParser->mSrc + idx, src.c_str(), src.mLength + 1);
|
||||||
|
activeTypeDef->mEmitParser->mSrcIdx = idx;
|
||||||
|
activeTypeDef->mEmitParser->mSrcLength = idx + src.mLength;
|
||||||
|
activeTypeDef->mEmitParser->mParserData->mSrcLength = activeTypeDef->mEmitParser->mSrcLength;
|
||||||
|
}
|
||||||
|
|
||||||
|
activeTypeDef->mEmitParser->Parse(mCompiler->mPassInstance);
|
||||||
|
activeTypeDef->mEmitParser->FinishSideNodes();
|
||||||
|
|
||||||
|
auto typeDeclaration = activeTypeDef->mEmitParser->mAlloc->Alloc<BfTypeDeclaration>();
|
||||||
|
|
||||||
|
BfReducer bfReducer;
|
||||||
|
bfReducer.mSource = activeTypeDef->mEmitParser;
|
||||||
|
bfReducer.mPassInstance = mCompiler->mPassInstance;
|
||||||
|
bfReducer.mAlloc = activeTypeDef->mEmitParser->mAlloc;
|
||||||
|
bfReducer.mSystem = mSystem;
|
||||||
|
bfReducer.mCurTypeDecl = typeDeclaration;
|
||||||
|
typeDeclaration->mDefineNode = activeTypeDef->mEmitParser->mRootNode;
|
||||||
|
bfReducer.HandleTypeDeclaration(typeDeclaration, NULL);
|
||||||
|
|
||||||
|
BfDefBuilder defBuilder(mSystem);
|
||||||
|
defBuilder.mCurTypeDef = typeInstance->mTypeDef;
|
||||||
|
defBuilder.DoVisitChild(typeDeclaration->mDefineNode);
|
||||||
|
defBuilder.FinishTypeDef(typeInstance->mTypeDef->mTypeCode == BfTypeCode_Enum);
|
||||||
|
|
||||||
|
//
|
||||||
|
{
|
||||||
|
AutoCrit crit(mSystem->mDataLock);
|
||||||
|
mSystem->mParsers.Add(activeTypeDef->mEmitParser);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((prevFailIdx != mCompiler->mPassInstance->mFailedIdx) && (refNode != NULL))
|
||||||
|
Fail("Emitted code had errors", refNode);
|
||||||
|
else if ((prevWarnIdx != mCompiler->mPassInstance->mWarnIdx) && (refNode != NULL))
|
||||||
|
Warn(0, "Emitted code had warnings", refNode);
|
||||||
|
else if ((prevFailIdx != mCompiler->mPassInstance->mFailedIdx) ||
|
||||||
|
(prevWarnIdx != mCompiler->mPassInstance->mWarnIdx))
|
||||||
|
{
|
||||||
|
AddFailType(typeInstance);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void BfModule::ExecuteCEOnCompile(BfTypeInstance* typeInstance, BfCEOnCompileKind onCompileKind, CeEmitContext* ceEmitContext)
|
||||||
|
{
|
||||||
|
if (!typeInstance->mTypeDef->mHasCEOnCompile)
|
||||||
|
return;
|
||||||
|
|
||||||
|
int methodCount = (int)typeInstance->mTypeDef->mMethods.size();
|
||||||
|
for (int methodIdx = 0; methodIdx < methodCount; methodIdx++)
|
||||||
|
{
|
||||||
|
auto methodDef = typeInstance->mTypeDef->mMethods[methodIdx];
|
||||||
|
auto methodDeclaration = BfNodeDynCast<BfMethodDeclaration>(methodDef->mMethodDeclaration);
|
||||||
|
if (methodDeclaration == NULL)
|
||||||
|
continue;
|
||||||
|
if (methodDeclaration->mAttributes == NULL)
|
||||||
|
continue;
|
||||||
|
auto customAttributes = GetCustomAttributes(methodDeclaration->mAttributes, BfAttributeTargets_Method);
|
||||||
|
defer({ delete customAttributes; });
|
||||||
|
|
||||||
|
auto onCompileAttribute = customAttributes->Get(mCompiler->mOnCompileAttributeTypeDef);
|
||||||
|
if (onCompileAttribute == NULL)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (onCompileAttribute->mCtorArgs.size() < 1)
|
||||||
|
continue;
|
||||||
|
auto constant = typeInstance->mConstHolder->GetConstant(onCompileAttribute->mCtorArgs[0]);
|
||||||
|
if (constant == NULL)
|
||||||
|
continue;
|
||||||
|
if (onCompileKind != (BfCEOnCompileKind)constant->mInt32)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (!methodDef->mIsStatic)
|
||||||
|
{
|
||||||
|
Fail("OnCompile methods must be static", methodDeclaration);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!methodDef->mParams.IsEmpty())
|
||||||
|
{
|
||||||
|
Fail("OnCompile methods cannot declare parameters", methodDeclaration);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
SetAndRestoreValue<CeEmitContext*> prevEmitContext(mCompiler->mCEMachine->mCurEmitContext);
|
||||||
|
|
||||||
|
if (onCompileKind == BfCEOnCompileKind_TypeInit)
|
||||||
|
{
|
||||||
|
mCompiler->mCEMachine->mCurEmitContext = ceEmitContext;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto methodInstance = GetRawMethodInstanceAtIdx(typeInstance, methodDef->mIdx);
|
||||||
|
auto result = mCompiler->mCEMachine->Call(methodDef->GetRefNode(), this, methodInstance, {}, (CeEvalFlags)(CeEvalFlags_PersistantError | CeEvalFlags_DeferIfNotOnlyError), NULL);
|
||||||
|
|
||||||
|
if (!ceEmitContext->mEmitData.IsEmpty())
|
||||||
|
{
|
||||||
|
String ctxStr = "OnCompile execution of ";
|
||||||
|
ctxStr += MethodToString(methodInstance);
|
||||||
|
UpdateCEEmit(ceEmitContext, typeInstance, methodInstance->mMethodDef->mDeclaringType, ctxStr, methodInstance->mMethodDef->GetRefNode());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mCompiler->mCanceling)
|
||||||
|
{
|
||||||
|
DeferRebuildType(typeInstance);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void BfModule::DoCEEmit(BfTypeInstance* typeInstance, bool& hadNewMembers)
|
||||||
|
{
|
||||||
|
typeInstance->mTypeDef->ClearEmitted();
|
||||||
|
|
||||||
|
int startMethodCount = typeInstance->mTypeDef->mMethods.mSize;
|
||||||
|
int startFieldCount = typeInstance->mTypeDef->mFields.mSize;
|
||||||
|
|
||||||
|
CeEmitContext emitContext;
|
||||||
|
emitContext.mType = typeInstance;
|
||||||
|
ExecuteCEOnCompile(typeInstance, BfCEOnCompileKind_TypeInit, &emitContext);
|
||||||
|
|
||||||
|
if ((startMethodCount != typeInstance->mTypeDef->mMethods.mSize) ||
|
||||||
|
(startFieldCount != typeInstance->mTypeDef->mFields.mSize))
|
||||||
|
{
|
||||||
|
typeInstance->mTypeDef->ClearMemberSets();
|
||||||
|
hadNewMembers = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateType)
|
void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateType)
|
||||||
{
|
{
|
||||||
auto typeInstance = resolvedTypeRef->ToTypeInstance();
|
auto typeInstance = resolvedTypeRef->ToTypeInstance();
|
||||||
|
@ -1991,7 +2164,7 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy
|
||||||
resolvedTypeRef->mSize = typeInstance->mAlign = mSystem->mPtrSize;
|
resolvedTypeRef->mSize = typeInstance->mAlign = mSystem->mPtrSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
BF_ASSERT((typeInstance->mMethodInstanceGroups.size() == 0) || (typeInstance->mMethodInstanceGroups.size() == typeDef->mMethods.size()));
|
BF_ASSERT((typeInstance->mMethodInstanceGroups.size() == 0) || (typeInstance->mMethodInstanceGroups.size() == typeDef->mMethods.size()) || (typeInstance->mTypeDef->mHasEmitMembers));
|
||||||
typeInstance->mMethodInstanceGroups.Resize(typeDef->mMethods.size());
|
typeInstance->mMethodInstanceGroups.Resize(typeDef->mMethods.size());
|
||||||
for (int i = 0; i < (int)typeInstance->mMethodInstanceGroups.size(); i++)
|
for (int i = 0; i < (int)typeInstance->mMethodInstanceGroups.size(); i++)
|
||||||
{
|
{
|
||||||
|
@ -2807,9 +2980,9 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy
|
||||||
BF_ASSERT(!typeInstance->mNeedsMethodProcessing);
|
BF_ASSERT(!typeInstance->mNeedsMethodProcessing);
|
||||||
if (typeInstance->mDefineState < BfTypeDefineState_HasInterfaces)
|
if (typeInstance->mDefineState < BfTypeDefineState_HasInterfaces)
|
||||||
typeInstance->mDefineState = BfTypeDefineState_HasInterfaces;
|
typeInstance->mDefineState = BfTypeDefineState_HasInterfaces;
|
||||||
|
|
||||||
for (auto& validateEntry : deferredTypeValidateList)
|
for (auto& validateEntry : deferredTypeValidateList)
|
||||||
{
|
{
|
||||||
SetAndRestoreValue<bool> ignoreErrors(mIgnoreErrors, mIgnoreErrors | validateEntry.mIgnoreErrors);
|
SetAndRestoreValue<bool> ignoreErrors(mIgnoreErrors, mIgnoreErrors | validateEntry.mIgnoreErrors);
|
||||||
ValidateGenericConstraints(validateEntry.mTypeRef, validateEntry.mGenericType, false);
|
ValidateGenericConstraints(validateEntry.mTypeRef, validateEntry.mGenericType, false);
|
||||||
}
|
}
|
||||||
|
@ -2858,7 +3031,28 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy
|
||||||
|
|
||||||
if (typeInstance->mTypeOptionsIdx == -2)
|
if (typeInstance->mTypeOptionsIdx == -2)
|
||||||
SetTypeOptions(typeInstance);
|
SetTypeOptions(typeInstance);
|
||||||
|
|
||||||
|
// if (typeInstance->mDefineState == BfTypeDefineState_CETypeInit)
|
||||||
|
// {
|
||||||
|
// if (populateType <= BfPopulateType_AllowStaticMethods)
|
||||||
|
// return;
|
||||||
|
//
|
||||||
|
// auto refNode = typeDef->GetRefNode();
|
||||||
|
// Fail("OnCompile const evaluation creates a data dependency during TypeInit", refNode);
|
||||||
|
// mCompiler->mCEMachine->Fail("OnCompile const evaluation creates a data dependency during TypeInit");
|
||||||
|
// }
|
||||||
|
// else if (typeInstance->mDefineState < BfTypeDefineState_CEPostTypeInit)
|
||||||
|
// {
|
||||||
|
// typeInstance->mDefineState = BfTypeDefineState_CETypeInit;
|
||||||
|
// ExecuteCEOnCompile(typeInstance, BfCEOnCompileKind_TypeInit);
|
||||||
|
//
|
||||||
|
// if (_CheckTypeDone())
|
||||||
|
// return;
|
||||||
|
//
|
||||||
|
// if (typeInstance->mDefineState < BfTypeDefineState_CEPostTypeInit)
|
||||||
|
// typeInstance->mDefineState = BfTypeDefineState_CEPostTypeInit;
|
||||||
|
// }
|
||||||
|
|
||||||
if (populateType <= BfPopulateType_AllowStaticMethods)
|
if (populateType <= BfPopulateType_AllowStaticMethods)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -3156,6 +3350,44 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (typeInstance->mDefineState == BfTypeDefineState_CETypeInit)
|
||||||
|
{
|
||||||
|
if (populateType <= BfPopulateType_AllowStaticMethods)
|
||||||
|
return;
|
||||||
|
|
||||||
|
String error = "OnCompile const evaluation creates a data dependency during TypeInit";
|
||||||
|
if (mCompiler->mCEMachine->mCurBuilder != NULL)
|
||||||
|
{
|
||||||
|
error += StrFormat(" during const-eval generation of '%s'", MethodToString(mCompiler->mCEMachine->mCurBuilder->mCeFunction->mMethodInstance).c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
auto refNode = typeDef->GetRefNode();
|
||||||
|
Fail(error, refNode);
|
||||||
|
if (mCompiler->mCEMachine->mCurFrame != NULL)
|
||||||
|
mCompiler->mCEMachine->Fail(*mCompiler->mCEMachine->mCurFrame, error);
|
||||||
|
else
|
||||||
|
mCompiler->mCEMachine->Fail(error);
|
||||||
|
}
|
||||||
|
else if (typeInstance->mDefineState < BfTypeDefineState_CEPostTypeInit)
|
||||||
|
{
|
||||||
|
typeInstance->mDefineState = BfTypeDefineState_CETypeInit;
|
||||||
|
bool hadNewMembers = false;
|
||||||
|
DoCEEmit(typeInstance, hadNewMembers);
|
||||||
|
|
||||||
|
if (typeInstance->mDefineState < BfTypeDefineState_CEPostTypeInit)
|
||||||
|
typeInstance->mDefineState = BfTypeDefineState_CEPostTypeInit;
|
||||||
|
|
||||||
|
if (hadNewMembers)
|
||||||
|
{
|
||||||
|
typeInstance->mTypeDef->mHasEmitMembers = true;
|
||||||
|
DoPopulateType(resolvedTypeRef, populateType);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_CheckTypeDone())
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_CheckTypeDone())
|
if (_CheckTypeDone())
|
||||||
|
@ -3670,7 +3902,12 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy
|
||||||
member->mRefCount++;
|
member->mRefCount++;
|
||||||
}
|
}
|
||||||
|
|
||||||
typeInstance->mDefineState = BfTypeDefineState_Defined;
|
if (typeInstance->mDefineState < BfTypeDefineState_Defined)
|
||||||
|
{
|
||||||
|
typeInstance->mDefineState = BfTypeDefineState_Defined;
|
||||||
|
if (!typeInstance->IsBoxed())
|
||||||
|
ExecuteCEOnCompile(typeInstance, BfCEOnCompileKind_TypeDone, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
if (typeInstance->mTypeFailed)
|
if (typeInstance->mTypeFailed)
|
||||||
mHadBuildError = true;
|
mHadBuildError = true;
|
||||||
|
@ -3832,7 +4069,7 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy
|
||||||
int64 min = 0;
|
int64 min = 0;
|
||||||
int64 max = 0;
|
int64 max = 0;
|
||||||
|
|
||||||
bool isFirst = false;
|
bool isFirst = true;
|
||||||
|
|
||||||
if (typeInstance->mTypeInfoEx == NULL)
|
if (typeInstance->mTypeInfoEx == NULL)
|
||||||
typeInstance->mTypeInfoEx = new BfTypeInfoEx();
|
typeInstance->mTypeInfoEx = new BfTypeInfoEx();
|
||||||
|
@ -4310,20 +4547,19 @@ void BfModule::DoTypeInstanceMethodProcessing(BfTypeInstance* typeInstance)
|
||||||
if (methodInstanceGroup->mOnDemandKind == BfMethodOnDemandKind_AlwaysInclude)
|
if (methodInstanceGroup->mOnDemandKind == BfMethodOnDemandKind_AlwaysInclude)
|
||||||
continue;
|
continue;
|
||||||
if (methodInstanceGroup->mOnDemandKind == BfMethodOnDemandKind_InWorkList)
|
if (methodInstanceGroup->mOnDemandKind == BfMethodOnDemandKind_InWorkList)
|
||||||
continue;
|
continue;
|
||||||
if (methodInstanceGroup->mOnDemandKind == BfMethodOnDemandKind_Decl_AwaitingReference)
|
|
||||||
continue;
|
|
||||||
if (methodInstanceGroup->mOnDemandKind == BfMethodOnDemandKind_Referenced)
|
if (methodInstanceGroup->mOnDemandKind == BfMethodOnDemandKind_Referenced)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (isFailedType)
|
if (isFailedType)
|
||||||
{
|
{
|
||||||
// We don't want method decls from failed generic types to clog up our type system
|
// We don't want method decls from failed generic types to clog up our type system
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// This should still be set to the default value
|
BF_ASSERT((methodInstanceGroup->mOnDemandKind == BfMethodOnDemandKind_NotSet) ||
|
||||||
BF_ASSERT((methodInstanceGroup->mOnDemandKind == BfMethodOnDemandKind_NotSet) || (methodInstanceGroup->mOnDemandKind == BfMethodOnDemandKind_Decl_AwaitingDecl));
|
(methodInstanceGroup->mOnDemandKind == BfMethodOnDemandKind_Decl_AwaitingDecl) ||
|
||||||
|
(methodInstanceGroup->mOnDemandKind == BfMethodOnDemandKind_Decl_AwaitingReference));
|
||||||
|
|
||||||
if ((isBoxed) && (!methodDef->mIsVirtual))
|
if ((isBoxed) && (!methodDef->mIsVirtual))
|
||||||
{
|
{
|
||||||
|
@ -4351,12 +4587,11 @@ void BfModule::DoTypeInstanceMethodProcessing(BfTypeInstance* typeInstance)
|
||||||
|
|
||||||
if ((methodDef->mName == BF_METHODNAME_DYNAMICCAST) && (typeInstance->IsValueType()))
|
if ((methodDef->mName == BF_METHODNAME_DYNAMICCAST) && (typeInstance->IsValueType()))
|
||||||
continue; // This is just a placeholder for boxed types
|
continue; // This is just a placeholder for boxed types
|
||||||
|
|
||||||
if (methodInstanceGroup->mOnDemandKind == BfMethodOnDemandKind_NotSet)
|
|
||||||
methodInstanceGroup->mOnDemandKind = BfMethodOnDemandKind_AlwaysInclude;
|
|
||||||
|
|
||||||
|
bool doAlwaysInclude = false;
|
||||||
|
|
||||||
if (wantsOnDemandMethods)
|
if (wantsOnDemandMethods)
|
||||||
{
|
{
|
||||||
bool implRequired = false;
|
bool implRequired = false;
|
||||||
bool declRequired = false;
|
bool declRequired = false;
|
||||||
|
|
||||||
|
@ -4452,9 +4687,8 @@ void BfModule::DoTypeInstanceMethodProcessing(BfTypeInstance* typeInstance)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!implRequired)
|
if (!implRequired)
|
||||||
{
|
{
|
||||||
BF_ASSERT(methodInstanceGroup->mOnDemandKind != BfMethodOnDemandKind_NotSet);
|
if (methodInstanceGroup->mOnDemandKind == BfMethodOnDemandKind_NotSet)
|
||||||
if (methodInstanceGroup->mOnDemandKind == BfMethodOnDemandKind_AlwaysInclude)
|
|
||||||
{
|
{
|
||||||
if (!mIsScratchModule)
|
if (!mIsScratchModule)
|
||||||
mOnDemandMethodCount++;
|
mOnDemandMethodCount++;
|
||||||
|
@ -4462,19 +4696,41 @@ void BfModule::DoTypeInstanceMethodProcessing(BfTypeInstance* typeInstance)
|
||||||
|
|
||||||
if (!declRequired)
|
if (!declRequired)
|
||||||
{
|
{
|
||||||
if (methodInstanceGroup->mOnDemandKind == BfMethodOnDemandKind_AlwaysInclude)
|
if (methodInstanceGroup->mOnDemandKind == BfMethodOnDemandKind_NotSet)
|
||||||
methodInstanceGroup->mOnDemandKind = BfMethodOnDemandKind_NoDecl_AwaitingReference;
|
methodInstanceGroup->mOnDemandKind = BfMethodOnDemandKind_NoDecl_AwaitingReference;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (methodInstanceGroup->mOnDemandKind == BfMethodOnDemandKind_AlwaysInclude)
|
if (methodInstanceGroup->mOnDemandKind == BfMethodOnDemandKind_NotSet)
|
||||||
methodInstanceGroup->mOnDemandKind = BfMethodOnDemandKind_Decl_AwaitingDecl;
|
methodInstanceGroup->mOnDemandKind = BfMethodOnDemandKind_Decl_AwaitingDecl;
|
||||||
}
|
}
|
||||||
|
|
||||||
VerifyOnDemandMethods();
|
VerifyOnDemandMethods();
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
doAlwaysInclude = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
doAlwaysInclude = true;
|
||||||
|
|
||||||
|
if (doAlwaysInclude)
|
||||||
|
{
|
||||||
|
bool wasDeclared = (methodInstanceGroup->mOnDemandKind == BfMethodOnDemandKind_Decl_AwaitingDecl) ||
|
||||||
|
(methodInstanceGroup->mOnDemandKind == BfMethodOnDemandKind_Decl_AwaitingReference);
|
||||||
|
|
||||||
|
methodInstanceGroup->mOnDemandKind = BfMethodOnDemandKind_AlwaysInclude;
|
||||||
|
|
||||||
|
if (wasDeclared)
|
||||||
|
{
|
||||||
|
if (!mIsScratchModule)
|
||||||
|
mOnDemandMethodCount--;
|
||||||
|
if (methodInstanceGroup->mDefault != NULL)
|
||||||
|
AddMethodToWorkList(methodInstanceGroup->mDefault);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
BfLogSysM("Starting DoTypeInstanceMethodProcessing %p GetMethodInstance pass. OnDemandMethods: %d\n", typeInstance, mOnDemandMethodCount);
|
BfLogSysM("Starting DoTypeInstanceMethodProcessing %p GetMethodInstance pass. OnDemandMethods: %d\n", typeInstance, mOnDemandMethodCount);
|
||||||
|
@ -5480,7 +5736,7 @@ BfPrimitiveType* BfModule::GetPrimitiveType(BfTypeCode typeCode)
|
||||||
|
|
||||||
BfIRType BfModule::GetIRLoweredType(BfTypeCode loweredTypeCode, BfTypeCode loweredTypeCode2)
|
BfIRType BfModule::GetIRLoweredType(BfTypeCode loweredTypeCode, BfTypeCode loweredTypeCode2)
|
||||||
{
|
{
|
||||||
BF_ASSERT(!mIsConstModule);
|
BF_ASSERT(!mIsComptimeModule);
|
||||||
|
|
||||||
BF_ASSERT(loweredTypeCode != BfTypeCode_None);
|
BF_ASSERT(loweredTypeCode != BfTypeCode_None);
|
||||||
if (loweredTypeCode2 == BfTypeCode_None)
|
if (loweredTypeCode2 == BfTypeCode_None)
|
||||||
|
|
|
@ -341,6 +341,7 @@ BfParser::BfParser(BfSystem* bfSystem, BfProject* bfProject) : BfSource(bfSystem
|
||||||
mAwaitingDelete = false;
|
mAwaitingDelete = false;
|
||||||
mScanOnly = false;
|
mScanOnly = false;
|
||||||
mCompleteParse = false;
|
mCompleteParse = false;
|
||||||
|
mIsEmitted = false;
|
||||||
mJumpTable = NULL;
|
mJumpTable = NULL;
|
||||||
mProject = bfProject;
|
mProject = bfProject;
|
||||||
mPassInstance = NULL;
|
mPassInstance = NULL;
|
||||||
|
@ -525,6 +526,8 @@ void BfParser::SetSource(const char* data, int length)
|
||||||
canCache = false;
|
canCache = false;
|
||||||
if (mProject == NULL)
|
if (mProject == NULL)
|
||||||
canCache = false;
|
canCache = false;
|
||||||
|
if (mIsEmitted)
|
||||||
|
canCache = false;
|
||||||
|
|
||||||
uint64 cacheHash = 0;
|
uint64 cacheHash = 0;
|
||||||
if (canCache)
|
if (canCache)
|
||||||
|
@ -3447,8 +3450,11 @@ void BfParser::Parse(BfPassInstance* passInstance)
|
||||||
{
|
{
|
||||||
BP_ZONE_F("BfParser::Parse %s", mFileName.c_str());
|
BP_ZONE_F("BfParser::Parse %s", mFileName.c_str());
|
||||||
|
|
||||||
|
mSyntaxToken = BfSyntaxToken_None;
|
||||||
mPassInstance = passInstance;
|
mPassInstance = passInstance;
|
||||||
|
|
||||||
|
int startIdx = mSrcIdx;
|
||||||
|
|
||||||
if (mUsingCache)
|
if (mUsingCache)
|
||||||
{
|
{
|
||||||
mRootNode = mParserData->mRootNode;
|
mRootNode = mParserData->mRootNode;
|
||||||
|
@ -3476,7 +3482,7 @@ void BfParser::Parse(BfPassInstance* passInstance)
|
||||||
mPassInstance->Warn(0, "No matching #endif found", mPreprocessorNodeStack.back().first);
|
mPassInstance->Warn(0, "No matching #endif found", mPreprocessorNodeStack.back().first);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 1; i < mJumpTableSize; i++)
|
for (int i = (startIdx / PARSER_JUMPTABLE_DIVIDE)+1; i < mJumpTableSize; i++)
|
||||||
if (mJumpTable[i].mCharIdx == 0)
|
if (mJumpTable[i].mCharIdx == 0)
|
||||||
mJumpTable[i] = mJumpTable[i - 1];
|
mJumpTable[i] = mJumpTable[i - 1];
|
||||||
|
|
||||||
|
@ -3523,6 +3529,26 @@ void BfParser::Close()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void BfParser::HadSrcRealloc()
|
||||||
|
{
|
||||||
|
int jumpTableSize = ((mSrcAllocSize + 1) + PARSER_JUMPTABLE_DIVIDE - 1) / PARSER_JUMPTABLE_DIVIDE;
|
||||||
|
if (jumpTableSize > mJumpTableSize)
|
||||||
|
{
|
||||||
|
auto jumpTable = new BfLineStartEntry[jumpTableSize];
|
||||||
|
memset(jumpTable, 0, jumpTableSize * sizeof(BfLineStartEntry));
|
||||||
|
memcpy(jumpTable, mJumpTable, mJumpTableSize * sizeof(BfLineStartEntry));
|
||||||
|
|
||||||
|
delete mJumpTable;
|
||||||
|
|
||||||
|
mJumpTable = jumpTable;
|
||||||
|
mJumpTableSize = jumpTableSize;
|
||||||
|
|
||||||
|
mParserData->mJumpTable = mJumpTable;
|
||||||
|
mParserData->mJumpTableSize = mJumpTableSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void BfParser::GenerateAutoCompleteFrom(int srcPosition)
|
void BfParser::GenerateAutoCompleteFrom(int srcPosition)
|
||||||
{
|
{
|
||||||
BfSourcePositionFinder posFinder(this, srcPosition);
|
BfSourcePositionFinder posFinder(this, srcPosition);
|
||||||
|
|
|
@ -81,7 +81,7 @@ public:
|
||||||
Dictionary<int, BfParserWarningEnabledChange> mWarningEnabledChanges;
|
Dictionary<int, BfParserWarningEnabledChange> mWarningEnabledChanges;
|
||||||
std::set<int> mUnwarns;
|
std::set<int> mUnwarns;
|
||||||
bool mFailed; // Don't cache if there's a warning or an error
|
bool mFailed; // Don't cache if there's a warning or an error
|
||||||
bool mDidReduce;
|
bool mDidReduce;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
BfParserData();
|
BfParserData();
|
||||||
|
@ -157,6 +157,7 @@ public:
|
||||||
bool mQuickCompatMode;
|
bool mQuickCompatMode;
|
||||||
bool mScanOnly;
|
bool mScanOnly;
|
||||||
bool mCompleteParse;
|
bool mCompleteParse;
|
||||||
|
bool mIsEmitted;
|
||||||
BfLineStartEntry* mJumpTable;
|
BfLineStartEntry* mJumpTable;
|
||||||
int mJumpTableSize;
|
int mJumpTableSize;
|
||||||
int mOrigSrcLength;
|
int mOrigSrcLength;
|
||||||
|
@ -231,6 +232,7 @@ public:
|
||||||
void Parse(BfPassInstance* passInstance);
|
void Parse(BfPassInstance* passInstance);
|
||||||
int GetCharIdAtIndex(int findIndex);
|
int GetCharIdAtIndex(int findIndex);
|
||||||
virtual void Close() override;
|
virtual void Close() override;
|
||||||
|
virtual void HadSrcRealloc() override;
|
||||||
|
|
||||||
void GenerateAutoCompleteFrom(int srcPosition);
|
void GenerateAutoCompleteFrom(int srcPosition);
|
||||||
|
|
||||||
|
|
|
@ -1143,7 +1143,7 @@ void BfMethodInstance::GetIRFunctionInfo(BfModule* module, BfIRType& returnType,
|
||||||
|
|
||||||
BfTypeCode loweredReturnTypeCode = BfTypeCode_None;
|
BfTypeCode loweredReturnTypeCode = BfTypeCode_None;
|
||||||
BfTypeCode loweredReturnTypeCode2 = BfTypeCode_None;
|
BfTypeCode loweredReturnTypeCode2 = BfTypeCode_None;
|
||||||
if ((!module->mIsConstModule) && (GetLoweredReturnType(&loweredReturnTypeCode, &loweredReturnTypeCode2)))
|
if ((!module->mIsComptimeModule) && (GetLoweredReturnType(&loweredReturnTypeCode, &loweredReturnTypeCode2)))
|
||||||
{
|
{
|
||||||
auto irReturnType = module->GetIRLoweredType(loweredReturnTypeCode, loweredReturnTypeCode2);
|
auto irReturnType = module->GetIRLoweredType(loweredReturnTypeCode, loweredReturnTypeCode2);
|
||||||
returnType = irReturnType;
|
returnType = irReturnType;
|
||||||
|
@ -1153,7 +1153,7 @@ void BfMethodInstance::GetIRFunctionInfo(BfModule* module, BfIRType& returnType,
|
||||||
auto voidType = module->GetPrimitiveType(BfTypeCode_None);
|
auto voidType = module->GetPrimitiveType(BfTypeCode_None);
|
||||||
returnType = module->mBfIRBuilder->MapType(voidType);
|
returnType = module->mBfIRBuilder->MapType(voidType);
|
||||||
}
|
}
|
||||||
else if ((!module->mIsConstModule) && (GetStructRetIdx(forceStatic) != -1))
|
else if ((!module->mIsComptimeModule) && (GetStructRetIdx(forceStatic) != -1))
|
||||||
{
|
{
|
||||||
auto voidType = module->GetPrimitiveType(BfTypeCode_None);
|
auto voidType = module->GetPrimitiveType(BfTypeCode_None);
|
||||||
returnType = module->mBfIRBuilder->MapType(voidType);
|
returnType = module->mBfIRBuilder->MapType(voidType);
|
||||||
|
@ -1210,11 +1210,11 @@ void BfMethodInstance::GetIRFunctionInfo(BfModule* module, BfIRType& returnType,
|
||||||
{
|
{
|
||||||
checkType = checkType->GetUnderlyingType();
|
checkType = checkType->GetUnderlyingType();
|
||||||
}
|
}
|
||||||
else if ((!module->mIsConstModule) && (checkType->IsSplattable()) && (AllowsSplatting(-1)))
|
else if ((!module->mIsComptimeModule) && (checkType->IsSplattable()) && (AllowsSplatting(-1)))
|
||||||
{
|
{
|
||||||
doSplat = true;
|
doSplat = true;
|
||||||
}
|
}
|
||||||
else if ((!module->mIsConstModule) && (!mMethodDef->mIsMutating) && (mCallingConvention == BfCallingConvention_Unspecified))
|
else if ((!module->mIsComptimeModule) && (!mMethodDef->mIsMutating) && (mCallingConvention == BfCallingConvention_Unspecified))
|
||||||
checkLowered = true;
|
checkLowered = true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -1227,11 +1227,11 @@ void BfMethodInstance::GetIRFunctionInfo(BfModule* module, BfIRType& returnType,
|
||||||
{
|
{
|
||||||
checkType = checkType->GetUnderlyingType();
|
checkType = checkType->GetUnderlyingType();
|
||||||
}
|
}
|
||||||
else if ((!module->mIsConstModule) && (checkType->IsSplattable()) && (AllowsSplatting(paramIdx)))
|
else if ((!module->mIsComptimeModule) && (checkType->IsSplattable()) && (AllowsSplatting(paramIdx)))
|
||||||
{
|
{
|
||||||
doSplat = true;
|
doSplat = true;
|
||||||
}
|
}
|
||||||
else if (!module->mIsConstModule)
|
else if (!module->mIsComptimeModule)
|
||||||
checkLowered = true;
|
checkLowered = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1311,7 +1311,7 @@ void BfMethodInstance::GetIRFunctionInfo(BfModule* module, BfIRType& returnType,
|
||||||
paramIdx++; // Skip over the explicit 'this'
|
paramIdx++; // Skip over the explicit 'this'
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((!module->mIsConstModule) && (GetStructRetIdx(forceStatic) == 1))
|
if ((!module->mIsComptimeModule) && (GetStructRetIdx(forceStatic) == 1))
|
||||||
{
|
{
|
||||||
BF_SWAP(paramTypes[0], paramTypes[1]);
|
BF_SWAP(paramTypes[0], paramTypes[1]);
|
||||||
}
|
}
|
||||||
|
@ -1509,6 +1509,8 @@ BfTypeInstance::~BfTypeInstance()
|
||||||
delete methodInst;
|
delete methodInst;
|
||||||
for (auto operatorInfo : mOperatorInfo)
|
for (auto operatorInfo : mOperatorInfo)
|
||||||
delete operatorInfo;
|
delete operatorInfo;
|
||||||
|
for (auto localMethod : mOwnedLocalMethods)
|
||||||
|
delete localMethod;
|
||||||
delete mHotTypeData;
|
delete mHotTypeData;
|
||||||
delete mConstHolder;
|
delete mConstHolder;
|
||||||
}
|
}
|
||||||
|
|
|
@ -416,7 +416,9 @@ enum BfTypeRebuildFlags
|
||||||
BfTypeRebuildFlag_UnderlyingTypeDeferred = 0x1000,
|
BfTypeRebuildFlag_UnderlyingTypeDeferred = 0x1000,
|
||||||
BfTypeRebuildFlag_TypeDataSaved = 0x2000,
|
BfTypeRebuildFlag_TypeDataSaved = 0x2000,
|
||||||
BfTypeRebuildFlag_InTempPool = 0x4000,
|
BfTypeRebuildFlag_InTempPool = 0x4000,
|
||||||
BfTypeRebuildFlag_ResolvingBase = 0x8000
|
BfTypeRebuildFlag_ResolvingBase = 0x8000,
|
||||||
|
BfTypeRebuildFlag_InFailTypes = 0x10000,
|
||||||
|
BfTypeRebuildFlag_RebuildQueued = 0x20000,
|
||||||
};
|
};
|
||||||
|
|
||||||
class BfTypeDIReplaceCallback;
|
class BfTypeDIReplaceCallback;
|
||||||
|
@ -425,9 +427,12 @@ enum BfTypeDefineState : uint8
|
||||||
{
|
{
|
||||||
BfTypeDefineState_Undefined,
|
BfTypeDefineState_Undefined,
|
||||||
BfTypeDefineState_Declared,
|
BfTypeDefineState_Declared,
|
||||||
BfTypeDefineState_ResolvingBaseType,
|
BfTypeDefineState_ResolvingBaseType,
|
||||||
BfTypeDefineState_HasInterfaces,
|
BfTypeDefineState_HasInterfaces,
|
||||||
|
BfTypeDefineState_CETypeInit,
|
||||||
|
BfTypeDefineState_CEPostTypeInit,
|
||||||
BfTypeDefineState_Defined,
|
BfTypeDefineState_Defined,
|
||||||
|
BfTypeDefineState_CEAfterFields,
|
||||||
BfTypeDefineState_DefinedAndMethodsSlotted,
|
BfTypeDefineState_DefinedAndMethodsSlotted,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -830,6 +835,7 @@ public:
|
||||||
bool mInCEMachine:1;
|
bool mInCEMachine:1;
|
||||||
bool mIsDisposed:1;
|
bool mIsDisposed:1;
|
||||||
BfMethodChainType mChainType;
|
BfMethodChainType mChainType;
|
||||||
|
BfComptimeFlags mComptimeFlags;
|
||||||
BfCallingConvention mCallingConvention;
|
BfCallingConvention mCallingConvention;
|
||||||
BfMethodInstanceGroup* mMethodInstanceGroup;
|
BfMethodInstanceGroup* mMethodInstanceGroup;
|
||||||
BfMethodDef* mMethodDef;
|
BfMethodDef* mMethodDef;
|
||||||
|
@ -868,6 +874,7 @@ public:
|
||||||
mInCEMachine = false;
|
mInCEMachine = false;
|
||||||
mIsDisposed = false;
|
mIsDisposed = false;
|
||||||
mChainType = BfMethodChainType_None;
|
mChainType = BfMethodChainType_None;
|
||||||
|
mComptimeFlags = BfComptimeFlag_None;
|
||||||
mCallingConvention = BfCallingConvention_Unspecified;
|
mCallingConvention = BfCallingConvention_Unspecified;
|
||||||
mMethodInstanceGroup = NULL;
|
mMethodInstanceGroup = NULL;
|
||||||
mMethodDef = NULL;
|
mMethodDef = NULL;
|
||||||
|
@ -1792,6 +1799,7 @@ public:
|
||||||
Array<BfMethodInstance*> mInternalMethods;
|
Array<BfMethodInstance*> mInternalMethods;
|
||||||
Dictionary<BfTypeDef*, BfStaticSearch> mStaticSearchMap;
|
Dictionary<BfTypeDef*, BfStaticSearch> mStaticSearchMap;
|
||||||
Dictionary<BfTypeDef*, BfInternalAccessSet> mInternalAccessMap;
|
Dictionary<BfTypeDef*, BfInternalAccessSet> mInternalAccessMap;
|
||||||
|
Array<BfLocalMethod*> mOwnedLocalMethods; // Local methods in CEMachine
|
||||||
bool mHasStaticInitMethod;
|
bool mHasStaticInitMethod;
|
||||||
bool mHasStaticDtorMethod;
|
bool mHasStaticDtorMethod;
|
||||||
bool mHasStaticMarkMethod;
|
bool mHasStaticMarkMethod;
|
||||||
|
@ -1969,7 +1977,7 @@ public:
|
||||||
bool IsAlwaysInclude();
|
bool IsAlwaysInclude();
|
||||||
bool HasBeenInstantiated() { return mHasBeenInstantiated || ((mAlwaysIncludeFlags & BfAlwaysIncludeFlag_AssumeInstantiated) != 0); }
|
bool HasBeenInstantiated() { return mHasBeenInstantiated || ((mAlwaysIncludeFlags & BfAlwaysIncludeFlag_AssumeInstantiated) != 0); }
|
||||||
bool IncludeAllMethods() { return ((mAlwaysIncludeFlags & BfAlwaysIncludeFlag_IncludeAllMethods) != 0); }
|
bool IncludeAllMethods() { return ((mAlwaysIncludeFlags & BfAlwaysIncludeFlag_IncludeAllMethods) != 0); }
|
||||||
|
bool DefineStateAllowsStaticMethods() { return mDefineState >= BfTypeDefineState_HasInterfaces; }
|
||||||
|
|
||||||
virtual void ReportMemory(MemReporter* memReporter) override;
|
virtual void ReportMemory(MemReporter* memReporter) override;
|
||||||
};
|
};
|
||||||
|
|
|
@ -91,7 +91,9 @@ int BfSource::AllocChars(int charCount)
|
||||||
|
|
||||||
BF_ASSERT(mSourceData->ToParser() != NULL);
|
BF_ASSERT(mSourceData->ToParser() != NULL);
|
||||||
mSourceData->mSrc = mSrc;
|
mSourceData->mSrc = mSrc;
|
||||||
}
|
|
||||||
|
HadSrcRealloc();
|
||||||
|
}
|
||||||
|
|
||||||
int retVal = mSrcLength;
|
int retVal = mSrcLength;
|
||||||
mSrcLength += charCount;
|
mSrcLength += charCount;
|
||||||
|
|
|
@ -101,6 +101,7 @@ public:
|
||||||
virtual ~BfSource();
|
virtual ~BfSource();
|
||||||
|
|
||||||
virtual BfParser* ToParser() { return NULL; }
|
virtual BfParser* ToParser() { return NULL; }
|
||||||
|
virtual void HadSrcRealloc() {}
|
||||||
|
|
||||||
BfErrorNode* CreateErrorNode(BfAstNode* astNode);
|
BfErrorNode* CreateErrorNode(BfAstNode* astNode);
|
||||||
void AddErrorNode(BfAstNode* astNode);
|
void AddErrorNode(BfAstNode* astNode);
|
||||||
|
|
|
@ -42,7 +42,7 @@ USING_NS_BF;
|
||||||
|
|
||||||
bool BfModule::AddDeferredCallEntry(BfDeferredCallEntry* deferredCallEntry, BfScopeData* scopeData)
|
bool BfModule::AddDeferredCallEntry(BfDeferredCallEntry* deferredCallEntry, BfScopeData* scopeData)
|
||||||
{
|
{
|
||||||
if ((((mCompiler->mIsResolveOnly) && (!mIsConstModule)) ||
|
if ((((mCompiler->mIsResolveOnly) && (!mIsComptimeModule)) ||
|
||||||
(mBfIRBuilder->mIgnoreWrites)) && (deferredCallEntry->mDeferredBlock == NULL))
|
(mBfIRBuilder->mIgnoreWrites)) && (deferredCallEntry->mDeferredBlock == NULL))
|
||||||
{
|
{
|
||||||
// For resolve entries, we only keep deferred blocks because we need to process them later so we can
|
// For resolve entries, we only keep deferred blocks because we need to process them later so we can
|
||||||
|
@ -783,7 +783,7 @@ void BfModule::EmitDeferredCall(BfModuleMethodInstance moduleMethodInstance, Siz
|
||||||
|
|
||||||
void BfModule::EmitDeferredCall(BfDeferredCallEntry& deferredCallEntry, bool moveBlocks)
|
void BfModule::EmitDeferredCall(BfDeferredCallEntry& deferredCallEntry, bool moveBlocks)
|
||||||
{
|
{
|
||||||
if ((mCompiler->mIsResolveOnly) && (!mIsConstModule) && (deferredCallEntry.mHandlerCount > 0))
|
if ((mCompiler->mIsResolveOnly) && (!mIsComptimeModule) && (deferredCallEntry.mHandlerCount > 0))
|
||||||
{
|
{
|
||||||
// We only want to process deferred blocks once, otherwise it could significantly slow down autocompletion
|
// We only want to process deferred blocks once, otherwise it could significantly slow down autocompletion
|
||||||
return;
|
return;
|
||||||
|
@ -1770,7 +1770,7 @@ BfLocalVariable* BfModule::HandleVariableDeclaration(BfVariableDeclaration* varD
|
||||||
initValue = LoadValue(initValue);
|
initValue = LoadValue(initValue);
|
||||||
if (initValue.IsSplat())
|
if (initValue.IsSplat())
|
||||||
{
|
{
|
||||||
BF_ASSERT(!mIsConstModule);
|
BF_ASSERT(!mIsComptimeModule);
|
||||||
if (!localDef->mAddr)
|
if (!localDef->mAddr)
|
||||||
localDef->mAddr = AllocLocalVariable(resolvedType, localDef->mName);
|
localDef->mAddr = AllocLocalVariable(resolvedType, localDef->mName);
|
||||||
AggregateSplatIntoAddr(initValue, localDef->mAddr);
|
AggregateSplatIntoAddr(initValue, localDef->mAddr);
|
||||||
|
@ -3944,7 +3944,7 @@ void BfModule::Visit(BfDeleteStatement* deleteStmt)
|
||||||
allowPrivate = false;
|
allowPrivate = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((mCompiler->mOptions.mObjectHasDebugFlags) && (!mIsConstModule))
|
if ((mCompiler->mOptions.mObjectHasDebugFlags) && (!mIsComptimeModule))
|
||||||
{
|
{
|
||||||
auto preDelete = GetInternalMethod((deleteStmt->mTargetTypeToken != NULL) ? "Dbg_ObjectPreCustomDelete" : "Dbg_ObjectPreDelete");
|
auto preDelete = GetInternalMethod((deleteStmt->mTargetTypeToken != NULL) ? "Dbg_ObjectPreCustomDelete" : "Dbg_ObjectPreDelete");
|
||||||
SizedArray<BfIRValue, 4> llvmArgs;
|
SizedArray<BfIRValue, 4> llvmArgs;
|
||||||
|
@ -4001,7 +4001,7 @@ void BfModule::Visit(BfDeleteStatement* deleteStmt)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if ((mCompiler->mOptions.mEnableRealtimeLeakCheck) && (!mIsConstModule))
|
if ((mCompiler->mOptions.mEnableRealtimeLeakCheck) && (!mIsComptimeModule))
|
||||||
{
|
{
|
||||||
SizedArray<BfIRValue, 4> llvmArgs;
|
SizedArray<BfIRValue, 4> llvmArgs;
|
||||||
llvmArgs.push_back(mBfIRBuilder->CreateBitCast(val.mValue, mBfIRBuilder->MapType(objectType)));
|
llvmArgs.push_back(mBfIRBuilder->CreateBitCast(val.mValue, mBfIRBuilder->MapType(objectType)));
|
||||||
|
@ -4958,12 +4958,12 @@ void BfModule::Visit(BfReturnStatement* returnStmt)
|
||||||
BfType* origType;
|
BfType* origType;
|
||||||
BfExprEvaluator exprEvaluator(this);
|
BfExprEvaluator exprEvaluator(this);
|
||||||
bool alreadyWritten = false;
|
bool alreadyWritten = false;
|
||||||
if ((!mIsConstModule) && (mCurMethodInstance->GetStructRetIdx() != -1))
|
if ((!mIsComptimeModule) && (mCurMethodInstance->GetStructRetIdx() != -1))
|
||||||
exprEvaluator.mReceivingValue = &mCurMethodState->mRetVal;
|
exprEvaluator.mReceivingValue = &mCurMethodState->mRetVal;
|
||||||
if (mCurMethodInstance->mMethodDef->mIsReadOnly)
|
if (mCurMethodInstance->mMethodDef->mIsReadOnly)
|
||||||
exprEvaluator.mAllowReadOnlyReference = true;
|
exprEvaluator.mAllowReadOnlyReference = true;
|
||||||
auto retValue = CreateValueFromExpression(exprEvaluator, returnStmt->mExpression, expectingReturnType, BfEvalExprFlags_AllowRefExpr, &origType);
|
auto retValue = CreateValueFromExpression(exprEvaluator, returnStmt->mExpression, expectingReturnType, BfEvalExprFlags_AllowRefExpr, &origType);
|
||||||
if ((!mIsConstModule) && (mCurMethodInstance->GetStructRetIdx() != -1))
|
if ((!mIsComptimeModule) && (mCurMethodInstance->GetStructRetIdx() != -1))
|
||||||
alreadyWritten = exprEvaluator.mReceivingValue == NULL;
|
alreadyWritten = exprEvaluator.mReceivingValue == NULL;
|
||||||
MarkScopeLeft(&mCurMethodState->mHeadScope);
|
MarkScopeLeft(&mCurMethodState->mHeadScope);
|
||||||
|
|
||||||
|
@ -6453,7 +6453,7 @@ void BfModule::Visit(BfForEachStatement* forEachStmt)
|
||||||
auto retVal = exprEvaluator.CreateCall(&methodMatcher, itr);
|
auto retVal = exprEvaluator.CreateCall(&methodMatcher, itr);
|
||||||
if (exprEvaluator.mReceivingValue != NULL)
|
if (exprEvaluator.mReceivingValue != NULL)
|
||||||
{
|
{
|
||||||
if (mIsConstModule)
|
if (mIsComptimeModule)
|
||||||
{
|
{
|
||||||
mBfIRBuilder->CreateStore(retVal.mValue, nextResult.mValue);
|
mBfIRBuilder->CreateStore(retVal.mValue, nextResult.mValue);
|
||||||
}
|
}
|
||||||
|
@ -6802,7 +6802,7 @@ void BfModule::Visit(BfDeferStatement* deferStmt)
|
||||||
|
|
||||||
if (!customAllocator)
|
if (!customAllocator)
|
||||||
{
|
{
|
||||||
if ((mCompiler->mOptions.mEnableRealtimeLeakCheck) && (!mIsConstModule))
|
if ((mCompiler->mOptions.mEnableRealtimeLeakCheck) && (!mIsComptimeModule))
|
||||||
{
|
{
|
||||||
auto moduleMethodInstance = GetInternalMethod("Dbg_MarkObjectDeleted");
|
auto moduleMethodInstance = GetInternalMethod("Dbg_MarkObjectDeleted");
|
||||||
AddDeferredCall(moduleMethodInstance, llvmArgs, scope, deleteStmt, false, true);
|
AddDeferredCall(moduleMethodInstance, llvmArgs, scope, deleteStmt, false, true);
|
||||||
|
@ -6819,7 +6819,7 @@ void BfModule::Visit(BfDeferStatement* deferStmt)
|
||||||
auto moduleMethodInstance = GetMethodInstance(objectType, methodInstance->mMethodDef, BfTypeVector());
|
auto moduleMethodInstance = GetMethodInstance(objectType, methodInstance->mMethodDef, BfTypeVector());
|
||||||
AddDeferredCall(moduleMethodInstance, llvmArgs, scope, deleteStmt, false, true);
|
AddDeferredCall(moduleMethodInstance, llvmArgs, scope, deleteStmt, false, true);
|
||||||
|
|
||||||
if ((mCompiler->mOptions.mObjectHasDebugFlags) && (!mIsConstModule))
|
if ((mCompiler->mOptions.mObjectHasDebugFlags) && (!mIsComptimeModule))
|
||||||
{
|
{
|
||||||
auto moduleMethodInstance = GetMethodByName(internalType->ToTypeInstance(), (deleteStmt->mTargetTypeToken != NULL) ? "Dbg_ObjectPreCustomDelete" : "Dbg_ObjectPreDelete");
|
auto moduleMethodInstance = GetMethodByName(internalType->ToTypeInstance(), (deleteStmt->mTargetTypeToken != NULL) ? "Dbg_ObjectPreCustomDelete" : "Dbg_ObjectPreDelete");
|
||||||
AddDeferredCall(moduleMethodInstance, llvmArgs, scope, deleteStmt, false, true);
|
AddDeferredCall(moduleMethodInstance, llvmArgs, scope, deleteStmt, false, true);
|
||||||
|
@ -6831,7 +6831,7 @@ void BfModule::Visit(BfDeferStatement* deferStmt)
|
||||||
{
|
{
|
||||||
val = LoadValue(val);
|
val = LoadValue(val);
|
||||||
BfModuleMethodInstance moduleMethodInstance;
|
BfModuleMethodInstance moduleMethodInstance;
|
||||||
if ((mCompiler->mOptions.mDebugAlloc) && (!mIsConstModule))
|
if ((mCompiler->mOptions.mDebugAlloc) && (!mIsComptimeModule))
|
||||||
moduleMethodInstance = GetMethodByName(internalType->ToTypeInstance(), "Dbg_RawFree");
|
moduleMethodInstance = GetMethodByName(internalType->ToTypeInstance(), "Dbg_RawFree");
|
||||||
else
|
else
|
||||||
moduleMethodInstance = GetMethodByName(internalType->ToTypeInstance(), "Free");
|
moduleMethodInstance = GetMethodByName(internalType->ToTypeInstance(), "Free");
|
||||||
|
|
|
@ -679,6 +679,42 @@ void BfTypeDef::FreeMembers()
|
||||||
mIsNextRevision = false;
|
mIsNextRevision = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void BfTypeDef::ClearEmitted()
|
||||||
|
{
|
||||||
|
for (auto& partial : mPartials)
|
||||||
|
partial->ClearEmitted();
|
||||||
|
|
||||||
|
if (mEmitParser != NULL)
|
||||||
|
{
|
||||||
|
mEmitParser->mRefCount--;
|
||||||
|
BF_ASSERT(mEmitParser->mRefCount >= 0);
|
||||||
|
mEmitParser = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mHasEmitMembers)
|
||||||
|
{
|
||||||
|
for (int methodIdx = (int)mMethods.size() - 1; methodIdx >= 0; methodIdx--)
|
||||||
|
{
|
||||||
|
auto methodDef = mMethods[methodIdx];
|
||||||
|
if ((methodDef->mMethodDeclaration != NULL) && (methodDef->mMethodDeclaration->IsEmitted()))
|
||||||
|
{
|
||||||
|
delete methodDef;
|
||||||
|
mMethods.RemoveAt(methodIdx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int fieldIdx = (int)mFields.size() - 1; fieldIdx >= 0; fieldIdx--)
|
||||||
|
{
|
||||||
|
auto fieldDef = mFields[fieldIdx];
|
||||||
|
if ((fieldDef->mFieldDeclaration != NULL) && (fieldDef->mFieldDeclaration->IsEmitted()))
|
||||||
|
{
|
||||||
|
delete fieldDef;
|
||||||
|
mFields.RemoveAt(fieldIdx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void BfTypeDef::PopulateMemberSets()
|
void BfTypeDef::PopulateMemberSets()
|
||||||
{
|
{
|
||||||
if ((!mMethodSet.IsEmpty()) || (!mFieldSet.IsEmpty()) || (!mPropertySet.IsEmpty()))
|
if ((!mMethodSet.IsEmpty()) || (!mFieldSet.IsEmpty()) || (!mPropertySet.IsEmpty()))
|
||||||
|
@ -721,6 +757,13 @@ void BfTypeDef::PopulateMemberSets()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void BfTypeDef::ClearMemberSets()
|
||||||
|
{
|
||||||
|
mMethodSet.Clear();
|
||||||
|
mFieldSet.Clear();
|
||||||
|
mPropertySet.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
BfTypeDef::~BfTypeDef()
|
BfTypeDef::~BfTypeDef()
|
||||||
{
|
{
|
||||||
BfLogSysM("BfTypeDef::~BfTypeDef %08X\n", this);
|
BfLogSysM("BfTypeDef::~BfTypeDef %08X\n", this);
|
||||||
|
@ -732,6 +775,12 @@ BfTypeDef::~BfTypeDef()
|
||||||
mSource->mRefCount--;
|
mSource->mRefCount--;
|
||||||
BF_ASSERT(mSource->mRefCount >= 0);
|
BF_ASSERT(mSource->mRefCount >= 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (mEmitParser != NULL)
|
||||||
|
{
|
||||||
|
mEmitParser->mRefCount--;
|
||||||
|
BF_ASSERT(mEmitParser->mRefCount >= 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
BfSource* BfTypeDef::GetLastSource()
|
BfSource* BfTypeDef::GetLastSource()
|
||||||
|
@ -1533,6 +1582,8 @@ BfError* BfPassInstance::WarnAt(int warningNumber, const StringImpl& warning, Bf
|
||||||
if (!WantsRangeRecorded(bfParser, srcIdx, srcLen, true))
|
if (!WantsRangeRecorded(bfParser, srcIdx, srcLen, true))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
mWarnIdx++;
|
||||||
|
|
||||||
TrimSourceRange(bfSource, srcIdx, srcLen);
|
TrimSourceRange(bfSource, srcIdx, srcLen);
|
||||||
|
|
||||||
BfError* errorVal = new BfError();
|
BfError* errorVal = new BfError();
|
||||||
|
@ -1564,6 +1615,7 @@ BfError* BfPassInstance::WarnAt(int warningNumber, const StringImpl& warning, Bf
|
||||||
|
|
||||||
BfError* BfPassInstance::Warn(int warningNumber, const StringImpl& warning)
|
BfError* BfPassInstance::Warn(int warningNumber, const StringImpl& warning)
|
||||||
{
|
{
|
||||||
|
mWarnIdx++;
|
||||||
mLastWasAdded = false;
|
mLastWasAdded = false;
|
||||||
mLastWasDisplayed = (int)mErrors.size() <= sMaxDisplayErrors;
|
mLastWasDisplayed = (int)mErrors.size() <= sMaxDisplayErrors;
|
||||||
if (!mLastWasDisplayed)
|
if (!mLastWasDisplayed)
|
||||||
|
@ -1577,6 +1629,7 @@ BfError* BfPassInstance::Warn(int warningNumber, const StringImpl& warning, BfAs
|
||||||
{
|
{
|
||||||
BP_ZONE("BfPassInstance::Warn");
|
BP_ZONE("BfPassInstance::Warn");
|
||||||
|
|
||||||
|
mWarnIdx++;
|
||||||
mLastWasAdded = false;
|
mLastWasAdded = false;
|
||||||
mLastWasDisplayed = (int)mErrors.size() <= sMaxErrors;
|
mLastWasDisplayed = (int)mErrors.size() <= sMaxErrors;
|
||||||
if (!mLastWasDisplayed)
|
if (!mLastWasDisplayed)
|
||||||
|
@ -1638,9 +1691,9 @@ BfMoreInfo* BfPassInstance::MoreInfoAt(const StringImpl& info, BfSourceData* bfS
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
BfMoreInfo* BfPassInstance::MoreInfo(const StringImpl& info)
|
BfMoreInfo* BfPassInstance::MoreInfo(const StringImpl& info, bool forceQueue)
|
||||||
{
|
{
|
||||||
if (!mLastWasDisplayed)
|
if ((!mLastWasDisplayed) || (forceQueue))
|
||||||
{
|
{
|
||||||
if (mLastWasAdded)
|
if (mLastWasAdded)
|
||||||
{
|
{
|
||||||
|
@ -2534,6 +2587,8 @@ void BfSystem::InjectNewRevision(BfTypeDef* typeDef)
|
||||||
{
|
{
|
||||||
BfLogSys(this, "InjectNewRevision from %p (decl:%p) into %p (decl:%p)\n", typeDef->mNextRevision, typeDef->mNextRevision->mTypeDeclaration, typeDef, typeDef->mTypeDeclaration);
|
BfLogSys(this, "InjectNewRevision from %p (decl:%p) into %p (decl:%p)\n", typeDef->mNextRevision, typeDef->mNextRevision->mTypeDeclaration, typeDef, typeDef->mTypeDeclaration);
|
||||||
|
|
||||||
|
typeDef->ClearEmitted();
|
||||||
|
|
||||||
bool setDeclaringType = !typeDef->mIsCombinedPartial;
|
bool setDeclaringType = !typeDef->mIsCombinedPartial;
|
||||||
|
|
||||||
auto nextTypeDef = typeDef->mNextRevision;
|
auto nextTypeDef = typeDef->mNextRevision;
|
||||||
|
@ -2651,7 +2706,7 @@ void BfSystem::InjectNewRevision(BfTypeDef* typeDef)
|
||||||
typeDef->mTypeCode = nextTypeDef->mTypeCode;
|
typeDef->mTypeCode = nextTypeDef->mTypeCode;
|
||||||
|
|
||||||
typeDef->mIsAlwaysInclude = nextTypeDef->mIsAlwaysInclude;
|
typeDef->mIsAlwaysInclude = nextTypeDef->mIsAlwaysInclude;
|
||||||
typeDef->mIsNoDiscard = nextTypeDef->mIsNoDiscard;
|
typeDef->mIsNoDiscard = nextTypeDef->mIsNoDiscard;
|
||||||
typeDef->mIsPartial = nextTypeDef->mIsPartial;
|
typeDef->mIsPartial = nextTypeDef->mIsPartial;
|
||||||
typeDef->mIsExplicitPartial = nextTypeDef->mIsExplicitPartial;
|
typeDef->mIsExplicitPartial = nextTypeDef->mIsExplicitPartial;
|
||||||
//mPartialUsed
|
//mPartialUsed
|
||||||
|
@ -2663,6 +2718,7 @@ void BfSystem::InjectNewRevision(BfTypeDef* typeDef)
|
||||||
typeDef->mIsConcrete = nextTypeDef->mIsConcrete;
|
typeDef->mIsConcrete = nextTypeDef->mIsConcrete;
|
||||||
typeDef->mIsStatic = nextTypeDef->mIsStatic;
|
typeDef->mIsStatic = nextTypeDef->mIsStatic;
|
||||||
typeDef->mHasAppendCtor = nextTypeDef->mHasAppendCtor;
|
typeDef->mHasAppendCtor = nextTypeDef->mHasAppendCtor;
|
||||||
|
typeDef->mHasCEOnCompile = nextTypeDef->mHasCEOnCompile;
|
||||||
typeDef->mHasCtorNoBody = nextTypeDef->mHasCtorNoBody;
|
typeDef->mHasCtorNoBody = nextTypeDef->mHasCtorNoBody;
|
||||||
typeDef->mHasOverrideMethods = nextTypeDef->mHasOverrideMethods;
|
typeDef->mHasOverrideMethods = nextTypeDef->mHasOverrideMethods;
|
||||||
typeDef->mHasExtensionMethods = nextTypeDef->mHasExtensionMethods;
|
typeDef->mHasExtensionMethods = nextTypeDef->mHasExtensionMethods;
|
||||||
|
@ -2722,7 +2778,7 @@ void BfSystem::InjectNewRevision(BfTypeDef* typeDef)
|
||||||
delete nextTypeDef;
|
delete nextTypeDef;
|
||||||
typeDef->mNextRevision = NULL;
|
typeDef->mNextRevision = NULL;
|
||||||
|
|
||||||
typeDef->mDefState = BfTypeDef::DefState_Defined;
|
typeDef->mDefState = BfTypeDef::DefState_Defined;
|
||||||
|
|
||||||
VerifyTypeDef(typeDef);
|
VerifyTypeDef(typeDef);
|
||||||
}
|
}
|
||||||
|
@ -2771,6 +2827,8 @@ void BfSystem::AddToCompositePartial(BfPassInstance* passInstance, BfTypeDef* co
|
||||||
typeDef->mHasCtorNoBody = partialTypeDef->mHasCtorNoBody;
|
typeDef->mHasCtorNoBody = partialTypeDef->mHasCtorNoBody;
|
||||||
typeDef->mHasExtensionMethods = partialTypeDef->mHasExtensionMethods;
|
typeDef->mHasExtensionMethods = partialTypeDef->mHasExtensionMethods;
|
||||||
typeDef->mHasOverrideMethods = partialTypeDef->mHasOverrideMethods;
|
typeDef->mHasOverrideMethods = partialTypeDef->mHasOverrideMethods;
|
||||||
|
typeDef->mIsAlwaysInclude = partialTypeDef->mIsAlwaysInclude;
|
||||||
|
typeDef->mHasCEOnCompile = partialTypeDef->mHasCEOnCompile;
|
||||||
|
|
||||||
for (auto generic : partialTypeDef->mGenericParamDefs)
|
for (auto generic : partialTypeDef->mGenericParamDefs)
|
||||||
{
|
{
|
||||||
|
@ -2806,6 +2864,7 @@ void BfSystem::AddToCompositePartial(BfPassInstance* passInstance, BfTypeDef* co
|
||||||
typeDef->mIsConcrete |= partialTypeDef->mIsConcrete;
|
typeDef->mIsConcrete |= partialTypeDef->mIsConcrete;
|
||||||
typeDef->mIsStatic |= partialTypeDef->mIsStatic;
|
typeDef->mIsStatic |= partialTypeDef->mIsStatic;
|
||||||
typeDef->mHasAppendCtor |= partialTypeDef->mHasAppendCtor;
|
typeDef->mHasAppendCtor |= partialTypeDef->mHasAppendCtor;
|
||||||
|
typeDef->mHasCEOnCompile |= partialTypeDef->mHasCEOnCompile;
|
||||||
typeDef->mHasExtensionMethods |= partialTypeDef->mHasExtensionMethods;
|
typeDef->mHasExtensionMethods |= partialTypeDef->mHasExtensionMethods;
|
||||||
typeDef->mHasOverrideMethods |= partialTypeDef->mHasOverrideMethods;
|
typeDef->mHasOverrideMethods |= partialTypeDef->mHasOverrideMethods;
|
||||||
typeDef->mProtection = BF_MIN(typeDef->mProtection, partialTypeDef->mProtection);
|
typeDef->mProtection = BF_MIN(typeDef->mProtection, partialTypeDef->mProtection);
|
||||||
|
@ -3237,12 +3296,12 @@ void BfSystem::RemoveOldParsers()
|
||||||
|
|
||||||
BfLogSys(this, "Deleting Old Parser: %p New Parser: %p\n", bfParser, bfParser->mNextRevision);
|
BfLogSys(this, "Deleting Old Parser: %p New Parser: %p\n", bfParser, bfParser->mNextRevision);
|
||||||
|
|
||||||
|
mParsers.RemoveAt(i);
|
||||||
|
i--;
|
||||||
|
|
||||||
mDataLock.Unlock();
|
mDataLock.Unlock();
|
||||||
delete bfParser;
|
delete bfParser;
|
||||||
mDataLock.Lock();
|
mDataLock.Lock();
|
||||||
|
|
||||||
mParsers.erase(mParsers.begin() + i);
|
|
||||||
i--;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -218,6 +218,13 @@ enum BfAlwaysIncludeFlags : uint8
|
||||||
BfAlwaysIncludeFlag_All = BfAlwaysIncludeFlag_Type | BfAlwaysIncludeFlag_IncludeAllMethods | BfAlwaysIncludeFlag_AssumeInstantiated
|
BfAlwaysIncludeFlag_All = BfAlwaysIncludeFlag_Type | BfAlwaysIncludeFlag_IncludeAllMethods | BfAlwaysIncludeFlag_AssumeInstantiated
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum BfCEOnCompileKind : uint8
|
||||||
|
{
|
||||||
|
BfCEOnCompileKind_None,
|
||||||
|
BfCEOnCompileKind_TypeInit,
|
||||||
|
BfCEOnCompileKind_TypeDone
|
||||||
|
};
|
||||||
|
|
||||||
enum BfPlatformType
|
enum BfPlatformType
|
||||||
{
|
{
|
||||||
BfPlatformType_Unknown,
|
BfPlatformType_Unknown,
|
||||||
|
@ -740,6 +747,14 @@ enum BfCommutableKind : int8
|
||||||
BfCommutableKind_Reverse,
|
BfCommutableKind_Reverse,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum BfComptimeFlags : int8
|
||||||
|
{
|
||||||
|
BfComptimeFlag_None,
|
||||||
|
BfComptimeFlag_Comptime = 1,
|
||||||
|
BfComptimeFlag_OnlyFromComptime = 2,
|
||||||
|
BfComptimeFlag_ConstEval = 4
|
||||||
|
};
|
||||||
|
|
||||||
class BfMethodDef : public BfMemberDef
|
class BfMethodDef : public BfMemberDef
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -774,7 +789,7 @@ public:
|
||||||
bool mIsNoSplat;
|
bool mIsNoSplat;
|
||||||
bool mIsNoReflect;
|
bool mIsNoReflect;
|
||||||
bool mIsSkipCall;
|
bool mIsSkipCall;
|
||||||
bool mIsConstEval;
|
bool mHasComptime;
|
||||||
bool mIsOperator;
|
bool mIsOperator;
|
||||||
bool mIsExtern;
|
bool mIsExtern;
|
||||||
bool mIsNoDiscard;
|
bool mIsNoDiscard;
|
||||||
|
@ -803,7 +818,7 @@ public:
|
||||||
mIsNoSplat = false;
|
mIsNoSplat = false;
|
||||||
mIsNoReflect = false;
|
mIsNoReflect = false;
|
||||||
mIsSkipCall = false;
|
mIsSkipCall = false;
|
||||||
mIsConstEval = false;
|
mHasComptime = false;
|
||||||
mIsOperator = false;
|
mIsOperator = false;
|
||||||
mIsExtern = false;
|
mIsExtern = false;
|
||||||
mIsNoDiscard = false;
|
mIsNoDiscard = false;
|
||||||
|
@ -914,11 +929,12 @@ public:
|
||||||
|
|
||||||
public:
|
public:
|
||||||
BfTypeDef* mNextRevision;
|
BfTypeDef* mNextRevision;
|
||||||
|
|
||||||
BfSystem* mSystem;
|
BfSystem* mSystem;
|
||||||
BfProject* mProject;
|
BfProject* mProject;
|
||||||
BfTypeDeclaration* mTypeDeclaration;
|
BfTypeDeclaration* mTypeDeclaration;
|
||||||
BfSource* mSource;
|
BfSource* mSource;
|
||||||
|
BfParser* mEmitParser;
|
||||||
DefState mDefState;
|
DefState mDefState;
|
||||||
Val128 mSignatureHash; // Data, methods, etc
|
Val128 mSignatureHash; // Data, methods, etc
|
||||||
Val128 mFullHash;
|
Val128 mFullHash;
|
||||||
|
@ -953,7 +969,7 @@ public:
|
||||||
int mPartialIdx;
|
int mPartialIdx;
|
||||||
int mNestDepth;
|
int mNestDepth;
|
||||||
int mDupDetectedRevision; // Error state
|
int mDupDetectedRevision; // Error state
|
||||||
BfTypeCode mTypeCode;
|
BfTypeCode mTypeCode;
|
||||||
bool mIsAlwaysInclude;
|
bool mIsAlwaysInclude;
|
||||||
bool mIsNoDiscard;
|
bool mIsNoDiscard;
|
||||||
bool mIsPartial;
|
bool mIsPartial;
|
||||||
|
@ -966,6 +982,7 @@ public:
|
||||||
bool mIsAbstract;
|
bool mIsAbstract;
|
||||||
bool mIsConcrete;
|
bool mIsConcrete;
|
||||||
bool mIsStatic;
|
bool mIsStatic;
|
||||||
|
bool mHasCEOnCompile;
|
||||||
bool mHasAppendCtor;
|
bool mHasAppendCtor;
|
||||||
bool mHasCtorNoBody;
|
bool mHasCtorNoBody;
|
||||||
bool mHasExtensionMethods;
|
bool mHasExtensionMethods;
|
||||||
|
@ -973,6 +990,7 @@ public:
|
||||||
bool mIsOpaque;
|
bool mIsOpaque;
|
||||||
bool mIsNextRevision;
|
bool mIsNextRevision;
|
||||||
bool mInDeleteQueue;
|
bool mInDeleteQueue;
|
||||||
|
bool mHasEmitMembers;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
BfTypeDef()
|
BfTypeDef()
|
||||||
|
@ -988,7 +1006,7 @@ public:
|
||||||
mNameEx = NULL;
|
mNameEx = NULL;
|
||||||
mSystem = NULL;
|
mSystem = NULL;
|
||||||
mProject = NULL;
|
mProject = NULL;
|
||||||
mTypeCode = BfTypeCode_None;
|
mTypeCode = BfTypeCode_None;
|
||||||
mIsAlwaysInclude = false;
|
mIsAlwaysInclude = false;
|
||||||
mIsNoDiscard = false;
|
mIsNoDiscard = false;
|
||||||
mIsExplicitPartial = false;
|
mIsExplicitPartial = false;
|
||||||
|
@ -996,6 +1014,7 @@ public:
|
||||||
mIsCombinedPartial = false;
|
mIsCombinedPartial = false;
|
||||||
mTypeDeclaration = NULL;
|
mTypeDeclaration = NULL;
|
||||||
mSource = NULL;
|
mSource = NULL;
|
||||||
|
mEmitParser = NULL;
|
||||||
mDefState = DefState_New;
|
mDefState = DefState_New;
|
||||||
mHash = 0;
|
mHash = 0;
|
||||||
mPartialIdx = -1;
|
mPartialIdx = -1;
|
||||||
|
@ -1005,6 +1024,7 @@ public:
|
||||||
mIsFunction = false;
|
mIsFunction = false;
|
||||||
mIsClosure = false;
|
mIsClosure = false;
|
||||||
mIsStatic = false;
|
mIsStatic = false;
|
||||||
|
mHasCEOnCompile = false;
|
||||||
mHasAppendCtor = false;
|
mHasAppendCtor = false;
|
||||||
mHasCtorNoBody = false;
|
mHasCtorNoBody = false;
|
||||||
mHasExtensionMethods = false;
|
mHasExtensionMethods = false;
|
||||||
|
@ -1013,12 +1033,13 @@ public:
|
||||||
mPartialUsed = false;
|
mPartialUsed = false;
|
||||||
mIsNextRevision = false;
|
mIsNextRevision = false;
|
||||||
mInDeleteQueue = false;
|
mInDeleteQueue = false;
|
||||||
|
mHasEmitMembers = false;
|
||||||
mDupDetectedRevision = -1;
|
mDupDetectedRevision = -1;
|
||||||
mNestDepth = 0;
|
mNestDepth = 0;
|
||||||
mOuterType = NULL;
|
mOuterType = NULL;
|
||||||
mTypeDeclaration = NULL;
|
mTypeDeclaration = NULL;
|
||||||
mDtorDef = NULL;
|
mDtorDef = NULL;
|
||||||
mNextRevision = NULL;
|
mNextRevision = NULL;
|
||||||
mProtection = BfProtection_Public;
|
mProtection = BfProtection_Public;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1026,7 +1047,9 @@ public:
|
||||||
bool IsGlobalsContainer();
|
bool IsGlobalsContainer();
|
||||||
void Reset();
|
void Reset();
|
||||||
void FreeMembers();
|
void FreeMembers();
|
||||||
|
void ClearEmitted();
|
||||||
void PopulateMemberSets();
|
void PopulateMemberSets();
|
||||||
|
void ClearMemberSets();
|
||||||
void RemoveGenericParamDef(BfGenericParamDef* genericParamDef);
|
void RemoveGenericParamDef(BfGenericParamDef* genericParamDef);
|
||||||
int GetSelfGenericParamCount();
|
int GetSelfGenericParamCount();
|
||||||
String ToString();
|
String ToString();
|
||||||
|
@ -1284,12 +1307,13 @@ public:
|
||||||
BfSystem* mSystem;
|
BfSystem* mSystem;
|
||||||
bool mTrimMessagesToCursor;
|
bool mTrimMessagesToCursor;
|
||||||
int mFailedIdx;
|
int mFailedIdx;
|
||||||
|
int mWarnIdx;
|
||||||
|
|
||||||
Dictionary<BfSourceData*, String> mSourceFileNameMap;
|
Dictionary<BfSourceData*, String> mSourceFileNameMap;
|
||||||
HashSet<BfErrorEntry> mErrorSet;
|
HashSet<BfErrorEntry> mErrorSet;
|
||||||
Array<BfError*> mErrors;
|
Array<BfError*> mErrors;
|
||||||
int mIgnoreCount;
|
int mIgnoreCount;
|
||||||
int mWarningCount;
|
int mWarningCount;
|
||||||
int mDeferredErrorCount;
|
int mDeferredErrorCount;
|
||||||
Deque<String> mOutStream;
|
Deque<String> mOutStream;
|
||||||
bool mLastWasDisplayed;
|
bool mLastWasDisplayed;
|
||||||
|
@ -1303,11 +1327,12 @@ public:
|
||||||
{
|
{
|
||||||
mTrimMessagesToCursor = false;
|
mTrimMessagesToCursor = false;
|
||||||
mFailedIdx = 0;
|
mFailedIdx = 0;
|
||||||
|
mWarnIdx = 0;
|
||||||
mSystem = bfSystem;
|
mSystem = bfSystem;
|
||||||
mLastWasDisplayed = false;
|
mLastWasDisplayed = false;
|
||||||
mLastWasAdded = false;
|
mLastWasAdded = false;
|
||||||
mClassifierPassId = 0;
|
mClassifierPassId = 0;
|
||||||
mWarningCount = 0;
|
mWarningCount = 0;
|
||||||
mDeferredErrorCount = 0;
|
mDeferredErrorCount = 0;
|
||||||
mIgnoreCount = 0;
|
mIgnoreCount = 0;
|
||||||
mFilterErrorsTo = NULL;
|
mFilterErrorsTo = NULL;
|
||||||
|
@ -1336,7 +1361,7 @@ public:
|
||||||
BfError* WarnAfter(int warningNumber, const StringImpl& warning, BfAstNode* refNode);
|
BfError* WarnAfter(int warningNumber, const StringImpl& warning, BfAstNode* refNode);
|
||||||
|
|
||||||
BfMoreInfo* MoreInfoAt(const StringImpl& info, BfSourceData* bfSource, int srcIdx, int srcLen, BfFailFlags flags = BfFailFlag_None);
|
BfMoreInfo* MoreInfoAt(const StringImpl& info, BfSourceData* bfSource, int srcIdx, int srcLen, BfFailFlags flags = BfFailFlag_None);
|
||||||
BfMoreInfo* MoreInfo(const StringImpl& info);
|
BfMoreInfo* MoreInfo(const StringImpl& info, bool forceQueue = false);
|
||||||
BfMoreInfo* MoreInfo(const StringImpl& info, BfAstNode* refNode);
|
BfMoreInfo* MoreInfo(const StringImpl& info, BfAstNode* refNode);
|
||||||
BfMoreInfo* MoreInfoAfter(const StringImpl& info, BfAstNode* refNode);
|
BfMoreInfo* MoreInfoAfter(const StringImpl& info, BfAstNode* refNode);
|
||||||
|
|
||||||
|
|
|
@ -728,8 +728,7 @@ CeOperand CeBuilder::GetOperand(BeValue* value, bool allowAlloca, bool allowImme
|
||||||
CeStaticFieldInfo* staticFieldInfoPtr = NULL;
|
CeStaticFieldInfo* staticFieldInfoPtr = NULL;
|
||||||
if (mCeMachine->mStaticFieldMap.TryGetValue(globalVar->mName, &staticFieldInfoPtr))
|
if (mCeMachine->mStaticFieldMap.TryGetValue(globalVar->mName, &staticFieldInfoPtr))
|
||||||
{
|
{
|
||||||
CeStaticFieldInfo* staticFieldInfo = staticFieldInfoPtr;
|
CeStaticFieldInfo* staticFieldInfo = staticFieldInfoPtr;
|
||||||
|
|
||||||
int* staticFieldTableIdxPtr = NULL;
|
int* staticFieldTableIdxPtr = NULL;
|
||||||
if (mStaticFieldMap.TryAdd(globalVar, NULL, &staticFieldTableIdxPtr))
|
if (mStaticFieldMap.TryAdd(globalVar, NULL, &staticFieldTableIdxPtr))
|
||||||
{
|
{
|
||||||
|
@ -1190,8 +1189,6 @@ void CeBuilder::Build()
|
||||||
|
|
||||||
bool isGenericVariation = (methodInstance->mIsUnspecializedVariation) || (methodInstance->GetOwner()->IsUnspecializedTypeVariation());
|
bool isGenericVariation = (methodInstance->mIsUnspecializedVariation) || (methodInstance->GetOwner()->IsUnspecializedTypeVariation());
|
||||||
int dependentGenericStartIdx = 0;
|
int dependentGenericStartIdx = 0;
|
||||||
if (methodInstance->mMethodInfoEx != NULL)
|
|
||||||
dependentGenericStartIdx = (int)methodInstance->mMethodInfoEx->mMethodGenericArguments.size();
|
|
||||||
if ((((methodInstance->mMethodInfoEx != NULL) && ((int)methodInstance->mMethodInfoEx->mMethodGenericArguments.size() > dependentGenericStartIdx)) ||
|
if ((((methodInstance->mMethodInfoEx != NULL) && ((int)methodInstance->mMethodInfoEx->mMethodGenericArguments.size() > dependentGenericStartIdx)) ||
|
||||||
((methodInstance->GetOwner()->IsGenericTypeInstance()) && (!isGenericVariation) && (!methodInstance->mMethodDef->mIsLocalMethod))))
|
((methodInstance->GetOwner()->IsGenericTypeInstance()) && (!isGenericVariation) && (!methodInstance->mMethodDef->mIsLocalMethod))))
|
||||||
{
|
{
|
||||||
|
@ -2646,13 +2643,17 @@ CeMachine::CeMachine(BfCompiler* compiler)
|
||||||
mCurFunctionId = 0;
|
mCurFunctionId = 0;
|
||||||
mRevisionExecuteTime = 0;
|
mRevisionExecuteTime = 0;
|
||||||
mCurTargetSrc = NULL;
|
mCurTargetSrc = NULL;
|
||||||
|
mCurBuilder = NULL;
|
||||||
mPreparingFunction = NULL;
|
mPreparingFunction = NULL;
|
||||||
|
mCurEvalFlags = CeEvalFlags_None;
|
||||||
|
mCurFrame = NULL;
|
||||||
mCurModule = NULL;
|
mCurModule = NULL;
|
||||||
mCurMethodInstance = NULL;
|
mCurMethodInstance = NULL;
|
||||||
mCurExpectingType = NULL;
|
mCurExpectingType = NULL;
|
||||||
|
mCurEmitContext = NULL;
|
||||||
mHeap = NULL;
|
mHeap = NULL;
|
||||||
mStringCharsOffset = -1;
|
mStringCharsOffset = -1;
|
||||||
mAppendAllocInfo = NULL;
|
mAppendAllocInfo = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
CeMachine::~CeMachine()
|
CeMachine::~CeMachine()
|
||||||
|
@ -2689,19 +2690,25 @@ CeMachine::~CeMachine()
|
||||||
|
|
||||||
BfError* CeMachine::Fail(const StringImpl& error)
|
BfError* CeMachine::Fail(const StringImpl& error)
|
||||||
{
|
{
|
||||||
auto bfError = mCurModule->Fail(StrFormat("Unable to const-evaluate %s", mCurModule->MethodToString(mCurMethodInstance).c_str()), mCurTargetSrc);
|
auto bfError = mCurModule->Fail(StrFormat("Unable to comptime %s", mCurModule->MethodToString(mCurMethodInstance).c_str()), mCurTargetSrc, (mCurEvalFlags & CeEvalFlags_PersistantError) != 0);
|
||||||
if (bfError == NULL)
|
if (bfError == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
mCompiler->mPassInstance->MoreInfo(error);
|
mCompiler->mPassInstance->MoreInfo(error, mCeModule->mCompiler->GetAutoComplete() != NULL);
|
||||||
return bfError;
|
return bfError;
|
||||||
}
|
}
|
||||||
|
|
||||||
BfError* CeMachine::Fail(const CeFrame& curFrame, const StringImpl& str)
|
BfError* CeMachine::Fail(const CeFrame& curFrame, const StringImpl& str)
|
||||||
{
|
{
|
||||||
auto bfError = mCurModule->Fail(StrFormat("Unable to const-evaluate %s", mCurModule->MethodToString(mCurMethodInstance).c_str()), mCurTargetSrc);
|
auto bfError = mCurModule->Fail(StrFormat("Unable to comptime %s", mCurModule->MethodToString(mCurMethodInstance).c_str()), mCurTargetSrc, (mCurEvalFlags & CeEvalFlags_PersistantError) != 0);
|
||||||
if (bfError == NULL)
|
if (bfError == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
if ((mCurEvalFlags & CeEvalFlags_DeferIfNotOnlyError) != 0)
|
||||||
|
{
|
||||||
|
if (mCurModule->mHadBuildError)
|
||||||
|
bfError->mIsDeferred = true;
|
||||||
|
}
|
||||||
|
|
||||||
auto passInstance = mCompiler->mPassInstance;
|
auto passInstance = mCompiler->mPassInstance;
|
||||||
|
|
||||||
for (int stackIdx = mCallStack.size(); stackIdx >= 0; stackIdx--)
|
for (int stackIdx = mCallStack.size(); stackIdx >= 0; stackIdx--)
|
||||||
|
@ -2748,7 +2755,7 @@ BfError* CeMachine::Fail(const CeFrame& curFrame, const StringImpl& str)
|
||||||
contextMethodInstance = func->mCeFunctionInfo->mMethodInstance;
|
contextMethodInstance = func->mCeFunctionInfo->mMethodInstance;
|
||||||
}
|
}
|
||||||
|
|
||||||
err += StrFormat("in const evaluation of ");
|
err += StrFormat("in comptime ");
|
||||||
|
|
||||||
//
|
//
|
||||||
{
|
{
|
||||||
|
@ -2766,7 +2773,7 @@ BfError* CeMachine::Fail(const CeFrame& curFrame, const StringImpl& str)
|
||||||
if (emitEntry != NULL)
|
if (emitEntry != NULL)
|
||||||
err += StrFormat(" at line% d:%d in %s", emitEntry->mLine + 1, emitEntry->mColumn + 1, ceFunction->mFiles[emitEntry->mFile].c_str());
|
err += StrFormat(" at line% d:%d in %s", emitEntry->mLine + 1, emitEntry->mColumn + 1, ceFunction->mFiles[emitEntry->mFile].c_str());
|
||||||
|
|
||||||
auto moreInfo = passInstance->MoreInfo(err);
|
auto moreInfo = passInstance->MoreInfo(err, mCeModule->mCompiler->GetAutoComplete() != NULL);
|
||||||
if ((moreInfo != NULL) && (emitEntry != NULL))
|
if ((moreInfo != NULL) && (emitEntry != NULL))
|
||||||
{
|
{
|
||||||
BfErrorLocation* location = new BfErrorLocation();
|
BfErrorLocation* location = new BfErrorLocation();
|
||||||
|
@ -2785,7 +2792,7 @@ void CeMachine::Init()
|
||||||
mCeModule = new BfModule(mCompiler->mContext, "__constEval");
|
mCeModule = new BfModule(mCompiler->mContext, "__constEval");
|
||||||
mCeModule->mIsSpecialModule = true;
|
mCeModule->mIsSpecialModule = true;
|
||||||
//mCeModule->mIsScratchModule = true;
|
//mCeModule->mIsScratchModule = true;
|
||||||
mCeModule->mIsConstModule = true;
|
mCeModule->mIsComptimeModule = true;
|
||||||
//mCeModule->mIsReified = true;
|
//mCeModule->mIsReified = true;
|
||||||
if (mCompiler->mIsResolveOnly)
|
if (mCompiler->mIsResolveOnly)
|
||||||
mCeModule->mIsReified = true;
|
mCeModule->mIsReified = true;
|
||||||
|
@ -2882,7 +2889,8 @@ addr_ce CeMachine::GetReflectType(int typeId)
|
||||||
if (bfType == NULL)
|
if (bfType == NULL)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
mCeModule->PopulateType(bfType, BfPopulateType_DataAndMethods);
|
if (bfType->mDefineState != BfTypeDefineState_CETypeInit)
|
||||||
|
mCeModule->PopulateType(bfType, BfPopulateType_DataAndMethods);
|
||||||
|
|
||||||
Dictionary<int, int> usedStringMap;
|
Dictionary<int, int> usedStringMap;
|
||||||
auto irData = mCeModule->CreateTypeData(bfType, usedStringMap, true, true, true, false);
|
auto irData = mCeModule->CreateTypeData(bfType, usedStringMap, true, true, true, false);
|
||||||
|
@ -2991,6 +2999,30 @@ void CeMachine::PrepareConstStructEntry(CeConstStructData& constEntry)
|
||||||
constEntry.mBindExecuteId = mExecuteId;
|
constEntry.mBindExecuteId = mExecuteId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CeMachine::CheckMemory(addr_ce addr, int32 size)
|
||||||
|
{
|
||||||
|
if (((addr)-0x10000) + (size) > (mMemory.mSize - 0x10000))
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CeMachine::GetStringFromStringView(addr_ce addr, StringImpl& str)
|
||||||
|
{
|
||||||
|
int ptrSize = mCeModule->mSystem->mPtrSize;
|
||||||
|
if (!CheckMemory(addr, ptrSize * 2))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
addr_ce charsPtr = *(addr_ce*)(mMemory.mVals + addr);
|
||||||
|
int32 len = *(int32*)(mMemory.mVals + addr + ptrSize);
|
||||||
|
|
||||||
|
if (!CheckMemory(charsPtr, len))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
str.Append((const char*)(mMemory.mVals + charsPtr), len);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
BeContext* CeMachine::GetBeContext()
|
BeContext* CeMachine::GetBeContext()
|
||||||
{
|
{
|
||||||
if (mCeModule == NULL)
|
if (mCeModule == NULL)
|
||||||
|
@ -3016,6 +3048,12 @@ void CeMachine::CompileStarted()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CeMachine::CompileDone()
|
||||||
|
{
|
||||||
|
// So things like delted local methods get recheckeds
|
||||||
|
mRevision++;
|
||||||
|
}
|
||||||
|
|
||||||
void CeMachine::DerefMethodInfo(CeFunctionInfo* ceFunctionInfo)
|
void CeMachine::DerefMethodInfo(CeFunctionInfo* ceFunctionInfo)
|
||||||
{
|
{
|
||||||
ceFunctionInfo->mRefCount--;
|
ceFunctionInfo->mRefCount--;
|
||||||
|
@ -3257,6 +3295,13 @@ bool CeMachine::WriteConstant(BfModule* module, addr_ce addr, BfConstant* consta
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((constant->mConstType == BfConstType_TypeOf) || (constant->mConstType == BfConstType_TypeOf_WithData))
|
||||||
|
{
|
||||||
|
auto constTypeOf = (BfTypeOf_Const*)constant;
|
||||||
|
CE_GETC(addr_ce) = GetReflectType(constTypeOf->mType->mTypeId);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3489,7 +3534,6 @@ CeErrorKind CeMachine::WriteConstant(CeConstStructData& data, BeConstant* constV
|
||||||
return CeErrorKind_None;
|
return CeErrorKind_None;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#define CE_CREATECONST_CHECKPTR(PTR, SIZE) \
|
#define CE_CREATECONST_CHECKPTR(PTR, SIZE) \
|
||||||
if ((((uint8*)(PTR) - memStart) - 0x10000) + (SIZE) > (memSize - 0x10000)) \
|
if ((((uint8*)(PTR) - memStart) - 0x10000) + (SIZE) > (memSize - 0x10000)) \
|
||||||
{ \
|
{ \
|
||||||
|
@ -3829,8 +3873,10 @@ bool CeMachine::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
|
||||||
uint8* stackPtr = startStackPtr;
|
uint8* stackPtr = startStackPtr;
|
||||||
uint8* framePtr = startFramePtr;
|
uint8* framePtr = startFramePtr;
|
||||||
bool needsFunctionIds = mCeModule->mSystem->mPtrSize != 8;
|
bool needsFunctionIds = mCeModule->mSystem->mPtrSize != 8;
|
||||||
|
int32 ptrSize = mCeModule->mSystem->mPtrSize;
|
||||||
volatile bool* cancelPtr = &mCompiler->mCanceling;
|
|
||||||
|
volatile bool* fastFinishPtr = &mCompiler->mFastFinish;
|
||||||
|
volatile bool* cancelingPtr = &mCompiler->mCanceling;
|
||||||
|
|
||||||
auto _GetCurFrame = [&]()
|
auto _GetCurFrame = [&]()
|
||||||
{
|
{
|
||||||
|
@ -3973,12 +4019,30 @@ bool CeMachine::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
|
||||||
handled = true;
|
handled = true;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
else if (checkFunction->mFunctionKind == CeFunctionKind_EmitDefinition)
|
||||||
|
{
|
||||||
|
int32 typeId = *(int32*)((uint8*)stackPtr);
|
||||||
|
addr_ce strViewPtr = *(addr_ce*)((uint8*)stackPtr + sizeof(int32));
|
||||||
|
if ((mCurEmitContext == NULL) || (mCurEmitContext->mType->mTypeId != typeId))
|
||||||
|
{
|
||||||
|
_Fail("Missing emit context");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!GetStringFromStringView(strViewPtr, mCurEmitContext->mEmitData))
|
||||||
|
{
|
||||||
|
_Fail("Invalid StringView");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
handled = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
else if (checkFunction->mFunctionKind == CeFunctionKind_Sleep)
|
else if (checkFunction->mFunctionKind == CeFunctionKind_Sleep)
|
||||||
{
|
{
|
||||||
int32 sleepMS = *(int32*)((uint8*)stackPtr);
|
int32 sleepMS = *(int32*)((uint8*)stackPtr);
|
||||||
while (sleepMS > 0)
|
while (sleepMS > 0)
|
||||||
{
|
{
|
||||||
if (*cancelPtr)
|
if (*fastFinishPtr)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (sleepMS > 200)
|
if (sleepMS > 200)
|
||||||
|
@ -4104,9 +4168,9 @@ bool CeMachine::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
|
||||||
|
|
||||||
if (!checkFunction->mFailed)
|
if (!checkFunction->mFailed)
|
||||||
return true;
|
return true;
|
||||||
auto error = Fail(_GetCurFrame(), "Method call failed");
|
auto error = Fail(_GetCurFrame(), StrFormat("Method call '%s' failed", mCeModule->MethodToString(checkFunction->mMethodInstance).c_str()));
|
||||||
if ((error != NULL) && (!checkFunction->mGenError.IsEmpty()))
|
if ((error != NULL) && (!checkFunction->mGenError.IsEmpty()))
|
||||||
mCompiler->mPassInstance->MoreInfo("Const Method Generation Error: " + checkFunction->mGenError);
|
mCompiler->mPassInstance->MoreInfo("Comptime method generation error: " + checkFunction->mGenError);
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -4124,9 +4188,10 @@ bool CeMachine::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
|
||||||
|
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
if (*cancelPtr)
|
if (*fastFinishPtr)
|
||||||
{
|
{
|
||||||
_Fail("Compilation cancelled");
|
if (*cancelingPtr)
|
||||||
|
_Fail("Comptime evaluation canceled");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4576,10 +4641,14 @@ bool CeMachine::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
|
||||||
|
|
||||||
if (staticFieldInfo->mAddr == 0)
|
if (staticFieldInfo->mAddr == 0)
|
||||||
{
|
{
|
||||||
|
if (ceStaticFieldEntry.mSize < 0)
|
||||||
|
_Fail(StrFormat("Reference to unsized global variable '%s'", ceStaticFieldEntry.mName.c_str()));
|
||||||
|
|
||||||
CE_CHECKALLOC(ceStaticFieldEntry.mSize);
|
CE_CHECKALLOC(ceStaticFieldEntry.mSize);
|
||||||
uint8* ptr = CeMalloc(ceStaticFieldEntry.mSize);
|
uint8* ptr = CeMalloc(ceStaticFieldEntry.mSize);
|
||||||
_FixVariables();
|
_FixVariables();
|
||||||
memset(ptr, 0, ceStaticFieldEntry.mSize);
|
if (ceStaticFieldEntry.mSize > 0)
|
||||||
|
memset(ptr, 0, ceStaticFieldEntry.mSize);
|
||||||
staticFieldInfo->mAddr = (addr_ce)(ptr - memStart);
|
staticFieldInfo->mAddr = (addr_ce)(ptr - memStart);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4641,14 +4710,22 @@ bool CeMachine::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
|
||||||
callEntry.mFunction = callEntry.mFunctionInfo->mCeFunction;
|
callEntry.mFunction = callEntry.mFunctionInfo->mCeFunction;
|
||||||
if (!callEntry.mFunction->mInitialized)
|
if (!callEntry.mFunction->mInitialized)
|
||||||
{
|
{
|
||||||
|
auto curFrame = _GetCurFrame();
|
||||||
|
SetAndRestoreValue<CeFrame*> prevFrame(mCurFrame, &curFrame);
|
||||||
PrepareFunction(callEntry.mFunction, NULL);
|
PrepareFunction(callEntry.mFunction, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
callEntry.mBindRevision = mRevision;
|
callEntry.mBindRevision = mRevision;
|
||||||
}
|
}
|
||||||
|
|
||||||
BF_ASSERT(memStart == mMemory.mVals);
|
BF_ASSERT(memStart == mMemory.mVals);
|
||||||
auto callFunction = callEntry.mFunction;
|
auto callFunction = callEntry.mFunction;
|
||||||
|
|
||||||
|
if (callFunction->mMethodInstance->mMethodDef->mIsLocalMethod)
|
||||||
|
{
|
||||||
|
NOP;
|
||||||
|
}
|
||||||
|
|
||||||
if (needsFunctionIds)
|
if (needsFunctionIds)
|
||||||
*(int32*)(framePtr + resultFrameIdx) = callFunction->mId;
|
*(int32*)(framePtr + resultFrameIdx) = callFunction->mId;
|
||||||
else
|
else
|
||||||
|
@ -4678,7 +4755,14 @@ bool CeMachine::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
|
||||||
|
|
||||||
CE_CHECKADDR(valueAddr, sizeof(int32));
|
CE_CHECKADDR(valueAddr, sizeof(int32));
|
||||||
int32 objTypeId = *(int32*)(memStart + valueAddr);
|
int32 objTypeId = *(int32*)(memStart + valueAddr);
|
||||||
auto valueType = mCeModule->mContext->mTypes[objTypeId]->ToTypeInstance();
|
BfType* bfType = GetBfType(objTypeId);
|
||||||
|
if ((bfType == NULL) || (!bfType->IsObject()))
|
||||||
|
{
|
||||||
|
_Fail("Invalid virtual method target");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto valueType = bfType->ToTypeInstance();
|
||||||
if (valueType->mVirtualMethodTable.IsEmpty())
|
if (valueType->mVirtualMethodTable.IsEmpty())
|
||||||
mCeModule->PopulateType(valueType, BfPopulateType_DataAndMethods);
|
mCeModule->PopulateType(valueType, BfPopulateType_DataAndMethods);
|
||||||
auto methodInstance = (BfMethodInstance*)valueType->mVirtualMethodTable[virtualIdx].mImplementingMethod;
|
auto methodInstance = (BfMethodInstance*)valueType->mVirtualMethodTable[virtualIdx].mImplementingMethod;
|
||||||
|
@ -4702,23 +4786,26 @@ bool CeMachine::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
|
||||||
CE_CHECKADDR(valueAddr, sizeof(int32));
|
CE_CHECKADDR(valueAddr, sizeof(int32));
|
||||||
int32 objTypeId = *(int32*)(memStart + valueAddr);
|
int32 objTypeId = *(int32*)(memStart + valueAddr);
|
||||||
auto valueType = mCeModule->mContext->mTypes[objTypeId]->ToTypeInstance();
|
auto valueType = mCeModule->mContext->mTypes[objTypeId]->ToTypeInstance();
|
||||||
if (valueType->mVirtualMethodTable.IsEmpty())
|
|
||||||
mCeModule->PopulateType(valueType, BfPopulateType_DataAndMethods);
|
|
||||||
|
|
||||||
BfMethodInstance* methodInstance = NULL;
|
BfMethodInstance* methodInstance = NULL;
|
||||||
|
|
||||||
auto checkType = valueType;
|
if (valueType != NULL)
|
||||||
while (checkType != NULL)
|
|
||||||
{
|
{
|
||||||
for (auto& iface : checkType->mInterfaces)
|
if (valueType->mVirtualMethodTable.IsEmpty())
|
||||||
|
mCeModule->PopulateType(valueType, BfPopulateType_DataAndMethods);
|
||||||
|
|
||||||
|
auto checkType = valueType;
|
||||||
|
while (checkType != NULL)
|
||||||
{
|
{
|
||||||
if (iface.mInterfaceType == ifaceType)
|
for (auto& iface : checkType->mInterfaces)
|
||||||
{
|
{
|
||||||
methodInstance = valueType->mInterfaceMethodTable[iface.mStartInterfaceTableIdx + methodIdx].mMethodRef;
|
if (iface.mInterfaceType == ifaceType)
|
||||||
break;
|
{
|
||||||
|
methodInstance = valueType->mInterfaceMethodTable[iface.mStartInterfaceTableIdx + methodIdx].mMethodRef;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
checkType = checkType->mBaseType;
|
||||||
}
|
}
|
||||||
checkType = checkType->mBaseType;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (methodInstance == NULL)
|
if (methodInstance == NULL)
|
||||||
|
@ -5305,18 +5392,25 @@ void CeMachine::PrepareFunction(CeFunction* ceFunction, CeBuilder* parentBuilder
|
||||||
auto owner = ceFunction->mMethodInstance->GetOwner();
|
auto owner = ceFunction->mMethodInstance->GetOwner();
|
||||||
if (owner == mCeModule->mContext->mBfObjectType)
|
if (owner == mCeModule->mContext->mBfObjectType)
|
||||||
{
|
{
|
||||||
if (methodDef->mName == "ConstEval_GetType")
|
if (methodDef->mName == "Comptime_GetType")
|
||||||
{
|
{
|
||||||
ceFunction->mFunctionKind = CeFunctionKind_GetReflectType;
|
ceFunction->mFunctionKind = CeFunctionKind_GetReflectType;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (owner->IsInstanceOf(mCeModule->mCompiler->mTypeTypeDef))
|
else if (owner->IsInstanceOf(mCeModule->mCompiler->mTypeTypeDef))
|
||||||
{
|
{
|
||||||
if (methodDef->mName == "ConstEval_GetTypeById")
|
if (methodDef->mName == "Comptime_GetTypeById")
|
||||||
{
|
{
|
||||||
ceFunction->mFunctionKind = CeFunctionKind_GetReflectTypeById;
|
ceFunction->mFunctionKind = CeFunctionKind_GetReflectTypeById;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (owner->IsInstanceOf(mCeModule->mCompiler->mCompilerTypeDef))
|
||||||
|
{
|
||||||
|
if (methodDef->mName == "Comptime_EmitDefinition")
|
||||||
|
{
|
||||||
|
ceFunction->mFunctionKind = CeFunctionKind_EmitDefinition;
|
||||||
|
}
|
||||||
|
}
|
||||||
else if (owner->IsInstanceOf(mCeModule->mCompiler->mDiagnosticsDebugTypeDef))
|
else if (owner->IsInstanceOf(mCeModule->mCompiler->mDiagnosticsDebugTypeDef))
|
||||||
{
|
{
|
||||||
if (methodDef->mName == "Write")
|
if (methodDef->mName == "Write")
|
||||||
|
@ -5373,6 +5467,7 @@ void CeMachine::PrepareFunction(CeFunction* ceFunction, CeBuilder* parentBuilder
|
||||||
ceFunction->mGenerating = true;
|
ceFunction->mGenerating = true;
|
||||||
|
|
||||||
CeBuilder ceBuilder;
|
CeBuilder ceBuilder;
|
||||||
|
SetAndRestoreValue<CeBuilder*> prevBuilder(mCurBuilder, &ceBuilder);
|
||||||
ceBuilder.mParentBuilder = parentBuilder;
|
ceBuilder.mParentBuilder = parentBuilder;
|
||||||
ceBuilder.mPtrSize = mCeModule->mCompiler->mSystem->mPtrSize;
|
ceBuilder.mPtrSize = mCeModule->mCompiler->mSystem->mPtrSize;
|
||||||
ceBuilder.mCeMachine = this;
|
ceBuilder.mCeMachine = this;
|
||||||
|
@ -5534,6 +5629,7 @@ BfTypedValue CeMachine::Call(BfAstNode* targetSrc, BfModule* module, BfMethodIns
|
||||||
// DISABLED
|
// DISABLED
|
||||||
//return BfTypedValue();
|
//return BfTypedValue();
|
||||||
|
|
||||||
|
SetAndRestoreValue<CeEvalFlags> prevEvalFlags(mCurEvalFlags, flags);
|
||||||
SetAndRestoreValue<BfAstNode*> prevTargetSrc(mCurTargetSrc, targetSrc);
|
SetAndRestoreValue<BfAstNode*> prevTargetSrc(mCurTargetSrc, targetSrc);
|
||||||
SetAndRestoreValue<BfModule*> prevModule(mCurModule, module);
|
SetAndRestoreValue<BfModule*> prevModule(mCurModule, module);
|
||||||
SetAndRestoreValue<BfMethodInstance*> prevMethodInstance(mCurMethodInstance, methodInstance);
|
SetAndRestoreValue<BfMethodInstance*> prevMethodInstance(mCurMethodInstance, methodInstance);
|
||||||
|
|
|
@ -251,6 +251,7 @@ enum CeFunctionKind
|
||||||
CeFunctionKind_DebugWrite_Int,
|
CeFunctionKind_DebugWrite_Int,
|
||||||
CeFunctionKind_GetReflectType,
|
CeFunctionKind_GetReflectType,
|
||||||
CeFunctionKind_GetReflectTypeById,
|
CeFunctionKind_GetReflectTypeById,
|
||||||
|
CeFunctionKind_EmitDefinition,
|
||||||
CeFunctionKind_Sleep,
|
CeFunctionKind_Sleep,
|
||||||
CeFunctionKind_Char32_ToLower,
|
CeFunctionKind_Char32_ToLower,
|
||||||
CeFunctionKind_Char32_ToUpper,
|
CeFunctionKind_Char32_ToUpper,
|
||||||
|
@ -372,7 +373,9 @@ public:
|
||||||
enum CeEvalFlags
|
enum CeEvalFlags
|
||||||
{
|
{
|
||||||
CeEvalFlags_None = 0,
|
CeEvalFlags_None = 0,
|
||||||
CeEvalFlags_Cascade = 1
|
CeEvalFlags_Cascade = 1,
|
||||||
|
CeEvalFlags_PersistantError = 2,
|
||||||
|
CeEvalFlags_DeferIfNotOnlyError = 4,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum CeOperandKind
|
enum CeOperandKind
|
||||||
|
@ -602,6 +605,18 @@ public:
|
||||||
BfIRValue mAppendSizeValue;
|
BfIRValue mAppendSizeValue;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class CeEmitContext
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
BfType* mType;
|
||||||
|
String mEmitData;
|
||||||
|
|
||||||
|
CeEmitContext()
|
||||||
|
{
|
||||||
|
mType = NULL;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
class CeMachine
|
class CeMachine
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -628,7 +643,11 @@ public:
|
||||||
HashSet<int> mStaticCtorExecSet;
|
HashSet<int> mStaticCtorExecSet;
|
||||||
CeAppendAllocInfo* mAppendAllocInfo;
|
CeAppendAllocInfo* mAppendAllocInfo;
|
||||||
|
|
||||||
|
CeEmitContext* mCurEmitContext;
|
||||||
|
CeEvalFlags mCurEvalFlags;
|
||||||
|
CeBuilder* mCurBuilder;
|
||||||
CeFunction* mPreparingFunction;
|
CeFunction* mPreparingFunction;
|
||||||
|
CeFrame* mCurFrame;
|
||||||
BfAstNode* mCurTargetSrc;
|
BfAstNode* mCurTargetSrc;
|
||||||
BfMethodInstance* mCurMethodInstance;
|
BfMethodInstance* mCurMethodInstance;
|
||||||
BfModule* mCurModule;
|
BfModule* mCurModule;
|
||||||
|
@ -650,6 +669,8 @@ public:
|
||||||
addr_ce GetConstantData(BeConstant* constant);
|
addr_ce GetConstantData(BeConstant* constant);
|
||||||
BfType* GetBfType(int typeId);
|
BfType* GetBfType(int typeId);
|
||||||
void PrepareConstStructEntry(CeConstStructData& constStructData);
|
void PrepareConstStructEntry(CeConstStructData& constStructData);
|
||||||
|
bool CheckMemory(addr_ce addr, int32 size);
|
||||||
|
bool GetStringFromStringView(addr_ce addr, StringImpl& str);
|
||||||
|
|
||||||
BeContext* GetBeContext();
|
BeContext* GetBeContext();
|
||||||
BeModule* GetBeModule();
|
BeModule* GetBeModule();
|
||||||
|
@ -659,7 +680,7 @@ public:
|
||||||
CeErrorKind WriteConstant(CeConstStructData& data, BeConstant* constVal);
|
CeErrorKind WriteConstant(CeConstStructData& data, BeConstant* constVal);
|
||||||
BfIRValue CreateConstant(BfModule* module, uint8* ptr, BfType* type, BfType** outType = NULL);
|
BfIRValue CreateConstant(BfModule* module, uint8* ptr, BfType* type, BfType** outType = NULL);
|
||||||
void CreateFunction(BfMethodInstance* methodInstance, CeFunction* ceFunction);
|
void CreateFunction(BfMethodInstance* methodInstance, CeFunction* ceFunction);
|
||||||
bool Execute(CeFunction* startFunction, uint8* startStackPtr, uint8* startFramePtr, BfType*& returnType);
|
bool Execute(CeFunction* startFunction, uint8* startStackPtr, uint8* startFramePtr, BfType*& returnType);
|
||||||
|
|
||||||
void PrepareFunction(CeFunction* methodInstance, CeBuilder* parentBuilder);
|
void PrepareFunction(CeFunction* methodInstance, CeBuilder* parentBuilder);
|
||||||
void MapFunctionId(CeFunction* ceFunction);
|
void MapFunctionId(CeFunction* ceFunction);
|
||||||
|
@ -670,6 +691,7 @@ public:
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void CompileStarted();
|
void CompileStarted();
|
||||||
|
void CompileDone();
|
||||||
void QueueMethod(BfMethodInstance* methodInstance, BfIRValue func);
|
void QueueMethod(BfMethodInstance* methodInstance, BfIRValue func);
|
||||||
void QueueMethod(BfModuleMethodInstance moduleMethodInstance);
|
void QueueMethod(BfModuleMethodInstance moduleMethodInstance);
|
||||||
void QueueStaticField(BfFieldInstance* fieldInstance, const StringImpl& mangledFieldName);
|
void QueueStaticField(BfFieldInstance* fieldInstance, const StringImpl& mangledFieldName);
|
||||||
|
|
|
@ -23,8 +23,8 @@ namespace Tests
|
||||||
const String cStrA = "Abc";
|
const String cStrA = "Abc";
|
||||||
const String cStrB = GetStringA(cStrA, 12, 23);
|
const String cStrB = GetStringA(cStrA, 12, 23);
|
||||||
|
|
||||||
// ConstEval attribute means this method will always be const-evaluated
|
// Comptime attribute means this method will always be const-evaluated
|
||||||
[ConstEval]
|
[Comptime]
|
||||||
static String GetStringA(String str, int a, int b)
|
static String GetStringA(String str, int a, int b)
|
||||||
{
|
{
|
||||||
// Const-eval functions can return scope-allocated data
|
// Const-eval functions can return scope-allocated data
|
||||||
|
@ -101,7 +101,7 @@ namespace Tests
|
||||||
}
|
}
|
||||||
|
|
||||||
// This method can only be const evaluated
|
// This method can only be const evaluated
|
||||||
[ConstEval]
|
[Comptime]
|
||||||
public static int32 ConstSum(params int32[] vals)
|
public static int32 ConstSum(params int32[] vals)
|
||||||
{
|
{
|
||||||
int32 sum = 0;
|
int32 sum = 0;
|
||||||
|
@ -112,8 +112,8 @@ namespace Tests
|
||||||
|
|
||||||
public static int32 MethodB()
|
public static int32 MethodB()
|
||||||
{
|
{
|
||||||
// Returns different results depending on whether we are const-evaluating
|
// Returns different results depending on whether we are comptime
|
||||||
return Compiler.IsConstEval ? 1 : 0;
|
return Compiler.IsComptime ? 1 : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int32 MethodC(StructA sa = .(1, 2), (int32, int32) tup = (20, 30), int32[2] arr = .(300, 400))
|
public static int32 MethodC(StructA sa = .(1, 2), (int32, int32) tup = (20, 30), int32[2] arr = .(300, 400))
|
||||||
|
@ -121,7 +121,7 @@ namespace Tests
|
||||||
return sa.mA + sa.mB + tup.0 + tup.1 + arr[0] + arr[1];
|
return sa.mA + sa.mB + tup.0 + tup.1 + arr[0] + arr[1];
|
||||||
}
|
}
|
||||||
|
|
||||||
[ConstEval]
|
[Comptime(ConstEval=true)]
|
||||||
static var StrToValue(String str)
|
static var StrToValue(String str)
|
||||||
{
|
{
|
||||||
if (str.Contains('.'))
|
if (str.Contains('.'))
|
||||||
|
@ -164,7 +164,7 @@ namespace Tests
|
||||||
//Compiler.Assert(val1 == 24);
|
//Compiler.Assert(val1 == 24);
|
||||||
Test.Assert(val1 == 70);
|
Test.Assert(val1 == 70);
|
||||||
|
|
||||||
// This method is marked as ConstEval so it always evaluates as const
|
// This method is marked as Comptime so it always evaluates as const
|
||||||
let val2 = ConstSum(3, 20, 100);
|
let val2 = ConstSum(3, 20, 100);
|
||||||
Compiler.Assert(val2 == 123);
|
Compiler.Assert(val2 == 123);
|
||||||
|
|
||||||
|
|
|
@ -195,6 +195,22 @@ namespace Tests
|
||||||
TI iface = val as TI;
|
TI iface = val as TI;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void MethodA<T>(List<T> list)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void MethodA<T>(Span<T> list)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void MethodB<T>()
|
||||||
|
{
|
||||||
|
List<T> list = null;
|
||||||
|
MethodA(list);
|
||||||
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public static void TestBasics()
|
public static void TestBasics()
|
||||||
{
|
{
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue