Implement invocation interface; don't create new thread for main.

From-SVN: r42428
This commit is contained in:
Per Bothner 2001-05-21 23:47:48 -07:00 committed by Per Bothner
parent b4fbaca7cb
commit c93d7fae7b
22 changed files with 461 additions and 1945 deletions

View file

@ -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 ();
}

View file

@ -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
}

View file

@ -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;

View file

@ -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);
}