// 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_LOADED);
    }
#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;
}
