//===- ClasspathConstructor.cpp -------------------------------------------===//
//===----------- GNU classpath java/lang/reflect/Constructor --------------===//
//
//                            The VMKit project
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "types.h"

#include "Classpath.h"
#include "ClasspathReflect.h"
#include "JavaArray.h"
#include "JavaClass.h"
#include "JavaObject.h"
#include "JavaThread.h"
#include "JavaTypes.h"
#include "JavaUpcalls.h"
#include "Jnjvm.h"
#include "JnjvmClassLoader.h"

using namespace j3;

extern "C" {

JNIEXPORT jobject JNICALL Java_java_lang_reflect_Constructor_getParameterTypes(
#ifdef NATIVE_JNI
JNIEnv *env,
#endif
JavaObjectConstructor* cons) {

  JavaObject* res = 0;
  
  llvm_gcroot(cons, 0);
  llvm_gcroot(res, 0);

  BEGIN_NATIVE_EXCEPTION(0)

  verifyNull(cons);
  UserClass* cl = JavaObjectConstructor::getClass(cons);
  JavaMethod* meth = JavaObjectConstructor::getInternalMethod(cons);
  JnjvmClassLoader* loader = cl->classLoader;

  res = meth->getParameterTypes(loader);
  END_NATIVE_EXCEPTION

  return (jobject)res;
}

JNIEXPORT jint JNICALL Java_java_lang_reflect_Constructor_getModifiersInternal(
#ifdef NATIVE_JNI
JNIEnv *env,
#endif
JavaObjectConstructor* cons) {

  llvm_gcroot(cons, 0);
  jint res = 0;

  BEGIN_NATIVE_EXCEPTION(0)

  verifyNull(cons);
  JavaMethod* meth = JavaObjectConstructor::getInternalMethod(cons);
  res = meth->access;

  END_NATIVE_EXCEPTION

  return res;
}

JavaObject* proceedConstructor(JavaObjectConstructor* cons,
                               ArrayObject* args,
                               JavaObject* Clazz, jint index) 
  __attribute__ ((noinline));
 
JavaObject* proceedConstructor(JavaObjectConstructor* cons,
                               ArrayObject* args,
                               JavaObject* Clazz, jint index) {
  JavaObject* res = 0;
	mvm::gc* excp = 0;
	JavaObject* jexcp;
	
  llvm_gcroot(cons, 0);
  llvm_gcroot(args, 0);
  llvm_gcroot(Clazz, 0);
  llvm_gcroot(res, 0);
  llvm_gcroot(excp, 0);
	llvm_gcroot(jexcp, 0);

  JavaMethod* meth = JavaObjectConstructor::getInternalMethod(cons);
  UserClass* cl = JavaObjectConstructor::getClass(cons);
  Jnjvm* vm = cl->classLoader->vm;
  sint32 nbArgs = args ? ArrayObject::getSize(args) : 0;
  Signdef* sign = meth->getSignature();
  sint32 size = sign->nbArguments;

  if (isAbstract(cl->access)) vm->instantiationException(cl);

  mvm::ThreadAllocator allocator;
  // Allocate a buffer to store the arguments.
  jvalue* buf = size ? 
      (jvalue*)allocator.Allocate(size * sizeof(jvalue)) : NULL;

  if (nbArgs == size) {
    UserCommonClass* _cl = UserCommonClass::resolvedImplClass(Clazz, false);
    UserClass* cl = _cl->asClass();
    if (cl) {
      cl->initialiseClass();
      res = cl->doNew();
      JavaObject** ptr = (JavaObject**)ArrayObject::getElements(args);
      
      Typedef* const* arguments = sign->getArgumentsType();
      // Store the arguments, unboxing primitives if necessary.
      for (sint32 i = 0; i < size; ++i) {
        JavaObject::decapsulePrimitive(ptr[i], &buf[i], arguments[i]);
        if (!arguments[i]->isPrimitive()) {
          buf[i].l = reinterpret_cast<jobject>(&ptr[i]);
        }
      }
      
      TRY {
        meth->invokeIntSpecialBuf(cl, res, buf);
      } CATCH {
        excp = mvm::Thread::get()->getPendingException();
      } END_CATCH;
			mvm::Thread* mut = mvm::Thread::get();
      if (excp) {
				jexcp = Jnjvm::asJavaException(excp);
        if (jexcp && JavaObject::getClass(jexcp)->isAssignableFrom(vm->upcalls->newException)) {
          mut->clearPendingException();
          // If it's an exception, we encapsule it in an
          // invocationTargetException
          vm->invocationTargetException(jexcp);
        } else {
          // If it's an error, throw it again.
          mut->throwIt();
        }
        return NULL;
      }
    } else {
      vm->illegalArgumentException("class is not a regular class");
      return NULL;
    }
  } else {
    vm->illegalArgumentException("wrong number of arguments");
    return NULL;
  }
 
  return res;
}

JNIEXPORT JavaObject* JNICALL Java_java_lang_reflect_Constructor_constructNative(
#ifdef NATIVE_JNI
JNIEnv *env,
#endif
JavaObjectConstructor* cons, ArrayObject* args, JavaObject* Clazz, jint index) {

  JavaObject* res = 0;

  llvm_gcroot(res, 0);
  llvm_gcroot(cons, 0);
  llvm_gcroot(args, 0);
  llvm_gcroot(Clazz, 0);
  
  BEGIN_NATIVE_EXCEPTION(0)

  res = proceedConstructor(cons, args, Clazz, index);
  
  END_NATIVE_EXCEPTION
  
  return res;
}

JNIEXPORT 
ArrayObject* JNICALL Java_java_lang_reflect_Constructor_getExceptionTypes(
#ifdef NATIVE_JNI
JNIEnv *env, 
#endif
JavaObjectConstructor* cons) {
  
  ArrayObject* res = 0;

  llvm_gcroot(res, 0);
  llvm_gcroot(cons, 0);

  BEGIN_NATIVE_EXCEPTION(0)
  
  verifyNull(cons);
  UserClass* cl = JavaObjectConstructor::getClass(cons);
  JavaMethod* meth = JavaObjectConstructor::getInternalMethod(cons);
  JnjvmClassLoader* loader = cl->classLoader;

  res = (ArrayObject*)meth->getExceptionTypes(loader);

  END_NATIVE_EXCEPTION

  return res;
}

JNIEXPORT JavaObject* JNICALL Java_java_lang_reflect_Constructor_getSignature(
#ifdef NATIVE_JNI
JNIEnv *env, 
#endif
JavaObjectConstructor* Meth) {

  JavaObject* result = 0;

  llvm_gcroot(result, 0);
  llvm_gcroot(Meth, 0);

  BEGIN_NATIVE_EXCEPTION(0)

  verifyNull(Meth);
  JavaMethod* meth = JavaObjectConstructor::getInternalMethod(Meth);
  Jnjvm* vm = meth->classDef->classLoader->vm;
  result = vm->internalUTF8ToStr(meth->type);
  
  END_NATIVE_EXCEPTION

  return result;
}


}
