//===-------------------- JavaRuntimeJIT.cpp ------------------------------===//
//=== ---- Runtime functions called by code compiled by the JIT -----------===//
//
//                            The VMKit project
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//


#include "ClasspathReflect.h"
#include "JavaArray.h"
#include "JavaClass.h"
#include "JavaConstantPool.h"
#include "JavaString.h"
#include "JavaThread.h"
#include "JavaTypes.h"
#include "Jnjvm.h"

#include "j3/OpcodeNames.def"

#include <cstdarg>

using namespace j3;

extern "C" void* j3InterfaceLookup(UserClass* caller, uint32 index) {

  void* res = 0;

  BEGIN_NATIVE_EXCEPTION(1)
  
  UserConstantPool* ctpInfo = caller->getConstantPool();
  if (ctpInfo->ctpRes[index]) {
    res = ctpInfo->ctpRes[index];
  } else {
    UserCommonClass* cl = 0;
    const UTF8* utf8 = 0;
    Signdef* sign = 0;
  
    ctpInfo->resolveMethod(index, cl, utf8, sign);
    assert(cl->isClass() && isInterface(cl->access) && "Wrong type of method");
    res = cl->asClass()->lookupInterfaceMethodDontThrow(utf8, sign->keyName);
    
    assert(res && "Can not found method");
    ctpInfo->ctpRes[index] = (void*)res;
  }
  
    
  END_NATIVE_EXCEPTION

  // Since the function is marked readnone, LLVM may move it after the
  // exception check. Therefore, we trick LLVM to check the return value of the
  // function.
  JavaObject* obj = JavaThread::get()->pendingException;
  if (obj) return (JavaMethod*)obj;
  return res;
}

// Throws if the field is not found.
extern "C" void* j3VirtualFieldLookup(UserClass* caller, uint32 index) {
  
  void* res = 0;
  
  BEGIN_NATIVE_EXCEPTION(1)

  UserConstantPool* ctpInfo = caller->getConstantPool();
  if (ctpInfo->ctpRes[index]) {
    res = ctpInfo->ctpRes[index];
  } else {
  
    UserCommonClass* cl = 0;
    const UTF8* utf8 = 0;
    Typedef* sign = 0;
  
    ctpInfo->resolveField(index, cl, utf8, sign);
 
    UserClass* lookup = cl->isArray() ? cl->super : cl->asClass();
    JavaField* field = lookup->lookupField(utf8, sign->keyName, false, true, 0);
  
    ctpInfo->ctpRes[index] = (void*)field->ptrOffset;
  
    res = (void*)field->ptrOffset;
  }

  END_NATIVE_EXCEPTION

  // Since the function is marked readnone, LLVM may move it after the
  // exception check. Therefore, we trick LLVM to check the return value of the
  // function.
  JavaObject* obj = JavaThread::get()->pendingException;
  if (obj) return (void*)obj;
  return res;
}

// Throws if the field or its class is not found.
extern "C" void* j3StaticFieldLookup(UserClass* caller, uint32 index) {
  
  void* res = 0;
  
  BEGIN_NATIVE_EXCEPTION(1)
  
  UserConstantPool* ctpInfo = caller->getConstantPool();
  
  if (ctpInfo->ctpRes[index]) {
    res = ctpInfo->ctpRes[index];
  } else {
  
    UserCommonClass* cl = 0;
    UserClass* fieldCl = 0;
    const UTF8* utf8 = 0;
    Typedef* sign = 0;
  
    ctpInfo->resolveField(index, cl, utf8, sign);
 
    assert(cl->asClass() && "Lookup a field of something not an array");
    JavaField* field = cl->asClass()->lookupField(utf8, sign->keyName, true,
                                                  true, &fieldCl);
    
    fieldCl->initialiseClass(JavaThread::get()->getJVM());
    void* obj = ((UserClass*)fieldCl)->getStaticInstance();
  
    assert(obj && "No static instance in static field lookup");
  
    void* ptr = (void*)((uint64)obj + field->ptrOffset);
    ctpInfo->ctpRes[index] = ptr;
   
    res = ptr;
  }

  END_NATIVE_EXCEPTION

  // Since the function is marked readnone, LLVM may move it after the
  // exception check. Therefore, we trick LLVM to check the return value of the
  // function.
  JavaObject* obj = JavaThread::get()->pendingException;
  if (obj) return (void*)obj;
  return res;
}

#ifndef WITHOUT_VTABLE
// Throws if the method is not found.
extern "C" uint32 j3VirtualTableLookup(UserClass* caller, uint32 index,
                                       uint32* offset, JavaObject* obj) {
  llvm_gcroot(obj, 0);
  uint32 res = 0;
  
  BEGIN_NATIVE_EXCEPTION(1)
    
  UserCommonClass* cl = 0;
  const UTF8* utf8 = 0;
  Signdef* sign = 0;
  
  caller->getConstantPool()->resolveMethod(index, cl, utf8, sign);
  UserClass* lookup = cl->isArray() ? cl->super : cl->asClass();
  JavaMethod* dmeth = lookup->lookupMethodDontThrow(utf8, sign->keyName, false,
                                                    true, 0);
  if (!dmeth) {
    assert((obj->getClass()->isClass() && 
            obj->getClass()->asClass()->isInitializing()) &&
           "Class not ready in a virtual lookup.");
    // Arg, the bytecode is buggy! Perform the lookup on the object class
    // and do not update offset.
    lookup = obj->getClass()->isArray() ? obj->getClass()->super : 
                                       obj->getClass()->asClass();
    dmeth = lookup->lookupMethod(utf8, sign->keyName, false, true, 0);
  } else {
    *offset = dmeth->offset;
  }

#if !defined(ISOLATE_SHARING) && !defined(SERVICE)
  assert(dmeth->classDef->isInitializing() && 
         "Class not ready in a virtual lookup.");
#endif

  res = dmeth->offset;

  END_NATIVE_EXCEPTION

  return res;
}
#endif

// Throws if the class is not found.
extern "C" void* j3ClassLookup(UserClass* caller, uint32 index) { 
  
  void* res = 0;
  
  BEGIN_NATIVE_EXCEPTION(1)
   
  UserConstantPool* ctpInfo = caller->getConstantPool();
  UserClass* cl = (UserClass*)ctpInfo->loadClass(index);
  // We can not initialize here, because bytecodes such as CHECKCAST
  // or classes used in catch clauses do not trigger class initialization.
  // This is really sad, because we need to insert class initialization checks
  // in the LLVM code.
  assert(cl && "No cl after class lookup");
  res = (void*)cl;

  END_NATIVE_EXCEPTION
  
  // Since the function is marked readnone, LLVM may move it after the
  // exception check. Therefore, we trick LLVM to check the return value of the
  // function.
  JavaObject* obj = JavaThread::get()->pendingException;
  if (obj) return (void*)obj;
  return res;
}

// Calls Java code.
// Throws if initializing the class throws an exception.
extern "C" UserCommonClass* j3RuntimeInitialiseClass(UserClass* cl) {
  BEGIN_NATIVE_EXCEPTION(1)
 
  cl->resolveClass();
  cl->initialiseClass(JavaThread::get()->getJVM());
  
  END_NATIVE_EXCEPTION

  // Since the function is marked readnone, LLVM may move it after the
  // exception check. Therefore, we trick LLVM to check the return value of the
  // function.
  JavaObject* obj = JavaThread::get()->pendingException;
  if (obj) return (UserCommonClass*)obj;
  return cl;
}

// Calls Java code.
extern "C" JavaObject* j3RuntimeDelegatee(UserCommonClass* cl) {
  JavaObject* res = 0;
  llvm_gcroot(res, 0);

  BEGIN_NATIVE_EXCEPTION(1)
  Jnjvm* vm = JavaThread::get()->getJVM();
  res = cl->getClassDelegatee(vm);
  END_NATIVE_EXCEPTION
  
  // Since the function is marked readnone, LLVM may move it after the
  // exception check. Therefore, we trick LLVM to check the return value of the
  // function.
  JavaObject* obj = JavaThread::get()->pendingException;
  if (obj) return obj;
  return res;
}

// Throws if one of the dimension is negative.
static JavaArray* multiCallNewIntern(UserClassArray* cl, uint32 len,
                                     sint32* dims, Jnjvm* vm) {
  assert(len > 0 && "Negative size given by VMKit");
 
  JavaArray* _res = cl->doNew(dims[0], vm);
  ArrayObject* res = 0;
  llvm_gcroot(_res, 0);
  llvm_gcroot(res, 0);

  if (len > 1) {
    res = (ArrayObject*)_res;
    UserCommonClass* _base = cl->baseClass();
    assert(_base->isArray() && "Base class not an array");
    UserClassArray* base = (UserClassArray*)_base;
    if (dims[0] > 0) {
      for (sint32 i = 0; i < dims[0]; ++i) {
        res->elements[i] = multiCallNewIntern(base, (len - 1),
                                              &dims[1], vm);
      }
    } else {
      for (uint32 i = 1; i < len; ++i) {
        sint32 p = dims[i];
        if (p < 0) JavaThread::get()->getJVM()->negativeArraySizeException(p);
      }
    }
  }
  return _res;
}

// Throws if one of the dimension is negative.
extern "C" JavaArray* j3MultiCallNew(UserClassArray* cl, uint32 len, ...) {
  JavaArray* res = 0;
  llvm_gcroot(res, 0);

  BEGIN_NATIVE_EXCEPTION(1)

  va_list ap;
  va_start(ap, len);
  sint32* dims = (sint32*)alloca(sizeof(sint32) * len);
  for (uint32 i = 0; i < len; ++i){
    dims[i] = va_arg(ap, int);
  }
  Jnjvm* vm = JavaThread::get()->getJVM();
  res = multiCallNewIntern(cl, len, dims, vm);

  END_NATIVE_EXCEPTION

  return res;
}

// Throws if the class can not be resolved.
extern "C" UserClassArray* j3GetArrayClass(UserCommonClass* cl,
                                              UserClassArray** dcl) {
  UserClassArray* res = 0;

  BEGIN_NATIVE_EXCEPTION(1)
  
  JnjvmClassLoader* JCL = cl->classLoader;
  if (cl->asClass()) cl->asClass()->resolveClass();
  const UTF8* arrayName = JCL->constructArrayName(1, cl->getName());
  
  res = JCL->constructArray(arrayName);
  if (dcl) *dcl = res;

  END_NATIVE_EXCEPTION

  // Since the function is marked readnone, LLVM may move it after the
  // exception check. Therefore, we trick LLVM to check the return value of the
  // function.
  JavaObject* obj = JavaThread::get()->pendingException;
  if (obj) return (UserClassArray*)obj;
  return res;
}

// Does not call Java code. Can not yield a GC.
extern "C" void j3EndJNI(uint32** oldLRN) {
  JavaThread* th = JavaThread::get();
  
  // We're going back to Java
  th->endJNI();
  
  // Update the number of references.
  th->currentAddedReferences = *oldLRN;


}

extern "C" void* j3StartJNI(uint32* localReferencesNumber,
                            uint32** oldLocalReferencesNumber,
                            mvm::KnownFrame* Frame) 
  __attribute__((noinline));

// Never throws. Does not call Java code. Can not yied a GC.
extern "C" void* j3StartJNI(uint32* localReferencesNumber,
                            uint32** oldLocalReferencesNumber,
                            mvm::KnownFrame* Frame) {
  
  JavaThread* th = JavaThread::get();
 
  *oldLocalReferencesNumber = th->currentAddedReferences;
  th->currentAddedReferences = localReferencesNumber;
  th->startKnownFrame(*Frame);

  th->startJNI(1);

  return Frame->currentFP;
}

// Never throws.
extern "C" void j3JavaObjectAquire(JavaObject* obj) {
  BEGIN_NATIVE_EXCEPTION(1)
  
  llvm_gcroot(obj, 0);
  obj->acquire();

  END_NATIVE_EXCEPTION
}

// Never throws.
extern "C" void j3JavaObjectRelease(JavaObject* obj) {
  BEGIN_NATIVE_EXCEPTION(1)
  
  llvm_gcroot(obj, 0);
  obj->release();
  
  END_NATIVE_EXCEPTION
}

// Does not call any Java code. Can not yield a GC.
extern "C" void j3ThrowException(JavaObject* obj) {
  return JavaThread::get()->throwException(obj);
}

// Never throws.
extern "C" void j3OverflowThinLock(JavaObject* obj) {
  obj->overflowThinLock();
}

// Creates a Java object and then throws it.
extern "C" JavaObject* j3NullPointerException() {
  JavaObject *exc = 0;
  JavaThread *th = JavaThread::get();

  BEGIN_NATIVE_EXCEPTION(1)
  
  exc = th->getJVM()->CreateNullPointerException();

  END_NATIVE_EXCEPTION

#ifdef DWARF_EXCEPTIONS
  th->throwException(exc);
#else
  th->pendingException = exc;
#endif

  return exc;
}

// Creates a Java object and then throws it.
extern "C" JavaObject* j3NegativeArraySizeException(sint32 val) {
  JavaObject *exc = 0;
  JavaThread *th = JavaThread::get();

  BEGIN_NATIVE_EXCEPTION(1)
  
  exc = th->getJVM()->CreateNegativeArraySizeException();

  END_NATIVE_EXCEPTION

#ifdef DWARF_EXCEPTIONS
  th->throwException(exc);
#else
  th->pendingException = exc;
#endif

  return exc;
}

// Creates a Java object and then throws it.
extern "C" JavaObject* j3OutOfMemoryError(sint32 val) {
  JavaObject *exc = 0;
  JavaThread *th = JavaThread::get();

  BEGIN_NATIVE_EXCEPTION(1)
  
  exc = th->getJVM()->CreateOutOfMemoryError();

  END_NATIVE_EXCEPTION

#ifdef DWARF_EXCEPTIONS
  th->throwException(exc);
#else
  th->pendingException = exc;
#endif

  return exc;
}

// Creates a Java object and then throws it.
extern "C" JavaObject* j3StackOverflowError() {
  JavaObject *exc = 0;
  JavaThread *th = JavaThread::get();

  BEGIN_NATIVE_EXCEPTION(1)
  
  exc = th->getJVM()->CreateStackOverflowError();

  END_NATIVE_EXCEPTION

#ifdef DWARF_EXCEPTIONS
  th->throwException(exc);
#else
  th->pendingException = exc;
#endif

  return exc;
}

// Creates a Java object and then throws it.
extern "C" JavaObject* j3ArithmeticException() {
  JavaObject *exc = 0;
  JavaThread *th = JavaThread::get();

  BEGIN_NATIVE_EXCEPTION(1)
  
  exc = th->getJVM()->CreateArithmeticException();

  END_NATIVE_EXCEPTION

#ifdef DWARF_EXCEPTIONS
  th->throwException(exc);
#else
  th->pendingException = exc;
#endif

  return exc;
}

// Creates a Java object and then throws it.
extern "C" JavaObject* j3ClassCastException(JavaObject* obj,
                                               UserCommonClass* cl) {
  JavaObject *exc = 0;
  llvm_gcroot(obj, 0);
  llvm_gcroot(exc, 0);
  
  JavaThread *th = JavaThread::get();

  BEGIN_NATIVE_EXCEPTION(1)
  
  exc = th->getJVM()->CreateClassCastException(obj, cl);

  END_NATIVE_EXCEPTION

#ifdef DWARF_EXCEPTIONS
  th->throwException(exc);
#else
  th->pendingException = exc;
#endif

  return exc;
}

// Creates a Java object and then throws it.
extern "C" JavaObject* j3IndexOutOfBoundsException(JavaObject* obj,
                                                      sint32 index) {
  JavaObject *exc = 0;
  llvm_gcroot(obj, 0);
  llvm_gcroot(exc, 0);
  
  JavaThread *th = JavaThread::get();

  BEGIN_NATIVE_EXCEPTION(1)
  
  exc = th->getJVM()->CreateIndexOutOfBoundsException(index);

  END_NATIVE_EXCEPTION

#ifdef DWARF_EXCEPTIONS
  th->throwException(exc);
#else
  th->pendingException = exc;
#endif
  
  return exc;
}

// Creates a Java object and then throws it.
extern "C" JavaObject* j3ArrayStoreException(JavaVirtualTable* VT) {
  JavaObject *exc = 0;
  JavaThread *th = JavaThread::get();

  BEGIN_NATIVE_EXCEPTION(1)
  
  exc = th->getJVM()->CreateArrayStoreException(VT);

  END_NATIVE_EXCEPTION

#ifdef DWARF_EXCEPTIONS
  th->throwException(exc);
#else
  th->pendingException = exc;
#endif
  
  return exc;
}

// Create an exception then throws it.
extern "C" void j3ThrowExceptionFromJIT() {
  JavaObject *exc = 0;
  JavaThread *th = JavaThread::get();
  
  BEGIN_NATIVE_EXCEPTION(1)

  JavaMethod* meth = th->getCallingMethodLevel(0);
  exc = th->getJVM()->CreateUnsatisfiedLinkError(meth);

  END_NATIVE_EXCEPTION

#ifdef DWARF_EXCEPTIONS
  th->throwException(exc);
#else
  th->pendingException = exc;
#endif
  
}

extern "C" void* j3StringLookup(UserClass* cl, uint32 index) {
  
  JavaString** str = 0;
  
  BEGIN_NATIVE_EXCEPTION(1)
  
  UserConstantPool* ctpInfo = cl->getConstantPool();
  const UTF8* utf8 = ctpInfo->UTF8At(ctpInfo->ctpDef[index]);
  str = cl->classLoader->UTF8ToStr(utf8);
#if defined(ISOLATE_SHARING) || !defined(ISOLATE)
  ctpInfo->ctpRes[index] = str;
#endif
  
  END_NATIVE_EXCEPTION

  return (void*)str;
}

extern "C" void* j3ResolveVirtualStub(JavaObject* obj) {
  llvm_gcroot(obj, 0);
  JavaThread *th = JavaThread::get();
  UserCommonClass* cl = obj->getClass();
  void* result = NULL;
  
  BEGIN_NATIVE_EXCEPTION(1)

  // Lookup the caller of this class.
  mvm::StackWalker Walker(th);
  while (Walker.get()->MethodType != 1) ++Walker;
  mvm::MethodInfo* MI = Walker.get();
  JavaMethod* meth = (JavaMethod*)MI->getMetaInfo();
  void* ip = *Walker;

  // Lookup the method info in the constant pool of the caller.
  uint16 ctpIndex = meth->lookupCtpIndex(reinterpret_cast<uintptr_t>(ip));
  assert(ctpIndex && "No constant pool index");
  JavaConstantPool* ctpInfo = meth->classDef->getConstantPool();
  CommonClass* ctpCl = 0;
  const UTF8* utf8 = 0;
  Signdef* sign = 0;

  ctpInfo->resolveMethod(ctpIndex, ctpCl, utf8, sign);
  assert(cl->isAssignableFrom(ctpCl) && "Wrong call object");
  UserClass* lookup = cl->isArray() ? cl->super : cl->asClass();
  JavaMethod* Virt = lookup->lookupMethod(utf8, sign->keyName, false, true, 0);

  // Compile the found method.
  result = Virt->compiledPtr();

  // Update the virtual table.
  assert(lookup->isResolved() && "Class not resolved");
#if !defined(ISOLATE_SHARING) && !defined(SERVICE)
  assert(lookup->isInitializing() && "Class not ready");
#endif
  assert(lookup->virtualVT && "Class has no VT");
  assert(lookup->virtualTableSize > Virt->offset && 
         "The method's offset is greater than the virtual table size");
  ((void**)obj->getVirtualTable())[Virt->offset] = result;
  
  if (ctpCl->isInterface()) {
    InterfaceMethodTable* IMT = cl->virtualVT->IMT;
    uint32_t index = InterfaceMethodTable::getIndex(Virt->name, Virt->type);
    if ((IMT->contents[index] & 1) == 0) {
      IMT->contents[index] = (uintptr_t)result;
    } else {
      
      JavaMethod* Imeth = 
        ctpCl->asClass()->lookupInterfaceMethodDontThrow(utf8, sign->keyName);
      assert(Imeth && "Method not in hierarchy?");
      uintptr_t* table = (uintptr_t*)(IMT->contents[index] & ~1);
      uint32 i = 0;
      while (table[i] != (uintptr_t)Imeth) { i += 2; }
      table[i + 1] = (uintptr_t)result;
    }
  }

  END_NATIVE_EXCEPTION

  return result;
}

extern "C" void* j3ResolveStaticStub() {
  JavaThread *th = JavaThread::get();
  void* result = NULL;
  
  BEGIN_NATIVE_EXCEPTION(1)

  // Lookup the caller of this class.
  mvm::StackWalker Walker(th);
  while (Walker.get()->MethodType != 1) ++Walker;
  mvm::MethodInfo* MI = Walker.get();
  assert(MI->MethodType == 1 && "Wrong call to stub");
  JavaMethod* caller = (JavaMethod*)MI->getMetaInfo();
  void* ip = *Walker;

  // Lookup the method info in the constant pool of the caller.
  uint16 ctpIndex = caller->lookupCtpIndex(reinterpret_cast<uintptr_t>(ip));
  assert(ctpIndex && "No constant pool index");
  JavaConstantPool* ctpInfo = caller->classDef->getConstantPool();
  CommonClass* cl = 0;
  const UTF8* utf8 = 0;
  Signdef* sign = 0;

  ctpInfo->resolveMethod(ctpIndex, cl, utf8, sign);
  UserClass* lookup = cl->isArray() ? cl->super : cl->asClass();
  assert(lookup->isInitializing() && "Class not ready");
  JavaMethod* callee = lookup->lookupMethod(utf8, sign->keyName, true, true, 0);

  // Compile the found method.
  result = callee->compiledPtr();
    
  // Update the entry in the constant pool.
  ctpInfo->ctpRes[ctpIndex] = result;

  END_NATIVE_EXCEPTION

  return result;
}

extern "C" void* j3ResolveSpecialStub() {
  JavaThread *th = JavaThread::get();
  void* result = NULL;
  
  BEGIN_NATIVE_EXCEPTION(1)

  // Lookup the caller of this class.
  mvm::StackWalker Walker(th);
  while (Walker.get()->MethodType != 1) ++Walker;
  mvm::MethodInfo* MI = Walker.get();
  assert(MI->MethodType == 1 && "Wrong call to stub");
  JavaMethod* caller = (JavaMethod*)MI->getMetaInfo();
  void* ip = *Walker;

  // Lookup the method info in the constant pool of the caller.
  uint16 ctpIndex = caller->lookupCtpIndex(reinterpret_cast<uintptr_t>(ip));
  assert(ctpIndex && "No constant pool index");
  JavaConstantPool* ctpInfo = caller->classDef->getConstantPool();
  CommonClass* cl = 0;
  const UTF8* utf8 = 0;
  Signdef* sign = 0;

  ctpInfo->resolveMethod(ctpIndex, cl, utf8, sign);
  UserClass* lookup = cl->isArray() ? cl->super : cl->asClass();
  assert(lookup->isInitializing() && "Class not ready");
  JavaMethod* callee =
    lookup->lookupSpecialMethodDontThrow(utf8, sign->keyName, caller->classDef);
  
  if (!callee) {
    th->getJVM()->abstractMethodError(lookup, utf8);
  }

  // Compile the found method.
  result = callee->compiledPtr();
    
  // Update the entry in the constant pool.
  ctpInfo->ctpRes[ctpIndex] = result;

  END_NATIVE_EXCEPTION

  return result;
}

extern "C" void j3PrintMethodStart(JavaMethod* meth) {
  fprintf(stderr, "[%p] executing %s.%s\n", (void*)mvm::Thread::get(),
          UTF8Buffer(meth->classDef->name).cString(),
          UTF8Buffer(meth->name).cString());
}

extern "C" void j3PrintMethodEnd(JavaMethod* meth) {
  fprintf(stderr, "[%p] return from %s.%s\n", (void*)mvm::Thread::get(),
          UTF8Buffer(meth->classDef->name).cString(),
          UTF8Buffer(meth->name).cString());
}

extern "C" void j3PrintExecution(uint32 opcode, uint32 index,
                                    JavaMethod* meth) {
  fprintf(stderr, "[%p] executing %s.%s %s at %d\n", (void*)mvm::Thread::get(),
         UTF8Buffer(meth->classDef->name).cString(),
         UTF8Buffer(meth->name).cString(),
         OpcodeNames[opcode], index);
}

#ifdef SERVICE

extern "C" void j3ServiceCallStart(Jnjvm* OldService,
                                 Jnjvm* NewService) {
  fprintf(stderr, "I have switched from %d to %d\n", OldService->IsolateID,
          NewService->IsolateID);

  fprintf(stderr, "Now the thread id is %d\n", mvm::Thread::get()->IsolateID);
}

extern "C" void j3ServiceCallStop(Jnjvm* OldService,
                                Jnjvm* NewService) {
  fprintf(stderr, "End service call\n");
}

#endif


#ifdef ISOLATE_SHARING
extern "C" void* j3StaticCtpLookup(UserClass* cl, uint32 index) {
  UserConstantPool* ctpInfo = cl->getConstantPool();
  JavaConstantPool* shared = ctpInfo->getSharedPool();
  uint32 clIndex = shared->getClassIndexFromMethod(index);
  UserClass* refCl = (UserClass*)ctpInfo->loadClass(clIndex);
  refCl->initialiseClass(JavaThread::get()->getJVM());

  CommonClass* baseCl = 0;
  const UTF8* utf8 = 0;
  Signdef* sign = 0;

  shared->resolveMethod(index, baseCl, utf8, sign);
  UserClass* methodCl = 0;
  refCl->lookupMethod(utf8, sign->keyName, true, true, &methodCl);
  ctpInfo->ctpRes[index] = methodCl->getConstantPool();
  shared->ctpRes[clIndex] = refCl->classDef;
  return (void*)methodCl->getConstantPool();
}

extern "C" UserConstantPool* j3SpecialCtpLookup(UserConstantPool* ctpInfo,
                                                   uint32 index,
                                                   UserConstantPool** res) {
  JavaConstantPool* shared = ctpInfo->getSharedPool();
  uint32 clIndex = shared->getClassIndexFromMethod(index);
  UserClass* refCl = (UserClass*)ctpInfo->loadClass(clIndex);

  CommonClass* baseCl = 0;
  const UTF8* utf8 = 0;
  Signdef* sign = 0;

  shared->resolveMethod(index, baseCl, utf8, sign);
  UserClass* methodCl = 0;
  refCl->lookupMethod(utf8, sign->keyName, false, true, &methodCl);
  shared->ctpRes[clIndex] = refCl->classDef;
  *res = methodCl->getConstantPool();
  return methodCl->getConstantPool();
}

#endif
