mirror of
https://github.com/beefytech/Beef.git
synced 2025-06-10 04:22:20 +02:00
Fixed deferred targeted boxing, DisableChecks, sized array generics
This commit is contained in:
parent
a94b52ff58
commit
b640bf9d5e
8 changed files with 189 additions and 89 deletions
|
@ -382,6 +382,7 @@ BfCompiler::BfCompiler(BfSystem* bfSystem, bool isResolveOnly)
|
||||||
mCReprAttributeTypeDef = NULL;
|
mCReprAttributeTypeDef = NULL;
|
||||||
mAlignAttributeTypeDef = NULL;
|
mAlignAttributeTypeDef = NULL;
|
||||||
mNoDiscardAttributeTypeDef = NULL;
|
mNoDiscardAttributeTypeDef = NULL;
|
||||||
|
mDisableChecksAttributeTypeDef = NULL;
|
||||||
mDisableObjectAccessChecksAttributeTypeDef = NULL;
|
mDisableObjectAccessChecksAttributeTypeDef = NULL;
|
||||||
mDbgRawAllocDataTypeDef = NULL;
|
mDbgRawAllocDataTypeDef = NULL;
|
||||||
mDeferredCallTypeDef = NULL;
|
mDeferredCallTypeDef = NULL;
|
||||||
|
@ -5835,6 +5836,7 @@ bool BfCompiler::DoCompile(const StringImpl& outputDirectory)
|
||||||
mCReprAttributeTypeDef = _GetRequiredType("System.CReprAttribute");
|
mCReprAttributeTypeDef = _GetRequiredType("System.CReprAttribute");
|
||||||
mAlignAttributeTypeDef = _GetRequiredType("System.AlignAttribute");
|
mAlignAttributeTypeDef = _GetRequiredType("System.AlignAttribute");
|
||||||
mNoDiscardAttributeTypeDef = _GetRequiredType("System.NoDiscardAttribute");
|
mNoDiscardAttributeTypeDef = _GetRequiredType("System.NoDiscardAttribute");
|
||||||
|
mDisableChecksAttributeTypeDef = _GetRequiredType("System.DisableChecksAttribute");
|
||||||
mDisableObjectAccessChecksAttributeTypeDef = _GetRequiredType("System.DisableObjectAccessChecksAttribute");
|
mDisableObjectAccessChecksAttributeTypeDef = _GetRequiredType("System.DisableObjectAccessChecksAttribute");
|
||||||
mDbgRawAllocDataTypeDef = _GetRequiredType("System.DbgRawAllocData");
|
mDbgRawAllocDataTypeDef = _GetRequiredType("System.DbgRawAllocData");
|
||||||
mDeferredCallTypeDef = _GetRequiredType("System.DeferredCall");
|
mDeferredCallTypeDef = _GetRequiredType("System.DeferredCall");
|
||||||
|
|
|
@ -380,6 +380,7 @@ public:
|
||||||
BfTypeDef* mCReprAttributeTypeDef;
|
BfTypeDef* mCReprAttributeTypeDef;
|
||||||
BfTypeDef* mAlignAttributeTypeDef;
|
BfTypeDef* mAlignAttributeTypeDef;
|
||||||
BfTypeDef* mNoDiscardAttributeTypeDef;
|
BfTypeDef* mNoDiscardAttributeTypeDef;
|
||||||
|
BfTypeDef* mDisableChecksAttributeTypeDef;
|
||||||
BfTypeDef* mDisableObjectAccessChecksAttributeTypeDef;
|
BfTypeDef* mDisableObjectAccessChecksAttributeTypeDef;
|
||||||
BfTypeDef* mFriendAttributeTypeDef;
|
BfTypeDef* mFriendAttributeTypeDef;
|
||||||
BfTypeDef* mCheckedAttributeTypeDef;
|
BfTypeDef* mCheckedAttributeTypeDef;
|
||||||
|
|
|
@ -2396,7 +2396,7 @@ void BfExprEvaluator::Visit(BfCaseExpression* caseExpr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isPayloadEnum = caseValAddr.mType->IsPayloadEnum();
|
bool isPayloadEnum = (caseValAddr.mType != NULL) && (caseValAddr.mType->IsPayloadEnum());
|
||||||
auto tupleExpr = BfNodeDynCast<BfTupleExpression>(caseExpr->mCaseExpression);
|
auto tupleExpr = BfNodeDynCast<BfTupleExpression>(caseExpr->mCaseExpression);
|
||||||
|
|
||||||
if ((caseValAddr) &&
|
if ((caseValAddr) &&
|
||||||
|
@ -5171,8 +5171,13 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, const BfTypedValu
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((argValue) && (arg != NULL))
|
if ((argValue) && (arg != NULL))
|
||||||
{
|
{
|
||||||
argValue = mModule->Cast(arg, argValue, wantType);
|
//
|
||||||
|
{
|
||||||
|
SetAndRestoreValue<BfScopeData*> prevScopeData(mModule->mCurMethodState->mOverrideScope, boxScopeData);
|
||||||
|
argValue = mModule->Cast(arg, argValue, wantType);
|
||||||
|
}
|
||||||
|
|
||||||
if (!argValue)
|
if (!argValue)
|
||||||
{
|
{
|
||||||
failed = true;
|
failed = true;
|
||||||
|
@ -7367,9 +7372,7 @@ void BfExprEvaluator::LookupQualifiedName(BfAstNode* nameNode, BfIdentifierNode*
|
||||||
prevDef = mPropDef;
|
prevDef = mPropDef;
|
||||||
prevTarget = mPropTarget;
|
prevTarget = mPropTarget;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*if ((mResult) || (mPropDef != NULL))
|
|
||||||
break;*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mPropDef != NULL)
|
if (mPropDef != NULL)
|
||||||
|
@ -13738,72 +13741,100 @@ void BfExprEvaluator::CheckPropFail(BfMethodDef* propMethodDef, BfMethodInstance
|
||||||
BfTypedValue BfExprEvaluator::GetResult(bool clearResult, bool resolveGenericType)
|
BfTypedValue BfExprEvaluator::GetResult(bool clearResult, bool resolveGenericType)
|
||||||
{
|
{
|
||||||
if ((!mResult) && (mPropDef != NULL))
|
if ((!mResult) && (mPropDef != NULL))
|
||||||
{
|
{
|
||||||
BfMethodDef* matchedMethod = GetPropertyMethodDef(mPropDef, BfMethodType_PropertyGetter, mPropCheckedKind);
|
bool handled = false;
|
||||||
if (matchedMethod == NULL)
|
if (mPropTarget.mType->IsGenericTypeInstance())
|
||||||
{
|
{
|
||||||
mModule->Fail("Property has no getter", mPropSrc);
|
auto genericTypeInst = (BfGenericTypeInstance*)mPropTarget.mType;
|
||||||
return mResult;
|
if (genericTypeInst->mTypeDef == mModule->mCompiler->mSizedArrayTypeDef)
|
||||||
}
|
{
|
||||||
|
if (mPropDef->mName == "Count")
|
||||||
auto methodInstance = GetPropertyMethodInstance(matchedMethod);
|
|
||||||
if (methodInstance.mMethodInstance == NULL)
|
|
||||||
return mResult;
|
|
||||||
if (!mModule->mBfIRBuilder->mIgnoreWrites)
|
|
||||||
{
|
|
||||||
BF_ASSERT(!methodInstance.mFunc.IsFake());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mPropSrc != NULL)
|
|
||||||
mModule->UpdateExprSrcPos(mPropSrc);
|
|
||||||
|
|
||||||
CheckPropFail(matchedMethod, methodInstance.mMethodInstance);
|
|
||||||
PerformCallChecks(methodInstance.mMethodInstance, mPropSrc);
|
|
||||||
|
|
||||||
if (methodInstance.mMethodInstance->IsSkipCall())
|
|
||||||
{
|
|
||||||
mResult = mModule->GetDefaultTypedValue(methodInstance.mMethodInstance->mReturnType);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
SizedArray<BfIRValue, 4> args;
|
|
||||||
if (!matchedMethod->mIsStatic)
|
|
||||||
{
|
|
||||||
if ((mPropDefBypassVirtual) && (mPropTarget.mType != methodInstance.mMethodInstance->GetOwner()))
|
|
||||||
mPropTarget = mModule->Cast(mPropSrc, mOrigPropTarget, methodInstance.mMethodInstance->GetOwner());
|
|
||||||
|
|
||||||
mModule->EmitObjectAccessCheck(mPropTarget);
|
|
||||||
PushThis(mPropSrc, mPropTarget, methodInstance.mMethodInstance, args);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool failed = false;
|
|
||||||
for (int paramIdx = 0; paramIdx < (int)mIndexerValues.size(); paramIdx++)
|
|
||||||
{
|
|
||||||
auto val = mModule->Cast(mPropSrc, mIndexerValues[paramIdx].mTypedValue, methodInstance.mMethodInstance->GetParamType(paramIdx));
|
|
||||||
if (!val)
|
|
||||||
failed = true;
|
|
||||||
else
|
|
||||||
PushArg(val, args);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mPropDefBypassVirtual)
|
|
||||||
{
|
|
||||||
auto methodDef = methodInstance.mMethodInstance->mMethodDef;
|
|
||||||
if ((methodDef->mIsAbstract) && (mPropDefBypassVirtual))
|
|
||||||
{
|
{
|
||||||
mModule->Fail(StrFormat("Abstract base property method '%s' cannot be invoked", mModule->MethodToString(methodInstance.mMethodInstance).c_str()), mPropSrc);
|
auto sizedType = genericTypeInst->mTypeGenericArguments[1];
|
||||||
|
if (sizedType->IsConstExprValue())
|
||||||
|
{
|
||||||
|
auto constExprType = (BfConstExprValueType*)sizedType;
|
||||||
|
mResult = BfTypedValue(mModule->GetConstValue(constExprType->mValue.mInt64), mModule->GetPrimitiveType(BfTypeCode_IntPtr));
|
||||||
|
handled = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
BF_ASSERT(mModule->mCurMethodInstance->mIsUnspecialized);
|
||||||
|
mResult = BfTypedValue(mModule->mBfIRBuilder->GetUndefConstValue(BfTypeCode_IntPtr), mModule->GetPrimitiveType(BfTypeCode_IntPtr));
|
||||||
|
handled = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if (failed)
|
|
||||||
mResult = mModule->GetDefaultTypedValue(methodInstance.mMethodInstance->mReturnType);
|
if (!handled)
|
||||||
else
|
{
|
||||||
mResult = CreateCall(methodInstance.mMethodInstance, methodInstance.mFunc, mPropDefBypassVirtual, args);
|
BfMethodDef* matchedMethod = GetPropertyMethodDef(mPropDef, BfMethodType_PropertyGetter, mPropCheckedKind);
|
||||||
if (mResult.mType != NULL)
|
if (matchedMethod == NULL)
|
||||||
{
|
{
|
||||||
if ((mResult.mType->IsVar()) && (mModule->mCompiler->mIsResolveOnly))
|
mModule->Fail("Property has no getter", mPropSrc);
|
||||||
mModule->Fail("Property type reference failed to resolve", mPropSrc);
|
return mResult;
|
||||||
BF_ASSERT(!mResult.mType->IsRef());
|
}
|
||||||
|
|
||||||
|
auto methodInstance = GetPropertyMethodInstance(matchedMethod);
|
||||||
|
if (methodInstance.mMethodInstance == NULL)
|
||||||
|
return mResult;
|
||||||
|
if (!mModule->mBfIRBuilder->mIgnoreWrites)
|
||||||
|
{
|
||||||
|
BF_ASSERT(!methodInstance.mFunc.IsFake());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mPropSrc != NULL)
|
||||||
|
mModule->UpdateExprSrcPos(mPropSrc);
|
||||||
|
|
||||||
|
CheckPropFail(matchedMethod, methodInstance.mMethodInstance);
|
||||||
|
PerformCallChecks(methodInstance.mMethodInstance, mPropSrc);
|
||||||
|
|
||||||
|
if (methodInstance.mMethodInstance->IsSkipCall())
|
||||||
|
{
|
||||||
|
mResult = mModule->GetDefaultTypedValue(methodInstance.mMethodInstance->mReturnType);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SizedArray<BfIRValue, 4> args;
|
||||||
|
if (!matchedMethod->mIsStatic)
|
||||||
|
{
|
||||||
|
if ((mPropDefBypassVirtual) && (mPropTarget.mType != methodInstance.mMethodInstance->GetOwner()))
|
||||||
|
mPropTarget = mModule->Cast(mPropSrc, mOrigPropTarget, methodInstance.mMethodInstance->GetOwner());
|
||||||
|
|
||||||
|
mModule->EmitObjectAccessCheck(mPropTarget);
|
||||||
|
PushThis(mPropSrc, mPropTarget, methodInstance.mMethodInstance, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool failed = false;
|
||||||
|
for (int paramIdx = 0; paramIdx < (int)mIndexerValues.size(); paramIdx++)
|
||||||
|
{
|
||||||
|
auto val = mModule->Cast(mPropSrc, mIndexerValues[paramIdx].mTypedValue, methodInstance.mMethodInstance->GetParamType(paramIdx));
|
||||||
|
if (!val)
|
||||||
|
failed = true;
|
||||||
|
else
|
||||||
|
PushArg(val, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mPropDefBypassVirtual)
|
||||||
|
{
|
||||||
|
auto methodDef = methodInstance.mMethodInstance->mMethodDef;
|
||||||
|
if ((methodDef->mIsAbstract) && (mPropDefBypassVirtual))
|
||||||
|
{
|
||||||
|
mModule->Fail(StrFormat("Abstract base property method '%s' cannot be invoked", mModule->MethodToString(methodInstance.mMethodInstance).c_str()), mPropSrc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (failed)
|
||||||
|
mResult = mModule->GetDefaultTypedValue(methodInstance.mMethodInstance->mReturnType);
|
||||||
|
else
|
||||||
|
mResult = CreateCall(methodInstance.mMethodInstance, methodInstance.mFunc, mPropDefBypassVirtual, args);
|
||||||
|
if (mResult.mType != NULL)
|
||||||
|
{
|
||||||
|
if ((mResult.mType->IsVar()) && (mModule->mCompiler->mIsResolveOnly))
|
||||||
|
mModule->Fail("Property type reference failed to resolve", mPropSrc);
|
||||||
|
BF_ASSERT(!mResult.mType->IsRef());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mPropDef = NULL;
|
mPropDef = NULL;
|
||||||
|
@ -15838,6 +15869,10 @@ void BfExprEvaluator::Visit(BfIndexerExpression* indexerExpr)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool wantsChecks = checkedKind == BfCheckedKind_Checked;
|
||||||
|
if (checkedKind == BfCheckedKind_NotSet)
|
||||||
|
wantsChecks = mModule->GetDefaultCheckedKind() == BfCheckedKind_Checked;
|
||||||
|
|
||||||
//target.mType = mModule->ResolveGenericType(target.mType);
|
//target.mType = mModule->ResolveGenericType(target.mType);
|
||||||
if (target.mType->IsVar())
|
if (target.mType->IsVar())
|
||||||
{
|
{
|
||||||
|
@ -15914,7 +15949,7 @@ void BfExprEvaluator::Visit(BfIndexerExpression* indexerExpr)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (mModule->HasCompiledOutput())
|
else if ((mModule->HasCompiledOutput()) && (wantsChecks))
|
||||||
{
|
{
|
||||||
if (checkedKind == BfCheckedKind_NotSet)
|
if (checkedKind == BfCheckedKind_NotSet)
|
||||||
checkedKind = mModule->GetDefaultCheckedKind();
|
checkedKind = mModule->GetDefaultCheckedKind();
|
||||||
|
|
|
@ -816,7 +816,7 @@ BfModule::BfModule(BfContext* context, const StringImpl& moduleName)
|
||||||
mCompiler = context->mCompiler;
|
mCompiler = context->mCompiler;
|
||||||
mSystem = mCompiler->mSystem;
|
mSystem = mCompiler->mSystem;
|
||||||
mProject = NULL;
|
mProject = NULL;
|
||||||
mCurMethodState = NULL;
|
mCurMethodState = NULL;
|
||||||
mAttributeState = NULL;
|
mAttributeState = NULL;
|
||||||
mCurLocalMethodId = 0;
|
mCurLocalMethodId = 0;
|
||||||
mParentNodeEntry = NULL;
|
mParentNodeEntry = NULL;
|
||||||
|
@ -2479,7 +2479,7 @@ BfError* BfModule::Fail(const StringImpl& error, BfAstNode* refNode, bool isPers
|
||||||
|
|
||||||
BfLogSysM("BfModule::Fail module %p type %p %s\n", this, mCurTypeInstance, error.c_str());
|
BfLogSysM("BfModule::Fail module %p type %p %s\n", this, mCurTypeInstance, error.c_str());
|
||||||
|
|
||||||
String errorString = error;
|
String errorString = error;
|
||||||
bool isWhileSpecializing = false;
|
bool isWhileSpecializing = false;
|
||||||
bool isWhileSpecializingMethod = false;
|
bool isWhileSpecializingMethod = false;
|
||||||
|
|
||||||
|
@ -2493,20 +2493,12 @@ BfError* BfModule::Fail(const StringImpl& error, BfAstNode* refNode, bool isPers
|
||||||
errorString += StrFormat("\n while compiling '%s'", TypeToString(mCurTypeInstance, BfTypeNameFlags_None).c_str());
|
errorString += StrFormat("\n while compiling '%s'", TypeToString(mCurTypeInstance, BfTypeNameFlags_None).c_str());
|
||||||
else if (mProject != NULL)
|
else if (mProject != NULL)
|
||||||
errorString += StrFormat("\n while compiling project '%s'", mProject->mName.c_str());
|
errorString += StrFormat("\n while compiling project '%s'", mProject->mName.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((mCurTypeInstance != NULL) && (mCurMethodState != NULL))
|
if (mCurTypeInstance != NULL)
|
||||||
{
|
{
|
||||||
auto checkMethodState = mCurMethodState;
|
auto _CheckMethodInstance = [&](BfMethodInstance* methodInstance)
|
||||||
while (checkMethodState != NULL)
|
|
||||||
{
|
{
|
||||||
auto methodInstance = checkMethodState->mMethodInstance;
|
|
||||||
if (methodInstance == NULL)
|
|
||||||
{
|
|
||||||
checkMethodState = checkMethodState->mPrevMethodState;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Propogatea the fail all the way to the main method (assuming we're in a local method or lambda)
|
// Propogatea the fail all the way to the main method (assuming we're in a local method or lambda)
|
||||||
methodInstance->mHasFailed = true;
|
methodInstance->mHasFailed = true;
|
||||||
|
|
||||||
|
@ -2516,7 +2508,7 @@ BfError* BfModule::Fail(const StringImpl& error, BfAstNode* refNode, bool isPers
|
||||||
//auto unspecializedMethod = &mCurMethodInstance->mMethodInstanceGroup->mMethodSpecializationMap.begin()->second;
|
//auto unspecializedMethod = &mCurMethodInstance->mMethodInstanceGroup->mMethodSpecializationMap.begin()->second;
|
||||||
auto unspecializedMethod = methodInstance->mMethodInstanceGroup->mDefault;
|
auto unspecializedMethod = methodInstance->mMethodInstanceGroup->mDefault;
|
||||||
if (unspecializedMethod->mHasFailed)
|
if (unspecializedMethod->mHasFailed)
|
||||||
return NULL; // At least SOME error has already been reported
|
return false; // At least SOME error has already been reported
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isSpecializedMethod)
|
if (isSpecializedMethod)
|
||||||
|
@ -2536,8 +2528,30 @@ BfError* BfModule::Fail(const StringImpl& error, BfAstNode* refNode, bool isPers
|
||||||
errorString += StrFormat("\n while specializing type '%s'", TypeToString(mCurTypeInstance).c_str());
|
errorString += StrFormat("\n while specializing type '%s'", TypeToString(mCurTypeInstance).c_str());
|
||||||
isWhileSpecializing = true;
|
isWhileSpecializing = true;
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
checkMethodState = checkMethodState->mPrevMethodState;
|
if (mCurMethodState != NULL)
|
||||||
|
{
|
||||||
|
auto checkMethodState = mCurMethodState;
|
||||||
|
while (checkMethodState != NULL)
|
||||||
|
{
|
||||||
|
auto methodInstance = checkMethodState->mMethodInstance;
|
||||||
|
if (methodInstance == NULL)
|
||||||
|
{
|
||||||
|
checkMethodState = checkMethodState->mPrevMethodState;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!_CheckMethodInstance(methodInstance))
|
||||||
|
return NULL;
|
||||||
|
checkMethodState = checkMethodState->mPrevMethodState;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (mCurMethodInstance != NULL)
|
||||||
|
{
|
||||||
|
if (!_CheckMethodInstance(mCurMethodInstance))
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Keep in mind that all method specializations with generic type instances as its method generic params
|
// Keep in mind that all method specializations with generic type instances as its method generic params
|
||||||
|
@ -2553,6 +2567,12 @@ BfError* BfModule::Fail(const StringImpl& error, BfAstNode* refNode, bool isPers
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((!isWhileSpecializing) && ((mCurTypeInstance->IsGenericTypeInstance()) && (!mCurTypeInstance->IsUnspecializedType())))
|
||||||
|
{
|
||||||
|
errorString += StrFormat("\n while specializing type '%s'", TypeToString(mCurTypeInstance).c_str());
|
||||||
|
isWhileSpecializing = true;
|
||||||
|
}
|
||||||
|
|
||||||
if (!mHadBuildError)
|
if (!mHadBuildError)
|
||||||
mHadBuildError = true;
|
mHadBuildError = true;
|
||||||
|
|
||||||
|
@ -3028,6 +3048,8 @@ BfModuleOptions BfModule::GetModuleOptions()
|
||||||
|
|
||||||
BfCheckedKind BfModule::GetDefaultCheckedKind()
|
BfCheckedKind BfModule::GetDefaultCheckedKind()
|
||||||
{
|
{
|
||||||
|
if ((mCurMethodState != NULL) && (mCurMethodState->mDisableChecks))
|
||||||
|
return BfCheckedKind_Unchecked;
|
||||||
bool runtimeChecks = mCompiler->mOptions.mRuntimeChecks;
|
bool runtimeChecks = mCompiler->mOptions.mRuntimeChecks;
|
||||||
auto typeOptions = GetTypeOptions();
|
auto typeOptions = GetTypeOptions();
|
||||||
if (typeOptions != NULL)
|
if (typeOptions != NULL)
|
||||||
|
@ -16922,6 +16944,8 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup)
|
||||||
auto customAttributes = methodInstance->GetCustomAttributes();
|
auto customAttributes = methodInstance->GetCustomAttributes();
|
||||||
if ((customAttributes != NULL) && (customAttributes->Contains(mCompiler->mDisableObjectAccessChecksAttributeTypeDef)))
|
if ((customAttributes != NULL) && (customAttributes->Contains(mCompiler->mDisableObjectAccessChecksAttributeTypeDef)))
|
||||||
mCurMethodState->mIgnoreObjectAccessCheck = true;
|
mCurMethodState->mIgnoreObjectAccessCheck = true;
|
||||||
|
if ((customAttributes != NULL) && (customAttributes->Contains(mCompiler->mDisableChecksAttributeTypeDef)))
|
||||||
|
mCurMethodState->mDisableChecks = true;
|
||||||
|
|
||||||
if ((methodDef->mMethodType == BfMethodType_CtorNoBody) && (!methodDef->mIsStatic) &&
|
if ((methodDef->mMethodType == BfMethodType_CtorNoBody) && (!methodDef->mIsStatic) &&
|
||||||
((methodInstance->mChainType == BfMethodChainType_ChainHead) || (methodInstance->mChainType == BfMethodChainType_None)))
|
((methodInstance->mChainType == BfMethodChainType_ChainHead) || (methodInstance->mChainType == BfMethodChainType_None)))
|
||||||
|
|
|
@ -899,6 +899,7 @@ public:
|
||||||
int mBlockNestLevel; // 0 = top level
|
int mBlockNestLevel; // 0 = top level
|
||||||
bool mIsEmbedded; // Is an embedded statement (ie: if () stmt) not wrapped in a block
|
bool mIsEmbedded; // Is an embedded statement (ie: if () stmt) not wrapped in a block
|
||||||
bool mIgnoreObjectAccessCheck;
|
bool mIgnoreObjectAccessCheck;
|
||||||
|
bool mDisableChecks;
|
||||||
BfMixinState* mMixinState;
|
BfMixinState* mMixinState;
|
||||||
BfClosureState* mClosureState;
|
BfClosureState* mClosureState;
|
||||||
BfDeferredCallEmitState* mDeferredCallEmitState;
|
BfDeferredCallEmitState* mDeferredCallEmitState;
|
||||||
|
@ -910,6 +911,7 @@ public:
|
||||||
BfScopeData mHeadScope;
|
BfScopeData mHeadScope;
|
||||||
BfScopeData* mCurScope;
|
BfScopeData* mCurScope;
|
||||||
BfScopeData* mTailScope; // Usually equals mCurScope
|
BfScopeData* mTailScope; // Usually equals mCurScope
|
||||||
|
BfScopeData* mOverrideScope;
|
||||||
TempKind mTempKind; // Used for var inference, etc
|
TempKind mTempKind; // Used for var inference, etc
|
||||||
bool mInDeferredBlock;
|
bool mInDeferredBlock;
|
||||||
bool mHadReturn;
|
bool mHadReturn;
|
||||||
|
@ -942,6 +944,7 @@ public:
|
||||||
mHeadScope.mIsScopeHead = true;
|
mHeadScope.mIsScopeHead = true;
|
||||||
mCurScope = &mHeadScope;
|
mCurScope = &mHeadScope;
|
||||||
mTailScope = &mHeadScope;
|
mTailScope = &mHeadScope;
|
||||||
|
mOverrideScope = NULL;
|
||||||
mHadReturn = false;
|
mHadReturn = false;
|
||||||
mLeftBlockUncond = false;
|
mLeftBlockUncond = false;
|
||||||
mLeftBlockCond = false;
|
mLeftBlockCond = false;
|
||||||
|
@ -956,6 +959,7 @@ public:
|
||||||
mNoBind = false;
|
mNoBind = false;
|
||||||
mIsEmbedded = false;
|
mIsEmbedded = false;
|
||||||
mIgnoreObjectAccessCheck = false;
|
mIgnoreObjectAccessCheck = false;
|
||||||
|
mDisableChecks = false;
|
||||||
mInConditionalBlock = false;
|
mInConditionalBlock = false;
|
||||||
mAllowUinitReads = false;
|
mAllowUinitReads = false;
|
||||||
mCancelledDeferredCall = false;
|
mCancelledDeferredCall = false;
|
||||||
|
@ -1332,7 +1336,7 @@ public:
|
||||||
Array<BfIRBuilder*> mPrevIRBuilders; // Before extensions
|
Array<BfIRBuilder*> mPrevIRBuilders; // Before extensions
|
||||||
BfIRBuilder* mBfIRBuilder;
|
BfIRBuilder* mBfIRBuilder;
|
||||||
|
|
||||||
BfMethodState* mCurMethodState;
|
BfMethodState* mCurMethodState;
|
||||||
BfAttributeState* mAttributeState;
|
BfAttributeState* mAttributeState;
|
||||||
BfFilePosition mCurFilePosition;
|
BfFilePosition mCurFilePosition;
|
||||||
BfMethodInstance* mCurMethodInstance;
|
BfMethodInstance* mCurMethodInstance;
|
||||||
|
|
|
@ -4338,10 +4338,19 @@ BfTypeInstance* BfModule::GetWrappedStructType(BfType* type, bool allowSpecializ
|
||||||
{
|
{
|
||||||
if (allowSpecialized)
|
if (allowSpecialized)
|
||||||
{
|
{
|
||||||
|
if (type->IsUnknownSizedArray())
|
||||||
|
{
|
||||||
|
BfUnknownSizedArrayType* sizedArrayType = (BfUnknownSizedArrayType*)type;
|
||||||
|
BfTypeVector typeVector;
|
||||||
|
typeVector.Add(sizedArrayType->mElementType);
|
||||||
|
typeVector.Add(sizedArrayType->mElementCountSource);
|
||||||
|
return ResolveTypeDef(mCompiler->mSizedArrayTypeDef, typeVector, BfPopulateType_Data)->ToTypeInstance();
|
||||||
|
}
|
||||||
|
|
||||||
BfSizedArrayType* sizedArrayType = (BfSizedArrayType*)type;
|
BfSizedArrayType* sizedArrayType = (BfSizedArrayType*)type;
|
||||||
BfTypeVector typeVector;
|
BfTypeVector typeVector;
|
||||||
typeVector.Add(sizedArrayType->mElementType);
|
typeVector.Add(sizedArrayType->mElementType);
|
||||||
auto sizeValue = BfTypedValue(GetConstValue(sizedArrayType->mElementCount), GetPrimitiveType(BfTypeCode_IntPtr));
|
auto sizeValue = BfTypedValue(GetConstValue(BF_MAX(sizedArrayType->mElementCount, 0)), GetPrimitiveType(BfTypeCode_IntPtr));
|
||||||
typeVector.Add(CreateConstExprValueType(sizeValue));
|
typeVector.Add(CreateConstExprValueType(sizeValue));
|
||||||
return ResolveTypeDef(mCompiler->mSizedArrayTypeDef, typeVector, BfPopulateType_Data)->ToTypeInstance();
|
return ResolveTypeDef(mCompiler->mSizedArrayTypeDef, typeVector, BfPopulateType_Data)->ToTypeInstance();
|
||||||
}
|
}
|
||||||
|
@ -9038,7 +9047,12 @@ BfIRValue BfModule::CastToValue(BfAstNode* srcNode, BfTypedValue typedVal, BfTyp
|
||||||
{
|
{
|
||||||
BfScopeData* scopeData = NULL;
|
BfScopeData* scopeData = NULL;
|
||||||
if (mCurMethodState != NULL)
|
if (mCurMethodState != NULL)
|
||||||
scopeData = mCurMethodState->mCurScope;
|
{
|
||||||
|
if (mCurMethodState->mOverrideScope)
|
||||||
|
scopeData = mCurMethodState->mOverrideScope;
|
||||||
|
else
|
||||||
|
scopeData = mCurMethodState->mCurScope;
|
||||||
|
}
|
||||||
|
|
||||||
if ((castFlags & BfCastFlags_WarnOnBox) != 0)
|
if ((castFlags & BfCastFlags_WarnOnBox) != 0)
|
||||||
{
|
{
|
||||||
|
|
|
@ -2155,8 +2155,8 @@ public:
|
||||||
|
|
||||||
virtual bool IsDependentOnUnderlyingType() override { return true; }
|
virtual bool IsDependentOnUnderlyingType() override { return true; }
|
||||||
virtual BfType* GetUnderlyingType() override { return mElementType; }
|
virtual BfType* GetUnderlyingType() override { return mElementType; }
|
||||||
virtual bool IsUnspecializedType() override { return mElementType->IsUnspecializedType(); }
|
virtual bool IsUnspecializedType() override { return mElementType->IsUnspecializedType() || mElementCountSource->IsUnspecializedType(); }
|
||||||
virtual bool IsUnspecializedTypeVariation() override { return mElementType->IsUnspecializedTypeVariation(); }
|
virtual bool IsUnspecializedTypeVariation() override { return mElementType->IsUnspecializedTypeVariation() || mElementCountSource->IsUnspecializedTypeVariation(); }
|
||||||
virtual bool CanBeValuelessType() override { return true; }
|
virtual bool CanBeValuelessType() override { return true; }
|
||||||
// Leave the default "zero sized" definition
|
// Leave the default "zero sized" definition
|
||||||
//virtual bool IsValuelessType() override { return mElementType->IsValuelessType(); }
|
//virtual bool IsValuelessType() override { return mElementType->IsValuelessType(); }
|
||||||
|
|
|
@ -42,4 +42,24 @@ namespace Tests
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class ConstGenerics
|
||||||
|
{
|
||||||
|
public static float GetSum<TCount>(float[TCount] vals) where TCount : const int
|
||||||
|
{
|
||||||
|
float total = 0;
|
||||||
|
for (int i < vals.Count)
|
||||||
|
total += vals[i];
|
||||||
|
return total;
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public static void TestBasics()
|
||||||
|
{
|
||||||
|
float[5] fVals = .(10, 20, 30, 40, 50);
|
||||||
|
|
||||||
|
float totals = GetSum(fVals);
|
||||||
|
Test.Assert(totals == 10+20+30+40+50);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue