1 /****************************** builtin.c **************************************
3 Copyright (c) 1997 A. Krall, R. Grafl, M. Gschwind, M. Probst
5 See file COPYRIGHT for information on usage and disclaimer of warranties
7 Enthaelt die C-Funktionen fuer alle JavaVM-Befehle, die sich nicht direkt
8 auf Maschinencode "ubersetzen lassen. Im Code f"ur die Methoden steht
9 dann ein Funktionsaufruf (nat"urlich mit den Aufrufskonventionen von C).
11 Authors: Reinhard Grafl EMAIL: cacao@complang.tuwien.ac.at
12 Andreas Krall EMAIL: cacao@complang.tuwien.ac.at
13 Mark Probst EMAIL: cacao@complang.tuwien.ac.at
15 Last Change: 1996/12/03
17 *******************************************************************************/
28 #include "threads/thread.h"
29 #include "threads/locks.h" /* schani */
31 #include "sysdep/native-math.h"
33 builtin_descriptor builtin_desc[] = {
34 {(functionptr) builtin_instanceof, "instanceof"},
35 {(functionptr) builtin_checkcast, "checkcast"},
36 {(functionptr) builtin_arrayinstanceof, "arrayinstanceof"},
37 {(functionptr) builtin_checkarraycast, "checkarraycast"},
38 {(functionptr) asm_builtin_checkarraycast, "checkarraycast"},
39 {(functionptr) asm_builtin_aastore, "aastore"},
40 {(functionptr) builtin_new, "new"},
41 {(functionptr) builtin_anewarray, "anewarray"},
42 {(functionptr) builtin_newarray_array, "newarray_array"},
43 {(functionptr) builtin_newarray_boolean, "newarray_boolean"},
44 {(functionptr) builtin_newarray_char, "newarray_char"},
45 {(functionptr) builtin_newarray_float, "newarray_float"},
46 {(functionptr) builtin_newarray_double, "newarray_double"},
47 {(functionptr) builtin_newarray_byte, "newarray_byte"},
48 {(functionptr) builtin_newarray_short, "newarray_short"},
49 {(functionptr) builtin_newarray_int, "newarray_int"},
50 {(functionptr) builtin_newarray_long, "newarray_long"},
51 {(functionptr) builtin_displaymethodstart, "displaymethodstart"},
52 {(functionptr) builtin_displaymethodstop, "displaymethodstop"},
53 {(functionptr) builtin_monitorenter, "monitorenter"},
54 {(functionptr) asm_builtin_monitorenter, "monitorenter"},
55 {(functionptr) builtin_monitorexit, "monitorexit"},
56 {(functionptr) asm_builtin_monitorexit, "monitorexit"},
57 {(functionptr) builtin_idiv, "idiv"},
58 {(functionptr) asm_builtin_idiv, "idiv"},
59 {(functionptr) builtin_irem, "irem"},
60 {(functionptr) asm_builtin_irem, "irem"},
61 {(functionptr) builtin_ladd, "ladd"},
62 {(functionptr) builtin_lsub, "lsub"},
63 {(functionptr) builtin_lmul, "lmul"},
64 {(functionptr) builtin_ldiv, "ldiv"},
65 {(functionptr) asm_builtin_ldiv, "ldiv"},
66 {(functionptr) builtin_lrem, "lrem"},
67 {(functionptr) asm_builtin_lrem, "lrem"},
68 {(functionptr) builtin_lshl, "lshl"},
69 {(functionptr) builtin_lshr, "lshr"},
70 {(functionptr) builtin_lushr, "lushr"},
71 {(functionptr) builtin_land, "land"},
72 {(functionptr) builtin_lor, "lor"},
73 {(functionptr) builtin_lxor, "lxor"},
74 {(functionptr) builtin_lneg, "lneg"},
75 {(functionptr) builtin_lcmp, "lcmp"},
76 {(functionptr) builtin_fadd, "fadd"},
77 {(functionptr) builtin_fsub, "fsub"},
78 {(functionptr) builtin_fmul, "fmul"},
79 {(functionptr) builtin_fdiv, "fdiv"},
80 {(functionptr) builtin_frem, "frem"},
81 {(functionptr) builtin_fneg, "fneg"},
82 {(functionptr) builtin_fcmpl, "fcmpl"},
83 {(functionptr) builtin_fcmpg, "fcmpg"},
84 {(functionptr) builtin_dadd, "dadd"},
85 {(functionptr) builtin_dsub, "dsub"},
86 {(functionptr) builtin_dmul, "dmul"},
87 {(functionptr) builtin_ddiv, "ddiv"},
88 {(functionptr) builtin_drem, "drem"},
89 {(functionptr) builtin_dneg, "dneg"},
90 {(functionptr) builtin_dcmpl, "dcmpl"},
91 {(functionptr) builtin_dcmpg, "dcmpg"},
92 {(functionptr) builtin_i2l, "i2l"},
93 {(functionptr) builtin_i2f, "i2f"},
94 {(functionptr) builtin_i2d, "i2d"},
95 {(functionptr) builtin_l2i, "l2i"},
96 {(functionptr) builtin_l2f, "l2f"},
97 {(functionptr) builtin_l2d, "l2d"},
98 {(functionptr) builtin_f2i, "f2i"},
99 {(functionptr) builtin_f2l, "f2l"},
100 {(functionptr) builtin_f2d, "f2d"},
101 {(functionptr) builtin_d2i, "d2i"},
102 {(functionptr) builtin_d2l, "d2l"},
103 {(functionptr) builtin_d2f, "d2f"},
104 {(functionptr) NULL, "unknown"}
108 /*****************************************************************************
110 *****************************************************************************/
114 /*************** interne Funktion: builtin_isanysubclass *********************
116 "uberpr"uft, ob eine Klasse eine Unterklasse einer anderen Klasse ist.
117 Dabei gelten auch Interfaces, die eine Klasse implementiert, als
119 R"uckgabewert: 1 ... es trifft zu
120 0 ... es trifft nicht zu
122 *****************************************************************************/
124 static s4 builtin_isanysubclass (classinfo *sub, classinfo *super)
126 if (super->flags & ACC_INTERFACE)
127 return (sub->vftbl->interfacetablelength > super->index) &&
128 (sub->vftbl->interfacetable[-super->index] != NULL);
130 return (unsigned) (sub->vftbl->baseval - super->vftbl->baseval) <=
131 (unsigned) (super->vftbl->diffval);
135 /****************** Funktion: builtin_instanceof *****************************
137 "Uberpr"uft, ob ein Objekt eine Instanz einer Klasse (oder einer davon
138 abgeleiteten Klasse) ist, oder ob die Klasse des Objekts ein Interface
141 0, wenn nicht, oder wenn Objekt ein NULL-Zeiger
143 *****************************************************************************/
145 s4 builtin_instanceof(java_objectheader *obj, classinfo *class)
148 log_text ("builtin_instanceof called");
152 return builtin_isanysubclass (obj->vftbl->class, class);
157 /**************** Funktion: builtin_checkcast *******************************
159 "Uberpr"uft, ob ein Objekt eine Instanz einer Klasse (oder einer davon
160 abgeleiteten Klasse ist).
161 Unterschied zu builtin_instanceof: Ein NULL-Zeiger ist immer richtig
162 Return: 1, wenn ja, oder wenn Objekt ein NULL-Zeiger
165 ****************************************************************************/
167 s4 builtin_checkcast(java_objectheader *obj, classinfo *class)
170 log_text ("builtin_checkcast called");
175 if (builtin_isanysubclass (obj->vftbl->class, class))
179 printf ("#### checkcast failed ");
180 unicode_display (obj->vftbl->class->name);
182 unicode_display (class->name);
190 /*********** interne Funktion: builtin_descriptorscompatible ******************
192 "uberpr"uft, ob zwei Array-Typdescriptoren compartible sind, d.h.,
193 ob ein Array vom Typ 'desc' gefahrlos einer Variblen vom Typ 'target'
194 zugewiesen werden kann.
198 ******************************************************************************/
200 static s4 builtin_descriptorscompatible
201 (constant_arraydescriptor *desc, constant_arraydescriptor *target)
203 if (desc==target) return 1;
204 if (desc->arraytype != target->arraytype) return 0;
205 switch (target->arraytype) {
206 case ARRAYTYPE_OBJECT:
207 return builtin_isanysubclass (desc->objectclass, target->objectclass);
208 case ARRAYTYPE_ARRAY:
209 return builtin_descriptorscompatible
210 (desc->elementdescriptor, target->elementdescriptor);
217 /******************** Funktion: builtin_checkarraycast ***********************
219 "uberpr"uft, ob ein gegebenes Objekt tats"achlich von einem
220 Untertyp des geforderten Arraytyps ist.
221 Dazu muss das Objekt auf jeden Fall ein Array sein.
222 Bei einfachen Arrays (int,short,double,etc.) muss der Typ genau
224 Bei Arrays von Objekten muss der Elementtyp des tats"achlichen Arrays
225 ein Untertyp (oder der selbe Typ) vom geforderten Elementtyp sein.
226 Bei Arrays vom Arrays (die eventuell wieder Arrays von Arrays
227 sein k"onnen) m"ussen die untersten Elementtypen in der entsprechenden
228 Unterklassenrelation stehen.
230 Return: 1, wenn Cast in Ordung ist
231 0, wenn es nicht geht
233 Achtung: ein Cast mit einem NULL-Zeiger geht immer gut.
235 *****************************************************************************/
237 s4 builtin_checkarraycast(java_objectheader *o, constant_arraydescriptor *desc)
239 java_arrayheader *a = (java_arrayheader*) o;
242 if (o->vftbl->class != class_array) {
246 if (a->arraytype != desc->arraytype) {
250 switch (a->arraytype) {
251 case ARRAYTYPE_OBJECT: {
252 java_objectarray *oa = (java_objectarray*) o;
253 return builtin_isanysubclass (oa->elementtype, desc->objectclass);
255 case ARRAYTYPE_ARRAY: {
256 java_arrayarray *aa = (java_arrayarray*) o;
257 return builtin_descriptorscompatible
258 (aa->elementdescriptor, desc->elementdescriptor);
266 s4 builtin_arrayinstanceof
267 (java_objectheader *obj, constant_arraydescriptor *desc)
270 return builtin_checkarraycast (obj, desc);
274 /************************** exception functions *******************************
276 ******************************************************************************/
278 java_objectheader *builtin_throw_exception (java_objectheader *exceptionptr) {
279 unicode_display (exceptionptr->vftbl->class->name);
286 /******************* Funktion: builtin_canstore *******************************
288 "uberpr"uft, ob ein Objekt in einem Array gespeichert werden
290 Return: 1, wenn es geht
293 ******************************************************************************/
296 s4 builtin_canstore (java_objectarray *a, java_objectheader *o)
300 switch (a->header.arraytype) {
301 case ARRAYTYPE_OBJECT:
302 if ( ! builtin_checkcast (o, a->elementtype) ) {
308 case ARRAYTYPE_ARRAY:
309 if ( ! builtin_checkarraycast
310 (o, ((java_arrayarray*)a)->elementdescriptor) ) {
317 panic ("builtin_canstore called with invalid arraytype");
324 /*****************************************************************************
326 *****************************************************************************/
330 /******************** Funktion: builtin_new **********************************
332 Legt ein neues Objekt einer Klasse am Heap an.
333 Return: Der Zeiger auf das Objekt, oder NULL, wenn kein Speicher
336 *****************************************************************************/
338 java_objectheader *builtin_new (classinfo *c)
340 java_objectheader *o;
342 o = heap_allocate ( c->instancesize, true, c->finalizer );
345 memset (o, 0, c->instancesize);
347 o -> vftbl = c -> vftbl;
353 /******************** Funktion: builtin_anewarray ****************************
355 Legt ein Array von Zeigern auf Objekte am Heap an.
357 size ......... Anzahl der Elemente
358 elementtype .. ein Zeiger auf die classinfo-Struktur des Typs
361 Return: Zeiger auf das Array, oder NULL (wenn kein Speicher frei)
363 *****************************************************************************/
365 java_objectarray *builtin_anewarray (s4 size, classinfo *elementtype)
370 a = heap_allocate ( sizeof(java_objectarray) + (size-1) * sizeof(void*),
371 true, 0 /* FALSE */ );
374 a -> header.objheader.vftbl = class_array -> vftbl;
375 a -> header.size = size;
376 a -> header.arraytype = ARRAYTYPE_OBJECT;
377 a -> elementtype = elementtype;
378 for (i=0; i<size; i++) a->data[i] = NULL;
384 /******************** Funktion: builtin_newarray_array ***********************
386 Legt ein Array von Zeigern auf Arrays am Heap an.
387 Paramter: size ......... Anzahl der Elemente
388 elementdesc .. Zeiger auf die Arraybeschreibungs-Struktur f"ur
391 Return: Zeiger auf das Array, oder NULL
393 *****************************************************************************/
395 java_arrayarray *builtin_newarray_array
396 (s4 size, constant_arraydescriptor *elementdesc)
401 a = heap_allocate ( sizeof(java_arrayarray) + (size-1) * sizeof(void*),
405 a -> header.objheader.vftbl = class_array -> vftbl;
406 a -> header.size = size;
407 a -> header.arraytype = ARRAYTYPE_ARRAY;
408 a -> elementdescriptor = elementdesc;
409 for (i=0; i<size; i++) a->data[i] = NULL;
414 /******************** Funktion: builtin_newarray_boolean ************************
416 Legt ein Array von Bytes am Heap an, das allerdings als Boolean-Array
417 gekennzeichnet wird (wichtig bei Casts!)
419 Return: Zeiger auf das Array, oder NULL
421 *****************************************************************************/
423 java_booleanarray *builtin_newarray_boolean (s4 size)
425 java_booleanarray *a;
427 a = heap_allocate ( sizeof(java_booleanarray) + (size-1) * sizeof(u1),
431 a -> header.objheader.vftbl = class_array -> vftbl;
432 a -> header.size = size;
433 a -> header.arraytype = ARRAYTYPE_BOOLEAN;
434 memset (a->data, 0, sizeof(u1) * size);
439 /******************** Funktion: builtin_newarray_char ************************
441 Legt ein Array von 16-bit-Integers am Heap an.
442 Return: Zeiger auf das Array, oder NULL
444 *****************************************************************************/
446 java_chararray *builtin_newarray_char (s4 size)
450 a = heap_allocate ( sizeof(java_chararray) + (size-1) * sizeof(u2),
454 a -> header.objheader.vftbl = class_array -> vftbl;
455 a -> header.size = size;
456 a -> header.arraytype = ARRAYTYPE_CHAR;
457 memset (a->data, 0, sizeof(u2) * size);
463 /******************** Funktion: builtin_newarray_float ***********************
465 Legt ein Array von 32-bit-IEEE-float am Heap an.
466 Return: Zeiger auf das Array, oder NULL
468 *****************************************************************************/
470 java_floatarray *builtin_newarray_float (s4 size)
475 a = heap_allocate ( sizeof(java_floatarray) + (size-1) * sizeof(float),
479 a -> header.objheader.vftbl = class_array -> vftbl;
480 a -> header.size = size;
481 a -> header.arraytype = ARRAYTYPE_FLOAT;
482 for (i=0; i<size; i++) a->data[i] = 0.0;
487 /******************** Funktion: builtin_newarray_double ***********************
489 Legt ein Array von 64-bit-IEEE-float am Heap an.
490 Return: Zeiger auf das Array, oder NULL
492 *****************************************************************************/
494 java_doublearray *builtin_newarray_double (s4 size)
499 a = heap_allocate ( sizeof(java_doublearray) + (size-1) * sizeof(double),
503 a -> header.objheader.vftbl = class_array -> vftbl;
504 a -> header.size = size;
505 a -> header.arraytype = ARRAYTYPE_DOUBLE;
506 for (i=0; i<size; i++) a->data[i] = 0.0;
513 /******************** Funktion: builtin_newarray_byte ***********************
515 Legt ein Array von 8-bit-Integers am Heap an.
516 Return: Zeiger auf das Array, oder NULL
518 *****************************************************************************/
520 java_bytearray *builtin_newarray_byte (s4 size)
524 a = heap_allocate ( sizeof(java_bytearray) + (size-1) * sizeof(s1),
528 a -> header.objheader.vftbl = class_array->vftbl;
529 a -> header.size = size;
530 a -> header.arraytype = ARRAYTYPE_BYTE;
531 memset (a->data, 0, sizeof(u1) * size);
536 /******************** Funktion: builtin_newarray_short ***********************
538 Legt ein Array von 16-bit-Integers am Heap an.
539 Return: Zeiger auf das Array, oder NULL
541 *****************************************************************************/
543 java_shortarray *builtin_newarray_short (s4 size)
547 a = heap_allocate ( sizeof(java_shortarray) + (size-1) * sizeof(s2),
551 a -> header.objheader.vftbl = class_array -> vftbl;
552 a -> header.size = size;
553 a -> header.arraytype = ARRAYTYPE_SHORT;
554 memset (a->data, 0, sizeof(s2) * size);
559 /******************** Funktion: builtin_newarray_int ***********************
561 Legt ein Array von 32-bit-Integers am Heap an.
562 Return: Zeiger auf das Array, oder NULL
564 *****************************************************************************/
566 java_intarray *builtin_newarray_int (s4 size)
570 a = heap_allocate ( sizeof(java_intarray) + (size-1) * sizeof(s4),
574 a -> header.objheader.vftbl = class_array -> vftbl;
575 a -> header.size = size;
576 a -> header.arraytype = ARRAYTYPE_INT;
577 memset (a->data, 0, sizeof(s4) * size);
582 /******************** Funktion: builtin_newarray_long ***********************
584 Legt ein Array von 64-bit-Integers am Heap an.
585 Return: Zeiger auf das Array, oder NULL
587 *****************************************************************************/
589 java_longarray *builtin_newarray_long (s4 size)
593 a = heap_allocate ( sizeof(java_longarray) + (size-1) * sizeof(s8),
597 a -> header.objheader.vftbl = class_array -> vftbl;
598 a -> header.size = size;
599 a -> header.arraytype = ARRAYTYPE_LONG;
600 memset (a->data, 0, sizeof(s8) * size);
606 /***************** Funktion: builtin_multianewarray ***************************
608 Legt ein mehrdimensionales Array am Heap an.
609 Die Gr"ossen der einzelnen Dimensionen werden in einem Integerarray
610 "ubergeben. Der Typ es zu erzeugenden Arrays wird als
611 Referenz auf eine constant_arraydescriptor - Struktur "ubergeben.
613 Return: Ein Zeiger auf das Array, oder NULL, wenn kein Speicher mehr
616 ******************************************************************************/
620 static java_arrayheader *multianewarray_part (java_intarray *dims, int thisdim,
621 constant_arraydescriptor *desc)
626 size = dims -> data[thisdim];
628 if (thisdim == (dims->header.size-1)) {
629 /* letzte Dimension schon erreicht */
631 switch (desc -> arraytype) {
632 case ARRAYTYPE_BOOLEAN:
633 return (java_arrayheader*) builtin_newarray_boolean (size);
635 return (java_arrayheader*) builtin_newarray_char (size);
636 case ARRAYTYPE_FLOAT:
637 return (java_arrayheader*) builtin_newarray_float (size);
638 case ARRAYTYPE_DOUBLE:
639 return (java_arrayheader*) builtin_newarray_double (size);
641 return (java_arrayheader*) builtin_newarray_byte (size);
642 case ARRAYTYPE_SHORT:
643 return (java_arrayheader*) builtin_newarray_short (size);
645 return (java_arrayheader*) builtin_newarray_int (size);
647 return (java_arrayheader*) builtin_newarray_long (size);
648 case ARRAYTYPE_OBJECT:
649 return (java_arrayheader*) builtin_anewarray (size, desc->objectclass);
651 case ARRAYTYPE_ARRAY:
652 return (java_arrayheader*) builtin_newarray_array (size, desc->elementdescriptor);
654 default: panic ("Invalid arraytype in multianewarray");
658 /* wenn letzte Dimension noch nicht erreicht wurde */
660 if (desc->arraytype != ARRAYTYPE_ARRAY)
661 panic ("multianewarray with too many dimensions");
663 a = builtin_newarray_array (size, desc->elementdescriptor);
666 for (i=0; i<size; i++) {
667 java_arrayheader *ea =
668 multianewarray_part (dims, thisdim+1, desc->elementdescriptor);
669 if (!ea) return NULL;
674 return (java_arrayheader*) a;
678 java_arrayheader *builtin_multianewarray (java_intarray *dims,
679 constant_arraydescriptor *desc)
681 return multianewarray_part (dims, 0, desc);
685 static java_arrayheader *nmultianewarray_part (int n, long *dims, int thisdim,
686 constant_arraydescriptor *desc)
691 size = (int) dims[thisdim];
693 if (thisdim == (n - 1)) {
694 /* letzte Dimension schon erreicht */
696 switch (desc -> arraytype) {
697 case ARRAYTYPE_BOOLEAN:
698 return (java_arrayheader*) builtin_newarray_boolean(size);
700 return (java_arrayheader*) builtin_newarray_char(size);
701 case ARRAYTYPE_FLOAT:
702 return (java_arrayheader*) builtin_newarray_float(size);
703 case ARRAYTYPE_DOUBLE:
704 return (java_arrayheader*) builtin_newarray_double(size);
706 return (java_arrayheader*) builtin_newarray_byte(size);
707 case ARRAYTYPE_SHORT:
708 return (java_arrayheader*) builtin_newarray_short(size);
710 return (java_arrayheader*) builtin_newarray_int(size);
712 return (java_arrayheader*) builtin_newarray_long(size);
713 case ARRAYTYPE_OBJECT:
714 return (java_arrayheader*) builtin_anewarray(size,
716 case ARRAYTYPE_ARRAY:
717 return (java_arrayheader*) builtin_newarray_array(size,
718 desc->elementdescriptor);
720 default: panic ("Invalid arraytype in multianewarray");
724 /* wenn letzte Dimension noch nicht erreicht wurde */
726 if (desc->arraytype != ARRAYTYPE_ARRAY)
727 panic ("multianewarray with too many dimensions");
729 a = builtin_newarray_array(size, desc->elementdescriptor);
732 for (i = 0; i < size; i++) {
733 java_arrayheader *ea =
734 nmultianewarray_part(n, dims, thisdim + 1, desc->elementdescriptor);
735 if (!ea) return NULL;
740 return (java_arrayheader*) a;
744 java_arrayheader *builtin_nmultianewarray (int size,
745 constant_arraydescriptor *desc, long *dims)
747 (void) builtin_newarray_int(size); /* for compatibility with -old */
748 return nmultianewarray_part (size, dims, 0, desc);
754 /************************* Funktion: builtin_aastore *************************
756 speichert eine Referenz auf ein Objekt in einem Object-Array oder
757 in einem Array-Array.
758 Dabei wird allerdings vorher "uberpr"uft, ob diese Operation
761 Return: 1, wenn alles OK ist
762 0, wenn dieses Objekt nicht in dieses Array gespeichert werden
765 *****************************************************************************/
767 s4 builtin_aastore (java_objectarray *a, s4 index, java_objectheader *o)
769 if (builtin_canstore(a,o)) {
781 /*****************************************************************************
782 METHODEN-PROTOKOLLIERUNG
784 Verschiedene Funktionen, mit denen eine Meldung ausgegeben werden
785 kann, wann immer Methoden aufgerufen oder beendet werden.
788 *****************************************************************************/
793 java_objectheader *builtin_trace_exception (java_objectheader *exceptionptr,
794 methodinfo *method, int *pos, int noindent) {
798 if (verbose || runverbose) {
799 printf("Exception ");
800 unicode_display (exceptionptr->vftbl->class->name);
801 printf(" thrown in ");
803 unicode_display (method->class->name);
805 unicode_display (method->name);
806 if (method->flags & ACC_SYNCHRONIZED)
810 printf("(%p) at position %p\n", method->entrypoint, pos);
813 printf("call_java_method\n");
820 void builtin_trace_args(long a0, long a1, long a2, long a3, long a4, long a5,
823 sprintf (logtext, " ");
824 sprintf (logtext+methodindent, "called: ");
825 unicode_sprint (logtext+strlen(logtext), method->class->name);
826 sprintf (logtext+strlen(logtext), ".");
827 unicode_sprint (logtext+strlen(logtext), method->name);
828 unicode_sprint (logtext+strlen(logtext), method->descriptor);
829 sprintf (logtext+strlen(logtext), "(");
830 switch (method->paramcount) {
832 sprintf(logtext+strlen(logtext), "%lx, %lx, %lx, %lx, %lx, %lx",
833 a0, a1, a2, a3, a4, a5);
836 sprintf(logtext+strlen(logtext), "%lx, %lx, %lx, %lx, %lx",
840 sprintf(logtext+strlen(logtext), "%lx, %lx, %lx, %lx",
844 sprintf(logtext+strlen(logtext), "%lx, %lx, %lx", a0, a1, a2);
847 sprintf(logtext+strlen(logtext), "%lx, %lx", a0, a1);
850 sprintf(logtext+strlen(logtext), "%lx", a0);
853 sprintf (logtext+strlen(logtext), ")");
859 void builtin_displaymethodstart(methodinfo *method)
861 sprintf (logtext, " ");
862 sprintf (logtext+methodindent, "called: ");
863 unicode_sprint (logtext+strlen(logtext), method->class->name);
864 sprintf (logtext+strlen(logtext), ".");
865 unicode_sprint (logtext+strlen(logtext), method->name);
866 unicode_sprint (logtext+strlen(logtext), method->descriptor);
871 void builtin_displaymethodstop(methodinfo *method, long l, double d)
874 sprintf (logtext, " ");
875 sprintf (logtext+methodindent, "finished: ");
876 unicode_sprint (logtext+strlen(logtext), method->class->name);
877 sprintf (logtext+strlen(logtext), ".");
878 unicode_sprint (logtext+strlen(logtext), method->name);
879 unicode_sprint (logtext+strlen(logtext), method->descriptor);
880 switch (method->returntype) {
883 sprintf (logtext+strlen(logtext), "->%ld", l);
887 sprintf (logtext+strlen(logtext), "->%g", d);
890 sprintf (logtext+strlen(logtext), "->%p", (void*) l);
896 void builtin_displaymethodexception(methodinfo *method)
898 sprintf (logtext, " ");
899 sprintf (logtext+methodindent, "exception abort: ");
900 unicode_sprint (logtext+strlen(logtext), method->class->name);
901 sprintf (logtext+strlen(logtext), ".");
902 unicode_sprint (logtext+strlen(logtext), method->name);
903 unicode_sprint (logtext+strlen(logtext), method->descriptor);
908 /****************************************************************************
909 SYNCHRONIZATION FUNCTIONS
910 *****************************************************************************/
913 * Lock the mutex of an object.
917 internal_lock_mutex_for_object (java_objectheader *object)
919 mutexHashEntry *entry;
924 hashValue = MUTEX_HASH_VALUE(object);
925 entry = &mutexHashTable[hashValue];
927 if (entry->object != 0)
929 if (entry->mutex.count == 0 && entry->conditionCount == 0)
932 entry->mutex.holder = 0;
933 entry->mutex.count = 0;
934 entry->mutex.muxWaiters = 0;
938 while (entry->next != 0 && entry->object != object)
941 if (entry->object != object)
943 entry->next = firstFreeOverflowEntry;
944 firstFreeOverflowEntry = firstFreeOverflowEntry->next;
949 assert(entry->conditionCount == 0);
955 entry->mutex.holder = 0;
956 entry->mutex.count = 0;
957 entry->mutex.muxWaiters = 0;
960 if (entry->object == 0)
961 entry->object = object;
963 internal_lock_mutex(&entry->mutex);
969 * Unlocks the mutex of an object.
973 internal_unlock_mutex_for_object (java_objectheader *object)
976 mutexHashEntry *entry;
978 hashValue = MUTEX_HASH_VALUE(object);
979 entry = &mutexHashTable[hashValue];
981 if (entry->object == object)
982 internal_unlock_mutex(&entry->mutex);
985 while (entry->next != 0 && entry->next->object != object)
988 assert(entry->next != 0);
990 internal_unlock_mutex(&entry->next->mutex);
992 if (entry->next->mutex.count == 0 && entry->conditionCount == 0)
994 mutexHashEntry *unlinked = entry->next;
996 entry->next = unlinked->next;
997 unlinked->next = firstFreeOverflowEntry;
998 firstFreeOverflowEntry = unlinked;
1005 builtin_monitorenter (java_objectheader *o)
1010 assert(blockInts == 0);
1014 hashValue = MUTEX_HASH_VALUE(o);
1015 if (mutexHashTable[hashValue].object == o
1016 && mutexHashTable[hashValue].mutex.holder == currentThread)
1017 ++mutexHashTable[hashValue].mutex.count;
1019 internal_lock_mutex_for_object(o);
1023 assert(blockInts == 0);
1027 void builtin_monitorexit (java_objectheader *o)
1032 assert(blockInts == 0);
1036 hashValue = MUTEX_HASH_VALUE(o);
1037 if (mutexHashTable[hashValue].object == o)
1039 if (mutexHashTable[hashValue].mutex.count == 1
1040 && mutexHashTable[hashValue].mutex.muxWaiters != 0)
1041 internal_unlock_mutex_for_object(o);
1043 --mutexHashTable[hashValue].mutex.count;
1046 internal_unlock_mutex_for_object(o);
1050 assert(blockInts == 0);
1055 /*****************************************************************************
1056 DIVERSE HILFSFUNKTIONEN
1057 *****************************************************************************/
1061 /*********** Funktionen f"ur die Integerdivision *****************************
1063 Auf manchen Systemen (z.B. DEC ALPHA) wird durch die CPU keine Integer-
1064 division unterst"utzt.
1065 Daf"ur gibt es dann diese Hilfsfunktionen
1067 ******************************************************************************/
1069 s4 builtin_idiv (s4 a, s4 b) { return a/b; }
1070 s4 builtin_irem (s4 a, s4 b) { return a%b; }
1073 /************** Funktionen f"ur Long-Arithmetik *******************************
1075 Auf Systemen, auf denen die CPU keine 64-Bit-Integers unterst"utzt,
1076 werden diese Funktionen gebraucht
1078 ******************************************************************************/
1081 s8 builtin_ladd (s8 a, s8 b)
1086 return builtin_i2l(0);
1090 s8 builtin_lsub (s8 a, s8 b)
1095 return builtin_i2l(0);
1099 s8 builtin_lmul (s8 a, s8 b)
1104 return builtin_i2l(0);
1108 s8 builtin_ldiv (s8 a, s8 b)
1113 return builtin_i2l(0);
1117 s8 builtin_lrem (s8 a, s8 b)
1122 return builtin_i2l(0);
1126 s8 builtin_lshl (s8 a, s4 b)
1131 return builtin_i2l(0);
1135 s8 builtin_lshr (s8 a, s4 b)
1140 return builtin_i2l(0);
1144 s8 builtin_lushr (s8 a, s4 b)
1147 return ((u8)a)>>(b&63);
1149 return builtin_i2l(0);
1153 s8 builtin_land (s8 a, s8 b)
1158 return builtin_i2l(0);
1162 s8 builtin_lor (s8 a, s8 b)
1167 return builtin_i2l(0);
1171 s8 builtin_lxor (s8 a, s8 b)
1176 return builtin_i2l(0);
1180 s8 builtin_lneg (s8 a)
1185 return builtin_i2l(0);
1189 s4 builtin_lcmp (s8 a, s8 b)
1204 /*********** Funktionen f"ur die Floating-Point-Operationen ******************/
1206 float builtin_fadd (float a, float b)
1208 if (isnanf(a)) return FLT_NAN;
1209 if (isnanf(b)) return FLT_NAN;
1211 if (finitef(b)) return a+b;
1215 if (finitef(b)) return a;
1217 if (copysignf(1.0, a)==copysignf(1.0, b)) return a;
1218 else return FLT_NAN;
1223 float builtin_fsub (float a, float b)
1225 return builtin_fadd (a, builtin_fneg(b));
1228 float builtin_fmul (float a, float b)
1230 if (isnanf(a)) return FLT_NAN;
1231 if (isnanf(b)) return FLT_NAN;
1233 if (finitef(b)) return a*b;
1235 if (a==0) return FLT_NAN;
1236 else return copysignf(b, copysignf(1.0, b)*a);
1241 if (b==0) return FLT_NAN;
1242 else return copysignf(a, copysignf(1.0, a)*b);
1245 return copysignf(a, copysignf(1.0, a)*copysignf(1.0, b));
1250 float builtin_fdiv (float a, float b)
1252 if (finitef(a) && finitef(b)) {
1265 float builtin_frem (float a, float b)
1268 /* return (float) builtin_drem((double) a, (double) b); */
1272 if (finite((double) a) && finite((double) b)) {
1274 if (finite((double) f))
1278 if (isnan((double) b))
1280 if (finite((double) a))
1286 if (finitef(a) && finitef(b)) {
1289 return a - floorf(f) * b;
1300 float builtin_fneg (float a)
1302 if (isnanf(a)) return a;
1304 if (finitef(a)) return -a;
1305 else return copysignf(a,-copysignf(1.0, a));
1309 s4 builtin_fcmpl (float a, float b)
1311 if (isnanf(a)) return -1;
1312 if (isnanf(b)) return -1;
1313 if (!finitef(a) || !finitef(b)) {
1314 a = finitef(a) ? 0 : copysignf(1.0, a);
1315 b = finitef(b) ? 0 : copysignf(1.0, b);
1322 s4 builtin_fcmpg (float a, float b)
1324 if (isnanf(a)) return 1;
1325 if (isnanf(b)) return 1;
1326 if (!finitef(a) || !finitef(b)) {
1327 a = finitef(a) ? 0 : copysignf(1.0, a);
1328 b = finitef(b) ? 0 : copysignf(1.0, b);
1337 /*********** Funktionen f"ur doppelt genaue Fliesskommazahlen ***************/
1339 double builtin_dadd (double a, double b)
1341 if (isnan(a)) return DBL_NAN;
1342 if (isnan(b)) return DBL_NAN;
1344 if (finite(b)) return a+b;
1348 if (finite(b)) return a;
1350 if (copysign(1.0, a)==copysign(1.0, b)) return a;
1351 else return DBL_NAN;
1356 double builtin_dsub (double a, double b)
1358 return builtin_dadd (a, builtin_dneg(b));
1361 double builtin_dmul (double a, double b)
1363 if (isnan(a)) return DBL_NAN;
1364 if (isnan(b)) return DBL_NAN;
1366 if (finite(b)) return a*b;
1368 if (a==0) return DBL_NAN;
1369 else return copysign(b, copysign(1.0, b)*a);
1374 if (b==0) return DBL_NAN;
1375 else return copysign(a, copysign(1.0, a)*b);
1378 return copysign(a, copysign(1.0, a)*copysign(1.0, b));
1383 double builtin_ddiv (double a, double b)
1385 if (finite(a) && finite(b)) {
1398 double builtin_drem (double a, double b)
1402 if (finite(a) && finite(b)) {
1405 if ((d < 1.0) && (d > 0.0))
1418 double builtin_dneg (double a)
1420 if (isnan(a)) return a;
1422 if (finite(a)) return -a;
1423 else return copysign(a,-copysign(1.0, a));
1427 s4 builtin_dcmpl (double a, double b)
1429 if (isnan(a)) return -1;
1430 if (isnan(b)) return -1;
1431 if (!finite(a) || !finite(b)) {
1432 a = finite(a) ? 0 : copysign(1.0, a);
1433 b = finite(b) ? 0 : copysign(1.0, b);
1440 s4 builtin_dcmpg (double a, double b)
1442 if (isnan(a)) return 1;
1443 if (isnan(b)) return 1;
1444 if (!finite(a) || !finite(b)) {
1445 a = finite(a) ? 0 : copysign(1.0, a);
1446 b = finite(b) ? 0 : copysign(1.0, b);
1454 /*********************** Umwandlungsoperationen ****************************/
1456 s8 builtin_i2l (s4 i)
1461 s8 v; v.high = 0; v.low=i; return v;
1465 float builtin_i2f (s4 a)
1467 float f = (float) a;
1471 double builtin_i2d (s4 a)
1473 double d = (double) a;
1478 s4 builtin_l2i (s8 l)
1487 float builtin_l2f (s8 a)
1490 float f = (float) a;
1497 double builtin_l2d (s8 a)
1500 double d = (double) a;
1508 s4 builtin_f2i(float a)
1511 return builtin_d2i((double) a);
1520 if (a < (-2147483648))
1521 return (-2147483648);
1524 f = copysignf((float) 1.0, a);
1527 return (-2147483648); */
1531 s8 builtin_f2l (float a)
1534 return builtin_d2l((double) a);
1539 if (a > 9223372036854775807L)
1540 return 9223372036854775807L;
1541 if (a < (-9223372036854775808L))
1542 return (-9223372036854775808L);
1547 f = copysignf((float) 1.0, a);
1549 return 9223372036854775807L;
1550 return (-9223372036854775808L); */
1554 double builtin_f2d (float a)
1556 if (finitef(a)) return (double) a;
1558 if (isnanf(a)) return DBL_NAN;
1559 else return copysign(DBL_POSINF, (double) copysignf(1.0, a) );
1564 s4 builtin_d2i (double a)
1569 if (a >= 2147483647)
1571 if (a <= (-2147483648))
1572 return (-2147483648);
1577 d = copysign(1.0, a);
1580 return (-2147483648);
1584 s8 builtin_d2l (double a)
1589 if (a >= 9223372036854775807L)
1590 return 9223372036854775807L;
1591 if (a <= (-9223372036854775807L-1))
1592 return (-9223372036854775807L-1);
1597 d = copysign(1.0, a);
1599 return 9223372036854775807L;
1600 return (-9223372036854775807L-1);
1604 float builtin_d2f (double a)
1606 if (finite(a)) return (float) a;
1608 if (isnan(a)) return FLT_NAN;
1609 else return copysignf (FLT_POSINF, (float) copysign(1.0, a));
1615 * These are local overrides for various environment variables in Emacs.
1616 * Please do not remove this and leave it at the end of the file, where
1617 * Emacs will automagically detect them.
1618 * ---------------------------------------------------------------------
1621 * indent-tabs-mode: t