1 // natFirstThread.cc - Implementation of FirstThread native methods.
3 /* Copyright (C) 1998, 1999, 2000 Free Software Foundation
5 This file is part of libgcj.
7 This software is copyrighted work licensed under the terms of the
8 Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
19 #include <gnu/gcj/runtime/FirstThread.h>
20 #include <java/lang/Class.h>
21 #include <java/lang/String.h>
22 #include <java/lang/System.h>
23 #include <java/lang/reflect/Modifier.h>
24 #include <java/io/PrintStream.h>
28 #include <java/lang/ThreadGroup.h>
29 #include <java/lang/UnsatisfiedLinkError.h>
32 #define DIE(Message) die (JvNewStringLatin1 (Message))
34 typedef void main_func (jobject);
37 extern void (*_Jv_JVMPI_Notify_THREAD_START) (JVMPI_Event *event);
40 /* This will be non-NULL if the user has preloaded a JNI library, or
41 linked one into the executable. */
44 #pragma weak JNI_OnLoad
45 extern jint JNI_OnLoad (JavaVM *, void *) __attribute__((weak));
49 gnu::gcj::runtime::FirstThread::run (void)
52 Utf8Const* main_signature = _Jv_makeUtf8Const ("([Ljava.lang.String;)V", 22);
53 Utf8Const* main_name = _Jv_makeUtf8Const ("main", 4);
55 /* Some systems let you preload shared libraries before running a
56 program. Under Linux, this is done by setting the LD_PRELOAD
57 environment variable. We take advatage of this here to allow for
58 dynamically loading a JNI library into a fully linked executable. */
60 if (JNI_OnLoad != NULL)
62 JavaVM *vm = _Jv_GetJavaVM ();
68 jint vers = JNI_OnLoad (vm, NULL);
69 if (vers != JNI_VERSION_1_1 && vers != JNI_VERSION_1_2)
71 // FIXME: unload the library.
72 throw new java::lang::UnsatisfiedLinkError (JvNewStringLatin1 ("unrecognized version from preloaded JNI_OnLoad"));
77 klass = java::lang::Class::forName (klass_name);
79 _Jv_InitClass (klass);
81 _Jv_Method *meth = _Jv_GetMethodLocal (klass, main_name, main_signature);
83 // Some checks from Java Spec section 12.1.4.
85 DIE ("no suitable method `main' in class");
86 if (! java::lang::reflect::Modifier::isStatic(meth->accflags))
87 DIE ("`main' must be static");
88 if (! java::lang::reflect::Modifier::isPublic(meth->accflags))
89 DIE ("`main' must be public");
92 if (_Jv_JVMPI_Notify_THREAD_START)
96 jstring thread_name = getName ();
97 jstring group_name = NULL, parent_name = NULL;
98 java::lang::ThreadGroup *group = getThreadGroup ();
102 group_name = group->getName ();
103 group = group->getParent ();
106 parent_name = group->getName ();
109 int thread_len = thread_name ? JvGetStringUTFLength (thread_name) : 0;
110 int group_len = group_name ? JvGetStringUTFLength (group_name) : 0;
111 int parent_len = parent_name ? JvGetStringUTFLength (parent_name) : 0;
113 char thread_chars[thread_len + 1];
114 char group_chars[group_len + 1];
115 char parent_chars[parent_len + 1];
118 JvGetStringUTFRegion (thread_name, 0,
119 thread_name->length(), thread_chars);
121 JvGetStringUTFRegion (group_name, 0,
122 group_name->length(), group_chars);
124 JvGetStringUTFRegion (parent_name, 0,
125 parent_name->length(), parent_chars);
127 thread_chars[thread_len] = '\0';
128 group_chars[group_len] = '\0';
129 parent_chars[parent_len] = '\0';
131 event.event_type = JVMPI_EVENT_THREAD_START;
133 event.u.thread_start.thread_name = thread_chars;
134 event.u.thread_start.group_name = group_chars;
135 event.u.thread_start.parent_name = parent_chars;
136 event.u.thread_start.thread_id = (jobjectID) this;
137 event.u.thread_start.thread_env_id = _Jv_GetCurrentJNIEnv ();
140 (*_Jv_JVMPI_Notify_THREAD_START) (&event);
145 main_func *real_main = (main_func *) meth->ncode;