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);
140 return (unsigned) (sub->vftbl->baseval - super->vftbl->baseval) <=
141 (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) {
257 if (a->arraytype != desc->arraytype) {
261 switch (a->arraytype) {
262 case ARRAYTYPE_OBJECT: {
263 java_objectarray *oa = (java_objectarray*) o;
264 return builtin_isanysubclass (oa->elementtype, desc->objectclass);
266 case ARRAYTYPE_ARRAY: {
267 java_arrayarray *aa = (java_arrayarray*) o;
268 return builtin_descriptorscompatible
269 (aa->elementdescriptor, desc->elementdescriptor);
277 s4 builtin_arrayinstanceof
278 (java_objectheader *obj, constant_arraydescriptor *desc)
281 return builtin_checkarraycast (obj, desc);
285 /************************** exception functions *******************************
287 ******************************************************************************/
289 java_objectheader *builtin_throw_exception (java_objectheader *local_exceptionptr) {
290 exceptionptr = local_exceptionptr;
291 utf_display (local_exceptionptr->vftbl->class->name);
294 return local_exceptionptr;
298 /******************* Funktion: builtin_canstore *******************************
300 "uberpr"uft, ob ein Objekt in einem Array gespeichert werden
302 Return: 1, wenn es geht
305 ******************************************************************************/
308 s4 builtin_canstore (java_objectarray *a, java_objectheader *o)
312 switch (a->header.arraytype) {
313 case ARRAYTYPE_OBJECT:
314 if ( ! builtin_checkcast (o, a->elementtype) ) {
320 case ARRAYTYPE_ARRAY:
321 if ( ! builtin_checkarraycast
322 (o, ((java_arrayarray*)a)->elementdescriptor) ) {
329 panic ("builtin_canstore called with invalid arraytype");
336 /*****************************************************************************
338 *****************************************************************************/
342 /******************** Funktion: builtin_new **********************************
344 Legt ein neues Objekt einer Klasse am Heap an.
345 Return: Der Zeiger auf das Objekt, oder NULL, wenn kein Speicher
348 *****************************************************************************/
351 #define align_size(size) ((size + ((1 << ALIGNMENT) - 1)) & ~((1 << ALIGNMENT) - 1))
353 java_objectheader *builtin_new (classinfo *c)
355 java_objectheader *o;
357 #ifdef SIZE_FROM_CLASSINFO
358 c->alignedsize = align_size(c->instancesize);
359 o = heap_allocate ( c->alignedsize, true, c->finalizer );
361 o = heap_allocate ( c->instancesize, true, c->finalizer );
365 memset (o, 0, c->instancesize);
367 o -> vftbl = c -> vftbl;
373 /******************** Funktion: builtin_anewarray ****************************
375 Legt ein Array von Zeigern auf Objekte am Heap an.
377 size ......... Anzahl der Elemente
378 elementtype .. ein Zeiger auf die classinfo-Struktur des Typs
381 Return: Zeiger auf das Array, oder NULL (wenn kein Speicher frei)
383 *****************************************************************************/
386 void* __builtin_newarray(s4 base_size,
393 #ifdef SIZE_FROM_CLASSINFO
394 s4 alignedsize = align_size(base_size + (size-1) * elementsize);
395 a = heap_allocate ( alignedsize, true, NULL );
397 a = heap_allocate ( sizeof(java_objectarray) + (size-1) * elementsize,
403 #ifdef SIZE_FROM_CLASSINFO
404 memset(a, 0, alignedsize);
406 memset(a, 0, base_size + (size-1) * elementsize);
409 a -> objheader.vftbl = class_array -> vftbl;
411 #ifdef SIZE_FROM_CLASSINFO
412 a -> alignedsize = alignedsize;
414 a -> arraytype = arraytype;
420 java_objectarray *builtin_anewarray (s4 size, classinfo *elementtype)
423 a = (java_objectarray*)__builtin_newarray(sizeof(java_objectarray),
430 a -> elementtype = elementtype;
436 /******************** Funktion: builtin_newarray_array ***********************
438 Legt ein Array von Zeigern auf Arrays am Heap an.
439 Paramter: size ......... Anzahl der Elemente
440 elementdesc .. Zeiger auf die Arraybeschreibungs-Struktur f"ur
443 Return: Zeiger auf das Array, oder NULL
445 *****************************************************************************/
447 java_arrayarray *builtin_newarray_array
448 (s4 size, constant_arraydescriptor *elementdesc)
451 a = (java_arrayarray*)__builtin_newarray(sizeof(java_arrayarray),
458 a -> elementdescriptor = elementdesc;
463 /******************** Funktion: builtin_newarray_boolean ************************
465 Legt ein Array von Bytes am Heap an, das allerdings als Boolean-Array
466 gekennzeichnet wird (wichtig bei Casts!)
468 Return: Zeiger auf das Array, oder NULL
470 *****************************************************************************/
472 java_booleanarray *builtin_newarray_boolean (s4 size)
474 java_booleanarray *a;
475 a = (java_booleanarray*)__builtin_newarray(sizeof(java_booleanarray),
483 /******************** Funktion: builtin_newarray_char ************************
485 Legt ein Array von 16-bit-Integers am Heap an.
486 Return: Zeiger auf das Array, oder NULL
488 *****************************************************************************/
490 java_chararray *builtin_newarray_char (s4 size)
493 a = (java_chararray*)__builtin_newarray(sizeof(java_chararray),
502 /******************** Funktion: builtin_newarray_float ***********************
504 Legt ein Array von 32-bit-IEEE-float am Heap an.
505 Return: Zeiger auf das Array, oder NULL
507 *****************************************************************************/
509 java_floatarray *builtin_newarray_float (s4 size)
512 a = (java_floatarray*)__builtin_newarray(sizeof(java_floatarray),
521 /******************** Funktion: builtin_newarray_double ***********************
523 Legt ein Array von 64-bit-IEEE-float am Heap an.
524 Return: Zeiger auf das Array, oder NULL
526 *****************************************************************************/
528 java_doublearray *builtin_newarray_double (s4 size)
531 a = (java_doublearray*)__builtin_newarray(sizeof(java_doublearray),
542 /******************** Funktion: builtin_newarray_byte ***********************
544 Legt ein Array von 8-bit-Integers am Heap an.
545 Return: Zeiger auf das Array, oder NULL
547 *****************************************************************************/
549 java_bytearray *builtin_newarray_byte (s4 size)
552 a = (java_bytearray*)__builtin_newarray(sizeof(java_bytearray),
561 /******************** Funktion: builtin_newarray_short ***********************
563 Legt ein Array von 16-bit-Integers am Heap an.
564 Return: Zeiger auf das Array, oder NULL
566 *****************************************************************************/
568 java_shortarray *builtin_newarray_short (s4 size)
571 a = (java_shortarray*)__builtin_newarray(sizeof(java_shortarray),
580 /******************** Funktion: builtin_newarray_int ***********************
582 Legt ein Array von 32-bit-Integers am Heap an.
583 Return: Zeiger auf das Array, oder NULL
585 *****************************************************************************/
587 java_intarray *builtin_newarray_int (s4 size)
590 a = (java_intarray*)__builtin_newarray(sizeof(java_intarray),
599 /******************** Funktion: builtin_newarray_long ***********************
601 Legt ein Array von 64-bit-Integers am Heap an.
602 Return: Zeiger auf das Array, oder NULL
604 *****************************************************************************/
606 java_longarray *builtin_newarray_long (s4 size)
609 a = (java_longarray*)__builtin_newarray(sizeof(java_longarray),
619 /***************** Funktion: builtin_multianewarray ***************************
621 Legt ein mehrdimensionales Array am Heap an.
622 Die Gr"ossen der einzelnen Dimensionen werden in einem Integerarray
623 "ubergeben. Der Typ es zu erzeugenden Arrays wird als
624 Referenz auf eine constant_arraydescriptor - Struktur "ubergeben.
626 Return: Ein Zeiger auf das Array, oder NULL, wenn kein Speicher mehr
629 ******************************************************************************/
633 static java_arrayheader *multianewarray_part (java_intarray *dims, int thisdim,
634 constant_arraydescriptor *desc)
639 size = dims -> data[thisdim];
641 if (thisdim == (dims->header.size-1)) {
642 /* letzte Dimension schon erreicht */
644 switch (desc -> arraytype) {
645 case ARRAYTYPE_BOOLEAN:
646 return (java_arrayheader*) builtin_newarray_boolean (size);
648 return (java_arrayheader*) builtin_newarray_char (size);
649 case ARRAYTYPE_FLOAT:
650 return (java_arrayheader*) builtin_newarray_float (size);
651 case ARRAYTYPE_DOUBLE:
652 return (java_arrayheader*) builtin_newarray_double (size);
654 return (java_arrayheader*) builtin_newarray_byte (size);
655 case ARRAYTYPE_SHORT:
656 return (java_arrayheader*) builtin_newarray_short (size);
658 return (java_arrayheader*) builtin_newarray_int (size);
660 return (java_arrayheader*) builtin_newarray_long (size);
661 case ARRAYTYPE_OBJECT:
662 return (java_arrayheader*) builtin_anewarray (size, desc->objectclass);
664 case ARRAYTYPE_ARRAY:
665 return (java_arrayheader*) builtin_newarray_array (size, desc->elementdescriptor);
667 default: panic ("Invalid arraytype in multianewarray");
671 /* wenn letzte Dimension noch nicht erreicht wurde */
673 if (desc->arraytype != ARRAYTYPE_ARRAY)
674 panic ("multianewarray with too many dimensions");
676 a = builtin_newarray_array (size, desc->elementdescriptor);
679 for (i=0; i<size; i++) {
680 java_arrayheader *ea =
681 multianewarray_part (dims, thisdim+1, desc->elementdescriptor);
682 if (!ea) return NULL;
687 return (java_arrayheader*) a;
691 java_arrayheader *builtin_multianewarray (java_intarray *dims,
692 constant_arraydescriptor *desc)
694 return multianewarray_part (dims, 0, desc);
698 static java_arrayheader *nmultianewarray_part (int n, long *dims, int thisdim,
699 constant_arraydescriptor *desc)
704 size = (int) dims[thisdim];
706 if (thisdim == (n - 1)) {
707 /* letzte Dimension schon erreicht */
709 switch (desc -> arraytype) {
710 case ARRAYTYPE_BOOLEAN:
711 return (java_arrayheader*) builtin_newarray_boolean(size);
713 return (java_arrayheader*) builtin_newarray_char(size);
714 case ARRAYTYPE_FLOAT:
715 return (java_arrayheader*) builtin_newarray_float(size);
716 case ARRAYTYPE_DOUBLE:
717 return (java_arrayheader*) builtin_newarray_double(size);
719 return (java_arrayheader*) builtin_newarray_byte(size);
720 case ARRAYTYPE_SHORT:
721 return (java_arrayheader*) builtin_newarray_short(size);
723 return (java_arrayheader*) builtin_newarray_int(size);
725 return (java_arrayheader*) builtin_newarray_long(size);
726 case ARRAYTYPE_OBJECT:
727 return (java_arrayheader*) builtin_anewarray(size,
729 case ARRAYTYPE_ARRAY:
730 return (java_arrayheader*) builtin_newarray_array(size,
731 desc->elementdescriptor);
733 default: panic ("Invalid arraytype in multianewarray");
737 /* wenn letzte Dimension noch nicht erreicht wurde */
739 if (desc->arraytype != ARRAYTYPE_ARRAY)
740 panic ("multianewarray with too many dimensions");
742 a = builtin_newarray_array(size, desc->elementdescriptor);
745 for (i = 0; i < size; i++) {
746 java_arrayheader *ea =
747 nmultianewarray_part(n, dims, thisdim + 1, desc->elementdescriptor);
748 if (!ea) return NULL;
753 return (java_arrayheader*) a;
757 java_arrayheader *builtin_nmultianewarray (int size,
758 constant_arraydescriptor *desc, long *dims)
760 (void) builtin_newarray_int(size); /* for compatibility with -old */
761 return nmultianewarray_part (size, dims, 0, desc);
767 /************************* Funktion: builtin_aastore *************************
769 speichert eine Referenz auf ein Objekt in einem Object-Array oder
770 in einem Array-Array.
771 Dabei wird allerdings vorher "uberpr"uft, ob diese Operation
774 Return: 1, wenn alles OK ist
775 0, wenn dieses Objekt nicht in dieses Array gespeichert werden
778 *****************************************************************************/
780 s4 builtin_aastore (java_objectarray *a, s4 index, java_objectheader *o)
782 if (builtin_canstore(a,o)) {
794 /*****************************************************************************
795 METHODEN-PROTOKOLLIERUNG
797 Verschiedene Funktionen, mit denen eine Meldung ausgegeben werden
798 kann, wann immer Methoden aufgerufen oder beendet werden.
801 *****************************************************************************/
806 java_objectheader *builtin_trace_exception (java_objectheader *exceptionptr,
807 methodinfo *method, int *pos, int noindent) {
811 if (verbose || runverbose) {
812 printf("Exception ");
813 utf_display (exceptionptr->vftbl->class->name);
814 printf(" thrown in ");
816 utf_display (method->class->name);
818 utf_display (method->name);
819 if (method->flags & ACC_SYNCHRONIZED)
823 printf("(%p) at position %p\n", method->entrypoint, pos);
826 printf("call_java_method\n");
833 void builtin_trace_args(long a0, long a1, long a2, long a3, long a4, long a5,
836 sprintf (logtext, " ");
837 sprintf (logtext+methodindent, "called: ");
838 utf_sprint (logtext+strlen(logtext), method->class->name);
839 sprintf (logtext+strlen(logtext), ".");
840 utf_sprint (logtext+strlen(logtext), method->name);
841 utf_sprint (logtext+strlen(logtext), method->descriptor);
842 sprintf (logtext+strlen(logtext), "(");
843 switch (method->paramcount) {
845 sprintf(logtext+strlen(logtext), "%lx, %lx, %lx, %lx, %lx, %lx",
846 a0, a1, a2, a3, a4, a5);
849 sprintf(logtext+strlen(logtext), "%lx, %lx, %lx, %lx, %lx",
853 sprintf(logtext+strlen(logtext), "%lx, %lx, %lx, %lx",
857 sprintf(logtext+strlen(logtext), "%lx, %lx, %lx", a0, a1, a2);
860 sprintf(logtext+strlen(logtext), "%lx, %lx", a0, a1);
863 sprintf(logtext+strlen(logtext), "%lx", a0);
866 sprintf (logtext+strlen(logtext), ")");
872 void builtin_displaymethodstart(methodinfo *method)
874 sprintf (logtext, " ");
875 sprintf (logtext+methodindent, "called: ");
876 utf_sprint (logtext+strlen(logtext), method->class->name);
877 sprintf (logtext+strlen(logtext), ".");
878 utf_sprint (logtext+strlen(logtext), method->name);
879 utf_sprint (logtext+strlen(logtext), method->descriptor);
884 void builtin_displaymethodstop(methodinfo *method, long l, double d)
887 sprintf (logtext, " ");
888 sprintf (logtext+methodindent, "finished: ");
889 utf_sprint (logtext+strlen(logtext), method->class->name);
890 sprintf (logtext+strlen(logtext), ".");
891 utf_sprint (logtext+strlen(logtext), method->name);
892 utf_sprint (logtext+strlen(logtext), method->descriptor);
893 switch (method->returntype) {
896 sprintf (logtext+strlen(logtext), "->%ld", l);
900 sprintf (logtext+strlen(logtext), "->%g", d);
903 sprintf (logtext+strlen(logtext), "->%p", (void*) l);
909 void builtin_displaymethodexception(methodinfo *method)
911 sprintf (logtext, " ");
912 sprintf (logtext+methodindent, "exception abort: ");
913 utf_sprint (logtext+strlen(logtext), method->class->name);
914 sprintf (logtext+strlen(logtext), ".");
915 utf_sprint (logtext+strlen(logtext), method->name);
916 utf_sprint (logtext+strlen(logtext), method->descriptor);
921 /****************************************************************************
922 SYNCHRONIZATION FUNCTIONS
923 *****************************************************************************/
926 * Lock the mutex of an object.
930 internal_lock_mutex_for_object (java_objectheader *object)
932 mutexHashEntry *entry;
937 hashValue = MUTEX_HASH_VALUE(object);
938 entry = &mutexHashTable[hashValue];
940 if (entry->object != 0)
942 if (entry->mutex.count == 0 && entry->conditionCount == 0)
945 entry->mutex.holder = 0;
946 entry->mutex.count = 0;
947 entry->mutex.muxWaiters = 0;
951 while (entry->next != 0 && entry->object != object)
954 if (entry->object != object)
956 entry->next = firstFreeOverflowEntry;
957 firstFreeOverflowEntry = firstFreeOverflowEntry->next;
962 assert(entry->conditionCount == 0);
968 entry->mutex.holder = 0;
969 entry->mutex.count = 0;
970 entry->mutex.muxWaiters = 0;
973 if (entry->object == 0)
974 entry->object = object;
976 internal_lock_mutex(&entry->mutex);
982 * Unlocks the mutex of an object.
986 internal_unlock_mutex_for_object (java_objectheader *object)
989 mutexHashEntry *entry;
991 hashValue = MUTEX_HASH_VALUE(object);
992 entry = &mutexHashTable[hashValue];
994 if (entry->object == object)
995 internal_unlock_mutex(&entry->mutex);
998 while (entry->next != 0 && entry->next->object != object)
1001 assert(entry->next != 0);
1003 internal_unlock_mutex(&entry->next->mutex);
1005 if (entry->next->mutex.count == 0 && entry->conditionCount == 0)
1007 mutexHashEntry *unlinked = entry->next;
1009 entry->next = unlinked->next;
1010 unlinked->next = firstFreeOverflowEntry;
1011 firstFreeOverflowEntry = unlinked;
1018 builtin_monitorenter (java_objectheader *o)
1023 assert(blockInts == 0);
1027 hashValue = MUTEX_HASH_VALUE(o);
1028 if (mutexHashTable[hashValue].object == o
1029 && mutexHashTable[hashValue].mutex.holder == currentThread)
1030 ++mutexHashTable[hashValue].mutex.count;
1032 internal_lock_mutex_for_object(o);
1036 assert(blockInts == 0);
1040 void builtin_monitorexit (java_objectheader *o)
1045 assert(blockInts == 0);
1049 hashValue = MUTEX_HASH_VALUE(o);
1050 if (mutexHashTable[hashValue].object == o)
1052 if (mutexHashTable[hashValue].mutex.count == 1
1053 && mutexHashTable[hashValue].mutex.muxWaiters != 0)
1054 internal_unlock_mutex_for_object(o);
1056 --mutexHashTable[hashValue].mutex.count;
1059 internal_unlock_mutex_for_object(o);
1063 assert(blockInts == 0);
1068 /*****************************************************************************
1069 DIVERSE HILFSFUNKTIONEN
1070 *****************************************************************************/
1074 /*********** Funktionen f"ur die Integerdivision *****************************
1076 Auf manchen Systemen (z.B. DEC ALPHA) wird durch die CPU keine Integer-
1077 division unterst"utzt.
1078 Daf"ur gibt es dann diese Hilfsfunktionen
1080 ******************************************************************************/
1082 s4 builtin_idiv (s4 a, s4 b) { return a/b; }
1083 s4 builtin_irem (s4 a, s4 b) { return a%b; }
1086 /************** Funktionen f"ur Long-Arithmetik *******************************
1088 Auf Systemen, auf denen die CPU keine 64-Bit-Integers unterst"utzt,
1089 werden diese Funktionen gebraucht
1091 ******************************************************************************/
1094 s8 builtin_ladd (s8 a, s8 b)
1099 return builtin_i2l(0);
1103 s8 builtin_lsub (s8 a, s8 b)
1108 return builtin_i2l(0);
1112 s8 builtin_lmul (s8 a, s8 b)
1117 return builtin_i2l(0);
1121 s8 builtin_ldiv (s8 a, s8 b)
1126 return builtin_i2l(0);
1130 s8 builtin_lrem (s8 a, s8 b)
1135 return builtin_i2l(0);
1139 s8 builtin_lshl (s8 a, s4 b)
1144 return builtin_i2l(0);
1148 s8 builtin_lshr (s8 a, s4 b)
1153 return builtin_i2l(0);
1157 s8 builtin_lushr (s8 a, s4 b)
1160 return ((u8)a)>>(b&63);
1162 return builtin_i2l(0);
1166 s8 builtin_land (s8 a, s8 b)
1171 return builtin_i2l(0);
1175 s8 builtin_lor (s8 a, s8 b)
1180 return builtin_i2l(0);
1184 s8 builtin_lxor (s8 a, s8 b)
1189 return builtin_i2l(0);
1193 s8 builtin_lneg (s8 a)
1198 return builtin_i2l(0);
1202 s4 builtin_lcmp (s8 a, s8 b)
1217 /*********** Funktionen f"ur die Floating-Point-Operationen ******************/
1219 float builtin_fadd (float a, float b)
1221 if (isnanf(a)) return FLT_NAN;
1222 if (isnanf(b)) return FLT_NAN;
1224 if (finitef(b)) return a+b;
1228 if (finitef(b)) return a;
1230 if (copysignf(1.0, a)==copysignf(1.0, b)) return a;
1231 else return FLT_NAN;
1236 float builtin_fsub (float a, float b)
1238 return builtin_fadd (a, builtin_fneg(b));
1241 float builtin_fmul (float a, float b)
1243 if (isnanf(a)) return FLT_NAN;
1244 if (isnanf(b)) return FLT_NAN;
1246 if (finitef(b)) return a*b;
1248 if (a==0) return FLT_NAN;
1249 else return copysignf(b, copysignf(1.0, b)*a);
1254 if (b==0) return FLT_NAN;
1255 else return copysignf(a, copysignf(1.0, a)*b);
1258 return copysignf(a, copysignf(1.0, a)*copysignf(1.0, b));
1263 float builtin_fdiv (float a, float b)
1265 if (finitef(a) && finitef(b)) {
1278 float builtin_frem (float a, float b)
1281 /* return (float) builtin_drem((double) a, (double) b); */
1285 if (finite((double) a) && finite((double) b)) {
1287 if (finite((double) f))
1291 if (isnan((double) b))
1293 if (finite((double) a))
1299 if (finitef(a) && finitef(b)) {
1302 return a - floorf(f) * b;
1313 float builtin_fneg (float a)
1315 if (isnanf(a)) return a;
1317 if (finitef(a)) return -a;
1318 else return copysignf(a,-copysignf(1.0, a));
1322 s4 builtin_fcmpl (float a, float b)
1324 if (isnanf(a)) return -1;
1325 if (isnanf(b)) return -1;
1326 if (!finitef(a) || !finitef(b)) {
1327 a = finitef(a) ? 0 : copysignf(1.0, a);
1328 b = finitef(b) ? 0 : copysignf(1.0, b);
1335 s4 builtin_fcmpg (float a, float b)
1337 if (isnanf(a)) return 1;
1338 if (isnanf(b)) return 1;
1339 if (!finitef(a) || !finitef(b)) {
1340 a = finitef(a) ? 0 : copysignf(1.0, a);
1341 b = finitef(b) ? 0 : copysignf(1.0, b);
1350 /*********** Funktionen f"ur doppelt genaue Fliesskommazahlen ***************/
1352 double builtin_dadd (double a, double b)
1354 if (isnan(a)) return DBL_NAN;
1355 if (isnan(b)) return DBL_NAN;
1357 if (finite(b)) return a+b;
1361 if (finite(b)) return a;
1363 if (copysign(1.0, a)==copysign(1.0, b)) return a;
1364 else return DBL_NAN;
1369 double builtin_dsub (double a, double b)
1371 return builtin_dadd (a, builtin_dneg(b));
1374 double builtin_dmul (double a, double b)
1376 if (isnan(a)) return DBL_NAN;
1377 if (isnan(b)) return DBL_NAN;
1379 if (finite(b)) return a*b;
1381 if (a==0) return DBL_NAN;
1382 else return copysign(b, copysign(1.0, b)*a);
1387 if (b==0) return DBL_NAN;
1388 else return copysign(a, copysign(1.0, a)*b);
1391 return copysign(a, copysign(1.0, a)*copysign(1.0, b));
1396 double builtin_ddiv (double a, double b)
1398 if (finite(a) && finite(b)) {
1411 double builtin_drem (double a, double b)
1415 if (finite(a) && finite(b)) {
1418 if ((d < 1.0) && (d > 0.0))
1431 double builtin_dneg (double a)
1433 if (isnan(a)) return a;
1435 if (finite(a)) return -a;
1436 else return copysign(a,-copysign(1.0, a));
1440 s4 builtin_dcmpl (double a, double b)
1442 if (isnan(a)) return -1;
1443 if (isnan(b)) return -1;
1444 if (!finite(a) || !finite(b)) {
1445 a = finite(a) ? 0 : copysign(1.0, a);
1446 b = finite(b) ? 0 : copysign(1.0, b);
1453 s4 builtin_dcmpg (double a, double b)
1455 if (isnan(a)) return 1;
1456 if (isnan(b)) return 1;
1457 if (!finite(a) || !finite(b)) {
1458 a = finite(a) ? 0 : copysign(1.0, a);
1459 b = finite(b) ? 0 : copysign(1.0, b);
1467 /*********************** Umwandlungsoperationen ****************************/
1469 s8 builtin_i2l (s4 i)
1474 s8 v; v.high = 0; v.low=i; return v;
1478 float builtin_i2f (s4 a)
1480 float f = (float) a;
1484 double builtin_i2d (s4 a)
1486 double d = (double) a;
1491 s4 builtin_l2i (s8 l)
1500 float builtin_l2f (s8 a)
1503 float f = (float) a;
1510 double builtin_l2d (s8 a)
1513 double d = (double) a;
1521 s4 builtin_f2i(float a)
1524 return builtin_d2i((double) a);
1533 if (a < (-2147483648))
1534 return (-2147483648);
1537 f = copysignf((float) 1.0, a);
1540 return (-2147483648); */
1544 s8 builtin_f2l (float a)
1547 return builtin_d2l((double) a);
1552 if (a > 9223372036854775807L)
1553 return 9223372036854775807L;
1554 if (a < (-9223372036854775808L))
1555 return (-9223372036854775808L);
1560 f = copysignf((float) 1.0, a);
1562 return 9223372036854775807L;
1563 return (-9223372036854775808L); */
1567 double builtin_f2d (float a)
1569 if (finitef(a)) return (double) a;
1571 if (isnanf(a)) return DBL_NAN;
1572 else return copysign(DBL_POSINF, (double) copysignf(1.0, a) );
1577 s4 builtin_d2i (double a)
1582 if (a >= 2147483647)
1584 if (a <= (-2147483648))
1585 return (-2147483648);
1590 d = copysign(1.0, a);
1593 return (-2147483648);
1597 s8 builtin_d2l (double a)
1602 if (a >= 9223372036854775807L)
1603 return 9223372036854775807L;
1604 if (a <= (-9223372036854775807L-1))
1605 return (-9223372036854775807L-1);
1610 d = copysign(1.0, a);
1612 return 9223372036854775807L;
1613 return (-9223372036854775807L-1);
1617 float builtin_d2f (double a)
1619 if (finite(a)) return (float) a;
1621 if (isnan(a)) return FLT_NAN;
1622 else return copysignf (FLT_POSINF, (float) copysign(1.0, a));
1628 * These are local overrides for various environment variables in Emacs.
1629 * Please do not remove this and leave it at the end of the file, where
1630 * Emacs will automagically detect them.
1631 * ---------------------------------------------------------------------
1634 * indent-tabs-mode: t