diff --git a/BeefLibs/corlib/src/Reflection/MethodInfo.bf b/BeefLibs/corlib/src/Reflection/MethodInfo.bf index a00f5f3a..17ab4673 100644 --- a/BeefLibs/corlib/src/Reflection/MethodInfo.bf +++ b/BeefLibs/corlib/src/Reflection/MethodInfo.bf @@ -55,6 +55,9 @@ namespace System.Reflection public int ParamCount => Compiler.IsComptime ? Type.[Friend]Comptime_Method_GetInfo(mData.mComptimeMethodInstance).mParamCount : mData.mMethodData.[Friend]mParamCount; + public int GenericArgCount => Compiler.IsComptime ? + Type.[Friend]Comptime_Method_GetInfo(mData.mComptimeMethodInstance).mGenericArgCount : + 0; public bool IsConstructor => Compiler.IsComptime ? (Name == "__BfCtor" || Name == "__BfStaticCtor") : @@ -81,6 +84,18 @@ namespace System.Reflection } } + public Type GetGenericArgType(int genericArgIdx) + { + if (Compiler.IsComptime) + { + return Type.[Friend]Comptime_Method_GetGenericArg(mData.mComptimeMethodInstance, (.)genericArgIdx); + } + else + { + Runtime.FatalError(); + } + } + public StringView GetParamName(int paramIdx) { if (Compiler.IsComptime) diff --git a/BeefLibs/corlib/src/Type.bf b/BeefLibs/corlib/src/Type.bf index aa7f84e4..0f961213 100644 --- a/BeefLibs/corlib/src/Type.bf +++ b/BeefLibs/corlib/src/Type.bf @@ -503,6 +503,7 @@ namespace System { public int32 mReturnTypeId; public int32 mParamCount; + public int32 mGenericArgCount; public MethodFlags mMethodFlags; public int32 mMethodIdx; } @@ -540,6 +541,7 @@ namespace System static extern String Comptime_Method_GetName(int64 methodHandle); static extern ComptimeMethodData Comptime_Method_GetInfo(int64 methodHandle); static extern ComptimeParamInfo Comptime_Method_GetParamInfo(int64 methodHandle, int32 paramIdx); + static extern Type Comptime_Method_GetGenericArg(int64 methodHandle, int32 genericArgIdx); static extern String Comptime_Field_GetName(int64 fieldHandle); static extern ComptimeFieldInfo Comptime_Field_GetInfo(int64 fieldHandle); diff --git a/IDEHelper/Compiler/CeMachine.cpp b/IDEHelper/Compiler/CeMachine.cpp index 1953460c..bdf8a93c 100644 --- a/IDEHelper/Compiler/CeMachine.cpp +++ b/IDEHelper/Compiler/CeMachine.cpp @@ -5910,10 +5910,11 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8* { // int32 mReturnType // int32 mParamCount + // int32 mGenericArgCount // int16 mFlags // int32 mMethodIdx - int64 methodHandle = *(int64*)((uint8*)stackPtr + 4+4+2+4); + int64 methodHandle = *(int64*)((uint8*)stackPtr + 4+4+4+2+4); auto methodInstance = mCeMachine->GetMethodInstance(methodHandle); if (methodInstance == NULL) @@ -5922,12 +5923,17 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8* return false; } + int genericArgCount = 0; + if (methodInstance->mMethodInfoEx != NULL) + genericArgCount = methodInstance->mMethodInfoEx->mMethodGenericArguments.mSize; + *(int32*)(stackPtr + 0) = methodInstance->mReturnType->mTypeId; *(int32*)(stackPtr + 4) = methodInstance->GetParamCount(); - *(int16*)(stackPtr + 4+4) = methodInstance->GetMethodFlags(); - *(int32*)(stackPtr + 4+4+2) = methodInstance->mMethodDef->mIdx; + *(int32*)(stackPtr + 4+4) = genericArgCount; + *(int16*)(stackPtr + 4+4+4) = methodInstance->GetMethodFlags(); + *(int32*)(stackPtr + 4+4+4+2) = methodInstance->mMethodDef->mIdx; } - else if (checkFunction->mFunctionKind == CeFunctionKind_Method_GetParamInfo) + else if (checkFunction->mFunctionKind == CeFunctionKind_Method_GetParamInfo) { // int32 mParamType // int16 mFlags @@ -5955,6 +5961,28 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8* *(int16*)(stackPtr + 4) = 0; // Flags CeSetAddrVal(stackPtr + 4+2, stringAddr, ptrSize); } + else if (checkFunction->mFunctionKind == CeFunctionKind_Method_GetGenericArg) + { + int64 methodHandle = *(int64*)((uint8*)stackPtr + ptrSize); + int32 genericArgIdx = *(int32*)((uint8*)stackPtr + ptrSize + 8); + + auto methodInstance = mCeMachine->GetMethodInstance(methodHandle); + if (methodInstance == NULL) + { + _Fail("Invalid method instance"); + return false; + } + + if ((methodInstance->mMethodInfoEx == NULL) || (genericArgIdx < 0) || (genericArgIdx >= methodInstance->mMethodInfoEx->mMethodGenericArguments.mSize)) + { + _Fail("genericArgIdx is out of range"); + return false; + } + + auto reflectType = GetReflectType(methodInstance->mMethodInfoEx->mMethodGenericArguments[genericArgIdx]->mTypeId); + _FixVariables(); + CeSetAddrVal(stackPtr + 0, reflectType, ptrSize); + } else if (checkFunction->mFunctionKind == CeFunctionKind_EmitTypeBody) { int32 typeId = *(int32*)((uint8*)stackPtr); @@ -9054,6 +9082,10 @@ void CeMachine::CheckFunctionKind(CeFunction* ceFunction) { ceFunction->mFunctionKind = CeFunctionKind_Method_GetParamInfo; } + else if (methodDef->mName == "Comptime_Method_GetGenericArg") + { + ceFunction->mFunctionKind = CeFunctionKind_Method_GetGenericArg; + } } else if (owner->IsInstanceOf(mCeModule->mCompiler->mCompilerTypeDef)) { diff --git a/IDEHelper/Compiler/CeMachine.h b/IDEHelper/Compiler/CeMachine.h index 90eb8ec3..fd6d6938 100644 --- a/IDEHelper/Compiler/CeMachine.h +++ b/IDEHelper/Compiler/CeMachine.h @@ -430,6 +430,7 @@ enum CeFunctionKind CeFunctionKind_Method_GetName, CeFunctionKind_Method_GetInfo, CeFunctionKind_Method_GetParamInfo, + CeFunctionKind_Method_GetGenericArg, CeFunctionKind_EmitTypeBody, CeFunctionKind_EmitAddInterface, @@ -1007,7 +1008,6 @@ public: Dictionary mOnCompileMap; Dictionary mTypeIFaceMap; Dictionary mEmitSourceMap; // key is (extension<<32)|charId - Array mPendingInterfaces; Dictionary mRebuildMap; Val128 mHash;