1
0
Fork 0
mirror of https://github.com/beefytech/Beef.git synced 2025-06-10 20:42:21 +02:00

Added reflection category to distinct build options (wip)

This commit is contained in:
Brian Fiete 2020-07-11 16:24:07 -07:00
parent 5cb6570e14
commit 037b2ac1e4
15 changed files with 538 additions and 94 deletions

View file

@ -5906,8 +5906,13 @@ void BfCompiler::CompileReified()
if (typeDef->mIsPartial)
continue;
auto scratchModule = mContext->mScratchModule;
bool isAlwaysInclude = (typeDef->mIsAlwaysInclude) || (typeDef->mProject->mAlwaysIncludeAll);
auto typeOptions = scratchModule->GetTypeOptions(typeDef);
if (typeOptions != NULL)
typeOptions->Apply(isAlwaysInclude, BfOptionFlags_ReflectAlwaysIncludeType);
if (typeDef->mProject->IsTestProject())
{
for (auto methodDef : typeDef->mMethods)
@ -5922,8 +5927,7 @@ void BfCompiler::CompileReified()
//TODO: Just because the type is required doesn't mean we want to reify it. Why did we have that check?
if ((mOptions.mCompileOnDemandKind != BfCompileOnDemandKind_AlwaysInclude) && (!isAlwaysInclude))
continue;
auto scratchModule = mContext->mScratchModule;
scratchModule->ResolveTypeDef(typeDef, BfPopulateType_Full);
}
@ -6396,7 +6400,15 @@ bool BfCompiler::DoCompile(const StringImpl& outputDirectory)
for (auto typeDef : mSystem->mTypeDefs)
{
if ((typeDef->mIsAlwaysInclude) && (!typeDef->mIsPartial))
if (typeDef->mIsPartial)
continue;
bool isAlwaysInclude = (typeDef->mIsAlwaysInclude) || (typeDef->mProject->mAlwaysIncludeAll);
auto typeOptions = mContext->mScratchModule->GetTypeOptions(typeDef);
if (typeOptions != NULL)
isAlwaysInclude = typeOptions->Apply(isAlwaysInclude, BfOptionFlags_ReflectAlwaysIncludeType);
if (isAlwaysInclude)
{
auto requiredType = mContext->mScratchModule->ResolveTypeDef(typeDef);
if (requiredType != NULL)

View file

@ -1896,10 +1896,14 @@ void BfContext::UpdateRevisedTypes()
workspaceConfigHashCtx.Mixin(typeOptions.mSIMDSetting);
workspaceConfigHashCtx.Mixin(typeOptions.mOptimizationLevel);
workspaceConfigHashCtx.Mixin(typeOptions.mEmitDebugInfo);
workspaceConfigHashCtx.Mixin(typeOptions.mRuntimeChecks);
workspaceConfigHashCtx.Mixin(typeOptions.mInitLocalVariables);
workspaceConfigHashCtx.Mixin(typeOptions.mEmitDynamicCastCheck);
workspaceConfigHashCtx.Mixin(typeOptions.mEmitObjectAccessCheck);
workspaceConfigHashCtx.Mixin(typeOptions.mAndFlags);
workspaceConfigHashCtx.Mixin(typeOptions.mOrFlags);
workspaceConfigHashCtx.Mixin(typeOptions.mReflectMethodFilters.size());
for (auto& filter : typeOptions.mReflectMethodFilters)
workspaceConfigHashCtx.MixinStr(filter);
workspaceConfigHashCtx.Mixin(typeOptions.mReflectMethodAttributeFilters.size());
for (auto& filter : typeOptions.mReflectMethodAttributeFilters)
workspaceConfigHashCtx.MixinStr(filter);
workspaceConfigHashCtx.Mixin(typeOptions.mAllocStackTraceDepth);
}
@ -2629,7 +2633,10 @@ void BfContext::TryUnreifyModules()
bool isRequired = false;
for (auto typeInst : module->mOwnedTypeInstances)
{
if ((typeInst->mTypeDef->mIsAlwaysInclude) || (typeInst->mTypeDef->IsGlobalsContainer()))
if (typeInst->mTypeDef->IsGlobalsContainer())
isRequired = true;
if (typeInst->IsAlwaysInclude())
isRequired = true;
}

View file

@ -3341,7 +3341,7 @@ BfCheckedKind BfModule::GetDefaultCheckedKind()
bool runtimeChecks = mCompiler->mOptions.mRuntimeChecks;
auto typeOptions = GetTypeOptions();
if (typeOptions != NULL)
runtimeChecks = BfTypeOptions::Apply(runtimeChecks, typeOptions->mRuntimeChecks);
runtimeChecks = typeOptions->Apply(runtimeChecks, BfOptionFlags_RuntimeChecks);
return runtimeChecks ? BfCheckedKind_Checked : BfCheckedKind_Unchecked;
}
@ -4738,6 +4738,8 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary<int, int>& usedStrin
typeFlags |= BfTypeFlags_Union;
if (type->IsDelegate())
typeFlags |= BfTypeFlags_Delegate;
if (type->IsFunction())
typeFlags |= BfTypeFlags_Function;
if (type->WantsGCMarking())
typeFlags |= BfTypeFlags_WantsMarking;
@ -4839,7 +4841,8 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary<int, int>& usedStrin
// Reserve position
mTypeDataRefs[typeInstance] = BfIRValue();
PopulateType(typeInstance, BfPopulateType_DataAndMethods);
if (typeInstance->IsReified())
PopulateType(typeInstance, BfPopulateType_DataAndMethods);
BfTypeDef* typeDef = typeInstance->mTypeDef;
StringT<128> mangledName;
@ -6198,12 +6201,14 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary<int, int>& usedStrin
if ((typeInstance->IsTypedPrimitive()) || (typeInstance->IsBoxed()))
{
underlyingType = typeInstance->GetUnderlyingType()->mTypeId;
}
}
int outerTypeId = 0;
auto outerType = mContext->mUnreifiedModule->GetOuterType(typeInstance);
if (outerType != NULL)
{
outerTypeId = outerType->mTypeId;
}
BfIRValue customAttrDataPtr;
if (customAttrs.size() > 0)
@ -8753,7 +8758,7 @@ void BfModule::EmitObjectAccessCheck(BfTypedValue typedVal)
bool emitObjectAccessCheck = mCompiler->mOptions.mEmitObjectAccessCheck;
auto typeOptions = GetTypeOptions();
if (typeOptions != NULL)
emitObjectAccessCheck = BfTypeOptions::Apply(emitObjectAccessCheck, typeOptions->mEmitObjectAccessCheck);
emitObjectAccessCheck = typeOptions->Apply(emitObjectAccessCheck, BfOptionFlags_EmitObjectAccessCheck);
if (!emitObjectAccessCheck)
return;
@ -8875,7 +8880,7 @@ void BfModule::EmitDynamicCastCheck(BfTypedValue typedVal, BfType* type, bool al
bool emitDynamicCastCheck = mCompiler->mOptions.mEmitDynamicCastCheck;
auto typeOptions = GetTypeOptions();
if (typeOptions != NULL)
emitDynamicCastCheck = BfTypeOptions::Apply(emitDynamicCastCheck, typeOptions->mEmitDynamicCastCheck);
emitDynamicCastCheck = typeOptions->Apply(emitDynamicCastCheck, BfOptionFlags_EmitDynamicCastCheck);
if (emitDynamicCastCheck)
{
@ -12715,7 +12720,7 @@ BfIRValue BfModule::AllocLocalVariable(BfType* type, const StringImpl& name, boo
bool initLocalVariables = mCompiler->mOptions.mInitLocalVariables;
auto typeOptions = GetTypeOptions();
if (typeOptions != NULL)
initLocalVariables = BfTypeOptions::Apply(initLocalVariables, typeOptions->mInitLocalVariables);
initLocalVariables = typeOptions->Apply(initLocalVariables, BfOptionFlags_InitLocalVariables);
// Local variable inits are implicitly handled in the Beef Backend
if ((initLocalVariables) && (!IsTargetingBeefBackend()))
{
@ -18448,6 +18453,7 @@ BfMethodDef* BfModule::GetLocalMethodDef(BfLocalMethod* localMethod)
if (methodDeclaration != NULL)
{
BfDefBuilder defBuilder(mCompiler->mSystem);
defBuilder.mCurSource = localMethod->mMethodDeclaration->GetParser();
defBuilder.mPassInstance = mCompiler->mPassInstance;
defBuilder.mCurTypeDef = mCurMethodInstance->mMethodDef->mDeclaringType;

View file

@ -1603,6 +1603,7 @@ public:
void MarkDerivedDirty(BfTypeInstance* typeInst);
void CheckAddFailType();
bool PopulateType(BfType* resolvedTypeRef, BfPopulateType populateType = BfPopulateType_Data);
BfTypeOptions* GetTypeOptions(BfTypeDef* typeDef);
int GenerateTypeOptions(BfCustomAttributes* customAttributes, BfTypeInstance* typeInstance, bool checkTypeName);
void SetTypeOptions(BfTypeInstance* typeInstance);
BfModuleOptions GetModuleOptions();

View file

@ -1234,6 +1234,245 @@ bool BfModule::PopulateType(BfType* resolvedTypeRef, BfPopulateType populateType
return result;
}
BfTypeOptions* BfModule::GetTypeOptions(BfTypeDef* typeDef)
{
if (mContext->mSystem->mTypeOptions.size() == 0)
{
return NULL;
}
Array<int> matchedIndices;
if (!mCompiler->mAttributeTypeOptionMap.IsEmpty())
{
auto customAttributes = typeDef->mTypeDeclaration->mAttributes;
while (customAttributes != NULL)
{
if (!mCompiler->mAttributeTypeOptionMap.IsEmpty())
{
SetAndRestoreValue<bool> prevIgnoreErrors(mIgnoreErrors, true);
auto typeRef = customAttributes->mAttributeTypeRef;
// StringT<128> attrName;
// for (auto& customAttrs : customAttributes->mAttributeTypeRef)
// {
// attrName.Clear();
// customAttrs.mType->mTypeDef->mFullName.ToString(attrName);
// Array<int>* arrPtr;
// if (mCompiler->mAttributeTypeOptionMap.TryGetValue(attrName, &arrPtr))
// {
// for (auto optionsIdx : *arrPtr)
// {
// matchedIndices.Add(optionsIdx);
// }
// }
// }
}
customAttributes = customAttributes->mNextAttribute;
}
}
int typeOptionsCount = (int)mContext->mSystem->mTypeOptions.size();
auto _CheckTypeName = [&](const StringImpl& typeName)
{
for (int optionIdx = 0; optionIdx < (int)mContext->mSystem->mTypeOptions.size(); optionIdx++)
{
auto& typeOptions = mContext->mSystem->mTypeOptions[optionIdx];
bool matched = false;
for (auto& filter : typeOptions.mTypeFilters)
{
int filterIdx = 0;
int typeNameIdx = 0;
const char* filterPtr = filter.c_str();
const char* namePtr = typeName.c_str();
char prevFilterC = 0;
while (true)
{
char filterC;
while (true)
{
filterC = *(filterPtr++);
if (filterC != ' ')
break;
}
char nameC;
while (true)
{
nameC = *(namePtr++);
if (nameC != ' ')
break;
}
if ((filterC == 0) || (nameC == 0))
{
matched = (filterC == 0) && (nameC == 0);
break;
}
bool doWildcard = false;
if (nameC != filterC)
{
if (filterC == '*')
doWildcard = true;
else if (((filterC == ',') || (filterC == '>')) &&
((prevFilterC == '<') || (prevFilterC == ',')))
{
doWildcard = true;
filterPtr--;
}
if (!doWildcard)
{
matched = false;
break;
}
}
if (doWildcard)
{
int openDepth = 0;
const char* startNamePtr = namePtr;
while (true)
{
nameC = *(namePtr++);
if (nameC == 0)
{
namePtr--;
if (openDepth != 0)
matched = false;
break;
}
if ((nameC == '>') && (openDepth == 0))
{
namePtr--;
break;
}
if (nameC == '<')
openDepth++;
else if (nameC == '>')
openDepth--;
else if ((nameC == ',') && (openDepth == 0))
{
namePtr--;
break;
}
}
if (!matched)
break;
}
prevFilterC = filterC;
}
}
if (matched)
matchedIndices.push_back(optionIdx);
}
};
// if (typeInstance->IsTypedPrimitive())
// {
// auto underlyingType = typeInstance->GetUnderlyingType();
// if (underlyingType != NULL)
// {
// String typeName = TypeToString(underlyingType);
// _CheckTypeName(typeName);
// }
// else
// {
// // Can this only happen for functions that are being extended?
// }
// }
//
// if ((!typeInstance->IsBoxed()) && (typeInstance->mTypeDef == mCompiler->mPointerTTypeDef))
// {
// BF_ASSERT(typeInstance->IsGenericTypeInstance());
// auto innerType = typeInstance->mGenericTypeInfo->mTypeGenericArguments[0];
// auto ptrType = CreatePointerType(innerType);
// String typeName = TypeToString(ptrType);
// _CheckTypeName(typeName);
// }
String typeName = BfTypeUtils::TypeToString(typeDef);
_CheckTypeName(typeName);
int matchedIdx = -1;
if (matchedIndices.size() == 1)
{
matchedIdx = matchedIndices[0];
}
else if (matchedIndices.size() > 1)
{
// Try to find a merged typeoptions with these indices
for (int mergedIdx = 0; mergedIdx < (int)mContext->mSystem->mMergedTypeOptions.size(); mergedIdx++)
{
auto& typeOptions = mContext->mSystem->mMergedTypeOptions[mergedIdx];
if (typeOptions.mMatchedIndices == matchedIndices)
{
matchedIdx = typeOptionsCount + mergedIdx;
break;
}
}
// Otherwise make one...
if (matchedIdx == -1)
{
auto& first = mContext->mSystem->mTypeOptions[matchedIndices[0]];
BfTypeOptions mergedTypeOptions;
mergedTypeOptions.mSIMDSetting = first.mSIMDSetting;
mergedTypeOptions.mOptimizationLevel = first.mOptimizationLevel;
mergedTypeOptions.mEmitDebugInfo = first.mEmitDebugInfo;
mergedTypeOptions.mAndFlags = first.mAndFlags;
mergedTypeOptions.mOrFlags = first.mOrFlags;
mergedTypeOptions.mAllocStackTraceDepth = first.mAllocStackTraceDepth;
mergedTypeOptions.mReflectMethodFilters = first.mReflectMethodFilters;
mergedTypeOptions.mReflectMethodAttributeFilters = first.mReflectMethodAttributeFilters;
mergedTypeOptions.mMatchedIndices = matchedIndices;
for (int idx = 1; idx < (int)matchedIndices.size(); idx++)
{
auto& typeOptions = mContext->mSystem->mTypeOptions[matchedIndices[idx]];
if (typeOptions.mSIMDSetting != -1)
mergedTypeOptions.mSIMDSetting = typeOptions.mSIMDSetting;
if (typeOptions.mOptimizationLevel != -1)
mergedTypeOptions.mOptimizationLevel = typeOptions.mOptimizationLevel;
if (typeOptions.mEmitDebugInfo != -1)
mergedTypeOptions.mEmitDebugInfo = typeOptions.mEmitDebugInfo;
mergedTypeOptions.mOrFlags = (BfOptionFlags)(mergedTypeOptions.mOrFlags | typeOptions.mOrFlags);
mergedTypeOptions.mAndFlags = (BfOptionFlags)(mergedTypeOptions.mAndFlags | typeOptions.mOrFlags);
mergedTypeOptions.mAndFlags = (BfOptionFlags)(mergedTypeOptions.mAndFlags & typeOptions.mAndFlags);
mergedTypeOptions.mOrFlags = (BfOptionFlags)(mergedTypeOptions.mOrFlags & typeOptions.mAndFlags);
if (typeOptions.mAllocStackTraceDepth != -1)
mergedTypeOptions.mAllocStackTraceDepth = typeOptions.mAllocStackTraceDepth;
for (auto filter : typeOptions.mReflectMethodFilters)
mergedTypeOptions.mReflectMethodFilters.Add(filter);
for (auto filter : typeOptions.mReflectMethodAttributeFilters)
mergedTypeOptions.mReflectMethodAttributeFilters.Add(filter);
}
matchedIdx = typeOptionsCount + (int)mContext->mSystem->mMergedTypeOptions.size();
mContext->mSystem->mMergedTypeOptions.push_back(mergedTypeOptions);
}
}
return mSystem->GetTypeOptions( matchedIdx);
}
int BfModule::GenerateTypeOptions(BfCustomAttributes* customAttributes, BfTypeInstance* typeInstance, bool checkTypeName)
{
if (mContext->mSystem->mTypeOptions.size() == 0)
@ -1379,14 +1618,14 @@ int BfModule::GenerateTypeOptions(BfCustomAttributes* customAttributes, BfTypeIn
}
if (matched)
matchedIndices.push_back(optionIdx);
matchedIndices.push_back(optionIdx);
}
};
if (typeInstance->IsTypedPrimitive())
{
auto underlyingType = typeInstance->GetUnderlyingType();
if (underlyingType != NULL)
if (underlyingType != NULL)
{
String typeName = TypeToString(underlyingType);
_CheckTypeName(typeName);
@ -1407,7 +1646,7 @@ int BfModule::GenerateTypeOptions(BfCustomAttributes* customAttributes, BfTypeIn
}
String typeName = TypeToString(typeInstance);
_CheckTypeName(typeName);
_CheckTypeName(typeName);
}
int matchedIdx = -1;
@ -1436,11 +1675,11 @@ int BfModule::GenerateTypeOptions(BfCustomAttributes* customAttributes, BfTypeIn
mergedTypeOptions.mSIMDSetting = first.mSIMDSetting;
mergedTypeOptions.mOptimizationLevel = first.mOptimizationLevel;
mergedTypeOptions.mEmitDebugInfo = first.mEmitDebugInfo;
mergedTypeOptions.mRuntimeChecks = first.mRuntimeChecks;
mergedTypeOptions.mInitLocalVariables = first.mInitLocalVariables;
mergedTypeOptions.mEmitDynamicCastCheck = first.mEmitDynamicCastCheck;
mergedTypeOptions.mEmitObjectAccessCheck = first.mEmitObjectAccessCheck;
mergedTypeOptions.mAllocStackTraceDepth = first.mAllocStackTraceDepth;
mergedTypeOptions.mAndFlags = first.mAndFlags;
mergedTypeOptions.mOrFlags = first.mOrFlags;
mergedTypeOptions.mAllocStackTraceDepth = first.mAllocStackTraceDepth;
mergedTypeOptions.mReflectMethodFilters = first.mReflectMethodFilters;
mergedTypeOptions.mReflectMethodAttributeFilters = first.mReflectMethodAttributeFilters;
mergedTypeOptions.mMatchedIndices = matchedIndices;
for (int idx = 1; idx < (int)matchedIndices.size(); idx++)
@ -1452,16 +1691,19 @@ int BfModule::GenerateTypeOptions(BfCustomAttributes* customAttributes, BfTypeIn
mergedTypeOptions.mOptimizationLevel = typeOptions.mOptimizationLevel;
if (typeOptions.mEmitDebugInfo != -1)
mergedTypeOptions.mEmitDebugInfo = typeOptions.mEmitDebugInfo;
if (typeOptions.mRuntimeChecks != BfOptionalBool_NotSet)
mergedTypeOptions.mRuntimeChecks = typeOptions.mRuntimeChecks;
if (typeOptions.mInitLocalVariables != BfOptionalBool_NotSet)
mergedTypeOptions.mInitLocalVariables = typeOptions.mInitLocalVariables;
if (typeOptions.mEmitDynamicCastCheck != BfOptionalBool_NotSet)
mergedTypeOptions.mEmitDynamicCastCheck = typeOptions.mEmitDynamicCastCheck;
if (typeOptions.mEmitObjectAccessCheck != BfOptionalBool_NotSet)
mergedTypeOptions.mEmitObjectAccessCheck = typeOptions.mEmitObjectAccessCheck;
mergedTypeOptions.mOrFlags = (BfOptionFlags)(mergedTypeOptions.mOrFlags | typeOptions.mOrFlags);
mergedTypeOptions.mAndFlags = (BfOptionFlags)(mergedTypeOptions.mAndFlags | typeOptions.mOrFlags);
mergedTypeOptions.mAndFlags = (BfOptionFlags)(mergedTypeOptions.mAndFlags & typeOptions.mAndFlags);
mergedTypeOptions.mOrFlags = (BfOptionFlags)(mergedTypeOptions.mOrFlags & typeOptions.mAndFlags);
if (typeOptions.mAllocStackTraceDepth != -1)
mergedTypeOptions.mAllocStackTraceDepth = typeOptions.mAllocStackTraceDepth;
for (auto filter : typeOptions.mReflectMethodFilters)
mergedTypeOptions.mReflectMethodFilters.Add(filter);
for (auto filter : typeOptions.mReflectMethodAttributeFilters)
mergedTypeOptions.mReflectMethodAttributeFilters.Add(filter);
}
matchedIdx = typeOptionsCount + (int)mContext->mSystem->mMergedTypeOptions.size();
mContext->mSystem->mMergedTypeOptions.push_back(mergedTypeOptions);
@ -1880,6 +2122,7 @@ bool BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy
{
BfTypeReference* mTypeRef;
BfTypeInstance* mGenericType;
bool mIgnoreErrors;
};
Array<_DeferredValidate> deferredTypeValidateList;
@ -1930,7 +2173,7 @@ bool BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy
{
// Specialized type variations don't need to validate their constraints
if (!typeInstance->IsUnspecializedTypeVariation())
deferredTypeValidateList.Add({ checkTypeRef, genericTypeInst });
deferredTypeValidateList.Add({ checkTypeRef, genericTypeInst, false });
}
auto checkTypeInst = checkType->ToTypeInstance();
@ -2077,8 +2320,7 @@ bool BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy
{
if ((genericTypeInst->IsSpecializedType()) && (!genericTypeInst->mGenericTypeInfo->mValidatedGenericConstraints) && (!typeInstance->IsBoxed()))
{
SetAndRestoreValue<bool> ignoreErrors(mIgnoreErrors, true);
ValidateGenericConstraints(NULL, genericTypeInst, false);
deferredTypeValidateList.Add({ NULL, genericTypeInst, true });
}
}
@ -2086,15 +2328,14 @@ bool BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy
{
BfType* outerType = GetOuterType(typeInstance);
if (outerType != NULL)
{
PopulateType(outerType, BfPopulateType_BaseType);
AddDependency(outerType, typeInstance, BfDependencyMap::DependencyFlag_OuterType);
}
}
if ((baseTypeInst != NULL) && (typeInstance->mBaseType == NULL))
{
//curFieldDataIdx = 1;
// if (!typeInstance->mTypeFailed)
// PopulateType(baseTypeInst, BfPopulateType_Data);
if (typeInstance->mTypeFailed)
{
if (baseTypeInst->IsDataIncomplete())
@ -2217,6 +2458,7 @@ bool BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy
for (auto& validateEntry : deferredTypeValidateList)
{
SetAndRestoreValue<bool> ignoreErrors(mIgnoreErrors, mIgnoreErrors | validateEntry.mIgnoreErrors);
ValidateGenericConstraints(validateEntry.mTypeRef, validateEntry.mGenericType, false);
}
@ -8564,6 +8806,8 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula
resolvedEntry->mValue = delegateType;
AddDependency(directTypeRef->mType, delegateType, BfDependencyMap::DependencyFlag_ParamOrReturnValue);
if (delegateInfo->mFunctionThisType != NULL)
AddDependency(delegateInfo->mFunctionThisType, delegateType, BfDependencyMap::DependencyFlag_ParamOrReturnValue);
for (auto paramType : paramTypes)
AddDependency(paramType, delegateType, BfDependencyMap::DependencyFlag_ParamOrReturnValue);

View file

@ -6936,7 +6936,7 @@ BfInvocationExpression* BfReducer::CreateInvocationExpression(BfAstNode* target,
return invocationExpr;
}
BfInitializerExpression * BfReducer::TryCreateInitializerExpression(BfExpression* target)
BfInitializerExpression* BfReducer::TryCreateInitializerExpression(BfExpression* target)
{
auto block = BfNodeDynCast<BfBlock>(mVisitorPos.GetNext());
if (block == NULL)

View file

@ -1909,6 +1909,17 @@ void BfTypeInstance::GenerateProjectsReferenced()
BfTypeUtils::GetProjectList(genericArgType, &mGenericTypeInfo->mProjectsReferenced, 0);
}
bool BfTypeInstance::IsAlwaysInclude()
{
bool alwaysInclude = mTypeDef->mIsAlwaysInclude || mTypeDef->mProject->mAlwaysIncludeAll;
if (mTypeOptionsIdx > 0)
{
auto typeOptions = mModule->mSystem->GetTypeOptions(mTypeOptionsIdx);
typeOptions->Apply(alwaysInclude, BfOptionFlags_ReflectAlwaysIncludeType);
}
return alwaysInclude;
}
bool BfTypeInstance::IsSpecializedByAutoCompleteMethod()
{
if (mGenericTypeInfo == NULL)

View file

@ -1878,6 +1878,7 @@ public:
bool GetResultInfo(BfType*& valueType, int& okTagId);
BfGenericTypeInfo::GenericParamsVector* GetGenericParamsVector(BfTypeDef* declaringTypeDef);
void GenerateProjectsReferenced();
bool IsAlwaysInclude();
virtual void ReportMemory(MemReporter* memReporter) override;
};

View file

@ -6412,7 +6412,7 @@ void BfModule::Visit(BfForEachStatement* forEachStmt)
bool boundsCheck = mCompiler->mOptions.mRuntimeChecks;
auto typeOptions = GetTypeOptions();
if (typeOptions != NULL)
boundsCheck = BfTypeOptions::Apply(boundsCheck, typeOptions->mRuntimeChecks);
boundsCheck = typeOptions->Apply(boundsCheck, BfOptionFlags_RuntimeChecks);
BfMethodMatcher methodMatcher(forEachStmt->mVariableName, this, "get__", argValues.mResolvedArgs, NULL);
methodMatcher.mMethodType = BfMethodType_PropertyGetter;

View file

@ -3617,51 +3617,57 @@ BF_EXPORT void BF_CALLTYPE BfSystem_ClearTypeOptions(BfSystem* bfSystem)
bfSystem->mTypeOptions.Clear();
}
BF_EXPORT void BF_CALLTYPE BfSystem_AddTypeOptions(BfSystem* bfSystem, char* filter, int32 simdSetting, int32 optimizationLevel, int32 emitDebugInfo, int32 runtimeChecks,
int32 initLocalVariables, int32 emitDynamicCastCheck, int32 emitObjectAccessCheck, int32 allocStackTraceDepth)
BF_EXPORT void BF_CALLTYPE BfSystem_AddTypeOptions(BfSystem* bfSystem, char* filter, int32 simdSetting, int32 optimizationLevel, int32 emitDebugInfo, int32 andFlags, int32 orFlags, int32 allocStackTraceDepth, char* reflectMethodFilter)
{
AutoCrit autoCrit(bfSystem->mDataLock);
BfTypeOptions typeOptions;
String filterStr = filter;
int idx = 0;
while (true)
auto _ParseFilters = [&](char* filter, Array<String>& filters, Array<String>& attributeFilters)
{
int semiIdx = (int)filterStr.IndexOf(';', idx);
String newFilter;
if (semiIdx == -1)
newFilter = filterStr.Substring(idx);
else
newFilter = filterStr.Substring(idx, semiIdx - idx);
newFilter.Trim();
if (!newFilter.IsEmpty())
String filterStr = filter;
int idx = 0;
while (true)
{
if (newFilter.StartsWith('['))
{
newFilter.Remove(0);
if (newFilter.EndsWith(']'))
newFilter.Remove(newFilter.length() - 1);
newFilter.Trim();
typeOptions.mAttributeFilters.Add(newFilter);
}
int semiIdx = (int)filterStr.IndexOf(';', idx);
String newFilter;
if (semiIdx == -1)
newFilter = filterStr.Substring(idx);
else
typeOptions.mTypeFilters.Add(newFilter);
}
newFilter = filterStr.Substring(idx, semiIdx - idx);
newFilter.Trim();
if (!newFilter.IsEmpty())
{
if (newFilter.StartsWith('['))
{
newFilter.Remove(0);
if (newFilter.EndsWith(']'))
newFilter.Remove(newFilter.length() - 1);
newFilter.Trim();
attributeFilters.Add(newFilter);
}
else
filters.Add(newFilter);
}
if (semiIdx == -1)
break;
idx = semiIdx + 1;
}
};
_ParseFilters(filter, typeOptions.mTypeFilters, typeOptions.mAttributeFilters);
if (semiIdx == -1)
break;
idx = semiIdx + 1;
}
if ((typeOptions.mTypeFilters.IsEmpty()) && (typeOptions.mAttributeFilters.IsEmpty()))
return;
typeOptions.mSIMDSetting = simdSetting;
typeOptions.mOptimizationLevel = optimizationLevel;
typeOptions.mEmitDebugInfo = emitDebugInfo;
typeOptions.mRuntimeChecks = (BfOptionalBool)runtimeChecks;
typeOptions.mInitLocalVariables = (BfOptionalBool)initLocalVariables;
typeOptions.mEmitDynamicCastCheck = (BfOptionalBool)emitDynamicCastCheck;
typeOptions.mEmitObjectAccessCheck = (BfOptionalBool)emitObjectAccessCheck;
typeOptions.mAndFlags = (BfOptionFlags)andFlags;
typeOptions.mOrFlags = (BfOptionFlags)orFlags;
typeOptions.mAllocStackTraceDepth = allocStackTraceDepth;
_ParseFilters(reflectMethodFilter, typeOptions.mReflectMethodFilters, typeOptions.mReflectMethodAttributeFilters);
bfSystem->mTypeOptions.push_back(typeOptions);
}

View file

@ -180,7 +180,8 @@ enum BfTypeFlags
//
BfTypeFlags_WantsMarking = 0x8000,
BfTypeFlags_Delegate = 0x10000,
BfTypeFlags_HasDestructor = 0x20000,
BfTypeFlags_Function = 0x20000,
BfTypeFlags_HasDestructor = 0x40000,
};
enum BfObjectFlags : uint8
@ -1267,11 +1268,23 @@ public:
void WriteErrorSummary();
};
enum BfOptionalBool
enum BfOptionFlags
{
BfOptionalBool_NotSet = -1,
BfOptionalBool_False = 0,
BfOptionalBool_True = 1
BfOptionFlags_None = 0,
BfOptionFlags_RuntimeChecks = 1,
BfOptionFlags_InitLocalVariables = 2,
BfOptionFlags_EmitDynamicCastCheck = 4,
BfOptionFlags_EmitObjectAccessCheck = 8,
BfOptionFlags_ReflectAlwaysIncludeType = 0x10,
BfOptionFlags_ReflectAlwaysIncludeAll = 0x20,
BfOptionFlags_ReflectAssumeInstantiated = 0x40,
BfOptionFlags_ReflectStaticFields = 0x80,
BfOptionFlags_ReflectNonStaticFields = 0x100,
BfOptionFlags_ReflectStaticMethods = 0x200,
BfOptionFlags_ReflectNonStaticMethods = 0x400,
BfOptionFlags_ReflectConstructors = 0x800,
};
class BfTypeOptions
@ -1283,10 +1296,10 @@ public:
int mSIMDSetting;
int mOptimizationLevel;
int mEmitDebugInfo;
BfOptionalBool mRuntimeChecks;
BfOptionalBool mInitLocalVariables;
BfOptionalBool mEmitDynamicCastCheck;
BfOptionalBool mEmitObjectAccessCheck;
BfOptionFlags mAndFlags;
BfOptionFlags mOrFlags;
Array<String> mReflectMethodFilters;
Array<String> mReflectMethodAttributeFilters;
int mAllocStackTraceDepth;
public:
@ -1295,13 +1308,14 @@ public:
if (applyVal != -1)
return applyVal;
return val;
}
}
static bool Apply(bool val, BfOptionalBool applyVal)
bool Apply(bool val, BfOptionFlags flags)
{
if (applyVal != BfOptionalBool_NotSet)
return applyVal == BfOptionalBool_True;
return val;
if (val)
return (mAndFlags & flags) != 0;
else
return (mOrFlags & flags) != 0;
}
};