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) new_builtin_checkclasscast, "checkclasscast"},
39 {(functionptr) new_builtin_checkintercast, "checkintercast"},
40 {(functionptr) builtin_arrayinstanceof, "arrayinstanceof"},
41 {(functionptr) builtin_checkarraycast, "checkarraycast"},
42 {(functionptr) new_builtin_checkarraycast, "checkarraycast"},
43 {(functionptr) new_builtin_aastore, "aastore"},
44 {(functionptr) builtin_new, "new"},
45 {(functionptr) builtin_anewarray, "anewarray"},
46 {(functionptr) builtin_newarray_array, "newarray_array"},
47 {(functionptr) builtin_newarray_boolean, "newarray_boolean"},
48 {(functionptr) builtin_newarray_char, "newarray_char"},
49 {(functionptr) builtin_newarray_float, "newarray_float"},
50 {(functionptr) builtin_newarray_double, "newarray_double"},
51 {(functionptr) builtin_newarray_byte, "newarray_byte"},
52 {(functionptr) builtin_newarray_short, "newarray_short"},
53 {(functionptr) builtin_newarray_int, "newarray_int"},
54 {(functionptr) builtin_newarray_long, "newarray_long"},
55 {(functionptr) builtin_displaymethodstart, "displaymethodstart"},
56 {(functionptr) builtin_displaymethodstop, "displaymethodstop"},
57 {(functionptr) builtin_monitorenter, "monitorenter"},
58 {(functionptr) new_builtin_monitorenter, "monitorenter"},
59 {(functionptr) builtin_monitorexit, "monitorexit"},
60 {(functionptr) new_builtin_monitorexit, "monitorexit"},
61 {(functionptr) builtin_idiv, "idiv"},
62 {(functionptr) new_builtin_idiv, "idiv"},
63 {(functionptr) builtin_irem, "irem"},
64 {(functionptr) new_builtin_irem, "irem"},
65 {(functionptr) builtin_ladd, "ladd"},
66 {(functionptr) builtin_lsub, "lsub"},
67 {(functionptr) builtin_lmul, "lmul"},
68 {(functionptr) builtin_ldiv, "ldiv"},
69 {(functionptr) new_builtin_ldiv, "ldiv"},
70 {(functionptr) builtin_lrem, "lrem"},
71 {(functionptr) new_builtin_lrem, "lrem"},
72 {(functionptr) builtin_lshl, "lshl"},
73 {(functionptr) builtin_lshr, "lshr"},
74 {(functionptr) builtin_lushr, "lushr"},
75 {(functionptr) builtin_land, "land"},
76 {(functionptr) builtin_lor, "lor"},
77 {(functionptr) builtin_lxor, "lxor"},
78 {(functionptr) builtin_lneg, "lneg"},
79 {(functionptr) builtin_lcmp, "lcmp"},
80 {(functionptr) builtin_fadd, "fadd"},
81 {(functionptr) builtin_fsub, "fsub"},
82 {(functionptr) builtin_fmul, "fmul"},
83 {(functionptr) builtin_fdiv, "fdiv"},
84 {(functionptr) builtin_frem, "frem"},
85 {(functionptr) builtin_fneg, "fneg"},
86 {(functionptr) builtin_fcmpl, "fcmpl"},
87 {(functionptr) builtin_fcmpg, "fcmpg"},
88 {(functionptr) builtin_dadd, "dadd"},
89 {(functionptr) builtin_dsub, "dsub"},
90 {(functionptr) builtin_dmul, "dmul"},
91 {(functionptr) builtin_ddiv, "ddiv"},
92 {(functionptr) builtin_drem, "drem"},
93 {(functionptr) builtin_dneg, "dneg"},
94 {(functionptr) builtin_dcmpl, "dcmpl"},
95 {(functionptr) builtin_dcmpg, "dcmpg"},
96 {(functionptr) builtin_i2l, "i2l"},
97 {(functionptr) builtin_i2f, "i2f"},
98 {(functionptr) builtin_i2d, "i2d"},
99 {(functionptr) builtin_l2i, "l2i"},
100 {(functionptr) builtin_l2f, "l2f"},
101 {(functionptr) builtin_l2d, "l2d"},
102 {(functionptr) builtin_f2i, "f2i"},
103 {(functionptr) builtin_f2l, "f2l"},
104 {(functionptr) builtin_f2d, "f2d"},
105 {(functionptr) builtin_d2i, "d2i"},
106 {(functionptr) builtin_d2l, "d2l"},
107 {(functionptr) builtin_d2f, "d2f"},
108 {(functionptr) NULL, "unknown"}
112 /*****************************************************************************
114 *****************************************************************************/
118 /*************** interne Funktion: builtin_isanysubclass *********************
120 "uberpr"uft, ob eine Klasse eine Unterklasse einer anderen Klasse ist.
121 Dabei gelten auch Interfaces, die eine Klasse implementiert, als
123 R"uckgabewert: 1 ... es trifft zu
124 0 ... es trifft nicht zu
126 *****************************************************************************/
128 static s4 builtin_isanysubclass (classinfo *sub, classinfo *super)
130 if (super->flags & ACC_INTERFACE) {
131 s4 index = super->index;
132 if (index >= sub->vftbl->interfacetablelength) return 0;
133 return ( sub->vftbl->interfacevftbl[index] ) ? 1 : 0;
135 return (sub->vftbl->lowclassval >= super->vftbl->lowclassval) &
136 (sub->vftbl->lowclassval <= super->vftbl->highclassval);
140 /****************** Funktion: builtin_instanceof *****************************
142 "Uberpr"uft, ob ein Objekt eine Instanz einer Klasse (oder einer davon
143 abgeleiteten Klasse) ist, oder ob die Klasse des Objekts ein Interface
146 0, wenn nicht, oder wenn Objekt ein NULL-Zeiger
148 *****************************************************************************/
150 s4 builtin_instanceof(java_objectheader *obj, classinfo *class)
153 log_text ("builtin_instanceof called");
157 return builtin_isanysubclass (obj->vftbl->class, class);
162 /**************** Funktion: builtin_checkcast *******************************
164 "Uberpr"uft, ob ein Objekt eine Instanz einer Klasse (oder einer davon
165 abgeleiteten Klasse ist).
166 Unterschied zu builtin_instanceof: Ein NULL-Zeiger ist immer richtig
167 Return: 1, wenn ja, oder wenn Objekt ein NULL-Zeiger
170 ****************************************************************************/
172 s4 builtin_checkcast(java_objectheader *obj, classinfo *class)
175 log_text ("builtin_checkcast called");
179 if ( builtin_isanysubclass (obj->vftbl->class, class) ) {
183 printf ("#### checkcast failed ");
184 unicode_display (obj->vftbl->class->name);
186 unicode_display (class->name);
194 /***************** function: builtin_checkclasscast ****************************
196 Returns 1 (true) if the object "sub" is a subclass of the class "super",
197 otherwise returns 0 (false). If sub is NULL it also returns 1 (true).
199 *******************************************************************************/
201 s4 builtin_checkclasscast(java_objectheader *sub, classinfo *super)
206 return (sub->vftbl->lowclassval >= super->vftbl->lowclassval) &
207 (sub->vftbl->lowclassval <= super->vftbl->highclassval);
211 /***************** function: builtin_checkintercast ****************************
213 Returns 1 (true) if the object "sub" is a subclass of the interface "super",
214 otherwise returns 0 (false). If "sub" is NULL it also returns 1 (true).
216 *******************************************************************************/
218 s4 builtin_checkintercast(java_objectheader *sub, classinfo *super)
223 return (sub->vftbl->interfacetablelength > super->index) &&
224 (sub->vftbl->interfacevftbl[super->index] != NULL);
229 /*********** interne Funktion: builtin_descriptorscompatible ******************
231 "uberpr"uft, ob zwei Array-Typdescriptoren compartible sind, d.h.,
232 ob ein Array vom Typ 'desc' gefahrlos einer Variblen vom Typ 'target'
233 zugewiesen werden kann.
237 ******************************************************************************/
239 static s4 builtin_descriptorscompatible
240 (constant_arraydescriptor *desc, constant_arraydescriptor *target)
242 if (desc==target) return 1;
243 if (desc->arraytype != target->arraytype) return 0;
244 switch (target->arraytype) {
245 case ARRAYTYPE_OBJECT:
246 return builtin_isanysubclass (desc->objectclass, target->objectclass);
247 case ARRAYTYPE_ARRAY:
248 return builtin_descriptorscompatible
249 (desc->elementdescriptor, target->elementdescriptor);
256 /******************** Funktion: builtin_checkarraycast ***********************
258 "uberpr"uft, ob ein gegebenes Objekt tats"achlich von einem
259 Untertyp des geforderten Arraytyps ist.
260 Dazu muss das Objekt auf jeden Fall ein Array sein.
261 Bei einfachen Arrays (int,short,double,etc.) muss der Typ genau
263 Bei Arrays von Objekten muss der Elementtyp des tats"achlichen Arrays
264 ein Untertyp (oder der selbe Typ) vom geforderten Elementtyp sein.
265 Bei Arrays vom Arrays (die eventuell wieder Arrays von Arrays
266 sein k"onnen) m"ussen die untersten Elementtypen in der entsprechenden
267 Unterklassenrelation stehen.
269 Return: 1, wenn Cast in Ordung ist
270 0, wenn es nicht geht
272 Achtung: ein Cast mit einem NULL-Zeiger geht immer gut.
274 *****************************************************************************/
276 s4 builtin_checkarraycast(java_objectheader *o, constant_arraydescriptor *desc)
278 java_arrayheader *a = (java_arrayheader*) o;
281 if (o->vftbl->class != class_array) {
285 if (a->arraytype != desc->arraytype) {
289 switch (a->arraytype) {
290 case ARRAYTYPE_OBJECT: {
291 java_objectarray *oa = (java_objectarray*) o;
292 return builtin_isanysubclass (oa->elementtype, desc->objectclass);
294 case ARRAYTYPE_ARRAY: {
295 java_arrayarray *aa = (java_arrayarray*) o;
296 return builtin_descriptorscompatible
297 (aa->elementdescriptor, desc->elementdescriptor);
305 s4 builtin_arrayinstanceof
306 (java_objectheader *obj, constant_arraydescriptor *desc)
309 return builtin_checkarraycast (obj, desc);
313 /************************** exception functions *******************************
315 ******************************************************************************/
317 java_objectheader *builtin_throw_exception (java_objectheader *exceptionptr) {
318 unicode_display (exceptionptr->vftbl->class->name);
325 /******************* Funktion: builtin_canstore *******************************
327 "uberpr"uft, ob ein Objekt in einem Array gespeichert werden
329 Return: 1, wenn es geht
332 ******************************************************************************/
335 s4 builtin_canstore (java_objectarray *a, java_objectheader *o)
339 switch (a->header.arraytype) {
340 case ARRAYTYPE_OBJECT:
341 if ( ! builtin_checkcast (o, a->elementtype) ) {
347 case ARRAYTYPE_ARRAY:
348 if ( ! builtin_checkarraycast
349 (o, ((java_arrayarray*)a)->elementdescriptor) ) {
356 panic ("builtin_canstore called with invalid arraytype");
363 /*****************************************************************************
365 *****************************************************************************/
369 /******************** Funktion: builtin_new **********************************
371 Legt ein neues Objekt einer Klasse am Heap an.
372 Return: Der Zeiger auf das Objekt, oder NULL, wenn kein Speicher
375 *****************************************************************************/
377 java_objectheader *builtin_new (classinfo *c)
379 java_objectheader *o;
381 o = heap_allocate ( c->instancesize, true, c->finalizer );
384 memset (o, 0, c->instancesize);
386 o -> vftbl = c -> vftbl;
392 /******************** Funktion: builtin_anewarray ****************************
394 Legt ein Array von Zeigern auf Objekte am Heap an.
396 size ......... Anzahl der Elemente
397 elementtype .. ein Zeiger auf die classinfo-Struktur des Typs
400 Return: Zeiger auf das Array, oder NULL (wenn kein Speicher frei)
402 *****************************************************************************/
404 java_objectarray *builtin_anewarray (s4 size, classinfo *elementtype)
409 a = heap_allocate ( sizeof(java_objectarray) + (size-1) * sizeof(void*),
410 true, 0 /* FALSE */ );
413 a -> header.objheader.vftbl = class_array -> vftbl;
414 a -> header.size = size;
415 a -> header.arraytype = ARRAYTYPE_OBJECT;
416 a -> elementtype = elementtype;
417 for (i=0; i<size; i++) a->data[i] = NULL;
423 /******************** Funktion: builtin_newarray_array ***********************
425 Legt ein Array von Zeigern auf Arrays am Heap an.
426 Paramter: size ......... Anzahl der Elemente
427 elementdesc .. Zeiger auf die Arraybeschreibungs-Struktur f"ur
430 Return: Zeiger auf das Array, oder NULL
432 *****************************************************************************/
434 java_arrayarray *builtin_newarray_array
435 (s4 size, constant_arraydescriptor *elementdesc)
440 a = heap_allocate ( sizeof(java_arrayarray) + (size-1) * sizeof(void*),
444 a -> header.objheader.vftbl = class_array -> vftbl;
445 a -> header.size = size;
446 a -> header.arraytype = ARRAYTYPE_ARRAY;
447 a -> elementdescriptor = elementdesc;
448 for (i=0; i<size; i++) a->data[i] = NULL;
453 /******************** Funktion: builtin_newarray_boolean ************************
455 Legt ein Array von Bytes am Heap an, das allerdings als Boolean-Array
456 gekennzeichnet wird (wichtig bei Casts!)
458 Return: Zeiger auf das Array, oder NULL
460 *****************************************************************************/
462 java_booleanarray *builtin_newarray_boolean (s4 size)
464 java_booleanarray *a;
466 a = heap_allocate ( sizeof(java_booleanarray) + (size-1) * sizeof(u1),
470 a -> header.objheader.vftbl = class_array -> vftbl;
471 a -> header.size = size;
472 a -> header.arraytype = ARRAYTYPE_BOOLEAN;
473 memset (a->data, 0, sizeof(u1) * size);
478 /******************** Funktion: builtin_newarray_char ************************
480 Legt ein Array von 16-bit-Integers am Heap an.
481 Return: Zeiger auf das Array, oder NULL
483 *****************************************************************************/
485 java_chararray *builtin_newarray_char (s4 size)
489 a = heap_allocate ( sizeof(java_chararray) + (size-1) * sizeof(u2),
493 a -> header.objheader.vftbl = class_array -> vftbl;
494 a -> header.size = size;
495 a -> header.arraytype = ARRAYTYPE_CHAR;
496 memset (a->data, 0, sizeof(u2) * size);
502 /******************** Funktion: builtin_newarray_float ***********************
504 Legt ein Array von 32-bit-IEEE-float am Heap an.
505 Return: Zeiger auf das Array, oder NULL
507 *****************************************************************************/
509 java_floatarray *builtin_newarray_float (s4 size)
514 a = heap_allocate ( sizeof(java_floatarray) + (size-1) * sizeof(float),
518 a -> header.objheader.vftbl = class_array -> vftbl;
519 a -> header.size = size;
520 a -> header.arraytype = ARRAYTYPE_FLOAT;
521 for (i=0; i<size; i++) a->data[i] = 0.0;
526 /******************** Funktion: builtin_newarray_double ***********************
528 Legt ein Array von 64-bit-IEEE-float am Heap an.
529 Return: Zeiger auf das Array, oder NULL
531 *****************************************************************************/
533 java_doublearray *builtin_newarray_double (s4 size)
538 a = heap_allocate ( sizeof(java_doublearray) + (size-1) * sizeof(double),
542 a -> header.objheader.vftbl = class_array -> vftbl;
543 a -> header.size = size;
544 a -> header.arraytype = ARRAYTYPE_DOUBLE;
545 for (i=0; i<size; i++) a->data[i] = 0.0;
552 /******************** Funktion: builtin_newarray_byte ***********************
554 Legt ein Array von 8-bit-Integers am Heap an.
555 Return: Zeiger auf das Array, oder NULL
557 *****************************************************************************/
559 java_bytearray *builtin_newarray_byte (s4 size)
563 a = heap_allocate ( sizeof(java_bytearray) + (size-1) * sizeof(s1),
567 a -> header.objheader.vftbl = class_array->vftbl;
568 a -> header.size = size;
569 a -> header.arraytype = ARRAYTYPE_BYTE;
570 memset (a->data, 0, sizeof(u1) * size);
575 /******************** Funktion: builtin_newarray_short ***********************
577 Legt ein Array von 16-bit-Integers am Heap an.
578 Return: Zeiger auf das Array, oder NULL
580 *****************************************************************************/
582 java_shortarray *builtin_newarray_short (s4 size)
586 a = heap_allocate ( sizeof(java_shortarray) + (size-1) * sizeof(s2),
590 a -> header.objheader.vftbl = class_array -> vftbl;
591 a -> header.size = size;
592 a -> header.arraytype = ARRAYTYPE_SHORT;
593 memset (a->data, 0, sizeof(s2) * size);
598 /******************** Funktion: builtin_newarray_int ***********************
600 Legt ein Array von 32-bit-Integers am Heap an.
601 Return: Zeiger auf das Array, oder NULL
603 *****************************************************************************/
605 java_intarray *builtin_newarray_int (s4 size)
609 a = heap_allocate ( sizeof(java_intarray) + (size-1) * sizeof(s4),
613 a -> header.objheader.vftbl = class_array -> vftbl;
614 a -> header.size = size;
615 a -> header.arraytype = ARRAYTYPE_INT;
616 memset (a->data, 0, sizeof(s4) * size);
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)
632 a = heap_allocate ( sizeof(java_longarray) + (size-1) * sizeof(s8),
636 a -> header.objheader.vftbl = class_array -> vftbl;
637 a -> header.size = size;
638 a -> header.arraytype = ARRAYTYPE_LONG;
639 memset (a->data, 0, sizeof(s8) * size);
645 /***************** Funktion: builtin_multianewarray ***************************
647 Legt ein mehrdimensionales Array am Heap an.
648 Die Gr"ossen der einzelnen Dimensionen werden in einem Integerarray
649 "ubergeben. Der Typ es zu erzeugenden Arrays wird als
650 Referenz auf eine constant_arraydescriptor - Struktur "ubergeben.
652 Return: Ein Zeiger auf das Array, oder NULL, wenn kein Speicher mehr
655 ******************************************************************************/
659 static java_arrayheader *multianewarray_part (java_intarray *dims, int thisdim,
660 constant_arraydescriptor *desc)
665 size = dims -> data[thisdim];
667 if (thisdim == (dims->header.size-1)) {
668 /* letzte Dimension schon erreicht */
670 switch (desc -> arraytype) {
671 case ARRAYTYPE_BOOLEAN:
672 return (java_arrayheader*) builtin_newarray_boolean (size);
674 return (java_arrayheader*) builtin_newarray_char (size);
675 case ARRAYTYPE_FLOAT:
676 return (java_arrayheader*) builtin_newarray_float (size);
677 case ARRAYTYPE_DOUBLE:
678 return (java_arrayheader*) builtin_newarray_double (size);
680 return (java_arrayheader*) builtin_newarray_byte (size);
681 case ARRAYTYPE_SHORT:
682 return (java_arrayheader*) builtin_newarray_short (size);
684 return (java_arrayheader*) builtin_newarray_int (size);
686 return (java_arrayheader*) builtin_newarray_long (size);
687 case ARRAYTYPE_OBJECT:
688 return (java_arrayheader*) builtin_anewarray (size, desc->objectclass);
690 case ARRAYTYPE_ARRAY:
691 return (java_arrayheader*) builtin_newarray_array (size, desc->elementdescriptor);
693 default: panic ("Invalid arraytype in multianewarray");
697 /* wenn letzte Dimension noch nicht erreicht wurde */
699 if (desc->arraytype != ARRAYTYPE_ARRAY)
700 panic ("multianewarray with too many dimensions");
702 a = builtin_newarray_array (size, desc->elementdescriptor);
705 for (i=0; i<size; i++) {
706 java_arrayheader *ea =
707 multianewarray_part (dims, thisdim+1, desc->elementdescriptor);
708 if (!ea) return NULL;
713 return (java_arrayheader*) a;
717 java_arrayheader *builtin_multianewarray (java_intarray *dims,
718 constant_arraydescriptor *desc)
720 return multianewarray_part (dims, 0, desc);
724 static java_arrayheader *nmultianewarray_part (int n, long *dims, int thisdim,
725 constant_arraydescriptor *desc)
730 size = (int) dims[thisdim];
732 if (thisdim == (n - 1)) {
733 /* letzte Dimension schon erreicht */
735 switch (desc -> arraytype) {
736 case ARRAYTYPE_BOOLEAN:
737 return (java_arrayheader*) builtin_newarray_boolean(size);
739 return (java_arrayheader*) builtin_newarray_char(size);
740 case ARRAYTYPE_FLOAT:
741 return (java_arrayheader*) builtin_newarray_float(size);
742 case ARRAYTYPE_DOUBLE:
743 return (java_arrayheader*) builtin_newarray_double(size);
745 return (java_arrayheader*) builtin_newarray_byte(size);
746 case ARRAYTYPE_SHORT:
747 return (java_arrayheader*) builtin_newarray_short(size);
749 return (java_arrayheader*) builtin_newarray_int(size);
751 return (java_arrayheader*) builtin_newarray_long(size);
752 case ARRAYTYPE_OBJECT:
753 return (java_arrayheader*) builtin_anewarray(size,
755 case ARRAYTYPE_ARRAY:
756 return (java_arrayheader*) builtin_newarray_array(size,
757 desc->elementdescriptor);
759 default: panic ("Invalid arraytype in multianewarray");
763 /* wenn letzte Dimension noch nicht erreicht wurde */
765 if (desc->arraytype != ARRAYTYPE_ARRAY)
766 panic ("multianewarray with too many dimensions");
768 a = builtin_newarray_array(size, desc->elementdescriptor);
771 for (i = 0; i < size; i++) {
772 java_arrayheader *ea =
773 nmultianewarray_part(n, dims, thisdim + 1, desc->elementdescriptor);
774 if (!ea) return NULL;
779 return (java_arrayheader*) a;
783 java_arrayheader *builtin_nmultianewarray (int size,
784 constant_arraydescriptor *desc, long *dims)
786 (void) builtin_newarray_int(size); /* for compatibility with -old */
787 return nmultianewarray_part (size, dims, 0, desc);
793 /************************* Funktion: builtin_aastore *************************
795 speichert eine Referenz auf ein Objekt in einem Object-Array oder
796 in einem Array-Array.
797 Dabei wird allerdings vorher "uberpr"uft, ob diese Operation
800 Return: 1, wenn alles OK ist
801 0, wenn dieses Objekt nicht in dieses Array gespeichert werden
804 *****************************************************************************/
806 s4 builtin_aastore (java_objectarray *a, s4 index, java_objectheader *o)
808 if (builtin_canstore(a,o)) {
820 /*****************************************************************************
821 METHODEN-PROTOKOLLIERUNG
823 Verschiedene Funktionen, mit denen eine Meldung ausgegeben werden
824 kann, wann immer Methoden aufgerufen oder beendet werden.
827 *****************************************************************************/
832 java_objectheader *builtin_trace_exception (java_objectheader *exceptionptr,
833 methodinfo *method, int *pos, int noindent) {
837 if (verbose || runverbose) {
838 printf("Exception ");
839 unicode_display (exceptionptr->vftbl->class->name);
840 printf(" thrown in ");
842 unicode_display (method->class->name);
844 unicode_display (method->name);
845 if (method->flags & ACC_SYNCHRONIZED)
849 printf("(%p) at position %p\n", method->entrypoint, pos);
852 printf("call_java_method\n");
859 void builtin_trace_args(long a0, long a1, long a2, long a3, long a4, long a5,
862 sprintf (logtext, " ");
863 sprintf (logtext+methodindent, "called: ");
864 unicode_sprint (logtext+strlen(logtext), method->class->name);
865 sprintf (logtext+strlen(logtext), ".");
866 unicode_sprint (logtext+strlen(logtext), method->name);
867 unicode_sprint (logtext+strlen(logtext), method->descriptor);
868 sprintf (logtext+strlen(logtext), "(");
869 switch (method->paramcount) {
871 sprintf(logtext+strlen(logtext), "%lx, %lx, %lx, %lx, %lx, %lx",
872 a0, a1, a2, a3, a4, a5);
875 sprintf(logtext+strlen(logtext), "%lx, %lx, %lx, %lx, %lx",
879 sprintf(logtext+strlen(logtext), "%lx, %lx, %lx, %lx",
883 sprintf(logtext+strlen(logtext), "%lx, %lx, %lx", a0, a1, a2);
886 sprintf(logtext+strlen(logtext), "%lx, %lx", a0, a1);
889 sprintf(logtext+strlen(logtext), "%lx", a0);
892 sprintf (logtext+strlen(logtext), ")");
898 void builtin_displaymethodstart(methodinfo *method)
900 sprintf (logtext, " ");
901 sprintf (logtext+methodindent, "called: ");
902 unicode_sprint (logtext+strlen(logtext), method->class->name);
903 sprintf (logtext+strlen(logtext), ".");
904 unicode_sprint (logtext+strlen(logtext), method->name);
905 unicode_sprint (logtext+strlen(logtext), method->descriptor);
910 void builtin_displaymethodstop(methodinfo *method, long l, double d)
913 sprintf (logtext, " ");
914 sprintf (logtext+methodindent, "finished: ");
915 unicode_sprint (logtext+strlen(logtext), method->class->name);
916 sprintf (logtext+strlen(logtext), ".");
917 unicode_sprint (logtext+strlen(logtext), method->name);
918 unicode_sprint (logtext+strlen(logtext), method->descriptor);
919 switch (method->returntype) {
922 sprintf (logtext+strlen(logtext), "->%ld", l);
926 sprintf (logtext+strlen(logtext), "->%g", d);
929 sprintf (logtext+strlen(logtext), "->%p", (void*) l);
935 void builtin_displaymethodexception(methodinfo *method)
937 sprintf (logtext, " ");
938 sprintf (logtext+methodindent, "exception abort: ");
939 unicode_sprint (logtext+strlen(logtext), method->class->name);
940 sprintf (logtext+strlen(logtext), ".");
941 unicode_sprint (logtext+strlen(logtext), method->name);
942 unicode_sprint (logtext+strlen(logtext), method->descriptor);
947 /****************************************************************************
948 SYNCHRONIZATION FUNCTIONS
949 *****************************************************************************/
952 * Lock the mutex of an object.
956 internal_lock_mutex_for_object (java_objectheader *object)
958 mutexHashEntry *entry;
963 hashValue = MUTEX_HASH_VALUE(object);
964 entry = &mutexHashTable[hashValue];
966 if (entry->object != 0)
968 if (entry->mutex.count == 0 && entry->conditionCount == 0)
971 entry->mutex.holder = 0;
972 entry->mutex.count = 0;
973 entry->mutex.muxWaiters = 0;
977 while (entry->next != 0 && entry->object != object)
980 if (entry->object != object)
982 entry->next = firstFreeOverflowEntry;
983 firstFreeOverflowEntry = firstFreeOverflowEntry->next;
988 assert(entry->conditionCount == 0);
994 entry->mutex.holder = 0;
995 entry->mutex.count = 0;
996 entry->mutex.muxWaiters = 0;
999 if (entry->object == 0)
1000 entry->object = object;
1002 internal_lock_mutex(&entry->mutex);
1008 * Unlocks the mutex of an object.
1012 internal_unlock_mutex_for_object (java_objectheader *object)
1015 mutexHashEntry *entry;
1017 hashValue = MUTEX_HASH_VALUE(object);
1018 entry = &mutexHashTable[hashValue];
1020 if (entry->object == object)
1021 internal_unlock_mutex(&entry->mutex);
1024 while (entry->next != 0 && entry->next->object != object)
1025 entry = entry->next;
1027 assert(entry->next != 0);
1029 internal_unlock_mutex(&entry->next->mutex);
1031 if (entry->next->mutex.count == 0 && entry->conditionCount == 0)
1033 mutexHashEntry *unlinked = entry->next;
1035 entry->next = unlinked->next;
1036 unlinked->next = firstFreeOverflowEntry;
1037 firstFreeOverflowEntry = unlinked;
1044 builtin_monitorenter (java_objectheader *o)
1049 assert(blockInts == 0);
1053 hashValue = MUTEX_HASH_VALUE(o);
1054 if (mutexHashTable[hashValue].object == o
1055 && mutexHashTable[hashValue].mutex.holder == currentThread)
1056 ++mutexHashTable[hashValue].mutex.count;
1058 internal_lock_mutex_for_object(o);
1062 assert(blockInts == 0);
1066 void builtin_monitorexit (java_objectheader *o)
1071 assert(blockInts == 0);
1075 hashValue = MUTEX_HASH_VALUE(o);
1076 if (mutexHashTable[hashValue].object == o)
1078 if (mutexHashTable[hashValue].mutex.count == 1
1079 && mutexHashTable[hashValue].mutex.muxWaiters != 0)
1080 internal_unlock_mutex_for_object(o);
1082 --mutexHashTable[hashValue].mutex.count;
1085 internal_unlock_mutex_for_object(o);
1089 assert(blockInts == 0);
1094 /*****************************************************************************
1095 DIVERSE HILFSFUNKTIONEN
1096 *****************************************************************************/
1100 /*********** Funktionen f"ur die Integerdivision *****************************
1102 Auf manchen Systemen (z.B. DEC ALPHA) wird durch die CPU keine Integer-
1103 division unterst"utzt.
1104 Daf"ur gibt es dann diese Hilfsfunktionen
1106 ******************************************************************************/
1108 s4 builtin_idiv (s4 a, s4 b) { return a/b; }
1109 s4 builtin_irem (s4 a, s4 b) { return a%b; }
1112 /************** Funktionen f"ur Long-Arithmetik *******************************
1114 Auf Systemen, auf denen die CPU keine 64-Bit-Integers unterst"utzt,
1115 werden diese Funktionen gebraucht
1117 ******************************************************************************/
1120 s8 builtin_ladd (s8 a, s8 b)
1125 return builtin_i2l(0);
1129 s8 builtin_lsub (s8 a, s8 b)
1134 return builtin_i2l(0);
1138 s8 builtin_lmul (s8 a, s8 b)
1143 return builtin_i2l(0);
1147 s8 builtin_ldiv (s8 a, s8 b)
1152 return builtin_i2l(0);
1156 s8 builtin_lrem (s8 a, s8 b)
1161 return builtin_i2l(0);
1165 s8 builtin_lshl (s8 a, s4 b)
1170 return builtin_i2l(0);
1174 s8 builtin_lshr (s8 a, s4 b)
1179 return builtin_i2l(0);
1183 s8 builtin_lushr (s8 a, s4 b)
1186 return ((u8)a)>>(b&63);
1188 return builtin_i2l(0);
1192 s8 builtin_land (s8 a, s8 b)
1197 return builtin_i2l(0);
1201 s8 builtin_lor (s8 a, s8 b)
1206 return builtin_i2l(0);
1210 s8 builtin_lxor (s8 a, s8 b)
1215 return builtin_i2l(0);
1219 s8 builtin_lneg (s8 a)
1224 return builtin_i2l(0);
1228 s4 builtin_lcmp (s8 a, s8 b)
1243 /*********** Funktionen f"ur die Floating-Point-Operationen ******************/
1245 float builtin_fadd (float a, float b)
1247 if (isnanf(a)) return FLT_NAN;
1248 if (isnanf(b)) return FLT_NAN;
1250 if (finitef(b)) return a+b;
1254 if (finitef(b)) return a;
1256 if (copysignf(1.0, a)==copysignf(1.0, b)) return a;
1257 else return FLT_NAN;
1262 float builtin_fsub (float a, float b)
1264 return builtin_fadd (a, builtin_fneg(b));
1267 float builtin_fmul (float a, float b)
1269 if (isnanf(a)) return FLT_NAN;
1270 if (isnanf(b)) return FLT_NAN;
1272 if (finitef(b)) return a*b;
1274 if (a==0) return FLT_NAN;
1275 else return copysignf(b, copysignf(1.0, b)*a);
1280 if (b==0) return FLT_NAN;
1281 else return copysignf(a, copysignf(1.0, a)*b);
1284 return copysignf(a, copysignf(1.0, a)*copysignf(1.0, b));
1289 float builtin_fdiv (float a, float b)
1291 if (finitef(a) && finitef(b)) {
1304 float builtin_frem (float a, float b)
1307 /* return (float) builtin_drem((double) a, (double) b); */
1311 if (finite((double) a) && finite((double) b)) {
1313 if (finite((double) f))
1317 if (isnan((double) b))
1319 if (finite((double) a))
1325 if (finitef(a) && finitef(b)) {
1328 return a - floorf(f) * b;
1339 float builtin_fneg (float a)
1341 if (isnanf(a)) return a;
1343 if (finitef(a)) return -a;
1344 else return copysignf(a,-copysignf(1.0, a));
1348 s4 builtin_fcmpl (float a, float b)
1350 if (isnanf(a)) return -1;
1351 if (isnanf(b)) return -1;
1352 if (!finitef(a) || !finitef(b)) {
1353 a = finitef(a) ? 0 : copysignf(1.0, a);
1354 b = finitef(b) ? 0 : copysignf(1.0, b);
1361 s4 builtin_fcmpg (float a, float b)
1363 if (isnanf(a)) return 1;
1364 if (isnanf(b)) return 1;
1365 if (!finitef(a) || !finitef(b)) {
1366 a = finitef(a) ? 0 : copysignf(1.0, a);
1367 b = finitef(b) ? 0 : copysignf(1.0, b);
1376 /*********** Funktionen f"ur doppelt genaue Fliesskommazahlen ***************/
1378 double builtin_dadd (double a, double b)
1380 if (isnan(a)) return DBL_NAN;
1381 if (isnan(b)) return DBL_NAN;
1383 if (finite(b)) return a+b;
1387 if (finite(b)) return a;
1389 if (copysign(1.0, a)==copysign(1.0, b)) return a;
1390 else return DBL_NAN;
1395 double builtin_dsub (double a, double b)
1397 return builtin_dadd (a, builtin_dneg(b));
1400 double builtin_dmul (double a, double b)
1402 if (isnan(a)) return DBL_NAN;
1403 if (isnan(b)) return DBL_NAN;
1405 if (finite(b)) return a*b;
1407 if (a==0) return DBL_NAN;
1408 else return copysign(b, copysign(1.0, b)*a);
1413 if (b==0) return DBL_NAN;
1414 else return copysign(a, copysign(1.0, a)*b);
1417 return copysign(a, copysign(1.0, a)*copysign(1.0, b));
1422 double builtin_ddiv (double a, double b)
1424 if (finite(a) && finite(b)) {
1437 double builtin_drem (double a, double b)
1441 if (finite(a) && finite(b)) {
1444 if ((d < 1.0) && (d > 0.0))
1457 double builtin_dneg (double a)
1459 if (isnan(a)) return a;
1461 if (finite(a)) return -a;
1462 else return copysign(a,-copysign(1.0, a));
1466 s4 builtin_dcmpl (double a, double b)
1468 if (isnan(a)) return -1;
1469 if (isnan(b)) return -1;
1470 if (!finite(a) || !finite(b)) {
1471 a = finite(a) ? 0 : copysign(1.0, a);
1472 b = finite(b) ? 0 : copysign(1.0, b);
1479 s4 builtin_dcmpg (double a, double b)
1481 if (isnan(a)) return 1;
1482 if (isnan(b)) return 1;
1483 if (!finite(a) || !finite(b)) {
1484 a = finite(a) ? 0 : copysign(1.0, a);
1485 b = finite(b) ? 0 : copysign(1.0, b);
1493 /*********************** Umwandlungsoperationen ****************************/
1495 s8 builtin_i2l (s4 i)
1500 s8 v; v.high = 0; v.low=i; return v;
1504 float builtin_i2f (s4 a)
1506 float f = (float) a;
1510 double builtin_i2d (s4 a)
1512 double d = (double) a;
1517 s4 builtin_l2i (s8 l)
1526 float builtin_l2f (s8 a)
1529 float f = (float) a;
1536 double builtin_l2d (s8 a)
1539 double d = (double) a;
1547 s4 builtin_f2i(float a)
1550 return builtin_d2i((double) a);
1559 if (a < (-2147483648))
1560 return (-2147483648);
1563 f = copysignf((float) 1.0, a);
1566 return (-2147483648); */
1570 s8 builtin_f2l (float a)
1573 return builtin_d2l((double) a);
1578 if (a > 9223372036854775807L)
1579 return 9223372036854775807L;
1580 if (a < (-9223372036854775808L))
1581 return (-9223372036854775808L);
1586 f = copysignf((float) 1.0, a);
1588 return 9223372036854775807L;
1589 return (-9223372036854775808L); */
1593 double builtin_f2d (float a)
1595 if (finitef(a)) return (double) a;
1597 if (isnanf(a)) return DBL_NAN;
1598 else return copysign(DBL_POSINF, (double) copysignf(1.0, a) );
1603 s4 builtin_d2i (double a)
1608 if (a >= 2147483647)
1610 if (a <= (-2147483648))
1611 return (-2147483648);
1616 d = copysign(1.0, a);
1619 return (-2147483648);
1623 s8 builtin_d2l (double a)
1628 if (a >= 9223372036854775807L)
1629 return 9223372036854775807L;
1630 if (a <= (-9223372036854775807L-1))
1631 return (-9223372036854775807L-1);
1636 d = copysign(1.0, a);
1638 return 9223372036854775807L;
1639 return (-9223372036854775807L-1);
1643 float builtin_d2f (double a)
1645 if (finite(a)) return (float) a;
1647 if (isnan(a)) return FLT_NAN;
1648 else return copysignf (FLT_POSINF, (float) copysign(1.0, a));