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) 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);
347 o = heap_allocate ( c->alignedsize, true, c->finalizer );
349 o = heap_allocate ( c->instancesize, true, c->finalizer );
353 memset (o, 0, c->instancesize);
355 o -> vftbl = c -> vftbl;
361 /******************** Funktion: builtin_anewarray ****************************
363 Legt ein Array von Zeigern auf Objekte am Heap an.
365 size ......... Anzahl der Elemente
366 elementtype .. ein Zeiger auf die classinfo-Struktur des Typs
369 Return: Zeiger auf das Array, oder NULL (wenn kein Speicher frei)
371 *****************************************************************************/
374 void* __builtin_newarray(s4 base_size,
381 #ifdef SIZE_FROM_CLASSINFO
382 s4 alignedsize = align_size(base_size + (size-1) * elementsize);
383 a = heap_allocate ( alignedsize, true, NULL );
385 a = heap_allocate ( sizeof(java_objectarray) + (size-1) * elementsize,
391 #ifdef SIZE_FROM_CLASSINFO
392 memset(a, 0, alignedsize);
394 memset(a, 0, base_size + (size-1) * elementsize);
397 a -> objheader.vftbl = class_array -> vftbl;
399 #ifdef SIZE_FROM_CLASSINFO
400 a -> alignedsize = alignedsize;
402 a -> arraytype = arraytype;
408 java_objectarray *builtin_anewarray (s4 size, classinfo *elementtype)
411 a = (java_objectarray*)__builtin_newarray(sizeof(java_objectarray),
418 a -> elementtype = elementtype;
424 /******************** Funktion: builtin_newarray_array ***********************
426 Legt ein Array von Zeigern auf Arrays am Heap an.
427 Paramter: size ......... Anzahl der Elemente
428 elementdesc .. Zeiger auf die Arraybeschreibungs-Struktur f"ur
431 Return: Zeiger auf das Array, oder NULL
433 *****************************************************************************/
435 java_arrayarray *builtin_newarray_array
436 (s4 size, constant_arraydescriptor *elementdesc)
439 a = (java_arrayarray*)__builtin_newarray(sizeof(java_arrayarray),
446 a -> elementdescriptor = elementdesc;
451 /******************** Funktion: builtin_newarray_boolean ************************
453 Legt ein Array von Bytes am Heap an, das allerdings als Boolean-Array
454 gekennzeichnet wird (wichtig bei Casts!)
456 Return: Zeiger auf das Array, oder NULL
458 *****************************************************************************/
460 java_booleanarray *builtin_newarray_boolean (s4 size)
462 java_booleanarray *a;
463 a = (java_booleanarray*)__builtin_newarray(sizeof(java_booleanarray),
471 /******************** Funktion: builtin_newarray_char ************************
473 Legt ein Array von 16-bit-Integers am Heap an.
474 Return: Zeiger auf das Array, oder NULL
476 *****************************************************************************/
478 java_chararray *builtin_newarray_char (s4 size)
481 a = (java_chararray*)__builtin_newarray(sizeof(java_chararray),
490 /******************** Funktion: builtin_newarray_float ***********************
492 Legt ein Array von 32-bit-IEEE-float am Heap an.
493 Return: Zeiger auf das Array, oder NULL
495 *****************************************************************************/
497 java_floatarray *builtin_newarray_float (s4 size)
500 a = (java_floatarray*)__builtin_newarray(sizeof(java_floatarray),
509 /******************** Funktion: builtin_newarray_double ***********************
511 Legt ein Array von 64-bit-IEEE-float am Heap an.
512 Return: Zeiger auf das Array, oder NULL
514 *****************************************************************************/
516 java_doublearray *builtin_newarray_double (s4 size)
519 a = (java_doublearray*)__builtin_newarray(sizeof(java_doublearray),
530 /******************** Funktion: builtin_newarray_byte ***********************
532 Legt ein Array von 8-bit-Integers am Heap an.
533 Return: Zeiger auf das Array, oder NULL
535 *****************************************************************************/
537 java_bytearray *builtin_newarray_byte (s4 size)
540 a = (java_bytearray*)__builtin_newarray(sizeof(java_bytearray),
549 /******************** Funktion: builtin_newarray_short ***********************
551 Legt ein Array von 16-bit-Integers am Heap an.
552 Return: Zeiger auf das Array, oder NULL
554 *****************************************************************************/
556 java_shortarray *builtin_newarray_short (s4 size)
559 a = (java_shortarray*)__builtin_newarray(sizeof(java_shortarray),
568 /******************** Funktion: builtin_newarray_int ***********************
570 Legt ein Array von 32-bit-Integers am Heap an.
571 Return: Zeiger auf das Array, oder NULL
573 *****************************************************************************/
575 java_intarray *builtin_newarray_int (s4 size)
578 a = (java_intarray*)__builtin_newarray(sizeof(java_intarray),
587 /******************** Funktion: builtin_newarray_long ***********************
589 Legt ein Array von 64-bit-Integers am Heap an.
590 Return: Zeiger auf das Array, oder NULL
592 *****************************************************************************/
594 java_longarray *builtin_newarray_long (s4 size)
597 a = (java_longarray*)__builtin_newarray(sizeof(java_longarray),
607 /***************** Funktion: builtin_multianewarray ***************************
609 Legt ein mehrdimensionales Array am Heap an.
610 Die Gr"ossen der einzelnen Dimensionen werden in einem Integerarray
611 "ubergeben. Der Typ es zu erzeugenden Arrays wird als
612 Referenz auf eine constant_arraydescriptor - Struktur "ubergeben.
614 Return: Ein Zeiger auf das Array, oder NULL, wenn kein Speicher mehr
617 ******************************************************************************/
621 static java_arrayheader *multianewarray_part (java_intarray *dims, int thisdim,
622 constant_arraydescriptor *desc)
627 size = dims -> data[thisdim];
629 if (thisdim == (dims->header.size-1)) {
630 /* letzte Dimension schon erreicht */
632 switch (desc -> arraytype) {
633 case ARRAYTYPE_BOOLEAN:
634 return (java_arrayheader*) builtin_newarray_boolean (size);
636 return (java_arrayheader*) builtin_newarray_char (size);
637 case ARRAYTYPE_FLOAT:
638 return (java_arrayheader*) builtin_newarray_float (size);
639 case ARRAYTYPE_DOUBLE:
640 return (java_arrayheader*) builtin_newarray_double (size);
642 return (java_arrayheader*) builtin_newarray_byte (size);
643 case ARRAYTYPE_SHORT:
644 return (java_arrayheader*) builtin_newarray_short (size);
646 return (java_arrayheader*) builtin_newarray_int (size);
648 return (java_arrayheader*) builtin_newarray_long (size);
649 case ARRAYTYPE_OBJECT:
650 return (java_arrayheader*) builtin_anewarray (size, desc->objectclass);
652 case ARRAYTYPE_ARRAY:
653 return (java_arrayheader*) builtin_newarray_array (size, desc->elementdescriptor);
655 default: panic ("Invalid arraytype in multianewarray");
659 /* wenn letzte Dimension noch nicht erreicht wurde */
661 if (desc->arraytype != ARRAYTYPE_ARRAY)
662 panic ("multianewarray with too many dimensions");
664 a = builtin_newarray_array (size, desc->elementdescriptor);
667 for (i=0; i<size; i++) {
668 java_arrayheader *ea =
669 multianewarray_part (dims, thisdim+1, desc->elementdescriptor);
670 if (!ea) return NULL;
675 return (java_arrayheader*) a;
679 java_arrayheader *builtin_multianewarray (java_intarray *dims,
680 constant_arraydescriptor *desc)
682 return multianewarray_part (dims, 0, desc);
686 static java_arrayheader *nmultianewarray_part (int n, long *dims, int thisdim,
687 constant_arraydescriptor *desc)
692 size = (int) dims[thisdim];
694 if (thisdim == (n - 1)) {
695 /* letzte Dimension schon erreicht */
697 switch (desc -> arraytype) {
698 case ARRAYTYPE_BOOLEAN:
699 return (java_arrayheader*) builtin_newarray_boolean(size);
701 return (java_arrayheader*) builtin_newarray_char(size);
702 case ARRAYTYPE_FLOAT:
703 return (java_arrayheader*) builtin_newarray_float(size);
704 case ARRAYTYPE_DOUBLE:
705 return (java_arrayheader*) builtin_newarray_double(size);
707 return (java_arrayheader*) builtin_newarray_byte(size);
708 case ARRAYTYPE_SHORT:
709 return (java_arrayheader*) builtin_newarray_short(size);
711 return (java_arrayheader*) builtin_newarray_int(size);
713 return (java_arrayheader*) builtin_newarray_long(size);
714 case ARRAYTYPE_OBJECT:
715 return (java_arrayheader*) builtin_anewarray(size,
717 case ARRAYTYPE_ARRAY:
718 return (java_arrayheader*) builtin_newarray_array(size,
719 desc->elementdescriptor);
721 default: panic ("Invalid arraytype in multianewarray");
725 /* wenn letzte Dimension noch nicht erreicht wurde */
727 if (desc->arraytype != ARRAYTYPE_ARRAY)
728 panic ("multianewarray with too many dimensions");
730 a = builtin_newarray_array(size, desc->elementdescriptor);
733 for (i = 0; i < size; i++) {
734 java_arrayheader *ea =
735 nmultianewarray_part(n, dims, thisdim + 1, desc->elementdescriptor);
736 if (!ea) return NULL;
741 return (java_arrayheader*) a;
745 java_arrayheader *builtin_nmultianewarray (int size,
746 constant_arraydescriptor *desc, long *dims)
748 (void) builtin_newarray_int(size); /* for compatibility with -old */
749 return nmultianewarray_part (size, dims, 0, desc);
755 /************************* Funktion: builtin_aastore *************************
757 speichert eine Referenz auf ein Objekt in einem Object-Array oder
758 in einem Array-Array.
759 Dabei wird allerdings vorher "uberpr"uft, ob diese Operation
762 Return: 1, wenn alles OK ist
763 0, wenn dieses Objekt nicht in dieses Array gespeichert werden
766 *****************************************************************************/
768 s4 builtin_aastore (java_objectarray *a, s4 index, java_objectheader *o)
770 if (builtin_canstore(a,o)) {
782 /*****************************************************************************
783 METHODEN-PROTOKOLLIERUNG
785 Verschiedene Funktionen, mit denen eine Meldung ausgegeben werden
786 kann, wann immer Methoden aufgerufen oder beendet werden.
789 *****************************************************************************/
794 java_objectheader *builtin_trace_exception (java_objectheader *exceptionptr,
795 methodinfo *method, int *pos, int noindent) {
799 if (verbose || runverbose) {
800 printf("Exception ");
801 unicode_display (exceptionptr->vftbl->class->name);
802 printf(" thrown in ");
804 unicode_display (method->class->name);
806 unicode_display (method->name);
807 if (method->flags & ACC_SYNCHRONIZED)
811 printf("(%p) at position %p\n", method->entrypoint, pos);
814 printf("call_java_method\n");
821 void builtin_trace_args(long a0, long a1, long a2, long a3, long a4, long a5,
824 sprintf (logtext, " ");
825 sprintf (logtext+methodindent, "called: ");
826 unicode_sprint (logtext+strlen(logtext), method->class->name);
827 sprintf (logtext+strlen(logtext), ".");
828 unicode_sprint (logtext+strlen(logtext), method->name);
829 unicode_sprint (logtext+strlen(logtext), method->descriptor);
830 sprintf (logtext+strlen(logtext), "(");
831 switch (method->paramcount) {
833 sprintf(logtext+strlen(logtext), "%lx, %lx, %lx, %lx, %lx, %lx",
834 a0, a1, a2, a3, a4, a5);
837 sprintf(logtext+strlen(logtext), "%lx, %lx, %lx, %lx, %lx",
841 sprintf(logtext+strlen(logtext), "%lx, %lx, %lx, %lx",
845 sprintf(logtext+strlen(logtext), "%lx, %lx, %lx", a0, a1, a2);
848 sprintf(logtext+strlen(logtext), "%lx, %lx", a0, a1);
851 sprintf(logtext+strlen(logtext), "%lx", a0);
854 sprintf (logtext+strlen(logtext), ")");
860 void builtin_displaymethodstart(methodinfo *method)
862 sprintf (logtext, " ");
863 sprintf (logtext+methodindent, "called: ");
864 unicode_sprint (logtext+strlen(logtext), method->class->name);
865 sprintf (logtext+strlen(logtext), ".");
866 unicode_sprint (logtext+strlen(logtext), method->name);
867 unicode_sprint (logtext+strlen(logtext), method->descriptor);
872 void builtin_displaymethodstop(methodinfo *method, long l, double d)
875 sprintf (logtext, " ");
876 sprintf (logtext+methodindent, "finished: ");
877 unicode_sprint (logtext+strlen(logtext), method->class->name);
878 sprintf (logtext+strlen(logtext), ".");
879 unicode_sprint (logtext+strlen(logtext), method->name);
880 unicode_sprint (logtext+strlen(logtext), method->descriptor);
881 switch (method->returntype) {
884 sprintf (logtext+strlen(logtext), "->%ld", l);
888 sprintf (logtext+strlen(logtext), "->%g", d);
891 sprintf (logtext+strlen(logtext), "->%p", (void*) l);
897 void builtin_displaymethodexception(methodinfo *method)
899 sprintf (logtext, " ");
900 sprintf (logtext+methodindent, "exception abort: ");
901 unicode_sprint (logtext+strlen(logtext), method->class->name);
902 sprintf (logtext+strlen(logtext), ".");
903 unicode_sprint (logtext+strlen(logtext), method->name);
904 unicode_sprint (logtext+strlen(logtext), method->descriptor);
909 /****************************************************************************
910 SYNCHRONIZATION FUNCTIONS
911 *****************************************************************************/
914 * Lock the mutex of an object.
918 internal_lock_mutex_for_object (java_objectheader *object)
920 mutexHashEntry *entry;
925 hashValue = MUTEX_HASH_VALUE(object);
926 entry = &mutexHashTable[hashValue];
928 if (entry->object != 0)
930 if (entry->mutex.count == 0 && entry->conditionCount == 0)
933 entry->mutex.holder = 0;
934 entry->mutex.count = 0;
935 entry->mutex.muxWaiters = 0;
939 while (entry->next != 0 && entry->object != object)
942 if (entry->object != object)
944 entry->next = firstFreeOverflowEntry;
945 firstFreeOverflowEntry = firstFreeOverflowEntry->next;
950 assert(entry->conditionCount == 0);
956 entry->mutex.holder = 0;
957 entry->mutex.count = 0;
958 entry->mutex.muxWaiters = 0;
961 if (entry->object == 0)
962 entry->object = object;
964 internal_lock_mutex(&entry->mutex);
970 * Unlocks the mutex of an object.
974 internal_unlock_mutex_for_object (java_objectheader *object)
977 mutexHashEntry *entry;
979 hashValue = MUTEX_HASH_VALUE(object);
980 entry = &mutexHashTable[hashValue];
982 if (entry->object == object)
983 internal_unlock_mutex(&entry->mutex);
986 while (entry->next != 0 && entry->next->object != object)
989 assert(entry->next != 0);
991 internal_unlock_mutex(&entry->next->mutex);
993 if (entry->next->mutex.count == 0 && entry->conditionCount == 0)
995 mutexHashEntry *unlinked = entry->next;
997 entry->next = unlinked->next;
998 unlinked->next = firstFreeOverflowEntry;
999 firstFreeOverflowEntry = unlinked;
1006 builtin_monitorenter (java_objectheader *o)
1011 assert(blockInts == 0);
1015 hashValue = MUTEX_HASH_VALUE(o);
1016 if (mutexHashTable[hashValue].object == o
1017 && mutexHashTable[hashValue].mutex.holder == currentThread)
1018 ++mutexHashTable[hashValue].mutex.count;
1020 internal_lock_mutex_for_object(o);
1024 assert(blockInts == 0);
1028 void builtin_monitorexit (java_objectheader *o)
1033 assert(blockInts == 0);
1037 hashValue = MUTEX_HASH_VALUE(o);
1038 if (mutexHashTable[hashValue].object == o)
1040 if (mutexHashTable[hashValue].mutex.count == 1
1041 && mutexHashTable[hashValue].mutex.muxWaiters != 0)
1042 internal_unlock_mutex_for_object(o);
1044 --mutexHashTable[hashValue].mutex.count;
1047 internal_unlock_mutex_for_object(o);
1051 assert(blockInts == 0);
1056 /*****************************************************************************
1057 DIVERSE HILFSFUNKTIONEN
1058 *****************************************************************************/
1062 /*********** Funktionen f"ur die Integerdivision *****************************
1064 Auf manchen Systemen (z.B. DEC ALPHA) wird durch die CPU keine Integer-
1065 division unterst"utzt.
1066 Daf"ur gibt es dann diese Hilfsfunktionen
1068 ******************************************************************************/
1070 s4 builtin_idiv (s4 a, s4 b) { return a/b; }
1071 s4 builtin_irem (s4 a, s4 b) { return a%b; }
1074 /************** Funktionen f"ur Long-Arithmetik *******************************
1076 Auf Systemen, auf denen die CPU keine 64-Bit-Integers unterst"utzt,
1077 werden diese Funktionen gebraucht
1079 ******************************************************************************/
1082 s8 builtin_ladd (s8 a, s8 b)
1087 return builtin_i2l(0);
1091 s8 builtin_lsub (s8 a, s8 b)
1096 return builtin_i2l(0);
1100 s8 builtin_lmul (s8 a, s8 b)
1105 return builtin_i2l(0);
1109 s8 builtin_ldiv (s8 a, s8 b)
1114 return builtin_i2l(0);
1118 s8 builtin_lrem (s8 a, s8 b)
1123 return builtin_i2l(0);
1127 s8 builtin_lshl (s8 a, s4 b)
1132 return builtin_i2l(0);
1136 s8 builtin_lshr (s8 a, s4 b)
1141 return builtin_i2l(0);
1145 s8 builtin_lushr (s8 a, s4 b)
1148 return ((u8)a)>>(b&63);
1150 return builtin_i2l(0);
1154 s8 builtin_land (s8 a, s8 b)
1159 return builtin_i2l(0);
1163 s8 builtin_lor (s8 a, s8 b)
1168 return builtin_i2l(0);
1172 s8 builtin_lxor (s8 a, s8 b)
1177 return builtin_i2l(0);
1181 s8 builtin_lneg (s8 a)
1186 return builtin_i2l(0);
1190 s4 builtin_lcmp (s8 a, s8 b)
1205 /*********** Funktionen f"ur die Floating-Point-Operationen ******************/
1207 float builtin_fadd (float a, float b)
1209 if (isnanf(a)) return FLT_NAN;
1210 if (isnanf(b)) return FLT_NAN;
1212 if (finitef(b)) return a+b;
1216 if (finitef(b)) return a;
1218 if (copysignf(1.0, a)==copysignf(1.0, b)) return a;
1219 else return FLT_NAN;
1224 float builtin_fsub (float a, float b)
1226 return builtin_fadd (a, builtin_fneg(b));
1229 float builtin_fmul (float a, float b)
1231 if (isnanf(a)) return FLT_NAN;
1232 if (isnanf(b)) return FLT_NAN;
1234 if (finitef(b)) return a*b;
1236 if (a==0) return FLT_NAN;
1237 else return copysignf(b, copysignf(1.0, b)*a);
1242 if (b==0) return FLT_NAN;
1243 else return copysignf(a, copysignf(1.0, a)*b);
1246 return copysignf(a, copysignf(1.0, a)*copysignf(1.0, b));
1251 float builtin_fdiv (float a, float b)
1253 if (finitef(a) && finitef(b)) {
1266 float builtin_frem (float a, float b)
1269 /* return (float) builtin_drem((double) a, (double) b); */
1273 if (finite((double) a) && finite((double) b)) {
1275 if (finite((double) f))
1279 if (isnan((double) b))
1281 if (finite((double) a))
1287 if (finitef(a) && finitef(b)) {
1290 return a - floorf(f) * b;
1301 float builtin_fneg (float a)
1303 if (isnanf(a)) return a;
1305 if (finitef(a)) return -a;
1306 else return copysignf(a,-copysignf(1.0, a));
1310 s4 builtin_fcmpl (float a, float b)
1312 if (isnanf(a)) return -1;
1313 if (isnanf(b)) return -1;
1314 if (!finitef(a) || !finitef(b)) {
1315 a = finitef(a) ? 0 : copysignf(1.0, a);
1316 b = finitef(b) ? 0 : copysignf(1.0, b);
1323 s4 builtin_fcmpg (float a, float b)
1325 if (isnanf(a)) return 1;
1326 if (isnanf(b)) return 1;
1327 if (!finitef(a) || !finitef(b)) {
1328 a = finitef(a) ? 0 : copysignf(1.0, a);
1329 b = finitef(b) ? 0 : copysignf(1.0, b);
1338 /*********** Funktionen f"ur doppelt genaue Fliesskommazahlen ***************/
1340 double builtin_dadd (double a, double b)
1342 if (isnan(a)) return DBL_NAN;
1343 if (isnan(b)) return DBL_NAN;
1345 if (finite(b)) return a+b;
1349 if (finite(b)) return a;
1351 if (copysign(1.0, a)==copysign(1.0, b)) return a;
1352 else return DBL_NAN;
1357 double builtin_dsub (double a, double b)
1359 return builtin_dadd (a, builtin_dneg(b));
1362 double builtin_dmul (double a, double b)
1364 if (isnan(a)) return DBL_NAN;
1365 if (isnan(b)) return DBL_NAN;
1367 if (finite(b)) return a*b;
1369 if (a==0) return DBL_NAN;
1370 else return copysign(b, copysign(1.0, b)*a);
1375 if (b==0) return DBL_NAN;
1376 else return copysign(a, copysign(1.0, a)*b);
1379 return copysign(a, copysign(1.0, a)*copysign(1.0, b));
1384 double builtin_ddiv (double a, double b)
1386 if (finite(a) && finite(b)) {
1399 double builtin_drem (double a, double b)
1403 if (finite(a) && finite(b)) {
1406 if ((d < 1.0) && (d > 0.0))
1419 double builtin_dneg (double a)
1421 if (isnan(a)) return a;
1423 if (finite(a)) return -a;
1424 else return copysign(a,-copysign(1.0, a));
1428 s4 builtin_dcmpl (double a, double b)
1430 if (isnan(a)) return -1;
1431 if (isnan(b)) return -1;
1432 if (!finite(a) || !finite(b)) {
1433 a = finite(a) ? 0 : copysign(1.0, a);
1434 b = finite(b) ? 0 : copysign(1.0, b);
1441 s4 builtin_dcmpg (double a, double b)
1443 if (isnan(a)) return 1;
1444 if (isnan(b)) return 1;
1445 if (!finite(a) || !finite(b)) {
1446 a = finite(a) ? 0 : copysign(1.0, a);
1447 b = finite(b) ? 0 : copysign(1.0, b);
1455 /*********************** Umwandlungsoperationen ****************************/
1457 s8 builtin_i2l (s4 i)
1462 s8 v; v.high = 0; v.low=i; return v;
1466 float builtin_i2f (s4 a)
1468 float f = (float) a;
1472 double builtin_i2d (s4 a)
1474 double d = (double) a;
1479 s4 builtin_l2i (s8 l)
1488 float builtin_l2f (s8 a)
1491 float f = (float) a;
1498 double builtin_l2d (s8 a)
1501 double d = (double) a;
1509 s4 builtin_f2i(float a)
1512 return builtin_d2i((double) a);
1521 if (a < (-2147483648))
1522 return (-2147483648);
1525 f = copysignf((float) 1.0, a);
1528 return (-2147483648); */
1532 s8 builtin_f2l (float a)
1535 return builtin_d2l((double) a);
1540 if (a > 9223372036854775807L)
1541 return 9223372036854775807L;
1542 if (a < (-9223372036854775808L))
1543 return (-9223372036854775808L);
1548 f = copysignf((float) 1.0, a);
1550 return 9223372036854775807L;
1551 return (-9223372036854775808L); */
1555 double builtin_f2d (float a)
1557 if (finitef(a)) return (double) a;
1559 if (isnanf(a)) return DBL_NAN;
1560 else return copysign(DBL_POSINF, (double) copysignf(1.0, a) );
1565 s4 builtin_d2i (double a)
1570 if (a >= 2147483647)
1572 if (a <= (-2147483648))
1573 return (-2147483648);
1578 d = copysign(1.0, a);
1581 return (-2147483648);
1585 s8 builtin_d2l (double a)
1590 if (a >= 9223372036854775807L)
1591 return 9223372036854775807L;
1592 if (a <= (-9223372036854775807L-1))
1593 return (-9223372036854775807L-1);
1598 d = copysign(1.0, a);
1600 return 9223372036854775807L;
1601 return (-9223372036854775807L-1);
1605 float builtin_d2f (double a)
1607 if (finite(a)) return (float) a;
1609 if (isnan(a)) return FLT_NAN;
1610 else return copysignf (FLT_POSINF, (float) copysign(1.0, a));
1616 * These are local overrides for various environment variables in Emacs.
1617 * Please do not remove this and leave it at the end of the file, where
1618 * Emacs will automagically detect them.
1619 * ---------------------------------------------------------------------
1622 * indent-tabs-mode: t