add basic support for MethodSpecs
llvm-svn: 54126
diff --git a/vmkit/lib/N3/VMCore/Assembly.cpp b/vmkit/lib/N3/VMCore/Assembly.cpp
index 27a23de..47ba453 100644
--- a/vmkit/lib/N3/VMCore/Assembly.cpp
+++ b/vmkit/lib/N3/VMCore/Assembly.cpp
@@ -1754,6 +1754,7 @@
VMMethod* Assembly::readMethodSpec(uint32 token) {
uint32 index = token & 0xffff;
+ uint32 blobOffset = CLIHeader->blobStream->realOffset;
Table* methodTable = CLIHeader->tables[CONSTANT_MethodSpec];
uint32* methodArray = (uint32*) alloca(sizeof(uint32) * methodTable->rowSize);
@@ -1763,6 +1764,27 @@
uint32 method = methodArray[CONSTANT_METHOD_SPEC_METHOD];
uint32 instantiation = methodArray[CONSTANT_METHOD_SPEC_INSTANTIATION];
+ uint32 offset = blobOffset + instantiation;
+
+ std::vector<VMCommonClass*> genArgs;
+ methodSpecSignature(offset, genArgs);
+
+ uint32 table = method & 1;
+ index = method >> 1;
+
+ uint32 methodToken;
+
+ switch (table) {
+ case 0 : {
+ methodToken = index + (CONSTANT_MethodDef << 24);
+ break;
+ }
+ case 1 : {
+ methodToken = index + (CONSTANT_MemberRef << 24);
+ return readMemberRefAsMethod(methodToken);
+ }
+ }
+
VMThread::get()->vm->error("MethodSpec");
// return NULL;
return (VMMethod*) (method ^ instantiation);
diff --git a/vmkit/lib/N3/VMCore/Assembly.h b/vmkit/lib/N3/VMCore/Assembly.h
index da52f7b..9896c18 100644
--- a/vmkit/lib/N3/VMCore/Assembly.h
+++ b/vmkit/lib/N3/VMCore/Assembly.h
@@ -234,6 +234,8 @@
bool isGenericMethod(uint32& offset);
void localVarSignature(uint32& offset,
std::vector<VMCommonClass*>& locals);
+ void methodSpecSignature(uint32& offset,
+ std::vector<VMCommonClass*>& genArgs);
VMCommonClass* extractFieldSignature(uint32& offset);
VMCommonClass* extractTypeInSignature(uint32& offset);
VMCommonClass* exploreType(uint32& offset);
diff --git a/vmkit/lib/N3/VMCore/CLISignature.cpp b/vmkit/lib/N3/VMCore/CLISignature.cpp
index 938d020..4176d63 100644
--- a/vmkit/lib/N3/VMCore/CLISignature.cpp
+++ b/vmkit/lib/N3/VMCore/CLISignature.cpp
@@ -394,6 +394,22 @@
return callingConvention & CONSTANT_Generic ? true : false;
}
+void Assembly::methodSpecSignature(uint32& offset,
+ std::vector<VMCommonClass*>& genArgs) {
+ uncompressSignature(offset); // count
+ uint32 genericSig = uncompressSignature(offset);
+
+ if (genericSig != 0x0a) {
+ VMThread::get()->vm->error("unknown methodSpec sig %x", genericSig);
+ }
+
+ uint32 genArgCount = uncompressSignature(offset);
+
+ for (uint32 i = 0; i < genArgCount; i++) {
+ genArgs.push_back(exploreType(offset));
+ }
+}
+
void Assembly::localVarSignature(uint32& offset,
std::vector<VMCommonClass*>& locals) {
//uint32 count =