OSDN Git Service

gcc/java:
[pf3gnuchains/gcc-fork.git] / libjava / gnu / gcj / runtime / natFirstThread.cc
1 // natFirstThread.cc - Implementation of FirstThread native methods.
2
3 /* Copyright (C) 1998, 1999, 2000  Free Software Foundation
4
5    This file is part of libgcj.
6
7 This software is copyrighted work licensed under the terms of the
8 Libgcj License.  Please consult the file "LIBGCJ_LICENSE" for
9 details.  */
10
11 #include <config.h>
12
13 #include <stdlib.h>
14
15 #include <gcj/cni.h>
16 #include <jvm.h>
17 #include <jni.h>
18
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>
25
26 #ifdef ENABLE_JVMPI
27 #include <jvmpi.h>
28 #include <java/lang/ThreadGroup.h>
29 #include <java/lang/UnsatisfiedLinkError.h>
30 #endif
31
32 #define DIE(Message)  die (JvNewStringLatin1 (Message))
33
34 typedef void main_func (jobject);
35
36 #ifdef WITH_JVMPI
37 extern void (*_Jv_JVMPI_Notify_THREAD_START) (JVMPI_Event *event);
38 #endif
39
40 /* This will be non-NULL if the user has preloaded a JNI library, or
41    linked one into the executable.  */
42 extern "C" 
43 {
44 #pragma weak JNI_OnLoad
45   extern jint JNI_OnLoad (JavaVM *, void *) __attribute__((weak));
46 }
47
48 void
49 gnu::gcj::runtime::FirstThread::run (void)
50 {
51
52   Utf8Const* main_signature = _Jv_makeUtf8Const ("([Ljava.lang.String;)V", 22);
53   Utf8Const* main_name = _Jv_makeUtf8Const ("main", 4);
54
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.  */
59
60   if (JNI_OnLoad != NULL)
61     {
62       JavaVM *vm = _Jv_GetJavaVM ();
63       if (vm == NULL)
64         {
65           // FIXME: what?
66           return;
67         }
68       jint vers = JNI_OnLoad (vm, NULL);
69       if (vers != JNI_VERSION_1_1 && vers != JNI_VERSION_1_2)
70         {
71           // FIXME: unload the library.
72           throw new java::lang::UnsatisfiedLinkError (JvNewStringLatin1 ("unrecognized version from preloaded JNI_OnLoad"));
73         }
74     }
75
76   if (klass == NULL)
77     klass = java::lang::Class::forName (klass_name);
78   if (klass != NULL)
79     _Jv_InitClass (klass);
80
81   _Jv_Method *meth = _Jv_GetMethodLocal (klass, main_name, main_signature);
82
83   // Some checks from Java Spec section 12.1.4.
84   if (meth == NULL)
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");
90
91 #ifdef WITH_JVMPI
92   if (_Jv_JVMPI_Notify_THREAD_START)
93     {
94       JVMPI_Event event;
95
96       jstring thread_name = getName ();
97       jstring group_name = NULL, parent_name = NULL;
98       java::lang::ThreadGroup *group = getThreadGroup ();
99
100       if (group)
101         {
102           group_name = group->getName ();
103           group = group->getParent ();
104
105           if (group)
106             parent_name = group->getName ();
107         }
108
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;
112
113       char thread_chars[thread_len + 1];
114       char group_chars[group_len + 1];
115       char parent_chars[parent_len + 1];
116
117       if (thread_name)
118         JvGetStringUTFRegion (thread_name, 0, 
119                               thread_name->length(), thread_chars);
120       if (group_name)
121         JvGetStringUTFRegion (group_name, 0, 
122                               group_name->length(), group_chars);
123       if (parent_name)
124         JvGetStringUTFRegion (parent_name, 0, 
125                               parent_name->length(), parent_chars);
126
127       thread_chars[thread_len] = '\0';
128       group_chars[group_len] = '\0';
129       parent_chars[parent_len] = '\0';
130
131       event.event_type = JVMPI_EVENT_THREAD_START;
132       event.env_id = NULL;
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 ();
138
139       _Jv_DisableGC ();
140       (*_Jv_JVMPI_Notify_THREAD_START) (&event);
141       _Jv_EnableGC ();
142     }
143 #endif
144
145   main_func *real_main = (main_func *) meth->ncode;
146   (*real_main) (args);
147 }