OSDN Git Service

* java/lang/natRuntime.cc (lt_preloaded_symbols): Define as `extern'.
[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  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
82   // Make status right for Unix.  This is perhaps strange.
83   if (status < 0 || status > 255)
84     status = 255;
85
86   if (finalize_on_exit)
87     _Jv_RunAllFinalizers ();
88
89   // Delete all files registered with File.deleteOnExit()
90   gnu::gcj::runtime::FileDeleter::deleteOnExitNow ();
91
92   ::exit (status);
93 }
94
95 jlong
96 java::lang::Runtime::freeMemory (void)
97 {
98   return _Jv_GCFreeMemory ();
99 }
100
101 void
102 java::lang::Runtime::gc (void)
103 {
104   _Jv_RunGC ();
105 }
106
107 void
108 java::lang::Runtime::_load (jstring path, jboolean do_search)
109 {
110   JvSynchronize sync (this);
111   checkLink (path);
112   using namespace java::lang;
113 #ifdef USE_LTDL
114   jint len = _Jv_GetStringUTFLength (path);
115   char buf[len + 1 + 3];
116   int offset = 0;
117 #ifndef WIN32
118   // On Unix boxes, prefix library name with `lib', for loadLibrary.
119   if (do_search)
120     {
121       strcpy (buf, "lib");
122       offset = 3;
123     }
124 #endif
125   jsize total = JvGetStringUTFRegion (path, 0, path->length(), &buf[offset]);
126   buf[offset + total] = '\0';
127   // FIXME: make sure path is absolute.
128   lt_dlhandle h = do_search ? lt_dlopenext (buf) : lt_dlopen (buf);
129   if (h == NULL)
130     {
131       const char *msg = lt_dlerror ();
132       jstring str = path->concat (JvNewStringLatin1 (": "));
133       str = str->concat (JvNewStringLatin1 (msg));
134       _Jv_Throw (new UnsatisfiedLinkError (str));
135     }
136
137   add_library (h);
138
139   void *onload = lt_dlsym (h, "JNI_OnLoad");
140   if (onload != NULL)
141     {
142       JavaVM *vm = _Jv_GetJavaVM ();
143       if (vm == NULL)
144         {
145           // FIXME: what?
146           return;
147         }
148       jint vers = ((jint (*) (JavaVM *, void *)) onload) (vm, NULL);
149       if (vers != JNI_VERSION_1_1 && vers != JNI_VERSION_1_2)
150         {
151           // FIXME: unload the library.
152           _Jv_Throw (new UnsatisfiedLinkError (JvNewStringLatin1 ("unrecognized version from JNI_OnLoad")));
153         }
154     }
155 #else
156   _Jv_Throw (new UnknownError
157              (JvNewStringLatin1 (do_search
158                                  ? "Runtime.loadLibrary not implemented"
159                                  : "Runtime.load not implemented")));
160 #endif /* USE_LTDL */
161 }
162
163 jboolean
164 java::lang::Runtime::loadLibraryInternal (jstring lib)
165 {
166   JvSynchronize sync (this);
167   using namespace java::lang;
168 #ifdef USE_LTDL
169   jint len = _Jv_GetStringUTFLength (lib);
170   char buf[len + 1];
171   jsize total = JvGetStringUTFRegion (lib, 0, lib->length(), buf);
172   buf[total] = '\0';
173   // FIXME: make sure path is absolute.
174   lt_dlhandle h = lt_dlopenext (buf);
175   if (h != NULL)
176     add_library (h);
177   return h != NULL;
178 #else
179   return false;
180 #endif /* USE_LTDL */
181 }
182
183 void
184 java::lang::Runtime::init (void)
185 {
186   finalize_on_exit = false;
187 #ifdef USE_LTDL
188   lt_dlinit ();
189 #endif
190 }
191
192 void
193 java::lang::Runtime::runFinalization (void)
194 {
195   _Jv_RunFinalizers ();
196 }
197
198 jlong
199 java::lang::Runtime::totalMemory (void)
200 {
201   return _Jv_GCTotalMemory ();
202 }
203
204 void
205 java::lang::Runtime::traceInstructions (jboolean)
206 {
207   // Do nothing.
208 }
209
210 void
211 java::lang::Runtime::traceMethodCalls (jboolean)
212 {
213   // Do nothing.
214 }