Initial revision
[cacao.git] / nat / lang.c
1 /* -*- mode: c; tab-width: 4; c-basic-offset: 4 -*- */
2 /****************************** nat/lang.c *************************************
3
4         Copyright (c) 1997 A. Krall, R. Grafl, M. Gschwind, M. Probst
5
6         See file COPYRIGHT for information on usage and disclaimer of warranties
7
8         Contains the native functions for class java.lang.
9
10         Authors: Reinhard Grafl      EMAIL: cacao@complang.tuwien.ac.at
11                  Mark Probst         EMAIL: cacao@complang.tuwien.ac.at
12
13         Last Change: 1997/06/10
14
15 *******************************************************************************/
16
17 #include <math.h>
18 #include <assert.h>
19 #include <sys/time.h>
20
21 #include "../threads/thread.h"                       /* schani */
22 #include "../threads/locks.h"
23
24 static void use_class_as_object (classinfo *c) 
25 {
26         c->header.vftbl = class_java_lang_Class -> vftbl;
27 }
28
29
30 /************************************** java.lang.Object ***********************************/
31
32 struct java_lang_Class* java_lang_Object_getClass (struct java_lang_Object* this)
33 {
34         classinfo *c = this->header.vftbl -> class;
35         use_class_as_object (c);
36         return (java_lang_Class*) c;
37 }
38
39 s4 java_lang_Object_hashCode (struct java_lang_Object* this)
40 {
41         return ((char*) this) - ((char*) 0);    
42 }
43
44
45 struct java_lang_Object* java_lang_Object_clone (struct java_lang_Object* this)
46 {
47         classinfo *c;
48         java_lang_Object *new;
49
50         if (((java_objectheader*)this)->vftbl->class == class_array)
51           {
52             static u4 multiplicator[10];
53             static int is_initialized = 0;
54
55             java_arrayheader *array = (java_arrayheader*)this;
56             u4 size;
57
58             if (!is_initialized)
59               {
60                 multiplicator[ARRAYTYPE_INT] = sizeof(s4);
61                 multiplicator[ARRAYTYPE_LONG] = sizeof(s8);
62                 multiplicator[ARRAYTYPE_FLOAT] = sizeof(float);
63                 multiplicator[ARRAYTYPE_DOUBLE] = sizeof(double);
64                 multiplicator[ARRAYTYPE_BYTE] = sizeof(s1);
65                 multiplicator[ARRAYTYPE_CHAR] = sizeof(u2);
66                 multiplicator[ARRAYTYPE_SHORT] = sizeof(s2);
67                 multiplicator[ARRAYTYPE_BOOLEAN] = sizeof(u1);
68                 multiplicator[ARRAYTYPE_OBJECT] = sizeof(void*);
69                 multiplicator[ARRAYTYPE_ARRAY] = sizeof(void*);
70                 is_initialized = 1;
71               }
72             
73             size = sizeof(java_arrayheader)
74               + array->size * multiplicator[array->arraytype];
75
76             new = (java_lang_Object*)heap_allocate(size, false, NULL);
77             memcpy(new, this, size);
78
79             return new;
80           }
81         else
82           {
83             if (! builtin_instanceof ((java_objectheader*) this, class_java_lang_Cloneable) ) {
84                 exceptionptr = native_new_and_init (class_java_lang_CloneNotSupportedException);
85                 return NULL;
86                 }
87         
88         c = this -> header.vftbl -> class;
89         new = (java_lang_Object*) builtin_new (c);
90         if (!new) {
91                 exceptionptr = proto_java_lang_OutOfMemoryError;
92                 return NULL;
93                 }
94
95             memcpy (new, this, c->instancesize);
96             return new;
97           }
98 }
99         
100 void java_lang_Object_notify (struct java_lang_Object* this)
101 {
102         if (runverbose)
103                 log_text ("java_lang_Object_notify called");
104
105 #ifdef USE_THREADS
106     signal_cond_for_object(&this->header);
107 #endif
108 }
109
110 void java_lang_Object_notifyAll (struct java_lang_Object* this)
111 {
112         if (runverbose)
113                 log_text ("java_lang_Object_notifyAll called");
114
115 #ifdef USE_THREADS
116         broadcast_cond_for_object(&this->header);
117 #endif
118 }
119
120 void java_lang_Object_wait (struct java_lang_Object* this, s8 time)
121 {
122         if (runverbose)
123                 log_text ("java_lang_Object_wait called");
124
125 #ifdef USE_THREADS
126         wait_cond_for_object(&this->header, time);
127 #endif
128 }
129
130
131 /********************************** java.lang.Class **************************************/
132
133
134 struct java_lang_Class* java_lang_Class_forName (struct java_lang_String* s)
135 {
136         java_chararray *a,*b;
137         u4 i;
138         unicode *u;
139         classinfo *c;
140         
141         if (!s) return NULL;
142         if (!(a = s->value) ) return NULL;
143         b = builtin_newarray_char (s->count);
144         if (!b) return NULL;
145         for (i=0; i<s->count; i++) {
146                 if (a->data[s->offset+i]=='.') b->data[i] = '/';
147             else                           b->data[i] = a->data[s->offset+i];
148             }
149         u = unicode_new_u2 (b->data, b->header.size);
150         c = u->class;
151         if (!c) {
152                 c = loader_load (u);
153                 loader_initclasses ();
154
155                 if (!c) {       
156                         exceptionptr = 
157                         native_new_and_init (class_java_lang_ClassNotFoundException);
158         
159                         return NULL;
160                         }
161
162                 }
163         
164         use_class_as_object (c);
165         return (java_lang_Class*) c;
166 }
167
168 struct java_lang_Object* java_lang_Class_newInstance (struct java_lang_Class* this)
169 {
170         java_objectheader *o = native_new_and_init ((classinfo*) this);
171         if (!o) {
172                 exceptionptr = 
173                         native_new_and_init (class_java_lang_InstantiationException);
174                 }
175         return (java_lang_Object*) o;
176 }
177
178 struct java_lang_String* java_lang_Class_getName (struct java_lang_Class* this)
179 {
180         u4 i;
181         classinfo *c = (classinfo*) this;
182         java_lang_String *s = (java_lang_String*) javastring_new(c->name);
183
184         if (!s) return NULL;
185
186         for (i=0; i<s->value->header.size; i++) {
187                 if (s->value->data[i] == '/') s->value->data[i] = '.';
188                 }
189         
190         return s;
191 }
192
193 struct java_lang_Class* java_lang_Class_getSuperclass (struct java_lang_Class* this)
194 {
195         classinfo *c = ((classinfo*) this) -> super;
196         if (!c) return NULL;
197
198         use_class_as_object (c);
199         return (java_lang_Class*) c;
200 }
201
202 java_objectarray* java_lang_Class_getInterfaces (struct java_lang_Class* this)
203 {
204         classinfo *c = (classinfo*) this;
205         u4 i;
206         java_objectarray *a = builtin_anewarray (c->interfacescount, class_java_lang_Class);
207         if (!a) return NULL;
208         for (i=0; i<c->interfacescount; i++) {
209                 use_class_as_object (c->interfaces[i]);
210
211                 a->data[i] = (java_objectheader*) c->interfaces[i];
212                 }
213         return a;
214 }
215
216 struct java_lang_ClassLoader* java_lang_Class_getClassLoader (struct java_lang_Class* this)
217 {
218         log_text ("java_lang_Class_getClassLoader called");
219         return NULL;
220 }
221
222 s4 java_lang_Class_isInterface (struct java_lang_Class* this)
223 {
224         classinfo *c = (classinfo*) this;
225         if (c->flags & ACC_INTERFACE) return 1;
226         return 0;
227 }
228
229 /************************************ java.lang.ClassLoader *******************************/
230
231
232 struct java_lang_Class* java_lang_ClassLoader_defineClass (struct java_lang_ClassLoader* this, java_bytearray* par1, s4 par2, s4 par3)
233 {
234         log_text ("java_lang_ClassLoader_defineClass called");
235         return NULL;
236 }
237 void java_lang_ClassLoader_resolveClass (struct java_lang_ClassLoader* this, struct java_lang_Class* par1)
238 {
239         log_text ("java_lang_ClassLoader_resolveClass called");
240 }
241 struct java_lang_Class* java_lang_ClassLoader_findSystemClass (struct java_lang_ClassLoader* this, struct java_lang_String* par1)
242 {
243         log_text ("java_lang_ClassLoader_findSystemClass called");
244         return NULL;
245 }       
246 void java_lang_ClassLoader_init (struct java_lang_ClassLoader* this)
247 {
248         log_text ("java_lang_ClassLoader_init called");
249 }
250 struct java_lang_Class* java_lang_ClassLoader_findSystemClass0 (struct java_lang_ClassLoader* this, struct java_lang_String* par1)
251 {
252         log_text ("java_lang_ClassLoader_findSystemClass0 called");
253         return NULL;
254 }
255
256 struct java_lang_Class* java_lang_ClassLoader_defineClass0 (struct java_lang_ClassLoader* this, java_bytearray* par1, s4 par2, s4 par3)
257 {
258         log_text ("java_lang_ClassLoader_defineClass0 called");
259         return NULL;
260 }
261 void java_lang_ClassLoader_resolveClass0 (struct java_lang_ClassLoader* this, struct java_lang_Class* par1)
262 {
263         log_text ("java_lang_ClassLoader_resolveClass0 called");
264         return;
265 }
266
267 /************************************** java.lang.Compiler  *******************************/
268
269 void java_lang_Compiler_initialize ()
270 {
271         log_text ("java_lang_Compiler_initialize called");
272 }
273 s4 java_lang_Compiler_compileClass (struct java_lang_Class* par1) 
274 {
275         log_text ("java_lang_Compiler_compileClass called");
276         return 0;
277 }
278 s4 java_lang_Compiler_compileClasses (struct java_lang_String* par1)
279 {
280         log_text ("java_lang_Compiler_compileClasses called");
281         return 0;
282 }
283 struct java_lang_Object* java_lang_Compiler_command (struct java_lang_Object* par1)
284 {
285         log_text ("java_lang_Compiler_command called");
286         return NULL;
287 }
288 void java_lang_Compiler_enable ()
289 {
290         log_text ("java_lang_Compiler_enable called");
291 }
292 void java_lang_Compiler_disable ()
293 {
294         log_text ("java_lang_Compiler_disable called");
295 }
296
297
298 /******************************** java.lang.Double **************************************/
299
300 struct java_lang_String* java_lang_Double_toString (double par1)
301 {
302         char b[400];
303         sprintf (b, "%-.6g", par1);
304         return (java_lang_String*) javastring_new_char (b);
305 }
306 struct java_lang_Double* java_lang_Double_valueOf (struct java_lang_String* par1)
307 {       
308         float val;
309         java_lang_Double *d = (java_lang_Double*) builtin_new (class_java_lang_Double);
310         if (d) {        
311                 sscanf (javastring_tochar((java_objectheader*) par1), "%f", &val);
312                 d->value = val;
313                 return d;
314         }
315         return NULL;
316 }
317 s8 java_lang_Double_doubleToLongBits (double par1)
318 {
319         s8 l;
320         double d = par1;
321         memcpy ((u1*) &l, (u1*) &d, 8);
322         return l;
323 }
324 double java_lang_Double_longBitsToDouble (s8 par1)
325 {
326         s8 l = par1;
327         double d;
328         memcpy ((u1*) &d, (u1*) &l, 8);
329         return d;
330 }
331
332 /******************************** java.lang.Float ***************************************/
333
334 struct java_lang_String* java_lang_Float_toString (float par1)
335 {
336         char b[50];
337         sprintf (b, "%-.6g", (double) par1);
338         return (java_lang_String*) javastring_new_char (b);
339 }
340 struct java_lang_Float* java_lang_Float_valueOf (struct java_lang_String* par1)
341 {
342         float val;
343         java_lang_Float *d = (java_lang_Float*) builtin_new (class_java_lang_Float);
344         if (d) {        
345                 sscanf (javastring_tochar((java_objectheader*) par1), "%f", &val);
346                 d->value = val;
347                 return d;
348         }
349         return NULL;
350 }
351 s4 java_lang_Float_floatToIntBits (float par1)
352 {
353         s4 i;
354         float f = par1;
355         memcpy ((u1*) &i, (u1*) &f, 4);
356         return i;
357 }
358 float java_lang_Float_intBitsToFloat (s4 par1)
359 {
360         s4 i = par1;
361         float f;
362         memcpy ((u1*) &f, (u1*) &i, 4);
363         return f;
364 }
365
366
367 /******************************** java.lang.Math ****************************************/
368
369 double java_lang_Math_sin (double par1)
370 {
371         return sin(par1);
372 }
373
374 double java_lang_Math_cos (double par1)
375 {
376         return cos(par1);
377 }
378
379 double java_lang_Math_tan (double par1)
380 {
381         return tan(par1);
382 }
383
384 double java_lang_Math_asin (double par1)
385 {
386         return asin(par1);
387 }
388
389 double java_lang_Math_acos (double par1)
390 {
391         return acos(par1);
392 }
393
394 double java_lang_Math_atan (double par1)
395 {
396         return atan(par1);
397 }
398
399 double java_lang_Math_exp (double par1)
400 {
401         return exp(par1);
402 }
403
404 double java_lang_Math_log (double par1)
405 {
406         if (par1<0.0) {
407                 exceptionptr = proto_java_lang_ArithmeticException;
408                 return 0.0;
409                 }
410         return log(par1);
411 }
412
413 double java_lang_Math_sqrt (double par1)
414 {
415         if (par1<0.0) {
416                 exceptionptr = proto_java_lang_ArithmeticException;
417                 return 0.0;
418                 }
419         return sqrt(par1);
420 }
421
422 static u8 dbl_nan    = 0xffffffffffffffffL ;
423
424 #define DBL_NAN    (*((double*) (&dbl_nan)))
425
426 double java_lang_Math_IEEEremainder (double a, double b)
427 {
428         double d;
429         if (finite(a) && finite(b)) {
430                 d = a / b;
431                 if (finite(d))
432                         return a - floor(d) * b;
433                 return DBL_NAN;
434                 }
435         if (isnan(b))
436                 return DBL_NAN;
437         if (finite(a))
438                 return a;
439         return DBL_NAN;
440 }
441
442 double java_lang_Math_ceil (double par1)
443 {
444         return ceil(par1);
445 }
446
447 double java_lang_Math_floor (double par1)
448 {
449         return floor(par1);
450 }
451
452 double java_lang_Math_rint (double par1)
453 {
454         panic ("native Methode java_lang_rint not implemented yet");
455         return 0.0;
456 }
457
458 double java_lang_Math_atan2 (double par1, double par2)
459 {
460         return atan2(par1,par2);
461 }
462
463 double java_lang_Math_pow (double par1, double par2)
464 {
465         return pow(par1,par2);
466 }
467
468
469 /******************************* java.lang.Runtime **************************************/
470
471 void java_lang_Runtime_exitInternal (struct java_lang_Runtime* this, s4 par1)
472 {
473         cacao_shutdown (par1);
474 }
475 struct java_lang_Process* java_lang_Runtime_execInternal (struct java_lang_Runtime* this, java_objectarray* par1, java_objectarray* par2)
476 {
477         log_text ("java_lang_Runtime_execInternal called");
478         return NULL;
479 }
480 s8 java_lang_Runtime_freeMemory (struct java_lang_Runtime* this)
481 {
482         log_text ("java_lang_Runtime_freeMemory called");
483         return builtin_i2l (0);
484 }
485 s8 java_lang_Runtime_totalMemory (struct java_lang_Runtime* this)
486 {
487         log_text ("java_lang_Runtime_totalMemory called");
488         return builtin_i2l (0);
489 }
490 void java_lang_Runtime_gc (struct java_lang_Runtime* this)
491 {
492         gc_call();
493 }
494 void java_lang_Runtime_runFinalization (struct java_lang_Runtime* this)
495 {
496         log_text ("java_lang_Runtime_runFinalization called");
497 }
498 void java_lang_Runtime_traceInstructions (struct java_lang_Runtime* this, s4 par1)
499 {
500         log_text ("java_lang_Runtime_traceInstructions called");
501 }
502 void java_lang_Runtime_traceMethodCalls (struct java_lang_Runtime* this, s4 par1)
503 {
504         log_text ("java_lang_Runtime_traceMethodCalls called");
505 }
506 struct java_lang_String* java_lang_Runtime_initializeLinkerInternal (struct java_lang_Runtime* this)
507 {       
508         log_text ("java_lang_Runtime_initializeLinkerInternal called");
509         return (java_lang_String*)javastring_new_char(".");
510 }
511 struct java_lang_String* java_lang_Runtime_buildLibName (struct java_lang_Runtime* this, struct java_lang_String* par1, struct java_lang_String* par2)
512 {
513         log_text ("java_lang_Runtime_buildLibName called");
514         return NULL;
515 }
516 s4 java_lang_Runtime_loadFileInternal (struct java_lang_Runtime* this, struct java_lang_String* par1)
517 {
518         log_text ("java_lang_Runtime_loadFileInternal called");
519         return 1;
520 }
521
522
523 /**************************************** java.lang.SecurityManager ***********************/
524
525 java_objectarray* java_lang_SecurityManager_getClassContext (struct java_lang_SecurityManager* this)
526 {
527         log_text ("called: java_lang_SecurityManager_getClassContext");
528         return NULL;
529 }
530 struct java_lang_ClassLoader* java_lang_SecurityManager_currentClassLoader (struct java_lang_SecurityManager* this)
531 {
532         log_text ("called: java_lang_SecurityManager_currentClassLoader");
533         return NULL;
534 }
535 s4 java_lang_SecurityManager_classDepth (struct java_lang_SecurityManager* this, struct java_lang_String* par1)
536 {
537         log_text ("called: java_lang_SecurityManager_classDepth");
538         return 0;
539 }
540 s4 java_lang_SecurityManager_classLoaderDepth (struct java_lang_SecurityManager* this)
541 {
542         log_text ("called: java_lang_SecurityManager_classLoaderDepth");
543         return 0;
544 }
545
546
547
548 /*********************************** java.lang.System ************************************/
549
550 s8 java_lang_System_currentTimeMillis ()
551 {
552         struct timeval tv;
553
554         (void) gettimeofday(&tv, NULL);
555         return ((s8) tv.tv_sec) * 1000 + tv.tv_usec / 1000;
556 }
557
558
559 void java_lang_System_arraycopy (struct java_lang_Object* source, s4 sp, 
560                                  struct java_lang_Object* dest, s4 dp, s4 len)
561 {
562         s4 i;
563         java_arrayheader *s = (java_arrayheader*) source;
564         java_arrayheader *d = (java_arrayheader*) dest;
565
566         if ( (!s) || (!d) ) { 
567                 exceptionptr = proto_java_lang_NullPointerException; 
568                 return; 
569                 }
570         if ( (s->objheader.vftbl->class != class_array) || (d->objheader.vftbl->class != class_array) ) {
571                 exceptionptr = proto_java_lang_ArrayStoreException; 
572                 return; 
573                 }
574                 
575         if (s->arraytype != d->arraytype) {
576                 exceptionptr = proto_java_lang_ArrayStoreException; 
577                 return; 
578                 }
579
580         if ((sp<0) || (sp+len > s->size) || (dp<0) || (dp+len > d->size)) {
581                 exceptionptr = proto_java_lang_ArrayIndexOutOfBoundsException; 
582                 return; 
583                 }
584
585         switch (s->arraytype) {
586         case ARRAYTYPE_BYTE:
587                 {
588                 java_bytearray *bas = (java_bytearray*) s;
589                 java_bytearray *bad = (java_bytearray*) d;
590                 if (dp<=sp) 
591                         for (i=0; i<len; i++) bad->data[dp+i] = bas->data[sp+i];
592                 else 
593                         for (i=len-1; i>=0; i--) bad->data[dp+i] = bas->data[sp+i];
594                 }
595                 break;
596         case ARRAYTYPE_BOOLEAN:
597                 {
598                 java_booleanarray *bas = (java_booleanarray*) s;
599                 java_booleanarray *bad = (java_booleanarray*) d;
600                 if (dp<=sp) 
601                         for (i=0; i<len; i++) bad->data[dp+i] = bas->data[sp+i];
602                 else 
603                         for (i=len-1; i>=0; i--) bad->data[dp+i] = bas->data[sp+i];
604                 }
605                 break;
606         case ARRAYTYPE_CHAR:
607                 {
608                 java_chararray *cas = (java_chararray*) s;
609                 java_chararray *cad = (java_chararray*) d;
610                 if (dp<=sp) 
611                         for (i=0; i<len; i++) cad->data[dp+i] = cas->data[sp+i];
612                 else 
613                         for (i=len-1; i>=0; i--) cad->data[dp+i] = cas->data[sp+i];
614                 }
615                 break;
616         case ARRAYTYPE_SHORT:
617                 {
618                 java_shortarray *sas = (java_shortarray*) s;
619                 java_shortarray *sad = (java_shortarray*) d;
620                 if (dp<=sp) 
621                         for (i=0; i<len; i++) sad->data[dp+i] = sas->data[sp+i];
622                 else
623                         for (i=len-1; i>=0; i--) sad->data[dp+i] = sas->data[sp+i];
624                 }
625                 break;
626         case ARRAYTYPE_INT:
627                 {
628                 java_intarray *ias = (java_intarray*) s;
629                 java_intarray *iad = (java_intarray*) d;
630                 if (dp<=sp) 
631                         for (i=0; i<len; i++) iad->data[dp+i] = ias->data[sp+i];
632                 else
633                         for (i=len-1; i>=0; i--) iad->data[dp+i] = ias->data[sp+i];
634                 }
635                 break;
636         case ARRAYTYPE_LONG:
637                 {
638                 java_longarray *las = (java_longarray*) s;
639                 java_longarray *lad = (java_longarray*) d;
640                 if (dp<=sp) 
641                         for (i=0; i<len; i++) lad->data[dp+i] = las->data[sp+i];
642                 else
643                         for (i=len-1; i>=0; i--) lad->data[dp+i] = las->data[sp+i];
644                 }
645                 break;
646         case ARRAYTYPE_FLOAT:
647                 {
648                 java_floatarray *fas = (java_floatarray*) s;
649                 java_floatarray *fad = (java_floatarray*) d;
650                 if (dp<=sp) 
651                         for (i=0; i<len; i++) fad->data[dp+i] = fas->data[sp+i];
652                 else
653                         for (i=len-1; i>=0; i--) fad->data[dp+i] = fas->data[sp+i];
654                 }
655                 break;
656         case ARRAYTYPE_DOUBLE:
657                 {
658                 java_doublearray *das = (java_doublearray*) s;
659                 java_doublearray *dad = (java_doublearray*) d;
660                 if (dp<=sp) 
661                         for (i=0; i<len; i++) dad->data[dp+i] = das->data[sp+i];
662                 else
663                         for (i=len-1; i>=0; i--) dad->data[dp+i] = das->data[sp+i];
664                 }
665                 break;
666         case ARRAYTYPE_OBJECT:
667                 {
668                 java_objectarray *oas = (java_objectarray*) s;
669                 java_objectarray *oad = (java_objectarray*) d;
670                 if (dp<=sp) 
671                         for (i=0; i<len; i++) {
672                                 java_objectheader *o = oas->data[sp+i];
673                                 if (!builtin_canstore(oad, o)) {
674                                         exceptionptr = proto_java_lang_ArrayStoreException;
675                                         return;
676                                         }
677                                 oad->data[dp+i] = o;
678                                 }
679                 else 
680                         for (i=len-1; i>=0; i--) {
681                                 java_objectheader *o = oas->data[sp+i];
682                                 if (!builtin_canstore(oad, o)) {
683                                         exceptionptr = proto_java_lang_ArrayStoreException;
684                                         return;
685                                         }
686                                 oad->data[dp+i] = o;
687                                 }
688                 
689                 }
690                 break;
691         case ARRAYTYPE_ARRAY:
692                 {
693                 java_arrayarray *aas = (java_arrayarray*) s;
694                 java_arrayarray *aad = (java_arrayarray*) d;
695                 if (dp<=sp) 
696                         for (i=0; i<len; i++) {
697                                 java_arrayheader *o = aas->data[sp+i];
698                                 if (!builtin_canstore( (java_objectarray*)aad, 
699                                         (java_objectheader*)o )) {
700                                         exceptionptr = proto_java_lang_ArrayStoreException;
701                                         return;
702                                         }
703                                 aad->data[dp+i] = o;
704                                 }
705                 else
706                         for (i=len-1; i>=0; i--) {
707                                 java_arrayheader *o = aas->data[sp+i];
708                                 if (!builtin_canstore( (java_objectarray*)aad, 
709                                         (java_objectheader*)o )) {
710                                         exceptionptr = proto_java_lang_ArrayStoreException;
711                                         return;
712                                         }
713                                 aad->data[dp+i] = o;
714                                 }
715
716                 }
717                 break;
718
719         default:
720                 panic ("Unknown data type for arraycopy");
721         }
722
723 }
724
725
726 #define MAXPROPS 100
727 static int activeprops = 15;
728
729 static char *proplist[MAXPROPS][2] = {
730         { "java.class.path", NULL },
731         { "java.home", NULL }, 
732         { "user.home", NULL }, 
733         { "user.name", NULL }, 
734         { "user.dir",  NULL }, 
735         
736         { "java.class.version", "45.3" },
737         { "java.version", "cacao:0.2" },
738         { "java.vendor", "CACAO Team" },
739         { "java.vendor.url", "http://www.complang.tuwien.ac.at/java/cacao/" },
740         { "os.arch", "Alpha" },
741         { "os.name", "Linux/Digital Unix" },
742         { "os.version", "4.0/3.2C/V4.0" },
743         { "path.separator", ":" },
744         { "file.separator", "/" },
745         { "line.separator", "\n" }
746 };      
747
748 void attach_property (char *name, char *value)
749 {
750         if (activeprops >= MAXPROPS) panic ("Too many properties defined");
751         proplist[activeprops][0] = name;
752         proplist[activeprops][1] = value;
753         activeprops++;
754 }
755
756
757 struct java_util_Properties* java_lang_System_initProperties (struct java_util_Properties* p)
758 {
759         u4 i;
760         methodinfo *m;
761 #define BUFFERSIZE 200
762         char buffer[BUFFERSIZE];
763         
764         proplist[0][1] = classpath;
765         proplist[1][1] = getenv("JAVAHOME");
766         proplist[2][1] = getenv("HOME");
767         proplist[3][1] = getenv("USER");
768         proplist[4][1] = getcwd(buffer,BUFFERSIZE);
769         
770         if (!p) panic ("initProperties called with NULL-Argument");
771
772         m = class_resolvemethod (
773                 p->header.vftbl->class, 
774                 unicode_new_char ("put"), 
775                 unicode_new_char ("(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;")
776         );
777     if (!m) panic ("Can not find method 'put' for class Properties");
778     
779     for (i=0; i<activeprops; i++) {
780         if (proplist[i][1]==NULL) proplist[i][1]="";
781                 
782         asm_calljavamethod (m,  p, 
783                                 javastring_new_char(proplist[i][0]),
784                                 javastring_new_char(proplist[i][1]),  
785                                         NULL
786                            );
787         }
788
789         return p;
790 }
791
792
793
794
795 /*********************************** java.lang.Thread ***********************************/
796
797 struct java_lang_Thread* java_lang_Thread_currentThread ()
798 {
799   if (runverbose)
800     log_text ("java_lang_Thread_currentThread called");
801 #ifdef USE_THREADS
802         return (struct java_lang_Thread*)currentThread;
803 #else
804         return 0;
805 #endif
806 }
807
808 void java_lang_Thread_yield ()
809 {
810   if (runverbose)
811     log_text ("java_lang_Thread_yield called");
812 #ifdef USE_THREADS
813         yieldThread();
814 #endif
815 }
816
817 void java_lang_Thread_sleep (s8 par1)
818 {
819   if (runverbose)
820     log_text ("java_lang_Thread_sleep called");
821 #ifdef USE_THREADS
822         yieldThread();
823 #endif
824         /* not yet implemented */
825 }
826
827 void java_lang_Thread_start (struct java_lang_Thread* this)
828 {
829   if (runverbose)
830     log_text ("java_lang_Thread_start called");
831 #ifdef USE_THREADS
832         startThread((thread*)this);
833 #endif
834 }
835
836 s4 java_lang_Thread_isAlive (struct java_lang_Thread* this)
837 {
838   if (runverbose)
839     log_text ("java_lang_Thread_isAlive called");
840 #ifdef USE_THREADS
841         return aliveThread((thread*)this);
842 #else
843         return 0;
844 #endif
845 }
846
847 s4 java_lang_Thread_countStackFrames (struct java_lang_Thread* this)
848 {
849   log_text ("java_lang_Thread_countStackFrames called");
850   return 0;         /* not yet implemented */
851 }
852
853 void java_lang_Thread_setPriority0 (struct java_lang_Thread* this, s4 par1)
854 {
855   if (runverbose)
856     log_text ("java_lang_Thread_setPriority0 called");
857 #ifdef USE_THREADS
858   setPriorityThread((thread*)this, par1);
859 #endif
860 }
861
862 void java_lang_Thread_stop0 (struct java_lang_Thread* this, struct java_lang_Object* par1)
863 {
864   if (runverbose)
865     log_text ("java_lang_Thread_stop0 called");
866 #ifdef USE_THREADS
867         if (currentThread == (thread*)this)
868         {
869             log_text("killing");
870             killThread(0);
871             /*
872                 exceptionptr = proto_java_lang_ThreadDeath;
873                 return;
874             */
875         }
876         else
877         {
878                 CONTEXT((thread*)this).flags |= THREAD_FLAGS_KILLED;
879                 resumeThread((thread*)this);
880         }
881 #endif
882 }
883
884 void java_lang_Thread_suspend0 (struct java_lang_Thread* this)
885 {
886   if (runverbose)
887     log_text ("java_lang_Thread_suspend0 called");
888 #ifdef USE_THREADS
889         suspendThread((thread*)this);
890 #endif
891 }
892
893 void java_lang_Thread_resume0 (struct java_lang_Thread* this)
894 {
895   if (runverbose)
896     log_text ("java_lang_Thread_resume0 called");
897 #ifdef USE_THREADS
898         resumeThread((thread*)this);
899 #endif
900 }
901
902
903
904 /************************************ java.lang.Throwable *********************************/
905
906 void java_lang_Throwable_printStackTrace0 (struct java_lang_Throwable* this, struct java_io_PrintStream* par1)
907 {
908         log_text ("java_lang_Throwable_printStackTrace0 called");
909         return;
910 }
911
912 struct java_lang_Throwable* java_lang_Throwable_fillInStackTrace (struct java_lang_Throwable *this)
913 {
914         this -> detailMessage = 
915           (java_lang_String*) (javastring_new_char ("no backtrace info!") );
916         return this;
917 }
918