//===----- JavaAOTCompiler.cpp - Support for Ahead of Time Compiler --------===//
//
//                            The VMKit project
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "llvm/BasicBlock.h"
#include "llvm/Constants.h"
#include "llvm/Instructions.h"
#include "llvm/LLVMContext.h"
#include "llvm/Module.h"
#include "llvm/PassManager.h"
#include "llvm/Support/raw_ostream.h"

#include "mvm/Threads/Thread.h"

#include "j3/J3Intrinsics.h"
#include "j3/JavaAOTCompiler.h"
#include "j3/JavaJITCompiler.h"

#include "JavaArray.h"
#include "JavaConstantPool.h"
#include "JavaString.h"
#include "JavaThread.h"
#include "JavaTypes.h"
#include "JavaUpcalls.h"
#include "Jnjvm.h"
#include "Reader.h"
#include "Zip.h"

#include <cstdio>

using namespace j3;
using namespace llvm;

bool JavaAOTCompiler::isCompiling(const CommonClass* cl) const {
  if (cl->isClass()) {
    // A class is being static compiled if owner class is not null.
    return cl->asClass()->getOwnerClass() != 0;
  } else if (cl->isArray()) {
    // Only compile an aray if we are compiling rt.jar.
    return compileRT;
  } else if (cl->isPrimitive() && compileRT) {
    return true;
  } else {
    return false;
  }
}

Constant* JavaAOTCompiler::getNativeClass(CommonClass* classDef) {

  if (classDef->isClass() || isCompiling(classDef) || assumeCompiled) {

    native_class_iterator End = nativeClasses.end();
    native_class_iterator I = nativeClasses.find(classDef);
    if (I == End) {
      const llvm::Type* Ty = 0;
      
      if (classDef->isArray()) {
        Ty = JavaIntrinsics.JavaClassArrayType->getContainedType(0); 
      } else if (classDef->isPrimitive()) {
        Ty = JavaIntrinsics.JavaClassPrimitiveType->getContainedType(0); 
      } else {
        Ty = JavaIntrinsics.JavaClassType->getContainedType(0); 
      }
    
      GlobalVariable* varGV =
        new GlobalVariable(*getLLVMModule(), Ty, false,
                        GlobalValue::ExternalLinkage, 0,
                        UTF8Buffer(classDef->name).toCompileName()->cString());
    
      nativeClasses.insert(std::make_pair(classDef, varGV));

      if (classDef->isClass() && isCompiling(classDef)) {
        Constant* C = CreateConstantFromClass(classDef->asClass());
        varGV->setInitializer(C);
      } else if (classDef->isArray()) {
        Constant* C = CreateConstantFromClassArray(classDef->asArrayClass());
        varGV->setInitializer(C);
      } else if (classDef->isPrimitive()) {
        Constant* C = 
          CreateConstantFromClassPrimitive(classDef->asPrimitiveClass());
        varGV->setInitializer(C);
      }

      return varGV;

    } else {
      return I->second;
    }
  } else if (classDef->isArray()) {
    array_class_iterator End = arrayClasses.end();
    array_class_iterator I = arrayClasses.find(classDef->asArrayClass());
    if (I == End) {
      const llvm::Type* Ty = JavaIntrinsics.JavaClassArrayType;
      Module& Mod = *getLLVMModule();
    
      GlobalVariable* varGV = 
        new GlobalVariable(Mod, Ty, false, GlobalValue::InternalLinkage,
                           Constant::getNullValue(Ty),
                        UTF8Buffer(classDef->name).toCompileName()->cString());
    
      arrayClasses.insert(std::make_pair(classDef->asArrayClass(), varGV));
      return varGV;
    } else {
      return I->second;
    }
  } else {
    assert(0 && "Implement me");
  }
  return 0;
}

Constant* JavaAOTCompiler::getConstantPool(JavaConstantPool* ctp) {
  llvm::Constant* varGV = 0;
  constant_pool_iterator End = constantPools.end();
  constant_pool_iterator I = constantPools.find(ctp);
  if (I == End) {
    const Type* Ty = JavaIntrinsics.ConstantPoolType->getContainedType(0);
    Module& Mod = *getLLVMModule();
    
    varGV = new GlobalVariable(Mod, Ty, false,
                               GlobalValue::InternalLinkage,
                               Constant::getNullValue(Ty), "");
    constantPools.insert(std::make_pair(ctp, varGV));
    return varGV;
  } else {
    return I->second;
  }
}

Constant* JavaAOTCompiler::getMethodInClass(JavaMethod* meth) {
  Class* cl = meth->classDef;
  Constant* MOffset = 0;
  Constant* Array = 0;

  for (uint32 i = 0; i < cl->nbVirtualMethods + cl->nbStaticMethods; ++i) {
    if (&cl->virtualMethods[i] == meth) {
      MOffset = ConstantInt::get(Type::getInt32Ty(getLLVMContext()), i);
      break;
    }
  }
  assert(MOffset && "No offset for method");

  method_iterator SI = virtualMethods.find(cl);
  if (SI != virtualMethods.end()) {
    Array = SI->second; 
    assert(Array && "No array in class");
  } else {
    std::string name(UTF8Buffer(cl->name).toCompileName()->cString());
    name += "_VirtualMethods";
    Module& Mod = *getLLVMModule();
    const Type* ATy =
      ArrayType::get(JavaIntrinsics.JavaMethodType->getContainedType(0),
                     cl->nbVirtualMethods + cl->nbStaticMethods);

    Array = new GlobalVariable(Mod, ATy, false, GlobalValue::ExternalLinkage,
                               0, name);
    virtualMethods.insert(std::make_pair(cl, Array));
  }
    
  Constant* GEPs[2] = { getIntrinsics()->constantZero, MOffset };
  return ConstantExpr::getGetElementPtr(Array, GEPs, 2);
}

Constant* JavaAOTCompiler::getString(JavaString* str) {
  string_iterator SI = strings.find(str);
  if (SI != strings.end()) {
    return SI->second;
  } else {
    assert(str && "No string given");
    LLVMClassInfo* LCI = getClassInfo(str->getClass()->asClass());
    const llvm::Type* Ty = LCI->getVirtualType();
    Module& Mod = *getLLVMModule();
    
    GlobalVariable* varGV = 
      new GlobalVariable(Mod, Ty->getContainedType(0), false,
                         GlobalValue::InternalLinkage, 0, "");
    Constant* res = ConstantExpr::getCast(Instruction::BitCast, varGV,
                                          JavaIntrinsics.JavaObjectType);
    strings.insert(std::make_pair(str, res));
    Constant* C = CreateConstantFromJavaString(str);
    varGV->setInitializer(C);
    return res;
  }
}

Constant* JavaAOTCompiler::getStringPtr(JavaString** str) {
  fprintf(stderr, "Implement me");
  abort();
}

Constant* JavaAOTCompiler::getJavaClass(CommonClass* cl) {
  java_class_iterator End = javaClasses.end();
  java_class_iterator I = javaClasses.find(cl);
  if (I == End) {
    final_object_iterator End = finalObjects.end();
    final_object_iterator I = finalObjects.find(cl->delegatee[0]);
    if (I == End) {
    
      Class* javaClass = cl->classLoader->bootstrapLoader->upcalls->newClass;
      LLVMClassInfo* LCI = getClassInfo(javaClass);
      const llvm::Type* Ty = LCI->getVirtualType();
      Module& Mod = *getLLVMModule();
    
      GlobalVariable* varGV = 
        new GlobalVariable(Mod, Ty->getContainedType(0), false,
                           GlobalValue::InternalLinkage, 0, "");
    
      Constant* res = ConstantExpr::getCast(Instruction::BitCast, varGV,
                                            JavaIntrinsics.JavaObjectType);
  
      javaClasses.insert(std::make_pair(cl, res));
      varGV->setInitializer(CreateConstantFromJavaClass(cl));
      return res;
    } else {
      return I->second;
    }
  } else {
    return I->second;
  }
}

Constant* JavaAOTCompiler::getJavaClassPtr(CommonClass* cl) {
#ifdef ISOLATE
  abort();
  return 0;
#else
  // Make sure it's emitted.
  getJavaClass(cl);

  Constant* Cl = getNativeClass(cl);
  Cl = ConstantExpr::getBitCast(Cl, JavaIntrinsics.JavaCommonClassType);

  Constant* GEP[2] = { getIntrinsics()->constantZero,
                       getIntrinsics()->constantZero };
  
  Constant* TCMArray = ConstantExpr::getGetElementPtr(Cl, GEP, 2);
    
  Constant* GEP2[2] = { getIntrinsics()->constantZero,
                        getIntrinsics()->constantZero };

  Constant* Ptr = ConstantExpr::getGetElementPtr(TCMArray, GEP2, 2);
  return Ptr;
#endif
}

JavaObject* JavaAOTCompiler::getFinalObject(llvm::Value* obj) {
  if (Constant* CI = dyn_cast<Constant>(obj)) {
    reverse_final_object_iterator End = reverseFinalObjects.end();
    reverse_final_object_iterator I = reverseFinalObjects.find(CI);
    if (I != End) return I->second;
  }
  
  return 0;
}

Constant* JavaAOTCompiler::HandleMagic(JavaObject* obj, CommonClass* objCl) {

  static const UTF8* AddressArray = objCl->classLoader->asciizConstructUTF8("org/vmmagic/unboxed/AddressArray");
  static const UTF8* WordArray = objCl->classLoader->asciizConstructUTF8("org/vmmagic/unboxed/WordArray");
  static const UTF8* ExtentArray = objCl->classLoader->asciizConstructUTF8("org/vmmagic/unboxed/ExtentArray");
  static const UTF8* ObjectReferenceArray = objCl->classLoader->asciizConstructUTF8("org/vmmagic/unboxed/ObjectReferenceArray");
  static const UTF8* OffsetArray = objCl->classLoader->asciizConstructUTF8("org/vmmagic/unboxed/OffsetArray");
  const UTF8* name = objCl->name;

  if (name->equals(AddressArray) || name->equals(WordArray) ||
      name->equals(ExtentArray) || name->equals(ObjectReferenceArray) || 
      name->equals(OffsetArray)) {
    
    intptr_t* realObj = (intptr_t*)obj;
    intptr_t size = realObj[0];

    const ArrayType* ATy = ArrayType::get(JavaIntrinsics.JavaObjectType,
                                          size + 1);
  
    std::vector<Constant*> Vals;
    for (sint32 i = 0; i < size + 1; ++i) {
      Constant* CI = ConstantInt::get(Type::getInt64Ty(getLLVMContext()),
                                      uint64_t(realObj[i]));
      CI = ConstantExpr::getIntToPtr(CI, JavaIntrinsics.JavaObjectType);
      Vals.push_back(CI);
    }

    Constant* CA = ConstantArray::get(ATy, Vals);
  
    GlobalVariable* varGV = new GlobalVariable(*getLLVMModule(), CA->getType(),
                                               false,
                                               GlobalValue::InternalLinkage,
                                               CA, "");
 
    return ConstantExpr::getBitCast(varGV, JavaIntrinsics.JavaObjectType);

  } else {
    Constant* CI = ConstantInt::get(Type::getInt64Ty(getLLVMContext()),
                                    uint64_t(obj));
    CI = ConstantExpr::getIntToPtr(CI, JavaIntrinsics.JavaObjectType);
    return CI;
  }
}


Constant* JavaAOTCompiler::getFinalObject(JavaObject* obj, CommonClass* objCl) {
  llvm::GlobalVariable* varGV = 0;
  final_object_iterator End = finalObjects.end();
  final_object_iterator I = finalObjects.find(obj);
  if (I == End) {
  
    if (mvm::Collector::begOf(obj)) {
      const Type* Ty = 0;
      CommonClass* cl = obj->getClass();
      
      if (cl->isArray()) {
        Classpath* upcalls = cl->classLoader->bootstrapLoader->upcalls;
        CommonClass* subClass = cl->asArrayClass()->baseClass();
        if (subClass->isPrimitive()) {
          if (subClass == upcalls->OfBool) {
            Ty = Type::getInt8Ty(getLLVMContext());
          } else if (subClass == upcalls->OfByte) {
            Ty = Type::getInt8Ty(getLLVMContext());
          } else if (subClass == upcalls->OfShort) {
            Ty = Type::getInt16Ty(getLLVMContext());
          } else if (subClass == upcalls->OfChar) {
            Ty = Type::getInt16Ty(getLLVMContext());
          } else if (subClass == upcalls->OfInt) {
            Ty = Type::getInt32Ty(getLLVMContext());
          } else if (subClass == upcalls->OfFloat) {
            Ty = Type::getFloatTy(getLLVMContext());
          } else if (subClass == upcalls->OfLong) {
            Ty = Type::getInt64Ty(getLLVMContext());
          } else if (subClass == upcalls->OfDouble) {
            Ty = Type::getDoubleTy(getLLVMContext());
          } else {
            abort();
          }
        } else {
          Ty = JavaIntrinsics.JavaObjectType;
        }
        
        std::vector<const Type*> Elemts;
        const ArrayType* ATy = ArrayType::get(Ty, ((JavaArray*)obj)->size);
        Elemts.push_back(JavaIntrinsics.JavaObjectType->getContainedType(0));
        Elemts.push_back(JavaIntrinsics.pointerSizeType);
        Elemts.push_back(ATy);
        Ty = StructType::get(getLLVMModule()->getContext(), Elemts);

      } else {
        LLVMClassInfo* LCI = getClassInfo(cl->asClass());
        Ty = LCI->getVirtualType()->getContainedType(0);
      }

      Module& Mod = *getLLVMModule();
      // Set as External, so that inlining MMTk code works.
      varGV = new GlobalVariable(Mod, Ty, false, GlobalValue::ExternalLinkage,
                                 0, "finalObject");

      Constant* C = ConstantExpr::getBitCast(varGV,
                                             JavaIntrinsics.JavaObjectType);
  
      finalObjects.insert(std::make_pair(obj, C));
      reverseFinalObjects.insert(std::make_pair(C, obj));
    
      varGV->setInitializer(CreateConstantFromJavaObject(obj));
      return C;
    } else {
      Constant* CI = HandleMagic(obj, objCl);
      finalObjects.insert(std::make_pair(obj, CI));
      return CI;
    }
  } else {
    return I->second;
  }
}

Constant* JavaAOTCompiler::CreateConstantFromStaticInstance(Class* cl) {
  LLVMClassInfo* LCI = getClassInfo(cl);
  const Type* Ty = LCI->getStaticType();
  const StructType* STy = dyn_cast<StructType>(Ty->getContainedType(0));
  
  std::vector<Constant*> Elts;
  
  for (uint32 i = 0; i < cl->nbStaticFields; ++i) {
    JavaField& field = cl->staticFields[i];
    const Typedef* type = field.getSignature();
    LLVMAssessorInfo& LAI = getTypedefInfo(type);
    const Type* Ty = LAI.llvmType;

    Attribut* attribut = field.lookupAttribut(Attribut::constantAttribut);

    if (!attribut) {
      void* obj = cl->getStaticInstance();
      if (obj) {
        if (type->isPrimitive()) {
          const PrimitiveTypedef* prim = (const PrimitiveTypedef*)type;
          if (prim->isBool() || prim->isByte()) {
            ConstantInt* CI = ConstantInt::get(
                Type::getInt8Ty(getLLVMContext()),
                field.getInt8Field(obj));
            Elts.push_back(CI);
          } else if (prim->isShort() || prim->isChar()) {
            ConstantInt* CI = ConstantInt::get(
                Type::getInt16Ty(getLLVMContext()),
                field.getInt16Field(obj));
            Elts.push_back(CI);
          } else if (prim->isInt()) {
            ConstantInt* CI = ConstantInt::get(
                Type::getInt32Ty(getLLVMContext()),
                field.getInt32Field(obj));
            Elts.push_back(CI);
          } else if (prim->isLong()) {
            ConstantInt* CI = ConstantInt::get(
                Type::getInt64Ty(getLLVMContext()),
                field.getLongField(obj));
            Elts.push_back(CI);
          } else if (prim->isFloat()) {
            Constant* CF = ConstantFP::get(
                Type::getFloatTy(getLLVMContext()),
                field.getFloatField(obj));
            Elts.push_back(CF);
          } else if (prim->isDouble()) {
            Constant* CF = ConstantFP::get(
                Type::getDoubleTy(getLLVMContext()),
                field.getDoubleField(obj));
            Elts.push_back(CF);
          } else {
            abort();
          }
        } else {
          JavaObject* val = field.getObjectField(obj);
          if (val) {
            JnjvmClassLoader* JCL = cl->classLoader;
            CommonClass* FieldCl = field.getSignature()->assocClass(JCL);
            Constant* CO = getFinalObject(val, FieldCl);
            Elts.push_back(CO);
          } else {
            Elts.push_back(Constant::getNullValue(Ty));
          }
        }
      } else {
        Elts.push_back(Constant::getNullValue(Ty));
      }
    } else {
      Reader reader(attribut, &(cl->bytes));
      JavaConstantPool * ctpInfo = cl->ctpInfo;
      uint16 idx = reader.readU2();
      if (type->isPrimitive()) {
        if (Ty == Type::getInt64Ty(getLLVMContext())) {
          Elts.push_back(ConstantInt::get(Ty, (uint64)ctpInfo->LongAt(idx)));
        } else if (Ty == Type::getDoubleTy(getLLVMContext())) {
          Elts.push_back(ConstantFP::get(Ty, ctpInfo->DoubleAt(idx)));
        } else if (Ty == Type::getFloatTy(getLLVMContext())) {
          Elts.push_back(ConstantFP::get(Ty, ctpInfo->FloatAt(idx)));
        } else {
          Elts.push_back(ConstantInt::get(Ty, (uint64)ctpInfo->IntegerAt(idx)));
        }
      } else if (type->isReference()){
        const UTF8* utf8 = ctpInfo->UTF8At(ctpInfo->ctpDef[idx]);
        JavaString* obj = ctpInfo->resolveString(utf8, idx);
        Constant* C = getString(obj);
        C = ConstantExpr::getBitCast(C, JavaIntrinsics.JavaObjectType);
        Elts.push_back(C);
      } else {
        fprintf(stderr, "Implement me");
        abort();
      }
    }
  }
   
  return ConstantStruct::get(STy, Elts);
}

Constant* JavaAOTCompiler::getStaticInstance(Class* classDef) {
#ifdef ISOLATE
  assert(0 && "Should not be here");
  abort();
#endif
  static_instance_iterator End = staticInstances.end();
  static_instance_iterator I = staticInstances.find(classDef);
  if (I == End) {
    
    LLVMClassInfo* LCI = getClassInfo(classDef);
    const Type* Ty = LCI->getStaticType();
    Ty = Ty->getContainedType(0);
    std::string name(UTF8Buffer(classDef->name).toCompileName()->cString());
    name += "_static";
    Module& Mod = *getLLVMModule();
    GlobalVariable* varGV = 
      new GlobalVariable(Mod, Ty, false, GlobalValue::ExternalLinkage,
                         0, name);

    Constant* res = ConstantExpr::getCast(Instruction::BitCast, varGV,
                                          JavaIntrinsics.ptrType);
    staticInstances.insert(std::make_pair(classDef, res));
    
    if (isCompiling(classDef)) { 
      Constant* C = CreateConstantFromStaticInstance(classDef);
      varGV->setInitializer(C);
    }

    return res;
  } else {
    return I->second;
  }
}

Constant* JavaAOTCompiler::getVirtualTable(JavaVirtualTable* VT) {
  CommonClass* classDef = VT->cl;
  uint32 size = 0;
  if (classDef->isClass()) {
    LLVMClassInfo* LCI = getClassInfo(classDef->asClass());
    LCI->getVirtualType();
    size = classDef->asClass()->virtualTableSize;
  } else {
    size = JavaVirtualTable::getBaseSize();
  }
  llvm::Constant* res = 0;
  virtual_table_iterator End = virtualTables.end();
  virtual_table_iterator I = virtualTables.find(VT);
  if (I == End) {
    
    const ArrayType* ATy = 
      dyn_cast<ArrayType>(JavaIntrinsics.VTType->getContainedType(0));
    const PointerType* PTy = dyn_cast<PointerType>(ATy->getContainedType(0));
    ATy = ArrayType::get(PTy, size);
    std::string name(UTF8Buffer(classDef->name).toCompileName()->cString());
    name += "_VT";
    // Do not set a virtual table as a constant, because the runtime may
    // modify it.
    Module& Mod = *getLLVMModule();
    GlobalVariable* varGV = new GlobalVariable(Mod, ATy, false,
                                               GlobalValue::ExternalLinkage,
                                               0, name);
  
    res = ConstantExpr::getCast(Instruction::BitCast, varGV,
                                JavaIntrinsics.VTType);
    virtualTables.insert(std::make_pair(VT, res));
  
    if (isCompiling(classDef) || assumeCompiled) {
      Constant* C = CreateConstantFromVT(VT);
      varGV->setInitializer(C);
    }
    
    return res;
  } else {
    return I->second;
  } 
}

Constant* JavaAOTCompiler::getNativeFunction(JavaMethod* meth, void* ptr) {
  llvm::Constant* varGV = 0;
  native_function_iterator End = nativeFunctions.end();
  native_function_iterator I = nativeFunctions.find(meth);
  if (I == End) {
    
    LLVMSignatureInfo* LSI = getSignatureInfo(meth->getSignature());
    const llvm::Type* valPtrType = LSI->getNativePtrType();
    
    Module& Mod = *getLLVMModule();
    varGV = new GlobalVariable(Mod, valPtrType, false,
                               GlobalValue::InternalLinkage,
                               Constant::getNullValue(valPtrType), "");
  
    nativeFunctions.insert(std::make_pair(meth, varGV));
    return varGV;
  } else {
    return I->second;
  }
}

Constant* JavaAOTCompiler::CreateConstantForBaseObject(CommonClass* cl) {
  const StructType* STy = 
    dyn_cast<StructType>(JavaIntrinsics.JavaObjectType->getContainedType(0));
  
  std::vector<Constant*> Elmts;

  // VT
  Elmts.push_back(getVirtualTable(cl->virtualVT));
  
  // lock
  Constant* L = ConstantInt::get(Type::getInt64Ty(getLLVMContext()), 0);
  Elmts.push_back(ConstantExpr::getIntToPtr(L, JavaIntrinsics.ptrType));

  return ConstantStruct::get(STy, Elmts);
}

Constant* JavaAOTCompiler::CreateConstantFromJavaClass(CommonClass* cl) {
  Class* javaClass = cl->classLoader->bootstrapLoader->upcalls->newClass;
  LLVMClassInfo* LCI = getClassInfo(javaClass);
  const StructType* STy = 
    dyn_cast<StructType>(LCI->getVirtualType()->getContainedType(0));

  std::vector<Constant*> Elmts;

  // JavaObject
  Elmts.push_back(CreateConstantForBaseObject(javaClass));
  
  // signers
  Elmts.push_back(Constant::getNullValue(JavaIntrinsics.JavaObjectType));
  
  // pd
  Elmts.push_back(Constant::getNullValue(JavaIntrinsics.JavaObjectType));
  
  // vmdata
  Constant* Cl = getNativeClass(cl);
  Cl = ConstantExpr::getCast(Instruction::BitCast, Cl,
                             JavaIntrinsics.JavaObjectType);
  Elmts.push_back(Cl);

  // constructor
  Elmts.push_back(Constant::getNullValue(JavaIntrinsics.JavaObjectType));

  return ConstantStruct::get(STy, Elmts);
}

Constant* JavaAOTCompiler::CreateConstantFromJavaObject(JavaObject* obj) {
  CommonClass* cl = obj->getClass();

  if (cl->isArray()) {
    Classpath* upcalls = cl->classLoader->bootstrapLoader->upcalls;
    CommonClass* subClass = cl->asArrayClass()->baseClass();
    if (subClass->isPrimitive()) {
      if (subClass == upcalls->OfBool) {
        return CreateConstantFromIntArray<ArrayUInt8>((ArrayUInt8*)obj,
                                        Type::getInt8Ty(getLLVMContext()));
      } else if (subClass == upcalls->OfByte) {
        return CreateConstantFromIntArray<ArraySInt8>((ArraySInt8*)obj,
                                        Type::getInt8Ty(getLLVMContext()));
      } else if (subClass == upcalls->OfShort) {
        return CreateConstantFromIntArray<ArraySInt16>((ArraySInt16*)obj,
                                        Type::getInt16Ty(getLLVMContext()));
      } else if (subClass == upcalls->OfChar) {
        return CreateConstantFromIntArray<ArrayUInt16>((ArrayUInt16*)obj,
                                        Type::getInt16Ty(getLLVMContext()));
      } else if (subClass == upcalls->OfInt) {
        return CreateConstantFromIntArray<ArraySInt32>((ArraySInt32*)obj,
                                        Type::getInt32Ty(getLLVMContext()));
      } else if (subClass == upcalls->OfFloat) {
        return CreateConstantFromFPArray<ArrayFloat>((ArrayFloat*)obj,
                                        Type::getFloatTy(getLLVMContext()));
      } else if (subClass == upcalls->OfLong) {
        return CreateConstantFromIntArray<ArrayLong>((ArrayLong*)obj,
                                        Type::getInt64Ty(getLLVMContext()));
      } else if (subClass == upcalls->OfDouble) {
        return CreateConstantFromFPArray<ArrayDouble>((ArrayDouble*)obj,
                                        Type::getDoubleTy(getLLVMContext()));
      } else {
        abort();
      }
    } else {
      return CreateConstantFromObjectArray((ArrayObject*)obj);
    }
  } else {
    
    std::vector<Constant*> Elmts;
    
    // JavaObject
    Constant* CurConstant = CreateConstantForBaseObject(obj->getClass());

    for (uint32 j = 1; j <= cl->virtualVT->depth; ++j) {
      std::vector<Constant*> TempElts;
      Elmts.push_back(CurConstant);
      TempElts.push_back(CurConstant);
      Class* curCl = cl->virtualVT->display[j]->cl->asClass();
      LLVMClassInfo* LCI = getClassInfo(curCl);
      const StructType* STy = 
        dyn_cast<StructType>(LCI->getVirtualType()->getContainedType(0));

      for (uint32 i = 0; i < curCl->nbVirtualFields; ++i) {
        JavaField& field = curCl->virtualFields[i];
        const Typedef* type = field.getSignature();
        if (type->isPrimitive()) {
          const PrimitiveTypedef* prim = (const PrimitiveTypedef*)type;
          if (prim->isBool() || prim->isByte()) {
            ConstantInt* CI = ConstantInt::get(Type::getInt8Ty(getLLVMContext()),
                                               field.getInt8Field(obj));
            TempElts.push_back(CI);
          } else if (prim->isShort() || prim->isChar()) {
            ConstantInt* CI = ConstantInt::get(Type::getInt16Ty(getLLVMContext()),
                                               field.getInt16Field(obj));
            TempElts.push_back(CI);
          } else if (prim->isInt()) {
            ConstantInt* CI = ConstantInt::get(Type::getInt32Ty(getLLVMContext()),
                                               field.getInt32Field(obj));
            TempElts.push_back(CI);
          } else if (prim->isLong()) {
            ConstantInt* CI = ConstantInt::get(Type::getInt64Ty(getLLVMContext()),
                                               field.getLongField(obj));
            TempElts.push_back(CI);
          } else if (prim->isFloat()) {
            Constant* CF = ConstantFP::get(Type::getFloatTy(getLLVMContext()),
                                           field.getFloatField(obj));
            TempElts.push_back(CF);
          } else if (prim->isDouble()) {
            Constant* CF = ConstantFP::get(Type::getDoubleTy(getLLVMContext()),
                                           field.getDoubleField(obj));
            TempElts.push_back(CF);
          } else {
            abort();
          }
        } else {
          JavaObject* val = field.getObjectField(obj);
          if (val) {
            JnjvmClassLoader* JCL = cl->classLoader;
            CommonClass* FieldCl = field.getSignature()->assocClass(JCL);
            Constant* C = getFinalObject(val, FieldCl);
            TempElts.push_back(C);
          } else {
            const llvm::Type* Ty = JavaIntrinsics.JavaObjectType;
            TempElts.push_back(Constant::getNullValue(Ty));
          }
        }
      }
      CurConstant = ConstantStruct::get(STy, TempElts);
    }

    return CurConstant;
  }
}

Constant* JavaAOTCompiler::CreateConstantFromJavaString(JavaString* str) {
  Class* cl = str->getClass()->asClass();
  LLVMClassInfo* LCI = getClassInfo(cl);
  const StructType* STy = 
    dyn_cast<StructType>(LCI->getVirtualType()->getContainedType(0));

  std::vector<Constant*> Elmts;

  Elmts.push_back(CreateConstantForBaseObject(cl));

  Constant* Array = CreateConstantFromIntArray<ArrayUInt16>(str->value,
                                        Type::getInt16Ty(getLLVMContext()));
  

  Module& Mod = *getLLVMModule();
  GlobalVariable* varGV = new GlobalVariable(Mod, Array->getType(), false,
                                             GlobalValue::InternalLinkage,
                                             Array, "");
 
	Array = ConstantExpr::getBitCast(varGV, JavaIntrinsics.JavaObjectType);

  Elmts.push_back(Array);
  Elmts.push_back(ConstantInt::get(Type::getInt32Ty(getLLVMContext()),
                                   str->count));
  Elmts.push_back(ConstantInt::get(Type::getInt32Ty(getLLVMContext()),
                                   str->cachedHashCode));
  Elmts.push_back(ConstantInt::get(Type::getInt32Ty(getLLVMContext()),
                                   str->offset));
 
  return ConstantStruct::get(STy, Elmts);
}


Constant* JavaAOTCompiler::CreateConstantFromAttribut(Attribut& attribut) {
  const StructType* STy = 
    dyn_cast<StructType>(JavaIntrinsics.AttributType->getContainedType(0));


  std::vector<Constant*> Elmts;

  // name
  Elmts.push_back(getUTF8(attribut.name));

  // start
  Elmts.push_back(ConstantInt::get(Type::getInt32Ty(getLLVMContext()), attribut.start));

  // nbb
  Elmts.push_back(ConstantInt::get(Type::getInt32Ty(getLLVMContext()), attribut.nbb));
  
  return ConstantStruct::get(STy, Elmts);
}

Constant* JavaAOTCompiler::CreateConstantFromCommonClass(CommonClass* cl) {
  const StructType* STy = 
    dyn_cast<StructType>(JavaIntrinsics.JavaCommonClassType->getContainedType(0));
  Module& Mod = *getLLVMModule();
  
  const llvm::Type* TempTy = 0;

  std::vector<Constant*> CommonClassElts;
  std::vector<Constant*> TempElmts;

  // delegatee
  const ArrayType* ATy = dyn_cast<ArrayType>(STy->getContainedType(0));
  assert(ATy && "Malformed type");

  Constant* TCM[1] = { getJavaClass(cl) };
  CommonClassElts.push_back(ConstantArray::get(ATy, TCM, 1));
  
  // access
  CommonClassElts.push_back(ConstantInt::get(Type::getInt16Ty(getLLVMContext()), cl->access));
 
  // interfaces
  if (cl->nbInterfaces) {
    for (uint32 i = 0; i < cl->nbInterfaces; ++i) {
      TempElmts.push_back(getNativeClass(cl->interfaces[i]));
    }

    ATy = ArrayType::get(JavaIntrinsics.JavaClassType, cl->nbInterfaces);
    Constant* interfaces = ConstantArray::get(ATy, TempElmts);
    interfaces = new GlobalVariable(Mod, ATy, true,
                                    GlobalValue::InternalLinkage,
                                    interfaces, "");
    interfaces = ConstantExpr::getCast(Instruction::BitCast, interfaces,
                            PointerType::getUnqual(JavaIntrinsics.JavaClassType));

    CommonClassElts.push_back(interfaces);
  } else {
    const Type* Ty = PointerType::getUnqual(JavaIntrinsics.JavaClassType);
    CommonClassElts.push_back(Constant::getNullValue(Ty));
  }

  // nbInterfaces
  CommonClassElts.push_back(ConstantInt::get(Type::getInt16Ty(getLLVMContext()), cl->nbInterfaces));

  // name
  CommonClassElts.push_back(getUTF8(cl->name));

  // super
  if (cl->super) {
    CommonClassElts.push_back(getNativeClass(cl->super));
  } else {
    TempTy = JavaIntrinsics.JavaClassType;
    CommonClassElts.push_back(Constant::getNullValue(TempTy));
  }

  // classLoader: store the static initializer, it will be overriden once
  // the class is loaded.
  Constant* loader = ConstantExpr::getBitCast(StaticInitializer,
                                              JavaIntrinsics.ptrType);
  CommonClassElts.push_back(loader);
  
  // virtualTable
  if (cl->virtualVT) {
    CommonClassElts.push_back(getVirtualTable(cl->virtualVT));
  } else {
    TempTy = JavaIntrinsics.VTType;
    CommonClassElts.push_back(Constant::getNullValue(TempTy));
  }
  return ConstantStruct::get(STy, CommonClassElts);
}

Constant* JavaAOTCompiler::CreateConstantFromJavaField(JavaField& field) {
  const StructType* STy = 
    dyn_cast<StructType>(JavaIntrinsics.JavaFieldType->getContainedType(0));
  
  std::vector<Constant*> FieldElts;
  std::vector<Constant*> TempElts;
  
  // signature
  FieldElts.push_back(Constant::getNullValue(JavaIntrinsics.ptrType));
  
  // access
  FieldElts.push_back(ConstantInt::get(Type::getInt16Ty(getLLVMContext()), field.access));

  // name
  FieldElts.push_back(getUTF8(field.name));

  // type
  FieldElts.push_back(getUTF8(field.type));
  
  // attributs 
  if (field.nbAttributs) {
    const llvm::Type* AttrTy = JavaIntrinsics.AttributType->getContainedType(0);
    const ArrayType* ATy = ArrayType::get(AttrTy, field.nbAttributs);
    for (uint32 i = 0; i < field.nbAttributs; ++i) {
      TempElts.push_back(CreateConstantFromAttribut(field.attributs[i]));
    }

    Constant* attributs = ConstantArray::get(ATy, TempElts);
    TempElts.clear();
    attributs = new GlobalVariable(*getLLVMModule(), ATy, true,
                                   GlobalValue::InternalLinkage,
                                   attributs, "");
    attributs = ConstantExpr::getCast(Instruction::BitCast, attributs,
                                      JavaIntrinsics.AttributType);
  
    FieldElts.push_back(attributs);
  } else {
    FieldElts.push_back(Constant::getNullValue(JavaIntrinsics.AttributType));
  }
  
  // nbAttributs
  FieldElts.push_back(ConstantInt::get(Type::getInt16Ty(getLLVMContext()), field.nbAttributs));

  // classDef
  FieldElts.push_back(getNativeClass(field.classDef));

  // ptrOffset
  FieldElts.push_back(ConstantInt::get(Type::getInt32Ty(getLLVMContext()), field.ptrOffset));

  // num
  FieldElts.push_back(ConstantInt::get(Type::getInt16Ty(getLLVMContext()), field.num));

  return ConstantStruct::get(STy, FieldElts); 
}

Constant* JavaAOTCompiler::CreateConstantFromJavaMethod(JavaMethod& method) {
  const StructType* STy = 
    dyn_cast<StructType>(JavaIntrinsics.JavaMethodType->getContainedType(0));
  Module& Mod = *getLLVMModule();
  
  std::vector<Constant*> MethodElts;
  std::vector<Constant*> TempElts;
  
  // signature
  MethodElts.push_back(Constant::getNullValue(JavaIntrinsics.ptrType));
  
  // access
  MethodElts.push_back(ConstantInt::get(Type::getInt16Ty(getLLVMContext()), method.access));
 
  // attributs
  if (method.nbAttributs) {
    const llvm::Type* AttrTy = JavaIntrinsics.AttributType->getContainedType(0);
    const ArrayType* ATy = ArrayType::get(AttrTy, method.nbAttributs);
    for (uint32 i = 0; i < method.nbAttributs; ++i) {
      TempElts.push_back(CreateConstantFromAttribut(method.attributs[i]));
    }

    Constant* attributs = ConstantArray::get(ATy, TempElts);
    TempElts.clear();
    attributs = new GlobalVariable(Mod, ATy, true,
                                   GlobalValue::InternalLinkage,
                                   attributs, "");
    attributs = ConstantExpr::getCast(Instruction::BitCast, attributs,
                                      JavaIntrinsics.AttributType);

    MethodElts.push_back(attributs);
  } else {
    MethodElts.push_back(Constant::getNullValue(JavaIntrinsics.AttributType));
  }
  
  // nbAttributs
  MethodElts.push_back(ConstantInt::get(Type::getInt16Ty(getLLVMContext()), method.nbAttributs));
  
  // classDef
  MethodElts.push_back(getNativeClass(method.classDef));
  
  // name
  MethodElts.push_back(getUTF8(method.name));

  // type
  MethodElts.push_back(getUTF8(method.type));
  
  // canBeInlined
  MethodElts.push_back(ConstantInt::get(Type::getInt8Ty(getLLVMContext()), method.canBeInlined));

  // code
  if (isAbstract(method.access)) {
    MethodElts.push_back(Constant::getNullValue(JavaIntrinsics.ptrType));
  } else {
    LLVMMethodInfo* LMI = getMethodInfo(&method);
    Function* func = LMI->getMethod();
    MethodElts.push_back(ConstantExpr::getCast(Instruction::BitCast, func,
                                               JavaIntrinsics.ptrType));
  }
  
  // codeInfo
  MethodElts.push_back(Constant::getNullValue(JavaIntrinsics.CodeLineInfoType));
  
  // codeInfoLength
  MethodElts.push_back(ConstantInt::get(Type::getInt16Ty(getLLVMContext()), 0));

  // offset
  MethodElts.push_back(ConstantInt::get(Type::getInt32Ty(getLLVMContext()), method.offset));

  return ConstantStruct::get(STy, MethodElts); 
}

Constant* JavaAOTCompiler::CreateConstantFromClassPrimitive(ClassPrimitive* cl) {
  const llvm::Type* JCPTy = 
    JavaIntrinsics.JavaClassPrimitiveType->getContainedType(0);
  const StructType* STy = dyn_cast<StructType>(JCPTy);
  
  std::vector<Constant*> ClassElts;
  
  // common class
  ClassElts.push_back(CreateConstantFromCommonClass(cl));

  // primSize
  ClassElts.push_back(ConstantInt::get(Type::getInt32Ty(getLLVMContext()), cl->logSize));

  return ConstantStruct::get(STy, ClassElts);
}

Constant* JavaAOTCompiler::CreateConstantFromClassArray(ClassArray* cl) {
  const StructType* STy = 
    dyn_cast<StructType>(JavaIntrinsics.JavaClassArrayType->getContainedType(0));
  
  std::vector<Constant*> ClassElts;
  Constant* ClGEPs[2] = { getIntrinsics()->constantZero,
                          getIntrinsics()->constantZero };
  
  // common class
  ClassElts.push_back(CreateConstantFromCommonClass(cl));

  // baseClass
  Constant* Cl = getNativeClass(cl->baseClass());
  if (Cl->getType() != JavaIntrinsics.JavaCommonClassType)
    Cl = ConstantExpr::getGetElementPtr(Cl, ClGEPs, 2);
    
  ClassElts.push_back(Cl);
  
  return ConstantStruct::get(STy, ClassElts);
}

Constant* JavaAOTCompiler::CreateConstantFromClass(Class* cl) {
  const StructType* STy = 
    dyn_cast<StructType>(JavaIntrinsics.JavaClassType->getContainedType(0));
  Module& Mod = *getLLVMModule();
  
  std::vector<Constant*> ClassElts;
  std::vector<Constant*> TempElts;

  // common class
  ClassElts.push_back(CreateConstantFromCommonClass(cl));

  // virtualSize
  ClassElts.push_back(ConstantInt::get(Type::getInt32Ty(getLLVMContext()),
                                       cl->virtualSize));
  
  // alginment
  ClassElts.push_back(ConstantInt::get(Type::getInt32Ty(getLLVMContext()),
                                       cl->alignment));

  // IsolateInfo
  const ArrayType* ATy = dyn_cast<ArrayType>(STy->getContainedType(3));
  assert(ATy && "Malformed type");
  
  const StructType* TCMTy = dyn_cast<StructType>(ATy->getContainedType(0));
  assert(TCMTy && "Malformed type");

  uint32 status = cl->needsInitialisationCheck() ? vmjc : ready;
  TempElts.push_back(ConstantInt::get(Type::getInt8Ty(getLLVMContext()),
                                      status));
  TempElts.push_back(ConstantInt::get(Type::getInt1Ty(getLLVMContext()),
                                      status == ready ? 1 : 0));
  TempElts.push_back(getStaticInstance(cl));
  Constant* CStr[1] = { ConstantStruct::get(TCMTy, TempElts) };
  TempElts.clear();
  ClassElts.push_back(ConstantArray::get(ATy, CStr, 1));

  // thinlock
  ClassElts.push_back(Constant::getNullValue(JavaIntrinsics.ptrType));

  if (cl->nbVirtualFields + cl->nbStaticFields) {
    ATy = ArrayType::get(JavaIntrinsics.JavaFieldType->getContainedType(0),
                         cl->nbVirtualFields + cl->nbStaticFields);
  }

  // virtualFields
  if (cl->nbVirtualFields) {

    for (uint32 i = 0; i < cl->nbVirtualFields; ++i) {
      TempElts.push_back(CreateConstantFromJavaField(cl->virtualFields[i]));
    }

  } 
  
  // staticFields
  if (cl->nbStaticFields) {

    for (uint32 i = 0; i < cl->nbStaticFields; ++i) {
      TempElts.push_back(CreateConstantFromJavaField(cl->staticFields[i]));
    }

  }

  Constant* fields = 0;
  if (cl->nbStaticFields + cl->nbVirtualFields) {
  
    fields = ConstantArray::get(ATy, TempElts);
    TempElts.clear();
    fields = new GlobalVariable(Mod, ATy, false,
                                GlobalValue::InternalLinkage,
                                fields, "");
    fields = ConstantExpr::getCast(Instruction::BitCast, fields,
                                   JavaIntrinsics.JavaFieldType);
  } else {
    fields = Constant::getNullValue(JavaIntrinsics.JavaFieldType);
  }

  // virtualFields
  ClassElts.push_back(fields);

  ConstantInt* nbVirtualFields = 
    ConstantInt::get(Type::getInt16Ty(getLLVMContext()), cl->nbVirtualFields);
  // nbVirtualFields
  ClassElts.push_back(nbVirtualFields);
  
  // staticFields
  // Output null, getLLVMModule() will be set in  the initializer. Otherwise, the
  // assembly emitter of LLVM will try to align the data.
  ClassElts.push_back(Constant::getNullValue(JavaIntrinsics.JavaFieldType));

  // nbStaticFields
  ClassElts.push_back(ConstantInt::get(Type::getInt16Ty(getLLVMContext()), cl->nbStaticFields));
  
  // virtualMethods
  if (cl->nbVirtualMethods + cl->nbStaticMethods) {
    ATy = ArrayType::get(JavaIntrinsics.JavaMethodType->getContainedType(0),
                         cl->nbVirtualMethods + cl->nbStaticMethods);
  }

  if (cl->nbVirtualMethods) {
    for (uint32 i = 0; i < cl->nbVirtualMethods; ++i) {
      TempElts.push_back(CreateConstantFromJavaMethod(cl->virtualMethods[i]));
    }
  }
    
  if (cl->nbStaticMethods) {
    for (uint32 i = 0; i < cl->nbStaticMethods; ++i) {
      TempElts.push_back(CreateConstantFromJavaMethod(cl->staticMethods[i]));
    }
  }

  Constant* methods = 0;
  if (cl->nbVirtualMethods + cl->nbStaticMethods) {
    methods = ConstantArray::get(ATy, TempElts);
    TempElts.clear();

    GlobalVariable* GV = NULL;
    method_iterator SI = virtualMethods.find(cl);
    if (SI != virtualMethods.end()) {
      GV = dyn_cast<GlobalVariable>(SI->second);
      GV->setInitializer(methods);
    } else {
      std::string name(UTF8Buffer(cl->name).toCompileName()->cString());
      name += "_VirtualMethods";
      GV = new GlobalVariable(Mod, ATy, false, GlobalValue::ExternalLinkage,
                              methods, name);
      virtualMethods.insert(std::make_pair(cl, GV));
    }
    methods = ConstantExpr::getCast(Instruction::BitCast, GV,
                                    JavaIntrinsics.JavaMethodType);
  } else {
    methods = Constant::getNullValue(JavaIntrinsics.JavaMethodType);
  }

  // virtualMethods
  ClassElts.push_back(methods);

  ConstantInt* nbVirtualMethods = 
    ConstantInt::get(Type::getInt16Ty(getLLVMContext()), cl->nbVirtualMethods);
  // nbVirtualMethods
  ClassElts.push_back(nbVirtualMethods);
  
  // staticMethods
  // Output null, getLLVMModule() will be set in  the initializer.
  ClassElts.push_back(Constant::getNullValue(JavaIntrinsics.JavaMethodType));

  // nbStaticMethods
  ClassElts.push_back(ConstantInt::get(Type::getInt16Ty(getLLVMContext()), cl->nbStaticMethods));

  // ownerClass
  ClassElts.push_back(Constant::getNullValue(JavaIntrinsics.ptrType));
  
  // bytes
  ClassElts.push_back(Constant::getNullValue(JavaIntrinsics.JavaArrayUInt8Type));

  // ctpInfo
  ClassElts.push_back(Constant::getNullValue(JavaIntrinsics.ptrType));

  // attributs
  if (cl->nbAttributs) {
    ATy = ArrayType::get(JavaIntrinsics.AttributType->getContainedType(0),
                         cl->nbAttributs);

    for (uint32 i = 0; i < cl->nbAttributs; ++i) {
      TempElts.push_back(CreateConstantFromAttribut(cl->attributs[i]));
    }

    Constant* attributs = ConstantArray::get(ATy, TempElts);
    TempElts.clear();
    attributs = new GlobalVariable(*getLLVMModule(), ATy, true,
                                   GlobalValue::InternalLinkage,
                                   attributs, "");
    attributs = ConstantExpr::getCast(Instruction::BitCast, attributs,
                                      JavaIntrinsics.AttributType);
    ClassElts.push_back(attributs);
  } else {
    ClassElts.push_back(Constant::getNullValue(JavaIntrinsics.AttributType));
  }
  
  // nbAttributs
  ClassElts.push_back(ConstantInt::get(Type::getInt16Ty(getLLVMContext()), cl->nbAttributs));
  
  // innerClasses
  if (cl->nbInnerClasses) {
    for (uint32 i = 0; i < cl->nbInnerClasses; ++i) {
      TempElts.push_back(getNativeClass(cl->innerClasses[i]));
    }

    const llvm::Type* TempTy = JavaIntrinsics.JavaClassType;
    ATy = ArrayType::get(TempTy, cl->nbInnerClasses);
    Constant* innerClasses = ConstantArray::get(ATy, TempElts);
    innerClasses = new GlobalVariable(*getLLVMModule(), ATy, true,
                                      GlobalValue::InternalLinkage,
                                      innerClasses, "");
    innerClasses = ConstantExpr::getCast(Instruction::BitCast, innerClasses,
                                         PointerType::getUnqual(TempTy));

    ClassElts.push_back(innerClasses);
  } else {
    const Type* Ty = PointerType::getUnqual(JavaIntrinsics.JavaClassType);
    ClassElts.push_back(Constant::getNullValue(Ty));
  }

  // nbInnerClasses
  ClassElts.push_back(ConstantInt::get(Type::getInt16Ty(getLLVMContext()), cl->nbInnerClasses));

  // outerClass
  if (cl->outerClass) {
    ClassElts.push_back(getNativeClass(cl->outerClass));
  } else {
    ClassElts.push_back(Constant::getNullValue(JavaIntrinsics.JavaClassType));
  }

  // innerAccess
  ClassElts.push_back(ConstantInt::get(Type::getInt16Ty(getLLVMContext()), cl->innerAccess));
  
  // innerOuterResolved
  ClassElts.push_back(ConstantInt::get(Type::getInt8Ty(getLLVMContext()), cl->innerOuterResolved));
  
  // isAnonymous
  ClassElts.push_back(ConstantInt::get(Type::getInt8Ty(getLLVMContext()), cl->isAnonymous));
  
  // virtualTableSize
  ClassElts.push_back(ConstantInt::get(Type::getInt32Ty(getLLVMContext()), cl->virtualTableSize));
  
  // staticSize
  ClassElts.push_back(ConstantInt::get(Type::getInt32Ty(getLLVMContext()), cl->staticSize));

  return ConstantStruct::get(STy, ClassElts);
}

template<typename T>
Constant* JavaAOTCompiler::CreateConstantFromIntArray(const T* val, const Type* Ty) {
  std::vector<const Type*> Elemts;
  const ArrayType* ATy = ArrayType::get(Ty, val->size);
  Elemts.push_back(JavaIntrinsics.JavaObjectType->getContainedType(0));
  Elemts.push_back(JavaIntrinsics.pointerSizeType);
  

  Elemts.push_back(ATy);

  const StructType* STy = StructType::get(getLLVMModule()->getContext(), Elemts);
  
  std::vector<Constant*> Cts;
  Cts.push_back(CreateConstantForBaseObject(val->getClass()));
  Cts.push_back(ConstantInt::get(JavaIntrinsics.pointerSizeType, val->size));
  
  std::vector<Constant*> Vals;
  for (sint32 i = 0; i < val->size; ++i) {
    Vals.push_back(ConstantInt::get(Ty, (uint64)val->elements[i]));
  }

  Cts.push_back(ConstantArray::get(ATy, Vals));
  
  return ConstantStruct::get(STy, Cts);
}

template<typename T>
Constant* JavaAOTCompiler::CreateConstantFromFPArray(const T* val, const Type* Ty) {
  std::vector<const Type*> Elemts;
  const ArrayType* ATy = ArrayType::get(Ty, val->size);
  Elemts.push_back(JavaIntrinsics.JavaObjectType->getContainedType(0));
  Elemts.push_back(JavaIntrinsics.pointerSizeType);
  

  Elemts.push_back(ATy);

  const StructType* STy = StructType::get(getLLVMModule()->getContext(), Elemts);
  
  std::vector<Constant*> Cts;
  Cts.push_back(CreateConstantForBaseObject(val->getClass()));
  Cts.push_back(ConstantInt::get(JavaIntrinsics.pointerSizeType, val->size));
  
  std::vector<Constant*> Vals;
  for (sint32 i = 0; i < val->size; ++i) {
    Vals.push_back(ConstantFP::get(Ty, (double)val->elements[i]));
  }

  Cts.push_back(ConstantArray::get(ATy, Vals));
  
  return ConstantStruct::get(STy, Cts);
}

Constant* JavaAOTCompiler::CreateConstantFromObjectArray(const ArrayObject* val) {
  std::vector<const Type*> Elemts;
  const llvm::Type* Ty = JavaIntrinsics.JavaObjectType;
  const ArrayType* ATy = ArrayType::get(Ty, val->size);
  Elemts.push_back(JavaIntrinsics.JavaObjectType->getContainedType(0));
  Elemts.push_back(JavaIntrinsics.pointerSizeType);
  

  Elemts.push_back(ATy);

  const StructType* STy = StructType::get(getLLVMModule()->getContext(), Elemts);
  
  std::vector<Constant*> Cts;
  Cts.push_back(CreateConstantForBaseObject(val->getClass()));
  Cts.push_back(ConstantInt::get(JavaIntrinsics.pointerSizeType, val->size));
  
  std::vector<Constant*> Vals;
  for (sint32 i = 0; i < val->size; ++i) {
    if (val->elements[i]) {
      Vals.push_back(getFinalObject(val->elements[i],
                                val->getClass()->asArrayClass()->baseClass()));
    } else {
      Vals.push_back(Constant::getNullValue(JavaIntrinsics.JavaObjectType));
    }
  }

  Cts.push_back(ConstantArray::get(ATy, Vals));
  
  return ConstantStruct::get(STy, Cts);
}

Constant* JavaAOTCompiler::CreateConstantFromUTF8(const UTF8* val) {
  std::vector<const Type*> Elemts;
  const ArrayType* ATy = ArrayType::get(Type::getInt16Ty(getLLVMContext()), val->size);
  Elemts.push_back(JavaIntrinsics.pointerSizeType);

  Elemts.push_back(ATy);

  const StructType* STy = StructType::get(getLLVMModule()->getContext(),
                                          Elemts);
  
  std::vector<Constant*> Cts;
  Cts.push_back(ConstantInt::get(JavaIntrinsics.pointerSizeType, val->size));
  
  std::vector<Constant*> Vals;
  for (sint32 i = 0; i < val->size; ++i) {
    Vals.push_back(ConstantInt::get(Type::getInt16Ty(getLLVMContext()), val->elements[i]));
  }

  Cts.push_back(ConstantArray::get(ATy, Vals));
  
  return ConstantStruct::get(STy, Cts);

}

Constant* JavaAOTCompiler::getUTF8(const UTF8* val) {
  utf8_iterator End = utf8s.end();
  utf8_iterator I = utf8s.find(val);
  if (I == End) {
    Constant* C = CreateConstantFromUTF8(val);
    Module& Mod = *getLLVMModule();
    GlobalVariable* varGV = new GlobalVariable(Mod, C->getType(), true,
                                               GlobalValue::InternalLinkage,
                                               C, "");
    
    Constant* res = ConstantExpr::getCast(Instruction::BitCast, varGV,
                                          JavaIntrinsics.UTF8Type);
    utf8s.insert(std::make_pair(val, res));

    return res;
  } else {
    return I->second;
  }
}

Constant* JavaAOTCompiler::CreateConstantFromVT(JavaVirtualTable* VT) {
  CommonClass* classDef = VT->cl;
  uint32 size = classDef->isClass() ? classDef->asClass()->virtualTableSize :
                                      JavaVirtualTable::getBaseSize();
  JavaVirtualTable* RealVT = classDef->isClass() ? 
    VT : ClassArray::SuperArray->virtualVT;

  const ArrayType* ATy = 
    dyn_cast<ArrayType>(JavaIntrinsics.VTType->getContainedType(0));
  const PointerType* PTy = dyn_cast<PointerType>(ATy->getContainedType(0));
  ATy = ArrayType::get(PTy, size);

  ConstantPointerNull* N = ConstantPointerNull::get(PTy);
  std::vector<Constant*> Elemts;
   
  // Destructor
  Function* Finalizer = 0;
  JavaMethod* meth = (JavaMethod*)(RealVT->destructor);
  if (meth) {
    LLVMMethodInfo* LMI = getMethodInfo(meth);
    Finalizer = LMI->getMethod();
  }
  
  Elemts.push_back(Finalizer ? 
      ConstantExpr::getCast(Instruction::BitCast, Finalizer, PTy) : N);
  
  // Delete
  Elemts.push_back(N);
  
  // Tracer
  Function* Tracer = 0;
  if (classDef->isArray()) {
    if (classDef->asArrayClass()->baseClass()->isPrimitive()) {
      Tracer = JavaIntrinsics.JavaArrayTracerFunction;
    } else {
      Tracer = JavaIntrinsics.ArrayObjectTracerFunction;
    }
  } else if (classDef->isClass()) {
    Tracer = JavaIntrinsics.RegularObjectTracerFunction;
  }

  Elemts.push_back(Tracer ? 
      ConstantExpr::getCast(Instruction::BitCast, Tracer, PTy) : N);
  
  for (uint32_t i = 0; i < VirtualTable::numberOfSpecializedTracers(); i++) {
    // Push null for now.
    Elemts.push_back(N);
  }

  // Class
  Elemts.push_back(ConstantExpr::getCast(Instruction::BitCast,
                                         getNativeClass(classDef), PTy));

  // depth
  Elemts.push_back(ConstantExpr::getIntToPtr(
        ConstantInt::get(Type::getInt64Ty(getLLVMContext()), VT->depth), PTy));
  
  // offset
  Elemts.push_back(ConstantExpr::getIntToPtr(
        ConstantInt::get(Type::getInt64Ty(getLLVMContext()), VT->offset), PTy));
  
  // cache
  Elemts.push_back(N);
  
  // display
  for (uint32 i = 0; i < JavaVirtualTable::getDisplayLength(); ++i) {
    if (VT->display[i]) {
      Constant* Temp = getVirtualTable(VT->display[i]);
      Temp = ConstantExpr::getBitCast(Temp, PTy);
      Elemts.push_back(Temp);
    } else {
      Elemts.push_back(Constant::getNullValue(PTy));
    }
  }
  
  // nbSecondaryTypes
  Elemts.push_back(ConstantExpr::getIntToPtr(
        ConstantInt::get(Type::getInt64Ty(getLLVMContext()), VT->nbSecondaryTypes), PTy));
  
  // secondaryTypes
  const ArrayType* DTy = ArrayType::get(JavaIntrinsics.VTType,
                                        VT->nbSecondaryTypes);
  
  std::vector<Constant*> TempElmts;
  for (uint32 i = 0; i < VT->nbSecondaryTypes; ++i) {
    assert(VT->secondaryTypes[i] && "No secondary type");
    Constant* Cl = getVirtualTable(VT->secondaryTypes[i]);
    TempElmts.push_back(Cl);
  }
  Constant* display = ConstantArray::get(DTy, TempElmts);
  TempElmts.clear();
  
  display = new GlobalVariable(*getLLVMModule(), DTy, true,
                               GlobalValue::InternalLinkage,
                               display, "");

  display = ConstantExpr::getCast(Instruction::BitCast, display, PTy);
  
  Elemts.push_back(display);
    
  // baseClassVT
  if (VT->baseClassVT) {
    Constant* Temp = getVirtualTable(VT->baseClassVT);
    Temp = ConstantExpr::getBitCast(Temp, PTy);
    Elemts.push_back(Temp);
  } else {
    Elemts.push_back(Constant::getNullValue(PTy));
  }
   
  // IMT
  if (!VT->IMT) {
    Elemts.push_back(Constant::getNullValue(PTy));
  } else {
    Class* cl = classDef->asClass();
    assert(cl && "Not a class");
    std::set<JavaMethod*> contents[InterfaceMethodTable::NumIndexes];
    classDef->asClass()->fillIMT(contents);
  

    const ArrayType* ATy = 
      dyn_cast<ArrayType>(JavaIntrinsics.VTType->getContainedType(0));
    const PointerType* PTy = dyn_cast<PointerType>(ATy->getContainedType(0));
    ATy = ArrayType::get(PTy, InterfaceMethodTable::NumIndexes);
  
    ConstantPointerNull* N = ConstantPointerNull::get(PTy);
    std::vector<Constant*> IElemts;

    for (uint32_t i = 0; i < InterfaceMethodTable::NumIndexes; ++i) {
      std::set<JavaMethod*>& atIndex = contents[i];
      uint32_t size = atIndex.size();
      if (size == 1) {
        JavaMethod* Imeth = *(atIndex.begin());
        JavaMethod* meth = cl->lookupMethodDontThrow(Imeth->name,
                                                     Imeth->type,
                                                     false, true, 0);
        assert(meth && "No method found");
        LLVMMethodInfo* LMI = getMethodInfo(meth);
        Function* func = LMI->getMethod();
        IElemts.push_back(ConstantExpr::getBitCast(func, PTy));
      } else if (size > 1) {
        std::vector<JavaMethod*> methods;
        bool SameMethod = true;
        JavaMethod* OldMethod = 0;
      
        for (std::set<JavaMethod*>::iterator it = atIndex.begin(),
             et = atIndex.end(); it != et; ++it) {
          JavaMethod* Imeth = *it;
          JavaMethod* Cmeth = cl->lookupMethodDontThrow(Imeth->name, Imeth->type,
                                                      false, true, 0);
       
          if (OldMethod && OldMethod != Cmeth) SameMethod = false;
          else OldMethod = Cmeth;
        
          methods.push_back(Cmeth);
        }

        if (SameMethod) {
          assert(methods[0] && "No method found");
          LLVMMethodInfo* LMI = getMethodInfo(methods[0]);
          Function* func = LMI->getMethod();
          IElemts.push_back(ConstantExpr::getBitCast(func, PTy));
        } else {

          uint32_t length = 2 * size;
        
          const ArrayType* ATy = 
            dyn_cast<ArrayType>(JavaIntrinsics.VTType->getContainedType(0));
          ATy = ArrayType::get(PTy, length);
          std::vector<Constant*> InternalElemts;
     

          std::set<JavaMethod*>::iterator Interf = atIndex.begin();
          for (std::vector<JavaMethod*>::iterator it = methods.begin(),
               et = methods.end(); it != et; ++it, ++Interf) {
            JavaMethod* Imeth = *Interf;
            JavaMethod* Cmeth = *it;
            assert(Cmeth && "No method found");

            LLVMMethodInfo* LMI = getMethodInfo(Cmeth);
            Function* func = LMI->getMethod();
            InternalElemts.push_back(
              ConstantExpr::getBitCast(getMethodInClass(Imeth), PTy));
            InternalElemts.push_back(ConstantExpr::getBitCast(func, PTy));
          }
          Constant* Array = ConstantArray::get(ATy, InternalElemts);
    
          GlobalVariable* GV = new GlobalVariable(*getLLVMModule(), ATy, false,
                                                  GlobalValue::InternalLinkage,
                                                  Array, "");
     
          Constant* CI =
            ConstantExpr::getPtrToInt(GV, Type::getInt32Ty(getLLVMContext()));
          CI = ConstantExpr::getAdd(CI, JavaIntrinsics.constantOne);
          CI = ConstantExpr::getIntToPtr(CI, PTy);
          IElemts.push_back(CI);
        }
      } else {
        IElemts.push_back(N);
      }
    }
 
    Constant* Array = ConstantArray::get(ATy, IElemts);
    GlobalVariable* GV = new GlobalVariable(*getLLVMModule(), ATy, false,
                                            GlobalValue::InternalLinkage,
                                            Array, "");
    Elemts.push_back(ConstantExpr::getBitCast(GV, PTy));
  }
 
  // methods
  for (uint32 i = JavaVirtualTable::getFirstJavaMethodIndex(); i < size; ++i) {
    JavaMethod* meth = ((JavaMethod**)RealVT)[i];
    LLVMMethodInfo* LMI = getMethodInfo(meth);
    Function* F = LMI->getMethod();
    if (isAbstract(meth->access)) {
      Elemts.push_back(Constant::getNullValue(PTy));
    } else {
      Elemts.push_back(ConstantExpr::getCast(Instruction::BitCast, F, PTy));
    }
  }

  Constant* Array = ConstantArray::get(ATy, Elemts);
  
  return Array;
}

namespace mvm {
  llvm::FunctionPass* createEscapeAnalysisPass(llvm::Function*);
}

namespace j3 {
  llvm::FunctionPass* createLowerConstantCallsPass();
}

JavaAOTCompiler::JavaAOTCompiler(const std::string& ModuleID) :
  JavaLLVMCompiler(ModuleID) {
 
  generateStubs = true;
  assumeCompiled = false;
  compileRT = false;

  std::vector<const llvm::Type*> llvmArgs;
  llvmArgs.push_back(JavaIntrinsics.ptrType); // class loader.
  const FunctionType* FTy = FunctionType::get(Type::getVoidTy(getLLVMContext()),
                                              llvmArgs, false);

  StaticInitializer = Function::Create(FTy, GlobalValue::InternalLinkage,
                                       "Init", getLLVMModule());
  
  llvmArgs.clear();
  FTy = FunctionType::get(Type::getVoidTy(getLLVMContext()), llvmArgs, false);
  Callback = Function::Create(FTy, GlobalValue::ExternalLinkage,
                              "staticCallback", getLLVMModule());

  llvmArgs.clear();
  llvmArgs.push_back(JavaIntrinsics.JavaMethodType);
  
  FTy = FunctionType::get(JavaIntrinsics.ptrType, llvmArgs, false);

  NativeLoader = Function::Create(FTy, GlobalValue::ExternalLinkage,
                                  "vmjcNativeLoader", getLLVMModule());
  
  llvmArgs.clear();
  FTy = FunctionType::get(Type::getVoidTy(getLLVMContext()), llvmArgs, false);
  ObjectPrinter = Function::Create(FTy, GlobalValue::ExternalLinkage,
                                   "printJavaObject", getLLVMModule());

  addJavaPasses();
}

void JavaAOTCompiler::printStats() {
  fprintf(stderr, "----------------- Info from the module -----------------\n");
  fprintf(stderr, "Number of native classes            : %llu\n", 
          (unsigned long long int) nativeClasses.size());
  fprintf(stderr, "Number of Java classes              : %llu\n",
          (unsigned long long int) javaClasses.size());
  fprintf(stderr, "Number of external array classes    : %llu\n",
          (unsigned long long int) arrayClasses.size());
  fprintf(stderr, "Number of virtual tables            : %llu\n", 
          (unsigned long long int) virtualTables.size());
  fprintf(stderr, "Number of static instances          : %llu\n", 
          (unsigned long long int) staticInstances.size());
  fprintf(stderr, "Number of constant pools            : %llu\n", 
          (unsigned long long int) constantPools.size());
  fprintf(stderr, "Number of strings                   : %llu\n", 
          (unsigned long long int) strings.size());
  fprintf(stderr, "Number of native functions          : %llu\n", 
          (unsigned long long int) nativeFunctions.size());
  fprintf(stderr, "----------------- Total size in .data ------------------\n");
  uint64 size = 0;
  Module* Mod = getLLVMModule();
  for (Module::const_global_iterator i = Mod->global_begin(),
       e = Mod->global_end(); i != e; ++i) {
    size += mvm::MvmModule::getTypeSize(i->getType());
  }
  fprintf(stderr, "%lluB\n", (unsigned long long int)size);
}


#ifdef SERVICE
Value* JavaAOTCompiler::getIsolate(Jnjvm* isolate, Value* Where) {
  llvm::Constant* varGV = 0;
  isolate_iterator End = isolates.end();
  isolate_iterator I = isolates.find(isolate);
  if (I == End) {
  
    
    Constant* cons = 
      ConstantExpr::getIntToPtr(ConstantInt::get(Type::getInt64Ty(getLLVMContext()),
                                                 uint64_t(isolate)),
                                ptrType);

    Module& Mod = *getLLVMModule();
    varGV = new GlobalVariable(Mod, ptrType, !staticCompilation,
                               GlobalValue::ExternalLinkage,
                               cons, "");
  
    isolates.insert(std::make_pair(isolate, varGV));
  } else {
    varGV = I->second;
  }
  if (BasicBlock* BB = dyn_cast<BasicBlock>(Where)) {
    return new LoadInst(varGV, "", BB);
  } else {
    assert(dyn_cast<Instruction>(Where) && "Wrong use of module");
    return new LoadInst(varGV, "", dyn_cast<Instruction>(Where));
  }
}
#endif

void JavaAOTCompiler::CreateStaticInitializer() {

  std::vector<const llvm::Type*> llvmArgs;
  llvmArgs.push_back(JavaIntrinsics.ptrType); // class loader
  llvmArgs.push_back(JavaIntrinsics.JavaCommonClassType); // cl
  const FunctionType* FTy =
    FunctionType::get(Type::getVoidTy(getLLVMContext()), llvmArgs, false);

  Function* AddClass = Function::Create(FTy, GlobalValue::ExternalLinkage,
                                        "vmjcAddPreCompiledClass",
                                        getLLVMModule());
 
  llvmArgs.clear();
  // class loader
  llvmArgs.push_back(JavaIntrinsics.ptrType);
  // array ptr
  llvmArgs.push_back(PointerType::getUnqual(JavaIntrinsics.JavaClassArrayType));
  // name
  llvmArgs.push_back(JavaIntrinsics.UTF8Type);
  FTy = FunctionType::get(Type::getVoidTy(getLLVMContext()), llvmArgs, false);
  
  Function* GetClassArray = Function::Create(FTy, GlobalValue::ExternalLinkage,
                                             "vmjcGetClassArray", getLLVMModule());
  
  BasicBlock* currentBlock = BasicBlock::Create(getLLVMContext(), "enter",
                                                StaticInitializer);
  Function::arg_iterator loader = StaticInitializer->arg_begin();
  
  Value* Args[3];
  // If we have defined some strings.
  if (strings.begin() != strings.end()) {
    llvmArgs.clear();
    llvmArgs.push_back(JavaIntrinsics.ptrType); // class loader
    llvmArgs.push_back(strings.begin()->second->getType()); // val
    FTy = FunctionType::get(Type::getVoidTy(getLLVMContext()), llvmArgs, false);
  
    Function* AddString = Function::Create(FTy, GlobalValue::ExternalLinkage,
                                           "vmjcAddString", getLLVMModule());
  

  
    for (string_iterator i = strings.begin(), e = strings.end(); i != e; ++i) {
      Args[0] = loader;
      Args[1] = i->second;
      CallInst::Create(AddString, Args, Args + 2, "", currentBlock);
    }
  }
 
#if 0
  // Disable initialization of UTF8s, it makes the Init method too big.
  // If we have defined some UTF8s.
  if (utf8s.begin() != utf8s.end()) {
    llvmArgs.clear();
    llvmArgs.push_back(JavaIntrinsics.ptrType); // class loader
    llvmArgs.push_back(utf8s.begin()->second->getType()); // val
    FTy = FunctionType::get(Type::getVoidTy(getLLVMContext()), llvmArgs, false);
  
    Function* AddUTF8 = Function::Create(FTy, GlobalValue::ExternalLinkage,
                                         "vmjcAddUTF8", getLLVMModule());
  

  
    for (utf8_iterator i = utf8s.begin(), e = utf8s.end(); i != e; ++i) {
      Args[0] = loader;
      Args[1] = i->second;
      CallInst::Create(AddUTF8, Args, Args + 2, "", currentBlock);
    }
  }
#endif

  for (native_class_iterator i = nativeClasses.begin(), 
       e = nativeClasses.end(); i != e; ++i) {
    if (isCompiling(i->first)) {
      Args[0] = loader;
      Args[1] = ConstantExpr::getBitCast(i->second,
                                         JavaIntrinsics.JavaCommonClassType);
      CallInst::Create(AddClass, Args, Args + 2, "", currentBlock);
    }
  }
  
  for (array_class_iterator i = arrayClasses.begin(), 
       e = arrayClasses.end(); i != e; ++i) {
    Args[0] = loader;
    Args[1] = i->second;
    Args[2] = getUTF8(i->first->name);
    CallInst::Create(GetClassArray, Args, Args + 3, "", currentBlock);
  }
  

  ReturnInst::Create(getLLVMContext(), currentBlock);
}

void JavaAOTCompiler::setNoInline(Class* cl) {
  for (uint32 i = 0; i < cl->nbVirtualMethods; ++i) {
    JavaMethod& meth = cl->virtualMethods[i];
    if (!isAbstract(meth.access)) {
      LLVMMethodInfo* LMI = getMethodInfo(&meth);
      Function* func = LMI->getMethod();
      func->addFnAttr(Attribute::NoInline);
    }
  }
  
  for (uint32 i = 0; i < cl->nbStaticMethods; ++i) {
    JavaMethod& meth = cl->staticMethods[i];
    if (!isAbstract(meth.access)) {
      LLVMMethodInfo* LMI = getMethodInfo(&meth);
      Function* func = LMI->getMethod();
      func->addFnAttr(Attribute::NoInline);
    }
  }
}

void JavaAOTCompiler::makeVT(Class* cl) {
  JavaVirtualTable* VT = cl->virtualVT;
  
  if (cl->super) {
    // Copy the super VT into the current VT.
    uint32 size = cl->super->virtualTableSize - 
        JavaVirtualTable::getFirstJavaMethodIndex();
    memcpy(VT->getFirstJavaMethod(), cl->super->virtualVT->getFirstJavaMethod(),
           size * sizeof(uintptr_t));
    VT->destructor = cl->super->virtualVT->destructor;
  }
  
  for (uint32 i = 0; i < cl->nbVirtualMethods; ++i) {
    JavaMethod& meth = cl->virtualMethods[i];
    ((void**)VT)[meth.offset] = &meth;
  }

  if (!cl->super) VT->destructor = 0;

}

void JavaAOTCompiler::makeIMT(Class* cl) {
}

void JavaAOTCompiler::setMethod(JavaMethod* meth, void* ptr, const char* name) {
  Function* func = getMethodInfo(meth)->getMethod();
  func->setName(name);
  func->setLinkage(GlobalValue::ExternalLinkage);
}

Value* JavaAOTCompiler::addCallback(Class* cl, uint16 index,
                                    Signdef* sign, bool stat,
                                    BasicBlock* insert) {
 
  JavaConstantPool* ctpInfo = cl->ctpInfo;
  Signdef* signature = 0;
  const UTF8* name = 0;
  const UTF8* methCl = 0;
  ctpInfo->nameOfStaticOrSpecialMethod(index, methCl, name, signature);


  fprintf(stderr, "Warning: emitting a callback from %s (%s.%s)\n",
          UTF8Buffer(cl->name).cString(), UTF8Buffer(methCl).cString(),
          UTF8Buffer(name).cString());

  LLVMSignatureInfo* LSI = getSignatureInfo(sign);
  
  const FunctionType* type = stat ? LSI->getStaticType() : 
                                    LSI->getVirtualType();
  
  Value* func = ConstantExpr::getBitCast(Callback,
                                         PointerType::getUnqual(type));
  
  return func;
}

void JavaAOTCompiler::compileClass(Class* cl) {
  
  // Make sure the class is emitted.
  getNativeClass(cl);

  for (uint32 i = 0; i < cl->nbVirtualMethods; ++i) {
    JavaMethod& meth = cl->virtualMethods[i];
    if (!isAbstract(meth.access)) parseFunction(&meth);
    if (generateStubs) compileAllStubs(meth.getSignature());
  }
  
  for (uint32 i = 0; i < cl->nbStaticMethods; ++i) {
    JavaMethod& meth = cl->staticMethods[i];
    if (!isAbstract(meth.access)) parseFunction(&meth);
    if (generateStubs) compileAllStubs(meth.getSignature());
  }
}



static void extractFiles(ArrayUInt8* bytes,
                         JavaAOTCompiler* M,
                         JnjvmBootstrapLoader* bootstrapLoader,
                         std::vector<Class*>& classes) {
      
  ZipArchive archive(bytes, bootstrapLoader->allocator);
    
  char* realName = (char*)alloca(4096);
  for (ZipArchive::table_iterator i = archive.filetable.begin(), 
       e = archive.filetable.end(); i != e; ++i) {
    ZipFile* file = i->second;
     
    char* name = file->filename;
    uint32 size = strlen(name);
    if (size > 6 && !strcmp(&(name[size - 6]), ".class")) {
      UserClassArray* array = bootstrapLoader->upcalls->ArrayOfByte;
      ArrayUInt8* res = 
        (ArrayUInt8*)array->doNew(file->ucsize, bootstrapLoader->allocator);
      int ok = archive.readFile(res, file);
      if (!ok) return;
      
      memcpy(realName, name, size);
      realName[size - 6] = 0;
      const UTF8* utf8 = bootstrapLoader->asciizConstructUTF8(realName);
      Class* cl = bootstrapLoader->constructClass(utf8, res);
      if (cl == ClassArray::SuperArray) M->compileRT = true;
      classes.push_back(cl);  
    } else if (size > 4 && (!strcmp(&name[size - 4], ".jar") || 
                            !strcmp(&name[size - 4], ".zip"))) {
      UserClassArray* array = bootstrapLoader->upcalls->ArrayOfByte;
      ArrayUInt8* res = 
        (ArrayUInt8*)array->doNew(file->ucsize, bootstrapLoader->allocator);
      int ok = archive.readFile(res, file);
      if (!ok) return;
      
      extractFiles(res, M, bootstrapLoader, classes);
    }
  }
}


static const char* name;

void mainCompilerStart(JavaThread* th) {
  
  Jnjvm* vm = th->getJVM();
  JnjvmBootstrapLoader* bootstrapLoader = vm->bootstrapLoader;
  JavaAOTCompiler* M = (JavaAOTCompiler*)bootstrapLoader->getCompiler();
  JavaJITCompiler* Comp = 0;
    if (!M->clinits->empty()) {
      Comp = JavaJITCompiler::CreateCompiler("JIT");
      Comp->EmitFunctionName = true;
      bootstrapLoader->setCompiler(Comp);
      bootstrapLoader->analyseClasspathEnv(vm->classpath);
    } else {
      bootstrapLoader->analyseClasspathEnv(vm->classpath);
      bootstrapLoader->upcalls->initialiseClasspath(bootstrapLoader);
    }
  
    uint32 size = strlen(name);
    
    if (size > 4 && 
       (!strcmp(&name[size - 4], ".jar") || !strcmp(&name[size - 4], ".zip"))) {
  
      std::vector<Class*> classes;
      ArrayUInt8* bytes = Reader::openFile(bootstrapLoader, name);
      
      if (!bytes) {
        fprintf(stderr, "Can't find zip file.\n");
        goto end;
      }

      extractFiles(bytes, M, bootstrapLoader, classes);


      // First resolve everyone so that there can not be unknown references in
      // constant pools.
      for (std::vector<Class*>::iterator i = classes.begin(),
           e = classes.end(); i != e; ++i) {
        Class* cl = *i;
        cl->resolveClass();
        cl->setOwnerClass(JavaThread::get());
        
        for (uint32 i = 0; i < cl->nbVirtualMethods; ++i) {
          LLVMMethodInfo* LMI = M->getMethodInfo(&cl->virtualMethods[i]);
          LMI->getMethod();
        }

        for (uint32 i = 0; i < cl->nbStaticMethods; ++i) {
          LLVMMethodInfo* LMI = M->getMethodInfo(&cl->staticMethods[i]);
          LMI->getMethod();
        }

      }

      if (!M->clinits->empty()) {
        vm->loadBootstrap();

        for (std::vector<std::string>::iterator i = M->clinits->begin(),
             e = M->clinits->end(); i != e; ++i) {
          
          if (i->at(i->length() - 1) == '*') {
            for (std::vector<Class*>::iterator ii = classes.begin(),
                 ee = classes.end(); ii != ee; ++ii) {
              Class* cl = *ii;
              if (!strncmp(UTF8Buffer(cl->name).cString(), i->c_str(),
                           i->length() - 1)) {
                TRY {
                  cl->asClass()->initialiseClass(vm);
                } CATCH {
                  fprintf(stderr, "Error when initializing %s\n",
                          UTF8Buffer(cl->name).cString());
                  abort();
                } END_CATCH;
              }
            }
          } else {

            const UTF8* name = bootstrapLoader->asciizConstructUTF8(i->c_str());
            CommonClass* cl = bootstrapLoader->lookupClass(name);
            if (cl && cl->isClass()) {
              TRY {
                cl->asClass()->initialiseClass(vm);
              } CATCH {
                fprintf(stderr, "Error when initializing %s\n",
                        UTF8Buffer(cl->name).cString());
                abort();
              } END_CATCH;
            } else {
              fprintf(stderr, "Class %s does not exist or is an array class.\n",
                      i->c_str());
            }
          }
        }
        bootstrapLoader->setCompiler(M);
      }
      
      for (std::vector<Class*>::iterator i = classes.begin(), e = classes.end();
           i != e; ++i) {
        Class* cl = *i;
        cl->setOwnerClass(JavaThread::get());
      }
      
      for (std::vector<Class*>::iterator i = classes.begin(), e = classes.end();
           i != e; ++i) {
        Class* cl = *i;
        M->compileClass(cl);
      }

    } else {
      char* realName = (char*)alloca(size + 1);
      if (size > 6 && !strcmp(&name[size - 6], ".class")) {
        memcpy(realName, name, size - 6);
        realName[size - 6] = 0;
      } else {
        memcpy(realName, name, size + 1);
      }
     
      const UTF8* utf8 = bootstrapLoader->asciizConstructUTF8(realName);
      UserClass* cl = bootstrapLoader->loadName(utf8, true, true);
      
      if (!M->clinits->empty()) {
        vm->loadBootstrap();
        cl->initialiseClass(vm);
        bootstrapLoader->setCompiler(M);
      }
      
      cl->setOwnerClass(JavaThread::get());
      cl->resolveInnerOuterClasses();
      for (uint32 i = 0; i < cl->nbInnerClasses; ++i) {
        cl->innerClasses[i]->setOwnerClass(JavaThread::get());
        M->compileClass(cl->innerClasses[i]);
      }
      M->compileClass(cl);
    }
 
    if (M->compileRT) {
      // Make sure that if we compile RT, the native classes are emitted.
      M->getNativeClass(bootstrapLoader->upcalls->OfVoid);
      M->getNativeClass(bootstrapLoader->upcalls->OfBool);
      M->getNativeClass(bootstrapLoader->upcalls->OfByte);
      M->getNativeClass(bootstrapLoader->upcalls->OfChar);
      M->getNativeClass(bootstrapLoader->upcalls->OfShort);
      M->getNativeClass(bootstrapLoader->upcalls->OfInt);
      M->getNativeClass(bootstrapLoader->upcalls->OfFloat);
      M->getNativeClass(bootstrapLoader->upcalls->OfLong);
      M->getNativeClass(bootstrapLoader->upcalls->OfDouble);

      // Also do not allow inling of some functions.
#define SET_INLINE(NAME) { \
      const UTF8* name = bootstrapLoader->asciizConstructUTF8(NAME); \
      Class* cl = (Class*)bootstrapLoader->lookupClass(name); \
      if (cl) M->setNoInline(cl); }

      SET_INLINE("java/util/concurrent/atomic/AtomicReferenceFieldUpdater")
      SET_INLINE("java/util/concurrent/atomic/AtomicReferenceFieldUpdater"
                 "$AtomicReferenceFieldUpdaterImpl")
      SET_INLINE("java/util/concurrent/atomic/AtomicIntegerFieldUpdater")
      SET_INLINE("java/util/concurrent/atomic/AtomicIntegerFieldUpdater"
                 "$AtomicIntegerFieldUpdaterImpl")
      SET_INLINE("java/util/concurrent/atomic/AtomicLongFieldUpdater")
      SET_INLINE("java/util/concurrent/atomic/AtomicLongFieldUpdater"
                 "$CASUpdater")
      SET_INLINE("java/util/concurrent/atomic/AtomicLongFieldUpdater"
                 "$LockedUpdater")
#undef SET_INLINE
    }

    M->CreateStaticInitializer();

end:

  vm->threadSystem.nonDaemonLock.lock();
  --(vm->threadSystem.nonDaemonThreads);
  if (vm->threadSystem.nonDaemonThreads == 0)
      vm->threadSystem.nonDaemonVar.signal();
  vm->threadSystem.nonDaemonLock.unlock();  
  
}

void JavaAOTCompiler::compileFile(Jnjvm* vm, const char* n) {
  name = n;
  JavaThread* th = new JavaThread(0, 0, vm);
  vm->setMainThread(th);
  th->start((void (*)(mvm::Thread*))mainCompilerStart);
  vm->waitForExit();
}

/// compileAllStubs - Compile all the native -> Java stubs. 
/// TODO: Once LLVM supports va_arg, enable AP.
///
void JavaAOTCompiler::compileAllStubs(Signdef* sign) {
  sign->getStaticCallBuf();
  // getStaticCallAP();
  sign->getVirtualCallBuf();
  // getVirtualCallAP();
}

void JavaAOTCompiler::generateMain(const char* name, bool jit) {

  // Type Definitions
  std::vector<const Type*> FuncArgs;
  FuncArgs.push_back(Type::getInt32Ty(getLLVMContext()));
  FuncArgs.push_back(PointerType::getUnqual(JavaIntrinsics.ptrType));
  
  FunctionType* FuncTy = FunctionType::get(Type::getInt32Ty(getLLVMContext()),
                                           FuncArgs, false);

  Function* MainFunc = Function::Create(FuncTy, GlobalValue::ExternalLinkage,
                                        "main", TheModule);
  BasicBlock* currentBlock = BasicBlock::Create(getLLVMContext(), "enter",
                                                MainFunc);
 
  GlobalVariable* GvarArrayStr = new GlobalVariable(
    *TheModule, ArrayType::get(Type::getInt8Ty(getLLVMContext()),
                               strlen(name) + 1),
    true, GlobalValue::InternalLinkage, 0, "mainClass");


  Constant* NameArray = ConstantArray::get(getLLVMContext(), name, true);
  GvarArrayStr->setInitializer(NameArray);
  Value* Indices[2] = { JavaIntrinsics.constantZero,
                        JavaIntrinsics.constantZero };
  Value* ArgName = ConstantExpr::getGetElementPtr(GvarArrayStr, Indices, 2);

  Function::arg_iterator FuncVals = MainFunc->arg_begin();
  Value* Argc = FuncVals++;
  Value* Argv = FuncVals++;
  Value* Args[3] = { Argc, Argv, ArgName };

  FuncArgs.push_back(Args[2]->getType());

  FuncTy = FunctionType::get(Type::getInt32Ty(getLLVMContext()), FuncArgs, false);

  Function* CalledFunc = 
    Function::Create(FuncTy, GlobalValue::ExternalLinkage,
                     jit ? "StartJnjvmWithJIT" : "StartJnjvmWithoutJIT",
                     TheModule);

  Value* res = CallInst::Create(CalledFunc, Args, Args + 3, "", currentBlock);
  ReturnInst::Create(getLLVMContext(), res, currentBlock);

}


// Use a FakeFunction to return from loadMethod, so that the compiler thinks
// the method is defined by J3.
extern "C" void __JavaAOTFakeFunction__() {}

void* JavaAOTCompiler::loadMethod(void* handle, const char* symbol) {
  Function* F = mvm::MvmModule::globalModule->getFunction(symbol);
  if (F) {
    return (void*)(uintptr_t)__JavaAOTFakeFunction__;
  }

  return JavaCompiler::loadMethod(handle, symbol);
}

#ifdef WITH_MMTK

#include <set>
extern std::set<gc*> __InternalSet__;

CommonClass* JavaAOTCompiler::getUniqueBaseClass(CommonClass* cl) {
  std::set<gc*>::iterator I = __InternalSet__.begin();
  std::set<gc*>::iterator E = __InternalSet__.end();
  CommonClass* currentClass = 0;

  for (; I != E; ++I) {
    JavaObject* obj = (JavaObject*)(*I);
    if (!VMClassLoader::isVMClassLoader(obj) && obj->instanceOf(cl)) {
      if (currentClass) {
        if (obj->getClass() != currentClass) {
          return 0;
        }
      } else {
        currentClass = obj->getClass();
      }
    }
  }
  return currentClass;
}

#else
CommonClass* JavaAOTCompiler::getUniqueBaseClass(CommonClass* cl) {
  return 0;
}
#endif
