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 718 2003-12-08 13:03:43Z jowenn $
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*/
62 builtin_descriptor builtin_desc[] = {
63 {(functionptr) builtin_instanceof, "instanceof"},
64 {(functionptr) builtin_checkcast, "checkcast"},
65 {(functionptr) asm_builtin_checkcast, "checkcast"},
66 {(functionptr) builtin_arrayinstanceof, "arrayinstanceof"},
68 {(functionptr) asm_builtin_arrayinstanceof,"arrayinstanceof"},
70 {(functionptr) builtin_checkarraycast, "checkarraycast"},
71 {(functionptr) asm_builtin_checkarraycast, "checkarraycast"},
72 {(functionptr) asm_builtin_aastore, "aastore"},
73 {(functionptr) builtin_new, "new"},
74 {(functionptr) builtin_newarray, "newarray"},
75 {(functionptr) builtin_anewarray, "anewarray"},
78 * have 2 parameters (needs stack manipulation)
80 {(functionptr) asm_builtin_newarray, "newarray"},
82 {(functionptr) builtin_newarray_boolean, "newarray_boolean"},
83 {(functionptr) builtin_newarray_char, "newarray_char"},
84 {(functionptr) builtin_newarray_float, "newarray_float"},
85 {(functionptr) builtin_newarray_double, "newarray_double"},
86 {(functionptr) builtin_newarray_byte, "newarray_byte"},
87 {(functionptr) builtin_newarray_short, "newarray_short"},
88 {(functionptr) builtin_newarray_int, "newarray_int"},
89 {(functionptr) builtin_newarray_long, "newarray_long"},
90 {(functionptr) builtin_displaymethodstart, "displaymethodstart"},
91 {(functionptr) builtin_displaymethodstop, "displaymethodstop"},
92 {(functionptr) builtin_monitorenter, "monitorenter"},
93 {(functionptr) asm_builtin_monitorenter, "monitorenter"},
94 {(functionptr) builtin_monitorexit, "monitorexit"},
95 {(functionptr) asm_builtin_monitorexit, "monitorexit"},
97 {(functionptr) builtin_idiv, "idiv"},
98 {(functionptr) asm_builtin_idiv, "idiv"},
99 {(functionptr) builtin_irem, "irem"},
100 {(functionptr) asm_builtin_irem, "irem"},
102 {(functionptr) builtin_ladd, "ladd"},
103 {(functionptr) builtin_lsub, "lsub"},
104 {(functionptr) builtin_lmul, "lmul"},
105 #if !(SUPPORT_DIVISION && SUPPORT_LONG && SUPPORT_LONG_DIV)
106 {(functionptr) builtin_ldiv, "ldiv"},
107 {(functionptr) asm_builtin_ldiv, "ldiv"},
108 {(functionptr) builtin_lrem, "lrem"},
109 {(functionptr) asm_builtin_lrem, "lrem"},
111 {(functionptr) builtin_lshl, "lshl"},
112 {(functionptr) builtin_lshr, "lshr"},
113 {(functionptr) builtin_lushr, "lushr"},
114 {(functionptr) builtin_land, "land"},
115 {(functionptr) builtin_lor, "lor"},
116 {(functionptr) builtin_lxor, "lxor"},
117 {(functionptr) builtin_lneg, "lneg"},
118 {(functionptr) builtin_lcmp, "lcmp"},
119 {(functionptr) builtin_fadd, "fadd"},
120 {(functionptr) builtin_fsub, "fsub"},
121 {(functionptr) builtin_fmul, "fmul"},
122 {(functionptr) builtin_fdiv, "fdiv"},
123 {(functionptr) builtin_frem, "frem"},
124 {(functionptr) builtin_fneg, "fneg"},
125 {(functionptr) builtin_fcmpl, "fcmpl"},
126 {(functionptr) builtin_fcmpg, "fcmpg"},
127 {(functionptr) builtin_dadd, "dadd"},
128 {(functionptr) builtin_dsub, "dsub"},
129 {(functionptr) builtin_dmul, "dmul"},
130 {(functionptr) builtin_ddiv, "ddiv"},
131 {(functionptr) builtin_drem, "drem"},
132 {(functionptr) builtin_dneg, "dneg"},
133 {(functionptr) builtin_dcmpl, "dcmpl"},
134 {(functionptr) builtin_dcmpg, "dcmpg"},
135 {(functionptr) builtin_i2l, "i2l"},
136 {(functionptr) builtin_i2f, "i2f"},
137 {(functionptr) builtin_i2d, "i2d"},
138 {(functionptr) builtin_l2i, "l2i"},
139 {(functionptr) builtin_l2f, "l2f"},
140 {(functionptr) builtin_l2d, "l2d"},
141 {(functionptr) builtin_f2i, "f2i"},
142 {(functionptr) builtin_f2l, "f2l"},
143 {(functionptr) builtin_f2d, "f2d"},
144 {(functionptr) builtin_d2i, "d2i"},
145 {(functionptr) builtin_d2l, "d2l"},
146 #if defined(__I386__)
147 {(functionptr) asm_builtin_f2i, "f2i"},
148 {(functionptr) asm_builtin_f2l, "f2l"},
149 {(functionptr) asm_builtin_d2i, "d2i"},
150 {(functionptr) asm_builtin_d2l, "d2l"},
152 {(functionptr) builtin_d2f, "d2f"},
153 {(functionptr) NULL, "unknown"}
157 /*****************************************************************************
159 *****************************************************************************/
163 /*************** internal function: builtin_isanysubclass *********************
165 Checks a subclass relation between two classes. Implemented interfaces
166 are interpreted as super classes.
167 Return value: 1 ... sub is subclass of super
170 *****************************************************************************/
172 s4 builtin_isanysubclass (classinfo *sub, classinfo *super)
175 if (super->flags & ACC_INTERFACE)
176 return (sub->vftbl->interfacetablelength > super->index) &&
177 (sub->vftbl->interfacetable[-super->index] != NULL);
190 for (tmp=sub;tmp!=0;tmp=tmp->super) {
192 utf_display(tmp->name);
196 for (tmp=super;tmp!=0;tmp=tmp->super) {
198 utf_display(tmp->name);
203 printf("sub->vftbl->baseval %d, super->vftbl->baseval %d\n diff %d, super->vftbl->diffval %d\n",
204 sub->vftbl->baseval, super->vftbl->baseval, (unsigned)(sub->vftbl->baseval - super->vftbl->baseval),
205 super->vftbl->diffval); */
207 return (unsigned) (sub->vftbl->baseval - super->vftbl->baseval) <=
208 (unsigned) (super->vftbl->diffval);
211 /* XXX inline this? */
212 s4 builtin_isanysubclass_vftbl(vftbl *sub,vftbl *super)
216 if ((base = super->baseval) <= 0)
217 /* super is an interface */
218 return (sub->interfacetablelength > -base) &&
219 (sub->interfacetable[base] != NULL);
220 return (unsigned) (sub->baseval - base)
221 <= (unsigned) (super->diffval);
225 /****************** function: builtin_instanceof *****************************
227 Checks if an object is an instance of some given class (or subclass of
228 that class). If class is an interface, checks if the interface is
230 Return value: 1 ... obj is an instance of class or implements the interface
231 0 ... otherwise or if obj == NULL
233 *****************************************************************************/
235 /* XXX should use vftbl */
236 s4 builtin_instanceof(java_objectheader *obj, classinfo *class)
239 log_text ("builtin_instanceof called");
242 return builtin_isanysubclass (obj->vftbl->class, class);
247 /**************** function: builtin_checkcast *******************************
249 The same as builtin_instanceof except that 1 is returned when
252 ****************************************************************************/
254 /* XXX should use vftbl */
255 s4 builtin_checkcast(java_objectheader *obj, classinfo *class)
258 log_text("builtin_checkcast called");
263 if (builtin_isanysubclass(obj->vftbl->class, class))
267 printf("#### checkcast failed ");
268 utf_display(obj->vftbl->class->name);
270 utf_display(class->name);
278 /*********** internal function: builtin_descriptorscompatible ******************
280 Checks if two array type descriptors are assignment compatible
281 Return value: 1 ... target = desc is possible
284 ******************************************************************************/
286 /* XXX inline this? */
287 static s4 builtin_descriptorscompatible(arraydescriptor *desc,arraydescriptor *target)
289 if (desc==target) return 1;
290 if (desc->arraytype != target->arraytype) return 0;
291 if (desc->arraytype != ARRAYTYPE_OBJECT) return 1;
293 /* {both arrays are arrays of references} */
294 if (desc->dimension == target->dimension)
295 return builtin_isanysubclass_vftbl(desc->elementvftbl,target->elementvftbl);
296 if (desc->dimension < target->dimension) return 0;
298 /* {desc has higher dimension than target} */
299 return builtin_isanysubclass_vftbl(pseudo_class_Arraystub_vftbl,target->elementvftbl);
303 /******************** function: builtin_checkarraycast ***********************
305 Checks if an object is really a subtype of the requested array type.
306 The object has to be an array to begin with. For simple arrays (int, short,
307 double, etc.) the types have to match exactly.
308 For arrays of objects, the type of elements in the array has to be a
309 subtype (or the same type) of the requested element type. For arrays of
310 arrays (which in turn can again be arrays of arrays), the types at the
311 lowest level have to satisfy the corresponding sub class relation.
313 Return value: 1 ... cast is possible
316 ATTENTION: a cast with a NULL pointer is always possible.
318 *****************************************************************************/
320 s4 builtin_checkarraycast(java_objectheader *o, vftbl *target)
322 arraydescriptor *desc;
325 if ((desc = o->vftbl->arraydesc) == NULL) return 0;
327 return builtin_descriptorscompatible(desc, target->arraydesc);
331 s4 builtin_arrayinstanceof(java_objectheader *obj, vftbl *target)
334 return builtin_checkarraycast(obj, target);
338 /************************** exception functions *******************************
340 ******************************************************************************/
342 java_objectheader *builtin_throw_exception(java_objectheader *local_exceptionptr)
345 char logtext[MAXLOGTEXT];
346 sprintf(logtext, "Builtin exception thrown: ");
347 if (local_exceptionptr)
348 utf_sprint(logtext + strlen(logtext), local_exceptionptr->vftbl->class->name);
350 sprintf(logtext+strlen(logtext),"%s","Error: <Nullpointer instead of exception>");
351 if (!proto_java_lang_ClassCastException) sprintf(logtext+strlen(logtext),"%s","proto_java_lang_ClassCastException==0");
352 if (!proto_java_lang_NullPointerException) sprintf(logtext+strlen(logtext),"%s","proto_java_lang_NullPointerException==0");
353 if (!proto_java_lang_NullPointerException) sprintf(logtext+strlen(logtext),"%s","proto_java_lang_NullPointerException==0");
354 if (!proto_java_lang_ArrayIndexOutOfBoundsException) sprintf(logtext+strlen(logtext),"%s","proto_java_lang_ArrayIndexOutOfBoundsException==0");
355 if (!proto_java_lang_NegativeArraySizeException) sprintf(logtext+strlen(logtext),"%s","proto_java_lang_NegativeArraySizeException==0");
356 if (!proto_java_lang_OutOfMemoryError) sprintf(logtext+strlen(logtext),"%s","proto_java_lang_OutOfMemoryError==0");
357 if (!proto_java_lang_ArithmeticException) sprintf(logtext+strlen(logtext),"%s","proto_java_lang_ArithmeticException==0");
358 if (!proto_java_lang_ArrayStoreException) sprintf(logtext+strlen(logtext),"%s","proto_java_lang_ArrayStoreException==0");
359 if (!proto_java_lang_ThreadDeath) sprintf(logtext+strlen(logtext),"%s","proto_java_lang_ThreadDeath==0");
360 if (!proto_java_lang_ThreadDeath) sprintf(logtext+strlen(logtext),"%s","proto_java_lang_ThreadDeath==0");
364 exceptionptr = local_exceptionptr;
365 return local_exceptionptr;
369 /******************* function: builtin_canstore *******************************
371 Checks, if an object can be stored in an array.
372 Return value: 1 ... possible
375 ******************************************************************************/
377 s4 builtin_canstore (java_objectarray *a, java_objectheader *o)
379 arraydescriptor *desc;
380 arraydescriptor *valuedesc;
381 vftbl *componentvftbl;
388 /* The following is guaranteed (by verifier checks):
390 * *) a->...vftbl->arraydesc != NULL
391 * *) a->...vftbl->arraydesc->componentvftbl != NULL
392 * *) o->vftbl is not an interface vftbl
395 desc = a->header.objheader.vftbl->arraydesc;
396 componentvftbl = desc->componentvftbl;
397 valuevftbl = o->vftbl;
399 if ((dim_m1 = desc->dimension - 1) == 0) {
400 /* {a is a one-dimensional array} */
401 /* {a is an array of references} */
403 if (valuevftbl == componentvftbl)
406 if ((base = componentvftbl->baseval) <= 0)
407 /* an array of interface references */
408 return (valuevftbl->interfacetablelength > -base &&
409 valuevftbl->interfacetable[base] != NULL);
411 return (unsigned)(valuevftbl->baseval - base)
412 <= (unsigned)(componentvftbl->diffval);
414 /* {a has dimension > 1} */
415 /* {componentvftbl->arraydesc != NULL} */
417 /* check if o is an array */
418 if ((valuedesc = valuevftbl->arraydesc) == NULL)
420 /* {o is an array} */
422 return builtin_descriptorscompatible(valuedesc,componentvftbl->arraydesc);
426 /* This is an optimized version where a is guaranteed to be one-dimensional */
427 s4 builtin_canstore_onedim (java_objectarray *a, java_objectheader *o)
429 arraydescriptor *desc;
436 /* The following is guaranteed (by verifier checks):
438 * *) a->...vftbl->arraydesc != NULL
439 * *) a->...vftbl->arraydesc->elementvftbl != NULL
440 * *) a->...vftbl->arraydesc->dimension == 1
441 * *) o->vftbl is not an interface vftbl
444 desc = a->header.objheader.vftbl->arraydesc;
445 elementvftbl = desc->elementvftbl;
446 valuevftbl = o->vftbl;
448 /* {a is a one-dimensional array} */
450 if (valuevftbl == elementvftbl)
453 if ((base = elementvftbl->baseval) <= 0)
454 /* an array of interface references */
455 return (valuevftbl->interfacetablelength > -base &&
456 valuevftbl->interfacetable[base] != NULL);
458 return (unsigned)(valuevftbl->baseval - base)
459 <= (unsigned)(elementvftbl->diffval);
463 /* This is an optimized version where a is guaranteed to be a
464 * one-dimensional array of a class type */
465 /* XXX this could be inlined by the code generator */
466 s4 builtin_canstore_onedim_class(java_objectarray *a, java_objectheader *o)
473 /* The following is guaranteed (by verifier checks):
475 * *) a->...vftbl->arraydesc != NULL
476 * *) a->...vftbl->arraydesc->elementvftbl != NULL
477 * *) a->...vftbl->arraydesc->elementvftbl is not an interface vftbl
478 * *) a->...vftbl->arraydesc->dimension == 1
479 * *) o->vftbl is not an interface vftbl
482 elementvftbl = a->header.objheader.vftbl->arraydesc->elementvftbl;
483 valuevftbl = o->vftbl;
485 /* {a is a one-dimensional array} */
487 if (valuevftbl == elementvftbl)
490 return (unsigned)(valuevftbl->baseval - elementvftbl->baseval)
491 <= (unsigned)(elementvftbl->diffval);
495 /******************** Function: builtin_new **********************************
497 Creates a new instance of class c on the heap.
498 Return value: pointer to the object or NULL if no memory is
501 *****************************************************************************/
504 #define align_size(size) ((size + ((1 << ALIGNMENT) - 1)) & ~((1 << ALIGNMENT) - 1))
506 java_objectheader *builtin_new(classinfo *c)
508 java_objectheader *o;
512 #ifdef SIZE_FROM_CLASSINFO
513 c->alignedsize = align_size(c->instancesize);
514 o = heap_allocate(c->alignedsize, true, c->finalizer);
516 o = heap_allocate(c->instancesize, true, c->finalizer);
520 memset(o, 0, c->instancesize);
527 /********************** Function: builtin_newarray **************************
529 Creates an array with the given vftbl on the heap.
531 Return value: pointer to the array or NULL if no memory is available
533 CAUTION: The given vftbl must be the vftbl of the *array* class,
534 not of the element class.
536 *****************************************************************************/
538 java_arrayheader *builtin_newarray(s4 size, vftbl *arrayvftbl)
541 arraydescriptor *desc = arrayvftbl->arraydesc;
542 s4 dataoffset = desc->dataoffset;
543 s4 componentsize = desc->componentsize;
547 exceptionptr=native_new_and_init(loader_load(utf_new_char("java/lang/NegativeArraySizeException")));
550 #ifdef SIZE_FROM_CLASSINFO
551 actualsize = align_size(dataoffset + size * componentsize);
553 actualsize = dataoffset + size * componentsize;
556 if (((u4)actualsize)<((u4)size)) { /* overflow */
557 exceptionptr=native_new_and_init(loader_load(utf_new_char("java/lang/OutOfMemoryError")));
560 a = (java_arrayheader *) heap_allocate(actualsize,
561 (desc->arraytype == ARRAYTYPE_OBJECT),
564 memset(a,0,actualsize);
567 /*printf("builtin_newarray: Created an array of size : %d\n",size);*/
569 a->objheader.vftbl = arrayvftbl;
571 #ifdef SIZE_FROM_CLASSINFO
572 a->alignedsize = actualsize;
579 /********************** Function: builtin_anewarray *************************
581 Creates an array of references to the given class type on the heap.
583 Return value: pointer to the array or NULL if no memory is available
585 XXX This function does not do The Right Thing, because it uses a
586 classinfo pointer at runtime. builtin_newarray should be used
589 *****************************************************************************/
591 java_objectarray *builtin_anewarray(s4 size, classinfo *component)
593 return (java_objectarray*) builtin_newarray(size, class_array_of(component)->vftbl);
597 /******************** Function: builtin_newarray_int ***********************
599 Creates an array of 32 bit Integers on the heap.
601 Return value: pointer to the array or NULL if no memory is available
603 *****************************************************************************/
605 java_intarray *builtin_newarray_int(s4 size)
607 return (java_intarray*) builtin_newarray(size, primitivetype_table[ARRAYTYPE_INT].arrayvftbl);
611 /******************** Function: builtin_newarray_long ***********************
613 Creates an array of 64 bit Integers on the heap.
615 Return value: pointer to the array or NULL if no memory is available
617 *****************************************************************************/
619 java_longarray *builtin_newarray_long(s4 size)
621 return (java_longarray*) builtin_newarray(size, primitivetype_table[ARRAYTYPE_LONG].arrayvftbl);
625 /******************** function: builtin_newarray_float ***********************
627 Creates an array of 32 bit IEEE floats on the heap.
629 Return value: pointer to the array or NULL if no memory is available
631 *****************************************************************************/
633 java_floatarray *builtin_newarray_float(s4 size)
635 return (java_floatarray*) builtin_newarray(size, primitivetype_table[ARRAYTYPE_FLOAT].arrayvftbl);
639 /******************** function: builtin_newarray_double ***********************
641 Creates an array of 64 bit IEEE floats on the heap.
643 Return value: pointer to the array or NULL if no memory is available
645 *****************************************************************************/
647 java_doublearray *builtin_newarray_double(s4 size)
649 return (java_doublearray*) builtin_newarray(size, primitivetype_table[ARRAYTYPE_DOUBLE].arrayvftbl);
653 /******************** function: builtin_newarray_byte ***********************
655 Creates an array of 8 bit Integers on the heap.
657 Return value: pointer to the array or NULL if no memory is available
659 *****************************************************************************/
661 java_bytearray *builtin_newarray_byte(s4 size)
663 return (java_bytearray*) builtin_newarray(size, primitivetype_table[ARRAYTYPE_BYTE].arrayvftbl);
667 /******************** function: builtin_newarray_char ************************
669 Creates an array of characters on the heap.
671 Return value: pointer to the array or NULL if no memory is available
673 *****************************************************************************/
675 java_chararray *builtin_newarray_char(s4 size)
677 return (java_chararray*) builtin_newarray(size, primitivetype_table[ARRAYTYPE_CHAR].arrayvftbl);
681 /******************** function: builtin_newarray_short ***********************
683 Creates an array of 16 bit Integers on the heap.
685 Return value: pointer to the array or NULL if no memory is available
687 *****************************************************************************/
689 java_shortarray *builtin_newarray_short(s4 size)
691 return (java_shortarray*) builtin_newarray(size, primitivetype_table[ARRAYTYPE_SHORT].arrayvftbl);
695 /******************** function: builtin_newarray_boolean ************************
697 Creates an array of bytes on the heap. The array is designated as an array
698 of booleans (important for casts)
700 Return value: pointer to the array or NULL if no memory is available
702 *****************************************************************************/
704 java_booleanarray *builtin_newarray_boolean(s4 size)
706 return (java_booleanarray*) builtin_newarray(size, primitivetype_table[ARRAYTYPE_BOOLEAN].arrayvftbl);
710 /**************** function: builtin_nmultianewarray ***************************
712 Creates a multi-dimensional array on the heap. The dimensions are passed in
716 n............number of dimensions to create
717 arrayvftbl...vftbl of the array class
718 dims.........array containing the size of each dimension to create
720 Return value: pointer to the array or NULL if no memory is available
722 ******************************************************************************/
724 /* Helper functions */
726 java_arrayheader *builtin_nmultianewarray (int n, vftbl *arrayvftbl, long *dims)
730 vftbl *componentvftbl;
732 /* create this dimension */
733 size = (int) dims[0];
734 a = builtin_newarray(size,arrayvftbl);
737 /* if this is the last dimension return */
740 /* get the vftbl of the components to create */
741 componentvftbl = arrayvftbl->arraydesc->componentvftbl;
742 if (!componentvftbl) /* XXX the verifier could check this */
743 panic ("multianewarray with too many dimensions");
745 /* create the component arrays */
746 for (i = 0; i < size; i++) {
747 java_arrayheader *ea =
748 builtin_nmultianewarray(n,componentvftbl,dims+1);
749 if (!ea) return NULL;
750 ((java_objectarray*)a)->data[i] = (java_objectheader *) ea;
757 /*****************************************************************************
760 Various functions for printing a message at method entry or exit (for
763 *****************************************************************************/
768 java_objectheader *builtin_trace_exception(java_objectheader *exceptionptr,
769 methodinfo *method, int *pos,
774 if (verbose || runverbose) {
775 printf("Exception ");
777 utf_display (exceptionptr->vftbl->class->name);
780 printf("Error: <Nullpointer instead of exception>");
781 if (!proto_java_lang_ClassCastException) printf("%s","proto_java_lang_ClassCastException==0");
782 if (!proto_java_lang_NullPointerException) printf("%s","proto_java_lang_NullPointerException==0");
783 if (!proto_java_lang_NullPointerException) printf("%s","proto_java_lang_NullPointerException==0");
784 if (!proto_java_lang_ArrayIndexOutOfBoundsException) printf("%s","proto_java_lang_ArrayIndexOutOfBoundsException==0");
785 if (!proto_java_lang_NegativeArraySizeException) printf("%s","proto_java_lang_NegativeArraySizeException==0");
786 if (!proto_java_lang_OutOfMemoryError) printf("%s","proto_java_lang_OutOfMemoryError==0");
787 if (!proto_java_lang_ArithmeticException) printf("%s","proto_java_lang_ArithmeticException==0");
788 if (!proto_java_lang_ArrayStoreException) printf("%s","proto_java_lang_ArrayStoreException==0");
789 if (!proto_java_lang_ThreadDeath) printf("%s","proto_java_lang_ThreadDeath==0");
790 if (!proto_java_lang_ThreadDeath) printf("%s","proto_java_lang_ThreadDeath==0");
793 printf(" thrown in ");
795 utf_display (method->class->name);
797 utf_display (method->name);
798 if (method->flags & ACC_SYNCHRONIZED)
802 printf("(%p) at position %p\n", method->entrypoint, pos);
805 printf("call_java_method\n");
812 #ifdef TRACE_ARGS_NUM
813 void builtin_trace_args(s8 a0, s8 a1, s8 a2, s8 a3, s8 a4, s8 a5,
814 #if TRACE_ARGS_NUM > 6
820 char logtext[MAXLOGTEXT];
821 for (i = 0; i < methodindent; i++)
823 sprintf(logtext + methodindent, "called: ");
824 utf_sprint(logtext + strlen(logtext), method->class->name);
825 sprintf(logtext + strlen(logtext), ".");
826 utf_sprint(logtext + strlen(logtext), method->name);
827 utf_sprint(logtext + strlen(logtext), method->descriptor);
828 sprintf(logtext + strlen(logtext), "(");
830 switch (method->paramcount) {
834 #if defined(__I386__)
836 sprintf(logtext+strlen(logtext), "%llx", a0);
840 sprintf(logtext+strlen(logtext), "%llx, %llx", a0, a1);
844 sprintf(logtext+strlen(logtext), "%llx, %llx, %llx", a0, a1, a2);
848 sprintf(logtext+strlen(logtext), "%llx, %llx, %llx, %llx",
853 sprintf(logtext+strlen(logtext), "%llx, %llx, %llx, %llx, %llx",
858 sprintf(logtext+strlen(logtext), "%llx, %llx, %llx, %llx, %llx, %llx",
859 a0, a1, a2, a3, a4, a5);
862 #if TRACE_ARGS_NUM > 6
864 sprintf(logtext+strlen(logtext), "%llx, %llx, %llx, %llx, %llx, %llx, %llx",
865 a0, a1, a2, a3, a4, a5, a6);
869 sprintf(logtext+strlen(logtext), "%llx, %llx, %llx, %llx, %llx, %llx, %llx, %llx",
870 a0, a1, a2, a3, a4, a5, a6, a7);
874 sprintf(logtext+strlen(logtext), "%llx, %llx, %llx, %llx, %llx, %llx, %llx, %llx, ...(%d)",
875 a0, a1, a2, a3, a4, a5, a6, a7, method->paramcount - 8);
879 sprintf(logtext+strlen(logtext), "%llx, %llx, %llx, %llx, %llx, %llx, ...(%d)",
880 a0, a1, a2, a3, a4, a5, method->paramcount - 6);
885 sprintf(logtext+strlen(logtext), "%lx", a0);
889 sprintf(logtext+strlen(logtext), "%lx, %lx", a0, a1);
893 sprintf(logtext+strlen(logtext), "%lx, %lx, %lx", a0, a1, a2);
897 sprintf(logtext+strlen(logtext), "%lx, %lx, %lx, %lx",
902 sprintf(logtext+strlen(logtext), "%lx, %lx, %lx, %lx, %lx",
907 sprintf(logtext+strlen(logtext), "%lx, %lx, %lx, %lx, %lx, %lx",
908 a0, a1, a2, a3, a4, a5);
911 #if TRACE_ARGS_NUM > 6
913 sprintf(logtext+strlen(logtext), "%lx, %lx, %lx, %lx, %lx, %lx, %lx",
914 a0, a1, a2, a3, a4, a5, a6);
918 sprintf(logtext+strlen(logtext), "%lx, %lx, %lx, %lx, %lx, %lx, %lx, %lx",
919 a0, a1, a2, a3, a4, a5, a6, a7);
923 sprintf(logtext+strlen(logtext), "%lx, %lx, %lx, %lx, %lx, %lx, %lx, %lx, ...(%d)",
924 a0, a1, a2, a3, a4, a5, a6, a7, method->paramcount - 8);
928 sprintf(logtext+strlen(logtext), "%lx, %lx, %lx, %lx, %lx, %lx, ...(%d)",
929 a0, a1, a2, a3, a4, a5, method->paramcount - 6);
934 sprintf (logtext+strlen(logtext), ")");
942 void builtin_displaymethodstart(methodinfo *method)
944 char logtext[MAXLOGTEXT];
945 sprintf(logtext, " ");
946 sprintf(logtext + methodindent, "called: ");
947 utf_sprint(logtext + strlen(logtext), method->class->name);
948 sprintf(logtext + strlen(logtext), ".");
949 utf_sprint(logtext + strlen(logtext), method->name);
950 utf_sprint(logtext + strlen(logtext), method->descriptor);
956 void builtin_displaymethodstop(methodinfo *method, s8 l, double d, float f)
959 char logtext[MAXLOGTEXT];
960 for (i = 0; i < methodindent; i++)
963 sprintf(logtext + methodindent, "finished: ");
964 utf_sprint(logtext + strlen(logtext), method->class->name);
965 sprintf(logtext + strlen(logtext), ".");
966 utf_sprint(logtext + strlen(logtext), method->name);
967 utf_sprint(logtext + strlen(logtext), method->descriptor);
969 switch (method->returntype) {
971 sprintf(logtext + strlen(logtext), "->%d", (s4) l);
974 #if defined(__I386__)
975 sprintf(logtext + strlen(logtext), "->%lld", (s8) l);
977 sprintf(logtext + strlen(logtext), "->%ld", (s8) l);
981 #if defined(__I386__)
982 sprintf(logtext + strlen(logtext), "->%p", (u1*) ((s4) l));
984 sprintf(logtext + strlen(logtext), "->%p", (u1*) l);
988 sprintf(logtext + strlen(logtext), "->%g", f);
991 sprintf(logtext + strlen(logtext), "->%g", d);
998 void builtin_displaymethodexception(methodinfo *method)
1001 char logtext[MAXLOGTEXT];
1002 for (i = 0; i < methodindent; i++)
1004 sprintf(logtext + methodindent, "exception abort: ");
1005 utf_sprint(logtext + strlen(logtext), method->class->name);
1006 sprintf(logtext + strlen(logtext), ".");
1007 utf_sprint(logtext + strlen(logtext), method->name);
1008 utf_sprint(logtext + strlen(logtext), method->descriptor);
1013 /****************************************************************************
1014 SYNCHRONIZATION FUNCTIONS
1015 *****************************************************************************/
1018 * Lock the mutex of an object.
1020 void internal_lock_mutex_for_object(java_objectheader *object)
1023 mutexHashEntry *entry;
1026 assert(object != 0);
1028 hashValue = MUTEX_HASH_VALUE(object);
1029 entry = &mutexHashTable[hashValue];
1031 if (entry->object != 0) {
1032 if (entry->mutex.count == 0 && entry->conditionCount == 0) {
1034 entry->mutex.holder = 0;
1035 entry->mutex.count = 0;
1036 entry->mutex.muxWaiters = 0;
1039 while (entry->next != 0 && entry->object != object)
1040 entry = entry->next;
1042 if (entry->object != object) {
1043 entry->next = firstFreeOverflowEntry;
1044 firstFreeOverflowEntry = firstFreeOverflowEntry->next;
1046 entry = entry->next;
1049 assert(entry->conditionCount == 0);
1054 entry->mutex.holder = 0;
1055 entry->mutex.count = 0;
1056 entry->mutex.muxWaiters = 0;
1059 if (entry->object == 0)
1060 entry->object = object;
1062 internal_lock_mutex(&entry->mutex);
1068 * Unlocks the mutex of an object.
1070 void internal_unlock_mutex_for_object (java_objectheader *object)
1074 mutexHashEntry *entry;
1076 hashValue = MUTEX_HASH_VALUE(object);
1077 entry = &mutexHashTable[hashValue];
1079 if (entry->object == object) {
1080 internal_unlock_mutex(&entry->mutex);
1083 while (entry->next != 0 && entry->next->object != object)
1084 entry = entry->next;
1086 assert(entry->next != 0);
1088 internal_unlock_mutex(&entry->next->mutex);
1090 if (entry->next->mutex.count == 0 && entry->conditionCount == 0) {
1091 mutexHashEntry *unlinked = entry->next;
1093 entry->next = unlinked->next;
1094 unlinked->next = firstFreeOverflowEntry;
1095 firstFreeOverflowEntry = unlinked;
1102 void builtin_monitorenter(java_objectheader *o)
1107 assert(blockInts == 0);
1111 hashValue = MUTEX_HASH_VALUE(o);
1112 if (mutexHashTable[hashValue].object == o
1113 && mutexHashTable[hashValue].mutex.holder == currentThread)
1114 ++mutexHashTable[hashValue].mutex.count;
1116 internal_lock_mutex_for_object(o);
1120 assert(blockInts == 0);
1125 void builtin_monitorexit (java_objectheader *o)
1130 assert(blockInts == 0);
1134 hashValue = MUTEX_HASH_VALUE(o);
1135 if (mutexHashTable[hashValue].object == o) {
1136 if (mutexHashTable[hashValue].mutex.count == 1
1137 && mutexHashTable[hashValue].mutex.muxWaiters != 0)
1138 internal_unlock_mutex_for_object(o);
1140 --mutexHashTable[hashValue].mutex.count;
1143 internal_unlock_mutex_for_object(o);
1147 assert(blockInts == 0);
1152 /*****************************************************************************
1153 MISCELLANEOUS HELPER FUNCTIONS
1154 *****************************************************************************/
1158 /*********** Functions for integer divisions *****************************
1160 On some systems (eg. DEC ALPHA), integer division is not supported by the
1161 CPU. These helper functions implement the missing functionality.
1163 ******************************************************************************/
1165 s4 builtin_idiv(s4 a, s4 b) { return a / b; }
1166 s4 builtin_irem(s4 a, s4 b) { return a % b; }
1169 /************** Functions for long arithmetics *******************************
1171 On systems where 64 bit Integers are not supported by the CPU, these
1172 functions are needed.
1174 ******************************************************************************/
1177 s8 builtin_ladd(s8 a, s8 b)
1182 return builtin_i2l(0);
1186 s8 builtin_lsub(s8 a, s8 b)
1191 return builtin_i2l(0);
1195 s8 builtin_lmul(s8 a, s8 b)
1200 return builtin_i2l(0);
1204 s8 builtin_ldiv(s8 a, s8 b)
1209 return builtin_i2l(0);
1213 s8 builtin_lrem(s8 a, s8 b)
1218 return builtin_i2l(0);
1222 s8 builtin_lshl(s8 a, s4 b)
1225 return a << (b & 63);
1227 return builtin_i2l(0);
1231 s8 builtin_lshr(s8 a, s4 b)
1234 return a >> (b & 63);
1236 return builtin_i2l(0);
1240 s8 builtin_lushr(s8 a, s4 b)
1243 return ((u8) a) >> (b & 63);
1245 return builtin_i2l(0);
1249 s8 builtin_land(s8 a, s8 b)
1254 return builtin_i2l(0);
1258 s8 builtin_lor(s8 a, s8 b)
1263 return builtin_i2l(0);
1267 s8 builtin_lxor(s8 a, s8 b)
1272 return builtin_i2l(0);
1276 s8 builtin_lneg(s8 a)
1281 return builtin_i2l(0);
1285 s4 builtin_lcmp(s8 a, s8 b)
1288 if (a < b) return -1;
1289 if (a > b) return 1;
1300 /*********** Functions for floating point operations *************************/
1302 float builtin_fadd(float a, float b)
1304 if (isnanf(a)) return intBitsToFloat(FLT_NAN);
1305 if (isnanf(b)) return intBitsToFloat(FLT_NAN);
1316 if (copysignf(1.0, a) == copysignf(1.0, b))
1319 return intBitsToFloat(FLT_NAN);
1325 float builtin_fsub(float a, float b)
1327 return builtin_fadd(a, builtin_fneg(b));
1331 float builtin_fmul(float a, float b)
1333 if (isnanf(a)) return intBitsToFloat(FLT_NAN);
1334 if (isnanf(b)) return intBitsToFloat(FLT_NAN);
1336 if (finitef(b)) return a * b;
1338 if (a == 0) return intBitsToFloat(FLT_NAN);
1339 else return copysignf(b, copysignf(1.0, b)*a);
1344 if (b == 0) return intBitsToFloat(FLT_NAN);
1345 else return copysignf(a, copysignf(1.0, a)*b);
1348 return copysignf(a, copysignf(1.0, a)*copysignf(1.0, b));
1354 float builtin_fdiv(float a, float b)
1356 if (finitef(a) && finitef(b)) {
1361 return intBitsToFloat(FLT_POSINF);
1363 return intBitsToFloat(FLT_NEGINF);
1366 return intBitsToFloat(FLT_NAN);
1370 float builtin_frem(float a, float b)
1376 float builtin_fneg(float a)
1378 if (isnanf(a)) return a;
1380 if (finitef(a)) return -a;
1381 else return copysignf(a, -copysignf(1.0, a));
1386 s4 builtin_fcmpl(float a, float b)
1388 if (isnanf(a)) return -1;
1389 if (isnanf(b)) return -1;
1390 if (!finitef(a) || !finitef(b)) {
1391 a = finitef(a) ? 0 : copysignf(1.0, a);
1392 b = finitef(b) ? 0 : copysignf(1.0, b);
1394 if (a > b) return 1;
1395 if (a == b) return 0;
1400 s4 builtin_fcmpg(float a, float b)
1402 if (isnanf(a)) return 1;
1403 if (isnanf(b)) return 1;
1404 if (!finitef(a) || !finitef(b)) {
1405 a = finitef(a) ? 0 : copysignf(1.0, a);
1406 b = finitef(b) ? 0 : copysignf(1.0, b);
1408 if (a > b) return 1;
1409 if (a == b) return 0;
1415 /************************* Functions for doubles ****************************/
1417 double builtin_dadd(double a, double b)
1419 if (isnan(a)) return longBitsToDouble(DBL_NAN);
1420 if (isnan(b)) return longBitsToDouble(DBL_NAN);
1422 if (finite(b)) return a + b;
1426 if (finite(b)) return a;
1428 if (copysign(1.0, a)==copysign(1.0, b)) return a;
1429 else return longBitsToDouble(DBL_NAN);
1435 double builtin_dsub(double a, double b)
1437 return builtin_dadd(a, builtin_dneg(b));
1441 double builtin_dmul(double a, double b)
1443 if (isnan(a)) return longBitsToDouble(DBL_NAN);
1444 if (isnan(b)) return longBitsToDouble(DBL_NAN);
1446 if (finite(b)) return a * b;
1448 if (a == 0) return longBitsToDouble(DBL_NAN);
1449 else return copysign(b, copysign(1.0, b) * a);
1454 if (b == 0) return longBitsToDouble(DBL_NAN);
1455 else return copysign(a, copysign(1.0, a) * b);
1458 return copysign(a, copysign(1.0, a) * copysign(1.0, b));
1464 double builtin_ddiv(double a, double b)
1472 return longBitsToDouble(DBL_NAN);
1474 return copysign(0.0, b);
1480 return longBitsToDouble(DBL_POSINF);
1482 return longBitsToDouble(DBL_NEGINF);
1485 return longBitsToDouble(DBL_NAN);
1488 /* if (finite(a) && finite(b)) { */
1493 /* return longBitsToDouble(DBL_POSINF); */
1494 /* else if (a < 0) */
1495 /* return longBitsToDouble(DBL_NEGINF); */
1499 /* keep compiler happy */
1504 double builtin_drem(double a, double b)
1510 double builtin_dneg(double a)
1512 if (isnan(a)) return a;
1514 if (finite(a)) return -a;
1515 else return copysign(a, -copysign(1.0, a));
1520 s4 builtin_dcmpl(double a, double b)
1522 if (isnan(a)) return -1;
1523 if (isnan(b)) return -1;
1524 if (!finite(a) || !finite(b)) {
1525 a = finite(a) ? 0 : copysign(1.0, a);
1526 b = finite(b) ? 0 : copysign(1.0, b);
1528 if (a > b) return 1;
1529 if (a == b) return 0;
1534 s4 builtin_dcmpg(double a, double b)
1536 if (isnan(a)) return 1;
1537 if (isnan(b)) return 1;
1538 if (!finite(a) || !finite(b)) {
1539 a = finite(a) ? 0 : copysign(1.0, a);
1540 b = finite(b) ? 0 : copysign(1.0, b);
1542 if (a > b) return 1;
1543 if (a == b) return 0;
1548 /*********************** Conversion operations ****************************/
1550 s8 builtin_i2l(s4 i)
1563 float builtin_i2f(s4 a)
1565 float f = (float) a;
1570 double builtin_i2d(s4 a)
1572 double d = (double) a;
1577 s4 builtin_l2i(s8 l)
1587 float builtin_l2f(s8 a)
1590 float f = (float) a;
1598 double builtin_l2d(s8 a)
1601 double d = (double) a;
1609 s4 builtin_f2i(float a)
1612 return builtin_d2i((double) a);
1621 if (a < (-2147483648))
1622 return (-2147483648);
1625 f = copysignf((float) 1.0, a);
1628 return (-2147483648); */
1632 s8 builtin_f2l(float a)
1635 return builtin_d2l((double) a);
1640 if (a > 9223372036854775807L)
1641 return 9223372036854775807L;
1642 if (a < (-9223372036854775808L))
1643 return (-9223372036854775808L);
1648 f = copysignf((float) 1.0, a);
1650 return 9223372036854775807L;
1651 return (-9223372036854775808L); */
1655 double builtin_f2d(float a)
1657 if (finitef(a)) return (double) a;
1660 return longBitsToDouble(DBL_NAN);
1662 return copysign(longBitsToDouble(DBL_POSINF), (double) copysignf(1.0, a) );
1667 s4 builtin_d2i(double a)
1672 if (a >= 2147483647)
1674 if (a <= (-2147483647-1))
1675 return (-2147483647-1);
1680 d = copysign(1.0, a);
1683 return (-2147483647-1);
1687 s8 builtin_d2l(double a)
1692 if (a >= 9223372036854775807LL)
1693 return 9223372036854775807LL;
1694 if (a <= (-9223372036854775807LL-1))
1695 return (-9223372036854775807LL-1);
1700 d = copysign(1.0, a);
1702 return 9223372036854775807LL;
1703 return (-9223372036854775807LL-1);
1707 float builtin_d2f(double a)
1713 return intBitsToFloat(FLT_NAN);
1715 return copysignf(intBitsToFloat(FLT_POSINF), (float) copysign(1.0, a));
1720 /* used to convert FLT_xxx defines into float values */
1722 inline float intBitsToFloat(s4 i)
1731 /* used to convert DBL_xxx defines into double values */
1733 inline float longBitsToDouble(s8 l)
1742 java_arrayheader *builtin_clone_array(void *env, java_arrayheader *o)
1744 return Java_java_lang_VMObject_clone(0, 0, o);
1749 * These are local overrides for various environment variables in Emacs.
1750 * Please do not remove this and leave it at the end of the file, where
1751 * Emacs will automagically detect them.
1752 * ---------------------------------------------------------------------
1755 * indent-tabs-mode: t