#include <stdio.h>
#include <string.h>
#include <vector>

#include "llvm/ExecutionEngine/ExecutionEngine.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/DataLayout.h"

#include "j3/j3.h"
#include "j3/j3class.h"
#include "j3/j3classloader.h"
#include "j3/j3reader.h"
#include "j3/j3constants.h"
#include "j3/j3method.h"
#include "j3/j3mangler.h"
#include "j3/j3object.h"
#include "j3/j3thread.h"
#include "j3/j3field.h"
#include "j3/j3attribute.h"
#include "j3/j3codegen.h"

using namespace j3;

/*  
 *  ------------ J3Type ------------
 */
J3Type::J3Type(J3ClassLoader* loader, const vmkit::Name* name) { 
	pthread_mutexattr_t attr;
	pthread_mutexattr_init(&attr);
	pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
	pthread_mutex_init(&_mutex, &attr);
	_loader = loader; 
	_name = name; 
}

const char* J3Type::genId(const char* prefix, const char* suffix) {
	size_t plen = prefix ? strlen(prefix) : 0;
	size_t slen = suffix ? strlen(suffix) : 0;
	size_t len = nativeNameLength();
	char* id = (char*)loader()->allocator()->allocate(plen + len + slen + 1);

	memcpy(id, prefix, plen);
	memcpy(id+plen, nativeName(), len);
	memcpy(id+plen+plen, suffix, slen);

	return id;
}

void* J3Type::getSymbolAddress() {
	return this;
}

const char* J3Type::vtId() {
	const char* id = vtSymbol()->id();

	if(!id)
		vtSymbol()->setId(id = genId("vt_"));

	return id;
}

J3VirtualTable* J3Type::vt() { 
	return vtSymbol()->vt(); 
}

void J3Type::dump() {
	fprintf(stderr, "Type: %s", name()->cStr());
}

J3ObjectHandle* J3Type::javaClass(bool doPush, J3ObjectHandle* protectionDomain) {
	if(!_javaClass) {
		lock();
		if(!_javaClass) {
			J3* vm = J3Thread::get()->vm();
			J3ObjectHandle* prev = J3Thread::get()->tell();
			_javaClass = loader()->globalReferences()->add(J3ObjectHandle::doNewObject(vm->classClass));
			J3Thread::get()->restore(prev);
			_javaClass->setLong(vm->classClassVMData, (int64_t)(uintptr_t)this);
			vm->classClassInit->invokeSpecial(_javaClass);
		}
		unlock();
	}
	return doPush ? J3Thread::get()->push(_javaClass) : _javaClass;
}

void J3Type::doNativeName() {
	J3::internalError("should not happen");
}

char* J3Type::nativeName() {
	if(!_nativeName)
		doNativeName();
	return _nativeName;
}

uint32_t J3Type::nativeNameLength() {
	if(!_nativeNameLength)
		doNativeName();
	return _nativeNameLength;
}

J3ArrayClass* J3Type::getArray(uint32_t prof, const vmkit::Name* name) {
	if(!_array) {
		lock();
		if(!_array) {
			_array = new(loader()->allocator()) J3ArrayClass(loader(), this, name);
		}
		unlock();
	}

	return prof > 1 ? _array->getArray(prof-1) : _array;
}

uint64_t J3Type::getSizeInBits() {
	return 1 << (logSize()+3);
}

bool J3Type::isAssignableTo(J3Type* parent) {
	resolve();
	parent->resolve();
	return vt()->isAssignableTo(parent->vt());
}

J3Type* J3Type::resolve() {
	if(status < RESOLVED)
		doResolve(0, 0);
	return this;
}

J3Type* J3Type::resolve(J3Field* hiddenFields, uint32_t nbHiddenFields) {
	if(status < RESOLVED)
		doResolve(hiddenFields, nbHiddenFields);
	else
		J3::internalError("trying to resolve class %s with hidden fields while it is already loaded", name()->cStr());
	return this;
}

J3Type* J3Type::initialise() {
	if(status < INITED)
		doInitialise();
	return this;
}

J3Class* J3Type::asClass() {
	if(!isClass())
		J3::internalError("should not happen");
	return (J3Class*)this;
}

J3Layout* J3Type::asLayout() {
	if(!isLayout())
		J3::internalError("should not happen");
	return (J3Layout*)this;
}

J3StaticLayout* J3Type::asStaticLayout() {
	if(!isStaticLayout())
		J3::internalError("should not happen");
	return (J3StaticLayout*)this;
}

J3Primitive* J3Type::asPrimitive() {
	if(!isPrimitive())
		J3::internalError("should not happen");
	return (J3Primitive*)this;
}

J3ArrayClass* J3Type::asArrayClass() {
	if(!isArrayClass())
		J3::internalError("should not happen");
	return (J3ArrayClass*)this;
}

J3ObjectType* J3Type::asObjectType() {
	if(!isObjectType())
		J3::internalError("should not happen");
	return (J3ObjectType*)this;
}

/*  
 *  ------------ J3ObjectType ------------
 */
J3ObjectType::J3ObjectType(J3ClassLoader* loader, const vmkit::Name* name) : J3Type(loader, name) {
}

llvm::Type* J3ObjectType::llvmType() {
	return J3Thread::get()->vm()->typeJ3ObjectPtr;
}

J3Method* J3ObjectType::findMethod(uint32_t access, const vmkit::Name* name, J3Signature* signature, bool error) {
	J3::internalError("should not happen - findMethod: %s::%s\n", J3ObjectType::name()->cStr(), name->cStr());
}

J3ObjectType* J3ObjectType::nativeClass(J3ObjectHandle* handle) {
	return (J3ObjectType*)(uintptr_t)handle->getLong(J3Thread::get()->vm()->classClassVMData);
}

J3ObjectHandle* J3ObjectType::clone(J3ObjectHandle* obj) {
	J3::internalError("should not happen");
}

uint16_t J3ObjectType::access() {
	J3::internalError("should not happen");
}

uint16_t J3ObjectType::modifiers() {
	J3::internalError("should not happen");
}

J3Class* J3ObjectType::super() {
	J3::internalError("should not happen");
}

void J3ObjectType::prepareInterfaceTable() {
	//fprintf(stderr, "prepare interface table of %s\n", name()->cStr());

	uint32_t total = 0;
	J3InterfaceSlotDescriptor* slots = _interfaceSlotDescriptors;

	for(uint32_t i=0; i<vt()->checker.nbSecondaryTypes; i++) {
		J3Type* type = vt()->checker.secondaryTypes[i]->type();

		if(type->isClass()) {
			J3Class* ifce = vt()->checker.secondaryTypes[i]->type()->asClass();
			if(J3Cst::isInterface(ifce->access())) {
				//fprintf(stderr, "  processing interface: %s\n", ifce->name()->cStr());
				for(uint32_t j=0; j<ifce->nbMethods(); j++) {
					J3Method* base = ifce->methods()[j];
					//fprintf(stderr, "    processing %s method %s %s\n", 
					//J3Cst::isAbstract(base->access()) ? "abstract" : "concrete",
					//base->signature()->cStr(), base->name()->cStr());
					J3Method* method = findMethod(0, base->name(), base->signature(), J3Cst::isAbstract(base->access()));

					if(!method)
						method = base;

					uint32_t index = base->interfaceIndex() % J3VirtualTable::nbInterfaceMethodTable;
					uint32_t found = 0;

					for(uint32_t i=0; !found && i<slots[index].nbMethods; i++)
						if(slots[index].methods[i] == method)
							found=1;

					if(!found) {
						total++;
						J3Method** tmp = (J3Method**)alloca(sizeof(J3Method*)*(slots[index].nbMethods+1));
						memcpy(tmp, slots[index].methods, sizeof(J3Method*)*slots[index].nbMethods);
						tmp[slots[index].nbMethods] = method;
						slots[index].methods = tmp;
						slots[index].nbMethods++;
					}
				}
			}
		}
	}

	J3Method** methods = (J3Method**)loader()->allocator()->allocate(total*sizeof(J3Method*));
	uint32_t cur = 0;

	for(uint32_t i=0; i<J3VirtualTable::nbInterfaceMethodTable; i++) {
		memcpy(methods + cur, slots[i].methods, slots[i].nbMethods*sizeof(J3Method*));
		slots[i].methods = methods + cur;
		cur += slots[i].nbMethods;
	}

	//dumpInterfaceSlotDescriptors();
}

void J3ObjectType::dumpInterfaceSlotDescriptors() {
	J3InterfaceSlotDescriptor* slots = _interfaceSlotDescriptors;
	fprintf(stderr, "slot descriptors of %s\n", name()->cStr());
	for(uint32_t i=0; i<J3VirtualTable::nbInterfaceMethodTable; i++) {
		if(slots[i].nbMethods) {
			fprintf(stderr, "  slot[%d]:\n", i);
			for(uint32_t j=0; j<slots[i].nbMethods; j++)
				fprintf(stderr, "    %s::%s %s\n", 
								slots[i].methods[j]->cl()->name()->cStr(),
								slots[i].methods[j]->name()->cStr(),
								slots[i].methods[j]->signature()->name()->cStr());
		}
	}
}

/*  
 *  ------------ J3Layout ------------
 */
J3StaticLayout::J3StaticLayout(J3ClassLoader* loader, J3Class* cl, const vmkit::Name* name) : J3Layout(loader, name) {
	_cl = cl;
}

J3ObjectHandle* J3StaticLayout::extractAttribute(J3Attribute* attr) { 
	return cl()->extractAttribute(attr); 
}

J3Layout::J3Layout(J3ClassLoader* loader, const vmkit::Name* name) : J3ObjectType(loader, name) {
}

uintptr_t J3Layout::structSize() { 
	return _structSize; 
}

J3Method* J3Layout::localFindMethod(const vmkit::Name* name, J3Signature* signature) {
	//fprintf(stderr, " --- lookup %s%s in %s\n", name->cStr(), signature->name()->cStr(), J3Layout::name()->cStr());

	for(size_t i=0; i<nbMethods(); i++) {
		J3Method* cur = methods()[i];

		//fprintf(stderr, "%s::%s%s\n", cur->cl()->name()->cStr(), cur->name()->cStr(), cur->signature()->name()->cStr());

		if(cur->name() == name && cur->signature()->name() == signature->name()) {
			return cur;
		}
	}
	return 0;
}

J3Field* J3Layout::localFindField(const vmkit::Name* name, const J3Type* type) {
	for(size_t i=0; i<nbFields(); i++) {
		J3Field* cur = fields() + i;

		//printf("  compare with %s - %s\n", cur->name()->cStr(), cur->type()->name()->cStr());
		if(cur->name() == name && cur->type() == type) {
			return cur;
		}
	}
	return 0;
}

/*  
 *  ------------ J3Class ------------
 */
J3Class::J3Class(J3ClassLoader* loader, const vmkit::Name* name, J3ClassBytes* bytes, J3ObjectHandle* protectionDomain, const char* source) : 
	J3Layout(loader, name), 
	_staticLayout(loader, this, name) {
	_protectionDomain = protectionDomain ? loader->globalReferences()->add(protectionDomain) : 0;
	_source = source;
	_bytes = bytes;
	status = LOADED;
	/* allocating the J3ObjectHande looks a little strange, but it will become important to reload AOT compiled class loaders */
	_staticObjectSymbol = new(loader->staticObjects()) J3StaticObjectSymbol(loader->staticObjectHandles()->push());
}

void J3Class::compileAll() {
	resolve();

	for(uint32_t i=0; i<nbMethods(); i++) {
		if(!J3Cst::isAbstract(methods()[i]->access()))
			methods()[i]->ensureCompiled(J3CodeGen::WithMethod);
	}

	for(uint32_t i=0; i<staticLayout()->nbMethods(); i++) {
		if(!J3Cst::isAbstract(staticLayout()->methods()[i]->access()))
			staticLayout()->methods()[i]->ensureCompiled(J3CodeGen::WithMethod);
	}
}

void J3Class::aotSnapshot(llvm::Linker* linker) {
	for(uint32_t i=0; i<nbMethods(); i++) {
		methods()[i]->aotSnapshot(linker);
	}

	for(uint32_t i=0; i<staticLayout()->nbMethods(); i++) {
		staticLayout()->methods()[i]->aotSnapshot(linker);
	}
}

uint16_t J3Class::modifiers() {
	return access();
#if 0
  if (isEnum(res) && cl->getSuper() != vm->upcalls->EnumClass) {
    // javac may put that flag to inner classes of enum classes.
    res &= ~ACC_ENUM;
  }
#endif
}

J3ObjectHandle* J3Class::clone(J3ObjectHandle* obj) {
	//fprintf(stderr, " cloning %p with %lu bytes\n", obj->obj(), structSize());
	J3ObjectHandle* res = J3ObjectHandle::doNewObject(this);
	obj->rawObjectCopyTo(0, res, 0, structSize() - sizeof(J3Object));
	return res;
}

J3ObjectHandle* J3Class::extractAttribute(J3Attribute* attr) {
	if(attr)
		J3::internalError("extract attribute");
	else
		return J3ObjectHandle::doNewArray(J3Thread::get()->vm()->typeByte->getArray(), 0);
}

J3Method* J3Class::findInterfaceMethodRecursive(const vmkit::Name* name, J3Signature* signature) {
	J3Class* cur = this;
	while(1) {
		J3Method* res = cur->localFindMethod(name, signature);

		if(res)
			return res;

		switch(cur->nbInterfaces()) {
			case 1: cur = cur->interfaces()[0]; break;
			default:
				for(uint32_t i=0; i<cur->nbInterfaces(); i++) {
					res = cur->interfaces()[i]->findInterfaceMethodRecursive(name, signature);
					if(res)
						return res;
				}
			case 0:
				return 0;
		}
	}
}

J3Method* J3Class::findInterfaceMethod(const vmkit::Name* name, J3Signature* signature, bool error) {
	resolve();
	J3Method* res = findInterfaceMethodRecursive(name, signature);

	if(res)
		return res;

	if(error)
		J3::noSuchMethodError("no such interface method", this, name, signature);
	else
		return 0;
}

J3Method* J3Class::findMethod(uint32_t access, const vmkit::Name* name, J3Signature* signature, bool error) {
	resolve();

	J3Class* cur = this;
	while(1) {
		J3Layout* layout = J3Cst::isStatic(access) ? (J3Layout*)cur->staticLayout() : cur;
		J3Method* res = layout->localFindMethod(name, signature);

		if(res)
			return res;

		if(cur == cur->super()) {
			if(error)
				J3::noSuchMethodError("no such method", this, name, signature);
			else
				return 0;
		}

		cur = cur->super();
	}
}

J3Field* J3Class::findInterfaceFieldRecursive(const vmkit::Name* name, J3Type* type) {
	J3Class* cur = this;

	while(1) {
		J3Field* res = cur->staticLayout()->localFindField(name, type);

		if(res)
			return res;

		switch(cur->nbInterfaces()) {
			case 1: cur = cur->interfaces()[0]; break;
			default:
				for(uint32_t i=0; i<cur->nbInterfaces(); i++) {
					res = cur->interfaces()[i]->findInterfaceFieldRecursive(name, type);
					if(res)
						return res;
				}
			case 0:
				return 0;
		}
	}
}

J3Field* J3Class::findField(uint32_t access, const vmkit::Name* name, J3Type* type, bool error) {
	resolve();

	J3Class* cur = this;

	while(1) {
		J3Layout* layout = J3Cst::isStatic(access) ? (J3Layout*)cur->staticLayout() : cur;
		J3Field* res = layout->localFindField(name, type);

		//fprintf(stderr, "[%d] Lookup: %s %s in %s\n", access, type->name()->cStr(), name->cStr(), cur->name()->cStr());

		if(res)
			return res;

		if(cur == cur->super()) {
			if(J3Cst::isStatic(access)) {
				J3Class* prev = 0;
				for(cur=this; cur!=prev; cur=cur->super()) {
					for(uint32_t i=0; i<cur->nbInterfaces(); i++) {
						res = cur->interfaces()[i]->findInterfaceFieldRecursive(name, type);
						if(res)
							return res;
					}
					prev = cur;
				}
			}

			if(error)
				J3::noSuchFieldError("no such field", this, name, type);
			else
				return 0;
		}

		cur = cur->super();
	}
}

void J3Class::registerNative(const vmkit::Name* name, const vmkit::Name* signatureName, void* fnPtr) {
	resolve();
	J3Signature* signature = loader()->getSignature(this, signatureName);
	J3Method* res = staticLayout()->localFindMethod(name, signature);
	if(!res)
		res = localFindMethod(name, signature);
	if(!res || !J3Cst::isNative(res->access()))
		J3::noSuchMethodError("unable to find native method", this, name, signature);

	res->registerNative(fnPtr);
}

const char* J3Class::staticObjectId() {
	const char* id = staticObjectSymbol()->id();

	if(!id)
		staticObjectSymbol()->setId(id = genId("static_"));

	return id;
}

void J3Class::doInitialise() {
	resolve();
	lock();
	if(status < INITED) {
		J3* vm = J3Thread::get()->vm();
		if(vm->options()->debugIniting)
			fprintf(stderr, "Initing: %s\n", name()->cStr());
		status = INITED;

		super()->initialise();

		for(size_t i=0; i<nbInterfaces(); i++)
			interfaces()[i]->initialise();

		J3ObjectHandle* prev = J3Thread::get()->tell();
		J3ObjectHandle* stacked = J3ObjectHandle::allocate(staticLayout()->vt(), staticLayout()->structSize());

		staticObjectSymbol()->setHandle(stacked);
		J3Thread::get()->restore(prev);

		for(size_t i=0; i<staticLayout()->nbFields(); i++) {
			J3Field* cur = staticLayout()->fields() + i;
			J3Attribute* attr = cur->attributes()->lookup(vm->constantValueAttribute);

			if(attr) {
				J3Reader reader(bytes());
				reader.seek(attr->offset(), reader.SeekSet);

				uint32_t length = reader.readU4();
				if(length != 2)
					J3::classFormatError(this, "bad length for ConstantAttribute");
				
				uint32_t idx = reader.readU2();
				J3ObjectHandle* staticObject = staticObjectSymbol()->handle();

				switch(getCtpType(idx)) {
					case J3Cst::CONSTANT_Long:    staticObject->setLong(cur, longAt(idx)); break;
					case J3Cst::CONSTANT_Float:   staticObject->setFloat(cur, floatAt(idx)); break;
					case J3Cst::CONSTANT_Double:  staticObject->setDouble(cur, doubleAt(idx)); break;
					case J3Cst::CONSTANT_Integer: staticObject->setInteger(cur, integerAt(idx)); break;
					case J3Cst::CONSTANT_String:  staticObject->setObject(cur, stringAt(idx)->handle()); break;
					default:
						J3::classFormatError(this, "invalid ctp entry ConstantAttribute with type %d", getCtpType(idx));
				}
			}
		}

		J3Method* clinit = staticLayout()->localFindMethod(vm->clinitName, vm->clinitSign);
			
		if(clinit)
			clinit->invokeStatic();
	}
	unlock();
}

void J3Class::doResolve(J3Field* hiddenFields, size_t nbHiddenFields) {
	lock();
	if(status < RESOLVED) {
		if(J3Thread::get()->vm()->options()->debugResolve)
			fprintf(stderr, "Resolving: %s\n", name()->cStr());

		status = RESOLVED;
		readClassBytes(hiddenFields, nbHiddenFields);
		
		staticLayout()->vtSymbol()->setVt(J3VirtualTable::create(staticLayout()));

		vtSymbol()->setVt(J3VirtualTable::create(this));

		if(!J3Cst::isInterface(access()) && !J3Cst::isAbstract(access()))
			prepareInterfaceTable();
	}
	unlock();
}

void J3Class::readClassBytes(J3Field* hiddenFields, uint32_t nbHiddenFields) {
	J3Reader reader(_bytes);

	uint32_t magic = reader.readU4();
	if(magic != J3Cst::MAGIC)
		J3::classFormatError(this, "bad magic");
			
	/* uint16_t minor = */reader.readU2();
	/* uint16_t major = */reader.readU2();
			
	nbCtp     = reader.readU2();
	
	if(nbCtp < 1)
		J3::classFormatError(this, "zero-sized constant pool");
	
	ctpTypes    = (uint8_t*)loader()->allocator()->allocate(nbCtp * sizeof(uint8_t));
	ctpValues   = (uint32_t*)loader()->allocator()->allocate(nbCtp * sizeof(uint32_t));
	ctpResolved = (void**)loader()->allocator()->allocate(nbCtp * sizeof(void*));
	
	ctpTypes[0] = 0;

	for(uint32_t i=1; i<nbCtp; i++) {
		switch(ctpTypes[i] = reader.readU1()) {
			case J3Cst::CONSTANT_Utf8:
				ctpValues[i] = reader.tell();
				reader.seek(reader.readU2(), reader.SeekCur);
				break;
			case J3Cst::CONSTANT_MethodType:
			case J3Cst::CONSTANT_String:
			case J3Cst::CONSTANT_Class:
				ctpValues[i] = reader.readU2();
				break;
			case J3Cst::CONSTANT_InvokeDynamic:
			case J3Cst::CONSTANT_Float:
			case J3Cst::CONSTANT_Integer:
			case J3Cst::CONSTANT_Fieldref:
			case J3Cst::CONSTANT_Methodref:
			case J3Cst::CONSTANT_InterfaceMethodref:
			case J3Cst::CONSTANT_NameAndType:
				ctpValues[i] = reader.readU4();
				break;
			case J3Cst::CONSTANT_Long:
			case J3Cst::CONSTANT_Double:
				ctpValues[i] = reader.readU4();
				ctpValues[i+1] = reader.readU4();
				i++;
				break;
			case J3Cst::CONSTANT_MethodHandle:
				ctpValues[i] = reader.readU1() << 16;
				ctpValues[i] |= reader.readU2();
				break;
			default:
				J3::classFormatError(this, "wrong constant pool entry type: %d", ctpTypes[i]);
		}
	}
	
	_access = reader.readU2();
	
	J3ObjectType* self = classAt(reader.readU2());
	
	if(self != this)
		J3::classFormatError(this, "wrong class file (describes class %s)", self->name()->cStr());
	
	uint16_t superIdx = reader.readU2();

	_super = superIdx ? classAt(superIdx)->asClass() : this;

	_nbInterfaces = reader.readU2();
	_interfaces = (J3Class**)loader()->allocator()->allocate(nbInterfaces()*sizeof(J3Class*));
	
	for(size_t i=0; i<nbInterfaces(); i++) {
		_interfaces[i] = classAt(reader.readU2())->asClass();
	}

	size_t   n = nbHiddenFields + reader.readU2(), nbStaticFields = 0, nbVirtualFields = 0;
	_fields = (J3Field*)alloca(sizeof(J3Field)*n);
	J3Field* pFields0[n]; size_t i0 = 0; /* sort fields by reverse size */
	J3Field* pFields1[n]; size_t i1 = 0;
	J3Field* pFields2[n]; size_t i2 = 0;
	J3Field* pFields3[n]; size_t i3 = 0;

	memset(fields(), 0, sizeof(J3Field)*n);
	
	for(size_t i=0; i<n; i++) {
		J3Field* f = fields() + i;

		if(i < nbHiddenFields) {
			f->_access     = hiddenFields[i].access();
			f->_name       = hiddenFields[i].name();
			f->_type       = hiddenFields[i].type();
			f->_attributes = new (loader()->allocator(), 0) J3Attributes(0);
		} else {
			f->_access     = reader.readU2();
			f->_name       = nameAt(reader.readU2());
			f->_type       = loader()->getTypeFromDescriptor(this, nameAt(reader.readU2()));
			f->_attributes = readAttributes(&reader);
		}

		if(J3Cst::isStatic(f->access())) {
			f->_layout = staticLayout();
			nbStaticFields++;
		} else {
			f->_layout = this;
			nbVirtualFields++;
		}

		switch(f->_type->logSize()) {
			case 0:  pFields0[i0++] = f; break;
			case 1:  pFields1[i1++] = f; break;
			case 2:  pFields2[i2++] = f; break;
			case 3:  pFields3[i3++] = f; break;
			default: J3::internalError("should not happen");
		}
	}

	staticLayout()->_fields = new(loader()->allocator()) J3Field[nbStaticFields];
	_fields = new(loader()->allocator()) J3Field[nbVirtualFields];

	if(super() == this)
		_structSize = sizeof(J3Object);
	else {
		super()->resolve();
		_structSize = super()->structSize();
	}

	_staticLayout._structSize = sizeof(J3Object);
	_structSize = ((_structSize - 1) & -sizeof(uintptr_t)) + sizeof(uintptr_t);

	fillFields(pFields3, i3);
	fillFields(pFields2, i2);
	fillFields(pFields1, i1);
	fillFields(pFields0, i0);
	
	size_t     nbVirtualMethods = 0, nbStaticMethods = 0;

	n = reader.readU2();
	J3Method** methodsTmp = (J3Method**)alloca(sizeof(J3Method*)*n);

	for(size_t i=0; i<n; i++) {
		uint16_t           access = reader.readU2();
		const vmkit::Name* name = nameAt(reader.readU2());
		J3Signature*       signature = loader()->getSignature(this, nameAt(reader.readU2()));
		J3Method*          method = new(loader()->allocator()) J3Method(access, this, name, signature);
		J3Attributes*      attributes = readAttributes(&reader);
		
		method->postInitialise(access, attributes);
		methodsTmp[i] = method;

		if(J3Cst::isStatic(access))
			nbStaticMethods++;
		else
			nbVirtualMethods++;
	}

	staticLayout()->_methods = (J3Method**)loader()->allocator()->allocate(sizeof(J3Method*)*nbStaticMethods);
	_methods = (J3Method**)loader()->allocator()->allocate(sizeof(J3Method*)*nbVirtualMethods);

	for(int i=0; i<n; i++) {
		J3Layout* layout;
		if(J3Cst::isStatic(methodsTmp[i]->access()))
			layout = staticLayout();
		else {
			layout = this;
			if(methodsTmp[i]->name() == J3Thread::get()->vm()->initName) {
				_nbConstructors++;
				if(J3Cst::isPublic(methodsTmp[i]->access()))
					_nbPublicConstructors++;
			}
		}

		methodsTmp[i]->_slot = layout->_nbMethods;
		layout->_methods[layout->_nbMethods++] = methodsTmp[i];

		if(J3Cst::isPublic(methodsTmp[i]->access()))
			layout->_nbPublicMethods++;
	}

	_attributes = readAttributes(&reader);
}

void J3Class::fillFields(J3Field** fields, size_t n) {
	for(size_t i=0; i<n; i++) {
		J3Field*  cur = fields[i];
		J3Layout* layout = J3Cst::isStatic(fields[i]->access()) ? (J3Layout*)staticLayout() : this;

		//if(name() == J3Thread::get()->vm()->names()->get("java/lang/ClassLoader"))
		//fprintf(stderr, " field %s: %s\n", J3Cst::isStatic(fields[i]->access()) ? "static" : "virtual", fields[i]->name()->cStr());

		cur->_offset = layout->structSize();
		cur->_slot = layout->_nbFields;
		layout->_structSize += 1 << fields[i]->type()->logSize();
		layout->fields()[layout->_nbFields++] = *fields[i];

		if(J3Cst::isPublic(fields[i]->access()))
			layout->_nbPublicFields++;
	}
}

J3Attributes* J3Class::readAttributes(J3Reader* reader) {
	size_t nbAttributes = reader->readU2();
	J3Attributes* res = new (loader()->allocator(), nbAttributes) J3Attributes(nbAttributes);
	
	for(size_t i=0; i<nbAttributes; i++) {
		res->attribute(i)->_id     = nameAt(reader->readU2());
		res->attribute(i)->_offset = reader->tell();
		reader->seek(reader->readU4(), reader->SeekCur);
	}

	return res;
}

uint8_t J3Class::getCtpType(uint16_t idx) {
	check(idx);
	return ctpTypes[idx];
}

void* J3Class::getCtpResolved(uint16_t idx) {
	check(idx);
	return ctpResolved[idx];
}

J3StringSymbol* J3Class::stringAt(uint16_t idx) {
	check(idx, J3Cst::CONSTANT_String);
	J3StringSymbol* res = (J3StringSymbol*)ctpResolved[idx];

	if(!res) {
		ctpResolved[idx] = res = loader()->newStringSymbol(J3Thread::get()->vm()->nameToString(nameAt(ctpValues[idx]), 0));
		loader()->addSymbol(res->id(), res);
	}

	return res;
}

float J3Class::floatAt(uint16_t idx) {
	check(idx, J3Cst::CONSTANT_Float);
	J3Value v;
	v.valInteger = ctpValues[idx];
	return v.valFloat;
}

double J3Class::doubleAt(uint16_t idx) {
	check(idx, J3Cst::CONSTANT_Double);
	J3Value v;
	v.valLong = ((uint64_t)ctpValues[idx] << 32) + (uint64_t)ctpValues[idx+1];
	return v.valDouble;
}

uint32_t J3Class::integerAt(uint16_t idx) {
	check(idx, J3Cst::CONSTANT_Integer);
	return ctpValues[idx];
}

uint64_t J3Class::longAt(uint16_t idx) {
	check(idx, J3Cst::CONSTANT_Long);
	return ((uint64_t)ctpValues[idx] << 32) + (uint64_t)ctpValues[idx+1];
}

J3Method* J3Class::interfaceOrMethodAt(uint16_t idx, uint16_t access, bool isInterfaceMethod) {
	J3Method* res = (J3Method*)ctpResolved[idx];
	
	if(res) {
		if((res->access() & J3Cst::ACC_STATIC) != (access & J3Cst::ACC_STATIC))
			J3::classFormatError(this, "inconsistent use of virtual and static methods"); 
		return res;
	}

	uint16_t ntIdx = ctpValues[idx] & 0xffff;
	J3ObjectType* cl = classAt(ctpValues[idx] >> 16);

	check(ntIdx, J3Cst::CONSTANT_NameAndType);

	const vmkit::Name* name = nameAt(ctpValues[ntIdx] >> 16);
	J3Signature* signature = (J3Signature*)ctpResolved[ntIdx];
	if(!signature)
		ctpResolved[idx] = signature = loader()->getSignature(this, nameAt(ctpValues[ntIdx] & 0xffff));

	res = (isInterfaceMethod && J3Cst::isInterface(cl->access())) ? 
		cl->asClass()->findInterfaceMethod(name, signature) : 
		cl->findMethod(access, name, signature);

	ctpResolved[idx] = res;

	return res;
}

J3Method* J3Class::methodAt(uint16_t idx, uint16_t access) {
	check(idx, J3Cst::CONSTANT_Methodref);
	return interfaceOrMethodAt(idx, access, 0);
}

J3Method* J3Class::interfaceMethodAt(uint16_t idx, uint16_t access) {
	check(idx, J3Cst::CONSTANT_InterfaceMethodref);
	return interfaceOrMethodAt(idx, access, 1);
}

J3Field* J3Class::fieldAt(uint16_t idx, uint16_t access) {
	check(idx, J3Cst::CONSTANT_Fieldref);
	J3Field* res = (J3Field*)ctpResolved[idx];

	if(res) {
		if((res->access() & J3Cst::ACC_STATIC) != (access & J3Cst::ACC_STATIC))
			J3::classFormatError(this, "inconstitent use of virtual and static field"); 
		return res;
	}

	uint16_t ntIdx = ctpValues[idx] & 0xffff;
	J3Class* cl = classAt(ctpValues[idx] >> 16)->asClass();

	check(ntIdx, J3Cst::CONSTANT_NameAndType);
	const vmkit::Name* name = nameAt(ctpValues[ntIdx] >> 16);
	J3Type*            type = (J3Type*)ctpResolved[ntIdx];

	if(!type)
		ctpResolved[ntIdx] = type = loader()->getTypeFromDescriptor(this, nameAt(ctpValues[ntIdx] & 0xffff));
	
	res = cl->findField(access, name, type);

	return res;
}

J3ObjectType* J3Class::classAt(uint16_t idx) {
	check(idx, J3Cst::CONSTANT_Class);
	J3ObjectType* res = (J3ObjectType*)ctpResolved[idx];

	if(res)
		return res;

	const char* buf;
	size_t length; 

	utfAt(ctpValues[idx], &buf, &length);

	res = loader()->getTypeFromQualified(this, buf, length);

	ctpResolved[idx] = res;

	return res;
}

void J3Class::utfAt(uint16_t idx, const char** buf, size_t* length) {
	check(idx, J3Cst::CONSTANT_Utf8);

	J3Reader reader(_bytes);

	reader.seek(ctpValues[idx], reader.SeekSet);

	*length = reader.readU2();
	*buf = (const char*)reader.pointer();
}

const vmkit::Name*  J3Class::nameAt(uint16_t idx) {
	check(idx, J3Cst::CONSTANT_Utf8);
	const vmkit::Name* res = (const vmkit::Name*)ctpResolved[idx];

	if(res)
		return res;

	const char* buf;
	size_t length;
	utfAt(idx, &buf, &length);

	res = J3Thread::get()->vm()->names()->get(buf, 0, length);//(const char*)reader.pointer(), 0, len);

	ctpResolved[idx] = (void*)res;

	return res;
}

void J3Class::check(uint16_t idx, uint32_t id) {
	if(idx > nbCtp || (id != -1 && ctpTypes[idx] != id))
		J3::classFormatError(this, "wrong constant pool type %d at index %d for %d", id, idx, nbCtp);
}

void J3Class::doNativeName() {
	J3Mangler mangler(this);

	mangler.mangle(name());
		
	_nativeNameLength = mangler.length() + 3;
	_nativeName = (char*)loader()->allocator()->allocate(_nativeNameLength + 1);

	_nativeName[0] = 'L';
	memcpy(_nativeName + 1, mangler.cStr(), mangler.length());
	_nativeName[_nativeNameLength-2] = '_';
	_nativeName[_nativeNameLength-1] = '2';
	_nativeName[_nativeNameLength]   = 0;
}

/*  
 *  ------------ J3ArrayClass ------------
 */
J3ArrayClass::J3ArrayClass(J3ClassLoader* loader, J3Type* component, const vmkit::Name* name) : J3ObjectType(loader, name) {
	_component = component;

	if(!name) {
		const vmkit::Name* compName = component->name();
		uint32_t           len = compName->length();
		char               buf[len + 16];
		uint32_t           pos = 0;

		//printf("     build array of %s\n", component->name()->cStr());
		buf[pos++] = J3Cst::ID_Array;
	
		if(component->isClass())
			buf[pos++] = J3Cst::ID_Classname;
		memcpy(buf+pos, compName->cStr(), len * sizeof(char));
		pos += len;
		if(component->isClass())
			buf[pos++] = J3Cst::ID_End;
		buf[pos] = 0;

		_name = J3Thread::get()->vm()->names()->get(buf);
	}
}

J3ObjectHandle* J3ArrayClass::clone(J3ObjectHandle* obj) {
	size_t n = obj->arrayLength();
	J3ObjectHandle* res = J3ObjectHandle::doNewArray(this, n);
	obj->rawArrayCopyTo(0, res, 0, n<<component()->logSize());
	return res;
}

uint16_t J3ArrayClass::access() {
	return super()->access();
}

uint16_t J3ArrayClass::modifiers() {
	return super()->modifiers();
}

J3Class* J3ArrayClass::super() {
	return J3Thread::get()->vm()->objectClass;
}

J3Method* J3ArrayClass::findMethod(uint32_t access, const vmkit::Name* name, J3Signature* signature, bool error) {
	return super()->findMethod(access, name, signature, error);
}

void J3ArrayClass::doResolve(J3Field* hiddenFields, size_t nbHiddenFields) {
	lock();
	if(status < RESOLVED) {
		status = RESOLVED;
		vtSymbol()->setVt(J3VirtualTable::create(this));
		prepareInterfaceTable();
	}
	unlock();
}
	
void J3ArrayClass::doInitialise() {
	resolve();
	status = INITED;
}

void J3ArrayClass::doNativeName() {
	uint32_t len = component()->nativeNameLength();

	_nativeNameLength = len + 2;
	_nativeName = (char*)loader()->allocator()->allocate(_nativeNameLength + 1);

	_nativeName[0] = '_';
	_nativeName[1] = '3';

	memcpy(_nativeName+2, component()->nativeName(), len);
	_nativeName[_nativeNameLength] = 0;
}

J3ObjectHandle* J3ArrayClass::multianewArray(uint32_t dim, uint32_t* args) {
	J3ObjectHandle* res = J3ObjectHandle::doNewArray(this, args[0]);

	if(dim > 1)
		for(uint32_t i=0; i<args[0]; i++)
			res->setObjectAt(i, component()->asArrayClass()->multianewArray(dim-1, args+1));

	return res;
}

/*  
 *  ------------ J3Primitive ------------
 */
J3Primitive::J3Primitive(J3ClassLoader* loader, char id, llvm::Type* type, uint32_t logSize) : 
	J3Type(loader, J3Thread::get()->vm()->names()->get(id)) {
	_llvmType = type;
	_nativeName = (char*)loader->allocator()->allocate(2);
	_nativeName[0] = id;
	_nativeName[1] = 0;
	_nativeNameLength = 1;
	vtSymbol()->setVt(J3VirtualTable::create(this));
	_logSize = logSize;
}

void J3Primitive::defineJavaClass(const char* className) {
	J3* vm = J3Thread::get()->vm();
	_javaClass = vm->initialClassLoader->loadClass(vm->names()->get(className))->javaClass(0);
}
