// natMethod.cc - Native code for Method class.

/* Copyright (C) 1998, 1999, 2000, 2001 , 2002, 2003, 2004, 2005, 2006 Free Software Foundation

   This file is part of libgcj.

This software is copyrighted work licensed under the terms of the
Libgcj License.  Please consult the file "LIBGCJ_LICENSE" for
details.  */

#include <config.h>

#include <gcj/cni.h>
#include <jvm.h>
#include <jni.h>
#include <java-stack.h>

#include <java/lang/reflect/Method.h>
#include <java/lang/reflect/Constructor.h>
#include <java/lang/reflect/InvocationTargetException.h>
#include <java/lang/reflect/Modifier.h>

#include <java/lang/Void.h>
#include <java/lang/Byte.h>
#include <java/lang/Boolean.h>
#include <java/lang/Character.h>
#include <java/lang/Short.h>
#include <java/lang/Integer.h>
#include <java/lang/Long.h>
#include <java/lang/Float.h>
#include <java/lang/Double.h>
#include <java/lang/IllegalAccessException.h>
#include <java/lang/IllegalArgumentException.h>
#include <java/lang/IncompatibleClassChangeError.h>
#include <java/lang/NullPointerException.h>
#include <java/lang/ArrayIndexOutOfBoundsException.h>
#include <java/lang/VirtualMachineError.h>
#include <java/lang/Class.h>
#include <gcj/method.h>
#include <gnu/gcj/RawData.h>
#include <java/lang/NoClassDefFoundError.h>

#include <stdlib.h>

#if USE_LIBFFI
#include <ffi.h>
#else
#include <java/lang/UnsupportedOperationException.h>
#endif

typedef JArray< ::java::lang::annotation::Annotation * > * anno_a_t;
typedef JArray< JArray< ::java::lang::annotation::Annotation * > *> * anno_aa_t;



struct cpair
{
  jclass prim;
  jclass wrap;
};

// This is used to determine when a primitive widening conversion is
// allowed.
static cpair primitives[] =
{
#define BOOLEAN 0
  { JvPrimClass (boolean), &java::lang::Boolean::class$ },
  { JvPrimClass (byte), &java::lang::Byte::class$ },
#define SHORT 2
  { JvPrimClass (short), &java::lang::Short::class$ },
#define CHAR 3
  { JvPrimClass (char), &java::lang::Character::class$ },
  { JvPrimClass (int), &java::lang::Integer::class$ },
  { JvPrimClass (long), &java::lang::Long::class$ },
  { JvPrimClass (float), &java::lang::Float::class$ },
  { JvPrimClass (double), &java::lang::Double::class$ },
  { NULL, NULL }
};

static inline jboolean
can_widen (jclass from, jclass to)
{
  int fromx = -1, tox = -1;

  for (int i = 0; primitives[i].prim; ++i)
    {
      if (primitives[i].wrap == from)
	fromx = i;
      if (primitives[i].prim == to)
	tox = i;
    }

  // Can't handle a miss.
  if (fromx == -1 || tox == -1)
    return false;
  // Boolean arguments may not be widened.
  if (fromx == BOOLEAN && tox != BOOLEAN)
    return false;
  // Nothing promotes to char.
  if (tox == CHAR && fromx != CHAR)
    return false;

  return fromx <= tox;
}

#ifdef USE_LIBFFI
static inline ffi_type *
get_ffi_type (jclass klass)
{
  // A special case.
  if (klass == NULL)
    return &ffi_type_pointer;

  ffi_type *r;
  if (klass == JvPrimClass (byte))
    r = &ffi_type_sint8;
  else if (klass == JvPrimClass (short))
    r = &ffi_type_sint16;
  else if (klass == JvPrimClass (int))
    r = &ffi_type_sint32;
  else if (klass == JvPrimClass (long))
    r = &ffi_type_sint64;
  else if (klass == JvPrimClass (float))
    r = &ffi_type_float;
  else if (klass == JvPrimClass (double))
    r = &ffi_type_double;
  else if (klass == JvPrimClass (boolean))
    {
      // On some platforms a bool is a byte, on others an int.
      if (sizeof (jboolean) == sizeof (jbyte))
	r = &ffi_type_sint8;
      else
	{
	  JvAssert (sizeof (jboolean) == sizeof (jint));
	  r = &ffi_type_sint32;
	}
    }
  else if (klass == JvPrimClass (char))
    r = &ffi_type_uint16;
  else
    {
      JvAssert (! klass->isPrimitive());
      r = &ffi_type_pointer;
    }

  return r;
}
#endif // USE_LIBFFI

jobject
java::lang::reflect::Method::invoke (jobject obj, jobjectArray args)
{
  using namespace java::lang::reflect;
  jclass iface = NULL;
  
  if (parameter_types == NULL)
    getType ();
    
  jmethodID meth = _Jv_FromReflectedMethod (this);

  if (Modifier::isStatic(meth->accflags))
    {
      // We have to initialize a static class.  It is safe to do this
      // here and not in _Jv_CallAnyMethodA because JNI initializes a
      // class whenever a method lookup is done.
      _Jv_InitClass (declaringClass);
    }
  else
    {
      jclass objClass = JV_CLASS (obj);
      if (! _Jv_IsAssignableFrom (objClass, declaringClass))
        throw new java::lang::IllegalArgumentException;
    }

  // Check accessibility, if required.
  if (! this->isAccessible())
    {
      if (! (Modifier::isPublic (meth->accflags)))
	{
	  Class *caller = _Jv_StackTrace::GetCallingClass (&Method::class$);
	  if (! _Jv_CheckAccess(caller, declaringClass, meth->accflags))
	    throw new IllegalAccessException;
	}
      else
	// Method is public, check to see if class is accessible.
	{
	  jint flags = (declaringClass->accflags
			& (Modifier::PUBLIC
			   | Modifier::PROTECTED
			   | Modifier::PRIVATE));
	  if (flags == 0) // i.e. class is package private
	    {
	      Class *caller = _Jv_StackTrace::GetCallingClass (&Method::class$);
	      if (! _Jv_ClassNameSamePackage (caller->name,
					      declaringClass->name))
		throw new IllegalAccessException;
	    }
	}
    }

  if (declaringClass->isInterface())
    iface = declaringClass;

  return _Jv_CallAnyMethodA (obj, return_type, meth, false,
			     parameter_types, args, iface);
}

jint
java::lang::reflect::Method::getModifiersInternal ()
{
  return _Jv_FromReflectedMethod (this)->accflags;
}

jstring
java::lang::reflect::Method::getSignature()
{
  return declaringClass->getReflectionSignature (this);
}

jobject
java::lang::reflect::Method::getDefaultValue()
{
  return declaringClass->getMethodDefaultValue(this);
}

anno_a_t
java::lang::reflect::Method::getDeclaredAnnotationsInternal()
{
  return (anno_a_t) declaringClass->getDeclaredAnnotations(this, false);
}

anno_aa_t
java::lang::reflect::Method::getParameterAnnotationsInternal()
{
  return (anno_aa_t) declaringClass->getDeclaredAnnotations(this, true);
}

jstring
java::lang::reflect::Method::getName ()
{
  if (name == NULL)
    name = _Jv_NewStringUtf8Const (_Jv_FromReflectedMethod (this)->name);
  return name;
}

/* Internal method to set return_type and parameter_types fields. */

void
java::lang::reflect::Method::getType ()
{
  _Jv_Method *method = _Jv_FromReflectedMethod (this);
  _Jv_GetTypesFromSignature (method,
			     declaringClass,
			     &parameter_types,
			     &return_type);

  int count = 0;
  if (method->throws != NULL)
    {
      while (method->throws[count] != NULL)
	++count;
    }

  exception_types
    = (JArray<jclass> *) JvNewObjectArray (count, &java::lang::Class::class$,
					   NULL);
  jclass *elts = elements (exception_types);
  for (int i = 0; i < count; ++i)
    elts[i] = _Jv_FindClass (method->throws[i],
			     declaringClass->getClassLoaderInternal ());
}

void
_Jv_GetTypesFromSignature (jmethodID method,
			   jclass declaringClass,
			   JArray<jclass> **arg_types_out,
			   jclass *return_type_out)
{

  _Jv_Utf8Const* sig = method->signature;
  java::lang::ClassLoader *loader = declaringClass->getClassLoaderInternal();
  char *ptr = sig->chars();
  int numArgs = 0;
  /* First just count the number of parameters. */
  // FIXME: should do some validation here, e.g., that there is only
  // one return type.
  for (; ; ptr++)
    {
      switch (*ptr)
	{
	case 0:
	case ')':
	case 'V':
	  break;
	case '[':
	case '(':
	  continue;
	case 'B':
	case 'C':
	case 'D':
	case 'F':
	case 'S':
	case 'I':
	case 'J':
	case 'Z':
	  numArgs++;
	  continue;
	case 'L':
	  numArgs++;
	  do 
	    ptr++;
	  while (*ptr != ';' && ptr[1] != '\0');
	  continue;
	}
      break;
    }

  JArray<jclass> *args = (JArray<jclass> *)
    JvNewObjectArray (numArgs, &java::lang::Class::class$, NULL);
  jclass* argPtr = elements (args);
  for (ptr = sig->chars(); *ptr != '\0'; ptr++)
    {
      if (*ptr == '(')
	continue;
      if (*ptr == ')')
	{
	  argPtr = return_type_out;
	  continue;
	}

      char *end_ptr;
      jclass type = _Jv_FindClassFromSignature (ptr, loader, &end_ptr);
      if (type == NULL)
	// FIXME: This isn't ideal.
	throw new java::lang::NoClassDefFoundError (sig->toString());

      // ARGPTR can be NULL if we are processing the return value of a
      // call from Constructor.
      if (argPtr)
	*argPtr++ = type;

      ptr = end_ptr;
    }
  *arg_types_out = args;
}

// This is a very rough analog of the JNI CallNonvirtual<type>MethodA
// functions.  It handles both Methods and Constructors, and it can
// handle any return type.  In the Constructor case, the `obj'
// argument is unused and should be NULL; also, the `return_type' is
// the class that the constructor will construct.  RESULT is a pointer
// to a `jvalue' (see jni.h); for a void method this should be NULL.
// This function returns an exception (if one was thrown), or NULL if
// the call went ok.
void
_Jv_CallAnyMethodA (jobject obj,
		    jclass return_type,
		    jmethodID meth,
		    jboolean is_constructor,
		    jboolean is_virtual_call,
		    JArray<jclass> *parameter_types,
		    const jvalue *args,
		    jvalue *result,
		    jboolean is_jni_call,
		    jclass iface)
{
  using namespace java::lang::reflect;
  
#ifdef USE_LIBFFI
  JvAssert (! is_constructor || ! obj);
  JvAssert (! is_constructor || return_type);

  // See whether call needs an object as the first argument.  A
  // constructor does need a `this' argument, but it is one we create.
  jboolean needs_this = false;
  if (is_constructor
      || ! Modifier::isStatic(meth->accflags))
    needs_this = true;

  int param_count = parameter_types->length;
  if (needs_this)
    ++param_count;

  ffi_type *rtype;
  // A constructor itself always returns void.
  if (is_constructor || return_type == JvPrimClass (void))
    rtype = &ffi_type_void;
  else
    rtype = get_ffi_type (return_type);
  ffi_type **argtypes = (ffi_type **) __builtin_alloca (param_count
							* sizeof (ffi_type *));

  jclass *paramelts = elements (parameter_types);

  // Special case for the `this' argument of a constructor.  Note that
  // the JDK 1.2 docs specify that the new object must be allocated
  // before argument conversions are done.
  if (is_constructor)
    obj = _Jv_AllocObject (return_type);

  const int size_per_arg = sizeof(jvalue);
  ffi_cif cif;

  char *p = (char *) __builtin_alloca (param_count * size_per_arg);
		// Overallocate to get correct alignment.
  void **values = (void **)
			__builtin_alloca (param_count * sizeof (void *));

  int i = 0;
  if (needs_this)
    {
      // The `NULL' type is `Object'.
      argtypes[i] = get_ffi_type (NULL);
      values[i] = p;
      memcpy (p, &obj, sizeof (jobject));
      p += size_per_arg;
      ++i;
    }

  for (int arg = 0; i < param_count; ++i, ++arg)
    {
      int tsize;

      argtypes[i] = get_ffi_type (paramelts[arg]);
      if (paramelts[arg]->isPrimitive())
	tsize = paramelts[arg]->size();
      else
	tsize = sizeof (jobject);

      // Copy appropriate bits from the jvalue into the ffi array.
      // FIXME: we could do this copying all in one loop, above, by
      // over-allocating a bit.
      // How do we do this without breaking big-endian platforms?
      values[i] = p;
      memcpy (p, &args[arg], tsize);
      p += size_per_arg;
    }

  ffi_abi cabi = FFI_DEFAULT_ABI;
#if defined (X86_WIN32) && !defined (__CYGWIN__)
  if (needs_this)
    cabi = FFI_THISCALL;
#endif
  if (ffi_prep_cif (&cif, cabi, param_count,
		    rtype, argtypes) != FFI_OK)
    throw new java::lang::VirtualMachineError(JvNewStringLatin1("internal error: ffi_prep_cif failed"));

  using namespace java::lang;
  using namespace java::lang::reflect;

  union
  {
    ffi_arg i;
    jobject o;
    jlong l;
    jfloat f;
    jdouble d;
  } ffi_result;

  switch (rtype->type)
    {
    case FFI_TYPE_VOID:
      break;
    case FFI_TYPE_SINT8:
      result->b = 0;
      break;
    case FFI_TYPE_SINT16:
      result->s = 0;
      break;
    case FFI_TYPE_UINT16:
      result->c = 0;
      break;
    case FFI_TYPE_SINT32:
      result->i = 0;
      break;
    case FFI_TYPE_SINT64:
      result->j = 0;
      break;
    case FFI_TYPE_FLOAT:
      result->f = 0;
      break;
    case FFI_TYPE_DOUBLE:
      result->d = 0;
      break;
    case FFI_TYPE_POINTER:
      result->l = 0;
      break;
    default:
      JvFail ("Unknown ffi_call return type");
      break;
    }

  void *ncode;

  // FIXME: If a vtable index is -1 at this point it is invalid, so we
  // have to use the ncode.  
  //
  // This can happen because methods in final classes don't have
  // vtable entries, but _Jv_isVirtualMethod() doesn't know that.  We
  // could solve this problem by allocating a vtable index for methods
  // in final classes.
  if (is_virtual_call 
      && ! Modifier::isFinal (meth->accflags)
      && (_Jv_ushort)-1 != meth->index)
    {
      _Jv_VTable *vtable = *(_Jv_VTable **) obj;
      if (iface == NULL)
	{
	  if (is_jni_call && Modifier::isAbstract (meth->accflags))
	    {
	      // With JNI we don't know if this is an interface call
	      // or a call to an abstract method.  Look up the method
	      // by name, the slow way.
	      _Jv_Method *concrete_meth
		= _Jv_LookupDeclaredMethod (vtable->clas,
					    meth->name,
					    meth->signature,
					    NULL);
	      if (concrete_meth == NULL
		  || concrete_meth->ncode == NULL
		  || Modifier::isAbstract(concrete_meth->accflags))
		throw new java::lang::IncompatibleClassChangeError
		  (_Jv_GetMethodString (vtable->clas, meth));
	      ncode = concrete_meth->ncode;
	    }
	  else
	    ncode = vtable->get_method (meth->index);
	}
      else
	ncode = _Jv_LookupInterfaceMethodIdx (vtable->clas, iface,
					      meth->index);
    }
  else
    {
      ncode = meth->ncode;
    }

  try
    {
      ffi_call (&cif, (void (*)()) ncode, &ffi_result, values);
    }
  catch (Throwable *ex)
    {
      // For JNI we just throw the real error.  For reflection, we
      // wrap the underlying method's exception in an
      // InvocationTargetException.
      if (! is_jni_call)
	ex = new InvocationTargetException (ex);
      throw ex;
    }

  // Since ffi_call returns integer values promoted to a word, use
  // a narrowing conversion for jbyte, jchar, etc. results.
  // Note that boolean is handled either by the FFI_TYPE_SINT8 or
  // FFI_TYPE_SINT32 case.
  if (is_constructor)
    result->l = obj;
  else
    {
      switch (rtype->type)
	{
	case FFI_TYPE_VOID:
	  break;
	case FFI_TYPE_SINT8:
	  result->b = (jbyte)ffi_result.i;
	  break;
	case FFI_TYPE_SINT16:
	  result->s = (jshort)ffi_result.i;
	  break;
	case FFI_TYPE_UINT16:
	  result->c = (jchar)ffi_result.i;
	  break;
	case FFI_TYPE_SINT32:
	  result->i = (jint)ffi_result.i;
	  break;
	case FFI_TYPE_SINT64:
	  result->j = (jlong)ffi_result.l;
	  break;
	case FFI_TYPE_FLOAT:
	  result->f = (jfloat)ffi_result.f;
	  break;
	case FFI_TYPE_DOUBLE:
	  result->d = (jdouble)ffi_result.d;
	  break;
	case FFI_TYPE_POINTER:
	  result->l = (jobject)ffi_result.o;
	  break;
	default:
	  JvFail ("Unknown ffi_call return type");
	  break;
	}
    }
#else
  throw new java::lang::UnsupportedOperationException(JvNewStringLatin1("reflection not available in this build"));
#endif // USE_LIBFFI
}

// This is another version of _Jv_CallAnyMethodA, but this one does
// more checking and is used by the reflection (and not JNI) code.
jobject
_Jv_CallAnyMethodA (jobject obj,
		    jclass return_type,
		    jmethodID meth,
		    jboolean is_constructor,
		    JArray<jclass> *parameter_types,
		    jobjectArray args,
		    jclass iface)
{
  if (parameter_types->length == 0 && args == NULL)
    {
      // The JDK accepts this, so we do too.
    }
  else if (parameter_types->length != args->length)
    throw new java::lang::IllegalArgumentException;

  int param_count = parameter_types->length;

  jclass *paramelts = elements (parameter_types);
  jobject *argelts = args == NULL ? NULL : elements (args);
  jvalue argvals[param_count];

#define COPY(Where, What, Type) \
  do { \
    Type val = (What); \
    memcpy ((Where), &val, sizeof (Type)); \
  } while (0)

  for (int i = 0; i < param_count; ++i)
    {
      jclass k = argelts[i] ? argelts[i]->getClass() : NULL;
      if (paramelts[i]->isPrimitive())
	{
	  if (! argelts[i]
	      || ! k
	      || ! can_widen (k, paramelts[i]))
	    throw new java::lang::IllegalArgumentException;
	    
	  if (paramelts[i] == JvPrimClass (boolean))
	    COPY (&argvals[i],
		  ((java::lang::Boolean *) argelts[i])->booleanValue(),
		  jboolean);
	  else if (paramelts[i] == JvPrimClass (char))
	    COPY (&argvals[i],
		  ((java::lang::Character *) argelts[i])->charValue(),
		  jchar);
          else
	    {
	      java::lang::Number *num = (java::lang::Number *) argelts[i];
	      if (paramelts[i] == JvPrimClass (byte))
		COPY (&argvals[i], num->byteValue(), jbyte);
	      else if (paramelts[i] == JvPrimClass (short))
		COPY (&argvals[i], num->shortValue(), jshort);
	      else if (paramelts[i] == JvPrimClass (int))
		COPY (&argvals[i], num->intValue(), jint);
	      else if (paramelts[i] == JvPrimClass (long))
		COPY (&argvals[i], num->longValue(), jlong);
	      else if (paramelts[i] == JvPrimClass (float))
		COPY (&argvals[i], num->floatValue(), jfloat);
	      else if (paramelts[i] == JvPrimClass (double))
		COPY (&argvals[i], num->doubleValue(), jdouble);
	    }
	}
      else
	{
	  if (argelts[i] && ! paramelts[i]->isAssignableFrom (k))
	    throw new java::lang::IllegalArgumentException;
	  COPY (&argvals[i], argelts[i], jobject);
	}
    }

  jvalue ret_value;
  _Jv_CallAnyMethodA (obj, return_type, meth, is_constructor,
  		      _Jv_isVirtualMethod (meth),
		      parameter_types, argvals, &ret_value,
		      false, iface);

  jobject r;
#define VAL(Wrapper, Field)  (new Wrapper (ret_value.Field))
  if (is_constructor)
    r = ret_value.l;
  else  if (return_type == JvPrimClass (byte))
    r = VAL (java::lang::Byte, b);
  else if (return_type == JvPrimClass (short))
    r = VAL (java::lang::Short, s);
  else if (return_type == JvPrimClass (int))
    r = VAL (java::lang::Integer, i);
  else if (return_type == JvPrimClass (long))
    r = VAL (java::lang::Long, j);
  else if (return_type == JvPrimClass (float))
    r = VAL (java::lang::Float, f);
  else if (return_type == JvPrimClass (double))
    r = VAL (java::lang::Double, d);
  else if (return_type == JvPrimClass (boolean))
    r = VAL (java::lang::Boolean, z);
  else if (return_type == JvPrimClass (char))
    r = VAL (java::lang::Character, c);
  else if (return_type == JvPrimClass (void))
    r = NULL;
  else
    {
      JvAssert (return_type == NULL || ! return_type->isPrimitive());
      r = ret_value.l;
    }

  return r;
}
