summaryrefslogtreecommitdiff
path: root/src/vm/binder.cpp
diff options
context:
space:
mode:
authorJan Kotas <jkotas@microsoft.com>2017-07-28 11:53:01 -0400
committerStephen Toub <stoub@microsoft.com>2017-07-28 11:53:01 -0400
commit045335bb661be28cbdffa3b1e2d8ccbc2667fd58 (patch)
treef13c7e41b14542f2af9081265db7b3a32516bd69 /src/vm/binder.cpp
parent829778f99fdfba9460ecf500a5d95641c23af272 (diff)
downloadcoreclr-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.cpp101
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);