848c2edcac21af046d9ddaaf89cf7f458a8cebf5
[cacao.git] / src / native / vm / VMRuntime.c
1 /* nat/Runtime.c - java/lang/Runtime
2
3    Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
4    R. Grafl, A. Krall, C. Kruegel, C. Oates, R. Obermaisser,
5    M. Probst, S. Ring, E. Steiner, C. Thalinger, D. Thuernbeck,
6    P. Tomsich, J. Wenninger
7
8    This file is part of CACAO.
9
10    This program is free software; you can redistribute it and/or
11    modify it under the terms of the GNU General Public License as
12    published by the Free Software Foundation; either version 2, or (at
13    your option) any later version.
14
15    This program is distributed in the hope that it will be useful, but
16    WITHOUT ANY WARRANTY; without even the implied warranty of
17    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18    General Public License for more details.
19
20    You should have received a copy of the GNU General Public License
21    along with this program; if not, write to the Free Software
22    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
23    02111-1307, USA.
24
25    Contact: cacao@complang.tuwien.ac.at
26
27    Authors: Roman Obermaiser
28
29    Changes: Joseph Wenninger
30             Christian Thalinger
31
32    $Id: VMRuntime.c 1344 2004-07-21 17:12:53Z twisti $
33
34 */
35
36
37 #include <string.h>
38 #include <stdlib.h>
39 #include <unistd.h>
40 #include <sys/utsname.h>
41 #include "main.h"
42 #include "jni.h"
43 #include "builtin.h"
44 #include "exceptions.h"
45 #include "loader.h"
46 #include "native.h"
47 #include "tables.h"
48 #include "asmpart.h"
49 #include "mm/boehm.h"
50 #include "toolbox/logging.h"
51 #include "toolbox/memory.h"
52 #include "java_io_File.h"
53 #include "java_lang_String.h"
54 #include "java_lang_Process.h"
55 #include "java_util_Properties.h"    /* needed for java_lang_Runtime.h */
56 #include "java_lang_VMRuntime.h"
57
58
59 #define JOWENN_DEBUG
60
61 /* should we run all finalizers on exit? */
62 static s4 finalizeOnExit = false;
63
64 #define MAXPROPS 100
65 static bool shouldFinalizersBeRunOnExit=false;
66 static int activeprops = 19;  
67    
68 static char *proplist[MAXPROPS][2] = {
69         { "java.class.path", NULL },
70         { "java.home", NULL },
71         { "user.home", NULL },  
72         { "user.name", NULL },
73         { "user.dir",  NULL },
74                                 
75         { "os.arch", NULL },
76         { "os.name", NULL },
77         { "os.version", NULL },
78                                          
79         { "java.class.version", "45.3" },
80         { "java.version", PACKAGE":"VERSION },
81         { "java.vendor", "CACAO Team" },
82         { "java.vendor.url", "http://www.complang.tuwien.ac.at/java/cacao/" },
83         { "java.vm.name", "CACAO"}, 
84         { "java.tmpdir", "/tmp/"},
85         { "java.io.tmpdir", "/tmp/"},
86
87         { "path.separator", ":" },
88         { "file.separator", "/" },
89         { "line.separator", "\n" },
90         { "java.protocol.handler.pkgs", "gnu.java.net.protocol"}
91 };
92
93 void attach_property(char *name, char *value)
94 {
95         if (activeprops >= MAXPROPS) panic("Too many properties defined");
96         proplist[activeprops][0] = name;
97         proplist[activeprops][1] = value;
98         activeprops++;
99 }
100 /*
101  * Class:     java_lang_VMRuntime
102  * Method:    execInternal
103  * Signature: ([Ljava/lang/String;[Ljava/lang/String;Ljava/io/File;)Ljava/lang/Process;
104  */
105 JNIEXPORT java_lang_Process* JNICALL Java_java_lang_VMRuntime_execInternal(JNIEnv *env, jclass clazz, java_objectarray *cmd, java_objectarray *shellenv, java_io_File *workingdir)
106 {
107         log_text("Java_java_lang_Runtime_execInternal called");
108
109         return NULL;
110 }
111
112
113 /*
114  * Class:     java/lang/VMRuntime
115  * Method:    exitInternal
116  * Signature: (I)V
117  */
118 JNIEXPORT void JNICALL Java_java_lang_VMRuntime_exit(JNIEnv *env, jclass clazz, s4 par1)
119 {
120         if (finalizeOnExit)
121                 gc_finalize_all();
122
123         cacao_shutdown(par1);
124 }
125
126
127 /*
128  * Class:     java/lang/Runtime
129  * Method:    freeMemory
130  * Signature: ()J
131  */
132 JNIEXPORT s8 JNICALL Java_java_lang_VMRuntime_freeMemory(JNIEnv *env, jclass clazz)
133 {
134         return gc_get_free_bytes();
135 }
136
137
138 /*
139  * Class:     java/lang/Runtime
140  * Method:    gc
141  * Signature: ()V
142  */
143 JNIEXPORT void JNICALL Java_java_lang_VMRuntime_gc(JNIEnv *env, jclass clazz)
144 {
145         gc_call();
146 }
147
148
149 /*
150  * Class:     java/lang/Runtime
151  * Method:    runFinalization
152  * Signature: ()V
153  */
154 JNIEXPORT void JNICALL Java_java_lang_VMRuntime_runFinalization(JNIEnv *env, jclass clazz)
155 {
156         gc_invoke_finalizers();
157 }
158
159
160 /*
161  * Class:     java/lang/Runtime
162  * Method:    runFinalizersOnExit
163  * Signature: (Z)V
164  */
165 JNIEXPORT void JNICALL Java_java_lang_VMRuntime_runFinalizersOnExit(JNIEnv *env, jclass clazz, s4 par1)
166 {
167 #ifdef __GNUC__
168 #warning threading
169 #endif
170         shouldFinalizersBeRunOnExit=par1;
171 }
172
173 /*
174  * Class:     java/lang/Runtime
175  * Method:    runFinalizationsForExit
176  * Signature: ()V
177  */
178 JNIEXPORT void JNICALL Java_java_lang_VMRuntime_runFinalizationForExit(JNIEnv *env, jclass clazz)
179 {
180         if (shouldFinalizersBeRunOnExit) {
181                 gc_call();
182         //      gc_finalize_all();
183         }
184         log_text("Java_java_lang_VMRuntime_runFinalizationForExit called");
185
186 }
187
188
189 /*
190  * Class:     java/lang/Runtime
191  * Method:    totalMemory
192  * Signature: ()J
193  */
194 JNIEXPORT s8 JNICALL Java_java_lang_VMRuntime_totalMemory(JNIEnv *env, jclass clazz)
195 {
196         return gc_get_heap_size();
197 }
198
199
200 /*
201  * Class:     java/lang/Runtime
202  * Method:    traceInstructions
203  * Signature: (Z)V
204  */
205 JNIEXPORT void JNICALL Java_java_lang_VMRuntime_traceInstructions(JNIEnv *env, jclass clazz, s4 par1)
206 {
207         /* not supported */
208 }
209
210
211 /*
212  * Class:     java/lang/Runtime
213  * Method:    traceMethodCalls
214  * Signature: (Z)V
215  */
216 JNIEXPORT void JNICALL Java_java_lang_VMRuntime_traceMethodCalls(JNIEnv *env, jclass clazz, s4 par1)
217 {
218         /* not supported */
219 }
220
221
222 /*
223  * Class:     java_lang_Runtime
224  * Method:    availableProcessors
225  * Signature: ()I
226  */
227 JNIEXPORT s4 JNICALL Java_java_lang_VMRuntime_availableProcessors(JNIEnv *env, jclass clazz)
228 {
229 #if defined(_SC_NPROC_ONLN)
230         return (s4) sysconf(_SC_NPROC_ONLN);
231
232 #elif defined(_SC_NPROCESSORS_ONLN)
233         return (s4) sysconf(_SC_NPROCESSORS_ONLN);
234
235 #else
236         return 1;
237 #endif
238 }
239
240
241 /*
242  * Class:     java_lang_Runtime
243  * Method:    nativeLoad
244  * Signature: (Ljava/lang/String;)I
245  */
246 JNIEXPORT s4 JNICALL Java_java_lang_VMRuntime_nativeLoad(JNIEnv *env, jclass clazz, java_lang_String *par1)
247 {
248 #ifdef JOWENN_DEBUG     
249         char *buffer;
250         int buffer_len;
251         utf *data;
252         
253         data = javastring_toutf(par1, 0);
254         
255         if (!data) {
256                 log_text("nativeLoad: Error: empty string");
257                 return 1;
258         }
259         
260         buffer_len = utf_strlen(data) + 40;
261
262                 
263         buffer = MNEW(char, buffer_len);
264
265         strcpy(buffer, "Java_java_lang_VMRuntime_nativeLoad:");
266         utf_sprint(buffer + strlen((char *) data), data);
267         log_text(buffer);       
268
269         MFREE(buffer, char, buffer_len);
270 #endif
271         log_text("Java_java_lang_VMRuntime_nativeLoad");
272
273         return 1;
274 }
275
276
277 /*
278  * Class:     java_lang_VMRuntime
279  * Method:    nativeGetLibname
280  * Signature: (Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
281  */
282 JNIEXPORT java_lang_String* JNICALL Java_java_lang_VMRuntime_nativeGetLibname(JNIEnv *env, jclass clazz, java_lang_String *par1, java_lang_String *par2)
283 {
284         char *buffer;
285         int buffer_len;
286         utf *data;
287         java_lang_String *resultString; 
288         data = javastring_toutf(par2, 0);
289         
290         if (!data) {
291                 log_text("nativeGetLibName: Error: empty string");
292                 return 0;;
293         }
294         
295         buffer_len = utf_strlen(data) + 6/*lib .so*/ +1 /*0*/;
296         buffer = MNEW(char, buffer_len);
297         sprintf(buffer,"lib");
298         utf_sprint(buffer+3,data);
299         strcat(buffer,".so");
300
301         log_text(buffer);
302         
303         resultString=javastring_new_char(buffer);       
304
305         MFREE(buffer, char, buffer_len);
306
307         return resultString;
308 }
309
310
311 /*
312  * Class:     java_lang_VMRuntime
313  * Method:    insertSystemProperties
314  * Signature: (Ljava/util/Properties;)V
315  */
316 JNIEXPORT void JNICALL Java_java_lang_VMRuntime_insertSystemProperties(JNIEnv *env, jclass clazz, java_util_Properties *p)
317 {
318
319 #define BUFFERSIZE 200
320         u4 i;
321         methodinfo *m;
322         char buffer[BUFFERSIZE];
323         struct utsname utsnamebuf;
324
325         proplist[0][1] = classpath;
326         proplist[1][1] = getenv("JAVA_HOME");
327         proplist[2][1] = getenv("HOME");
328         proplist[3][1] = getenv("USER");
329         proplist[4][1] = getcwd(buffer, BUFFERSIZE);
330
331         /* get properties from system */
332         uname(&utsnamebuf);
333         proplist[5][1] = utsnamebuf.machine;
334         proplist[6][1] = utsnamebuf.sysname;
335         proplist[7][1] = utsnamebuf.release;
336
337         if (!p) {
338                 *exceptionptr = new_exception(string_java_lang_NullPointerException);
339                 return;
340         }
341
342         /* search for method to add properties */
343         m = class_resolvemethod(p->header.vftbl->class,
344                                                         utf_new_char("put"),
345                                                         utf_new_char("(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;")
346                                                         );
347
348         if (!m) {
349                 *exceptionptr = new_exception_message(string_java_lang_NoSuchMethodError,
350                                                                                           "java.lang.Properties.put(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;)");
351                 return;
352         }
353
354         /* add the properties */
355         for (i = 0; i < activeprops; i++) {
356
357                 if (proplist[i][1] == NULL) proplist[i][1] = "";
358
359                 asm_calljavafunction(m,
360                                                          p,
361                                                          javastring_new_char(proplist[i][0]),
362                                                          javastring_new_char(proplist[i][1]),
363                                                          NULL
364                                                          );
365         }
366
367         return;
368 }
369
370
371 /*
372  * Class:     java_lang_VMRuntime
373  * Method:    maxMemory
374  * Signature: ()J
375  */
376 JNIEXPORT s8 JNICALL Java_java_lang_VMRuntime_maxMemory(JNIEnv *env, jclass clazz)
377 {
378         return gc_get_max_heap_size();
379 }
380
381
382 /*
383  * These are local overrides for various environment variables in Emacs.
384  * Please do not remove this and leave it at the end of the file, where
385  * Emacs will automagically detect them.
386  * ---------------------------------------------------------------------
387  * Local variables:
388  * mode: c
389  * indent-tabs-mode: t
390  * c-basic-offset: 4
391  * tab-width: 4
392  * End:
393  */