Skip to content

Commit 3625a85

Browse files
authored
Fix locals initialization of generic instance type (#3188)
***NO_CI***
1 parent 00cc119 commit 3625a85

File tree

2 files changed

+19
-72
lines changed

2 files changed

+19
-72
lines changed

src/CLR/Core/Execution.cpp

Lines changed: 16 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1915,7 +1915,6 @@ HRESULT CLR_RT_ExecutionEngine::InitializeLocals(
19151915
{
19161916
NanoCLRDataType dt = DATATYPE_VOID;
19171917
CLR_RT_TypeDef_Index cls;
1918-
CLR_RT_TypeSpec_Index typeSpecIndex;
19191918
CLR_UINT32 levels = 0;
19201919
NanoCLRDataType dtModifier = DATATYPE_VOID;
19211920

@@ -1963,10 +1962,17 @@ HRESULT CLR_RT_ExecutionEngine::InitializeLocals(
19631962
// otherwise the comparison won't be possible
19641963
sig--;
19651964

1966-
if (!assembly->FindTypeSpec(sig, typeSpecIndex))
1967-
{
1968-
NANOCLR_SET_AND_LEAVE(CLR_E_WRONG_TYPE);
1969-
}
1965+
// Parse the TypeSpec signature to get the instantiated element
1966+
CLR_RT_SignatureParser sp;
1967+
sp.Initialize_TypeSpec(assembly, sig);
1968+
1969+
CLR_RT_SignatureParser::Element element;
1970+
NANOCLR_CHECK_HRESULT(sp.Advance(element));
1971+
1972+
// element.Class and element.DataType represent the T
1973+
cls = element.Class;
1974+
dt = element.DataType;
1975+
19701976
goto done;
19711977

19721978
case DATATYPE_VAR:
@@ -1977,7 +1983,7 @@ HRESULT CLR_RT_ExecutionEngine::InitializeLocals(
19771983
// parse the locals-signature to extract that T
19781984
CLR_RT_SignatureParser parser;
19791985
parser.Initialize_MethodLocals(assembly, methodDef);
1980-
CLR_RT_SignatureParser::Element element;
1986+
CLR_RT_SignatureParser::Element sigElement;
19811987

19821988
// ensure we don’t walk past the available generic parameters
19831989
const int maxParams = methodDefInstance.target->genericParamCount;
@@ -1987,17 +1993,17 @@ HRESULT CLR_RT_ExecutionEngine::InitializeLocals(
19871993
}
19881994

19891995
// advance into the VAR entry
1990-
parser.Advance(element);
1996+
parser.Advance(sigElement);
19911997

19921998
// walk forward to the Nth generic-parameter
19931999
for (int i = 0; i < genericParamPosition; i++)
19942000
{
1995-
parser.Advance(element);
2001+
parser.Advance(sigElement);
19962002
}
19972003

19982004
// element.Class and element.DataType represent the T
1999-
cls = element.Class;
2000-
dt = element.DataType;
2005+
cls = sigElement.Class;
2006+
dt = sigElement.DataType;
20012007

20022008
goto done;
20032009
}
@@ -2081,13 +2087,6 @@ HRESULT CLR_RT_ExecutionEngine::InitializeLocals(
20812087
NANOCLR_CHECK_HRESULT(NewObject(*locals, inst));
20822088
}
20832089
}
2084-
else if (dt == DATATYPE_GENERICINST)
2085-
{
2086-
// locals for generic instances are always OBJECT type
2087-
dt = DATATYPE_OBJECT;
2088-
locals->SetDataId(CLR_RT_HEAPBLOCK_RAW_ID(dt, CLR_RT_HeapBlock::HB_Alive, 1));
2089-
locals->ClearData();
2090-
}
20912090
else
20922091
{
20932092
if (c_CLR_RT_DataTypeLookup[dt].m_flags & CLR_RT_DataTypeLookup::c_Reference)

src/CLR/Core/Interpreter.cpp

Lines changed: 3 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -2569,33 +2569,7 @@ HRESULT CLR_RT_Thread::Execute_IL(CLR_RT_StackFrame &stackArg)
25692569
CLR_RT_HeapBlock *obj = &evalPos[0];
25702570
NanoCLRDataType dt = obj->DataType();
25712571

2572-
// If it's a byref, it must be a struct instance on the stack/heap
2573-
bool instanceIsByRef =
2574-
(obj->DataType() == DATATYPE_BYREF) || (obj->DataType() == DATATYPE_ARRAY_BYREF);
2575-
2576-
if (instanceIsByRef)
2577-
{
2578-
// extra check for DATATYPE_DATETIME and DATATYPE_TIMESPAN (special cases)
2579-
if (obj->Dereference()->DataType() == DATATYPE_DATETIME ||
2580-
obj->Dereference()->DataType() == DATATYPE_TIMESPAN)
2581-
{
2582-
NANOCLR_CHECK_HRESULT(CLR_RT_TypeDescriptor::ExtractObjectAndDataType(obj, dt));
2583-
}
2584-
else
2585-
{
2586-
// we already have a pointer to the raw struct
2587-
dt = DATATYPE_VALUETYPE;
2588-
2589-
obj = obj->Dereference();
2590-
FAULT_ON_NULL(obj);
2591-
}
2592-
}
2593-
else
2594-
{
2595-
// ordinary object/array
2596-
FAULT_ON_NULL(obj);
2597-
NANOCLR_CHECK_HRESULT(CLR_RT_TypeDescriptor::ExtractObjectAndDataType(obj, dt));
2598-
}
2572+
NANOCLR_CHECK_HRESULT(CLR_RT_TypeDescriptor::ExtractObjectAndDataType(obj, dt));
25992573

26002574
switch (dt)
26012575
{
@@ -2691,35 +2665,9 @@ HRESULT CLR_RT_Thread::Execute_IL(CLR_RT_StackFrame &stackArg)
26912665
}
26922666

26932667
CLR_RT_HeapBlock *obj = &evalPos[1];
2694-
NanoCLRDataType dt;
2695-
2696-
// If it's a byref, it must be a struct instance on the stack/heap
2697-
bool instanceIsByRef =
2698-
(obj->DataType() == DATATYPE_BYREF) || (obj->DataType() == DATATYPE_ARRAY_BYREF);
2699-
2700-
if (instanceIsByRef)
2701-
{
2702-
// extra check for DATATYPE_DATETIME and DATATYPE_TIMESPAN (special cases)
2703-
if (obj->Dereference()->DataType() == DATATYPE_DATETIME ||
2704-
obj->Dereference()->DataType() == DATATYPE_TIMESPAN)
2705-
{
2706-
NANOCLR_CHECK_HRESULT(CLR_RT_TypeDescriptor::ExtractObjectAndDataType(obj, dt));
2707-
}
2708-
else
2709-
{
2710-
// we already have a pointer to the raw struct
2711-
dt = DATATYPE_VALUETYPE;
2668+
NanoCLRDataType dt = obj->DataType();
27122669

2713-
// follow the byref so obj really points at the struct
2714-
obj = obj->Dereference();
2715-
}
2716-
}
2717-
else
2718-
{
2719-
// ordinary object/array
2720-
FAULT_ON_NULL(obj);
2721-
NANOCLR_CHECK_HRESULT(CLR_RT_TypeDescriptor::ExtractObjectAndDataType(obj, dt));
2722-
}
2670+
NANOCLR_CHECK_HRESULT(CLR_RT_TypeDescriptor::ExtractObjectAndDataType(obj, dt));
27232671

27242672
switch (dt)
27252673
{

0 commit comments

Comments
 (0)