mirror of
https://github.com/beefytech/Beef.git
synced 2025-06-08 03:28:20 +02:00
Comptime improvments, IOn<X> interfaces, const payload enum
This commit is contained in:
parent
e7fe91facb
commit
f37fb2c1b7
20 changed files with 884 additions and 364 deletions
|
@ -181,8 +181,8 @@ namespace Beefy
|
|||
}
|
||||
|
||||
int fileLen = (.)sr.Length;
|
||||
if (sr.TryRead(.((.)outBuffer.PrepareBuffer(fileLen), fileLen)) case .Err(let readErr))
|
||||
return .Err(.ReadError(readErr));
|
||||
if (sr.TryRead(.((.)outBuffer.PrepareBuffer(fileLen), fileLen)) case .Err)
|
||||
return .Err(.ReadError(.Unknown));
|
||||
|
||||
if (onPreFilter != null)
|
||||
onPreFilter();
|
||||
|
|
|
@ -540,6 +540,26 @@ namespace System
|
|||
}
|
||||
}
|
||||
|
||||
interface IOnTypeInit
|
||||
{
|
||||
void OnTypeInit(Type type, Self* prev) mut;
|
||||
}
|
||||
|
||||
interface IOnTypeDone
|
||||
{
|
||||
void OnTypeDone(Type type, Self* prev) mut;
|
||||
}
|
||||
|
||||
interface IOnFieldInit
|
||||
{
|
||||
void OnFieldInit(ComptimeFieldInfo type, Self* prev) mut;
|
||||
}
|
||||
|
||||
interface IOnMethodInit
|
||||
{
|
||||
void OnMethodInit(ComptimeMethodInfo type, Self* prev) mut;
|
||||
}
|
||||
|
||||
interface IComptimeTypeApply
|
||||
{
|
||||
void ApplyToType(Type type);
|
||||
|
|
|
@ -44,8 +44,8 @@ namespace System.IO
|
|||
if (bytes == 0)
|
||||
return .Ok;
|
||||
outData.AddRange(.(&buffer, bytes));
|
||||
case .Err(let err):
|
||||
return .Err(err);
|
||||
case .Err:
|
||||
return .Err(.Unknown);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -150,4 +150,31 @@ namespace System.Reflection
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Ordered]
|
||||
struct ComptimeFieldInfo
|
||||
{
|
||||
int64 mNativeFieldInstance;
|
||||
TypeId mOwner;
|
||||
TypeId mTypeId;
|
||||
int32 mFieldIdx;
|
||||
FieldFlags mFlags;
|
||||
|
||||
public StringView Name
|
||||
{
|
||||
get
|
||||
{
|
||||
if (Compiler.IsComptime)
|
||||
return Type.[Friend]Comptime_Field_GetName(mNativeFieldInstance);
|
||||
return "?";
|
||||
}
|
||||
}
|
||||
|
||||
public Type Owner => Type.[Friend]GetType_((.)mOwner);
|
||||
public Type FieldType => Type.[Friend]GetType_((.)mTypeId);
|
||||
public int FieldIdx => mFieldIdx;
|
||||
public bool IsConst => mFlags.HasFlag(.Const);
|
||||
public bool IsStatic => mFlags.HasFlag(.Static);
|
||||
public bool IsInstanceField => !mFlags.HasFlag(.Static) && !mFlags.HasFlag(.Const);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -159,6 +159,7 @@ namespace System
|
|||
.Int16,
|
||||
.Int32,
|
||||
.Int64,
|
||||
.Int,
|
||||
.Float,
|
||||
.Double:
|
||||
return true;
|
||||
|
@ -483,6 +484,15 @@ namespace System
|
|||
}
|
||||
}
|
||||
|
||||
public virtual int32 BitSize
|
||||
{
|
||||
[Error("This property can only be accessed directly from a typeof() expression")]
|
||||
get
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
public int32 GetTypeId()
|
||||
{
|
||||
return (int32)mTypeId;
|
||||
|
@ -497,6 +507,7 @@ namespace System
|
|||
static extern int64 Comptime_GetMethod(int32 typeId, int32 methodIdx);
|
||||
static extern String Comptime_Method_ToString(int64 methodHandle);
|
||||
static extern String Comptime_Method_GetName(int64 methodHandle);
|
||||
static extern String Comptime_Field_GetName(int64 fieldHandle);
|
||||
static extern ComptimeMethodInfo.Info Comptime_Method_GetInfo(int64 methodHandle);
|
||||
static extern ComptimeMethodInfo.ParamInfo Comptime_Method_GetParamInfo(int64 methodHandle, int32 paramIdx);
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
using System.Reflection;
|
||||
namespace System
|
||||
{
|
||||
public struct Attribute
|
||||
|
@ -495,6 +496,26 @@ namespace System
|
|||
}
|
||||
}
|
||||
|
||||
interface IOnTypeInit
|
||||
{
|
||||
void OnTypeInit(Type type, Self* prev) mut;
|
||||
}
|
||||
|
||||
interface IOnTypeDone
|
||||
{
|
||||
void OnTypeDone(Type type, Self* prev) mut;
|
||||
}
|
||||
|
||||
interface IOnFieldInit
|
||||
{
|
||||
void OnFieldInit(ComptimeFieldInfo type, Self* prev) mut;
|
||||
}
|
||||
|
||||
interface IOnMethodInit
|
||||
{
|
||||
void OnMethodInit(ComptimeMethodInfo type, Self* prev) mut;
|
||||
}
|
||||
|
||||
interface IComptimeTypeApply
|
||||
{
|
||||
void ApplyToType(Type type);
|
||||
|
|
|
@ -327,4 +327,18 @@ namespace System.Reflection
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct ComptimeMethodInfo
|
||||
{
|
||||
public int64 mNativeMethodInstance;
|
||||
}
|
||||
|
||||
struct ComptimeFieldInfo
|
||||
{
|
||||
int64 mNativeFieldInstance;
|
||||
TypeId mOwner;
|
||||
TypeId mTypeId;
|
||||
int32 mFieldIdx;
|
||||
FieldFlags mFlags;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -430,6 +430,11 @@ BfCompiler::BfCompiler(BfSystem* bfSystem, bool isResolveOnly)
|
|||
mIHashableTypeDef = NULL;
|
||||
mIComptimeTypeApply = NULL;
|
||||
mIComptimeMethodApply = NULL;
|
||||
mComptimeFieldInfoTypeDef = NULL;
|
||||
mIOnTypeInitTypeDef = NULL;
|
||||
mIOnTypeDoneTypeDef = NULL;
|
||||
mIOnFieldInitTypeDef = NULL;
|
||||
mIOnMethodInitTypeDef = NULL;
|
||||
mLinkNameAttributeTypeDef = NULL;
|
||||
mCallingConventionAttributeTypeDef = NULL;
|
||||
mMethodRefTypeDef = NULL;
|
||||
|
@ -5007,6 +5012,9 @@ void BfCompiler::GetSymbolReferences()
|
|||
|
||||
if ((fieldDef->mIsConst) && (fieldDef->mInitializer != NULL))
|
||||
{
|
||||
BfMethodState methodState;
|
||||
methodState.mTempKind = BfMethodState::TempKind_Static;
|
||||
SetAndRestoreValue<BfMethodState*> prevMethodState(module->mCurMethodState, &methodState);
|
||||
BfConstResolver constResolver(module);
|
||||
constResolver.Resolve(fieldDef->mInitializer);
|
||||
}
|
||||
|
@ -6825,6 +6833,12 @@ bool BfCompiler::DoCompile(const StringImpl& outputDirectory)
|
|||
mIHashableTypeDef = _GetRequiredType("System.IHashable");
|
||||
mIComptimeTypeApply = _GetRequiredType("System.IComptimeTypeApply");
|
||||
mIComptimeMethodApply = _GetRequiredType("System.IComptimeMethodApply");
|
||||
mComptimeFieldInfoTypeDef = _GetRequiredType("System.Reflection.ComptimeFieldInfo");
|
||||
mIOnTypeInitTypeDef = _GetRequiredType("System.IOnTypeInit");
|
||||
mIOnTypeDoneTypeDef = _GetRequiredType("System.IOnTypeDone");
|
||||
mIOnFieldInitTypeDef = _GetRequiredType("System.IOnFieldInit");
|
||||
mIOnMethodInitTypeDef = _GetRequiredType("System.IOnMethodInit");
|
||||
|
||||
mLinkNameAttributeTypeDef = _GetRequiredType("System.LinkNameAttribute");
|
||||
mCallingConventionAttributeTypeDef = _GetRequiredType("System.CallingConventionAttribute");
|
||||
mMethodRefTypeDef = _GetRequiredType("System.MethodReference", 1);
|
||||
|
|
|
@ -390,6 +390,11 @@ public:
|
|||
BfTypeDef* mIHashableTypeDef;
|
||||
BfTypeDef* mIComptimeTypeApply;
|
||||
BfTypeDef* mIComptimeMethodApply;
|
||||
BfTypeDef* mComptimeFieldInfoTypeDef;
|
||||
BfTypeDef* mIOnTypeInitTypeDef;
|
||||
BfTypeDef* mIOnTypeDoneTypeDef;
|
||||
BfTypeDef* mIOnFieldInitTypeDef;
|
||||
BfTypeDef* mIOnMethodInitTypeDef;
|
||||
|
||||
BfTypeDef* mMethodRefTypeDef;
|
||||
BfTypeDef* mNullableTypeDef;
|
||||
|
|
|
@ -1684,6 +1684,24 @@ void BfContext::DeleteType(BfType* type, bool deferDepRebuilds)
|
|||
|
||||
BfLogSysM("Deleting Type: %p %s\n", type, mScratchModule->TypeToString(type).c_str());
|
||||
|
||||
if (typeInst != NULL)
|
||||
{
|
||||
for (auto& methodInstGroup : typeInst->mMethodInstanceGroups)
|
||||
{
|
||||
if ((methodInstGroup.mDefault != NULL) && (methodInstGroup.mDefault->mInCEMachine))
|
||||
mCompiler->mCEMachine->RemoveMethod(methodInstGroup.mDefault);
|
||||
if (methodInstGroup.mMethodSpecializationMap != NULL)
|
||||
{
|
||||
for (auto& methodSpecializationItr : *methodInstGroup.mMethodSpecializationMap)
|
||||
{
|
||||
auto methodInstance = methodSpecializationItr.mValue;
|
||||
if (methodInstance->mInCEMachine)
|
||||
mCompiler->mCEMachine->RemoveMethod(methodInstance);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// All dependencies cause rebuilds when we delete types
|
||||
if (dType != NULL)
|
||||
{
|
||||
|
@ -1775,7 +1793,7 @@ void BfContext::DeleteType(BfType* type, bool deferDepRebuilds)
|
|||
|
||||
for (auto dependentType : rebuildTypeQueue)
|
||||
RebuildType(dependentType);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void BfContext::UpdateAfterDeletingTypes()
|
||||
|
|
|
@ -2296,26 +2296,8 @@ bool BfMethodMatcher::CheckMethod(BfTypeInstance* targetTypeInstance, BfTypeInst
|
|||
if (mModule->mCurMethodInstance != NULL)
|
||||
allowSpecializeFail = mModule->mCurMethodInstance->mIsUnspecialized;
|
||||
|
||||
// if (mModule->mModuleName == "BeefTest_TestProgram")
|
||||
// {
|
||||
// OutputDebugStrF("?Prv: %s\n %s\n?New: %s\n %s\n\n",
|
||||
// mModule->MethodToString(prevMethodInstance, BfMethodNameFlag_None, &mBestMethodGenericArguments).c_str(),
|
||||
// mModule->MethodToString(prevMethodInstance, BfMethodNameFlag_None).c_str(),
|
||||
// mModule->MethodToString(methodInstance, BfMethodNameFlag_None, genericArgumentsSubstitute).c_str(),
|
||||
// mModule->MethodToString(methodInstance, BfMethodNameFlag_None).c_str());
|
||||
// }
|
||||
|
||||
CompareMethods(prevMethodInstance, &mBestMethodGenericArguments, methodInstance, genericArgumentsSubstitute, &isBetter, &isWorse, allowSpecializeFail);
|
||||
|
||||
// if (mModule->mModuleName == "BeefTest_TestProgram")
|
||||
// {
|
||||
// OutputDebugStrF("%sPrv: %s\n %s\n%sNew: %s\n %s\n\n",
|
||||
// isWorse ? "*" : " ", mModule->MethodToString(prevMethodInstance, BfMethodNameFlag_None, &mBestMethodGenericArguments).c_str(),
|
||||
// mModule->MethodToString(prevMethodInstance, BfMethodNameFlag_None).c_str(),
|
||||
// isBetter ? "*" : " ", mModule->MethodToString(methodInstance, BfMethodNameFlag_None, genericArgumentsSubstitute).c_str(),
|
||||
// mModule->MethodToString(methodInstance, BfMethodNameFlag_None).c_str());
|
||||
// }
|
||||
|
||||
// If we had both a 'better' and 'worse', that's ambiguous because the methods are each better in different ways (not allowed)
|
||||
// And if neither better nor worse then they are equally good, which is not allowed either
|
||||
if (((!isBetter) && (!isWorse)) || ((isBetter) && (isWorse)))
|
||||
|
@ -7421,7 +7403,7 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, const BfTypedValu
|
|||
argValue = mModule->Cast(refNode, argValue, underlyingType);
|
||||
}
|
||||
else
|
||||
argValue = mModule->Cast(refNode, argValue, underlyingType);
|
||||
argValue = mModule->Cast(refNode, argValue, underlyingType, ((mBfEvalExprFlags & BfEvalExprFlags_Comptime) != 0) ? BfCastFlags_WantsConst : BfCastFlags_None);
|
||||
if (argValue)
|
||||
argValue = mModule->ToRef(argValue, (BfRefType*)wantType);
|
||||
}
|
||||
|
@ -7430,10 +7412,10 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, const BfTypedValu
|
|||
if (mModule->mCurMethodState != NULL)
|
||||
{
|
||||
SetAndRestoreValue<BfScopeData*> prevScopeData(mModule->mCurMethodState->mOverrideScope, boxScopeData);
|
||||
argValue = mModule->Cast(refNode, argValue, wantType);
|
||||
argValue = mModule->Cast(refNode, argValue, wantType, ((mBfEvalExprFlags & BfEvalExprFlags_Comptime) != 0) ? BfCastFlags_WantsConst : BfCastFlags_None);
|
||||
}
|
||||
else
|
||||
argValue = mModule->Cast(refNode, argValue, wantType);
|
||||
argValue = mModule->Cast(refNode, argValue, wantType, ((mBfEvalExprFlags & BfEvalExprFlags_Comptime) != 0) ? BfCastFlags_WantsConst : BfCastFlags_None);
|
||||
}
|
||||
|
||||
if (!argValue)
|
||||
|
@ -8145,10 +8127,8 @@ BfTypedValue BfExprEvaluator::CheckEnumCreation(BfAstNode* targetSrc, BfTypeInst
|
|||
constFailed = true;
|
||||
continue;
|
||||
}
|
||||
if (argValue.IsValuelessType())
|
||||
{
|
||||
if (resolvedFieldType->IsValuelessType())
|
||||
continue;
|
||||
}
|
||||
|
||||
// Used receiving value?
|
||||
if (argValue.mValue == receivingValue.mValue)
|
||||
|
@ -8167,7 +8147,7 @@ BfTypedValue BfExprEvaluator::CheckEnumCreation(BfAstNode* targetSrc, BfTypeInst
|
|||
{
|
||||
// argValue can have a value even if tuplePtr does not have a value. This can happen if we are assigning to a (void) tuple,
|
||||
// but we have a value that needs to be attempted to be casted to void
|
||||
argValue = mModule->Cast(argValues.mResolvedArgs[tupleFieldIdx].mExpression, argValue, resolvedFieldType);
|
||||
argValue = mModule->Cast(argValues.mResolvedArgs[tupleFieldIdx].mExpression, argValue, resolvedFieldType, wantConst ? BfCastFlags_WantsConst : BfCastFlags_None);
|
||||
if (wantConst)
|
||||
{
|
||||
if (!argValue.mValue.IsConst())
|
||||
|
@ -10777,9 +10757,55 @@ bool BfExprEvaluator::LookupTypeProp(BfTypeOfExpression* typeOfExpr, BfIdentifie
|
|||
}
|
||||
}
|
||||
}
|
||||
else if (memberName == "BitSize")
|
||||
{
|
||||
auto int32Type = mModule->GetPrimitiveType(BfTypeCode_Int32);
|
||||
|
||||
BfType* checkType = type;
|
||||
if (checkType->IsTypedPrimitive())
|
||||
checkType = checkType->GetUnderlyingType();
|
||||
|
||||
if (checkType->IsGenericParam())
|
||||
{
|
||||
mResult = mModule->GetDefaultTypedValue(int32Type, false, Beefy::BfDefaultValueKind_Undef);
|
||||
return true;
|
||||
}
|
||||
|
||||
if ((typeInstance != NULL) && (typeInstance->IsEnum()))
|
||||
{
|
||||
if (typeInstance->mTypeInfoEx != NULL)
|
||||
{
|
||||
int64 minValue = typeInstance->mTypeInfoEx->mMinValue;
|
||||
if (minValue < 0)
|
||||
minValue = ~minValue;
|
||||
int64 maxValue = typeInstance->mTypeInfoEx->mMaxValue;
|
||||
if (maxValue < 0)
|
||||
maxValue = ~maxValue;
|
||||
uint64 value = (uint64)minValue | (uint64)maxValue;
|
||||
|
||||
int bitCount = 1;
|
||||
if (typeInstance->mTypeInfoEx->mMinValue < 0)
|
||||
bitCount++;
|
||||
|
||||
while (value >>= 1)
|
||||
bitCount++;
|
||||
|
||||
mModule->AddDependency(typeInstance, mModule->mCurTypeInstance, BfDependencyMap::DependencyFlag_ReadFields);
|
||||
mResult = BfTypedValue(mModule->mBfIRBuilder->CreateConst(BfTypeCode_Int32, bitCount), int32Type);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
int bitSize = checkType->mSize * 8;
|
||||
if (checkType->GetTypeCode() == BfTypeCode_Boolean)
|
||||
bitSize = 1;
|
||||
mResult = BfTypedValue(mModule->mBfIRBuilder->CreateConst(BfTypeCode_Int32, bitSize), int32Type);
|
||||
return true;
|
||||
}
|
||||
else if ((memberName == "MinValue") || (memberName == "MaxValue"))
|
||||
{
|
||||
bool isMin = memberName == "MinValue";
|
||||
bool isBitSize = memberName == "BitSize";
|
||||
|
||||
BfType* checkType = type;
|
||||
if (checkType->IsTypedPrimitive())
|
||||
|
@ -10833,6 +10859,7 @@ bool BfExprEvaluator::LookupTypeProp(BfTypeOfExpression* typeOfExpr, BfIdentifie
|
|||
{
|
||||
if (typeInstance->mTypeInfoEx != NULL)
|
||||
{
|
||||
mModule->AddDependency(typeInstance, mModule->mCurTypeInstance, BfDependencyMap::DependencyFlag_ReadFields);
|
||||
mResult = BfTypedValue(mModule->mBfIRBuilder->CreateConst(primType->mTypeDef->mTypeCode, isMin ? (uint64)typeInstance->mTypeInfoEx->mMinValue : (uint64)typeInstance->mTypeInfoEx->mMaxValue), typeInstance);
|
||||
return true;
|
||||
}
|
||||
|
@ -20693,7 +20720,7 @@ void BfExprEvaluator::PerformUnaryOperation_OnResult(BfExpression* unaryOpExpr,
|
|||
else if (!CheckModifyResult(mResult, unaryOpExpr, "take address of", false, true))
|
||||
{
|
||||
if (!mResult.IsAddr())
|
||||
mResult = mModule->MakeAddressable(mResult);
|
||||
mResult = mModule->MakeAddressable(mResult, false, true);
|
||||
mResult = BfTypedValue(mResult.mValue, ptrType, false);
|
||||
}
|
||||
else
|
||||
|
@ -21409,7 +21436,9 @@ void BfExprEvaluator::PerformBinaryOperation(BfExpression* leftExpression, BfExp
|
|||
ResolveArgValues(argValues, BfResolveArgsFlag_DeferParamEval);
|
||||
|
||||
mResult = BfTypedValue(alloca, allocType, true);
|
||||
MatchConstructor(opToken, NULL, mResult, allocType, argValues, true, false);
|
||||
auto result = MatchConstructor(opToken, NULL, mResult, allocType, argValues, true, false);
|
||||
if ((result) && (!result.mType->IsVoid()))
|
||||
mResult = result;
|
||||
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -1001,13 +1001,23 @@ bool BfIRConstHolder::WriteConstant(BfIRValue val, void* ptr, BfType* type)
|
|||
return false;
|
||||
}
|
||||
|
||||
for (auto& fieldInstance : typeInst->mFieldInstances)
|
||||
if (typeInst->IsUnion())
|
||||
{
|
||||
if (fieldInstance.mDataOffset < 0)
|
||||
continue;
|
||||
if (!WriteConstant(aggConstant->mValues[fieldInstance.mDataIdx], (uint8*)ptr + fieldInstance.mDataOffset, fieldInstance.mResolvedType))
|
||||
auto innerType = typeInst->GetUnionInnerType();
|
||||
if (!WriteConstant(aggConstant->mValues[1], (uint8*)ptr, innerType))
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((!typeInst->IsUnion()) || (typeInst->IsPayloadEnum()))
|
||||
{
|
||||
for (auto& fieldInstance : typeInst->mFieldInstances)
|
||||
{
|
||||
if (fieldInstance.mDataOffset < 0)
|
||||
continue;
|
||||
if (!WriteConstant(aggConstant->mValues[fieldInstance.mDataIdx], (uint8*)ptr + fieldInstance.mDataOffset, fieldInstance.mResolvedType))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -1110,15 +1120,27 @@ BfIRValue BfIRConstHolder::ReadConstant(void* ptr, BfType* type)
|
|||
irValues.Add(val);
|
||||
}
|
||||
|
||||
for (auto& fieldInstance : typeInst->mFieldInstances)
|
||||
if (typeInst->IsUnion())
|
||||
{
|
||||
if (fieldInstance.mDataOffset < 0)
|
||||
continue;
|
||||
auto val = ReadConstant((uint8*)ptr + fieldInstance.mDataOffset, fieldInstance.mResolvedType);
|
||||
auto innerType = typeInst->GetUnionInnerType();
|
||||
auto val = ReadConstant(ptr, innerType);
|
||||
if (!val)
|
||||
return BfIRValue();
|
||||
irValues.Add(val);
|
||||
}
|
||||
|
||||
if ((!typeInst->IsUnion()) || (typeInst->IsPayloadEnum()))
|
||||
{
|
||||
for (auto& fieldInstance : typeInst->mFieldInstances)
|
||||
{
|
||||
if (fieldInstance.mDataOffset < 0)
|
||||
continue;
|
||||
auto val = ReadConstant((uint8*)ptr + fieldInstance.mDataOffset, fieldInstance.mResolvedType);
|
||||
if (!val)
|
||||
return BfIRValue();
|
||||
irValues.Add(val);
|
||||
}
|
||||
}
|
||||
BfIRType irType;
|
||||
irType.mKind = BfIRTypeData::TypeKind_TypeId;
|
||||
irType.mId = type->mTypeId;
|
||||
|
@ -1656,6 +1678,15 @@ String BfIRBuilder::ToString(BfIRValue irValue)
|
|||
{
|
||||
return ToString(constant->mIRType) + " zeroinitializer";
|
||||
}
|
||||
else if (constant->mConstType == BfConstType_AggCE)
|
||||
{
|
||||
auto constAgg = (BfConstantAggCE*)constant;
|
||||
return ToString(constAgg->mType) + StrFormat(" aggCe@%p", constAgg->mCEAddr);
|
||||
}
|
||||
else if (constant->mConstType == BfConstType_ArrayZero8)
|
||||
{
|
||||
return StrFormat("zero8[%d]", constant->mInt32);
|
||||
}
|
||||
else if (constant->mConstType == BfConstType_TypeOf)
|
||||
{
|
||||
auto typeofConst = (BfTypeOf_Const*)constant;
|
||||
|
@ -1666,6 +1697,7 @@ String BfIRBuilder::ToString(BfIRValue irValue)
|
|||
auto typeofConst = (BfTypeOf_WithData_Const*)constant;
|
||||
return "typeof_withData " + mModule->TypeToString(typeofConst->mType);
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
BF_FATAL("Unhandled");
|
||||
|
@ -1783,7 +1815,15 @@ String BfIRBuilder::ToString(BfIRType irType)
|
|||
}
|
||||
else if (irType.mKind == BfIRTypeData::TypeKind_TypeId)
|
||||
{
|
||||
return StrFormat("Type Id %d (%s)", irType.mId, mModule->TypeToString(mModule->mContext->mTypes[irType.mId]).c_str());
|
||||
return StrFormat("Type#%d:%s", irType.mId, mModule->TypeToString(mModule->mContext->mTypes[irType.mId]).c_str());
|
||||
}
|
||||
else if (irType.mKind == BfIRTypeData::TypeKind_TypeInstId)
|
||||
{
|
||||
return StrFormat("TypeInst#%d:%s", irType.mId, mModule->TypeToString(mModule->mContext->mTypes[irType.mId]).c_str());
|
||||
}
|
||||
else if (irType.mKind == BfIRTypeData::TypeKind_TypeInstPtrId)
|
||||
{
|
||||
return StrFormat("TypeInstPtr#%d:%s", irType.mId, mModule->TypeToString(mModule->mContext->mTypes[irType.mId]).c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -3940,7 +3980,7 @@ BfIRType BfIRBuilder::MapTypeInst(BfTypeInstance* typeInst, BfIRPopulateType pop
|
|||
PopulateType(typeInst, populateType);
|
||||
}
|
||||
|
||||
if (!mIgnoreWrites)
|
||||
if ((!mIgnoreWrites) && (populateType != BfIRPopulateType_Identity))
|
||||
BF_ASSERT(mTypeMap.ContainsKey(typeInst));
|
||||
BfIRType retType;
|
||||
retType.mKind = BfIRType::TypeKind_TypeInstId;
|
||||
|
|
|
@ -6477,19 +6477,7 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary<int, int>& usedStrin
|
|||
}
|
||||
}
|
||||
|
||||
SizedArray<BfIRValue, 16> fieldTypes;
|
||||
|
||||
enum FieldFlags
|
||||
{
|
||||
FieldFlags_Protected = 3,
|
||||
FieldFlags_Public = 6,
|
||||
FieldFlags_Static = 0x10,
|
||||
FieldFlags_Const = 0x40,
|
||||
FieldFlags_SpecialName = 0x80,
|
||||
FieldFlags_EnumPayload = 0x100,
|
||||
FieldFlags_EnumDiscriminator = 0x200,
|
||||
FieldFlags_EnumCase = 0x400
|
||||
};
|
||||
SizedArray<BfIRValue, 16> fieldTypes;
|
||||
|
||||
bool is32Bit = mCompiler->mSystem->mPtrSize == 4;
|
||||
|
||||
|
@ -6509,7 +6497,7 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary<int, int>& usedStrin
|
|||
GetConstValue(payloadType->mTypeId, typeIdType), // mFieldTypeId
|
||||
GetConstValue(0, intPtrType), // mData
|
||||
GetConstValue(0, intPtrType), // mDataHi
|
||||
GetConstValue(FieldFlags_SpecialName | FieldFlags_EnumPayload, shortType), // mFlags
|
||||
GetConstValue(BfFieldFlags_SpecialName | BfFieldFlags_EnumPayload, shortType), // mFlags
|
||||
GetConstValue(-1, intType), // mCustomAttributesIdx
|
||||
};
|
||||
}
|
||||
|
@ -6521,7 +6509,7 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary<int, int>& usedStrin
|
|||
payloadNameConst, // mName
|
||||
GetConstValue(payloadType->mTypeId, typeIdType), // mFieldTypeId
|
||||
GetConstValue(0, intPtrType), // mData
|
||||
GetConstValue(FieldFlags_SpecialName | FieldFlags_EnumPayload, shortType), // mFlags
|
||||
GetConstValue(BfFieldFlags_SpecialName | BfFieldFlags_EnumPayload, shortType), // mFlags
|
||||
GetConstValue(-1, intType), // mCustomAttributesIdx
|
||||
};
|
||||
}
|
||||
|
@ -6542,7 +6530,7 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary<int, int>& usedStrin
|
|||
GetConstValue(dscrType->mTypeId, typeIdType), // mFieldTypeId
|
||||
GetConstValue(BF_ALIGN(payloadType->mSize, dscrType->mAlign), intPtrType), // mData
|
||||
GetConstValue(0, intPtrType), // mDataHi
|
||||
GetConstValue(FieldFlags_SpecialName | FieldFlags_EnumDiscriminator, shortType), // mFlags
|
||||
GetConstValue(BfFieldFlags_SpecialName | BfFieldFlags_EnumDiscriminator, shortType), // mFlags
|
||||
GetConstValue(-1, intType), // mCustomAttributesIdx
|
||||
};
|
||||
}
|
||||
|
@ -6554,7 +6542,7 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary<int, int>& usedStrin
|
|||
dscrNameConst, // mName
|
||||
GetConstValue(dscrType->mTypeId, typeIdType), // mFieldTypeId
|
||||
GetConstValue(BF_ALIGN(payloadType->mSize, dscrType->mAlign), intPtrType), // mData
|
||||
GetConstValue(FieldFlags_SpecialName | FieldFlags_EnumDiscriminator, shortType), // mFlags
|
||||
GetConstValue(BfFieldFlags_SpecialName | BfFieldFlags_EnumDiscriminator, shortType), // mFlags
|
||||
GetConstValue(-1, intType), // mCustomAttributesIdx
|
||||
};
|
||||
}
|
||||
|
@ -6581,18 +6569,18 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary<int, int>& usedStrin
|
|||
else
|
||||
typeId = fieldType->mTypeId;
|
||||
|
||||
FieldFlags fieldFlags = (FieldFlags)0;
|
||||
BfFieldFlags fieldFlags = (BfFieldFlags)0;
|
||||
|
||||
if (fieldDef->mProtection == BfProtection_Protected)
|
||||
fieldFlags = (FieldFlags)(fieldFlags | FieldFlags_Protected);
|
||||
fieldFlags = (BfFieldFlags)(fieldFlags | BfFieldFlags_Protected);
|
||||
if (fieldDef->mProtection == BfProtection_Public)
|
||||
fieldFlags = (FieldFlags)(fieldFlags | FieldFlags_Public);
|
||||
fieldFlags = (BfFieldFlags)(fieldFlags | BfFieldFlags_Public);
|
||||
if (fieldDef->mIsStatic)
|
||||
fieldFlags = (FieldFlags)(fieldFlags | FieldFlags_Static);
|
||||
fieldFlags = (BfFieldFlags)(fieldFlags | BfFieldFlags_Static);
|
||||
if (fieldDef->mIsConst)
|
||||
fieldFlags = (FieldFlags)(fieldFlags | FieldFlags_Const);
|
||||
fieldFlags = (BfFieldFlags)(fieldFlags | BfFieldFlags_Const);
|
||||
if (fieldDef->IsEnumCaseEntry())
|
||||
fieldFlags = (FieldFlags)(fieldFlags | FieldFlags_EnumCase);
|
||||
fieldFlags = (BfFieldFlags)(fieldFlags | BfFieldFlags_EnumCase);
|
||||
|
||||
int customAttrIdx = _HandleCustomAttrs(fieldInstance->mCustomAttributes);
|
||||
BfIRValue constValue;
|
||||
|
@ -11319,7 +11307,7 @@ BfIRValue BfModule::ConstantToCurrent(BfConstant* constant, BfIRConstHolder* con
|
|||
{
|
||||
newVals.Add(ConstantToCurrent(constHolder->GetConstant(val), constHolder, elementType));
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
auto wantTypeInst = wantType->ToTypeInstance();
|
||||
|
@ -11329,19 +11317,32 @@ BfIRValue BfModule::ConstantToCurrent(BfConstant* constant, BfIRConstHolder* con
|
|||
newVals.Add(baseVal);
|
||||
}
|
||||
|
||||
for (auto& fieldInstance : wantTypeInst->mFieldInstances)
|
||||
if (wantType->IsUnion())
|
||||
{
|
||||
if (fieldInstance.mDataIdx < 0)
|
||||
continue;
|
||||
auto val = constArray->mValues[fieldInstance.mDataIdx];
|
||||
BfIRValue memberVal = ConstantToCurrent(constHolder->GetConstant(val), constHolder, fieldInstance.mResolvedType);
|
||||
if (fieldInstance.mDataIdx == newVals.mSize)
|
||||
newVals.Add(memberVal);
|
||||
else
|
||||
auto innerType = wantType->ToTypeInstance()->GetUnionInnerType();
|
||||
if (!innerType->IsValuelessType())
|
||||
{
|
||||
while (fieldInstance.mDataIdx >= newVals.mSize)
|
||||
newVals.Add(BfIRValue());
|
||||
newVals[fieldInstance.mDataIdx] = memberVal;
|
||||
auto val = ConstantToCurrent(constHolder->GetConstant(constArray->mValues[1]), constHolder, innerType);
|
||||
newVals.Add(val);
|
||||
}
|
||||
}
|
||||
|
||||
if ((!wantType->IsUnion()) || (wantType->IsPayloadEnum()))
|
||||
{
|
||||
for (auto& fieldInstance : wantTypeInst->mFieldInstances)
|
||||
{
|
||||
if (fieldInstance.mDataIdx < 0)
|
||||
continue;
|
||||
auto val = constArray->mValues[fieldInstance.mDataIdx];
|
||||
BfIRValue memberVal = ConstantToCurrent(constHolder->GetConstant(val), constHolder, fieldInstance.mResolvedType);
|
||||
if (fieldInstance.mDataIdx == newVals.mSize)
|
||||
newVals.Add(memberVal);
|
||||
else
|
||||
{
|
||||
while (fieldInstance.mDataIdx >= newVals.mSize)
|
||||
newVals.Add(BfIRValue());
|
||||
newVals[fieldInstance.mDataIdx] = memberVal;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -11539,7 +11540,7 @@ void BfModule::GetCustomAttributes(BfCustomAttributes* customAttributes, BfAttri
|
|||
BfConstResolver constResolver(this);
|
||||
if (allowNonConstArgs)
|
||||
constResolver.mBfEvalExprFlags = (BfEvalExprFlags)(constResolver.mBfEvalExprFlags | BfEvalExprFlags_AllowNonConst);
|
||||
|
||||
|
||||
bool inPropSet = false;
|
||||
SizedArray<BfResolvedArg, 2> argValues;
|
||||
for (BfExpression* arg : attributesDirective->mArguments)
|
||||
|
@ -11743,6 +11744,7 @@ void BfModule::GetCustomAttributes(BfCustomAttributes* customAttributes, BfAttri
|
|||
}
|
||||
|
||||
BfMethodMatcher methodMatcher(attributesDirective, this, "", argValues, BfMethodGenericArguments());
|
||||
methodMatcher.mBfEvalExprFlags = constResolver.mBfEvalExprFlags;
|
||||
attrTypeDef = attrTypeInst->mTypeDef;
|
||||
|
||||
bool success = true;
|
||||
|
@ -12969,6 +12971,7 @@ bool BfModule::IsCompatibleInterfaceMethod(BfMethodInstance* iMethodInst, BfMeth
|
|||
if (iMethodInst->GetParamCount() != methodInstance->GetParamCount())
|
||||
return false;
|
||||
|
||||
auto selfType = methodInstance->GetOwner();
|
||||
for (int paramIdx = 0; paramIdx < (int)iMethodInst->GetParamCount(); paramIdx++)
|
||||
{
|
||||
if (iMethodInst->GetParamKind(paramIdx) != methodInstance->GetParamKind(paramIdx))
|
||||
|
@ -12977,12 +12980,10 @@ bool BfModule::IsCompatibleInterfaceMethod(BfMethodInstance* iMethodInst, BfMeth
|
|||
BfType* iParamType = iMethodInst->GetParamType(paramIdx);
|
||||
BfType* methodParamType = methodInstance->GetParamType(paramIdx);
|
||||
|
||||
if (iParamType->IsSelf())
|
||||
{
|
||||
if (methodParamType != methodInstance->GetOwner())
|
||||
return false;
|
||||
}
|
||||
else if (!iParamType->IsGenericParam())
|
||||
iParamType = ResolveSelfType(iParamType, selfType);
|
||||
methodParamType = ResolveSelfType(methodParamType, selfType);
|
||||
|
||||
if (!iParamType->IsGenericParam())
|
||||
{
|
||||
if (methodParamType != iParamType)
|
||||
return false;
|
||||
|
@ -13730,6 +13731,9 @@ BfModuleMethodInstance BfModule::GetMethodInstance(BfTypeInstance* typeInst, BfM
|
|||
// We haven't processed it yet
|
||||
_SetReified();
|
||||
CheckHotMethod(methodInstance, "");
|
||||
|
||||
if (methodInstance->mMethodProcessRequest == NULL)
|
||||
AddMethodToWorkList(methodInstance);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -24120,28 +24124,27 @@ bool BfModule::SlotVirtualMethod(BfMethodInstance* methodInstance, BfAmbiguityCo
|
|||
if (iMethodInst->mMethodDef->mName == methodInstance->mMethodDef->mName)
|
||||
hadNameMatch = iMethodInst;
|
||||
|
||||
bool doesMethodSignatureMatch = CompareMethodSignatures(iMethodInst, methodInstance);
|
||||
|
||||
bool doesMethodSignatureMatch = CompareMethodSignatures(iMethodInst, methodInstance);
|
||||
if ((!doesMethodSignatureMatch) && (iMethodInst->GetNumGenericParams() == 0) && (interfaceMethodEntry->mMethodRef.IsNull()))
|
||||
{
|
||||
doesMethodSignatureMatch = IsCompatibleInterfaceMethod(iMethodInst, methodInstance);
|
||||
}
|
||||
|
||||
if ((doesMethodSignatureMatch) && (methodInstance->GetOwner()->IsValueType()))
|
||||
{
|
||||
if ((!iMethodInst->mMethodDef->mIsMutating) && (methodInstance->mMethodDef->mIsMutating))
|
||||
{
|
||||
if ((methodInstance->mMethodInfoEx != NULL) && (methodInstance->mMethodInfoEx->mExplicitInterface == ifaceInst))
|
||||
{
|
||||
auto error = mCompiler->mPassInstance->Fail(StrFormat("Implementation method '%s' cannot specify 'mut' because the interface method does not allow it",
|
||||
MethodToString(methodInstance).c_str()), methodInstance->mMethodDef->GetMutNode());
|
||||
if (error != NULL)
|
||||
mCompiler->mPassInstance->MoreInfo(StrFormat("Declare the interface method as 'mut' to allow matching 'mut' implementations"), iMethodInst->mMethodDef->mMethodDeclaration);
|
||||
showedError = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ((doesMethodSignatureMatch) && (methodInstance->GetOwner()->IsValueType()))
|
||||
{
|
||||
if ((!iMethodInst->mMethodDef->mIsMutating) && (methodInstance->mMethodDef->mIsMutating))
|
||||
{
|
||||
if ((methodInstance->mMethodInfoEx != NULL) && (methodInstance->mMethodInfoEx->mExplicitInterface == ifaceInst))
|
||||
{
|
||||
auto error = mCompiler->mPassInstance->Fail(StrFormat("Implementation method '%s' cannot specify 'mut' because the interface method does not allow it",
|
||||
MethodToString(methodInstance).c_str()), methodInstance->mMethodDef->GetMutNode());
|
||||
if (error != NULL)
|
||||
mCompiler->mPassInstance->MoreInfo(StrFormat("Declare the interface method as 'mut' to allow matching 'mut' implementations"), iMethodInst->mMethodDef->mMethodDeclaration);
|
||||
showedError = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (doesMethodSignatureMatch)
|
||||
{
|
||||
usedMethod = true;
|
||||
|
@ -24455,7 +24458,7 @@ void BfModule::DbgFinish()
|
|||
BfIRValue linkMarker;
|
||||
|
||||
if (mBfIRBuilder->DbgHasInfo())
|
||||
{
|
||||
{
|
||||
bool needForceLinking = false;
|
||||
for (auto& ownedType : mOwnedTypeInstances)
|
||||
{
|
||||
|
|
|
@ -102,7 +102,8 @@ enum BfCastFlags
|
|||
BfCastFlags_PreferAddr = 0x400,
|
||||
BfCastFlags_WarnOnBox = 0x800,
|
||||
BfCastFlags_IsCastCheck = 0x1000,
|
||||
BfCastFlags_IsConstraintCheck = 0x2000,
|
||||
BfCastFlags_IsConstraintCheck = 0x2000,
|
||||
BfCastFlags_WantsConst = 0x4000
|
||||
};
|
||||
|
||||
enum BfCastResultFlags
|
||||
|
@ -1762,7 +1763,7 @@ public:
|
|||
void FinishCEParseContext(BfAstNode* refNode, BfTypeInstance* typeInstance, BfCEParseContext* ceParseContext);
|
||||
BfCEParseContext CEEmitParse(BfTypeInstance* typeInstance, const StringImpl& src);
|
||||
void UpdateCEEmit(CeEmitContext* ceEmitContext, BfTypeInstance* typeInstance, const StringImpl& ctxString, BfAstNode* refNode);
|
||||
void HandleCEAttributes(CeEmitContext* ceEmitContext, BfTypeInstance* typeInst, BfCustomAttributes* customAttributes, HashSet<BfTypeInstance*> foundAttributes, bool underlyingTypeDeferred);
|
||||
void HandleCEAttributes(CeEmitContext* ceEmitContext, BfTypeInstance* typeInst, BfFieldInstance* fieldInstance, BfCustomAttributes* customAttributes, Dictionary<BfTypeInstance*, BfIRValue>& foundAttributes, bool underlyingTypeDeferred);
|
||||
void CEMixin(BfAstNode* refNode, const StringImpl& src);
|
||||
void ExecuteCEOnCompile(CeEmitContext* ceEmitContext, BfTypeInstance* typeInst, BfCEOnCompileKind onCompileKind, bool underlyingTypeDeferred);
|
||||
void DoCEEmit(BfTypeInstance* typeInstance, bool& hadNewMembers, bool underlyingTypeDeferred);
|
||||
|
|
|
@ -2139,96 +2139,181 @@ void BfModule::UpdateCEEmit(CeEmitContext* ceEmitContext, BfTypeInstance* typeIn
|
|||
}
|
||||
}
|
||||
|
||||
void BfModule::HandleCEAttributes(CeEmitContext* ceEmitContext, BfTypeInstance* typeInstance, BfCustomAttributes* customAttributes, HashSet<BfTypeInstance*> foundAttributes, bool underlyingTypeDeferred)
|
||||
void BfModule::HandleCEAttributes(CeEmitContext* ceEmitContext, BfTypeInstance* typeInstance, BfFieldInstance* fieldInstance, BfCustomAttributes* customAttributes, Dictionary<BfTypeInstance*, BfIRValue>& prevAttrInstances, bool underlyingTypeDeferred)
|
||||
{
|
||||
BfTypeInstance* iComptimeTypeApply = NULL;
|
||||
for (auto& customAttribute : customAttributes->mAttributes)
|
||||
{
|
||||
auto attrType = customAttribute.mType;
|
||||
mContext->mUnreifiedModule->PopulateType(attrType, BfPopulateType_DataAndMethods);
|
||||
if (attrType->mDefineState < BfTypeDefineState_DefinedAndMethodsSlotted)
|
||||
|
||||
BfMethodInstance* methodInstance = NULL;
|
||||
bool isFieldApply = false;
|
||||
BfIRValue irValue;
|
||||
int checkDepth = 0;
|
||||
auto checkAttrType = attrType;
|
||||
while (checkAttrType != NULL)
|
||||
{
|
||||
mContext->mUnreifiedModule->PopulateType(checkAttrType, BfPopulateType_DataAndMethods);
|
||||
if (checkAttrType->mDefineState < BfTypeDefineState_DefinedAndMethodsSlotted)
|
||||
break;
|
||||
|
||||
for (auto& ifaceEntry : checkAttrType->mInterfaces)
|
||||
{
|
||||
isFieldApply = false;
|
||||
isFieldApply = (ceEmitContext != NULL) && (ifaceEntry.mInterfaceType->IsInstanceOf(mCompiler->mIOnFieldInitTypeDef));
|
||||
|
||||
if ((isFieldApply) ||
|
||||
((ceEmitContext != NULL) && (ifaceEntry.mInterfaceType->IsInstanceOf(mCompiler->mIComptimeTypeApply))) ||
|
||||
((ceEmitContext != NULL) && (ifaceEntry.mInterfaceType->IsInstanceOf(mCompiler->mIOnTypeInitTypeDef))) ||
|
||||
((ceEmitContext == NULL) && (ifaceEntry.mInterfaceType->IsInstanceOf(mCompiler->mIOnTypeDoneTypeDef))))
|
||||
{
|
||||
// Passes
|
||||
}
|
||||
else
|
||||
continue;
|
||||
|
||||
prevAttrInstances.TryGetValue(checkAttrType, &irValue);
|
||||
methodInstance = checkAttrType->mInterfaceMethodTable[ifaceEntry.mStartInterfaceTableIdx].mMethodRef;
|
||||
break;
|
||||
}
|
||||
if (methodInstance != NULL)
|
||||
break;
|
||||
|
||||
checkAttrType = checkAttrType->mBaseType;
|
||||
checkDepth++;
|
||||
}
|
||||
|
||||
if (methodInstance == NULL)
|
||||
continue;
|
||||
|
||||
for (auto& ifaceEntry : attrType->mInterfaces)
|
||||
{
|
||||
if (iComptimeTypeApply == NULL)
|
||||
iComptimeTypeApply = ResolveTypeDef(mCompiler->mIComptimeTypeApply)->ToTypeInstance();
|
||||
if (ifaceEntry.mInterfaceType != iComptimeTypeApply)
|
||||
continue;
|
||||
|
||||
if (!foundAttributes.Add(attrType))
|
||||
continue;
|
||||
|
||||
BfMethodInstance* methodInstance = attrType->mInterfaceMethodTable[ifaceEntry.mStartInterfaceTableIdx].mMethodRef;
|
||||
if (methodInstance == NULL)
|
||||
continue;
|
||||
|
||||
SetAndRestoreValue<CeEmitContext*> prevEmitContext(mCompiler->mCEMachine->mCurEmitContext, ceEmitContext);
|
||||
auto ceContext = mCompiler->mCEMachine->AllocContext();
|
||||
SetAndRestoreValue<CeEmitContext*> prevEmitContext(mCompiler->mCEMachine->mCurEmitContext, ceEmitContext);
|
||||
auto ceContext = mCompiler->mCEMachine->AllocContext();
|
||||
|
||||
BfIRValue attrVal = ceContext->CreateAttribute(customAttribute.mRef, this, typeInstance->mConstHolder, &customAttribute);
|
||||
BfIRValue attrVal = ceContext->CreateAttribute(customAttribute.mRef, this, typeInstance->mConstHolder, &customAttribute);
|
||||
for (int baseIdx = 0; baseIdx < checkDepth; baseIdx++)
|
||||
attrVal = mBfIRBuilder->CreateExtractValue(attrVal, 0);
|
||||
|
||||
SizedArray<BfIRValue, 1> args;
|
||||
if (!attrType->IsValuelessType())
|
||||
args.Add(attrVal);
|
||||
SizedArray<BfIRValue, 1> args;
|
||||
if (!attrType->IsValuelessType())
|
||||
args.Add(attrVal);
|
||||
if (isFieldApply)
|
||||
{
|
||||
auto fieldDef = fieldInstance->GetFieldDef();
|
||||
BfFieldFlags fieldFlags = (BfFieldFlags)0;
|
||||
|
||||
if (fieldDef->mProtection == BfProtection_Protected)
|
||||
fieldFlags = (BfFieldFlags)(fieldFlags | BfFieldFlags_Protected);
|
||||
if (fieldDef->mProtection == BfProtection_Public)
|
||||
fieldFlags = (BfFieldFlags)(fieldFlags | BfFieldFlags_Public);
|
||||
if (fieldDef->mIsStatic)
|
||||
fieldFlags = (BfFieldFlags)(fieldFlags | BfFieldFlags_Static);
|
||||
if (fieldDef->mIsConst)
|
||||
fieldFlags = (BfFieldFlags)(fieldFlags | BfFieldFlags_Const);
|
||||
|
||||
auto fieldInfoType = ResolveTypeDef(mCompiler->mComptimeFieldInfoTypeDef);
|
||||
if (fieldInfoType != NULL)
|
||||
{
|
||||
SizedArray<BfIRValue, 9> fieldData =
|
||||
{
|
||||
mBfIRBuilder->CreateConstAggZero(mBfIRBuilder->MapType(fieldInfoType, BfIRPopulateType_Identity)),
|
||||
GetConstValue((uint64)(intptr)fieldInstance, GetPrimitiveType(BfTypeCode_Int64)), // mNativeFieldInstance
|
||||
GetConstValue(typeInstance->mTypeId, GetPrimitiveType(BfTypeCode_Int32)), // mOwner
|
||||
GetConstValue((fieldInstance->mResolvedType != NULL) ? fieldInstance->mResolvedType->mTypeId : 0, GetPrimitiveType(BfTypeCode_Int32)), // mTypeId
|
||||
GetConstValue(fieldDef->mIdx, GetPrimitiveType(BfTypeCode_Int32)), // mFieldIdx
|
||||
GetConstValue((int)fieldFlags, GetPrimitiveType(BfTypeCode_Int16)), // mFieldFlags
|
||||
};
|
||||
FixConstValueParams(fieldInfoType->ToTypeInstance(), fieldData);
|
||||
auto fieldDataAgg = mBfIRBuilder->CreateConstAgg(mBfIRBuilder->MapType(fieldInfoType, BfIRPopulateType_Identity), fieldData);
|
||||
args.Add(fieldDataAgg);
|
||||
}
|
||||
}
|
||||
else
|
||||
args.Add(mBfIRBuilder->CreateTypeOf(typeInstance));
|
||||
|
||||
DoPopulateType_CeCheckEnum(typeInstance, underlyingTypeDeferred);
|
||||
auto result = ceContext->Call(customAttribute.mRef, this, methodInstance, args, CeEvalFlags_None, NULL);
|
||||
|
||||
if (typeInstance->mDefineState == BfTypeDefineState_DefinedAndMethodsSlotted)
|
||||
return;
|
||||
|
||||
if (typeInstance->mDefineState != BfTypeDefineState_CETypeInit)
|
||||
{
|
||||
// We populated before we could finish
|
||||
AssertErrorState();
|
||||
}
|
||||
if (methodInstance->GetParamCount() > 1)
|
||||
{
|
||||
if (irValue)
|
||||
args.Add(irValue);
|
||||
else
|
||||
args.Add(mBfIRBuilder->CreateConstNull());
|
||||
}
|
||||
else
|
||||
{
|
||||
// Only allow a single instance
|
||||
if (irValue)
|
||||
continue;
|
||||
}
|
||||
|
||||
DoPopulateType_CeCheckEnum(typeInstance, underlyingTypeDeferred);
|
||||
if (fieldInstance != NULL)
|
||||
mCompiler->mCEMachine->mFieldInstanceSet.Add(fieldInstance);
|
||||
BfTypedValue result;
|
||||
///
|
||||
{
|
||||
SetAndRestoreValue<bool> prevIgnoreWrites(mBfIRBuilder->mIgnoreWrites, true);
|
||||
result = ceContext->Call(customAttribute.mRef, this, methodInstance, args, CeEvalFlags_ForceReturnThis, NULL);
|
||||
}
|
||||
if (fieldInstance != NULL)
|
||||
mCompiler->mCEMachine->mFieldInstanceSet.Remove(fieldInstance);
|
||||
if (result.mType == methodInstance->GetOwner())
|
||||
prevAttrInstances[methodInstance->GetOwner()] = result.mValue;
|
||||
|
||||
if (ceEmitContext == NULL)
|
||||
continue;
|
||||
|
||||
if (typeInstance->mDefineState == BfTypeDefineState_DefinedAndMethodsSlotted)
|
||||
return;
|
||||
|
||||
if (typeInstance->mDefineState != BfTypeDefineState_CETypeInit)
|
||||
{
|
||||
// We populated before we could finish
|
||||
AssertErrorState();
|
||||
}
|
||||
else
|
||||
{
|
||||
auto owner = methodInstance->GetOwner();
|
||||
int typeId = owner->mTypeId;
|
||||
if ((!result) && (mCompiler->mFastFinish))
|
||||
{
|
||||
auto owner = methodInstance->GetOwner();
|
||||
int typeId = owner->mTypeId;
|
||||
if ((!result) && (mCompiler->mFastFinish))
|
||||
if ((typeInstance->mCeTypeInfo != NULL) && (typeInstance->mCeTypeInfo->mNext == NULL))
|
||||
typeInstance->mCeTypeInfo->mNext = new BfCeTypeInfo();
|
||||
if ((typeInstance->mCeTypeInfo != NULL) && (typeInstance->mCeTypeInfo->mNext != NULL))
|
||||
typeInstance->mCeTypeInfo->mNext->mFailed = true;
|
||||
if (typeInstance->mCeTypeInfo != NULL)
|
||||
{
|
||||
if ((typeInstance->mCeTypeInfo != NULL) && (typeInstance->mCeTypeInfo->mNext == NULL))
|
||||
typeInstance->mCeTypeInfo->mNext = new BfCeTypeInfo();
|
||||
if ((typeInstance->mCeTypeInfo != NULL) && (typeInstance->mCeTypeInfo->mNext != NULL))
|
||||
typeInstance->mCeTypeInfo->mNext->mFailed = true;
|
||||
if (typeInstance->mCeTypeInfo != NULL)
|
||||
BfCeTypeEmitEntry* entry = NULL;
|
||||
if (typeInstance->mCeTypeInfo->mTypeIFaceMap.TryGetValue(typeId, &entry))
|
||||
{
|
||||
BfCeTypeEmitEntry* entry = NULL;
|
||||
if (typeInstance->mCeTypeInfo->mTypeIFaceMap.TryGetValue(typeId, &entry))
|
||||
{
|
||||
ceEmitContext->mEmitData = entry->mEmitData;
|
||||
}
|
||||
ceEmitContext->mEmitData = entry->mEmitData;
|
||||
}
|
||||
}
|
||||
else if (ceEmitContext->HasEmissions())
|
||||
{
|
||||
if (typeInstance->mCeTypeInfo == NULL)
|
||||
typeInstance->mCeTypeInfo = new BfCeTypeInfo();
|
||||
if (typeInstance->mCeTypeInfo->mNext == NULL)
|
||||
typeInstance->mCeTypeInfo->mNext = new BfCeTypeInfo();
|
||||
}
|
||||
else if (ceEmitContext->HasEmissions())
|
||||
{
|
||||
if (typeInstance->mCeTypeInfo == NULL)
|
||||
typeInstance->mCeTypeInfo = new BfCeTypeInfo();
|
||||
if (typeInstance->mCeTypeInfo->mNext == NULL)
|
||||
typeInstance->mCeTypeInfo->mNext = new BfCeTypeInfo();
|
||||
|
||||
BfCeTypeEmitEntry entry;
|
||||
entry.mEmitData = ceEmitContext->mEmitData;
|
||||
typeInstance->mCeTypeInfo->mNext->mTypeIFaceMap[typeId] = entry;
|
||||
}
|
||||
|
||||
if ((ceEmitContext->HasEmissions()) && (!mCompiler->mFastFinish))
|
||||
{
|
||||
String ctxStr = "comptime ApplyToType of ";
|
||||
ctxStr += TypeToString(attrType);
|
||||
ctxStr += " to ";
|
||||
ctxStr += TypeToString(typeInstance);
|
||||
ctxStr += " ";
|
||||
ctxStr += customAttribute.mRef->LocationToString();
|
||||
UpdateCEEmit(ceEmitContext, typeInstance, ctxStr, customAttribute.mRef);
|
||||
}
|
||||
BfCeTypeEmitEntry entry;
|
||||
entry.mEmitData = ceEmitContext->mEmitData;
|
||||
typeInstance->mCeTypeInfo->mNext->mTypeIFaceMap[typeId] = entry;
|
||||
}
|
||||
|
||||
mCompiler->mCEMachine->ReleaseContext(ceContext);
|
||||
if ((ceEmitContext->HasEmissions()) && (!mCompiler->mFastFinish))
|
||||
{
|
||||
String ctxStr = "comptime ";
|
||||
ctxStr += methodInstance->mMethodDef->mName;
|
||||
ctxStr += " of ";
|
||||
ctxStr += TypeToString(attrType);
|
||||
ctxStr += " to ";
|
||||
ctxStr += TypeToString(typeInstance);
|
||||
ctxStr += " ";
|
||||
ctxStr += customAttribute.mRef->LocationToString();
|
||||
UpdateCEEmit(ceEmitContext, typeInstance, ctxStr, customAttribute.mRef);
|
||||
}
|
||||
}
|
||||
|
||||
mCompiler->mCEMachine->ReleaseContext(ceContext);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2306,16 +2391,17 @@ void BfModule::CEMixin(BfAstNode* refNode, const StringImpl& code)
|
|||
|
||||
void BfModule::ExecuteCEOnCompile(CeEmitContext* ceEmitContext, BfTypeInstance* typeInstance, BfCEOnCompileKind onCompileKind, bool underlyingTypeDeferred)
|
||||
{
|
||||
HashSet<BfTypeInstance*> foundAttributes;
|
||||
Dictionary<BfTypeInstance*, BfIRValue> prevAttrInstances;
|
||||
|
||||
if (typeInstance->mCustomAttributes != NULL)
|
||||
HandleCEAttributes(ceEmitContext, typeInstance, NULL, typeInstance->mCustomAttributes, prevAttrInstances, underlyingTypeDeferred);
|
||||
|
||||
if (ceEmitContext != NULL)
|
||||
{
|
||||
if (typeInstance->mCustomAttributes != NULL)
|
||||
HandleCEAttributes(ceEmitContext, typeInstance, typeInstance->mCustomAttributes, foundAttributes, underlyingTypeDeferred);
|
||||
|
||||
for (auto& fieldInstance : typeInstance->mFieldInstances)
|
||||
{
|
||||
if (fieldInstance.mCustomAttributes != NULL)
|
||||
HandleCEAttributes(ceEmitContext, typeInstance, fieldInstance.mCustomAttributes, foundAttributes, underlyingTypeDeferred);
|
||||
HandleCEAttributes(ceEmitContext, typeInstance, &fieldInstance, fieldInstance.mCustomAttributes, prevAttrInstances, underlyingTypeDeferred);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2357,7 +2443,7 @@ void BfModule::ExecuteCEOnCompile(CeEmitContext* ceEmitContext, BfTypeInstance*
|
|||
if (onCompileAttribute == NULL)
|
||||
continue;
|
||||
|
||||
HandleCEAttributes(ceEmitContext, typeInstance, customAttributes, foundAttributes, underlyingTypeDeferred);
|
||||
HandleCEAttributes(ceEmitContext, typeInstance, NULL, customAttributes, prevAttrInstances, underlyingTypeDeferred);
|
||||
|
||||
if (onCompileAttribute->mCtorArgs.size() < 1)
|
||||
continue;
|
||||
|
@ -2477,114 +2563,155 @@ void BfModule::DoCEEmit(BfMethodInstance* methodInstance)
|
|||
|
||||
CeEmitContext ceEmitContext;
|
||||
ceEmitContext.mMethodInstance = methodInstance;
|
||||
|
||||
Dictionary<BfTypeInstance*, BfIRValue> prevAttrInstances;
|
||||
|
||||
BfTypeInstance* iComptimeMethodApply = NULL;
|
||||
for (auto& customAttribute : customAttributes->mAttributes)
|
||||
{
|
||||
auto attrType = customAttribute.mType;
|
||||
mContext->mUnreifiedModule->PopulateType(attrType, BfPopulateType_DataAndMethods);
|
||||
if (attrType->mDefineState < BfTypeDefineState_DefinedAndMethodsSlotted)
|
||||
continue;
|
||||
|
||||
BfMethodInstance* applyMethodInstance = NULL;
|
||||
BfIRValue irValue;
|
||||
int checkDepth = 0;
|
||||
auto checkAttrType = attrType;
|
||||
|
||||
for (auto& ifaceEntry : attrType->mInterfaces)
|
||||
while (checkAttrType != NULL)
|
||||
{
|
||||
if (iComptimeMethodApply == NULL)
|
||||
iComptimeMethodApply = ResolveTypeDef(mCompiler->mIComptimeMethodApply)->ToTypeInstance();
|
||||
if (ifaceEntry.mInterfaceType != iComptimeMethodApply)
|
||||
mContext->mUnreifiedModule->PopulateType(checkAttrType, BfPopulateType_DataAndMethods);
|
||||
if (checkAttrType->mDefineState < BfTypeDefineState_DefinedAndMethodsSlotted)
|
||||
break;
|
||||
|
||||
for (auto& ifaceEntry : checkAttrType->mInterfaces)
|
||||
{
|
||||
if ((!ifaceEntry.mInterfaceType->IsInstanceOf(mCompiler->mIComptimeMethodApply)) &&
|
||||
(!ifaceEntry.mInterfaceType->IsInstanceOf(mCompiler->mIOnMethodInitTypeDef)))
|
||||
continue;
|
||||
|
||||
prevAttrInstances.TryGetValue(checkAttrType, &irValue);
|
||||
applyMethodInstance = checkAttrType->mInterfaceMethodTable[ifaceEntry.mStartInterfaceTableIdx].mMethodRef;
|
||||
break;
|
||||
}
|
||||
|
||||
if (applyMethodInstance != NULL)
|
||||
break;
|
||||
|
||||
checkAttrType = checkAttrType->mBaseType;
|
||||
checkDepth++;
|
||||
}
|
||||
|
||||
if (applyMethodInstance == NULL)
|
||||
continue;
|
||||
|
||||
SetAndRestoreValue<CeEmitContext*> prevEmitContext(mCompiler->mCEMachine->mCurEmitContext, &ceEmitContext);
|
||||
auto ceContext = mCompiler->mCEMachine->AllocContext();
|
||||
|
||||
BfIRValue attrVal = ceContext->CreateAttribute(customAttribute.mRef, this, typeInstance->mConstHolder, &customAttribute);
|
||||
for (int baseIdx = 0; baseIdx < checkDepth; baseIdx++)
|
||||
attrVal = mBfIRBuilder->CreateExtractValue(attrVal, 0);
|
||||
|
||||
SizedArray<BfIRValue, 1> args;
|
||||
if (!attrType->IsValuelessType())
|
||||
args.Add(attrVal);
|
||||
args.Add(mBfIRBuilder->CreateConst(BfTypeCode_UInt64, (uint64)(intptr)methodInstance));
|
||||
if (applyMethodInstance->GetParamCount() > 1)
|
||||
{
|
||||
if (irValue)
|
||||
args.Add(irValue);
|
||||
else
|
||||
args.Add(mBfIRBuilder->CreateConstNull());
|
||||
}
|
||||
else
|
||||
{
|
||||
// Only allow a single instance
|
||||
if (irValue)
|
||||
continue;
|
||||
}
|
||||
|
||||
// if (!foundAttributes.Add(attrType))
|
||||
// continue;
|
||||
mCompiler->mCEMachine->mMethodInstanceSet.Add(methodInstance);
|
||||
|
||||
BfMethodInstance* applyMethodInstance = attrType->mInterfaceMethodTable[ifaceEntry.mStartInterfaceTableIdx].mMethodRef;
|
||||
if (applyMethodInstance == NULL)
|
||||
continue;
|
||||
|
||||
SetAndRestoreValue<CeEmitContext*> prevEmitContext(mCompiler->mCEMachine->mCurEmitContext, &ceEmitContext);
|
||||
auto ceContext = mCompiler->mCEMachine->AllocContext();
|
||||
|
||||
BfIRValue attrVal = ceContext->CreateAttribute(customAttribute.mRef, this, typeInstance->mConstHolder, &customAttribute);
|
||||
|
||||
SizedArray<BfIRValue, 1> args;
|
||||
if (!attrType->IsValuelessType())
|
||||
args.Add(attrVal);
|
||||
args.Add(mBfIRBuilder->CreateConst(BfTypeCode_UInt64, (uint64)(intptr)methodInstance));
|
||||
mCompiler->mCEMachine->mMethodInstanceSet.Add(methodInstance);
|
||||
|
||||
//TESTING
|
||||
//TESTING
|
||||
// mCompiler->mCEMachine->ReleaseContext(ceContext);
|
||||
// ceContext = mCompiler->mCEMachine->AllocContext();
|
||||
// ceContext->mMemory.mSize = ceContext->mMemory.mAllocSize;
|
||||
|
||||
|
||||
auto activeTypeDef = typeInstance->mTypeDef;
|
||||
auto result = ceContext->Call(customAttribute.mRef, this, applyMethodInstance, args, CeEvalFlags_None, NULL);
|
||||
auto activeTypeDef = typeInstance->mTypeDef;
|
||||
|
||||
//auto result = ceContext->Call(customAttribute.mRef, this, applyMethodInstance, args, CeEvalFlags_None, NULL);
|
||||
BfTypedValue result;
|
||||
///
|
||||
{
|
||||
SetAndRestoreValue<bool> prevIgnoreWrites(mBfIRBuilder->mIgnoreWrites, true);
|
||||
result = ceContext->Call(customAttribute.mRef, this, applyMethodInstance, args, CeEvalFlags_ForceReturnThis, NULL);
|
||||
}
|
||||
if (result.mType == methodInstance->GetOwner())
|
||||
prevAttrInstances[methodInstance->GetOwner()] = result.mValue;
|
||||
|
||||
if ((!result) && (mCompiler->mFastFinish))
|
||||
{
|
||||
methodInstance->mCeCancelled = true;
|
||||
}
|
||||
|
||||
if ((!ceEmitContext.mEmitData.IsEmpty()) || (!ceEmitContext.mExitEmitData.IsEmpty()))
|
||||
{
|
||||
String src;
|
||||
src += "// Code emission in comptime ApplyToMethod of ";
|
||||
src += TypeToString(attrType);
|
||||
src += " to ";
|
||||
src += MethodToString(methodInstance);
|
||||
src += " ";
|
||||
src += customAttribute.mRef->LocationToString();
|
||||
src += "\n";
|
||||
|
||||
//auto emitTypeDef = typeInstance->mCeTypeInfo->mNext->mTypeDef;
|
||||
//auto emitParser = emitTypeDef->mSource->ToParser();
|
||||
|
||||
//auto emitParser = activeTypeDef->mEmitParser;
|
||||
|
||||
BfReducer bfReducer;
|
||||
//bfReducer.mSource = emitParser;
|
||||
bfReducer.mPassInstance = mCompiler->mPassInstance;
|
||||
bfReducer.mSystem = mSystem;
|
||||
bfReducer.mCurTypeDecl = activeTypeDef->mTypeDeclaration;
|
||||
bfReducer.mCurMethodDecl = BfNodeDynCast<BfMethodDeclaration>(methodInstance->mMethodDef->mMethodDeclaration);
|
||||
|
||||
if (!ceEmitContext.mEmitData.IsEmpty())
|
||||
{
|
||||
SetAndRestoreValue<BfAstNode*> prevCustomAttribute(mCurMethodState->mEmitRefNode, customAttribute.mRef);
|
||||
|
||||
String entrySrc = src;
|
||||
if (mCurTypeInstance->mTypeDef->mEmitParent != NULL)
|
||||
entrySrc += "\n\n";
|
||||
entrySrc += src;
|
||||
entrySrc += ceEmitContext.mEmitData;
|
||||
BfCEParseContext ceParseContext = CEEmitParse(typeInstance, entrySrc);
|
||||
auto emitParser = mCurTypeInstance->mTypeDef->mSource->ToParser();
|
||||
bfReducer.mSource = emitParser;
|
||||
bfReducer.mAlloc = emitParser->mAlloc;
|
||||
bfReducer.HandleBlock(emitParser->mRootNode, false);
|
||||
Visit(emitParser->mRootNode);
|
||||
FinishCEParseContext(customAttribute.mRef, typeInstance, &ceParseContext);
|
||||
}
|
||||
|
||||
if (!ceEmitContext.mExitEmitData.IsEmpty())
|
||||
{
|
||||
String exitSrc;
|
||||
if (mCurTypeInstance->mTypeDef->mEmitParent != NULL)
|
||||
exitSrc += "\n\n";
|
||||
exitSrc += src;
|
||||
exitSrc += ceEmitContext.mExitEmitData;
|
||||
BfCEParseContext ceParseContext = CEEmitParse(typeInstance, exitSrc);
|
||||
auto emitParser = mCurTypeInstance->mTypeDef->mSource->ToParser();
|
||||
bfReducer.mSource = emitParser;
|
||||
bfReducer.mAlloc = emitParser->mAlloc;
|
||||
bfReducer.HandleBlock(emitParser->mRootNode, false);
|
||||
auto deferredBlock = AddDeferredBlock(emitParser->mRootNode, &mCurMethodState->mHeadScope);
|
||||
deferredBlock->mEmitRefNode = customAttribute.mRef;
|
||||
FinishCEParseContext(customAttribute.mRef, typeInstance, &ceParseContext);
|
||||
}
|
||||
}
|
||||
|
||||
mCompiler->mCEMachine->ReleaseContext(ceContext);
|
||||
if ((!result) && (mCompiler->mFastFinish))
|
||||
{
|
||||
methodInstance->mCeCancelled = true;
|
||||
}
|
||||
|
||||
if ((!ceEmitContext.mEmitData.IsEmpty()) || (!ceEmitContext.mExitEmitData.IsEmpty()))
|
||||
{
|
||||
String src;
|
||||
src += "// Code emission in comptime ApplyToMethod of ";
|
||||
src += TypeToString(attrType);
|
||||
src += " to ";
|
||||
src += MethodToString(methodInstance);
|
||||
src += " ";
|
||||
src += customAttribute.mRef->LocationToString();
|
||||
src += "\n";
|
||||
|
||||
//auto emitTypeDef = typeInstance->mCeTypeInfo->mNext->mTypeDef;
|
||||
//auto emitParser = emitTypeDef->mSource->ToParser();
|
||||
|
||||
//auto emitParser = activeTypeDef->mEmitParser;
|
||||
|
||||
BfReducer bfReducer;
|
||||
//bfReducer.mSource = emitParser;
|
||||
bfReducer.mPassInstance = mCompiler->mPassInstance;
|
||||
bfReducer.mSystem = mSystem;
|
||||
bfReducer.mCurTypeDecl = activeTypeDef->mTypeDeclaration;
|
||||
bfReducer.mCurMethodDecl = BfNodeDynCast<BfMethodDeclaration>(methodInstance->mMethodDef->mMethodDeclaration);
|
||||
|
||||
if (!ceEmitContext.mEmitData.IsEmpty())
|
||||
{
|
||||
SetAndRestoreValue<BfAstNode*> prevCustomAttribute(mCurMethodState->mEmitRefNode, customAttribute.mRef);
|
||||
|
||||
String entrySrc = src;
|
||||
if (mCurTypeInstance->mTypeDef->mEmitParent != NULL)
|
||||
entrySrc += "\n\n";
|
||||
entrySrc += src;
|
||||
entrySrc += ceEmitContext.mEmitData;
|
||||
BfCEParseContext ceParseContext = CEEmitParse(typeInstance, entrySrc);
|
||||
auto emitParser = mCurTypeInstance->mTypeDef->mSource->ToParser();
|
||||
bfReducer.mSource = emitParser;
|
||||
bfReducer.mAlloc = emitParser->mAlloc;
|
||||
bfReducer.HandleBlock(emitParser->mRootNode, false);
|
||||
Visit(emitParser->mRootNode);
|
||||
FinishCEParseContext(customAttribute.mRef, typeInstance, &ceParseContext);
|
||||
}
|
||||
|
||||
if (!ceEmitContext.mExitEmitData.IsEmpty())
|
||||
{
|
||||
String exitSrc;
|
||||
if (mCurTypeInstance->mTypeDef->mEmitParent != NULL)
|
||||
exitSrc += "\n\n";
|
||||
exitSrc += src;
|
||||
exitSrc += ceEmitContext.mExitEmitData;
|
||||
BfCEParseContext ceParseContext = CEEmitParse(typeInstance, exitSrc);
|
||||
auto emitParser = mCurTypeInstance->mTypeDef->mSource->ToParser();
|
||||
bfReducer.mSource = emitParser;
|
||||
bfReducer.mAlloc = emitParser->mAlloc;
|
||||
bfReducer.HandleBlock(emitParser->mRootNode, false);
|
||||
auto deferredBlock = AddDeferredBlock(emitParser->mRootNode, &mCurMethodState->mHeadScope);
|
||||
deferredBlock->mEmitRefNode = customAttribute.mRef;
|
||||
FinishCEParseContext(customAttribute.mRef, typeInstance, &ceParseContext);
|
||||
}
|
||||
}
|
||||
|
||||
mCompiler->mCEMachine->ReleaseContext(ceContext);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4183,15 +4310,46 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy
|
|||
if (!fieldInstance->mFieldIncluded)
|
||||
continue;
|
||||
|
||||
if (fieldInstance->mCustomAttributes != NULL)
|
||||
{
|
||||
// Already handled
|
||||
}
|
||||
else if ((fieldDef != NULL) && (fieldDef->mFieldDeclaration != NULL) && (fieldDef->mFieldDeclaration->mAttributes != NULL))
|
||||
{
|
||||
if (auto propDecl = BfNodeDynCast<BfPropertyDeclaration>(fieldDef->mFieldDeclaration))
|
||||
{
|
||||
// Handled elsewhere
|
||||
}
|
||||
else
|
||||
{
|
||||
BfTypeState typeState;
|
||||
typeState.mPrevState = mContext->mCurTypeState;
|
||||
typeState.mCurFieldDef = fieldDef;
|
||||
typeState.mCurTypeDef = fieldDef->mDeclaringType;
|
||||
typeState.mType = typeInstance;
|
||||
SetAndRestoreValue<BfTypeState*> prevTypeState(mContext->mCurTypeState, &typeState);
|
||||
|
||||
fieldInstance->mCustomAttributes = GetCustomAttributes(fieldDef->mFieldDeclaration->mAttributes, fieldDef->mIsStatic ? BfAttributeTargets_StaticField : BfAttributeTargets_Field);
|
||||
|
||||
for (auto customAttr : fieldInstance->mCustomAttributes->mAttributes)
|
||||
{
|
||||
if (TypeToString(customAttr.mType) == "System.ThreadStaticAttribute")
|
||||
{
|
||||
if ((!fieldDef->mIsStatic) || (fieldDef->mIsConst))
|
||||
{
|
||||
Fail("ThreadStatic attribute can only be used on static fields", fieldDef->mFieldDeclaration->mAttributes);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (resolvedFieldType == NULL)
|
||||
{
|
||||
if ((underlyingType != NULL) || (typeInstance->IsPayloadEnum()))
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!fieldInstance->mFieldIncluded)
|
||||
continue;
|
||||
|
||||
if (fieldDef == NULL)
|
||||
continue;
|
||||
|
||||
|
@ -4226,6 +4384,8 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
bool tryCE = true;
|
||||
|
@ -4473,38 +4633,7 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy
|
|||
AddDependency(resolvedFieldType, typeInstance, BfDependencyMap::DependencyFlag_StaticValue);
|
||||
}
|
||||
|
||||
auto fieldDef = fieldInstance->GetFieldDef();
|
||||
|
||||
BF_ASSERT(fieldInstance->mCustomAttributes == NULL);
|
||||
if ((fieldDef != NULL) && (fieldDef->mFieldDeclaration != NULL) && (fieldDef->mFieldDeclaration->mAttributes != NULL))
|
||||
{
|
||||
if (auto propDecl = BfNodeDynCast<BfPropertyDeclaration>(fieldDef->mFieldDeclaration))
|
||||
{
|
||||
// Handled elsewhere
|
||||
}
|
||||
else
|
||||
{
|
||||
BfTypeState typeState;
|
||||
typeState.mPrevState = mContext->mCurTypeState;
|
||||
typeState.mCurFieldDef = fieldDef;
|
||||
typeState.mCurTypeDef = fieldDef->mDeclaringType;
|
||||
typeState.mType = typeInstance;
|
||||
SetAndRestoreValue<BfTypeState*> prevTypeState(mContext->mCurTypeState, &typeState);
|
||||
|
||||
fieldInstance->mCustomAttributes = GetCustomAttributes(fieldDef->mFieldDeclaration->mAttributes, fieldDef->mIsStatic ? BfAttributeTargets_StaticField : BfAttributeTargets_Field);
|
||||
|
||||
for (auto customAttr : fieldInstance->mCustomAttributes->mAttributes)
|
||||
{
|
||||
if (TypeToString(customAttr.mType) == "System.ThreadStaticAttribute")
|
||||
{
|
||||
if ((!fieldDef->mIsStatic) || (fieldDef->mIsConst))
|
||||
{
|
||||
Fail("ThreadStatic attribute can only be used on static fields", fieldDef->mFieldDeclaration->mAttributes);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
auto fieldDef = fieldInstance->GetFieldDef();
|
||||
|
||||
if (fieldInstance->mResolvedType != NULL)
|
||||
{
|
||||
|
@ -12896,7 +13025,9 @@ BfIRValue BfModule::CastToValue(BfAstNode* srcNode, BfTypedValue typedVal, BfTyp
|
|||
{
|
||||
BfTypedValue result;
|
||||
BfExprEvaluator exprEvaluator(this);
|
||||
exprEvaluator.mBfEvalExprFlags = BfEvalExprFlags_FromConversionOp;
|
||||
exprEvaluator.mBfEvalExprFlags = BfEvalExprFlags_FromConversionOp;
|
||||
if ((castFlags & BfCastFlags_WantsConst) != 0)
|
||||
exprEvaluator.mBfEvalExprFlags = (BfEvalExprFlags)(exprEvaluator.mBfEvalExprFlags | BfEvalExprFlags_Comptime);
|
||||
|
||||
auto methodDeclaration = BfNodeDynCast<BfMethodDeclaration>(methodMatcher.mBestMethodDef->mMethodDeclaration);
|
||||
if ((methodDeclaration != NULL) && (methodDeclaration->mBody == NULL))
|
||||
|
|
|
@ -1383,9 +1383,11 @@ public:
|
|||
public:
|
||||
BfFieldDef* GetFieldDef();
|
||||
|
||||
BfFieldInstance(const BfFieldInstance& copyFrom)
|
||||
BfFieldInstance(BfFieldInstance&& copyFrom)
|
||||
{
|
||||
BF_ASSERT(copyFrom.mCustomAttributes == NULL);
|
||||
mCustomAttributes = copyFrom.mCustomAttributes;
|
||||
copyFrom.mCustomAttributes = NULL;
|
||||
|
||||
mOwner = copyFrom.mOwner;
|
||||
mResolvedType = copyFrom.mResolvedType;
|
||||
|
||||
|
@ -1404,6 +1406,28 @@ public:
|
|||
mLastRevisionReferenced = copyFrom.mLastRevisionReferenced;
|
||||
}
|
||||
|
||||
BfFieldInstance(const BfFieldInstance& copyFrom)
|
||||
{
|
||||
BF_ASSERT(copyFrom.mCustomAttributes == NULL);
|
||||
|
||||
mOwner = copyFrom.mOwner;
|
||||
mResolvedType = copyFrom.mResolvedType;
|
||||
|
||||
mCustomAttributes = copyFrom.mCustomAttributes;
|
||||
mConstIdx = copyFrom.mConstIdx;
|
||||
mFieldIdx = copyFrom.mFieldIdx;
|
||||
mDataIdx = copyFrom.mDataIdx;
|
||||
mMergedDataIdx = copyFrom.mMergedDataIdx;
|
||||
mDataOffset = copyFrom.mDataOffset;
|
||||
mDataSize = copyFrom.mDataSize;
|
||||
mFieldIncluded = copyFrom.mFieldIncluded;
|
||||
mIsEnumPayloadCase = copyFrom.mIsEnumPayloadCase;
|
||||
mIsThreadLocal = copyFrom.mIsThreadLocal;
|
||||
mIsInferredType = copyFrom.mIsInferredType;
|
||||
mHadConstEval = copyFrom.mHadConstEval;
|
||||
mLastRevisionReferenced = copyFrom.mLastRevisionReferenced;
|
||||
}
|
||||
|
||||
BfFieldInstance()
|
||||
{
|
||||
mFieldIdx = -1;
|
||||
|
|
|
@ -2981,7 +2981,7 @@ BfTypedValue BfModule::HandleCaseBind(BfTypedValue enumVal, const BfTypedValue&
|
|||
if (type->IsEnum())
|
||||
{
|
||||
auto enumType = (BfTypeInstance*)type;
|
||||
for (auto fieldInstance : enumType->mFieldInstances)
|
||||
for (auto& fieldInstance : enumType->mFieldInstances)
|
||||
{
|
||||
auto fieldDef = fieldInstance.GetFieldDef();
|
||||
if ((fieldDef != NULL) && (fieldDef->IsEnumCaseEntry()) && (fieldDef->mName == findName))
|
||||
|
|
|
@ -1471,6 +1471,18 @@ enum BfOptionFlags
|
|||
|
||||
};
|
||||
|
||||
enum BfFieldFlags
|
||||
{
|
||||
BfFieldFlags_Protected = 3,
|
||||
BfFieldFlags_Public = 6,
|
||||
BfFieldFlags_Static = 0x10,
|
||||
BfFieldFlags_Const = 0x40,
|
||||
BfFieldFlags_SpecialName = 0x80,
|
||||
BfFieldFlags_EnumPayload = 0x100,
|
||||
BfFieldFlags_EnumDiscriminator = 0x200,
|
||||
BfFieldFlags_EnumCase = 0x400
|
||||
};
|
||||
|
||||
enum BfReflectKind
|
||||
{
|
||||
BfReflectKind_None = 0,
|
||||
|
|
|
@ -3376,7 +3376,7 @@ void CeContext::PrepareConstStructEntry(CeConstStructData& constEntry)
|
|||
|
||||
bool CeContext::CheckMemory(addr_ce addr, int32 size)
|
||||
{
|
||||
if (((addr)-0x10000) + (size) > (mMemory.mSize - 0x10000))
|
||||
if ((addr < 0x10000) || (addr + size > mMemory.mSize))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
@ -3441,10 +3441,12 @@ bool CeContext::GetStringFromStringView(addr_ce addr, StringImpl& str)
|
|||
addr_ce charsPtr = *(addr_ce*)(mMemory.mVals + addr);
|
||||
int32 len = *(int32*)(mMemory.mVals + addr + ptrSize);
|
||||
|
||||
if (!CheckMemory(charsPtr, len))
|
||||
return false;
|
||||
|
||||
str.Append((const char*)(mMemory.mVals + charsPtr), len);
|
||||
if (len > 0)
|
||||
{
|
||||
if (!CheckMemory(charsPtr, len))
|
||||
return false;
|
||||
str.Append((const char*)(mMemory.mVals + charsPtr), len);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -3595,6 +3597,19 @@ bool CeContext::WriteConstant(BfModule* module, addr_ce addr, BfConstant* consta
|
|||
return false;
|
||||
}
|
||||
|
||||
if (typeInst->IsPayloadEnum())
|
||||
{
|
||||
auto innerType = typeInst->GetUnionInnerType();
|
||||
if (!innerType->IsValuelessType())
|
||||
{
|
||||
auto fieldConstant = module->mBfIRBuilder->GetConstant(aggConstant->mValues[1]);
|
||||
if (fieldConstant == NULL)
|
||||
return false;
|
||||
if (!WriteConstant(module, addr, fieldConstant, innerType))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
for (auto& fieldInstance : typeInst->mFieldInstances)
|
||||
{
|
||||
if (fieldInstance.mDataOffset < 0)
|
||||
|
@ -3611,9 +3626,15 @@ bool CeContext::WriteConstant(BfModule* module, addr_ce addr, BfConstant* consta
|
|||
}
|
||||
|
||||
if (constant->mConstType == BfConstType_AggZero)
|
||||
{
|
||||
{
|
||||
BF_ASSERT(type->IsComposite());
|
||||
memset(mMemory.mVals + addr, 0, type->mSize);
|
||||
memset(mMemory.mVals + addr, 0, type->mSize);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (constant->mConstType == BfConstType_ArrayZero8)
|
||||
{
|
||||
memset(mMemory.mVals + addr, 0, constant->mInt32);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -3722,6 +3743,29 @@ bool CeContext::WriteConstant(BfModule* module, addr_ce addr, BfConstant* consta
|
|||
return true;
|
||||
}
|
||||
|
||||
if (constant->mConstType == BfConstType_ExtractValue)
|
||||
{
|
||||
Array<BfConstantExtractValue*> extractStack;
|
||||
auto checkConstant = constant;
|
||||
while (true)
|
||||
{
|
||||
if (checkConstant == NULL)
|
||||
break;
|
||||
|
||||
if (checkConstant->mConstType == BfConstType_ExtractValue)
|
||||
{
|
||||
auto gepConst = (BfConstantExtractValue*)constant;
|
||||
BfIRValue targetConst(BfIRValueFlags_Const, gepConst->mTarget);
|
||||
checkConstant = module->mBfIRBuilder->GetConstant(targetConst);
|
||||
extractStack.Add(gepConst);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (checkConstant->mConstType == BfConstType_AggCE)
|
||||
return WriteConstant(module, addr, checkConstant, type, isParams);
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -3926,8 +3970,7 @@ BfIRValue CeContext::CreateConstant(BfModule* module, uint8* ptr, BfType* bfType
|
|||
|
||||
if (typeInst->IsInstanceOf(ceModule->mCompiler->mTypeTypeDef))
|
||||
{
|
||||
addr_ce addr = *(addr_ce*)(instData);
|
||||
int typeId = GetTypeIdFromType(addr);
|
||||
int typeId = GetTypeIdFromType(instData - mMemory.mVals);
|
||||
if (typeId <= 0)
|
||||
{
|
||||
Fail("Unable to locate return type type");
|
||||
|
@ -3950,13 +3993,20 @@ BfIRValue CeContext::CreateConstant(BfModule* module, uint8* ptr, BfType* bfType
|
|||
return BfIRValue();
|
||||
fieldVals.Add(result);
|
||||
}
|
||||
|
||||
if (typeInst->mIsUnion)
|
||||
|
||||
if (typeInst->IsUnion())
|
||||
{
|
||||
auto unionInnerType = typeInst->GetUnionInnerType();
|
||||
fieldVals.Add(CreateConstant(module, ptr, unionInnerType, outType));
|
||||
auto innerType = typeInst->GetUnionInnerType();
|
||||
if (!innerType->IsValuelessType())
|
||||
{
|
||||
auto result = CreateConstant(module, instData, innerType);
|
||||
if (!result)
|
||||
return BfIRValue();
|
||||
fieldVals.Add(result);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||
if ((!typeInst->IsUnion()) || (typeInst->IsPayloadEnum()))
|
||||
{
|
||||
for (int fieldIdx = 0; fieldIdx < typeInst->mFieldInstances.size(); fieldIdx++)
|
||||
{
|
||||
|
@ -3997,7 +4047,7 @@ BfIRValue CeContext::CreateConstant(BfModule* module, uint8* ptr, BfType* bfType
|
|||
fieldVal = irBuilder->CreateConstArrayZero(0);
|
||||
}
|
||||
|
||||
auto instResult = irBuilder->CreateConstAgg(irBuilder->MapTypeInst(typeInst, BfIRPopulateType_Full), fieldVals);
|
||||
auto instResult = irBuilder->CreateConstAgg(irBuilder->MapTypeInst(typeInst, BfIRPopulateType_Identity), fieldVals);
|
||||
return instResult;
|
||||
}
|
||||
|
||||
|
@ -4156,14 +4206,30 @@ BfTypedValue CeContext::Call(BfAstNode* targetSrc, BfModule* module, BfMethodIns
|
|||
int thisArgIdx = -1;
|
||||
int appendAllocIdx = -1;
|
||||
bool hasAggData = false;
|
||||
if (methodInstance->mMethodDef->mMethodType == BfMethodType_Ctor)
|
||||
if (!methodInstance->mMethodDef->mIsStatic)
|
||||
{
|
||||
if (!methodInstance->GetOwner()->IsValuelessType())
|
||||
{
|
||||
thisArgIdx = 0;
|
||||
auto constant = module->mBfIRBuilder->GetConstant(args[0]);
|
||||
if ((constant != NULL) && (constant->mConstType == BfConstType_AggCE))
|
||||
hasAggData = true;
|
||||
auto checkConstant = module->mBfIRBuilder->GetConstant(args[0]);
|
||||
while (checkConstant != NULL)
|
||||
{
|
||||
if ((checkConstant != NULL) && (checkConstant->mConstType == BfConstType_AggCE))
|
||||
{
|
||||
hasAggData = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (checkConstant->mConstType == BfConstType_ExtractValue)
|
||||
{
|
||||
auto gepConst = (BfConstantExtractValue*)checkConstant;
|
||||
BfIRValue targetConst(BfIRValueFlags_Const, gepConst->mTarget);
|
||||
checkConstant = module->mBfIRBuilder->GetConstant(targetConst);
|
||||
continue;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ((methodInstance->GetParamCount() >= 1) && (methodInstance->GetParamKind(0) == BfParamKind_AppendIdx))
|
||||
|
@ -4181,14 +4247,12 @@ BfTypedValue CeContext::Call(BfAstNode* targetSrc, BfModule* module, BfMethodIns
|
|||
paramType = methodInstance->GetParamType(paramIdx);
|
||||
if (paramType->IsTypedPrimitive())
|
||||
paramType = paramType->GetUnderlyingType();
|
||||
if (!paramType->IsValuelessType())
|
||||
if ((!paramType->IsValuelessType()) && (!paramType->IsVar()))
|
||||
break;
|
||||
}
|
||||
if (paramType->IsComposite())
|
||||
{
|
||||
paramCompositeSize += paramType->mSize;
|
||||
}
|
||||
|
||||
|
||||
BfType* compositeType = paramType->IsComposite() ? paramType : NULL;
|
||||
|
||||
auto arg = args[argIdx];
|
||||
bool isConst = arg.IsConst();
|
||||
if (isConst)
|
||||
|
@ -4203,6 +4267,17 @@ BfTypedValue CeContext::Call(BfAstNode* targetSrc, BfModule* module, BfMethodIns
|
|||
// else
|
||||
// isConst = false;
|
||||
}
|
||||
else if (((constant->mConstType == BfConstType_AggZero) || (constant->mConstType == BfConstType_Agg)) &&
|
||||
((paramType->IsPointer()) || (paramType->IsRef())))
|
||||
compositeType = paramType->GetUnderlyingType();
|
||||
}
|
||||
|
||||
if (compositeType != NULL)
|
||||
{
|
||||
if ((paramType->IsPointer()) || (paramType->IsRef()))
|
||||
paramCompositeSize += paramType->GetUnderlyingType()->mSize;
|
||||
else
|
||||
paramCompositeSize += paramType->mSize;
|
||||
}
|
||||
|
||||
if (!isConst)
|
||||
|
@ -4252,6 +4327,7 @@ BfTypedValue CeContext::Call(BfAstNode* targetSrc, BfModule* module, BfMethodIns
|
|||
BfTypeInstance* thisType = methodInstance->GetOwner();
|
||||
addr_ce allocThisInstAddr = 0;
|
||||
addr_ce allocThisAddr = 0;
|
||||
addr_ce thisAddr = 0;
|
||||
int allocThisSize = -1;
|
||||
|
||||
if ((thisArgIdx != -1) && (!hasAggData))
|
||||
|
@ -4294,6 +4370,7 @@ BfTypedValue CeContext::Call(BfAstNode* targetSrc, BfModule* module, BfMethodIns
|
|||
|
||||
allocThisInstAddr = allocThisPtr - memStart;
|
||||
allocThisAddr = allocThisInstAddr;
|
||||
thisAddr = allocThisAddr;
|
||||
}
|
||||
|
||||
addr_ce allocAppendIdxAddr = 0;
|
||||
|
@ -4327,7 +4404,7 @@ BfTypedValue CeContext::Call(BfAstNode* targetSrc, BfModule* module, BfMethodIns
|
|||
paramType = methodInstance->GetParamType(paramIdx);
|
||||
if (paramType->IsTypedPrimitive())
|
||||
paramType = paramType->GetUnderlyingType();
|
||||
if (!paramType->IsValuelessType())
|
||||
if ((!paramType->IsValuelessType()) && (!paramType->IsVar()))
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -4357,10 +4434,14 @@ BfTypedValue CeContext::Call(BfAstNode* targetSrc, BfModule* module, BfMethodIns
|
|||
}
|
||||
|
||||
auto constant = module->mBfIRBuilder->GetConstant(arg);
|
||||
if (paramType->IsComposite())
|
||||
BfType* compositeType = paramType->IsComposite() ? paramType : NULL;
|
||||
if (((constant->mConstType == BfConstType_AggZero) || (constant->mConstType == BfConstType_Agg)) &&
|
||||
((paramType->IsPointer()) || (paramType->IsRef())))
|
||||
compositeType = paramType->GetUnderlyingType();
|
||||
if (compositeType != NULL)
|
||||
{
|
||||
useCompositeAddr -= paramType->mSize;
|
||||
if (!WriteConstant(module, useCompositeAddr, constant, paramType, isParams))
|
||||
useCompositeAddr -= compositeType->mSize;
|
||||
if (!WriteConstant(module, useCompositeAddr, constant, compositeType, isParams))
|
||||
{
|
||||
Fail(StrFormat("Failed to process argument for param '%s'", methodInstance->GetParamName(paramIdx).c_str()));
|
||||
return BfTypedValue();
|
||||
|
@ -4369,17 +4450,47 @@ BfTypedValue CeContext::Call(BfAstNode* targetSrc, BfModule* module, BfMethodIns
|
|||
|
||||
stackPtr -= ceModule->mSystem->mPtrSize;
|
||||
int64 addr64 = useCompositeAddr;
|
||||
if (argIdx == thisArgIdx)
|
||||
thisAddr = addr64;
|
||||
memcpy(stackPtr, &addr64, ceModule->mSystem->mPtrSize);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
{
|
||||
stackPtr -= paramType->mSize;
|
||||
if (!WriteConstant(module, stackPtr - memStart, constant, paramType, isParams))
|
||||
auto useCompositeAddr = stackPtr - memStart;
|
||||
if (!WriteConstant(module, useCompositeAddr, constant, paramType, isParams))
|
||||
{
|
||||
Fail(StrFormat("Failed to process argument for param '%s'", methodInstance->GetParamName(paramIdx).c_str()));
|
||||
return BfTypedValue();
|
||||
}
|
||||
_FixVariables();
|
||||
|
||||
if (argIdx == thisArgIdx)
|
||||
{
|
||||
auto checkConstant = constant;
|
||||
while (checkConstant != NULL)
|
||||
{
|
||||
if ((checkConstant != NULL) && (checkConstant->mConstType == BfConstType_AggCE))
|
||||
{
|
||||
auto constAggData = (BfConstantAggCE*)checkConstant;
|
||||
if (paramType->IsPointer())
|
||||
thisAddr = constAggData->mCEAddr;
|
||||
else
|
||||
thisAddr = useCompositeAddr;
|
||||
break;
|
||||
}
|
||||
|
||||
if (checkConstant->mConstType == BfConstType_ExtractValue)
|
||||
{
|
||||
auto gepConst = (BfConstantExtractValue*)checkConstant;
|
||||
BfIRValue targetConst(BfIRValueFlags_Const, gepConst->mTarget);
|
||||
checkConstant = module->mBfIRBuilder->GetConstant(targetConst);
|
||||
continue;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4399,16 +4510,18 @@ BfTypedValue CeContext::Call(BfAstNode* targetSrc, BfModule* module, BfMethodIns
|
|||
|
||||
addr_ce retInstAddr = retAddr;
|
||||
|
||||
if (returnType->IsInstanceOf(mCeMachine->mCompiler->mTypeTypeDef))
|
||||
{
|
||||
// Allow
|
||||
}
|
||||
else if ((returnType->IsObject()) || (returnType->IsPointer()))
|
||||
if ((returnType->IsObject()) || (returnType->IsPointer()))
|
||||
{
|
||||
// Or pointer?
|
||||
retInstAddr = *(addr_ce*)(memStart + retAddr);
|
||||
}
|
||||
|
||||
if ((flags & CeEvalFlags_ForceReturnThis) != 0)
|
||||
{
|
||||
returnType = thisType;
|
||||
retInstAddr = thisAddr;
|
||||
}
|
||||
|
||||
BfTypedValue returnValue;
|
||||
|
||||
if (success)
|
||||
|
@ -4452,7 +4565,7 @@ BfTypedValue CeContext::Call(BfAstNode* targetSrc, BfModule* module, BfMethodIns
|
|||
}
|
||||
else if (returnType->IsComposite())
|
||||
{
|
||||
returnValue = BfTypedValue(module->mBfIRBuilder->CreateConstArrayZero(module->mBfIRBuilder->MapType(returnType)), returnType);
|
||||
returnValue = BfTypedValue(module->mBfIRBuilder->CreateConstAggZero(module->mBfIRBuilder->MapType(returnType, BfIRPopulateType_Identity)), returnType);
|
||||
}
|
||||
else if (returnType->IsValuelessType())
|
||||
{
|
||||
|
@ -4462,6 +4575,8 @@ BfTypedValue CeContext::Call(BfAstNode* targetSrc, BfModule* module, BfMethodIns
|
|||
|
||||
mCallStack.Clear();
|
||||
|
||||
moduleCurMethodInstance.Restore();
|
||||
moduleCurTypeInstance.Restore();
|
||||
module->AddDependency(methodInstance->GetOwner(), module->mCurTypeInstance, BfDependencyMap::DependencyFlag_ConstEval);
|
||||
|
||||
return returnValue;
|
||||
|
@ -5014,6 +5129,20 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
|
|||
*(int16*)(stackPtr + 4) = 0; // Flags
|
||||
CeSetAddrVal(stackPtr + 4+2, stringAddr, ptrSize);
|
||||
}
|
||||
else if (checkFunction->mFunctionKind == CeFunctionKind_Field_GetName)
|
||||
{
|
||||
int64 fieldHandle = *(int64*)((uint8*)stackPtr + ptrSize);
|
||||
|
||||
auto fieldInstance = mCeMachine->GetFieldInstance(fieldHandle);
|
||||
if (fieldInstance == NULL)
|
||||
{
|
||||
_Fail("Invalid field instance");
|
||||
return false;
|
||||
}
|
||||
|
||||
CeSetAddrVal(stackPtr + 0, GetString(fieldInstance->GetFieldDef()->mName), ptrSize);
|
||||
_FixVariables();
|
||||
}
|
||||
else if (checkFunction->mFunctionKind == CeFunctionKind_EmitTypeBody)
|
||||
{
|
||||
int32 typeId = *(int32*)((uint8*)stackPtr);
|
||||
|
@ -7506,6 +7635,12 @@ void CeMachine::DerefMethodInfo(CeFunctionInfo* ceFunctionInfo)
|
|||
delete ceFunctionInfo;
|
||||
}
|
||||
|
||||
void CeMachine::RemoveFunc(CeFunction* ceFunction)
|
||||
{
|
||||
mFunctionIdMap.Remove(ceFunction->mId);
|
||||
ceFunction->mId = -1;
|
||||
}
|
||||
|
||||
void CeMachine::RemoveMethod(BfMethodInstance* methodInstance)
|
||||
{
|
||||
BfLogSys(methodInstance->GetOwner()->mModule->mSystem, "CeMachine::RemoveMethod %p\n", methodInstance);
|
||||
|
@ -7527,13 +7662,9 @@ void CeMachine::RemoveMethod(BfMethodInstance* methodInstance)
|
|||
}
|
||||
if (ceFunction->mId != -1)
|
||||
{
|
||||
mFunctionIdMap.Remove(ceFunction->mId);
|
||||
ceFunction->mId = -1;
|
||||
RemoveFunc(ceFunction);
|
||||
for (auto innerFunction : ceFunction->mInnerFunctions)
|
||||
{
|
||||
mFunctionIdMap.Remove(innerFunction->mId);
|
||||
innerFunction->mId = -1;
|
||||
}
|
||||
RemoveFunc(innerFunction);
|
||||
}
|
||||
|
||||
delete ceFunction;
|
||||
|
@ -7555,6 +7686,7 @@ void CeMachine::RemoveMethod(BfMethodInstance* methodInstance)
|
|||
|
||||
mFunctions.Remove(itr);
|
||||
}
|
||||
methodInstance->mInCEMachine = false;
|
||||
}
|
||||
|
||||
CeErrorKind CeMachine::WriteConstant(CeConstStructData& data, BeConstant* constVal, CeContext* ceContext)
|
||||
|
@ -7865,6 +7997,10 @@ void CeMachine::CheckFunctionKind(CeFunction* ceFunction)
|
|||
{
|
||||
ceFunction->mFunctionKind = CeFunctionKind_Method_GetParamInfo;
|
||||
}
|
||||
else if (methodDef->mName == "Comptime_Field_GetName")
|
||||
{
|
||||
ceFunction->mFunctionKind = CeFunctionKind_Field_GetName;
|
||||
}
|
||||
}
|
||||
else if (owner->IsInstanceOf(mCeModule->mCompiler->mCompilerTypeDef))
|
||||
{
|
||||
|
@ -8208,7 +8344,7 @@ CeFunction* CeMachine::GetFunction(BfMethodInstance* methodInstance, BfIRValue f
|
|||
ceFunction->mCeMachine = this;
|
||||
ceFunction->mIsVarReturn = methodInstance->mReturnType->IsVar();
|
||||
ceFunction->mCeFunctionInfo = ceFunctionInfo;
|
||||
ceFunction->mMethodInstance = methodInstance;
|
||||
ceFunction->mMethodInstance = methodInstance;
|
||||
ceFunctionInfo->mMethodInstance = methodInstance;
|
||||
ceFunctionInfo->mCeFunction = ceFunction;
|
||||
MapFunctionId(ceFunction);
|
||||
|
@ -8283,6 +8419,14 @@ BfMethodInstance* CeMachine::GetMethodInstance(int64 methodHandle)
|
|||
return methodInstance;
|
||||
}
|
||||
|
||||
BfFieldInstance* CeMachine::GetFieldInstance(int64 fieldHandle)
|
||||
{
|
||||
BfFieldInstance* fieldInstance = (BfFieldInstance*)(intptr)fieldHandle;
|
||||
if (!mFieldInstanceSet.Contains(fieldInstance))
|
||||
return NULL;
|
||||
return fieldInstance;
|
||||
}
|
||||
|
||||
CeFunction* CeMachine::QueueMethod(BfMethodInstance* methodInstance, BfIRValue func)
|
||||
{
|
||||
if (mPreparingFunction != NULL)
|
||||
|
@ -8369,7 +8513,7 @@ void CeMachine::ReleaseContext(CeContext* ceContext)
|
|||
BfTypedValue CeMachine::Call(BfAstNode* targetSrc, BfModule* module, BfMethodInstance* methodInstance, const BfSizedArray<BfIRValue>& args, CeEvalFlags flags, BfType* expectingType)
|
||||
{
|
||||
auto ceContext = AllocContext();
|
||||
auto result = ceContext->Call(targetSrc, module, methodInstance, args, flags, expectingType);
|
||||
auto result = ceContext->Call(targetSrc, module, methodInstance, args, flags, expectingType);
|
||||
ReleaseContext(ceContext);
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -332,6 +332,7 @@ enum CeFunctionKind
|
|||
CeFunctionKind_Method_GetName,
|
||||
CeFunctionKind_Method_GetInfo,
|
||||
CeFunctionKind_Method_GetParamInfo,
|
||||
CeFunctionKind_Field_GetName,
|
||||
|
||||
CeFunctionKind_EmitTypeBody,
|
||||
CeFunctionKind_EmitAddInterface,
|
||||
|
@ -516,7 +517,7 @@ public:
|
|||
String mGenError;
|
||||
int mFrameSize;
|
||||
int mMaxReturnSize;
|
||||
int mId;
|
||||
int mId;
|
||||
|
||||
public:
|
||||
CeFunction()
|
||||
|
@ -544,7 +545,8 @@ enum CeEvalFlags
|
|||
CeEvalFlags_Cascade = 1,
|
||||
CeEvalFlags_PersistantError = 2,
|
||||
CeEvalFlags_DeferIfNotOnlyError = 4,
|
||||
CeEvalFlags_NoRebuild = 8
|
||||
CeEvalFlags_NoRebuild = 8,
|
||||
CeEvalFlags_ForceReturnThis = 0x10
|
||||
};
|
||||
|
||||
enum CeOperandKind
|
||||
|
@ -689,8 +691,8 @@ public:
|
|||
Dictionary<BeConstant*, int> mConstDataMap;
|
||||
Dictionary<BeFunction*, int> mInnerFunctionMap;
|
||||
Dictionary<BeGlobalVariable*, int> mStaticFieldMap;
|
||||
Dictionary<String, BfFieldInstance*> mStaticFieldInstanceMap;
|
||||
|
||||
Dictionary<String, BfFieldInstance*> mStaticFieldInstanceMap;
|
||||
|
||||
public:
|
||||
CeBuilder()
|
||||
{
|
||||
|
@ -927,7 +929,9 @@ public:
|
|||
Dictionary<int, CeFunction*> mFunctionIdMap; // Only used for 32-bit
|
||||
Dictionary<BfType*, CeTypeInfo> mTypeInfoMap;
|
||||
HashSet<BfMethodInstance*> mMethodInstanceSet;
|
||||
|
||||
HashSet<BfFieldInstance*> mFieldInstanceSet;
|
||||
Array<BeFunction*> mFunctionList;
|
||||
|
||||
Array<CeContext*> mContextList;
|
||||
|
||||
BfCompiler* mCompiler;
|
||||
|
@ -937,7 +941,7 @@ public:
|
|||
int mRevisionExecuteTime;
|
||||
int mCurFunctionId;
|
||||
int mExecuteId;
|
||||
CeAppendAllocInfo* mAppendAllocInfo;
|
||||
CeAppendAllocInfo* mAppendAllocInfo;
|
||||
|
||||
CeContext* mCurContext;
|
||||
CeEmitContext* mCurEmitContext;
|
||||
|
@ -957,6 +961,7 @@ public:
|
|||
BeModule* GetBeModule();
|
||||
|
||||
void DerefMethodInfo(CeFunctionInfo* ceFunctionInfo);
|
||||
void RemoveFunc(CeFunction* ceFunction);
|
||||
void RemoveMethod(BfMethodInstance* methodInstance);
|
||||
void CreateFunction(BfMethodInstance* methodInstance, CeFunction* ceFunction);
|
||||
CeErrorKind WriteConstant(CeConstStructData& data, BeConstant* constVal, CeContext* ceContext);
|
||||
|
@ -970,6 +975,7 @@ public:
|
|||
CeFunction* GetPreparedFunction(BfMethodInstance* methodInstance);
|
||||
CeTypeInfo* GetTypeInfo(BfType* type);
|
||||
BfMethodInstance* GetMethodInstance(int64 methodHandle);
|
||||
BfFieldInstance* GetFieldInstance(int64 fieldHandle);
|
||||
|
||||
public:
|
||||
void CompileStarted();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue