OSDN Git Service

* exception.cc (java_eh_info): Make value type jthrowable.
[pf3gnuchains/gcc-fork.git] / libjava / java / lang / natRuntime.cc
1 // natRuntime.cc - Implementation of native side of Runtime class.
2
3 /* Copyright (C) 1998, 1999, 2000, 2001  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 <java/lang/Runtime.h>
18 #include <java/lang/UnknownError.h>
19 #include <java/lang/UnsatisfiedLinkError.h>
20 #include <gnu/gcj/runtime/FileDeleter.h>
21
22 #include <jni.h>
23
24 #ifdef USE_LTDL
25 #include <ltdl.h>
26
27 /* FIXME: we don't always need this.  The next libtool will let us use
28    AC_LTDL_PREOPEN to see if we do.  */
29 extern const lt_dlsymlist lt_preloaded_symbols[1] = { { 0, 0 } };
30
31 // We keep track of all the libraries loaded by this application.  For
32 // now we use them to look up symbols for JNI.  `libraries_size' holds
33 // the total size of the buffer.  `libraries_count' is the number of
34 // items which are in use.
35 static int libraries_size;
36 static int libraries_count;
37 static lt_dlhandle *libraries;
38
39 static void
40 add_library (lt_dlhandle lib)
41 {
42   if (libraries_count == libraries_size)
43     {
44       int ns = libraries_size * 2;
45       if (ns == 0)
46         ns = 10;
47       lt_dlhandle *n = (lt_dlhandle *) _Jv_Malloc (ns * sizeof (lt_dlhandle));
48       if (libraries)
49         {
50           memcpy (n, libraries, libraries_size * sizeof (lt_dlhandle));
51           _Jv_Free (libraries);
52         }
53       libraries = n;
54       libraries_size = ns;
55       for (int i = libraries_count; i < libraries_size; ++i)
56         libraries[i] = NULL;
57     }
58
59   libraries[libraries_count++] = lib;
60 }
61
62 void *
63 _Jv_FindSymbolInExecutable (const char *symname)
64 {
65   for (int i = 0; i < libraries_count; ++i)
66     {
67       void *r = lt_dlsym (libraries[i], symname);
68       if (r)
69         return r;
70     }
71
72   return lt_dlsym (NULL, symname);
73 }
74
75 #endif /* USE_LTDL */
76
77 void
78 java::lang::Runtime::exit (jint status)
79 {
80   checkExit (status);
81   _exit (status);
82 }
83
84 void
85 java::lang::Runtime::_exit (jint status)
86 {
87   // Make status right for Unix.  This is perhaps strange.
88   if (status < 0 || status > 255)
89     status = 255;
90
91   if (finalize_on_exit)
92     _Jv_RunAllFinalizers ();
93
94   // Delete all files registered with File.deleteOnExit()
95   gnu::gcj::runtime::FileDeleter::deleteOnExitNow ();
96
97   ::exit (status);
98 }
99
100 jlong
101 java::lang::Runtime::freeMemory (void)
102 {
103   return _Jv_GCFreeMemory ();
104 }
105
106 void
107 java::lang::Runtime::gc (void)
108 {
109   _Jv_RunGC ();
110 }
111
112 void
113 java::lang::Runtime::_load (jstring path, jboolean do_search)
114 {
115   JvSynchronize sync (this);
116   checkLink (path);
117   using namespace java::lang;
118 #ifdef USE_LTDL
119   jint len = _Jv_GetStringUTFLength (path);
120   char buf[len + 1 + 3];
121   int offset = 0;
122 #ifndef WIN32
123   // On Unix boxes, prefix library name with `lib', for loadLibrary.
124   if (do_search)
125     {
126       strcpy (buf, "lib");
127       offset = 3;
128     }
129 #endif
130   jsize total = JvGetStringUTFRegion (path, 0, path->length(), &buf[offset]);
131   buf[offset + total] = '\0';
132   // FIXME: make sure path is absolute.
133   lt_dlhandle h = do_search ? lt_dlopenext (buf) : lt_dlopen (buf);
134   if (h == NULL)
135     {
136       const char *msg = lt_dlerror ();
137       jstring str = path->concat (JvNewStringLatin1 (": "));
138       str = str->concat (JvNewStringLatin1 (msg));
139       throw new UnsatisfiedLinkError (str);
140     }
141
142   add_library (h);
143
144   void *onload = lt_dlsym (h, "JNI_OnLoad");
145   if (onload != NULL)
146     {
147       JavaVM *vm = _Jv_GetJavaVM ();
148       if (vm == NULL)
149         {
150           // FIXME: what?
151           return;
152         }
153       jint vers = ((jint (*) (JavaVM *, void *)) onload) (vm, NULL);
154       if (vers != JNI_VERSION_1_1 && vers != JNI_VERSION_1_2)
155         {
156           // FIXME: unload the library.
157           throw new UnsatisfiedLinkError (JvNewStringLatin1 ("unrecognized version from JNI_OnLoad"));
158         }
159     }
160 #else
161   throw new UnknownError
162     (JvNewStringLatin1 (do_search
163                         ? "Runtime.loadLibrary not implemented"
164                         : "Runtime.load not implemented"));
165 #endif /* USE_LTDL */
166 }
167
168 jboolean
169 java::lang::Runtime::loadLibraryInternal (jstring lib)
170 {
171   JvSynchronize sync (this);
172   using namespace java::lang;
173 #ifdef USE_LTDL
174   jint len = _Jv_GetStringUTFLength (lib);
175   char buf[len + 1];
176   jsize total = JvGetStringUTFRegion (lib, 0, lib->length(), buf);
177   buf[total] = '\0';
178   // FIXME: make sure path is absolute.
179   lt_dlhandle h = lt_dlopenext (buf);
180   if (h != NULL)
181     add_library (h);
182   return h != NULL;
183 #else
184   return false;
185 #endif /* USE_LTDL */
186 }
187
188 void
189 java::lang::Runtime::init (void)
190 {
191   finalize_on_exit = false;
192 #ifdef USE_LTDL
193   lt_dlinit ();
194 #endif
195 }
196
197 void
198 java::lang::Runtime::runFinalization (void)
199 {
200   _Jv_RunFinalizers ();
201 }
202
203 jlong
204 java::lang::Runtime::totalMemory (void)
205 {
206   return _Jv_GCTotalMemory ();
207 }
208
209 void
210 java::lang::Runtime::traceInstructions (jboolean)
211 {
212   // Do nothing.
213 }
214
215 void
216 java::lang::Runtime::traceMethodCalls (jboolean)
217 {
218   // Do nothing.
219 }