1 /* -*- mode: c; tab-width: 4; c-basic-offset: 4 -*- */
2 /****************************** builtin.c **************************************
4 Copyright (c) 1997 A. Krall, R. Grafl, M. Gschwind, M. Probst
6 See file COPYRIGHT for information on usage and disclaimer of warranties
8 Enthaelt die C-Funktionen fuer alle JavaVM-Befehle, die sich nicht direkt
9 auf Maschinencode "ubersetzen lassen. Im Code f"ur die Methoden steht
10 dann ein Funktionsaufruf (nat"urlich mit den Aufrufskonventionen von C).
12 Authors: Reinhard Grafl EMAIL: cacao@complang.tuwien.ac.at
13 Andreas Krall EMAIL: cacao@complang.tuwien.ac.at
14 Mark Probst EMAIL: cacao@complang.tuwien.ac.at
16 Last Change: 1996/12/03
18 *******************************************************************************/
29 #include "threads/thread.h"
30 #include "threads/locks.h" /* schani */
32 #include "sysdep/native-math.h"
34 builtin_descriptor builtin_desc[] = {
35 {(functionptr) builtin_instanceof, "instanceof"},
36 {(functionptr) builtin_checkcast, "checkcast"},
37 {(functionptr) new_builtin_checkcast, "checkcast"},
38 {(functionptr) builtin_arrayinstanceof, "arrayinstanceof"},
39 {(functionptr) builtin_checkarraycast, "checkarraycast"},
40 {(functionptr) new_builtin_checkarraycast, "checkarraycast"},
41 {(functionptr) new_builtin_aastore, "aastore"},
42 {(functionptr) builtin_new, "new"},
43 {(functionptr) builtin_anewarray, "anewarray"},
44 {(functionptr) builtin_newarray_array, "newarray_array"},
45 {(functionptr) builtin_newarray_boolean, "newarray_boolean"},
46 {(functionptr) builtin_newarray_char, "newarray_char"},
47 {(functionptr) builtin_newarray_float, "newarray_float"},
48 {(functionptr) builtin_newarray_double, "newarray_double"},
49 {(functionptr) builtin_newarray_byte, "newarray_byte"},
50 {(functionptr) builtin_newarray_short, "newarray_short"},
51 {(functionptr) builtin_newarray_int, "newarray_int"},
52 {(functionptr) builtin_newarray_long, "newarray_long"},
53 {(functionptr) builtin_displaymethodstart, "displaymethodstart"},
54 {(functionptr) builtin_displaymethodstop, "displaymethodstop"},
55 {(functionptr) builtin_monitorenter, "monitorenter"},
56 {(functionptr) new_builtin_monitorenter, "monitorenter"},
57 {(functionptr) builtin_monitorexit, "monitorexit"},
58 {(functionptr) new_builtin_monitorexit, "monitorexit"},
59 {(functionptr) builtin_idiv, "idiv"},
60 {(functionptr) new_builtin_idiv, "idiv"},
61 {(functionptr) builtin_irem, "irem"},
62 {(functionptr) new_builtin_irem, "irem"},
63 {(functionptr) builtin_ladd, "ladd"},
64 {(functionptr) builtin_lsub, "lsub"},
65 {(functionptr) builtin_lmul, "lmul"},
66 {(functionptr) builtin_ldiv, "ldiv"},
67 {(functionptr) new_builtin_ldiv, "ldiv"},
68 {(functionptr) builtin_lrem, "lrem"},
69 {(functionptr) new_builtin_lrem, "lrem"},
70 {(functionptr) builtin_lshl, "lshl"},
71 {(functionptr) builtin_lshr, "lshr"},
72 {(functionptr) builtin_lushr, "lushr"},
73 {(functionptr) builtin_land, "land"},
74 {(functionptr) builtin_lor, "lor"},
75 {(functionptr) builtin_lxor, "lxor"},
76 {(functionptr) builtin_lneg, "lneg"},
77 {(functionptr) builtin_lcmp, "lcmp"},
78 {(functionptr) builtin_fadd, "fadd"},
79 {(functionptr) builtin_fsub, "fsub"},
80 {(functionptr) builtin_fmul, "fmul"},
81 {(functionptr) builtin_fdiv, "fdiv"},
82 {(functionptr) builtin_frem, "frem"},
83 {(functionptr) builtin_fneg, "fneg"},
84 {(functionptr) builtin_fcmpl, "fcmpl"},
85 {(functionptr) builtin_fcmpg, "fcmpg"},
86 {(functionptr) builtin_dadd, "dadd"},
87 {(functionptr) builtin_dsub, "dsub"},
88 {(functionptr) builtin_dmul, "dmul"},
89 {(functionptr) builtin_ddiv, "ddiv"},
90 {(functionptr) builtin_drem, "drem"},
91 {(functionptr) builtin_dneg, "dneg"},
92 {(functionptr) builtin_dcmpl, "dcmpl"},
93 {(functionptr) builtin_dcmpg, "dcmpg"},
94 {(functionptr) builtin_i2l, "i2l"},
95 {(functionptr) builtin_i2f, "i2f"},
96 {(functionptr) builtin_i2d, "i2d"},
97 {(functionptr) builtin_l2i, "l2i"},
98 {(functionptr) builtin_l2f, "l2f"},
99 {(functionptr) builtin_l2d, "l2d"},
100 {(functionptr) builtin_f2i, "f2i"},
101 {(functionptr) builtin_f2l, "f2l"},
102 {(functionptr) builtin_f2d, "f2d"},
103 {(functionptr) builtin_d2i, "d2i"},
104 {(functionptr) builtin_d2l, "d2l"},
105 {(functionptr) builtin_d2f, "d2f"},
106 {(functionptr) NULL, "unknown"}
110 /*****************************************************************************
112 *****************************************************************************/
116 /*************** interne Funktion: builtin_isanysubclass *********************
118 "uberpr"uft, ob eine Klasse eine Unterklasse einer anderen Klasse ist.
119 Dabei gelten auch Interfaces, die eine Klasse implementiert, als
121 R"uckgabewert: 1 ... es trifft zu
122 0 ... es trifft nicht zu
124 *****************************************************************************/
126 static s4 builtin_isanysubclass (classinfo *sub, classinfo *super)
128 if (super->flags & ACC_INTERFACE) {
129 u4 index = super->index;
130 /* if (sub->vftbl == NULL) return 0; */
131 if (index >= sub->vftbl->interfacetablelength) return 0;
132 return ( sub->vftbl->interfacevftbl[index] ) ? 1 : 0;
136 if (sub==super) return 1;
144 /****************** Funktion: builtin_instanceof *****************************
146 "Uberpr"uft, ob ein Objekt eine Instanz einer Klasse (oder einer davon
147 abgeleiteten Klasse) ist, oder ob die Klasse des Objekts ein Interface
150 0, wenn nicht, oder wenn Objekt ein NULL-Zeiger
152 *****************************************************************************/
154 s4 builtin_instanceof(java_objectheader *obj, classinfo *class)
157 log_text ("builtin_instanceof called");
161 return builtin_isanysubclass (obj->vftbl->class, class);
166 /**************** Funktion: builtin_checkcast *******************************
168 "Uberpr"uft, ob ein Objekt eine Instanz einer Klasse (oder einer davon
169 abgeleiteten Klasse ist).
170 Unterschied zu builtin_instanceof: Ein NULL-Zeiger ist immer richtig
171 Return: 1, wenn ja, oder wenn Objekt ein NULL-Zeiger
174 ****************************************************************************/
176 s4 builtin_checkcast(java_objectheader *obj, classinfo *class)
179 log_text ("builtin_checkcast called");
183 if ( builtin_isanysubclass (obj->vftbl->class, class) ) {
187 printf ("#### checkcast failed ");
188 unicode_display (obj->vftbl->class->name);
190 unicode_display (class->name);
199 /*********** interne Funktion: builtin_descriptorscompatible ******************
201 "uberpr"uft, ob zwei Array-Typdescriptoren compartible sind, d.h.,
202 ob ein Array vom Typ 'desc' gefahrlos einer Variblen vom Typ 'target'
203 zugewiesen werden kann.
207 ******************************************************************************/
209 static s4 builtin_descriptorscompatible
210 (constant_arraydescriptor *desc, constant_arraydescriptor *target)
212 if (desc==target) return 1;
213 if (desc->arraytype != target->arraytype) return 0;
214 switch (target->arraytype) {
215 case ARRAYTYPE_OBJECT:
216 return builtin_isanysubclass (desc->objectclass, target->objectclass);
217 case ARRAYTYPE_ARRAY:
218 return builtin_descriptorscompatible
219 (desc->elementdescriptor, target->elementdescriptor);
226 /******************** Funktion: builtin_checkarraycast ***********************
228 "uberpr"uft, ob ein gegebenes Objekt tats"achlich von einem
229 Untertyp des geforderten Arraytyps ist.
230 Dazu muss das Objekt auf jeden Fall ein Array sein.
231 Bei einfachen Arrays (int,short,double,etc.) muss der Typ genau
233 Bei Arrays von Objekten muss der Elementtyp des tats"achlichen Arrays
234 ein Untertyp (oder der selbe Typ) vom geforderten Elementtyp sein.
235 Bei Arrays vom Arrays (die eventuell wieder Arrays von Arrays
236 sein k"onnen) m"ussen die untersten Elementtypen in der entsprechenden
237 Unterklassenrelation stehen.
239 Return: 1, wenn Cast in Ordung ist
240 0, wenn es nicht geht
242 Achtung: ein Cast mit einem NULL-Zeiger geht immer gut.
244 *****************************************************************************/
246 s4 builtin_checkarraycast(java_objectheader *o, constant_arraydescriptor *desc)
248 java_arrayheader *a = (java_arrayheader*) o;
251 if (o->vftbl->class != class_array) {
255 if (a->arraytype != desc->arraytype) {
259 switch (a->arraytype) {
260 case ARRAYTYPE_OBJECT: {
261 java_objectarray *oa = (java_objectarray*) o;
262 return builtin_isanysubclass (oa->elementtype, desc->objectclass);
264 case ARRAYTYPE_ARRAY: {
265 java_arrayarray *aa = (java_arrayarray*) o;
266 return builtin_descriptorscompatible
267 (aa->elementdescriptor, desc->elementdescriptor);
275 s4 builtin_arrayinstanceof
276 (java_objectheader *obj, constant_arraydescriptor *desc)
279 return builtin_checkarraycast (obj, desc);
283 /************************** exception functions *******************************
285 ******************************************************************************/
287 java_objectheader *builtin_throw_exception (java_objectheader *exceptionptr) {
288 unicode_display (exceptionptr->vftbl->class->name);
295 /******************* Funktion: builtin_canstore *******************************
297 "uberpr"uft, ob ein Objekt in einem Array gespeichert werden
299 Return: 1, wenn es geht
302 ******************************************************************************/
305 s4 builtin_canstore (java_objectarray *a, java_objectheader *o)
309 switch (a->header.arraytype) {
310 case ARRAYTYPE_OBJECT:
311 if ( ! builtin_checkcast (o, a->elementtype) ) {
317 case ARRAYTYPE_ARRAY:
318 if ( ! builtin_checkarraycast
319 (o, ((java_arrayarray*)a)->elementdescriptor) ) {
326 panic ("builtin_canstore called with invalid arraytype");
333 /*****************************************************************************
335 *****************************************************************************/
339 /******************** Funktion: builtin_new **********************************
341 Legt ein neues Objekt einer Klasse am Heap an.
342 Return: Der Zeiger auf das Objekt, oder NULL, wenn kein Speicher
345 *****************************************************************************/
347 java_objectheader *builtin_new (classinfo *c)
349 java_objectheader *o;
351 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 *****************************************************************************/
374 java_objectarray *builtin_anewarray (s4 size, classinfo *elementtype)
379 a = heap_allocate ( sizeof(java_objectarray) + (size-1) * sizeof(void*),
380 true, 0 /* FALSE */ );
383 a -> header.objheader.vftbl = class_array -> vftbl;
384 a -> header.size = size;
385 a -> header.arraytype = ARRAYTYPE_OBJECT;
386 a -> elementtype = elementtype;
387 for (i=0; i<size; i++) a->data[i] = NULL;
393 /******************** Funktion: builtin_newarray_array ***********************
395 Legt ein Array von Zeigern auf Arrays am Heap an.
396 Paramter: size ......... Anzahl der Elemente
397 elementdesc .. Zeiger auf die Arraybeschreibungs-Struktur f"ur
400 Return: Zeiger auf das Array, oder NULL
402 *****************************************************************************/
404 java_arrayarray *builtin_newarray_array
405 (s4 size, constant_arraydescriptor *elementdesc)
410 a = heap_allocate ( sizeof(java_arrayarray) + (size-1) * sizeof(void*),
414 a -> header.objheader.vftbl = class_array -> vftbl;
415 a -> header.size = size;
416 a -> header.arraytype = ARRAYTYPE_ARRAY;
417 a -> elementdescriptor = elementdesc;
418 for (i=0; i<size; i++) a->data[i] = NULL;
423 /******************** Funktion: builtin_newarray_boolean ************************
425 Legt ein Array von Bytes am Heap an, das allerdings als Boolean-Array
426 gekennzeichnet wird (wichtig bei Casts!)
428 Return: Zeiger auf das Array, oder NULL
430 *****************************************************************************/
432 java_booleanarray *builtin_newarray_boolean (s4 size)
434 java_booleanarray *a;
436 a = heap_allocate ( sizeof(java_booleanarray) + (size-1) * sizeof(u1),
440 a -> header.objheader.vftbl = class_array -> vftbl;
441 a -> header.size = size;
442 a -> header.arraytype = ARRAYTYPE_BOOLEAN;
443 memset (a->data, 0, sizeof(u1) * size);
448 /******************** Funktion: builtin_newarray_char ************************
450 Legt ein Array von 16-bit-Integers am Heap an.
451 Return: Zeiger auf das Array, oder NULL
453 *****************************************************************************/
455 java_chararray *builtin_newarray_char (s4 size)
459 a = heap_allocate ( sizeof(java_chararray) + (size-1) * sizeof(u2),
463 a -> header.objheader.vftbl = class_array -> vftbl;
464 a -> header.size = size;
465 a -> header.arraytype = ARRAYTYPE_CHAR;
466 memset (a->data, 0, sizeof(u2) * size);
472 /******************** Funktion: builtin_newarray_float ***********************
474 Legt ein Array von 32-bit-IEEE-float am Heap an.
475 Return: Zeiger auf das Array, oder NULL
477 *****************************************************************************/
479 java_floatarray *builtin_newarray_float (s4 size)
484 a = heap_allocate ( sizeof(java_floatarray) + (size-1) * sizeof(float),
488 a -> header.objheader.vftbl = class_array -> vftbl;
489 a -> header.size = size;
490 a -> header.arraytype = ARRAYTYPE_FLOAT;
491 for (i=0; i<size; i++) a->data[i] = 0.0;
496 /******************** Funktion: builtin_newarray_double ***********************
498 Legt ein Array von 64-bit-IEEE-float am Heap an.
499 Return: Zeiger auf das Array, oder NULL
501 *****************************************************************************/
503 java_doublearray *builtin_newarray_double (s4 size)
508 a = heap_allocate ( sizeof(java_doublearray) + (size-1) * sizeof(double),
512 a -> header.objheader.vftbl = class_array -> vftbl;
513 a -> header.size = size;
514 a -> header.arraytype = ARRAYTYPE_DOUBLE;
515 for (i=0; i<size; i++) a->data[i] = 0.0;
522 /******************** Funktion: builtin_newarray_byte ***********************
524 Legt ein Array von 8-bit-Integers am Heap an.
525 Return: Zeiger auf das Array, oder NULL
527 *****************************************************************************/
529 java_bytearray *builtin_newarray_byte (s4 size)
533 a = heap_allocate ( sizeof(java_bytearray) + (size-1) * sizeof(s1),
537 a -> header.objheader.vftbl = class_array->vftbl;
538 a -> header.size = size;
539 a -> header.arraytype = ARRAYTYPE_BYTE;
540 memset (a->data, 0, sizeof(u1) * size);
545 /******************** Funktion: builtin_newarray_short ***********************
547 Legt ein Array von 16-bit-Integers am Heap an.
548 Return: Zeiger auf das Array, oder NULL
550 *****************************************************************************/
552 java_shortarray *builtin_newarray_short (s4 size)
556 a = heap_allocate ( sizeof(java_shortarray) + (size-1) * sizeof(s2),
560 a -> header.objheader.vftbl = class_array -> vftbl;
561 a -> header.size = size;
562 a -> header.arraytype = ARRAYTYPE_SHORT;
563 memset (a->data, 0, sizeof(s2) * size);
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)
579 a = heap_allocate ( sizeof(java_intarray) + (size-1) * sizeof(s4),
583 a -> header.objheader.vftbl = class_array -> vftbl;
584 a -> header.size = size;
585 a -> header.arraytype = ARRAYTYPE_INT;
586 memset (a->data, 0, sizeof(s4) * size);
591 /******************** Funktion: builtin_newarray_long ***********************
593 Legt ein Array von 64-bit-Integers am Heap an.
594 Return: Zeiger auf das Array, oder NULL
596 *****************************************************************************/
598 java_longarray *builtin_newarray_long (s4 size)
602 a = heap_allocate ( sizeof(java_longarray) + (size-1) * sizeof(s8),
606 a -> header.objheader.vftbl = class_array -> vftbl;
607 a -> header.size = size;
608 a -> header.arraytype = ARRAYTYPE_LONG;
609 memset (a->data, 0, sizeof(s8) * size);
615 /***************** Funktion: builtin_multianewarray ***************************
617 Legt ein mehrdimensionales Array am Heap an.
618 Die Gr"ossen der einzelnen Dimensionen werden in einem Integerarray
619 "ubergeben. Der Typ es zu erzeugenden Arrays wird als
620 Referenz auf eine constant_arraydescriptor - Struktur "ubergeben.
622 Return: Ein Zeiger auf das Array, oder NULL, wenn kein Speicher mehr
625 ******************************************************************************/
629 static java_arrayheader *multianewarray_part (java_intarray *dims, int thisdim,
630 constant_arraydescriptor *desc)
635 size = dims -> data[thisdim];
637 if (thisdim == (dims->header.size-1)) {
638 /* letzte Dimension schon erreicht */
640 switch (desc -> arraytype) {
641 case ARRAYTYPE_BOOLEAN:
642 return (java_arrayheader*) builtin_newarray_boolean (size);
644 return (java_arrayheader*) builtin_newarray_char (size);
645 case ARRAYTYPE_FLOAT:
646 return (java_arrayheader*) builtin_newarray_float (size);
647 case ARRAYTYPE_DOUBLE:
648 return (java_arrayheader*) builtin_newarray_double (size);
650 return (java_arrayheader*) builtin_newarray_byte (size);
651 case ARRAYTYPE_SHORT:
652 return (java_arrayheader*) builtin_newarray_short (size);
654 return (java_arrayheader*) builtin_newarray_int (size);
656 return (java_arrayheader*) builtin_newarray_long (size);
657 case ARRAYTYPE_OBJECT:
658 return (java_arrayheader*) builtin_anewarray (size, desc->objectclass);
660 case ARRAYTYPE_ARRAY:
661 return (java_arrayheader*) builtin_newarray_array (size, desc->elementdescriptor);
663 default: panic ("Invalid arraytype in multianewarray");
667 /* wenn letzte Dimension noch nicht erreicht wurde */
669 if (desc->arraytype != ARRAYTYPE_ARRAY)
670 panic ("multianewarray with too many dimensions");
672 a = builtin_newarray_array (size, desc->elementdescriptor);
675 for (i=0; i<size; i++) {
676 java_arrayheader *ea =
677 multianewarray_part (dims, thisdim+1, desc->elementdescriptor);
678 if (!ea) return NULL;
683 return (java_arrayheader*) a;
687 java_arrayheader *builtin_multianewarray (java_intarray *dims,
688 constant_arraydescriptor *desc)
690 return multianewarray_part (dims, 0, desc);
694 static java_arrayheader *nmultianewarray_part (int n, long *dims, int thisdim,
695 constant_arraydescriptor *desc)
700 size = (int) dims[thisdim];
702 if (thisdim == (n - 1)) {
703 /* letzte Dimension schon erreicht */
705 switch (desc -> arraytype) {
706 case ARRAYTYPE_BOOLEAN:
707 return (java_arrayheader*) builtin_newarray_boolean(size);
709 return (java_arrayheader*) builtin_newarray_char(size);
710 case ARRAYTYPE_FLOAT:
711 return (java_arrayheader*) builtin_newarray_float(size);
712 case ARRAYTYPE_DOUBLE:
713 return (java_arrayheader*) builtin_newarray_double(size);
715 return (java_arrayheader*) builtin_newarray_byte(size);
716 case ARRAYTYPE_SHORT:
717 return (java_arrayheader*) builtin_newarray_short(size);
719 return (java_arrayheader*) builtin_newarray_int(size);
721 return (java_arrayheader*) builtin_newarray_long(size);
722 case ARRAYTYPE_OBJECT:
723 return (java_arrayheader*) builtin_anewarray(size,
725 case ARRAYTYPE_ARRAY:
726 return (java_arrayheader*) builtin_newarray_array(size,
727 desc->elementdescriptor);
729 default: panic ("Invalid arraytype in multianewarray");
733 /* wenn letzte Dimension noch nicht erreicht wurde */
735 if (desc->arraytype != ARRAYTYPE_ARRAY)
736 panic ("multianewarray with too many dimensions");
738 a = builtin_newarray_array(size, desc->elementdescriptor);
741 for (i = 0; i < size; i++) {
742 java_arrayheader *ea =
743 nmultianewarray_part(n, dims, thisdim + 1, desc->elementdescriptor);
744 if (!ea) return NULL;
749 return (java_arrayheader*) a;
753 java_arrayheader *builtin_nmultianewarray (int size,
754 constant_arraydescriptor *desc, long *dims)
756 (void) builtin_newarray_int(size); /* for compatibility with -old */
757 return nmultianewarray_part (size, dims, 0, desc);
763 /************************* Funktion: builtin_aastore *************************
765 speichert eine Referenz auf ein Objekt in einem Object-Array oder
766 in einem Array-Array.
767 Dabei wird allerdings vorher "uberpr"uft, ob diese Operation
770 Return: 1, wenn alles OK ist
771 0, wenn dieses Objekt nicht in dieses Array gespeichert werden
774 *****************************************************************************/
776 s4 builtin_aastore (java_objectarray *a, s4 index, java_objectheader *o)
778 if (builtin_canstore(a,o)) {
790 /*****************************************************************************
791 METHODEN-PROTOKOLLIERUNG
793 Verschiedene Funktionen, mit denen eine Meldung ausgegeben werden
794 kann, wann immer Methoden aufgerufen oder beendet werden.
797 *****************************************************************************/
802 java_objectheader *builtin_trace_exception (java_objectheader *exceptionptr,
803 methodinfo *method, int *pos, int noindent) {
807 if (verbose || runverbose) {
808 printf("Exception ");
809 unicode_display (exceptionptr->vftbl->class->name);
810 printf(" thrown in ");
812 unicode_display (method->class->name);
814 unicode_display (method->name);
815 if (method->flags & ACC_SYNCHRONIZED)
819 printf("(%p) at position %p\n", method->entrypoint, pos);
822 printf("call_java_method\n");
829 void builtin_trace_args(long a0, long a1, long a2, long a3, long a4, long a5,
832 sprintf (logtext, " ");
833 sprintf (logtext+methodindent, "called: ");
834 unicode_sprint (logtext+strlen(logtext), method->class->name);
835 sprintf (logtext+strlen(logtext), ".");
836 unicode_sprint (logtext+strlen(logtext), method->name);
837 unicode_sprint (logtext+strlen(logtext), method->descriptor);
838 sprintf (logtext+strlen(logtext), "(");
839 switch (method->paramcount) {
841 sprintf(logtext+strlen(logtext), "%lx, %lx, %lx, %lx, %lx, %lx",
842 a0, a1, a2, a3, a4, a5);
845 sprintf(logtext+strlen(logtext), "%lx, %lx, %lx, %lx, %lx",
849 sprintf(logtext+strlen(logtext), "%lx, %lx, %lx, %lx",
853 sprintf(logtext+strlen(logtext), "%lx, %lx, %lx", a0, a1, a2);
856 sprintf(logtext+strlen(logtext), "%lx, %lx", a0, a1);
859 sprintf(logtext+strlen(logtext), "%lx", a0);
862 sprintf (logtext+strlen(logtext), ")");
868 void builtin_displaymethodstart(methodinfo *method)
870 sprintf (logtext, " ");
871 sprintf (logtext+methodindent, "called: ");
872 unicode_sprint (logtext+strlen(logtext), method->class->name);
873 sprintf (logtext+strlen(logtext), ".");
874 unicode_sprint (logtext+strlen(logtext), method->name);
875 unicode_sprint (logtext+strlen(logtext), method->descriptor);
880 void builtin_displaymethodstop(methodinfo *method, long l, double d)
883 sprintf (logtext, " ");
884 sprintf (logtext+methodindent, "finished: ");
885 unicode_sprint (logtext+strlen(logtext), method->class->name);
886 sprintf (logtext+strlen(logtext), ".");
887 unicode_sprint (logtext+strlen(logtext), method->name);
888 unicode_sprint (logtext+strlen(logtext), method->descriptor);
889 switch (method->returntype) {
892 sprintf (logtext+strlen(logtext), "->%ld", l);
896 sprintf (logtext+strlen(logtext), "->%g", d);
899 sprintf (logtext+strlen(logtext), "->%p", (void*) l);
905 void builtin_displaymethodexception(methodinfo *method)
907 sprintf (logtext, " ");
908 sprintf (logtext+methodindent, "exception abort: ");
909 unicode_sprint (logtext+strlen(logtext), method->class->name);
910 sprintf (logtext+strlen(logtext), ".");
911 unicode_sprint (logtext+strlen(logtext), method->name);
912 unicode_sprint (logtext+strlen(logtext), method->descriptor);
917 /****************************************************************************
918 SYNCHRONIZATION FUNCTIONS
919 *****************************************************************************/
922 * Lock the mutex of an object.
926 internal_lock_mutex_for_object (java_objectheader *object)
928 mutexHashEntry *entry;
933 hashValue = MUTEX_HASH_VALUE(object);
934 entry = &mutexHashTable[hashValue];
936 if (entry->object != 0)
938 if (entry->mutex.count == 0 && entry->conditionCount == 0)
941 entry->mutex.holder = 0;
942 entry->mutex.count = 0;
943 entry->mutex.muxWaiters = 0;
947 while (entry->next != 0 && entry->object != object)
950 if (entry->object != object)
952 entry->next = firstFreeOverflowEntry;
953 firstFreeOverflowEntry = firstFreeOverflowEntry->next;
958 assert(entry->conditionCount == 0);
964 entry->mutex.holder = 0;
965 entry->mutex.count = 0;
966 entry->mutex.muxWaiters = 0;
969 if (entry->object == 0)
970 entry->object = object;
972 internal_lock_mutex(&entry->mutex);
978 * Unlocks the mutex of an object.
982 internal_unlock_mutex_for_object (java_objectheader *object)
985 mutexHashEntry *entry;
987 hashValue = MUTEX_HASH_VALUE(object);
988 entry = &mutexHashTable[hashValue];
990 if (entry->object == object)
991 internal_unlock_mutex(&entry->mutex);
994 while (entry->next != 0 && entry->next->object != object)
997 assert(entry->next != 0);
999 internal_unlock_mutex(&entry->next->mutex);
1001 if (entry->next->mutex.count == 0 && entry->conditionCount == 0)
1003 mutexHashEntry *unlinked = entry->next;
1005 entry->next = unlinked->next;
1006 unlinked->next = firstFreeOverflowEntry;
1007 firstFreeOverflowEntry = unlinked;
1014 builtin_monitorenter (java_objectheader *o)
1019 assert(blockInts == 0);
1023 hashValue = MUTEX_HASH_VALUE(o);
1024 if (mutexHashTable[hashValue].object == o
1025 && mutexHashTable[hashValue].mutex.holder == currentThread)
1026 ++mutexHashTable[hashValue].mutex.count;
1028 internal_lock_mutex_for_object(o);
1032 assert(blockInts == 0);
1036 void builtin_monitorexit (java_objectheader *o)
1041 assert(blockInts == 0);
1045 hashValue = MUTEX_HASH_VALUE(o);
1046 if (mutexHashTable[hashValue].object == o)
1048 if (mutexHashTable[hashValue].mutex.count == 1
1049 && mutexHashTable[hashValue].mutex.muxWaiters != 0)
1050 internal_unlock_mutex_for_object(o);
1052 --mutexHashTable[hashValue].mutex.count;
1055 internal_unlock_mutex_for_object(o);
1059 assert(blockInts == 0);
1064 /*****************************************************************************
1065 DIVERSE HILFSFUNKTIONEN
1066 *****************************************************************************/
1070 /*********** Funktionen f"ur die Integerdivision *****************************
1072 Auf manchen Systemen (z.B. DEC ALPHA) wird durch die CPU keine Integer-
1073 division unterst"utzt.
1074 Daf"ur gibt es dann diese Hilfsfunktionen
1076 ******************************************************************************/
1078 s4 builtin_idiv (s4 a, s4 b) { return a/b; }
1079 s4 builtin_irem (s4 a, s4 b) { return a%b; }
1082 /************** Funktionen f"ur Long-Arithmetik *******************************
1084 Auf Systemen, auf denen die CPU keine 64-Bit-Integers unterst"utzt,
1085 werden diese Funktionen gebraucht
1087 ******************************************************************************/
1090 s8 builtin_ladd (s8 a, s8 b)
1095 return builtin_i2l(0);
1099 s8 builtin_lsub (s8 a, s8 b)
1104 return builtin_i2l(0);
1108 s8 builtin_lmul (s8 a, s8 b)
1113 return builtin_i2l(0);
1117 s8 builtin_ldiv (s8 a, s8 b)
1122 return builtin_i2l(0);
1126 s8 builtin_lrem (s8 a, s8 b)
1131 return builtin_i2l(0);
1135 s8 builtin_lshl (s8 a, s4 b)
1140 return builtin_i2l(0);
1144 s8 builtin_lshr (s8 a, s4 b)
1149 return builtin_i2l(0);
1153 s8 builtin_lushr (s8 a, s4 b)
1156 return ((u8)a)>>(b&63);
1158 return builtin_i2l(0);
1162 s8 builtin_land (s8 a, s8 b)
1167 return builtin_i2l(0);
1171 s8 builtin_lor (s8 a, s8 b)
1176 return builtin_i2l(0);
1180 s8 builtin_lxor (s8 a, s8 b)
1185 return builtin_i2l(0);
1189 s8 builtin_lneg (s8 a)
1194 return builtin_i2l(0);
1198 s4 builtin_lcmp (s8 a, s8 b)
1213 /*********** Funktionen f"ur die Floating-Point-Operationen ******************/
1215 float builtin_fadd (float a, float b)
1217 if (isnanf(a)) return FLT_NAN;
1218 if (isnanf(b)) return FLT_NAN;
1220 if (finitef(b)) return a+b;
1224 if (finitef(b)) return a;
1226 if (copysignf(1.0, a)==copysignf(1.0, b)) return a;
1227 else return FLT_NAN;
1232 float builtin_fsub (float a, float b)
1234 return builtin_fadd (a, builtin_fneg(b));
1237 float builtin_fmul (float a, float b)
1239 if (isnanf(a)) return FLT_NAN;
1240 if (isnanf(b)) return FLT_NAN;
1242 if (finitef(b)) return a*b;
1244 if (a==0) return FLT_NAN;
1245 else return copysignf(b, copysignf(1.0, b)*a);
1250 if (b==0) return FLT_NAN;
1251 else return copysignf(a, copysignf(1.0, a)*b);
1254 return copysignf(a, copysignf(1.0, a)*copysignf(1.0, b));
1259 float builtin_fdiv (float a, float b)
1261 if (finitef(a) && finitef(b)) {
1274 float builtin_frem (float a, float b)
1277 /* return (float) builtin_drem((double) a, (double) b); */
1281 if (finite((double) a) && finite((double) b)) {
1283 if (finite((double) f))
1287 if (isnan((double) b))
1289 if (finite((double) a))
1295 if (finitef(a) && finitef(b)) {
1298 return a - floorf(f) * b;
1309 float builtin_fneg (float a)
1311 if (isnanf(a)) return a;
1313 if (finitef(a)) return -a;
1314 else return copysignf(a,-copysignf(1.0, a));
1318 s4 builtin_fcmpl (float a, float b)
1320 if (isnanf(a)) return -1;
1321 if (isnanf(b)) return -1;
1322 if (!finitef(a) || !finitef(b)) {
1323 a = finitef(a) ? 0 : copysignf(1.0, a);
1324 b = finitef(b) ? 0 : copysignf(1.0, b);
1331 s4 builtin_fcmpg (float a, float b)
1333 if (isnanf(a)) return 1;
1334 if (isnanf(b)) return 1;
1335 if (!finitef(a) || !finitef(b)) {
1336 a = finitef(a) ? 0 : copysignf(1.0, a);
1337 b = finitef(b) ? 0 : copysignf(1.0, b);
1346 /*********** Funktionen f"ur doppelt genaue Fliesskommazahlen ***************/
1348 double builtin_dadd (double a, double b)
1350 if (isnan(a)) return DBL_NAN;
1351 if (isnan(b)) return DBL_NAN;
1353 if (finite(b)) return a+b;
1357 if (finite(b)) return a;
1359 if (copysign(1.0, a)==copysign(1.0, b)) return a;
1360 else return DBL_NAN;
1365 double builtin_dsub (double a, double b)
1367 return builtin_dadd (a, builtin_dneg(b));
1370 double builtin_dmul (double a, double b)
1372 if (isnan(a)) return DBL_NAN;
1373 if (isnan(b)) return DBL_NAN;
1375 if (finite(b)) return a*b;
1377 if (a==0) return DBL_NAN;
1378 else return copysign(b, copysign(1.0, b)*a);
1383 if (b==0) return DBL_NAN;
1384 else return copysign(a, copysign(1.0, a)*b);
1387 return copysign(a, copysign(1.0, a)*copysign(1.0, b));
1392 double builtin_ddiv (double a, double b)
1394 if (finite(a) && finite(b)) {
1407 double builtin_drem (double a, double b)
1411 if (finite(a) && finite(b)) {
1414 if ((d < 1.0) && (d > 0.0))
1427 double builtin_dneg (double a)
1429 if (isnan(a)) return a;
1431 if (finite(a)) return -a;
1432 else return copysign(a,-copysign(1.0, a));
1436 s4 builtin_dcmpl (double a, double b)
1438 if (isnan(a)) return -1;
1439 if (isnan(b)) return -1;
1440 if (!finite(a) || !finite(b)) {
1441 a = finite(a) ? 0 : copysign(1.0, a);
1442 b = finite(b) ? 0 : copysign(1.0, b);
1449 s4 builtin_dcmpg (double a, double b)
1451 if (isnan(a)) return 1;
1452 if (isnan(b)) return 1;
1453 if (!finite(a) || !finite(b)) {
1454 a = finite(a) ? 0 : copysign(1.0, a);
1455 b = finite(b) ? 0 : copysign(1.0, b);
1463 /*********************** Umwandlungsoperationen ****************************/
1465 s8 builtin_i2l (s4 i)
1470 s8 v; v.high = 0; v.low=i; return v;
1474 float builtin_i2f (s4 a)
1476 float f = (float) a;
1480 double builtin_i2d (s4 a)
1482 double d = (double) a;
1487 s4 builtin_l2i (s8 l)
1496 float builtin_l2f (s8 a)
1499 float f = (float) a;
1506 double builtin_l2d (s8 a)
1509 double d = (double) a;
1517 s4 builtin_f2i(float a)
1520 return builtin_d2i((double) a);
1529 if (a < (-2147483648))
1530 return (-2147483648);
1533 f = copysignf((float) 1.0, a);
1536 return (-2147483648); */
1540 s8 builtin_f2l (float a)
1543 return builtin_d2l((double) a);
1548 if (a > 9223372036854775807L)
1549 return 9223372036854775807L;
1550 if (a < (-9223372036854775808L))
1551 return (-9223372036854775808L);
1556 f = copysignf((float) 1.0, a);
1558 return 9223372036854775807L;
1559 return (-9223372036854775808L); */
1563 double builtin_f2d (float a)
1565 if (finitef(a)) return (double) a;
1567 if (isnanf(a)) return DBL_NAN;
1568 else return copysign(DBL_POSINF, (double) copysignf(1.0, a) );
1573 s4 builtin_d2i (double a)
1578 if (a >= 2147483647)
1580 if (a <= (-2147483648))
1581 return (-2147483648);
1586 d = copysign(1.0, a);
1589 return (-2147483648);
1593 s8 builtin_d2l (double a)
1598 if (a >= 9223372036854775807L)
1599 return 9223372036854775807L;
1600 if (a <= (-9223372036854775807L-1))
1601 return (-9223372036854775807L-1);
1606 d = copysign(1.0, a);
1608 return 9223372036854775807L;
1609 return (-9223372036854775807L-1);
1613 float builtin_d2f (double a)
1615 if (finite(a)) return (float) a;
1617 if (isnan(a)) return FLT_NAN;
1618 else return copysignf (FLT_POSINF, (float) copysign(1.0, a));