From 3338f3c069def4f328f603c9778efa31a51108ba Mon Sep 17 00:00:00 2001 From: Brian Fiete Date: Sat, 29 Jan 2022 09:57:43 -0500 Subject: [PATCH] Allow CreateObject for default ctors with append allocs --- .../corlib/src/Reflection/TypeInstance.bf | 43 ++++++++++++++++--- BeefLibs/corlib/src/Type.bf | 3 +- IDEHelper/Compiler/BfModule.cpp | 17 ++++++-- IDEHelper/Compiler/BfModuleTypeUtils.cpp | 3 +- IDEHelper/Compiler/BfSystem.cpp | 9 +++- 5 files changed, 61 insertions(+), 14 deletions(-) diff --git a/BeefLibs/corlib/src/Reflection/TypeInstance.bf b/BeefLibs/corlib/src/Reflection/TypeInstance.bf index 5eb42155..bcc70b2c 100644 --- a/BeefLibs/corlib/src/Reflection/TypeInstance.bf +++ b/BeefLibs/corlib/src/Reflection/TypeInstance.bf @@ -121,32 +121,55 @@ namespace System.Reflection return .Err; MethodInfo methodInfo = default; + MethodInfo calcAppendMethodInfo = default; if (!IsBoxed) { for (int methodId < mMethodDataCount) { let methodData = &mMethodDataPtr[methodId]; if ((!methodData.mFlags.HasFlag(.Constructor)) || (methodData.mFlags.HasFlag(.Static))) + { + if (((Object)methodData.mName == "this$calcAppend") && (methodData.mParamCount == 0)) + calcAppendMethodInfo = .(this, methodData); continue; - if (methodData.mParamCount != 0) - continue; - - methodInfo = .(this, methodData); - break; + } + if (methodData.mParamCount == 0) + { + methodInfo = .(this, methodData); + break; + } + else if ((methodData.mParamCount == 1) && (methodData.mParamData[0].mParamFlags.HasFlag(.AppendIdx))) + methodInfo = .(this, methodData); } if (!methodInfo.IsInitialized) return .Err; + if ((methodInfo.[Friend]mMethodData.mParamCount != 0) && (!calcAppendMethodInfo.IsInitialized)) + return .Err; } Object obj; let objType = typeof(Object) as TypeInstance; + int allocSize = mInstSize; + bool hasAppendAlloc = (methodInfo.IsInitialized) && (methodInfo.[Friend]mMethodData.mParamCount != 0); + + if (hasAppendAlloc) + { + switch (calcAppendMethodInfo.Invoke(null)) + { + case .Err: + return .Err; + case .Ok(let val): + allocSize += val.Get(); + } + } + #if BF_ENABLE_OBJECT_DEBUG_FLAGS int32 stackCount = Compiler.Options.AllocStackCount; if (mAllocStackCountOverride != 0) stackCount = mAllocStackCountOverride; - obj = Internal.Dbg_ObjectAlloc(mTypeClassVData, mInstSize, mInstAlign, stackCount); + obj = Internal.Dbg_ObjectAlloc(mTypeClassVData, allocSize, mInstAlign, stackCount); #else void* mem = new [Align(16)] uint8[mInstSize]* (?); obj = Internal.UnsafeCastToObject(mem); @@ -155,7 +178,13 @@ namespace System.Reflection Internal.MemSet((uint8*)Internal.UnsafeCastToPtr(obj) + objType.mInstSize, 0, mInstSize - objType.mInstSize); if (methodInfo.IsInitialized) { - if (methodInfo.Invoke(obj) case .Err) + Object[] args = null; + if (hasAppendAlloc) + args = scope:: .(scope:: box ((int)Internal.UnsafeCastToPtr(obj) + mInstSize)); + else + args = scope:: Object[0]; + + if (methodInfo.Invoke(obj, params args) case .Err) { delete obj; return .Err; diff --git a/BeefLibs/corlib/src/Type.bf b/BeefLibs/corlib/src/Type.bf index 6b27fea5..099a20dd 100644 --- a/BeefLibs/corlib/src/Type.bf +++ b/BeefLibs/corlib/src/Type.bf @@ -756,7 +756,8 @@ namespace System.Reflection { None = 0, Splat = 1, - Implicit = 2 + Implicit = 2, + AppendIdx = 4 } [CRepr, AlwaysInclude] diff --git a/IDEHelper/Compiler/BfModule.cpp b/IDEHelper/Compiler/BfModule.cpp index 1193f292..c644c2b9 100644 --- a/IDEHelper/Compiler/BfModule.cpp +++ b/IDEHelper/Compiler/BfModule.cpp @@ -6830,14 +6830,14 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary& usedStrin includeMethod = true; if ((methodDef->mIsStatic) && ((methodReflectKind & BfReflectKind_StaticMethods) != 0)) includeMethod = true; - - if (methodDef->mMethodType == BfMethodType_Ctor) + + if ((methodDef->mMethodType == BfMethodType_Ctor) || (methodDef->mMethodType == BfMethodType_CtorCalcAppend)) { if ((methodReflectKind & BfReflectKind_Constructors) != 0) includeMethod = true; - if ((methodDef->mParams.IsEmpty()) && ((methodReflectKind & BfReflectKind_DefaultConstructor) != 0)) + if ((methodDef->IsDefaultCtor()) && ((methodReflectKind & BfReflectKind_DefaultConstructor) != 0)) includeMethod = true; - } + } if ((!includeMethod) && (typeOptions != NULL)) includeMethod = ApplyTypeOptionMethodFilters(includeMethod, methodDef, typeOptions); @@ -6906,6 +6906,7 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary& usedStrin ParamFlag_None = 0, ParamFlag_Splat = 1, ParamFlag_Implicit = 2, + ParamFlag_AppendIdx = 4 }; SizedArray paramVals; @@ -6917,6 +6918,8 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary& usedStrin ParamFlags paramFlags = ParamFlag_None; if (defaultMethod->GetParamIsSplat(paramIdx)) paramFlags = (ParamFlags)(paramFlags | ParamFlag_Splat); + if (defaultMethod->GetParamKind(paramIdx) == BfParamKind_AppendIdx) + paramFlags = (ParamFlags)(paramFlags | ParamFlag_Implicit | ParamFlag_AppendIdx); BfIRValue paramNameConst = GetStringObjectValue(paramName, !mIsComptimeModule); @@ -10109,6 +10112,12 @@ BfTypedValue BfModule::BoxValue(BfAstNode* srcNode, BfTypedValue typedVal, BfTyp if ((!typedVal.mType->IsPointer()) || (toTypeInstance == mContext->mBfObjectType)) fromStructTypeInstance = GetWrappedStructType(typedVal.mType); + else + { + auto checkStructTypeInstance = GetWrappedStructType(typedVal.mType); + if (checkStructTypeInstance == toType->GetUnderlyingType()) + fromStructTypeInstance = checkStructTypeInstance; + } if (isStructPtr) { diff --git a/IDEHelper/Compiler/BfModuleTypeUtils.cpp b/IDEHelper/Compiler/BfModuleTypeUtils.cpp index bf687fb7..5a61cc41 100644 --- a/IDEHelper/Compiler/BfModuleTypeUtils.cpp +++ b/IDEHelper/Compiler/BfModuleTypeUtils.cpp @@ -5536,9 +5536,10 @@ void BfModule::DoTypeInstanceMethodProcessing(BfTypeInstance* typeInstance) } if (typeInstance->IncludeAllMethods()) implRequired = true; + // "AssumeInstantiated" also forces default ctor if (((typeInstance->mAlwaysIncludeFlags & BfAlwaysIncludeFlag_AssumeInstantiated) != 0) && - (methodDef->mMethodType == BfMethodType_Ctor) && (methodDef->mParams.IsEmpty())) + (methodDef->IsDefaultCtor())) implRequired = true; if ((typeOptionsIncludeAll) && (ApplyTypeOptionMethodFilters(true, methodDef, typeOptions))) diff --git a/IDEHelper/Compiler/BfSystem.cpp b/IDEHelper/Compiler/BfSystem.cpp index 5b6c7f62..8f8d5fd3 100644 --- a/IDEHelper/Compiler/BfSystem.cpp +++ b/IDEHelper/Compiler/BfSystem.cpp @@ -550,7 +550,14 @@ bool BfMethodDef::IsEmptyPartial() bool BfMethodDef::IsDefaultCtor() { - return ((mMethodType == BfMethodType_Ctor) || (mMethodType == BfMethodType_CtorNoBody)) && (mParams.IsEmpty()); + if ((mMethodType == BfMethodType_Ctor) || (mMethodType == BfMethodType_CtorNoBody)) + { + return ((mParams.IsEmpty()) || + ((mParams.mSize == 1) && (mParams[0]->mParamKind == BfParamKind_AppendIdx))); + } + else if (mMethodType == BfMethodType_CtorCalcAppend) + return mParams.IsEmpty(); + return false; } bool BfMethodDef::IsCtorOrInit()