[llvm-commits] [vmkit] r52778 - in /vmkit/trunk: include/debug.h lib/N3/VMCore/Assembly.cpp lib/N3/VMCore/Assembly.h lib/N3/VMCore/CLIJit.cpp lib/N3/VMCore/CLISignature.cpp lib/N3/VMCore/Opcodes.cpp lib/N3/VMCore/VMClass.cpp lib/N3/VMCore/VMClass.h lib/N3/VMCore/VirtualTables.cpp
Tilmann Scheller
tilmann.scheller at googlemail.com
Thu Jun 26 02:41:08 PDT 2008
Author: tilmann
Date: Thu Jun 26 04:41:06 2008
New Revision: 52778
URL: http://llvm.org/viewvc/llvm-project?rev=52778&view=rev
Log:
add preliminary support for generic classes to N3
Modified:
vmkit/trunk/include/debug.h
vmkit/trunk/lib/N3/VMCore/Assembly.cpp
vmkit/trunk/lib/N3/VMCore/Assembly.h
vmkit/trunk/lib/N3/VMCore/CLIJit.cpp
vmkit/trunk/lib/N3/VMCore/CLISignature.cpp
vmkit/trunk/lib/N3/VMCore/Opcodes.cpp
vmkit/trunk/lib/N3/VMCore/VMClass.cpp
vmkit/trunk/lib/N3/VMCore/VMClass.h
vmkit/trunk/lib/N3/VMCore/VirtualTables.cpp
Modified: vmkit/trunk/include/debug.h
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/include/debug.h?rev=52778&r1=52777&r2=52778&view=diff
==============================================================================
--- vmkit/trunk/include/debug.h (original)
+++ vmkit/trunk/include/debug.h Thu Jun 26 04:41:06 2008
@@ -10,6 +10,12 @@
#ifndef DEBUG_H
#define DEBUG_H
+#define DEBUG 0
+#define N3_COMPILE 0 //2
+#define N3_EXECUTE 0
+#define DEBUG_LOAD 0 //2
+#define N3_LOAD 0 //1
+
#define ESC "\033["
#define COLOR_NORMAL ""
#define END "m"
Modified: vmkit/trunk/lib/N3/VMCore/Assembly.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/N3/VMCore/Assembly.cpp?rev=52778&r1=52777&r2=52778&view=diff
==============================================================================
--- vmkit/trunk/lib/N3/VMCore/Assembly.cpp (original)
+++ vmkit/trunk/lib/N3/VMCore/Assembly.cpp Thu Jun 26 04:41:06 2008
@@ -215,6 +215,11 @@
STRING(CONSTANT_FILE_NAME)
BLOB(CONSTANT_FILE_HASH_VALUE))
+DEF_TABLE_MASK(METHOD_GenericParam, 4,
+ INT16(CONSTANT_GENERIC_PARAM_NUMBER)
+ INT16(CONSTANT_GENERIC_PARAM_FLAGS)
+ TYPE_OR_METHODDEF(CONSTANT_GENERIC_PARAM_OWNER)
+ STRING(CONSTANT_GENERIC_PARAM_NAME))
void Header::print(mvm::PrintBuffer* buf) const {
buf->write("Header<>");
@@ -332,7 +337,52 @@
VMClass* cl = (VMClass*)loadedNameClasses->lookupOrCreate(CC, this, classDup);
loadedTokenClasses->lookupOrCreate(token, cl);
cl->token = token;
- cl->assembly = this;
+ return cl;
+}
+
+static VMCommonClass* genClassDup(ClassNameCmp &cmp, Assembly* ass) {
+ VMClass* cl = gc_new(VMGenericClass)();
+ cl->initialise(ass->vm, false);
+ cl->name = cmp.name;
+ cl->nameSpace = cmp.nameSpace;
+ cl->virtualTracer = 0;
+ cl->staticInstance = 0;
+ cl->virtualInstance = 0;
+ cl->virtualType = 0;
+ cl->super = 0;
+ cl->status = hashed;
+ cl->assembly = ass;
+ return cl;
+}
+
+VMGenericClass* Assembly::constructGenericClass(const UTF8* name,
+ const UTF8* nameSpace, std::vector<VMCommonClass*> genArgs, uint32 token) {
+ uint32 size = name->size + 2;
+ sint32 i = 0;
+ for (std::vector<VMCommonClass*>::iterator it = genArgs.begin(), e = genArgs.end(); it!= e; ++it) {
+ size += (*it)->name->size + 1;
+ }
+ uint16* buf = (uint16*) alloca(sizeof(uint16) * size);
+ for (i = 0; i < name->size; i++) {
+ buf[i] = name->at(i);
+ }
+ buf[i++] = '<';
+ for (std::vector<VMCommonClass*>::iterator it = genArgs.begin(), e = genArgs.end(); it!= e; ++it) {
+ for (int j = 0; j < (*it)->name->size; i++, j++) {
+ buf[i] = (*it)->name->at(j);
+ }
+ buf[i++] = ',';
+ }
+ buf[i] = '>';
+ const UTF8* genName = UTF8::readerConstruct(VMThread::get()->vm, buf, size);
+ printf("%s\n", genName->printString());
+
+ ClassNameCmp CC(genName, nameSpace);
+ VMGenericClass* cl = (VMGenericClass*) loadedNameClasses->lookupOrCreate(CC, this, genClassDup);
+
+ cl->genericParams = genArgs; // TODO GC safe?
+ cl->token = token;
+
return cl;
}
@@ -377,6 +427,7 @@
ass->assemblyRefs = 0;
ass->isRead = false;
ass->name = name;
+ ass->currGenericClass = 0;
return ass;
}
@@ -429,7 +480,7 @@
unimplemented, // 0x27
METHOD_ManifestResource, // 0x28
METHOD_NestedClass, // 0x29
- unimplemented, // 0x2A
+ METHOD_GenericParam, // 0x2A
METHOD_MethodSpec, // 0x2B
METHOD_GenericParamConstraint,// 0x2C
unimplemented,
@@ -496,7 +547,7 @@
"unimplemented", // 0x27
"METHOD_ManifestResource", // 0x28
"METHOD_NestedClass", // 0x29
- "unimplemented", // 0x2A
+ "METHOD_GenericParam", // 0x2A
"METHOD_MethodSpec", // 0x2B
"METHOD_GenericParamConstraint", // 0x2C
"unimplemented",
@@ -909,6 +960,10 @@
}
VMClass* Assembly::readTypeDef(N3* vm, uint32 index) {
+ return readTypeDef(vm, index, (std::vector<VMCommonClass*>) 0);
+}
+
+VMClass* Assembly::readTypeDef(N3* vm, uint32 index, std::vector<VMCommonClass*> genArgs) {
uint32 token = (CONSTANT_TypeDef << 24) + index;
uint32 stringOffset = CLIHeader->stringStream->realOffset;
@@ -929,9 +984,18 @@
//Table* methodTable = CLIHeader->tables[CONSTANT_MethodDef];
//uint32 methodSize = methodTable->rowsNumber;
- VMClass* type = constructClass(readString(vm, name + stringOffset),
+ VMClass* type;
+
+ if (genArgs == (std::vector<VMCommonClass*>) 0) {
+ type = constructClass(readString(vm, name + stringOffset),
+ readString(vm, nameSpace + stringOffset),
+ token);
+ } else {
+ // generic type
+ type = constructGenericClass(readString(vm, name + stringOffset),
readString(vm, nameSpace + stringOffset),
- token);
+ genArgs, token);
+ }
type->vm = vm;
@@ -991,10 +1055,15 @@
}
}
+VMCommonClass* Assembly::loadType(N3* vm, uint32 token, bool resolve,
+ bool resolveStatic, bool clinit, bool dothrow) {
+ return loadType(vm, token, resolve, resolveStatic, clinit, dothrow, (std::vector<VMCommonClass*>) 0);
+}
VMCommonClass* Assembly::loadType(N3* vm, uint32 token, bool resolve,
- bool resolveStatic, bool clinit, bool dothrow) {
+ bool resolveStatic, bool clinit, bool dothrow,
+ std::vector<VMCommonClass*> genArgs) {
VMCommonClass* type = lookupClassFromToken(token);
if (!type || type->status == hashed) {
@@ -1002,7 +1071,7 @@
uint32 index = token & 0xffff;
if (table == CONSTANT_TypeDef) {
- type = readTypeDef(vm, index);
+ type = readTypeDef(vm, index, genArgs);
} else if (table == CONSTANT_TypeRef) {
type = readTypeRef(vm, index);
} else if (table == CONSTANT_TypeSpec) {
@@ -1027,6 +1096,9 @@
}
void Assembly::readClass(VMCommonClass* cl) {
+ // temporarily store the class being read in case it is a generic class
+ currGenericClass = dynamic_cast<VMGenericClass*>(cl);
+
uint32 index = cl->token & 0xffff;
Table* typeTable = CLIHeader->tables[CONSTANT_TypeDef];
uint32 typeSize = typeTable->rowsNumber;
@@ -1077,6 +1149,9 @@
}
}
}
+
+ // we have stopped reading a generic class
+ currGenericClass = 0;
}
void Assembly::readCustomAttributes(uint32 offset, std::vector<llvm::GenericValue>& args, VMMethod* meth) {
@@ -1233,6 +1308,8 @@
if (rva) {
meth->offset = textSection->rawAddress +
(rva - textSection->virtualAddress);
+ } else {
+ meth->offset = 0;
}
if (paramList && paramTable != 0 && paramList <= paramSize) {
@@ -1580,16 +1657,26 @@
case 3: VMThread::get()->vm->error("implement me %d", table); break;
case 4: {
VMClass* type = (VMClass*)readTypeSpec(vm, index);
- VMMethod* meth = gc_new(VMMethod)();
- bool virt = extractMethodSignature(offset, type, args);
- bool structReturn = false;
- const llvm::FunctionType* signature = VMMethod::resolveSignature(args, virt, structReturn);
- meth->_signature = signature;
- meth->classDef = type;
- meth->name = name;
- meth->virt = virt;
- meth->structReturn = structReturn;
- return meth;
+
+ VMGenericClass* genClass = dynamic_cast<VMGenericClass*>(type);
+
+ if (genClass) {
+ bool virt = extractMethodSignature(offset, type, args);
+ VMMethod* meth = type->lookupMethod(name, args, !virt, true);
+ return meth;
+ } else {
+ VMMethod* meth = gc_new(VMMethod)();
+ bool virt = extractMethodSignature(offset, type, args);
+ bool structReturn = false;
+ const llvm::FunctionType* signature = VMMethod::resolveSignature(args, virt, structReturn);
+ meth->_signature = signature;
+ meth->classDef = type;
+ meth->name = name;
+ meth->virt = virt;
+ meth->structReturn = structReturn;
+ meth->parameters = args; // TODO check whether this fix is correct
+ return meth;
+ }
}
default:
VMThread::get()->vm->error("unknown MemberRefParent tag %d", table);
Modified: vmkit/trunk/lib/N3/VMCore/Assembly.h
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/N3/VMCore/Assembly.h?rev=52778&r1=52777&r2=52778&view=diff
==============================================================================
--- vmkit/trunk/lib/N3/VMCore/Assembly.h (original)
+++ vmkit/trunk/lib/N3/VMCore/Assembly.h Thu Jun 26 04:41:06 2008
@@ -42,6 +42,7 @@
class UTF8;
class VirtualMachine;
class VMClass;
+class VMGenericClass;
class VMClassArray;
class VMClassPointer;
class VMCommonClass;
@@ -142,6 +143,10 @@
uint32 dims);
VMClass* constructClass(const UTF8* name,
const UTF8* nameSpace, uint32 token);
+ VMGenericClass* constructGenericClass(const UTF8* name,
+ const UTF8* nameSpace,
+ std::vector<VMCommonClass*> genArgs,
+ uint32 token);
VMField* constructField(VMClass* cl, const UTF8* name,
VMCommonClass* signature, uint32 token);
VMMethod* constructMethod(VMClass* cl, const UTF8* name,
@@ -155,6 +160,9 @@
ClassTokenMap* loadedTokenClasses;
MethodTokenMap* loadedTokenMethods;
FieldTokenMap* loadedTokenFields;
+
+ // helper which points to the current generic class while it is being read in readClass()
+ VMGenericClass* currGenericClass;
mvm::Lock* lockVar;
mvm::Cond* condVar;
@@ -202,6 +210,8 @@
uint32 getTypeDefTokenFromMethod(uint32 token);
VMCommonClass* loadType(N3* vm, uint32 token, bool resolveFunc, bool resolve,
bool clinit, bool dothrow);
+ VMCommonClass* loadType(N3* vm, uint32 token, bool resolveFunc, bool resolve,
+ bool clinit, bool dothrow, std::vector<VMCommonClass*> genArgs);
VMCommonClass* loadTypeFromName(const UTF8* name, const UTF8* nameSpace,
bool resolveFunc, bool resolve,
@@ -213,6 +223,7 @@
VMField* readField(uint32 index, VMCommonClass* cl);
Param* readParam(uint32 index, VMMethod* meth);
VMClass* readTypeDef(N3* vm, uint32 index);
+ VMClass* readTypeDef(N3* vm, uint32 index, std::vector<VMCommonClass*> genArgs);
VMCommonClass* readTypeSpec(N3* vm, uint32 index);
Assembly* readAssemblyRef(N3* vm, uint32 index);
VMCommonClass* readTypeRef(N3* vm, uint32 index);
@@ -704,6 +715,11 @@
#define CONSTANT_FILE_NAME 1
#define CONSTANT_FILE_HASH_VALUE 2
+#define CONSTANT_GENERIC_PARAM_NUMBER 0
+#define CONSTANT_GENERIC_PARAM_FLAGS 1
+#define CONSTANT_GENERIC_PARAM_OWNER 2
+#define CONSTANT_GENERIC_PARAM_NAME 3
+
} // end namespace n3
#endif
Modified: vmkit/trunk/lib/N3/VMCore/CLIJit.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/N3/VMCore/CLIJit.cpp?rev=52778&r1=52777&r2=52778&view=diff
==============================================================================
--- vmkit/trunk/lib/N3/VMCore/CLIJit.cpp (original)
+++ vmkit/trunk/lib/N3/VMCore/CLIJit.cpp Thu Jun 26 04:41:06 2008
@@ -7,9 +7,9 @@
//
//===----------------------------------------------------------------------===//
-#define DEBUG 0
-#define N3_COMPILE 0
-#define N3_EXECUTE 0
+//#define DEBUG 0
+//#define N3_COMPILE 0
+//#define N3_EXECUTE 0
#include "debug.h"
#include "types.h"
@@ -458,12 +458,23 @@
CLIJit* jit = gc_new(CLIJit)();
jit->compilingClass = meth->classDef;
jit->compilingMethod = meth;
+
+ // save current class in case of recursive calls to compile()
+ VMGenericClass* old = jit->compilingClass->assembly->currGenericClass;
+ // temporarily store the class being compiled in case it is a generic class
+ jit->compilingClass->assembly->currGenericClass = dynamic_cast<VMGenericClass*>(jit->compilingClass);
+
+
jit->unifiedUnreachable = unifiedUnreachable;
jit->inlineMethods = inlineMethods;
jit->inlineMethods[meth] = true;
Instruction* ret = jit->inlineCompile(llvmFunction, currentBlock,
currentExceptionBlock, args);
inlineMethods[meth] = false;
+
+ // restore saved class
+ jit->compilingClass = old;
+
return ret;
}
@@ -915,7 +926,7 @@
Function* CLIJit::compileNative() {
PRINT_DEBUG(N3_COMPILE, 1, COLOR_NORMAL, "native compile %s\n",
compilingMethod->printString());
-
+
const FunctionType *funcType = compilingMethod->getSignature();
Function* func = llvmFunction = compilingMethod->methPtr;
@@ -1409,6 +1420,11 @@
jit->compilingClass = cl;
jit->compilingMethod = meth;
+ // save current class in case of recursive calls to compile()
+ VMGenericClass* old = cl->assembly->currGenericClass;
+ // temporarily store the class being compiled in case it is a generic class
+ cl->assembly->currGenericClass = dynamic_cast<VMGenericClass*>(cl);
+
meth->getSignature();
if (isInternal(meth->implFlags)) {
return jit->compileNative();
@@ -1417,6 +1433,9 @@
} else {
return jit->compileFatOrTiny();
}
+
+ // restore saved class
+ cl->assembly->currGenericClass = old;
}
llvm::Function *VMMethod::compiledPtr() {
Modified: vmkit/trunk/lib/N3/VMCore/CLISignature.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/N3/VMCore/CLISignature.cpp?rev=52778&r1=52777&r2=52778&view=diff
==============================================================================
--- vmkit/trunk/lib/N3/VMCore/CLISignature.cpp (original)
+++ vmkit/trunk/lib/N3/VMCore/CLISignature.cpp Thu Jun 26 04:41:06 2008
@@ -136,9 +136,11 @@
}
static VMCommonClass* METHOD_ElementTypeVar(uint32 op, Assembly* ass, uint32& offset) {
+ uint32 number = ass->uncompressSignature(offset);
+ return ass->currGenericClass->genericParams[number];
//uint32 type = READ_U4(ass->bytes, offset);
- VMThread::get()->vm->error("implement me");
- return 0;
+ //VMThread::get()->vm->error("implement me");
+ //return 0;
}
static VMCommonClass* METHOD_ElementTypeArray(uint32 op, Assembly* ass, uint32& offset) {
@@ -167,8 +169,54 @@
}
static VMCommonClass* METHOD_ElementTypeGenericInst(uint32 op, Assembly* ass, uint32& offset) {
- VMThread::get()->vm->error("implement me");
- return 0;
+ // offset points to (CLASS | VALUETYPE) TypeDefOrRefEncoded
+
+ // skip generic type definition
+ offset++; // this is (CLASS | VALUETYPE)
+
+ // save starting offset for later use
+ uint32 genericTypeOffset = offset;
+
+ ass->uncompressSignature(offset); // TypeDefOrRefEncoded
+
+ //VMCommonClass* cl = ass->exploreType(offset);
+
+ uint32 argCount = ass->uncompressSignature(offset);
+
+ std::vector<VMCommonClass*> args;
+
+ // Get generic arguments.
+ for (uint32 i = 0; i < argCount; ++i) {
+ args.push_back(ass->exploreType(offset));
+ }
+
+ // save offset
+ uint32 endOffset = offset;
+ // restore starting offset
+ offset = genericTypeOffset;
+
+ // TypeDefOrRefEncoded
+ uint32 value = ass->uncompressSignature(offset);
+ uint32 table = value & 3;
+ uint32 index = value >> 2;
+ uint32 token = 0;
+
+ switch (table) {
+ case 0: table = CONSTANT_TypeDef; break;
+ case 1: table = CONSTANT_TypeRef; break;
+ case 2: table = CONSTANT_TypeSpec; break;
+ default:
+ VMThread::get()->vm->error("unknown TypeDefOrRefEncoded %d", index);
+ break;
+ }
+
+ token = (table << 24) + index;
+ VMCommonClass* cl = ass->loadType((N3*)(VMThread::get()->vm), token, false,
+ false, false, true, args);
+ // restore endOffset
+ offset = endOffset;
+
+ return cl;
}
static VMCommonClass* METHOD_ElementTypeTypedByRef(uint32 op, Assembly* ass, uint32& offset) {
Modified: vmkit/trunk/lib/N3/VMCore/Opcodes.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/N3/VMCore/Opcodes.cpp?rev=52778&r1=52777&r2=52778&view=diff
==============================================================================
--- vmkit/trunk/lib/N3/VMCore/Opcodes.cpp (original)
+++ vmkit/trunk/lib/N3/VMCore/Opcodes.cpp Thu Jun 26 04:41:06 2008
@@ -7,9 +7,9 @@
//
//===----------------------------------------------------------------------===//
-#define DEBUG 0
-#define N3_COMPILE 0
-#define N3_EXECUTE 0
+//#define DEBUG 0
+//#define N3_COMPILE 0
+//#define N3_EXECUTE 0
#include <string.h>
Modified: vmkit/trunk/lib/N3/VMCore/VMClass.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/N3/VMCore/VMClass.cpp?rev=52778&r1=52777&r2=52778&view=diff
==============================================================================
--- vmkit/trunk/lib/N3/VMCore/VMClass.cpp (original)
+++ vmkit/trunk/lib/N3/VMCore/VMClass.cpp Thu Jun 26 04:41:06 2008
@@ -395,6 +395,7 @@
void VMCommonClass::resolveType(bool stat, bool clinit) {
VMCommonClass* cl = this;
+ //printf("*** Resolving: %s\n", cl->printString());
if (cl->status < resolved) {
cl->aquire();
int status = cl->status;
@@ -815,3 +816,7 @@
}
return true;
}
+
+void VMGenericClass::print(mvm::PrintBuffer* buf) const {
+ buf->write("Generic Class");
+}
Modified: vmkit/trunk/lib/N3/VMCore/VMClass.h
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/N3/VMCore/VMClass.h?rev=52778&r1=52777&r2=52778&view=diff
==============================================================================
--- vmkit/trunk/lib/N3/VMCore/VMClass.h (original)
+++ vmkit/trunk/lib/N3/VMCore/VMClass.h Thu Jun 26 04:41:06 2008
@@ -147,6 +147,15 @@
uint32 explicitLayoutSize;
};
+class VMGenericClass : public VMClass {
+public:
+ static VirtualTable* VT;
+ virtual void print(mvm::PrintBuffer* buf) const;
+ virtual void TRACER;
+
+ std::vector<VMCommonClass*> genericParams;
+};
+
class VMClassArray : public VMCommonClass {
public:
static VirtualTable* VT;
Modified: vmkit/trunk/lib/N3/VMCore/VirtualTables.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/N3/VMCore/VirtualTables.cpp?rev=52778&r1=52777&r2=52778&view=diff
==============================================================================
--- vmkit/trunk/lib/N3/VMCore/VirtualTables.cpp (original)
+++ vmkit/trunk/lib/N3/VMCore/VirtualTables.cpp Thu Jun 26 04:41:06 2008
@@ -40,6 +40,7 @@
INIT(UTF8);
INIT(VMCommonClass);
INIT(VMClass);
+ INIT(VMGenericClass);
INIT(VMClassArray);
INIT(VMClassPointer);
INIT(VMMethod);
@@ -169,6 +170,11 @@
outerClass->MARK_AND_TRACE;
}
+void VMGenericClass::TRACER {
+ VMClass::PARENT_TRACER;
+ TRACE_VECTOR(VMCommonClass*, genericParams, std::allocator);
+}
+
void VMClassArray::TRACER {
VMCommonClass::PARENT_TRACER;
baseClass->MARK_AND_TRACE;
More information about the llvm-commits
mailing list