Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
65 commits
Select commit Hold shift + click to select a range
f78de42
Implements dispatching of IList generic methods to SZArrayHelper
josesimoes Nov 6, 2025
450552e
Fix building type name with MVAR param
josesimoes Nov 7, 2025
c2e0be8
Implement runtime array element type resolution for generic parameters
josesimoes Nov 7, 2025
52426c9
Fix propagation of array element type during execution
josesimoes Nov 7, 2025
d92bdaa
Fix resolving array element type
josesimoes Nov 10, 2025
f1cee64
Revert unwanted change
josesimoes Nov 10, 2025
9db589e
HasStaticConstructor now is const member
josesimoes Nov 10, 2025
6259080
Generic TypeSpec isn't stored iin a movable delegate field anymore
josesimoes Nov 10, 2025
9e3b3df
Add guard against duplicate execution of static generic cctor
josesimoes Nov 10, 2025
2e02150
Code style fixes
nfbot Nov 10, 2025
0727158
Remove duplicated declarations
josesimoes Nov 11, 2025
16e3238
Fix box/unbox of generic types
josesimoes Nov 12, 2025
a1baeca
Code style fixes
nfbot Nov 12, 2025
59e489e
Fix instanciation of generic static fields on demand
josesimoes Nov 13, 2025
f93571f
Fix newobj handler for generic constructors
josesimoes Nov 13, 2025
39ab637
Merge branch 'develop' of https://github.com/nanoframework/nf-interpr…
josesimoes Nov 13, 2025
d0487c5
Fix accessing a null element in a byref array
josesimoes Nov 13, 2025
15b3164
Fix ldelem to provide generic context in generic arrays
josesimoes Nov 13, 2025
789aa1b
Fix box, unbox and stelem for generic types inside interface adapter
josesimoes Nov 13, 2025
0befd34
Fix TypeDescriptor initialization from TypeSpec
josesimoes Nov 14, 2025
049421b
Fix initializing TypeDescriptor from signature parser
josesimoes Nov 17, 2025
e42f176
TypeDescriptor intialization from TypeSpec now received generic conte…
josesimoes Nov 17, 2025
dead557
FIx TypeDescriptor initialization from signature token
josesimoes Nov 17, 2025
0bf6457
Resolving a token in for a MethodDef instance now preserves generic t…
josesimoes Nov 17, 2025
4e67fe7
Update several declarations for previous commits
josesimoes Nov 17, 2025
d5eb9b3
IsInstanceOf now receives caller as parameter
josesimoes Nov 17, 2025
6d55384
CastToType now passes caller parameter to IsInstanceOf
josesimoes Nov 17, 2025
2fca244
Fix CALL_VIRT handler to find generic context and pass it to calles
josesimoes Nov 17, 2025
377d7e8
Fix getting the declaring type of MethodDef instance
josesimoes Nov 17, 2025
d2648ed
Fix preservation of generic context in callvirt
josesimoes Nov 17, 2025
4bca5ea
Add missing clear methodSpec element in MethodDef_Instance struct
josesimoes Nov 18, 2025
19ca181
Add API to get generic argument from MethodSpec_Instance
josesimoes Nov 18, 2025
878fb37
MethodDef Instance added as parameter to several APIs to allow resolv…
josesimoes Nov 18, 2025
dbe1528
ComputeHashForClosedGenericType now properly resolves MVAR and VAR types
josesimoes Nov 18, 2025
378c820
Code style fixes
josesimoes Nov 18, 2025
9479d93
BuildTypeName for TypeSpec now takes optional MethodDef instance as p…
josesimoes Nov 18, 2025
a4135b5
Add BuildMethodName for MethodDef instance
josesimoes Nov 18, 2025
5b24217
Add dump method for MethodDef instance
josesimoes Nov 18, 2025
ce35fc2
Fix DumpToken processing for FieldDef
josesimoes Nov 18, 2025
7082704
HeapBlock_Delegate now also stores a MethodSpec Index to allow resolu…
josesimoes Nov 18, 2025
f8eb33c
Rename API and parameter for coherence sake
josesimoes Nov 19, 2025
c0fa578
Code style fixes
josesimoes Nov 19, 2025
0a1dce9
BuildMethodName from MethodDef instance now considers genericType in …
josesimoes Nov 19, 2025
cda3c5d
Rename and moved GetGenericParam to CLR_RT_TypeSpec_Instance
josesimoes Nov 19, 2025
06294b7
Fix processing of MVAR when initializing locals
josesimoes Nov 19, 2025
a24b99f
Fixes in CLR_RT_TypeSpec_Instance API
josesimoes Nov 19, 2025
c15d89f
Several improvements in BuildTypeName and BuildMethodName
josesimoes Nov 19, 2025
3bfc5d6
ResolveToken for TypeDef instance now handles MVAR inside a VAR resol…
josesimoes Nov 20, 2025
f992c7a
Code style fixes
nfbot Nov 20, 2025
cf7d094
Merge pull request #103 from nanoframework/nfbot/clang-format-fix/d1d…
josesimoes Nov 20, 2025
dfd4e3b
Fix macro name
josesimoes Nov 20, 2025
b91acdd
Increase CODE region size in TI_CC1352R1_LAUNCHXL
josesimoes Nov 20, 2025
de6ce52
Refactor to add helper function for HandleGenericCctorReschedule
josesimoes Nov 20, 2025
eb258d2
Fix token resolution for TypeSpec instance when resolving VAR
josesimoes Nov 20, 2025
c56d735
Add null check in AllocateGenericStaticFieldsOnDemand
josesimoes Nov 20, 2025
094b778
Add missing null check
josesimoes Nov 20, 2025
c000131
Simplification in PushThreadProcDelegate
josesimoes Nov 20, 2025
d061317
Add defensive check
josesimoes Nov 20, 2025
1879a8a
Enhanced delegate diagnostics in CLR_RT_DUMP::OBJECT
josesimoes Nov 20, 2025
3265bb3
Fix comment
josesimoes Nov 20, 2025
e254835
Created a helper function ResolveGenericTypeParameter
josesimoes Nov 20, 2025
46a7d2d
Remove duplicated comment
josesimoes Nov 20, 2025
c97b506
Merge branch 'develop' of https://github.com/nanoframework/nf-interpr…
josesimoes Nov 20, 2025
43d7fcd
Code style fixes
nfbot Nov 20, 2025
81c8f6c
Merge pull request #105 from nanoframework/nfbot/clang-format-fix/a03…
josesimoes Nov 20, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/CLR/Core/CLR_RT_HeapBlock_Delegate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ HRESULT CLR_RT_HeapBlock_Delegate::CreateInstance(

dlg->m_object.SetObjectReference(nullptr);
dlg->m_genericTypeSpec.Clear();
dlg->m_genericMethodSpec.Clear();

#if defined(NANOCLR_APPDOMAINS)
dlg->m_appDomain = g_CLR_RT_ExecutionEngine.GetCurrentAppDomain();
Expand Down
9 changes: 6 additions & 3 deletions src/CLR/Core/CLR_RT_StackFrame.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -118,15 +118,18 @@ HRESULT CLR_RT_StackFrame::Push(CLR_RT_Thread *th, const CLR_RT_MethodDef_Instan
// void* m_customPointer;
// };
//
// Initialize generic type context storage to invalid
stack->m_genericTypeSpecStorage.Clear();
//
#ifndef NANOCLR_NO_IL_INLINE
stack->m_inlineFrame = nullptr;
#endif
#if defined(NANOCLR_PROFILE_NEW_CALLS)
stack->m_callchain.Enter(stack); // CLR_PROF_CounterCallChain m_callchain;
#endif
//
// CLR_RT_HeapBlock m_extension[1];
//
//
// CLR_RT_HeapBlock m_extension[1];
//
#if defined(ENABLE_NATIVE_PROFILER)
stack->m_fNativeProfiled = stack->m_owningThread->m_fNativeProfiled;
#endif
Expand Down
124 changes: 78 additions & 46 deletions src/CLR/Core/Execution.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2028,6 +2028,40 @@ CLR_RT_HeapBlock *CLR_RT_ExecutionEngine::AccessStaticField(const CLR_RT_FieldDe
return nullptr;
}

// Helper function to resolve generic type parameters (VAR/MVAR) to their concrete types
// Used by both InitializeReference and InitializeLocals to reduce code duplication
static HRESULT ResolveGenericTypeParameter(
const CLR_RT_TypeSpec_Index &genericTypeIndex,
CLR_UINT8 paramPosition,
CLR_RT_TypeDef_Index &outClass,
NanoCLRDataType &outDataType)
{
NATIVE_PROFILE_CLR_CORE();
NANOCLR_HEADER();

if (!NANOCLR_INDEX_IS_VALID(genericTypeIndex))
{
NANOCLR_SET_AND_LEAVE(CLR_E_FAIL);
}

CLR_RT_TypeSpec_Instance typeSpec;
if (!typeSpec.InitializeFromIndex(genericTypeIndex))
{
NANOCLR_SET_AND_LEAVE(CLR_E_FAIL);
}

CLR_RT_SignatureParser::Element paramElement;
if (!typeSpec.GetGenericParam(paramPosition, paramElement))
{
NANOCLR_SET_AND_LEAVE(CLR_E_FAIL);
}

outClass = paramElement.Class;
outDataType = paramElement.DataType;

NANOCLR_NOCLEANUP();
}

HRESULT CLR_RT_ExecutionEngine::InitializeReference(
CLR_RT_HeapBlock &ref,
CLR_RT_SignatureParser &parser,
Expand Down Expand Up @@ -2063,8 +2097,13 @@ HRESULT CLR_RT_ExecutionEngine::InitializeReference(

if (dt == DATATYPE_VAR)
{
genericInstance->assembly
->FindGenericParamAtTypeSpec(genericInstance->data, res.GenericParamPosition, realTypeDef, dt);
if (genericInstance == nullptr || !NANOCLR_INDEX_IS_VALID(*genericInstance))
{
NANOCLR_SET_AND_LEAVE(CLR_E_FAIL);
}

NANOCLR_CHECK_HRESULT(
ResolveGenericTypeParameter(*genericInstance, res.GenericParamPosition, realTypeDef, dt));

goto process_datatype;
}
Expand Down Expand Up @@ -2297,44 +2336,53 @@ HRESULT CLR_RT_ExecutionEngine::InitializeLocals(
// type-level generic parameter in a locals signature (e.g. 'T' inside a generic type)
CLR_INT8 genericParamPosition = *sig++;

// Resolve type-level generic parameter (VAR) using the method's enclosing type context
if (methodDefInstance.genericType && NANOCLR_INDEX_IS_VALID(*methodDefInstance.genericType) &&
methodDefInstance.genericType->data != CLR_EmptyToken)
{
CLR_RT_TypeSpec_Instance typeSpec{};
typeSpec.InitializeFromIndex(
(const CLR_RT_TypeSpec_Index &)methodDefInstance.genericType->data);

typeSpec.assembly->FindGenericParamAtTypeSpec(
methodDefInstance.genericType->data,
genericParamPosition,
cls,
dt);
NANOCLR_CHECK_HRESULT(
ResolveGenericTypeParameter(*methodDefInstance.genericType, genericParamPosition, cls, dt));
}
else
{
assembly->FindGenericParamAtTypeSpec(
methodDefInstance.genericType->data,
genericParamPosition,
cls,
dt);
NANOCLR_SET_AND_LEAVE(CLR_E_FAIL);
}

goto done;
}

case DATATYPE_MVAR:
{
// Method-level generic parameter (e.g., '!!T' in a generic method like Array.Empty<T>())
CLR_UINT8 genericParamPosition = *sig++;

CLR_RT_GenericParam_Index gpIndex;
// For generic methods, use the MethodSpec's signature to get the concrete type
if (NANOCLR_INDEX_IS_VALID(methodDefInstance.methodSpec))
{
CLR_RT_MethodSpec_Instance methodSpec;
if (!methodSpec.InitializeFromIndex(methodDefInstance.methodSpec))
{
NANOCLR_SET_AND_LEAVE(CLR_E_FAIL);
}

assembly->FindGenericParamAtMethodDef(methodDefInstance, genericParamPosition, gpIndex);
// Use GetGenericArgument to get the concrete type from MethodSpec's signature
if (!methodSpec.GetGenericArgument(genericParamPosition, cls, dt))
{
NANOCLR_SET_AND_LEAVE(CLR_E_FAIL);
}
}
else
{
// Fallback: try to resolve using GenericParam table (for open generic methods)
CLR_RT_GenericParam_Index gpIndex;
assembly->FindGenericParamAtMethodDef(methodDefInstance, genericParamPosition, gpIndex);

CLR_RT_GenericParam_CrossReference gp =
assembly->crossReferenceGenericParam[gpIndex.GenericParam()];
CLR_RT_GenericParam_CrossReference gp =
assembly->crossReferenceGenericParam[gpIndex.GenericParam()];

cls = gp.classTypeDef;
dt = gp.dataType;
cls = gp.classTypeDef;
dt = gp.dataType;
}

goto done;
}
Expand Down Expand Up @@ -3538,37 +3586,20 @@ bool CLR_RT_ExecutionEngine::IsInstanceOf(
CLR_RT_HeapBlock &obj,
CLR_RT_Assembly *assm,
CLR_UINT32 token,
bool isInstInstruction)
bool isInstInstruction,
const CLR_RT_MethodDef_Instance *caller)
{
NATIVE_PROFILE_CLR_CORE();

CLR_RT_TypeDescriptor desc{};
CLR_RT_TypeDescriptor descTarget{};
CLR_RT_TypeDef_Instance clsTarget{};
CLR_RT_TypeSpec_Instance defTarget{};

if (FAILED(desc.InitializeFromObject(obj)))
return false;

if (clsTarget.ResolveToken(token, assm))
{
//
// Shortcut for identity.
//
if (desc.m_handlerCls.data == clsTarget.data)
return true;

if (FAILED(descTarget.InitializeFromType(clsTarget)))
return false;
}
else if (defTarget.ResolveToken(token, assm))
{
if (FAILED(descTarget.InitializeFromTypeSpec(defTarget)))
return false;
}
else
{
// Use InitializeFromSignatureToken to properly resolve VAR/MVAR tokens
if (FAILED(descTarget.InitializeFromSignatureToken(assm, token, caller)))
return false;
}

return IsInstanceOf(desc, descTarget, isInstInstruction);
}
Expand Down Expand Up @@ -3609,7 +3640,8 @@ HRESULT CLR_RT_ExecutionEngine::CastToType(
CLR_RT_HeapBlock &ref,
CLR_UINT32 tk,
CLR_RT_Assembly *assm,
bool isInstInstruction)
bool isInstInstruction,
const CLR_RT_MethodDef_Instance *caller)
{
NATIVE_PROFILE_CLR_CORE();
NANOCLR_HEADER();
Expand All @@ -3618,7 +3650,7 @@ HRESULT CLR_RT_ExecutionEngine::CastToType(
{
;
}
else if (g_CLR_RT_ExecutionEngine.IsInstanceOf(ref, assm, tk, isInstInstruction) == true)
else if (g_CLR_RT_ExecutionEngine.IsInstanceOf(ref, assm, tk, isInstInstruction, caller) == true)
{
;
}
Expand Down
Loading