mirror of
https://github.com/beefytech/Beef.git
synced 2025-06-08 11:38:21 +02:00
Initial const eval feature release
This commit is contained in:
parent
be929c3626
commit
ff1f8aff3f
27 changed files with 887 additions and 178 deletions
|
@ -260,6 +260,12 @@ namespace System
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[AttributeUsage(.Method | .Invocation)]
|
||||||
|
public struct ConstEvalAttribute : Attribute
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
[AttributeUsage(.Method /*2*/)]
|
[AttributeUsage(.Method /*2*/)]
|
||||||
public struct IntrinsicAttribute : Attribute
|
public struct IntrinsicAttribute : Attribute
|
||||||
{
|
{
|
||||||
|
|
|
@ -34,5 +34,21 @@ namespace System
|
||||||
|
|
||||||
[LinkName("#IsConstEval")]
|
[LinkName("#IsConstEval")]
|
||||||
public static extern bool IsConstEval;
|
public static extern bool IsConstEval;
|
||||||
|
|
||||||
|
[LinkName("#IsBuilding")]
|
||||||
|
public static extern bool IsBuilding;
|
||||||
|
|
||||||
|
[LinkName("#IsReified")]
|
||||||
|
public static extern bool IsReified;
|
||||||
|
|
||||||
|
[LinkName("#CompileRev")]
|
||||||
|
public static extern int32 CompileRev;
|
||||||
|
|
||||||
|
[ConstEval]
|
||||||
|
public static void Assert(bool cond)
|
||||||
|
{
|
||||||
|
if (!cond)
|
||||||
|
Runtime.FatalError("Assert failed");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,6 +36,30 @@ namespace System.Reflection
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool IsConst
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return mFieldData.mFlags.HasFlag(.Const);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool IsStatic
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return mFieldData.mFlags.HasFlag(.Static);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool IsInstanceField
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return !mFieldData.mFlags.HasFlag(.Static) && !mFieldData.mFlags.HasFlag(.Const);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public StringView Name
|
public StringView Name
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
|
@ -520,6 +544,14 @@ namespace System.Reflection
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int32 Index
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return mIdx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public Result<FieldInfo> GetNext() mut
|
public Result<FieldInfo> GetNext() mut
|
||||||
{
|
{
|
||||||
if (!MoveNext())
|
if (!MoveNext())
|
||||||
|
|
|
@ -454,14 +454,20 @@ namespace System
|
||||||
{
|
{
|
||||||
return (int32)mTypeId;
|
return (int32)mTypeId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static extern Type ConstEval_GetTypeById(int32 typeId);
|
||||||
|
|
||||||
protected static Type GetType(TypeId typeId)
|
protected static Type GetType(TypeId typeId)
|
||||||
{
|
{
|
||||||
|
if (Compiler.IsConstEval)
|
||||||
|
return ConstEval_GetTypeById((.)typeId);
|
||||||
return sTypes[(int32)typeId];
|
return sTypes[(int32)typeId];
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static Type GetType_(int32 typeId)
|
protected static Type GetType_(int32 typeId)
|
||||||
{
|
{
|
||||||
|
if (Compiler.IsConstEval)
|
||||||
|
return ConstEval_GetTypeById(typeId);
|
||||||
return sTypes[typeId];
|
return sTypes[typeId];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -148,6 +148,24 @@ public:
|
||||||
~AutoPerfRecordAndPrint();
|
~AutoPerfRecordAndPrint();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class AutoTimer
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
uint32 mStartTick;
|
||||||
|
int* mTimePtr;
|
||||||
|
|
||||||
|
public:
|
||||||
|
AutoTimer(int& timeRef)
|
||||||
|
{
|
||||||
|
mTimePtr = &timeRef;
|
||||||
|
mStartTick = BFTickCount();
|
||||||
|
}
|
||||||
|
|
||||||
|
~AutoTimer()
|
||||||
|
{
|
||||||
|
*mTimePtr += BFTickCount() - mStartTick;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
class DebugTimeGuard
|
class DebugTimeGuard
|
||||||
{
|
{
|
||||||
|
|
|
@ -231,6 +231,12 @@ namespace System
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[AttributeUsage(.Method | .Invocation)]
|
||||||
|
public struct ConstEvalAttribute : Attribute
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
[AttributeUsage(.Method /*2*/)]
|
[AttributeUsage(.Method /*2*/)]
|
||||||
public struct IntrinsicAttribute : Attribute
|
public struct IntrinsicAttribute : Attribute
|
||||||
{
|
{
|
||||||
|
|
|
@ -11781,6 +11781,9 @@ namespace IDE
|
||||||
bool didClean = false;
|
bool didClean = false;
|
||||||
if (mWantsBeefClean)
|
if (mWantsBeefClean)
|
||||||
{
|
{
|
||||||
|
mBfBuildCompiler?.CancelBackground();
|
||||||
|
mBfResolveCompiler?.CancelBackground();
|
||||||
|
|
||||||
if ((!mBfBuildCompiler.HasQueuedCommands()) &&
|
if ((!mBfBuildCompiler.HasQueuedCommands()) &&
|
||||||
((mBfResolveCompiler == null) || (!mBfResolveCompiler.HasQueuedCommands())))
|
((mBfResolveCompiler == null) || (!mBfResolveCompiler.HasQueuedCommands())))
|
||||||
{
|
{
|
||||||
|
@ -11857,6 +11860,9 @@ namespace IDE
|
||||||
|
|
||||||
if (mWantsClean)
|
if (mWantsClean)
|
||||||
{
|
{
|
||||||
|
mBfBuildCompiler?.CancelBackground();
|
||||||
|
mBfResolveCompiler?.CancelBackground();
|
||||||
|
|
||||||
if ((!mBfBuildCompiler.HasQueuedCommands()) && (!mBfResolveCompiler.HasQueuedCommands())
|
if ((!mBfBuildCompiler.HasQueuedCommands()) && (!mBfResolveCompiler.HasQueuedCommands())
|
||||||
#if IDE_C_SUPPORT
|
#if IDE_C_SUPPORT
|
||||||
&& (!mDepClang.HasQueuedCommands()) && (!mResolveClang.HasQueuedCommands())
|
&& (!mDepClang.HasQueuedCommands()) && (!mResolveClang.HasQueuedCommands())
|
||||||
|
|
|
@ -1027,6 +1027,18 @@ namespace IDE.ui
|
||||||
doBackground = true;
|
doBackground = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If there's a long-running const eval then cancel that first
|
||||||
|
if (!mDeferredResolveResults.IsEmpty)
|
||||||
|
{
|
||||||
|
for (var result in mDeferredResolveResults)
|
||||||
|
{
|
||||||
|
if (result.mResolveType == .ClassifyFullRefresh)
|
||||||
|
{
|
||||||
|
bfCompiler.RequestCancelBackground();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (mIsClang)
|
if (mIsClang)
|
||||||
{
|
{
|
||||||
#if !IDE_C_SUPPORT
|
#if !IDE_C_SUPPORT
|
||||||
|
|
|
@ -26,6 +26,9 @@ namespace IDE.ui
|
||||||
public int mDirtyDelay;
|
public int mDirtyDelay;
|
||||||
public int mStatusBoxUpdateCnt = -1;
|
public int mStatusBoxUpdateCnt = -1;
|
||||||
|
|
||||||
|
public int32 mResolveStuckTicks;
|
||||||
|
public float mResolveLastPct = -1;
|
||||||
|
|
||||||
public this()
|
public this()
|
||||||
{
|
{
|
||||||
mConfigComboBox = new DarkComboBox();
|
mConfigComboBox = new DarkComboBox();
|
||||||
|
@ -225,8 +228,19 @@ namespace IDE.ui
|
||||||
#endif
|
#endif
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
float completionPct = gApp.mBfResolveCompiler.GetCompletionPercentage();
|
||||||
|
if (completionPct != mResolveLastPct)
|
||||||
|
{
|
||||||
|
mResolveStuckTicks = 0;
|
||||||
|
mResolveLastPct = completionPct;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
mResolveStuckTicks++;
|
||||||
|
|
||||||
MarkDirtyEx();
|
MarkDirtyEx();
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
mResolveStuckTicks = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Draw(Graphics g)
|
public override void Draw(Graphics g)
|
||||||
|
@ -380,6 +394,10 @@ namespace IDE.ui
|
||||||
{
|
{
|
||||||
DrawStatusBox("Custom Build Commands...", gApp.mBuildContext.mUpdateCnt);
|
DrawStatusBox("Custom Build Commands...", gApp.mBuildContext.mUpdateCnt);
|
||||||
}
|
}
|
||||||
|
else if (mResolveStuckTicks > 300)
|
||||||
|
{
|
||||||
|
DrawStatusBox("Const Evaluation");
|
||||||
|
}
|
||||||
else
|
else
|
||||||
mStatusBoxUpdateCnt = -1;
|
mStatusBoxUpdateCnt = -1;
|
||||||
|
|
||||||
|
|
|
@ -470,8 +470,8 @@ void BfAutoComplete::AddMethod(BfTypeInstance* typeInstance, BfMethodDef* method
|
||||||
if (auto entryAdded = AddEntry(entry, filter))
|
if (auto entryAdded = AddEntry(entry, filter))
|
||||||
{
|
{
|
||||||
if (methodDecl != NULL)
|
if (methodDecl != NULL)
|
||||||
{
|
{
|
||||||
if ((methodInstance != NULL) && (methodInstance->mMethodDef->mIsLocalMethod) && (GetCursorIdx(methodDecl) == methodDecl->mReturnType->mSrcEnd))
|
if ((methodInstance != NULL) && (methodInstance->mMethodDef->mIsLocalMethod) && (methodDecl->mReturnType != NULL) && (GetCursorIdx(methodDecl) == methodDecl->mReturnType->mSrcEnd))
|
||||||
{
|
{
|
||||||
// This isn't really a local method decl, it just looks like one
|
// This isn't really a local method decl, it just looks like one
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -397,6 +397,7 @@ BfCompiler::BfCompiler(BfSystem* bfSystem, bool isResolveOnly)
|
||||||
mActionTypeDef = NULL;
|
mActionTypeDef = NULL;
|
||||||
mEnumTypeDef = NULL;
|
mEnumTypeDef = NULL;
|
||||||
mFriendAttributeTypeDef = NULL;
|
mFriendAttributeTypeDef = NULL;
|
||||||
|
mConstEvalAttributeTypeDef = NULL;
|
||||||
mNoExtensionAttributeTypeDef = NULL;
|
mNoExtensionAttributeTypeDef = NULL;
|
||||||
mCheckedAttributeTypeDef = NULL;
|
mCheckedAttributeTypeDef = NULL;
|
||||||
mUncheckedAttributeTypeDef = NULL;
|
mUncheckedAttributeTypeDef = NULL;
|
||||||
|
@ -406,7 +407,8 @@ BfCompiler::BfCompiler(BfSystem* bfSystem, bool isResolveOnly)
|
||||||
mGenericIEnumeratorTypeDef = NULL;
|
mGenericIEnumeratorTypeDef = NULL;
|
||||||
mGenericIRefEnumeratorTypeDef = NULL;
|
mGenericIRefEnumeratorTypeDef = NULL;
|
||||||
mInlineAttributeTypeDef = NULL;
|
mInlineAttributeTypeDef = NULL;
|
||||||
mInternalTypeDef = NULL;
|
mThreadTypeDef = NULL;
|
||||||
|
mInternalTypeDef = NULL;
|
||||||
mDiagnosticsDebugTypeDef = NULL;
|
mDiagnosticsDebugTypeDef = NULL;
|
||||||
mIDisposableTypeDef = NULL;
|
mIDisposableTypeDef = NULL;
|
||||||
mIPrintableTypeDef = NULL;
|
mIPrintableTypeDef = NULL;
|
||||||
|
@ -6596,6 +6598,7 @@ bool BfCompiler::DoCompile(const StringImpl& outputDirectory)
|
||||||
mActionTypeDef = _GetRequiredType("System.Action");
|
mActionTypeDef = _GetRequiredType("System.Action");
|
||||||
mEnumTypeDef = _GetRequiredType("System.Enum");
|
mEnumTypeDef = _GetRequiredType("System.Enum");
|
||||||
mFriendAttributeTypeDef = _GetRequiredType("System.FriendAttribute");
|
mFriendAttributeTypeDef = _GetRequiredType("System.FriendAttribute");
|
||||||
|
mConstEvalAttributeTypeDef = _GetRequiredType("System.ConstEvalAttribute");
|
||||||
mNoExtensionAttributeTypeDef = _GetRequiredType("System.NoExtensionAttribute");
|
mNoExtensionAttributeTypeDef = _GetRequiredType("System.NoExtensionAttribute");
|
||||||
mCheckedAttributeTypeDef = _GetRequiredType("System.CheckedAttribute");
|
mCheckedAttributeTypeDef = _GetRequiredType("System.CheckedAttribute");
|
||||||
mUncheckedAttributeTypeDef = _GetRequiredType("System.UncheckedAttribute");
|
mUncheckedAttributeTypeDef = _GetRequiredType("System.UncheckedAttribute");
|
||||||
|
@ -6606,6 +6609,7 @@ bool BfCompiler::DoCompile(const StringImpl& outputDirectory)
|
||||||
mGenericIEnumeratorTypeDef = _GetRequiredType("System.Collections.IEnumerator", 1);
|
mGenericIEnumeratorTypeDef = _GetRequiredType("System.Collections.IEnumerator", 1);
|
||||||
mGenericIRefEnumeratorTypeDef = _GetRequiredType("System.Collections.IRefEnumerator", 1);
|
mGenericIRefEnumeratorTypeDef = _GetRequiredType("System.Collections.IRefEnumerator", 1);
|
||||||
mInlineAttributeTypeDef = _GetRequiredType("System.InlineAttribute");
|
mInlineAttributeTypeDef = _GetRequiredType("System.InlineAttribute");
|
||||||
|
mThreadTypeDef = _GetRequiredType("System.Threading.Thread");
|
||||||
mInternalTypeDef = _GetRequiredType("System.Internal");
|
mInternalTypeDef = _GetRequiredType("System.Internal");
|
||||||
mDiagnosticsDebugTypeDef = _GetRequiredType("System.Diagnostics.Debug");
|
mDiagnosticsDebugTypeDef = _GetRequiredType("System.Diagnostics.Debug");
|
||||||
mIDisposableTypeDef = _GetRequiredType("System.IDisposable");
|
mIDisposableTypeDef = _GetRequiredType("System.IDisposable");
|
||||||
|
@ -7258,6 +7262,11 @@ bool BfCompiler::DoCompile(const StringImpl& outputDirectory)
|
||||||
mPassInstance->OutputLine(StrFormat(":low %d module%s built, %d object file%s generated",
|
mPassInstance->OutputLine(StrFormat(":low %d module%s built, %d object file%s generated",
|
||||||
numModulesWritten, (numModulesWritten != 1) ? "s" : "",
|
numModulesWritten, (numModulesWritten != 1) ? "s" : "",
|
||||||
numObjFilesWritten, (numObjFilesWritten != 1) ? "s" : ""));
|
numObjFilesWritten, (numObjFilesWritten != 1) ? "s" : ""));
|
||||||
|
|
||||||
|
if ((mCEMachine != NULL) && (!mIsResolveOnly) && (mCEMachine->mRevisionExecuteTime > 0))
|
||||||
|
{
|
||||||
|
mPassInstance->OutputLine(StrFormat(":med Const evaluation time: %0.2fs", mCEMachine->mRevisionExecuteTime / 1000.0f));
|
||||||
|
}
|
||||||
|
|
||||||
BpLeave();
|
BpLeave();
|
||||||
mPassInstance->WriteErrorSummary();
|
mPassInstance->WriteErrorSummary();
|
||||||
|
|
|
@ -359,6 +359,7 @@ public:
|
||||||
BfTypeDef* mGenericIEnumeratorTypeDef;
|
BfTypeDef* mGenericIEnumeratorTypeDef;
|
||||||
BfTypeDef* mGenericIRefEnumeratorTypeDef;
|
BfTypeDef* mGenericIRefEnumeratorTypeDef;
|
||||||
|
|
||||||
|
BfTypeDef* mThreadTypeDef;
|
||||||
BfTypeDef* mInternalTypeDef;
|
BfTypeDef* mInternalTypeDef;
|
||||||
BfTypeDef* mDiagnosticsDebugTypeDef;
|
BfTypeDef* mDiagnosticsDebugTypeDef;
|
||||||
BfTypeDef* mIDisposableTypeDef;
|
BfTypeDef* mIDisposableTypeDef;
|
||||||
|
@ -401,6 +402,7 @@ public:
|
||||||
BfTypeDef* mDisableChecksAttributeTypeDef;
|
BfTypeDef* mDisableChecksAttributeTypeDef;
|
||||||
BfTypeDef* mDisableObjectAccessChecksAttributeTypeDef;
|
BfTypeDef* mDisableObjectAccessChecksAttributeTypeDef;
|
||||||
BfTypeDef* mFriendAttributeTypeDef;
|
BfTypeDef* mFriendAttributeTypeDef;
|
||||||
|
BfTypeDef* mConstEvalAttributeTypeDef;
|
||||||
BfTypeDef* mNoExtensionAttributeTypeDef;
|
BfTypeDef* mNoExtensionAttributeTypeDef;
|
||||||
BfTypeDef* mCheckedAttributeTypeDef;
|
BfTypeDef* mCheckedAttributeTypeDef;
|
||||||
BfTypeDef* mUncheckedAttributeTypeDef;
|
BfTypeDef* mUncheckedAttributeTypeDef;
|
||||||
|
|
|
@ -36,7 +36,7 @@ BfConstResolver::BfConstResolver(BfModule* bfModule) : BfExprEvaluator(bfModule)
|
||||||
|
|
||||||
BfTypedValue BfConstResolver::Resolve(BfExpression* expr, BfType* wantType, BfConstResolveFlags flags)
|
BfTypedValue BfConstResolver::Resolve(BfExpression* expr, BfType* wantType, BfConstResolveFlags flags)
|
||||||
{
|
{
|
||||||
mBfEvalExprFlags = (BfEvalExprFlags)(mBfEvalExprFlags | BfEvalExprFlags_ConstExpr);
|
mBfEvalExprFlags = (BfEvalExprFlags)(mBfEvalExprFlags | BfEvalExprFlags_ConstEval);
|
||||||
|
|
||||||
// Handle the 'int[?] val = .(1, 2, 3)' case
|
// Handle the 'int[?] val = .(1, 2, 3)' case
|
||||||
if ((flags & BfConstResolveFlag_ArrayInitSize) != 0)
|
if ((flags & BfConstResolveFlag_ArrayInitSize) != 0)
|
||||||
|
@ -76,7 +76,7 @@ BfTypedValue BfConstResolver::Resolve(BfExpression* expr, BfType* wantType, BfCo
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
mResult = BfTypedValue(mModule->mBfIRBuilder->GetUndefConstValue(BfTypeCode_IntPtr), mModule->GetPrimitiveType(BfTypeCode_IntPtr));
|
mResult = BfTypedValue(mModule->mBfIRBuilder->GetUndefConstValue(mModule->mBfIRBuilder->GetPrimitiveType(BfTypeCode_IntPtr)), mModule->GetPrimitiveType(BfTypeCode_IntPtr));
|
||||||
return mResult;
|
return mResult;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -176,7 +176,7 @@ BfTypedValue BfConstResolver::Resolve(BfExpression* expr, BfType* wantType, BfCo
|
||||||
BfTypedValue result;
|
BfTypedValue result;
|
||||||
result.mKind = BfTypedValueKind_Value;
|
result.mKind = BfTypedValueKind_Value;
|
||||||
result.mType = genericTypeConstraint;
|
result.mType = genericTypeConstraint;
|
||||||
result.mValue = mModule->mBfIRBuilder->GetUndefConstValue(primType->mTypeDef->mTypeCode);
|
result.mValue = mModule->mBfIRBuilder->GetUndefConstValue(mModule->mBfIRBuilder->GetPrimitiveType(primType->mTypeDef->mTypeCode));
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -821,6 +821,8 @@ void BfDefBuilder::ParseAttributes(BfAttributeDirective* attributes, BfMethodDef
|
||||||
methodDef->mIsNoReturn = true;
|
methodDef->mIsNoReturn = true;
|
||||||
else if (typeRefName == "SkipCall")
|
else if (typeRefName == "SkipCall")
|
||||||
methodDef->mIsSkipCall = true;
|
methodDef->mIsSkipCall = true;
|
||||||
|
else if (typeRefName == "ConstEval")
|
||||||
|
methodDef->mIsConstEval = true;
|
||||||
else if (typeRefName == "NoShow")
|
else if (typeRefName == "NoShow")
|
||||||
methodDef->mIsNoShow = true;
|
methodDef->mIsNoShow = true;
|
||||||
else if (typeRefName == "NoDiscard")
|
else if (typeRefName == "NoDiscard")
|
||||||
|
|
|
@ -2630,14 +2630,14 @@ BfAutoComplete* BfExprEvaluator::GetAutoComplete()
|
||||||
|
|
||||||
bool BfExprEvaluator::IsConstEval()
|
bool BfExprEvaluator::IsConstEval()
|
||||||
{
|
{
|
||||||
return (mModule->mIsConstModule) || ((mBfEvalExprFlags & BfEvalExprFlags_ConstExpr) != 0);
|
return (mModule->mIsConstModule) || ((mBfEvalExprFlags & BfEvalExprFlags_ConstEval) != 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BfExprEvaluator::IsConstEvalEntry()
|
bool BfExprEvaluator::IsConstEvalEntry()
|
||||||
{
|
{
|
||||||
if (mModule->mIsConstModule)
|
if (mModule->mIsConstModule)
|
||||||
return false;
|
return false;
|
||||||
return ((mBfEvalExprFlags & BfEvalExprFlags_ConstExpr) != 0);
|
return ((mBfEvalExprFlags & BfEvalExprFlags_ConstEval) != 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int BfExprEvaluator::GetStructRetIdx(BfMethodInstance* methodInstance, bool forceStatic)
|
int BfExprEvaluator::GetStructRetIdx(BfMethodInstance* methodInstance, bool forceStatic)
|
||||||
|
@ -3263,6 +3263,11 @@ void BfExprEvaluator::Visit(BfLiteralExpression* literalExpr)
|
||||||
|
|
||||||
void BfExprEvaluator::Visit(BfStringInterpolationExpression* stringInterpolationExpression)
|
void BfExprEvaluator::Visit(BfStringInterpolationExpression* stringInterpolationExpression)
|
||||||
{
|
{
|
||||||
|
if (IsConstEvalEntry())
|
||||||
|
{
|
||||||
|
mModule->Fail("Const evaluation of string interpolation not allowed", stringInterpolationExpression);
|
||||||
|
}
|
||||||
|
|
||||||
if ((mBfEvalExprFlags & BfEvalExprFlags_StringInterpolateFormat) != 0)
|
if ((mBfEvalExprFlags & BfEvalExprFlags_StringInterpolateFormat) != 0)
|
||||||
{
|
{
|
||||||
BfVariant variant;
|
BfVariant variant;
|
||||||
|
@ -4993,6 +4998,20 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, BfMethodInstance*
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((mBfEvalExprFlags & BfEvalExprFlags_ConstEval) != 0)
|
||||||
|
{
|
||||||
|
if (methodInstance->mReturnType->IsInstanceOf(mModule->mCompiler->mSpanTypeDef))
|
||||||
|
{
|
||||||
|
if (mExpectingType->IsSizedArray())
|
||||||
|
{
|
||||||
|
return BfTypedValue(mModule->mBfIRBuilder->GetUndefConstValue(mModule->mBfIRBuilder->MapType(mExpectingType)), mExpectingType);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (methodInstance->mReturnType->IsValuelessType())
|
||||||
|
return BfTypedValue(mModule->mBfIRBuilder->GetFakeVal(), methodInstance->mReturnType);
|
||||||
|
return BfTypedValue(mModule->mBfIRBuilder->GetUndefConstValue(mModule->mBfIRBuilder->MapType(methodInstance->mReturnType)), methodInstance->mReturnType);
|
||||||
|
}
|
||||||
|
|
||||||
BfTypedValue result;
|
BfTypedValue result;
|
||||||
if (sret != NULL)
|
if (sret != NULL)
|
||||||
result = *sret;
|
result = *sret;
|
||||||
|
@ -5009,15 +5028,15 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, BfMethodInstance*
|
||||||
{
|
{
|
||||||
mModule->mCompiler->mCEMachine->QueueMethod(methodInstance, func);
|
mModule->mCompiler->mCEMachine->QueueMethod(methodInstance, func);
|
||||||
}
|
}
|
||||||
else if ((mBfEvalExprFlags & BfEvalExprFlags_ConstExpr) != 0)
|
else if ((mBfEvalExprFlags & BfEvalExprFlags_ConstEval) != 0)
|
||||||
{
|
{
|
||||||
if (mFunctionBindResult != NULL)
|
if (mFunctionBindResult != NULL)
|
||||||
{
|
{
|
||||||
forceBind = true;
|
forceBind = true;
|
||||||
}
|
}
|
||||||
else if (mUsedAsStatement)
|
else if ((mBfEvalExprFlags & BfEvalExprFlags_InCascade) != 0)
|
||||||
{
|
{
|
||||||
// Don't allow use in a cascade
|
mModule->Fail("Const evaluation not allowed with cascade operator", targetSrc);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -5648,7 +5667,7 @@ void BfExprEvaluator::PushArg(BfTypedValue argVal, SizedArrayImpl<BfIRValue>& ir
|
||||||
{
|
{
|
||||||
if (argVal.mType->IsComposite())
|
if (argVal.mType->IsComposite())
|
||||||
{
|
{
|
||||||
if ((mBfEvalExprFlags & BfEvalExprFlags_ConstExpr) != 0)
|
if ((mBfEvalExprFlags & BfEvalExprFlags_ConstEval) != 0)
|
||||||
{
|
{
|
||||||
// Const eval entry - we want any incoming consts as they are
|
// Const eval entry - we want any incoming consts as they are
|
||||||
}
|
}
|
||||||
|
@ -6121,7 +6140,24 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, const BfTypedValu
|
||||||
if (methodDef->mMethodType == BfMethodType_Extension)
|
if (methodDef->mMethodType == BfMethodType_Extension)
|
||||||
numElements++;
|
numElements++;
|
||||||
|
|
||||||
if (wantType->IsArray())
|
if (IsConstEvalEntry())
|
||||||
|
{
|
||||||
|
if ((wantType->IsArray()) || (wantType->IsInstanceOf(mModule->mCompiler->mSpanTypeDef)))
|
||||||
|
{
|
||||||
|
auto genericTypeInst = wantType->ToGenericTypeInstance();
|
||||||
|
expandedParamsElementType = genericTypeInst->mGenericTypeInfo->mTypeGenericArguments[0];
|
||||||
|
|
||||||
|
auto irSizedArrayType = mModule->mBfIRBuilder->GetSizedArrayType(mModule->mBfIRBuilder->MapType(expandedParamsElementType), numElements);
|
||||||
|
|
||||||
|
Array<BfIRValue> values;
|
||||||
|
for (int i = 0; i < numElements; i++)
|
||||||
|
values.Add(mModule->mBfIRBuilder->GetFakeVal());
|
||||||
|
expandedParamsArray = BfTypedValue(mModule->mBfIRBuilder->CreateConstAgg(irSizedArrayType, values), wantType);
|
||||||
|
|
||||||
|
PushArg(expandedParamsArray, irArgs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (wantType->IsArray())
|
||||||
{
|
{
|
||||||
BfArrayType* arrayType = (BfArrayType*)wantType;
|
BfArrayType* arrayType = (BfArrayType*)wantType;
|
||||||
mModule->PopulateType(arrayType, BfPopulateType_DataAndMethods);
|
mModule->PopulateType(arrayType, BfPopulateType_DataAndMethods);
|
||||||
|
@ -6152,9 +6188,9 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, const BfTypedValu
|
||||||
|
|
||||||
PushArg(expandedParamsArray, irArgs);
|
PushArg(expandedParamsArray, irArgs);
|
||||||
}
|
}
|
||||||
else
|
else if (wantType->IsInstanceOf(mModule->mCompiler->mSpanTypeDef))
|
||||||
{
|
{
|
||||||
auto genericTypeInst = wantType->ToGenericTypeInstance();
|
auto genericTypeInst = wantType->ToGenericTypeInstance();
|
||||||
expandedParamsElementType = genericTypeInst->mGenericTypeInfo->mTypeGenericArguments[0];
|
expandedParamsElementType = genericTypeInst->mGenericTypeInfo->mTypeGenericArguments[0];
|
||||||
|
|
||||||
expandedParamsArray = BfTypedValue(mModule->CreateAlloca(wantType), wantType, true);
|
expandedParamsArray = BfTypedValue(mModule->CreateAlloca(wantType), wantType, true);
|
||||||
|
@ -6538,7 +6574,14 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, const BfTypedValu
|
||||||
{
|
{
|
||||||
if (argValue)
|
if (argValue)
|
||||||
{
|
{
|
||||||
if (expandedParamAlloca)
|
if (IsConstEvalEntry())
|
||||||
|
{
|
||||||
|
auto constant = mModule->mBfIRBuilder->GetConstant(expandedParamsArray.mValue);
|
||||||
|
BF_ASSERT(constant->mConstType == BfConstType_Agg);
|
||||||
|
auto constAgg = (BfConstantAgg*)constant;
|
||||||
|
constAgg->mValues[extendedParamIdx] = argValue.mValue;
|
||||||
|
}
|
||||||
|
else if (expandedParamAlloca)
|
||||||
{
|
{
|
||||||
argValue = mModule->LoadValue(argValue);
|
argValue = mModule->LoadValue(argValue);
|
||||||
auto addr = mModule->mBfIRBuilder->CreateInBoundsGEP(expandedParamAlloca, extendedParamIdx);
|
auto addr = mModule->mBfIRBuilder->CreateInBoundsGEP(expandedParamAlloca, extendedParamIdx);
|
||||||
|
@ -7965,7 +8008,9 @@ BfTypedValue BfExprEvaluator::MatchMethod(BfAstNode* targetSrc, BfMethodBoundExp
|
||||||
mResultLocalVar = NULL;
|
mResultLocalVar = NULL;
|
||||||
mResultFieldInstance = NULL;
|
mResultFieldInstance = NULL;
|
||||||
mResultLocalVarRefNode = NULL;
|
mResultLocalVarRefNode = NULL;
|
||||||
MatchConstructor(targetSrc, methodBoundExpr, structInst, resolvedTypeInstance, argValues, false, false);
|
auto result = MatchConstructor(targetSrc, methodBoundExpr, structInst, resolvedTypeInstance, argValues, false, false);
|
||||||
|
if ((result) && (!result.mType->IsVoid()))
|
||||||
|
return result;
|
||||||
mModule->ValidateAllocation(resolvedTypeInstance, targetSrc);
|
mModule->ValidateAllocation(resolvedTypeInstance, targetSrc);
|
||||||
|
|
||||||
mModule->AddDependency(resolvedTypeInstance, mModule->mCurTypeInstance, BfDependencyMap::DependencyFlag_LocalUsage);
|
mModule->AddDependency(resolvedTypeInstance, mModule->mCurTypeInstance, BfDependencyMap::DependencyFlag_LocalUsage);
|
||||||
|
@ -8368,7 +8413,26 @@ BfTypedValue BfExprEvaluator::MatchMethod(BfAstNode* targetSrc, BfMethodBoundExp
|
||||||
mModule->MethodToString(moduleMethodInstance.mMethodInstance).c_str(), mModule->MethodToString(mModule->mCurMethodInstance).c_str()), targetSrc);
|
mModule->MethodToString(moduleMethodInstance.mMethodInstance).c_str(), mModule->MethodToString(mModule->mCurMethodInstance).c_str()), targetSrc);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto result = CreateCall(targetSrc, callTarget, origTarget, methodDef, moduleMethodInstance, bypassVirtual, argValues.mResolvedArgs, skipThis);
|
|
||||||
|
BfTypedValue result;
|
||||||
|
|
||||||
|
//
|
||||||
|
{
|
||||||
|
SetAndRestoreValue<BfEvalExprFlags> prevEvalExprFlag(mBfEvalExprFlags);
|
||||||
|
|
||||||
|
if ((mModule->mAttributeState != NULL) && (mModule->mAttributeState->mCustomAttributes != NULL) && (mModule->mAttributeState->mCustomAttributes->Contains(mModule->mCompiler->mConstEvalAttributeTypeDef)))
|
||||||
|
{
|
||||||
|
mModule->mAttributeState->mUsed = true;
|
||||||
|
mBfEvalExprFlags = (BfEvalExprFlags)(mBfEvalExprFlags | BfEvalExprFlags_ConstEval);
|
||||||
|
}
|
||||||
|
else if (moduleMethodInstance.mMethodInstance->mMethodDef->mIsConstEval)
|
||||||
|
{
|
||||||
|
mBfEvalExprFlags = (BfEvalExprFlags)(mBfEvalExprFlags | BfEvalExprFlags_ConstEval);
|
||||||
|
}
|
||||||
|
|
||||||
|
result = CreateCall(targetSrc, callTarget, origTarget, methodDef, moduleMethodInstance, bypassVirtual, argValues.mResolvedArgs, skipThis);
|
||||||
|
}
|
||||||
|
|
||||||
if (result)
|
if (result)
|
||||||
{
|
{
|
||||||
if (result.mType->IsRef())
|
if (result.mType->IsRef())
|
||||||
|
@ -9474,7 +9538,7 @@ void BfExprEvaluator::DoTypeIntAttr(BfTypeReference* typeRef, BfToken token)
|
||||||
// We do this so we know it's a constant but we can't assume anything about its value
|
// We do this so we know it's a constant but we can't assume anything about its value
|
||||||
// We make the value an Int32 which doesn't match the IntPtr type, but it allows us to
|
// We make the value an Int32 which doesn't match the IntPtr type, but it allows us to
|
||||||
// assume it can be implicitly cased to int32
|
// assume it can be implicitly cased to int32
|
||||||
mResult = BfTypedValue(mModule->mBfIRBuilder->GetUndefConstValue(BfTypeCode_Int32), sizeType);
|
mResult = BfTypedValue(mModule->mBfIRBuilder->GetUndefConstValue(mModule->mBfIRBuilder->MapType(sizeType)), sizeType);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
mResult = BfTypedValue(mModule->GetConstValue(attrVal, sizeType), sizeType);
|
mResult = BfTypedValue(mModule->GetConstValue(attrVal, sizeType), sizeType);
|
||||||
|
@ -11918,7 +11982,7 @@ BfLambdaInstance* BfExprEvaluator::GetLambdaInstance(BfLambdaBindExpression* lam
|
||||||
mModule->mCurMethodState->mHotDataReferenceBuilder->mInnerMethods.Add(methodInstance->mHotMethod);
|
mModule->mCurMethodState->mHotDataReferenceBuilder->mInnerMethods.Add(methodInstance->mHotMethod);
|
||||||
|
|
||||||
methodState.Reset();
|
methodState.Reset();
|
||||||
|
|
||||||
lambdaInstance = new BfLambdaInstance();
|
lambdaInstance = new BfLambdaInstance();
|
||||||
rootMethodState->mLambdaCache[cacheNodeList] = lambdaInstance;
|
rootMethodState->mLambdaCache[cacheNodeList] = lambdaInstance;
|
||||||
lambdaInstance->mDelegateTypeInstance = delegateTypeInstance;
|
lambdaInstance->mDelegateTypeInstance = delegateTypeInstance;
|
||||||
|
@ -12022,6 +12086,8 @@ BfLambdaInstance* BfExprEvaluator::GetLambdaInstance(BfLambdaBindExpression* lam
|
||||||
mModule->mCurMethodState->mHotDataReferenceBuilder->mInnerMethods.Add(dtorMethodInstance->mHotMethod);
|
mModule->mCurMethodState->mHotDataReferenceBuilder->mInnerMethods.Add(dtorMethodInstance->mHotMethod);
|
||||||
lambdaInstance->mDtorMethodInstance = dtorMethodInstance;
|
lambdaInstance->mDtorMethodInstance = dtorMethodInstance;
|
||||||
lambdaInstance->mDtorFunc = dtorFunc;
|
lambdaInstance->mDtorFunc = dtorFunc;
|
||||||
|
|
||||||
|
dtorMethodInstance->mMethodInstanceGroup = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
prevClosureState.Restore();
|
prevClosureState.Restore();
|
||||||
|
@ -12043,7 +12109,7 @@ BfLambdaInstance* BfExprEvaluator::GetLambdaInstance(BfLambdaBindExpression* lam
|
||||||
if (processMethods)
|
if (processMethods)
|
||||||
rootMethodState->mDeferredLambdaInstances.Add(lambdaInstance);
|
rootMethodState->mDeferredLambdaInstances.Add(lambdaInstance);
|
||||||
|
|
||||||
methodInstance->mMethodInstanceGroup = NULL;
|
methodInstance->mMethodInstanceGroup = NULL;
|
||||||
|
|
||||||
return lambdaInstance;
|
return lambdaInstance;
|
||||||
}
|
}
|
||||||
|
@ -13199,7 +13265,7 @@ void BfExprEvaluator::CreateObject(BfObjectCreateExpression* objCreateExpr, BfAs
|
||||||
{
|
{
|
||||||
allocValue = mModule->AllocFromType(resolvedTypeRef, allocTarget, appendSizeValue, BfIRValue(), 0, BfAllocFlags_None, allocAlign);
|
allocValue = mModule->AllocFromType(resolvedTypeRef, allocTarget, appendSizeValue, BfIRValue(), 0, BfAllocFlags_None, allocAlign);
|
||||||
}
|
}
|
||||||
if (((mBfEvalExprFlags & BfEvalExprFlags_ConstExpr) != 0) && (mModule->mCompiler->mCEMachine != NULL))
|
if (((mBfEvalExprFlags & BfEvalExprFlags_ConstEval) != 0) && (mModule->mCompiler->mCEMachine != NULL))
|
||||||
{
|
{
|
||||||
mModule->mCompiler->mCEMachine->SetAppendAllocInfo(mModule, allocValue, appendSizeValue);
|
mModule->mCompiler->mCEMachine->SetAppendAllocInfo(mModule, allocValue, appendSizeValue);
|
||||||
}
|
}
|
||||||
|
@ -13250,7 +13316,7 @@ void BfExprEvaluator::CreateObject(BfObjectCreateExpression* objCreateExpr, BfAs
|
||||||
{
|
{
|
||||||
mModule->AssertErrorState();
|
mModule->AssertErrorState();
|
||||||
}
|
}
|
||||||
else if ((mBfEvalExprFlags & BfEvalExprFlags_ConstExpr) == 0)
|
else if ((mBfEvalExprFlags & BfEvalExprFlags_ConstEval) == 0)
|
||||||
{
|
{
|
||||||
SizedArray<BfIRValue, 1> irArgs;
|
SizedArray<BfIRValue, 1> irArgs;
|
||||||
irArgs.push_back(mResult.mValue);
|
irArgs.push_back(mResult.mValue);
|
||||||
|
@ -13328,7 +13394,7 @@ void BfExprEvaluator::CreateObject(BfObjectCreateExpression* objCreateExpr, BfAs
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (((mBfEvalExprFlags & BfEvalExprFlags_ConstExpr) != 0) && (mModule->mCompiler->mCEMachine != NULL))
|
if (((mBfEvalExprFlags & BfEvalExprFlags_ConstEval) != 0) && (mModule->mCompiler->mCEMachine != NULL))
|
||||||
{
|
{
|
||||||
mModule->mCompiler->mCEMachine->ClearAppendAllocInfo();
|
mModule->mCompiler->mCEMachine->ClearAppendAllocInfo();
|
||||||
}
|
}
|
||||||
|
@ -15362,6 +15428,7 @@ void BfExprEvaluator::DoInvocation(BfAstNode* target, BfMethodBoundExpression* m
|
||||||
|
|
||||||
int methodCount = 0;
|
int methodCount = 0;
|
||||||
bool mayBeSkipCall = false;
|
bool mayBeSkipCall = false;
|
||||||
|
bool mayBeConstEvalCall = false;
|
||||||
if (thisValue.mType != NULL)
|
if (thisValue.mType != NULL)
|
||||||
{
|
{
|
||||||
if (thisValue.mType->IsAllocType())
|
if (thisValue.mType->IsAllocType())
|
||||||
|
@ -15379,6 +15446,8 @@ void BfExprEvaluator::DoInvocation(BfAstNode* target, BfMethodBoundExpression* m
|
||||||
{
|
{
|
||||||
if (methodDef->mIsSkipCall)
|
if (methodDef->mIsSkipCall)
|
||||||
mayBeSkipCall = true;
|
mayBeSkipCall = true;
|
||||||
|
if (methodDef->mIsConstEval)
|
||||||
|
mayBeConstEvalCall = true;
|
||||||
methodDef = methodDef->mNextWithSameName;
|
methodDef = methodDef->mNextWithSameName;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -15404,7 +15473,7 @@ void BfExprEvaluator::DoInvocation(BfAstNode* target, BfMethodBoundExpression* m
|
||||||
|
|
||||||
BfResolveArgFlags resolveArgsFlags = (BfResolveArgFlags)(BfResolveArgFlag_DeferFixits | BfResolveArgFlag_AllowUnresolvedTypes);
|
BfResolveArgFlags resolveArgsFlags = (BfResolveArgFlags)(BfResolveArgFlag_DeferFixits | BfResolveArgFlag_AllowUnresolvedTypes);
|
||||||
resolveArgsFlags = (BfResolveArgFlags)(resolveArgsFlags | BfResolveArgFlag_DeferParamEval);
|
resolveArgsFlags = (BfResolveArgFlags)(resolveArgsFlags | BfResolveArgFlag_DeferParamEval);
|
||||||
if (mayBeSkipCall)
|
if ((mayBeSkipCall) || (mayBeConstEvalCall))
|
||||||
resolveArgsFlags = (BfResolveArgFlags)(resolveArgsFlags | BfResolveArgFlag_DeferParamValues);
|
resolveArgsFlags = (BfResolveArgFlags)(resolveArgsFlags | BfResolveArgFlag_DeferParamValues);
|
||||||
|
|
||||||
static int sCallIdx = 0;
|
static int sCallIdx = 0;
|
||||||
|
@ -15430,10 +15499,13 @@ void BfExprEvaluator::DoInvocation(BfAstNode* target, BfMethodBoundExpression* m
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((isCascade) && (cascadeOperatorToken != NULL) && ((mBfEvalExprFlags & BfEvalExprFlags_ConstExpr) != 0))
|
if ((isCascade) && (cascadeOperatorToken != NULL) && ((mBfEvalExprFlags & BfEvalExprFlags_ConstEval) != 0))
|
||||||
mModule->Fail("Cascade operator cannot be used in const evaluation", cascadeOperatorToken);
|
mModule->Fail("Cascade operator cannot be used in const evaluation", cascadeOperatorToken);
|
||||||
|
|
||||||
SetAndRestoreValue<bool> prevUsedAsStatement(mUsedAsStatement, mUsedAsStatement || isCascade);
|
SetAndRestoreValue<bool> prevUsedAsStatement(mUsedAsStatement, mUsedAsStatement || isCascade);
|
||||||
|
SetAndRestoreValue<BfEvalExprFlags> prevEvalExprFlags(mBfEvalExprFlags);
|
||||||
|
if (isCascade)
|
||||||
|
mBfEvalExprFlags = (BfEvalExprFlags)(mBfEvalExprFlags | BfEvalExprFlags_InCascade);
|
||||||
ResolveArgValues(argValues, resolveArgsFlags);
|
ResolveArgValues(argValues, resolveArgsFlags);
|
||||||
mResult = MatchMethod(methodNodeSrc, methodBoundExpr, thisValue, allowImplicitThis, bypassVirtual, targetFunctionName, argValues, methodGenericArguments, checkedKind);
|
mResult = MatchMethod(methodNodeSrc, methodBoundExpr, thisValue, allowImplicitThis, bypassVirtual, targetFunctionName, argValues, methodGenericArguments, checkedKind);
|
||||||
argValues.HandleFixits(mModule);
|
argValues.HandleFixits(mModule);
|
||||||
|
@ -15840,7 +15912,7 @@ BfTypedValue BfExprEvaluator::GetResult(bool clearResult, bool resolveGenericTyp
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
BF_ASSERT(mModule->mCurMethodInstance->mIsUnspecialized);
|
BF_ASSERT(mModule->mCurMethodInstance->mIsUnspecialized);
|
||||||
mResult = BfTypedValue(mModule->mBfIRBuilder->GetUndefConstValue(BfTypeCode_IntPtr), mModule->GetPrimitiveType(BfTypeCode_IntPtr));
|
mResult = BfTypedValue(mModule->mBfIRBuilder->GetUndefConstValue(mModule->mBfIRBuilder->GetPrimitiveType(BfTypeCode_IntPtr)), mModule->GetPrimitiveType(BfTypeCode_IntPtr));
|
||||||
handled = true;
|
handled = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -17166,8 +17238,8 @@ void BfExprEvaluator::InitializedSizedArray(BfSizedArrayType* arrayType, BfToken
|
||||||
{
|
{
|
||||||
if (checkArrayType->mElementCount == -1)
|
if (checkArrayType->mElementCount == -1)
|
||||||
{
|
{
|
||||||
mModule->Fail("Initializers not supported for unknown-sized arrays", valueExprs[0]);
|
// mModule->Fail("Initializers not supported for unknown-sized arrays", valueExprs[0]);
|
||||||
failedAt.Add(depth);
|
// failedAt.Add(depth);
|
||||||
}
|
}
|
||||||
else if (initCountDiff > 0)
|
else if (initCountDiff > 0)
|
||||||
{
|
{
|
||||||
|
@ -17453,6 +17525,10 @@ void BfExprEvaluator::InitializedSizedArray(BfSizedArrayType* arrayType, BfToken
|
||||||
members.push_back(defaultVal.mValue);
|
members.push_back(defaultVal.mValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto allocArrayType = checkArrayType;
|
||||||
|
if (checkArrayType->IsUndefSizedArray())
|
||||||
|
allocArrayType = mModule->CreateSizedArrayType(checkArrayType->GetUnderlyingType(), (int)members.size());
|
||||||
|
|
||||||
if (checkArrayType->mElementType->IsStruct())
|
if (checkArrayType->mElementType->IsStruct())
|
||||||
{
|
{
|
||||||
// This fixed cases where we have non-size-aligned initializers. Assume zero-initialized
|
// This fixed cases where we have non-size-aligned initializers. Assume zero-initialized
|
||||||
|
@ -17629,19 +17705,63 @@ void BfExprEvaluator::Visit(BfTupleExpression* tupleExpr)
|
||||||
mResult = *mReceivingValue;
|
mResult = *mReceivingValue;
|
||||||
mReceivingValue = NULL;
|
mReceivingValue = NULL;
|
||||||
curTupleValue = mResult.mValue;
|
curTupleValue = mResult.mValue;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
int valueIdx = -1;
|
||||||
|
bool isExactConst = true;
|
||||||
|
|
||||||
|
for (int fieldIdx = 0; fieldIdx < (int)tupleType->mFieldInstances.size(); fieldIdx++)
|
||||||
|
{
|
||||||
|
BfFieldInstance* fieldInstance = &tupleType->mFieldInstances[fieldIdx];
|
||||||
|
if (fieldInstance->mDataIdx < 0)
|
||||||
|
continue;
|
||||||
|
++valueIdx;
|
||||||
|
auto typedValue = typedValues[valueIdx];
|
||||||
|
if (typedValue.mType != fieldInstance->mResolvedType)
|
||||||
|
{
|
||||||
|
isExactConst = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (!typedValue.mValue.IsConst())
|
||||||
|
{
|
||||||
|
isExactConst = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isExactConst)
|
||||||
|
{
|
||||||
|
mModule->PopulateType(tupleType);
|
||||||
|
|
||||||
|
Array<BfIRValue> irValues;
|
||||||
|
irValues.Resize(typedValues.mSize + 1);
|
||||||
|
irValues[0] = mModule->mBfIRBuilder->CreateConstStructZero(mModule->mBfIRBuilder->MapType(tupleType->mBaseType));
|
||||||
|
|
||||||
|
for (int fieldIdx = 0; fieldIdx < (int)tupleType->mFieldInstances.size(); fieldIdx++)
|
||||||
|
{
|
||||||
|
BfFieldInstance* fieldInstance = &tupleType->mFieldInstances[fieldIdx];
|
||||||
|
if (fieldInstance->mDataIdx < 0)
|
||||||
|
continue;
|
||||||
|
irValues[fieldInstance->mDataIdx] = typedValues[fieldIdx].mValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
mResult = BfTypedValue(mModule->mBfIRBuilder->CreateConstAgg(mModule->mBfIRBuilder->MapType(tupleType), irValues), tupleType);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
curTupleValue = mModule->CreateAlloca(tupleType);
|
curTupleValue = mModule->CreateAlloca(tupleType);
|
||||||
mResultIsTempComposite = true;
|
mResultIsTempComposite = true;
|
||||||
mResult = BfTypedValue(curTupleValue, tupleType, BfTypedValueKind_TempAddr);
|
mResult = BfTypedValue(curTupleValue, tupleType, BfTypedValueKind_TempAddr);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int valueIdx = 0; valueIdx < (int)typedValues.size(); valueIdx++)
|
int valueIdx = -1;
|
||||||
|
for (int fieldIdx = 0; fieldIdx < (int)tupleType->mFieldInstances.size(); fieldIdx++)
|
||||||
{
|
{
|
||||||
BfFieldInstance* fieldInstance = &tupleType->mFieldInstances[valueIdx];
|
BfFieldInstance* fieldInstance = &tupleType->mFieldInstances[fieldIdx];
|
||||||
if (fieldInstance->mResolvedType->IsValuelessType())
|
if (fieldInstance->mResolvedType->IsValuelessType())
|
||||||
continue;
|
continue;
|
||||||
|
++valueIdx;
|
||||||
auto typedVal = typedValues[valueIdx];
|
auto typedVal = typedValues[valueIdx];
|
||||||
if (!typedVal)
|
if (!typedVal)
|
||||||
{
|
{
|
||||||
|
@ -20511,6 +20631,20 @@ void BfExprEvaluator::PerformBinaryOperation(BfAstNode* leftExpression, BfAstNod
|
||||||
|
|
||||||
if (!handled)
|
if (!handled)
|
||||||
{
|
{
|
||||||
|
if ((leftValue.mType->IsUndefSizedArray()) || (rightValue.mType->IsUndefSizedArray()))
|
||||||
|
{
|
||||||
|
if ((leftValue.mType->IsSizedArray()) && (rightValue.mType->IsSizedArray() &&
|
||||||
|
(leftValue.mType->GetUnderlyingType() == rightValue.mType->GetUnderlyingType())))
|
||||||
|
{
|
||||||
|
if (BfBinOpEqualityCheck(binaryOp))
|
||||||
|
{
|
||||||
|
auto boolType = mModule->GetPrimitiveType(BfTypeCode_Boolean);
|
||||||
|
mResult = mModule->GetDefaultTypedValue(boolType, false, BfDefaultValueKind_Undef);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
mModule->Fail(StrFormat("Operator '%s' cannot be applied to operands of type '%s' and '%s'",
|
mModule->Fail(StrFormat("Operator '%s' cannot be applied to operands of type '%s' and '%s'",
|
||||||
BfGetOpName(binaryOp),
|
BfGetOpName(binaryOp),
|
||||||
mModule->TypeToString(leftValue.mType).c_str(),
|
mModule->TypeToString(leftValue.mType).c_str(),
|
||||||
|
|
|
@ -175,9 +175,7 @@ USING_NS_BF;
|
||||||
auto constRHS = GetConstantById(rhs.mId); \
|
auto constRHS = GetConstantById(rhs.mId); \
|
||||||
if ((constLHS->mConstType == BfConstType_Undef) || (constRHS->mConstType == BfConstType_Undef)) \
|
if ((constLHS->mConstType == BfConstType_Undef) || (constRHS->mConstType == BfConstType_Undef)) \
|
||||||
{ \
|
{ \
|
||||||
if (((constLHS->mConstType == BfConstType_Undef) || (constLHS->mTypeCode < BfTypeCode_Length)) && \
|
return GetUndefConstValue(MapType(mModule->GetPrimitiveType(BfTypeCode_Boolean))); \
|
||||||
((constRHS->mConstType == BfConstType_Undef) || (constRHS->mTypeCode < BfTypeCode_Length))) \
|
|
||||||
return GetUndefConstValue(BfTypeCode_Boolean); \
|
|
||||||
} \
|
} \
|
||||||
if ((constLHS->mTypeCode < BfTypeCode_Length) && (constRHS->mTypeCode < BfTypeCode_Length)) \
|
if ((constLHS->mTypeCode < BfTypeCode_Length) && (constRHS->mTypeCode < BfTypeCode_Length)) \
|
||||||
{ \
|
{ \
|
||||||
|
@ -654,6 +652,14 @@ BfIRValue BfIRConstHolder::CreateConst(BfConstant* fromConst, BfIRConstHolder* f
|
||||||
}
|
}
|
||||||
return CreateConstAgg(constAgg->mType, copiedVals);
|
return CreateConstAgg(constAgg->mType, copiedVals);
|
||||||
}
|
}
|
||||||
|
else if (fromConst->mConstType == BfConstType_Undef)
|
||||||
|
{
|
||||||
|
auto constUndef = (BfConstantUndef*)fromConst;
|
||||||
|
BF_ASSERT(constUndef->mType.mKind != BfIRTypeData::TypeKind_Stream);
|
||||||
|
if (constUndef->mType.mKind == BfIRTypeData::TypeKind_Stream)
|
||||||
|
return GetUndefConstValue(BfIRValue());
|
||||||
|
return GetUndefConstValue(constUndef->mType);
|
||||||
|
}
|
||||||
else if ((IsInt(fromConst->mTypeCode)) || (fromConst->mTypeCode == BfTypeCode_Boolean) || (fromConst->mTypeCode == BfTypeCode_StringId))
|
else if ((IsInt(fromConst->mTypeCode)) || (fromConst->mTypeCode == BfTypeCode_Boolean) || (fromConst->mTypeCode == BfTypeCode_StringId))
|
||||||
{
|
{
|
||||||
return CreateConst(fromConst->mTypeCode, fromConst->mUInt64);
|
return CreateConst(fromConst->mTypeCode, fromConst->mUInt64);
|
||||||
|
@ -778,11 +784,11 @@ BfIRValue BfIRConstHolder::CreateTypeOf(BfType* type)
|
||||||
return irValue;
|
return irValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
BfIRValue BfIRConstHolder::GetUndefConstValue(BfTypeCode typeCode)
|
BfIRValue BfIRConstHolder::GetUndefConstValue(BfIRType irType)
|
||||||
{
|
{
|
||||||
auto constUndef = mTempAlloc.Alloc<BfConstantUndef>();
|
auto constUndef = mTempAlloc.Alloc<BfConstantUndef>();
|
||||||
constUndef->mConstType = BfConstType_Undef;
|
constUndef->mConstType = BfConstType_Undef;
|
||||||
constUndef->mTypeCode = typeCode;
|
constUndef->mType = irType;
|
||||||
|
|
||||||
BfIRValue undefVal(BfIRValueFlags_Const, mTempAlloc.GetChunkedId(constUndef));
|
BfIRValue undefVal(BfIRValueFlags_Const, mTempAlloc.GetChunkedId(constUndef));
|
||||||
#ifdef CHECK_CONSTHOLDER
|
#ifdef CHECK_CONSTHOLDER
|
||||||
|
@ -3461,12 +3467,11 @@ BfIRFunction BfIRBuilder::GetFakeFunction()
|
||||||
}
|
}
|
||||||
|
|
||||||
BfIRType BfIRBuilder::GetPrimitiveType(BfTypeCode typeCode)
|
BfIRType BfIRBuilder::GetPrimitiveType(BfTypeCode typeCode)
|
||||||
{
|
{
|
||||||
|
|
||||||
FixTypeCode(typeCode);
|
FixTypeCode(typeCode);
|
||||||
BfIRType retType = WriteCmd(BfIRCmd_PrimitiveType, typeCode);
|
BfIRType retType = WriteCmd(BfIRCmd_PrimitiveType, typeCode);
|
||||||
NEW_CMD_INSERTED_IRTYPE;
|
NEW_CMD_INSERTED_IRTYPE;
|
||||||
return retType;
|
return retType;
|
||||||
}
|
}
|
||||||
|
|
||||||
BfIRType BfIRBuilder::CreateStructType(const StringImpl& name)
|
BfIRType BfIRBuilder::CreateStructType(const StringImpl& name)
|
||||||
|
@ -3495,6 +3500,7 @@ BfIRType BfIRBuilder::MapType(BfType* type, BfIRPopulateType populateType)
|
||||||
{
|
{
|
||||||
PopulateType(type, populateType);
|
PopulateType(type, populateType);
|
||||||
}
|
}
|
||||||
|
BF_ASSERT(type->mTypeId > 0);
|
||||||
BfIRType retType;
|
BfIRType retType;
|
||||||
retType.mKind = BfIRType::TypeKind_TypeId;
|
retType.mKind = BfIRType::TypeKind_TypeId;
|
||||||
retType.mId = type->mTypeId;
|
retType.mId = type->mTypeId;
|
||||||
|
|
|
@ -815,7 +815,7 @@ struct BfConstantSizedArrayType
|
||||||
struct BfConstantUndef
|
struct BfConstantUndef
|
||||||
{
|
{
|
||||||
BfConstType mConstType;
|
BfConstType mConstType;
|
||||||
BfTypeCode mTypeCode;
|
BfIRType mType;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct BfConstantBitCast
|
struct BfConstantBitCast
|
||||||
|
@ -903,7 +903,7 @@ public:
|
||||||
BfIRValue CreateConstArrayZero(BfIRType type, int count);
|
BfIRValue CreateConstArrayZero(BfIRType type, int count);
|
||||||
BfIRValue CreateConstArrayZero(int count);
|
BfIRValue CreateConstArrayZero(int count);
|
||||||
BfIRValue CreateTypeOf(BfType* type);
|
BfIRValue CreateTypeOf(BfType* type);
|
||||||
BfIRValue GetUndefConstValue(BfTypeCode typeCode);
|
BfIRValue GetUndefConstValue(BfIRType type);
|
||||||
};
|
};
|
||||||
|
|
||||||
enum BfIRPopulateType
|
enum BfIRPopulateType
|
||||||
|
|
|
@ -83,8 +83,8 @@ BfLocalMethod::~BfLocalMethod()
|
||||||
BF_ASSERT(mSource->mRefCount >= 0);
|
BF_ASSERT(mSource->mRefCount >= 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
delete mMethodDef;
|
delete mMethodInstanceGroup;
|
||||||
delete mMethodInstanceGroup;
|
delete mMethodDef;
|
||||||
}
|
}
|
||||||
|
|
||||||
void BfDeferredLocalAssignData::ExtendFrom(BfDeferredLocalAssignData* outerLocalAssignData, bool doChain)
|
void BfDeferredLocalAssignData::ExtendFrom(BfDeferredLocalAssignData* outerLocalAssignData, bool doChain)
|
||||||
|
@ -1134,7 +1134,7 @@ void BfModule::EnsureIRBuilder(bool dbgVerifyCodeGen)
|
||||||
// code as we walk the AST
|
// code as we walk the AST
|
||||||
//mBfIRBuilder->mDbgVerifyCodeGen = true;
|
//mBfIRBuilder->mDbgVerifyCodeGen = true;
|
||||||
if (
|
if (
|
||||||
(mModuleName == "-")
|
(mModuleName == "System_StringView")
|
||||||
//|| (mModuleName == "BeefTest2_ClearColorValue")
|
//|| (mModuleName == "BeefTest2_ClearColorValue")
|
||||||
//|| (mModuleName == "Tests_FuncRefs")
|
//|| (mModuleName == "Tests_FuncRefs")
|
||||||
)
|
)
|
||||||
|
@ -1441,12 +1441,12 @@ BfTypedValue BfModule::GetDefaultTypedValue(BfType* type, bool allowRef, BfDefau
|
||||||
|
|
||||||
if (defaultValueKind == BfDefaultValueKind_Undef)
|
if (defaultValueKind == BfDefaultValueKind_Undef)
|
||||||
{
|
{
|
||||||
auto primType = type->ToPrimitiveType();
|
// auto primType = type->ToPrimitiveType();
|
||||||
if (primType != NULL)
|
// if (primType != NULL)
|
||||||
{
|
// {
|
||||||
return BfTypedValue(mBfIRBuilder->GetUndefConstValue(primType->mTypeDef->mTypeCode), type);
|
// return BfTypedValue(mBfIRBuilder->GetUndefConstValue( primType), type);
|
||||||
}
|
// }
|
||||||
return BfTypedValue(mBfIRBuilder->CreateUndefValue(mBfIRBuilder->MapType(type)), type);
|
return BfTypedValue(mBfIRBuilder->GetUndefConstValue(mBfIRBuilder->MapType(type)), type);
|
||||||
}
|
}
|
||||||
|
|
||||||
BfTypedValue typedValue;
|
BfTypedValue typedValue;
|
||||||
|
@ -5390,7 +5390,7 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary<int, int>& usedStrin
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((!typeInstance->IsInterface()) && (typeInstance->mVirtualMethodTableSize > 0) && (needsVData))
|
if ((!mIsConstModule) && (!typeInstance->IsInterface()) && (typeInstance->mVirtualMethodTableSize > 0) && (needsVData))
|
||||||
{
|
{
|
||||||
int startTabIdx = (int)vData.size();
|
int startTabIdx = (int)vData.size();
|
||||||
|
|
||||||
|
@ -7925,7 +7925,7 @@ BfTypedValue BfModule::CreateValueFromExpression(BfExprEvaluator& exprEvaluator,
|
||||||
BfTypedValue result;
|
BfTypedValue result;
|
||||||
result.mKind = BfTypedValueKind_Value;
|
result.mKind = BfTypedValueKind_Value;
|
||||||
result.mType = genericTypeConstraint;
|
result.mType = genericTypeConstraint;
|
||||||
result.mValue = mBfIRBuilder->GetUndefConstValue(primType->mTypeDef->mTypeCode);
|
result.mValue = mBfIRBuilder->GetUndefConstValue(mBfIRBuilder->MapType(primType));
|
||||||
typedVal = result;
|
typedVal = result;
|
||||||
handled = true;
|
handled = true;
|
||||||
}
|
}
|
||||||
|
@ -12064,6 +12064,11 @@ void BfModule::AddMethodReference(const BfMethodRef& methodRef, BfGetMethodInsta
|
||||||
|
|
||||||
BfModuleMethodInstance BfModule::ReferenceExternalMethodInstance(BfMethodInstance* methodInstance, BfGetMethodInstanceFlags flags)
|
BfModuleMethodInstance BfModule::ReferenceExternalMethodInstance(BfMethodInstance* methodInstance, BfGetMethodInstanceFlags flags)
|
||||||
{
|
{
|
||||||
|
if (mIsConstModule)
|
||||||
|
{
|
||||||
|
NOP;
|
||||||
|
}
|
||||||
|
|
||||||
if ((flags & BfGetMethodInstanceFlag_ResultNotUsed) != 0)
|
if ((flags & BfGetMethodInstanceFlag_ResultNotUsed) != 0)
|
||||||
return BfModuleMethodInstance(methodInstance, BfIRValue());
|
return BfModuleMethodInstance(methodInstance, BfIRValue());
|
||||||
|
|
||||||
|
@ -12257,6 +12262,11 @@ BfModule* BfModule::GetOrCreateMethodModule(BfMethodInstance* methodInstance)
|
||||||
|
|
||||||
BfModuleMethodInstance BfModule::GetMethodInstance(BfTypeInstance* typeInst, BfMethodDef* methodDef, const BfTypeVector& methodGenericArguments, BfGetMethodInstanceFlags flags, BfTypeInstance* foreignType)
|
BfModuleMethodInstance BfModule::GetMethodInstance(BfTypeInstance* typeInst, BfMethodDef* methodDef, const BfTypeVector& methodGenericArguments, BfGetMethodInstanceFlags flags, BfTypeInstance* foreignType)
|
||||||
{
|
{
|
||||||
|
if (mIsConstModule)
|
||||||
|
{
|
||||||
|
NOP;
|
||||||
|
}
|
||||||
|
|
||||||
if (methodDef->mMethodType == BfMethodType_Init)
|
if (methodDef->mMethodType == BfMethodType_Init)
|
||||||
return BfModuleMethodInstance();
|
return BfModuleMethodInstance();
|
||||||
|
|
||||||
|
@ -12338,7 +12348,7 @@ BfModuleMethodInstance BfModule::GetMethodInstance(BfTypeInstance* typeInst, BfM
|
||||||
if ((mCurMethodInstance != NULL) && (mCurMethodInstance->mMethodInfoEx != NULL) && (mCurMethodInstance->mMethodInfoEx->mMinDependDepth >= 32))
|
if ((mCurMethodInstance != NULL) && (mCurMethodInstance->mMethodInfoEx != NULL) && (mCurMethodInstance->mMethodInfoEx->mMinDependDepth >= 32))
|
||||||
flags = (BfGetMethodInstanceFlags)(flags | BfGetMethodInstanceFlag_DepthExceeded);
|
flags = (BfGetMethodInstanceFlags)(flags | BfGetMethodInstanceFlag_DepthExceeded);
|
||||||
|
|
||||||
if ((!mIsReified) && (instModule->mIsReified))
|
if ((!mIsConstModule) && (!mIsReified) && (instModule->mIsReified))
|
||||||
{
|
{
|
||||||
BF_ASSERT(!mCompiler->mIsResolveOnly);
|
BF_ASSERT(!mCompiler->mIsResolveOnly);
|
||||||
// A resolve-only module is specializing a method from a type in a reified module,
|
// A resolve-only module is specializing a method from a type in a reified module,
|
||||||
|
@ -12351,7 +12361,7 @@ BfModuleMethodInstance BfModule::GetMethodInstance(BfTypeInstance* typeInst, BfM
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if ((mIsReified) && (!instModule->mIsReified))
|
if ((!mIsConstModule) && (mIsReified) && (!instModule->mIsReified))
|
||||||
{
|
{
|
||||||
if (!typeInst->IsUnspecializedTypeVariation())
|
if (!typeInst->IsUnspecializedTypeVariation())
|
||||||
{
|
{
|
||||||
|
@ -13080,6 +13090,10 @@ void BfModule::SetupMethodIdHash(BfMethodInstance* methodInstance)
|
||||||
}
|
}
|
||||||
|
|
||||||
methodInstance->mIdHash = (int64)hashCtx.Finish64();
|
methodInstance->mIdHash = (int64)hashCtx.Finish64();
|
||||||
|
if (methodInstance->mIdHash == 0x3400000029LL)
|
||||||
|
{
|
||||||
|
NOP;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
BfIRValue BfModule::GetInterfaceSlotNum(BfTypeInstance* ifaceType)
|
BfIRValue BfModule::GetInterfaceSlotNum(BfTypeInstance* ifaceType)
|
||||||
|
@ -13134,6 +13148,18 @@ BfTypedValue BfModule::GetCompilerFieldValue(const StringImpl& str)
|
||||||
{
|
{
|
||||||
return BfTypedValue(mBfIRBuilder->CreateConst(BfTypeCode_Boolean, mIsConstModule ? 1 : 0), GetPrimitiveType(BfTypeCode_Boolean));
|
return BfTypedValue(mBfIRBuilder->CreateConst(BfTypeCode_Boolean, mIsConstModule ? 1 : 0), GetPrimitiveType(BfTypeCode_Boolean));
|
||||||
}
|
}
|
||||||
|
if (str == "#IsBuilding")
|
||||||
|
{
|
||||||
|
return BfTypedValue(mBfIRBuilder->CreateConst(BfTypeCode_Boolean, (!mCompiler->mIsResolveOnly) ? 1 : 0), GetPrimitiveType(BfTypeCode_Boolean));
|
||||||
|
}
|
||||||
|
if (str == "#IsReified")
|
||||||
|
{
|
||||||
|
return BfTypedValue(mBfIRBuilder->CreateConst(BfTypeCode_Boolean, mIsReified ? 1 : 0), GetPrimitiveType(BfTypeCode_Boolean));
|
||||||
|
}
|
||||||
|
if (str == "#CompileRev")
|
||||||
|
{
|
||||||
|
return BfTypedValue(mBfIRBuilder->CreateConst(BfTypeCode_Int32, mCompiler->mRevision), GetPrimitiveType(BfTypeCode_Int32));
|
||||||
|
}
|
||||||
if (str == "#ModuleName")
|
if (str == "#ModuleName")
|
||||||
{
|
{
|
||||||
return BfTypedValue(GetStringObjectValue(mModuleName), ResolveTypeDef(mCompiler->mStringTypeDef));
|
return BfTypedValue(GetStringObjectValue(mModuleName), ResolveTypeDef(mCompiler->mStringTypeDef));
|
||||||
|
@ -14504,7 +14530,7 @@ void BfModule::CreateDelegateInvokeMethod()
|
||||||
if (mCurMethodInstance->mReturnType->IsValueType())
|
if (mCurMethodInstance->mReturnType->IsValueType())
|
||||||
mBfIRBuilder->PopulateType(mCurMethodInstance->mReturnType, BfIRPopulateType_Full);
|
mBfIRBuilder->PopulateType(mCurMethodInstance->mReturnType, BfIRPopulateType_Full);
|
||||||
|
|
||||||
if ((!mIsConstModule) && (mCurMethodInstance->GetStructRetIdx() != 0))
|
if ((mIsConstModule) || (mCurMethodInstance->GetStructRetIdx() != 0))
|
||||||
memberFuncArgs.push_back(BfIRValue()); // Push 'target'
|
memberFuncArgs.push_back(BfIRValue()); // Push 'target'
|
||||||
|
|
||||||
int thisIdx = 0;
|
int thisIdx = 0;
|
||||||
|
@ -17078,11 +17104,13 @@ void BfModule::ProcessMethod_ProcessDeferredLocals(int startIdx)
|
||||||
BP_ZONE_F("ProcessMethod lambdaInstance %s", lambdaInstance->mMethodInstance->mMethodDef->mName.c_str());
|
BP_ZONE_F("ProcessMethod lambdaInstance %s", lambdaInstance->mMethodInstance->mMethodDef->mName.c_str());
|
||||||
lambdaInstance->mMethodInstance->mMethodInstanceGroup = &methodInstanceGroup;
|
lambdaInstance->mMethodInstance->mMethodInstanceGroup = &methodInstanceGroup;
|
||||||
ProcessMethod(lambdaInstance->mMethodInstance);
|
ProcessMethod(lambdaInstance->mMethodInstance);
|
||||||
|
lambdaInstance->mMethodInstance->mMethodInstanceGroup = NULL;
|
||||||
|
|
||||||
if (lambdaInstance->mDtorMethodInstance != NULL)
|
if (lambdaInstance->mDtorMethodInstance != NULL)
|
||||||
{
|
{
|
||||||
lambdaInstance->mDtorMethodInstance->mMethodInstanceGroup = &methodInstanceGroup;
|
lambdaInstance->mDtorMethodInstance->mMethodInstanceGroup = &methodInstanceGroup;
|
||||||
ProcessMethod(lambdaInstance->mDtorMethodInstance);
|
ProcessMethod(lambdaInstance->mDtorMethodInstance);
|
||||||
|
lambdaInstance->mDtorMethodInstance->mMethodInstanceGroup = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -17546,22 +17574,25 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup)
|
||||||
|
|
||||||
BF_ASSERT(methodInstance->mMethodInstanceGroup->mOnDemandKind != BfMethodOnDemandKind_NotSet);
|
BF_ASSERT(methodInstance->mMethodInstanceGroup->mOnDemandKind != BfMethodOnDemandKind_NotSet);
|
||||||
|
|
||||||
if ((methodInstance->mMethodInstanceGroup->mOnDemandKind != BfMethodOnDemandKind_AlwaysInclude) &&
|
if (!mIsConstModule)
|
||||||
(methodInstance->mMethodInstanceGroup->mOnDemandKind != BfMethodOnDemandKind_Referenced))
|
|
||||||
{
|
{
|
||||||
methodInstance->mMethodInstanceGroup->mOnDemandKind = BfMethodOnDemandKind_Referenced;
|
if ((methodInstance->mMethodInstanceGroup->mOnDemandKind != BfMethodOnDemandKind_AlwaysInclude) &&
|
||||||
|
(methodInstance->mMethodInstanceGroup->mOnDemandKind != BfMethodOnDemandKind_Referenced))
|
||||||
auto owningModule = methodInstance->GetOwner()->mModule;
|
|
||||||
|
|
||||||
if (owningModule->mIsScratchModule)
|
|
||||||
{
|
{
|
||||||
BF_ASSERT(owningModule->mOnDemandMethodCount == 0);
|
methodInstance->mMethodInstanceGroup->mOnDemandKind = BfMethodOnDemandKind_Referenced;
|
||||||
}
|
|
||||||
else
|
auto owningModule = methodInstance->GetOwner()->mModule;
|
||||||
{
|
|
||||||
BF_ASSERT((owningModule->mOnDemandMethodCount > 0) || (!HasCompiledOutput()) || (owningModule->mExtensionCount > 0));
|
if (owningModule->mIsScratchModule)
|
||||||
if (owningModule->mOnDemandMethodCount > 0)
|
{
|
||||||
owningModule->mOnDemandMethodCount--;
|
BF_ASSERT(owningModule->mOnDemandMethodCount == 0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
BF_ASSERT((owningModule->mOnDemandMethodCount > 0) || (!HasCompiledOutput()) || (owningModule->mExtensionCount > 0));
|
||||||
|
if (owningModule->mOnDemandMethodCount > 0)
|
||||||
|
owningModule->mOnDemandMethodCount--;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -69,7 +69,8 @@ enum BfEvalExprFlags
|
||||||
BfEvalExprFlags_AllowNonConst = 0x10000,
|
BfEvalExprFlags_AllowNonConst = 0x10000,
|
||||||
BfEvalExprFlags_StringInterpolateFormat = 0x20000,
|
BfEvalExprFlags_StringInterpolateFormat = 0x20000,
|
||||||
BfEvalExprFlags_NoLookupError = 0x40000,
|
BfEvalExprFlags_NoLookupError = 0x40000,
|
||||||
BfEvalExprFlags_ConstExpr = 0x80000,
|
BfEvalExprFlags_ConstEval = 0x80000,
|
||||||
|
BfEvalExprFlags_InCascade = 0x100000,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum BfCastFlags
|
enum BfCastFlags
|
||||||
|
@ -904,13 +905,15 @@ public:
|
||||||
|
|
||||||
~BfLambdaInstance()
|
~BfLambdaInstance()
|
||||||
{
|
{
|
||||||
delete mMethodInstance->mMethodDef;
|
auto methodDef = mMethodInstance->mMethodDef;
|
||||||
delete mMethodInstance;
|
delete mMethodInstance;
|
||||||
|
delete methodDef;
|
||||||
|
|
||||||
if (mDtorMethodInstance != NULL)
|
if (mDtorMethodInstance != NULL)
|
||||||
{
|
{
|
||||||
delete mDtorMethodInstance->mMethodDef;
|
auto methodDef = mDtorMethodInstance->mMethodDef;
|
||||||
delete mDtorMethodInstance;
|
delete mDtorMethodInstance;
|
||||||
|
delete methodDef;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -10169,12 +10169,12 @@ BfIRValue BfModule::CastToValue(BfAstNode* srcNode, BfTypedValue typedVal, BfTyp
|
||||||
|
|
||||||
if (allowCast)
|
if (allowCast)
|
||||||
{
|
{
|
||||||
if (ignoreWrites)
|
if ((ignoreWrites) && (!typedVal.mValue.IsConst()))
|
||||||
return mBfIRBuilder->GetFakeVal();
|
return mBfIRBuilder->GetFakeVal();
|
||||||
return mBfIRBuilder->CreateBitCast(typedVal.mValue, mBfIRBuilder->MapType(toType));
|
return mBfIRBuilder->CreateBitCast(typedVal.mValue, mBfIRBuilder->MapType(toType));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// MethodRef -> Function
|
// MethodRef -> Function
|
||||||
if ((typedVal.mType->IsMethodRef()) && (toType->IsFunction()))
|
if ((typedVal.mType->IsMethodRef()) && (toType->IsFunction()))
|
||||||
|
@ -10566,12 +10566,13 @@ BfIRValue BfModule::CastToValue(BfAstNode* srcNode, BfTypedValue typedVal, BfTyp
|
||||||
|
|
||||||
auto undefConst = (BfConstantUndef*)constant;
|
auto undefConst = (BfConstantUndef*)constant;
|
||||||
|
|
||||||
auto fakeVal = GetFakeTypedValue(GetPrimitiveType(undefConst->mTypeCode));
|
BF_ASSERT(undefConst->mType.mKind == BfIRTypeData::TypeKind_TypeId);
|
||||||
// Why did we have this BfCastFlags_Explicit? It broke creating errors on things like "int16 val = TCount;"
|
auto bfType = mContext->mTypes[undefConst->mType.mId];
|
||||||
//auto val = CastToValue(srcNode, fakeVal, toType, (BfCastFlags)(castFlags | BfCastFlags_Explicit));
|
|
||||||
|
auto fakeVal = GetFakeTypedValue(bfType);
|
||||||
auto val = CastToValue(srcNode, fakeVal, toType, castFlags);
|
auto val = CastToValue(srcNode, fakeVal, toType, castFlags);
|
||||||
if (val)
|
if (val)
|
||||||
return val;
|
return mBfIRBuilder->GetUndefConstValue(mBfIRBuilder->MapType(toType));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5441,7 +5441,7 @@ BfExpression* BfReducer::CreateAttributedExpression(BfTokenNode* tokenNode, bool
|
||||||
|
|
||||||
if (!onlyAllowIdentifier)
|
if (!onlyAllowIdentifier)
|
||||||
{
|
{
|
||||||
BfExpression* expr = CreateExpressionAfter(attrib);
|
BfExpression* expr = CreateExpressionAfter(attrib, CreateExprFlags_EarlyExit);
|
||||||
if (expr != NULL)
|
if (expr != NULL)
|
||||||
{
|
{
|
||||||
if (auto identifier = BfNodeDynCast<BfIdentifierNode>(expr))
|
if (auto identifier = BfNodeDynCast<BfIdentifierNode>(expr))
|
||||||
|
|
|
@ -535,6 +535,13 @@ BfMethodInfoEx::~BfMethodInfoEx()
|
||||||
|
|
||||||
BfMethodInstance::~BfMethodInstance()
|
BfMethodInstance::~BfMethodInstance()
|
||||||
{
|
{
|
||||||
|
if (mMethodInstanceGroup != NULL)
|
||||||
|
BfLogSys(GetOwner()->mModule->mSystem, "BfMethodInstance::~BfMethodInstance %p Local:%d InCEMachine:%d\n", this, mMethodDef->mIsLocalMethod, mInCEMachine);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
BF_ASSERT(!mMethodDef->mIsLocalMethod);
|
||||||
|
}
|
||||||
|
|
||||||
if (mInCEMachine)
|
if (mInCEMachine)
|
||||||
{
|
{
|
||||||
auto module = GetOwner()->mModule;
|
auto module = GetOwner()->mModule;
|
||||||
|
|
|
@ -6438,10 +6438,15 @@ void BfModule::Visit(BfForEachStatement* forEachStmt)
|
||||||
methodMatcher.CheckType(itrInterface, itr, false);
|
methodMatcher.CheckType(itrInterface, itr, false);
|
||||||
methodMatcher.TryDevirtualizeCall(itr);
|
methodMatcher.TryDevirtualizeCall(itr);
|
||||||
exprEvaluator.mReceivingValue = &nextResult;
|
exprEvaluator.mReceivingValue = &nextResult;
|
||||||
auto retVal = exprEvaluator.CreateCall(&methodMatcher, itr);
|
auto retVal = exprEvaluator.CreateCall(&methodMatcher, itr);
|
||||||
if (exprEvaluator.mReceivingValue != NULL)
|
if (exprEvaluator.mReceivingValue != NULL)
|
||||||
{
|
{
|
||||||
AssertErrorState();
|
if (mIsConstModule)
|
||||||
|
{
|
||||||
|
mBfIRBuilder->CreateStore(retVal.mValue, nextResult.mValue);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
AssertErrorState();
|
||||||
}
|
}
|
||||||
if ((retVal) && (!retVal.mType->IsVar()))
|
if ((retVal) && (!retVal.mType->IsVar()))
|
||||||
{
|
{
|
||||||
|
|
|
@ -733,6 +733,7 @@ public:
|
||||||
bool mIsNoSplat;
|
bool mIsNoSplat;
|
||||||
bool mIsNoReflect;
|
bool mIsNoReflect;
|
||||||
bool mIsSkipCall;
|
bool mIsSkipCall;
|
||||||
|
bool mIsConstEval;
|
||||||
bool mIsOperator;
|
bool mIsOperator;
|
||||||
bool mIsExtern;
|
bool mIsExtern;
|
||||||
bool mIsNoDiscard;
|
bool mIsNoDiscard;
|
||||||
|
@ -761,6 +762,7 @@ public:
|
||||||
mIsNoSplat = false;
|
mIsNoSplat = false;
|
||||||
mIsNoReflect = false;
|
mIsNoReflect = false;
|
||||||
mIsSkipCall = false;
|
mIsSkipCall = false;
|
||||||
|
mIsConstEval = false;
|
||||||
mIsOperator = false;
|
mIsOperator = false;
|
||||||
mIsExtern = false;
|
mIsExtern = false;
|
||||||
mIsNoDiscard = false;
|
mIsNoDiscard = false;
|
||||||
|
|
|
@ -214,6 +214,13 @@ CeFunction::~CeFunction()
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
CeFunctionInfo::~CeFunctionInfo()
|
||||||
|
{
|
||||||
|
delete mCeFunction;
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
#define CE_GET(T) *((T*)(mPtr += sizeof(T)) - 1)
|
#define CE_GET(T) *((T*)(mPtr += sizeof(T)) - 1)
|
||||||
|
|
||||||
void CeDumpContext::DumpOperandInfo(CeOperandInfoKind operandInfoKind)
|
void CeDumpContext::DumpOperandInfo(CeOperandInfoKind operandInfoKind)
|
||||||
|
@ -2151,6 +2158,10 @@ void CeBuilder::Build()
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mcAgg = GetOperand(castedInst->mAggVal);
|
||||||
|
}
|
||||||
|
|
||||||
auto aggType = mcAgg.mType;
|
auto aggType = mcAgg.mType;
|
||||||
int byteOffset = 0;
|
int byteOffset = 0;
|
||||||
|
@ -2590,8 +2601,10 @@ CeMachine::CeMachine(BfCompiler* compiler)
|
||||||
mCeModule = NULL;
|
mCeModule = NULL;
|
||||||
mRevision = 0;
|
mRevision = 0;
|
||||||
mExecuteId = 0;
|
mExecuteId = 0;
|
||||||
|
mRevisionExecuteTime = 0;
|
||||||
mCurTargetSrc = NULL;
|
mCurTargetSrc = NULL;
|
||||||
mCurModule = NULL;
|
mCurModule = NULL;
|
||||||
|
mCurMethodInstance = NULL;
|
||||||
mCurExpectingType = NULL;
|
mCurExpectingType = NULL;
|
||||||
mHeap = NULL;
|
mHeap = NULL;
|
||||||
mStringCharsOffset = -1;
|
mStringCharsOffset = -1;
|
||||||
|
@ -2613,7 +2626,7 @@ CeMachine::~CeMachine()
|
||||||
|
|
||||||
BfError* CeMachine::Fail(const StringImpl& error)
|
BfError* CeMachine::Fail(const StringImpl& error)
|
||||||
{
|
{
|
||||||
auto bfError = mCurModule->Fail("Unable to const-evaluate function", mCurTargetSrc);
|
auto bfError = mCurModule->Fail(StrFormat("Unable to const-evaluate %s", mCurModule->MethodToString(mCurMethodInstance).c_str()), mCurTargetSrc);
|
||||||
if (bfError == NULL)
|
if (bfError == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
mCompiler->mPassInstance->MoreInfo(error);
|
mCompiler->mPassInstance->MoreInfo(error);
|
||||||
|
@ -2622,7 +2635,7 @@ BfError* CeMachine::Fail(const StringImpl& error)
|
||||||
|
|
||||||
BfError* CeMachine::Fail(const CeFrame& curFrame, const StringImpl& str)
|
BfError* CeMachine::Fail(const CeFrame& curFrame, const StringImpl& str)
|
||||||
{
|
{
|
||||||
auto bfError = mCurModule->Fail("Unable to const-evaluate function", mCurTargetSrc);
|
auto bfError = mCurModule->Fail(StrFormat("Unable to const-evaluate %s", mCurModule->MethodToString(mCurMethodInstance).c_str()), mCurTargetSrc);
|
||||||
if (bfError == NULL)
|
if (bfError == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
@ -2696,7 +2709,11 @@ void CeMachine::Init()
|
||||||
mCeModule->mIsSpecialModule = true;
|
mCeModule->mIsSpecialModule = true;
|
||||||
//mCeModule->mIsScratchModule = true;
|
//mCeModule->mIsScratchModule = true;
|
||||||
mCeModule->mIsConstModule = true;
|
mCeModule->mIsConstModule = true;
|
||||||
mCeModule->mIsReified = true;
|
//mCeModule->mIsReified = true;
|
||||||
|
if (mCompiler->mIsResolveOnly)
|
||||||
|
mCeModule->mIsReified = true;
|
||||||
|
else
|
||||||
|
mCeModule->mIsReified = false;
|
||||||
mCeModule->Init();
|
mCeModule->Init();
|
||||||
|
|
||||||
mCeModule->mBfIRBuilder = new BfIRBuilder(mCeModule);
|
mCeModule->mBfIRBuilder = new BfIRBuilder(mCeModule);
|
||||||
|
@ -2731,6 +2748,28 @@ bool CeMachine::CeFree(addr_ce addr)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
addr_ce CeMachine::CeAllocArray(BfArrayType* arrayType, int count, addr_ce& elemsAddr)
|
||||||
|
{
|
||||||
|
mCeModule->PopulateType(arrayType);
|
||||||
|
|
||||||
|
BfType* elemType = arrayType->GetUnderlyingType();
|
||||||
|
auto countOffset = arrayType->mBaseType->mFieldInstances[0].mDataOffset;
|
||||||
|
auto elemOffset = arrayType->mFieldInstances[0].mDataOffset;
|
||||||
|
|
||||||
|
int allocSize = elemOffset + elemType->GetStride() * count;
|
||||||
|
|
||||||
|
uint8* mem = CeMalloc(allocSize);
|
||||||
|
|
||||||
|
memset(mem, 0, allocSize);
|
||||||
|
|
||||||
|
*(int32*)(mem) = arrayType->mTypeId;
|
||||||
|
*(int32*)(mem + countOffset) = count;
|
||||||
|
|
||||||
|
elemsAddr = (addr_ce)(mem + elemOffset - mMemory.mVals);
|
||||||
|
|
||||||
|
return (addr_ce)(mem - mMemory.mVals);
|
||||||
|
}
|
||||||
|
|
||||||
addr_ce CeMachine::GetConstantData(BeConstant* constant)
|
addr_ce CeMachine::GetConstantData(BeConstant* constant)
|
||||||
{
|
{
|
||||||
auto writeConstant = constant;
|
auto writeConstant = constant;
|
||||||
|
@ -2889,6 +2928,7 @@ BeModule* CeMachine::GetBeModule()
|
||||||
|
|
||||||
void CeMachine::CompileStarted()
|
void CeMachine::CompileStarted()
|
||||||
{
|
{
|
||||||
|
mRevisionExecuteTime = 0;
|
||||||
mRevision++;
|
mRevision++;
|
||||||
if (mCeModule != NULL)
|
if (mCeModule != NULL)
|
||||||
{
|
{
|
||||||
|
@ -2912,37 +2952,48 @@ void CeMachine::DerefMethodInfo(CeFunctionInfo* ceFunctionInfo)
|
||||||
|
|
||||||
void CeMachine::RemoveMethod(BfMethodInstance* methodInstance)
|
void CeMachine::RemoveMethod(BfMethodInstance* methodInstance)
|
||||||
{
|
{
|
||||||
|
BfLogSys(methodInstance->GetOwner()->mModule->mSystem, "CeMachine::RemoveMethod %p\n", methodInstance);
|
||||||
|
|
||||||
auto itr = mFunctions.Find(methodInstance);
|
auto itr = mFunctions.Find(methodInstance);
|
||||||
auto ceFunctionInfo = itr->mValue;
|
auto ceFunctionInfo = itr->mValue;
|
||||||
BF_ASSERT(itr != mFunctions.end());
|
BF_ASSERT(itr != mFunctions.end());
|
||||||
if (itr != mFunctions.end())
|
if (itr != mFunctions.end())
|
||||||
{
|
{
|
||||||
auto ceFunction = ceFunctionInfo->mCeFunction;
|
if (ceFunctionInfo->mMethodInstance == methodInstance)
|
||||||
for (auto& callEntry : ceFunction->mCallTable)
|
|
||||||
{
|
{
|
||||||
if (callEntry.mFunctionInfo != NULL)
|
auto ceFunction = ceFunctionInfo->mCeFunction;
|
||||||
DerefMethodInfo(callEntry.mFunctionInfo);
|
for (auto& callEntry : ceFunction->mCallTable)
|
||||||
}
|
{
|
||||||
delete ceFunction;
|
if (callEntry.mFunctionInfo != NULL)
|
||||||
ceFunctionInfo->mCeFunction = NULL;
|
DerefMethodInfo(callEntry.mFunctionInfo);
|
||||||
ceFunctionInfo->mMethodInstance = NULL;
|
}
|
||||||
|
delete ceFunction;
|
||||||
|
ceFunctionInfo->mCeFunction = NULL;
|
||||||
|
ceFunctionInfo->mMethodInstance = NULL;
|
||||||
|
|
||||||
if (ceFunctionInfo->mRefCount > 1)
|
if (methodInstance->mMethodDef->mIsLocalMethod)
|
||||||
{
|
{
|
||||||
// Generate a methodref
|
// We can't rebuild these anyway
|
||||||
ceFunctionInfo->mMethodRef = methodInstance;
|
}
|
||||||
}
|
else if (ceFunctionInfo->mRefCount > 1)
|
||||||
|
{
|
||||||
|
// Generate a methodref
|
||||||
|
ceFunctionInfo->mMethodRef = methodInstance;
|
||||||
|
}
|
||||||
|
|
||||||
DerefMethodInfo(ceFunctionInfo);
|
DerefMethodInfo(ceFunctionInfo);
|
||||||
|
}
|
||||||
|
|
||||||
mFunctions.Remove(itr);
|
mFunctions.Remove(itr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CheckFunctions();
|
||||||
}
|
}
|
||||||
|
|
||||||
//#define CE_GETC(T) *((T*)(addr += sizeof(T)) - 1)
|
//#define CE_GETC(T) *((T*)(addr += sizeof(T)) - 1)
|
||||||
#define CE_GETC(T) *(T*)(mMemory.mVals + addr)
|
#define CE_GETC(T) *(T*)(mMemory.mVals + addr)
|
||||||
|
|
||||||
bool CeMachine::WriteConstant(BfModule* module, addr_ce addr, BfConstant* constant, BfType* type)
|
bool CeMachine::WriteConstant(BfModule* module, addr_ce addr, BfConstant* constant, BfType* type, bool isParams)
|
||||||
{
|
{
|
||||||
switch (constant->mTypeCode)
|
switch (constant->mTypeCode)
|
||||||
{
|
{
|
||||||
|
@ -2987,8 +3038,56 @@ bool CeMachine::WriteConstant(BfModule* module, addr_ce addr, BfConstant* consta
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
else
|
else if (type->IsArray())
|
||||||
{
|
{
|
||||||
|
auto elemType = type->GetUnderlyingType();
|
||||||
|
|
||||||
|
addr_ce elemsAddr = 0;
|
||||||
|
addr_ce arrayAddr = CeAllocArray((BfArrayType*)type, aggConstant->mValues.size(), elemsAddr);
|
||||||
|
|
||||||
|
for (int i = 0; i < (int)aggConstant->mValues.size(); i++)
|
||||||
|
{
|
||||||
|
auto fieldConstant = module->mBfIRBuilder->GetConstant(aggConstant->mValues[i]);
|
||||||
|
if (fieldConstant == NULL)
|
||||||
|
return false;
|
||||||
|
WriteConstant(module, elemsAddr + i * elemType->GetStride(), fieldConstant, elemType);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mCeModule->mSystem->mPtrSize == 4)
|
||||||
|
CE_GETC(int32) = arrayAddr;
|
||||||
|
else
|
||||||
|
CE_GETC(int64) = arrayAddr;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else if ((type->IsInstanceOf(module->mCompiler->mSpanTypeDef)) && (isParams))
|
||||||
|
{
|
||||||
|
auto elemType = type->GetUnderlyingType();
|
||||||
|
addr_ce elemsAddr = CeMalloc(elemType->GetStride() * aggConstant->mValues.size()) - mMemory.mVals;
|
||||||
|
|
||||||
|
for (int i = 0; i < (int)aggConstant->mValues.size(); i++)
|
||||||
|
{
|
||||||
|
auto fieldConstant = module->mBfIRBuilder->GetConstant(aggConstant->mValues[i]);
|
||||||
|
if (fieldConstant == NULL)
|
||||||
|
return false;
|
||||||
|
WriteConstant(module, elemsAddr + i * elemType->GetStride(), fieldConstant, elemType);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mCeModule->mSystem->mPtrSize == 4)
|
||||||
|
{
|
||||||
|
CE_GETC(int32) = elemsAddr;
|
||||||
|
addr += 4;
|
||||||
|
CE_GETC(int32) = (int32)aggConstant->mValues.size();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
CE_GETC(int32) = elemsAddr;
|
||||||
|
addr += 8;
|
||||||
|
CE_GETC(int64) = (int32)aggConstant->mValues.size();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
BF_ASSERT(type->IsStruct());
|
BF_ASSERT(type->IsStruct());
|
||||||
|
|
||||||
module->PopulateType(type);
|
module->PopulateType(type);
|
||||||
|
@ -3087,7 +3186,40 @@ CeErrorKind CeMachine::WriteConstant(CeConstStructData& data, BeConstant* constV
|
||||||
}
|
}
|
||||||
|
|
||||||
if (globalVar->mInitializer == NULL)
|
if (globalVar->mInitializer == NULL)
|
||||||
return CeErrorKind_GlobalVariable;
|
{
|
||||||
|
auto ptr = data.mData.GrowUninitialized(mCeModule->mSystem->mPtrSize);
|
||||||
|
int64 addr64 = (addr_ce)0;
|
||||||
|
memcpy(ptr, &addr64, mCeModule->mSystem->mPtrSize);
|
||||||
|
return CeErrorKind_None;
|
||||||
|
|
||||||
|
//TODO: Add this global variable in there and fixup
|
||||||
|
|
||||||
|
// CeStaticFieldInfo* staticFieldInfoPtr = NULL;
|
||||||
|
// if (mCeMachine->mStaticFieldMap.TryGetValue(globalVar->mName, &staticFieldInfoPtr))
|
||||||
|
// {
|
||||||
|
// CeStaticFieldInfo* staticFieldInfo = staticFieldInfoPtr;
|
||||||
|
//
|
||||||
|
// int* staticFieldTableIdxPtr = NULL;
|
||||||
|
// if (mStaticFieldMap.TryAdd(globalVar, NULL, &staticFieldTableIdxPtr))
|
||||||
|
// {
|
||||||
|
// CeStaticFieldEntry staticFieldEntry;
|
||||||
|
// staticFieldEntry.mTypeId = staticFieldInfo->mFieldInstance->mOwner->mTypeId;
|
||||||
|
// staticFieldEntry.mName = globalVar->mName;
|
||||||
|
// staticFieldEntry.mSize = globalVar->mType->mSize;
|
||||||
|
// *staticFieldTableIdxPtr = (int)mCeFunction->mStaticFieldTable.size();
|
||||||
|
// mCeFunction->mStaticFieldTable.Add(staticFieldEntry);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// auto result = FrameAlloc(mCeMachine->GetBeContext()->GetPointerTo(globalVar->mType));
|
||||||
|
//
|
||||||
|
// Emit(CeOp_GetStaticField);
|
||||||
|
// EmitFrameOffset(result);
|
||||||
|
// Emit((int32)*staticFieldTableIdxPtr);
|
||||||
|
//
|
||||||
|
// return result;
|
||||||
|
// }
|
||||||
|
// return CeErrorKind_GlobalVariable;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
BF_ASSERT(!data.mQueueFixups);
|
BF_ASSERT(!data.mQueueFixups);
|
||||||
|
@ -3375,7 +3507,7 @@ BfIRValue CeMachine::CreateConstant(BfModule* module, uint8* ptr, BfType* bfType
|
||||||
|
|
||||||
if (typeInst->IsInstanceOf(mCeModule->mCompiler->mSpanTypeDef))
|
if (typeInst->IsInstanceOf(mCeModule->mCompiler->mSpanTypeDef))
|
||||||
{
|
{
|
||||||
if ((outType != NULL) && (mCurExpectingType->IsSizedArray()))
|
if ((outType != NULL) && ((mCurExpectingType == NULL) || (mCurExpectingType->IsSizedArray())))
|
||||||
{
|
{
|
||||||
module->PopulateType(typeInst);
|
module->PopulateType(typeInst);
|
||||||
|
|
||||||
|
@ -3402,6 +3534,9 @@ BfIRValue CeMachine::CreateConstant(BfModule* module, uint8* ptr, BfType* bfType
|
||||||
*outType = module->CreateSizedArrayType(elemType, lenVal);
|
*outType = module->CreateSizedArrayType(elemType, lenVal);
|
||||||
return instResult;
|
return instResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Fail(StrFormat("Span return type '%s' must be received by a sized array", module->TypeToString(typeInst).c_str()));
|
||||||
|
return BfIRValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (typeInst->IsObjectOrInterface())
|
if (typeInst->IsObjectOrInterface())
|
||||||
|
@ -3590,7 +3725,7 @@ BfIRValue CeMachine::CreateConstant(BfModule* module, uint8* ptr, BfType* bfType
|
||||||
|
|
||||||
bool CeMachine::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8* startFramePtr)
|
bool CeMachine::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8* startFramePtr)
|
||||||
{
|
{
|
||||||
mExecuteId++;
|
mExecuteId++;
|
||||||
|
|
||||||
CeFunction* ceFunction = startFunction;
|
CeFunction* ceFunction = startFunction;
|
||||||
uint8* memStart = &mMemory[0];
|
uint8* memStart = &mMemory[0];
|
||||||
|
@ -3598,7 +3733,9 @@ bool CeMachine::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
|
||||||
uint8* instPtr = (ceFunction->mCode.IsEmpty()) ? NULL : &ceFunction->mCode[0];
|
uint8* instPtr = (ceFunction->mCode.IsEmpty()) ? NULL : &ceFunction->mCode[0];
|
||||||
uint8* stackPtr = startStackPtr;
|
uint8* stackPtr = startStackPtr;
|
||||||
uint8* framePtr = startFramePtr;
|
uint8* framePtr = startFramePtr;
|
||||||
|
|
||||||
|
volatile bool* cancelPtr = &mCompiler->mCanceling;
|
||||||
|
|
||||||
auto _GetCurFrame = [&]()
|
auto _GetCurFrame = [&]()
|
||||||
{
|
{
|
||||||
CeFrame ceFrame;
|
CeFrame ceFrame;
|
||||||
|
@ -3659,32 +3796,6 @@ bool CeMachine::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
|
||||||
handled = true;
|
handled = true;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else if (checkFunction->mFunctionKind == CeFunctionKind_DebugWrite)
|
|
||||||
{
|
|
||||||
int32 ptrVal = *(int32*)((uint8*)stackPtr + 0);
|
|
||||||
auto size = *(int32*)(stackPtr + mCeModule->mSystem->mPtrSize);
|
|
||||||
CE_CHECKADDR(ptrVal, size);
|
|
||||||
char* strPtr = (char*)(ptrVal + memStart);
|
|
||||||
String str;
|
|
||||||
str.Insert(0, strPtr, size);
|
|
||||||
OutputDebugStr(str);
|
|
||||||
handled = true;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else if (checkFunction->mFunctionKind == CeFunctionKind_DebugWrite_Int)
|
|
||||||
{
|
|
||||||
int32 intVal = *(int32*)((uint8*)stackPtr + 0);
|
|
||||||
OutputDebugStrF("Debug Val: %d\n", intVal);
|
|
||||||
handled = true;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else if (checkFunction->mFunctionKind == CeFunctionKind_GetReflectType)
|
|
||||||
{
|
|
||||||
int32 typeId = *(int32*)((uint8*)stackPtr + mCeModule->mSystem->mPtrSize);
|
|
||||||
auto reflectType = GetReflectType(typeId);
|
|
||||||
_FixVariables();
|
|
||||||
*(addr_ce*)(stackPtr + 0) = reflectType;
|
|
||||||
}
|
|
||||||
else if (checkFunction->mFunctionKind == CeFunctionKind_FatalError)
|
else if (checkFunction->mFunctionKind == CeFunctionKind_FatalError)
|
||||||
{
|
{
|
||||||
int32 strInstAddr = *(int32*)((uint8*)stackPtr + 0);
|
int32 strInstAddr = *(int32*)((uint8*)stackPtr + 0);
|
||||||
|
@ -3725,6 +3836,67 @@ bool CeMachine::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
else if (checkFunction->mFunctionKind == CeFunctionKind_DebugWrite)
|
||||||
|
{
|
||||||
|
int32 ptrVal = *(int32*)((uint8*)stackPtr + 0);
|
||||||
|
auto size = *(int32*)(stackPtr + mCeModule->mSystem->mPtrSize);
|
||||||
|
CE_CHECKADDR(ptrVal, size);
|
||||||
|
char* strPtr = (char*)(ptrVal + memStart);
|
||||||
|
String str;
|
||||||
|
str.Insert(0, strPtr, size);
|
||||||
|
OutputDebugStr(str);
|
||||||
|
handled = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else if (checkFunction->mFunctionKind == CeFunctionKind_DebugWrite_Int)
|
||||||
|
{
|
||||||
|
int32 intVal = *(int32*)((uint8*)stackPtr + 0);
|
||||||
|
OutputDebugStrF("Debug Val: %d\n", intVal);
|
||||||
|
handled = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else if (checkFunction->mFunctionKind == CeFunctionKind_GetReflectType)
|
||||||
|
{
|
||||||
|
addr_ce objAddr = *(addr_ce*)((uint8*)stackPtr + mCeModule->mSystem->mPtrSize);
|
||||||
|
CE_CHECKADDR(addr_ce, 4);
|
||||||
|
int32 typeId = *(int32*)(objAddr + memStart);
|
||||||
|
|
||||||
|
auto reflectType = GetReflectType(typeId);
|
||||||
|
_FixVariables();
|
||||||
|
*(addr_ce*)(stackPtr + 0) = reflectType;
|
||||||
|
handled = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else if (checkFunction->mFunctionKind == CeFunctionKind_GetReflectTypeById)
|
||||||
|
{
|
||||||
|
int32 typeId = *(int32*)((uint8*)stackPtr + mCeModule->mSystem->mPtrSize);
|
||||||
|
auto reflectType = GetReflectType(typeId);
|
||||||
|
_FixVariables();
|
||||||
|
*(addr_ce*)(stackPtr + 0) = reflectType;
|
||||||
|
handled = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else if (checkFunction->mFunctionKind == CeFunctionKind_Sleep)
|
||||||
|
{
|
||||||
|
int32 sleepMS = *(int32*)((uint8*)stackPtr);
|
||||||
|
while (sleepMS > 0)
|
||||||
|
{
|
||||||
|
if (*cancelPtr)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (sleepMS > 200)
|
||||||
|
{
|
||||||
|
Sleep(200);
|
||||||
|
sleepMS -= 200;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
Sleep(sleepMS);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
handled = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
else if (checkFunction->mFunctionKind == CeFunctionKind_Char32_ToLower)
|
else if (checkFunction->mFunctionKind == CeFunctionKind_Char32_ToLower)
|
||||||
{
|
{
|
||||||
int32& result = *(int32*)((uint8*)stackPtr + 0);
|
int32& result = *(int32*)((uint8*)stackPtr + 0);
|
||||||
|
@ -3847,9 +4019,7 @@ bool CeMachine::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
|
||||||
return false;
|
return false;
|
||||||
if (handled)
|
if (handled)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
volatile bool* cancelPtr = &mCompiler->mCanceling;
|
|
||||||
|
|
||||||
int callCount = 0;
|
int callCount = 0;
|
||||||
int instIdx = 0;
|
int instIdx = 0;
|
||||||
|
@ -3858,7 +4028,7 @@ bool CeMachine::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
|
||||||
{
|
{
|
||||||
if (*cancelPtr)
|
if (*cancelPtr)
|
||||||
{
|
{
|
||||||
_Fail("Cancelled");
|
_Fail("Compilation cancelled");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4989,6 +5159,8 @@ bool CeMachine::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
|
||||||
|
|
||||||
void CeMachine::PrepareFunction(CeFunction* ceFunction, CeBuilder* parentBuilder)
|
void CeMachine::PrepareFunction(CeFunction* ceFunction, CeBuilder* parentBuilder)
|
||||||
{
|
{
|
||||||
|
AutoTimer autoTimer(mRevisionExecuteTime);
|
||||||
|
|
||||||
if (mHeap == NULL)
|
if (mHeap == NULL)
|
||||||
mHeap = new ContiguousHeap();
|
mHeap = new ContiguousHeap();
|
||||||
|
|
||||||
|
@ -5007,6 +5179,13 @@ void CeMachine::PrepareFunction(CeFunction* ceFunction, CeBuilder* parentBuilder
|
||||||
ceFunction->mFunctionKind = CeFunctionKind_GetReflectType;
|
ceFunction->mFunctionKind = CeFunctionKind_GetReflectType;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (owner->IsInstanceOf(mCeModule->mCompiler->mTypeTypeDef))
|
||||||
|
{
|
||||||
|
if (methodDef->mName == "ConstEval_GetTypeById")
|
||||||
|
{
|
||||||
|
ceFunction->mFunctionKind = CeFunctionKind_GetReflectTypeById;
|
||||||
|
}
|
||||||
|
}
|
||||||
else if (owner->IsInstanceOf(mCeModule->mCompiler->mDiagnosticsDebugTypeDef))
|
else if (owner->IsInstanceOf(mCeModule->mCompiler->mDiagnosticsDebugTypeDef))
|
||||||
{
|
{
|
||||||
if (methodDef->mName == "Write")
|
if (methodDef->mName == "Write")
|
||||||
|
@ -5017,6 +5196,11 @@ void CeMachine::PrepareFunction(CeFunction* ceFunction, CeBuilder* parentBuilder
|
||||||
ceFunction->mFunctionKind = CeFunctionKind_DebugWrite;
|
ceFunction->mFunctionKind = CeFunctionKind_DebugWrite;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (owner->IsInstanceOf(mCeModule->mCompiler->mThreadTypeDef))
|
||||||
|
{
|
||||||
|
if (methodDef->mName == "SleepInternal")
|
||||||
|
ceFunction->mFunctionKind = CeFunctionKind_Sleep;
|
||||||
|
}
|
||||||
else if (owner->IsInstanceOf(mCeModule->mCompiler->mInternalTypeDef))
|
else if (owner->IsInstanceOf(mCeModule->mCompiler->mInternalTypeDef))
|
||||||
{
|
{
|
||||||
if (methodDef->mName == "ThrowIndexOutOfRange")
|
if (methodDef->mName == "ThrowIndexOutOfRange")
|
||||||
|
@ -5063,7 +5247,7 @@ void CeMachine::PrepareFunction(CeFunction* ceFunction, CeBuilder* parentBuilder
|
||||||
ceBuilder.mCeFunction = ceFunction;
|
ceBuilder.mCeFunction = ceFunction;
|
||||||
ceBuilder.Build();
|
ceBuilder.Build();
|
||||||
|
|
||||||
if (!ceFunction->mCode.IsEmpty())
|
/*if (!ceFunction->mCode.IsEmpty())
|
||||||
{
|
{
|
||||||
CeDumpContext dumpCtx;
|
CeDumpContext dumpCtx;
|
||||||
dumpCtx.mCeFunction = ceFunction;
|
dumpCtx.mCeFunction = ceFunction;
|
||||||
|
@ -5073,6 +5257,14 @@ void CeMachine::PrepareFunction(CeFunction* ceFunction, CeBuilder* parentBuilder
|
||||||
dumpCtx.Dump();
|
dumpCtx.Dump();
|
||||||
|
|
||||||
OutputDebugStrF("Code for %s:\n%s\n", ceBuilder.mBeFunction->mName.c_str(), dumpCtx.mStr.c_str());
|
OutputDebugStrF("Code for %s:\n%s\n", ceBuilder.mBeFunction->mName.c_str(), dumpCtx.mStr.c_str());
|
||||||
|
}*/
|
||||||
|
}
|
||||||
|
|
||||||
|
void CeMachine::CheckFunctions()
|
||||||
|
{
|
||||||
|
for (auto kv : mFunctions)
|
||||||
|
{
|
||||||
|
BF_ASSERT((((intptr)(void*)kv.mKey->mMethodDef) & 0xFF) != 0xDD);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5084,6 +5276,8 @@ CeFunction* CeMachine::GetFunction(BfMethodInstance* methodInstance, BfIRValue f
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CheckFunctions();
|
||||||
|
|
||||||
CeFunctionInfo** functionInfoPtr = NULL;
|
CeFunctionInfo** functionInfoPtr = NULL;
|
||||||
CeFunctionInfo* ceFunctionInfo = NULL;
|
CeFunctionInfo* ceFunctionInfo = NULL;
|
||||||
CeFunction* ceFunction = NULL;
|
CeFunction* ceFunction = NULL;
|
||||||
|
@ -5093,6 +5287,11 @@ CeFunction* CeMachine::GetFunction(BfMethodInstance* methodInstance, BfIRValue f
|
||||||
BF_ASSERT(ceFunctionInfo->mCeFunction != NULL);
|
BF_ASSERT(ceFunctionInfo->mCeFunction != NULL);
|
||||||
return ceFunctionInfo->mCeFunction;
|
return ceFunctionInfo->mCeFunction;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BF_ASSERT(!methodInstance->mInCEMachine);
|
||||||
|
methodInstance->mInCEMachine = true;
|
||||||
|
|
||||||
|
BfLogSys(mCeModule->mSystem, "CeMachine::GetFunction %p\n", methodInstance);
|
||||||
|
|
||||||
if (!func)
|
if (!func)
|
||||||
{
|
{
|
||||||
|
@ -5130,8 +5329,7 @@ CeFunction* CeMachine::GetFunction(BfMethodInstance* methodInstance, BfIRValue f
|
||||||
added = true;
|
added = true;
|
||||||
auto module = methodInstance->GetOwner()->mModule;
|
auto module = methodInstance->GetOwner()->mModule;
|
||||||
|
|
||||||
BF_ASSERT(!methodInstance->mInCEMachine);
|
BF_ASSERT(ceFunctionInfo->mCeFunction == NULL);
|
||||||
methodInstance->mInCEMachine = true;
|
|
||||||
|
|
||||||
ceFunction = new CeFunction();
|
ceFunction = new CeFunction();
|
||||||
ceFunction->mCeFunctionInfo = ceFunctionInfo;
|
ceFunction->mCeFunctionInfo = ceFunctionInfo;
|
||||||
|
@ -5140,6 +5338,8 @@ CeFunction* CeMachine::GetFunction(BfMethodInstance* methodInstance, BfIRValue f
|
||||||
ceFunctionInfo->mMethodInstance = methodInstance;
|
ceFunctionInfo->mMethodInstance = methodInstance;
|
||||||
ceFunctionInfo->mCeFunction = ceFunction;
|
ceFunctionInfo->mCeFunction = ceFunction;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return ceFunction;
|
return ceFunction;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5188,14 +5388,24 @@ void CeMachine::ClearAppendAllocInfo()
|
||||||
}
|
}
|
||||||
|
|
||||||
BfTypedValue CeMachine::Call(BfAstNode* targetSrc, BfModule* module, BfMethodInstance* methodInstance, const BfSizedArray<BfIRValue>& args, CeEvalFlags flags, BfType* expectingType)
|
BfTypedValue CeMachine::Call(BfAstNode* targetSrc, BfModule* module, BfMethodInstance* methodInstance, const BfSizedArray<BfIRValue>& args, CeEvalFlags flags, BfType* expectingType)
|
||||||
{
|
{
|
||||||
|
AutoTimer autoTimer(mRevisionExecuteTime);
|
||||||
|
|
||||||
// DISABLED
|
// DISABLED
|
||||||
return BfTypedValue();
|
//return BfTypedValue();
|
||||||
|
|
||||||
|
SetAndRestoreValue<BfAstNode*> prevTargetSrc(mCurTargetSrc, targetSrc);
|
||||||
|
SetAndRestoreValue<BfModule*> prevModule(mCurModule, module);
|
||||||
|
SetAndRestoreValue<BfMethodInstance*> prevMethodInstance(mCurMethodInstance, methodInstance);
|
||||||
|
SetAndRestoreValue<BfType*> prevExpectingType(mCurExpectingType, expectingType);
|
||||||
|
|
||||||
if (mAppendAllocInfo != NULL)
|
if (mAppendAllocInfo != NULL)
|
||||||
{
|
{
|
||||||
if ((mAppendAllocInfo->mAppendSizeValue) && (!mAppendAllocInfo->mAppendSizeValue.IsConst()))
|
if ((mAppendAllocInfo->mAppendSizeValue) && (!mAppendAllocInfo->mAppendSizeValue.IsConst()))
|
||||||
|
{
|
||||||
|
Fail("Non-constant append alloc");
|
||||||
return BfTypedValue();
|
return BfTypedValue();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int thisArgIdx = -1;
|
int thisArgIdx = -1;
|
||||||
|
@ -5206,22 +5416,39 @@ BfTypedValue CeMachine::Call(BfAstNode* targetSrc, BfModule* module, BfMethodIns
|
||||||
thisArgIdx = 0;
|
thisArgIdx = 0;
|
||||||
if ((methodInstance->GetParamCount() >= 1) && (methodInstance->GetParamKind(0) == BfParamKind_AppendIdx))
|
if ((methodInstance->GetParamCount() >= 1) && (methodInstance->GetParamKind(0) == BfParamKind_AppendIdx))
|
||||||
appendAllocIdx = 1;
|
appendAllocIdx = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int argIdx = 0; argIdx < (int)args.size(); argIdx++)
|
int paramCompositeSize = 0;
|
||||||
|
int paramIdx = methodInstance->GetParamCount();
|
||||||
|
for (int argIdx = (int)args.size() - 1; argIdx >= 0; argIdx--)
|
||||||
{
|
{
|
||||||
|
BfType* paramType = NULL;
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
paramIdx--;
|
||||||
|
paramType = methodInstance->GetParamType(paramIdx);
|
||||||
|
if (paramType->IsTypedPrimitive())
|
||||||
|
paramType = paramType->GetUnderlyingType();
|
||||||
|
if (!paramType->IsValuelessType())
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (paramType->IsComposite())
|
||||||
|
{
|
||||||
|
auto paramTypeInst = paramType->ToTypeInstance();
|
||||||
|
paramCompositeSize += paramTypeInst->mInstSize;
|
||||||
|
}
|
||||||
|
|
||||||
auto arg = args[argIdx];
|
auto arg = args[argIdx];
|
||||||
if (!arg.IsConst())
|
if (!arg.IsConst())
|
||||||
{
|
{
|
||||||
if ((argIdx != thisArgIdx) && (argIdx != appendAllocIdx))
|
if ((argIdx != thisArgIdx) && (argIdx != appendAllocIdx))
|
||||||
|
{
|
||||||
|
Fail(StrFormat("Non-constant argument for param '%s'", methodInstance->GetParamName(paramIdx).c_str()));
|
||||||
return BfTypedValue();
|
return BfTypedValue();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SetAndRestoreValue<BfAstNode*> prevTargetSrc(mCurTargetSrc, targetSrc);
|
|
||||||
SetAndRestoreValue<BfModule*> prevModule(mCurModule, module);
|
|
||||||
SetAndRestoreValue<BfType*> prevExpectingType(mCurExpectingType, expectingType);
|
|
||||||
|
|
||||||
BF_ASSERT(mCallStack.IsEmpty());
|
BF_ASSERT(mCallStack.IsEmpty());
|
||||||
|
|
||||||
auto methodDef = methodInstance->mMethodDef;
|
auto methodDef = methodInstance->mMethodDef;
|
||||||
|
@ -5285,28 +5512,9 @@ BfTypedValue CeMachine::Call(BfAstNode* targetSrc, BfModule* module, BfMethodIns
|
||||||
memStart += memOffset;
|
memStart += memOffset;
|
||||||
stackPtr += memOffset;
|
stackPtr += memOffset;
|
||||||
};
|
};
|
||||||
|
|
||||||
addr_ce compositeStartAddr = stackPtr - memStart;
|
addr_ce compositeStartAddr = stackPtr - memStart;
|
||||||
int paramIdx = methodInstance->GetParamCount();
|
stackPtr -= paramCompositeSize;
|
||||||
for (int argIdx = (int)args.size() - 1; argIdx >= 0; argIdx--)
|
|
||||||
{
|
|
||||||
BfType* paramType = NULL;
|
|
||||||
while (true)
|
|
||||||
{
|
|
||||||
paramIdx--;
|
|
||||||
paramType = methodInstance->GetParamType(paramIdx);
|
|
||||||
if (paramType->IsTypedPrimitive())
|
|
||||||
paramType = paramType->GetUnderlyingType();
|
|
||||||
if (!paramType->IsValuelessType())
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (paramType->IsComposite())
|
|
||||||
{
|
|
||||||
auto paramTypeInst = paramType->ToTypeInstance();
|
|
||||||
stackPtr -= paramTypeInst->mInstSize;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
addr_ce useCompositeAddr = compositeStartAddr;
|
addr_ce useCompositeAddr = compositeStartAddr;
|
||||||
paramIdx = methodInstance->GetParamCount();
|
paramIdx = methodInstance->GetParamCount();
|
||||||
for (int argIdx = (int)args.size() - 1; argIdx >= 0; argIdx--)
|
for (int argIdx = (int)args.size() - 1; argIdx >= 0; argIdx--)
|
||||||
|
@ -5322,6 +5530,7 @@ BfTypedValue CeMachine::Call(BfAstNode* targetSrc, BfModule* module, BfMethodIns
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool isParams = methodInstance->GetParamKind(paramIdx) == BfParamKind_Params;
|
||||||
auto arg = args[argIdx];
|
auto arg = args[argIdx];
|
||||||
if (!arg.IsConst())
|
if (!arg.IsConst())
|
||||||
{
|
{
|
||||||
|
@ -5351,8 +5560,11 @@ BfTypedValue CeMachine::Call(BfAstNode* targetSrc, BfModule* module, BfMethodIns
|
||||||
{
|
{
|
||||||
auto paramTypeInst = paramType->ToTypeInstance();
|
auto paramTypeInst = paramType->ToTypeInstance();
|
||||||
useCompositeAddr -= paramTypeInst->mInstSize;
|
useCompositeAddr -= paramTypeInst->mInstSize;
|
||||||
if (!WriteConstant(module, useCompositeAddr, constant, paramType))
|
if (!WriteConstant(module, useCompositeAddr, constant, paramType, isParams))
|
||||||
|
{
|
||||||
|
Fail(StrFormat("Failed to process argument for param '%s'", methodInstance->GetParamName(paramIdx).c_str()));
|
||||||
return BfTypedValue();
|
return BfTypedValue();
|
||||||
|
}
|
||||||
_FixVariables();
|
_FixVariables();
|
||||||
|
|
||||||
stackPtr -= mCeModule->mSystem->mPtrSize;
|
stackPtr -= mCeModule->mSystem->mPtrSize;
|
||||||
|
@ -5362,8 +5574,11 @@ BfTypedValue CeMachine::Call(BfAstNode* targetSrc, BfModule* module, BfMethodIns
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
stackPtr -= paramType->mSize;
|
stackPtr -= paramType->mSize;
|
||||||
if (!WriteConstant(module, stackPtr - memStart, constant, paramType))
|
if (!WriteConstant(module, stackPtr - memStart, constant, paramType, isParams))
|
||||||
|
{
|
||||||
|
Fail(StrFormat("Failed to process argument for param '%s'", methodInstance->GetParamName(paramIdx).c_str()));
|
||||||
return BfTypedValue();
|
return BfTypedValue();
|
||||||
|
}
|
||||||
_FixVariables();
|
_FixVariables();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5405,6 +5620,10 @@ BfTypedValue CeMachine::Call(BfAstNode* targetSrc, BfModule* module, BfMethodIns
|
||||||
BfIRValue constVal = CreateConstant(module, retPtr, returnType, &usedReturnType);
|
BfIRValue constVal = CreateConstant(module, retPtr, returnType, &usedReturnType);
|
||||||
if (constVal)
|
if (constVal)
|
||||||
returnValue = BfTypedValue(constVal, usedReturnType);
|
returnValue = BfTypedValue(constVal, usedReturnType);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Fail("Failed to encode return argument");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -202,6 +202,8 @@ public:
|
||||||
mCeFunction = NULL;
|
mCeFunction = NULL;
|
||||||
mRefCount = 0;
|
mRefCount = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
~CeFunctionInfo();
|
||||||
};
|
};
|
||||||
|
|
||||||
class CeCallEntry
|
class CeCallEntry
|
||||||
|
@ -247,6 +249,8 @@ enum CeFunctionKind
|
||||||
CeFunctionKind_DebugWrite,
|
CeFunctionKind_DebugWrite,
|
||||||
CeFunctionKind_DebugWrite_Int,
|
CeFunctionKind_DebugWrite_Int,
|
||||||
CeFunctionKind_GetReflectType,
|
CeFunctionKind_GetReflectType,
|
||||||
|
CeFunctionKind_GetReflectTypeById,
|
||||||
|
CeFunctionKind_Sleep,
|
||||||
CeFunctionKind_Char32_ToLower,
|
CeFunctionKind_Char32_ToLower,
|
||||||
CeFunctionKind_Char32_ToUpper,
|
CeFunctionKind_Char32_ToUpper,
|
||||||
CeFunctionKind_Char32_IsLower,
|
CeFunctionKind_Char32_IsLower,
|
||||||
|
@ -595,7 +599,8 @@ public:
|
||||||
BfCompiler* mCompiler;
|
BfCompiler* mCompiler;
|
||||||
BfModule* mCeModule;
|
BfModule* mCeModule;
|
||||||
int mRevision;
|
int mRevision;
|
||||||
int mExecuteId;
|
int mRevisionExecuteTime;
|
||||||
|
int mExecuteId;
|
||||||
|
|
||||||
// These are only valid for the current execution
|
// These are only valid for the current execution
|
||||||
ContiguousHeap* mHeap;
|
ContiguousHeap* mHeap;
|
||||||
|
@ -610,6 +615,7 @@ public:
|
||||||
CeAppendAllocInfo* mAppendAllocInfo;
|
CeAppendAllocInfo* mAppendAllocInfo;
|
||||||
|
|
||||||
BfAstNode* mCurTargetSrc;
|
BfAstNode* mCurTargetSrc;
|
||||||
|
BfMethodInstance* mCurMethodInstance;
|
||||||
BfModule* mCurModule;
|
BfModule* mCurModule;
|
||||||
BfType* mCurExpectingType;
|
BfType* mCurExpectingType;
|
||||||
|
|
||||||
|
@ -623,6 +629,7 @@ public:
|
||||||
void Init();
|
void Init();
|
||||||
uint8* CeMalloc(int size);
|
uint8* CeMalloc(int size);
|
||||||
bool CeFree(addr_ce addr);
|
bool CeFree(addr_ce addr);
|
||||||
|
addr_ce CeAllocArray(BfArrayType* arrayType, int count, addr_ce& elemsAddr);
|
||||||
addr_ce GetReflectType(int typeId);
|
addr_ce GetReflectType(int typeId);
|
||||||
addr_ce GetString(int stringId);
|
addr_ce GetString(int stringId);
|
||||||
addr_ce GetConstantData(BeConstant* constant);
|
addr_ce GetConstantData(BeConstant* constant);
|
||||||
|
@ -633,13 +640,15 @@ public:
|
||||||
BeModule* GetBeModule();
|
BeModule* GetBeModule();
|
||||||
void DerefMethodInfo(CeFunctionInfo* ceFunctionInfo);
|
void DerefMethodInfo(CeFunctionInfo* ceFunctionInfo);
|
||||||
void RemoveMethod(BfMethodInstance* methodInstance);
|
void RemoveMethod(BfMethodInstance* methodInstance);
|
||||||
bool WriteConstant(BfModule* module, addr_ce addr, BfConstant* constant, BfType* type);
|
bool WriteConstant(BfModule* module, addr_ce addr, BfConstant* constant, BfType* type, bool isParams = false);
|
||||||
CeErrorKind WriteConstant(CeConstStructData& data, BeConstant* constVal);
|
CeErrorKind WriteConstant(CeConstStructData& data, BeConstant* constVal);
|
||||||
BfIRValue CreateConstant(BfModule* module, uint8* ptr, BfType* type, BfType** outType = NULL);
|
BfIRValue CreateConstant(BfModule* module, uint8* ptr, BfType* type, BfType** outType = NULL);
|
||||||
void CreateFunction(BfMethodInstance* methodInstance, CeFunction* ceFunction);
|
void CreateFunction(BfMethodInstance* methodInstance, CeFunction* ceFunction);
|
||||||
bool Execute(CeFunction* startFunction, uint8* startStackPtr, uint8* startFramePtr);
|
bool Execute(CeFunction* startFunction, uint8* startStackPtr, uint8* startFramePtr);
|
||||||
|
|
||||||
void PrepareFunction(CeFunction* methodInstance, CeBuilder* parentBuilder);
|
void PrepareFunction(CeFunction* methodInstance, CeBuilder* parentBuilder);
|
||||||
|
|
||||||
|
void CheckFunctions();
|
||||||
CeFunction* GetFunction(BfMethodInstance* methodInstance, BfIRValue func, bool& added);
|
CeFunction* GetFunction(BfMethodInstance* methodInstance, BfIRValue func, bool& added);
|
||||||
CeFunction* GetPreparedFunction(BfMethodInstance* methodInstance);
|
CeFunction* GetPreparedFunction(BfMethodInstance* methodInstance);
|
||||||
|
|
||||||
|
|
159
IDEHelper/Tests/src/ConstEval.bf
Normal file
159
IDEHelper/Tests/src/ConstEval.bf
Normal file
|
@ -0,0 +1,159 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Diagnostics;
|
||||||
|
|
||||||
|
namespace Tests
|
||||||
|
{
|
||||||
|
class ConstEval
|
||||||
|
{
|
||||||
|
struct StructA
|
||||||
|
{
|
||||||
|
public int32 mA;
|
||||||
|
public int32 mB;
|
||||||
|
|
||||||
|
public static int32 sVal = 1000;
|
||||||
|
|
||||||
|
public this(int32 a, int32 b)
|
||||||
|
{
|
||||||
|
mA = a + sVal;
|
||||||
|
mB = b;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const String cStrA = "Abc";
|
||||||
|
const String cStrB = GetStringA(cStrA, 12, 23);
|
||||||
|
|
||||||
|
[ConstEval]
|
||||||
|
static String GetStringA(String str, int a, int b)
|
||||||
|
{
|
||||||
|
// Const-eval functions can return scope-allocated data
|
||||||
|
return scope $"{str}:{a}:{b}";
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32 Factorial(int32 n)
|
||||||
|
{
|
||||||
|
return n <= 1 ? 1 : (n * Factorial(n - 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32 Fibonacci(int32 n)
|
||||||
|
{
|
||||||
|
return n <= 1 ? n : Fibonacci(n - 1) + Fibonacci(n - 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String GetTypeDesc<T>()
|
||||||
|
{
|
||||||
|
String str = scope .();
|
||||||
|
|
||||||
|
T val = default;
|
||||||
|
val.GetType().GetFullName(str);
|
||||||
|
str.Append(" ");
|
||||||
|
|
||||||
|
for (var fieldInfo in typeof(T).GetFields())
|
||||||
|
{
|
||||||
|
if (!fieldInfo.IsInstanceField)
|
||||||
|
continue;
|
||||||
|
if (@fieldInfo.Index > 0)
|
||||||
|
str.Append(", ");
|
||||||
|
fieldInfo.FieldType.GetFullName(str);
|
||||||
|
str.Append(" ");
|
||||||
|
str.Append(fieldInfo.Name);
|
||||||
|
}
|
||||||
|
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Span<int32> GetSorted(String numList)
|
||||||
|
{
|
||||||
|
List<int32> list = scope .();
|
||||||
|
for (var sv in numList.Split(','))
|
||||||
|
{
|
||||||
|
sv.Trim();
|
||||||
|
if (int32.Parse(sv) case .Ok(let val))
|
||||||
|
list.Add(val);
|
||||||
|
}
|
||||||
|
list.Sort();
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int32 MethodA()
|
||||||
|
{
|
||||||
|
mixin Add10(var a)
|
||||||
|
{
|
||||||
|
a += 10
|
||||||
|
}
|
||||||
|
|
||||||
|
int32 a = 1;
|
||||||
|
|
||||||
|
void Inc()
|
||||||
|
{
|
||||||
|
a++;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i < 2)
|
||||||
|
{
|
||||||
|
defer { a *= 2; }
|
||||||
|
Inc();
|
||||||
|
Add10!(a);
|
||||||
|
}
|
||||||
|
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
|
||||||
|
// This method can only be const evaluated
|
||||||
|
[ConstEval]
|
||||||
|
public static int32 ConstSum(params int32[] vals)
|
||||||
|
{
|
||||||
|
int32 sum = 0;
|
||||||
|
for (let val in vals)
|
||||||
|
sum += val;
|
||||||
|
return sum;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int32 MethodB()
|
||||||
|
{
|
||||||
|
// Returns different results depending on whether we are const-evaluating
|
||||||
|
return Compiler.IsConstEval ? 1 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int32 MethodC(StructA sa = .(1, 2), (int32, int32) tup = (20, 30), int32[2] arr = .(300, 400))
|
||||||
|
{
|
||||||
|
return sa.mA + sa.mB + tup.0 + tup.1 + arr[0] + arr[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public static void TestBasics()
|
||||||
|
{
|
||||||
|
const int fac = Factorial(8);
|
||||||
|
Test.Assert(fac == 40320);
|
||||||
|
const int fib = Fibonacci(27);
|
||||||
|
Test.Assert(fib == 196418);
|
||||||
|
|
||||||
|
// Generated string has reference equality to equivalent literal
|
||||||
|
Test.Assert(cStrB === "Abc:12:23");
|
||||||
|
|
||||||
|
const String strC = GetTypeDesc<StructA>();
|
||||||
|
Test.Assert(strC === "Tests.ConstEval.StructA int32 mA, int32 mB");
|
||||||
|
|
||||||
|
// Const Span<T> results can be used to initialize statically-sized arrays
|
||||||
|
const int32[?] iArr = GetSorted("8, 1, 3, 7");
|
||||||
|
Compiler.Assert(iArr == .(1, 3, 7, 8));
|
||||||
|
Test.Assert(iArr == .(1, 3, 7, 8));
|
||||||
|
|
||||||
|
let val0 = [ConstEval]MethodA();
|
||||||
|
Compiler.Assert(val0 == 70);
|
||||||
|
let val1 = MethodA();
|
||||||
|
// 'val1' is a read-only variable, but not const, so the following line would fail
|
||||||
|
//Compiler.Assert(val1 == 24);
|
||||||
|
Test.Assert(val1 == 70);
|
||||||
|
|
||||||
|
// This method is marked as ConstEval so it always evaluates as const
|
||||||
|
let val2 = ConstSum(3, 20, 100);
|
||||||
|
Compiler.Assert(val2 == 123);
|
||||||
|
|
||||||
|
Test.Assert(MethodB() == 0);
|
||||||
|
Test.Assert([ConstEval]MethodB() == 1);
|
||||||
|
|
||||||
|
Test.Assert(MethodC() == 1753);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue