mirror of
https://github.com/beefytech/Beef.git
synced 2025-06-10 04:22:20 +02:00
Dynamic boxing
This commit is contained in:
parent
7036433e5d
commit
da5b81f419
14 changed files with 266 additions and 151 deletions
|
@ -46,9 +46,11 @@ namespace System
|
||||||
Constructors = 0x10,
|
Constructors = 0x10,
|
||||||
StaticMethods = 0x20,
|
StaticMethods = 0x20,
|
||||||
Methods = 0x40,
|
Methods = 0x40,
|
||||||
All = 0x7F,
|
DynamicBoxing = 0x80,
|
||||||
|
//User = 0x100, // Internal Use
|
||||||
|
All = 0xFF,
|
||||||
|
|
||||||
ApplyToInnerTypes = 0x80,
|
ApplyToInnerTypes = 0x200,
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum AttributeFlags
|
public enum AttributeFlags
|
||||||
|
|
|
@ -83,20 +83,23 @@ namespace System.Reflection
|
||||||
return .Err;
|
return .Err;
|
||||||
|
|
||||||
MethodInfo methodInfo = default;
|
MethodInfo methodInfo = default;
|
||||||
for (int methodId < mMethodDataCount)
|
if (!IsBoxed)
|
||||||
{
|
{
|
||||||
let methodData = &mMethodDataPtr[methodId];
|
for (int methodId < mMethodDataCount)
|
||||||
if ((!methodData.mFlags.HasFlag(.Constructor)) || (methodData.mFlags.HasFlag(.Static)))
|
{
|
||||||
continue;
|
let methodData = &mMethodDataPtr[methodId];
|
||||||
if (methodData.mParamCount != 0)
|
if ((!methodData.mFlags.HasFlag(.Constructor)) || (methodData.mFlags.HasFlag(.Static)))
|
||||||
continue;
|
continue;
|
||||||
|
if (methodData.mParamCount != 0)
|
||||||
methodInfo = .(this, methodData);
|
continue;
|
||||||
break;
|
|
||||||
}
|
methodInfo = .(this, methodData);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
if (!methodInfo.IsInitialized)
|
if (!methodInfo.IsInitialized)
|
||||||
return .Err;
|
return .Err;
|
||||||
|
}
|
||||||
Object obj;
|
Object obj;
|
||||||
|
|
||||||
let objType = typeof(Object) as TypeInstance;
|
let objType = typeof(Object) as TypeInstance;
|
||||||
|
@ -109,10 +112,13 @@ namespace System.Reflection
|
||||||
obj.[Friend]mClassVData = (.)(void*)mTypeClassVData;
|
obj.[Friend]mClassVData = (.)(void*)mTypeClassVData;
|
||||||
#endif
|
#endif
|
||||||
Internal.MemSet((uint8*)Internal.UnsafeCastToPtr(obj) + objType.mInstSize, 0, mInstSize - objType.mInstSize);
|
Internal.MemSet((uint8*)Internal.UnsafeCastToPtr(obj) + objType.mInstSize, 0, mInstSize - objType.mInstSize);
|
||||||
if (methodInfo.Invoke(obj) case .Err)
|
if (methodInfo.IsInitialized)
|
||||||
{
|
{
|
||||||
delete obj;
|
if (methodInfo.Invoke(obj) case .Err)
|
||||||
return .Err;
|
{
|
||||||
|
delete obj;
|
||||||
|
return .Err;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return obj;
|
return obj;
|
||||||
|
|
|
@ -304,6 +304,14 @@ namespace System
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public TypeInstance BoxedType
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return (TypeInstance)GetType(mBoxedType);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public bool IsEnum
|
public bool IsEnum
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
|
|
|
@ -296,6 +296,22 @@ namespace System
|
||||||
return *(T*)(void*)mData;
|
return *(T*)(void*)mData;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Result<Object> GetBoxed()
|
||||||
|
{
|
||||||
|
if (IsObject)
|
||||||
|
return .Err;
|
||||||
|
|
||||||
|
var type = VariantType;
|
||||||
|
var boxedType = type.BoxedType;
|
||||||
|
if (boxedType == null)
|
||||||
|
return .Err;
|
||||||
|
|
||||||
|
var self = this;
|
||||||
|
var object = Try!(boxedType.CreateObject());
|
||||||
|
Internal.MemCpy((uint8*)Internal.UnsafeCastToPtr(object) + boxedType.[Friend]mMemberDataOffset, self.DataPtr, type.Size);
|
||||||
|
return object;
|
||||||
|
}
|
||||||
|
|
||||||
/*public void Get<T>(ref T val)
|
/*public void Get<T>(ref T val)
|
||||||
{
|
{
|
||||||
if (VariantType != typeof(T))
|
if (VariantType != typeof(T))
|
||||||
|
|
|
@ -106,6 +106,8 @@ namespace IDE
|
||||||
[Reflect]
|
[Reflect]
|
||||||
public BuildOptions.AlwaysIncludeKind mReflectAlwaysInclude;
|
public BuildOptions.AlwaysIncludeKind mReflectAlwaysInclude;
|
||||||
[Reflect]
|
[Reflect]
|
||||||
|
public bool? mReflectBoxing;
|
||||||
|
[Reflect]
|
||||||
public bool? mReflectStaticFields;
|
public bool? mReflectStaticFields;
|
||||||
[Reflect]
|
[Reflect]
|
||||||
public bool? mReflectNonStaticFields;
|
public bool? mReflectNonStaticFields;
|
||||||
|
@ -135,6 +137,7 @@ namespace IDE
|
||||||
newVal.mEmitObjectAccessCheck = mEmitObjectAccessCheck;
|
newVal.mEmitObjectAccessCheck = mEmitObjectAccessCheck;
|
||||||
newVal.mAllocStackTraceDepth = mAllocStackTraceDepth;
|
newVal.mAllocStackTraceDepth = mAllocStackTraceDepth;
|
||||||
newVal.mReflectAlwaysInclude = mReflectAlwaysInclude;
|
newVal.mReflectAlwaysInclude = mReflectAlwaysInclude;
|
||||||
|
newVal.mReflectBoxing = mReflectBoxing;
|
||||||
newVal.mReflectStaticFields = mReflectStaticFields;
|
newVal.mReflectStaticFields = mReflectStaticFields;
|
||||||
newVal.mReflectNonStaticFields = mReflectNonStaticFields;
|
newVal.mReflectNonStaticFields = mReflectNonStaticFields;
|
||||||
newVal.mReflectStaticMethods = mReflectStaticMethods;
|
newVal.mReflectStaticMethods = mReflectStaticMethods;
|
||||||
|
@ -166,6 +169,8 @@ namespace IDE
|
||||||
|
|
||||||
if (data.Contains("ReflectAlwaysInclude"))
|
if (data.Contains("ReflectAlwaysInclude"))
|
||||||
mReflectAlwaysInclude = data.GetEnum<BuildOptions.AlwaysIncludeKind>("ReflectAlwaysInclude");
|
mReflectAlwaysInclude = data.GetEnum<BuildOptions.AlwaysIncludeKind>("ReflectAlwaysInclude");
|
||||||
|
if (data.Contains("ReflectBoxing"))
|
||||||
|
mReflectStaticFields = data.GetBool("ReflectBoxing");
|
||||||
if (data.Contains("ReflectStaticFields"))
|
if (data.Contains("ReflectStaticFields"))
|
||||||
mReflectStaticFields = data.GetBool("ReflectStaticFields");
|
mReflectStaticFields = data.GetBool("ReflectStaticFields");
|
||||||
if (data.Contains("ReflectNonStaticFields"))
|
if (data.Contains("ReflectNonStaticFields"))
|
||||||
|
@ -191,6 +196,7 @@ namespace IDE
|
||||||
data.ConditionalAdd("EmitObjectAccessCheck", mEmitObjectAccessCheck);
|
data.ConditionalAdd("EmitObjectAccessCheck", mEmitObjectAccessCheck);
|
||||||
data.ConditionalAdd("AllocStackTraceDepth", mAllocStackTraceDepth);
|
data.ConditionalAdd("AllocStackTraceDepth", mAllocStackTraceDepth);
|
||||||
data.ConditionalAdd("ReflectAlwaysInclude", mReflectAlwaysInclude);
|
data.ConditionalAdd("ReflectAlwaysInclude", mReflectAlwaysInclude);
|
||||||
|
data.ConditionalAdd("ReflectBoxing", mReflectBoxing);
|
||||||
data.ConditionalAdd("ReflectStaticFields", mReflectStaticFields);
|
data.ConditionalAdd("ReflectStaticFields", mReflectStaticFields);
|
||||||
data.ConditionalAdd("ReflectNonStaticFields", mReflectNonStaticFields);
|
data.ConditionalAdd("ReflectNonStaticFields", mReflectNonStaticFields);
|
||||||
data.ConditionalAdd("ReflectStaticMethods", mReflectStaticMethods);
|
data.ConditionalAdd("ReflectStaticMethods", mReflectStaticMethods);
|
||||||
|
|
|
@ -18,14 +18,15 @@ namespace IDE.Compiler
|
||||||
|
|
||||||
ReflectAlwaysIncludeType = 0x10,
|
ReflectAlwaysIncludeType = 0x10,
|
||||||
ReflectAlwaysIncludeAll = 0x20,
|
ReflectAlwaysIncludeAll = 0x20,
|
||||||
ReflectAssumeInstantiated = 0x40,
|
ReflectAssumeInstantiated = 0x40,
|
||||||
ReflectStaticFields = 0x80,
|
ReflectBoxing = 0x80,
|
||||||
ReflectNonStaticFields = 0x100,
|
ReflectStaticFields = 0x100,
|
||||||
ReflectStaticMethods = 0x200,
|
ReflectNonStaticFields = 0x200,
|
||||||
ReflectNonStaticMethods = 0x400,
|
ReflectStaticMethods = 0x400,
|
||||||
ReflectConstructors = 0x800,
|
ReflectNonStaticMethods = 0x800,
|
||||||
|
ReflectConstructors = 0x1000,
|
||||||
|
|
||||||
All = 0xFFF
|
All = 0x1FFF
|
||||||
};
|
};
|
||||||
|
|
||||||
[CallingConvention(.Stdcall), CLink]
|
[CallingConvention(.Stdcall), CLink]
|
||||||
|
@ -401,6 +402,7 @@ namespace IDE.Compiler
|
||||||
orFlags |= .ReflectAlwaysIncludeType | .ReflectAlwaysIncludeAll | .ReflectAssumeInstantiated;
|
orFlags |= .ReflectAlwaysIncludeType | .ReflectAlwaysIncludeAll | .ReflectAssumeInstantiated;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SetFlag(typeOption.mReflectBoxing, .ReflectBoxing);
|
||||||
SetFlag(typeOption.mReflectStaticFields, .ReflectStaticFields);
|
SetFlag(typeOption.mReflectStaticFields, .ReflectStaticFields);
|
||||||
SetFlag(typeOption.mReflectNonStaticFields, .ReflectNonStaticFields);
|
SetFlag(typeOption.mReflectNonStaticFields, .ReflectNonStaticFields);
|
||||||
SetFlag(typeOption.mReflectStaticMethods, .ReflectStaticMethods);
|
SetFlag(typeOption.mReflectStaticMethods, .ReflectStaticMethods);
|
||||||
|
|
|
@ -151,6 +151,10 @@ namespace IDE.ui
|
||||||
typeName.Clear(); typeName.Append(optionsName, "mReflectAlwaysInclude");
|
typeName.Clear(); typeName.Append(optionsName, "mReflectAlwaysInclude");
|
||||||
AddPropertiesItem(reflectItem, "Always Include", typeName);
|
AddPropertiesItem(reflectItem, "Always Include", typeName);
|
||||||
|
|
||||||
|
typeName.Clear(); typeName.Append(optionsName, "mReflectBoxing");
|
||||||
|
AddPropertiesItem(reflectItem, "Dynamic Boxing", typeName,
|
||||||
|
scope String[] ( "No", "Yes" ));
|
||||||
|
|
||||||
typeName.Clear(); typeName.Append(optionsName, "mReflectStaticFields");
|
typeName.Clear(); typeName.Append(optionsName, "mReflectStaticFields");
|
||||||
AddPropertiesItem(reflectItem, "Static Fields", typeName,
|
AddPropertiesItem(reflectItem, "Static Fields", typeName,
|
||||||
scope String[] ( "No", "Yes" ));
|
scope String[] ( "No", "Yes" ));
|
||||||
|
|
|
@ -438,6 +438,7 @@ BfCompiler::BfCompiler(BfSystem* bfSystem, bool isResolveOnly)
|
||||||
mErrorAttributeTypeDef = NULL;
|
mErrorAttributeTypeDef = NULL;
|
||||||
mWarnAttributeTypeDef = NULL;
|
mWarnAttributeTypeDef = NULL;
|
||||||
mIgnoreErrorsAttributeTypeDef = NULL;
|
mIgnoreErrorsAttributeTypeDef = NULL;
|
||||||
|
mReflectAttributeTypeDef = NULL;
|
||||||
|
|
||||||
mLastAutocompleteModule = NULL;
|
mLastAutocompleteModule = NULL;
|
||||||
}
|
}
|
||||||
|
@ -4247,7 +4248,7 @@ void BfCompiler::ProcessAutocompleteTempType()
|
||||||
|
|
||||||
BP_ZONE("ProcessAutocompleteTempType.CheckMethod");
|
BP_ZONE("ProcessAutocompleteTempType.CheckMethod");
|
||||||
BfMethodInstanceGroup methodInstanceGroup;
|
BfMethodInstanceGroup methodInstanceGroup;
|
||||||
methodInstanceGroup.mOwner = typeInst;
|
methodInstanceGroup.mOwner = typeInst;
|
||||||
methodInstanceGroup.mOnDemandKind = BfMethodOnDemandKind_AlwaysInclude;
|
methodInstanceGroup.mOnDemandKind = BfMethodOnDemandKind_AlwaysInclude;
|
||||||
|
|
||||||
BfMethodInstance* methodInstance = new BfMethodInstance();
|
BfMethodInstance* methodInstance = new BfMethodInstance();
|
||||||
|
@ -5111,9 +5112,37 @@ void BfCompiler::PopulateReified()
|
||||||
if (!unspecializedType->mIsReified)
|
if (!unspecializedType->mIsReified)
|
||||||
unspecializedType->mIsReified = true;
|
unspecializedType->mIsReified = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((typeInst != NULL) && (typeInst->mTypeDef->mName->ToString() == "StructA"))
|
||||||
|
{
|
||||||
|
NOP;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((type->IsValueType()) && (!type->IsUnspecializedType()))
|
||||||
|
{
|
||||||
|
bool dynamicBoxing = false;
|
||||||
|
if ((typeInst != NULL) && (typeInst->mTypeOptionsIdx != -2))
|
||||||
|
{
|
||||||
|
auto typeOptions = mSystem->GetTypeOptions(typeInst->mTypeOptionsIdx);
|
||||||
|
if (typeOptions != NULL)
|
||||||
|
{
|
||||||
|
if (typeOptions->Apply(false, BfOptionFlags_ReflectBoxing))
|
||||||
|
dynamicBoxing = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
auto reflectKind = module->GetReflectKind(BfReflectKind_None, typeInst);
|
||||||
|
if ((reflectKind & BfReflectKind_DynamicBoxing) != 0)
|
||||||
|
dynamicBoxing = true;
|
||||||
|
if (dynamicBoxing)
|
||||||
|
{
|
||||||
|
auto boxedType = module->CreateBoxedType(typeInst);
|
||||||
|
module->AddDependency(boxedType, typeInst, BfDependencyMap::DependencyFlag_Allocates);
|
||||||
|
boxedType->mHasBeenInstantiated = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Check reifications forced by virtuals or interfaces
|
// Check reifications forced by virtuals or interfaces
|
||||||
if ((!mIsResolveOnly) && (typeInst != NULL) && (typeInst->mIsReified) && (typeInst->IsObject()) && (!typeInst->IsUnspecializedType())
|
if ((!mIsResolveOnly) && (typeInst != NULL) && (typeInst->mIsReified) && (!typeInst->IsUnspecializedType())
|
||||||
&& (typeInst->mHasBeenInstantiated) && (!typeInst->IsIncomplete()))
|
&& (typeInst->mHasBeenInstantiated) && (!typeInst->IsIncomplete()))
|
||||||
{
|
{
|
||||||
// If we have chained methods, make sure we implement the chain members if the chain head is implemented and reified
|
// If we have chained methods, make sure we implement the chain members if the chain head is implemented and reified
|
||||||
|
@ -5228,7 +5257,20 @@ void BfCompiler::PopulateReified()
|
||||||
|
|
||||||
for (int iMethodIdx = 0; iMethodIdx < iMethodCount; iMethodIdx++)
|
for (int iMethodIdx = 0; iMethodIdx < iMethodCount; iMethodIdx++)
|
||||||
{
|
{
|
||||||
auto ifaceMethodInst = ifaceInst->mMethodInstanceGroups[iMethodIdx].mDefault;
|
auto& ifaceMethodInstGroup = ifaceInst->mMethodInstanceGroups[iMethodIdx];
|
||||||
|
auto ifaceMethodInst = ifaceMethodInstGroup.mDefault;
|
||||||
|
|
||||||
|
if (typeInst->IsObject())
|
||||||
|
{
|
||||||
|
// If the implementor is an object then this can be dynamically dispatched
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// If this method is explicitly reflected then a struct's implementation may be invoked with reflection
|
||||||
|
if (!ifaceMethodInstGroup.mExplicitlyReflected)
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if ((ifaceMethodInst == NULL) || (!ifaceMethodInst->IsReifiedAndImplemented()))
|
if ((ifaceMethodInst == NULL) || (!ifaceMethodInst->IsReifiedAndImplemented()))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
@ -6348,6 +6390,7 @@ bool BfCompiler::DoCompile(const StringImpl& outputDirectory)
|
||||||
mErrorAttributeTypeDef = _GetRequiredType("System.ErrorAttribute");
|
mErrorAttributeTypeDef = _GetRequiredType("System.ErrorAttribute");
|
||||||
mWarnAttributeTypeDef = _GetRequiredType("System.WarnAttribute");
|
mWarnAttributeTypeDef = _GetRequiredType("System.WarnAttribute");
|
||||||
mIgnoreErrorsAttributeTypeDef = _GetRequiredType("System.IgnoreErrorsAttribute");
|
mIgnoreErrorsAttributeTypeDef = _GetRequiredType("System.IgnoreErrorsAttribute");
|
||||||
|
mReflectAttributeTypeDef = _GetRequiredType("System.ReflectAttribute");
|
||||||
|
|
||||||
for (int i = 0; i < BfTypeCode_Length; i++)
|
for (int i = 0; i < BfTypeCode_Length; i++)
|
||||||
mContext->mPrimitiveStructTypes[i] = NULL;
|
mContext->mPrimitiveStructTypes[i] = NULL;
|
||||||
|
|
|
@ -404,6 +404,7 @@ public:
|
||||||
BfTypeDef* mErrorAttributeTypeDef;
|
BfTypeDef* mErrorAttributeTypeDef;
|
||||||
BfTypeDef* mWarnAttributeTypeDef;
|
BfTypeDef* mWarnAttributeTypeDef;
|
||||||
BfTypeDef* mIgnoreErrorsAttributeTypeDef;
|
BfTypeDef* mIgnoreErrorsAttributeTypeDef;
|
||||||
|
BfTypeDef* mReflectAttributeTypeDef;
|
||||||
|
|
||||||
|
|
||||||
int mCurTypeId;
|
int mCurTypeId;
|
||||||
|
|
|
@ -5530,120 +5530,24 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary<int, int>& usedStrin
|
||||||
reflectIncludeAllMethods = true;
|
reflectIncludeAllMethods = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
enum ReflectKind
|
BfReflectKind reflectKind = BfReflectKind_Type;
|
||||||
{
|
|
||||||
ReflectKind_None = 0,
|
|
||||||
ReflectKind_Type = 1,
|
|
||||||
ReflectKind_NonStaticFields = 2,
|
|
||||||
ReflectKind_StaticFields = 4,
|
|
||||||
ReflectKind_DefaultConstructor = 8,
|
|
||||||
ReflectKind_Constructors = 0x10,
|
|
||||||
ReflectKind_StaticMethods = 0x20,
|
|
||||||
ReflectKind_Methods = 0x40,
|
|
||||||
ReflectKind_User = 0x80,
|
|
||||||
ReflectKind_All = 0x7F,
|
|
||||||
|
|
||||||
ReflectKind_ApplyToInnerTypes = 0x80
|
|
||||||
};
|
|
||||||
|
|
||||||
ReflectKind reflectKind = ReflectKind_Type;
|
|
||||||
|
|
||||||
auto _GetReflectUser = [&](BfTypeInstance* attrType)
|
|
||||||
{
|
|
||||||
ReflectKind reflectKind = ReflectKind_None;
|
|
||||||
|
|
||||||
if (attrType->mCustomAttributes != NULL)
|
|
||||||
{
|
|
||||||
for (auto& customAttr : attrType->mCustomAttributes->mAttributes)
|
|
||||||
{
|
|
||||||
if (customAttr.mType->mTypeDef->mName->ToString() == "AttributeUsageAttribute")
|
|
||||||
{
|
|
||||||
for (auto& prop : customAttr.mSetProperties)
|
|
||||||
{
|
|
||||||
auto propDef = prop.mPropertyRef.mTypeInstance->mTypeDef->mProperties[prop.mPropertyRef.mPropIdx];
|
|
||||||
if (propDef->mName == "ReflectUser")
|
|
||||||
{
|
|
||||||
if (prop.mParam.mValue.IsConst())
|
|
||||||
{
|
|
||||||
auto constant = attrType->mConstHolder->GetConstant(prop.mParam.mValue);
|
|
||||||
reflectKind = (ReflectKind)(reflectKind | (ReflectKind)constant->mInt32);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check for Flags arg
|
|
||||||
if (customAttr.mCtorArgs.size() < 2)
|
|
||||||
continue;
|
|
||||||
auto constant = attrType->mConstHolder->GetConstant(customAttr.mCtorArgs[1]);
|
|
||||||
if (constant == NULL)
|
|
||||||
continue;
|
|
||||||
if (constant->mTypeCode == BfTypeCode_Boolean)
|
|
||||||
continue;
|
|
||||||
if ((constant->mInt8 & BfCustomAttributeFlags_ReflectAttribute) != 0)
|
|
||||||
reflectKind = (ReflectKind)(reflectKind | ReflectKind_User);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return reflectKind;
|
|
||||||
};
|
|
||||||
|
|
||||||
auto _GetReflectUserFromDirective = [&](BfAttributeDirective* attributesDirective, BfAttributeTargets attrTarget)
|
auto _GetReflectUserFromDirective = [&](BfAttributeDirective* attributesDirective, BfAttributeTargets attrTarget)
|
||||||
{
|
{
|
||||||
ReflectKind reflectKind = ReflectKind_None;
|
BfReflectKind reflectKind = BfReflectKind_None;
|
||||||
auto customAttrs = GetCustomAttributes(attributesDirective, attrTarget);
|
auto customAttrs = GetCustomAttributes(attributesDirective, attrTarget);
|
||||||
if (customAttrs != NULL)
|
if (customAttrs != NULL)
|
||||||
{
|
{
|
||||||
for (auto& attr : customAttrs->mAttributes)
|
for (auto& attr : customAttrs->mAttributes)
|
||||||
{
|
{
|
||||||
reflectKind = (ReflectKind)(reflectKind | _GetReflectUser(attr.mType));
|
reflectKind = (BfReflectKind)(reflectKind | GetUserReflectKind(attr.mType));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return reflectKind;
|
return reflectKind;
|
||||||
};
|
};
|
||||||
|
|
||||||
//
|
reflectKind = GetReflectKind(reflectKind, typeInstance);
|
||||||
{
|
|
||||||
|
|
||||||
auto checkTypeInstance = typeInstance;
|
|
||||||
while (checkTypeInstance != NULL)
|
|
||||||
{
|
|
||||||
if (checkTypeInstance->mCustomAttributes != NULL)
|
|
||||||
{
|
|
||||||
auto checkReflectKind = ReflectKind_None;
|
|
||||||
|
|
||||||
for (auto& customAttr : checkTypeInstance->mCustomAttributes->mAttributes)
|
|
||||||
{
|
|
||||||
if (customAttr.mType->mTypeDef->mName->ToString() == "ReflectAttribute")
|
|
||||||
{
|
|
||||||
if (customAttr.mCtorArgs.size() > 0)
|
|
||||||
{
|
|
||||||
auto constant = checkTypeInstance->mConstHolder->GetConstant(customAttr.mCtorArgs[0]);
|
|
||||||
checkReflectKind = (ReflectKind)((int)checkReflectKind | constant->mInt32);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
checkReflectKind = ReflectKind_All;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
auto userReflectKind = _GetReflectUser(customAttr.mType);
|
|
||||||
checkReflectKind = (ReflectKind)(checkReflectKind | userReflectKind);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((checkTypeInstance == typeInstance) ||
|
|
||||||
((checkReflectKind & ReflectKind_ApplyToInnerTypes) != 0))
|
|
||||||
{
|
|
||||||
reflectKind = (ReflectKind)(reflectKind | checkReflectKind);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
checkTypeInstance = mContext->mUnreifiedModule->GetOuterType(checkTypeInstance);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fields
|
// Fields
|
||||||
BfType* reflectFieldDataType = ResolveTypeDef(mCompiler->mReflectFieldDataDef);
|
BfType* reflectFieldDataType = ResolveTypeDef(mCompiler->mReflectFieldDataDef);
|
||||||
BfIRValue emptyValueType = mBfIRBuilder->CreateConstStruct(mBfIRBuilder->MapTypeInst(reflectFieldDataType->ToTypeInstance()->mBaseType), SizedArray<BfIRValue, 1>());
|
BfIRValue emptyValueType = mBfIRBuilder->CreateConstStruct(mBfIRBuilder->MapTypeInst(reflectFieldDataType->ToTypeInstance()->mBaseType), SizedArray<BfIRValue, 1>());
|
||||||
|
@ -5836,7 +5740,7 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary<int, int>& usedStrin
|
||||||
if (fieldDef == NULL)
|
if (fieldDef == NULL)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
auto fieldReflectKind = (ReflectKind)(reflectKind & ~ReflectKind_User);
|
auto fieldReflectKind = (BfReflectKind)(reflectKind & ~BfReflectKind_User);
|
||||||
|
|
||||||
bool includeField = reflectIncludeAllFields;
|
bool includeField = reflectIncludeAllFields;
|
||||||
|
|
||||||
|
@ -5850,17 +5754,17 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary<int, int>& usedStrin
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
auto userReflectKind = _GetReflectUser(customAttr.mType);
|
auto userReflectKind = GetUserReflectKind(customAttr.mType);
|
||||||
fieldReflectKind = (ReflectKind)(fieldReflectKind | userReflectKind);
|
fieldReflectKind = (BfReflectKind)(fieldReflectKind | userReflectKind);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((fieldReflectKind & ReflectKind_User) != 0)
|
if ((fieldReflectKind & BfReflectKind_User) != 0)
|
||||||
includeField = true;
|
includeField = true;
|
||||||
if ((!fieldDef->mIsStatic) && ((fieldReflectKind & ReflectKind_NonStaticFields) != 0))
|
if ((!fieldDef->mIsStatic) && ((fieldReflectKind & BfReflectKind_NonStaticFields) != 0))
|
||||||
includeField = true;
|
includeField = true;
|
||||||
if ((fieldDef->mIsStatic) && ((fieldReflectKind & ReflectKind_StaticFields) != 0))
|
if ((fieldDef->mIsStatic) && ((fieldReflectKind & BfReflectKind_StaticFields) != 0))
|
||||||
includeField = true;
|
includeField = true;
|
||||||
|
|
||||||
if ((!fieldDef->mIsStatic) && (typeOptions != NULL))
|
if ((!fieldDef->mIsStatic) && (typeOptions != NULL))
|
||||||
|
@ -6142,7 +6046,7 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary<int, int>& usedStrin
|
||||||
if (defaultMethod->mMethodDef->mMethodType == BfMethodType_CtorNoBody)
|
if (defaultMethod->mMethodDef->mMethodType == BfMethodType_CtorNoBody)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
auto methodReflectKind = (ReflectKind)(reflectKind & ~ReflectKind_User);
|
auto methodReflectKind = (BfReflectKind)(reflectKind & ~BfReflectKind_User);
|
||||||
|
|
||||||
bool includeMethod = reflectIncludeAllMethods;
|
bool includeMethod = reflectIncludeAllMethods;
|
||||||
|
|
||||||
|
@ -6158,8 +6062,8 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary<int, int>& usedStrin
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
auto userReflectKind = _GetReflectUser(customAttr.mType);
|
auto userReflectKind = GetUserReflectKind(customAttr.mType);
|
||||||
methodReflectKind = (ReflectKind)(methodReflectKind | userReflectKind);
|
methodReflectKind = (BfReflectKind)(methodReflectKind | userReflectKind);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6172,15 +6076,15 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary<int, int>& usedStrin
|
||||||
for (BfParameterDeclaration* paramDecl : methodDeclaration->mParams)
|
for (BfParameterDeclaration* paramDecl : methodDeclaration->mParams)
|
||||||
{
|
{
|
||||||
if (paramDecl->mAttributes != NULL)
|
if (paramDecl->mAttributes != NULL)
|
||||||
methodReflectKind = (ReflectKind)(methodReflectKind | _GetReflectUserFromDirective(paramDecl->mAttributes, BfAttributeTargets_Parameter));
|
methodReflectKind = (BfReflectKind)(methodReflectKind | _GetReflectUserFromDirective(paramDecl->mAttributes, BfAttributeTargets_Parameter));
|
||||||
}
|
}
|
||||||
if (methodDeclaration->mReturnAttributes != NULL)
|
if (methodDeclaration->mReturnAttributes != NULL)
|
||||||
methodReflectKind = (ReflectKind)(methodReflectKind | _GetReflectUserFromDirective(methodDeclaration->mReturnAttributes, BfAttributeTargets_ReturnValue));
|
methodReflectKind = (BfReflectKind)(methodReflectKind | _GetReflectUserFromDirective(methodDeclaration->mReturnAttributes, BfAttributeTargets_ReturnValue));
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((methodReflectKind & (ReflectKind_Methods | ReflectKind_User)) != 0)
|
if ((methodReflectKind & (BfReflectKind_Methods | BfReflectKind_User)) != 0)
|
||||||
includeMethod = true;
|
includeMethod = true;
|
||||||
if ((methodDef->mIsStatic) && ((methodReflectKind & ReflectKind_StaticMethods) != 0))
|
if ((methodDef->mIsStatic) && ((methodReflectKind & BfReflectKind_StaticMethods) != 0))
|
||||||
includeMethod = true;
|
includeMethod = true;
|
||||||
|
|
||||||
if ((!includeMethod) && (typeOptions != NULL))
|
if ((!includeMethod) && (typeOptions != NULL))
|
||||||
|
@ -6395,6 +6299,11 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary<int, int>& usedStrin
|
||||||
if ((!typeInstance->IsInterface()) && (typeInstance->mIsReified) && (!typeInstance->IsUnspecializedType())
|
if ((!typeInstance->IsInterface()) && (typeInstance->mIsReified) && (!typeInstance->IsUnspecializedType())
|
||||||
&& (!typeInstance->mInterfaceMethodTable.IsEmpty()))
|
&& (!typeInstance->mInterfaceMethodTable.IsEmpty()))
|
||||||
{
|
{
|
||||||
|
if (typeDef->mName->ToString() == "StructA")
|
||||||
|
{
|
||||||
|
NOP;
|
||||||
|
}
|
||||||
|
|
||||||
SizedArray<BfIRValue, 16> methods;
|
SizedArray<BfIRValue, 16> methods;
|
||||||
for (auto& methodEntry : typeInstance->mInterfaceMethodTable)
|
for (auto& methodEntry : typeInstance->mInterfaceMethodTable)
|
||||||
{
|
{
|
||||||
|
@ -6412,8 +6321,8 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary<int, int>& usedStrin
|
||||||
methods.Add(funcVal);
|
methods.Add(funcVal);
|
||||||
}
|
}
|
||||||
|
|
||||||
while ((!methods.IsEmpty()) && (methods.back() == voidPtrNull))
|
// while ((!methods.IsEmpty()) && (methods.back() == voidPtrNull))
|
||||||
methods.pop_back();
|
// methods.pop_back();
|
||||||
|
|
||||||
BfIRType methodDataArrayType = mBfIRBuilder->GetSizedArrayType(mBfIRBuilder->MapType(voidPtrType, BfIRPopulateType_Full), (int)methods.size());
|
BfIRType methodDataArrayType = mBfIRBuilder->GetSizedArrayType(mBfIRBuilder->MapType(voidPtrType, BfIRPopulateType_Full), (int)methods.size());
|
||||||
BfIRValue methodDataConst = mBfIRBuilder->CreateConstArray(methodDataArrayType, methods);
|
BfIRValue methodDataConst = mBfIRBuilder->CreateConstArray(methodDataArrayType, methods);
|
||||||
|
@ -13461,6 +13370,89 @@ BfTypeOptions* BfModule::GetTypeOptions()
|
||||||
return mSystem->GetTypeOptions(mCurTypeInstance->mTypeOptionsIdx);
|
return mSystem->GetTypeOptions(mCurTypeInstance->mTypeOptionsIdx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BfReflectKind BfModule::GetUserReflectKind(BfTypeInstance* attrType)
|
||||||
|
{
|
||||||
|
BfReflectKind reflectKind = BfReflectKind_None;
|
||||||
|
|
||||||
|
if (attrType->mCustomAttributes != NULL)
|
||||||
|
{
|
||||||
|
for (auto& customAttr : attrType->mCustomAttributes->mAttributes)
|
||||||
|
{
|
||||||
|
if (customAttr.mType->mTypeDef->mName->ToString() == "AttributeUsageAttribute")
|
||||||
|
{
|
||||||
|
for (auto& prop : customAttr.mSetProperties)
|
||||||
|
{
|
||||||
|
auto propDef = prop.mPropertyRef.mTypeInstance->mTypeDef->mProperties[prop.mPropertyRef.mPropIdx];
|
||||||
|
if (propDef->mName == "ReflectUser")
|
||||||
|
{
|
||||||
|
if (prop.mParam.mValue.IsConst())
|
||||||
|
{
|
||||||
|
auto constant = attrType->mConstHolder->GetConstant(prop.mParam.mValue);
|
||||||
|
reflectKind = (BfReflectKind)(reflectKind | (BfReflectKind)constant->mInt32);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check for Flags arg
|
||||||
|
if (customAttr.mCtorArgs.size() < 2)
|
||||||
|
continue;
|
||||||
|
auto constant = attrType->mConstHolder->GetConstant(customAttr.mCtorArgs[1]);
|
||||||
|
if (constant == NULL)
|
||||||
|
continue;
|
||||||
|
if (constant->mTypeCode == BfTypeCode_Boolean)
|
||||||
|
continue;
|
||||||
|
if ((constant->mInt8 & BfCustomAttributeFlags_ReflectAttribute) != 0)
|
||||||
|
reflectKind = (BfReflectKind)(reflectKind | BfReflectKind_User);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return reflectKind;
|
||||||
|
}
|
||||||
|
|
||||||
|
BfReflectKind BfModule::GetReflectKind(BfReflectKind reflectKind, BfTypeInstance* typeInstance)
|
||||||
|
{
|
||||||
|
auto checkTypeInstance = typeInstance;
|
||||||
|
while (checkTypeInstance != NULL)
|
||||||
|
{
|
||||||
|
if (checkTypeInstance->mCustomAttributes != NULL)
|
||||||
|
{
|
||||||
|
auto checkReflectKind = BfReflectKind_None;
|
||||||
|
|
||||||
|
for (auto& customAttr : checkTypeInstance->mCustomAttributes->mAttributes)
|
||||||
|
{
|
||||||
|
if (customAttr.mType->mTypeDef->mName->ToString() == "ReflectAttribute")
|
||||||
|
{
|
||||||
|
if (customAttr.mCtorArgs.size() > 0)
|
||||||
|
{
|
||||||
|
auto constant = checkTypeInstance->mConstHolder->GetConstant(customAttr.mCtorArgs[0]);
|
||||||
|
checkReflectKind = (BfReflectKind)((int)checkReflectKind | constant->mInt32);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
checkReflectKind = BfReflectKind_All;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
auto userReflectKind = GetUserReflectKind(customAttr.mType);
|
||||||
|
checkReflectKind = (BfReflectKind)(checkReflectKind | userReflectKind);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((checkTypeInstance == typeInstance) ||
|
||||||
|
((checkReflectKind & BfReflectKind_ApplyToInnerTypes) != 0))
|
||||||
|
{
|
||||||
|
reflectKind = (BfReflectKind)(reflectKind | checkReflectKind);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
checkTypeInstance = mContext->mUnreifiedModule->GetOuterType(checkTypeInstance);
|
||||||
|
}
|
||||||
|
|
||||||
|
return reflectKind;
|
||||||
|
}
|
||||||
|
|
||||||
bool BfModule::HasDeferredScopeCalls(BfScopeData* scope)
|
bool BfModule::HasDeferredScopeCalls(BfScopeData* scope)
|
||||||
{
|
{
|
||||||
BfScopeData* checkScope = mCurMethodState->mCurScope;
|
BfScopeData* checkScope = mCurMethodState->mCurScope;
|
||||||
|
|
|
@ -1512,6 +1512,8 @@ public:
|
||||||
BfTypedValue GetIntCoercible(const BfTypedValue& typedValue);
|
BfTypedValue GetIntCoercible(const BfTypedValue& typedValue);
|
||||||
bool WantsDebugInfo();
|
bool WantsDebugInfo();
|
||||||
BfTypeOptions* GetTypeOptions();
|
BfTypeOptions* GetTypeOptions();
|
||||||
|
BfReflectKind GetUserReflectKind(BfTypeInstance* attrType);
|
||||||
|
BfReflectKind GetReflectKind(BfReflectKind reflectKind, BfTypeInstance* typeInstance);
|
||||||
void CleanupFileInstances();
|
void CleanupFileInstances();
|
||||||
void AssertErrorState();
|
void AssertErrorState();
|
||||||
void AssertParseErrorState();
|
void AssertParseErrorState();
|
||||||
|
|
|
@ -3996,15 +3996,28 @@ void BfModule::DoTypeInstanceMethodProcessing(BfTypeInstance* typeInstance)
|
||||||
isFailedType = true;
|
isFailedType = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool typeOptionsIncludeAll = false;
|
bool typeOptionsIncludeAll = false;
|
||||||
if (typeOptions != NULL)
|
if (typeOptions != NULL)
|
||||||
typeOptionsIncludeAll = typeOptions->Apply(typeOptionsIncludeAll, BfOptionFlags_ReflectAlwaysIncludeAll);
|
typeOptionsIncludeAll = typeOptions->Apply(typeOptionsIncludeAll, BfOptionFlags_ReflectAlwaysIncludeAll);
|
||||||
|
|
||||||
// Generate all methods. Pass 1
|
// Generate all methods. Pass 1
|
||||||
for (auto methodDef : typeDef->mMethods)
|
for (auto methodDef : typeDef->mMethods)
|
||||||
{
|
{
|
||||||
auto methodInstanceGroup = &typeInstance->mMethodInstanceGroups[methodDef->mIdx];
|
auto methodInstanceGroup = &typeInstance->mMethodInstanceGroups[methodDef->mIdx];
|
||||||
|
|
||||||
|
if (typeOptions != NULL)
|
||||||
|
{
|
||||||
|
BfOptionFlags optionFlags = BfOptionFlags_ReflectNonStaticMethods;
|
||||||
|
if (methodDef->mMethodType == BfMethodType_Ctor)
|
||||||
|
optionFlags = BfOptionFlags_ReflectConstructors;
|
||||||
|
else if (methodDef->mIsStatic)
|
||||||
|
optionFlags = BfOptionFlags_ReflectStaticMethods;
|
||||||
|
methodInstanceGroup->mExplicitlyReflected = typeOptions->Apply(false, optionFlags);
|
||||||
|
methodInstanceGroup->mExplicitlyReflected = ApplyTypeOptionMethodFilters(methodInstanceGroup->mExplicitlyReflected, methodDef, typeOptions);
|
||||||
|
}
|
||||||
|
if ((typeInstance->mCustomAttributes != NULL) && (typeInstance->mCustomAttributes->Contains(mCompiler->mReflectAttributeTypeDef)))
|
||||||
|
methodInstanceGroup->mExplicitlyReflected = true;
|
||||||
|
|
||||||
if (methodInstanceGroup->mOnDemandKind == BfMethodOnDemandKind_AlwaysInclude)
|
if (methodInstanceGroup->mOnDemandKind == BfMethodOnDemandKind_AlwaysInclude)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
|
|
@ -1196,6 +1196,7 @@ public:
|
||||||
int mMethodIdx;
|
int mMethodIdx;
|
||||||
int mRefCount; // External references from BfMethodRefType
|
int mRefCount; // External references from BfMethodRefType
|
||||||
BfMethodOnDemandKind mOnDemandKind;
|
BfMethodOnDemandKind mOnDemandKind;
|
||||||
|
bool mExplicitlyReflected;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
BfMethodInstanceGroup()
|
BfMethodInstanceGroup()
|
||||||
|
@ -1206,6 +1207,7 @@ public:
|
||||||
mMethodIdx = -1;
|
mMethodIdx = -1;
|
||||||
mOnDemandKind = BfMethodOnDemandKind_NotSet;
|
mOnDemandKind = BfMethodOnDemandKind_NotSet;
|
||||||
mRefCount = 0;
|
mRefCount = 0;
|
||||||
|
mExplicitlyReflected = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
~BfMethodInstanceGroup();
|
~BfMethodInstanceGroup();
|
||||||
|
|
|
@ -1289,17 +1289,35 @@ enum BfOptionFlags
|
||||||
BfOptionFlags_ReflectAlwaysIncludeType = 0x10,
|
BfOptionFlags_ReflectAlwaysIncludeType = 0x10,
|
||||||
BfOptionFlags_ReflectAlwaysIncludeAll = 0x20,
|
BfOptionFlags_ReflectAlwaysIncludeAll = 0x20,
|
||||||
BfOptionFlags_ReflectAssumeInstantiated = 0x40,
|
BfOptionFlags_ReflectAssumeInstantiated = 0x40,
|
||||||
BfOptionFlags_ReflectStaticFields = 0x80,
|
BfOptionFlags_ReflectBoxing = 0x80,
|
||||||
BfOptionFlags_ReflectNonStaticFields = 0x100,
|
BfOptionFlags_ReflectStaticFields = 0x100,
|
||||||
BfOptionFlags_ReflectStaticMethods = 0x200,
|
BfOptionFlags_ReflectNonStaticFields = 0x200,
|
||||||
BfOptionFlags_ReflectNonStaticMethods = 0x400,
|
BfOptionFlags_ReflectStaticMethods = 0x400,
|
||||||
BfOptionFlags_ReflectConstructors = 0x800,
|
BfOptionFlags_ReflectNonStaticMethods = 0x800,
|
||||||
|
BfOptionFlags_ReflectConstructors = 0x1000,
|
||||||
|
|
||||||
BfOptionFlags_Reflect_MethodMask = BfOptionFlags_ReflectStaticMethods | BfOptionFlags_ReflectNonStaticMethods | BfOptionFlags_ReflectConstructors,
|
BfOptionFlags_Reflect_MethodMask = BfOptionFlags_ReflectStaticMethods | BfOptionFlags_ReflectNonStaticMethods | BfOptionFlags_ReflectConstructors,
|
||||||
BfOptionFlags_Mask = 0xFFF
|
BfOptionFlags_Mask = 0xFFF
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum BfReflectKind
|
||||||
|
{
|
||||||
|
BfReflectKind_None = 0,
|
||||||
|
BfReflectKind_Type = 1,
|
||||||
|
BfReflectKind_NonStaticFields = 2,
|
||||||
|
BfReflectKind_StaticFields = 4,
|
||||||
|
BfReflectKind_DefaultConstructor = 8,
|
||||||
|
BfReflectKind_Constructors = 0x10,
|
||||||
|
BfReflectKind_StaticMethods = 0x20,
|
||||||
|
BfReflectKind_Methods = 0x40,
|
||||||
|
BfReflectKind_DynamicBoxing = 0x80,
|
||||||
|
BfReflectKind_User = 0x100,
|
||||||
|
BfReflectKind_All = 0x1FF,
|
||||||
|
|
||||||
|
BfReflectKind_ApplyToInnerTypes = 0x200
|
||||||
|
};
|
||||||
|
|
||||||
class BfTypeOptions
|
class BfTypeOptions
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue