// natVMClassLoader.cc - VMClassLoader native methods

/* Copyright (C) 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.  */

/* 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/VMClassLoader.h>
#include <java/lang/VMCompiler.h>
#include <gnu/gcj/runtime/ExtensionClassLoader.h>
#include <gnu/gcj/runtime/SystemClassLoader.h>
#include <gnu/gcj/runtime/BootClassLoader.h>
#include <java/lang/ClassLoader.h>
#include <java/lang/Class.h>
#include <java/lang/Throwable.h>
#include <java/security/ProtectionDomain.h>
#include <java/lang/ClassFormatError.h>
#include <java/lang/StringBuffer.h>
#include <java/lang/SecurityManager.h>
#include <java/lang/Runtime.h>
#include <java/util/HashSet.h>
#include <java/lang/SecurityException.h>
#include <java/lang/VirtualMachineError.h>

java::lang::Class *
java::lang::VMClassLoader::defineClass (java::lang::ClassLoader *loader,
					jstring name,
					jbyteArray data, 
					jint offset,
					jint length,
					java::security::ProtectionDomain *pd)
{
  jclass klass = VMCompiler::compileClass(loader, name, data,
					  offset, length, pd);

  if (klass)
    _Jv_RegisterInitiatingLoader (klass, klass->loader);

#ifdef INTERPRETER
  if (klass == NULL)
    {
      klass = new java::lang::Class ();

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

      // Record the defining loader.  For the bootstrap class loader,
      // we record NULL.
      if (loader != bootLoader)
	klass->loader = 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;
	}

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

	  if (found_name != NULL)
	    _Jv_UnregisterInitiatingLoader (klass, klass->loader);

	  // If EX is not a ClassNotFoundException, that's ok, because we
	  // account for the possibility in defineClass().
	  throw ex;
	}

      // if everything proceeded sucessfully, we're loaded.
      JvAssert (klass->state == JV_STATE_READ);
    }
#endif // INTERPRETER

  if (! klass)
    {
      StringBuffer *sb = new StringBuffer();
      if (name)
	{
	  sb->append(JvNewStringLatin1("found class file for class "));
	  sb->append(name);
	}
      else
	sb->append(JvNewStringLatin1("found unnamed class file"));
      sb->append(JvNewStringLatin1(", but no interpreter configured in this libgcj"));
      throw new VirtualMachineError(sb->toString());
    }

  return klass;
}

java::lang::ClassLoader *
java::lang::VMClassLoader::getSystemClassLoaderInternal()
{
  _Jv_InitClass (&gnu::gcj::runtime::ExtensionClassLoader::class$);
  _Jv_CopyClassesToSystemLoader (gnu::gcj::runtime::ExtensionClassLoader::system_instance);
  return gnu::gcj::runtime::ExtensionClassLoader::system_instance;
}

jclass
java::lang::VMClassLoader::getPrimitiveClass (jchar type)
{
  char sig[2];
  sig[0] = (char) type;
  sig[1] = '\0';
  // Note: this cannot return NULL, since the input is always correct.
  return _Jv_FindClassFromSignature (sig, NULL);
}

void
java::lang::VMClassLoader::initBootLoader(jstring libdir)
{
  bootLoader = new gnu::gcj::runtime::BootClassLoader(libdir);
}

jclass
java::lang::VMClassLoader::nativeFindClass (jstring name)
{
  jclass klass = NULL;

  if (lib_control != LIB_NEVER)
    {
      // 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-"));
      // Skip inner classes
      jstring cn;
      jint ci = name->indexOf('$');
      if (ci == -1)
	cn = name;
      else
	cn = name->substring (0, ci);
      jstring so_base_name
	= (sb->append (cn)->toString ())->replace ('.', '-');

      using namespace ::java::lang;
      Runtime *rt = Runtime::getRuntime();

      _Jv_Utf8Const *name_u = NULL;

      // Compare against `3' because that is the length of "lib".
      while (! klass && so_base_name && so_base_name->length() > 3)
	{
	  if (lib_control == LIB_CACHE)
	    {
	      // If we've already tried this name, we're done.
	      if (tried_libraries->contains(so_base_name))
		break;
	      tried_libraries->add(so_base_name);
	    }

	  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)
	    {
	      if (name_u == NULL)
		name_u = _Jv_makeUtf8Const (name);
	      klass = _Jv_FindClassInCache (name_u);
	    }
	}
    }

  if (klass)
    definePackageForNative(name);

  return klass;
}

jclass
java::lang::VMClassLoader::loadClass(jstring name, jboolean resolve)
{
  using namespace ::java::lang;

  SecurityManager *sm = (SecurityManager *)SecurityManager::current;
  if (sm)
    {
      jint lastDot = name->lastIndexOf('.');
      if (lastDot != -1)
	sm->checkPackageAccess(name->substring(0, lastDot));
    }

  // We try the boot loader first, so that the endorsed directory
  // overrides compiled-in classes.
  jclass klass = NULL;
  if (bootLoader)
    klass = bootLoader->bootLoadClass(name);
  if (! klass)
    {
      _Jv_Utf8Const *utf = _Jv_makeUtf8Const (name);
      klass = _Jv_FindClassInCache (utf);
    }
  if (! klass)
    klass = nativeFindClass(name);
  if (klass)
    {
      // We never want to return a class without its supers linked.
      // It isn't clear from the spec, but this is what other
      // implementations do in practice.
      if (resolve)
	resolveClass (klass);
      else
	_Jv_Linker::wait_for_state (klass, JV_STATE_LOADING);

      definePackageForNative(name);
    }

  return klass;
}
