//===--- CLIRuntimeJIT.cpp - Runtime functions for the JIT compiled code --===//
//
//                              The vmkit project
//
// This file is distributed under the University Of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//


#include <cstdio>

#include "llvm/DerivedTypes.h"
#include "llvm/Instructions.h"
#include "llvm/ExecutionEngine/ExecutionEngine.h"

#include "mvm/JIT.h"
#include "mvm/Object.h"
#include "mvm/PrintBuffer.h"
#include "mvm/Threads/Locks.h"

#include "CLIString.h"
#include "MSCorlib.h"
#include "N3.h"
#include "VMArray.h"
#include "VMCache.h"
#include "VMClass.h"
#include "VMObject.h"
#include "VMThread.h"
#include "Assembly.h"

#include "mvm/GC/GC.h"

#include <cstdarg>

using namespace n3;
using namespace llvm;

extern "C" VMObject* initialiseClass(VMClass* cl) {
  cl->clinitClass(NULL);
  return cl->staticInstance;
}

extern "C" void n3ClassCastException() {
  fflush(stdout);
  assert(0 && "implement class cast exception");
}

extern "C" void n3NullPointerException() {
  fflush(stdout);
  assert(0 && "implement null pointer exception");
}

extern "C" void indexOutOfBounds() {
  fflush(stdout);
  assert(0 && "implement index out of bounds exception");
}

extern "C" VMObject* newString(const ArrayChar* utf8) {
	N3 *vm = (N3*)VMThread::get()->getVM();
  declare_gcroot(VMObject*, res) = vm->arrayToString(utf8);
	return res;
}

extern "C" bool n3InstanceOf(VMObject* obj, VMCommonClass* cl) {
  return VMObject::instanceOf(obj, cl);
}

extern "C" void* GetCppException() {
  return VMThread::getCppException();
}

extern "C" void ThrowException(VMObject* obj) {
  return VMThread::throwException(obj);
}

extern "C" VMObject* GetCLIException() {
	declare_gcroot(VMObject*, res) = VMThread::getCLIException();
  return res;
}

extern "C" bool CompareException(VMClass* cl) {
  return VMThread::compareException(cl);
}

extern "C" void ClearException() {
  return VMThread::get()->clearException();
}

static VMObject* doMultiNewIntern(VMClassArray* cl, uint32 dim, sint32* buf) {
  if (dim <= 0) VMThread::get()->getVM()->error("Can't happen");
  sint32 n = buf[0];
  if (n < 0) VMThread::get()->getVM()->negativeArraySizeException(n);
  
  declare_gcroot(VMArray*, res) = (VMArray*)cl->doNew(n);
  if (dim > 1) {
    VMCommonClass* base = cl->baseClass;
    if (n > 0) {
      for (sint32 i = 0; i < n; ++i) {
        res->elements[i] = doMultiNewIntern((VMClassArray*)base, dim - 1, &(buf[1]));
      }   
    }   
    for (uint32 i = 1; i < dim; ++i) {
      if (buf[i] < 0) VMThread::get()->getVM()->negativeArraySizeException(buf[i]);
    }   
  }
  return res;
}

extern "C" VMObject* doMultiNew(VMClassArray* cl, ...) {
  sint32* dimSizes = (sint32*)alloca(cl->dims * sizeof(sint32));
  va_list ap; 
  va_start(ap, cl);
  for (uint32 i = 0; i < cl->dims; ++i) {
    dimSizes[i] = va_arg(ap, sint32);
  }
  va_end(ap);
  return doMultiNewIntern(cl, cl->dims, dimSizes);
}

extern "C" CacheNode* n3VirtualLookup(CacheNode* cache, VMObject *obj) {
  Enveloppe* enveloppe = cache->enveloppe;
  VMCommonClass* ocl = obj->classOf;
  VMMethod* orig = enveloppe->originalMethod;

  CacheNode* rcache = 0;
  CacheNode* tmp = enveloppe->firstCache;
  CacheNode* last = tmp;
  enveloppe->cacheLock->lock();

  while (tmp) {
    if (ocl == tmp->lastCible) {
      rcache = tmp;
      break;
    } else {
      last = tmp;
      tmp = tmp->next;
    }
  }

  if (!rcache) {
    VMMethod* dmeth = ocl->lookupMethodDontThrow(orig->name,
                                                 orig->parameters,
                                                 false, true);
    if (dmeth == 0) {
			mvm::PrintBuffer _methAsciiz(orig->name);
      mvm::PrintBuffer _nameAsciiz(orig->classDef->name);
      mvm::PrintBuffer _nameSpaceAsciiz(orig->classDef->nameSpace);
      const char* methAsciiz = _methAsciiz.cString();
      const char* nameAsciiz = _nameAsciiz.cString();
      const char* nameSpaceAsciiz = _nameSpaceAsciiz.cString();

      char *buf = (char*)alloca(3 + strlen(methAsciiz) + 
                                    strlen(nameAsciiz) + 
                                    strlen(nameSpaceAsciiz));
      sprintf(buf, "%s.%s.%s", nameSpaceAsciiz, nameAsciiz, methAsciiz);
      const UTF8* newName = VMThread::get()->getVM()->asciizToUTF8(buf);
      dmeth = ocl->lookupMethod(newName, orig->parameters, false, true);
    }
    
    if (cache->methPtr) {
      rcache = CacheNode::allocate(orig->classDef->assembly->allocator);
      rcache->enveloppe = enveloppe;
    } else {
      rcache = cache;
    }
    
    Function* func = dmeth->compiledPtr(NULL);
    rcache->methPtr = mvm::MvmModule::executionEngine->getPointerToGlobal(func);
    rcache->lastCible = (VMClass*)ocl;
    rcache->box = (dmeth->classDef->super == MSCorlib::pValue);
  }

  if (enveloppe->firstCache != rcache) {
    CacheNode *f = enveloppe->firstCache;
    enveloppe->firstCache = rcache;
    last->next = rcache->next;
    rcache->next = f;

  }
  
  enveloppe->cacheLock->unlock();
  
  return rcache;
}

extern "C" VMObject* newObject(VMClass* cl) {
	declare_gcroot(VMObject*, res) = cl->doNew();
  return res;
}

extern "C" VMObject* newArray(VMClassArray* cl, sint32 nb) {
	declare_gcroot(VMObject*, res) = cl->doNew(nb);
  return res;
}
