// prims.cc - Code for core of runtime environment.

/* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007  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 <platform.h>

#include <stdlib.h>
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
#include <signal.h>

#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif

#include <gcj/cni.h>
#include <jvm.h>
#include <java-signal.h>
#include <java-threads.h>
#include <java-interp.h>

#ifdef ENABLE_JVMPI
#include <jvmpi.h>
#include <java/lang/ThreadGroup.h>
#endif

#ifdef INTERPRETER
#include <jvmti.h>
#include "jvmti-int.h"
#endif

#ifndef DISABLE_GETENV_PROPERTIES
#include <java-props.h>
#define PROCESS_GCJ_PROPERTIES process_gcj_properties()
#else
#define PROCESS_GCJ_PROPERTIES
#endif // DISABLE_GETENV_PROPERTIES

#include <java/lang/Class.h>
#include <java/lang/ClassLoader.h>
#include <java/lang/Runtime.h>
#include <java/lang/String.h>
#include <java/lang/Thread.h>
#include <java/lang/ThreadGroup.h>
#include <java/lang/ArrayIndexOutOfBoundsException.h>
#include <java/lang/ArithmeticException.h>
#include <java/lang/ClassFormatError.h>
#include <java/lang/ClassNotFoundException.h>
#include <java/lang/InternalError.h>
#include <java/lang/NegativeArraySizeException.h>
#include <java/lang/NoClassDefFoundError.h>
#include <java/lang/NullPointerException.h>
#include <java/lang/OutOfMemoryError.h>
#include <java/lang/System.h>
#include <java/lang/VMClassLoader.h>
#include <java/lang/reflect/Modifier.h>
#include <java/io/PrintStream.h>
#include <java/lang/UnsatisfiedLinkError.h>
#include <java/lang/VirtualMachineError.h>
#include <gnu/gcj/runtime/ExtensionClassLoader.h>
#include <gnu/gcj/runtime/FinalizerThread.h>
#include <execution.h>

#ifdef INTERPRETER
#include <gnu/classpath/jdwp/Jdwp.h>
#include <gnu/classpath/jdwp/VMVirtualMachine.h>
#endif // INTERPRETER

#include <gnu/java/lang/MainThread.h>

#ifdef USE_LTDL
#include <ltdl.h>
#endif

// Execution engine for compiled code.
_Jv_CompiledEngine _Jv_soleCompiledEngine;

// Execution engine for code compiled with -findirect-classes
_Jv_IndirectCompiledEngine _Jv_soleIndirectCompiledEngine;

// We allocate a single OutOfMemoryError exception which we keep
// around for use if we run out of memory.
static java::lang::OutOfMemoryError *no_memory;

// Number of bytes in largest array object we create.  This could be
// increased to the largest size_t value, so long as the appropriate
// functions are changed to take a size_t argument instead of jint.
#define MAX_OBJECT_SIZE (((size_t)1<<31) - 1)

// Properties set at compile time.
const char **_Jv_Compiler_Properties = NULL;
int _Jv_Properties_Count = 0;

#ifndef DISABLE_GETENV_PROPERTIES
// Property key/value pairs.
property_pair *_Jv_Environment_Properties;
#endif

// Stash the argv pointer to benefit native libraries that need it.
const char **_Jv_argv;
int _Jv_argc;

// Debugging options
static bool remoteDebug = false;
#ifdef INTERPRETER
static char defaultJdwpOptions[] = "";
static char *jdwpOptions = defaultJdwpOptions;

// Typedefs for JVMTI agent functions.
typedef jint jvmti_agent_onload_func (JavaVM *vm, char *options,
                                      void *reserved);
typedef jint jvmti_agent_onunload_func (JavaVM *vm);

// JVMTI agent function pointers.
static jvmti_agent_onload_func *jvmti_agentonload = NULL;
static jvmti_agent_onunload_func *jvmti_agentonunload = NULL;
static char *jvmti_agent_opts;
#endif // INTERPRETER

// Argument support.
int
_Jv_GetNbArgs (void)
{
  // _Jv_argc is 0 if not explicitly initialized.
  return _Jv_argc;
}

const char *
_Jv_GetSafeArg (int index)
{
  if (index >=0 && index < _Jv_GetNbArgs ())
    return _Jv_argv[index];
  else
    return "";
}

void
_Jv_SetArgs (int argc, const char **argv)
{
  _Jv_argc = argc;
  _Jv_argv = argv;
}

#ifdef ENABLE_JVMPI
// Pointer to JVMPI notification functions.
void (*_Jv_JVMPI_Notify_OBJECT_ALLOC) (JVMPI_Event *event);
void (*_Jv_JVMPI_Notify_THREAD_START) (JVMPI_Event *event);
void (*_Jv_JVMPI_Notify_THREAD_END) (JVMPI_Event *event);
#endif


#if defined (HANDLE_SEGV) || defined(HANDLE_FPE)
/* Unblock a signal.  Unless we do this, the signal may only be sent
   once.  */
static void 
unblock_signal (int signum __attribute__ ((__unused__)))
{
#ifdef _POSIX_VERSION
  sigset_t sigs;

  sigemptyset (&sigs);
  sigaddset (&sigs, signum);
  sigprocmask (SIG_UNBLOCK, &sigs, NULL);
#endif
}
#endif

#ifdef HANDLE_SEGV
SIGNAL_HANDLER (catch_segv)
{
  unblock_signal (SIGSEGV);
  MAKE_THROW_FRAME (nullp);
  java::lang::NullPointerException *nullp 
    = new java::lang::NullPointerException;
  throw nullp;
}
#endif

#ifdef HANDLE_FPE
SIGNAL_HANDLER (catch_fpe)
{
  unblock_signal (SIGFPE);
#ifdef HANDLE_DIVIDE_OVERFLOW
  HANDLE_DIVIDE_OVERFLOW;
#else
  MAKE_THROW_FRAME (arithexception);
#endif
  java::lang::ArithmeticException *arithexception 
    = new java::lang::ArithmeticException (JvNewStringLatin1 ("/ by zero"));
  throw arithexception;
}
#endif


jboolean
_Jv_equalUtf8Consts (const Utf8Const* a, const Utf8Const *b)
{
  int len;
  const _Jv_ushort *aptr, *bptr;
  if (a == b)
    return true;
  if (a->hash != b->hash)
    return false;
  len = a->length;
  if (b->length != len)
    return false;
  aptr = (const _Jv_ushort *)a->data;
  bptr = (const _Jv_ushort *)b->data;
  len = (len + 1) >> 1;
  while (--len >= 0)
    if (*aptr++ != *bptr++)
      return false;
  return true;
}

/* True iff A is equal to STR.
   HASH is STR->hashCode().  
*/

jboolean
_Jv_equal (Utf8Const* a, jstring str, jint hash)
{
  if (a->hash != (_Jv_ushort) hash)
    return false;
  jint len = str->length();
  jint i = 0;
  jchar *sptr = _Jv_GetStringChars (str);
  unsigned char* ptr = (unsigned char*) a->data;
  unsigned char* limit = ptr + a->length;
  for (;; i++, sptr++)
    {
      int ch = UTF8_GET (ptr, limit);
      if (i == len)
	return ch < 0;
      if (ch != *sptr)
	return false;
    }
  return true;
}

/* Like _Jv_equal, but stop after N characters.  */
jboolean
_Jv_equaln (Utf8Const *a, jstring str, jint n)
{
  jint len = str->length();
  jint i = 0;
  jchar *sptr = _Jv_GetStringChars (str);
  unsigned char* ptr = (unsigned char*) a->data;
  unsigned char* limit = ptr + a->length;
  for (; n-- > 0; i++, sptr++)
    {
      int ch = UTF8_GET (ptr, limit);
      if (i == len)
	return ch < 0;
      if (ch != *sptr)
	return false;
    }
  return true;
}

// Determines whether the given Utf8Const object contains
// a type which is primitive or some derived form of it, eg.
// an array or multi-dimensional array variant.
jboolean
_Jv_isPrimitiveOrDerived(const Utf8Const *a)
{
  unsigned char *aptr = (unsigned char *) a->data;
  unsigned char *alimit = aptr + a->length;
  int ac = UTF8_GET(aptr, alimit);

  // Skips any leading array marks.
  while (ac == '[')
    ac = UTF8_GET(aptr, alimit);

  // There should not be another character. This implies that
  // the type name is only one character long.
  if (UTF8_GET(aptr, alimit) == -1)
    switch ( ac )
      {
        case 'Z':
        case 'B':
        case 'C':
        case 'S':
        case 'I':
        case 'J':
        case 'F':
        case 'D':
          return true;
        default:
          break;
       }

   return false;
}

// Find out whether two _Jv_Utf8Const candidates contain the same
// classname.
// The method is written to handle the different formats of classnames.
// Eg. "Ljava/lang/Class;", "Ljava.lang.Class;", "java/lang/Class" and
// "java.lang.Class" will be seen as equal.
// Warning: This function is not smart enough to declare "Z" and "boolean"
// and similar cases as equal (and is not meant to be used this way)!
jboolean
_Jv_equalUtf8Classnames (const Utf8Const *a, const Utf8Const *b)
{
  // If the class name's length differs by two characters
  // it is possible that we have candidates which are given
  // in the two different formats ("Lp1/p2/cn;" vs. "p1/p2/cn")
  switch (a->length - b->length)
    {
      case -2:
      case 0:
      case 2:
        break;
      default:
        return false;
    }

  unsigned char *aptr = (unsigned char *) a->data;
  unsigned char *alimit = aptr + a->length;
  unsigned char *bptr = (unsigned char *) b->data;
  unsigned char *blimit = bptr + b->length;

  if (alimit[-1] == ';')
    alimit--;

  if (blimit[-1] == ';')
    blimit--;

  int ac = UTF8_GET(aptr, alimit);
  int bc = UTF8_GET(bptr, blimit);

  // Checks whether both strings have the same amount of leading [ characters.
  while (ac == '[')
    {
      if (bc == '[')
        {
          ac = UTF8_GET(aptr, alimit);
          bc = UTF8_GET(bptr, blimit);
          continue;
        }

      return false;
    }

  // Skips leading L character.
  if (ac == 'L')
    ac = UTF8_GET(aptr, alimit);
        
  if (bc == 'L')
    bc = UTF8_GET(bptr, blimit);

  // Compares the remaining characters.
  while (ac != -1 && bc != -1)
    {
      // Replaces package separating dots with slashes.
      if (ac == '.')
        ac = '/';

      if (bc == '.')
        bc = '/';
      
      // Now classnames differ if there is at least one non-matching
      // character.
      if (ac != bc)
        return false;

      ac = UTF8_GET(aptr, alimit);
      bc = UTF8_GET(bptr, blimit);
    }

  return (ac == bc);
}

/* Count the number of Unicode chars encoded in a given Ut8 string. */
int
_Jv_strLengthUtf8(const char* str, int len)
{
  unsigned char* ptr;
  unsigned char* limit;
  int str_length;

  ptr = (unsigned char*) str;
  limit = ptr + len;
  str_length = 0;
  for (; ptr < limit; str_length++)
    {
      if (UTF8_GET (ptr, limit) < 0)
	return (-1);
    }
  return (str_length);
}

/* Calculate a hash value for a string encoded in Utf8 format.
 * This returns the same hash value as specified or java.lang.String.hashCode.
 */
jint
_Jv_hashUtf8String (const char* str, int len)
{
  unsigned char* ptr = (unsigned char*) str;
  unsigned char* limit = ptr + len;
  jint hash = 0;

  for (; ptr < limit;)
    {
      int ch = UTF8_GET (ptr, limit);
      /* Updated specification from
	 http://www.javasoft.com/docs/books/jls/clarify.html. */
      hash = (31 * hash) + ch;
    }
  return hash;
}

void
_Jv_Utf8Const::init(const char *s, int len)
{
  ::memcpy (data, s, len);
  data[len] = 0;
  length = len;
  hash = _Jv_hashUtf8String (s, len) & 0xFFFF;
}

_Jv_Utf8Const *
_Jv_makeUtf8Const (const char* s, int len)
{
  if (len < 0)
    len = strlen (s);
  Utf8Const* m
    = (Utf8Const*) _Jv_AllocBytes (_Jv_Utf8Const::space_needed(s, len));
  m->init(s, len);
  return m;
}

_Jv_Utf8Const *
_Jv_makeUtf8Const (jstring string)
{
  jint hash = string->hashCode ();
  jint len = _Jv_GetStringUTFLength (string);

  Utf8Const* m = (Utf8Const*)
    _Jv_AllocBytes (sizeof(Utf8Const) + len + 1);

  m->hash = hash;
  m->length = len;

  _Jv_GetStringUTFRegion (string, 0, string->length (), m->data);
  m->data[len] = 0;
  
  return m;
}



#ifdef __GCJ_DEBUG
void
_Jv_Abort (const char *function, const char *file, int line,
	   const char *message)
#else
void
_Jv_Abort (const char *, const char *, int, const char *message)
#endif
{
#ifdef __GCJ_DEBUG
  fprintf (stderr,
	   "libgcj failure: %s\n   in function %s, file %s, line %d\n",
	   message, function, file, line);
#else
  fprintf (stderr, "libgcj failure: %s\n", message);
#endif
  fflush (stderr);
  abort ();
}

static void
fail_on_finalization (jobject)
{
  JvFail ("object was finalized");
}

void
_Jv_GCWatch (jobject obj)
{
  _Jv_RegisterFinalizer (obj, fail_on_finalization);
}

void
_Jv_ThrowBadArrayIndex(jint bad_index)
{
  throw new java::lang::ArrayIndexOutOfBoundsException
    (java::lang::String::valueOf (bad_index));
}

void
_Jv_ThrowNullPointerException ()
{
  throw new java::lang::NullPointerException;
}

// Resolve an entry in the constant pool and return the target
// address.
void *
_Jv_ResolvePoolEntry (jclass this_class, jint index)
{
  _Jv_Constants *pool = &this_class->constants;

  if ((pool->tags[index] & JV_CONSTANT_ResolvedFlag) != 0)
    return pool->data[index].field->u.addr;

  JvSynchronize sync (this_class);
  return (_Jv_Linker::resolve_pool_entry (this_class, index))
    .field->u.addr;
}


// Explicitly throw a no memory exception.
// The collector calls this when it encounters an out-of-memory condition.
void _Jv_ThrowNoMemory()
{
  throw no_memory;
}

#ifdef ENABLE_JVMPI
# define JVMPI_NOTIFY_ALLOC(klass,size,obj) \
    if (__builtin_expect (_Jv_JVMPI_Notify_OBJECT_ALLOC != 0, false)) \
      jvmpi_notify_alloc(klass,size,obj);
static void
jvmpi_notify_alloc(jclass klass, jint size, jobject obj)
{
  // Service JVMPI allocation request.
  JVMPI_Event event;

  event.event_type = JVMPI_EVENT_OBJECT_ALLOC;
  event.env_id = NULL;
  event.u.obj_alloc.arena_id = 0;
  event.u.obj_alloc.class_id = (jobjectID) klass;
  event.u.obj_alloc.is_array = 0;
  event.u.obj_alloc.size = size;
  event.u.obj_alloc.obj_id = (jobjectID) obj;

  // FIXME:  This doesn't look right for the Boehm GC.  A GC may
  // already be in progress.  _Jv_DisableGC () doesn't wait for it.
  // More importantly, I don't see the need for disabling GC, since we
  // blatantly have a pointer to obj on our stack, ensuring that the
  // object can't be collected.  Even for a nonconservative collector,
  // it appears to me that this must be true, since we are about to
  // return obj. Isn't this whole approach way too intrusive for
  // a useful profiling interface?			- HB
  _Jv_DisableGC ();
  (*_Jv_JVMPI_Notify_OBJECT_ALLOC) (&event);
  _Jv_EnableGC ();
}
#else /* !ENABLE_JVMPI */
# define JVMPI_NOTIFY_ALLOC(klass,size,obj) /* do nothing */
#endif

// Allocate a new object of class KLASS.
// First a version that assumes that we have no finalizer, and that
// the class is already initialized.
// If we know that JVMPI is disabled, this can be replaced by a direct call
// to the allocator for the appropriate GC.
jobject
_Jv_AllocObjectNoInitNoFinalizer (jclass klass)
{
  jint size = klass->size ();
  jobject obj = (jobject) _Jv_AllocObj (size, klass);
  JVMPI_NOTIFY_ALLOC (klass, size, obj);
  return obj;
}

// And now a version that initializes if necessary.
jobject
_Jv_AllocObjectNoFinalizer (jclass klass)
{
  if (_Jv_IsPhantomClass(klass) )
    throw new java::lang::NoClassDefFoundError(klass->getName());

  _Jv_InitClass (klass);
  jint size = klass->size ();
  jobject obj = (jobject) _Jv_AllocObj (size, klass);
  JVMPI_NOTIFY_ALLOC (klass, size, obj);
  return obj;
}

// And now the general version that registers a finalizer if necessary.
jobject
_Jv_AllocObject (jclass klass)
{
  jobject obj = _Jv_AllocObjectNoFinalizer (klass);
  
  // We assume that the compiler only generates calls to this routine
  // if there really is an interesting finalizer.
  // Unfortunately, we still have to the dynamic test, since there may
  // be cni calls to this routine.
  // Note that on IA64 get_finalizer() returns the starting address of the
  // function, not a function pointer.  Thus this still works.
  if (klass->vtable->get_finalizer ()
      != java::lang::Object::class$.vtable->get_finalizer ())
    _Jv_RegisterFinalizer (obj, _Jv_FinalizeObject);
  return obj;
}

// Allocate a String, including variable length storage.
jstring
_Jv_AllocString(jsize len)
{
  using namespace java::lang;

  jsize sz = sizeof(java::lang::String) + len * sizeof(jchar);

  // We assert that for strings allocated this way, the data field
  // will always point to the object itself.  Thus there is no reason
  // for the garbage collector to scan any of it.
  // Furthermore, we're about to overwrite the string data, so
  // initialization of the object is not an issue.

  // String needs no initialization, and there is no finalizer, so
  // we can go directly to the collector's allocator interface.
  jstring obj = (jstring) _Jv_AllocPtrFreeObj(sz, &String::class$);

  obj->data = obj;
  obj->boffset = sizeof(java::lang::String);
  obj->count = len;
  obj->cachedHashCode = 0;

  JVMPI_NOTIFY_ALLOC (&String::class$, sz, obj);
  
  return obj;
}

// A version of the above that assumes the object contains no pointers,
// and requires no finalization.  This can't happen if we need pointers
// to locks.
#ifdef JV_HASH_SYNCHRONIZATION
jobject
_Jv_AllocPtrFreeObject (jclass klass)
{
  _Jv_InitClass (klass);
  jint size = klass->size ();

  jobject obj = (jobject) _Jv_AllocPtrFreeObj (size, klass);

  JVMPI_NOTIFY_ALLOC (klass, size, obj);

  return obj;
}
#endif /* JV_HASH_SYNCHRONIZATION */


// Allocate a new array of Java objects.  Each object is of type
// `elementClass'.  `init' is used to initialize each slot in the
// array.
jobjectArray
_Jv_NewObjectArray (jsize count, jclass elementClass, jobject init)
{
  // Creating an array of an unresolved type is impossible. So we throw
  // the NoClassDefFoundError.
  if ( _Jv_IsPhantomClass(elementClass) )
    throw new java::lang::NoClassDefFoundError(elementClass->getName());

  if (__builtin_expect (count < 0, false))
    throw new java::lang::NegativeArraySizeException;

  JvAssert (! elementClass->isPrimitive ());

  // Ensure that elements pointer is properly aligned.
  jobjectArray obj = NULL;
  size_t size = (size_t) elements (obj);
  // Check for overflow.
  if (__builtin_expect ((size_t) count > 
			(MAX_OBJECT_SIZE - 1 - size) / sizeof (jobject), false))
    throw no_memory;

  size += count * sizeof (jobject);

  jclass klass = _Jv_GetArrayClass (elementClass,
				    elementClass->getClassLoaderInternal());

  obj = (jobjectArray) _Jv_AllocArray (size, klass);
  // Cast away const.
  jsize *lp = const_cast<jsize *> (&obj->length);
  *lp = count;
  // We know the allocator returns zeroed memory.  So don't bother
  // zeroing it again.
  if (init)
    {
      jobject *ptr = elements(obj);
      while (--count >= 0)
	*ptr++ = init;
    }
  return obj;
}

// Allocate a new array of primitives.  ELTYPE is the type of the
// element, COUNT is the size of the array.
jobject
_Jv_NewPrimArray (jclass eltype, jint count)
{
  int elsize = eltype->size();
  if (__builtin_expect (count < 0, false))
    throw new java::lang::NegativeArraySizeException;

  JvAssert (eltype->isPrimitive ());
  jobject dummy = NULL;
  size_t size = (size_t) _Jv_GetArrayElementFromElementType (dummy, eltype);

  // Check for overflow.
  if (__builtin_expect ((size_t) count > 
			(MAX_OBJECT_SIZE - size) / elsize, false))
    throw no_memory;

  jclass klass = _Jv_GetArrayClass (eltype, 0);

# ifdef JV_HASH_SYNCHRONIZATION
  // Since the vtable is always statically allocated,
  // these are completely pointerfree!  Make sure the GC doesn't touch them.
  __JArray *arr =
    (__JArray*) _Jv_AllocPtrFreeObj (size + elsize * count, klass);
  memset((char *)arr + size, 0, elsize * count);
# else
  __JArray *arr = (__JArray*) _Jv_AllocObj (size + elsize * count, klass);
  // Note that we assume we are given zeroed memory by the allocator.
# endif
  // Cast away const.
  jsize *lp = const_cast<jsize *> (&arr->length);
  *lp = count;

  return arr;
}

jobject
_Jv_NewArray (jint type, jint size)
{
  switch (type)
    {
      case  4:  return JvNewBooleanArray (size);
      case  5:  return JvNewCharArray (size);
      case  6:  return JvNewFloatArray (size);
      case  7:  return JvNewDoubleArray (size);
      case  8:  return JvNewByteArray (size);
      case  9:  return JvNewShortArray (size);
      case 10:  return JvNewIntArray (size);
      case 11:  return JvNewLongArray (size);
    }
  throw new java::lang::InternalError
    (JvNewStringLatin1 ("invalid type code in _Jv_NewArray"));
}

// Allocate a possibly multi-dimensional array but don't check that
// any array length is <0.
static jobject
_Jv_NewMultiArrayUnchecked (jclass type, jint dimensions, jint *sizes)
{
  JvAssert (type->isArray());
  jclass element_type = type->getComponentType();
  jobject result;
  if (element_type->isPrimitive())
    result = _Jv_NewPrimArray (element_type, sizes[0]);
  else
    result = _Jv_NewObjectArray (sizes[0], element_type, NULL);

  if (dimensions > 1)
    {
      JvAssert (! element_type->isPrimitive());
      JvAssert (element_type->isArray());
      jobject *contents = elements ((jobjectArray) result);
      for (int i = 0; i < sizes[0]; ++i)
	contents[i] = _Jv_NewMultiArrayUnchecked (element_type, dimensions - 1,
						  sizes + 1);
    }

  return result;
}

jobject
_Jv_NewMultiArray (jclass type, jint dimensions, jint *sizes)
{
  for (int i = 0; i < dimensions; ++i)
    if (sizes[i] < 0)
      throw new java::lang::NegativeArraySizeException;

  return _Jv_NewMultiArrayUnchecked (type, dimensions, sizes);
}

jobject
_Jv_NewMultiArray (jclass array_type, jint dimensions, ...)
{
  // Creating an array of an unresolved type is impossible. So we throw
  // the NoClassDefFoundError.
  if (_Jv_IsPhantomClass(array_type))
    throw new java::lang::NoClassDefFoundError(array_type->getName());

  va_list args;
  jint sizes[dimensions];
  va_start (args, dimensions);
  for (int i = 0; i < dimensions; ++i)
    {
      jint size = va_arg (args, jint);
      if (size < 0)
	throw new java::lang::NegativeArraySizeException;
      sizes[i] = size;
    }
  va_end (args);

  return _Jv_NewMultiArrayUnchecked (array_type, dimensions, sizes);
}



// Ensure 8-byte alignment, for hash synchronization.
#define DECLARE_PRIM_TYPE(NAME)			\
  java::lang::Class _Jv_##NAME##Class __attribute__ ((aligned (8)));

DECLARE_PRIM_TYPE(byte)
DECLARE_PRIM_TYPE(short)
DECLARE_PRIM_TYPE(int)
DECLARE_PRIM_TYPE(long)
DECLARE_PRIM_TYPE(boolean)
DECLARE_PRIM_TYPE(char)
DECLARE_PRIM_TYPE(float)
DECLARE_PRIM_TYPE(double)
DECLARE_PRIM_TYPE(void)

void
_Jv_InitPrimClass (jclass cl, const char *cname, char sig, int len)
{    
  using namespace java::lang::reflect;

  // We must set the vtable for the class; the Java constructor
  // doesn't do this.
  (*(_Jv_VTable **) cl) = java::lang::Class::class$.vtable;

  // Initialize the fields we care about.  We do this in the same
  // order they are declared in Class.h.
  cl->name = _Jv_makeUtf8Const ((char *) cname, -1);
  cl->accflags = Modifier::PUBLIC | Modifier::FINAL | Modifier::ABSTRACT;
  cl->method_count = sig;
  cl->size_in_bytes = len;
  cl->vtable = JV_PRIMITIVE_VTABLE;
  cl->state = JV_STATE_DONE;
  cl->depth = -1;
}

jclass
_Jv_FindClassFromSignature (char *sig, java::lang::ClassLoader *loader,
			    char **endp)
{
  // First count arrays.
  int array_count = 0;
  while (*sig == '[')
    {
      ++sig;
      ++array_count;
    }

  jclass result = NULL;
  switch (*sig)
    {
    case 'B':
      result = JvPrimClass (byte);
      break;
    case 'S':
      result = JvPrimClass (short);
      break;
    case 'I':
      result = JvPrimClass (int);
      break;
    case 'J':
      result = JvPrimClass (long);
      break;
    case 'Z':
      result = JvPrimClass (boolean);
      break;
    case 'C':
      result = JvPrimClass (char);
      break;
    case 'F':
      result = JvPrimClass (float);
      break;
    case 'D':
      result = JvPrimClass (double);
      break;
    case 'V':
      result = JvPrimClass (void);
      break;
    case 'L':
      {
	char *save = ++sig;
	while (*sig && *sig != ';')
	  ++sig;
	// Do nothing if signature appears to be malformed.
	if (*sig == ';')
	  {
	    _Jv_Utf8Const *name = _Jv_makeUtf8Const (save, sig - save);
	    result = _Jv_FindClass (name, loader);
	  }
	break;
      }
    default:
      // Do nothing -- bad signature.
      break;
    }

  if (endp)
    {
      // Not really the "end", but the last valid character that we
      // looked at.
      *endp = sig;
    }

  if (! result)
    return NULL;

  // Find arrays.
  while (array_count-- > 0)
    result = _Jv_GetArrayClass (result, loader);
  return result;
}


jclass
_Jv_FindClassFromSignatureNoException (char *sig, java::lang::ClassLoader *loader,
                                       char **endp)
{
  jclass klass;

  try
    {
      klass = _Jv_FindClassFromSignature(sig, loader, endp);
    }
  catch (java::lang::NoClassDefFoundError *ncdfe)
    {
      return NULL;
    }
  catch (java::lang::ClassNotFoundException *cnfe)
    {
      return NULL;
    }

  return klass;
}

JArray<jstring> *
JvConvertArgv (int argc, const char **argv)
{
  if (argc < 0)
    argc = 0;
  jobjectArray ar = JvNewObjectArray(argc, &java::lang::String::class$, NULL);
  jobject *ptr = elements(ar);
  jbyteArray bytes = NULL;
  for (int i = 0;  i < argc;  i++)
    {
      const char *arg = argv[i];
      int len = strlen (arg);
      if (bytes == NULL || bytes->length < len)
	bytes = JvNewByteArray (len);
      jbyte *bytePtr = elements (bytes);
      // We assume jbyte == char.
      memcpy (bytePtr, arg, len);

      // Now convert using the default encoding.
      *ptr++ = new java::lang::String (bytes, 0, len);
    }
  return (JArray<jstring>*) ar;
}

// FIXME: These variables are static so that they will be
// automatically scanned by the Boehm collector.  This is needed
// because with qthreads the collector won't scan the initial stack --
// it will only scan the qthreads stacks.

// Command line arguments.
static JArray<jstring> *arg_vec;

// The primary thread.
static java::lang::Thread *main_thread;

#ifndef DISABLE_GETENV_PROPERTIES

#define c_isspace(c) (memchr (" \t\n\r\v\f", c, 6) != NULL)

static char *
next_property_key (char *s, size_t *length)
{
  size_t l = 0;

  JvAssert (s);

  // Skip over whitespace
  while (c_isspace (*s))
    s++;

  // If we've reached the end, return NULL.  Also return NULL if for
  // some reason we've come across a malformed property string.
  if (*s == 0
      || *s == ':'
      || *s == '=')
    return NULL;

  // Determine the length of the property key.
  while (s[l] != 0
	 && ! c_isspace (s[l])
	 && s[l] != ':'
	 && s[l] != '=')
    {
      if (s[l] == '\\'
	  && s[l+1] != 0)
	l++;
      l++;
    }

  *length = l;

  return s;
}

static char *
next_property_value (char *s, size_t *length)
{
  size_t l = 0;

  JvAssert (s);

  while (c_isspace (*s))
    s++;

  if (*s == ':'
      || *s == '=')
    s++;

  while (c_isspace (*s))
    s++;

  // Determine the length of the property value.
  while (s[l] != 0
	 && ! c_isspace (s[l])
	 && s[l] != ':'
	 && s[l] != '=')
    {
      if (s[l] == '\\'
	  && s[l+1] != 0)
	l += 2;
      else
	l++;
    }

  *length = l;

  return s;
}

static void
process_gcj_properties ()
{
  char *props = getenv("GCJ_PROPERTIES");

  if (NULL == props)
    return;

  // Later on we will write \0s into this string.  It is simplest to
  // just duplicate it here.
  props = strdup (props);

  char *p = props;
  size_t length;
  size_t property_count = 0;

  // Whip through props quickly in order to count the number of
  // property values.
  while (p && (p = next_property_key (p, &length)))
    {
      // Skip to the end of the key
      p += length;

      p = next_property_value (p, &length);
      if (p)
	p += length;
      
      property_count++;
    }

  // Allocate an array of property value/key pairs.
  _Jv_Environment_Properties = 
    (property_pair *) malloc (sizeof(property_pair) 
			      * (property_count + 1));

  // Go through the properties again, initializing _Jv_Properties
  // along the way.
  p = props;
  property_count = 0;
  while (p && (p = next_property_key (p, &length)))
    {
      _Jv_Environment_Properties[property_count].key = p;
      _Jv_Environment_Properties[property_count].key_length = length;

      // Skip to the end of the key
      p += length;

      p = next_property_value (p, &length);
      
      _Jv_Environment_Properties[property_count].value = p;
      _Jv_Environment_Properties[property_count].value_length = length;

      if (p)
	p += length;

      property_count++;
    }
  memset ((void *) &_Jv_Environment_Properties[property_count], 
	  0, sizeof (property_pair));

  // Null terminate the strings.
  for (property_pair *prop = &_Jv_Environment_Properties[0];
       prop->key != NULL;
       prop++)
    {
      prop->key[prop->key_length] = 0;
      prop->value[prop->value_length] = 0;
    }
}
#endif // DISABLE_GETENV_PROPERTIES

namespace gcj
{
  _Jv_Utf8Const *void_signature;
  _Jv_Utf8Const *clinit_name;
  _Jv_Utf8Const *init_name;
  _Jv_Utf8Const *finit_name;
  
  bool runtimeInitialized = false;
  
  // When true, print debugging information about class loading.
  bool verbose_class_flag;
  
  // When true, enable the bytecode verifier and BC-ABI type verification. 
  bool verifyClasses = true;

  // Thread stack size specified by the -Xss runtime argument.
  size_t stack_size = 0;

  // Start time of the VM
  jlong startTime = 0;

  // Arguments passed to the VM
  JArray<jstring>* vmArgs;

  // Currently loaded classes
  jint loadedClasses = 0;

  // Unloaded classes
  jlong unloadedClasses = 0;
}

// We accept all non-standard options accepted by Sun's java command,
// for compatibility with existing application launch scripts.
static jint
parse_x_arg (char* option_string)
{
  if (strlen (option_string) <= 0)
    return -1;

  if (! strcmp (option_string, "int"))
    {
      // FIXME: this should cause the vm to never load shared objects
    }
  else if (! strcmp (option_string, "mixed"))
    {
      // FIXME: allow interpreted and native code
    }
  else if (! strcmp (option_string, "batch"))
    {
      // FIXME: disable background JIT'ing
    }
  else if (! strcmp (option_string, "debug"))
    {
      remoteDebug = true;
    }
#ifdef INTERPRETER
  else if (! strncmp (option_string, "runjdwp:", 8))
    {
      if (strlen (option_string) > 8)
	  jdwpOptions = &option_string[8];
      else
	{
	  fprintf (stderr,
		   "libgcj: argument required for JDWP options");
	  return -1;
	}
    }
#endif // INTERPRETER
  else if (! strncmp (option_string, "bootclasspath:", 14))
    {
      // FIXME: add a parse_bootclasspath_arg function
    }
  else if (! strncmp (option_string, "bootclasspath/a:", 16))
    {
    }
  else if (! strncmp (option_string, "bootclasspath/p:", 16))
    {
    }
  else if (! strcmp (option_string, "check:jni"))
    {
      // FIXME: enable strict JNI checking
    }
  else if (! strcmp (option_string, "future"))
    {
      // FIXME: enable strict class file format checks
    }
  else if (! strcmp (option_string, "noclassgc"))
    {
      // FIXME: disable garbage collection for classes
    }
  else if (! strcmp (option_string, "incgc"))
    {
      // FIXME: incremental garbage collection
    }
  else if (! strncmp (option_string, "loggc:", 6))
    {
      if (option_string[6] == '\0')
        {
          fprintf (stderr,
                   "libgcj: filename argument expected for loggc option\n");
          return -1;
        }
      // FIXME: set gc logging filename
    }
  else if (! strncmp (option_string, "ms", 2))
    {
      // FIXME: ignore this option until PR 20699 is fixed.
      // _Jv_SetInitialHeapSize (option_string + 2);
    }
  else if (! strncmp (option_string, "mx", 2))
    _Jv_SetMaximumHeapSize (option_string + 2);
  else if (! strcmp (option_string, "prof"))
    {
      // FIXME: enable profiling of program running in vm
    }
  else if (! strncmp (option_string, "runhprof:", 9))
    {
      // FIXME: enable specific type of vm profiling.  add a
      // parse_runhprof_arg function
    }
  else if (! strcmp (option_string, "rs"))
    {
      // FIXME: reduced system signal usage.  disable thread dumps,
      // only terminate in response to user-initiated calls,
      // e.g. System.exit()
    }
  else if (! strncmp (option_string, "ss", 2))
    {
      _Jv_SetStackSize (option_string + 2);
    }
  else if (! strcmp (option_string, "X:+UseAltSigs"))
    {
      // FIXME: use signals other than SIGUSR1 and SIGUSR2
    }
  else if (! strcmp (option_string, "share:off"))
    {
      // FIXME: don't share class data
    }
  else if (! strcmp (option_string, "share:auto"))
    {
      // FIXME: share class data where possible
    }
  else if (! strcmp (option_string, "share:on"))
    {
      // FIXME: fail if impossible to share class data
    }
  else
    {
      // Unrecognized.
      return -1;
    }
  return 0;
}

static jint
parse_verbose_args (char* option_string,
                    bool ignore_unrecognized)
{
  size_t len = sizeof ("-verbose") - 1;

  if (strlen (option_string) < len)
    return -1;

  if (option_string[len] == ':'
      && option_string[len + 1] != '\0')
    {
      char* verbose_args = option_string + len + 1;

      do
	{
	  if (! strncmp (verbose_args,
			 "gc", sizeof ("gc") - 1))
            {
              if (verbose_args[sizeof ("gc") - 1] == '\0'
                  || verbose_args[sizeof ("gc") - 1] == ',')
                {
                  // FIXME: we should add functions to boehm-gc that
                  // toggle GC_print_stats, GC_PRINT_ADDRESS_MAP and
                  // GC_print_back_height.
                  verbose_args += sizeof ("gc") - 1;
                }
              else
                {
                verbose_arg_err:
                  fprintf (stderr, "libgcj: unknown verbose option: %s\n",
                           option_string);
                  return -1;
                }
            }
	  else if (! strncmp (verbose_args,
			      "class",
			      sizeof ("class") - 1))
            {
              if (verbose_args[sizeof ("class") - 1] == '\0'
                  || verbose_args[sizeof ("class") - 1] == ',')
                {
                  gcj::verbose_class_flag = true;
                  verbose_args += sizeof ("class") - 1;
                }
              else
                goto verbose_arg_err;
            }
	  else if (! strncmp (verbose_args, "jni",
			      sizeof ("jni") - 1))
            {
              if (verbose_args[sizeof ("jni") - 1] == '\0'
                  || verbose_args[sizeof ("jni") - 1] == ',')
                {
                  // FIXME: enable JNI messages.
                  verbose_args += sizeof ("jni") - 1;
                }
              else
                goto verbose_arg_err;
            }
	  else if (ignore_unrecognized
		   && verbose_args[0] == 'X')
	    {
	      // ignore unrecognized non-standard verbose option
	      while (verbose_args[0] != '\0'
		     && verbose_args[0] != ',')
                verbose_args++;
	    }
          else if (verbose_args[0] == ',')
            {
              verbose_args++;
            }
          else
            goto verbose_arg_err;

          if (verbose_args[0] == ',')
            verbose_args++;
	}
      while (verbose_args[0] != '\0');
    }
  else if (option_string[len] == 'g'
	   && option_string[len + 1] == 'c'
	   && option_string[len + 2] == '\0')
    {
      // FIXME: we should add functions to boehm-gc that
      // toggle GC_print_stats, GC_PRINT_ADDRESS_MAP and
      // GC_print_back_height.
      return 0;
    }
  else if (option_string[len] == '\0')
    {
      gcj::verbose_class_flag = true;
      return 0;
    }
  else
    {
      // unrecognized option beginning with -verbose
      return -1;
    }
  return 0;
}

#ifdef INTERPRETER
// This function loads the agent functions for JVMTI from the library indicated
// by name.  It returns a negative value on failure, the value of which
// indicates where ltdl failed, it also prints an error message.
static jint
load_jvmti_agent (const char *name)
{
#ifdef USE_LTDL
  if (lt_dlinit ())
    {
      fprintf (stderr, 
              "libgcj: Error in ltdl init while loading agent library.\n");
      return -1;
    }
 
  lt_dlhandle lib = lt_dlopenext (name);
  if (!lib)
    {
      fprintf (stderr, 
               "libgcj: Error opening agent library.\n");
      return -2;
    }

  if (lib)
    {
      jvmti_agentonload 
        = (jvmti_agent_onload_func *) lt_dlsym (lib, "Agent_OnLoad");
 
      if (!jvmti_agentonload)
        {
          fprintf (stderr, 
                   "libgcj: Error finding agent function in library %s.\n",
                   name);
          lt_dlclose (lib);
          lib = NULL;
          return -4;
        }
      else
        {
          jvmti_agentonunload
            = (jvmti_agent_onunload_func *) lt_dlsym (lib, "Agent_OnUnload");
	   
          return 0;
        }
    }
  else
    {
      fprintf (stderr, "libgcj: Library %s not found in library path.\n", name);
      return -3;
    }

#endif /* USE_LTDL */

  // If LTDL cannot be used, return an error code indicating this.
  return -99;
}
#endif // INTERPRETER

static jint
parse_init_args (JvVMInitArgs* vm_args)
{
  // if _Jv_Compiler_Properties is non-NULL then it needs to be
  // re-allocated dynamically.
  if (_Jv_Compiler_Properties)
    {
      const char** props = _Jv_Compiler_Properties;
      _Jv_Compiler_Properties = NULL;

      for (int i = 0; props[i]; i++)
	{
	  _Jv_Compiler_Properties = (const char**) _Jv_Realloc
	    (_Jv_Compiler_Properties,
	     (_Jv_Properties_Count + 1) * sizeof (const char*));
	  _Jv_Compiler_Properties[_Jv_Properties_Count++] = props[i];
	}
    }

  if (vm_args == NULL)
    return 0;

  for (int i = 0; i < vm_args->nOptions; ++i)
    {
      char* option_string = vm_args->options[i].optionString;
      
      if (! strcmp (option_string, "vfprintf")
	  || ! strcmp (option_string, "exit")
	  || ! strcmp (option_string, "abort"))
	{
	  // FIXME: we are required to recognize these, but for
	  // now we don't handle them in any way.
	  continue;
	}
      else if (! strncmp (option_string,
			  "-verbose", sizeof ("-verbose") - 1))
	{
	  jint result = parse_verbose_args (option_string,
                                            vm_args->ignoreUnrecognized);
	  if (result < 0)
	    return result;
	}
      else if (! strncmp (option_string, "-D", 2))
	{
	  _Jv_Compiler_Properties = (const char**) _Jv_Realloc
	    (_Jv_Compiler_Properties,
	     (_Jv_Properties_Count + 1) * sizeof (char*));

	  _Jv_Compiler_Properties[_Jv_Properties_Count++] =
	    strdup (option_string + 2);

	  continue;
	}
#ifdef INTERPRETER
      else if (! strncmp (option_string, "-agentlib", sizeof ("-agentlib") - 1))
	{
          char *strPtr;
	                                              
          if (strlen(option_string) > (sizeof ("-agentlib:") - 1))
            strPtr = &option_string[sizeof ("-agentlib:") - 1];
          else
            {
              fprintf (stderr,
                "libgcj: Malformed agentlib argument %s: expected lib name\n",
                option_string);
              return -1;
            }

          // These are optional arguments to pass to the agent library.
          jvmti_agent_opts = strchr (strPtr, '=');
   
          if (! strncmp (strPtr, "jdwp", 4))
            {    	
              // We want to run JDWP here so set the correct variables.
              remoteDebug = true;
              jdwpOptions = ++jvmti_agent_opts;
            }
          else
            {
              jint nameLength;
   
              if (jvmti_agent_opts == NULL)
                nameLength = strlen (strPtr);
              else
                {
                  nameLength = jvmti_agent_opts - strPtr;
                  jvmti_agent_opts++;
                }
               
              char lib_name[nameLength + 3 + 1];
              strcpy (lib_name, "lib");
              strncat (lib_name, strPtr, nameLength);
      
              jint result = load_jvmti_agent (lib_name);
      
              if (result < 0)
	        {
	          return -1;
	        }

	      // Mark JVMTI active
	      JVMTI::enabled = true;
            }
    
          continue;
	}
      else if (! strncmp (option_string, "-agentpath:", 
                          sizeof ("-agentpath:") - 1))
	{
          char *strPtr;
	                                              
          if (strlen(option_string) > 10)
            strPtr = &option_string[10];
          else
            {
              fprintf (stderr,
                "libgcj: Malformed agentlib argument %s: expected lib path\n",
                option_string);
              return -1;
            }
		
          // These are optional arguments to pass to the agent library.
          jvmti_agent_opts = strchr (strPtr, '=');
    
          jint nameLength;
   
          if (jvmti_agent_opts == NULL)
            nameLength = strlen (strPtr);
          else
            {
              nameLength = jvmti_agent_opts - strPtr;
              jvmti_agent_opts++;
            }
    
          char lib_name[nameLength + 3 + 1];
          strcpy (lib_name, "lib");
          strncat (lib_name, strPtr, nameLength);
          jint result = load_jvmti_agent (strPtr);

          if (result < 0)
            {
              return -1;
            }
	
	  // Mark JVMTI active
	  JVMTI::enabled = true;
          continue;
	}
#endif // INTERPRETER
      else
        {
	  int r = -1;
          if (option_string[0] == '_')
	    r = parse_x_arg (option_string + 1);
	  else if (! strncmp (option_string, "-X", 2))
	    r = parse_x_arg (option_string + 2);

	  if (r == -1 && ! vm_args->ignoreUnrecognized)
            {
              fprintf (stderr, "libgcj: unknown option: %s\n", option_string);
              return -1;
            }
	}
    }
  return 0;
}

jint
_Jv_CreateJavaVM (JvVMInitArgs* vm_args)
{
  using namespace gcj;

  if (runtimeInitialized)
    return -1;

  runtimeInitialized = true;
  startTime = _Jv_platform_gettimeofday();

  jint result = parse_init_args (vm_args);
  if (result < 0)
    return -1;

  PROCESS_GCJ_PROPERTIES;

  /* Threads must be initialized before the GC, so that it inherits the
     signal mask.  */
  _Jv_InitThreads ();
  _Jv_InitGC ();
  _Jv_InitializeSyncMutex ();
  
#ifdef INTERPRETER
  _Jv_InitInterpreter ();
#endif  

#ifdef HANDLE_SEGV
  INIT_SEGV;
#endif

#ifdef HANDLE_FPE
  INIT_FPE;
#endif

  /* Initialize Utf8 constants declared in jvm.h. */
  void_signature = _Jv_makeUtf8Const ("()V", 3);
  clinit_name = _Jv_makeUtf8Const ("<clinit>", 8);
  init_name = _Jv_makeUtf8Const ("<init>", 6);
  finit_name = _Jv_makeUtf8Const ("finit$", 6);

  /* Initialize built-in classes to represent primitive TYPEs. */
  _Jv_InitPrimClass (&_Jv_byteClass,    "byte",    'B', 1);
  _Jv_InitPrimClass (&_Jv_shortClass,   "short",   'S', 2);
  _Jv_InitPrimClass (&_Jv_intClass,     "int",     'I', 4);
  _Jv_InitPrimClass (&_Jv_longClass,    "long",    'J', 8);
  _Jv_InitPrimClass (&_Jv_booleanClass, "boolean", 'Z', 1);
  _Jv_InitPrimClass (&_Jv_charClass,    "char",    'C', 2);
  _Jv_InitPrimClass (&_Jv_floatClass,   "float",   'F', 4);
  _Jv_InitPrimClass (&_Jv_doubleClass,  "double",  'D', 8);
  _Jv_InitPrimClass (&_Jv_voidClass,    "void",    'V', 0);

  // We have to initialize this fairly early, to avoid circular class
  // initialization.  In particular we want to start the
  // initialization of ClassLoader before we start the initialization
  // of VMClassLoader.
  _Jv_InitClass (&java::lang::ClassLoader::class$);

  // Set up the system class loader and the bootstrap class loader.
  gnu::gcj::runtime::ExtensionClassLoader::initialize();
  java::lang::VMClassLoader::initialize(JvNewStringLatin1(TOOLEXECLIBDIR));

  _Jv_RegisterBootstrapPackages();

  no_memory = new java::lang::OutOfMemoryError;

#ifdef USE_LTDL
  LTDL_SET_PRELOADED_SYMBOLS ();
#endif

  _Jv_platform_initialize ();

  _Jv_JNI_Init ();

#ifdef INTERPRETER
  _Jv_JVMTI_Init ();
#endif

  _Jv_GCInitializeFinalizers (&::gnu::gcj::runtime::FinalizerThread::finalizerReady);

  // Start the GC finalizer thread.  A VirtualMachineError can be
  // thrown by the runtime if, say, threads aren't available.
  try
    {
      using namespace gnu::gcj::runtime;
      FinalizerThread *ft = new FinalizerThread ();
      ft->start ();
    }
  catch (java::lang::VirtualMachineError *ignore)
    {
    }

  runtimeInitialized = true;

  return 0;
}

void
_Jv_RunMain (JvVMInitArgs *vm_args, jclass klass, const char *name, int argc,
             const char **argv, bool is_jar)
{
#ifndef DISABLE_MAIN_ARGS
  _Jv_SetArgs (argc, argv);
#endif

  java::lang::Runtime *runtime = NULL;

  try
    {
      if (_Jv_CreateJavaVM (vm_args) < 0)
	{
	  fprintf (stderr, "libgcj: couldn't create virtual machine\n");
	  exit (1);
	}
      
      if (vm_args == NULL)
	gcj::vmArgs = JvConvertArgv(0, NULL);
      else
	{
	  const char* vmArgs[vm_args->nOptions];
	  const char** vmPtr = vmArgs;
	  struct _Jv_VMOption* optionPtr = vm_args->options;
	  for (int i = 0; i < vm_args->nOptions; ++i)
	    *vmPtr++ = (*optionPtr++).optionString;
	  gcj::vmArgs = JvConvertArgv(vm_args->nOptions, vmArgs);
	}

      // Get the Runtime here.  We want to initialize it before searching
      // for `main'; that way it will be set up if `main' is a JNI method.
      runtime = java::lang::Runtime::getRuntime ();

#ifdef DISABLE_MAIN_ARGS
      arg_vec = JvConvertArgv (0, 0);
#else      
      arg_vec = JvConvertArgv (argc - 1, argv + 1);
#endif

      using namespace gnu::java::lang;
      if (klass)
	main_thread = new MainThread (klass, arg_vec);
      else
	main_thread = new MainThread (JvNewStringUTF (name),
				      arg_vec, is_jar);
      _Jv_AttachCurrentThread (main_thread);

#ifdef INTERPRETER
      // Start JVMTI if an agent function has been found.
      if (jvmti_agentonload)
        (*jvmti_agentonload) (_Jv_GetJavaVM (), jvmti_agent_opts, NULL);

      // Start JDWP
      if (remoteDebug)
	{
	  using namespace gnu::classpath::jdwp;
	  VMVirtualMachine::initialize ();
	  Jdwp *jdwp = new Jdwp ();
	  jdwp->setDaemon (true);	  
	  jdwp->configure (JvNewStringLatin1 (jdwpOptions));
	  jdwp->start ();

	  // Wait for JDWP to initialize and start
	  jdwp->join ();
	}
      // Send VMInit
      if (JVMTI_REQUESTED_EVENT (VMInit))
	_Jv_JVMTI_PostEvent (JVMTI_EVENT_VM_INIT, main_thread);
#endif // INTERPRETER
    }
  catch (java::lang::Throwable *t)
    {
      java::lang::System::err->println (JvNewStringLatin1 
        ("Exception during runtime initialization"));
      t->printStackTrace();
      if (runtime)
	java::lang::Runtime::exitNoChecksAccessor (1);
      // In case the runtime creation failed.
      ::exit (1);
    }

  _Jv_ThreadRun (main_thread);

#ifdef INTERPRETER
  // Send VMDeath
  if (JVMTI_REQUESTED_EVENT (VMDeath))
    {
      java::lang::Thread *thread = java::lang::Thread::currentThread ();
      JNIEnv *jni_env = _Jv_GetCurrentJNIEnv ();
      _Jv_JVMTI_PostEvent (JVMTI_EVENT_VM_DEATH, thread, jni_env);
    }

  // Run JVMTI AgentOnUnload if it exists and an agent is loaded.
  if (jvmti_agentonunload)
    (*jvmti_agentonunload) (_Jv_GetJavaVM ());
#endif // INTERPRETER

  // If we got here then something went wrong, as MainThread is not
  // supposed to terminate.
  ::exit (1);
}

void
_Jv_RunMain (jclass klass, const char *name, int argc, const char **argv, 
	     bool is_jar)
{
  _Jv_RunMain (NULL, klass, name, argc, argv, is_jar);
}

void
JvRunMain (jclass klass, int argc, const char **argv)
{
  _Jv_RunMain (klass, NULL, argc, argv, false);
}

void
JvRunMainName (const char *name, int argc, const char **argv)
{
  _Jv_RunMain (NULL, name, argc, argv, false);
}



// Parse a string and return a heap size.
static size_t
parse_memory_size (const char *spec)
{
  char *end;
  unsigned long val = strtoul (spec, &end, 10);
  if (*end == 'k' || *end == 'K')
    val *= 1024;
  else if (*end == 'm' || *end == 'M')
    val *= 1048576;
  return (size_t) val;
}

// Set the initial heap size.  This might be ignored by the GC layer.
// This must be called before _Jv_RunMain.
void
_Jv_SetInitialHeapSize (const char *arg)
{
  size_t size = parse_memory_size (arg);
  _Jv_GCSetInitialHeapSize (size);
}

// Set the maximum heap size.  This might be ignored by the GC layer.
// This must be called before _Jv_RunMain.
void
_Jv_SetMaximumHeapSize (const char *arg)
{
  size_t size = parse_memory_size (arg);
  _Jv_GCSetMaximumHeapSize (size);
}

void
_Jv_SetStackSize (const char *arg)
{
  size_t size = parse_memory_size (arg);
  gcj::stack_size = size;
}

void *
_Jv_Malloc (jsize size)
{
  if (__builtin_expect (size == 0, false))
    size = 1;
  void *ptr = malloc ((size_t) size);
  if (__builtin_expect (ptr == NULL, false))
    throw no_memory;
  return ptr;
}

void *
_Jv_Realloc (void *ptr, jsize size)
{
  if (__builtin_expect (size == 0, false))
    size = 1;
  ptr = realloc (ptr, (size_t) size);
  if (__builtin_expect (ptr == NULL, false))
    throw no_memory;
  return ptr;
}

void *
_Jv_MallocUnchecked (jsize size)
{
  if (__builtin_expect (size == 0, false))
    size = 1;
  return malloc ((size_t) size);
}

void
_Jv_Free (void* ptr)
{
  return free (ptr);
}



// In theory, these routines can be #ifdef'd away on machines which
// support divide overflow signals.  However, we never know if some
// code might have been compiled with "-fuse-divide-subroutine", so we
// always include them in libgcj.

jint
_Jv_divI (jint dividend, jint divisor)
{
  if (__builtin_expect (divisor == 0, false))
    {
      java::lang::ArithmeticException *arithexception 
	= new java::lang::ArithmeticException (JvNewStringLatin1 ("/ by zero"));      
      throw arithexception;
    }
  
  if (dividend == (jint) 0x80000000L && divisor == -1)
    return dividend;

  return dividend / divisor;
}

jint
_Jv_remI (jint dividend, jint divisor)
{
  if (__builtin_expect (divisor == 0, false))
    {
      java::lang::ArithmeticException *arithexception 
	= new java::lang::ArithmeticException (JvNewStringLatin1 ("/ by zero"));      
      throw arithexception;
    }
  
  if (dividend == (jint) 0x80000000L && divisor == -1)
    return 0;
  
  return dividend % divisor;
}

jlong
_Jv_divJ (jlong dividend, jlong divisor)
{
  if (__builtin_expect (divisor == 0, false))
    {
      java::lang::ArithmeticException *arithexception 
	= new java::lang::ArithmeticException (JvNewStringLatin1 ("/ by zero"));      
      throw arithexception;
    }

  if (dividend == (jlong) 0x8000000000000000LL && divisor == -1)
    return dividend;

  return dividend / divisor;
}

jlong
_Jv_remJ (jlong dividend, jlong divisor)
{
  if (__builtin_expect (divisor == 0, false))
    {
      java::lang::ArithmeticException *arithexception 
	= new java::lang::ArithmeticException (JvNewStringLatin1 ("/ by zero"));      
      throw arithexception;
    }

  if (dividend == (jlong) 0x8000000000000000LL && divisor == -1)
    return 0;

  return dividend % divisor;
}



// Return true if SELF_KLASS can access a field or method in
// OTHER_KLASS.  The field or method's access flags are specified in
// FLAGS.
jboolean
_Jv_CheckAccess (jclass self_klass, jclass other_klass, jint flags)
{
  using namespace java::lang::reflect;
  return ((self_klass == other_klass)
	  || ((flags & Modifier::PUBLIC) != 0)
	  || (((flags & Modifier::PROTECTED) != 0)
	      && _Jv_IsAssignableFromSlow (self_klass, other_klass))
	  || (((flags & Modifier::PRIVATE) == 0)
	      && _Jv_ClassNameSamePackage (self_klass->name,
					   other_klass->name)));
}

// Prepend GCJ_VERSIONED_LIBDIR to a module search path stored in a C
// char array, if the path is not already prefixed by
// GCJ_VERSIONED_LIBDIR.  Return a newly JvMalloc'd char buffer.  The
// result should be freed using JvFree.
char*
_Jv_PrependVersionedLibdir (char* libpath)
{
  char* retval = 0;

  if (libpath && libpath[0] != '\0')
    {
      if (! strncmp (libpath,
                     GCJ_VERSIONED_LIBDIR,
                     sizeof (GCJ_VERSIONED_LIBDIR) - 1))
        {
          // LD_LIBRARY_PATH is already prefixed with
          // GCJ_VERSIONED_LIBDIR.
          retval = (char*) _Jv_Malloc (strlen (libpath) + 1);
          strcpy (retval, libpath);
        }
      else
        {
          // LD_LIBRARY_PATH is not prefixed with
          // GCJ_VERSIONED_LIBDIR.
	  char path_sep[2];
	  path_sep[0] = (char) _Jv_platform_path_separator;
	  path_sep[1] = '\0';
          jsize total = ((sizeof (GCJ_VERSIONED_LIBDIR) - 1)
			 + 1 /* path separator */ + strlen (libpath) + 1);
          retval = (char*) _Jv_Malloc (total);
          strcpy (retval, GCJ_VERSIONED_LIBDIR);
          strcat (retval, path_sep);
          strcat (retval, libpath);
        }
    }
  else
    {
      // LD_LIBRARY_PATH was not specified or is empty.
      retval = (char*) _Jv_Malloc (sizeof (GCJ_VERSIONED_LIBDIR));
      strcpy (retval, GCJ_VERSIONED_LIBDIR);
    }

  return retval;
}
