diff options
author | Jan Kotas <jkotas@microsoft.com> | 2017-07-28 11:53:01 -0400 |
---|---|---|
committer | Stephen Toub <stoub@microsoft.com> | 2017-07-28 11:53:01 -0400 |
commit | 045335bb661be28cbdffa3b1e2d8ccbc2667fd58 (patch) | |
tree | f13c7e41b14542f2af9081265db7b3a32516bd69 /src/vm/binder.cpp | |
parent | 829778f99fdfba9460ecf500a5d95641c23af272 (diff) | |
download | coreclr-045335bb661be28cbdffa3b1e2d8ccbc2667fd58.tar.gz coreclr-045335bb661be28cbdffa3b1e2d8ccbc2667fd58.tar.bz2 coreclr-045335bb661be28cbdffa3b1e2d8ccbc2667fd58.zip |
Add generic encoding support to metasig
Diffstat (limited to 'src/vm/binder.cpp')
-rw-r--r-- | src/vm/binder.cpp | 101 |
1 files changed, 55 insertions, 46 deletions
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); |