1 /* -*- mode: c; tab-width: 4; c-basic-offset: 4 -*- */
2 /****************************** nat/lang.c *************************************
4 Copyright (c) 1997 A. Krall, R. Grafl, M. Gschwind, M. Probst
6 See file COPYRIGHT for information on usage and disclaimer of warranties
8 Contains the native functions for class java.lang.
10 Authors: Reinhard Grafl EMAIL: cacao@complang.tuwien.ac.at
11 Mark Probst EMAIL: cacao@complang.tuwien.ac.at
13 Last Change: 1997/06/10
15 *******************************************************************************/
21 #include "../threads/thread.h" /* schani */
22 #include "../threads/locks.h"
24 static void use_class_as_object (classinfo *c)
26 c->header.vftbl = class_java_lang_Class -> vftbl;
30 /************************************** java.lang.Object ***********************************/
32 struct java_lang_Class* java_lang_Object_getClass (struct java_lang_Object* this)
34 classinfo *c = this->header.vftbl -> class;
35 use_class_as_object (c);
36 return (java_lang_Class*) c;
39 s4 java_lang_Object_hashCode (struct java_lang_Object* this)
41 return ((char*) this) - ((char*) 0);
45 struct java_lang_Object* java_lang_Object_clone (struct java_lang_Object* this)
48 java_lang_Object *new;
50 if (((java_objectheader*)this)->vftbl->class == class_array)
52 static u4 multiplicator[10];
53 static int is_initialized = 0;
55 java_arrayheader *array = (java_arrayheader*)this;
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*);
73 size = sizeof(java_arrayheader)
74 + array->size * multiplicator[array->arraytype];
76 new = (java_lang_Object*)heap_allocate(size, false, NULL);
77 memcpy(new, this, size);
83 if (! builtin_instanceof ((java_objectheader*) this, class_java_lang_Cloneable) ) {
84 exceptionptr = native_new_and_init (class_java_lang_CloneNotSupportedException);
88 c = this -> header.vftbl -> class;
89 new = (java_lang_Object*) builtin_new (c);
91 exceptionptr = proto_java_lang_OutOfMemoryError;
95 memcpy (new, this, c->instancesize);
100 void java_lang_Object_notify (struct java_lang_Object* this)
103 log_text ("java_lang_Object_notify called");
106 signal_cond_for_object(&this->header);
110 void java_lang_Object_notifyAll (struct java_lang_Object* this)
113 log_text ("java_lang_Object_notifyAll called");
116 broadcast_cond_for_object(&this->header);
120 void java_lang_Object_wait (struct java_lang_Object* this, s8 time)
123 log_text ("java_lang_Object_wait called");
126 wait_cond_for_object(&this->header, time);
131 /********************************** java.lang.Class **************************************/
134 struct java_lang_Class* java_lang_Class_forName (struct java_lang_String* s)
136 java_chararray *a,*b;
142 if (!(a = s->value) ) return NULL;
143 b = builtin_newarray_char (s->count);
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];
149 u = unicode_new_u2 (b->data, b->header.size);
153 loader_initclasses ();
157 native_new_and_init (class_java_lang_ClassNotFoundException);
164 use_class_as_object (c);
165 return (java_lang_Class*) c;
168 struct java_lang_Object* java_lang_Class_newInstance (struct java_lang_Class* this)
170 java_objectheader *o = native_new_and_init ((classinfo*) this);
173 native_new_and_init (class_java_lang_InstantiationException);
175 return (java_lang_Object*) o;
178 struct java_lang_String* java_lang_Class_getName (struct java_lang_Class* this)
181 classinfo *c = (classinfo*) this;
182 java_lang_String *s = (java_lang_String*) javastring_new(c->name);
186 for (i=0; i<s->value->header.size; i++) {
187 if (s->value->data[i] == '/') s->value->data[i] = '.';
193 struct java_lang_Class* java_lang_Class_getSuperclass (struct java_lang_Class* this)
195 classinfo *c = ((classinfo*) this) -> super;
198 use_class_as_object (c);
199 return (java_lang_Class*) c;
202 java_objectarray* java_lang_Class_getInterfaces (struct java_lang_Class* this)
204 classinfo *c = (classinfo*) this;
206 java_objectarray *a = builtin_anewarray (c->interfacescount, class_java_lang_Class);
208 for (i=0; i<c->interfacescount; i++) {
209 use_class_as_object (c->interfaces[i]);
211 a->data[i] = (java_objectheader*) c->interfaces[i];
216 struct java_lang_ClassLoader* java_lang_Class_getClassLoader (struct java_lang_Class* this)
218 log_text ("java_lang_Class_getClassLoader called");
222 s4 java_lang_Class_isInterface (struct java_lang_Class* this)
224 classinfo *c = (classinfo*) this;
225 if (c->flags & ACC_INTERFACE) return 1;
229 /************************************ java.lang.ClassLoader *******************************/
232 struct java_lang_Class* java_lang_ClassLoader_defineClass (struct java_lang_ClassLoader* this, java_bytearray* par1, s4 par2, s4 par3)
234 log_text ("java_lang_ClassLoader_defineClass called");
237 void java_lang_ClassLoader_resolveClass (struct java_lang_ClassLoader* this, struct java_lang_Class* par1)
239 log_text ("java_lang_ClassLoader_resolveClass called");
241 struct java_lang_Class* java_lang_ClassLoader_findSystemClass (struct java_lang_ClassLoader* this, struct java_lang_String* par1)
243 log_text ("java_lang_ClassLoader_findSystemClass called");
246 void java_lang_ClassLoader_init (struct java_lang_ClassLoader* this)
248 log_text ("java_lang_ClassLoader_init called");
250 struct java_lang_Class* java_lang_ClassLoader_findSystemClass0 (struct java_lang_ClassLoader* this, struct java_lang_String* par1)
252 log_text ("java_lang_ClassLoader_findSystemClass0 called");
256 struct java_lang_Class* java_lang_ClassLoader_defineClass0 (struct java_lang_ClassLoader* this, java_bytearray* par1, s4 par2, s4 par3)
258 log_text ("java_lang_ClassLoader_defineClass0 called");
261 void java_lang_ClassLoader_resolveClass0 (struct java_lang_ClassLoader* this, struct java_lang_Class* par1)
263 log_text ("java_lang_ClassLoader_resolveClass0 called");
267 /************************************** java.lang.Compiler *******************************/
269 void java_lang_Compiler_initialize ()
271 log_text ("java_lang_Compiler_initialize called");
273 s4 java_lang_Compiler_compileClass (struct java_lang_Class* par1)
275 log_text ("java_lang_Compiler_compileClass called");
278 s4 java_lang_Compiler_compileClasses (struct java_lang_String* par1)
280 log_text ("java_lang_Compiler_compileClasses called");
283 struct java_lang_Object* java_lang_Compiler_command (struct java_lang_Object* par1)
285 log_text ("java_lang_Compiler_command called");
288 void java_lang_Compiler_enable ()
290 log_text ("java_lang_Compiler_enable called");
292 void java_lang_Compiler_disable ()
294 log_text ("java_lang_Compiler_disable called");
298 /******************************** java.lang.Double **************************************/
300 struct java_lang_String* java_lang_Double_toString (double par1)
303 sprintf (b, "%-.6g", par1);
304 return (java_lang_String*) javastring_new_char (b);
306 struct java_lang_Double* java_lang_Double_valueOf (struct java_lang_String* par1)
309 java_lang_Double *d = (java_lang_Double*) builtin_new (class_java_lang_Double);
311 sscanf (javastring_tochar((java_objectheader*) par1), "%f", &val);
317 s8 java_lang_Double_doubleToLongBits (double par1)
321 memcpy ((u1*) &l, (u1*) &d, 8);
324 double java_lang_Double_longBitsToDouble (s8 par1)
328 memcpy ((u1*) &d, (u1*) &l, 8);
332 /******************************** java.lang.Float ***************************************/
334 struct java_lang_String* java_lang_Float_toString (float par1)
337 sprintf (b, "%-.6g", (double) par1);
338 return (java_lang_String*) javastring_new_char (b);
340 struct java_lang_Float* java_lang_Float_valueOf (struct java_lang_String* par1)
343 java_lang_Float *d = (java_lang_Float*) builtin_new (class_java_lang_Float);
345 sscanf (javastring_tochar((java_objectheader*) par1), "%f", &val);
351 s4 java_lang_Float_floatToIntBits (float par1)
355 memcpy ((u1*) &i, (u1*) &f, 4);
358 float java_lang_Float_intBitsToFloat (s4 par1)
362 memcpy ((u1*) &f, (u1*) &i, 4);
367 /******************************** java.lang.Math ****************************************/
369 double java_lang_Math_sin (double par1)
374 double java_lang_Math_cos (double par1)
379 double java_lang_Math_tan (double par1)
384 double java_lang_Math_asin (double par1)
389 double java_lang_Math_acos (double par1)
394 double java_lang_Math_atan (double par1)
399 double java_lang_Math_exp (double par1)
404 double java_lang_Math_log (double par1)
407 exceptionptr = proto_java_lang_ArithmeticException;
413 double java_lang_Math_sqrt (double par1)
416 exceptionptr = proto_java_lang_ArithmeticException;
422 static u8 dbl_nan = 0xffffffffffffffffL ;
424 #define DBL_NAN (*((double*) (&dbl_nan)))
426 double java_lang_Math_IEEEremainder (double a, double b)
429 if (finite(a) && finite(b)) {
432 return a - floor(d) * b;
442 double java_lang_Math_ceil (double par1)
447 double java_lang_Math_floor (double par1)
452 double java_lang_Math_rint (double par1)
454 panic ("native Methode java_lang_rint not implemented yet");
458 double java_lang_Math_atan2 (double par1, double par2)
460 return atan2(par1,par2);
463 double java_lang_Math_pow (double par1, double par2)
465 return pow(par1,par2);
469 /******************************* java.lang.Runtime **************************************/
471 void java_lang_Runtime_exitInternal (struct java_lang_Runtime* this, s4 par1)
473 cacao_shutdown (par1);
475 struct java_lang_Process* java_lang_Runtime_execInternal (struct java_lang_Runtime* this, java_objectarray* par1, java_objectarray* par2)
477 log_text ("java_lang_Runtime_execInternal called");
480 s8 java_lang_Runtime_freeMemory (struct java_lang_Runtime* this)
482 log_text ("java_lang_Runtime_freeMemory called");
483 return builtin_i2l (0);
485 s8 java_lang_Runtime_totalMemory (struct java_lang_Runtime* this)
487 log_text ("java_lang_Runtime_totalMemory called");
488 return builtin_i2l (0);
490 void java_lang_Runtime_gc (struct java_lang_Runtime* this)
494 void java_lang_Runtime_runFinalization (struct java_lang_Runtime* this)
496 log_text ("java_lang_Runtime_runFinalization called");
498 void java_lang_Runtime_traceInstructions (struct java_lang_Runtime* this, s4 par1)
500 log_text ("java_lang_Runtime_traceInstructions called");
502 void java_lang_Runtime_traceMethodCalls (struct java_lang_Runtime* this, s4 par1)
504 log_text ("java_lang_Runtime_traceMethodCalls called");
506 struct java_lang_String* java_lang_Runtime_initializeLinkerInternal (struct java_lang_Runtime* this)
508 log_text ("java_lang_Runtime_initializeLinkerInternal called");
509 return (java_lang_String*)javastring_new_char(".");
511 struct java_lang_String* java_lang_Runtime_buildLibName (struct java_lang_Runtime* this, struct java_lang_String* par1, struct java_lang_String* par2)
513 log_text ("java_lang_Runtime_buildLibName called");
516 s4 java_lang_Runtime_loadFileInternal (struct java_lang_Runtime* this, struct java_lang_String* par1)
518 log_text ("java_lang_Runtime_loadFileInternal called");
523 /**************************************** java.lang.SecurityManager ***********************/
525 java_objectarray* java_lang_SecurityManager_getClassContext (struct java_lang_SecurityManager* this)
527 log_text ("called: java_lang_SecurityManager_getClassContext");
530 struct java_lang_ClassLoader* java_lang_SecurityManager_currentClassLoader (struct java_lang_SecurityManager* this)
532 log_text ("called: java_lang_SecurityManager_currentClassLoader");
535 s4 java_lang_SecurityManager_classDepth (struct java_lang_SecurityManager* this, struct java_lang_String* par1)
537 log_text ("called: java_lang_SecurityManager_classDepth");
540 s4 java_lang_SecurityManager_classLoaderDepth (struct java_lang_SecurityManager* this)
542 log_text ("called: java_lang_SecurityManager_classLoaderDepth");
548 /*********************************** java.lang.System ************************************/
550 s8 java_lang_System_currentTimeMillis ()
554 (void) gettimeofday(&tv, NULL);
555 return ((s8) tv.tv_sec) * 1000 + tv.tv_usec / 1000;
559 void java_lang_System_arraycopy (struct java_lang_Object* source, s4 sp,
560 struct java_lang_Object* dest, s4 dp, s4 len)
563 java_arrayheader *s = (java_arrayheader*) source;
564 java_arrayheader *d = (java_arrayheader*) dest;
566 if ( (!s) || (!d) ) {
567 exceptionptr = proto_java_lang_NullPointerException;
570 if ( (s->objheader.vftbl->class != class_array) || (d->objheader.vftbl->class != class_array) ) {
571 exceptionptr = proto_java_lang_ArrayStoreException;
575 if (s->arraytype != d->arraytype) {
576 exceptionptr = proto_java_lang_ArrayStoreException;
580 if ((sp<0) || (sp+len > s->size) || (dp<0) || (dp+len > d->size)) {
581 exceptionptr = proto_java_lang_ArrayIndexOutOfBoundsException;
585 switch (s->arraytype) {
588 java_bytearray *bas = (java_bytearray*) s;
589 java_bytearray *bad = (java_bytearray*) d;
591 for (i=0; i<len; i++) bad->data[dp+i] = bas->data[sp+i];
593 for (i=len-1; i>=0; i--) bad->data[dp+i] = bas->data[sp+i];
596 case ARRAYTYPE_BOOLEAN:
598 java_booleanarray *bas = (java_booleanarray*) s;
599 java_booleanarray *bad = (java_booleanarray*) d;
601 for (i=0; i<len; i++) bad->data[dp+i] = bas->data[sp+i];
603 for (i=len-1; i>=0; i--) bad->data[dp+i] = bas->data[sp+i];
608 java_chararray *cas = (java_chararray*) s;
609 java_chararray *cad = (java_chararray*) d;
611 for (i=0; i<len; i++) cad->data[dp+i] = cas->data[sp+i];
613 for (i=len-1; i>=0; i--) cad->data[dp+i] = cas->data[sp+i];
616 case ARRAYTYPE_SHORT:
618 java_shortarray *sas = (java_shortarray*) s;
619 java_shortarray *sad = (java_shortarray*) d;
621 for (i=0; i<len; i++) sad->data[dp+i] = sas->data[sp+i];
623 for (i=len-1; i>=0; i--) sad->data[dp+i] = sas->data[sp+i];
628 java_intarray *ias = (java_intarray*) s;
629 java_intarray *iad = (java_intarray*) d;
631 for (i=0; i<len; i++) iad->data[dp+i] = ias->data[sp+i];
633 for (i=len-1; i>=0; i--) iad->data[dp+i] = ias->data[sp+i];
638 java_longarray *las = (java_longarray*) s;
639 java_longarray *lad = (java_longarray*) d;
641 for (i=0; i<len; i++) lad->data[dp+i] = las->data[sp+i];
643 for (i=len-1; i>=0; i--) lad->data[dp+i] = las->data[sp+i];
646 case ARRAYTYPE_FLOAT:
648 java_floatarray *fas = (java_floatarray*) s;
649 java_floatarray *fad = (java_floatarray*) d;
651 for (i=0; i<len; i++) fad->data[dp+i] = fas->data[sp+i];
653 for (i=len-1; i>=0; i--) fad->data[dp+i] = fas->data[sp+i];
656 case ARRAYTYPE_DOUBLE:
658 java_doublearray *das = (java_doublearray*) s;
659 java_doublearray *dad = (java_doublearray*) d;
661 for (i=0; i<len; i++) dad->data[dp+i] = das->data[sp+i];
663 for (i=len-1; i>=0; i--) dad->data[dp+i] = das->data[sp+i];
666 case ARRAYTYPE_OBJECT:
668 java_objectarray *oas = (java_objectarray*) s;
669 java_objectarray *oad = (java_objectarray*) d;
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;
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;
691 case ARRAYTYPE_ARRAY:
693 java_arrayarray *aas = (java_arrayarray*) s;
694 java_arrayarray *aad = (java_arrayarray*) d;
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;
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;
720 panic ("Unknown data type for arraycopy");
727 static int activeprops = 15;
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 },
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" }
748 void attach_property (char *name, char *value)
750 if (activeprops >= MAXPROPS) panic ("Too many properties defined");
751 proplist[activeprops][0] = name;
752 proplist[activeprops][1] = value;
757 struct java_util_Properties* java_lang_System_initProperties (struct java_util_Properties* p)
761 #define BUFFERSIZE 200
762 char buffer[BUFFERSIZE];
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);
770 if (!p) panic ("initProperties called with NULL-Argument");
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;")
777 if (!m) panic ("Can not find method 'put' for class Properties");
779 for (i=0; i<activeprops; i++) {
780 if (proplist[i][1]==NULL) proplist[i][1]="";
782 asm_calljavamethod (m, p,
783 javastring_new_char(proplist[i][0]),
784 javastring_new_char(proplist[i][1]),
795 /*********************************** java.lang.Thread ***********************************/
797 struct java_lang_Thread* java_lang_Thread_currentThread ()
800 log_text ("java_lang_Thread_currentThread called");
802 return (struct java_lang_Thread*)currentThread;
808 void java_lang_Thread_yield ()
811 log_text ("java_lang_Thread_yield called");
817 void java_lang_Thread_sleep (s8 par1)
820 log_text ("java_lang_Thread_sleep called");
824 /* not yet implemented */
827 void java_lang_Thread_start (struct java_lang_Thread* this)
830 log_text ("java_lang_Thread_start called");
832 startThread((thread*)this);
836 s4 java_lang_Thread_isAlive (struct java_lang_Thread* this)
839 log_text ("java_lang_Thread_isAlive called");
841 return aliveThread((thread*)this);
847 s4 java_lang_Thread_countStackFrames (struct java_lang_Thread* this)
849 log_text ("java_lang_Thread_countStackFrames called");
850 return 0; /* not yet implemented */
853 void java_lang_Thread_setPriority0 (struct java_lang_Thread* this, s4 par1)
856 log_text ("java_lang_Thread_setPriority0 called");
858 setPriorityThread((thread*)this, par1);
862 void java_lang_Thread_stop0 (struct java_lang_Thread* this, struct java_lang_Object* par1)
865 log_text ("java_lang_Thread_stop0 called");
867 if (currentThread == (thread*)this)
872 exceptionptr = proto_java_lang_ThreadDeath;
878 CONTEXT((thread*)this).flags |= THREAD_FLAGS_KILLED;
879 resumeThread((thread*)this);
884 void java_lang_Thread_suspend0 (struct java_lang_Thread* this)
887 log_text ("java_lang_Thread_suspend0 called");
889 suspendThread((thread*)this);
893 void java_lang_Thread_resume0 (struct java_lang_Thread* this)
896 log_text ("java_lang_Thread_resume0 called");
898 resumeThread((thread*)this);
904 /************************************ java.lang.Throwable *********************************/
906 void java_lang_Throwable_printStackTrace0 (struct java_lang_Throwable* this, struct java_io_PrintStream* par1)
908 log_text ("java_lang_Throwable_printStackTrace0 called");
912 struct java_lang_Throwable* java_lang_Throwable_fillInStackTrace (struct java_lang_Throwable *this)
914 this -> detailMessage =
915 (java_lang_String*) (javastring_new_char ("no backtrace info!") );