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 "sysdep/native-math.h"
33 builtin_descriptor builtin_desc[] = {
34 {(functionptr) builtin_instanceof, "instanceof"},
35 {(functionptr) builtin_checkcast, "checkcast"},
36 {(functionptr) builtin_arrayinstanceof, "arrayinstanceof"},
37 {(functionptr) builtin_checkarraycast, "checkarraycast"},
38 {(functionptr) asm_builtin_checkarraycast, "checkarraycast"},
39 {(functionptr) asm_builtin_aastore, "aastore"},
40 {(functionptr) builtin_new, "new"},
41 {(functionptr) builtin_anewarray, "anewarray"},
42 {(functionptr) builtin_newarray_array, "newarray_array"},
43 {(functionptr) builtin_newarray_boolean, "newarray_boolean"},
44 {(functionptr) builtin_newarray_char, "newarray_char"},
45 {(functionptr) builtin_newarray_float, "newarray_float"},
46 {(functionptr) builtin_newarray_double, "newarray_double"},
47 {(functionptr) builtin_newarray_byte, "newarray_byte"},
48 {(functionptr) builtin_newarray_short, "newarray_short"},
49 {(functionptr) builtin_newarray_int, "newarray_int"},
50 {(functionptr) builtin_newarray_long, "newarray_long"},
51 {(functionptr) builtin_displaymethodstart, "displaymethodstart"},
52 {(functionptr) builtin_displaymethodstop, "displaymethodstop"},
53 {(functionptr) builtin_monitorenter, "monitorenter"},
54 {(functionptr) asm_builtin_monitorenter, "monitorenter"},
55 {(functionptr) builtin_monitorexit, "monitorexit"},
56 {(functionptr) asm_builtin_monitorexit, "monitorexit"},
57 {(functionptr) builtin_idiv, "idiv"},
58 {(functionptr) asm_builtin_idiv, "idiv"},
59 {(functionptr) builtin_irem, "irem"},
60 {(functionptr) asm_builtin_irem, "irem"},
61 {(functionptr) builtin_ladd, "ladd"},
62 {(functionptr) builtin_lsub, "lsub"},
63 {(functionptr) builtin_lmul, "lmul"},
64 {(functionptr) builtin_ldiv, "ldiv"},
65 {(functionptr) asm_builtin_ldiv, "ldiv"},
66 {(functionptr) builtin_lrem, "lrem"},
67 {(functionptr) asm_builtin_lrem, "lrem"},
68 {(functionptr) builtin_lshl, "lshl"},
69 {(functionptr) builtin_lshr, "lshr"},
70 {(functionptr) builtin_lushr, "lushr"},
71 {(functionptr) builtin_land, "land"},
72 {(functionptr) builtin_lor, "lor"},
73 {(functionptr) builtin_lxor, "lxor"},
74 {(functionptr) builtin_lneg, "lneg"},
75 {(functionptr) builtin_lcmp, "lcmp"},
76 {(functionptr) builtin_fadd, "fadd"},
77 {(functionptr) builtin_fsub, "fsub"},
78 {(functionptr) builtin_fmul, "fmul"},
79 {(functionptr) builtin_fdiv, "fdiv"},
80 {(functionptr) builtin_frem, "frem"},
81 {(functionptr) builtin_fneg, "fneg"},
82 {(functionptr) builtin_fcmpl, "fcmpl"},
83 {(functionptr) builtin_fcmpg, "fcmpg"},
84 {(functionptr) builtin_dadd, "dadd"},
85 {(functionptr) builtin_dsub, "dsub"},
86 {(functionptr) builtin_dmul, "dmul"},
87 {(functionptr) builtin_ddiv, "ddiv"},
88 {(functionptr) builtin_drem, "drem"},
89 {(functionptr) builtin_dneg, "dneg"},
90 {(functionptr) builtin_dcmpl, "dcmpl"},
91 {(functionptr) builtin_dcmpg, "dcmpg"},
92 {(functionptr) builtin_i2l, "i2l"},
93 {(functionptr) builtin_i2f, "i2f"},
94 {(functionptr) builtin_i2d, "i2d"},
95 {(functionptr) builtin_l2i, "l2i"},
96 {(functionptr) builtin_l2f, "l2f"},
97 {(functionptr) builtin_l2d, "l2d"},
98 {(functionptr) builtin_f2i, "f2i"},
99 {(functionptr) builtin_f2l, "f2l"},
100 {(functionptr) builtin_f2d, "f2d"},
101 {(functionptr) builtin_d2i, "d2i"},
102 {(functionptr) builtin_d2l, "d2l"},
103 {(functionptr) builtin_d2f, "d2f"},
104 {(functionptr) NULL, "unknown"}
108 /*****************************************************************************
110 *****************************************************************************/
114 /*************** interne Funktion: builtin_isanysubclass *********************
116 "uberpr"uft, ob eine Klasse eine Unterklasse einer anderen Klasse ist.
117 Dabei gelten auch Interfaces, die eine Klasse implementiert, als
119 R"uckgabewert: 1 ... es trifft zu
120 0 ... es trifft nicht zu
122 *****************************************************************************/
124 static s4 builtin_isanysubclass (classinfo *sub, classinfo *super)
126 if (super->flags & ACC_INTERFACE)
127 return (sub->vftbl->interfacetablelength > super->index) &&
128 (sub->vftbl->interfacetable[-super->index] != NULL);
130 return (unsigned) (sub->vftbl->baseval - super->vftbl->baseval) <=
131 (unsigned) (super->vftbl->diffval);
135 /****************** Funktion: builtin_instanceof *****************************
137 "Uberpr"uft, ob ein Objekt eine Instanz einer Klasse (oder einer davon
138 abgeleiteten Klasse) ist, oder ob die Klasse des Objekts ein Interface
141 0, wenn nicht, oder wenn Objekt ein NULL-Zeiger
143 *****************************************************************************/
145 s4 builtin_instanceof(java_objectheader *obj, classinfo *class)
148 log_text ("builtin_instanceof called");
152 return builtin_isanysubclass (obj->vftbl->class, class);
157 /**************** Funktion: builtin_checkcast *******************************
159 "Uberpr"uft, ob ein Objekt eine Instanz einer Klasse (oder einer davon
160 abgeleiteten Klasse ist).
161 Unterschied zu builtin_instanceof: Ein NULL-Zeiger ist immer richtig
162 Return: 1, wenn ja, oder wenn Objekt ein NULL-Zeiger
165 ****************************************************************************/
167 s4 builtin_checkcast(java_objectheader *obj, classinfo *class)
170 log_text ("builtin_checkcast called");
175 if (builtin_isanysubclass (obj->vftbl->class, class))
179 printf ("#### checkcast failed ");
180 unicode_display (obj->vftbl->class->name);
182 unicode_display (class->name);
190 /*********** interne Funktion: builtin_descriptorscompatible ******************
192 "uberpr"uft, ob zwei Array-Typdescriptoren compartible sind, d.h.,
193 ob ein Array vom Typ 'desc' gefahrlos einer Variblen vom Typ 'target'
194 zugewiesen werden kann.
198 ******************************************************************************/
200 static s4 builtin_descriptorscompatible
201 (constant_arraydescriptor *desc, constant_arraydescriptor *target)
203 if (desc==target) return 1;
204 if (desc->arraytype != target->arraytype) return 0;
205 switch (target->arraytype) {
206 case ARRAYTYPE_OBJECT:
207 return builtin_isanysubclass (desc->objectclass, target->objectclass);
208 case ARRAYTYPE_ARRAY:
209 return builtin_descriptorscompatible
210 (desc->elementdescriptor, target->elementdescriptor);
217 /******************** Funktion: builtin_checkarraycast ***********************
219 "uberpr"uft, ob ein gegebenes Objekt tats"achlich von einem
220 Untertyp des geforderten Arraytyps ist.
221 Dazu muss das Objekt auf jeden Fall ein Array sein.
222 Bei einfachen Arrays (int,short,double,etc.) muss der Typ genau
224 Bei Arrays von Objekten muss der Elementtyp des tats"achlichen Arrays
225 ein Untertyp (oder der selbe Typ) vom geforderten Elementtyp sein.
226 Bei Arrays vom Arrays (die eventuell wieder Arrays von Arrays
227 sein k"onnen) m"ussen die untersten Elementtypen in der entsprechenden
228 Unterklassenrelation stehen.
230 Return: 1, wenn Cast in Ordung ist
231 0, wenn es nicht geht
233 Achtung: ein Cast mit einem NULL-Zeiger geht immer gut.
235 *****************************************************************************/
237 s4 builtin_checkarraycast(java_objectheader *o, constant_arraydescriptor *desc)
239 java_arrayheader *a = (java_arrayheader*) o;
242 if (o->vftbl->class != class_array) {
246 if (a->arraytype != desc->arraytype) {
250 switch (a->arraytype) {
251 case ARRAYTYPE_OBJECT: {
252 java_objectarray *oa = (java_objectarray*) o;
253 return builtin_isanysubclass (oa->elementtype, desc->objectclass);
255 case ARRAYTYPE_ARRAY: {
256 java_arrayarray *aa = (java_arrayarray*) o;
257 return builtin_descriptorscompatible
258 (aa->elementdescriptor, desc->elementdescriptor);
266 s4 builtin_arrayinstanceof
267 (java_objectheader *obj, constant_arraydescriptor *desc)
270 return builtin_checkarraycast (obj, desc);
274 /************************** exception functions *******************************
276 ******************************************************************************/
278 java_objectheader *builtin_throw_exception (java_objectheader *exceptionptr) {
279 unicode_display (exceptionptr->vftbl->class->name);
286 /******************* Funktion: builtin_canstore *******************************
288 "uberpr"uft, ob ein Objekt in einem Array gespeichert werden
290 Return: 1, wenn es geht
293 ******************************************************************************/
296 s4 builtin_canstore (java_objectarray *a, java_objectheader *o)
300 switch (a->header.arraytype) {
301 case ARRAYTYPE_OBJECT:
302 if ( ! builtin_checkcast (o, a->elementtype) ) {
308 case ARRAYTYPE_ARRAY:
309 if ( ! builtin_checkarraycast
310 (o, ((java_arrayarray*)a)->elementdescriptor) ) {
317 panic ("builtin_canstore called with invalid arraytype");
324 /*****************************************************************************
326 *****************************************************************************/
330 /******************** Funktion: builtin_new **********************************
332 Legt ein neues Objekt einer Klasse am Heap an.
333 Return: Der Zeiger auf das Objekt, oder NULL, wenn kein Speicher
336 *****************************************************************************/
339 #define align_size(size) ((size + ((1 << ALIGNMENT) - 1)) & ~((1 << ALIGNMENT) - 1))
341 java_objectheader *builtin_new (classinfo *c)
343 java_objectheader *o;
345 #ifdef SIZE_FROM_CLASSINFO
346 c->alignedsize = align_size(c->instancesize);
348 o = heap_allocate ( c->alignedsize, true, c->finalizer );
350 o = heap_allocate ( c->instancesize, true, c->finalizer );
354 memset (o, 0, c->instancesize);
356 o -> vftbl = c -> vftbl;
362 /******************** Funktion: builtin_anewarray ****************************
364 Legt ein Array von Zeigern auf Objekte am Heap an.
366 size ......... Anzahl der Elemente
367 elementtype .. ein Zeiger auf die classinfo-Struktur des Typs
370 Return: Zeiger auf das Array, oder NULL (wenn kein Speicher frei)
372 *****************************************************************************/
375 void* __builtin_newarray(s4 base_size,
382 #ifdef SIZE_FROM_CLASSINFO
383 s4 alignedsize = align_size(base_size + (size-1) * elementsize);
385 a = heap_allocate ( alignedsize, true, NULL );
387 a = heap_allocate ( sizeof(java_objectarray) + (size-1) * elementsize,
393 #ifdef SIZE_FROM_CLASSINFO
394 memset(a, 0, alignedsize);
396 memset(a, 0, base_size + (size-1) * elementsize);
399 a -> objheader.vftbl = class_array -> vftbl;
401 #ifdef SIZE_FROM_CLASSINFO
402 a -> alignedsize = alignedsize;
404 a -> arraytype = arraytype;
410 java_objectarray *builtin_anewarray (s4 size, classinfo *elementtype)
413 a = (java_objectarray*)__builtin_newarray(sizeof(java_objectarray),
420 a -> elementtype = elementtype;
426 /******************** Funktion: builtin_newarray_array ***********************
428 Legt ein Array von Zeigern auf Arrays am Heap an.
429 Paramter: size ......... Anzahl der Elemente
430 elementdesc .. Zeiger auf die Arraybeschreibungs-Struktur f"ur
433 Return: Zeiger auf das Array, oder NULL
435 *****************************************************************************/
437 java_arrayarray *builtin_newarray_array
438 (s4 size, constant_arraydescriptor *elementdesc)
441 a = (java_arrayarray*)__builtin_newarray(sizeof(java_arrayarray),
448 a -> elementdescriptor = elementdesc;
453 /******************** Funktion: builtin_newarray_boolean ************************
455 Legt ein Array von Bytes am Heap an, das allerdings als Boolean-Array
456 gekennzeichnet wird (wichtig bei Casts!)
458 Return: Zeiger auf das Array, oder NULL
460 *****************************************************************************/
462 java_booleanarray *builtin_newarray_boolean (s4 size)
464 java_booleanarray *a;
465 a = (java_booleanarray*)__builtin_newarray(sizeof(java_booleanarray),
473 /******************** Funktion: builtin_newarray_char ************************
475 Legt ein Array von 16-bit-Integers am Heap an.
476 Return: Zeiger auf das Array, oder NULL
478 *****************************************************************************/
480 java_chararray *builtin_newarray_char (s4 size)
483 a = (java_chararray*)__builtin_newarray(sizeof(java_chararray),
492 /******************** Funktion: builtin_newarray_float ***********************
494 Legt ein Array von 32-bit-IEEE-float am Heap an.
495 Return: Zeiger auf das Array, oder NULL
497 *****************************************************************************/
499 java_floatarray *builtin_newarray_float (s4 size)
502 a = (java_floatarray*)__builtin_newarray(sizeof(java_floatarray),
511 /******************** Funktion: builtin_newarray_double ***********************
513 Legt ein Array von 64-bit-IEEE-float am Heap an.
514 Return: Zeiger auf das Array, oder NULL
516 *****************************************************************************/
518 java_doublearray *builtin_newarray_double (s4 size)
521 a = (java_doublearray*)__builtin_newarray(sizeof(java_doublearray),
532 /******************** Funktion: builtin_newarray_byte ***********************
534 Legt ein Array von 8-bit-Integers am Heap an.
535 Return: Zeiger auf das Array, oder NULL
537 *****************************************************************************/
539 java_bytearray *builtin_newarray_byte (s4 size)
542 a = (java_bytearray*)__builtin_newarray(sizeof(java_bytearray),
551 /******************** Funktion: builtin_newarray_short ***********************
553 Legt ein Array von 16-bit-Integers am Heap an.
554 Return: Zeiger auf das Array, oder NULL
556 *****************************************************************************/
558 java_shortarray *builtin_newarray_short (s4 size)
561 a = (java_shortarray*)__builtin_newarray(sizeof(java_shortarray),
570 /******************** Funktion: builtin_newarray_int ***********************
572 Legt ein Array von 32-bit-Integers am Heap an.
573 Return: Zeiger auf das Array, oder NULL
575 *****************************************************************************/
577 java_intarray *builtin_newarray_int (s4 size)
580 a = (java_intarray*)__builtin_newarray(sizeof(java_intarray),
589 /******************** Funktion: builtin_newarray_long ***********************
591 Legt ein Array von 64-bit-Integers am Heap an.
592 Return: Zeiger auf das Array, oder NULL
594 *****************************************************************************/
596 java_longarray *builtin_newarray_long (s4 size)
599 a = (java_longarray*)__builtin_newarray(sizeof(java_longarray),
609 /***************** Funktion: builtin_multianewarray ***************************
611 Legt ein mehrdimensionales Array am Heap an.
612 Die Gr"ossen der einzelnen Dimensionen werden in einem Integerarray
613 "ubergeben. Der Typ es zu erzeugenden Arrays wird als
614 Referenz auf eine constant_arraydescriptor - Struktur "ubergeben.
616 Return: Ein Zeiger auf das Array, oder NULL, wenn kein Speicher mehr
619 ******************************************************************************/
623 static java_arrayheader *multianewarray_part (java_intarray *dims, int thisdim,
624 constant_arraydescriptor *desc)
629 size = dims -> data[thisdim];
631 if (thisdim == (dims->header.size-1)) {
632 /* letzte Dimension schon erreicht */
634 switch (desc -> arraytype) {
635 case ARRAYTYPE_BOOLEAN:
636 return (java_arrayheader*) builtin_newarray_boolean (size);
638 return (java_arrayheader*) builtin_newarray_char (size);
639 case ARRAYTYPE_FLOAT:
640 return (java_arrayheader*) builtin_newarray_float (size);
641 case ARRAYTYPE_DOUBLE:
642 return (java_arrayheader*) builtin_newarray_double (size);
644 return (java_arrayheader*) builtin_newarray_byte (size);
645 case ARRAYTYPE_SHORT:
646 return (java_arrayheader*) builtin_newarray_short (size);
648 return (java_arrayheader*) builtin_newarray_int (size);
650 return (java_arrayheader*) builtin_newarray_long (size);
651 case ARRAYTYPE_OBJECT:
652 return (java_arrayheader*) builtin_anewarray (size, desc->objectclass);
654 case ARRAYTYPE_ARRAY:
655 return (java_arrayheader*) builtin_newarray_array (size, desc->elementdescriptor);
657 default: panic ("Invalid arraytype in multianewarray");
661 /* wenn letzte Dimension noch nicht erreicht wurde */
663 if (desc->arraytype != ARRAYTYPE_ARRAY)
664 panic ("multianewarray with too many dimensions");
666 a = builtin_newarray_array (size, desc->elementdescriptor);
669 for (i=0; i<size; i++) {
670 java_arrayheader *ea =
671 multianewarray_part (dims, thisdim+1, desc->elementdescriptor);
672 if (!ea) return NULL;
677 return (java_arrayheader*) a;
681 java_arrayheader *builtin_multianewarray (java_intarray *dims,
682 constant_arraydescriptor *desc)
684 return multianewarray_part (dims, 0, desc);
688 static java_arrayheader *nmultianewarray_part (int n, long *dims, int thisdim,
689 constant_arraydescriptor *desc)
694 size = (int) dims[thisdim];
696 if (thisdim == (n - 1)) {
697 /* letzte Dimension schon erreicht */
699 switch (desc -> arraytype) {
700 case ARRAYTYPE_BOOLEAN:
701 return (java_arrayheader*) builtin_newarray_boolean(size);
703 return (java_arrayheader*) builtin_newarray_char(size);
704 case ARRAYTYPE_FLOAT:
705 return (java_arrayheader*) builtin_newarray_float(size);
706 case ARRAYTYPE_DOUBLE:
707 return (java_arrayheader*) builtin_newarray_double(size);
709 return (java_arrayheader*) builtin_newarray_byte(size);
710 case ARRAYTYPE_SHORT:
711 return (java_arrayheader*) builtin_newarray_short(size);
713 return (java_arrayheader*) builtin_newarray_int(size);
715 return (java_arrayheader*) builtin_newarray_long(size);
716 case ARRAYTYPE_OBJECT:
717 return (java_arrayheader*) builtin_anewarray(size,
719 case ARRAYTYPE_ARRAY:
720 return (java_arrayheader*) builtin_newarray_array(size,
721 desc->elementdescriptor);
723 default: panic ("Invalid arraytype in multianewarray");
727 /* wenn letzte Dimension noch nicht erreicht wurde */
729 if (desc->arraytype != ARRAYTYPE_ARRAY)
730 panic ("multianewarray with too many dimensions");
732 a = builtin_newarray_array(size, desc->elementdescriptor);
735 for (i = 0; i < size; i++) {
736 java_arrayheader *ea =
737 nmultianewarray_part(n, dims, thisdim + 1, desc->elementdescriptor);
738 if (!ea) return NULL;
743 return (java_arrayheader*) a;
747 java_arrayheader *builtin_nmultianewarray (int size,
748 constant_arraydescriptor *desc, long *dims)
750 (void) builtin_newarray_int(size); /* for compatibility with -old */
751 return nmultianewarray_part (size, dims, 0, desc);
757 /************************* Funktion: builtin_aastore *************************
759 speichert eine Referenz auf ein Objekt in einem Object-Array oder
760 in einem Array-Array.
761 Dabei wird allerdings vorher "uberpr"uft, ob diese Operation
764 Return: 1, wenn alles OK ist
765 0, wenn dieses Objekt nicht in dieses Array gespeichert werden
768 *****************************************************************************/
770 s4 builtin_aastore (java_objectarray *a, s4 index, java_objectheader *o)
772 if (builtin_canstore(a,o)) {
784 /*****************************************************************************
785 METHODEN-PROTOKOLLIERUNG
787 Verschiedene Funktionen, mit denen eine Meldung ausgegeben werden
788 kann, wann immer Methoden aufgerufen oder beendet werden.
791 *****************************************************************************/
796 java_objectheader *builtin_trace_exception (java_objectheader *exceptionptr,
797 methodinfo *method, int *pos, int noindent) {
801 if (verbose || runverbose) {
802 printf("Exception ");
803 unicode_display (exceptionptr->vftbl->class->name);
804 printf(" thrown in ");
806 unicode_display (method->class->name);
808 unicode_display (method->name);
809 if (method->flags & ACC_SYNCHRONIZED)
813 printf("(%p) at position %p\n", method->entrypoint, pos);
816 printf("call_java_method\n");
823 void builtin_trace_args(long a0, long a1, long a2, long a3, long a4, long a5,
826 sprintf (logtext, " ");
827 sprintf (logtext+methodindent, "called: ");
828 unicode_sprint (logtext+strlen(logtext), method->class->name);
829 sprintf (logtext+strlen(logtext), ".");
830 unicode_sprint (logtext+strlen(logtext), method->name);
831 unicode_sprint (logtext+strlen(logtext), method->descriptor);
832 sprintf (logtext+strlen(logtext), "(");
833 switch (method->paramcount) {
835 sprintf(logtext+strlen(logtext), "%lx, %lx, %lx, %lx, %lx, %lx",
836 a0, a1, a2, a3, a4, a5);
839 sprintf(logtext+strlen(logtext), "%lx, %lx, %lx, %lx, %lx",
843 sprintf(logtext+strlen(logtext), "%lx, %lx, %lx, %lx",
847 sprintf(logtext+strlen(logtext), "%lx, %lx, %lx", a0, a1, a2);
850 sprintf(logtext+strlen(logtext), "%lx, %lx", a0, a1);
853 sprintf(logtext+strlen(logtext), "%lx", a0);
856 sprintf (logtext+strlen(logtext), ")");
862 void builtin_displaymethodstart(methodinfo *method)
864 sprintf (logtext, " ");
865 sprintf (logtext+methodindent, "called: ");
866 unicode_sprint (logtext+strlen(logtext), method->class->name);
867 sprintf (logtext+strlen(logtext), ".");
868 unicode_sprint (logtext+strlen(logtext), method->name);
869 unicode_sprint (logtext+strlen(logtext), method->descriptor);
874 void builtin_displaymethodstop(methodinfo *method, long l, double d)
877 sprintf (logtext, " ");
878 sprintf (logtext+methodindent, "finished: ");
879 unicode_sprint (logtext+strlen(logtext), method->class->name);
880 sprintf (logtext+strlen(logtext), ".");
881 unicode_sprint (logtext+strlen(logtext), method->name);
882 unicode_sprint (logtext+strlen(logtext), method->descriptor);
883 switch (method->returntype) {
886 sprintf (logtext+strlen(logtext), "->%ld", l);
890 sprintf (logtext+strlen(logtext), "->%g", d);
893 sprintf (logtext+strlen(logtext), "->%p", (void*) l);
899 void builtin_displaymethodexception(methodinfo *method)
901 sprintf (logtext, " ");
902 sprintf (logtext+methodindent, "exception abort: ");
903 unicode_sprint (logtext+strlen(logtext), method->class->name);
904 sprintf (logtext+strlen(logtext), ".");
905 unicode_sprint (logtext+strlen(logtext), method->name);
906 unicode_sprint (logtext+strlen(logtext), method->descriptor);
911 /****************************************************************************
912 SYNCHRONIZATION FUNCTIONS
913 *****************************************************************************/
916 * Lock the mutex of an object.
920 internal_lock_mutex_for_object (java_objectheader *object)
922 mutexHashEntry *entry;
927 hashValue = MUTEX_HASH_VALUE(object);
928 entry = &mutexHashTable[hashValue];
930 if (entry->object != 0)
932 if (entry->mutex.count == 0 && entry->conditionCount == 0)
935 entry->mutex.holder = 0;
936 entry->mutex.count = 0;
937 entry->mutex.muxWaiters = 0;
941 while (entry->next != 0 && entry->object != object)
944 if (entry->object != object)
946 entry->next = firstFreeOverflowEntry;
947 firstFreeOverflowEntry = firstFreeOverflowEntry->next;
952 assert(entry->conditionCount == 0);
958 entry->mutex.holder = 0;
959 entry->mutex.count = 0;
960 entry->mutex.muxWaiters = 0;
963 if (entry->object == 0)
964 entry->object = object;
966 internal_lock_mutex(&entry->mutex);
972 * Unlocks the mutex of an object.
976 internal_unlock_mutex_for_object (java_objectheader *object)
979 mutexHashEntry *entry;
981 hashValue = MUTEX_HASH_VALUE(object);
982 entry = &mutexHashTable[hashValue];
984 if (entry->object == object)
985 internal_unlock_mutex(&entry->mutex);
988 while (entry->next != 0 && entry->next->object != object)
991 assert(entry->next != 0);
993 internal_unlock_mutex(&entry->next->mutex);
995 if (entry->next->mutex.count == 0 && entry->conditionCount == 0)
997 mutexHashEntry *unlinked = entry->next;
999 entry->next = unlinked->next;
1000 unlinked->next = firstFreeOverflowEntry;
1001 firstFreeOverflowEntry = unlinked;
1008 builtin_monitorenter (java_objectheader *o)
1013 assert(blockInts == 0);
1017 hashValue = MUTEX_HASH_VALUE(o);
1018 if (mutexHashTable[hashValue].object == o
1019 && mutexHashTable[hashValue].mutex.holder == currentThread)
1020 ++mutexHashTable[hashValue].mutex.count;
1022 internal_lock_mutex_for_object(o);
1026 assert(blockInts == 0);
1030 void builtin_monitorexit (java_objectheader *o)
1035 assert(blockInts == 0);
1039 hashValue = MUTEX_HASH_VALUE(o);
1040 if (mutexHashTable[hashValue].object == o)
1042 if (mutexHashTable[hashValue].mutex.count == 1
1043 && mutexHashTable[hashValue].mutex.muxWaiters != 0)
1044 internal_unlock_mutex_for_object(o);
1046 --mutexHashTable[hashValue].mutex.count;
1049 internal_unlock_mutex_for_object(o);
1053 assert(blockInts == 0);
1058 /*****************************************************************************
1059 DIVERSE HILFSFUNKTIONEN
1060 *****************************************************************************/
1064 /*********** Funktionen f"ur die Integerdivision *****************************
1066 Auf manchen Systemen (z.B. DEC ALPHA) wird durch die CPU keine Integer-
1067 division unterst"utzt.
1068 Daf"ur gibt es dann diese Hilfsfunktionen
1070 ******************************************************************************/
1072 s4 builtin_idiv (s4 a, s4 b) { return a/b; }
1073 s4 builtin_irem (s4 a, s4 b) { return a%b; }
1076 /************** Funktionen f"ur Long-Arithmetik *******************************
1078 Auf Systemen, auf denen die CPU keine 64-Bit-Integers unterst"utzt,
1079 werden diese Funktionen gebraucht
1081 ******************************************************************************/
1084 s8 builtin_ladd (s8 a, s8 b)
1089 return builtin_i2l(0);
1093 s8 builtin_lsub (s8 a, s8 b)
1098 return builtin_i2l(0);
1102 s8 builtin_lmul (s8 a, s8 b)
1107 return builtin_i2l(0);
1111 s8 builtin_ldiv (s8 a, s8 b)
1116 return builtin_i2l(0);
1120 s8 builtin_lrem (s8 a, s8 b)
1125 return builtin_i2l(0);
1129 s8 builtin_lshl (s8 a, s4 b)
1134 return builtin_i2l(0);
1138 s8 builtin_lshr (s8 a, s4 b)
1143 return builtin_i2l(0);
1147 s8 builtin_lushr (s8 a, s4 b)
1150 return ((u8)a)>>(b&63);
1152 return builtin_i2l(0);
1156 s8 builtin_land (s8 a, s8 b)
1161 return builtin_i2l(0);
1165 s8 builtin_lor (s8 a, s8 b)
1170 return builtin_i2l(0);
1174 s8 builtin_lxor (s8 a, s8 b)
1179 return builtin_i2l(0);
1183 s8 builtin_lneg (s8 a)
1188 return builtin_i2l(0);
1192 s4 builtin_lcmp (s8 a, s8 b)
1207 /*********** Funktionen f"ur die Floating-Point-Operationen ******************/
1209 float builtin_fadd (float a, float b)
1211 if (isnanf(a)) return FLT_NAN;
1212 if (isnanf(b)) return FLT_NAN;
1214 if (finitef(b)) return a+b;
1218 if (finitef(b)) return a;
1220 if (copysignf(1.0, a)==copysignf(1.0, b)) return a;
1221 else return FLT_NAN;
1226 float builtin_fsub (float a, float b)
1228 return builtin_fadd (a, builtin_fneg(b));
1231 float builtin_fmul (float a, float b)
1233 if (isnanf(a)) return FLT_NAN;
1234 if (isnanf(b)) return FLT_NAN;
1236 if (finitef(b)) return a*b;
1238 if (a==0) return FLT_NAN;
1239 else return copysignf(b, copysignf(1.0, b)*a);
1244 if (b==0) return FLT_NAN;
1245 else return copysignf(a, copysignf(1.0, a)*b);
1248 return copysignf(a, copysignf(1.0, a)*copysignf(1.0, b));
1253 float builtin_fdiv (float a, float b)
1255 if (finitef(a) && finitef(b)) {
1268 float builtin_frem (float a, float b)
1271 /* return (float) builtin_drem((double) a, (double) b); */
1275 if (finite((double) a) && finite((double) b)) {
1277 if (finite((double) f))
1281 if (isnan((double) b))
1283 if (finite((double) a))
1289 if (finitef(a) && finitef(b)) {
1292 return a - floorf(f) * b;
1303 float builtin_fneg (float a)
1305 if (isnanf(a)) return a;
1307 if (finitef(a)) return -a;
1308 else return copysignf(a,-copysignf(1.0, a));
1312 s4 builtin_fcmpl (float a, float b)
1314 if (isnanf(a)) return -1;
1315 if (isnanf(b)) return -1;
1316 if (!finitef(a) || !finitef(b)) {
1317 a = finitef(a) ? 0 : copysignf(1.0, a);
1318 b = finitef(b) ? 0 : copysignf(1.0, b);
1325 s4 builtin_fcmpg (float a, float b)
1327 if (isnanf(a)) return 1;
1328 if (isnanf(b)) return 1;
1329 if (!finitef(a) || !finitef(b)) {
1330 a = finitef(a) ? 0 : copysignf(1.0, a);
1331 b = finitef(b) ? 0 : copysignf(1.0, b);
1340 /*********** Funktionen f"ur doppelt genaue Fliesskommazahlen ***************/
1342 double builtin_dadd (double a, double b)
1344 if (isnan(a)) return DBL_NAN;
1345 if (isnan(b)) return DBL_NAN;
1347 if (finite(b)) return a+b;
1351 if (finite(b)) return a;
1353 if (copysign(1.0, a)==copysign(1.0, b)) return a;
1354 else return DBL_NAN;
1359 double builtin_dsub (double a, double b)
1361 return builtin_dadd (a, builtin_dneg(b));
1364 double builtin_dmul (double a, double b)
1366 if (isnan(a)) return DBL_NAN;
1367 if (isnan(b)) return DBL_NAN;
1369 if (finite(b)) return a*b;
1371 if (a==0) return DBL_NAN;
1372 else return copysign(b, copysign(1.0, b)*a);
1377 if (b==0) return DBL_NAN;
1378 else return copysign(a, copysign(1.0, a)*b);
1381 return copysign(a, copysign(1.0, a)*copysign(1.0, b));
1386 double builtin_ddiv (double a, double b)
1388 if (finite(a) && finite(b)) {
1401 double builtin_drem (double a, double b)
1405 if (finite(a) && finite(b)) {
1408 if ((d < 1.0) && (d > 0.0))
1421 double builtin_dneg (double a)
1423 if (isnan(a)) return a;
1425 if (finite(a)) return -a;
1426 else return copysign(a,-copysign(1.0, a));
1430 s4 builtin_dcmpl (double a, double b)
1432 if (isnan(a)) return -1;
1433 if (isnan(b)) return -1;
1434 if (!finite(a) || !finite(b)) {
1435 a = finite(a) ? 0 : copysign(1.0, a);
1436 b = finite(b) ? 0 : copysign(1.0, b);
1443 s4 builtin_dcmpg (double a, double b)
1445 if (isnan(a)) return 1;
1446 if (isnan(b)) return 1;
1447 if (!finite(a) || !finite(b)) {
1448 a = finite(a) ? 0 : copysign(1.0, a);
1449 b = finite(b) ? 0 : copysign(1.0, b);
1457 /*********************** Umwandlungsoperationen ****************************/
1459 s8 builtin_i2l (s4 i)
1464 s8 v; v.high = 0; v.low=i; return v;
1468 float builtin_i2f (s4 a)
1470 float f = (float) a;
1474 double builtin_i2d (s4 a)
1476 double d = (double) a;
1481 s4 builtin_l2i (s8 l)
1490 float builtin_l2f (s8 a)
1493 float f = (float) a;
1500 double builtin_l2d (s8 a)
1503 double d = (double) a;
1511 s4 builtin_f2i(float a)
1514 return builtin_d2i((double) a);
1523 if (a < (-2147483648))
1524 return (-2147483648);
1527 f = copysignf((float) 1.0, a);
1530 return (-2147483648); */
1534 s8 builtin_f2l (float a)
1537 return builtin_d2l((double) a);
1542 if (a > 9223372036854775807L)
1543 return 9223372036854775807L;
1544 if (a < (-9223372036854775808L))
1545 return (-9223372036854775808L);
1550 f = copysignf((float) 1.0, a);
1552 return 9223372036854775807L;
1553 return (-9223372036854775808L); */
1557 double builtin_f2d (float a)
1559 if (finitef(a)) return (double) a;
1561 if (isnanf(a)) return DBL_NAN;
1562 else return copysign(DBL_POSINF, (double) copysignf(1.0, a) );
1567 s4 builtin_d2i (double a)
1572 if (a >= 2147483647)
1574 if (a <= (-2147483648))
1575 return (-2147483648);
1580 d = copysign(1.0, a);
1583 return (-2147483648);
1587 s8 builtin_d2l (double a)
1592 if (a >= 9223372036854775807L)
1593 return 9223372036854775807L;
1594 if (a <= (-9223372036854775807L-1))
1595 return (-9223372036854775807L-1);
1600 d = copysign(1.0, a);
1602 return 9223372036854775807L;
1603 return (-9223372036854775807L-1);
1607 float builtin_d2f (double a)
1609 if (finite(a)) return (float) a;
1611 if (isnan(a)) return FLT_NAN;
1612 else return copysignf (FLT_POSINF, (float) copysign(1.0, a));
1618 * These are local overrides for various environment variables in Emacs.
1619 * Please do not remove this and leave it at the end of the file, where
1620 * Emacs will automagically detect them.
1621 * ---------------------------------------------------------------------
1624 * indent-tabs-mode: t