Skip to content

Commit

Permalink
Emit type of type parameter in generic constraint table
Browse files Browse the repository at this point in the history
  • Loading branch information
hez2010 committed Sep 19, 2023
1 parent c8a2ccf commit 5d3da96
Show file tree
Hide file tree
Showing 13 changed files with 160 additions and 138 deletions.
23 changes: 19 additions & 4 deletions src/coreclr/ildasm/dasm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3099,21 +3099,36 @@ char *DumpGenericPars(_Inout_updates_(SZSTRING_SIZE) char* szString, mdToken tok
{
CQuickBytes out;
mdToken tkConstrType,tkOwner;
szptr += sprintf_s(szptr,SZSTRING_REMAINING_SIZE(szptr),"(");
DWORD ix;
BOOL first = true, hasLiteralTypeParameter = false;
for (ix=0; ix<NumConstrs; ix++)
{
if (FAILED(g_pPubImport->GetGenericParamConstraintProps(tkConstr[ix], &tkOwner, &tkConstrType)))
return NULL;

if(ix) szptr += sprintf_s(szptr,SZSTRING_REMAINING_SIZE(szptr),", ");
if (TypeFromToken(tkConstrType) == mdtGenericParamType)
{
hasLiteralTypeParameter = true;
continue;
}
if(first)
{
szptr += sprintf_s(szptr,SZSTRING_REMAINING_SIZE(szptr),"(");
first = false;
}
else
{
szptr += sprintf_s(szptr,SZSTRING_REMAINING_SIZE(szptr),", ");
}
CHECK_REMAINING_SIZE;
out.Shrink(0);
szptr += sprintf_s(szptr,SZSTRING_REMAINING_SIZE(szptr),"%s",PrettyPrintClass(&out,tkConstrType,g_pImport));
CHECK_REMAINING_SIZE;
}
if(ix < NumConstrs) break;
szptr += sprintf_s(szptr,SZSTRING_REMAINING_SIZE(szptr),") ");
if (!hasLiteralTypeParameter || NumConstrs > 1)
{
szptr += sprintf_s(szptr,SZSTRING_REMAINING_SIZE(szptr),") ");
}
CHECK_REMAINING_SIZE;
}
// re-get name, wzUniBuf may not contain it any more
Expand Down
1 change: 1 addition & 0 deletions src/coreclr/inc/corhdr.h
Original file line number Diff line number Diff line change
Expand Up @@ -1504,6 +1504,7 @@ typedef enum CorTokenType
mdtGenericParam = 0x2a000000, //
mdtMethodSpec = 0x2b000000, //
mdtGenericParamConstraint = 0x2c000000,
mdtGenericParamType = 0x2d000000, //

mdtString = 0x70000000, //
mdtName = 0x71000000, //
Expand Down
77 changes: 16 additions & 61 deletions src/coreclr/inc/metamodelpub.h
Original file line number Diff line number Diff line change
Expand Up @@ -1401,54 +1401,8 @@ class NestedClassRec

// Generics


class GenericParamRec
{
METADATA_FIELDS_PROTECTION:
USHORT m_Number; // index; zero = first var
USHORT m_Flags; // index; zero = first var
public:
enum {

COL_Number, // index; zero = first var
COL_Flags, // flags, for future use
COL_Owner, // typeDef/methodDef
COL_Name, // Purely descriptive, not used for binding purposes
COL_Type,
COL_COUNT,
COL_KEY = COL_Owner
};

USHORT GetNumber()
{
LIMITED_METHOD_CONTRACT;

return GET_UNALIGNED_VAL16(&m_Number);
}
void SetNumber(USHORT Number)
{
LIMITED_METHOD_CONTRACT;

m_Number = VAL16(Number);
}

USHORT GetFlags()
{
LIMITED_METHOD_CONTRACT;

return GET_UNALIGNED_VAL16(&m_Flags);
}
void SetFlags(USHORT Flags)
{
LIMITED_METHOD_CONTRACT;

m_Flags = VAL16(Flags);
}
};

// this definition is for reading the old GenericParamRec from a v2.0 assembly.
class GenericParamV2_0Rec
{
METADATA_FIELDS_PROTECTION:
USHORT m_Number; // index; zero = first var
USHORT m_Flags; // index; zero = first var
Expand Down Expand Up @@ -1554,7 +1508,7 @@ class GenericParamConstraintRec
enum {

COL_Owner, // GenericParam
COL_Constraint, // typeDef/Ref/Spec
COL_Constraint, // typeDef/Ref/Spec, can be masked by genericParamTypeMask
COL_COUNT,
COL_KEY = COL_Owner
};
Expand Down Expand Up @@ -1774,20 +1728,21 @@ enum {
#undef MiniMdTable

// List of MiniMd coded token types.
#define MiniMdCodedTokens() \
MiniMdCodedToken(TypeDefOrRef) \
MiniMdCodedToken(HasConstant) \
MiniMdCodedToken(HasCustomAttribute) \
MiniMdCodedToken(HasFieldMarshal) \
MiniMdCodedToken(HasDeclSecurity) \
MiniMdCodedToken(MemberRefParent) \
MiniMdCodedToken(HasSemantic) \
MiniMdCodedToken(MethodDefOrRef) \
MiniMdCodedToken(MemberForwarded) \
MiniMdCodedToken(Implementation) \
MiniMdCodedToken(CustomAttributeType) \
MiniMdCodedToken(ResolutionScope) \
MiniMdCodedToken(TypeOrMethodDef) \
#define MiniMdCodedTokens() \
MiniMdCodedToken(TypeDefOrRef) \
MiniMdCodedToken(TypeDefOrRefOrGpType) \
MiniMdCodedToken(HasConstant) \
MiniMdCodedToken(HasCustomAttribute) \
MiniMdCodedToken(HasFieldMarshal) \
MiniMdCodedToken(HasDeclSecurity) \
MiniMdCodedToken(MemberRefParent) \
MiniMdCodedToken(HasSemantic) \
MiniMdCodedToken(MethodDefOrRef) \
MiniMdCodedToken(MemberForwarded) \
MiniMdCodedToken(Implementation) \
MiniMdCodedToken(CustomAttributeType) \
MiniMdCodedToken(ResolutionScope) \
MiniMdCodedToken(TypeOrMethodDef) \

#undef MiniMdCodedToken
#define MiniMdCodedToken(x) CDTKN_##x,
Expand Down
40 changes: 23 additions & 17 deletions src/coreclr/md/compiler/emit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1657,8 +1657,6 @@ STDMETHODIMP RegMeta::DefineGenericParam( // S_OK or error.
// See if this version of the metadata can do Generics
if (!m_pStgdb->m_MiniMd.SupportsGenerics())
IfFailGo(CLDB_E_INCOMPATIBLE);
if (!m_pStgdb->m_MiniMd.SupportsConstGenerics())
IfFailGo(CLDB_E_INCOMPATIBLE);

if ((tkOwnerType == mdtTypeDef) || (tkOwnerType == mdtMethodDef))
{
Expand Down Expand Up @@ -1740,10 +1738,6 @@ STDMETHODIMP RegMeta::SetGenericParamProps( // S_OK or error.
if (!m_pStgdb->m_MiniMd.SupportsGenerics())
IfFailGo(CLDB_E_INCOMPATIBLE);

// See if this version of the metadata can do Const Generics
if (!m_pStgdb->m_MiniMd.SupportsConstGenerics())
IfFailGo(CLDB_E_INCOMPATIBLE);

if (TypeFromToken(gp) == mdtGenericParam)
{
GenericParamRec *pGenericParam;
Expand Down Expand Up @@ -1782,19 +1776,15 @@ HRESULT RegMeta::_SetGenericParamProps( // S_OK or error.
if ((szName != NULL) && (*szName != 0))
IfFailGo(m_pStgdb->m_MiniMd.PutStringW(TBL_GenericParam, GenericParamRec::COL_Name,
pGenericParam, szName));
// If there is a type, set it
if (tkType != NULL)
IfFailGo(m_pStgdb->m_MiniMd.PutToken(TBL_GenericParam, GenericParamRec::COL_Type,
pGenericParam, tkType));

// If there are new flags, set them.
if (dwParamFlags != (DWORD) -1)
pGenericParam->SetFlags((USHORT)dwParamFlags);

// If there is a new array of constraints, apply it.
if (rtkConstraints != NULL)
// If there is a type or a new array of constraints, apply it.
if (rtkConstraints != NULL || RidFromToken(tkType) != 0)
{
//Clear existing constraints
//Clear existing type and constraints
GenericParamConstraintRec* pGPCRec;
RID ridGPC;
RID rid;
Expand All @@ -1812,19 +1802,35 @@ HRESULT RegMeta::_SetGenericParamProps( // S_OK or error.
IfFailGo(UpdateENCLog(TokenFromRid(ridGPC,mdtGenericParamConstraint)));
}

//Emit new constraints
mdToken* ptk;
for (ptk = rtkConstraints; (ptk != NULL)&&(RidFromToken(*ptk)!=0); ptk++)
if (RidFromToken(tkType) != 0)
{
//Emit type
IfFailGo(m_pStgdb->m_MiniMd.AddGenericParamConstraintRecord(&pGPCRec, &ridGPC));
IfFailGo(m_pStgdb->m_MiniMd.PutCol(TBL_GenericParamConstraint,
GenericParamConstraintRec::COL_Owner,
pGPCRec, RidFromToken(tkGP)));
IfFailGo(m_pStgdb->m_MiniMd.PutToken(TBL_GenericParamConstraint,
GenericParamConstraintRec::COL_Constraint,
pGPCRec, *ptk));
pGPCRec, (tkType & ~mdtTypeSpec) | mdtGenericParamType));
IfFailGo(UpdateENCLog(TokenFromRid(ridGPC,mdtGenericParamConstraint)));
}

if (rtkConstraints != NULL)
{
//Emit new constraints
mdToken* ptk;
for (ptk = rtkConstraints; (ptk != NULL)&&(RidFromToken(*ptk)!=0); ptk++)
{
IfFailGo(m_pStgdb->m_MiniMd.AddGenericParamConstraintRecord(&pGPCRec, &ridGPC));
IfFailGo(m_pStgdb->m_MiniMd.PutCol(TBL_GenericParamConstraint,
GenericParamConstraintRec::COL_Owner,
pGPCRec, RidFromToken(tkGP)));
IfFailGo(m_pStgdb->m_MiniMd.PutToken(TBL_GenericParamConstraint,
GenericParamConstraintRec::COL_Constraint,
pGPCRec, *ptk));
IfFailGo(UpdateENCLog(TokenFromRid(ridGPC,mdtGenericParamConstraint)));
}
}
}
}
else
Expand Down
16 changes: 15 additions & 1 deletion src/coreclr/md/compiler/import.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2847,7 +2847,21 @@ HRESULT RegMeta::GetGenericParamProps( // S_OK or error.
if (ptOwner)
*ptOwner = pMiniMd->getOwnerOfGenericParam(pGenericParamRec);
if (ptType)
*ptType = pMiniMd->SupportsConstGenerics() ? pMiniMd->getTypeOfGenericParam(pGenericParamRec) : NULL;
{
*ptType = NULL;
RID rid;
IfFailGo(pMiniMd->getGenericParamConstraintsForGenericParam(RidFromToken(rd), NULL, &rid));
if (rid != 0)
{
GenericParamConstraintRec* gpcRec;
IfFailGo(pMiniMd->GetGenericParamConstraintRecord(rid, &gpcRec));
mdToken tkType = pMiniMd->getConstraintOfGenericParamConstraint(gpcRec);
if (!IsNilToken(tkType) && (TypeFromToken(tkType) == mdtGenericParamType))
{
*ptType = (tkType & ~mdtGenericParamType) | mdtTypeSpec;
}
}
}
// This call has to be last to set 'hr', so CLDB_S_TRUNCATION is not rewritten with S_OK
if (pchName || szName)
IfFailGo(pMiniMd->getNameOfGenericParam(pGenericParamRec, szName, cchName, pchName));
Expand Down
16 changes: 15 additions & 1 deletion src/coreclr/md/enc/mdinternalrw.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3261,7 +3261,21 @@ HRESULT MDInternalRW::GetGenericParamProps( // S_OK or error.
if (ptOwner)
*ptOwner = m_pStgdb->m_MiniMd.getOwnerOfGenericParam(pGenericParamRec);
if (ptType)
*ptType = m_pStgdb->m_MiniMd.SupportsConstGenerics() ? m_pStgdb->m_MiniMd.getTypeOfGenericParam(pGenericParamRec) : NULL;
{
*ptType = NULL;
RID rid;
IfFailGo(m_pStgdb->m_MiniMd.getGenericParamConstraintsForGenericParam(RidFromToken(rd), NULL, &rid));
if (rid != 0)
{
GenericParamConstraintRec* gpcRec;
IfFailGo(m_pStgdb->m_MiniMd.GetGenericParamConstraintRecord(rid, &gpcRec));
mdToken tkType = m_pStgdb->m_MiniMd.getConstraintOfGenericParamConstraint(gpcRec);
if (!IsNilToken(tkType) && (TypeFromToken(tkType) == mdtGenericParamType))
{
*ptType = (tkType & ~mdtGenericParamType) | mdtTypeSpec;
}
}
}
if (szName != NULL)
{
IfFailGo(m_pStgdb->m_MiniMd.getNameOfGenericParam(pGenericParamRec, szName));
Expand Down
6 changes: 5 additions & 1 deletion src/coreclr/md/enc/metamodelrw.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -310,10 +310,14 @@ ULONG CMiniMdRW::GetTableForToken( // Table index, or -1.
mdToken tkn) // Token to find.
{
ULONG type = TypeFromToken(tkn);

// Get the type -- if a string, no associated table.
if (type >= mdtString)
return (ULONG) -1;
// Type of generic param is TypeSpec
if (type == mdtGenericParamType)
{
type = mdtTypeSpec;
}
// Table number is same as high-byte of token.
ULONG ixTbl = type >> 24;
// Make sure.
Expand Down
16 changes: 3 additions & 13 deletions src/coreclr/md/inc/metamodel.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,7 @@
#define METAMODEL_MAJOR_VER_V2_0 2 // Major version for v2.0
#define METAMODEL_MINOR_VER_V2_0 0 // Minor version for v2.0

#define METAMODEL_MAJOR_VER_V3_0 3 // Major version for v3.0
#define METAMODEL_MINOR_VER_V3_0 0 // Minor version for v3.0

#define METAMODEL_MAJOR_VER 3
#define METAMODEL_MAJOR_VER 2
#define METAMODEL_MINOR_VER 0

// Metadata version number up through Whidbey Beta2
Expand Down Expand Up @@ -558,6 +555,7 @@ class CMiniMdBase : public IMetaModelCommonRO
// use that value to index into an array of token types.
//*****************************************************************************
static const mdToken mdtTypeDefOrRef[3];
static const mdToken mdtTypeDefOrRefOrGpType[4];
static const mdToken mdtHasConstant[3];
static const mdToken mdtHasCustomAttribute[24];
static const mdToken mdtHasFieldMarshal[2];
Expand Down Expand Up @@ -1981,7 +1979,6 @@ template <class Impl> class CMiniMdTemplate : public CMiniMdBase
USHORT _GETFLD(GenericParam,Flags);
mdToken _GETCDTKN(GenericParam,Owner,mdtTypeOrMethodDef);
_GETSTR(GenericParam,Name);
mdToken _GETCDTKN(GenericParam,Type,mdtTypeDefOrRef)

__checkReturn
HRESULT getGenericParamConstraintsForGenericParam(RID rid, RID *pEnd, RID *pFoundRid)
Expand All @@ -1999,21 +1996,14 @@ template <class Impl> class CMiniMdTemplate : public CMiniMdBase

//GenericParamConstraintRec
mdToken _GETTKN(GenericParamConstraint,Owner,mdtGenericParam);
mdToken _GETCDTKN(GenericParamConstraint,Constraint,mdtTypeDefOrRef);
mdToken _GETCDTKN(GenericParamConstraint,Constraint,mdtTypeDefOrRefOrGpType);

BOOL SupportsGenerics()
{
// Only 2.0 of the metadata (and 1.1) support generics
return (m_Schema.m_major >= METAMODEL_MAJOR_VER_V2_0 ||
(m_Schema.m_major == METAMODEL_MAJOR_VER_B1 && m_Schema.m_minor == METAMODEL_MINOR_VER_B1));
}// SupportGenerics

BOOL SupportsConstGenerics()
{
// Only 3.0 of the metadata support const generics
return (m_Schema.m_major >= METAMODEL_MAJOR_VER_V3_0 ||
(m_Schema.m_major == METAMODEL_MAJOR_VER_V3_0 && m_Schema.m_minor >= METAMODEL_MINOR_VER_V3_0));
}// SupportsConstGenerics

protected:
//*****************************************************************************
Expand Down
16 changes: 15 additions & 1 deletion src/coreclr/md/runtime/mdinternalro.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2489,7 +2489,21 @@ HRESULT MDInternalRO::GetGenericParamProps( // S_OK or error.
if (ptOwner)
*ptOwner = m_LiteWeightStgdb.m_MiniMd.getOwnerOfGenericParam(pGenericParamRec);
if (ptType)
*ptType = m_LiteWeightStgdb.m_MiniMd.SupportsConstGenerics() ? m_LiteWeightStgdb.m_MiniMd.getTypeOfGenericParam(pGenericParamRec) : NULL;
{
*ptType = NULL;
RID rid;
IfFailGo(m_LiteWeightStgdb.m_MiniMd.getGenericParamConstraintsForGenericParam(RidFromToken(rd), NULL, &rid));
if (rid != 0)
{
GenericParamConstraintRec* gpcRec;
IfFailGo(m_LiteWeightStgdb.m_MiniMd.GetGenericParamConstraintRecord(rid, &gpcRec));
mdToken tkType = m_LiteWeightStgdb.m_MiniMd.getConstraintOfGenericParamConstraint(gpcRec);
if (!IsNilToken(tkType) && (TypeFromToken(tkType) == mdtGenericParamType))
{
*ptType = (tkType & ~mdtGenericParamType) | mdtTypeSpec;
}
}
}
if (szName != NULL)
{
IfFailGo(m_LiteWeightStgdb.m_MiniMd.getNameOfGenericParam(pGenericParamRec, szName));
Expand Down
Loading

0 comments on commit 5d3da96

Please sign in to comment.