From 045335bb661be28cbdffa3b1e2d8ccbc2667fd58 Mon Sep 17 00:00:00 2001 From: Jan Kotas Date: Fri, 28 Jul 2017 11:53:01 -0400 Subject: Add generic encoding support to metasig --- src/vm/binder.cpp | 101 +++++++++++++++++++++++++++++------------------------- src/vm/binder.h | 1 + src/vm/metasig.h | 6 ++++ 3 files changed, 62 insertions(+), 46 deletions(-) (limited to 'src') diff --git a/src/vm/binder.cpp b/src/vm/binder.cpp index 9ce1584c31..6a60712e3f 100644 --- a/src/vm/binder.cpp +++ b/src/vm/binder.cpp @@ -311,6 +311,58 @@ Signature MscorlibBinder::GetSignatureLocal(LPHARDCODEDMETASIG pHardcodedSig) #ifndef DACCESS_COMPILE +bool MscorlibBinder::ConvertType(const BYTE*& pSig, SigBuilder * pSigBuilder) +{ + bool bSomethingResolved = false; + + CorElementType type = (CorElementType)*pSig++; + + switch (type) + { + case ELEMENT_TYPE_GENERICINST: + { + pSigBuilder->AppendElementType(type); + if (ConvertType(pSig, pSigBuilder)) + bSomethingResolved = true; + int arity = *pSig++; + pSigBuilder->AppendData(arity); + for (int i = 0; i < arity; i++) + { + if (ConvertType(pSig, pSigBuilder)) + bSomethingResolved = true; + } + } + break; + + case ELEMENT_TYPE_BYREF: + case ELEMENT_TYPE_PTR: + case ELEMENT_TYPE_SZARRAY: + pSigBuilder->AppendElementType(type); + if (ConvertType(pSig, pSigBuilder)) + bSomethingResolved = true; + break; + + case ELEMENT_TYPE_CLASS: + case ELEMENT_TYPE_VALUETYPE: + { + // The binder class id may overflow 1 byte. Use 2 bytes to encode it. + BinderClassID id = (BinderClassID)(*pSig + 0x100 * *(pSig + 1)); + pSig += 2; + + pSigBuilder->AppendElementType(type); + pSigBuilder->AppendToken(GetClassLocal(id)->GetCl()); + bSomethingResolved = true; + } + break; + + default: + pSigBuilder->AppendElementType(type); + break; + } + + return bSomethingResolved; +} + //------------------------------------------------------------------ // Resolve type references in the hardcoded metasig. // Returns a new signature with type refences resolved. @@ -327,7 +379,7 @@ void MscorlibBinder::BuildConvertedSignature(const BYTE* pSig, SigBuilder * pSig unsigned argCount; unsigned callConv; - INDEBUG(bool bSomethingResolved = false;) + bool bSomethingResolved = false; // calling convention callConv = *pSig++; @@ -346,51 +398,8 @@ void MscorlibBinder::BuildConvertedSignature(const BYTE* pSig, SigBuilder * pSig // <= because we want to include the return value or the field for (unsigned i = 0; i <= argCount; i++) { - - for (;;) { - BinderClassID id = CLASS__NIL; - bool again = false; - - CorElementType type = (CorElementType)*pSig++; - - switch (type) - { - case ELEMENT_TYPE_BYREF: - case ELEMENT_TYPE_PTR: - case ELEMENT_TYPE_SZARRAY: - again = true; - break; - - case ELEMENT_TYPE_CLASS: - case ELEMENT_TYPE_VALUETYPE: - // The binder class id may overflow 1 byte. Use 2 bytes to encode it. - id = (BinderClassID) (*pSig + 0x100 * *(pSig + 1)); - pSig += 2; - break; - - case ELEMENT_TYPE_VOID: - if (i != 0) { - if (pSig[-2] != ELEMENT_TYPE_PTR) - THROW_BAD_FORMAT(BFA_ONLY_VOID_PTR_IN_ARGS, (Module*)NULL); // only pointer to void allowed in arguments - } - break; - - default: - break; - } - - pSigBuilder->AppendElementType(type); - - if (id != CLASS__NIL) - { - pSigBuilder->AppendToken(GetClassLocal(id)->GetCl()); - - INDEBUG(bSomethingResolved = true;) - } - - if (!again) - break; - } + if (ConvertType(pSig, pSigBuilder)) + bSomethingResolved = true; } _ASSERTE(bSomethingResolved); diff --git a/src/vm/binder.h b/src/vm/binder.h index 8e26bdd255..ad80292ea0 100644 --- a/src/vm/binder.h +++ b/src/vm/binder.h @@ -277,6 +277,7 @@ private: Signature GetSignatureLocal(LPHARDCODEDMETASIG pHardcodedSig); + bool ConvertType(const BYTE*& pSig, SigBuilder * pSigBuilder); void BuildConvertedSignature(const BYTE* pSig, SigBuilder * pSigBuilder); const BYTE* ConvertSignature(LPHARDCODEDMETASIG pHardcodedSig, const BYTE* pSig); diff --git a/src/vm/metasig.h b/src/vm/metasig.h index c2dc42fb9d..f8d9cfe5e1 100644 --- a/src/vm/metasig.h +++ b/src/vm/metasig.h @@ -56,6 +56,7 @@ // T -- TypedReference -- TypedReference // G -- -- Generic type variable // M -- -- Generic method variable +// GI -- -- Generic type instantiation // //#DEFINE_METASIG @@ -128,6 +129,8 @@ #define G(n) METASIG_ATOM(ELEMENT_TYPE_VAR) METASIG_ATOM(n) #define M(n) METASIG_ATOM(ELEMENT_TYPE_MVAR) METASIG_ATOM(n) +#define GI(type, n, x) METASIG_ATOM(ELEMENT_TYPE_GENERICINST) type METASIG_ATOM(n) x + // The references to other types have special definition in some cases #ifndef C #define C(x) METASIG_ATOM(ELEMENT_TYPE_CLASS) METASIG_ATOM(CLASS__ ## x % 0x100) METASIG_ATOM(CLASS__ ## x / 0x100) @@ -145,6 +148,8 @@ #define G(n) METASIG_ATOM(ELEMENT_TYPE_VAR) #define M(n) METASIG_ATOM(ELEMENT_TYPE_MVAR) +#define GI(type, n, x) METASIG_ATOM(ELEMENT_TYPE_GENERICINST) + // The references to other types have special definition in some cases #ifndef C #define C(x) METASIG_ATOM(ELEMENT_TYPE_CLASS) @@ -608,6 +613,7 @@ DEFINE_METASIG_T(IM(IAsyncResult_RetVoid, C(IASYNCRESULT), v)) #undef T #undef G #undef M +#undef GI #undef _ -- cgit v1.2.3