Implement invocation interface; don't create new thread for main.
From-SVN: r42428
This commit is contained in:
parent
b4fbaca7cb
commit
c93d7fae7b
22 changed files with 461 additions and 1945 deletions
|
@ -1,29 +0,0 @@
|
|||
// NativeThread.java - Wrapper for attached user threads.
|
||||
|
||||
/* Copyright (C) 1998, 1999, 2000 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. */
|
||||
|
||||
package gnu.gcj.jni;
|
||||
|
||||
/**
|
||||
* @author Tom Tromey <tromey@cygnus.com>
|
||||
* @date February 9, 2000
|
||||
*/
|
||||
|
||||
public class NativeThread extends Thread
|
||||
{
|
||||
public NativeThread (ThreadGroup g, String name)
|
||||
{
|
||||
super (g, null, name);
|
||||
init ();
|
||||
}
|
||||
|
||||
// Call this to mark the thread as finished.
|
||||
public native void finish ();
|
||||
public native void init ();
|
||||
}
|
|
@ -1,30 +0,0 @@
|
|||
// natNativeThread.cc - Native side of attached threads.
|
||||
|
||||
/* Copyright (C) 1998, 1999, 2000 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. */
|
||||
|
||||
// Written by Tom Tromey <tromey@cygnus.com>
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <gcj/cni.h>
|
||||
#include <jvm.h>
|
||||
#include <gnu/gcj/jni/NativeThread.h>
|
||||
#include <java/lang/Thread.h>
|
||||
|
||||
void
|
||||
gnu::gcj::jni::NativeThread::finish ()
|
||||
{
|
||||
finish_ ();
|
||||
}
|
||||
|
||||
void
|
||||
gnu::gcj::jni::NativeThread::init ()
|
||||
{
|
||||
alive_flag = true; // alive_flag is private in java.lang.Thread
|
||||
}
|
|
@ -19,59 +19,29 @@ import java.util.jar.*;
|
|||
|
||||
// This is entirely internal to our implementation.
|
||||
|
||||
final class FirstThread extends Thread
|
||||
final class FirstThread
|
||||
{
|
||||
public native void run ();
|
||||
|
||||
public FirstThread (Class k, Object o)
|
||||
{
|
||||
super (null, null, "main");
|
||||
klass = k;
|
||||
klass_name = null;
|
||||
args = o;
|
||||
}
|
||||
|
||||
public FirstThread (String class_name, Object o)
|
||||
{
|
||||
super (null, null, "main");
|
||||
klass = null;
|
||||
klass_name = class_name;
|
||||
args = o;
|
||||
}
|
||||
|
||||
private static void die (String s)
|
||||
{
|
||||
System.err.println(s);
|
||||
System.exit(1);
|
||||
}
|
||||
|
||||
public static void main (String[] args)
|
||||
public static String getMain (String name)
|
||||
{
|
||||
String mainName = null;
|
||||
try {
|
||||
|
||||
JarFile j = new JarFile (args[0]);
|
||||
JarFile j = new JarFile (name);
|
||||
|
||||
Attributes a = j.getManifest().getMainAttributes();
|
||||
|
||||
jarMainClassName = a.getValue(Attributes.Name.MAIN_CLASS);
|
||||
mainName = a.getValue(Attributes.Name.MAIN_CLASS);
|
||||
|
||||
if (jarMainClassName != null)
|
||||
{
|
||||
jarMainClassName = jarMainClassName.replace('/','.');
|
||||
return;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
// empty
|
||||
}
|
||||
|
||||
System.err.println ("Failed to load Main-Class manifest attribute from\n"
|
||||
+ args[0]);
|
||||
if (mainName == null)
|
||||
System.err.println ("Failed to load Main-Class manifest attribute from\n"
|
||||
+ name);
|
||||
return mainName;
|
||||
}
|
||||
|
||||
// If interpreter is invoked with -jar, the main class name is recorded
|
||||
// here.
|
||||
public static String jarMainClassName;
|
||||
|
||||
// Private data.
|
||||
private Class klass;
|
||||
private String klass_name;
|
||||
|
|
|
@ -1,147 +0,0 @@
|
|||
// natFirstThread.cc - Implementation of FirstThread native methods.
|
||||
|
||||
/* Copyright (C) 1998, 1999, 2000 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 <stdlib.h>
|
||||
|
||||
#include <gcj/cni.h>
|
||||
#include <jvm.h>
|
||||
#include <jni.h>
|
||||
|
||||
#include <gnu/gcj/runtime/FirstThread.h>
|
||||
#include <java/lang/Class.h>
|
||||
#include <java/lang/String.h>
|
||||
#include <java/lang/System.h>
|
||||
#include <java/lang/reflect/Modifier.h>
|
||||
#include <java/io/PrintStream.h>
|
||||
|
||||
#ifdef ENABLE_JVMPI
|
||||
#include <jvmpi.h>
|
||||
#include <java/lang/ThreadGroup.h>
|
||||
#include <java/lang/UnsatisfiedLinkError.h>
|
||||
#endif
|
||||
|
||||
#define DIE(Message) die (JvNewStringLatin1 (Message))
|
||||
|
||||
typedef void main_func (jobject);
|
||||
|
||||
#ifdef WITH_JVMPI
|
||||
extern void (*_Jv_JVMPI_Notify_THREAD_START) (JVMPI_Event *event);
|
||||
#endif
|
||||
|
||||
/* This will be non-NULL if the user has preloaded a JNI library, or
|
||||
linked one into the executable. */
|
||||
extern "C"
|
||||
{
|
||||
#pragma weak JNI_OnLoad
|
||||
extern jint JNI_OnLoad (JavaVM *, void *) __attribute__((weak));
|
||||
}
|
||||
|
||||
void
|
||||
gnu::gcj::runtime::FirstThread::run (void)
|
||||
{
|
||||
|
||||
Utf8Const* main_signature = _Jv_makeUtf8Const ("([Ljava.lang.String;)V", 22);
|
||||
Utf8Const* main_name = _Jv_makeUtf8Const ("main", 4);
|
||||
|
||||
/* Some systems let you preload shared libraries before running a
|
||||
program. Under Linux, this is done by setting the LD_PRELOAD
|
||||
environment variable. We take advatage of this here to allow for
|
||||
dynamically loading a JNI library into a fully linked executable. */
|
||||
|
||||
if (JNI_OnLoad != NULL)
|
||||
{
|
||||
JavaVM *vm = _Jv_GetJavaVM ();
|
||||
if (vm == NULL)
|
||||
{
|
||||
// FIXME: what?
|
||||
return;
|
||||
}
|
||||
jint vers = JNI_OnLoad (vm, NULL);
|
||||
if (vers != JNI_VERSION_1_1 && vers != JNI_VERSION_1_2)
|
||||
{
|
||||
// FIXME: unload the library.
|
||||
throw new java::lang::UnsatisfiedLinkError (JvNewStringLatin1 ("unrecognized version from preloaded JNI_OnLoad"));
|
||||
}
|
||||
}
|
||||
|
||||
if (klass == NULL)
|
||||
klass = java::lang::Class::forName (klass_name);
|
||||
if (klass != NULL)
|
||||
_Jv_InitClass (klass);
|
||||
|
||||
_Jv_Method *meth = _Jv_GetMethodLocal (klass, main_name, main_signature);
|
||||
|
||||
// Some checks from Java Spec section 12.1.4.
|
||||
if (meth == NULL)
|
||||
DIE ("no suitable method `main' in class");
|
||||
if (! java::lang::reflect::Modifier::isStatic(meth->accflags))
|
||||
DIE ("`main' must be static");
|
||||
if (! java::lang::reflect::Modifier::isPublic(meth->accflags))
|
||||
DIE ("`main' must be public");
|
||||
|
||||
#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);
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue