summaryrefslogtreecommitdiff
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
parent829778f99fdfba9460ecf500a5d95641c23af272 (diff)
downloadcoreclr-045335bb661be28cbdffa3b1e2d8ccbc2667fd58.tar.gz
coreclr-045335bb661be28cbdffa3b1e2d8ccbc2667fd58.tar.bz2
coreclr-045335bb661be28cbdffa3b1e2d8ccbc2667fd58.zip
Add generic encoding support to metasig
-rw-r--r--src/vm/binder.cpp101
-rw-r--r--src/vm/binder.h1
-rw-r--r--src/vm/metasig.h6
3 files changed, 62 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);
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 _