aboutsummaryrefslogtreecommitdiff
path: root/libjava/gnu/gcj/runtime
diff options
context:
space:
mode:
Diffstat (limited to 'libjava/gnu/gcj/runtime')
-rw-r--r--libjava/gnu/gcj/runtime/FirstThread.java51
-rw-r--r--libjava/gnu/gcj/runtime/natFirstThread.cc47
2 files changed, 92 insertions, 6 deletions
diff --git a/libjava/gnu/gcj/runtime/FirstThread.java b/libjava/gnu/gcj/runtime/FirstThread.java
index fd59261..c52ab42 100644
--- a/libjava/gnu/gcj/runtime/FirstThread.java
+++ b/libjava/gnu/gcj/runtime/FirstThread.java
@@ -17,11 +17,44 @@ import java.util.jar.*;
* @date August 24, 1998
*/
-// This is entirely internal to our implementation.
-
-final class FirstThread
+final class FirstThread extends Thread
{
- 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;
try {
@@ -37,15 +70,21 @@ final class FirstThread
}
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;
}
+ private native void call_main ();
+
// Private data.
private Class klass;
private String klass_name;
private Object args;
+ private boolean is_jar;
// If the user links statically then we need to ensure that these
// classes are linked in. Otherwise bootstrapping fails. These
diff --git a/libjava/gnu/gcj/runtime/natFirstThread.cc b/libjava/gnu/gcj/runtime/natFirstThread.cc
new file mode 100644
index 0000000..1d62471
--- /dev/null
+++ b/libjava/gnu/gcj/runtime/natFirstThread.cc
@@ -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);
+}