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 727 2003-12-11 10:52:40Z edwin $
52 #include "threads/thread.h"
53 #include "threads/locks.h"
54 #include "toolbox/loging.h"
55 #include "toolbox/memory.h"
56 #include "nat/java_lang_Cloneable.h"
57 #include "nat/java_lang_VMObject.h"
60 #undef DEBUG /*define DEBUG 1*/
64 builtin_descriptor builtin_desc[] = {
65 {(functionptr) builtin_instanceof, "instanceof"},
66 {(functionptr) builtin_checkcast, "checkcast"},
67 {(functionptr) asm_builtin_checkcast, "checkcast"},
68 {(functionptr) builtin_arrayinstanceof, "arrayinstanceof"},
70 {(functionptr) asm_builtin_arrayinstanceof,"arrayinstanceof"},
72 {(functionptr) builtin_checkarraycast, "checkarraycast"},
73 {(functionptr) asm_builtin_checkarraycast, "checkarraycast"},
74 {(functionptr) asm_builtin_aastore, "aastore"},
75 {(functionptr) builtin_new, "new"},
76 {(functionptr) builtin_newarray, "newarray"},
77 {(functionptr) builtin_anewarray, "anewarray"},
80 * have 2 parameters (needs stack manipulation)
82 {(functionptr) asm_builtin_newarray, "newarray"},
84 {(functionptr) builtin_newarray_boolean, "newarray_boolean"},
85 {(functionptr) builtin_newarray_char, "newarray_char"},
86 {(functionptr) builtin_newarray_float, "newarray_float"},
87 {(functionptr) builtin_newarray_double, "newarray_double"},
88 {(functionptr) builtin_newarray_byte, "newarray_byte"},
89 {(functionptr) builtin_newarray_short, "newarray_short"},
90 {(functionptr) builtin_newarray_int, "newarray_int"},
91 {(functionptr) builtin_newarray_long, "newarray_long"},
92 {(functionptr) builtin_displaymethodstart, "displaymethodstart"},
93 {(functionptr) builtin_displaymethodstop, "displaymethodstop"},
94 {(functionptr) builtin_monitorenter, "monitorenter"},
95 {(functionptr) asm_builtin_monitorenter, "monitorenter"},
96 {(functionptr) builtin_monitorexit, "monitorexit"},
97 {(functionptr) asm_builtin_monitorexit, "monitorexit"},
99 {(functionptr) builtin_idiv, "idiv"},
100 {(functionptr) asm_builtin_idiv, "idiv"},
101 {(functionptr) builtin_irem, "irem"},
102 {(functionptr) asm_builtin_irem, "irem"},
104 {(functionptr) builtin_ladd, "ladd"},
105 {(functionptr) builtin_lsub, "lsub"},
106 {(functionptr) builtin_lmul, "lmul"},
107 #if !(SUPPORT_DIVISION && SUPPORT_LONG && SUPPORT_LONG_DIV)
108 {(functionptr) builtin_ldiv, "ldiv"},
109 {(functionptr) asm_builtin_ldiv, "ldiv"},
110 {(functionptr) builtin_lrem, "lrem"},
111 {(functionptr) asm_builtin_lrem, "lrem"},
113 {(functionptr) builtin_lshl, "lshl"},
114 {(functionptr) builtin_lshr, "lshr"},
115 {(functionptr) builtin_lushr, "lushr"},
116 {(functionptr) builtin_land, "land"},
117 {(functionptr) builtin_lor, "lor"},
118 {(functionptr) builtin_lxor, "lxor"},
119 {(functionptr) builtin_lneg, "lneg"},
120 {(functionptr) builtin_lcmp, "lcmp"},
121 {(functionptr) builtin_fadd, "fadd"},
122 {(functionptr) builtin_fsub, "fsub"},
123 {(functionptr) builtin_fmul, "fmul"},
124 {(functionptr) builtin_fdiv, "fdiv"},
125 {(functionptr) builtin_frem, "frem"},
126 {(functionptr) builtin_fneg, "fneg"},
127 {(functionptr) builtin_fcmpl, "fcmpl"},
128 {(functionptr) builtin_fcmpg, "fcmpg"},
129 {(functionptr) builtin_dadd, "dadd"},
130 {(functionptr) builtin_dsub, "dsub"},
131 {(functionptr) builtin_dmul, "dmul"},
132 {(functionptr) builtin_ddiv, "ddiv"},
133 {(functionptr) builtin_drem, "drem"},
134 {(functionptr) builtin_dneg, "dneg"},
135 {(functionptr) builtin_dcmpl, "dcmpl"},
136 {(functionptr) builtin_dcmpg, "dcmpg"},
137 {(functionptr) builtin_i2l, "i2l"},
138 {(functionptr) builtin_i2f, "i2f"},
139 {(functionptr) builtin_i2d, "i2d"},
140 {(functionptr) builtin_l2i, "l2i"},
141 {(functionptr) builtin_l2f, "l2f"},
142 {(functionptr) builtin_l2d, "l2d"},
143 {(functionptr) builtin_f2i, "f2i"},
144 {(functionptr) builtin_f2l, "f2l"},
145 {(functionptr) builtin_f2d, "f2d"},
146 {(functionptr) builtin_d2i, "d2i"},
147 {(functionptr) builtin_d2l, "d2l"},
148 #if defined(__I386__)
149 {(functionptr) asm_builtin_f2i, "f2i"},
150 {(functionptr) asm_builtin_f2l, "f2l"},
151 {(functionptr) asm_builtin_d2i, "d2i"},
152 {(functionptr) asm_builtin_d2l, "d2l"},
154 {(functionptr) builtin_d2f, "d2f"},
155 {(functionptr) NULL, "unknown"}
160 /*****************************************************************************
162 *****************************************************************************/
166 /*************** internal function: builtin_isanysubclass *********************
168 Checks a subclass relation between two classes. Implemented interfaces
169 are interpreted as super classes.
170 Return value: 1 ... sub is subclass of super
173 *****************************************************************************/
175 s4 builtin_isanysubclass (classinfo *sub, classinfo *super)
178 if (super->flags & ACC_INTERFACE)
179 return (sub->vftbl->interfacetablelength > super->index) &&
180 (sub->vftbl->interfacetable[-super->index] != NULL);
193 for (tmp=sub;tmp!=0;tmp=tmp->super) {
195 utf_display(tmp->name);
199 for (tmp=super;tmp!=0;tmp=tmp->super) {
201 utf_display(tmp->name);
206 printf("sub->vftbl->baseval %d, super->vftbl->baseval %d\n diff %d, super->vftbl->diffval %d\n",
207 sub->vftbl->baseval, super->vftbl->baseval, (unsigned)(sub->vftbl->baseval - super->vftbl->baseval),
208 super->vftbl->diffval); */
210 return (unsigned) (sub->vftbl->baseval - super->vftbl->baseval) <=
211 (unsigned) (super->vftbl->diffval);
214 /* XXX inline this? */
215 s4 builtin_isanysubclass_vftbl(vftbl *sub,vftbl *super)
219 if ((base = super->baseval) <= 0)
220 /* super is an interface */
221 return (sub->interfacetablelength > -base) &&
222 (sub->interfacetable[base] != NULL);
223 return (unsigned) (sub->baseval - base)
224 <= (unsigned) (super->diffval);
228 /****************** function: builtin_instanceof *****************************
230 Checks if an object is an instance of some given class (or subclass of
231 that class). If class is an interface, checks if the interface is
233 Return value: 1 ... obj is an instance of class or implements the interface
234 0 ... otherwise or if obj == NULL
236 *****************************************************************************/
238 /* XXX should use vftbl */
239 s4 builtin_instanceof(java_objectheader *obj, classinfo *class)
242 log_text ("builtin_instanceof called");
245 return builtin_isanysubclass (obj->vftbl->class, class);
250 /**************** function: builtin_checkcast *******************************
252 The same as builtin_instanceof except that 1 is returned when
255 ****************************************************************************/
257 /* XXX should use vftbl */
258 s4 builtin_checkcast(java_objectheader *obj, classinfo *class)
261 log_text("builtin_checkcast called");
266 if (builtin_isanysubclass(obj->vftbl->class, class))
270 printf("#### checkcast failed ");
271 utf_display(obj->vftbl->class->name);
273 utf_display(class->name);
281 /*********** internal function: builtin_descriptorscompatible ******************
283 Checks if two array type descriptors are assignment compatible
284 Return value: 1 ... target = desc is possible
287 ******************************************************************************/
289 /* XXX inline this? */
290 static s4 builtin_descriptorscompatible(arraydescriptor *desc,arraydescriptor *target)
292 if (desc==target) return 1;
293 if (desc->arraytype != target->arraytype) return 0;
294 if (desc->arraytype != ARRAYTYPE_OBJECT) return 1;
296 /* {both arrays are arrays of references} */
297 if (desc->dimension == target->dimension)
298 return builtin_isanysubclass_vftbl(desc->elementvftbl,target->elementvftbl);
299 if (desc->dimension < target->dimension) return 0;
301 /* {desc has higher dimension than target} */
302 return builtin_isanysubclass_vftbl(pseudo_class_Arraystub_vftbl,target->elementvftbl);
306 /******************** function: builtin_checkarraycast ***********************
308 Checks if an object is really a subtype of the requested array type.
309 The object has to be an array to begin with. For simple arrays (int, short,
310 double, etc.) the types have to match exactly.
311 For arrays of objects, the type of elements in the array has to be a
312 subtype (or the same type) of the requested element type. For arrays of
313 arrays (which in turn can again be arrays of arrays), the types at the
314 lowest level have to satisfy the corresponding sub class relation.
316 Return value: 1 ... cast is possible
319 ATTENTION: a cast with a NULL pointer is always possible.
321 *****************************************************************************/
323 s4 builtin_checkarraycast(java_objectheader *o, vftbl *target)
325 arraydescriptor *desc;
328 if ((desc = o->vftbl->arraydesc) == NULL) return 0;
330 return builtin_descriptorscompatible(desc, target->arraydesc);
334 s4 builtin_arrayinstanceof(java_objectheader *obj, vftbl *target)
337 return builtin_checkarraycast(obj, target);
341 /************************** exception functions *******************************
343 ******************************************************************************/
345 java_objectheader *builtin_throw_exception(java_objectheader *local_exceptionptr)
348 char logtext[MAXLOGTEXT];
349 sprintf(logtext, "Builtin exception thrown: ");
350 if (local_exceptionptr)
351 utf_sprint(logtext + strlen(logtext), local_exceptionptr->vftbl->class->name);
353 sprintf(logtext+strlen(logtext),"%s","Error: <Nullpointer instead of exception>");
354 if (!proto_java_lang_ClassCastException) sprintf(logtext+strlen(logtext),"%s","proto_java_lang_ClassCastException==0");
355 if (!proto_java_lang_NullPointerException) sprintf(logtext+strlen(logtext),"%s","proto_java_lang_NullPointerException==0");
356 if (!proto_java_lang_NullPointerException) sprintf(logtext+strlen(logtext),"%s","proto_java_lang_NullPointerException==0");
357 if (!proto_java_lang_ArrayIndexOutOfBoundsException) sprintf(logtext+strlen(logtext),"%s","proto_java_lang_ArrayIndexOutOfBoundsException==0");
358 if (!proto_java_lang_NegativeArraySizeException) sprintf(logtext+strlen(logtext),"%s","proto_java_lang_NegativeArraySizeException==0");
359 if (!proto_java_lang_OutOfMemoryError) sprintf(logtext+strlen(logtext),"%s","proto_java_lang_OutOfMemoryError==0");
360 if (!proto_java_lang_ArithmeticException) sprintf(logtext+strlen(logtext),"%s","proto_java_lang_ArithmeticException==0");
361 if (!proto_java_lang_ArrayStoreException) sprintf(logtext+strlen(logtext),"%s","proto_java_lang_ArrayStoreException==0");
362 if (!proto_java_lang_ThreadDeath) sprintf(logtext+strlen(logtext),"%s","proto_java_lang_ThreadDeath==0");
363 if (!proto_java_lang_ThreadDeath) sprintf(logtext+strlen(logtext),"%s","proto_java_lang_ThreadDeath==0");
367 exceptionptr = local_exceptionptr;
368 return local_exceptionptr;
372 /******************* function: builtin_canstore *******************************
374 Checks, if an object can be stored in an array.
375 Return value: 1 ... possible
378 ******************************************************************************/
380 s4 builtin_canstore (java_objectarray *a, java_objectheader *o)
382 arraydescriptor *desc;
383 arraydescriptor *valuedesc;
384 vftbl *componentvftbl;
391 /* The following is guaranteed (by verifier checks):
393 * *) a->...vftbl->arraydesc != NULL
394 * *) a->...vftbl->arraydesc->componentvftbl != NULL
395 * *) o->vftbl is not an interface vftbl
398 desc = a->header.objheader.vftbl->arraydesc;
399 componentvftbl = desc->componentvftbl;
400 valuevftbl = o->vftbl;
402 if ((dim_m1 = desc->dimension - 1) == 0) {
403 /* {a is a one-dimensional array} */
404 /* {a is an array of references} */
406 if (valuevftbl == componentvftbl)
409 if ((base = componentvftbl->baseval) <= 0)
410 /* an array of interface references */
411 return (valuevftbl->interfacetablelength > -base &&
412 valuevftbl->interfacetable[base] != NULL);
414 return (unsigned)(valuevftbl->baseval - base)
415 <= (unsigned)(componentvftbl->diffval);
417 /* {a has dimension > 1} */
418 /* {componentvftbl->arraydesc != NULL} */
420 /* check if o is an array */
421 if ((valuedesc = valuevftbl->arraydesc) == NULL)
423 /* {o is an array} */
425 return builtin_descriptorscompatible(valuedesc,componentvftbl->arraydesc);
429 /* This is an optimized version where a is guaranteed to be one-dimensional */
430 s4 builtin_canstore_onedim (java_objectarray *a, java_objectheader *o)
432 arraydescriptor *desc;
439 /* The following is guaranteed (by verifier checks):
441 * *) a->...vftbl->arraydesc != NULL
442 * *) a->...vftbl->arraydesc->elementvftbl != NULL
443 * *) a->...vftbl->arraydesc->dimension == 1
444 * *) o->vftbl is not an interface vftbl
447 desc = a->header.objheader.vftbl->arraydesc;
448 elementvftbl = desc->elementvftbl;
449 valuevftbl = o->vftbl;
451 /* {a is a one-dimensional array} */
453 if (valuevftbl == elementvftbl)
456 if ((base = elementvftbl->baseval) <= 0)
457 /* an array of interface references */
458 return (valuevftbl->interfacetablelength > -base &&
459 valuevftbl->interfacetable[base] != NULL);
461 return (unsigned)(valuevftbl->baseval - base)
462 <= (unsigned)(elementvftbl->diffval);
466 /* This is an optimized version where a is guaranteed to be a
467 * one-dimensional array of a class type */
468 /* XXX this could be inlined by the code generator */
469 s4 builtin_canstore_onedim_class(java_objectarray *a, java_objectheader *o)
476 /* The following is guaranteed (by verifier checks):
478 * *) a->...vftbl->arraydesc != NULL
479 * *) a->...vftbl->arraydesc->elementvftbl != NULL
480 * *) a->...vftbl->arraydesc->elementvftbl is not an interface vftbl
481 * *) a->...vftbl->arraydesc->dimension == 1
482 * *) o->vftbl is not an interface vftbl
485 elementvftbl = a->header.objheader.vftbl->arraydesc->elementvftbl;
486 valuevftbl = o->vftbl;
488 /* {a is a one-dimensional array} */
490 if (valuevftbl == elementvftbl)
493 return (unsigned)(valuevftbl->baseval - elementvftbl->baseval)
494 <= (unsigned)(elementvftbl->diffval);
498 /******************** Function: builtin_new **********************************
500 Creates a new instance of class c on the heap.
501 Return value: pointer to the object or NULL if no memory is
504 *****************************************************************************/
507 #define align_size(size) ((size + ((1 << ALIGNMENT) - 1)) & ~((1 << ALIGNMENT) - 1))
509 java_objectheader *builtin_new(classinfo *c)
511 java_objectheader *o;
515 #ifdef SIZE_FROM_CLASSINFO
516 c->alignedsize = align_size(c->instancesize);
517 o = heap_allocate(c->alignedsize, true, c->finalizer);
519 o = heap_allocate(c->instancesize, true, c->finalizer);
523 memset(o, 0, c->instancesize);
530 /********************** Function: builtin_newarray **************************
532 Creates an array with the given vftbl on the heap.
534 Return value: pointer to the array or NULL if no memory is available
536 CAUTION: The given vftbl must be the vftbl of the *array* class,
537 not of the element class.
539 *****************************************************************************/
541 java_arrayheader *builtin_newarray(s4 size, vftbl *arrayvftbl)
544 arraydescriptor *desc = arrayvftbl->arraydesc;
545 s4 dataoffset = desc->dataoffset;
546 s4 componentsize = desc->componentsize;
550 exceptionptr=native_new_and_init(loader_load(utf_new_char("java/lang/NegativeArraySizeException")));
553 #ifdef SIZE_FROM_CLASSINFO
554 actualsize = align_size(dataoffset + size * componentsize);
556 actualsize = dataoffset + size * componentsize;
559 if (((u4)actualsize)<((u4)size)) { /* overflow */
560 exceptionptr=native_new_and_init(loader_load(utf_new_char("java/lang/OutOfMemoryError")));
563 a = (java_arrayheader *) heap_allocate(actualsize,
564 (desc->arraytype == ARRAYTYPE_OBJECT),
567 memset(a,0,actualsize);
570 /*printf("builtin_newarray: Created an array of size : %d\n",size);*/
572 a->objheader.vftbl = arrayvftbl;
574 #ifdef SIZE_FROM_CLASSINFO
575 a->alignedsize = actualsize;
582 /********************** Function: builtin_anewarray *************************
584 Creates an array of references to the given class type on the heap.
586 Return value: pointer to the array or NULL if no memory is available
588 XXX This function does not do The Right Thing, because it uses a
589 classinfo pointer at runtime. builtin_newarray should be used
592 *****************************************************************************/
594 java_objectarray *builtin_anewarray(s4 size, classinfo *component)
596 return (java_objectarray*) builtin_newarray(size, class_array_of(component)->vftbl);
600 /******************** Function: builtin_newarray_int ***********************
602 Creates an array of 32 bit Integers on the heap.
604 Return value: pointer to the array or NULL if no memory is available
606 *****************************************************************************/
608 java_intarray *builtin_newarray_int(s4 size)
610 return (java_intarray*) builtin_newarray(size, primitivetype_table[ARRAYTYPE_INT].arrayvftbl);
614 /******************** Function: builtin_newarray_long ***********************
616 Creates an array of 64 bit Integers on the heap.
618 Return value: pointer to the array or NULL if no memory is available
620 *****************************************************************************/
622 java_longarray *builtin_newarray_long(s4 size)
624 return (java_longarray*) builtin_newarray(size, primitivetype_table[ARRAYTYPE_LONG].arrayvftbl);
628 /******************** function: builtin_newarray_float ***********************
630 Creates an array of 32 bit IEEE floats on the heap.
632 Return value: pointer to the array or NULL if no memory is available
634 *****************************************************************************/
636 java_floatarray *builtin_newarray_float(s4 size)
638 return (java_floatarray*) builtin_newarray(size, primitivetype_table[ARRAYTYPE_FLOAT].arrayvftbl);
642 /******************** function: builtin_newarray_double ***********************
644 Creates an array of 64 bit IEEE floats on the heap.
646 Return value: pointer to the array or NULL if no memory is available
648 *****************************************************************************/
650 java_doublearray *builtin_newarray_double(s4 size)
652 return (java_doublearray*) builtin_newarray(size, primitivetype_table[ARRAYTYPE_DOUBLE].arrayvftbl);
656 /******************** function: builtin_newarray_byte ***********************
658 Creates an array of 8 bit Integers on the heap.
660 Return value: pointer to the array or NULL if no memory is available
662 *****************************************************************************/
664 java_bytearray *builtin_newarray_byte(s4 size)
666 return (java_bytearray*) builtin_newarray(size, primitivetype_table[ARRAYTYPE_BYTE].arrayvftbl);
670 /******************** function: builtin_newarray_char ************************
672 Creates an array of characters on the heap.
674 Return value: pointer to the array or NULL if no memory is available
676 *****************************************************************************/
678 java_chararray *builtin_newarray_char(s4 size)
680 return (java_chararray*) builtin_newarray(size, primitivetype_table[ARRAYTYPE_CHAR].arrayvftbl);
684 /******************** function: builtin_newarray_short ***********************
686 Creates an array of 16 bit Integers on the heap.
688 Return value: pointer to the array or NULL if no memory is available
690 *****************************************************************************/
692 java_shortarray *builtin_newarray_short(s4 size)
694 return (java_shortarray*) builtin_newarray(size, primitivetype_table[ARRAYTYPE_SHORT].arrayvftbl);
698 /******************** function: builtin_newarray_boolean ************************
700 Creates an array of bytes on the heap. The array is designated as an array
701 of booleans (important for casts)
703 Return value: pointer to the array or NULL if no memory is available
705 *****************************************************************************/
707 java_booleanarray *builtin_newarray_boolean(s4 size)
709 return (java_booleanarray*) builtin_newarray(size, primitivetype_table[ARRAYTYPE_BOOLEAN].arrayvftbl);
713 /**************** function: builtin_nmultianewarray ***************************
715 Creates a multi-dimensional array on the heap. The dimensions are passed in
719 n............number of dimensions to create
720 arrayvftbl...vftbl of the array class
721 dims.........array containing the size of each dimension to create
723 Return value: pointer to the array or NULL if no memory is available
725 ******************************************************************************/
727 /* Helper functions */
729 java_arrayheader *builtin_nmultianewarray (int n, vftbl *arrayvftbl, long *dims)
733 vftbl *componentvftbl;
735 /* create this dimension */
736 size = (int) dims[0];
737 a = builtin_newarray(size,arrayvftbl);
740 /* if this is the last dimension return */
743 /* get the vftbl of the components to create */
744 componentvftbl = arrayvftbl->arraydesc->componentvftbl;
745 if (!componentvftbl) /* XXX the verifier could check this */
746 panic ("multianewarray with too many dimensions");
748 /* create the component arrays */
749 for (i = 0; i < size; i++) {
750 java_arrayheader *ea =
751 builtin_nmultianewarray(n,componentvftbl,dims+1);
752 if (!ea) return NULL;
753 ((java_objectarray*)a)->data[i] = (java_objectheader *) ea;
760 /*****************************************************************************
763 Various functions for printing a message at method entry or exit (for
766 *****************************************************************************/
771 java_objectheader *builtin_trace_exception(java_objectheader *exceptionptr,
772 methodinfo *method, int *pos,
777 if (verbose || runverbose) {
778 printf("Exception ");
780 utf_display (exceptionptr->vftbl->class->name);
783 printf("Error: <Nullpointer instead of exception>");
784 if (!proto_java_lang_ClassCastException) printf("%s","proto_java_lang_ClassCastException==0");
785 if (!proto_java_lang_NullPointerException) printf("%s","proto_java_lang_NullPointerException==0");
786 if (!proto_java_lang_NullPointerException) printf("%s","proto_java_lang_NullPointerException==0");
787 if (!proto_java_lang_ArrayIndexOutOfBoundsException) printf("%s","proto_java_lang_ArrayIndexOutOfBoundsException==0");
788 if (!proto_java_lang_NegativeArraySizeException) printf("%s","proto_java_lang_NegativeArraySizeException==0");
789 if (!proto_java_lang_OutOfMemoryError) printf("%s","proto_java_lang_OutOfMemoryError==0");
790 if (!proto_java_lang_ArithmeticException) printf("%s","proto_java_lang_ArithmeticException==0");
791 if (!proto_java_lang_ArrayStoreException) printf("%s","proto_java_lang_ArrayStoreException==0");
792 if (!proto_java_lang_ThreadDeath) printf("%s","proto_java_lang_ThreadDeath==0");
793 if (!proto_java_lang_ThreadDeath) printf("%s","proto_java_lang_ThreadDeath==0");
796 printf(" thrown in ");
798 utf_display (method->class->name);
800 utf_display (method->name);
801 if (method->flags & ACC_SYNCHRONIZED)
805 printf("(%p) at position %p\n", method->entrypoint, pos);
808 printf("call_java_method\n");
815 #ifdef TRACE_ARGS_NUM
816 void builtin_trace_args(s8 a0, s8 a1, s8 a2, s8 a3, s8 a4, s8 a5,
817 #if TRACE_ARGS_NUM > 6
823 char logtext[MAXLOGTEXT];
824 for (i = 0; i < methodindent; i++)
826 sprintf(logtext + methodindent, "called: ");
827 utf_sprint(logtext + strlen(logtext), method->class->name);
828 sprintf(logtext + strlen(logtext), ".");
829 utf_sprint(logtext + strlen(logtext), method->name);
830 utf_sprint(logtext + strlen(logtext), method->descriptor);
831 sprintf(logtext + strlen(logtext), "(");
833 switch (method->paramcount) {
837 #if defined(__I386__)
839 sprintf(logtext+strlen(logtext), "%llx", a0);
843 sprintf(logtext+strlen(logtext), "%llx, %llx", a0, a1);
847 sprintf(logtext+strlen(logtext), "%llx, %llx, %llx", a0, a1, a2);
851 sprintf(logtext+strlen(logtext), "%llx, %llx, %llx, %llx",
856 sprintf(logtext+strlen(logtext), "%llx, %llx, %llx, %llx, %llx",
861 sprintf(logtext+strlen(logtext), "%llx, %llx, %llx, %llx, %llx, %llx",
862 a0, a1, a2, a3, a4, a5);
865 #if TRACE_ARGS_NUM > 6
867 sprintf(logtext+strlen(logtext), "%llx, %llx, %llx, %llx, %llx, %llx, %llx",
868 a0, a1, a2, a3, a4, a5, a6);
872 sprintf(logtext+strlen(logtext), "%llx, %llx, %llx, %llx, %llx, %llx, %llx, %llx",
873 a0, a1, a2, a3, a4, a5, a6, a7);
877 sprintf(logtext+strlen(logtext), "%llx, %llx, %llx, %llx, %llx, %llx, %llx, %llx, ...(%d)",
878 a0, a1, a2, a3, a4, a5, a6, a7, method->paramcount - 8);
882 sprintf(logtext+strlen(logtext), "%llx, %llx, %llx, %llx, %llx, %llx, ...(%d)",
883 a0, a1, a2, a3, a4, a5, method->paramcount - 6);
888 sprintf(logtext+strlen(logtext), "%lx", a0);
892 sprintf(logtext+strlen(logtext), "%lx, %lx", a0, a1);
896 sprintf(logtext+strlen(logtext), "%lx, %lx, %lx", a0, a1, a2);
900 sprintf(logtext+strlen(logtext), "%lx, %lx, %lx, %lx",
905 sprintf(logtext+strlen(logtext), "%lx, %lx, %lx, %lx, %lx",
910 sprintf(logtext+strlen(logtext), "%lx, %lx, %lx, %lx, %lx, %lx",
911 a0, a1, a2, a3, a4, a5);
914 #if TRACE_ARGS_NUM > 6
916 sprintf(logtext+strlen(logtext), "%lx, %lx, %lx, %lx, %lx, %lx, %lx",
917 a0, a1, a2, a3, a4, a5, a6);
921 sprintf(logtext+strlen(logtext), "%lx, %lx, %lx, %lx, %lx, %lx, %lx, %lx",
922 a0, a1, a2, a3, a4, a5, a6, a7);
926 sprintf(logtext+strlen(logtext), "%lx, %lx, %lx, %lx, %lx, %lx, %lx, %lx, ...(%d)",
927 a0, a1, a2, a3, a4, a5, a6, a7, method->paramcount - 8);
931 sprintf(logtext+strlen(logtext), "%lx, %lx, %lx, %lx, %lx, %lx, ...(%d)",
932 a0, a1, a2, a3, a4, a5, method->paramcount - 6);
937 sprintf (logtext+strlen(logtext), ")");
945 void builtin_displaymethodstart(methodinfo *method)
947 char logtext[MAXLOGTEXT];
948 sprintf(logtext, " ");
949 sprintf(logtext + methodindent, "called: ");
950 utf_sprint(logtext + strlen(logtext), method->class->name);
951 sprintf(logtext + strlen(logtext), ".");
952 utf_sprint(logtext + strlen(logtext), method->name);
953 utf_sprint(logtext + strlen(logtext), method->descriptor);
959 void builtin_displaymethodstop(methodinfo *method, s8 l, double d, float f)
962 char logtext[MAXLOGTEXT];
963 for (i = 0; i < methodindent; i++)
966 sprintf(logtext + methodindent, "finished: ");
967 utf_sprint(logtext + strlen(logtext), method->class->name);
968 sprintf(logtext + strlen(logtext), ".");
969 utf_sprint(logtext + strlen(logtext), method->name);
970 utf_sprint(logtext + strlen(logtext), method->descriptor);
972 switch (method->returntype) {
974 sprintf(logtext + strlen(logtext), "->%d", (s4) l);
977 #if defined(__I386__)
978 sprintf(logtext + strlen(logtext), "->%lld", (s8) l);
980 sprintf(logtext + strlen(logtext), "->%ld", (s8) l);
984 #if defined(__I386__)
985 sprintf(logtext + strlen(logtext), "->%p", (u1*) ((s4) l));
987 sprintf(logtext + strlen(logtext), "->%p", (u1*) l);
991 sprintf(logtext + strlen(logtext), "->%g", f);
994 sprintf(logtext + strlen(logtext), "->%g", d);
1001 void builtin_displaymethodexception(methodinfo *method)
1004 char logtext[MAXLOGTEXT];
1005 for (i = 0; i < methodindent; i++)
1007 sprintf(logtext + methodindent, "exception abort: ");
1008 utf_sprint(logtext + strlen(logtext), method->class->name);
1009 sprintf(logtext + strlen(logtext), ".");
1010 utf_sprint(logtext + strlen(logtext), method->name);
1011 utf_sprint(logtext + strlen(logtext), method->descriptor);
1016 /****************************************************************************
1017 SYNCHRONIZATION FUNCTIONS
1018 *****************************************************************************/
1021 * Lock the mutex of an object.
1023 void internal_lock_mutex_for_object(java_objectheader *object)
1026 mutexHashEntry *entry;
1029 assert(object != 0);
1031 hashValue = MUTEX_HASH_VALUE(object);
1032 entry = &mutexHashTable[hashValue];
1034 if (entry->object != 0) {
1035 if (entry->mutex.count == 0 && entry->conditionCount == 0) {
1037 entry->mutex.holder = 0;
1038 entry->mutex.count = 0;
1039 entry->mutex.muxWaiters = 0;
1042 while (entry->next != 0 && entry->object != object)
1043 entry = entry->next;
1045 if (entry->object != object) {
1046 entry->next = firstFreeOverflowEntry;
1047 firstFreeOverflowEntry = firstFreeOverflowEntry->next;
1049 entry = entry->next;
1052 assert(entry->conditionCount == 0);
1057 entry->mutex.holder = 0;
1058 entry->mutex.count = 0;
1059 entry->mutex.muxWaiters = 0;
1062 if (entry->object == 0)
1063 entry->object = object;
1065 internal_lock_mutex(&entry->mutex);
1071 * Unlocks the mutex of an object.
1073 void internal_unlock_mutex_for_object (java_objectheader *object)
1077 mutexHashEntry *entry;
1079 hashValue = MUTEX_HASH_VALUE(object);
1080 entry = &mutexHashTable[hashValue];
1082 if (entry->object == object) {
1083 internal_unlock_mutex(&entry->mutex);
1086 while (entry->next != 0 && entry->next->object != object)
1087 entry = entry->next;
1089 assert(entry->next != 0);
1091 internal_unlock_mutex(&entry->next->mutex);
1093 if (entry->next->mutex.count == 0 && entry->conditionCount == 0) {
1094 mutexHashEntry *unlinked = entry->next;
1096 entry->next = unlinked->next;
1097 unlinked->next = firstFreeOverflowEntry;
1098 firstFreeOverflowEntry = unlinked;
1105 void builtin_monitorenter(java_objectheader *o)
1110 assert(blockInts == 0);
1114 hashValue = MUTEX_HASH_VALUE(o);
1115 if (mutexHashTable[hashValue].object == o
1116 && mutexHashTable[hashValue].mutex.holder == currentThread)
1117 ++mutexHashTable[hashValue].mutex.count;
1119 internal_lock_mutex_for_object(o);
1123 assert(blockInts == 0);
1128 void builtin_monitorexit (java_objectheader *o)
1133 assert(blockInts == 0);
1137 hashValue = MUTEX_HASH_VALUE(o);
1138 if (mutexHashTable[hashValue].object == o) {
1139 if (mutexHashTable[hashValue].mutex.count == 1
1140 && mutexHashTable[hashValue].mutex.muxWaiters != 0)
1141 internal_unlock_mutex_for_object(o);
1143 --mutexHashTable[hashValue].mutex.count;
1146 internal_unlock_mutex_for_object(o);
1150 assert(blockInts == 0);
1155 /*****************************************************************************
1156 MISCELLANEOUS HELPER FUNCTIONS
1157 *****************************************************************************/
1161 /*********** Functions for integer divisions *****************************
1163 On some systems (eg. DEC ALPHA), integer division is not supported by the
1164 CPU. These helper functions implement the missing functionality.
1166 ******************************************************************************/
1168 s4 builtin_idiv(s4 a, s4 b) { return a / b; }
1169 s4 builtin_irem(s4 a, s4 b) { return a % b; }
1172 /************** Functions for long arithmetics *******************************
1174 On systems where 64 bit Integers are not supported by the CPU, these
1175 functions are needed.
1177 ******************************************************************************/
1180 s8 builtin_ladd(s8 a, s8 b)
1185 return builtin_i2l(0);
1189 s8 builtin_lsub(s8 a, s8 b)
1194 return builtin_i2l(0);
1198 s8 builtin_lmul(s8 a, s8 b)
1203 return builtin_i2l(0);
1207 s8 builtin_ldiv(s8 a, s8 b)
1212 return builtin_i2l(0);
1216 s8 builtin_lrem(s8 a, s8 b)
1221 return builtin_i2l(0);
1225 s8 builtin_lshl(s8 a, s4 b)
1228 return a << (b & 63);
1230 return builtin_i2l(0);
1234 s8 builtin_lshr(s8 a, s4 b)
1237 return a >> (b & 63);
1239 return builtin_i2l(0);
1243 s8 builtin_lushr(s8 a, s4 b)
1246 return ((u8) a) >> (b & 63);
1248 return builtin_i2l(0);
1252 s8 builtin_land(s8 a, s8 b)
1257 return builtin_i2l(0);
1261 s8 builtin_lor(s8 a, s8 b)
1266 return builtin_i2l(0);
1270 s8 builtin_lxor(s8 a, s8 b)
1275 return builtin_i2l(0);
1279 s8 builtin_lneg(s8 a)
1284 return builtin_i2l(0);
1288 s4 builtin_lcmp(s8 a, s8 b)
1291 if (a < b) return -1;
1292 if (a > b) return 1;
1303 /*********** Functions for floating point operations *************************/
1305 float builtin_fadd(float a, float b)
1307 if (isnanf(a)) return intBitsToFloat(FLT_NAN);
1308 if (isnanf(b)) return intBitsToFloat(FLT_NAN);
1319 if (copysignf(1.0, a) == copysignf(1.0, b))
1322 return intBitsToFloat(FLT_NAN);
1328 float builtin_fsub(float a, float b)
1330 return builtin_fadd(a, builtin_fneg(b));
1334 float builtin_fmul(float a, float b)
1336 if (isnanf(a)) return intBitsToFloat(FLT_NAN);
1337 if (isnanf(b)) return intBitsToFloat(FLT_NAN);
1339 if (finitef(b)) return a * b;
1341 if (a == 0) return intBitsToFloat(FLT_NAN);
1342 else return copysignf(b, copysignf(1.0, b)*a);
1347 if (b == 0) return intBitsToFloat(FLT_NAN);
1348 else return copysignf(a, copysignf(1.0, a)*b);
1351 return copysignf(a, copysignf(1.0, a)*copysignf(1.0, b));
1357 float builtin_fdiv(float a, float b)
1359 if (finitef(a) && finitef(b)) {
1364 return intBitsToFloat(FLT_POSINF);
1366 return intBitsToFloat(FLT_NEGINF);
1369 return intBitsToFloat(FLT_NAN);
1373 float builtin_frem(float a, float b)
1379 float builtin_fneg(float a)
1381 if (isnanf(a)) return a;
1383 if (finitef(a)) return -a;
1384 else return copysignf(a, -copysignf(1.0, a));
1389 s4 builtin_fcmpl(float a, float b)
1391 if (isnanf(a)) return -1;
1392 if (isnanf(b)) return -1;
1393 if (!finitef(a) || !finitef(b)) {
1394 a = finitef(a) ? 0 : copysignf(1.0, a);
1395 b = finitef(b) ? 0 : copysignf(1.0, b);
1397 if (a > b) return 1;
1398 if (a == b) return 0;
1403 s4 builtin_fcmpg(float a, float b)
1405 if (isnanf(a)) return 1;
1406 if (isnanf(b)) return 1;
1407 if (!finitef(a) || !finitef(b)) {
1408 a = finitef(a) ? 0 : copysignf(1.0, a);
1409 b = finitef(b) ? 0 : copysignf(1.0, b);
1411 if (a > b) return 1;
1412 if (a == b) return 0;
1418 /************************* Functions for doubles ****************************/
1420 double builtin_dadd(double a, double b)
1422 if (isnan(a)) return longBitsToDouble(DBL_NAN);
1423 if (isnan(b)) return longBitsToDouble(DBL_NAN);
1425 if (finite(b)) return a + b;
1429 if (finite(b)) return a;
1431 if (copysign(1.0, a)==copysign(1.0, b)) return a;
1432 else return longBitsToDouble(DBL_NAN);
1438 double builtin_dsub(double a, double b)
1440 return builtin_dadd(a, builtin_dneg(b));
1444 double builtin_dmul(double a, double b)
1446 if (isnan(a)) return longBitsToDouble(DBL_NAN);
1447 if (isnan(b)) return longBitsToDouble(DBL_NAN);
1449 if (finite(b)) return a * b;
1451 if (a == 0) return longBitsToDouble(DBL_NAN);
1452 else return copysign(b, copysign(1.0, b) * a);
1457 if (b == 0) return longBitsToDouble(DBL_NAN);
1458 else return copysign(a, copysign(1.0, a) * b);
1461 return copysign(a, copysign(1.0, a) * copysign(1.0, b));
1467 double builtin_ddiv(double a, double b)
1475 return longBitsToDouble(DBL_NAN);
1477 return copysign(0.0, b);
1483 return longBitsToDouble(DBL_POSINF);
1485 return longBitsToDouble(DBL_NEGINF);
1488 return longBitsToDouble(DBL_NAN);
1491 /* if (finite(a) && finite(b)) { */
1496 /* return longBitsToDouble(DBL_POSINF); */
1497 /* else if (a < 0) */
1498 /* return longBitsToDouble(DBL_NEGINF); */
1502 /* keep compiler happy */
1507 double builtin_drem(double a, double b)
1513 double builtin_dneg(double a)
1515 if (isnan(a)) return a;
1517 if (finite(a)) return -a;
1518 else return copysign(a, -copysign(1.0, a));
1523 s4 builtin_dcmpl(double a, double b)
1525 if (isnan(a)) return -1;
1526 if (isnan(b)) return -1;
1527 if (!finite(a) || !finite(b)) {
1528 a = finite(a) ? 0 : copysign(1.0, a);
1529 b = finite(b) ? 0 : copysign(1.0, b);
1531 if (a > b) return 1;
1532 if (a == b) return 0;
1537 s4 builtin_dcmpg(double a, double b)
1539 if (isnan(a)) return 1;
1540 if (isnan(b)) return 1;
1541 if (!finite(a) || !finite(b)) {
1542 a = finite(a) ? 0 : copysign(1.0, a);
1543 b = finite(b) ? 0 : copysign(1.0, b);
1545 if (a > b) return 1;
1546 if (a == b) return 0;
1551 /*********************** Conversion operations ****************************/
1553 s8 builtin_i2l(s4 i)
1566 float builtin_i2f(s4 a)
1568 float f = (float) a;
1573 double builtin_i2d(s4 a)
1575 double d = (double) a;
1580 s4 builtin_l2i(s8 l)
1590 float builtin_l2f(s8 a)
1593 float f = (float) a;
1601 double builtin_l2d(s8 a)
1604 double d = (double) a;
1612 s4 builtin_f2i(float a)
1615 return builtin_d2i((double) a);
1624 if (a < (-2147483648))
1625 return (-2147483648);
1628 f = copysignf((float) 1.0, a);
1631 return (-2147483648); */
1635 s8 builtin_f2l(float a)
1638 return builtin_d2l((double) a);
1643 if (a > 9223372036854775807L)
1644 return 9223372036854775807L;
1645 if (a < (-9223372036854775808L))
1646 return (-9223372036854775808L);
1651 f = copysignf((float) 1.0, a);
1653 return 9223372036854775807L;
1654 return (-9223372036854775808L); */
1658 double builtin_f2d(float a)
1660 if (finitef(a)) return (double) a;
1663 return longBitsToDouble(DBL_NAN);
1665 return copysign(longBitsToDouble(DBL_POSINF), (double) copysignf(1.0, a) );
1670 s4 builtin_d2i(double a)
1675 if (a >= 2147483647)
1677 if (a <= (-2147483647-1))
1678 return (-2147483647-1);
1683 d = copysign(1.0, a);
1686 return (-2147483647-1);
1690 s8 builtin_d2l(double a)
1695 if (a >= 9223372036854775807LL)
1696 return 9223372036854775807LL;
1697 if (a <= (-9223372036854775807LL-1))
1698 return (-9223372036854775807LL-1);
1703 d = copysign(1.0, a);
1705 return 9223372036854775807LL;
1706 return (-9223372036854775807LL-1);
1710 float builtin_d2f(double a)
1716 return intBitsToFloat(FLT_NAN);
1718 return copysignf(intBitsToFloat(FLT_POSINF), (float) copysign(1.0, a));
1723 /* used to convert FLT_xxx defines into float values */
1725 inline float intBitsToFloat(s4 i)
1734 /* used to convert DBL_xxx defines into double values */
1736 inline float longBitsToDouble(s8 l)
1745 java_arrayheader *builtin_clone_array(void *env, java_arrayheader *o)
1747 return Java_java_lang_VMObject_clone(0, 0, o);
1752 * These are local overrides for various environment variables in Emacs.
1753 * Please do not remove this and leave it at the end of the file, where
1754 * Emacs will automagically detect them.
1755 * ---------------------------------------------------------------------
1758 * indent-tabs-mode: t