// field.h - Header file for fieldID instances.  -*- c++ -*-

/* Copyright (C) 1998, 1999, 2000, 2004  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.  */

#ifndef __GCJ_FIELD_H__
#define __GCJ_FIELD_H__

#include <java/lang/Class.h>
#include <java/lang/reflect/Field.h>
#include <java/lang/reflect/Modifier.h>
#include <gnu/gcj/RawData.h>

#define _Jv_FIELD_UNRESOLVED_FLAG	0x8000
#define	_Jv_FIELD_CONSTANT_VALUE	0x4000

struct _Jv_Field
{
  struct _Jv_Utf8Const*	name;

  /* The type of the field, if isResolved().
     If !isResolved():  The fields's signature as a (Utf8Const*). */
  jclass		type;

  _Jv_ushort		flags;

  _Jv_ushort		bsize;  /* not really needed ... */

  union {
    jint		boffset;  /* offset in bytes for instance field */
    char*		addr;  /* address of static field */
    
    jobject* object_addr;  /* address of static object field... etc */
    jbyte* byte_addr;
    jshort* short_addr;
    jchar* char_addr;
    jint* int_addr;
    jlong* long_addr;
    jfloat* float_addr;
    jdouble* double_addr;
  } u;

#ifdef __cplusplus
  jboolean isResolved ()
  { return ! (flags & _Jv_FIELD_UNRESOLVED_FLAG); }

  public:

  int getOffset () { return u.boffset; }

  jobject getObjectField (jobject obj)
  { return *(jobject *)((char *)obj + getOffset ()); }

  jfieldID getNextField () { return this + 1; }

  jboolean isRef () 
    { 
      if (!isResolved ()) 
	{
	  char first = ((_Jv_Utf8Const*)type)->first(); 
	  return first == '[' || first == 'L';
	}
      else
	{
	  return ! type->isPrimitive ();
	}
    }

  jclass getClass ()
  {
    // We can't use JvAssert here because it is not in a public
    // header.
    // JvAssert (isResolved ());
    return type;
  }

  // Need to mask off all unknown/internal flags before returning.
  int getModifiers()
  {
    return flags & java::lang::reflect::Modifier::ALL_FLAGS;
  }

  _Jv_Utf8Const * getNameUtf8Const (jclass) { return name; }
#endif
};

#ifdef __cplusplus

inline jbyte
_Jv_GetStaticByteField (jclass, _Jv_Field* field)
{
  return * (jbyte *) field->u.addr;
}

inline jshort
_Jv_GetStaticShortField (jclass, _Jv_Field* field)
{
  return * (jshort *) field->u.addr;
}

inline jint
_Jv_GetStaticIntField (jclass, _Jv_Field* field)
{
  return * (jint *) field->u.addr;
}

inline jlong
_Jv_GetStaticLongField (jclass, _Jv_Field* field)
{
  return * (jlong *) field->u.addr;
}

inline jobject
_Jv_GetObjectField (jobject obj, _Jv_Field* field)
{
  return field->getObjectField (obj);
}

inline jbyte
_Jv_GetByteField (jobject obj, _Jv_Field* field)
{
  return * (jbyte *) ((char*) obj + field->getOffset ());
}

inline jshort
_Jv_GetShortField (jobject obj, _Jv_Field* field)
{
  return * (jshort *) ((char*) obj + field->getOffset ());
}
inline jint
_Jv_GetIntField (jobject obj, _Jv_Field* field)
{
  return * (jint *) ((char*) obj + field->getOffset ());
}
inline jlong
_Jv_GetLongField (jobject obj, _Jv_Field* field)
{
  return * (jlong *) ((char*) obj + field->getOffset ());
}

extern inline jfieldID 
_Jv_FromReflectedField (java::lang::reflect::Field *field)
{ 
  return (jfieldID) ((char *) field->declaringClass->fields + field->offset); 
} 


#ifdef __GCJ_CNI_H__
extern inline jfieldID
JvGetFirstInstanceField (jclass klass)
{
  return &(klass->fields[klass->static_field_count]);
}

extern inline jint
JvNumInstanceFields (jclass klass)
{
  return klass->field_count - klass->static_field_count;
}

extern inline jfieldID
JvGetFirstStaticField (jclass klass)
{
  return &(klass->fields[0]);
}

extern inline jint
JvNumStaticFields (jclass klass)
{
  return klass->static_field_count;
}

extern inline jboolean
JvFieldIsRef (jfieldID field)
{
  return field->isRef () && field->type != &gnu::gcj::RawData::class$;
}

extern inline jobject
JvGetObjectField (jobject obj, _Jv_Field* field)
{
  return _Jv_GetObjectField (obj, field);
}
#endif /* defined (__GCJ_CNI_H__) */

#endif /* __cplusplus */

#endif /* __GCJ_FIELD_H */
