// natClassLoader.cc - Implementation of java.lang.ClassLoader native methods.

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

/* Author: Kresten Krab Thorup <krab@gnu.org>  */

#include <config.h>

#include <stdlib.h>
#include <string.h>

#include <gcj/cni.h>
#include <jvm.h>

#include <java-threads.h>
#include <java-interp.h>

#include <java/lang/Character.h>
#include <java/lang/Thread.h>
#include <java/lang/ClassLoader.h>
#include <gnu/gcj/runtime/VMClassLoader.h>
#include <java/lang/InternalError.h>
#include <java/lang/IllegalAccessError.h>
#include <java/lang/LinkageError.h>
#include <java/lang/ClassFormatError.h>
#include <java/lang/NoClassDefFoundError.h>
#include <java/lang/ClassNotFoundException.h>
#include <java/lang/ClassCircularityError.h>
#include <java/lang/IncompatibleClassChangeError.h>
#include <java/lang/VirtualMachineError.h>
#include <java/lang/VMClassLoader.h>
#include <java/lang/reflect/Modifier.h>
#include <java/lang/Runtime.h>
#include <java/lang/StringBuffer.h>
#include <java/io/Serializable.h>
#include <java/lang/Cloneable.h>

// FIXME: remove these.
#define CloneableClass java::lang::Cloneable::class$
#define ObjectClass java::lang::Object::class$
#define ClassClass java::lang::Class::class$
#define VMClassLoaderClass gnu::gcj::runtime::VMClassLoader::class$
#define ClassLoaderClass java::lang::ClassLoader::class$
#define SerializableClass java::io::Serializable::class$

/////////// java.lang.ClassLoader native methods ////////////

java::lang::Class *
java::lang::ClassLoader::defineClass0 (jstring name,
				       jbyteArray data, 
				       jint offset,
				       jint length,
				       java::security::ProtectionDomain *pd)
{
#ifdef INTERPRETER
  jclass klass;
  klass = (jclass) JvAllocObject (&ClassClass, sizeof (_Jv_InterpClass));
  _Jv_InitNewClassFields (klass);

  // synchronize on the class, so that it is not
  // attempted initialized until we're done loading.
  _Jv_MonitorEnter (klass);

  // record which is the defining loader
  klass->loader = this;

  // register that we are the initiating loader...
  if (name != 0)
    {
      _Jv_Utf8Const *   name2 = _Jv_makeUtf8Const (name);

      if (! _Jv_VerifyClassName (name2))
	throw new java::lang::ClassFormatError
	  (JvNewStringLatin1 ("erroneous class name"));

      klass->name = name2;
    }

  try
    {
      _Jv_DefineClass (klass, data, offset, length);
    }
  catch (java::lang::Throwable *ex)
    {
      klass->state = JV_STATE_ERROR;
      klass->notifyAll ();

      _Jv_UnregisterClass (klass);

      _Jv_MonitorExit (klass);

      // FIXME: Here we may want to test that EX does
      // indeed represent a valid exception.  That is,
      // anything but ClassNotFoundException, 
      // or some kind of Error.

      // FIXME: Rewrite this as a cleanup instead of
      // as a catch handler.

      throw ex;
    }
    
  klass->protectionDomain = pd;

  // if everything proceeded sucessfully, we're loaded.
  JvAssert (klass->state == JV_STATE_LOADED);

  // if an exception is generated, this is initially missed.
  // however, we come back here in handleException0 below...
  _Jv_MonitorExit (klass);

  return klass;

#else // INTERPRETER

  return 0;
#endif
}

void
_Jv_WaitForState (jclass klass, int state)
{
  if (klass->state >= state)
    return;
  
  _Jv_MonitorEnter (klass) ;

  if (state == JV_STATE_LINKED)
    {
      // Must call _Jv_PrepareCompiledClass while holding the class
      // mutex.
      _Jv_PrepareCompiledClass (klass);
      _Jv_MonitorExit (klass);
      return;
    }
	
  java::lang::Thread *self = java::lang::Thread::currentThread();

  // this is similar to the strategy for class initialization.
  // if we already hold the lock, just leave.
  while (klass->state <= state
	 && klass->thread 
	 && klass->thread != self)
    klass->wait ();

  _Jv_MonitorExit (klass);

  if (klass->state == JV_STATE_ERROR)
    throw new java::lang::LinkageError;
}

// Finish linking a class.  Only called from ClassLoader::resolveClass.
void
java::lang::ClassLoader::linkClass0 (java::lang::Class *klass)
{
  if (klass->state >= JV_STATE_LINKED)
    return;

#ifdef INTERPRETER
  if (_Jv_IsInterpretedClass (klass))
    _Jv_PrepareClass (klass);
#endif

  _Jv_PrepareCompiledClass (klass);
}

void
java::lang::ClassLoader::markClassErrorState0 (java::lang::Class *klass)
{
  klass->state = JV_STATE_ERROR;
  klass->notifyAll ();
}

jclass
java::lang::VMClassLoader::getPrimitiveClass (jchar type)
{
  char sig[2];
  sig[0] = (char) type;
  sig[1] = '\0';
  return _Jv_FindClassFromSignature (sig, NULL);
}

// This is the findClass() implementation for the System classloader. It is 
// the only native method in VMClassLoader, so we define it here.
jclass
gnu::gcj::runtime::VMClassLoader::findClass (jstring name)
{
  _Jv_Utf8Const *name_u = _Jv_makeUtf8Const (name);
  jclass klass = _Jv_FindClassInCache (name_u, 0);

  if (! klass)
    {
      // Turn `gnu.pkg.quux' into `lib-gnu-pkg-quux'.  Then search for
      // a module named (eg, on Linux) `lib-gnu-pkg-quux.so', followed
      // by `lib-gnu-pkg.so' and `lib-gnu.so'.  If loading one of
      // these causes the class to appear in the cache, then use it.
      java::lang::StringBuffer *sb = new java::lang::StringBuffer (JvNewStringLatin1("lib-"));
      jstring so_base_name = (sb->append (name)->toString ())->replace ('.', '-');

      while (! klass && so_base_name && so_base_name->length() > 0)
	{
	  using namespace ::java::lang;
	  Runtime *rt = Runtime::getRuntime();
	  jboolean loaded = rt->loadLibraryInternal (so_base_name);

	  jint nd = so_base_name->lastIndexOf ('-');
	  if (nd == -1)
	    so_base_name = NULL;
	  else
	    so_base_name = so_base_name->substring (0, nd);

	  if (loaded)
	    klass = _Jv_FindClassInCache (name_u, 0);
	}
    }

  // Now try loading using the interpreter.
  if (! klass)
    {
      klass = java::net::URLClassLoader::findClass (name);
    }

  return klass;
}

jclass
java::lang::ClassLoader::findLoadedClass (jstring name)
{
  return _Jv_FindClassInCache (_Jv_makeUtf8Const (name), this);
}

/** This function does class-preparation for compiled classes.  
    NOTE: It contains replicated functionality from
    _Jv_ResolvePoolEntry, and this is intentional, since that function
    lives in resolve.cc which is entirely conditionally compiled.
 */
void
_Jv_PrepareCompiledClass (jclass klass)
{
  if (klass->state >= JV_STATE_LINKED)
    return;

  // Short-circuit, so that mutually dependent classes are ok.
  klass->state = JV_STATE_LINKED;

  _Jv_Constants *pool = &klass->constants;
  for (int index = 1; index < pool->size; ++index)
    {
      if (pool->tags[index] == JV_CONSTANT_Class)
	{
	  _Jv_Utf8Const *name = pool->data[index].utf8;
	  
	  jclass found;
	  if (name->data[0] == '[')
	    found = _Jv_FindClassFromSignature (&name->data[0],
						klass->loader);
	  else
	    found = _Jv_FindClass (name, klass->loader);
		
	  if (! found)
	    {
	      jstring str = _Jv_NewStringUTF (name->data);
	      throw new java::lang::ClassNotFoundException (str);
	    }

	  pool->data[index].clazz = found;
	  pool->tags[index] |= JV_CONSTANT_ResolvedFlag;
	}
      else if (pool->tags[index] == JV_CONSTANT_String)
	{
	  jstring str;
	  str = _Jv_NewStringUtf8Const (pool->data[index].utf8);
	  pool->data[index].o = str;
	  pool->tags[index] |= JV_CONSTANT_ResolvedFlag;
	}
    }

#ifdef INTERPRETER
  // FIXME: although the comment up top says that this function is
  // only called for compiled classes, it is actually called for every
  // class.
  if (! _Jv_IsInterpretedClass (klass))
    {
#endif /* INTERPRETER */
      jfieldID f = JvGetFirstStaticField (klass);
      for (int n = JvNumStaticFields (klass); n > 0; --n)
	{
	  int mod = f->getModifiers ();
	  // Maybe the compiler should mark these with
	  // _Jv_FIELD_CONSTANT_VALUE?  For now we just know that this
	  // only happens for constant strings.
	  if (f->getClass () == &StringClass
	      && java::lang::reflect::Modifier::isStatic (mod)
	      && java::lang::reflect::Modifier::isFinal (mod))
	    {
	      jstring *strp = (jstring *) f->u.addr;
	      if (*strp)
		*strp = _Jv_NewStringUtf8Const ((_Jv_Utf8Const *) *strp);
	    }
	  f = f->getNextField ();
	}
#ifdef INTERPRETER
    }
#endif /* INTERPRETER */

  if (klass->vtable == NULL)
    _Jv_MakeVTable(klass);

  if (klass->otable != NULL && klass->otable->state == 0)
    _Jv_LinkOffsetTable(klass);

  klass->notifyAll ();
}


//
//  A single class can have many "initiating" class loaders,
//  and a single "defining" class loader.  The Defining
//  class loader is what is returned from Class.getClassLoader()
//  and is used when loading dependent classes during resolution.
//  The set of initiating class loaders are used to ensure
//  safety of linking, and is maintained in the hash table
//  "initiated_classes".  A defining classloader is by definition also
//  initiating, so we only store classes in this table, if they have more
//  than one class loader associated.
//


// Size of local hash table.
#define HASH_LEN 1013

// Hash function for Utf8Consts.
#define HASH_UTF(Utf) (((Utf)->hash) % HASH_LEN)

struct _Jv_LoaderInfo {
    _Jv_LoaderInfo          *next;
    java::lang::Class       *klass;
    java::lang::ClassLoader *loader;
};

static _Jv_LoaderInfo *initiated_classes[HASH_LEN];
static jclass loaded_classes[HASH_LEN];

// This is the root of a linked list of classes



jclass
_Jv_FindClassInCache (_Jv_Utf8Const *name, java::lang::ClassLoader *loader)
{
  _Jv_MonitorEnter (&ClassClass);
  jint hash = HASH_UTF (name);

  // first, if LOADER is a defining loader, then it is also initiating
  jclass klass;
  for (klass = loaded_classes[hash]; klass; klass = klass->next)
    {
      if (loader == klass->loader && _Jv_equalUtf8Consts (name, klass->name))
	break;
    }

  // otherwise, it may be that the class in question was defined
  // by some other loader, but that the loading was initiated by 
  // the loader in question.
  if (!klass)
    {
      _Jv_LoaderInfo *info;
      for (info = initiated_classes[hash]; info; info = info->next)
	{
	  if (loader == info->loader
	      && _Jv_equalUtf8Consts (name, info->klass->name))
	    {
	      klass = info->klass;
	      break;
	    }
	}
    }

  _Jv_MonitorExit (&ClassClass);

  return klass;
}

void
_Jv_UnregisterClass (jclass the_class)
{
  _Jv_MonitorEnter (&ClassClass);
  jint hash = HASH_UTF(the_class->name);

  jclass *klass = &(loaded_classes[hash]);
  for ( ; *klass; klass = &((*klass)->next))
    {
      if (*klass == the_class)
	{
	  *klass = (*klass)->next;
	  break;
	}
    }

  _Jv_LoaderInfo **info = &(initiated_classes[hash]);
  for ( ; ; info = &((*info)->next))
    {
      while (*info && (*info)->klass == the_class)
	{
	  *info = (*info)->next;
	}

      if (*info == NULL)
	break;
    }

  _Jv_MonitorExit (&ClassClass);
}

void
_Jv_RegisterInitiatingLoader (jclass klass, java::lang::ClassLoader *loader)
{
  // non-gc alloc!
  _Jv_LoaderInfo *info = (_Jv_LoaderInfo *) _Jv_Malloc (sizeof(_Jv_LoaderInfo));
  jint hash = HASH_UTF(klass->name);

  _Jv_MonitorEnter (&ClassClass);
  info->loader = loader;
  info->klass  = klass;
  info->next   = initiated_classes[hash];
  initiated_classes[hash] = info;
  _Jv_MonitorExit (&ClassClass);
}

// This function is called many times during startup, before main() is
// run.  At that point in time we know for certain we are running 
// single-threaded, so we don't need to lock when adding classes to the 
// class chain.  At all other times, the caller should synchronize on
// Class::class$.
void
_Jv_RegisterClasses (jclass *classes)
{
  for (; *classes; ++classes)
    {
      jclass klass = *classes;

      (*_Jv_RegisterClassHook) (klass);

      // registering a compiled class causes
      // it to be immediately "prepared".  
      if (klass->state == JV_STATE_NOTHING)
	klass->state = JV_STATE_COMPILED;
    }
}

void
_Jv_RegisterClassHookDefault (jclass klass)
{
  jint hash = HASH_UTF (klass->name);

  jclass check_class = loaded_classes[hash];

  // If the class is already registered, don't re-register it.
  while (check_class != NULL)
    {
      if (check_class == klass)
	{
	  // If you get this, it means you have the same class in two
	  // different libraries.
#define TEXT "Duplicate class registration: "
	  // We size-limit MESSAGE so that you can't trash the stack.
	  char message[200];
	  strcpy (message, TEXT);
	  strncpy (message + sizeof (TEXT) - 1, klass->name->data,
		   sizeof (message) - sizeof (TEXT));
	  message[sizeof (message) - 1] = '\0';
	  if (! gcj::runtimeInitialized)
	    JvFail (message);
	  else
	    {
	      java::lang::String *str = JvNewStringLatin1 (message);
	      throw new java::lang::VirtualMachineError (str);
	    }
	}

      check_class = check_class->next;
    }

  klass->next = loaded_classes[hash];
  loaded_classes[hash] = klass;
}

// A pointer to a function that actually registers a class.
// Normally _Jv_RegisterClassHookDefault, but could be some other function
// that registers the class in e.g. a ClassLoader-local table.
// Should synchronize on Class:class$ while setting/restore this variable.

void (*_Jv_RegisterClassHook) (jclass cl) = _Jv_RegisterClassHookDefault;

void
_Jv_RegisterClass (jclass klass)
{
  jclass classes[2];
  classes[0] = klass;
  classes[1] = NULL;
  _Jv_RegisterClasses (classes);
}

jclass
_Jv_FindClass (_Jv_Utf8Const *name, java::lang::ClassLoader *loader)
{
  jclass klass = _Jv_FindClassInCache (name, loader);

  if (! klass)
    {
      jstring sname = _Jv_NewStringUTF (name->data);

      if (loader)
	{
	  // Load using a user-defined loader, jvmspec 5.3.2
	  klass = loader->loadClass(sname, false);

	  // If "loader" delegated the loadClass operation to another
	  // loader, explicitly register that it is also an initiating
	  // loader of the given class.
	  if (klass && (klass->getClassLoader () != loader))
	    _Jv_RegisterInitiatingLoader (klass, loader);
	}
      else 
	{
	  java::lang::ClassLoader *sys
	    = java::lang::ClassLoader::getSystemClassLoader ();

	  // Load using the bootstrap loader jvmspec 5.3.1.
	  klass = sys->loadClass (sname, false); 

	  // Register that we're an initiating loader.
	  if (klass)
	    _Jv_RegisterInitiatingLoader (klass, 0);
	}
    }
  else
    {
      // we need classes to be in the hash while
      // we're loading, so that they can refer to themselves. 
      _Jv_WaitForState (klass, JV_STATE_LOADED);
    }

  return klass;
}

void
_Jv_InitNewClassFields (jclass ret)
{
  ret->next = NULL;
  ret->name = NULL;
  ret->accflags = 0;
  ret->superclass = NULL;
  ret->constants.size = 0;
  ret->constants.tags = NULL;
  ret->constants.data = NULL;
  ret->methods = NULL;
  ret->method_count = 0;
  ret->vtable_method_count = 0;
  ret->fields = NULL;
  ret->size_in_bytes = 0;
  ret->field_count = 0;
  ret->static_field_count = 0;
  ret->vtable = NULL;
  ret->interfaces = NULL;
  ret->loader = NULL;
  ret->interface_count = 0;
  ret->state = JV_STATE_NOTHING;
  ret->thread = NULL;
  ret->depth = 0;
  ret->ancestors = NULL;
  ret->idt = NULL;
  ret->arrayclass = NULL;
}

jclass
_Jv_NewClass (_Jv_Utf8Const *name, jclass superclass,
	      java::lang::ClassLoader *loader)
{
  jclass ret = (jclass) JvAllocObject (&ClassClass);
  _Jv_InitNewClassFields (ret);
  ret->name = name;
  ret->superclass = superclass;
  ret->loader = loader;

  _Jv_RegisterClass (ret);

  return ret;
}

static _Jv_IDispatchTable *array_idt = NULL;
static jshort array_depth = 0;
static jclass *array_ancestors = NULL;

// Create a class representing an array of ELEMENT and store a pointer to it
// in element->arrayclass. LOADER is the ClassLoader which _initiated_ the 
// instantiation of this array. ARRAY_VTABLE is the vtable to use for the new 
// array class. This parameter is optional.
void
_Jv_NewArrayClass (jclass element, java::lang::ClassLoader *loader,
		   _Jv_VTable *array_vtable)
{
  JvSynchronize sync (element);

  _Jv_Utf8Const *array_name;
  int len;

  if (element->arrayclass)
    return;

  if (element->isPrimitive())
    {
      if (element == JvPrimClass (void))
	throw new java::lang::ClassNotFoundException ();
      len = 3;
    }
  else
    len = element->name->length + 5;

  {
    char signature[len];
    int index = 0;
    signature[index++] = '[';
    // Compute name of array class.
    if (element->isPrimitive())
      {
	signature[index++] = (char) element->method_count;
      }
    else
      {
	size_t length = element->name->length;
	const char *const name = element->name->data;
	if (name[0] != '[')
	  signature[index++] = 'L';
	memcpy (&signature[index], name, length);
	index += length;
	if (name[0] != '[')
	  signature[index++] = ';';
      }      
    array_name = _Jv_makeUtf8Const (signature, index);
  }

  // Create new array class.
  jclass array_class = _Jv_NewClass (array_name, &ObjectClass,
  				     element->loader);

  // Note that `vtable_method_count' doesn't include the initial
  // gc_descr slot.
  JvAssert (ObjectClass.vtable_method_count == NUM_OBJECT_METHODS);
  int dm_count = ObjectClass.vtable_method_count;

  // Create a new vtable by copying Object's vtable.
  _Jv_VTable *vtable;
  if (array_vtable)
    vtable = array_vtable;
  else
    vtable = _Jv_VTable::new_vtable (dm_count);
  vtable->clas = array_class;
  vtable->gc_descr = ObjectClass.vtable->gc_descr;
  for (int i = 0; i < dm_count; ++i)
    vtable->set_method (i, ObjectClass.vtable->get_method (i));

  array_class->vtable = vtable;
  array_class->vtable_method_count = ObjectClass.vtable_method_count;

  // Stash the pointer to the element type.
  array_class->methods = (_Jv_Method *) element;

  // Register our interfaces.
  static jclass interfaces[] = { &CloneableClass, &SerializableClass };
  array_class->interfaces = interfaces;
  array_class->interface_count = sizeof interfaces / sizeof interfaces[0];

  // Since all array classes have the same interface dispatch table, we can 
  // cache one and reuse it. It is not necessary to synchronize this.
  if (!array_idt)
    {
      _Jv_PrepareConstantTimeTables (array_class);
      array_idt = array_class->idt;
      array_depth = array_class->depth;
      array_ancestors = array_class->ancestors;
    }
  else
    {
      array_class->idt = array_idt;
      array_class->depth = array_depth;
      array_class->ancestors = array_ancestors;
    }

  using namespace java::lang::reflect;
  {
    // Array classes are "abstract final"...
    _Jv_ushort accflags = Modifier::FINAL | Modifier::ABSTRACT;
    // ... and inherit accessibility from element type, per vmspec 5.3.3.2
    accflags |= (element->accflags & Modifier::PUBLIC);
    accflags |= (element->accflags & Modifier::PROTECTED);
    accflags |= (element->accflags & Modifier::PRIVATE);      
    array_class->accflags = accflags;
  }

  // An array class has no visible instance fields. "length" is invisible to 
  // reflection.

  // say this class is initialized and ready to go!
  array_class->state = JV_STATE_DONE;

  // vmspec, section 5.3.3 describes this
  if (element->loader != loader)
    _Jv_RegisterInitiatingLoader (array_class, loader);

  element->arrayclass = array_class;
}
