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
12 Philipp Tomsich EMAIL: cacao@complang.tuwien.ac.at
14 Last Change: $Id: lang.c 115 1999-01-20 01:52:45Z phil $
16 *******************************************************************************/
23 #include "../threads/thread.h" /* schani */
24 #include "../threads/locks.h"
26 static void use_class_as_object (classinfo *c)
28 c->header.vftbl = class_java_lang_Class -> vftbl;
32 /************************************** java.lang.Object ***********************************/
34 struct java_lang_Class* java_lang_Object_getClass (struct java_lang_Object* this)
36 classinfo *c = this->header.vftbl -> class;
37 use_class_as_object (c);
38 return (java_lang_Class*) c;
41 s4 java_lang_Object_hashCode (struct java_lang_Object* this)
43 return ((char*) this) - ((char*) 0);
47 struct java_lang_Object* java_lang_Object_clone (struct java_lang_Object* this)
50 java_lang_Object *new;
52 if (((java_objectheader*)this)->vftbl->class == class_array)
54 static u4 multiplicator[10];
55 static int is_initialized = 0;
57 java_arrayheader *array = (java_arrayheader*)this;
62 multiplicator[ARRAYTYPE_INT] = sizeof(s4);
63 multiplicator[ARRAYTYPE_LONG] = sizeof(s8);
64 multiplicator[ARRAYTYPE_FLOAT] = sizeof(float);
65 multiplicator[ARRAYTYPE_DOUBLE] = sizeof(double);
66 multiplicator[ARRAYTYPE_BYTE] = sizeof(s1);
67 multiplicator[ARRAYTYPE_CHAR] = sizeof(u2);
68 multiplicator[ARRAYTYPE_SHORT] = sizeof(s2);
69 multiplicator[ARRAYTYPE_BOOLEAN] = sizeof(u1);
70 multiplicator[ARRAYTYPE_OBJECT] = sizeof(void*);
71 multiplicator[ARRAYTYPE_ARRAY] = sizeof(void*);
75 size = sizeof(java_arrayheader)
76 + array->size * multiplicator[array->arraytype];
78 new = (java_lang_Object*)heap_allocate(size, false, NULL);
79 memcpy(new, this, size);
85 if (! builtin_instanceof ((java_objectheader*) this, class_java_lang_Cloneable) ) {
86 exceptionptr = native_new_and_init (class_java_lang_CloneNotSupportedException);
90 c = this -> header.vftbl -> class;
91 new = (java_lang_Object*) builtin_new (c);
93 exceptionptr = proto_java_lang_OutOfMemoryError;
97 memcpy (new, this, c->instancesize);
102 void java_lang_Object_notify (struct java_lang_Object* this)
105 log_text ("java_lang_Object_notify called");
108 signal_cond_for_object(&this->header);
112 void java_lang_Object_notifyAll (struct java_lang_Object* this)
115 log_text ("java_lang_Object_notifyAll called");
118 broadcast_cond_for_object(&this->header);
122 void java_lang_Object_wait (struct java_lang_Object* this, s8 time)
125 log_text ("java_lang_Object_wait called");
128 wait_cond_for_object(&this->header, time);
133 /********************************** java.lang.Class **************************************/
136 struct java_lang_Class* java_lang_Class_forName (struct java_lang_String* s)
138 java_chararray *a,*b;
144 if (!(a = s->value) ) return NULL;
145 b = builtin_newarray_char (s->count);
147 for (i=0; i<s->count; i++) {
148 if (a->data[s->offset+i]=='.') b->data[i] = '/';
149 else b->data[i] = a->data[s->offset+i];
151 u = unicode_new_u2 (b->data, b->header.size);
155 loader_initclasses ();
159 native_new_and_init (class_java_lang_ClassNotFoundException);
166 use_class_as_object (c);
167 return (java_lang_Class*) c;
170 struct java_lang_Object* java_lang_Class_newInstance (struct java_lang_Class* this)
172 java_objectheader *o = native_new_and_init ((classinfo*) this);
175 native_new_and_init (class_java_lang_InstantiationException);
177 return (java_lang_Object*) o;
180 struct java_lang_String* java_lang_Class_getName (struct java_lang_Class* this)
183 classinfo *c = (classinfo*) this;
184 java_lang_String *s = (java_lang_String*) javastring_new(c->name);
188 for (i=0; i<s->value->header.size; i++) {
189 if (s->value->data[i] == '/') s->value->data[i] = '.';
195 struct java_lang_Class* java_lang_Class_getSuperclass (struct java_lang_Class* this)
197 classinfo *c = ((classinfo*) this) -> super;
200 use_class_as_object (c);
201 return (java_lang_Class*) c;
204 java_objectarray* java_lang_Class_getInterfaces (struct java_lang_Class* this)
206 classinfo *c = (classinfo*) this;
208 java_objectarray *a = builtin_anewarray (c->interfacescount, class_java_lang_Class);
210 for (i=0; i<c->interfacescount; i++) {
211 use_class_as_object (c->interfaces[i]);
213 a->data[i] = (java_objectheader*) c->interfaces[i];
218 struct java_lang_ClassLoader* java_lang_Class_getClassLoader (struct java_lang_Class* this)
220 log_text ("java_lang_Class_getClassLoader called");
224 s4 java_lang_Class_isInterface (struct java_lang_Class* this)
226 classinfo *c = (classinfo*) this;
227 if (c->flags & ACC_INTERFACE) return 1;
231 /************************************ java.lang.ClassLoader *******************************/
234 struct java_lang_Class* java_lang_ClassLoader_defineClass (struct java_lang_ClassLoader* this, java_bytearray* par1, s4 par2, s4 par3)
236 log_text ("java_lang_ClassLoader_defineClass called");
239 void java_lang_ClassLoader_resolveClass (struct java_lang_ClassLoader* this, struct java_lang_Class* par1)
241 log_text ("java_lang_ClassLoader_resolveClass called");
243 struct java_lang_Class* java_lang_ClassLoader_findSystemClass (struct java_lang_ClassLoader* this, struct java_lang_String* par1)
245 log_text ("java_lang_ClassLoader_findSystemClass called");
248 void java_lang_ClassLoader_init (struct java_lang_ClassLoader* this)
250 log_text ("java_lang_ClassLoader_init called");
252 struct java_lang_Class* java_lang_ClassLoader_findSystemClass0 (struct java_lang_ClassLoader* this, struct java_lang_String* par1)
254 log_text ("java_lang_ClassLoader_findSystemClass0 called");
258 struct java_lang_Class* java_lang_ClassLoader_defineClass0 (struct java_lang_ClassLoader* this, java_bytearray* par1, s4 par2, s4 par3)
260 log_text ("java_lang_ClassLoader_defineClass0 called");
263 void java_lang_ClassLoader_resolveClass0 (struct java_lang_ClassLoader* this, struct java_lang_Class* par1)
265 log_text ("java_lang_ClassLoader_resolveClass0 called");
269 /************************************** java.lang.Compiler *******************************/
271 void java_lang_Compiler_initialize ()
273 log_text ("java_lang_Compiler_initialize called");
275 s4 java_lang_Compiler_compileClass (struct java_lang_Class* par1)
277 log_text ("java_lang_Compiler_compileClass called");
280 s4 java_lang_Compiler_compileClasses (struct java_lang_String* par1)
282 log_text ("java_lang_Compiler_compileClasses called");
285 struct java_lang_Object* java_lang_Compiler_command (struct java_lang_Object* par1)
287 log_text ("java_lang_Compiler_command called");
290 void java_lang_Compiler_enable ()
292 log_text ("java_lang_Compiler_enable called");
294 void java_lang_Compiler_disable ()
296 log_text ("java_lang_Compiler_disable called");
300 /******************************** java.lang.Double **************************************/
302 struct java_lang_String* java_lang_Double_toString (double par1)
305 sprintf (b, "%-.6g", par1);
306 return (java_lang_String*) javastring_new_char (b);
308 struct java_lang_Double* java_lang_Double_valueOf (struct java_lang_String* par1)
311 java_lang_Double *d = (java_lang_Double*) builtin_new (class_java_lang_Double);
313 sscanf (javastring_tochar((java_objectheader*) par1), "%f", &val);
319 s8 java_lang_Double_doubleToLongBits (double par1)
323 memcpy ((u1*) &l, (u1*) &d, 8);
326 double java_lang_Double_longBitsToDouble (s8 par1)
330 memcpy ((u1*) &d, (u1*) &l, 8);
334 /******************************** java.lang.Float ***************************************/
336 struct java_lang_String* java_lang_Float_toString (float par1)
339 sprintf (b, "%-.6g", (double) par1);
340 return (java_lang_String*) javastring_new_char (b);
342 struct java_lang_Float* java_lang_Float_valueOf (struct java_lang_String* par1)
345 java_lang_Float *d = (java_lang_Float*) builtin_new (class_java_lang_Float);
347 sscanf (javastring_tochar((java_objectheader*) par1), "%f", &val);
353 s4 java_lang_Float_floatToIntBits (float par1)
357 memcpy ((u1*) &i, (u1*) &f, 4);
360 float java_lang_Float_intBitsToFloat (s4 par1)
364 memcpy ((u1*) &f, (u1*) &i, 4);
369 /******************************** java.lang.Math ****************************************/
371 double java_lang_Math_sin (double par1)
376 double java_lang_Math_cos (double par1)
381 double java_lang_Math_tan (double par1)
386 double java_lang_Math_asin (double par1)
391 double java_lang_Math_acos (double par1)
396 double java_lang_Math_atan (double par1)
401 double java_lang_Math_exp (double par1)
406 double java_lang_Math_log (double par1)
409 exceptionptr = proto_java_lang_ArithmeticException;
415 double java_lang_Math_sqrt (double par1)
418 exceptionptr = proto_java_lang_ArithmeticException;
424 static u8 dbl_nan = 0xffffffffffffffffL ;
426 #define DBL_NAN (*((double*) (&dbl_nan)))
428 double java_lang_Math_IEEEremainder (double a, double b)
431 if (finite(a) && finite(b)) {
434 return a - floor(d) * b;
444 double java_lang_Math_ceil (double par1)
449 double java_lang_Math_floor (double par1)
454 double java_lang_Math_rint (double par1)
456 return rint(par1); /* phil, 1998/12/12 */
459 double java_lang_Math_atan2 (double par1, double par2)
461 return atan2(par1,par2);
464 double java_lang_Math_pow (double par1, double par2)
466 return pow(par1,par2);
470 /******************************* java.lang.Runtime **************************************/
472 void java_lang_Runtime_exitInternal (struct java_lang_Runtime* this, s4 par1)
474 cacao_shutdown (par1);
476 struct java_lang_Process* java_lang_Runtime_execInternal (struct java_lang_Runtime* this, java_objectarray* par1, java_objectarray* par2)
478 log_text ("java_lang_Runtime_execInternal called");
481 s8 java_lang_Runtime_freeMemory (struct java_lang_Runtime* this)
483 log_text ("java_lang_Runtime_freeMemory called");
484 return builtin_i2l (0);
486 s8 java_lang_Runtime_totalMemory (struct java_lang_Runtime* this)
488 log_text ("java_lang_Runtime_totalMemory called");
489 return builtin_i2l (0);
491 void java_lang_Runtime_gc (struct java_lang_Runtime* this)
495 void java_lang_Runtime_runFinalization (struct java_lang_Runtime* this)
497 log_text ("java_lang_Runtime_runFinalization called");
499 void java_lang_Runtime_traceInstructions (struct java_lang_Runtime* this, s4 par1)
501 log_text ("java_lang_Runtime_traceInstructions called");
503 void java_lang_Runtime_traceMethodCalls (struct java_lang_Runtime* this, s4 par1)
505 log_text ("java_lang_Runtime_traceMethodCalls called");
507 struct java_lang_String* java_lang_Runtime_initializeLinkerInternal (struct java_lang_Runtime* this)
509 log_text ("java_lang_Runtime_initializeLinkerInternal called");
510 return (java_lang_String*)javastring_new_char(".");
512 struct java_lang_String* java_lang_Runtime_buildLibName (struct java_lang_Runtime* this, struct java_lang_String* par1, struct java_lang_String* par2)
514 log_text ("java_lang_Runtime_buildLibName called");
517 s4 java_lang_Runtime_loadFileInternal (struct java_lang_Runtime* this, struct java_lang_String* par1)
519 log_text ("java_lang_Runtime_loadFileInternal called");
524 /**************************************** java.lang.SecurityManager ***********************/
526 java_objectarray* java_lang_SecurityManager_getClassContext (struct java_lang_SecurityManager* this)
528 log_text ("called: java_lang_SecurityManager_getClassContext");
531 struct java_lang_ClassLoader* java_lang_SecurityManager_currentClassLoader (struct java_lang_SecurityManager* this)
533 log_text ("called: java_lang_SecurityManager_currentClassLoader");
536 s4 java_lang_SecurityManager_classDepth (struct java_lang_SecurityManager* this, struct java_lang_String* par1)
538 log_text ("called: java_lang_SecurityManager_classDepth");
541 s4 java_lang_SecurityManager_classLoaderDepth (struct java_lang_SecurityManager* this)
543 log_text ("called: java_lang_SecurityManager_classLoaderDepth");
549 /*********************************** java.lang.System ************************************/
551 s8 java_lang_System_currentTimeMillis ()
555 (void) gettimeofday(&tv, NULL);
556 return ((s8) tv.tv_sec) * 1000 + tv.tv_usec / 1000;
560 void java_lang_System_arraycopy (struct java_lang_Object* source, s4 sp,
561 struct java_lang_Object* dest, s4 dp, s4 len)
564 java_arrayheader *s = (java_arrayheader*) source;
565 java_arrayheader *d = (java_arrayheader*) dest;
567 if (((s == NULL) | (d == NULL)) != 0) {
568 exceptionptr = proto_java_lang_NullPointerException;
572 if (s->objheader.vftbl->class != class_array) {
573 exceptionptr = proto_java_lang_ArrayStoreException;
577 if (((sp<0) | (sp+len > s->size) | (dp<0) | (dp+len > d->size)) != 0) {
578 exceptionptr = proto_java_lang_ArrayIndexOutOfBoundsException;
582 switch (s->arraytype) {
584 if (s->objheader.vftbl != d->objheader.vftbl) {
585 exceptionptr = proto_java_lang_ArrayStoreException;
588 memmove(((java_bytearray*) d)->data + dp,
589 ((java_bytearray*) s)->data + sp,
592 case ARRAYTYPE_BOOLEAN:
593 if (s->objheader.vftbl != d->objheader.vftbl) {
594 exceptionptr = proto_java_lang_ArrayStoreException;
597 memmove(((java_booleanarray*) d)->data + dp,
598 ((java_booleanarray*) s)->data + sp,
602 if (s->objheader.vftbl != d->objheader.vftbl) {
603 exceptionptr = proto_java_lang_ArrayStoreException;
606 memmove(((java_chararray*) d)->data + dp,
607 ((java_chararray*) s)->data + sp,
608 (size_t) len * sizeof(u2));
610 case ARRAYTYPE_SHORT:
611 if (s->objheader.vftbl != d->objheader.vftbl) {
612 exceptionptr = proto_java_lang_ArrayStoreException;
615 memmove(((java_shortarray*) d)->data + dp,
616 ((java_shortarray*) s)->data + sp,
617 (size_t) len * sizeof(s2));
620 if (s->objheader.vftbl != d->objheader.vftbl) {
621 exceptionptr = proto_java_lang_ArrayStoreException;
624 memmove(((java_intarray*) d)->data + dp,
625 ((java_intarray*) s)->data + sp,
626 (size_t) len * sizeof(s4));
629 if (s->objheader.vftbl != d->objheader.vftbl) {
630 exceptionptr = proto_java_lang_ArrayStoreException;
633 memmove(((java_longarray*) d)->data + dp,
634 ((java_longarray*) s)->data + sp,
635 (size_t) len * sizeof(s8));
637 case ARRAYTYPE_FLOAT:
638 if (s->objheader.vftbl != d->objheader.vftbl) {
639 exceptionptr = proto_java_lang_ArrayStoreException;
642 memmove(((java_floatarray*) d)->data + dp,
643 ((java_floatarray*) s)->data + sp,
644 (size_t) len * sizeof(float));
646 case ARRAYTYPE_DOUBLE:
647 if (s->objheader.vftbl != d->objheader.vftbl) {
648 exceptionptr = proto_java_lang_ArrayStoreException;
651 memmove(((java_doublearray*) d)->data + dp,
652 ((java_doublearray*) s)->data + sp,
653 (size_t) len * sizeof(double));
655 case ARRAYTYPE_OBJECT:
657 java_objectarray *oas = (java_objectarray*) s;
658 java_objectarray *oad = (java_objectarray*) d;
660 if (d->objheader.vftbl->class != class_array) {
661 exceptionptr = proto_java_lang_ArrayStoreException;
664 if (s->arraytype != d->arraytype) {
665 exceptionptr = proto_java_lang_ArrayStoreException;
670 for (i=0; i<len; i++) {
671 java_objectheader *o = oas->data[sp+i];
672 if (!builtin_canstore(oad, o)) {
673 exceptionptr = proto_java_lang_ArrayStoreException;
679 for (i=len-1; i>=0; i--) {
680 java_objectheader *o = oas->data[sp+i];
681 if (!builtin_canstore(oad, o)) {
682 exceptionptr = proto_java_lang_ArrayStoreException;
690 case ARRAYTYPE_ARRAY:
692 java_arrayarray *aas = (java_arrayarray*) s;
693 java_arrayarray *aad = (java_arrayarray*) d;
695 if (d->objheader.vftbl->class != class_array) {
696 exceptionptr = proto_java_lang_ArrayStoreException;
699 if (s->arraytype != d->arraytype) {
700 exceptionptr = proto_java_lang_ArrayStoreException;
705 for (i=0; i<len; i++) {
706 java_arrayheader *o = aas->data[sp+i];
707 if (!builtin_canstore( (java_objectarray*)aad,
708 (java_objectheader*)o )) {
709 exceptionptr = proto_java_lang_ArrayStoreException;
715 for (i=len-1; i>=0; i--) {
716 java_arrayheader *o = aas->data[sp+i];
717 if (!builtin_canstore( (java_objectarray*)aad,
718 (java_objectheader*)o )) {
719 exceptionptr = proto_java_lang_ArrayStoreException;
729 panic ("Unknown data type for arraycopy");
736 static int activeprops = 15;
738 static char *proplist[MAXPROPS][2] = {
739 { "java.class.path", NULL },
740 { "java.home", NULL },
741 { "user.home", NULL },
742 { "user.name", NULL },
743 { "user.dir", NULL },
745 { "java.class.version", "45.3" },
746 { "java.version", "cacao:0.3" },
747 { "java.vendor", "CACAO Team" },
748 { "java.vendor.url", "http://www.complang.tuwien.ac.at/java/cacao/" },
749 { "os.arch", "Alpha" },
750 { "os.name", "Linux/Digital Unix" },
751 { "os.version", "4.0/3.2C/V4.0" },
752 { "path.separator", ":" },
753 { "file.separator", "/" },
754 { "line.separator", "\n" }
757 void attach_property (char *name, char *value)
759 if (activeprops >= MAXPROPS) panic ("Too many properties defined");
760 proplist[activeprops][0] = name;
761 proplist[activeprops][1] = value;
766 struct java_util_Properties* java_lang_System_initProperties (struct java_util_Properties* p)
770 #define BUFFERSIZE 200
771 char buffer[BUFFERSIZE];
773 proplist[0][1] = classpath;
774 proplist[1][1] = getenv("JAVA_HOME");
775 proplist[2][1] = getenv("HOME");
776 proplist[3][1] = getenv("USER");
777 proplist[4][1] = getcwd(buffer,BUFFERSIZE);
779 if (!p) panic ("initProperties called with NULL-Argument");
781 m = class_resolvemethod (
782 p->header.vftbl->class,
783 unicode_new_char ("put"),
784 unicode_new_char ("(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;")
786 if (!m) panic ("Can not find method 'put' for class Properties");
788 for (i=0; i<activeprops; i++) {
789 if (proplist[i][1]==NULL) proplist[i][1]="";
791 asm_calljavamethod (m, p,
792 javastring_new_char(proplist[i][0]),
793 javastring_new_char(proplist[i][1]),
804 /*********************************** java.lang.Thread ***********************************/
806 struct java_lang_Thread* java_lang_Thread_currentThread ()
809 log_text ("java_lang_Thread_currentThread called");
811 return (struct java_lang_Thread*)currentThread;
817 void java_lang_Thread_yield ()
820 log_text ("java_lang_Thread_yield called");
826 void java_lang_Thread_sleep (s8 par1)
829 log_text ("java_lang_Thread_sleep called");
833 /* not yet implemented */
836 void java_lang_Thread_start (struct java_lang_Thread* this)
839 log_text ("java_lang_Thread_start called");
841 startThread((thread*)this);
845 s4 java_lang_Thread_isAlive (struct java_lang_Thread* this)
848 log_text ("java_lang_Thread_isAlive called");
850 return aliveThread((thread*)this);
856 s4 java_lang_Thread_countStackFrames (struct java_lang_Thread* this)
858 log_text ("java_lang_Thread_countStackFrames called");
859 return 0; /* not yet implemented */
862 void java_lang_Thread_setPriority0 (struct java_lang_Thread* this, s4 par1)
865 log_text ("java_lang_Thread_setPriority0 called");
867 setPriorityThread((thread*)this, par1);
871 void java_lang_Thread_stop0 (struct java_lang_Thread* this, struct java_lang_Object* par1)
874 log_text ("java_lang_Thread_stop0 called");
876 if (currentThread == (thread*)this)
881 exceptionptr = proto_java_lang_ThreadDeath;
887 CONTEXT((thread*)this).flags |= THREAD_FLAGS_KILLED;
888 resumeThread((thread*)this);
893 void java_lang_Thread_suspend0 (struct java_lang_Thread* this)
896 log_text ("java_lang_Thread_suspend0 called");
898 suspendThread((thread*)this);
902 void java_lang_Thread_resume0 (struct java_lang_Thread* this)
905 log_text ("java_lang_Thread_resume0 called");
907 resumeThread((thread*)this);
913 /************************************ java.lang.Throwable *********************************/
915 void java_lang_Throwable_printStackTrace0 (struct java_lang_Throwable* this, struct java_io_PrintStream* par1)
917 log_text ("java_lang_Throwable_printStackTrace0 called");
921 struct java_lang_Throwable* java_lang_Throwable_fillInStackTrace (struct java_lang_Throwable *this)
923 this -> detailMessage =
924 (java_lang_String*) (javastring_new_char ("no backtrace info!") );