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 *******************************************************************************/
22 #include "../threads/thread.h" /* schani */
23 #include "../threads/locks.h"
25 static void use_class_as_object (classinfo *c)
27 c->header.vftbl = class_java_lang_Class -> vftbl;
31 /************************************** java.lang.Object ***********************************/
33 struct java_lang_Class* java_lang_Object_getClass (struct java_lang_Object* this)
35 classinfo *c = this->header.vftbl -> class;
36 use_class_as_object (c);
37 return (java_lang_Class*) c;
40 s4 java_lang_Object_hashCode (struct java_lang_Object* this)
42 return ((char*) this) - ((char*) 0);
46 struct java_lang_Object* java_lang_Object_clone (struct java_lang_Object* this)
49 java_lang_Object *new;
51 if (((java_objectheader*)this)->vftbl->class == class_array)
53 static u4 multiplicator[10];
54 static int is_initialized = 0;
56 java_arrayheader *array = (java_arrayheader*)this;
61 multiplicator[ARRAYTYPE_INT] = sizeof(s4);
62 multiplicator[ARRAYTYPE_LONG] = sizeof(s8);
63 multiplicator[ARRAYTYPE_FLOAT] = sizeof(float);
64 multiplicator[ARRAYTYPE_DOUBLE] = sizeof(double);
65 multiplicator[ARRAYTYPE_BYTE] = sizeof(s1);
66 multiplicator[ARRAYTYPE_CHAR] = sizeof(u2);
67 multiplicator[ARRAYTYPE_SHORT] = sizeof(s2);
68 multiplicator[ARRAYTYPE_BOOLEAN] = sizeof(u1);
69 multiplicator[ARRAYTYPE_OBJECT] = sizeof(void*);
70 multiplicator[ARRAYTYPE_ARRAY] = sizeof(void*);
74 size = sizeof(java_arrayheader)
75 + array->size * multiplicator[array->arraytype];
77 new = (java_lang_Object*)heap_allocate(size, false, NULL);
78 memcpy(new, this, size);
84 if (! builtin_instanceof ((java_objectheader*) this, class_java_lang_Cloneable) ) {
85 exceptionptr = native_new_and_init (class_java_lang_CloneNotSupportedException);
89 c = this -> header.vftbl -> class;
90 new = (java_lang_Object*) builtin_new (c);
92 exceptionptr = proto_java_lang_OutOfMemoryError;
96 memcpy (new, this, c->instancesize);
101 void java_lang_Object_notify (struct java_lang_Object* this)
104 log_text ("java_lang_Object_notify called");
107 signal_cond_for_object(&this->header);
111 void java_lang_Object_notifyAll (struct java_lang_Object* this)
114 log_text ("java_lang_Object_notifyAll called");
117 broadcast_cond_for_object(&this->header);
121 void java_lang_Object_wait (struct java_lang_Object* this, s8 time)
124 log_text ("java_lang_Object_wait called");
127 wait_cond_for_object(&this->header, time);
132 /********************************** java.lang.Class **************************************/
135 struct java_lang_Class* java_lang_Class_forName (struct java_lang_String* s)
137 java_chararray *a,*b;
143 if (!(a = s->value) ) return NULL;
144 b = builtin_newarray_char (s->count);
146 for (i=0; i<s->count; i++) {
147 if (a->data[s->offset+i]=='.') b->data[i] = '/';
148 else b->data[i] = a->data[s->offset+i];
150 u = unicode_new_u2 (b->data, b->header.size);
154 loader_initclasses ();
158 native_new_and_init (class_java_lang_ClassNotFoundException);
165 use_class_as_object (c);
166 return (java_lang_Class*) c;
169 struct java_lang_Object* java_lang_Class_newInstance (struct java_lang_Class* this)
171 java_objectheader *o = native_new_and_init ((classinfo*) this);
174 native_new_and_init (class_java_lang_InstantiationException);
176 return (java_lang_Object*) o;
179 struct java_lang_String* java_lang_Class_getName (struct java_lang_Class* this)
182 classinfo *c = (classinfo*) this;
183 java_lang_String *s = (java_lang_String*) javastring_new(c->name);
187 for (i=0; i<s->value->header.size; i++) {
188 if (s->value->data[i] == '/') s->value->data[i] = '.';
194 struct java_lang_Class* java_lang_Class_getSuperclass (struct java_lang_Class* this)
196 classinfo *c = ((classinfo*) this) -> super;
199 use_class_as_object (c);
200 return (java_lang_Class*) c;
203 java_objectarray* java_lang_Class_getInterfaces (struct java_lang_Class* this)
205 classinfo *c = (classinfo*) this;
207 java_objectarray *a = builtin_anewarray (c->interfacescount, class_java_lang_Class);
209 for (i=0; i<c->interfacescount; i++) {
210 use_class_as_object (c->interfaces[i]);
212 a->data[i] = (java_objectheader*) c->interfaces[i];
217 struct java_lang_ClassLoader* java_lang_Class_getClassLoader (struct java_lang_Class* this)
219 log_text ("java_lang_Class_getClassLoader called");
223 s4 java_lang_Class_isInterface (struct java_lang_Class* this)
225 classinfo *c = (classinfo*) this;
226 if (c->flags & ACC_INTERFACE) return 1;
230 /************************************ java.lang.ClassLoader *******************************/
233 struct java_lang_Class* java_lang_ClassLoader_defineClass (struct java_lang_ClassLoader* this, java_bytearray* par1, s4 par2, s4 par3)
235 log_text ("java_lang_ClassLoader_defineClass called");
238 void java_lang_ClassLoader_resolveClass (struct java_lang_ClassLoader* this, struct java_lang_Class* par1)
240 log_text ("java_lang_ClassLoader_resolveClass called");
242 struct java_lang_Class* java_lang_ClassLoader_findSystemClass (struct java_lang_ClassLoader* this, struct java_lang_String* par1)
244 log_text ("java_lang_ClassLoader_findSystemClass called");
247 void java_lang_ClassLoader_init (struct java_lang_ClassLoader* this)
249 log_text ("java_lang_ClassLoader_init called");
251 struct java_lang_Class* java_lang_ClassLoader_findSystemClass0 (struct java_lang_ClassLoader* this, struct java_lang_String* par1)
253 log_text ("java_lang_ClassLoader_findSystemClass0 called");
257 struct java_lang_Class* java_lang_ClassLoader_defineClass0 (struct java_lang_ClassLoader* this, java_bytearray* par1, s4 par2, s4 par3)
259 log_text ("java_lang_ClassLoader_defineClass0 called");
262 void java_lang_ClassLoader_resolveClass0 (struct java_lang_ClassLoader* this, struct java_lang_Class* par1)
264 log_text ("java_lang_ClassLoader_resolveClass0 called");
268 /************************************** java.lang.Compiler *******************************/
270 void java_lang_Compiler_initialize ()
272 log_text ("java_lang_Compiler_initialize called");
274 s4 java_lang_Compiler_compileClass (struct java_lang_Class* par1)
276 log_text ("java_lang_Compiler_compileClass called");
279 s4 java_lang_Compiler_compileClasses (struct java_lang_String* par1)
281 log_text ("java_lang_Compiler_compileClasses called");
284 struct java_lang_Object* java_lang_Compiler_command (struct java_lang_Object* par1)
286 log_text ("java_lang_Compiler_command called");
289 void java_lang_Compiler_enable ()
291 log_text ("java_lang_Compiler_enable called");
293 void java_lang_Compiler_disable ()
295 log_text ("java_lang_Compiler_disable called");
299 /******************************** java.lang.Double **************************************/
301 struct java_lang_String* java_lang_Double_toString (double par1)
304 sprintf (b, "%-.6g", par1);
305 return (java_lang_String*) javastring_new_char (b);
307 struct java_lang_Double* java_lang_Double_valueOf (struct java_lang_String* par1)
310 java_lang_Double *d = (java_lang_Double*) builtin_new (class_java_lang_Double);
312 sscanf (javastring_tochar((java_objectheader*) par1), "%f", &val);
318 s8 java_lang_Double_doubleToLongBits (double par1)
322 memcpy ((u1*) &l, (u1*) &d, 8);
325 double java_lang_Double_longBitsToDouble (s8 par1)
329 memcpy ((u1*) &d, (u1*) &l, 8);
333 /******************************** java.lang.Float ***************************************/
335 struct java_lang_String* java_lang_Float_toString (float par1)
338 sprintf (b, "%-.6g", (double) par1);
339 return (java_lang_String*) javastring_new_char (b);
341 struct java_lang_Float* java_lang_Float_valueOf (struct java_lang_String* par1)
344 java_lang_Float *d = (java_lang_Float*) builtin_new (class_java_lang_Float);
346 sscanf (javastring_tochar((java_objectheader*) par1), "%f", &val);
352 s4 java_lang_Float_floatToIntBits (float par1)
356 memcpy ((u1*) &i, (u1*) &f, 4);
359 float java_lang_Float_intBitsToFloat (s4 par1)
363 memcpy ((u1*) &f, (u1*) &i, 4);
368 /******************************** java.lang.Math ****************************************/
370 double java_lang_Math_sin (double par1)
375 double java_lang_Math_cos (double par1)
380 double java_lang_Math_tan (double par1)
385 double java_lang_Math_asin (double par1)
390 double java_lang_Math_acos (double par1)
395 double java_lang_Math_atan (double par1)
400 double java_lang_Math_exp (double par1)
405 double java_lang_Math_log (double par1)
408 exceptionptr = proto_java_lang_ArithmeticException;
414 double java_lang_Math_sqrt (double par1)
417 exceptionptr = proto_java_lang_ArithmeticException;
423 static u8 dbl_nan = 0xffffffffffffffffL ;
425 #define DBL_NAN (*((double*) (&dbl_nan)))
427 double java_lang_Math_IEEEremainder (double a, double b)
430 if (finite(a) && finite(b)) {
433 return a - floor(d) * b;
443 double java_lang_Math_ceil (double par1)
448 double java_lang_Math_floor (double par1)
453 double java_lang_Math_rint (double par1)
455 panic ("native Methode java_lang_rint not implemented yet");
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!") );