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,12 +274,38 @@ namespace System
|
|||
|
||||
}
|
||||
|
||||
[AttributeUsage(.Method | .Invocation)]
|
||||
public struct ConstEvalAttribute : Attribute
|
||||
[AttributeUsage(.Method)]
|
||||
public struct ComptimeAttribute : Attribute
|
||||
{
|
||||
public this()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public bool OnlyFromComptime
|
||||
{
|
||||
set
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
public bool ConstEval
|
||||
{
|
||||
set
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[AttributeUsage(.Invocation)]
|
||||
public struct ConstEvalAttribute : Attribute
|
||||
{
|
||||
public this()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
[AttributeUsage(.Method /*2*/)]
|
||||
public struct IntrinsicAttribute : Attribute
|
||||
{
|
||||
|
|
|
@ -1,7 +1,38 @@
|
|||
using System.Reflection;
|
||||
namespace System
|
||||
{
|
||||
[AttributeUsage(.Method)]
|
||||
struct OnCompileAttribute : Attribute
|
||||
{
|
||||
public enum Kind
|
||||
{
|
||||
None,
|
||||
TypeInit,
|
||||
TypeDone
|
||||
}
|
||||
|
||||
public this(Kind kind)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
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")]
|
||||
public static extern int CallerLineNum;
|
||||
|
||||
|
@ -32,8 +63,8 @@ namespace System
|
|||
[LinkName("#TimeLocal")]
|
||||
public static extern String TimeLocal;
|
||||
|
||||
[LinkName("#IsConstEval")]
|
||||
public static extern bool IsConstEval;
|
||||
[LinkName("#IsComptime")]
|
||||
public static extern bool IsComptime;
|
||||
|
||||
[LinkName("#IsBuilding")]
|
||||
public static extern bool IsBuilding;
|
||||
|
@ -44,11 +75,39 @@ namespace System
|
|||
[LinkName("#CompileRev")]
|
||||
public static extern int32 CompileRev;
|
||||
|
||||
[ConstEval]
|
||||
[Comptime]
|
||||
public static void Assert(bool cond)
|
||||
{
|
||||
if (!cond)
|
||||
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
|
||||
{
|
||||
if (Compiler.IsConstEval)
|
||||
if (Compiler.IsComptime)
|
||||
return InitUserDefaultCulture();
|
||||
if (tlCurrentCulture == null)
|
||||
tlCurrentCulture = CultureInfo.DefaultThreadCurrentCulture ?? CultureInfo.UserDefaultCulture;
|
||||
|
|
|
@ -131,7 +131,7 @@ namespace System
|
|||
public static T* AllocRawArrayUnmarked<T>(int size)
|
||||
{
|
||||
#if BF_ENABLE_REALTIME_LEAK_CHECK
|
||||
if (Compiler.IsConstEval)
|
||||
if (Compiler.IsComptime)
|
||||
return new T[size]*(?);
|
||||
// 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
|
||||
|
|
|
@ -1235,7 +1235,7 @@ namespace System
|
|||
// _isCustomFormat, _specifierIsUpper, _specifier & _precision.
|
||||
this(CultureInfo cultureInfo)
|
||||
{
|
||||
if (Compiler.IsConstEval)
|
||||
if (Compiler.IsComptime)
|
||||
_cbuf = new char8[0];
|
||||
else
|
||||
_cbuf = sEmtpyBuf;
|
||||
|
|
|
@ -40,12 +40,12 @@ namespace System
|
|||
return false;
|
||||
}
|
||||
#endif
|
||||
extern Type ConstEval_GetType();
|
||||
extern Type Comptime_GetType();
|
||||
|
||||
public Type GetType()
|
||||
{
|
||||
if (Compiler.IsConstEval)
|
||||
return ConstEval_GetType();
|
||||
if (Compiler.IsComptime)
|
||||
return Comptime_GetType();
|
||||
|
||||
Type type;
|
||||
#if BF_ENABLE_OBJECT_DEBUG_FLAGS
|
||||
|
@ -65,8 +65,8 @@ namespace System
|
|||
[NoShow]
|
||||
Type RawGetType()
|
||||
{
|
||||
if (Compiler.IsConstEval)
|
||||
return ConstEval_GetType();
|
||||
if (Compiler.IsComptime)
|
||||
return Comptime_GetType();
|
||||
|
||||
Type type;
|
||||
#if BF_ENABLE_OBJECT_DEBUG_FLAGS
|
||||
|
|
|
@ -35,6 +35,11 @@ namespace System
|
|||
return .Ok(matched);
|
||||
}
|
||||
|
||||
public virtual Result<MethodInfo, MethodError> GetMethod(int methodIdx)
|
||||
{
|
||||
return .Err(.NoResults);
|
||||
}
|
||||
|
||||
public virtual Result<Object> CreateObject()
|
||||
{
|
||||
return .Err;
|
||||
|
@ -61,6 +66,13 @@ namespace System.Reflection
|
|||
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()
|
||||
{
|
||||
if (mTypeClassVData == null)
|
||||
|
|
|
@ -471,19 +471,19 @@ namespace System
|
|||
return (int32)mTypeId;
|
||||
}
|
||||
|
||||
static extern Type ConstEval_GetTypeById(int32 typeId);
|
||||
static extern Type Comptime_GetTypeById(int32 typeId);
|
||||
|
||||
protected static Type GetType(TypeId typeId)
|
||||
{
|
||||
if (Compiler.IsConstEval)
|
||||
return ConstEval_GetTypeById((.)typeId);
|
||||
if (Compiler.IsComptime)
|
||||
return Comptime_GetTypeById((.)typeId);
|
||||
return sTypes[(int32)typeId];
|
||||
}
|
||||
|
||||
protected static Type GetType_(int32 typeId)
|
||||
{
|
||||
if (Compiler.IsConstEval)
|
||||
return ConstEval_GetTypeById(typeId);
|
||||
if (Compiler.IsComptime)
|
||||
return Comptime_GetTypeById(typeId);
|
||||
return sTypes[typeId];
|
||||
}
|
||||
|
||||
|
@ -547,6 +547,11 @@ namespace System
|
|||
return .Err;
|
||||
}
|
||||
|
||||
public virtual Result<FieldInfo> GetField(int idx)
|
||||
{
|
||||
return .Err;
|
||||
}
|
||||
|
||||
public virtual FieldInfo.Enumerator GetFields(BindingFlags bindingFlags = cDefaultLookup)
|
||||
{
|
||||
return FieldInfo.Enumerator(null, bindingFlags);
|
||||
|
@ -912,6 +917,13 @@ namespace System.Reflection
|
|||
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)
|
||||
{
|
||||
return FieldInfo.Enumerator(this, bindingFlags);
|
||||
|
|
|
@ -130,6 +130,11 @@ namespace IDE
|
|||
public virtual void RequestCancelBackground()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public virtual void RequestFastFinish()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public void CancelBackground()
|
||||
|
|
|
@ -61,6 +61,9 @@ namespace IDE.Compiler
|
|||
[CallingConvention(.Stdcall), CLink]
|
||||
static extern void BfCompiler_Cancel(void* bfCompiler);
|
||||
|
||||
[CallingConvention(.Stdcall), CLink]
|
||||
static extern void BfCompiler_RequestFastFinish(void* bfCompiler);
|
||||
|
||||
[CallingConvention(.Stdcall), CLink]
|
||||
static extern void BfCompiler_ClearCompletionPercentage(void* bfCompiler);
|
||||
|
||||
|
@ -111,6 +114,12 @@ namespace IDE.Compiler
|
|||
[CallingConvention(.Stdcall), CLink]
|
||||
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
|
||||
{
|
||||
None = 0,
|
||||
|
@ -267,6 +276,20 @@ namespace IDE.Compiler
|
|||
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)
|
||||
{
|
||||
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()
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -6145,6 +6162,16 @@ namespace IDE
|
|||
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)))
|
||||
return null;
|
||||
|
@ -6219,6 +6246,8 @@ namespace IDE
|
|||
sourceViewPanelTab.mTabbedView.FinishTabAnim();
|
||||
if (setFocus)
|
||||
sourceViewPanel.FocusEdit();
|
||||
|
||||
sourceViewPanel.CheckEmitRevision();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -6236,6 +6265,7 @@ namespace IDE
|
|||
}
|
||||
else
|
||||
success = sourceViewPanel.Show(useFilePath, !mInitialized);
|
||||
sourceViewPanel.mEmitRevision = emitRevision;
|
||||
|
||||
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 WaitEvent mDoneEvent = new WaitEvent() ~ delete _;
|
||||
|
@ -306,6 +317,7 @@ namespace IDE.ui
|
|||
public List<ResolveParams> mDeferredResolveResults = new .() ~ DeleteContainerAndItems!(_);
|
||||
public bool mTrackedTextElementViewListDirty;
|
||||
public String mFilePath ~ delete _;
|
||||
public int32 mEmitRevision = -1;
|
||||
public bool mIsBinary;
|
||||
public String mAliasFilePath ~ delete _;
|
||||
#if IDE_C_SUPPORT
|
||||
|
@ -321,6 +333,7 @@ namespace IDE.ui
|
|||
HTTPRequest mOldVerHTTPRequest ~ delete _;
|
||||
IDEApp.ExecutionInstance mOldVerLoadExecutionInstance ~ { if (_ != null) _.mAutoDelete = true; };
|
||||
SourceFindTask mSourceFindTask ~ delete _;
|
||||
HoverResolveTask mHoverResolveTask ~ delete _;
|
||||
bool mWantsFastClassify;
|
||||
bool mWantsFullClassify; // This triggers a classify
|
||||
bool mWantsFullRefresh; // If mWantsFullClassify is set, mWantsFullRefresh makes the whole thing refresh
|
||||
|
@ -579,6 +592,8 @@ namespace IDE.ui
|
|||
|
||||
if (ResolveCompiler.mThreadWorkerHi.mThreadRunning)
|
||||
{
|
||||
ResolveCompiler.RequestFastFinish();
|
||||
|
||||
//Debug.WriteLine("Deferred DoAutoComplete");
|
||||
DeleteAndNullify!(mQueuedAutoComplete);
|
||||
mQueuedAutoComplete = new .();
|
||||
|
@ -968,6 +983,11 @@ namespace IDE.ui
|
|||
//return;
|
||||
}*/
|
||||
|
||||
if (compiler.IsPerformingBackgroundOperation())
|
||||
{
|
||||
compiler.RequestFastFinish();
|
||||
}
|
||||
|
||||
if (bfSystem == null)
|
||||
return false;
|
||||
|
||||
|
@ -1023,7 +1043,7 @@ namespace IDE.ui
|
|||
bool doBackground = (useResolveType == ResolveType.Classify) || (useResolveType == ResolveType.ClassifyFullRefresh);
|
||||
if (mAsyncAutocomplete)
|
||||
{
|
||||
if ((useResolveType == .Autocomplete) || (useResolveType == .GetCurrentLocation) || (useResolveType == .GetSymbolInfo))
|
||||
if ((useResolveType == .Autocomplete) || (useResolveType == .GetCurrentLocation) || (useResolveType == .GetSymbolInfo) || (useResolveType == .GetResultString))
|
||||
doBackground = true;
|
||||
}
|
||||
|
||||
|
@ -1111,7 +1131,9 @@ namespace IDE.ui
|
|||
|
||||
bool isHi = (resolveType != .ClassifyFullRefresh) && (resolveType != .Classify);
|
||||
if (isHi)
|
||||
{
|
||||
Debug.Assert(!bfCompiler.mThreadWorkerHi.mThreadRunning);
|
||||
}
|
||||
else
|
||||
Debug.Assert(!bfCompiler.mThreadWorker.mThreadRunning);
|
||||
|
||||
|
@ -1209,7 +1231,10 @@ namespace IDE.ui
|
|||
var bfCompiler = BfResolveCompiler;
|
||||
//var bfSystem = IDEApp.sApp.mBfResolveSystem;
|
||||
//bfCompiler.StartTiming();
|
||||
DoClassify(ResolveType.Classify, resolveParams);
|
||||
ResolveType resolveType = ResolveType.Classify;
|
||||
if (resolveParams != null)
|
||||
resolveType = resolveParams.mResolveType;
|
||||
DoClassify(resolveType, resolveParams);
|
||||
//bfCompiler.StopTiming();
|
||||
if (bfCompiler != null)
|
||||
bfCompiler.QueueDeferredResolveAll();
|
||||
|
@ -1600,6 +1625,11 @@ namespace IDE.ui
|
|||
}
|
||||
else if (resolveType == ResolveType.GetResultString)
|
||||
{
|
||||
if ((mHoverResolveTask != null) && (mHoverResolveTask.mCursorPos == resolveParams.mOverrideCursorPos))
|
||||
{
|
||||
mHoverResolveTask.mResult = new String(autocompleteInfo);
|
||||
}
|
||||
|
||||
resolveParams.mResultString = new String(autocompleteInfo);
|
||||
}
|
||||
else if (resolveType == ResolveType.GetCurrentLocation)
|
||||
|
@ -1664,7 +1694,7 @@ namespace IDE.ui
|
|||
var bfCompiler = BfResolveCompiler;
|
||||
//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;
|
||||
|
||||
if (!isBackground)
|
||||
|
@ -1775,15 +1805,18 @@ namespace IDE.ui
|
|||
int cursorPos = mEditWidget.mEditWidgetContent.CursorTextPos;
|
||||
/*if (resolveType == ResolveType.Autocomplete)
|
||||
cursorPos--;*/
|
||||
if ((resolveParams != null) && (resolveParams.mOverrideCursorPos != -1))
|
||||
if (resolveParams != null)
|
||||
{
|
||||
if (resolveParams.mOverrideCursorPos != -1)
|
||||
cursorPos = resolveParams.mOverrideCursorPos;
|
||||
}
|
||||
|
||||
if ((resolveType == ResolveType.GetNavigationData) || (resolveType == ResolveType.GetFixits))
|
||||
parser.SetAutocomplete(-1);
|
||||
else
|
||||
{
|
||||
bool setAutocomplete = ((!isBackground) && (resolveType != ResolveType.RenameSymbol));
|
||||
if ((resolveType == .Autocomplete) || (resolveType == .GetCurrentLocation) || (resolveType == .GetSymbolInfo))
|
||||
if ((resolveType == .Autocomplete) || (resolveType == .GetCurrentLocation) || (resolveType == .GetSymbolInfo) || (resolveType == .GetResultString))
|
||||
setAutocomplete = true;
|
||||
if (setAutocomplete)
|
||||
parser.SetAutocomplete(Math.Max(0, cursorPos));
|
||||
|
@ -1866,7 +1899,9 @@ namespace IDE.ui
|
|||
|
||||
resolveParams.mCancelled = true;
|
||||
if (resolveType == ResolveType.ClassifyFullRefresh)
|
||||
{
|
||||
QueueFullRefresh(false);
|
||||
}
|
||||
bfCompiler.QueueDeferredResolveAll();
|
||||
}
|
||||
}
|
||||
|
@ -4640,6 +4675,7 @@ namespace IDE.ui
|
|||
public void UpdateMouseover(bool mouseoverFired, bool mouseInbounds, int line, int lineChar)
|
||||
{
|
||||
|
||||
|
||||
#unwarn
|
||||
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 y;
|
||||
|
@ -4857,18 +4893,22 @@ namespace IDE.ui
|
|||
|
||||
String origDebugExpr = null;
|
||||
|
||||
bool handlingHoverResolveTask = false;
|
||||
|
||||
if ((debugExpr != null) || (isOverMessage))
|
||||
{
|
||||
let resolveParams = scope ResolveParams();
|
||||
resolveParams.mOverrideCursorPos = (int32)textIdx;
|
||||
if (!gApp.mDebugger.IsPaused())
|
||||
Classify(ResolveType.GetResultString, resolveParams);
|
||||
if (!String.IsNullOrEmpty(resolveParams.mResultString))
|
||||
if (mHoverResolveTask != null)
|
||||
{
|
||||
if (mHoverResolveTask.mCursorPos != textIdx)
|
||||
DeleteAndNullify!(mHoverResolveTask);
|
||||
}
|
||||
|
||||
if ((!String.IsNullOrEmpty(mHoverResolveTask?.mResult)))
|
||||
{
|
||||
origDebugExpr = scope:: String();
|
||||
origDebugExpr.Set(debugExpr);
|
||||
|
||||
debugExpr.Set(resolveParams.mResultString);
|
||||
debugExpr.Set(mHoverResolveTask.mResult);
|
||||
|
||||
if (debugExpr.StartsWith(':'))
|
||||
{
|
||||
|
@ -4889,6 +4929,12 @@ namespace IDE.ui
|
|||
}
|
||||
}
|
||||
|
||||
if (mHoverResolveTask?.mResult != null)
|
||||
{
|
||||
handlingHoverResolveTask = true;
|
||||
DeleteAndNullify!(mHoverResolveTask);
|
||||
}
|
||||
|
||||
if (!triedShow)
|
||||
{
|
||||
mHoverWatch.Show(this, x, y, debugExpr, debugExpr);
|
||||
|
@ -4899,6 +4945,22 @@ namespace IDE.ui
|
|||
if ((!didShow) &&
|
||||
((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 ((mIsClang) && (textIdx != -1))
|
||||
{
|
||||
|
@ -4994,7 +5056,6 @@ namespace IDE.ui
|
|||
{
|
||||
mWantsFullRefresh = true;
|
||||
mRefireMouseOverAfterRefresh = true;
|
||||
//Debug.WriteLine("Full refresh...");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -5026,7 +5087,6 @@ namespace IDE.ui
|
|||
{
|
||||
if (mHoverWatch.mCloseDelay > 0)
|
||||
{
|
||||
//Debug.WriteLine("mHoverWatch.mCloseCountdown = 20");
|
||||
mHoverWatch.mCloseDelay--;
|
||||
mHoverWatch.mCloseCountdown = 20;
|
||||
}
|
||||
|
@ -5042,7 +5102,6 @@ namespace IDE.ui
|
|||
}
|
||||
else
|
||||
{
|
||||
//Debug.WriteLine("mCloseCountdown = 0");
|
||||
mHoverWatch.mCloseCountdown = 0;
|
||||
}
|
||||
}
|
||||
|
@ -5088,7 +5147,7 @@ namespace IDE.ui
|
|||
#if IDE_C_SUPPORT
|
||||
hasClangHoverErrorData = mClangHoverErrorData != null;
|
||||
#endif
|
||||
if (((mouseoverFired) || (mHoverWatch != null) || (hasClangHoverErrorData)) &&
|
||||
if (((mouseoverFired) || (mHoverWatch != null) || (hasClangHoverErrorData) || (mHoverResolveTask?.mResult != null)) &&
|
||||
(mousePos.x >= 0))
|
||||
{
|
||||
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)
|
||||
{
|
||||
var srcCharData = mEditWidget.Content.mData.mText;
|
||||
|
@ -5840,6 +5450,13 @@ namespace IDE.ui
|
|||
checkIdx++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!resolveResult.mWaitEvent.WaitFor(0))
|
||||
{
|
||||
if (waitTime != 0)
|
||||
ResolveCompiler.RequestFastFinish();
|
||||
}
|
||||
|
||||
if (!resolveResult.mWaitEvent.WaitFor(waitTime))
|
||||
{
|
||||
checkIdx++;
|
||||
|
@ -5847,6 +5464,9 @@ namespace IDE.ui
|
|||
}
|
||||
mDeferredResolveResults.RemoveAt(checkIdx);
|
||||
}
|
||||
|
||||
//Debug.WriteLine($"HandleResolveResult {resolveResult}");
|
||||
|
||||
HandleResolveResult(resolveResult.mResolveType, resolveResult.mAutocompleteInfo, resolveResult);
|
||||
|
||||
//Debug.WriteLine("ProcessDeferredResolveResults finished {0}", resolveResult.mResolveType);
|
||||
|
@ -5887,12 +5507,15 @@ namespace IDE.ui
|
|||
{
|
||||
MarkDirty();
|
||||
if (resolveResult.mPassInstance.HadSignatureChanges())
|
||||
{
|
||||
mWantsFullRefresh = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
/*if (checkIt)
|
||||
Debug.Assert(data.mDisplayTypeId == 8);*/
|
||||
|
||||
//Debug.WriteLine($"Deleting {resolveResult}");
|
||||
delete resolveResult;
|
||||
}
|
||||
}
|
||||
|
@ -6368,6 +5991,9 @@ namespace IDE.ui
|
|||
mLockFlashPct = 0;
|
||||
MarkDirty();
|
||||
}
|
||||
|
||||
if ((mEmitRevision >= 0) && ((mUpdateCnt % 30) == 0))
|
||||
CheckEmitRevision();
|
||||
}
|
||||
|
||||
void InjectErrors(BfPassInstance processingPassInstance, EditWidgetContent.CharData[] processResolveCharData, IdSpan processCharIdSpan, bool keepPersistentErrors)
|
||||
|
@ -6396,10 +6022,14 @@ namespace IDE.ui
|
|||
int32 errorCount = processingPassInstance.GetErrorCount();
|
||||
mErrorList.Capacity = mErrorList.Count + errorCount;
|
||||
|
||||
bool hadNonDeferredErrors = false;
|
||||
|
||||
for (int32 errorIdx = 0; errorIdx < errorCount; errorIdx++)
|
||||
{
|
||||
BfPassInstance.BfError bfError = new BfPassInstance.BfError();
|
||||
processingPassInstance.GetErrorData(errorIdx, bfError);
|
||||
if (!bfError.mIsDeferred)
|
||||
hadNonDeferredErrors = true;
|
||||
|
||||
for (int32 moreInfoIdx < bfError.mMoreInfoCount)
|
||||
{
|
||||
|
@ -6425,6 +6055,9 @@ namespace IDE.ui
|
|||
if (bfError.mIsWhileSpecializing)
|
||||
continue;
|
||||
|
||||
if ((bfError.mIsDeferred) && (hadNonDeferredErrors))
|
||||
continue;
|
||||
|
||||
if (bfError.mIsPersistent)
|
||||
{
|
||||
if (bfError.mIdSpan.IsEmpty)
|
||||
|
@ -6823,5 +6456,27 @@ namespace IDE.ui
|
|||
|
||||
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);
|
||||
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;
|
||||
BeType* llvmConstType = GetBeType(typeCode, isSigned);
|
||||
|
@ -1969,6 +1984,13 @@ void BeIRCodeGen::HandleNextCmd()
|
|||
//SetResult(curId, globalVariable);
|
||||
}
|
||||
break;
|
||||
case BfIRCmd_SetReflectTypeData:
|
||||
{
|
||||
CMD_PARAM(BeType*, type);
|
||||
CMD_PARAM(BeValue*, value);
|
||||
mReflectDataMap[type] = value;
|
||||
}
|
||||
break;
|
||||
case BfIRCmd_CreateBlock:
|
||||
{
|
||||
CMD_PARAM(String, name);
|
||||
|
|
|
@ -89,6 +89,7 @@ public:
|
|||
Dictionary<int, BeIRTypeEntry> mTypes;
|
||||
|
||||
Dictionary<BeType*, BeDbgType*> mOnDemandTypeMap;
|
||||
Dictionary<BeType*, BeValue*> mReflectDataMap;
|
||||
Array<int> mConfigConsts;
|
||||
|
||||
public:
|
||||
|
|
|
@ -946,6 +946,14 @@ BfParser* BfAstNode::GetParser()
|
|||
return sourceData->ToParser();
|
||||
}
|
||||
|
||||
bool BfAstNode::IsEmitted()
|
||||
{
|
||||
auto parser = GetParser();
|
||||
if (parser == NULL)
|
||||
return false;
|
||||
return parser->mIsEmitted;
|
||||
}
|
||||
|
||||
bool BfAstNode::IsFromParser(BfParser* parser)
|
||||
{
|
||||
if (parser == NULL)
|
||||
|
|
|
@ -1088,6 +1088,7 @@ public:
|
|||
BfSourceData* GetSourceData();
|
||||
BfParserData* GetParserData();
|
||||
BfParser* GetParser();
|
||||
bool IsEmitted();
|
||||
bool IsFromParser(BfParser* parser);
|
||||
String ToString();
|
||||
StringView ToStringView();
|
||||
|
|
|
@ -346,6 +346,8 @@ BfCompiler::BfCompiler(BfSystem* bfSystem, bool isResolveOnly)
|
|||
memset(&mStats, 0, sizeof(mStats));
|
||||
mCompletionPct = 0;
|
||||
mCanceling = false;
|
||||
mFastFinish = false;
|
||||
mHasQueuedTypeRebuilds = false;
|
||||
mIsResolveOnly = isResolveOnly;
|
||||
mResolvePassData = NULL;
|
||||
mPassInstance = NULL;
|
||||
|
@ -397,6 +399,7 @@ BfCompiler::BfCompiler(BfSystem* bfSystem, bool isResolveOnly)
|
|||
mActionTypeDef = NULL;
|
||||
mEnumTypeDef = NULL;
|
||||
mFriendAttributeTypeDef = NULL;
|
||||
mComptimeAttributeTypeDef = NULL;
|
||||
mConstEvalAttributeTypeDef = NULL;
|
||||
mNoExtensionAttributeTypeDef = NULL;
|
||||
mCheckedAttributeTypeDef = NULL;
|
||||
|
@ -409,10 +412,13 @@ BfCompiler::BfCompiler(BfSystem* bfSystem, bool isResolveOnly)
|
|||
mInlineAttributeTypeDef = NULL;
|
||||
mThreadTypeDef = NULL;
|
||||
mInternalTypeDef = NULL;
|
||||
mCompilerTypeDef = NULL;
|
||||
mDiagnosticsDebugTypeDef = NULL;
|
||||
mIDisposableTypeDef = NULL;
|
||||
mIPrintableTypeDef = NULL;
|
||||
mIHashableTypeDef = NULL;
|
||||
mIComptimeTypeApply = NULL;
|
||||
mIComptimeMethodApply = NULL;
|
||||
mLinkNameAttributeTypeDef = NULL;
|
||||
mCallingConventionAttributeTypeDef = NULL;
|
||||
mMethodRefTypeDef = NULL;
|
||||
|
@ -447,6 +453,7 @@ BfCompiler::BfCompiler(BfSystem* bfSystem, bool isResolveOnly)
|
|||
mWarnAttributeTypeDef = NULL;
|
||||
mIgnoreErrorsAttributeTypeDef = NULL;
|
||||
mReflectAttributeTypeDef = NULL;
|
||||
mOnCompileAttributeTypeDef = NULL;
|
||||
|
||||
mLastAutocompleteModule = NULL;
|
||||
|
||||
|
@ -3919,6 +3926,8 @@ void BfCompiler::ProcessAutocompleteTempType()
|
|||
return;
|
||||
}
|
||||
|
||||
mFastFinish = false;
|
||||
|
||||
SetAndRestoreValue<BfMethodState*> prevMethodState(module->mCurMethodState, NULL);
|
||||
SetAndRestoreValue<BfTypeInstance*> prevTypeInstance(module->mCurTypeInstance, NULL);
|
||||
SetAndRestoreValue<BfMethodInstance*> prevMethodInstance(module->mCurMethodInstance, NULL);
|
||||
|
@ -6529,6 +6538,8 @@ bool BfCompiler::DoCompile(const StringImpl& outputDirectory)
|
|||
mOutputDirectory = outputDirectory;
|
||||
mSystem->StartYieldSection();
|
||||
|
||||
mFastFinish = false;
|
||||
mHasQueuedTypeRebuilds = false;
|
||||
mCanceling = false;
|
||||
mSystem->CheckLockYield();
|
||||
|
||||
|
@ -6611,6 +6622,7 @@ bool BfCompiler::DoCompile(const StringImpl& outputDirectory)
|
|||
mActionTypeDef = _GetRequiredType("System.Action");
|
||||
mEnumTypeDef = _GetRequiredType("System.Enum");
|
||||
mFriendAttributeTypeDef = _GetRequiredType("System.FriendAttribute");
|
||||
mComptimeAttributeTypeDef = _GetRequiredType("System.ComptimeAttribute");
|
||||
mConstEvalAttributeTypeDef = _GetRequiredType("System.ConstEvalAttribute");
|
||||
mNoExtensionAttributeTypeDef = _GetRequiredType("System.NoExtensionAttribute");
|
||||
mCheckedAttributeTypeDef = _GetRequiredType("System.CheckedAttribute");
|
||||
|
@ -6624,10 +6636,13 @@ bool BfCompiler::DoCompile(const StringImpl& outputDirectory)
|
|||
mInlineAttributeTypeDef = _GetRequiredType("System.InlineAttribute");
|
||||
mThreadTypeDef = _GetRequiredType("System.Threading.Thread");
|
||||
mInternalTypeDef = _GetRequiredType("System.Internal");
|
||||
mCompilerTypeDef = _GetRequiredType("System.Compiler");
|
||||
mDiagnosticsDebugTypeDef = _GetRequiredType("System.Diagnostics.Debug");
|
||||
mIDisposableTypeDef = _GetRequiredType("System.IDisposable");
|
||||
mIPrintableTypeDef = _GetRequiredType("System.IPrintable");
|
||||
mIHashableTypeDef = _GetRequiredType("System.IHashable");
|
||||
mIComptimeTypeApply = _GetRequiredType("System.IComptimeTypeApply");
|
||||
mIComptimeMethodApply = _GetRequiredType("System.IComptimeMethodApply");
|
||||
mLinkNameAttributeTypeDef = _GetRequiredType("System.LinkNameAttribute");
|
||||
mCallingConventionAttributeTypeDef = _GetRequiredType("System.CallingConventionAttribute");
|
||||
mMethodRefTypeDef = _GetRequiredType("System.MethodReference", 1);
|
||||
|
@ -6662,6 +6677,7 @@ bool BfCompiler::DoCompile(const StringImpl& outputDirectory)
|
|||
mWarnAttributeTypeDef = _GetRequiredType("System.WarnAttribute");
|
||||
mIgnoreErrorsAttributeTypeDef = _GetRequiredType("System.IgnoreErrorsAttribute");
|
||||
mReflectAttributeTypeDef = _GetRequiredType("System.ReflectAttribute");
|
||||
mOnCompileAttributeTypeDef = _GetRequiredType("System.OnCompileAttribute");
|
||||
|
||||
for (int i = 0; i < BfTypeCode_Length; i++)
|
||||
mContext->mPrimitiveStructTypes[i] = NULL;
|
||||
|
@ -7213,6 +7229,8 @@ bool BfCompiler::DoCompile(const StringImpl& outputDirectory)
|
|||
}
|
||||
mCodeGen.ProcessErrors(mPassInstance, mCanceling);
|
||||
|
||||
mCEMachine->CompileDone();
|
||||
|
||||
// This has to happen after codegen because we may delete modules that are referenced in codegen
|
||||
mContext->Cleanup();
|
||||
if ((!IsHotCompile()) && (!mIsResolveOnly) && (!mCanceling))
|
||||
|
@ -7346,7 +7364,7 @@ bool BfCompiler::DoCompile(const StringImpl& outputDirectory)
|
|||
|
||||
mContext->ValidateDependencies();
|
||||
|
||||
return !didCancel;
|
||||
return !didCancel && !mHasQueuedTypeRebuilds;
|
||||
}
|
||||
|
||||
bool BfCompiler::Compile(const StringImpl& outputDirectory)
|
||||
|
@ -7380,11 +7398,19 @@ void BfCompiler::ClearResults()
|
|||
void BfCompiler::Cancel()
|
||||
{
|
||||
mCanceling = true;
|
||||
mFastFinish = true;
|
||||
mHadCancel = true;
|
||||
BfLogSysM("BfCompiler::Cancel\n");
|
||||
BpEvent("BfCompiler::Cancel", "");
|
||||
}
|
||||
|
||||
void BfCompiler::RequestFastFinish()
|
||||
{
|
||||
mFastFinish = true;
|
||||
BfLogSysM("BfCompiler::RequestFastFinish\n");
|
||||
BpEvent("BfCompiler::RequestFastFinish", "");
|
||||
}
|
||||
|
||||
//#define WANT_COMPILE_LOG
|
||||
|
||||
void BfCompiler::CompileLog(const char* fmt ...)
|
||||
|
@ -8538,6 +8564,38 @@ String BfCompiler::GetTypeDefInfo(const StringImpl& inTypeName)
|
|||
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);
|
||||
|
@ -8738,6 +8796,11 @@ BF_EXPORT void BF_CALLTYPE BfCompiler_Cancel(BfCompiler* bfCompiler)
|
|||
bfCompiler->Cancel();
|
||||
}
|
||||
|
||||
BF_EXPORT void BF_CALLTYPE BfCompiler_RequestFastFinish(BfCompiler* bfCompiler)
|
||||
{
|
||||
bfCompiler->RequestFastFinish();
|
||||
}
|
||||
|
||||
BF_EXPORT void BF_CALLTYPE BfCompiler_ClearBuildCache(BfCompiler* bfCompiler)
|
||||
{
|
||||
bfCompiler->ClearBuildCache();
|
||||
|
@ -9251,3 +9314,17 @@ BF_EXPORT void BF_CALLTYPE BfCompiler_ForceRebuild(BfCompiler* bfCompiler)
|
|||
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;
|
||||
String mOutputDirectory;
|
||||
bool mCanceling;
|
||||
bool mFastFinish;
|
||||
bool mHasQueuedTypeRebuilds; // Infers we had a fast finish that requires a type rebuild
|
||||
bool mHadCancel;
|
||||
bool mWantsDeferMethodDecls;
|
||||
bool mInInvalidState;
|
||||
|
@ -362,10 +364,13 @@ public:
|
|||
|
||||
BfTypeDef* mThreadTypeDef;
|
||||
BfTypeDef* mInternalTypeDef;
|
||||
BfTypeDef* mCompilerTypeDef;
|
||||
BfTypeDef* mDiagnosticsDebugTypeDef;
|
||||
BfTypeDef* mIDisposableTypeDef;
|
||||
BfTypeDef* mIPrintableTypeDef;
|
||||
BfTypeDef* mIHashableTypeDef;
|
||||
BfTypeDef* mIComptimeTypeApply;
|
||||
BfTypeDef* mIComptimeMethodApply;
|
||||
|
||||
BfTypeDef* mMethodRefTypeDef;
|
||||
BfTypeDef* mNullableTypeDef;
|
||||
|
@ -403,6 +408,7 @@ public:
|
|||
BfTypeDef* mDisableChecksAttributeTypeDef;
|
||||
BfTypeDef* mDisableObjectAccessChecksAttributeTypeDef;
|
||||
BfTypeDef* mFriendAttributeTypeDef;
|
||||
BfTypeDef* mComptimeAttributeTypeDef;
|
||||
BfTypeDef* mConstEvalAttributeTypeDef;
|
||||
BfTypeDef* mNoExtensionAttributeTypeDef;
|
||||
BfTypeDef* mCheckedAttributeTypeDef;
|
||||
|
@ -417,6 +423,7 @@ public:
|
|||
BfTypeDef* mWarnAttributeTypeDef;
|
||||
BfTypeDef* mIgnoreErrorsAttributeTypeDef;
|
||||
BfTypeDef* mReflectAttributeTypeDef;
|
||||
BfTypeDef* mOnCompileAttributeTypeDef;
|
||||
|
||||
int mCurTypeId;
|
||||
int mTypeInitCount;
|
||||
|
@ -493,9 +500,11 @@ public:
|
|||
void ProcessAutocompleteTempType();
|
||||
void GetSymbolReferences();
|
||||
void Cancel();
|
||||
void RequestFastFinish();
|
||||
String GetTypeDefList();
|
||||
String GetTypeDefMatches(const StringImpl& searchSrc);
|
||||
String GetTypeDefInfo(const StringImpl& typeName);
|
||||
int GetEmitSource(const StringImpl& fileName, StringImpl* outBuffer);
|
||||
|
||||
void CompileLog(const char* fmt ...);
|
||||
void ReportMemory(MemReporter* memReporter);
|
||||
|
|
|
@ -36,7 +36,7 @@ BfConstResolver::BfConstResolver(BfModule* bfModule) : BfExprEvaluator(bfModule)
|
|||
|
||||
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
|
||||
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) ||
|
||||
(typeDef->mDefState == BfTypeDef::DefState_Deleted) ||
|
||||
|
@ -1026,6 +1026,11 @@ void BfContext::RebuildType(BfType* type, bool deleteOnDemandTypes, bool rebuild
|
|||
delete typeInst->mTypeInfoEx;
|
||||
typeInst->mTypeInfoEx = NULL;
|
||||
|
||||
typeInst->mTypeDef->ClearEmitted();
|
||||
for (auto localMethod : typeInst->mOwnedLocalMethods)
|
||||
delete localMethod;
|
||||
typeInst->mOwnedLocalMethods.Clear();
|
||||
|
||||
if (typeInst->IsGenericTypeInstance())
|
||||
{
|
||||
auto genericTypeInstance = (BfTypeInstance*)typeInst;
|
||||
|
@ -2851,7 +2856,24 @@ void BfContext::Cleanup()
|
|||
|
||||
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();
|
||||
survivingLocalMethods.push_back(localMethod);
|
||||
|
|
|
@ -861,8 +861,10 @@ void BfDefBuilder::ParseAttributes(BfAttributeDirective* attributes, BfMethodDef
|
|||
methodDef->mIsNoReturn = true;
|
||||
else if (typeRefName == "SkipCall")
|
||||
methodDef->mIsSkipCall = true;
|
||||
else if (typeRefName == "ConstEval")
|
||||
methodDef->mIsConstEval = true;
|
||||
else if (typeRefName == "Comptime")
|
||||
{
|
||||
methodDef->mHasComptime = true;
|
||||
}
|
||||
else if (typeRefName == "NoShow")
|
||||
methodDef->mIsNoShow = true;
|
||||
else if (typeRefName == "NoDiscard")
|
||||
|
@ -883,6 +885,10 @@ void BfDefBuilder::ParseAttributes(BfAttributeDirective* attributes, BfMethodDef
|
|||
methodDef->mCommutableKind = BfCommutableKind_Forward;
|
||||
}
|
||||
}
|
||||
else if (typeRefName == "OnCompile")
|
||||
{
|
||||
mCurTypeDef->mHasCEOnCompile = true;
|
||||
}
|
||||
}
|
||||
|
||||
attributes = attributes->mNextAttribute;
|
||||
|
@ -927,6 +933,7 @@ void BfDefBuilder::Visit(BfPropertyDeclaration* propertyDeclaration)
|
|||
Fail("Const properties are not allowed", propertyDeclaration->mConstSpecifier);
|
||||
}
|
||||
|
||||
if (mSignatureHashCtx != NULL)
|
||||
HashNode(*mSignatureHashCtx, propertyDeclaration, propertyDeclaration->mDefinitionBlock);
|
||||
|
||||
BfPropertyDef* propertyDef = new BfPropertyDef();
|
||||
|
@ -956,6 +963,7 @@ void BfDefBuilder::Visit(BfPropertyDeclaration* propertyDeclaration)
|
|||
if (propertyDeclaration->mDefinitionBlock == NULL) // To differentiate between autocompleting partial property if it transitions to a field
|
||||
{
|
||||
//mCurTypeDef->mSignatureHash = HashString("nullprop", mCurTypeDef->mSignatureHash);
|
||||
if (mSignatureHashCtx != NULL)
|
||||
mSignatureHashCtx->MixinStr("nullprop");
|
||||
}
|
||||
|
||||
|
@ -984,11 +992,14 @@ void BfDefBuilder::Visit(BfPropertyDeclaration* propertyDeclaration)
|
|||
}
|
||||
|
||||
for (auto methodDeclaration : propertyDeclaration->mMethods)
|
||||
{
|
||||
if (mSignatureHashCtx != NULL)
|
||||
{
|
||||
HashNode(*mSignatureHashCtx, methodDeclaration->mAttributes);
|
||||
HashNode(*mSignatureHashCtx, methodDeclaration->mProtectionSpecifier);
|
||||
HashNode(*mSignatureHashCtx, methodDeclaration->mNameNode);
|
||||
HashNode(*mSignatureHashCtx, methodDeclaration->mMutSpecifier);
|
||||
}
|
||||
|
||||
if (!wantsBody)
|
||||
continue;
|
||||
|
@ -1141,6 +1152,7 @@ void BfDefBuilder::Visit(BfFieldDeclaration* fieldDeclaration)
|
|||
fieldDef->mInitializer = fieldDeclaration->mInitializer;
|
||||
|
||||
//mCurTypeDef->mSignatureHash = HashNode(fieldDeclaration, mCurTypeDef->mSignatureHash);
|
||||
if (mSignatureHashCtx != NULL)
|
||||
HashNode(*mSignatureHashCtx, fieldDeclaration);
|
||||
}
|
||||
|
||||
|
@ -1918,26 +1930,35 @@ void BfDefBuilder::FinishTypeDef(bool wantsToString)
|
|||
bool hasCtor = false;
|
||||
bool needsDefaultCtor = (mCurTypeDef->mTypeCode != BfTypeCode_Interface) && (!mCurTypeDef->mIsStatic) && (!isAlias);
|
||||
bool hasDefaultCtor = false;
|
||||
bool hasStaticCtor = false;
|
||||
bool hasDtor = false;
|
||||
bool hasStaticDtor = false;
|
||||
bool hasMarkMethod = false;
|
||||
bool hasStaticMarkMethod = false;
|
||||
bool hasDynamicCastMethod = false;
|
||||
bool hasToStringMethod = false;
|
||||
BfMethodDef* ctorClear = NULL;
|
||||
BfMethodDef* staticCtor = NULL;
|
||||
BfMethodDef* dtor = NULL;
|
||||
BfMethodDef* staticDtor = NULL;
|
||||
BfMethodDef* markMethod = NULL;
|
||||
BfMethodDef* staticMarkMethod = NULL;
|
||||
BfMethodDef* dynamicCastMethod = NULL;
|
||||
BfMethodDef* toStringMethod = NULL;
|
||||
bool needsEqualsMethod = ((mCurTypeDef->mTypeCode == BfTypeCode_Struct) || (mCurTypeDef->mTypeCode == BfTypeCode_Enum)) && (!mCurTypeDef->mIsStatic);
|
||||
bool hasEqualsMethod = false;
|
||||
BfMethodDef* equalsMethod = NULL;
|
||||
BfMethodDef* strictEqualsMethod = NULL;
|
||||
|
||||
bool needsStaticInit = false;
|
||||
for (int methodIdx = 0; methodIdx < (int)mCurTypeDef->mMethods.size(); 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->mIsStatic)
|
||||
{
|
||||
if (hasStaticCtor)
|
||||
if ((staticCtor != NULL) && (staticCtor->mMethodDeclaration != NULL))
|
||||
{
|
||||
Fail("Only one static constructor is allowed", method->mMethodDeclaration);
|
||||
method->mIsStatic = false;
|
||||
|
@ -1950,9 +1971,9 @@ void BfDefBuilder::FinishTypeDef(bool wantsToString)
|
|||
}
|
||||
|
||||
if (method->mName == BF_METHODNAME_MARKMEMBERS_STATIC)
|
||||
hasStaticMarkMethod = true;
|
||||
_SetMethod(staticMarkMethod, method);
|
||||
|
||||
hasStaticCtor = true;
|
||||
_SetMethod(staticCtor, method);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1997,6 +2018,10 @@ void BfDefBuilder::FinishTypeDef(bool wantsToString)
|
|||
}
|
||||
}
|
||||
}
|
||||
if (method->mMethodType == BfMethodType_CtorClear)
|
||||
{
|
||||
ctorClear = method;
|
||||
}
|
||||
else if (method->mMethodType == BfMethodType_Init)
|
||||
{
|
||||
if (method->mIsStatic)
|
||||
|
@ -2006,22 +2031,22 @@ void BfDefBuilder::FinishTypeDef(bool wantsToString)
|
|||
{
|
||||
if (method->mIsStatic)
|
||||
{
|
||||
if (hasStaticDtor)
|
||||
if ((staticDtor != NULL) && (staticDtor->mMethodDeclaration != NULL))
|
||||
{
|
||||
Fail("Only one static constructor is allowed", method->mMethodDeclaration);
|
||||
method->mIsStatic = false;
|
||||
}
|
||||
|
||||
hasStaticDtor = true;
|
||||
_SetMethod(staticDtor, method);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (hasDtor)
|
||||
if ((dtor != NULL) && (dtor->mMethodDeclaration != NULL))
|
||||
{
|
||||
Fail("Only one destructor is allowed", method->mMethodDeclaration);
|
||||
method->mIsStatic = false;
|
||||
}
|
||||
hasDtor = true;
|
||||
_SetMethod(dtor, method);
|
||||
}
|
||||
|
||||
if (method->mParams.size() != 0)
|
||||
|
@ -2032,16 +2057,16 @@ void BfDefBuilder::FinishTypeDef(bool wantsToString)
|
|||
if (method->mIsStatic)
|
||||
{
|
||||
if (method->mName == BF_METHODNAME_MARKMEMBERS_STATIC)
|
||||
hasStaticMarkMethod = true;
|
||||
_SetMethod(staticMarkMethod, method);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (method->mName == BF_METHODNAME_MARKMEMBERS)
|
||||
hasMarkMethod = true;
|
||||
_SetMethod(markMethod, method);
|
||||
if (method->mName == BF_METHODNAME_DYNAMICCAST)
|
||||
hasDynamicCastMethod = true;
|
||||
_SetMethod(dynamicCastMethod, method);
|
||||
if (method->mName == BF_METHODNAME_TO_STRING)
|
||||
hasToStringMethod = true;
|
||||
_SetMethod(toStringMethod, method);
|
||||
}
|
||||
}
|
||||
else if ((method->mMethodType == BfMethodType_Operator) &&
|
||||
|
@ -2056,7 +2081,7 @@ void BfDefBuilder::FinishTypeDef(bool wantsToString)
|
|||
if ((method->mParams[0]->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)
|
||||
{
|
||||
|
@ -2131,24 +2156,24 @@ void BfDefBuilder::FinishTypeDef(bool wantsToString)
|
|||
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, "");
|
||||
methodDef->mIsMutating = true;
|
||||
}
|
||||
|
||||
if ((needsDtor) && (!hasDtor))
|
||||
if ((needsDtor) && (dtor == NULL))
|
||||
{
|
||||
auto methodDef = AddMethod(mCurTypeDef, BfMethodType_Dtor, BfProtection_Public, false, "");
|
||||
BF_ASSERT(mCurTypeDef->mDtorDef == methodDef);
|
||||
}
|
||||
|
||||
if ((needsStaticDtor) && (!hasStaticDtor))
|
||||
if ((needsStaticDtor) && (staticDtor == NULL))
|
||||
{
|
||||
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, "");
|
||||
}
|
||||
|
@ -2202,7 +2227,7 @@ void BfDefBuilder::FinishTypeDef(bool wantsToString)
|
|||
|
||||
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);
|
||||
methodDef->mIsNoReflect = true;
|
||||
|
@ -2214,7 +2239,7 @@ void BfDefBuilder::FinishTypeDef(bool wantsToString)
|
|||
methodDef->mIsNoReflect = true;
|
||||
}
|
||||
|
||||
if ((hasNonStaticField) && (!hasMarkMethod))
|
||||
if ((hasNonStaticField) && (markMethod == NULL))
|
||||
{
|
||||
auto methodDef = AddMethod(mCurTypeDef, BfMethodType_Normal, BfProtection_Protected, false, BF_METHODNAME_MARKMEMBERS);
|
||||
methodDef->mIsVirtual = true;
|
||||
|
@ -2225,7 +2250,7 @@ void BfDefBuilder::FinishTypeDef(bool wantsToString)
|
|||
}
|
||||
}
|
||||
|
||||
if (hasToStringMethod)
|
||||
if (toStringMethod != NULL)
|
||||
wantsToString = false;
|
||||
|
||||
if ((mCurTypeDef->mTypeCode == BfTypeCode_Enum) && (!isPayloadEnum))
|
||||
|
@ -2292,7 +2317,7 @@ void BfDefBuilder::FinishTypeDef(bool wantsToString)
|
|||
mCurTypeDef->mHasOverrideMethods = true;
|
||||
}
|
||||
|
||||
if ((needsEqualsMethod) && (!hasEqualsMethod))
|
||||
if ((needsEqualsMethod) && (equalsMethod == NULL))
|
||||
{
|
||||
auto methodDef = new BfMethodDef();
|
||||
mCurTypeDef->mMethods.push_back(methodDef);
|
||||
|
|
|
@ -799,7 +799,8 @@ void BfMethodMatcher::CompareMethods(BfMethodInstance* prevMethodInstance, BfTyp
|
|||
SET_BETTER_OR_WORSE((!isUnspecializedParam) && (!paramType->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()),
|
||||
(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))
|
||||
betterByConstExprParam = true;
|
||||
|
@ -2698,21 +2699,21 @@ BfAutoComplete* BfExprEvaluator::GetAutoComplete()
|
|||
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 ((mBfEvalExprFlags & BfEvalExprFlags_ConstEval) != 0);
|
||||
return ((mBfEvalExprFlags & BfEvalExprFlags_Comptime) != 0);
|
||||
}
|
||||
|
||||
int BfExprEvaluator::GetStructRetIdx(BfMethodInstance* methodInstance, bool forceStatic)
|
||||
{
|
||||
if (IsConstEval())
|
||||
if (IsComptime())
|
||||
return -1;
|
||||
return methodInstance->GetStructRetIdx(forceStatic);
|
||||
}
|
||||
|
@ -3333,7 +3334,7 @@ void BfExprEvaluator::Visit(BfLiteralExpression* literalExpr)
|
|||
|
||||
void BfExprEvaluator::Visit(BfStringInterpolationExpression* stringInterpolationExpression)
|
||||
{
|
||||
if (IsConstEvalEntry())
|
||||
if (IsComptimeEntry())
|
||||
{
|
||||
mModule->Fail("Const evaluation of string interpolation not allowed", stringInterpolationExpression);
|
||||
}
|
||||
|
@ -5074,6 +5075,19 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, BfMethodInstance*
|
|||
BF_ASSERT(!methodInstance->mDisallowCalling);
|
||||
|
||||
if ((mModule->mCompiler->mResolvePassData != NULL) && (mModule->mCompiler->mResolvePassData->mAutoComplete != NULL))
|
||||
{
|
||||
bool wantQuickEval = true;
|
||||
|
||||
if (IsComptime())
|
||||
{
|
||||
auto autoComplete = mModule->mCompiler->mResolvePassData->mAutoComplete;
|
||||
wantQuickEval =
|
||||
((autoComplete->mResolveType != BfResolveType_Autocomplete) &&
|
||||
(autoComplete->mResolveType != BfResolveType_Autocomplete_HighPri) &&
|
||||
(autoComplete->mResolveType != BfResolveType_GetResultString));
|
||||
}
|
||||
|
||||
if (wantQuickEval)
|
||||
{
|
||||
// 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
|
||||
|
@ -5089,7 +5103,7 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, BfMethodInstance*
|
|||
}
|
||||
}
|
||||
|
||||
if ((mBfEvalExprFlags & BfEvalExprFlags_ConstEval) != 0)
|
||||
if ((mBfEvalExprFlags & BfEvalExprFlags_Comptime) != 0)
|
||||
{
|
||||
if (methodInstance->mReturnType->IsInstanceOf(mModule->mCompiler->mSpanTypeDef))
|
||||
{
|
||||
|
@ -5113,6 +5127,7 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, BfMethodInstance*
|
|||
result = _GetDefaultReturnValue();
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
bool forceBind = false;
|
||||
|
||||
|
@ -5120,7 +5135,7 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, BfMethodInstance*
|
|||
{
|
||||
bool doConstReturn = false;
|
||||
|
||||
if ((mBfEvalExprFlags & BfEvalExprFlags_ConstEval) != 0)
|
||||
if ((mBfEvalExprFlags & BfEvalExprFlags_Comptime) != 0)
|
||||
{
|
||||
if (mFunctionBindResult != NULL)
|
||||
{
|
||||
|
@ -5134,6 +5149,11 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, BfMethodInstance*
|
|||
{
|
||||
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
|
||||
{
|
||||
CeEvalFlags evalFlags = CeEvalFlags_None;
|
||||
|
@ -5143,9 +5163,20 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, BfMethodInstance*
|
|||
BF_ASSERT(!constRet.mType->IsVar());
|
||||
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)
|
||||
{
|
||||
|
@ -5206,7 +5237,7 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, BfMethodInstance*
|
|||
|
||||
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);
|
||||
}
|
||||
|
@ -5226,7 +5257,7 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, BfMethodInstance*
|
|||
funcCallInst = mModule->mBfIRBuilder->CreateLoad(funcPtr);
|
||||
}
|
||||
}
|
||||
else if (mModule->mIsConstModule)
|
||||
else if (mModule->mIsComptimeModule)
|
||||
{
|
||||
funcCallInst = mModule->mBfIRBuilder->ConstEval_GetVirtualFunc(irArgs[0], methodInstance->mVirtualTableIdx, funcPtrType1);
|
||||
}
|
||||
|
@ -5323,7 +5354,7 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, BfMethodInstance*
|
|||
if (irArgs.size() != 0)
|
||||
{
|
||||
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);
|
||||
else
|
||||
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);
|
||||
|
||||
auto typeInst = paramType->ToTypeInstance();
|
||||
if ((typeInst != NULL) && (typeInst->mIsCRepr) && (typeInst->IsSplattable()) && (!IsConstEval()))
|
||||
if ((typeInst != NULL) && (typeInst->mIsCRepr) && (typeInst->IsSplattable()) && (!IsComptime()))
|
||||
{
|
||||
// We're splatting
|
||||
}
|
||||
|
@ -5527,7 +5558,7 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, BfMethodInstance*
|
|||
doingThis = false;
|
||||
continue;
|
||||
}
|
||||
bool isSplatted = methodInstance->GetParamIsSplat(thisIdx) && (!IsConstEval()); // (resolvedTypeRef->IsSplattable()) && (!methodDef->mIsMutating);
|
||||
bool isSplatted = methodInstance->GetParamIsSplat(thisIdx) && (!IsComptime()); // (resolvedTypeRef->IsSplattable()) && (!methodDef->mIsMutating);
|
||||
if (isSplatted)
|
||||
{
|
||||
BfTypeUtils::SplatIterate(_HandleParamType, paramType);
|
||||
|
@ -5561,7 +5592,7 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, BfMethodInstance*
|
|||
continue;
|
||||
}
|
||||
|
||||
if ((methodInstance->GetParamIsSplat(paramIdx)) && (!IsConstEval()))
|
||||
if ((methodInstance->GetParamIsSplat(paramIdx)) && (!IsComptime()))
|
||||
{
|
||||
BfTypeUtils::SplatIterate(_HandleParamType, paramType);
|
||||
paramIdx++;
|
||||
|
@ -5614,7 +5645,7 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, BfMethodInstance*
|
|||
{
|
||||
BfTypeCode loweredRetType = BfTypeCode_None;
|
||||
BfTypeCode loweredRetType2 = BfTypeCode_None;
|
||||
if ((!IsConstEval()) && (methodInstance->GetLoweredReturnType(&loweredRetType, &loweredRetType2)))
|
||||
if ((!IsComptime()) && (methodInstance->GetLoweredReturnType(&loweredRetType, &loweredRetType2)))
|
||||
{
|
||||
auto retVal = mModule->CreateAlloca(methodInstance->mReturnType);
|
||||
BfIRType loweredIRType = mModule->GetIRLoweredType(loweredRetType, loweredRetType2);
|
||||
|
@ -5780,7 +5811,7 @@ void BfExprEvaluator::PushArg(BfTypedValue argVal, SizedArrayImpl<BfIRValue>& ir
|
|||
return;
|
||||
|
||||
bool wantSplat = false;
|
||||
if ((argVal.mType->IsSplattable()) && (!disableSplat) && (!IsConstEval()))
|
||||
if ((argVal.mType->IsSplattable()) && (!disableSplat) && (!IsComptime()))
|
||||
{
|
||||
disableLowering = true;
|
||||
auto argTypeInstance = argVal.mType->ToTypeInstance();
|
||||
|
@ -5801,7 +5832,7 @@ void BfExprEvaluator::PushArg(BfTypedValue argVal, SizedArrayImpl<BfIRValue>& ir
|
|||
{
|
||||
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
|
||||
}
|
||||
|
@ -5812,7 +5843,7 @@ void BfExprEvaluator::PushArg(BfTypedValue argVal, SizedArrayImpl<BfIRValue>& ir
|
|||
else
|
||||
argVal = mModule->MakeAddressable(argVal);
|
||||
|
||||
if ((!IsConstEval()) && (!disableLowering) && (!isIntrinsic))
|
||||
if ((!IsComptime()) && (!disableLowering) && (!isIntrinsic))
|
||||
{
|
||||
BfTypeCode loweredTypeCode = BfTypeCode_None;
|
||||
BfTypeCode loweredTypeCode2 = BfTypeCode_None;
|
||||
|
@ -5906,7 +5937,7 @@ void BfExprEvaluator::PushThis(BfAstNode* targetSrc, BfTypedValue argVal, BfMeth
|
|||
auto owner = methodInstance->GetOwner();
|
||||
|
||||
bool allowThisSplatting;
|
||||
if (mModule->mIsConstModule)
|
||||
if (mModule->mIsComptimeModule)
|
||||
allowThisSplatting = owner->IsTypedPrimitive() || owner->IsValuelessType();
|
||||
else
|
||||
allowThisSplatting = methodInstance->AllowsSplatting(-1);
|
||||
|
@ -6210,7 +6241,7 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, const BfTypedValu
|
|||
}
|
||||
else
|
||||
{
|
||||
wantsSplat = methodInstance->GetParamIsSplat(paramIdx) && (!IsConstEval());
|
||||
wantsSplat = methodInstance->GetParamIsSplat(paramIdx) && (!IsComptime());
|
||||
if (methodInstance->IsImplicitCapture(paramIdx))
|
||||
{
|
||||
auto paramType = methodInstance->GetParamType(paramIdx);
|
||||
|
@ -6275,7 +6306,7 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, const BfTypedValu
|
|||
if (methodDef->mMethodType == BfMethodType_Extension)
|
||||
numElements++;
|
||||
|
||||
if (IsConstEvalEntry())
|
||||
if (IsComptimeEntry())
|
||||
{
|
||||
if ((wantType->IsArray()) || (wantType->IsInstanceOf(mModule->mCompiler->mSpanTypeDef)))
|
||||
{
|
||||
|
@ -6694,7 +6725,7 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, const BfTypedValu
|
|||
else
|
||||
{
|
||||
// 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);
|
||||
}
|
||||
|
@ -6714,7 +6745,7 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, const BfTypedValu
|
|||
{
|
||||
if (argValue)
|
||||
{
|
||||
if (IsConstEvalEntry())
|
||||
if (IsComptimeEntry())
|
||||
{
|
||||
auto constant = mModule->mBfIRBuilder->GetConstant(expandedParamsArray.mValue);
|
||||
BF_ASSERT(constant->mConstType == BfConstType_Agg);
|
||||
|
@ -8592,11 +8623,24 @@ BfTypedValue BfExprEvaluator::MatchMethod(BfAstNode* targetSrc, BfMethodBoundExp
|
|||
if ((mModule->mAttributeState != NULL) && (mModule->mAttributeState->mCustomAttributes != NULL) && (mModule->mAttributeState->mCustomAttributes->Contains(mModule->mCompiler->mConstEvalAttributeTypeDef)))
|
||||
{
|
||||
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);
|
||||
|
@ -11314,7 +11358,7 @@ void BfExprEvaluator::Visit(BfDelegateBindExpression* delegateBindExpr)
|
|||
for (int paramIdx = 0; paramIdx < methodInstance->GetParamCount(); 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);
|
||||
}
|
||||
|
@ -13180,7 +13224,7 @@ void BfExprEvaluator::CreateObject(BfObjectCreateExpression* objCreateExpr, BfAs
|
|||
|
||||
// Actually leave it alone?
|
||||
if ((isUninit) &&
|
||||
((mModule->IsOptimized()) || (mModule->mIsConstModule) || (mModule->mBfIRBuilder->mIgnoreWrites)))
|
||||
((mModule->IsOptimized()) || (mModule->mIsComptimeModule) || (mModule->mBfIRBuilder->mIgnoreWrites)))
|
||||
return;
|
||||
|
||||
bool doClear = true;
|
||||
|
@ -13564,7 +13608,7 @@ void BfExprEvaluator::CreateObject(BfObjectCreateExpression* objCreateExpr, BfAs
|
|||
{
|
||||
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);
|
||||
}
|
||||
|
@ -13615,7 +13659,7 @@ void BfExprEvaluator::CreateObject(BfObjectCreateExpression* objCreateExpr, BfAs
|
|||
{
|
||||
mModule->AssertErrorState();
|
||||
}
|
||||
else if ((mBfEvalExprFlags & BfEvalExprFlags_ConstEval) == 0)
|
||||
else if ((mBfEvalExprFlags & BfEvalExprFlags_Comptime) == 0)
|
||||
{
|
||||
SizedArray<BfIRValue, 1> irArgs;
|
||||
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");
|
||||
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();
|
||||
}
|
||||
|
@ -13887,7 +13931,7 @@ BfTypedValue BfExprEvaluator::MakeCallableTarget(BfAstNode* targetSrc, BfTypedVa
|
|||
|
||||
if ((target.mType->IsStruct()) && (!target.IsAddr()))
|
||||
{
|
||||
if (IsConstEvalEntry())
|
||||
if (IsComptimeEntry())
|
||||
return target;
|
||||
target = mModule->MakeAddressable(target);
|
||||
}
|
||||
|
@ -13923,7 +13967,7 @@ BfTypedValue BfExprEvaluator::MakeCallableTarget(BfAstNode* targetSrc, BfTypedVa
|
|||
auto ptrType = mModule->CreatePointerType(primStructType);
|
||||
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.mKind = BfTypedValueKind_SplatHead;
|
||||
|
@ -15739,7 +15783,7 @@ void BfExprEvaluator::DoInvocation(BfAstNode* target, BfMethodBoundExpression* m
|
|||
|
||||
int methodCount = 0;
|
||||
bool mayBeSkipCall = false;
|
||||
bool mayBeConstEvalCall = false;
|
||||
bool mayBeComptimeCall = false;
|
||||
if (thisValue.mType != NULL)
|
||||
{
|
||||
if (thisValue.mType->IsAllocType())
|
||||
|
@ -15757,8 +15801,8 @@ void BfExprEvaluator::DoInvocation(BfAstNode* target, BfMethodBoundExpression* m
|
|||
{
|
||||
if (methodDef->mIsSkipCall)
|
||||
mayBeSkipCall = true;
|
||||
if (methodDef->mIsConstEval)
|
||||
mayBeConstEvalCall = true;
|
||||
if (methodDef->mHasComptime)
|
||||
mayBeComptimeCall = true;
|
||||
methodDef = methodDef->mNextWithSameName;
|
||||
}
|
||||
}
|
||||
|
@ -15784,7 +15828,7 @@ void BfExprEvaluator::DoInvocation(BfAstNode* target, BfMethodBoundExpression* m
|
|||
|
||||
BfResolveArgsFlags resolveArgsFlags = (BfResolveArgsFlags)(BfResolveArgsFlag_DeferFixits | BfResolveArgsFlag_AllowUnresolvedTypes);
|
||||
resolveArgsFlags = (BfResolveArgsFlags)(resolveArgsFlags | BfResolveArgsFlag_DeferParamEval);
|
||||
if ((mayBeSkipCall) || (mayBeConstEvalCall))
|
||||
if ((mayBeSkipCall) || (mayBeComptimeCall))
|
||||
resolveArgsFlags = (BfResolveArgsFlags)(resolveArgsFlags | BfResolveArgsFlag_DeferParamValues);
|
||||
|
||||
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);
|
||||
|
||||
SetAndRestoreValue<bool> prevUsedAsStatement(mUsedAsStatement, mUsedAsStatement || isCascade);
|
||||
|
@ -16080,6 +16124,10 @@ BfModuleMethodInstance BfExprEvaluator::GetPropertyMethodInstance(BfMethodDef* m
|
|||
while (checkTypeInst != NULL)
|
||||
{
|
||||
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)
|
||||
{
|
||||
|
@ -18735,7 +18783,7 @@ void BfExprEvaluator::Visit(BfIndexerExpression* indexerExpr)
|
|||
}
|
||||
}
|
||||
}
|
||||
else if (((mModule->HasCompiledOutput()) || (mModule->mIsConstModule)) &&
|
||||
else if (((mModule->HasCompiledOutput()) || (mModule->mIsComptimeModule)) &&
|
||||
(wantsChecks))
|
||||
{
|
||||
if (checkedKind == BfCheckedKind_NotSet)
|
||||
|
@ -18767,7 +18815,7 @@ void BfExprEvaluator::Visit(BfIndexerExpression* indexerExpr)
|
|||
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);
|
||||
|
||||
SizedArray<BfIRValue, 1> args;
|
||||
|
|
|
@ -390,8 +390,8 @@ public:
|
|||
void FinishExpressionResult();
|
||||
virtual bool CheckAllowValue(const BfTypedValue& typedValue, BfAstNode* refNode);
|
||||
BfAutoComplete* GetAutoComplete();
|
||||
bool IsConstEval();
|
||||
bool IsConstEvalEntry();
|
||||
bool IsComptime();
|
||||
bool IsComptimeEntry();
|
||||
int GetStructRetIdx(BfMethodInstance* methodInstance, bool forceStatic = false);
|
||||
BfTypedValue SetupNullConditional(BfTypedValue target, BfTokenNode* dotToken);
|
||||
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;
|
||||
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)
|
||||
{
|
||||
auto aggZero = (BfConstant*)fromConst;
|
||||
|
@ -791,6 +797,19 @@ BfIRValue BfIRConstHolder::CreateTypeOf(BfType* type)
|
|||
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->mTypeData = typeData;
|
||||
auto irValue = BfIRValue(BfIRValueFlags_Const, mTempAlloc.GetChunkedId(typeOf));
|
||||
#ifdef CHECK_CONSTHOLDER
|
||||
irValue.mHolder = this;
|
||||
#endif
|
||||
return irValue;
|
||||
}
|
||||
|
||||
BfIRValue BfIRConstHolder::GetUndefConstValue(BfIRType irType)
|
||||
{
|
||||
auto constUndef = mTempAlloc.Alloc<BfConstantUndef>();
|
||||
|
@ -1950,10 +1969,17 @@ void BfIRBuilder::Write(const BfIRValue& irValue)
|
|||
Write(constant->mInt64);
|
||||
}
|
||||
break;
|
||||
case (int)BfConstType_Undef:
|
||||
case (int)BfConstType_TypeOf:
|
||||
{
|
||||
auto undefConst = (BfConstantUndef*)constant;
|
||||
Write(undefConst->mType);
|
||||
auto typeofConst = (BfTypeOf_Const*)constant;
|
||||
Write(MapType(typeofConst->mType, BfIRPopulateType_Identity));
|
||||
}
|
||||
break;
|
||||
case (int)BfConstType_TypeOf_WithData:
|
||||
{
|
||||
auto typeofConst = (BfTypeOf_WithData_Const*)constant;
|
||||
Write(MapType(typeofConst->mType, BfIRPopulateType_Identity));
|
||||
Write(typeofConst->mTypeData);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
@ -4476,6 +4502,12 @@ BfIRValue BfIRBuilder::CreateGlobalStringPtr(const StringImpl& str)
|
|||
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)
|
||||
{
|
||||
if (addNow)
|
||||
|
|
|
@ -120,6 +120,7 @@ enum BfConstType
|
|||
BfConstType_PtrToInt,
|
||||
BfConstType_IntToPtr,
|
||||
BfConstType_TypeOf,
|
||||
BfConstType_TypeOf_WithData,
|
||||
BfConstType_AggZero,
|
||||
BfConstType_Agg,
|
||||
BfConstType_ArrayZero,
|
||||
|
@ -235,6 +236,7 @@ enum BfIRCmd : uint8
|
|||
BfIRCmd_GlobalVar_SetAlignment,
|
||||
BfIRCmd_GlobalVar_SetStorageKind,
|
||||
BfIRCmd_GlobalStringPtr,
|
||||
BfIRCmd_SetReflectTypeData,
|
||||
|
||||
BfIRCmd_CreateBlock,
|
||||
BfIRCmd_MaybeChainNewBlock,
|
||||
|
@ -771,6 +773,14 @@ struct BfTypeOf_Const
|
|||
{
|
||||
BfConstType mConstType;
|
||||
BfType* mType;
|
||||
BfIRValue mTypeData;
|
||||
};
|
||||
|
||||
struct BfTypeOf_WithData_Const
|
||||
{
|
||||
BfConstType mConstType;
|
||||
BfType* mType;
|
||||
BfIRValue mTypeData;
|
||||
};
|
||||
|
||||
struct BfConstant
|
||||
|
@ -906,6 +916,7 @@ public:
|
|||
BfIRValue CreateConstArrayZero(BfIRType type, int count);
|
||||
BfIRValue CreateConstArrayZero(int count);
|
||||
BfIRValue CreateTypeOf(BfType* type);
|
||||
BfIRValue CreateTypeOf(BfType* type, BfIRValue typeData);
|
||||
BfIRValue GetUndefConstValue(BfIRType type);
|
||||
};
|
||||
|
||||
|
@ -1199,6 +1210,7 @@ public:
|
|||
void GlobalVar_SetAlignment(BfIRValue globalVar, int alignment);
|
||||
void GlobalVar_SetStorageKind(BfIRValue globalVar, BfIRStorageKind storageKind);
|
||||
BfIRValue CreateGlobalStringPtr(const StringImpl& str);
|
||||
void SetReflectTypeData(BfIRType type, BfIRValue globalVar);
|
||||
|
||||
BfIRBlock CreateBlock(const StringImpl& name, bool addNow = false);
|
||||
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);
|
||||
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;
|
||||
llvm::Type* llvmConstType = GetLLVMType(typeCode, isSigned);
|
||||
|
@ -2266,6 +2281,13 @@ void BfIRCodeGen::HandleNextCmd()
|
|||
SetResult(curId, mIRBuilder->CreateGlobalStringPtr(llvm::StringRef(str.c_str(), str.length())));
|
||||
}
|
||||
break;
|
||||
case BfIRCmd_SetReflectTypeData:
|
||||
{
|
||||
CMD_PARAM(llvm::Type*, type);
|
||||
CMD_PARAM(llvm::Value*, value);
|
||||
mReflectDataMap[type] = value;
|
||||
}
|
||||
break;
|
||||
case BfIRCmd_CreateBlock:
|
||||
{
|
||||
CMD_PARAM(String, name);
|
||||
|
|
|
@ -108,6 +108,7 @@ public:
|
|||
Dictionary<llvm::Function*, int> mIntrinsicReverseMap;
|
||||
Array<llvm::Constant*> mConfigConsts32;
|
||||
Array<llvm::Constant*> mConfigConsts64;
|
||||
Dictionary<llvm::Type*, llvm::Value*> mReflectDataMap;
|
||||
|
||||
public:
|
||||
void InitTarget();
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -32,6 +32,7 @@ NS_BF_BEGIN
|
|||
class BfType;
|
||||
class BfResolvedType;
|
||||
class BfExprEvaluator;
|
||||
class CeEmitContext;
|
||||
|
||||
enum BfPopulateType
|
||||
{
|
||||
|
@ -71,7 +72,7 @@ enum BfEvalExprFlags
|
|||
BfEvalExprFlags_AllowNonConst = 0x10000,
|
||||
BfEvalExprFlags_StringInterpolateFormat = 0x20000,
|
||||
BfEvalExprFlags_NoLookupError = 0x40000,
|
||||
BfEvalExprFlags_ConstEval = 0x80000,
|
||||
BfEvalExprFlags_Comptime = 0x80000,
|
||||
BfEvalExprFlags_InCascade = 0x100000,
|
||||
};
|
||||
|
||||
|
@ -1450,7 +1451,7 @@ public:
|
|||
bool mWantsIRIgnoreWrites;
|
||||
bool mHasGenericMethods;
|
||||
bool mIsSpecialModule; // vdata, unspecialized, external
|
||||
bool mIsConstModule;
|
||||
bool mIsComptimeModule;
|
||||
bool mIsScratchModule;
|
||||
bool mIsSpecializedMethodModuleRoot;
|
||||
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();
|
||||
bool CheckInternalProtection(BfTypeDef* usingTypeDef);
|
||||
void AddFailType(BfTypeInstance* typeInstance);
|
||||
void DeferRebuildType(BfTypeInstance* typeInstance);
|
||||
void MarkDerivedDirty(BfTypeInstance* typeInst);
|
||||
void CheckAddFailType();
|
||||
void PopulateType(BfType* resolvedTypeRef, BfPopulateType populateType = BfPopulateType_Data);
|
||||
|
@ -1695,6 +1697,9 @@ public:
|
|||
void SetTypeOptions(BfTypeInstance* typeInstance);
|
||||
BfModuleOptions GetModuleOptions();
|
||||
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);
|
||||
static BfModule* GetModuleFor(BfType* type);
|
||||
void DoTypeInstanceMethodProcessing(BfTypeInstance* typeInstance);
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
#include "BfCompiler.h"
|
||||
#include "BfSystem.h"
|
||||
#include "BfParser.h"
|
||||
#include "BfReducer.h"
|
||||
#include "BfCodeGen.h"
|
||||
#include "BfExprEvaluator.h"
|
||||
#include <fcntl.h>
|
||||
|
@ -17,6 +18,7 @@
|
|||
#include "BfFixits.h"
|
||||
#include "BfIRCodeGen.h"
|
||||
#include "BfDefBuilder.h"
|
||||
#include "CeMachine.h"
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
@ -1931,6 +1933,177 @@ void BfModule::SetTypeOptions(BfTypeInstance* typeInstance)
|
|||
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)
|
||||
{
|
||||
auto typeInstance = resolvedTypeRef->ToTypeInstance();
|
||||
|
@ -1991,7 +2164,7 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy
|
|||
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());
|
||||
for (int i = 0; i < (int)typeInstance->mMethodInstanceGroups.size(); i++)
|
||||
{
|
||||
|
@ -2859,6 +3032,27 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy
|
|||
if (typeInstance->mTypeOptionsIdx == -2)
|
||||
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)
|
||||
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())
|
||||
|
@ -3670,7 +3902,12 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy
|
|||
member->mRefCount++;
|
||||
}
|
||||
|
||||
if (typeInstance->mDefineState < BfTypeDefineState_Defined)
|
||||
{
|
||||
typeInstance->mDefineState = BfTypeDefineState_Defined;
|
||||
if (!typeInstance->IsBoxed())
|
||||
ExecuteCEOnCompile(typeInstance, BfCEOnCompileKind_TypeDone, NULL);
|
||||
}
|
||||
|
||||
if (typeInstance->mTypeFailed)
|
||||
mHadBuildError = true;
|
||||
|
@ -3832,7 +4069,7 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy
|
|||
int64 min = 0;
|
||||
int64 max = 0;
|
||||
|
||||
bool isFirst = false;
|
||||
bool isFirst = true;
|
||||
|
||||
if (typeInstance->mTypeInfoEx == NULL)
|
||||
typeInstance->mTypeInfoEx = new BfTypeInfoEx();
|
||||
|
@ -4311,8 +4548,6 @@ void BfModule::DoTypeInstanceMethodProcessing(BfTypeInstance* typeInstance)
|
|||
continue;
|
||||
if (methodInstanceGroup->mOnDemandKind == BfMethodOnDemandKind_InWorkList)
|
||||
continue;
|
||||
if (methodInstanceGroup->mOnDemandKind == BfMethodOnDemandKind_Decl_AwaitingReference)
|
||||
continue;
|
||||
if (methodInstanceGroup->mOnDemandKind == BfMethodOnDemandKind_Referenced)
|
||||
continue;
|
||||
|
||||
|
@ -4322,8 +4557,9 @@ void BfModule::DoTypeInstanceMethodProcessing(BfTypeInstance* typeInstance)
|
|||
continue;
|
||||
}
|
||||
|
||||
// This should still be set to the default value
|
||||
BF_ASSERT((methodInstanceGroup->mOnDemandKind == BfMethodOnDemandKind_NotSet) || (methodInstanceGroup->mOnDemandKind == BfMethodOnDemandKind_Decl_AwaitingDecl));
|
||||
BF_ASSERT((methodInstanceGroup->mOnDemandKind == BfMethodOnDemandKind_NotSet) ||
|
||||
(methodInstanceGroup->mOnDemandKind == BfMethodOnDemandKind_Decl_AwaitingDecl) ||
|
||||
(methodInstanceGroup->mOnDemandKind == BfMethodOnDemandKind_Decl_AwaitingReference));
|
||||
|
||||
if ((isBoxed) && (!methodDef->mIsVirtual))
|
||||
{
|
||||
|
@ -4352,8 +4588,7 @@ void BfModule::DoTypeInstanceMethodProcessing(BfTypeInstance* typeInstance)
|
|||
if ((methodDef->mName == BF_METHODNAME_DYNAMICCAST) && (typeInstance->IsValueType()))
|
||||
continue; // This is just a placeholder for boxed types
|
||||
|
||||
if (methodInstanceGroup->mOnDemandKind == BfMethodOnDemandKind_NotSet)
|
||||
methodInstanceGroup->mOnDemandKind = BfMethodOnDemandKind_AlwaysInclude;
|
||||
bool doAlwaysInclude = false;
|
||||
|
||||
if (wantsOnDemandMethods)
|
||||
{
|
||||
|
@ -4453,8 +4688,7 @@ void BfModule::DoTypeInstanceMethodProcessing(BfTypeInstance* typeInstance)
|
|||
|
||||
if (!implRequired)
|
||||
{
|
||||
BF_ASSERT(methodInstanceGroup->mOnDemandKind != BfMethodOnDemandKind_NotSet);
|
||||
if (methodInstanceGroup->mOnDemandKind == BfMethodOnDemandKind_AlwaysInclude)
|
||||
if (methodInstanceGroup->mOnDemandKind == BfMethodOnDemandKind_NotSet)
|
||||
{
|
||||
if (!mIsScratchModule)
|
||||
mOnDemandMethodCount++;
|
||||
|
@ -4462,18 +4696,40 @@ void BfModule::DoTypeInstanceMethodProcessing(BfTypeInstance* typeInstance)
|
|||
|
||||
if (!declRequired)
|
||||
{
|
||||
if (methodInstanceGroup->mOnDemandKind == BfMethodOnDemandKind_AlwaysInclude)
|
||||
if (methodInstanceGroup->mOnDemandKind == BfMethodOnDemandKind_NotSet)
|
||||
methodInstanceGroup->mOnDemandKind = BfMethodOnDemandKind_NoDecl_AwaitingReference;
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (methodInstanceGroup->mOnDemandKind == BfMethodOnDemandKind_AlwaysInclude)
|
||||
if (methodInstanceGroup->mOnDemandKind == BfMethodOnDemandKind_NotSet)
|
||||
methodInstanceGroup->mOnDemandKind = BfMethodOnDemandKind_Decl_AwaitingDecl;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -5480,7 +5736,7 @@ BfPrimitiveType* BfModule::GetPrimitiveType(BfTypeCode typeCode)
|
|||
|
||||
BfIRType BfModule::GetIRLoweredType(BfTypeCode loweredTypeCode, BfTypeCode loweredTypeCode2)
|
||||
{
|
||||
BF_ASSERT(!mIsConstModule);
|
||||
BF_ASSERT(!mIsComptimeModule);
|
||||
|
||||
BF_ASSERT(loweredTypeCode != BfTypeCode_None);
|
||||
if (loweredTypeCode2 == BfTypeCode_None)
|
||||
|
|
|
@ -341,6 +341,7 @@ BfParser::BfParser(BfSystem* bfSystem, BfProject* bfProject) : BfSource(bfSystem
|
|||
mAwaitingDelete = false;
|
||||
mScanOnly = false;
|
||||
mCompleteParse = false;
|
||||
mIsEmitted = false;
|
||||
mJumpTable = NULL;
|
||||
mProject = bfProject;
|
||||
mPassInstance = NULL;
|
||||
|
@ -525,6 +526,8 @@ void BfParser::SetSource(const char* data, int length)
|
|||
canCache = false;
|
||||
if (mProject == NULL)
|
||||
canCache = false;
|
||||
if (mIsEmitted)
|
||||
canCache = false;
|
||||
|
||||
uint64 cacheHash = 0;
|
||||
if (canCache)
|
||||
|
@ -3447,8 +3450,11 @@ void BfParser::Parse(BfPassInstance* passInstance)
|
|||
{
|
||||
BP_ZONE_F("BfParser::Parse %s", mFileName.c_str());
|
||||
|
||||
mSyntaxToken = BfSyntaxToken_None;
|
||||
mPassInstance = passInstance;
|
||||
|
||||
int startIdx = mSrcIdx;
|
||||
|
||||
if (mUsingCache)
|
||||
{
|
||||
mRootNode = mParserData->mRootNode;
|
||||
|
@ -3476,7 +3482,7 @@ void BfParser::Parse(BfPassInstance* passInstance)
|
|||
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)
|
||||
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)
|
||||
{
|
||||
BfSourcePositionFinder posFinder(this, srcPosition);
|
||||
|
|
|
@ -157,6 +157,7 @@ public:
|
|||
bool mQuickCompatMode;
|
||||
bool mScanOnly;
|
||||
bool mCompleteParse;
|
||||
bool mIsEmitted;
|
||||
BfLineStartEntry* mJumpTable;
|
||||
int mJumpTableSize;
|
||||
int mOrigSrcLength;
|
||||
|
@ -231,6 +232,7 @@ public:
|
|||
void Parse(BfPassInstance* passInstance);
|
||||
int GetCharIdAtIndex(int findIndex);
|
||||
virtual void Close() override;
|
||||
virtual void HadSrcRealloc() override;
|
||||
|
||||
void GenerateAutoCompleteFrom(int srcPosition);
|
||||
|
||||
|
|
|
@ -1143,7 +1143,7 @@ void BfMethodInstance::GetIRFunctionInfo(BfModule* module, BfIRType& returnType,
|
|||
|
||||
BfTypeCode loweredReturnTypeCode = BfTypeCode_None;
|
||||
BfTypeCode loweredReturnTypeCode2 = BfTypeCode_None;
|
||||
if ((!module->mIsConstModule) && (GetLoweredReturnType(&loweredReturnTypeCode, &loweredReturnTypeCode2)))
|
||||
if ((!module->mIsComptimeModule) && (GetLoweredReturnType(&loweredReturnTypeCode, &loweredReturnTypeCode2)))
|
||||
{
|
||||
auto irReturnType = module->GetIRLoweredType(loweredReturnTypeCode, loweredReturnTypeCode2);
|
||||
returnType = irReturnType;
|
||||
|
@ -1153,7 +1153,7 @@ void BfMethodInstance::GetIRFunctionInfo(BfModule* module, BfIRType& returnType,
|
|||
auto voidType = module->GetPrimitiveType(BfTypeCode_None);
|
||||
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);
|
||||
returnType = module->mBfIRBuilder->MapType(voidType);
|
||||
|
@ -1210,11 +1210,11 @@ void BfMethodInstance::GetIRFunctionInfo(BfModule* module, BfIRType& returnType,
|
|||
{
|
||||
checkType = checkType->GetUnderlyingType();
|
||||
}
|
||||
else if ((!module->mIsConstModule) && (checkType->IsSplattable()) && (AllowsSplatting(-1)))
|
||||
else if ((!module->mIsComptimeModule) && (checkType->IsSplattable()) && (AllowsSplatting(-1)))
|
||||
{
|
||||
doSplat = true;
|
||||
}
|
||||
else if ((!module->mIsConstModule) && (!mMethodDef->mIsMutating) && (mCallingConvention == BfCallingConvention_Unspecified))
|
||||
else if ((!module->mIsComptimeModule) && (!mMethodDef->mIsMutating) && (mCallingConvention == BfCallingConvention_Unspecified))
|
||||
checkLowered = true;
|
||||
}
|
||||
else
|
||||
|
@ -1227,11 +1227,11 @@ void BfMethodInstance::GetIRFunctionInfo(BfModule* module, BfIRType& returnType,
|
|||
{
|
||||
checkType = checkType->GetUnderlyingType();
|
||||
}
|
||||
else if ((!module->mIsConstModule) && (checkType->IsSplattable()) && (AllowsSplatting(paramIdx)))
|
||||
else if ((!module->mIsComptimeModule) && (checkType->IsSplattable()) && (AllowsSplatting(paramIdx)))
|
||||
{
|
||||
doSplat = true;
|
||||
}
|
||||
else if (!module->mIsConstModule)
|
||||
else if (!module->mIsComptimeModule)
|
||||
checkLowered = true;
|
||||
}
|
||||
|
||||
|
@ -1311,7 +1311,7 @@ void BfMethodInstance::GetIRFunctionInfo(BfModule* module, BfIRType& returnType,
|
|||
paramIdx++; // Skip over the explicit 'this'
|
||||
}
|
||||
|
||||
if ((!module->mIsConstModule) && (GetStructRetIdx(forceStatic) == 1))
|
||||
if ((!module->mIsComptimeModule) && (GetStructRetIdx(forceStatic) == 1))
|
||||
{
|
||||
BF_SWAP(paramTypes[0], paramTypes[1]);
|
||||
}
|
||||
|
@ -1509,6 +1509,8 @@ BfTypeInstance::~BfTypeInstance()
|
|||
delete methodInst;
|
||||
for (auto operatorInfo : mOperatorInfo)
|
||||
delete operatorInfo;
|
||||
for (auto localMethod : mOwnedLocalMethods)
|
||||
delete localMethod;
|
||||
delete mHotTypeData;
|
||||
delete mConstHolder;
|
||||
}
|
||||
|
|
|
@ -416,7 +416,9 @@ enum BfTypeRebuildFlags
|
|||
BfTypeRebuildFlag_UnderlyingTypeDeferred = 0x1000,
|
||||
BfTypeRebuildFlag_TypeDataSaved = 0x2000,
|
||||
BfTypeRebuildFlag_InTempPool = 0x4000,
|
||||
BfTypeRebuildFlag_ResolvingBase = 0x8000
|
||||
BfTypeRebuildFlag_ResolvingBase = 0x8000,
|
||||
BfTypeRebuildFlag_InFailTypes = 0x10000,
|
||||
BfTypeRebuildFlag_RebuildQueued = 0x20000,
|
||||
};
|
||||
|
||||
class BfTypeDIReplaceCallback;
|
||||
|
@ -427,7 +429,10 @@ enum BfTypeDefineState : uint8
|
|||
BfTypeDefineState_Declared,
|
||||
BfTypeDefineState_ResolvingBaseType,
|
||||
BfTypeDefineState_HasInterfaces,
|
||||
BfTypeDefineState_CETypeInit,
|
||||
BfTypeDefineState_CEPostTypeInit,
|
||||
BfTypeDefineState_Defined,
|
||||
BfTypeDefineState_CEAfterFields,
|
||||
BfTypeDefineState_DefinedAndMethodsSlotted,
|
||||
};
|
||||
|
||||
|
@ -830,6 +835,7 @@ public:
|
|||
bool mInCEMachine:1;
|
||||
bool mIsDisposed:1;
|
||||
BfMethodChainType mChainType;
|
||||
BfComptimeFlags mComptimeFlags;
|
||||
BfCallingConvention mCallingConvention;
|
||||
BfMethodInstanceGroup* mMethodInstanceGroup;
|
||||
BfMethodDef* mMethodDef;
|
||||
|
@ -868,6 +874,7 @@ public:
|
|||
mInCEMachine = false;
|
||||
mIsDisposed = false;
|
||||
mChainType = BfMethodChainType_None;
|
||||
mComptimeFlags = BfComptimeFlag_None;
|
||||
mCallingConvention = BfCallingConvention_Unspecified;
|
||||
mMethodInstanceGroup = NULL;
|
||||
mMethodDef = NULL;
|
||||
|
@ -1792,6 +1799,7 @@ public:
|
|||
Array<BfMethodInstance*> mInternalMethods;
|
||||
Dictionary<BfTypeDef*, BfStaticSearch> mStaticSearchMap;
|
||||
Dictionary<BfTypeDef*, BfInternalAccessSet> mInternalAccessMap;
|
||||
Array<BfLocalMethod*> mOwnedLocalMethods; // Local methods in CEMachine
|
||||
bool mHasStaticInitMethod;
|
||||
bool mHasStaticDtorMethod;
|
||||
bool mHasStaticMarkMethod;
|
||||
|
@ -1969,7 +1977,7 @@ public:
|
|||
bool IsAlwaysInclude();
|
||||
bool HasBeenInstantiated() { return mHasBeenInstantiated || ((mAlwaysIncludeFlags & BfAlwaysIncludeFlag_AssumeInstantiated) != 0); }
|
||||
bool IncludeAllMethods() { return ((mAlwaysIncludeFlags & BfAlwaysIncludeFlag_IncludeAllMethods) != 0); }
|
||||
|
||||
bool DefineStateAllowsStaticMethods() { return mDefineState >= BfTypeDefineState_HasInterfaces; }
|
||||
|
||||
virtual void ReportMemory(MemReporter* memReporter) override;
|
||||
};
|
||||
|
|
|
@ -91,6 +91,8 @@ int BfSource::AllocChars(int charCount)
|
|||
|
||||
BF_ASSERT(mSourceData->ToParser() != NULL);
|
||||
mSourceData->mSrc = mSrc;
|
||||
|
||||
HadSrcRealloc();
|
||||
}
|
||||
|
||||
int retVal = mSrcLength;
|
||||
|
|
|
@ -101,6 +101,7 @@ public:
|
|||
virtual ~BfSource();
|
||||
|
||||
virtual BfParser* ToParser() { return NULL; }
|
||||
virtual void HadSrcRealloc() {}
|
||||
|
||||
BfErrorNode* CreateErrorNode(BfAstNode* astNode);
|
||||
void AddErrorNode(BfAstNode* astNode);
|
||||
|
|
|
@ -42,7 +42,7 @@ USING_NS_BF;
|
|||
|
||||
bool BfModule::AddDeferredCallEntry(BfDeferredCallEntry* deferredCallEntry, BfScopeData* scopeData)
|
||||
{
|
||||
if ((((mCompiler->mIsResolveOnly) && (!mIsConstModule)) ||
|
||||
if ((((mCompiler->mIsResolveOnly) && (!mIsComptimeModule)) ||
|
||||
(mBfIRBuilder->mIgnoreWrites)) && (deferredCallEntry->mDeferredBlock == NULL))
|
||||
{
|
||||
// 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)
|
||||
{
|
||||
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
|
||||
return;
|
||||
|
@ -1770,7 +1770,7 @@ BfLocalVariable* BfModule::HandleVariableDeclaration(BfVariableDeclaration* varD
|
|||
initValue = LoadValue(initValue);
|
||||
if (initValue.IsSplat())
|
||||
{
|
||||
BF_ASSERT(!mIsConstModule);
|
||||
BF_ASSERT(!mIsComptimeModule);
|
||||
if (!localDef->mAddr)
|
||||
localDef->mAddr = AllocLocalVariable(resolvedType, localDef->mName);
|
||||
AggregateSplatIntoAddr(initValue, localDef->mAddr);
|
||||
|
@ -3944,7 +3944,7 @@ void BfModule::Visit(BfDeleteStatement* deleteStmt)
|
|||
allowPrivate = false;
|
||||
}
|
||||
|
||||
if ((mCompiler->mOptions.mObjectHasDebugFlags) && (!mIsConstModule))
|
||||
if ((mCompiler->mOptions.mObjectHasDebugFlags) && (!mIsComptimeModule))
|
||||
{
|
||||
auto preDelete = GetInternalMethod((deleteStmt->mTargetTypeToken != NULL) ? "Dbg_ObjectPreCustomDelete" : "Dbg_ObjectPreDelete");
|
||||
SizedArray<BfIRValue, 4> llvmArgs;
|
||||
|
@ -4001,7 +4001,7 @@ void BfModule::Visit(BfDeleteStatement* deleteStmt)
|
|||
}
|
||||
else
|
||||
{
|
||||
if ((mCompiler->mOptions.mEnableRealtimeLeakCheck) && (!mIsConstModule))
|
||||
if ((mCompiler->mOptions.mEnableRealtimeLeakCheck) && (!mIsComptimeModule))
|
||||
{
|
||||
SizedArray<BfIRValue, 4> llvmArgs;
|
||||
llvmArgs.push_back(mBfIRBuilder->CreateBitCast(val.mValue, mBfIRBuilder->MapType(objectType)));
|
||||
|
@ -4958,12 +4958,12 @@ void BfModule::Visit(BfReturnStatement* returnStmt)
|
|||
BfType* origType;
|
||||
BfExprEvaluator exprEvaluator(this);
|
||||
bool alreadyWritten = false;
|
||||
if ((!mIsConstModule) && (mCurMethodInstance->GetStructRetIdx() != -1))
|
||||
if ((!mIsComptimeModule) && (mCurMethodInstance->GetStructRetIdx() != -1))
|
||||
exprEvaluator.mReceivingValue = &mCurMethodState->mRetVal;
|
||||
if (mCurMethodInstance->mMethodDef->mIsReadOnly)
|
||||
exprEvaluator.mAllowReadOnlyReference = true;
|
||||
auto retValue = CreateValueFromExpression(exprEvaluator, returnStmt->mExpression, expectingReturnType, BfEvalExprFlags_AllowRefExpr, &origType);
|
||||
if ((!mIsConstModule) && (mCurMethodInstance->GetStructRetIdx() != -1))
|
||||
if ((!mIsComptimeModule) && (mCurMethodInstance->GetStructRetIdx() != -1))
|
||||
alreadyWritten = exprEvaluator.mReceivingValue == NULL;
|
||||
MarkScopeLeft(&mCurMethodState->mHeadScope);
|
||||
|
||||
|
@ -6453,7 +6453,7 @@ void BfModule::Visit(BfForEachStatement* forEachStmt)
|
|||
auto retVal = exprEvaluator.CreateCall(&methodMatcher, itr);
|
||||
if (exprEvaluator.mReceivingValue != NULL)
|
||||
{
|
||||
if (mIsConstModule)
|
||||
if (mIsComptimeModule)
|
||||
{
|
||||
mBfIRBuilder->CreateStore(retVal.mValue, nextResult.mValue);
|
||||
}
|
||||
|
@ -6802,7 +6802,7 @@ void BfModule::Visit(BfDeferStatement* deferStmt)
|
|||
|
||||
if (!customAllocator)
|
||||
{
|
||||
if ((mCompiler->mOptions.mEnableRealtimeLeakCheck) && (!mIsConstModule))
|
||||
if ((mCompiler->mOptions.mEnableRealtimeLeakCheck) && (!mIsComptimeModule))
|
||||
{
|
||||
auto moduleMethodInstance = GetInternalMethod("Dbg_MarkObjectDeleted");
|
||||
AddDeferredCall(moduleMethodInstance, llvmArgs, scope, deleteStmt, false, true);
|
||||
|
@ -6819,7 +6819,7 @@ void BfModule::Visit(BfDeferStatement* deferStmt)
|
|||
auto moduleMethodInstance = GetMethodInstance(objectType, methodInstance->mMethodDef, BfTypeVector());
|
||||
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");
|
||||
AddDeferredCall(moduleMethodInstance, llvmArgs, scope, deleteStmt, false, true);
|
||||
|
@ -6831,7 +6831,7 @@ void BfModule::Visit(BfDeferStatement* deferStmt)
|
|||
{
|
||||
val = LoadValue(val);
|
||||
BfModuleMethodInstance moduleMethodInstance;
|
||||
if ((mCompiler->mOptions.mDebugAlloc) && (!mIsConstModule))
|
||||
if ((mCompiler->mOptions.mDebugAlloc) && (!mIsComptimeModule))
|
||||
moduleMethodInstance = GetMethodByName(internalType->ToTypeInstance(), "Dbg_RawFree");
|
||||
else
|
||||
moduleMethodInstance = GetMethodByName(internalType->ToTypeInstance(), "Free");
|
||||
|
|
|
@ -679,6 +679,42 @@ void BfTypeDef::FreeMembers()
|
|||
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()
|
||||
{
|
||||
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()
|
||||
{
|
||||
BfLogSysM("BfTypeDef::~BfTypeDef %08X\n", this);
|
||||
|
@ -732,6 +775,12 @@ BfTypeDef::~BfTypeDef()
|
|||
mSource->mRefCount--;
|
||||
BF_ASSERT(mSource->mRefCount >= 0);
|
||||
}
|
||||
|
||||
if (mEmitParser != NULL)
|
||||
{
|
||||
mEmitParser->mRefCount--;
|
||||
BF_ASSERT(mEmitParser->mRefCount >= 0);
|
||||
}
|
||||
}
|
||||
|
||||
BfSource* BfTypeDef::GetLastSource()
|
||||
|
@ -1533,6 +1582,8 @@ BfError* BfPassInstance::WarnAt(int warningNumber, const StringImpl& warning, Bf
|
|||
if (!WantsRangeRecorded(bfParser, srcIdx, srcLen, true))
|
||||
return NULL;
|
||||
|
||||
mWarnIdx++;
|
||||
|
||||
TrimSourceRange(bfSource, srcIdx, srcLen);
|
||||
|
||||
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)
|
||||
{
|
||||
mWarnIdx++;
|
||||
mLastWasAdded = false;
|
||||
mLastWasDisplayed = (int)mErrors.size() <= sMaxDisplayErrors;
|
||||
if (!mLastWasDisplayed)
|
||||
|
@ -1577,6 +1629,7 @@ BfError* BfPassInstance::Warn(int warningNumber, const StringImpl& warning, BfAs
|
|||
{
|
||||
BP_ZONE("BfPassInstance::Warn");
|
||||
|
||||
mWarnIdx++;
|
||||
mLastWasAdded = false;
|
||||
mLastWasDisplayed = (int)mErrors.size() <= sMaxErrors;
|
||||
if (!mLastWasDisplayed)
|
||||
|
@ -1638,9 +1691,9 @@ BfMoreInfo* BfPassInstance::MoreInfoAt(const StringImpl& info, BfSourceData* bfS
|
|||
return NULL;
|
||||
}
|
||||
|
||||
BfMoreInfo* BfPassInstance::MoreInfo(const StringImpl& info)
|
||||
BfMoreInfo* BfPassInstance::MoreInfo(const StringImpl& info, bool forceQueue)
|
||||
{
|
||||
if (!mLastWasDisplayed)
|
||||
if ((!mLastWasDisplayed) || (forceQueue))
|
||||
{
|
||||
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);
|
||||
|
||||
typeDef->ClearEmitted();
|
||||
|
||||
bool setDeclaringType = !typeDef->mIsCombinedPartial;
|
||||
|
||||
auto nextTypeDef = typeDef->mNextRevision;
|
||||
|
@ -2663,6 +2718,7 @@ void BfSystem::InjectNewRevision(BfTypeDef* typeDef)
|
|||
typeDef->mIsConcrete = nextTypeDef->mIsConcrete;
|
||||
typeDef->mIsStatic = nextTypeDef->mIsStatic;
|
||||
typeDef->mHasAppendCtor = nextTypeDef->mHasAppendCtor;
|
||||
typeDef->mHasCEOnCompile = nextTypeDef->mHasCEOnCompile;
|
||||
typeDef->mHasCtorNoBody = nextTypeDef->mHasCtorNoBody;
|
||||
typeDef->mHasOverrideMethods = nextTypeDef->mHasOverrideMethods;
|
||||
typeDef->mHasExtensionMethods = nextTypeDef->mHasExtensionMethods;
|
||||
|
@ -2771,6 +2827,8 @@ void BfSystem::AddToCompositePartial(BfPassInstance* passInstance, BfTypeDef* co
|
|||
typeDef->mHasCtorNoBody = partialTypeDef->mHasCtorNoBody;
|
||||
typeDef->mHasExtensionMethods = partialTypeDef->mHasExtensionMethods;
|
||||
typeDef->mHasOverrideMethods = partialTypeDef->mHasOverrideMethods;
|
||||
typeDef->mIsAlwaysInclude = partialTypeDef->mIsAlwaysInclude;
|
||||
typeDef->mHasCEOnCompile = partialTypeDef->mHasCEOnCompile;
|
||||
|
||||
for (auto generic : partialTypeDef->mGenericParamDefs)
|
||||
{
|
||||
|
@ -2806,6 +2864,7 @@ void BfSystem::AddToCompositePartial(BfPassInstance* passInstance, BfTypeDef* co
|
|||
typeDef->mIsConcrete |= partialTypeDef->mIsConcrete;
|
||||
typeDef->mIsStatic |= partialTypeDef->mIsStatic;
|
||||
typeDef->mHasAppendCtor |= partialTypeDef->mHasAppendCtor;
|
||||
typeDef->mHasCEOnCompile |= partialTypeDef->mHasCEOnCompile;
|
||||
typeDef->mHasExtensionMethods |= partialTypeDef->mHasExtensionMethods;
|
||||
typeDef->mHasOverrideMethods |= partialTypeDef->mHasOverrideMethods;
|
||||
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);
|
||||
|
||||
mParsers.RemoveAt(i);
|
||||
i--;
|
||||
|
||||
mDataLock.Unlock();
|
||||
delete bfParser;
|
||||
mDataLock.Lock();
|
||||
|
||||
mParsers.erase(mParsers.begin() + i);
|
||||
i--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -218,6 +218,13 @@ enum BfAlwaysIncludeFlags : uint8
|
|||
BfAlwaysIncludeFlag_All = BfAlwaysIncludeFlag_Type | BfAlwaysIncludeFlag_IncludeAllMethods | BfAlwaysIncludeFlag_AssumeInstantiated
|
||||
};
|
||||
|
||||
enum BfCEOnCompileKind : uint8
|
||||
{
|
||||
BfCEOnCompileKind_None,
|
||||
BfCEOnCompileKind_TypeInit,
|
||||
BfCEOnCompileKind_TypeDone
|
||||
};
|
||||
|
||||
enum BfPlatformType
|
||||
{
|
||||
BfPlatformType_Unknown,
|
||||
|
@ -740,6 +747,14 @@ enum BfCommutableKind : int8
|
|||
BfCommutableKind_Reverse,
|
||||
};
|
||||
|
||||
enum BfComptimeFlags : int8
|
||||
{
|
||||
BfComptimeFlag_None,
|
||||
BfComptimeFlag_Comptime = 1,
|
||||
BfComptimeFlag_OnlyFromComptime = 2,
|
||||
BfComptimeFlag_ConstEval = 4
|
||||
};
|
||||
|
||||
class BfMethodDef : public BfMemberDef
|
||||
{
|
||||
public:
|
||||
|
@ -774,7 +789,7 @@ public:
|
|||
bool mIsNoSplat;
|
||||
bool mIsNoReflect;
|
||||
bool mIsSkipCall;
|
||||
bool mIsConstEval;
|
||||
bool mHasComptime;
|
||||
bool mIsOperator;
|
||||
bool mIsExtern;
|
||||
bool mIsNoDiscard;
|
||||
|
@ -803,7 +818,7 @@ public:
|
|||
mIsNoSplat = false;
|
||||
mIsNoReflect = false;
|
||||
mIsSkipCall = false;
|
||||
mIsConstEval = false;
|
||||
mHasComptime = false;
|
||||
mIsOperator = false;
|
||||
mIsExtern = false;
|
||||
mIsNoDiscard = false;
|
||||
|
@ -919,6 +934,7 @@ public:
|
|||
BfProject* mProject;
|
||||
BfTypeDeclaration* mTypeDeclaration;
|
||||
BfSource* mSource;
|
||||
BfParser* mEmitParser;
|
||||
DefState mDefState;
|
||||
Val128 mSignatureHash; // Data, methods, etc
|
||||
Val128 mFullHash;
|
||||
|
@ -966,6 +982,7 @@ public:
|
|||
bool mIsAbstract;
|
||||
bool mIsConcrete;
|
||||
bool mIsStatic;
|
||||
bool mHasCEOnCompile;
|
||||
bool mHasAppendCtor;
|
||||
bool mHasCtorNoBody;
|
||||
bool mHasExtensionMethods;
|
||||
|
@ -973,6 +990,7 @@ public:
|
|||
bool mIsOpaque;
|
||||
bool mIsNextRevision;
|
||||
bool mInDeleteQueue;
|
||||
bool mHasEmitMembers;
|
||||
|
||||
public:
|
||||
BfTypeDef()
|
||||
|
@ -996,6 +1014,7 @@ public:
|
|||
mIsCombinedPartial = false;
|
||||
mTypeDeclaration = NULL;
|
||||
mSource = NULL;
|
||||
mEmitParser = NULL;
|
||||
mDefState = DefState_New;
|
||||
mHash = 0;
|
||||
mPartialIdx = -1;
|
||||
|
@ -1005,6 +1024,7 @@ public:
|
|||
mIsFunction = false;
|
||||
mIsClosure = false;
|
||||
mIsStatic = false;
|
||||
mHasCEOnCompile = false;
|
||||
mHasAppendCtor = false;
|
||||
mHasCtorNoBody = false;
|
||||
mHasExtensionMethods = false;
|
||||
|
@ -1013,6 +1033,7 @@ public:
|
|||
mPartialUsed = false;
|
||||
mIsNextRevision = false;
|
||||
mInDeleteQueue = false;
|
||||
mHasEmitMembers = false;
|
||||
mDupDetectedRevision = -1;
|
||||
mNestDepth = 0;
|
||||
mOuterType = NULL;
|
||||
|
@ -1026,7 +1047,9 @@ public:
|
|||
bool IsGlobalsContainer();
|
||||
void Reset();
|
||||
void FreeMembers();
|
||||
void ClearEmitted();
|
||||
void PopulateMemberSets();
|
||||
void ClearMemberSets();
|
||||
void RemoveGenericParamDef(BfGenericParamDef* genericParamDef);
|
||||
int GetSelfGenericParamCount();
|
||||
String ToString();
|
||||
|
@ -1284,6 +1307,7 @@ public:
|
|||
BfSystem* mSystem;
|
||||
bool mTrimMessagesToCursor;
|
||||
int mFailedIdx;
|
||||
int mWarnIdx;
|
||||
|
||||
Dictionary<BfSourceData*, String> mSourceFileNameMap;
|
||||
HashSet<BfErrorEntry> mErrorSet;
|
||||
|
@ -1303,6 +1327,7 @@ public:
|
|||
{
|
||||
mTrimMessagesToCursor = false;
|
||||
mFailedIdx = 0;
|
||||
mWarnIdx = 0;
|
||||
mSystem = bfSystem;
|
||||
mLastWasDisplayed = false;
|
||||
mLastWasAdded = false;
|
||||
|
@ -1336,7 +1361,7 @@ public:
|
|||
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* MoreInfo(const StringImpl& info);
|
||||
BfMoreInfo* MoreInfo(const StringImpl& info, bool forceQueue = false);
|
||||
BfMoreInfo* MoreInfo(const StringImpl& info, BfAstNode* refNode);
|
||||
BfMoreInfo* MoreInfoAfter(const StringImpl& info, BfAstNode* refNode);
|
||||
|
||||
|
|
|
@ -729,7 +729,6 @@ CeOperand CeBuilder::GetOperand(BeValue* value, bool allowAlloca, bool allowImme
|
|||
if (mCeMachine->mStaticFieldMap.TryGetValue(globalVar->mName, &staticFieldInfoPtr))
|
||||
{
|
||||
CeStaticFieldInfo* staticFieldInfo = staticFieldInfoPtr;
|
||||
|
||||
int* staticFieldTableIdxPtr = NULL;
|
||||
if (mStaticFieldMap.TryAdd(globalVar, NULL, &staticFieldTableIdxPtr))
|
||||
{
|
||||
|
@ -1190,8 +1189,6 @@ void CeBuilder::Build()
|
|||
|
||||
bool isGenericVariation = (methodInstance->mIsUnspecializedVariation) || (methodInstance->GetOwner()->IsUnspecializedTypeVariation());
|
||||
int dependentGenericStartIdx = 0;
|
||||
if (methodInstance->mMethodInfoEx != NULL)
|
||||
dependentGenericStartIdx = (int)methodInstance->mMethodInfoEx->mMethodGenericArguments.size();
|
||||
if ((((methodInstance->mMethodInfoEx != NULL) && ((int)methodInstance->mMethodInfoEx->mMethodGenericArguments.size() > dependentGenericStartIdx)) ||
|
||||
((methodInstance->GetOwner()->IsGenericTypeInstance()) && (!isGenericVariation) && (!methodInstance->mMethodDef->mIsLocalMethod))))
|
||||
{
|
||||
|
@ -2646,10 +2643,14 @@ CeMachine::CeMachine(BfCompiler* compiler)
|
|||
mCurFunctionId = 0;
|
||||
mRevisionExecuteTime = 0;
|
||||
mCurTargetSrc = NULL;
|
||||
mCurBuilder = NULL;
|
||||
mPreparingFunction = NULL;
|
||||
mCurEvalFlags = CeEvalFlags_None;
|
||||
mCurFrame = NULL;
|
||||
mCurModule = NULL;
|
||||
mCurMethodInstance = NULL;
|
||||
mCurExpectingType = NULL;
|
||||
mCurEmitContext = NULL;
|
||||
mHeap = NULL;
|
||||
mStringCharsOffset = -1;
|
||||
mAppendAllocInfo = NULL;
|
||||
|
@ -2689,19 +2690,25 @@ CeMachine::~CeMachine()
|
|||
|
||||
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)
|
||||
return NULL;
|
||||
mCompiler->mPassInstance->MoreInfo(error);
|
||||
mCompiler->mPassInstance->MoreInfo(error, mCeModule->mCompiler->GetAutoComplete() != NULL);
|
||||
return bfError;
|
||||
}
|
||||
|
||||
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)
|
||||
return NULL;
|
||||
|
||||
if ((mCurEvalFlags & CeEvalFlags_DeferIfNotOnlyError) != 0)
|
||||
{
|
||||
if (mCurModule->mHadBuildError)
|
||||
bfError->mIsDeferred = true;
|
||||
}
|
||||
|
||||
auto passInstance = mCompiler->mPassInstance;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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)
|
||||
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))
|
||||
{
|
||||
BfErrorLocation* location = new BfErrorLocation();
|
||||
|
@ -2785,7 +2792,7 @@ void CeMachine::Init()
|
|||
mCeModule = new BfModule(mCompiler->mContext, "__constEval");
|
||||
mCeModule->mIsSpecialModule = true;
|
||||
//mCeModule->mIsScratchModule = true;
|
||||
mCeModule->mIsConstModule = true;
|
||||
mCeModule->mIsComptimeModule = true;
|
||||
//mCeModule->mIsReified = true;
|
||||
if (mCompiler->mIsResolveOnly)
|
||||
mCeModule->mIsReified = true;
|
||||
|
@ -2882,6 +2889,7 @@ addr_ce CeMachine::GetReflectType(int typeId)
|
|||
if (bfType == NULL)
|
||||
return 0;
|
||||
|
||||
if (bfType->mDefineState != BfTypeDefineState_CETypeInit)
|
||||
mCeModule->PopulateType(bfType, BfPopulateType_DataAndMethods);
|
||||
|
||||
Dictionary<int, int> usedStringMap;
|
||||
|
@ -2991,6 +2999,30 @@ void CeMachine::PrepareConstStructEntry(CeConstStructData& constEntry)
|
|||
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()
|
||||
{
|
||||
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)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -3489,7 +3534,6 @@ CeErrorKind CeMachine::WriteConstant(CeConstStructData& data, BeConstant* constV
|
|||
return CeErrorKind_None;
|
||||
}
|
||||
|
||||
|
||||
#define CE_CREATECONST_CHECKPTR(PTR, SIZE) \
|
||||
if ((((uint8*)(PTR) - memStart) - 0x10000) + (SIZE) > (memSize - 0x10000)) \
|
||||
{ \
|
||||
|
@ -3829,8 +3873,10 @@ bool CeMachine::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
|
|||
uint8* stackPtr = startStackPtr;
|
||||
uint8* framePtr = startFramePtr;
|
||||
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 = [&]()
|
||||
{
|
||||
|
@ -3973,12 +4019,30 @@ bool CeMachine::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
|
|||
handled = 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)
|
||||
{
|
||||
int32 sleepMS = *(int32*)((uint8*)stackPtr);
|
||||
while (sleepMS > 0)
|
||||
{
|
||||
if (*cancelPtr)
|
||||
if (*fastFinishPtr)
|
||||
break;
|
||||
|
||||
if (sleepMS > 200)
|
||||
|
@ -4104,9 +4168,9 @@ bool CeMachine::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
|
|||
|
||||
if (!checkFunction->mFailed)
|
||||
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()))
|
||||
mCompiler->mPassInstance->MoreInfo("Const Method Generation Error: " + checkFunction->mGenError);
|
||||
mCompiler->mPassInstance->MoreInfo("Comptime method generation error: " + checkFunction->mGenError);
|
||||
return false;
|
||||
};
|
||||
|
||||
|
@ -4124,9 +4188,10 @@ bool CeMachine::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
|
|||
|
||||
while (true)
|
||||
{
|
||||
if (*cancelPtr)
|
||||
if (*fastFinishPtr)
|
||||
{
|
||||
_Fail("Compilation cancelled");
|
||||
if (*cancelingPtr)
|
||||
_Fail("Comptime evaluation canceled");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -4576,9 +4641,13 @@ bool CeMachine::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
|
|||
|
||||
if (staticFieldInfo->mAddr == 0)
|
||||
{
|
||||
if (ceStaticFieldEntry.mSize < 0)
|
||||
_Fail(StrFormat("Reference to unsized global variable '%s'", ceStaticFieldEntry.mName.c_str()));
|
||||
|
||||
CE_CHECKALLOC(ceStaticFieldEntry.mSize);
|
||||
uint8* ptr = CeMalloc(ceStaticFieldEntry.mSize);
|
||||
_FixVariables();
|
||||
if (ceStaticFieldEntry.mSize > 0)
|
||||
memset(ptr, 0, ceStaticFieldEntry.mSize);
|
||||
staticFieldInfo->mAddr = (addr_ce)(ptr - memStart);
|
||||
}
|
||||
|
@ -4641,6 +4710,8 @@ bool CeMachine::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
|
|||
callEntry.mFunction = callEntry.mFunctionInfo->mCeFunction;
|
||||
if (!callEntry.mFunction->mInitialized)
|
||||
{
|
||||
auto curFrame = _GetCurFrame();
|
||||
SetAndRestoreValue<CeFrame*> prevFrame(mCurFrame, &curFrame);
|
||||
PrepareFunction(callEntry.mFunction, NULL);
|
||||
}
|
||||
|
||||
|
@ -4649,6 +4720,12 @@ bool CeMachine::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
|
|||
|
||||
BF_ASSERT(memStart == mMemory.mVals);
|
||||
auto callFunction = callEntry.mFunction;
|
||||
|
||||
if (callFunction->mMethodInstance->mMethodDef->mIsLocalMethod)
|
||||
{
|
||||
NOP;
|
||||
}
|
||||
|
||||
if (needsFunctionIds)
|
||||
*(int32*)(framePtr + resultFrameIdx) = callFunction->mId;
|
||||
else
|
||||
|
@ -4678,7 +4755,14 @@ bool CeMachine::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
|
|||
|
||||
CE_CHECKADDR(valueAddr, sizeof(int32));
|
||||
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())
|
||||
mCeModule->PopulateType(valueType, BfPopulateType_DataAndMethods);
|
||||
auto methodInstance = (BfMethodInstance*)valueType->mVirtualMethodTable[virtualIdx].mImplementingMethod;
|
||||
|
@ -4702,11 +4786,13 @@ bool CeMachine::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
|
|||
CE_CHECKADDR(valueAddr, sizeof(int32));
|
||||
int32 objTypeId = *(int32*)(memStart + valueAddr);
|
||||
auto valueType = mCeModule->mContext->mTypes[objTypeId]->ToTypeInstance();
|
||||
BfMethodInstance* methodInstance = NULL;
|
||||
|
||||
if (valueType != NULL)
|
||||
{
|
||||
if (valueType->mVirtualMethodTable.IsEmpty())
|
||||
mCeModule->PopulateType(valueType, BfPopulateType_DataAndMethods);
|
||||
|
||||
BfMethodInstance* methodInstance = NULL;
|
||||
|
||||
auto checkType = valueType;
|
||||
while (checkType != NULL)
|
||||
{
|
||||
|
@ -4720,6 +4806,7 @@ bool CeMachine::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
|
|||
}
|
||||
checkType = checkType->mBaseType;
|
||||
}
|
||||
}
|
||||
|
||||
if (methodInstance == NULL)
|
||||
{
|
||||
|
@ -5305,18 +5392,25 @@ void CeMachine::PrepareFunction(CeFunction* ceFunction, CeBuilder* parentBuilder
|
|||
auto owner = ceFunction->mMethodInstance->GetOwner();
|
||||
if (owner == mCeModule->mContext->mBfObjectType)
|
||||
{
|
||||
if (methodDef->mName == "ConstEval_GetType")
|
||||
if (methodDef->mName == "Comptime_GetType")
|
||||
{
|
||||
ceFunction->mFunctionKind = CeFunctionKind_GetReflectType;
|
||||
}
|
||||
}
|
||||
else if (owner->IsInstanceOf(mCeModule->mCompiler->mTypeTypeDef))
|
||||
{
|
||||
if (methodDef->mName == "ConstEval_GetTypeById")
|
||||
if (methodDef->mName == "Comptime_GetTypeById")
|
||||
{
|
||||
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))
|
||||
{
|
||||
if (methodDef->mName == "Write")
|
||||
|
@ -5373,6 +5467,7 @@ void CeMachine::PrepareFunction(CeFunction* ceFunction, CeBuilder* parentBuilder
|
|||
ceFunction->mGenerating = true;
|
||||
|
||||
CeBuilder ceBuilder;
|
||||
SetAndRestoreValue<CeBuilder*> prevBuilder(mCurBuilder, &ceBuilder);
|
||||
ceBuilder.mParentBuilder = parentBuilder;
|
||||
ceBuilder.mPtrSize = mCeModule->mCompiler->mSystem->mPtrSize;
|
||||
ceBuilder.mCeMachine = this;
|
||||
|
@ -5534,6 +5629,7 @@ BfTypedValue CeMachine::Call(BfAstNode* targetSrc, BfModule* module, BfMethodIns
|
|||
// DISABLED
|
||||
//return BfTypedValue();
|
||||
|
||||
SetAndRestoreValue<CeEvalFlags> prevEvalFlags(mCurEvalFlags, flags);
|
||||
SetAndRestoreValue<BfAstNode*> prevTargetSrc(mCurTargetSrc, targetSrc);
|
||||
SetAndRestoreValue<BfModule*> prevModule(mCurModule, module);
|
||||
SetAndRestoreValue<BfMethodInstance*> prevMethodInstance(mCurMethodInstance, methodInstance);
|
||||
|
|
|
@ -251,6 +251,7 @@ enum CeFunctionKind
|
|||
CeFunctionKind_DebugWrite_Int,
|
||||
CeFunctionKind_GetReflectType,
|
||||
CeFunctionKind_GetReflectTypeById,
|
||||
CeFunctionKind_EmitDefinition,
|
||||
CeFunctionKind_Sleep,
|
||||
CeFunctionKind_Char32_ToLower,
|
||||
CeFunctionKind_Char32_ToUpper,
|
||||
|
@ -372,7 +373,9 @@ public:
|
|||
enum CeEvalFlags
|
||||
{
|
||||
CeEvalFlags_None = 0,
|
||||
CeEvalFlags_Cascade = 1
|
||||
CeEvalFlags_Cascade = 1,
|
||||
CeEvalFlags_PersistantError = 2,
|
||||
CeEvalFlags_DeferIfNotOnlyError = 4,
|
||||
};
|
||||
|
||||
enum CeOperandKind
|
||||
|
@ -602,6 +605,18 @@ public:
|
|||
BfIRValue mAppendSizeValue;
|
||||
};
|
||||
|
||||
class CeEmitContext
|
||||
{
|
||||
public:
|
||||
BfType* mType;
|
||||
String mEmitData;
|
||||
|
||||
CeEmitContext()
|
||||
{
|
||||
mType = NULL;
|
||||
}
|
||||
};
|
||||
|
||||
class CeMachine
|
||||
{
|
||||
public:
|
||||
|
@ -628,7 +643,11 @@ public:
|
|||
HashSet<int> mStaticCtorExecSet;
|
||||
CeAppendAllocInfo* mAppendAllocInfo;
|
||||
|
||||
CeEmitContext* mCurEmitContext;
|
||||
CeEvalFlags mCurEvalFlags;
|
||||
CeBuilder* mCurBuilder;
|
||||
CeFunction* mPreparingFunction;
|
||||
CeFrame* mCurFrame;
|
||||
BfAstNode* mCurTargetSrc;
|
||||
BfMethodInstance* mCurMethodInstance;
|
||||
BfModule* mCurModule;
|
||||
|
@ -650,6 +669,8 @@ public:
|
|||
addr_ce GetConstantData(BeConstant* constant);
|
||||
BfType* GetBfType(int typeId);
|
||||
void PrepareConstStructEntry(CeConstStructData& constStructData);
|
||||
bool CheckMemory(addr_ce addr, int32 size);
|
||||
bool GetStringFromStringView(addr_ce addr, StringImpl& str);
|
||||
|
||||
BeContext* GetBeContext();
|
||||
BeModule* GetBeModule();
|
||||
|
@ -670,6 +691,7 @@ public:
|
|||
|
||||
public:
|
||||
void CompileStarted();
|
||||
void CompileDone();
|
||||
void QueueMethod(BfMethodInstance* methodInstance, BfIRValue func);
|
||||
void QueueMethod(BfModuleMethodInstance moduleMethodInstance);
|
||||
void QueueStaticField(BfFieldInstance* fieldInstance, const StringImpl& mangledFieldName);
|
||||
|
|
|
@ -23,8 +23,8 @@ namespace Tests
|
|||
const String cStrA = "Abc";
|
||||
const String cStrB = GetStringA(cStrA, 12, 23);
|
||||
|
||||
// ConstEval attribute means this method will always be const-evaluated
|
||||
[ConstEval]
|
||||
// Comptime attribute means this method will always be const-evaluated
|
||||
[Comptime]
|
||||
static String GetStringA(String str, int a, int b)
|
||||
{
|
||||
// Const-eval functions can return scope-allocated data
|
||||
|
@ -101,7 +101,7 @@ namespace Tests
|
|||
}
|
||||
|
||||
// This method can only be const evaluated
|
||||
[ConstEval]
|
||||
[Comptime]
|
||||
public static int32 ConstSum(params int32[] vals)
|
||||
{
|
||||
int32 sum = 0;
|
||||
|
@ -112,8 +112,8 @@ namespace Tests
|
|||
|
||||
public static int32 MethodB()
|
||||
{
|
||||
// Returns different results depending on whether we are const-evaluating
|
||||
return Compiler.IsConstEval ? 1 : 0;
|
||||
// Returns different results depending on whether we are comptime
|
||||
return Compiler.IsComptime ? 1 : 0;
|
||||
}
|
||||
|
||||
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];
|
||||
}
|
||||
|
||||
[ConstEval]
|
||||
[Comptime(ConstEval=true)]
|
||||
static var StrToValue(String str)
|
||||
{
|
||||
if (str.Contains('.'))
|
||||
|
@ -164,7 +164,7 @@ namespace Tests
|
|||
//Compiler.Assert(val1 == 24);
|
||||
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);
|
||||
Compiler.Assert(val2 == 123);
|
||||
|
||||
|
|
|
@ -195,6 +195,22 @@ namespace Tests
|
|||
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]
|
||||
public static void TestBasics()
|
||||
{
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue