mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-03-29 16:41:24 +08:00
Makefile.am: New friends for java/lang/Thread.h.
* Makefile.am: New friends for java/lang/Thread.h. * prims.cc (runFirst): Removed. (JvRunMain): Merged into _Jv_RunMain. Now just calls that. (_Jv_RunMain): Now takes either a klass or class name parameter. Create a gnu.gcj.runtime.FirstThread and attach the native thread to that, then run it using _Jv_ThreadRun. Remove special handling of jar files, instead pass is_jar parameter through to FirstThread. * gcj/javaprims.h: Add prototypes for _Jv_ThreadRun and new variant of _Jv_AttachCurrentThread. * gnu/gcj/runtime/FirstThread.java (FirstThread): Now extends Thread. (run): New method. Take care of looking up main class manifest attribute and calling forName if neccessary. Then call call_main. (call_main): New native method. * gnu/gcj/runtime/natFirstThread.cc (call_main): New function, code relocated from prims.cc. Look up and call main method. * java/lang/Thread.java (run_): Removed. * java/lang/natThread.cc (run_): Renamed to... (_Jv_ThreadRun): this. JVMPI notification code moved to ... (_Jv_NotifyThreadStart): here. New function. (countStackFrames, destroy, resume, suspend, stop): Throw UnsupportedOperationExceptions rather than JvFail'ing. (_Jv_AttachCurrentThread): New variant takes a Thread argument. Existing version wraps new variant. From-SVN: r45182
This commit is contained in:
parent
387edc7625
commit
2dc55bc99f
libjava
@ -2,6 +2,31 @@
|
|||||||
|
|
||||||
* name-finder.cc (lookup): Ignore a null dli_fname from dladdr.
|
* name-finder.cc (lookup): Ignore a null dli_fname from dladdr.
|
||||||
|
|
||||||
|
* Makefile.am: New friends for java/lang/Thread.h.
|
||||||
|
* prims.cc (runFirst): Removed.
|
||||||
|
(JvRunMain): Merged into _Jv_RunMain. Now just calls that.
|
||||||
|
(_Jv_RunMain): Now takes either a klass or class name parameter.
|
||||||
|
Create a gnu.gcj.runtime.FirstThread and attach the native thread
|
||||||
|
to that, then run it using _Jv_ThreadRun. Remove special handling of
|
||||||
|
jar files, instead pass is_jar parameter through to FirstThread.
|
||||||
|
* gcj/javaprims.h: Add prototypes for _Jv_ThreadRun and new variant
|
||||||
|
of _Jv_AttachCurrentThread.
|
||||||
|
* gnu/gcj/runtime/FirstThread.java (FirstThread): Now extends Thread.
|
||||||
|
(run): New method. Take care of looking up main class manifest
|
||||||
|
attribute and calling forName if neccessary. Then call call_main.
|
||||||
|
(call_main): New native method.
|
||||||
|
* gnu/gcj/runtime/natFirstThread.cc (call_main): New function, code
|
||||||
|
relocated from prims.cc. Look up and call main method.
|
||||||
|
* java/lang/Thread.java (run_): Removed.
|
||||||
|
* java/lang/natThread.cc (run_): Renamed to...
|
||||||
|
(_Jv_ThreadRun): this. JVMPI notification code moved to ...
|
||||||
|
(_Jv_NotifyThreadStart): here. New function.
|
||||||
|
(countStackFrames, destroy, resume, suspend, stop): Throw
|
||||||
|
UnsupportedOperationExceptions rather than JvFail'ing.
|
||||||
|
(_Jv_AttachCurrentThread): New variant takes a Thread argument.
|
||||||
|
Existing version wraps new variant.
|
||||||
|
|
||||||
|
|
||||||
2001-08-23 Tom Tromey <tromey@redhat.com>
|
2001-08-23 Tom Tromey <tromey@redhat.com>
|
||||||
|
|
||||||
* java/lang/reflect/Field.java (toString): Use
|
* java/lang/reflect/Field.java (toString): Use
|
||||||
|
@ -267,7 +267,7 @@ $(nat_headers) $(x_nat_headers): libgcj.jar
|
|||||||
java/lang/ClassLoader.h: java/lang/ClassLoader.class libgcj.jar
|
java/lang/ClassLoader.h: java/lang/ClassLoader.class libgcj.jar
|
||||||
$(GCJH) -classpath $(top_builddir) \
|
$(GCJH) -classpath $(top_builddir) \
|
||||||
-friend 'jclass _Jv_FindClass (_Jv_Utf8Const *name, java::lang::ClassLoader *loader);' \
|
-friend 'jclass _Jv_FindClass (_Jv_Utf8Const *name, java::lang::ClassLoader *loader);' \
|
||||||
-friend 'void _Jv_RunMain (const char *name, int argc, const char **argv, bool is_jar);' \
|
-friend 'void _Jv_RunMain (jclass klass, const char *name, int argc, const char **argv, bool is_jar);' \
|
||||||
$(basename $<)
|
$(basename $<)
|
||||||
|
|
||||||
## Our internal main program needs to be able to create a FirstThread.
|
## Our internal main program needs to be able to create a FirstThread.
|
||||||
@ -284,6 +284,8 @@ java/lang/Thread.h: java/lang/Thread.class libgcj.jar
|
|||||||
-prepend '#define _JV_INTERRUPTED 2' \
|
-prepend '#define _JV_INTERRUPTED 2' \
|
||||||
-friend '_Jv_JNIEnv * _Jv_GetCurrentJNIEnv ();' \
|
-friend '_Jv_JNIEnv * _Jv_GetCurrentJNIEnv ();' \
|
||||||
-friend 'void _Jv_SetCurrentJNIEnv (_Jv_JNIEnv *env);' \
|
-friend 'void _Jv_SetCurrentJNIEnv (_Jv_JNIEnv *env);' \
|
||||||
|
-friend 'void _Jv_ThreadRun (java::lang::Thread* thread);' \
|
||||||
|
-friend 'jint _Jv_AttachCurrentThread(java::lang::Thread* thread);' \
|
||||||
-friend 'java::lang::Thread* _Jv_AttachCurrentThread(jstring name, java::lang::ThreadGroup* group);' \
|
-friend 'java::lang::Thread* _Jv_AttachCurrentThread(jstring name, java::lang::ThreadGroup* group);' \
|
||||||
-friend 'jint _Jv_DetachCurrentThread ();' \
|
-friend 'jint _Jv_DetachCurrentThread ();' \
|
||||||
$(basename $<)
|
$(basename $<)
|
||||||
@ -1343,6 +1345,7 @@ gnu/gcj/convert/natOutput_EUCJIS.cc \
|
|||||||
gnu/gcj/convert/natOutput_SJIS.cc \
|
gnu/gcj/convert/natOutput_SJIS.cc \
|
||||||
gnu/gcj/io/natSimpleSHSStream.cc \
|
gnu/gcj/io/natSimpleSHSStream.cc \
|
||||||
gnu/gcj/io/shs.cc \
|
gnu/gcj/io/shs.cc \
|
||||||
|
gnu/gcj/runtime/natFirstThread.cc \
|
||||||
java/io/natFile.cc \
|
java/io/natFile.cc \
|
||||||
java/io/natFileDescriptor.cc \
|
java/io/natFileDescriptor.cc \
|
||||||
java/io/natObjectInputStream.cc \
|
java/io/natObjectInputStream.cc \
|
||||||
|
1061
libjava/Makefile.in
1061
libjava/Makefile.in
File diff suppressed because one or more lines are too long
@ -398,6 +398,11 @@ extern "C" jsize _Jv_GetStringUTFLength (jstring);
|
|||||||
extern "C" jsize _Jv_GetStringUTFRegion (jstring, jsize, jsize, char *);
|
extern "C" jsize _Jv_GetStringUTFRegion (jstring, jsize, jsize, char *);
|
||||||
|
|
||||||
extern jint _Jv_CreateJavaVM (void* /*vm_args*/);
|
extern jint _Jv_CreateJavaVM (void* /*vm_args*/);
|
||||||
|
|
||||||
|
void
|
||||||
|
_Jv_ThreadRun (java::lang::Thread* thread);
|
||||||
|
jint
|
||||||
|
_Jv_AttachCurrentThread(java::lang::Thread* thread);
|
||||||
extern "C" java::lang::Thread*
|
extern "C" java::lang::Thread*
|
||||||
_Jv_AttachCurrentThread(jstring name, java::lang::ThreadGroup* group);
|
_Jv_AttachCurrentThread(jstring name, java::lang::ThreadGroup* group);
|
||||||
extern "C" jint _Jv_DetachCurrentThread (void);
|
extern "C" jint _Jv_DetachCurrentThread (void);
|
||||||
|
@ -136,5 +136,5 @@ main (int argc, const char **argv)
|
|||||||
exit (1);
|
exit (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
_Jv_RunMain (argv[i], argc - i, argv + i, jar_mode);
|
_Jv_RunMain (NULL, argv[i], argc - i, argv + i, jar_mode);
|
||||||
}
|
}
|
||||||
|
@ -17,11 +17,44 @@ import java.util.jar.*;
|
|||||||
* @date August 24, 1998
|
* @date August 24, 1998
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// This is entirely internal to our implementation.
|
final class FirstThread extends Thread
|
||||||
|
|
||||||
final class FirstThread
|
|
||||||
{
|
{
|
||||||
public static String getMain (String name)
|
public FirstThread (Class k, String[] args)
|
||||||
|
{
|
||||||
|
super (null, null, "main");
|
||||||
|
klass = k;
|
||||||
|
this.args = args;
|
||||||
|
}
|
||||||
|
|
||||||
|
public FirstThread (String class_name, String[] args, boolean is_jar)
|
||||||
|
{
|
||||||
|
super (null, null, "main");
|
||||||
|
klass_name = class_name;
|
||||||
|
this.args = args;
|
||||||
|
this.is_jar = is_jar;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void run()
|
||||||
|
{
|
||||||
|
if (is_jar)
|
||||||
|
klass_name = getMain(klass_name);
|
||||||
|
|
||||||
|
if (klass == null)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
klass = Class.forName(klass_name);
|
||||||
|
}
|
||||||
|
catch (ClassNotFoundException x)
|
||||||
|
{
|
||||||
|
throw new NoClassDefFoundError(klass_name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
call_main();
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getMain (String name)
|
||||||
{
|
{
|
||||||
String mainName = null;
|
String mainName = null;
|
||||||
try {
|
try {
|
||||||
@ -37,15 +70,21 @@ final class FirstThread
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (mainName == null)
|
if (mainName == null)
|
||||||
System.err.println ("Failed to load Main-Class manifest attribute from\n"
|
{
|
||||||
+ name);
|
System.err.println ("Failed to load Main-Class manifest attribute from\n"
|
||||||
|
+ name);
|
||||||
|
System.exit(1);
|
||||||
|
}
|
||||||
return mainName;
|
return mainName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private native void call_main ();
|
||||||
|
|
||||||
// Private data.
|
// Private data.
|
||||||
private Class klass;
|
private Class klass;
|
||||||
private String klass_name;
|
private String klass_name;
|
||||||
private Object args;
|
private Object args;
|
||||||
|
private boolean is_jar;
|
||||||
|
|
||||||
// If the user links statically then we need to ensure that these
|
// If the user links statically then we need to ensure that these
|
||||||
// classes are linked in. Otherwise bootstrapping fails. These
|
// classes are linked in. Otherwise bootstrapping fails. These
|
||||||
|
47
libjava/gnu/gcj/runtime/natFirstThread.cc
Normal file
47
libjava/gnu/gcj/runtime/natFirstThread.cc
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
// natFirstThread.cc - Implementation of FirstThread native methods.
|
||||||
|
|
||||||
|
/* Copyright (C) 1998, 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. */
|
||||||
|
|
||||||
|
#include <config.h>
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include <gcj/cni.h>
|
||||||
|
#include <jvm.h>
|
||||||
|
|
||||||
|
#include <gnu/gcj/runtime/FirstThread.h>
|
||||||
|
|
||||||
|
typedef void main_func (jobject);
|
||||||
|
|
||||||
|
void
|
||||||
|
gnu::gcj::runtime::FirstThread::call_main (void)
|
||||||
|
{
|
||||||
|
Utf8Const* main_signature = _Jv_makeUtf8Const ("([Ljava.lang.String;)V", 22);
|
||||||
|
Utf8Const* main_name = _Jv_makeUtf8Const ("main", 4);
|
||||||
|
|
||||||
|
_Jv_Method *meth = _Jv_GetMethodLocal (klass, main_name, main_signature);
|
||||||
|
|
||||||
|
// Some checks from Java Spec section 12.1.4.
|
||||||
|
const char *msg = NULL;
|
||||||
|
if (meth == NULL)
|
||||||
|
msg = "no suitable method `main' in class";
|
||||||
|
else if (! java::lang::reflect::Modifier::isStatic(meth->accflags))
|
||||||
|
msg = "`main' must be static";
|
||||||
|
else if (! java::lang::reflect::Modifier::isPublic(meth->accflags))
|
||||||
|
msg = "`main' must be public";
|
||||||
|
if (msg != NULL)
|
||||||
|
{
|
||||||
|
fprintf (stderr, "%s\n", msg);
|
||||||
|
::exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
main_func *real_main = (main_func *) meth->ncode;
|
||||||
|
(*real_main) (args);
|
||||||
|
}
|
@ -166,7 +166,8 @@ void _Jv_SetInitialHeapSize (const char *arg);
|
|||||||
void _Jv_SetMaximumHeapSize (const char *arg);
|
void _Jv_SetMaximumHeapSize (const char *arg);
|
||||||
|
|
||||||
extern "C" void JvRunMain (jclass klass, int argc, const char **argv);
|
extern "C" void JvRunMain (jclass klass, int argc, const char **argv);
|
||||||
void _Jv_RunMain (const char* name, int argc, const char **argv, bool is_jar);
|
void _Jv_RunMain (jclass klass, const char *name, int argc, const char **argv,
|
||||||
|
bool is_jar);
|
||||||
|
|
||||||
// This function is used to determine the hash code of an object.
|
// This function is used to determine the hash code of an object.
|
||||||
inline jint
|
inline jint
|
||||||
@ -276,7 +277,7 @@ _Jv_JNIEnv *_Jv_GetCurrentJNIEnv ();
|
|||||||
void _Jv_SetCurrentJNIEnv (_Jv_JNIEnv *);
|
void _Jv_SetCurrentJNIEnv (_Jv_JNIEnv *);
|
||||||
|
|
||||||
struct _Jv_JavaVM;
|
struct _Jv_JavaVM;
|
||||||
_Jv_JavaVM *_Jv_GetJavaVM ();
|
_Jv_JavaVM *_Jv_GetJavaVM ();
|
||||||
|
|
||||||
#ifdef ENABLE_JVMPI
|
#ifdef ENABLE_JVMPI
|
||||||
#include "jvmpi.h"
|
#include "jvmpi.h"
|
||||||
|
@ -109,8 +109,6 @@ public class Thread implements Runnable
|
|||||||
|
|
||||||
public final native void resume ();
|
public final native void resume ();
|
||||||
|
|
||||||
// This method exists only to avoid a warning from the C++ compiler.
|
|
||||||
private static final native void run_ (Object obj);
|
|
||||||
private final native void finish_ ();
|
private final native void finish_ ();
|
||||||
|
|
||||||
// Check the thread's interrupted status. If clear_flag is true, the
|
// Check the thread's interrupted status. If clear_flag is true, the
|
||||||
|
@ -87,7 +87,8 @@ jint
|
|||||||
java::lang::Thread::countStackFrames (void)
|
java::lang::Thread::countStackFrames (void)
|
||||||
{
|
{
|
||||||
// NOTE: This is deprecated in JDK 1.2.
|
// NOTE: This is deprecated in JDK 1.2.
|
||||||
JvFail ("java::lang::Thread::countStackFrames unimplemented");
|
throw new UnsupportedOperationException
|
||||||
|
(JvNewStringLatin1 ("Thread.countStackFrames unimplemented"));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -102,7 +103,8 @@ java::lang::Thread::destroy (void)
|
|||||||
{
|
{
|
||||||
// NOTE: This is marked as unimplemented in the JDK 1.2
|
// NOTE: This is marked as unimplemented in the JDK 1.2
|
||||||
// documentation.
|
// documentation.
|
||||||
JvFail ("java::lang::Thread::destroy unimplemented");
|
throw new UnsupportedOperationException
|
||||||
|
(JvNewStringLatin1 ("Thread.destroy unimplemented"));
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -142,7 +144,8 @@ void
|
|||||||
java::lang::Thread::resume (void)
|
java::lang::Thread::resume (void)
|
||||||
{
|
{
|
||||||
checkAccess ();
|
checkAccess ();
|
||||||
JvFail ("java::lang::Thread::resume unimplemented");
|
throw new UnsupportedOperationException
|
||||||
|
(JvNewStringLatin1 ("Thread.resume unimplemented"));
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -213,12 +216,11 @@ java::lang::Thread::finish_ ()
|
|||||||
_Jv_MutexUnlock (&nt->join_mutex);
|
_Jv_MutexUnlock (&nt->join_mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
// Run once at thread startup, either when thread is attached or when
|
||||||
java::lang::Thread::run_ (jobject obj)
|
// _Jv_ThreadRun is called.
|
||||||
|
static void
|
||||||
|
_Jv_NotifyThreadStart (java::lang::Thread* thread)
|
||||||
{
|
{
|
||||||
java::lang::Thread *thread = (java::lang::Thread *) obj;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
#ifdef ENABLE_JVMPI
|
#ifdef ENABLE_JVMPI
|
||||||
if (_Jv_JVMPI_Notify_THREAD_START)
|
if (_Jv_JVMPI_Notify_THREAD_START)
|
||||||
{
|
{
|
||||||
@ -272,7 +274,14 @@ java::lang::Thread::run_ (jobject obj)
|
|||||||
_Jv_EnableGC ();
|
_Jv_EnableGC ();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
_Jv_ThreadRun (java::lang::Thread* thread)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
_Jv_NotifyThreadStart (thread);
|
||||||
thread->run ();
|
thread->run ();
|
||||||
}
|
}
|
||||||
catch (java::lang::Throwable *t)
|
catch (java::lang::Throwable *t)
|
||||||
@ -304,14 +313,14 @@ java::lang::Thread::start (void)
|
|||||||
alive_flag = true;
|
alive_flag = true;
|
||||||
startable_flag = false;
|
startable_flag = false;
|
||||||
natThread *nt = (natThread *) data;
|
natThread *nt = (natThread *) data;
|
||||||
_Jv_ThreadStart (this, nt->thread, (_Jv_ThreadStartFunc *) &run_);
|
_Jv_ThreadStart (this, nt->thread, (_Jv_ThreadStartFunc *) &_Jv_ThreadRun);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
java::lang::Thread::stop (java::lang::Throwable *)
|
java::lang::Thread::stop (java::lang::Throwable *)
|
||||||
{
|
{
|
||||||
throw new UnsupportedOperationException
|
throw new UnsupportedOperationException
|
||||||
(JvNewStringLatin1 ("java::lang::Thread::stop unimplemented"));
|
(JvNewStringLatin1 ("Thread.stop unimplemented"));
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -319,7 +328,7 @@ java::lang::Thread::suspend (void)
|
|||||||
{
|
{
|
||||||
checkAccess ();
|
checkAccess ();
|
||||||
throw new UnsupportedOperationException
|
throw new UnsupportedOperationException
|
||||||
(JvNewStringLatin1 ("java::lang::Thread::suspend unimplemented"));
|
(JvNewStringLatin1 ("Thread.suspend unimplemented"));
|
||||||
}
|
}
|
||||||
|
|
||||||
static int nextThreadNumber = 0;
|
static int nextThreadNumber = 0;
|
||||||
@ -373,6 +382,20 @@ _Jv_SetCurrentJNIEnv (JNIEnv *env)
|
|||||||
((natThread *) t->data)->jni_env = env;
|
((natThread *) t->data)->jni_env = env;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Attach the current native thread to an existing (but unstarted) Thread
|
||||||
|
// object. Returns -1 on failure, 0 upon success.
|
||||||
|
jint
|
||||||
|
_Jv_AttachCurrentThread(java::lang::Thread* thread)
|
||||||
|
{
|
||||||
|
if (thread == NULL || thread->startable_flag == false)
|
||||||
|
return -1;
|
||||||
|
thread->startable_flag = false;
|
||||||
|
thread->alive_flag = true;
|
||||||
|
natThread *nt = (natThread *) thread->data;
|
||||||
|
_Jv_ThreadRegister (nt->thread);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
java::lang::Thread*
|
java::lang::Thread*
|
||||||
_Jv_AttachCurrentThread(jstring name, java::lang::ThreadGroup* group)
|
_Jv_AttachCurrentThread(jstring name, java::lang::ThreadGroup* group)
|
||||||
{
|
{
|
||||||
@ -382,10 +405,8 @@ _Jv_AttachCurrentThread(jstring name, java::lang::ThreadGroup* group)
|
|||||||
if (name == NULL)
|
if (name == NULL)
|
||||||
name = java::lang::Thread::gen_name ();
|
name = java::lang::Thread::gen_name ();
|
||||||
thread = new java::lang::Thread (NULL, group, NULL, name);
|
thread = new java::lang::Thread (NULL, group, NULL, name);
|
||||||
thread->startable_flag = false;
|
_Jv_AttachCurrentThread (thread);
|
||||||
thread->alive_flag = true;
|
_Jv_NotifyThreadStart (thread);
|
||||||
natThread *nt = (natThread *) thread->data;
|
|
||||||
_Jv_ThreadRegister (nt->thread);
|
|
||||||
return thread;
|
return thread;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
184
libjava/prims.cc
184
libjava/prims.cc
@ -90,14 +90,12 @@ property_pair *_Jv_Environment_Properties;
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// The name of this executable.
|
// The name of this executable.
|
||||||
static char * _Jv_execName;
|
static char *_Jv_execName;
|
||||||
|
|
||||||
// Stash the argv pointer to benefit native libraries that need it.
|
// Stash the argv pointer to benefit native libraries that need it.
|
||||||
const char **_Jv_argv;
|
const char **_Jv_argv;
|
||||||
int _Jv_argc;
|
int _Jv_argc;
|
||||||
|
|
||||||
typedef void main_func (jobject);
|
|
||||||
|
|
||||||
#ifdef ENABLE_JVMPI
|
#ifdef ENABLE_JVMPI
|
||||||
// Pointer to JVMPI notification functions.
|
// Pointer to JVMPI notification functions.
|
||||||
void (*_Jv_JVMPI_Notify_OBJECT_ALLOC) (JVMPI_Event *event);
|
void (*_Jv_JVMPI_Notify_OBJECT_ALLOC) (JVMPI_Event *event);
|
||||||
@ -643,7 +641,7 @@ JvConvertArgv (int argc, const char **argv)
|
|||||||
// it will only scan the qthreads stacks.
|
// it will only scan the qthreads stacks.
|
||||||
|
|
||||||
// Command line arguments.
|
// Command line arguments.
|
||||||
static jobject arg_vec;
|
static JArray<jstring> *arg_vec;
|
||||||
|
|
||||||
// The primary thread.
|
// The primary thread.
|
||||||
static java::lang::Thread *main_thread;
|
static java::lang::Thread *main_thread;
|
||||||
@ -690,7 +688,6 @@ win32_exception_handler (LPEXCEPTION_POINTERS e)
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#ifndef DISABLE_GETENV_PROPERTIES
|
#ifndef DISABLE_GETENV_PROPERTIES
|
||||||
|
|
||||||
static char *
|
static char *
|
||||||
@ -885,93 +882,15 @@ _Jv_CreateJavaVM (void* /*vm_args*/)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
runFirst (::java::lang::Class *klass, ::java::lang::Object *args)
|
|
||||||
{
|
|
||||||
Utf8Const* main_signature = _Jv_makeUtf8Const ("([Ljava.lang.String;)V", 22);
|
|
||||||
Utf8Const* main_name = _Jv_makeUtf8Const ("main", 4);
|
|
||||||
|
|
||||||
_Jv_Method *meth = _Jv_GetMethodLocal (klass, main_name, main_signature);
|
|
||||||
|
|
||||||
// Some checks from Java Spec section 12.1.4.
|
|
||||||
const char *msg = NULL;
|
|
||||||
if (meth == NULL)
|
|
||||||
msg = "no suitable method `main' in class";
|
|
||||||
else if (! java::lang::reflect::Modifier::isStatic(meth->accflags))
|
|
||||||
msg = "`main' must be static";
|
|
||||||
else if (! java::lang::reflect::Modifier::isPublic(meth->accflags))
|
|
||||||
msg = "`main' must be public";
|
|
||||||
if (msg != NULL)
|
|
||||||
{
|
|
||||||
fprintf (stderr, "%s\n", msg);
|
|
||||||
::exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef WITH_JVMPI
|
|
||||||
if (_Jv_JVMPI_Notify_THREAD_START)
|
|
||||||
{
|
|
||||||
JVMPI_Event event;
|
|
||||||
|
|
||||||
jstring thread_name = getName ();
|
|
||||||
jstring group_name = NULL, parent_name = NULL;
|
|
||||||
java::lang::ThreadGroup *group = getThreadGroup ();
|
|
||||||
|
|
||||||
if (group)
|
|
||||||
{
|
|
||||||
group_name = group->getName ();
|
|
||||||
group = group->getParent ();
|
|
||||||
|
|
||||||
if (group)
|
|
||||||
parent_name = group->getName ();
|
|
||||||
}
|
|
||||||
|
|
||||||
int thread_len = thread_name ? JvGetStringUTFLength (thread_name) : 0;
|
|
||||||
int group_len = group_name ? JvGetStringUTFLength (group_name) : 0;
|
|
||||||
int parent_len = parent_name ? JvGetStringUTFLength (parent_name) : 0;
|
|
||||||
|
|
||||||
char thread_chars[thread_len + 1];
|
|
||||||
char group_chars[group_len + 1];
|
|
||||||
char parent_chars[parent_len + 1];
|
|
||||||
|
|
||||||
if (thread_name)
|
|
||||||
JvGetStringUTFRegion (thread_name, 0,
|
|
||||||
thread_name->length(), thread_chars);
|
|
||||||
if (group_name)
|
|
||||||
JvGetStringUTFRegion (group_name, 0,
|
|
||||||
group_name->length(), group_chars);
|
|
||||||
if (parent_name)
|
|
||||||
JvGetStringUTFRegion (parent_name, 0,
|
|
||||||
parent_name->length(), parent_chars);
|
|
||||||
|
|
||||||
thread_chars[thread_len] = '\0';
|
|
||||||
group_chars[group_len] = '\0';
|
|
||||||
parent_chars[parent_len] = '\0';
|
|
||||||
|
|
||||||
event.event_type = JVMPI_EVENT_THREAD_START;
|
|
||||||
event.env_id = NULL;
|
|
||||||
event.u.thread_start.thread_name = thread_chars;
|
|
||||||
event.u.thread_start.group_name = group_chars;
|
|
||||||
event.u.thread_start.parent_name = parent_chars;
|
|
||||||
event.u.thread_start.thread_id = (jobjectID) this;
|
|
||||||
event.u.thread_start.thread_env_id = _Jv_GetCurrentJNIEnv ();
|
|
||||||
|
|
||||||
_Jv_DisableGC ();
|
|
||||||
(*_Jv_JVMPI_Notify_THREAD_START) (&event);
|
|
||||||
_Jv_EnableGC ();
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
main_func *real_main = (main_func *) meth->ncode;
|
|
||||||
(*real_main) (args);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
JvRunMain (jclass klass, int argc, const char **argv)
|
_Jv_RunMain (jclass klass, const char *name, int argc, const char **argv,
|
||||||
|
bool is_jar)
|
||||||
{
|
{
|
||||||
_Jv_argv = argv;
|
_Jv_argv = argv;
|
||||||
_Jv_argc = argc;
|
_Jv_argc = argc;
|
||||||
|
|
||||||
_Jv_CreateJavaVM (NULL);
|
java::lang::Runtime *runtime = NULL;
|
||||||
|
|
||||||
#ifdef HAVE_PROC_SELF_EXE
|
#ifdef HAVE_PROC_SELF_EXE
|
||||||
char exec_name[20];
|
char exec_name[20];
|
||||||
sprintf (exec_name, "/proc/%d/exe", getpid ());
|
sprintf (exec_name, "/proc/%d/exe", getpid ());
|
||||||
@ -980,68 +899,51 @@ JvRunMain (jclass klass, int argc, const char **argv)
|
|||||||
_Jv_ThisExecutable (argv[0]);
|
_Jv_ThisExecutable (argv[0]);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Get the Runtime here. We want to initialize it before searching
|
try
|
||||||
// for `main'; that way it will be set up if `main' is a JNI method.
|
{
|
||||||
java::lang::Runtime *rtime = java::lang::Runtime::getRuntime ();
|
_Jv_CreateJavaVM (NULL);
|
||||||
|
|
||||||
main_thread = _Jv_AttachCurrentThread (JvNewStringLatin1 ("main"), NULL);
|
// Get the Runtime here. We want to initialize it before searching
|
||||||
arg_vec = JvConvertArgv (argc - 1, argv + 1);
|
// for `main'; that way it will be set up if `main' is a JNI method.
|
||||||
runFirst (klass, arg_vec);
|
runtime = java::lang::Runtime::getRuntime ();
|
||||||
|
|
||||||
|
arg_vec = JvConvertArgv (argc - 1, argv + 1);
|
||||||
|
|
||||||
|
if (klass)
|
||||||
|
main_thread = new gnu::gcj::runtime::FirstThread (klass, arg_vec);
|
||||||
|
else
|
||||||
|
main_thread = new gnu::gcj::runtime::FirstThread
|
||||||
|
(JvNewStringLatin1 (name), arg_vec, is_jar);
|
||||||
|
|
||||||
|
if (is_jar)
|
||||||
|
{
|
||||||
|
// We need a new ClassLoader because the classpath must be the
|
||||||
|
// jar file only. The easiest way to do this is to lose our
|
||||||
|
// reference to the previous classloader.
|
||||||
|
_Jv_Jar_Class_Path = strdup (name);
|
||||||
|
java::lang::ClassLoader::system = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (java::lang::Throwable *t)
|
||||||
|
{
|
||||||
|
java::lang::System::err->println (JvNewStringLatin1
|
||||||
|
("Exception during runtime initialization"));
|
||||||
|
t->printStackTrace();
|
||||||
|
runtime->exit (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
_Jv_AttachCurrentThread (main_thread);
|
||||||
|
_Jv_ThreadRun (main_thread);
|
||||||
_Jv_ThreadWait ();
|
_Jv_ThreadWait ();
|
||||||
|
|
||||||
int status = (int) java::lang::ThreadGroup::had_uncaught_exception;
|
int status = (int) java::lang::ThreadGroup::had_uncaught_exception;
|
||||||
|
runtime->exit (status);
|
||||||
rtime->_exit (status);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
_Jv_RunMain (const char *name, int argc, const char **argv, bool is_jar)
|
JvRunMain (jclass klass, int argc, const char **argv)
|
||||||
{
|
{
|
||||||
jstring class_name;
|
_Jv_RunMain (klass, NULL, argc, argv, false);
|
||||||
|
|
||||||
_Jv_CreateJavaVM (NULL);
|
|
||||||
|
|
||||||
#ifdef HAVE_PROC_SELF_EXE
|
|
||||||
char exec_name[20];
|
|
||||||
sprintf (exec_name, "/proc/%d/exe", getpid ());
|
|
||||||
_Jv_ThisExecutable (exec_name);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// 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.
|
|
||||||
java::lang::Runtime *rtime = java::lang::Runtime::getRuntime ();
|
|
||||||
|
|
||||||
main_thread = _Jv_AttachCurrentThread (JvNewStringLatin1 ("main"), NULL);
|
|
||||||
|
|
||||||
if (is_jar)
|
|
||||||
{
|
|
||||||
// name specifies a jar file. We must now extract the
|
|
||||||
// Main-Class attribute from the jar's manifest file.
|
|
||||||
// This is done by gnu.gcj.runtime.FirstThread.getMain.
|
|
||||||
_Jv_Jar_Class_Path = strdup (name);
|
|
||||||
jstring jar_name = JvNewStringLatin1 (name);
|
|
||||||
// FirstThread.getMain extracts the main class name.
|
|
||||||
class_name = gnu::gcj::runtime::FirstThread::getMain (jar_name);
|
|
||||||
|
|
||||||
// We need a new ClassLoader because the classpath must be the
|
|
||||||
// jar file only. The easiest way to do this is to lose our
|
|
||||||
// reference to the previous classloader.
|
|
||||||
java::lang::ClassLoader::system = NULL;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
class_name = JvNewStringLatin1 (name);
|
|
||||||
|
|
||||||
arg_vec = JvConvertArgv (argc - 1, argv + 1);
|
|
||||||
|
|
||||||
if (class_name)
|
|
||||||
{
|
|
||||||
runFirst(java::lang::Class::forName (class_name), arg_vec);
|
|
||||||
_Jv_ThreadWait ();
|
|
||||||
}
|
|
||||||
|
|
||||||
int status = (int) java::lang::ThreadGroup::had_uncaught_exception;
|
|
||||||
|
|
||||||
rtime->exit (status);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user