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 Contains C functions for JavaVM Instructions that cannot be translated
8 to machine language directly. Consequently, the generated machine code
9 for these instructions contains function calls instead of machine
10 instructions, using the C calling convention.
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: 2003/02/12
18 *******************************************************************************/
28 #include "threads/thread.h"
29 #include "threads/locks.h" /* schani */
31 #include "native-math.h"
33 builtin_descriptor builtin_desc[] = {
34 {(functionptr) builtin_instanceof, "instanceof"},
35 {(functionptr) builtin_checkcast, "checkcast"},
36 {(functionptr) asm_builtin_checkcast, "checkcast"},
37 {(functionptr) builtin_arrayinstanceof, "arrayinstanceof"},
39 {(functionptr) asm_builtin_arrayinstanceof,"arrayinstanceof"},
41 {(functionptr) builtin_checkarraycast, "checkarraycast"},
42 {(functionptr) asm_builtin_checkarraycast, "checkarraycast"},
43 {(functionptr) asm_builtin_aastore, "aastore"},
44 {(functionptr) builtin_new, "new"},
45 {(functionptr) builtin_anewarray, "anewarray"},
46 {(functionptr) builtin_newarray_array, "newarray_array"},
49 * have 2 parameters (needs stack manipulation)
51 {(functionptr) asm_builtin_anewarray, "anewarray"},
52 {(functionptr) asm_builtin_newarray_array, "newarray_array"},
54 {(functionptr) builtin_newarray_boolean, "newarray_boolean"},
55 {(functionptr) builtin_newarray_char, "newarray_char"},
56 {(functionptr) builtin_newarray_float, "newarray_float"},
57 {(functionptr) builtin_newarray_double, "newarray_double"},
58 {(functionptr) builtin_newarray_byte, "newarray_byte"},
59 {(functionptr) builtin_newarray_short, "newarray_short"},
60 {(functionptr) builtin_newarray_int, "newarray_int"},
61 {(functionptr) builtin_newarray_long, "newarray_long"},
62 {(functionptr) builtin_displaymethodstart, "displaymethodstart"},
63 {(functionptr) builtin_displaymethodstop, "displaymethodstop"},
64 {(functionptr) builtin_monitorenter, "monitorenter"},
65 {(functionptr) asm_builtin_monitorenter, "monitorenter"},
66 {(functionptr) builtin_monitorexit, "monitorexit"},
67 {(functionptr) asm_builtin_monitorexit, "monitorexit"},
68 {(functionptr) builtin_idiv, "idiv"},
69 #if !defined(SUPPORT_DIVISION)
70 {(functionptr) asm_builtin_idiv, "idiv"},
72 {(functionptr) builtin_irem, "irem"},
73 #if !defined(SUPPORT_DIVISION)
74 {(functionptr) asm_builtin_irem, "irem"},
76 {(functionptr) builtin_ladd, "ladd"},
77 {(functionptr) builtin_lsub, "lsub"},
78 {(functionptr) builtin_lmul, "lmul"},
79 {(functionptr) builtin_ldiv, "ldiv"},
80 #if !defined(SUPPORT_DIVISION) || !defined(SUPPORT_LONG) || !defined(SUPPORT_LONG_MULDIV)
81 {(functionptr) asm_builtin_ldiv, "ldiv"},
83 {(functionptr) builtin_lrem, "lrem"},
84 #if !defined(SUPPORT_DIVISION) || !defined(SUPPORT_LONG) || !defined(SUPPORT_LONG_MULDIV)
85 {(functionptr) asm_builtin_lrem, "lrem"},
87 {(functionptr) builtin_lshl, "lshl"},
88 {(functionptr) builtin_lshr, "lshr"},
89 {(functionptr) builtin_lushr, "lushr"},
90 {(functionptr) builtin_land, "land"},
91 {(functionptr) builtin_lor, "lor"},
92 {(functionptr) builtin_lxor, "lxor"},
93 {(functionptr) builtin_lneg, "lneg"},
94 {(functionptr) builtin_lcmp, "lcmp"},
95 {(functionptr) builtin_fadd, "fadd"},
96 {(functionptr) builtin_fsub, "fsub"},
97 {(functionptr) builtin_fmul, "fmul"},
98 {(functionptr) builtin_fdiv, "fdiv"},
99 {(functionptr) builtin_frem, "frem"},
100 {(functionptr) builtin_fneg, "fneg"},
101 {(functionptr) builtin_fcmpl, "fcmpl"},
102 {(functionptr) builtin_fcmpg, "fcmpg"},
103 {(functionptr) builtin_dadd, "dadd"},
104 {(functionptr) builtin_dsub, "dsub"},
105 {(functionptr) builtin_dmul, "dmul"},
106 {(functionptr) builtin_ddiv, "ddiv"},
107 {(functionptr) builtin_drem, "drem"},
108 {(functionptr) builtin_dneg, "dneg"},
109 {(functionptr) builtin_dcmpl, "dcmpl"},
110 {(functionptr) builtin_dcmpg, "dcmpg"},
111 {(functionptr) builtin_i2l, "i2l"},
112 {(functionptr) builtin_i2f, "i2f"},
113 {(functionptr) builtin_i2d, "i2d"},
114 {(functionptr) builtin_l2i, "l2i"},
115 {(functionptr) builtin_l2f, "l2f"},
116 {(functionptr) builtin_l2d, "l2d"},
117 {(functionptr) builtin_f2i, "f2i"},
118 {(functionptr) builtin_f2l, "f2l"},
119 {(functionptr) builtin_f2d, "f2d"},
120 {(functionptr) builtin_d2i, "d2i"},
121 {(functionptr) builtin_d2l, "d2l"},
122 {(functionptr) builtin_d2f, "d2f"},
123 {(functionptr) NULL, "unknown"}
127 /*****************************************************************************
129 *****************************************************************************/
133 /*************** internal function: builtin_isanysubclass *********************
135 Checks a subclass relation between two classes. Implemented interfaces
136 are interpreted as super classes.
137 Return value: 1 ... sub is subclass of super
140 *****************************************************************************/
142 s4 builtin_isanysubclass (classinfo *sub, classinfo *super)
144 if (super->flags & ACC_INTERFACE)
145 return (sub->vftbl->interfacetablelength > super->index) &&
146 (sub->vftbl->interfacetable[-super->index] != NULL);
158 return (unsigned) (sub->vftbl->baseval - super->vftbl->baseval) <=
159 (unsigned) (super->vftbl->diffval);
163 /****************** function: builtin_instanceof *****************************
165 Checks if an object is an instance of some given class (or subclass of
166 that class). If class is an interface, checks if the interface is
168 Return value: 1 ... obj is an instance of class or implements the interface
169 0 ... otherwise or if obj == NULL
171 *****************************************************************************/
173 s4 builtin_instanceof(java_objectheader *obj, classinfo *class)
176 log_text ("builtin_instanceof called");
180 return builtin_isanysubclass (obj->vftbl->class, class);
185 /**************** function: builtin_checkcast *******************************
187 The same as builtin_instanceof except that 1 is returned when
190 ****************************************************************************/
192 s4 builtin_checkcast(java_objectheader *obj, classinfo *class)
195 log_text ("builtin_checkcast called");
200 if (builtin_isanysubclass (obj->vftbl->class, class))
204 printf ("#### checkcast failed ");
205 utf_display (obj->vftbl->class->name);
207 utf_display (class->name);
215 /*********** internal function: builtin_descriptorscompatible ******************
217 Checks if two array type descriptors are assignment compatible
218 Return value: 1 ... target = desc is possible
221 ******************************************************************************/
223 static s4 builtin_descriptorscompatible(constant_arraydescriptor *desc, constant_arraydescriptor *target)
225 if (desc==target) return 1;
226 if (desc->arraytype != target->arraytype) return 0;
227 switch (target->arraytype) {
228 case ARRAYTYPE_OBJECT:
229 return builtin_isanysubclass (desc->objectclass, target->objectclass);
230 case ARRAYTYPE_ARRAY:
231 return builtin_descriptorscompatible
232 (desc->elementdescriptor, target->elementdescriptor);
239 /******************** function: builtin_checkarraycast ***********************
241 Checks if an object is really a subtype of the requested array type.
242 The object has to be an array to begin with. For simple arrays (int, short,
243 double, etc.) the types have to match exactly.
244 For arrays of objects, the type of elements in the array has to be a
245 subtype (or the same type) of the requested element type. For arrays of
246 arrays (which in turn can again be arrays of arrays), the types at the
247 lowest level have to satisfy the corresponding sub class relation.
249 Return value: 1 ... cast is possible
252 ATTENTION: a cast with a NULL pointer is always possible.
254 *****************************************************************************/
256 s4 builtin_checkarraycast(java_objectheader *o, constant_arraydescriptor *desc)
258 java_arrayheader *a = (java_arrayheader*) o;
261 if (o->vftbl->class != class_array) {
263 printf ("#### checkarraycast failed 1\n");
268 if (a->arraytype != desc->arraytype) {
270 printf ("#### checkarraycast failed 2\n");
275 switch (a->arraytype) {
276 case ARRAYTYPE_OBJECT: {
277 java_objectarray *oa = (java_objectarray*) o;
278 int result = builtin_isanysubclass (oa->elementtype, desc->objectclass);
282 printf ("#### checkarraycast failed 3\n");
286 case ARRAYTYPE_ARRAY: {
287 java_arrayarray *aa = (java_arrayarray*) o;
288 int result = builtin_descriptorscompatible
289 (aa->elementdescriptor, desc->elementdescriptor);
293 printf ("#### checkarraycast failed 4\n");
303 s4 builtin_arrayinstanceof(java_objectheader *obj, constant_arraydescriptor *desc)
306 return builtin_checkarraycast (obj, desc);
310 /************************** exception functions *******************************
312 ******************************************************************************/
314 java_objectheader *builtin_throw_exception (java_objectheader *local_exceptionptr) {
316 sprintf(logtext, "Builtin exception thrown: ");
317 utf_sprint(logtext + strlen(logtext), local_exceptionptr->vftbl->class->name);
320 exceptionptr = local_exceptionptr;
321 return local_exceptionptr;
325 /******************* function: builtin_canstore *******************************
327 Checks, if an object can be stored in an array.
328 Return value: 1 ... possible
331 ******************************************************************************/
334 s4 builtin_canstore (java_objectarray *a, java_objectheader *o)
338 switch (a->header.arraytype) {
339 case ARRAYTYPE_OBJECT:
340 if ( ! builtin_checkcast (o, a->elementtype) ) {
346 case ARRAYTYPE_ARRAY:
347 if ( ! builtin_checkarraycast
348 (o, ((java_arrayarray*)a)->elementdescriptor) ) {
355 panic ("builtin_canstore called with invalid arraytype");
362 /*****************************************************************************
364 *****************************************************************************/
368 /******************** Function: builtin_new **********************************
370 Creates a new instance of class c on the heap.
371 Return value: pointer to the object or NULL if no memory is
374 *****************************************************************************/
377 #define align_size(size) ((size + ((1 << ALIGNMENT) - 1)) & ~((1 << ALIGNMENT) - 1))
379 java_objectheader *builtin_new (classinfo *c)
381 java_objectheader *o;
385 #ifdef SIZE_FROM_CLASSINFO
386 c->alignedsize = align_size(c->instancesize);
387 o = heap_allocate ( c->alignedsize, true, c->finalizer );
389 o = heap_allocate ( c->instancesize, true, c->finalizer );
393 memset (o, 0, c->instancesize);
395 o -> vftbl = c -> vftbl;
401 /******************** function: builtin_anewarray ****************************
403 Creates an array of pointers to objects on the heap.
405 size ......... number of elements
406 elementtype .. pointer to the classinfo structure for the element type
408 Return value: pointer to the array or NULL if no memory is available
410 *****************************************************************************/
413 void* __builtin_newarray(s4 base_size,
420 #ifdef SIZE_FROM_CLASSINFO
421 s4 alignedsize = align_size(base_size + (size-1) * elementsize);
422 a = heap_allocate ( alignedsize, references, NULL );
424 a = heap_allocate ( sizeof(java_objectarray) + (size-1) * elementsize,
430 #ifdef SIZE_FROM_CLASSINFO
431 memset(a, 0, alignedsize);
433 memset(a, 0, base_size + (size-1) * elementsize);
436 a -> objheader.vftbl = class_array -> vftbl;
438 #ifdef SIZE_FROM_CLASSINFO
439 a -> alignedsize = alignedsize;
441 a -> arraytype = arraytype;
447 java_objectarray *builtin_anewarray (s4 size, classinfo *elementtype)
450 a = (java_objectarray*)__builtin_newarray(sizeof(java_objectarray),
457 a -> elementtype = elementtype;
463 /******************** function: builtin_newarray_array ***********************
465 Creates an array of pointers to arrays on the heap.
467 size ......... number of elements
468 elementdesc .. pointer to the array description structure for the
471 Return value: pointer to the array or NULL if no memory is available
473 *****************************************************************************/
475 java_arrayarray *builtin_newarray_array
476 (s4 size, constant_arraydescriptor *elementdesc)
479 a = (java_arrayarray*)__builtin_newarray(sizeof(java_arrayarray),
486 a -> elementdescriptor = elementdesc;
491 /******************** function: builtin_newarray_boolean ************************
493 Creates an array of bytes on the heap. The array is designated as an array
494 of booleans (important for casts)
496 Return value: pointer to the array or NULL if no memory is available
498 *****************************************************************************/
500 java_booleanarray *builtin_newarray_boolean (s4 size)
502 java_booleanarray *a;
503 a = (java_booleanarray*)__builtin_newarray(sizeof(java_booleanarray),
511 /******************** function: builtin_newarray_char ************************
513 Creates an array of characters on the heap.
515 Return value: pointer to the array or NULL if no memory is available
517 *****************************************************************************/
519 java_chararray *builtin_newarray_char (s4 size)
522 a = (java_chararray*)__builtin_newarray(sizeof(java_chararray),
531 /******************** function: builtin_newarray_float ***********************
533 Creates an array of 32 bit IEEE floats on the heap.
535 Return value: pointer to the array or NULL if no memory is available
537 *****************************************************************************/
539 java_floatarray *builtin_newarray_float (s4 size)
542 a = (java_floatarray*)__builtin_newarray(sizeof(java_floatarray),
551 /******************** function: builtin_newarray_double ***********************
553 Creates an array of 64 bit IEEE floats on the heap.
555 Return value: pointer to the array or NULL if no memory is available
557 *****************************************************************************/
559 java_doublearray *builtin_newarray_double (s4 size)
562 a = (java_doublearray*)__builtin_newarray(sizeof(java_doublearray),
573 /******************** function: builtin_newarray_byte ***********************
575 Creates an array of 8 bit Integers on the heap.
577 Return value: pointer to the array or NULL if no memory is available
579 *****************************************************************************/
581 java_bytearray *builtin_newarray_byte (s4 size)
584 a = (java_bytearray*)__builtin_newarray(sizeof(java_bytearray),
593 /******************** function: builtin_newarray_short ***********************
595 Creates an array of 16 bit Integers on the heap.
597 Return value: pointer to the array or NULL if no memory is available
599 *****************************************************************************/
601 java_shortarray *builtin_newarray_short (s4 size)
604 a = (java_shortarray*)__builtin_newarray(sizeof(java_shortarray),
613 /******************** Function: builtin_newarray_int ***********************
615 Creates an array of 32 bit Integers on the heap.
617 Return value: pointer to the array or NULL if no memory is available
619 *****************************************************************************/
621 java_intarray *builtin_newarray_int (s4 size)
624 a = (java_intarray*)__builtin_newarray(sizeof(java_intarray),
633 /******************** Function: builtin_newarray_long ***********************
635 Creates an array of 64 bit Integers on the heap.
637 Return value: pointer to the array or NULL if no memory is available
639 *****************************************************************************/
641 java_longarray *builtin_newarray_long (s4 size)
644 a = (java_longarray*)__builtin_newarray(sizeof(java_longarray),
654 /***************** function: builtin_multianewarray ***************************
656 Creates a multi-dimensional array on the heap. The dimensions are passed in
657 an array of Integers. The type for the array is passed as a reference to a
658 constant_arraydescriptor structure.
660 Return value: pointer to the array or NULL if no memory is available
662 ******************************************************************************/
664 /* Helper functions */
666 static java_arrayheader *multianewarray_part (java_intarray *dims, int thisdim,
667 constant_arraydescriptor *desc)
672 size = dims -> data[thisdim];
674 if (thisdim == (dims->header.size-1)) {
675 /* last dimension reached */
677 switch (desc -> arraytype) {
678 case ARRAYTYPE_BOOLEAN:
679 return (java_arrayheader*) builtin_newarray_boolean (size);
681 return (java_arrayheader*) builtin_newarray_char (size);
682 case ARRAYTYPE_FLOAT:
683 return (java_arrayheader*) builtin_newarray_float (size);
684 case ARRAYTYPE_DOUBLE:
685 return (java_arrayheader*) builtin_newarray_double (size);
687 return (java_arrayheader*) builtin_newarray_byte (size);
688 case ARRAYTYPE_SHORT:
689 return (java_arrayheader*) builtin_newarray_short (size);
691 return (java_arrayheader*) builtin_newarray_int (size);
693 return (java_arrayheader*) builtin_newarray_long (size);
694 case ARRAYTYPE_OBJECT:
695 return (java_arrayheader*) builtin_anewarray (size, desc->objectclass);
697 case ARRAYTYPE_ARRAY:
698 return (java_arrayheader*) builtin_newarray_array (size, desc->elementdescriptor);
700 default: panic ("Invalid arraytype in multianewarray");
704 /* if the last dimension has not been reached yet */
706 if (desc->arraytype != ARRAYTYPE_ARRAY)
707 panic ("multianewarray with too many dimensions");
709 a = builtin_newarray_array (size, desc->elementdescriptor);
712 for (i=0; i<size; i++) {
713 java_arrayheader *ea =
714 multianewarray_part (dims, thisdim+1, desc->elementdescriptor);
715 if (!ea) return NULL;
720 return (java_arrayheader*) a;
724 java_arrayheader *builtin_multianewarray (java_intarray *dims,
725 constant_arraydescriptor *desc)
727 return multianewarray_part (dims, 0, desc);
731 static java_arrayheader *nmultianewarray_part (int n, long *dims, int thisdim,
732 constant_arraydescriptor *desc)
737 size = (int) dims[thisdim];
739 if (thisdim == (n - 1)) {
740 /* last dimension reached */
742 switch (desc -> arraytype) {
743 case ARRAYTYPE_BOOLEAN:
744 return (java_arrayheader*) builtin_newarray_boolean(size);
746 return (java_arrayheader*) builtin_newarray_char(size);
747 case ARRAYTYPE_FLOAT:
748 return (java_arrayheader*) builtin_newarray_float(size);
749 case ARRAYTYPE_DOUBLE:
750 return (java_arrayheader*) builtin_newarray_double(size);
752 return (java_arrayheader*) builtin_newarray_byte(size);
753 case ARRAYTYPE_SHORT:
754 return (java_arrayheader*) builtin_newarray_short(size);
756 return (java_arrayheader*) builtin_newarray_int(size);
758 return (java_arrayheader*) builtin_newarray_long(size);
759 case ARRAYTYPE_OBJECT:
760 return (java_arrayheader*) builtin_anewarray(size,
762 case ARRAYTYPE_ARRAY:
763 return (java_arrayheader*) builtin_newarray_array(size,
764 desc->elementdescriptor);
766 default: panic ("Invalid arraytype in multianewarray");
770 /* if the last dimension has not been reached yet */
772 if (desc->arraytype != ARRAYTYPE_ARRAY)
773 panic ("multianewarray with too many dimensions");
775 a = builtin_newarray_array(size, desc->elementdescriptor);
778 for (i = 0; i < size; i++) {
779 java_arrayheader *ea =
780 nmultianewarray_part(n, dims, thisdim + 1, desc->elementdescriptor);
781 if (!ea) return NULL;
786 return (java_arrayheader*) a;
790 java_arrayheader *builtin_nmultianewarray (int size,
791 constant_arraydescriptor *desc, long *dims)
793 (void) builtin_newarray_int(size); /* for compatibility with -old */
794 return nmultianewarray_part (size, dims, 0, desc);
800 /************************* function: builtin_aastore *************************
802 Stores a reference to an object into an object array or into an array
803 array. Before any action is performed, the validity of the operation is
806 Return value: 1 ... ok
807 0 ... this object cannot be stored into this array
809 *****************************************************************************/
811 s4 builtin_aastore (java_objectarray *a, s4 index, java_objectheader *o)
813 if (builtin_canstore(a,o)) {
825 /*****************************************************************************
828 Various functions for printing a message at method entry or exit (for
831 *****************************************************************************/
836 java_objectheader *builtin_trace_exception (java_objectheader *exceptionptr,
837 methodinfo *method, int *pos, int noindent) {
841 if (verbose || runverbose) {
842 printf("Exception ");
843 utf_display (exceptionptr->vftbl->class->name);
844 printf(" thrown in ");
846 utf_display (method->class->name);
848 utf_display (method->name);
849 if (method->flags & ACC_SYNCHRONIZED)
853 printf("(%p) at position %p\n", method->entrypoint, pos);
856 printf("call_java_method\n");
863 #ifdef TRACE_ARGS_NUM
864 void builtin_trace_args(s8 a0, s8 a1, s8 a2, s8 a3, s8 a4, s8 a5,
865 #if TRACE_ARGS_NUM > 6
871 for (i=0; i<methodindent; i++)
873 sprintf (logtext+methodindent, "called: ");
874 utf_sprint (logtext+strlen(logtext), method->class->name);
875 sprintf (logtext+strlen(logtext), ".");
876 utf_sprint (logtext+strlen(logtext), method->name);
877 utf_sprint (logtext+strlen(logtext), method->descriptor);
878 sprintf (logtext+strlen(logtext), "(");
879 switch (method->paramcount) {
884 sprintf(logtext+strlen(logtext), "%llx", a0);
888 sprintf(logtext+strlen(logtext), "%llx, %llx", a0, a1);
892 sprintf(logtext+strlen(logtext), "%llx, %llx, %llx", a0, a1, a2);
896 sprintf(logtext+strlen(logtext), "%llx, %llx, %llx, %llx",
901 sprintf(logtext+strlen(logtext), "%llx, %llx, %llx, %llx, %llx",
906 sprintf(logtext+strlen(logtext), "%llx, %llx, %llx, %llx, %llx, %llx",
907 a0, a1, a2, a3, a4, a5);
910 #if TRACE_ARGS_NUM > 6
912 sprintf(logtext+strlen(logtext), "%llx, %llx, %llx, %llx, %llx, %llx, %llx",
913 a0, a1, a2, a3, a4, a5, a6);
917 sprintf(logtext+strlen(logtext), "%llx, %llx, %llx, %llx, %llx, %llx, %llx, %llx",
918 a0, a1, a2, a3, a4, a5, a6, a7);
922 sprintf(logtext+strlen(logtext), "%llx, %llx, %llx, %llx, %llx, %llx, %llx, %llx, ...(%d)",
923 a0, a1, a2, a3, a4, a5, a6, a7, method->paramcount - 8);
927 sprintf(logtext+strlen(logtext), "%llx, %llx, %llx, %llx, %llx, %llx, ...(%d)",
928 a0, a1, a2, a3, a4, a5, method->paramcount - 6);
932 sprintf (logtext+strlen(logtext), ")");
939 void builtin_displaymethodstart(methodinfo *method)
941 sprintf (logtext, " ");
942 sprintf (logtext+methodindent, "called: ");
943 utf_sprint (logtext+strlen(logtext), method->class->name);
944 sprintf (logtext+strlen(logtext), ".");
945 utf_sprint (logtext+strlen(logtext), method->name);
946 utf_sprint (logtext+strlen(logtext), method->descriptor);
951 void builtin_displaymethodstop(methodinfo *method, s8 l, double d, float f)
954 for (i=0; i<methodindent; i++)
957 sprintf (logtext+methodindent, "finished: ");
958 utf_sprint (logtext+strlen(logtext), method->class->name);
959 sprintf (logtext+strlen(logtext), ".");
960 utf_sprint (logtext+strlen(logtext), method->name);
961 utf_sprint (logtext+strlen(logtext), method->descriptor);
962 switch (method->returntype) {
964 sprintf (logtext+strlen(logtext), "->%ld", l);
967 sprintf (logtext+strlen(logtext), "->%lld", l);
970 sprintf (logtext+strlen(logtext), "->%p", l);
973 sprintf (logtext+strlen(logtext), "->%g", f);
976 sprintf (logtext+strlen(logtext), "->%g", d);
982 void builtin_displaymethodexception(methodinfo *method)
985 for (i=0; i<methodindent; i++)
987 sprintf (logtext+methodindent, "exception abort: ");
988 utf_sprint (logtext+strlen(logtext), method->class->name);
989 sprintf (logtext+strlen(logtext), ".");
990 utf_sprint (logtext+strlen(logtext), method->name);
991 utf_sprint (logtext+strlen(logtext), method->descriptor);
996 /****************************************************************************
997 SYNCHRONIZATION FUNCTIONS
998 *****************************************************************************/
1001 * Lock the mutex of an object.
1005 internal_lock_mutex_for_object (java_objectheader *object)
1007 mutexHashEntry *entry;
1010 assert(object != 0);
1012 hashValue = MUTEX_HASH_VALUE(object);
1013 entry = &mutexHashTable[hashValue];
1015 if (entry->object != 0)
1017 if (entry->mutex.count == 0 && entry->conditionCount == 0)
1020 entry->mutex.holder = 0;
1021 entry->mutex.count = 0;
1022 entry->mutex.muxWaiters = 0;
1026 while (entry->next != 0 && entry->object != object)
1027 entry = entry->next;
1029 if (entry->object != object)
1031 entry->next = firstFreeOverflowEntry;
1032 firstFreeOverflowEntry = firstFreeOverflowEntry->next;
1034 entry = entry->next;
1037 assert(entry->conditionCount == 0);
1043 entry->mutex.holder = 0;
1044 entry->mutex.count = 0;
1045 entry->mutex.muxWaiters = 0;
1048 if (entry->object == 0)
1049 entry->object = object;
1051 internal_lock_mutex(&entry->mutex);
1057 * Unlocks the mutex of an object.
1061 internal_unlock_mutex_for_object (java_objectheader *object)
1064 mutexHashEntry *entry;
1066 hashValue = MUTEX_HASH_VALUE(object);
1067 entry = &mutexHashTable[hashValue];
1069 if (entry->object == object)
1070 internal_unlock_mutex(&entry->mutex);
1073 while (entry->next != 0 && entry->next->object != object)
1074 entry = entry->next;
1076 assert(entry->next != 0);
1078 internal_unlock_mutex(&entry->next->mutex);
1080 if (entry->next->mutex.count == 0 && entry->conditionCount == 0)
1082 mutexHashEntry *unlinked = entry->next;
1084 entry->next = unlinked->next;
1085 unlinked->next = firstFreeOverflowEntry;
1086 firstFreeOverflowEntry = unlinked;
1093 builtin_monitorenter (java_objectheader *o)
1098 assert(blockInts == 0);
1102 hashValue = MUTEX_HASH_VALUE(o);
1103 if (mutexHashTable[hashValue].object == o
1104 && mutexHashTable[hashValue].mutex.holder == currentThread)
1105 ++mutexHashTable[hashValue].mutex.count;
1107 internal_lock_mutex_for_object(o);
1111 assert(blockInts == 0);
1115 void builtin_monitorexit (java_objectheader *o)
1120 assert(blockInts == 0);
1124 hashValue = MUTEX_HASH_VALUE(o);
1125 if (mutexHashTable[hashValue].object == o)
1127 if (mutexHashTable[hashValue].mutex.count == 1
1128 && mutexHashTable[hashValue].mutex.muxWaiters != 0)
1129 internal_unlock_mutex_for_object(o);
1131 --mutexHashTable[hashValue].mutex.count;
1134 internal_unlock_mutex_for_object(o);
1138 assert(blockInts == 0);
1143 /*****************************************************************************
1144 MISCELLANEOUS HELPER FUNCTIONS
1145 *****************************************************************************/
1149 /*********** Functions for integer divisions *****************************
1151 On some systems (eg. DEC ALPHA), integer division is not supported by the
1152 CPU. These helper functions implement the missing functionality.
1154 ******************************************************************************/
1156 s4 builtin_idiv (s4 a, s4 b) { return a/b; }
1157 s4 builtin_irem (s4 a, s4 b) { return a%b; }
1160 /************** Functions for long arithmetics *******************************
1162 On systems where 64 bit Integers are not supported by the CPU, these
1163 functions are needed.
1165 ******************************************************************************/
1168 s8 builtin_ladd (s8 a, s8 b)
1173 return builtin_i2l(0);
1177 s8 builtin_lsub (s8 a, s8 b)
1182 return builtin_i2l(0);
1186 s8 builtin_lmul (s8 a, s8 b)
1191 return builtin_i2l(0);
1195 s8 builtin_ldiv (s8 a, s8 b)
1200 return builtin_i2l(0);
1204 s8 builtin_lrem (s8 a, s8 b)
1209 return builtin_i2l(0);
1213 s8 builtin_lshl (s8 a, s4 b)
1218 return builtin_i2l(0);
1222 s8 builtin_lshr (s8 a, s4 b)
1227 return builtin_i2l(0);
1231 s8 builtin_lushr (s8 a, s4 b)
1234 return ((u8)a)>>(b&63);
1236 return builtin_i2l(0);
1240 s8 builtin_land (s8 a, s8 b)
1245 return builtin_i2l(0);
1249 s8 builtin_lor (s8 a, s8 b)
1254 return builtin_i2l(0);
1258 s8 builtin_lxor (s8 a, s8 b)
1263 return builtin_i2l(0);
1267 s8 builtin_lneg (s8 a)
1272 return builtin_i2l(0);
1276 s4 builtin_lcmp (s8 a, s8 b)
1291 /*********** Functions for floating point operations *************************/
1293 float builtin_fadd (float a, float b)
1295 if (isnanf(a)) return FLT_NAN;
1296 if (isnanf(b)) return FLT_NAN;
1298 if (finitef(b)) return a+b;
1302 if (finitef(b)) return a;
1304 if (copysignf(1.0, a)==copysignf(1.0, b)) return a;
1305 else return FLT_NAN;
1310 float builtin_fsub (float a, float b)
1312 return builtin_fadd (a, builtin_fneg(b));
1315 float builtin_fmul (float a, float b)
1317 if (isnanf(a)) return FLT_NAN;
1318 if (isnanf(b)) return FLT_NAN;
1320 if (finitef(b)) return a*b;
1322 if (a==0) return FLT_NAN;
1323 else return copysignf(b, copysignf(1.0, b)*a);
1328 if (b==0) return FLT_NAN;
1329 else return copysignf(a, copysignf(1.0, a)*b);
1332 return copysignf(a, copysignf(1.0, a)*copysignf(1.0, b));
1337 float builtin_fdiv (float a, float b)
1339 if (finitef(a) && finitef(b)) {
1352 float builtin_frem (float a, float b)
1358 float builtin_fneg (float a)
1360 if (isnanf(a)) return a;
1362 if (finitef(a)) return -a;
1363 else return copysignf(a,-copysignf(1.0, a));
1367 s4 builtin_fcmpl (float a, float b)
1369 if (isnanf(a)) return -1;
1370 if (isnanf(b)) return -1;
1371 if (!finitef(a) || !finitef(b)) {
1372 a = finitef(a) ? 0 : copysignf(1.0, a);
1373 b = finitef(b) ? 0 : copysignf(1.0, b);
1380 s4 builtin_fcmpg (float a, float b)
1382 if (isnanf(a)) return 1;
1383 if (isnanf(b)) return 1;
1384 if (!finitef(a) || !finitef(b)) {
1385 a = finitef(a) ? 0 : copysignf(1.0, a);
1386 b = finitef(b) ? 0 : copysignf(1.0, b);
1395 /************************* Functions for doubles ****************************/
1397 double builtin_dadd (double a, double b)
1399 if (isnan(a)) return DBL_NAN;
1400 if (isnan(b)) return DBL_NAN;
1402 if (finite(b)) return a+b;
1406 if (finite(b)) return a;
1408 if (copysign(1.0, a)==copysign(1.0, b)) return a;
1409 else return DBL_NAN;
1414 double builtin_dsub (double a, double b)
1416 return builtin_dadd (a, builtin_dneg(b));
1419 double builtin_dmul (double a, double b)
1421 if (isnan(a)) return DBL_NAN;
1422 if (isnan(b)) return DBL_NAN;
1424 if (finite(b)) return a*b;
1426 if (a==0) return DBL_NAN;
1427 else return copysign(b, copysign(1.0, b)*a);
1432 if (b==0) return DBL_NAN;
1433 else return copysign(a, copysign(1.0, a)*b);
1436 return copysign(a, copysign(1.0, a)*copysign(1.0, b));
1441 double builtin_ddiv (double a, double b)
1443 if (finite(a) && finite(b)) {
1456 double builtin_drem (double a, double b)
1461 double builtin_dneg (double a)
1463 if (isnan(a)) return a;
1465 if (finite(a)) return -a;
1466 else return copysign(a,-copysign(1.0, a));
1470 s4 builtin_dcmpl (double a, double b)
1472 if (isnan(a)) return -1;
1473 if (isnan(b)) return -1;
1474 if (!finite(a) || !finite(b)) {
1475 a = finite(a) ? 0 : copysign(1.0, a);
1476 b = finite(b) ? 0 : copysign(1.0, b);
1483 s4 builtin_dcmpg (double a, double b)
1485 if (isnan(a)) return 1;
1486 if (isnan(b)) return 1;
1487 if (!finite(a) || !finite(b)) {
1488 a = finite(a) ? 0 : copysign(1.0, a);
1489 b = finite(b) ? 0 : copysign(1.0, b);
1497 /*********************** Conversion operations ****************************/
1499 s8 builtin_i2l (s4 i)
1504 s8 v; v.high = 0; v.low=i; return v;
1508 float builtin_i2f (s4 a)
1510 float f = (float) a;
1514 double builtin_i2d (s4 a)
1516 double d = (double) a;
1521 s4 builtin_l2i (s8 l)
1530 float builtin_l2f (s8 a)
1533 float f = (float) a;
1540 double builtin_l2d (s8 a)
1543 double d = (double) a;
1551 s4 builtin_f2i(float a)
1554 return builtin_d2i((double) a);
1563 if (a < (-2147483648))
1564 return (-2147483648);
1567 f = copysignf((float) 1.0, a);
1570 return (-2147483648); */
1574 s8 builtin_f2l (float a)
1577 return builtin_d2l((double) a);
1582 if (a > 9223372036854775807L)
1583 return 9223372036854775807L;
1584 if (a < (-9223372036854775808L))
1585 return (-9223372036854775808L);
1590 f = copysignf((float) 1.0, a);
1592 return 9223372036854775807L;
1593 return (-9223372036854775808L); */
1597 double builtin_f2d (float a)
1599 if (finitef(a)) return (double) a;
1601 if (isnanf(a)) return DBL_NAN;
1602 else return copysign(DBL_POSINF, (double) copysignf(1.0, a) );
1607 s4 builtin_d2i (double a)
1612 if (a >= 2147483647)
1614 if (a <= (-2147483647-1))
1615 return (-2147483647-1);
1620 d = copysign(1.0, a);
1623 return (-2147483647-1);
1627 s8 builtin_d2l (double a)
1632 if (a >= 9223372036854775807L)
1633 return 9223372036854775807L;
1634 if (a <= (-9223372036854775807L-1))
1635 return (-9223372036854775807L-1);
1640 d = copysign(1.0, a);
1642 return 9223372036854775807L;
1643 return (-9223372036854775807L-1);
1647 float builtin_d2f (double a)
1649 if (finite(a)) return (float) a;
1651 if (isnan(a)) return FLT_NAN;
1652 else return copysignf (FLT_POSINF, (float) copysign(1.0, a));
1658 * These are local overrides for various environment variables in Emacs.
1659 * Please do not remove this and leave it at the end of the file, where
1660 * Emacs will automagically detect them.
1661 * ---------------------------------------------------------------------
1664 * indent-tabs-mode: t