1 /****************************** builtin.c **************************************
3 Copyright (c) 1997 A. Krall, R. Grafl, M. Gschwind, M. Probst
5 See file COPYRIGHT for information on usage and disclaimer of warranties
7 Enthaelt die C-Funktionen fuer alle JavaVM-Befehle, die sich nicht direkt
8 auf Maschinencode "ubersetzen lassen. Im Code f"ur die Methoden steht
9 dann ein Funktionsaufruf (nat"urlich mit den Aufrufskonventionen von C).
11 Authors: Reinhard Grafl EMAIL: cacao@complang.tuwien.ac.at
12 Andreas Krall EMAIL: cacao@complang.tuwien.ac.at
13 Mark Probst EMAIL: cacao@complang.tuwien.ac.at
15 Last Change: 1996/12/03
17 *******************************************************************************/
28 #include "threads/thread.h"
29 #include "threads/locks.h" /* schani */
31 #include "native-math.h"
33 builtin_descriptor builtin_desc[] = {
34 {(functionptr) builtin_instanceof, "instanceof"},
35 {(functionptr) builtin_checkcast, "checkcast"},
36 {(functionptr) asm_builtin_checkcast, "checkcast"},
37 {(functionptr) builtin_arrayinstanceof, "arrayinstanceof"},
38 {(functionptr) builtin_checkarraycast, "checkarraycast"},
39 {(functionptr) asm_builtin_checkarraycast, "checkarraycast"},
40 {(functionptr) asm_builtin_aastore, "aastore"},
41 {(functionptr) builtin_new, "new"},
42 {(functionptr) builtin_anewarray, "anewarray"},
43 {(functionptr) builtin_newarray_array, "newarray_array"},
44 {(functionptr) builtin_newarray_boolean, "newarray_boolean"},
45 {(functionptr) builtin_newarray_char, "newarray_char"},
46 {(functionptr) builtin_newarray_float, "newarray_float"},
47 {(functionptr) builtin_newarray_double, "newarray_double"},
48 {(functionptr) builtin_newarray_byte, "newarray_byte"},
49 {(functionptr) builtin_newarray_short, "newarray_short"},
50 {(functionptr) builtin_newarray_int, "newarray_int"},
51 {(functionptr) builtin_newarray_long, "newarray_long"},
52 {(functionptr) builtin_displaymethodstart, "displaymethodstart"},
53 {(functionptr) builtin_displaymethodstop, "displaymethodstop"},
54 {(functionptr) builtin_monitorenter, "monitorenter"},
55 {(functionptr) asm_builtin_monitorenter, "monitorenter"},
56 {(functionptr) builtin_monitorexit, "monitorexit"},
57 {(functionptr) asm_builtin_monitorexit, "monitorexit"},
58 {(functionptr) builtin_idiv, "idiv"},
59 {(functionptr) asm_builtin_idiv, "idiv"},
60 {(functionptr) builtin_irem, "irem"},
61 {(functionptr) asm_builtin_irem, "irem"},
62 {(functionptr) builtin_ladd, "ladd"},
63 {(functionptr) builtin_lsub, "lsub"},
64 {(functionptr) builtin_lmul, "lmul"},
65 {(functionptr) builtin_ldiv, "ldiv"},
66 {(functionptr) asm_builtin_ldiv, "ldiv"},
67 {(functionptr) builtin_lrem, "lrem"},
68 {(functionptr) asm_builtin_lrem, "lrem"},
69 {(functionptr) builtin_lshl, "lshl"},
70 {(functionptr) builtin_lshr, "lshr"},
71 {(functionptr) builtin_lushr, "lushr"},
72 {(functionptr) builtin_land, "land"},
73 {(functionptr) builtin_lor, "lor"},
74 {(functionptr) builtin_lxor, "lxor"},
75 {(functionptr) builtin_lneg, "lneg"},
76 {(functionptr) builtin_lcmp, "lcmp"},
77 {(functionptr) builtin_fadd, "fadd"},
78 {(functionptr) builtin_fsub, "fsub"},
79 {(functionptr) builtin_fmul, "fmul"},
80 {(functionptr) builtin_fdiv, "fdiv"},
81 {(functionptr) builtin_frem, "frem"},
82 {(functionptr) builtin_fneg, "fneg"},
83 {(functionptr) builtin_fcmpl, "fcmpl"},
84 {(functionptr) builtin_fcmpg, "fcmpg"},
85 {(functionptr) builtin_dadd, "dadd"},
86 {(functionptr) builtin_dsub, "dsub"},
87 {(functionptr) builtin_dmul, "dmul"},
88 {(functionptr) builtin_ddiv, "ddiv"},
89 {(functionptr) builtin_drem, "drem"},
90 {(functionptr) builtin_dneg, "dneg"},
91 {(functionptr) builtin_dcmpl, "dcmpl"},
92 {(functionptr) builtin_dcmpg, "dcmpg"},
93 {(functionptr) builtin_i2l, "i2l"},
94 {(functionptr) builtin_i2f, "i2f"},
95 {(functionptr) builtin_i2d, "i2d"},
96 {(functionptr) builtin_l2i, "l2i"},
97 {(functionptr) builtin_l2f, "l2f"},
98 {(functionptr) builtin_l2d, "l2d"},
99 {(functionptr) builtin_f2i, "f2i"},
100 {(functionptr) builtin_f2l, "f2l"},
101 {(functionptr) builtin_f2d, "f2d"},
102 {(functionptr) builtin_d2i, "d2i"},
103 {(functionptr) builtin_d2l, "d2l"},
104 {(functionptr) builtin_d2f, "d2f"},
105 {(functionptr) NULL, "unknown"}
109 /*****************************************************************************
111 *****************************************************************************/
115 /*************** interne Funktion: builtin_isanysubclass *********************
117 "uberpr"uft, ob eine Klasse eine Unterklasse einer anderen Klasse ist.
118 Dabei gelten auch Interfaces, die eine Klasse implementiert, als
120 R"uckgabewert: 1 ... es trifft zu
121 0 ... es trifft nicht zu
123 *****************************************************************************/
125 s4 builtin_isanysubclass (classinfo *sub, classinfo *super)
127 if (super->flags & ACC_INTERFACE)
128 return (sub->vftbl->interfacetablelength > super->index) &&
129 (sub->vftbl->interfacetable[-super->index] != NULL);
141 return (unsigned) (sub->vftbl->baseval - super->vftbl->baseval) <=
142 (unsigned) (super->vftbl->diffval);
146 /****************** Funktion: builtin_instanceof *****************************
148 "Uberpr"uft, ob ein Objekt eine Instanz einer Klasse (oder einer davon
149 abgeleiteten Klasse) ist, oder ob die Klasse des Objekts ein Interface
152 0, wenn nicht, oder wenn Objekt ein NULL-Zeiger
154 *****************************************************************************/
156 s4 builtin_instanceof(java_objectheader *obj, classinfo *class)
159 log_text ("builtin_instanceof called");
163 return builtin_isanysubclass (obj->vftbl->class, class);
168 /**************** Funktion: builtin_checkcast *******************************
170 "Uberpr"uft, ob ein Objekt eine Instanz einer Klasse (oder einer davon
171 abgeleiteten Klasse ist).
172 Unterschied zu builtin_instanceof: Ein NULL-Zeiger ist immer richtig
173 Return: 1, wenn ja, oder wenn Objekt ein NULL-Zeiger
176 ****************************************************************************/
178 s4 builtin_checkcast(java_objectheader *obj, classinfo *class)
181 log_text ("builtin_checkcast called");
186 if (builtin_isanysubclass (obj->vftbl->class, class))
190 printf ("#### checkcast failed ");
191 utf_display (obj->vftbl->class->name);
193 utf_display (class->name);
201 /*********** interne Funktion: builtin_descriptorscompatible ******************
203 "uberpr"uft, ob zwei Array-Typdescriptoren compartible sind, d.h.,
204 ob ein Array vom Typ 'desc' gefahrlos einer Variblen vom Typ 'target'
205 zugewiesen werden kann.
209 ******************************************************************************/
211 static s4 builtin_descriptorscompatible
212 (constant_arraydescriptor *desc, constant_arraydescriptor *target)
214 if (desc==target) return 1;
215 if (desc->arraytype != target->arraytype) return 0;
216 switch (target->arraytype) {
217 case ARRAYTYPE_OBJECT:
218 return builtin_isanysubclass (desc->objectclass, target->objectclass);
219 case ARRAYTYPE_ARRAY:
220 return builtin_descriptorscompatible
221 (desc->elementdescriptor, target->elementdescriptor);
228 /******************** Funktion: builtin_checkarraycast ***********************
230 "uberpr"uft, ob ein gegebenes Objekt tats"achlich von einem
231 Untertyp des geforderten Arraytyps ist.
232 Dazu muss das Objekt auf jeden Fall ein Array sein.
233 Bei einfachen Arrays (int,short,double,etc.) muss der Typ genau
235 Bei Arrays von Objekten muss der Elementtyp des tats"achlichen Arrays
236 ein Untertyp (oder der selbe Typ) vom geforderten Elementtyp sein.
237 Bei Arrays vom Arrays (die eventuell wieder Arrays von Arrays
238 sein k"onnen) m"ussen die untersten Elementtypen in der entsprechenden
239 Unterklassenrelation stehen.
241 Return: 1, wenn Cast in Ordung ist
242 0, wenn es nicht geht
244 Achtung: ein Cast mit einem NULL-Zeiger geht immer gut.
246 *****************************************************************************/
248 s4 builtin_checkarraycast(java_objectheader *o, constant_arraydescriptor *desc)
250 java_arrayheader *a = (java_arrayheader*) o;
253 if (o->vftbl->class != class_array) {
255 printf ("#### checkarraycast failed 1\n");
260 if (a->arraytype != desc->arraytype) {
262 printf ("#### checkarraycast failed 2\n");
267 switch (a->arraytype) {
268 case ARRAYTYPE_OBJECT: {
269 java_objectarray *oa = (java_objectarray*) o;
270 int result = builtin_isanysubclass (oa->elementtype, desc->objectclass);
274 printf ("#### checkarraycast failed 3\n");
278 case ARRAYTYPE_ARRAY: {
279 java_arrayarray *aa = (java_arrayarray*) o;
280 int result = builtin_descriptorscompatible
281 (aa->elementdescriptor, desc->elementdescriptor);
285 printf ("#### checkarraycast failed 4\n");
295 s4 builtin_arrayinstanceof
296 (java_objectheader *obj, constant_arraydescriptor *desc)
299 return builtin_checkarraycast (obj, desc);
303 /************************** exception functions *******************************
305 ******************************************************************************/
307 java_objectheader *builtin_throw_exception (java_objectheader *local_exceptionptr) {
309 sprintf(logtext, "Builtin exception thrown: ");
310 utf_sprint(logtext + strlen(logtext), local_exceptionptr->vftbl->class->name);
313 exceptionptr = local_exceptionptr;
314 return local_exceptionptr;
318 /******************* Funktion: builtin_canstore *******************************
320 "uberpr"uft, ob ein Objekt in einem Array gespeichert werden
322 Return: 1, wenn es geht
325 ******************************************************************************/
328 s4 builtin_canstore (java_objectarray *a, java_objectheader *o)
332 switch (a->header.arraytype) {
333 case ARRAYTYPE_OBJECT:
334 if ( ! builtin_checkcast (o, a->elementtype) ) {
340 case ARRAYTYPE_ARRAY:
341 if ( ! builtin_checkarraycast
342 (o, ((java_arrayarray*)a)->elementdescriptor) ) {
349 panic ("builtin_canstore called with invalid arraytype");
356 /*****************************************************************************
358 *****************************************************************************/
362 /******************** Funktion: builtin_new **********************************
364 Legt ein neues Objekt einer Klasse am Heap an.
365 Return: Der Zeiger auf das Objekt, oder NULL, wenn kein Speicher
368 *****************************************************************************/
371 #define align_size(size) ((size + ((1 << ALIGNMENT) - 1)) & ~((1 << ALIGNMENT) - 1))
373 java_objectheader *builtin_new (classinfo *c)
375 java_objectheader *o;
379 #ifdef SIZE_FROM_CLASSINFO
380 c->alignedsize = align_size(c->instancesize);
381 o = heap_allocate ( c->alignedsize, true, c->finalizer );
383 o = heap_allocate ( c->instancesize, true, c->finalizer );
387 memset (o, 0, c->instancesize);
389 o -> vftbl = c -> vftbl;
395 /******************** Funktion: builtin_anewarray ****************************
397 Legt ein Array von Zeigern auf Objekte am Heap an.
399 size ......... Anzahl der Elemente
400 elementtype .. ein Zeiger auf die classinfo-Struktur des Typs
403 Return: Zeiger auf das Array, oder NULL (wenn kein Speicher frei)
405 *****************************************************************************/
408 void* __builtin_newarray(s4 base_size,
415 #ifdef SIZE_FROM_CLASSINFO
416 s4 alignedsize = align_size(base_size + (size-1) * elementsize);
417 a = heap_allocate ( alignedsize, true, NULL );
419 a = heap_allocate ( sizeof(java_objectarray) + (size-1) * elementsize,
425 #ifdef SIZE_FROM_CLASSINFO
426 memset(a, 0, alignedsize);
428 memset(a, 0, base_size + (size-1) * elementsize);
431 a -> objheader.vftbl = class_array -> vftbl;
433 #ifdef SIZE_FROM_CLASSINFO
434 a -> alignedsize = alignedsize;
436 a -> arraytype = arraytype;
442 java_objectarray *builtin_anewarray (s4 size, classinfo *elementtype)
445 a = (java_objectarray*)__builtin_newarray(sizeof(java_objectarray),
452 a -> elementtype = elementtype;
458 /******************** Funktion: builtin_newarray_array ***********************
460 Legt ein Array von Zeigern auf Arrays am Heap an.
461 Paramter: size ......... Anzahl der Elemente
462 elementdesc .. Zeiger auf die Arraybeschreibungs-Struktur f"ur
465 Return: Zeiger auf das Array, oder NULL
467 *****************************************************************************/
469 java_arrayarray *builtin_newarray_array
470 (s4 size, constant_arraydescriptor *elementdesc)
473 a = (java_arrayarray*)__builtin_newarray(sizeof(java_arrayarray),
480 a -> elementdescriptor = elementdesc;
485 /******************** Funktion: builtin_newarray_boolean ************************
487 Legt ein Array von Bytes am Heap an, das allerdings als Boolean-Array
488 gekennzeichnet wird (wichtig bei Casts!)
490 Return: Zeiger auf das Array, oder NULL
492 *****************************************************************************/
494 java_booleanarray *builtin_newarray_boolean (s4 size)
496 java_booleanarray *a;
497 a = (java_booleanarray*)__builtin_newarray(sizeof(java_booleanarray),
505 /******************** Funktion: builtin_newarray_char ************************
507 Legt ein Array von 16-bit-Integers am Heap an.
508 Return: Zeiger auf das Array, oder NULL
510 *****************************************************************************/
512 java_chararray *builtin_newarray_char (s4 size)
515 a = (java_chararray*)__builtin_newarray(sizeof(java_chararray),
524 /******************** Funktion: builtin_newarray_float ***********************
526 Legt ein Array von 32-bit-IEEE-float am Heap an.
527 Return: Zeiger auf das Array, oder NULL
529 *****************************************************************************/
531 java_floatarray *builtin_newarray_float (s4 size)
534 a = (java_floatarray*)__builtin_newarray(sizeof(java_floatarray),
543 /******************** Funktion: builtin_newarray_double ***********************
545 Legt ein Array von 64-bit-IEEE-float am Heap an.
546 Return: Zeiger auf das Array, oder NULL
548 *****************************************************************************/
550 java_doublearray *builtin_newarray_double (s4 size)
553 a = (java_doublearray*)__builtin_newarray(sizeof(java_doublearray),
564 /******************** Funktion: builtin_newarray_byte ***********************
566 Legt ein Array von 8-bit-Integers am Heap an.
567 Return: Zeiger auf das Array, oder NULL
569 *****************************************************************************/
571 java_bytearray *builtin_newarray_byte (s4 size)
574 a = (java_bytearray*)__builtin_newarray(sizeof(java_bytearray),
583 /******************** Funktion: builtin_newarray_short ***********************
585 Legt ein Array von 16-bit-Integers am Heap an.
586 Return: Zeiger auf das Array, oder NULL
588 *****************************************************************************/
590 java_shortarray *builtin_newarray_short (s4 size)
593 a = (java_shortarray*)__builtin_newarray(sizeof(java_shortarray),
602 /******************** Funktion: builtin_newarray_int ***********************
604 Legt ein Array von 32-bit-Integers am Heap an.
605 Return: Zeiger auf das Array, oder NULL
607 *****************************************************************************/
609 java_intarray *builtin_newarray_int (s4 size)
612 a = (java_intarray*)__builtin_newarray(sizeof(java_intarray),
621 /******************** Funktion: builtin_newarray_long ***********************
623 Legt ein Array von 64-bit-Integers am Heap an.
624 Return: Zeiger auf das Array, oder NULL
626 *****************************************************************************/
628 java_longarray *builtin_newarray_long (s4 size)
631 a = (java_longarray*)__builtin_newarray(sizeof(java_longarray),
641 /***************** Funktion: builtin_multianewarray ***************************
643 Legt ein mehrdimensionales Array am Heap an.
644 Die Gr"ossen der einzelnen Dimensionen werden in einem Integerarray
645 "ubergeben. Der Typ es zu erzeugenden Arrays wird als
646 Referenz auf eine constant_arraydescriptor - Struktur "ubergeben.
648 Return: Ein Zeiger auf das Array, oder NULL, wenn kein Speicher mehr
651 ******************************************************************************/
655 static java_arrayheader *multianewarray_part (java_intarray *dims, int thisdim,
656 constant_arraydescriptor *desc)
661 size = dims -> data[thisdim];
663 if (thisdim == (dims->header.size-1)) {
664 /* letzte Dimension schon erreicht */
666 switch (desc -> arraytype) {
667 case ARRAYTYPE_BOOLEAN:
668 return (java_arrayheader*) builtin_newarray_boolean (size);
670 return (java_arrayheader*) builtin_newarray_char (size);
671 case ARRAYTYPE_FLOAT:
672 return (java_arrayheader*) builtin_newarray_float (size);
673 case ARRAYTYPE_DOUBLE:
674 return (java_arrayheader*) builtin_newarray_double (size);
676 return (java_arrayheader*) builtin_newarray_byte (size);
677 case ARRAYTYPE_SHORT:
678 return (java_arrayheader*) builtin_newarray_short (size);
680 return (java_arrayheader*) builtin_newarray_int (size);
682 return (java_arrayheader*) builtin_newarray_long (size);
683 case ARRAYTYPE_OBJECT:
684 return (java_arrayheader*) builtin_anewarray (size, desc->objectclass);
686 case ARRAYTYPE_ARRAY:
687 return (java_arrayheader*) builtin_newarray_array (size, desc->elementdescriptor);
689 default: panic ("Invalid arraytype in multianewarray");
693 /* wenn letzte Dimension noch nicht erreicht wurde */
695 if (desc->arraytype != ARRAYTYPE_ARRAY)
696 panic ("multianewarray with too many dimensions");
698 a = builtin_newarray_array (size, desc->elementdescriptor);
701 for (i=0; i<size; i++) {
702 java_arrayheader *ea =
703 multianewarray_part (dims, thisdim+1, desc->elementdescriptor);
704 if (!ea) return NULL;
709 return (java_arrayheader*) a;
713 java_arrayheader *builtin_multianewarray (java_intarray *dims,
714 constant_arraydescriptor *desc)
716 return multianewarray_part (dims, 0, desc);
720 static java_arrayheader *nmultianewarray_part (int n, long *dims, int thisdim,
721 constant_arraydescriptor *desc)
726 size = (int) dims[thisdim];
728 if (thisdim == (n - 1)) {
729 /* letzte Dimension schon erreicht */
731 switch (desc -> arraytype) {
732 case ARRAYTYPE_BOOLEAN:
733 return (java_arrayheader*) builtin_newarray_boolean(size);
735 return (java_arrayheader*) builtin_newarray_char(size);
736 case ARRAYTYPE_FLOAT:
737 return (java_arrayheader*) builtin_newarray_float(size);
738 case ARRAYTYPE_DOUBLE:
739 return (java_arrayheader*) builtin_newarray_double(size);
741 return (java_arrayheader*) builtin_newarray_byte(size);
742 case ARRAYTYPE_SHORT:
743 return (java_arrayheader*) builtin_newarray_short(size);
745 return (java_arrayheader*) builtin_newarray_int(size);
747 return (java_arrayheader*) builtin_newarray_long(size);
748 case ARRAYTYPE_OBJECT:
749 return (java_arrayheader*) builtin_anewarray(size,
751 case ARRAYTYPE_ARRAY:
752 return (java_arrayheader*) builtin_newarray_array(size,
753 desc->elementdescriptor);
755 default: panic ("Invalid arraytype in multianewarray");
759 /* wenn letzte Dimension noch nicht erreicht wurde */
761 if (desc->arraytype != ARRAYTYPE_ARRAY)
762 panic ("multianewarray with too many dimensions");
764 a = builtin_newarray_array(size, desc->elementdescriptor);
767 for (i = 0; i < size; i++) {
768 java_arrayheader *ea =
769 nmultianewarray_part(n, dims, thisdim + 1, desc->elementdescriptor);
770 if (!ea) return NULL;
775 return (java_arrayheader*) a;
779 java_arrayheader *builtin_nmultianewarray (int size,
780 constant_arraydescriptor *desc, long *dims)
782 (void) builtin_newarray_int(size); /* for compatibility with -old */
783 return nmultianewarray_part (size, dims, 0, desc);
789 /************************* Funktion: builtin_aastore *************************
791 speichert eine Referenz auf ein Objekt in einem Object-Array oder
792 in einem Array-Array.
793 Dabei wird allerdings vorher "uberpr"uft, ob diese Operation
796 Return: 1, wenn alles OK ist
797 0, wenn dieses Objekt nicht in dieses Array gespeichert werden
800 *****************************************************************************/
802 s4 builtin_aastore (java_objectarray *a, s4 index, java_objectheader *o)
804 if (builtin_canstore(a,o)) {
816 /*****************************************************************************
817 METHODEN-PROTOKOLLIERUNG
819 Verschiedene Funktionen, mit denen eine Meldung ausgegeben werden
820 kann, wann immer Methoden aufgerufen oder beendet werden.
823 *****************************************************************************/
828 java_objectheader *builtin_trace_exception (java_objectheader *exceptionptr,
829 methodinfo *method, int *pos, int noindent) {
833 if (verbose || runverbose) {
834 printf("Exception ");
835 utf_display (exceptionptr->vftbl->class->name);
836 printf(" thrown in ");
838 utf_display (method->class->name);
840 utf_display (method->name);
841 if (method->flags & ACC_SYNCHRONIZED)
845 printf("(%p) at position %p\n", method->entrypoint, pos);
848 printf("call_java_method\n");
855 void builtin_trace_args(long a0, long a1, long a2, long a3, long a4, long a5,
858 sprintf (logtext, " ");
859 sprintf (logtext+methodindent, "called: ");
860 utf_sprint (logtext+strlen(logtext), method->class->name);
861 sprintf (logtext+strlen(logtext), ".");
862 utf_sprint (logtext+strlen(logtext), method->name);
863 utf_sprint (logtext+strlen(logtext), method->descriptor);
864 sprintf (logtext+strlen(logtext), "(");
865 switch (method->paramcount) {
867 sprintf(logtext+strlen(logtext), "%lx, %lx, %lx, %lx, %lx, %lx",
868 a0, a1, a2, a3, a4, a5);
871 sprintf(logtext+strlen(logtext), "%lx, %lx, %lx, %lx, %lx",
875 sprintf(logtext+strlen(logtext), "%lx, %lx, %lx, %lx",
879 sprintf(logtext+strlen(logtext), "%lx, %lx, %lx", a0, a1, a2);
882 sprintf(logtext+strlen(logtext), "%lx, %lx", a0, a1);
885 sprintf(logtext+strlen(logtext), "%lx", a0);
888 sprintf (logtext+strlen(logtext), ")");
894 void builtin_displaymethodstart(methodinfo *method)
896 sprintf (logtext, " ");
897 sprintf (logtext+methodindent, "called: ");
898 utf_sprint (logtext+strlen(logtext), method->class->name);
899 sprintf (logtext+strlen(logtext), ".");
900 utf_sprint (logtext+strlen(logtext), method->name);
901 utf_sprint (logtext+strlen(logtext), method->descriptor);
906 void builtin_displaymethodstop(methodinfo *method, long l, double d)
909 sprintf (logtext, " ");
910 sprintf (logtext+methodindent, "finished: ");
911 utf_sprint (logtext+strlen(logtext), method->class->name);
912 sprintf (logtext+strlen(logtext), ".");
913 utf_sprint (logtext+strlen(logtext), method->name);
914 utf_sprint (logtext+strlen(logtext), method->descriptor);
915 switch (method->returntype) {
918 sprintf (logtext+strlen(logtext), "->%ld", l);
922 sprintf (logtext+strlen(logtext), "->%g", d);
925 sprintf (logtext+strlen(logtext), "->%p", (void*) l);
931 void builtin_displaymethodexception(methodinfo *method)
933 sprintf (logtext, " ");
934 sprintf (logtext+methodindent, "exception abort: ");
935 utf_sprint (logtext+strlen(logtext), method->class->name);
936 sprintf (logtext+strlen(logtext), ".");
937 utf_sprint (logtext+strlen(logtext), method->name);
938 utf_sprint (logtext+strlen(logtext), method->descriptor);
943 /****************************************************************************
944 SYNCHRONIZATION FUNCTIONS
945 *****************************************************************************/
948 * Lock the mutex of an object.
952 internal_lock_mutex_for_object (java_objectheader *object)
954 mutexHashEntry *entry;
959 hashValue = MUTEX_HASH_VALUE(object);
960 entry = &mutexHashTable[hashValue];
962 if (entry->object != 0)
964 if (entry->mutex.count == 0 && entry->conditionCount == 0)
967 entry->mutex.holder = 0;
968 entry->mutex.count = 0;
969 entry->mutex.muxWaiters = 0;
973 while (entry->next != 0 && entry->object != object)
976 if (entry->object != object)
978 entry->next = firstFreeOverflowEntry;
979 firstFreeOverflowEntry = firstFreeOverflowEntry->next;
984 assert(entry->conditionCount == 0);
990 entry->mutex.holder = 0;
991 entry->mutex.count = 0;
992 entry->mutex.muxWaiters = 0;
995 if (entry->object == 0)
996 entry->object = object;
998 internal_lock_mutex(&entry->mutex);
1004 * Unlocks the mutex of an object.
1008 internal_unlock_mutex_for_object (java_objectheader *object)
1011 mutexHashEntry *entry;
1013 hashValue = MUTEX_HASH_VALUE(object);
1014 entry = &mutexHashTable[hashValue];
1016 if (entry->object == object)
1017 internal_unlock_mutex(&entry->mutex);
1020 while (entry->next != 0 && entry->next->object != object)
1021 entry = entry->next;
1023 assert(entry->next != 0);
1025 internal_unlock_mutex(&entry->next->mutex);
1027 if (entry->next->mutex.count == 0 && entry->conditionCount == 0)
1029 mutexHashEntry *unlinked = entry->next;
1031 entry->next = unlinked->next;
1032 unlinked->next = firstFreeOverflowEntry;
1033 firstFreeOverflowEntry = unlinked;
1040 builtin_monitorenter (java_objectheader *o)
1045 assert(blockInts == 0);
1049 hashValue = MUTEX_HASH_VALUE(o);
1050 if (mutexHashTable[hashValue].object == o
1051 && mutexHashTable[hashValue].mutex.holder == currentThread)
1052 ++mutexHashTable[hashValue].mutex.count;
1054 internal_lock_mutex_for_object(o);
1058 assert(blockInts == 0);
1062 void builtin_monitorexit (java_objectheader *o)
1067 assert(blockInts == 0);
1071 hashValue = MUTEX_HASH_VALUE(o);
1072 if (mutexHashTable[hashValue].object == o)
1074 if (mutexHashTable[hashValue].mutex.count == 1
1075 && mutexHashTable[hashValue].mutex.muxWaiters != 0)
1076 internal_unlock_mutex_for_object(o);
1078 --mutexHashTable[hashValue].mutex.count;
1081 internal_unlock_mutex_for_object(o);
1085 assert(blockInts == 0);
1090 /*****************************************************************************
1091 DIVERSE HILFSFUNKTIONEN
1092 *****************************************************************************/
1096 /*********** Funktionen f"ur die Integerdivision *****************************
1098 Auf manchen Systemen (z.B. DEC ALPHA) wird durch die CPU keine Integer-
1099 division unterst"utzt.
1100 Daf"ur gibt es dann diese Hilfsfunktionen
1102 ******************************************************************************/
1104 s4 builtin_idiv (s4 a, s4 b) { return a/b; }
1105 s4 builtin_irem (s4 a, s4 b) { return a%b; }
1108 /************** Funktionen f"ur Long-Arithmetik *******************************
1110 Auf Systemen, auf denen die CPU keine 64-Bit-Integers unterst"utzt,
1111 werden diese Funktionen gebraucht
1113 ******************************************************************************/
1116 s8 builtin_ladd (s8 a, s8 b)
1121 return builtin_i2l(0);
1125 s8 builtin_lsub (s8 a, s8 b)
1130 return builtin_i2l(0);
1134 s8 builtin_lmul (s8 a, s8 b)
1139 return builtin_i2l(0);
1143 s8 builtin_ldiv (s8 a, s8 b)
1148 return builtin_i2l(0);
1152 s8 builtin_lrem (s8 a, s8 b)
1157 return builtin_i2l(0);
1161 s8 builtin_lshl (s8 a, s4 b)
1166 return builtin_i2l(0);
1170 s8 builtin_lshr (s8 a, s4 b)
1175 return builtin_i2l(0);
1179 s8 builtin_lushr (s8 a, s4 b)
1182 return ((u8)a)>>(b&63);
1184 return builtin_i2l(0);
1188 s8 builtin_land (s8 a, s8 b)
1193 return builtin_i2l(0);
1197 s8 builtin_lor (s8 a, s8 b)
1202 return builtin_i2l(0);
1206 s8 builtin_lxor (s8 a, s8 b)
1211 return builtin_i2l(0);
1215 s8 builtin_lneg (s8 a)
1220 return builtin_i2l(0);
1224 s4 builtin_lcmp (s8 a, s8 b)
1239 /*********** Funktionen f"ur die Floating-Point-Operationen ******************/
1241 float builtin_fadd (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;
1250 if (finitef(b)) return a;
1252 if (copysignf(1.0, a)==copysignf(1.0, b)) return a;
1253 else return FLT_NAN;
1258 float builtin_fsub (float a, float b)
1260 return builtin_fadd (a, builtin_fneg(b));
1263 float builtin_fmul (float a, float b)
1265 if (isnanf(a)) return FLT_NAN;
1266 if (isnanf(b)) return FLT_NAN;
1268 if (finitef(b)) return a*b;
1270 if (a==0) return FLT_NAN;
1271 else return copysignf(b, copysignf(1.0, b)*a);
1276 if (b==0) return FLT_NAN;
1277 else return copysignf(a, copysignf(1.0, a)*b);
1280 return copysignf(a, copysignf(1.0, a)*copysignf(1.0, b));
1285 float builtin_fdiv (float a, float b)
1287 if (finitef(a) && finitef(b)) {
1300 float builtin_frem (float a, float b)
1303 /* return (float) builtin_drem((double) a, (double) b); */
1307 if (finite((double) a) && finite((double) b)) {
1309 if (finite((double) f))
1313 if (isnan((double) b))
1315 if (finite((double) a))
1321 if (finitef(a) && finitef(b)) {
1324 return a - floorf(f) * b;
1335 float builtin_fneg (float a)
1337 if (isnanf(a)) return a;
1339 if (finitef(a)) return -a;
1340 else return copysignf(a,-copysignf(1.0, a));
1344 s4 builtin_fcmpl (float a, float b)
1346 if (isnanf(a)) return -1;
1347 if (isnanf(b)) return -1;
1348 if (!finitef(a) || !finitef(b)) {
1349 a = finitef(a) ? 0 : copysignf(1.0, a);
1350 b = finitef(b) ? 0 : copysignf(1.0, b);
1357 s4 builtin_fcmpg (float a, float b)
1359 if (isnanf(a)) return 1;
1360 if (isnanf(b)) return 1;
1361 if (!finitef(a) || !finitef(b)) {
1362 a = finitef(a) ? 0 : copysignf(1.0, a);
1363 b = finitef(b) ? 0 : copysignf(1.0, b);
1372 /*********** Funktionen f"ur doppelt genaue Fliesskommazahlen ***************/
1374 double builtin_dadd (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;
1383 if (finite(b)) return a;
1385 if (copysign(1.0, a)==copysign(1.0, b)) return a;
1386 else return DBL_NAN;
1391 double builtin_dsub (double a, double b)
1393 return builtin_dadd (a, builtin_dneg(b));
1396 double builtin_dmul (double a, double b)
1398 if (isnan(a)) return DBL_NAN;
1399 if (isnan(b)) return DBL_NAN;
1401 if (finite(b)) return a*b;
1403 if (a==0) return DBL_NAN;
1404 else return copysign(b, copysign(1.0, b)*a);
1409 if (b==0) return DBL_NAN;
1410 else return copysign(a, copysign(1.0, a)*b);
1413 return copysign(a, copysign(1.0, a)*copysign(1.0, b));
1418 double builtin_ddiv (double a, double b)
1420 if (finite(a) && finite(b)) {
1433 double builtin_drem (double a, double b)
1437 if (finite(a) && finite(b)) {
1440 if ((d < 1.0) && (d > 0.0))
1453 double builtin_dneg (double a)
1455 if (isnan(a)) return a;
1457 if (finite(a)) return -a;
1458 else return copysign(a,-copysign(1.0, a));
1462 s4 builtin_dcmpl (double a, double b)
1464 if (isnan(a)) return -1;
1465 if (isnan(b)) return -1;
1466 if (!finite(a) || !finite(b)) {
1467 a = finite(a) ? 0 : copysign(1.0, a);
1468 b = finite(b) ? 0 : copysign(1.0, b);
1475 s4 builtin_dcmpg (double a, double b)
1477 if (isnan(a)) return 1;
1478 if (isnan(b)) return 1;
1479 if (!finite(a) || !finite(b)) {
1480 a = finite(a) ? 0 : copysign(1.0, a);
1481 b = finite(b) ? 0 : copysign(1.0, b);
1489 /*********************** Umwandlungsoperationen ****************************/
1491 s8 builtin_i2l (s4 i)
1496 s8 v; v.high = 0; v.low=i; return v;
1500 float builtin_i2f (s4 a)
1502 float f = (float) a;
1506 double builtin_i2d (s4 a)
1508 double d = (double) a;
1513 s4 builtin_l2i (s8 l)
1522 float builtin_l2f (s8 a)
1525 float f = (float) a;
1532 double builtin_l2d (s8 a)
1535 double d = (double) a;
1543 s4 builtin_f2i(float a)
1546 return builtin_d2i((double) a);
1555 if (a < (-2147483648))
1556 return (-2147483648);
1559 f = copysignf((float) 1.0, a);
1562 return (-2147483648); */
1566 s8 builtin_f2l (float a)
1569 return builtin_d2l((double) a);
1574 if (a > 9223372036854775807L)
1575 return 9223372036854775807L;
1576 if (a < (-9223372036854775808L))
1577 return (-9223372036854775808L);
1582 f = copysignf((float) 1.0, a);
1584 return 9223372036854775807L;
1585 return (-9223372036854775808L); */
1589 double builtin_f2d (float a)
1591 if (finitef(a)) return (double) a;
1593 if (isnanf(a)) return DBL_NAN;
1594 else return copysign(DBL_POSINF, (double) copysignf(1.0, a) );
1599 s4 builtin_d2i (double a)
1604 if (a >= 2147483647)
1606 if (a <= (-2147483648))
1607 return (-2147483648);
1612 d = copysign(1.0, a);
1615 return (-2147483648);
1619 s8 builtin_d2l (double a)
1624 if (a >= 9223372036854775807L)
1625 return 9223372036854775807L;
1626 if (a <= (-9223372036854775807L-1))
1627 return (-9223372036854775807L-1);
1632 d = copysign(1.0, a);
1634 return 9223372036854775807L;
1635 return (-9223372036854775807L-1);
1639 float builtin_d2f (double a)
1641 if (finite(a)) return (float) a;
1643 if (isnan(a)) return FLT_NAN;
1644 else return copysignf (FLT_POSINF, (float) copysign(1.0, a));
1650 * These are local overrides for various environment variables in Emacs.
1651 * Please do not remove this and leave it at the end of the file, where
1652 * Emacs will automagically detect them.
1653 * ---------------------------------------------------------------------
1656 * indent-tabs-mode: t