1 /****************************** builtin.c **************************************
3 Copyright (c) 1997 A. Krall, R. Grafl, M. Gschwind, M. Probst
5 See file COPYRIGHT for information on usage and disclaimer of warranties
7 Enthaelt die C-Funktionen fuer alle JavaVM-Befehle, die sich nicht direkt
8 auf Maschinencode "ubersetzen lassen. Im Code f"ur die Methoden steht
9 dann ein Funktionsaufruf (nat"urlich mit den Aufrufskonventionen von C).
11 Authors: Reinhard Grafl EMAIL: cacao@complang.tuwien.ac.at
12 Andreas Krall EMAIL: cacao@complang.tuwien.ac.at
13 Mark Probst EMAIL: cacao@complang.tuwien.ac.at
15 Last Change: 1996/12/03
17 *******************************************************************************/
28 #include "threads/thread.h"
29 #include "threads/locks.h" /* schani */
31 #include "native-math.h"
33 builtin_descriptor builtin_desc[] = {
34 {(functionptr) builtin_instanceof, "instanceof"},
35 {(functionptr) builtin_checkcast, "checkcast"},
36 {(functionptr) asm_builtin_checkcast, "checkcast"},
37 {(functionptr) builtin_arrayinstanceof, "arrayinstanceof"},
38 {(functionptr) builtin_checkarraycast, "checkarraycast"},
39 {(functionptr) asm_builtin_checkarraycast, "checkarraycast"},
40 {(functionptr) asm_builtin_aastore, "aastore"},
41 {(functionptr) builtin_new, "new"},
42 {(functionptr) builtin_anewarray, "anewarray"},
43 {(functionptr) builtin_newarray_array, "newarray_array"},
44 {(functionptr) builtin_newarray_boolean, "newarray_boolean"},
45 {(functionptr) builtin_newarray_char, "newarray_char"},
46 {(functionptr) builtin_newarray_float, "newarray_float"},
47 {(functionptr) builtin_newarray_double, "newarray_double"},
48 {(functionptr) builtin_newarray_byte, "newarray_byte"},
49 {(functionptr) builtin_newarray_short, "newarray_short"},
50 {(functionptr) builtin_newarray_int, "newarray_int"},
51 {(functionptr) builtin_newarray_long, "newarray_long"},
52 {(functionptr) builtin_displaymethodstart, "displaymethodstart"},
53 {(functionptr) builtin_displaymethodstop, "displaymethodstop"},
54 {(functionptr) builtin_monitorenter, "monitorenter"},
55 {(functionptr) asm_builtin_monitorenter, "monitorenter"},
56 {(functionptr) builtin_monitorexit, "monitorexit"},
57 {(functionptr) asm_builtin_monitorexit, "monitorexit"},
58 {(functionptr) builtin_idiv, "idiv"},
59 {(functionptr) asm_builtin_idiv, "idiv"},
60 {(functionptr) builtin_irem, "irem"},
61 {(functionptr) asm_builtin_irem, "irem"},
62 {(functionptr) builtin_ladd, "ladd"},
63 {(functionptr) builtin_lsub, "lsub"},
64 {(functionptr) builtin_lmul, "lmul"},
65 {(functionptr) builtin_ldiv, "ldiv"},
66 {(functionptr) asm_builtin_ldiv, "ldiv"},
67 {(functionptr) builtin_lrem, "lrem"},
68 {(functionptr) asm_builtin_lrem, "lrem"},
69 {(functionptr) builtin_lshl, "lshl"},
70 {(functionptr) builtin_lshr, "lshr"},
71 {(functionptr) builtin_lushr, "lushr"},
72 {(functionptr) builtin_land, "land"},
73 {(functionptr) builtin_lor, "lor"},
74 {(functionptr) builtin_lxor, "lxor"},
75 {(functionptr) builtin_lneg, "lneg"},
76 {(functionptr) builtin_lcmp, "lcmp"},
77 {(functionptr) builtin_fadd, "fadd"},
78 {(functionptr) builtin_fsub, "fsub"},
79 {(functionptr) builtin_fmul, "fmul"},
80 {(functionptr) builtin_fdiv, "fdiv"},
81 {(functionptr) builtin_frem, "frem"},
82 {(functionptr) builtin_fneg, "fneg"},
83 {(functionptr) builtin_fcmpl, "fcmpl"},
84 {(functionptr) builtin_fcmpg, "fcmpg"},
85 {(functionptr) builtin_dadd, "dadd"},
86 {(functionptr) builtin_dsub, "dsub"},
87 {(functionptr) builtin_dmul, "dmul"},
88 {(functionptr) builtin_ddiv, "ddiv"},
89 {(functionptr) builtin_drem, "drem"},
90 {(functionptr) builtin_dneg, "dneg"},
91 {(functionptr) builtin_dcmpl, "dcmpl"},
92 {(functionptr) builtin_dcmpg, "dcmpg"},
93 {(functionptr) builtin_i2l, "i2l"},
94 {(functionptr) builtin_i2f, "i2f"},
95 {(functionptr) builtin_i2d, "i2d"},
96 {(functionptr) builtin_l2i, "l2i"},
97 {(functionptr) builtin_l2f, "l2f"},
98 {(functionptr) builtin_l2d, "l2d"},
99 {(functionptr) builtin_f2i, "f2i"},
100 {(functionptr) builtin_f2l, "f2l"},
101 {(functionptr) builtin_f2d, "f2d"},
102 {(functionptr) builtin_d2i, "d2i"},
103 {(functionptr) builtin_d2l, "d2l"},
104 {(functionptr) builtin_d2f, "d2f"},
105 {(functionptr) NULL, "unknown"}
109 /*****************************************************************************
111 *****************************************************************************/
115 /*************** interne Funktion: builtin_isanysubclass *********************
117 "uberpr"uft, ob eine Klasse eine Unterklasse einer anderen Klasse ist.
118 Dabei gelten auch Interfaces, die eine Klasse implementiert, als
120 R"uckgabewert: 1 ... es trifft zu
121 0 ... es trifft nicht zu
123 *****************************************************************************/
125 s4 builtin_isanysubclass (classinfo *sub, classinfo *super)
127 if (super->flags & ACC_INTERFACE)
128 return (sub->vftbl->interfacetablelength > super->index) &&
129 (sub->vftbl->interfacetable[-super->index] != NULL);
141 return (unsigned) (sub->vftbl->baseval - super->vftbl->baseval) <=
142 (unsigned) (super->vftbl->diffval);
146 /****************** Funktion: builtin_instanceof *****************************
148 "Uberpr"uft, ob ein Objekt eine Instanz einer Klasse (oder einer davon
149 abgeleiteten Klasse) ist, oder ob die Klasse des Objekts ein Interface
152 0, wenn nicht, oder wenn Objekt ein NULL-Zeiger
154 *****************************************************************************/
156 s4 builtin_instanceof(java_objectheader *obj, classinfo *class)
159 log_text ("builtin_instanceof called");
163 return builtin_isanysubclass (obj->vftbl->class, class);
168 /**************** Funktion: builtin_checkcast *******************************
170 "Uberpr"uft, ob ein Objekt eine Instanz einer Klasse (oder einer davon
171 abgeleiteten Klasse ist).
172 Unterschied zu builtin_instanceof: Ein NULL-Zeiger ist immer richtig
173 Return: 1, wenn ja, oder wenn Objekt ein NULL-Zeiger
176 ****************************************************************************/
178 s4 builtin_checkcast(java_objectheader *obj, classinfo *class)
181 log_text ("builtin_checkcast called");
186 if (builtin_isanysubclass (obj->vftbl->class, class))
190 printf ("#### checkcast failed ");
191 utf_display (obj->vftbl->class->name);
193 utf_display (class->name);
201 /*********** interne Funktion: builtin_descriptorscompatible ******************
203 "uberpr"uft, ob zwei Array-Typdescriptoren compartible sind, d.h.,
204 ob ein Array vom Typ 'desc' gefahrlos einer Variblen vom Typ 'target'
205 zugewiesen werden kann.
209 ******************************************************************************/
211 static s4 builtin_descriptorscompatible
212 (constant_arraydescriptor *desc, constant_arraydescriptor *target)
214 if (desc==target) return 1;
215 if (desc->arraytype != target->arraytype) return 0;
216 switch (target->arraytype) {
217 case ARRAYTYPE_OBJECT:
218 return builtin_isanysubclass (desc->objectclass, target->objectclass);
219 case ARRAYTYPE_ARRAY:
220 return builtin_descriptorscompatible
221 (desc->elementdescriptor, target->elementdescriptor);
228 /******************** Funktion: builtin_checkarraycast ***********************
230 "uberpr"uft, ob ein gegebenes Objekt tats"achlich von einem
231 Untertyp des geforderten Arraytyps ist.
232 Dazu muss das Objekt auf jeden Fall ein Array sein.
233 Bei einfachen Arrays (int,short,double,etc.) muss der Typ genau
235 Bei Arrays von Objekten muss der Elementtyp des tats"achlichen Arrays
236 ein Untertyp (oder der selbe Typ) vom geforderten Elementtyp sein.
237 Bei Arrays vom Arrays (die eventuell wieder Arrays von Arrays
238 sein k"onnen) m"ussen die untersten Elementtypen in der entsprechenden
239 Unterklassenrelation stehen.
241 Return: 1, wenn Cast in Ordung ist
242 0, wenn es nicht geht
244 Achtung: ein Cast mit einem NULL-Zeiger geht immer gut.
246 *****************************************************************************/
248 s4 builtin_checkarraycast(java_objectheader *o, constant_arraydescriptor *desc)
250 java_arrayheader *a = (java_arrayheader*) o;
253 if (o->vftbl->class != class_array) {
255 printf ("#### checkarraycast failed 1\n");
260 if (a->arraytype != desc->arraytype) {
262 printf ("#### checkarraycast failed 2\n");
267 switch (a->arraytype) {
268 case ARRAYTYPE_OBJECT: {
269 java_objectarray *oa = (java_objectarray*) o;
270 int result = builtin_isanysubclass (oa->elementtype, desc->objectclass);
274 printf ("#### checkarraycast failed 3\n");
278 case ARRAYTYPE_ARRAY: {
279 java_arrayarray *aa = (java_arrayarray*) o;
280 int result = builtin_descriptorscompatible
281 (aa->elementdescriptor, desc->elementdescriptor);
285 printf ("#### checkarraycast failed 4\n");
295 s4 builtin_arrayinstanceof
296 (java_objectheader *obj, constant_arraydescriptor *desc)
299 return builtin_checkarraycast (obj, desc);
303 /************************** exception functions *******************************
305 ******************************************************************************/
307 java_objectheader *builtin_throw_exception (java_objectheader *local_exceptionptr) {
309 sprintf(logtext, "Builtin exception thrown: ");
310 utf_sprint(logtext + strlen(logtext), local_exceptionptr->vftbl->class->name);
313 exceptionptr = local_exceptionptr;
314 return local_exceptionptr;
318 /******************* Funktion: builtin_canstore *******************************
320 "uberpr"uft, ob ein Objekt in einem Array gespeichert werden
322 Return: 1, wenn es geht
325 ******************************************************************************/
328 s4 builtin_canstore (java_objectarray *a, java_objectheader *o)
332 switch (a->header.arraytype) {
333 case ARRAYTYPE_OBJECT:
334 if ( ! builtin_checkcast (o, a->elementtype) ) {
340 case ARRAYTYPE_ARRAY:
341 if ( ! builtin_checkarraycast
342 (o, ((java_arrayarray*)a)->elementdescriptor) ) {
349 panic ("builtin_canstore called with invalid arraytype");
356 /*****************************************************************************
358 *****************************************************************************/
362 /******************** Funktion: builtin_new **********************************
364 Legt ein neues Objekt einer Klasse am Heap an.
365 Return: Der Zeiger auf das Objekt, oder NULL, wenn kein Speicher
368 *****************************************************************************/
371 #define align_size(size) ((size + ((1 << ALIGNMENT) - 1)) & ~((1 << ALIGNMENT) - 1))
373 java_objectheader *builtin_new (classinfo *c)
375 java_objectheader *o;
379 #ifdef SIZE_FROM_CLASSINFO
380 c->alignedsize = align_size(c->instancesize);
381 o = heap_allocate ( c->alignedsize, true, c->finalizer );
383 o = heap_allocate ( c->instancesize, true, c->finalizer );
387 memset (o, 0, c->instancesize);
389 o -> vftbl = c -> vftbl;
395 /******************** Funktion: builtin_anewarray ****************************
397 Legt ein Array von Zeigern auf Objekte am Heap an.
399 size ......... Anzahl der Elemente
400 elementtype .. ein Zeiger auf die classinfo-Struktur des Typs
403 Return: Zeiger auf das Array, oder NULL (wenn kein Speicher frei)
405 *****************************************************************************/
408 void* __builtin_newarray(s4 base_size,
415 #ifdef SIZE_FROM_CLASSINFO
416 s4 alignedsize = align_size(base_size + (size-1) * elementsize);
417 a = heap_allocate ( alignedsize, true, NULL );
419 a = heap_allocate ( sizeof(java_objectarray) + (size-1) * elementsize,
425 #ifdef SIZE_FROM_CLASSINFO
426 memset(a, 0, alignedsize);
428 memset(a, 0, base_size + (size-1) * elementsize);
431 a -> objheader.vftbl = class_array -> vftbl;
433 #ifdef SIZE_FROM_CLASSINFO
434 a -> alignedsize = alignedsize;
436 a -> arraytype = arraytype;
442 java_objectarray *builtin_anewarray (s4 size, classinfo *elementtype)
445 a = (java_objectarray*)__builtin_newarray(sizeof(java_objectarray),
452 a -> elementtype = elementtype;
458 /******************** Funktion: builtin_newarray_array ***********************
460 Legt ein Array von Zeigern auf Arrays am Heap an.
461 Paramter: size ......... Anzahl der Elemente
462 elementdesc .. Zeiger auf die Arraybeschreibungs-Struktur f"ur
465 Return: Zeiger auf das Array, oder NULL
467 *****************************************************************************/
469 java_arrayarray *builtin_newarray_array
470 (s4 size, constant_arraydescriptor *elementdesc)
473 a = (java_arrayarray*)__builtin_newarray(sizeof(java_arrayarray),
480 a -> elementdescriptor = elementdesc;
485 /******************** Funktion: builtin_newarray_boolean ************************
487 Legt ein Array von Bytes am Heap an, das allerdings als Boolean-Array
488 gekennzeichnet wird (wichtig bei Casts!)
490 Return: Zeiger auf das Array, oder NULL
492 *****************************************************************************/
494 java_booleanarray *builtin_newarray_boolean (s4 size)
496 java_booleanarray *a;
497 a = (java_booleanarray*)__builtin_newarray(sizeof(java_booleanarray),
505 /******************** Funktion: builtin_newarray_char ************************
507 Legt ein Array von 16-bit-Integers am Heap an.
508 Return: Zeiger auf das Array, oder NULL
510 *****************************************************************************/
512 java_chararray *builtin_newarray_char (s4 size)
515 a = (java_chararray*)__builtin_newarray(sizeof(java_chararray),
524 /******************** Funktion: builtin_newarray_float ***********************
526 Legt ein Array von 32-bit-IEEE-float am Heap an.
527 Return: Zeiger auf das Array, oder NULL
529 *****************************************************************************/
531 java_floatarray *builtin_newarray_float (s4 size)
534 a = (java_floatarray*)__builtin_newarray(sizeof(java_floatarray),
543 /******************** Funktion: builtin_newarray_double ***********************
545 Legt ein Array von 64-bit-IEEE-float am Heap an.
546 Return: Zeiger auf das Array, oder NULL
548 *****************************************************************************/
550 java_doublearray *builtin_newarray_double (s4 size)
553 a = (java_doublearray*)__builtin_newarray(sizeof(java_doublearray),
564 /******************** Funktion: builtin_newarray_byte ***********************
566 Legt ein Array von 8-bit-Integers am Heap an.
567 Return: Zeiger auf das Array, oder NULL
569 *****************************************************************************/
571 java_bytearray *builtin_newarray_byte (s4 size)
574 a = (java_bytearray*)__builtin_newarray(sizeof(java_bytearray),
583 /******************** Funktion: builtin_newarray_short ***********************
585 Legt ein Array von 16-bit-Integers am Heap an.
586 Return: Zeiger auf das Array, oder NULL
588 *****************************************************************************/
590 java_shortarray *builtin_newarray_short (s4 size)
593 a = (java_shortarray*)__builtin_newarray(sizeof(java_shortarray),
602 /******************** Funktion: builtin_newarray_int ***********************
604 Legt ein Array von 32-bit-Integers am Heap an.
605 Return: Zeiger auf das Array, oder NULL
607 *****************************************************************************/
609 java_intarray *builtin_newarray_int (s4 size)
612 a = (java_intarray*)__builtin_newarray(sizeof(java_intarray),
621 /******************** Funktion: builtin_newarray_long ***********************
623 Legt ein Array von 64-bit-Integers am Heap an.
624 Return: Zeiger auf das Array, oder NULL
626 *****************************************************************************/
628 java_longarray *builtin_newarray_long (s4 size)
631 a = (java_longarray*)__builtin_newarray(sizeof(java_longarray),
641 /***************** Funktion: builtin_multianewarray ***************************
643 Legt ein mehrdimensionales Array am Heap an.
644 Die Gr"ossen der einzelnen Dimensionen werden in einem Integerarray
645 "ubergeben. Der Typ es zu erzeugenden Arrays wird als
646 Referenz auf eine constant_arraydescriptor - Struktur "ubergeben.
648 Return: Ein Zeiger auf das Array, oder NULL, wenn kein Speicher mehr
651 ******************************************************************************/
655 static java_arrayheader *multianewarray_part (java_intarray *dims, int thisdim,
656 constant_arraydescriptor *desc)
661 size = dims -> data[thisdim];
663 if (thisdim == (dims->header.size-1)) {
664 /* letzte Dimension schon erreicht */
666 switch (desc -> arraytype) {
667 case ARRAYTYPE_BOOLEAN:
668 return (java_arrayheader*) builtin_newarray_boolean (size);
670 return (java_arrayheader*) builtin_newarray_char (size);
671 case ARRAYTYPE_FLOAT:
672 return (java_arrayheader*) builtin_newarray_float (size);
673 case ARRAYTYPE_DOUBLE:
674 return (java_arrayheader*) builtin_newarray_double (size);
676 return (java_arrayheader*) builtin_newarray_byte (size);
677 case ARRAYTYPE_SHORT:
678 return (java_arrayheader*) builtin_newarray_short (size);
680 return (java_arrayheader*) builtin_newarray_int (size);
682 return (java_arrayheader*) builtin_newarray_long (size);
683 case ARRAYTYPE_OBJECT:
684 return (java_arrayheader*) builtin_anewarray (size, desc->objectclass);
686 case ARRAYTYPE_ARRAY:
687 return (java_arrayheader*) builtin_newarray_array (size, desc->elementdescriptor);
689 default: panic ("Invalid arraytype in multianewarray");
693 /* wenn letzte Dimension noch nicht erreicht wurde */
695 if (desc->arraytype != ARRAYTYPE_ARRAY)
696 panic ("multianewarray with too many dimensions");
698 a = builtin_newarray_array (size, desc->elementdescriptor);
701 for (i=0; i<size; i++) {
702 java_arrayheader *ea =
703 multianewarray_part (dims, thisdim+1, desc->elementdescriptor);
704 if (!ea) return NULL;
709 return (java_arrayheader*) a;
713 java_arrayheader *builtin_multianewarray (java_intarray *dims,
714 constant_arraydescriptor *desc)
716 return multianewarray_part (dims, 0, desc);
720 static java_arrayheader *nmultianewarray_part (int n, long *dims, int thisdim,
721 constant_arraydescriptor *desc)
726 size = (int) dims[thisdim];
728 if (thisdim == (n - 1)) {
729 /* letzte Dimension schon erreicht */
731 switch (desc -> arraytype) {
732 case ARRAYTYPE_BOOLEAN:
733 return (java_arrayheader*) builtin_newarray_boolean(size);
735 return (java_arrayheader*) builtin_newarray_char(size);
736 case ARRAYTYPE_FLOAT:
737 return (java_arrayheader*) builtin_newarray_float(size);
738 case ARRAYTYPE_DOUBLE:
739 return (java_arrayheader*) builtin_newarray_double(size);
741 return (java_arrayheader*) builtin_newarray_byte(size);
742 case ARRAYTYPE_SHORT:
743 return (java_arrayheader*) builtin_newarray_short(size);
745 return (java_arrayheader*) builtin_newarray_int(size);
747 return (java_arrayheader*) builtin_newarray_long(size);
748 case ARRAYTYPE_OBJECT:
749 return (java_arrayheader*) builtin_anewarray(size,
751 case ARRAYTYPE_ARRAY:
752 return (java_arrayheader*) builtin_newarray_array(size,
753 desc->elementdescriptor);
755 default: panic ("Invalid arraytype in multianewarray");
759 /* wenn letzte Dimension noch nicht erreicht wurde */
761 if (desc->arraytype != ARRAYTYPE_ARRAY)
762 panic ("multianewarray with too many dimensions");
764 a = builtin_newarray_array(size, desc->elementdescriptor);
767 for (i = 0; i < size; i++) {
768 java_arrayheader *ea =
769 nmultianewarray_part(n, dims, thisdim + 1, desc->elementdescriptor);
770 if (!ea) return NULL;
775 return (java_arrayheader*) a;
779 java_arrayheader *builtin_nmultianewarray (int size,
780 constant_arraydescriptor *desc, long *dims)
782 (void) builtin_newarray_int(size); /* for compatibility with -old */
783 return nmultianewarray_part (size, dims, 0, desc);
789 /************************* Funktion: builtin_aastore *************************
791 speichert eine Referenz auf ein Objekt in einem Object-Array oder
792 in einem Array-Array.
793 Dabei wird allerdings vorher "uberpr"uft, ob diese Operation
796 Return: 1, wenn alles OK ist
797 0, wenn dieses Objekt nicht in dieses Array gespeichert werden
800 *****************************************************************************/
802 s4 builtin_aastore (java_objectarray *a, s4 index, java_objectheader *o)
804 if (builtin_canstore(a,o)) {
816 /*****************************************************************************
817 METHODEN-PROTOKOLLIERUNG
819 Verschiedene Funktionen, mit denen eine Meldung ausgegeben werden
820 kann, wann immer Methoden aufgerufen oder beendet werden.
823 *****************************************************************************/
828 java_objectheader *builtin_trace_exception (java_objectheader *exceptionptr,
829 methodinfo *method, int *pos, int noindent) {
833 if (verbose || runverbose) {
834 printf("Exception ");
835 utf_display (exceptionptr->vftbl->class->name);
836 printf(" thrown in ");
838 utf_display (method->class->name);
840 utf_display (method->name);
841 if (method->flags & ACC_SYNCHRONIZED)
845 printf("(%p) at position %p\n", method->entrypoint, pos);
848 printf("call_java_method\n");
855 void builtin_trace_args(long a0, long a1, long a2, long a3, long a4, long a5,
858 sprintf (logtext, " ");
859 sprintf (logtext+methodindent, "called: ");
860 utf_sprint (logtext+strlen(logtext), method->class->name);
861 sprintf (logtext+strlen(logtext), ".");
862 utf_sprint (logtext+strlen(logtext), method->name);
863 utf_sprint (logtext+strlen(logtext), method->descriptor);
864 sprintf (logtext+strlen(logtext), "(");
865 switch (method->paramcount) {
867 sprintf(logtext+strlen(logtext), "%lx, %lx, %lx, %lx, %lx, %lx",
868 a0, a1, a2, a3, a4, a5);
871 sprintf(logtext+strlen(logtext), "%lx, %lx, %lx, %lx, %lx",
875 sprintf(logtext+strlen(logtext), "%lx, %lx, %lx, %lx",
879 sprintf(logtext+strlen(logtext), "%lx, %lx, %lx", a0, a1, a2);
882 sprintf(logtext+strlen(logtext), "%lx, %lx", a0, a1);
885 sprintf(logtext+strlen(logtext), "%lx", a0);
888 sprintf (logtext+strlen(logtext), ")");
894 void builtin_displaymethodstart(methodinfo *method)
896 sprintf (logtext, " ");
897 sprintf (logtext+methodindent, "called: ");
898 utf_sprint (logtext+strlen(logtext), method->class->name);
899 sprintf (logtext+strlen(logtext), ".");
900 utf_sprint (logtext+strlen(logtext), method->name);
901 utf_sprint (logtext+strlen(logtext), method->descriptor);
906 void builtin_displaymethodstop(methodinfo *method, long l, double d)
909 sprintf (logtext, " ");
910 sprintf (logtext+methodindent, "finished: ");
911 utf_sprint (logtext+strlen(logtext), method->class->name);
912 sprintf (logtext+strlen(logtext), ".");
913 utf_sprint (logtext+strlen(logtext), method->name);
914 utf_sprint (logtext+strlen(logtext), method->descriptor);
915 switch (method->returntype) {
919 sprintf (logtext+strlen(logtext), "->%ld", l);
923 sprintf (logtext+strlen(logtext), "->%g", d);
929 void builtin_displaymethodexception(methodinfo *method)
931 sprintf (logtext, " ");
932 sprintf (logtext+methodindent, "exception abort: ");
933 utf_sprint (logtext+strlen(logtext), method->class->name);
934 sprintf (logtext+strlen(logtext), ".");
935 utf_sprint (logtext+strlen(logtext), method->name);
936 utf_sprint (logtext+strlen(logtext), method->descriptor);
941 /****************************************************************************
942 SYNCHRONIZATION FUNCTIONS
943 *****************************************************************************/
946 * Lock the mutex of an object.
950 internal_lock_mutex_for_object (java_objectheader *object)
952 mutexHashEntry *entry;
957 hashValue = MUTEX_HASH_VALUE(object);
958 entry = &mutexHashTable[hashValue];
960 if (entry->object != 0)
962 if (entry->mutex.count == 0 && entry->conditionCount == 0)
965 entry->mutex.holder = 0;
966 entry->mutex.count = 0;
967 entry->mutex.muxWaiters = 0;
971 while (entry->next != 0 && entry->object != object)
974 if (entry->object != object)
976 entry->next = firstFreeOverflowEntry;
977 firstFreeOverflowEntry = firstFreeOverflowEntry->next;
982 assert(entry->conditionCount == 0);
988 entry->mutex.holder = 0;
989 entry->mutex.count = 0;
990 entry->mutex.muxWaiters = 0;
993 if (entry->object == 0)
994 entry->object = object;
996 internal_lock_mutex(&entry->mutex);
1002 * Unlocks the mutex of an object.
1006 internal_unlock_mutex_for_object (java_objectheader *object)
1009 mutexHashEntry *entry;
1011 hashValue = MUTEX_HASH_VALUE(object);
1012 entry = &mutexHashTable[hashValue];
1014 if (entry->object == object)
1015 internal_unlock_mutex(&entry->mutex);
1018 while (entry->next != 0 && entry->next->object != object)
1019 entry = entry->next;
1021 assert(entry->next != 0);
1023 internal_unlock_mutex(&entry->next->mutex);
1025 if (entry->next->mutex.count == 0 && entry->conditionCount == 0)
1027 mutexHashEntry *unlinked = entry->next;
1029 entry->next = unlinked->next;
1030 unlinked->next = firstFreeOverflowEntry;
1031 firstFreeOverflowEntry = unlinked;
1038 builtin_monitorenter (java_objectheader *o)
1043 assert(blockInts == 0);
1047 hashValue = MUTEX_HASH_VALUE(o);
1048 if (mutexHashTable[hashValue].object == o
1049 && mutexHashTable[hashValue].mutex.holder == currentThread)
1050 ++mutexHashTable[hashValue].mutex.count;
1052 internal_lock_mutex_for_object(o);
1056 assert(blockInts == 0);
1060 void builtin_monitorexit (java_objectheader *o)
1065 assert(blockInts == 0);
1069 hashValue = MUTEX_HASH_VALUE(o);
1070 if (mutexHashTable[hashValue].object == o)
1072 if (mutexHashTable[hashValue].mutex.count == 1
1073 && mutexHashTable[hashValue].mutex.muxWaiters != 0)
1074 internal_unlock_mutex_for_object(o);
1076 --mutexHashTable[hashValue].mutex.count;
1079 internal_unlock_mutex_for_object(o);
1083 assert(blockInts == 0);
1088 /*****************************************************************************
1089 DIVERSE HILFSFUNKTIONEN
1090 *****************************************************************************/
1094 /*********** Funktionen f"ur die Integerdivision *****************************
1096 Auf manchen Systemen (z.B. DEC ALPHA) wird durch die CPU keine Integer-
1097 division unterst"utzt.
1098 Daf"ur gibt es dann diese Hilfsfunktionen
1100 ******************************************************************************/
1102 s4 builtin_idiv (s4 a, s4 b) { return a/b; }
1103 s4 builtin_irem (s4 a, s4 b) { return a%b; }
1106 /************** Funktionen f"ur Long-Arithmetik *******************************
1108 Auf Systemen, auf denen die CPU keine 64-Bit-Integers unterst"utzt,
1109 werden diese Funktionen gebraucht
1111 ******************************************************************************/
1114 s8 builtin_ladd (s8 a, s8 b)
1119 return builtin_i2l(0);
1123 s8 builtin_lsub (s8 a, s8 b)
1128 return builtin_i2l(0);
1132 s8 builtin_lmul (s8 a, s8 b)
1137 return builtin_i2l(0);
1141 s8 builtin_ldiv (s8 a, s8 b)
1146 return builtin_i2l(0);
1150 s8 builtin_lrem (s8 a, s8 b)
1155 return builtin_i2l(0);
1159 s8 builtin_lshl (s8 a, s4 b)
1164 return builtin_i2l(0);
1168 s8 builtin_lshr (s8 a, s4 b)
1173 return builtin_i2l(0);
1177 s8 builtin_lushr (s8 a, s4 b)
1180 return ((u8)a)>>(b&63);
1182 return builtin_i2l(0);
1186 s8 builtin_land (s8 a, s8 b)
1191 return builtin_i2l(0);
1195 s8 builtin_lor (s8 a, s8 b)
1200 return builtin_i2l(0);
1204 s8 builtin_lxor (s8 a, s8 b)
1209 return builtin_i2l(0);
1213 s8 builtin_lneg (s8 a)
1218 return builtin_i2l(0);
1222 s4 builtin_lcmp (s8 a, s8 b)
1237 /*********** Funktionen f"ur die Floating-Point-Operationen ******************/
1239 float builtin_fadd (float a, float b)
1241 if (isnanf(a)) return FLT_NAN;
1242 if (isnanf(b)) return FLT_NAN;
1244 if (finitef(b)) return a+b;
1248 if (finitef(b)) return a;
1250 if (copysignf(1.0, a)==copysignf(1.0, b)) return a;
1251 else return FLT_NAN;
1256 float builtin_fsub (float a, float b)
1258 return builtin_fadd (a, builtin_fneg(b));
1261 float builtin_fmul (float a, float b)
1263 if (isnanf(a)) return FLT_NAN;
1264 if (isnanf(b)) return FLT_NAN;
1266 if (finitef(b)) return a*b;
1268 if (a==0) return FLT_NAN;
1269 else return copysignf(b, copysignf(1.0, b)*a);
1274 if (b==0) return FLT_NAN;
1275 else return copysignf(a, copysignf(1.0, a)*b);
1278 return copysignf(a, copysignf(1.0, a)*copysignf(1.0, b));
1283 float builtin_fdiv (float a, float b)
1285 if (finitef(a) && finitef(b)) {
1298 float builtin_frem (float a, float b)
1301 /* return (float) builtin_drem((double) a, (double) b); */
1305 if (finite((double) a) && finite((double) b)) {
1307 if (finite((double) f))
1311 if (isnan((double) b))
1313 if (finite((double) a))
1319 if (finitef(a) && finitef(b)) {
1322 return a - floorf(f) * b;
1333 float builtin_fneg (float a)
1335 if (isnanf(a)) return a;
1337 if (finitef(a)) return -a;
1338 else return copysignf(a,-copysignf(1.0, a));
1342 s4 builtin_fcmpl (float a, float b)
1344 if (isnanf(a)) return -1;
1345 if (isnanf(b)) return -1;
1346 if (!finitef(a) || !finitef(b)) {
1347 a = finitef(a) ? 0 : copysignf(1.0, a);
1348 b = finitef(b) ? 0 : copysignf(1.0, b);
1355 s4 builtin_fcmpg (float a, float b)
1357 if (isnanf(a)) return 1;
1358 if (isnanf(b)) return 1;
1359 if (!finitef(a) || !finitef(b)) {
1360 a = finitef(a) ? 0 : copysignf(1.0, a);
1361 b = finitef(b) ? 0 : copysignf(1.0, b);
1370 /*********** Funktionen f"ur doppelt genaue Fliesskommazahlen ***************/
1372 double builtin_dadd (double a, double b)
1374 if (isnan(a)) return DBL_NAN;
1375 if (isnan(b)) return DBL_NAN;
1377 if (finite(b)) return a+b;
1381 if (finite(b)) return a;
1383 if (copysign(1.0, a)==copysign(1.0, b)) return a;
1384 else return DBL_NAN;
1389 double builtin_dsub (double a, double b)
1391 return builtin_dadd (a, builtin_dneg(b));
1394 double builtin_dmul (double a, double b)
1396 if (isnan(a)) return DBL_NAN;
1397 if (isnan(b)) return DBL_NAN;
1399 if (finite(b)) return a*b;
1401 if (a==0) return DBL_NAN;
1402 else return copysign(b, copysign(1.0, b)*a);
1407 if (b==0) return DBL_NAN;
1408 else return copysign(a, copysign(1.0, a)*b);
1411 return copysign(a, copysign(1.0, a)*copysign(1.0, b));
1416 double builtin_ddiv (double a, double b)
1418 if (finite(a) && finite(b)) {
1431 double builtin_drem (double a, double b)
1435 if (finite(a) && finite(b)) {
1438 if ((d < 1.0) && (d > 0.0))
1451 double builtin_dneg (double a)
1453 if (isnan(a)) return a;
1455 if (finite(a)) return -a;
1456 else return copysign(a,-copysign(1.0, a));
1460 s4 builtin_dcmpl (double a, double b)
1462 if (isnan(a)) return -1;
1463 if (isnan(b)) return -1;
1464 if (!finite(a) || !finite(b)) {
1465 a = finite(a) ? 0 : copysign(1.0, a);
1466 b = finite(b) ? 0 : copysign(1.0, b);
1473 s4 builtin_dcmpg (double a, double b)
1475 if (isnan(a)) return 1;
1476 if (isnan(b)) return 1;
1477 if (!finite(a) || !finite(b)) {
1478 a = finite(a) ? 0 : copysign(1.0, a);
1479 b = finite(b) ? 0 : copysign(1.0, b);
1487 /*********************** Umwandlungsoperationen ****************************/
1489 s8 builtin_i2l (s4 i)
1494 s8 v; v.high = 0; v.low=i; return v;
1498 float builtin_i2f (s4 a)
1500 float f = (float) a;
1504 double builtin_i2d (s4 a)
1506 double d = (double) a;
1511 s4 builtin_l2i (s8 l)
1520 float builtin_l2f (s8 a)
1523 float f = (float) a;
1530 double builtin_l2d (s8 a)
1533 double d = (double) a;
1541 s4 builtin_f2i(float a)
1544 return builtin_d2i((double) a);
1553 if (a < (-2147483648))
1554 return (-2147483648);
1557 f = copysignf((float) 1.0, a);
1560 return (-2147483648); */
1564 s8 builtin_f2l (float a)
1567 return builtin_d2l((double) a);
1572 if (a > 9223372036854775807L)
1573 return 9223372036854775807L;
1574 if (a < (-9223372036854775808L))
1575 return (-9223372036854775808L);
1580 f = copysignf((float) 1.0, a);
1582 return 9223372036854775807L;
1583 return (-9223372036854775808L); */
1587 double builtin_f2d (float a)
1589 if (finitef(a)) return (double) a;
1591 if (isnanf(a)) return DBL_NAN;
1592 else return copysign(DBL_POSINF, (double) copysignf(1.0, a) );
1597 s4 builtin_d2i (double a)
1602 if (a >= 2147483647)
1604 if (a <= (-2147483648))
1605 return (-2147483648);
1610 d = copysign(1.0, a);
1613 return (-2147483648);
1617 s8 builtin_d2l (double a)
1622 if (a >= 9223372036854775807L)
1623 return 9223372036854775807L;
1624 if (a <= (-9223372036854775807L-1))
1625 return (-9223372036854775807L-1);
1630 d = copysign(1.0, a);
1632 return 9223372036854775807L;
1633 return (-9223372036854775807L-1);
1637 float builtin_d2f (double a)
1639 if (finite(a)) return (float) a;
1641 if (isnan(a)) return FLT_NAN;
1642 else return copysignf (FLT_POSINF, (float) copysign(1.0, a));
1648 * These are local overrides for various environment variables in Emacs.
1649 * Please do not remove this and leave it at the end of the file, where
1650 * Emacs will automagically detect them.
1651 * ---------------------------------------------------------------------
1654 * indent-tabs-mode: t