// 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;
    }

  if (ffi_prep_cif (&cif, FFI_DEFAULT_ABI, 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;
}
