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 624 2003-11-13 14:06:52Z twisti $
51 #include "threads/thread.h"
52 #include "threads/locks.h"
53 #include "toolbox/loging.h"
54 #include "toolbox/memory.h"
56 #include "native-math.h"
59 builtin_descriptor builtin_desc[] = {
60 {(functionptr) builtin_instanceof, "instanceof"},
61 {(functionptr) builtin_checkcast, "checkcast"},
62 {(functionptr) asm_builtin_checkcast, "checkcast"},
63 {(functionptr) builtin_arrayinstanceof, "arrayinstanceof"},
65 {(functionptr) asm_builtin_arrayinstanceof,"arrayinstanceof"},
67 {(functionptr) builtin_checkarraycast, "checkarraycast"},
68 {(functionptr) asm_builtin_checkarraycast, "checkarraycast"},
69 {(functionptr) asm_builtin_aastore, "aastore"},
70 {(functionptr) builtin_new, "new"},
71 {(functionptr) builtin_anewarray, "anewarray"},
72 {(functionptr) builtin_newarray_array, "newarray_array"},
74 /* have 2 parameters (needs stack manipulation) */
75 {(functionptr) asm_builtin_anewarray, "anewarray"},
76 {(functionptr) asm_builtin_newarray_array, "newarray_array"},
78 {(functionptr) builtin_newarray_boolean, "newarray_boolean"},
79 {(functionptr) builtin_newarray_char, "newarray_char"},
80 {(functionptr) builtin_newarray_float, "newarray_float"},
81 {(functionptr) builtin_newarray_double, "newarray_double"},
82 {(functionptr) builtin_newarray_byte, "newarray_byte"},
83 {(functionptr) builtin_newarray_short, "newarray_short"},
84 {(functionptr) builtin_newarray_int, "newarray_int"},
85 {(functionptr) builtin_newarray_long, "newarray_long"},
86 {(functionptr) builtin_displaymethodstart, "displaymethodstart"},
87 {(functionptr) builtin_displaymethodstop, "displaymethodstop"},
88 {(functionptr) builtin_monitorenter, "monitorenter"},
89 {(functionptr) asm_builtin_monitorenter, "monitorenter"},
90 {(functionptr) builtin_monitorexit, "monitorexit"},
91 {(functionptr) asm_builtin_monitorexit, "monitorexit"},
93 {(functionptr) builtin_idiv, "idiv"},
94 {(functionptr) asm_builtin_idiv, "idiv"},
95 {(functionptr) builtin_irem, "irem"},
96 {(functionptr) asm_builtin_irem, "irem"},
98 {(functionptr) builtin_ladd, "ladd"},
99 {(functionptr) builtin_lsub, "lsub"},
100 {(functionptr) builtin_lmul, "lmul"},
101 #if !(SUPPORT_DIVISION && SUPPORT_LONG && SUPPORT_LONG_DIV)
102 {(functionptr) builtin_ldiv, "ldiv"},
103 {(functionptr) asm_builtin_ldiv, "ldiv"},
104 {(functionptr) builtin_lrem, "lrem"},
105 {(functionptr) asm_builtin_lrem, "lrem"},
107 {(functionptr) builtin_lshl, "lshl"},
108 {(functionptr) builtin_lshr, "lshr"},
109 {(functionptr) builtin_lushr, "lushr"},
110 {(functionptr) builtin_land, "land"},
111 {(functionptr) builtin_lor, "lor"},
112 {(functionptr) builtin_lxor, "lxor"},
113 {(functionptr) builtin_lneg, "lneg"},
114 {(functionptr) builtin_lcmp, "lcmp"},
115 {(functionptr) builtin_fadd, "fadd"},
116 {(functionptr) builtin_fsub, "fsub"},
117 {(functionptr) builtin_fmul, "fmul"},
118 {(functionptr) builtin_fdiv, "fdiv"},
119 {(functionptr) builtin_frem, "frem"},
120 {(functionptr) builtin_fneg, "fneg"},
121 {(functionptr) builtin_fcmpl, "fcmpl"},
122 {(functionptr) builtin_fcmpg, "fcmpg"},
123 {(functionptr) builtin_dadd, "dadd"},
124 {(functionptr) builtin_dsub, "dsub"},
125 {(functionptr) builtin_dmul, "dmul"},
126 {(functionptr) builtin_ddiv, "ddiv"},
127 {(functionptr) builtin_drem, "drem"},
128 {(functionptr) builtin_dneg, "dneg"},
129 {(functionptr) builtin_dcmpl, "dcmpl"},
130 {(functionptr) builtin_dcmpg, "dcmpg"},
131 {(functionptr) builtin_i2l, "i2l"},
132 {(functionptr) builtin_i2f, "i2f"},
133 {(functionptr) builtin_i2d, "i2d"},
134 {(functionptr) builtin_l2i, "l2i"},
135 {(functionptr) builtin_l2f, "l2f"},
136 {(functionptr) builtin_l2d, "l2d"},
137 {(functionptr) builtin_f2i, "f2i"},
138 {(functionptr) builtin_f2l, "f2l"},
139 {(functionptr) builtin_f2d, "f2d"},
140 {(functionptr) builtin_d2i, "d2i"},
141 {(functionptr) builtin_d2l, "d2l"},
142 #if defined(__I386__)
143 {(functionptr) asm_builtin_f2i, "f2i"},
144 {(functionptr) asm_builtin_f2l, "f2l"},
145 {(functionptr) asm_builtin_d2i, "d2i"},
146 {(functionptr) asm_builtin_d2l, "d2l"},
148 {(functionptr) builtin_d2f, "d2f"},
149 {(functionptr) NULL, "unknown"}
153 /*****************************************************************************
155 *****************************************************************************/
159 /*************** internal function: builtin_isanysubclass *********************
161 Checks a subclass relation between two classes. Implemented interfaces
162 are interpreted as super classes.
163 Return value: 1 ... sub is subclass of super
166 *****************************************************************************/
168 s4 builtin_isanysubclass (classinfo *sub, classinfo *super)
170 if (super->flags & ACC_INTERFACE)
171 return (sub->vftbl->interfacetablelength > super->index) &&
172 (sub->vftbl->interfacetable[-super->index] != NULL);
184 return (unsigned) (sub->vftbl->baseval - super->vftbl->baseval) <=
185 (unsigned) (super->vftbl->diffval);
189 /****************** function: builtin_instanceof *****************************
191 Checks if an object is an instance of some given class (or subclass of
192 that class). If class is an interface, checks if the interface is
194 Return value: 1 ... obj is an instance of class or implements the interface
195 0 ... otherwise or if obj == NULL
197 *****************************************************************************/
199 s4 builtin_instanceof(java_objectheader *obj, classinfo *class)
202 log_text ("builtin_instanceof called");
206 return builtin_isanysubclass (obj->vftbl->class, class);
211 /**************** function: builtin_checkcast *******************************
213 The same as builtin_instanceof except that 1 is returned when
216 ****************************************************************************/
218 s4 builtin_checkcast(java_objectheader *obj, classinfo *class)
221 log_text("builtin_checkcast called");
226 if (builtin_isanysubclass(obj->vftbl->class, class))
230 printf("#### checkcast failed ");
231 utf_display(obj->vftbl->class->name);
233 utf_display(class->name);
241 /*********** internal function: builtin_descriptorscompatible ******************
243 Checks if two array type descriptors are assignment compatible
244 Return value: 1 ... target = desc is possible
247 ******************************************************************************/
249 static s4 builtin_descriptorscompatible(constant_arraydescriptor *desc, constant_arraydescriptor *target)
251 if (desc == target) return 1;
252 if (desc->arraytype != target->arraytype) return 0;
254 switch (target->arraytype) {
255 case ARRAYTYPE_OBJECT:
256 return builtin_isanysubclass(desc->objectclass, target->objectclass);
257 case ARRAYTYPE_ARRAY:
258 return builtin_descriptorscompatible
259 (desc->elementdescriptor, target->elementdescriptor);
266 /******************** function: builtin_checkarraycast ***********************
268 Checks if an object is really a subtype of the requested array type.
269 The object has to be an array to begin with. For simple arrays (int, short,
270 double, etc.) the types have to match exactly.
271 For arrays of objects, the type of elements in the array has to be a
272 subtype (or the same type) of the requested element type. For arrays of
273 arrays (which in turn can again be arrays of arrays), the types at the
274 lowest level have to satisfy the corresponding sub class relation.
276 Return value: 1 ... cast is possible
279 ATTENTION: a cast with a NULL pointer is always possible.
281 *****************************************************************************/
283 s4 builtin_checkarraycast(java_objectheader *o, constant_arraydescriptor *desc)
285 java_arrayheader *a = (java_arrayheader*) o;
288 if (o->vftbl->class != class_array) {
290 printf("#### checkarraycast failed 1\n");
295 if (a->arraytype != desc->arraytype) {
297 printf("#### checkarraycast failed 2\n");
302 switch (a->arraytype) {
303 case ARRAYTYPE_OBJECT: {
304 java_objectarray *oa = (java_objectarray*) o;
305 int result = builtin_isanysubclass(oa->elementtype, desc->objectclass);
309 printf("#### checkarraycast failed 3\n");
313 case ARRAYTYPE_ARRAY: {
314 java_arrayarray *aa = (java_arrayarray*) o;
315 int result = builtin_descriptorscompatible
316 (aa->elementdescriptor, desc->elementdescriptor);
320 printf("#### checkarraycast failed 4\n");
330 s4 builtin_arrayinstanceof(java_objectheader *obj, constant_arraydescriptor *desc)
333 return builtin_checkarraycast (obj, desc);
337 /************************** exception functions *******************************
339 ******************************************************************************/
341 java_objectheader *builtin_throw_exception(java_objectheader *local_exceptionptr)
344 sprintf(logtext, "Builtin exception thrown: ");
345 utf_sprint(logtext + strlen(logtext), local_exceptionptr->vftbl->class->name);
348 exceptionptr = local_exceptionptr;
349 return local_exceptionptr;
353 /******************* function: builtin_canstore *******************************
355 Checks, if an object can be stored in an array.
356 Return value: 1 ... possible
359 ******************************************************************************/
362 s4 builtin_canstore(java_objectarray *a, java_objectheader *o)
366 switch (a->header.arraytype) {
367 case ARRAYTYPE_OBJECT:
368 if (!builtin_checkcast(o, a->elementtype)) {
374 case ARRAYTYPE_ARRAY:
375 if (!builtin_checkarraycast
376 (o, ((java_arrayarray*)a)->elementdescriptor)) {
383 panic("builtin_canstore called with invalid arraytype");
390 /*****************************************************************************
392 *****************************************************************************/
396 /******************** Function: builtin_new **********************************
398 Creates a new instance of class c on the heap.
399 Return value: pointer to the object or NULL if no memory is
402 *****************************************************************************/
405 #define align_size(size) ((size + ((1 << ALIGNMENT) - 1)) & ~((1 << ALIGNMENT) - 1))
407 java_objectheader *builtin_new(classinfo *c)
409 java_objectheader *o;
413 #ifdef SIZE_FROM_CLASSINFO
414 c->alignedsize = align_size(c->instancesize);
415 o = heap_allocate(c->alignedsize, true, c->finalizer);
417 o = heap_allocate(c->instancesize, true, c->finalizer);
421 memset(o, 0, c->instancesize);
430 /******************** function: builtin_anewarray ****************************
432 Creates an array of pointers to objects on the heap.
434 size ......... number of elements
435 elementtype .. pointer to the classinfo structure for the element type
437 Return value: pointer to the array or NULL if no memory is available
439 *****************************************************************************/
442 void* __builtin_newarray(s4 base_size,
451 #ifdef SIZE_FROM_CLASSINFO
452 s4 alignedsize = align_size(base_size + (size-1) * elementsize);
453 a = heap_allocate(alignedsize, references, NULL);
455 a = heap_allocate(sizeof(java_objectarray) + (size-1) * elementsize,
461 #ifdef SIZE_FROM_CLASSINFO
462 memset(a, 0, alignedsize);
464 memset(a, 0, base_size + (size-1) * elementsize);
473 c = create_array_class(utf_new_char("[I"));
474 use_class_as_object(c, "int");
478 c = create_array_class(utf_new_char("[J"));
479 use_class_as_object(c, "long");
482 case ARRAYTYPE_FLOAT:
483 c = create_array_class(utf_new_char("[F"));
484 use_class_as_object(c, "float");
487 case ARRAYTYPE_DOUBLE:
488 c = create_array_class(utf_new_char("[D"));
489 use_class_as_object(c, "double");
493 c = create_array_class(utf_new_char("[B"));
494 use_class_as_object(c, "byte");
498 c = create_array_class(utf_new_char("[C"));
499 use_class_as_object(c, "char");
502 case ARRAYTYPE_SHORT:
503 c = create_array_class(utf_new_char("[S"));
504 use_class_as_object(c, "short");
507 case ARRAYTYPE_BOOLEAN:
508 c = create_array_class(utf_new_char("[Z"));
509 use_class_as_object(c, "boolean");
512 case ARRAYTYPE_OBJECT:
515 cname = heap_allocate(utf_strlen(el->name), false, NULL);
516 utf_sprint(cname, el->name);
517 buf = heap_allocate(strlen(cname) + 3, false, NULL);
518 /* printf("\n\n[L%s;\n\n", cname); */
519 sprintf(buf, "[L%s;", cname);
520 c = create_array_class(utf_new_char(buf));
521 /* MFREE(buf, char, strlen(cname) + 3); */
522 /* MFREE(cname, char, utf_strlen(el->name)); */
523 use_class_as_object(c, cname);
527 case ARRAYTYPE_ARRAY:
528 c = create_array_class(utf_new_char("[["));
529 use_class_as_object(c, "java/lang/Boolean");
533 panic("unknown array type");
536 a->objheader.vftbl = c->vftbl;
539 a->objheader.vftbl = class_array->vftbl;
542 #ifdef SIZE_FROM_CLASSINFO
543 a->alignedsize = alignedsize;
545 a->arraytype = arraytype;
551 java_objectarray *builtin_anewarray(s4 size, classinfo *elementtype)
554 a = (java_objectarray*)__builtin_newarray(sizeof(java_objectarray),
562 a->elementtype = elementtype;
568 /******************** function: builtin_newarray_array ***********************
570 Creates an array of pointers to arrays on the heap.
572 size ......... number of elements
573 elementdesc .. pointer to the array description structure for the
576 Return value: pointer to the array or NULL if no memory is available
578 *****************************************************************************/
580 java_arrayarray *builtin_newarray_array(s4 size,
581 constant_arraydescriptor *elementdesc)
584 a = (java_arrayarray*)__builtin_newarray(sizeof(java_arrayarray),
589 elementdesc->objectclass);
592 a->elementdescriptor = elementdesc;
597 /******************** function: builtin_newarray_boolean ************************
599 Creates an array of bytes on the heap. The array is designated as an array
600 of booleans (important for casts)
602 Return value: pointer to the array or NULL if no memory is available
604 *****************************************************************************/
606 java_booleanarray *builtin_newarray_boolean(s4 size)
608 java_booleanarray *a;
609 a = (java_booleanarray*)__builtin_newarray(sizeof(java_booleanarray),
618 /******************** function: builtin_newarray_char ************************
620 Creates an array of characters on the heap.
622 Return value: pointer to the array or NULL if no memory is available
624 *****************************************************************************/
626 java_chararray *builtin_newarray_char(s4 size)
629 a = (java_chararray*)__builtin_newarray(sizeof(java_chararray),
639 /******************** function: builtin_newarray_float ***********************
641 Creates an array of 32 bit IEEE floats on the heap.
643 Return value: pointer to the array or NULL if no memory is available
645 *****************************************************************************/
647 java_floatarray *builtin_newarray_float(s4 size)
650 a = (java_floatarray*)__builtin_newarray(sizeof(java_floatarray),
660 /******************** function: builtin_newarray_double ***********************
662 Creates an array of 64 bit IEEE floats on the heap.
664 Return value: pointer to the array or NULL if no memory is available
666 *****************************************************************************/
668 java_doublearray *builtin_newarray_double(s4 size)
671 a = (java_doublearray*)__builtin_newarray(sizeof(java_doublearray),
683 /******************** function: builtin_newarray_byte ***********************
685 Creates an array of 8 bit Integers on the heap.
687 Return value: pointer to the array or NULL if no memory is available
689 *****************************************************************************/
691 java_bytearray *builtin_newarray_byte(s4 size)
694 a = (java_bytearray*)__builtin_newarray(sizeof(java_bytearray),
704 /******************** function: builtin_newarray_short ***********************
706 Creates an array of 16 bit Integers on the heap.
708 Return value: pointer to the array or NULL if no memory is available
710 *****************************************************************************/
712 java_shortarray *builtin_newarray_short(s4 size)
715 a = (java_shortarray*)__builtin_newarray(sizeof(java_shortarray),
725 /******************** Function: builtin_newarray_int ***********************
727 Creates an array of 32 bit Integers on the heap.
729 Return value: pointer to the array or NULL if no memory is available
731 *****************************************************************************/
733 java_intarray *builtin_newarray_int(s4 size)
736 a = (java_intarray*)__builtin_newarray(sizeof(java_intarray),
745 asm_handle_builtin_exception(proto_java_lang_OutOfMemoryError);
753 /******************** Function: builtin_newarray_long ***********************
755 Creates an array of 64 bit Integers on the heap.
757 Return value: pointer to the array or NULL if no memory is available
759 *****************************************************************************/
761 java_longarray *builtin_newarray_long(s4 size)
764 a = (java_longarray*)__builtin_newarray(sizeof(java_longarray),
775 /***************** function: builtin_multianewarray ***************************
777 Creates a multi-dimensional array on the heap. The dimensions are passed in
778 an array of Integers. The type for the array is passed as a reference to a
779 constant_arraydescriptor structure.
781 Return value: pointer to the array or NULL if no memory is available
783 ******************************************************************************/
785 /* Helper functions */
787 static java_arrayheader *multianewarray_part(java_intarray *dims, int thisdim,
788 constant_arraydescriptor *desc)
793 size = dims->data[thisdim];
795 if (thisdim == (dims->header.size - 1)) {
796 /* last dimension reached */
798 switch (desc -> arraytype) {
799 case ARRAYTYPE_BOOLEAN:
800 return (java_arrayheader*) builtin_newarray_boolean(size);
802 return (java_arrayheader*) builtin_newarray_char(size);
803 case ARRAYTYPE_FLOAT:
804 return (java_arrayheader*) builtin_newarray_float(size);
805 case ARRAYTYPE_DOUBLE:
806 return (java_arrayheader*) builtin_newarray_double(size);
808 return (java_arrayheader*) builtin_newarray_byte(size);
809 case ARRAYTYPE_SHORT:
810 return (java_arrayheader*) builtin_newarray_short(size);
812 return (java_arrayheader*) builtin_newarray_int(size);
814 return (java_arrayheader*) builtin_newarray_long(size);
815 case ARRAYTYPE_OBJECT:
816 return (java_arrayheader*) builtin_anewarray(size, desc->objectclass);
818 case ARRAYTYPE_ARRAY:
819 return (java_arrayheader*) builtin_newarray_array(size, desc->elementdescriptor);
821 default: panic("Invalid arraytype in multianewarray");
825 /* if the last dimension has not been reached yet */
827 if (desc->arraytype != ARRAYTYPE_ARRAY)
828 panic("multianewarray with too many dimensions");
830 a = builtin_newarray_array(size, desc->elementdescriptor);
833 for (i = 0; i < size; i++) {
834 java_arrayheader *ea =
835 multianewarray_part(dims, thisdim + 1, desc->elementdescriptor);
836 if (!ea) return NULL;
841 return (java_arrayheader*) a;
845 java_arrayheader *builtin_multianewarray(java_intarray *dims,
846 constant_arraydescriptor *desc)
848 return multianewarray_part(dims, 0, desc);
852 static java_arrayheader *nmultianewarray_part(int n, long *dims, int thisdim,
853 constant_arraydescriptor *desc)
858 size = (int) dims[thisdim];
860 if (thisdim == (n - 1)) {
861 /* last dimension reached */
863 switch (desc -> arraytype) {
864 case ARRAYTYPE_BOOLEAN:
865 return (java_arrayheader*) builtin_newarray_boolean(size);
867 return (java_arrayheader*) builtin_newarray_char(size);
868 case ARRAYTYPE_FLOAT:
869 return (java_arrayheader*) builtin_newarray_float(size);
870 case ARRAYTYPE_DOUBLE:
871 return (java_arrayheader*) builtin_newarray_double(size);
873 return (java_arrayheader*) builtin_newarray_byte(size);
874 case ARRAYTYPE_SHORT:
875 return (java_arrayheader*) builtin_newarray_short(size);
877 return (java_arrayheader*) builtin_newarray_int(size);
879 return (java_arrayheader*) builtin_newarray_long(size);
880 case ARRAYTYPE_OBJECT:
881 return (java_arrayheader*) builtin_anewarray(size,
883 case ARRAYTYPE_ARRAY:
884 return (java_arrayheader*) builtin_newarray_array(size,
885 desc->elementdescriptor);
887 default: panic ("Invalid arraytype in multianewarray");
891 /* if the last dimension has not been reached yet */
893 if (desc->arraytype != ARRAYTYPE_ARRAY)
894 panic ("multianewarray with too many dimensions");
896 a = builtin_newarray_array(size, desc->elementdescriptor);
899 for (i = 0; i < size; i++) {
900 java_arrayheader *ea =
901 nmultianewarray_part(n, dims, thisdim + 1, desc->elementdescriptor);
902 if (!ea) return NULL;
907 return (java_arrayheader*) a;
911 java_arrayheader *builtin_nmultianewarray (int size,
912 constant_arraydescriptor *desc, long *dims)
914 (void) builtin_newarray_int(size); /* for compatibility with -old */
915 return nmultianewarray_part (size, dims, 0, desc);
921 /************************* function: builtin_aastore *************************
923 Stores a reference to an object into an object array or into an array
924 array. Before any action is performed, the validity of the operation is
927 Return value: 1 ... ok
928 0 ... this object cannot be stored into this array
930 *****************************************************************************/
932 s4 builtin_aastore (java_objectarray *a, s4 index, java_objectheader *o)
934 if (builtin_canstore(a,o)) {
946 /*****************************************************************************
949 Various functions for printing a message at method entry or exit (for
952 *****************************************************************************/
957 java_objectheader *builtin_trace_exception(java_objectheader *exceptionptr,
958 methodinfo *method, int *pos,
964 if (verbose || runverbose) {
965 printf("Exception ");
966 utf_display (exceptionptr->vftbl->class->name);
967 printf(" thrown in ");
969 utf_display (method->class->name);
971 utf_display (method->name);
972 if (method->flags & ACC_SYNCHRONIZED)
976 printf("(%p) at position %p\n", method->entrypoint, pos);
979 printf("call_java_method\n");
986 #ifdef TRACE_ARGS_NUM
987 void builtin_trace_args(s8 a0, s8 a1, s8 a2, s8 a3, s8 a4, s8 a5,
988 #if TRACE_ARGS_NUM > 6
994 for (i = 0; i < methodindent; i++)
996 sprintf(logtext + methodindent, "called: ");
997 utf_sprint(logtext + strlen(logtext), method->class->name);
998 sprintf(logtext + strlen(logtext), ".");
999 utf_sprint(logtext + strlen(logtext), method->name);
1000 utf_sprint(logtext + strlen(logtext), method->descriptor);
1001 sprintf(logtext + strlen(logtext), "(");
1003 switch (method->paramcount) {
1007 #if defined(__I386__)
1009 sprintf(logtext+strlen(logtext), "%llx", a0);
1013 sprintf(logtext+strlen(logtext), "%llx, %llx", a0, a1);
1017 sprintf(logtext+strlen(logtext), "%llx, %llx, %llx", a0, a1, a2);
1021 sprintf(logtext+strlen(logtext), "%llx, %llx, %llx, %llx",
1026 sprintf(logtext+strlen(logtext), "%llx, %llx, %llx, %llx, %llx",
1027 a0, a1, a2, a3, a4);
1031 sprintf(logtext+strlen(logtext), "%llx, %llx, %llx, %llx, %llx, %llx",
1032 a0, a1, a2, a3, a4, a5);
1035 #if TRACE_ARGS_NUM > 6
1037 sprintf(logtext+strlen(logtext), "%llx, %llx, %llx, %llx, %llx, %llx, %llx",
1038 a0, a1, a2, a3, a4, a5, a6);
1042 sprintf(logtext+strlen(logtext), "%llx, %llx, %llx, %llx, %llx, %llx, %llx, %llx",
1043 a0, a1, a2, a3, a4, a5, a6, a7);
1047 sprintf(logtext+strlen(logtext), "%llx, %llx, %llx, %llx, %llx, %llx, %llx, %llx, ...(%d)",
1048 a0, a1, a2, a3, a4, a5, a6, a7, method->paramcount - 8);
1052 sprintf(logtext+strlen(logtext), "%llx, %llx, %llx, %llx, %llx, %llx, ...(%d)",
1053 a0, a1, a2, a3, a4, a5, method->paramcount - 6);
1058 sprintf(logtext+strlen(logtext), "%lx", a0);
1062 sprintf(logtext+strlen(logtext), "%lx, %lx", a0, a1);
1066 sprintf(logtext+strlen(logtext), "%lx, %lx, %lx", a0, a1, a2);
1070 sprintf(logtext+strlen(logtext), "%lx, %lx, %lx, %lx",
1075 sprintf(logtext+strlen(logtext), "%lx, %lx, %lx, %lx, %lx",
1076 a0, a1, a2, a3, a4);
1080 sprintf(logtext+strlen(logtext), "%lx, %lx, %lx, %lx, %lx, %lx",
1081 a0, a1, a2, a3, a4, a5);
1084 #if TRACE_ARGS_NUM > 6
1086 sprintf(logtext+strlen(logtext), "%lx, %lx, %lx, %lx, %lx, %lx, %lx",
1087 a0, a1, a2, a3, a4, a5, a6);
1091 sprintf(logtext+strlen(logtext), "%lx, %lx, %lx, %lx, %lx, %lx, %lx, %lx",
1092 a0, a1, a2, a3, a4, a5, a6, a7);
1096 sprintf(logtext+strlen(logtext), "%lx, %lx, %lx, %lx, %lx, %lx, %lx, %lx, ...(%d)",
1097 a0, a1, a2, a3, a4, a5, a6, a7, method->paramcount - 8);
1101 sprintf(logtext+strlen(logtext), "%lx, %lx, %lx, %lx, %lx, %lx, ...(%d)",
1102 a0, a1, a2, a3, a4, a5, method->paramcount - 6);
1107 sprintf(logtext + strlen(logtext), ")");
1115 void builtin_displaymethodstart(methodinfo *method)
1117 sprintf(logtext, " ");
1118 sprintf(logtext + methodindent, "called: ");
1119 utf_sprint(logtext + strlen(logtext), method->class->name);
1120 sprintf(logtext + strlen(logtext), ".");
1121 utf_sprint(logtext + strlen(logtext), method->name);
1122 utf_sprint(logtext + strlen(logtext), method->descriptor);
1128 void builtin_displaymethodstop(methodinfo *method, s8 l, double d, float f)
1131 for (i = 0; i < methodindent; i++)
1134 sprintf(logtext + methodindent, "finished: ");
1135 utf_sprint(logtext + strlen(logtext), method->class->name);
1136 sprintf(logtext + strlen(logtext), ".");
1137 utf_sprint(logtext + strlen(logtext), method->name);
1138 utf_sprint(logtext + strlen(logtext), method->descriptor);
1140 switch (method->returntype) {
1142 sprintf(logtext + strlen(logtext), "->%d", (s4) l);
1145 #if defined(__I386__)
1146 sprintf(logtext + strlen(logtext), "->%lld", (s8) l);
1148 sprintf(logtext + strlen(logtext), "->%ld", (s8) l);
1152 #if defined(__I386__)
1153 sprintf(logtext + strlen(logtext), "->%p", (u1*) ((s4) l));
1155 sprintf(logtext + strlen(logtext), "->%p", (u1*) l);
1159 sprintf(logtext + strlen(logtext), "->%g", f);
1162 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) {
1203 if (entry->mutex.count == 0 && entry->conditionCount == 0) {
1205 entry->mutex.holder = 0;
1206 entry->mutex.count = 0;
1207 entry->mutex.muxWaiters = 0;
1210 while (entry->next != 0 && entry->object != object)
1211 entry = entry->next;
1213 if (entry->object != object) {
1214 entry->next = firstFreeOverflowEntry;
1215 firstFreeOverflowEntry = firstFreeOverflowEntry->next;
1217 entry = entry->next;
1220 assert(entry->conditionCount == 0);
1225 entry->mutex.holder = 0;
1226 entry->mutex.count = 0;
1227 entry->mutex.muxWaiters = 0;
1230 if (entry->object == 0)
1231 entry->object = object;
1233 internal_lock_mutex(&entry->mutex);
1239 * Unlocks the mutex of an object.
1243 internal_unlock_mutex_for_object (java_objectheader *object)
1246 mutexHashEntry *entry;
1248 hashValue = MUTEX_HASH_VALUE(object);
1249 entry = &mutexHashTable[hashValue];
1251 if (entry->object == object) {
1252 internal_unlock_mutex(&entry->mutex);
1255 while (entry->next != 0 && entry->next->object != object)
1256 entry = entry->next;
1258 assert(entry->next != 0);
1260 internal_unlock_mutex(&entry->next->mutex);
1262 if (entry->next->mutex.count == 0 && entry->conditionCount == 0) {
1263 mutexHashEntry *unlinked = entry->next;
1265 entry->next = unlinked->next;
1266 unlinked->next = firstFreeOverflowEntry;
1267 firstFreeOverflowEntry = unlinked;
1274 void builtin_monitorenter(java_objectheader *o)
1279 assert(blockInts == 0);
1283 hashValue = MUTEX_HASH_VALUE(o);
1284 if (mutexHashTable[hashValue].object == o
1285 && mutexHashTable[hashValue].mutex.holder == currentThread)
1286 ++mutexHashTable[hashValue].mutex.count;
1288 internal_lock_mutex_for_object(o);
1292 assert(blockInts == 0);
1297 void builtin_monitorexit (java_objectheader *o)
1302 assert(blockInts == 0);
1306 hashValue = MUTEX_HASH_VALUE(o);
1307 if (mutexHashTable[hashValue].object == o) {
1308 if (mutexHashTable[hashValue].mutex.count == 1
1309 && mutexHashTable[hashValue].mutex.muxWaiters != 0)
1310 internal_unlock_mutex_for_object(o);
1312 --mutexHashTable[hashValue].mutex.count;
1315 internal_unlock_mutex_for_object(o);
1319 assert(blockInts == 0);
1324 /*****************************************************************************
1325 MISCELLANEOUS HELPER FUNCTIONS
1326 *****************************************************************************/
1330 /*********** Functions for integer divisions *****************************
1332 On some systems (eg. DEC ALPHA), integer division is not supported by the
1333 CPU. These helper functions implement the missing functionality.
1335 ******************************************************************************/
1337 s4 builtin_idiv(s4 a, s4 b) { return a / b; }
1338 s4 builtin_irem(s4 a, s4 b) { return a % b; }
1341 /************** Functions for long arithmetics *******************************
1343 On systems where 64 bit Integers are not supported by the CPU, these
1344 functions are needed.
1346 ******************************************************************************/
1349 s8 builtin_ladd(s8 a, s8 b)
1354 return builtin_i2l(0);
1358 s8 builtin_lsub(s8 a, s8 b)
1363 return builtin_i2l(0);
1367 s8 builtin_lmul(s8 a, s8 b)
1372 return builtin_i2l(0);
1376 s8 builtin_ldiv(s8 a, s8 b)
1381 return builtin_i2l(0);
1385 s8 builtin_lrem(s8 a, s8 b)
1390 return builtin_i2l(0);
1394 s8 builtin_lshl(s8 a, s4 b)
1397 return a << (b & 63);
1399 return builtin_i2l(0);
1403 s8 builtin_lshr(s8 a, s4 b)
1406 return a >> (b & 63);
1408 return builtin_i2l(0);
1412 s8 builtin_lushr(s8 a, s4 b)
1415 return ((u8) a) >> (b & 63);
1417 return builtin_i2l(0);
1421 s8 builtin_land(s8 a, s8 b)
1426 return builtin_i2l(0);
1430 s8 builtin_lor(s8 a, s8 b)
1435 return builtin_i2l(0);
1439 s8 builtin_lxor(s8 a, s8 b)
1444 return builtin_i2l(0);
1448 s8 builtin_lneg(s8 a)
1453 return builtin_i2l(0);
1457 s4 builtin_lcmp(s8 a, s8 b)
1460 if (a < b) return -1;
1461 if (a > b) return 1;
1472 /*********** Functions for floating point operations *************************/
1474 float builtin_fadd(float a, float b)
1476 if (isnanf(a)) return FLT_NAN;
1477 if (isnanf(b)) return FLT_NAN;
1488 if (copysignf(1.0, a) == copysignf(1.0, b))
1497 float builtin_fsub(float a, float b)
1499 return builtin_fadd(a, builtin_fneg(b));
1503 float builtin_fmul(float a, float b)
1505 if (isnanf(a)) return FLT_NAN;
1506 if (isnanf(b)) return FLT_NAN;
1508 if (finitef(b)) return a*b;
1510 if (a == 0) return FLT_NAN;
1511 else return copysignf(b, copysignf(1.0, b)*a);
1516 if (b == 0) return FLT_NAN;
1517 else return copysignf(a, copysignf(1.0, a)*b);
1520 return copysignf(a, copysignf(1.0, a)*copysignf(1.0, b));
1526 float builtin_fdiv(float a, float b)
1528 if (finitef(a) && finitef(b)) {
1542 float builtin_frem(float a, float b)
1548 float builtin_fneg(float a)
1550 if (isnanf(a)) return a;
1552 if (finitef(a)) return -a;
1553 else return copysignf(a, -copysignf(1.0, a));
1558 s4 builtin_fcmpl(float a, float b)
1560 if (isnanf(a)) return -1;
1561 if (isnanf(b)) return -1;
1562 if (!finitef(a) || !finitef(b)) {
1563 a = finitef(a) ? 0 : copysignf(1.0, a);
1564 b = finitef(b) ? 0 : copysignf(1.0, b);
1566 if (a > b) return 1;
1567 if (a == b) return 0;
1572 s4 builtin_fcmpg(float a, float b)
1574 if (isnanf(a)) return 1;
1575 if (isnanf(b)) return 1;
1576 if (!finitef(a) || !finitef(b)) {
1577 a = finitef(a) ? 0 : copysignf(1.0, a);
1578 b = finitef(b) ? 0 : copysignf(1.0, b);
1580 if (a > b) return 1;
1581 if (a == b) return 0;
1587 /************************* Functions for doubles ****************************/
1589 double builtin_dadd(double a, double b)
1591 if (isnan(a)) return DBL_NAN;
1592 if (isnan(b)) return DBL_NAN;
1594 if (finite(b)) return a+b;
1598 if (finite(b)) return a;
1600 if (copysign(1.0, a)==copysign(1.0, b)) return a;
1601 else return DBL_NAN;
1607 double builtin_dsub(double a, double b)
1609 return builtin_dadd(a, builtin_dneg(b));
1613 double builtin_dmul(double a, double b)
1615 if (isnan(a)) return DBL_NAN;
1616 if (isnan(b)) return DBL_NAN;
1618 if (finite(b)) return a * b;
1620 if (a == 0) return DBL_NAN;
1621 else return copysign(b, copysign(1.0, b) * a);
1626 if (b == 0) return DBL_NAN;
1627 else return copysign(a, copysign(1.0, a) * b);
1630 return copysign(a, copysign(1.0, a) * copysign(1.0, b));
1636 double builtin_ddiv(double a, double b)
1638 if (finite(a) && finite(b)) {
1652 double builtin_drem(double a, double b)
1658 double builtin_dneg(double a)
1660 if (isnan(a)) return a;
1662 if (finite(a)) return -a;
1663 else return copysign(a, -copysign(1.0, a));
1668 s4 builtin_dcmpl(double a, double b)
1670 if (isnan(a)) return -1;
1671 if (isnan(b)) return -1;
1672 if (!finite(a) || !finite(b)) {
1673 a = finite(a) ? 0 : copysign(1.0, a);
1674 b = finite(b) ? 0 : copysign(1.0, b);
1676 if (a > b) return 1;
1677 if (a == b) return 0;
1682 s4 builtin_dcmpg(double a, double b)
1684 if (isnan(a)) return 1;
1685 if (isnan(b)) return 1;
1686 if (!finite(a) || !finite(b)) {
1687 a = finite(a) ? 0 : copysign(1.0, a);
1688 b = finite(b) ? 0 : copysign(1.0, b);
1690 if (a > b) return 1;
1691 if (a == b) return 0;
1696 /*********************** Conversion operations ****************************/
1698 s8 builtin_i2l(s4 i)
1703 s8 v; v.high = 0; v.low=i; return v;
1708 float builtin_i2f(s4 a)
1710 float f = (float) a;
1715 double builtin_i2d(s4 a)
1717 double d = (double) a;
1722 s4 builtin_l2i(s8 l)
1732 float builtin_l2f(s8 a)
1735 float f = (float) a;
1743 double builtin_l2d(s8 a)
1746 double d = (double) a;
1754 s4 builtin_f2i(float a)
1757 return builtin_d2i((double) a);
1766 if (a < (-2147483648))
1767 return (-2147483648);
1770 f = copysignf((float) 1.0, a);
1773 return (-2147483648); */
1777 s8 builtin_f2l(float a)
1780 return builtin_d2l((double) a);
1785 if (a > 9223372036854775807L)
1786 return 9223372036854775807L;
1787 if (a < (-9223372036854775808L))
1788 return (-9223372036854775808L);
1793 f = copysignf((float) 1.0, a);
1795 return 9223372036854775807L;
1796 return (-9223372036854775808L); */
1800 double builtin_f2d(float a)
1802 if (finitef(a)) return (double) a;
1807 return copysign(DBL_POSINF, (double) copysignf(1.0, a) );
1812 s4 builtin_d2i(double a)
1817 if (a >= 2147483647)
1819 if (a <= (-2147483647-1))
1820 return (-2147483647-1);
1825 d = copysign(1.0, a);
1828 return (-2147483647-1);
1832 s8 builtin_d2l(double a)
1837 if (a >= 9223372036854775807LL)
1838 return 9223372036854775807LL;
1839 if (a <= (-9223372036854775807LL-1))
1840 return (-9223372036854775807LL-1);
1845 d = copysign(1.0, a);
1847 return 9223372036854775807LL;
1848 return (-9223372036854775807LL-1);
1852 float builtin_d2f(double a)
1860 return copysignf(FLT_POSINF, (float) copysign(1.0, a));
1866 * These are local overrides for various environment variables in Emacs.
1867 * Please do not remove this and leave it at the end of the file, where
1868 * Emacs will automagically detect them.
1869 * ---------------------------------------------------------------------
1872 * indent-tabs-mode: t