mirror of git://gcc.gnu.org/git/gcc.git
				
				
				
			
		
			
				
	
	
		
			324 lines
		
	
	
		
			7.1 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			324 lines
		
	
	
		
			7.1 KiB
		
	
	
	
		
			C++
		
	
	
	
// natRuntime.cc - Implementation of native side of Runtime class.
 | 
						||
 | 
						||
/* 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 <gcj/cni.h>
 | 
						||
#include <jvm.h>
 | 
						||
#include <java-props.h>
 | 
						||
#include <java-stack.h>
 | 
						||
#include <java/lang/Long.h>
 | 
						||
#include <java/lang/Runtime.h>
 | 
						||
#include <java/lang/UnknownError.h>
 | 
						||
#include <java/lang/UnsatisfiedLinkError.h>
 | 
						||
#include <gnu/gcj/runtime/FinalizerThread.h>
 | 
						||
#include <java/io/File.h>
 | 
						||
#include <java/util/TimeZone.h>
 | 
						||
#include <java/lang/StringBuffer.h>
 | 
						||
#include <java/lang/Process.h>
 | 
						||
#include <java/lang/ClassLoader.h>
 | 
						||
 | 
						||
// It is convenient and safe to simply include all of these.
 | 
						||
#include <java/lang/Win32Process.h>
 | 
						||
#include <java/lang/EcosProcess.h>
 | 
						||
#include <java/lang/PosixProcess.h>
 | 
						||
 | 
						||
#include <jni.h>
 | 
						||
 | 
						||
#ifdef HAVE_PWD_H
 | 
						||
#include <pwd.h>
 | 
						||
#endif
 | 
						||
#include <errno.h>
 | 
						||
 | 
						||
#ifdef HAVE_LOCALE_H
 | 
						||
#include <locale.h>
 | 
						||
#endif
 | 
						||
 | 
						||
#ifdef HAVE_LANGINFO_H
 | 
						||
#include <langinfo.h>
 | 
						||
#endif
 | 
						||
 | 
						||
 | 
						||
 | 
						||
#ifdef USE_LTDL
 | 
						||
#include <ltdl.h>
 | 
						||
 | 
						||
/* FIXME: we don't always need this.  The next libtool will let us use
 | 
						||
   AC_LTDL_PREOPEN to see if we do.  */
 | 
						||
extern const lt_dlsymlist lt_preloaded_symbols[1] = { { 0, 0 } };
 | 
						||
 | 
						||
struct lookup_data
 | 
						||
{
 | 
						||
  const char *symname;
 | 
						||
  void *result;
 | 
						||
};
 | 
						||
 | 
						||
static int
 | 
						||
find_symbol (lt_dlhandle handle, lt_ptr data)
 | 
						||
{
 | 
						||
  lookup_data *ld = (lookup_data *) data;
 | 
						||
  ld->result = lt_dlsym (handle, ld->symname);
 | 
						||
  return ld->result != NULL;
 | 
						||
}
 | 
						||
 | 
						||
void *
 | 
						||
_Jv_FindSymbolInExecutable (const char *symname)
 | 
						||
{
 | 
						||
  lookup_data data;
 | 
						||
  data.symname = symname;
 | 
						||
  data.result = NULL;
 | 
						||
  lt_dlforeach (find_symbol, (lt_ptr) &data);
 | 
						||
  return data.result;
 | 
						||
}
 | 
						||
 | 
						||
#else
 | 
						||
 | 
						||
void *
 | 
						||
_Jv_FindSymbolInExecutable (const char *)
 | 
						||
{
 | 
						||
  return NULL;
 | 
						||
}
 | 
						||
 | 
						||
#endif /* USE_LTDL */
 | 
						||
 | 
						||
 | 
						||
 | 
						||
void
 | 
						||
java::lang::Runtime::runFinalizationForExit ()
 | 
						||
{
 | 
						||
  if (finalizeOnExit)
 | 
						||
    _Jv_RunAllFinalizers ();
 | 
						||
}
 | 
						||
 | 
						||
void
 | 
						||
java::lang::Runtime::exitInternal (jint status)
 | 
						||
{
 | 
						||
  // Make status right for Unix.  This is perhaps strange.
 | 
						||
  if (status < 0 || status > 255)
 | 
						||
    status = 255;
 | 
						||
 | 
						||
  ::exit (status);
 | 
						||
}
 | 
						||
 | 
						||
jlong
 | 
						||
java::lang::Runtime::freeMemory (void)
 | 
						||
{
 | 
						||
  return _Jv_GCFreeMemory ();
 | 
						||
}
 | 
						||
 | 
						||
void
 | 
						||
java::lang::Runtime::gc (void)
 | 
						||
{
 | 
						||
  _Jv_RunGC ();
 | 
						||
}
 | 
						||
 | 
						||
#ifdef USE_LTDL
 | 
						||
// List of names for JNI_OnLoad.
 | 
						||
static const char *onload_names[] = _Jv_platform_onload_names;
 | 
						||
#endif
 | 
						||
 | 
						||
void
 | 
						||
java::lang::Runtime::_load (jstring path, jboolean do_search)
 | 
						||
{
 | 
						||
  JvSynchronize sync (this);
 | 
						||
  using namespace java::lang;
 | 
						||
#ifdef USE_LTDL
 | 
						||
  jint len = _Jv_GetStringUTFLength (path);
 | 
						||
  char buf[len + 1 + strlen (_Jv_platform_solib_prefix)
 | 
						||
	   + strlen (_Jv_platform_solib_suffix)];
 | 
						||
  int offset = 0;
 | 
						||
  if (do_search)
 | 
						||
    {
 | 
						||
      strcpy (buf, _Jv_platform_solib_prefix);
 | 
						||
      offset = strlen (_Jv_platform_solib_prefix);
 | 
						||
    }
 | 
						||
  jsize total = JvGetStringUTFRegion (path, 0, path->length(), &buf[offset]);
 | 
						||
  buf[offset + total] = '\0';
 | 
						||
 | 
						||
  char *lib_name = buf;
 | 
						||
 | 
						||
  if (do_search)
 | 
						||
    {
 | 
						||
      ClassLoader *look = _Jv_StackTrace::GetFirstNonSystemClassLoader ();
 | 
						||
 | 
						||
      if (look != NULL)
 | 
						||
	{
 | 
						||
	  // Don't include solib prefix in string passed to
 | 
						||
	  // findLibrary.
 | 
						||
	  jstring name = look->findLibrary(JvNewStringUTF(&buf[offset]));
 | 
						||
	  if (name != NULL)
 | 
						||
	    {
 | 
						||
	      len = _Jv_GetStringUTFLength (name);
 | 
						||
	      lib_name = (char *) _Jv_AllocBytes(len + 1);
 | 
						||
	      total = JvGetStringUTFRegion (name, 0,
 | 
						||
					    name->length(), lib_name);
 | 
						||
	      lib_name[total] = '\0';
 | 
						||
	      // Don't append suffixes any more; we have the full file
 | 
						||
	      // name.
 | 
						||
	      do_search = false;
 | 
						||
	    }
 | 
						||
	}
 | 
						||
    }
 | 
						||
 | 
						||
  lt_dlhandle h;
 | 
						||
  // FIXME: make sure path is absolute.
 | 
						||
  {
 | 
						||
    // Synchronize on java.lang.Class. This is to protect the class chain from
 | 
						||
    // concurrent modification by class registration calls which may be run
 | 
						||
    // during the dlopen().
 | 
						||
    JvSynchronize sync (&java::lang::Class::class$);
 | 
						||
    h = do_search ? lt_dlopenext (lib_name) : lt_dlopen (lib_name);
 | 
						||
  }
 | 
						||
  if (h == NULL)
 | 
						||
    {
 | 
						||
      const char *msg = lt_dlerror ();
 | 
						||
      jstring str = JvNewStringLatin1 (lib_name);
 | 
						||
      str = str->concat (JvNewStringLatin1 (": "));
 | 
						||
      str = str->concat (JvNewStringLatin1 (msg));
 | 
						||
      throw new UnsatisfiedLinkError (str);
 | 
						||
    }
 | 
						||
 | 
						||
  // Search for JNI_OnLoad function.
 | 
						||
  void *onload = NULL;
 | 
						||
  const char **name = onload_names;
 | 
						||
  while (*name != NULL)
 | 
						||
    {
 | 
						||
      onload = lt_dlsym (h, *name);
 | 
						||
      if (onload != NULL)
 | 
						||
	break;
 | 
						||
      ++name;
 | 
						||
    }
 | 
						||
 | 
						||
  if (onload != NULL)
 | 
						||
    {
 | 
						||
      JavaVM *vm = _Jv_GetJavaVM ();
 | 
						||
      if (vm == NULL)
 | 
						||
	{
 | 
						||
	  // FIXME: what?
 | 
						||
	  return;
 | 
						||
	}
 | 
						||
 | 
						||
      // Push a new frame so that JNI_OnLoad will get the right class
 | 
						||
      // loader if it calls FindClass.
 | 
						||
      ::java::lang::ClassLoader *loader
 | 
						||
	  = _Jv_StackTrace::GetFirstNonSystemClassLoader();
 | 
						||
      JNIEnv *env = _Jv_GetJNIEnvNewFrameWithLoader (loader);
 | 
						||
      jint vers = ((jint (JNICALL *) (JavaVM *, void *)) onload) (vm, NULL);
 | 
						||
      _Jv_JNI_PopSystemFrame (env);
 | 
						||
      if (vers != JNI_VERSION_1_1 && vers != JNI_VERSION_1_2
 | 
						||
	  && vers != JNI_VERSION_1_4)
 | 
						||
	{
 | 
						||
	  // FIXME: unload the library.
 | 
						||
	  throw new UnsatisfiedLinkError (JvNewStringLatin1 ("unrecognized version from JNI_OnLoad"));
 | 
						||
	}
 | 
						||
    }
 | 
						||
#else
 | 
						||
  throw new UnknownError
 | 
						||
    (JvNewStringLatin1 (do_search
 | 
						||
			? "Runtime.loadLibrary not implemented"
 | 
						||
			: "Runtime.load not implemented"));
 | 
						||
#endif /* USE_LTDL */
 | 
						||
}
 | 
						||
 | 
						||
jboolean
 | 
						||
java::lang::Runtime::loadLibraryInternal (jstring lib)
 | 
						||
{
 | 
						||
  JvSynchronize sync (this);
 | 
						||
  using namespace java::lang;
 | 
						||
#ifdef USE_LTDL
 | 
						||
  jint len = _Jv_GetStringUTFLength (lib);
 | 
						||
  char buf[len + 1];
 | 
						||
  jsize total = JvGetStringUTFRegion (lib, 0, lib->length(), buf);
 | 
						||
  buf[total] = '\0';
 | 
						||
  // FIXME: make sure path is absolute.
 | 
						||
  lt_dlhandle h = lt_dlopenext (buf);
 | 
						||
  return h != NULL;
 | 
						||
#else
 | 
						||
  return false;
 | 
						||
#endif /* USE_LTDL */
 | 
						||
}
 | 
						||
 | 
						||
void
 | 
						||
java::lang::Runtime::init (void)
 | 
						||
{
 | 
						||
#ifdef USE_LTDL
 | 
						||
  lt_dlinit ();
 | 
						||
  // Set module load path.
 | 
						||
  lt_dlsetsearchpath (_Jv_Module_Load_Path);
 | 
						||
  // Make sure self is opened.
 | 
						||
  lt_dlopen (NULL);
 | 
						||
#endif
 | 
						||
}
 | 
						||
 | 
						||
void
 | 
						||
java::lang::Runtime::runFinalization (void)
 | 
						||
{
 | 
						||
  gnu::gcj::runtime::FinalizerThread::finalizerReady ();
 | 
						||
}
 | 
						||
 | 
						||
jlong
 | 
						||
java::lang::Runtime::totalMemory (void)
 | 
						||
{
 | 
						||
  return _Jv_GCTotalMemory ();
 | 
						||
}
 | 
						||
 | 
						||
jlong
 | 
						||
java::lang::Runtime::maxMemory (void)
 | 
						||
{
 | 
						||
  // We don't have a maximum.  FIXME: we might if we ask the GC for
 | 
						||
  // one.
 | 
						||
  return Long::MAX_VALUE;
 | 
						||
}
 | 
						||
 | 
						||
void
 | 
						||
java::lang::Runtime::traceInstructions (jboolean)
 | 
						||
{
 | 
						||
  // Do nothing.
 | 
						||
}
 | 
						||
 | 
						||
void
 | 
						||
java::lang::Runtime::traceMethodCalls (jboolean)
 | 
						||
{
 | 
						||
  // Do nothing.
 | 
						||
}
 | 
						||
 | 
						||
java::lang::Process *
 | 
						||
java::lang::Runtime::execInternal (jstringArray cmd,
 | 
						||
				   jstringArray env,
 | 
						||
				   java::io::File *dir)
 | 
						||
{
 | 
						||
  return new _Jv_platform_process (cmd, env, dir, false);
 | 
						||
}
 | 
						||
 | 
						||
jint
 | 
						||
java::lang::Runtime::availableProcessors (void)
 | 
						||
{
 | 
						||
  // FIXME: find the real value.
 | 
						||
  return 1;
 | 
						||
}
 | 
						||
 | 
						||
jstring
 | 
						||
java::lang::Runtime::nativeGetLibname (jstring pathname, jstring libname)
 | 
						||
{
 | 
						||
  java::lang::StringBuffer *sb = new java::lang::StringBuffer ();
 | 
						||
  sb->append(pathname);
 | 
						||
  if (pathname->length() > 0)
 | 
						||
    sb->append (_Jv_platform_file_separator);
 | 
						||
 | 
						||
  sb->append (JvNewStringLatin1 (_Jv_platform_solib_prefix));
 | 
						||
  sb->append(libname);
 | 
						||
  sb->append (JvNewStringLatin1 (_Jv_platform_solib_suffix));
 | 
						||
 | 
						||
  return sb->toString();
 | 
						||
}
 |