[vmkit-commits] [vmkit] r54579 - in /vmkit/trunk/lib/N3/VMCore: Assembly.cpp Assembly.h CLIJit.cpp CLISignature.cpp N3Initialise.cpp Opcodes.cpp VMArray.cpp VMArray.h VMClass.cpp VMClass.h VMThread.cpp VMThread.h VirtualTables.cpp
Tilmann Scheller
tilmann.scheller at googlemail.com
Sat Aug 9 03:23:36 PDT 2008
Author: tilmann
Date: Sat Aug 9 05:23:35 2008
New Revision: 54579
URL: http://llvm.org/viewvc/llvm-project?rev=54579&view=rev
Log:
add support for generic methods to N3
fix bug in box instruction
Modified:
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/N3Initialise.cpp
vmkit/trunk/lib/N3/VMCore/Opcodes.cpp
vmkit/trunk/lib/N3/VMCore/VMArray.cpp
vmkit/trunk/lib/N3/VMCore/VMArray.h
vmkit/trunk/lib/N3/VMCore/VMClass.cpp
vmkit/trunk/lib/N3/VMCore/VMClass.h
vmkit/trunk/lib/N3/VMCore/VMThread.cpp
vmkit/trunk/lib/N3/VMCore/VMThread.h
vmkit/trunk/lib/N3/VMCore/VirtualTables.cpp
Modified: vmkit/trunk/lib/N3/VMCore/Assembly.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/N3/VMCore/Assembly.cpp?rev=54579&r1=54578&r2=54579&view=diff
==============================================================================
--- vmkit/trunk/lib/N3/VMCore/Assembly.cpp (original)
+++ vmkit/trunk/lib/N3/VMCore/Assembly.cpp Sat Aug 9 05:23:35 2008
@@ -420,17 +420,40 @@
return meth;
}
+static VMGenericMethod* genMethodDup(uint32& key, Assembly* ass) {
+ VMGenericMethod* meth = gc_new(VMGenericMethod)();
+ meth->token = key;
+ meth->canBeInlined = false;
+ return meth;
+}
+
VMMethod* Assembly::constructMethod(VMClass* cl, const UTF8* name,
- uint32 token) {
+ uint32 token, bool generic) {
VMMethod* meth;
- if (VMThread::get()->currGenericClass == 0) {
+ if (VMThread::get()->currGenericClass == 0 && generic == false) {
// we are not reading a generic class
meth = loadedTokenMethods->lookupOrCreate(token, this, methodDup);
} else {
- // we are reading a generic class, don't add a reference
+ // we are reading a generic class or a generic method, don't add a reference
// to the loadedTokenMethods map
meth = methodDup(token, this);
+
+ if (generic) {
+ // we are reading a generic method
+ if (VMThread::get()->genMethodInstantiation == NULL) {
+ cl->genericMethods.push_back(meth);
+ } else {
+ VMGenericMethod* genMethod = genMethodDup(token, this);
+ genMethod->genericParams = *VMThread::get()->genMethodInstantiation;
+ meth = genMethod;
+ if (isStatic(meth->flags)) {
+ cl->staticMethods.push_back(meth);
+ } else {
+ cl->virtualMethods.push_back(meth);
+ }
+ }
+ }
}
meth->classDef = cl;
@@ -1323,43 +1346,42 @@
uint32 paramList = methArray[CONSTANT_METHODDEF_PARAMLIST];
uint32 offset = blobOffset + signature;
-
- if (isGenericMethod(offset)) {
- // generic methods are read on instantiation
- return NULL;
+
+ VMMethod* meth =
+ constructMethod((VMClass*)cl, readString(cl->vm, (name + stringOffset)),
+ token, isGenericMethod(offset));
+
+ offset = blobOffset + signature;
+
+ VMGenericMethod* tmp = VMThread::get()->currGenericMethod;
+ VMThread::get()->currGenericMethod = dynamic_cast<VMGenericMethod*>(meth);
+ meth->virt = extractMethodSignature(offset, cl, meth->parameters);
+ VMThread::get()->currGenericMethod = tmp;
+
+ meth->flags = flags;
+ meth->implFlags = implFlags;
+
+ if (rva) {
+ meth->offset = textSection->rawAddress +
+ (rva - textSection->virtualAddress);
} else {
- offset = blobOffset + signature;
-
- VMMethod* meth =
- constructMethod((VMClass*)cl, readString(cl->vm, (name + stringOffset)),
- token);
- meth->virt = extractMethodSignature(offset, cl, meth->parameters);
- meth->flags = flags;
- meth->implFlags = implFlags;
-
- if (rva) {
- meth->offset = textSection->rawAddress +
- (rva - textSection->virtualAddress);
- } else {
- meth->offset = 0;
- }
-
- if (paramList && paramTable != 0 && paramList <= paramSize) {
- uint32 endParam = (index == methodSize) ?
- paramSize + 1 :
- methTable->readIndexInRow(index + 1, CONSTANT_METHODDEF_PARAMLIST,
- bytes);
+ meth->offset = 0;
+ }
- uint32 nbParams = endParam - paramList;
+ if (paramList && paramTable != 0 && paramList <= paramSize) {
+ uint32 endParam = (index == methodSize) ?
+ paramSize + 1 :
+ methTable->readIndexInRow(index + 1, CONSTANT_METHODDEF_PARAMLIST,
+ bytes);
- for (uint32 j = 0; j < nbParams; ++j) {
- meth->params.push_back(readParam(j + paramList, meth));
- }
+ uint32 nbParams = endParam - paramList;
+ for (uint32 j = 0; j < nbParams; ++j) {
+ meth->params.push_back(readParam(j + paramList, meth));
}
-
- return meth;
}
+
+ return meth;
}
VMField* Assembly::readField(uint32 index, VMCommonClass* cl) {
@@ -1637,7 +1659,7 @@
}
case CONSTANT_MemberRef : {
- meth = readMemberRefAsMethod(token);
+ meth = readMemberRefAsMethod(token, NULL);
break;
}
@@ -1679,7 +1701,7 @@
return i + 1 + (CONSTANT_TypeDef << 24);
}
-VMMethod* Assembly::readMemberRefAsMethod(uint32 token) {
+VMMethod* Assembly::readMemberRefAsMethod(uint32 token, std::vector<VMCommonClass*>* genArgs) {
uint32 index = token & 0xffff;
Table* memberTable = CLIHeader->tables[CONSTANT_MemberRef];
uint32* memberArray = (uint32*)alloca(sizeof(uint32) * memberTable->rowSize);
@@ -1706,7 +1728,34 @@
VMCommonClass* type = loadType(((N3*)VMThread::get()->vm), typeToken,
true, false, false, true);
bool virt = extractMethodSignature(offset, type, args);
- VMMethod* meth = type->lookupMethod(name, args, !virt, true);
+ VMMethod* meth;
+
+ if (genArgs != NULL) {
+ VMClass* cl = dynamic_cast<VMClass*>(type);
+
+ if (cl == NULL) {
+ VMThread::get()->vm->error("Only instances of generic classes are allowed.");
+ }
+
+ // search for matching signature
+ for (uint i = 0; i < cl->genericMethods.size(); ++i) {
+ VMMethod* genMethod = cl->genericMethods.at(i);
+
+ if (!name->equals(genMethod->name) || !genMethod->signatureEqualsGeneric(args)) {
+ continue;
+ }
+
+ // use found token to create instance of generic method
+ VMThread::get()->genMethodInstantiation = genArgs;
+ meth = readMethodDef(genMethod->token & 0xFFFFFF, type);
+ VMThread::get()->genMethodInstantiation = NULL;
+ meth->token = token;
+ // insert in global hashmap
+ }
+ } else {
+ meth = type->lookupMethod(name, args, !virt, true);
+ }
+
return meth;
}
@@ -1781,7 +1830,7 @@
}
case 1 : {
methodToken = index + (CONSTANT_MemberRef << 24);
- return readMemberRefAsMethod(methodToken);
+ return readMemberRefAsMethod(methodToken, &genArgs);
}
}
Modified: vmkit/trunk/lib/N3/VMCore/Assembly.h
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/N3/VMCore/Assembly.h?rev=54579&r1=54578&r2=54579&view=diff
==============================================================================
--- vmkit/trunk/lib/N3/VMCore/Assembly.h (original)
+++ vmkit/trunk/lib/N3/VMCore/Assembly.h Sat Aug 9 05:23:35 2008
@@ -150,7 +150,7 @@
VMField* constructField(VMClass* cl, const UTF8* name,
VMCommonClass* signature, uint32 token);
VMMethod* constructMethod(VMClass* cl, const UTF8* name,
- uint32 token);
+ uint32 token, bool generic);
VMCommonClass* lookupClassFromName(const UTF8* name, const UTF8* nameSpace);
VMCommonClass* lookupClassFromToken(uint32 token);
VMMethod* lookupMethodFromToken(uint32 token);
@@ -248,7 +248,7 @@
VMMethod* getMethodFromToken(uint32 token);
uint32 getTypedefTokenFromMethod(uint32 token);
- VMMethod* readMemberRefAsMethod(uint32 token);
+ VMMethod* readMemberRefAsMethod(uint32 token, std::vector<VMCommonClass*>* genArgs);
const UTF8* readUserString(uint32 token);
uint32 getExplicitLayout(uint32 token);
Modified: vmkit/trunk/lib/N3/VMCore/CLIJit.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/N3/VMCore/CLIJit.cpp?rev=54579&r1=54578&r2=54579&view=diff
==============================================================================
--- vmkit/trunk/lib/N3/VMCore/CLIJit.cpp (original)
+++ vmkit/trunk/lib/N3/VMCore/CLIJit.cpp Sat Aug 9 05:23:35 2008
@@ -1462,13 +1462,16 @@
jit->compilingClass = cl;
jit->compilingMethod = meth;
- // save previous generic class
+ // save previous generic and method class
VMGenericClass* old = VMThread::get()->currGenericClass;
+ VMGenericMethod* oldMethod = VMThread::get()->currGenericMethod;
// temporarily store the class of the method to be compiled
- // in case it is a generic class
+ // in case it is a generic class
VMThread::get()->currGenericClass = dynamic_cast<VMGenericClass*>(cl);
+ VMThread::get()->currGenericMethod = dynamic_cast<VMGenericMethod*>(meth);
+
Function* func;
meth->getSignature();
@@ -1483,6 +1486,8 @@
// restore saved class
VMThread::get()->currGenericClass = old;
+ VMThread::get()->currGenericMethod = oldMethod;
+
return func;
}
Modified: vmkit/trunk/lib/N3/VMCore/CLISignature.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/N3/VMCore/CLISignature.cpp?rev=54579&r1=54578&r2=54579&view=diff
==============================================================================
--- vmkit/trunk/lib/N3/VMCore/CLISignature.cpp (original)
+++ vmkit/trunk/lib/N3/VMCore/CLISignature.cpp Sat Aug 9 05:23:35 2008
@@ -249,8 +249,18 @@
}
static VMCommonClass* METHOD_ElementTypeMvar(uint32 op, Assembly* ass, uint32& offset) {
- VMThread::get()->vm->error("implement me");
- return 0;
+ uint32 number = ass->uncompressSignature(offset);
+
+ if (VMThread::get()->currGenericMethod == NULL) {
+ // return dummy VMClass, use the token field
+ // to store the generic argument number
+ VMClass* cl = gc_new(VMClass)();
+ cl->token = number;
+ cl->assembly = NULL;
+ return cl;
+ } else {
+ return VMThread::get()->currGenericMethod->genericParams[number];
+ }
}
static VMCommonClass* METHOD_ElementTypeCmodReqd(uint32 op, Assembly* ass, uint32& offset) {
@@ -365,11 +375,16 @@
//uint32 count =
uncompressSignature(offset);
uint32 call = uncompressSignature(offset);
+
+ if (call & CONSTANT_Generic) {
+ //uint32 genArgCount =
+ uncompressSignature(offset);
+ }
+
uint32 paramCount = uncompressSignature(offset);
uint32 hasThis = call & CONSTANT_HasThis ? 1 : 0;
uint32 realCount = paramCount + hasThis;
- //uint32 generic = call & CONSTANT_Generic ? 1 : 0;
VMCommonClass* ret = exploreType(offset);
types.push_back(ret);
@@ -377,6 +392,7 @@
if (hasThis) {
types.push_back(cl);
}
+
for (uint32 i = hasThis; i < realCount; ++i) {
VMCommonClass* cur = exploreType(offset);
types.push_back(cur);
Modified: vmkit/trunk/lib/N3/VMCore/N3Initialise.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/N3/VMCore/N3Initialise.cpp?rev=54579&r1=54578&r2=54579&view=diff
==============================================================================
--- vmkit/trunk/lib/N3/VMCore/N3Initialise.cpp (original)
+++ vmkit/trunk/lib/N3/VMCore/N3Initialise.cpp Sat Aug 9 05:23:35 2008
@@ -187,8 +187,10 @@
INIT(UTF8);
INIT(VMCommonClass);
INIT(VMClass);
+ INIT(VMGenericClass);
INIT(VMClassArray);
INIT(VMMethod);
+ INIT(VMGenericMethod);
INIT(VMField);
INIT(VMCond);
INIT(LockObj);
Modified: vmkit/trunk/lib/N3/VMCore/Opcodes.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/N3/VMCore/Opcodes.cpp?rev=54579&r1=54578&r2=54579&view=diff
==============================================================================
--- vmkit/trunk/lib/N3/VMCore/Opcodes.cpp (original)
+++ vmkit/trunk/lib/N3/VMCore/Opcodes.cpp Sat Aug 9 05:23:35 2008
@@ -1280,6 +1280,11 @@
VMCommonClass* type = assembly->loadType(vm, token, true, false, false,
true);
assert(type);
+
+ if (!type->isPrimitive) {
+ // the box instruction has no effect on non-primitive types
+ break;
+ }
Value* var = new LoadInst(type->llvmVar(), "", currentBlock);
Value* obj = CallInst::Create(objConsLLVM, var, "", currentBlock);
Modified: vmkit/trunk/lib/N3/VMCore/VMArray.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/N3/VMCore/VMArray.cpp?rev=54579&r1=54578&r2=54579&view=diff
==============================================================================
--- vmkit/trunk/lib/N3/VMCore/VMArray.cpp (original)
+++ vmkit/trunk/lib/N3/VMCore/VMArray.cpp Sat Aug 9 05:23:35 2008
@@ -218,3 +218,20 @@
return buf->cString();
}
+bool UTF8::equals(const UTF8 *string) const
+{
+ if (size != string->size) {
+ return false;
+ }
+
+ for (sint32 i = 0; i < size; ++i) {
+ if (at(i) != string->at(i)) {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+
+
Modified: vmkit/trunk/lib/N3/VMCore/VMArray.h
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/N3/VMCore/VMArray.h?rev=54579&r1=54578&r2=54579&view=diff
==============================================================================
--- vmkit/trunk/lib/N3/VMCore/VMArray.h (original)
+++ vmkit/trunk/lib/N3/VMCore/VMArray.h Sat Aug 9 05:23:35 2008
@@ -104,6 +104,8 @@
static const UTF8* readerConstruct(VirtualMachine *vm, uint16* buf, uint32 n);
const UTF8* extract(VirtualMachine *vm, uint32 start, uint32 len) const;
+
+ bool equals(const UTF8* string) const;
};
} // end namespace n3
Modified: vmkit/trunk/lib/N3/VMCore/VMClass.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/N3/VMCore/VMClass.cpp?rev=54579&r1=54578&r2=54579&view=diff
==============================================================================
--- vmkit/trunk/lib/N3/VMCore/VMClass.cpp (original)
+++ vmkit/trunk/lib/N3/VMCore/VMClass.cpp Sat Aug 9 05:23:35 2008
@@ -110,6 +110,32 @@
buf->write(">");
}
+void VMGenericMethod::print(mvm::PrintBuffer* buf) const {
+ buf->write("CLIGenericMethod<");
+ classDef->nameSpace->print(buf);
+ buf->write(".");
+ classDef->name->print(buf);
+ buf->write("::");
+ name->print(buf);
+ buf->write("(");
+ std::vector<VMCommonClass*>::iterator i = ((VMMethod*)this)->parameters.begin();
+ std::vector<VMCommonClass*>::iterator e = ((VMMethod*)this)->parameters.end();
+
+ ++i;
+ if (i != e) {
+ while (true) {
+ (*i)->nameSpace->print(buf);
+ buf->write(".");
+ (*i)->name->print(buf);
+ ++i;
+ if (i == e) break;
+ else buf->write(" ,");
+ }
+ }
+ buf->write(")");
+ buf->write(">");
+}
+
void VMField::print(mvm::PrintBuffer* buf) const {
buf->write("CLIField<");
classDef->nameSpace->print(buf);
@@ -796,9 +822,59 @@
return true;
}
+bool VMMethod::signatureEqualsGeneric(std::vector<VMCommonClass*> & args) {
+ bool stat = isStatic(flags);
+
+ if (args.size() != parameters.size())
+ return false;
+ else {
+ std::vector<VMCommonClass*>::iterator i = parameters.begin(), a =
+ args.begin(), e = args.end();
+
+ if (((*i)->assembly == NULL && (*a)->assembly != NULL) ||
+ ((*i)->assembly != NULL && (*a)->assembly == NULL))
+ return false;
+
+ if ((*i)->assembly == NULL && (*a)->assembly == NULL) {
+ if ((*i)->token != (*a)->token) {
+ return false;
+ }
+ }
+
+ if ((*i) != (*a))
+ return false;
+ ++i;
+ ++a;
+
+ if (!stat) {
+ ++i;
+ ++a;
+ }
+
+ for (; a != e; ++i, ++a) {
+ if (((*i)->assembly == NULL && (*a)->assembly != NULL) ||
+ ((*i)->assembly != NULL && (*a)->assembly == NULL))
+ return false;
+
+ if ((*i)->assembly == NULL && (*a)->assembly == NULL) {
+ if ((*i)->token != (*a)->token) {
+ return false;
+ } else {
+ continue;
+ }
+ }
+
+ if ((*i) != (*a))
+ return false;
+ }
+ }
+ return true;
+}
+
void VMGenericClass::print(mvm::PrintBuffer* buf) const {
buf->write("GenCLIType<");
nameSpace->print(buf);
buf->write("::");
name->print(buf);
- buf->write(">");}
+ buf->write(">");
+}
Modified: vmkit/trunk/lib/N3/VMCore/VMClass.h
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/N3/VMCore/VMClass.h?rev=54579&r1=54578&r2=54579&view=diff
==============================================================================
--- vmkit/trunk/lib/N3/VMCore/VMClass.h (original)
+++ vmkit/trunk/lib/N3/VMCore/VMClass.h Sat Aug 9 05:23:35 2008
@@ -141,6 +141,7 @@
VMObject* virtualInstance;
std::vector<VMClass*> innerClasses;
VMClass* outerClass;
+ std::vector<VMMethod*> genericMethods;
VMObject* operator()();
VMObject* doNew();
@@ -229,10 +230,20 @@
static const llvm::FunctionType* resolveSignature(
std::vector<VMCommonClass*>& params, bool isVirt, bool &structRet);
bool signatureEquals(std::vector<VMCommonClass*>& args);
+ bool signatureEqualsGeneric(std::vector<VMCommonClass*>& args);
llvm::GlobalVariable* llvmVar();
llvm::GlobalVariable* _llvmVar;
};
+class VMGenericMethod : public VMMethod {
+public:
+ static VirtualTable* VT;
+ virtual void print(mvm::PrintBuffer* buf) const;
+ virtual void TRACER;
+
+ std::vector<VMCommonClass*> genericParams;
+};
+
class VMField : public mvm::Object {
public:
static VirtualTable* VT;
Modified: vmkit/trunk/lib/N3/VMCore/VMThread.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/N3/VMCore/VMThread.cpp?rev=54579&r1=54578&r2=54579&view=diff
==============================================================================
--- vmkit/trunk/lib/N3/VMCore/VMThread.cpp (original)
+++ vmkit/trunk/lib/N3/VMCore/VMThread.cpp Sat Aug 9 05:23:35 2008
@@ -59,7 +59,10 @@
key->self = mvm::Thread::self();
key->pendingException = 0;
key->perFunctionPasses = new llvm::FunctionPassManager(vm->TheModuleProvider);
- key->perFunctionPasses->add(new llvm::TargetData(vm->module));
+ key->perFunctionPasses->add(new llvm::TargetData(vm->module));
+ key->currGenericClass = NULL;
+ key->currGenericMethod = NULL;
+ key->genMethodInstantiation = NULL;
AddStandardCompilePasses(key->perFunctionPasses);
return key;
}
Modified: vmkit/trunk/lib/N3/VMCore/VMThread.h
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/N3/VMCore/VMThread.h?rev=54579&r1=54578&r2=54579&view=diff
==============================================================================
--- vmkit/trunk/lib/N3/VMCore/VMThread.h (original)
+++ vmkit/trunk/lib/N3/VMCore/VMThread.h Sat Aug 9 05:23:35 2008
@@ -26,6 +26,7 @@
class VMClass;
class VMGenericClass;
class VMObject;
+class VMGenericMethod;
class VMThread : public mvm::Thread {
public:
@@ -42,6 +43,11 @@
// helper which points to the current generic class
VMGenericClass* currGenericClass;
+ // helper which contains the instantiation of the
+ // current generic method
+ std::vector<VMCommonClass*>* genMethodInstantiation;
+ // helper which points to the current generic method
+ VMGenericMethod* currGenericMethod;
static const unsigned int StateRunning;
static const unsigned int StateWaiting;
Modified: vmkit/trunk/lib/N3/VMCore/VirtualTables.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/N3/VMCore/VirtualTables.cpp?rev=54579&r1=54578&r2=54579&view=diff
==============================================================================
--- vmkit/trunk/lib/N3/VMCore/VirtualTables.cpp (original)
+++ vmkit/trunk/lib/N3/VMCore/VirtualTables.cpp Sat Aug 9 05:23:35 2008
@@ -44,6 +44,7 @@
INIT(VMClassArray);
INIT(VMClassPointer);
INIT(VMMethod);
+ INIT(VMGenericMethod);
INIT(VMField);
INIT(VMCond);
INIT(LockObj);
@@ -168,6 +169,7 @@
virtualInstance->MARK_AND_TRACE;
TRACE_VECTOR(VMClass*, innerClasses, std::allocator);
outerClass->MARK_AND_TRACE;
+ TRACE_VECTOR(VMMethod*, genericMethods, std::allocator);
}
void VMGenericClass::TRACER {
@@ -195,6 +197,11 @@
name->MARK_AND_TRACE;
}
+void VMGenericMethod::TRACER {
+ VMMethod::PARENT_TRACER;
+ TRACE_VECTOR(VMCommonClass*, genericParams, std::allocator);
+}
+
void VMField::TRACER {
signature->MARK_AND_TRACE;
classDef->MARK_AND_TRACE;
More information about the vmkit-commits
mailing list