//===- ClasspathVMStackWalker.cpp -----------------------------------------===//
//===------------ GNU classpath gnu/classpath/VMStackWalker ---------------===//
//
//                              JnJVM
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include <string.h>

#include "types.h"

#include "mvm/JIT.h"

#include "JavaArray.h"
#include "JavaClass.h"
#include "JavaJIT.h"
#include "JavaObject.h"
#include "JavaTypes.h"
#include "JavaThread.h"
#include "JavaUpcalls.h"
#include "Jnjvm.h"
#include "NativeUtil.h"

using namespace jnjvm;

extern "C" {

#ifdef MULTIPLE_VM
uint32 getPools(UserConstantPool** pools, uint32 size) {
  unsigned int* top;
  register unsigned int  **cur = &top;
  register unsigned int  **max = (unsigned int**)mvm::Thread::get()->baseSP;
  
  uint32 i = 0;
  for(; cur<max && i < size; cur++) {
    void* obj = (void*)(*cur);
    obj = Collector::begOf(obj);
    if (obj && ((mvm::Object*)obj)->getVirtualTable() == UserConstantPool::VT) {
      UserConstantPool* ctp = (UserConstantPool*)obj;
      pools[i++] = ctp;
    }
  }
  return i;
}
#endif

#ifdef MULTIPLE_VM
JavaObject* getClassInContext(Jnjvm* vm, Class* cl, UserConstantPool** ctps, uint32& ctpIndex) {
  for (; ctpIndex < 100; ++ctpIndex) {
    UserClass* newCl = ctps[ctpIndex]->getClass();
    if (cl == newCl->classDef) return newCl->getClassDelegatee(vm);
  }
  return 0;
}

ArrayObject* recGetClassContext(Jnjvm* vm, int** stack, uint32 size, uint32 first, uint32 rec, UserConstantPool** ctps, uint32 ctpIndex) {
  if (size != first) {
    JavaMethod* meth = JavaJIT::IPToJavaMethod(stack[first]);
    if (meth) {
      JavaObject* obj = getClassInContext(vm, meth->classDef, ctps, ctpIndex);
      ArrayObject* res = recGetClassContext(vm, stack, size, first + 1, rec + 1, ctps, ctpIndex); 
      res->elements[rec] = obj;
      assert(res->elements[rec] && "Did not found the user class");
      return res;
    } else {
      return recGetClassContext(vm, stack, size, first + 1, rec, ctps, ctpIndex);
    }   
  } else {
    return (ArrayObject*)vm->upcalls->classArrayClass->doNew(rec, vm);
  }
}
#else
ArrayObject* recGetClassContext(Jnjvm* vm, int** stack, uint32 size, uint32 first, uint32 rec) {
  if (size != first) {
    JavaMethod* meth = JavaJIT::IPToJavaMethod(stack[first]);
    if (meth) {
      ArrayObject* res = recGetClassContext(vm, stack, size, first + 1, rec + 1); 
      res->elements[rec] = meth->classDef->getClassDelegatee(vm);
      return res;
    } else {
      return recGetClassContext(vm, stack, size, first + 1, rec);
    }   
  } else {
    return (ArrayObject*)vm->upcalls->classArrayClass->doNew(rec, vm);
  }
}
#endif

JNIEXPORT jobject JNICALL Java_gnu_classpath_VMStackWalker_getClassContext(
#ifdef NATIVE_JNI
JNIEnv *env,
jclass clazz,
#endif
) {
  Jnjvm* vm = JavaThread::get()->isolate;
  int* ips[100];
  int real_size = mvm::jit::getBacktrace((void**)(void*)ips, 100);
#ifdef MULTIPLE_VM
  UserConstantPool* pools[100];
  getPools(pools, 100);
#endif

  int i = 0;
  int first = 0;
  UserCommonClass* cl = vm->upcalls->vmStackWalker; 

  while (i < real_size) {
    JavaMethod* meth = JavaJIT::IPToJavaMethod(ips[i++]);
#ifdef MULTIPLE_VM
    if (meth && meth->classDef == cl->classDef) {
#else
    if (meth && meth->classDef == cl) {
#endif
      first = i;
      break;
    }   
  }

#ifdef MULTIPLE_VM
  return (jobject)recGetClassContext(vm, ips, real_size, first, 0, pools, 0);
#else
  return (jobject)recGetClassContext(vm, ips, real_size, first, 0);
#endif
}

JNIEXPORT jobject JNICALL Java_gnu_classpath_VMStackWalker_getClassLoader(
#ifdef NATIVE_JNI
JNIEnv *env,
jclass clazz,
#endif
jclass _Cl) {
  Jnjvm* vm = JavaThread::get()->isolate;
  JavaObject* Cl = (JavaObject*)_Cl;
  UserCommonClass* cl = (UserCommonClass*)vm->upcalls->vmdataClass->getObjectField(Cl);
  return (jobject)cl->classLoader->getJavaClassLoader();
}

extern "C" JavaObject* getCallingClass() {
  UserClass* cl = JavaJIT::getCallingClass();
  if (cl) return cl->getClassDelegatee(JavaThread::get()->isolate);
  return 0;
}

extern "C" JavaObject* getCallingClassLoader() {
  return JavaJIT::getCallingClassLoader();
}

}
