1 /* builtin.c - functions for unsupported operations
3 Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
4 R. Grafl, A. Krall, C. Kruegel, C. Oates, R. Obermaisser,
5 M. Probst, S. Ring, E. Steiner, C. Thalinger, D. Thuernbeck,
6 P. Tomsich, J. Wenninger
8 This file is part of CACAO.
10 This program is free software; you can redistribute it and/or
11 modify it under the terms of the GNU General Public License as
12 published by the Free Software Foundation; either version 2, or (at
13 your option) any later version.
15 This program is distributed in the hope that it will be useful, but
16 WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
25 Contact: cacao@complang.tuwien.ac.at
27 Authors: Reinhard Grafl
31 Contains C functions for JavaVM Instructions that cannot be
32 translated to machine language directly. Consequently, the
33 generated machine code for these instructions contains function
34 calls instead of machine instructions, using the C calling
37 $Id: builtin.c 557 2003-11-02 22:51:59Z twisti $
47 #include "threads/thread.h"
48 #include "threads/locks.h"
49 #include "toolbox/loging.h"
51 #include "native-math.h"
54 builtin_descriptor builtin_desc[] = {
55 {(functionptr) builtin_instanceof, "instanceof"},
56 {(functionptr) builtin_checkcast, "checkcast"},
57 {(functionptr) asm_builtin_checkcast, "checkcast"},
58 {(functionptr) builtin_arrayinstanceof, "arrayinstanceof"},
60 {(functionptr) asm_builtin_arrayinstanceof,"arrayinstanceof"},
62 {(functionptr) builtin_checkarraycast, "checkarraycast"},
63 {(functionptr) asm_builtin_checkarraycast, "checkarraycast"},
64 {(functionptr) asm_builtin_aastore, "aastore"},
65 {(functionptr) builtin_new, "new"},
66 {(functionptr) builtin_anewarray, "anewarray"},
67 {(functionptr) builtin_newarray_array, "newarray_array"},
69 /* have 2 parameters (needs stack manipulation) */
70 {(functionptr) asm_builtin_anewarray, "anewarray"},
71 {(functionptr) asm_builtin_newarray_array, "newarray_array"},
73 {(functionptr) builtin_newarray_boolean, "newarray_boolean"},
74 {(functionptr) builtin_newarray_char, "newarray_char"},
75 {(functionptr) builtin_newarray_float, "newarray_float"},
76 {(functionptr) builtin_newarray_double, "newarray_double"},
77 {(functionptr) builtin_newarray_byte, "newarray_byte"},
78 {(functionptr) builtin_newarray_short, "newarray_short"},
79 {(functionptr) builtin_newarray_int, "newarray_int"},
80 {(functionptr) builtin_newarray_long, "newarray_long"},
81 {(functionptr) builtin_displaymethodstart, "displaymethodstart"},
82 {(functionptr) builtin_displaymethodstop, "displaymethodstop"},
83 {(functionptr) builtin_monitorenter, "monitorenter"},
84 {(functionptr) asm_builtin_monitorenter, "monitorenter"},
85 {(functionptr) builtin_monitorexit, "monitorexit"},
86 {(functionptr) asm_builtin_monitorexit, "monitorexit"},
88 {(functionptr) builtin_idiv, "idiv"},
89 {(functionptr) asm_builtin_idiv, "idiv"},
90 {(functionptr) builtin_irem, "irem"},
91 {(functionptr) asm_builtin_irem, "irem"},
93 {(functionptr) builtin_ladd, "ladd"},
94 {(functionptr) builtin_lsub, "lsub"},
95 {(functionptr) builtin_lmul, "lmul"},
96 #if !(SUPPORT_DIVISION && SUPPORT_LONG && SUPPORT_LONG_MULDIV)
97 {(functionptr) builtin_ldiv, "ldiv"},
98 {(functionptr) asm_builtin_ldiv, "ldiv"},
99 {(functionptr) builtin_lrem, "lrem"},
100 {(functionptr) asm_builtin_lrem, "lrem"},
102 {(functionptr) builtin_lshl, "lshl"},
103 {(functionptr) builtin_lshr, "lshr"},
104 {(functionptr) builtin_lushr, "lushr"},
105 {(functionptr) builtin_land, "land"},
106 {(functionptr) builtin_lor, "lor"},
107 {(functionptr) builtin_lxor, "lxor"},
108 {(functionptr) builtin_lneg, "lneg"},
109 {(functionptr) builtin_lcmp, "lcmp"},
110 {(functionptr) builtin_fadd, "fadd"},
111 {(functionptr) builtin_fsub, "fsub"},
112 {(functionptr) builtin_fmul, "fmul"},
113 {(functionptr) builtin_fdiv, "fdiv"},
114 {(functionptr) builtin_frem, "frem"},
115 {(functionptr) builtin_fneg, "fneg"},
116 {(functionptr) builtin_fcmpl, "fcmpl"},
117 {(functionptr) builtin_fcmpg, "fcmpg"},
118 {(functionptr) builtin_dadd, "dadd"},
119 {(functionptr) builtin_dsub, "dsub"},
120 {(functionptr) builtin_dmul, "dmul"},
121 {(functionptr) builtin_ddiv, "ddiv"},
122 {(functionptr) builtin_drem, "drem"},
123 {(functionptr) builtin_dneg, "dneg"},
124 {(functionptr) builtin_dcmpl, "dcmpl"},
125 {(functionptr) builtin_dcmpg, "dcmpg"},
126 {(functionptr) builtin_i2l, "i2l"},
127 {(functionptr) builtin_i2f, "i2f"},
128 {(functionptr) builtin_i2d, "i2d"},
129 {(functionptr) builtin_l2i, "l2i"},
130 {(functionptr) builtin_l2f, "l2f"},
131 {(functionptr) builtin_l2d, "l2d"},
132 {(functionptr) builtin_f2i, "f2i"},
133 {(functionptr) builtin_f2l, "f2l"},
134 {(functionptr) builtin_f2d, "f2d"},
135 {(functionptr) builtin_d2i, "d2i"},
136 {(functionptr) builtin_d2l, "d2l"},
137 #if defined(__I386__)
138 {(functionptr) asm_builtin_f2i, "f2i"},
139 {(functionptr) asm_builtin_f2l, "f2l"},
140 {(functionptr) asm_builtin_d2i, "d2i"},
141 {(functionptr) asm_builtin_d2l, "d2l"},
143 {(functionptr) builtin_d2f, "d2f"},
144 {(functionptr) NULL, "unknown"}
148 /*****************************************************************************
150 *****************************************************************************/
154 /*************** internal function: builtin_isanysubclass *********************
156 Checks a subclass relation between two classes. Implemented interfaces
157 are interpreted as super classes.
158 Return value: 1 ... sub is subclass of super
161 *****************************************************************************/
163 s4 builtin_isanysubclass (classinfo *sub, classinfo *super)
165 if (super->flags & ACC_INTERFACE)
166 return (sub->vftbl->interfacetablelength > super->index) &&
167 (sub->vftbl->interfacetable[-super->index] != NULL);
179 return (unsigned) (sub->vftbl->baseval - super->vftbl->baseval) <=
180 (unsigned) (super->vftbl->diffval);
184 /****************** function: builtin_instanceof *****************************
186 Checks if an object is an instance of some given class (or subclass of
187 that class). If class is an interface, checks if the interface is
189 Return value: 1 ... obj is an instance of class or implements the interface
190 0 ... otherwise or if obj == NULL
192 *****************************************************************************/
194 s4 builtin_instanceof(java_objectheader *obj, classinfo *class)
197 log_text ("builtin_instanceof called");
201 return builtin_isanysubclass (obj->vftbl->class, class);
206 /**************** function: builtin_checkcast *******************************
208 The same as builtin_instanceof except that 1 is returned when
211 ****************************************************************************/
213 s4 builtin_checkcast(java_objectheader *obj, classinfo *class)
216 log_text ("builtin_checkcast called");
221 if (builtin_isanysubclass (obj->vftbl->class, class))
225 printf ("#### checkcast failed ");
226 utf_display (obj->vftbl->class->name);
228 utf_display (class->name);
236 /*********** internal function: builtin_descriptorscompatible ******************
238 Checks if two array type descriptors are assignment compatible
239 Return value: 1 ... target = desc is possible
242 ******************************************************************************/
244 static s4 builtin_descriptorscompatible(constant_arraydescriptor *desc, constant_arraydescriptor *target)
246 if (desc==target) return 1;
247 if (desc->arraytype != target->arraytype) return 0;
248 switch (target->arraytype) {
249 case ARRAYTYPE_OBJECT:
250 return builtin_isanysubclass (desc->objectclass, target->objectclass);
251 case ARRAYTYPE_ARRAY:
252 return builtin_descriptorscompatible
253 (desc->elementdescriptor, target->elementdescriptor);
260 /******************** function: builtin_checkarraycast ***********************
262 Checks if an object is really a subtype of the requested array type.
263 The object has to be an array to begin with. For simple arrays (int, short,
264 double, etc.) the types have to match exactly.
265 For arrays of objects, the type of elements in the array has to be a
266 subtype (or the same type) of the requested element type. For arrays of
267 arrays (which in turn can again be arrays of arrays), the types at the
268 lowest level have to satisfy the corresponding sub class relation.
270 Return value: 1 ... cast is possible
273 ATTENTION: a cast with a NULL pointer is always possible.
275 *****************************************************************************/
277 s4 builtin_checkarraycast(java_objectheader *o, constant_arraydescriptor *desc)
279 java_arrayheader *a = (java_arrayheader*) o;
282 if (o->vftbl->class != class_array) {
284 printf ("#### checkarraycast failed 1\n");
289 if (a->arraytype != desc->arraytype) {
291 printf ("#### checkarraycast failed 2\n");
296 switch (a->arraytype) {
297 case ARRAYTYPE_OBJECT: {
298 java_objectarray *oa = (java_objectarray*) o;
299 int result = builtin_isanysubclass (oa->elementtype, desc->objectclass);
303 printf ("#### checkarraycast failed 3\n");
307 case ARRAYTYPE_ARRAY: {
308 java_arrayarray *aa = (java_arrayarray*) o;
309 int result = builtin_descriptorscompatible
310 (aa->elementdescriptor, desc->elementdescriptor);
314 printf ("#### checkarraycast failed 4\n");
324 s4 builtin_arrayinstanceof(java_objectheader *obj, constant_arraydescriptor *desc)
327 return builtin_checkarraycast (obj, desc);
331 /************************** exception functions *******************************
333 ******************************************************************************/
335 java_objectheader *builtin_throw_exception (java_objectheader *local_exceptionptr) {
337 sprintf(logtext, "Builtin exception thrown: ");
338 utf_sprint(logtext + strlen(logtext), local_exceptionptr->vftbl->class->name);
341 exceptionptr = local_exceptionptr;
342 return local_exceptionptr;
346 /******************* function: builtin_canstore *******************************
348 Checks, if an object can be stored in an array.
349 Return value: 1 ... possible
352 ******************************************************************************/
355 s4 builtin_canstore (java_objectarray *a, java_objectheader *o)
359 switch (a->header.arraytype) {
360 case ARRAYTYPE_OBJECT:
361 if ( ! builtin_checkcast (o, a->elementtype) ) {
367 case ARRAYTYPE_ARRAY:
368 if ( ! builtin_checkarraycast
369 (o, ((java_arrayarray*)a)->elementdescriptor) ) {
376 panic ("builtin_canstore called with invalid arraytype");
383 /*****************************************************************************
385 *****************************************************************************/
389 /******************** Function: builtin_new **********************************
391 Creates a new instance of class c on the heap.
392 Return value: pointer to the object or NULL if no memory is
395 *****************************************************************************/
398 #define align_size(size) ((size + ((1 << ALIGNMENT) - 1)) & ~((1 << ALIGNMENT) - 1))
400 java_objectheader *builtin_new(classinfo *c)
402 java_objectheader *o;
406 #ifdef SIZE_FROM_CLASSINFO
407 c->alignedsize = align_size(c->instancesize);
408 o = heap_allocate(c->alignedsize, true, c->finalizer);
410 o = heap_allocate(c->instancesize, true, c->finalizer);
414 memset(o, 0, c->instancesize);
423 /******************** function: builtin_anewarray ****************************
425 Creates an array of pointers to objects on the heap.
427 size ......... number of elements
428 elementtype .. pointer to the classinfo structure for the element type
430 Return value: pointer to the array or NULL if no memory is available
432 *****************************************************************************/
434 void XXX_copy_vftbl(vftbl **dest, vftbl *src)
436 *dest = mem_alloc(sizeof(vftbl) + sizeof(methodptr)*(src->vftbllength-1));
437 memcpy(*dest, src, sizeof(vftbl) - sizeof(methodptr));
438 memcpy(&(*dest)->table, &src->table, src->vftbllength * sizeof(methodptr));
441 void XXX_use_class_as_object(classinfo *c, char *cname)
443 vftbl *vt = class_get(utf_new_char(cname))->vftbl;
445 if (!c->classvftbl) {
446 c->classvftbl = true;
447 XXX_copy_vftbl(&newtbl, vt);
448 newtbl->class = c->header.vftbl->class;
449 newtbl->baseval = c->header.vftbl->baseval;
450 newtbl->diffval = c->header.vftbl->diffval;
451 c->header.vftbl = newtbl;
456 void* __builtin_newarray(s4 base_size,
465 #ifdef SIZE_FROM_CLASSINFO
466 s4 alignedsize = align_size(base_size + (size-1) * elementsize);
467 a = heap_allocate( alignedsize, references, NULL );
469 a = heap_allocate(sizeof(java_objectarray) + (size-1) * elementsize,
475 #ifdef SIZE_FROM_CLASSINFO
476 memset(a, 0, alignedsize);
478 memset(a, 0, base_size + (size-1) * elementsize);
487 c = create_array_class(utf_new_char("[I"));
488 XXX_use_class_as_object(c, "int");
492 c = create_array_class(utf_new_char("[J"));
493 XXX_use_class_as_object(c, "long");
496 case ARRAYTYPE_FLOAT:
497 c = create_array_class(utf_new_char("[F"));
498 XXX_use_class_as_object(c, "float");
501 case ARRAYTYPE_DOUBLE:
502 c = create_array_class(utf_new_char("[D"));
503 XXX_use_class_as_object(c, "double");
507 c = create_array_class(utf_new_char("[B"));
508 XXX_use_class_as_object(c, "byte");
512 c = create_array_class(utf_new_char("[C"));
513 XXX_use_class_as_object(c, "char");
516 case ARRAYTYPE_SHORT:
517 c = create_array_class(utf_new_char("[S"));
518 XXX_use_class_as_object(c, "short");
521 case ARRAYTYPE_BOOLEAN:
522 c = create_array_class(utf_new_char("[Z"));
523 XXX_use_class_as_object(c, "boolean");
526 case ARRAYTYPE_OBJECT:
529 cname = heap_allocate(utf_strlen(el->name), false, NULL);
530 utf_sprint(cname, el->name);
531 buf = heap_allocate(strlen(cname) + 3, false, NULL);
532 /* printf("\n\n[L%s;\n\n", cname); */
533 sprintf(buf, "[L%s;", cname);
534 c = create_array_class(utf_new_char(buf));
535 /* MFREE(buf, char, strlen(cname) + 3); */
536 /* MFREE(cname, char, utf_strlen(el->name)); */
537 XXX_use_class_as_object(c, cname);
541 case ARRAYTYPE_ARRAY:
542 c = create_array_class(utf_new_char("[["));
543 XXX_use_class_as_object(c, "java/lang/Boolean");
547 panic("unknown array type");
550 a->objheader.vftbl = c->vftbl;
553 a->objheader.vftbl = class_array->vftbl;
556 #ifdef SIZE_FROM_CLASSINFO
557 a -> alignedsize = alignedsize;
559 a -> arraytype = arraytype;
565 java_objectarray *builtin_anewarray (s4 size, classinfo *elementtype)
568 a = (java_objectarray*)__builtin_newarray(sizeof(java_objectarray),
576 a -> elementtype = elementtype;
582 /******************** function: builtin_newarray_array ***********************
584 Creates an array of pointers to arrays on the heap.
586 size ......... number of elements
587 elementdesc .. pointer to the array description structure for the
590 Return value: pointer to the array or NULL if no memory is available
592 *****************************************************************************/
594 java_arrayarray *builtin_newarray_array
595 (s4 size, constant_arraydescriptor *elementdesc)
598 a = (java_arrayarray*)__builtin_newarray(sizeof(java_arrayarray),
603 elementdesc->objectclass);
606 a -> elementdescriptor = elementdesc;
611 /******************** function: builtin_newarray_boolean ************************
613 Creates an array of bytes on the heap. The array is designated as an array
614 of booleans (important for casts)
616 Return value: pointer to the array or NULL if no memory is available
618 *****************************************************************************/
620 java_booleanarray *builtin_newarray_boolean (s4 size)
622 java_booleanarray *a;
623 a = (java_booleanarray*)__builtin_newarray(sizeof(java_booleanarray),
632 /******************** function: builtin_newarray_char ************************
634 Creates an array of characters on the heap.
636 Return value: pointer to the array or NULL if no memory is available
638 *****************************************************************************/
640 java_chararray *builtin_newarray_char (s4 size)
643 a = (java_chararray*)__builtin_newarray(sizeof(java_chararray),
653 /******************** function: builtin_newarray_float ***********************
655 Creates an array of 32 bit IEEE floats on the heap.
657 Return value: pointer to the array or NULL if no memory is available
659 *****************************************************************************/
661 java_floatarray *builtin_newarray_float (s4 size)
664 a = (java_floatarray*)__builtin_newarray(sizeof(java_floatarray),
674 /******************** function: builtin_newarray_double ***********************
676 Creates an array of 64 bit IEEE floats on the heap.
678 Return value: pointer to the array or NULL if no memory is available
680 *****************************************************************************/
682 java_doublearray *builtin_newarray_double (s4 size)
685 a = (java_doublearray*)__builtin_newarray(sizeof(java_doublearray),
697 /******************** function: builtin_newarray_byte ***********************
699 Creates an array of 8 bit Integers on the heap.
701 Return value: pointer to the array or NULL if no memory is available
703 *****************************************************************************/
705 java_bytearray *builtin_newarray_byte (s4 size)
708 a = (java_bytearray*)__builtin_newarray(sizeof(java_bytearray),
718 /******************** function: builtin_newarray_short ***********************
720 Creates an array of 16 bit Integers on the heap.
722 Return value: pointer to the array or NULL if no memory is available
724 *****************************************************************************/
726 java_shortarray *builtin_newarray_short (s4 size)
729 a = (java_shortarray*)__builtin_newarray(sizeof(java_shortarray),
739 /******************** Function: builtin_newarray_int ***********************
741 Creates an array of 32 bit Integers on the heap.
743 Return value: pointer to the array or NULL if no memory is available
745 *****************************************************************************/
747 java_intarray *builtin_newarray_int (s4 size)
750 a = (java_intarray*)__builtin_newarray(sizeof(java_intarray),
760 /******************** Function: builtin_newarray_long ***********************
762 Creates an array of 64 bit Integers on the heap.
764 Return value: pointer to the array or NULL if no memory is available
766 *****************************************************************************/
768 java_longarray *builtin_newarray_long (s4 size)
771 a = (java_longarray*)__builtin_newarray(sizeof(java_longarray),
782 /***************** function: builtin_multianewarray ***************************
784 Creates a multi-dimensional array on the heap. The dimensions are passed in
785 an array of Integers. The type for the array is passed as a reference to a
786 constant_arraydescriptor structure.
788 Return value: pointer to the array or NULL if no memory is available
790 ******************************************************************************/
792 /* Helper functions */
794 static java_arrayheader *multianewarray_part (java_intarray *dims, int thisdim,
795 constant_arraydescriptor *desc)
800 size = dims -> data[thisdim];
802 if (thisdim == (dims->header.size-1)) {
803 /* last dimension reached */
805 switch (desc -> arraytype) {
806 case ARRAYTYPE_BOOLEAN:
807 return (java_arrayheader*) builtin_newarray_boolean (size);
809 return (java_arrayheader*) builtin_newarray_char (size);
810 case ARRAYTYPE_FLOAT:
811 return (java_arrayheader*) builtin_newarray_float (size);
812 case ARRAYTYPE_DOUBLE:
813 return (java_arrayheader*) builtin_newarray_double (size);
815 return (java_arrayheader*) builtin_newarray_byte (size);
816 case ARRAYTYPE_SHORT:
817 return (java_arrayheader*) builtin_newarray_short (size);
819 return (java_arrayheader*) builtin_newarray_int (size);
821 return (java_arrayheader*) builtin_newarray_long (size);
822 case ARRAYTYPE_OBJECT:
823 return (java_arrayheader*) builtin_anewarray (size, desc->objectclass);
825 case ARRAYTYPE_ARRAY:
826 return (java_arrayheader*) builtin_newarray_array (size, desc->elementdescriptor);
828 default: panic ("Invalid arraytype in multianewarray");
832 /* if the last dimension has not been reached yet */
834 if (desc->arraytype != ARRAYTYPE_ARRAY)
835 panic ("multianewarray with too many dimensions");
837 a = builtin_newarray_array (size, desc->elementdescriptor);
840 for (i=0; i<size; i++) {
841 java_arrayheader *ea =
842 multianewarray_part (dims, thisdim+1, desc->elementdescriptor);
843 if (!ea) return NULL;
848 return (java_arrayheader*) a;
852 java_arrayheader *builtin_multianewarray (java_intarray *dims,
853 constant_arraydescriptor *desc)
855 return multianewarray_part (dims, 0, desc);
859 static java_arrayheader *nmultianewarray_part (int n, long *dims, int thisdim,
860 constant_arraydescriptor *desc)
865 size = (int) dims[thisdim];
867 if (thisdim == (n - 1)) {
868 /* last dimension reached */
870 switch (desc -> arraytype) {
871 case ARRAYTYPE_BOOLEAN:
872 return (java_arrayheader*) builtin_newarray_boolean(size);
874 return (java_arrayheader*) builtin_newarray_char(size);
875 case ARRAYTYPE_FLOAT:
876 return (java_arrayheader*) builtin_newarray_float(size);
877 case ARRAYTYPE_DOUBLE:
878 return (java_arrayheader*) builtin_newarray_double(size);
880 return (java_arrayheader*) builtin_newarray_byte(size);
881 case ARRAYTYPE_SHORT:
882 return (java_arrayheader*) builtin_newarray_short(size);
884 return (java_arrayheader*) builtin_newarray_int(size);
886 return (java_arrayheader*) builtin_newarray_long(size);
887 case ARRAYTYPE_OBJECT:
888 return (java_arrayheader*) builtin_anewarray(size,
890 case ARRAYTYPE_ARRAY:
891 return (java_arrayheader*) builtin_newarray_array(size,
892 desc->elementdescriptor);
894 default: panic ("Invalid arraytype in multianewarray");
898 /* if the last dimension has not been reached yet */
900 if (desc->arraytype != ARRAYTYPE_ARRAY)
901 panic ("multianewarray with too many dimensions");
903 a = builtin_newarray_array(size, desc->elementdescriptor);
906 for (i = 0; i < size; i++) {
907 java_arrayheader *ea =
908 nmultianewarray_part(n, dims, thisdim + 1, desc->elementdescriptor);
909 if (!ea) return NULL;
914 return (java_arrayheader*) a;
918 java_arrayheader *builtin_nmultianewarray (int size,
919 constant_arraydescriptor *desc, long *dims)
921 (void) builtin_newarray_int(size); /* for compatibility with -old */
922 return nmultianewarray_part (size, dims, 0, desc);
928 /************************* function: builtin_aastore *************************
930 Stores a reference to an object into an object array or into an array
931 array. Before any action is performed, the validity of the operation is
934 Return value: 1 ... ok
935 0 ... this object cannot be stored into this array
937 *****************************************************************************/
939 s4 builtin_aastore (java_objectarray *a, s4 index, java_objectheader *o)
941 if (builtin_canstore(a,o)) {
953 /*****************************************************************************
956 Various functions for printing a message at method entry or exit (for
959 *****************************************************************************/
964 java_objectheader *builtin_trace_exception (java_objectheader *exceptionptr,
965 methodinfo *method, int *pos, int noindent) {
969 if (verbose || runverbose) {
970 printf("Exception ");
971 utf_display (exceptionptr->vftbl->class->name);
972 printf(" thrown in ");
974 utf_display (method->class->name);
976 utf_display (method->name);
977 if (method->flags & ACC_SYNCHRONIZED)
981 printf("(%p) at position %p\n", method->entrypoint, pos);
984 printf("call_java_method\n");
991 #ifdef TRACE_ARGS_NUM
992 void builtin_trace_args(s8 a0, s8 a1, s8 a2, s8 a3, s8 a4, s8 a5,
993 #if TRACE_ARGS_NUM > 6
999 for (i=0; i<methodindent; i++)
1001 sprintf (logtext+methodindent, "called: ");
1002 utf_sprint (logtext+strlen(logtext), method->class->name);
1003 sprintf (logtext+strlen(logtext), ".");
1004 utf_sprint (logtext+strlen(logtext), method->name);
1005 utf_sprint (logtext+strlen(logtext), method->descriptor);
1006 sprintf (logtext+strlen(logtext), "(");
1007 switch (method->paramcount) {
1011 #if defined(__I386__)
1013 sprintf(logtext+strlen(logtext), "%llx", a0);
1017 sprintf(logtext+strlen(logtext), "%llx, %llx", a0, a1);
1021 sprintf(logtext+strlen(logtext), "%llx, %llx, %llx", a0, a1, a2);
1025 sprintf(logtext+strlen(logtext), "%llx, %llx, %llx, %llx",
1030 sprintf(logtext+strlen(logtext), "%llx, %llx, %llx, %llx, %llx",
1031 a0, a1, a2, a3, a4);
1035 sprintf(logtext+strlen(logtext), "%llx, %llx, %llx, %llx, %llx, %llx",
1036 a0, a1, a2, a3, a4, a5);
1039 #if TRACE_ARGS_NUM > 6
1041 sprintf(logtext+strlen(logtext), "%llx, %llx, %llx, %llx, %llx, %llx, %llx",
1042 a0, a1, a2, a3, a4, a5, a6);
1046 sprintf(logtext+strlen(logtext), "%llx, %llx, %llx, %llx, %llx, %llx, %llx, %llx",
1047 a0, a1, a2, a3, a4, a5, a6, a7);
1051 sprintf(logtext+strlen(logtext), "%llx, %llx, %llx, %llx, %llx, %llx, %llx, %llx, ...(%d)",
1052 a0, a1, a2, a3, a4, a5, a6, a7, method->paramcount - 8);
1056 sprintf(logtext+strlen(logtext), "%llx, %llx, %llx, %llx, %llx, %llx, ...(%d)",
1057 a0, a1, a2, a3, a4, a5, method->paramcount - 6);
1062 sprintf(logtext+strlen(logtext), "%lx", a0);
1066 sprintf(logtext+strlen(logtext), "%lx, %lx", a0, a1);
1070 sprintf(logtext+strlen(logtext), "%lx, %lx, %lx", a0, a1, a2);
1074 sprintf(logtext+strlen(logtext), "%lx, %lx, %lx, %lx",
1079 sprintf(logtext+strlen(logtext), "%lx, %lx, %lx, %lx, %lx",
1080 a0, a1, a2, a3, a4);
1084 sprintf(logtext+strlen(logtext), "%lx, %lx, %lx, %lx, %lx, %lx",
1085 a0, a1, a2, a3, a4, a5);
1088 #if TRACE_ARGS_NUM > 6
1090 sprintf(logtext+strlen(logtext), "%lx, %lx, %lx, %lx, %lx, %lx, %lx",
1091 a0, a1, a2, a3, a4, a5, a6);
1095 sprintf(logtext+strlen(logtext), "%lx, %lx, %lx, %lx, %lx, %lx, %lx, %lx",
1096 a0, a1, a2, a3, a4, a5, a6, a7);
1100 sprintf(logtext+strlen(logtext), "%lx, %lx, %lx, %lx, %lx, %lx, %lx, %lx, ...(%d)",
1101 a0, a1, a2, a3, a4, a5, a6, a7, method->paramcount - 8);
1105 sprintf(logtext+strlen(logtext), "%lx, %lx, %lx, %lx, %lx, %lx, ...(%d)",
1106 a0, a1, a2, a3, a4, a5, method->paramcount - 6);
1111 sprintf (logtext+strlen(logtext), ")");
1118 void builtin_displaymethodstart(methodinfo *method)
1120 sprintf (logtext, " ");
1121 sprintf (logtext+methodindent, "called: ");
1122 utf_sprint (logtext+strlen(logtext), method->class->name);
1123 sprintf (logtext+strlen(logtext), ".");
1124 utf_sprint (logtext+strlen(logtext), method->name);
1125 utf_sprint (logtext+strlen(logtext), method->descriptor);
1130 void builtin_displaymethodstop(methodinfo *method, s8 l, double d, float f)
1133 for (i=0; i<methodindent; i++)
1136 sprintf (logtext+methodindent, "finished: ");
1137 utf_sprint (logtext+strlen(logtext), method->class->name);
1138 sprintf (logtext+strlen(logtext), ".");
1139 utf_sprint (logtext+strlen(logtext), method->name);
1140 utf_sprint (logtext+strlen(logtext), method->descriptor);
1141 switch (method->returntype) {
1143 sprintf (logtext+strlen(logtext), "->%d", (s4) l);
1146 #if defined(__I386__)
1147 sprintf(logtext+strlen(logtext), "->%lld", (s8) l);
1149 sprintf(logtext+strlen(logtext), "->%ld", (s8) l);
1153 #if defined(__I386__)
1154 sprintf(logtext+strlen(logtext), "->%p", (u1*) ((s4) l));
1156 sprintf(logtext+strlen(logtext), "->%p", (u1*) l);
1160 sprintf (logtext+strlen(logtext), "->%g", f);
1163 sprintf (logtext+strlen(logtext), "->%g", d);
1169 void builtin_displaymethodexception(methodinfo *method)
1172 for (i=0; i<methodindent; i++)
1174 sprintf (logtext+methodindent, "exception abort: ");
1175 utf_sprint (logtext+strlen(logtext), method->class->name);
1176 sprintf (logtext+strlen(logtext), ".");
1177 utf_sprint (logtext+strlen(logtext), method->name);
1178 utf_sprint (logtext+strlen(logtext), method->descriptor);
1183 /****************************************************************************
1184 SYNCHRONIZATION FUNCTIONS
1185 *****************************************************************************/
1188 * Lock the mutex of an object.
1192 internal_lock_mutex_for_object (java_objectheader *object)
1194 mutexHashEntry *entry;
1197 assert(object != 0);
1199 hashValue = MUTEX_HASH_VALUE(object);
1200 entry = &mutexHashTable[hashValue];
1202 if (entry->object != 0)
1204 if (entry->mutex.count == 0 && entry->conditionCount == 0)
1207 entry->mutex.holder = 0;
1208 entry->mutex.count = 0;
1209 entry->mutex.muxWaiters = 0;
1213 while (entry->next != 0 && entry->object != object)
1214 entry = entry->next;
1216 if (entry->object != object)
1218 entry->next = firstFreeOverflowEntry;
1219 firstFreeOverflowEntry = firstFreeOverflowEntry->next;
1221 entry = entry->next;
1224 assert(entry->conditionCount == 0);
1230 entry->mutex.holder = 0;
1231 entry->mutex.count = 0;
1232 entry->mutex.muxWaiters = 0;
1235 if (entry->object == 0)
1236 entry->object = object;
1238 internal_lock_mutex(&entry->mutex);
1244 * Unlocks the mutex of an object.
1248 internal_unlock_mutex_for_object (java_objectheader *object)
1251 mutexHashEntry *entry;
1253 hashValue = MUTEX_HASH_VALUE(object);
1254 entry = &mutexHashTable[hashValue];
1256 if (entry->object == object)
1257 internal_unlock_mutex(&entry->mutex);
1260 while (entry->next != 0 && entry->next->object != object)
1261 entry = entry->next;
1263 assert(entry->next != 0);
1265 internal_unlock_mutex(&entry->next->mutex);
1267 if (entry->next->mutex.count == 0 && entry->conditionCount == 0)
1269 mutexHashEntry *unlinked = entry->next;
1271 entry->next = unlinked->next;
1272 unlinked->next = firstFreeOverflowEntry;
1273 firstFreeOverflowEntry = unlinked;
1280 builtin_monitorenter (java_objectheader *o)
1285 assert(blockInts == 0);
1289 hashValue = MUTEX_HASH_VALUE(o);
1290 if (mutexHashTable[hashValue].object == o
1291 && mutexHashTable[hashValue].mutex.holder == currentThread)
1292 ++mutexHashTable[hashValue].mutex.count;
1294 internal_lock_mutex_for_object(o);
1298 assert(blockInts == 0);
1302 void builtin_monitorexit (java_objectheader *o)
1307 assert(blockInts == 0);
1311 hashValue = MUTEX_HASH_VALUE(o);
1312 if (mutexHashTable[hashValue].object == o)
1314 if (mutexHashTable[hashValue].mutex.count == 1
1315 && mutexHashTable[hashValue].mutex.muxWaiters != 0)
1316 internal_unlock_mutex_for_object(o);
1318 --mutexHashTable[hashValue].mutex.count;
1321 internal_unlock_mutex_for_object(o);
1325 assert(blockInts == 0);
1330 /*****************************************************************************
1331 MISCELLANEOUS HELPER FUNCTIONS
1332 *****************************************************************************/
1336 /*********** Functions for integer divisions *****************************
1338 On some systems (eg. DEC ALPHA), integer division is not supported by the
1339 CPU. These helper functions implement the missing functionality.
1341 ******************************************************************************/
1343 s4 builtin_idiv (s4 a, s4 b) { return a/b; }
1344 s4 builtin_irem (s4 a, s4 b) { return a%b; }
1347 /************** Functions for long arithmetics *******************************
1349 On systems where 64 bit Integers are not supported by the CPU, these
1350 functions are needed.
1352 ******************************************************************************/
1355 s8 builtin_ladd (s8 a, s8 b)
1360 return builtin_i2l(0);
1364 s8 builtin_lsub (s8 a, s8 b)
1369 return builtin_i2l(0);
1373 s8 builtin_lmul (s8 a, s8 b)
1378 return builtin_i2l(0);
1382 s8 builtin_ldiv (s8 a, s8 b)
1387 return builtin_i2l(0);
1391 s8 builtin_lrem (s8 a, s8 b)
1396 return builtin_i2l(0);
1400 s8 builtin_lshl (s8 a, s4 b)
1405 return builtin_i2l(0);
1409 s8 builtin_lshr (s8 a, s4 b)
1414 return builtin_i2l(0);
1418 s8 builtin_lushr (s8 a, s4 b)
1421 return ((u8)a)>>(b&63);
1423 return builtin_i2l(0);
1427 s8 builtin_land (s8 a, s8 b)
1432 return builtin_i2l(0);
1436 s8 builtin_lor (s8 a, s8 b)
1441 return builtin_i2l(0);
1445 s8 builtin_lxor (s8 a, s8 b)
1450 return builtin_i2l(0);
1454 s8 builtin_lneg (s8 a)
1459 return builtin_i2l(0);
1463 s4 builtin_lcmp (s8 a, s8 b)
1478 /*********** Functions for floating point operations *************************/
1480 float builtin_fadd (float a, float b)
1482 if (isnanf(a)) return FLT_NAN;
1483 if (isnanf(b)) return FLT_NAN;
1485 if (finitef(b)) return a+b;
1489 if (finitef(b)) return a;
1491 if (copysignf(1.0, a)==copysignf(1.0, b)) return a;
1492 else return FLT_NAN;
1497 float builtin_fsub (float a, float b)
1499 return builtin_fadd (a, builtin_fneg(b));
1502 float builtin_fmul (float a, float b)
1504 if (isnanf(a)) return FLT_NAN;
1505 if (isnanf(b)) return FLT_NAN;
1507 if (finitef(b)) return a*b;
1509 if (a==0) return FLT_NAN;
1510 else return copysignf(b, copysignf(1.0, b)*a);
1515 if (b==0) return FLT_NAN;
1516 else return copysignf(a, copysignf(1.0, a)*b);
1519 return copysignf(a, copysignf(1.0, a)*copysignf(1.0, b));
1524 float builtin_fdiv (float a, float b)
1526 if (finitef(a) && finitef(b)) {
1539 float builtin_frem (float a, float b)
1545 float builtin_fneg (float a)
1547 if (isnanf(a)) return a;
1549 if (finitef(a)) return -a;
1550 else return copysignf(a,-copysignf(1.0, a));
1554 s4 builtin_fcmpl (float a, float b)
1556 if (isnanf(a)) return -1;
1557 if (isnanf(b)) return -1;
1558 if (!finitef(a) || !finitef(b)) {
1559 a = finitef(a) ? 0 : copysignf(1.0, a);
1560 b = finitef(b) ? 0 : copysignf(1.0, b);
1567 s4 builtin_fcmpg (float a, float b)
1569 if (isnanf(a)) return 1;
1570 if (isnanf(b)) return 1;
1571 if (!finitef(a) || !finitef(b)) {
1572 a = finitef(a) ? 0 : copysignf(1.0, a);
1573 b = finitef(b) ? 0 : copysignf(1.0, b);
1582 /************************* Functions for doubles ****************************/
1584 double builtin_dadd (double a, double b)
1586 if (isnan(a)) return DBL_NAN;
1587 if (isnan(b)) return DBL_NAN;
1589 if (finite(b)) return a+b;
1593 if (finite(b)) return a;
1595 if (copysign(1.0, a)==copysign(1.0, b)) return a;
1596 else return DBL_NAN;
1601 double builtin_dsub (double a, double b)
1603 return builtin_dadd (a, builtin_dneg(b));
1606 double builtin_dmul (double a, double b)
1608 if (isnan(a)) return DBL_NAN;
1609 if (isnan(b)) return DBL_NAN;
1611 if (finite(b)) return a*b;
1613 if (a==0) return DBL_NAN;
1614 else return copysign(b, copysign(1.0, b)*a);
1619 if (b==0) return DBL_NAN;
1620 else return copysign(a, copysign(1.0, a)*b);
1623 return copysign(a, copysign(1.0, a)*copysign(1.0, b));
1628 double builtin_ddiv (double a, double b)
1630 if (finite(a) && finite(b)) {
1643 double builtin_drem (double a, double b)
1648 double builtin_dneg (double a)
1650 if (isnan(a)) return a;
1652 if (finite(a)) return -a;
1653 else return copysign(a,-copysign(1.0, a));
1657 s4 builtin_dcmpl (double a, double b)
1659 if (isnan(a)) return -1;
1660 if (isnan(b)) return -1;
1661 if (!finite(a) || !finite(b)) {
1662 a = finite(a) ? 0 : copysign(1.0, a);
1663 b = finite(b) ? 0 : copysign(1.0, b);
1670 s4 builtin_dcmpg (double a, double b)
1672 if (isnan(a)) return 1;
1673 if (isnan(b)) return 1;
1674 if (!finite(a) || !finite(b)) {
1675 a = finite(a) ? 0 : copysign(1.0, a);
1676 b = finite(b) ? 0 : copysign(1.0, b);
1684 /*********************** Conversion operations ****************************/
1686 s8 builtin_i2l (s4 i)
1691 s8 v; v.high = 0; v.low=i; return v;
1695 float builtin_i2f (s4 a)
1697 float f = (float) a;
1701 double builtin_i2d (s4 a)
1703 double d = (double) a;
1708 s4 builtin_l2i (s8 l)
1717 float builtin_l2f (s8 a)
1720 float f = (float) a;
1727 double builtin_l2d (s8 a)
1730 double d = (double) a;
1738 s4 builtin_f2i(float a)
1741 return builtin_d2i((double) a);
1750 if (a < (-2147483648))
1751 return (-2147483648);
1754 f = copysignf((float) 1.0, a);
1757 return (-2147483648); */
1761 s8 builtin_f2l (float a)
1764 return builtin_d2l((double) a);
1769 if (a > 9223372036854775807L)
1770 return 9223372036854775807L;
1771 if (a < (-9223372036854775808L))
1772 return (-9223372036854775808L);
1777 f = copysignf((float) 1.0, a);
1779 return 9223372036854775807L;
1780 return (-9223372036854775808L); */
1784 double builtin_f2d (float a)
1786 if (finitef(a)) return (double) a;
1788 if (isnanf(a)) return DBL_NAN;
1789 else return copysign(DBL_POSINF, (double) copysignf(1.0, a) );
1794 s4 builtin_d2i (double a)
1799 if (a >= 2147483647)
1801 if (a <= (-2147483647-1))
1802 return (-2147483647-1);
1807 d = copysign(1.0, a);
1810 return (-2147483647-1);
1814 s8 builtin_d2l (double a)
1819 if (a >= 9223372036854775807LL)
1820 return 9223372036854775807LL;
1821 if (a <= (-9223372036854775807LL-1))
1822 return (-9223372036854775807LL-1);
1827 d = copysign(1.0, a);
1829 return 9223372036854775807LL;
1830 return (-9223372036854775807LL-1);
1834 float builtin_d2f (double a)
1836 if (finite(a)) return (float) a;
1838 if (isnan(a)) return FLT_NAN;
1839 else return copysignf (FLT_POSINF, (float) copysign(1.0, a));
1845 * These are local overrides for various environment variables in Emacs.
1846 * Please do not remove this and leave it at the end of the file, where
1847 * Emacs will automagically detect them.
1848 * ---------------------------------------------------------------------
1851 * indent-tabs-mode: t